MenuPanel.st
changeset 1726 a4733a8b51e1
parent 1723 f633725a0ace
child 1727 a6365337be59
--- a/MenuPanel.st	Fri Feb 25 14:20:01 2000 +0100
+++ b/MenuPanel.st	Fri Feb 25 17:58:56 2000 +0100
@@ -21,8 +21,9 @@
 		buttonLightColor buttonShadowColor buttonHalfLightColor
 		buttonHalfShadowColor enteredItem buttonEnteredBgColor
 		prevFocusView previousPointerGrab previousKeyboardGrab
-		relativeGrabOrigin hasImplicitGrap'
-	classVariableNames:'InitialSelectionQuerySignal DefaultAdornment
+		relativeGrabOrigin hasImplicitGrap iconIndicationOff
+		iconIndicationOn iconRadioGroupOff iconRadioGroupOn'
+	classVariableNames:'InitialSelectionQuerySignal DefaultAdornment ShortcutKeyOffset
 		DefaultGroupDividerSize DefaultHilightLevel DefaultLevel
 		DefaultItemSpace DefaultButtonItemSpace DefaultForegroundColor
 		DefaultBackgroundColor DefaultHilightForegroundColor
@@ -39,25 +40,17 @@
 !
 
 Object subclass:#Item
-	instanceVariableNames:'layout menuPanel subMenu adornment rawLabel disabledRawLabel
-		enableChannel nameKey accessCharacterPosition value label
-		shortcutKey rawImage activeHelpKey activeHelpText submenuChannel
-		startGroup isButton isVisible hideMenuOnActivated'
+	instanceVariableNames:'layout menuPanel subMenu rawLabel rawLabelExtent disabledRawLabel
+		enableChannel nameKey value label activeHelpKey activeHelpText
+		submenuChannel startGroup isButton isVisible hideMenuOnActivated
+		indication accessCharacterPosition shortcutKey argument choice
+		choiceValue showBusyCursorWhilePerforming accessCharacter'
 	classVariableNames:'HorizontalInset VerticalInset HorizontalButtonInset
-		VerticalButtonInset LabelRightOffset ShortcutKeyOffset
-		IndicatorOn IndicatorOff'
+		VerticalButtonInset LabelRightOffset'
 	poolDictionaries:''
 	privateIn:MenuPanel
 !
 
-Object subclass:#Adornment
-	instanceVariableNames:'indication accessCharacterPosition shortcutKey argument choice
-		choiceValue showBusyCursorWhilePerforming'
-	classVariableNames:''
-	poolDictionaries:''
-	privateIn:MenuPanel::Item
-!
-
 !MenuPanel class methodsFor:'documentation'!
 
 copyright
@@ -317,6 +310,80 @@
 
 ! !
 
+!MenuPanel class methodsFor:'default icons'!
+
+iconIndicationOff
+    "This resource specification was automatically generated
+     by the ImageEditor of ST/X."
+
+    "Do not manually edit this!! If it is corrupted,
+     the ImageEditor may not be able to read the specification."
+
+    "
+     self iconIndicationOff inspect
+     ImageEditor openOnClass:self andSelector:#iconIndicationOff
+    "
+
+    <resource: #image>
+
+    ^Icon
+        constantNamed:#'MenuPanel iconIndicationOff'
+        ifAbsentPut:[(Depth2Image new) width: 14; height: 14; photometric:(#palette); bitsPerSample:(#(2 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'UUUUPG???8A0@@B@\@@@ G@@@HA0@@B@\@@@ G@@@HA0@@B@\@@@ G@@@HA0@@B@Z*** @@@@@@b') ; colorMapFromArray:#[255 255 255 127 127 127 170 170 170 0 0 0]; mask:((Depth1Image new) width: 14; height: 14; photometric:(#blackIs0); bitsPerSample:(#(1 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'??3??O?<??3??O?<??3??O?<??3??O?<??3??@@a') ; yourself); yourself]!
+
+iconIndicationOn
+    "This resource specification was automatically generated
+     by the ImageEditor of ST/X."
+
+    "Do not manually edit this!! If it is corrupted,
+     the ImageEditor may not be able to read the specification."
+
+    "
+     self iconIndicationOn inspect
+     ImageEditor openOnClass:self andSelector:#iconIndicationOn
+    "
+
+    <resource: #image>
+
+    ^Icon
+        constantNamed:#'MenuPanel iconIndicationOn'
+        ifAbsentPut:[(Depth2Image new) width: 14; height: 14; photometric:(#palette); bitsPerSample:(#(2 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'****$H@@@MBEUUWP!!UUU4HUUT]BEUTGP!!ETA4HPTA]BD@AWP!!PAU4HUAU]BEUUWP/???4EUUUU@b') ; colorMapFromArray:#[0 0 0 255 255 255 127 127 127 170 170 170]; mask:((Depth1Image new) width: 14; height: 14; photometric:(#blackIs0); bitsPerSample:(#(1 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'??3??O?<??3??O?<??3??O?<??3??O?<??3??@@a') ; yourself); yourself]!
+
+iconRadioGroupOff
+    "This resource specification was automatically generated
+     by the ImageEditor of ST/X."
+
+    "Do not manually edit this!! If it is corrupted,
+     the ImageEditor may not be able to read the specification."
+
+    "
+     self iconRadioGroupOff inspect
+     ImageEditor openOnClass:self andSelector:#iconRadioGroupOff
+    "
+
+    <resource: #image>
+
+    ^Icon
+        constantNamed:#'MenuPanel iconRadioGroupOff'
+        ifAbsentPut:[(Depth2Image new) width: 15; height: 15; photometric:(#palette); bitsPerSample:(#(2 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@AUP@@E@AP@DO?Y@D_?>(AO??;AO???LS???3D???<1O???LS???3A_??3@Z??<0A+?00@C@C0@@O?@@') ; colorMapFromArray:#[0 0 0 85 85 85 170 170 170 255 255 255]; mask:((Depth1Image new) width: 15; height: 15; photometric:(#blackIs0); bitsPerSample:(#(1 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'A<@_<C?8_?1??O?:??+?>/?:??)?=G?4O< HL@_@') ; yourself); yourself]!
+
+iconRadioGroupOn
+    "This resource specification was automatically generated
+     by the ImageEditor of ST/X."
+
+    "Do not manually edit this!! If it is corrupted,
+     the ImageEditor may not be able to read the specification."
+
+    "
+     self iconRadioGroupOn inspect
+     ImageEditor openOnClass:self andSelector:#iconRadioGroupOn
+    "
+
+    <resource: #image>
+
+    ^Icon
+        constantNamed:#'MenuPanel iconRadioGroupOn'
+        ifAbsentPut:[(Depth2Image new) width: 15; height: 15; photometric:(#palette); bitsPerSample:(#(2 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@AUP@@E@AP@DO?Y@D]@^(AL@@;AM@@GLS@@@3D0@@L1L@@CLSP@A3A\@@3@Z4A<0A+?00@C@C0@@O?@@') ; colorMapFromArray:#[0 0 0 85 85 85 170 170 170 255 255 255]; mask:((Depth1Image new) width: 15; height: 15; photometric:(#blackIs0); bitsPerSample:(#(1 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'A<@_<C?8_?1??O?:??+?>/?:??)?=G?4O< HL@_@') ; yourself); yourself]! !
+
 !MenuPanel class methodsFor:'defaults'!
 
 updateStyleCache
@@ -440,6 +507,8 @@
     DefaultSelectionFollowsMouse := styleSheet at:#'menu.selectionFollowsMouse' default:false.
     DefaultEnteredLevel          := styleSheet at:#'menu.enteredLevel'          default:0.
 
+    ShortcutKeyOffset            := 5.
+
     Item updateStyleCache
 
     "
@@ -1315,7 +1384,7 @@
             x := shortKeyInset + shCtKey + self subMenuIndicationWidth.
 
             (shCtKey ~~ 0 and:[hasMenu]) ifTrue:[
-                x := x + (Item shortcutKeyOffset) 
+                x := x + ShortcutKeyOffset 
             ]
         ].
 "/ to have a small inset
@@ -1338,6 +1407,52 @@
     ^ RightArrowForm width
 ! !
 
+!MenuPanel methodsFor:'accessing-interactors'!
+
+iconIndicationOff
+    iconIndicationOff isNil ifTrue:[
+        superMenu notNil ifTrue:[
+            iconIndicationOff := superMenu iconIndicationOff
+        ] ifFalse:[
+            iconIndicationOff := self registerImageOnDevice:(self class iconIndicationOff)
+        ].
+    ].
+    ^ iconIndicationOff
+!
+
+iconIndicationOn
+    iconIndicationOn isNil ifTrue:[
+        superMenu notNil ifTrue:[
+            iconIndicationOn := superMenu iconIndicationOn
+        ] ifFalse:[
+            iconIndicationOn := self registerImageOnDevice:(self class iconIndicationOn)
+        ].
+    ].
+    ^ iconIndicationOn
+!
+
+iconRadioGroupOff
+    iconRadioGroupOff isNil ifTrue:[
+        superMenu notNil ifTrue:[
+            iconRadioGroupOff := superMenu iconRadioGroupOff
+        ] ifFalse:[
+            iconRadioGroupOff := self registerImageOnDevice:(self class iconRadioGroupOff)
+        ].
+    ].
+    ^ iconRadioGroupOff
+!
+
+iconRadioGroupOn
+    iconRadioGroupOn isNil ifTrue:[
+        superMenu notNil ifTrue:[
+            iconRadioGroupOn := superMenu iconRadioGroupOn
+        ] ifFalse:[
+            iconRadioGroupOn := self registerImageOnDevice:(self class iconRadioGroupOn)
+        ].
+    ].
+    ^ iconRadioGroupOn
+! !
+
 !MenuPanel methodsFor:'accessing-items'!
 
 itemAt:stringOrNumber
@@ -3207,6 +3322,19 @@
     ^ true.
 !
 
+registerImageOnDevice:anImage
+    |image|
+
+    (image := anImage) notNil ifTrue:[
+        image device ~~ device ifTrue:[
+            image := image copy.
+        ].
+        image := image on:device.
+        image := image clearMaskedPixels.
+    ].
+    ^ image
+!
+
 selectItemsForShortcutKey:aKey maxDepth:maxDepth
     "get sequence of items up to the item providing the key (inclusive). The
      last entry into the collection is the item providing the key, the first
@@ -3221,7 +3349,7 @@
             anItem shortcutKey == aKey ifTrue:[
                 seq := OrderedCollection new.
             ] ifFalse:[
-                (menu := anItem basicGetSubmenu) notNil ifTrue:[
+                (menu := anItem currentSubmenu) notNil ifTrue:[
                     seq := menu selectItemsForShortcutKey:aKey maxDepth:maxDepth-1
                 ]
             ].
@@ -3494,7 +3622,11 @@
         item selected:false.
     ].
     newSel notNil ifTrue:[
-        self pointerEntersItem:nil.
+        newSel == enteredItem ifTrue:[
+            enteredItem := nil
+        ] ifFalse:[
+            self pointerEntersItem:nil
+        ].
         selection := newSel.
 
         ActiveHelp isActive ifTrue:[
@@ -3534,10 +3666,6 @@
     ^ LabelRightOffset
 !
 
-shortcutKeyOffset
-    ^ ShortcutKeyOffset
-!
-
 verticalInset
     ^ VerticalInset
 ! !
@@ -3561,90 +3689,6 @@
     VerticalButtonInset   := 3.
 
     LabelRightOffset      := 15.
-    ShortcutKeyOffset     := 5.
-
-    IndicatorOn  := self checkedImage.
-    IndicatorOff := self uncheckedImage.
-! !
-
-!MenuPanel::Item class methodsFor:'image specs'!
-
-checkOffIcon
-    "This resource specification was automatically generated
-     by the ImageEditor of ST/X."
-
-    "Do not manually edit this!! If it is corrupted,
-     the ImageEditor may not be able to read the specification."
-
-    "
-     self checkOffIcon inspect
-     ImageEditor openOnClass:self andSelector:#checkOffIcon
-    "
-
-    <resource: #image>
-
-    ^Icon
-	constantNamed:#'MenuPanel::Item checkOffIcon'
-	ifAbsentPut:[(Depth2Image new) width: 15; height: 15; photometric:(#palette); bitsPerSample:(#(2 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@AUP@@E@AP@DO?Y@D_?>(AO??;AO???LS???3D???<1O???LS???3A_??3@Z??<0A+?00@C@C0@@O?@@') ; colorMapFromArray:#[0 0 0 85 85 85 170 170 170 255 255 255]; mask:((Depth1Image new) width: 15; height: 15; photometric:(#blackIs0); bitsPerSample:(#(1 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'A<@_<C?8_?1??O?:??+?>/?:??)?=G?4O< HL@_@') ; yourself); yourself]!
-
-checkOnIcon
-    "This resource specification was automatically generated
-     by the ImageEditor of ST/X."
-
-    "Do not manually edit this!! If it is corrupted,
-     the ImageEditor may not be able to read the specification."
-
-    "
-     self checkOnIcon inspect
-     ImageEditor openOnClass:self andSelector:#checkOnIcon
-    "
-
-    <resource: #image>
-
-    ^Icon
-	constantNamed:#'MenuPanel::Item checkOnIcon'
-	ifAbsentPut:[(Depth2Image new) width: 15; height: 15; photometric:(#palette); bitsPerSample:(#(2 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@AUP@@E@AP@DO?Y@D]@^(AL@@;AM@@GLS@@@3D0@@L1L@@CLSP@A3A\@@3@Z4A<0A+?00@C@C0@@O?@@') ; colorMapFromArray:#[0 0 0 85 85 85 170 170 170 255 255 255]; mask:((Depth1Image new) width: 15; height: 15; photometric:(#blackIs0); bitsPerSample:(#(1 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'A<@_<C?8_?1??O?:??+?>/?:??)?=G?4O< HL@_@') ; yourself); yourself]!
-
-checkedImage
-    "This resource specification was automatically generated
-     by the ImageEditor of ST/X."
-
-    "Do not manually edit this!! If it is corrupted,
-     the ImageEditor may not be able to read the specification."
-
-    "
-     self checkedImage inspect
-     ImageEditor openOnClass:self andSelector:#checkedImage
-    "
-
-    <resource: #image>
-
-    ^Icon
-	constantNamed:#'MenuPanel::Item checkedImage'
-	ifAbsentPut:[(Depth2Image new) width: 14; height: 14; photometric:(#palette); bitsPerSample:(#(2 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'****$H@@@MBEUUWP!!UUU4HUUT]BEUTGP!!ETA4HPTA]BD@AWP!!PAU4HUAU]BEUUWP/???4EUUUU@b') ; colorMapFromArray:#[0 0 0 255 255 255 127 127 127 170 170 170]; mask:((Depth1Image new) width: 14; height: 14; photometric:(#blackIs0); bitsPerSample:(#(1 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'??3??O?<??3??O?<??3??O?<??3??O?<??3??@@a') ; yourself); yourself]
-
-    "Modified: / 6.9.1998 / 22:29:58 / cg"
-!
-
-uncheckedImage
-    "This resource specification was automatically generated
-     by the ImageEditor of ST/X."
-
-    "Do not manually edit this!! If it is corrupted,
-     the ImageEditor may not be able to read the specification."
-
-    "
-     self uncheckedImage inspect
-     ImageEditor openOnClass:self andSelector:#uncheckedImage
-    "
-
-    <resource: #image>
-
-    ^Icon
-	constantNamed:#'MenuPanel::Item uncheckedImage'
-	ifAbsentPut:[(Depth2Image new) width: 14; height: 14; photometric:(#palette); bitsPerSample:(#(2 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'UUUUPG???8A0@@B@\@@@ G@@@HA0@@B@\@@@ G@@@HA0@@B@\@@@ G@@@HA0@@B@Z*** @@@@@@b') ; colorMapFromArray:#[255 255 255 127 127 127 170 170 170 0 0 0]; mask:((Depth1Image new) width: 14; height: 14; photometric:(#blackIs0); bitsPerSample:(#(1 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'??3??O?<??3??O?<??3??O?<??3??O?<??3??@@a') ; yourself); yourself]
-
-    "Modified: / 6.9.1998 / 22:24:24 / cg"
 ! !
 
 !MenuPanel::Item class methodsFor:'instance creation'!
@@ -3680,15 +3724,14 @@
 toggleIndication
     "toggle indication or choice
     "
-    |arg choiceHolder|
-
-    self indication notNil ifTrue:[    
+    |arg|
+
+    indication notNil ifTrue:[    
         arg := self indicationValue not.
         self indicationValue:arg.
     ] ifFalse:[
-        (choiceHolder := self choice) notNil ifTrue:[
-            arg := self choiceValue.
-            choiceHolder value:arg.
+        choice notNil ifTrue:[
+            choice value:choiceValue.
           ^ true
         ]
     ].
@@ -3700,55 +3743,31 @@
 accessCharacter
     "returns my accessCharacter or nil
     "
-    accessCharacterPosition isNil ifTrue:[
-	^ nil
-    ].
-  ^ (rawLabel string) at:accessCharacterPosition ifAbsent:nil
+    ^ accessCharacter
 !
 
 accessCharacterPosition
     "get the access character position or nil
     "
-  ^ accessCharacterPosition
-!
-
-accessCharacterPosition:anIndex
+    ^ accessCharacterPosition
+!
+
+accessCharacterPosition:anIndex 
     "set the access character position or nil
     "
-    accessCharacterPosition ~~ anIndex ifTrue:[
-	accessCharacterPosition := anIndex.
-	self updateRawLabel.
-    ].
+    accessCharacterPosition := anIndex.
 !
 
 argument
     "gets the argument
     "
-    adornment isNil ifTrue:[^ nil ].
-  ^ adornment argument
+    ^ argument
 !
 
 argument:anArgument
     "sets the argument
     "
-    (anArgument notNil or:[adornment notNil]) ifTrue:[
-        self adornment argument:anArgument.
-    ]
-
-    "Modified: / 4.2.2000 / 12:41:00 / cg"
-!
-
-basicGetSubmenu
-    "returns my submenu or nil
-    "
-    ^ subMenu
-!
-
-compareAccessCharacterWith:aKey
-    "returns true if key is my access character
-    "
-    ^ self accessCharacter == aKey
-
+    argument := anArgument.
 !
 
 currentSubmenu
@@ -3767,30 +3786,62 @@
     "set a new label; if the label changed, a redraw is performed;
      handle characters $& (ST-80 compatibility)
     "
-    |i rest s|
-
-    accessCharacterPosition := nil.
-    label := aLabel value.
-
-    (label isString and:[(s := label size) > 1]) ifTrue:[
-	i := 1.
-
-	[((i := label indexOf:$& startingAt:i) ~~ 0 
-	and:[i < s])] whileTrue:[
-	    rest := label copyFrom:(i+1).
-
-	    i == 1 ifTrue:[label := rest]
-		  ifFalse:[label := (label copyFrom:1 to:(i-1)), rest].
-
-	    (label at:i) == $& ifTrue:[i := i + 1]
-			      ifFalse:[accessCharacterPosition := i].
-	    s := s - 1.
-	]
-    ].
-
-    self updateRawLabel
-
-    "Modified: / 31.7.1998 / 00:52:26 / cg"
+    |size char lbl
+     h "{ Class:SmallInteger }"
+     w "{ Class:SmallInteger }"
+    |
+    accessCharacter := rawLabelExtent := disabledRawLabel := nil.
+    label    := aLabel value.
+    rawLabel := label value ? ''.
+
+    rawLabel isString ifTrue:[
+        "CHECK FOR SEPARATOR"
+
+        (isButton not and:[indication isNil and:[choice isNil]]) ifTrue:[
+            size := rawLabel size.
+
+            size == 0 ifTrue:[
+                rawLabel := nil.                        "blank separator"
+              ^ self
+            ].
+
+            size == 1 ifTrue:[
+                char := rawLabel first.
+
+                (char == $- or:[char == $=]) ifTrue:[
+                    label    := rawLabel.               "line separator"
+                    rawLabel := nil.
+                  ^ self
+                ]
+            ]
+        ]
+    ] ifFalse:[
+        rawLabel isCollection ifTrue:[
+            rawLabel := rawLabel asArray.
+        ]
+    ].
+    rawLabel isArray ifTrue:[
+        w := h := 0.
+
+        rawLabel keysAndValuesDo:[:i :el|
+            el notNil ifTrue:[
+                lbl := self updateAccessCharacterFor:el.
+                rawLabel at:i put:lbl.
+                w := w max:(lbl widthOn:menuPanel).
+                h := h + 1 + (lbl heightOn:menuPanel).
+            ] ifFalse:[
+                h := h + 3
+            ]
+        ]
+    ] ifFalse:[
+        rawLabel := self updateAccessCharacterFor:rawLabel.
+        w := rawLabel  widthOn:menuPanel.
+        h := rawLabel heightOn:menuPanel.
+    ].
+    rawLabelExtent := w@h.
+
+    menuPanel shown ifTrue:[ self fetchImages ].
+    menuPanel mustRearrange
 !
 
 menuPanel
@@ -3830,7 +3881,7 @@
     "
     shortcutKey ~~ aKey ifTrue:[
         shortcutKey := aKey.
-        menuPanel invalidateItem:self repairNow:false.
+        self invalidate.
     ].
 !
 
@@ -3845,12 +3896,7 @@
     "start group #left #right #center ...
      at the moment only #right is implemented
     "
-    (startGroup isNil or:[startGroup == #right]) ifTrue:[
-	startGroup := aSymbol
-    ] ifFalse:[
-	self warn:('not supported group: ', aSymbol printString ).
-    ]
-
+    startGroup := aSymbol.
 !
 
 submenu
@@ -3890,7 +3936,20 @@
 textLabel
     "returns my textLabel or nil if none text
     "
-    ^ rawLabel perform:#string ifNotUnderstood:nil
+    |txt|
+
+    rawLabel notNil ifTrue:[
+        rawLabel isArray ifFalse:[
+            ^ rawLabel perform:#string ifNotUnderstood:nil
+        ].
+
+        rawLabel do:[:el|
+            (txt := el perform:#string ifNotUnderstood:nil) notNil ifTrue:[
+                ^ txt
+            ]
+        ].
+    ].
+    ^ nil
 
 !
 
@@ -3909,69 +3968,57 @@
 value:aValue argument:anArgument
     "set the value and an argument
     "
-    self value:aValue.
-    self argument:anArgument.
+    value    := aValue.
+    argument := anArgument.
 ! !
 
 !MenuPanel::Item methodsFor:'accessing-behavior'!
 
 choice
-    "get choice indication
-    "
-    adornment isNil ifTrue:[^ nil].
-  ^ adornment choice
-
-    "Created: / 14.8.1998 / 14:38:52 / cg"
+    "implements a radio group; the field
+    "
+    ^ choice
+
 !
 
 choice:something
     "set choice indication
     "
-    |old new|
-
-    old := self choice.
-    old == something ifTrue:[^ self].
-
-    old isValueModel ifTrue:[
-        old removeDependent:self
-    ].
-
-    new := something.
-    new isSymbol ifTrue:[
-        new := self aspectAt:new.
-        new isNil ifTrue:[
-            new := something
+    choice == something ifTrue:[^ self].
+
+    choice isValueModel ifTrue:[
+        choice removeDependent:self
+    ].
+
+    (choice := something) notNil ifTrue:[
+        choice isSymbol ifTrue:[
+            (choice := self aspectAt:choice) isNil ifTrue:[
+                choice := something
+            ]
+        ].
+        choice isValueModel ifTrue:[
+            choice addDependent:self
         ]
     ].
-    new isValueModel ifTrue:[
-        new addDependent:self
-    ].
-    self adornment choice:new.
-    self updateRawLabel.
-
-    "Created: / 14.8.1998 / 14:39:11 / cg"
-    "Modified: / 14.8.1998 / 16:13:19 / cg"
 !
 
 choiceValue
-    "get choice value
-    "
-    adornment isNil ifTrue:[^ nil].
-  ^ adornment choiceValue
-
-    "Created: / 14.8.1998 / 15:46:33 / cg"
+    "implements a radio group; the value writen to the choice if selected
+    "
+    ^ choiceValue
+
 !
 
 choiceValue:something
-    "set choice value
-    "
-    (something notNil or:[adornment notNil]) ifTrue:[
-        self adornment choiceValue:something.
-        self updateRawLabel.
-    ]
-
-    "Created: / 14.8.1998 / 15:46:59 / cg"
-    "Modified: / 4.2.2000 / 12:41:45 / cg"
+    "implements a radio group; the value writen to the choice if selected
+    "
+    choiceValue ~= something ifTrue:[
+        choiceValue := something.
+
+        choice notNil ifTrue:[
+            self invalidate
+        ]
+    ].
 !
 
 enabled
@@ -4027,9 +4074,7 @@
     ].
 
     newState ~~ oldState ifTrue:[
-        rawLabel notNil ifTrue:[
-            menuPanel invalidateItem:self repairNow:false
-        ]
+        self invalidate
     ].
 !
 
@@ -4043,7 +4088,7 @@
 hideMenuOnActivated:aBool
    "hide the menu when the item was activated; the default is true
    "
-   hideMenuOnActivated := aBool ? true.
+   hideMenuOnActivated := aBool.
 
 
 !
@@ -4051,27 +4096,26 @@
 indication
     "get on/off indication
     "
-    adornment isNil ifTrue:[^ nil].
-  ^ adornment indication
+    ^ indication
 !
 
 indication:something
     "set on/off indication
     "
-    |old|
-
-    old := self indication.
-    old == something ifTrue:[^ self].
-
-    old isValueModel ifTrue:[
-        old removeDependent:self
-    ].
-
-    something isValueModel ifTrue:[
-        something addDependent:self
-    ].
-    self adornment indication:something.
-    self updateRawLabel.
+    indication == something ifTrue:[^ self].
+
+    indication isValueModel ifTrue:[
+        indication removeDependent:self
+    ].
+
+    (indication := something) notNil ifTrue:[
+        indication isValueModel ifTrue:[
+            indication addDependent:self
+        ] ifFalse:[
+            "/ to force an update of the value
+            self indicationValue
+        ]
+    ].
 !
 
 isButton
@@ -4095,23 +4139,18 @@
 
 showBusyCursorWhilePerforming
     "get the flag which controls if a busy cursor is to be shown
-     while performing the menu action. Defaults to false."
-
-    adornment isNil ifTrue:[^ false ].
-  ^ adornment showBusyCursorWhilePerforming
+     while performing the menu action. Defaults to false.
+    "
+    ^ showBusyCursorWhilePerforming ? false
 
 
 !
 
 showBusyCursorWhilePerforming:aBoolean
     "set/clear the flag which controls if a busy cursor is to be shown
-     while performing the menu action. Defaults to false."
-
-    ((aBoolean == true) or:[adornment notNil]) ifTrue:[
-        self adornment showBusyCursorWhilePerforming:aBoolean.
-    ]
-
-
+     while performing the menu action. Defaults to false.
+    "
+    showBusyCursorWhilePerforming := aBoolean.
 !
 
 submenuChannel
@@ -4138,7 +4177,7 @@
     "set a new layout ( Rectangle )
     "
     layout := aLayout.
-    menuPanel invalidateItem:self repairNow:false.
+    self invalidate.
 
 !
 
@@ -4178,12 +4217,17 @@
             x := x + 5.
         ].
     ] ifFalse:[
-        x := x + (rawLabel  widthOn:menuPanel).
-        y := y + (rawLabel heightOn:menuPanel).
-
-        (isButton not and:[menuPanel showSeparatingLines]) ifTrue:[
-            "width of separator is 2 plus right offset 1 := 3"
-            isVertical ifFalse:[x := x + 3] ifTrue:[y := y + 3].
+        x := x + rawLabelExtent x.
+        y := y + rawLabelExtent y.
+
+        isButton ifFalse:[
+            menuPanel showSeparatingLines ifTrue:[
+                "width of separator is 2 plus right offset 1 := 3"
+                isVertical ifFalse:[x := x + 3] ifTrue:[y := y + 3].
+            ].
+            (indication notNil or:[choice notNil]) ifTrue:[
+                x := x + 2 + menuPanel iconIndicationOff width.
+            ].
         ]
     ].
     ^ x@y
@@ -4357,62 +4401,38 @@
 
 !MenuPanel::Item methodsFor:'change & update'!
 
-choiceChanged
-    "called when the choice changed
-    "
-    |indicator|
-
-    isButton ifFalse:[
-        indicator := self choiceForm.
-
-        indicator = rawLabel icon ifTrue:[
-            ^ self
+update:something with:aParameter from:changedObject
+
+    |form rect|
+
+    (menuPanel isNil or:[layout isNil]) ifTrue:[^ self].        "/ not yet realized or computed
+
+    self isSeparator ifFalse:[
+        "/ NOT A SEPARATOR
+
+        menuPanel shown ifTrue:[
+            changedObject == enableChannel ifTrue:[
+                ^ self invalidate
+            ].
+
+            (changedObject == indication or:[changedObject == choice]) ifTrue:[
+                isButton ifTrue:[
+                    self invalidate
+                ] ifFalse:[
+                    "/ invalidate the interactor only
+                    "/ take any interactor; interactors has the same extent
+                    form := menuPanel iconIndicationOff.
+
+                    rect := Rectangle left:(layout left + HorizontalInset)
+                                       top:(layout top)
+                                     width:(form width)
+                                    height:(layout height).
+
+                    menuPanel invalidate:rect repairNow:false
+                ].
+                ^ self
+            ].
         ].
-        rawLabel icon:indicator.
-
-        disabledRawLabel notNil ifTrue:[
-            disabledRawLabel icon:indicator
-        ]
-    ].
-    menuPanel invalidateItem:self repairNow:false.
-
-!
-
-indicationChanged
-    "called when the indication changed
-    "
-    |indicator|
-
-    isButton ifFalse:[
-        indicator := self indicatorForm.
-
-        indicator = rawLabel icon ifTrue:[
-            ^ self
-        ].
-        rawLabel icon:indicator.
-
-        disabledRawLabel notNil ifTrue:[
-            disabledRawLabel icon:indicator
-        ]
-    ].
-    menuPanel invalidateItem:self repairNow:false
-!
-
-update:something with:aParameter from:changedObject
-
-    rawLabel notNil ifTrue:[
-        "/ NOT A SEPARATOR
-
-        changedObject == self indication ifTrue:[
-            ^ self indicationChanged
-        ].
-
-        changedObject == self choice ifTrue:[
-            ^ self choiceChanged
-        ].
-        changedObject == enableChannel ifTrue:[
-            ^ menuPanel invalidateItem:self repairNow:false
-        ]
     ].
 
     changedObject == isVisible ifTrue:[
@@ -4427,15 +4447,11 @@
 updateIndicators
     "update indicators
     "
-    |indicator| 
-
-    indicator := self indication.
-
-    (indicator notNil and:[indicator isSymbol]) ifTrue:[
-        " indicator is a selector otherwise a change notification
+    (indication notNil and:[indication isSymbol]) ifTrue:[
+        " indication is a selector otherwise a change notification
           is raised from the model !!!!
         "
-        self indicationChanged        
+        self update:nil with:nil from:indication
     ]
 ! !
 
@@ -4462,15 +4478,15 @@
         item enabled:(enableChannel value)
     ].
 
-    item accessCharacterPosition:(self accessCharacterPosition).
-    item startGroup:(self startGroup).
-    item argument:(self argument).
-    item nameKey:(self nameKey).
+    item accessCharacterPosition:accessCharacterPosition.
+    item startGroup:startGroup.
+    item argument:argument.
+    item nameKey:nameKey.
     item shortcutKeyCharacter:shortcutKey.
     item value:(value value).
-    item indication:(self indication value).
-    item choice:(self choice value).
-    item choiceValue:(self choiceValue).
+    item indication:(indication value).
+    item choice:(choice value).
+    item choiceValue:choiceValue.
     item isVisible:(self isVisible).
     item hideMenuOnActivated:(self hideMenuOnActivated).
     item showBusyCursorWhilePerforming:(self showBusyCursorWhilePerforming).
@@ -4491,40 +4507,35 @@
 menuItem:aMenuItem
     "setup attributes from a MenuItem
     "
-    |var lbl|
+    |lbl|
 
     menuPanel disabledRedrawDo:[
-        label := nil.
-        self activeHelpKey:(aMenuItem activeHelpKey).
-        self enabled:(aMenuItem enabled).
-        self nameKey:(aMenuItem nameKey).
+        label := rawLabel := nil.
+        accessCharacterPosition       := aMenuItem accessCharacterPosition.
+        argument                      := aMenuItem argument.
+        choiceValue                   := aMenuItem choiceValue.
+        showBusyCursorWhilePerforming := aMenuItem showBusyCursorWhilePerforming.
+        hideMenuOnActivated           := aMenuItem hideMenuOnActivated.
+        isButton                      := aMenuItem isButton ? false.
+        nameKey                       := aMenuItem nameKey.
+        startGroup                    := aMenuItem startGroup.
+        shortcutKey                   := aMenuItem shortcutKeyCharacter.
+        value                         := aMenuItem value.
+        activeHelpKey                 := aMenuItem activeHelpKey.
+        activeHelpText                := nil.
+
+        self    enabled:(aMenuItem enabled).
         self indication:(aMenuItem indication).
-        self choice:(aMenuItem choice).
-        self choiceValue:(aMenuItem choiceValue).
-        self isButton:(aMenuItem isButton).
-        self startGroup:(aMenuItem startGroup).
-        self isVisible:(aMenuItem isVisible).
-        self hideMenuOnActivated:(aMenuItem hideMenuOnActivated).
-        self showBusyCursorWhilePerforming:(aMenuItem showBusyCursorWhilePerforming).
+        self     choice:(aMenuItem choice).
+        self  isVisible:(aMenuItem isVisible).
 
         (lbl := aMenuItem labelImage value) isNil ifTrue:[
             lbl := aMenuItem rawLabel. "/ avoid translating &'s twice
         ].
+
         self label:lbl.
-
-        (var := aMenuItem accessCharacterPosition) notNil ifTrue:[
-            self accessCharacterPosition:var.
-        ].
-
-        self shortcutKey:(aMenuItem shortcutKeyCharacter).
-
-        (var := aMenuItem argument) notNil ifTrue:[
-            self argument:var.
-        ].
-
         submenuChannel := aMenuItem submenuChannel.
         self submenu:(aMenuItem submenu).
-        self value:(aMenuItem value).
     ]
 
     "Modified: / 22.8.1998 / 15:34:16 / cg"
@@ -4535,9 +4546,8 @@
 drawButton
     "draw as button
     "
-    |drawObject fg level isSelected bg holder ownBgCol
+    |drawObject fg level isSelected bg ownBgCol
      x "{ Class:SmallInteger }"
-     y "{ Class:SmallInteger }"
     |
     drawObject := rawLabel.
 
@@ -4569,37 +4579,27 @@
         menuPanel fillRectangle:layout.
     ].
 
-    "DRAW LABEL"
-    menuPanel paint:fg.
-
-    y := layout top  + ((layout height - (drawObject heightOn:menuPanel)) // 2).
     x := layout left + menuPanel buttonPassiveLevel + HorizontalButtonInset.
 
-    drawObject isImageOrForm ifFalse:[
-        y := y + menuPanel font ascent
-    ].
-
     isSelected ifFalse:[
         "check whether button should be drawn selected; indicator or radio button"
 
-        self indicationValue == true ifTrue:[
+        indication notNil ifTrue:[
             "button is indicator and set"
-            isSelected := true
-        ]ifFalse:[
-            "check if part of radio button group and the active one"
-            isSelected := ((holder := self choice) notNil and:[holder value = self choiceValue]).
+            isSelected := self indicationValue
+        ] ifFalse:[
+            isSelected := (choice notNil and:[choice value = choiceValue]).
         ]
     ].
 
     isSelected ifTrue:[   
-        x := x + 1.
-        y := y + 1.
         level := menuPanel buttonActiveLevel.
+        x     := x + level abs.
     ] ifFalse:[   
         level := self isEntered ifTrue:[menuPanel buttonEnteredLevel]
                                ifFalse:[menuPanel buttonPassiveLevel].
     ].
-    drawObject displayOn:menuPanel x:x y:y.
+    self drawRawLabel:drawObject atX:x paint:fg.
 
     level ~~ 0 ifTrue:[
         menuPanel drawButtonEdgesFor:self level:level
@@ -4609,15 +4609,14 @@
 drawLabel
     "draw a labeled entry; no button, no separator.
     "
-    |scKey cLb cLa img fg arrow 
-     buttonLevel isSelected
+    |scKey cLb cLa drawObject fg arrow 
+     isSelected form
      h "{ Class:SmallInteger }"
      y "{ Class:SmallInteger }"
      x "{ Class:SmallInteger }"
      t "{ Class:SmallInteger }"
-     l "{ Class:SmallInteger }"
     |
-    img := rawLabel.
+    drawObject := rawLabel.
 
     (isSelected := self isSelected) ifTrue:[
         fg := self activeForegroundColor
@@ -4626,36 +4625,32 @@
             fg := menuPanel foregroundColor
         ] ifFalse:[
             fg  := menuPanel disabledForegroundColor.
-            img := self disabledRawLabel
+            drawObject := self disabledRawLabel
         ]
     ].
 
     h := layout height.
-    l := layout left.
+    x := layout left + HorizontalInset.
     t := layout top.
-    y := t + ((h - (img heightOn:menuPanel)) // 2).
-
-    img isImageOrForm ifFalse:[
-        y := y + menuPanel font ascent
-    ].
-
-    menuPanel paint:fg.
-    img displayOn:menuPanel x:(l + HorizontalInset) y:y.
+
+    ((form := self indicatorForm) notNil or:[(form := self choiceForm) notNil]) ifTrue:[
+        y := t + ((h - form height) // 2).
+        form displayOn:menuPanel x:x y:y.
+        x := x + 2 + form width.
+    ].
+
+    self drawRawLabel:drawObject atX:x paint:fg.
 
     "/ DRAW SHORTCUT KEY
 
-    (shortcutKey notNil and:[MenuView showAcceleratorKeys == true]) ifTrue:[
-        menuPanel isVerticalLayout ifTrue:[ "/ only for vertical menus ...
-            (scKey:= self shortcutKeyAsString) notNil ifTrue:[
-                (x := menuPanel shortKeyInset) == 0 ifTrue:[
-                    x := HorizontalInset + LabelRightOffset + (img widthOn:menuPanel)
-                ].
-                x := l + x.
-                y := t + ((h - (scKey heightOn:menuPanel)) // 2).
-                y := y + menuPanel font ascent.
-                scKey displayOn:menuPanel x:x y:y. 
-            ].
-        ].
+    (     shortcutKey notNil
+     and:[(x := menuPanel shortKeyInset) ~~ 0
+     and:[(scKey:= self shortcutKeyAsString) notNil]]
+    ) ifTrue:[
+        x := layout left + x.
+        y := t + ((h - (scKey heightOn:menuPanel)) // 2).
+        y := y + menuPanel font ascent.
+        scKey displayOn:menuPanel x:x y:y. 
     ].
 
     "/ DRAW SUBMENU INDICATION
@@ -4666,7 +4661,7 @@
         y := t + (h - arrow height // 2).
 
         (menuPanel styleSheet is3D not
-        or:[(img := menuPanel rightArrowShadow) isNil]) ifTrue:[
+        or:[(drawObject := menuPanel rightArrowShadow) isNil]) ifTrue:[
             ^ menuPanel displayForm:arrow x:x y:y
         ].
         cLa := menuPanel shadowColor.
@@ -4680,12 +4675,47 @@
         menuPanel paint:cLa.
         menuPanel displayForm:arrow x:x y:y.
         menuPanel paint:cLb.
-        menuPanel displayForm:img x:x y:y. 
+        menuPanel displayForm:drawObject x:x y:y. 
     ]
 
     "Modified: / 6.9.1998 / 21:48:53 / cg"
 !
 
+drawRawLabel:aLabel atX:x paint:fg
+    "draw a labeled entry; no button, no separator.
+    "
+    |y  "{ Class:SmallInteger }"
+     y0 "{ Class:SmallInteger }"
+     x0 "{ Class:SmallInteger }"
+    |
+
+    menuPanel paint:fg.
+
+    y := layout top + (layout height - rawLabelExtent y // 2).
+
+    aLabel isArray ifFalse:[
+        aLabel isImageOrForm ifFalse:[
+            y := y + menuPanel font ascent
+        ].
+        ^ aLabel displayOn:menuPanel x:x y:y.
+    ].
+
+    aLabel do:[:el|
+        el notNil ifTrue:[
+            el isImageOrForm ifFalse:[
+                y0 := y + menuPanel font ascent
+            ] ifTrue:[
+                y0 := y
+            ].
+            x0 := x + (rawLabelExtent x - (el widthOn:menuPanel) // 2).
+            el displayOn:menuPanel x:x0 y:y0.
+            y := y + 1 + (el heightOn:menuPanel)
+        ] ifFalse:[
+            y := y + 3   "/ see #label:
+        ]
+    ].
+!
+
 drawSeparatingLines
     "draw separating lines
     "
@@ -4779,6 +4809,15 @@
 
 !
 
+invalidate
+
+    (rawLabel notNil and:[menuPanel notNil]) ifTrue:[
+        menuPanel invalidateItem:self repairNow:false
+    ]
+
+
+!
+
 redraw
     "redraw item
     "
@@ -4839,31 +4878,14 @@
 destroy
     "destroy submenus, remove dependencies
     "
-    |channel|
-
     self submenu:nil.
 
-    enableChannel isValueModel ifTrue:[
-        enableChannel removeDependent:self
-    ].
-
-    isVisible isValueModel ifTrue:[
-        isVisible removeDependent:self
-    ].
-
-    channel := self indication.
-    channel isValueModel ifTrue:[
-        channel removeDependent:self
-    ].
-
-    channel := self choice.
-    channel isValueModel ifTrue:[
-        channel removeDependent:self
-    ].
+    enableChannel isValueModel ifTrue:[enableChannel removeDependent:self].
+    isVisible     isValueModel  ifTrue:[isVisible    removeDependent:self].
+    indication    isValueModel ifTrue:[indication    removeDependent:self].
+    choice        isValueModel ifTrue:[choice        removeDependent:self].
 
     menuPanel := nil.
-
-    "Modified: / 14.8.1998 / 14:37:57 / cg"
 !
 
 in:aPanel
@@ -4878,30 +4900,45 @@
 disabledRawLabel
     "returns the label used if the item is disabled
     "
-    disabledRawLabel isNil ifTrue:[
-	(     rawImage notNil
-	 and:[(rawImage respondsTo:#colorMap)
-	 and:[rawImage colorMap notNil]]
-	) ifFalse:[
-	    disabledRawLabel := rawLabel.
-	] ifTrue:[
-	    disabledRawLabel := menuPanel lightenedImageOnDevice:rawImage.
-
-	    rawLabel class == LabelAndIcon ifTrue:[
-		(isButton
-		  or:[((self indication notNil or:[self choice notNil])
-		 and:[label class == LabelAndIcon])]
-		) ifTrue:[
-		    disabledRawLabel := LabelAndIcon form:(rawLabel icon)
-						    image:disabledRawLabel
-						   string:(rawLabel string)
-		] ifFalse:[
-		    disabledRawLabel := LabelAndIcon form:disabledRawLabel
-						    image:(rawLabel image)
-						   string:(rawLabel string)
-		]
-	    ]
-	]
+    |block form image|
+
+    disabledRawLabel notNil ifTrue:[^ disabledRawLabel].
+
+    disabledRawLabel := rawLabel ? ''.
+
+    disabledRawLabel isString ifTrue:[
+        ^ disabledRawLabel
+    ].
+
+    block := [:el| |rslt|
+        (rslt := el) notNil ifTrue:[
+            el isImageOrForm ifTrue:[
+                el colorMap notNil ifTrue:[
+                    rslt := menuPanel lightenedImageOnDevice:el
+                ]
+            ] ifFalse:[
+                el class == LabelAndIcon ifTrue:[
+                    ((form := el icon) notNil and:[form colorMap notNil]) ifTrue:[
+                        form := menuPanel lightenedImageOnDevice:form
+                    ].
+                    ((image := el image) notNil and:[image colorMap notNil]) ifTrue:[
+                        image := menuPanel lightenedImageOnDevice:image
+                    ].
+                    rslt := LabelAndIcon form:form image:image string:(el string).
+                ]
+            ]
+        ].
+        rslt
+    ].
+
+    rawLabel isArray ifTrue:[
+        disabledRawLabel := Array new:(rawLabel size).
+
+        rawLabel keysAndValuesDo:[:anIndex :aLabel|
+            disabledRawLabel at:anIndex put:(block value:aLabel)
+        ]
+    ] ifFalse:[
+        disabledRawLabel := block value:rawLabel
     ].
     ^ disabledRawLabel
 !
@@ -4909,103 +4946,78 @@
 fetchImages
     "fetch images
     "
-    |icon|
-
-    rawImage notNil ifTrue:[
-	rawLabel isImage ifTrue:[
-	    rawLabel := menuPanel imageOnDevice:rawImage
-	] ifFalse:[
-	    rawLabel class == LabelAndIcon ifTrue:[
-		(icon := rawLabel image) notNil ifTrue:[
-		    rawLabel image:(menuPanel imageOnDevice:icon)
-		].
-		(icon := rawLabel icon) notNil ifTrue:[
-		    (self indication isNil and:[self choice isNil]) ifTrue:[
-			rawLabel icon:(menuPanel imageOnDevice:icon)
-		    ]
-		]
-	    ]
-	]
-    ].
-!
-
-updateRawLabel
-    "recreate rawLabel
-    "
-    |char size form|
-
-    label isNil ifTrue:[        "/ not yet initialized
-        ^ self
-    ].
-
-    (form := self indicatorForm) isNil ifTrue:[
-        form := self choiceForm
-    ].
-    rawImage         := nil.
-    disabledRawLabel := nil.
-    rawLabel         := label value.
-
-    rawLabel isString ifTrue:[
-"/        rawLabel isText ifFalse:[
-"/            rawLabel := rawLabel withoutSeparators
-"/        ].        
-"/
-        form isNil ifTrue:[                             "/ check for separator
-            rawLabel isEmpty ifTrue:[
-                  rawLabel := nil.                      "/ indication for separator
-                ^ self
+    |icon block|
+
+    rawLabel notNil ifTrue:[
+        block := [:el| |rslt|
+            (rslt := el) notNil ifTrue:[
+                el isImageOrForm ifTrue:[
+                    rslt := menuPanel imageOnDevice:el
+                ] ifFalse:[
+                    el class == LabelAndIcon ifTrue:[
+                        (icon := el image) notNil ifTrue:[
+                            el image:(menuPanel imageOnDevice:icon)
+                        ].
+
+                        (icon := el icon) notNil ifTrue:[
+                            el icon:(menuPanel imageOnDevice:icon)
+                        ]
+                    ]
+                ]
             ].
-
-            rawLabel size == 1 ifTrue:[
-                char := rawLabel first.
-
-                (char == $- or:[char == $=]) ifTrue:[   "/ other line separators
-                    label    := rawLabel.
-                    rawLabel := nil.                    "/ indication for separator
-                  ^ self
-                ]
-            ]
+            rslt
         ].
-"/        rawLabel isEmpty ifTrue:[
-"/            rawLabel := label value
-"/        ].
-        size := self accessCharacterPosition.
-
-        (size notNil and:[size <= rawLabel size]) ifTrue:[
-            rawLabel isText ifFalse:[
-                rawLabel := Text string:rawLabel
-            ].
-            rawLabel emphasisAt:size add:#underline
+
+        rawLabel isArray ifTrue:[
+            rawLabel keysAndValuesDo:[:anIndex :aLabel|
+                rawLabel at:anIndex put:(block value:aLabel)
+            ]
+        ] ifFalse:[
+            rawLabel := block value:rawLabel
         ]
     ].
-    rawLabel isImage ifTrue:[
-        rawImage := rawLabel.
-
-        form notNil ifTrue:[
-            isButton ifTrue:[form := nil].
-            rawLabel := LabelAndIcon form:form image:rawImage.
-        ]
-    ] ifFalse:[
-        rawLabel class == LabelAndIcon ifTrue:[
-            rawImage := rawLabel icon.
-
-            (form notNil and:[isButton not]) ifTrue:[
-                rawLabel image:rawImage.
-                rawLabel icon:form
-            ]                
-        ] ifFalse:[
-            rawImage := nil.
-            rawLabel isNil ifTrue:[rawLabel := ''].
-
-            (form notNil and:[isButton not]) ifTrue:[
-                rawLabel := LabelAndIcon icon:form string:rawLabel.
-            ] ifFalse:[
-                disabledRawLabel := rawLabel.
-            ]
+!
+
+updateAccessCharacterFor:aLabel
+    |s i rest label pos|
+
+    (accessCharacter notNil or:[aLabel isNil]) ifTrue:[
+        ^ aLabel
+    ].
+
+    aLabel isString ifFalse:[
+        aLabel class == LabelAndIcon ifTrue:[
+            aLabel string:(self updateAccessCharacterFor:(aLabel string))
         ].
-    ].
-    menuPanel shown ifTrue:[ self fetchImages ].
-    menuPanel mustRearrange
+        ^ aLabel
+    ].
+
+    s := aLabel size.
+    i := 1.
+
+    label := aLabel.
+    pos := accessCharacterPosition.
+
+    [((i := label indexOf:$& startingAt:i) ~~ 0 and:[i < s])] whileTrue:[
+        rest := label copyFrom:(i+1).
+
+        i == 1 ifTrue:[label := rest]
+              ifFalse:[label := (label copyFrom:1 to:(i-1)), rest].
+
+        (label at:i) == $& ifTrue:[i := i + 1] ifFalse:[pos := i].
+        s := s - 1.
+    ].
+
+    (pos isNil or:[(accessCharacter := label at:pos ifAbsent:nil) isNil]) ifTrue:[
+        ^ aLabel
+    ].
+
+    label isText ifFalse:[
+        label := Text string:label
+    ].
+    label emphasisAt:pos add:#underline.
+  ^ label
+
 ! !
 
 !MenuPanel::Item methodsFor:'printing & storing'!
@@ -5032,16 +5044,6 @@
     ^menuPanel activeForegroundColor
 !
 
-adornment
-    "returns adornment; if not existing yet a new instance
-     is created
-    "
-    adornment isNil ifTrue:[
-	adornment := Adornment new
-    ].
-  ^ adornment
-!
-
 backgroundColor
     "returns the background color derived from menuPanel
     "
@@ -5089,14 +5091,10 @@
 choiceForm
     "returns choice form or nil
     "
-    |holder|
-
-    (holder := self choice) isNil ifTrue:[^ nil].
-
-    holder value = self choiceValue ifTrue:[
-	^ self class checkOnIcon
-    ].
-    ^ self class checkOffIcon
+    choice isNil ifTrue:[^ nil].
+
+    ^ choice value = choiceValue ifTrue:[menuPanel iconRadioGroupOn]
+                                ifFalse:[menuPanel iconRadioGroupOff]
 !
 
 findSubMenuIn:aRecv
@@ -5105,7 +5103,7 @@
      Ignore the error if that message is not understood
      (but not other message-not-understoods)"
 
-    |subm argument sel|
+    |subm sel|
 
     subm := nil.
 
@@ -5145,7 +5143,7 @@
                 ]
             ]
         ] ifFalse:[
-            (argument := self argument) notNil ifTrue:[
+            argument notNil ifTrue:[
                 sel := submenuChannel asSymbol.
                 Object messageNotUnderstoodSignal handle:[:ex| 
                     ex parameter selector == sel ifFalse:[
@@ -5180,98 +5178,92 @@
 indicationValue
     "returns indication value or nil in case of no indication
     "
-    |indication numArgs sel recv|
-
-    (indication := self indication) isNil ifTrue:[
-        ^ nil                                           "/ has no indication
-    ].
-
-    indication isSymbol ifTrue:[
-        (numArgs := indication numArgs) ~~ 0 ifTrue:[
-            numArgs == 2 ifTrue:[
-                recv := menuPanel receiver.
-
-                (recv isValueModel) ifFalse:[
-                    (recv notNil or:[(recv := menuPanel application) notNil]) ifTrue:[
-                        sel := indication copyFrom:1 to:(indication indexOf:$:).
-                        indication := nil.
-                        sel := sel asSymbol.
-
-                        Object messageNotUnderstoodSignal handle:[:ex| 
-                            ex parameter selector == sel ifFalse:[
-                                ex reject
-                            ].
-                        ] do:[
-                            indication := recv perform:sel with:self argument
-                        ]
+    |numArgs sel recv|
+
+    indication isNil ifTrue:[^ nil].                                    "no indication specified"
+
+    indication isSymbol ifFalse:[                                       
+        ^ indication value == true                                      "block or model"
+    ].
+
+    (numArgs := indication numArgs) == 2 ifTrue:[
+        recv := menuPanel receiver.
+
+        (recv isValueModel) ifFalse:[
+            (recv notNil or:[(recv := menuPanel application) notNil]) ifTrue:[
+                sel := indication copyFrom:1 to:(indication indexOf:$:).
+                sel := sel asSymbol.
+
+                Object messageNotUnderstoodSignal handle:[:ex| 
+                    ex parameter selector == sel ifFalse:[
+                        ex reject
                     ].
-                ].
-                ^ indication value == true
+                ] do:[
+                    sel := recv perform:sel with:argument
+                ]
             ].
-            indication := (indication copyWithoutLast:1) asSymbol
         ].
-        indication := self aspectAt:indication.
-
-        indication isValueModel ifTrue:[
-            self adornment indication:indication.
-            indication addDependent:self.
-        ]
-    ].
-    ^ indication value == true
-
-    "Modified: / 8.8.1998 / 02:15:15 / cg"
+        ^ sel value == true
+    ].
+
+    numArgs ~~ 0 ifTrue:[
+        sel := (indication copyWithoutLast:1) asSymbol
+    ] ifFalse:[
+        sel := indication
+    ].    
+    sel := self aspectAt:sel.
+
+    sel isValueModel ifTrue:[
+        indication := sel.
+        indication addDependent:self.
+    ].
+    ^ sel value == true
 !
 
 indicationValue:aValue
     "set the indication value
     "
-    |numArgs indication recv|
-
-    (indication := self indication) isNil ifTrue:[
-	^ self                                          "/ has no indication
-    ].
-
-    indication isSymbol ifFalse:[
-	(indication respondsTo:#value:) ifTrue:[        "/ valueHolder or block
-	    indication value:aValue
-	].
-	^ self
+    |numArgs recv|
+
+    indication isNil ifTrue:[^ self].                                   "no indication specified"
+
+    indication isSymbol ifFalse:[                                       
+        indication perform:#value: with:aValue ifNotUnderstood:nil.     "block or model"
+      ^ self
+    ].
+
+    (numArgs := indication numArgs) == 0 ifTrue:[                       "no arguments to selector; cannot set"
+        ^ self
     ].
 
     recv := menuPanel receiver.
+    recv isValueModel ifTrue:[^ self].
+
     recv isNil ifTrue:[
-	recv := menuPanel application.
-	recv isNil ifTrue:[^ self].
-    ].
-
-    (numArgs := indication numArgs) ~~ 0 ifTrue:[
-	Object messageNotUnderstoodSignal handle:[:ex| 
-	    (ex parameter selector ~~ indication) ifTrue:[
-		ex reject
-	    ]
-	] do:[
-	    numArgs == 1 ifTrue:[
-		recv perform:indication with:aValue
-	    ] ifFalse:[
-		recv perform:indication with:(self argument ? self) with:aValue
-	    ]
-	]
-    ].
-
-    "Modified: / 28.7.1998 / 20:47:08 / cg"
+        recv := menuPanel application.
+        recv isNil ifTrue:[^ self].
+    ].
+
+    Object messageNotUnderstoodSignal handle:[:ex| 
+        (ex parameter selector ~~ indication) ifTrue:[
+            ex reject
+        ]
+    ] do:[
+        numArgs == 1 ifTrue:[
+            recv perform:indication with:aValue
+        ] ifFalse:[
+            recv perform:indication with:(argument ? self) with:aValue
+        ]
+    ].
 !
 
 indicatorForm
     "returns indication form or nil
     "
-    |value|
-
-    (value := self indicationValue) isNil ifTrue:[
-	^ nil
-    ].
-  ^ value ifTrue:[IndicatorOn] ifFalse:[IndicatorOff]
-
-    "Created: / 14.8.1998 / 15:53:53 / cg"
+    indication isNil ifTrue:[^ nil].
+
+  ^ self indicationValue == true ifTrue:[menuPanel iconIndicationOn]
+                                ifFalse:[menuPanel iconIndicationOff]
 !
 
 isEntered
@@ -5360,10 +5352,8 @@
     "returns true if item is selectable; no separator, visible and enabled.
      in case of a choice (RadioButton) i have to check for the choiceValue
     "
-    |holder|
-
     (rawLabel notNil and:[self isVisible and:[self enabled]]) ifTrue:[
-        ((holder := self choice) isNil or:[holder value ~= self choiceValue]) ifTrue:[
+        (choice isNil or:[choice value ~= choiceValue]) ifTrue:[
             ^ true
         ].
     ].
@@ -5382,7 +5372,7 @@
 hasIndication
     "returns true if on/off indication exists
     "
-  ^ self indication notNil
+    ^ indication notNil
 !
 
 hasSubmenu
@@ -5530,13 +5520,17 @@
     "change selection to a state. Dependant on the state open or hide an existing
      submenu and perform a redraw
     "
+    menuPanel isNil ifTrue:[
+        ^ self hideSubmenu
+    ].
+
     isSelected ifFalse:[
+        self invalidate.
         self hideSubmenu.
-        menuPanel invalidateItem:self repairNow:true.
     ] ifTrue:[
         menuPanel realized ifTrue:[
-            (self indication isNil or:[isButton not]) ifTrue:[
-                menuPanel invalidateItem:self repairNow:true.
+            (indication isNil or:[isButton not]) ifTrue:[
+                self invalidate
             ].
 
             (subMenu := self setupSubmenu) notNil ifTrue:[
@@ -5546,109 +5540,9 @@
     ].
 ! !
 
-!MenuPanel::Item::Adornment methodsFor:'accessing'!
-
-accessCharacterPosition
-    "get the index of the access character in the label text or string, or nil if none
-    "
-    ^ accessCharacterPosition
-!
-
-accessCharacterPosition:anIndexOrNil
-    "set the index of the access character in the label text or string, or nil if none
-    "
-    accessCharacterPosition := anIndexOrNil
-!
-
-argument
-    "ST/X goody; get argunment to a selector or block
-    "
-  ^ argument
-!
-
-argument:anArgumentOrNil
-    "ST/X goody; set argunment to a selector or block
-    "
-    argument := anArgumentOrNil
-!
-
-choice
-    "get has choice indicator value
-    "
-  ^ choice
-
-    "Created: / 14.8.1998 / 14:41:31 / cg"
-!
-
-choice:something
-    "set choice indicator value
-    "
-    choice := something.
-
-    "Created: / 14.8.1998 / 14:41:39 / cg"
-!
-
-choiceValue
-    "return the value of the instance variable 'choiceValue' (automatically generated)"
-
-    ^ choiceValue
-
-    "Created: / 14.8.1998 / 15:47:52 / cg"
-!
-
-choiceValue:something
-    "set the value of the instance variable 'choiceValue' (automatically generated)"
-
-    choiceValue := something.
-
-    "Created: / 14.8.1998 / 15:47:52 / cg"
-!
-
-indication
-    "get has on/off indicator value
-    "
-  ^ indication
-!
-
-indication:something
-    "set has on/off indicator value
-    "
-    indication := something.
-!
-
-shortcutKey
-    "get the character that is used as a shortcut key for this item
-    "
-  ^ shortcutKey
-!
-
-shortcutKey:aKeyOrNil
-    "set the character that is used as a shortcut key for this item
-    "
-    shortcutKey := aKeyOrNil
-!
-
-showBusyCursorWhilePerforming
-    "get the flag which controls if a busy cursor is to be shown
-     while performing the menu action. Defaults to false."
-
-    ^ showBusyCursorWhilePerforming ? false
-
-
-!
-
-showBusyCursorWhilePerforming:aBoolean
-    "set/clear the flag which controls if a busy cursor is to be shown
-     while performing the menu action. Defaults to false."
-
-    showBusyCursorWhilePerforming := aBoolean
-
-
-! !
-
 !MenuPanel class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libwidg2/MenuPanel.st,v 1.209 2000-02-24 07:47:47 ca Exp $'
+    ^ '$Header: /cvs/stx/stx/libwidg2/MenuPanel.st,v 1.210 2000-02-25 16:58:56 ca Exp $'
 ! !
 MenuPanel initialize!