changeset 126:c9843fbaac88

Dynamic minimal size changing improved; works over layouts sharing alignment. EnumContent sub-contents use EnumValueContent instead of BoolContent; fixes a few small bugs. EnumContent substrings get translated (bug fixed). The widget manager no longer attempts to set widget sizes smaller than their minimals, even though some will not be shown. SwitchWidget: has fixed sizableness now.
author Diggory Hardy <diggory.hardy@gmail.com>
date Thu, 08 Jan 2009 13:05:44 +0000
parents 3e648bc53bde
children 3328c6fb77ca
files data/conf/guiDemo.mtt mde/content/AStringContent.d mde/content/Content.d mde/content/Items.d mde/gui/WMScreen.d mde/gui/WidgetManager.d mde/gui/widget/Floating.d mde/gui/widget/Ifaces.d mde/gui/widget/TextWidget.d mde/gui/widget/Widget.d mde/gui/widget/layout.d mde/gui/widget/miscContent.d
diffstat 12 files changed, 233 insertions(+), 118 deletions(-) [+]
line wrap: on
line diff
--- a/data/conf/guiDemo.mtt	Tue Jan 06 16:54:04 2009 +0000
+++ b/data/conf/guiDemo.mtt	Thu Jan 08 13:05:44 2009 +0000
@@ -3,7 +3,7 @@
 <char[]|Design="Working">
 {Working}
 <WidgetData|root={0:[0x4100,0,3,1],1:["bar","float","bar"]}>
-<WidgetData|float={0:[0x4200,14,14],1:["optaC","switchC"]}>
+<WidgetData|float={0:[0x4200,14,14,14],1:["optaC","optaC","switchC"]}>
 <WidgetData|bar={0:[0x4100,14,1,3],1:["menu","blank","menu"]}>
 <WidgetData|menu={0:[0x2031],1:["imde.menu","menu0"]}>
 <WidgetData|menu0={0:[0x4011,0],1:["menu1"]}>
--- a/mde/content/AStringContent.d	Tue Jan 06 16:54:04 2009 +0000
+++ b/mde/content/AStringContent.d	Thu Jan 08 13:05:44 2009 +0000
@@ -154,6 +154,10 @@
 	assignNoCb (val);
 	super (symbol);
     }
+    // for use by EnumValueContent
+    protected this (char[] symbol, int dummy) {
+        super (symbol);
+    }
     
     void assignNoCb (bool val) {
 	v = val;
@@ -289,7 +293,6 @@
 /** A content representing an enumeration.
  *
  * Extends IntContent for Options support. */
-// maybe avoid problems by adding a special callback to BoolContent subclass?
 class EnumContent : IntContent, IContentList
 {
     /** CTOR.
@@ -300,29 +303,32 @@
     */
     this (char[] symbol, char[][] enumSymbols, int val = 0) {
         enums.length = enumSymbols.length;
+        char[] symPeriod = symbol~'.';
         foreach (i, ref e; enums) {
-            e = new BoolContent (enumSymbols[i], false);
-            e.addCallback (&enumAssignCb);
+            e = new EnumValueContent (this, i, symPeriod~enumSymbols[i]);
         }
-	super (symbol, val);
-        //NOTE: if val is 0, no enumeration should be set; however it seems to work!
+        super (symbol, val);	// calls assignNoCb
     }
     
-    override void assignNoCb (int val) {
-        if (val == v) return;
+    override void assignNoCb (int val) {	// called by children (via opAssign)
         if (val >= enums.length || val < 0) {
 	    logger.error ("EnumContent "~name_~" assigned invalid value; keeping value: "~sv);
 	    return;
 	}
-        enums[v] = false;
-        enums[val] = true;
+        enums[v]  .assignFromParent (false);
+        enums[val].assignFromParent (true);
 	v = val;
-        svAssign;
+        sv = enums[v].name_;
+        if (pos > sv.length) pos = sv.length;
+        endEvent;
     }
-    void svAssign () {
-	sv = enums[v].name_;
-	if (pos > sv.length) pos = sv.length;
-        endEvent;
+    // Change if true, assert current value if false
+    void childAssign (int val) {
+        debug assert (0 <= val && val < enums.length, "cA out of bounds");
+        if (enums[val].v)
+            assignNoCb (val);
+        else
+            enums[val].assignFromParent (v == val);
     }
     
     override char[] endEdit () {
@@ -346,19 +352,35 @@
     }
     
 protected:
-    void enumAssignCb (Content c) {
-        if (enums[v] is c) {	// No other is set so persist value
-            enums[v].assignNoCb (true);
+    EnumValueContent[] enums;
+    
+    /** Special version of BoolContent for each enumeration to update the parent Enum. */
+    private class EnumValueContent : BoolContent {
+        /** New enumeration of parent with index num. */
+        this (EnumContent parent, size_t num, char[] symbol) {
+            this.parent = parent;
+            i = num;
+            super (symbol, 0);	// parent sets value (if true); we shouldn't
+            sv = "false";	// except for this
+        }
+        
+        override void assignNoCb (bool val) {
+            v = val;
+            parent.childAssign (i);
         }
-        foreach (i,e; enums)
-            if (c is e) {
-            	enums[v].assignNoCb = false;	// NOTE: opAssign causes sigsegv (due to recursive calling?)
-                v = i;
-                svAssign;
-                return;
-            }
-        debug logger.error ("EnumContent.enumAssignCb: invalid value (code error)");
+        void assignFromParent (bool val) {	// don't call back to parent
+            super.assignNoCb (val);
+            endEvent;
+        }
+        
+        override char[] endEdit () {
+            v = sv && (sv[0] == 't' || sv[0] == 'T' || sv[0] == '1');
+            parent.childAssign (i);
+            return sv;
+        }
+    
+    protected:
+        EnumContent parent;
+        size_t i;
     }
-    
-    BoolContent[] enums;	// NOTE: an array isn't always fastest
 }
--- a/mde/content/Content.d	Tue Jan 06 16:54:04 2009 +0000
+++ b/mde/content/Content.d	Thu Jan 08 13:05:44 2009 +0000
@@ -20,6 +20,14 @@
 
 import util = mde.util;
 
+debug {
+    import tango.util.log.Log : Log, Logger;
+    private Logger logger;
+    static this () {
+        logger = Log.getLogger ("mde.gui.content.Content");
+    }
+}
+
 /** IContent − interface for all Content classes.
  *
  * Very little code uses IContent (except for passing opaquely). */
--- a/mde/content/Items.d	Tue Jan 06 16:54:04 2009 +0000
+++ b/mde/content/Items.d	Thu Jan 08 13:05:44 2009 +0000
@@ -102,7 +102,7 @@
 	    foreach (s, v; opts.content) {
 		trle = trl.getStruct (s);
 		v.name (trle.name, trle.desc);
-		ContentList cl = cast(ContentList) v;
+		IContentList cl = cast(IContentList) v;
 		if (cl) {
 		    foreach (i,c; cl.list) {
 			trle = trl.getStruct (c.symbol);
--- a/mde/gui/WMScreen.d	Tue Jan 06 16:54:04 2009 +0000
+++ b/mde/gui/WMScreen.d	Thu Jan 08 13:05:44 2009 +0000
@@ -183,8 +183,14 @@
         w = cast(wdim) nw;
         h = cast(wdim) nh;
         
-        if (w < mw || h < mh)
-            logger.warn ("Minimal dimensions ({},{}) not met: ({},{}), but I cannot resize myself!",mw,mh,w,h);
+        if (w < mw) {
+            logger.warn ("Min width for gui, {}, not met: {}", mw, w);
+            w = mw;
+        }
+        if (h < mh) {
+            logger.warn ("Min height for gui, {}, not met: {}", mh, h);
+            h = mh;
+        }
         
         if (!child) return;     // if not created yet.
         child.setWidth  (w, -1);
@@ -208,8 +214,14 @@
         
         mw = child.minWidth;
         mh = child.minHeight;
-        if (w < mw || h < mh)
-            logger.warn ("Minimal dimensions ({},{}) not met: ({},{}), but I cannot resize myself!",mw,mh,w,h);
+        if (w < mw) {
+            logger.warn ("Min width for gui, {}, not met: {}", mw, w);
+            w = mw;
+        }
+        if (h < mh) {
+            logger.warn ("Min height for gui, {}, not met: {}", mh, h);
+            h = mh;
+        }
         
         debug (mdeWidgets) logger.trace ("Setting size and position of root widget...");
         child.setWidth  (w, -1);
--- a/mde/gui/WidgetManager.d	Tue Jan 06 16:54:04 2009 +0000
+++ b/mde/gui/WidgetManager.d	Thu Jan 08 13:05:44 2009 +0000
@@ -242,8 +242,27 @@
     // If call reaches the widget manager there isn't any recursion.
     //NOTE: should be override
     final void recursionCheck (widgetID) {}
-    //FIXME: implement
-    override void minSizeChange (IChildWidget widget, wdim mw, wdim mh) {}
+    
+    override void minWChange (IChildWidget widget, wdim nmw) {
+        debug assert (widget is child, "WM.mSC (code error)");
+        mw = nmw;
+        if (w < nmw) {
+            child.setWidth (nmw, -1);
+            w = nmw;
+        }
+        child.setPosition (0,0);
+        requestRedraw;
+    }
+    override void minHChange (IChildWidget widget, wdim nmh) {
+        debug assert (widget is child, "WM.mSC (code error)");
+        mh = nmh;
+        if (h < nmh) {
+            child.setHeight (nmh, -1);
+            h = nmh;
+        }
+        child.setPosition (0,0);
+        requestRedraw;
+    }
     //END IParentWidget methods
     
     //BEGIN IWidgetManager methods
@@ -493,8 +512,8 @@
     IRenderer rend;
     
     // Widgets:
-    wdim w,h;				// area available to the widgets
-    wdim mw,mh;				// minimal area required by widgets (ideally for limiting w,h)
+    wdim w,h;				// current widget size; should be at least (mw,mh) even if not displayable
+    wdim mw,mh;				// minimal area required by widgets
     scope IChildWidget child;		// The primary widget.
     uint setupN;			// n to pass to IChildWidget.setup
     
--- a/mde/gui/widget/Floating.d	Tue Jan 06 16:54:04 2009 +0000
+++ b/mde/gui/widget/Floating.d	Thu Jan 08 13:05:44 2009 +0000
@@ -116,35 +116,35 @@
             subWidgets[i].setPosition (x + d.x + d.border.x1, y + d.y + d.border.y1);
     }
     
-    override void minSizeChange (IChildWidget widg, wdim nmw, wdim nmh) {
-        size_t i = 0;
-        while (i < subWidgets.length) {
-            if (subWidgets[i] is widg)
-                goto gotI;
-            ++i;
-        }
-        debug logger.error ("minSizeChange: widget is not my child (code error)");
-        return;
-        
-        gotI:
-        with (sWData[i]) {
+    override void minWChange (IChildWidget widg, wdim nmw) {
+        with (sWData[getWidgetIndex(widg)]) {
             mw = nmw + border.x1 + border.x2;
-            mh = nmh + border.y1 + border.y2;
             
             if (mw > w || !widg.isWSizable) {
                 w = mw;
                 widg.setWidth  (w - border.x1 - border.x2, -1);
             }
+            
+            if (x + w > this.w)
+                x = (w > this.w) ? 0 : this.w - w;
+            
+            widg.setPosition (this.x + border.x1 + x,this.y + border.y1 + y);
+            mgr.requestRedraw;
+        }
+    }
+    override void minHChange (IChildWidget widg, wdim nmh) {
+        with (sWData[getWidgetIndex(widg)]) {
+            mh = nmh + border.y1 + border.y2;
+            
             if (mh > h || !widg.isHSizable) {
                 h = mh;
                 widg.setHeight (h - border.y1 - border.y2, -1);
             }
             
-            if (x + w > this.w)
-                x = (w > this.w) ? 0 : this.w - w;
             if (y + h > this.h)
                 y = (h > this.h) ? 0 : this.h - h;
             
+            widg.setPosition (this.x + border.x1 + x,this.y + border.y1 + y);
             mgr.requestRedraw;
         }
     }
--- a/mde/gui/widget/Ifaces.d	Tue Jan 06 16:54:04 2009 +0000
+++ b/mde/gui/widget/Ifaces.d	Thu Jan 08 13:05:44 2009 +0000
@@ -46,16 +46,15 @@
     /** Child widgets should call this on their parent if their minimal size changes, since they
      * cannot resize themselves.
      * 
-     * Parents should resize children calling this when the size is increased, and when
-     * decreased and the widget is not resizable (but should not do so when it is).
+     * Children may depend on their parent resizing them if necessary to keep width valid.
+     * Widgets may also depend on setPosition being called afterwards.
      * 
      * Params:
      *	widget	= The child widget calling the function
      *	mw	= New minimal width
      *	mh	= New minimal height */
-    //FIXME: set rules for setting size: i.e. can widget rely on parent (ulimately mgr) setting
-    // a new size?
-    void minSizeChange (IChildWidget widget, wdim mw, wdim mh);
+    void minWChange (IChildWidget widget, wdim mw);
+    void minHChange (IChildWidget widget, wdim mh);	/// ditto
 }
 
 
--- a/mde/gui/widget/TextWidget.d	Tue Jan 06 16:54:04 2009 +0000
+++ b/mde/gui/widget/TextWidget.d	Thu Jan 08 13:05:44 2009 +0000
@@ -111,11 +111,17 @@
         if (content is null) throw new ContentException (this);
         super (mgr, parent, id);
         
+        Content c2 = cast(Content) content;
+        if (c2)		// add callback if possible
+            c2.addCallback (&update);
         adapter = mgr.renderer.getAdapter ();
 	adapter.text = content.toString(0);
     }
     
 protected:
+    void update (Content) {	// callback
+        adapter.text = content.toString(0);
+    }
     IContent content;
 }
 
@@ -127,6 +133,7 @@
         if (content is null) throw new ContentException (this);
         super (mgr, parent, id);
         
+        content.addCallback (&update);
         adapter = mgr.renderer.getAdapter ();
 	adapter.text = content.toString(0);
     }
@@ -145,8 +152,12 @@
     override void keyEvent (ushort s, char[] i) {
 	adapter.text = content.keyStroke (s, i);
 	adapter.index = content.editIndex;
-	adapter.getDimensions (mw, mh);
-        parent.minSizeChange (this, mw, mh);
+        wdim omw = mw, omh = mh;
+        adapter.getDimensions (mw, mh);
+        if (omw != mw)
+            parent.minWChange (this, mw);
+        if (omh != mh)
+            parent.minHChange (this, mh);
 	mgr.requestRedraw;
     }
     override void keyFocusLost () {
@@ -156,5 +167,14 @@
     }
     
 protected:
+    void update (Content) {	// callback
+        adapter.text = content.toString(0);
+        wdim omw = mw, omh = mh;
+        adapter.getDimensions (mw, mh);
+        if (omw != mw)
+            parent.minWChange (this, mw);
+        if (omh != mh)
+            parent.minHChange (this, mh);
+    }
     AStringContent content;
 }
--- a/mde/gui/widget/Widget.d	Tue Jan 06 16:54:04 2009 +0000
+++ b/mde/gui/widget/Widget.d	Thu Jan 08 13:05:44 2009 +0000
@@ -58,7 +58,8 @@
     }
     
     // Parent widgets need to implement this.
-    override void minSizeChange (IChildWidget widget, wdim mw, wdim mh) {}
+    override void minWChange (IChildWidget widget, wdim mw) {}
+    override void minHChange (IChildWidget widget, wdim mh) {}
 //END IParentWidget methods
     
 //BEGIN Load and save
@@ -236,6 +237,14 @@
         return c;
     }
     
+    size_t getWidgetIndex (IChildWidget widg) {
+        foreach (i,w; subWidgets)
+            if (w is widg)
+                return i;
+        
+        throw new GuiException ("getWidgetIndex: widget not found (code error)");
+    }
+    
 protected:
     IChildWidget[] subWidgets;
 }
--- a/mde/gui/widget/layout.d	Tue Jan 06 16:54:04 2009 +0000
+++ b/mde/gui/widget/layout.d	Thu Jan 08 13:05:44 2009 +0000
@@ -161,12 +161,20 @@
 	    col = AlignColumns.getInstance (id, cols);
         else
 	    col = (new AlignColumns (cols));
-        col.addCallbacks (&setColWidth, &setupAlignDimData);
         if (data.ints[1] & 2)
 	    row = AlignColumns.getInstance (id~"R", rows);      // id must be unique to that for cols!
         else
 	    row = (new AlignColumns (rows));
-        row.addCallbacks (&setRowHeight, &setupAlignDimData);
+        
+        AlignColumns.CallbackStruct cbS;
+        cbS.setWidth = &setColWidth;
+        cbS.sADD = &setupAlignDimData;
+        cbS.newMW = &colNewMW;
+        col.cbs ~= cbS;
+        cbS.setWidth = &setRowHeight;
+        cbS.newMW = &rowNewMW;
+        row.cbs ~= cbS;
+        
         useSpacing = (data.ints[1] & 4) != 0;
     }
     
@@ -240,30 +248,19 @@
             widget.setPosition (x + col.pos[i % cols], y + row.pos[i / cols]);
     }
     
-    override void minSizeChange (IChildWidget widg, wdim nmw, wdim nmh) {
-        size_t c = 0;
-        while (c < subWidgets.length) {
-            if (subWidgets[c] is widg)
-                goto gotCell;
-            ++c;
-        }
-        debug logger.error ("minSizeChange: widget is not my child (code error)");
-        return;
-        
-        gotCell:
-        size_t r = c / cols;
-        c = c % cols;
-        bool sizeChange = col.newMinWidth (c, r+colR, nmw);
-        sizeChange = row.newMinWidth (r, c+rowR, nmh) || sizeChange;
-        if (sizeChange) {
-            w = col.w;
-            h = row.w;
-            parent.minSizeChange (this, col.mw, row.mw);
-        }
-        mgr.requestRedraw;
+    // Unlike for most widgets, these actually resize self and sub-widgets, since the parent
+    // simply calling setWidth/setHeight wouldn't work.
+    override void minWChange (IChildWidget widg, wdim nmw) {
+        size_t i = getWidgetIndex(widg);
+        col.newMinWidth (i%cols, i/cols + colR, nmw);
+        // callbacks to all sharing layouts do the rest
+    }
+    override void minHChange (IChildWidget widg, wdim nmh) {
+        size_t i = getWidgetIndex(widg);
+        row.newMinWidth (i/cols, i%cols + rowR, nmh);
     }
     //END Size & position
-    
+   
     
     // Find the relevant widget.
     override IChildWidget getWidget (wdim cx, wdim cy) {
@@ -385,6 +382,25 @@
         }
     }
     
+    void colNewMW (bool mwChange) {
+        if (mwChange) {
+            w = col.w;
+            parent.minWChange (this, col.mw);
+        } else {	// don't propegate call to parent
+            setPosition (x,y);
+            mgr.requestRedraw;
+        }
+    }
+    void rowNewMW (bool mwChange) {
+        if (mwChange) {
+            h = row.w;
+            parent.minHChange (this, row.mw);
+        } else {	// don't propegate call to parent
+            setPosition (x,y);
+            mgr.requestRedraw;
+        }
+    }
+    
     
     //BEGIN Col/row resizing callback
     override void resizeCallback (wdim cx, wdim cy) {
@@ -479,8 +495,8 @@
 	    setupWidths = false;
 	    reset (cols);
 	    
-	    foreach (dg; sADD)
-		dg (n, flags);	// set flag 1
+	    foreach (cb; cbs)
+                cb.sADD (n, flags);	// set flag 1
 	}
     }
     
@@ -559,15 +575,6 @@
         }
     }
     
-    /** Add a callback to be called to notify changes in a column's width, and the sADD callback.
-     */
-    typeof(this) addCallbacks (void delegate (size_t,wdim,int) setCW, void delegate (uint,uint) sDg) {
-	assert (setCW && sDg, "AlignColumns.addCallbacks: null callback (code error)");
-        setWidthCb ~= setCW;
-	sADD ~= sDg;
-        return this;
-    }
-    
     /** Get the row/column of relative position l.
      *
      * returns:
@@ -659,14 +666,14 @@
     
     /** Called when one of the cells in column col now has minimal width nmw.
      *
-     * Enlarges column minimal width if necessary; tries to keep total width the same but returns
-     * true if it cannot. */
-    bool newMinWidth (size_t col, size_t row, wdim nmw) {
+     * Enlarges column minimal width if necessary; tries to keep total width the same. */
+    void newMinWidth (size_t col, size_t row, wdim nmw) {
         minCellWidths[col + row*cols] = nmw;
         wdim nd = 0;	// negative diff to keep overall size constant if possible
-        if (minWidth[col] < nmw) {	// increase minimal
+        wdim omw = minWidth[col];		// to check if mw actually changes
+        if (minWidth[col] < nmw) {		// increase minimal
             minWidth[col] = nmw;
-            nd = width[col] - nmw;	// negative diff
+            nd = width[col] - nmw;		// negative diff
         } else if (minWidth[col] > nmw) {	// potentially decrease minimal
             nmw = 0;
             for (size_t r = 0; r < rows; ++r) {
@@ -684,16 +691,18 @@
         foreach (imw; minWidth)
             mw += imw;
         
-        if (nd != 0) {	// needs enlarging
+        if (nd < 0 || (nd > 0 && !sizable[col])) {	// needs enlarging or shrinking
             width[col] = nmw;
-            foreach (dg; setWidthCb)
-                dg(col, nmw, -1);
+            foreach (cb; cbs)
+                cb.setWidth (col, nmw, -1);
             if (lastSizable >= 0)
             	adjustCellSizes (nd, lastSizable, -1);	// doesn't necessarily resize exactly
             genPositions;
         }
 
-        return true;
+        bool mwChange = nmw != omw;	// size only changes if true, presuming old size is valid
+        foreach (cb; cbs)
+            cb.newMW (mwChange);
     }
     
     /* Generate position infomation for each column and set w. */
@@ -734,8 +743,8 @@
         ptrdiff_t i = start;
         if (diff > 0) {             // increase size of first resizable cell
             width[i] += diff;
-            foreach (dg; setWidthCb)
-                dg(i, width[i], incr);
+            foreach (cb; cbs)
+                cb.setWidth (i, width[i], incr);
         }
         else if (diff < 0) {        // decrease
             wdim rd = diff;         // running diff
@@ -744,15 +753,15 @@
                 width[i] += rd;     // decrease this cell's size (but may be too much)
                 rd = width[i] - minWidth[i];
                 if (rd >= 0) {      // OK; we're done
-                    foreach (dg; setWidthCb)
-                        dg(i, width[i], incr);
+                    foreach (cb; cbs)
+                        cb.setWidth (i, width[i], incr);
                     break;          // we hit the mark exactly: diff is correct
                 }
                 
                 // else we decreased it too much!
                 width[i] = minWidth[i];
-                foreach (dg; setWidthCb)
-                    dg(i, width[i], incr);
+                foreach (cb; cbs)
+                    cb.setWidth (i, width[i], incr);
                 // rd is remainder to decrease by
                 
                 do {
@@ -790,6 +799,14 @@
     wdim[]  pos;                /// ditto
     wdim    spacing;            // used by genPositions (which cannot access the layout class's data)
     wdim    w,mw;               // current & minimal widths
+    
+    package struct CallbackStruct {
+        void delegate (size_t,wdim,int) setWidth; // set width of a column, with resize direction
+    	void delegate (uint,uint) sADD;	// setupAlignDimData dlgs
+        void delegate (bool) newMW;	// propegate or finalize minimal width change
+    }
+    CallbackStruct cbs[];
+    
 protected:
     /* Minimal width for each column.
      *
@@ -803,8 +820,6 @@
     /* indicies of the first/last resizable column (negative if none are resizable). */
     ptrdiff_t  firstSizable = -1, lastSizable = -1;  // set by calcFLSbl
     // Callbacks used to actually adjust a column's width:
-    void delegate (size_t,wdim,int) setWidthCb[]; // set width of a column, with resize direction
-    void delegate (uint,uint) sADD[];	// setupAlignDimData dlgs
     
     uint setup_n = uint.max;	// param n of last setup call
     bool setupWidths;		// setWidths has been run
--- a/mde/gui/widget/miscContent.d	Tue Jan 06 16:54:04 2009 +0000
+++ b/mde/gui/widget/miscContent.d	Thu Jan 08 13:05:44 2009 +0000
@@ -144,8 +144,11 @@
             throw new ContentException (this);
         WDCheck (data, 1, subWidgets.length);
         
-        foreach (i,sc; content.list)
+        foreach (i,sc; content.list) {
             subWidgets[i] = mgr.makeWidget (this, data.strings[i], sc);
+            isWS |= subWidgets[i].isWSizable;
+            isHS |= subWidgets[i].isHSizable;
+        }
         currentW = subWidgets[content()];
         
         content.addCallback (&switchWidget);
@@ -162,17 +165,22 @@
         return r;
     }
     
-    override void minSizeChange (IChildWidget widget, wdim nmw, wdim nmh) {
+    override void minWChange (IChildWidget widget, wdim nmw) {
+        if (widget !is currentW) return;
         mw = nmw;
+        parent.minWChange (this, nmw);
+    }
+    override void minHChange (IChildWidget widget, wdim nmh) {
+        if (widget !is currentW) return;
         mh = nmh;
-        parent.minSizeChange (this, nmw, nmh);
+        parent.minHChange (this, nmh);
     }
     
     override bool isWSizable () {
-        return currentW.isWSizable;
+        return isWS;
     }
     override bool isHSizable () {
-        return currentW.isHSizable;
+        return isHS;
     }
     
     override void setWidth (wdim nw, int dir) {
@@ -200,7 +208,8 @@
         currentW = subWidgets[content()];
         mw = currentW.minWidth;
         mh = currentW.minHeight;
-        parent.minSizeChange (this, mw, mh);
+        parent.minWChange (this, mw);
+        parent.minHChange (this, mh);
         w = currentW.width;
         h = currentW.height;
         currentW.setPosition (x,y);
@@ -208,4 +217,6 @@
     
     IChildWidget currentW;
     EnumContent content;
+    
+    bool isWS, isHS;	// no infrastructure for changing sizability, so need to fix it.
 }