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