ExtendedComboBox.st
changeset 3134 d0a3d82a5bcd
parent 2904 b0b7eb41d6fa
child 3235 e38e4be1602e
--- a/ExtendedComboBox.st	Tue Nov 07 11:10:04 2006 +0100
+++ b/ExtendedComboBox.st	Tue Nov 07 12:53:23 2006 +0100
@@ -9,27 +9,25 @@
  other person.  No title to or ownership of the software is
  hereby transferred.
 "
-
-
-
 "{ Package: 'stx:libwidg2' }"
 
 View subclass:#ExtendedComboBox
-        instanceVariableNames:'menuButton menuField menuWrapper adjust menuWidgetHolder
-                menuWidget menuHeight openAction isReadOnly closeOnSelect
-                usePreferredWidthForMenu hasHorizontalScrollBar
-                hasVerticalScrollBar miniScrollerHorizontal miniScrollerVertical
-                autoHideScrollBars'
-        classVariableNames:''
-        poolDictionaries:''
-        category:'Views-Interactors'
+	instanceVariableNames:'menuButton menuField menuWrapper adjust menuWidgetHolder
+		menuWidget menuHeight openAction isReadOnly closeOnSelect
+		menuExtent usePreferredWidthForMenu hasHorizontalScrollBar
+		hasVerticalScrollBar miniScrollerHorizontal miniScrollerVertical
+		autoHideScrollBars'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Views-Interactors'
 !
 
 PopUpView subclass:#MenuWrapper
-        instanceVariableNames:'comboBox widget lastPointerView implicitGrabView'
-        classVariableNames:''
-        poolDictionaries:''
-        privateIn:ExtendedComboBox
+	instanceVariableNames:'comboBox widget lastPointerView implicitGrabView eventHandler
+		resizeCursor restoreCursor'
+	classVariableNames:''
+	poolDictionaries:''
+	privateIn:ExtendedComboBox
 !
 
 !ExtendedComboBox class methodsFor:'documentation'!
@@ -400,6 +398,21 @@
     model value:aValue.
 !
 
+menuExtent
+    ^ menuExtent
+!
+
+menuExtent:anExtent
+    menuExtent := anExtent.
+
+    anExtent notNil ifTrue:[
+        menuHeight := nil.
+    ] ifFalse:[
+        menuHeight := anExtent y max:50.
+    ].
+    usePreferredWidthForMenu := true.
+!
+
 menuWidget
     "get the menu widget or nil"
 
@@ -1003,7 +1016,7 @@
 openMenu
     "pull the menu - triggered from the button"
 
-    |h w menuOrigin widgetPrfExt useableExt|
+    |h w menuOrigin useableExt widgetPrfExt|
 
     openAction notNil ifTrue:[
         openAction valueWithOptionalArgument:menuWidget
@@ -1017,8 +1030,12 @@
 
     menuOrigin   := device translatePoint:(0@height) fromView:self toView:nil.
     useableExt   := device usableExtent.
-    widgetPrfExt := menuWrapper preferredExtent.
 
+    menuExtent notNil ifTrue:[
+        widgetPrfExt := menuExtent.
+    ] ifFalse:[
+        widgetPrfExt := menuWrapper preferredExtent.
+    ].
     menuHeight isNil ifTrue:[
         menuHeight := (5 + widgetPrfExt y) min:(useableExt y // 2).
     ].
@@ -1034,7 +1051,6 @@
             ]
         ]
     ].
-
     "/ nice side-effect; set width first, to allow menuHeight
     "/ to be a block computing the height based upon the width.
     "/ (allows for geometry adjustments)
@@ -1063,6 +1079,10 @@
     focus control and implicit grab on buttonPress.
 
     [instance variables:]
+        comboBox                <ExtendedComboBox>
+
+        widget                  <View>          the widget which contains the menu
+
         lastPointerView         <View>          view which contained the
                                                 mouse pointer.
                                                 used for enter/leave event generation.
@@ -1072,6 +1092,12 @@
                                                 If non-nil, all events are forwarded to this
                                                 one (for example to scroll with mouse outside the scrollbar)
 
+        eventHandler            <OneArgBlock>   if not nil, the block will
+                                                handle all inputEvents
+
+        resizeCursor            <Cursor>        shown for resize handle
+
+        restoreCursor           <Cursor>        default cursor
 "
 ! !
 
@@ -1109,12 +1135,25 @@
 
     |x y oldGrabber p|
 
+    eventHandler notNil ifTrue:[
+        (eventHandler value:event) ifTrue:[^ self].
+    ].
+
     (event isInputEvent not
     or:[event isPointerEnterLeaveEvent]) ifTrue:[
         super dispatchEvent:event withFocusOn:focusViewOrNil delegate:doDelegate.
         ^ self
     ].
 
+    event isButtonMotionEvent ifTrue:[
+        implicitGrabView isNil ifTrue:[
+            (self isEventAssignedToResizeArea:event) ifTrue:[
+                self setupResizeEventHandler.
+                ^ self.
+            ].
+        ].
+    ].
+
     event isButtonPressEvent ifTrue:[
         x := event x.
         y := event y.
@@ -1154,8 +1193,7 @@
     "/ but never get the buttonRelease, since someone else (a popUp) grabbed the
     "/ pointer in the meantime, and has eaten the release event ... (double-sigh)
     implicitGrabView notNil ifTrue:[
-        self sensor leftButtonPressed ifFalse:[
-"/            Transcript showCR:'clear'.
+        (ev isButtonReleaseEvent or:[self sensor leftButtonPressed]) ifFalse:[
             implicitGrabView := nil.
         ].
     ].
@@ -1217,6 +1255,44 @@
     view dispatchEvent:ev withFocusOn:focusView delegate:false.
 
     "Modified: / 10.10.2001 / 13:54:20 / cg"
+!
+
+setupResizeEventHandler
+    |clickExtent clickPoint|
+
+
+    self windowGroup showCursor:resizeCursor.
+
+    eventHandler := [:ev|
+        ev isButtonEvent ifTrue:[
+            clickPoint notNil ifTrue:[
+                ev isButtonMotionEvent ifTrue:[ |offset extent|
+                    offset := self sensor mousePoint - clickPoint.
+                    extent := (clickExtent + offset) max:(comboBox width)@50.
+                    self extent:extent.
+                ] ifFalse:[
+                    ev isButtonReleaseEvent ifTrue:[
+                        comboBox menuExtent:self extent.
+                    ].
+                    clickPoint := clickExtent := nil.
+                ].
+            ].
+
+            clickPoint isNil ifTrue:[
+                ev isButtonMotionEvent ifTrue:[
+                    (self isEventAssignedToResizeArea:ev) ifFalse:[
+                        self windowGroup showCursor:restoreCursor.
+                        clickPoint := clickExtent := eventHandler := nil.
+                    ].
+                ].
+                ev isButtonPressEvent ifTrue:[  "/ start resize
+                    clickPoint  := self sensor mousePoint.
+                    clickExtent := self extent.
+                ].
+            ].
+        ].
+        ev isInputEvent
+    ].
 ! !
 
 !ExtendedComboBox::MenuWrapper methodsFor:'focus handling'!
@@ -1266,14 +1342,15 @@
     "hide request from windowGroup (i.e. via Escape key).
      Can be redefined in subclasses which dont like this"
 
-    comboBox closeMenu
-
+    eventHandler := nil.
+    comboBox closeMenu.
 !
 
 initialize
     super initialize.
     super level:0.
     super borderWidth:1.
+    self enableMotionEvents.
 !
 
 level:aNumber
@@ -1282,6 +1359,12 @@
 mapped
     "grab resources (mouse and keyboard)
     "
+    eventHandler := nil.
+
+    resizeCursor isNil ifTrue:[
+        restoreCursor := self cursor.
+        resizeCursor  := Cursor fourWay onDevice:device.
+    ].
     super mapped.
     self assignInitialKeyboardFocus.
     widget notNil ifTrue:[widget level:0].
@@ -1289,6 +1372,25 @@
 
 !ExtendedComboBox::MenuWrapper methodsFor:'queries'!
 
+isEventAssignedToResizeArea:ev
+    |x y|
+
+    ((x := ev x) notNil and:[(y := ev y) notNil]) ifTrue:[ |evView|
+        evView := ev view.
+        
+        evView ~~ self ifTrue:[ |p|
+            p := device translatePoint:(x@y) fromView:evView toView:self.
+            x := p x.
+            y := p y.
+        ].
+
+        (x - width)  abs <= 5 ifTrue:[
+            (y - height) abs <= 5 ifTrue:[^ true].
+        ].
+    ].
+    ^ false
+!
+
 raiseDeiconified
     ^ self raise
 
@@ -1345,5 +1447,5 @@
 !ExtendedComboBox class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libwidg2/ExtendedComboBox.st,v 1.48 2006-01-31 22:45:49 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libwidg2/ExtendedComboBox.st,v 1.49 2006-11-07 11:53:23 ca Exp $'
 ! !