Changeset 11

Show
Ignore:
Timestamp:
11/25/06 08:01:52 (2 years ago)
Author:
baxissimo
Message:

You can manipulate the slider now.
Also changed events to be struct pointers instead of inout, because inout doesn't seem to work in a template parameter right now.
Also switch everything over std.signals/signalobj instead of Lutger's sslot class.

Files:

Legend:

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

    r7 r11  
    2828module luigi.adaptor.base; 
    2929 
    30 import sslot.signal; 
     30//import sslot.signal; 
     31import luigi.signalobj; 
    3132import luigi.base; 
    3233import luigi.event; 
     
    8990{ 
    9091    //------------------------------------------------------- 
    91     // Use 'emit' to emit signals from your InputAdaptor implementation. 
     92    // Use 'sig.*.emit' to emit signals from your InputAdaptor implementation. 
    9293    // Use example:   
    9394    //       KeyEvent ev; 
    9495    //       [...build KeyEvent from native data...] 
    95     //       emit.key(ev); 
     96    //       sig.key.emit(ev); 
    9697 
    9798    // You MUST call this from your Adaptor's constructor! 
     
    118119    } 
    119120    private _LuigiSignals _lsig; 
    120     alias _lsig emit; 
    121     alias _lsig sigs; 
     121    alias _lsig sig; 
    122122 
    123123    // Implementation of InputAdaptor 
    124     void addKeyCallback(KeyEventFn cb)                 {_lsig.key.connect(cb);} 
    125     void addMouseButtonCallback(MouseButtonEventFn cb) {_lsig.mouseButton.connect(cb);} 
    126     void addMouseMoveCallback(MouseMoveEventFn cb)     {_lsig.mouseMove.connect(cb);} 
    127     void addMouseWheelCallback(MouseWheelEventFn cb)   {_lsig.mouseWheel.connect(cb);} 
    128     void addWindowSizeCallback(WindowSizeEventFn cb)   {_lsig.windowSize.connect(cb);} 
    129     void addWindowCloseCallback(WindowCloseEventFn cb) {_lsig.windowClose.connect(cb);}  
     124    void addKeyCallback(KeyEventFn cb)                 {_lsig.key.fconnect(cb);} 
     125    void addMouseButtonCallback(MouseButtonEventFn cb) {_lsig.mouseButton.fconnect(cb);} 
     126    void addMouseMoveCallback(MouseMoveEventFn cb)     {_lsig.mouseMove.fconnect(cb);} 
     127    void addMouseWheelCallback(MouseWheelEventFn cb)   {_lsig.mouseWheel.fconnect(cb);} 
     128    void addWindowSizeCallback(WindowSizeEventFn cb)   {_lsig.windowSize.fconnect(cb);} 
     129    void addWindowCloseCallback(WindowCloseEventFn cb) {_lsig.windowClose.fconnect(cb);}  
    130130 
    131131    // And again for delegates... 
    132     void addKeyCallback(KeyEventDg cb)                 {_lsig.key.connect(cb);}          
    133     void addMouseButtonCallback(MouseButtonEventDg cb) {_lsig.mouseButton.connect(cb);}  
    134     void addMouseMoveCallback(MouseMoveEventDg cb)     {_lsig.mouseMove.connect(cb);}    
    135     void addMouseWheelCallback(MouseWheelEventDg cb)   {_lsig.mouseWheel.connect(cb);}   
    136     void addWindowSizeCallback(WindowSizeEventDg cb)   {_lsig.windowSize.connect(cb);}   
    137     void addWindowCloseCallback(WindowCloseEventDg cb) {_lsig.windowClose.connect(cb);}  
     132    void addKeyCallback(KeyEventDg cb)                 {_lsig.key.fconnect(cb);}          
     133    void addMouseButtonCallback(MouseButtonEventDg cb) {_lsig.mouseButton.fconnect(cb);}  
     134    void addMouseMoveCallback(MouseMoveEventDg cb)     {_lsig.mouseMove.fconnect(cb);}    
     135    void addMouseWheelCallback(MouseWheelEventDg cb)   {_lsig.mouseWheel.fconnect(cb);}   
     136    void addWindowSizeCallback(WindowSizeEventDg cb)   {_lsig.windowSize.fconnect(cb);}   
     137    void addWindowCloseCallback(WindowCloseEventDg cb) {_lsig.windowClose.fconnect(cb);}  
    138138 
    139139} 
  • trunk/luigi/adaptor/glfw.d

    r7 r11  
    3232import luigi.adaptor.base; 
    3333import derelict.glfw.glfw; 
    34 import sslot.signal; 
     34//import sslot.signal; 
     35import luigi.signalobj; 
    3536 
    3637import std.stdio : writefln; 
     
    157158    static void keyCallbackC(int k, int action) 
    158159    { 
    159         KeyEvent ev; 
     160        _KeyEvent ev; 
    160161        ev.key = translate_key(k); 
    161162        m_lastKey = ev.key; 
     
    165166        ev.is_key = true; 
    166167        ev.is_char = false; 
    167         inst.emit.key(ev); 
     168        inst.sig.key.emit(&ev); 
    168169    } 
    169170    static void charCallbackC(int ch, int action) 
    170171    { 
    171         KeyEvent ev; 
     172        _KeyEvent ev; 
    172173        // In practice it seems that char callbacks always come _after_ 
    173174        // key callbacks. (That's probably the case for any sane operating system). 
     
    182183        ev.is_key = false; 
    183184        ev.is_char = true; 
    184         inst.emit.key(ev); 
     185        inst.sig.key.emit(&ev); 
    185186    } 
    186187    static void mouseButtonCallbackC(int button, int action) 
    187188    { 
    188         MouseButtonEvent ev; 
     189        _MouseButtonEvent ev;  
    189190        int x,y; 
    190191        glfwGetMousePos(&x, &y); 
     
    198199        else if (button == GLFW_MOUSE_BUTTON_MIDDLE) ev.button = MouseButtons.Middle; 
    199200         
    200         inst.emit.mouseButton(ev); 
     201        inst.sig.mouseButton.emit(&ev); 
    201202    } 
    202203    static void mousePosCallbackC(int x, int y) 
    203204    { 
    204         MouseMoveEvent ev; 
     205        _MouseMoveEvent ev; 
    205206        ev.x = ev.winx = x; 
    206207        ev.y = ev.winy = y; 
     
    208209        ev.mods = inst._getMods(); 
    209210 
    210         inst.emit.mouseMove(ev); 
     211        inst.sig.mouseMove.emit(&ev); 
    211212    } 
    212213    static void mouseWheelCallbackC(int pos) 
    213214    { 
    214         MouseWheelEvent ev; 
     215        _MouseWheelEvent ev; 
    215216        int x,y; 
    216217        glfwGetMousePos(&x, &y); 
     
    222223        inst.m_lastWheelPos = pos; 
    223224 
    224         inst.emit.mouseWheel(ev); 
     225        inst.sig.mouseWheel.emit(&ev); 
    225226    } 
    226227    static void windowSizeCallbackC(int width, int height) 
    227228    { 
    228         WindowSizeEvent ev; 
     229        _WindowSizeEvent ev; 
    229230        ev.w = width; 
    230231        ev.h = height; 
    231         inst.emit.windowSize(ev); 
     232        inst.sig.windowSize.emit(&ev); 
    232233    } 
    233234    static int  windowCloseCallbackC() 
    234235    { 
    235         WindowCloseEvent ev; 
    236         inst.emit.windowClose(ev); 
     236        _WindowCloseEvent ev; 
     237        inst.sig.windowClose.emit(&ev); 
    237238        return true; 
    238239    } 
  • trunk/luigi/arranger.d

    r10 r11  
    231231 
    232232    override void add(Arrangeable item, ...) 
    233     { 
     233    in {  
    234234        assert(_arguments.length == 0, "FlowArranger.add does not take arguments"); 
     235    } 
     236    body{ 
    235237        m_items ~= item; 
    236238        return item; 
     
    238240 
    239241    override void remove(Arrangeable item, ...) 
    240    
     242    in
    241243        assert(_arguments.length == 0, "FlowArranger.remove does not take arguments"); 
     244    } 
     245    body{ 
    242246        m_items.drop_item(item); 
    243247    } 
     
    566570 
    567571    override  void add(Arrangeable item, ...) 
    568    
     572    in
    569573        assert(_arguments.length == 0, "GridArranger.add does not take arguments"); 
     574    } 
     575    body{ 
    570576        m_items ~= item; 
    571577        return item; 
     
    573579 
    574580    override  void remove(Arrangeable item, ...) 
    575    
     581    in
    576582        assert(_arguments.length == 0, "GridArranger.remove does not take arguments"); 
     583    } 
     584    body{ 
    577585        m_items.drop_item(item); 
    578586    } 
     
    814822 
    815823    override  void add(Arrangeable item, ...) 
    816     { 
    817         assert(_arguments.length <= 1, "BorderArranger.add takes one argument, a Region."); 
     824    in { 
     825        assert(_arguments.length <= 1, 
     826               "BorderArranger.add takes one argument, a Region."); 
    818827        if (_arguments.length == 1) { 
    819828            assert(_arguments[0] == typeid(Region)); 
    820829        } 
    821  
     830    } 
     831    body{ 
    822832        Region place; 
    823833        if (_arguments.length == 1) { 
     
    868878 
    869879    override  void remove(Arrangeable item, ...) 
    870    
     880    in
    871881        assert(_arguments.length <= 1, "BorderArranger.remove takes one argument, a Region."); 
    872882        if (_arguments.length == 1) { 
    873883            assert(_arguments[0] == typeid(Region)); 
    874884        } 
    875  
     885    } 
     886    body{ 
    876887        if (item != null) {  
    877888            if (item == m_north) { m_north = null; } 
  • trunk/luigi/base.d

    r7 r11  
    9696        else {            y+=v; h-=2*v; } 
    9797    } 
     98 
     99    /** Intersection of two rects. */ 
     100    void intersect(Rect o) { 
     101 
     102    } 
     103    /** Grow rect to enclose other rect (union of rects.) */ 
     104    void enclose(Rect o) { 
     105        enclose(o.pos); 
     106        enclose(Point(o.x2,o.y2)); 
     107    } 
     108    /** Grow rect to enclose point p. */ 
     109    void enclose(Point p) { 
     110        if (p.x < x) {  w = x2-p.x;  x = p.x; } 
     111        else if (p.x > x2) {  x2 = p.x; } 
     112        if (p.y < y) {  h = y2-p.y;  y = p.y; } 
     113        else if (p.y > y2) {  y2 = p.y; } 
     114    } 
     115 
    98116 
    99117    char[] toString() { 
  • trunk/luigi/event.d

    r7 r11  
    2929module luigi.event; 
    3030 
    31 import sslot.signal; 
     31//import sslot.signal; 
     32import luigi.signalobj; 
    3233import luigi.base; 
    3334 
     
    152153 
    153154 
    154 enum EventStatus { 
    155     Alive = 0, 
    156     Dead = 1, 
    157  
    158     OK = 0, 
    159     Abort = 1, 
    160 
    161  
    162 struct KeyEvent 
     155struct _KeyEvent 
    163156{ 
    164157    union { 
     
    180173    bool is_char; 
    181174    bool is_key; 
    182 
    183  
    184 struct MouseButtonEvent 
     175 
     176    bool is_alive = false; 
     177    bool alive(bool tf) { return is_alive=tf; } 
     178    bool alive() { return is_alive; } 
     179
     180 
     181struct _MouseButtonEvent 
    185182{ 
    186183    union { 
     
    195192    bool is_release() { return !is_press; } 
    196193    MouseButtons button; 
     194    bool is_left() { return (button & MouseButtons.Left)!=0; } 
     195    bool is_right() { return (button & MouseButtons.Right)!=0; } 
     196    bool is_middle() { return (button & MouseButtons.Middle)!=0; } 
    197197    MouseButtons pressed; 
    198198    bool left_down() { return (pressed & MouseButtons.Left)!=0; } 
     
    203203    bool ctrl_down() { return (mods & KeyMods.Ctrl)!=0; } 
    204204    bool alt_down() { return (mods & KeyMods.Alt)!=0; } 
    205 
    206  
    207 struct MouseMoveEvent 
     205 
     206    bool is_alive = false; 
     207    bool alive(bool tf) { return is_alive=tf; } 
     208    bool alive() { return is_alive; } 
     209
     210 
     211struct _MouseMoveEvent 
    208212{ 
    209213    union { 
     
    223227    bool ctrl_down() { return (mods & KeyMods.Ctrl)!=0; } 
    224228    bool alt_down() { return (mods & KeyMods.Alt)!=0; } 
    225 
    226  
    227 struct MouseWheelEvent 
     229 
     230    bool is_alive = false; 
     231    bool alive(bool tf) { return is_alive=tf; } 
     232    bool alive() { return is_alive; } 
     233
     234 
     235struct _MouseWheelEvent 
    228236{ 
    229237    union { 
     
    244252    bool ctrl_down() { return (mods & KeyMods.Ctrl)!=0; } 
    245253    bool alt_down() { return (mods & KeyMods.Alt)!=0; } 
    246 
    247  
    248 struct WindowSizeEvent 
     254 
     255    bool is_alive = false; 
     256    bool alive(bool tf) { return is_alive=tf; } 
     257    bool alive() { return is_alive; } 
     258
     259 
     260struct _WindowSizeEvent 
    249261{ 
    250262    WindowHandle id; 
     
    252264    alias width w; 
    253265    alias height h; 
    254 
    255  
    256 struct WindowCloseEvent 
     266 
     267    bool is_alive = false; 
     268    bool alive(bool tf) { return is_alive=tf; } 
     269    bool alive() { return is_alive; } 
     270
     271 
     272struct _WindowCloseEvent 
    257273{ 
    258274    WindowHandle id; 
     275 
     276    bool is_alive = false; 
     277    bool alive(bool tf) { return is_alive=tf; } 
     278    bool alive() { return is_alive; } 
    259279} 
    260280 
     
    262282/// extern luigi.gui.Widget; 
    263283 
    264 struct FocusEvent 
     284struct _FocusEvent 
    265285{ 
    266286    Object previous; 
    267 
    268  
    269  
    270 alias int function(KeyEvent)         KeyEventFn; 
    271 alias int function(MouseButtonEvent) MouseButtonEventFn; 
    272 alias int function(MouseMoveEvent)   MouseMoveEventFn; 
    273 alias int function(MouseWheelEvent)  MouseWheelEventFn; 
    274 alias int function(WindowSizeEvent)  WindowSizeEventFn; 
    275 alias int function(WindowCloseEvent) WindowCloseEventFn; 
    276  
    277 alias int delegate(KeyEvent)         KeyEventDg; 
    278 alias int delegate(MouseButtonEvent) MouseButtonEventDg; 
    279 alias int delegate(MouseMoveEvent)   MouseMoveEventDg; 
    280 alias int delegate(MouseWheelEvent)  MouseWheelEventDg; 
    281 alias int delegate(WindowSizeEvent)  WindowSizeEventDg; 
    282 alias int delegate(WindowCloseEvent) WindowCloseEventDg; 
    283  
    284 alias Signal!(int, KeyEvent)         KeyEventSignal; 
    285 alias Signal!(int, MouseButtonEvent) MouseButtonEventSignal; 
    286 alias Signal!(int, MouseMoveEvent)   MouseMoveEventSignal; 
    287 alias Signal!(int, MouseWheelEvent)  MouseWheelEventSignal; 
    288 alias Signal!(int, WindowSizeEvent)  WindowSizeEventSignal; 
    289 alias Signal!(int, WindowCloseEvent) WindowCloseEventSignal; 
    290  
     287 
     288    bool is_alive = false; 
     289    bool alive(bool tf) { return is_alive=tf; } 
     290    bool alive() { return is_alive; } 
     291
     292 
     293 
     294alias _KeyEvent* KeyEvent; 
     295alias _MouseButtonEvent* MouseButtonEvent; 
     296alias _MouseMoveEvent* MouseMoveEvent; 
     297alias _MouseWheelEvent* MouseWheelEvent; 
     298alias _WindowSizeEvent* WindowSizeEvent; 
     299alias _WindowCloseEvent* WindowCloseEvent; 
     300alias _FocusEvent* FocusEvent; 
     301 
     302alias void function(KeyEvent)         KeyEventFn; 
     303alias void function(MouseButtonEvent) MouseButtonEventFn; 
     304alias void function(MouseMoveEvent)   MouseMoveEventFn; 
     305alias void function(MouseWheelEvent)  MouseWheelEventFn; 
     306alias void function(WindowSizeEvent)  WindowSizeEventFn; 
     307alias void function(WindowCloseEvent) WindowCloseEventFn; 
     308 
     309alias void delegate(KeyEvent)         KeyEventDg; 
     310alias void delegate(MouseButtonEvent) MouseButtonEventDg; 
     311alias void delegate(MouseMoveEvent)   MouseMoveEventDg; 
     312alias void delegate(MouseWheelEvent)  MouseWheelEventDg; 
     313alias void delegate(WindowSizeEvent)  WindowSizeEventDg; 
     314alias void delegate(WindowCloseEvent) WindowCloseEventDg; 
     315 
     316alias FlexSignal!(KeyEvent)         KeyEventSignal; 
     317alias FlexSignal!(MouseButtonEvent) MouseButtonEventSignal; 
     318alias FlexSignal!(MouseMoveEvent)   MouseMoveEventSignal; 
     319alias FlexSignal!(MouseWheelEvent)  MouseWheelEventSignal; 
     320alias FlexSignal!(WindowSizeEvent)  WindowSizeEventSignal; 
     321alias FlexSignal!(WindowCloseEvent) WindowCloseEventSignal; 
     322 
  • trunk/luigi/example1.brf

    r10 r11  
    1 -g 
    2 -debug 
     1-release 
    32-I$(DMDDIR)\baxissimo 
    43-I$(DMDDIR)\ext 
  • trunk/luigi/example1.d

    r10 r11  
    5656} 
    5757 
    58  
    59 // doesn't work .. ICE if you try to use this 
    60 class 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 } 
    68 class 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 } 
    77 class 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 } 
    8658 
    8759void main(char[][] argv) 
     
    155127            }); 
    156128*/ 
    157             auto T = new BDelegate(  
     129            auto T = new DelegateSlot!(Widget,bool)( 
    158130                (Widget w, bool onoff) 
    159131                {  
     
    173145            Button b4 = g.add_widget(new Button("Click me!")); 
    174146            //b4.clicked.connect( (Widget w){ writefln("Ouch! Not so hard!"); } );  
    175             auto T = new VDelegate((Widget w){ writefln("Ouch! Not so hard!"); } );  
     147            auto T = new DelegateSlot!(Widget)((Widget w){ writefln("Ouch! Not so hard!"); } );  
    176148            b4.clicked.connect( &T.slot ); 
    177149        } 
     
    195167            Button b29 = arranged( g.add_widget(new Button("Tool9"))); 
    196168            Slider s01 = arranged( g.add_widget(new Slider("Thingy"))); 
    197             auto T = new CoolTarget!(double)((double d){ writefln("Slider now %s",d); } ); 
    198             s01.value_changed.fconnect!(typeof(&T.slot),1)(&T.slot); 
     169            Slider s02 = arranged( g.add_widget(new Slider("Thingy"))); 
     170            s02.vertical = true; 
     171            s01.precision = 0.1; 
     172            s02.precision = 0.1; 
     173            auto T = new DelegateSlot!(double)((double d){ writefln("Slider now %s",d); } ); 
     174            s01.value_changed.fconnect2nd(&T.slot); 
     175            s02.value_changed.fconnect2nd(&T.slot); 
     176            s02.value_changed.fconnect2nd(&s01.value); 
     177            s01.value_changed.fconnect2nd(&s02.value); 
    199178        } 
    200179 
  • trunk/luigi/gui.d

    r10 r11  
    3131  William Baxter wbaxter@gmail.com 
    3232*/ 
     33 
     34/* 
     35  WARNING: Because of how overloading works in D as of 0.174,  
     36           ** ALL SETTERS SHOULD COME BEFORE GETTERS ** 
     37  I.e. 
     38 
     39          int value(int newval) 
     40 
     41   should always appear before  
     42 
     43          int value() 
     44 
     45   Otherwise, signal.fconnect will connect to the getter rather  
     46   than the setter. 
     47 */ 
    3348 
    3449module luigi.gui; 
     
    7590    } 
    7691 
     92    Theme theme(Theme th) { return m_theme=th; } 
    7793    Theme theme() { return m_theme; } 
    7894 
     
    272288 
    273289 
     290    void enable(bool isEnabled=true) { return m_enabled = isEnabled; } 
     291    void disable() { m_enabled = false; } 
    274292    bool enabled() { return m_enabled; } 
    275293    bool disabled() { return !m_enabled; } 
    276     void enable(bool isEnabled=true) { return m_enabled = isEnabled; } 
    277     void disable() { m_enabled = false; } 
    278294     
    279295    void show() { m_shown = true; } 
    280296    void hide() { m_shown = false; } 
     297    bool shown(bool show_) { return m_shown = show_; } 
    281298    bool shown() { return m_shown; } 
    282     bool shown(bool show_) { return m_shown = show_; } 
    283299 
    284300 
     
    367383    } 
    368384 
    369     bool focusable()  
    370     in {  get_root()._focus_sanity_check(); } body 
    371     {  
    372         return m_focusable && m_enabled; 
    373     } 
    374  
    375385    bool focusable(bool onOff)  
    376386    in {  get_root()._focus_sanity_check(); } body 
     
    391401    } 
    392402 
     403    bool focusable()  
     404    in {  get_root()._focus_sanity_check(); } body 
     405    {  
     406        return m_focusable && m_enabled; 
     407    } 
     408 
    393409    /** Finds the keyboard focus of this widget's hierarchy. */ 
    394410    Widget get_focus() 
     
    428444        // now focus this guy. 
    429445        // Set his m_focused flag and percolate m_childFocused flags up the chain. 
    430         FocusEvent ev; 
     446        _FocusEvent ev; 
    431447        ev.previous = oldFocus; 
    432         int ret = this.on_focus(ev); 
    433         if (ret==EventStatus.OK) { 
     448        this.on_focus(&ev); 
     449        if (!ev.alive) { 
    434450            m_focused = true; 
    435451            if (parent) parent._set_child_focused_rup(); 
     
    536552    //--------------------------------------------------- 
    537553    // Base widget event handling 
    538     int on_key(inout KeyEvent ev) { 
    539         writefln("widget got key %0.1f %0.1f - ", ev.x-rect.x, ev.y-rect.y, this); 
    540         return 0; 
    541     } 
    542     int on_mouse_button(inout MouseButtonEvent ev) 
     554    void on_key(KeyEvent ev) { 
     555        ev.alive = true; 
     556    } 
     557    void on_mouse_button(MouseButtonEvent ev) 
    543558    { 
    544559        alias .toString str; 
     560        version (LuigiTrace) 
    545561        writefln("button %s %s: ",str(ev.button), ev.is_press?"press":"release",  
    546562                 "(%s) [%s] ", str(ev.pressed), str(ev.mods),  
    547563                 "(%0.1f,%0.1f) - ", ev.x-rect.x, ev.y-rect.y, 
    548564                 this); 
    549         return 0; 
    550     } 
    551     int on_mouse_move(inout MouseMoveEvent ev) 
    552     { 
    553         //writefln("widget got mouse move %0.1f %0.1f - ", ev.x-rect.x, ev.y-rect.y, this); 
    554         return 0; 
    555     } 
    556     int on_mouse_wheel(inout MouseWheelEvent ev) 
    557     { 
    558         writefln("widget got wheel %0.1f %0.1f - ", ev.x-rect.x, ev.y-rect.y, this); 
    559         return 0; 
    560     } 
    561  
    562     int on_focus(inout FocusEvent ev) { 
     565        ev.alive = true; 
     566    } 
     567    void on_mouse_move(MouseMoveEvent ev) 
     568    { 
     569        ev.alive = true; 
     570    } 
     571    void on_mouse_wheel(MouseWheelEvent ev) 
     572    { 
     573        ev.alive = true; 
     574    } 
     575 
     576    void on_focus(FocusEvent ev) { 
    563577        // TODO: do focus change notifications for those who care? 
    564578        Button b = cast(Button)this; 
    565         return EventStatus.OK; 
    566     } 
    567  
     579    } 
     580 
     581    void stretch(ubyte both)       { m_stretchx = m_stretchy = both; } 
     582    void stretch(ubyte x, ubyte y) { m_stretchx = x; m_stretchy = y; } 
     583    int stretch_x(int s) { return m_stretchx=s; } 
     584    int stretch_y(int s) { return m_stretchy=s; } 
    568585    int stretch_x() { return m_stretchx; } 
    569586    int stretch_y() { return m_stretchy; } 
    570     void stretch(ubyte both)       { m_stretchx = m_stretchy = both; } 
    571     void stretch(ubyte x, ubyte y) { m_stretchx = x; m_stretchy = y; } 
    572587 
    573588    //------------------------------------------------------------------------ 
     
    691706    } 
    692707 
    693     override Arranger arranger() { return super.arranger(); } 
    694708    override Arranger arranger(Arranger a) {  
    695709        super.arranger(a); 
     
    703717        return arranger;  
    704718    } 
     719    override Arranger arranger() { return super.arranger(); } 
    705720     
    706721    override Widget[] children() { return m_children; } 
     
    10461061 
    10471062    // Top-level event interface callbacks 
    1048     final int on_sys_key(KeyEvent ev) { 
     1063    final void on_sys_key(KeyEvent ev) { 
    10491064        // find the innermost focus item and send it the key event 
    10501065        Widget focus = get_focus(); 
    1051         int ret = EventStatus.Alive; 
    1052         if (focus) {  
    1053             ret = focus.on_key(ev); 
    1054         } 
    1055         if (ret==EventStatus.Alive && ev.is_press)  
     1066        if (focus) { 
     1067            Luigi().theme.on_key(focus,ev); 
     1068        } 
     1069        if ((!focus || ev.alive) && ev.is_press)  
    10561070        { 
    10571071            // if the key wasn't consumed, check for tab/shift-tab 
     
    10671081            } 
    10681082        } 
    1069          
    1070         return ret; 
    1071     } 
    1072     final int on_sys_mouse_button(MouseButtonEvent ev) 
     1083    } 
     1084    final void on_sys_mouse_button(MouseButtonEvent ev) 
    10731085    { 
    10741086        Widget target; 
     
    10801092        } 
    10811093        if (target) { 
    1082             // try to give it focus.  TODO: click_focusable attribute? 
     1094            // try to give it focus. 
    10831095            target.focus(); 
    10841096            _event_to_widget(target, ev); 
    1085             return target.on_mouse_button(ev); 
    1086         } 
    1087         return 0; 
    1088     } 
    1089     final int on_sys_mouse_move(MouseMoveEvent ev) 
     1097            Luigi().theme.on_mouse_button(target, ev); 
     1098        } 
     1099    } 
     1100    final void on_sys_mouse_move(MouseMoveEvent ev) 
    10901101    { 
    10911102        Widget target; 
     
    10981109        if (target) { 
    10991110            _event_to_widget(target, ev); 
    1100             return target.on_mouse_move(ev); 
    1101         } 
    1102         return 0; 
    1103     } 
    1104     final int on_sys_mouse_wheel(MouseWheelEvent ev) 
     1111            Luigi().theme.on_mouse_move(target, ev); 
     1112        } 
     1113    } 
     1114    final void on_sys_mouse_wheel(MouseWheelEvent ev) 
    11051115    { 
    11061116        Widget target; 
     
    11131123        if (target) { 
    11141124            _event_to_widget(target, ev); 
    1115             return target.on_mouse_wheel(ev); 
     1125            Luigi().theme.on_mouse_wheel(target, ev); 
    11161126        } 
    11171127        return 0; 
    11181128    } 
    1119     final int on_sys_window_close(WindowCloseEvent ev) 
    1120     { 
    1121         return 0; 
    1122     } 
    1123     final int on_sys_window_size(WindowSizeEvent ev)  
     1129    final void on_sys_window_close(WindowCloseEvent ev) 
     1130    { 
     1131    } 
     1132    final void on_sys_window_size(WindowSizeEvent ev)  
    11241133    { 
    11251134        //writefln("Size changed! : %f, %f", ev.w, ev.h); 
    11261135        set_rect(Rect(0,0,ev.w, ev.h)); 
    1127         return 0; 
    11281136    } 
    11291137 
     
    11721180interface Valuator 
    11731181{ 
     1182    /** Set the current value as a double */ 
     1183    double value(double); 
    11741184    /** Get the current value as a double */ 
    11751185    double value(); 
    1176     /** Set the current value as a double */ 
    1177     double value(double); 
    11781186} 
    11791187 
     
    11831191    mixin WidgetMixin; 
    11841192 
    1185     override int on_key(inout KeyEvent ev) 
     1193    override void on_key(KeyEvent ev) 
    11861194    { 
    11871195        if (ev.is_press) { 
     
    11911199            { 
    11921200                clicked.emit(this); 
    1193                 return EventStatus.Dead
    1194             } 
    1195         } 
    1196         return EventStatus.Alive; 
     1201                return
     1202            } 
     1203        } 
     1204        ev.alive = true; 
    11971205    } 
    11981206     
    1199     override int on_mouse_button(inout MouseButtonEvent ev) 
    1200     { 
    1201         if (disabled) return EventStatus.Alive; 
     1207    override void on_mouse_button(MouseButtonEvent ev) 
     1208    { 
     1209        if (disabled) { ev.alive=true; return; } 
    12021210 
    12031211        alias MouseButtons b; 
     
    12111219            m_depressed = false; 
    12121220        } 
    1213         return EventStatus.Dead; 
    1214     } 
    1215  
    1216     override int on_mouse_move(inout MouseMoveEvent ev) 
    1217     { 
    1218         if (disabled) return EventStatus.Alive; 
     1221    } 
     1222 
     1223    override void on_mouse_move(MouseMoveEvent ev) 
     1224    { 
     1225        if (disabled) { ev.alive=true; return; } 
    12191226 
    12201227        if (is_grabbing_mouse()) 
    12211228        { 
    12221229            m_depressed = rect.contains(ev.p); 
    1223             return EventStatus.Dead; 
    1224         } 
    1225         return EventStatus.Alive; 
    1226     } 
    1227  
     1230            return; 
     1231        } 
     1232        ev.alive = true; 
     1233    } 
    12281234 
    12291235    this(char[] label_) { 
     
    12491255    mixin WidgetMixin; 
    12501256 
     1257    override double value(double v) { return m_checked=(v!=0); } 
    12511258    override double value() { return m_checked; } 
    1252     override double value(double v) { return m_checked=(v!=0); } 
    1253  
    1254     override int on_key(inout KeyEvent ev) 
     1259 
     1260    override void on_key(KeyEvent ev) 
    12551261    { 
    12561262        if (ev.is_press) { 
     
    12611267                m_checked = !m_checked; 
    12621268                value_changed.emit(this,m_checked); 
    1263                 return EventStatus.Dead
    1264             } 
    1265         } 
    1266         return EventStatus.Alive; 
     1269                return
     1270            } 
     1271        } 
     1272        ev.alive = true; 
    12671273    } 
    12681274     
    1269     override int on_mouse_button(inout MouseButtonEvent ev) 
    1270     { 
    1271         if (disabled) return EventStatus.Alive; 
     1275    override void on_mouse_button(MouseButtonEvent ev) 
     1276    { 
     1277        if (disabled) { ev.alive=true; return; } 
    12721278 
    12731279        alias MouseButtons b; 
     
    12841290            m_depressed = false; 
    12851291        } 
    1286         return EventStatus.Dead; 
    1287     } 
    1288  
    1289     override int on_mouse_move(inout MouseMoveEvent ev) 
    1290     { 
    1291         if (disabled) return EventStatus.Alive; 
     1292    } 
     1293 
     1294    override void on_mouse_move(MouseMoveEvent ev) 
     1295    { 
     1296        if (disabled) { ev.alive=true; return; } 
    12921297 
    12931298        if (is_grabbing_mouse()) 
    12941299        { 
    12951300            m_depressed = rect.contains(ev.p); 
    1296             return EventStatus.Dead; 
    1297         } 
    1298         return EventStatus.Alive; 
     1301        } 
     1302        ev.alive = true; 
    12991303    } 
    13001304 
     
    13231327    mixin WidgetMixin; 
    13241328 
    1325     override int on_key(inout KeyEvent ev) 
     1329    override void on_key(KeyEvent ev) 
    13261330    { 
    13271331        if (ev.is_press) { 
     
    13331337            { 
    13341338                switch(ev.key) { 
     1339                case Key.Tab: 
     1340                case Key.Escape: 
     1341                    // pass tab & escape through 
     1342                    ev.alive = true; 
     1343                    return; 
    13351344                case 'A': 
    13361345                    if (ev.ctrl_down) { 
     
    14021411                case Key.Enter: 
    14031412                case Key.KP_Enter: 
    1404                     text_accepted.emit(this); 
    1405                     return EventStatus.Dead
     1413                    text_accepted.emit(this, m_text); 
     1414                    break
    14061415                default: 
    14071416                    ; 
     
    14091418            } 
    14101419        } 
    1411         return EventStatus.Alive; 
    14121420    } 
    14131421     
    1414     override int on_mouse_button(inout MouseButtonEvent ev) 
    1415     { 
    1416         if (disabled) return EventStatus.Alive; 
     1422    override void on_mouse_button(MouseButtonEvent ev) 
     1423    { 
     1424        if (disabled) { ev.alive = true;  return; } 
    14171425 
    14181426        alias MouseButtons b; 
     
    14231431            if (is_grabbing_mouse()) {release_mouse();} 
    14241432        } 
    1425         return EventStatus.Dead; 
    1426     } 
    1427  
    1428     override int on_mouse_move(inout MouseMoveEvent ev) 
    1429     { 
    1430         if (disabled) return EventStatus.Alive; 
     1433    } 
     1434 
     1435    override void on_mouse_move(MouseMoveEvent ev) 
     1436    { 
     1437        if (disabled) { ev.alive = true; return; } 
    14311438 
    14321439        if (is_grabbing_mouse()) 
    14331440        { 
    1434             return EventStatus.Dead
    1435         } 
    1436         return EventStatus.Alive; 
     1441            return
     1442        } 
     1443        ev.alive = true; 
    14371444    } 
    14381445 
     
    14541461        // launch selection changed notificaiton 
    14551462    } 
     1463    int selection_start(int begin)   { return sel_begin = begin; } 
     1464    int selection_end(int after_end) { return sel_end = after_end; } 
    14561465    int selection_start()            { return sel_begin; } 
    14571466    int selection_end()              { return sel_end; } 
    1458     int selection_start(int begin)   { return sel_begin = begin; } 
    1459     int selection_end(int after_end) { return sel_end = after_end; } 
    14601467    int selection_length()           { return sel_end-sel_begin; } 
    14611468 
     
    14811488 
    14821489 
     1490    char[] text(char[] t) {  
     1491        if (m_text is t || (m_text && t && m_text == t)) return m_text; 
     1492        m_text = t; 
     1493        text_accepted.emit(this, m_text); 
     1494        return m_text; 
     1495    } 
    14831496    char[] text() { return m_text; } 
    1484     char[] text(char[] t) { return m_text=t; } 
    14851497 
    14861498 
     
    14961508    char [] label; 
    14971509 
    1498     alias FlexSignal!(Widget) TextAcceptedSignal; 
     1510    alias FlexSignal!(Widget, char[]) TextAcceptedSignal; 
    14991511    TextAcceptedSignal text_accepted; 
    15001512    // mixin Signal!(Widget) text_accepted; 
     
    15241536} 
    15251537 
     1538/** 
     1539 * Slider represents a floating point value.  Since it uses a double for  
     1540 * internal representation of the value it can also easily handle integral 
     1541 * numbers as large (larger even) than an int. 
     1542 * 
     1543 * The model used for tracking the value is that users can 
     1544 * programmatically set any value they wish using value() and it will 
     1545 * be honored.  However manipulations of the value through the UI are 
     1546 * restricted to integer multiples of the precision.  Zero is always 
     1547 * attainable via the UI as long as it is between max and min. 
     1548 */ 
    15261549class Slider : Widget, Valuator 
    15271550{ 
    15281551    mixin WidgetMixin; 
    15291552 
    1530     override double value() { return m_value; } 
    1531     override double value(double v) {  
     1553    override double value(double v) { 
    15321554        if (v<m_min) v=m_min; 
    15331555        if (v>m_max) v=m_max; 
    15341556        if (v==m_value) return m_value; 
     1557 
     1558        // want to have (m_value = prec * i) for some integer i 
     1559        real prec = precision; 
     1560        double i = lrint(v/prec); 
     1561        v = prec * i; 
     1562        if (v==m_value) return m_value; 
     1563 
    15351564        m_value = v; 
    15361565        value_changed.emit(this,v); 
    1537         return m_value;  
    1538     } 
     1566        return v; 
     1567    } 
     1568    override double value() { return m_value; } 
    15391569 
    15401570    this(char[] label_) { 
     
    15451575    } 
    15461576 
    1547     int on_key(inout KeyEvent ev) { 
     1577    override void on_key(KeyEvent ev) { 
     1578        double get_inc() 
     1579        { 
     1580            if (ev.ctrl_down) return m_precision; 
     1581            if (ev.shift_down) return m_page; 
     1582