Changeset 7

Show
Ignore:
Timestamp:
11/15/06 10:43:56 (2 years ago)
Author:
baxissimo
Message:

Numerous improvements. Checkbox works now.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/luigi/adaptor/base.d

    r6 r7  
    3030import sslot.signal; 
    3131import luigi.base; 
    32  
    33 /** WindowHandle is just an opaque piece of data used to identify 
    34    windows on the underlying windowing system.  It could be an int for 
    35    GLUT, or an HWND for Win32, etc. 
    36 */ 
    37 typedef void* WindowHandle; 
    38  
    39 enum KeyMods { 
    40     None = 0, 
    41     Ctrl  = 0x1, CtrlBit  = 1, 
    42     Shift = 0x2, ShiftBit = 2, 
    43     Alt   = 0x4, AltBit   = 3 
    44 }; 
    45  
    46 char[] toString(KeyMods k) { 
    47     alias KeyMods e; 
    48     char [] ret; 
    49     if (k & e.Shift) { ret ~= "Shift"; } 
    50     if (k & e.Ctrl)  { if (ret) ret~="|"; ret ~= "Ctrl"; } 
    51     if (k & e.Alt)   { if (ret) ret~="|"; ret ~= "Alt"; } 
    52     if (!ret) ret = "None"; 
    53     return ret; 
    54 
    55  
    56 enum MouseButtons { 
    57     None = 0, 
    58     Left  = 0x1,    LeftBit = 1, 
    59     Right = 0x2,    RightBit = 2, 
    60     Middle = 0x4,   MiddleBit = 3, 
    61     Button0 = Left,   Button0Bit = 1, 
    62     Button1 = Right,  Button1Bit = 2, 
    63     Button2 = Middle, Button2Bit = 3, 
    64     Button3 = 0x8,    Button3Bit = 4, 
    65     Button4 = 0x10,   Button4Bit = 5, 
    66     Button5 = 0x20,   Button5Bit = 6 
    67 }; 
    68  
    69 char[] toString(MouseButtons b) { 
    70     alias MouseButtons e; 
    71     char[] ret; 
    72     if (b & e.Left)   { ret ~= "Left"; } 
    73     if (b & e.Middle) { if (ret) ret~="|"; ret ~= "Middle"; } 
    74     if (b & e.Right)  { if (ret) ret~="|"; ret ~= "Right"; }  
    75     if (b & e.Button3){ if (ret) ret~="|"; ret ~= "Button3"; } 
    76     if (b & e.Button4) { if (ret) ret~="|"; ret ~= "Button4"; } 
    77     if (b & e.Button5) { if (ret) ret~="|"; ret ~= "Button5"; } 
    78     if (!ret) ret = "None"; 
    79     return ret; 
    80 
    81  
    82 enum Key { 
    83     Unknown = -1, 
    84     Space = 32, 
    85     Special = 256, 
    86     Escape, 
    87     F1, 
    88     F2, 
    89     F3,  
    90     F4, 
    91     F5, 
    92     F6, 
    93     F7, 
    94     F8, 
    95     F9, 
    96     F10, 
    97     F11, 
    98     F12, 
    99     F13, 
    100     F14, 
    101     F15, 
    102     F16, 
    103     F17, 
    104     F18, 
    105     F19, 
    106     F20, 
    107     F21, 
    108     F22, 
    109     F23, 
    110     F24, 
    111     F25, 
    112     Up, 
    113     Down, 
    114     Left, 
    115     Right, 
    116     LShift,  Shift = LShift, 
    117     RShift, 
    118     LCtrl,   Ctrl = LCtrl, 
    119     RCtrl, 
    120     LAlt,    Alt = LAlt, 
    121     RAlt, 
    122     Tab, 
    123     Enter, 
    124     Backspace, 
    125     Insert, 
    126     Del, 
    127     PageUp, 
    128     PageDown, 
    129     Home, 
    130     End, 
    131     KP_0, 
    132     KP_1, 
    133     KP_2, 
    134     KP_3, 
    135     KP_4, 
    136     KP_5, 
    137     KP_6, 
    138     KP_7, 
    139     KP_8, 
    140     KP_9, 
    141     KP_Divide, 
    142     KP_Multiply, 
    143     KP_Subtract, 
    144     KP_Add, 
    145     KP_Decimal, 
    146     KP_Equal, 
    147     KP_Enter, 
    148 
    149  
    150  
    151  
    152 enum EventStatus { 
    153     Alive = 0, 
    154     Dead = 1, 
    155  
    156     OK = 0, 
    157     Abort = 1, 
    158 
    159  
    160 struct KeyEvent 
    161 
    162     union { 
    163         Point p; 
    164         struct { float x,y; } 
    165     } 
    166     union {  
    167         Point winp; 
    168         struct { float winx,winy; } 
    169     } 
    170     bool is_press; 
    171     bool is_release() { return !is_press; } 
    172     int key; // an ascii char (uppercase) or enum Key 
    173     dchar ch; 
    174     KeyMods mods; 
    175 
    176  
    177 struct MouseButtonEvent 
    178 
    179     union { 
    180         Point p; 
    181         struct { float x,y; } 
    182     } 
    183     union {  
    184         Point winp; 
    185         struct { float winx,winy; } 
    186     } 
    187     bool is_press; // otherwise release 
    188     bool is_release() { return !is_press; } 
    189     MouseButtons button; 
    190     MouseButtons pressed; 
    191     KeyMods mods; 
    192 
    193  
    194 struct MouseMoveEvent 
    195 
    196     union { 
    197         Point p; 
    198         struct { float x,y; } 
    199     } 
    200     union {  
    201         Point winp; 
    202         struct { float winx,winy; } 
    203     } 
    204     MouseButtons pressed; 
    205     KeyMods mods; 
    206 
    207  
    208 struct MouseWheelEvent 
    209 
    210     union { 
    211         Point p; 
    212         struct { float x,y; } 
    213     } 
    214     union {  
    215         Point winp; 
    216         struct { float winx,winy; } 
    217     } 
    218     int delta; 
    219     MouseButtons pressed; 
    220     KeyMods mods; 
    221 
    222  
    223 struct WindowSizeEvent 
    224 
    225     WindowHandle id; 
    226     float width,height; 
    227     alias width w; 
    228     alias height h; 
    229 
    230  
    231 struct WindowCloseEvent 
    232 
    233     WindowHandle id; 
    234 
    235  
    236 // how do I do this??? 
    237 /// extern luigi.gui.Widget; 
    238  
    239 struct FocusEvent 
    240 
    241     Object previous; 
    242 
    243  
    244  
    245 alias int function(KeyEvent)         KeyEventFn; 
    246 alias int function(MouseButtonEvent) MouseButtonEventFn; 
    247 alias int function(MouseMoveEvent)   MouseMoveEventFn; 
    248 alias int function(MouseWheelEvent)  MouseWheelEventFn; 
    249 alias int function(WindowSizeEvent)  WindowSizeEventFn; 
    250 alias int function(WindowCloseEvent) WindowCloseEventFn; 
    251  
    252 alias int delegate(KeyEvent)         KeyEventDg; 
    253 alias int delegate(MouseButtonEvent) MouseButtonEventDg; 
    254 alias int delegate(MouseMoveEvent)   MouseMoveEventDg; 
    255 alias int delegate(MouseWheelEvent)  MouseWheelEventDg; 
    256 alias int delegate(WindowSizeEvent)  WindowSizeEventDg; 
    257 alias int delegate(WindowCloseEvent) WindowCloseEventDg; 
    258  
    259 alias Signal!(int, KeyEvent)         KeyEventSignal; 
    260 alias Signal!(int, MouseButtonEvent) MouseButtonEventSignal; 
    261 alias Signal!(int, MouseMoveEvent)   MouseMoveEventSignal; 
    262 alias Signal!(int, MouseWheelEvent)  MouseWheelEventSignal; 
    263 alias Signal!(int, WindowSizeEvent)  WindowSizeEventSignal; 
    264 alias Signal!(int, WindowCloseEvent) WindowCloseEventSignal; 
     32import luigi.event; 
    26533 
    26634 
  • trunk/luigi/adaptor/glfw.d

    r6 r7  
    2929 
    3030import luigi.base; 
     31import luigi.event; 
    3132import luigi.adaptor.base; 
    3233import derelict.glfw.glfw; 
     
    8081    case GLFW_KEY_BACKSPACE: return Key.Backspace; 
    8182    case GLFW_KEY_INSERT: return Key.Insert; 
    82     case GLFW_KEY_DEL: return Key.Del
     83    case GLFW_KEY_DEL: return Key.Delete
    8384    case GLFW_KEY_PAGEUP: return Key.PageUp; 
    8485    case GLFW_KEY_PAGEDOWN: return Key.PageDown; 
     
    162163        ev.is_press  = (action==GLFW_PRESS); 
    163164        ev.mods = inst._getMods(); 
     165        ev.is_key = true; 
     166        ev.is_char = false; 
    164167        inst.emit.key(ev); 
    165168    } 
     
    168171        KeyEvent ev; 
    169172        // In practice it seems that char callbacks always come _after_ 
    170         // key callbacks. And you only get one char for one key.  This isn't  
     173        // key callbacks. (That's probably the case for any sane operating system). 
     174        // Also, you only get one char for one key.  This isn't  
    171175        // necessarily the case in general with fancy input methods  
    172176        // (e.g. european and asian) but it seems to be the case with GLFW. 
    173         // Not every key has a char, but every char has a key. 
     177        // Not every key has a char, but every char has a key in GLFW 
    174178        ev.key = m_lastKey; 
    175179        ev.ch = ch; 
    176180        ev.is_press  = (action==GLFW_PRESS); 
    177181        ev.mods = inst._getMods(); 
     182        ev.is_key = false; 
     183        ev.is_char = true; 
    178184        inst.emit.key(ev); 
    179185    } 
  • trunk/luigi/arranger.d

    r6 r7  
    66   items to support the Arrangeable interface.  The Arrangeable  
    77   interface just provides information about an item's preferred,  
    8    minimum and maximum sizes. 
     8   and minimum sizes. 
    99 
    1010   Note in many toolkits "arranging" is referred to as "layout". 
     
    6262interface Arrangeable 
    6363{ 
    64     // TODO: make size methods be **width_for_height and **height_for_width? 
    65     // In general, for something like a flow layout, given a width I can  
    66     // tell you how tall I want to be, but absent that I can't say much. 
    67     Size minimum_size(); 
    68     Size maximum_size(); 
    69     Size preferred_size(); 
     64    Size minimum_size(Size bounds); 
     65    Size preferred_size(Size bounds); 
    7066 
    7167    void set_rect(Rect s); 
     
    9692} 
    9793 
     94struct Gaps 
     95{ 
     96    float x=0,y=0; 
     97    bool standard=true; 
     98 
     99    static Gaps opCall(float xgap, float ygap) { 
     100        Gaps g; 
     101        g.standard = false; 
     102        g.x = xgap; 
     103        g.y = ygap; 
     104        return g; 
     105    } 
     106 
     107    static Gaps opCall(float gap) { 
     108        Gaps g; 
     109        g.standard = false; 
     110        g.x = g.y = gap; 
     111        return g; 
     112    } 
     113 
     114    static Gaps opCall() { 
     115        Gaps g; 
     116        g.standard = true; 
     117        g.x = g.y = 0; 
     118        return g; 
     119    } 
     120} 
     121 
     122typedef Gaps Pads; 
     123 
    98124 
    99125//-------------------------------------------------------------------------- 
     
    106132    void set_rect(Rect p); 
    107133 
    108     Size minimum_size(); 
    109     Size preferred_size(); 
    110     Size maximum_size(); 
     134    Size minimum_size(Size bounds); 
     135    Size preferred_size(Size bounds); 
    111136 
    112137    void arrange(); 
     138 
     139    /// Return the natural order (tab order) of the item. 
     140    /// The item should be contained by the given arranger. 
     141    int orderof(Arrangeable item); 
    113142 
    114143    // ArrangeableIterator child_iterator(); 
     
    135164    abstract override void arrange(); 
    136165 
    137     abstract override Size minimum_size(); 
    138     abstract override Size preferred_size(); 
    139  
    140     Size maximum_size() 
    141     { 
    142         return Size(float.max, float.max); 
    143     } 
     166    abstract override Size minimum_size(Size bounds); 
     167    abstract override Size preferred_size(Size bounds); 
     168 
     169    abstract override int orderof(Arrangeable a); 
     170 
    144171    bool auto_add() { return m_auto_add; } 
    145172    bool auto_add(bool v) { return m_auto_add=v; } 
     
    167194    this() 
    168195    { 
    169         this(Alignment.Left|Alignment.Top, DEFAULT_GAP, DEFAULT_GAP); 
     196        this(Alignment.Left|Alignment.Top, Gaps()); 
    170197    } 
    171198         
    172199    this(Alignment align_) 
    173200    {    
    174         this(align_, DEFAULT_GAP, DEFAULT_GAP); 
    175     } 
    176  
    177     this(Alignment align_, float horz_gap, float vert_gap
     201        this(align_, Gaps()); 
     202    } 
     203 
     204    this(Alignment align_, Gaps gaps_
    178205    { 
    179206        this.rect = Rect(0,0,0,0); 
    180207        this.alignment = align_; 
    181         this.xgap = horz_gap; 
    182         this.ygap = vert_gap; 
     208        if (gaps_.standard) { 
     209            gaps_.x = DEFAULT_GAP; 
     210            gaps_.y = DEFAULT_GAP; 
     211        } 
     212        m_gaps = gaps_; 
     213    } 
     214 
     215    override int orderof(Arrangeable item) { 
     216        assert(item !is null); 
     217        int idx = m_items.find_item(item); 
     218        assert(idx != NOT_FOUND); 
     219        return idx; 
    183220    } 
    184221 
     
    201238    } 
    202239 
    203     Size minimum_size(
     240    Size minimum_size(Size bounds
    204241    { 
    205242        return Size(_max_item_width(), _max_item_height()); 
     
    211248        foreach(Arrangeable item; m_items) 
    212249        { 
    213             maxWidth = math.fmax(maxWidth, item.preferred_size.width); 
     250            maxWidth = math.fmax(maxWidth, item.preferred_size(rect.size).width); 
    214251        } 
    215252        return maxWidth; 
     
    221258        foreach(Arrangeable item ; m_items) 
    222259        { 
    223             maxHeight = math.fmax(maxHeight, item.preferred_size.height); 
     260            maxHeight = math.fmax(maxHeight, item.preferred_size(rect.size).height); 
    224261        } 
    225262        return maxHeight; 
    226263    } 
    227264 
    228     override  Size preferred_size() 
    229     { 
    230         float height = 0; 
    231         float width = 0; 
     265    override  Size preferred_size(Size bounds) 
     266    { 
     267        float htotal=0, height = 0; 
     268        float wtotal = 0, width = 0; 
     269        int rows = 0; 
     270         
    232271        foreach(Arrangeable c; m_items) 
    233272        { 
    234             Size s = c.preferred_size(); 
    235             width += s.width; 
    236             height = math.fmax(height, s.height); 
     273            Size s = c.preferred_size(bounds); 
     274            width += s.width + xgap; 
     275            height = max(height, s.height); 
     276            if (width>bounds.width) { 
     277                wtotal = max(wtotal, width-xgap); 
     278                width = 0; 
     279                htotal += height + ygap; 
     280                rows++; 
     281            } 
    237282        } 
    238         width += (m_items.length + 1)*xgap
    239         height += 2*ygap
    240         return Size(width, height); 
     283        htotal += height
     284        wtotal = max(wtotal,width-xgap)
     285        return Size(wtotal, htotal); 
    241286    } 
    242287 
     
    248293        foreach(Arrangeable c ; m_items)  
    249294            { 
    250                 Size s = c.preferred_size(); 
     295                Size s = c.preferred_size(rect.size); 
    251296                currentWidth += s.width + xgap; 
    252297                if(currentWidth > rect.width) 
     
    288333            foreach(FlowRow r; rows)  
    289334                { 
    290                     r.position = Point(rect.x, y); 
     335                    r.position = Point(0, y-rect.y); 
    291336                    r.arrange(); 
    292337                    y += r.size.height + ygap; 
     
    297342                { 
    298343                    float x = rect.x2 - r.size.width; 
    299                     r.position = Point(x, y); 
     344                    r.position = Point(x-rect.x, y-rect.y); 
    300345                    r.arrange(); 
    301346                    y += r.size.height + ygap; 
     
    308353                { 
    309354                    float x = rect.x + (rect.width - r.size.width)/2; 
    310                     r.position = Point(x, y); 
     355                    r.position = Point(x-rect.x, y-rect.y); 
    311356                    r.arrange(); 
    312357                    y += r.size.height + ygap; 
     
    321366 
    322367 
    323     float xgap() { return m_xgap; } 
    324     float xgap(float v) { m_xgap = v; return m_xgap; } 
    325     float ygap() { return m_ygap; } 
    326     float ygap(float v) { m_ygap = v; return m_ygap; } 
     368    float xgap() { return m_gaps.x; } 
     369    float xgap(float v) { m_gaps.x = v; return m_gaps.x; } 
     370    float ygap() { return m_gaps.y; } 
     371    float ygap(float v) { m_gaps.y = v; return m_gaps.y; } 
    327372 
    328373    Alignment alignment() { return m_alignment; } 
     
    334379    Arrangeable[] m_items; 
    335380    Alignment m_alignment; 
    336     float m_xgap; 
    337     float m_ygap; 
    338  
     381    Gaps m_gaps; 
    339382} 
    340383 
     
    366409    { 
    367410        _recalc(); 
    368         float x = rect.x; 
    369         float y = rect.y + (rect.height / 2); 
     411        float x0 = rect.x; 
     412        float y0 = rect.y; 
     413        float x = x0; 
     414        float y = y0 + (rect.height / 2); 
    370415        foreach(Arrangeable item ; m_items) 
    371416            { 
    372                 Size s = item.preferred_size(); 
     417                Size s = item.preferred_size(rect.size); 
    373418                item.set_rect(Rect(x, y-(s.height/2), s.width, s.height)); 
    374419                x += s.width + xgap; 
     
    382427        foreach(Arrangeable item ; m_items) 
    383428            { 
    384                 Size s = item.preferred_size(); 
     429                Size s = item.preferred_size(rect.size); 
    385430                width += s.width; 
    386431            } 
     
    395440        foreach(Arrangeable item ; m_items) 
    396441            { 
    397                 maxHeight = math.fmax(maxHeight, item.preferred_size().height); 
     442                maxHeight = math.fmax(maxHeight, item.preferred_size(rect.size).height); 
    398443            } 
    399444        return maxHeight; 
     
    439484    this() 
    440485    { 
    441         this(1, 0, 0, 0); 
     486        this(1, 0, Gaps()); 
    442487    } 
    443488 
    444489    this(int Columns, int Rows = 0) 
    445490    { 
    446         this(Columns, Rows, 0, 0); 
    447     } 
    448  
    449     this(int Columns, int Rows, float Xgap, float Ygap
     491        this(Columns, Rows, Gaps()); 
     492    } 
     493 
     494    this(int Columns, int Rows, Gaps gaps_
    450495    { 
    451496        super(); 
     497        this.columns = Columns; 
    452498        this.rows = Rows; 
    453         this.columns = Columns; 
    454         this.xgap = Xgap; 
    455         this.ygap = Ygap; 
    456     } 
    457  
    458     override Size preferred_size() { 
    459         writefln("calc Preferred"); 
    460         return _calc_size( (Arrangeable item){ return item.preferred_size(); } ); 
    461     } 
    462  
    463     override Size minimum_size() { 
    464         writefln("calc minimum"); 
    465         return _calc_size( (Arrangeable item){ return item.minimum_size(); } ); 
    466     } 
    467  
     499        if (gaps_.standard) { 
     500            gaps_.x = 0; 
     501            gaps_.y = 0; 
     502        } 
     503        this.m_gaps = gaps_; 
     504    } 
     505 
     506    override int orderof(Arrangeable item) { 
     507        assert(item !is null); 
     508        int idx = m_items.find_item(item); 
     509        assert(idx != NOT_FOUND); 
     510        return idx; 
     511    } 
     512 
     513    override Size preferred_size(Size bounds) { 
     514        float[] widths, heights; 
     515        return _calc_size( 
     516            widths,heights, 
     517            (Arrangeable item){ return item.preferred_size(bounds); } ); 
     518    } 
     519 
     520    override Size minimum_size(Size bounds) { 
     521        float[] widths, heights; 
     522        return _calc_size(  
     523            widths, heights, 
     524            (Arrangeable item){ return item.minimum_size(bounds); } ); 
     525    } 
    468526 
    469527    override void arrange() 
    470528    { 
    471         GridSize grid = _calc_grid(); 
    472  
    473         float width = rect.width; 
    474         float height = rect.height; 
    475  
    476         width = (width - (grid.cols - 1) * xgap) / grid.cols; 
    477         height = (height - (grid.rows - 1) * ygap) / grid.rows; 
    478  
     529        if (m_items.length == 0) return; 
     530 
     531        float[] widths, heights; 
     532        GridCells grid = _update_cell_widths( 
     533            widths,heights, 
     534            (Arrangeable i){ return i.preferred_size(rect.size); }); 
     535 
     536 
     537        float x0 = rect.x; 
     538        float y0 = rect.y; 
    479539        float x,y; 
    480540        int c,r; 
    481         for(c = 0, x = rect.x; c < grid.cols; c++, x += width + xgap) 
     541 
     542        for(c = 0, x = x0; c < grid.cols; x += widths[c] + xgap, c++) 
    482543        { 
    483             for(r = 0, y = rect.y; r < grid.rows; r++, y += height + ygap
     544            for(r = 0, y = y0; r < grid.rows; y += heights[r] + ygap, r++
    484545            { 
    485546                int i = r * grid.cols + c; 
     
    487548                { 
    488549                    Arrangeable item = m_items[i]; 
    489                     item.set_rect(Rect(x, y, width, height)); 
     550                    item.set_rect(Rect(x-x0, y-y0, widths[c], heights[r])); 
    490551                    item.arrange(); 
    491552                } 
     
    512573    } 
    513574 
    514     float xgap() { return m_xgap; } 
    515     float xgap(float x) { return m_xgap = x; } 
    516  
    517     float ygap() { return m_ygap; } 
    518     float ygap(float y) { return m_ygap = y; } 
     575    float xgap() { return m_gaps.x; } 
     576    float xgap(float v) { m_gaps.x = v; return m_gaps.x; } 
     577    float ygap() { return m_gaps.y; } 
     578    float ygap(float v) { m_gaps.y = v; return m_gaps.y; } 
     579 
    519580 
    520581    int rows() { return m_rows; } 
     
    524585    int columns(int v) { return m_cols = v; } 
    525586 
    526     private struct GridSize { 
    527         static GridSize opCall(int r, int c) { GridSize g; g.rows = r; g.cols = c; return g; } 
     587    private struct GridCells { 
     588        static GridCells opCall(int c, int r) 
     589        { GridCells g; g.rows = r; g.cols = c; return g; } 
    528590        int cols=0; 
    529591        int rows=0; 
    530592    } 
    531593 
    532     private GridSize _calc_grid() 
     594    private GridCells _calc_grid() 
    533595    { 
    534596        int newRows = rows; 
    535597        int newCols = columns; 
    536         int components = m_items.length; 
     598        int nItems = m_items.length; 
    537599        if(newRows > 0) 
    538600        { 
    539             newCols = (components + newRows - 1)/newRows; 
     601            newCols = (nItems + newRows - 1)/newRows; 
    540602        } 
    541603        else 
    542604        { 
    543             newRows = (components + newCols - 1)/newCols; 
    544         } 
    545         return GridSize(newRows, newCols); 
    546     } 
    547  
    548     private Size _calc_size(Size delegate(Arrangeable i) size_getter) 
    549     { 
    550         GridSize grid = _calc_grid(); 
    551         float[] widths; widths.length = grid.cols; 
    552         float[] heights; heights.length = grid.rows; 
     605            newRows = (nItems + newCols - 1)/newCols; 
     606        } 
     607        return GridCells(newCols, newRows); 
     608    } 
     609 
     610    private GridCells _update_cell_widths( 
     611        inout float[] widths, inout float[] heights, Size delegate(Arrangeable i)size_getter 
     612        ) 
     613    { 
     614        GridCells grid = _calc_grid(); 
     615        widths.length = grid.cols; 
     616        heights.length = grid.rows; 
    553617 
    554618        widths[] = 0; 
    555619        heights[] = 0; 
    556620 
    557         int c,r; 
    558         foreach(inout w; widths) { 
    559             foreach(inout h; heights) { 
     621        foreach(c, inout w; widths) { 
     622            foreach(r, inout h; heights) { 
    560623                int i = r * grid.cols + c; 
    561624                if(i < m_items.length) 
     
    567630            } 
    568631        } 
     632        return grid; 
     633    } 
     634 
     635    private Size _calc_size(float[] widths, float[]heights,  
     636                            Size delegate(Arrangeable i) size_getter) 
     637    { 
     638        GridCells grid = _update_cell_widths(widths,heights,size_getter); 
    569639 
    570640        float width = 0; 
     
    575645        return Size(width + xgap * (grid.cols - 1), 
    576646                    height + ygap * (grid.rows - 1)); 
    577  
    578647    } 
    579648     
     
    581650    private: 
    582651    Arrangeable[] m_items; 
    583     int m_rows; 
    584     int m_cols; 
    585     float m_xgap; 
    586     float m_ygap; 
     652    int m_cols,m_rows; 
     653    Gaps m_gaps; 
    587654} 
    588655 
     
    608675    this()  
    609676    { 
    610         this(0, 0); 
    611     } 
    612  
    613     this(float Xgap, float Ygap) 
    614     { 
    615         this.xgap = Xgap; 
    616         this.ygap = Ygap; 
     677        this(Gaps()); 
     678    } 
     679 
     680    this(Gaps gap_) 
     681    { 
     682        if (gap_.standard) { 
     683            gap_.x = gap_.y = 0; 
     684        } 
     685        m_gaps = gap_; 
    617686        auto_add = false; 
    618687    } 
    619688 
    620     override  Size minimum_size() 
     689    override int orderof(Arrangeable item) { 
     690        assert(item !is null); 
     691        if (item==m_north)  { return 0; } 
     692        if (item==m_west)   { return 1; } 
     693        if (item==m_center) { return 2; } 
     694        if (item==m_east)   { return 3; } 
     695        if (item==m_south)  { return 4; } 
     696 
     697        assert(0, "Item is not contained in this Arranger."); 
     698        return 0; 
     699    } 
     700 
     701 
     702    override  Size minimum_size(Size bounds) 
    621703    { 
    622704        float width = 0; 
    623705        float height = 0; 
    624706        if(m_north != null){ 
    625             Size s = m_north.minimum_size(); 
     707            Size s = m_north.minimum_size(bounds); 
    626708            width = math.fmax(width, s.width); 
    627709            height += s.height + ygap; 
    628710        } 
    629711        if(m_south != null){ 
    630             Size s = m_south.minimum_size(); 
     712            Size s = m_south.minimum_size(bounds); 
    631713            width = math.fmax(width, s.width); 
    632714            height += s.height + ygap; 
    633715        } 
    634716        if(m_center != null){ 
    635             Size s = m_center.minimum_size(); 
     717            Size s = m_center.minimum_size(bounds); 
    636718            height = math.fmax(height, s.height); 
    637719            width += s.width; 
    638720        } 
    639721        if(m_east != null){ 
    640             Size s = m_east.minimum_size(); 
     722            Size s = m_east.minimum_size(bounds); 
    641723            width += s.width; 
    642724            height = math.fmax(height, s.height); 
    643725        } 
    644726        if(m_west != null){ 
    645             Size s = m_west.minimum_size(); 
     727            Size s = m_west.minimum_size(bounds); 
    646728            width += s.width; 
    647729            height = math.fmax(height, s.height); 
     
    650732    } 
    651733 
    652     override  Size preferred_size(
     734    override  Size preferred_size(Size bounds
    653735    { 
    654736        float width = 0; 
    655737        float height = 0; 
    656738        if(m_north != null){ 
    657             Size s = m_north.preferred_size(); 
     739            Size s = m_north.preferred_size(bounds); 
    658740            width = math.fmax(width, s.width); 
    659741            height += s.height + ygap; 
    660742        } 
    661743        if(m_south != null){ 
    662             Size s = m_south.preferred_size(); 
     744            Size s = m_south.preferred_size(bounds); 
    663745            width = math.fmax(width, s.width); 
    664746            height += s.height + ygap; 
    665747        } 
    666748        if(m_center != null){ 
    667             Size s = m_center.preferred_size(); 
     749            Size s = m_center.preferred_size(bounds); 
    668750            height = math.fmax(height, s.height); 
    669751            width += s.width; 
    670752        } 
    671753        if(m_east != null){ 
    672             Size s = m_east.preferred_size(); 
     754            Size s = m_east.preferred_size(bounds); 
    673755            width += s.width; 
    674756            height = math.fmax(height, s.height); 
    675757        } 
    676758        if(m_west != null){ 
    677             Size s = m_west.preferred_size(); 
     759            Size s = m_west.preferred_size(bounds); 
    678760            width += s.width; 
    679761            height = math.fmax(height, s.height); 
     
    690772 
    691773        if (m_north != null) { 
    692             Size s = m_north.preferred_size(); 
     774            Size s = m_north.preferred_size(rect.size); 
    693775            m_north.set_rect(Rect(left, top, right-left, s.height)); 
    694776            top += s.height + ygap; 
     
    696778        } 
    697779        if(m_south != null){ 
    698             Size s = m_south.preferred_size(); 
     780            Size s = m_south.preferred_size(rect.size); 
    699781            bottom -= s.height; 
    700782            m_south.set_rect(Rect(left, bottom, right-left, s.height)); 
     
    703785        } 
    704786        if(m_west != null){ 
    705             Size s = m_west.preferred_size(); 
     787            Size s = m_west.preferred_size(rect.size); 
    706788            m_west.set_rect(Rect(left, top, s.width, bottom - top)); 
    707789            left += s.width + xgap; 
     
    709791        } 
    710792        if(m_east != null){ 
    711             Size s = m_east.preferred_size(); 
     793            Size s = m_east.preferred_size(rect.size); 
    712794            right -= s.width; 
    713795            m_east.set_rect(Rect(right, top, s.width, bottom - top)); 
     
    809891    } 
    810892 
    811     float xgap() { return m_xgap; } 
    812     float xgap(float x) { return m_xgap = x; } 
    813  
    814     float ygap() { return m_ygap; } 
    815     float ygap(float y) { return m_ygap = y; } 
     893    float xgap() { return m_gaps.x; } 
     894    float xgap(float v) { m_gaps.x = v; return m_gaps.x; } 
     895    float ygap() { return m_gaps.y; } 
     896    float ygap(float v) { m_gaps.y = v; return m_gaps.y; } 
    816897 
    817898private: 
     
    822903    Arrangeable m_center; 
    823904 
    824     float m_xgap; 
    825     float m_ygap; 
     905    Gaps m_gaps; 
    826906} 
  • trunk/luigi/base.d

    r6 r7  
    4848{ 
    4949    // This layout lets you use rect either like 
    50     //    (r.x, r.y, r.w, r.h) // primary 
     50    //    (r.x, r.y, r.width, r.height) // primary 
    5151    // or like 
    5252    //    (r.x1, r.y1, r.x2, r.y2)  // also allowed with restrictions 
     53    // or like 
     54    //    (r.pos, r.size); 
    5355    union { 
    54         struct { float x = 0,y = 0; } 
    55         struct { float x1, y1; } 
    56     } 
    57     float width=0 ,height=0; 
    58  
     56        struct { float x,y; } 
     57        Point pos; 
     58    } 
     59    union { 
     60        struct { float width ,height; } 
     61        Size size; 
     62    } 
     63 
     64    alias x x1; 
     65    alias y y1; 
    5966    alias width w; 
    6067    alias height h; 
     
    112119        Size s; s.width = _w;  s.height = _h; return s; 
    113120    } 
     121 
     122    void opAddAssign(Size o) { w+=o.w; h+=o.h; } 
     123    void opSubAssign(Size o) { w-=o.w; h-=o.h; } 
    114124 
    115125    char[] toString() { 
     
    282292} 
    283293 
     294// Remove a range of elements from an array in place.   
     295// It is not an error for the range to be empty or for start to be greater than end. 
     296// If so, the array is not modified. 
     297// Out of bounds checks performed only in debug mode. 
     298// Returns: the array, which (is modified in-place). 
     299// Note: This is an O(n) operation. 
     300template drop_range(T) 
     301{ 
     302  T[] drop_range( inout T[] arr, int start, int end ) 
     303  { 
     304    debug if ( start>=arr.length || end > arr.length || start<0 || end<0) 
     305        throw new Exception(string.format("Attempt to drop range %s,%s from size %s",start,end,arr.length)); 
     306    if (start>=end) return arr; 
     307    size_t len = end-start; 
     308    size_t max = arr.length-len; 
     309    for (; start < max; start++ ) arr[start]=arr[start+len]; 
     310    arr.length= max; 
     311    return arr; 
     312  } 
     313}  
     314 
    284315/*********************************************************************************** 
    285316 * Lookup the index of the first element of an array that satisfies a delegate. 
  • trunk/luigi/example1.d

    r6 r7  
    2727*/ 
    2828import luigui = luigi.gui; 
     29import luigi.adaptor.glfw; 
    2930 
    3031import derelict.glfw.glfw; 
     
    5657 
    5758 
     59// doesn't work .. ICE if you try to use this 
     60class CoolTarget(T...) 
     61{ 
     62    this( void delegate(T...) dg) { fn = dg; } 
     63    void slot(T args) { 
     64        fn(args); 
     65    } 
     66    void delegate(T...) fn; 
     67} 
     68class BDelegate 
     69{ 
     70    alias void delegate(luigui.Widget, bool) func_t; 
     71    this(func_t dg) { fn = dg; } 
     72    void slot(luigui.Widget w, bool b) { 
     73        fn(w,b); 
     74    } 
     75    func_t fn; 
     76} 
     77class VDelegate 
     78{ 
     79    alias void delegate(luigui.Widget) func_t; 
     80    this(func_t dg) { fn = dg; } 
     81    void slot(luigui.Widget w) { 
     82        fn(w); 
     83    } 
     84    func_t fn; 
     85} 
     86 
    5887void main(char[][] argv) 
    5988{ 
     
    82111 
    83112    //---------------- CREATE GUI ---------------------- 
     113     
    84114    luigui.Overlay gui; 
    85115    with(luigui) { 
     116        Luigi().adaptor = GLFWAdaptor(); 
     117        StdTheme theme = cast(StdTheme)Luigi().theme; 
    86118        gui = new Overlay; 
    87119     
     
    89121        //gui.arranger = new GridArranger(2,2); 
    90122        //BorderArranger layout = new BorderArranger(5,5); 
    91         gui.arranger = new BorderArranger(5,5); 
     123        gui.arranger = new BorderArranger(Gaps(5)); 
    92124 
    93125        alias BorderArranger.Region Region; 
    94126        alias Alignment A; 
    95127 
    96         Panel northGroup = arranger_add(new FlowPanel(gui), Region.North); 
    97  
    98         Button b10 = arranger_add(new Button(northGroup, "File")); 
    99         Button b11 = arranger_add(new Button(northGroup, "Edit")); 
    100         Button b12 = arranger_add(new Button(northGroup, "View")); 
    101         Button b13 = arranger_add(new Button(northGroup, "Favorites")); 
    102         Button b14 = arranger_add(new Button(northGroup, "Tools")); 
    103         Button b15 = arranger_add(new Button(northGroup, "Options")); 
    104         Button b16 = arranger_add(new Button(northGroup, "Help")); 
    105  
    106         Panel westGroup = arranger_add(new GridPanel(gui,2), Region.West); 
    107         Button b20 = arranger_add(new Button(westGroup, "Tool0")); 
    108         Button b21 = arranger_add(new Button(westGroup, "Tool1")); 
    109         Button b22 = arranger_add(new Button(westGroup, "Tool2")); 
    110         Button b23 = arranger_add(new Button(westGroup, "Tool3")); 
    111         Button b24 = arranger_add(new Button(westGroup, "Tool4")); 
    112         Button b25 = arranger_add(new Button(westGroup, "Tool5")); 
    113         Button b26 = arranger_add(new Button(westGroup, "Tool6")); 
    114         Button b27 = arranger_add(new Button(westGroup, "Tool7")); 
    115         Button b28 = arranger_add(new Button(westGroup, "Tool8")); 
    116         Button b29 = arranger_add(new Button(westGroup, "Tool9")); 
    117  
    118  
    119         Button b3 = arranger_add(new Button(gui, "Mate!"), Region.East); 
    120         Button b4 = arranger_add(new Button(gui, "How do you do?"), Region.South); 
    121  
    122         b4.clicked.connect( (Widget w){ writefln("ouch!"); } );  
     128        Panel eastGroup = gui.add_widget(new GridPanel(1,0, Gaps(2))); 
     129        gui.arranger.add(eastGroup, Region.East); 
     130        with(eastGroup) { 
     131        &n