changeset 77:3dfd934100f7

Continuing widget data changes started in last commit: all previous widgets work again now (but lacking saving).
author Diggory Hardy <diggory.hardy@gmail.com>
date Tue, 29 Jul 2008 17:11:22 +0100
parents 65780e0e48e6
children 79a1809421aa
files data/conf/gui.mtt mde/gui/WidgetData.d mde/gui/widget/Ifaces.d mde/gui/widget/TextWidget.d mde/gui/widget/Widget.d mde/gui/widget/createWidget.d mde/gui/widget/layout.d mde/gui/widget/miscWidgets.d mde/setup/Init.d mde/setup/sdl.d
diffstat 10 files changed, 118 insertions(+), 91 deletions(-) [+]
line wrap: on
line diff
--- a/data/conf/gui.mtt	Mon Jul 28 18:49:18 2008 +0100
+++ b/data/conf/gui.mtt	Tue Jul 29 17:11:22 2008 +0100
@@ -1,8 +1,15 @@
 {MT01}
 <char[]|Renderer="Simple">
-<char[]|Design="Basic">
+<char[]|Design="Working">
+{Working}
+<WidgetData|root=[0xB004,3,3],["square","blank","square","blank","content","blank","square","blank","square"]>
+<WidgetData|square=[0x1,6,6],[]>
+<WidgetData|content=[0xB004,3,2],["blank","button","blank","blank","blank","opts"]>
+<WidgetData|button=[0x4010,200,200],[]>
+<WidgetData|blank=[0x3001],[]>
+<WidgetData|opts=[0xB005, 0xfe8c00],[]>
 {Basic}
-<WidgetData|root=[0x4010,200,200],"">
+<WidgetData|root=[0x21,0x90D970],["A string!"]>
 !{
 {W1}
 <int|x=30>
--- a/mde/gui/WidgetData.d	Mon Jul 28 18:49:18 2008 +0100
+++ b/mde/gui/WidgetData.d	Tue Jul 29 17:11:22 2008 +0100
@@ -289,7 +289,7 @@
                 if (strs.length != 2)
                     throw new ParseException ("Not two components");
                 ints = parseTo!(int[]) (strs[0]);
-                str = parseTo!(char[]) (strs[1]);
+                strings = parseTo!(char[][]) (strs[1]);
             }
             widgetData[id] = data;
         }
@@ -329,7 +329,7 @@
             // Note: is a very simple form of struct serialization
             with(data) {
                 dlg ("WidgetData", id, 
-                     parseFrom!(int[]) (ints) ~ ',' ~ parseFrom!(char[]) (str) );
+                     parseFrom!(int[]) (ints) ~ ',' ~ parseFrom!(char[][]) (strings) );
             }
         }
     }
--- a/mde/gui/widget/Ifaces.d	Mon Jul 28 18:49:18 2008 +0100
+++ b/mde/gui/widget/Ifaces.d	Tue Jul 29 17:11:22 2008 +0100
@@ -268,6 +268,6 @@
  *************************************************************************************************/
 struct WidgetData
 {
-    int[]   ints;	// An array of integer data
-    char[]  str;	// One string
+    int[]    ints;
+    char[][] strings;
 }
--- a/mde/gui/widget/TextWidget.d	Mon Jul 28 18:49:18 2008 +0100
+++ b/mde/gui/widget/TextWidget.d	Tue Jul 29 17:11:22 2008 +0100
@@ -60,6 +60,7 @@
 }
 
 /// Basic text widget
+// FIXME (content, creation for different types)
 class ContentWidget(ContentT : IContent) : Widget
 {
     /** Constructor for a widget containing [fixed] content.
@@ -69,8 +70,8 @@
      * where contentID is an ID for the string ID of the contained content
      * and colour is an 8-bit-per-channel RGB colour of the form 0xRRGGBB. */
     this (IWidgetManager mgr, WidgetData data) {
-        if (data.length != 2) throw new WidgetDataException;
-        text.set (data.str, data[1]);
+        WDCheck (data, 2, 1);
+        text.set (data.strings[0], data.ints[1]);
         text.getDimensions (mw, mh);
         super (mgr,data);
     }
@@ -118,11 +119,11 @@
 /// Basic text widget
 class ContentOptionWidget : Widget
 {
-    this (IWindow wind, int[] data, IContent c) {
-        if (data.length != 2) throw new WidgetDataException;
-        content.set (c, data[1]);
+    this (IWidgetManager mgr, WidgetData data, IContent c) {
+        WDCheck (data, 2, 0);
+        content.set (c, data.ints[1]);
         content.getDimensions (mw, mh);
-        super (wind,data);
+        super (mgr,data);
     }
     
     void draw () {
--- a/mde/gui/widget/Widget.d	Mon Jul 28 18:49:18 2008 +0100
+++ b/mde/gui/widget/Widget.d	Tue Jul 29 17:11:22 2008 +0100
@@ -13,21 +13,43 @@
 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. */
+ * 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.renderer.IRenderer;
+import mde.gui.exception;
 
-/** An abstract base widget class.
-*
-* 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. */
+
+/*************************************************************************************************
+ * Widgets may use WDCheck as a utility to check what data holds. Its use is encouraged, so that
+ * the checks can easily be updated should WidgetData be changed.
+ * 
+ * Params:
+ *  data    = the WidgetData to check lengths of
+ *  n_ints  = number of integers wanted
+ *  n_strings= number of strings (default 0 since not all widgets use strings)
+ *************************************************************************************************/
+void WDCheck (WidgetData data, size_t n_ints, size_t n_strings = 0) {
+    if (data.ints.length    != n_ints ||
+        data.strings.length != n_strings)
+        throw new WidgetDataException;
+}
+
+
+/*************************************************************************************************
+ * An abstract base widget class.
+ *
+ * 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 : IChildWidget
 {
 //BEGIN Load and save
--- a/mde/gui/widget/createWidget.d	Mon Jul 28 18:49:18 2008 +0100
+++ b/mde/gui/widget/createWidget.d	Tue Jul 29 17:11:22 2008 +0100
@@ -20,9 +20,9 @@
 import mde.gui.exception : WidgetDataException;
 
 // Widgets to create:
-//import mde.gui.widget.layout;
+import mde.gui.widget.layout;
 import mde.gui.widget.miscWidgets;
-//import mde.gui.widget.TextWidget;
+import mde.gui.widget.TextWidget;
 
 /** Create a widget of type data[0] (see enum WIDGET_TYPES) under manager mgr, with initialisation
 * data [1..$]. */
@@ -56,6 +56,7 @@
     LAYOUT                  = 0x8000,   // is a layout widget (i.e. has sub-widgets)?
     
     // Use widget names rather than usual capitals convention
+    Unnamed                 = 0x0,      // Only for use by widgets not created with createWidget
     
     // blank: 0x1
     FixedBlank              = 0x1,
@@ -77,12 +78,12 @@
 // Only used for binarySearch algorithm generation; must be ordered by numerical values.
 const char[][] WIDGETS = [
         "FixedBlank",
-        //"Text",
-        //"Int",
+        "Text",
+        "Int",
         "SizableBlank",
         "Button",
-        //"GridLayout",
-        /+"TrialContentLayout"+/];
+        "GridLayout",
+        "TrialContentLayout"];
 
 /* Generates a binary search algorithm. */
 char[] binarySearch (char[] var, char[][] consts) {
--- a/mde/gui/widget/layout.d	Mon Jul 28 18:49:18 2008 +0100
+++ b/mde/gui/widget/layout.d	Tue Jul 29 17:11:22 2008 +0100
@@ -48,27 +48,38 @@
      * [widgetID, r, c, w11, w12, ..., w1c, ..., wr1, ..., wrc]
      * where r and c are the number of rows and columns, and wij is the ID (from parent Window's
      * list) for the widget in row i and column j. The number of parameters must be r*c + 3. */
-    this (IWindow wind, int[] data) {
+    this (IWidgetManager mgr, WidgetData data) {
         // Get grid size and check data
-        // Check sufficient data for rows, cols, and at least one widget:
-        if (data.length < 4) throw new WidgetDataException;
+        // Check sufficient data for rows, cols, and possibly row/col widths.
+        if (data.ints.length < 3) throw new WidgetDataException;
         
-        rows = data[1];
-        cols = data[2];
-        if (data.length != 3 + rows * cols) throw new WidgetDataException;
-        /* data.length >= 4 so besides checking the length is correct, this tells us:
-         *      rows * cols >= 4 - 3 = 1            a free check!
-         * The only thing not checked is whether both rows and cols are negative, which would
-         * cause an exception when dynamic arrays are allocated by genCachedConstructionData, which
-         * is an acceptible method of failure (and is unlikely anyway). */
+        rows = data.ints[1];
+        cols = data.ints[2];
+        // Check: at least one sub-widget, ints length == 3 or also contains row & col widths,
+        // strings' length is correct:
+        if (rows < 1 || cols < 1 ||
+            (data.ints.length != 3 && data.ints.length != 3 + rows + cols) ||
+            data.strings.length != rows * cols)
+            throw new WidgetDataException;
         
         // Get all sub-widgets
         subWidgets.length = rows*cols;
         foreach (i, ref subWidget; subWidgets) {
-            subWidget = wind.makeWidget (data[i+3]);
+            subWidget = mgr.makeWidget (data.strings[i]);
         }
-        super (wind, data);
+        
+        super (mgr, data);
+        
+        if (data.ints.length == 3 + rows + cols) {
+            col.setCheck (cast(wdim[]) data.ints[3..cols+3]);
+            row.setCheck (cast(wdim[]) data.ints[cols+3..$]);
+        } else {
+            col.dupMin;
+            row.dupMin;
+        }
+        adjustCache;
     }
+    /+FIXME
     /** Return construction data to recreate this GridLayoutWidget. */
     int[] getCreationData () {
         int[] ret;
@@ -80,7 +91,7 @@
             ret[i+3] = window.addCreationData (widget);
         
         return ret;
-    }
+    }+/
 }
 
 
@@ -89,10 +100,10 @@
  *************************************************************************************************/
 class TrialContentLayoutWidget : GridWidget
 {
-    this (IWindow wind, int[] data) {
+    this (IWidgetManager mgr, WidgetData data) {
         debug scope (failure)
                 logger.warn ("TrialContentLayoutWidget: failure");
-        if (data.length != 3) throw new WidgetDataException;
+        WDCheck (data, 2);
         
         OptionList optsList = OptionList.trial();
         rows = optsList.list.length;
@@ -100,15 +111,23 @@
         
         // Get all sub-widgets
         subWidgets.length = rows*cols;
+        WidgetData COWData;
+        COWData.ints = [0, data.ints[1]];
         foreach (i, c; optsList.list) {
-            subWidgets[i] = new ContentOptionWidget (wind, data[1..3], c);
+            subWidgets[i] = new ContentOptionWidget (mgr, COWData, c);
         }
-        super (wind, data);
+        super (mgr, data);
+        
+        // Set col/row widths to minimals.
+        col.dupMin;
+        row.dupMin;
+        adjustCache;
     }
     
+    /+FIXME
     int[] getCreationData () {
         return [widgetType];
-    }
+    }+/
     
 private:
     OptionList optsList;
@@ -130,11 +149,14 @@
     //BEGIN Creation & saving
     /** Partial constructor for a grid layout widget.
      *
-     * Deriving classes should check data length, and set rows, cols, and the subWidgets array,
+     * Deriving classes should check data lengths, and set rows, cols, and the subWidgets array,
      * before calling this super constructor. (If it's necessary to call super(...) first,
-     * the call to genCachedConstructionData can be moved to the derived this() methods.) */
-    protected this (IWindow wind, int[] data) {
-        super (wind, data);
+     * the call to genCachedConstructionData can be moved to the derived this() methods.)
+     * 
+     * Derived constructors should call either dupMin or setCheck on col and row, and then call
+     * adjustCache, after calling this. */
+    protected this (IWidgetManager mgr, WidgetData data) {
+        super (mgr, data);
         
         // Needn't be set before genCachedConstructionData is called:
         col.setColWidth = &setColWidth;
@@ -144,34 +166,6 @@
         genCachedConstructionData;
     }
     
-    /** This implementation of adjust() does two things:
-     * 1. Pass adjust data on to sub-widgets
-     * 2. Set the size, from the adjust data if possible
-     *
-     * Can be overridden (probably along with getMutableData()) if a different implementation is
-     * wanted. adjustCache() may still be useful. */
-    int[] adjust (int[] data) {
-        // Give all sub-widgets their data:
-        foreach (widget; subWidgets)
-            data = widget.adjust (data);
-        
-        /** We basically short-cut setSize by loading previous col/row sizes and doing the final
-         * calculations.
-         * Note: if setSize gets called afterwards, it should have same dimensions and so not do
-         * anything. */
-        int lenUsed = 0;
-        if (data.length < rows + cols) {    // data error; use defaults
-            col.dupMin;
-            row.dupMin;
-        } else {                            // sufficient data
-            lenUsed = rows+cols;
-            col.setCheck (cast(wdim[])data[0..cols]);
-            row.setCheck (cast(wdim[])data[cols..lenUsed]);
-        }
-        
-        adjustCache();
-        return data[lenUsed..$];
-    }
     /** Generates cached mutable data.
      *
      * Should be called by adjust() after setting col and row widths (currently via dupMin or
@@ -189,6 +183,7 @@
             widget.setHeight (row.width[i / cols], -1);
         }
     }
+    /+ FIXME - saving
     /** Returns sub-widget mutable data along with column widths and row heights, as used by
      *  adjust(). */
     int[] getMutableData () {
@@ -197,7 +192,7 @@
             ret ~= widget.getMutableData;
         
         return ret ~ cast(int[])col.width ~ cast(int[])row.width;
-    }
+    }+/
     //END Creation & saving
     
     //BEGIN Size & position
@@ -234,7 +229,7 @@
     
     
     // Find the relevant widget.
-    IWidget getWidget (wdim cx, wdim cy) {
+    IChildWidget getWidget (wdim cx, wdim cy) {
         debug scope (failure)
                 logger.warn ("getWidget: failure");
         // Find row/column:
@@ -263,8 +258,8 @@
             dragX = cx;
             dragY = cy;
             
-            window.gui.addClickCallback (&endCallback);
-            window.gui.addMotionCallback (&resizeCallback);
+            mgr.addClickCallback (&endCallback);
+            mgr.addMotionCallback (&resizeCallback);
         }
     }
     
@@ -284,7 +279,7 @@
      * rows, cols and subWidgets must be set before calling. */
     void genCachedConstructionData () {
         // Will only change if renderer changes:
-        col.spacing = row.spacing = window.renderer.layoutSpacing;
+        col.spacing = row.spacing = mgr.renderer.layoutSpacing;
         
         // Calculate the minimal column and row sizes:
         // set length, making sure the arrays are initialised to zero:
@@ -302,7 +297,7 @@
         
         
         // Calculate the overall minimal size, starting with the spacing:
-        mh = window.renderer.layoutSpacing;	// use mh temporarily
+        mh = mgr.renderer.layoutSpacing;	// use mh temporarily
         mw = mh * cast(wdim)(cols - 1);
         mh *= cast(wdim)(rows - 1);
         
@@ -370,11 +365,11 @@
         foreach (i,widget; subWidgets)
             widget.setPosition (x + col.pos[i % cols],
                                 y + row.pos[i / cols]);
-        window.requestRedraw;
+        mgr.requestRedraw;
     }
     bool endCallback (wdabs cx, wdabs cy, ubyte b, bool state) {
         if (b == 1 && state == false) {
-            window.gui.removeCallbacks (cast(void*) this);
+            mgr.removeCallbacks (cast(void*) this);
             return true;	// we've handled the up-click
         }
         return false;		// we haven't handled it
@@ -390,7 +385,7 @@
     
     /* All widgets in the grid, by row. Order:  [ 0 1 ]
      *                                          [ 2 3 ] */
-    IWidget[] subWidgets;
+    IChildWidget[] subWidgets;
     
     /* Widths, positions, etc., either of columns or of rows
      *
@@ -491,7 +486,7 @@
         */
         wdim adjustCellSizes (wdim diff, myDiff start, int incr)
         in {
-            // Could occur if adjust isn't called first, but this would be a code error:
+            // Could occur if constructor doesn't call dupMin/setCheck (code error):
             assert (width !is null, "adjustCellSizes: width is null");
             // Most likely if passed negative when sizing is disabled:
             assert (start >= 0 && start < minWidth.length, "adjustCellSizes: invalid start");
--- a/mde/gui/widget/miscWidgets.d	Mon Jul 28 18:49:18 2008 +0100
+++ b/mde/gui/widget/miscWidgets.d	Tue Jul 29 17:11:22 2008 +0100
@@ -27,7 +27,7 @@
 class FixedBlankWidget : FixedWidget
 {
     this (IWidgetManager mgr, WidgetData data) {
-        if (data.ints.length != 3) throw new WidgetDataException;
+        WDCheck (data, 3);
         super (mgr, data);
     }
     
@@ -42,7 +42,7 @@
 class SizableBlankWidget : SizableWidget
 {
     this (IWidgetManager mgr, WidgetData data) {
-        if (data.ints.length != 1) throw new WidgetDataException;
+        WDCheck (data, 1);
         super (mgr, data);
     }
     
@@ -61,7 +61,7 @@
     // it is whether the mouse is over the button after being clicked.
     
     this (IWidgetManager mgr, WidgetData data) {
-        if (data.ints.length != 3) throw new WidgetDataException;
+        WDCheck (data, 3);
         super (mgr, data);
     }
     
--- a/mde/setup/Init.d	Mon Jul 28 18:49:18 2008 +0100
+++ b/mde/setup/Init.d	Tue Jul 29 17:11:22 2008 +0100
@@ -262,7 +262,7 @@
         const LOG_F_START = " - running";
         const LOG_F_END = " - completed";
         const LOG_F_BAD = " - failed";
-        const LOG_F_FAIL = " - failed: ";
+        const LOG_F_FAIL = " - exception: ";
         /* Runs all functions consecutively, first-to-last.
         * If any function fails, halts immediately. */
         void runStageForward (InitStage s) {
--- a/mde/setup/sdl.d	Mon Jul 28 18:49:18 2008 +0100
+++ b/mde/setup/sdl.d	Tue Jul 29 17:11:22 2008 +0100
@@ -178,6 +178,7 @@
 
 void cleanupSDL () {    // cleanup func
     closeJoysticks();
+    logger.trace ("cleanupSDL - middle");
     SDL_Quit();
 }