ApplicationModel subclass:#UIPainter
instanceVariableNames:'objectList currentView selectionPanel tabSelection lastSlice
specView layoutTool fileName specClass specSelector
specSuperclass aspects'
classVariableNames:''
poolDictionaries:''
category:'Interface-UIPainter'
!
!UIPainter class methodsFor:'documentation'!
documentation
"
not yet finished, not yet published, not yet released.
[start with:]
UIPainter open
"
! !
!UIPainter class methodsFor:'instance creation'!
listHolder:aListHolder
|application|
application := self new.
application objectList:aListHolder.
^ application open
!
painter:aBuilderView
|application|
application := self new.
application painter:aBuilderView.
^ application open
! !
!UIPainter class methodsFor:'ST-80 queries'!
preferenceFor:aSymbol
^ false
! !
!UIPainter class methodsFor:'constants'!
titleOfLayoutMenu
^ 'Dimension'
! !
!UIPainter class methodsFor:'icons'!
iconAlignB
^ Image fromFile:'b_alignB.xbm'
!
iconAlignCenterH
^ Image fromFile:'b_alignCH.xbm'
!
iconAlignCenterV
^ Image fromFile:'b_alignCV.xbm'
!
iconAlignL
^ Image fromFile:'b_alignL.xbm'
!
iconAlignLR
^ Image fromFile:'b_alignLR.xbm'
!
iconAlignR
^ Image fromFile:'b_alignR.xbm'
!
iconAlignT
^ Image fromFile:'b_alignT.xbm'
!
iconAlignTB
^ Image fromFile:'b_alignTB.xbm'
! !
!UIPainter class methodsFor:'interface specs'!
menuAlignment
^ #(#Menu #(
#(#MenuItem
#'label:' 'align left'
#'value:' #alignSelectionLeft
#'labelImage:' #( ResourceRetriever UIPainter iconAlignL )
)
#(#MenuItem
#'label:' 'align right'
#'value:' #alignSelectionRight
#'labelImage:' #( ResourceRetriever UIPainter iconAlignR )
)
#(#MenuItem
#'label:' 'align left & right'
#'value:' #alignSelectionLeftAndRight
#'labelImage:' #( ResourceRetriever UIPainter iconAlignLR )
)
#(#MenuItem
#'label:' 'align top'
#'value:' #alignSelectionTop
#'labelImage:' #( ResourceRetriever UIPainter iconAlignT )
)
#(#MenuItem
#'label:' 'align bottom'
#'value:' #alignSelectionBottom
#'labelImage:' #( ResourceRetriever UIPainter iconAlignB )
)
#(#MenuItem
#'label:' 'align top & bottom'
#'value:' #alignSelectionTopAndBottom
#'labelImage:' #( ResourceRetriever UIPainter iconAlignTB )
)
#(#MenuItem
#'label:' 'align centered horizontal'
#'value:' #alignSelectionCenterHor
#'labelImage:' #( ResourceRetriever UIPainter iconAlignCenterH )
)
#(#MenuItem
#'label:' 'align centered vertical'
#'value:' #alignSelectionCenterVer
#'labelImage:' #( ResourceRetriever UIPainter iconAlignCenterV )
)
)
#( 4 2 )
nil
)
!
menuPullDown
^ #(#Menu #(
#(#MenuItem
#'label:' 'file'
#'value:' #file
#'submenu:'
#(#Menu #(
#(#MenuItem
#'label:' 'new'
#'value:' #removeAll
)
#(#MenuItem
#'label:' 'from class ...'
#'value:' #doFromClass
)
#(#MenuItem
#'label:' 'pick a view '
#'value:' #doPickAView
)
#(#MenuItem
#'label:' 'load'
#'value:' #doOpen
)
#(#MenuItem
#'label:' 'save'
#'value:' #doSave
)
#(#MenuItem
#'label:' 'save as ...'
#'value:' #doSaveAs
)
#(#MenuItem
#'label:' 'raise'
#'value:' #doRaise
)
#(#MenuItem
#'label:' 'quit'
#'value:' #closeRequest
)
)
#(3 3 1)
nil
)
)
#(#MenuItem
#'label:' 'font'
#'value:' #font
#'submenu:'
#(#Menu #(
#(#MenuItem
#'label:' 'larger'
#'value:' #largerFont
)
#(#MenuItem
#'label:' 'smaller'
#'value:' #smallerFont
)
#(#MenuItem
#'label:' 'normal'
#'value:' #normalFont
)
#(#MenuItem
#'label:' 'bold'
#'value:' #boldFont
)
#(#MenuItem
#'label:' 'italic'
#'value:' #italicFont
)
#(#MenuItem
#'label:' 'bold italic'
#'value:' #boldItalicFont
)
#(#MenuItem
#'label:' 'font panel'
#'value:' #showFontPanel
)
)
#(2 4)
nil
)
)
#(#MenuItem
#'label:' 'special'
#'value:' #special
#'submenu:'
#(#Menu #(
#(#MenuItem
#'label:' 'group radioButtons'
#'value:' #groupRadioButtons
)
#(#MenuItem
#'label:' 'group enterFields'
#'value:' #groupEnterFields
)
)
nil
nil
)
)
#(#MenuItem
#'label:' 'misc'
#'value:' #misc
#'submenu:'
#(#Menu #(
#(#MenuItem
#'label:' 'grid'
#'value:' #grid
#'submenu:'
#(#Menu #(
#(#MenuItem
#'label:' '\c show'
#'value:' #gridShown
)
#(#MenuItem
#'label:' '\c align'
#'value:' #gridAlign
)
)
nil
nil
)
)
#(#MenuItem
#'label:' 'undo'
#'value:' #undo
#'submenu:'
#(#Menu #(
#(#MenuItem
#'label:' 'last'
#'value:' #undoLast
)
#(#MenuItem
#'label:' 'menu'
#'value:' #openUndoMenu
)
#(#MenuItem
#'label:' 'delete'
#'value:' #removeUndoHistory
)
)
#(2)
nil
)
)
)
nil
nil
)
)
#(#MenuItem
#'label:' 'code'
#'value:' #code
#'submenu:'
#(#Menu #(
#(#MenuItem
#'label:' 'class & method'
#'value:' #defineClassAndSelector
)
#(#MenuItem
#'label:' 'install spec'
#'value:' #doInstallSpec
)
#(#MenuItem
#'label:' 'install aspects'
#'value:' #doInstallAspects
)
#(#MenuItem
#'label:' 'windowSpec'
#'value:' #doWindowSpec
)
)
#( 1 2 )
nil
)
)
#(#MenuItem
#'label:' 'test'
#'nameKey:' #test
#'value:' #test
#'submenu:'
#(#Menu #(
#(#MenuItem
#'label:' '\c test mode'
#'value:' #testMode
)
)
nil
nil
)
)
)
nil
nil
)
!
nameAndSelectorSpec
"this window spec was automatically generated by the ST/X UIPainter"
"do not manually edit this - the painter/builder may not be able to
handle the specification if its corrupted."
"
UIPainter new openOnClass:UIPainter andSelector:#nameAndSelectorSpec
UIPainter new openInterface:#nameAndSelectorSpec
"
<resource: #canvas>
^
#(#FullSpec
#'window:'
#(#WindowSpec
#'name:' 'uIPainterView'
#'layout:' #(#LayoutFrame 0 0.0 0 0.0 0 1.0 0 1.0)
#'label:' 'unnamed'
#'bounds:' #(#Rectangle 0 0 300 223)
)
#'component:'
#(#SpecCollection
#'collection:'
#(
#(#LabelSpec
#'name:' 'label1'
#'layout:' #(#LayoutFrame 10 0 50 0 110 0 70 0)
#'label:' 'class:'
#'foregroundColor:' #(#Color 0.0 0.0 0.0)
#'backgroundColor:' #(#Color 66.9993 66.9993 66.9993)
#'initiallyInvisible:' false
#'translateLabel:' false
#'level:' 0
#'adjust:' #right
#'hasCharacterOrientedLabel:' true
)
#(#LabelSpec
#'name:' 'label2'
#'layout:' #(#LayoutFrame 10 0 90 0 110 0 110 0)
#'label:' 'superclass:'
#'foregroundColor:' #(#Color 0.0 0.0 0.0)
#'backgroundColor:' #(#Color 66.9993 66.9993 66.9993)
#'initiallyInvisible:' false
#'translateLabel:' false
#'level:' 0
#'adjust:' #right
#'hasCharacterOrientedLabel:' true
)
#(#LabelSpec
#'name:' 'label3'
#'layout:' #(#LayoutFrame 10 0 130 0 110 0 150 0)
#'label:' 'selector:'
#'foregroundColor:' #(#Color 0.0 0.0 0.0)
#'backgroundColor:' #(#Color 66.9993 66.9993 66.9993)
#'initiallyInvisible:' false
#'translateLabel:' false
#'level:' 0
#'adjust:' #right
#'hasCharacterOrientedLabel:' true
)
#(#InputFieldSpec
#'name:' 'classNameField'
#'layout:' #(#LayoutFrame 120 0 50 0 289 0 72 0)
#'model:' #classNameChannel
#'tabable:' true
#'immediateAccept:' false
#'acceptOnLeave:' true
#'acceptOnReturn:' true
#'acceptOnTab:' true
#'acceptOnLostFocus:' true
#'hasBorder:' false
)
#(#InputFieldSpec
#'name:' 'superclassNameField'
#'layout:' #(#LayoutFrame 120 0 90 0 289 0 112 0)
#'model:' #superclassNameChannel
#'tabable:' true
#'immediateAccept:' false
#'acceptOnLeave:' true
#'acceptOnReturn:' true
#'acceptOnTab:' true
#'acceptOnLostFocus:' true
#'hasBorder:' false
)
#(#InputFieldSpec
#'name:' 'methodNameField'
#'layout:' #(#LayoutFrame 120 0 130 0 289 0 152 0)
#'model:' #methodNameChannel
#'tabable:' true
#'immediateAccept:' false
#'acceptOnLeave:' true
#'acceptOnReturn:' true
#'acceptOnTab:' true
#'acceptOnLostFocus:' true
#'hasBorder:' false
)
#(#ActionButtonSpec
#'name:' 'button1'
#'layout:' #(#LayoutFrame 30 0 180 0 129 0 209 0)
#'label:' 'cancel'
#'foregroundColor:' #(#Color 0.0 0.0 0.0)
#'backgroundColor:' #(#Color 66.9993 66.9993 66.9993)
#'translateLabel:' false
#'tabable:' true
#'model:' #cancel
#'isTriggerOnDown:' false
)
#(#ActionButtonSpec
#'name:' 'button2'
#'layout:' #(#LayoutFrame 160 0 180 0 259 0 209 0)
#'label:' 'ok'
#'foregroundColor:' #(#Color 0.0 0.0 0.0)
#'backgroundColor:' #(#Color 66.9993 66.9993 66.9993)
#'translateLabel:' false
#'tabable:' true
#'isDefault:' true
#'model:' #accept
#'isTriggerOnDown:' false
)
#(#LabelSpec
#'name:' 'boxLabel'
#'layout:' #(#LayoutFrame 0 0.0 11 0 0 1.0 32 0)
#'label:' 'class & selector for code:'
#'foregroundColor:' #(#Color 0.0 0.0 0.0)
#'backgroundColor:' #(#Color 66.9993 66.9993 66.9993)
#'initiallyInvisible:' false
#'translateLabel:' false
#'level:' 0
#'adjust:' #left
#'hasCharacterOrientedLabel:' true
)
)
)
)
!
windowSpec
"this window spec was automatically generated by the ST/X UIPainter"
"do not manually edit this - the painter/builder may not be able to
handle the specification if its corrupted."
"
UIPainter new openOnClass:UIPainter andSelector:#windowSpec
UIPainter new openInterface:#windowSpec
"
"UIPainter open"
<resource: #canvas>
^
#(#FullSpec
#'window:'
#(#WindowSpec
#'name:' 'uIPainterView'
#'layout:' #(#LayoutFrame 0 0.0 0 0.0 0 1.0 0 1.0)
#'label:' 'Tree-View'
#'bounds:' #(#Rectangle 0 0 460 390)
)
#'component:'
#(#SpecCollection
#'collection:'
#(
#(#ViewSpec
#'name:' 'view1'
#'layout:' #(#LayoutFrame 0 0.0 29 0.0 0 1.0 0 1.0)
#'component:'
#(#SpecCollection
#'collection:'
#(
#(#SequenceViewSpec
#'name:' 'selectionInList'
#'layout:' #(#LayoutFrame 0 0.0 40 0.0 0 0.35 0 1.0)
#'enableChannel:' #enableChannel
#'menu:' #objectListMenu
#'model:' #objectList
#'callbacksSpec:'
#(#UIEventCallbackSubSpec
#'doubleClickSelector:' #doubleClick
)
#'hasHorizontalScrollBar:' true
#'hasVerticalScrollBar:' true
#'miniScrollerHorizontal:' false
#'miniScrollerVertical:' false
#'isMultiSelect:' true
)
#(#PanelViewSpec
#'name:' 'panelViewButtons'
#'layout:' #(#LayoutFrame -130 1.0 0 0.0 0 1.0 35 0.0)
#'component:'
#(#SpecCollection
#'collection:'
#(
#(#ActionButtonSpec
#'name:' 'moveLeft'
#'label:' ''
#'translateLabel:' true
#'labelChannel:' #'LABELb_moveLeft.xbm'
#'defaultable:' true
#'model:' #moveSelectionLeft
#'isTriggerOnDown:' true
#'enableChannel:' #enableChannel
#'autoRepeat:' true
#'extent:' #(#Point 26 24)
)
#(#ActionButtonSpec
#'name:' 'moveRight'
#'label:' ''
#'translateLabel:' true
#'labelChannel:' #'LABELb_moveRight.xbm'
#'defaultable:' true
#'model:' #moveSelectionRight
#'isTriggerOnDown:' true
#'enableChannel:' #enableChannel
#'autoRepeat:' true
#'extent:' #(#Point 26 24)
)
#(#ActionButtonSpec
#'name:' 'moveUp'
#'label:' ''
#'translateLabel:' true
#'labelChannel:' #'LABELb_moveUp.xbm'
#'defaultable:' true
#'model:' #moveSelectionUp
#'isTriggerOnDown:' true
#'enableChannel:' #enableChannel
#'autoRepeat:' true
#'extent:' #(#Point 26 24)
)
#(#ActionButtonSpec
#'name:' 'moveDown'
#'label:' ''
#'translateLabel:' true
#'labelChannel:' #'LABELb_moveDown.xbm'
#'defaultable:' true
#'model:' #moveSelectionDown
#'isTriggerOnDown:' true
#'enableChannel:' #enableChannel
#'autoRepeat:' true
#'extent:' #(#Point 26 24)
)
)
)
#'level:' 1
#'horizontalLayout:' #fitSpace
#'verticalLayout:' #fitSpace
#'horizontalSpace:' 4
#'verticalSpace:' 4
)
#(#NoteBookViewSpec
#'name:' 'propertyView'
#'layout:' #(#LayoutFrame 0 0.35 40 0.0 0 1.0 -30 1.0)
#'model:' #tabModel
#'menu:' #tabList
#'tabWidget:' #Window
#'direction:' #top
#'useIndex:' false
#'fitLastRow:' true
#'moveSelectedRow:' true
#'enableChannel:' #enableChannel
#'level:' 0
#'canvas:' #noteBookView
)
#(#HorizontalPanelViewSpec
#'name:' 'hrzPanelViewOk'
#'layout:' #(#LayoutFrame 0 0.35 -30 1.0 0 1.0 0 1.0)
#'component:'
#(#SpecCollection
#'collection:'
#(
#(#ActionButtonSpec
#'name:' 'cancelButton'
#'label:' 'cancel'
#'model:' #cancel
#'isTriggerOnDown:' false
#'enableChannel:' #modifiedChannel
#'autoRepeat:' false
#'extent:' #(#Point 145 24)
)
#(#ActionButtonSpec
#'name:' 'acceptButton'
#'label:' 'ok'
#'model:' #accept
#'isTriggerOnDown:' false
#'enableChannel:' #modifiedChannel
#'autoRepeat:' false
#'extent:' #(#Point 145 24)
)
)
)
#'level:' 0
#'horizontalLayout:' #fitSpace
#'verticalLayout:' #fitSpace
#'horizontalSpace:' 3
#'verticalSpace:' 3
)
#(#MenuPanelSpec
#'name:' 'menuPanel1'
#'layout:' #(#LayoutFrame 0 0.0 0 0.0 -226 1.0 25 0)
#'menu:' #menuAlignment
#'showSeparatingLines:' true
#'verticalLayout:' false
#'fitFirstPanel:' true
)
)
)
)
#(#MenuPanelSpec
#'name:' 'menuBar1'
#'layout:' #(#LayoutFrame 0 0.0 0 0.0 0 1.0 24 0)
#'menu:' #menuPullDown
#'showSeparatingLines:' false
#'verticalLayout:' false
#'fitFirstPanel:' true
)
)
)
)
! !
!UIPainter methodsFor:'actions'!
accept
"automatically generated by UIPainter ..."
|layout|
currentView notNil ifTrue:[
tabSelection = 'Dimension' ifTrue:[
(layout := layoutTool layout) notNil ifTrue:[
layoutTool layoutType == #Extent ifTrue:[
self painter setExtent:layout
] ifFalse:[
self painter setDimension:layout
]
]
] ifFalse:[
self painter updateFromSpec:(specView specEdited).
].
self cancel
]
!
cancel
"cancel all changes and read back attributes from current view
"
specView specEdited:(self painter specFor:currentView).
layoutTool forView:currentView.
self modifiedChannel value:false.
! !
!UIPainter methodsFor:'aspects'!
doubleClick
objectList selectGroup
!
enableChannel
"true if modifications are allowed otherwise running test
"
^ self painter enableChannel
!
menuAlignment
|menu channel|
channel := self enableChannel.
menu := Menu new.
menu fromLiteralArrayEncoding:(self class menuAlignment).
menu receiver:self.
menu menuItems do:[:anItem| anItem enabled:channel].
^ menu
!
menuPullDown
|menu channel|
channel := self enableChannel.
menu := Menu new.
menu fromLiteralArrayEncoding:(self class menuPullDown).
menu receiver:self.
menu menuItems do:[:anItem|
anItem nameKey ~~ #test ifTrue:[anItem enabled:channel]
].
^ menu
!
modifiedChannel
|holder|
(holder := builder bindingAt:#modifiedChannel) isNil ifTrue:[
builder aspectAt:#modifiedChannel put:(holder := false asValue).
].
^ holder
!
noteBookView
"automatically generated by UIPainter ..."
|noteBook channel|
(noteBook := builder bindingAt:#noteBookView) isNil ifTrue:[
noteBook := View origin:0.0 @0.0 corner:1.0@1.0.
layoutTool := UIPropertyView for:#Dimension in:noteBook.
specView := UIPropertyView for:#Specification in:noteBook.
channel := self modifiedChannel.
layoutTool modifiedHolder:channel.
specView modifiedHolder:channel.
specView viewBackground:(layoutTool viewBackground).
builder aspectAt:#noteBookView put:noteBook.
].
^ noteBook
!
objectList
^ objectList
!
objectListMenu
"returns a block which returns the menu
!!hack!!
"
^ [ self painter showMiddleButtonMenu ].
!
tabList
"automatically generated by UIPainter ..."
|holder|
(holder := builder bindingAt:#tabList) isNil ifTrue:[
builder aspectAt:#tabList put:(holder := ValueHolder new).
].
^ holder
!
tabModel
"automatically generated by UIPainter ..."
|holder|
(holder := builder bindingAt:#tabModel) isNil ifTrue:[
lastSlice := 'Basics'.
holder := AspectAdaptor new subject:self; forAspect:#tabSelection.
builder aspectAt:#tabModel put:holder.
].
^ holder
! !
!UIPainter methodsFor:'binding access'!
aspectFor:aKey
"check wether aspect is assigned to a label icon
"
(aKey startsWith:'LABEL') ifFalse:[
^ aspects at:aKey ifAbsent:[ super aspectFor:aKey ]
].
^ Image fromFile:(aKey copyFrom:(('LABEL' size) + 1))
! !
!UIPainter methodsFor:'change & update'!
update:something with:aParameter from:someObject
(someObject == objectList and:[something ~~ #list]) ifTrue:[
something ~~ #layout ifTrue:[
self objectListChanged
] ifFalse:[
(self modifiedChannel value) ifFalse:[
layoutTool forView:currentView
]
]
]
! !
!UIPainter methodsFor:'event handling'!
doesNotUnderstand:aMessage
|painter|
painter := self painter.
(painter respondsTo:(aMessage selector)) ifTrue:[
^ aMessage sendTo:painter
].
self error
!
objectListChanged
"something changed in the painter view
"
|setSel slices list spec props|
props := objectList selectedProperty.
tabSelection := nil.
props isNil ifFalse:[
currentView := props view.
layoutTool forView:currentView.
spec := props spec copy.
slices := spec class slices.
list := slices collect:[:slice| slice first asString ].
list add:'Dimension'.
(self tabList) value:list.
(list findFirst:[:aName| aName = lastSlice]) ~~ 0 ifTrue:[
setSel := lastSlice
]
] ifTrue:[
layoutTool forView:nil
].
specView specEdited:spec.
self tabModel value:setSel.
! !
!UIPainter methodsFor:'file access'!
openFile:aFileName
|aStream |
aStream := FileStream readonlyFileNamed:aFileName.
aStream notNil ifTrue:[
self painter fileInContentsFrom:aStream.
aStream close.
fileName := aFileName
]
!
saveAs:aFileName
|aStream|
aStream := FileStream newFileNamed:aFileName.
aStream notNil ifTrue:[
self painter storeContentsOn:aStream.
aStream close.
fileName := aFileName
].
! !
!UIPainter methodsFor:'private'!
painter
^ objectList painter
! !
!UIPainter methodsFor:'selection'!
tabSelection
^ tabSelection
!
tabSelection:something
|specEdited slices spec idx|
something isNil ifTrue:[^ self].
tabSelection := something.
(specEdited := specView specEdited) notNil ifTrue:[
slices := specEdited class slices.
lastSlice := tabSelection.
idx:= slices findFirst:[:aSlice| aSlice first = tabSelection ].
idx == 0 ifTrue:[
layoutTool forView:currentView.
^ layoutTool raise.
].
spec := specEdited class perform:((slices at:idx) last).
].
specView raise.
specEdited isNil ifTrue:[
specView buildFromSpec:nil
] ifFalse:[
specView buildFromSpec:spec
]
! !
!UIPainter methodsFor:'startup / release'!
closeRequest
"close all windows open by builder
"
objectList removeDependent:self.
objectList painter release.
objectList := nil.
selectionPanel notNil ifTrue:[
selectionPanel closeRequest
].
super closeRequest.
!
closeRequestFor:aTopView
"handle a close request for a specific view
"
|topView|
topView := self window.
topView == aTopView ifTrue:[
super closeRequestFor:aTopView
] ifFalse:[
(selectionPanel notNil and:[aTopView == selectionPanel window]) ifTrue:[
aTopView application:nil.
aTopView terminate.
selectionPanel := nil.
] ifFalse:[
topView raise.
topView device beep
]
].
!
openInterface
"open interfaces
"
|painterView painter cls topView|
aspects := IdentityDictionary new.
aspects at:#classNameChannel put:(
(specClass notNil ifTrue:[specClass]
ifFalse:['NewApplication']) asValue
).
specSuperclass isNil ifTrue:[
specClass notNil ifTrue:[
(cls := Smalltalk at:specClass asSymbol) notNil ifTrue:[
specSuperclass := cls superclass name.
]
]
].
aspects at:#superclassNameChannel put:(
(specSuperclass notNil ifTrue:[specSuperclass]
ifFalse:['ApplicationModel']) asValue
).
aspects at:#methodNameChannel put:(
(specSelector notNil ifTrue:[specSelector]
ifFalse:[#windowSpec]) asValue
).
painterView := StandardSystemView new.
painterView label:'unnamed'.
painterView extent:300@300.
painter := UIPainterView in:painterView.
painter layout:(0.0 @ 0.0 corner:1.0 @ 1.0) asLayout.
objectList := painter listHolder.
objectList addDependent:self.
super openInterface.
topView := self window.
topView label:'Interface Builder'.
topView icon:(Image fromFile:'bitmaps/Builder.xbm' resolution:100).
painterView openInGroup:(topView windowGroup).
topView beMaster.
painterView beSlave.
painterView application:self.
painterView open.
selectionPanel := UISelectionPanel open.
selectionPanel window beSlave.
selectionPanel window application:self.
!
openNewWindowCanvas
"open new
"
self open.
!
openOnClass:aClass
"open up an interface builder
"
self openOnClass:aClass andSelector:#windowSpec
!
openOnClass:aClass andSelector:aSelector
"open up an interface builder, fetching a spec from someClass
via some selector
"
|painter|
self openInterface.
painter := self painter.
specClass := aClass name.
specSuperclass := aClass superclass name.
specSelector := aSelector.
painter className:aClass name.
painter methodName:aSelector.
painter setupFromSpec:(aClass perform:aSelector).
! !
!UIPainter methodsFor:'user interaction - dialog'!
checkClassAndSelector
"check for class & superclass"
|superclass cls|
specClass isNil ifTrue:[^ false].
specClass isBehavior ifFalse:[
cls := Smalltalk at:specClass asSymbol
] ifTrue:[
cls := specClass
].
cls isNil ifTrue:[
(superclass := Smalltalk at:specSuperclass asSymbol) isNil ifTrue:[
self warn:'no class named ' , specSuperclass , ' exists.'.
^ false.
].
(self confirm:'create ' , specClass , ' ?') ifTrue:[
superclass subclass:(specClass asSymbol)
instanceVariableNames:''
classVariableNames:''
poolDictionaries:''
category:'New-Applications'.
^ true.
].
^ false.
].
cls isBehavior ifFalse:[
self warn:'a global named ' , specClass , ' exists, but is no class.'.
^ false.
].
specSuperclass isBehavior ifFalse:[
superclass := Smalltalk at:specSuperclass asSymbol
] ifTrue:[
superclass := specSuperclass
].
specSuperclass notNil ifTrue:[
superclass isNil ifTrue:[
self warn:'no class named ' , specSuperclass , ' exists.'.
^ false.
].
(cls isSubclassOf:superclass) ifFalse:[
self warn:'a global named ' , specClass , ' exists, but is not a subclass of ' , superclass name , '.'.
^ false.
]
].
^ true
!
defineClassAndSelector
"launch a dialog to define class, superclass and method"
|again|
[
again := false.
(self openDialogInterface:#nameAndSelectorSpec) ifTrue:[
specClass := (self aspectFor:#classNameChannel) value.
specSelector := (self aspectFor:#methodNameChannel) value.
specSuperclass := (self aspectFor:#superclassNameChannel) value.
(again := self checkClassAndSelector not) ifFalse:[
self painter className:specClass
superclassName:specSuperclass
selector:specSelector.
]
]
] doWhile:[again]
! !
!UIPainter methodsFor:'user interaction - pullDown'!
doFromClass
|className methodName cls sel accepted failed spec s painter|
className := '' asValue.
methodName := '' asValue.
painter := self painter.
(s := painter className) notNil ifTrue:[
className value:s
].
(s := painter methodName) notNil ifTrue:[
methodName value:s
].
failed := false.
[
accepted :=
(DialogBox new
addTextLabel:'Classes name:';
addInputFieldOn:className;
addVerticalSpace;
addTextLabel:'methods name:';
addInputFieldOn:methodName;
addAbortButton;
addOkButton;
open
) accepted.
accepted ifTrue:[
cls := Smalltalk classNamed:className value.
cls isNil ifTrue:[
failed := true.
self warn:'no such class'.
] ifFalse:[
sel := methodName value asSymbol.
(cls respondsTo:sel ) ifFalse:[
failed := true.
self warn:'no such method'
] ifTrue:[
spec := cls perform:sel.
spec isArray ifFalse:[
failed := true.
self warn:'not a windowSpec method'
].
"/ ok, got it
painter className:className value.
painter methodName:methodName value.
painter setupFromSpec:spec.
^ self
]
]
]
] doWhile:[accepted and:[failed]].
!
doInstallAspects
|code|
(specClass isNil or:[specSelector isNil]) ifTrue:[
self defineClassAndSelector
].
self checkClassAndSelector ifFalse:[
^ self
].
self painter className:specClass
superclassName:specSuperclass
selector:specSelector.
code := self painter generateAspectMethods.
(ReadStream on:code) fileIn.
!
doInstallSpec
|code|
(specClass isNil or:[specSelector isNil]) ifTrue:[
self defineClassAndSelector
].
self checkClassAndSelector ifFalse:[
^ self
].
self painter className:specClass
superclassName:specSuperclass
selector:specSelector.
code := self painter generateCode.
(ReadStream on:code) fileIn.
!
doOpen
|box|
box := FileSelectionBox new.
box title:(resources string:'Which file ?').
box selectingDirectory:false.
box pattern:'*.*'.
box action:[:aFile| self openFile:aFile ].
box open
!
doPickAView
|painter view className methodName cls sel accepted spec s|
(view := Display viewFromUser) notNil ifTrue:[
painter := self painter.
spec := UISpecification fromView:view topView.
"/ ok, got it
painter setupFromSpec:spec.
painter className:view class name.
painter methodName:#newSpec.
]
!
doRaise
self painter topView raise.
selectionPanel notNil ifTrue:[
selectionPanel window raise
]
!
doSave
fileName notNil ifTrue:[
self saveAs:fileName
] ifFalse:[
self doSaveAs
]
!
doSaveAs
|box|
box := FileSelectionBox new.
box title:(resources string:'Which file ?').
box selectingDirectory:false.
box pattern:'*.*'.
box action:[:aFile| self saveAs:aFile ].
box open
!
doWindowSpec
|code code2 v|
code := self painter generateWindowSpecMethodSource.
v := CodeView open.
v contents:code.
v label:'windowSpec'.
! !
!UIPainter class methodsFor:'documentation'!
version
^ '$Header$'
! !