Changeset 179:1f9d00f392bd

Show
Ignore:
Timestamp:
09/15/09 14:09:59 (3 years ago)
Author:
Diggory Hardy <diggory.hardy@gmail.com>
Tags:

tip

branch:
default
Message:

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.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • codeDoc/jobs.txt

    r177 r179  
    44 
    55In progress: 
    6 Optional context menus don't always show/hide properly. 
     6Investigating what happens when IServiceContent.setContent is called. 
     7 
    78Having setContent recusively call on subWidgets is not quite right: where the addContent function was used to pass a different content, the content should not be reset by a content() call propegated from a parent. 
    8 Why is ServiceContent.opCall() called in addition to call from CollapsibleWidget? 
    9 Why is ServiceContentList.opCall() not called? Probably because it's callbacks are never called. 
    109 
    1110 
     
    1312To do (importance 0-5: 0 pointless, 1 no obvious impact now, 2 todo sometime, 3 useful, 4 important, 5 urgent): 
    1413Also search for FIXME/NOTE/BUG/WARNING comment marks. 
     145   Context menu callbacks (actions) sometimes are sometimes called when opening the context menu. 
    15154   Move createWidget code out of WidgetManager. 
     164   Make GridLayoutWidget decrease size when no cols/rows are resizable and min-size reduces (to make optional context menu items disappear completely when not available). 
    16173   Make clickEvent only for down-clicks? 
    17183   RequestRedraw should become a function of the renderer. 
  • mde/content/Content.d

    r170 r179  
    127127     * --- */ 
    128128    final void endEvent () { 
    129     foreach (dg; cb) 
     129    foreach (dg; cb) { 
     130        debug logger.trace ("calling callback {}", dg.ptr); 
    130131        dg (this); 
     132    } 
    131133    } 
    132134     
  • mde/content/ServiceContent.d

    r173 r179  
    3434} 
    3535 
    36 /** Interface for ServiceContent and ServiceContentList. */ 
     36/** Interface for ServiceContent and ServiceContentList. 
     37 * 
     38 * When the value changes, needs to call callbacks from collapsible widgets and 
     39 * the like, to show/hide the button. 
     40 *  
     41 * When ServiceContent buttons are pressed, they need to call event callbacks, 
     42 * doing the service. */ 
    3743interface IServiceContent : IContent { 
    3844    void setContent (Content cont); 
     
    5763    T oCont = activeCont; 
    5864    activeCont = cast(T)cont; 
    59     if ((oCont !is null) != (activeCont !is null)) 
     65    if ((oCont !is null) != (activeCont !is null)) { 
     66        logger.trace ("00"); 
    6067        endEvent; 
     68        logger.trace ("01"); 
     69    } 
    6170    } 
    6271     
     
    8190    this (char[] symbol) { 
    8291    super (symbol); 
     92    foreach (child; list_) { 
     93        if ((cast(IBoolContent)child)()) { 
     94        v = true; 
     95        break; 
     96        } 
     97    } 
     98    endEvent; 
    8399    } 
    84100     
     
    87103        (cast(IServiceContent)child).setContent (cont); 
    88104    } 
     105    bool ov = v; 
     106    v = false; 
     107    foreach (child; list_) { 
     108        if ((cast(IBoolContent)child)()) { 
     109        v = true; 
     110        break; 
     111        } 
     112    } 
     113    if (v != ov) { 
     114        debug logger.trace ("ServiceContentList.endEvent"); 
     115        endEvent; 
     116    } 
    89117    } 
    90118     
     
    92120    assert (cast(IBoolContent) x, "Only IBoolContent children are allowed!"); 
    93121    list_ ~= x; 
    94     x.addCallback (&childChangeCB); 
     122    //NOTE: this should only ever be changed when setContent is called and after creation 
     123    //x.addCallback (&childChangeCB); 
    95124    } 
    96125     
    97126    override bool opCall () { 
    98     debug logger.trace ("ServiceContentList.opCall"); 
     127    debug logger.trace ("ServiceContentList.opCall: {}", symbol); 
    99128    return v; 
    100129    } 
     
    118147        debug assert (cast(AStringService)c); 
    119148        with (cast(AStringService)c) { 
    120         if (activeCont !is null) 
     149        if (activeCont !is null) { 
    121150            clipboard = activeCont.toString(0); 
     151            debug logger.trace ("set clipboard to \"{}\"", clipboard); 
     152        } 
    122153        } 
    123154    }); 
     
    125156        debug assert (cast(AStringService)c); 
    126157        with (cast(AStringService)c) { 
    127         if (activeCont !is null) 
     158        if (activeCont !is null) { 
    128159            activeCont = clipboard; 
     160            debug logger.trace ("assigned from clipboard: \"{}\"", activeCont.toString(0)); 
     161        } 
    129162        } 
    130163    }); 
     
    149182     
    150183private: 
     184    /+NOTE: trying a different method 
    151185    void childChangeCB (IContent icont) { 
    152186    if (v == false) {   // then value changes iff icont() 
     
    167201        endEvent; 
    168202    } 
    169     } 
     203    }+/ 
    170204     
    171205    bool v = false; // cache value so we can see when it changes 
  • mde/gui/widget/AParentWidget.d

    r177 r179  
    9090    // They must at a minimum make sure widget's size is at least nmw by nmh. 
    9191    public  override void minWChange (IChildWidget widget, wdim nmw) { 
    92     if (widget.width < nmw) 
     92    if (!widget.isWSizable || widget.width < nmw) 
    9393        widget.setWidth (nmw, -1); 
    9494    } 
    9595    public override void minHChange (IChildWidget widget, wdim nmh) { 
    96     if (widget.height < nmh) 
     96    if (!widget.isHSizable || widget.height < nmh) 
    9797        widget.setHeight (nmh, -1); 
    9898    } 
  • mde/gui/widget/Ifaces.d

    r177 r179  
    107107     * changes, since they cannot properly resize themselves. 
    108108     *  
    109      * Parents $(I must) increase their child's size if the child is too small. 
     109     * Parents $(I must) increase their child's size if the child is too small, 
     110     * and if the child is not resizable, shrink if too big (except for reasons 
     111     * like alignment within a grid). 
     112     *  
    110113     * Parents $(I must not) change their own size, even if they are not 
    111114     * sizable; they may only change their childrens' sizes if it does not 
  • mde/gui/widget/ParentContent.d

    r177 r179  
    209209        parent.minWChange (this, nmw); 
    210210    } else {    // changes won't be seen, but we must follow function spec 
    211         if (widget.width < nmw) 
     211        if (!widget.isWSizable || widget.width < nmw) 
    212212        widget.setWidth (nmw, -1); 
    213213    } 
     
    218218        parent.minHChange (this, nmh); 
    219219    } else { 
    220         if (widget.height < nmh) 
     220        if (!widget.isHSizable || widget.height < nmh) 
    221221        widget.setHeight (nmh, -1); 
    222222    } 
     
    337337    } 
    338338    override void minHChange (IChildWidget widget, wdim nmh) { 
    339         debug assert (widget is subWidgets[0]); 
     339   debug assert (widget is subWidgets[0]); 
    340340    if (display) { 
    341341        mh = nmh; 
     
    387387    if (display == content_()) return; 
    388388        display = content_(); 
    389     logger.trace ("{}.cbDisplay ({})", id, display); 
    390         if (display) { 
     389    if (display) { 
    391390            mw = subWidgets[0].minWidth; 
    392391            mh = subWidgets[0].minHeight; 
     
    396395        parent.minWChange (this, mw); 
    397396        parent.minHChange (this, mh); 
    398         if (!display) return; 
     397   if (!display) return; 
    399398        // set incase parent didn't: 
    400399        subWidgets[0].setWidth (w, -1); 
  • mde/gui/widget/WidgetManager.d

    r177 r179  
    146146    } 
    147147        mw = nmw; 
    148         if (w < nmw) { 
    149             childRoot.setWidth (nmw, -1); 
    150             w = nmw; 
    151         } 
     148    matchMinimalSize (); 
     149    nmw = w;    // reuse to see if width is changed 
     150    w = mw > sW ? mw : sW; 
     151    if (w != nmw) 
     152        childRoot.setWidth  (w, -1); 
    152153        childRoot.setPosition (0,0); 
    153154        requestRedraw; 
     
    160161    } 
    161162        mh = nmh; 
    162         if (h < nmh) { 
    163             childRoot.setHeight (nmh, -1); 
    164             h = nmh; 
    165         } 
     163    matchMinimalSize (); 
     164    nmh = h; 
     165    h = mh > sH ? mh : sH; 
     166    if (h != nmh) 
     167        childRoot.setHeight (nmh, -1); 
    166168        childRoot.setPosition (0,0); 
    167169        requestRedraw; 
     
    373375         
    374376        debug (mdeWidgets) logger.trace ("Setting size and position of root widget..."); 
    375         childRoot.setWidth  (w, -1); 
     377    w = mw > sW ? mw : sW; 
     378    h = mh > sH ? mh : sH; 
     379    childRoot.setWidth  (w, -1); 
    376380        childRoot.setHeight (h, -1); 
    377381        childRoot.setPosition (0,0); 
     
    386390     
    387391    final void wmSizeEvent (int nw, int nh) { 
    388         w = cast(wdim) nw; 
    389         h = cast(wdim) nh; 
     392        sW = cast(wdim) nw; 
     393        sH = cast(wdim) nh; 
    390394        matchMinimalSize; 
    391395         
    392396        if (!childRoot) return;     // if not created yet. 
    393         childRoot.setWidth  (w, -1); 
    394         childRoot.setHeight (h, -1); 
     397    if (sW != w && w != mw) { 
     398        w = mw > sW ? mw : sW; 
     399        childRoot.setWidth  (w, -1); 
     400    } 
     401    if (sH != h && h != mh) { 
     402        h = mh > sH ? mh : sH; 
     403        childRoot.setHeight (h, -1); 
     404    } 
    395405        childRoot.setPosition (0,0); 
    396406    debug logWidgetSize (null); 
     
    476486        underMouse = getPopupWidget (cx, cy, closePopup); 
    477487        if (underMouse is null) { 
    478             debug assert (childRoot.onSelf (cx, cy), "WidgetManager: childRoot doesn't cover whole area"); 
     488        // Note: I'm surprised this never fails, since clicks outside the 
     489        // window are reported. If it does, better allow underMouse to be 
     490        // null. 
     491            debug assert (childRoot.onSelf (cx, cy), "WidgetManager: click not on childRoot"); 
    479492            underMouse = childRoot.getWidget (cx, cy); 
    480493        } 
     
    489502     
    490503    /** If possible, the screen-interaction derived class should override to 
    491      * make sure the window is at least (mw,mh) in size. In any case, this 
    492      * method MUST make sure w >= mw and h >= mh even if the window isn't this 
    493      * big. 
     504     * make sure the window is at least (mw,mh) in size (use sW, sH to store 
     505     * the actual size). 
    494506     *  
    495      * A resize may not be required when this is called, however. */ 
     507     * A resize won't always be required when this is called. */ 
    496508    void matchMinimalSize () { 
    497     if (w < mw) { 
    498         logger.warn ("Min width for gui, {}, not met: {}", mw, w); 
    499         w = mw; 
    500     } 
    501     if (h < mh) { 
    502         logger.warn ("Min height for gui, {}, not met: {}", mh, h); 
    503         h = mh; 
    504     } 
     509    if (sW < mw) 
     510        logger.warn ("Min width for gui, {}, not met: {}", mw, sW); 
     511    if (sH < mh) 
     512        logger.warn ("Min height for gui, {}, not met: {}", mh, sH); 
    505513    } 
    506514     
     
    622630    wdim w,h;               // current widget size; should be at least (mw,mh) even if not displayable 
    623631    wdim mw,mh;             // minimal area required by widgets 
     632    wdim sW,sH;             // actual screen size; ideally equal to w,h 
    624633    uint setupN;            // n to pass to IChildWidget.setup 
    625634     
  • mde/gui/widget/layout.d

    r177 r179  
    639639     * 
    640640     * returns: 
    641      * -i if in space to left of col i, or i if on col i. */ 
     641     * -i if in space to left of col i, or i if on col i. 
     642     *  
     643     * Handles l right-of-last-column fine, asserts if l < pos[0]. */ 
    642644    ptrdiff_t getCell (wdim l) { 
    643645        debug assert (width, "AlignColumns not initialized when getCell called (code error)"); 
     
    668670         
    669671        wdim diff = nw - w; 
    670         if (firstSizable == -1) 
    671             diff = adjustCellSizes (diff, cols-1, -1); 
    672         else 
    673             diff = adjustCellSizes (diff, (dir == -1 ? lastSizable : firstSizable), dir); 
     672    if (diff > 0) { 
     673        if (firstSizable == -1) 
     674        diff = adjustCellSizes (diff, cols-1, -1); 
     675        else 
     676        diff = adjustCellSizes (diff, (dir == -1 ? lastSizable : firstSizable), dir); 
     677        debug assert (diff == 0); 
     678    } else { 
     679        // For decreasing, visit all cols; it's possible some have size above minimal 
     680        diff = adjustCellSizes (diff, (dir == -1 ? cols-1 : 0), dir); 
     681        debug if (diff != 0) 
     682        logger.warn ("Unable to meet target width ({}); outstanding diff: {}", nw, diff); 
     683    } 
    674684        genPositions; 
    675685         
    676686        debug if (nw != w) { 
    677             logger.trace ("resizeWidth on {} to {} failed, new width: {}, diff {}, firstSizable {}, columns {}",cast(void*)this, nw,w, diff, firstSizable, cols); 
     687            logger.error ("resizeWidth on {} to {} failed, new width: {}, diff {}, firstSizable {}, columns {}",cast(void*)this, nw,w, diff, firstSizable, cols); 
    678688            /+ Also print column widths & positions: 
    679             logger.trace ("resizeWidth to {} failed! Column dimensions and positions:",nw); 
     689            logger.error ("resizeWidth to {} failed! Column dimensions and positions:",nw); 
    680690            foreach (i,w; width) 
    681                 logger.trace ("\t{}\t{}", w,pos[i]);+/ 
     691                logger.error ("\t{}\t{}", w,pos[i]);+/ 
    682692        } 
    683693        return w; 
     
    689699    bool findResizeCols (wdim l) { 
    690700        resizeU = -getCell (l);             // potential start for upward-resizes 
    691         if (resizeU <= 0) 
    692             return true;        // not on a space between cells 
     701    if (resizeU <= 0) 
     702        return true;        // not on a space between cells 
     703    if (resizeU >= cols) {      // right of last column; cannot resize 
     704        resizeU = -1; 
     705        return true; 
     706    } 
    693707        resizeD = resizeU - 1;              // potential start for downward-resizes 
    694708         
     
    718732        // do shrinking first (in case we hit the minimum) 
    719733        if (diff >= 0) { 
    720             diff = -adjustCellSizes (-diff, resizeU, 1)
    721             adjustCellSizes (diff, resizeD, -1); 
     734            diff = adjustCellSizes (-diff, resizeU, 1) - diff
     735            diff = adjustCellSizes (diff, resizeD, -1); 
    722736        } else { 
    723             diff = -adjustCellSizes (diff, resizeD, -1); 
    724             adjustCellSizes (diff, resizeU, 1); 
    725         } 
     737            diff = adjustCellSizes (diff, resizeD, -1) - diff; 
     738            diff = adjustCellSizes (diff, resizeU, 1); 
     739        } 
     740    debug assert (diff == 0); 
    726741        genPositions; 
    727742    } 
     
    752767                return false; 
    753768            minWidth[col] = nmw; 
    754             if (!sizable[col] && lastSizable >= 0) 
    755                 nd = width[col] - nmw;  // Not resizable but another column is 
    756             // Else leave larger; mustn't shrink ourself 
    757         } else 
    758             return false; 
    759          
     769            if (!sizable[col]) 
     770                nd = width[col] - nmw;  // Not resizable, so shrink 
     771            // Else resizable so leave 
     772        } 
    760773        mw = spacing * cast(wdim)(cols - 1); 
    761774        foreach (imw; minWidth) 
    762775            mw += imw; 
    763776         
    764         if (nd != 0) {  // needs enlarging or shrinking 
     777    if (nd == 0) 
     778        return false; 
     779     
     780    if (nd < 0) {   // needs enlarging; we should do so here 
     781        // set new width: 
    765782            width[col] = nmw; 
    766783            foreach (cb; cbs) 
    767784                cb.setWidth (col, nmw, -1); 
    768             if (lastSizable >= 0) 
    769                 adjustCellSizes (nd, lastSizable, -1); 
    770         } 
    771          
     785        // Try to compensate (keep overall size the same by shrinking larger 
     786        // than necessary columns); may not be possible: 
     787            adjustCellSizes (nd, 0, 1); 
     788        } else if (lastSizable >= 0) { 
     789        // If another column can be increased, do that (otherwise the call 
     790        // to parent.minXChange should decrease, if possible): 
     791        // Although it _may_ not, if e.g. alignment forces larger-than-minimal size. 
     792        width[col] = nmw; 
     793        foreach (cb; cbs) 
     794        cb.setWidth (col, nmw, -1); 
     795        nd = adjustCellSizes (nd, lastSizable, -1); 
     796        debug assert (nd == 0); 
     797    } 
     798    //else debug logger.trace ("expecting parent.minXChange to shrink"); 
     799     
    772800        debug wdim ow = w; 
    773801        genPositions; 
     
    801829    * 
    802830    * Returns: 
    803     *  The amount adjusted. This may be larger than diff, since cellD is clamped by cellDMin. 
     831    *  (diff - "the actual amount adjusted") - 0 if met exactly, <0 if unable 
     832    * to shrink as much as requested. 
    804833    * 
    805834    * Will shrink non-sizable columns if they're over minimal size. 
     
    822851            foreach (cb; cbs) 
    823852                cb.setWidth (i, width[i], incr); 
     853        return 0; 
    824854        } 
    825855        else if (diff < 0) {        // decrease 
     
    844874                i += incr; 
    845875            } 
    846             diff -= rd; // still had rd left to decrease (may be 0) 
     876            return rd; // still had rd left to decrease (may be 0) 
    847877        } 
    848878        // else no adjustment needed (diff == 0) 
    849          
    850         return diff; 
     879        return 0; 
    851880    } 
    852881