source: mainline/uspace/lib/ui/src/menudd.c@ 46bd63c9

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

Split drop-down menu into two classes: drop-down and menu

Naming is clearly the hardest problem in computer science.

  • Property mode set to 100644
File size: 7.2 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 libui
30 * @{
31 */
32/**
33 * @file Menu drop-down
34 *
35 * One of the drop-down menus of a menu bar. This class takes the generic
36 * ui_menu and ties it to the menu bar.
37 */
38
39#include <adt/list.h>
40#include <errno.h>
41#include <stdlib.h>
42#include <str.h>
43#include <ui/accel.h>
44#include <ui/menu.h>
45#include <ui/menudd.h>
46#include <ui/menubar.h>
47#include <ui/resource.h>
48#include "../private/menubar.h"
49#include "../private/menudd.h"
50
51static void ui_menu_dd_left(ui_menu_t *, void *, sysarg_t);
52static void ui_menu_dd_right(ui_menu_t *, void *, sysarg_t);
53static void ui_menu_dd_close_req(ui_menu_t *, void *);
54static void ui_menu_dd_press_accel(ui_menu_t *, void *, char32_t, sysarg_t);
55
56static ui_menu_cb_t ui_menu_dd_menu_cb = {
57 .left = ui_menu_dd_left,
58 .right = ui_menu_dd_right,
59 .close_req = ui_menu_dd_close_req,
60 .press_accel = ui_menu_dd_press_accel
61};
62
63/** Create new menu drop-down.
64 *
65 * @param mbar Menu bar
66 * @param caption Caption
67 * @param rmdd Place to store pointer to new menu drop-down or @c NULL
68 * @param rmenu Place to store pointer to new menu or @c NULL
69 * @return EOK on success, ENOMEM if out of memory
70 */
71errno_t ui_menu_dd_create(ui_menu_bar_t *mbar, const char *caption,
72 ui_menu_dd_t **rmdd, ui_menu_t **rmenu)
73{
74 errno_t rc;
75 ui_menu_dd_t *mdd;
76
77 mdd = calloc(1, sizeof(ui_menu_dd_t));
78 if (mdd == NULL)
79 return ENOMEM;
80
81 mdd->caption = str_dup(caption);
82 if (mdd->caption == NULL) {
83 free(mdd);
84 return ENOMEM;
85 }
86
87 /* Create menu */
88 rc = ui_menu_create(mbar->window, &mdd->menu);
89 if (rc != EOK) {
90 free(mdd->caption);
91 free(mdd);
92 return rc;
93 }
94
95 mdd->mbar = mbar;
96 list_append(&mdd->lmenudds, &mbar->menudds);
97
98 ui_menu_set_cb(mdd->menu, &ui_menu_dd_menu_cb, (void *)mdd);
99
100 if (rmdd != NULL)
101 *rmdd = mdd;
102 if (rmenu != NULL)
103 *rmenu = mdd->menu;
104 return EOK;
105}
106
107/** Destroy menu drop-down.
108 *
109 * @param menu Menu or @c NULL
110 */
111void ui_menu_dd_destroy(ui_menu_dd_t *mdd)
112{
113 if (mdd == NULL)
114 return;
115
116 /* Destroy menu */
117 ui_menu_destroy(mdd->menu);
118
119 list_remove(&mdd->lmenudds);
120 free(mdd->caption);
121 free(mdd);
122}
123
124/** Get first menu drop-down in menu bar.
125 *
126 * @param mbar Menu bar
127 * @return First menu or @c NULL if there is none
128 */
129ui_menu_dd_t *ui_menu_dd_first(ui_menu_bar_t *mbar)
130{
131 link_t *link;
132
133 link = list_first(&mbar->menudds);
134 if (link == NULL)
135 return NULL;
136
137 return list_get_instance(link, ui_menu_dd_t, lmenudds);
138}
139
140/** Get next menu drop-down in menu bar.
141 *
142 * @param cur Current menu drop-down
143 * @return Next menu drop-down or @c NULL if @a cur is the last one
144 */
145ui_menu_dd_t *ui_menu_dd_next(ui_menu_dd_t *cur)
146{
147 link_t *link;
148
149 link = list_next(&cur->lmenudds, &cur->mbar->menudds);
150 if (link == NULL)
151 return NULL;
152
153 return list_get_instance(link, ui_menu_dd_t, lmenudds);
154}
155
156/** Get last menu drop-down in menu bar.
157 *
158 * @param mbar Menu bar
159 * @return Last menu drop-down or @c NULL if there is none
160 */
161ui_menu_dd_t *ui_menu_dd_last(ui_menu_bar_t *mbar)
162{
163 link_t *link;
164
165 link = list_last(&mbar->menudds);
166 if (link == NULL)
167 return NULL;
168
169 return list_get_instance(link, ui_menu_dd_t, lmenudds);
170}
171
172/** Get previous menu drop-down in menu bar.
173 *
174 * @param cur Current menu drop-down
175 * @return Previous menu drop-down or @c NULL if @a cur is the fist one
176 */
177ui_menu_dd_t *ui_menu_dd_prev(ui_menu_dd_t *cur)
178{
179 link_t *link;
180
181 link = list_prev(&cur->lmenudds, &cur->mbar->menudds);
182 if (link == NULL)
183 return NULL;
184
185 return list_get_instance(link, ui_menu_dd_t, lmenudds);
186}
187
188/** Get menu drop-down caption.
189 *
190 * @param mdd Menu drop-down
191 * @return Caption (owned by @a menu)
192 */
193const char *ui_menu_dd_caption(ui_menu_dd_t *mdd)
194{
195 return mdd->caption;
196}
197
198/** Get menu drop-down accelerator character.
199 *
200 * @param mdd Menu drop-down
201 * @return Accelerator character (lowercase) or the null character if
202 * the menu has no accelerator.
203 */
204char32_t ui_menu_dd_get_accel(ui_menu_dd_t *mdd)
205{
206 return ui_accel_get(mdd->caption);
207}
208
209/** Open menu drop-down.
210 *
211 * @param mdd Menu drop-down
212 * @param prect Parent rectangle around which the drop-down should be placed
213 * @param idev_id Input device associated with the drop-down's seat
214 */
215errno_t ui_menu_dd_open(ui_menu_dd_t *mdd, gfx_rect_t *prect, sysarg_t idev_id)
216{
217 return ui_menu_open(mdd->menu, prect, idev_id);
218}
219
220/** Close menu drop-down.
221 *
222 * @param mdd Menu drop-down
223 */
224void ui_menu_dd_close(ui_menu_dd_t *mdd)
225{
226 ui_menu_close(mdd->menu);
227}
228
229/** Determine if menu drop-down is open.
230 *
231 * @param mdd Menu drop-down
232 * @return @c true iff menu drop-down is open
233 */
234bool ui_menu_dd_is_open(ui_menu_dd_t *mdd)
235{
236 return ui_menu_is_open(mdd->menu);
237}
238
239/** Handle menu left event.
240 *
241 * @param menu Menu
242 * @param arg Argument (ui_menu_dd_t *)
243 * @param idev_id Input device ID
244 */
245static void ui_menu_dd_left(ui_menu_t *menu, void *arg, sysarg_t idev_id)
246{
247 ui_menu_dd_t *mdd = (ui_menu_dd_t *)arg;
248
249 (void)menu;
250
251 ui_menu_bar_left(mdd->mbar, idev_id);
252}
253
254/** Handle menu right event.
255 *
256 * @param menu Menu
257 * @param arg Argument (ui_menu_dd_t *)
258 * @param idev_id Input device ID
259 */
260static void ui_menu_dd_right(ui_menu_t *menu, void *arg, sysarg_t idev_id)
261{
262 ui_menu_dd_t *mdd = (ui_menu_dd_t *)arg;
263
264 (void)menu;
265
266 ui_menu_bar_right(mdd->mbar, idev_id);
267}
268
269/** Handle menu close request.
270 *
271 * @param menu Menu
272 * @param arg Argument (ui_menu_dd_t *)
273 */
274static void ui_menu_dd_close_req(ui_menu_t *menu, void *arg)
275{
276 ui_menu_dd_t *mdd = (ui_menu_dd_t *)arg;
277
278 (void)menu;
279 ui_menu_bar_deactivate(mdd->mbar);
280}
281
282/** Handle menu accelerator key press event.
283 *
284 * @param menu Menu
285 * @param arg Argument (ui_menu_dd_t *)
286 * @param c Character
287 * @param kbd_id Keyboard ID
288 */
289static void ui_menu_dd_press_accel(ui_menu_t *menu, void *arg, char32_t c,
290 sysarg_t kbd_id)
291{
292 ui_menu_dd_t *mdd = (ui_menu_dd_t *)arg;
293
294 (void)menu;
295 ui_menu_bar_press_accel(mdd->mbar, c, kbd_id);
296}
297
298/** @}
299 */
Note: See TracBrowser for help on using the repository browser.