source: mainline/uspace/app/taskbar-cfg/startmenu.c@ 10657856

Last change on this file since 10657856 was 28ca31ed, checked in by Jiri Svoboda <jiri@…>, 18 months ago

Moving start menu entry up and down

  • Property mode set to 100644
File size: 14.5 KB
Line 
1/*
2 * Copyright (c) 2024 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 taskbar-cfg
30 * @{
31 */
32/** @file Start menu configuration tab
33 */
34
35#include <gfx/coord.h>
36#include <loc.h>
37#include <stdio.h>
38#include <stdlib.h>
39#include <str.h>
40#include <tbarcfg/tbarcfg.h>
41#include <ui/control.h>
42#include <ui/label.h>
43#include <ui/list.h>
44#include <ui/pbutton.h>
45#include <ui/resource.h>
46#include <ui/tab.h>
47#include <ui/window.h>
48#include "smeedit.h"
49#include "startmenu.h"
50#include "taskbar-cfg.h"
51
52static void startmenu_entry_selected(ui_list_entry_t *, void *);
53static void startmenu_new_entry_clicked(ui_pbutton_t *, void *);
54static void startmenu_delete_entry_clicked(ui_pbutton_t *, void *);
55static void startmenu_edit_entry_clicked(ui_pbutton_t *, void *);
56static void startmenu_up_entry_clicked(ui_pbutton_t *, void *);
57static void startmenu_down_entry_clicked(ui_pbutton_t *, void *);
58
59/** Entry list callbacks */
60ui_list_cb_t startmenu_entry_list_cb = {
61 .selected = startmenu_entry_selected
62};
63
64/** New entry button callbacks */
65ui_pbutton_cb_t startmenu_new_entry_button_cb = {
66 .clicked = startmenu_new_entry_clicked
67};
68
69/** Delete entry button callbacks */
70ui_pbutton_cb_t startmenu_delete_entry_button_cb = {
71 .clicked = startmenu_delete_entry_clicked
72};
73
74/** Edit entry button callbacks */
75ui_pbutton_cb_t startmenu_edit_entry_button_cb = {
76 .clicked = startmenu_edit_entry_clicked
77};
78
79/** Move entry up button callbacks */
80ui_pbutton_cb_t startmenu_up_entry_button_cb = {
81 .clicked = startmenu_up_entry_clicked
82};
83
84/** Move entry down button callbacks */
85ui_pbutton_cb_t startmenu_down_entry_button_cb = {
86 .clicked = startmenu_down_entry_clicked
87};
88
89/** Create start menu configuration tab
90 *
91 * @param tbcfg Taskbar configuration dialog
92 * @param rsmenu Place to store pointer to new start menu configuration tab
93 * @return EOK on success or an error code
94 */
95errno_t startmenu_create(taskbar_cfg_t *tbcfg, startmenu_t **rsmenu)
96{
97 ui_resource_t *ui_res;
98 startmenu_t *smenu;
99 gfx_rect_t rect;
100 errno_t rc;
101
102 ui_res = ui_window_get_res(tbcfg->window);
103
104 smenu = calloc(1, sizeof(startmenu_t));
105 if (smenu == NULL) {
106 printf("Out of memory.\n");
107 return ENOMEM;
108 }
109
110 smenu->tbarcfg = tbcfg;
111
112 /* 'Start Menu' tab */
113
114 rc = ui_tab_create(tbcfg->tabset, "Start Menu", &smenu->tab);
115 if (rc != EOK)
116 goto error;
117
118 rc = ui_fixed_create(&smenu->fixed);
119 if (rc != EOK) {
120 printf("Error creating fixed layout.\n");
121 goto error;
122 }
123
124 /* 'Start menu entries:' label */
125
126 rc = ui_label_create(ui_res, "Start menu entries:",
127 &smenu->entries_label);
128 if (rc != EOK) {
129 printf("Error creating label.\n");
130 goto error;
131 }
132
133 if (ui_resource_is_textmode(ui_res)) {
134 rect.p0.x = 4;
135 rect.p0.y = 4;
136 rect.p1.x = 36;
137 rect.p1.y = 5;
138 } else {
139 rect.p0.x = 20;
140 rect.p0.y = 60;
141 rect.p1.x = 360;
142 rect.p1.y = 80;
143 }
144
145 ui_label_set_rect(smenu->entries_label, &rect);
146
147 rc = ui_fixed_add(smenu->fixed, ui_label_ctl(smenu->entries_label));
148 if (rc != EOK) {
149 printf("Error adding control to layout.\n");
150 goto error;
151 }
152
153 /* List of entries */
154
155 rc = ui_list_create(tbcfg->window, false, &smenu->entries_list);
156 if (rc != EOK) {
157 printf("Error creating list.\n");
158 goto error;
159 }
160
161 if (ui_resource_is_textmode(ui_res)) {
162 rect.p0.x = 4;
163 rect.p0.y = 5;
164 rect.p1.x = 56;
165 rect.p1.y = 20;
166 } else {
167 rect.p0.x = 20;
168 rect.p0.y = 80;
169 rect.p1.x = 360;
170 rect.p1.y = 330;
171 }
172
173 ui_list_set_rect(smenu->entries_list, &rect);
174
175 rc = ui_fixed_add(smenu->fixed, ui_list_ctl(smenu->entries_list));
176 if (rc != EOK) {
177 printf("Error adding control to layout.\n");
178 goto error;
179 }
180
181 ui_list_set_cb(smenu->entries_list, &startmenu_entry_list_cb,
182 (void *)smenu);
183
184 /* New entry button */
185
186 rc = ui_pbutton_create(ui_res, "New...", &smenu->new_entry);
187 if (rc != EOK) {
188 printf("Error creating button.\n");
189 goto error;
190 }
191
192 if (ui_resource_is_textmode(ui_res)) {
193 rect.p0.x = 58;
194 rect.p0.y = 5;
195 rect.p1.x = 68;
196 rect.p1.y = 6;
197 } else {
198 rect.p0.x = 370;
199 rect.p0.y = 80;
200 rect.p1.x = 450;
201 rect.p1.y = 105;
202 }
203
204 ui_pbutton_set_rect(smenu->new_entry, &rect);
205
206 rc = ui_fixed_add(smenu->fixed, ui_pbutton_ctl(smenu->new_entry));
207 if (rc != EOK) {
208 printf("Error adding control to layout.\n");
209 goto error;
210 }
211
212 ui_pbutton_set_cb(smenu->new_entry, &startmenu_new_entry_button_cb,
213 (void *)smenu);
214
215 /* Delete entry button */
216
217 rc = ui_pbutton_create(ui_res, "Delete", &smenu->delete_entry);
218 if (rc != EOK) {
219 printf("Error creating button.\n");
220 goto error;
221 }
222
223 if (ui_resource_is_textmode(ui_res)) {
224 rect.p0.x = 58;
225 rect.p0.y = 7;
226 rect.p1.x = 68;
227 rect.p1.y = 8;
228 } else {
229 rect.p0.x = 370;
230 rect.p0.y = 110;
231 rect.p1.x = 450;
232 rect.p1.y = 135;
233 }
234
235 ui_pbutton_set_rect(smenu->delete_entry, &rect);
236
237 rc = ui_fixed_add(smenu->fixed, ui_pbutton_ctl(smenu->delete_entry));
238 if (rc != EOK) {
239 printf("Error adding control to layout.\n");
240 goto error;
241 }
242
243 ui_pbutton_set_cb(smenu->delete_entry,
244 &startmenu_delete_entry_button_cb, (void *)smenu);
245
246 /* Edit entry button */
247
248 rc = ui_pbutton_create(ui_res, "Edit...", &smenu->edit_entry);
249 if (rc != EOK) {
250 printf("Error creating button.\n");
251 goto error;
252 }
253
254 if (ui_resource_is_textmode(ui_res)) {
255 rect.p0.x = 58;
256 rect.p0.y = 9;
257 rect.p1.x = 68;
258 rect.p1.y = 10;
259 } else {
260 rect.p0.x = 370;
261 rect.p0.y = 140;
262 rect.p1.x = 450;
263 rect.p1.y = 165;
264 }
265
266 ui_pbutton_set_rect(smenu->edit_entry, &rect);
267
268 rc = ui_fixed_add(smenu->fixed, ui_pbutton_ctl(smenu->edit_entry));
269 if (rc != EOK) {
270 printf("Error adding control to layout.\n");
271 goto error;
272 }
273
274 ui_pbutton_set_cb(smenu->edit_entry,
275 &startmenu_edit_entry_button_cb, (void *)smenu);
276
277 /* Move entry up button */
278
279 rc = ui_pbutton_create(ui_res, "Up", &smenu->up_entry);
280 if (rc != EOK) {
281 printf("Error creating button.\n");
282 goto error;
283 }
284
285 if (ui_resource_is_textmode(ui_res)) {
286 rect.p0.x = 58;
287 rect.p0.y = 12;
288 rect.p1.x = 68;
289 rect.p1.y = 13;
290 } else {
291 rect.p0.x = 370;
292 rect.p0.y = 190;
293 rect.p1.x = 450;
294 rect.p1.y = 215;
295 }
296
297 ui_pbutton_set_rect(smenu->up_entry, &rect);
298
299 rc = ui_fixed_add(smenu->fixed, ui_pbutton_ctl(smenu->up_entry));
300 if (rc != EOK) {
301 printf("Error adding control to layout.\n");
302 goto error;
303 }
304
305 ui_pbutton_set_cb(smenu->up_entry,
306 &startmenu_up_entry_button_cb, (void *)smenu);
307
308 /* Move entry down button */
309
310 rc = ui_pbutton_create(ui_res, "Down", &smenu->down_entry);
311 if (rc != EOK) {
312 printf("Error creating button.\n");
313 goto error;
314 }
315
316 if (ui_resource_is_textmode(ui_res)) {
317 rect.p0.x = 58;
318 rect.p0.y = 14;
319 rect.p1.x = 68;
320 rect.p1.y = 15;
321 } else {
322 rect.p0.x = 370;
323 rect.p0.y = 220;
324 rect.p1.x = 450;
325 rect.p1.y = 245;
326 }
327
328 ui_pbutton_set_rect(smenu->down_entry, &rect);
329
330 rc = ui_fixed_add(smenu->fixed, ui_pbutton_ctl(smenu->down_entry));
331 if (rc != EOK) {
332 printf("Error adding control to layout.\n");
333 goto error;
334 }
335
336 ui_pbutton_set_cb(smenu->down_entry,
337 &startmenu_down_entry_button_cb, (void *)smenu);
338
339 ui_tab_add(smenu->tab, ui_fixed_ctl(smenu->fixed));
340
341 *rsmenu = smenu;
342 return EOK;
343error:
344 if (smenu->down_entry != NULL)
345 ui_pbutton_destroy(smenu->down_entry);
346 if (smenu->up_entry != NULL)
347 ui_pbutton_destroy(smenu->up_entry);
348 if (smenu->delete_entry != NULL)
349 ui_pbutton_destroy(smenu->delete_entry);
350 if (smenu->new_entry != NULL)
351 ui_pbutton_destroy(smenu->new_entry);
352 if (smenu->entries_label != NULL)
353 ui_label_destroy(smenu->entries_label);
354 if (smenu->entries_list != NULL)
355 ui_list_destroy(smenu->entries_list);
356 if (smenu->fixed != NULL)
357 ui_fixed_destroy(smenu->fixed);
358 free(smenu);
359 return rc;
360}
361
362/** Populate start menu tab with start menu configuration data
363 *
364 * @param smenu Start menu configuration tab
365 * @param tbarcfg Taskbar configuration
366 * @return EOK on success or an error code
367 */
368errno_t startmenu_populate(startmenu_t *smenu, tbarcfg_t *tbarcfg)
369{
370 smenu_entry_t *entry;
371 startmenu_entry_t *smentry;
372 errno_t rc;
373
374 entry = tbarcfg_smenu_first(tbarcfg);
375 while (entry != NULL) {
376 rc = startmenu_insert(smenu, entry, &smentry);
377 if (rc != EOK)
378 return rc;
379
380 entry = tbarcfg_smenu_next(entry);
381 }
382
383 return EOK;
384}
385
386/** Destroy start menu configuration tab.
387 *
388 * @param smenu Start menu configuration tab
389 */
390void startmenu_destroy(startmenu_t *smenu)
391{
392 ui_list_entry_t *lentry;
393 startmenu_entry_t *entry;
394
395 lentry = ui_list_first(smenu->entries_list);
396 while (lentry != NULL) {
397 entry = (startmenu_entry_t *)ui_list_entry_get_arg(lentry);
398 free(entry);
399 ui_list_entry_delete(lentry);
400 lentry = ui_list_first(smenu->entries_list);
401 }
402
403 /* This will automatically destroy all controls in the tab */
404 ui_tab_destroy(smenu->tab);
405 free(smenu);
406}
407
408/** Insert new entry into entries list.
409 *
410 * @param smenu Start menu configuration tab
411 * @param entry Backing entry
412 * @param rsmentry Place to store pointer to new entry or NULL
413 * @return EOK on success or an error code
414 */
415errno_t startmenu_insert(startmenu_t *smenu, smenu_entry_t *entry,
416 startmenu_entry_t **rsmentry)
417{
418 startmenu_entry_t *smentry;
419 ui_list_entry_attr_t attr;
420 errno_t rc;
421
422 smentry = calloc(1, sizeof(startmenu_entry_t));
423 if (smentry == NULL)
424 return ENOMEM;
425
426 smentry->startmenu = smenu;
427 smentry->entry = entry;
428
429 ui_list_entry_attr_init(&attr);
430 attr.caption = smenu_entry_get_caption(entry);
431 attr.arg = (void *)smentry;
432 rc = ui_list_entry_append(smenu->entries_list, &attr, &smentry->lentry);
433 if (rc != EOK) {
434 free(smentry);
435 return rc;
436 }
437
438 if (rsmentry != NULL)
439 *rsmentry = smentry;
440 return EOK;
441}
442
443/** Get selected start menu entry.
444 *
445 * @param smenu Start menu
446 * @return Selected entry or @c NULL if no entry is selected
447 */
448startmenu_entry_t *startmenu_get_selected(startmenu_t *smenu)
449{
450 ui_list_entry_t *entry;
451
452 entry = ui_list_get_cursor(smenu->entries_list);
453 if (entry == NULL)
454 return NULL;
455
456 return (startmenu_entry_t *)ui_list_entry_get_arg(entry);
457}
458
459/** Create new menu entry.
460 *
461 * @param smenu Start menu
462 */
463void startmenu_new_entry(startmenu_t *smenu)
464{
465 smeedit_t *smee;
466 errno_t rc;
467
468 rc = smeedit_create(smenu, NULL, &smee);
469 if (rc != EOK)
470 return;
471
472 (void)smee;
473}
474
475/** Edit selected menu entry.
476 *
477 * @param smenu Start menu
478 */
479void startmenu_edit(startmenu_t *smenu)
480{
481 smeedit_t *smee;
482 startmenu_entry_t *smentry;
483 errno_t rc;
484
485 smentry = startmenu_get_selected(smenu);
486 if (smentry == NULL)
487 return;
488
489 rc = smeedit_create(smenu, smentry, &smee);
490 if (rc != EOK)
491 return;
492
493 (void)smee;
494}
495
496/** Update start menu entry caption.
497 *
498 * When editing an entry the entry's label might change. We need
499 * to update the list entry caption to reflect that.
500 *
501 * @param entry Start menu entry
502 */
503errno_t startmenu_entry_update(startmenu_entry_t *entry)
504{
505 return ui_list_entry_set_caption(entry->lentry,
506 smenu_entry_get_caption(entry->entry));
507}
508
509/** Repaint start menu entry list.
510 *
511 * When editing an entry the entry's label might change. We need
512 * to update the list entry caption to reflect that.
513 *
514 * @param smenu Start menu
515 */
516void startmenu_repaint(startmenu_t *smenu)
517{
518 (void) ui_control_paint(ui_list_ctl(smenu->entries_list));
519}
520
521/** Entry in entry list is selected.
522 *
523 * @param lentry UI list entry
524 * @param arg Argument (dcfg_seats_entry_t *)
525 */
526static void startmenu_entry_selected(ui_list_entry_t *lentry, void *arg)
527{
528 (void)lentry;
529 (void)arg;
530}
531
532/** New entry button clicked.
533 *
534 * @param pbutton Push button
535 * @param arg Argument (startmenu_t *)
536 */
537static void startmenu_new_entry_clicked(ui_pbutton_t *pbutton, void *arg)
538{
539 startmenu_t *smenu = (startmenu_t *)arg;
540
541 (void)pbutton;
542 startmenu_new_entry(smenu);
543}
544
545/** Delete entry button clicked.
546 *
547 * @param pbutton Push button
548 * @param arg Argument (startmenu_t *)
549 */
550static void startmenu_delete_entry_clicked(ui_pbutton_t *pbutton, void *arg)
551{
552 startmenu_t *smenu = (startmenu_t *)arg;
553 startmenu_entry_t *smentry;
554 errno_t rc;
555
556 (void)pbutton;
557
558 smentry = startmenu_get_selected(smenu);
559 if (smentry == NULL)
560 return;
561
562 rc = smenu_entry_destroy(smentry->entry);
563 if (rc != EOK)
564 return;
565
566 ui_list_entry_delete(smentry->lentry);
567 free(smentry);
568 (void)ui_control_paint(ui_list_ctl(smenu->entries_list));
569}
570
571/** Edit entry button clicked.
572 *
573 * @param pbutton Push button
574 * @param arg Argument (startmenu_t *)
575 */
576static void startmenu_edit_entry_clicked(ui_pbutton_t *pbutton, void *arg)
577{
578 startmenu_t *smenu = (startmenu_t *)arg;
579
580 (void)pbutton;
581 startmenu_edit(smenu);
582}
583
584/** Up entry button clicked.
585 *
586 * @param pbutton Push button
587 * @param arg Argument (startmenu_t *)
588 */
589static void startmenu_up_entry_clicked(ui_pbutton_t *pbutton, void *arg)
590{
591 startmenu_t *smenu = (startmenu_t *)arg;
592 startmenu_entry_t *smentry;
593 errno_t rc;
594
595 (void)pbutton;
596
597 smentry = startmenu_get_selected(smenu);
598 if (smentry == NULL)
599 return;
600
601 rc = smenu_entry_move_up(smentry->entry);
602 if (rc != EOK)
603 return;
604
605 ui_list_entry_move_up(smentry->lentry);
606
607 (void)ui_control_paint(ui_list_ctl(smenu->entries_list));
608}
609
610/** Down entry button clicked.
611 *
612 * @param pbutton Push button
613 * @param arg Argument (startmenu_t *)
614 */
615static void startmenu_down_entry_clicked(ui_pbutton_t *pbutton, void *arg)
616{
617 startmenu_t *smenu = (startmenu_t *)arg;
618 startmenu_entry_t *smentry;
619 errno_t rc;
620
621 (void)pbutton;
622
623 smentry = startmenu_get_selected(smenu);
624 if (smentry == NULL)
625 return;
626
627 rc = smenu_entry_move_up(smentry->entry);
628 if (rc != EOK)
629 return;
630
631 ui_list_entry_move_down(smentry->lentry);
632
633 (void)ui_control_paint(ui_list_ctl(smenu->entries_list));
634}
635
636/** @}
637 */
Note: See TracBrowser for help on using the repository browser.