diff mde/gui/widget/Widget.d @ 45:0fd51d2c6c8a

Several changes to resising windows and layout widgets. This commit still has some bugs. Moved the implementable widgets from mde.gui.widget.Widget to miscWidgets, leaving base widgets in Widget. Rewrote some of GridLayoutWidget's implementation. Made many operations general to work for either columns or rows. Some optimisations were intended but ended up being removed due to problems. Allowed layout's to resize from either direction (only with window resizes). committer: Diggory Hardy <diggory.hardy@gmail.com>
author Diggory Hardy <diggory.hardy@gmail.com>
date Thu, 22 May 2008 11:34:09 +0100
parents 07bd1a09e161
children 03fa79a48c48
line wrap: on
line diff
--- a/mde/gui/widget/Widget.d	Fri May 16 12:22:10 2008 +0100
+++ b/mde/gui/widget/Widget.d	Thu May 22 11:34:09 2008 +0100
@@ -13,17 +13,16 @@
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>. */
 
-/// GUI Widget module.
+/** GUI Widget module.
+ *
+ * This module contains some base widget classes suitable for widget classes to inherit. However,
+ * inheriting one of them is by no means necessary for a widget so long as the IWidget interface is
+ * implemented. */
 module mde.gui.widget.Widget;
 
 public import mde.gui.widget.Ifaces;
-import mde.gui.exception;
 import mde.gui.renderer.IRenderer;
 
-import mde.resource.font;
-
-import tango.io.Stdout;
-
 /** An abstract base widget class.
 *
 * This abstract class, and the more concrete FixedWidget and ScalableWidget classes provides a
@@ -31,7 +30,8 @@
 * IWidget); they are simply provided for convenience and to promote code reuse. */
 abstract class Widget : IWidget
 {
-    // Base this(); all widgets must at least check data.length is correct.
+//BEGIN Load and save
+    // Base this(). All widgets must check data.length is correct before calling this method.
     this (IWindow wind, int[] data) {
         window = wind;
         widgetType = data[0];
@@ -40,14 +40,12 @@
     // Most widgets don't need to do adjustments based on mutable data, however they usually do
     // still need to set their size.
     int[] adjust (int[] data) {
-        setSize (0,0);
+        setSize (0,0,true,true);
         return data;
     }
     
-    bool isWSizable () {    return false;   }
-    bool isHSizable () {    return false;   }
-    
-    // Widget type should always be the first value.
+    // Widget type should always be the first value. Any widget using extra creation data will need
+    // to reimplemnt this method.
     int[] getCreationData () {
         return [widgetType];
     }
@@ -55,181 +53,83 @@
     int[] getMutableData () {
         return [];
     }
+//END Load and save
+    
+//BEGIN Size and position
+    bool isWSizable () {    return false;   }
+    bool isHSizable () {    return false;   }
+    
+    /* Return minimal/fixed size. */
+    void getMinimalSize (out int a, out int b) {
+        a = mw;
+        b = mh;
+    }
     
     void getCurrentSize (out int cw, out int ch) {
         cw = w;
         ch = h;
     }
     
+    /* Set size: minimal size is (mw,mh). Note that both resizable and fixed widgets should allow
+     * enlarging, so in both cases this is a correct implementation. */
+    void setSize (int nw, int nh, bool, bool) {
+        w = (nw >= mw ? nw : mw);
+        h = (nh >= mh ? nh : mh);
+    }
+    
     void setPosition (int nx, int ny) {
         x = nx;
         y = ny;
     }
+//END Size and position
     
-    /* Return self, since we don't have child widgets and the method wouldn't have been called
-    * unless the location was over us. Valid for all widgets without children. */
+//BEGIN Events
+    /* This method is only called when the location is over this widget; hence for all widgets
+     * without children this method is valid. */
     IWidget getWidget (int,int) {
         return this;
     }
     
-    /* Dummy event method (widget doesn't respond to events) */
+    /* Dummy event method (suitable for all widgets which don't respond to events). */
     void clickEvent (ushort cx, ushort cy, ubyte b, bool state) {}
+//END Events
     
-    /* Basic draw method: draw the background (all widgets should do this) */
+    /* Basic draw method: draw the background (all widgets should do this). */
     void draw () {
         window.renderer.drawWidgetBack (x,y, w,h);
     }
     
 protected:
-    final int widgetType;   // the type (stored for saving)
-    IWindow window;         // the enclosing window
-    int x, y;               // position
-    int w, h;               // size
+    final int widgetType;	// the type (stored for saving)
+    IWindow window;		// the enclosing window
+    int x, y;			// position
+    int w, h;			// size
+    int mw = 0, mh = 0;		// minimal or fixed size, depending on whether the widget is
+    				// resizible; both types of widgets should actually be expandable.
 }
-/** A base for fixed-size widgets. */
+
+/** A base for fixed-size widgets taking their size from the creation data. */
 class FixedWidget : Widget {
+    // Check data.length is at least 3 before calling!
     this (IWindow wind, int[] data) {
-        w = wF;
-        h = hF;
+        mw = data[1];
+        mh = data[2];
         super (wind, data);
+        w = mw;
+        h = mh;
     }
     
     int[] getCreationData () {
-        return [widgetType, wF, hF];
-    }
-    
-    /* Not resizable, so return current size. */
-    void getMinimalSize (out int mw, out int mh) {
-        mw = wF;
-        mh = hF;
+        return [widgetType, mw, mh];
     }
-    
-    /* Ignore: a fixed size widget. */
-    void setSize (int nw, int nh) {
-        w = (nw >= wF ? nw : wF);
-        h = (nh >= hF ? nh : hF);
-    }
-    
-protected:
-    int wF, hF;             // The "fixed" size, i.e. the preferred & minimal size
 }
 /** A base for resizable widgets. */
 class SizableWidget : Widget {
+    // Check data.length is at least 1 before calling!
     this (IWindow wind, int[] data) {
         super (wind, data);
     }
     
     bool isWSizable () {    return true;    }
     bool isHSizable () {    return true;    }
-    
-    /* Return zero. */
-    void getMinimalSize (out int mw, out int mh) {}
-    
-    /* Set size: a fully resizable widget. */
-    void setSize (int nw, int nh) {
-        w = (nw >= 0 ? nw : 0);
-        h = (nh >= 0 ? nh : 0);
-    }
-    
-    void draw () {
-        super.draw;
-        
-        window.renderer.drawBlank (x,y, w,h);
-    }
 }
-
-//BEGIN Widgets
-/// A fixed-size blank widget.
-class FixedBlankWidget : FixedWidget
-{
-    this (IWindow wind, int[] data) {
-        if (data.length != 3) throw new WidgetDataException;
-        wF = data[1];
-        hF = data[2];
-        super (wind, data);
-    }
-    void draw () {
-        super.draw;
-        
-        window.renderer.drawBlank (x,y, w,h);
-    }
-}
-
-/// A completely resizable blank widget (initial size zero).
-class SizableBlankWidget : SizableWidget
-{
-    this (IWindow wind, int[] data) {
-        if (data.length != 1) throw new WidgetDataException;
-        super (wind, data);
-    }
-}
-
-/// First interactible widget
-class ButtonWidget : FixedWidget
-{
-    bool pushed = false;    // true if button is pushed in (visually)
-    // pushed is not the same as the button being clicked but not yet released.
-    // it is whether the mouse is over the button after being clicked.
-    
-    this (IWindow wind, int[] data) {
-        if (data.length != 3) throw new WidgetDataException;
-        wF = data[1];
-        hF = data[2];
-        super (wind, data);
-    }
-    
-    void draw () {
-        window.renderer.drawButton (x,y, w,h, pushed);
-    }
-    
-    void clickEvent (ushort, ushort, ubyte b, bool state) {
-        if (b == 1 && state == true) {
-            pushed = true;
-            window.requestRedraw;
-            window.gui.addClickCallback (&clickWhileHeld);
-            window.gui.addMotionCallback (&motionWhileHeld);
-        }
-    }
-    // Called when a mouse motion/click event occurs while (held == true)
-    bool clickWhileHeld (ushort cx, ushort cy, ubyte b, bool state) {
-        if (b == 1 && state == false) {
-            if (cx >= x && cx < x+w && cy >= y && cy < y+h) // button event
-                Stdout ("Button clicked!").newline;
-            
-            pushed = false;
-            window.requestRedraw;
-            window.gui.removeCallbacks (cast(void*) this);
-            
-            return true;
-        }
-        return false;
-    }
-    void motionWhileHeld (ushort cx, ushort cy) {
-        bool oldPushed = pushed;
-        if (cx >= x && cx < x+w && cy >= y && cy < y+h) pushed = true;
-        else pushed = false;
-        if (oldPushed != pushed)
-            window.requestRedraw;
-    }
-}
-
-/// Basic text widget
-class TextWidget : FixedWidget
-{
-    this (IWindow wind, int[] data) {
-        if (data.length != 1) throw new WidgetDataException;
-        wF = 100;	//FIXME: set properly
-        hF = 25;
-        super (wind,data);
-    }
-    
-    void draw () {
-        super.draw();
-        if (font is null) font = Font.get("/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans.ttf");
-        font.drawStr (x,y, "Text Widget");
-    }
-    
-protected:
-    static Font font;
-}
-//END Widgets