cg@3582: "{ Encoding: utf8 }" cg@3582: ca@199: " tz@738: COPYRIGHT (c) 1997 by eXept Software AG ca@1606: All Rights Reserved ca@199: ca@199: This software is furnished under a license and may be used ca@199: only in accordance with the terms of that license and with the tz@738: inclusion of the above copyright notice. This software may not ca@199: be provided or otherwise made available to, or used by, any ca@199: other person. No title to or ownership of the software is ca@199: hereby transferred. ca@199: " cg@1372: "{ Package: 'stx:libtool2' }" cg@1372: cg@3178: "{ NameSpace: Smalltalk }" cg@3178: tz@738: ResourceSpecEditor subclass:#MenuEditor ca@1606: instanceVariableNames:'selectionHolder tabHolder listOfItems listOfTabs ca@1618: selectedSuperItems notifyDisabledCounter wizards listOfItemsView cg@2569: dropOverLine savedSpec' ca@1462: classVariableNames:'ImageRetrieverClasses' ca@220: poolDictionaries:'' ca@220: category:'Interface-UIPainter' ca@199: ! ca@199: ca@1606: HierarchicalItem subclass:#Item ca@1606: instanceVariableNames:'menuItem' ca@1606: classVariableNames:'' ca@1606: poolDictionaries:'' ca@1606: privateIn:MenuEditor ca@1606: ! ca@1606: cg@2850: ApplicationModel subclass:#ImageResourceEditor cg@2850: instanceVariableNames:'selectorHolder iconAndLabelHolder retrieverHolder imageHolder cg@2850: imageList selectorFilterHolder imageListView' cg@2850: classVariableNames:'' cg@2850: poolDictionaries:'' cg@2850: privateIn:MenuEditor cg@2850: ! cg@2850: cg@2850: HierarchicalItem subclass:#ImageResourceEditorItem cg@2850: instanceVariableNames:'selector icon' cg@2850: classVariableNames:'' cg@2850: poolDictionaries:'' cg@2850: privateIn:MenuEditor::ImageResourceEditor cg@2850: ! cg@2850: cg@1631: MenuEditor::Item subclass:#ActionItem ca@1606: instanceVariableNames:'' cg@1407: classVariableNames:'' cg@1407: poolDictionaries:'' cg@1407: privateIn:MenuEditor cg@1407: ! cg@1407: cg@1631: MenuEditor::Item subclass:#LinkedMenuItem ca@1606: instanceVariableNames:'' ca@1606: classVariableNames:'' ca@1606: poolDictionaries:'' ca@1606: privateIn:MenuEditor ca@1606: ! ca@1606: ca@1844: MenuEditor::Item subclass:#MenuSliceItem ca@1844: instanceVariableNames:'' ca@1844: classVariableNames:'' ca@1844: poolDictionaries:'' ca@1844: privateIn:MenuEditor ca@1844: ! ca@1844: ca@1633: MenuEditor::Item subclass:#RegularMenuItem sv@1454: instanceVariableNames:'' sv@1454: classVariableNames:'' sv@1454: poolDictionaries:'' sv@1454: privateIn:MenuEditor sv@1454: ! sv@1454: ca@1633: MenuEditor::RegularMenuItem subclass:#RootItem cg@1631: instanceVariableNames:'' cg@1631: classVariableNames:'' cg@1631: poolDictionaries:'' cg@1631: privateIn:MenuEditor cg@1631: ! cg@1631: cg@1631: MenuEditor::Item subclass:#SeparatorItem cg@1631: instanceVariableNames:'' cg@1631: classVariableNames:'' cg@1631: poolDictionaries:'' cg@1631: privateIn:MenuEditor cg@1631: ! cg@1631: ca@199: !MenuEditor class methodsFor:'documentation'! ca@199: ca@199: copyright ca@199: " tz@738: COPYRIGHT (c) 1997 by eXept Software AG ca@1606: All Rights Reserved ca@199: ca@199: This software is furnished under a license and may be used ca@199: only in accordance with the terms of that license and with the tz@738: inclusion of the above copyright notice. This software may not ca@199: be provided or otherwise made available to, or used by, any ca@199: other person. No title to or ownership of the software is ca@199: hereby transferred. ca@199: " ca@199: ! ca@199: ca@199: documentation ca@199: " tz@728: The MenuEditor allows you to create, modify or just inspect cg@2936: menu specifications. Such specifications are returned by menu-spec methods cg@2936: of the application class. These methods are typically tagged with a menu-resource. cg@2936: The menu editor is able to retrieve such specifications and generate new menu-spec cg@2936: methods. cg@2936: cg@2936: The editor is typically opened by double-clicking on a menu-spec method in the browser. ca@1606: ca@1606: [Instance variables:] ca@1606: cg@3013: listOfItemsView the view which shows the list of items cg@3013: listOfItems hierarchical list of menu items cg@3013: listOfTabs list of current shown tab-labels cg@3013: cg@3013: selectionHolder collection of current selected items cg@3013: selectedSuperItems collection of superItems derived from selection cg@3013: cg@3013: tabHolder selected tab label holder cg@3013: notifyDisabledCounter ~~ 0 than change notifications are discard cg@3013: wizards keeps all created wizard dialogs cg@3013: cg@3013: dropOverLine nil: drop context not dropabel. cg@3013: = 0: drop context dropable but no item specified cg@3013: ~ 0: drop context dropable for item at lineNumber cg@3013: used t6o restore drop indication drawings cg@2188: ca@1606: [Class variables:] cg@3013: ImageRetrieverClasses sorted collection of image receivers ca@199: ca@199: [start with:] cg@3013: MenuEditor open cg@3013: MenuEditor openOnClass:MenuEditor andSelector:#menu ca@199: ca@199: [author:] cg@3013: Claus Atzkern, eXept Software AG cg@3013: Thomas Zwick, eXept Software AG ca@199: " ca@199: ! ! ca@199: ca@1462: !MenuEditor class methodsFor:'initialization'! ca@1462: ca@1462: initialize cg@2188: ImageRetrieverClasses := #( ca@1606: Icon cg@2188: SystemBrowser ca@1606: ToolbarIconLibrary cg@2188: ). cg@1546: cg@1546: " cg@1546: self initialize cg@1546: " ca@1462: ! ! ca@1462: tz@508: !MenuEditor class methodsFor:'instance creation'! tz@508: tz@728: openModalOnMenu: aMenu ca@1606: "Open a MenuEditor modal on aMenu ca@1606: self openModalOnMenu: (self perform: #menu) decodeAsLiteralArray tz@734: " ca@1606: ^self new openModalOnMenu:aMenu tz@633: ! ! tz@633: ca@1462: !MenuEditor class methodsFor:'accessing image retriever'! ca@1462: ca@1462: addNewImageRetriever:aSymbolOrClass cg@1546: "add a class to the imageRetriever list" cg@1546: ca@1462: |key| ca@1462: cg@1546: aSymbolOrClass isBehavior ifTrue:[ ca@1606: key := aSymbolOrClass nameWithNameSpacePrefix cg@1546: ] ifFalse:[ ca@1606: key := aSymbolOrClass ca@1462: ]. ca@1463: ca@1462: key size ~~ 0 ifTrue:[ ca@1606: key := key asSymbol. ca@1606: ca@1606: (ImageRetrieverClasses includes:key) ifFalse:[ ca@1606: ImageRetrieverClasses := ImageRetrieverClasses asOrderedCollection. ca@1606: ImageRetrieverClasses add:key. ca@1606: ImageRetrieverClasses sort. ca@1606: ] ca@1462: ]. ca@1462: ! ca@1462: ca@1462: imageRetrieverClasses ca@1462: "returns a collection of image retrievers ca@1462: " ca@1462: ^ ImageRetrieverClasses ca@1462: ! ! ca@1462: tz@633: !MenuEditor class methodsFor:'aspects'! tz@633: tz@633: aspects tz@728: "get the aspects for the attributes of the menu components" tz@728: tz@728: ^#( cg@3587: rawLabel cg@3587: accessCharacterPosition cg@3587: showBusyCursorWhilePerforming cg@3587: horizontalLayout cg@3587: triggerOnDown cg@3587: font cg@3587: argument cg@3587: submenuChannel cg@3587: keepLinkedMenu cg@3587: enabled cg@3587: itemValue cg@3587: nameKey cg@3587: indication cg@3587: choice cg@3587: choiceValue cg@3587: translateLabel cg@3587: isButton cg@3587: shortcutKeyCharacter cg@3587: startGroup cg@3587: isVisible cg@3587: hideMenuOnActivated cg@3587: auxValue cg@3587: activeHelpKey cg@3587: resourceRetriever cg@3587: sendToOriginator cg@3587: ignoreMnemonicKeys cg@3587: ignoreShortcutKeys cg@3587: isMenuSlice cg@3587: hasMenuIndicator tz@633: ) cg@3587: cg@3587: "Modified: / 09-08-2018 / 17:03:56 / Claus Gittinger" ca@1606: ! ! ca@1606: ca@1606: !MenuEditor class methodsFor:'defaults'! ca@1606: ca@1606: resourceType ca@1606: "get the type of the resource of the method generated by the MenuEditor ca@1606: " ca@1606: ^ #menu tz@633: ! ! tz@633: ca@371: !MenuEditor class methodsFor:'help specs'! ca@371: ca@371: helpSpec cg@3587: ^super helpSpec addPairsFrom: #( cg@2850: cg@2850: #editCut cg@2850: 'Cut Item' cg@2850: cg@2850: #editCopy cg@2850: 'Copy Item' cg@2850: cg@2850: #editPaste cg@2850: 'Paste Item' cg@2850: cg@2850: #fileSaveSpec cg@2850: 'Save Menuspec' cg@2850: cg@2850: #addMenuSlice cg@2850: 'Add Menuslice' cg@1690: cg@1690: #addDelayedMenu cg@1690: 'Add a new delayed menu to item.' cg@1690: cg@1690: #addDelayedSubMenuLink cg@1690: 'Add a new linked delayed menu to item.' cg@1690: cg@1690: #addMenuItem cg@1690: 'Add a new menu item.' cg@1690: cg@1690: #addMenuSeparator cg@1690: 'Add a new menu separator.' cg@1690: ca@1844: #addMenuSliceItem ca@1844: 'Add a new menu slice.' ca@1844: cg@1690: #addSubMenu cg@1690: 'Add a new sub menu.' cg@1690: cg@1690: #addSubMenuLink cg@1690: 'Add a new linked sub menu.' cg@1690: cg@1690: #basicsAction cg@1690: 'An action selector with 0, 1 (the argument field), or 2 (the selected item) arguments.' cg@1690: cg@2810: #browseMethod cg@2810: 'Open a browser on this method in the application. Create the method, if it does not exist.' cg@2810: cg@1690: #basicsArgument cg@1690: 'An optional arg passed with above selector, if it is a 1 or 2 arg selector (enter a Smalltalk literal).' cg@1690: cg@1690: #basicsChoice cg@1690: 'Aspect for a boolean holder, block or method, specifying the choices state (RadioButton behavior).' cg@1690: cg@1690: #basicsChoiceValue cg@1690: 'That choices value (typically number or symbol).' cg@1690: cg@1690: #basicsIndication cg@1690: 'Aspect for boolean holder, block, or method, specifying the indication state (CheckToggle behavior).' cg@1690: cg@1690: #basicsIsButton cg@1690: 'Button-like look and behavior.' cg@1690: cg@1690: #basicsKey cg@1690: 'Internal key of the item (optional, for programmed accesses).' cg@1690: cg@1690: #basicsLabel cg@1690: 'Label of the item.' cg@1690: cg@1690: #basicsMenu cg@1690: 'Aspect providing the sub menu to be opened if item is selected (provide spec or valueHolder).' cg@1690: cg@1690: #basicsMenuArgument cg@1690: 'An argument passed with the menu selector.' cg@1690: cg@1690: #basicsNameKey cg@1690: 'Unique identifier of the item (optional).' cg@1690: cg@1690: #basicsSelector cg@1690: 'Selector under which the generated menu spec is saved.' cg@1690: cg@1690: #basicsSeparatorType cg@1690: 'List of valid separators.' cg@1690: cg@1690: #basicsTranslateLabel cg@1690: 'Translate the label via the classes resource file (internationalization).' cg@1690: cg@1690: #browseResource cg@1690: 'Search for methods with image resource.' cg@1690: cg@1690: #detailsAccelerator cg@1690: 'Accelerator key to select the menu item from the keyboard (Cmdx or Ctrlx).' cg@1690: cg@1690: #detailsAccessCharaterPosition cg@1690: 'Index of the access character position of the textual label (obsolete, VW compatibility).' cg@1690: cg@1690: #detailsAuxValue cg@1690: 'Some additional value - for arbitrary use by the program.' cg@1690: cg@1690: #detailsEnabled cg@1702: 'Aspect or binding providing a boolean value holder to enable/disable the menu item.' cg@1690: ca@1844: #detailsIgnoreAcceleratorKeys ca@1844: 'Ignore accelerator keys in submenu(s).' ca@1844: ca@1844: #detailsIgnoreMnemonicKeys ca@1844: 'Ignore mnemonic keys (access characters) in submenu(s).' ca@1844: cg@1690: #detailsStartGroup cg@2123: 'Specify start of a specially aligned group.' cg@1690: cg@1690: #detailsVisibility cg@1690: 'Boolean, or aspect or binding for a boolean holder controlling the visibility of the menu item.' cg@1690: cg@1690: #fileLoad cg@1690: 'Load a menu spec from a class.' cg@1690: cg@1690: #fileNew cg@1690: 'Create a new menu spec.' cg@1690: cg@1690: #filePickAMenu cg@1690: 'Select a menu from an open view and read its specification' cg@1690: cg@2331: #fileChooseAMenu cg@2331: 'Select a menu from an open view and edit its spec-method' cg@2331: cg@1690: #fileSave cg@1690: 'Save the menu spec (and the help spec, if modified).' cg@1690: cg@1690: #fileSaveAs cg@1690: 'Open a dialog to save the menu spec (and the help spec, if modified).' cg@1690: cg@1690: #fileShowMenuSpec cg@1690: 'Opens a Workspace showing the current menu spec.' cg@1690: cg@3587: #forceMenuIndicator cg@3587: 'Always show a menu indicator in horizontal menu (little down-arrow).' cg@3587: cg@1690: #generateAspectMethods cg@1690: 'Generates aspect methods for defined aspect selectors of the menu.' cg@1690: cg@1690: #hideMenuOnActivated cg@1702: 'If on, the menu hides itself after the item was activated (PopUp/PullDown-Menus only).' cg@1690: cg@1690: #horizontalLayout cg@3013: 'If on, the submenu organizes its items horizontal instead of vertical (default).' cg@1690: cg@1690: #imageImageAndLabel cg@1690: 'Toggle display of both image and textual label.' cg@1690: cg@1690: #imageImageEditor cg@1690: 'Open an Image Editor on the resource method defined by retriever and selector.' cg@1690: cg@2797: #imageBrowseImageClass cg@2797: 'Open a Browser on the resource retriever class.' cg@2797: cg@1690: #imageImageList cg@1690: 'Currently existing image resources.' cg@1690: cg@1690: #imageRetriever cg@3071: 'Class implementing the image resource method. If unspecified, the application instance / class are asked.' cg@1690: cg@1690: #imageSelector cg@1690: 'Selector returning an image (sent to above or the application).' cg@1690: cg@1690: #keepLinkedMenu cg@2055: 'Keep the linked menu after activation (do not destroy; if off, menu is rebuild for every activation).' cg@1690: cg@1690: #sendToOriginator cg@1702: 'Send action-Message to widget (instead of application); only valid for PopUpMenus.' cg@1690: cg@1690: #settingsRedefineAspectMethods cg@1690: 'Toggles the permission to overwrite existing aspect methods.' cg@1690: cg@1690: #showBusyCursorWhilePerforming cg@1690: 'If on, a busy cursor is shown while the items action is performing.' cg@1690: cg@1690: #triggerOnDown cg@1702: 'If on, the items action is performed on mouse-button press (default is: on button-release).' cg@1690: cg@2850: #selectorFilter cg@2850: 'In the list below, only matching selectors are shown' cg@1690: ) cg@2055: cg@3587: "Modified: / 09-08-2018 / 17:09:02 / Claus Gittinger" ca@371: ! ! ca@371: tz@734: !MenuEditor class methodsFor:'image specs'! tz@734: cg@2297: browseActionImage cg@2297: cg@2297: cg@2297: ^ UIPainter browseActionImage cg@2297: ! cg@2297: sv@2156: defaultIcon sv@2156: sv@2156: sv@2156: ^ ToolbarIconLibrary startMenuEditorIcon sv@2156: ! sv@2156: ca@1606: iconUnknown ca@1606: "returns an image used for picked items containing an image tz@734: " cg@2271: ca@1606: ca@1606: ^ MenuPanelSpec icon cg@1425: ! ! tz@734: ca@199: !MenuEditor class methodsFor:'interface specs'! ca@199: tz@525: windowSpec tz@738: "This resource specification was automatically generated tz@738: by the UIPainter of ST/X." tz@738: tz@738: "Do not manually edit this!! If it is corrupted, tz@738: the UIPainter may not be able to read the specification." tz@525: tz@525: " tz@525: UIPainter new openOnClass:MenuEditor andSelector:#windowSpec tz@525: MenuEditor new openInterface:#windowSpec tz@738: MenuEditor open tz@525: " tz@525: tz@525: tz@525: mawalch@3545: ^ mawalch@3545: #(FullSpec mawalch@3545: name: windowSpec mawalch@3545: uuid: '7d4bc1c6-2067-11b2-b33d-3065ec8abe8a' mawalch@3545: window: mawalch@3545: (WindowSpec mawalch@3545: label: 'Menu Editor' mawalch@3545: name: 'Menu Editor' mawalch@3545: uuid: '7d4bc6f8-2067-11b2-b33d-3065ec8abe8a' mawalch@3545: min: (Point 550 385) mawalch@3545: bounds: (Rectangle 0 0 574 473) mawalch@3545: menu: menu mawalch@3545: icon: defaultIcon mawalch@3545: returnIsOKInDialog: false mawalch@3545: escapeIsCancelInDialog: false mawalch@3545: ) mawalch@3545: component: mawalch@3545: (SpecCollection mawalch@3545: collection: ( mawalch@3545: (MenuPanelSpec mawalch@3545: name: 'toolbar' mawalch@3545: layout: (LayoutFrame 0 0.0 0 0 0 1.0 32 0) mawalch@3545: uuid: '7d4bcc98-2067-11b2-b33d-3065ec8abe8a' mawalch@3545: tabable: true mawalch@3545: menu: toolbar mawalch@3545: showSeparatingLines: true mawalch@3545: ) mawalch@3545: (VariableHorizontalPanelSpec mawalch@3545: name: 'mainPanel' mawalch@3545: layout: (LayoutFrame 0 0.0 34 0.0 0 1.0 -26 1.0) mawalch@3545: uuid: '7d4bd2ba-2067-11b2-b33d-3065ec8abe8a' mawalch@3545: component: mawalch@3545: (SpecCollection mawalch@3545: collection: ( mawalch@3545: (HierarchicalListViewSpec mawalch@3545: name: 'ListOfItemsView' mawalch@3545: uuid: '7d4bd7ba-2067-11b2-b33d-3065ec8abe8a' mawalch@3545: model: selectionHolder mawalch@3545: menu: editMenu mawalch@3545: hasHorizontalScrollBar: true mawalch@3545: hasVerticalScrollBar: true mawalch@3545: miniScrollerHorizontal: true mawalch@3545: miniScrollerVertical: true mawalch@3545: listModel: listOfItems mawalch@3545: multipleSelectOk: true mawalch@3545: useIndex: false mawalch@3545: highlightMode: label mawalch@3545: doubleClickSelector: indicatorClickedAt: mawalch@3545: selectConditionSelector: canSelect: mawalch@3545: showLeftIndicators: false mawalch@3545: indicatorSelector: indicatorClickedAt: mawalch@3545: postBuildCallback: postBuildListOfItemsView: mawalch@3545: properties: mawalch@3545: (PropertyListDictionary mawalch@3545: dropSelector: doDrop: mawalch@3545: dragArgument: nil mawalch@3545: overSelector: dropOver: mawalch@3545: canDropSelector: canDrop: mawalch@3545: dropObjectSelector: dropObjects mawalch@3545: enterSelector: dropEnter: mawalch@3545: dropArgument: nil mawalch@3545: leaveSelector: dropLeave: mawalch@3545: ) mawalch@3545: ) mawalch@3545: (ViewSpec mawalch@3545: name: 'Box' mawalch@3545: uuid: '7d4be156-2067-11b2-b33d-3065ec8abe8a' mawalch@3545: level: -1 mawalch@3545: component: mawalch@3545: (SpecCollection mawalch@3545: collection: ( mawalch@3545: (NoteBookViewSpec mawalch@3545: name: 'NoteBook' mawalch@3545: layout: (LayoutFrame 1 0.0 0 0.0 1 1.0 -39 1.0) mawalch@3545: uuid: '7d4be430-2067-11b2-b33d-3065ec8abe8a' mawalch@3545: enableChannel: hasSingleSelectionChannel mawalch@3545: tabable: true mawalch@3545: model: tabHolder mawalch@3545: menu: listOfTabs mawalch@3545: fitLastRow: false mawalch@3545: translateLabel: true mawalch@3545: canvas: wizardHolder mawalch@3545: keepCanvasAlive: true mawalch@3545: postBuildCallback: postBuildNoteBook: mawalch@3545: ) mawalch@3545: (UISubSpecification mawalch@3545: name: 'SubSpecification' mawalch@3545: layout: (LayoutFrame 2 0.0 -35 1.0 -2 1.0 -2 1.0) mawalch@3545: uuid: '7d4beab6-2067-11b2-b33d-3065ec8abe8a' mawalch@3545: majorKey: ToolApplicationModel mawalch@3545: minorKey: windowSpecForCommit mawalch@3545: ) mawalch@3545: ) mawalch@3545: mawalch@3545: ) mawalch@3545: ) mawalch@3545: ) mawalch@3545: mawalch@3545: ) mawalch@3545: handles: (Any 0.29999999999999999 1.0) mawalch@3545: ) mawalch@3545: (UISubSpecification mawalch@3545: name: 'infoBarSubSpec' mawalch@3545: layout: (LayoutFrame 0 0.0 -24 1 0 1.0 0 1.0) mawalch@3545: uuid: '7d4bee30-2067-11b2-b33d-3065ec8abe8a' mawalch@3545: majorKey: ToolApplicationModel mawalch@3545: minorKey: windowSpecForInfoBar mawalch@3545: ) mawalch@3545: ) mawalch@3545: mawalch@3545: ) mawalch@3545: ) tz@525: ! ! tz@525: tz@525: !MenuEditor class methodsFor:'menu specs'! tz@525: ca@1606: addMenu ca@1606: "This resource specification was automatically generated ca@1606: by the MenuEditor of ST/X." ca@1606: ca@1606: "Do not manually edit this!! If it is corrupted, ca@1606: the MenuEditor may not be able to read the specification." ca@1606: ca@1606: " ca@1606: MenuEditor new openOnClass:MenuEditor andSelector:#addMenu ca@1606: (Menu new fromLiteralArrayEncoding:(MenuEditor addMenu)) startUp ca@1606: " ca@1606: ca@1606: ca@1606: cg@2188: ^ ca@1844: #(Menu cg@3013: ( cg@3013: (MenuItem cg@3013: activeHelpKey: addMenuSeparator cg@3013: label: 'Separator' cg@3013: itemValue: doCreateSep cg@3013: translateLabel: true cg@3013: labelImage: (ResourceRetriever #'MenuEditor::Item' iconSeparator '') cg@3013: ) cg@3013: (MenuItem cg@3013: activeHelpKey: addMenuItem cg@3013: label: 'Item' cg@3013: itemValue: doCreateItem cg@3013: translateLabel: true cg@3013: labelImage: (ResourceRetriever #'MenuEditor::Item' iconItem '') cg@3013: ) cg@3013: (MenuItem cg@3013: activeHelpKey: addMenuSliceItem cg@3013: label: 'Menu Slice' cg@3013: itemValue: doCreateMenuSliceItem cg@3013: translateLabel: true cg@3013: labelImage: (ResourceRetriever #'MenuEditor::Item' iconSliceMenu '') cg@3013: ) cg@3013: (MenuItem cg@3013: activeHelpKey: addMenuItem cg@3013: label: 'Menu' cg@3013: itemValue: doCreateMenu cg@3013: translateLabel: true cg@3013: labelImage: (ResourceRetriever #'MenuEditor::Item' iconMenu '') cg@3013: ) cg@3013: (MenuItem cg@3013: activeHelpKey: addSubMenuLink cg@3013: label: 'Linked Menu' cg@3013: itemValue: doCreateLinkedMenu cg@3013: translateLabel: true cg@3013: labelImage: (ResourceRetriever #'MenuEditor::Item' iconLinkedMenu '') cg@3013: ) cg@3013: (MenuItem cg@3013: label: '-' cg@3013: ) cg@3013: (MenuItem cg@3013: activeHelpKey: addDelayedMenu cg@3013: enabled: canCreateDelayedMenuChannel cg@3013: label: 'Delayed Menu' cg@3013: itemValue: doCreateDelayedMenu: cg@3013: translateLabel: true cg@3013: labelImage: (ResourceRetriever #'MenuEditor::Item' iconDelayedMenu '') cg@3013: argument: menu cg@3013: ) cg@3013: (MenuItem cg@3013: activeHelpKey: addDelayedSubMenuLink cg@3013: enabled: canCreateDelayedMenuChannel cg@3013: label: 'Delayed Linked Menu' cg@3013: itemValue: doCreateDelayedMenu: cg@3013: translateLabel: true cg@3013: labelImage: (ResourceRetriever #'MenuEditor::Item' iconDelayedLinkedMenu '') cg@3013: argument: linkedMenu cg@3013: ) cg@3013: (MenuItem cg@3013: label: '-' cg@3013: ) cg@3013: (MenuItem cg@3013: label: 'Standard Menus' cg@3013: translateLabel: true cg@3013: submenuChannel: standardMenus cg@3013: keepLinkedMenu: true cg@3013: ) cg@3013: ) cg@2275: "/ nil cg@2275: "/ nil ca@1606: ) ca@1606: ! ca@1606: ca@1606: editMenu ca@1606: "This resource specification was automatically generated ca@1606: by the MenuEditor of ST/X." ca@1606: ca@1606: "Do not manually edit this!! If it is corrupted, ca@1606: the MenuEditor may not be able to read the specification." ca@1606: ca@1606: " ca@1606: MenuEditor new openOnClass:MenuEditor andSelector:#editMenu ca@1606: (Menu new fromLiteralArrayEncoding:(MenuEditor editMenu)) startUp ca@1606: " ca@1606: ca@1606: ca@1606: cg@3013: ^ cg@2186: #(Menu cg@3135: ( cg@3135: (MenuItem cg@3135: activeHelpKey: editCut cg@3135: enabled: hasSelectionChannel cg@3135: label: 'Cut' cg@3135: itemValue: doCut cg@3135: translateLabel: true cg@3135: shortcutKey: Cut cg@3135: ) cg@3135: (MenuItem cg@3135: activeHelpKey: editCopy cg@3135: enabled: hasSelectionChannel cg@3135: label: 'Copy' cg@3135: itemValue: doCopy cg@3135: translateLabel: true cg@3135: shortcutKey: Copy cg@3135: ) cg@3135: (MenuItem cg@3135: activeHelpKey: editPaste cg@3135: enabled: canPasteHolder cg@3135: label: 'Paste' cg@3135: itemValue: doPaste cg@3135: translateLabel: true cg@3135: shortcutKey: Paste cg@3135: ) cg@3135: (MenuItem cg@3135: activeHelpKey: editDelete cg@3135: enabled: hasSelectionChannel cg@3135: label: 'Delete' cg@3135: itemValue: doDelete cg@3135: translateLabel: true cg@3135: isVisible: false cg@3135: ) cg@3135: (MenuItem cg@3135: label: '-' cg@3135: ) cg@3135: (MenuItem cg@3135: activeHelpKey: makeLinkedMenu cg@3135: enabled: hasNonLinkedMenuSelectedHolder cg@3135: label: 'Make Linked Menu...' cg@3135: itemValue: doMakeLinkedMenu cg@3135: translateLabel: true cg@3135: ) cg@3135: (MenuItem cg@3135: label: '-' cg@3135: ) cg@3135: (MenuItem cg@3135: activeHelpKey: editMoveUp cg@3135: enabled: enableMovingUpOrDownHolder cg@3135: label: 'Move Up' cg@3135: itemValue: doMoveUpOrDown: cg@3135: translateLabel: true cg@3135: startGroup: right cg@3135: shortcutKey: CtrlCursorUp cg@3135: labelImage: (ResourceRetriever Icon upIcon 'Move Up') cg@3135: argument: up cg@3135: ) cg@3135: (MenuItem cg@3135: activeHelpKey: editMoveDown cg@3135: enabled: enableMovingUpOrDownHolder cg@3135: label: 'Move Down' cg@3135: itemValue: doMoveUpOrDown: cg@3135: translateLabel: true cg@3135: shortcutKey: CtrlCursorDown cg@3135: labelImage: (ResourceRetriever Icon downIcon 'Move Down') cg@3135: argument: down cg@3135: ) cg@3135: (MenuItem cg@3135: activeHelpKey: editMoveIn cg@3135: enabled: enableMovingInHolder cg@3135: label: 'Move Into Next' cg@3135: itemValue: doMoveIn: cg@3135: translateLabel: true cg@3135: shortcutKey: CtrlCursorRight cg@3135: labelImage: (ResourceRetriever Icon downRightIcon 'Move Into Next') cg@3135: argument: inNext cg@3135: ) cg@3135: (MenuItem cg@3135: activeHelpKey: editMoveInAbove cg@3135: enabled: enableMovingInAboveHolder cg@3135: label: 'Move Into Previous' cg@3135: itemValue: doMoveIn: cg@3135: translateLabel: true cg@3135: labelImage: (ResourceRetriever Icon upRightIcon 'Move Into Previous' ) cg@3135: argument: inPrev cg@3135: ) cg@3135: (MenuItem cg@3135: activeHelpKey: editMoveOut cg@3135: enabled: enableMovingOutHolder cg@3135: label: 'Move Out' cg@3135: itemValue: doMoveOut cg@3135: translateLabel: true cg@3135: shortcutKey: CtrlCursorLeft cg@3135: labelImage: (ResourceRetriever Icon leftDownIcon 'Move Out' ) cg@3135: ) cg@3135: ) cg@3135: nil cg@3135: nil ca@1606: ) ca@1606: ! ca@1606: cg@2187: editMenuForMainMenuWithoutAccelerators cg@2187: "This resource specification was automatically generated cg@2187: by the MenuEditor of ST/X." cg@2187: cg@2187: "Do not manually edit this!! If it is corrupted, cg@2187: the MenuEditor may not be able to read the specification." cg@2187: cg@2187: " cg@2187: MenuEditor new openOnClass:MenuEditor andSelector:#editMenuForMainMenuWithoutAccelerators cg@2187: (Menu new fromLiteralArrayEncoding:(MenuEditor editMenuForMainMenuWithoutAccelerators)) startUp cg@2187: " cg@2187: cg@2187: cg@2187: cg@2188: ^ cg@2187: #(Menu cg@2188: ( cg@2188: (MenuItem cg@2188: activeHelpKey: editCut cg@2188: enabled: hasSelectionChannel cg@2188: label: 'Cut' cg@2188: itemValue: doCut cg@2188: translateLabel: true cg@2188: ) cg@2188: (MenuItem cg@2188: activeHelpKey: editCopy cg@2188: enabled: hasSelectionChannel cg@2188: label: 'Copy' cg@2188: itemValue: doCopy cg@2188: translateLabel: true cg@2188: ) cg@2188: (MenuItem cg@2188: activeHelpKey: editPaste cg@2188: enabled: canPasteHolder cg@2188: label: 'Paste' cg@2188: itemValue: doPaste cg@2188: translateLabel: true cg@2188: ) cg@2188: (MenuItem cg@2188: activeHelpKey: editDelete cg@2188: enabled: hasSelectionChannel cg@2188: label: 'Delete' cg@2188: itemValue: doDelete cg@2188: translateLabel: true cg@2188: isVisible: false cg@2188: ) cg@2188: (MenuItem cg@2188: label: '-' cg@2188: ) cg@2188: (MenuItem cg@2188: activeHelpKey: editMoveUp cg@2188: enabled: enableMovingUpOrDownHolder cg@2188: label: 'Move Up' cg@2188: itemValue: doMoveUpOrDown: cg@2188: translateLabel: true cg@2188: startGroup: right cg@2188: labelImage: (ResourceRetriever Icon upIcon 'Move Up') cg@2188: argument: up cg@2188: ) cg@2188: (MenuItem cg@2188: activeHelpKey: editMoveDown cg@2188: enabled: enableMovingUpOrDownHolder cg@2188: label: 'Move Down' cg@2188: itemValue: doMoveUpOrDown: cg@2188: translateLabel: true cg@2188: labelImage: (ResourceRetriever Icon downIcon 'Move Down') cg@2188: argument: down cg@2188: ) cg@2188: (MenuItem cg@2188: activeHelpKey: editMoveIn cg@2188: enabled: enableMovingInHolder cg@2188: label: 'Move Into Next' cg@2188: itemValue: doMoveIn: cg@2188: translateLabel: true cg@2188: labelImage: (ResourceRetriever Icon downRightIcon 'Move Into Next') cg@2188: argument: inNext cg@2188: ) cg@2188: (MenuItem cg@2188: activeHelpKey: editMoveInAbove cg@2188: enabled: enableMovingInAboveHolder cg@2188: label: 'Move Into Previous' cg@2188: itemValue: doMoveIn: cg@2188: translateLabel: true cg@2188: labelImage: (ResourceRetriever Icon upRightIcon 'Move Into Previous') cg@2188: argument: inPrev cg@2188: ) cg@2188: (MenuItem cg@2188: activeHelpKey: editMoveOut cg@2188: enabled: enableMovingOutHolder cg@2188: label: 'Move Out' cg@2188: itemValue: doMoveOut cg@2188: translateLabel: true cg@2188: labelImage: (ResourceRetriever Icon leftDownIcon 'Move Out') cg@2188: ) cg@2188: ) cg@2188: nil cg@2188: nil cg@2187: ) cg@2187: ! cg@2187: ca@1606: fileMenu ca@1606: "This resource specification was automatically generated ca@1606: by the MenuEditor of ST/X." ca@1606: ca@1606: "Do not manually edit this!! If it is corrupted, ca@1606: the MenuEditor may not be able to read the specification." ca@1606: ca@1606: " ca@1606: MenuEditor new openOnClass:MenuEditor andSelector:#fileMenu ca@1606: (Menu new fromLiteralArrayEncoding:(MenuEditor fileMenu)) startUp ca@1606: " ca@1606: ca@1606: ca@1606: cg@3013: ^ cg@1971: #(Menu cg@3013: ( cg@3013: (MenuItem cg@3013: isVisible: isNotEditingSpecOnlyAndNotEmbeddedInBrowser cg@3013: activeHelpKey: fileNew cg@3013: label: 'New' cg@3013: itemValue: doNew cg@3013: translateLabel: true cg@3013: ) cg@3013: (MenuItem cg@3013: isVisible: isNotEditingSpecOnlyAndNotEmbeddedInBrowser cg@3013: label: '-' cg@3013: ) cg@3013: (MenuItem cg@3013: isVisible: isNotEditingSpecOnlyAndNotEmbeddedInBrowser cg@3013: activeHelpKey: fileLoad cg@3013: label: 'Load...' cg@3013: itemValue: doLoad cg@3013: translateLabel: true cg@3013: ) cg@3013: (MenuItem cg@3013: isVisible: isNotEditingSpecOnlyAndNotEmbeddedInBrowser cg@3013: label: '-' cg@3013: ) cg@3013: (MenuItem cg@3013: isVisible: isEditingSpecOnly cg@3013: activeHelpKey: fileSaveSpec cg@3013: label: 'Save' cg@3013: itemValue: doSave cg@3013: translateLabel: true cg@3013: ) cg@3013: (MenuItem cg@3013: isVisible: isNotEditingSpecOnly cg@3013: activeHelpKey: fileSave cg@3013: label: 'Save' cg@3013: itemValue: doSave cg@3013: translateLabel: true cg@3013: ) cg@3013: (MenuItem cg@3013: isVisible: isNotEditingSpecOnlyAndNotEmbeddedInBrowser cg@3013: activeHelpKey: fileSaveAs cg@3013: label: 'Save As...' cg@3013: itemValue: doSaveAs cg@3013: translateLabel: true cg@3013: ) cg@3013: (MenuItem cg@3013: label: '-' cg@3013: ) cg@3013: (MenuItem cg@3013: activeHelpKey: filePickAMenu cg@3013: label: 'Pick a Menu...' cg@3013: itemValue: doPickAMenu cg@3013: translateLabel: true cg@3013: ) cg@3013: (MenuItem cg@3013: activeHelpKey: fileChooseAMenu cg@3013: label: 'Choose a Menu...' cg@3013: itemValue: doChooseAMenu cg@3013: translateLabel: true cg@3013: ) cg@3013: (MenuItem cg@3013: label: '-' cg@3013: isVisible: isStandAlone cg@3013: ) cg@3013: (MenuItem cg@3013: activeHelpKey: fileBrowseClass cg@3013: enabled: hasValidSpecClass cg@3013: label: 'Browse Class' cg@3013: itemValue: doBrowseClass cg@3013: translateLabel: true cg@3013: isVisible: isStandAlone cg@3013: ) cg@3013: (MenuItem cg@3013: activeHelpKey: fileShowMenuSpec cg@3013: label: 'Show Menu Spec' cg@3013: itemValue: doShowMenuSpec cg@3013: translateLabel: true cg@3013: isVisible: isStandAlone cg@3013: ) cg@3013: (MenuItem cg@3013: label: '-' cg@3013: isVisible: isStandAlone cg@3013: ) cg@3013: (MenuItem cg@3013: activeHelpKey: fileExit cg@3013: label: 'Exit' cg@3013: itemValue: closeRequest cg@3013: translateLabel: true cg@3013: isVisible: isStandAlone cg@3013: ) cg@3013: ) cg@3013: nil cg@3013: nil ca@1606: ) ca@1606: ! ca@1606: ca@1614: generateMenu ca@1614: "This resource specification was automatically generated ca@1614: by the MenuEditor of ST/X." ca@1614: ca@1614: "Do not manually edit this!! If it is corrupted, ca@1614: the MenuEditor may not be able to read the specification." ca@1614: ca@1614: " ca@1614: MenuEditor new openOnClass:MenuEditor andSelector:#generateMenu ca@1614: (Menu new fromLiteralArrayEncoding:(MenuEditor generateMenu)) startUp ca@1614: " ca@1614: ca@1614: ca@1614: cg@2188: ^ ca@1614: #(#Menu cg@2188: #( cg@2188: #(#MenuItem cg@2188: #activeHelpKey: #generateAspectMethods cg@2188: #enabled: #hasValidSpecClass cg@2188: #label: 'Aspect Methods' cg@2188: #itemValue: #doGenerateAspectMethods cg@2188: #translateLabel: true cg@2188: ) cg@2188: ) cg@2188: nil cg@2188: nil ca@1614: ) ca@1614: ! ca@1614: ca@1606: helpMenu ca@1606: "This resource specification was automatically generated ca@1606: by the MenuEditor of ST/X." ca@1606: ca@1606: "Do not manually edit this!! If it is corrupted, ca@1606: the MenuEditor may not be able to read the specification." ca@1606: ca@1606: " ca@1606: MenuEditor new openOnClass:MenuEditor andSelector:#helpMenu ca@1606: (Menu new fromLiteralArrayEncoding:(MenuEditor helpMenu)) startUp ca@1606: " ca@1606: ca@1606: ca@1606: cg@2188: ^ ca@1606: #(#Menu cg@2188: #( cg@2188: #(#MenuItem cg@2188: #activeHelpKey: #helpTutorial cg@2188: #label: 'Documentation' cg@2188: #itemValue: #openHTMLDocument: cg@2188: #translateLabel: true cg@2188: #argument: 'tools/uipainter/MenuEditor.html' cg@2188: ) cg@2188: #(#MenuItem cg@2188: #label: '-' cg@2188: ) cg@2188: #(#MenuItem cg@2188: #activeHelpKey: #helpHelpTool cg@2188: #label: 'Help Tool' cg@2188: #itemValue: #openHTMLDocument: cg@2188: #translateLabel: true cg@2188: #argument: 'tools/uipainter/HelpTool.html' cg@2188: ) cg@2188: #(#MenuItem cg@2188: #label: '-' cg@2188: ) cg@2188: #(#MenuItem cg@2188: #activeHelpKey: #helpShowHelp cg@2188: #label: 'Show Help Texts' cg@2188: #translateLabel: true cg@2188: #indication: #showingHelp: cg@2188: ) cg@2188: #(#MenuItem cg@2188: #label: '-' cg@2188: ) cg@2188: #(#MenuItem cg@2188: #activeHelpKey: #aboutThisAppliaction cg@2188: #label: 'About MenuEditor...' cg@2188: #itemValue: #openAboutThisApplication cg@2188: #translateLabel: true cg@2188: ) cg@2188: ) cg@2188: nil cg@2188: nil ca@1606: ) ca@1606: ! ca@1606: tz@525: menu tz@738: "This resource specification was automatically generated tz@738: by the MenuEditor of ST/X." tz@738: tz@738: "Do not manually edit this!! If it is corrupted, tz@738: the MenuEditor may not be able to read the specification." tz@525: tz@525: " tz@525: MenuEditor new openOnClass:MenuEditor andSelector:#menu tz@525: (Menu new fromLiteralArrayEncoding:(MenuEditor menu)) startUp tz@525: " tz@525: tz@525: tz@525: cg@3013: ^ ca@1775: #(Menu cg@3013: ( cg@3013: (MenuItem cg@3013: label: '&File' cg@3013: translateLabel: true cg@3013: submenuChannel: fileMenu cg@3013: keepLinkedMenu: true cg@3013: ignoreMnemonicKeys: true cg@3013: ignoreShortcutKeys: true cg@3013: ) cg@3013: (MenuItem cg@3013: label: '&Edit' cg@3013: translateLabel: true cg@3013: submenuChannel: editMenuForMainMenuWithoutAccelerators cg@3013: keepLinkedMenu: true cg@3013: ) cg@3013: (MenuItem cg@3013: enabled: hasSingleSelectionChannel cg@3013: label: 'Item' cg@3013: translateLabel: true cg@3013: submenuChannel: addMenu cg@3013: keepLinkedMenu: true cg@3013: ignoreMnemonicKeys: true cg@3013: ignoreShortcutKeys: true cg@3013: ) cg@3013: (MenuItem cg@3013: isVisible: isNotEditingSpecOnly cg@3013: label: 'Generate' cg@3013: translateLabel: true cg@3013: submenuChannel: generateMenu cg@3013: keepLinkedMenu: true cg@3013: ignoreMnemonicKeys: true cg@3013: ignoreShortcutKeys: true cg@3013: ) cg@3013: (MenuItem cg@3013: label: 'Test' cg@3013: translateLabel: true cg@3013: submenuChannel: submenuTest cg@3013: ignoreMnemonicKeys: true cg@3013: ignoreShortcutKeys: true cg@3013: ) cg@3013: (MenuItem cg@3013: label: 'Settings' cg@3013: translateLabel: true cg@3013: submenuChannel: settingsMenu cg@3013: keepLinkedMenu: true cg@3013: ignoreMnemonicKeys: true cg@3013: ignoreShortcutKeys: true cg@3013: ) cg@3013: (MenuItem cg@3013: label: 'History' cg@3013: translateLabel: true cg@3013: isVisible: isStandAlone cg@3013: submenuChannel: menuHistory cg@3013: ignoreMnemonicKeys: true cg@3013: ignoreShortcutKeys: true cg@3013: ) cg@3013: (MenuItem cg@3013: label: 'MENU_Help' cg@3013: translateLabel: true cg@3013: startGroup: conditionalRight cg@3013: submenuChannel: helpMenu cg@3013: keepLinkedMenu: true cg@3013: ignoreMnemonicKeys: true cg@3013: ignoreShortcutKeys: true cg@3013: ) cg@3013: ) cg@3013: nil cg@3013: nil tz@525: ) tz@525: ! tz@525: cg@1631: settingsMenu cg@1631: "This resource specification was automatically generated cg@1631: by the MenuEditor of ST/X." cg@1631: cg@1631: "Do not manually edit this!! If it is corrupted, cg@1631: the MenuEditor may not be able to read the specification." cg@1631: cg@1631: " cg@1632: MenuEditor new openOnClass:MenuEditor andSelector:#settingsMenu cg@1632: (Menu new fromLiteralArrayEncoding:(MenuEditor settingsMenu)) startUp cg@1631: " cg@1631: cg@1631: cg@1631: cg@2188: ^ cg@1631: #(#Menu cg@3013: #( cg@3013: #(#MenuItem cg@3013: isVisible: isNotEditingSpecOnly cg@3013: #activeHelpKey: #settingsRedefineAspectMethods cg@3013: #enabled: #hasValidSpecClass cg@3013: #label: 'Redefine Aspect Methods' cg@3013: #translateLabel: true cg@3013: #hideMenuOnActivated: false cg@3013: #indication: #redefineAspectMethodsChannel cg@3013: ) cg@3013: #(#MenuItem cg@3013: #activeHelpKey: #settingsRedefineAspectMethods cg@3013: #label: 'AutoAccept on Selection-Change' cg@3013: #translateLabel: true cg@3013: #hideMenuOnActivated: false cg@3013: #indication: #autoAcceptOnSelectionChange cg@3013: ) cg@3013: ) cg@3013: nil cg@3013: nil cg@1631: ) cg@1631: ! cg@1631: ca@1606: standardMenus tz@738: "This resource specification was automatically generated tz@738: by the MenuEditor of ST/X." tz@738: tz@738: "Do not manually edit this!! If it is corrupted, tz@738: the MenuEditor may not be able to read the specification." tz@525: tz@525: " ca@1606: MenuEditor new openOnClass:MenuEditor andSelector:#standardMenus ca@1606: (Menu new fromLiteralArrayEncoding:(MenuEditor standardMenus)) startUp tz@525: " tz@525: tz@525: tz@525: cg@2188: ^ ca@1606: #(#Menu cg@2188: #( cg@2188: #(#MenuItem cg@2188: #label: 'Standard Menu: File' cg@2188: #itemValue: #doCreateStandardFileMenu cg@2188: #translateLabel: true cg@2188: ) cg@2188: #(#MenuItem cg@2188: #label: 'Standard Menu: Edit' cg@2188: #itemValue: #doCreateStandardEditMenu cg@2188: #translateLabel: true cg@2188: ) cg@2188: #(#MenuItem cg@2188: #label: 'Standard Menu: Help' cg@2188: #itemValue: #doCreateStandardHelpMenu cg@2188: #translateLabel: true cg@2188: ) cg@2188: ) cg@2188: nil cg@2188: nil tz@525: ) tz@525: ! tz@525: ca@1606: toolbar tz@738: "This resource specification was automatically generated tz@738: by the MenuEditor of ST/X." tz@738: tz@738: "Do not manually edit this!! If it is corrupted, tz@738: the MenuEditor may not be able to read the specification." tz@525: tz@525: " ca@1606: MenuEditor new openOnClass:MenuEditor andSelector:#toolbar ca@1606: (Menu new fromLiteralArrayEncoding:(MenuEditor toolbar)) startUp tz@525: " tz@525: tz@525: tz@525: cg@3013: ^ cg@1749: #(Menu cg@3013: ( cg@3013: (MenuItem cg@3013: activeHelpKey: fileNew cg@3013: label: 'New' cg@3013: itemValue: doNew cg@3013: translateLabel: true cg@3013: isButton: true cg@3013: labelImage: (ResourceRetriever ToolbarIconLibrary newMenuIcon) cg@3013: ) cg@3013: (MenuItem cg@3013: label: '-' cg@3013: ) cg@3013: (MenuItem cg@3013: activeHelpKey: fileLoad cg@3013: label: 'Load' cg@3013: itemValue: doLoad cg@3013: translateLabel: true cg@3013: isButton: true cg@3013: isVisible: isNotEditingSpecOnly cg@3013: submenuChannel: menuHistory cg@3013: labelImage: (ResourceRetriever ToolbarIconLibrary loadFromMethodIcon) cg@3013: keepLinkedMenu: true cg@3013: ) cg@3013: (MenuItem cg@3013: activeHelpKey: fileSave cg@3013: label: 'Save' cg@3013: itemValue: doSave cg@3013: translateLabel: true cg@3013: isButton: true cg@3013: isVisible: isNotEditingSpecOnly cg@3013: labelImage: (ResourceRetriever ToolbarIconLibrary saveAsMethodIcon) cg@3013: ) cg@3013: (MenuItem cg@3013: activeHelpKey: fileSaveSpec cg@3013: label: 'Save' cg@3013: itemValue: doSave cg@3013: translateLabel: true cg@3013: isButton: true cg@3013: isVisible: isEditingSpecOnly cg@3013: labelImage: (ResourceRetriever XPToolbarIconLibrary saveImageIcon) cg@3013: ) cg@3013: (MenuItem cg@3013: label: '-' cg@3013: ) cg@3013: (MenuItem cg@3013: activeHelpKey: editCut cg@3013: enabled: hasSelectionChannel cg@3013: label: 'Cut' cg@3013: itemValue: doCut cg@3013: translateLabel: true cg@3013: isButton: true cg@3013: labelImage: (ResourceRetriever ToolbarIconLibrary cutMenuItemIcon) cg@3013: ) cg@3013: (MenuItem cg@3013: activeHelpKey: editCopy cg@3013: enabled: hasSelectionChannel cg@3013: label: 'Copy' cg@3013: itemValue: doCopy cg@3013: translateLabel: true cg@3013: isButton: true cg@3013: labelImage: (ResourceRetriever ToolbarIconLibrary copyMenuItemIcon) cg@3013: ) cg@3013: (MenuItem cg@3013: activeHelpKey: editPaste cg@3013: enabled: canPasteHolder cg@3013: label: 'Paste' cg@3013: itemValue: doPaste cg@3013: translateLabel: true cg@3013: isButton: true cg@3013: labelImage: (ResourceRetriever ToolbarIconLibrary pasteMenuItemIcon) cg@3013: ) cg@3013: (MenuItem cg@3013: label: '-' cg@3013: ) cg@3013: (MenuItem cg@3013: activeHelpKey: addMenuItem cg@3013: enabled: hasSingleSelectionChannel cg@3013: label: 'Add Item' cg@3013: itemValue: doCreateItem cg@3013: translateLabel: true cg@3013: isButton: true cg@3013: labelImage: (ResourceRetriever #'MenuEditor::Item' iconItem) cg@3013: ) cg@3013: (MenuItem cg@3013: activeHelpKey: addMenuSeparator cg@3013: enabled: hasSingleSelectionChannel cg@3013: label: 'Add Separator' cg@3013: itemValue: doCreateSep cg@3013: translateLabel: true cg@3013: isButton: true cg@3013: labelImage: (ResourceRetriever #'MenuEditor::Item' iconSeparator) cg@3013: ) cg@3013: (MenuItem cg@3013: activeHelpKey: addMenuSlice cg@3013: enabled: hasSingleSelectionChannel cg@3013: label: 'Menu Slice' cg@3013: itemValue: doCreateMenuSliceItem cg@3013: translateLabel: true cg@3013: isButton: true cg@3013: labelImage: (ResourceRetriever #'MenuEditor::Item' iconSliceMenu) cg@3013: ) cg@3013: (MenuItem cg@3013: activeHelpKey: addSubMenu cg@3013: enabled: hasSingleSelectionChannel cg@3013: label: 'Add Menu' cg@3013: itemValue: doCreateMenu cg@3013: translateLabel: true cg@3013: isButton: true cg@3013: submenuChannel: standardMenus cg@3013: labelImage: (ResourceRetriever #'MenuEditor::Item' iconMenu) cg@3013: keepLinkedMenu: true cg@3013: ) cg@3013: (MenuItem cg@3013: activeHelpKey: addSubMenuLink cg@3013: enabled: hasSingleSelectionChannel cg@3013: label: 'Add Linked Menu' cg@3013: itemValue: doCreateLinkedMenu cg@3013: translateLabel: true cg@3013: isButton: true cg@3013: labelImage: (ResourceRetriever #'MenuEditor::Item' iconLinkedMenu) cg@3013: ) cg@3013: (MenuItem cg@3013: activeHelpKey: addDelayedMenu cg@3013: enabled: canCreateDelayedMenuChannel cg@3013: label: 'Add Delayed Menu' cg@3013: itemValue: doCreateDelayedMenu: cg@3013: translateLabel: true cg@3013: isButton: true cg@3013: labelImage: (ResourceRetriever #'MenuEditor::Item' iconDelayedMenu) cg@3013: argument: menu cg@3013: ) cg@3013: (MenuItem cg@3013: activeHelpKey: addDelayedSubMenuLink cg@3013: enabled: canCreateDelayedMenuChannel cg@3013: label: 'Add Delayed Linked Menu' cg@3013: itemValue: doCreateDelayedMenu: cg@3013: translateLabel: true cg@3013: isButton: true cg@3013: labelImage: (ResourceRetriever #'MenuEditor::Item' iconDelayedLinkedMenu) cg@3013: argument: linkedMenu cg@3013: ) cg@3013: (MenuItem cg@3013: label: '' cg@3013: ) cg@3013: (MenuItem cg@3013: activeHelpKey: editMoveUp cg@3013: enabled: enableMovingUpOrDownHolder cg@3013: label: 'Move Up' cg@3013: itemValue: doMoveUp cg@3013: translateLabel: true cg@3013: isButton: true cg@3013: startGroup: right cg@3013: labelImage: (ResourceRetriever Icon upIcon) cg@3013: ) cg@3013: (MenuItem cg@3013: activeHelpKey: editMoveDown cg@3013: enabled: enableMovingUpOrDownHolder cg@3013: label: 'Move Down' cg@3013: itemValue: doMoveDown cg@3013: translateLabel: true cg@3013: isButton: true cg@3013: labelImage: (ResourceRetriever Icon downIcon) cg@3013: ) cg@3013: (MenuItem cg@3013: activeHelpKey: editMoveIn cg@3013: enabled: enableMovingInHolder cg@3013: label: 'Move Into Next' cg@3013: itemValue: doMoveInNext cg@3013: translateLabel: true cg@3013: isButton: true cg@3013: labelImage: (ResourceRetriever Icon downRightIcon) cg@3013: ) cg@3013: (MenuItem cg@3013: activeHelpKey: editMoveInAbove cg@3013: enabled: enableMovingInAboveHolder cg@3013: label: 'Move Into Previous' cg@3013: itemValue: doMoveInPrevious cg@3013: translateLabel: true cg@3013: isButton: true cg@3013: labelImage: (ResourceRetriever Icon upRightIcon) cg@3013: ) cg@3013: (MenuItem cg@3013: activeHelpKey: editMoveOut cg@3013: enabled: enableMovingOutHolder cg@3013: label: 'Move Out' cg@3013: itemValue: doMoveOut cg@3013: translateLabel: true cg@3013: isButton: true cg@3013: labelImage: (ResourceRetriever Icon leftDownIcon) cg@3013: ) cg@3013: ) cg@3013: nil cg@3013: nil tz@525: ) tz@525: ! ! tz@525: cg@1725: !MenuEditor class methodsFor:'menu specs-standard'! ca@1606: ca@1606: standardEditMenu ca@1606: "This resource specification was automatically generated ca@1606: by the MenuEditor of ST/X." ca@1606: ca@1606: "Do not manually edit this!! If it is corrupted, ca@1606: the MenuEditor may not be able to read the specification." ca@1606: ca@1606: " ca@1606: MenuEditor new openOnClass:MenuEditor andSelector:#standardEditMenu ca@1606: (Menu new fromLiteralArrayEncoding:(MenuEditor standardEditMenu)) startUp ca@1606: " ca@1606: ca@1606: ca@1606: cg@2188: ^ ca@1606: #(#Menu cg@2188: #( cg@2188: #(#MenuItem cg@2188: #label: 'Cut' cg@2188: #translateLabel: true cg@2188: #value: #cutSelection cg@2188: ) cg@2188: #(#MenuItem cg@2188: #label: 'Copy' cg@2188: #translateLabel: true cg@2188: #value: #copySelection cg@2188: ) cg@2188: #(#MenuItem cg@2188: #label: 'Paste' cg@2188: #translateLabel: true cg@2188: #value: #paste cg@2188: ) cg@2188: ) cg@2188: nil cg@2188: nil tz@525: ) tz@525: ! tz@525: ca@1606: standardFileMenu ca@1606: "This resource specification was automatically generated ca@1606: by the MenuEditor of ST/X." ca@1606: ca@1606: "Do not manually edit this!! If it is corrupted, ca@1606: the MenuEditor may not be able to read the specification." ca@1606: ca@1606: " ca@1606: MenuEditor new openOnClass:MenuEditor andSelector:#standardFileMenu ca@1606: (Menu new fromLiteralArrayEncoding:(MenuEditor standardFileMenu)) startUp ca@1606: " ca@1606: ca@1606: ca@1606: cg@2188: ^ ca@1606: #(#Menu ca@1606: #( ca@1606: #(#MenuItem ca@1606: #label: 'New' ca@1606: #translateLabel: true ca@1606: #value: #menuNew ca@1606: ) ca@1606: #(#MenuItem ca@1606: #label: '-' ca@1606: ) ca@1606: #(#MenuItem ca@1606: #label: 'Open...' ca@1606: #translateLabel: true ca@1606: #value: #menuOpen ca@1606: ) ca@1606: #(#MenuItem ca@1606: #label: '-' ca@1606: ) ca@1606: #(#MenuItem ca@1606: #label: 'Save' ca@1606: #translateLabel: true ca@1606: #value: #menuSave ca@1606: ) ca@1606: #(#MenuItem ca@1606: #label: 'Save As...' ca@1606: #translateLabel: true ca@1606: #value: #menuSaveAs ca@1606: ) ca@1606: #(#MenuItem ca@1606: #label: '-' ca@1606: ) ca@1606: #(#MenuItem ca@1606: #label: 'Exit' ca@1606: #translateLabel: true ca@1606: #value: #closeRequest ca@1606: ) ca@1606: ) ca@1606: nil ca@1606: nil tz@525: ) tz@525: ! tz@525: ca@1606: standardHelpMenu ca@1606: "This resource specification was automatically generated ca@1606: by the MenuEditor of ST/X." ca@1606: ca@1606: "Do not manually edit this!! If it is corrupted, ca@1606: the MenuEditor may not be able to read the specification." ca@1606: ca@1606: " ca@1606: MenuEditor new openOnClass:MenuEditor andSelector:#standardHelpMenu ca@1606: (Menu new fromLiteralArrayEncoding:(MenuEditor standardHelpMenu)) startUp ca@1606: " ca@1606: ca@1606: ca@1606: cg@2188: ^ ca@1606: #(#Menu cg@2188: #( cg@2188: #(#MenuItem cg@2188: #label: 'Documentation' cg@2188: #translateLabel: true cg@2188: #value: #openDocumentation cg@2188: ) cg@2188: #(#MenuItem cg@2188: #label: '-' cg@2188: ) cg@2188: #(#MenuItem cg@2188: #label: 'About this Application...' cg@2188: #translateLabel: true cg@2188: #value: #openAboutThisApplication cg@2188: ) cg@2188: ) cg@2188: nil cg@2188: nil tz@525: ) ca@199: ! ! ca@199: ca@199: !MenuEditor methodsFor:'accessing'! ca@199: cg@2123: helpSpec sv@3016: |spec t g| cg@2123: cg@2123: spec := super helpSpec. cg@2123: t := spec at:#detailsStartGroup. cg@2123: g := (aspects at:#startGroup ifAbsent:nil) value. cg@2123: g == #conditionalRight ifTrue:[ sv@3016: t := t , ' #conditionalRight means: "right on non-win32 systems"' cg@2123: ]. cg@2123: g == #right ifTrue:[ sv@3016: t := t , ' #right means: "right align from here"' cg@2123: ]. cg@2123: g == #left ifTrue:[ sv@3016: t := t , ' #left means: "left align group"' cg@2123: ]. cg@2123: spec at:#detailsStartGroup put:t. cg@2123: cg@2123: ^ spec. cg@2123: "/ #detailsStartGroup cg@2123: "/ 'Specify start of a right-aligned item group.' cg@2123: cg@2123: "Created: / 16-10-2006 / 13:19:14 / cg" cg@2123: ! cg@2123: ca@1606: helpTool ca@1606: "get the help tool application ca@1606: " ca@1669: ^ wizards at:#help ifAbsentPut:[ |tool| cg@2188: tool := UIHelpTool new. cg@2188: tool masterApplication:self. cg@2188: tool modifiedHolder: self enablingCommitButtonsHolder. cg@2188: tool builder window:(ApplicationSubView new client:tool spec:#innerSpec). cg@2188: tool masterApplication:self. cg@2188: tool ca@1606: ] ca@1606: ! ca@1606: ca@1606: imageTool cg@2850: "get the image tool application" cg@2850: cg@3013: ^ wizards cg@3013: at:#image cg@3013: ifAbsentPut:[ cg@3013: |tool| cg@3013: cg@3013: tool := ImageResourceEditor new createBuilder. cg@3013: tool masterApplication:self. cg@3013: tool modifiedChannel: self enablingCommitButtonsHolder. cg@3013: tool builder window:(ApplicationSubView new client:tool). cg@3013: tool cg@3013: ] cg@2850: cg@2850: "Modified: / 03-08-2011 / 10:03:08 / cg" ca@1606: ! ca@1606: cg@2569: savedSpec cg@2569: ^ savedSpec cg@2569: ! cg@2569: ca@1606: useHelpTool:aHelpTool ca@1606: "take the help dictionaries from aHelpTool into my helpTool ca@1606: " cg@1971: self helpTool loadFromHelpTool:aHelpTool. ca@1606: ! ! ca@1606: ca@1606: !MenuEditor methodsFor:'actions'! ca@1606: ca@1606: accept ca@1606: "accept modifications ca@1606: " ca@1606: self accept:true. ca@1606: ! ca@1606: ca@1606: accept:ok cg@2297: "if ok is true, the modifications are accepted. cg@2297: then reload from item ca@1606: " ca@1606: |selectedItem rscRetrHolder helpKeyHolder helpTool imageTool acceptChannel| ca@1606: ca@1606: selectedItem := self selectedItem. ca@1606: cg@2862: selectedItem notNil ifTrue:[ cg@3013: self withoutNotifyDo:[ cg@3013: rscRetrHolder := aspects at:#resourceRetriever. cg@3013: helpKeyHolder := aspects at:#activeHelpKey. cg@3013: imageTool := self imageTool. cg@3013: helpTool := self helpTool. cg@3013: acceptChannel := self acceptChannel. cg@3013: cg@3013: acceptChannel triggerValue:true. cg@3013: acceptChannel setValue:false. cg@3013: cg@3013: ok ifTrue:[ cg@3013: helpTool accept. cg@3013: rscRetrHolder value:(imageTool resourceRetriever). cg@3013: helpKeyHolder value:(helpTool helpKey). cg@3013: selectedItem fromAspects:aspects. cg@3013: self setModified. cg@3013: cg@3013: selectedItem isRootItem ifTrue:[ cg@3013: "/ update specSelector cg@3013: specSelector := selectedItem rawLabel. cg@3013: ]. cg@3013: ]. cg@3013: selectedItem toAspects:aspects. cg@3013: helpTool helpKey:(helpKeyHolder value). cg@3013: imageTool resourceRetriever:(rscRetrHolder value). cg@3013: ] ca@218: ]. ca@1606: self updateChannels. cg@2075: "/ self clearModified. cg@2075: self clearModifiedFlag. cg@2075: cg@2075: self enablingCommitButtonsHolder value:false. cg@2075: cg@2862: "Modified: / 29-11-2011 / 11:28:02 / cg" ca@1606: ! ca@1606: ca@1606: cancel cg@2070: "reload aspects from current selected item; reset modification flag" cg@2070: ca@1606: self accept:false. cg@2070: cg@2070: "Modified: / 29-08-2006 / 10:20:46 / cg" ca@287: ! ca@287: ca@1606: indicatorClickedAt:atLine ca@1606: "indicator clicked at line number; toggle expand of item at line ca@1606: " ca@1606: |item| ca@1606: ca@1606: item := listOfItems at:atLine ifAbsent:nil. cg@2862: item notNil ifTrue:[ cg@3013: item toggleExpand. cg@3013: self hasSelection ifFalse:[ cg@3013: self selectedItem:item cg@3013: ] ca@1610: ]. cg@2862: cg@2862: "Modified: / 29-11-2011 / 11:28:20 / cg" ca@199: ! ! ca@199: ca@199: !MenuEditor methodsFor:'aspects'! ca@199: ca@1606: canCreateDelayedMenuChannel ca@1606: "boolean holder, true if the current selected item accepts a delayed menu ca@1606: " ca@1606: ^ builder booleanValueAspectFor:#canCreateDelayedMenuChannel ca@220: ! ca@220: cg@1636: hasItemValue cg@1636: "boolean holder, true if any item is selected cg@1636: " cg@2188: ^ BlockValue cg@2188: with:[:holder | holder size > 0] cg@2188: argument:(self aspectFor:#itemValue) cg@2161: cg@2161: "Modified: / 08-03-2007 / 22:59:42 / cg" cg@1636: ! cg@1636: cg@3135: hasNonLinkedMenuSelectedHolder sv@3664: "boolean holder, true if a single non linked menu item is selected" sv@3664: cg@3135: ^ BlockValue sv@3664: with:[:selection | sv@3664: (selection size == 1) sv@3664: and:[selection first isKindOfNonLinkedMenu sv@3664: and:[selection first isRootItem not]] cg@3135: ] cg@3135: argument:(self selectionHolder) sv@3664: sv@3664: "Modified: / 17-05-2019 / 16:18:19 / Stefan Vogel" cg@3135: ! cg@3135: ca@1606: hasSelectionChannel ca@1606: "boolean holder, true if any item is selected ca@1606: " ca@1606: ^ builder booleanValueAspectFor:#hasSelectionChannel ca@220: ! ca@220: ca@1606: hasSingleSelectionChannel ca@1606: "boolean holder, true if one item is selected ca@1606: " ca@1606: ^ builder booleanValueAspectFor:#hasSingleSelectionChannel ca@1606: ! ca@1606: ca@1606: listOfItems ca@1606: "returns the hierarchical list of menuItems ca@1244: " ca@1606: ^ listOfItems ca@1606: ! ca@1606: ca@1606: listOfTabs ca@1606: "returns the list of current shown tab-labels retrieved ca@1606: from the current selected item. ca@1606: " ca@1606: ^ listOfTabs ca@1606: ! ca@1606: ca@1617: redefineAspectMethodsChannel cg@2188: "boolean holder, true if aspects should be generated in only implemented ca@1617: in superClass by calling #super ... ca@1617: " ca@1617: ^ builder booleanValueAspectFor:#redefineAspectMethodsChannel ca@1617: ! ca@1617: ca@1606: selectionHolder ca@1606: "value holder, which keeps the current selected items ca@1606: " ca@1606: ^ selectionHolder ca@199: ! ca@199: ca@1606: tabHolder ca@1606: "value holder, which keeps the current selected tab label or nil ca@1606: " ca@1606: ^ tabHolder ca@1606: ! ca@1606: ca@1606: wizardHolder ca@1606: "holder, which keeps the current wizard window ca@1606: " tz@879: |holder| ca@1606: ca@1606: holder := builder bindingAt:#wizardHolder. ca@1606: cg@2151: holder isNil ifTrue:[ cg@2188: holder := nil asValue. cg@2188: builder aspectAt:#wizardHolder put:holder. tz@879: ]. tz@879: ^ holder ca@199: ! ! ca@199: tz@728: !MenuEditor methodsFor:'building'! tz@728: ca@1606: buildFromMenu:aMenu selector:aSelector ca@1606: "rebuild menu from a Menu ca@1606: " ca@1606: |root menu| ca@1606: ca@1606: aMenu isCollection ifTrue:[menu := aMenu decodeAsLiteralArray] cg@2188: ifFalse:[menu := aMenu]. cg@1988: cg@1988: self enablingCommitButtonsHolder value:false. ca@1606: root := listOfItems root. ca@1606: ca@1606: self withoutNotifyDo:[ cg@2188: selectionHolder setValue:#(). cg@2188: root menu:aMenu labeled:(aSelector ? specSelector). ca@1606: ]. ca@1606: self selectedItem:root. tz@734: self updateHistory. tz@734: ! tz@734: cg@2019: buildFromResourceSpec:aResourceSpec cg@2019: "rebuild the menu from a resource spec" cg@2019: cg@2019: self buildFromMenu:aResourceSpec selector:nil cg@2019: ! cg@2019: cg@1971: loadFromClass:aClass andSelector:aSelector cg@1971: "rebuild menu from a class and selector" cg@1971: cg@1971: |cls menu| cg@1971: cg@1971: self assert:(aClass isNil or:[aClass isClass]). cg@1971: cg@1971: menu := nil. cg@1971: cg@2188: self isStandAlone ifTrue:[ self helpTool loadFromClass:aClass ]. cg@1971: cg@1971: specClass := aClass. cg@1971: specSelector := aSelector. cg@1971: cg@1971: aSelector notNil ifTrue:[ cg@3013: aClass notNil ifTrue:[ cg@3013: cls := aClass isBehavior ifTrue:[ aClass ] ifFalse:[ self resolveName:aClass]. cg@3013: cg@3013: (cls respondsTo:aSelector) ifTrue:[ cg@3013: menu := cls perform: aSelector. cg@3013: ]. cg@3013: ]. cg@1971: ]. cg@2569: self loadFromMenu:menu selector:aSelector. cg@2569: ! cg@2569: cg@2569: loadFromMenu:menuArg selector:selectorOrNil cg@2569: "rebuild menu" cg@2569: cg@2569: |menu| cg@2569: cg@2569: menu := menuArg. cg@2569: menu notNil ifTrue:[ cg@3013: (menu isCollection) ifTrue:[ cg@3013: menu := Menu decodeFromLiteralArray:menu cg@3013: ]. cg@2569: ]. cg@2569: self buildFromMenu:menu selector:selectorOrNil. cg@1971: self clearModified. cg@2168: cg@2169: "Modified: / 27-03-2007 / 11:16:47 / cg" tz@728: ! ! tz@728: ca@199: !MenuEditor methodsFor:'change & update'! ca@199: ca@1606: selectedSuperItems ca@1606: "returns collection of superItems derived from selection ca@1606: " ca@1606: |selection size root| ca@1606: cg@2862: selectedSuperItems notNil ifTrue:[ ^ selectedSuperItems ]. ca@1606: ca@1606: selection := selectionHolder value. ca@1606: size := selection size. ca@1606: ca@1606: size <= 1 ifTrue:[ cg@3013: selectedSuperItems := selection ? #(). ca@1606: ^ selectedSuperItems ca@1606: ]. ca@1606: ca@1606: root := listOfItems root. ca@1606: ca@1606: (selection includesIdentical:root) ifTrue:[ cg@3013: selectedSuperItems := Array with:root. cg@2188: ^ selectedSuperItems ca@1606: ]. ca@1606: selectedSuperItems := OrderedCollection new. ca@1606: ca@1606: selection do:[:anItem| cg@3013: anItem parentsDetect:[:el| selection includesIdentical:el ] cg@3013: ifNone:[ selectedSuperItems add:anItem ]. ca@1606: ]. ca@1606: ^ selectedSuperItems cg@2862: cg@2862: "Modified: / 29-11-2011 / 11:28:23 / cg" ca@1606: ! ca@1606: ca@1606: selectionChanged ca@1606: "called if the selection has changed ca@1606: " ca@1606: |newTabList selection| ca@1606: ca@1606: selection := selectionHolder value. ca@1606: ca@1606: selection size == 1 ifTrue:[ cg@2188: selectedSuperItems := selection. cg@2188: cg@2188: newTabList := selection first slices collect:[:el| el first ]. cg@2188: newTabList = listOfTabs ifFalse:[ cg@2188: listOfTabs contents:newTabList. cg@2188: ]. ca@1606: ] ifFalse:[ cg@2188: "must compute selected super items on request cg@2188: " cg@2188: selectedSuperItems := nil. ca@1606: ]. ca@1606: self cancel. ca@1606: self tabChanged. ca@1606: self updateChannels. ca@1606: ! ca@1606: ca@1606: tabChanged cg@2593: "called if the tab changed" cg@2593: ca@1606: |tab selector item canvas wizardHolder| ca@1606: ca@1606: wizardHolder := self wizardHolder. ca@1606: item := self selectedItem. cg@3013: item isNil ifTrue:[ cg@3013: wizardHolder value:nil. cg@3013: ^ self cg@2593: ]. ca@1606: ca@1606: tab := tabHolder value. ca@1606: ca@1676: tab notNil ifTrue:[ cg@3013: tab := item slices detect:[:el| el first = tab ] ifNone:nil. ca@1606: ]. ca@1676: tab isNil ifTrue:[ cg@3013: tabHolder value:( listOfTabs at:1 ifAbsent:nil ). cg@3013: ^ self. ca@1606: ]. ca@1606: selector := tab last. ca@1606: cg@3013: selector == #help ifTrue:[ cg@3013: wizardHolder value:(self helpTool window). cg@3013: ^ self cg@2593: ]. cg@3013: selector == #image ifTrue:[ cg@3013: wizardHolder value:(self imageTool window). cg@3013: ^ self cg@2593: ]. cg@2593: cg@3013: canvas := wizards cg@3013: at:(item class name, selector) asSymbol cg@3013: ifAbsentPut:[ cg@3013: SimpleView new cg@3013: client:self cg@3013: spec:(item class perform:selector) cg@3013: builder:(self builder) cg@3013: ]. ca@1606: ca@1606: wizardHolder value:canvas. ca@1606: ! ca@1606: cg@970: update:something with:aParameter from:changedObject cg@1711: |lbl| cg@1711: ca@1606: notifyDisabledCounter ~~ 0 ifTrue:[ ^ self ]. ca@1606: ca@1606: changedObject == selectionHolder ifTrue:[ ^ self selectionChanged ]. ca@1606: changedObject == tabHolder ifTrue:[ ^ self tabChanged ]. ca@1606: cg@1711: changedObject == self autoAcceptOnSelectionChange ifTrue:[ cg@2188: lbl := changedObject value ifTrue:['Apply'] ifFalse:['OK']. cg@2188: (builder componentAt:'okButton') label:(resources string:lbl). cg@2188: ^ self cg@1711: ]. cg@1711: ca@1606: super update:something with:aParameter from:changedObject cg@970: ! cg@970: tz@748: updateChannels cg@2869: "update all channels" cg@2869: cg@2869: |selection sizeOfSel selectedItem hasSelection| ca@1606: ca@1606: super updateChannels. ca@1606: ca@1606: selection := selectionHolder value. ca@1606: sizeOfSel := selection size. ca@1606: cg@2869: hasSelection := sizeOfSel ~~ 0. ca@1606: sizeOfSel == 1 ifTrue:[selectedItem := selection at:1] cg@3013: ifFalse:[selectedItem := nil]. cg@2869: cg@2869: self hasSelectionChannel value:hasSelection. ca@1606: self hasSingleSelectionChannel value:(selectedItem notNil). ca@1606: ca@1606: selectedItem isNil ifTrue:[ cg@2869: "/ self enableMovingUpOrDownHolder value:false. cg@3013: self enableMovingInHolder value:false. cg@3013: self enableMovingOutHolder value:false. cg@3013: self enableMovingInAboveHolder value:false. cg@3013: self canCreateDelayedMenuChannel value:false. ca@1244: ] ifFalse:[ cg@2869: "/ self enableMovingUpOrDownHolder value:(selectedItem canMoveUpOrDown). cg@3013: self enableMovingInHolder value:(selectedItem canMoveInNext). cg@3013: self enableMovingOutHolder value:(selectedItem canMoveOut). cg@3013: self enableMovingInAboveHolder value:(selectedItem canMoveInAbove). cg@3013: self canCreateDelayedMenuChannel value:(selectedItem canAddDelayedMenu). tz@902: ]. cg@2869: self enableMovingUpOrDownHolder value:(selection conform:[:i | i canMoveUpOrDown]). cg@2869: cg@2869: "Modified (comment): / 18-01-2012 / 11:24:07 / cg" ca@220: ! ! ca@220: ca@1606: !MenuEditor methodsFor:'drag & drop'! ca@1606: cg@2118: canDrop:aDropContext ca@1618: "return true, if the DropContext can be dropped into the list of items. cg@1953: The dropable objects are already validated by: #dropEnter:" cg@1953: ca@1618: ^ (dropOverLine notNil and:[dropOverLine ~~ 0]) cg@2118: cg@2118: "Modified: / 13-10-2006 / 16:03:47 / cg" ca@1618: ! ca@1618: ca@1618: changeDropLineTo:aLineOrNil in:aContext ca@1618: "the over dropLine changed; redraw drop indication stuff ca@1244: " ca@1618: |x0 x1 y0| ca@1618: ca@1618: aLineOrNil == dropOverLine ifTrue:[ cg@2188: ^ self. "/ nothing changed ca@1244: ]. ca@1618: x0 := listOfItemsView margin + 2. ca@1618: x1 := listOfItemsView width - x0. ca@1618: ca@1618: "/ inform the DragAndDrop handler that the draw contents will change ca@1618: aContext contentsWillChange. ca@1618: ca@1618: (dropOverLine notNil and:[dropOverLine ~~ 0]) ifTrue:[ cg@2188: "/ restore old draw cg@2188: y0 := listOfItemsView yVisibleOfLine:(dropOverLine + 1). cg@2188: y0 := y0 - 3. cg@2188: cg@2188: listOfItemsView invalidate:(Rectangle left:x0 top:y0 width:(x1-x0+1) height:2) cg@2188: repairNow:true. ca@1606: ]. ca@1618: ca@1618: dropOverLine := aLineOrNil. ca@1618: ca@1618: (dropOverLine notNil and:[dropOverLine ~~ 0]) ifTrue:[ cg@2188: "/ highlight new drop target cg@2188: y0 := listOfItemsView yVisibleOfLine:(dropOverLine + 1). cg@2188: y0 := y0 - 3. cg@2188: cg@2188: listOfItemsView paint:(Color white). cg@2188: listOfItemsView displayLineFromX:x0 y:y0 toX:x1 y:y0. cg@2188: y0 := y0 + 1. cg@2188: listOfItemsView paint:(Color black). cg@2188: listOfItemsView displayLineFromX:x0 y:y0 toX:x1 y:y0. ca@1618: ]. ca@1606: ! ca@1606: cg@2118: doDrop:aDropContext cg@1702: "drop the dropContext into the hierachical list of items ca@1244: " ca@1618: |done item| ca@1618: cg@2151: dropOverLine isNil ifTrue:[^ false ]. "/ context not valid to me ... ca@1618: ca@1618: item := listOfItems at:dropOverLine ifAbsent:nil. cg@2118: self dropLeave:aDropContext. cg@2151: item isNil ifTrue:[^ false]. ca@1618: ca@1618: selectionHolder setValue:(Array with:item). ca@1618: ca@1618: done := false. ca@1618: cg@1702: self addAndSelectValueOf:[ cg@2188: done := true. cg@2188: aDropContext dropObjects collect:[:el| Item menuItem:(el theObject) ] ca@1618: ]. ca@1618: ^ done cg@2118: cg@2118: "Modified: / 13-10-2006 / 16:03:54 / cg" cg@2118: ! cg@2118: cg@2118: dropEnter:aDropContext ca@1618: "a drop operation enters my widget; validate dropable objects. ca@1618: If the objects are not dropable, dropOverLine is set to nil, ca@1618: otherwise to 0 (can drop the contents but not). ca@1618: " ca@1606: |objects| ca@1606: ca@1618: dropOverLine := nil. ca@1618: cg@1988: self enablingCommitButtonsHolder value ifTrue:[ cg@2188: "/ current editing spec is modified (couldn't accept operation) cg@2188: ^ self ca@1618: ]. cg@2118: objects := aDropContext dropObjects. ca@1618: objects isEmpty ifTrue:[ ^ self ]. "/ nothing to drop ??? ca@1618: ca@1618: "/ test whether all objects are dropable (kind of MenuItem) cg@2113: (objects conform:[:el | (el theObject askFor:#isMenuItem)]) ifTrue:[ cg@2188: "/ ok, the contents is dropable cg@2188: dropOverLine := 0. cg@2113: ] cg@2113: cg@2118: "Modified: / 13-10-2006 / 16:04:14 / cg" cg@2118: ! cg@2118: cg@2118: dropLeave:aDropContext cg@2729: "restore drop indications drawn..." cg@2729: cg@2118: self changeDropLineTo:nil in:aDropContext. cg@2118: cg@2118: "Modified: / 13-10-2006 / 16:03:59 / cg" tz@879: ! tz@879: ca@1606: dropObjects ca@1606: "returns list of DropObjects ca@1606: " ca@1606: |obj items| ca@1606: ca@1606: items := self selectedSuperItems. ca@1606: items isEmpty ifTrue:[ ^ nil ]. ca@1606: ca@1606: ^ items collect:[:el| cg@2188: obj := DropObject new:(el menuItem). cg@2188: obj displayObject:(el rawLabel). cg@2188: obj ca@199: ]. ca@1618: ! ca@1618: cg@2118: dropOver:aDropContext cg@1685: "called during drag & drop while moving over the widget." cg@1685: ca@1618: |lnNr item| ca@1618: cg@2151: dropOverLine isNil ifTrue:[^ self ]. "/ context not valid to me ... ca@1618: cg@3566: lnNr := listOfItemsView yVisibleToLineNr:(aDropContext targetPointInDeviceCoordinates y). ca@1618: item := nil. ca@1618: cg@2862: lnNr notNil ifTrue:[ cg@3566: item := listOfItems at:lnNr ifAbsent:nil. cg@3566: item notNil ifTrue:[ cg@3566: (item isAction and:[item hasDelayedMenu]) ifTrue:[ cg@3566: item := nil cg@3566: ] cg@3566: ] ca@1618: ]. cg@2151: item isNil ifTrue:[ lnNr := 0 ]. "/ not dropable for item ca@1618: ca@1618: "/ redraw drop indication cg@2118: self changeDropLineTo:lnNr in:aDropContext. cg@2118: cg@2862: "Modified: / 29-11-2011 / 11:28:17 / cg" cg@3566: "Modified: / 15-06-2018 / 02:27:44 / Claus Gittinger" ca@1606: ! ! ca@1606: ca@1606: !MenuEditor methodsFor:'event processing'! ca@1606: ca@1606: processEvent:anEvent cg@1895: "filter keyboard edit-events typed into the listOfItemsView. cg@1895: Return true, if I have eaten the event" cg@1895: cg@2946: cg@2946: cg@2275: |evView rawKey key| ca@1606: cg@2187: anEvent isKeyPressEvent ifFalse:[^ false]. ca@1606: cg@3636: key := anEvent key. cg@3636: ca@1606: evView := anEvent targetView. cg@3636: evView isNil ifTrue:[^ false ]. ca@1606: cg@2263: "/ only handle keyboard events for the left item list cg@2263: "/ (otherwise, copy-paste would not work in the editFields on the right) cg@3636: (evView isSameOrComponentOf:listOfItemsView) ifFalse:[ cg@3636: key == #Accept ifTrue:[ cg@3636: self accept. cg@3636: ]. cg@3636: ^ false cg@3636: ]. cg@3636: ca@1606: rawKey := anEvent rawKey. ca@1606: ca@1606: ( key == #Delete ca@1606: or:[key == #BackSpace ca@1606: or:[key == #Cut]] ca@1606: ) ifTrue:[ cg@3636: self doCut. cg@3636: ^ true. ca@199: ]. cg@1256: ca@1606: key == #Copy ifTrue:[ self doCopy. ^ true ]. ca@1606: key == #Paste ifTrue:[ self doPaste. ^ true ]. ca@1606: cg@2188: (rawKey == #CtrlCursorUp) ifTrue:[ cg@3636: self doMoveUp. cg@3636: ^ true. cg@1958: ]. cg@2188: (rawKey == #CtrlCursorDown) ifTrue:[ cg@3636: self doMoveDown. cg@3636: ^ true. cg@1958: ]. cg@2188: (rawKey == #CtrlCursorLeft) ifTrue:[ cg@3636: self doMoveOut. cg@3636: ^ true. cg@1958: ]. cg@2188: (rawKey == #CtrlCursorRight) ifTrue:[ cg@3636: self doMoveInNext. cg@3636: ^ true. cg@1958: ]. cg@1958: cg@1958: ^ false. cg@3636: cg@3636: "Modified: / 12-02-2019 / 10:56:08 / Claus Gittinger" ca@1606: ! ! ca@1606: ca@1606: !MenuEditor methodsFor:'initialization & release'! ca@1606: ca@1606: closeRequest cg@2036: "asks for permission before closing" cg@2036: cg@2075: self askForModification ifFalse:[^self]. cg@2075: cg@2075: "/ self enablingCommitButtonsHolder value ifTrue:[ cg@2075: "/ self setModified. cg@2075: "/ self askForListModification. cg@2075: "/ modified ifTrue:[^ self]. cg@2075: "/ self clearModified. cg@2075: "/ ]. cg@2036: super closeRequest cg@2075: cg@2075: "Modified: / 05-09-2006 / 18:44:15 / cg" ca@1606: ! ca@199: cg@1992: commonPostBuild cg@1992: self autoAcceptOnSelectionChange addDependent:self. cg@1992: self autoAcceptOnSelectionChange value ifTrue:[ sv@3536: (builder componentAt:'okButton') label:(resources string:'Apply') cg@1992: ]. cg@1992: cg@1997: "/ using masters infoHolder ? sv@3541: self useAlienInfoLabel ifTrue:[ sv@3536: (builder componentAt:#mainPanel) layout bottomOffset:0. sv@3536: (builder componentAt:#infoBarSubSpec) beInvisible cg@1997: ] sv@3536: sv@3536: "Modified: / 20-02-2018 / 13:05:21 / stefan" cg@1992: ! cg@1992: cg@2581: commonPostOpen cg@2581: "reset keyboardProcessor for menuBar" cg@2581: cg@2581: super commonPostOpen. cg@2581: builder keyboardProcessor menuBar:nil. cg@2581: self windowGroup addPreEventHook:self. cg@2581: ! cg@2581: tz@738: initialize ca@1606: "setup aspects, ... ca@1606: " tz@738: super initialize. ca@1606: notifyDisabledCounter := 0. ca@1606: ca@1606: Item withAllSubclasses do:[:aClass| cg@2188: aClass addBindingsTo:aspects for:self. ca@1606: ]. ca@1606: ca@1606: selectionHolder := #() asValue. ca@1606: selectionHolder addDependent:self. ca@1606: ca@1606: listOfItems := HierarchicalList new. ca@1606: listOfItems application:self. cg@1631: listOfItems root:(RootItem new). ca@1606: ca@1606: tabHolder := nil asValue. ca@1606: tabHolder addDependent:self. ca@1606: ca@1606: listOfTabs := List new. ca@1606: wizards := IdentityDictionary new. tz@738: ! tz@738: cg@2569: loadFromResourceSpec:aResourceSpec cg@2569: self loadFromMenu:aResourceSpec selector:nil cg@2569: ! cg@2569: cg@2569: openModalOnMenu:aMenuOrNil cg@2569: "build a tree from aMenu and open it modal" cg@2569: cg@2569: self openModalOnResourceSpec:aMenuOrNil ca@1606: ! ca@1606: ca@1618: postBuildListOfItemsView:aSrollableView ca@1618: listOfItemsView := aSrollableView scrolledView. ca@1250: ! ca@1250: ca@1676: postBuildNoteBook:aNoteBook ca@1676: aNoteBook tabLabelInset:16@4. ca@199: ! ! ca@199: cg@2275: !MenuEditor methodsFor:'menus-dynamic'! cg@2275: cg@2275: submenuTest cg@2275: "returns a menu on the current editing menu cg@2275: " cg@2275: |menu indication choice submenu retriever| cg@2275: cg@2275: menu := listOfItems root submenu. cg@2275: menu isNil ifTrue:[^ nil ]. cg@2275: cg@2275: menu allItemsDo:[:anItem| cg@3138: anItem ignoreShortcutKeys:true. cg@3138: anItem isVisible:true. cg@3138: anItem enabled:true. cg@3138: anItem translateLabel:false. cg@3138: cg@3138: anItem itemValue notNil ifTrue:[ cg@3138: anItem itemValue:[ Transcript showCR:(anItem label) ]. cg@3138: ]. cg@3138: anItem indication notNil ifTrue:[ cg@3138: indication isNil ifTrue:[ indication := true asValue ]. cg@3138: anItem indication:indication cg@3138: ]. cg@3138: anItem choice notNil ifTrue:[ cg@3138: choice isNil ifTrue:[ choice := anItem choiceValue asValue ]. cg@3138: anItem choice:choice cg@3138: ]. cg@3138: anItem isMenuSlice ifTrue:[ cg@3138: anItem submenuChannel:nil. cg@3138: anItem label:'... Slice Menu ...'. cg@3138: ]. cg@3138: anItem submenuChannel notNil ifTrue:[ cg@3138: anItem submenuChannel:nil. cg@3138: anItem submenu isNil ifTrue:[ cg@3138: submenu isNil ifTrue:[ cg@3138: submenu := Menu new. cg@3138: submenu addItem:(MenuItem label:'Linked Menu...'). cg@3138: ]. cg@3138: anItem submenu:submenu. cg@3138: ]. cg@3138: ]. cg@3138: retriever := anItem resourceRetriever. cg@3138: retriever notNil ifTrue:[ cg@3138: retriever labelText notNil ifTrue:[ retriever labelText:(anItem label) ] cg@3138: ]. cg@2275: ]. cg@2275: menu findGuiResourcesIn:(self resolveName:specClass). cg@2275: ^ menu cg@2275: ! ! cg@2275: ca@1606: !MenuEditor methodsFor:'private'! ca@1606: cg@1702: addAndSelectValueOf:aBlockOrItem ca@1606: "add an item(s) derived from the block; test if add operation ca@1606: is enabled. On success the new item(s) are returned otherwise nil. ca@1606: " ca@1606: |intoItem index newItem| ca@1606: ca@1606: intoItem := self selectedItem. cg@2151: intoItem isNil ifTrue:[ ^ nil]. ca@1606: ca@1606: self askForItemModification ifFalse:[ ^ nil ]. ca@1606: ca@1606: index := 1. ca@1606: ca@1618: (intoItem canAddChildren and:[intoItem isExpanded]) ifFalse:[ cg@3013: intoItem parent notNil ifTrue:[ cg@3013: [ intoItem parent canAddChildren ] whileFalse:[ cg@3013: intoItem := intoItem parent. cg@3013: ]. cg@3013: index := intoItem parent identityIndexOf:intoItem. cg@3013: index := index + 1. cg@3013: intoItem := intoItem parent. cg@3013: ]. ca@1606: ]. cg@1702: newItem := aBlockOrItem value. ca@1606: cg@2862: newItem notNil ifTrue:[ cg@3013: selectionHolder setValue:nil. cg@3013: intoItem expand. cg@3013: cg@3013: newItem isCollection ifTrue:[ cg@3013: intoItem addAll:newItem beforeIndex:index. cg@3013: selectionHolder value:newItem. cg@3013: ] ifFalse:[ cg@3013: intoItem add:newItem beforeIndex:index. cg@3013: selectionHolder value:(Array with:newItem). cg@3013: ]. cg@3013: self setModified. ca@1606: ]. ca@1606: ^ newItem cg@2862: cg@2862: "Modified: / 29-11-2011 / 11:28:06 / cg" tz@407: ! tz@407: ca@1606: clearModified cg@1971: "clear the modifiedChannel and the commitPanel" cg@1971: cg@2008: super clearModified. cg@1988: self enablingCommitButtonsHolder value:false. cg@1189: self clearModifiedFlag. tz@407: ! tz@407: ca@1606: generateMenuSpec cg@2569: "generate and returns the current menu spec or nil" cg@2569: cg@3135: ^ self generateMenuSpecFor:listOfItems root cg@3135: ! cg@3135: cg@3135: generateMenuSpecFor:aMenuItem cg@3135: "generate and returns a menu spec or nil" cg@3135: cg@2569: |menu| ca@1606: cg@3135: menu := aMenuItem submenu. cg@2151: menu isNil ifTrue:[^ nil]. cg@2569: cg@2569: ^ menu literalArrayEncoding. cg@2569: ! cg@2569: cg@2569: generateMenuSpecString cg@2569: "generate and returns the current menu spec as string or nil" cg@2569: cg@3135: ^ self generateMenuSpecStringFor:listOfItems root cg@3135: ! cg@3135: cg@3135: generateMenuSpecStringFor:aMenuItem cg@3135: "generate and returns the current menu spec as string or nil" cg@3135: cg@2569: |menu specStream| cg@2569: cg@3135: menu := self generateMenuSpecFor:aMenuItem. cg@2569: menu isNil ifTrue:[^ nil]. cg@2569: sv@3328: specStream := WriteStream on:''. cg@2569: UISpecification prettyPrintSpecArray:menu on:specStream indent:5. cg@2569: ^ specStream contents. ca@1606: ! ca@1606: ca@1606: withoutNotifyDo:aBlock ca@1606: "evaluate the block; all change notifications are sv@1722: discard during the block is evaluated" sv@1722: ca@1606: |blockResult| ca@1606: cg@2188: [ cg@2188: notifyDisabledCounter := notifyDisabledCounter + 1. cg@2188: blockResult := aBlock value. sv@1722: ] ensure:[ cg@2188: notifyDisabledCounter := notifyDisabledCounter - 1 cg@2188: ]. ca@1606: ^ blockResult ca@1606: ! ! ca@1606: ca@1606: !MenuEditor methodsFor:'queries'! ca@1606: ca@1606: hasValidSpecClass ca@1606: "returns true if a valid specClass exists ca@1606: " cg@2151: specClass isNil ifTrue:[^ false]. cg@3353: ^ (self resolveName:specClass) notNil cg@3353: cg@3353: "Modified: / 19-11-2016 / 20:19:30 / cg" cg@2569: ! cg@2569: cg@2569: isEditingSpecOnly cg@2581: ^ masterApplication notNil cg@2581: and:[ masterApplication perform:#isEditingSpecOnly ifNotUnderstood:false] cg@2569: ! cg@2569: cg@2569: isNotEditingSpecOnly cg@2569: ^ self isEditingSpecOnly not cg@2581: ! cg@2581: cg@2581: isNotEditingSpecOnlyAndNotEmbeddedInBrowser cg@2581: ^ self isNotEditingSpecOnly and:[ self isEmbeddedInBrowser not ] ca@1606: ! ! ca@1606: ca@1606: !MenuEditor methodsFor:'selection'! ca@1606: ca@1606: canSelect:anIndex ca@1606: "called whenever the selection changed; test whether ca@1606: current item is not modified .... ca@1606: " cg@1711: |oldSelectedItem newSelectedItem anythingChanged| ca@1606: cg@1988: self enablingCommitButtonsHolder value ifFalse:[ cg@2188: ^ true ca@1606: ]. ca@1606: oldSelectedItem := self selectedItem. cg@2151: oldSelectedItem isNil ifTrue:[^ true]. ca@1606: ca@1606: newSelectedItem := listOfItems at:anIndex ifAbsent:nil. ca@1606: oldSelectedItem == newSelectedItem ifTrue:[ cg@2188: ^ true ca@1606: ]. cg@1711: cg@1988: anythingChanged := self enablingCommitButtonsHolder value. cg@2188: anythingChanged ifTrue:[ cg@2188: self autoAcceptOnSelectionChange value ifTrue:[ cg@2188: self accept. cg@2188: ^ true cg@2188: ]. cg@1711: ]. cg@1711: ca@1606: ^ self askForItemModification tz@879: ! tz@879: ca@1610: hasSelection ca@1610: "returns true if a selection exists ca@1610: " ca@1610: ^ selectionHolder value size ~~ 0 ca@1610: ! ca@1610: ca@1606: selectedItem cg@2869: "returns the selected item or nil (none or multiple selected)" cg@2869: ca@1606: |selection| ca@1606: ca@1606: selection := selectionHolder value. ca@1606: selection size == 1 ifTrue:[ ^ selection first ]. cg@2869: ^ nil cg@2869: cg@2869: "Modified: / 18-01-2012 / 11:33:42 / cg" ca@1606: ! ca@1606: ca@1606: selectedItem:anItem ca@1606: "change selection to an item ca@1606: " ca@1606: |selection| ca@1606: ca@1606: anItem notNil ifTrue:[ selection := Array with:anItem ] ca@1606: ifFalse:[ selection := #() ]. ca@1606: ca@1606: selectionHolder value:selection. cg@2869: ! cg@2869: cg@2869: selectedItems cg@2869: "returns the selected items or an empty collection" cg@2869: cg@2869: ^ selectionHolder value. cg@2869: cg@2869: "Created: / 18-01-2012 / 11:32:20 / cg" cg@2869: ! cg@2869: cg@2869: selectedItems:aCollectionOfItems cg@2869: "set the selected items" cg@2869: cg@2869: selectionHolder value:aCollectionOfItems. cg@2869: cg@2869: "Created: / 18-01-2012 / 11:32:37 / cg" ca@1606: ! ! ca@1606: cg@1715: !MenuEditor methodsFor:'user actions-aspects'! ca@1614: ca@1614: collectActionSelectors ca@1614: |selectors| ca@1614: ca@1614: selectors := IdentitySet new. ca@1614: ca@1614: listOfItems root recursiveDo:[:el| cg@2188: el actionSelectors do:[:s| selectors add:s ]. ca@1614: ]. ca@1614: ^ selectors asOrderedCollection ca@1614: ! ca@1614: ca@1614: collectAspectSelectors ca@1614: |selectors| ca@1614: ca@1614: selectors := IdentitySet new. ca@1614: ca@1614: listOfItems root recursiveDo:[:el| cg@3013: selectors addAll:(el aspectSelectors). ca@1614: ]. ca@1614: ^ selectors asOrderedCollection ca@1614: ! ca@1614: cg@2297: doBrowseActionMethod cg@3029: "open a browser on the action callback method (create if not yet existing)" cg@2810: cg@2810: self doBrowseApplicationMethodFor:#itemValue cg@2810: cg@2810: "Modified: / 21-10-2010 / 14:09:33 / cg" cg@2810: ! cg@2810: cg@2810: doBrowseApplicationMethodFor:aspect cg@3028: |selector cls implClass browsedClass category| cg@2297: cg@2810: specClass isNil ifTrue:[ cg@3585: self warn:('Please define the application class first.'). cg@3026: ^ self cg@2297: ]. cg@2297: cg@3237: selector := (self aspectValueFor:aspect). cg@2810: selector isEmptyOrNil ifTrue:[ cg@3029: Dialog information:(resources string:'Missing name for the action/aspect method.'). cg@3026: ^ self cg@2297: ]. cg@2810: (selector = 'true' or:[selector = 'false']) ifTrue:[^ self]. cg@2810: (selector == true or:[selector == false]) ifTrue:[^ self]. cg@2810: cg@2810: selector := selector asSymbol. cg@2297: cg@2297: cls := self resolveName:specClass. cg@2297: cls isNil ifTrue:[ cg@3026: self warn:(resources string:'Class %1 does not exist!!' with:specClass asString). cg@3026: ^ self cg@2297: ]. cg@2297: cg@3028: browsedClass := cls. cg@2630: (cls includesSelector:selector) ifFalse:[ jan@3099: | generate | cg@3028: (implClass := cls whichClassImplements:selector) notNil ifTrue:[ jan@3099: generate := (Dialog cg@3029: confirm:(resources cg@3029: stringWithCRs:'The application does not directly implement %1.\However it inherits this from %2.\\Create a redefinition in %1?' cg@3029: with:cls name cg@3029: with:implClass name) cg@3029: initialAnswer:false) jan@3099: ] ifFalse:[ jan@3099: generate := true. jan@3099: ]. jan@3099: category := UserPreferences current categoryForMenuActionsMethods. jan@3099: jan@3099: SmalltalkCodeGeneratorTool jan@3099: createActionMethodFor:selector in:cls jan@3099: category:category jan@3099: redefine:(self redefineAspectMethodsChannel value). cg@2297: ]. cg@2297: cg@3243: browsedClass browserClass openInClass:browsedClass selector:selector cg@2810: cg@2810: "Created: / 21-10-2010 / 14:07:32 / cg" cg@2833: "Modified: / 31-01-2011 / 18:28:59 / cg" jan@3099: "Modified: / 17-03-2014 / 12:25:37 / Jan Vrany " cg@3585: "Modified: / 09-08-2018 / 15:31:11 / Claus Gittinger" cg@2810: ! cg@2810: cg@3029: doBrowseChoiceMethod cg@3029: "open a browser on the choice aspect method (create if not yet existing)" cg@3029: cg@3029: self doBrowseApplicationMethodFor:#choice cg@3029: ! cg@3029: cg@2810: doBrowseEnabledMethod cg@2810: "open a browser on the enabled method (create if not yet existing)" cg@2810: cg@2810: self doBrowseApplicationMethodFor:#enabled cg@2810: cg@2810: "Created: / 21-10-2010 / 14:09:41 / cg" cg@2810: ! cg@2810: cg@3029: doBrowseIndicationMethod cg@3029: "open a browser on the indicator aspect method (create if not yet existing)" cg@3029: cg@3029: self doBrowseApplicationMethodFor:#indication cg@3029: ! cg@3029: cg@2810: doBrowseVisibilityMethod cg@2810: "open a browser on the visibility method (create if not yet existing)" cg@2810: cg@2810: self doBrowseApplicationMethodFor:#isVisible cg@2810: cg@2810: "Created: / 21-10-2010 / 14:09:56 / cg" cg@2297: ! cg@2297: ca@1614: doGenerateAspectMethods cg@1805: "compile aspect and action methods" cg@1805: cg@1805: |cls redefineAspectMethods category| ca@1614: cg@2151: specClass isNil ifTrue:[ cg@3013: self warn:'Define the class first !!'. cg@3013: ^ self ca@1614: ]. ca@1617: redefineAspectMethods := self redefineAspectMethodsChannel value. ca@1614: ca@1614: cls := self resolveName:specClass. cg@2151: cls isNil ifTrue:[ cg@3013: self warn:'Class ', specClass asString, ' does not exist!!'. cg@3013: ^ self ca@1614: ]. ca@1617: cg@1805: category := UserPreferences current categoryForMenuActionsMethods. cg@1805: ca@1617: self collectActionSelectors do:[:aSelector| cg@3013: SmalltalkCodeGeneratorTool cg@3013: createActionMethodFor:aSelector in:cls cg@3013: category:category cg@3013: redefine:redefineAspectMethods. ca@1614: ]. ca@1617: ca@1617: self collectAspectSelectors do:[:anAspect| cg@3013: SmalltalkCodeGeneratorTool cg@3013: createAspectMethodFor:anAspect in:cls cg@3013: category:category cg@3013: redefine:redefineAspectMethods ca@1614: ]. cg@2833: cg@2833: "Modified: / 31-01-2011 / 18:29:06 / cg" ca@1614: ! ! ca@1614: cg@1715: !MenuEditor methodsFor:'user actions-building'! ca@1606: cg@3135: compileSpecMethodFor:aMenuItem selector:specSelector cg@3135: "save current editing menu to cg@3135: class: specClass cg@3135: selector: specSelector cg@3135: " cg@3135: |cls specCode mthd category s| cg@3135: cg@3135: specCode := self generateMenuSpecStringFor:aMenuItem. cg@3135: specCode isNil ifTrue:[^ nil]. cg@3135: cg@3135: cls := self resolveName:specClass. cg@3135: cg@3135: "/ if that method already exists, do not overwrite the category cg@3135: cg@3135: category := 'menu specs'. cg@3135: (mthd := cls theMetaclass compiledMethodAt:specSelector) notNil ifTrue:[ cg@3135: category := mthd category. cg@3135: ]. cg@3135: cg@3135: s := '' writeStream. cg@3135: cg@3135: s nextPutChunkSeparator; cg@3135: nextPutAll:(cls name); cg@3135: nextPutAll:' class methodsFor:'; cg@3135: nextPutAll:category storeString; cg@3135: nextPutChunkSeparator; cg@3135: cr; cr; cg@3135: nextPutAll:specSelector; cg@3135: cr; cg@3135: nextPutAllAsChunk:(self class codeGenerationComment) withCRs; cg@3135: cr; cr; cg@3135: nextPutLine:' "'; cg@3135: nextPutLine:(' MenuEditor new openOnClass:' , cls name , ' andSelector:#' , specSelector); cg@3135: nextPutLine:(' (Menu new fromLiteralArrayEncoding:(' , cls name , ' ' , specSelector , ')) startUp'); cg@3135: nextPutLine:' "'; cg@3135: cr; cg@3135: nextPutLine:' '; cg@3135: cr; cg@3135: nextPutAll:' ^ '; cg@3135: nextChunkPut:specCode; cg@3135: space; cg@3135: nextPutChunkSeparator; cg@3135: cr. cg@3135: cg@3135: Class packageQuerySignal answer:cls package do:[ cg@3135: (ReadStream on:s contents) fileIn. cg@3135: ]. cg@3135: ! cg@3135: cg@2331: doChooseAMenu cg@2331: "pick a menu and edit its spec method" cg@2331: cg@2331: |view subSpec app bldr spec menuSelector1 menuSelector2 info| cg@2331: cg@2331: self askForModification ifTrue:[ cg@3013: view := Screen current viewFromUser. cg@3013: (view isNil or:[view == Screen current rootView]) ifTrue:[ cg@3013: ^ self cg@3013: ]. cg@3013: view specClass == MenuPanelSpec ifTrue:[ cg@3013: (app := view application) isNil ifTrue:[ cg@3013: info := 'Could not figure out the application class.' cg@3013: ] ifFalse:[ cg@3013: (bldr := app builder) isNil ifTrue:[ cg@3013: info := 'Application has no builder.' cg@3013: ] ifFalse:[ cg@3013: menuSelector1 := bldr namedComponents keyAtValue:view ifAbsent:nil. cg@3013: (spec := bldr spec) isNil ifTrue:[ cg@3013: info := 'Cannot fetch spec from applications builder.' cg@3013: ] ifFalse:[ cg@3013: subSpec := spec findSpecForWhich:[:subSpec | subSpec name = view name]. cg@3013: subSpec isNil ifTrue:[ cg@3013: info := 'Cannot find view-spec for ',view name asString,'.' cg@3013: ] ifFalse:[ cg@3013: menuSelector2 := subSpec menu. cg@3013: ] cg@3013: ]. cg@3013: (menuSelector1 isNil and:[ menuSelector2 isNil ]) ifTrue:[ cg@3013: info := 'menu is probably not provided by a menuSelector.' cg@3013: ] ifFalse:[ cg@3013: (app class respondsTo:menuSelector1) ifTrue:[ cg@3013: self loadFromClass:app class andSelector:menuSelector1. cg@3013: ^ self. cg@3013: ]. cg@3013: (app class respondsTo:menuSelector2) ifTrue:[ cg@3013: self loadFromClass:app class andSelector:menuSelector2. cg@3013: ^ self. cg@3013: ]. cg@3013: info := 'menu is probably not provided by a menuSelector.' cg@3013: ]. cg@3013: ] cg@3013: ]. cg@3013: info notNil ifTrue:[ cg@3013: app notNil ifTrue:[ cg@3013: (Dialog confirm:(info,'\\Browse ?' withCRs)) ifTrue:[ cg@3013: app browse. cg@3013: ]. cg@3013: ] ifFalse:[ cg@3013: Dialog information:info. cg@3013: ]. cg@3013: ]. cg@3013: ^ self. cg@3013: ]. cg@2331: ]. cg@2331: ! cg@2331: tz@633: doNew ca@1606: "clear editing menu; start from scratch ca@1606: " ca@1606: super doNew ifTrue:[ self helpTool doNew ]. ca@199: ! ca@199: tz@633: doPickAMenu cg@2331: "let user pick a menu and create a new spec" cg@1971: tz@633: |view| tz@633: ca@1244: self askForModification ifTrue:[ cg@3013: view := Screen current viewFromUser. cg@3013: (view isNil or:[view == Screen current rootView]) ifTrue:[ cg@3013: ^ self cg@3013: ]. cg@3013: view specClass == MenuPanelSpec ifTrue:[ cg@3013: specSelector := #pickedMenu. cg@3013: self buildFromMenu:(view asMenu) selector:specSelector. cg@3013: ]. tz@633: ]. tz@888: ! tz@888: tz@633: doSave ca@1606: "save current editing menu to sv@3016: class: specClass sv@3016: selector: specSelector sv@3016: " cg@2569: self isEditingSpecOnly ifTrue:[ sv@3016: savedSpec := self generateMenuSpec. sv@3016: hasSaved := true. sv@3016: self clearModified. sv@3016: ^ self cg@2569: ]. ca@199: tz@642: super doSave ifFalse: [^nil]. cg@3135: cg@3135: self compileSpecMethodFor:listOfItems root selector:specSelector. ca@1669: self isStandAlone ifTrue:[ sv@3016: self helpTool doSave ca@1669: ]. tz@699: tz@633: self updateHistory. tz@633: hasSaved := true. cg@1971: self clearModified. cg@2856: cg@3075: "Modified: / 28-01-2014 / 21:57:24 / cg" ca@199: ! ca@199: tz@633: doSaveAs ca@1606: "save current editing menu to class and selector ca@1606: defined by the user. ca@1606: " ca@1606: super doSaveAs ifTrue:[ ca@1606: listOfItems root rawLabel:specSelector ca@1606: ]. ca@1606: ! ca@1606: ca@1606: doShowMenuSpec cg@2569: "opens a code view with the contents of the menu spec" cg@2569: cg@2569: |code| cg@2569: cg@2569: code := self generateMenuSpecString. cg@2569: cg@2862: code notNil ifTrue:[ cg@3013: CodeView openWith:code title: 'Menu Spec' ca@1606: ]. cg@2862: cg@2862: "Modified: / 29-11-2011 / 11:28:12 / cg" cg@1971: ! cg@1971: cg@1971: save cg@1971: self doSave ca@1606: ! ! ca@1606: cg@1715: !MenuEditor methodsFor:'user actions-creation'! ca@1606: ca@1606: doCreateDelayedMenu:what ca@1606: |selectedItem delayedItem| ca@1606: ca@1606: selectedItem := self selectedItem. cg@2151: selectedItem isNil ifTrue:[^ self]. ca@1606: ca@1606: selectedItem canAddDelayedMenu ifFalse:[ ^ self ]. ca@1606: self askForItemModification ifFalse:[ ^ self ]. ca@1606: ca@1633: what == #menu ifTrue:[ delayedItem := RegularMenuItem new ] cg@3013: ifFalse:[ delayedItem := LinkedMenuItem new ]. ca@1606: ca@1606: delayedItem setExpanded:true. ca@1606: delayedItem := selectedItem add:delayedItem. ca@1606: cg@2862: delayedItem notNil ifTrue:[ cg@3013: self selectedItem:delayedItem. ca@1606: ]. cg@2862: cg@2862: "Modified: / 29-11-2011 / 11:28:09 / cg" ca@1606: ! ca@1606: ca@1606: doCreateItem ca@1606: "create a new Item ca@1606: " cg@1702: self addAndSelectValueOf:[ ActionItem new translateLabel:true ]. ca@1606: ! ca@1606: ca@1606: doCreateLinkedMenu ca@1606: "create a new Linked Menu ca@1606: " cg@1702: self addAndSelectValueOf:[ LinkedMenuItem new ]. ca@1606: ! ca@1606: ca@1606: doCreateMenu ca@1606: "create a new Menu ca@1606: " cg@1702: self addAndSelectValueOf: cg@2188: [ |item| cg@2188: item := RegularMenuItem new. cg@2188: "/ --- do not add it expanded - because that makes it hard to add multipe menus cg@2188: "/ item expand. cg@2188: item cg@2188: ]. ca@1606: ! ca@1606: ca@1844: doCreateMenuSliceItem ca@1844: "create a new MenuSlice Item ca@1844: " ca@1844: self addAndSelectValueOf:[ MenuSliceItem new ]. ca@1844: ! ca@1844: ca@1606: doCreateSep ca@1606: "create a new Separator Item ca@1606: " cg@1702: self addAndSelectValueOf:[ SeparatorItem new ]. ca@1606: ! ca@1606: ca@1606: doCreateStandardEditMenu cg@2345: "create a standard edit menu ca@1606: " cg@1702: self addAndSelectValueOf:[ cg@3013: RegularMenuItem menu:(self class standardEditMenu) labeled:'Edit' translateLabel:true ca@1606: ]. ca@218: ! ca@199: ca@1606: doCreateStandardFileMenu cg@2345: "create a standard file menu ca@1606: " cg@1702: self addAndSelectValueOf:[ cg@3013: RegularMenuItem menu:(self class standardFileMenu) labeled:'File' translateLabel:true ca@1606: ]. ca@1606: ! ca@1606: ca@1606: doCreateStandardHelpMenu cg@2345: "create a standard help menu ca@1606: " ca@1606: |item| ca@1606: cg@1702: self addAndSelectValueOf:[ cg@3013: item := RegularMenuItem menu:(self class standardHelpMenu) labeled:'Help' translateLabel:true. cg@3013: item aspectAt:#startGroup put:#conditionalRight. cg@3013: item ca@1606: ]. cg@2122: cg@2122: "Modified: / 16-10-2006 / 12:49:27 / cg" ca@1606: ! ! ca@1606: cg@1715: !MenuEditor methodsFor:'user actions-editing'! ca@1606: ca@1606: doCopy ca@1606: "copy selected menuItems to the clipboard ca@1606: " ca@1606: |clip items| ca@1606: ca@1606: items := self selectedSuperItems. ca@1606: items isEmpty ifTrue:[ ^ self ]. ca@1606: ca@1606: clip := OrderedCollection new. ca@1606: items do:[:el| clip add:(el menuItem) ]. ca@1606: ca@1606: self clipboard:clip. ca@1606: self updateAllToolInstances. ca@1606: ! ca@1606: ca@1606: doCut ca@1606: "copy selected menuItems to the clipboard and delete ca@1606: " ca@1606: self doCopy. ca@1606: self doDelete. ca@1606: ! ca@1606: ca@1606: doDelete ca@1606: "delete selected menuItems ca@1606: " ca@1606: |selectedItem parent toDelete behind nextItem prevItem| ca@1606: ca@1606: toDelete := self selectedSuperItems. ca@1606: toDelete isEmpty ifTrue:[ ^ self ]. ca@1606: ca@1606: self clearModified. ca@1606: ca@1606: selectedItem := toDelete first. ca@1606: ca@1606: selectedItem isRootItem ifTrue:[ cg@2188: ^ selectedItem removeAll. ca@1606: ]. ca@1606: "/ compute the new selection ca@1606: ca@1606: prevItem := parent := selectedItem parent. ca@1606: nextItem := nil. ca@1606: ca@1606: parent children size ~~ 1 ifTrue:[ cg@2188: behind := false. cg@2188: cg@2188: parent do:[:el| cg@2188: behind ifTrue:[ cg@2188: (nextItem notNil or:[toDelete includesIdentical:el]) ifFalse:[ nextItem := el ]. cg@2188: ] ifFalse:[ cg@2188: behind := el == selectedItem. cg@2188: (behind or:[toDelete includesIdentical:el]) ifFalse:[ prevItem := el ]. cg@2188: ] cg@2188: ] ca@1606: ]. ca@1606: self withoutNotifyDo:[ cg@2188: toDelete do:[:el| el remove ]. ca@1606: ]. ca@1606: self selectedItem:(nextItem ? prevItem). cg@1971: self setModified. ca@1606: self updateChannels. ca@1606: ! ca@1606: ca@1606: doPaste ca@1606: "paste from clipboard ca@1606: " ca@1606: ^ self doPaste:(self clipboard) ca@218: ! ca@218: ca@1606: doPaste:aCollection ca@1606: "paste collection of MenuItems ca@1606: " ca@1606: |item loMenuItems| ca@1606: ca@1606: aCollection size == 0 ifTrue:[ ^ self ]. ca@1606: ca@1606: item := self selectedItem. cg@2151: item isNil ifTrue:[ ^ self ]. ca@1606: ca@1606: loMenuItems := OrderedCollection new. ca@1606: aCollection do:[:el| cg@2188: (el askFor:#isMenuItem) ifTrue:[ loMenuItems add:el ]. ca@1606: ]. ca@1606: loMenuItems isEmpty ifTrue:[ ^ self ]. ca@1606: cg@1702: self addAndSelectValueOf:[ cg@2188: loMenuItems collect:[:el| Item menuItem:el ] ca@1606: ]. ca@1606: ! ! ca@1606: cg@1715: !MenuEditor methodsFor:'user actions-hierarchy'! ca@1606: cg@3135: doMakeLinkedMenu cg@3135: "the selected item must be a regular submenu. cg@3135: create a new menuspec for it, cg@3135: and chenge the item to a linke menu item." cg@3135: cg@3135: |cls subSelector oldMenuItem newLinkedMenuItem index| cg@3135: cg@3135: oldMenuItem := self selectionHolder value first. cg@3135: cg@3135: subSelector := Dialog cg@3135: request:'Name of spec method for submenu:' cg@3135: initialAnswer:((oldMenuItem label reject:[:ch | ch isLetterOrDigit not]),'MenuSpec') asLowercaseFirst. cg@3135: subSelector isEmptyOrNil ifTrue:[^ self]. cg@3135: subSelector := subSelector asSymbol. cg@3135: cg@3135: cls := self resolveName:specClass. cg@3135: (cls theMetaclass compiledMethodAt:subSelector) notNil ifTrue:[ cg@3135: (Dialog confirm:'Overwrite existing spec?') ifFalse:[^ self]. cg@3135: ]. cg@3135: cg@3135: self compileSpecMethodFor:oldMenuItem selector:subSelector. cg@3135: cg@3135: newLinkedMenuItem := LinkedMenuItem new. cg@3135: newLinkedMenuItem submenuChannel:subSelector. cg@3135: newLinkedMenuItem menuItem nameKey:(oldMenuItem menuItem nameKey). cg@3135: newLinkedMenuItem menuItem label:oldMenuItem menuItem label. cg@3135: newLinkedMenuItem menuItem rawLabel:oldMenuItem menuItem rawLabel. cg@3135: newLinkedMenuItem menuItem translateLabel:(oldMenuItem menuItem translateLabel). cg@3587: newLinkedMenuItem menuItem hasMenuIndicator:(oldMenuItem menuItem hasMenuIndicator). cg@3135: cg@3135: index := oldMenuItem parent identityIndexOf:oldMenuItem. cg@3135: oldMenuItem parent at:index put:newLinkedMenuItem. cg@3135: cg@3135: self selectedItem:newLinkedMenuItem. cg@3587: cg@3587: "Modified: / 09-08-2018 / 17:09:40 / Claus Gittinger" cg@3135: ! cg@3135: cg@1958: doMoveDown cg@1958: "move selected item down" cg@1958: cg@1958: self doMoveUpOrDown:#down cg@1958: ! cg@1958: ca@1606: doMoveIn:aDirection ca@1606: "move selected item into the next (#inNext) or previous (#inPrev) item ca@1606: " ca@1606: |item idx parent toParent| ca@1606: ca@1606: item := self selectedItem. cg@2151: item isNil ifTrue:[^ self]. ca@1606: ca@1606: aDirection == #inNext ifTrue:[ item canMoveInNext ifFalse:[^ self] ] cg@2188: ifFalse:[ item canMoveInAbove ifFalse:[^ self] ]. ca@1606: ca@1606: self askForItemModification ifFalse:[ ^ self ]. ca@1606: ca@1606: parent := item parent. ca@1606: idx := parent identityIndexOf:item. ca@1606: ca@1606: aDirection == #inNext ifTrue:[ toParent := parent at:(idx + 1) ifAbsent:nil ] cg@2188: ifFalse:[ toParent := parent at:(idx - 1) ifAbsent:nil ]. ca@1606: ca@1606: self withoutNotifyDo:[ cg@2188: selectionHolder setValue:#(). cg@2188: parent removeIndex:idx. cg@2188: cg@2188: aDirection == #inNext ifTrue:[ toParent addFirst:item ] cg@2188: ifFalse:[ toParent addLast:item ]. cg@2188: item makeVisible. ca@1606: ]. ca@1606: self selectedItem:item. cg@1971: self setModified. cg@1468: ! cg@1468: cg@1958: doMoveInNext cg@1958: "move selected item into the next item" cg@1958: cg@1958: self doMoveIn:#inNext. cg@1958: ! cg@1958: cg@1958: doMoveInPrevious cg@1958: "move selected item into the previous item" cg@1958: cg@1958: self doMoveIn:#inPrev. cg@1958: ! cg@1958: ca@1606: doMoveOut ca@1606: "move selected item out of current item ca@1606: " ca@1606: |item parent grandParent index| ca@1606: ca@1606: item := self selectedItem. cg@2151: item isNil ifTrue:[^ self]. ca@1606: item canMoveOut ifFalse:[^ self]. ca@1606: ca@1606: self askForItemModification ifFalse:[ ^ self ]. ca@1606: ca@1606: parent := item parent. ca@1606: grandParent := parent parent. ca@1606: index := grandParent identityIndexOf:parent. ca@1606: ca@1606: self withoutNotifyDo:[ cg@2188: selectionHolder setValue:#(). cg@2188: parent remove:item. cg@2188: index > grandParent size ifTrue:[ grandParent add:item ] cg@2188: ifFalse:[ grandParent add:item afterIndex:index ] ca@1606: ]. ca@1606: self selectedItem:item. cg@1971: self setModified. ca@218: ! ca@218: cg@1958: doMoveUp cg@1958: "move selected item up" cg@1958: cg@1958: self doMoveUpOrDown:#up cg@1958: ! cg@1958: cg@2869: doMoveUpOrDown:aDirectionSymbol cg@2869: "move selected item up (#up) or down (#down)" cg@2869: cg@2869: |items itemsSortedByIndex index parent children| cg@2869: cg@2869: items := self selectedItems. cg@2869: items isEmptyOrNil ifTrue:[^ self]. cg@2869: (items conform:[:i | i canMoveUpOrDown]) ifFalse:[^ self]. ca@1606: ca@1606: self askForItemModification ifFalse:[ ^ self ]. ca@1606: ca@1606: self withoutNotifyDo:[ cg@3013: itemsSortedByIndex := items copy. cg@3013: (items collect:[:i | listOfItems identityIndexOf:i]) cg@3013: sortWith:itemsSortedByIndex. cg@3013: cg@3013: aDirectionSymbol == #down ifTrue:[ cg@3013: itemsSortedByIndex := itemsSortedByIndex reversed cg@3013: ]. cg@3013: itemsSortedByIndex do:[:item | cg@3013: parent := item parent. cg@3013: children := parent children. cg@3013: index := children identityIndexOf:item. cg@3013: cg@3013: selectionHolder setValue:#(). cg@3013: children removeIndex:index. cg@3013: cg@3013: aDirectionSymbol == #up ifTrue:[ cg@3013: index == 1 ifTrue:[ children add:item ] cg@3013: ifFalse:[ children add:item beforeIndex:index - 1 ] cg@3013: ] ifFalse:[ cg@3013: index > children size ifTrue:[ children addFirst:item ] cg@3013: ifFalse:[ children add:item afterIndex:index ] cg@3013: ]. cg@3013: parent childrenOrderChanged. cg@3013: ] ca@1606: ]. cg@2869: self selectedItems:items. cg@1971: self setModified. cg@2869: cg@2869: "Modified: / 18-01-2012 / 11:35:38 / cg" ca@199: ! ! ca@199: ca@1606: !MenuEditor::Item class methodsFor:'defaults'! ca@1606: ca@1606: defaultLabel ca@1606: ^ self subclassResponsibility ca@1606: ! ! ca@1606: ca@1606: !MenuEditor::Item class methodsFor:'image specs'! ca@1606: ca@1606: iconDelayedLinkedMenu ca@1606: "This resource specification was automatically generated ca@1606: by the ImageEditor of ST/X." cg@3225: ca@1606: "Do not manually edit this!! If it is corrupted, ca@1606: the ImageEditor may not be able to read the specification." cg@3225: ca@1606: " ca@1606: self iconDelayedLinkedMenu inspect ca@1606: ImageEditor openOnClass:self andSelector:#iconDelayedLinkedMenu cg@3225: Icon flushCachedIcons cg@3225: " cg@3225: cg@3225: cg@3225: cg@3225: ^Icon cg@3225: constantNamed:'MenuEditor::Item iconDelayedLinkedMenu' cg@3225: ifAbsentPut:[(Depth4Image new) width:20; height:16; bits:(ByteArray fromPackedString:' cg@2270: @@@@@@@@@@@@@@DQDQDQDQDQDR@AH"H"H"H"H"H0@@@BH"H"@@@BL@QDPBH"H"@@H#@DQDPBH@H"@"H0ADQDPBA@H"H"L@@@QDP@Q@@@@C@ADPQDQDQ@DQD: cg@3225: @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:((ImageMask new) width:20; height:16; bits:(ByteArray fromPackedString:'???0???0???0???0???0???0???0???0???0???0???0???0???0???0???0???0') ; yourself); yourself] ca@1606: ! ca@1606: ca@1606: iconDelayedMenu sv@3120: ca@1606: "This resource specification was automatically generated ca@1606: by the ImageEditor of ST/X." ca@1606: "Do not manually edit this!! If it is corrupted, ca@1606: the ImageEditor may not be able to read the specification." ca@1606: " ca@1606: self iconDelayedMenu inspect ca@1606: ImageEditor openOnClass:self andSelector:#iconDelayedMenu sv@3120: Icon flushCachedIcons" sv@3120: sv@3120: ^ Icon constantNamed:'MenuEditor::Item class iconDelayedMenu' sv@3120: ifAbsentPut:[ sv@3120: (Depth2Image new) sv@3120: width:20; sv@3120: height:16; sv@3120: photometric:(#palette); sv@3120: bitsPerSample:(#( 2 )); sv@3120: samplesPerPixel:(1); sv@3120: bits:(ByteArray sv@3120: fromPackedString:'@@@@@@@UUUUUVA*****,F***@B0Z***@+A****J,F*****0@@@@@@AUUUUUXF*****0Z****+A@@@@@LEUUUUU0Z****+B?????<@@@@@@@b'); sv@3120: colorMapFromArray:#[ 0 0 0 255 255 255 170 170 170 127 127 127 ]; sv@3120: mask:((ImageMask new) sv@3120: width:20; sv@3120: height:16; sv@3120: bits:(ByteArray sv@3120: fromPackedString:'???0???0???0???0???0???0???0???0???0???0???0???0???0???0???0???0'); sv@3120: yourself); sv@3120: yourself sv@3120: ] ca@1606: ! ca@1606: ca@1606: iconItem sv@3120: ca@1606: "This resource specification was automatically generated ca@1606: by the ImageEditor of ST/X." ca@1606: "Do not manually edit this!! If it is corrupted, ca@1606: the ImageEditor may not be able to read the specification." ca@1606: " ca@1606: self iconItem inspect ca@1606: ImageEditor openOnClass:self andSelector:#iconItem sv@3120: Icon flushCachedIcons" sv@3120: sv@3120: ^ Icon constantNamed:'MenuEditor::Item class iconItem' sv@3120: ifAbsentPut:[ sv@3120: (Depth2Image new) sv@3120: width:20; sv@3120: height:16; sv@3120: photometric:(#palette); sv@3120: bitsPerSample:(#( 2 )); sv@3120: samplesPerPixel:(1); sv@3120: bits:(ByteArray sv@3120: fromPackedString:'UUUUUUUUUUUUUP@@@@@@EUUUUU Z****+A.?/;+,F:::/>0[++>:;A...++,F::?..0Z****+B?????<@@@@@@@@@@@@@@@@@@@@@@@@@@@b'); sv@3120: colorMapFromArray:#[ 0 0 0 255 255 255 170 170 170 127 127 127 ]; sv@3120: mask:((ImageMask new) sv@3120: width:20; sv@3120: height:16; sv@3120: bits:(ByteArray sv@3120: fromPackedString:'@@@@@@@@???0???0???0???0???0???0???0???0???0???0???0@@@@@@@@@@@@'); sv@3120: yourself); sv@3120: yourself sv@3120: ] ca@1606: ! ca@1606: ca@1606: iconLinkedMenu sv@3120: ca@1606: "This resource specification was automatically generated ca@1606: by the ImageEditor of ST/X." ca@1606: "Do not manually edit this!! If it is corrupted, ca@1606: the ImageEditor may not be able to read the specification." ca@1606: " ca@1606: self iconLinkedMenu inspect ca@1606: ImageEditor openOnClass:self andSelector:#iconLinkedMenu sv@3120: Icon flushCachedIcons" sv@3120: sv@3120: ^ Icon constantNamed:'MenuEditor::Item class iconLinkedMenu' sv@3120: ifAbsentPut:[ sv@3120: (Depth4Image new) sv@3120: width:20; sv@3120: height:16; sv@3120: photometric:(#palette); sv@3120: bitsPerSample:(#( 4 )); sv@3120: samplesPerPixel:(1); sv@3120: bits:(ByteArray sv@3120: fromPackedString:' ca@1606: @@@@@@@@@@@@@@QDQDQDQDQDQA@DH"H"H"H"H"HPABH@@@H"H"H"D@PQ@3L0DQDQDQ@D@@L3L0@@@@@PADPCL3L0PCADD@P"@@@3L0@3@!!@DH"H"@3L3L3@P sv@3120: AADQDQ@3L3L3@@P@@@@@@3L3LA@DQDQDQD@@L0PPABH"H"H"HC@"D@P"H"H"H"@BH!!@BDQDQDQDQDQDP@@@@@@@@@@@@@@@a'); sv@3120: colorMapFromArray:#[ 0 0 0 127 127 127 170 170 170 255 0 0 255 255 255 ]; sv@3120: mask:((ImageMask new) sv@3120: width:20; sv@3120: height:16; sv@3120: bits:(ByteArray sv@3120: fromPackedString:'???0???0???0???0???0???0???0???0???0???0???0???0???0???0???0???0'); sv@3120: yourself); sv@3120: yourself sv@3120: ] ca@1606: ! ca@1606: ca@1606: iconMenu sv@3120: ca@1606: "This resource specification was automatically generated ca@1606: by the ImageEditor of ST/X." ca@1606: "Do not manually edit this!! If it is corrupted, ca@1606: the ImageEditor may not be able to read the specification." ca@1606: " ca@1606: self iconMenu inspect ca@1606: ImageEditor openOnClass:self andSelector:#iconMenu sv@3120: Icon flushCachedIcons" sv@3120: sv@3120: ^ Icon constantNamed:'MenuEditor::Item class iconMenu' sv@3120: ifAbsentPut:[ sv@3120: (Depth2Image new) sv@3120: width:20; sv@3120: height:16; sv@3120: photometric:(#palette); sv@3120: bitsPerSample:(#( 2 )); sv@3120: samplesPerPixel:(1); sv@3120: bits:(ByteArray sv@3120: fromPackedString:'@@@@@@@?????=C*****$N*****P5UUUUUC@@@@@DO?????P:****)C*****$MUUUUUP0@@@@AC?????4N*****P:****)BUUUUUT@@@@@@@b'); sv@3120: colorMapFromArray:#[ 0 0 0 127 127 127 170 170 170 255 255 255 ]; sv@3120: mask:((ImageMask new) sv@3120: width:20; sv@3120: height:16; sv@3120: bits:(ByteArray sv@3120: fromPackedString:'???0???0???0???0???0???0???0???0???0???0???0???0???0???0???0???0'); sv@3120: yourself); sv@3120: yourself sv@3120: ] ca@1606: ! ca@1606: ca@1606: iconSeparator sv@3120: ca@1606: "This resource specification was automatically generated ca@1606: by the ImageEditor of ST/X." ca@1606: "Do not manually edit this!! If it is corrupted, ca@1606: the ImageEditor may not be able to read the specification." ca@1606: " ca@1606: self iconSeparator inspect ca@1606: ImageEditor openOnClass:self andSelector:#iconSeparator sv@3120: Icon flushCachedIcons" sv@3120: sv@3120: ^ Icon constantNamed:'MenuEditor::Item class iconSeparator' sv@3120: ifAbsentPut:[ sv@3120: (Depth2Image new) sv@3120: width:20; sv@3120: height:16; sv@3120: photometric:(#palette); sv@3120: bitsPerSample:(#( 2 )); sv@3120: samplesPerPixel:(1); sv@3120: bits:(ByteArray sv@3120: fromPackedString:'UUUUUUUUUUUUUP@@@@@@EUUUUU Z****+A*****,F????:0[@@@@[A)UUUU,F*****0Z****+B?????<@@@@@@@@@@@@@@@@@@@@@@@@@@@b'); sv@3120: colorMapFromArray:#[ 0 0 0 255 255 255 170 170 170 127 127 127 ]; sv@3120: mask:((ImageMask new) sv@3120: width:20; sv@3120: height:16; sv@3120: bits:(ByteArray sv@3120: fromPackedString:'@@@@@@@@???0???0???0???0???0???0???0???0???0???0???0@@@@@@@@@@@@'); sv@3120: yourself); sv@3120: yourself sv@3120: ] ca@1844: ! ca@1844: ca@1844: iconSliceMenu sv@3120: ca@1844: "This resource specification was automatically generated ca@1844: by the ImageEditor of ST/X." ca@1844: "Do not manually edit this!! If it is corrupted, ca@1844: the ImageEditor may not be able to read the specification." ca@1844: " ca@1844: self iconSliceMenu inspect ca@1844: ImageEditor openOnClass:self andSelector:#iconSliceMenu sv@3120: Icon flushCachedIcons" sv@3120: sv@3120: ^ Icon constantNamed:'MenuEditor::Item class iconSliceMenu' sv@3120: ifAbsentPut:[ sv@3120: (Depth2Image new) sv@3120: width:20; sv@3120: height:16; sv@3120: photometric:(#palette); sv@3120: bitsPerSample:(#( 2 )); sv@3120: samplesPerPixel:(1); sv@3120: bits:(ByteArray sv@3120: fromPackedString:'@@@@@@@@@@@@@@@@@@@@O?????0:*****C/?6??XN:*[*) ;*).*&C.*&:*XN5U[UU :*****C*****(@@@@@@@@@@@@@@@@@@@@@@@@@@@b'); sv@3120: colorMapFromArray:#[ 0 0 0 127 127 127 170 170 170 255 255 255 ]; sv@3120: mask:((ImageMask new) sv@3120: width:20; sv@3120: height:16; sv@3120: bits:(ByteArray sv@3120: fromPackedString:'@@@@@@@@???0???0???0???0???0???0???0???0???0???0???0@@@@@@@@@@@@'); sv@3120: yourself); sv@3120: yourself sv@3120: ] ca@1606: ! ! ca@1606: ca@1606: !MenuEditor::Item class methodsFor:'instance creation'! ca@1606: ca@1606: classFor:aMenuItem ca@1606: cg@1631: aMenuItem isNil ifTrue:[ ^ nil ]. cg@1631: cg@1631: aMenuItem itemValue isNil ifTrue:[ cg@2188: aMenuItem isMenuSlice ifTrue:[ ^ MenuEditor::MenuSliceItem ]. cg@2188: aMenuItem submenu notNil ifTrue:[ ^ MenuEditor::RegularMenuItem ]. cg@2188: aMenuItem submenuChannel notNil ifTrue:[ ^ MenuEditor::LinkedMenuItem ]. cg@2188: cg@2188: (self separatorTypeOf:(aMenuItem rawLabel)) notNil ifTrue:[ cg@2188: ^ MenuEditor::SeparatorItem cg@2188: ] ca@1606: ]. cg@1631: ^ MenuEditor::ActionItem sv@1454: ! sv@1454: ca@1606: menuItem:aMenuItem ca@1606: |item cls| ca@1606: ca@1606: cls := self classFor:aMenuItem. cg@2151: cls isNil ifTrue:[^ nil]. ca@1606: ca@1606: item := cls new. ca@1606: item menuItem:aMenuItem. cg@2151: ^ item ca@1606: ! ! ca@1606: cg@1668: !MenuEditor::Item class methodsFor:'interface specs'! ca@1606: ca@1606: detailsEditSpec ca@1606: "This resource specification was automatically generated ca@1606: by the UIPainter of ST/X." ca@1606: ca@1606: "Do not manually edit this!! If it is corrupted, ca@1606: the UIPainter may not be able to read the specification." ca@1606: ca@1606: " ca@1606: UIPainter new openOnClass:MenuEditor::Item andSelector:#detailsEditSpec ca@1606: " ca@1606: ca@1606: ca@1606: cg@3013: ^ sv@1737: #(FullSpec cg@3013: name: detailsEditSpec cg@3013: window: sv@1737: (WindowSpec cg@3013: label: 'Details Edit' cg@3013: name: 'Details Edit' cg@3013: min: (Point 10 10) cg@3013: bounds: (Rectangle 0 0 407 291) cg@3013: ) cg@3013: component: sv@1737: (SpecCollection cg@3013: collection: ( cg@3013: (LabelSpec cg@3013: label: 'Accelerator:' cg@3013: name: 'shortcutKeyLabel' cg@3013: layout: (AlignmentOrigin 107 0 26 0 1 0.5) cg@3013: activeHelpKey: detailsAccelerator cg@3013: translateLabel: true cg@3013: resizeForLabel: true cg@3013: adjust: right cg@3013: ) cg@3013: (InputFieldSpec cg@3013: name: 'shortcutKeyField' cg@3013: layout: (LayoutFrame 110 0 15 0 -5 1.0 37 0) cg@3013: activeHelpKey: detailsAccelerator cg@3013: tabable: true cg@3013: model: shortcutKeyCharacter cg@3013: group: inputGroup cg@3013: type: symbolOrNil cg@3013: immediateAccept: false cg@3013: acceptOnReturn: true cg@3013: acceptOnTab: true cg@3013: acceptChannel: acceptChannel cg@3013: modifiedChannel: modifiedChannel cg@3013: acceptOnPointerLeave: false cg@3013: ) cg@3013: (LabelSpec cg@3013: label: 'Enabled:' cg@3013: name: 'enabledLabel' cg@3013: layout: (AlignmentOrigin 107 0 51 0 1 0.5) cg@3013: activeHelpKey: detailsEnabled cg@3013: translateLabel: true cg@3013: resizeForLabel: true cg@3013: adjust: right cg@3013: ) cg@3013: (InputFieldSpec cg@3013: name: 'enabledField' cg@3013: layout: (LayoutFrame 110 0 40 0 -25 1.0 62 0) cg@3013: activeHelpKey: detailsEnabled cg@3013: tabable: true cg@3013: model: enabled cg@3013: group: inputGroup cg@3013: type: symbolOrBooleanOrNil cg@3013: immediateAccept: false cg@3013: acceptOnReturn: true cg@3013: acceptOnTab: true cg@3013: acceptChannel: acceptChannel cg@3013: modifiedChannel: modifiedChannel cg@3013: acceptOnPointerLeave: false cg@3013: ) cg@3013: (ActionButtonSpec cg@3013: label: 'browseActionImage' cg@3013: name: 'Button1' cg@3013: layout: (LayoutFrame -25 1 40 0 -5 1 62 0) cg@3013: activeHelpKey: browseMethod cg@3013: hasCharacterOrientedLabel: false cg@3013: translateLabel: true cg@3013: resizeForLabel: true cg@3013: tabable: true cg@3013: model: doBrowseEnabledMethod cg@3013: ) cg@3013: (LabelSpec cg@3013: label: 'Visibility:' cg@3013: name: 'visibilityLabel' cg@3013: layout: (AlignmentOrigin 107 0 76 0 1 0.5) cg@3013: activeHelpKey: detailsVisibility cg@3013: translateLabel: true cg@3013: resizeForLabel: true cg@3013: adjust: right cg@3013: ) cg@3013: (InputFieldSpec cg@3013: name: 'isVisibleInputField' cg@3013: layout: (LayoutFrame 110 0 65 0 -25 1.0 87 0) cg@3013: activeHelpKey: detailsVisibility cg@3013: tabable: true cg@3013: model: isVisible cg@3013: group: inputGroup cg@3013: type: symbolOrBooleanOrNil cg@3013: immediateAccept: false cg@3013: acceptOnReturn: true cg@3013: acceptOnTab: true cg@3013: acceptChannel: acceptChannel cg@3013: modifiedChannel: modifiedChannel cg@3013: acceptOnPointerLeave: false cg@3013: ) cg@3013: (ActionButtonSpec cg@3013: label: 'browseActionImage' cg@3013: name: 'Button2' cg@3013: layout: (LayoutFrame -25 1 65 0 -5 1 87 0) cg@3013: activeHelpKey: browseMethod cg@3013: hasCharacterOrientedLabel: false cg@3013: translateLabel: true cg@3013: resizeForLabel: true cg@3013: tabable: true cg@3013: model: doBrowseVisibilityMethod cg@3013: ) cg@3013: (LabelSpec cg@3013: label: 'Aux Value' cg@3013: name: 'auxLabel' cg@3013: layout: (AlignmentOrigin 107 0 101 0 1 0.5) cg@3013: activeHelpKey: detailsAuxValue cg@3013: translateLabel: true cg@3013: resizeForLabel: true cg@3013: adjust: right cg@3013: ) cg@3013: (InputFieldSpec cg@3013: name: 'auxInputField' cg@3013: layout: (LayoutFrame 110 0 90 0 -5 1.0 112 0) cg@3013: activeHelpKey: detailsAuxValue cg@3013: tabable: true cg@3013: model: auxValue cg@3013: group: inputGroup cg@3013: type: smalltalkObjectOrNil cg@3013: immediateAccept: false cg@3013: acceptOnReturn: true cg@3013: acceptOnTab: true cg@3013: acceptChannel: acceptChannel cg@3013: modifiedChannel: modifiedChannel cg@3013: acceptOnPointerLeave: false cg@3013: ) cg@3013: (LabelSpec cg@3013: label: 'Start Group:' cg@3013: name: 'StartGroupLabel' cg@3013: layout: (AlignmentOrigin 107 0 139 0 1 0.5) cg@3013: activeHelpKey: detailsStartGroup cg@3013: translateLabel: true cg@3013: resizeForLabel: true cg@3013: adjust: right cg@3013: ) cg@3013: (PopUpListSpec cg@3013: label: 'left' cg@3013: name: 'StartGroupPopUp' cg@3013: layout: (LayoutFrame 110 0 128 0 -5 1.0 150 0) cg@3013: activeHelpKey: detailsStartGroup cg@3013: tabable: true cg@3013: model: startGroup cg@3013: menu: cg@3013: (Array cg@3013: left right cg@3013: conditionalRight cg@3013: ) cg@3013: ) cg@3013: (LabelSpec cg@3013: label: 'Access Character Position:' cg@3013: name: 'accessCharLabel' cg@3013: layout: (AlignmentOrigin 217 0 170 0 1 0.5) cg@3013: translateLabel: true cg@3013: resizeForLabel: true cg@3013: adjust: right cg@3013: ) cg@3013: (InputFieldSpec cg@3013: name: 'accessCharField' cg@3013: layout: (LayoutFrame 220 0 159 0 -5 1.0 181 0) cg@3013: activeHelpKey: detailsAccessCharaterPosition cg@3013: tabable: true cg@3013: model: accessCharacterPosition cg@3013: group: inputGroup cg@3013: type: numberOrNil cg@3013: immediateAccept: false cg@3013: acceptOnReturn: true cg@3013: acceptOnTab: true cg@3013: acceptChannel: acceptChannel cg@3013: modifiedChannel: modifiedChannel cg@3013: acceptOnPointerLeave: false cg@3013: ) cg@3013: (CheckBoxSpec cg@3013: label: 'Ignore Accelerator (i.e. Display Only)' cg@3013: name: 'ignoreShortcutKeysInItem' cg@3013: layout: (AlignmentOrigin 42 0 204 0 0 0.5) cg@3013: activeHelpKey: detailsIgnoreAcceleratorKeys cg@3013: visibilityChannel: hasNoSubmenu cg@3013: model: ignoreShortcutKeys cg@3013: translateLabel: true cg@3013: resizeForLabel: true cg@3013: ) cg@3013: (CheckBoxSpec cg@3013: label: 'Ignore Accelerators in Submenu' cg@3013: name: 'ignoreShortcutKeys' cg@3013: layout: (AlignmentOrigin 42 0 204 0 0 0.5) cg@3013: activeHelpKey: detailsIgnoreAcceleratorKeys cg@3013: visibilityChannel: hasSubmenu cg@3013: model: ignoreShortcutKeys cg@3013: translateLabel: true cg@3013: resizeForLabel: true cg@3013: ) cg@3013: (CheckBoxSpec cg@3013: label: 'Ignore Mnemonics in Submenu' cg@3013: name: 'ignoreMnemonicKeys' cg@3013: layout: (AlignmentOrigin 42 0 232 0 0 0.5) cg@3013: activeHelpKey: detailsIgnoreMnemonicKeys cg@3013: visibilityChannel: hasSubmenu cg@3013: model: ignoreMnemonicKeys cg@3013: translateLabel: true cg@3013: resizeForLabel: true cg@3013: ) cg@3013: (LabelSpec cg@3013: label: 'Font:' cg@3013: name: 'fontLabel' cg@3013: layout: (AlignmentOrigin 107 0 271 0 1 0.5) cg@3013: translateLabel: true cg@3013: resizeForLabel: true cg@3013: adjust: right cg@3013: ) cg@3013: (FontMenuSpec cg@3013: name: 'fontMenu' cg@3013: layout: (LayoutFrame 110 0 260 0 -5 1.0 282 0) cg@3013: activeHelpKey: fontMenu cg@3013: model: font cg@3013: allowSymbolicFonts: true cg@3013: ) cg@3013: ) cg@3013: cg@3013: ) sv@1454: ) cg@2122: cg@2810: "Modified: / 21-10-2010 / 14:15:09 / cg" sv@1454: ! ! sv@1454: cg@1725: !MenuEditor::Item class methodsFor:'interface-editor'! cg@1725: cg@1725: addBindingsTo:aspects for:aMenuEditor cg@1725: "add additional bindings to the aspects cg@1725: " cg@2341: aspects at:#notDelayedMenu ifAbsentPut:[true asValue]. cg@2341: aspects at:#hasSubmenu ifAbsentPut:[false asValue]. cg@2341: aspects at:#hasNoSubmenu ifAbsentPut:[true asValue]. cg@1725: ! ! cg@1725: ca@1606: !MenuEditor::Item class methodsFor:'testing'! ca@1606: ca@1606: separatorTypeOf:aString ca@1606: |size first| ca@1606: ca@1606: size := aString size. ca@1606: ca@1606: size == 0 ifTrue:[ ^ #blank ]. ca@1606: ca@1606: size == 1 ifTrue:[ ca@1606: first := aString first. ca@1606: first == $- ifTrue:[ ^ #single ]. ca@1606: first == $= ifTrue:[ ^ #double ]. ca@1606: first == (Character space) ifTrue:[ ^ #blank ]. ca@1606: ]. ca@1606: ^ nil sv@1454: ! ! sv@1454: sv@1454: !MenuEditor::Item methodsFor:'accessing'! sv@1454: ca@1606: children ca@1606: "optimize access; do not ask the model for unspecified children ca@1606: " ca@1606: ^ children ca@1606: ! ca@1606: cg@3587: hasMenuIndicator:aBoolean cg@3587: menuItem hasMenuIndicator:aBoolean cg@3587: cg@3587: "Created: / 09-08-2018 / 17:03:06 / Claus Gittinger" cg@3587: ! cg@3587: ca@1606: menuItem ca@1606: "returns self as a MenuItem ca@1606: " cg@2168: ^ MenuItem decodeFromLiteralArray:(menuItem literalArrayEncoding). cg@2168: cg@2168: "Modified: / 27-03-2007 / 08:43:14 / cg" ca@1606: ! ca@1606: ca@1606: menuItem:aMenuItem ca@1606: "rebuild self from a MenuItem ca@1606: " ca@1606: |value| ca@1606: cg@3138: menuItem := MenuItem label:(self rawLabel). ca@1606: ca@1606: MenuEditor aspects do:[:aKey| cg@3138: value := self validateValue:(aMenuItem perform:aKey). cg@3138: cg@3138: value notNil ifTrue:[ cg@3138: self aspectAt:aKey put:value. cg@3138: ]. ca@1606: ]. ca@1606: ! ca@1606: ca@1606: rawLabel ca@1606: "returns the label assigned to the item ca@1606: " ca@1606: ^ menuItem rawLabel ca@1606: ! ca@1606: ca@1606: rawLabel:aValue ca@1606: "set the label assigned to the item ca@1606: " ca@1606: aValue isString ifTrue:[ cg@2188: "/ KLUDGE alarm: '-' and '' indicate a separator cg@2188: "/ (there is no separate menuItem class for them) cg@2188: cg@2188: (self isKindOfMenu or:[(self class separatorTypeOf:aValue) isNil]) ifTrue:[ cg@2188: menuItem rawLabel:aValue cg@2188: ] ca@1606: ]. ca@1606: ! ca@1606: ca@1606: slices ca@1606: "returns a sequence of supported slices ca@1606: " ca@1606: ^ self subclassResponsibility sv@1454: ! sv@1454: ca@1606: submenu ca@1606: "returns the submenu (of class Menu) or nil ca@1606: " ca@1606: ^ nil cg@1631: ! cg@1631: cg@1631: translateLabel:aBoolean cg@1631: menuItem translateLabel:aBoolean ca@1606: ! ! ca@1606: ca@1606: !MenuEditor::Item methodsFor:'aspects'! ca@1606: ca@1606: aspectAt:aKey put:aValue cg@2075: "set a specific aspect named aKey to the aValue" cg@2075: ca@1606: aKey == #rawLabel ifTrue:[ ^ self rawLabel:aValue ]. ca@1606: aKey == #submenuChannel ifTrue:[ ^ self ]. cg@3095: menuItem perform:(aKey asMutator) with:aValue. cg@2075: cg@2075: "Modified: / 05-09-2006 / 17:47:19 / cg" ca@1606: ! ca@1606: ca@1606: fromAspects:aspects ca@1606: "read values from aspects ca@1606: " ca@1606: MenuEditor aspects do:[:aKey| cg@3013: self aspectAt:aKey put:((aspects at:aKey) value). ca@1606: ]. ca@2189: self validateMenuItem. ca@1606: self changed. ca@1606: ! ca@1606: ca@1606: toAspects:aspects ca@1606: "write values to aspects ca@1606: " ca@1606: MenuEditor aspects do:[:aKey| cg@2188: (aspects at:aKey) value:(menuItem perform:aKey) ca@1606: ]. ca@1606: (aspects at:#notDelayedMenu) value:(self isDelayedMenu not). ca@1778: (aspects at:#hasSubmenu) value:(self isKindOfMenu or:[self children size ~~ 0]). cg@2010: (aspects at:#hasNoSubmenu) value:(self isKindOfMenu not ). ca@2189: ! ca@2189: ca@2189: validateMenuItem ca@2189: "validate the menuItem for correctness" ca@2189: ca@2189: menuItem isNil ifTrue:[^ self]. ca@2189: ca@2189: menuItem choice isEmptyOrNil ifTrue:[ cg@3013: menuItem choice:nil. cg@3013: menuItem choiceValue:nil. ca@2189: ]. ca@1606: ! ! ca@1606: ca@1606: !MenuEditor::Item methodsFor:'displaying'! ca@1606: ca@1606: displayLabel ca@1606: "returns the label on default displayed on the screen ca@1606: " ca@1606: ^ menuItem rawLabel ca@1606: ! ca@1606: cg@3178: displayOn:aGC x:x y:y h:h isHighlightedAsSelected:isHighlightedAsSelected cg@3178: "display the item in the graphicsContext, aGC" cg@3178: ca@1606: |label| ca@1606: ca@1606: label := self displayLabel. ca@1606: ca@1606: label notNil ifTrue:[ cg@3178: self displayLabel:label h:(self heightOn:aGC) on:aGC x:x y:y h:h isHighlightedAsSelected:isHighlightedAsSelected ca@1606: ]. ca@1606: ! ca@1606: ca@1606: heightOn:aGC ca@1606: "returns the height of the label on a GC ca@1606: " cg@2151: height isNil ifTrue:[ height := parent heightOn:aGC ]. cg@2151: ^ height sv@1454: ! sv@1454: sv@1454: label ca@1606: "get the rawLabel assigned to the item ca@1606: " ca@1606: ^ menuItem rawLabel sv@1454: ! sv@1454: ca@1606: label:aLabel ca@1606: "set the rawLabel assigned to the item ca@1606: " ca@1606: self rawLabel:aLabel sv@1454: ! sv@1454: ca@1606: widthOn:aGC ca@1606: "returns the height of the displayLabel on a GC ca@1606: " cg@2151: width isNil ifTrue:[ width := self widthOf:(self displayLabel) on:aGC ]. cg@2151: ^ width sv@1454: ! ! sv@1454: ca@1606: !MenuEditor::Item methodsFor:'initialization'! ca@1606: ca@1606: initialize cg@3396: "must be called if redefined" cg@3396: ca@1606: super initialize. ca@1606: menuItem := MenuItem label:(self class defaultLabel). cg@3396: cg@3396: "Modified: / 08-02-2017 / 00:28:44 / cg" sv@1454: ! ! sv@1454: ca@1653: !MenuEditor::Item methodsFor:'private'! ca@1653: ca@1653: validateValue:aValue ca@1653: "if we pick a menupanel, the values of an item can be ca@1653: a block model, .... ca@1653: " ca@1653: aValue notNil ifTrue:[ cg@2188: aValue isBlock ifTrue:[ ^ #block ]. cg@2188: aValue isValueModel ifTrue:[ ^ #valueModel ]. ca@1653: ]. ca@1653: ^ aValue ca@1653: ! ! ca@1653: sv@1454: !MenuEditor::Item methodsFor:'queries'! sv@1454: ca@1606: isAction ca@1606: "returns true if the item is an Action ca@1606: " ca@1606: ^ false ca@1606: ! ca@1606: ca@1606: isDelayedMenu ca@1606: "returns true if the item is a Delayed (Linked) Menu ca@1606: " ca@1606: ^ parent isAction ca@1606: ! ca@1606: cg@3135: isKindOfLinkedMenu cg@3135: "returns true if the item is a Linked Menu cg@3135: " cg@3135: ^ false cg@3135: ! cg@3135: ca@1606: isKindOfMenu ca@1606: "returns true if the item is a Linked Menu or Menu ca@1606: " ca@1606: ^ false ca@1606: ! ca@1606: cg@3135: isKindOfNonLinkedMenu cg@3135: "returns true if the item is a Linked Menu cg@3135: " cg@3135: ^ false cg@3135: ! cg@3135: ca@1633: isMenuEditItem ca@1633: ^ true ca@1633: ! ca@1633: ca@1606: isRootItem ca@1606: "returns true if the item is the root item ca@1606: " ca@1606: ^ false ca@1606: ! ! ca@1606: cg@1660: !MenuEditor::Item methodsFor:'queries-editor'! ca@1614: ca@1614: actionSelectors cg@2232: "return my action selectors" cg@2232: ca@1614: |value| ca@1614: ca@1614: value := menuItem value. ca@1614: value isSymbol ifTrue:[ ^ Array with:value ]. cg@2232: ^ #() ca@1614: ! ca@1614: ca@1614: aspectSelectors cg@2232: "return my aspect selectors" cg@2232: ca@1614: |aspects| ca@1614: ca@1614: aspects := OrderedCollection new. ca@1614: ca@1614: #( indication choice enabled isVisible ) do:[:aKey| |sel| cg@3013: sel := menuItem perform:aKey. cg@3013: sel isSymbol ifTrue:[ aspects add:sel ] cg@2188: ]. ca@1614: ^ aspects ca@1614: ! ! ca@1614: cg@1660: !MenuEditor::Item methodsFor:'queries-operation'! ca@1606: ca@1606: canAddChildren ca@1606: "returns true if children can be added ca@1606: " ca@1606: ^ false ca@1606: ! ca@1606: ca@1606: canAddDelayedMenu ca@1606: "returns true if a delayed menu can be added; ca@1606: on default false is returned ca@1606: " ca@1606: ^ false ca@1606: ! ca@1606: ca@1606: canMoveInAbove ca@1606: "returns true if the item can become a child of its previous sibling ca@1606: " ca@1606: |siblings index nextItem| ca@1606: ca@1606: siblings := parent children. ca@1606: siblings size > 1 ifFalse:[ ^ false ]. ca@1606: ca@1606: index := siblings identityIndexOf:self. ca@1606: nextItem := siblings at:(index - 1) ifAbsent:nil. ca@1606: cg@2151: nextItem isNil ifTrue:[^ false]. cg@2151: ^ nextItem canAddChildren sv@1454: ! sv@1454: ca@1606: canMoveInNext ca@1606: "returns true if the item can become a child of its next sibling ca@1606: " ca@1606: |siblings index nextItem| ca@1606: ca@1606: siblings := parent children. ca@1606: siblings size > 1 ifFalse:[ ^ false ]. ca@1606: ca@1606: index := siblings identityIndexOf:self. ca@1606: nextItem := siblings at:(index + 1) ifAbsent:nil. ca@1606: cg@2151: nextItem isNil ifTrue:[^ false]. cg@2151: ^ nextItem canAddChildren ca@1606: ! ca@1606: ca@1606: canMoveOut ca@1606: "returns true if the item can be moved out from its current parent ca@1606: " ca@1606: self isDelayedMenu ifTrue:[^ false]. ca@1606: parent isDelayedMenu ifTrue:[^ false]. ca@1606: ca@1606: ^ parent parent notNil sv@1454: ! sv@1454: ca@1606: canMoveUpOrDown ca@1606: "returns true if the item can change its vertical order in its sibling ca@1606: " ca@1606: ^ parent children size > 1 ca@1606: ! ! ca@1606: cg@2850: !MenuEditor::ImageResourceEditor class methodsFor:'interface specs'! cg@2850: cg@2850: windowSpec cg@2850: "This resource specification was automatically generated cg@2850: by the UIPainter of ST/X." cg@2850: cg@2850: "Do not manually edit this!! If it is corrupted, cg@2850: the UIPainter may not be able to read the specification." cg@2850: cg@2850: " cg@2850: UIPainter new openOnClass:MenuEditor::ImageResourceEditor andSelector:#windowSpec cg@2850: MenuEditor::ImageResourceEditor new openInterface:#windowSpec cg@2850: MenuEditor::ImageResourceEditor open cg@2850: " cg@2850: cg@2850: cg@2850: cg@3013: ^ cg@2850: #(FullSpec cg@3013: name: windowSpec cg@3013: window: cg@2850: (WindowSpec cg@3013: label: 'Image Item' cg@3013: name: 'Image Item' cg@3013: min: (Point 10 10) cg@3013: bounds: (Rectangle 0 0 303 304) cg@3013: ) cg@3013: component: cg@2850: (SpecCollection cg@3013: collection: ( cg@3013: (LabelSpec cg@3013: label: 'Retriever:' cg@3013: name: 'retrieverLabel' cg@3013: layout: (AlignmentOrigin 107 0 26 0 1 0.5) cg@3013: activeHelpKey: imageRetriever cg@3013: translateLabel: true cg@3013: resizeForLabel: true cg@3013: adjust: right cg@3013: ) cg@3013: (ComboBoxSpec cg@3013: name: 'retrieverHolder' cg@3013: layout: (LayoutFrame 110 0 15 0 -2 1.0 37 0) cg@3013: activeHelpKey: imageRetriever cg@3013: tabable: true cg@3013: model: retrieverHolder cg@3013: type: symbolOrNil cg@3013: immediateAccept: true cg@3013: acceptOnReturn: false cg@3013: acceptOnTab: false cg@3013: acceptOnPointerLeave: false cg@3013: entryCompletionBlock: entryCompletionForRetriever cg@3013: comboList: retrieverList cg@3013: isFilenameBox: false cg@3013: ) cg@3013: (LabelSpec cg@3013: label: 'Selector:' cg@3013: name: 'iconLabel' cg@3013: layout: (AlignmentOrigin 107 0 51 0 1 0.5) cg@3013: activeHelpKey: imageSelector cg@3013: translateLabel: true cg@3013: resizeForLabel: true cg@3013: adjust: right cg@3013: ) cg@3013: (InputFieldSpec cg@3013: name: 'selectorHolder' cg@3013: layout: (LayoutFrame 110 0 40 0 -24 1.0 62 0) cg@3013: activeHelpKey: imageSelector cg@3013: tabable: true cg@3013: model: selectorHolder cg@3013: group: inputGroup cg@3013: type: symbolOrNil cg@3013: immediateAccept: true cg@3013: acceptOnReturn: false cg@3013: acceptOnTab: false cg@3013: modifiedChannel: modifiedChannel cg@3013: acceptOnPointerLeave: false cg@3013: ) cg@3013: (ActionButtonSpec cg@3013: label: '...' cg@3013: name: 'browseButton' cg@3013: layout: (LayoutFrame -22 1 40 0 -2 1 62 0) cg@3013: activeHelpKey: browseResource cg@3013: tabable: true cg@3013: model: doBrowseForImageResource cg@3013: ) cg@3013: (DividerSpec cg@3013: name: 'Separator1' cg@3013: layout: (LayoutFrame 0 0.0 66 0 0 1.0 70 0) cg@3013: ) cg@3013: (ViewSpec cg@3013: name: 'SelectorFilterBox2' cg@3013: layout: (LayoutFrame 0 0.0 74 0 0 1.0 96 0) cg@3013: activeHelpKey: selectorFilter cg@3013: component: cg@3013: (SpecCollection cg@3013: collection: ( cg@3013: (LabelSpec cg@3013: label: 'Filter:' cg@3013: name: 'Label1' cg@3013: layout: (AlignmentOrigin 107 0 11 0 1 0.5) cg@3013: activeHelpKey: selectorFilter cg@3013: translateLabel: true cg@3013: resizeForLabel: true cg@3013: adjust: right cg@3013: ) cg@3013: (InputFieldSpec cg@3013: name: 'EntryField1' cg@3013: layout: (LayoutFrame 110 0 0 0 -2 1 22 0) cg@3013: model: selectorFilterHolder cg@3013: immediateAccept: true cg@3013: acceptOnLeave: true cg@3013: acceptOnReturn: false cg@3013: acceptOnTab: false cg@3013: acceptOnPointerLeave: false cg@3013: activeHelpKey: selectorFilter cg@3013: ) cg@3013: ) cg@3013: cg@3013: ) cg@3013: ) cg@3013: (HierarchicalListViewSpec cg@3013: name: 'imageList' cg@3013: layout: (LayoutFrame 2 0.0 100 0 -2 1.0 -60 1.0) cg@3013: activeHelpKey: imageImageList cg@3013: model: imageHolder cg@3013: menu: menuEditImage cg@3013: hasHorizontalScrollBar: true cg@3013: hasVerticalScrollBar: true cg@3013: miniScrollerHorizontal: true cg@3013: listModel: imageList cg@3013: useIndex: false cg@3013: highlightMode: label cg@3013: postBuildCallback: postBuildImageViewer: cg@3013: ) cg@3013: (ViewSpec cg@3013: name: 'Box1' cg@3013: layout: (LayoutFrame 20 0.0 -60 1.0 -20 1.0 0 1.0) cg@3013: level: 0 cg@3013: component: cg@3013: (SpecCollection cg@3013: collection: ( cg@3013: (CheckBoxSpec cg@3013: label: 'Image & Label' cg@3013: name: 'iconAndLabelCheckBox' cg@3013: layout: (AlignmentOrigin 0 0 17 0 0 0.5) cg@3013: activeHelpKey: imageImageAndLabel cg@3013: tabable: true cg@3013: model: iconAndLabelHolder cg@3013: translateLabel: true cg@3013: ) cg@3013: (ActionButtonSpec cg@3013: label: 'Image Editor' cg@3013: name: 'imageEditorButton' cg@3013: layout: (AlignmentOrigin -69 1.0 17 0 0 0.5) cg@3013: activeHelpKey: imageImageEditor cg@3013: hasCharacterOrientedLabel: false cg@3013: foregroundColor: (Color 0.0 0.0 66.9993133440146) cg@3013: tabable: true cg@3013: model: doEditImage cg@3013: ) cg@3013: (ActionButtonSpec cg@3013: label: 'Browse' cg@3013: name: 'Button1' cg@3013: layout: (AlignmentOrigin -69 1.0 41 0 0 0.5) cg@3013: activeHelpKey: imageBrowseImageClass cg@3013: hasCharacterOrientedLabel: false cg@3013: foregroundColor: (Color 0.0 0.0 66.9993133440146) cg@3013: tabable: true cg@3013: model: doBrowseImageClass cg@3013: ) cg@3013: ) cg@3013: cg@3013: ) cg@3013: ) cg@3013: ) cg@3013: cg@3013: ) cg@2850: ) cg@2850: cg@2850: "Modified: / 03-08-2011 / 10:16:13 / cg" cg@2850: ! ! cg@2850: cg@2850: !MenuEditor::ImageResourceEditor methodsFor:'accessing'! cg@2850: cg@2850: resourceRetriever cg@2850: |rcv sel cls clsName| cg@2850: cg@2850: sel := selectorHolder value. cg@2850: sel size == 0 ifTrue:[ ^ nil ]. cg@2850: cls := self retrieverClass. cg@3013: cls notNil ifTrue:[ cg@3013: clsName := retrieverHolder value. cg@3013: clsName isEmptyOrNil ifTrue:[ cg@3013: clsName := cls name. cg@3013: ]. cg@3013: clsName := clsName asSymbol. cg@2850: ]. cg@2850: cg@2850: rcv := ResourceRetriever new. cg@2850: rcv className:clsName. cg@2850: rcv selector:sel. cg@2850: cg@2850: iconAndLabelHolder value ifTrue:[ rcv labelText:'' ]. cg@2850: ^ rcv cg@2850: ! cg@2850: cg@2850: resourceRetriever:aResourceRetriever cg@2850: |className sel isOn| cg@2850: cg@2850: aResourceRetriever notNil ifTrue:[ cg@3013: className := aResourceRetriever className. cg@3013: className isBehavior ifTrue:[ cg@3013: className := className name asSymbol cg@3013: ]. cg@3013: sel := aResourceRetriever selector. cg@3013: isOn := aResourceRetriever labelText notNil. cg@2850: ] ifFalse:[ cg@3013: className := sel := nil. cg@3013: isOn := false. cg@2850: ]. cg@2850: cg@2850: retrieverHolder value:className. cg@2850: selectorHolder value:sel. cg@2850: iconAndLabelHolder value:isOn. cg@2850: ! cg@2850: cg@2850: retrieverClass cg@2850: |clsName cls| cg@2850: cg@2850: clsName := retrieverHolder value. cg@2850: clsName notEmptyOrNil ifTrue:[ cg@3013: cls := Smalltalk at:clsName ifAbsent:nil. cg@3013: (cls isBehavior) ifTrue:[ cg@3013: ^ cls cg@3013: ]. cg@2850: ]. cg@2850: ^ nil cg@2850: ! ! cg@2850: cg@2850: !MenuEditor::ImageResourceEditor methodsFor:'actions'! cg@2850: cg@2850: doBrowseForImageResource cg@2850: "opens a browser on image-resource methods" cg@2850: cg@2850: |classAndSelector| cg@2850: cg@2850: classAndSelector := ResourceSelectionBrowser cg@2850: request:'Use Image From Class' cg@2850: onSuperclass:nil cg@2850: andClass:(self retrieverClass) cg@2850: andSelector:(selectorHolder value) cg@2850: withResourceTypes:#(image fileImage programImage). cg@2850: cg@2850: classAndSelector isNil ifTrue:[ ^ self ]. cg@2850: cg@2850: retrieverHolder value:(classAndSelector methodClass) name. cg@2850: selectorHolder value:(classAndSelector methodSelector). cg@2850: ! cg@2850: cg@2850: doBrowseImageClass cg@2850: |cls sel image| cg@2850: cg@2850: (cls := retrieverHolder value) isNil ifTrue:[ cg@3026: Dialog warn:'No resource retriever is defined.'. cg@2850: ] ifFalse:[ cg@3026: sel := selectorHolder value. cg@3026: cg@3026: cls := Smalltalk classNamed:cls. cg@3026: cls isNil ifTrue:[ cg@3026: Dialog warn:'No such resource retriever class.'. cg@3026: ] ifFalse:[ cg@3026: (cls respondsTo:#visualFor:) ifTrue:[ cg@3571: Error handle:[:ex | cg@3571: self warn:'The class seems to not understand #',sel. cg@3571: ] do:[ cg@3571: image := cls visualFor:sel. cg@3571: ]. cg@3571: (image notNil and:[image ~~ (cls perform:sel ifNotUnderstood:nil)]) ifTrue:[ cg@3211: self warn:'The image as returned by #visualFor: is probably provided by another class.\\Showing all implementors of #',sel. cg@3211: "/ sel := #visualFor:. cg@3483: SystemBrowser default browseImplementorsOf:sel. cg@3211: ^ self. cg@3026: ]. cg@3026: ]. cg@3483: SystemBrowser default openInClass:(cls class) selector:sel cg@3026: ] cg@2850: ] cg@2850: cg@2850: "Created: / 20-09-2010 / 13:27:34 / cg" cg@3483: "Modified: / 01-09-2017 / 14:21:02 / cg" cg@3571: "Modified: / 08-07-2018 / 15:41:37 / Claus Gittinger" cg@2850: ! cg@2850: cg@2850: doEditImage cg@2850: |sel cls item image| cg@2850: cg@2850: item := imageHolder value. cg@2850: item notNil ifTrue:[ cg@3013: item doEdit. cg@3013: ^ self. cg@2850: ]. cg@2850: cg@3013: sel := selectorHolder value. cg@2850: sel isNil ifTrue:[ cg@3013: Dialog warn:'No selector is defined.'. cg@3013: ^ self. cg@2850: ]. cg@2850: cls := retrieverHolder value. cg@2850: cls isNil ifTrue:[ cg@3013: Dialog warn:'No resource retriever is defined.'. cg@3013: ^ self. cg@2850: ]. cg@2850: cls := Smalltalk classNamed:cls. cg@2850: cls isNil ifTrue:[ cg@3013: Dialog warn:'No such resource retriever class.'. cg@3013: ^ self. cg@2850: ]. cg@2850: (cls respondsTo:#visualFor:) ifTrue:[ cg@3013: image := cls visualFor:sel. cg@3013: image ~~ (cls perform:sel ifNotUnderstood:nil) ifTrue:[ cg@3013: self warn:'The image is resolved via #visualFor: from some unknown class'. cg@3013: image notNil ifTrue:[ cg@3013: ImageEditor openOnImage:image. cg@3013: ]. cg@3013: ^ self. cg@3013: ]. cg@2850: ]. cg@2850: cg@2850: ImageEditor openOnClass:cls andSelector:sel cg@2850: ! ! cg@2850: cg@2850: !MenuEditor::ImageResourceEditor methodsFor:'aspects'! cg@2850: cg@2850: entryCompletionForRetriever cg@2850: ^ DoWhatIMeanSupport classNameEntryCompletionBlock. cg@2850: cg@2850: "Modified: / 10-08-2006 / 12:55:22 / cg" cg@2850: ! cg@2850: cg@2850: iconAndLabelHolder cg@2850: ^ iconAndLabelHolder cg@2850: ! cg@2850: cg@2850: imageHolder cg@2850: ^ imageHolder. cg@2850: ! cg@2850: cg@2850: imageList cg@2850: ^ imageList cg@2850: ! cg@2850: cg@2850: modifiedChannel cg@2850: ^ builder booleanValueAspectFor: #modifiedChannel cg@2850: ! cg@2850: cg@2850: modifiedChannel:aChannel cg@2850: builder aspectAt:#modifiedChannel put:aChannel. cg@2850: ! cg@2850: cg@2850: retrieverHolder cg@2850: ^ retrieverHolder cg@2850: ! cg@2850: cg@2850: retrieverList cg@3165: |listOfClassNames cls owner| cg@3165: cg@3165: listOfClassNames := builder bindingAt:#retrieverList. cg@3165: listOfClassNames isNil ifTrue:[ cg@3165: listOfClassNames := MenuEditor imageRetrieverClasses asList. cg@3165: builder aspectAt:#retrieverList put:listOfClassNames. cg@2850: ]. cg@3013: (masterApplication notNil cg@2850: and:[(cls := masterApplication specClass) notNil]) ifTrue:[ cg@3165: (listOfClassNames includes:cls name) ifFalse:[ listOfClassNames addFirst:cls name ]. cg@3165: cls isPrivate ifTrue:[ cg@3165: (owner := cls owningClass) notNil ifTrue:[ cg@3165: (listOfClassNames includes:owner name) ifFalse:[ listOfClassNames addFirst:owner name ]. cg@3165: ]. cg@3165: ]. cg@2850: ]. cg@3165: ^ listOfClassNames cg@2850: ! cg@2850: cg@2850: selectorFilterHolder cg@2850: ^ selectorFilterHolder cg@2850: cg@2850: "Created: / 03-08-2011 / 10:01:05 / cg" cg@2850: ! cg@2850: cg@2850: selectorHolder cg@2850: ^ selectorHolder. cg@2850: ! ! cg@2850: cg@2850: !MenuEditor::ImageResourceEditor methodsFor:'change & update'! cg@2850: cg@2850: retrieverChanged cg@2850: |retriever list name| cg@2850: cg@2850: retriever := self retrieverClass. cg@2850: imageHolder setValue:nil. cg@2850: cg@2850: self updateImageList. cg@2850: self updateSelectedImage. cg@2850: cg@2850: (retriever notNil and:[imageList size ~~ 0]) ifTrue:[ cg@3013: list := self retrieverList. cg@3013: name := retriever name. cg@3013: cg@3013: (list includes:name) ifFalse:[ cg@3013: list add:(name asSymbol). cg@3013: ] cg@2850: ]. cg@2850: cg@2850: "Modified: / 03-08-2011 / 10:56:58 / cg" cg@2850: ! cg@2850: cg@2850: selectorChanged cg@2850: self updateSelectedImage. cg@2850: cg@2850: "Modified: / 03-08-2011 / 10:56:04 / cg" cg@2850: ! cg@2850: cg@2850: selectorFilterChanged cg@2850: self updateImageList. cg@2850: self updateSelectedImage. cg@2850: cg@2850: "Created: / 03-08-2011 / 10:58:47 / cg" cg@2850: ! cg@2850: cg@2850: update:what with:aPara from:aModel cg@2850: |item| cg@2850: cg@2850: self modifiedChannel value:true. cg@2850: cg@2850: aModel == retrieverHolder ifTrue:[ self retrieverChanged. ^ self ]. cg@2850: aModel == selectorHolder ifTrue:[ self selectorChanged. ^ self ]. cg@2850: aModel == selectorFilterHolder ifTrue:[ self selectorFilterChanged. ^ self ]. cg@2850: cg@2850: aModel == imageHolder ifTrue:[ cg@3013: item := imageHolder value. cg@3013: item notNil ifTrue:[ cg@3013: selectorHolder value:(item label) cg@3013: ]. cg@3013: ^ self cg@2850: ]. cg@2850: super update:what with:aPara from:aModel cg@2850: cg@2862: "Modified: / 29-11-2011 / 11:28:26 / cg" cg@2850: ! cg@2850: cg@2850: updateImageList cg@2850: |retriever selectorFilterString filter| cg@2850: cg@2850: retriever := self retrieverClass. cg@2850: cg@2850: filter := [:sel | true]. cg@2850: (selectorFilterString := selectorFilterHolder value) notEmptyOrNil ifTrue:[ sv@3431: selectorFilterString includesMatchCharacters ifTrue:[ sv@3431: filter := [:sel | selectorFilterString match:sel caseSensitive:false]. sv@3431: ] ifFalse:[ sv@3431: filter := [:sel | sel includesString:selectorFilterString caseSensitive:false]. sv@3431: ]. cg@2850: ]. cg@2850: cg@2850: imageList root updateFromClass:retriever selectorFilter:filter. cg@2850: cg@2850: "Created: / 03-08-2011 / 10:56:41 / cg" sv@3431: "Modified: / 27-03-2017 / 12:54:00 / stefan" cg@2850: ! cg@2850: cg@2850: updateSelectedImage cg@2850: "provider or selector has changed; select it in the list" cg@2850: cg@2850: |item selector line| cg@2850: cg@2850: imageList isEmpty ifTrue:[^ self]. cg@2850: cg@2850: selector := selectorHolder value. cg@3013: selector isEmptyOrNil ifTrue:[ cg@3013: imageHolder value:nil. cg@3013: ^ self cg@2850: ]. cg@2850: cg@2850: item := nil. cg@2850: selector := selector asSymbol. cg@2850: cg@3013: imageList do:[:anItem| cg@3013: |sel| cg@3013: cg@3013: sel := anItem selector. cg@3013: selector == sel ifTrue:[ cg@3013: imageHolder value:anItem. cg@3013: ^ self cg@3013: ]. cg@3013: item isNil ifTrue:[ cg@3013: (sel startsWith:selector) ifTrue:[ item := anItem ] cg@3013: ] cg@2850: ]. cg@2850: imageHolder value:nil. cg@2850: cg@2862: item notNil ifTrue:[ cg@3013: line := imageList identityIndexOf:item. cg@3013: line ~~ 0 ifTrue:[ cg@3013: "/ imageListView scrollToLine:line cg@3013: imageListView makeLineVisible:line cg@3013: ] cg@2850: ]. cg@2850: cg@2850: "Created: / 03-08-2011 / 10:55:45 / cg" cg@2850: ! ! cg@2850: cg@2850: !MenuEditor::ImageResourceEditor methodsFor:'initialization'! cg@2850: cg@2850: initialize cg@2850: super initialize. cg@2850: cg@2850: iconAndLabelHolder := true asValue. cg@2850: iconAndLabelHolder addDependent:self. cg@2850: cg@2850: imageHolder := nil asValue. cg@2850: cg@2850: selectorHolder := nil asValue. cg@2850: selectorHolder addDependent:self. cg@2850: cg@2850: imageList := HierarchicalList new. cg@2850: imageList application:self. cg@2850: imageList root:(ImageResourceEditorItem new). cg@2850: imageList showRoot:false. cg@2850: cg@2850: imageHolder := nil asValue. cg@2850: imageHolder addDependent:self. cg@2850: cg@2850: retrieverHolder := nil asValue. cg@2850: retrieverHolder addDependent:self. cg@2850: cg@2850: selectorFilterHolder := '' asValue. cg@2850: selectorFilterHolder addDependent:self. cg@2850: cg@2850: "Modified: / 03-08-2011 / 10:18:46 / cg" cg@2850: ! cg@2850: cg@2850: postBuildImageViewer:aWidget cg@2850: imageListView := aWidget. cg@2850: ! ! cg@2850: cg@2850: !MenuEditor::ImageResourceEditor::ImageResourceEditorItem methodsFor:'accessing'! cg@2850: cg@2850: icon cg@2850: ^ icon cg@2850: ! cg@2850: cg@2850: label cg@2850: ^ selector cg@2850: ! cg@2850: cg@2850: selector cg@2850: ^ selector cg@2850: ! ! cg@2850: cg@2850: !MenuEditor::ImageResourceEditor::ImageResourceEditorItem methodsFor:'instance creation'! cg@2850: cg@2850: forClass:aClass selector:aSelector cg@2850: |w h magnify iconOrSymbol| cg@2850: cg@2850: selector := aSelector asSymbol. cg@2850: selector numArgs == 0 ifFalse:[^ self]. cg@2850: cg@2850: "do what the ResourceRetriever will do" cg@2850: (aClass respondsTo:#visualFor:) ifTrue:[ cg@3013: iconOrSymbol := aClass visualFor:selector. cg@2850: ]. cg@2850: iconOrSymbol isNil ifTrue:[ cg@3013: iconOrSymbol := aClass perform:selector. cg@2850: ]. cg@2948: iconOrSymbol isNil ifTrue:[^ self]. cg@2948: cg@2850: iconOrSymbol isSymbol ifTrue:[ cg@3013: icon := ToolbarIconLibrary perform:iconOrSymbol. cg@2850: ] ifFalse:[ cg@3013: icon := iconOrSymbol. cg@2850: ]. cg@2850: cg@2850: w := icon width. cg@2850: h := icon height. cg@2850: cg@2850: w > 32 ifTrue:[ cg@3013: magnify := 32 / w. cg@3013: h > 32 ifTrue:[ magnify := (32 / h) max:magnify ]. cg@2850: ] ifFalse:[ cg@3013: h > 32 ifFalse:[^ self]. cg@3013: magnify := 32 / h. cg@2850: ]. cg@2850: icon := icon magnifiedBy: magnify. cg@2850: cg@2850: "Modified: / 13-04-2011 / 18:56:45 / cg" cg@2850: "Created: / 03-08-2011 / 10:47:16 / cg" cg@2850: ! cg@2850: cg@2850: initialize cg@3396: "must be called if redefined" cg@3396: cg@2850: super initialize. cg@2850: children := #(). cg@3396: cg@3396: "Modified: / 08-02-2017 / 00:28:37 / cg" cg@2850: ! cg@2850: cg@2850: updateFromClass:aClass selectorFilter:aFilterBlock cg@2850: (aClass notNil and:[aClass isBehavior]) ifFalse:[ sv@3110: ^ self collapse. cg@2850: ]. cg@2850: "/ aClass == selector ifTrue:[ cg@2850: "/ ^ self expand cg@2850: "/ ]. cg@2850: self collapse. cg@2850: cg@2850: selector := aClass. cg@2850: cg@2850: self application withWaitCursorDo:[ sv@3110: |methods| sv@3110: methods := aClass methodsWithAnyResource:#(image programImage). sv@3110: children := methods sv@3110: select:[:each| aFilterBlock value:each selector] sv@3110: thenCollect:[:each| sv@3110: |item| sv@3110: item := self class new forClass:aClass selector:each selector. sv@3110: item parent:self. sv@3110: ]. sv@3110: sv@3110: children sort:[:a :b | a label < b label ]. sv@3110: self expand cg@2850: ]. cg@2850: cg@2850: "Created: / 03-08-2011 / 10:48:10 / cg" cg@2850: ! ! cg@2850: cg@2850: !MenuEditor::ImageResourceEditor::ImageResourceEditorItem methodsFor:'user operations'! cg@2850: cg@2850: doEdit cg@2850: "open image browser on self" cg@2850: cg@2850: |parent aClass image| cg@2850: cg@2850: parent := self parent. cg@2850: parent notNil ifTrue:[ cg@3013: aClass := parent selector. cg@3013: (aClass respondsTo:#visualFor:) ifTrue:[ cg@3013: image := aClass visualFor:selector. cg@3013: image ~~ (aClass perform:selector) ifTrue:[ cg@3013: self warn:'The image is resolved via #visualFor: from some unknown class'. cg@3013: ImageEditor openOnImage:image. cg@3013: ^ self. cg@3013: ]. cg@3013: ]. cg@3013: ImageEditor openOnClass:aClass andSelector:selector. cg@2850: ]. cg@2850: ! ! cg@2850: cg@1631: !MenuEditor::ActionItem class methodsFor:'defaults'! ca@1606: ca@1606: defaultLabel ca@1606: ^ 'Action' ca@1606: ! ! ca@1606: cg@1668: !MenuEditor::ActionItem class methodsFor:'interface specs'! ca@1606: ca@1606: basicsEditSpec ca@1606: "This resource specification was automatically generated ca@1606: by the UIPainter of ST/X." ca@1606: ca@1606: "Do not manually edit this!! If it is corrupted, ca@1606: the UIPainter may not be able to read the specification." ca@1606: ca@1606: " ca@1634: UIPainter new openOnClass:MenuEditor::ActionItem andSelector:#basicsEditSpec ca@1606: " ca@1606: ca@1606: ca@1606: cg@3029: ^ sv@1737: #(FullSpec cg@3029: name: basicsEditSpec cg@3029: window: sv@1737: (WindowSpec cg@3029: label: 'basicsEditSpec' cg@3029: name: 'basicsEditSpec' cg@3029: min: (Point 10 10) cg@3029: bounds: (Rectangle 0 0 340 340) cg@3029: ) cg@3029: component: sv@1737: (SpecCollection cg@3029: collection: ( cg@3029: (LabelSpec cg@3029: label: 'Name Key:' cg@3029: name: 'nameKeyLabel' cg@3029: layout: (AlignmentOrigin 107 0 25 0 1 0.5) cg@3029: activeHelpKey: basicsKey cg@3029: translateLabel: true cg@3029: resizeForLabel: true cg@3029: adjust: right cg@3029: ) cg@3029: (InputFieldSpec cg@3029: name: 'nameKeyField' cg@3029: layout: (LayoutFrame 110 0 15 0 -5 1.0 37 0) cg@3029: activeHelpKey: basicsKey cg@3029: tabable: true cg@3029: model: nameKey cg@3029: group: inputGroup cg@3029: type: symbolOrNil cg@3029: immediateAccept: false cg@3029: acceptOnLeave: false cg@3029: acceptOnReturn: true cg@3029: acceptOnTab: true cg@3029: acceptOnLostFocus: false cg@3029: acceptChannel: acceptChannel cg@3029: modifiedChannel: modifiedChannel cg@3029: acceptOnPointerLeave: false cg@3029: ) cg@3029: (LabelSpec cg@3029: label: 'Label:' cg@3029: name: 'labelLabel' cg@3029: layout: (AlignmentOrigin 107 0 51 0 1 0.5) cg@3029: activeHelpKey: basicsLabel cg@3029: translateLabel: true cg@3029: resizeForLabel: true cg@3029: adjust: right cg@3029: ) cg@3029: (InputFieldSpec cg@3029: name: 'labelField' cg@3029: layout: (LayoutFrame 110 0 40 0 -5 1.0 62 0) cg@3029: activeHelpKey: basicsLabel cg@3029: tabable: true cg@3029: model: rawLabel cg@3029: group: inputGroup cg@3029: immediateAccept: false cg@3029: acceptOnReturn: true cg@3029: acceptOnTab: true cg@3029: acceptOnLostFocus: false cg@3029: acceptChannel: acceptChannel cg@3029: modifiedChannel: modifiedChannel cg@3029: acceptOnPointerLeave: false cg@3029: ) cg@3029: (LabelSpec cg@3029: label: 'Action:' cg@3029: name: 'valueLabel' cg@3029: layout: (AlignmentOrigin 107 0 82 0 1 0.5) cg@3029: activeHelpKey: basicsAction cg@3029: translateLabel: true cg@3029: resizeForLabel: true cg@3029: adjust: right cg@3029: ) cg@3029: (InputFieldSpec cg@3029: name: 'valueField' cg@3029: layout: (LayoutFrame 110 0 71 0 -25 1.0 93 0) cg@3029: activeHelpKey: basicsAction cg@3029: tabable: true cg@3029: model: itemValue cg@3029: group: inputGroup cg@3029: type: symbolOrNil cg@3029: immediateAccept: false cg@3029: acceptOnLeave: true cg@3029: acceptOnReturn: true cg@3029: acceptOnTab: true cg@3029: acceptOnLostFocus: true cg@3029: acceptChannel: acceptChannel cg@3029: modifiedChannel: modifiedChannel cg@3029: acceptOnPointerLeave: true cg@3029: ) cg@3029: (ActionButtonSpec cg@3029: label: 'browseActionImage' cg@3029: name: 'Button1' cg@3029: layout: (LayoutFrame -25 1 71 0 -5 1 93 0) cg@3029: activeHelpKey: browseMethod cg@3029: hasCharacterOrientedLabel: false cg@3029: translateLabel: true cg@3029: resizeForLabel: true cg@3029: tabable: true cg@3029: model: doBrowseActionMethod cg@3029: ) cg@3029: (LabelSpec cg@3029: label: 'Argument:' cg@3029: name: 'argumentLabel' cg@3029: layout: (AlignmentOrigin 107 0 107 0 1 0.5) cg@3029: activeHelpKey: basicsArgument cg@3029: translateLabel: true cg@3029: resizeForLabel: true cg@3029: adjust: right cg@3029: ) cg@3029: (InputFieldSpec cg@3029: name: 'argumentField' cg@3029: layout: (LayoutFrame 110 0 96 0 -5 1.0 118 0) cg@3029: activeHelpKey: basicsArgument cg@3029: tabable: true cg@3029: model: argument cg@3029: group: inputGroup cg@3029: type: smalltalkObjectOrNil cg@3029: immediateAccept: false cg@3029: acceptOnReturn: true cg@3029: acceptOnTab: true cg@3029: acceptOnLostFocus: false cg@3029: acceptChannel: acceptChannel cg@3029: modifiedChannel: modifiedChannel cg@3029: acceptOnPointerLeave: false cg@3029: ) cg@3029: (LabelSpec cg@3029: label: 'Indication:' cg@3029: name: 'indicationLabel' cg@3029: layout: (AlignmentOrigin 107 0 138 0 1 0.5) cg@3029: activeHelpKey: basicsIndication cg@3029: translateLabel: true cg@3029: resizeForLabel: true cg@3029: adjust: right cg@3029: ) cg@3029: (InputFieldSpec cg@3029: name: 'indicationField' cg@3029: layout: (LayoutFrame 110 0 127 0 -25 1.0 149 0) cg@3029: activeHelpKey: basicsIndication cg@3029: enableChannel: indicationEnabled cg@3029: tabable: true cg@3029: model: indication cg@3029: group: inputGroup cg@3029: type: symbolOrNil cg@3029: immediateAccept: true cg@3029: acceptOnReturn: false cg@3029: acceptOnTab: false cg@3029: acceptOnLostFocus: false cg@3029: modifiedChannel: modifiedChannel cg@3029: acceptOnPointerLeave: false cg@3029: ) cg@3029: (ActionButtonSpec cg@3029: label: 'browseActionImage' cg@3029: name: 'Button2' cg@3029: layout: (LayoutFrame -25 1 127 0 -5 1 149 0) cg@3029: activeHelpKey: browseMethod cg@3029: hasCharacterOrientedLabel: false cg@3029: translateLabel: true cg@3029: resizeForLabel: true cg@3029: tabable: true cg@3029: model: doBrowseIndicationMethod cg@3029: ) cg@3029: (LabelSpec cg@3029: label: 'Choice:' cg@3029: name: 'choiceLabel' cg@3029: layout: (AlignmentOrigin 107 0 163 0 1 0.5) cg@3029: activeHelpKey: basicsChoice cg@3029: translateLabel: true cg@3029: resizeForLabel: true cg@3029: adjust: right cg@3029: ) cg@3029: (InputFieldSpec cg@3029: name: 'choiceField' cg@3029: layout: (LayoutFrame 110 0 152 0 -25 1.0 174 0) cg@3029: activeHelpKey: basicsChoice cg@3029: enableChannel: choiceEnabled cg@3029: tabable: true cg@3029: model: choice cg@3029: group: inputGroup cg@3029: type: symbolOrNil cg@3029: immediateAccept: true cg@3029: acceptOnReturn: false cg@3029: acceptOnTab: false cg@3029: acceptOnLostFocus: false cg@3029: modifiedChannel: modifiedChannel cg@3029: acceptOnPointerLeave: false cg@3029: ) cg@3029: (ActionButtonSpec cg@3029: label: 'browseActionImage' cg@3029: name: 'Button3' cg@3029: layout: (LayoutFrame -25 1 152 0 -5 1 174 0) cg@3029: activeHelpKey: browseMethod cg@3029: hasCharacterOrientedLabel: false cg@3029: translateLabel: true cg@3029: resizeForLabel: true cg@3029: tabable: true cg@3029: model: doBrowseChoiceMethod cg@3029: ) cg@3029: (LabelSpec cg@3029: label: 'Value:' cg@3029: name: 'choiceValueLabel' cg@3029: layout: (AlignmentOrigin 107 0 188 0 1 0.5) cg@3029: activeHelpKey: basicsChoiceValue cg@3029: translateLabel: true cg@3029: resizeForLabel: true cg@3029: adjust: right cg@3029: ) cg@3029: (InputFieldSpec cg@3029: name: 'choiceValueField' cg@3029: layout: (LayoutFrame 110 0 177 0 -5 1.0 199 0) cg@3029: activeHelpKey: basicsChoiceValue cg@3029: enableChannel: choiceValueEnabled cg@3029: tabable: true cg@3029: model: choiceValue cg@3029: group: inputGroup cg@3029: type: smalltalkObjectOrNil cg@3029: immediateAccept: false cg@3029: acceptOnLeave: false cg@3029: acceptOnReturn: true cg@3029: acceptOnTab: true cg@3029: acceptOnLostFocus: false cg@3029: acceptChannel: acceptChannel cg@3029: modifiedChannel: modifiedChannel cg@3029: acceptOnPointerLeave: false cg@3029: ) cg@3029: (CheckBoxSpec cg@3029: label: 'Translate Label' cg@3029: name: 'translateLabelCheckBox' cg@3029: layout: (AlignmentOrigin 7 0 213 0 0 0) cg@3029: activeHelpKey: basicsTranslateLabel cg@3029: tabable: true cg@3029: model: translateLabel cg@3029: translateLabel: true cg@3029: ) cg@3029: (CheckBoxSpec cg@3029: label: 'Is Button' cg@3029: name: 'isButtonCheckBox' cg@3029: layout: (AlignmentOrigin 7 0 238 0 0 0) cg@3029: activeHelpKey: basicsIsButton cg@3029: tabable: true cg@3029: model: isButton cg@3029: translateLabel: true cg@3029: ) cg@3029: (CheckBoxSpec cg@3029: label: 'Hide Menu after Activation' cg@3029: name: 'hideMenuOnActivated' cg@3029: layout: (AlignmentOrigin 7 0 263 0 0 0) cg@3029: activeHelpKey: hideMenuOnActivated cg@3029: tabable: true cg@3029: model: hideMenuOnActivated cg@3029: translateLabel: true cg@3029: ) cg@3029: (CheckBoxSpec cg@3029: label: 'BusyCursor while Active' cg@3029: name: 'showBusyCursorWhilePerforming' cg@3029: layout: (AlignmentOrigin 7 0 288 0 0 0) cg@3029: activeHelpKey: showBusyCursorWhilePerforming cg@3029: tabable: true cg@3029: model: showBusyCursorWhilePerforming cg@3029: translateLabel: true cg@3029: ) cg@3029: (CheckBoxSpec cg@3365: label: 'Trigger on Down' cg@3029: name: 'triggerOnDown' cg@3029: layout: (AlignmentOrigin 25 0.5 238 0 0 0) cg@3029: activeHelpKey: triggerOnDown cg@3029: enableChannel: hasNoDelayedMenuValue cg@3029: tabable: true cg@3029: model: triggerOnDown cg@3029: translateLabel: true cg@3029: ) cg@3029: (CheckBoxSpec cg@3365: label: 'Send to Originating Widget' cg@3029: name: 'sendToOriginator' cg@3029: layout: (AlignmentOrigin 7 0 313 0 0 0) cg@3029: activeHelpKey: sendToOriginator cg@3029: enableChannel: hasItemValue cg@3029: tabable: true cg@3029: model: sendToOriginator cg@3029: translateLabel: true cg@3029: ) cg@3029: ) cg@3029: cg@3029: ) ca@1606: ) ca@199: ! ! ca@199: cg@1725: !MenuEditor::ActionItem class methodsFor:'interface-editor'! cg@1725: cg@1725: addBindingsTo:aspects for:aMenuEditor cg@1725: "add additional bindings to the aspects cg@1725: " cg@3013: aspects cg@3013: at:#indicationEnabled cg@3013: ifAbsentPut:[ BlockValue with:[:a | a size == 0 ] argument:(aspects at:#choice)]. cg@3013: cg@3013: aspects cg@3013: at:#choiceEnabled cg@3013: ifAbsentPut:[ BlockValue with:[:a | a size == 0 ] argument:(aspects at:#indication)]. cg@3013: cg@3013: aspects cg@3013: at:#choiceValueEnabled cg@3013: ifAbsentPut:[ BlockValue with:[:a | a size ~~ 0 ] argument:(aspects at:#choice)]. cg@3013: cg@3013: aspects cg@3013: at:#hasNoDelayedMenuValue cg@3013: ifAbsentPut:[true asValue]. cg@1725: ! ! cg@1725: cg@1631: !MenuEditor::ActionItem methodsFor:'accessing'! ca@1606: ca@1606: menuItem ca@1606: |item| ca@1606: ca@1606: item := super menuItem. ca@1606: self hasDelayedMenu ifTrue:[ cg@2188: children first setDelayedAttributesTo:item. cg@2188: cg@2188: menuItem value isNil ifTrue:[ cg@2188: menuItem value:#unspecified cg@2188: ] ca@199: ]. ca@1606: ^ item ca@199: ! ca@199: ca@213: menuItem:anItem ca@1606: |submenu item| ca@1606: ca@1606: super menuItem:anItem. ca@1606: submenu := anItem submenu. ca@1606: ca@1606: submenu notNil ifTrue:[ cg@2188: item := MenuEditor::RegularMenuItem new ca@1606: ] ifFalse:[ cg@2188: anItem submenuChannel isNil ifTrue:[ cg@2188: ^ self cg@2188: ]. cg@2188: item := MenuEditor::LinkedMenuItem new ca@1606: ]. ca@1606: item getDelayedAttributesFrom:anItem. ca@1606: self add:item. ca@199: ! ca@199: ca@1606: slices ca@1606: ^ #( ca@1606: (Basics basicsEditSpec ) ca@1606: (Details detailsEditSpec) ca@1606: (Image image ) ca@1606: (Help help) ca@1606: ) ca@199: ! ! ca@199: cg@1631: !MenuEditor::ActionItem methodsFor:'adding & removing'! ca@1606: cg@2188: add:anItem ca@1606: "add an item; test whether the item is a delayed menu and cg@2075: not already a delayed menu exists." cg@2188: cg@2075: (anItem isKindOfMenu and:[ self canAddDelayedMenu ]) ifFalse:[ cg@2188: ^ nil ca@853: ]. cg@2188: ca@1606: menuItem triggerOnDown:false. cg@2075: anItem argument:(menuItem argument). ca@1606: isExpanded := false. ca@1606: anItem parent:self. ca@1606: children := Array with:anItem. ca@1606: self expand. cg@2075: ^ anItem cg@2075: cg@2075: "Modified: / 05-09-2006 / 17:49:57 / cg" ca@199: ! ! ca@199: cg@1631: !MenuEditor::ActionItem methodsFor:'aspects'! ca@1606: ca@1606: aspectAt:aKey put:aValue cg@2075: "set a specific aspect named aKey to the aValue" cg@2075: ca@1606: aKey == #argument ifTrue:[ cg@3013: self hasDelayedMenu ifTrue:[ cg@3013: children first argument:aValue cg@3013: ]. cg@3013: menuItem argument:aValue. cg@3013: ^ self ca@1606: ]. ca@1778: ca@1623: aKey == #triggerOnDown ifTrue:[ cg@3013: |triggerOnDown| cg@3013: cg@3013: self hasDelayedMenu ifTrue:[ cg@3013: triggerOnDown := false cg@3013: ] ifFalse:[ cg@3013: triggerOnDown := aValue cg@3013: ]. cg@3013: menuItem triggerOnDown:triggerOnDown. cg@3013: ^ self. ca@1623: ]. ca@1606: super aspectAt:aKey put:aValue. cg@2055: cg@2075: "Modified: / 05-09-2006 / 17:47:24 / cg" ca@1606: ! ca@1606: ca@1606: toAspects:aspects ca@1606: "write values to aspects ca@1606: " ca@1623: |hasDelayedMenu| ca@1623: ca@1606: super toAspects:aspects. ca@1606: ca@1623: hasDelayedMenu := self hasDelayedMenu. ca@1623: (aspects at:#hasNoDelayedMenuValue) value:(hasDelayedMenu not). ca@1623: ca@1623: hasDelayedMenu ifTrue:[ cg@2188: (aspects at:#triggerOnDown) value:false ca@1623: ]. ca@356: ! ! ca@356: cg@1631: !MenuEditor::ActionItem methodsFor:'displaying'! ca@1606: ca@1606: icon ca@1606: ^ self class iconItem ca@1606: ! ! ca@1606: cg@1631: !MenuEditor::ActionItem methodsFor:'initialization'! ca@199: ca@199: initialize cg@3396: "must be called if redefined" cg@3396: ca@199: super initialize. ca@1606: isExpanded := true. cg@3396: cg@3396: "Modified: / 08-02-2017 / 00:28:28 / cg" ca@1606: ! ! ca@1606: cg@1631: !MenuEditor::ActionItem methodsFor:'queries'! ca@1606: ca@1606: canCollapse ca@1606: ^ false ca@1606: ! ca@1606: ca@1606: hasDelayedMenu ca@1606: "returns true if a delayed menu exists ca@1606: " ca@1606: ^ children size ~~ 0 ca@1606: ! ca@1606: ca@1606: hasIndicator ca@1606: ^ false ca@1606: ! ca@1606: ca@1606: isAction ca@1606: ^ true ca@1606: ! ! ca@1606: cg@1660: !MenuEditor::ActionItem methodsFor:'queries-operation'! ca@1606: ca@1606: canAddDelayedMenu ca@1623: "returns true if a delayed menu can be added ca@1606: " ca@1623: ^ self hasDelayedMenu not ca@1606: ! ! ca@1606: cg@1631: !MenuEditor::LinkedMenuItem class methodsFor:'defaults'! ca@1606: ca@1606: defaultLabel ca@1606: ^ 'Linked Menu' ca@199: ! ! ca@199: cg@1668: !MenuEditor::LinkedMenuItem class methodsFor:'interface specs'! ca@1606: ca@1606: basicsEditSpec ca@1606: "This resource specification was automatically generated ca@1606: by the UIPainter of ST/X." ca@1606: ca@1606: "Do not manually edit this!! If it is corrupted, ca@1606: the UIPainter may not be able to read the specification." ca@1606: ca@1606: " sv@1737: UIPainter new openOnClass:MenuEditor::LinkedMenuItem andSelector:#basicsEditSpec ca@1606: " ca@1606: ca@1606: ca@1606: cg@2188: ^ sv@1737: #(FullSpec cg@3013: name: basicsEditSpec cg@3013: window: sv@1737: (WindowSpec cg@3013: label: 'basicsEditSpec' cg@3013: name: 'basicsEditSpec' cg@3013: min: (Point 10 10) cg@3013: bounds: (Rectangle 0 0 340 340) cg@3013: ) cg@3013: component: sv@1737: (SpecCollection cg@3013: collection: ( cg@3013: (LabelSpec cg@3013: label: 'Name Key:' cg@3013: name: 'nameKeyLabel' cg@3013: layout: (AlignmentOrigin 107 0 25 0 1 0.5) cg@3013: activeHelpKey: basicsKey cg@3013: visibilityChannel: notDelayedMenu cg@3013: translateLabel: true cg@3013: resizeForLabel: true cg@3013: adjust: right cg@3013: ) cg@3013: (InputFieldSpec cg@3013: name: 'nameKeyField' cg@3013: layout: (LayoutFrame 110 0 15 0 -5 1.0 37 0) cg@3013: activeHelpKey: basicsKey cg@3013: visibilityChannel: notDelayedMenu cg@3013: tabable: true cg@3013: model: nameKey cg@3013: group: inputGroup cg@3013: type: symbolOrNil cg@3013: immediateAccept: false cg@3013: acceptOnLeave: false cg@3013: acceptOnReturn: true cg@3013: acceptOnTab: true cg@3013: acceptOnLostFocus: false cg@3013: acceptChannel: acceptChannel cg@3013: modifiedChannel: modifiedChannel cg@3013: acceptOnPointerLeave: false cg@3013: ) cg@3013: (LabelSpec cg@3013: label: 'Label:' cg@3013: name: 'labelLabel' cg@3013: layout: (AlignmentOrigin 107 0 51 0 1 0.5) cg@3013: activeHelpKey: basicsLabel cg@3013: visibilityChannel: notDelayedMenu cg@3013: translateLabel: true cg@3013: resizeForLabel: true cg@3013: adjust: right cg@3013: ) cg@3013: (InputFieldSpec cg@3013: name: 'labelField' cg@3013: layout: (LayoutFrame 110 0 40 0 -5 1.0 62 0) cg@3013: activeHelpKey: basicsLabel cg@3013: visibilityChannel: notDelayedMenu cg@3013: tabable: true cg@3013: model: rawLabel cg@3013: group: inputGroup cg@3013: immediateAccept: false cg@3013: acceptOnReturn: true cg@3013: acceptOnTab: true cg@3013: acceptOnLostFocus: false cg@3013: acceptChannel: acceptChannel cg@3013: modifiedChannel: modifiedChannel cg@3013: acceptOnPointerLeave: false cg@3013: ) cg@3013: (LabelSpec cg@3013: label: 'Menu:' cg@3013: name: 'menuLabel' cg@3013: layout: (AlignmentOrigin 107 0 90 0 1 0.5) cg@3013: activeHelpKey: basicsLabel cg@3013: translateLabel: true cg@3013: resizeForLabel: true cg@3013: adjust: right cg@3013: ) cg@3013: (InputFieldSpec cg@3013: name: 'menuField' cg@3013: layout: (LayoutFrame 110 0 79 0 -5 1.0 101 0) cg@3013: activeHelpKey: basicsMenu cg@3013: tabable: true cg@3013: model: submenuChannel cg@3013: group: inputGroup cg@3013: type: symbolOrNil cg@3013: immediateAccept: false cg@3013: acceptOnReturn: true cg@3013: acceptOnTab: true cg@3013: acceptOnLostFocus: false cg@3013: acceptChannel: acceptChannel cg@3013: modifiedChannel: modifiedChannel cg@3013: acceptOnPointerLeave: false cg@3013: ) cg@3013: (LabelSpec cg@3013: label: 'Argument:' cg@3013: name: 'argumentLabel' cg@3013: layout: (AlignmentOrigin 107 0 115 0 1 0.5) cg@3013: activeHelpKey: basicsLabel cg@3013: translateLabel: true cg@3013: resizeForLabel: true cg@3013: adjust: right cg@3013: ) cg@3013: (InputFieldSpec cg@3013: name: 'argumentField' cg@3013: layout: (LayoutFrame 110 0 104 0 -5 1.0 126 0) cg@3013: activeHelpKey: basicsMenuArgument cg@3013: enableChannel: notDelayedMenu cg@3013: tabable: true cg@3013: model: argument cg@3013: group: inputGroup cg@3013: type: smalltalkObjectOrNil cg@3013: immediateAccept: false cg@3013: acceptOnReturn: true cg@3013: acceptOnTab: true cg@3013: acceptOnLostFocus: false cg@3013: acceptChannel: acceptChannel cg@3013: modifiedChannel: modifiedChannel cg@3013: acceptOnPointerLeave: false cg@3013: ) cg@3013: (CheckBoxSpec cg@3013: label: 'Translate Label' cg@3013: name: 'translateLabelCheckBox' cg@3013: layout: (Point 20 213) cg@3013: activeHelpKey: basicsTranslateLabel cg@3013: visibilityChannel: notDelayedMenu cg@3013: tabable: true cg@3013: model: translateLabel cg@3013: translateLabel: true cg@3013: ) cg@3013: (CheckBoxSpec cg@3013: label: 'Is Button' cg@3013: name: 'isButtonCheckBox' cg@3013: layout: (Point 20 238) cg@3013: activeHelpKey: basicsIsButton cg@3013: visibilityChannel: notDelayedMenu cg@3013: tabable: true cg@3013: model: isButton cg@3013: translateLabel: true cg@3013: ) cg@3013: (CheckBoxSpec cg@3013: label: 'Horizontal Layout' cg@3013: name: 'horizontalLayout' cg@3013: layout: (Point 20 263) cg@3013: activeHelpKey: horizontalLayout cg@3013: tabable: true cg@3013: model: horizontalLayout cg@3013: translateLabel: true cg@3013: ) cg@3013: (CheckBoxSpec cg@3013: label: 'Do not Destroy Linked Menu' cg@3013: name: 'keepLinkedMenu' cg@3013: layout: (Point 20 288) cg@3013: activeHelpKey: keepLinkedMenu cg@3013: tabable: true cg@3013: model: keepLinkedMenu cg@3013: translateLabel: true cg@3013: ) cg@3013: ) cg@3013: cg@3013: ) ca@1606: ) ca@1606: ! ! ca@1606: cg@1631: !MenuEditor::LinkedMenuItem methodsFor:'accessing'! ca@1606: ca@1606: argument:aValue ca@1606: menuItem argument:aValue. ca@1606: ! ca@1606: ca@1606: menuItem ca@1606: "returns self as a MenuItem ca@1606: " ca@1606: |item| ca@1606: ca@1606: item := super menuItem. ca@1606: item submenuChannel:(self submenuChannel). ca@1606: ^ item ca@1606: ! ca@1606: ca@1606: slices ca@1606: self isDelayedMenu ifTrue:[ cg@2188: ^ #( cg@2188: (Basics basicsEditSpec ) cg@2188: ) ca@1389: ]. ca@1389: ca@1606: ^ #( cg@2188: (Basics basicsEditSpec ) cg@2188: (Details detailsEditSpec) cg@2188: (Image image ) cg@2188: (Help help) ca@1606: ) cg@3511: ! ! cg@3511: cg@3511: !MenuEditor::LinkedMenuItem methodsFor:'accessing-channels'! ca@1606: ca@1606: submenuChannel ca@1606: ^ menuItem submenuChannel ? #unspecified ca@1606: ! ca@1606: ca@1606: submenuChannel:aValue ca@1606: menuItem submenuChannel:aValue. ca@1606: ! ! ca@1606: cg@1631: !MenuEditor::LinkedMenuItem methodsFor:'aspects'! ca@1606: ca@1606: aspectAt:aKey put:aValue cg@2075: "set a specific aspect named aKey to the aValue" cg@2075: ca@1606: aKey == #submenuChannel ifTrue:[ ^ self submenuChannel:aValue ]. ca@1606: super aspectAt:aKey put:aValue. cg@2075: cg@2075: "Modified: / 05-09-2006 / 17:47:39 / cg" ca@1606: ! ca@1606: ca@1653: getDelayedAttributesFrom:anItem ca@1653: ca@1606: menuItem rawLabel:'Delayed'. ca@1606: ca@1653: menuItem submenuChannel:(self validateValue:(anItem submenuChannel)). ca@1653: menuItem horizontalLayout:(self validateValue:(anItem horizontalLayout)). cg@1881: menuItem keepLinkedMenu:(self validateValue:(anItem keepLinkedMenu)). ca@1389: ! ca@1389: ca@1606: setDelayedAttributesTo:aMenuItem ca@1606: aMenuItem submenuChannel:(self submenuChannel). ca@1606: aMenuItem horizontalLayout:(menuItem horizontalLayout). ca@1606: aMenuItem keepLinkedMenu:(menuItem keepLinkedMenu). ca@1606: ! ! ca@1606: cg@1631: !MenuEditor::LinkedMenuItem methodsFor:'displaying'! ca@1606: ca@1606: displayLabel ca@1606: "returns the label dependent on is delayed or not ca@1606: " ca@1606: self isDelayedMenu ifTrue:[ ^ self submenuChannel ]. ca@1606: ^ menuItem rawLabel ca@199: ! ca@199: ca@1606: icon ca@1606: self isDelayedMenu ifTrue:[ ^ self class iconDelayedLinkedMenu ]. ca@1606: ^ self class iconLinkedMenu ca@1606: ! ! ca@1606: ca@1780: !MenuEditor::LinkedMenuItem methodsFor:'initialization'! ca@1780: ca@1780: initialize cg@3396: "setup default values on the item" cg@3396: cg@3396: "must be called if redefined" cg@3396: ca@1780: super initialize. ca@1780: ca@1780: "setting default values ca@1780: " cg@2334: "/ CG: Thu, 08 May 2008 11:16:54 GMT cg@3013: "/ I think having keepLinkedMenu true by default cg@2334: "/ will confuse newcomers (even me occasionally) cg@2334: "/ (will search, why the menu is not updated...) cg@2334: cg@2334: "/ menuItem keepLinkedMenu:true. cg@2334: menuItem keepLinkedMenu:false. cg@3396: cg@3396: "Modified (comment): / 08-02-2017 / 00:29:14 / cg" ca@1780: ! ! ca@1780: cg@1631: !MenuEditor::LinkedMenuItem methodsFor:'queries'! ca@1606: cg@3135: isKindOfLinkedMenu cg@3135: ^ true cg@3135: ! cg@3135: ca@1606: isKindOfMenu ca@1606: ^ true ca@1606: ! ! ca@1606: ca@1844: !MenuEditor::MenuSliceItem class methodsFor:'defaults'! ca@1844: ca@1844: defaultLabel ca@1844: ^ 'Menu Slice' ca@1844: ! ! ca@1844: ca@1844: !MenuEditor::MenuSliceItem class methodsFor:'interface specs'! ca@1844: ca@1844: basicsEditSpec ca@1844: "This resource specification was automatically generated ca@1844: by the UIPainter of ST/X." ca@1844: ca@1844: "Do not manually edit this!! If it is corrupted, ca@1844: the UIPainter may not be able to read the specification." ca@1844: ca@1844: " ca@1844: UIPainter new openOnClass:MenuEditor::MenuSliceItem andSelector:#basicsEditSpec ca@1844: " ca@1844: ca@1844: ca@1844: cg@2188: ^ ca@1844: #(FullSpec cg@3013: name: basicsEditSpec cg@3013: window: ca@1844: (WindowSpec cg@3013: label: 'basicsEditSpec' cg@3013: name: 'basicsEditSpec' cg@3013: min: (Point 10 10) cg@3013: bounds: (Rectangle 0 0 344 146) cg@3013: ) cg@3013: component: ca@1844: (SpecCollection cg@3013: collection: ( cg@3013: (LabelSpec cg@3013: label: 'Name Key:' cg@3013: name: 'nameKeyLabel' cg@3013: layout: (AlignmentOrigin 107 0 25 0 1 0.5) cg@3013: activeHelpKey: basicsKey cg@3013: visibilityChannel: notDelayedMenu cg@3013: translateLabel: true cg@3013: resizeForLabel: true cg@3013: adjust: right cg@3013: ) cg@3013: (InputFieldSpec cg@3013: name: 'nameKeyField' cg@3013: layout: (LayoutFrame 110 0 15 0 -5 1.0 37 0) cg@3013: activeHelpKey: basicsKey cg@3013: visibilityChannel: notDelayedMenu cg@3013: tabable: true cg@3013: model: nameKey cg@3013: group: inputGroup cg@3013: type: symbolOrNil cg@3013: immediateAccept: false cg@3013: acceptOnLeave: false cg@3013: acceptOnReturn: true cg@3013: acceptOnTab: true cg@3013: acceptOnLostFocus: false cg@3013: acceptChannel: acceptChannel cg@3013: modifiedChannel: modifiedChannel cg@3013: acceptOnPointerLeave: false cg@3013: ) cg@3013: (LabelSpec cg@3013: label: 'Label:' cg@3013: name: 'labelLabel' cg@3013: layout: (AlignmentOrigin 107 0 51 0 1 0.5) cg@3013: activeHelpKey: basicsLabel cg@3013: visibilityChannel: notDelayedMenu cg@3013: translateLabel: true cg@3013: resizeForLabel: true cg@3013: adjust: right cg@3013: ) cg@3013: (InputFieldSpec cg@3013: name: 'labelField' cg@3013: layout: (LayoutFrame 110 0 40 0 -5 1.0 62 0) cg@3013: activeHelpKey: basicsLabel cg@3013: visibilityChannel: notDelayedMenu cg@3013: tabable: true cg@3013: model: rawLabel cg@3013: group: inputGroup cg@3013: immediateAccept: false cg@3013: acceptOnReturn: true cg@3013: acceptOnTab: true cg@3013: acceptOnLostFocus: false cg@3013: acceptChannel: acceptChannel cg@3013: modifiedChannel: modifiedChannel cg@3013: acceptOnPointerLeave: false cg@3013: ) cg@3013: (LabelSpec cg@3013: label: 'Menu:' cg@3013: name: 'menuLabel' cg@3013: layout: (AlignmentOrigin 107 0 90 0 1 0.5) cg@3013: activeHelpKey: basicsLabel cg@3013: translateLabel: true cg@3013: resizeForLabel: true cg@3013: adjust: right cg@3013: ) cg@3013: (InputFieldSpec cg@3013: name: 'menuField' cg@3013: layout: (LayoutFrame 110 0 79 0 -5 1.0 101 0) cg@3013: activeHelpKey: basicsMenu cg@3013: tabable: true cg@3013: model: submenuChannel cg@3013: group: inputGroup cg@3013: type: symbolOrNil cg@3013: immediateAccept: false cg@3013: acceptOnReturn: true cg@3013: acceptOnTab: true cg@3013: acceptOnLostFocus: false cg@3013: acceptChannel: acceptChannel cg@3013: modifiedChannel: modifiedChannel cg@3013: acceptOnPointerLeave: false cg@3013: ) cg@3013: (LabelSpec cg@3013: label: 'Argument:' cg@3013: name: 'argumentLabel' cg@3013: layout: (AlignmentOrigin 107 0 115 0 1 0.5) cg@3013: activeHelpKey: basicsLabel cg@3013: translateLabel: true cg@3013: resizeForLabel: true cg@3013: adjust: right cg@3013: ) cg@3013: (InputFieldSpec cg@3013: name: 'argumentField' cg@3013: layout: (LayoutFrame 110 0 104 0 -5 1.0 126 0) cg@3013: activeHelpKey: basicsMenuArgument cg@3013: enableChannel: notDelayedMenu cg@3013: tabable: true cg@3013: model: argument cg@3013: group: inputGroup cg@3013: type: smalltalkObjectOrNil cg@3013: immediateAccept: false cg@3013: acceptOnReturn: true cg@3013: acceptOnTab: true cg@3013: acceptOnLostFocus: false cg@3013: acceptChannel: acceptChannel cg@3013: modifiedChannel: modifiedChannel cg@3013: acceptOnPointerLeave: false cg@3013: ) cg@3013: ) cg@3013: cg@3013: ) ca@1844: ) ca@1844: ! ! ca@1844: ca@1844: !MenuEditor::MenuSliceItem methodsFor:'accessing'! ca@1844: ca@1844: icon ca@1844: ^ self class iconSliceMenu ca@1844: ! ca@1844: ca@1844: menuItem ca@1844: "returns self as a MenuItem ca@1844: " ca@1844: |item| ca@1844: ca@1844: item := super menuItem. ca@1844: item submenuChannel:(self submenuChannel). ca@1844: item isMenuSlice:true. ca@1844: ^ item ca@1844: ! ca@1844: ca@1844: slices ca@1844: ^ #( cg@2188: (Basics basicsEditSpec) ca@1844: ) ca@1844: ! ! ca@1844: ca@1844: !MenuEditor::MenuSliceItem methodsFor:'aspects'! ca@1844: ca@1844: argument:aValue ca@1844: menuItem argument:aValue. ca@1844: ! ca@1844: ca@1844: aspectAt:aKey put:aValue cg@2075: "set a specific aspect named aKey to the aValue" cg@2075: ca@1844: aKey == #submenuChannel ifTrue:[ ^ self submenuChannel:aValue ]. ca@1844: aKey == #isSliceMenu ifTrue:[ ^ self ]. ca@1844: ca@1844: super aspectAt:aKey put:aValue. cg@2075: cg@2075: "Modified: / 05-09-2006 / 17:47:42 / cg" ca@1844: ! ca@1844: ca@1844: submenuChannel ca@1844: ^ menuItem submenuChannel ? #unspecified ca@1844: ! ca@1844: ca@1844: submenuChannel:aValue ca@1844: menuItem submenuChannel:aValue. ca@1844: ! ! ca@1844: ca@1633: !MenuEditor::RegularMenuItem class methodsFor:'defaults'! ca@1606: ca@1606: defaultDelayedLabel ca@1606: ^ 'delayed' ca@199: ! ca@199: ca@1606: defaultLabel ca@1606: ^ 'Menu' ca@1606: ! ! ca@1606: ca@1633: !MenuEditor::RegularMenuItem class methodsFor:'instance creation'! ca@1606: ca@1606: menu:aMenu labeled:aString ca@1606: |item| ca@1606: ca@1606: item := self new. ca@1606: item menu:aMenu labeled:aString. cg@1631: ^ item cg@1631: ! cg@1631: cg@1631: menu:aMenu labeled:aString translateLabel:translateLabel cg@1631: |item| cg@1631: cg@1631: item := self new. cg@1631: item menu:aMenu labeled:aString. cg@1631: item translateLabel:translateLabel. cg@1631: ^ item ca@1606: ! ! ca@1606: cg@1668: !MenuEditor::RegularMenuItem class methodsFor:'interface specs'! ca@1606: ca@1606: basicsEditSpec ca@1606: "This resource specification was automatically generated ca@1606: by the UIPainter of ST/X." ca@1606: ca@1606: "Do not manually edit this!! If it is corrupted, ca@1606: the UIPainter may not be able to read the specification." ca@1606: ca@1606: " sv@1737: UIPainter new openOnClass:MenuEditor::RegularMenuItem andSelector:#basicsEditSpec ca@1606: " ca@1606: ca@1606: ca@1606: cg@3587: ^ cg@3587: #(FullSpec cg@3587: name: basicsEditSpec cg@3589: uuid: '62cf58f0-9bea-11e8-8c6e-b8f6b1108e05' cg@3587: window: cg@3587: (WindowSpec cg@3587: label: 'basicsEditSpec' cg@3587: name: 'basicsEditSpec' cg@3587: uuid: 'd6768940-9be5-11e8-8c6e-b8f6b1108e05' cg@3587: min: (Point 10 10) cg@3587: bounds: (Rectangle 0 0 340 340) cg@3587: ) cg@3587: component: cg@3587: (SpecCollection cg@3587: collection: ( cg@3587: (LabelSpec cg@3587: label: 'Name Key:' cg@3587: name: 'nameKeyLabel' cg@3587: layout: (AlignmentOrigin 107 0 25 0 1 0.5) cg@3587: activeHelpKey: basicsKey cg@3587: uuid: 'd676e930-9be5-11e8-8c6e-b8f6b1108e05' cg@3587: visibilityChannel: notDelayedMenu cg@3587: translateLabel: true cg@3587: resizeForLabel: true cg@3587: adjust: right cg@3587: ) cg@3587: (InputFieldSpec cg@3587: name: 'nameKeyField' cg@3587: layout: (LayoutFrame 110 0 15 0 -5 1.0 37 0) cg@3587: activeHelpKey: basicsKey cg@3587: uuid: 'd676ec64-9be5-11e8-8c6e-b8f6b1108e05' cg@3587: visibilityChannel: notDelayedMenu cg@3587: tabable: true cg@3587: model: nameKey cg@3587: group: inputGroup cg@3587: type: symbolOrNil cg@3587: immediateAccept: false cg@3587: acceptOnLeave: false cg@3587: acceptOnReturn: true cg@3587: acceptOnTab: true cg@3587: acceptOnLostFocus: false cg@3587: acceptChannel: acceptChannel cg@3587: modifiedChannel: modifiedChannel cg@3587: acceptOnPointerLeave: false cg@3587: ) cg@3587: (LabelSpec cg@3587: label: 'Label:' cg@3587: name: 'labelLabel' cg@3587: layout: (AlignmentOrigin 107 0 51 0 1 0.5) cg@3587: activeHelpKey: basicsLabel cg@3587: uuid: 'd676effc-9be5-11e8-8c6e-b8f6b1108e05' cg@3587: visibilityChannel: notDelayedMenu cg@3587: translateLabel: true cg@3587: resizeForLabel: true cg@3587: adjust: right cg@3587: ) cg@3587: (InputFieldSpec cg@3587: name: 'labelField' cg@3587: layout: (LayoutFrame 110 0 40 0 -5 1.0 62 0) cg@3587: activeHelpKey: basicsLabel cg@3587: uuid: 'd676f150-9be5-11e8-8c6e-b8f6b1108e05' cg@3587: visibilityChannel: notDelayedMenu cg@3587: tabable: true cg@3587: model: rawLabel cg@3587: group: inputGroup cg@3587: immediateAccept: false cg@3587: acceptOnReturn: true cg@3587: acceptOnTab: true cg@3587: acceptOnLostFocus: false cg@3587: acceptChannel: acceptChannel cg@3587: modifiedChannel: modifiedChannel cg@3587: acceptOnPointerLeave: false cg@3587: ) cg@3587: (VerticalPanelViewSpec cg@3587: name: 'VerticalPanel1' cg@3589: layout: (LayoutFrame 6 0 188 0 0 1 323 0) cg@3587: uuid: 'd676f326-9be5-11e8-8c6e-b8f6b1108e05' cg@3589: horizontalLayout: fit cg@3587: verticalLayout: top cg@3587: horizontalSpace: 3 cg@3587: verticalSpace: 3 cg@3587: component: cg@3587: (SpecCollection cg@3587: collection: ( cg@3587: (CheckBoxSpec cg@3587: label: 'Translate Label' cg@3587: name: 'translateLabelCheckBox' cg@3587: activeHelpKey: basicsTranslateLabel cg@3587: uuid: 'd676f54c-9be5-11e8-8c6e-b8f6b1108e05' cg@3587: visibilityChannel: notDelayedMenu cg@3587: tabable: true cg@3587: model: translateLabel cg@3587: translateLabel: true cg@3589: extent: (Point 334 30) cg@3587: ) cg@3587: (CheckBoxSpec cg@3587: label: 'Is Button' cg@3587: name: 'isButtonCheckBox' cg@3587: activeHelpKey: basicsIsButton cg@3587: uuid: 'd676f786-9be5-11e8-8c6e-b8f6b1108e05' cg@3587: visibilityChannel: notDelayedMenu cg@3587: tabable: true cg@3587: model: isButton cg@3587: translateLabel: true cg@3589: extent: (Point 334 30) cg@3587: ) cg@3587: (CheckBoxSpec cg@3587: label: 'Horizontal Layout' cg@3587: name: 'horizontalLayout' cg@3587: activeHelpKey: horizontalLayout cg@3587: uuid: 'd676f8d0-9be5-11e8-8c6e-b8f6b1108e05' cg@3587: tabable: true cg@3587: model: horizontalLayout cg@3587: translateLabel: true cg@3589: extent: (Point 334 30) cg@3587: ) cg@3587: (CheckBoxSpec cg@3587: label: 'Force Menu Indicator' cg@3587: name: 'CheckBox1' cg@3587: activeHelpKey: forceMenuIndicator cg@3587: uuid: 'd676fa06-9be5-11e8-8c6e-b8f6b1108e05' cg@3587: tabable: true cg@3587: model: hasMenuIndicator cg@3587: translateLabel: true cg@3589: extent: (Point 334 30) cg@3587: ) cg@3587: ) cg@3587: cg@3587: ) cg@3587: ) cg@3587: ) cg@3587: cg@3587: ) cg@3587: ) ca@1606: ! ! ca@1606: ca@1633: !MenuEditor::RegularMenuItem methodsFor:'accessing'! ca@1606: ca@1606: argument:aValue ca@1606: "/ ignorred. ca@218: ! ca@218: ca@1606: menu:aMenu labeled:aString ca@1606: |expanded item menu| ca@1606: cg@3582: self synchronized:[ cg@3582: self isRootItem ifTrue:[ expanded := true ] cg@3582: ifFalse:[ expanded := isExpanded ]. cg@3582: cg@3582: self removeAll. cg@3582: self rawLabel:aString. cg@3582: cg@3582: menu := aMenu value. cg@3582: cg@3582: (menu isNil or:[menu isString]) ifTrue:[ cg@3582: menu := nil cg@3582: ] ifFalse:[ cg@3582: aMenu isCollection ifTrue:[ menu := Menu decodeFromLiteralArray:aMenu ] cg@3582: ifFalse:[ menu := aMenu ]. cg@3582: cg@3582: menu hasItems ifFalse:[ cg@3582: menu := nil cg@3582: ]. cg@3582: ]. cg@3582: menu notNil ifTrue:[ cg@3582: isExpanded := false. "/ discard change notifications cg@3582: children := OrderedCollection new. cg@3582: cg@3582: menu itemsDo:[:el| cg@3582: item := self class menuItem:el. cg@3582: item parent:self. cg@3582: children add:item. cg@3582: ]. cg@3582: expanded ifTrue:[ self expand ]. cg@3582: ]. cg@3582: isExpanded := expanded. cg@2188: ]. ca@1606: self changed cg@2168: cg@2862: "Modified: / 29-11-2011 / 11:28:33 / cg" cg@3582: "Modified: / 28-07-2018 / 15:49:52 / Claus Gittinger" ca@199: ! ca@199: ca@1606: menuItem ca@1606: "returns self as a MenuItem ca@1606: " ca@1606: |item| ca@1606: ca@1606: item := super menuItem. ca@1606: item submenu:(self submenu). ca@1606: ^ item ca@199: ! ca@199: ca@1606: menuItem:anItem ca@1606: ca@1606: super menuItem:anItem. ca@1606: self menu:(anItem submenu) labeled:nil. ca@1606: ! ca@1606: ca@1606: slices ca@1606: self isDelayedMenu ifTrue:[ cg@2188: ^ #( cg@2188: (Basics basicsEditSpec ) cg@2188: ) ca@1606: ]. ca@1606: ca@1606: ^ #( cg@2188: (Basics basicsEditSpec ) cg@2188: (Details detailsEditSpec) cg@2188: (Image image ) cg@2188: (Help help) ca@1606: ) ca@1606: ! ca@1606: ca@1606: submenu ca@1606: |menu| ca@1606: ca@1606: menu := Menu new. ca@1606: ca@1606: children size ~~ 0 ifTrue:[ ca@1606: children do:[:el| menu addItem:(el menuItem) ]. ca@1606: ]. ca@1606: ^ menu ca@1606: ! ! ca@1606: ca@1633: !MenuEditor::RegularMenuItem methodsFor:'aspects'! ca@1606: ca@1606: getDelayedAttributesFrom:aMenuItem ca@1606: ca@1653: |menu| ca@1653: ca@1653: menu := self validateValue:(aMenuItem submenu value). ca@1653: ca@1653: self menu:menu labeled:nil. ca@1606: menuItem horizontalLayout:(aMenuItem horizontalLayout). ca@1606: ! ca@1606: ca@1606: setDelayedAttributesTo:aMenuItem ca@1606: aMenuItem submenu:(self submenu). ca@1606: aMenuItem horizontalLayout:(menuItem horizontalLayout). ca@1606: ! ! ca@1606: ca@1633: !MenuEditor::RegularMenuItem methodsFor:'displaying'! ca@1606: ca@1606: displayLabel ca@1606: "returns the label dependent on is delayed or not ca@1606: " ca@1606: self isDelayedMenu ifTrue:[ ^ self class defaultDelayedLabel ]. ca@1606: ^ menuItem rawLabel ca@1606: ! ca@1606: ca@1606: icon ca@1606: self isDelayedMenu ifTrue:[ ^ self class iconDelayedMenu ]. ca@1606: ^ self class iconMenu ca@1606: ! ! ca@1606: ca@1633: !MenuEditor::RegularMenuItem methodsFor:'queries'! ca@1606: ca@1606: canAddChildren ca@1606: "children can be added ca@1606: " ca@1606: ^ true ca@1606: ! ca@1606: ca@1606: canExpand ca@1606: "returns true if the item is expandable ca@1606: " ca@1606: ^ isExpanded == false ca@1606: ! ca@1606: ca@1606: hasIndicator ca@1606: ^ true cg@968: ! cg@968: ca@1606: isKindOfMenu ca@1606: ^ true cg@3135: ! cg@3135: cg@3135: isKindOfNonLinkedMenu cg@3135: ^ true ca@1606: ! ! ca@1606: cg@1631: !MenuEditor::RootItem class methodsFor:'defaults'! cg@1631: cg@1631: defaultLabel cg@1631: ^ MenuEditor resourceType cg@1631: ! ! cg@1631: cg@1668: !MenuEditor::RootItem class methodsFor:'interface specs'! cg@1631: cg@1631: basicsEditSpec cg@1631: "This resource specification was automatically generated cg@1631: by the UIPainter of ST/X." cg@1631: cg@1631: "Do not manually edit this!! If it is corrupted, cg@1631: the UIPainter may not be able to read the specification." cg@1631: cg@1631: " sv@1737: UIPainter new openOnClass:MenuEditor::RootItem andSelector:#basicsEditSpec cg@1631: " cg@1631: cg@1631: cg@1631: cg@2188: ^ sv@1737: #(FullSpec cg@2188: name: basicsEditSpec cg@2188: window: sv@1737: (WindowSpec cg@2188: label: 'basicsEditSpec' cg@2188: name: 'basicsEditSpec' cg@2188: min: (Point 10 10) cg@2188: bounds: (Rectangle 0 0 260 46) cg@2188: ) cg@2188: component: sv@1737: (SpecCollection cg@2188: collection: ( cg@2188: (LabelSpec cg@2188: label: 'Selector:' cg@2188: name: 'selectorLabel' cg@2188: layout: (AlignmentOrigin 107 0 26 0 1 0.5) cg@2188: activeHelpKey: basicsSelector cg@2188: translateLabel: true cg@2188: resizeForLabel: true cg@2188: adjust: right cg@2188: ) cg@2188: (InputFieldSpec cg@2188: name: 'selectorField' cg@2188: layout: (LayoutFrame 110 0 15 0 -5 1.0 37 0) cg@2188: activeHelpKey: basicsSelector cg@2188: tabable: true cg@2188: model: rawLabel cg@2188: group: inputGroup cg@2188: type: string cg@2188: immediateAccept: false cg@2188: acceptOnReturn: true cg@2188: acceptOnTab: true cg@2188: acceptChannel: acceptChannel cg@2188: modifiedChannel: modifiedChannel cg@2188: acceptOnPointerLeave: false cg@2188: ) cg@2188: ) cg@2188: cg@2188: ) cg@1631: ) cg@1631: ! ! cg@1631: cg@1725: !MenuEditor::RootItem class methodsFor:'interface-editor'! cg@1725: cg@1725: addBindingsTo:aspects for:aMenuEditor cg@1725: "add additional bindings to the aspects cg@1725: " cg@1725: ! ! cg@1725: cg@1631: !MenuEditor::RootItem methodsFor:'accessing'! cg@1631: cg@1631: menuItem:aMenuItem cg@1631: "rebuild self from a MenuItem cg@1631: " cg@1631: |submenu selector| cg@1631: cg@1631: aMenuItem notNil ifTrue:[ cg@1631: submenu := aMenuItem submenu. cg@1631: selector := aMenuItem rawLabel. cg@1631: ] ifFalse:[ cg@1631: selector := submenu := nil. cg@1631: ]. cg@1631: self menu:submenu labeled:selector. cg@1631: ! cg@1631: cg@1631: rawLabel:aValue cg@1631: "set the label assigned to the item cg@1631: " cg@1631: |value| cg@1631: cg@1631: aValue isString ifTrue:[ cg@2188: value := aValue withoutSeparators. cg@2188: cg@2188: (value notEmpty and:[value first isLetter]) ifTrue:[ cg@2188: menuItem rawLabel:(value asSymbol) cg@2188: ]. cg@1631: ]. cg@1631: ! cg@1631: cg@1631: slices cg@1631: ^ #( cg@1631: (Basics basicsEditSpec) cg@1631: ) cg@1631: ! ! cg@1631: cg@1631: !MenuEditor::RootItem methodsFor:'adding & removing'! cg@1631: cg@1631: remove cg@1631: "cannot remove the root item; delete all my children cg@1631: " cg@1631: self removeAll. cg@1631: ! ! cg@1631: cg@1631: !MenuEditor::RootItem methodsFor:'aspects'! cg@1631: cg@1631: aspectAt:aKey put:aValue cg@2075: "ignore all aspects other than the rawLabel" cg@2075: cg@1631: aKey == #rawLabel ifTrue:[ self rawLabel:aValue ]. cg@2075: cg@2075: "Modified: / 05-09-2006 / 17:48:01 / cg" cg@1631: ! ! cg@1631: cg@1631: !MenuEditor::RootItem methodsFor:'displaying'! cg@1631: cg@1631: heightOn:aGC cg@2151: height isNil ifTrue:[ height := aGC font heightOn:aGC device ]. cg@2151: ^ height cg@1631: ! ! cg@1631: cg@1631: !MenuEditor::RootItem methodsFor:'initialization'! cg@1631: cg@1631: initialize cg@3396: "must be called if redefined" cg@3396: cg@1631: super initialize. cg@1631: isExpanded := true. cg@3396: cg@3396: "Modified: / 08-02-2017 / 00:29:29 / cg" cg@1631: ! ! cg@1631: cg@1631: !MenuEditor::RootItem methodsFor:'queries'! cg@1631: cg@1631: canCollapse cg@1631: ^ false cg@1631: ! cg@1631: cg@1631: hasIndicator cg@1631: ^ false cg@1631: ! cg@1631: cg@1631: isDelayedMenu cg@1631: ^ false cg@1631: ! cg@1631: cg@1631: isRootItem cg@1631: ^ true cg@1631: ! ! cg@1631: cg@1660: !MenuEditor::RootItem methodsFor:'queries-editor'! cg@1631: cg@1631: actionSelectors cg@2232: "return my action selectors" cg@2232: cg@1631: ^ #() cg@1631: ! cg@1631: cg@1631: aspectSelectors cg@1631: "returns my aspect selectors cg@1631: " cg@1631: ^ #() cg@1631: ! ! cg@1631: cg@1660: !MenuEditor::RootItem methodsFor:'queries-operation'! cg@1631: cg@1631: canMoveInAbove cg@1631: ^ false cg@1631: ! cg@1631: cg@1631: canMoveInNext cg@1631: ^ false cg@1631: ! cg@1631: cg@1631: canMoveOut cg@1631: ^ false cg@1631: ! cg@1631: cg@1631: canMoveUpOrDown cg@1631: ^ false cg@1631: ! ! cg@1631: cg@1668: !MenuEditor::SeparatorItem class methodsFor:'interface specs'! cg@1631: cg@1631: basicsEditSpec cg@1631: "This resource specification was automatically generated cg@1631: by the UIPainter of ST/X." cg@1631: cg@1631: "Do not manually edit this!! If it is corrupted, cg@1631: the UIPainter may not be able to read the specification." cg@1631: cg@1631: " sv@1737: UIPainter new openOnClass:MenuEditor::SeparatorItem andSelector:#basicsEditSpec cg@1631: " cg@1631: cg@1631: cg@1631: cg@2188: ^ sv@1737: #(FullSpec cg@2188: name: basicsEditSpec cg@2188: window: sv@1737: (WindowSpec cg@2188: label: 'basicsEditSpec' cg@2188: name: 'basicsEditSpec' cg@2188: min: (Point 10 10) cg@2188: bounds: (Rectangle 0 0 260 245) cg@2188: ) cg@2188: component: sv@1737: (SpecCollection cg@2188: collection: ( cg@2188: (LabelSpec cg@2188: label: 'Separator:' cg@2188: name: 'separatorLabel' cg@2188: layout: (AlignmentOrigin 107 0 26 0 1 0.5) cg@2188: translateLabel: true cg@2188: resizeForLabel: true cg@2188: adjust: right cg@2188: ) cg@2188: (ComboListSpec cg@2188: name: 'seperatorList' cg@2188: layout: (LayoutFrame 110 0 15 0 -5 1.0 37 0) cg@2188: activeHelpKey: basicsSeparatorType cg@2188: tabable: true cg@2188: model: seperatorSelection cg@2188: comboList: seperatorList cg@2188: useIndex: true cg@2188: ) cg@2188: (LabelSpec cg@2188: label: 'Visibility:' cg@2188: name: 'visibilityLabel' cg@2188: layout: (AlignmentOrigin 107 0 51 0 1 0.5) cg@2188: translateLabel: true cg@2188: resizeForLabel: true cg@2188: adjust: right cg@2188: ) cg@2188: (InputFieldSpec cg@2188: name: 'visibilityInputField' cg@2188: layout: (LayoutFrame 110 0 40 0 -5 1.0 62 0) cg@2188: activeHelpKey: detailsVisibility cg@2188: tabable: true cg@2188: model: isVisible cg@2188: group: inputGroup cg@2188: type: symbolOrBooleanOrNil cg@2188: immediateAccept: false cg@2188: acceptOnReturn: true cg@2188: acceptOnTab: true cg@2188: acceptChannel: acceptChannel cg@2188: modifiedChannel: modifiedChannel cg@2188: acceptOnPointerLeave: false cg@2188: ) cg@2188: (LabelSpec cg@2188: label: 'Start Group:' cg@2188: name: 'startGroupLabel' cg@2188: layout: (AlignmentOrigin 107 0 88 0 1 0.5) cg@2188: translateLabel: true cg@2188: resizeForLabel: true cg@2188: adjust: right cg@2188: ) cg@2188: (PopUpListSpec cg@2188: label: 'left' cg@2188: name: 'startGroupPopUp' cg@2188: layout: (LayoutFrame 110 0 77 0 -5 1.0 99 0) cg@2188: activeHelpKey: detailsStartGroup cg@2188: tabable: true cg@2188: model: startGroup cg@2188: menu: (left right conditionalRight) cg@2188: ) cg@2188: ) cg@2188: cg@2188: ) cg@1631: ) cg@2122: cg@2122: "Modified: / 16-10-2006 / 12:48:30 / cg" cg@1631: ! ! cg@1631: cg@1725: !MenuEditor::SeparatorItem class methodsFor:'interface-editor'! cg@1725: cg@1725: addBindingsTo:aspects for:aMenuEditor cg@1725: "add additional bindings to the aspects cg@1725: " cg@1725: |holder| cg@1725: cg@2188: aspects cg@2188: at:#seperatorList cg@2188: ifAbsentPut: cg@2188: [ cg@2188: |l| cg@2188: cg@2188: l := self separatorSlices collect:[:el| el last ]. cg@2188: l := l collect:[:s | self classResources string:s ]. cg@2188: l cg@2188: ]. cg@1725: cg@1725: aspects at:#seperatorSelection ifAbsentPut:[ cg@2188: holder := 0 asValue. cg@2188: holder addDependent:aMenuEditor. cg@2188: holder cg@1725: ]. cg@1725: ! cg@1725: cg@1725: defaultLabel cg@1725: ^ '-' cg@1725: ! cg@1725: cg@1725: separatorSlices cg@1725: "get the list of menu spec values of the corresponding separator types cg@1725: " cg@1725: ^ #( cg@1725: ( #blank '' 'blank' ) cg@1725: ( #single '-' 'single line') cg@1725: ( #double '=' 'double line') cg@1725: ) cg@1725: ! ! cg@1725: cg@1631: !MenuEditor::SeparatorItem methodsFor:'accessing'! cg@1631: cg@1631: icon cg@1631: ^ self class iconSeparator cg@1631: ! cg@1631: cg@1631: rawLabel:aValue cg@1631: |value| cg@1631: cg@1631: aValue isString ifTrue:[ cg@3013: value := aValue withoutSeparators. cg@3013: cg@3013: (self class separatorTypeOf:value) notNil ifTrue:[ cg@3013: menuItem rawLabel:value cg@3013: ] cg@1631: ]. cg@2862: cg@2862: "Modified: / 29-11-2011 / 11:28:39 / cg" cg@1631: ! cg@1631: cg@1631: separatorType cg@1631: ^ self class separatorTypeOf:(menuItem rawLabel). cg@1631: ! cg@1631: cg@1631: slices cg@1631: ^ #( cg@1631: (Basics basicsEditSpec) cg@1631: ) cg@1631: ! ! cg@1631: cg@1631: !MenuEditor::SeparatorItem methodsFor:'aspects'! cg@1631: cg@1631: fromAspects:aspects cg@1631: "put my values into the values of aspects cg@1631: " cg@1631: |index slice| cg@1631: cg@1631: index := (aspects at:#seperatorSelection) value ? 0. cg@1631: slice := self class separatorSlices at:index ifAbsent:nil. cg@1631: cg@2862: slice notNil ifTrue:[ slice := slice at:2 ]. cg@1631: cg@1631: (aspects at:#rawLabel) value:slice. cg@1631: ^ super fromAspects:aspects. cg@2862: cg@2862: "Modified: / 29-11-2011 / 11:28:36 / cg" cg@1631: ! cg@1631: cg@1631: toAspects:aspects cg@1631: "put my values into the values of aspects cg@1631: " cg@1631: |index type| cg@1631: cg@1631: type := self separatorType. cg@1631: index := self class separatorSlices findFirst:[:el| el first == type ]. cg@1631: cg@1631: (aspects at:#seperatorSelection) value:index. cg@1631: ^ super toAspects:aspects. cg@1631: ! ! cg@1631: cg@1631: !MenuEditor::SeparatorItem methodsFor:'displaying'! cg@1631: cg@3178: displayOn:aGC x:x y:y h:h isHighlightedAsSelected:isHighlightedAsSelected cg@3178: "draw the receiver in the graphicsContext, aGC" cg@3178: cg@1631: |x1 y0 type| cg@1631: cg@1631: type := self separatorType. cg@1631: type == #blank ifTrue:[ ^ self ]. cg@1631: cg@1631: x1 := x + (self widthOn:aGC). cg@1631: y0 := y + (h // 2) - 1. cg@1631: cg@1631: type == #double ifTrue:[ cg@3178: y0 := y0 + 1. cg@3178: aGC displayLineFromX:x y:y0 toX:x1 y:y0. cg@3178: y0 := y0 - 2 cg@1631: ]. cg@1631: aGC displayLineFromX:x y:y0 toX:x1 y:y0 cg@1631: ! cg@1631: cg@1631: widthOn:aGC cg@2151: width isNil ifTrue:[ width := 60 ]. cg@2151: ^ width cg@1631: ! ! cg@1631: cg@2019: !MenuEditor class methodsFor:'documentation'! ca@199: ca@199: version ca@199: ^ '$Header$' cg@2589: ! cg@2589: cg@2589: version_CVS cg@2589: ^ '$Header$' ca@199: ! ! ca@1606: cg@2946: ca@1462: MenuEditor initialize!