|
1 /* |
|
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. |
|
3 * |
|
4 * Copyright 2023 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 <Windows.h> |
|
30 |
|
31 #include <stdio.h> |
|
32 #include <stdlib.h> |
|
33 #include <stdbool.h> |
|
34 |
|
35 #include <ui/ui.h> |
|
36 |
|
37 typedef struct WindowData { |
|
38 UiInteger* check; |
|
39 UiInteger* toggle; |
|
40 UiInteger* radio; |
|
41 UiString* text; |
|
42 UiString* password; |
|
43 UiList* list; |
|
44 UiString* t1; |
|
45 UiString* t2; |
|
46 UiString* t3; |
|
47 UiString* path; |
|
48 UiList* list2; |
|
49 UiList* list3; |
|
50 UiDouble* progress; |
|
51 UiInteger* spinner; |
|
52 } WindowData; |
|
53 |
|
54 static UiIcon* folder_icon; |
|
55 |
|
56 void action1(UiEvent* event, void* data) { |
|
57 char* action = data; |
|
58 |
|
59 WindowData* wdata = event->window; |
|
60 int64_t is_checked = wdata->check->get(wdata->check); |
|
61 int64_t radio = wdata->radio->get(wdata->radio); |
|
62 |
|
63 printf("data: %s %d\n", data, is_checked); |
|
64 |
|
65 double d = wdata->progress->get(wdata->progress); |
|
66 wdata->progress->set(wdata->progress, d + 1); |
|
67 |
|
68 int spinner_active = wdata->spinner->get(wdata->spinner); |
|
69 wdata->spinner->set(wdata->spinner, !spinner_active); |
|
70 } |
|
71 |
|
72 void action_set_checkbox(UiEvent* event, void* data) { |
|
73 char* action = data; |
|
74 |
|
75 WindowData* wdata = event->window; |
|
76 wdata->check->set(wdata->check, 1); |
|
77 } |
|
78 |
|
79 void action_onchange(UiEvent* event, void* data) { |
|
80 printf("onchange: %d\n", event->intval); |
|
81 } |
|
82 |
|
83 void action_switch(UiEvent* event, void* data) { |
|
84 printf("onchange: %d\n", event->intval); |
|
85 } |
|
86 |
|
87 void action_toolbar_button(UiEvent* event, void *data) { |
|
88 printf("toolbar action\n"); |
|
89 } |
|
90 |
|
91 |
|
92 void action_listselection_changed(UiEvent* event, void* data) { |
|
93 printf("selection changed\n"); |
|
94 UiListSelection* sel = event->eventdata; |
|
95 for (int i = 0; i < sel->count; i++) { |
|
96 int row = sel->rows[i]; |
|
97 printf("row: %d\n", row); |
|
98 } |
|
99 } |
|
100 |
|
101 void action_onactivate(UiEvent* event, void* Data) { |
|
102 printf("activate\n"); |
|
103 UiListSelection* sel = event->eventdata; |
|
104 for (int i = 0; i < sel->count; i++) { |
|
105 int row = sel->rows[i]; |
|
106 printf("row: %d\n", row); |
|
107 } |
|
108 } |
|
109 |
|
110 typedef struct TableData { |
|
111 char* col1; |
|
112 char* col2; |
|
113 char* col3; |
|
114 } TableData; |
|
115 |
|
116 void* table_getvalue(void* data, int i) { |
|
117 TableData* t = data; |
|
118 switch (i) { |
|
119 case 0: return folder_icon; |
|
120 case 1: return t->col1; |
|
121 case 2: return t->col2; |
|
122 case 3: return t->col3; |
|
123 } |
|
124 return NULL; |
|
125 } |
|
126 |
|
127 void action_add(UiEvent* event, void* data) { |
|
128 WindowData* wdata = event->window; |
|
129 char* t1 = wdata->t1->get(wdata->t1); |
|
130 char* t2 = wdata->t2->get(wdata->t2); |
|
131 char* t3 = wdata->t3->get(wdata->t3); |
|
132 |
|
133 TableData* tdat = malloc(sizeof(TableData)); |
|
134 tdat->col1 = _strdup(t1); |
|
135 tdat->col2 = _strdup(t2); |
|
136 tdat->col3 = _strdup(t3); |
|
137 ui_list_append(wdata->list2, tdat); |
|
138 wdata->list2->update(wdata->list2, 0); |
|
139 |
|
140 } |
|
141 |
|
142 void action_breadcrumb(UiEvent* event, void* data) { |
|
143 int i = event->intval; |
|
144 char* c = event->eventdata; |
|
145 printf("index: %d\n", i); |
|
146 } |
|
147 |
|
148 void dragstart(UiEvent* event, void* data) { |
|
149 UiListDnd* ldnd = event->eventdata; |
|
150 ui_selection_settext(ldnd->dnd, "Hello World!", -1); |
|
151 } |
|
152 |
|
153 void dragcomplete(UiEvent* event, void* data) { |
|
154 |
|
155 } |
|
156 |
|
157 void dragover(UiEvent* event, void* data) { |
|
158 |
|
159 } |
|
160 |
|
161 void drop(UiEvent* event, void* data) { |
|
162 |
|
163 } |
|
164 |
|
165 void application_startup(UiEvent* event, void* data) { |
|
166 UiObject* obj = ui_window("Test", NULL); |
|
167 WindowData* wdata = ui_malloc(obj->ctx, sizeof(WindowData)); |
|
168 obj->window = wdata; |
|
169 wdata->check = ui_int_new(obj->ctx, "check"); |
|
170 wdata->toggle = ui_int_new(obj->ctx, "toggle"); |
|
171 wdata->radio = ui_int_new(obj->ctx, "radio"); |
|
172 wdata->text = ui_string_new(obj->ctx, "text"); |
|
173 wdata->password = ui_string_new(obj->ctx, "password"); |
|
174 wdata->list = ui_list_new(obj->ctx, "list"); |
|
175 wdata->list2 = ui_list_new(obj->ctx, "list2"); |
|
176 wdata->list3 = ui_list_new(obj->ctx, "list3"); |
|
177 wdata->t1 = ui_string_new(obj->ctx, "t1"); |
|
178 wdata->t2 = ui_string_new(obj->ctx, "t2"); |
|
179 wdata->t3 = ui_string_new(obj->ctx, "t3"); |
|
180 wdata->path = ui_string_new(obj->ctx, "path"); |
|
181 wdata->progress = ui_double_new(obj->ctx, "progress"); |
|
182 wdata->spinner = ui_int_new(obj->ctx, "spinner"); |
|
183 |
|
184 ui_list_append(wdata->list, "Hello"); |
|
185 ui_list_append(wdata->list, "World"); |
|
186 ui_list_append(wdata->list, "Item3"); |
|
187 ui_list_append(wdata->list, "Item4"); |
|
188 ui_list_append(wdata->list, "Item5"); |
|
189 ui_list_append(wdata->list, "Item6"); |
|
190 |
|
191 ui_list_append(wdata->list3, "usr"); |
|
192 ui_list_append(wdata->list3, "share"); |
|
193 ui_list_append(wdata->list3, "test"); |
|
194 ui_list_append(wdata->list3, "dir"); |
|
195 |
|
196 //folder_icon = ui_icon("Folder", 32); |
|
197 folder_icon = ui_foldericon(16); |
|
198 |
|
199 TableData* td1 = malloc(sizeof(TableData)); |
|
200 TableData* td2 = malloc(sizeof(TableData)); |
|
201 TableData* td3 = malloc(sizeof(TableData)); |
|
202 TableData* td4 = malloc(sizeof(TableData)); |
|
203 TableData* td5 = malloc(sizeof(TableData)); |
|
204 TableData* td6 = malloc(sizeof(TableData)); |
|
205 td1->col1 = "a1"; |
|
206 td1->col2 = "b1"; |
|
207 td1->col3 = "c1"; |
|
208 td2->col1 = "a2"; |
|
209 td2->col2 = "b2"; |
|
210 td2->col3 = "b3"; |
|
211 td3->col1 = "a3"; |
|
212 td3->col2 = "b3"; |
|
213 td3->col3 = "c3"; |
|
214 td4->col1 = "a3"; |
|
215 td4->col2 = "b3"; |
|
216 td4->col3 = "c3"; |
|
217 td5->col1 = "a3"; |
|
218 td5->col2 = "b3"; |
|
219 td5->col3 = "c3"; |
|
220 td6->col1 = "a3"; |
|
221 td6->col2 = "b3"; |
|
222 td6->col3 = "c3"; |
|
223 |
|
224 ui_list_append(wdata->list2, td1); |
|
225 ui_list_append(wdata->list2, td2); |
|
226 ui_list_append(wdata->list2, td3); |
|
227 ui_list_append(wdata->list2, td4); |
|
228 ui_list_append(wdata->list2, td5); |
|
229 ui_list_append(wdata->list2, td6); |
|
230 |
|
231 ui_scrolledwindow0(obj) { |
|
232 ui_grid(obj, .margin = 10, .columnspacing = 5, .rowspacing = 20) { |
|
233 ui_button(obj, .label = "Button1", .onclick = action1, .onclickdata = "action1"); |
|
234 ui_button(obj, .label = "Button2", .onclick = action1, .onclickdata = "action2"); |
|
235 ui_button(obj, .label = "Button3", .onclick = action1, .onclickdata = "action3", .hexpand = true); |
|
236 ui_newline(obj); |
|
237 |
|
238 ui_button(obj, .label = "Button4", .onclick = action1, .onclickdata = "action4"); |
|
239 ui_button(obj, .label = "Button5", .onclick = action1, .onclickdata = "action5", .colspan = 2); |
|
240 ui_newline(obj); |
|
241 |
|
242 ui_button(obj, .label = "Very Long Button Label Text ____________ Test", .onclick = action_set_checkbox); |
|
243 ui_newline(obj); |
|
244 |
|
245 ui_checkbox(obj, .label = "Option 1", .value = wdata->check, .onchange = action_onchange); |
|
246 ui_togglebutton(obj, .label = "Option 2", .value = wdata->toggle); |
|
247 ui_newline(obj); |
|
248 |
|
249 ui_label(obj, .label = "Progress"); |
|
250 ui_progressspinner(obj, .value = wdata->spinner); |
|
251 ui_newline(obj); |
|
252 |
|
253 ui_hbox(obj, .colspan = 3) { |
|
254 ui_radiobutton(obj, .label = "Radio 1", .value = wdata->radio); |
|
255 ui_radiobutton(obj, .label = "Radio 2", .value = wdata->radio); |
|
256 ui_radiobutton(obj, .label = "Radio 3", .value = wdata->radio); |
|
257 } |
|
258 ui_newline(obj); |
|
259 ui_radiobutton(obj, .label = "Radio 4", .value = wdata->radio); |
|
260 ui_switch(obj, .label = "test", .onchange = action_switch); |
|
261 ui_newline(obj); |
|
262 |
|
263 //ui_breadcrumbbar(obj, .list = wdata->list3, .onactivate=action_breadcrumb); |
|
264 ui_textfield(obj, .varname = "newtext"); |
|
265 ui_path_textfield(obj, .colspan = 2, .value=wdata->path, .onactivate = action_breadcrumb); |
|
266 ui_newline(obj); |
|
267 wdata->path->set(wdata->path, "/usr/path/test"); |
|
268 |
|
269 ui_textfield(obj, .value = wdata->text); |
|
270 ui_passwordfield(obj, .value = wdata->password); |
|
271 ui_newline(obj); |
|
272 |
|
273 ui_frame(obj, .label = "Test", .colspan = 3) { |
|
274 ui_button(obj, .label = "Button1", .onclick = action1, .onclickdata = "action1"); |
|
275 } |
|
276 ui_newline(obj); |
|
277 |
|
278 ui_expander(obj, .label = "Expand", .colspan = 3, .margin = 10, .spacing = 5, .isexpanded = false) { |
|
279 ui_button(obj, .label = "Button1", .onclick = action1, .onclickdata = "action1"); |
|
280 ui_button(obj, .label = "Button1", .onclick = action1, .onclickdata = "action1"); |
|
281 ui_button(obj, .label = "Button1", .onclick = action1, .onclickdata = "action1"); |
|
282 } |
|
283 ui_newline(obj); |
|
284 |
|
285 ui_combobox(obj, .list = wdata->list, .onselection= action_listselection_changed, .onactivate= action_onactivate); |
|
286 ui_newline(obj); |
|
287 |
|
288 ui_tabview(obj, .colspan = 3, .vexpand = true, .hexpand = true, .tabview = UI_TABVIEW_NAVIGATION_SIDE) { |
|
289 ui_tab(obj, "Tab 1") { |
|
290 ui_button(obj, .label = "Tab 1 Button"); |
|
291 } |
|
292 ui_tab(obj, "Tab 2") { |
|
293 ui_button(obj, .label = "Tab 2 Button"); |
|
294 } |
|
295 ui_tab(obj, "Tab 3") { |
|
296 |
|
297 } |
|
298 } |
|
299 ui_newline(obj); |
|
300 |
|
301 ui_label(obj, .label = "Test Label"); |
|
302 ui_progressbar(obj, .value = wdata->progress, .colspan = 2); |
|
303 ui_newline(obj); |
|
304 |
|
305 ui_newline(obj); |
|
306 ui_textfield(obj, .value = wdata->t1); |
|
307 ui_textfield(obj, .value = wdata->t2); |
|
308 ui_textfield(obj, .value = wdata->t3); |
|
309 ui_newline(obj); |
|
310 ui_button(obj, .label = "Add", .onclick = action_add); |
|
311 ui_newline(obj); |
|
312 |
|
313 |
|
314 ui_newline(obj); |
|
315 |
|
316 UiModel* model = ui_model(obj->ctx, UI_ICON_TEXT, "Col 1", UI_STRING, "Col 2", UI_STRING, "Col 3", -1); |
|
317 model->getvalue = table_getvalue; |
|
318 ui_table(obj, .colspan = 3, .model = model, .list = wdata->list2, .onactivate = action_onactivate, |
|
319 .onselection = action_listselection_changed, |
|
320 .ondragstart = dragstart, .ondragcomplete = dragcomplete, .ondrop = drop); |
|
321 ui_model_free(obj->ctx, model); |
|
322 } |
|
323 } |
|
324 |
|
325 ui_show(obj); |
|
326 } |
|
327 |
|
328 |
|
329 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR lpCmdLine, int nCmdShow) |
|
330 { |
|
331 ui_init("app1", 0, NULL); |
|
332 ui_onstartup(application_startup, NULL); |
|
333 |
|
334 ui_menu("File") { |
|
335 ui_menuitem(.label = "Item 1"); |
|
336 ui_menuitem(.label = "Item 2"); |
|
337 ui_menuseparator(); |
|
338 ui_menu("File Sub") { |
|
339 ui_menuitem(.label = "Sub Item"); |
|
340 } |
|
341 |
|
342 ui_menuitem(.label = "Exit"); |
|
343 } |
|
344 |
|
345 ui_toolbar_item("Test", .label = "Home", .icon = "Home", .onclick = action_toolbar_button); |
|
346 ui_toolbar_toggleitem("Toggle", .label = "Toggle", .onchange = action_toolbar_button); |
|
347 ui_toolbar_toggleitem("Toggle2", .label = "Toggle2", .onchange = action_toolbar_button); |
|
348 ui_toolbar_toggleitem("Toggle3", .label = "Toggle3", .onchange = action_toolbar_button); |
|
349 |
|
350 ui_toolbar_menu("Menu", .label = "Menu") { |
|
351 |
|
352 ui_menuitem(.label = "x", NULL, NULL); |
|
353 ui_menuitem(.label = "x", NULL, NULL); |
|
354 ui_menuitem(.label = "x", NULL, NULL); |
|
355 ui_menuitem(.label = "x", NULL, NULL); |
|
356 ui_menuitem(.label = "x", NULL, NULL); |
|
357 ui_menu("TB Sub") { |
|
358 ui_menuitem("TB subitem", NULL, NULL); |
|
359 } |
|
360 } |
|
361 |
|
362 ui_toolbar_menu(NULL, .label = "Menu") { |
|
363 ui_menuitem("Secondary Test", NULL, NULL); |
|
364 ui_menu("Secondary Sub") { |
|
365 ui_menuitem("Secondary subitem", NULL, NULL); |
|
366 } |
|
367 } |
|
368 |
|
369 ui_toolbar_add_default("Test", UI_TOOLBAR_LEFT); |
|
370 ui_toolbar_add_default("Toggle", UI_TOOLBAR_LEFT); |
|
371 ui_toolbar_add_default("Toggle2", UI_TOOLBAR_CENTER); |
|
372 ui_toolbar_add_default("Toggle3", UI_TOOLBAR_CENTER); |
|
373 ui_toolbar_add_default("Menu", UI_TOOLBAR_RIGHT); |
|
374 |
|
375 ui_main(); |
|
376 |
|
377 return (EXIT_SUCCESS); |
|
378 } |