"
COPYRIGHT (c) 1995 by eXept Software AG
All Rights Reserved
This software is furnished under a license and may be used
only in accordance with the terms of that license and with the
inclusion of the above copyright notice. This software may not
be provided or otherwise made available to, or used by, any
other person. No title to or ownership of the software is
hereby transferred.
"
ApplicationModel subclass:#UIPainter
instanceVariableNames:'activeHelpTool layoutTool specTool objectList selectionPanel
tabSelection specClass specSelector specSuperclass aspects'
classVariableNames:''
poolDictionaries:''
category:'Interface-UIPainter'
!
!UIPainter class methodsFor:'documentation'!
copyright
"
COPYRIGHT (c) 1995 by eXept Software AG
All Rights Reserved
This software is furnished under a license and may be used
only in accordance with the terms of that license and with the
inclusion of the above copyright notice. This software may not
be provided or otherwise made available to, or used by, any
other person. No title to or ownership of the software is
hereby transferred.
"
!
documentation
"
GUI-Builder:
this class allows the user to build its own applications providing a graphical
user interface to buildin components and to define the behavior of the components
during runtime. The resulting specifications can be installed as methods on
classes, typically subclasses of an ApplicationModel. These specifications
are used by the UIBuilder to generate the application window and its component
structues when open the application.
[start with:]
UIPainter open
[author:]
Claus Gittinger
Claus Atzkern
[see also:]
UIBuilder
ApplicationModel
UISpecification
"
! !
!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:'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 nil iconAlignL )
)
#(#MenuItem
#'label:' 'align right'
#'value:' #alignSelectionRight
#'labelImage:' #( ResourceRetriever nil iconAlignR )
)
#(#MenuItem
#'label:' 'align left & right'
#'value:' #alignSelectionLeftAndRight
#'labelImage:' #( ResourceRetriever nil iconAlignLR )
)
#(#MenuItem
#'label:' 'align top'
#'value:' #alignSelectionTop
#'labelImage:' #( ResourceRetriever nil iconAlignT )
)
#(#MenuItem
#'label:' 'align bottom'
#'value:' #alignSelectionBottom
#'labelImage:' #( ResourceRetriever nil iconAlignB )
)
#(#MenuItem
#'label:' 'align top & bottom'
#'value:' #alignSelectionTopAndBottom
#'labelImage:' #( ResourceRetriever nil iconAlignTB )
)
#(#MenuItem
#'label:' 'align centered horizontal'
#'value:' #alignSelectionCenterHor
#'labelImage:' #( ResourceRetriever nil iconAlignCenterH )
)
#(#MenuItem
#'label:' 'align centered vertical'
#'value:' #alignSelectionCenterVer
#'labelImage:' #( ResourceRetriever nil iconAlignCenterV )
)
)
#( 3 3 )
nil
)
!
menuPullDown
^ #(#Menu #(
#(#MenuItem
#'label:' 'file'
#'value:' #file
#'submenu:'
#(#Menu #(
#(#MenuItem
#'label:' 'new'
#'value:' #doNew
)
#(#MenuItem
#'label:' 'from class ...'
#'value:' #doFromClass
)
#(#MenuItem
#'label:' 'pick a view '
#'value:' #doPickAView
)
#(#MenuItem
#'label:' 'raise'
#'value:' #doRaise
)
#(#MenuItem
#'label:' 'quit'
#'value:' #closeRequest
)
)
#(3 1)
nil
)
)
#(#MenuItem
#'label:' 'misc'
#'value:' #misc
#'submenu:'
#(#Menu #(
#(#MenuItem
#'label:' 'grid'
#'value:' #grid
#'submenu:'
#(#Menu #(
#(#MenuItem
#'label:' 'show'
#'indication:' #gridShown:
)
#(#MenuItem
#'label:' 'align'
#'indication:' #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 help spec'
#'value:' #doInstallHelp
)
#(#MenuItem
#'label:' 'install aspects'
#'value:' #doInstallAspects
)
#(#MenuItem
#'label:' 'show windowSpec'
#'value:' #doWindowSpec
)
#(#MenuItem
#'label:' 'browse application'
#'value:' #doBrowseAppClass
)
#(#MenuItem
#'label:' 'start application'
#'value:' #doStartApplication
)
)
#( 1 3 1)
nil
)
)
#(#MenuItem
#'label:' 'test'
#'nameKey:' #test
#'value:' #test
#'submenu:'
#(#Menu #(
#(#MenuItem
#'label:' 'test mode'
#'indication:' #testMode:
)
)
nil
nil
)
)
)
nil
nil
)
"Modified: 17.6.1997 / 12:30:17 / cg"
!
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:' 'Painter'
#'bounds:' #(#Rectangle 0 0 391 170)
)
#'component:'
#(#SpecCollection
#'collection:'
#(
#(#LabelSpec
#'name:' 'classLabel'
#'layout:' #(#AlignmentOrigin 45 0.11 51 0 1 0.5)
#'label:' 'class:'
#'adjust:' #right
#'resizeForLabel:' true
)
#(#LabelSpec
#'name:' 'superClassLabel'
#'layout:' #(#AlignmentOrigin 45 0.11 77 0 1 0.5)
#'label:' 'superclass:'
#'adjust:' #right
#'resizeForLabel:' true
)
#(#LabelSpec
#'name:' 'selectorLabel'
#'layout:' #(#AlignmentOrigin 45 0.11 105 0 1 0.5)
#'label:' 'selector:'
#'adjust:' #right
#'resizeForLabel:' true
)
#(#InputFieldSpec
#'name:' 'methodNameField'
#'layout:' #(#LayoutFrame 47 0.11 95 0 -5 1.0 117 0)
#'tabable:' true
#'model:' #methodNameChannel
)
#(#LabelSpec
#'name:' 'boxLabel'
#'layout:' #(#Point 5 10)
#'label:' 'class & selector for code:'
#'adjust:' #left
#'resizeForLabel:' true
)
#(#InputFieldSpec
#'name:' 'classNameField'
#'layout:' #(#LayoutFrame 47 0.11 39 0 -5 1.0 61 0)
#'tabable:' true
#'model:' #classNameChannel
)
#(#ComboBoxSpec
#'name:' 'comboBox1'
#'layout:' #(#LayoutFrame 47 0.11 67 0 -5 1.0 89 0)
#'tabable:' true
#'model:' #superclassNameChannel
#'comboList:' #superclassNameDefaults
)
#(#HorizontalPanelViewSpec
#'name:' 'commitPanel'
#'layout:' #(#LayoutFrame 0 0.0 -24 1.0 0 1.0 0 1.0)
#'component:'
#(#SpecCollection
#'collection:'
#(
#(#ActionButtonSpec
#'name:' 'button1'
#'label:' 'cancel'
#'tabable:' true
#'model:' #cancel
#'extent:' #(#Point 191 24)
)
#(#ActionButtonSpec
#'name:' 'button2'
#'label:' 'ok'
#'tabable:' true
#'isDefault:' true
#'model:' #accept
#'extent:' #(#Point 191 24)
)
)
)
#'horizontalLayout:' #fitSpace
#'verticalLayout:' #fit
#'horizontalSpace:' 3
#'verticalSpace:' 3
)
)
)
)
"Modified: 24.6.1997 / 18:50:14 / cg"
!
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
#'flags:' 0
#'window:'
#(#WindowSpec
#'name:' 'uIPainterView'
#'layout:' #(#LayoutFrame 0 0.0 0 0.0 0 1.0 0 1.0)
#'flags:' 0
#'label:' 'Tree-View'
#'bounds:' #(#Rectangle 0 0 524 456)
)
#'component:'
#(#SpecCollection
#'collection:'
#(
#(#MenuPanelSpec
#'name:' 'menuPullDown'
#'layout:' #(#LayoutFrame 0 0.0 0 0.0 0 1.0 25 0)
#'flags:' 0
#'tabable:' true
#'menu:' #menuPullDown
)
#(#MenuPanelSpec
#'name:' 'menuAlignment'
#'layout:' #(#LayoutFrame 0 0.0 29 0 233 0 54 0)
#'flags:' 0
#'tabable:' true
#'menu:' #menuAlignment
#'showSeparatingLines:' true
)
#(#PanelViewSpec
#'name:' 'panelViewButtons'
#'layout:' #(#LayoutFrame -125 1.0 25 0.0 0 1.0 57 0.0)
#'flags:' 0
#'component:'
#(#SpecCollection
#'collection:'
#(
#(#ActionButtonSpec
#'name:' 'moveLeft'
#'flags:' 0
#'label:' ''
#'translateLabel:' true
#'labelChannel:' #'LABELb_moveLeft.xbm'
#'tabable:' true
#'defaultable:' true
#'model:' #moveSelectionLeft
#'isTriggerOnDown:' true
#'enableChannel:' #enableChannel
#'extent:' #(#Point 26 24)
)
#(#ActionButtonSpec
#'name:' 'moveRight'
#'flags:' 0
#'label:' ''
#'translateLabel:' true
#'labelChannel:' #'LABELb_moveRight.xbm'
#'tabable:' true
#'defaultable:' true
#'model:' #moveSelectionRight
#'isTriggerOnDown:' true
#'enableChannel:' #enableChannel
#'extent:' #(#Point 26 24)
)
#(#ActionButtonSpec
#'name:' 'moveUp'
#'flags:' 0
#'label:' ''
#'translateLabel:' true
#'labelChannel:' #'LABELb_moveUp.xbm'
#'tabable:' true
#'defaultable:' true
#'model:' #moveSelectionUp
#'isTriggerOnDown:' true
#'enableChannel:' #enableChannel
#'extent:' #(#Point 26 24)
)
#(#ActionButtonSpec
#'name:' 'moveDown'
#'flags:' 0
#'label:' ''
#'translateLabel:' true
#'labelChannel:' #'LABELb_moveDown.xbm'
#'tabable:' true
#'defaultable:' true
#'model:' #moveSelectionDown
#'isTriggerOnDown:' true
#'enableChannel:' #enableChannel
#'extent:' #(#Point 26 24)
)
)
)
#'level:' 1
#'horizontalLayout:' #fitSpace
#'verticalLayout:' #fitSpace
#'horizontalSpace:' 4
#'verticalSpace:' 4
)
#(#SequenceViewSpec
#'name:' 'objectTree'
#'layout:' #(#LayoutFrame 0 0.0 59 0.0 0 0.35 -25 1.0)
#'flags:' 0
#'enableChannel:' #enableChannel
#'tabable:' true
#'menu:' #objectListMenu
#'model:' #objectList
#'hasHorizontalScrollBar:' true
#'hasVerticalScrollBar:' true
#'miniScrollerHorizontal:' true
#'isMultiSelect:' true
#'doubleClickSelector:' #doubleClick
#'useIndex:' true
)
#(#NoteBookViewSpec
#'name:' 'noteBook'
#'layout:' #(#LayoutFrame 0 0.35 59 0.0 0 1.0 -55 1.0)
#'flags:' 0
#'enableChannel:' #enableChannel
#'tabable:' true
#'menu:' #tabList
#'style:'
#(#FontDescription
#helvetica #medium
#roman #'10'
)
#'model:' #tabModel
#'tabWidget:' #Window
#'canvas:' #noteBookView
)
#(#HorizontalPanelViewSpec
#'name:' 'modifyPanel'
#'layout:' #(#LayoutFrame 0 0.35 -55 1.0 0 1.0 -25 1.0)
#'flags:' 0
#'component:'
#(#SpecCollection
#'collection:'
#(
#(#ActionButtonSpec
#'name:' 'cancelButton'
#'flags:' 0
#'label:' 'cancel'
#'tabable:' true
#'model:' #cancel
#'enableChannel:' #modifiedChannel
#'extent:' #(#Point 166 24)
)
#(#ActionButtonSpec
#'name:' 'acceptButton'
#'flags:' 0
#'label:' 'ok'
#'tabable:' true
#'model:' #accept
#'enableChannel:' #modifiedChannel
#'extent:' #(#Point 166 24)
)
)
)
#'level:' 0
#'horizontalLayout:' #fitSpace
#'verticalLayout:' #fitSpace
#'horizontalSpace:' 3
#'verticalSpace:' 3
)
#(#LabelSpec
#'name:' 'helpInfo'
#'layout:' #(#LayoutFrame 2 0.0 -25 1.0 -2 1.0 -2 1.0)
#'flags:' 0
#'label:' ''
#'level:' -1
#'adjust:' #left
)
#(#ToggleSpec
#'name:' 'galleryLabel'
#'layout:' #(#LayoutFrame -162 1.0 1 0 -82 1.0 23 0)
#'flags:' 0
#'label:' 'Gallery'
#'model:' #galleryShown
#'isTriggerOnDown:' true
#'showLamp:' true
#'lampColor:' #(#Color 100.0 100.0 0.0)
)
#(#ToggleSpec
#'name:' 'painterLabel'
#'layout:' #(#LayoutFrame -81 1.0 1 0 -1 1.0 23 0)
#'flags:' 0
#'label:' 'Painter'
#'model:' #painterShown
#'isTriggerOnDown:' true
#'showLamp:' true
#'lampColor:' #(#Color 100.0 100.0 0.0)
)
)
)
)
! !
!UIPainter methodsFor:'actions'!
accept
|layout|
objectList removeDependent:self.
self isLayoutToolSelected ifTrue:[
(layout := layoutTool layout) notNil ifTrue:[
layoutTool layoutType == #Extent ifTrue:[
self painter setExtent:layout
] ifFalse:[
self painter setLayout:layout
]
]
] ifFalse:[
self isHelpToolSelected ifTrue:[
activeHelpTool accept
].
self painter updateFromSpec:(specTool specification).
].
self modifiedChannel value:false.
objectList addDependent:self.
!
cancel
"cancel all changes and read back attributes from current view
"
self modifiedChannel value ifTrue:[
specTool specification:(self painter specForSelection).
layoutTool layoutView:(layoutTool layoutView).
self modifiedChannel value:false.
]
!
doubleClick
objectList selectGroup
! !
!UIPainter methodsFor:'active help'!
activeHelpApplicationClass
"gets application class keeping the associated help component
"
|cls|
specClass notNil ifTrue:[
specClass isBehavior ifFalse:[cls := Smalltalk at:specClass asSymbol]
ifTrue:[cls := specClass].
(cls isSubclassOf:UISpecification) ifTrue:[
cls := UISpecificationTool
]
].
^ cls
!
activeHelpTool
|cls|
activeHelpTool isNil ifTrue:[
activeHelpTool := UIHelpTool new.
(cls := self activeHelpApplicationClass) notNil ifTrue:[
activeHelpTool dictionary:(cls helpSpec).
]
].
^ activeHelpTool
!
showHelp:aHelpText for:view
"hook to allow an application to display active help
texts in its own info area.
This method may be redefined in a concrete application.
If it returns false, the ActiveHelp manager will popup a
bubble with the help text."
|l|
(l := self builder componentAt:#helpInfo) notNil ifTrue:[
aHelpText replaceAll:(Character cr) by:(Character space).
l label:aHelpText.
^ true.
].
^ false
! !
!UIPainter methodsFor:'aspects'!
enableChannel
"true if modifications are allowed otherwise running test
"
^ self painter enableChannel
!
galleryShown
|holder|
(holder := builder bindingAt:#galleryShown) isNil ifTrue:[
builder aspectAt:#galleryShown put:(holder := true asValue).
holder addDependent:self
].
^ holder
!
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]
ifFalse:[anItem value: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 n1 n2|
(noteBook := builder bindingAt:#noteBookView) isNil ifTrue:[
noteBook := View new.
layoutTool := UILayoutTool new.
specTool := UISpecificationTool new.
channel := self modifiedChannel.
layoutTool masterApplication:self.
specTool masterApplication:self.
n1 := SubCanvas origin:0.0@0.0 corner:1.0@1.0 in:noteBook.
n2 := SubCanvas origin:0.0@0.0 corner:1.0@1.0 in:noteBook.
n1 client:layoutTool.
specTool builder:(n2 client:specTool).
layoutTool masterApplication:self.
specTool masterApplication:self.
layoutTool modifiedHolder:channel.
specTool modifiedHolder:channel.
builder aspectAt:#noteBookView put:noteBook.
].
^ noteBook
!
objectList
^ objectList
!
objectListMenu
"returns a block which returns the menu
!!hack!!
"
^ [ self painter showMiddleButtonMenu ].
!
painterShown
|holder|
(holder := builder bindingAt:#painterShown) isNil ifTrue:[
builder aspectAt:#painterShown put:(holder := true asValue).
holder addDependent:self
].
^ holder
!
tabList
"automatically generated by UIPainter ..."
|holder|
(holder := builder bindingAt:#tabList) isNil ifTrue:[
builder aspectAt:#tabList put:(holder := ValueHolder new).
holder value:#( 'Properties' ).
].
^ holder
!
tabModel
"automatically generated by UIPainter ..."
|holder|
(holder := builder bindingAt:#tabModel) isNil ifTrue:[
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 ifTrue:[
^ self
].
layoutTool update
].
^ self modifiedChannel value:false
].
self galleryShown == someObject ifTrue:[
(self galleryShown value) ifTrue:[
self raiseUIView:(selectionPanel window)
] ifFalse:[
self hideUIView:(selectionPanel window)
].
^ self
].
self painterShown == someObject ifTrue:[
(self painterShown value) ifTrue:[
self raiseUIView:(self painter topView)
] ifFalse:[
self hideUIView:(self painter topView)
].
^ self
].
! !
!UIPainter methodsFor:'event handling'!
doesNotUnderstand:aMessage
|painter|
painter := self painter.
(painter respondsTo:(aMessage selector)) ifTrue:[
^ aMessage sendTo:painter
].
super doesNotUnderstand:aMessage
!
objectListChanged
"something changed in the painter view
"
|oldSelection view slices list spec props size nameOfSpec|
props := objectList selectedProperty.
oldSelection := tabSelection.
tabSelection := nil.
props isNil ifFalse:[
view := props view.
spec := props spec copy.
layoutTool layoutView == view ifFalse:[
slices := spec class slices.
size := slices size + 1.
list := Array new:size.
slices keysAndValuesDo:[:i :s|list at:i put:(s first asString)].
list at:size put:(layoutTool class label).
(self tabList) value:list.
] ifTrue:[
list := self tabList value
].
(list findFirst:[:n| n = oldSelection ]) ~~ 0 ifTrue:[
tabSelection := oldSelection
] ifFalse:[
tabSelection := list first
].
nameOfSpec := spec class name.
] ifTrue:[
nameOfSpec := ''
].
self showHelp:nameOfSpec for:nil.
layoutTool layoutView:view.
specTool specification:spec.
tabSelection notNil ifTrue:[
self isLayoutToolSelected ifTrue:[
(self noteBookView subViews at:1) raise
] ifFalse:[
specTool selection:tabSelection.
(self noteBookView subViews at:2) raise
]
].
(builder componentAt:#noteBook) setSelection:tabSelection.
self modifiedChannel value:false.
! !
!UIPainter methodsFor:'private'!
hideUIView:aView
aView beIndependent.
aView unmap.
!
painter
^ objectList painter
!
raiseUIView:aView
aView map.
aView bePartner.
!
setClass:cls selector:selector
|clsName superClassName|
clsName := cls name.
superClassName := cls superclass name.
(self aspectFor:#classNameChannel) value:clsName.
(self aspectFor:#methodNameChannel) value:(selector ? '').
(self aspectFor:#superclassNameChannel) value:superClassName.
self painter
className:clsName
superclassName:superClassName
selector:(selector ? '').
specClass := clsName.
specSelector := (selector ? '').
specSuperclass := superClassName.
"Modified: 24.6.1997 / 19:07:01 / cg"
! !
!UIPainter methodsFor:'queries'!
isHelpToolSelected
^ tabSelection = 'Help'
!
isLayoutToolSelected
^ tabSelection = layoutTool class label
! !
!UIPainter methodsFor:'selection'!
tabSelection
^ tabSelection
!
tabSelection:something
|raiseViewIdx|
something notNil ifTrue:[
raiseViewIdx := 1.
tabSelection := something.
self isLayoutToolSelected ifFalse:[
specTool selection:tabSelection.
raiseViewIdx := 2
].
(self noteBookView subViews at:raiseViewIdx) raise.
self cancel.
]
! !
!UIPainter methodsFor:'startup / release'!
closeRequest
"close all windows open by builder
"
|anyUnsavedChanges|
objectList painter isModified ifTrue:[
(self confirm:'quit without saving ?') ifFalse:[
^ self
]
].
objectList removeDependent:self.
objectList painter release.
selectionPanel notNil ifTrue:[
selectionPanel masterApplication:nil.
selectionPanel closeRequest
].
selectionPanel := nil.
layoutTool := nil.
objectList := nil.
activeHelpTool := nil.
super closeRequest.
!
closeRequestFor:aTopView
"handle a close request for a specific view
"
|topView|
topView := self window.
topView == aTopView ifTrue:[
super closeRequestFor:aTopView
] ifFalse:[
aTopView = selectionPanel window ifTrue:[
self galleryShown value:false
] ifFalse:[
self painterShown value:false
].
topView raise.
].
!
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:#superclassNameDefaults put:#('ApplicationModel' 'SimpleDialog') asValue.
aspects at:#methodNameChannel put:(
(specSelector notNil ifTrue:[specSelector asValue]
ifFalse:[#windowSpec]) asValue
).
painterView := StandardSystemView new.
painterView label:'unnamed canvas'.
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 bePartner.
topView label:'Interface Builder'.
topView icon:(Image fromFile:'bitmaps/Builder.xbm' resolution:100).
painterView openInGroup:(topView windowGroup).
painterView bePartner.
painterView application:self.
painterView open.
painterView application:self.
selectionPanel := UISelectionPanel new.
selectionPanel allButOpenInterface:#windowSpec.
selectionPanel window openInGroup:(topView windowGroup).
selectionPanel window bePartner.
selectionPanel openWindow.
selectionPanel masterApplication: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|
aClass isNil ifTrue:[
self warn:'nil class given (class was probably renamed ?)'.
].
self openInterface.
aClass notNil ifTrue:[
painter := self painter.
self setClass:aClass selector:aSelector.
"/ specClass := aClass name.
"/ specSuperclass := aClass superclass name.
"/ specSelector := aSelector.
"/
"/ (aspects at:#classNameChannel) value:specClass.
"/ (aspects at:#superclassNameChannel) value:specSuperclass.
"/ (aspects at:#methodNameChannel) value:specSelector asSymbol.
"/
"/ painter
"/ className:aClass name
"/ superclassName:aClass superclass name
"/ selector:aSelector.
painter setupFromSpec:(aClass perform:aSelector).
]
"Modified: 24.6.1997 / 19:07:05 / cg"
! !
!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:[
specSuperclass isEmpty ifFalse:[
superclass := Smalltalk at:specSuperclass asSymbol
] ifTrue:[
specSuperclass := nil.
]
] 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.
]
].
superclass isNil ifTrue:[
cls notNil ifTrue:[
specSuperclass := cls superclass name
]
].
^ true
"Modified: 25.6.1997 / 13:37:11 / cg"
!
defineClassAndSelector
"launch a dialog to define class, superclass and method"
|again tmp|
[
again := false.
(tmp := specClass) isNil ifTrue:[tmp := 'NewApplication'].
aspects at:#classNameChannel put:tmp asValue.
(tmp := specSelector) isNil ifTrue:[tmp := 'windowSpec'].
aspects at:#methodNameChannel put:tmp asValue.
(tmp := specSuperclass) isNil ifTrue:[tmp := 'ApplicationModel'].
aspects at:#superclassNameChannel put:tmp asValue.
(self openDialogInterface:#nameAndSelectorSpec) ifTrue:[
specClass := (self aspectFor:#classNameChannel) value.
specSelector := (self aspectFor:#methodNameChannel) value.
specSelector notNil ifTrue:[specSelector := specSelector asSymbol].
specSuperclass := (self aspectFor:#superclassNameChannel) value.
(again := self checkClassAndSelector not) ifFalse:[
self painter className:specClass
superclassName:specSuperclass
selector:specSelector.
]
]
] doWhile:[again]
"Modified: 17.6.1997 / 14:42:02 / cg"
! !
!UIPainter methodsFor:'user interaction - pullDown'!
doBrowseAppClass
"open a browser on the class"
|cls|
specClass isNil ifTrue:[
^ self information:'no class yet'.
].
specClass isBehavior ifFalse:[
cls := Smalltalk at:specClass asSymbol
] ifTrue:[
cls := specClass
].
cls isNil ifTrue:[
^ self information:'no class yet'.
].
SystemBrowser openInClass:cls
!
doFromClass
|className methodName cls sel accepted failed spec s painter|
objectList painter isModified ifTrue:[
(self confirm:'edit another interface without saving your modifications ?') ifFalse:[
^ self
]
].
className := (specClass ? '') asValue.
methodName := (specSelector ? '') 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
self setClass:cls selector:sel.
painter setupFromSpec:spec.
^ self
]
]
]
] doWhile:[accepted and:[failed]].
"Modified: 24.6.1997 / 18:59:29 / cg"
!
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.
!
doInstallHelp
|dict cls src|
cls := self activeHelpApplicationClass.
cls isNil ifTrue:[
^ self information:'no application class defined'
].
activeHelpTool isNil ifTrue:[
^ self information:'no help text defined'
].
dict := activeHelpTool dictionary.
src := '' writeStream.
src nextPutAll:
'helpSpec
"return a dictionary filled with helpKey -> helptext associations.
These are used by the activeHelp tool.
"
^ super helpSpec addPairsFrom:#(
'.
dict keysAndValuesDo:[:key :txt|
|t|
src nextPutLine:key storeString.
t := txt asString.
(t endsWith:Character cr) ifTrue:[
t := t copyWithoutLast:1
].
src nextPutLine:t storeString; cr.
].
src nextPutLine:')'.
src := src contents.
Compiler compile:src forClass:cls class inCategory:'help specs'
!
doInstallSpec
|code painter|
(specClass isNil or:[specSelector isNil]) ifTrue:[
self defineClassAndSelector
].
self checkClassAndSelector ifFalse:[
^ self
].
painter := self painter.
painter className:specClass
superclassName:specSuperclass
selector:specSelector.
code := painter generateWindowSpecMethodSource withCRs.
painter resetModification.
(ReadStream on:code) fileIn.
!
doNew
objectList painter isModified ifTrue:[
(self confirm:'new interface without saving your modifications ?') ifFalse:[
^ self
]
].
self removeAll
"Modified: 17.6.1997 / 12:33:31 / cg"
!
doPickAView
|painter view cls spec|
objectList painter isModified ifTrue:[
(self confirm:'pick another interface without saving your modifications ?') ifFalse:[
^ self
]
].
(view := Screen current viewFromUser) notNil ifTrue:[
view == Screen current rootView ifFalse:[
painter := self painter.
spec := UISpecification fromView:view topView.
"/ ok, got it
view application notNil ifTrue:[
cls := view application class
] ifFalse:[
cls := view class
].
self setClass:cls selector:nil.
painter setupFromSpec:spec.
]
]
"Modified: 24.6.1997 / 19:02:57 / cg"
!
doRaise
|top x|
top := self painter topView.
top realized ifFalse:[
self painterShown value:true
].
top raise.
top := selectionPanel window.
top realized ifFalse:[
self galleryShown value:true
].
top raise.
!
doStartApplication
|cls|
(specClass isNil or:[specSelector isNil]) ifTrue:[
^ self information:'no class or selector defined'.
].
specClass isBehavior ifFalse:[
cls := Smalltalk at:specClass asSymbol
] ifTrue:[
cls := specClass
].
cls isNil ifTrue:[
^ self information:'class not existant'.
].
(cls respondsTo:specSelector) ifFalse:[
self halt.
^ self information:('no method for: #'
, specSelector , ' in ' , cls name ,
'\\(did you install the spec ?)') withCRs.
].
cls new openInterface:specSelector
"Modified: 17.6.1997 / 14:40:21 / cg"
!
doWindowSpec
|code code2 v|
code := self painter generateWindowSpecMethodSource.
v := CodeView open.
v contents:code.
v label:'windowSpec'.
! !
!UIPainter class methodsFor:'documentation'!
version
^ '$Header$'
! !