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