source: mainline/uspace/lib/ui/src/promptdialog.c@ 6a0b2cc

ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 6a0b2cc was c0757e1f, checked in by Jiri Svoboda <jiri@…>, 2 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: 8.9 KB
Line 
1/*
2 * Copyright (c) 2021 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 Prompt dialog
34 */
35
36#include <errno.h>
37#include <mem.h>
38#include <stdlib.h>
39#include <ui/entry.h>
40#include <ui/fixed.h>
41#include <ui/label.h>
42#include <ui/promptdialog.h>
43#include <ui/pbutton.h>
44#include <ui/resource.h>
45#include <ui/ui.h>
46#include <ui/window.h>
47#include "../private/promptdialog.h"
48
49static void ui_prompt_dialog_wnd_close(ui_window_t *, void *);
50static void ui_prompt_dialog_wnd_kbd(ui_window_t *, void *, kbd_event_t *);
51
52ui_window_cb_t ui_prompt_dialog_wnd_cb = {
53 .close = ui_prompt_dialog_wnd_close,
54 .kbd = ui_prompt_dialog_wnd_kbd
55};
56
57static void ui_prompt_dialog_bok_clicked(ui_pbutton_t *, void *);
58static void ui_prompt_dialog_bcancel_clicked(ui_pbutton_t *, void *);
59
60ui_pbutton_cb_t ui_prompt_dialog_bok_cb = {
61 .clicked = ui_prompt_dialog_bok_clicked
62};
63
64ui_pbutton_cb_t ui_prompt_dialog_bcancel_cb = {
65 .clicked = ui_prompt_dialog_bcancel_clicked
66};
67
68/** Initialize prompt dialog parameters structure.
69 *
70 * Prompt dialog parameters structure must always be initialized using
71 * this function first.
72 *
73 * @param params Prompt dialog parameters structure
74 */
75void ui_prompt_dialog_params_init(ui_prompt_dialog_params_t *params)
76{
77 memset(params, 0, sizeof(ui_prompt_dialog_params_t));
78 params->itext = "";
79}
80
81/** Create new prompt dialog.
82 *
83 * @param ui User interface
84 * @param params Prompt dialog parameters
85 * @param rdialog Place to store pointer to new dialog
86 * @return EOK on success or an error code
87 */
88errno_t ui_prompt_dialog_create(ui_t *ui, ui_prompt_dialog_params_t *params,
89 ui_prompt_dialog_t **rdialog)
90{
91 errno_t rc;
92 ui_prompt_dialog_t *dialog;
93 ui_window_t *window = NULL;
94 ui_wnd_params_t wparams;
95 ui_fixed_t *fixed = NULL;
96 ui_label_t *label = NULL;
97 ui_entry_t *entry = NULL;
98 ui_pbutton_t *bok = NULL;
99 ui_pbutton_t *bcancel = NULL;
100 gfx_rect_t rect;
101 ui_resource_t *ui_res;
102
103 dialog = calloc(1, sizeof(ui_prompt_dialog_t));
104 if (dialog == NULL) {
105 rc = ENOMEM;
106 goto error;
107 }
108
109 ui_wnd_params_init(&wparams);
110 wparams.caption = params->caption;
111
112 /* FIXME: Auto layout */
113 if (ui_is_textmode(ui)) {
114 wparams.rect.p0.x = 0;
115 wparams.rect.p0.y = 0;
116 wparams.rect.p1.x = 40;
117 wparams.rect.p1.y = 9;
118 } else {
119 wparams.rect.p0.x = 0;
120 wparams.rect.p0.y = 0;
121 wparams.rect.p1.x = 300;
122 wparams.rect.p1.y = 135;
123 }
124
125 rc = ui_window_create(ui, &wparams, &window);
126 if (rc != EOK)
127 goto error;
128
129 ui_window_set_cb(window, &ui_prompt_dialog_wnd_cb, dialog);
130
131 ui_res = ui_window_get_res(window);
132
133 rc = ui_fixed_create(&fixed);
134 if (rc != EOK)
135 goto error;
136
137 rc = ui_label_create(ui_res, params->prompt, &label);
138 if (rc != EOK)
139 goto error;
140
141 /* FIXME: Auto layout */
142 if (ui_is_textmode(ui)) {
143 rect.p0.x = 3;
144 rect.p0.y = 2;
145 rect.p1.x = 17;
146 rect.p1.y = 3;
147 } else {
148 rect.p0.x = 10;
149 rect.p0.y = 35;
150 rect.p1.x = 190;
151 rect.p1.y = 50;
152 }
153
154 ui_label_set_rect(label, &rect);
155
156 rc = ui_fixed_add(fixed, ui_label_ctl(label));
157 if (rc != EOK)
158 goto error;
159
160 label = NULL;
161
162 rc = ui_entry_create(window, params->itext, &entry);
163 if (rc != EOK)
164 goto error;
165
166 /* FIXME: Auto layout */
167 if (ui_is_textmode(ui)) {
168 rect.p0.x = 3;
169 rect.p0.y = 4;
170 rect.p1.x = 37;
171 rect.p1.y = 5;
172 } else {
173 rect.p0.x = 10;
174 rect.p0.y = 55;
175 rect.p1.x = 290;
176 rect.p1.y = 80;
177 }
178
179 ui_entry_set_rect(entry, &rect);
180
181 rc = ui_fixed_add(fixed, ui_entry_ctl(entry));
182 if (rc != EOK)
183 goto error;
184
185 ui_entry_activate(entry);
186
187 /* Select all */
188 ui_entry_seek_start(entry, false);
189 ui_entry_seek_end(entry, true);
190
191 dialog->ename = entry;
192 entry = NULL;
193
194 rc = ui_pbutton_create(ui_res, "OK", &bok);
195 if (rc != EOK)
196 goto error;
197
198 ui_pbutton_set_cb(bok, &ui_prompt_dialog_bok_cb, dialog);
199
200 /* FIXME: Auto layout */
201 if (ui_is_textmode(ui)) {
202 rect.p0.x = 10;
203 rect.p0.y = 6;
204 rect.p1.x = 20;
205 rect.p1.y = 7;
206 } else {
207 rect.p0.x = 55;
208 rect.p0.y = 90;
209 rect.p1.x = 145;
210 rect.p1.y = 118;
211 }
212
213 ui_pbutton_set_rect(bok, &rect);
214
215 ui_pbutton_set_default(bok, true);
216
217 rc = ui_fixed_add(fixed, ui_pbutton_ctl(bok));
218 if (rc != EOK)
219 goto error;
220
221 dialog->bok = bok;
222 bok = NULL;
223
224 rc = ui_pbutton_create(ui_res, "Cancel", &bcancel);
225 if (rc != EOK)
226 goto error;
227
228 ui_pbutton_set_cb(bcancel, &ui_prompt_dialog_bcancel_cb, dialog);
229
230 /* FIXME: Auto layout */
231 if (ui_is_textmode(ui)) {
232 rect.p0.x = 22;
233 rect.p0.y = 6;
234 rect.p1.x = 32;
235 rect.p1.y = 7;
236 } else {
237 rect.p0.x = 155;
238 rect.p0.y = 90;
239 rect.p1.x = 245;
240 rect.p1.y = 118;
241 }
242
243 ui_pbutton_set_rect(bcancel, &rect);
244
245 rc = ui_fixed_add(fixed, ui_pbutton_ctl(bcancel));
246 if (rc != EOK)
247 goto error;
248
249 dialog->bcancel = bcancel;
250 bcancel = NULL;
251
252 ui_window_add(window, ui_fixed_ctl(fixed));
253 fixed = NULL;
254
255 rc = ui_window_paint(window);
256 if (rc != EOK)
257 goto error;
258
259 dialog->window = window;
260 *rdialog = dialog;
261 return EOK;
262error:
263 if (entry != NULL)
264 ui_entry_destroy(entry);
265 if (bok != NULL)
266 ui_pbutton_destroy(bok);
267 if (bcancel != NULL)
268 ui_pbutton_destroy(bcancel);
269 if (label != NULL)
270 ui_label_destroy(label);
271 if (fixed != NULL)
272 ui_fixed_destroy(fixed);
273 if (window != NULL)
274 ui_window_destroy(window);
275 if (dialog != NULL)
276 free(dialog);
277 return rc;
278}
279
280/** Destroy prompt dialog.
281 *
282 * @param dialog Prompt dialog or @c NULL
283 */
284void ui_prompt_dialog_destroy(ui_prompt_dialog_t *dialog)
285{
286 if (dialog == NULL)
287 return;
288
289 ui_window_destroy(dialog->window);
290 free(dialog);
291}
292
293/** Set mesage dialog callback.
294 *
295 * @param dialog Prompt dialog
296 * @param cb Prompt dialog callbacks
297 * @param arg Callback argument
298 */
299void ui_prompt_dialog_set_cb(ui_prompt_dialog_t *dialog, ui_prompt_dialog_cb_t *cb,
300 void *arg)
301{
302 dialog->cb = cb;
303 dialog->arg = arg;
304}
305
306/** Prompt dialog window close handler.
307 *
308 * @param window Window
309 * @param arg Argument (ui_prompt_dialog_t *)
310 */
311static void ui_prompt_dialog_wnd_close(ui_window_t *window, void *arg)
312{
313 ui_prompt_dialog_t *dialog = (ui_prompt_dialog_t *) arg;
314
315 if (dialog->cb != NULL && dialog->cb->close != NULL)
316 dialog->cb->close(dialog, dialog->arg);
317}
318
319/** Prompt dialog window keyboard event handler.
320 *
321 * @param window Window
322 * @param arg Argument (ui_prompt_dialog_t *)
323 * @param event Keyboard event
324 */
325static void ui_prompt_dialog_wnd_kbd(ui_window_t *window, void *arg,
326 kbd_event_t *event)
327{
328 ui_prompt_dialog_t *dialog = (ui_prompt_dialog_t *) arg;
329 const char *text;
330
331 if (event->type == KEY_PRESS &&
332 (event->mods & (KM_CTRL | KM_SHIFT | KM_ALT)) == 0) {
333 if (event->key == KC_ENTER) {
334 /* Confirm */
335 if (dialog->cb != NULL && dialog->cb->bok != NULL) {
336 text = ui_entry_get_text(dialog->ename);
337 dialog->cb->bok(dialog, dialog->arg, text);
338 return;
339 }
340 } else if (event->key == KC_ESCAPE) {
341 /* Cancel */
342 if (dialog->cb != NULL && dialog->cb->bcancel != NULL) {
343 dialog->cb->bcancel(dialog, dialog->arg);
344 return;
345 }
346 }
347 }
348
349 ui_window_def_kbd(window, event);
350}
351
352/** Prompt dialog OK button click handler.
353 *
354 * @param pbutton Push button
355 * @param arg Argument (ui_prompt_dialog_t *)
356 */
357static void ui_prompt_dialog_bok_clicked(ui_pbutton_t *pbutton, void *arg)
358{
359 ui_prompt_dialog_t *dialog = (ui_prompt_dialog_t *) arg;
360 const char *text;
361
362 if (dialog->cb != NULL && dialog->cb->bok != NULL) {
363 text = ui_entry_get_text(dialog->ename);
364 dialog->cb->bok(dialog, dialog->arg, text);
365 }
366}
367
368/** Prompt dialog cancel button click handler.
369 *
370 * @param pbutton Push button
371 * @param arg Argument (ui_prompt_dialog_t *)
372 */
373static void ui_prompt_dialog_bcancel_clicked(ui_pbutton_t *pbutton, void *arg)
374{
375 ui_prompt_dialog_t *dialog = (ui_prompt_dialog_t *) arg;
376
377 if (dialog->cb != NULL && dialog->cb->bcancel != NULL)
378 dialog->cb->bcancel(dialog, dialog->arg);
379}
380
381/** @}
382 */
Note: See TracBrowser for help on using the repository browser.