Mercurial > dwindows
comparison dw.hpp @ 2882:99311a9091af
C++: Add lambda support via Connect functions on C++11, on older compilers
use traditional function pointers instead. Also added inital menu support
although it is incomplete as of this commit.
author | bsmith@81767d24-ef19-dc11-ae90-00e081727c95 |
---|---|
date | Thu, 22 Dec 2022 13:59:46 +0000 |
parents | 2ba0959eb3cf |
children | 06e475feaac0 |
comparison
equal
deleted
inserted
replaced
2881:ac404083dc6b | 2882:99311a9091af |
---|---|
7 #define _HPP_DW | 7 #define _HPP_DW |
8 #include <dw.h> | 8 #include <dw.h> |
9 | 9 |
10 // Attempt to support compilers without nullptr type literal | 10 // Attempt to support compilers without nullptr type literal |
11 #if __cplusplus >= 201103L | 11 #if __cplusplus >= 201103L |
12 #define DW_CPP11 | |
12 #define DW_NULL nullptr | 13 #define DW_NULL nullptr |
14 #include <functional> | |
13 #else | 15 #else |
14 #define DW_NULL NULL | 16 #define DW_NULL NULL |
15 #endif | 17 #endif |
16 | 18 |
17 // Attempt to allow compilation on GCC older than 4.7 | 19 // Attempt to allow compilation on GCC older than 4.7 |
19 #define override | 21 #define override |
20 #endif | 22 #endif |
21 | 23 |
22 namespace DW | 24 namespace DW |
23 { | 25 { |
26 | |
27 // Forward declare these so they can be referenced | |
28 class Render; | |
29 class Pixmap; | |
30 class MenuItem; | |
31 | |
24 | 32 |
25 // Base handle class which allows opaque access to | 33 // Base handle class which allows opaque access to |
26 // The base system handles | 34 // The base system handles |
27 class Handle | 35 class Handle |
28 { | 36 { |
103 | 111 |
104 // TODO: Find a way to implement this cross platform... | 112 // TODO: Find a way to implement this cross platform... |
105 // That way we can skip adding unused signal handlers | 113 // That way we can skip adding unused signal handlers |
106 #define IsOverridden(a, b) true | 114 #define IsOverridden(a, b) true |
107 | 115 |
116 // Base class for several types of widgets including buttons and menu items | |
117 class Clickable : virtual public Widget | |
118 { | |
119 private: | |
120 bool ClickedConnected; | |
121 #ifdef DW_CPP11 | |
122 std::function<int()> _ConnectClicked; | |
123 #else | |
124 int (*_ConnectClicked)(); | |
125 #endif | |
126 static int _OnClicked(HWND window, void *data) { | |
127 if(reinterpret_cast<Clickable *>(data)->_ConnectClicked) | |
128 return reinterpret_cast<Clickable *>(data)->_ConnectClicked(); | |
129 return reinterpret_cast<Clickable *>(data)->OnClicked(); } | |
130 protected: | |
131 void Setup() { | |
132 if(IsOverridden(Clickable::OnClicked, this)) { | |
133 dw_signal_connect(hwnd, DW_SIGNAL_CLICKED, DW_SIGNAL_FUNC(_OnClicked), this); | |
134 ClickedConnected = true; | |
135 } | |
136 } | |
137 // Our signal handler functions to be overriden... | |
138 // If they are not overridden and an event is generated, remove the unused handler | |
139 virtual int OnClicked() { | |
140 dw_signal_disconnect_by_name(hwnd, DW_SIGNAL_CLICKED); | |
141 ClickedConnected = false; | |
142 return FALSE; | |
143 } | |
144 public: | |
145 #ifdef DW_CPP11 | |
146 void ConnectClicked(std::function<int()> userfunc) | |
147 #else | |
148 void ConnectClicked(int (*userfunc)()) | |
149 #endif | |
150 { | |
151 _ConnectClicked = userfunc; | |
152 if(!ClickedConnected) { | |
153 dw_signal_connect(hwnd, DW_SIGNAL_CLICKED, DW_SIGNAL_FUNC(_OnClicked), this); | |
154 ClickedConnected = true; | |
155 } | |
156 } | |
157 }; | |
158 | |
159 class Menus : public Handle | |
160 { | |
161 protected: | |
162 void SetHMENUI(HMENUI newmenu) { | |
163 menu = newmenu; | |
164 SetHandle(reinterpret_cast<void *>(newmenu)); | |
165 } | |
166 HMENUI menu; | |
167 public: | |
168 // User functions | |
169 HMENUI GetHMENUI() { return menu; } | |
170 }; | |
171 | |
172 class Menu : public Menus | |
173 { | |
174 public: | |
175 // Constructors | |
176 Menu(HWND location) { SetHMENUI(dw_menubar_new(location)); } | |
177 Menu(unsigned long id) { SetHMENUI(dw_menu_new(id)); } | |
178 Menu() { SetHMENUI(dw_menu_new(0)); } | |
179 }; | |
180 | |
181 class MenuItem : public Clickable | |
182 { | |
183 public: | |
184 // Constructors | |
185 MenuItem(Menus *menu, const char *title, unsigned long id, unsigned long flags, int end, int check, Menus *submenu) { | |
186 SetHWND(dw_menu_append_item(menu->GetHMENUI(), title, id, flags, end, check, submenu ? submenu->GetHMENUI() : DW_NULL)); | |
187 } | |
188 | |
189 // User functions | |
190 void SetState(unsigned long flags) { dw_window_set_style(hwnd, flags, flags); } | |
191 void SetStyle(unsigned long flags, unsigned long mask) { dw_window_set_style(hwnd, flags, mask); } | |
192 }; | |
193 | |
108 // Top-level window class is packable | 194 // Top-level window class is packable |
109 class Window : public Boxes | 195 class Window : public Boxes |
110 { | 196 { |
111 private: | 197 private: |
198 bool DeleteConnected, ConfigureConnected; | |
199 #ifdef DW_CPP11 | |
200 std::function<int()> _ConnectDelete; | |
201 std::function<int(int, int)> _ConnectConfigure; | |
202 #else | |
203 int (*_ConnectDelete)(); | |
204 int (*_ConnectConfigure)(int width, int height); | |
205 #endif | |
112 void Setup() { | 206 void Setup() { |
113 if(IsOverridden(Window::OnDelete, this)) | 207 if(IsOverridden(Window::OnDelete, this)) { |
114 dw_signal_connect(hwnd, DW_SIGNAL_DELETE, DW_SIGNAL_FUNC(_OnDelete), this); | 208 dw_signal_connect(hwnd, DW_SIGNAL_DELETE, DW_SIGNAL_FUNC(_OnDelete), this); |
115 if(IsOverridden(Window::OnConfigure, this)) | 209 DeleteConnected = true; |
210 } | |
211 if(IsOverridden(Window::OnConfigure, this)) { | |
116 dw_signal_connect(hwnd, DW_SIGNAL_CONFIGURE, DW_SIGNAL_FUNC(_OnConfigure), this); | 212 dw_signal_connect(hwnd, DW_SIGNAL_CONFIGURE, DW_SIGNAL_FUNC(_OnConfigure), this); |
117 } | 213 ConfigureConnected = true; |
118 static int _OnDelete(HWND window, void *data) { return reinterpret_cast<Window *>(data)->OnDelete(); } | 214 } |
119 static int _OnConfigure(HWND window, int width, int height, void *data) { return reinterpret_cast<Window *>(data)->OnConfigure(width, height); } | 215 } |
216 static int _OnDelete(HWND window, void *data) { | |
217 if(reinterpret_cast<Window *>(data)->_ConnectDelete) | |
218 return reinterpret_cast<Window *>(data)->_ConnectDelete(); | |
219 return reinterpret_cast<Window *>(data)->OnDelete(); } | |
220 static int _OnConfigure(HWND window, int width, int height, void *data) { | |
221 if(reinterpret_cast<Window *>(data)->_ConnectConfigure) | |
222 return reinterpret_cast<Window *>(data)->_ConnectConfigure(width, height); | |
223 return reinterpret_cast<Window *>(data)->OnConfigure(width, height); } | |
224 Menu *menu; | |
120 public: | 225 public: |
121 // Constructors | 226 // Constructors |
122 Window(HWND owner, const char *title, unsigned long style) { SetHWND(dw_window_new(owner, title, style)); Setup(); } | 227 Window(HWND owner, const char *title, unsigned long style) { SetHWND(dw_window_new(owner, title, style)); Setup(); } |
123 Window(const char *title, unsigned long style) { SetHWND(dw_window_new(HWND_DESKTOP, title, style)); Setup(); } | 228 Window(const char *title, unsigned long style) { SetHWND(dw_window_new(HWND_DESKTOP, title, style)); Setup(); } |
124 Window(unsigned long style) { SetHWND(dw_window_new(HWND_DESKTOP, "", style)); Setup(); } | 229 Window(unsigned long style) { SetHWND(dw_window_new(HWND_DESKTOP, "", style)); Setup(); } |
138 int Raise() { return dw_window_raise(hwnd); } | 243 int Raise() { return dw_window_raise(hwnd); } |
139 int Lower() { return dw_window_lower(hwnd); } | 244 int Lower() { return dw_window_lower(hwnd); } |
140 void Redraw() { dw_window_redraw(hwnd); } | 245 void Redraw() { dw_window_redraw(hwnd); } |
141 void Default(Widget *defaultitem) { if(defaultitem) dw_window_default(hwnd, defaultitem->GetHWND()); } | 246 void Default(Widget *defaultitem) { if(defaultitem) dw_window_default(hwnd, defaultitem->GetHWND()); } |
142 void SetIcon(HICN icon) { dw_window_set_icon(hwnd, icon); } | 247 void SetIcon(HICN icon) { dw_window_set_icon(hwnd, icon); } |
248 Menu *MenuBar() { if(menu == DW_NULL) menu = new Menu(hwnd); return menu; } | |
249 #ifdef DW_CPP11 | |
250 void ConnectDelete(std::function<int()> userfunc) | |
251 #else | |
252 void ConnectDelete(int (*userfunc)()) | |
253 #endif | |
254 { | |
255 _ConnectDelete = userfunc; | |
256 if(!DeleteConnected) { | |
257 dw_signal_connect(hwnd, DW_SIGNAL_DELETE, DW_SIGNAL_FUNC(_OnDelete), this); | |
258 DeleteConnected = true; | |
259 } | |
260 } | |
261 #ifdef DW_CPP11 | |
262 void ConnectConfigure(std::function<int(int, int)> userfunc) | |
263 #else | |
264 void ConnectConfigure(int (*userfunc)(int, int)) | |
265 #endif | |
266 { | |
267 _ConnectConfigure = userfunc; | |
268 if(!ConfigureConnected) { | |
269 dw_signal_connect(hwnd, DW_SIGNAL_CONFIGURE, DW_SIGNAL_FUNC(_OnConfigure), this); | |
270 ConfigureConnected = true; | |
271 } | |
272 } | |
143 protected: | 273 protected: |
144 // Our signal handler functions to be overriden... | 274 // Our signal handler functions to be overriden... |
145 // If they are not overridden and an event is generated, remove the unused handler | 275 // If they are not overridden and an event is generated, remove the unused handler |
146 virtual int OnDelete() { dw_signal_disconnect_by_name(hwnd, DW_SIGNAL_DELETE); return FALSE; } | 276 virtual int OnDelete() { |
147 virtual int OnConfigure(int width, int height) { dw_signal_disconnect_by_name(hwnd, DW_SIGNAL_CONFIGURE); return FALSE; }; | 277 dw_signal_disconnect_by_name(hwnd, DW_SIGNAL_DELETE); |
278 DeleteConnected = false; | |
279 return FALSE; | |
280 } | |
281 virtual int OnConfigure(int width, int height) { | |
282 dw_signal_disconnect_by_name(hwnd, DW_SIGNAL_CONFIGURE); | |
283 ConfigureConnected = false; | |
284 return FALSE; | |
285 }; | |
148 }; | 286 }; |
149 | 287 |
150 // Class for focusable widgets | 288 // Class for focusable widgets |
151 class Focusable : virtual public Widget | 289 class Focusable : virtual public Widget |
152 { | 290 { |
154 void Enable() { dw_window_enable(hwnd); } | 292 void Enable() { dw_window_enable(hwnd); } |
155 void Disable() { dw_window_disable(hwnd); } | 293 void Disable() { dw_window_disable(hwnd); } |
156 void SetFocus() { dw_window_set_focus(hwnd); } | 294 void SetFocus() { dw_window_set_focus(hwnd); } |
157 }; | 295 }; |
158 | 296 |
159 // Base class for several types of buttons | |
160 class Buttons : virtual public Focusable | |
161 { | |
162 private: | |
163 static int _OnClicked(HWND window, void *data) { return reinterpret_cast<Buttons *>(data)->OnClicked(); } | |
164 protected: | |
165 void Setup() { | |
166 if(IsOverridden(Buttons::OnClicked, this)) | |
167 dw_signal_connect(hwnd, DW_SIGNAL_CLICKED, DW_SIGNAL_FUNC(_OnClicked), this); | |
168 } | |
169 // Our signal handler functions to be overriden... | |
170 // If they are not overridden and an event is generated, remove the unused handler | |
171 virtual int OnClicked() { dw_signal_disconnect_by_name(hwnd, DW_SIGNAL_CLICKED); return FALSE; } | |
172 }; | |
173 | |
174 // Text based button | 297 // Text based button |
175 class TextButton : public Buttons | 298 class TextButton : public Clickable, public Focusable |
176 { | 299 { |
177 public: | 300 public: |
178 // User functions | 301 // User functions |
179 void SetText(const char *text) { dw_window_set_text(hwnd, text); } | 302 void SetText(const char *text) { dw_window_set_text(hwnd, text); } |
180 char *GetText() { return dw_window_get_text(hwnd); } | 303 char *GetText() { return dw_window_get_text(hwnd); } |
189 Button(const char *text) { SetHWND(dw_button_new(text, 0)); Setup(); } | 312 Button(const char *text) { SetHWND(dw_button_new(text, 0)); Setup(); } |
190 Button() { SetHWND(dw_button_new("", 0)); Setup(); } | 313 Button() { SetHWND(dw_button_new("", 0)); Setup(); } |
191 }; | 314 }; |
192 | 315 |
193 // Image based button | 316 // Image based button |
194 class BitmapButton : public Buttons | 317 class BitmapButton : public Clickable, public Focusable |
195 { | 318 { |
196 public: | 319 public: |
197 // Constructors | 320 // Constructors |
198 BitmapButton(const char *text, unsigned long id) { SetHWND(dw_bitmapbutton_new(text, id)); Setup(); } | 321 BitmapButton(const char *text, unsigned long id) { SetHWND(dw_bitmapbutton_new(text, id)); Setup(); } |
199 BitmapButton(unsigned long id) { SetHWND(dw_bitmapbutton_new("", id)); Setup(); } | 322 BitmapButton(unsigned long id) { SetHWND(dw_bitmapbutton_new("", id)); Setup(); } |
290 // User functions | 413 // User functions |
291 void GetData(unsigned int *year, unsigned int *month, unsigned int *day) { dw_calendar_get_date(hwnd, year, month, day); } | 414 void GetData(unsigned int *year, unsigned int *month, unsigned int *day) { dw_calendar_get_date(hwnd, year, month, day); } |
292 void SetData(unsigned int year, unsigned int month, unsigned int day) { dw_calendar_set_date(hwnd, year, month, day); } | 415 void SetData(unsigned int year, unsigned int month, unsigned int day) { dw_calendar_set_date(hwnd, year, month, day); } |
293 }; | 416 }; |
294 | 417 |
295 | |
296 // Forward declare these so our Drawable abstract class can reference | |
297 class Render; | |
298 class Pixmap; | |
299 | 418 |
300 // Abstract class that defines drawing, either to screen or picture (pixmap) | 419 // Abstract class that defines drawing, either to screen or picture (pixmap) |
301 class Drawable | 420 class Drawable |
302 { | 421 { |
303 public: | 422 public: |
317 }; | 436 }; |
318 | 437 |
319 class Render : public Drawable, public Widget | 438 class Render : public Drawable, public Widget |
320 { | 439 { |
321 private: | 440 private: |
441 bool ExposeConnected, ConfigureConnected; | |
442 #ifdef DW_CPP11 | |
443 std::function<int(DWExpose *)> _ConnectExpose; | |
444 std::function<int(int, int)> _ConnectConfigure; | |
445 #else | |
446 int (*_ConnectExpose)(DWExpose *); | |
447 int (*_ConnectConfigure)(int width, int height); | |
448 #endif | |
322 void Setup() { | 449 void Setup() { |
323 if(IsOverridden(Render::OnExpose, this)) | 450 if(IsOverridden(Render::OnExpose, this)) { |
324 dw_signal_connect(hwnd, DW_SIGNAL_EXPOSE, DW_SIGNAL_FUNC(_OnExpose), this); | 451 dw_signal_connect(hwnd, DW_SIGNAL_EXPOSE, DW_SIGNAL_FUNC(_OnExpose), this); |
325 if(IsOverridden(Render::OnConfigure, this)) | 452 ExposeConnected = true; |
453 } | |
454 if(IsOverridden(Render::OnConfigure, this)) { | |
326 dw_signal_connect(hwnd, DW_SIGNAL_CONFIGURE, DW_SIGNAL_FUNC(_OnConfigure), this); | 455 dw_signal_connect(hwnd, DW_SIGNAL_CONFIGURE, DW_SIGNAL_FUNC(_OnConfigure), this); |
327 } | 456 ConfigureConnected = true; |
328 static int _OnExpose(HWND window, DWExpose *exp, void *data) { return reinterpret_cast<Render *>(data)->OnExpose(exp); } | 457 } |
329 static int _OnConfigure(HWND window, int width, int height, void *data) { return reinterpret_cast<Render *>(data)->OnConfigure(width, height); } | 458 } |
459 static int _OnExpose(HWND window, DWExpose *exp, void *data) { | |
460 if(reinterpret_cast<Render *>(data)->_ConnectExpose) | |
461 return reinterpret_cast<Render *>(data)->_ConnectExpose(exp); | |
462 return reinterpret_cast<Render *>(data)->OnExpose(exp); } | |
463 static int _OnConfigure(HWND window, int width, int height, void *data) { | |
464 if(reinterpret_cast<Render *>(data)->_ConnectConfigure) | |
465 return reinterpret_cast<Render *>(data)->_ConnectConfigure(width, height); | |
466 return reinterpret_cast<Render *>(data)->OnConfigure(width, height); } | |
330 public: | 467 public: |
331 // Constructors | 468 // Constructors |
332 Render(unsigned long id) { SetHWND(dw_render_new(id)); Setup(); } | 469 Render(unsigned long id) { SetHWND(dw_render_new(id)); Setup(); } |
333 Render() { SetHWND(dw_render_new(0)); Setup(); } | 470 Render() { SetHWND(dw_render_new(0)); Setup(); } |
334 | 471 |
349 void BitBlt(int xdest, int ydest, int width, int height, Pixmap *src, int xsrc, int ysrc); | 486 void BitBlt(int xdest, int ydest, int width, int height, Pixmap *src, int xsrc, int ysrc); |
350 int SetFont(const char *fontname) { return dw_window_set_font(hwnd, fontname); } | 487 int SetFont(const char *fontname) { return dw_window_set_font(hwnd, fontname); } |
351 void GetTextExtents(const char *text, int *width, int *height) { dw_font_text_extents_get(hwnd, DW_NULL, text, width, height); } | 488 void GetTextExtents(const char *text, int *width, int *height) { dw_font_text_extents_get(hwnd, DW_NULL, text, width, height); } |
352 char *GetFont() { return dw_window_get_font(hwnd); } | 489 char *GetFont() { return dw_window_get_font(hwnd); } |
353 void Redraw() { dw_render_redraw(hwnd); } | 490 void Redraw() { dw_render_redraw(hwnd); } |
491 #ifdef DW_CPP11 | |
492 void ConnectExpose(std::function<int(DWExpose *)> userfunc) | |
493 #else | |
494 void ConnectExpose(int (*userfunc)(DWExpose *)) | |
495 #endif | |
496 { | |
497 _ConnectExpose = userfunc; | |
498 if(!ExposeConnected) { | |
499 dw_signal_connect(hwnd, DW_SIGNAL_EXPOSE, DW_SIGNAL_FUNC(_OnExpose), this); | |
500 ExposeConnected = true; | |
501 } | |
502 } | |
503 #ifdef DW_CPP11 | |
504 void ConnectConfigure(std::function<int(int, int)> userfunc) | |
505 #else | |
506 void ConnectConfigure(int (*userfunc)(int, int)) | |
507 #endif | |
508 { | |
509 _ConnectConfigure = userfunc; | |
510 if(!ConfigureConnected) { | |
511 dw_signal_connect(hwnd, DW_SIGNAL_CONFIGURE, DW_SIGNAL_FUNC(_OnConfigure), this); | |
512 ConfigureConnected = true; | |
513 } | |
514 } | |
354 protected: | 515 protected: |
355 // Our signal handler functions to be overriden... | 516 // Our signal handler functions to be overriden... |
356 // If they are not overridden and an event is generated, remove the unused handler | 517 // If they are not overridden and an event is generated, remove the unused handler |
357 virtual int OnExpose(DWExpose *exp) { dw_signal_disconnect_by_name(hwnd, DW_SIGNAL_EXPOSE); return FALSE; } | 518 virtual int OnExpose(DWExpose *exp) { |
358 virtual int OnConfigure(int width, int height) { dw_signal_disconnect_by_name(hwnd, DW_SIGNAL_CONFIGURE); return FALSE; }; | 519 dw_signal_disconnect_by_name(hwnd, DW_SIGNAL_EXPOSE); |
520 ExposeConnected = false; | |
521 return FALSE; | |
522 } | |
523 virtual int OnConfigure(int width, int height) { | |
524 dw_signal_disconnect_by_name(hwnd, DW_SIGNAL_CONFIGURE); | |
525 ConfigureConnected = false; | |
526 return FALSE; | |
527 }; | |
359 }; | 528 }; |
360 | 529 |
361 class Pixmap : public Drawable, public Handle | 530 class Pixmap : public Drawable, public Handle |
362 { | 531 { |
363 private: | 532 private: |
408 | 577 |
409 // Class for the HTML rendering widget | 578 // Class for the HTML rendering widget |
410 class HTML : public Widget | 579 class HTML : public Widget |
411 { | 580 { |
412 private: | 581 private: |
582 bool ChangedConnected, ResultConnected; | |
583 #ifdef DW_CPP11 | |
584 std::function<int(int, char *)> _ConnectChanged; | |
585 std::function<int(int, char *, void *)> _ConnectResult; | |
586 #else | |
587 int (*_ConnectChanged)(int status, char *url); | |
588 int (*_ConnectResult)(int status, char *result, void *scriptdata); | |
589 #endif | |
413 void Setup() { | 590 void Setup() { |
414 if(IsOverridden(HTML::OnChanged, this)) | 591 if(IsOverridden(HTML::OnChanged, this)) { |
415 dw_signal_connect(hwnd, DW_SIGNAL_HTML_CHANGED, DW_SIGNAL_FUNC(_OnChanged), this); | 592 dw_signal_connect(hwnd, DW_SIGNAL_HTML_CHANGED, DW_SIGNAL_FUNC(_OnChanged), this); |
416 if(IsOverridden(HTML::OnResult, this)) | 593 ChangedConnected = true; |
594 } | |
595 if(IsOverridden(HTML::OnResult, this)) { | |
417 dw_signal_connect(hwnd, DW_SIGNAL_HTML_CHANGED, DW_SIGNAL_FUNC(_OnResult), this); | 596 dw_signal_connect(hwnd, DW_SIGNAL_HTML_CHANGED, DW_SIGNAL_FUNC(_OnResult), this); |
418 } | 597 ResultConnected = true; |
419 static int _OnChanged(HWND window, int status, char *url, void *data) { return reinterpret_cast<HTML *>(data)->OnChanged(status, url); } | 598 } |
420 static int _OnResult(HWND window, int status, char *result, void *scriptdata, void *data) { return reinterpret_cast<HTML *>(data)->OnResult(status, result, scriptdata); } | 599 } |
600 static int _OnChanged(HWND window, int status, char *url, void *data) { | |
601 if(reinterpret_cast<HTML *>(data)->_ConnectChanged) | |
602 return reinterpret_cast<HTML *>(data)->_ConnectChanged(status, url); | |
603 return reinterpret_cast<HTML *>(data)->OnChanged(status, url); } | |
604 static int _OnResult(HWND window, int status, char *result, void *scriptdata, void *data) { | |
605 if(reinterpret_cast<HTML *>(data)->_ConnectResult) | |
606 return reinterpret_cast<HTML *>(data)->_ConnectResult(status, result, scriptdata); | |
607 return reinterpret_cast<HTML *>(data)->OnResult(status, result, scriptdata); } | |
421 public: | 608 public: |
422 // Constructors | 609 // Constructors |
423 HTML(unsigned long id) { SetHWND(dw_html_new(id)); Setup(); } | 610 HTML(unsigned long id) { SetHWND(dw_html_new(id)); Setup(); } |
424 HTML() { SetHWND(dw_html_new(0)); Setup(); } | 611 HTML() { SetHWND(dw_html_new(0)); Setup(); } |
425 | 612 |
426 // User functions | 613 // User functions |
427 void Action(int action) { dw_html_action(hwnd, action); } | 614 void Action(int action) { dw_html_action(hwnd, action); } |
428 int JavascriptRun(const char *script, void *scriptdata) { return dw_html_javascript_run(hwnd, script, scriptdata); } | 615 int JavascriptRun(const char *script, void *scriptdata) { return dw_html_javascript_run(hwnd, script, scriptdata); } |
429 int Raw(const char *buffer) { return dw_html_raw(hwnd, buffer); } | 616 int Raw(const char *buffer) { return dw_html_raw(hwnd, buffer); } |
430 int URL(const char *url) { return dw_html_url(hwnd, url); } | 617 int URL(const char *url) { return dw_html_url(hwnd, url); } |
618 #ifdef DW_CPP11 | |
619 void ConnectChanged(std::function<int(int, char *)> userfunc) | |
620 #else | |
621 void ConnectChanged(int (*userfunc)(int, char *)) | |
622 #endif | |
623 { | |
624 _ConnectChanged = userfunc; | |
625 if(!ChangedConnected) { | |
626 dw_signal_connect(hwnd, DW_SIGNAL_HTML_CHANGED, DW_SIGNAL_FUNC(_OnChanged), this); | |
627 ChangedConnected = true; | |
628 } | |
629 } | |
630 #ifdef DW_CPP11 | |
631 void ConnectResult(std::function<int(int, char *, void *)> userfunc) | |
632 #else | |
633 void ConnectResult(int (*userfunc)(int, char *, void *)) | |
634 #endif | |
635 { | |
636 _ConnectResult = userfunc; | |
637 if(!ResultConnected) { | |
638 dw_signal_connect(hwnd, DW_SIGNAL_HTML_CHANGED, DW_SIGNAL_FUNC(_OnResult), this); | |
639 ResultConnected = true; | |
640 } | |
641 } | |
431 protected: | 642 protected: |
432 // Our signal handler functions to be overriden... | 643 // Our signal handler functions to be overriden... |
433 // If they are not overridden and an event is generated, remove the unused handler | 644 // If they are not overridden and an event is generated, remove the unused handler |
434 virtual int OnChanged(int status, char *url) { dw_signal_disconnect_by_name(hwnd, DW_SIGNAL_HTML_CHANGED); return FALSE; } | 645 virtual int OnChanged(int status, char *url) { |
435 virtual int OnResult(int status, char *result, void *scriptdata) { dw_signal_disconnect_by_name(hwnd, DW_SIGNAL_HTML_RESULT); return FALSE; }; | 646 dw_signal_disconnect_by_name(hwnd, DW_SIGNAL_HTML_CHANGED); |
647 ChangedConnected = false; | |
648 return FALSE; | |
649 } | |
650 virtual int OnResult(int status, char *result, void *scriptdata) { | |
651 dw_signal_disconnect_by_name(hwnd, DW_SIGNAL_HTML_RESULT); | |
652 ResultConnected = false; | |
653 return FALSE; | |
654 }; | |
436 }; | 655 }; |
437 | 656 |
438 // Base class for several widgets that allow text entry | 657 // Base class for several widgets that allow text entry |
439 class TextEntry : virtual public Focusable, virtual public TextWidget | 658 class TextEntry : virtual public Focusable, virtual public TextWidget |
440 { | 659 { |
465 | 684 |
466 // Base class for several widgets that have a list of elements | 685 // Base class for several widgets that have a list of elements |
467 class ListBoxes : virtual public Focusable | 686 class ListBoxes : virtual public Focusable |
468 { | 687 { |
469 private: | 688 private: |
689 bool ListSelectConnected; | |
690 #ifdef DW_CPP11 | |
691 std::function<int(int)> _ConnectListSelect; | |
692 #else | |
693 int (*_ConnectListSelect)(int index); | |
694 #endif | |
470 void Setup() { | 695 void Setup() { |
471 if(IsOverridden(ListBoxes::OnListSelect, this)) | 696 if(IsOverridden(ListBoxes::OnListSelect, this)) { |
472 dw_signal_connect(hwnd, DW_SIGNAL_LIST_SELECT, DW_SIGNAL_FUNC(_OnListSelect), this); | 697 dw_signal_connect(hwnd, DW_SIGNAL_LIST_SELECT, DW_SIGNAL_FUNC(_OnListSelect), this); |
473 } | 698 ListSelectConnected = true; |
474 static int _OnListSelect(HWND window, int index, void *data) { return reinterpret_cast<ListBoxes *>(data)->OnListSelect(index); } | 699 } |
700 } | |
701 static int _OnListSelect(HWND window, int index, void *data) { | |
702 if(reinterpret_cast<ListBoxes *>(data)->_ConnectListSelect) | |
703 return reinterpret_cast<ListBoxes *>(data)->_ConnectListSelect(index); | |
704 return reinterpret_cast<ListBoxes *>(data)->OnListSelect(index); | |
705 } | |
475 public: | 706 public: |
476 // User functions | 707 // User functions |
477 void Append(const char *text) { dw_listbox_append(hwnd, text); } | 708 void Append(const char *text) { dw_listbox_append(hwnd, text); } |
478 void Clear() { dw_listbox_clear(hwnd); } | 709 void Clear() { dw_listbox_clear(hwnd); } |
479 int Count() { return dw_listbox_count(hwnd); } | 710 int Count() { return dw_listbox_count(hwnd); } |
484 void ListAppend(char **text, int count) { dw_listbox_list_append(hwnd, text, count); } | 715 void ListAppend(char **text, int count) { dw_listbox_list_append(hwnd, text, count); } |
485 void Select(int index, int state) { dw_listbox_select(hwnd, index, state); } | 716 void Select(int index, int state) { dw_listbox_select(hwnd, index, state); } |
486 int Selected() { return dw_listbox_selected(hwnd); } | 717 int Selected() { return dw_listbox_selected(hwnd); } |
487 int Selected(int where) { return dw_listbox_selected_multi(hwnd, where); } | 718 int Selected(int where) { return dw_listbox_selected_multi(hwnd, where); } |
488 void SetTop(int top) { dw_listbox_set_top(hwnd, top); } | 719 void SetTop(int top) { dw_listbox_set_top(hwnd, top); } |
720 #ifdef DW_CPP11 | |
721 void ConnectListSelect(std::function<int(int)> userfunc) | |
722 #else | |
723 void ConnectListSelect(int (*userfunc)(int)) | |
724 #endif | |
725 { | |
726 _ConnectListSelect = userfunc; | |
727 if(!ListSelectConnected) { | |
728 dw_signal_connect(hwnd, DW_SIGNAL_LIST_SELECT, DW_SIGNAL_FUNC(_OnListSelect), this); | |
729 ListSelectConnected = true; | |
730 } | |
731 } | |
489 protected: | 732 protected: |
490 // Our signal handler functions to be overriden... | 733 // Our signal handler functions to be overriden... |
491 // If they are not overridden and an event is generated, remove the unused handler | 734 // If they are not overridden and an event is generated, remove the unused handler |
492 virtual int OnListSelect(int index) { dw_signal_disconnect_by_name(hwnd, DW_SIGNAL_LIST_SELECT); return FALSE; } | 735 virtual int OnListSelect(int index) { |
736 dw_signal_disconnect_by_name(hwnd, DW_SIGNAL_LIST_SELECT); | |
737 ListSelectConnected = false; | |
738 return FALSE; | |
739 } | |
493 }; | 740 }; |
494 | 741 |
495 class Combobox : public TextEntry, public ListBoxes | 742 class Combobox : public TextEntry, public ListBoxes |
496 { | 743 { |
497 public: | 744 public: |
514 | 761 |
515 // Base class for several ranged type widgets | 762 // Base class for several ranged type widgets |
516 class Ranged : virtual public Widget | 763 class Ranged : virtual public Widget |
517 { | 764 { |
518 private: | 765 private: |
519 static int _OnValueChanged(HWND window, int value, void *data) { return reinterpret_cast<Ranged *>(data)->OnValueChanged(value); } | 766 bool ValueChangedConnected; |
767 #ifdef DW_CPP11 | |
768 std::function<int(int)> _ConnectValueChanged; | |
769 #else | |
770 int (*_ConnectValueChanged)(int value); | |
771 #endif | |
772 static int _OnValueChanged(HWND window, int value, void *data) { | |
773 if(reinterpret_cast<Ranged *>(data)->_ConnectValueChanged) | |
774 return reinterpret_cast<Ranged *>(data)->_ConnectValueChanged(value); | |
775 return reinterpret_cast<Ranged *>(data)->OnValueChanged(value); | |
776 } | |
520 protected: | 777 protected: |
521 void Setup() { | 778 void Setup() { |
522 if(IsOverridden(Ranged::OnValueChanged, this)) | 779 if(IsOverridden(Ranged::OnValueChanged, this)) { |
523 dw_signal_connect(hwnd, DW_SIGNAL_VALUE_CHANGED, DW_SIGNAL_FUNC(_OnValueChanged), this); | 780 dw_signal_connect(hwnd, DW_SIGNAL_VALUE_CHANGED, DW_SIGNAL_FUNC(_OnValueChanged), this); |
781 ValueChangedConnected = true; | |
782 } | |
524 } | 783 } |
525 // Our signal handler functions to be overriden... | 784 // Our signal handler functions to be overriden... |
526 // If they are not overridden and an event is generated, remove the unused handler | 785 // If they are not overridden and an event is generated, remove the unused handler |
527 virtual int OnValueChanged(int value) { dw_signal_disconnect_by_name(hwnd, DW_SIGNAL_VALUE_CHANGED); return FALSE; } | 786 virtual int OnValueChanged(int value) { |
787 dw_signal_disconnect_by_name(hwnd, DW_SIGNAL_VALUE_CHANGED); | |
788 ValueChangedConnected = false; | |
789 return FALSE; | |
790 } | |
791 public: | |
792 #ifdef DW_CPP11 | |
793 void ConnectValueChanged(std::function<int(int)> userfunc) | |
794 #else | |
795 void ConnectValueChanged(int (*userfunc)(int)) | |
796 #endif | |
797 { | |
798 _ConnectValueChanged = userfunc; | |
799 if(!ValueChangedConnected) { | |
800 dw_signal_connect(hwnd, DW_SIGNAL_VALUE_CHANGED, DW_SIGNAL_FUNC(_OnValueChanged), this); | |
801 ValueChangedConnected = true; | |
802 } | |
803 } | |
528 }; | 804 }; |
529 | 805 |
530 class Slider : public Ranged | 806 class Slider : public Ranged |
531 { | 807 { |
532 public: | 808 public: |
596 protected: | 872 protected: |
597 App() { } | 873 App() { } |
598 static App *_app; | 874 static App *_app; |
599 public: | 875 public: |
600 // Allow the code to compile if handicapped on older compilers | 876 // Allow the code to compile if handicapped on older compilers |
601 #if __cplusplus >= 201103L | 877 #ifdef DW_CPP11 |
602 // Singletons should not be cloneable. | 878 // Singletons should not be cloneable. |
603 App(App &other) = delete; | 879 App(App &other) = delete; |
604 // Singletons should not be assignable. | 880 // Singletons should not be assignable. |
605 void operator=(const App &) = delete; | 881 void operator=(const App &) = delete; |
606 #endif | 882 #endif |
610 static App *Init(const char *appid, const char *appname) { if(!_app) { _app = new App(); dw_app_id_set(appid, appname); dw_init(TRUE, 0, DW_NULL); } return _app; } | 886 static App *Init(const char *appid, const char *appname) { if(!_app) { _app = new App(); dw_app_id_set(appid, appname); dw_init(TRUE, 0, DW_NULL); } return _app; } |
611 static App *Init(int argc, char *argv[]) { if(!_app) { _app = new App(); dw_init(TRUE, argc, argv); } return _app; } | 887 static App *Init(int argc, char *argv[]) { if(!_app) { _app = new App(); dw_init(TRUE, argc, argv); } return _app; } |
612 static App *Init(int argc, char *argv[], const char *appid) { if(!_app) { _app = new App(); dw_app_id_set(appid, DW_NULL); dw_init(TRUE, argc, argv); } return _app; } | 888 static App *Init(int argc, char *argv[], const char *appid) { if(!_app) { _app = new App(); dw_app_id_set(appid, DW_NULL); dw_init(TRUE, argc, argv); } return _app; } |
613 static App *Init(int argc, char *argv[], const char *appid, const char *appname) { if(!_app) { _app = new App(); dw_app_id_set(appid, appname); dw_init(TRUE, argc, argv); } return _app; } | 889 static App *Init(int argc, char *argv[], const char *appid, const char *appname) { if(!_app) { _app = new App(); dw_app_id_set(appid, appname); dw_init(TRUE, argc, argv); } return _app; } |
614 | 890 |
891 // User functions | |
615 void Main() { dw_main(); } | 892 void Main() { dw_main(); } |
616 void MainIteration() { dw_main_iteration(); } | 893 void MainIteration() { dw_main_iteration(); } |
617 void MainQuit() { dw_main_quit(); } | 894 void MainQuit() { dw_main_quit(); } |
618 void Exit(int exitcode) { dw_exit(exitcode); } | 895 void Exit(int exitcode) { dw_exit(exitcode); } |
896 int MessageBox(const char *title, int flags, const char *format) { return dw_messagebox(title, flags, format); } | |
619 }; | 897 }; |
620 | 898 |
621 // Static singleton reference declared outside of the class | 899 // Static singleton reference declared outside of the class |
622 App* App::_app = DW_NULL; | 900 App* App::_app = DW_NULL; |
623 | 901 |