Changeset 92:085f2ca31914

Show
Ignore:
Timestamp:
10/21/08 04:57:19 (3 months ago)
Author:
Diggory Hardy <diggory.hardy@gmail.com>
branch:
default
Message:

Shared alignments supported in more complex cases.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • data/conf/gui.mtt

    r91 r92  
    88<WidgetData|button={0:[0x10,50,50]}> 
    99<WidgetData|blank={0:[0x2]}> 
    10 <WidgetData|opts={0:[0x8110,0],1:["optBox"]}> 
     10<WidgetData|opts={0:[0x8110,0],1:["optDBox"]}> 
     11<WidgetData|optDBox={0:[0xC100,0,2,1],1:["optBox","optDesc"]}> 
    1112<WidgetData|optBox={0:[0xC100,1,1,3],1:["optName","optSep","optVal"]}> 
    1213<WidgetData|optName={0:[0x4020, 1, 0xfe8c00]}> 
     14<WidgetData|optDesc={0:[0x4020, 2, 0xaf6000]}> 
    1315<WidgetData|optVal={0:[0x4020, 0, 0xBF00]}> 
    1416<WidgetData|optSep={0:[0x21, 0xff],1:["="]}> 
  • data/conf/options.mtt

    r91 r92  
    66<int|logOptions=0x3000> 
    77<double|pollInterval=0.01> 
    8 <char[]|a="tildb\naeouc\ngpqyg"> 
    9 <char[]|b="tildb"> 
    10 <char[]|c="aeouc"> 
    11 <char[]|g="gpqy"> 
    12 <char[]|z="fghijklpq"> 
    138 
    149{font} 
  • mde/gui/WidgetManager.d

    r91 r92  
    6363    } 
    6464     
    65     // NOTE - temporarily here to allow CTOR to run safely during static this 
    66     // called during init 
     65    // this() runs during static this(), when imde.input doesn't exist. init() runs later. 
    6766    void init () { 
    6867        // Doesn't need a lock - cannot conflict with other class functions. 
     
    171170         
    172171        child = makeWidget ("root"); 
     172        finalize; 
    173173         
    174174        mw = child.minWidth; 
     
    385385     * 
    386386     * A widget instance is created from data found under ID. Multiple instances may be created. 
    387      * FIXME - data conflicts when saving? 
     387     * NOTE - data conflicts when saving? 
    388388     * 
    389389     * An IContent may be passed. This could contain many things, e.g. some basic data, a widget, 
     
    395395    } 
    396396     
     397    /** Runs finalize for all descendants, in a deepest first order. */ 
     398    /* NOTE: The way this function works may seem a little odd, but it's designed to allow 
     399     * shared alignments to be initialized properly: 
     400     * 1. all sharing members need to know their children's min size 
     401     * 2. all sharing members need to add their children's min size to the alignment 
     402     * 3. all sharing members can only then get their min size 
     403     * This method will fail if alignment members are not all of the same generation. An alternate 
     404     * method without this drawback would be to have shared alignments created with a list of 
     405     * pointers to their members, and once all members have been created the alignment could 
     406     * initialize itself, first making sure each members' children have been initialized. */ 
     407    void finalize () { 
     408        IChildWidget[][] descendants;   // first index: depth; is a list of widgets at each depth 
     409         
     410        void recurseChildren (size_t depth, IChildWidget widget) { 
     411            foreach (child; widget.children) 
     412                recurseChildren (depth+1, child); 
     413             
     414            if (descendants.length <= depth) 
     415                descendants.length = depth * 2 + 1; 
     416            descendants[depth] ~= widget; 
     417        } 
     418         
     419        recurseChildren (0, child); 
     420        foreach_reverse (generation; descendants) { 
     421            foreach (widget; generation) 
     422                widget.prefinalize; 
     423            foreach (widget; generation) 
     424                widget.finalize; 
     425        } 
     426    } 
     427     
    397428    /** For making changes. */ 
    398429    void setData (widgetID id, WidgetData d) { 
     
    406437    * // 1. Create the root widget: 
    407438    * child = makeWidget ("root"); 
     439    * finalize; 
    408440    * // 2. Set the setSize, e.g.: 
    409441    * child.setWidth  (child.minWidth,  1); 
  • mde/gui/widget/Floating.d

    r91 r92  
    5454 * additionally an (x,y) coordinate for each subwidget (all x coords first, then all y coords). 
    5555 */ 
    56 class FloatingAreaWidget : SizableWidget 
     56class FloatingAreaWidget : ParentWidget 
    5757{ 
    5858    this (IWidgetManager mgr, widgetID id, WidgetData data) { 
     
    6060        foreach (i,s; data.strings) 
    6161            subWidgets[i] = mgr.makeWidget (s); 
     62        foreach (w; subWidgets) 
     63            w.finalize; 
    6264        sWCoords.length = subWidgets.length; 
    6365         
     
    8183    } 
    8284     
     85    bool isWSizable () {    return true;    } 
     86    bool isHSizable () {    return true;    } 
     87     
    8388    void setPosition (wdim x, wdim y) { 
    8489        super.setPosition (x,y); 
     
    98103     
    99104protected: 
    100     IChildWidget[] subWidgets;  // all subwidgets, framed or not 
    101105    wdimPair[] sWCoords;        // coords for subwidgets, relative to this widget 
    102106     
  • mde/gui/widget/Ifaces.d

    r91 r92  
    136136 * satisfy their minimal sizes as available from minWidth() and minHeight(). setWidth() and 
    137137 * setHeight() are called on all widgets after creation. 
     138 *  
     139 * Also see finalize(). 
    138140 *************************************************************************************************/ 
    139141//NOTE: add another this() without the data for default initialization, for the GUI editor? 
     
    141143{ 
    142144//BEGIN Load and save 
     145    // NOTE - change? 
     146    /** Called on all widgets after all widgets have been created in a deepest first order. 
     147     * 
     148     * Must be called before any other methods on the widget, which means this cannot call sub- 
     149     * widgets' methods, but finalize can. */ 
     150    void prefinalize (); 
     151    void finalize ();   /// ditto 
     152     
     153    /** Widget should return a list of all its children. */ 
     154    IChildWidget[] children (); 
     155     
    143156    /** When this is called, if the widget has any changed data to save it should call 
    144157     * IWidgetManager.setData (id, data) to set it and return true. Otherwise it should return 
     
    178191    /** The minimal size the widget could be shrunk to (or its fixed size). 
    179192     * 
    180      * Takes into account child-widgets and any other contents. 
    181      *  
    182      * Note: layout uses these calls to initialize it's alignment device. So, after creating a 
    183      * (layout) widget, minWidth should be the first function called on it! */ 
     193     * Takes into account child-widgets and any other contents. */ 
    184194    wdim minWidth (); 
    185195    wdim minHeight ();  /// ditto 
  • mde/gui/widget/Widget.d

    r91 r92  
    5050    } 
    5151     
     52    // Most widgets don't need this; all initialization os usually done in this() 
     53    void prefinalize () {} 
     54    void finalize () {} 
     55     
     56    // ParentWidget is inteded for parent widgets to derive 
     57    IChildWidget[] children () { 
     58        return null; 
     59    } 
     60     
    5261    // Don't save any data: fine for many widgets. 
     62    // FIXME: implementation could be added to ParentWidget 
    5363    bool saveChanges (widgetID) { 
    5464        return false; 
     
    142152} 
    143153 
     154/************************************************************************************************* 
     155* An abstract base widget class for parent widgets. 
     156*************************************************************************************************/ 
     157abstract class ParentWidget : Widget 
     158{ 
     159    this (IWidgetManager mgr, widgetID id, WidgetData data) { 
     160        super (mgr, id, data); 
     161    } 
     162     
     163    IChildWidget[] children () { 
     164        return subWidgets; 
     165    } 
     166     
     167protected: 
     168    IChildWidget[] subWidgets; 
     169} 
     170 
    144171/** A base for fixed-size widgets taking their size from the creation data. */ 
    145172class FixedWidget : Widget { 
  • mde/gui/widget/layout.d

    r91 r92  
    115115        rows = optsList.list.length; 
    116116        cols = 1; 
     117        sWId = data.strings[0]; 
    117118         
    118119        // Get all sub-widgets 
    119120        subWidgets.length = rows*cols; 
    120121        foreach (i, c; optsList.list) { 
    121             subWidgets[i] = mgr.makeWidget (data.strings[0], c); 
     122            subWidgets[i] = mgr.makeWidget (sWId, c); 
    122123        } 
    123124        super (mgr, id, data); 
     125    } 
     126     
     127    bool saveChanges (widgetID id) { 
     128        // Since all sub-widgets have the same id, it only makes sense to call on one 
     129        if (subWidgets is null) 
     130            return false; 
     131        return subWidgets[0].saveChanges (sWId); 
    124132    } 
    125133     
    126134private: 
    127135    OptionList optsList; 
     136    widgetID sWId;      // sub-widget's ID, for calling saveChanges FIXME no longer pass? 
    128137} 
    129138 
     
    139148 * The grid has no border but has spacing between widgets. 
    140149 *************************************************************************************************/ 
    141 abstract class GridWidget : Widget 
     150abstract class GridWidget : ParentWidget 
    142151{ 
    143152    //BEGIN Creation & saving 
     
    149158     *  
    150159     * Derived constructors may also set initWidths to the array of column widths followed by 
    151      * row heights used to initially set the row/column dimensions. */ 
     160     * row heights used to initially set the row/column dimensions. 
     161     *  
     162     * Sub-widgets are finalized here, so no methods should be called on sub-widgets before calling 
     163     * this super. */ 
    152164    protected this (IWidgetManager mgr, widgetID id, WidgetData data) { 
    153165        super (mgr, id, data); 
     
    164176            row = (new AlignColumns (rows)); 
    165177        row.addSetCallback (&setRowHeight); 
    166          
    167         // Calculate cached construction data 
    168         genCachedConstructionData; 
     178    } 
     179     
     180    /** Prior to finalizing but after sub-widgets are finalized, some information needs to be 
     181     * passed to the AlignColumns. */ 
     182    void prefinalize () { 
     183        genCachedConstructionData;  // min widths, sizableness 
    169184    } 
    170185     
     
    172187     * 
    173188     * As such, this must be the first function called after this(). */ 
    174     wdim minWidth () { 
    175         if (!alignInit) {       // assumes col & row.width are initialized simultaneously 
    176             alignInit = true; 
    177             if (initWidths) { 
    178                 debug assert (initWidths.length == cols + rows, "initWidths provided but has bad length"); 
    179                 col.setWidths (initWidths[0..cols]); 
    180                 row.setWidths (initWidths[cols..$]); 
    181                 initWidths = null;  // free 
    182             } else { 
    183                 col.setWidths; 
    184                 row.setWidths; 
    185             } 
    186              
    187             mw = col.mw; 
    188             mh = row.mw; 
    189             w = col.w; 
    190             h = row.w; 
    191              
    192             // Tell subwidgets their new sizes. Positions are given by a later call to setPosition. 
    193             foreach (i,widget; subWidgets) { 
    194                 // Resizing direction is arbitrarily set to negative: 
    195                 widget.setWidth  (col.width[i % cols], -1); 
    196                 widget.setHeight (row.width[i / cols], -1); 
    197             } 
    198         } 
    199         return mw; 
     189    void finalize () { 
     190        if (initWidths) { 
     191            debug assert (initWidths.length == cols + rows, "initWidths provided but has bad length"); 
     192            col.setWidths (initWidths[0..cols]); 
     193            row.setWidths (initWidths[cols..$]); 
     194            initWidths = null;  // free 
     195        } else { 
     196            col.setWidths; 
     197            row.setWidths; 
     198        } 
     199         
     200        mw = col.mw; 
     201        mh = row.mw; 
     202        w = col.w; 
     203        h = row.w; 
     204         
     205        // Tell subwidgets their new sizes. Positions are given by a later call to setPosition. 
     206        foreach (i,widget; subWidgets) { 
     207            // Resizing direction is arbitrarily set to negative: 
     208            widget.setWidth  (col.width[i % cols], -1); 
     209            widget.setHeight (row.width[i / cols], -1); 
     210        } 
    200211    } 
    201212    //END Creation & saving 
     
    280291     * 
    281292     * rows, cols and subWidgets must be set before calling. Part of the set-up for AlignColumns 
    282      * (col and row). */ 
     293     * (col and row). subWidgets need to know their minimal size and resizability. */ 
    283294    void genCachedConstructionData () { 
    284295        // Will only change if renderer changes: 
     296        // NOTE shared AlignColumns get this set by all sharing GridWidgets 
    285297        col.spacing = row.spacing = mgr.renderer.layoutSpacing; 
    286298         
     
    362374    myIt cols, rows;    // number of cells in grid 
    363375    wdim[] initWidths;  // see this / setInitialSize 
    364     bool alignInit;     // have AlignColumns instances been initialized? 
    365376     
    366377    /* All widgets in the grid, by row. Order:  [ 0 1 ] 
    367378     *                                          [ 2 3 ] */ 
    368     IChildWidget[] subWidgets; 
     379    //IChildWidget[] subWidgets; 
    369380     
    370381    AlignColumns col, row;