2 * Copyright (c) 2024 Jiri Svoboda
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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.
29 /** @addtogroup taskbar-cfg
32 /** @file Start menu configuration tab
35 #include <gfx/coord.h>
40 #include <tbarcfg/tbarcfg.h>
41 #include <ui/control.h>
44 #include <ui/pbutton.h>
45 #include <ui/resource.h>
47 #include <ui/window.h>
49 #include "startmenu.h"
50 #include "taskbar-cfg.h"
52 static void startmenu_entry_selected(ui_list_entry_t
*, void *);
53 static void startmenu_new_entry_clicked(ui_pbutton_t
*, void *);
54 static void startmenu_delete_entry_clicked(ui_pbutton_t
*, void *);
55 static void startmenu_edit_entry_clicked(ui_pbutton_t
*, void *);
56 static void startmenu_sep_entry_clicked(ui_pbutton_t
*, void *);
57 static void startmenu_up_entry_clicked(ui_pbutton_t
*, void *);
58 static void startmenu_down_entry_clicked(ui_pbutton_t
*, void *);
60 /** Entry list callbacks */
61 ui_list_cb_t startmenu_entry_list_cb
= {
62 .selected
= startmenu_entry_selected
65 /** New entry button callbacks */
66 ui_pbutton_cb_t startmenu_new_entry_button_cb
= {
67 .clicked
= startmenu_new_entry_clicked
70 /** Delete entry button callbacks */
71 ui_pbutton_cb_t startmenu_delete_entry_button_cb
= {
72 .clicked
= startmenu_delete_entry_clicked
75 /** Edit entry button callbacks */
76 ui_pbutton_cb_t startmenu_edit_entry_button_cb
= {
77 .clicked
= startmenu_edit_entry_clicked
80 /** Separator entry button callbacks */
81 ui_pbutton_cb_t startmenu_sep_entry_button_cb
= {
82 .clicked
= startmenu_sep_entry_clicked
85 /** Move entry up button callbacks */
86 ui_pbutton_cb_t startmenu_up_entry_button_cb
= {
87 .clicked
= startmenu_up_entry_clicked
90 /** Move entry down button callbacks */
91 ui_pbutton_cb_t startmenu_down_entry_button_cb
= {
92 .clicked
= startmenu_down_entry_clicked
95 /** Create start menu configuration tab
97 * @param tbcfg Taskbar configuration dialog
98 * @param rsmenu Place to store pointer to new start menu configuration tab
99 * @return EOK on success or an error code
101 errno_t
startmenu_create(taskbar_cfg_t
*tbcfg
, startmenu_t
**rsmenu
)
103 ui_resource_t
*ui_res
;
108 ui_res
= ui_window_get_res(tbcfg
->window
);
110 smenu
= calloc(1, sizeof(startmenu_t
));
112 printf("Out of memory.\n");
116 smenu
->tbarcfg
= tbcfg
;
118 /* 'Start Menu' tab */
120 rc
= ui_tab_create(tbcfg
->tabset
, "Start Menu", &smenu
->tab
);
124 rc
= ui_fixed_create(&smenu
->fixed
);
126 printf("Error creating fixed layout.\n");
130 /* 'Start menu entries:' label */
132 rc
= ui_label_create(ui_res
, "Start menu entries:",
133 &smenu
->entries_label
);
135 printf("Error creating label.\n");
139 if (ui_resource_is_textmode(ui_res
)) {
151 ui_label_set_rect(smenu
->entries_label
, &rect
);
153 rc
= ui_fixed_add(smenu
->fixed
, ui_label_ctl(smenu
->entries_label
));
155 printf("Error adding control to layout.\n");
159 /* List of entries */
161 rc
= ui_list_create(tbcfg
->window
, false, &smenu
->entries_list
);
163 printf("Error creating list.\n");
167 if (ui_resource_is_textmode(ui_res
)) {
179 ui_list_set_rect(smenu
->entries_list
, &rect
);
181 rc
= ui_fixed_add(smenu
->fixed
, ui_list_ctl(smenu
->entries_list
));
183 printf("Error adding control to layout.\n");
187 ui_list_set_cb(smenu
->entries_list
, &startmenu_entry_list_cb
,
190 /* New entry button */
192 rc
= ui_pbutton_create(ui_res
, "New...", &smenu
->new_entry
);
194 printf("Error creating button.\n");
198 if (ui_resource_is_textmode(ui_res
)) {
210 ui_pbutton_set_rect(smenu
->new_entry
, &rect
);
212 rc
= ui_fixed_add(smenu
->fixed
, ui_pbutton_ctl(smenu
->new_entry
));
214 printf("Error adding control to layout.\n");
218 ui_pbutton_set_cb(smenu
->new_entry
, &startmenu_new_entry_button_cb
,
221 /* Delete entry button */
223 rc
= ui_pbutton_create(ui_res
, "Delete", &smenu
->delete_entry
);
225 printf("Error creating button.\n");
229 if (ui_resource_is_textmode(ui_res
)) {
241 ui_pbutton_set_rect(smenu
->delete_entry
, &rect
);
243 rc
= ui_fixed_add(smenu
->fixed
, ui_pbutton_ctl(smenu
->delete_entry
));
245 printf("Error adding control to layout.\n");
249 ui_pbutton_set_cb(smenu
->delete_entry
,
250 &startmenu_delete_entry_button_cb
, (void *)smenu
);
252 /* Edit entry button */
254 rc
= ui_pbutton_create(ui_res
, "Edit...", &smenu
->edit_entry
);
256 printf("Error creating button.\n");
260 if (ui_resource_is_textmode(ui_res
)) {
272 ui_pbutton_set_rect(smenu
->edit_entry
, &rect
);
274 rc
= ui_fixed_add(smenu
->fixed
, ui_pbutton_ctl(smenu
->edit_entry
));
276 printf("Error adding control to layout.\n");
280 ui_pbutton_set_cb(smenu
->edit_entry
,
281 &startmenu_edit_entry_button_cb
, (void *)smenu
);
283 /* Separator entry button */
285 rc
= ui_pbutton_create(ui_res
, "Separator", &smenu
->sep_entry
);
287 printf("Error creating button.\n");
291 if (ui_resource_is_textmode(ui_res
)) {
303 ui_pbutton_set_rect(smenu
->sep_entry
, &rect
);
305 rc
= ui_fixed_add(smenu
->fixed
, ui_pbutton_ctl(smenu
->sep_entry
));
307 printf("Error adding control to layout.\n");
311 ui_pbutton_set_cb(smenu
->sep_entry
,
312 &startmenu_sep_entry_button_cb
, (void *)smenu
);
314 /* Move entry up button */
316 rc
= ui_pbutton_create(ui_res
, "Up", &smenu
->up_entry
);
318 printf("Error creating button.\n");
322 if (ui_resource_is_textmode(ui_res
)) {
334 ui_pbutton_set_rect(smenu
->up_entry
, &rect
);
336 rc
= ui_fixed_add(smenu
->fixed
, ui_pbutton_ctl(smenu
->up_entry
));
338 printf("Error adding control to layout.\n");
342 ui_pbutton_set_cb(smenu
->up_entry
,
343 &startmenu_up_entry_button_cb
, (void *)smenu
);
345 /* Move entry down button */
347 rc
= ui_pbutton_create(ui_res
, "Down", &smenu
->down_entry
);
349 printf("Error creating button.\n");
353 if (ui_resource_is_textmode(ui_res
)) {
365 ui_pbutton_set_rect(smenu
->down_entry
, &rect
);
367 rc
= ui_fixed_add(smenu
->fixed
, ui_pbutton_ctl(smenu
->down_entry
));
369 printf("Error adding control to layout.\n");
373 ui_pbutton_set_cb(smenu
->down_entry
,
374 &startmenu_down_entry_button_cb
, (void *)smenu
);
376 ui_tab_add(smenu
->tab
, ui_fixed_ctl(smenu
->fixed
));
381 if (smenu
->down_entry
!= NULL
)
382 ui_pbutton_destroy(smenu
->down_entry
);
383 if (smenu
->up_entry
!= NULL
)
384 ui_pbutton_destroy(smenu
->up_entry
);
385 if (smenu
->delete_entry
!= NULL
)
386 ui_pbutton_destroy(smenu
->delete_entry
);
387 if (smenu
->new_entry
!= NULL
)
388 ui_pbutton_destroy(smenu
->new_entry
);
389 if (smenu
->entries_label
!= NULL
)
390 ui_label_destroy(smenu
->entries_label
);
391 if (smenu
->entries_list
!= NULL
)
392 ui_list_destroy(smenu
->entries_list
);
393 if (smenu
->fixed
!= NULL
)
394 ui_fixed_destroy(smenu
->fixed
);
399 /** Populate start menu tab with start menu configuration data
401 * @param smenu Start menu configuration tab
402 * @param tbarcfg Taskbar configuration
403 * @return EOK on success or an error code
405 errno_t
startmenu_populate(startmenu_t
*smenu
, tbarcfg_t
*tbarcfg
)
407 smenu_entry_t
*entry
;
408 startmenu_entry_t
*smentry
;
411 entry
= tbarcfg_smenu_first(tbarcfg
);
412 while (entry
!= NULL
) {
413 rc
= startmenu_insert(smenu
, entry
, &smentry
);
417 entry
= tbarcfg_smenu_next(entry
);
423 /** Destroy start menu configuration tab.
425 * @param smenu Start menu configuration tab
427 void startmenu_destroy(startmenu_t
*smenu
)
429 ui_list_entry_t
*lentry
;
430 startmenu_entry_t
*entry
;
432 lentry
= ui_list_first(smenu
->entries_list
);
433 while (lentry
!= NULL
) {
434 entry
= (startmenu_entry_t
*)ui_list_entry_get_arg(lentry
);
436 ui_list_entry_delete(lentry
);
437 lentry
= ui_list_first(smenu
->entries_list
);
440 /* This will automatically destroy all controls in the tab */
441 ui_tab_destroy(smenu
->tab
);
445 /** Insert new entry into entries list.
447 * @param smenu Start menu configuration tab
448 * @param entry Backing entry
449 * @param rsmentry Place to store pointer to new entry or NULL
450 * @return EOK on success or an error code
452 errno_t
startmenu_insert(startmenu_t
*smenu
, smenu_entry_t
*entry
,
453 startmenu_entry_t
**rsmentry
)
455 startmenu_entry_t
*smentry
;
456 ui_list_entry_attr_t attr
;
460 smentry
= calloc(1, sizeof(startmenu_entry_t
));
464 smentry
->startmenu
= smenu
;
465 smentry
->entry
= entry
;
467 ui_list_entry_attr_init(&attr
);
468 separator
= smenu_entry_get_separator(entry
);
470 attr
.caption
= "-- Separator --";
472 attr
.caption
= smenu_entry_get_caption(entry
);
474 attr
.arg
= (void *)smentry
;
476 rc
= ui_list_entry_append(smenu
->entries_list
, &attr
, &smentry
->lentry
);
482 if (rsmentry
!= NULL
)
487 /** Get selected start menu entry.
489 * @param smenu Start menu
490 * @return Selected entry or @c NULL if no entry is selected
492 startmenu_entry_t
*startmenu_get_selected(startmenu_t
*smenu
)
494 ui_list_entry_t
*entry
;
496 entry
= ui_list_get_cursor(smenu
->entries_list
);
500 return (startmenu_entry_t
*)ui_list_entry_get_arg(entry
);
503 /** Create new menu entry.
505 * @param smenu Start menu
507 void startmenu_new_entry(startmenu_t
*smenu
)
512 rc
= smeedit_create(smenu
, NULL
, &smee
);
517 (void)tbarcfg_sync(smenu
->tbarcfg
->tbarcfg
);
518 (void)tbarcfg_notify(TBARCFG_NOTIFY_DEFAULT
);
521 /** Create new separator menu entry.
523 * @param smenu Start menu
525 void startmenu_sep_entry(startmenu_t
*smenu
)
527 startmenu_entry_t
*smentry
= NULL
;
528 smenu_entry_t
*entry
;
531 rc
= smenu_entry_sep_create(smenu
->tbarcfg
->tbarcfg
, &entry
);
535 (void)startmenu_insert(smenu
, entry
, &smentry
);
536 (void)ui_control_paint(ui_list_ctl(smenu
->entries_list
));
537 (void)tbarcfg_sync(smenu
->tbarcfg
->tbarcfg
);
538 (void)tbarcfg_notify(TBARCFG_NOTIFY_DEFAULT
);
541 /** Edit selected menu entry.
543 * @param smenu Start menu
545 void startmenu_edit(startmenu_t
*smenu
)
548 startmenu_entry_t
*smentry
;
551 smentry
= startmenu_get_selected(smenu
);
555 /* Do not edit separator entries */
556 if (smenu_entry_get_separator(smentry
->entry
))
559 rc
= smeedit_create(smenu
, smentry
, &smee
);
566 /** Update start menu entry caption.
568 * When editing an entry the entry's label might change. We need
569 * to update the list entry caption to reflect that.
571 * @param entry Start menu entry
573 errno_t
startmenu_entry_update(startmenu_entry_t
*entry
)
575 return ui_list_entry_set_caption(entry
->lentry
,
576 smenu_entry_get_caption(entry
->entry
));
579 /** Repaint start menu entry list.
581 * When editing an entry the entry's label might change. We need
582 * to update the list entry caption to reflect that.
584 * @param smenu Start menu
586 void startmenu_repaint(startmenu_t
*smenu
)
588 (void) ui_control_paint(ui_list_ctl(smenu
->entries_list
));
591 /** Entry in entry list is selected.
593 * @param lentry UI list entry
594 * @param arg Argument (dcfg_seats_entry_t *)
596 static void startmenu_entry_selected(ui_list_entry_t
*lentry
, void *arg
)
602 /** New entry button clicked.
604 * @param pbutton Push button
605 * @param arg Argument (startmenu_t *)
607 static void startmenu_new_entry_clicked(ui_pbutton_t
*pbutton
, void *arg
)
609 startmenu_t
*smenu
= (startmenu_t
*)arg
;
612 startmenu_new_entry(smenu
);
615 /** Delete entry button clicked.
617 * @param pbutton Push button
618 * @param arg Argument (startmenu_t *)
620 static void startmenu_delete_entry_clicked(ui_pbutton_t
*pbutton
, void *arg
)
622 startmenu_t
*smenu
= (startmenu_t
*)arg
;
623 startmenu_entry_t
*smentry
;
627 smentry
= startmenu_get_selected(smenu
);
631 smenu_entry_destroy(smentry
->entry
);
632 ui_list_entry_delete(smentry
->lentry
);
635 (void)ui_control_paint(ui_list_ctl(smenu
->entries_list
));
636 (void)tbarcfg_sync(smenu
->tbarcfg
->tbarcfg
);
637 (void)tbarcfg_notify(TBARCFG_NOTIFY_DEFAULT
);
640 /** Edit entry button clicked.
642 * @param pbutton Push button
643 * @param arg Argument (startmenu_t *)
645 static void startmenu_edit_entry_clicked(ui_pbutton_t
*pbutton
, void *arg
)
647 startmenu_t
*smenu
= (startmenu_t
*)arg
;
650 startmenu_edit(smenu
);
653 /** Separator entry button clicked.
655 * @param pbutton Push button
656 * @param arg Argument (startmenu_t *)
658 static void startmenu_sep_entry_clicked(ui_pbutton_t
*pbutton
, void *arg
)
660 startmenu_t
*smenu
= (startmenu_t
*)arg
;
663 startmenu_sep_entry(smenu
);
666 /** Up entry button clicked.
668 * @param pbutton Push button
669 * @param arg Argument (startmenu_t *)
671 static void startmenu_up_entry_clicked(ui_pbutton_t
*pbutton
, void *arg
)
673 startmenu_t
*smenu
= (startmenu_t
*)arg
;
674 startmenu_entry_t
*smentry
;
678 smentry
= startmenu_get_selected(smenu
);
682 smenu_entry_move_up(smentry
->entry
);
683 ui_list_entry_move_up(smentry
->lentry
);
685 (void)ui_control_paint(ui_list_ctl(smenu
->entries_list
));
686 (void)tbarcfg_sync(smenu
->tbarcfg
->tbarcfg
);
687 (void)tbarcfg_notify(TBARCFG_NOTIFY_DEFAULT
);
690 /** Down entry button clicked.
692 * @param pbutton Push button
693 * @param arg Argument (startmenu_t *)
695 static void startmenu_down_entry_clicked(ui_pbutton_t
*pbutton
, void *arg
)
697 startmenu_t
*smenu
= (startmenu_t
*)arg
;
698 startmenu_entry_t
*smentry
;
702 smentry
= startmenu_get_selected(smenu
);
706 smenu_entry_move_down(smentry
->entry
);
707 ui_list_entry_move_down(smentry
->lentry
);
709 (void)ui_control_paint(ui_list_ctl(smenu
->entries_list
));
710 (void)tbarcfg_sync(smenu
->tbarcfg
->tbarcfg
);
711 (void)tbarcfg_notify(TBARCFG_NOTIFY_DEFAULT
);