Changeset 11
- Timestamp:
- 11/25/06 08:01:52 (2 years ago)
- Files:
-
- trunk/luigi/adaptor/base.d (modified) (3 diffs)
- trunk/luigi/adaptor/glfw.d (modified) (7 diffs)
- trunk/luigi/arranger.d (modified) (6 diffs)
- trunk/luigi/base.d (modified) (1 diff)
- trunk/luigi/event.d (modified) (9 diffs)
- trunk/luigi/example1.brf (modified) (1 diff)
- trunk/luigi/example1.d (modified) (4 diffs)
- trunk/luigi/gui.d (modified) (38 diffs)
- trunk/luigi/signalobj.d (modified) (3 diffs)
- trunk/luigi/theme.d (modified) (17 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/luigi/adaptor/base.d
r7 r11 28 28 module luigi.adaptor.base; 29 29 30 import sslot.signal; 30 //import sslot.signal; 31 import luigi.signalobj; 31 32 import luigi.base; 32 33 import luigi.event; … … 89 90 { 90 91 //------------------------------------------------------- 91 // Use ' emit' to emit signals from your InputAdaptor implementation.92 // Use 'sig.*.emit' to emit signals from your InputAdaptor implementation. 92 93 // Use example: 93 94 // KeyEvent ev; 94 95 // [...build KeyEvent from native data...] 95 // emit.key(ev);96 // sig.key.emit(ev); 96 97 97 98 // You MUST call this from your Adaptor's constructor! … … 118 119 } 119 120 private _LuigiSignals _lsig; 120 alias _lsig emit; 121 alias _lsig sigs; 121 alias _lsig sig; 122 122 123 123 // 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);} 130 130 131 131 // 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);} 138 138 139 139 } trunk/luigi/adaptor/glfw.d
r7 r11 32 32 import luigi.adaptor.base; 33 33 import derelict.glfw.glfw; 34 import sslot.signal; 34 //import sslot.signal; 35 import luigi.signalobj; 35 36 36 37 import std.stdio : writefln; … … 157 158 static void keyCallbackC(int k, int action) 158 159 { 159 KeyEvent ev;160 _KeyEvent ev; 160 161 ev.key = translate_key(k); 161 162 m_lastKey = ev.key; … … 165 166 ev.is_key = true; 166 167 ev.is_char = false; 167 inst. emit.key(ev);168 inst.sig.key.emit(&ev); 168 169 } 169 170 static void charCallbackC(int ch, int action) 170 171 { 171 KeyEvent ev;172 _KeyEvent ev; 172 173 // In practice it seems that char callbacks always come _after_ 173 174 // key callbacks. (That's probably the case for any sane operating system). … … 182 183 ev.is_key = false; 183 184 ev.is_char = true; 184 inst. emit.key(ev);185 inst.sig.key.emit(&ev); 185 186 } 186 187 static void mouseButtonCallbackC(int button, int action) 187 188 { 188 MouseButtonEvent ev;189 _MouseButtonEvent ev; 189 190 int x,y; 190 191 glfwGetMousePos(&x, &y); … … 198 199 else if (button == GLFW_MOUSE_BUTTON_MIDDLE) ev.button = MouseButtons.Middle; 199 200 200 inst. emit.mouseButton(ev);201 inst.sig.mouseButton.emit(&ev); 201 202 } 202 203 static void mousePosCallbackC(int x, int y) 203 204 { 204 MouseMoveEvent ev;205 _MouseMoveEvent ev; 205 206 ev.x = ev.winx = x; 206 207 ev.y = ev.winy = y; … … 208 209 ev.mods = inst._getMods(); 209 210 210 inst. emit.mouseMove(ev);211 inst.sig.mouseMove.emit(&ev); 211 212 } 212 213 static void mouseWheelCallbackC(int pos) 213 214 { 214 MouseWheelEvent ev;215 _MouseWheelEvent ev; 215 216 int x,y; 216 217 glfwGetMousePos(&x, &y); … … 222 223 inst.m_lastWheelPos = pos; 223 224 224 inst. emit.mouseWheel(ev);225 inst.sig.mouseWheel.emit(&ev); 225 226 } 226 227 static void windowSizeCallbackC(int width, int height) 227 228 { 228 WindowSizeEvent ev;229 _WindowSizeEvent ev; 229 230 ev.w = width; 230 231 ev.h = height; 231 inst. emit.windowSize(ev);232 inst.sig.windowSize.emit(&ev); 232 233 } 233 234 static int windowCloseCallbackC() 234 235 { 235 WindowCloseEvent ev;236 inst. emit.windowClose(ev);236 _WindowCloseEvent ev; 237 inst.sig.windowClose.emit(&ev); 237 238 return true; 238 239 } trunk/luigi/arranger.d
r10 r11 231 231 232 232 override void add(Arrangeable item, ...) 233 {233 in { 234 234 assert(_arguments.length == 0, "FlowArranger.add does not take arguments"); 235 } 236 body{ 235 237 m_items ~= item; 236 238 return item; … … 238 240 239 241 override void remove(Arrangeable item, ...) 240 {242 in { 241 243 assert(_arguments.length == 0, "FlowArranger.remove does not take arguments"); 244 } 245 body{ 242 246 m_items.drop_item(item); 243 247 } … … 566 570 567 571 override void add(Arrangeable item, ...) 568 {572 in{ 569 573 assert(_arguments.length == 0, "GridArranger.add does not take arguments"); 574 } 575 body{ 570 576 m_items ~= item; 571 577 return item; … … 573 579 574 580 override void remove(Arrangeable item, ...) 575 {581 in { 576 582 assert(_arguments.length == 0, "GridArranger.remove does not take arguments"); 583 } 584 body{ 577 585 m_items.drop_item(item); 578 586 } … … 814 822 815 823 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."); 818 827 if (_arguments.length == 1) { 819 828 assert(_arguments[0] == typeid(Region)); 820 829 } 821 830 } 831 body{ 822 832 Region place; 823 833 if (_arguments.length == 1) { … … 868 878 869 879 override void remove(Arrangeable item, ...) 870 {880 in{ 871 881 assert(_arguments.length <= 1, "BorderArranger.remove takes one argument, a Region."); 872 882 if (_arguments.length == 1) { 873 883 assert(_arguments[0] == typeid(Region)); 874 884 } 875 885 } 886 body{ 876 887 if (item != null) { 877 888 if (item == m_north) { m_north = null; } trunk/luigi/base.d
r7 r11 96 96 else { y+=v; h-=2*v; } 97 97 } 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 98 116 99 117 char[] toString() { trunk/luigi/event.d
r7 r11 29 29 module luigi.event; 30 30 31 import sslot.signal; 31 //import sslot.signal; 32 import luigi.signalobj; 32 33 import luigi.base; 33 34 … … 152 153 153 154 154 enum EventStatus { 155 Alive = 0, 156 Dead = 1, 157 158 OK = 0, 159 Abort = 1, 160 } 161 162 struct KeyEvent 155 struct _KeyEvent 163 156 { 164 157 union { … … 180 173 bool is_char; 181 174 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 181 struct _MouseButtonEvent 185 182 { 186 183 union { … … 195 192 bool is_release() { return !is_press; } 196 193 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; } 197 197 MouseButtons pressed; 198 198 bool left_down() { return (pressed & MouseButtons.Left)!=0; } … … 203 203 bool ctrl_down() { return (mods & KeyMods.Ctrl)!=0; } 204 204 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 211 struct _MouseMoveEvent 208 212 { 209 213 union { … … 223 227 bool ctrl_down() { return (mods & KeyMods.Ctrl)!=0; } 224 228 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 235 struct _MouseWheelEvent 228 236 { 229 237 union { … … 244 252 bool ctrl_down() { return (mods & KeyMods.Ctrl)!=0; } 245 253 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 260 struct _WindowSizeEvent 249 261 { 250 262 WindowHandle id; … … 252 264 alias width w; 253 265 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 272 struct _WindowCloseEvent 257 273 { 258 274 WindowHandle id; 275 276 bool is_alive = false; 277 bool alive(bool tf) { return is_alive=tf; } 278 bool alive() { return is_alive; } 259 279 } 260 280 … … 262 282 /// extern luigi.gui.Widget; 263 283 264 struct FocusEvent284 struct _FocusEvent 265 285 { 266 286 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 294 alias _KeyEvent* KeyEvent; 295 alias _MouseButtonEvent* MouseButtonEvent; 296 alias _MouseMoveEvent* MouseMoveEvent; 297 alias _MouseWheelEvent* MouseWheelEvent; 298 alias _WindowSizeEvent* WindowSizeEvent; 299 alias _WindowCloseEvent* WindowCloseEvent; 300 alias _FocusEvent* FocusEvent; 301 302 alias void function(KeyEvent) KeyEventFn; 303 alias void function(MouseButtonEvent) MouseButtonEventFn; 304 alias void function(MouseMoveEvent) MouseMoveEventFn; 305 alias void function(MouseWheelEvent) MouseWheelEventFn; 306 alias void function(WindowSizeEvent) WindowSizeEventFn; 307 alias void function(WindowCloseEvent) WindowCloseEventFn; 308 309 alias void delegate(KeyEvent) KeyEventDg; 310 alias void delegate(MouseButtonEvent) MouseButtonEventDg; 311 alias void delegate(MouseMoveEvent) MouseMoveEventDg; 312 alias void delegate(MouseWheelEvent) MouseWheelEventDg; 313 alias void delegate(WindowSizeEvent) WindowSizeEventDg; 314 alias void delegate(WindowCloseEvent) WindowCloseEventDg; 315 316 alias FlexSignal!(KeyEvent) KeyEventSignal; 317 alias FlexSignal!(MouseButtonEvent) MouseButtonEventSignal; 318 alias FlexSignal!(MouseMoveEvent) MouseMoveEventSignal; 319 alias FlexSignal!(MouseWheelEvent) MouseWheelEventSignal; 320 alias FlexSignal!(WindowSizeEvent) WindowSizeEventSignal; 321 alias FlexSignal!(WindowCloseEvent) WindowCloseEventSignal; 322 trunk/luigi/example1.brf
r10 r11 1 -g 2 -debug 1 -release 3 2 -I$(DMDDIR)\baxissimo 4 3 -I$(DMDDIR)\ext trunk/luigi/example1.d
r10 r11 56 56 } 57 57 58 59 // doesn't work .. ICE if you try to use this60 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 BDelegate69 {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 VDelegate78 {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 58 87 59 void main(char[][] argv) … … 155 127 }); 156 128 */ 157 auto T = new BDelegate(129 auto T = new DelegateSlot!(Widget,bool)( 158 130 (Widget w, bool onoff) 159 131 { … … 173 145 Button b4 = g.add_widget(new Button("Click me!")); 174 146 //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!"); } ); 176 148 b4.clicked.connect( &T.slot ); 177 149 } … … 195 167 Button b29 = arranged( g.add_widget(new Button("Tool9"))); 196 168 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); 199 178 } 200 179 trunk/luigi/gui.d
r10 r11 31 31 William Baxter wbaxter@gmail.com 32 32 */ 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 */ 33 48 34 49 module luigi.gui; … … 75 90 } 76 91 92 Theme theme(Theme th) { return m_theme=th; } 77 93 Theme theme() { return m_theme; } 78 94 … … 272 288 273 289 290 void enable(bool isEnabled=true) { return m_enabled = isEnabled; } 291 void disable() { m_enabled = false; } 274 292 bool enabled() { return m_enabled; } 275 293 bool disabled() { return !m_enabled; } 276 void enable(bool isEnabled=true) { return m_enabled = isEnabled; }277 void disable() { m_enabled = false; }278 294 279 295 void show() { m_shown = true; } 280 296 void hide() { m_shown = false; } 297 bool shown(bool show_) { return m_shown = show_; } 281 298 bool shown() { return m_shown; } 282 bool shown(bool show_) { return m_shown = show_; }283 299 284 300 … … 367 383 } 368 384 369 bool focusable()370 in { get_root()._focus_sanity_check(); } body371 {372 return m_focusable && m_enabled;373 }374 375 385 bool focusable(bool onOff) 376 386 in { get_root()._focus_sanity_check(); } body … … 391 401 } 392 402 403 bool focusable() 404 in { get_root()._focus_sanity_check(); } body 405 { 406 return m_focusable && m_enabled; 407 } 408 393 409 /** Finds the keyboard focus of this widget's hierarchy. */ 394 410 Widget get_focus() … … 428 444 // now focus this guy. 429 445 // Set his m_focused flag and percolate m_childFocused flags up the chain. 430 FocusEvent ev;446 _FocusEvent ev; 431 447 ev.previous = oldFocus; 432 int ret = this.on_focus(ev);433 if ( ret==EventStatus.OK) {448 this.on_focus(&ev); 449 if (!ev.alive) { 434 450 m_focused = true; 435 451 if (parent) parent._set_child_focused_rup(); … … 536 552 //--------------------------------------------------- 537 553 // 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) 543 558 { 544 559 alias .toString str; 560 version (LuigiTrace) 545 561 writefln("button %s %s: ",str(ev.button), ev.is_press?"press":"release", 546 562 "(%s) [%s] ", str(ev.pressed), str(ev.mods), 547 563 "(%0.1f,%0.1f) - ", ev.x-rect.x, ev.y-rect.y, 548 564 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) { 563 577 // TODO: do focus change notifications for those who care? 564 578 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; } 568 585 int stretch_x() { return m_stretchx; } 569 586 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; }572 587 573 588 //------------------------------------------------------------------------ … … 691 706 } 692 707 693 override Arranger arranger() { return super.arranger(); }694 708 override Arranger arranger(Arranger a) { 695 709 super.arranger(a); … … 703 717 return arranger; 704 718 } 719 override Arranger arranger() { return super.arranger(); } 705 720 706 721 override Widget[] children() { return m_children; } … … 1046 1061 1047 1062 // Top-level event interface callbacks 1048 final inton_sys_key(KeyEvent ev) {1063 final void on_sys_key(KeyEvent ev) { 1049 1064 // find the innermost focus item and send it the key event 1050 1065 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) 1056 1070 { 1057 1071 // if the key wasn't consumed, check for tab/shift-tab … … 1067 1081 } 1068 1082 } 1069 1070 return ret; 1071 } 1072 final int on_sys_mouse_button(MouseButtonEvent ev) 1083 } 1084 final void on_sys_mouse_button(MouseButtonEvent ev) 1073 1085 { 1074 1086 Widget target; … … 1080 1092 } 1081 1093 if (target) { 1082 // try to give it focus. TODO: click_focusable attribute?1094 // try to give it focus. 1083 1095 target.focus(); 1084 1096 _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) 1090 1101 { 1091 1102 Widget target; … … 1098 1109 if (target) { 1099 1110 _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) 1105 1115 { 1106 1116 Widget target; … … 1113 1123 if (target) { 1114 1124 _event_to_widget(target, ev); 1115 return target.on_mouse_wheel(ev);1125 Luigi().theme.on_mouse_wheel(target, ev); 1116 1126 } 1117 1127 return 0; 1118 1128 } 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) 1124 1133 { 1125 1134 //writefln("Size changed! : %f, %f", ev.w, ev.h); 1126 1135 set_rect(Rect(0,0,ev.w, ev.h)); 1127 return 0;1128 1136 } 1129 1137 … … 1172 1180 interface Valuator 1173 1181 { 1182 /** Set the current value as a double */ 1183 double value(double); 1174 1184 /** Get the current value as a double */ 1175 1185 double value(); 1176 /** Set the current value as a double */1177 double value(double);1178 1186 } 1179 1187 … … 1183 1191 mixin WidgetMixin; 1184 1192 1185 override int on_key(inoutKeyEvent ev)1193 override void on_key(KeyEvent ev) 1186 1194 { 1187 1195 if (ev.is_press) { … … 1191 1199 { 1192 1200 clicked.emit(this); 1193 return EventStatus.Dead;1194 } 1195 } 1196 return EventStatus.Alive;1201 return; 1202 } 1203 } 1204 ev.alive = true; 1197 1205 } 1198 1206 1199 override int on_mouse_button(inoutMouseButtonEvent ev)1200 { 1201 if (disabled) return EventStatus.Alive;1207 override void on_mouse_button(MouseButtonEvent ev) 1208 { 1209 if (disabled) { ev.alive=true; return; } 1202 1210 1203 1211 alias MouseButtons b; … … 1211 1219 m_depressed = false; 1212 1220 } 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; } 1219 1226 1220 1227 if (is_grabbing_mouse()) 1221 1228 { 1222 1229 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 } 1228 1234 1229 1235 this(char[] label_) { … … 1249 1255 mixin WidgetMixin; 1250 1256 1257 override double value(double v) { return m_checked=(v!=0); } 1251 1258 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) 1255 1261 { 1256 1262 if (ev.is_press) { … … 1261 1267 m_checked = !m_checked; 1262 1268 value_changed.emit(this,m_checked); 1263 return EventStatus.Dead;1264 } 1265 } 1266 return EventStatus.Alive;1269 return; 1270 } 1271 } 1272 ev.alive = true; 1267 1273 } 1268 1274 1269 override int on_mouse_button(inoutMouseButtonEvent ev)1270 { 1271 if (disabled) return EventStatus.Alive;1275 override void on_mouse_button(MouseButtonEvent ev) 1276 { 1277 if (disabled) { ev.alive=true; return; } 1272 1278 1273 1279 alias MouseButtons b; … … 1284 1290 m_depressed = false; 1285 1291 } 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; } 1292 1297 1293 1298 if (is_grabbing_mouse()) 1294 1299 { 1295 1300 m_depressed = rect.contains(ev.p); 1296 return EventStatus.Dead; 1297 } 1298 return EventStatus.Alive; 1301 } 1302 ev.alive = true; 1299 1303 } 1300 1304 … … 1323 1327 mixin WidgetMixin; 1324 1328 1325 override int on_key(inoutKeyEvent ev)1329 override void on_key(KeyEvent ev) 1326 1330 { 1327 1331 if (ev.is_press) { … … 1333 1337 { 1334 1338 switch(ev.key) { 1339 case Key.Tab: 1340 case Key.Escape: 1341 // pass tab & escape through 1342 ev.alive = true; 1343 return; 1335 1344 case 'A': 1336 1345 if (ev.ctrl_down) { … … 1402 1411 case Key.Enter: 1403 1412 case Key.KP_Enter: 1404 text_accepted.emit(this );1405 return EventStatus.Dead;1413 text_accepted.emit(this, m_text); 1414 break; 1406 1415 default: 1407 1416 ; … … 1409 1418 } 1410 1419 } 1411 return EventStatus.Alive;1412 1420 } 1413 1421 1414 override int on_mouse_button(inoutMouseButtonEvent ev)1415 { 1416 if (disabled) return EventStatus.Alive;1422 override void on_mouse_button(MouseButtonEvent ev) 1423 { 1424 if (disabled) { ev.alive = true; return; } 1417 1425 1418 1426 alias MouseButtons b; … … 1423 1431 if (is_grabbing_mouse()) {release_mouse();} 1424 1432 } 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; } 1431 1438 1432 1439 if (is_grabbing_mouse()) 1433 1440 { 1434 return EventStatus.Dead;1435 } 1436 return EventStatus.Alive;1441 return; 1442 } 1443 ev.alive = true; 1437 1444 } 1438 1445 … … 1454 1461 // launch selection changed notificaiton 1455 1462 } 1463 int selection_start(int begin) { return sel_begin = begin; } 1464 int selection_end(int after_end) { return sel_end = after_end; } 1456 1465 int selection_start() { return sel_begin; } 1457 1466 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; }1460 1467 int selection_length() { return sel_end-sel_begin; } 1461 1468 … … 1481 1488 1482 1489 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 } 1483 1496 char[] text() { return m_text; } 1484 char[] text(char[] t) { return m_text=t; }1485 1497 1486 1498 … … 1496 1508 char [] label; 1497 1509 1498 alias FlexSignal!(Widget ) TextAcceptedSignal;1510 alias FlexSignal!(Widget, char[]) TextAcceptedSignal; 1499 1511 TextAcceptedSignal text_accepted; 1500 1512 // mixin Signal!(Widget) text_accepted; … … 1524 1536 } 1525 1537 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 */ 1526 1549 class Slider : Widget, Valuator 1527 1550 { 1528 1551 mixin WidgetMixin; 1529 1552 1530 override double value() { return m_value; } 1531 override double value(double v) { 1553 override double value(double v) { 1532 1554 if (v<m_min) v=m_min; 1533 1555 if (v>m_max) v=m_max; 1534 1556 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 1535 1564 m_value = v; 1536 1565 value_changed.emit(this,v); 1537 return m_value; 1538 } 1566 return v; 1567 } 1568 override double value() { return m_value; } 1539 1569 1540 1570 this(char[] label_) { … … 1545 1575 } 1546 1576 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
