diff -r 8aab97d1f5fe -r 54f978ea4b66 MenuEditor.st --- a/MenuEditor.st Mon Sep 23 11:37:48 2002 +0200 +++ b/MenuEditor.st Mon Sep 23 14:22:29 2002 +0200 @@ -1,6 +1,6 @@ " COPYRIGHT (c) 1997 by eXept Software AG - All Rights Reserved + 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 @@ -10,42 +10,79 @@ hereby transferred. " - - "{ Package: 'stx:libtool2' }" ResourceSpecEditor subclass:#MenuEditor - instanceVariableNames:'treeView typeOfCanvas listOfCanvas listOfSlices - lastImageRetriever slices' + instanceVariableNames:'selectionHolder tabHolder listOfItems listOfTabs + selectedSuperItems notifyDisabledCounter wizards listOfItemsView' classVariableNames:'ImageRetrieverClasses' poolDictionaries:'' category:'Interface-UIPainter' ! -Object subclass:#Item - instanceVariableNames:'activeHelpKey enabled label value nameKey indication shortcutKey - accessCharacterPos retriever icon iconAndLabel submenuChannel - startGroup argument translateLabel isButton isVisible choice - choiceValue auxValue hideMenuOnActivated font horizontalLayout - showBusyCursorWhilePerforming keepLinkedMenu triggerOnDown' +HierarchicalItem subclass:#Item + instanceVariableNames:'menuItem' + classVariableNames:'' + poolDictionaries:'' + privateIn:MenuEditor +! + +MenuEditor::Item subclass:#ItemAction + instanceVariableNames:'' + classVariableNames:'' + poolDictionaries:'' + privateIn:MenuEditor +! + +MenuEditor::Item subclass:#ItemLinkedMenu + instanceVariableNames:'' classVariableNames:'' poolDictionaries:'' privateIn:MenuEditor ! -SelectionInTreeView subclass:#TreeView +MenuEditor::Item subclass:#ItemMenu + instanceVariableNames:'' + classVariableNames:'' + poolDictionaries:'' + privateIn:MenuEditor +! + +MenuEditor::ItemMenu subclass:#ItemRoot + instanceVariableNames:'' + classVariableNames:'' + poolDictionaries:'' + privateIn:MenuEditor +! + +MenuEditor::Item subclass:#ItemSeparator instanceVariableNames:'' classVariableNames:'' poolDictionaries:'' privateIn:MenuEditor ! +ApplicationModel subclass:#ResourceEditor + instanceVariableNames:'selectorHolder iconAndLabelHolder retrieverHolder imageHolder + imageList imageViewer' + classVariableNames:'' + poolDictionaries:'' + privateIn:MenuEditor +! + +HierarchicalItem subclass:#ResourceEditorItem + instanceVariableNames:'selector icon' + classVariableNames:'' + poolDictionaries:'' + privateIn:MenuEditor +! + !MenuEditor class methodsFor:'documentation'! copyright " COPYRIGHT (c) 1997 by eXept Software AG - All Rights Reserved + 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 @@ -54,38 +91,45 @@ other person. No title to or ownership of the software is hereby transferred. " - - ! documentation " The MenuEditor allows you to create, modify or just inspect - hierarchical menus of menu bars, popup menu, or tool bar menus. + menus. + + + [Instance variables:] + + selectionHolder collection of current selected items + tabHolder selected tab label holder + listOfItems hierarchical list of menu items + listOfTabs list of current shown tab-labels + wizards keeps all created wizard dialogs + selectedSuperItems collection of superItems derived from selection + notifyDisabledCounter ~~ 0 than change notifications are discard + + [Class variables:] + ImageRetrieverClasses sorted collection of image receivers [start with:] - MenuEditor open - MenuEditor openOnClass:MenuEditor andSelector:#menu - - [see also:] - UIPainter + MenuEditor open + MenuEditor openOnClass:MenuEditor andSelector:#menu [author:] - Claus Atzkern, eXept Software AG - Thomas Zwick, eXept Software AG + Claus Atzkern, eXept Software AG + Thomas Zwick, eXept Software AG " - ! ! !MenuEditor class methodsFor:'initialization'! initialize ImageRetrieverClasses := #( - Icon - NewLauncher - SystemBrowser - ToolbarIconLibrary - ) + Icon + SystemBrowser + ToolbarIconLibrary + ). " self initialize @@ -95,30 +139,10 @@ !MenuEditor class methodsFor:'instance creation'! openModalOnMenu: aMenu - "Open a MenuEditor modal on aMenu" - "self openModalOnMenu: (self perform: #menu) decodeAsLiteralArray" - - ^self new openModalOnMenu: aMenu -! ! - -!MenuEditor class methodsFor:'accessing'! - -iconUnknown - "returns an image used for picked items containing an image + "Open a MenuEditor modal on aMenu + self openModalOnMenu: (self perform: #menu) decodeAsLiteralArray " - - - ^ MenuPanelSpec icon -! - -resourceType - "get the type of resource of the method generated by the MenuEditor" - - ^#menu - - - - + ^self new openModalOnMenu:aMenu ! ! !MenuEditor class methodsFor:'accessing image retriever'! @@ -129,19 +153,19 @@ |key| aSymbolOrClass isBehavior ifTrue:[ - key := aSymbolOrClass nameWithNameSpacePrefix + key := aSymbolOrClass nameWithNameSpacePrefix ] ifFalse:[ - key := aSymbolOrClass + key := aSymbolOrClass ]. key size ~~ 0 ifTrue:[ - key := key asSymbol. - - (ImageRetrieverClasses includes:key) ifFalse:[ - ImageRetrieverClasses := ImageRetrieverClasses asOrderedCollection. - ImageRetrieverClasses add:key. - ImageRetrieverClasses sort. - ] + key := key asSymbol. + + (ImageRetrieverClasses includes:key) ifFalse:[ + ImageRetrieverClasses := ImageRetrieverClasses asOrderedCollection. + ImageRetrieverClasses add:key. + ImageRetrieverClasses sort. + ] ]. ! @@ -157,74 +181,59 @@ "get the aspects for the attributes of the menu components" ^#( - label - accessCharacterPos - showBusyCursorWhilePerforming - horizontalLayout - triggerOnDown - font - argument - submenuChannel - keepLinkedMenu - enabled - value - nameKey - indication - choice - choiceValue - translateLabel - isButton - shortcutKey - startGroup - retriever - iconAndLabel - icon - isVisible - hideMenuOnActivated - auxValue + rawLabel + accessCharacterPosition + showBusyCursorWhilePerforming + horizontalLayout + triggerOnDown + font + argument + submenuChannel + keepLinkedMenu + enabled + value + nameKey + indication + choice + choiceValue + translateLabel + isButton + shortcutKeyCharacter + startGroup + isVisible + hideMenuOnActivated + auxValue + activeHelpKey + resourceRetriever ) - - "Modified: / 14.8.1998 / 14:46:36 / cg" +! ! + +!MenuEditor class methodsFor:'defaults'! + +aboutImage + "the image to be displayed in my about-box; + If nil is returned, the ST/X default image is used. + " + ^ Image fromFile:'bitmaps/xpmBitmaps/misc_tools/setup_menus.xpm' +! + +resourceType + "get the type of the resource of the method generated by the MenuEditor + " + ^ #menu ! ! !MenuEditor class methodsFor:'help specs'! flyByHelpSpec - - - ^super flyByHelpSpec addPairsFrom:#( - -#addMenuItem -'Add Item' - -#addMenuSeparator -'Add Separator' - -#addSubMenu -'Add SubMenu' - -#addSubMenuLink -'Add linked SubMenu' - -#fileLoad -'Load Menu' - -#fileNew -'New Menu' - -#filePickAMenu -'Pick a menu' - -#fileSave -'Save Menu' - -#fileSaveAs -'Save Menu' - -) + ^super flyByHelpSpec addPairsFrom:(self localHelpSpecStrings) ! helpSpec + ^super helpSpec addPairsFrom:(self localHelpSpecStrings) +! + +localHelpSpecStrings "This resource specification was automatically generated by the UIHelpTool of ST/X." @@ -237,7 +246,13 @@ - ^super helpSpec addPairsFrom:#( + ^ #( + +#addDelayedMenu +'Add a new delayed menu to item.' + +#addDelayedSubMenuLink +'Add a new linked delayed menu to item.' #addMenuItem 'Add a new menu item.' @@ -329,9 +344,15 @@ #fileSaveAs 'Open a dialog to save the menu spec (and the help spec, if modified).' +#fileShowMenuSpec +'Opens a Workspace showing the current menu spec.' + #hideMenuOnActivated 'If on, the menu hides itself after the item was activated.' +#horizontalLayout +'If on, the submenu organizes its items horizontal insteat of vertical (default).' + #imageImageAndLabel 'Toggle display of both image and textual label.' @@ -356,1011 +377,21 @@ #triggerOnDown 'If on, the items action is performed on mouse-button press (default is on button-release).' -#horizontalLayout -'If on, the submenu organizes its items horizontal insteat of vertical (default).' - ) ! ! !MenuEditor class methodsFor:'image specs'! -linkSubmenuImage - "This resource specification was automatically generated - by the ImageEditor of ST/X." - - "Do not manually edit this!!!! If it is corrupted, - the ImageEditor may not be able to read the specification." - - " - ImageEditor openOnClass:self andSelector:#linkSubmenuImage - " - - - - ^Icon - constantNamed:#'MenuEditor linkSubmenuImage' - ifAbsentPut:[(Depth4Image new) width: 22; height: 22; photometric:(#palette); bitsPerSample:(#(4 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@@@@@@@@@@@@@ADQDQDQDQDQDQH@D"H"H"H"H"H"K0@RH"H"H"H"H"H/@A????????????<@D@@@@@@@@@@@C0@PL3L0DQDQDQD_@A@3L3LBH"H"H"<@DCL3L3@"H"H"K0@PL3L3L0??????@A@@@@L3L@@@@@<@DQDQDCL3@PLAG0@RH"H"@3L0@3@/@AH"H"H L3L3L0<@G????? - - ^Icon - constantNamed:#'MenuEditor menuItemImage' - ifAbsentPut:[(Depth2Image new) width: 22; height: 22; photometric:(#palette); bitsPerSample:(#(2 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'UUUUUUUQUUUUUUUPUUUUUUU_UUUUUUUPUUUUUUUP@@@@@@@@EUUUUUVAF*****+HF:?+::;@F:.+*?;@F:.+::;@F:.+*:;@F:.+::;@F*****+DK??????A@@@@@@@@UUUUUUUPUUUUUUUXUUUUUUUPUUUUUUUPUUUUUUUPUUUUUUUX') ; colorMapFromArray:#[0 0 0 255 255 255 170 170 170 127 127 127]; mask:((Depth1Image new) width: 22; height: 22; photometric:(#blackIs0); bitsPerSample:(#(1 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@@@@@@@@@@@@@@@@@@??? - - ^Icon - constantNamed:#'MenuEditor menuSeparatorImage' - ifAbsentPut:[(Depth2Image new) width: 22; height: 22; photometric:(#palette); bitsPerSample:(#(2 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'UUUUUUURUUUUUUUPUUUUUUUPUUUUUUUPUUUUUUUP@@@@@@@@EUUUUUV@F*****+DF*****+CF?????+@F0@@@@[@F%UUUU[HF*****+@F*****+@K??????N@@@@@@@HUUUUUUUPUUUUUUUPUUUUUUUWUUUUUUUXUUUUUUUPUUUUUUUP') ; colorMapFromArray:#[0 0 0 255 255 255 170 170 170 127 127 127]; mask:((Depth1Image new) width: 22; height: 22; photometric:(#blackIs0); bitsPerSample:(#(1 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@@@@@@@@@@@@@@@@@@??? - - ^Icon - constantNamed:#'MenuEditor submenuImage' - ifAbsentPut:[(Depth2Image new) width: 22; height: 22; photometric:(#palette); bitsPerSample:(#(2 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@@@@@@EUUUUUV@F*****+@F*****+@G??????GD@@@@@C@EUUUUUWLF*****+@F*****+@G??????HD@@@@@C@EUUUUUW@F*****+@F*****+OG??????@D@@@@@C@EUUUUUW@F*****+@F*****+@K??????@@@@@@@@@@@@@@@@@') ; colorMapFromArray:#[0 0 0 255 255 255 170 170 170 127 127 127]; mask:((Depth1Image new) width: 22; height: 22; photometric:(#blackIs0); bitsPerSample:(#(1 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'??? + + ^ MenuPanelSpec icon ! ! !MenuEditor class methodsFor:'interface specs'! -basicsItemSpec - "This resource specification was automatically generated - by the UIPainter of ST/X." - - "Do not manually edit this!! If it is corrupted, - the UIPainter may not be able to read the specification." - - " - UIPainter new openOnClass:MenuEditor andSelector:#basicsItemSpec - MenuEditor new openInterface:#basicsItemSpec - " - - - - ^ - #(#FullSpec - #name: #basicsItemSpec - #window: - #(#WindowSpec - #label: 'Basics Item' - #name: 'Basics Item' - #min: #(#Point 10 10) - #max: #(#Point 1160 870) - #bounds: #(#Rectangle 898 390 1173 751) - ) - #component: - #(#SpecCollection - #collection: #( - #(#LabelSpec - #label: 'Name Key:' - #name: 'nameKeyLabel' - #layout: #(#AlignmentOrigin 107 0 26 0 1 0.5) - #activeHelpKey: #basicsKey - #resizeForLabel: true - #adjust: #right - ) - #(#InputFieldSpec - #name: 'nameKeyField' - #layout: #(#LayoutFrame 110 0 16 0 -5 1.0 38 0) - #activeHelpKey: #basicsKey - #tabable: true - #model: #nameKey - #group: #inputGroup1 - #type: #symbolOrNil - #acceptOnLeave: false - #acceptOnReturn: true - #acceptOnTab: true - #acceptOnLostFocus: false - #acceptChannel: #acceptChannel - #modifiedChannel: #modifiedChannel - #acceptOnPointerLeave: false - ) - #(#LabelSpec - #label: 'Label:' - #name: 'labelLabel' - #layout: #(#AlignmentOrigin 107 0 51 0 1 0.5) - #activeHelpKey: #basicsLabel - #resizeForLabel: true - #adjust: #right - ) - #(#InputFieldSpec - #name: 'labelField' - #layout: #(#LayoutFrame 110 0 40 0 -5 1.0 62 0) - #activeHelpKey: #basicsLabel - #tabable: true - #model: #label - #group: #inputGroup1 - #acceptOnReturn: true - #acceptOnTab: true - #acceptOnLostFocus: false - #acceptChannel: #acceptChannel - #modifiedChannel: #modifiedChannel - #acceptOnPointerLeave: false - ) - #(#LabelSpec - #label: 'Action:' - #name: 'valueLabel' - #layout: #(#AlignmentOrigin 107 0 85 0 1 0.5) - #activeHelpKey: #basicsAction - #resizeForLabel: true - #adjust: #right - ) - #(#InputFieldSpec - #name: 'valueField' - #layout: #(#LayoutFrame 110 0 74 0 -5 1.0 96 0) - #activeHelpKey: #basicsAction - #tabable: true - #model: #value - #group: #inputGroup1 - #type: #symbolOrNil - #acceptOnReturn: true - #acceptOnTab: true - #acceptOnLostFocus: false - #acceptChannel: #acceptChannel - #modifiedChannel: #modifiedChannel - #acceptOnPointerLeave: false - ) - #(#LabelSpec - #label: 'Argument:' - #name: 'argumentLabel' - #layout: #(#AlignmentOrigin 107 0 110 0 1 0.5) - #activeHelpKey: #basicsArgument - #resizeForLabel: true - #adjust: #right - ) - #(#InputFieldSpec - #name: 'argumentField' - #layout: #(#LayoutFrame 110 0 99 0 -5 1.0 121 0) - #activeHelpKey: #basicsArgument - #tabable: true - #model: #argument - #group: #inputGroup1 - #type: #smalltalkObject - #acceptOnReturn: true - #acceptOnTab: true - #acceptOnLostFocus: false - #acceptChannel: #acceptChannel - #modifiedChannel: #modifiedChannel - #acceptOnPointerLeave: false - ) - #(#LabelSpec - #label: 'Indication:' - #name: 'indicationLabel' - #layout: #(#AlignmentOrigin 107 0 144 0 1 0.5) - #activeHelpKey: #basicsIndication - #resizeForLabel: true - #adjust: #right - ) - #(#InputFieldSpec - #name: 'indicationField' - #layout: #(#LayoutFrame 110 0 133 0 -5 1.0 155 0) - #activeHelpKey: #basicsIndication - #enableChannel: #indicationEnabled - #tabable: true - #model: #indication - #group: #inputGroup1 - #type: #symbolOrNil - #immediateAccept: true - #acceptOnReturn: true - #acceptOnTab: true - #acceptOnLostFocus: false - #acceptChannel: #acceptChannel - #modifiedChannel: #modifiedChannel - #acceptOnPointerLeave: false - ) - #(#LabelSpec - #label: 'Choice:' - #name: 'choiceLabel' - #layout: #(#AlignmentOrigin 107 0 169 0 1 0.5) - #activeHelpKey: #basicsChoice - #translateLabel: true - #resizeForLabel: true - #adjust: #right - ) - #(#InputFieldSpec - #name: 'choiceField' - #layout: #(#LayoutFrame 110 0 158 0 -5 1.0 180 0) - #activeHelpKey: #basicsChoice - #enableChannel: #choiceEnabled - #tabable: true - #model: #choice - #group: #inputGroup1 - #type: #symbolOrNil - #immediateAccept: true - #acceptOnReturn: true - #acceptOnTab: true - #acceptOnLostFocus: false - #acceptChannel: #acceptChannel - #modifiedChannel: #modifiedChannel - #acceptOnPointerLeave: false - ) - #(#LabelSpec - #label: 'Value:' - #name: 'choiceValueLabel' - #layout: #(#AlignmentOrigin 107 0 194 0 1 0.5) - #activeHelpKey: #basicsChoiceValue - #translateLabel: true - #resizeForLabel: true - #adjust: #right - ) - #(#InputFieldSpec - #name: 'choiceValueField' - #layout: #(#LayoutFrame 110 0 183 0 -5 1.0 205 0) - #activeHelpKey: #basicsChoiceValue - #enableChannel: #choiceValueEnabled - #tabable: true - #model: #choiceValue - #group: #inputGroup1 - #type: #smalltalkObject - #acceptOnLeave: false - #acceptOnReturn: true - #acceptOnTab: true - #acceptOnLostFocus: false - #acceptChannel: #acceptChannel - #modifiedChannel: #modifiedChannel - #acceptOnPointerLeave: false - ) - #(#CheckBoxSpec - #label: 'Translate Label' - #name: 'translateLabelCheckBox' - #layout: #(#Point 20 218) - #activeHelpKey: #basicsTranslateLabel - #tabable: true - #model: #translateLabel - ) - #(#CheckBoxSpec - #label: 'Is Button' - #name: 'isButtonCheckBox' - #layout: #(#Point 20 243) - #activeHelpKey: #basicsIsButton - #tabable: true - #model: #isButton - ) - #(#CheckBoxSpec - #label: 'Hide Menu after Activation' - #name: 'hideMenuOnActivated' - #layout: #(#Point 20 267) - #activeHelpKey: #hideMenuOnActivated - #tabable: true - #model: #hideMenuOnActivated - ) - #(#CheckBoxSpec - #label: 'BusyCursor while Active' - #name: 'showBusyCursorWhilePerforming' - #layout: #(#Point 20 291) - #activeHelpKey: #showBusyCursorWhilePerforming - #tabable: true - #model: #showBusyCursorWhilePerforming - #translateLabel: true - ) - #(#CheckBoxSpec - #label: 'Trigger On Down' - #name: 'triggerOnDown' - #layout: #(#Point 20 315) - #activeHelpKey: #triggerOnDown - #tabable: true - #model: #triggerOnDown - #translateLabel: true - ) - ) - - ) - ) -! - -basicsLinkSpec - "This resource specification was automatically generated - by the UIPainter of ST/X." - - "Do not manually edit this!! If it is corrupted, - the UIPainter may not be able to read the specification." - - " - UIPainter new openOnClass:MenuEditor andSelector:#basicsLinkSpec - MenuEditor new openInterface:#basicsLinkSpec - " - - - - ^ - #(#FullSpec - #name: #basicsLinkSpec - #window: - #(#WindowSpec - #label: 'Basics Link' - #name: 'Basics Link' - #min: #(#Point 10 10) - #max: #(#Point 1280 1024) - #bounds: #(#Rectangle 900 124 1167 443) - ) - #component: - #(#SpecCollection - #collection: #( - #(#LabelSpec - #label: 'Name Key:' - #name: 'nameKeyLabel' - #layout: #(#AlignmentOrigin 107 0 26 0 1 0.5) - #activeHelpKey: #nameKey - #resizeForLabel: true - #adjust: #right - ) - #(#InputFieldSpec - #name: 'nameKeyField' - #layout: #(#LayoutFrame 110 0 15 0 -5 1.0 37 0) - #activeHelpKey: #basicsNameKey - #tabable: true - #model: #nameKey - #group: #inputGroup2 - #type: #symbolOrNil - #acceptOnReturn: true - #acceptOnTab: true - #acceptChannel: #acceptChannel - #modifiedChannel: #modifiedChannel - #acceptOnPointerLeave: false - ) - #(#LabelSpec - #label: 'Label:' - #name: 'labelLabel' - #layout: #(#AlignmentOrigin 107 0 51 0 1 0.5) - #resizeForLabel: true - ) - #(#InputFieldSpec - #name: 'labelField' - #layout: #(#LayoutFrame 110 0 40 0 -5 1.0 62 0) - #activeHelpKey: #basicsLabel - #tabable: true - #model: #label - #group: #inputGroup2 - #acceptOnReturn: true - #acceptOnTab: true - #acceptChannel: #acceptChannel - #modifiedChannel: #modifiedChannel - #acceptOnPointerLeave: false - ) - #(#LabelSpec - #label: 'Menu:' - #name: 'menuLabel' - #layout: #(#AlignmentOrigin 107 0 76 0 1 0.5) - #resizeForLabel: true - ) - #(#InputFieldSpec - #name: 'menuField' - #layout: #(#LayoutFrame 110 0 65 0 -5 1.0 87 0) - #activeHelpKey: #basicsMenu - #tabable: true - #model: #submenuChannel - #group: #inputGroup2 - #type: #symbolOrNil - #acceptOnReturn: true - #acceptOnTab: true - #acceptChannel: #acceptChannel - #modifiedChannel: #modifiedChannel - #acceptOnPointerLeave: false - ) - #(#LabelSpec - #label: 'Argument:' - #name: 'ArgumentLabel' - #layout: #(#AlignmentOrigin 107 0 100 0 1 0.5) - #resizeForLabel: true - ) - #(#InputFieldSpec - #name: 'argumentField' - #layout: #(#LayoutFrame 110 0 90 0 -5 1.0 112 0) - #activeHelpKey: #basicsMenuArgument - #tabable: true - #model: #argument - #group: #inputGroup2 - #acceptOnReturn: true - #acceptOnTab: true - #acceptChannel: #acceptChannel - #modifiedChannel: #modifiedChannel - #acceptOnPointerLeave: false - ) - #(#CheckBoxSpec - #label: 'Translate Label' - #name: 'translateLabelCheckBox' - #layout: #(#Point 20 190) - #activeHelpKey: #basicsTranslateLabel - #tabable: true - #model: #translateLabel - ) - #(#CheckBoxSpec - #label: 'Has Horizontal Layout' - #name: 'horizontalLayout' - #layout: #(#Point 20 217) - #activeHelpKey: #horizontalLayout - #tabable: true - #model: #horizontalLayout - ) - #(#CheckBoxSpec - #label: 'Do not destroy linked Menu' - #name: 'keepLinkedMenu' - #layout: #(#Point 20 244) - #tabable: true - #activeHelpKey: #keepLinkedMenu - #model: #keepLinkedMenu - #translateLabel: true - ) - ) - - ) - ) -! - -basicsMenuSpec - "This resource specification was automatically generated - by the UIPainter of ST/X." - - "Do not manually edit this!! If it is corrupted, - the UIPainter may not be able to read the specification." - - " - UIPainter new openOnClass:MenuEditor andSelector:#basicsMenuSpec - MenuEditor new openInterface:#basicsMenuSpec - " - - - - ^ - #(#FullSpec - #name: #basicsMenuSpec - #window: - #(#WindowSpec - #label: 'Basics Menu' - #name: 'Basics Menu' - #min: #(#Point 10 10) - #max: #(#Point 1280 1024) - #bounds: #(#Rectangle 93 223 360 542) - ) - #component: - #(#SpecCollection - #collection: #( - #(#LabelSpec - #label: 'Name Key:' - #name: 'nameKeyLabel' - #layout: #(#AlignmentOrigin 107 0 26 0 1 0.5) - #resizeForLabel: true - #adjust: #right - ) - #(#InputFieldSpec - #name: 'nameKeyField' - #layout: #(#LayoutFrame 110 0 15 0 -5 1.0 37 0) - #activeHelpKey: #basicsNameKey - #tabable: true - #model: #nameKey - #group: #inputGroup3 - #type: #symbolOrNil - #acceptOnReturn: true - #acceptOnTab: true - #acceptChannel: #acceptChannel - #modifiedChannel: #modifiedChannel - #acceptOnPointerLeave: false - ) - #(#LabelSpec - #label: 'Label:' - #name: 'labelLabel' - #layout: #(#AlignmentOrigin 107 0 51 0 1 0.5) - #resizeForLabel: true - #adjust: #right - ) - #(#InputFieldSpec - #name: 'labelField' - #layout: #(#LayoutFrame 110 0 40 0 -5 1.0 62 0) - #activeHelpKey: #basicsLabel - #tabable: true - #model: #label - #group: #inputGroup3 - #acceptOnReturn: true - #acceptOnTab: true - #acceptChannel: #acceptChannel - #modifiedChannel: #modifiedChannel - #acceptOnPointerLeave: false - ) - #(#CheckBoxSpec - #label: 'Translate Label' - #name: 'translateLabelCheckBox' - #layout: #(#Point 20 190) - #activeHelpKey: #basicsTranslateLabel - #tabable: true - #model: #translateLabel - ) - #(#CheckBoxSpec - #label: 'Has Horizontal Orientation' - #name: 'horizontalLayout' - #layout: #(#Point 20 217) - #activeHelpKey: #horizontalLayout - #tabable: true - #model: #horizontalLayout - ) - - ) - - ) - ) -! - -basicsRootSpec - "This resource specification was automatically generated - by the UIPainter of ST/X." - - "Do not manually edit this!! If it is corrupted, - the UIPainter may not be able to read the specification." - - " - UIPainter new openOnClass:MenuEditor andSelector:#basicsRootSpec - MenuEditor new openInterface:#basicsRootSpec - " - - - - ^ - #(#FullSpec - #name: #basicsRootSpec - #window: - #(#WindowSpec - #label: 'Basics Root' - #name: 'Basics Root' - #layout: #(#LayoutFrame 11 0 100 0 277 0 418 0) - #level: 0 - #min: #(#Point 10 10) - #max: #(#Point 1280 1024) - #bounds: #(#Rectangle 11 100 278 419) - #usePreferredExtent: false - #returnIsOKInDialog: true - #escapeIsCancelInDialog: true - ) - #component: - #(#SpecCollection - #collection: #( - #(#LabelSpec - #label: 'Selector:' - #name: 'selectorLabel' - #layout: #(#AlignmentOrigin 107 0 26 0 1 0.5) - #resizeForLabel: true - #adjust: #right - #activeHelpKey: #basicsSelector - ) - #(#InputFieldSpec - #name: 'selectorField' - #layout: #(#LayoutFrame 110 0 15 0 -5 1.0 37 0) - #activeHelpKey: #basicsSelector - #tabable: true - #model: #label - #group: #inputGroup - #acceptOnReturn: true - #acceptOnTab: true - #acceptChannel: #acceptChannel - #modifiedChannel: #modifiedChannel - #acceptOnPointerLeave: false - ) - ) - - ) - ) -! - -basicsSeparatorSpec - "This resource specification was automatically generated - by the UIPainter of ST/X." - - "Do not manually edit this!! If it is corrupted, - the UIPainter may not be able to read the specification." - - " - UIPainter new openOnClass:MenuEditor andSelector:#basicsSeparatorSpec - MenuEditor new openInterface:#basicsSeparatorSpec - " - - - - ^ - #(#FullSpec - #name: #basicsSeparatorSpec - #window: - #(#WindowSpec - #label: 'Basics Separator' - #name: 'Basics Separator' - #layout: #(#LayoutFrame 9 0 149 0 275 0 467 0) - #level: 0 - #min: #(#Point 10 10) - #max: #(#Point 1160 870) - #bounds: #(#Rectangle 9 149 276 468) - #usePreferredExtent: false - #returnIsOKInDialog: true - #escapeIsCancelInDialog: true - ) - #component: - #(#SpecCollection - #collection: #( - #(#LabelSpec - #label: 'Separator Type:' - #name: 'separatorLabel' - #layout: #(#AlignmentOrigin 127 0 26 0 1 0.5) - #resizeForLabel: true - #adjust: #right - ) - #(#ComboListSpec - #name: 'seperatorList' - #layout: #(#LayoutFrame 132 0 15 0 -5 1.0 37 0) - #activeHelpKey: #basicsSeparatorType - #tabable: true - #model: #seperatorSelection - #useIndex: true - ) - #(#LabelSpec - #label: 'Visibility:' - #name: 'visibilityLabel' - #layout: #(#AlignmentOrigin 127 0 76 0 1 0.5) - #resizeForLabel: true - #adjust: #right - ) - #(#InputFieldSpec - #name: 'visibilityInputField' - #layout: #(#LayoutFrame 132 0 65 0 -5 1.0 87 0) - #activeHelpKey: #detailsVisibility - #tabable: true - #model: #isVisible - #group: #inputGroup - #type: #symbolOrNil - #acceptOnReturn: true - #acceptOnTab: true - #acceptChannel: #acceptChannel - #modifiedChannel: #modifiedChannel - #acceptOnPointerLeave: false - ) - ) - - ) - ) -! - -detailsEditSpec - "This resource specification was automatically generated - by the UIPainter of ST/X." - - "Do not manually edit this!! If it is corrupted, - the UIPainter may not be able to read the specification." - - " - UIPainter new openOnClass:MenuEditor andSelector:#detailsEditSpec - MenuEditor new openInterface:#detailsEditSpec - " - - - - ^ - #(#FullSpec - #name: #detailsEditSpec - #window: - #(#WindowSpec - #label: 'Details Edit' - #name: 'Details Edit' - #min: #(#Point 10 10) - #max: #(#Point 1280 1024) - #bounds: #(#Rectangle 12 22 327 306) - ) - #component: - #(#SpecCollection - #collection: #( - #(#LabelSpec - #label: 'Accelerator:' - #name: 'shortcutKeyLabel' - #layout: #(#AlignmentOrigin 107 0 26 0 1 0.5) - #activeHelpKey: #detailsAccelerator - #resizeForLabel: true - #adjust: #right - ) - #(#InputFieldSpec - #name: 'shortcutKeyField' - #layout: #(#LayoutFrame 110 0 15 0 -5 1.0 37 0) - #activeHelpKey: #detailsAccelerator - #tabable: true - #model: #shortcutKey - #group: #inputGroup4 - #type: #symbolOrNil - #acceptOnReturn: true - #acceptOnTab: true - #acceptChannel: #acceptChannel - #modifiedChannel: #modifiedChannel - #acceptOnPointerLeave: false - ) - #(#LabelSpec - #label: 'Enabled:' - #name: 'enabledLabel' - #layout: #(#AlignmentOrigin 107 0 51 0 1 0.5) - #activeHelpKey: #detailsEnabled - #resizeForLabel: true - #adjust: #right - ) - #(#InputFieldSpec - #name: 'enabledField' - #layout: #(#LayoutFrame 110 0 40 0 -5 1.0 62 0) - #activeHelpKey: #detailsEnabled - #tabable: true - #model: #enabled - #group: #inputGroup4 - #type: #symbolOrNil - #acceptOnReturn: true - #acceptOnTab: true - #acceptChannel: #acceptChannel - #modifiedChannel: #modifiedChannel - #acceptOnPointerLeave: false - ) - #(#LabelSpec - #label: 'Visibility:' - #name: 'visibilityLabel' - #layout: #(#AlignmentOrigin 107 0 76 0 1 0.5) - #activeHelpKey: #detailsVisibility - #resizeForLabel: true - #adjust: #right - ) - #(#InputFieldSpec - #name: 'isVisibleInputField' - #layout: #(#LayoutFrame 110 0 65 0 -5 1.0 87 0) - #activeHelpKey: #detailsVisibility - #tabable: true - #model: #isVisible - #group: #inputGroup4 - #type: #symbolOrNil - #acceptOnReturn: true - #acceptOnTab: true - #acceptChannel: #acceptChannel - #modifiedChannel: #modifiedChannel - #acceptOnPointerLeave: false - ) - #(#LabelSpec - #label: 'Aux Value' - #name: 'auxLabel' - #layout: #(#AlignmentOrigin 107 0 101 0 1 0.5) - #activeHelpKey: #detailsAuxValue - #translateLabel: true - #resizeForLabel: true - #adjust: #right - ) - #(#InputFieldSpec - #name: 'auxInputField' - #layout: #(#LayoutFrame 110 0 90 0 -5 1.0 112 0) - #activeHelpKey: #detailsAuxValue - #tabable: true - #model: #auxValue - #group: #inputGroup4 - #type: #smalltalkObject - #acceptOnReturn: true - #acceptOnTab: true - #acceptChannel: #acceptChannel - #modifiedChannel: #modifiedChannel - #acceptOnPointerLeave: false - ) - #(#LabelSpec - #label: 'Start Group:' - #name: 'StartGroupLabel' - #layout: #(#AlignmentOrigin 107 0 139 0 1 0.5) - #activeHelpKey: #detailsStartGroup - #resizeForLabel: true - #adjust: #right - ) - #(#PopUpListSpec - #label: 'left' - #name: 'StartGroupPopUp' - #layout: #(#LayoutFrame 110 0 128 0 -5 1.0 150 0) - #activeHelpKey: #detailsStartGroup - #tabable: true - #model: #startGroup - #menu: - #(#left - #right - ) - #useIndex: false - ) - #(#LabelSpec - #label: 'Access Character Position:' - #name: 'accessCharLabel' - #layout: #(#AlignmentOrigin 217 0 170 0 1 0.5) - #activeHelpKey: #detailsAccessCharaterPosition - #resizeForLabel: true - #adjust: #right - ) - #(#InputFieldSpec - #name: 'accessCharField' - #layout: #(#LayoutFrame 220 0 159 0 -5 1.0 181 0) - #activeHelpKey: #detailsAccessCharaterPosition - #tabable: true - #model: #accessCharacterPos - #group: #inputGroup4 - #type: #numberOrNil - #immediateAccept: false - #acceptOnReturn: true - #acceptOnTab: true - #acceptChannel: #acceptChannel - #modifiedChannel: #modifiedChannel - #acceptOnPointerLeave: false - ) - #(#LabelSpec - #label: 'Font:' - #name: 'fontLabel' - #layout: #(#AlignmentOrigin 75 0 231 0 1 0.5) - #resizeForLabel: true - #adjust: #right - ) - #(#FontMenuSpec - #attributes: - #(#tabable - true - ) - #name: 'fontMenu' - #layout: #(#LayoutFrame 78 0 220 0 -5 1.0 242 0) - #activeHelpKey: #fontMenu - #model: #font - ) - ) - - ) - ) -! - -imageEditSpec - "This resource specification was automatically generated - by the UIPainter of ST/X." - - "Do not manually edit this!! If it is corrupted, - the UIPainter may not be able to read the specification." - - " - UIPainter new openOnClass:MenuEditor andSelector:#imageEditSpec - MenuEditor new openInterface:#imageEditSpec - " - - - - ^ - #(#FullSpec - #name: #imageEditSpec - #window: - #(#WindowSpec - #label: 'Image Item' - #name: 'Image Item' - #min: #(#Point 10 10) - #max: #(#Point 1280 1024) - #bounds: #(#Rectangle 12 22 300 317) - ) - #component: - #(#SpecCollection - #collection: #( - #(#LabelSpec - #label: 'Retriever:' - #name: 'retrieverLabel' - #layout: #(#AlignmentOrigin 107 0 26 0 1 0.5) - #activeHelpKey: #imageRetriever - #resizeForLabel: true - #adjust: #right - ) - #(#ComboBoxSpec - #name: 'retrieverField' - #layout: #(#LayoutFrame 110 0 15 0 -20 1.0 37 0) - #activeHelpKey: #imageRetriever - #tabable: true - #model: #retriever - #type: #symbolOrNil - #acceptOnReturn: true - #acceptOnTab: true - #acceptChannel: #acceptChannel - #acceptOnPointerLeave: false - #comboList: #retrieverClassList - ) - #(#LabelSpec - #label: 'Selector:' - #name: 'iconLabel' - #layout: #(#AlignmentOrigin 107 0 51 0 1 0.5) - #activeHelpKey: #imageSelector - #resizeForLabel: true - #adjust: #right - ) - #(#InputFieldSpec - #name: 'iconField' - #layout: #(#LayoutFrame 110 0 40 0 -42 1.0 62 0) - #activeHelpKey: #imageSelector - #tabable: true - #model: #icon - #group: #inputGroup5 - #type: #symbolOrNil - #acceptOnReturn: true - #acceptOnTab: true - #acceptChannel: #acceptChannel - #modifiedChannel: #modifiedChannel - #acceptOnPointerLeave: false - ) - #(#ActionButtonSpec - #label: '...' - #name: 'browseButton' - #layout: #(#LayoutFrame -40 1 40 0 -20 1 62 0) - #activeHelpKey: #browseResource - #tabable: true - #model: #doBrowseForImageResource - ) - #(#SelectionInListModelViewSpec - #name: 'selectionOfImage' - #layout: #(#LayoutFrame 20 0.0 67 0 -20 1.0 -30 1.0) - #activeHelpKey: #imageImageList - #tabable: true - #model: #selectionOfImage - #menu: #menuEditImage - #hasHorizontalScrollBar: true - #hasVerticalScrollBar: true - #miniScrollerHorizontal: true - #listModel: #listOfImages - #useIndex: false - #highlightMode: #line - #doubleClickSelector: #doEditImage - #valueChangeSelector: #imageSelected - ) - #(#ViewSpec - #name: 'Box1' - #layout: #(#LayoutFrame 20 0.0 -30 1.0 -20 1.0 0 1.0) - #level: 0 - #component: - #(#SpecCollection - #collection: #( - #(#CheckBoxSpec - #label: 'Image & Label' - #name: 'iconAndLabelCheckBox' - #layout: #(#AlignmentOrigin 0 0 0 0.5 0 0.5) - #activeHelpKey: #imageImageAndLabel - #tabable: true - #model: #iconAndLabel - ) - #(#ActionButtonSpec - #label: 'Image Editor' - #name: 'imageEditorButton' - #layout: #(#AlignmentOrigin 0 1.0 0 0.5 1 0.5) - #activeHelpKey: #imageImageEditor - #tabable: true - #model: #doEditImage - ) - ) - - ) - ) - ) - - ) - ) -! - windowSpec "This resource specification was automatically generated by the UIPainter of ST/X." @@ -1383,9 +414,9 @@ #(#WindowSpec #label: 'Menu Editor' #name: 'Menu Editor' - #min: #(#Point 550 440) + #min: #(#Point 550 385) #max: #(#Point 1152 900) - #bounds: #(#Rectangle 61 493 618 974) + #bounds: #(#Rectangle 117 275 693 750) #menu: #menu #returnIsOKInDialog: false #escapeIsCancelInDialog: false @@ -1394,10 +425,10 @@ #(#SpecCollection #collection: #( #(#MenuPanelSpec - #name: 'menuToolbarView' + #name: 'toolbar' #layout: #(#LayoutFrame 0 0.0 0 0 0 1.0 32 0) #tabable: true - #menu: #menuToolbar + #menu: #toolbar #showSeparatingLines: true ) #(#VariableHorizontalPanelSpec @@ -1406,13 +437,31 @@ #component: #(#SpecCollection #collection: #( - #(#ArbitraryComponentSpec - #name: 'TreeView' - #menu: #menuEdit + #(#HierarchicalListViewSpec + #name: 'ListOfItemsView' + #model: #selectionHolder + #menu: #editMenu #hasHorizontalScrollBar: true #hasVerticalScrollBar: true - #hasBorder: false - #component: #treeView + #miniScrollerHorizontal: true + #miniScrollerVertical: true + #listModel: #listOfItems + #multipleSelectOk: true + #useIndex: false + #highlightMode: #label + #doubleClickSelector: #indicatorClickedAt: + #selectConditionSelector: #canSelect: + #showLeftIndicators: false + #indicatorSelector: #indicatorClickedAt: + #properties: + #(#PropertyListDictionary + #dragArgument: nil + #dropObjectSelector: #dropObjects + #dropArgument: nil + #canDropSelector: #canDrop: + #dropSelector: #doDrop: + ) + #postBuildCallback: #postBuildListOfItemsView: ) #(#ViewSpec #name: 'Box' @@ -1423,12 +472,12 @@ #(#NoteBookViewSpec #name: 'NoteBook' #layout: #(#LayoutFrame 1 0.0 0 0.0 1 1.0 -30 1.0) - #enableChannel: #hasAnySingleSelection + #enableChannel: #hasSingleSelectionChannel #tabable: true - #model: #tabModel - #menu: #tabList - #useIndex: true - #canvas: #tabCanvasHolder + #model: #tabHolder + #menu: #listOfTabs + #fitLastRow: false + #canvas: #wizardHolder #keepCanvasAlive: true ) #(#UISubSpecification @@ -1444,7 +493,7 @@ ) ) - #handles: #(#Any 0.346499 1.0) + #handles: #(#Any 0.300493 1.0) ) #(#UISubSpecification #name: 'InfoBarSubSpec' @@ -1460,6 +509,319 @@ !MenuEditor class methodsFor:'menu specs'! +addMenu + "This resource specification was automatically generated + by the MenuEditor of ST/X." + + "Do not manually edit this!! If it is corrupted, + the MenuEditor may not be able to read the specification." + + " + MenuEditor new openOnClass:MenuEditor andSelector:#addMenu + (Menu new fromLiteralArrayEncoding:(MenuEditor addMenu)) startUp + " + + + + ^ + #(#Menu + #( + #(#MenuItem + #label: 'Separator' + #translateLabel: true + #value: #doCreateSep + #activeHelpKey: #addMenuSeparator + #labelImage: #(#ResourceRetriever #'MenuEditor::Item' #iconSeparator '') + ) + #(#MenuItem + #label: 'Item' + #translateLabel: true + #value: #doCreateItem + #activeHelpKey: #addMenuItem + #labelImage: #(#ResourceRetriever #'MenuEditor::Item' #iconItem '') + ) + #(#MenuItem + #label: 'Menu' + #translateLabel: true + #value: #doCreateMenu + #activeHelpKey: #addMenuItem + #labelImage: #(#ResourceRetriever #'MenuEditor::Item' #iconMenu '') + ) + #(#MenuItem + #label: 'Linked Menu' + #value: #doCreateLinkedMenu + #activeHelpKey: #addSubMenuLink + #labelImage: #(#ResourceRetriever #'MenuEditor::Item' #iconLinkedMenu '') + ) + #(#MenuItem + #label: '-' + ) + #(#MenuItem + #label: 'Delayed Menu' + #value: #doCreateDelayedMenu: + #enabled: #canCreateDelayedMenuChannel + #activeHelpKey: #addDelayedMenu + #argument: #menu + #labelImage: #(#ResourceRetriever #'MenuEditor::Item' #iconDelayedMenu '') + ) + #(#MenuItem + #label: 'Delayed Linked Menu' + #value: #doCreateDelayedMenu: + #enabled: #canCreateDelayedMenuChannel + #activeHelpKey: #addDelayedSubMenuLink + #argument: #linkedMenu + #labelImage: #(#ResourceRetriever #'MenuEditor::Item' #iconDelayedLinkedMenu '') + ) + #(#MenuItem + #label: '-' + ) + #(#MenuItem + #label: 'Standard Menus' + #translateLabel: true + #submenuChannel: #standardMenus + #keepLinkedMenu: true + ) + ) + nil + nil + ) +! + +editMenu + "This resource specification was automatically generated + by the MenuEditor of ST/X." + + "Do not manually edit this!! If it is corrupted, + the MenuEditor may not be able to read the specification." + + " + MenuEditor new openOnClass:MenuEditor andSelector:#editMenu + (Menu new fromLiteralArrayEncoding:(MenuEditor editMenu)) startUp + " + + + + ^ + #(#Menu + #( + #(#MenuItem + #label: 'Cut' + #value: #doCut + #activeHelpKey: #editCut + #enabled: #hasSelectionChannel + ) + #(#MenuItem + #label: 'Copy' + #value: #doCopy + #activeHelpKey: #editCopy + #enabled: #hasSelectionChannel + ) + #(#MenuItem + #label: 'Paste' + #value: #doPaste + #activeHelpKey: #editPaste + #enabled: #valueOfCanPaste + ) + #(#MenuItem + #label: 'Delete' + #value: #doDelete + #activeHelpKey: #editDelete + #enabled: #hasSelectionChannel + ) + #(#MenuItem + #label: '-' + ) + #(#MenuItem + #label: 'Move Up' + #startGroup: #right + #value: #doMoveUpOrDown: + #activeHelpKey: #editMoveUp + #enabled: #valueOfEnableMovingUpOrDown + #argument: #up + #labelImage: #(#ResourceRetriever #Icon #upIcon 'Move Up') + ) + #(#MenuItem + #label: 'Move Down' + #value: #doMoveUpOrDown: + #activeHelpKey: #editMoveDown + #enabled: #valueOfEnableMovingUpOrDown + #argument: #down + #labelImage: #(#ResourceRetriever #Icon #downIcon 'Move Down') + ) + #(#MenuItem + #label: 'Move In' + #value: #doMoveIn: + #activeHelpKey: #editMoveIn + #enabled: #valueOfEnableMovingIn + #argument: #inNext + #labelImage: #(#ResourceRetriever #Icon #downRightIcon 'Move In') + ) + #(#MenuItem + #label: 'Move In Above' + #value: #doMoveIn: + #activeHelpKey: #editMoveInAbove + #enabled: #valueOfEnableMovingInAbove + #argument: #inPrev + #labelImage: #(#ResourceRetriever #Icon #upRightIcon 'Move In Above') + ) + #(#MenuItem + #label: 'Move Out' + #value: #doMoveOut + #activeHelpKey: #editMoveOut + #enabled: #valueOfEnableMovingOut + #labelImage: #(#ResourceRetriever #Icon #leftDownIcon 'Move Out') + ) + ) + nil + nil + ) +! + +fileMenu + "This resource specification was automatically generated + by the MenuEditor of ST/X." + + "Do not manually edit this!! If it is corrupted, + the MenuEditor may not be able to read the specification." + + " + MenuEditor new openOnClass:MenuEditor andSelector:#fileMenu + (Menu new fromLiteralArrayEncoding:(MenuEditor fileMenu)) startUp + " + + + + ^ + #(#Menu + #( + #(#MenuItem + #label: 'New' + #translateLabel: true + #value: #doNew + #activeHelpKey: #fileNew + ) + #(#MenuItem + #label: '-' + ) + #(#MenuItem + #label: 'Load...' + #translateLabel: true + #value: #doLoad + #activeHelpKey: #fileLoad + ) + #(#MenuItem + #label: '-' + ) + #(#MenuItem + #label: 'Save' + #translateLabel: true + #value: #doSave + #activeHelpKey: #fileSave + ) + #(#MenuItem + #label: 'Save As...' + #translateLabel: true + #value: #doSaveAs + #activeHelpKey: #fileSaveAs + ) + #(#MenuItem + #label: '-' + ) + #(#MenuItem + #label: 'Pick a Menu...' + #translateLabel: true + #value: #doPickAMenu + #activeHelpKey: #filePickAMenu + ) + #(#MenuItem + #label: '-' + ) + #(#MenuItem + #label: 'Show Menu Spec' + #translateLabel: true + #value: #doShowMenuSpec + #activeHelpKey: #fileShowMenuSpec + ) + #(#MenuItem + #label: 'Browse Class' + #translateLabel: true + #value: #doBrowseClass + #activeHelpKey: #fileBrowseClass + #enabled: #hasValidSpecClass + ) + #(#MenuItem + #label: '-' + ) + #(#MenuItem + #label: 'Exit' + #translateLabel: true + #value: #closeRequest + #activeHelpKey: #fileExit + ) + ) + nil + nil + ) +! + +helpMenu + "This resource specification was automatically generated + by the MenuEditor of ST/X." + + "Do not manually edit this!! If it is corrupted, + the MenuEditor may not be able to read the specification." + + " + MenuEditor new openOnClass:MenuEditor andSelector:#helpMenu + (Menu new fromLiteralArrayEncoding:(MenuEditor helpMenu)) startUp + " + + + + ^ + #(#Menu + #( + #(#MenuItem + #label: 'Documentation' + #translateLabel: true + #value: #openHTMLDocument: + #activeHelpKey: #helpTutorial + #argument: 'tools/uipainter/MenuEditor.html' + ) + #(#MenuItem + #label: '-' + ) + #(#MenuItem + #label: 'Help Tool' + #translateLabel: true + #value: #openHTMLDocument: + #activeHelpKey: #helpHelpTool + #argument: 'tools/uipainter/HelpTool.html' + ) + #(#MenuItem + #label: '-' + ) + #(#MenuItem + #label: 'Show Help Texts' + #translateLabel: true + #activeHelpKey: #helpShowHelp + #indication: #showingHelp: + ) + #(#MenuItem + #label: '-' + ) + #(#MenuItem + #label: 'About MenuEditor...' + #translateLabel: true + #value: #openAboutThisApplication + #activeHelpKey: #aboutThisAppliaction + ) + ) + nil + nil + ) +! + menu "This resource specification was automatically generated by the MenuEditor of ST/X." @@ -1481,82 +843,23 @@ #label: '&File' #translateLabel: true #activeHelpKey: #file - #submenu: - #(#Menu - #( - #(#MenuItem - #label: 'New' - #translateLabel: true - #value: #doNew - #activeHelpKey: #fileNew - ) - #(#MenuItem - #label: '-' - ) - #(#MenuItem - #label: 'Load...' - #translateLabel: true - #value: #doLoad - #activeHelpKey: #fileLoad - ) - #(#MenuItem - #label: '-' - ) - #(#MenuItem - #label: 'Save' - #translateLabel: true - #value: #doSave - #activeHelpKey: #fileSave - ) - #(#MenuItem - #label: 'Save As...' - #translateLabel: true - #value: #doSaveAs - #activeHelpKey: #fileSaveAs - ) - #(#MenuItem - #label: '-' - ) - #(#MenuItem - #label: 'Pick a Menu...' - #translateLabel: true - #value: #doPickAMenu - #activeHelpKey: #filePickAMenu - ) - #(#MenuItem - #label: '-' - ) - #(#MenuItem - #label: 'Browse Class' - #translateLabel: true - #value: #doBrowseClass - #activeHelpKey: #fileBrowseClass - ) - #(#MenuItem - #label: '-' - ) - #(#MenuItem - #label: 'Exit' - #translateLabel: true - #value: #closeRequest - #activeHelpKey: #fileExit - ) - ) - nil - nil - ) + #submenuChannel: #fileMenu + #keepLinkedMenu: true ) #(#MenuItem - #label: 'Edit' + #label: '&Edit' #translateLabel: true #activeHelpKey: #edit - #submenuChannel: #menuEdit + #submenuChannel: #editMenu + #keepLinkedMenu: true ) #(#MenuItem #label: 'Add' #translateLabel: true #activeHelpKey: #add - #submenuChannel: #menuAdd + #enabled: #hasSingleSelectionChannel + #submenuChannel: #addMenu + #keepLinkedMenu: true ) #(#MenuItem #label: 'Test' @@ -1571,51 +874,11 @@ #submenuChannel: #menuHistory ) #(#MenuItem - #label: 'Help' + #label: '&Help' #translateLabel: true - #startGroup: #right - #submenu: - #(#Menu - #( - #(#MenuItem - #label: 'Documentation' - #translateLabel: true - #value: #openHTMLDocument: - #activeHelpKey: #helpTutorial - #argument: 'tools/uipainter/MenuEditor.html' - ) - #(#MenuItem - #label: '-' - ) - #(#MenuItem - #label: 'Help Tool' - #translateLabel: true - #value: #openHTMLDocument: - #activeHelpKey: #helpHelpTool - #argument: 'tools/uipainter/HelpTool.html' - ) - #(#MenuItem - #label: '-' - ) - #(#MenuItem - #label: 'Show Help Texts' - #translateLabel: true - #activeHelpKey: #helpShowHelp - #indication: #showingHelp: - ) - #(#MenuItem - #label: '-' - ) - #(#MenuItem - #label: 'About MenuEditor...' - #translateLabel: true - #value: #openAboutThisApplication - #activeHelpKey: #aboutThisAppliaction - ) - ) - nil - nil - ) + #activeHelpKey: #help + #submenuChannel: #helpMenu + #keepLinkedMenu: true ) ) nil @@ -1623,93 +886,7 @@ ) ! -menuAdd - "This resource specification was automatically generated - by the MenuEditor of ST/X." - - "Do not manually edit this!! If it is corrupted, - the MenuEditor may not be able to read the specification." - - " - MenuEditor new openOnClass:MenuEditor andSelector:#menuAdd - (Menu new fromLiteralArrayEncoding:(MenuEditor menuAdd)) startUp - " - - - - ^ - - #(#Menu - - #( - #(#MenuItem - #label: 'Menu Item' - #translateLabel: true - #value: #doCreateItem - #activeHelpKey: #addMenuItem - #labelImage: #(#ResourceRetriever #MenuEditor #menuItemImage 'Menu Item') - ) - #(#MenuItem - #label: 'Menu Separator' - #translateLabel: true - #value: #doCreateSep - #activeHelpKey: #addMenuSeparator - #labelImage: #(#ResourceRetriever #MenuEditor #menuSeparatorImage 'Menu Separator') - ) - #(#MenuItem - #label: '-' - ) - #(#MenuItem - #label: 'Submenu' - #translateLabel: true - #value: #doCreateMenu - #activeHelpKey: #addSubMenu - #labelImage: #(#ResourceRetriever #MenuEditor #submenuImage 'Submenu') - ) - #(#MenuItem - #label: 'Submenu Link' - #translateLabel: true - #value: #doCreateLink - #activeHelpKey: #addSubMenuLink - #labelImage: #(#ResourceRetriever #MenuEditor #linkSubmenuImage 'Submenu Link') - ) - #(#MenuItem - #label: '-' - ) - #(#MenuItem - #label: 'Standard Submenu' - #translateLabel: true - #submenu: - #(#Menu - - #( - #(#MenuItem - #label: 'Standard Menu: File' - #translateLabel: true - #value: #doCreateStandardFileMenu - ) - #(#MenuItem - #label: 'Standard Menu: Edit' - #translateLabel: true - #value: #doCreateStandardEditMenu - ) - #(#MenuItem - #label: 'Standard Menu: Help' - #translateLabel: true - #value: #doCreateStandardHelpMenu - ) - ) nil - nil - ) - ) - ) nil - nil - ) - - "Modified: / 23.8.1998 / 15:48:21 / cg" -! - -menuDefaultLink +standardMenus "This resource specification was automatically generated by the MenuEditor of ST/X." @@ -1717,26 +894,37 @@ the MenuEditor may not be able to read the specification." " - MenuEditor new openOnClass:MenuEditor andSelector:#menuDefaultLink - (Menu new fromLiteralArrayEncoding:(MenuEditor menuDefaultLink)) startUp + MenuEditor new openOnClass:MenuEditor andSelector:#standardMenus + (Menu new fromLiteralArrayEncoding:(MenuEditor standardMenus)) startUp " - ^ - - #(#Menu - - #( - #(#MenuItem - #'label:' '!!!! derives from application !!!!' - ) - ) nil - nil + ^ + #(#Menu + #( + #(#MenuItem + #label: 'Standard Menu: Edit' + #translateLabel: true + #value: #doCreateStandardEditMenu + ) + #(#MenuItem + #label: 'Standard Menu: Help' + #translateLabel: true + #value: #doCreateStandardHelpMenu + ) + #(#MenuItem + #label: 'Standard Menu: File' + #translateLabel: true + #value: #doCreateStandardFileMenu + ) + ) + nil + nil ) ! -menuEdit +toolbar "This resource specification was automatically generated by the MenuEditor of ST/X." @@ -1744,133 +932,8 @@ the MenuEditor may not be able to read the specification." " - MenuEditor new openOnClass:MenuEditor andSelector:#menuEdit - (Menu new fromLiteralArrayEncoding:(MenuEditor menuEdit)) startUp - " - - - - ^ - - #(#Menu - - #( - #(#MenuItem - #label: 'Cut' - #translateLabel: true - #value: #doCut - #activeHelpKey: #editCut - #enabled: #hasValidSelection - ) - #(#MenuItem - #label: 'Copy' - #translateLabel: true - #value: #doCopy - #activeHelpKey: #editCopy - #enabled: #hasValidSelection - ) - #(#MenuItem - #label: 'Paste' - #translateLabel: true - #value: #doPaste - #activeHelpKey: #editPaste - #enabled: #valueOfCanPaste - ) - #(#MenuItem - #label: 'Delete' - #translateLabel: true - #value: #doDelete - #activeHelpKey: #editDelete - #enabled: #hasValidSelection - ) - #(#MenuItem - #label: '-' - ) - #(#MenuItem - #label: 'Move Up' - #translateLabel: true - #value: #doStepUp - #activeHelpKey: #editMoveUp - #enabled: #valueOfEnableMovingUpOrDown - #labelImage: #(#ResourceRetriever #Icon #upIcon 'Move Up') - ) - #(#MenuItem - #label: 'Move Down' - #translateLabel: true - #value: #doStepDown - #activeHelpKey: #editMoveDown - #enabled: #valueOfEnableMovingUpOrDown - #labelImage: #(#ResourceRetriever #Icon #downIcon 'Move Down') - ) - #(#MenuItem - #label: 'Move In' - #translateLabel: true - #value: #doStepIn - #activeHelpKey: #editMoveIn - #enabled: #valueOfEnableMovingIn - #labelImage: #(#ResourceRetriever #Icon #downRightIcon 'Move In') - ) - #(#MenuItem - #label: 'Move Out' - #translateLabel: true - #value: #doStepOut - #activeHelpKey: #editMoveOut - #enabled: #valueOfEnableMovingOut - #labelImage: #(#ResourceRetriever #Icon #leftDownIcon 'Move Out') - ) - ) nil - nil - ) -! - -menuEditImage - "This resource specification was automatically generated - by the MenuEditor of ST/X." - - "Do not manually edit this!! If it is corrupted, - the MenuEditor may not be able to read the specification." - - " - MenuEditor new openOnClass:MenuEditor andSelector:#menuEditImage - (Menu new fromLiteralArrayEncoding:(MenuEditor menuEditImage)) startUp - " - - - - ^ - - #(#Menu - - #( - #(#MenuItem - #label: 'Edit' - #translateLabel: true - #value: #doEditImage - #activeHelpKey: #editCut - #enabled: #hasValidSelection - ) - #(#MenuItem - #label: 'Remove' - #translateLabel: true - #value: #doRemoveImage - #activeHelpKey: #editCopy - #enabled: #hasValidSelection - ) - ) nil - nil - ) -! - -menuToolbar - "This resource specification was automatically generated - by the MenuEditor of ST/X." - - "Do not manually edit this!! If it is corrupted, - the MenuEditor may not be able to read the specification." - - " - MenuEditor new openOnClass:MenuEditor andSelector:#menuToolbar - (Menu new fromLiteralArrayEncoding:(MenuEditor menuToolbar)) startUp + MenuEditor new openOnClass:MenuEditor andSelector:#toolbar + (Menu new fromLiteralArrayEncoding:(MenuEditor toolbar)) startUp " @@ -1879,18 +942,12 @@ #(#Menu #( #(#MenuItem - #label: 'New' - #isButton: true - #value: #doNew - #activeHelpKey: #fileNew - #labelImage: #(#ResourceRetriever #Icon #newIcon) - ) - #(#MenuItem #label: 'Load' #isButton: true #value: #doLoad #activeHelpKey: #fileLoad #labelImage: #(#ResourceRetriever #Icon #loadIcon) + #submenuChannel: #menuHistory ) #(#MenuItem #label: 'Save' @@ -1907,7 +964,7 @@ #isButton: true #value: #doCut #activeHelpKey: #editCut - #enabled: #hasValidSelection + #enabled: #hasSelectionChannel #labelImage: #(#ResourceRetriever #Icon #cutIcon) ) #(#MenuItem @@ -1915,7 +972,7 @@ #isButton: true #value: #doCopy #activeHelpKey: #editCopy - #enabled: #hasValidSelection + #enabled: #hasSelectionChannel #labelImage: #(#ResourceRetriever #Icon #copyIcon) ) #(#MenuItem @@ -1927,87 +984,104 @@ #labelImage: #(#ResourceRetriever #Icon #pasteIcon) ) #(#MenuItem - #label: 'Delete' - #isButton: true - #value: #doDelete - #activeHelpKey: #editDelete - #enabled: #hasValidSelection - #labelImage: #(#ResourceRetriever #Icon #deleteIcon) - ) - #(#MenuItem #label: '' ) #(#MenuItem - #label: 'Add Item' - #isButton: true - #value: #doCreateItem - #activeHelpKey: #addMenuItem - #enabled: #hasAnySingleSelection - #labelImage: #(#ResourceRetriever nil #menuItemImage) - ) - #(#MenuItem #label: 'Add Separator' #isButton: true #value: #doCreateSep #activeHelpKey: #addMenuSeparator - #enabled: #hasAnySingleSelection - #labelImage: #(#ResourceRetriever nil #menuSeparatorImage) + #enabled: #hasSingleSelectionChannel + #labelImage: #(#ResourceRetriever #'MenuEditor::Item' #iconSeparator) ) #(#MenuItem - #label: 'Add Submenu' + #label: 'Add Item' + #isButton: true + #value: #doCreateItem + #activeHelpKey: #addMenuItem + #enabled: #hasSingleSelectionChannel + #labelImage: #(#ResourceRetriever #'MenuEditor::Item' #iconItem) + ) + #(#MenuItem + #label: 'Add Menu' #isButton: true #value: #doCreateMenu #activeHelpKey: #addSubMenu - #enabled: #hasAnySingleSelection - #labelImage: #(#ResourceRetriever nil #submenuImage) + #enabled: #hasSingleSelectionChannel + #labelImage: #(#ResourceRetriever #'MenuEditor::Item' #iconMenu) + #submenuChannel: #standardMenus + #keepLinkedMenu: true ) #(#MenuItem - #label: 'Add Linked Submenu' + #label: 'Add Linked Menu' #isButton: true - #value: #doCreateLink + #value: #doCreateLinkedMenu #activeHelpKey: #addSubMenuLink - #enabled: #hasAnySingleSelection - #labelImage: #(#ResourceRetriever nil #linkSubmenuImage) + #enabled: #hasSingleSelectionChannel + #labelImage: #(#ResourceRetriever #'MenuEditor::Item' #iconLinkedMenu) ) #(#MenuItem #label: '' ) #(#MenuItem + #label: 'Add Delayed Menu' + #isButton: true + #value: #doCreateDelayedMenu: + #activeHelpKey: #addDelayedMenu + #enabled: #canCreateDelayedMenuChannel + #argument: #menu + #labelImage: #(#ResourceRetriever #'MenuEditor::Item' #iconDelayedMenu) + ) + #(#MenuItem + #label: 'Add Delayed Linked Menu' + #isButton: true + #value: #doCreateDelayedMenu: + #activeHelpKey: #addDelayedSubMenuLink + #enabled: #canCreateDelayedMenuChannel + #argument: #linkedMenu + #labelImage: #(#ResourceRetriever #'MenuEditor::Item' #iconDelayedLinkedMenu) + ) + #(#MenuItem #label: 'Move Up' #isButton: true - #value: #doStepUp + #startGroup: #right + #value: #doMoveUpOrDown: #activeHelpKey: #editMoveUp #enabled: #valueOfEnableMovingUpOrDown + #argument: #up #labelImage: #(#ResourceRetriever #Icon #upIcon) ) #(#MenuItem #label: 'Move Down' #isButton: true - #value: #doStepDown + #value: #doMoveUpOrDown: #activeHelpKey: #editMoveDown #enabled: #valueOfEnableMovingUpOrDown + #argument: #down #labelImage: #(#ResourceRetriever #Icon #downIcon) ) #(#MenuItem #label: 'Move In' #isButton: true - #value: #doStepIn + #value: #doMoveIn: #activeHelpKey: #editMoveIn #enabled: #valueOfEnableMovingIn + #argument: #inNext #labelImage: #(#ResourceRetriever #Icon #downRightIcon) ) #(#MenuItem #label: 'Move In Above' #isButton: true - #value: #doStepInAbove + #value: #doMoveIn: #activeHelpKey: #editMoveInAbove #enabled: #valueOfEnableMovingInAbove + #argument: #inPrev #labelImage: #(#ResourceRetriever #Icon #upRightIcon) ) #(#MenuItem #label: 'Move Out' #isButton: true - #value: #doStepOut + #value: #doMoveOut #activeHelpKey: #editMoveOut #enabled: #valueOfEnableMovingOut #labelImage: #(#ResourceRetriever #Icon #leftDownIcon) @@ -2018,567 +1092,620 @@ ) ! ! -!MenuEditor class methodsFor:'queries'! - -getAllImageSelectorsFrom: aClass - "returns all image selectors implementing an image spec in class aClass" - - |iconClass imageMethodSelectors r| - - aClass isNil ifTrue:[ - ^ #() - ]. - - aClass isSymbol - ifTrue: [iconClass := Smalltalk at: aClass] - ifFalse: [iconClass := aClass]. - aClass isBehavior ifFalse:[ - ^ #() - ]. - - imageMethodSelectors := OrderedCollection new. - - iconClass withAllSuperclassesDo:[:cls | - cls class selectorsAndMethodsDo:[:sel :m | - ((r := m resourceType) == #image - or:[r == #programImage]) ifTrue:[ - imageMethodSelectors add:sel - ] - ] - ]. - - ^ imageMethodSelectors sort - - "Modified: / 24.8.1998 / 21:42:34 / cg" - "Created: / 24.8.1998 / 21:53:20 / cg" -! ! - -!MenuEditor class methodsFor:'slices'! - -slicesItem - ^#( - (Basics basicsItemSpec) - (Details detailsEditSpec) - (Image imageEditSpec) +!MenuEditor class methodsFor:'menu specs - standard'! + +standardEditMenu + "This resource specification was automatically generated + by the MenuEditor of ST/X." + + "Do not manually edit this!! If it is corrupted, + the MenuEditor may not be able to read the specification." + + " + MenuEditor new openOnClass:MenuEditor andSelector:#standardEditMenu + (Menu new fromLiteralArrayEncoding:(MenuEditor standardEditMenu)) startUp + " + + + + ^ + #(#Menu + #( + #(#MenuItem + #label: 'Copy' + #translateLabel: true + #value: #copySelection + ) + #(#MenuItem + #label: 'Cut' + #translateLabel: true + #value: #cutSelection + ) + #(#MenuItem + #label: 'Paste' + #translateLabel: true + #value: #paste + ) + ) + nil + nil ) - -! - -slicesLink - ^#( - (Basics basicsLinkSpec) - (Details detailsEditSpec) - (Image imageEditSpec) - ) - ! -slicesMenu - ^#( - (Basics basicsMenuSpec) - (Details detailsEditSpec) - (Image imageEditSpec) +standardFileMenu + "This resource specification was automatically generated + by the MenuEditor of ST/X." + + "Do not manually edit this!! If it is corrupted, + the MenuEditor may not be able to read the specification." + + " + MenuEditor new openOnClass:MenuEditor andSelector:#standardFileMenu + (Menu new fromLiteralArrayEncoding:(MenuEditor standardFileMenu)) startUp + " + + + + ^ + #(#Menu + #( + #(#MenuItem + #label: 'New' + #translateLabel: true + #value: #menuNew + ) + #(#MenuItem + #label: '-' + ) + #(#MenuItem + #label: 'Open...' + #translateLabel: true + #value: #menuOpen + ) + #(#MenuItem + #label: '-' + ) + #(#MenuItem + #label: 'Save' + #translateLabel: true + #value: #menuSave + ) + #(#MenuItem + #label: 'Save As...' + #translateLabel: true + #value: #menuSaveAs + ) + #(#MenuItem + #label: '-' + ) + #(#MenuItem + #label: 'Exit' + #translateLabel: true + #value: #closeRequest + ) + ) + nil + nil ) - ! -slicesRootMenu - ^#( - (Basics basicsRootSpec) +standardHelpMenu + "This resource specification was automatically generated + by the MenuEditor of ST/X." + + "Do not manually edit this!! If it is corrupted, + the MenuEditor may not be able to read the specification." + + " + MenuEditor new openOnClass:MenuEditor andSelector:#standardHelpMenu + (Menu new fromLiteralArrayEncoding:(MenuEditor standardHelpMenu)) startUp + " + + + + ^ + #(#Menu + #( + #(#MenuItem + #label: 'Documentation' + #translateLabel: true + #value: #openDocumentation + ) + #(#MenuItem + #label: '-' + ) + #(#MenuItem + #label: 'About this Application' + #translateLabel: true + #value: #openAboutThisApplication + ) + ) + nil + nil ) - -! - -slicesSeparatorMenu - ^#( - (Basics basicsSeparatorSpec) - ) - ! ! !MenuEditor methodsFor:'accessing'! -submenuTest - "return the submenu assigned to item test; - this is dynamically constructed, to reflect the current - edited menu." - - |menu cls| - - menu := treeView asMenu. - menu ifNotNil:[ - (menu := treeView asMenu) allItemsDo:[:anItem| - anItem value:nil. - anItem enabled:true. - ]. - - cls := self resolveName:specClass. - menu findGuiResourcesIn:cls. - menu receiver:nil. +helpTool + "get the help tool application + " + ^ wizards at:#help ifAbsentPut:[ |tool| + tool := UIHelpTool new createBuilder. + tool masterApplication:self. + tool modifiedHolder: self valueOfEnablingCommitButtons. + tool builder window:(ApplicationSubView new client:tool). + tool masterApplication:self. + tool + ] +! + +imageTool + "get the image tool application + " + ^ wizards at:#image ifAbsentPut:[ |tool| + tool := ResourceEditor new createBuilder. + tool masterApplication:self. + tool modifiedChannel: self valueOfEnablingCommitButtons. + tool builder window:(ApplicationSubView new client:tool). + tool + ] +! + +useHelpTool:aHelpTool + "take the help dictionaries from aHelpTool into my helpTool + " + |tool| + + tool := self helpTool. + + tool buildFromClass:(aHelpTool specClass). + tool dictionaries:(aHelpTool dictionaries). + tool dictionary:(aHelpTool dictionary). +! ! + +!MenuEditor methodsFor:'actions'! + +accept + "accept modifications + " + self accept:true. +! + +accept:ok + "ok if true the modifications are accepted + than reload from item + " + |selectedItem rscRetrHolder helpKeyHolder helpTool imageTool acceptChannel| + + selectedItem := self selectedItem. + + selectedItem ifNotNil:[ + self withoutNotifyDo:[ + rscRetrHolder := aspects at:#resourceRetriever. + helpKeyHolder := aspects at:#activeHelpKey. + imageTool := self imageTool. + helpTool := self helpTool. + acceptChannel := self acceptChannel. + + acceptChannel triggerValue:true. + acceptChannel setValue:false. + + ok ifTrue:[ + rscRetrHolder value:(imageTool resourceRetriever). + helpKeyHolder value:(helpTool helpKey). + selectedItem fromAspects:aspects. + modified := true. + + selectedItem isRootItem ifTrue:[ + "/ update specSelector + specSelector := selectedItem rawLabel. + ]. + ]. + selectedItem toAspects:aspects. + helpTool setHelpKey:(helpKeyHolder value). + imageTool resourceRetriever:(rscRetrHolder value). + ] ]. - ^ menu + self updateChannels. + self clearModified. +! + +cancel + "reload aspects from current selected item; reset modification flag + " + self accept:false. ! -useHelpTool: aHelpTool - "take the help dictionaries from aHelpTool into my helpTool" - - self helpTool buildFromClass: aHelpTool specClass. - self helpTool dictionaries: aHelpTool dictionaries. - self helpTool dictionary: aHelpTool dictionary - - +indicatorClickedAt:atLine + "indicator clicked at line number; toggle expand of item at line + " + |item| + + item := listOfItems at:atLine ifAbsent:nil. + item ifNotNil:[ item toggleExpand ]. ! ! !MenuEditor methodsFor:'aspects'! -hasAnySingleSelection - - ^builder booleanValueAspectFor: #hasAnySingleSelection +canCreateDelayedMenuChannel + "boolean holder, true if the current selected item accepts a delayed menu + " + ^ builder booleanValueAspectFor:#canCreateDelayedMenuChannel ! -hasValidSelection - - ^builder booleanValueAspectFor: #hasValidSelection +hasSelectionChannel + "boolean holder, true if any item is selected + " + ^ builder booleanValueAspectFor:#hasSelectionChannel ! -listOfImages - "get a list of the images +hasSingleSelectionChannel + "boolean holder, true if one item is selected + " + ^ builder booleanValueAspectFor:#hasSingleSelectionChannel +! + +listOfItems + "returns the hierarchical list of menuItems " - |list| - - (list := builder bindingAt:#listOfImages) isNil ifTrue:[ - builder aspectAt:#listOfImages put: (list := List new). - ]. - ^ list - - + ^ listOfItems +! + +listOfTabs + "returns the list of current shown tab-labels retrieved + from the current selected item. + " + ^ listOfTabs +! + +selectionHolder + "value holder, which keeps the current selected items + " + ^ selectionHolder ! -selectionOfImage - "get selection of list of the images as value" - +tabHolder + "value holder, which keeps the current selected tab label or nil + " + ^ tabHolder +! + +wizardHolder + "holder, which keeps the current wizard window + " |holder| - (holder := builder bindingAt:#selectionOfImage) isNil ifTrue:[ - builder aspectAt:#selectionOfImage put: (holder := nil asValue). + + holder := builder bindingAt:#wizardHolder. + + holder ifNil:[ + holder := nil asValue. + builder aspectAt:#wizardHolder put:holder. ]. ^ holder - - -! - -tabCanvasHolder - "keep the canvas for the current selected item or nil - " - |holder| - - (holder := builder bindingAt:#tabCanvasHolder) isNil ifTrue:[ - builder aspectAt:#tabCanvasHolder put: (holder := ValueHolder new). - ]. - ^ holder - - -! - -tabList - "get a value holder with the list of the attribute sections (slices)" - - |holder| - - (holder := builder bindingAt:#tabList) isNil ifTrue:[ - builder aspectAt:#tabList put:(holder := nil asValue). - ]. - ^ holder - - -! - -treeView - "get a tree view representing hierarchically the menu items" - - ^ treeView ! ! !MenuEditor methodsFor:'building'! -buildFromClass:aClass andSelector:aSelector - - self isStandAlone ifTrue:[ - self helpTool buildFromClass:specClass - ]. - treeView buildFromClass: aClass andSelector: aSelector. - +buildFromClass:aSpecClass andSelector:aSpecSelector + "rebuild menu from a class and selector + " + |cls menu| + + menu := nil. + + self isStandAlone ifTrue:[ self helpTool buildFromClass:aSpecClass ]. + + aSpecSelector notNil ifTrue:[ + aSpecClass ifNotNil:[ + cls := self resolveName:aSpecClass. + menu := cls perform:aSpecSelector ifNotUnderstood:nil. + + menu ifNotNil:[ + (menu isMemberOf:Menu) ifFalse:[ + menu := Menu new fromLiteralArrayEncoding:menu + ]. + ] + ]. + ]. + self buildFromMenu:menu selector:aSpecSelector. +! + +buildFromMenu:aMenu selector:aSelector + "rebuild menu from a Menu + " + |root menu| + + aMenu isCollection ifTrue:[menu := aMenu decodeAsLiteralArray] + ifFalse:[menu := aMenu]. + + self valueOfEnablingCommitButtons value:false. + root := listOfItems root. + + self withoutNotifyDo:[ + selectionHolder setValue:#(). + root menu:aMenu labeled:(aSelector ? specSelector). + ]. + self selectedItem:root. self updateHistory. - self updateInfoLabel. - ! buildFromResourceSpec:aResourceSpec - |spec| - - spec := aResourceSpec isCollection ifTrue:[aResourceSpec decodeAsLiteralArray] - ifFalse:[aResourceSpec]. - - self buildFromMenu:spec + "rebuild menu from a resource spec + " + self buildFromMenu:aResourceSpec selector:nil ! ! !MenuEditor methodsFor:'change & update'! +selectedSuperItems + "returns collection of superItems derived from selection + " + |selection size root| + + selectedSuperItems ifNotNil:[ ^ selectedSuperItems ]. + + selection := selectionHolder value. + size := selection size. + + size <= 1 ifTrue:[ + selectedSuperItems := selection ? #(). + ^ selectedSuperItems + ]. + + root := listOfItems root. + + (selection includesIdentical:root) ifTrue:[ + selectedSuperItems := Array with:root. + ^ selectedSuperItems + ]. + selectedSuperItems := OrderedCollection new. + + selection do:[:anItem| + anItem parentsDetect:[:el| selection includesIdentical:el ] + ifNone:[ selectedSuperItems add:anItem ]. + ]. + ^ selectedSuperItems +! + +selectionChanged + "called if the selection has changed + " + |newTabList selection| + + selection := selectionHolder value. + + selection size == 1 ifTrue:[ + selectedSuperItems := selection. + + newTabList := selection first slices collect:[:el| ' ', el first, ' ' ]. + newTabList = listOfTabs ifFalse:[ + listOfTabs contents:newTabList. + ]. + ] ifFalse:[ + "must compute selected super items on request + " + selectedSuperItems := nil. + ]. + self cancel. + self tabChanged. + self updateChannels. +! + +tabChanged + "called if the tab changed + " + |tab selector item canvas wizardHolder| + + wizardHolder := self wizardHolder. + item := self selectedItem. + item ifNil:[ ^ wizardHolder value:nil ]. + + tab := tabHolder value. + + tab ifNotNil:[ + tab := tab withoutSeparators. + tab := item slices detect:[:el| el first = tab ] ifNone:nil. + ]. + tab ifNil:[ + ^ tabHolder value:( listOfTabs at:1 ifAbsent:nil ) + ]. + selector := tab last. + + selector == #help ifTrue:[ ^ wizardHolder value:(self helpTool window) ]. + selector == #image ifTrue:[ ^ wizardHolder value:(self imageTool window) ]. + + canvas := wizards at:(item class name, selector) asSymbol + ifAbsentPut:[ SimpleView new client:self + spec:(item class perform:selector) + builder:(self builder) + ]. + + wizardHolder value:canvas. +! + update:something with:aParameter from:changedObject - super update:something with:aParameter from:changedObject. - - changedObject == (aspects at:#retriever) ifTrue:[ - self updateImageView. - ]. - - "Modified: / 24.8.1998 / 21:47:48 / cg" + "Invoked when an object that I depend upon sends a change notification. + " + notifyDisabledCounter ~~ 0 ifTrue:[ ^ self ]. + + changedObject == selectionHolder ifTrue:[ ^ self selectionChanged ]. + changedObject == tabHolder ifTrue:[ ^ self tabChanged ]. + + super update:something with:aParameter from:changedObject ! updateChannels - "update channels" - - |node parent next prev state canPaste selectedNodes firstParent - enableMovingOut enableMovingIn indexOfLast| - - enableMovingOut := enableMovingIn := false. - - state := false. - node := treeView selectedNode. - - node notNil ifTrue:[ - "/ single node selected - self hasAnySingleSelection value:true. - canPaste := self valueOfCanPaste value. - - (parent := node parent) notNil ifTrue:[ - next := parent childAt:((parent indexOfChild:node) + 1). - prev := parent childAt:((parent indexOfChild:node) - 1). - self valueOfEnableMovingIn value:(next notNil and:[next hasChildren]). - self valueOfEnableMovingInAbove value:(prev notNil and:[prev hasChildren]). - self valueOfEnableMovingUpOrDown value:(parent children size > 1). - self valueOfEnableMovingOut value:parent parent notNil. - self hasValidSelection value:true. - self valueOfCanPaste value:canPaste. - ^ self - ]. + "update all channels + " + |selection sizeOfSel selectedItem| + + super updateChannels. + + selection := selectionHolder value. + sizeOfSel := selection size. + + sizeOfSel == 1 ifTrue:[selectedItem := selection at:1] + ifFalse:[selectedItem := nil]. + + self hasSelectionChannel value:(sizeOfSel ~~ 0). + self hasSingleSelectionChannel value:(selectedItem notNil). + + selectedItem isNil ifTrue:[ + self valueOfEnableMovingIn value:false. + self valueOfEnableMovingOut value:false. + self valueOfEnableMovingUpOrDown value:false. + self valueOfEnableMovingInAbove value:false. + self canCreateDelayedMenuChannel value:false. ] ifFalse:[ - "/ multiple nodes selected - canPaste := false. - - self hasAnySingleSelection value:false. - - treeView numberOfSelections ~~ 0 ifTrue:[ - canPaste := false. - state := (treeView isInSelection:1) not. - - selectedNodes := treeView selectedNodes. - - "/ see if all selected nodes have a common parent. - firstParent := selectedNodes first parent. - (selectedNodes conform:[:eachNode | eachNode parent == firstParent]) ifTrue:[ - "/ yes - they have -"/ next := firstParent childAt:((firstParent indexOfChild:node) + 1). -"/ self valueOfEnableMovingIn value:(next notNil and:[next hasChildren]). - enableMovingOut := firstParent parent notNil. -"/ self halt. - - indexOfLast := (selectedNodes collect:[:eachNode | firstParent indexOfChild:eachNode]) max. - next := firstParent childAt:(indexOfLast + 1). - enableMovingIn := (next notNil and:[next hasChildren]). - ] ifFalse:[ -"/ self halt. - ]. - ] - ]. - self valueOfEnableMovingUpOrDown value:false. - self valueOfEnableMovingIn value:enableMovingIn. - self valueOfEnableMovingOut value:enableMovingOut. - self hasValidSelection value:state. - self valueOfCanPaste value:canPaste. -! - -updateImageView - "update the image view - " - |cls newList icon| - - self isImageViewSelected ifFalse:[ - ^ self + self valueOfEnableMovingUpOrDown value:(selectedItem canMoveUpOrDown). + self valueOfEnableMovingOut value:(selectedItem canMoveOut). + self valueOfEnableMovingIn value:(selectedItem canMoveInNext). + self valueOfEnableMovingInAbove value:(selectedItem canMoveInAbove). + self canCreateDelayedMenuChannel value:(selectedItem canAddDelayedMenu). ]. - cls := self currentImageRetrieverClass. - - lastImageRetriever == cls ifTrue:[ - newList := self listOfImages - ] ifFalse:[ - cls notNil ifTrue:[ - self withWaitCursorDo:[ - lastImageRetriever := cls. - - newList := self class getAllImageSelectorsFrom:cls. - newList := newList collect: [:sel| |img| - img := cls perform: sel. - img height > 32 ifTrue:[ - img := img magnifiedBy: 32 / img extent y - ]. - LabelAndIcon icon:img string:sel - ]. - ]. - ] ifFalse:[ - newList := #() - ]. - self listOfImages contents:newList. - ]. - - icon := (aspects at:#icon) value. - - icon notNil ifTrue:[ - icon := newList detect:[:el| el string == icon] ifNone:nil. - ]. - self selectionOfImage value:icon. ! ! !MenuEditor methodsFor:'defaults'! aboutImage "the image to be displayed in my about-box; - If nil is returned, thhe ST/X default image is used." - - ^ Image fromFile:'bitmaps/xpmBitmaps/misc_tools/setup_menus.xpm' - - "Created: / 25.7.1998 / 20:48:12 / cg" - "Modified: / 27.7.1998 / 10:21:55 / cg" -! ! - -!MenuEditor methodsFor:'event handling'! - -doesNotUnderstand: aMessage - "detour incoming messages to the tree view" - - ^ aMessage sendTo:treeView -! ! - -!MenuEditor methodsFor:'private'! - -currentImageRetrieverClass - "returns the current class which provides the images dependent on - the retriver or the current spec. + If nil is returned, the ST/X default image is used. " - |clsName| - - clsName := (aspects at: #retriever) value. - - clsName size == 0 ifTrue:[ - clsName := specClass. - clsName isNil ifTrue:[^ nil]. - ]. - ^ Smalltalk at:clsName ifAbsent:nil -! - -helpKey - "get the help key of the selected menu item" - - |node| - - (node := treeView selectedNode) notNil ifTrue:[ - ^ node contents activeHelpKey - ]. - ^ nil -! - -helpTool - "get the help tool application + ^ self class aboutImage +! ! + +!MenuEditor methodsFor:'drag & drop'! + +canDrop:aContext + "return true, if the DropContext can be dropped into + the hierachical list of items " - |helpView helpTool| - - helpTool := listOfCanvas at:#help ifAbsent:nil. - - helpTool isNil ifTrue:[ - helpTool := UIHelpTool new createBuilder. - helpTool masterApplication:self. - helpTool modifiedHolder: self valueOfEnablingCommitButtons. - helpView := ApplicationSubView new client:helpTool. - helpTool builder window:helpView. - helpTool masterApplication:self. - listOfCanvas at:#help put:helpTool. + |objects modified| + + modified := self valueOfEnablingCommitButtons value. + modified ifTrue:[^ false]. + + self selectedItem ifNil:[^ false]. + + aContext sourceWidget == aContext targetWidget ifTrue:[ + ^ false ]. - ^ helpTool - - -! ! - -!MenuEditor methodsFor:'queries'! - -isHelpToolSelected - "return true if current selection is help tool + + objects := aContext dropObjects. + objects isEmpty ifTrue:[ ^ false ]. + + objects do:[:el| + el theObject class == MenuItem ifFalse:[^ false]. + ]. + ^ true +! + +doDrop:aDropContext + "drop the DropContext into the hierachical list of items " - ^ typeOfCanvas == #help - -! - -isImageViewSelected - "return true if current selection is help tool - " - ^ typeOfCanvas == #imageEditSpec - -! - -preferredExtent - - ^super preferredExtent max: (Screen current width//3)@(Screen current height//2.5) - - -! ! - -!MenuEditor methodsFor:'selection'! - -imageSelected - |imgSel| - - imgSel := self selectionOfImage value. - imgSel notNil ifTrue:[ - (aspects at: #icon) value: imgSel string - ] + |objects| + + (self canDrop:aDropContext) ifFalse:[^ false]. + + objects := aDropContext dropObjects collect:[:el| el theObject ]. + self doPaste:objects. + ^ true ! -menuChanged - - |node item myClass oldLabel oldSlices newList index| - - node := treeView selectedNode. - - node isNil ifTrue:[ - slices := nil. - index := 0. - ] ifFalse:[ - oldSlices := slices. - myClass := self class. - item := node contents. - - item isSeparator ifFalse:[ - node parent isNil ifFalse:[ - node hasChildren ifTrue:[ - slices := #slicesMenu - ] ifFalse:[ - item submenuChannel isNil ifTrue:[slices := #slicesItem] - ifFalse:[slices := #slicesLink] - ]. - slices := listOfSlices at:slices - ifAbsentPut:[(myClass perform:slices) copyWith:#('Help' #help)]. - ] ifTrue:[ - slices := listOfSlices at:#slicesRootMenu - ifAbsentPut:[myClass perform:#slicesRootMenu]. - ]. - ] ifTrue:[ - slices := myClass perform:#slicesSeparatorMenu. - ]. - index := tabSelection ? 0. - - slices ~~ oldSlices ifTrue:[ - tabSelection := 0. - typeOfCanvas := 0. - - self tabCanvasHolder value:nil. - - newList := slices collect:[:el| el first]. - - index ~~ 0 ifTrue:[ - oldLabel := self tabList value at:index ifAbsent:nil. - - oldLabel notNil ifTrue:[ - index := newList indexOf:oldLabel. - ] - ]. - self tabList value:newList. - ]. - index := index max:1. +dropObjects + "returns list of DropObjects + " + |obj items| + + items := self selectedSuperItems. + items isEmpty ifTrue:[ ^ nil ]. + + ^ items collect:[:el| + obj := DropObject new:(el menuItem). + obj displayObject:(el rawLabel). + obj ]. - self tabModel value:index. - aspects do:[:a| a removeDependent:self]. - self cancel. - self updateChannels. - aspects do:[:a| a addDependent:self]. - -! - -tabSelection:aSelection - "put the section aSelection into the note book +! ! + +!MenuEditor methodsFor:'event processing'! + +processEvent:anEvent + "filter keyboard edit-events typed into the listOfItemsView " - |view| - - aSelection = tabSelection ifTrue:[^self]. - - (tabSelection := aSelection) isNil ifTrue:[ - tabSelection == 0 ifTrue:[^ self]. - tabSelection := 0. + |evView inView rawKey key| + + anEvent isKeyPressEvent ifFalse:[^ false]. + + evView := anEvent targetView. + evView ifNil:[ ^ false ]. + + inView := evView isSameOrComponentOf:listOfItemsView. + inView ifFalse:[^ false]. + + key := anEvent key. + rawKey := anEvent rawKey. + + ( key == #Delete + or:[key == #BackSpace + or:[key == #Cut]] + ) ifTrue:[ + self doCut. + ^ true. ]. - "/ before bringing up the new notebook page, - "/ we must disable all now invisible input fields ... - "/ (otherwise, those would fire on #accept. - - (view := self tabCanvasHolder value) notNil ifTrue:[ - view allSubViewsDo:[:aComponent | - aComponent isInputField ifTrue:[ - aComponent disableIfInvisible:true - ] - ] - ]. - - tabSelection == 0 ifTrue:[ - ^ self tabCanvasHolder value:nil. + key == #Copy ifTrue:[ self doCopy. ^ true ]. + key == #Paste ifTrue:[ self doPaste. ^ true ]. + + ^ false +! ! + +!MenuEditor methodsFor:'initialization & release'! + +closeRequest + "ask for modification + " + self valueOfEnablingCommitButtons value ifTrue:[ + modified := true. + self askForListModification. + modified ifTrue:[^ self]. + self clearModified. ]. - - typeOfCanvas := (slices at:tabSelection) last. - - self isHelpToolSelected ifTrue:[ - view := self helpTool window. - ] ifFalse:[ - self updateImageView. - - view := listOfCanvas at:typeOfCanvas - ifAbsentPut:[SimpleView new client:self spec:typeOfCanvas builder:(self builder)]. - ]. - self tabCanvasHolder value:view. - -! ! - -!MenuEditor methodsFor:'startup / release'! + ^ super closeRequest +! initialize - "initialize value holders for the attributes of the menu components" - - |holder| - + "setup aspects, ... + " super initialize. - - aspects at:#seperatorSelection put:(holder := SelectionInList new). - holder list: Item separatorList. - holder addDependent:self. - - listOfCanvas := IdentityDictionary new. - listOfSlices := IdentityDictionary new. - - treeView := TreeView new. - treeView action:[:dummy| self menuChanged ]. - - aspects at:#indicationEnabled put:(BlockValue - with:[:a | a size == 0] - argument:(aspects at:#choice)). - aspects at:#choiceEnabled put:(BlockValue - with:[:a | a size == 0] - argument:(aspects at:#indication)). - aspects at:#choiceValueEnabled put:(BlockValue - with:[:a | a size > 0] - argument:(aspects at:#choice)). - - aspects at:#retrieverClassList put:self class imageRetrieverClasses asValue. - - aspects do: [:holder| holder addDependent:self]. + notifyDisabledCounter := 0. + + Item withAllSubclasses do:[:aClass| + aClass addBindingsTo:aspects for:self. + ]. + + selectionHolder := #() asValue. + selectionHolder addDependent:self. + + listOfItems := HierarchicalList new. + listOfItems application:self. + listOfItems root:(ItemRoot new). + + tabHolder := nil asValue. + tabHolder addDependent:self. + + listOfTabs := List new. + wizards := IdentityDictionary new. ! -openModalOnMenu: aMenu - "build a tree from aMenu and open it modal" - - super openModalOnResourceSpec: aMenu +openModalOnMenu:aMenu + "build a tree from aMenu and open it modal + " + self openModalOnResourceSpec:aMenu +! + +postBuildListOfItemsView:aView + listOfItemsView := aView. ! postOpenWith:aBuilder @@ -2586,146 +1713,222 @@ " super postOpenWith: aBuilder. aBuilder keyboardProcessor menuBar:nil. + self windowGroup addPreEventHook:self. ! ! -!MenuEditor methodsFor:'user actions'! - -accept - "invoked by button 'OK' and by save requests of menu item changes" - - |node item| - - super accept. - - (node := treeView selectedNode) notNil ifTrue:[ - item := node contents. - - self isHelpToolSelected ifTrue:[ - self helpTool accept. - item activeHelpKey: self helpTool helpKey. - self valueOfEnablingCommitButtons value: false. - self clearModifiedFlag. - ] ifFalse:[ - item buildFromAspects:aspects. - node changed. - specSelector := treeView selectorName. - ] - ]. - self updateInfoLabel. - +!MenuEditor methodsFor:'private'! + +addAndSelect:aNoneArgBlockOrItem + "add an item(s) derived from the block; test if add operation + is enabled. On success the new item(s) are returned otherwise nil. + " + |intoItem index newItem| + + intoItem := self selectedItem. + intoItem ifNil:[ ^ nil]. + + self askForItemModification ifFalse:[ ^ nil ]. + + index := 1. + + ( intoItem canAddChildren + and:[(intoItem isExpanded or:[intoItem isDelayedMenu]) ] + ) ifFalse:[ + [ intoItem parent canAddChildren ] whileFalse:[ + intoItem := intoItem parent. + ]. + index := intoItem parent identityIndexOf:intoItem. + index := index + 1. + intoItem := intoItem parent. + ]. + newItem := aNoneArgBlockOrItem value. + + newItem ifNotNil:[ + selectionHolder setValue:nil. + intoItem expand. + + newItem isCollection ifTrue:[ + intoItem addAll:newItem beforeIndex:index. + selectionHolder value:newItem. + ] ifFalse:[ + intoItem add:newItem beforeIndex:index. + selectionHolder value:(Array with:newItem). + ]. + modified := true. + ]. + ^ newItem ! -cancel - "invoked by button 'Cancel'" - |node item| - - node := treeView selectedNode. - - aspects keysAndValuesDo:[:aKey :anAspect| - aKey ~~ #retrieverClassList ifTrue:[ - anAspect setValue:''. "/ to clear the field. - anAspect value:'' - ] - ]. - - node notNil ifTrue:[ - item := node contents. - item toAspects:aspects. - self helpTool helpKey:(item activeHelpKey). - ]. - self updateImageView. +clearModified + "clear the modifiedChannel and the commitPanel + " self valueOfEnablingCommitButtons value:false. self clearModifiedFlag. ! -doBrowseForImageResource - "opens a browser on image-resource methods" - - |msg currClass w cls sel| - - currClass := self currentImageRetrieverClass. - msg := - (ResourceSelectionBrowser - request: 'Use Image From Class' - onSuperclass: nil - andClass: currClass - andSelector: (aspects at: #icon) - withResourceTypes: #(image fileImage programImage)). - - msg notNil ifTrue:[ - (w := msg asCollectionOfWords) size == 2 ifTrue:[ - cls := w at:1. - sel := w at:2. - cls ~= currClass ifTrue:[ - (aspects at: #retriever) value:cls asSymbol. +generateMenuSpec + "generate and returns the current menu spec or nil + " + |menu spec| + + menu := listOfItems root submenu. + menu ifNil:[^ nil]. + menu := menu literalArrayEncoding. + spec := WriteStream on:String new. + UISpecification prettyPrintSpecArray:menu on:spec indent:5. + ^ spec contents. +! + +submenuTest + "returns a menu on the current editing menu + " + |menu indication choice submenu retriever| + + menu := listOfItems root submenu. + menu ifNil:[^ nil ]. + + menu allItemsDo:[:anItem| + anItem isVisible:true. + anItem enabled:true. + anItem translateLabel:false. + + anItem value ifNotNil:[ + anItem value:[ Transcript showCR:(anItem label) ]. + ]. + anItem indication ifNotNil:[ + indication ifNil:[ indication := true asValue ]. + anItem indication:indication + ]. + anItem choice ifNotNil:[ + choice ifNil:[ choice := anItem choiceValue asValue ]. + anItem choice:choice + ]. + + anItem submenuChannel ifNotNil:[ + anItem submenuChannel:nil. + anItem submenu ifNil:[ + submenu ifNil:[ + submenu := Menu new. + submenu addItem:(MenuItem labeled:'Linked Menu...'). + ]. + anItem submenu:submenu. ]. - sel ~= (aspects at:#icon) ifTrue:[ - (aspects at: #icon) value:sel asSymbol. - ]. - self updateImageView. + ]. + retriever := anItem resourceRetriever. + retriever ifNotNil:[ + retriever labelText ifNotNil:[ retriever labelText:(anItem label) ] ]. ]. - - + menu findGuiResourcesIn:(self resolveName:specClass). + ^ menu ! -doEditImage - "opens a Image Editor on the resource retriever and the icon selector; - then updates the list of images and select the line of the image" - - super doEditImage. - lastImageRetriever := nil. - self updateImageView. +withoutNotifyDo:aBlock + "evaluate the block; all change notifications are + discard during the block is evaluated. + " + |blockResult| + + [ notifyDisabledCounter := notifyDisabledCounter + 1. + blockResult := aBlock value. + ] valueNowOrOnUnwindDo:[ + notifyDisabledCounter := notifyDisabledCounter - 1 + ]. + ^ blockResult +! ! + +!MenuEditor methodsFor:'queries'! + +hasValidSpecClass + "returns true if a valid specClass exists + " + |cls| + + specClass ifNil:[^ false]. + cls := self resolveName:specClass. + ^ cls notNil +! ! + +!MenuEditor methodsFor:'selection'! + +canSelect:anIndex + "called whenever the selection changed; test whether + current item is not modified .... + " + |oldSelectedItem newSelectedItem| + + self valueOfEnablingCommitButtons value ifFalse:[ + ^ true + ]. + oldSelectedItem := self selectedItem. + oldSelectedItem ifNil:[^ true]. + + newSelectedItem := listOfItems at:anIndex ifAbsent:nil. + oldSelectedItem == newSelectedItem ifTrue:[ + ^ true + ]. + ^ self askForItemModification ! +selectedItem + "returns the selected item or nil (none or multiple selected) + " + |selection| + + selection := selectionHolder value. + selection size == 1 ifTrue:[ ^ selection first ]. + ^ nil +! + +selectedItem:anItem + "change selection to an item + " + |selection| + + anItem notNil ifTrue:[ selection := Array with:anItem ] + ifFalse:[ selection := #() ]. + + selectionHolder value:selection. +! ! + +!MenuEditor methodsFor:'user actions - building'! + doNew - - super doNew ifTrue: [self helpTool doNew] + "clear editing menu; start from scratch + " + super doNew ifTrue:[ self helpTool doNew ]. ! doPickAMenu - + "pick a menu from user + " |view| self askForModification ifTrue:[ - ((view := Screen current viewFromUser) isNil or: - [view == Screen current rootView]) ifTrue:[ + ( (view := Screen current viewFromUser) isNil + or:[view == Screen current rootView] + ) ifTrue:[ ^ self ]. view specClass == MenuPanelSpec ifTrue:[ - ^ treeView buildFromMenu: view asMenu + specSelector := #pickedMenu. + ^ self buildFromMenu:(view asMenu) selector:specSelector. ]. ]. - ^ nil -! - -doRemoveImage - "removes the image of the selected line" - |cls sel| - - sel := self selectionOfImage value. - - sel size ~~ 0 ifTrue:[ - cls := self currentImageRetrieverClass. - cls notNil ifTrue:[ - cls class removeSelector:(sel string) - ]. - (aspects at:#icon) value:nil. - lastImageRetriever := nil. - self updateImageView. - ] ! doSave - |cls menu spec mthd category code excla| + "save current editing menu to + class: specClass + selector: specSelector + " + |cls spec mthd category code excla| super doSave ifFalse: [^nil]. - - cls := self resolveName: specClass. - menu := treeView asMenu literalArrayEncoding. - spec := WriteStream on:String new. - UISpecification prettyPrintSpecArray:menu on:spec indent:5. - spec := spec contents. + spec := self generateMenuSpec. + spec ifNil:[^ nil]. + + cls := self resolveName:specClass. "/ if that method already exists, do not overwrite the category @@ -2761,922 +1964,2653 @@ self isStandAlone ifTrue: [self helpTool installHelpSpecsOnClass:self specClass]. self updateHistory. - self updateInfoLabel. - hasSaved := true. modified := false. - ! doSaveAs - - super doSaveAs ifTrue: [treeView selectorName:specSelector] + "save current editing menu to class and selector + defined by the user. + " + super doSaveAs ifTrue:[ + listOfItems root rawLabel:specSelector + ]. +! + +doShowMenuSpec + "opens a code view with the contents of the menu spec + " + |spec| + + spec := self generateMenuSpec. + + spec ifNotNil:[ + CodeView openWith:spec title: 'Menu Spec' + ]. +! ! + +!MenuEditor methodsFor:'user actions - creation'! + +doCreateDelayedMenu:what + |selectedItem delayedItem| + + selectedItem := self selectedItem. + selectedItem ifNil:[^ self]. + + selectedItem canAddDelayedMenu ifFalse:[ ^ self ]. + self askForItemModification ifFalse:[ ^ self ]. + + what == #menu ifTrue:[ delayedItem := ItemMenu new ] + ifFalse:[ delayedItem := ItemLinkedMenu new ]. + + delayedItem setExpanded:true. + delayedItem := selectedItem add:delayedItem. + + delayedItem ifNotNil:[ + self selectedItem:delayedItem. + ]. +! + +doCreateItem + "create a new Item + " + self addAndSelect:[ ItemAction new ]. +! + +doCreateLinkedMenu + "create a new Linked Menu + " + self addAndSelect:[ ItemLinkedMenu new ]. +! + +doCreateMenu + "create a new Menu + " + self addAndSelect:[ |item| + item := ItemMenu new. + item expand. + item + ]. +! + +doCreateSep + "create a new Separator Item + " + self addAndSelect:[ ItemSeparator new ]. +! + +doCreateStandardEditMenu + "create a standart edit menu + " + self addAndSelect:[ + ItemMenu menu:(self class standardEditMenu) labeled:'Edit' + ]. ! -doStepDown - "shift selected menu item one step down" - - treeView selectedNodeChangeSequenceOrder:1. +doCreateStandardFileMenu + "create a standart file menu + " + self addAndSelect:[ + ItemMenu menu:(self class standardFileMenu) labeled:'File' + ]. +! + +doCreateStandardHelpMenu + "create a standart help menu + " + |item| + + self addAndSelect:[ + item := ItemMenu menu:(self class standardHelpMenu) labeled:'Help'. + item aspectAt:#startGroup put:#right. + item + ]. +! ! + +!MenuEditor methodsFor:'user actions - editing'! + +doCopy + "copy selected menuItems to the clipboard + " + |clip items| + + items := self selectedSuperItems. + items isEmpty ifTrue:[ ^ self ]. + + clip := OrderedCollection new. + items do:[:el| clip add:(el menuItem) ]. + + self clipboard:clip. + self updateAllToolInstances. +! + +doCut + "copy selected menuItems to the clipboard and delete + " + self doCopy. + self doDelete. +! + +doDelete + "delete selected menuItems + " + |selectedItem parent toDelete behind nextItem prevItem| + + toDelete := self selectedSuperItems. + toDelete isEmpty ifTrue:[ ^ self ]. + + self clearModified. + + selectedItem := toDelete first. + + selectedItem isRootItem ifTrue:[ + ^ selectedItem removeAll. + ]. + "/ compute the new selection + + prevItem := parent := selectedItem parent. + nextItem := nil. + + parent children size ~~ 1 ifTrue:[ + behind := false. + + parent do:[:el| + behind ifTrue:[ + (nextItem notNil or:[toDelete includesIdentical:el]) ifFalse:[ nextItem := el ]. + ] ifFalse:[ + behind := el == selectedItem. + (behind or:[toDelete includesIdentical:el]) ifFalse:[ prevItem := el ]. + ] + ] + ]. + self withoutNotifyDo:[ + toDelete do:[:el| el remove ]. + ]. + self selectedItem:(nextItem ? prevItem). modified := true. - - - - + self updateChannels. +! + +doPaste + "paste from clipboard + " + ^ self doPaste:(self clipboard) ! -doStepIn - "move selected menu item into next submenu" - - "/ treeView selectedNodeBecomeChildOfNext. - treeView selectedNodesBecomeChildrenOfNext. +doPaste:aCollection + "paste collection of MenuItems + " + |item loMenuItems| + + aCollection size == 0 ifTrue:[ ^ self ]. + + item := self selectedItem. + item ifNil:[ ^ self ]. + + loMenuItems := OrderedCollection new. + aCollection do:[:el| + el class == MenuItem ifTrue:[ loMenuItems add:el ]. + ]. + loMenuItems isEmpty ifTrue:[ ^ self ]. + + self addAndSelect:[ + loMenuItems collect:[:el| Item menuItem:el ] + ]. +! ! + +!MenuEditor methodsFor:'user actions - hierarchy'! + +doMoveIn:aDirection + "move selected item into the next (#inNext) or previous (#inPrev) item + " + |item idx parent toParent| + + item := self selectedItem. + item ifNil:[^ self]. + + aDirection == #inNext ifTrue:[ item canMoveInNext ifFalse:[^ self] ] + ifFalse:[ item canMoveInAbove ifFalse:[^ self] ]. + + self askForItemModification ifFalse:[ ^ self ]. + + parent := item parent. + idx := parent identityIndexOf:item. + + aDirection == #inNext ifTrue:[ toParent := parent at:(idx + 1) ifAbsent:nil ] + ifFalse:[ toParent := parent at:(idx - 1) ifAbsent:nil ]. + + self withoutNotifyDo:[ + selectionHolder setValue:#(). + parent removeIndex:idx. + + aDirection == #inNext ifTrue:[ toParent addFirst:item ] + ifFalse:[ toParent addLast:item ]. + item makeVisible. + ]. + self selectedItem:item. modified := true. ! -doStepInAbove - "move selected menu item into previous submenu" - - treeView selectedNodeBecomeChildOfPrevious. - modified := true. -! - -doStepOut - "move selected menu item(s) out from parent submenu" - - treeView selectedNodesBecomeSistersOfParent. +doMoveOut + "move selected item out of current item + " + |item parent grandParent index| + + item := self selectedItem. + item ifNil:[^ self]. + item canMoveOut ifFalse:[^ self]. + + self askForItemModification ifFalse:[ ^ self ]. + + parent := item parent. + grandParent := parent parent. + index := grandParent identityIndexOf:parent. + + self withoutNotifyDo:[ + selectionHolder setValue:#(). + parent remove:item. + index > grandParent size ifTrue:[ grandParent add:item ] + ifFalse:[ grandParent add:item afterIndex:index ] + ]. + self selectedItem:item. modified := true. ! -doStepUp - "shift selected menu item one step up" - - treeView selectedNodeChangeSequenceOrder:-1. +doMoveUpOrDown:aDirection + "move selected item up (#up) or down (#down) + " + |item index parent children| + + item := self selectedItem. + item ifNil:[^ self]. + item canMoveUpOrDown ifFalse:[^ self]. + + self askForItemModification ifFalse:[ ^ self ]. + + self withoutNotifyDo:[ + parent := item parent. + children := parent children. + index := children identityIndexOf:item. + + selectionHolder setValue:#(). + children removeIndex:index. + + aDirection == #up ifTrue:[ + index == 1 ifTrue:[ children add:item ] + ifFalse:[ children add:item beforeIndex:index - 1 ] + ] ifFalse:[ + index > children size ifTrue:[ children addFirst:item ] + ifFalse:[ children add:item afterIndex:index ] + ]. + parent childrenOrderChanged. + ]. + self selectedItem:item. modified := true. ! ! -!MenuEditor::Item class methodsFor:'constants'! - -separatorList - "get the list of available separator types" - - ^#('blank' 'single line' 'double line') +!MenuEditor::Item class methodsFor:'defaults'! + +defaultLabel + ^ self subclassResponsibility +! ! + +!MenuEditor::Item class methodsFor:'image specs'! + +iconDelayedLinkedMenu + "This resource specification was automatically generated + by the ImageEditor of ST/X." + + "Do not manually edit this!! If it is corrupted, + the ImageEditor may not be able to read the specification." + + " + self iconDelayedLinkedMenu inspect + ImageEditor openOnClass:self andSelector:#iconDelayedLinkedMenu + Icon flushCachedIcons + " + + + + ^Icon + constantNamed:#'MenuEditor::Item class iconDelayedLinkedMenu' + ifAbsentPut:[(Depth4Image new) width: 20; height: 16; photometric:(#palette); bitsPerSample:(#(4 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:' +@@@@@@@@@@@@@@DQDQDQDQDQDR@AH"H"H"H"H"H0@@@BH"H"@@@BL@QDPBH"H"@@H#@DQDPBH@H"@"H0ADQDPBA@H"H"L@@@QDP@Q@@@@@@ADPQDQDQ@DQD +@RH QDQDQ@H"L@D"H QDQD@"H#@A@@@@@DP@@@@0@QDQDQA@DQDQL@D"H"H @"H"H#@BL3L3L3L3L3L0@@@@@@@@@@@@@@@a') ; colorMapFromArray:#[0 0 0 255 255 255 170 170 170 127 127 127 255 0 0]; mask:((Depth1Image new) width: 20; height: 16; photometric:(#blackIs0); bitsPerSample:(#(1 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'???0???0???0???0???0???0???0???0???0???0???0???0???0???0???0???0') ; yourself); yourself] +! + +iconDelayedMenu + "This resource specification was automatically generated + by the ImageEditor of ST/X." + + "Do not manually edit this!! If it is corrupted, + the ImageEditor may not be able to read the specification." + + " + self iconDelayedMenu inspect + ImageEditor openOnClass:self andSelector:#iconDelayedMenu + Icon flushCachedIcons + " + + + + ^Icon + constantNamed:#'MenuEditor::Item class iconDelayedMenu' + ifAbsentPut:[(Depth2Image new) width: 20; height: 16; photometric:(#palette); bitsPerSample:(#(2 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@@@@@UUUUUVA*****,F***@B0Z***@+A****J,F*****0@@@@@@AUUUUUXF*****0Z****+A@@@@@LEUUUUU0Z****+B?????<@@@@@@@b') ; colorMapFromArray:#[0 0 0 255 255 255 170 170 170 127 127 127]; mask:((Depth1Image new) width: 20; height: 16; photometric:(#blackIs0); bitsPerSample:(#(1 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'???0???0???0???0???0???0???0???0???0???0???0???0???0???0???0???0') ; yourself); yourself] +! + +iconItem + "This resource specification was automatically generated + by the ImageEditor of ST/X." + + "Do not manually edit this!! If it is corrupted, + the ImageEditor may not be able to read the specification." + + " + self iconItem inspect + ImageEditor openOnClass:self andSelector:#iconItem + Icon flushCachedIcons + " + + + + ^Icon + constantNamed:#'MenuEditor::Item class iconItem' + ifAbsentPut:[(Depth2Image new) width: 20; height: 16; photometric:(#palette); bitsPerSample:(#(2 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'UUUUUUUUUUUUUP@@@@@@EUUUUU Z****+A.?/;+,F:::/>0[++>:;A...++,F::?..0Z****+B?????<@@@@@@@@@@@@@@@@@@@@@@@@@@@b') ; colorMapFromArray:#[0 0 0 255 255 255 170 170 170 127 127 127]; mask:((Depth1Image new) width: 20; height: 16; photometric:(#blackIs0); bitsPerSample:(#(1 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@@@@@@???0???0???0???0???0???0???0???0???0???0???0@@@@@@@@@@@@') ; yourself); yourself] +! + +iconLinkedMenu + "This resource specification was automatically generated + by the ImageEditor of ST/X." + + "Do not manually edit this!! If it is corrupted, + the ImageEditor may not be able to read the specification." + + " + self iconLinkedMenu inspect + ImageEditor openOnClass:self andSelector:#iconLinkedMenu + Icon flushCachedIcons + " + + + + ^Icon + constantNamed:#'MenuEditor::Item class iconLinkedMenu' + ifAbsentPut:[(Depth4Image new) width: 20; height: 16; photometric:(#palette); bitsPerSample:(#(4 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:' +@@@@@@@@@@@@@@QDQDQDQDQDQA@DH"H"H"H"H"HPABH@@@H"H"H"D@PQ@3L0DQDQDQ@D@@L3L0@@@@@PADPCL3L0PCADD@P"@@@3L0@3@!!@DH"H"@3L3L3@P +AADQDQ@3L3L3@@P@@@@@@3L3LA@DQDQDQD@@L0PPABH"H"H"HC@"D@P"H"H"H"@BH!!@BDQDQDQDQDQDP@@@@@@@@@@@@@@@a') ; colorMapFromArray:#[0 0 0 127 127 127 170 170 170 255 0 0 255 255 255]; mask:((Depth1Image new) width: 20; height: 16; photometric:(#blackIs0); bitsPerSample:(#(1 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'???0???0???0???0???0???0???0???0???0???0???0???0???0???0???0???0') ; yourself); yourself] +! + +iconMenu + "This resource specification was automatically generated + by the ImageEditor of ST/X." + + "Do not manually edit this!! If it is corrupted, + the ImageEditor may not be able to read the specification." + + " + self iconMenu inspect + ImageEditor openOnClass:self andSelector:#iconMenu + Icon flushCachedIcons + " + + + + ^Icon + constantNamed:#'MenuEditor::Item class iconMenu' + ifAbsentPut:[(Depth2Image new) width: 20; height: 16; photometric:(#palette); bitsPerSample:(#(2 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@@@@@?????=C*****$N*****P5UUUUUC@@@@@DO?????P:****)C*****$MUUUUUP0@@@@AC?????4N*****P:****)BUUUUUT@@@@@@@b') ; colorMapFromArray:#[0 0 0 127 127 127 170 170 170 255 255 255]; mask:((Depth1Image new) width: 20; height: 16; photometric:(#blackIs0); bitsPerSample:(#(1 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'???0???0???0???0???0???0???0???0???0???0???0???0???0???0???0???0') ; yourself); yourself] +! + +iconSeparator + "This resource specification was automatically generated + by the ImageEditor of ST/X." + + "Do not manually edit this!! If it is corrupted, + the ImageEditor may not be able to read the specification." + + " + self iconSeparator inspect + ImageEditor openOnClass:self andSelector:#iconSeparator + Icon flushCachedIcons + " + + + + ^Icon + constantNamed:#'MenuEditor::Item class iconSeparator' + ifAbsentPut:[(Depth2Image new) width: 20; height: 16; photometric:(#palette); bitsPerSample:(#(2 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'UUUUUUUUUUUUUP@@@@@@EUUUUU Z****+A*****,F????:0[@@@@[A)UUUU,F*****0Z****+B?????<@@@@@@@@@@@@@@@@@@@@@@@@@@@b') ; colorMapFromArray:#[0 0 0 255 255 255 170 170 170 127 127 127]; mask:((Depth1Image new) width: 20; height: 16; photometric:(#blackIs0); bitsPerSample:(#(1 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@@@@@@???0???0???0???0???0???0???0???0???0???0???0@@@@@@@@@@@@') ; yourself); yourself] +! ! + +!MenuEditor::Item class methodsFor:'instance creation'! + +classFor:aMenuItem + + aMenuItem ifNil:[ ^ nil ]. + + aMenuItem value ifNil:[ + aMenuItem submenu ifNotNil:[ ^ MenuEditor::ItemMenu ]. + aMenuItem submenuChannel ifNotNil:[ ^ MenuEditor::ItemLinkedMenu ]. + + (self separatorTypeOf:(aMenuItem rawLabel)) notNil ifTrue:[ + ^ MenuEditor::ItemSeparator + ] + ]. + ^ MenuEditor::ItemAction ! -separatorSlices - "get the list of menu spec values of the corresponding separator types" - - ^ #( - ( #blank '' ) - ( #single '-' ) - ( #double '=' ) +menuItem:aMenuItem + |item cls| + + cls := self classFor:aMenuItem. + cls ifNil:[^ nil]. + + item := cls new. + item menuItem:aMenuItem. + ^ item +! ! + +!MenuEditor::Item class methodsFor:'interface - editor'! + +addBindingsTo:aspects for:aMenuEditor + "add additional bindings to the aspects + " + aspects at:#falseChannel ifAbsentPut:[ + false asValue + ]. + aspects at:#notDelayedMenu ifAbsentPut:[ + true asValue + ]. +! ! + +!MenuEditor::Item class methodsFor:'interface - specs'! + +detailsEditSpec + "This resource specification was automatically generated + by the UIPainter of ST/X." + + "Do not manually edit this!! If it is corrupted, + the UIPainter may not be able to read the specification." + + " + UIPainter new openOnClass:MenuEditor::Item andSelector:#detailsEditSpec + " + + + + ^ + #(#FullSpec + #name: #detailsEditSpec + #window: + #(#WindowSpec + #label: 'Details Edit' + #name: 'Details Edit' + #min: #(#Point 10 10) + #max: #(#Point 1280 1024) + #bounds: #(#Rectangle 43 153 303 398) + ) + #component: + #(#SpecCollection + #collection: #( + #(#LabelSpec + #label: 'Accelerator:' + #name: 'shortcutKeyLabel' + #layout: #(#AlignmentOrigin 107 0 26 0 1 0.5) + #activeHelpKey: #detailsAccelerator + #resizeForLabel: true + #adjust: #right + ) + #(#InputFieldSpec + #name: 'shortcutKeyField' + #layout: #(#LayoutFrame 110 0 15 0 -5 1.0 37 0) + #activeHelpKey: #detailsAccelerator + #tabable: true + #model: #shortcutKeyCharacter + #group: #inputGroup + #type: #symbolOrNil + #immediateAccept: false + #acceptOnReturn: true + #acceptOnTab: true + #acceptChannel: #acceptChannel + #modifiedChannel: #modifiedChannel + #acceptOnPointerLeave: false + ) + #(#LabelSpec + #label: 'Enabled:' + #name: 'enabledLabel' + #layout: #(#AlignmentOrigin 107 0 51 0 1 0.5) + #activeHelpKey: #detailsEnabled + #resizeForLabel: true + #adjust: #right + ) + #(#InputFieldSpec + #name: 'enabledField' + #layout: #(#LayoutFrame 110 0 40 0 -5 1.0 62 0) + #activeHelpKey: #detailsEnabled + #tabable: true + #model: #enabled + #group: #inputGroup + #type: #symbolOrNil + #immediateAccept: false + #acceptOnReturn: true + #acceptOnTab: true + #acceptChannel: #acceptChannel + #modifiedChannel: #modifiedChannel + #acceptOnPointerLeave: false + ) + #(#LabelSpec + #label: 'Visibility:' + #name: 'visibilityLabel' + #layout: #(#AlignmentOrigin 107 0 76 0 1 0.5) + #activeHelpKey: #detailsVisibility + #resizeForLabel: true + #adjust: #right + ) + #(#InputFieldSpec + #name: 'isVisibleInputField' + #layout: #(#LayoutFrame 110 0 65 0 -5 1.0 87 0) + #activeHelpKey: #detailsVisibility + #tabable: true + #model: #isVisible + #group: #inputGroup + #type: #symbolOrNil + #immediateAccept: false + #acceptOnReturn: true + #acceptOnTab: true + #acceptChannel: #acceptChannel + #modifiedChannel: #modifiedChannel + #acceptOnPointerLeave: false + ) + #(#LabelSpec + #label: 'Aux Value' + #name: 'auxLabel' + #layout: #(#AlignmentOrigin 107 0 101 0 1 0.5) + #activeHelpKey: #detailsAuxValue + #translateLabel: true + #resizeForLabel: true + #adjust: #right + ) + #(#InputFieldSpec + #name: 'auxInputField' + #layout: #(#LayoutFrame 110 0 90 0 -5 1.0 112 0) + #activeHelpKey: #detailsAuxValue + #tabable: true + #model: #auxValue + #group: #inputGroup + #type: #smalltalkObject + #immediateAccept: false + #acceptOnReturn: true + #acceptOnTab: true + #acceptChannel: #acceptChannel + #modifiedChannel: #modifiedChannel + #acceptOnPointerLeave: false + ) + #(#LabelSpec + #label: 'Start Group:' + #name: 'StartGroupLabel' + #layout: #(#AlignmentOrigin 107 0 139 0 1 0.5) + #activeHelpKey: #detailsStartGroup + #resizeForLabel: true + #adjust: #right + ) + #(#PopUpListSpec + #label: 'left' + #name: 'StartGroupPopUp' + #layout: #(#LayoutFrame 110 0 128 0 -5 1.0 150 0) + #activeHelpKey: #detailsStartGroup + #tabable: true + #model: #startGroup + #menu: + #(#left + #right + ) + ) + #(#LabelSpec + #label: 'Access Character Position:' + #name: 'accessCharLabel' + #layout: #(#AlignmentOrigin 217 0 170 0 1 0.5) + #activeHelpKey: #detailsAccessCharaterPosition + #resizeForLabel: true + #adjust: #right + ) + #(#InputFieldSpec + #name: 'accessCharField' + #layout: #(#LayoutFrame 220 0 159 0 -5 1.0 181 0) + #activeHelpKey: #detailsAccessCharaterPosition + #tabable: true + #model: #accessCharacterPosition + #group: #inputGroup + #type: #numberOrNil + #immediateAccept: false + #acceptOnReturn: true + #acceptOnTab: true + #acceptChannel: #acceptChannel + #modifiedChannel: #modifiedChannel + #acceptOnPointerLeave: false + ) + #(#LabelSpec + #label: 'Font:' + #name: 'fontLabel' + #layout: #(#AlignmentOrigin 75 0 219 0 1 0.5) + #resizeForLabel: true + #adjust: #right + ) + #(#FontMenuSpec + #attributes: + #(#tabable + true + ) + #name: 'fontMenu' + #layout: #(#LayoutFrame 78 0 208 0 -5 1.0 230 0) + #activeHelpKey: #fontMenu + #model: #font + ) + ) + + ) ) ! ! -!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 class methodsFor:'testing'! + +separatorTypeOf:aString + |size first| + + size := aString size. + + size == 0 ifTrue:[ ^ #blank ]. + + size == 1 ifTrue:[ + first := aString first. + first == $- ifTrue:[ ^ #single ]. + first == $= ifTrue:[ ^ #double ]. + first == (Character space) ifTrue:[ ^ #blank ]. + ]. + ^ nil ! ! !MenuEditor::Item methodsFor:'accessing'! -activeHelpKey - "get the help key of the menu item" - - ^activeHelpKey +children + "optimize access; do not ask the model for unspecified children + " + ^ children +! + +menuItem + "returns self as a MenuItem + " + ^ MenuItem new fromLiteralArrayEncoding:(menuItem literalArrayEncoding). +! + +menuItem:aMenuItem + "rebuild self from a MenuItem + " + |value| + + menuItem := MenuItem labeled:(self rawLabel). + + MenuEditor aspects do:[:aKey| + value := aMenuItem perform:aKey. + value ifNotNil:[ self aspectAt:aKey put:value ] + ]. +! + +rawLabel + "returns the label assigned to the item + " + ^ menuItem rawLabel +! + +rawLabel:aValue + "set the label assigned to the item + " + aValue isString ifTrue:[ + (self class separatorTypeOf:aValue) ifNil:[ + menuItem rawLabel:aValue + ] + ]. +! + +slices + "returns a sequence of supported slices + " + ^ self subclassResponsibility ! -activeHelpKey:aKey - "set the help key of the menu item" - - activeHelpKey := aKey +submenu + "returns the submenu (of class Menu) or nil + " + ^ nil +! ! + +!MenuEditor::Item methodsFor:'aspects'! + +aspectAt:aKey put:aValue + "set a specific aspect named aKey to the aValue + " + aKey == #rawLabel ifTrue:[ ^ self rawLabel:aValue ]. + aKey == #submenuChannel ifTrue:[ ^ self ]. + + menuItem perform:((aKey, ':') asSymbol) with:aValue. +! + +fromAspects:aspects + "read values from aspects + " + MenuEditor aspects do:[:aKey| + self aspectAt:aKey put:((aspects at:aKey) value) + ]. + self changed. +! + +toAspects:aspects + "write values to aspects + " + MenuEditor aspects do:[:aKey| + (aspects at:aKey) value:(menuItem perform:aKey) + ]. + (aspects at:#notDelayedMenu) value:(self isDelayedMenu not). +! ! + +!MenuEditor::Item methodsFor:'displaying'! + +displayLabel + "returns the label on default displayed on the screen + " + ^ menuItem rawLabel +! + +displayOn:aGC x:x y:y h:h + "display the item in the graphicsContext, aGC. + " + |label| + + label := self displayLabel. + + label notNil ifTrue:[ + self displayLabel:label h:(self heightOn:aGC) on:aGC x:x y:y h:h + ]. +! + +heightOn:aGC + "returns the height of the label on a GC + " + height ifNil:[ height := parent heightOn:aGC ]. + ^ height ! label - "get the value of the menu item" - - ^label -! - -label:something - "set the value of the menu item" - - label := something ? '-' -! - -separatorType - "get the separator type assigned to item or nil" - - label size > 1 - ifFalse: - [ - label size == 0 ifTrue:[^#blank]. - label first == $- ifTrue:[^#single]. - label first == $= ifTrue:[^#double]. - ]. - ^nil - -! - -startGroup:aSymbolOrNil - "set the startGroup attribute" - - startGroup := aSymbolOrNil - - "Created: / 23.8.1998 / 15:56:03 / cg" -! - -submenuChannel - "return the value of the instance variable 'submenuChannel' (automatically generated)" - - ^submenuChannel -! - -submenuChannel:aChannel - "get the submenuChannel" - - submenuChannel := aChannel -! - -translateLabel:aBoolean - "set/clear the translate to national-language flag" - - translateLabel := aBoolean - - "Created: / 6.6.1998 / 17:23:33 / cg" + "get the rawLabel assigned to the item + " + ^ menuItem rawLabel ! -value:aSymbol - "set the value attribute" - - value := aSymbol - - "Created: / 23.8.1998 / 16:02:10 / cg" -! ! - -!MenuEditor::Item methodsFor:'building'! - -buildFromAspects:aspects - "read the values of the aspects into my values" - - |name| - self isSeparator - ifFalse: - [ - name := label. - label := (aspects at:#label) value. - - (label isNil or:[self isSeparator]) ifTrue:[ - (aspects at:#label) value:(label := name) - ]. - - enabled := (aspects at:#enabled) value. - value := (aspects at:#value) value. - nameKey := (aspects at:#nameKey) value. - indication := (aspects at:#indication) value. - choice := (aspects at:#choice) value. - choiceValue := (aspects at:#choiceValue) value. - shortcutKey := (aspects at:#shortcutKey) value. - startGroup := (aspects at:#startGroup) value. - accessCharacterPos := (aspects at:#accessCharacterPos) value. - showBusyCursorWhilePerforming := (aspects at:#showBusyCursorWhilePerforming) value. - triggerOnDown := (aspects at:#triggerOnDown) value. - keepLinkedMenu := (aspects at:#keepLinkedMenu) value ? false. - font := (aspects at:#font) value. - argument := (aspects at:#argument) value. - translateLabel := (aspects at:#translateLabel) value. - isButton := (aspects at:#isButton) value. - auxValue := (aspects at:#auxValue) value. - horizontalLayout := (aspects at:#horizontalLayout) value. - - argument isString ifTrue:[ - argument size > 1 ifTrue:[ - (argument at:1) == $# ifTrue:[ - argument := (argument copyFrom:2) asSymbol - ] - ] - ]. - 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. - ]. - isVisible := (aspects at:#isVisible) value. - hideMenuOnActivated := (aspects at:#hideMenuOnActivated) value. - - "Modified: / 14.8.1998 / 15:36:38 / cg" +label:aLabel + "set the rawLabel assigned to the item + " + self rawLabel:aLabel ! -buildFromMenuItem:anItem - "read the attributes of anItem into my values" - - |rtv| - - self label:(anItem rawLabel). - activeHelpKey := anItem activeHelpKey. - - (enabled := anItem enabled) isSymbol ifFalse:[ - enabled := nil - ]. - (value := anItem value) isSymbol ifFalse:[ - value := nil. - ]. - (indication := anItem indication) isSymbol ifFalse:[ - indication := nil - ]. - (choice := anItem choice) isSymbol ifFalse:[ - choice := nil - ]. - choiceValue := anItem choiceValue. - nameKey := anItem nameKey. - shortcutKey := anItem shortcutKeyCharacter. - startGroup := anItem startGroup. - accessCharacterPos := anItem accessCharacterPosition. - showBusyCursorWhilePerforming := anItem showBusyCursorWhilePerforming. - triggerOnDown := anItem triggerOnDown. - keepLinkedMenu := anItem keepLinkedMenu. - font := anItem font. - argument := anItem argument. - - submenuChannel := anItem submenuChannel. - translateLabel := anItem translateLabel. - isButton := anItem isButton. - isVisible := anItem isVisible. - hideMenuOnActivated := anItem hideMenuOnActivated. - auxValue := anItem auxValue. - horizontalLayout := anItem horizontalLayout. - - (((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. - ] - ] - - "Modified: / 29.9.1998 / 11:18:25 / cg" +widthOn:aGC + "returns the height of the displayLabel on a GC + " + width ifNil:[ width := self widthOf:(self displayLabel) on:aGC ]. + ^ width ! ! -!MenuEditor::Item methodsFor:'conversion'! - -asMenuItem - "converts self to a menu item" - - |item rcv| - - item := MenuItem labeled:label. - item isVisible:isVisible. - item hideMenuOnActivated:hideMenuOnActivated. - - self isSeparator ifFalse:[ - item activeHelpKey:activeHelpKey. - item enabled:enabled. - item accessCharacterPosition:accessCharacterPos. - item showBusyCursorWhilePerforming:showBusyCursorWhilePerforming. - item triggerOnDown:triggerOnDown. - item keepLinkedMenu:keepLinkedMenu. - item font:font. - item argument:argument. - item submenuChannel:submenuChannel. - item nameKey:nameKey. - item shortcutKeyCharacter:shortcutKey. - item startGroup:startGroup. - item value:value. - item indication:indication. - item choice:choice. - item choiceValue:choiceValue. - item translateLabel: translateLabel. - item isButton: isButton. - item auxValue: auxValue. - - horizontalLayout == true ifTrue:[ - item horizontalLayout:true. - ]. - - icon notNil ifTrue:[ - rcv := ResourceRetriever new. - rcv className:retriever. - rcv selector:icon. - iconAndLabel == true ifTrue:[ - rcv labelText:label - ]. - item labelImage:rcv - ] - ]. - ^item - - "Modified: / 14.8.1998 / 15:36:35 / cg" -! - -toAspects:aspects - "put my values into the values of 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:#enabled) value:enabled. - (aspects at:#value) value:value. - (aspects at:#nameKey) value:nameKey. - (aspects at:#indication) value:indication. - (aspects at:#choice) value:choice. - (aspects at:#choiceValue) value:choiceValue. - (aspects at:#shortcutKey) value:shortcutKey. - (aspects at:#startGroup) value:startGroup. - (aspects at:#accessCharacterPos) value:accessCharacterPos. - (aspects at:#showBusyCursorWhilePerforming) value:showBusyCursorWhilePerforming. - (aspects at:#triggerOnDown) value:triggerOnDown. - (aspects at:#keepLinkedMenu) value:(keepLinkedMenu ? false). - (aspects at:#font) value:font. - (aspects at:#translateLabel) value:translateLabel. - (aspects at:#submenuChannel) value:submenuChannel. - (aspects at:#retriever) value:retriever. - (aspects at:#icon) value:icon. - (aspects at:#iconAndLabel) value:iconAndLabel. - (aspects at:#isButton) value:isButton. - (aspects at:#auxValue) value:auxValue. - (aspects at:#horizontalLayout) value:(horizontalLayout ? false). - - (aspects at:#argument) - value:(argument isSymbol - ifTrue: ['#', argument] - ifFalse:[argument]). - ]. - (aspects at:#isVisible) value:isVisible. - (aspects at:#hideMenuOnActivated) value:(hideMenuOnActivated ? true). - - "Modified: / 14.8.1998 / 15:37:29 / cg" +!MenuEditor::Item methodsFor:'initialization'! + +initialize + super initialize. + menuItem := MenuItem label:(self class defaultLabel). ! ! !MenuEditor::Item methodsFor:'queries'! -iconFor: aNode - "get the icon of the menu item for the tree view" - - (aNode hasChildren or: [aNode parent isNil]) - ifTrue: - [ - ^MenuEditor submenuImage - ] - ifFalse: - [ - submenuChannel notNil - ifTrue: - [ - ^MenuEditor linkSubmenuImage - ] - ifFalse: - [ - self isSeparator - ifTrue: [^MenuEditor menuSeparatorImage] - ifFalse: [^MenuEditor menuItemImage] - ] - ] +isAction + "returns true if the item is an Action + " + ^ false +! + +isDelayedMenu + "returns true if the item is a Delayed (Linked) Menu + " + ^ parent isAction +! + +isKindOfMenu + "returns true if the item is a Linked Menu or Menu + " + ^ false +! + +isRootItem + "returns true if the item is the root item + " + ^ false +! ! + +!MenuEditor::Item methodsFor:'queries - operation'! + +canAddChildren + "returns true if children can be added + " + ^ false +! + +canAddDelayedMenu + "returns true if a delayed menu can be added; + on default false is returned + " + ^ false +! + +canMoveInAbove + "returns true if the item can become a child of its previous sibling + " + |siblings index nextItem| + + siblings := parent children. + siblings size > 1 ifFalse:[ ^ false ]. + + index := siblings identityIndexOf:self. + nextItem := siblings at:(index - 1) ifAbsent:nil. + + nextItem ifNil:[^ false]. + ^ nextItem canAddChildren ! -isSeparator - "return true if item is a seperator" - - ^self separatorType notNil +canMoveInNext + "returns true if the item can become a child of its next sibling + " + |siblings index nextItem| + + siblings := parent children. + siblings size > 1 ifFalse:[ ^ false ]. + + index := siblings identityIndexOf:self. + nextItem := siblings at:(index + 1) ifAbsent:nil. + + nextItem ifNil:[^ false]. + ^ nextItem canAddChildren +! + +canMoveOut + "returns true if the item can be moved out from its current parent + " + self isDelayedMenu ifTrue:[^ false]. + parent isDelayedMenu ifTrue:[^ false]. + + ^ parent parent notNil ! -treeViewLabel - "get the label of the menu item for the tree view" - - ^label -" asBoldText, - (value notNil ifTrue: [': [', - value , - (argument isString ifTrue: [' ', (Text string: argument emphasis: #italic)] ifFalse: ['']), - ']'] ifFalse: ['']) - - -" +canMoveUpOrDown + "returns true if the item can change its vertical order in its sibling + " + ^ parent children size > 1 +! ! + +!MenuEditor::ItemAction class methodsFor:'defaults'! + +defaultLabel + ^ 'Action' +! ! + +!MenuEditor::ItemAction class methodsFor:'interface - editor'! + +addBindingsTo:aspects for:aMenuEditor + "add additional bindings to the aspects + " + aspects at:#indicationEnabled ifAbsentPut:[ + BlockValue with:[:a | a size == 0 ] argument:(aspects at:#choice) + ]. + + aspects at:#choiceEnabled ifAbsentPut:[ + BlockValue with:[:a | a size == 0 ] argument:(aspects at:#indication) + ]. + + aspects at:#choiceValueEnabled ifAbsentPut:[ + BlockValue with:[:a | a size ~~ 0 ] argument:(aspects at:#choice) + ]. + aspects at:#hasNoDelayedMenuValue ifAbsentPut:[ + true asValue + ]. ! ! -!MenuEditor::TreeView class methodsFor:'documentation'! - -documentation -" - This tree view class provides a hierarchical representation - of the components of a menu. - - [see also:] - SelectionInTreeView - SelectionInTree - TreeItem - - [author:] - Claus Atzkern -" +!MenuEditor::ItemAction class methodsFor:'interface - specs'! + +basicsEditSpec + "This resource specification was automatically generated + by the UIPainter of ST/X." + + "Do not manually edit this!! If it is corrupted, + the UIPainter may not be able to read the specification." + + " + UIPainter new openOnClass:MenuEditor::ItemAction andSelector:#basicsEditSpec + " + + + + ^ + #(#FullSpec + #name: #basicsEditSpec + #window: + #(#WindowSpec + #label: 'basicsEditSpec' + #name: 'basicsEditSpec' + #min: #(#Point 10 10) + #max: #(#Point 1160 870) + #bounds: #(#Rectangle 9 625 349 965) + ) + #component: + #(#SpecCollection + #collection: #( + #(#LabelSpec + #label: 'Name Key:' + #name: 'nameKeyLabel' + #layout: #(#AlignmentOrigin 107 0 25 0 1 0.5) + #activeHelpKey: #basicsKey + #resizeForLabel: true + #adjust: #right + ) + #(#InputFieldSpec + #name: 'nameKeyField' + #layout: #(#LayoutFrame 110 0 15 0 -5 1.0 37 0) + #activeHelpKey: #basicsKey + #tabable: true + #model: #nameKey + #group: #inputGroup + #type: #symbolOrNil + #immediateAccept: false + #acceptOnLeave: false + #acceptOnReturn: true + #acceptOnTab: true + #acceptOnLostFocus: false + #acceptChannel: #acceptChannel + #modifiedChannel: #modifiedChannel + #acceptOnPointerLeave: false + ) + #(#LabelSpec + #label: 'Label:' + #name: 'labelLabel' + #layout: #(#AlignmentOrigin 107 0 51 0 1 0.5) + #activeHelpKey: #basicsLabel + #resizeForLabel: true + #adjust: #right + ) + #(#InputFieldSpec + #name: 'labelField' + #layout: #(#LayoutFrame 110 0 40 0 -5 1.0 62 0) + #activeHelpKey: #basicsLabel + #tabable: true + #model: #rawLabel + #group: #inputGroup + #immediateAccept: false + #acceptOnReturn: true + #acceptOnTab: true + #acceptOnLostFocus: false + #acceptChannel: #acceptChannel + #modifiedChannel: #modifiedChannel + #acceptOnPointerLeave: false + ) + #(#LabelSpec + #label: 'Action:' + #name: 'valueLabel' + #layout: #(#AlignmentOrigin 107 0 82 0 1 0.5) + #activeHelpKey: #basicsAction + #resizeForLabel: true + #adjust: #right + ) + #(#InputFieldSpec + #name: 'valueField' + #layout: #(#LayoutFrame 110 0 71 0 -5 1.0 93 0) + #activeHelpKey: #basicsAction + #tabable: true + #model: #value + #group: #inputGroup + #type: #symbolOrNil + #immediateAccept: false + #acceptOnReturn: true + #acceptOnTab: true + #acceptOnLostFocus: false + #acceptChannel: #acceptChannel + #modifiedChannel: #modifiedChannel + #acceptOnPointerLeave: false + ) + #(#LabelSpec + #label: 'Argument:' + #name: 'argumentLabel' + #layout: #(#AlignmentOrigin 107 0 107 0 1 0.5) + #activeHelpKey: #basicsArgument + #resizeForLabel: true + #adjust: #right + ) + #(#InputFieldSpec + #name: 'argumentField' + #layout: #(#LayoutFrame 110 0 96 0 -5 1.0 118 0) + #activeHelpKey: #basicsArgument + #tabable: true + #model: #argument + #group: #inputGroup + #type: #smalltalkObject + #immediateAccept: false + #acceptOnReturn: true + #acceptOnTab: true + #acceptOnLostFocus: false + #acceptChannel: #acceptChannel + #modifiedChannel: #modifiedChannel + #acceptOnPointerLeave: false + ) + #(#LabelSpec + #label: 'Indication:' + #name: 'indicationLabel' + #layout: #(#AlignmentOrigin 107 0 138 0 1 0.5) + #activeHelpKey: #basicsIndication + #visibilityChannel: #hasNoDelayedMenuValue + #resizeForLabel: true + #adjust: #right + ) + #(#InputFieldSpec + #name: 'indicationField' + #layout: #(#LayoutFrame 110 0 127 0 -5 1.0 149 0) + #activeHelpKey: #basicsIndication + #visibilityChannel: #hasNoDelayedMenuValue + #enableChannel: #indicationEnabled + #tabable: true + #model: #indication + #group: #inputGroup + #type: #symbolOrNil + #immediateAccept: true + #acceptOnReturn: false + #acceptOnTab: false + #acceptOnLostFocus: false + #modifiedChannel: #modifiedChannel + #acceptOnPointerLeave: false + ) + #(#LabelSpec + #label: 'Choice:' + #name: 'choiceLabel' + #layout: #(#AlignmentOrigin 107 0 163 0 1 0.5) + #activeHelpKey: #basicsChoice + #visibilityChannel: #hasNoDelayedMenuValue + #translateLabel: true + #resizeForLabel: true + #adjust: #right + ) + #(#InputFieldSpec + #name: 'choiceField' + #layout: #(#LayoutFrame 110 0 152 0 -5 1.0 174 0) + #activeHelpKey: #basicsChoice + #visibilityChannel: #hasNoDelayedMenuValue + #enableChannel: #choiceEnabled + #tabable: true + #model: #choice + #group: #inputGroup + #type: #symbolOrNil + #immediateAccept: true + #acceptOnReturn: false + #acceptOnTab: false + #acceptOnLostFocus: false + #modifiedChannel: #modifiedChannel + #acceptOnPointerLeave: false + ) + #(#LabelSpec + #label: 'Value:' + #name: 'choiceValueLabel' + #layout: #(#AlignmentOrigin 107 0 188 0 1 0.5) + #activeHelpKey: #basicsChoiceValue + #visibilityChannel: #hasNoDelayedMenuValue + #translateLabel: true + #resizeForLabel: true + #adjust: #right + ) + #(#InputFieldSpec + #name: 'choiceValueField' + #layout: #(#LayoutFrame 110 0 177 0 -5 1.0 199 0) + #activeHelpKey: #basicsChoiceValue + #visibilityChannel: #hasNoDelayedMenuValue + #enableChannel: #choiceValueEnabled + #tabable: true + #model: #choiceValue + #group: #inputGroup + #type: #smalltalkObject + #immediateAccept: false + #acceptOnLeave: false + #acceptOnReturn: true + #acceptOnTab: true + #acceptOnLostFocus: false + #acceptChannel: #acceptChannel + #modifiedChannel: #modifiedChannel + #acceptOnPointerLeave: false + ) + #(#CheckBoxSpec + #label: 'Translate Label' + #name: 'translateLabelCheckBox' + #layout: #(#Point 20 213) + #activeHelpKey: #basicsTranslateLabel + #tabable: true + #model: #translateLabel + ) + #(#CheckBoxSpec + #label: 'Is Button' + #name: 'isButtonCheckBox' + #layout: #(#Point 20 238) + #activeHelpKey: #basicsIsButton + #tabable: true + #model: #isButton + ) + #(#CheckBoxSpec + #label: 'Hide Menu after Activation' + #name: 'hideMenuOnActivated' + #layout: #(#Point 20 263) + #activeHelpKey: #hideMenuOnActivated + #tabable: true + #model: #hideMenuOnActivated + ) + #(#CheckBoxSpec + #label: 'BusyCursor while Active' + #name: 'showBusyCursorWhilePerforming' + #layout: #(#Point 20 288) + #activeHelpKey: #showBusyCursorWhilePerforming + #tabable: true + #model: #showBusyCursorWhilePerforming + #translateLabel: true + ) + #(#CheckBoxSpec + #label: 'Trigger On Down' + #name: 'triggerOnDown' + #layout: #(#Point 20 313) + #activeHelpKey: #triggerOnDown + #visibilityChannel: #hasNoDelayedMenuValue + #tabable: true + #model: #triggerOnDown + #translateLabel: true + ) + ) + + ) + ) ! ! -!MenuEditor::TreeView methodsFor:'accessing'! - -canTab - ^ true -! - -selectorName - "get the selector of the menu spec" - - ^(listOfNodes first contents label) asSymbol -! - -selectorName: aSymbol - "set the selector for the menu spec" - - listOfNodes first contents label: aSymbol -! ! - -!MenuEditor::TreeView methodsFor:'building'! - -buildFromClass:aClass andSelector:aSelector - "read a menu spec from aClass and aSelector and put - the encoded menu into the tree view" - - |spec cls menu firstNode firstNodeLabel| - - "if opened on a menu" - (aClass isNil and: [aSelector isNil and: [listOfNodes size > 0]]) ifTrue: [^nil]. - - self selection:nil. - - (aClass notNil and:[aSelector notNil]) ifTrue:[ - cls := self application resolveName:aClass. - - (cls respondsTo:aSelector) ifTrue:[ - spec := cls perform:aSelector +!MenuEditor::ItemAction methodsFor:'accessing'! + +menuItem + |item| + + item := super menuItem. + + self hasDelayedMenu ifTrue:[ + children first setDelayedAttributesTo:item. + + menuItem value ifNil:[ + menuItem value:#unspecified ] ]. - - spec isNil ifFalse:[ - (spec isMemberOf:Menu) ifFalse:[ - menu := Menu new fromLiteralArrayEncoding:spec. - ] ifTrue:[ - menu := spec. - ]. - firstNode := self nodeLabel:(aSelector asString). - self subMenu:menu parent:firstNode. - ] ifTrue:[ - (aClass notNil and: [aSelector isNil and: [listOfNodes size > 0]]) - ifTrue: - [ - firstNode := listOfNodes first - ] - ifFalse: - [ - aSelector notNil ifTrue:[firstNodeLabel := aSelector asString] - ifFalse:[firstNodeLabel := 'menu']. - firstNode := self nodeLabel:firstNodeLabel. - ] - ]. - - firstNode expand. - model root: firstNode. - - firstNode hasChildren ifFalse:[ - model add:(self nodeLabel:'Item 1') below:firstNode - ]. - - -! - -buildFromMenu:aMenu - "put aMenu into the tree view" - - |node| - - self selection:nil. - - node := self nodeLabel:'menu'. - self subMenu:aMenu parent:node. - - node hasChildren ifFalse:[ - node add:(self nodeLabel:'Item 1') - ]. - node expand. - model root:node. + ^ item ! menuItem:anItem - - |node| - - node := self nodeLabel: anItem label. - node contents buildFromMenuItem:anItem. - self subMenu: anItem submenu parent:node. - ^node. - - + |submenu item| + + super menuItem:anItem. + submenu := anItem submenu. + + submenu notNil ifTrue:[ + item := MenuEditor::ItemMenu new + ] ifFalse:[ + anItem submenuChannel ifNil:[ + ^ self + ]. + item := MenuEditor::ItemLinkedMenu new + ]. + item getDelayedAttributesFrom:anItem. + self add:item. ! -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::TreeView 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 - +slices + ^ #( + (Basics basicsEditSpec ) + (Details detailsEditSpec) + (Image image ) + (Help help) + ) ! ! -!MenuEditor::TreeView methodsFor:'drawing basics'! - -redrawLabelAt:x y:yTop index:anIndex - "draw text label assigned to a node at x y( center)" - - |isSelected y0 x0 x1 w type item| - - item := (listOfNodes at:anIndex) contents. - type := item separatorType. - - type isNil ifTrue:[ - ^ super redrawLabelAt:x y:yTop index:anIndex - ]. - isSelected := self isInSelection:anIndex. - x0 := x. - - highlightMode == #label ifTrue:[ - x0 := x + 4. - - isSelected ifTrue:[ - w := 80 + 8. - self paint:hilightBgColor. - self fillRectangleX:x y:yTop width:w height:fontHeight. - ] - ] ifFalse:[ - w := 0. +!MenuEditor::ItemAction methodsFor:'adding & removing'! + +add:anItem + "add an item; test whether the item is a delayed menu and + not already a delayed menu exists. + " + (anItem isKindOfMenu and:[self canAddDelayedMenu]) ifFalse:[ + ^ nil ]. - type == #blank ifFalse:[ - isSelected ifTrue:[self paint:hilightFgColor] - ifFalse:[self paint:fgColor]. - - x1 := x0 + 80. - y0 := yTop - 1 + (fontHeight // 2). - self displayLineFromX:x0 y:y0 toX:x1 y:y0. - - type == #double ifTrue:[ - y0 := y0 + 2. - self displayLineFromX:x0 y:y0 toX:x1 y:y0. - ] - ]. - - (isSelected and:[highlightMode == #label]) ifTrue:[ - self redrawSelFrameAtX:x y:yTop toX:(x + w) - ]. - + "/ reset values not setable if a delayed menu is configured + + menuItem choice:nil. + menuItem indication:nil. + menuItem choiceValue:nil. + menuItem triggerOnDown:false. + + anItem argument:(menuItem argument). + + isExpanded := false. + anItem parent:self. + children := Array with:anItem. + self expand. + ^ anItem ! ! -!MenuEditor::TreeView methodsFor:'event handling'! - -keyPress:key x:x y:y - "invoked if any key was pressed" - - - - (key == #Delete or:[key == #BackSpace]) ifTrue: [^self doDelete]. - key == #Cut ifTrue:[^self doCut]. - key == #Copy ifTrue:[^self doCopy]. - key == #Paste ifTrue:[^self doPaste]. - - super keyPress:key x:x y:y - +!MenuEditor::ItemAction methodsFor:'aspects'! + +aspectAt:aKey put:aValue + "pass the argument to the delayed menu if existant + " + aKey == #argument ifTrue:[ + self hasDelayedMenu ifTrue:[ + children first argument:aValue + ]. + menuItem argument:aValue. + ^ self + ]. + super aspectAt:aKey put:aValue. +! + +toAspects:aspects + "write values to aspects + " + super toAspects:aspects. + + (aspects at:#hasNoDelayedMenuValue) value:(self hasDelayedMenu not). ! ! -!MenuEditor::TreeView methodsFor:'initialization'! +!MenuEditor::ItemAction methodsFor:'displaying'! + +icon + ^ self class iconItem +! ! + +!MenuEditor::ItemAction methodsFor:'initialization'! initialize - "initialize the tree view of the menu components" - super initialize. - - self multipleSelectOk:true. - self showDirectoryIndicator: true. - self showDirectoryIndicatorForRoot: false. - self selectConditionBlock: [:i|self application askForItemModification]. - self validateDoubleClickBlock: [:node| node ~~ listOfNodes first]. - self model iconAction: [:aNode| aNode contents iconFor: aNode]. - self model labelAction: [:aNode| aNode contents treeViewLabel] + isExpanded := true. +! ! + +!MenuEditor::ItemAction methodsFor:'queries'! + +canCollapse + ^ false +! + +hasDelayedMenu + "returns true if a delayed menu exists + " + ^ children size ~~ 0 +! + +hasIndicator + ^ false +! + +isAction + ^ true +! ! + +!MenuEditor::ItemAction methodsFor:'queries - operation'! + +canAddDelayedMenu + "returns true if a delayed menu can be added; + no delayed menu exists and the indication or choice is unspecified + " + self hasDelayedMenu ifTrue:[ ^ false ]. + ^ (menuItem indication isNil and:[menuItem choice isNil]) +! ! + +!MenuEditor::ItemLinkedMenu class methodsFor:'defaults'! + +defaultLabel + ^ 'Linked Menu' ! ! -!MenuEditor::TreeView methodsFor:'menus'! - -XXdoDeleteSelectionBuffered:aBool - |appl idx| - - appl := self topView application. - - (appl hasValidSelection value and: [self askForItemModification]) ifFalse:[ - ^ self - ]. - aBool ifTrue:[ - self doCopy +!MenuEditor::ItemLinkedMenu class methodsFor:'interface - specs'! + +basicsEditSpec + "This resource specification was automatically generated + by the UIPainter of ST/X." + + "Do not manually edit this!! If it is corrupted, + the UIPainter may not be able to read the specification." + + " + UIPainter new openOnClass:MenuEditor::ItemLinkedMenu andSelector:#basicsEditSpec + " + + + + ^ + #(#FullSpec + #name: #basicsEditSpec + #window: + #(#WindowSpec + #label: 'basicsEditSpec' + #name: 'basicsEditSpec' + #min: #(#Point 10 10) + #max: #(#Point 1160 870) + #bounds: #(#Rectangle 346 355 686 695) + ) + #component: + #(#SpecCollection + #collection: #( + #(#LabelSpec + #label: 'Name Key:' + #name: 'nameKeyLabel' + #layout: #(#AlignmentOrigin 107 0 25 0 1 0.5) + #activeHelpKey: #basicsKey + #visibilityChannel: #notDelayedMenu + #resizeForLabel: true + #adjust: #right + ) + #(#InputFieldSpec + #name: 'nameKeyField' + #layout: #(#LayoutFrame 110 0 15 0 -5 1.0 37 0) + #activeHelpKey: #basicsKey + #visibilityChannel: #notDelayedMenu + #tabable: true + #model: #nameKey + #group: #inputGroup + #type: #symbolOrNil + #immediateAccept: false + #acceptOnLeave: false + #acceptOnReturn: true + #acceptOnTab: true + #acceptOnLostFocus: false + #acceptChannel: #acceptChannel + #modifiedChannel: #modifiedChannel + #acceptOnPointerLeave: false + ) + #(#LabelSpec + #label: 'Label:' + #name: 'labelLabel' + #layout: #(#AlignmentOrigin 107 0 51 0 1 0.5) + #activeHelpKey: #basicsLabel + #visibilityChannel: #notDelayedMenu + #resizeForLabel: true + #adjust: #right + ) + #(#InputFieldSpec + #name: 'labelField' + #layout: #(#LayoutFrame 110 0 40 0 -5 1.0 62 0) + #activeHelpKey: #basicsLabel + #visibilityChannel: #notDelayedMenu + #tabable: true + #model: #rawLabel + #group: #inputGroup + #immediateAccept: false + #acceptOnReturn: true + #acceptOnTab: true + #acceptOnLostFocus: false + #acceptChannel: #acceptChannel + #modifiedChannel: #modifiedChannel + #acceptOnPointerLeave: false + ) + #(#LabelSpec + #label: 'Menu:' + #name: 'menuLabel' + #layout: #(#AlignmentOrigin 107 0 90 0 1 0.5) + #activeHelpKey: #basicsLabel + #resizeForLabel: true + #adjust: #right + ) + #(#InputFieldSpec + #name: 'menuField' + #layout: #(#LayoutFrame 110 0 79 0 -5 1.0 101 0) + #activeHelpKey: #basicsMenu + #tabable: true + #model: #submenuChannel + #group: #inputGroup + #type: #symbolOrNil + #immediateAccept: false + #acceptOnReturn: true + #acceptOnTab: true + #acceptOnLostFocus: false + #acceptChannel: #acceptChannel + #modifiedChannel: #modifiedChannel + #acceptOnPointerLeave: false + ) + #(#LabelSpec + #label: 'Argument:' + #name: 'argumentLabel' + #layout: #(#AlignmentOrigin 107 0 115 0 1 0.5) + #activeHelpKey: #basicsLabel + #resizeForLabel: true + #adjust: #right + ) + #(#InputFieldSpec + #name: 'argumentField' + #layout: #(#LayoutFrame 110 0 104 0 -5 1.0 126 0) + #activeHelpKey: #basicsMenuArgument + #tabable: true + #model: #argument + #group: #inputGroup + #type: #smalltalkObject + #immediateAccept: false + #acceptOnReturn: true + #acceptOnTab: true + #acceptOnLostFocus: false + #acceptChannel: #acceptChannel + #modifiedChannel: #modifiedChannel + #acceptOnPointerLeave: false + ) + #(#CheckBoxSpec + #label: 'Translate Label' + #name: 'translateLabelCheckBox' + #layout: #(#Point 20 213) + #activeHelpKey: #basicsTranslateLabel + #visibilityChannel: #notDelayedMenu + #tabable: true + #model: #translateLabel + ) + #(#CheckBoxSpec + #label: 'Is Button' + #name: 'isButtonCheckBox' + #layout: #(#Point 20 238) + #activeHelpKey: #basicsIsButton + #visibilityChannel: #notDelayedMenu + #tabable: true + #model: #isButton + ) + #(#CheckBoxSpec + #label: 'Has Horizontal Layout' + #name: 'horizontalLayout' + #layout: #(#Point 20 263) + #activeHelpKey: #horizontalLayout + #tabable: true + #model: #horizontalLayout + ) + #(#CheckBoxSpec + #label: 'Do not destroy linked Menu' + #name: 'keepLinkedMenu' + #layout: #(#Point 20 288) + #activeHelpKey: #keepLinkedMenu + #tabable: true + #model: #keepLinkedMenu + #translateLabel: true + ) + ) + + ) + ) +! ! + +!MenuEditor::ItemLinkedMenu methodsFor:'accessing'! + +argument:aValue + menuItem argument:aValue. +! + +menuItem + "returns self as a MenuItem + " + |item| + + item := super menuItem. + item submenuChannel:(self submenuChannel). + ^ item +! + +slices + self isDelayedMenu ifTrue:[ + ^ #( + (Basics basicsEditSpec ) + ) ]. - idx := 10000. - self selection do:[:aNumber| idx := idx min:aNumber ]. - - self selectedNodesRemove. - self selection:(idx min:(self list size)). - self setModified. - - aBool ifTrue:[ - "/ must update copy&paste indication - appl updateAllToolInstances. - ] + ^ #( + (Basics basicsEditSpec ) + (Details detailsEditSpec) + (Image image ) + (Help help) + ) +! + +submenuChannel + ^ menuItem submenuChannel ? #unspecified +! + +submenuChannel:aValue + menuItem submenuChannel:aValue. +! ! + +!MenuEditor::ItemLinkedMenu methodsFor:'aspects'! + +aspectAt:aKey put:aValue + "set a specific aspect named aKey to the aValue + " + aKey == #submenuChannel ifTrue:[ ^ self submenuChannel:aValue ]. + super aspectAt:aKey put:aValue. +! + +getDelayedAttributesFrom:aMenuItem + menuItem rawLabel:'Delayed'. + + menuItem submenuChannel:(aMenuItem submenuChannel). + menuItem horizontalLayout:(aMenuItem horizontalLayout). + menuItem keepLinkedMenu:(aMenuItem keepLinkedMenu). ! -doCopy - |clip| - - self hasSelection ifTrue:[ - self application clipboard:(clip := OrderedCollection new). - self selectionDo:[:i | clip add:((listOfNodes at:i) copy)]. - self topView application updateAllToolInstances. - ] +setDelayedAttributesTo:aMenuItem + aMenuItem submenuChannel:(self submenuChannel). + aMenuItem horizontalLayout:(menuItem horizontalLayout). + aMenuItem keepLinkedMenu:(menuItem keepLinkedMenu). +! ! + +!MenuEditor::ItemLinkedMenu methodsFor:'displaying'! + +displayLabel + "returns the label dependent on is delayed or not + " + self isDelayedMenu ifTrue:[ ^ self submenuChannel ]. + ^ menuItem rawLabel ! -doCreateItem - - self addElement: (self nodeLabel:'Item') +icon + self isDelayedMenu ifTrue:[ ^ self class iconDelayedLinkedMenu ]. + ^ self class iconLinkedMenu +! ! + +!MenuEditor::ItemLinkedMenu methodsFor:'queries'! + +isKindOfMenu + ^ true +! ! + +!MenuEditor::ItemMenu class methodsFor:'defaults'! + +defaultDelayedLabel + ^ 'delayed' ! -doCreateLink - - |node item| - - node := self nodeLabel:'Submenu Link'. - item := node contents. - item submenuChannel:#menuDefaultLink. - self addElement:node. - self setModified. - - +defaultLabel + ^ 'Menu' +! ! + +!MenuEditor::ItemMenu class methodsFor:'instance creation'! + +menu:aMenu labeled:aString + |item| + + item := self new. + item menu:aMenu labeled:aString. + ^ item +! ! + +!MenuEditor::ItemMenu class methodsFor:'interface - specs'! + +basicsEditSpec + "This resource specification was automatically generated + by the UIPainter of ST/X." + + "Do not manually edit this!! If it is corrupted, + the UIPainter may not be able to read the specification." + + " + UIPainter new openOnClass:MenuEditor::ItemMenu andSelector:#basicsEditSpec + " + + + + ^ + #(#FullSpec + #name: #basicsEditSpec + #window: + #(#WindowSpec + #label: 'basicsEditSpec' + #name: 'basicsEditSpec' + #min: #(#Point 10 10) + #max: #(#Point 1160 870) + #bounds: #(#Rectangle 810 135 1150 475) + ) + #component: + #(#SpecCollection + #collection: #( + #(#LabelSpec + #label: 'Name Key:' + #name: 'nameKeyLabel' + #layout: #(#AlignmentOrigin 107 0 25 0 1 0.5) + #activeHelpKey: #basicsKey + #visibilityChannel: #notDelayedMenu + #resizeForLabel: true + #adjust: #right + ) + #(#InputFieldSpec + #name: 'nameKeyField' + #layout: #(#LayoutFrame 110 0 15 0 -5 1.0 37 0) + #activeHelpKey: #basicsKey + #visibilityChannel: #notDelayedMenu + #tabable: true + #model: #nameKey + #group: #inputGroup + #type: #symbolOrNil + #immediateAccept: false + #acceptOnLeave: false + #acceptOnReturn: true + #acceptOnTab: true + #acceptOnLostFocus: false + #acceptChannel: #acceptChannel + #modifiedChannel: #modifiedChannel + #acceptOnPointerLeave: false + ) + #(#LabelSpec + #label: 'Label:' + #name: 'labelLabel' + #layout: #(#AlignmentOrigin 107 0 51 0 1 0.5) + #activeHelpKey: #basicsLabel + #visibilityChannel: #notDelayedMenu + #resizeForLabel: true + #adjust: #right + ) + #(#InputFieldSpec + #name: 'labelField' + #layout: #(#LayoutFrame 110 0 40 0 -5 1.0 62 0) + #activeHelpKey: #basicsLabel + #visibilityChannel: #notDelayedMenu + #tabable: true + #model: #rawLabel + #group: #inputGroup + #immediateAccept: false + #acceptOnReturn: true + #acceptOnTab: true + #acceptOnLostFocus: false + #acceptChannel: #acceptChannel + #modifiedChannel: #modifiedChannel + #acceptOnPointerLeave: false + ) + #(#CheckBoxSpec + #label: 'Translate Label' + #name: 'translateLabelCheckBox' + #layout: #(#Point 20 213) + #activeHelpKey: #basicsTranslateLabel + #visibilityChannel: #notDelayedMenu + #tabable: true + #model: #translateLabel + ) + #(#CheckBoxSpec + #label: 'Is Button' + #name: 'isButtonCheckBox' + #layout: #(#Point 20 238) + #activeHelpKey: #basicsIsButton + #visibilityChannel: #notDelayedMenu + #tabable: true + #model: #isButton + ) + #(#CheckBoxSpec + #label: 'Has Horizontal Layout' + #name: 'horizontalLayout' + #layout: #(#Point 20 263) + #activeHelpKey: #horizontalLayout + #tabable: true + #model: #horizontalLayout + ) + ) + + ) + ) +! ! + +!MenuEditor::ItemMenu methodsFor:'accessing'! + +argument:aValue + "/ ignorred. ! -doCreateMenu - |node| - - node := self nodeLabel:'Submenu'. - node parent: self selectedNode. - node add:(self nodeLabel:'Item 1'). - self addElement:node +menu:aMenu labeled:aString + |expanded item menu| + + self criticalDo:[ + self isRootItem ifTrue:[ expanded := true ] + ifFalse:[ expanded := isExpanded ]. + + self removeAll. + self rawLabel:aString. + + aMenu ifNotNil:[ + aMenu isCollection ifTrue:[ menu := Menu new fromLiteralArrayEncoding:aMenu ] + ifFalse:[ menu := aMenu ]. + + menu numberOfItems == 0 ifTrue:[ + menu := nil + ]. + ]. + menu ifNotNil:[ + isExpanded := false. "/ discard change notifications + children := OrderedCollection new. + + menu itemsDo:[:el| + item := self class menuItem:el. + item parent:self. + children add:item. + ]. + expanded ifTrue:[ self expand ]. + ]. + isExpanded := expanded. + ]. + self changed ! -doCreateSep - - self addElement:(self nodeLabel:nil) +menuItem + "returns self as a MenuItem + " + |item| + + item := super menuItem. + item submenu:(self submenu). + ^ item ! -doCreateStandardEditMenu - - |node| - node := self nodeLabel:'Edit'. - node parent: self selectedNode. - node add:(self nodeLabel:'Copy' selector:#copySelection). - node add:(self nodeLabel:'Cut' selector:#cutSelection). - node add:(self nodeLabel:'Paste' selector:#paste). - self addElement:node - - "Created: / 23.8.1998 / 15:52:16 / cg" - "Modified: / 23.8.1998 / 15:59:36 / cg" +menuItem:anItem + + super menuItem:anItem. + self menu:(anItem submenu) labeled:nil. +! + +slices + self isDelayedMenu ifTrue:[ + ^ #( + (Basics basicsEditSpec ) + ) + ]. + + ^ #( + (Basics basicsEditSpec ) + (Details detailsEditSpec) + (Image image ) + (Help help) + ) +! + +submenu + |menu| + + menu := Menu new. + + children size ~~ 0 ifTrue:[ + children do:[:el| menu addItem:(el menuItem) ]. + ]. + ^ menu +! ! + +!MenuEditor::ItemMenu methodsFor:'aspects'! + +getDelayedAttributesFrom:aMenuItem + + self menu:(aMenuItem submenu) labeled:nil. + menuItem horizontalLayout:(aMenuItem horizontalLayout). +! + +setDelayedAttributesTo:aMenuItem + aMenuItem submenu:(self submenu). + aMenuItem horizontalLayout:(menuItem horizontalLayout). +! ! + +!MenuEditor::ItemMenu methodsFor:'displaying'! + +displayLabel + "returns the label dependent on is delayed or not + " + self isDelayedMenu ifTrue:[ ^ self class defaultDelayedLabel ]. + ^ menuItem rawLabel +! + +icon + self isDelayedMenu ifTrue:[ ^ self class iconDelayedMenu ]. + ^ self class iconMenu +! ! + +!MenuEditor::ItemMenu methodsFor:'queries'! + +canAddChildren + "children can be added + " + ^ true +! + +canExpand + "returns true if the item is expandable + " + ^ isExpanded == false +! + +hasIndicator + ^ true ! -doCreateStandardFileMenu - - |node| - node := self nodeLabel:'File'. - node parent: self selectedNode. - node add:(self nodeLabel:'New' selector:#menuNew). - node add:(self nodeLabel:'-' ). - node add:(self nodeLabel:'Open...' selector:#menuOpen). - node add:(self nodeLabel:'-' ). - node add:(self nodeLabel:'Save' selector:#menuSave). - node add:(self nodeLabel:'Save As...' selector:#menuSaveAs). - node add:(self nodeLabel:'-' ). - node add:(self nodeLabel:'Exit' selector:#closeRequest). - self addElement:node - - "Created: / 23.8.1998 / 15:51:55 / cg" - "Modified: / 23.8.1998 / 16:04:24 / cg" +isKindOfMenu + ^ true +! ! + +!MenuEditor::ItemRoot class methodsFor:'defaults'! + +defaultLabel + ^ MenuEditor resourceType +! ! + +!MenuEditor::ItemRoot class methodsFor:'interface - editor'! + +addBindingsTo:aspects for:aMenuEditor + "add additional bindings to the aspects + " +! ! + +!MenuEditor::ItemRoot class methodsFor:'interface - specs'! + +basicsEditSpec + "This resource specification was automatically generated + by the UIPainter of ST/X." + + "Do not manually edit this!! If it is corrupted, + the UIPainter may not be able to read the specification." + + " + UIPainter new openOnClass:MenuEditor::ItemRoot andSelector:#basicsEditSpec + " + + + + ^ + #(#FullSpec + #name: #basicsEditSpec + #window: + #(#WindowSpec + #label: 'basicsEditSpec' + #name: 'basicsEditSpec' + #min: #(#Point 10 10) + #max: #(#Point 1280 1024) + #bounds: #(#Rectangle 644 547 904 593) + ) + #component: + #(#SpecCollection + #collection: #( + #(#LabelSpec + #label: 'Selector:' + #name: 'selectorLabel' + #layout: #(#AlignmentOrigin 107 0 26 0 1 0.5) + #activeHelpKey: #basicsSelector + #resizeForLabel: true + #adjust: #right + ) + #(#InputFieldSpec + #name: 'selectorField' + #layout: #(#LayoutFrame 110 0 15 0 -5 1.0 37 0) + #activeHelpKey: #basicsSelector + #tabable: true + #model: #rawLabel + #group: #inputGroup + #type: #string + #immediateAccept: false + #acceptOnReturn: true + #acceptOnTab: true + #acceptChannel: #acceptChannel + #modifiedChannel: #modifiedChannel + #acceptOnPointerLeave: false + ) + ) + + ) + ) +! ! + +!MenuEditor::ItemRoot methodsFor:'accessing'! + +menuItem:aMenuItem + "rebuild self from a MenuItem + " + |submenu selector| + + aMenuItem notNil ifTrue:[ + submenu := aMenuItem submenu. + selector := aMenuItem rawLabel. + ] ifFalse:[ + selector := submenu := nil. + ]. + self menu:submenu labeled:selector. ! -doCreateStandardHelpMenu - - |node| - node := self nodeLabel:'Help'. - node parent: self selectedNode. - node contents startGroup:#right. - node add:(self nodeLabel:'Documentation' selector:#openDocumentation). - node add:(self nodeLabel:'-'). - node add:(self nodeLabel:'About this Application' selector:#openAboutThisApplication). - self addElement:node - - "Created: / 23.8.1998 / 15:52:46 / cg" - "Modified: / 23.8.1998 / 17:30:12 / cg" -! - -doCut - ^ self doDeleteSelectionBuffered:true +rawLabel:aValue + "set the label assigned to the item + " + |value| + + aValue isString ifTrue:[ + value := aValue withoutSeparators. + + (value notEmpty and:[value first isLetter]) ifTrue:[ + menuItem rawLabel:(value asSymbol) + ]. + ]. ! -doDelete - ^ self doDeleteSelectionBuffered:false +slices + ^ #( + (Basics basicsEditSpec) + ) +! ! + +!MenuEditor::ItemRoot methodsFor:'adding & removing'! + +remove + "cannot remove the root item; delete all my children + " + self removeAll. +! ! + +!MenuEditor::ItemRoot methodsFor:'aspects'! + +aspectAt:aKey put:aValue + "discard all other than the rawLabel + " + aKey == #rawLabel ifTrue:[ self rawLabel:aValue ]. +! ! + +!MenuEditor::ItemRoot methodsFor:'displaying'! + +heightOn:aGC + height ifNil:[ height := aGC font heightOn:aGC device ]. + ^ height +! ! + +!MenuEditor::ItemRoot methodsFor:'initialization'! + +initialize + super initialize. + isExpanded := true. +! ! + +!MenuEditor::ItemRoot methodsFor:'queries'! + +canCollapse + ^ false ! -doDeleteSelectionBuffered:aBool - |appl nsel list item prnt| - - appl := self topView application. - - (appl hasValidSelection value and: [self askForItemModification]) ifFalse:[ - ^ self +hasIndicator + ^ false +! + +isDelayedMenu + ^ false +! + +isRootItem + ^ true +! ! + +!MenuEditor::ItemRoot methodsFor:'queries - operation'! + +canMoveInAbove + ^ false +! + +canMoveInNext + ^ false +! + +canMoveOut + ^ false +! + +canMoveUpOrDown + ^ false +! ! + +!MenuEditor::ItemSeparator class methodsFor:'interface - editor'! + +addBindingsTo:aspects for:aMenuEditor + "add additional bindings to the aspects + " + |holder| + + aspects at:#seperatorList ifAbsentPut:[ + self separatorSlices collect:[:el| el last ] ]. - aBool ifTrue:[ - self doCopy + + aspects at:#seperatorSelection ifAbsentPut:[ + holder := 0 asValue. + holder addDependent:aMenuEditor. + holder ]. - list := self list. - nsel := list size. - self selection do:[:aNumber| nsel := nsel min:aNumber ]. - - ( (item := list at:nsel ifAbsent:nil) notNil - and:[(prnt := item parent) notNil - and:[prnt children last == item]] - ) ifTrue:[ - nsel := nsel - 1 +! + +defaultLabel + ^ '-' +! + +separatorSlices + "get the list of menu spec values of the corresponding separator types + " + ^ #( + ( #blank '' 'blank' ) + ( #single '-' 'single line') + ( #double '=' 'double line') + ) +! ! + +!MenuEditor::ItemSeparator class methodsFor:'interface - specs'! + +basicsEditSpec + "This resource specification was automatically generated + by the UIPainter of ST/X." + + "Do not manually edit this!! If it is corrupted, + the UIPainter may not be able to read the specification." + + " + UIPainter new openOnClass:MenuEditor::ItemSeparator andSelector:#basicsEditSpec + " + + + + ^ + #(#FullSpec + #name: #basicsEditSpec + #window: + #(#WindowSpec + #label: 'basicsEditSpec' + #name: 'basicsEditSpec' + #min: #(#Point 10 10) + #max: #(#Point 1160 870) + #bounds: #(#Rectangle 160 398 420 643) + ) + #component: + #(#SpecCollection + #collection: #( + #(#LabelSpec + #label: 'Separator:' + #name: 'separatorLabel' + #layout: #(#AlignmentOrigin 107 0 26 0 1 0.5) + #resizeForLabel: true + #adjust: #right + ) + #(#ComboListSpec + #name: 'seperatorList' + #layout: #(#LayoutFrame 110 0 15 0 -5 1.0 37 0) + #activeHelpKey: #basicsSeparatorType + #tabable: true + #model: #seperatorSelection + #comboList: #seperatorList + #useIndex: true + ) + #(#LabelSpec + #label: 'Visibility:' + #name: 'visibilityLabel' + #layout: #(#AlignmentOrigin 107 0 51 0 1 0.5) + #resizeForLabel: true + #adjust: #right + ) + #(#InputFieldSpec + #name: 'visibilityInputField' + #layout: #(#LayoutFrame 110 0 40 0 -5 1.0 62 0) + #activeHelpKey: #detailsVisibility + #tabable: true + #model: #isVisible + #group: #inputGroup + #type: #symbolOrNil + #immediateAccept: false + #acceptOnReturn: true + #acceptOnTab: true + #acceptChannel: #acceptChannel + #modifiedChannel: #modifiedChannel + #acceptOnPointerLeave: false + ) + #(#LabelSpec + #label: 'Start Group:' + #name: 'startGroupLabel' + #layout: #(#AlignmentOrigin 107 0 88 0 1 0.5) + #resizeForLabel: true + #adjust: #right + ) + #(#PopUpListSpec + #label: 'left' + #name: 'startGroupPopUp' + #layout: #(#LayoutFrame 110 0 77 0 -5 1.0 99 0) + #activeHelpKey: #detailsStartGroup + #tabable: true + #model: #startGroup + #menu: + #(#left + #right + ) + ) + ) + + ) + ) +! ! + +!MenuEditor::ItemSeparator methodsFor:'accessing'! + +icon + ^ self class iconSeparator +! + +rawLabel:aValue + |value| + + aValue isString ifTrue:[ + value := aValue withoutSeparators. + + (self class separatorTypeOf:value) ifNotNil:[ + menuItem rawLabel:value + ] ]. - - self selectedNodesRemove. - self selection:(nsel min:(list size)). - self setModified. - - aBool ifTrue:[ - "/ must update copy&paste indication - appl updateAllToolInstances. - ] +! + +separatorType + ^ self class separatorTypeOf:(menuItem rawLabel). +! + +slices + ^ #( + (Basics basicsEditSpec) + ) +! ! + +!MenuEditor::ItemSeparator methodsFor:'aspects'! + +fromAspects:aspects + "put my values into the values of aspects + " + |index slice| + + index := (aspects at:#seperatorSelection) value ? 0. + slice := self class separatorSlices at:index ifAbsent:nil. + + slice ifNotNil:[ slice := slice at:2 ]. + + (aspects at:#rawLabel) value:slice. + ^ super fromAspects:aspects. ! -doPaste - |clip| - - clip := self application clipboard. - (clip notNil and:[self selectedNode notNil]) ifTrue:[ - self addElement:(clip collect:[:el| el copy]) +toAspects:aspects + "put my values into the values of aspects + " + |index type| + + type := self separatorType. + index := self class separatorSlices findFirst:[:el| el first == type ]. + + (aspects at:#seperatorSelection) value:index. + ^ super toAspects:aspects. +! ! + +!MenuEditor::ItemSeparator methodsFor:'displaying'! + +displayOn:aGC x:x y:y h:h + "draw the receiver in the graphicsContext, aGC. + " + |x1 y0 type| + + type := self separatorType. + type == #blank ifTrue:[ ^ self ]. + + x1 := x + (self widthOn:aGC). + y0 := y + (h // 2) - 1. + + type == #double ifTrue:[ + y0 := y0 + 1. + aGC displayLineFromX:x y:y0 toX:x1 y:y0. + y0 := y0 - 2 ]. + aGC displayLineFromX:x y:y0 toX:x1 y:y0 +! + +widthOn:aGC + width ifNil:[ width := 60 ]. + ^ width ! ! -!MenuEditor::TreeView methodsFor:'private'! - -addElement: aNode - "add something after selection" - - |label sel selParent| - - self askForItemModification ifFalse:[^ self]. - - self selectedNodeAdd:aNode. - (aNode isCollection not and:[aNode name = 'Item']) - ifTrue:[ - sel := self selectedNode. - selParent := sel parent. - label := aNode name - , - ' ' - , - (selParent notNil - ifTrue:[ - (((sel children size = 0 - ifTrue: [selParent children] - ifFalse: [sel children]) - select:[:node| - |lab| - lab := node contents label. - ((node children size = 0) & - node contents submenuChannel isNil & - (lab ~= '-') & (lab ~= '=') & (lab ~= '')) - ]) size) printString - ] - ifFalse: ['1']). - - aNode name: label string asBoldText. - aNode contents label: label string. - ]. - aNode isCollection ifFalse: [ - self selectNode: aNode - ] ifTrue: [ - self selection: (aNode collect: [:node| self indexOfNode: node]) +!MenuEditor::ResourceEditor class methodsFor:'interface specs'! + +windowSpec + "This resource specification was automatically generated + by the UIPainter of ST/X." + + "Do not manually edit this!! If it is corrupted, + the UIPainter may not be able to read the specification." + + " + UIPainter new openOnClass:MenuEditor::ResourceEditor andSelector:#windowSpec + MenuEditor::ResourceEditor new openInterface:#windowSpec + MenuEditor::ResourceEditor open + " + + + + ^ + #(#FullSpec + #name: #windowSpec + #window: + #(#WindowSpec + #label: 'Image Item' + #name: 'Image Item' + #min: #(#Point 10 10) + #max: #(#Point 1280 1024) + #bounds: #(#Rectangle 333 290 621 585) + ) + #component: + #(#SpecCollection + #collection: #( + #(#LabelSpec + #label: 'Retriever:' + #name: 'retrieverLabel' + #layout: #(#AlignmentOrigin 107 0 26 0 1 0.5) + #activeHelpKey: #imageRetriever + #resizeForLabel: true + #adjust: #right + ) + #(#ComboBoxSpec + #name: 'retrieverHolder' + #layout: #(#LayoutFrame 110 0 15 0 -20 1.0 37 0) + #activeHelpKey: #imageRetriever + #tabable: true + #model: #retrieverHolder + #type: #symbolOrNil + #immediateAccept: true + #acceptOnReturn: false + #acceptOnTab: false + #acceptOnPointerLeave: false + #comboList: #retrieverList + #isFilenameBox: false + ) + #(#LabelSpec + #label: 'Selector:' + #name: 'iconLabel' + #layout: #(#AlignmentOrigin 107 0 51 0 1 0.5) + #activeHelpKey: #imageSelector + #resizeForLabel: true + #adjust: #right + ) + #(#InputFieldSpec + #name: 'selectorHolder' + #layout: #(#LayoutFrame 110 0 40 0 -42 1.0 62 0) + #activeHelpKey: #imageSelector + #tabable: true + #model: #selectorHolder + #group: #inputGroup + #type: #symbolOrNil + #immediateAccept: true + #acceptOnReturn: false + #acceptOnTab: false + #modifiedChannel: #modifiedChannel + #acceptOnPointerLeave: false + ) + #(#ActionButtonSpec + #label: '...' + #name: 'browseButton' + #layout: #(#LayoutFrame -40 1 40 0 -20 1 62 0) + #activeHelpKey: #browseResource + #tabable: true + #model: #doBrowseForImageResource + ) + #(#HierarchicalListViewSpec + #name: 'imageList' + #layout: #(#LayoutFrame 20 0.0 67 0 -20 1.0 -30 1.0) + #activeHelpKey: #imageImageList + #model: #imageHolder + #menu: #menuEditImage + #hasHorizontalScrollBar: true + #hasVerticalScrollBar: true + #miniScrollerHorizontal: true + #listModel: #imageList + #useIndex: false + #highlightMode: #label + #postBuildCallback: #postBuildImageViewer: + ) + #(#ViewSpec + #name: 'Box1' + #layout: #(#LayoutFrame 20 0.0 -30 1.0 -20 1.0 0 1.0) + #level: 0 + #component: + #(#SpecCollection + #collection: #( + #(#CheckBoxSpec + #label: 'Image & Label' + #name: 'iconAndLabelCheckBox' + #layout: #(#AlignmentOrigin 0 0 0 0.5 0 0.5) + #activeHelpKey: #imageImageAndLabel + #tabable: true + #model: #iconAndLabelHolder + ) + #(#ActionButtonSpec + #label: 'Image Editor' + #name: 'imageEditorButton' + #layout: #(#AlignmentOrigin 0 1.0 0 0.5 1 0.5) + #activeHelpKey: #imageImageEditor + #tabable: true + #model: #doEditImage + ) + ) + + ) + ) + ) + + ) + ) +! ! + +!MenuEditor::ResourceEditor methodsFor:'accessing'! + +resourceRetriever + |rcv sel cls| + + sel := selectorHolder value. + sel size == 0 ifTrue:[ ^ nil ]. + cls := self retrieverClass. + cls ifNotNil:[ cls := cls name asSymbol ]. + + rcv := ResourceRetriever new. + rcv className:cls. + rcv selector:sel. + + iconAndLabelHolder value ifTrue:[ rcv labelText:'' ]. + ^ rcv +! + +resourceRetriever:aResourceRetriever + |cls sel isOn| + + aResourceRetriever notNil ifTrue:[ + cls := aResourceRetriever className. + cls ifNotNil:[ + cls isBehavior ifTrue:[cls := cls name asSymbol]. + ]. + sel := aResourceRetriever selector. + isOn := aResourceRetriever labelText notNil. + ] ifFalse:[ + cls := sel := nil. + isOn := false. ]. - self setModified. + + retrieverHolder value:cls. + selectorHolder value:sel. + iconAndLabelHolder value:isOn. +! + +retrieverClass + |cls| + + cls := retrieverHolder value. + + cls size ~~ 0 ifTrue:[ + cls := Smalltalk at:cls ifAbsent:nil. + + (cls notNil and:[cls isBehavior]) ifTrue:[ + ^ cls + ]. + ]. + ^ nil +! ! + +!MenuEditor::ResourceEditor methodsFor:'actions'! + +doBrowseForImageResource + "opens a browser on image-resource methods" + + |msg| + + msg := ResourceSelectionBrowser + request:'Use Image From Class' + onSuperclass:nil + andClass:(self retrieverClass) + andSelector:(selectorHolder value) + withResourceTypes:#(image fileImage programImage). + + msg ifNil:[ ^ self ]. + msg := msg asCollectionOfWords. + msg size == 2 ifFalse:[ ^ self ]. + + retrieverHolder value:(msg first asSymbol). + selectorHolder value:(msg last asSymbol). +! + +doEditImage + |item| + + item := imageHolder value. + item ifNotNil:[ item doEdit ]. +! ! + +!MenuEditor::ResourceEditor methodsFor:'aspects'! + +iconAndLabelHolder + ^ iconAndLabelHolder +! + +imageHolder + ^ imageHolder. ! -askForItemModification - - ^self topView application askForItemModification +imageList + ^ imageList. +! + +modifiedChannel + ^ builder booleanValueAspectFor: #modifiedChannel +! + +modifiedChannel:aChannel + builder aspectAt:#modifiedChannel put:aChannel. +! + +retrieverHolder + ^ retrieverHolder +! + +retrieverList + |list| + + list := builder bindingAt:#retrieverList. + + list ifNil:[ + list := MenuEditor imageRetrieverClasses asList. + builder aspectAt:#retrieverList put:list. + ]. + ^ list ! -nodeLabel:aLabel - - ^TreeItem new contents: ((MenuEditor::Item new label:aLabel) translateLabel:true) - - "Modified: / 6.6.1998 / 17:22:35 / cg" +selectorHolder + ^ selectorHolder. +! ! + +!MenuEditor::ResourceEditor methodsFor:'change & update'! + +retrieverChanged + "called if the retriever changed + " + |retriever list name| + + retriever := self retrieverClass. + imageHolder setValue:nil. + + imageList root fromClass:retriever. + self selectorChanged. + + (retriever notNil and:[imageList size ~~ 0]) ifTrue:[ + list := self retrieverList. + name := retriever name. + + (list includes:name) ifFalse:[ + list add:(name asSymbol). + ] + ]. ! -nodeLabel:aLabel selector:aSelector - - ^TreeItem new contents: (((MenuEditor::Item new label:aLabel) value:aSelector) translateLabel:true) - - "Modified: / 6.6.1998 / 17:22:35 / cg" - "Created: / 23.8.1998 / 15:58:59 / cg" +selectorChanged + |item selector line| + + imageList isEmpty ifTrue:[^ self]. + + selector := selectorHolder value. + selector size == 0 ifTrue:[ ^ imageHolder value:nil ]. + + item := nil. + selector := selector asSymbol. + + imageList do:[:anItem| |sel| + sel := anItem selector. + selector == sel ifTrue:[ + ^ imageHolder value:anItem + ]. + item ifNil:[ + (sel startsWith:selector) ifTrue:[ item := anItem ] + ] + ]. + imageHolder value:nil. + + item ifNotNil:[ + line := imageList identityIndexOf:item. + imageViewer scrollToLine:line + ]. ! -selectedNodeAdd:something - - |node numChildren| - - something notNil ifTrue:[ - (node := self selectedNode) notNil ifTrue:[ - numChildren := node children size. - - node parent notNil ifTrue:[ - node isCollapsable ifTrue:[ - model add:something afterIndex:numChildren below:node - ] ifFalse:[ - model add:something after:node - ] - ] ifFalse:[ - model add:something afterIndex:numChildren below:(self root) - ] - ] - ] - - +update:what with:aPara from:aModel + "Invoked when an object that I depend upon sends a change notification." + + |item| + + self modifiedChannel value:true. + + aModel == retrieverHolder ifTrue:[ ^ self retrieverChanged ]. + aModel == selectorHolder ifTrue:[ ^ self selectorChanged ]. + + aModel == imageHolder ifTrue:[ + item := imageHolder value. + item ifNotNil:[ selectorHolder value:(item label) ]. + ^ self + ]. + super update:what with:aPara from:aModel +! ! + +!MenuEditor::ResourceEditor methodsFor:'initialization'! + +initialize + super initialize. + + iconAndLabelHolder := true asValue. + iconAndLabelHolder addDependent:self. + + imageHolder := nil asValue. + + selectorHolder := nil asValue. + selectorHolder addDependent:self. + + imageList := HierarchicalList new. + imageList application:self. + imageList root:(MenuEditor::ResourceEditorItem new). + imageList showRoot:false. + + imageHolder := nil asValue. + imageHolder addDependent:self. + + retrieverHolder := nil asValue. + retrieverHolder addDependent:self. +! + +postBuildImageViewer:aWidget + imageViewer := aWidget. +! ! + +!MenuEditor::ResourceEditorItem class methodsFor:'instance creation'! + +fromClass:aClass selector:aSelector + |item| + + item := self new. + item fromClass:aClass selector:aSelector. + ^ item +! ! + +!MenuEditor::ResourceEditorItem methodsFor:'accessing'! + +icon + ^ icon +! + +label + ^ selector ! -setModified - |app| - - (app := self topView application) modified: true. - app updateChannels +selector + ^ selector +! ! + +!MenuEditor::ResourceEditorItem methodsFor:'instance creation'! + +fromClass:aClass + |r item| + + (aClass notNil and:[aClass isBehavior]) ifFalse:[ + ^ self collapse. + ]. + aClass == selector ifTrue:[ + ^ self expand + ]. + self collapse. + + selector := aClass. + children := SortedCollection sortBlock:[:a :b| a label < b label ]. + + self application withWaitCursorDo:[ + aClass withAllSuperclassesDo:[:aClass| + aClass class selectorsAndMethodsDo:[:sel :m| + ((r := m resourceType) == #image or:[r == #programImage]) ifTrue:[ + item := self class fromClass:aClass selector:sel. + item parent:self. + children add:item + ] + ] + ]. + self expand + ]. +! + +fromClass:aClass selector:aSelector + |w h magnify| + + selector := aSelector asSymbol. + icon := aClass perform:selector. + + w := icon width. + h := icon height. + + w > 32 ifTrue:[ + magnify := 32 / w. + h > 32 ifTrue:[ magnify := (32 / h) max:magnify ]. + ] ifFalse:[ + h > 32 ifFalse:[^ self]. + magnify := 32 / h. + ]. + icon := icon magnifiedBy: magnify. +! + +initialize + super initialize. + children := #(). +! ! + +!MenuEditor::ResourceEditorItem methodsFor:'user operations'! + +doEdit + "open image browser on self + " + |parent| + + parent := self parent. + + parent ifNotNil:[ + ImageEditor openOnClass:(parent selector) andSelector:selector + ]. ! ! !MenuEditor class methodsFor:'documentation'! @@ -3684,4 +4618,5 @@ version ^ '$Header$' ! ! + MenuEditor initialize!