source: mainline/uspace/lib/ui/src/tabset.c@ b169619

topic/msim-upgrade topic/simplify-dev-export
Last change on this file since b169619 was 1eaead4, checked in by Jiri Svoboda <jiri@…>, 2 years ago

Tab set control

This allows to expand the space available in a dialog window
using stacking, with individual tabs that can be activated
by clicking the handle.

  • Property mode set to 100644
File size: 6.4 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 Tab set
34 */
35
36#include <adt/list.h>
37#include <errno.h>
38#include <gfx/render.h>
39#include <io/pos_event.h>
40#include <stdlib.h>
41#include <ui/control.h>
42#include <ui/tab.h>
43#include <ui/tabset.h>
44#include <ui/window.h>
45#include "../private/tab.h"
46#include "../private/tabset.h"
47#include "../private/resource.h"
48
49static void ui_tab_set_ctl_destroy(void *);
50static errno_t ui_tab_set_ctl_paint(void *);
51static ui_evclaim_t ui_tab_set_ctl_kbd_event(void *, kbd_event_t *);
52static ui_evclaim_t ui_tab_set_ctl_pos_event(void *, pos_event_t *);
53
54/** Tab set control ops */
55ui_control_ops_t ui_tab_set_ops = {
56 .destroy = ui_tab_set_ctl_destroy,
57 .paint = ui_tab_set_ctl_paint,
58 .kbd_event = ui_tab_set_ctl_kbd_event,
59 .pos_event = ui_tab_set_ctl_pos_event
60};
61
62/** Create new tab set.
63 *
64 * @param res UI resource
65 * @param rtabset Place to store pointer to new tab set
66 * @return EOK on success, ENOMEM if out of memory
67 */
68errno_t ui_tab_set_create(ui_resource_t *res, ui_tab_set_t **rtabset)
69{
70 ui_tab_set_t *tabset;
71 errno_t rc;
72
73 tabset = calloc(1, sizeof(ui_tab_set_t));
74 if (tabset == NULL)
75 return ENOMEM;
76
77 rc = ui_control_new(&ui_tab_set_ops, (void *) tabset, &tabset->control);
78 if (rc != EOK) {
79 free(tabset);
80 return rc;
81 }
82
83 tabset->res = res;
84 list_initialize(&tabset->tabs);
85 *rtabset = tabset;
86 return EOK;
87}
88
89/** Destroy tab set
90 *
91 * @param tabset Tab set or @c NULL
92 */
93void ui_tab_set_destroy(ui_tab_set_t *tabset)
94{
95 ui_tab_t *tab;
96
97 if (tabset == NULL)
98 return;
99
100 /* Destroy tabs */
101 tab = ui_tab_first(tabset);
102 while (tab != NULL) {
103 ui_tab_destroy(tab);
104 tab = ui_tab_first(tabset);
105 }
106
107 ui_control_delete(tabset->control);
108 free(tabset);
109}
110
111/** Get base control from tab set.
112 *
113 * @param tabset Tab set
114 * @return Control
115 */
116ui_control_t *ui_tab_set_ctl(ui_tab_set_t *tabset)
117{
118 return tabset->control;
119}
120
121/** Set tab set rectangle.
122 *
123 * @param tabset Tab set
124 * @param rect New tab set rectangle
125 */
126void ui_tab_set_set_rect(ui_tab_set_t *tabset, gfx_rect_t *rect)
127{
128 tabset->rect = *rect;
129}
130
131/** Paint tab set.
132 *
133 * @param tabset Tab set
134 * @return EOK on success or an error code
135 */
136errno_t ui_tab_set_paint(ui_tab_set_t *tabset)
137{
138 ui_resource_t *res;
139 ui_tab_t *tab;
140 errno_t rc;
141
142 res = tabset->res;
143
144 if (tabset->selected != NULL) {
145 rc = ui_tab_paint_body_frame(tabset->selected);
146 if (rc != EOK)
147 goto error;
148 }
149
150 tab = ui_tab_first(tabset);
151 while (tab != NULL) {
152 rc = ui_tab_paint(tab);
153 if (rc != EOK)
154 return rc;
155
156 tab = ui_tab_next(tab);
157 }
158
159 rc = gfx_update(res->gc);
160 if (rc != EOK)
161 goto error;
162
163 return EOK;
164error:
165 return rc;
166}
167
168/** Select or deselect tab from tab set.
169 *
170 * Select @a tab. If @a tab is @c NULL or it is already selected,
171 * then select none.
172 *
173 * @param tabset Tab set
174 * @param tab Tab to select (or deselect if selected) or @c NULL
175 */
176void ui_tab_set_select(ui_tab_set_t *tabset, ui_tab_t *tab)
177{
178 tabset->selected = tab;
179 (void) ui_tab_set_paint(tabset);
180}
181
182/** Handle tab set keyboard event.
183 *
184 * @param tabset Tab set
185 * @param kbd_event Keyboard event
186 * @return @c ui_claimed iff the event is claimed
187 */
188ui_evclaim_t ui_tab_set_kbd_event(ui_tab_set_t *tabset, kbd_event_t *event)
189{
190 ui_tab_t *tab;
191 ui_evclaim_t claim;
192
193 tab = ui_tab_first(tabset);
194 while (tab != NULL) {
195 claim = ui_tab_kbd_event(tab, event);
196 if (claim == ui_claimed)
197 return ui_claimed;
198
199 tab = ui_tab_next(tab);
200 }
201
202 return ui_unclaimed;
203}
204
205/** Handle tab set position event.
206 *
207 * @param tabset Tab set
208 * @param pos_event Position event
209 * @return @c ui_claimed iff the event is claimed
210 */
211ui_evclaim_t ui_tab_set_pos_event(ui_tab_set_t *tabset, pos_event_t *event)
212{
213 ui_tab_t *tab;
214 ui_evclaim_t claim;
215
216 tab = ui_tab_first(tabset);
217 while (tab != NULL) {
218 claim = ui_tab_pos_event(tab, event);
219 if (claim == ui_claimed)
220 return ui_claimed;
221
222 tab = ui_tab_next(tab);
223 }
224
225 return ui_unclaimed;
226}
227
228/** Destroy tab set control.
229 *
230 * @param arg Argument (ui_tab_set_t *)
231 */
232static void ui_tab_set_ctl_destroy(void *arg)
233{
234 ui_tab_set_t *tabset = (ui_tab_set_t *) arg;
235
236 ui_tab_set_destroy(tabset);
237}
238
239/** Paint tab set control.
240 *
241 * @param arg Argument (ui_tab_set_t *)
242 * @return EOK on success or an error code
243 */
244static errno_t ui_tab_set_ctl_paint(void *arg)
245{
246 ui_tab_set_t *tabset = (ui_tab_set_t *) arg;
247
248 return ui_tab_set_paint(tabset);
249}
250
251/** Handle tab set control keyboard event.
252 *
253 * @param arg Argument (ui_tab_set_t *)
254 * @param pos_event Position event
255 * @return @c ui_claimed iff the event is claimed
256 */
257static ui_evclaim_t ui_tab_set_ctl_kbd_event(void *arg, kbd_event_t *event)
258{
259 ui_tab_set_t *tabset = (ui_tab_set_t *) arg;
260
261 return ui_tab_set_kbd_event(tabset, event);
262}
263
264/** Handle tab set control position event.
265 *
266 * @param arg Argument (ui_tab_set_t *)
267 * @param pos_event Position event
268 * @return @c ui_claimed iff the event is claimed
269 */
270static ui_evclaim_t ui_tab_set_ctl_pos_event(void *arg, pos_event_t *event)
271{
272 ui_tab_set_t *tabset = (ui_tab_set_t *) arg;
273
274 return ui_tab_set_pos_event(tabset, event);
275}
276
277/** @}
278 */
Note: See TracBrowser for help on using the repository browser.