ui/win32/button.c

changeset 115
e57ca2747782
parent 113
dde28a806552
equal deleted inserted replaced
114:3da24640513a 115:e57ca2747782
30 #include "widget.h" 30 #include "widget.h"
31 31
32 #include <stdio.h> 32 #include <stdio.h>
33 #include <stdlib.h> 33 #include <stdlib.h>
34 34
35 #include <cx/array_list.h>
36
35 #include <commctrl.h> 37 #include <commctrl.h>
36 38
37 static W32WidgetClass button_widget_class = { 39 static W32WidgetClass button_widget_class = {
38 .eventproc = ui_button_eventproc, 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,
39 .enable = w32_widget_default_enable, 57 .enable = w32_widget_default_enable,
40 .show = w32_widget_default_show, 58 .show = w32_widget_default_show,
41 .get_preferred_size = ui_button_get_preferred_size, 59 .get_preferred_size = ui_button_get_preferred_size,
42 .destroy = w32_widget_default_destroy 60 .destroy = w32_widget_default_destroy
43 }; 61 };
80 size.height = sz.cy; 98 size.height = sz.cy;
81 } 99 }
82 return size; 100 return size;
83 } 101 }
84 102
85 void ui_button_eventproc(W32Widget *widget, HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { 103 int ui_button_eventproc(W32Widget *widget, HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
86 UiWidget *w = (UiWidget*)widget; 104 UiWidget *w = (UiWidget*)widget;
87 105
88 printf("button eventproc\n"); 106 if (uMsg != WM_COMMAND) {
89 fflush(stdout); 107 return 0;
108 }
90 109
91 UiEvent e; 110 UiEvent e;
92 e.obj = w->obj; 111 e.obj = w->obj;
93 e.document = e.obj->ctx->document; 112 e.document = e.obj->ctx->document;
94 e.window = e.obj->window; 113 e.window = e.obj->window;
98 e.set = ui_get_setop(); 117 e.set = ui_get_setop();
99 118
100 if (w->callback) { 119 if (w->callback) {
101 w->callback(&e, w->callbackdata); 120 w->callback(&e, w->callbackdata);
102 } 121 }
103 } 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 // Use a CxList as binding object (i->obj) and add all radiobuttons to it
240 // The first radiobutton, which binds to this var, creates the CxList
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 // TODO: select
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; // ignore uncheck events
272 }
273
274 int b = 0;
275 if (w->var) {
276 UiInteger *i = w->var->value;
277 CxList *group = i->obj;
278 // Find selected index and uncheck all radiobuttons in this group
279 // that are not this event widget
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 }

mercurial