diff mde/gui/widget/layout.d @ 179:1f9d00f392bd default tip

Fixed a bug where (non-resizible) widgets wouldn't get shrunk when minimal size decreases, meaning optional context menus are hiden properly now. Optimised when ServiceContentList.opCall is called, I think without breaking anything.
author Diggory Hardy <diggory.hardy@gmail.com>
date Tue, 15 Sep 2009 20:09:59 +0200
parents af40e9679436
children
line wrap: on
line diff
--- a/mde/gui/widget/layout.d	Tue Sep 15 10:36:37 2009 +0200
+++ b/mde/gui/widget/layout.d	Tue Sep 15 20:09:59 2009 +0200
@@ -638,7 +638,9 @@
     /** Get the row/column of relative position l.
      *
      * returns:
-     * -i if in space to left of col i, or i if on col i. */
+     * -i if in space to left of col i, or i if on col i.
+     * 
+     * Handles l right-of-last-column fine, asserts if l < pos[0]. */
     ptrdiff_t getCell (wdim l) {
         debug assert (width, "AlignColumns not initialized when getCell called (code error)");
         ptrdiff_t i = cols - 1;     // starting from right...
@@ -667,18 +669,26 @@
         if (nw == w) return w;
         
         wdim diff = nw - w;
-        if (firstSizable == -1)
-            diff = adjustCellSizes (diff, cols-1, -1);
-        else
-            diff = adjustCellSizes (diff, (dir == -1 ? lastSizable : firstSizable), dir);
+	if (diff > 0) {
+	    if (firstSizable == -1)
+		diff = adjustCellSizes (diff, cols-1, -1);
+	    else
+		diff = adjustCellSizes (diff, (dir == -1 ? lastSizable : firstSizable), dir);
+	    debug assert (diff == 0);
+	} else {
+	    // For decreasing, visit all cols; it's possible some have size above minimal
+	    diff = adjustCellSizes (diff, (dir == -1 ? cols-1 : 0), dir);
+	    debug if (diff != 0)
+		logger.warn ("Unable to meet target width ({}); outstanding diff: {}", nw, diff);
+	}
         genPositions;
         
         debug if (nw != w) {
-            logger.trace ("resizeWidth on {} to {} failed, new width: {}, diff {}, firstSizable {}, columns {}",cast(void*)this, nw,w, diff, firstSizable, cols);
+            logger.error ("resizeWidth on {} to {} failed, new width: {}, diff {}, firstSizable {}, columns {}",cast(void*)this, nw,w, diff, firstSizable, cols);
             /+ Also print column widths & positions:
-            logger.trace ("resizeWidth to {} failed! Column dimensions and positions:",nw);
+            logger.error ("resizeWidth to {} failed! Column dimensions and positions:",nw);
             foreach (i,w; width)
-                logger.trace ("\t{}\t{}", w,pos[i]);+/
+                logger.error ("\t{}\t{}", w,pos[i]);+/
         }
         return w;
     }
@@ -688,8 +698,12 @@
      * This and resizeCols are for moving dividers between cells. */
     bool findResizeCols (wdim l) {
         resizeU = -getCell (l);             // potential start for upward-resizes
-        if (resizeU <= 0)
-            return true;		// not on a space between cells
+	if (resizeU <= 0)
+	    return true;		// not on a space between cells
+	if (resizeU >= cols) {		// right of last column; cannot resize
+	    resizeU = -1;
+	    return true;
+	}
         resizeD = resizeU - 1;              // potential start for downward-resizes
         
         while (!sizable[resizeU]) {         // find first actually resizable column (upwards)
@@ -717,12 +731,13 @@
         
         // do shrinking first (in case we hit the minimum)
         if (diff >= 0) {
-            diff = -adjustCellSizes (-diff, resizeU, 1);
-            adjustCellSizes (diff, resizeD, -1);
+            diff = adjustCellSizes (-diff, resizeU, 1) - diff;
+            diff = adjustCellSizes (diff, resizeD, -1);
         } else {
-            diff = -adjustCellSizes (diff, resizeD, -1);
-            adjustCellSizes (diff, resizeU, 1);
+            diff = adjustCellSizes (diff, resizeD, -1) - diff;
+            diff = adjustCellSizes (diff, resizeU, 1);
         }
+	debug assert (diff == 0);
         genPositions;
     }
     
@@ -751,24 +766,37 @@
             if (minWidth[col] == nmw)		// no change
                 return false;
             minWidth[col] = nmw;
-            if (!sizable[col] && lastSizable >= 0)
-                nd = width[col] - nmw;	// Not resizable but another column is
-            // Else leave larger; mustn't shrink ourself
-        } else
-            return false;
-        
+            if (!sizable[col])
+                nd = width[col] - nmw;	// Not resizable, so shrink
+            // Else resizable so leave
+        }
         mw = spacing * cast(wdim)(cols - 1);
         foreach (imw; minWidth)
             mw += imw;
         
-        if (nd != 0) {	// needs enlarging or shrinking
+	if (nd == 0)
+	    return false;
+	
+	if (nd < 0) {	// needs enlarging; we should do so here
+	    // set new width:
             width[col] = nmw;
             foreach (cb; cbs)
                 cb.setWidth (col, nmw, -1);
-            if (lastSizable >= 0)
-            	adjustCellSizes (nd, lastSizable, -1);
-        }
-        
+	    // Try to compensate (keep overall size the same by shrinking larger
+	    // than necessary columns); may not be possible:
+            adjustCellSizes (nd, 0, 1);
+        } else if (lastSizable >= 0) {
+	    // If another column can be increased, do that (otherwise the call
+	    // to parent.minXChange should decrease, if possible):
+	    // Although it _may_ not, if e.g. alignment forces larger-than-minimal size.
+	    width[col] = nmw;
+	    foreach (cb; cbs)
+		cb.setWidth (col, nmw, -1);
+	    nd = adjustCellSizes (nd, lastSizable, -1);
+	    debug assert (nd == 0);
+	}
+	//else debug logger.trace ("expecting parent.minXChange to shrink");
+	
         debug wdim ow = w;
         genPositions;
         debug if (w < ow)
@@ -800,7 +828,8 @@
     *  incr = direction to resize in (added to index each step). Must be either -1 or +1.
     *
     * Returns:
-    *  The amount adjusted. This may be larger than diff, since cellD is clamped by cellDMin.
+    *  (diff - "the actual amount adjusted") - 0 if met exactly, <0 if unable
+    * to shrink as much as requested.
     *
     * Will shrink non-sizable columns if they're over minimal size.
     * Will increase column start, since it's assumed sizable.
@@ -821,6 +850,7 @@
             width[i] += diff;
             foreach (cb; cbs)
                 cb.setWidth (i, width[i], incr);
+	    return 0;
         }
         else if (diff < 0) {        // decrease
             wdim rd = diff;         // running diff
@@ -843,11 +873,10 @@
                 
                 i += incr;
             }
-            diff -= rd; // still had rd left to decrease (may be 0)
+            return rd; // still had rd left to decrease (may be 0)
         }
         // else no adjustment needed (diff == 0)
-        
-        return diff;
+        return 0;
     }