diff mde/gui/WMScreen.d @ 131:9cff74f68b84

Major revisions to popup handling. Buttons can close menus now, plus some smaller impovements. Removed Widget module. Moved Widget.AWidget to AChildWidget.AChildWidget and Widget.AParentWidget to AParentWidget.AParentWidget. Removed ASingleParentWidget to improve code sharing. AChildWidget doesn't implement IParentWidget like AWidget did. New IPopupParentWidget extending IParentWidget for the WM and some widgets to handle popups. Cut old popup management code. New underMouse() function replacing highlight(); called on all widgets. Separate menu-popup and button widgets aren't needed for menus now. Functions returning content widgets have been moved to their own module. Cleaned up jobs.txt. Switched to 80 line length for Ddoc.
author Diggory Hardy <diggory.hardy@gmail.com>
date Wed, 21 Jan 2009 13:01:40 +0000
parents 41582439a42b
children 264028f4115a
line wrap: on
line diff
--- a/mde/gui/WMScreen.d	Sat Jan 17 16:11:26 2009 +0000
+++ b/mde/gui/WMScreen.d	Wed Jan 21 13:01:40 2009 +0000
@@ -13,12 +13,12 @@
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>. */
 
-/*************************************************************************************************
+/******************************************************************************
  * A gui manager class using mde.setup.Screen and mde.input.Input.
  *
- * This is the module to use externally to create a graphical user interface (likely also with
- * content modules).
- *************************************************************************************************/
+ * This is the module to use externally to create a graphical user interface
+ * (likely also with content modules).
+ *****************************************************************************/
 module mde.gui.WMScreen;
 
 import mde.gui.WidgetManager;
@@ -34,17 +34,19 @@
     logger = Log.getLogger ("mde.gui.WMScreen");
 }
 
-/*************************************************************************************************
+/******************************************************************************
  * The widget manager.
  * 
- * This provides a layer on top of WidgetLoader, handling input and rendering. Other functionality
- * is contained in the super class, to simplify supporting new input/graphics libraries.
+ * This provides a layer on top of WidgetLoader, handling input and rendering.
+ * Other functionality is contained in the super class, to simplify supporting
+ * new input/graphics libraries.
  * 
- * Currently mouse coordinates are passed to widgets untranslated. It may make sense to translate
- * them and possibly drop events for some uses, such as if the gui is drawn to a texture.
+ * Currently mouse coordinates are passed to widgets untranslated. It may make
+ * sense to translate them and possibly drop events for some uses, such as if
+ * the gui is drawn to a texture.
  * 
- * Aside from the IWidgetManager methods, this class should be thread-safe.
- *************************************************************************************************/
+ * Public non IWidget* methods should be thread-safe.
+ *****************************************************************************/
 scope class WMScreen : AWidgetManager, Screen.IDrawable {
     /** Construct a new widget manager.
      * 
@@ -68,8 +70,8 @@
         synchronized(mutex) {
             if (child)
                 child.draw;
-	    foreach (popup; popups)
-		popup.widget.draw();
+	    if (childIPPW)
+                childIPPW.drawPopup;
 	}
     }
     
@@ -85,54 +87,25 @@
         
         wdabs cx = cast(wdabs) usx, cy = cast(wdabs) usy;
         
-        // 1. Callbacks have the highest priority recieving events (e.g. a button release)
+        // Callbacks have the highest priority receiving events (e.g. a button release)
         foreach (dg; clickCallbacks)
             if (dg (cx, cy, b, state)) return;
         
-        // 2. Then pop-ups: close from top, depending on click pos
-        // Note: assumes each evaluated popup's parent is not under another still open popup.
-        // Also assumes popup's parent doesn't have other children in its box.
-        size_t removeTo = popups.length;
-        bool eventDone;		// don't pass clickEvent
-        IChildWidget widg;	// widget clicked on
-        foreach_reverse (i,popup; popups) with (popup) {
-            if (cx < x || cx >= x + w ||
-                cy < y || cy >= y + h) {	// on popup
-                if (parent.onSelf (cx, cy)) {
-                    if (parent.popupParentClick()) removeTo = i;
-                    eventDone = true;
-                    break;
-                } else {
-                    removeTo = i;
-                    parent.popupClose;
-                }
-            } else {
-                widg = widget.getWidget (cast(wdabs)cx,cast(wdabs)cy);
-                break;
-            }
-        }
-        if (removeTo < popups.length) {
-            requestRedraw;
-            popups = popups[0..removeTo];
-        }
-        if (eventDone)
-            return;
+        // Update underMouse to get the widget clicked on
+        updateUnderMouse (cx, cy, state);
         
-        // 3. Then the main widget tree
-        debug assert (cx < child.width && cy < child.height, "WidgetManager: child doesn't cover whole area (code error)");
-        if (widg is null)
-            widg = child.getWidget (cast(wdabs)cx,cast(wdabs)cy);
-	if (keyFocus && keyFocus !is widg) {
+        // Disable keyboard input if on another widget:
+	if (keyFocus && keyFocus !is underMouse) {
 	    keyFocus.keyFocusLost;
 	    keyFocus = null;
 	    imde.input.setLetterCallback (null);
 	}
-        if (widg !is null) {
-	    if (widg.clickEvent (cast(wdabs)cx,cast(wdabs)cy,b,state) & 1) {
-		keyFocus = widg;
-		imde.input.setLetterCallback (&widg.keyEvent);
-	    }
-	}
+        // Finally, post the actual event:
+        if (underMouse.clickEvent (cast(wdabs)cx,cast(wdabs)cy,b,state) & 1) {
+            // keyboard input requested
+            keyFocus = underMouse;
+            imde.input.setLetterCallback (&underMouse.keyEvent);
+        }
     }
     
     /** For mouse motion events.
@@ -146,23 +119,8 @@
 	wdabs cx = cast(wdabs) scx, cy = cast(wdabs) scy;
         foreach (dg; motionCallbacks)
             dg (cx, cy);
-	
-	IChildWidget ohighlighted = highlighted;
-	foreach_reverse (popup; popups) with (popup) {
-	    if (cx >= x && cx < x+w && cy >= y && cy < y+h) {
-		highlighted = widget.getWidget (cx,cy);
-		goto foundPopup;
-	    }
-	}
-	highlighted = null;	// not over a popup
-	foundPopup:
-	if (ohighlighted != highlighted) {
-	    if (ohighlighted)
-		ohighlighted.highlight (false);
-	    if (highlighted)
-		highlighted.highlight (true);
-	    requestRedraw;
-	}
+        
+        updateUnderMouse (cx, cy, false);
     }
     
     
@@ -195,7 +153,6 @@
         // The renderer needs to be created on the first load, but not after this.
         if (rend is null)
             rend = createRenderer (rendName);
-	popups = null;
         
         debug (mdeWidgets) logger.trace ("Creating root widget...");
         child = makeWidget (this, "root");