diff mde/gui/widget/Widget.d @ 37:052df9b2fe07

Allowed widget resizing, changed widget IDs and made Input catch any callback exceptions. Enabled widget resizing. Removed IRenderer's temporary drawBox method and added drawButton for ButtonWidget. Made the Widget class abstract and added FixedWidget and SizableWidget classes. Rewrote much of createWidget to use meta-code; changed widget IDs. Made Input catch callback exceptions and report error messages. committer: Diggory Hardy <diggory.hardy@gmail.com>
author Diggory Hardy <diggory.hardy@gmail.com>
date Mon, 05 May 2008 14:47:25 +0100
parents 57d000574d75
children 5132301e9ed7
line wrap: on
line diff
--- a/mde/gui/widget/Widget.d	Fri May 02 17:38:43 2008 +0100
+++ b/mde/gui/widget/Widget.d	Mon May 05 14:47:25 2008 +0100
@@ -20,40 +20,35 @@
 import mde.gui.IGui;
 import mde.gui.exception;
 
-import gl = mde.gl.basic;
-
 import tango.io.Stdout;
 
-/** A base widget class. Widgets need not inherit this (they only need implement IWidget), but this
-* class provides a useful basic implementation for widgets.
+/** An abstract base widget class.
 *
-* Do not use directly (i.e. only for inheriting from).
-*/
-class Widget : IWidget
+* This abstract class, and the more concrete FixedWidget and ScalableWidget classes provides a
+* useful basic implementation for widgets. Widgets need not inherit these (they only need implement
+* IWidget); they are simply provided for convenience and to promote code reuse. */
+abstract class Widget : IWidget
 {
-    /** Minimum size is zero. */
-    void getMinimumSize (out int w, out int h) {}   // w,h initialised to 0
-    /** Current size. */
-    void getCurrentSize (out int w, out int h) {
-        w = this.w;
-        h = this.h;
+    void getCurrentSize (out int cw, out int ch) {
+        cw = w;
+        ch = h;
     }
     
-    void setPosition (int x, int y) {
-        this.x = x;
-        this.y = y;
+    void setPosition (int nx, int ny) {
+        x = nx;
+        y = ny;
     }
     
-    /** Return self, since we don't have child widgets and the method wouldn't have been called
+    /* 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. */
     IWidget getWidget (int,int) {
         return this;
     }
     
-    /** Dummy event method (widget doesn't respond to events) */
+    /* Dummy event method (widget doesn't respond to events) */
     void clickEvent (ushort cx, ushort cy, ubyte b, bool state) {}
     
-    /** 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);
     }
@@ -63,27 +58,67 @@
     int x, y;               // position
     int w, h;               // size
 }
+/** A base for fixed-size widgets. */
+class FixedWidget : Widget {
+    bool isWSizable () {    return false;   }
+    bool isHSizable () {    return false;   }
+    
+    /* Not resizable, so return current size. */
+    void getMinimalSize (out int mw, out int mh) {
+        mw = wF;
+        mh = hF;
+    }
+    
+    /* 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 {
+    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);
+    }
+}
 
 //BEGIN Widgets
-/// Draws a box. That's it.
-class BoxWidget : Widget
+/// A fixed-size blank widget.
+class FixedBlankWidget : FixedWidget
 {
     this (IWindow wind, IWidget, int[] data) {
         if (data.length != 2) throw new WidgetDataException;
         
         window = wind;
         
-        w = data[0];
-        h = data[1];
+        w = wF = data[0];
+        h = hF = data[1];
     }
-    void draw () {
-        gl.setColor(1f,0f,0f);
-        window.renderer.drawBox (x,y, w,h);
+}
+
+/// A completely resizable blank widget (initial size zero).
+class SizableBlankWidget : SizableWidget
+{
+    this (IWindow wind, IWidget, int[] data) {
+        if (data.length != 0) throw new WidgetDataException;
+        
+        window = wind;
     }
 }
 
 /// First interactible widget
-class ButtonWidget : 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.
@@ -94,21 +129,12 @@
         
         window = wind;
         
-        w = data[0];
-        h = data[1];
+        w = wF = data[0];
+        h = hF = data[1];
     }
     
     void draw () {
-        if (pushed)
-            gl.setColor (1f, 0f, 1f);
-        else
-            gl.setColor (.6f, 0f, .6f);
-        window.renderer.drawBox (x,y, w,h);
-    }
-    
-    void getMinimumSize (out int w, out int h) {
-        w = this.w; // button is not resizable
-        h = this.h;
+        window.renderer.drawButton (x,y, w,h, pushed);
     }
     
     void clickEvent (ushort, ushort, ubyte b, bool state) {