MenuEditor.st
changeset 1330 45983bc2efe1
parent 1322 fbc9a32078b5
child 1335 b80f8c8ec3d6
equal deleted inserted replaced
1329:a38c2e29d1fb 1330:45983bc2efe1
    18 	classVariableNames:''
    18 	classVariableNames:''
    19 	poolDictionaries:''
    19 	poolDictionaries:''
    20 	category:'Interface-UIPainter'
    20 	category:'Interface-UIPainter'
    21 !
    21 !
    22 
    22 
       
    23 SelectionInTreeView subclass:#TreeView
       
    24 	instanceVariableNames:''
       
    25 	classVariableNames:''
       
    26 	poolDictionaries:''
       
    27 	privateIn:MenuEditor
       
    28 !
       
    29 
    23 Object subclass:#Item
    30 Object subclass:#Item
    24 	instanceVariableNames:'activeHelpKey enabled label value nameKey indication shortcutKey
    31 	instanceVariableNames:'activeHelpKey enabled label value nameKey indication shortcutKey
    25 		accessCharacterPos retriever icon iconAndLabel submenuChannel
    32 		accessCharacterPos retriever icon iconAndLabel submenuChannel
    26 		startGroup argument translateLabel isButton isVisible choice
    33 		startGroup argument translateLabel isButton isVisible choice
    27 		choiceValue auxValue hideMenuOnActivated'
    34 		choiceValue auxValue hideMenuOnActivated'
    28 	classVariableNames:''
       
    29 	poolDictionaries:''
       
    30 	privateIn:MenuEditor
       
    31 !
       
    32 
       
    33 SelectionInTreeView subclass:#TreeView
       
    34 	instanceVariableNames:''
       
    35 	classVariableNames:''
    35 	classVariableNames:''
    36 	poolDictionaries:''
    36 	poolDictionaries:''
    37 	privateIn:MenuEditor
    37 	privateIn:MenuEditor
    38 !
    38 !
    39 
    39 
   177 
   177 
   178 #basicsAction
   178 #basicsAction
   179 'An action selector with 0, 1 (the argument field), or 2 (the selected item) arguments.'
   179 'An action selector with 0, 1 (the argument field), or 2 (the selected item) arguments.'
   180 
   180 
   181 #basicsArgument
   181 #basicsArgument
   182 'An argument passed to above selector, if it is a 1 or a 2 argument selector.'
   182 'An optional arg passed with above selector, if it is a 1 or 2 arg selector (enter a Smalltalk literal).'
   183 
   183 
   184 #basicsChoice
   184 #basicsChoice
   185 'A boolean holder, block or method, specifying the choices state (like a RadioButtonGroup).'
   185 'Aspect for a boolean holder, block or method, specifying the choices state (RadioButton behavior).'
   186 
   186 
   187 #basicsChoiceValue
   187 #basicsChoiceValue
   188 'That choices value (typically number or symbol).'
   188 'That choices value (typically number or symbol).'
   189 
   189 
   190 #basicsIndication
   190 #basicsIndication
   191 'A boolean holder, a boolean block, or a boolean method, specifying the indication state.'
   191 'Aspect for boolean holder, block, or method, specifying the indication state (CheckToggle behavior).'
   192 
   192 
   193 #basicsIsButton
   193 #basicsIsButton
   194 'Turns on/off a button behavior.'
   194 'Turns on/off a button behavior.'
   195 
   195 
   196 #basicsKey
   196 #basicsKey
   198 
   198 
   199 #basicsLabel
   199 #basicsLabel
   200 'Label of the item.'
   200 'Label of the item.'
   201 
   201 
   202 #basicsMenu
   202 #basicsMenu
   203 'A value holder providing the sub menu to be opened if item is selected.'
   203 'Aspect providing the sub menu to be opened if item is selected (provide spec or valueHolder).'
   204 
   204 
   205 #basicsMenuArgument
   205 #basicsMenuArgument
   206 'An argument passed with the menu selector.'
   206 'An argument passed with the menu selector.'
   207 
   207 
   208 #basicsNameKey
   208 #basicsNameKey
   252 
   252 
   253 #fileSaveAs
   253 #fileSaveAs
   254 'Opens a dialog to save the menu spec (and the help spec, if modified).'
   254 'Opens a dialog to save the menu spec (and the help spec, if modified).'
   255 
   255 
   256 #hideMenuOnActivated
   256 #hideMenuOnActivated
   257 'Switch on/off hide of the submenu after activation'
   257 'Hide the menu after activation (turn off for checkToggles or radioButtons)'
   258 
   258 
   259 #imageImageAndLabel
   259 #imageImageAndLabel
   260 'Toggles display of both image and textual label.'
   260 'Toggles display of both image and textual label.'
   261 
   261 
   262 #imageImageEditor
   262 #imageImageEditor
   270 
   270 
   271 #imageSelector
   271 #imageSelector
   272 'Selector returning an image (sent to above or the application).'
   272 'Selector returning an image (sent to above or the application).'
   273 
   273 
   274 )
   274 )
       
   275 
       
   276     "Modified: / 4.2.2000 / 12:24:53 / cg"
   275 ! !
   277 ! !
   276 
   278 
   277 !MenuEditor class methodsFor:'image specs'!
   279 !MenuEditor class methodsFor:'image specs'!
   278 
   280 
   279 linkSubmenuImage
   281 linkSubmenuImage
  2695 
  2697 
  2696     treeView selectedNodeChangeSequenceOrder:-1.
  2698     treeView selectedNodeChangeSequenceOrder:-1.
  2697     modified := true.
  2699     modified := true.
  2698 ! !
  2700 ! !
  2699 
  2701 
       
  2702 !MenuEditor::TreeView class methodsFor:'documentation'!
       
  2703 
       
  2704 documentation
       
  2705 "
       
  2706     This tree view class provides a hierarchical representation
       
  2707     of the components of a menu.
       
  2708 
       
  2709     [see also:]
       
  2710         SelectionInTreeView
       
  2711         SelectionInTree
       
  2712         TreeItem
       
  2713 
       
  2714     [author:]
       
  2715         Claus Atzkern
       
  2716 "
       
  2717 ! !
       
  2718 
       
  2719 !MenuEditor::TreeView methodsFor:'accessing'!
       
  2720 
       
  2721 canTab
       
  2722     ^ true
       
  2723 !
       
  2724 
       
  2725 selectorName
       
  2726     "get the selector of the menu spec"
       
  2727 
       
  2728     ^(listOfNodes first contents label) asSymbol
       
  2729 !
       
  2730 
       
  2731 selectorName: aSymbol
       
  2732     "set the selector for the menu spec"
       
  2733 
       
  2734     listOfNodes first contents label: aSymbol
       
  2735 ! !
       
  2736 
       
  2737 !MenuEditor::TreeView methodsFor:'building'!
       
  2738 
       
  2739 buildFromClass:aClass andSelector:aSelector
       
  2740     "read a menu spec from aClass and aSelector and put 
       
  2741      the encoded menu into the tree view"
       
  2742 
       
  2743     |spec cls menu firstNode firstNodeLabel|
       
  2744 
       
  2745     "if opened on a menu"
       
  2746     (aClass isNil and: [aSelector isNil and: [listOfNodes size > 0]]) ifTrue: [^nil].
       
  2747 
       
  2748     self selection:nil.
       
  2749 
       
  2750     (aClass notNil and:[aSelector notNil]) ifTrue:[
       
  2751         cls := self application resolveName:aClass.
       
  2752 
       
  2753         (cls respondsTo:aSelector) ifTrue:[
       
  2754             spec := cls perform:aSelector
       
  2755         ]
       
  2756     ].
       
  2757 
       
  2758     spec isNil ifFalse:[
       
  2759         (spec isMemberOf:Menu) ifFalse:[
       
  2760             menu := Menu new fromLiteralArrayEncoding:spec.
       
  2761         ] ifTrue:[
       
  2762             menu := spec.
       
  2763         ].
       
  2764         firstNode := self nodeLabel:(aSelector asString).
       
  2765         self subMenu:menu parent:firstNode.
       
  2766     ] ifTrue:[
       
  2767         (aClass notNil and: [aSelector isNil and: [listOfNodes size > 0]])
       
  2768         ifTrue:
       
  2769         [
       
  2770             firstNode := listOfNodes first
       
  2771         ]
       
  2772         ifFalse:
       
  2773         [
       
  2774             aSelector notNil ifTrue:[firstNodeLabel := aSelector asString]
       
  2775                         ifFalse:[firstNodeLabel := 'menu'].
       
  2776             firstNode := self nodeLabel:firstNodeLabel.
       
  2777         ]
       
  2778     ].
       
  2779 
       
  2780     firstNode expand.
       
  2781     model root: firstNode.
       
  2782 
       
  2783     firstNode hasChildren ifFalse:[
       
  2784         model add:(self nodeLabel:'Item 1') below:firstNode
       
  2785     ].
       
  2786 
       
  2787 
       
  2788 !
       
  2789 
       
  2790 buildFromMenu:aMenu
       
  2791     "put aMenu into the tree view"
       
  2792 
       
  2793     |node|
       
  2794 
       
  2795     self selection:nil.
       
  2796 
       
  2797     node := self nodeLabel:'menu'.
       
  2798     self subMenu:aMenu parent:node.
       
  2799 
       
  2800     node hasChildren ifFalse:[
       
  2801         node add:(self nodeLabel:'Item 1')
       
  2802     ].
       
  2803     node expand.
       
  2804     model root:node.
       
  2805 !
       
  2806 
       
  2807 menuItem:anItem
       
  2808 
       
  2809     |node|
       
  2810 
       
  2811     node := self nodeLabel: anItem label.
       
  2812     node contents buildFromMenuItem:anItem.
       
  2813     self subMenu: anItem submenu parent:node.
       
  2814     ^node.
       
  2815 
       
  2816 
       
  2817 !
       
  2818 
       
  2819 subMenu:aMenu parent:aParent
       
  2820 
       
  2821     |idx grp|
       
  2822 
       
  2823     aMenu isNil ifFalse:[
       
  2824         grp := aMenu groupSizes.
       
  2825         aMenu itemsDo:[:i| aParent add:(self menuItem:i)].
       
  2826 
       
  2827         grp notNil ifTrue:[
       
  2828             idx := 0.
       
  2829 
       
  2830             grp do:[:i|
       
  2831                 idx := idx + i + 1.
       
  2832                 aParent add:(self nodeLabel:nil) beforeIndex:idx.
       
  2833             ]
       
  2834         ]
       
  2835     ]
       
  2836 ! !
       
  2837 
       
  2838 !MenuEditor::TreeView methodsFor:'conversion'!
       
  2839 
       
  2840 asMenu
       
  2841     |menu root|
       
  2842 
       
  2843     root := self root.
       
  2844 
       
  2845     root hasChildren ifTrue:[
       
  2846         menu := Menu new.
       
  2847         root children do:[:aChild| menu addItem:(self asMenuItem:aChild)].
       
  2848     ].
       
  2849   ^ menu
       
  2850 !
       
  2851 
       
  2852 asMenuItem:aNode
       
  2853 
       
  2854     |menu item|
       
  2855 
       
  2856     item := aNode contents asMenuItem.
       
  2857 
       
  2858     aNode hasChildren ifTrue:[
       
  2859         menu := Menu new.
       
  2860         aNode children do:[:aChild| menu addItem:(self asMenuItem:aChild)].
       
  2861         item submenu:menu
       
  2862     ].
       
  2863   ^ item
       
  2864 
       
  2865 ! !
       
  2866 
       
  2867 !MenuEditor::TreeView methodsFor:'drawing basics'!
       
  2868 
       
  2869 redrawLabelAt:x y:yTop index:anIndex
       
  2870     "draw text label assigned to a node at x y( center)"
       
  2871 
       
  2872     |isSelected y0 x0 x1 w type item|
       
  2873 
       
  2874     item := (listOfNodes at:anIndex) contents.
       
  2875     type := item separatorType.
       
  2876 
       
  2877     type isNil ifTrue:[
       
  2878         ^ super redrawLabelAt:x y:yTop index:anIndex
       
  2879     ].
       
  2880     isSelected := self isInSelection:anIndex.
       
  2881     x0 := x.
       
  2882 
       
  2883     highlightMode == #label ifTrue:[
       
  2884         x0 := x + 4.
       
  2885 
       
  2886         isSelected ifTrue:[
       
  2887             w  := 80 + 8.
       
  2888             self paint:hilightBgColor.
       
  2889             self fillRectangleX:x y:yTop width:w height:fontHeight.
       
  2890         ]
       
  2891     ] ifFalse:[
       
  2892         w := 0.
       
  2893     ].
       
  2894     type == #blank ifFalse:[
       
  2895         isSelected ifTrue:[self paint:hilightFgColor]
       
  2896                   ifFalse:[self paint:fgColor].
       
  2897 
       
  2898         x1 := x0 + 80.
       
  2899         y0 := yTop - 1 + (fontHeight // 2).
       
  2900         self displayLineFromX:x0 y:y0 toX:x1 y:y0.
       
  2901 
       
  2902         type == #double ifTrue:[
       
  2903             y0 := y0 + 2.
       
  2904             self displayLineFromX:x0 y:y0 toX:x1 y:y0.
       
  2905         ]    
       
  2906     ].
       
  2907 
       
  2908     (isSelected and:[highlightMode == #label]) ifTrue:[
       
  2909         self redrawSelFrameAtX:x y:yTop toX:(x + w)
       
  2910     ].
       
  2911 
       
  2912 ! !
       
  2913 
       
  2914 !MenuEditor::TreeView methodsFor:'event handling'!
       
  2915 
       
  2916 keyPress:key x:x y:y
       
  2917     "invoked if any key was pressed"
       
  2918 
       
  2919     <resource: #keyboard (#Delete #BackSpace #Cut #Copy #Paste)>
       
  2920 
       
  2921     (key == #Delete or:[key == #BackSpace]) ifTrue: [^self doDelete].
       
  2922     key == #Cut   ifTrue:[^self doCut].
       
  2923     key == #Copy  ifTrue:[^self doCopy].
       
  2924     key == #Paste ifTrue:[^self doPaste].
       
  2925 
       
  2926     super keyPress:key x:x y:y
       
  2927 
       
  2928 ! !
       
  2929 
       
  2930 !MenuEditor::TreeView methodsFor:'initialization'!
       
  2931 
       
  2932 initialize
       
  2933     "initialize the tree view of the menu components"
       
  2934 
       
  2935     super initialize.
       
  2936 
       
  2937     self multipleSelectOk:true.
       
  2938     self showDirectoryIndicator: true.
       
  2939     self showDirectoryIndicatorForRoot: false.
       
  2940     self selectConditionBlock: [:i|self application askForItemModification]. 
       
  2941     self validateDoubleClickBlock: [:node| node ~~ listOfNodes first].
       
  2942     self model iconAction: [:aNode| aNode contents iconFor: aNode].
       
  2943     self model labelAction: [:aNode| aNode contents treeViewLabel]
       
  2944 ! !
       
  2945 
       
  2946 !MenuEditor::TreeView methodsFor:'menus'!
       
  2947 
       
  2948 doCopy
       
  2949     |clip|
       
  2950 
       
  2951     self hasSelection ifTrue:[
       
  2952         self application clipboard:(clip := OrderedCollection new).
       
  2953         self selectionDo:[:i | clip add:((listOfNodes at:i) copy)].
       
  2954         self topView application updateAllToolInstances.
       
  2955     ]
       
  2956 !
       
  2957 
       
  2958 doCreateItem
       
  2959 
       
  2960     self addElement: (self nodeLabel:'Item')
       
  2961 !
       
  2962 
       
  2963 doCreateLink
       
  2964 
       
  2965     |node item|
       
  2966 
       
  2967     node := self nodeLabel:'Submenu Link'.
       
  2968     item := node contents.
       
  2969     item submenuChannel:#menuDefaultLink.
       
  2970     self addElement:node.
       
  2971     self setModified.
       
  2972 
       
  2973 
       
  2974 !
       
  2975 
       
  2976 doCreateMenu
       
  2977 
       
  2978     |node|
       
  2979     node := self nodeLabel:'Submenu'.
       
  2980     node parent: self selectedNode.        
       
  2981     node add:(self nodeLabel:'Item 1').
       
  2982     self addElement:node
       
  2983 !
       
  2984 
       
  2985 doCreateSep
       
  2986 
       
  2987     self addElement:(self nodeLabel:nil)
       
  2988 !
       
  2989 
       
  2990 doCreateStandardEditMenu
       
  2991 
       
  2992     |node|
       
  2993     node := self nodeLabel:'Edit'.
       
  2994     node parent: self selectedNode.        
       
  2995     node add:(self nodeLabel:'Copy'  selector:#copySelection).
       
  2996     node add:(self nodeLabel:'Cut'   selector:#cutSelection).
       
  2997     node add:(self nodeLabel:'Paste' selector:#paste).
       
  2998     self addElement:node
       
  2999 
       
  3000     "Created: / 23.8.1998 / 15:52:16 / cg"
       
  3001     "Modified: / 23.8.1998 / 15:59:36 / cg"
       
  3002 !
       
  3003 
       
  3004 doCreateStandardFileMenu
       
  3005 
       
  3006     |node|
       
  3007     node := self nodeLabel:'File'.
       
  3008     node parent: self selectedNode.        
       
  3009     node add:(self nodeLabel:'New'        selector:#menuNew).
       
  3010     node add:(self nodeLabel:'-'          ).
       
  3011     node add:(self nodeLabel:'Open...'    selector:#menuOpen).
       
  3012     node add:(self nodeLabel:'-'          ).
       
  3013     node add:(self nodeLabel:'Save'       selector:#menuSave).
       
  3014     node add:(self nodeLabel:'Save As...' selector:#menuSaveAs).
       
  3015     node add:(self nodeLabel:'-'          ).
       
  3016     node add:(self nodeLabel:'Exit'       selector:#closeRequest).
       
  3017     self addElement:node
       
  3018 
       
  3019     "Created: / 23.8.1998 / 15:51:55 / cg"
       
  3020     "Modified: / 23.8.1998 / 16:04:24 / cg"
       
  3021 !
       
  3022 
       
  3023 doCreateStandardHelpMenu
       
  3024 
       
  3025     |node|
       
  3026     node := self nodeLabel:'Help'.
       
  3027     node parent: self selectedNode.        
       
  3028     node contents startGroup:#right.
       
  3029     node add:(self nodeLabel:'Documentation'          selector:#openDocumentation).
       
  3030     node add:(self nodeLabel:'-').
       
  3031     node add:(self nodeLabel:'About this Application' selector:#openAboutThisApplication).
       
  3032     self addElement:node
       
  3033 
       
  3034     "Created: / 23.8.1998 / 15:52:46 / cg"
       
  3035     "Modified: / 23.8.1998 / 17:30:12 / cg"
       
  3036 !
       
  3037 
       
  3038 doCut
       
  3039     |app|
       
  3040 
       
  3041     app := self topView application.
       
  3042     (app hasValidSelection value and: [self askForItemModification])
       
  3043     ifTrue:
       
  3044     [
       
  3045         |selectedNodes|
       
  3046         self doCopy.
       
  3047         selectedNodes := self selection asSortedCollection.
       
  3048         self selectedNodesRemove.
       
  3049         self selection: selectedNodes first - 1.
       
  3050         self setModified.
       
  3051         app updateAllToolInstances.
       
  3052     ]
       
  3053 
       
  3054 !
       
  3055 
       
  3056 doDelete
       
  3057 
       
  3058     (self topView application hasValidSelection value and: [self askForItemModification])
       
  3059     ifTrue:
       
  3060     [
       
  3061         |selectedNodes|
       
  3062         selectedNodes := self selection asSortedCollection.
       
  3063         self selectedNodesRemove.
       
  3064         self selection: selectedNodes first - 1.
       
  3065         self setModified.
       
  3066     ]
       
  3067 
       
  3068 !
       
  3069 
       
  3070 doPaste
       
  3071     |clip|
       
  3072 
       
  3073     clip := self application clipboard.
       
  3074     (clip notNil and:[self selectedNode notNil]) ifTrue:[
       
  3075         self addElement:(clip collect:[:el| el copy])
       
  3076     ].
       
  3077 ! !
       
  3078 
       
  3079 !MenuEditor::TreeView methodsFor:'private'!
       
  3080 
       
  3081 addElement: aNode
       
  3082     "add something after selection"
       
  3083 
       
  3084     |label sel|     
       
  3085 
       
  3086     self askForItemModification ifTrue:[   
       
  3087         self selectedNodeAdd:aNode.
       
  3088         (aNode isCollection not 
       
  3089         and: [aNode name = 'Item']) 
       
  3090         ifTrue:[
       
  3091             sel := self selectedNode.
       
  3092             label := aNode name , ' ',
       
  3093                 (sel parent notNil 
       
  3094                 ifTrue:
       
  3095                     [
       
  3096                         (((sel children size = 0 
       
  3097                             ifTrue: [sel parent children] 
       
  3098                             ifFalse: [sel children]) 
       
  3099                         select:[:node| 
       
  3100                             |lab| 
       
  3101                             lab := node contents label. 
       
  3102                             ((node children size = 0) & 
       
  3103                             node contents submenuChannel isNil &
       
  3104                             (lab ~= '-') & (lab ~= '=') & (lab ~= ''))
       
  3105                         ]) size) printString
       
  3106                     ] 
       
  3107                 ifFalse: ['1']).  
       
  3108 
       
  3109             aNode name: label string asBoldText.
       
  3110             aNode contents label: label string.
       
  3111         ].    
       
  3112         aNode isCollection ifFalse: [self selectNode: aNode] ifTrue: [self selection: (aNode collect: [:node| self indexOfNode: node])].
       
  3113         self setModified.
       
  3114     ]
       
  3115 !
       
  3116 
       
  3117 askForItemModification
       
  3118 
       
  3119     ^self topView application askForItemModification
       
  3120 !
       
  3121 
       
  3122 nodeLabel:aLabel
       
  3123 
       
  3124     ^TreeItem new contents: ((MenuEditor::Item new label:aLabel) translateLabel:true)
       
  3125 
       
  3126     "Modified: / 6.6.1998 / 17:22:35 / cg"
       
  3127 !
       
  3128 
       
  3129 nodeLabel:aLabel selector:aSelector
       
  3130 
       
  3131     ^TreeItem new contents: (((MenuEditor::Item new label:aLabel) value:aSelector) translateLabel:true)
       
  3132 
       
  3133     "Modified: / 6.6.1998 / 17:22:35 / cg"
       
  3134     "Created: / 23.8.1998 / 15:58:59 / cg"
       
  3135 !
       
  3136 
       
  3137 selectedNodeAdd:something
       
  3138 
       
  3139     |node numChildren|
       
  3140 
       
  3141     something notNil ifTrue:[
       
  3142         (node := self selectedNode) notNil ifTrue:[
       
  3143             numChildren := node children size.
       
  3144 
       
  3145             node parent notNil ifTrue:[
       
  3146                 node isCollapsable ifTrue:[
       
  3147                     model add:something afterIndex:numChildren below:node
       
  3148                 ] ifFalse:[
       
  3149                     model add:something after:node
       
  3150                 ]
       
  3151             ] ifFalse:[
       
  3152                 model add:something afterIndex:numChildren below:(self root)
       
  3153             ]
       
  3154         ]
       
  3155     ]
       
  3156 
       
  3157 
       
  3158 !
       
  3159 
       
  3160 setModified 
       
  3161     |app|
       
  3162 
       
  3163     (app := self topView application) modified: true.
       
  3164     app updateChannels
       
  3165 ! !
       
  3166 
  2700 !MenuEditor::Item class methodsFor:'constants'!
  3167 !MenuEditor::Item class methodsFor:'constants'!
  2701 
  3168 
  2702 separatorList
  3169 separatorList
  2703     "get the list of available separator types"
  3170     "get the list of available separator types"
  2704 
  3171 
  3034 
  3501 
  3035 
  3502 
  3036 "
  3503 "
  3037 ! !
  3504 ! !
  3038 
  3505 
  3039 !MenuEditor::TreeView class methodsFor:'documentation'!
       
  3040 
       
  3041 documentation
       
  3042 "
       
  3043     This tree view class provides a hierarchical representation
       
  3044     of the components of a menu.
       
  3045 
       
  3046     [see also:]
       
  3047         SelectionInTreeView
       
  3048         SelectionInTree
       
  3049         TreeItem
       
  3050 
       
  3051     [author:]
       
  3052         Claus Atzkern
       
  3053 "
       
  3054 ! !
       
  3055 
       
  3056 !MenuEditor::TreeView methodsFor:'accessing'!
       
  3057 
       
  3058 canTab
       
  3059     ^ true
       
  3060 !
       
  3061 
       
  3062 selectorName
       
  3063     "get the selector of the menu spec"
       
  3064 
       
  3065     ^(listOfNodes first contents label) asSymbol
       
  3066 !
       
  3067 
       
  3068 selectorName: aSymbol
       
  3069     "set the selector for the menu spec"
       
  3070 
       
  3071     listOfNodes first contents label: aSymbol
       
  3072 ! !
       
  3073 
       
  3074 !MenuEditor::TreeView methodsFor:'building'!
       
  3075 
       
  3076 buildFromClass:aClass andSelector:aSelector
       
  3077     "read a menu spec from aClass and aSelector and put 
       
  3078      the encoded menu into the tree view"
       
  3079 
       
  3080     |spec cls menu firstNode firstNodeLabel|
       
  3081 
       
  3082     "if opened on a menu"
       
  3083     (aClass isNil and: [aSelector isNil and: [listOfNodes size > 0]]) ifTrue: [^nil].
       
  3084 
       
  3085     self selection:nil.
       
  3086 
       
  3087     (aClass notNil and:[aSelector notNil]) ifTrue:[
       
  3088         cls := self application resolveName:aClass.
       
  3089 
       
  3090         (cls respondsTo:aSelector) ifTrue:[
       
  3091             spec := cls perform:aSelector
       
  3092         ]
       
  3093     ].
       
  3094 
       
  3095     spec isNil ifFalse:[
       
  3096         (spec isMemberOf:Menu) ifFalse:[
       
  3097             menu := Menu new fromLiteralArrayEncoding:spec.
       
  3098         ] ifTrue:[
       
  3099             menu := spec.
       
  3100         ].
       
  3101         firstNode := self nodeLabel:(aSelector asString).
       
  3102         self subMenu:menu parent:firstNode.
       
  3103     ] ifTrue:[
       
  3104         (aClass notNil and: [aSelector isNil and: [listOfNodes size > 0]])
       
  3105         ifTrue:
       
  3106         [
       
  3107             firstNode := listOfNodes first
       
  3108         ]
       
  3109         ifFalse:
       
  3110         [
       
  3111             aSelector notNil ifTrue:[firstNodeLabel := aSelector asString]
       
  3112                         ifFalse:[firstNodeLabel := 'menu'].
       
  3113             firstNode := self nodeLabel:firstNodeLabel.
       
  3114         ]
       
  3115     ].
       
  3116 
       
  3117     firstNode expand.
       
  3118     model root: firstNode.
       
  3119 
       
  3120     firstNode hasChildren ifFalse:[
       
  3121         model add:(self nodeLabel:'Item 1') below:firstNode
       
  3122     ].
       
  3123 
       
  3124 
       
  3125 !
       
  3126 
       
  3127 buildFromMenu:aMenu
       
  3128     "put aMenu into the tree view"
       
  3129 
       
  3130     |node|
       
  3131 
       
  3132     self selection:nil.
       
  3133 
       
  3134     node := self nodeLabel:'menu'.
       
  3135     self subMenu:aMenu parent:node.
       
  3136 
       
  3137     node hasChildren ifFalse:[
       
  3138         node add:(self nodeLabel:'Item 1')
       
  3139     ].
       
  3140     node expand.
       
  3141     model root:node.
       
  3142 !
       
  3143 
       
  3144 menuItem:anItem
       
  3145 
       
  3146     |node|
       
  3147 
       
  3148     node := self nodeLabel: anItem label.
       
  3149     node contents buildFromMenuItem:anItem.
       
  3150     self subMenu: anItem submenu parent:node.
       
  3151     ^node.
       
  3152 
       
  3153 
       
  3154 !
       
  3155 
       
  3156 subMenu:aMenu parent:aParent
       
  3157 
       
  3158     |idx grp|
       
  3159 
       
  3160     aMenu isNil ifFalse:[
       
  3161         grp := aMenu groupSizes.
       
  3162         aMenu itemsDo:[:i| aParent add:(self menuItem:i)].
       
  3163 
       
  3164         grp notNil ifTrue:[
       
  3165             idx := 0.
       
  3166 
       
  3167             grp do:[:i|
       
  3168                 idx := idx + i + 1.
       
  3169                 aParent add:(self nodeLabel:nil) beforeIndex:idx.
       
  3170             ]
       
  3171         ]
       
  3172     ]
       
  3173 ! !
       
  3174 
       
  3175 !MenuEditor::TreeView methodsFor:'conversion'!
       
  3176 
       
  3177 asMenu
       
  3178     |menu root|
       
  3179 
       
  3180     root := self root.
       
  3181 
       
  3182     root hasChildren ifTrue:[
       
  3183         menu := Menu new.
       
  3184         root children do:[:aChild| menu addItem:(self asMenuItem:aChild)].
       
  3185     ].
       
  3186   ^ menu
       
  3187 !
       
  3188 
       
  3189 asMenuItem:aNode
       
  3190 
       
  3191     |menu item|
       
  3192 
       
  3193     item := aNode contents asMenuItem.
       
  3194 
       
  3195     aNode hasChildren ifTrue:[
       
  3196         menu := Menu new.
       
  3197         aNode children do:[:aChild| menu addItem:(self asMenuItem:aChild)].
       
  3198         item submenu:menu
       
  3199     ].
       
  3200   ^ item
       
  3201 
       
  3202 ! !
       
  3203 
       
  3204 !MenuEditor::TreeView methodsFor:'drawing basics'!
       
  3205 
       
  3206 redrawLabelAt:x y:yTop index:anIndex
       
  3207     "draw text label assigned to a node at x y( center)"
       
  3208 
       
  3209     |isSelected y0 x0 x1 w type item|
       
  3210 
       
  3211     item := (listOfNodes at:anIndex) contents.
       
  3212     type := item separatorType.
       
  3213 
       
  3214     type isNil ifTrue:[
       
  3215         ^ super redrawLabelAt:x y:yTop index:anIndex
       
  3216     ].
       
  3217     isSelected := self isInSelection:anIndex.
       
  3218     x0 := x.
       
  3219 
       
  3220     highlightMode == #label ifTrue:[
       
  3221         x0 := x + 4.
       
  3222 
       
  3223         isSelected ifTrue:[
       
  3224             w  := 80 + 8.
       
  3225             self paint:hilightBgColor.
       
  3226             self fillRectangleX:x y:yTop width:w height:fontHeight.
       
  3227         ]
       
  3228     ] ifFalse:[
       
  3229         w := 0.
       
  3230     ].
       
  3231     type == #blank ifFalse:[
       
  3232         isSelected ifTrue:[self paint:hilightFgColor]
       
  3233                   ifFalse:[self paint:fgColor].
       
  3234 
       
  3235         x1 := x0 + 80.
       
  3236         y0 := yTop - 1 + (fontHeight // 2).
       
  3237         self displayLineFromX:x0 y:y0 toX:x1 y:y0.
       
  3238 
       
  3239         type == #double ifTrue:[
       
  3240             y0 := y0 + 2.
       
  3241             self displayLineFromX:x0 y:y0 toX:x1 y:y0.
       
  3242         ]    
       
  3243     ].
       
  3244 
       
  3245     (isSelected and:[highlightMode == #label]) ifTrue:[
       
  3246         self redrawSelFrameAtX:x y:yTop toX:(x + w)
       
  3247     ].
       
  3248 
       
  3249 ! !
       
  3250 
       
  3251 !MenuEditor::TreeView methodsFor:'event handling'!
       
  3252 
       
  3253 keyPress:key x:x y:y
       
  3254     "invoked if any key was pressed"
       
  3255 
       
  3256     <resource: #keyboard (#Delete #BackSpace #Cut #Copy #Paste)>
       
  3257 
       
  3258     (key == #Delete or:[key == #BackSpace]) ifTrue: [^self doDelete].
       
  3259     key == #Cut   ifTrue:[^self doCut].
       
  3260     key == #Copy  ifTrue:[^self doCopy].
       
  3261     key == #Paste ifTrue:[^self doPaste].
       
  3262 
       
  3263     super keyPress:key x:x y:y
       
  3264 
       
  3265 ! !
       
  3266 
       
  3267 !MenuEditor::TreeView methodsFor:'initialization'!
       
  3268 
       
  3269 initialize
       
  3270     "initialize the tree view of the menu components"
       
  3271 
       
  3272     super initialize.
       
  3273 
       
  3274     self multipleSelectOk:true.
       
  3275     self showDirectoryIndicator: true.
       
  3276     self showDirectoryIndicatorForRoot: false.
       
  3277     self selectConditionBlock: [:i|self application askForItemModification]. 
       
  3278     self validateDoubleClickBlock: [:node| node ~~ listOfNodes first].
       
  3279     self model iconAction: [:aNode| aNode contents iconFor: aNode].
       
  3280     self model labelAction: [:aNode| aNode contents treeViewLabel]
       
  3281 ! !
       
  3282 
       
  3283 !MenuEditor::TreeView methodsFor:'menus'!
       
  3284 
       
  3285 doCopy
       
  3286     |clip|
       
  3287 
       
  3288     self hasSelection ifTrue:[
       
  3289         self application clipboard:(clip := OrderedCollection new).
       
  3290         self selectionDo:[:i | clip add:((listOfNodes at:i) copy)].
       
  3291         self topView application updateAllToolInstances.
       
  3292     ]
       
  3293 !
       
  3294 
       
  3295 doCreateItem
       
  3296 
       
  3297     self addElement: (self nodeLabel:'Item')
       
  3298 !
       
  3299 
       
  3300 doCreateLink
       
  3301 
       
  3302     |node item|
       
  3303 
       
  3304     node := self nodeLabel:'Submenu Link'.
       
  3305     item := node contents.
       
  3306     item submenuChannel:#menuDefaultLink.
       
  3307     self addElement:node.
       
  3308     self setModified.
       
  3309 
       
  3310 
       
  3311 !
       
  3312 
       
  3313 doCreateMenu
       
  3314 
       
  3315     |node|
       
  3316     node := self nodeLabel:'Submenu'.
       
  3317     node parent: self selectedNode.        
       
  3318     node add:(self nodeLabel:'Item 1').
       
  3319     self addElement:node
       
  3320 !
       
  3321 
       
  3322 doCreateSep
       
  3323 
       
  3324     self addElement:(self nodeLabel:nil)
       
  3325 !
       
  3326 
       
  3327 doCreateStandardEditMenu
       
  3328 
       
  3329     |node|
       
  3330     node := self nodeLabel:'Edit'.
       
  3331     node parent: self selectedNode.        
       
  3332     node add:(self nodeLabel:'Copy'  selector:#copySelection).
       
  3333     node add:(self nodeLabel:'Cut'   selector:#cutSelection).
       
  3334     node add:(self nodeLabel:'Paste' selector:#paste).
       
  3335     self addElement:node
       
  3336 
       
  3337     "Created: / 23.8.1998 / 15:52:16 / cg"
       
  3338     "Modified: / 23.8.1998 / 15:59:36 / cg"
       
  3339 !
       
  3340 
       
  3341 doCreateStandardFileMenu
       
  3342 
       
  3343     |node|
       
  3344     node := self nodeLabel:'File'.
       
  3345     node parent: self selectedNode.        
       
  3346     node add:(self nodeLabel:'New'        selector:#menuNew).
       
  3347     node add:(self nodeLabel:'-'          ).
       
  3348     node add:(self nodeLabel:'Open...'    selector:#menuOpen).
       
  3349     node add:(self nodeLabel:'-'          ).
       
  3350     node add:(self nodeLabel:'Save'       selector:#menuSave).
       
  3351     node add:(self nodeLabel:'Save As...' selector:#menuSaveAs).
       
  3352     node add:(self nodeLabel:'-'          ).
       
  3353     node add:(self nodeLabel:'Exit'       selector:#closeRequest).
       
  3354     self addElement:node
       
  3355 
       
  3356     "Created: / 23.8.1998 / 15:51:55 / cg"
       
  3357     "Modified: / 23.8.1998 / 16:04:24 / cg"
       
  3358 !
       
  3359 
       
  3360 doCreateStandardHelpMenu
       
  3361 
       
  3362     |node|
       
  3363     node := self nodeLabel:'Help'.
       
  3364     node parent: self selectedNode.        
       
  3365     node contents startGroup:#right.
       
  3366     node add:(self nodeLabel:'Documentation'          selector:#openDocumentation).
       
  3367     node add:(self nodeLabel:'-').
       
  3368     node add:(self nodeLabel:'About this Application' selector:#openAboutThisApplication).
       
  3369     self addElement:node
       
  3370 
       
  3371     "Created: / 23.8.1998 / 15:52:46 / cg"
       
  3372     "Modified: / 23.8.1998 / 17:30:12 / cg"
       
  3373 !
       
  3374 
       
  3375 doCut
       
  3376     |app|
       
  3377 
       
  3378     app := self topView application.
       
  3379     (app hasValidSelection value and: [self askForItemModification])
       
  3380     ifTrue:
       
  3381     [
       
  3382         |selectedNodes|
       
  3383         self doCopy.
       
  3384         selectedNodes := self selection asSortedCollection.
       
  3385         self selectedNodesRemove.
       
  3386         self selection: selectedNodes first - 1.
       
  3387         self setModified.
       
  3388         app updateAllToolInstances.
       
  3389     ]
       
  3390 
       
  3391 !
       
  3392 
       
  3393 doDelete
       
  3394 
       
  3395     (self topView application hasValidSelection value and: [self askForItemModification])
       
  3396     ifTrue:
       
  3397     [
       
  3398         |selectedNodes|
       
  3399         selectedNodes := self selection asSortedCollection.
       
  3400         self selectedNodesRemove.
       
  3401         self selection: selectedNodes first - 1.
       
  3402         self setModified.
       
  3403     ]
       
  3404 
       
  3405 !
       
  3406 
       
  3407 doPaste
       
  3408     |clip|
       
  3409 
       
  3410     clip := self application clipboard.
       
  3411     (clip notNil and:[self selectedNode notNil]) ifTrue:[
       
  3412         self addElement:(clip collect:[:el| el copy])
       
  3413     ].
       
  3414 ! !
       
  3415 
       
  3416 !MenuEditor::TreeView methodsFor:'private'!
       
  3417 
       
  3418 addElement: aNode
       
  3419     "add something after selection"
       
  3420 
       
  3421     |label sel|     
       
  3422 
       
  3423     self askForItemModification ifTrue:[   
       
  3424         self selectedNodeAdd:aNode.
       
  3425         (aNode isCollection not 
       
  3426         and: [aNode name = 'Item']) 
       
  3427         ifTrue:[
       
  3428             sel := self selectedNode.
       
  3429             label := aNode name , ' ',
       
  3430                 (sel parent notNil 
       
  3431                 ifTrue:
       
  3432                     [
       
  3433                         (((sel children size = 0 
       
  3434                             ifTrue: [sel parent children] 
       
  3435                             ifFalse: [sel children]) 
       
  3436                         select:[:node| 
       
  3437                             |lab| 
       
  3438                             lab := node contents label. 
       
  3439                             ((node children size = 0) & 
       
  3440                             node contents submenuChannel isNil &
       
  3441                             (lab ~= '-') & (lab ~= '=') & (lab ~= ''))
       
  3442                         ]) size) printString
       
  3443                     ] 
       
  3444                 ifFalse: ['1']).  
       
  3445 
       
  3446             aNode name: label string asBoldText.
       
  3447             aNode contents label: label string.
       
  3448         ].    
       
  3449         aNode isCollection ifFalse: [self selectNode: aNode] ifTrue: [self selection: (aNode collect: [:node| self indexOfNode: node])].
       
  3450         self setModified.
       
  3451     ]
       
  3452 !
       
  3453 
       
  3454 askForItemModification
       
  3455 
       
  3456     ^self topView application askForItemModification
       
  3457 !
       
  3458 
       
  3459 nodeLabel:aLabel
       
  3460 
       
  3461     ^TreeItem new contents: ((MenuEditor::Item new label:aLabel) translateLabel:true)
       
  3462 
       
  3463     "Modified: / 6.6.1998 / 17:22:35 / cg"
       
  3464 !
       
  3465 
       
  3466 nodeLabel:aLabel selector:aSelector
       
  3467 
       
  3468     ^TreeItem new contents: (((MenuEditor::Item new label:aLabel) value:aSelector) translateLabel:true)
       
  3469 
       
  3470     "Modified: / 6.6.1998 / 17:22:35 / cg"
       
  3471     "Created: / 23.8.1998 / 15:58:59 / cg"
       
  3472 !
       
  3473 
       
  3474 selectedNodeAdd:something
       
  3475 
       
  3476     |node numChildren|
       
  3477 
       
  3478     something notNil ifTrue:[
       
  3479         (node := self selectedNode) notNil ifTrue:[
       
  3480             numChildren := node children size.
       
  3481 
       
  3482             node parent notNil ifTrue:[
       
  3483                 node isCollapsable ifTrue:[
       
  3484                     model add:something afterIndex:numChildren below:node
       
  3485                 ] ifFalse:[
       
  3486                     model add:something after:node
       
  3487                 ]
       
  3488             ] ifFalse:[
       
  3489                 model add:something afterIndex:numChildren below:(self root)
       
  3490             ]
       
  3491         ]
       
  3492     ]
       
  3493 
       
  3494 
       
  3495 !
       
  3496 
       
  3497 setModified 
       
  3498     |app|
       
  3499 
       
  3500     (app := self topView application) modified: true.
       
  3501     app updateChannels
       
  3502 ! !
       
  3503 
       
  3504 !MenuEditor class methodsFor:'documentation'!
  3506 !MenuEditor class methodsFor:'documentation'!
  3505 
  3507 
  3506 version
  3508 version
  3507     ^ '$Header$'
  3509     ^ '$Header$'
  3508 ! !
  3510 ! !