source: mainline/uspace/lib/ui/src/selectdialog.c@ aace43d8

ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since aace43d8 was c0757e1f, checked in by Jiri Svoboda <jiri@…>, 3 years ago

UI display configuration utility

In addition to the command-line utility 'disp', we introduce its UI
equivalent 'display-cfg'. Currently this allows the user to configure
seats in a very comfortable way.

  • Property mode set to 100644
File size: 10.1 KB
RevLine 
[c0757e1f]1/*
2 * Copyright (c) 2023 Jiri Svoboda
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - 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 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup libui
30 * @{
31 */
32/**
33 * @file Select dialog
34 */
35
36#include <errno.h>
37#include <mem.h>
38#include <stdlib.h>
39#include <ui/fixed.h>
40#include <ui/label.h>
41#include <ui/list.h>
42#include <ui/selectdialog.h>
43#include <ui/pbutton.h>
44#include <ui/resource.h>
45#include <ui/ui.h>
46#include <ui/window.h>
47#include "../private/selectdialog.h"
48
49static void ui_select_dialog_wnd_close(ui_window_t *, void *);
50static void ui_select_dialog_wnd_kbd(ui_window_t *, void *, kbd_event_t *);
51
52ui_window_cb_t ui_select_dialog_wnd_cb = {
53 .close = ui_select_dialog_wnd_close,
54 .kbd = ui_select_dialog_wnd_kbd
55};
56
57static void ui_select_dialog_bok_clicked(ui_pbutton_t *, void *);
58static void ui_select_dialog_bcancel_clicked(ui_pbutton_t *, void *);
59
60ui_pbutton_cb_t ui_select_dialog_bok_cb = {
61 .clicked = ui_select_dialog_bok_clicked
62};
63
64ui_pbutton_cb_t ui_select_dialog_bcancel_cb = {
65 .clicked = ui_select_dialog_bcancel_clicked
66};
67
68static void ui_select_dialog_list_selected(ui_list_entry_t *, void *);
69
70ui_list_cb_t ui_select_dialog_list_cb = {
71 .selected = ui_select_dialog_list_selected
72};
73
74/** Initialize select dialog parameters structure.
75 *
76 * Select dialog parameters structure must always be initialized using
77 * this function first.
78 *
79 * @param params Select dialog parameters structure
80 */
81void ui_select_dialog_params_init(ui_select_dialog_params_t *params)
82{
83 memset(params, 0, sizeof(ui_select_dialog_params_t));
84}
85
86/** Create new select dialog.
87 *
88 * @param ui User interface
89 * @param params Select dialog parameters
90 * @param rdialog Place to store pointer to new dialog
91 * @return EOK on success or an error code
92 */
93errno_t ui_select_dialog_create(ui_t *ui, ui_select_dialog_params_t *params,
94 ui_select_dialog_t **rdialog)
95{
96 errno_t rc;
97 ui_select_dialog_t *dialog;
98 ui_window_t *window = NULL;
99 ui_wnd_params_t wparams;
100 ui_fixed_t *fixed = NULL;
101 ui_label_t *label = NULL;
102 ui_list_t *list = NULL;
103 ui_pbutton_t *bok = NULL;
104 ui_pbutton_t *bcancel = NULL;
105 gfx_rect_t rect;
106 ui_resource_t *ui_res;
107
108 dialog = calloc(1, sizeof(ui_select_dialog_t));
109 if (dialog == NULL) {
110 rc = ENOMEM;
111 goto error;
112 }
113
114 ui_wnd_params_init(&wparams);
115 wparams.caption = params->caption;
116
117 /* FIXME: Auto layout */
118 if (ui_is_textmode(ui)) {
119 wparams.rect.p0.x = 0;
120 wparams.rect.p0.y = 0;
121 wparams.rect.p1.x = 40;
122 wparams.rect.p1.y = 19;
123 } else {
124 wparams.rect.p0.x = 0;
125 wparams.rect.p0.y = 0;
126 wparams.rect.p1.x = 300;
127 wparams.rect.p1.y = 235;
128 }
129
130 rc = ui_window_create(ui, &wparams, &window);
131 if (rc != EOK)
132 goto error;
133
134 ui_window_set_cb(window, &ui_select_dialog_wnd_cb, dialog);
135
136 ui_res = ui_window_get_res(window);
137
138 rc = ui_fixed_create(&fixed);
139 if (rc != EOK)
140 goto error;
141
142 rc = ui_label_create(ui_res, params->prompt, &label);
143 if (rc != EOK)
144 goto error;
145
146 /* FIXME: Auto layout */
147 if (ui_is_textmode(ui)) {
148 rect.p0.x = 3;
149 rect.p0.y = 2;
150 rect.p1.x = 17;
151 rect.p1.y = 3;
152 } else {
153 rect.p0.x = 10;
154 rect.p0.y = 35;
155 rect.p1.x = 190;
156 rect.p1.y = 50;
157 }
158
159 ui_label_set_rect(label, &rect);
160
161 rc = ui_fixed_add(fixed, ui_label_ctl(label));
162 if (rc != EOK)
163 goto error;
164
165 label = NULL;
166
167 rc = ui_list_create(window, true, &list);
168 if (rc != EOK)
169 goto error;
170
171 ui_list_set_cb(list, &ui_select_dialog_list_cb, dialog);
172
173 /* FIXME: Auto layout */
174 if (ui_is_textmode(ui)) {
175 rect.p0.x = 3;
176 rect.p0.y = 4;
177 rect.p1.x = 37;
178 rect.p1.y = 15;
179 } else {
180 rect.p0.x = 10;
181 rect.p0.y = 55;
182 rect.p1.x = 290;
183 rect.p1.y = 180;
184 }
185
186 ui_list_set_rect(list, &rect);
187
188 rc = ui_fixed_add(fixed, ui_list_ctl(list));
189 if (rc != EOK)
190 goto error;
191
192 dialog->list = list;
193 list = NULL;
194
195 rc = ui_pbutton_create(ui_res, "OK", &bok);
196 if (rc != EOK)
197 goto error;
198
199 ui_pbutton_set_cb(bok, &ui_select_dialog_bok_cb, dialog);
200
201 /* FIXME: Auto layout */
202 if (ui_is_textmode(ui)) {
203 rect.p0.x = 10;
204 rect.p0.y = 16;
205 rect.p1.x = 20;
206 rect.p1.y = 17;
207 } else {
208 rect.p0.x = 55;
209 rect.p0.y = 190;
210 rect.p1.x = 145;
211 rect.p1.y = 218;
212 }
213
214 ui_pbutton_set_rect(bok, &rect);
215
216 ui_pbutton_set_default(bok, true);
217
218 rc = ui_fixed_add(fixed, ui_pbutton_ctl(bok));
219 if (rc != EOK)
220 goto error;
221
222 dialog->bok = bok;
223 bok = NULL;
224
225 rc = ui_pbutton_create(ui_res, "Cancel", &bcancel);
226 if (rc != EOK)
227 goto error;
228
229 ui_pbutton_set_cb(bcancel, &ui_select_dialog_bcancel_cb, dialog);
230
231 /* FIXME: Auto layout */
232 if (ui_is_textmode(ui)) {
233 rect.p0.x = 22;
234 rect.p0.y = 16;
235 rect.p1.x = 32;
236 rect.p1.y = 17;
237 } else {
238 rect.p0.x = 155;
239 rect.p0.y = 190;
240 rect.p1.x = 245;
241 rect.p1.y = 218;
242 }
243
244 ui_pbutton_set_rect(bcancel, &rect);
245
246 rc = ui_fixed_add(fixed, ui_pbutton_ctl(bcancel));
247 if (rc != EOK)
248 goto error;
249
250 dialog->bcancel = bcancel;
251 bcancel = NULL;
252
253 ui_window_add(window, ui_fixed_ctl(fixed));
254 fixed = NULL;
255
256 rc = ui_window_paint(window);
257 if (rc != EOK)
258 goto error;
259
260 dialog->window = window;
261 *rdialog = dialog;
262 return EOK;
263error:
264 if (list != NULL)
265 ui_list_destroy(list);
266 if (bok != NULL)
267 ui_pbutton_destroy(bok);
268 if (bcancel != NULL)
269 ui_pbutton_destroy(bcancel);
270 if (label != NULL)
271 ui_label_destroy(label);
272 if (fixed != NULL)
273 ui_fixed_destroy(fixed);
274 if (window != NULL)
275 ui_window_destroy(window);
276 if (dialog != NULL)
277 free(dialog);
278 return rc;
279}
280
281/** Destroy select dialog.
282 *
283 * @param dialog Select dialog or @c NULL
284 */
285void ui_select_dialog_destroy(ui_select_dialog_t *dialog)
286{
287 if (dialog == NULL)
288 return;
289
290 ui_window_destroy(dialog->window);
291 free(dialog);
292}
293
294/** Set mesage dialog callback.
295 *
296 * @param dialog Select dialog
297 * @param cb Select dialog callbacks
298 * @param arg Callback argument
299 */
300void ui_select_dialog_set_cb(ui_select_dialog_t *dialog, ui_select_dialog_cb_t *cb,
301 void *arg)
302{
303 dialog->cb = cb;
304 dialog->arg = arg;
305}
306
307/** Append new entry to select dialog.
308 *
309 * @param dialog Select dialog
310 * @param attr List entry attributes
311 * @return EOK on success or an error code
312 */
313errno_t ui_select_dialog_append(ui_select_dialog_t *dialog,
314 ui_list_entry_attr_t *attr)
315{
316 return ui_list_entry_append(dialog->list, attr, NULL);
317}
318
319/** Paint select dialog.
320 *
321 * This needs to be called after appending entries.
322 *
323 * @param dialog Select dialog
324 * @return EOK on success or an error code
325 */
326errno_t ui_select_dialog_paint(ui_select_dialog_t *dialog)
327{
328 return ui_window_paint(dialog->window);
329}
330
331/** Select dialog window close handler.
332 *
333 * @param window Window
334 * @param arg Argument (ui_select_dialog_t *)
335 */
336static void ui_select_dialog_wnd_close(ui_window_t *window, void *arg)
337{
338 ui_select_dialog_t *dialog = (ui_select_dialog_t *) arg;
339
340 if (dialog->cb != NULL && dialog->cb->close != NULL)
341 dialog->cb->close(dialog, dialog->arg);
342}
343
344/** Select dialog window keyboard event handler.
345 *
346 * @param window Window
347 * @param arg Argument (ui_select_dialog_t *)
348 * @param event Keyboard event
349 */
350static void ui_select_dialog_wnd_kbd(ui_window_t *window, void *arg,
351 kbd_event_t *event)
352{
353 ui_select_dialog_t *dialog = (ui_select_dialog_t *) arg;
354 ui_list_entry_t *entry;
355 void *earg;
356
357 if (event->type == KEY_PRESS &&
358 (event->mods & (KM_CTRL | KM_SHIFT | KM_ALT)) == 0) {
359 if (event->key == KC_ENTER) {
360 /* Confirm */
361 if (dialog->cb != NULL && dialog->cb->bok != NULL) {
362 entry = ui_list_get_cursor(dialog->list);
363 earg = ui_list_entry_get_arg(entry);
364 dialog->cb->bok(dialog, dialog->arg, earg);
365 return;
366 }
367 } else if (event->key == KC_ESCAPE) {
368 /* Cancel */
369 if (dialog->cb != NULL && dialog->cb->bcancel != NULL) {
370 dialog->cb->bcancel(dialog, dialog->arg);
371 return;
372 }
373 }
374 }
375
376 ui_window_def_kbd(window, event);
377}
378
379/** Select dialog OK button click handler.
380 *
381 * @param pbutton Push button
382 * @param arg Argument (ui_select_dialog_t *)
383 */
384static void ui_select_dialog_bok_clicked(ui_pbutton_t *pbutton, void *arg)
385{
386 ui_select_dialog_t *dialog = (ui_select_dialog_t *) arg;
387 ui_list_entry_t *entry;
388 void *earg;
389
390 if (dialog->cb != NULL && dialog->cb->bok != NULL) {
391 entry = ui_list_get_cursor(dialog->list);
392 if (entry != NULL)
393 earg = ui_list_entry_get_arg(entry);
394 else
395 earg = NULL;
396
397 dialog->cb->bok(dialog, dialog->arg, earg);
398 }
399}
400
401/** Select dialog cancel button click handler.
402 *
403 * @param pbutton Push button
404 * @param arg Argument (ui_select_dialog_t *)
405 */
406static void ui_select_dialog_bcancel_clicked(ui_pbutton_t *pbutton, void *arg)
407{
408 ui_select_dialog_t *dialog = (ui_select_dialog_t *) arg;
409
410 if (dialog->cb != NULL && dialog->cb->bcancel != NULL)
411 dialog->cb->bcancel(dialog, dialog->arg);
412}
413
414/** Select dialog list entry selection handler.
415 *
416 * @param entry UI list entry
417 * @param arg Entry argument
418 */
419static void ui_select_dialog_list_selected(ui_list_entry_t *entry, void *arg)
420{
421 ui_list_t *list;
422 ui_select_dialog_t *dialog;
423
424 list = ui_list_entry_get_list(entry);
425 dialog = (ui_select_dialog_t *)ui_list_get_cb_arg(list);
426
427 if (dialog->cb != NULL && dialog->cb->bok != NULL)
428 dialog->cb->bok(dialog, dialog->arg, arg);
429}
430
431/** @}
432 */
Note: See TracBrowser for help on using the repository browser.