source: mainline/uspace/lib/ui/src/filedialog.c@ d7f7a4a

Last change on this file since d7f7a4a was d7f7a4a, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 4 years ago

Replace some license headers with SPDX identifier

Headers are replaced using tools/transorm-copyright.sh only
when it can be matched verbatim with the license header used
throughout most of the codebase.

  • Property mode set to 100644
File size: 9.4 KB
Line 
1/*
2 * SPDX-FileCopyrightText: 2022 Jiri Svoboda
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7/** @addtogroup libui
8 * @{
9 */
10/**
11 * @file File dialog
12 */
13
14#include <errno.h>
15#include <mem.h>
16#include <stdlib.h>
17#include <ui/entry.h>
18#include <ui/fixed.h>
19#include <ui/label.h>
20#include <ui/filedialog.h>
21#include <ui/filelist.h>
22#include <ui/pbutton.h>
23#include <ui/resource.h>
24#include <ui/ui.h>
25#include <ui/window.h>
26#include "../private/filedialog.h"
27
28static void ui_file_dialog_wnd_close(ui_window_t *, void *);
29static void ui_file_dialog_wnd_kbd(ui_window_t *, void *, kbd_event_t *);
30
31ui_window_cb_t ui_file_dialog_wnd_cb = {
32 .close = ui_file_dialog_wnd_close,
33 .kbd = ui_file_dialog_wnd_kbd
34};
35
36static void ui_file_dialog_flist_activate_req(ui_file_list_t *, void *);
37static void ui_file_dialog_flist_selected(ui_file_list_t *, void *,
38 const char *);
39
40ui_file_list_cb_t ui_file_dialog_flist_cb = {
41 .activate_req = ui_file_dialog_flist_activate_req,
42 .selected = ui_file_dialog_flist_selected
43};
44
45static void ui_file_dialog_bok_clicked(ui_pbutton_t *, void *);
46static void ui_file_dialog_bcancel_clicked(ui_pbutton_t *, void *);
47
48ui_pbutton_cb_t ui_file_dialog_bok_cb = {
49 .clicked = ui_file_dialog_bok_clicked
50};
51
52ui_pbutton_cb_t ui_file_dialog_bcancel_cb = {
53 .clicked = ui_file_dialog_bcancel_clicked
54};
55
56/** Initialize file dialog parameters structure.
57 *
58 * File dialog parameters structure must always be initialized using
59 * this function first.
60 *
61 * @param params File dialog parameters structure
62 */
63void ui_file_dialog_params_init(ui_file_dialog_params_t *params)
64{
65 memset(params, 0, sizeof(ui_file_dialog_params_t));
66 params->ifname = "";
67}
68
69/** Create new file dialog.
70 *
71 * @param ui User interface
72 * @param params File dialog parameters
73 * @param rdialog Place to store pointer to new dialog
74 * @return EOK on success or an error code
75 */
76errno_t ui_file_dialog_create(ui_t *ui, ui_file_dialog_params_t *params,
77 ui_file_dialog_t **rdialog)
78{
79 errno_t rc;
80 ui_file_dialog_t *dialog;
81 ui_window_t *window = NULL;
82 ui_wnd_params_t wparams;
83 ui_fixed_t *fixed = NULL;
84 ui_label_t *label = NULL;
85 ui_entry_t *entry = NULL;
86 ui_file_list_t *flist = NULL;
87 ui_pbutton_t *bok = NULL;
88 ui_pbutton_t *bcancel = NULL;
89 gfx_rect_t rect;
90 ui_resource_t *ui_res;
91
92 dialog = calloc(1, sizeof(ui_file_dialog_t));
93 if (dialog == NULL) {
94 rc = ENOMEM;
95 goto error;
96 }
97
98 ui_wnd_params_init(&wparams);
99 wparams.caption = params->caption;
100
101 /* FIXME: Auto layout */
102 if (ui_is_textmode(ui)) {
103 wparams.rect.p0.x = 0;
104 wparams.rect.p0.y = 0;
105 wparams.rect.p1.x = 40;
106 wparams.rect.p1.y = 20;
107 } else {
108 wparams.rect.p0.x = 0;
109 wparams.rect.p0.y = 0;
110 wparams.rect.p1.x = 300;
111 wparams.rect.p1.y = 335;
112 }
113
114 rc = ui_window_create(ui, &wparams, &window);
115 if (rc != EOK)
116 goto error;
117
118 ui_window_set_cb(window, &ui_file_dialog_wnd_cb, dialog);
119
120 ui_res = ui_window_get_res(window);
121
122 rc = ui_fixed_create(&fixed);
123 if (rc != EOK)
124 goto error;
125
126 rc = ui_label_create(ui_res, "File Name:", &label);
127 if (rc != EOK)
128 goto error;
129
130 /* FIXME: Auto layout */
131 if (ui_is_textmode(ui)) {
132 rect.p0.x = 3;
133 rect.p0.y = 2;
134 rect.p1.x = 17;
135 rect.p1.y = 3;
136 } else {
137 rect.p0.x = 10;
138 rect.p0.y = 35;
139 rect.p1.x = 190;
140 rect.p1.y = 50;
141 }
142
143 ui_label_set_rect(label, &rect);
144
145 rc = ui_fixed_add(fixed, ui_label_ctl(label));
146 if (rc != EOK)
147 goto error;
148
149 label = NULL;
150
151 rc = ui_entry_create(window, params->ifname, &entry);
152 if (rc != EOK)
153 goto error;
154
155 /* FIXME: Auto layout */
156 if (ui_is_textmode(ui)) {
157 rect.p0.x = 3;
158 rect.p0.y = 3;
159 rect.p1.x = 37;
160 rect.p1.y = 4;
161 } else {
162 rect.p0.x = 10;
163 rect.p0.y = 55;
164 rect.p1.x = 290;
165 rect.p1.y = 80;
166 }
167
168 ui_entry_set_rect(entry, &rect);
169
170 rc = ui_fixed_add(fixed, ui_entry_ctl(entry));
171 if (rc != EOK)
172 goto error;
173
174 ui_entry_activate(entry);
175
176 /* Select all */
177 ui_entry_seek_start(entry, false);
178 ui_entry_seek_end(entry, true);
179
180 dialog->ename = entry;
181 entry = NULL;
182
183 /* Files label */
184 rc = ui_label_create(ui_res, "Files:", &label);
185 if (rc != EOK)
186 goto error;
187
188 /* FIXME: Auto layout */
189 if (ui_is_textmode(ui)) {
190 rect.p0.x = 3;
191 rect.p0.y = 5;
192 rect.p1.x = 17;
193 rect.p1.y = 6;
194 } else {
195 rect.p0.x = 10;
196 rect.p0.y = 90;
197 rect.p1.x = 190;
198 rect.p1.y = 105;
199 }
200
201 ui_label_set_rect(label, &rect);
202
203 rc = ui_fixed_add(fixed, ui_label_ctl(label));
204 if (rc != EOK)
205 goto error;
206
207 label = NULL;
208
209 /* File list */
210
211 rc = ui_file_list_create(window, false, &flist);
212 if (rc != EOK)
213 goto error;
214
215 /* FIXME: Auto layout */
216 if (ui_is_textmode(ui)) {
217 rect.p0.x = 3;
218 rect.p0.y = 6;
219 rect.p1.x = 37;
220 rect.p1.y = 16;
221 } else {
222 rect.p0.x = 10;
223 rect.p0.y = 110;
224 rect.p1.x = 290;
225 rect.p1.y = 280;
226 }
227
228 ui_file_list_set_rect(flist, &rect);
229 ui_file_list_set_cb(flist, &ui_file_dialog_flist_cb, dialog);
230
231 rc = ui_fixed_add(fixed, ui_file_list_ctl(flist));
232 if (rc != EOK)
233 goto error;
234
235 dialog->flist = flist;
236 flist = NULL;
237
238 rc = ui_file_list_read_dir(dialog->flist, ".");
239 if (rc != EOK)
240 goto error;
241
242 /* OK button */
243
244 rc = ui_pbutton_create(ui_res, "OK", &bok);
245 if (rc != EOK)
246 goto error;
247
248 ui_pbutton_set_cb(bok, &ui_file_dialog_bok_cb, dialog);
249
250 /* FIXME: Auto layout */
251 if (ui_is_textmode(ui)) {
252 rect.p0.x = 10;
253 rect.p0.y = 17;
254 rect.p1.x = 20;
255 rect.p1.y = 18;
256 } else {
257 rect.p0.x = 55;
258 rect.p0.y = 290;
259 rect.p1.x = 145;
260 rect.p1.y = 318;
261 }
262
263 ui_pbutton_set_rect(bok, &rect);
264
265 ui_pbutton_set_default(bok, true);
266
267 rc = ui_fixed_add(fixed, ui_pbutton_ctl(bok));
268 if (rc != EOK)
269 goto error;
270
271 dialog->bok = bok;
272 bok = NULL;
273
274 /* Cancel button */
275
276 rc = ui_pbutton_create(ui_res, "Cancel", &bcancel);
277 if (rc != EOK)
278 goto error;
279
280 ui_pbutton_set_cb(bcancel, &ui_file_dialog_bcancel_cb, dialog);
281
282 /* FIXME: Auto layout */
283 if (ui_is_textmode(ui)) {
284 rect.p0.x = 22;
285 rect.p0.y = 17;
286 rect.p1.x = 32;
287 rect.p1.y = 18;
288 } else {
289 rect.p0.x = 155;
290 rect.p0.y = 290;
291 rect.p1.x = 245;
292 rect.p1.y = 318;
293 }
294
295 ui_pbutton_set_rect(bcancel, &rect);
296
297 rc = ui_fixed_add(fixed, ui_pbutton_ctl(bcancel));
298 if (rc != EOK)
299 goto error;
300
301 dialog->bcancel = bcancel;
302 bcancel = NULL;
303
304 ui_window_add(window, ui_fixed_ctl(fixed));
305 fixed = NULL;
306
307 rc = ui_window_paint(window);
308 if (rc != EOK)
309 goto error;
310
311 dialog->window = window;
312 *rdialog = dialog;
313 return EOK;
314error:
315 if (entry != NULL)
316 ui_entry_destroy(entry);
317 if (flist != NULL)
318 ui_file_list_destroy(flist);
319 if (bok != NULL)
320 ui_pbutton_destroy(bok);
321 if (bcancel != NULL)
322 ui_pbutton_destroy(bcancel);
323 if (label != NULL)
324 ui_label_destroy(label);
325 if (fixed != NULL)
326 ui_fixed_destroy(fixed);
327 if (window != NULL)
328 ui_window_destroy(window);
329 if (dialog != NULL)
330 free(dialog);
331 return rc;
332}
333
334/** Destroy file dialog.
335 *
336 * @param dialog File dialog or @c NULL
337 */
338void ui_file_dialog_destroy(ui_file_dialog_t *dialog)
339{
340 if (dialog == NULL)
341 return;
342
343 ui_window_destroy(dialog->window);
344 free(dialog);
345}
346
347/** Set mesage dialog callback.
348 *
349 * @param dialog File dialog
350 * @param cb File dialog callbacks
351 * @param arg Callback argument
352 */
353void ui_file_dialog_set_cb(ui_file_dialog_t *dialog, ui_file_dialog_cb_t *cb,
354 void *arg)
355{
356 dialog->cb = cb;
357 dialog->arg = arg;
358}
359
360/** File dialog window close handler.
361 *
362 * @param window Window
363 * @param arg Argument (ui_file_dialog_t *)
364 */
365static void ui_file_dialog_wnd_close(ui_window_t *window, void *arg)
366{
367 ui_file_dialog_t *dialog = (ui_file_dialog_t *) arg;
368
369 if (dialog->cb != NULL && dialog->cb->close != NULL)
370 dialog->cb->close(dialog, dialog->arg);
371}
372
373/** File dialog window keyboard event handler.
374 *
375 * @param window Window
376 * @param arg Argument (ui_prompt_dialog_t *)
377 * @param event Keyboard event
378 */
379static void ui_file_dialog_wnd_kbd(ui_window_t *window, void *arg,
380 kbd_event_t *event)
381{
382 ui_file_dialog_t *dialog = (ui_file_dialog_t *) arg;
383 const char *fname;
384 ui_evclaim_t claim;
385
386 claim = ui_window_def_kbd(window, event);
387 if (claim == ui_claimed)
388 return;
389
390 if (event->type == KEY_PRESS &&
391 (event->mods & (KM_CTRL | KM_SHIFT | KM_ALT)) == 0) {
392 if (event->key == KC_ENTER) {
393 /* Confirm */
394 if (dialog->cb != NULL && dialog->cb->bok != NULL) {
395 fname = ui_entry_get_text(dialog->ename);
396 dialog->cb->bok(dialog, dialog->arg, fname);
397 return;
398 }
399 } else if (event->key == KC_ESCAPE) {
400 /* Cancel */
401 if (dialog->cb != NULL && dialog->cb->bcancel != NULL) {
402 dialog->cb->bcancel(dialog, dialog->arg);
403 return;
404 }
405 }
406 }
407
408}
409
410static void ui_file_dialog_flist_activate_req(ui_file_list_t *flist, void *arg)
411{
412 ui_file_dialog_t *dialog = (ui_file_dialog_t *) arg;
413
414 ui_file_list_activate(dialog->flist);
415 ui_entry_deactivate(dialog->ename);
416}
417
418static void ui_file_dialog_flist_selected(ui_file_list_t *flist, void *arg,
419 const char *fname)
420{
421 ui_file_dialog_t *dialog = (ui_file_dialog_t *) arg;
422
423 dialog->cb->bok(dialog, dialog->arg, fname);
424}
425
426/** File dialog OK button click handler.
427 *
428 * @param pbutton Push button
429 * @param arg Argument (ui_file_dialog_t *)
430 */
431static void ui_file_dialog_bok_clicked(ui_pbutton_t *pbutton, void *arg)
432{
433 ui_file_dialog_t *dialog = (ui_file_dialog_t *) arg;
434 const char *fname;
435
436 if (dialog->cb != NULL && dialog->cb->bok != NULL) {
437 fname = ui_entry_get_text(dialog->ename);
438 dialog->cb->bok(dialog, dialog->arg, fname);
439 }
440}
441
442/** File dialog cancel button click handler.
443 *
444 * @param pbutton Push button
445 * @param arg Argument (ui_file_dialog_t *)
446 */
447static void ui_file_dialog_bcancel_clicked(ui_pbutton_t *pbutton, void *arg)
448{
449 ui_file_dialog_t *dialog = (ui_file_dialog_t *) arg;
450
451 if (dialog->cb != NULL && dialog->cb->bcancel != NULL)
452 dialog->cb->bcancel(dialog, dialog->arg);
453}
454
455/** @}
456 */
Note: See TracBrowser for help on using the repository browser.