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

topic/simplify-dev-export
Last change on this file since 550ed86 was 550ed86, checked in by Jiri Svoboda <jiri@…>, 20 months ago

Need to add new start menu entry to editor's list

  • Property mode set to 100644
File size: 11.7 KB
Line 
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 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 *);
56
57/** Entry list callbacks */
58ui_list_cb_t startmenu_entry_list_cb = {
59 .selected = startmenu_entry_selected
60};
61
62/** New entry button callbacks */
63ui_pbutton_cb_t startmenu_new_entry_button_cb = {
64 .clicked = startmenu_new_entry_clicked
65};
66
67/** Delete entry button callbacks */
68ui_pbutton_cb_t startmenu_delete_entry_button_cb = {
69 .clicked = startmenu_delete_entry_clicked
70};
71
72/** Edit entry button callbacks */
73ui_pbutton_cb_t startmenu_edit_entry_button_cb = {
74 .clicked = startmenu_edit_entry_clicked
75};
76
77/** Create start menu configuration tab
78 *
79 * @param tbcfg Taskbar configuration dialog
80 * @param rsmenu Place to store pointer to new start menu configuration tab
81 * @return EOK on success or an error code
82 */
83errno_t startmenu_create(taskbar_cfg_t *tbcfg, startmenu_t **rsmenu)
84{
85 ui_resource_t *ui_res;
86 startmenu_t *smenu;
87 gfx_rect_t rect;
88 errno_t rc;
89
90 ui_res = ui_window_get_res(tbcfg->window);
91
92 smenu = calloc(1, sizeof(startmenu_t));
93 if (smenu == NULL) {
94 printf("Out of memory.\n");
95 return ENOMEM;
96 }
97
98 smenu->tbarcfg = tbcfg;
99
100 /* 'Start Menu' tab */
101
102 rc = ui_tab_create(tbcfg->tabset, "Start Menu", &smenu->tab);
103 if (rc != EOK)
104 goto error;
105
106 rc = ui_fixed_create(&smenu->fixed);
107 if (rc != EOK) {
108 printf("Error creating fixed layout.\n");
109 goto error;
110 }
111
112 /* 'Start menu entries:' label */
113
114 rc = ui_label_create(ui_res, "Start menu entries:",
115 &smenu->entries_label);
116 if (rc != EOK) {
117 printf("Error creating label.\n");
118 goto error;
119 }
120
121 if (ui_resource_is_textmode(ui_res)) {
122 rect.p0.x = 4;
123 rect.p0.y = 4;
124 rect.p1.x = 36;
125 rect.p1.y = 5;
126 } else {
127 rect.p0.x = 20;
128 rect.p0.y = 60;
129 rect.p1.x = 360;
130 rect.p1.y = 80;
131 }
132
133 ui_label_set_rect(smenu->entries_label, &rect);
134
135 rc = ui_fixed_add(smenu->fixed, ui_label_ctl(smenu->entries_label));
136 if (rc != EOK) {
137 printf("Error adding control to layout.\n");
138 goto error;
139 }
140
141 /* List of entries */
142
143 rc = ui_list_create(tbcfg->window, false, &smenu->entries_list);
144 if (rc != EOK) {
145 printf("Error creating list.\n");
146 goto error;
147 }
148
149 if (ui_resource_is_textmode(ui_res)) {
150 rect.p0.x = 4;
151 rect.p0.y = 5;
152 rect.p1.x = 56;
153 rect.p1.y = 10;
154 } else {
155 rect.p0.x = 20;
156 rect.p0.y = 80;
157 rect.p1.x = 360;
158 rect.p1.y = 180;
159 }
160
161 ui_list_set_rect(smenu->entries_list, &rect);
162
163 rc = ui_fixed_add(smenu->fixed, ui_list_ctl(smenu->entries_list));
164 if (rc != EOK) {
165 printf("Error adding control to layout.\n");
166 goto error;
167 }
168
169 ui_list_set_cb(smenu->entries_list, &startmenu_entry_list_cb,
170 (void *)smenu);
171
172 /* New entry button */
173
174 rc = ui_pbutton_create(ui_res, "New...", &smenu->new_entry);
175 if (rc != EOK) {
176 printf("Error creating button.\n");
177 goto error;
178 }
179
180 if (ui_resource_is_textmode(ui_res)) {
181 rect.p0.x = 58;
182 rect.p0.y = 5;
183 rect.p1.x = 68;
184 rect.p1.y = 6;
185 } else {
186 rect.p0.x = 370;
187 rect.p0.y = 80;
188 rect.p1.x = 450;
189 rect.p1.y = 105;
190 }
191
192 ui_pbutton_set_rect(smenu->new_entry, &rect);
193
194 rc = ui_fixed_add(smenu->fixed, ui_pbutton_ctl(smenu->new_entry));
195 if (rc != EOK) {
196 printf("Error adding control to layout.\n");
197 goto error;
198 }
199
200 ui_pbutton_set_cb(smenu->new_entry, &startmenu_new_entry_button_cb,
201 (void *)smenu);
202
203 /* Delete entry button */
204
205 rc = ui_pbutton_create(ui_res, "Delete", &smenu->delete_entry);
206 if (rc != EOK) {
207 printf("Error creating button.\n");
208 goto error;
209 }
210
211 if (ui_resource_is_textmode(ui_res)) {
212 rect.p0.x = 58;
213 rect.p0.y = 7;
214 rect.p1.x = 68;
215 rect.p1.y = 8;
216 } else {
217 rect.p0.x = 370;
218 rect.p0.y = 110;
219 rect.p1.x = 450;
220 rect.p1.y = 135;
221 }
222
223 ui_pbutton_set_rect(smenu->delete_entry, &rect);
224
225 rc = ui_fixed_add(smenu->fixed, ui_pbutton_ctl(smenu->delete_entry));
226 if (rc != EOK) {
227 printf("Error adding control to layout.\n");
228 goto error;
229 }
230
231 ui_pbutton_set_cb(smenu->delete_entry,
232 &startmenu_delete_entry_button_cb, (void *)smenu);
233
234 /* Edit entry button */
235
236 rc = ui_pbutton_create(ui_res, "Edit...", &smenu->edit_entry);
237 if (rc != EOK) {
238 printf("Error creating button.\n");
239 goto error;
240 }
241
242 if (ui_resource_is_textmode(ui_res)) {
243 rect.p0.x = 58;
244 rect.p0.y = 9;
245 rect.p1.x = 68;
246 rect.p1.y = 10;
247 } else {
248 rect.p0.x = 370;
249 rect.p0.y = 140;
250 rect.p1.x = 450;
251 rect.p1.y = 165;
252 }
253
254 ui_pbutton_set_rect(smenu->edit_entry, &rect);
255
256 rc = ui_fixed_add(smenu->fixed, ui_pbutton_ctl(smenu->edit_entry));
257 if (rc != EOK) {
258 printf("Error adding control to layout.\n");
259 goto error;
260 }
261
262 ui_pbutton_set_cb(smenu->edit_entry,
263 &startmenu_edit_entry_button_cb, (void *)smenu);
264
265 ui_tab_add(smenu->tab, ui_fixed_ctl(smenu->fixed));
266
267 *rsmenu = smenu;
268 return EOK;
269error:
270 if (smenu->delete_entry != NULL)
271 ui_pbutton_destroy(smenu->delete_entry);
272 if (smenu->new_entry != NULL)
273 ui_pbutton_destroy(smenu->new_entry);
274 if (smenu->entries_label != NULL)
275 ui_label_destroy(smenu->entries_label);
276 if (smenu->entries_list != NULL)
277 ui_list_destroy(smenu->entries_list);
278 if (smenu->fixed != NULL)
279 ui_fixed_destroy(smenu->fixed);
280 free(smenu);
281 return rc;
282}
283
284/** Populate start menu tab with start menu configuration data
285 *
286 * @param smenu Start menu configuration tab
287 * @param tbarcfg Taskbar configuration
288 * @return EOK on success or an error code
289 */
290errno_t startmenu_populate(startmenu_t *smenu, tbarcfg_t *tbarcfg)
291{
292 smenu_entry_t *entry;
293 startmenu_entry_t *smentry;
294 errno_t rc;
295
296 entry = tbarcfg_smenu_first(tbarcfg);
297 while (entry != NULL) {
298 rc = startmenu_insert(smenu, entry, &smentry);
299 if (rc != EOK)
300 return rc;
301
302 entry = tbarcfg_smenu_next(entry);
303 }
304
305 return EOK;
306}
307
308/** Destroy start menu configuration tab.
309 *
310 * @param smenu Start menu configuration tab
311 */
312void startmenu_destroy(startmenu_t *smenu)
313{
314 ui_list_entry_t *lentry;
315 startmenu_entry_t *entry;
316
317 lentry = ui_list_first(smenu->entries_list);
318 while (lentry != NULL) {
319 entry = (startmenu_entry_t *)ui_list_entry_get_arg(lentry);
320 free(entry);
321 ui_list_entry_delete(lentry);
322 lentry = ui_list_first(smenu->entries_list);
323 }
324
325 /* This will automatically destroy all controls in the tab */
326 ui_tab_destroy(smenu->tab);
327 free(smenu);
328}
329
330/** Insert new entry into entries list.
331 *
332 * @param smenu Start menu configuration tab
333 * @param entry Backing entry
334 * @param rsmentry Place to store pointer to new entry or NULL
335 * @return EOK on success or an error code
336 */
337errno_t startmenu_insert(startmenu_t *smenu, smenu_entry_t *entry,
338 startmenu_entry_t **rsmentry)
339{
340 startmenu_entry_t *smentry;
341 ui_list_entry_attr_t attr;
342 errno_t rc;
343
344 smentry = calloc(1, sizeof(startmenu_entry_t));
345 if (smentry == NULL)
346 return ENOMEM;
347
348 smentry->startmenu = smenu;
349 smentry->entry = entry;
350
351 ui_list_entry_attr_init(&attr);
352 attr.caption = smenu_entry_get_caption(entry);
353 attr.arg = (void *)smentry;
354 rc = ui_list_entry_append(smenu->entries_list, &attr, &smentry->lentry);
355 if (rc != EOK) {
356 free(smentry);
357 return rc;
358 }
359
360 if (rsmentry != NULL)
361 *rsmentry = smentry;
362 return EOK;
363}
364
365/** Get selected start menu entry.
366 *
367 * @param smenu Start menu
368 * @return Selected entry or @c NULL if no entry is selected
369 */
370startmenu_entry_t *startmenu_get_selected(startmenu_t *smenu)
371{
372 ui_list_entry_t *entry;
373
374 entry = ui_list_get_cursor(smenu->entries_list);
375 if (entry == NULL)
376 return NULL;
377
378 return (startmenu_entry_t *)ui_list_entry_get_arg(entry);
379}
380
381/** Create new menu entry.
382 *
383 * @param smenu Start menu
384 */
385void startmenu_new_entry(startmenu_t *smenu)
386{
387 smeedit_t *smee;
388 errno_t rc;
389
390 rc = smeedit_create(smenu, NULL, &smee);
391 if (rc != EOK)
392 return;
393
394 (void)smee;
395}
396
397/** Edit selected menu entry.
398 *
399 * @param smenu Start menu
400 */
401void startmenu_edit(startmenu_t *smenu)
402{
403 smeedit_t *smee;
404 startmenu_entry_t *smentry;
405 errno_t rc;
406
407 smentry = startmenu_get_selected(smenu);
408 if (smentry == NULL)
409 return;
410
411 rc = smeedit_create(smenu, smentry, &smee);
412 if (rc != EOK)
413 return;
414
415 (void)smee;
416}
417
418/** Update start menu entry caption.
419 *
420 * When editing an entry the entry's label might change. We need
421 * to update the list entry caption to reflect that.
422 *
423 * @param entry Start menu entry
424 */
425errno_t startmenu_entry_update(startmenu_entry_t *entry)
426{
427 return ui_list_entry_set_caption(entry->lentry,
428 smenu_entry_get_caption(entry->entry));
429}
430
431/** Repaint start menu entry list.
432 *
433 * When editing an entry the entry's label might change. We need
434 * to update the list entry caption to reflect that.
435 *
436 * @param smenu Start menu
437 */
438void startmenu_repaint(startmenu_t *smenu)
439{
440 (void) ui_control_paint(ui_list_ctl(smenu->entries_list));
441}
442
443/** Entry in entry list is selected.
444 *
445 * @param lentry UI list entry
446 * @param arg Argument (dcfg_seats_entry_t *)
447 */
448static void startmenu_entry_selected(ui_list_entry_t *lentry, void *arg)
449{
450 (void)lentry;
451 (void)arg;
452}
453
454/** New entry button clicked.
455 *
456 * @param pbutton Push button
457 * @param arg Argument (startmenu_t *)
458 */
459static void startmenu_new_entry_clicked(ui_pbutton_t *pbutton, void *arg)
460{
461 startmenu_t *smenu = (startmenu_t *)arg;
462
463 (void)pbutton;
464 startmenu_new_entry(smenu);
465}
466
467/** Delete entry button clicked.
468 *
469 * @param pbutton Push button
470 * @param arg Argument (startmenu_t *)
471 */
472static void startmenu_delete_entry_clicked(ui_pbutton_t *pbutton, void *arg)
473{
474 startmenu_t *smenu = (startmenu_t *)arg;
475 startmenu_entry_t *smentry;
476 errno_t rc;
477
478 (void)pbutton;
479
480 smentry = startmenu_get_selected(smenu);
481 if (smentry == NULL)
482 return;
483
484 rc = smenu_entry_destroy(smentry->entry);
485 if (rc != EOK)
486 return;
487
488 ui_list_entry_delete(smentry->lentry);
489 free(smentry);
490 (void) ui_control_paint(ui_list_ctl(smenu->entries_list));
491}
492
493/** Edit entry button clicked.
494 *
495 * @param pbutton Push button
496 * @param arg Argument (startmenu_t *)
497 */
498static void startmenu_edit_entry_clicked(ui_pbutton_t *pbutton, void *arg)
499{
500 startmenu_t *smenu = (startmenu_t *)arg;
501
502 (void)pbutton;
503 startmenu_edit(smenu);
504}
505
506/** @}
507 */
Note: See TracBrowser for help on using the repository browser.