add submenuChannel
authorca
Thu, 17 Jul 1997 12:05:40 +0200
changeset 464 a788fdce92e2
parent 463 6545fa33ab45
child 465 67a0f3dd503a
add submenuChannel
MenuPanel.st
--- a/MenuPanel.st	Sun Jul 06 13:28:21 1997 +0200
+++ b/MenuPanel.st	Thu Jul 17 12:05:40 1997 +0200
@@ -22,7 +22,7 @@
 
 Object subclass:#Item
 	instanceVariableNames:'layout menuPanel subMenu adornment rawLabel enableChannel nameKey
-		accessCharacterPosition value label activeHelpKey'
+		accessCharacterPosition value label activeHelpKey submenuChannel'
 	classVariableNames:'HorizontalInset VerticalInset LabelRightOffset ShortcutKeyOffset
 		IndicatorOn IndicatorOff'
 	poolDictionaries:''
@@ -2167,7 +2167,9 @@
         ^ superMenu application
     ].
     (appl := super application) isNil ifTrue:[
-        appl := windowGroup mainGroup topViews first application
+        windowGroup notNil ifTrue:[
+            appl := windowGroup mainGroup topViews first application
+        ]
     ].
   ^ appl
 !
@@ -2530,9 +2532,6 @@
     LabelRightOffset  := 15.
     ShortcutKeyOffset := 5.
 
-"/    IndicatorOn  := Image fromFile:'RadioOn.xbm'.
-"/    IndicatorOff := Image fromFile:'RadioOff.xbm'.
-
     IndicatorOn  := CheckToggle checkImageForStyle:#borderedFatcross.
     IndicatorOff := CheckToggle checkImageForStyle:#border.
 
@@ -2769,16 +2768,15 @@
 submenu
     "returns my submenu or nil
     "
-    ^ subMenu
+    subMenu notNil ifTrue:[^ subMenu].
+  ^ self setupSubmenu
 !
 
 submenu:aSubMenu
     "set a new submenu; an existing submenu will be destroyed. This might lead
      to a redraw if 'hasSubmenu' changed
     "
-    |hadMenu|
-
-    (hadMenu := subMenu notNil) ifTrue:[
+    subMenu notNil ifTrue:[
         subMenu destroy
     ].
 
@@ -2789,10 +2787,6 @@
         subMenu superMenu:menuPanel
     ].
 
-    hadMenu ~~ (subMenu notNil) ifTrue:[
-        self redraw
-    ]
-
 !
 
 textLabel
@@ -2825,11 +2819,16 @@
 
     enableChannel isSymbol ifTrue:[
         (appl := menuPanel application) notNil ifTrue:[
-            state := appl aspectFor:enableChannel.
+            Object messageNotUnderstoodSignal handle:[:ex|
+                state := true
+            ] do:[
+                state := appl aspectFor:enableChannel.
+            ].
 
             (self isKindOfValueHolder:state) ifTrue:[
                 enableChannel := state.
-                enableChannel addDependent:self
+                enableChannel addDependent:self.
+                state := enableChannel value.
             ]
         ]
     ] ifFalse:[
@@ -2859,9 +2858,7 @@
         (self isKindOfValueHolder:enableChannel) ifTrue:[
             enableChannel addDependent:self
         ] ifFalse:[
-            enableChannel isSymbol ifTrue:[
-                ^ self
-            ]
+            enableChannel isSymbol ifTrue:[^ self]
         ].
         newState := enableChannel value.
     ].
@@ -2896,6 +2893,43 @@
     ].
     self adornment indication:something.
     self updateRawLabel.
+!
+
+setupSubmenu
+    |appl subm|
+
+    submenuChannel notNil ifTrue:[
+        submenuChannel isSymbol ifFalse:[
+            subm := submenuChannel
+        ] ifTrue:[
+            appl := menuPanel application.
+
+            appl notNil ifTrue:[
+                Object messageNotUnderstoodSignal handle:[:ex|
+                    subm := nil
+                ] do:[
+                    subm := appl aspectFor:submenuChannel
+                ]
+            ]
+        ].
+        (subm := subm value) isArray ifTrue:[
+            subm := Menu new fromLiteralArrayEncoding:subm.
+        ].
+        self submenu:subm.
+    ].
+  ^ subMenu
+!
+
+submenuChannel
+    "get the submenu channel
+    "
+  ^ submenuChannel
+!
+
+submenuChannel:aSelectorOrNil
+    "returns the submenu channel
+    "
+    submenuChannel := aSelectorOrNil.
 ! !
 
 !MenuPanel::Item methodsFor:'accessing dimension'!
@@ -2939,26 +2973,44 @@
             self hasSubmenu ifTrue:[
                 x := x + self rightArrow width.
 
-                s notNil ifTrue:[
-                    x := x + ShortcutKeyOffset
-                ] ifFalse:[
-                    x := x + LabelRightOffset
-                ]
+                s notNil ifTrue:[x := x + ShortcutKeyOffset]
+                        ifFalse:[x := x + LabelRightOffset]
             ]
+        ].
+    ] ifFalse:[
+        menuPanel verticalLayout ifFalse:[
+            ^ x max:(self preferredSeperatorSize)
         ]
     ].
-    ^ x
+  ^ x
 !
 
 preferredExtentY
     "compute my preferred extent y
     "
-    |y|
-
-    rawLabel notNil ifTrue:[y := rawLabel heightOn:menuPanel]
-                   ifFalse:[y := menuPanel font height].
-
-  ^ y + VerticalInset + VerticalInset.
+    |s y|
+
+    y := VerticalInset + VerticalInset.
+
+    rawLabel notNil ifTrue:[
+        ^ y + (rawLabel heightOn:menuPanel)
+    ].
+
+    menuPanel verticalLayout ifTrue:[
+        ^ y max:(self preferredSeperatorSize)
+    ].
+  ^ y + (menuPanel font height)
+!
+
+preferredSeperatorSize
+    "returns preferred extent x or y of a separator
+    "
+    |type|
+
+    type := self separatorType.
+    type == #doubleLine ifTrue:[^ 10 ].
+    type == #singleLine ifTrue:[^  6 ].
+  ^ 30
 !
 
 width
@@ -3014,9 +3066,12 @@
 asMenuItem
     "convert to a MenuItem
     "
-    |item|
-
-    item := MenuItem labeled:(self label).
+    |item label|
+
+    (label := self label) isImage ifTrue:[
+        label := label printString
+    ].
+    item := MenuItem labeled:label.
     item activeHelpKey:activeHelpKey.
 
     enableChannel notNil ifTrue:[
@@ -3029,8 +3084,12 @@
     item value:(value value).
     item indication:(self indication value).
 
-    subMenu notNil ifTrue:[
-        item submenu:(subMenu asMenu)
+    submenuChannel isSymbol ifTrue:[
+        item submenuChannel:submenuChannel
+    ] ifFalse:[
+        self submenu notNil ifTrue:[
+            item submenu:(self submenu asMenu)
+        ]
     ].
   ^ item
 
@@ -3059,6 +3118,7 @@
             self accessCharacterPosition:acp.
         ].
 
+        submenuChannel := aMenuItem submenuChannel.
         self submenu:(aMenuItem submenu).
         self value:(aMenuItem value).
     ]
@@ -3069,20 +3129,26 @@
 drawLabel
     "draw label
     "
-    |y|
+    |y img|
+
+    img := rawLabel.
 
     self enabled ifTrue:[
         menuPanel paint:(menuPanel foregroundColor)
     ] ifFalse:[
-        menuPanel paint:(menuPanel disabledForegroundColor)
+        menuPanel paint:(menuPanel disabledForegroundColor).
+
+        ((img respondsTo:#colorMap) and:[img colorMap notNil]) ifTrue:[
+            img := img lightened
+        ]
     ].
 
-    y := (layout top) + (((layout height) - (rawLabel heightOn:menuPanel)) // 2).
+    y := (layout top) + (((layout height) - (img heightOn:menuPanel)) // 2).
 
     (self textLabel) notNil ifTrue:[
         y := y + menuPanel font ascent.
     ].
-    rawLabel displayOn:menuPanel x:((layout left)+HorizontalInset) y:y.
+    img displayOn:menuPanel x:((layout left) + HorizontalInset) y:y.
     self drawShortcutKey.
 !
 
@@ -3126,19 +3192,26 @@
 drawSeparator
     "draw line separator
     "
-    |type l r y|
-
-    type := self seperatorType.
-
-    (type notNil and:[type ~~ #blankLine and:[menuPanel verticalLayout]]) ifTrue:[
-        l := (layout left)  + HorizontalInset.
+    |type l r t b x y|
+
+    type := self separatorType.
+
+    (type notNil and:[type ~~ #blankLine]) ifFalse:[
+        ^ self
+    ].
+
+    l := layout left.
+    t := layout top.
+
+    menuPanel paint:(menuPanel shadowColor).
+
+    menuPanel verticalLayout ifTrue:[
+        l := l + HorizontalInset.
         r := (layout right) - HorizontalInset.
-        y := (layout top) - 1 + ((layout height) // 2).
-
-        type == #doubleLine ifTrue:[
-            y := y - 2.
-        ].
-        menuPanel paint:(menuPanel shadowColor).
+        y := t - 1 + ((layout height) // 2).
+
+        type == #doubleLine ifTrue:[y := y - 2].
+
         menuPanel displayLineFromX:l y:y toX:r y:y.
         menuPanel paint:(menuPanel lightColor).
         y := y + 1.
@@ -3151,6 +3224,25 @@
             menuPanel paint:(menuPanel lightColor).
             y := y + 1.
             menuPanel displayLineFromX:l y:y toX:r y:y.
+        ].
+    ] ifFalse:[
+        b := layout bottom.
+        x := l - 1 + ((layout width) // 2).
+
+        type == #doubleLine ifTrue:[x := x - 2].
+
+        menuPanel displayLineFromX:x y:t toX:x y:b.
+        menuPanel paint:(menuPanel lightColor).
+        x := x + 1.
+        menuPanel displayLineFromX:x y:t toX:x y:b.
+
+        type == #doubleLine ifTrue:[
+            x := x + 3.
+            menuPanel paint:(menuPanel shadowColor).
+            menuPanel displayLineFromX:x y:t toX:x y:b.
+            menuPanel paint:(menuPanel lightColor).
+            x := x + 1.
+            menuPanel displayLineFromX:x y:t toX:x y:b.
         ]
     ]
 
@@ -3177,7 +3269,7 @@
     "
     |form x y col|
 
-    (subMenu notNil and:[menuPanel verticalLayout]) ifTrue:[
+    (self submenu notNil and:[menuPanel verticalLayout]) ifTrue:[
         form := self rightArrow.
         x    := (layout right) - form width - HorizontalInset.
         y    := layout top + ((layout height - (form heightOn:menuPanel)) // 2).
@@ -3320,26 +3412,37 @@
 indicationValue
     "returns indication value or nil
     "
-    |indication val rcv sel|
-
-    (indication := self indication) isNil ifTrue:[
-        ^ nil
+    |idct rcv setGet|
+
+    (idct := self indication) isNil ifTrue:[
+        ^ nil          "/ no indicator
     ].
-
-    indication isSymbol ifFalse:[
-        val := indication value
-    ] ifTrue:[
-        rcv := menuPanel receiver.
-        rcv notNil ifTrue:[
-            (indication last) == $: ifFalse:[
-                sel := indication
-            ] ifTrue:[
-                sel := indication copyFrom:1 to:((indication size) - 1)
+    idct isSymbol ifFalse:[ ^ idct value == true ].
+
+    setGet := (idct last) == $:.
+
+    (rcv := menuPanel receiver) isNil ifTrue:[
+        (rcv := menuPanel application) isNil ifTrue:[^ false].
+
+        setGet ifFalse:[
+            Object messageNotUnderstoodSignal handle:[:ex|idct := false]
+                                                  do:[idct := rcv aspectFor:idct].
+
+            (self isKindOfValueHolder:idct) ifTrue:[
+                self adornment indication:idct.
+                idct addDependent:self.
             ].
-            val := rcv perform:(sel asSymbol).
+          ^ idct value == true
         ]
     ].
-  ^ val == true
+
+    setGet ifTrue:[
+        idct := (idct copyWithoutLast:1) asSymbol
+    ].
+
+    Object messageNotUnderstoodSignal handle:[:ex| idct := false]
+                                          do:[ idct := (rcv perform:idct) == true].
+  ^ idct
 !
 
 indicationValue:aValue
@@ -3373,8 +3476,8 @@
   ^ value ifTrue:[IndicatorOn] ifFalse:[IndicatorOff]
 !
 
-seperatorType
-    "returns type of seperator line or nil
+separatorType
+    "returns type of separator line or nil
     "
     |c lbl|
 
@@ -3410,6 +3513,7 @@
 
     (indicator := self indicator) isNil ifTrue:[
         size == 0 ifTrue:[
+              rawLabel := nil.
             ^ menuPanel mustRearrange
         ].
             
@@ -3546,7 +3650,9 @@
 hideSubmenu
     "hide submenu
     "
-    |windowGrp|
+    |windowGrp subMenu|
+
+    subMenu := self submenu.
 
     subMenu realized ifFalse:[
         menuPanel device unmapWindow:subMenu id
@@ -3564,9 +3670,10 @@
 openSubmenuAt:aPoint
     "open submenu at a point
     "
-    |windowGrp|
+    |windowGrp subMenu|
 
     windowGrp := menuPanel topMenu windowGroup.
+    subMenu   := self setupSubmenu.
 
     windowGrp notNil ifTrue:[
         subMenu windowGroup:windowGrp.
@@ -3669,6 +3776,6 @@
 !MenuPanel class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libwidg2/MenuPanel.st,v 1.19 1997-07-06 09:14:32 ca Exp $'
+    ^ '$Header: /cvs/stx/stx/libwidg2/MenuPanel.st,v 1.20 1997-07-17 10:05:40 ca Exp $'
 ! !
 MenuPanel initialize!