diff mde/gui/WidgetManager.d @ 160:ccd01fde535e

Replaced WidgetManager's click and motion callbacks with a drag event system. This is less flexible, but much closer to what is required (and is simpler and less open to bugs through unintended use).
author Diggory Hardy <diggory.hardy@gmail.com>
date Thu, 21 May 2009 22:15:32 +0200
parents b06b04c75e86
children 2476790223b8
line wrap: on
line diff
--- a/mde/gui/WidgetManager.d	Thu May 21 20:55:10 2009 +0200
+++ b/mde/gui/WidgetManager.d	Thu May 21 22:15:32 2009 +0200
@@ -69,9 +69,6 @@
      * Params:
      *	name = The file name of the config for this GUI (to identify multiple GUIs). */
     protected this (char[] name) {
-        clickCallbacks = new typeof(clickCallbacks);
-        motionCallbacks = new typeof(motionCallbacks);
-        
         auto p = "MiscOptions.l10n" in Content.allContent;
         assert (p, "MiscOptions.l10n not created!");
         p.addCallback (&reloadStrings);
@@ -268,17 +265,6 @@
     void requestRedraw () {
         imde.mainSchedule.request(imde.SCHEDULE.DRAW);
     }
-    
-    void addClickCallback (bool delegate(wdabs, wdabs, ubyte, bool) dg) {
-        clickCallbacks[dg.ptr] = dg;
-    }
-    void addMotionCallback (void delegate(wdabs, wdabs) dg) {
-        motionCallbacks[dg.ptr] = dg;
-    }
-    void removeCallbacks (void* frame) {
-        clickCallbacks.removeKey(frame);
-        motionCallbacks.removeKey(frame);
-    }
     //END IWidgetManager methods
     
     debug void logWidgetSize (Content) {
@@ -304,12 +290,17 @@
     void wmMouseClick (wdabs cx, wdabs cy, ubyte b, bool state) {
 	if (child is null) return;
 	
-	// Callbacks have the highest priority receiving events (e.g. a button release)
-	foreach (dg; clickCallbacks)
-	    if (dg (cx, cy, b, state)) return;
-	    
-	    // Update underMouse to get the widget clicked on
-	    updateUnderMouse (cx, cy, state);
+	// Update underMouse to get the widget clicked on
+	updateUnderMouse (cx, cy, state);
+	
+	// end of a drag?
+	if (dragStart !is null && b == 1 && state == false) {
+	    if (dragStart.dragRelease (cx, cy, underMouse)) {
+		dragStart = null;
+		return;
+	    }
+	    dragStart = null;
+	}
 	
 	// Disable keyboard input if on another widget:
 	if (keyFocus && keyFocus !is underMouse) {
@@ -327,22 +318,25 @@
 	    popupContext.setup (0, 3);
 	    positionPopup (underMouse, popupContext);
 	    requestRedraw;
-	} else	// post other button presses to clickEvent
-	    if (underMouse.clickEvent (cast(wdabs)cx,cast(wdabs)cy,b,state) & 1) {
-		// keyboard input requested
+	} else {	// post other button presses to clickEvent
+	    int ret = underMouse.clickEvent (cast(wdabs)cx,cast(wdabs)cy,b,state);
+	    if (ret & 1) {	// keyboard input requested
 		keyFocus = underMouse;
 		setLetterCallback (&underMouse.keyEvent);
 	    }
+	    if (ret & 2)	// drag events requested
+		dragStart = underMouse;
+	}
     }
     
     /** For mouse motion events.
      *
      * Lock on mutex before calling. Pass new mouse coordinates. */
     void wmMouseMotion (wdabs cx, wdabs cy) {
-	foreach (dg; motionCallbacks)
-	    dg (cx, cy);
+	updateUnderMouse (cx, cy, false);
 	
-	updateUnderMouse (cx, cy, false);
+	if (dragStart !is null)
+	    dragStart.dragMotion (cx, cy, underMouse);
     }
     
     
@@ -504,11 +498,9 @@
     // Popup(s) handled directly by AWidgetManager:
     IChildWidget popupContext;		// context menu (active if not null)
     
-    // callbacks indexed by their frame pointers. Must support removal of elements in foreach:
-    SortedMap!(void*,bool delegate(wdabs cx, wdabs cy, ubyte b, bool state)) clickCallbacks;
-    SortedMap!(void*,void delegate(wdabs cx, wdabs cy)) motionCallbacks;
-    IChildWidget keyFocus;	// widget receiving keyboard input
-    IChildWidget underMouse;	// widget under the mouse pointer
+    IChildWidget dragStart;		// if non-null, this widget should receive motion and click-release events
+    IChildWidget keyFocus;		// widget receiving keyboard input
+    IChildWidget underMouse;		// widget under the mouse pointer
     
     Mutex mutex;			// lock on methods for use outside the package.
 }