ui/gtk/button.c

changeset 44
473954dc6b74
parent 32
e5f4d8af567e
child 45
ab71409644b0
equal deleted inserted replaced
43:ef01d2c90128 44:473954dc6b74
52 // TODO 52 // TODO
53 #endif 53 #endif
54 #endif 54 #endif
55 } 55 }
56 56
57 UIWIDGET ui_button_create(UiObject *obj, UiButtonArgs args) { 57 GtkWidget* ui_create_button(
58 UiObject* current = uic_current_obj(obj); 58 UiObject *obj,
59 GtkWidget *button = gtk_button_new(); 59 const char *label,
60 if(args.label) { 60 const char *icon,
61 gtk_button_set_label(GTK_BUTTON(button), args.label); 61 ui_callback onclick,
62 } 62 void *userdata)
63 ui_button_set_icon_name(button, args.icon); 63 {
64 64 GtkWidget *button = gtk_button_new_with_label(label);
65 65 ui_button_set_icon_name(button, icon);
66 if(args.onclick) { 66
67 if(onclick) {
67 UiEventData *event = malloc(sizeof(UiEventData)); 68 UiEventData *event = malloc(sizeof(UiEventData));
68 event->obj = obj; 69 event->obj = obj;
69 event->userdata = args.onclickdata; 70 event->userdata = userdata;
70 event->callback = args.onclick; 71 event->callback = onclick;
71 event->value = 0; 72 event->value = 0;
72 event->customdata = NULL; 73 event->customdata = NULL;
73 74
74 g_signal_connect( 75 g_signal_connect(
75 button, 76 button,
81 "destroy", 82 "destroy",
82 G_CALLBACK(ui_destroy_userdata), 83 G_CALLBACK(ui_destroy_userdata),
83 event); 84 event);
84 } 85 }
85 86
87 return button;
88 }
89
90 UIWIDGET ui_button_create(UiObject *obj, UiButtonArgs args) {
91 UiObject* current = uic_current_obj(obj);
92 GtkWidget *button = ui_create_button(obj, args.label, args.icon, args.onclick, args.onclickdata);
86 UI_APPLY_LAYOUT1(current, args); 93 UI_APPLY_LAYOUT1(current, args);
87 current->container->add(current->container, button, FALSE); 94 current->container->add(current->container, button, FALSE);
88
89 return button; 95 return button;
90 } 96 }
91 97
92 98
93 void ui_button_clicked(GtkWidget *widget, UiEventData *event) { 99 void ui_button_clicked(GtkWidget *widget, UiEventData *event) {
110 GtkToggleButton *button = integer->obj; 116 GtkToggleButton *button = integer->obj;
111 integer->value = value; 117 integer->value = value;
112 gtk_toggle_button_set_active(button, value != 0 ? TRUE : FALSE); 118 gtk_toggle_button_set_active(button, value != 0 ? TRUE : FALSE);
113 } 119 }
114 120
115 void ui_toggled_obs(GtkToggleToolButton *widget, UiVarEventData *event) { 121 void ui_toggled_obs(void *widget, UiVarEventData *event) {
122 UiInteger *i = event->var->value;
116 UiEvent e; 123 UiEvent e;
117 e.obj = event->obj; 124 e.obj = event->obj;
118 e.window = event->obj->window; 125 e.window = event->obj->window;
119 e.document = event->obj->ctx->document; 126 e.document = event->obj->ctx->document;
120 e.eventdata = event->var->value; 127 e.eventdata = event->var->value;
121 e.intval = gtk_toggle_tool_button_get_active(widget); 128 e.intval = i->get(i);
122 129
123 UiInteger *i = event->var->value;
124 ui_notify_evt(i->observers, &e); 130 ui_notify_evt(i->observers, &e);
125 } 131 }
126 132
127 static UIWIDGET togglebutton_create(UiObject *obj, GtkWidget *widget, UiToggleArgs args) { 133 static void ui_toggled_callback(GtkToggleButton *widget, UiEventData *event) {
134 UiEvent e;
135 e.obj = event->obj;
136 e.window = event->obj->window;
137 e.document = event->obj->ctx->document;
138 e.eventdata = NULL;
139 e.intval = gtk_toggle_button_get_active(widget);
140 event->callback(&e, event->userdata);
141 }
142
143 void ui_setup_togglebutton(
144 UiObject *obj,
145 GtkWidget *togglebutton,
146 const char *label,
147 const char *icon,
148 const char *varname,
149 UiInteger *value,
150 ui_callback onchange,
151 void *onchangedata)
152 {
153 if(label) {
154 gtk_button_set_label(GTK_BUTTON(togglebutton), label);
155 }
156 ui_button_set_icon_name(togglebutton, icon);
157
158 ui_bind_togglebutton(
159 obj,
160 togglebutton,
161 ui_toggle_button_get,
162 ui_toggle_button_set,
163 varname,
164 value,
165 (ui_toggled_func)ui_toggled_callback,
166 onchange,
167 onchangedata);
168 }
169
170 void ui_bind_togglebutton(
171 UiObject *obj,
172 GtkWidget *widget,
173 int64_t (*getfunc)(UiInteger*),
174 void (*setfunc)(UiInteger*, int64_t),
175 const char *varname,
176 UiInteger *value,
177 void (*toggled_callback)(void*, void*),
178 ui_callback onchange,
179 void *onchangedata)
180 {
128 UiObject* current = uic_current_obj(obj); 181 UiObject* current = uic_current_obj(obj);
129 182 UiVar* var = uic_widget_var(obj->ctx, current->ctx, value, varname, UI_VAR_INTEGER);
130 if(args.label) {
131 gtk_button_set_label(GTK_BUTTON(widget), args.label);
132 }
133 ui_button_set_icon_name(widget, args.icon);
134
135 UiVar* var = uic_widget_var(obj->ctx, current->ctx, args.value, args.varname, UI_VAR_INTEGER);
136 if (var) { 183 if (var) {
137 UiInteger* value = (UiInteger*)var->value; 184 UiInteger* value = (UiInteger*)var->value;
138 value->obj = widget; 185 value->obj = widget;
139 value->get = ui_toggle_button_get; 186 value->get = getfunc;
140 value->set = ui_toggle_button_set; 187 value->set = setfunc;
141 188
142 UiVarEventData *event = malloc(sizeof(UiVarEventData)); 189 UiVarEventData *event = malloc(sizeof(UiVarEventData));
143 event->obj = obj; 190 event->obj = obj;
144 event->var = var; 191 event->var = var;
145 event->observers = NULL; 192 event->observers = NULL;
146 event->callback = NULL; 193 event->callback = NULL;
147 event->userdata = NULL; 194 event->userdata = NULL;
148 195
149 g_signal_connect( 196 g_signal_connect(
150 widget, 197 widget,
151 "clicked", 198 "toggled",
152 G_CALLBACK(ui_toggled_obs), 199 G_CALLBACK(ui_toggled_obs),
153 event); 200 event);
154 g_signal_connect( 201 g_signal_connect(
155 widget, 202 widget,
156 "destroy", 203 "destroy",
157 G_CALLBACK(ui_destroy_vardata), 204 G_CALLBACK(ui_destroy_vardata),
158 event); 205 event);
159 } 206 }
160 207
208 if(onchange) {
209 UiEventData *event = malloc(sizeof(UiEventData));
210 event->obj = obj;
211 event->userdata = onchangedata;
212 event->callback = onchange;
213 event->value = 0;
214 event->customdata = NULL;
215
216 g_signal_connect(
217 widget,
218 "toggled",
219 G_CALLBACK(toggled_callback),
220 event);
221 g_signal_connect(
222 widget,
223 "destroy",
224 G_CALLBACK(ui_destroy_userdata),
225 event);
226 }
227 }
228
229 static UIWIDGET togglebutton_create(UiObject *obj, GtkWidget *widget, UiToggleArgs args) {
230 UiObject* current = uic_current_obj(obj);
231
232 ui_setup_togglebutton(current, widget, args.label, args.icon, args.varname, args.value, args.onchange, args.onchangedata);
233
161 UI_APPLY_LAYOUT1(current, args); 234 UI_APPLY_LAYOUT1(current, args);
162 current->container->add(current->container, widget, FALSE); 235 current->container->add(current->container, widget, FALSE);
163 236
164 return widget; 237 return widget;
165 } 238 }
166 239
167 UIWIDGET ui_togglebutton_create(UiObject* obj, UiToggleArgs args) { 240 UIWIDGET ui_togglebutton_create(UiObject* obj, UiToggleArgs args) {
168 return togglebutton_create(obj, gtk_toggle_button_new(), args); 241 return togglebutton_create(obj, gtk_toggle_button_new(), args);
169 } 242 }
170 243
244 #if GTK_MAJOR_VERSION >= 4
245
246 int64_t ui_check_button_get(UiInteger *integer) {
247 GtkCheckButton *button = integer->obj;
248 integer->value = (int)gtk_check_button_get_active(button);
249 return integer->value;
250 }
251
252 void ui_check_button_set(UiInteger *integer, int64_t value) {
253 GtkCheckButton *button = integer->obj;
254 integer->value = value;
255 gtk_check_button_set_active(button, value != 0 ? TRUE : FALSE);
256 }
257
258 static void ui_checkbox_callback(GtkCheckButton *widget, UiEventData *event) {
259 UiEvent e;
260 e.obj = event->obj;
261 e.window = event->obj->window;
262 e.document = event->obj->ctx->document;
263 e.eventdata = NULL;
264 e.intval = gtk_check_button_get_active(widget);
265 event->callback(&e, event->userdata);
266 }
267
268 UIWIDGET ui_checkbox_create(UiObject* obj, UiToggleArgs args) {
269 UiObject* current = uic_current_obj(obj);
270
271 GtkWidget *widget = gtk_check_button_new_with_label(args.label);
272 ui_bind_togglebutton(
273 obj,
274 widget,
275 ui_check_button_get,
276 ui_check_button_set,
277 args.varname,
278 args.value,
279 (ui_toggled_func)ui_checkbox_callback,
280 args.onchange,
281 args.onchangedata);
282
283 UI_APPLY_LAYOUT1(current, args);
284 current->container->add(current->container, widget, FALSE);
285
286 return widget;
287 }
288
289 #else
171 UIWIDGET ui_checkbox_create(UiObject* obj, UiToggleArgs args) { 290 UIWIDGET ui_checkbox_create(UiObject* obj, UiToggleArgs args) {
172 return togglebutton_create(obj, gtk_check_button_new(), args); 291 return togglebutton_create(obj, gtk_check_button_new(), args);
173 } 292 }
293 #endif
174 294
175 UIWIDGET ui_switch_create(UiObject* obj, UiToggleArgs args) { 295 UIWIDGET ui_switch_create(UiObject* obj, UiToggleArgs args) {
176 #ifdef UI_GTK3 296 #ifdef UI_GTK3
177 return NULL; // TODO 297 return NULL; // TODO
178 #else 298 #else
179 return ui_checkbox_create(obj, args); 299 return ui_checkbox_create(obj, args);
180 #endif 300 #endif
181 } 301 }
182 302
183 303 #if GTK_MAJOR_VERSION >= 4
184 304 #define RADIOBUTTON_NEW(group, label) gtk_check_button_new_with_label(label)
185 305 #define RADIOBUTTON_SET_GROUP(button, group)
186 306 #define RADIOBUTTON_GET_GROUP(button) GTK_CHECK_BUTTON(button)
307 #define RADIOBUTTON_GET_ACTIVE(button) gtk_check_button_get_active(GTK_CHECK_BUTTON(button))
308 #else
309 #define RADIOBUTTON_NEW(group, label) gtk_radio_button_new_with_label(group, label)
310 #define RADIOBUTTON_SET_GROUP(button, group) /* noop */
311 #define RADIOBUTTON_GET_GROUP(button) gtk_radio_button_get_group(GTK_RADIO_BUTTON(button))
312 #define RADIOBUTTON_GET_ACTIVE(button) gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button))
313 #endif
314
315 static void radiobutton_toggled(void *widget, UiEventData *event) {
316 UiEvent e;
317 e.obj = event->obj;
318 e.window = event->obj->window;
319 e.document = event->obj->ctx->document;
320 e.eventdata = NULL;
321 e.intval = RADIOBUTTON_GET_ACTIVE(widget);
322 event->callback(&e, event->userdata);
323 }
187 324
188 UIWIDGET ui_radiobutton_create(UiObject *obj, UiToggleArgs args) { 325 UIWIDGET ui_radiobutton_create(UiObject *obj, UiToggleArgs args) {
189 UiObject* current = uic_current_obj(obj); 326 UiObject* current = uic_current_obj(obj);
190 327
191 GSList *rg = NULL; 328 GSList *rg = NULL;
192 UiInteger *rgroup; 329 UiInteger *rgroup;
193 330
194 UiVar* var = NULL; 331 UiVar* var = uic_widget_var(obj->ctx, current->ctx, args.value, args.varname, UI_VAR_INTEGER);
195 if (args.value) {
196 var = uic_create_value_var(current->ctx, args.value);
197 } else if (args.varname) {
198 var = uic_create_var(obj->ctx, args.varname, UI_VAR_INTEGER);
199 }
200 332
201 UiBool first = FALSE; 333 UiBool first = FALSE;
202 if(var) { 334 if(var) {
203 rgroup = var->value; 335 rgroup = var->value;
204 rg = rgroup->obj; 336 rg = rgroup->obj;
205 if(!rg) { 337 if(!rg) {
206 first = TRUE; 338 first = TRUE;
207 } 339 }
208 } 340 }
209 341
210 GtkWidget *rbutton = gtk_radio_button_new_with_label(rg, args.label ? args.label : ""); 342 GtkWidget *rbutton = RADIOBUTTON_NEW(rg, args.label);
211 rg = gtk_radio_button_get_group(GTK_RADIO_BUTTON(rbutton));
212
213 if(rgroup) { 343 if(rgroup) {
344 #if GTK_MAJOR_VERSION >= 4
345 if(rg) {
346 gtk_check_button_set_group(GTK_CHECK_BUTTON(rbutton), rg->data);
347 }
348 rg = g_slist_prepend(rg, rbutton);
349 #else
350 gtk_radio_button_set_group(GTK_RADIO_BUTTON(rbutton), rg);
351 rg = gtk_radio_button_get_group(GTK_RADIO_BUTTON(rbutton));
352 #endif
353
214 rgroup->obj = rg; 354 rgroup->obj = rg;
215 rgroup->get = ui_radiobutton_get; 355 rgroup->get = ui_radiobutton_get;
216 rgroup->set = ui_radiobutton_set; 356 rgroup->set = ui_radiobutton_set;
217 357
218 ui_radiobutton_set(rgroup, rgroup->value); 358 ui_radiobutton_set(rgroup, rgroup->value);
224 event->callback = NULL; 364 event->callback = NULL;
225 event->userdata = NULL; 365 event->userdata = NULL;
226 366
227 g_signal_connect( 367 g_signal_connect(
228 rbutton, 368 rbutton,
229 "clicked", 369 "toggled",
230 G_CALLBACK(ui_radio_obs), 370 G_CALLBACK(ui_radio_obs),
231 event); 371 event);
232 if(first) { 372 if(first) {
233 g_signal_connect( 373 g_signal_connect(
234 rbutton, 374 rbutton,
236 G_CALLBACK(ui_destroy_vardata), 376 G_CALLBACK(ui_destroy_vardata),
237 event); 377 event);
238 } 378 }
239 } 379 }
240 380
381 if(args.onchange) {
382 UiEventData *event = malloc(sizeof(UiEventData));
383 event->obj = obj;
384 event->userdata = args.onchangedata;
385 event->callback = args.onchange;
386 event->value = 0;
387 event->customdata = NULL;
388
389 g_signal_connect(
390 rbutton,
391 "toggled",
392 G_CALLBACK(radiobutton_toggled),
393 event);
394 g_signal_connect(
395 rbutton,
396 "destroy",
397 G_CALLBACK(ui_destroy_userdata),
398 event);
399 }
400
241 UiContainer *ct = uic_get_current_container(obj); 401 UiContainer *ct = uic_get_current_container(obj);
242 ct->add(ct, rbutton, FALSE); 402 ct->add(ct, rbutton, FALSE);
243 403
244 return rbutton; 404 return rbutton;
245 } 405 }
246 406
247 void ui_radio_obs(GtkToggleToolButton *widget, UiVarEventData *event) { 407 void ui_radio_obs(GtkToggleButton *widget, UiVarEventData *event) {
248 UiInteger *i = event->var->value; 408 UiInteger *i = event->var->value;
249 409
250 UiEvent e; 410 UiEvent e;
251 e.obj = event->obj; 411 e.obj = event->obj;
252 e.window = event->obj->window; 412 e.window = event->obj->window;
255 e.intval = i->get(i); 415 e.intval = i->get(i);
256 416
257 ui_notify_evt(i->observers, &e); 417 ui_notify_evt(i->observers, &e);
258 } 418 }
259 419
420 #if GTK_MAJOR_VERSION >= 4
421 int64_t ui_radiobutton_get(UiInteger *value) {
422 int selection = 0;
423 GSList *ls = value->obj;
424 int i = 0;
425 guint len = g_slist_length(ls);
426 while(ls) {
427 if(gtk_check_button_get_active(GTK_CHECK_BUTTON(ls->data))) {
428 selection = len - i - 1;
429 break;
430 }
431 ls = ls->next;
432 i++;
433 }
434
435 value->value = selection;
436 return selection;
437 }
438
439 void ui_radiobutton_set(UiInteger *value, int64_t i) {
440 GSList *ls = value->obj;
441 int s = g_slist_length(ls) - 1 - i;
442 int j = 0;
443 while(ls) {
444 if(j == s) {
445 gtk_check_button_set_active(GTK_CHECK_BUTTON(ls->data), TRUE);
446 break;
447 }
448 ls = ls->next;
449 j++;
450 }
451
452 value->value = i;
453 }
454 #else
260 int64_t ui_radiobutton_get(UiInteger *value) { 455 int64_t ui_radiobutton_get(UiInteger *value) {
261 int selection = 0; 456 int selection = 0;
262 GSList *ls = value->obj; 457 GSList *ls = value->obj;
263 int i = 0; 458 int i = 0;
264 guint len = g_slist_length(ls); 459 guint len = g_slist_length(ls);
288 j++; 483 j++;
289 } 484 }
290 485
291 value->value = i; 486 value->value = i;
292 } 487 }
293 488 #endif

mercurial