| 42 .destroy = w32_widget_default_destroy |
44 .destroy = w32_widget_default_destroy |
| 43 }; |
45 }; |
| 44 |
46 |
| 45 static W32WidgetClass togglebutton_widget_class = { |
47 static W32WidgetClass togglebutton_widget_class = { |
| 46 .eventproc = ui_togglebutton_eventproc, |
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, |
| 47 .enable = w32_widget_default_enable, |
57 .enable = w32_widget_default_enable, |
| 48 .show = w32_widget_default_show, |
58 .show = w32_widget_default_show, |
| 49 .get_preferred_size = ui_button_get_preferred_size, |
59 .get_preferred_size = ui_button_get_preferred_size, |
| 50 .destroy = w32_widget_default_destroy |
60 .destroy = w32_widget_default_destroy |
| 51 }; |
61 }; |
| 194 |
204 |
| 195 if (w->callback) { |
205 if (w->callback) { |
| 196 w->callback(&e, w->callbackdata); |
206 w->callback(&e, w->callbackdata); |
| 197 } |
207 } |
| 198 } |
208 } |
| |
209 |
| |
210 |
| |
211 UIWIDGET ui_radiobutton_create(UiObject *obj, UiToggleArgs *args) { |
| |
212 HINSTANCE hInstance = GetModuleHandle(NULL); |
| |
213 UiContainerPrivate *container = ui_obj_container(obj); |
| |
214 HWND parent = ui_container_get_parent(container); |
| |
215 UiLayout layout = UI_ARGS2LAYOUT(args); |
| |
216 |
| |
217 HWND hwnd = CreateWindow( |
| |
218 "BUTTON", |
| |
219 args->label, |
| |
220 WS_VISIBLE | WS_CHILD | BS_AUTORADIOBUTTON | WS_GROUP , |
| |
221 0, 0, 100, 30, |
| |
222 parent, |
| |
223 (HMENU)1, |
| |
224 hInstance, |
| |
225 NULL); |
| |
226 ui_win32_set_ui_font(hwnd); |
| |
227 |
| |
228 W32Widget *widget = w32_widget_create(&radiobutton_widget_class, hwnd, sizeof(UiWidget)); |
| |
229 ui_container_add(container, widget, &layout); |
| |
230 UiWidget *btn = (UiWidget*)widget; |
| |
231 |
| |
232 UiVar *var = uic_widget_var(obj->ctx, obj->ctx, args->value, args->varname, UI_VAR_INTEGER); |
| |
233 if (var) { |
| |
234 UiInteger *i = var->value; |
| |
235 // Use a CxList as binding object (i->obj) and add all radiobuttons to it |
| |
236 // The first radiobutton, which binds to this var, creates the CxList |
| |
237 CxList *group = NULL; |
| |
238 if (i->obj) { |
| |
239 group = i->obj; |
| |
240 } else { |
| |
241 group = cxArrayListCreate(obj->ctx->allocator, NULL, CX_STORE_POINTERS, 8); |
| |
242 i->obj = group; |
| |
243 } |
| |
244 |
| |
245 cxListAdd(group, btn); |
| |
246 if (i->value == cxListSize(group)) { |
| |
247 // TODO: select |
| |
248 } |
| |
249 } |
| |
250 |
| |
251 btn->obj = obj; |
| |
252 btn->var = var; |
| |
253 btn->callback = args->onchange; |
| |
254 btn->callbackdata = args->onchangedata; |
| |
255 |
| |
256 return widget; |
| |
257 } |
| |
258 |
| |
259 void ui_radiobutton_eventproc(W32Widget *widget, HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { |
| |
260 if (uMsg != WM_COMMAND) { |
| |
261 return; |
| |
262 } |
| |
263 UiWidget *w = (UiWidget*)widget; |
| |
264 |
| |
265 int checked = SendMessage(w->widget.hwnd, BM_GETCHECK, 0, 0); |
| |
266 if (!checked) { |
| |
267 return; // ignore uncheck events |
| |
268 } |
| |
269 |
| |
270 int b = 0; |
| |
271 if (w->var) { |
| |
272 UiInteger *i = w->var->value; |
| |
273 CxList *group = i->obj; |
| |
274 // Find selected index and uncheck all radiobuttons in this group |
| |
275 // that are not this event widget |
| |
276 CxIterator iter = cxListIterator(group); |
| |
277 cx_foreach(UiWidget *, radiobutton, iter) { |
| |
278 if (radiobutton == w) { |
| |
279 i->value = iter.index+1; |
| |
280 b = i->value; |
| |
281 } else { |
| |
282 SendMessage(radiobutton->widget.hwnd, BM_SETCHECK, BST_UNCHECKED, 0); |
| |
283 } |
| |
284 } |
| |
285 } |
| |
286 |
| |
287 UiEvent e; |
| |
288 e.obj = w->obj; |
| |
289 e.document = e.obj->ctx->document; |
| |
290 e.window = e.obj->window; |
| |
291 e.eventdata = NULL; |
| |
292 e.eventdatatype = 0; |
| |
293 e.intval = b; |
| |
294 e.set = ui_get_setop(); |
| |
295 |
| |
296 if (w->callback) { |
| |
297 w->callback(&e, w->callbackdata); |
| |
298 } |
| |
299 } |
| |
300 |
| |
301 int64_t ui_radiobutton_get(UiInteger *i) { |
| |
302 return i->value; |
| |
303 } |
| |
304 |
| |
305 void ui_radiobutton_set(UiInteger *i, int64_t v) { |
| |
306 CxList *group = i->obj; |
| |
307 CxIterator iter = cxListIterator(group); |
| |
308 cx_foreach(UiWidget *, radiobutton, iter) { |
| |
309 SendMessage(radiobutton->widget.hwnd, BM_SETCHECK, iter.index+1 == v ? BST_CHECKED : BST_UNCHECKED, 0); |
| |
310 } |
| |
311 i->value = v; |
| |
312 } |