changeset 142:9dabcc44f515

Tightened rules for alignment sharing of grid layouts (avoids a bug and generally preferable).
author Diggory Hardy <diggory.hardy@gmail.com>
date Sun, 08 Feb 2009 17:36:57 +0000
parents 6f69a9c111eb
children 2ac3e0012788
files codeDoc/jobs.txt data/conf/guiDemo.mtt mde/gui/widget/layout.d
diffstat 3 files changed, 56 insertions(+), 31 deletions(-) [+]
line wrap: on
line diff
--- a/codeDoc/jobs.txt	Sun Feb 08 15:49:45 2009 +0000
+++ b/codeDoc/jobs.txt	Sun Feb 08 17:36:57 2009 +0000
@@ -13,7 +13,6 @@
 3   Widget saving: how to deal with modifier functions, esp. when they discard parameters? Remove feature except for dimdata and handle gui editing separately?
 3   glBindTexture not working with non-0 index - perhaps use a higher level graphics library at some point.
 3   Windows compatibility - no registry support (useful to find path).
-2   Layout alignment issue when attempting to align things which cannot have the same dimensions (e.g. a parent forces width to other's width + k). Solutions: let one column be forcibly enlarged without affecting others, or only share alignment if parents do or parents are same (would also remove some unwanted alignment)..
 2   Popup help boxes on hover/right click to display content description.
 2   Options need a "level": simple options, for advanced users, for debugging only, etc.
 2   Command-line options for paths to by-pass normal path finding functionality.
--- a/data/conf/guiDemo.mtt	Sun Feb 08 15:49:45 2009 +0000
+++ b/data/conf/guiDemo.mtt	Sun Feb 08 17:36:57 2009 +0000
@@ -31,7 +31,7 @@
 <WidgetData|optName={0:[0x4040, 0,1]}>
 <WidgetData|optDesc={0:[0x4040, 0,2]}>
 <WidgetData|optVal={0:[0x6030,4,0],1:["optEnum"]}>
-<WidgetData|optEnum={0:[0x4100,0,1,2],1:["optName","optVal"]}>
+<WidgetData|optEnum={0:[0x4100,1,1,2],1:["optName","optVal"]}>
 <WidgetData|optSep={0:[0x21, 0xff],1:[" = "]}>
 {Basic}
 <WidgetData|root={0:[0x21,0x90D970],1:["A string!"]}>
--- a/mde/gui/widget/layout.d	Sun Feb 08 15:49:45 2009 +0000
+++ b/mde/gui/widget/layout.d	Sun Feb 08 17:36:57 2009 +0000
@@ -166,15 +166,15 @@
     protected this (IWidgetManager mgr, IParentWidget parent, widgetID id, WidgetData data) {
         super (mgr, parent, id);
         
-        // Create cell aligners with appropriate col/row adjustment function
+        // Create cell aligners, potentially sharing
         if (data.ints[1] & 1)
-	    col = AlignColumns.getInstance (id, cols);
+	    col = AlignColumns.getInstance (id, parent, cols, false);
         else
-	    col = (new AlignColumns (cols));
+	    col = (new AlignColumns (cols,null));
         if (data.ints[1] & 2)
-	    row = AlignColumns.getInstance (id~"R", rows);      // id must be unique to that for cols!
+	    row = AlignColumns.getInstance (id, parent, rows, true);
         else
-	    row = (new AlignColumns (rows));
+	    row = (new AlignColumns (rows,null));
         
         AlignColumns.CallbackStruct cbS;
         cbS.setWidth = &setColWidth;
@@ -460,7 +460,7 @@
      *                                          [ 2 3 ] */
     //IChildWidget[] subWidgets; (inherited from AParentWidget)
     
-    AlignColumns col, row;	// aligners for cols and rows
+    package AlignColumns col, row;	// aligners for cols and rows
 				// "rows" allocated in col and row; return value of *.addRows():
     size_t colR = size_t.max, rowR = size_t.max;
 }
@@ -480,29 +480,50 @@
  *************************************************************************************************/
 package class AlignColumns
 {
-    /** Instance returned will be shared with any other widgets of same widgetID.
+    /** Get an aligner.
      *
-     * Also ensures each widget sharing an instance expects the same number of columns. */
-    static AlignColumns getInstance (widgetID id, size_t columns) {
-        AlignColumns* p = id in instances;
+     * Will be shared with other layouts with the same id which have the same
+     * parent or if the parents share an aligner.
+     * 
+     * Also ensures each widget sharing an instance expects the same number of
+     * columns. */
+    static AlignColumns getInstance (widgetID id, IParentWidget parent, size_t columns, bool horiz) {
+        if (horiz)
+            id ~= "H";	// make the ID different for each aligner
+        AlignColumns[]* p = id in instances;
         if (p) {
-            if (p.cols != columns)
-                throw new GuiException ("AlignColumns: no. of columns varies between sharing widgets (code error)");
-            //logger.trace ("Shared alignment for: "~id);
-            return *p;
-        } else {
-            auto a = new AlignColumns (columns);
-            instances[id] = a;
-            return a;
+            foreach (ac; *p) {
+                if (parent !is ac.parent) {	// If parents are different
+                    GridWidget parGrid = cast(GridWidget) parent,
+                               acPGrid = cast(GridWidget) ac.parent;
+                    // and either is not a GridWidget
+                    // or their aligners are different
+                    if (parGrid is null || acPGrid is null ||
+                        horiz ? parGrid.row !is acPGrid.row
+                              : parGrid.col !is acPGrid.col) {
+                        continue;	// don't share with it
+                    }
+                }
+                if (ac.cols != columns)
+                    continue;	// Alignment sharing with ContentListWidgets??
+                return ac;
+            }
         }
+        auto a = new AlignColumns (columns, parent);
+        if (p) *p ~= a;
+        else instances[id] = [a];
+        return a;
     }
     
-    /** Create an instance. After creation, the number of columns can only be changed by calling
-     * reset.
+    /** Create an aligner.
      * 
      * After creation, minimal widths should be set for all columns (minWidth) and
-     * setWidths must be called before other functions are used. */
-    this (size_t columns) {
+     * setWidths must be called before other functions are used.
+     * 
+     * Params:
+     *	columns = Number of columns. Not expected to change.
+     *	parent = The parent of the GridWidget using this aligner. (Used when sharing aligners.) */
+    this (size_t columns, IParentWidget parent) {
 	if (columns < 1)
 	    throw new GuiException("AlignColumns: created with <1 column (code error)");
 	minWidth.length = columns;
@@ -510,6 +531,7 @@
         static if (SIZABILITY & SIZABILITY_ENUM.START_TRUE)
             sizable[] = true;
         cols = columns;
+        this.parent = parent;
     }
     
     /** Like IChildWidget's setup; calls sADD delegates. */
@@ -733,13 +755,15 @@
             width[col] = nmw;
             foreach (cb; cbs)
                 cb.setWidth (col, nmw, -1);
-            if (lastSizable >= 0) {
-            	if (nd != adjustCellSizes (nd, lastSizable, -1))
-                    logger.error ("New minimal size not applied correctly (code error): minWidth: {}, nmw: {}, col: {}, nd: {}", minWidth, nmw, col, nd);
-            }
-            genPositions;
+            if (lastSizable >= 0)
+            	adjustCellSizes (nd, lastSizable, -1);
         }
         
+        debug wdim ow = w;
+        genPositions;
+        debug if (w < ow)
+            logger.error ("newMinWidth: shrunk (code error); w={}, ow={}, nd={}", w,ow,nd);
+        
         //debug logger.trace ("newMW for col: minWidth: {}, nmw: {}, col: {}, nd: {}, mw: {}, w: {}", minWidth, nmw, col, nd, mw, w);
         foreach (cb; cbs)
             cb.newMW ();
@@ -862,9 +886,11 @@
     uint setup_n = uint.max;	// param n of last setup call
     bool setupWidths;		// setWidths has been run
     
-    static HashMap!(widgetID,AlignColumns) instances;
+    IParentWidget parent;	// Used to determine when to share aligner
+    
+    static HashMap!(widgetID,AlignColumns[]) instances;
     static this () {
-        instances = new HashMap!(widgetID,AlignColumns);
+        instances = new HashMap!(widgetID,AlignColumns[]);
     }
     
     alias IParentWidget.SIZABILITY SIZABILITY;