1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 #include "button.h"
30 #include "widget.h"
31
32 #include <stdio.h>
33 #include <stdlib.h>
34
35 #include <cx/array_list.h>
36
37 #include <commctrl.h>
38
39 static W32WidgetClass button_widget_class = {
40 .eventproc = ui_button_eventproc,
41 .enable = w32_widget_default_enable,
42 .show = w32_widget_default_show,
43 .get_preferred_size = ui_button_get_preferred_size,
44 .destroy = w32_widget_default_destroy
45 };
46
47 static W32WidgetClass togglebutton_widget_class = {
48 .eventproc = ui_togglebutton_eventproc,
49 .enable = w32_widget_default_enable,
50 .show = w32_widget_default_show,
51 .get_preferred_size = ui_button_get_preferred_size,
52 .destroy = w32_widget_default_destroy
53 };
54
55 static W32WidgetClass radiobutton_widget_class = {
56 .eventproc = ui_radiobutton_eventproc,
57 .enable = w32_widget_default_enable,
58 .show = w32_widget_default_show,
59 .get_preferred_size = ui_button_get_preferred_size,
60 .destroy = w32_widget_default_destroy
61 };
62
63 UIWIDGET ui_button_create(UiObject *obj, UiButtonArgs *args) {
64 HINSTANCE hInstance = GetModuleHandle(
NULL);
65 UiContainerPrivate *container = ui_obj_container(obj);
66 HWND parent = ui_container_get_parent(container);
67 UiLayout layout =
UI_ARGS2LAYOUT(args);
68
69 HWND hwnd = CreateWindow(
70 "BUTTON",
71 args->label,
72 WS_VISIBLE |
WS_CHILD |
BS_PUSHBUTTON,
73 0,
0,
100,
30,
74 parent,
75 (
HMENU)
1,
76 hInstance,
77 NULL);
78 ui_win32_set_ui_font(hwnd);
79
80 W32Widget *widget = w32_widget_create(&button_widget_class, hwnd,
sizeof(UiWidget));
81 ui_container_add(container, widget, &layout);
82
83 UiWidget *btn = (UiWidget*)widget;
84 btn->obj = obj;
85 btn->callback = args->onclick;
86 btn->callbackdata = args->onclickdata;
87
88 return widget;
89 }
90
91 W32Size ui_button_get_preferred_size(W32Widget *widget) {
92 W32Size size;
93 size.width =
100;
94 size.height =
30;
95 SIZE sz;
96 if (Button_GetIdealSize(widget->hwnd, &sz)) {
97 size.width = sz.cx;
98 size.height = sz.cy;
99 }
100 return size;
101 }
102
103 int ui_button_eventproc(W32Widget *widget,
HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam) {
104 UiWidget *w = (UiWidget*)widget;
105
106 if (uMsg !=
WM_COMMAND) {
107 return 0;
108 }
109
110 UiEvent e;
111 e.obj = w->obj;
112 e.document = e.obj->ctx->document;
113 e.window = e.obj->window;
114 e.eventdata =
NULL;
115 e.eventdatatype =
0;
116 e.intval =
0;
117 e.set = ui_get_setop();
118
119 if (w->callback) {
120 w->callback(&e, w->callbackdata);
121 }
122
123 return 0;
124 }
125
126 static UIWIDGET create_togglebutton(UiObject *obj, UiToggleArgs *args,
unsigned long type) {
127 HINSTANCE hInstance = GetModuleHandle(
NULL);
128 UiContainerPrivate *container = ui_obj_container(obj);
129 HWND parent = ui_container_get_parent(container);
130 UiLayout layout =
UI_ARGS2LAYOUT(args);
131
132 HWND hwnd = CreateWindow(
133 "BUTTON",
134 args->label,
135 WS_VISIBLE |
WS_CHILD | type,
136 0,
0,
100,
30,
137 parent,
138 (
HMENU)
1,
139 hInstance,
140 NULL);
141 ui_win32_set_ui_font(hwnd);
142
143 W32Widget *widget = w32_widget_create(&togglebutton_widget_class, hwnd,
sizeof(UiWidget));
144 ui_container_add(container, widget, &layout);
145
146 UiVar *var = uic_widget_var(obj->ctx, obj->ctx, args->value, args->varname,
UI_VAR_INTEGER);
147 if (var) {
148 UiInteger *i = var->value;
149 i->obj = widget;
150 i->get = ui_togglebutton_get;
151 i->set = ui_togglebutton_set;
152 if (i->value !=
0) {
153 SendMessage(hwnd,
BM_SETCHECK,
BST_CHECKED,
0);
154 }
155 }
156
157 UiWidget *btn = (UiWidget*)widget;
158 btn->obj = obj;
159 btn->var = var;
160 btn->callback = args->onchange;
161 btn->callbackdata = args->onchangedata;
162
163 return widget;
164 }
165
166 UIWIDGET ui_togglebutton_create(UiObject *obj, UiToggleArgs *args) {
167 return create_togglebutton(obj, args,
BS_AUTOCHECKBOX |
BS_PUSHLIKE);
168 }
169
170 UIWIDGET ui_checkbox_create(UiObject *obj, UiToggleArgs *args) {
171 return create_togglebutton(obj, args,
BS_AUTOCHECKBOX);
172 }
173
174 UIWIDGET ui_switch_create(UiObject *obj, UiToggleArgs *args) {
175 return create_togglebutton(obj, args,
BS_AUTOCHECKBOX);
176 }
177
178 int64_t ui_togglebutton_get(UiInteger *i) {
179 UiWidget *btn = (UiWidget*)i->obj;
180 LRESULT state = SendMessage(btn->widget.hwnd,
BM_GETCHECK,
0,
0);
181 i->value = state;
182 return state;
183 }
184
185 void ui_togglebutton_set(UiInteger *i,
int64_t v) {
186 UiWidget *btn = (UiWidget*)i->obj;
187 WPARAM state = v ?
BST_CHECKED :
BST_UNCHECKED;
188 SendMessage(btn->widget.hwnd,
BM_SETCHECK, state,
0);
189 i->value = v;
190 }
191
192 int ui_togglebutton_eventproc(W32Widget *widget,
HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam) {
193 if (uMsg !=
WM_COMMAND) {
194 return 0;
195 }
196 UiWidget *w = (UiWidget*)widget;
197
198 UiEvent e;
199 e.obj = w->obj;
200 e.document = e.obj->ctx->document;
201 e.window = e.obj->window;
202 e.eventdata =
NULL;
203 e.eventdatatype =
0;
204 e.intval = SendMessage(w->widget.hwnd,
BM_GETCHECK,
0,
0);
205 e.set = ui_get_setop();
206
207 if (w->callback) {
208 w->callback(&e, w->callbackdata);
209 }
210
211 return 0;
212 }
213
214
215 UIWIDGET ui_radiobutton_create(UiObject *obj, UiToggleArgs *args) {
216 HINSTANCE hInstance = GetModuleHandle(
NULL);
217 UiContainerPrivate *container = ui_obj_container(obj);
218 HWND parent = ui_container_get_parent(container);
219 UiLayout layout =
UI_ARGS2LAYOUT(args);
220
221 HWND hwnd = CreateWindow(
222 "BUTTON",
223 args->label,
224 WS_VISIBLE |
WS_CHILD |
BS_AUTORADIOBUTTON |
WS_GROUP ,
225 0,
0,
100,
30,
226 parent,
227 (
HMENU)
1,
228 hInstance,
229 NULL);
230 ui_win32_set_ui_font(hwnd);
231
232 W32Widget *widget = w32_widget_create(&radiobutton_widget_class, hwnd,
sizeof(UiWidget));
233 ui_container_add(container, widget, &layout);
234 UiWidget *btn = (UiWidget*)widget;
235
236 UiVar *var = uic_widget_var(obj->ctx, obj->ctx, args->value, args->varname,
UI_VAR_INTEGER);
237 if (var) {
238 UiInteger *i = var->value;
239
240
241 CxList *group =
NULL;
242 if (i->obj) {
243 group = i->obj;
244 }
else {
245 group = cxArrayListCreate(obj->ctx->allocator,
NULL,
CX_STORE_POINTERS,
8);
246 i->obj = group;
247 }
248
249 cxListAdd(group, btn);
250 if (i->value == cxListSize(group)) {
251
252 }
253 }
254
255 btn->obj = obj;
256 btn->var = var;
257 btn->callback = args->onchange;
258 btn->callbackdata = args->onchangedata;
259
260 return widget;
261 }
262
263 int ui_radiobutton_eventproc(W32Widget *widget,
HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam) {
264 if (uMsg !=
WM_COMMAND) {
265 return 0;
266 }
267 UiWidget *w = (UiWidget*)widget;
268
269 int checked = SendMessage(w->widget.hwnd,
BM_GETCHECK,
0,
0);
270 if (!checked) {
271 return 0;
272 }
273
274 int b =
0;
275 if (w->var) {
276 UiInteger *i = w->var->value;
277 CxList *group = i->obj;
278
279
280 CxIterator iter = cxListIterator(group);
281 cx_foreach(UiWidget *, radiobutton, iter) {
282 if (radiobutton == w) {
283 i->value = iter.index
+1;
284 b = i->value;
285 }
else {
286 SendMessage(radiobutton->widget.hwnd,
BM_SETCHECK,
BST_UNCHECKED,
0);
287 }
288 }
289 }
290
291 UiEvent e;
292 e.obj = w->obj;
293 e.document = e.obj->ctx->document;
294 e.window = e.obj->window;
295 e.eventdata =
NULL;
296 e.eventdatatype =
0;
297 e.intval = b;
298 e.set = ui_get_setop();
299
300 if (w->callback) {
301 w->callback(&e, w->callbackdata);
302 }
303
304 return 0;
305 }
306
307 int64_t ui_radiobutton_get(UiInteger *i) {
308 return i->value;
309 }
310
311 void ui_radiobutton_set(UiInteger *i,
int64_t v) {
312 CxList *group = i->obj;
313 CxIterator iter = cxListIterator(group);
314 cx_foreach(UiWidget *, radiobutton, iter) {
315 SendMessage(radiobutton->widget.hwnd,
BM_SETCHECK, iter.index
+1 == v ?
BST_CHECKED :
BST_UNCHECKED,
0);
316 }
317 i->value = v;
318 }
319