PullDMenu.st
changeset 38 4b9b70b2cc87
parent 21 9ef599238fea
child 59 450ce95a72a4
--- a/PullDMenu.st	Sun Aug 07 15:22:53 1994 +0200
+++ b/PullDMenu.st	Sun Aug 07 15:23:42 1994 +0200
@@ -14,43 +14,63 @@
        instanceVariableNames:'menus titles activeMenuNumber
                               showSeparatingLines topMargin
                               fgColor bgColor activeFgColor activeBgColor
-                              onLevel offLevel'
+                              onLevel offLevel
+                              keepMenu'
        classVariableNames:''
        poolDictionaries:''
        category:'Views-Menus'
 !
 
 PullDownMenu comment:'
-
 COPYRIGHT (c) 1989 by Claus Gittinger
              All Rights Reserved
 
-$Header: /cvs/stx/stx/libwidg/Attic/PullDMenu.st,v 1.4 1994-01-08 17:27:45 claus Exp $
-
-written summer 89 by claus
+$Header: /cvs/stx/stx/libwidg/Attic/PullDMenu.st,v 1.5 1994-08-07 13:23:11 claus Exp $
 '!
 
 !PullDownMenu class methodsFor:'documentation'!
 
+copyright
+"
+ COPYRIGHT (c) 1989 by Claus Gittinger
+              All Rights Reserved
+
+ This software is furnished under a license and may be used
+ only in accordance with the terms of that license and with the
+ inclusion of the above copyright notice.   This software may not
+ be provided or otherwise made available to, or used by, any
+ other person.  No title to or ownership of the software is
+ hereby transferred.
+"
+!
+
+version
+"
+$Header: /cvs/stx/stx/libwidg/Attic/PullDMenu.st,v 1.5 1994-08-07 13:23:11 claus Exp $
+"
+!
+
 documentation
 "
-PullDown menu provides the top (always visible) part of these menus. It controls
-display of its menus, which become visible when one of the PullDownMenus entries 
-is pressed.
+    PullDown menu provides the top (always visible) part of these menus. 
+    It controls display of its menus, which become visible when one of the 
+    PullDownMenus entries is pressed.
 
-Instance variables:
+    Instance variables:
 
-menus                   <aCollection>   the sub menus
-titles                  <aCollection>   the strings in the menu
-activeMenuNumber        <Number>        the index of the currently active menu
-showSeparatingLines     <Boolean>       show separating lines between my menu-strings
-topMargin               <Number>        number of pixels at top
-fgColor                 <Color>         color to draw passive menu-titles
-bgColor                 <Color>         color to draw passive menu-titles
-activeFgColor           <Color>         color to draw activated menu-titles
-activeBgColor           <Color>         color to draw activated menu-titles
-onLevel                 <Integer>       level of entry-buttons when pressed
-offLevel                <Integer>       level of entry-buttons when released
+    menus                   <aCollection>   the sub menus
+    titles                  <aCollection>   the strings in the menu
+    activeMenuNumber        <Number>        the index of the currently active menu
+    showSeparatingLines     <Boolean>       show separating lines between my menu-strings
+    topMargin               <Number>        number of pixels at top
+    fgColor                 <Color>         color to draw passive menu-titles
+    bgColor                 <Color>         color to draw passive menu-titles
+    activeFgColor           <Color>         color to draw activated menu-titles
+    activeBgColor           <Color>         color to draw activated menu-titles
+    onLevel                 <Integer>       level of entry-buttons when pressed
+    offLevel                <Integer>       level of entry-buttons when released
+    keepmenu                <Boolean>       if on, pulled menu stays on click,
+                                            till clicked again (motif & windows behavior)
 "
 ! !
 
@@ -94,7 +114,7 @@
         ].
         topMargin := 2.
 
-        style == #iris ifTrue:[
+        ((style == #iris) or:[style == #motif]) ifTrue:[
             self level:2.
             softEdge := true.
             onLevel := 2.
@@ -106,6 +126,7 @@
         activeBgColor := fgColor.
         topMargin := 0
     ].
+    keepMenu := (style == #motif) or:[(style == #iris) or:[style == #mswindows]].
 !
 
 initEvents
@@ -329,20 +350,25 @@
     ]
 !
 
-hideActiveMenu
+hideActiveMenuRelease:aBoolean
     activeMenuNumber notNil ifTrue:[
         (menus at:activeMenuNumber) unrealize.
         self unHighlightActiveTitle.
+        aBoolean ifTrue:[device ungrabPointer. self cursor:Cursor normal].
         activeMenuNumber := nil
     ]
 !
 
+hideActiveMenu
+    ^ self hideActiveMenuRelease:true
+!
+
 pullMenu:aNumber
     "activate a menu"
 
     |subMenu|
 
-    activeMenuNumber notNil ifTrue:[self hideActiveMenu].
+    activeMenuNumber notNil ifTrue:[self hideActiveMenuRelease:false].
     subMenu := menus at:aNumber.
     subMenu notNil ifTrue:[
         activeMenuNumber := aNumber.
@@ -413,11 +439,43 @@
 !
 
 buttonPress:button x:x y:y
-    |titleIndex|
+    |titleIndex activeMenu activeLeft activeTop|
+
+    (y between:0 and:height) ifTrue:[
+        titleIndex := self titleIndexForX:x.
+    ].
 
-    titleIndex := self titleIndexForX:x.
-    titleIndex notNil ifTrue:[
-        self pullMenu:titleIndex
+    "
+     now, titleIndex is non-nil if pressed within myself
+    "
+    (titleIndex notNil and:[titleIndex ~~ activeMenuNumber]) ifTrue:[
+        self pullMenu:titleIndex.
+        keepMenu ifTrue:[
+            device grabPointerIn:self id.
+            self cursor:Cursor upRightArrow
+        ]
+    ] ifFalse:[
+        keepMenu ifTrue:[
+            titleIndex == activeMenuNumber ifTrue:[
+                "same pressed again ... stay"
+                ^ self
+            ].
+            "moving around below"
+            activeMenuNumber isNil ifTrue:[^self].
+            activeMenu := menus at:activeMenuNumber.
+            activeLeft := activeMenu left.
+            (x between:activeLeft and:(activeMenu right)) ifTrue:[
+                activeTop := activeMenu top.
+                (y between:activeTop and:(activeMenu bottom)) ifTrue:[
+                    "moving around in menu"
+                    activeMenu buttonPress:button
+                                         x:(x - activeLeft)
+                                         y:(y - activeTop).
+                    ^ self
+                ]
+            ].
+        ].
+        self hideActiveMenu
     ]
 !
 
@@ -432,7 +490,6 @@
         titleIndex := self titleIndexForX:x.
         titleIndex notNil ifTrue:[
             (titleIndex ~~ activeMenuNumber) ifTrue:[
-                self hideActiveMenu.
                 self pullMenu:titleIndex
             ]
         ]
@@ -457,24 +514,39 @@
 !
 
 buttonRelease:button x:x y:y
-    |activeMenu activeLeft activeTop|
+    |activeMenu activeLeft activeTop hideMenu|
 
+    hideMenu := false.
     (y >= height) ifTrue:[
         "release below title-line"
         activeMenuNumber isNil ifTrue:[^self].
         activeMenu := menus at:activeMenuNumber.
         activeLeft := activeMenu left.
+        "
+         released in a submenu ?
+        "
         (x between:activeLeft and:(activeMenu right)) ifTrue:[
             activeTop := activeMenu top.
             (y between:activeTop and:(activeMenu bottom)) ifTrue:[
                 "release in menu"
-                self hideActiveMenu.
+                self hideActiveMenu.   
                 activeMenu buttonRelease:button
                                        x:(x - activeLeft)
                                        y:(y - activeTop).
                 ^ self
             ]
+        ].
+        hideMenu := true.
+    ] ifFalse:[
+        y < 0 ifTrue:[
+            hideMenu := true
+        ] ifFalse:[
+            keepMenu ifFalse:[   
+                hideMenu := true
+            ]
         ]
-    ].
-    self hideActiveMenu
+    ].                  
+    hideMenu ifTrue:[
+       self hideActiveMenu.
+    ]
 ! !