comparison dw.hpp @ 2895:5a6bf6bd3001

C++: Divide up C++11 and Lambda support since some compilers can support lambdas without full C++11 support. For instance MSVC 2010 supports lambdas but only MSVC 2017 supports C++11 or higher. GCC 4.5 supports lambdas but GCC 4.8.1 supports C++11.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Fri, 23 Dec 2022 04:13:51 +0000
parents 5ae86b395927
children d91aaffca1fc
comparison
equal deleted inserted replaced
2894:5bbd275369cd 2895:5a6bf6bd3001
6 #ifndef _HPP_DW 6 #ifndef _HPP_DW
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_CPP11
13 #define DW_NULL nullptr 13 #define DW_NULL nullptr
14 #else
15 #define DW_NULL NULL
16 #endif
17
18 // Support Lambdas on C++11, Visual C 2010 or GCC 4.5
19 #ifdef DW_CPP11 || (defined(_MSC_VER) && _MSC_VER >= 1600) || \
20 (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 4)))
21 #define DW_LAMBDA
14 #include <functional> 22 #include <functional>
15 #else
16 #define DW_NULL NULL
17 #endif 23 #endif
18 24
19 // Attempt to allow compilation on GCC older than 4.7 25 // Attempt to allow compilation on GCC older than 4.7
20 #if defined(__GNUC__) && (__GNuC__ < 5 || (__GNUC__ == 4 && __GNUC_MINOR__ < 7)) 26 #if defined(__GNUC__) && (__GNuC__ < 5 || (__GNUC__ == 4 && __GNUC_MINOR__ < 7))
21 #define override 27 #define override
116 // Base class for several types of widgets including buttons and menu items 122 // Base class for several types of widgets including buttons and menu items
117 class Clickable : virtual public Widget 123 class Clickable : virtual public Widget
118 { 124 {
119 private: 125 private:
120 bool ClickedConnected; 126 bool ClickedConnected;
121 #ifdef DW_CPP11 127 #ifdef DW_LAMBDA
122 std::function<int()> _ConnectClicked; 128 std::function<int()> _ConnectClicked;
123 #else 129 #else
124 int (*_ConnectClicked)(); 130 int (*_ConnectClicked)();
125 #endif 131 #endif
126 static int _OnClicked(HWND window, void *data) { 132 static int _OnClicked(HWND window, void *data) {
140 dw_signal_disconnect_by_name(hwnd, DW_SIGNAL_CLICKED); 146 dw_signal_disconnect_by_name(hwnd, DW_SIGNAL_CLICKED);
141 ClickedConnected = false; 147 ClickedConnected = false;
142 return FALSE; 148 return FALSE;
143 } 149 }
144 public: 150 public:
145 #ifdef DW_CPP11 151 #ifdef DW_LAMBDA
146 void ConnectClicked(std::function<int()> userfunc) 152 void ConnectClicked(std::function<int()> userfunc)
147 #else 153 #else
148 void ConnectClicked(int (*userfunc)()) 154 void ConnectClicked(int (*userfunc)())
149 #endif 155 #endif
150 { 156 {
225 // Top-level window class is packable 231 // Top-level window class is packable
226 class Window : public Boxes 232 class Window : public Boxes
227 { 233 {
228 private: 234 private:
229 bool DeleteConnected, ConfigureConnected; 235 bool DeleteConnected, ConfigureConnected;
230 #ifdef DW_CPP11 236 #ifdef DW_LAMBDA
231 std::function<int()> _ConnectDelete; 237 std::function<int()> _ConnectDelete;
232 std::function<int(int, int)> _ConnectConfigure; 238 std::function<int(int, int)> _ConnectConfigure;
233 #else 239 #else
234 int (*_ConnectDelete)(); 240 int (*_ConnectDelete)();
235 int (*_ConnectConfigure)(int width, int height); 241 int (*_ConnectConfigure)(int width, int height);
293 dw_pointer_query_pos(&x, &y); 299 dw_pointer_query_pos(&x, &y);
294 dw_menu_popup(&pmenu, hwnd, (int)x, (int)y); 300 dw_menu_popup(&pmenu, hwnd, (int)x, (int)y);
295 delete menu; 301 delete menu;
296 } 302 }
297 } 303 }
298 #ifdef DW_CPP11 304 #ifdef DW_LAMBDA
299 void ConnectDelete(std::function<int()> userfunc) 305 void ConnectDelete(std::function<int()> userfunc)
300 #else 306 #else
301 void ConnectDelete(int (*userfunc)()) 307 void ConnectDelete(int (*userfunc)())
302 #endif 308 #endif
303 { 309 {
305 if(!DeleteConnected) { 311 if(!DeleteConnected) {
306 dw_signal_connect(hwnd, DW_SIGNAL_DELETE, DW_SIGNAL_FUNC(_OnDelete), this); 312 dw_signal_connect(hwnd, DW_SIGNAL_DELETE, DW_SIGNAL_FUNC(_OnDelete), this);
307 DeleteConnected = true; 313 DeleteConnected = true;
308 } 314 }
309 } 315 }
310 #ifdef DW_CPP11 316 #ifdef DW_LAMBDA
311 void ConnectConfigure(std::function<int(int, int)> userfunc) 317 void ConnectConfigure(std::function<int(int, int)> userfunc)
312 #else 318 #else
313 void ConnectConfigure(int (*userfunc)(int, int)) 319 void ConnectConfigure(int (*userfunc)(int, int))
314 #endif 320 #endif
315 { 321 {
509 515
510 class Render : public Drawable, public Widget 516 class Render : public Drawable, public Widget
511 { 517 {
512 private: 518 private:
513 bool ExposeConnected, ConfigureConnected; 519 bool ExposeConnected, ConfigureConnected;
514 #ifdef DW_CPP11 520 #ifdef DW_LAMBDA
515 std::function<int(DWExpose *)> _ConnectExpose; 521 std::function<int(DWExpose *)> _ConnectExpose;
516 std::function<int(int, int)> _ConnectConfigure; 522 std::function<int(int, int)> _ConnectConfigure;
517 #else 523 #else
518 int (*_ConnectExpose)(DWExpose *); 524 int (*_ConnectExpose)(DWExpose *);
519 int (*_ConnectConfigure)(int width, int height); 525 int (*_ConnectConfigure)(int width, int height);
558 void BitBlt(int xdest, int ydest, int width, int height, Pixmap *src, int xsrc, int ysrc); 564 void BitBlt(int xdest, int ydest, int width, int height, Pixmap *src, int xsrc, int ysrc);
559 int SetFont(const char *fontname) { return dw_window_set_font(hwnd, fontname); } 565 int SetFont(const char *fontname) { return dw_window_set_font(hwnd, fontname); }
560 void GetTextExtents(const char *text, int *width, int *height) { dw_font_text_extents_get(hwnd, DW_NULL, text, width, height); } 566 void GetTextExtents(const char *text, int *width, int *height) { dw_font_text_extents_get(hwnd, DW_NULL, text, width, height); }
561 char *GetFont() { return dw_window_get_font(hwnd); } 567 char *GetFont() { return dw_window_get_font(hwnd); }
562 void Redraw() { dw_render_redraw(hwnd); } 568 void Redraw() { dw_render_redraw(hwnd); }
563 #ifdef DW_CPP11 569 #ifdef DW_LAMBDA
564 void ConnectExpose(std::function<int(DWExpose *)> userfunc) 570 void ConnectExpose(std::function<int(DWExpose *)> userfunc)
565 #else 571 #else
566 void ConnectExpose(int (*userfunc)(DWExpose *)) 572 void ConnectExpose(int (*userfunc)(DWExpose *))
567 #endif 573 #endif
568 { 574 {
570 if(!ExposeConnected) { 576 if(!ExposeConnected) {
571 dw_signal_connect(hwnd, DW_SIGNAL_EXPOSE, DW_SIGNAL_FUNC(_OnExpose), this); 577 dw_signal_connect(hwnd, DW_SIGNAL_EXPOSE, DW_SIGNAL_FUNC(_OnExpose), this);
572 ExposeConnected = true; 578 ExposeConnected = true;
573 } 579 }
574 } 580 }
575 #ifdef DW_CPP11 581 #ifdef DW_LAMBDA
576 void ConnectConfigure(std::function<int(int, int)> userfunc) 582 void ConnectConfigure(std::function<int(int, int)> userfunc)
577 #else 583 #else
578 void ConnectConfigure(int (*userfunc)(int, int)) 584 void ConnectConfigure(int (*userfunc)(int, int))
579 #endif 585 #endif
580 { 586 {
650 // Class for the HTML rendering widget 656 // Class for the HTML rendering widget
651 class HTML : public Widget 657 class HTML : public Widget
652 { 658 {
653 private: 659 private:
654 bool ChangedConnected, ResultConnected; 660 bool ChangedConnected, ResultConnected;
655 #ifdef DW_CPP11 661 #ifdef DW_LAMBDA
656 std::function<int(int, char *)> _ConnectChanged; 662 std::function<int(int, char *)> _ConnectChanged;
657 std::function<int(int, char *, void *)> _ConnectResult; 663 std::function<int(int, char *, void *)> _ConnectResult;
658 #else 664 #else
659 int (*_ConnectChanged)(int status, char *url); 665 int (*_ConnectChanged)(int status, char *url);
660 int (*_ConnectResult)(int status, char *result, void *scriptdata); 666 int (*_ConnectResult)(int status, char *result, void *scriptdata);
685 // User functions 691 // User functions
686 void Action(int action) { dw_html_action(hwnd, action); } 692 void Action(int action) { dw_html_action(hwnd, action); }
687 int JavascriptRun(const char *script, void *scriptdata) { return dw_html_javascript_run(hwnd, script, scriptdata); } 693 int JavascriptRun(const char *script, void *scriptdata) { return dw_html_javascript_run(hwnd, script, scriptdata); }
688 int Raw(const char *buffer) { return dw_html_raw(hwnd, buffer); } 694 int Raw(const char *buffer) { return dw_html_raw(hwnd, buffer); }
689 int URL(const char *url) { return dw_html_url(hwnd, url); } 695 int URL(const char *url) { return dw_html_url(hwnd, url); }
690 #ifdef DW_CPP11 696 #ifdef DW_LAMBDA
691 void ConnectChanged(std::function<int(int, char *)> userfunc) 697 void ConnectChanged(std::function<int(int, char *)> userfunc)
692 #else 698 #else
693 void ConnectChanged(int (*userfunc)(int, char *)) 699 void ConnectChanged(int (*userfunc)(int, char *))
694 #endif 700 #endif
695 { 701 {
697 if(!ChangedConnected) { 703 if(!ChangedConnected) {
698 dw_signal_connect(hwnd, DW_SIGNAL_HTML_CHANGED, DW_SIGNAL_FUNC(_OnChanged), this); 704 dw_signal_connect(hwnd, DW_SIGNAL_HTML_CHANGED, DW_SIGNAL_FUNC(_OnChanged), this);
699 ChangedConnected = true; 705 ChangedConnected = true;
700 } 706 }
701 } 707 }
702 #ifdef DW_CPP11 708 #ifdef DW_LAMBDA
703 void ConnectResult(std::function<int(int, char *, void *)> userfunc) 709 void ConnectResult(std::function<int(int, char *, void *)> userfunc)
704 #else 710 #else
705 void ConnectResult(int (*userfunc)(int, char *, void *)) 711 void ConnectResult(int (*userfunc)(int, char *, void *))
706 #endif 712 #endif
707 { 713 {
757 // Base class for several widgets that have a list of elements 763 // Base class for several widgets that have a list of elements
758 class ListBoxes : virtual public Focusable 764 class ListBoxes : virtual public Focusable
759 { 765 {
760 private: 766 private:
761 bool ListSelectConnected; 767 bool ListSelectConnected;
762 #ifdef DW_CPP11 768 #ifdef DW_LAMBDA
763 std::function<int(int)> _ConnectListSelect; 769 std::function<int(int)> _ConnectListSelect;
764 #else 770 #else
765 int (*_ConnectListSelect)(int index); 771 int (*_ConnectListSelect)(int index);
766 #endif 772 #endif
767 void Setup() { 773 void Setup() {
787 void ListAppend(char **text, int count) { dw_listbox_list_append(hwnd, text, count); } 793 void ListAppend(char **text, int count) { dw_listbox_list_append(hwnd, text, count); }
788 void Select(int index, int state) { dw_listbox_select(hwnd, index, state); } 794 void Select(int index, int state) { dw_listbox_select(hwnd, index, state); }
789 int Selected() { return dw_listbox_selected(hwnd); } 795 int Selected() { return dw_listbox_selected(hwnd); }
790 int Selected(int where) { return dw_listbox_selected_multi(hwnd, where); } 796 int Selected(int where) { return dw_listbox_selected_multi(hwnd, where); }
791 void SetTop(int top) { dw_listbox_set_top(hwnd, top); } 797 void SetTop(int top) { dw_listbox_set_top(hwnd, top); }
792 #ifdef DW_CPP11 798 #ifdef DW_LAMBDA
793 void ConnectListSelect(std::function<int(int)> userfunc) 799 void ConnectListSelect(std::function<int(int)> userfunc)
794 #else 800 #else
795 void ConnectListSelect(int (*userfunc)(int)) 801 void ConnectListSelect(int (*userfunc)(int))
796 #endif 802 #endif
797 { 803 {
834 // Base class for several ranged type widgets 840 // Base class for several ranged type widgets
835 class Ranged : virtual public Widget 841 class Ranged : virtual public Widget
836 { 842 {
837 private: 843 private:
838 bool ValueChangedConnected; 844 bool ValueChangedConnected;
839 #ifdef DW_CPP11 845 #ifdef DW_LAMBDA
840 std::function<int(int)> _ConnectValueChanged; 846 std::function<int(int)> _ConnectValueChanged;
841 #else 847 #else
842 int (*_ConnectValueChanged)(int value); 848 int (*_ConnectValueChanged)(int value);
843 #endif 849 #endif
844 static int _OnValueChanged(HWND window, int value, void *data) { 850 static int _OnValueChanged(HWND window, int value, void *data) {
859 dw_signal_disconnect_by_name(hwnd, DW_SIGNAL_VALUE_CHANGED); 865 dw_signal_disconnect_by_name(hwnd, DW_SIGNAL_VALUE_CHANGED);
860 ValueChangedConnected = false; 866 ValueChangedConnected = false;
861 return FALSE; 867 return FALSE;
862 } 868 }
863 public: 869 public:
864 #ifdef DW_CPP11 870 #ifdef DW_LAMBDA
865 void ConnectValueChanged(std::function<int(int)> userfunc) 871 void ConnectValueChanged(std::function<int(int)> userfunc)
866 #else 872 #else
867 void ConnectValueChanged(int (*userfunc)(int)) 873 void ConnectValueChanged(int (*userfunc)(int))
868 #endif 874 #endif
869 { 875 {
941 947
942 class ObjectView : virtual public Widget 948 class ObjectView : virtual public Widget
943 { 949 {
944 private: 950 private:
945 bool ItemSelectConnected, ItemContextConnected; 951 bool ItemSelectConnected, ItemContextConnected;
946 #ifdef DW_CPP11 952 #ifdef DW_LAMBDA
947 std::function<int(HTREEITEM, char *, void *)> _ConnectItemSelect; 953 std::function<int(HTREEITEM, char *, void *)> _ConnectItemSelect;
948 std::function<int(char *, int, int, void *)> _ConnectItemContext; 954 std::function<int(char *, int, int, void *)> _ConnectItemContext;
949 #else 955 #else
950 int (*_ConnectItemSelect)(HTREEITEM, char *, void *); 956 int (*_ConnectItemSelect)(HTREEITEM, char *, void *);
951 int (*_ConnectItemContext)(char *, int, int, void *); 957 int (*_ConnectItemContext)(char *, int, int, void *);
982 dw_signal_disconnect_by_name(hwnd, DW_SIGNAL_ITEM_CONTEXT); 988 dw_signal_disconnect_by_name(hwnd, DW_SIGNAL_ITEM_CONTEXT);
983 ItemContextConnected = false; 989 ItemContextConnected = false;
984 return FALSE; 990 return FALSE;
985 } 991 }
986 public: 992 public:
987 #ifdef DW_CPP11 993 #ifdef DW_LAMBDA
988 void ConnectItemSelect(std::function<int(HTREEITEM, char *, void *)> userfunc) 994 void ConnectItemSelect(std::function<int(HTREEITEM, char *, void *)> userfunc)
989 #else 995 #else
990 void ConnectItemSelect(int (*userfunc)(HTREEITEM, char *, void *)) 996 void ConnectItemSelect(int (*userfunc)(HTREEITEM, char *, void *))
991 #endif 997 #endif
992 { 998 {
994 if(!ItemSelectConnected) { 1000 if(!ItemSelectConnected) {
995 dw_signal_connect(hwnd, DW_SIGNAL_ITEM_SELECT, DW_SIGNAL_FUNC(_OnItemSelect), this); 1001 dw_signal_connect(hwnd, DW_SIGNAL_ITEM_SELECT, DW_SIGNAL_FUNC(_OnItemSelect), this);
996 ItemSelectConnected = true; 1002 ItemSelectConnected = true;
997 } 1003 }
998 } 1004 }
999 #ifdef DW_CPP11 1005 #ifdef DW_LAMBDA
1000 void ConnectItemContext(std::function<int(char *, int, int, void *)> userfunc) 1006 void ConnectItemContext(std::function<int(char *, int, int, void *)> userfunc)
1001 #else 1007 #else
1002 void ConnectItemContext(int (*userfunc)(char *, int, int, void *)) 1008 void ConnectItemContext(int (*userfunc)(char *, int, int, void *))
1003 #endif 1009 #endif
1004 { 1010 {
1012 1018
1013 class Containers : virtual public Focusable, virtual public ObjectView 1019 class Containers : virtual public Focusable, virtual public ObjectView
1014 { 1020 {
1015 private: 1021 private:
1016 bool ItemEnterConnected, ColumnClickConnected; 1022 bool ItemEnterConnected, ColumnClickConnected;
1017 #ifdef DW_CPP11 1023 #ifdef DW_LAMBDA
1018 std::function<int(char *)> _ConnectItemEnter; 1024 std::function<int(char *)> _ConnectItemEnter;
1019 std::function<int(int)> _ConnectColumnClick; 1025 std::function<int(int)> _ConnectColumnClick;
1020 #else 1026 #else
1021 int (*_ConnectItemEnter)(char *); 1027 int (*_ConnectItemEnter)(char *);
1022 int (*_ConnectColumnClick)(int); 1028 int (*_ConnectColumnClick)(int);
1074 void Scroll(int direction, long rows) { dw_container_scroll(hwnd, direction, rows); } 1080 void Scroll(int direction, long rows) { dw_container_scroll(hwnd, direction, rows); }
1075 void SetColumnWidth(int column, int width) { dw_container_set_column_width(hwnd, column, width); } 1081 void SetColumnWidth(int column, int width) { dw_container_set_column_width(hwnd, column, width); }
1076 void SetRowData(int row, void *data) { dw_container_set_row_data(allocpointer, row, data); } 1082 void SetRowData(int row, void *data) { dw_container_set_row_data(allocpointer, row, data); }
1077 void SetRowTitle(int row, const char *title) { dw_container_set_row_title(allocpointer, row, title); } 1083 void SetRowTitle(int row, const char *title) { dw_container_set_row_title(allocpointer, row, title); }
1078 void SetStripe(unsigned long oddcolor, unsigned long evencolor) { dw_container_set_stripe(hwnd, oddcolor, evencolor); } 1084 void SetStripe(unsigned long oddcolor, unsigned long evencolor) { dw_container_set_stripe(hwnd, oddcolor, evencolor); }
1079 #ifdef DW_CPP11 1085 #ifdef DW_LAMBDA
1080 void ConnectItemEnter(std::function<int(char *)> userfunc) 1086 void ConnectItemEnter(std::function<int(char *)> userfunc)
1081 #else 1087 #else
1082 void ConnectItemEnter(int (*userfunc)(char *)) 1088 void ConnectItemEnter(int (*userfunc)(char *))
1083 #endif 1089 #endif
1084 { 1090 {
1086 if(!ItemEnterConnected) { 1092 if(!ItemEnterConnected) {
1087 dw_signal_connect(hwnd, DW_SIGNAL_ITEM_ENTER, DW_SIGNAL_FUNC(_OnItemEnter), this); 1093 dw_signal_connect(hwnd, DW_SIGNAL_ITEM_ENTER, DW_SIGNAL_FUNC(_OnItemEnter), this);
1088 ItemEnterConnected = true; 1094 ItemEnterConnected = true;
1089 } 1095 }
1090 } 1096 }
1091 #ifdef DW_CPP11 1097 #ifdef DW_LAMBDA
1092 void ConnecColumnClick(std::function<int(int)> userfunc) 1098 void ConnecColumnClick(std::function<int(int)> userfunc)
1093 #else 1099 #else
1094 void ConnectColumnClick(int (*userfunc)(int)) 1100 void ConnectColumnClick(int (*userfunc)(int))
1095 #endif 1101 #endif
1096 { 1102 {
1137 1143
1138 class Tree : virtual public Focusable, virtual public ObjectView 1144 class Tree : virtual public Focusable, virtual public ObjectView
1139 { 1145 {
1140 private: 1146 private:
1141 bool TreeExpandConnected; 1147 bool TreeExpandConnected;
1142 #ifdef DW_CPP11 1148 #ifdef DW_LAMBDA
1143 std::function<int(HTREEITEM)> _ConnectTreeExpand; 1149 std::function<int(HTREEITEM)> _ConnectTreeExpand;
1144 #else 1150 #else
1145 int (*_ConnectTreeExpand)(HTREEITEM); 1151 int (*_ConnectTreeExpand)(HTREEITEM);
1146 #endif 1152 #endif
1147 static int _OnTreeExpand(HWND window, HTREEITEM item, void *data) { 1153 static int _OnTreeExpand(HWND window, HTREEITEM item, void *data) {
1179 void Delete(HTREEITEM item) { dw_tree_item_delete(hwnd, item); } 1185 void Delete(HTREEITEM item) { dw_tree_item_delete(hwnd, item); }
1180 void Expand(HTREEITEM item) { dw_tree_item_expand(hwnd, item); } 1186 void Expand(HTREEITEM item) { dw_tree_item_expand(hwnd, item); }
1181 void *GetData(HTREEITEM item) { dw_tree_item_get_data(hwnd, item); } 1187 void *GetData(HTREEITEM item) { dw_tree_item_get_data(hwnd, item); }
1182 void Select(HTREEITEM item) { dw_tree_item_select(hwnd, item); } 1188 void Select(HTREEITEM item) { dw_tree_item_select(hwnd, item); }
1183 void SetData(HTREEITEM item, void *itemdata) { dw_tree_item_set_data(hwnd, item, itemdata); } 1189 void SetData(HTREEITEM item, void *itemdata) { dw_tree_item_set_data(hwnd, item, itemdata); }
1184 #ifdef DW_CPP11 1190 #ifdef DW_LAMBDA
1185 void ConnectTreeExpand(std::function<int(HTREEITEM)> userfunc) 1191 void ConnectTreeExpand(std::function<int(HTREEITEM)> userfunc)
1186 #else 1192 #else
1187 void ConnectTreeExpand(int (*userfunc)(HTREEITEM)) 1193 void ConnectTreeExpand(int (*userfunc)(HTREEITEM))
1188 #endif 1194 #endif
1189 { 1195 {