ui/gtk/button.c

changeset 0
2483f517c562
child 29
3fc287f06305
equal deleted inserted replaced
-1:000000000000 0:2483f517c562
1 /*
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3 *
4 * Copyright 2017 Olaf Wintermann. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #include <stdio.h>
30 #include <stdlib.h>
31
32 #include "button.h"
33 #include "container.h"
34 #include <cx/allocator.h>
35 #include "../common/context.h"
36 #include "../common/object.h"
37
38 UIWIDGET ui_button(UiObject *obj, char *label, ui_callback f, void *data) {
39 GtkWidget *button = gtk_button_new_with_label(label);
40
41 if(f) {
42 UiEventData *event = malloc(sizeof(UiEventData));
43 event->obj = obj;
44 event->userdata = data;
45 event->callback = f;
46 event->value = 0;
47
48 g_signal_connect(
49 button,
50 "clicked",
51 G_CALLBACK(ui_button_clicked),
52 event);
53 g_signal_connect(
54 button,
55 "destroy",
56 G_CALLBACK(ui_destroy_userdata),
57 event);
58 }
59
60 UiContainer *ct = uic_get_current_container(obj);
61 ct->add(ct, button, FALSE);
62
63 return button;
64 }
65
66
67 void ui_button_clicked(GtkWidget *widget, UiEventData *event) {
68 UiEvent e;
69 e.obj = event->obj;
70 e.window = event->obj->window;
71 e.document = event->obj->ctx->document;
72 e.eventdata = NULL;
73 e.intval = event->value;
74 event->callback(&e, event->userdata);
75 }
76
77 int64_t ui_toggle_button_get(UiInteger *integer) {
78 GtkToggleButton *button = integer->obj;
79 integer->value = (int)gtk_toggle_button_get_active(button);
80 return integer->value;
81 }
82
83 void ui_toggle_button_set(UiInteger *integer, int64_t value) {
84 GtkToggleButton *button = integer->obj;
85 integer->value = value;
86 gtk_toggle_button_set_active(button, value != 0 ? TRUE : FALSE);
87 }
88
89 void ui_toggled_obs(GtkToggleToolButton *widget, UiVarEventData *event) {
90 UiEvent e;
91 e.obj = event->obj;
92 e.window = event->obj->window;
93 e.document = event->obj->ctx->document;
94 e.eventdata = event->var->value;
95 e.intval = gtk_toggle_tool_button_get_active(widget);
96
97 UiInteger *i = event->var->value;
98 ui_notify_evt(i->observers, &e);
99 }
100
101 UIWIDGET ui_checkbox_var(UiObject *obj, char *label, UiVar *var) {
102 GtkWidget *button = gtk_check_button_new_with_label(label);
103
104 // bind value
105 if(var) {
106 UiInteger *value = var->value;
107 value->obj = GTK_TOGGLE_BUTTON(button);
108 value->get = ui_toggle_button_get;
109 value->set = ui_toggle_button_set;
110 gtk_toggle_button_set_active(value->obj, value->value);
111
112 UiVarEventData *event = malloc(sizeof(UiVarEventData));
113 event->obj = obj;
114 event->var = var;
115 event->observers = NULL;
116
117 g_signal_connect(
118 button,
119 "clicked",
120 G_CALLBACK(ui_toggled_obs),
121 event);
122 g_signal_connect(
123 button,
124 "destroy",
125 G_CALLBACK(ui_destroy_vardata),
126 event);
127 }
128
129 UiContainer *ct = uic_get_current_container(obj);
130 ct->add(ct, button, FALSE);
131
132 return button;
133 }
134
135 UIWIDGET ui_checkbox(UiObject *obj, char *label, UiInteger *value) {
136 UiVar *var = NULL;
137 if(value) {
138 var = malloc(sizeof(UiVar));
139 var->value = value;
140 var->type = UI_VAR_SPECIAL;
141 }
142 return ui_checkbox_var(obj, label, var);
143 }
144
145 UIWIDGET ui_checkbox_nv(UiObject *obj, char *label, char *varname) {
146 UiVar *var = uic_create_var(obj->ctx, varname, UI_VAR_INTEGER);
147 return ui_checkbox_var(obj, label, var);
148 }
149
150
151 UIWIDGET ui_radiobutton_var(UiObject *obj, char *label, UiVar *var) {
152 GSList *rg = NULL;
153 UiInteger *rgroup;
154
155 if(var) {
156 rgroup = var->value;
157 rg = rgroup->obj;
158 }
159
160 GtkWidget *rbutton = gtk_radio_button_new_with_label(rg, label);
161 rg = gtk_radio_button_get_group(GTK_RADIO_BUTTON(rbutton));
162
163 if(rgroup) {
164 rgroup->obj = rg;
165 rgroup->get = ui_radiobutton_get;
166 rgroup->set = ui_radiobutton_set;
167
168 ui_radiobutton_set(rgroup, rgroup->value);
169
170 UiVarEventData *event = malloc(sizeof(UiVarEventData));
171 event->obj = obj;
172 event->var = var;
173 event->observers = NULL;
174
175 g_signal_connect(
176 rbutton,
177 "clicked",
178 G_CALLBACK(ui_radio_obs),
179 event);
180 g_signal_connect(
181 rbutton,
182 "destroy",
183 G_CALLBACK(ui_destroy_vardata),
184 event);
185 }
186
187 UiContainer *ct = uic_get_current_container(obj);
188 ct->add(ct, rbutton, FALSE);
189
190 return rbutton;
191 }
192
193 UIWIDGET ui_radiobutton(UiObject *obj, char *label, UiInteger *rgroup) {
194 UiVar *var = NULL;
195 if(rgroup) {
196 var = malloc(sizeof(UiVar));
197 var->value = rgroup;
198 var->type = UI_VAR_SPECIAL;
199 }
200 return ui_radiobutton_var(obj, label, var);
201 }
202
203 UIWIDGET ui_radiobutton_nv(UiObject *obj, char *label, char *varname) {
204 UiVar *var = uic_create_var(obj->ctx, varname, UI_VAR_INTEGER);
205 return ui_radiobutton_var(obj, label, var);
206 }
207
208 void ui_radio_obs(GtkToggleToolButton *widget, UiVarEventData *event) {
209 UiInteger *i = event->var->value;
210
211 UiEvent e;
212 e.obj = event->obj;
213 e.window = event->obj->window;
214 e.document = event->obj->ctx->document;
215 e.eventdata = NULL;
216 e.intval = i->get(i);
217
218 ui_notify_evt(i->observers, &e);
219 }
220
221 int64_t ui_radiobutton_get(UiInteger *value) {
222 int selection = 0;
223 GSList *ls = value->obj;
224 int i = 0;
225 guint len = g_slist_length(ls);
226 while(ls) {
227 if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ls->data))) {
228 selection = len - i - 1;
229 break;
230 }
231 ls = ls->next;
232 i++;
233 }
234
235 value->value = selection;
236 return selection;
237 }
238
239 void ui_radiobutton_set(UiInteger *value, int64_t i) {
240 GSList *ls = value->obj;
241 int s = g_slist_length(ls) - 1 - i;
242 int j = 0;
243 while(ls) {
244 if(j == s) {
245 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ls->data), TRUE);
246 break;
247 }
248 ls = ls->next;
249 j++;
250 }
251
252 value->value = i;
253 }
254

mercurial