home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
BURKS 2
/
BURKS_AUG97.ISO
/
BURKS
/
LANGUAGE
/
SMALTALK
/
TEXTBOOK
/
AP31.ST
(
.txt
)
< prev
next >
Wrap
Text File
|
1997-04-22
|
8KB
|
313 lines
'Smalltalk Textbook Appendix 31'!
EngiDirectedGraph subclass: #EngiClassGraph
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'Engi-Inheritance'!
EngiClassGraph comment:
'
Engi 0.07 (24 March 1994)
Copyright (C) 1994 by Atsushi Aoki
'!
!EngiClassGraph methodsFor: 'defaults'!
defaultArrangeFormat
^Array
with: #left
with: 20
with: 1
with: #balance!
defaultBranchClass
^EngiClassBranch!
defaultVertexClass
^EngiClassVertex! !
"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
EngiClassGraph class
instanceVariableNames: ''!
!EngiClassGraph class methodsFor: 'instance creation'!
fromClass: aClass
"EngiClassGraph fromClass: Number."
| graphGenerationBlock aGraph |
graphGenerationBlock :=
[:collection :graph :table |
| fromVertex toVertex |
(table includesKey: collection first)
ifTrue: [fromVertex := table at: collection first]
ifFalse:
[fromVertex := graph defaultVertex.
fromVertex className: collection first.
table at: collection first put: fromVertex].
(collection copyFrom: 2 to: collection size)
do:
[:each |
graphGenerationBlock
value: each
value: graph
value: table.
(table includesKey: each first)
ifTrue: [toVertex := table at: each first]
ifFalse:
[toVertex := graph defaultVertex.
toVertex className: each first.
table at: each first put: toVertex].
graph connect: fromVertex with: toVertex].
graph yourself].
aGraph := graphGenerationBlock
value: (self classHierarchy: aClass)
value: self new
value: Dictionary new.
aGraph arrangeScan.
^aGraph! !
!EngiClassGraph class methodsFor: 'utilities'!
classHierarchy: aClass
"EngiClassGraph classHierarchy: Number."
| theClass collection old |
aClass isMeta
ifTrue: [theClass := aClass soleInstance]
ifFalse: [theClass := aClass].
collection := self subclassHierarchy: theClass.
(theClass allSuperclasses select: [:each | each isMeta not])
do:
[:each |
old := collection.
collection := OrderedCollection new.
collection addFirst: old.
collection addFirst: each name].
^collection!
subclassHierarchy: aClass
"EngiClassGraph subclassHierarchy: Number."
| theClass collection subs |
aClass isMeta
ifTrue: [theClass := aClass soleInstance]
ifFalse: [theClass := aClass].
collection := OrderedCollection new.
theClass subclasses isEmpty
ifFalse:
[subs := SortedCollection sortBlock: [:x :y | x name > y name].
subs addAll: (theClass subclasses select: [:each | each isMeta not]).
subs do: [:each | collection addFirst: (self subclassHierarchy: each)]].
collection addFirst: theClass name.
^collection!
superclassHierarchy: aClass
"EngiClassGraph superclassHierarchy: Number."
| theClass collection old |
aClass isMeta
ifTrue: [theClass := aClass soleInstance]
ifFalse: [theClass := aClass].
collection := OrderedCollection new.
collection addFirst: theClass name.
(theClass allSuperclasses select: [:each | each isMeta not])
do:
[:each |
old := collection.
collection := OrderedCollection new.
collection addFirst: old.
collection addFirst: each name].
^collection! !
!EngiClassGraph class methodsFor: 'examples'!
example1
"EngiClassGraph example1."
| classGraph activeWindow activeSensor |
classGraph := EngiClassGraph fromClass: Magnitude.
activeWindow := classGraph class activeWindow.
activeWindow clear.
classGraph display.
activeSensor := activeWindow sensor.
[activeSensor anyButtonPressed] whileFalse.
activeWindow display.
^classGraph!
example2
"EngiClassGraph example2."
| classGraph graphModel |
classGraph := EngiClassGraph fromClass: Magnitude.
graphModel := EngiGraphModel on: classGraph.
graphModel windowLabel: 'Inheritance'.
graphModel open! !
EngiGraphModel subclass: #EngiClassGraphModel
instanceVariableNames: ''
classVariableNames: 'MenuForClassGraph '
poolDictionaries: ''
category: 'Engi-Inheritance'!
EngiClassGraphModel comment:
'
Engi 0.07 (24 March 1994)
Copyright (C) 1994 by Atsushi Aoki
'!
!EngiClassGraphModel methodsFor: 'displaying'!
displayAxesOn: graphicsContext at: aPoint
^self! !
!EngiClassGraphModel methodsFor: 'menu messages'!
arrangeBalance
| graph balance answer |
graph := self value.
balance := graph arrangeBalance = #balance.
answer := EngiTextModel request: 'arrange balance:' default: balance printString.
(answer isNil or: [answer isEmpty])
ifTrue: [^nil].
answer := Compiler evaluate: answer logged: false.
((answer isKindOf: Boolean)
and: [answer ~= balance])
ifTrue:
[answer
ifTrue: [graph arrangeBalance: #balance]
ifFalse: [graph arrangeBalance: #unbalance].
graph arrangeScan.
self flushBounds.
self changed: #value]!
arrangeClasses
| graph |
graph := self value.
graph arrangeScan.
self flushBounds.
self changed: #value!
arrangeInterval
| graph interval answer |
graph := self value.
interval := graph arrangeInterval.
answer := EngiTextModel request: 'arrange interval:' default: interval printString.
(answer isNil or: [answer isEmpty])
ifTrue: [^nil].
answer := Compiler evaluate: answer logged: false.
((answer isKindOf: Number)
and: [answer ~= interval])
ifTrue:
[graph arrangeInterval: (answer asInteger max: 0).
graph arrangeScan.
self flushBounds.
self changed: #value]!
arrangeMargin
| graph margin answer |
graph := self value.
margin := graph arrangeMargin.
answer := EngiTextModel request: 'arrange margin:' default: margin printString.
(answer isNil or: [answer isEmpty])
ifTrue: [^nil].
answer := Compiler evaluate: answer logged: false.
((answer isKindOf: Number)
and: [answer ~= margin])
ifTrue:
[graph arrangeMargin: (answer asInteger max: 0).
graph arrangeScan.
self flushBounds.
self changed: #value]!
browseClass
| aSymbol aClass |
self selections isEmpty ifTrue: [^nil].
self selections
do:
[:each |
aSymbol := each className asSymbol.
(Smalltalk includesKey: aSymbol)
ifTrue:
[aClass := Smalltalk at: aSymbol.
(aClass isBehavior and: [aClass isMeta not])
ifTrue: [aClass browse]]]!
yellowButtonMenu
"EngiClassGraphModel flushMenus."
MenuForClassGraph isNil
ifTrue:
[| collection menu |
collection := OrderedCollection new.
collection add: 'arrange' -> #arrangeClasses.
collection add: 'interval' -> #arrangeInterval.
collection add: 'margin' -> #arrangeMargin.
collection add: 'balance' -> #arrangeBalance.
menu := EngiMenuMaker fromCollection: collection.
collection := OrderedCollection new.
collection add: 'browse' -> #browseClass.
collection add: 'arrange' -> menu.
MenuForClassGraph := EngiMenuMaker fromCollection: collection].
^MenuForClassGraph! !
!EngiClassGraphModel methodsFor: 'defaults'!
defaultWindowLabel
^'Inheritance'! !
"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
EngiClassGraphModel class
instanceVariableNames: ''!
!EngiClassGraphModel class methodsFor: 'class initialization'!
flushMenus
"EngiClassGraphModel flushMenus."
MenuForClassGraph := nil! !
!EngiClassGraphModel class methodsFor: 'examples'!
example1
"EngiClassGraphModel example1."
| classGraph graphModel |
classGraph := EngiClassGraph fromClass: Collection.
graphModel := EngiClassGraphModel openOn: classGraph.
^graphModel!
example2
"EngiClassGraphModel example2."
| classGraph graphModel |
classGraph := EngiClassGraph fromClass: Collection.
classGraph
doVertices:
[:vertex |
vertex strokeColor: ColorValue blue.
vertex fillColor: ColorValue green].
classGraph
doBranches:
[:branch |
branch strokeColor: ColorValue red.
branch lineWidth: 2].
graphModel := EngiClassGraphModel openOn: classGraph.
^graphModel! !