diff mde/gui/widget/Window.d @ 41:b3a6ca4516b4

The renderer now controls which parts of the window border allow resizing. committer: Diggory Hardy <diggory.hardy@gmail.com>
author Diggory Hardy <diggory.hardy@gmail.com>
date Tue, 13 May 2008 12:02:36 +0100
parents b28d7adc786b
children 0fd51d2c6c8a
line wrap: on
line diff
--- a/mde/gui/widget/Window.d	Thu May 08 16:05:51 2008 +0100
+++ b/mde/gui/widget/Window.d	Tue May 13 12:02:36 2008 +0100
@@ -22,6 +22,7 @@
 
 import mde.gui.IGui;
 import mde.gui.exception;
+import mde.gui.renderer.createRenderer;
 
 import mt = mde.mergetag.DataSet;
 import tango.scrapple.text.convert.parseTo : parseTo;
@@ -61,19 +62,20 @@
         if (widgetData is null)
             throw new WindowLoadException ("No widget creation data");
         
+        // Save gui and create the renderer:
         gui_ = gui;
-        rend = gui.renderer;
-        
-        // Get border sizes
-        border = rend.getBorder (BORDER_TYPES.WINDOW_TOTAL);
-        resize = rend.getBorder (BORDER_TYPES.WINDOW_RESIZE);
+        rend = createRenderer (gui.rendererName);
         
         // Create the primary widget (and indirectly all sub-widgets), throwing on error:
-        widget = makeWidget (0);    // primary widget always has ID 0.
+        // Note: GridLayoutWidget's this relies on rend.layoutSpacing.
+        widget = makeWidget (0);        // primary widget always has ID 0.
         widgetData = null;  // data is no longer needed: allow GC to collect (cannot safely delete)
         
-        // Note: this should return an empty array, but nothing much should happen if it's not empty:
-        widget.adjust (mutableData);    // adjust/set size, etc.
+        // get border sizes:
+        border = rend.setSizable (isWSizable, isHSizable);  // depends on widget
+        
+        // Note: this should return an empty array, but we shouldn't make a fuss if it's not empty:
+        widget.adjust (mutableData);    // adjust/set size, etc., depends on rend
         mutableData = null;             // no longer needed
         
         widget.getCurrentSize (w,h);    // and get this size
@@ -167,12 +169,19 @@
         
         return i;
     }
-
+    
     IGui gui () {
         return gui_;
     }
     
-    IRenderer renderer () {
+    void requestRedraw () {
+        gui_.requestRedraw;
+    }
+    
+    IRenderer renderer ()
+    in {
+        assert (rend !is null, "Window.renderer: rend is null");
+    } body {
         return rend;
     }
     //END IWindow methods
@@ -249,38 +258,24 @@
     }
     void clickEvent (ushort cx, ushort cy, ubyte b, bool state) {
         if (b == 1 && state == true) {
-            if (cx < x + resize.l || cx >= xw - resize.r ||
-                cy < y + resize.t || cy >= yh - resize.b) { // window is being resized
-                /* check for resizes (different to above; use whole border giving larger area for
-                 * diagonal resizes). */
-                resizeType = RESIZE.NONE;
+            resizeType = rend.getResizeType (cx-x, cy-y, w,h);
+            
+            if (resizeType != RESIZE_TYPE.NONE) {    // Some type of resize
+                // Set x/yDrag (unfortunately these need to be different for each edge)
+                if (resizeType & RESIZE_TYPE.L)
+                    xDrag = w + cx;
+                else if (resizeType & RESIZE_TYPE.R)
+                    xDrag = w - cx;
                 
-                if (isWSizable) {
-                    if (cx < x + border.l) {
-                        xDrag = w + cx;
-                        resizeType = RESIZE.L;
-                    }
-                    else if (cx >= xw - border.r) {
-                        xDrag = w - cx;
-                        resizeType = RESIZE.R;
-                    }
-                }
-                if (isHSizable) {
-                    if (cy < y + border.t) {
-                        yDrag = h + cy;
-                        resizeType |= RESIZE.T;
-                    }
-                    else if (cy >= yh - border.b) {
-                        yDrag = h - cy;
-                        resizeType |= RESIZE.B;
-                    }
-                }
+                if (resizeType & RESIZE_TYPE.T)
+                    yDrag = h + cy;
+                else if (resizeType & RESIZE_TYPE.B)
+                    yDrag = h - cy;
                 
-                if (resizeType != RESIZE.NONE) {    // only if some valid size is being done
-                    gui_.addClickCallback (&endCallback);
-                    gui_.addMotionCallback (&resizeCallback);
-                }
-            } else {                // window is being moved
+                // Add the callbacks (they use resizeType which has already been set)
+                gui_.addClickCallback (&endCallback);
+                gui_.addMotionCallback (&resizeCallback);
+            } else {                             // window is being moved
                 xDrag = cx - x;
                 yDrag = cy - y;
                 
@@ -300,15 +295,15 @@
     //END IWidget methods
     
 private:
-    alias IRenderer.BorderDimensions    BorderDimensions;
-    alias IRenderer.BORDER_TYPES        BORDER_TYPES;
+    alias IRenderer.BorderDimensions BorderDimensions;
+    alias IRenderer.RESIZE_TYPE RESIZE_TYPE;
     
     //BEGIN Window moving and resizing
     void moveCallback (ushort cx, ushort cy) {
         setPosition (cx-xDrag, cy-yDrag);
     }
     void resizeCallback (ushort cx, ushort cy) {
-        if (resizeType & RESIZE.L) {
+        if (resizeType & RESIZE_TYPE.L) {
             int mw, nw;
             getMinimalSize (mw, nw);    // (only want mw)
             nw = xDrag - cx;
@@ -317,11 +312,11 @@
             setSize (nw, h);
             setPosition (mw, y);
         }
-        else if (resizeType & RESIZE.R) {
+        else if (resizeType & RESIZE_TYPE.R) {
             setSize (xDrag + cx, h);
-            setPosition (x, y);
+            setPosition (x, y);         // required to call after setSize.
         }
-        if (resizeType & RESIZE.T) {
+        if (resizeType & RESIZE_TYPE.T) {
             int mh, nh;
             getMinimalSize (nh, mh);
             nh = yDrag - cy;
@@ -330,28 +325,29 @@
             setSize (w, nh);
             setPosition (x, mh);
         }
-        else if (resizeType & RESIZE.B) {
+        else if (resizeType & RESIZE_TYPE.B) {
             setSize (w, yDrag + cy);
             setPosition (x, y);
         }
     }
-    void endCallback (ushort cx, ushort cy, ubyte b, bool state) {
+    bool endCallback (ushort cx, ushort cy, ubyte b, bool state) {
         if (b == 1 && state == false) {
             // The mouse shouldn't have moved since the motion callback
             // was last called, so there's nothing else to do now.
             gui_.removeCallbacks (cast(void*) this);
+            
+            return true;    // we've handled the up-click
         }
+        return false;       // we haven't handled it
     }
     int xDrag, yDrag;               // where a drag starts relative to x and y
-    enum RESIZE : ubyte {
-        NONE = 0x0, L = 0x1, R = 0x2, T = 0x4, B = 0x8
-    }
-    RESIZE resizeType;              // Type of current resize
+    IRenderer.RESIZE_TYPE resizeType;   // Type of current resize
     //END Window moving and resizing
     
     // Load/save data:
     public char[] name;             // The window's name (id from config file)
     //bool edited = false;            // True if any widgets have been edited (excluding scaling)
+    
     // Data used for saving and loading (null in between):
     int[][widgetID] widgetData = null;// Data for all widgets under this window
     int[] mutableData = null;       // Widget's mutable data (adjusted sizes, etc.)
@@ -365,8 +361,7 @@
     int w,h;                        // Window size (calculated from Widgets)
     int xw, yh;                     // x+w, y+h (frequent use by clickEvent)
     int widgetX, widgetY;           // Widget position (= window position plus BORDER_WIDTH)
-    int mw = -1, mh = -1;           // minimal size
+    int mw = -1, mh = -1;           // minimal size (negative means requires calculation)
     
     BorderDimensions border;        // Total border size (move plus resize)
-    BorderDimensions resize;        // The outer resize part of the border
 }