MenuEditor.st
author Claus Gittinger <cg@exept.de>
Mon, 28 Jul 1997 16:05:49 +0200
changeset 263 25f080e1217f
parent 258 c6f8c3e2f463
child 266 dd70070d6652
permissions -rw-r--r--
checkin from browser

"
 COPYRIGHT (c) 1997 by eXept Software AG / Claus Gittinger
              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:#MenuEditor
	instanceVariableNames:'specClass tabSelection aspects slices activeHelpTool'
	classVariableNames:''
	poolDictionaries:''
	category:'Interface-UIPainter'
!

Object subclass:#Item
	instanceVariableNames:'activeHelpKey enabled label value nameKey indication shortcutKey
		accessCharaterPos retriever icon iconAndLabel submenuChannel'
	classVariableNames:''
	poolDictionaries:''
	privateIn:MenuEditor
!

SelectionInTreeView subclass:#Painter
	instanceVariableNames:'imageMenuLink imageSeparator'
	classVariableNames:'CopyBuffer ImageMenuLink ImageSeparator ImageItem ImageMenu
		ImageMenuOpen'
	poolDictionaries:''
	privateIn:MenuEditor
!

!MenuEditor class methodsFor:'documentation'!

copyright
"
 COPYRIGHT (c) 1997 by eXept Software AG / Claus Gittinger
              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
"
    create and modify or inspect popup and pullDown menus of the
    new style( derives from Menu).

    [start with:]
        MenuEditor open
        MenuEditor new openOnClass:MenuEditor andSelector:#menuPullDown

    [see also:]
        UIPainter
        UIHelpTool
        UISpecificationTool
        SelectionInTreeView

    [author:]
        Claus Atzkern
"

! !

!MenuEditor class methodsFor:'icons'!

iconCreateItem
    ^ Painter imageItem

!

iconCreateLink
    ^ Painter imageMenuLink

!

iconCreateMenu
    ^ Painter imageMenu

    "Modified: 28.7.1997 / 10:02:21 / cg"
!

iconCreateSep
    ^ Painter imageSeparator

!

iconUnknown
    "returns an image used for picked items containing an image
    "
    ^ Image fromFile:'brokenImage.xpm'

    "Modified: 28.7.1997 / 09:36:26 / cg"
! !

!MenuEditor class methodsFor:'interface specs'!

classAndMethodSpec
    "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:MenuEditor andSelector:#classAndMethodSpec
     MenuEditor new openInterface:#classAndMethodSpec
    "

    <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:' 'selectorLabel'
                    #'layout:' #(#AlignmentOrigin 45 0.11 74 0 1 0.5)
                    #'label:' 'selector:'
                    #'adjust:' #right
                    #'resizeForLabel:' true
                )
                 #(#InputFieldSpec
                    #'name:' 'methodNameField'
                    #'layout:' #(#LayoutFrame 47 0.11 64 0 0 1.0 86 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 0 1.0 61 0)
                    #'tabable:' true
                    #'model:' #classNameChannel
                )
                 #(#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: 28.7.1997 / 15:40:15 / cg"
!

classDefineSpec
    "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:MenuEditor andSelector:#classDefineSpec
     MenuEditor new openInterface:#classDefineSpec
    "

    <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 383 128)
          )
          #'component:' 
           #(#SpecCollection
              #'collection:' 
               #(
                 #(#LabelSpec
                    #'name:' 'classLabel'
                    #'layout:' #(#AlignmentOrigin 45 0.11 51 0 1 0.5)
                    #'label:' 'class:'
                    #'adjust:' #right
                    #'resizeForLabel:' true
                )
                 #(#LabelSpec
                    #'name:' 'boxLabel'
                    #'layout:' #(#Point 5 10)
                    #'label:' 'class for code:'
                    #'adjust:' #left
                    #'resizeForLabel:' true
                )
                 #(#InputFieldSpec
                    #'name:' 'classNameField'
                    #'layout:' #(#LayoutFrame 47 0.11 39 0 0 1.0 61 0)
                    #'tabable:' true
                    #'model:' #classNameChannel
                )
                 #(#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 187 24)
                          )
                           #(#ActionButtonSpec
                              #'name:' 'button2'
                              #'label:' 'ok'
                              #'tabable:' true
                              #'isDefault:' true
                              #'model:' #accept
                              #'extent:' #(#Point 187 24)
                          )
                        )
                    )
                    #'horizontalLayout:' #fitSpace
                    #'verticalLayout:' #fit
                    #'horizontalSpace:' 3
                    #'verticalSpace:' 3
                )
              )
          )
      )

    "Modified: 28.7.1997 / 15:40:39 / cg"
!

menuButtons
    "this window spec was automatically generated by the ST/X MenuEditor"

    "do not manually edit this - the builder may not be able to
     handle the specification if its corrupted."

    "
     MenuEditor new openOnClass:MenuEditor andSelector:#menuButtons
     (Menu new fromLiteralArrayEncoding:(MenuEditor menuButtons)) startUp
    "

    <resource: #menu>

    ^
     
       #(#Menu
          
           #(
             #(#MenuItem
                #'label:' 'createMenu'
                #'value:' #doCreateMenu
                #'enabled:' #hasAnySingleSelection
                #'labelImage:' 
                 #(#ResourceRetriever
                    #MenuEditor #iconCreateMenu
                )
            )
             #(#MenuItem
                #'label:' 'createLink'
                #'value:' #doCreateLink
                #'enabled:' #hasAnySingleSelection
                #'labelImage:' 
                 #(#ResourceRetriever
                    #MenuEditor #iconCreateLink
                )
            )
             #(#MenuItem
                #'label:' 'createItem'
                #'value:' #doCreateItem
                #'enabled:' #hasAnySingleSelection
                #'labelImage:' 
                 #(#ResourceRetriever
                    #MenuEditor #iconCreateItem
                )
            )
             #(#MenuItem
                #'label:' 'createSeparator'
                #'value:' #doCreateSep
                #'enabled:' #hasAnySingleSelection
                #'labelImage:' 
                 #(#ResourceRetriever
                    #MenuEditor #iconCreateSep
                )
            )
             #(#MenuItem
                #'label:' ''
            )
             #(#MenuItem
                #'label:' 'stepUp'
                #'value:' #doStepUp
                #'enabled:' #enabledStepOver
                #'labelImage:' 
                 #(#ResourceRetriever
                    #UIPainter #iconStepUp
                )
            )
             #(#MenuItem
                #'label:' 'stepDown'
                #'value:' #doStepDown
                #'enabled:' #enabledStepOver
                #'labelImage:' 
                 #(#ResourceRetriever
                    #UIPainter #iconStepDown
                )
            )
             #(#MenuItem
                #'label:' 'stepIn'
                #'value:' #doStepIn
                #'enabled:' #enabledStepIn
                #'labelImage:' 
                 #(#ResourceRetriever
                    #UIPainter #iconStepIn
                )
            )
             #(#MenuItem
                #'label:' 'stepOut'
                #'value:' #doStepOut
                #'enabled:' #enabledStepOut
                #'labelImage:' 
                 #(#ResourceRetriever
                    #UIPainter #iconStepOut
                )
            )
          ) nil
          nil
      )
!

menuDefaultLink
    "this window spec was automatically generated by the ST/X MenuEditor"

    "do not manually edit this - the builder may not be able to
     handle the specification if its corrupted."

    "
     MenuEditor new openOnClass:MenuEditor andSelector:#menuDefaultLink
     (Menu new fromLiteralArrayEncoding:(MenuEditor menuDefaultLink)) startUp
    "

    <resource: #menu>

    ^
     
       #(#Menu
          
           #(
             #(#MenuItem
                #'label:' '!! derives from application !!'
            )
          ) nil
          nil
      )
!

menuPainter
    "this window spec was automatically generated by the ST/X MenuEditor"

    "do not manually edit this - the builder may not be able to
     handle the specification if its corrupted."

    "
     MenuEditor new openOnClass:MenuEditor andSelector:#menuPainter
     (Menu new fromLiteralArrayEncoding:(MenuEditor menuPainter)) startUp
    "

    <resource: #menu>

    ^
     
       #(#Menu
          
           #(
             #(#MenuItem
                #'label:' 'copy'
                #'value:' #doCopy
                #'enabled:' #hasValidSelection
            )
             #(#MenuItem
                #'label:' 'cut'
                #'value:' #doCut
                #'enabled:' #hasValidSelection
            )
             #(#MenuItem
                #'label:' 'paste'
                #'value:' #doPaste
                #'enabled:' #hasAnySingleSelection
            )
             #(#MenuItem
                #'label:' '-'
            )
             #(#MenuItem
                #'label:' 'create'
                #'enabled:' #hasAnySingleSelection
                #'submenu:' 
                 #(#Menu
                    
                     #(
                       #(#MenuItem
                          #'label:' 'submenu static'
                          #'value:' #doCreateMenu
                          #'labelImage:' 
                           #(#ResourceRetriever
                              #MenuEditor #iconCreateMenu
                              'submenu static'
                          )
                      )
                       #(#MenuItem
                          #'label:' 'submenu dynamic'
                          #'value:' #doCreateLink
                          #'labelImage:' 
                           #(#ResourceRetriever
                              #MenuEditor #iconCreateLink
                              'submenu dynamic'
                          )
                      )
                       #(#MenuItem
                          #'label:' '-'
                      )
                       #(#MenuItem
                          #'label:' 'item'
                          #'value:' #doCreateItem
                          #'labelImage:' 
                           #(#ResourceRetriever
                              #MenuEditor #iconCreateItem
                              'item'
                          )
                      )
                       #(#MenuItem
                          #'label:' 'separator'
                          #'value:' #doCreateSep
                          #'labelImage:' 
                           #(#ResourceRetriever
                              #MenuEditor #iconCreateSep
                              'separator'
                          )
                      )
                    ) nil
                    nil
                )
            )
          ) nil
          nil
      )
!

menuPullDown
    "this window spec was automatically generated by the ST/X MenuEditor"

    "do not manually edit this - the builder may not be able to
     handle the specification if its corrupted."

    "
     MenuEditor new openOnClass:MenuEditor andSelector:#menuPullDown
     (Menu new fromLiteralArrayEncoding:(MenuEditor menuPullDown)) startUp
    "

    <resource: #menu>

    ^
     
       #(#Menu
          
           #(
             #(#MenuItem
                #'label:' 'file'
                #'value:' #file
                #'submenu:' 
                 #(#Menu
                    
                     #(
                       #(#MenuItem
                          #'label:' 'new'
                          #'value:' #doNew
                      )
                       #(#MenuItem
                          #'label:' 'from class ...'
                          #'value:' #doFromClass
                          #'enabled:' #isOwnerOfHelpTool
                      )
                       #(#MenuItem
                          #'label:' 'pick a menu'
                          #'value:' #doPickAMenu
                          #'enabled:' #isOwnerOfHelpTool
                      )
                       #(#MenuItem
                          #'label:' '='
                      )
                       #(#MenuItem
                          #'label:' 'quit'
                          #'value:' #closeRequest
                      )
                    ) nil
                    nil
                )
            )
             #(#MenuItem
                #'label:' 'edit'
                #'submenu:' 
                 #(#Menu
                    
                     #(
                       #(#MenuItem
                          #'label:' 'cut'
                          #'value:' #doCut
                      )
                       #(#MenuItem
                          #'label:' '='
                      )
                       #(#MenuItem
                          #'label:' 'create submenu static'
                          #'value:' #doCreateMenu
                      )
                       #(#MenuItem
                          #'label:' 'create summenu dynamic'
                          #'value:' #doCreateLink
                      )
                       #(#MenuItem
                          #'label:' '-'
                      )
                       #(#MenuItem
                          #'label:' 'create item'
                          #'value:' #doCreateItem
                      )
                       #(#MenuItem
                          #'label:' 'create separator'
                          #'value:' #doCreateSep
                      )
                    ) nil
                    nil
                )
            )
             #(#MenuItem
                #'label:' 'code'
                #'value:' #code
                #'submenu:' 
                 #(#Menu
                    
                     #(
                       #(#MenuItem
                          #'label:' 'class'
                          #'value:' #doDefineClass
                          #'enabled:' #isOwnerOfHelpTool
                      )
                       #(#MenuItem
                          #'label:' '-'
                      )
                       #(#MenuItem
                          #'label:' 'install window spec.'
                          #'value:' #doInstallSpec
                      )
                       #(#MenuItem
                          #'label:' 'install help spec.'
                          #'value:' #doInstallHelp
                          #'enabled:' #isOwnerOfHelpTool
                      )
                       #(#MenuItem
                          #'label:' '='
                      )
                       #(#MenuItem
                          #'label:' 'browse application'
                          #'value:' #doBrowseAppClass
                      )
                    ) nil
                    nil
                )
            )
             #(#MenuItem
                #'label:' 'test'
                #'submenuChannel:' #submenuTest
            )
          ) nil
          nil
      )

    "Modified: 28.7.1997 / 10:40:15 / 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:MenuEditor andSelector:#windowSpec
     MenuEditor new openInterface:#windowSpec
    "
    "MenuEditor open"

    <resource: #canvas>

    ^
     
       #(#FullSpec
          #'window:' 
           #(#WindowSpec
              #'name:' 'uIPainterView'
              #'layout:' #(#LayoutFrame 0 0.0 0 0.0 0 1.0 0 1.0)
              #'label:' 'Menu Builder'
              #'bounds:' #(#Rectangle 0 0 580 384)
          )
          #'component:' 
           #(#SpecCollection
              #'collection:' 
               #(
                 #(#ArbitraryComponentSpec
                    #'name:' 'painterView'
                    #'layout:' #(#LayoutFrame 0 0.0 57 0 0 0.5 0 1.0)
                    #'menu:' #menuPainter
                    #'hasHorizontalScrollBar:' true
                    #'hasVerticalScrollBar:' true
                    #'component:' #painter
                    #'hasBorder:' false
                )
                 #(#NoteBookViewSpec
                    #'name:' 'specificationView'
                    #'layout:' #(#LayoutFrame 0 0.5 0 0.0 0 1.0 -25 1.0)
                    #'tabable:' true
                    #'menu:' #tabList
                    #'model:' #tabModel
                    #'tabWidget:' #Window
                    #'useIndex:' true
                    #'canvas:' #tabCanvas
                )
                 #(#HorizontalPanelViewSpec
                    #'name:' 'confirmationPanel'
                    #'layout:' #(#LayoutFrame 0 0.5 -24 1.0 0 1.0 0 1.0)
                    #'component:' 
                     #(#SpecCollection
                        #'collection:' 
                         #(
                           #(#ActionButtonSpec
                              #'name:' 'cancelButton'
                              #'label:' 'cancel'
                              #'model:' #cancel
                              #'enableChannel:' #modifiedChannel
                              #'extent:' #(#Point 140 24)
                          )
                           #(#ActionButtonSpec
                              #'name:' 'acceptButton'
                              #'label:' 'ok'
                              #'model:' #accept
                              #'enableChannel:' #modifiedChannel
                              #'extent:' #(#Point 141 24)
                          )
                        )
                    )
                    #'horizontalLayout:' #fitSpace
                    #'verticalLayout:' #fit
                    #'horizontalSpace:' 3
                    #'verticalSpace:' 3
                )
                 #(#MenuPanelSpec
                    #'name:' 'pullDownMenu'
                    #'layout:' #(#LayoutFrame 0 0.0 0 0.0 0 0.5 24 0)
                    #'tabable:' true
                    #'menu:' #menuPullDown
                )
                 #(#MenuPanelSpec
                    #'name:' 'menuPanel1'
                    #'layout:' #(#LayoutFrame 0 0 28 0 0 0.5 53 0)
                    #'menu:' #menuButtons
                    #'showSeparatingLines:' true
                )
              )
          )
      )
! !

!MenuEditor class methodsFor:'slices'!

slicesItem
    ^#(
            (Basics     basicsItemSpec)
            (Details    detailsEditSpec)
            (Misc       miscEditSpec)
            (Help       help)
      )

!

slicesLink
    ^#(
            (Basics     basicsLinkSpec)
            (Details    detailsEditSpec)
            (Misc       miscEditSpec)
            (Help       help)
      )

!

slicesMenu
    ^#(
            (Basics     basicsMenuSpec)
            (Details    detailsEditSpec)
            (Misc       miscEditSpec)
            (Help       help)
      )

!

slicesRootMenu
    ^#(
            (Basics   basicsRootSpec)
      )

!

slicesSeparatorMenu
    ^#(
            (Basics   basicsSeparatorSpec)
      )

! !

!MenuEditor class methodsFor:'specs'!

basicsItemSpec
    "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:MenuEditor andSelector:#basicsItemSpec
     MenuEditor new openInterface:#basicsItemSpec
    "

    <resource: #canvas>

    ^
     
       #(#FullSpec
          #'window:' 
           #(#WindowSpec
              #'name:' 'uIPainterView'
              #'layout:' #(#LayoutFrame 0 0.0 0 0.0 0 1.0 0 1.0)
              #'label:' 'unnamed canvas'
              #'bounds:' #(#Rectangle 0 0 267 319)
          )
          #'component:' 
           #(#SpecCollection
              #'collection:' 
               #(
                 #(#LabelSpec
                    #'name:' 'nameKeyLabel'
                    #'layout:' #(#AlignmentOrigin 87 0 26 0 1 0.5)
                    #'label:' 'NameKey:'
                    #'adjust:' #right
                    #'resizeForLabel:' true
                )
                 #(#InputFieldSpec
                    #'name:' 'itemNameKey'
                    #'layout:' #(#LayoutFrame 91 0 15 0 0 1.0 37 0)
                    #'tabable:' true
                    #'model:' #nameKey
                    #'type:' #symbolOrNil
                )
                 #(#LabelSpec
                    #'name:' 'labelLabel'
                    #'layout:' #(#AlignmentOrigin 87 0 53 0 1 0.5)
                    #'label:' 'Label'
                    #'adjust:' #right
                    #'resizeForLabel:' true
                )
                 #(#InputFieldSpec
                    #'name:' 'itemLabel'
                    #'layout:' #(#LayoutFrame 91 0 42 0 0 1.0 64 0)
                    #'tabable:' true
                    #'model:' #label
                )
                 #(#LabelSpec
                    #'name:' 'valueLabel'
                    #'layout:' #(#AlignmentOrigin 87 0 79 0 1 0.5)
                    #'label:' 'Value:'
                    #'adjust:' #right
                    #'resizeForLabel:' true
                )
                 #(#InputFieldSpec
                    #'name:' 'itemValue'
                    #'layout:' #(#LayoutFrame 91 0 68 0 0 1.0 90 0)
                    #'tabable:' true
                    #'model:' #value
                    #'type:' #symbolOrNil
                )
                 #(#LabelSpec
                    #'name:' 'indicationLabel'
                    #'layout:' #(#AlignmentOrigin 87 0 139 0 1 0.5)
                    #'label:' 'Indication:'
                    #'adjust:' #right
                    #'resizeForLabel:' true
                )
                 #(#InputFieldSpec
                    #'name:' 'indicationValue'
                    #'layout:' #(#LayoutFrame 91 0 128 0 0 1.0 150 0)
                    #'tabable:' true
                    #'model:' #indication
                    #'type:' #symbolOrNil
                )
              )
          )
      )

    "Modified: 28.7.1997 / 15:37:47 / cg"
!

basicsLinkSpec
    "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:MenuEditor andSelector:#basicsLinkSpec
     MenuEditor new openInterface:#basicsLinkSpec
    "

    <resource: #canvas>

    ^
     
       #(#FullSpec
          #'window:' 
           #(#WindowSpec
              #'name:' 'uIPainterView'
              #'layout:' #(#LayoutFrame 0 0.0 0 0.0 0 1.0 0 1.0)
              #'label:' 'unnamed canvas'
              #'bounds:' #(#Rectangle 0 0 267 319)
          )
          #'component:' 
           #(#SpecCollection
              #'collection:' 
               #(
                 #(#LabelSpec
                    #'name:' 'nameKeyLabel'
                    #'layout:' #(#AlignmentOrigin 87 0 26 0 1 0.5)
                    #'label:' 'NameKey:'
                    #'adjust:' #right
                    #'resizeForLabel:' true
                )
                 #(#InputFieldSpec
                    #'name:' 'itemNameKey'
                    #'layout:' #(#LayoutFrame 91 0 15 0 0 1.0 37 0)
                    #'tabable:' true
                    #'model:' #nameKey
                    #'type:' #symbolOrNil
                )
                 #(#LabelSpec
                    #'name:' 'labelLabel'
                    #'layout:' #(#AlignmentOrigin 87 0 53 0 1 0.5)
                    #'label:' 'Label'
                    #'resizeForLabel:' true
                )
                 #(#InputFieldSpec
                    #'name:' 'itemLabel'
                    #'layout:' #(#LayoutFrame 91 0 42 0 0 1.0 64 0)
                    #'tabable:' true
                    #'model:' #label
                )
                 #(#InputFieldSpec
                    #'name:' 'submenuChannel'
                    #'layout:' #(#LayoutFrame 91 0 69 0 0 1.0 91 0)
                    #'tabable:' true
                    #'model:' #submenuChannel
                    #'type:' #symbolOrNil
                )
                 #(#LabelSpec
                    #'name:' 'menuLabel'
                    #'layout:' #(#AlignmentOrigin 87 0 80 0 1 0.5)
                    #'label:' 'Menu:'
                    #'resizeForLabel:' true
                )
              )
          )
      )

    "Modified: 28.7.1997 / 15:38:29 / cg"
!

basicsMenuSpec
    "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:MenuEditor andSelector:#basicsMenuSpec
     MenuEditor new openInterface:#basicsMenuSpec
    "

    <resource: #canvas>

    ^
     
       #(#FullSpec
          #'window:' 
           #(#WindowSpec
              #'name:' 'uIPainterView'
              #'layout:' #(#LayoutFrame 0 0.0 0 0.0 0 1.0 0 1.0)
              #'label:' 'unnamed canvas'
              #'bounds:' #(#Rectangle 0 0 267 319)
          )
          #'component:' 
           #(#SpecCollection
              #'collection:' 
               #(
                 #(#LabelSpec
                    #'name:' 'nameKeyLabel'
                    #'layout:' #(#AlignmentOrigin 87 0 26 0 1 0.5)
                    #'label:' 'NameKey:'
                    #'adjust:' #right
                    #'resizeForLabel:' true
                )
                 #(#InputFieldSpec
                    #'name:' 'itemNameKey'
                    #'layout:' #(#LayoutFrame 91 0 15 0 0 1.0 37 0)
                    #'tabable:' true
                    #'model:' #nameKey
                    #'type:' #symbolOrNil
                )
                 #(#LabelSpec
                    #'name:' 'labelLabel'
                    #'layout:' #(#AlignmentOrigin 87 0 53 0 1 0.5)
                    #'label:' 'Label'
                    #'adjust:' #right
                    #'resizeForLabel:' true
                )
                 #(#InputFieldSpec
                    #'name:' 'itemLabel'
                    #'layout:' #(#LayoutFrame 91 0 42 0 0 1.0 64 0)
                    #'tabable:' true
                    #'model:' #label
                )
              )
          )
      )

    "Modified: 28.7.1997 / 15:38:59 / cg"
!

basicsRootSpec
    "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:MenuEditor andSelector:#basicsRootSpec
     MenuEditor new openInterface:#basicsRootSpec
    "

    <resource: #canvas>

    ^
     
       #(#FullSpec
          #'window:' 
           #(#WindowSpec
              #'name:' 'uIPainterView'
              #'layout:' #(#LayoutFrame 0 0.0 0 0.0 0 1.0 0 1.0)
              #'label:' 'unnamed canvas'
              #'bounds:' #(#Rectangle 0 0 267 319)
          )
          #'component:' 
           #(#SpecCollection
              #'collection:' 
               #(
                 #(#LabelSpec
                    #'name:' 'selectorLabel'
                    #'layout:' #(#AlignmentOrigin 78 0 53 0 1 0.5)
                    #'label:' 'Selector:'
                    #'adjust:' #right
                    #'resizeForLabel:' true
                )
                 #(#InputFieldSpec
                    #'name:' 'selector'
                    #'layout:' #(#LayoutFrame 82 0 42 0 0 1.0 64 0)
                    #'tabable:' true
                    #'model:' #label
                )
              )
          )
      )

    "Modified: 28.7.1997 / 15:39:17 / cg"
!

basicsSeparatorSpec
    "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:MenuEditor andSelector:#basicsSeparatorSpec
     MenuEditor new openInterface:#basicsSeparatorSpec
    "

    <resource: #canvas>

    ^
     
       #(#FullSpec
          #'window:' 
           #(#WindowSpec
              #'name:' 'uIPainterView'
              #'layout:' #(#LayoutFrame 0 0.0 0 0.0 0 1.0 0 1.0)
              #'label:' 'unnamed canvas'
              #'bounds:' #(#Rectangle 0 0 267 319)
          )
          #'component:' 
           #(#SpecCollection
              #'collection:' 
               #(
                 #(#LabelSpec
                    #'name:' 'separatorLabel'
                    #'layout:' #(#AlignmentOrigin 127 0 22 0 1 0.5)
                    #'label:' 'Separator Type:'
                    #'adjust:' #right
                    #'resizeForLabel:' true
                )
                 #(#ComboListSpec
                    #'name:' 'comboList1'
                    #'layout:' #(#LayoutFrame 132 0 11 0 0 1.0 33 0)
                    #'model:' #seperatorSelection
                    #'useIndex:' false
                )
              )
          )
      )

    "Modified: 28.7.1997 / 15:39:43 / cg"
!

detailsEditSpec
    "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:MenuEditor andSelector:#detailsEditSpec
     MenuEditor new openInterface:#detailsEditSpec
    "

    <resource: #canvas>

    ^
     
       #(#FullSpec
          #'window:' 
           #(#WindowSpec
              #'name:' 'uIPainterView'
              #'layout:' #(#LayoutFrame 0 0.0 0 0.0 0 1.0 0 1.0)
              #'label:' 'unnamed canvas'
              #'bounds:' #(#Rectangle 0 0 259 288)
          )
          #'component:' 
           #(#SpecCollection
              #'collection:' 
               #(
                 #(#LabelSpec
                    #'name:' 'enabledLabel'
                    #'layout:' #(#AlignmentOrigin 87 0 59 0 1 0.5)
                    #'label:' 'Enabled:'
                    #'adjust:' #right
                    #'resizeForLabel:' true
                )
                 #(#InputFieldSpec
                    #'name:' 'enabled'
                    #'layout:' #(#LayoutFrame 91 0 48 0 0 1.0 70 0)
                    #'tabable:' true
                    #'model:' #enabled
                    #'type:' #symbolOrNil
                )
                 #(#LabelSpec
                    #'name:' 'shortcutKeyLabel'
                    #'layout:' #(#AlignmentOrigin 87 0 33 0 1 0.5)
                    #'label:' 'Accelerator:'
                    #'adjust:' #right
                    #'resizeForLabel:' true
                )
                 #(#InputFieldSpec
                    #'name:' 'accelerator'
                    #'layout:' #(#LayoutFrame 91 0 22 0 0 1.0 44 0)
                    #'tabable:' true
                    #'model:' #shortcutKey
                    #'type:' #symbolOrNil
                )
                 #(#LabelSpec
                    #'name:' 'accessCharPosLabel'
                    #'layout:' #(#AlignmentOrigin 211 0 127 0 1 0.5)
                    #'label:' 'Access Character Position:'
                    #'adjust:' #right
                    #'resizeForLabel:' true
                )
                 #(#InputFieldSpec
                    #'name:' 'accessCharaterPos'
                    #'layout:' #(#LayoutFrame 215 0 116 0 0 1.0 138 0)
                    #'tabable:' true
                    #'model:' #accessCharaterPos
                    #'type:' #numberOrNil
                )
              )
          )
      )

    "Modified: 28.7.1997 / 15:43:19 / cg"
!

miscEditSpec
    "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:MenuEditor andSelector:#miscEditSpec
     MenuEditor new openInterface:#miscEditSpec
    "

    <resource: #canvas>

    ^
     
       #(#FullSpec
          #'window:' 
           #(#WindowSpec
              #'name:' 'uIPainterView'
              #'layout:' #(#LayoutFrame 0 0.0 0 0.0 0 1.0 0 1.0)
              #'label:' 'unnamed canvas'
              #'bounds:' #(#Rectangle 0 0 245 142)
          )
          #'component:' 
           #(#SpecCollection
              #'collection:' 
               #(
                 #(#LabelSpec
                    #'name:' 'retrieverLabel'
                    #'layout:' #(#AlignmentOrigin 77 0 26 0 1 0.5)
                    #'label:' 'Retriever:'
                    #'adjust:' #right
                    #'resizeForLabel:' true
                )
                 #(#InputFieldSpec
                    #'name:' 'retriever'
                    #'layout:' #(#LayoutFrame 81 0 15 0 0 1.0 37 0)
                    #'tabable:' true
                    #'model:' #retriever
                    #'type:' #symbolOrNil
                )
                 #(#LabelSpec
                    #'name:' 'iconLabel'
                    #'layout:' #(#AlignmentOrigin 77 0 50 0 1 0.5)
                    #'label:' 'Icon:'
                    #'adjust:' #right
                    #'resizeForLabel:' true
                )
                 #(#InputFieldSpec
                    #'name:' 'icon'
                    #'layout:' #(#LayoutFrame 81 0 39 0 0 1.0 61 0)
                    #'tabable:' true
                    #'model:' #icon
                    #'type:' #symbolOrNil
                )
                 #(#CheckBoxSpec
                    #'name:' 'iconAndLabel'
                    #'layout:' #(#LayoutOrigin 15 0 85 0)
                    #'tabable:' true
                    #'model:' #iconAndLabel
                    #'label:' 'Icon & Label'
                )
              )
          )
      )

    "Modified: 28.7.1997 / 15:44:12 / cg"
! !

!MenuEditor class methodsFor:'startup'!

openModalOnClass:aClass andSelector:aSelector
    ^ self new openModalOnClass:aClass andSelector:aSelector


!

openOnClass:aClass andSelector:aSelector
    ^ self new openOnClass:aClass andSelector:aSelector


! !

!MenuEditor methodsFor:'accessing'!

menuDefaultLink
    ^ self class menuDefaultLink
!

specClass
    ^ specClass
!

specClass:aClass
    aClass isBehavior ifTrue:[specClass := aClass name]
                     ifFalse:[specClass := aClass].
!

submenuTest
    "returns submenu assigned to item test
    "
    |menu|

    menu := self painter asMenu.

    menu allItemsDo:[:anItem|
        anItem value:nil.
        anItem enabled:true.
    ].
  ^ menu
! !

!MenuEditor methodsFor:'accessing menu'!

menuButtons
    "this window spec was automatically generated by the ST/X MenuEditor"

    ^ self class menuButtons


!

menuPainter
    "this window spec was automatically generated by the ST/X MenuEditor"

    ^ self class menuPainter


! !

!MenuEditor methodsFor:'actions'!

accept
    "automatically generated by UIPainter ..."

    |painter node cont|

    painter := self painter.
    node := painter selectedNode.

    node notNil ifTrue:[
        self isHelpToolSelected ifTrue:[
            self activeHelpTool accept
        ].
        cont := node contents buildFromAspects:aspects.
        painter selectedNodeChanged
    ].
    self modifiedChannel value:false.

    "Modified: 28.7.1997 / 12:37:17 / cg"
!

cancel
    |node|

    (node := self painter selectedNode) notNil ifTrue:[
        aspects do:[:anAspect| anAspect value:nil ].
        node contents toAspects:aspects.
    ].
    self modifiedChannel value:false.

! !

!MenuEditor methodsFor:'active help'!

activeHelpTool
    "access current active help editor
    "
    activeHelpTool isNil ifTrue:[
        self activeHelpTool:(UIHelpTool new)
    ].
  ^ activeHelpTool
!

activeHelpTool:anApplication
    "change current active help editor
    "
    activeHelpTool := anApplication.

    activeHelpTool masterApplication isNil ifTrue:[
        activeHelpTool masterApplication:self.
    ].
!

isOwnerOfHelpTool
    "returns true in case of owner of the helptool
    "
  ^ self activeHelpTool masterApplication == self
! !

!MenuEditor methodsFor:'aspects'!

aspectFor:aKey
    "returns aspect for a key or nil
    "
  ^ aspects at:aKey ifAbsent:[ super aspectFor:aKey ]


!

enabledStepIn
    ^ builder booleanValueAspectFor:#enabledStepIn

    "Modified: 28.7.1997 / 12:51:55 / cg"
!

enabledStepOut
    ^ builder booleanValueAspectFor:#enabledStepOut

    "Modified: 28.7.1997 / 12:52:04 / cg"
!

enabledStepOver
    ^ builder booleanValueAspectFor:#enabledStepOver

    "Modified: 28.7.1997 / 12:52:07 / cg"
!

hasAnySingleSelection
    ^ builder booleanValueAspectFor:#hasAnySingleSelection

    "Modified: 28.7.1997 / 12:52:09 / cg"
!

hasValidSelection
    ^ builder booleanValueAspectFor:#hasValidSelection

    "Modified: 28.7.1997 / 12:52:11 / cg"
!

hasValidSingleSelection
    ^ builder booleanValueAspectFor:#hasValidSingleSelection

    "Modified: 28.7.1997 / 12:52:13 / cg"
!

menuPullDown
    |menu|

    menu := Menu new.
    menu fromLiteralArrayEncoding:(self class menuPullDown).
    menu receiver:self.
  ^ menu


!

modifiedChannel
    "automatically generated by UIPainter ..."

    ^ builder booleanValueAspectFor:#modifiedChannel

    "Modified: 28.7.1997 / 12:52:14 / cg"
!

tabCanvas
    "automatically generated by UIPainter ..."

    |holder|

    (holder := builder bindingAt:#tabCanvas) isNil ifTrue:[
        builder aspectAt:#tabCanvas put:(holder :=  SubCanvas new).
    ].
    ^ holder
!

tabList
    "automatically generated by UIPainter ..."

    ^ builder nilValueAspectFor:#tabList

    "Modified: 28.7.1997 / 13:11:17 / cg"
!

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

! !

!MenuEditor methodsFor:'change & update'!

update:something with:aParameter from:changedObject
    "one of my models changed its value
    "
    self modifiedChannel value:true
!

updateEnabledChannels
    "update enabled channels
    "
    |node parent next painter state|

    painter := self painter.
    node    := painter selectedNode.
    state   := false.

    node notNil ifTrue:[
        self hasAnySingleSelection value:true.

        (parent := node parent) notNil ifTrue:[
            next := parent childAt:((parent indexOfChild:node) + 1).
            self enabledStepIn           value:(next notNil and:[next hasChildren]).
            self enabledStepOver         value:(parent children size > 1).
            self enabledStepOut          value:(parent parent notNil).
            self hasValidSingleSelection value:true.
            self hasValidSelection       value:true.
          ^ self
        ]
    ] ifFalse:[
        self hasAnySingleSelection value:false.

        painter numberOfSelections ~~ 0 ifTrue:[
            state := (painter isInSelection:1) not
        ]
    ].
    self enabledStepOver         value:false.
    self enabledStepIn           value:false.
    self enabledStepOut          value:false.
    self hasValidSingleSelection value:false.
    self hasValidSelection       value:state.
! !

!MenuEditor methodsFor:'event handling'!

doesNotUnderstand:aMessage
   |painter|

   painter := self painter.

   (painter respondsTo:(aMessage selector)) ifTrue:[
        ^ aMessage sendTo:painter
   ].
   super doesNotUnderstand:aMessage


! !

!MenuEditor methodsFor:'queries'!

isHelpToolSelected
    "returns true if current selection is help tool
    "
    (slices notNil and:[tabSelection notNil]) ifTrue:[
        ^ (slices at:tabSelection) last == #help
    ].
  ^ false
! !

!MenuEditor methodsFor:'selection'!

menuChanged
    |node item slc sel|

    (node := self painter selectedNode) notNil ifTrue:[
        aspects do:[:anAspect| anAspect value:nil ].
        item := node contents.
        item toAspects:aspects.

        item isSeparator ifFalse:[
            node parent isNil ifFalse:[
                node hasChildren ifTrue:[
                    slc := #slicesMenu
                ] ifFalse:[
                    item submenuChannel isNil ifTrue:[slc := #slicesItem]
                                             ifFalse:[slc := #slicesLink]
                ].
            ] ifTrue:[
                slc := #slicesRootMenu
            ]
        ] ifTrue:[
            slc := #slicesSeparatorMenu
        ].
        slc := self class perform:slc.
    ].
    self modifiedChannel value:false.

    slc ~= slices  ifTrue:[
        (slices := slc) notNil ifTrue:[
            tabSelection notNil ifTrue:[sel := tabSelection min:(slices size)]
                               ifFalse:[sel := 1].

            self tabList value:(slices collect:[:s| s first]).
            self tabModel setValue:nil.
            self tabModel value:sel.
        ] ifFalse:[
            self tabList value:nil.
            self tabSelection:nil.
        ]
    ].
    self updateEnabledChannels
!

tabSelection
    ^ tabSelection
!

tabSelection:aSelection
    |tool sel|

    tabSelection == aSelection ifTrue:[
        ^ self
    ].

    (tabSelection := aSelection) isNil ifTrue:[
      ^ self tabCanvas client:nil
    ].
    self isHelpToolSelected ifTrue:[
        self tabCanvas client:(tool := self activeHelpTool).
        tool model:(self aspectFor:#activeHelpKey)
    ] ifFalse:[
        sel := (slices at:tabSelection) last.
        self tabCanvas client:self spec:(self class perform:sel) builder:builder
    ]    
! !

!MenuEditor methodsFor:'startup / release'!

buildFrom:aClass andSelector:aSelector
    |oldClass newClass|

    oldClass := self specClass.
    self specClass:aClass.
    newClass := self specClass.

    (self isOwnerOfHelpTool and:[oldClass ~= newClass]) ifTrue:[
        self activeHelpTool helpSpecFrom:newClass
    ].
    self painter buildFrom:newClass andSelector:aSelector.
!

initialize
    "initialize channels
    "
    |holder|

    super initialize.
    aspects := IdentityDictionary new.

    #(
        label
        accessCharaterPos
        submenuChannel
        activeHelpKey
        enabled
        value
        nameKey
        indication
        shortcutKey
        retriever
        iconAndLabel
        icon

     ) do:[:aKey|
        aspects at:aKey put:(holder := ValueHolder new).
        holder addDependent:self.
    ].

    aspects at:#seperatorSelection put:(holder := SelectionInList new).
    holder list:(Item separatorList).
    holder addDependent:self.


!

openModalOnClass:aClass andSelector:aSelector
    specClass := Association key:aClass value:aSelector.
    super openInterfaceModal.

!

openOnClass:aClass andSelector:aSelector
    specClass := Association key:aClass value:aSelector.
    super openInterface.
    self buildFrom:aClass andSelector:aSelector.

!

postBuildWith:builder
    |cls sel|

    specClass isAssociation ifTrue:[
        cls := specClass key.
        sel := specClass value.

        specClass := nil.

        (sel isKindOf:Menu) ifTrue:[
            self buildFrom:cls andSelector:nil.
          ^ self painter buildFromMenu:sel.
        ]
        
    ].
    self buildFrom:cls andSelector:sel.
! !

!MenuEditor methodsFor:'user interactions'!

doBrowseAppClass
    "open a browser on the class"

    |cls|

    (cls := self specClass) isNil ifTrue:[
        ^ self information:'no class yet'.
    ].

    cls isBehavior ifFalse:[
        (cls := Smalltalk at:cls asSymbol) isNil ifTrue:[
            ^ self information:'no valid class defined'.
        ]
    ].
    SystemBrowser openInClass:cls class selector:(self painter selectorName)

!

doDefineClass

    aspects at:#classNameChannel  put:(self specClass asValue).

    (self openDialogInterface:#classDefineSpec) ifTrue:[
        self specClass:((aspects at:#classNameChannel) value)
    ].

!

doFromClass

    aspects at:#classNameChannel  put:(self specClass asValue).
    aspects at:#methodNameChannel put:(self painter selectorName asValue).

    (self openDialogInterface:#classAndMethodSpec) ifTrue:[
        self buildFrom:(aspects at:#classNameChannel) value
           andSelector:(aspects at:#methodNameChannel) value
    ].
!

doInstallHelp
    "install help text
    "
    self activeHelpTool installHelpSpecInto:(self specClass)
!

doInstallSpec
    |cls selector painter menu spec mthd category code|

    (cls := self specClass) isNil ifTrue:[
        ^ self information:'no class yet'.
    ].

    cls isBehavior ifFalse:[
        (cls := Smalltalk at:cls asSymbol) isNil ifTrue:[
            ^ self information:'no valid class defined'.
        ]
    ].
    painter  := self painter.
    selector := painter selectorName.
    menu     := painter asMenu.

    menu isNil ifTrue:[
        ^ self information:'no menu defined'
    ].
    menu := menu literalArrayEncoding.
    spec := WriteStream on:String new.
    UISpecification prettyPrintSpecArray:menu on:spec indent:5.
    spec := spec contents.

    "/ if that method already exists, do not overwrite the category

    category := 'interface specs'.
    (mthd := cls class compiledMethodAt:selector) notNil ifTrue:[
        category := mthd category.
    ].

    code := Character excla asString 
            , cls name , ' class methodsFor:' , category storeString
            , Character excla asString , '\\'

            , selector , '\'
            , '    "this window spec was automatically generated by the ST/X MenuEditor"\\'
            , '    "do not manually edit this - the builder may not be able to\'
            , '     handle the specification if its corrupted."\\'
            , '    "\'
            , '     MenuEditor new openOnClass:' , cls name , ' andSelector:#' , selector , '\'
            , '     (Menu new fromLiteralArrayEncoding:(' , cls name , ' ' , selector , ')) startUp\'
            , '    "\'.

    code := code 
            , '\'
            , '    <resource: #menu>\\'
            , '    ^\' 
            , '     ', spec
            , '\'
            , Character excla asString
            , ' '
            , Character excla asString
            , '\\'.

    code := code withCRs.
    (ReadStream on:code) fileIn.

    (cls compiledMethodAt:selector) isNil ifTrue:[
        category := 'accessing menu'.
        code := Character excla asString 
                , cls name , ' methodsFor:' , category storeString
                , Character excla asString , '\\'

                , selector , '\'
                , '    "this window spec was automatically generated by the ST/X MenuEditor"\\'
                , '    ^ self class ', selector, '\\'
                , '\'
                , Character excla asString
                , ' '
                , Character excla asString
                , '\\'.

        code := code withCRs.
        (ReadStream on:code) fileIn.
    ].


!

doNew
    self buildFrom:nil andSelector:(self painter selectorName)
!

doPickAMenu

    |view|

    view := Screen current viewFromUser.

    (view isNil or:[view == Screen current rootView]) ifTrue:[
        ^ self
    ].
    view specClass == MenuPanelSpec ifTrue:[
        ^ self painter buildFromMenu:(view asMenu)
    ].
    ^ nil
!

doStepDown
    "move selected child after next child
    "
    self painter doStepOver:1
!

doStepIn
    self painter doStepIn

!

doStepOut
    self painter doStepOut
!

doStepUp
    "move selected child after next child
    "
    self painter doStepOver:-1
! !

!MenuEditor methodsFor:'values'!

painter
    "automatically generated by UIPainter ..."

    |painter|

    (painter := builder bindingAt:#painter) isNil ifTrue:[
        painter := Painter new.
        painter action:[:dummy| self menuChanged ].
        builder aspectAt:#painter put:painter.
    ].
  ^ painter
! !

!MenuEditor::Item class methodsFor:'constants'!

separatorList
   ^ #( 'blank' 'single line' 'double line' )
!

separatorSlices
   ^ #(
        ( #blank        ''  )
        ( #single       '-' )
        ( #double       '=' )
      )
! !

!MenuEditor::Item class methodsFor:'documentation'!

documentation
"
    implements the contents assigned to a TreeItem. An instance
    is associated with one item and keeps all its information

    [see also:]
        TreeItem
        MenuEditor

    [author:]
        Claus Atzkern
"


! !

!MenuEditor::Item methodsFor:'accessing'!

label
    "return the value of the instance variable 'label' (automatically generated)"

    ^ label!

label:something
    "set the value of the instance variable 'label' (automatically generated)"

    label := something ? '-'.
!

separatorType
    "returns separator type assigned to item or nil
    "
    |c|

    label size > 1 ifFalse:[
        label size == 0 ifTrue:[
            ^ #blank
        ].
        c := label first.
        c == $- ifTrue:[^ #single].
        c == $= ifTrue:[^ #double].
    ].    
  ^ nil

!

submenuChannel
    "return the value of the instance variable 'submenuChannel' (automatically generated)"

    ^ submenuChannel
!

submenuChannel:aChannel
    "return the value of the instance variable 'submenuChannel' (automatically generated)"

    submenuChannel := aChannel
! !

!MenuEditor::Item methodsFor:'conversion'!

asMenuItem
    "converts self to a menu item
    "
    |item rcv|

    item := MenuItem labeled:label.

    self isSeparator ifFalse:[
        item activeHelpKey:activeHelpKey.
        item enabled:enabled.
        item accessCharacterPosition:accessCharaterPos.
        item submenuChannel:submenuChannel.
        item nameKey:nameKey.
        item shortcutKeyCharacter:shortcutKey.
        item value:value.
        item indication:indication.

        icon notNil ifTrue:[
            rcv := ResourceRetriever new.
            rcv className:retriever.
            rcv selector:icon.
            iconAndLabel == true ifTrue:[
                rcv labelText:label
            ].
            item labelImage:rcv
        ]
    ].
  ^ item.
!

buildFromAspects:aspects
    |name|

    self isSeparator ifFalse:[
        name  := label.
        label := (aspects at:#label) value.

        (label isNil or:[self isSeparator]) ifTrue:[
            (aspects at:#label) value:(label := name)
        ].

        activeHelpKey       := (aspects at:#activeHelpKey) value.
        enabled             := (aspects at:#enabled) value.
        value               := (aspects at:#value) value.
        nameKey             := (aspects at:#nameKey) value.
        indication          := (aspects at:#indication) value.
        shortcutKey         := (aspects at:#shortcutKey) value.
        accessCharaterPos   := (aspects at:#accessCharaterPos) value.
        submenuChannel      := (aspects at:#submenuChannel)    value.
        retriever           := (aspects at:#retriever) value.
        icon                := (aspects at:#icon) value.
        iconAndLabel        := (aspects at:#iconAndLabel) value.
    ] ifTrue:[
        name  := (aspects at:#seperatorSelection) selectionIndex.
        label := (self class separatorSlices at:name) last.
    ]
!

buildFromMenuItem:anItem
    |rtv|

    self label:(anItem label).
    activeHelpKey := anItem activeHelpKey.

    (enabled := anItem enabled) isSymbol ifFalse:[
        enabled := nil
    ].

    (value := anItem value) isSymbol ifFalse:[
        value := nil.
    ].

    (indication := anItem indication) isSymbol ifFalse:[
        indication := nil
    ].

    nameKey           := anItem nameKey.
    shortcutKey       := anItem shortcutKeyCharacter.
    accessCharaterPos := anItem accessCharacterPosition.
    submenuChannel    := anItem submenuChannel.

    (    ((rtv := anItem adornment) notNil)
     and:[(rtv := rtv labelImage) isKindOf:ResourceRetriever]
    ) ifTrue:[
        retriever := rtv className.
        icon      := rtv selector.

        (iconAndLabel := rtv labelText notNil) ifTrue:[
            label := rtv labelText.
        ]
    ]
!

toAspects:aspects
    |type|

    (type := self separatorType) notNil ifTrue:[
        type := self class separatorSlices findFirst:[:el| el first == type ].
        (aspects at:#seperatorSelection) selectionIndex:type.
    ] ifFalse:[
        (aspects at:#label)                 value:label.
        (aspects at:#activeHelpKey)         value:activeHelpKey.
        (aspects at:#enabled)               value:enabled.
        (aspects at:#value)                 value:value.
        (aspects at:#nameKey)               value:nameKey.
        (aspects at:#indication)            value:indication.
        (aspects at:#shortcutKey)           value:shortcutKey.
        (aspects at:#accessCharaterPos)     value:accessCharaterPos.
        (aspects at:#submenuChannel)        value:submenuChannel.
        (aspects at:#retriever)             value:retriever.
        (aspects at:#icon)                  value:icon.
        (aspects at:#iconAndLabel)          value:iconAndLabel.
    ]
! !

!MenuEditor::Item methodsFor:'queries'!

isSeparator
    "returns true if item is a seperator
    "
    ^ self separatorType notNil
! !

!MenuEditor::Painter class methodsFor:'constants'!

imageClosed
    ^ self imageMenu

    "Created: 28.7.1997 / 10:31:37 / cg"
!

imageItem
    ImageItem isNil ifTrue:[
        ImageItem := Image fromFile:('ui_menuitem.xpm').
    ].
    ^ ImageItem

    "
     ImageItem := nil
    "

    "Created: 28.7.1997 / 09:51:00 / cg"
    "Modified: 28.7.1997 / 09:51:14 / cg"
!

imageMenu
    ImageMenu isNil ifTrue:[
        ImageMenu := Image fromFile:('ui_submenu.xpm').
    ].
    ^ ImageMenu

    "
    ImageMenu := nil
    "

    "Created: 28.7.1997 / 10:01:21 / cg"
    "Modified: 28.7.1997 / 10:29:14 / cg"
!

imageMenuLink
    ImageMenuLink isNil ifTrue:[
"/        ImageMenuLink := Image fromFile:('xpmBitmaps/document_images/tiny_yellow_dir_link.xpm').
        ImageMenuLink := Image fromFile:('ui_submenulink.xpm').
    ].
    ^ ImageMenuLink

    "
    ImageMenuLink := nil
    "

    "Modified: 28.7.1997 / 10:29:18 / cg"
!

imageMenuOpen
    ImageMenuOpen isNil ifTrue:[
        ImageMenuOpen := Image fromFile:('ui_submenu_open.xpm').
    ].
    ^ ImageMenuOpen

    "
    ImageMenuOpen := nil
    "

    "Created: 28.7.1997 / 10:21:31 / cg"
    "Modified: 28.7.1997 / 10:29:20 / cg"
!

imageOpened
    ^ self imageMenuOpen

    "Created: 28.7.1997 / 10:31:46 / cg"
!

imageSeparator
    ImageSeparator isNil ifTrue:[
"/        ImageSeparator := Image fromFile:('xpmBitmaps/document_images/tiny_file_exec.xpm').
        ImageSeparator := Image fromFile:('ui_menusep.xpm').
    ].
    ^ ImageSeparator

    "
     ImageSeparator := nil
    "

    "Modified: 28.7.1997 / 09:42:07 / cg"
! !

!MenuEditor::Painter class methodsFor:'defaults'!

defaultMenuMessage   
    "This message is the default yo be sent to the menuHolder to get a menu
    "
    ^ #menu


! !

!MenuEditor::Painter class methodsFor:'documentation'!

documentation
"
    menu selection list

    [see also:]
        SelectionInTreeView
        SelectionInTree
        TreeItem

    [author:]
        Claus Atzkern
"


! !

!MenuEditor::Painter methodsFor:'accessing'!

root
    ^ listOfNodes first
!

selectorName
    ^ (listOfNodes first contents label) asSymbol
! !

!MenuEditor::Painter methodsFor:'building'!

buildFrom:aClass andSelector:aSelector
    |spec cls menu node|

    (aClass notNil and:[aSelector notNil]) ifTrue:[
        aClass isBehavior ifFalse:[cls := Smalltalk at:aClass asSymbol]
                           ifTrue:[cls := aClass].

        (cls respondsTo:aSelector) ifTrue:[
            spec := cls perform:aSelector
        ]
    ].
    spec isNil ifFalse:[
        menu := Menu new fromLiteralArrayEncoding:spec.
        node := self nodeLabel:(aSelector asString).
        self subMenu:menu parent:node.
    ] ifTrue:[
        aSelector notNil ifTrue:[cls := aSelector asString]
                        ifFalse:[cls := 'menu'].

        node := self nodeLabel:cls.
    ].

    node hasChildren ifFalse:[
        node add:(self nodeLabel:'undefined')
    ].
    node expand.
    model root:node.

!

buildFromMenu:aMenu

    |node|

    node := self nodeLabel:'menu'.
    self subMenu:aMenu parent:node.

    node hasChildren ifFalse:[
        node add:(self nodeLabel:'undefined')
    ].
    node expand.
    model root:node.

!

menuItem:anItem

    |node|

    node := self nodeLabel:(anItem label).
    node contents buildFromMenuItem:anItem.
    node name:(node contents label).
    self subMenu:(anItem submenu) parent:node.
  ^ node.


!

subMenu:aMenu parent:aParent
    |idx grp|

    aMenu isNil ifFalse:[
        grp := aMenu groupSizes.
        aMenu itemsDo:[:i| aParent add:(self menuItem:i)].

        grp notNil ifTrue:[
            idx := 0.

            grp do:[:i|
                idx := idx + i + 1.
                aParent add:(self nodeLabel:nil) beforeIndex:idx.
            ]
        ]
    ]
! !

!MenuEditor::Painter methodsFor:'conversion'!

asMenu
    |menu root|

    root := self root.

    root hasChildren ifTrue:[
        menu := Menu new.
        root children do:[:aChild| menu addItem:(self asMenuItem:aChild)].
    ].
  ^ menu
!

asMenuItem:aNode

    |menu item|

    item := aNode contents asMenuItem.

    aNode hasChildren ifTrue:[
        menu := Menu new.
        aNode children do:[:aChild| menu addItem:(self asMenuItem:aChild)].
        item submenu:menu
    ].
  ^ item

! !

!MenuEditor::Painter methodsFor:'drawing basics'!

drawLabelIndex:anIndex atX:x y:yCenter
    "draw text label assigned to a node at x y( center)
    "
    |y x2 type item|

    item := (listOfNodes at:anIndex) contents.
    type := item separatorType.

    type isNil ifTrue:[
        super drawLabelIndex:anIndex atX:x y:yCenter
    ] ifFalse:[
        type == #blank ifFalse:[
            x2 := x + 80.

            self displayLineFromX:x y:yCenter toX:x2 y:yCenter.

            type == #double ifTrue:[
                y := yCenter + 2.
                self displayLineFromX:x y:y toX:x2 y:y.
            ]    
        ]
    ]

    "Modified: 28.7.1997 / 13:13:41 / cg"
!

figureFor:aNode
    "access figure for a node
    "
    |item|

    aNode hasChildren ifFalse:[
        item := aNode contents.

        item submenuChannel notNil ifTrue:[
            imageMenuLink isNil ifTrue:[
                imageMenuLink := (self class imageMenuLink) onDevice:device.
            ].
            ^ imageMenuLink
        ].

        item isSeparator ifTrue:[
            imageSeparator isNil ifTrue:[
                imageSeparator := (self class imageSeparator) onDevice:device.
            ].
            ^ imageSeparator
        ].
        imageItem isNil ifTrue:[
            imageItem := (self class imageItem) onDevice:device.
        ].
        ^ imageItem
    ].

    aNode isExpandable ifTrue:[ 
        imageClosed isNil ifTrue:[
            imageClosed := (self class imageMenu) onDevice:device.
        ].
        ^ imageClosed
    ].
    imageOpened isNil ifTrue:[
        imageOpened := (self class imageMenuOpen) onDevice:device.
    ].
    ^ imageOpened

    "Modified: 28.7.1997 / 10:27:52 / cg"
! !

!MenuEditor::Painter methodsFor:'initialization'!

initialize
    super initialize.
    imageOpened := nil.
    imageClosed := nil.
    self multipleSelectOk:true.
    self model:(SelectionInTree new).

    "Modified: 28.7.1997 / 10:28:48 / cg"
! !

!MenuEditor::Painter methodsFor:'menus'!

doCopy
    self hasSelection ifTrue:[
        CopyBuffer := OrderedCollection new.
        self selectionDo:[:i| CopyBuffer add:((listOfNodes at:i) copy)]
    ]
!

doCreateItem
    self addElement:(self nodeLabel:'undefined')
!

doCreateLink
    |node item|

    node := self nodeLabel:'undefined'.
    item := node contents.
    item submenuChannel:#menuDefaultLink.
    self addElement:node



!

doCreateMenu
    |node|

    node := self nodeLabel:'undefined'.
    node add:(self nodeLabel:'undefined').
    self addElement:node

!

doCreateSep
    self addElement:(self nodeLabel:nil)

!

doCut
    self doCopy.
    model removeSelection.
    self selection:nil.


!

doPaste

    (CopyBuffer notNil and:[self selectedNode notNil]) ifTrue:[
        self addElement:(CopyBuffer collect:[:el| el copy])
    ].
!

doStepIn
    |idx node cprt nprt|

    (    (node := self selectedNode) isNil
     or:[(cprt := node parent) isNil]
    ) ifTrue:[
        ^ self
    ].

    idx := cprt indexOfChild:node.

    idx == cprt children size ifTrue:[
        ^ self
    ].
    nprt := cprt childAt:(idx + 1).

    (nprt notNil and:[nprt hasChildren]) ifFalse:[
       ^ self
    ].

    model removeDependent:self.
    model removeSelection.
    selection := nil.
    model expand:nprt.
    model addDependent:self.

    model add:node beforeIndex:1 below:nprt.
    self selectNode:node.
!

doStepOut
    |node cprt nprt|

    (    (node := self selectedNode) isNil
     or:[(cprt := node parent) isNil
     or:[(nprt := cprt parent) isNil]]
    ) ifFalse:[
        model removeDependent:self.
        model removeSelection.
        selection := nil.
        model addDependent:self.

        model add:node afterIndex:(nprt indexOfChild:cprt) below:nprt.
        self selectNode:node.
    ]
!

doStepOver:anOffset
    "move child 'anOffset' forward or backward in list of children
    "
    |idx node size parent|

    (      (node   := self selectedNode) notNil
      and:[(parent := node parent) notNil
      and:[(size   := parent children size) > 1]]
    ) ifTrue:[
        idx := parent indexOfChild:node.

        model removeDependent:self.
        model removeSelection.
        selection := nil.
        model addDependent:self.

        (idx := idx + anOffset) < 1 ifTrue:[
            idx := size
        ] ifFalse:[
            idx > size ifTrue:[idx := 1]
        ].
        model add:node beforeIndex:idx below:parent.
        self selectNode:node.
    ]
! !

!MenuEditor::Painter methodsFor:'private'!

addElement:something
    "add something after selection
    "
    |node|

    (node := self selectedNode) notNil ifTrue:[
        node parent notNil ifTrue:[
            node isCollapsable ifTrue:[
                model add:something beforeIndex:1 below:node
            ] ifFalse:[
                model add:something after:node
            ]
        ] ifFalse:[
            model add:something beforeIndex:1 below:(self root)
        ]
    ]
!

nodeLabel:aLabel
   ^ TreeItem name:aLabel contents:(MenuEditor::Item new label:aLabel).
! !

!MenuEditor::Painter methodsFor:'selection'!

selectedNodeChanged
    |node name index|

    (index := self selectedIndex) ~~ 0 ifTrue:[
        node := listOfNodes at:index.
        name := node contents label.
        list at:index put:name.
        node name:name.
        self redrawLine:index.
    ]
! !

!MenuEditor class methodsFor:'documentation'!

version
    ^ '$Header$'
! !