GCC Code Coverage Report


Directory: src/gate/
File: src/gate/ui/buttons.c
Date: 2025-09-14 13:10:38
Exec Total Coverage
Lines: 0 21 0.0%
Functions: 0 2 0.0%
Branches: 0 10 0.0%

Line Branch Exec Source
1 /* GATE PROJECT LICENSE:
2 +----------------------------------------------------------------------------+
3 | Copyright(c) 2018-2025, Stefan Meislinger <sm@opengate.at> |
4 | 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 notice, |
10 | this list of conditions and the following disclaimer. |
11 | 2. Redistributions in binary form must reproduce the above copyright |
12 | notice, this list of conditions and the following disclaimer in the |
13 | documentation and/or other materials provided with the distribution. |
14 | |
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"|
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
18 | ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
25 | THE POSSIBILITY OF SUCH DAMAGE. |
26 +----------------------------------------------------------------------------+
27 */
28
29 #include "gate/ui/buttons.h"
30 #include "gate/results.h"
31
32 #if defined(GATE_UI_WINAPI)
33
34
35 #include "gate/ui/gateui_winapi.h"
36 #include "gate/platforms.h"
37
38 static gate_bool_t gate_ui_button_events(void* hwnd, gate_ui_ctrl_t* ctrl, gate_uint32_t msg, gate_uintptr_t wParam, gate_intptr_t lParam, gate_intptr_t* lresult)
39 {
40 HWND hwndCtrl;
41 gate_ui_button_t* button;
42 if ((ctrl != NULL) && (hwnd != NULL))
43 {
44 hwndCtrl = GATE_UI_WINAPI_GET_HWND(ctrl);
45 if (hwndCtrl)
46 {
47 switch (msg)
48 {
49 case WM_COMMAND:
50 {
51 if (hwndCtrl == (HWND)lParam)
52 {
53 button = (gate_ui_button_t*)ctrl;
54 switch (HIWORD(wParam))
55 {
56 case BN_CLICKED:
57 {
58 if (button->on_click != NULL)
59 {
60 button->on_click(ctrl);
61 }
62 *lresult = 0;
63 return true;
64 }
65 default:
66 {
67 break;
68 }
69 }
70 }
71 break;
72 }
73 default:
74 {
75 break;
76 }
77 }
78 }
79 }
80 return false;
81 }
82
83 gate_result_t gate_ui_button_create(
84 gate_ui_button_t* button, gate_ui_ctrl_t* parent,
85 gate_ui_position_t const* position,
86 gate_string_t const* caption,
87 gate_uint32_t flags,
88 void* userparam
89 )
90 {
91 gate_result_t ret;
92 gate_uint32_t styles, exstyles;
93 gate_ui_host_t* host;
94 HWND hwndParent;
95
96 do
97 {
98 host = gate_ui_ctrl_get_host(parent);
99 if (!host)
100 {
101 ret = GATE_RESULT_INVALIDSTATE;
102 break;
103 }
104 hwndParent = GATE_UI_WINAPI_GET_HWND(parent);
105 if (!hwndParent)
106 {
107 ret = GATE_RESULT_INVALIDSTATE;
108 break;
109 }
110
111 gate_mem_clear(button, sizeof(gate_ui_button_t));
112
113 exstyles = 0;
114 styles = WS_CHILD | WS_CLIPSIBLINGS | WS_TABSTOP | BS_PUSHBUTTON;
115 #if !defined(GATE_SYS_WIN16)
116 styles |= (BS_MULTILINE | BS_VCENTER);
117 #endif
118 /*styles |= BS_FLAT;*/
119 if (!GATE_FLAG_ENABLED(flags, GATE_UI_FLAG_ENABLED)) styles |= WS_DISABLED;
120 if (GATE_FLAG_ENABLED(flags, GATE_UI_FLAG_VISIBLE)) styles |= WS_VISIBLE;
121
122 ret = gate_ui_winapi_create(&button->ctrl, host, (void*)hwndParent,
123 _T("BUTTON"), position, styles, exstyles, caption, userparam, true);
124 if (GATE_SUCCEEDED(ret))
125 {
126 gate_ui_winapi_register_event(host, (void*)hwndParent, WM_COMMAND, &gate_ui_button_events, &button->ctrl);
127 }
128 } while (0);
129
130 return ret;
131 }
132
133 #endif /*GATE_UI_WINAPI*/
134
135
136 #if defined(GATE_UI_GTK)
137
138 #include "gate/ui/gateui_gtk.h"
139
140 static gate_uint32_t gate_ui_gtk_button_get_text_length(gate_ui_ctrl_t* ctrl)
141 {
142 gint char_count = 0;
143 gchar const* ptr_text = NULL;
144 GtkButton* button = GTK_BUTTON(GATE_UI_GTK_GET_CTRL_WIDGET(ctrl));
145 if (button)
146 {
147 ptr_text = gtk_button_get_label(button);
148 if (ptr_text)
149 {
150 char_count = gate_str_length(ptr_text);
151 }
152 }
153 return (gate_uint32_t)char_count;
154 }
155 static gate_result_t gate_ui_gtk_button_get_text(gate_ui_ctrl_t* ctrl, gate_string_t* text)
156 {
157 gate_result_t ret = GATE_RESULT_FAILED;
158 gchar const* ptr_text = NULL;
159 GtkButton* button = GTK_BUTTON(GATE_UI_GTK_GET_CTRL_WIDGET(ctrl));
160 if (button)
161 {
162 ptr_text = gtk_button_get_label(button);
163 if (ptr_text)
164 {
165 if (NULL == gate_string_create(text, ptr_text, gate_str_length(ptr_text)))
166 {
167 ret = GATE_RESULT_OUTOFMEMORY;
168 }
169 else
170 {
171 ret = GATE_RESULT_OK;
172 }
173 }
174 else
175 {
176 gate_string_create_empty(text);
177 ret = GATE_RESULT_OK;
178 }
179 }
180 return ret;
181
182 }
183 static gate_result_t gate_ui_gtk_button_set_text(gate_ui_ctrl_t* ctrl, gate_string_t const* text)
184 {
185 gate_result_t ret = GATE_RESULT_FAILED;
186 gchar label[4096];
187 GtkButton* button = GTK_BUTTON(GATE_UI_GTK_GET_CTRL_WIDGET(ctrl));
188 if (button)
189 {
190 gate_str_print_text(label, sizeof(label), text->str, text->length);
191 gtk_button_set_label(button, label);
192 ret = GATE_RESULT_OK;
193 }
194 return ret;
195 }
196 static gate_result_t gate_ui_gtk_button_get_state(gate_ui_ctrl_t* ctrl, gate_int32_t* value)
197 {
198 return GATE_RESULT_NOTIMPLEMENTED;
199 }
200 static gate_result_t gate_ui_gtk_button_set_state(gate_ui_ctrl_t* ctrl, gate_int32_t value)
201 {
202 return GATE_RESULT_NOTIMPLEMENTED;
203 }
204
205 static gate_ui_gtk_dispatcher_t gate_ui_gtk_button_dispatcher =
206 {
207 gate_ui_gtk_button_get_text_length,
208 gate_ui_gtk_button_get_text,
209 gate_ui_gtk_button_set_text,
210 NULL,
211 NULL,
212 NULL
213 };
214
215
216 static void gate_ui_button_clicked(GtkButton* button, gpointer user_data)
217 {
218 gate_ui_button_t* button_ctrl = (gate_ui_button_t*)user_data;
219 if (button_ctrl)
220 {
221 if (button_ctrl->on_click != NULL)
222 {
223 button_ctrl->on_click(&button_ctrl->ctrl);
224 }
225 }
226 }
227
228
229 gate_result_t gate_ui_button_create(gate_ui_button_t* button, gate_ui_ctrl_t* parent,
230 gate_ui_position_t const* position, gate_string_t const* caption,
231 gate_uint32_t flags, void* userparam)
232 {
233 gate_result_t ret = GATE_RESULT_OK;
234 GtkWidget* widget;
235 gate_ui_host_t* host = GATE_UI_GTK_GET_CTRL_HOST(parent);
236
237 gate_mem_clear(button, sizeof(gate_ui_button_t));
238 widget = gtk_button_new();
239 if (widget == NULL)
240 {
241 return GATE_RESULT_FAILED;
242 }
243
244 ret = gate_ui_gtk_ctrl_init(&button->ctrl, widget, host, userparam, parent,
245 &gate_ui_gtk_button_dispatcher, false, false, position, &flags);
246
247 if (GATE_SUCCEEDED(ret))
248 {
249 if (gate_string_length(caption) > 0)
250 {
251 gate_ui_ctrl_set_text(&button->ctrl, caption);
252 }
253
254 g_signal_connect(G_OBJECT(widget), "clicked", G_CALLBACK(gate_ui_button_clicked), (gpointer)button);
255 }
256
257 return ret;
258 }
259
260
261 #endif /* GATE_UI_GTK */
262
263 #if defined(GATE_UI_MOTIF)
264
265 #include "gate/ui/gateui_motif.h"
266 #include <Xm/PushB.h>
267
268 static void button_pushed(Widget widget, XtPointer client_data, XtPointer call_data)
269 {
270 gate_ui_button_t* ptr_button = (gate_ui_button_t*)client_data;
271 if (!ptr_button || !ptr_button->on_click)
272 {
273 return;
274 }
275 ptr_button->on_click(&ptr_button->ctrl);
276 }
277
278 gate_result_t gate_ui_button_create(gate_ui_button_t* button, gate_ui_ctrl_t* parent,
279 gate_ui_position_t const* position, gate_string_t const* caption,
280 gate_uint32_t flags, void* userparam)
281 {
282 gate_result_t ret = GATE_RESULT_FAILED;
283 Widget w = NULL;
284 Arg args[8];
285 unsigned args_count = 0;
286
287 do
288 {
289 if (!button || !parent)
290 {
291 ret = GATE_RESULT_INVALIDARG;
292 break;
293 }
294
295 XtSetArg(args[args_count], XmNrecomputeSize, 0); ++args_count;
296 XtSetArg(args[args_count], XmNshadowThickness, 1); ++args_count;
297 XtSetArg(args[args_count], XmNhighlightThickness, 1); ++args_count;
298
299 ret = gate_ui_motif_ctrl_create(&button->ctrl, xmPushButtonWidgetClass, userparam, NULL, parent,
300 position, &flags, false, NULL, args, args_count);
301 GATE_BREAK_IF_FAILED(ret);
302
303 w = GATE_UI_MOTIF_GET_CTRL_WIDGET(&button->ctrl);
304 XtAddCallback(w, XmNactivateCallback, &button_pushed, button);
305 ret = gate_ui_motif_widget_set_label(w, caption);
306 } while (0);
307
308 return ret;
309 }
310
311 #endif /* GATE_UI_MOTIF */
312
313
314 #if defined(GATE_UI_WASMHTML)
315
316 #include "gate/ui/gateui_wasmhtml.h"
317
318 static gate_string_t const html_class_button = GATE_STRING_INIT_STATIC("button");
319
320 gate_result_t gate_ui_button_create(gate_ui_button_t* button, gate_ui_ctrl_t* parent,
321 gate_ui_position_t const* position, gate_string_t const* caption,
322 gate_uint32_t flags, void* userparam)
323 {
324 gate_result_t ret = GATE_RESULT_FAILED;
325 gate_ui_host_t* host = gate_ui_ctrl_get_host(parent);
326 gate_uint32_t parent_id = gate_ui_wasm_ctrl_get_container(parent);
327 gate_uint32_t new_id = 0;
328
329 do
330 {
331 gate_ui_wasm_new_ctrl_id(host, &new_id);
332 ret = gate_ui_wasm_ctrl_create(host, new_id, parent_id, &html_class_button, userparam, &button->ctrl);
333 GATE_BREAK_IF_FAILED(ret);
334
335 if (position)
336 {
337 gate_ui_wasm_ctrl_set_position(&button->ctrl, &position->pos, &position->size);
338 }
339 gate_ui_wasm_ctrl_set_text(&button->ctrl, caption);
340 } while (0);
341
342 return ret;
343 }
344
345 #endif /* GATE_UI_WASMHTML */
346
347