source: mainline/uspace/app/taskbar/tbsmenu.c@ 7d78e466

ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 7d78e466 was 7d78e466, checked in by Jiri Svoboda <jiri@…>, 22 months ago

Load start menu from file using libstartmenu

  • Property mode set to 100644
File size: 7.0 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
30 * @{
31 */
32/** @file Task bar start menu
33 */
34
35#include <gfx/coord.h>
36#include <startmenu/startmenu.h>
37#include <stdbool.h>
38#include <stddef.h>
39#include <stdlib.h>
40#include <ui/fixed.h>
41#include <ui/menu.h>
42#include <ui/menuentry.h>
43#include <ui/resource.h>
44#include <ui/ui.h>
45#include <ui/window.h>
46#include "tbsmenu.h"
47
48static void tbsmenu_smenu_close_req(ui_menu_t *, void *);
49
50/** Start menu callbacks */
51static ui_menu_cb_t tbsmenu_smenu_cb = {
52 .close_req = tbsmenu_smenu_close_req,
53};
54
55static void tbsmenu_button_clicked(ui_pbutton_t *, void *);
56
57/** Start button callbacks */
58static ui_pbutton_cb_t tbsmenu_button_cb = {
59 .clicked = tbsmenu_button_clicked
60};
61
62/** Create task bar start menu.
63 *
64 * @param window Containing window
65 * @param fixed Fixed layout to which start button will be added
66 * @param rtbsmenu Place to store pointer to new start menu
67 * @return @c EOK on success or an error code
68 */
69errno_t tbsmenu_create(ui_window_t *window, ui_fixed_t *fixed,
70 tbsmenu_t **rtbsmenu)
71{
72 ui_resource_t *res = ui_window_get_res(window);
73 tbsmenu_t *tbsmenu = NULL;
74 errno_t rc;
75
76 tbsmenu = calloc(1, sizeof(tbsmenu_t));
77 if (tbsmenu == NULL) {
78 rc = ENOMEM;
79 goto error;
80 }
81
82 rc = ui_pbutton_create(res, "Start", &tbsmenu->sbutton);
83 if (rc != EOK)
84 goto error;
85
86 ui_pbutton_set_cb(tbsmenu->sbutton, &tbsmenu_button_cb,
87 (void *)tbsmenu);
88
89 rc = ui_fixed_add(fixed, ui_pbutton_ctl(tbsmenu->sbutton));
90 if (rc != EOK)
91 goto error;
92
93 rc = ui_menu_create(window, &tbsmenu->smenu);
94 if (rc != EOK)
95 goto error;
96
97 ui_menu_set_cb(tbsmenu->smenu, &tbsmenu_smenu_cb, (void *)tbsmenu);
98
99 tbsmenu->window = window;
100 tbsmenu->fixed = fixed;
101 list_initialize(&tbsmenu->entries);
102
103 *rtbsmenu = tbsmenu;
104 return EOK;
105error:
106 if (tbsmenu != NULL)
107 ui_pbutton_destroy(tbsmenu->sbutton);
108 if (tbsmenu != NULL)
109 free(tbsmenu);
110 return rc;
111}
112
113/** Load start menu from repository.
114 *
115 * @param tbsmenu Start menu
116 * @param Repository path
117 * @return EOK on success or an error code
118 */
119errno_t tbsmenu_load(tbsmenu_t *tbsmenu, const char *repopath)
120{
121 ui_menu_entry_t *tentry;
122 startmenu_t *smenu = NULL;
123 startmenu_entry_t *sme;
124 const char *caption;
125 const char *cmd;
126 errno_t rc;
127
128 rc = startmenu_open(repopath, &smenu);
129 if (rc != EOK)
130 goto error;
131
132 sme = startmenu_first(smenu);
133 while (sme != NULL) {
134 caption = startmenu_entry_get_caption(sme);
135 cmd = startmenu_entry_get_cmd(sme);
136
137 rc = ui_menu_entry_create(tbsmenu->smenu, caption, "", &tentry);
138 if (rc != EOK)
139 goto error;
140
141 (void)cmd;
142
143 sme = startmenu_next(sme);
144 }
145
146 startmenu_close(smenu);
147 return EOK;
148error:
149 if (smenu != NULL)
150 startmenu_close(smenu);
151 return rc;
152}
153
154/** Set start menu rectangle.
155 *
156 * @param tbsmenu Start menu
157 * @param rect Rectangle
158 */
159void tbsmenu_set_rect(tbsmenu_t *tbsmenu, gfx_rect_t *rect)
160{
161 tbsmenu->rect = *rect;
162 ui_pbutton_set_rect(tbsmenu->sbutton, rect);
163}
164
165/** Destroy task bar start menu.
166 *
167 * @param tbsmenu Start menu
168 */
169void tbsmenu_destroy(tbsmenu_t *tbsmenu)
170{
171 tbsmenu_entry_t *entry;
172
173 // TODO Close libstartmenu
174
175 /* Destroy entries */
176 entry = tbsmenu_first(tbsmenu);
177 while (entry != NULL) {
178 (void)tbsmenu_remove(tbsmenu, entry, false);
179 entry = tbsmenu_first(tbsmenu);
180 }
181
182 ui_fixed_remove(tbsmenu->fixed, ui_pbutton_ctl(tbsmenu->sbutton));
183 ui_pbutton_destroy(tbsmenu->sbutton);
184 ui_menu_destroy(tbsmenu->smenu);
185
186 free(tbsmenu);
187}
188
189/** Remove entry from strat menu.
190 *
191 * @param tbsmenu Start menu
192 * @param entry Start menu entry
193 * @param paint @c true to repaint start menu
194 * @return @c EOK on success or an error code
195 */
196errno_t tbsmenu_remove(tbsmenu_t *tbsmenu, tbsmenu_entry_t *entry,
197 bool paint)
198{
199 errno_t rc = EOK;
200
201 assert(entry->tbsmenu == tbsmenu);
202
203 list_remove(&entry->lentries);
204
205 // TODO Destroy menu entry
206 free(entry);
207 return rc;
208}
209
210/** Handle start menu close request.
211 *
212 * @param menu Menu
213 * @param arg Argument (tbsmenu_t *)
214 * @param wnd_id Window ID
215 */
216static void tbsmenu_smenu_close_req(ui_menu_t *menu, void *arg)
217{
218 tbsmenu_t *tbsmenu = (tbsmenu_t *)arg;
219
220 (void)tbsmenu;
221 ui_menu_close(menu);
222}
223
224/** Get first start menu entry.
225 *
226 * @param tbsmenu Start menu
227 * @return First entry or @c NULL if the menu is empty
228 */
229tbsmenu_entry_t *tbsmenu_first(tbsmenu_t *tbsmenu)
230{
231 link_t *link;
232
233 link = list_first(&tbsmenu->entries);
234 if (link == NULL)
235 return NULL;
236
237 return list_get_instance(link, tbsmenu_entry_t, lentries);
238}
239
240/** Get last start menu entry.
241 *
242 * @param tbsmenu Start menu
243 * @return Last entry or @c NULL if the menu is empty
244 */
245tbsmenu_entry_t *tbsmenu_last(tbsmenu_t *tbsmenu)
246{
247 link_t *link;
248
249 link = list_last(&tbsmenu->entries);
250 if (link == NULL)
251 return NULL;
252
253 return list_get_instance(link, tbsmenu_entry_t, lentries);
254}
255
256/** Get next start menu entry.
257 *
258 * @param cur Current entry
259 * @return Next entry or @c NULL if @a cur is the last entry
260 */
261tbsmenu_entry_t *tbsmenu_next(tbsmenu_entry_t *cur)
262{
263 link_t *link;
264
265 link = list_next(&cur->lentries, &cur->tbsmenu->entries);
266 if (link == NULL)
267 return NULL;
268
269 return list_get_instance(link, tbsmenu_entry_t, lentries);
270}
271
272/** Get number of start menu entries.
273 *
274 * @param tbsmenu Start menu
275 * @return Number of entries
276 */
277size_t tbsmenu_count(tbsmenu_t *tbsmenu)
278{
279 return list_count(&tbsmenu->entries);
280}
281
282/** Start button was clicked.
283 *
284 * @param pbutton Push button
285 * @param arg Argument (tbsmenu_entry_t *)
286 */
287static void tbsmenu_button_clicked(ui_pbutton_t *pbutton, void *arg)
288{
289 tbsmenu_t *tbsmenu = (tbsmenu_t *)arg;
290
291 if (!ui_menu_is_open(tbsmenu->smenu)) {
292 // XXX ev_pos_id is not set!!!
293 (void) ui_menu_open(tbsmenu->smenu, &tbsmenu->rect,
294 tbsmenu->ev_pos_id);
295 } else {
296 /* menu is open */
297 ui_menu_close(tbsmenu->smenu);
298 }
299}
300
301/** @}
302 */
Note: See TracBrowser for help on using the repository browser.