ui/gtk/button.c

branch
newapi
changeset 308
4efc7c19e31d
parent 301
f9e7c57e1e2f
equal deleted inserted replaced
307:301d6c73087a 308:4efc7c19e31d
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(GtkToggleButton *widget, UiVarEventData *event) { 121 void ui_toggled_obs(void *widget, UiVarEventData *event) {
116 UiInteger *i = event->var->value; 122 UiInteger *i = event->var->value;
117 UiEvent e; 123 UiEvent e;
118 e.obj = event->obj; 124 e.obj = event->obj;
119 e.window = event->obj->window; 125 e.window = event->obj->window;
120 e.document = event->obj->ctx->document; 126 e.document = event->obj->ctx->document;
122 e.intval = i->get(i); 128 e.intval = i->get(i);
123 129
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 }
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);
160 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;
180 GtkCheckButton *button = integer->obj; 253 GtkCheckButton *button = integer->obj;
181 integer->value = value; 254 integer->value = value;
182 gtk_check_button_set_active(button, value != 0 ? TRUE : FALSE); 255 gtk_check_button_set_active(button, value != 0 ? TRUE : FALSE);
183 } 256 }
184 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
185 UIWIDGET ui_checkbox_create(UiObject* obj, UiToggleArgs args) { 268 UIWIDGET ui_checkbox_create(UiObject* obj, UiToggleArgs args) {
186 UiObject* current = uic_current_obj(obj); 269 UiObject* current = uic_current_obj(obj);
187 270
188 GtkWidget *widget = gtk_check_button_new_with_label(args.label); 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
290 UIWIDGET ui_checkbox_create(UiObject* obj, UiToggleArgs args) {
291 return togglebutton_create(obj, gtk_check_button_new(), args);
292 }
293 #endif
294
295 UIWIDGET ui_switch_create(UiObject* obj, UiToggleArgs args) {
296 #ifdef UI_GTK3
297 return NULL; // TODO
298 #else
299 return ui_checkbox_create(obj, args);
300 #endif
301 }
302
303 #if GTK_MAJOR_VERSION >= 4
304 #define RADIOBUTTON_NEW(group, label) gtk_check_button_new_with_label(label)
305 #define RADIOBUTTON_SET_GROUP(button, group)
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 }
324
325 UIWIDGET ui_radiobutton_create(UiObject *obj, UiToggleArgs args) {
326 UiObject* current = uic_current_obj(obj);
327
328 GSList *rg = NULL;
329 UiInteger *rgroup;
189 330
190 UiVar* var = uic_widget_var(obj->ctx, current->ctx, args.value, args.varname, UI_VAR_INTEGER); 331 UiVar* var = uic_widget_var(obj->ctx, current->ctx, args.value, args.varname, UI_VAR_INTEGER);
191 if (var) { 332
192 UiInteger* value = (UiInteger*)var->value; 333 UiBool first = FALSE;
193 value->obj = widget; 334 if(var) {
194 value->get = ui_check_button_get; 335 rgroup = var->value;
195 value->set = ui_check_button_set; 336 rg = rgroup->obj;
337 if(!rg) {
338 first = TRUE;
339 }
340 }
341
342 GtkWidget *rbutton = RADIOBUTTON_NEW(rg, args.label);
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
354 rgroup->obj = rg;
355 rgroup->get = ui_radiobutton_get;
356 rgroup->set = ui_radiobutton_set;
357
358 ui_radiobutton_set(rgroup, rgroup->value);
196 359
197 UiVarEventData *event = malloc(sizeof(UiVarEventData)); 360 UiVarEventData *event = malloc(sizeof(UiVarEventData));
198 event->obj = obj; 361 event->obj = obj;
199 event->var = var; 362 event->var = var;
200 event->observers = NULL; 363 event->observers = NULL;
201 event->callback = NULL; 364 event->callback = NULL;
202 event->userdata = NULL; 365 event->userdata = NULL;
203
204 g_signal_connect(
205 widget,
206 "toggled",
207 G_CALLBACK(ui_toggled_obs),
208 event);
209 g_signal_connect(
210 widget,
211 "destroy",
212 G_CALLBACK(ui_destroy_vardata),
213 event);
214 }
215
216 UI_APPLY_LAYOUT1(current, args);
217 current->container->add(current->container, widget, FALSE);
218
219 return widget;
220 }
221
222 #else
223 UIWIDGET ui_checkbox_create(UiObject* obj, UiToggleArgs args) {
224 return togglebutton_create(obj, gtk_check_button_new(), args);
225 }
226 #endif
227
228 UIWIDGET ui_switch_create(UiObject* obj, UiToggleArgs args) {
229 #ifdef UI_GTK3
230 return NULL; // TODO
231 #else
232 return ui_checkbox_create(obj, args);
233 #endif
234 }
235
236 #if GTK_MAJOR_VERSION >= 4
237 #define RADIOBUTTON_NEW(group, label) gtk_check_button_new_with_label(label)
238 #define RADIOBUTTON_SET_GROUP(button, group)
239 #define RADIOBUTTON_GET_GROUP(button) GTK_CHECK_BUTTON(button)
240 #else
241 #define RADIOBUTTON_NEW(group, label) gtk_radio_button_new_with_label(group, label)
242 #define RADIOBUTTON_SET_GROUP(button, group) /* noop */
243 #define RADIOBUTTON_GET_GROUP(button) gtk_radio_button_get_group(GTK_RADIO_BUTTON(button))
244 #endif
245
246 UIWIDGET ui_radiobutton_create(UiObject *obj, UiToggleArgs args) {
247 UiObject* current = uic_current_obj(obj);
248
249 GSList *rg = NULL;
250 UiInteger *rgroup;
251
252 UiVar* var = NULL;
253 if (args.value) {
254 var = uic_create_value_var(current->ctx, args.value);
255 } else if (args.varname) {
256 var = uic_create_var(obj->ctx, args.varname, UI_VAR_INTEGER);
257 }
258
259 UiBool first = FALSE;
260 if(var) {
261 rgroup = var->value;
262 rg = rgroup->obj;
263 if(!rg) {
264 first = TRUE;
265 }
266 }
267
268 GtkWidget *rbutton = RADIOBUTTON_NEW(rg, args.label);
269 if(rgroup) {
270 #if GTK_MAJOR_VERSION >= 4
271 if(rg) {
272 gtk_check_button_set_group(GTK_CHECK_BUTTON(rbutton), rg->data);
273 }
274 rg = g_slist_prepend(rg, rbutton);
275 #else
276 gtk_radio_button_set_group(GTK_RADIO_BUTTON(rbutton), rg);
277 rg = gtk_radio_button_get_group(GTK_RADIO_BUTTON(rbutton));
278 #endif
279
280 rgroup->obj = rg;
281 rgroup->get = ui_radiobutton_get;
282 rgroup->set = ui_radiobutton_set;
283
284 ui_radiobutton_set(rgroup, rgroup->value);
285
286 UiVarEventData *event = malloc(sizeof(UiVarEventData));
287 event->obj = obj;
288 event->var = var;
289 event->observers = NULL;
290 event->callback = NULL;
291 event->userdata = NULL;
292 366
293 g_signal_connect( 367 g_signal_connect(
294 rbutton, 368 rbutton,
295 "toggled", 369 "toggled",
296 G_CALLBACK(ui_radio_obs), 370 G_CALLBACK(ui_radio_obs),
300 rbutton, 374 rbutton,
301 "destroy", 375 "destroy",
302 G_CALLBACK(ui_destroy_vardata), 376 G_CALLBACK(ui_destroy_vardata),
303 event); 377 event);
304 } 378 }
379 }
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);
305 } 399 }
306 400
307 UiContainer *ct = uic_get_current_container(obj); 401 UiContainer *ct = uic_get_current_container(obj);
308 ct->add(ct, rbutton, FALSE); 402 ct->add(ct, rbutton, FALSE);
309 403

mercurial