Changeset 37

Show
Ignore:
Timestamp:
12/05/06 20:00:24 (2 years ago)
Author:
baxissimo
Message:

Improvements to dxut mostly (adding scrollbar)

Files:

Legend:

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

    r11 r37  
    306306        FlowRow currentRow = new FlowRow(xgap); 
    307307        foreach(Arrangeable c ; m_items)  
     308        { 
     309            Size s = c.preferred_size(rect.size); 
     310            currentWidth += s.width + xgap; 
     311            if(currentWidth > rect.width) 
    308312            { 
    309                 Size s = c.preferred_size(rect.size); 
    310                 currentWidth += s.width + xgap; 
    311                 if(currentWidth > rect.width) 
    312                 { 
    313                     currentWidth = s.width - xgap; 
    314                     rows ~= currentRow; 
    315                     currentRow = new FlowRow(xgap); 
    316                 } 
    317                 currentRow.add(c); 
     313                currentWidth = s.width - xgap; 
     314                rows ~= currentRow; 
     315                currentRow = new FlowRow(xgap); 
    318316            } 
     317            currentRow.add(c); 
     318        } 
    319319        rows ~= currentRow; 
    320320        float totalHeight = 0; 
    321321        foreach(FlowRow r ; rows) 
    322            
    323                 totalHeight += r.size.height; 
    324            
     322       
     323            totalHeight += r.size.height; 
     324       
    325325        totalHeight += ygap*(rows.length - 1); 
    326326 
     
    346346        case A.Left: 
    347347            foreach(FlowRow r; rows)  
    348                
    349                     r.position = Point(0, y-rect.y); 
    350                     r.arrange(); 
    351                     y += r.size.height + ygap; 
    352                
     348           
     349                r.position = Point(0, y-rect.y); 
     350                r.arrange(); 
     351                y += r.size.height + ygap; 
     352           
    353353            break; 
    354354        case A.Right: 
    355355            foreach(FlowRow r; rows) 
    356                
    357                     float x = rect.x2 - r.size.width; 
    358                     r.position = Point(x-rect.x, y-rect.y); 
    359                     r.arrange(); 
    360                     y += r.size.height + ygap; 
    361                
     356           
     357                float x = rect.x2 - r.size.width; 
     358                r.position = Point(x-rect.x, y-rect.y); 
     359                r.arrange(); 
     360                y += r.size.height + ygap; 
     361           
    362362            break; 
    363363 
     
    365365        default: 
    366366            foreach(FlowRow r; rows) 
    367                
    368                     float x = rect.x + (rect.width - r.size.width)/2; 
    369                     r.position = Point(x-rect.x, y-rect.y); 
    370                     r.arrange(); 
    371                     y += r.size.height + ygap; 
    372                
     367           
     368                float x = rect.x + (rect.width - r.size.width)/2; 
     369                r.position = Point(x-rect.x, y-rect.y); 
     370                r.arrange(); 
     371                y += r.size.height + ygap; 
     372           
    373373            break; 
    374374        } 
    375375        foreach(Arrangeable item ; m_items) 
    376            
    377                item.arrange(); 
    378            
     376       
     377            item.arrange(); 
     378       
    379379    } 
    380380 
     
    428428        float y = y0 + (rect.height / 2); 
    429429        foreach(Arrangeable item ; m_items) 
    430            
    431                Size s = item.preferred_size(rect.size); 
    432                item.set_rect(Rect(x, y-(s.height/2), s.width, s.height)); 
    433                x += s.width + xgap; 
    434            
     430       
     431            Size s = item.preferred_size(rect.size); 
     432            item.set_rect(Rect(x, y-(s.height/2), s.width, s.height)); 
     433            x += s.width + xgap; 
     434       
    435435    } 
    436436 
     
    440440        float width = 0; 
    441441        foreach(Arrangeable item ; m_items) 
    442            
    443                Size s = item.preferred_size(rect.size); 
    444                width += s.width; 
    445            
     442       
     443            Size s = item.preferred_size(rect.size); 
     444            width += s.width; 
     445       
    446446        width += xgap * (m_items.length - 1); 
    447447        m_rect.width = width; 
     
    453453        float maxHeight = 0; 
    454454        foreach(Arrangeable item ; m_items) 
    455            
    456                maxHeight = math.fmax(maxHeight, item.preferred_size(rect.size).height); 
    457            
     455       
     456            maxHeight = math.fmax(maxHeight, item.preferred_size(rect.size).height); 
     457       
    458458        return maxHeight; 
    459459    } 
     
    637637        heights[] = 0; 
    638638 
    639         foreach(c, inout w; widths) { 
    640             foreach(r, inout h; heights) { 
     639        foreach(c, inout w; widths)  
     640        { 
     641            foreach(r, inout h; heights)  
     642            { 
    641643                int i = r * grid.cols + c; 
    642644                if(i < m_items.length) 
  • trunk/luigi/base.d

    r32 r37  
    105105 
    106106    /** Intersection of two rects. */ 
    107     void intersect(Rect o) { 
    108  
    109     } 
     107    //void intersect(Rect o) { 
     108    //    // not implemented 
     109    //} 
     110 
    110111    /** Grow rect to enclose other rect (union of rects.) */ 
    111112    void enclose(Rect o) { 
     
    153154    void opSubAssign(Size o) { w-=o.w; h-=o.h; } 
    154155 
     156    /** Allows Sizes to be multiplied by a scalar */ 
     157    void opMulAssign(float d) { w*=d; h*=d; } 
     158 
    155159    /** Return a printable representation of the Size */ 
    156160    char[] toString() { 
    157161        return string.format("(%0.1f,%0.1f)",w,h); 
    158162    } 
     163 
    159164} 
    160165 
  • trunk/luigi/example1.d

    r32 r37  
    9797            auto b29 = add_arranged(new Button("Tool9")); 
    9898 
    99             rgrp.add(b20,b21,b22,b23,b24,b25,b26,b27,b28,b29); 
     99            rgrp.multiadd(b20,b21,b22,b23,b24,b25,b26,b27,b28,b29); 
    100100            rgrp.value = 0; 
    101101            rgrp.selection_changed ~= (int t) { 
     
    103103            }; 
    104104 
    105             auto s01 = add_arranged(new Slider("Thingy")); 
    106             auto s02 = add_arranged(new Slider("Thingy")); 
     105            auto s01 = add_arranged(new Slider); 
     106            auto s02 = add_arranged(new Slider); 
    107107            s02.vertical = true; 
    108108            s01.precision = 0.1; 
     
    113113            s02.value_changed.connect2nd(&s01.value); 
    114114            s01.value_changed.connect2nd(&s02.value); 
     115 
     116/* 
     117            auto sb01 = add_arranged(new ScrollBar); 
     118            auto sb02 = add_arranged(new ScrollBar); 
     119            sb02.vertical = true; 
     120            sb01.precision = 1; 
     121            sb02.precision = 1; 
     122*/ 
    115123        } 
    116124 
     
    129137                b.get_root.arrange(); 
    130138            }; 
     139 
     140            auto onoff = new RadioGroup; 
     141            auto r0 = add_widget(new RadioButton("On")); 
     142            auto r1 = add_widget(new RadioButton("Off")); 
     143            onoff.multiadd(r0,1, r1,0); 
     144            onoff.value = 1; 
    131145        } 
    132146 
  • trunk/luigi/example1_sdl.d

    r33 r37  
    434434    SDL_WM_SetCaption("Gears", "gears"); 
    435435    SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL); 
     436    SDL_EnableUNICODE(1); 
    436437 
    437438    init(args); 
  • trunk/luigi/gui.d

    r33 r37  
    698698    } 
    699699 
    700     override Size minimum_size(Size bounds)   {  
     700    override Size minimum_size(Size bounds)   { 
    701701        if (arranger) { return arranger.minimum_size(bounds); } 
    702702        return super.minimum_size(bounds); 
     
    16081608    override double value() { return m_value; } 
    16091609 
    1610     this(char[] label_) { 
     1610    this() { 
    16111611        super(); 
    1612         label = label_; 
    16131612        value_changed = new ValueChangedSignal; 
    16141613        m_focusable = true; 
     
    16641663    bool vertical() { return m_orientation != Orientation.Horizontal; } 
    16651664 
    1666     char[] label; 
    1667  
    16681665    alias FlexSignal!(Widget, double) ValueChangedSignal; 
    16691666    ValueChangedSignal value_changed; 
     
    17071704} 
    17081705 
     1706class ScrollBar : Panel, Valuator 
     1707{ 
     1708    mixin WidgetMixin; 
     1709    // don't use panel mixin because we shouldn't be able to add things to this panel 
     1710 
     1711    class ScrollButton : Button 
     1712    { 
     1713        // use labels: 'up' 'down' 'left' 'right' to indicate which direction to point 
     1714        this(char[] label_) { 
     1715            super(label_); 
     1716            focusable = false; 
     1717        } 
     1718    } 
     1719    class ScrollTrack : Slider 
     1720    { 
     1721        this() {  
     1722            super();  
     1723            focusable = false; 
     1724        } 
     1725         
     1726    } 
     1727 
     1728    this() { 
     1729        super(); 
     1730        m_track = new ScrollTrack; 
     1731        m_upButton = new ScrollButton("left"); 
     1732        m_downButton = new ScrollButton("right"); 
     1733        // value_changed = new ValueChangedSignal; 
     1734        m_focusable = false; 
     1735        add(m_upButton); 
     1736        add(m_track); 
     1737        add(m_downButton); 
     1738        _set_button_labels(); 
     1739        writefln("%s(%s): trace!", __FILE__, __LINE__); 
     1740    } 
     1741 
     1742    // Panel-related overrides 
     1743 
     1744    // Don't allow adding children 
     1745    private override void add(Widget child) { super.add(child); } 
     1746    // Don't allow setting an arranger 
     1747    private override Arranger arranger(Arranger a) { return null; } 
     1748    private override Arranger arranger() { return null; } 
     1749 
     1750    override Size minimum_size(Size bounds)   { 
     1751        Size sz = m_track.minimum_size(bounds); 
     1752        Size szup = m_upButton.minimum_size(bounds); 
     1753        Size szdn = m_downButton.minimum_size(bounds); 
     1754        if (vertical) { 
     1755            sz.width = max(sz.width, szup.width); 
     1756            sz.width = max(sz.width, szdn.width); 
     1757            sz.height +=  szup.height + szdn.height; 
     1758        } 
     1759        else { 
     1760            sz.height = max(sz.height, szup.height); 
     1761            sz.height = max(sz.height, szdn.height); 
     1762            sz.width +=  szup.width + szdn.width; 
     1763        } 
     1764        return sz; 
     1765    } 
     1766    override Size preferred_size(Size bounds) { 
     1767        Size sz = m_track.preferred_size(bounds); 
     1768        Size szup = m_upButton.preferred_size(bounds); 
     1769        Size szdn = m_downButton.preferred_size(bounds); 
     1770        if (vertical) { 
     1771            sz.width = max(sz.width, szup.width); 
     1772            sz.width = max(sz.width, szdn.width); 
     1773            sz.height +=  szup.height + szdn.height; 
     1774        } 
     1775        else { 
     1776            sz.height = max(sz.height, szup.height); 
     1777            sz.height = max(sz.height, szdn.height); 
     1778            sz.width +=  szup.width + szdn.width; 
     1779        } 
     1780        return sz; 
     1781    } 
     1782    override void arrange() { 
     1783        Rect urect = Rect(0,0,0,0); 
     1784        Rect drect = Rect(0,0,0,0); 
     1785        urect.size = m_upButton.preferred_size(rect.size); 
     1786        drect.size = m_downButton.preferred_size(rect.size); 
     1787        if (vertical) { 
     1788            m_upButton.set_rect(urect); 
     1789            drect.y = rect.h - drect.h; 
     1790            m_downButton.set_rect(drect); 
     1791            m_track.set_rect( 
     1792                Rect( urect.x, urect.y2, urect.w, rect.h-urect.h-drect.h)); 
     1793        } else { 
     1794            m_downButton.set_rect(drect); 
     1795            urect.x = rect.x2 - urect.w; 
     1796            m_upButton.set_rect(urect); 
     1797            m_track.set_rect( 
     1798                Rect( drect.x2, drect.y, rect.w-urect.w-drect.w, drect.h)); 
     1799        } 
     1800    } 
     1801 
     1802    // Slider related overrides 
     1803 
     1804    override double value(double v) { return m_track.value(v); } 
     1805    override double value() { return m_track.value(); } 
     1806 
     1807    double value_max(double v) { return m_track.value_max(v); } 
     1808    double value_min(double v) { return m_track.value_min(v); } 
     1809    double increment(double v) { return m_track.increment(v); } 
     1810    double page_increment(double v) { return m_track.page_increment(v); } 
     1811    double precision(double prec) { return m_track.precision(prec); } 
     1812 
     1813    double value_max() { return m_track.value_max(); } 
     1814    double value_min() { return m_track.value_min(); } 
     1815    double increment() { return m_track.increment(); } 
     1816    double page_increment() { return m_track.page_increment(); } 
     1817    double precision() { return m_track.precision(); } 
     1818 
     1819    bool horizontal(bool tf) {  
     1820        if (horizontal == tf) return tf; 
     1821        m_track.horizontal(tf); 
     1822        _set_button_labels(); 
     1823        return tf; 
     1824    } 
     1825    bool vertical(bool tf) {  
     1826        if (vertical == tf) return tf; 
     1827        m_track.vertical(tf); 
     1828        _set_button_labels(); 
     1829        return tf; 
     1830    } 
     1831    bool horizontal() { return m_track.horizontal(); } 
     1832    bool vertical() { return m_track.vertical(); } 
     1833         
     1834    private void _set_button_labels() { 
     1835        if (m_track.vertical) { 
     1836            m_downButton.label = "down"; 
     1837            m_upButton.label = "up"; 
     1838        } 
     1839        else { 
     1840            m_downButton.label = "left"; 
     1841            m_upButton.label = "right"; 
     1842        } 
     1843    } 
     1844 
     1845    double page_size(double v) { return m_page_size = v; } 
     1846    double page_size() { return m_page_size; } 
     1847 
     1848 
     1849    alias m_track.ValueChangedSignal ValueChangedSignal; 
     1850 
     1851    double m_page_size = 1; 
     1852    ScrollTrack  m_track; 
     1853    ScrollButton m_downButton; // (or left) 
     1854    ScrollButton m_upButton; // (or right) 
     1855} 
     1856 
    17091857/** A radio button is just a Button with an alternate appearance  
    17101858    determined by the theme. 
     
    17581906    } 
    17591907 
    1760     /** Have button b join this group, using the next available value. 
    1761      *  If this is the first item, the 0 is used as the value.  
     1908    /**  Add button b to the group, generating an automatic id. 
     1909         If this is the first item, the 0 is used as the id. 
     1910         Otherwise the current max id plus one is used. 
     1911    */ 
     1912    void add(Button b) { 
     1913        int v = length() ? max_val()+1 : 0; 
     1914        add(b,v); 
     1915    } 
     1916 
     1917    /** Have all the buttons in the parameter list join this group. 
     1918     *  If all items are Buttons then call add(Button) to add to the group 
     1919     *  using default values.  If a button is followed by an integer, then  
     1920     *  use that as it's id.  For example: 
     1921     *  --------------- 
     1922     *    Button b1,b2; Checkbox c1,c2; RadioButton r1,r2; 
     1923     *    ... 
     1924     *    rgroup1.multiadd(b1,b2); // adds with ids 0 and 1. 
     1925     *    rgroup2.multiadd(c1,5, c2,10); // adds with ids 5 and 10 
     1926     *    rgroup3.multiadd(r1,1, r2); // adds with ids 1 and 2. 
     1927     *  --------------- 
    17621928     */ 
    1763     void add(Button b, ...) { 
    1764         void do_add (Button btn) { 
    1765             int v = length() ? max_val()+1 : 0; 
    1766             add(btn,v); 
    1767         } 
    1768         do_add(b); 
    1769         for (int i=0; i<_arguments.length; i++) 
    1770         { 
    1771             if (_arguments[i] == typeid(Button)) { 
    1772                 Button bb = *cast(Button*)_argptr; 
    1773                 do_add(bb); 
    1774                 _argptr += bb.sizeof; 
    1775             } 
    1776         } 
    1777     } 
     1929    void multiadd(ButtonOrInt ...)(ButtonOrInt buttons) { 
     1930        static if (buttons.length == 0) {} 
     1931        else static if( is (ButtonOrInt[0] : Button ) ) { 
     1932            static if( (buttons.length > 1) && is(ButtonOrInt[1] : int)) { 
     1933                add(buttons[0], buttons[1]); 
     1934                multiadd(buttons[2..$]); 
     1935            } 
     1936            else { 
     1937                add(buttons[0]); 
     1938                multiadd(buttons[1..$]); 
     1939            } 
     1940        } 
     1941        else { 
     1942            static assert( 
     1943                0,  
     1944                string.format("RadioGroup.multiadd: bad type '%s'. Button expected", 
     1945                              typeid(ButtonOrInt[0]))); 
     1946        } 
     1947    } 
     1948    // Simpler version -- just allows buttons 
     1949    //void multiadd(Button[] buttons ...) { 
     1950    //    foreach(btn; buttons) { 
     1951    //        add(btn); 
     1952    //   } 
     1953    //} 
     1954 
    17781955 
    17791956    /** Have button b leave this group */ 
  • trunk/luigi/themes/dxut.d

    r30 r37  
    7272        button_register(); 
    7373        checkbox_register(); 
     74        radiobutton_register(); 
    7475        textfield_register(); 
     76        optionmenu_register(); 
    7577        slider_register(); 
     78        scrollbar_register(); 
    7679        panel_register(); 
    7780        spinner_register(); 
    78         radiogroup_register(); 
    79         radiobutton_register(); 
    8081 
    8182        sel_text_color.set(255,255,255); 
     
    314315            } 
    315316            else if( !enabled ) { 
    316                 iState = WidgetState.Disabled;  
     317                iState = WidgetState.Disabled; 
    317318            } 
    318319            else if( depressed ) 
     
    331332 
    332333            if ( depressed ^ chk ) { 
     334                iState = WidgetState.Depressed; 
    333335                dx = dy = 1; 
     336            } 
     337            if (!depressed && chk && rollover) { 
     338                iState = WidgetState.Rollover; 
    334339            } 
    335340            if ( rollover ) { 
     
    377382    } 
    378383    Size checkbox_min_size(Widget widget, Size bounds) { 
    379         auto w = cast(Checkbox)widget; assert(w); 
     384        auto w = cast(Button)widget; assert(w); 
    380385        Element[] elem = get_widget_elements(w); 
    381386        Point p0 = Point(elem[0].texRect[0], elem[0].texRect[1]); 
     
    388393    } 
    389394    Size checkbox_best_size(Widget widget, Size bounds) { 
    390         auto w = cast(Checkbox)widget; assert(w); 
     395        auto w = cast(Button)widget; assert(w); 
    391396        Size minsz = checkbox_min_size(w,bounds); 
    392397        return Size(max(50.,minsz.w), max(22.,minsz.h)); 
    393398    } 
    394399    void checkbox_draw(Widget widget) { 
    395         auto w = cast(Checkbox)widget; assert(w); 
     400        auto w = cast(Button)widget; assert(w); 
    396401        with (w) { 
    397402            WidgetState iState = WidgetState.Normal; 
     
    430435            draw_elem_texture( elem[1], btn_rect ); 
    431436        } 
     437    } 
     438    //----RADIOBUTTON------------------------------------------------------- 
     439    void radiobutton_register() { 
     440        // radiobutton is identical to checkbox, except the textures it uses to draw. 
     441        addHandlers!(RadioButton)(&checkbox_draw, &checkbox_best_size, &checkbox_min_size); 
     442        Element[] elems = new Element[2]; 
     443        Element e; 
     444 
     445        e.fontColor.states[ WidgetState.Rollover ] = Color(0, 0, 0, 255); 
     446        e.texColor.states[ WidgetState.Rollover ] = Color(255, 255, 255, 160); 
     447     
     448        // radio button border 
     449        e.set_texture( m_texid, [54, 54, 81, 81] ); 
     450        e.set_font( m_default_font, Color(255, 255, 255, 255) ); 
     451        e.fontColor.states[ WidgetState.Disabled ] = Color( 200, 200, 200, 200 ); 
     452        e.texColor.states[ WidgetState.Normal ] = Color(255, 255, 255, 150); 
     453        e.texColor.states[ WidgetState.Focus ] = Color(255, 255, 255, 200); 
     454        e.texColor.states[ WidgetState.Depressed ] = Color(255, 255, 255, 255); 
     455        elems[0] = e; 
     456 
     457        // selection indicator 
     458        e.set_texture( m_texid, [81, 54, 108, 81] ); 
     459        elems[1] = e; 
     460 
     461        m_elements[RadioButton.classinfo] = elems; 
    432462    } 
    433463    //----TEXTFIELD--------------------------------------------------------- 
     
    856886        } 
    857887    } 
     888    //----SCROLLBAR--------------------------------------------------------- 
     889    enum ScrollArrow{ Up, Down, Right, Left } 
     890 
     891    void scrollbar_register() { 
     892        addHandlers!(ScrollBar.ScrollButton)( 
     893            &scrollbutton_draw, &scrollbutton_best_size, &scrollbutton_min_size); 
     894        //addEventHandlers!(ScrollBar.ScrollButton)( 
     895        //    &scrollbutton_mouse_button, &scrollbutton_mouse_move); 
     896        addHandlers!(ScrollBar.ScrollTrack)( 
     897            &scrolltrack_draw, &scrolltrack_best_size, &scrolltrack_min_size); 
     898        //addEventHandlers!(ScrollBar.ScrollTrack)( 
     899        //    &scrolltrack_mouse_button, &scrolltrack_mouse_move); 
     900         
     901        Element[] telems = new Element[2]; 
     902        Element e; 
     903         
     904 
     905        e.texColor.states[ WidgetState.Rollover ] =  Color(255, 255, 255, 160); 
     906        e.texColor.states[ WidgetState.Normal ] =    Color(255, 255, 255, 150); 
     907        e.texColor.states[ WidgetState.Depressed ] = Color(150, 150, 150, 255); 
     908        e.texColor.states[ WidgetState.Normal ] =    Color(255, 255, 255, 150); 
     909        e.texColor.states[ WidgetState.Focus ] =     Color(255, 255, 255, 200); 
     910 
     911        // track 
     912        e.set_texture( m_texid, [243, 144, 265, 155]); 
     913        e.texColor.states[ WidgetState.Disabled ] = Color(200, 200, 200, 255); 
     914        telems[0] = e; 
     915     
     916        // thumb 
     917        e.set_texture( 0, [266, 123, 286, 167] ); 
     918        telems[1] = e; 
     919 
     920        m_elements[ScrollBar.ScrollTrack.classinfo] = telems; 
     921 
     922        Element[] belems = new Element[4]; 
     923        // uparrow 
     924        e.set_texture( m_texid, [243, 124, 265, 144] ); 
     925        e.texColor.states[ WidgetState.Disabled ] = Color(200, 200, 200, 255); 
     926        belems[ScrollArrow.Up] = e; 
     927     
     928        // downarrow 
     929        e.set_texture( m_texid, [243, 155, 265, 176] ); 
     930        e.texColor.states[ WidgetState.Disabled ] = Color(200, 200, 200, 255); 
     931        belems[ScrollArrow.Down] = e; 
     932 
     933        // rightarrow 
     934        e.set_texture( m_texid, [243, 180, 265, 200] ); 
     935        e.texColor.states[ WidgetState.Disabled ] = Color(200, 200, 200, 255); 
     936        belems[ScrollArrow.Right] = e; 
     937     
     938        // leftarrow 
     939        e.set_texture( m_texid, [243, 211, 265, 232] ); 
     940        e.texColor.states[ WidgetState.Disabled ] = Color(200, 200, 200, 255); 
     941        belems[ScrollArrow.Left] = e; 
     942 
     943        m_elements[ScrollBar.ScrollButton.classinfo] = belems; 
     944 
     945    } 
     946    Size scrollbutton_min_size(Widget widget, Size bounds) { 
     947        auto w = cast(Button)widget; assert(w); 
     948        Element[] elem = get_widget_elements(w); 
     949        Size sz = Size(elem[0].texRect[2]-elem[0].texRect[0], 
     950                       elem[0].texRect[3]-elem[0].texRect[1]); 
     951        sz *= 0.5; 
     952        return sz; 
     953    } 
     954    Size scrollbutton_best_size(Widget widget, Size bounds) { 
     955        return scrollbutton_min_size(widget,bounds); 
     956    } 
     957    Size scrolltrack_min_size(Widget widget, Size bounds) { 
     958        return slider_min_size(widget,bounds); 
     959    } 
     960    Size scrolltrack_best_size(Widget widget, Size bounds) { 
     961        return slider_best_size(widget,bounds); 
     962    } 
     963    void scrollbutton_draw(Widget widget) { 
     964        auto w = cast(Button)widget; assert(w); 
     965        Element[] elem = get_widget_elements(w); 
     966        with(w) { 
     967            WidgetState iState = WidgetState.Normal; 
     968            if( !enabled ) { 
     969                iState = WidgetState.Disabled; 
     970            } 
     971            Rect r = rect; 
     972            ScrollArrow dirn; 
     973            switch(w.label) { 
     974            case "up":     dirn = ScrollArrow.Up; break; 
     975            case "down":   dirn = ScrollArrow.Down; break; 
     976            case "right":  dirn = ScrollArrow.Right; break; 
     977            default:       dirn = ScrollArrow.Left; 
     978            } 
     979            elem[dirn].texColor.blend( iState, m_elapsedTime, 0.8); 
     980            draw_elem_texture(elem[dirn], r); 
     981        } 
     982    } 
     983    void scrolltrack_draw(Widget widget) { 
     984        auto w = cast(ScrollBar.ScrollTrack)widget; assert(w); 
     985        Element[] elem = get_widget_elements(w); 
     986        with(w) { 
     987            WidgetState iState = WidgetState.Normal; 
     988            if( !enabled ) { 
     989                iState = WidgetState.Disabled; 
     990            } 
     991 
     992            Rect track_rect = rect; 
     993            elem[0].texColor.blend( iState, m_elapsedTime, 0.8 ); 
     994            if (horizontal) { 
     995                draw_elem_texture( elem[0], track_rect ); 
     996            } 
     997            else { 
     998                glPushMatrix(); 
     999                // Rotate rectangle 
     1000                Rect r = Rect(0,0,track_rect.h,track_rect.w); 
     1001                r.x = -r.w/2; 
     1002                r.y = -r.h/2; 
     1003                glTranslatef(rect.x+rect.w/2, rect.y+rect.h/2, 0); 
     1004                glRotatef(90,0,0,1); 
     1005                draw_elem_texture( elem[0], r ); 
     1006                glPopMatrix(); 
     1007            } 
     1008 
     1009            Rect thumb_rect = rect; 
     1010            int thumb_w = (elem[1].texRect[2] - elem[1].texRect[0])/2; 
     1011            int thumb_h = (elem[1].texRect[3] - elem[1].texRect[1])/2; 
     1012            thumb_rect.size = Size(thumb_w,thumb_h); 
     1013            if (thumb_rect.w > rect.w) { 
     1014                float shrinkby = rect.w/thumb_rect.w; 
     1015                thumb_rect.h *= shrinkby; 
     1016                thumb_rect.w = rect.w; 
     1017            } 
     1018            if (thumb_rect.h > rect.h) { 
     1019                float shrinkby = rect.h/thumb_rect.h; 
     1020                thumb_rect.w *= shrinkby; 
     1021                thumb_rect.h = rect.h; 
     1022            } 
     1023            elem[1].texColor.blend( iState, m_elapsedTime, 0.8 ); 
     1024            if ( horizontal ) { 
     1025                float t = (value-value_min)/(value_max-value_min); 
     1026                float v = rect.x + thumb_rect.w/2 + t*(rect.w-thumb_rect.w); 
     1027                thumb_rect.x = v-thumb_rect.w/2; 
     1028                thumb_rect.y = track_rect.y + (track_rect.h-thumb_rect.h)/2; 
     1029                draw_elem_texture( elem[1], thumb_rect ); 
     1030            } else { 
     1031                float t = (value-value_min)/(value_max-value_min); 
     1032                float v = rect.y2 - thumb_rect.w/2 - t*(rect.h-thumb_rect.h); 
     1033                thumb_rect = Rect(-thumb_rect.h/2,-thumb_rect.w/2,  
     1034                                  thumb_rect.h,   thumb_rect.w); 
     1035                glPushMatrix(); 
     1036                glTranslatef(rect.x+rect.w/2, v, 0); 
     1037                glRotatef(90,0,0,1); 
     1038                draw_elem_texture( elem[1], thumb_rect ); 
     1039                glPopMatrix(); 
     1040            } 
     1041        } 
     1042    } 
    8581043    //----PANEL------------------------------------------------------------- 
    8591044    void panel_register() { 
     
    8621047    void spinner_register() { 
    8631048    } 
    864     //----RADIOGROUP-------------------------------------------------------- 
    865     void radiogroup_register() { 
    866     } 
    867     //----RADIOBUTTON------------------------------------------------------- 
    868     void radiobutton_register() { 
     1049    //----OPTIONMENU-------------------------------------------------------- 
     1050    void optionmenu_register() { 
    8691051    } 
    8701052 
     
    8831065    float m_elapsedTime = 0; 
    8841066} 
     1067 
     1068 
    8851069 
    8861070