UIPainter.st
author ca
Mon, 26 May 1997 13:00:29 +0200
changeset 126 cf76b1df0473
parent 124 98d26d6f01cb
child 127 95070ea7ae42
permissions -rw-r--r--
update layout from view

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$'
! !