annotate src/libmlk-ui/ui/gridmenu.c @ 401:df5e1fea1d2e

ui: gridmenu should be fully constified
author David Demelier <markand@malikania.fr>
date Wed, 16 Mar 2022 13:37:56 +0100
parents 14ce7c4871e3
children d74f53299252
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
1 /*
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
2 * gridmenu.c -- GUI grid menu
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
3 *
378
460c78706989 misc: update copyright years
David Demelier <markand@malikania.fr>
parents: 320
diff changeset
4 * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr>
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
5 *
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
6 * Permission to use, copy, modify, and/or distribute this software for any
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
7 * purpose with or without fee is hereby granted, provided that the above
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
8 * copyright notice and this permission notice appear in all copies.
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
9 *
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
17 */
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
18
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
19 #include <assert.h>
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
20 #include <math.h>
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
21 #include <string.h>
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
22
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
23 #include <core/event.h>
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
24 #include <core/maths.h>
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
25 #include <core/painter.h>
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
26 #include <core/panic.h>
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
27 #include <core/texture.h>
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
28 #include <core/trace.h>
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
29
241
76afe639fd72 misc: add support for NLS, closes #22510 @4h
David Demelier <markand@malikania.fr>
parents: 192
diff changeset
30 #include "ui_p.h"
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
31 #include "frame.h"
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
32 #include "label.h"
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
33 #include "gridmenu.h"
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
34 #include "theme.h"
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
35
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
36 #define THEME(m) ((m)->theme ? (m)->theme : theme_default())
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
37
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
38 struct index {
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
39 unsigned int row;
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
40 unsigned int col;
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
41 };
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
42
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
43 static struct index
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
44 get_index(const struct gridmenu *menu)
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
45 {
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
46 return (struct index) {
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
47 .row = menu->selected / menu->ncols,
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
48 .col = menu->selected % menu->ncols
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
49 };
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
50 }
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
51
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
52 static void
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
53 geometry(struct gridmenu *menu)
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
54 {
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
55 const struct theme *theme = THEME(menu);
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
56 struct label label = {
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
57 .theme = theme,
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
58 .flags = LABEL_FLAGS_SHADOW
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
59 };
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
60 unsigned int reqw = 0, reqh = 0, lw, lh;
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
61
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
62 /* Compute which item has the bigger width/height to create a spacing. */
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
63 menu->eltw = menu->elth = 0;
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
64 menu->spacew = menu->spaceh = 0;
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
65
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
66 for (size_t i = 0; i < menu->itemsz; ++i) {
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
67 if (!(label.text = menu->items[i]))
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
68 continue;
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
69
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
70
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
71 label_query(&label, &lw, &lh);
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
72
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
73 menu->eltw = fmax(menu->eltw, lw);
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
74 menu->elth = fmax(menu->elth, lh);
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
75 }
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
76
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
77 /* Total texture size required to draw items. */
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
78 reqw = (theme->padding * 2) + (menu->eltw * menu->ncols);
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
79 reqh = (theme->padding * 2) + (menu->elth * menu->nrows);
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
80
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
81 /*
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
82 * Compute spacing between elements. We remove the padding because it
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
83 * is outside of the elements.
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
84 */
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
85 if (reqw > menu->w) {
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
86 tracef(_("gridmenu width is too small: %u < %u"), menu->w, reqw);
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
87 menu->spacew = 1;
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
88 } else if (menu->ncols > 1) {
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
89 reqw -= theme->padding * 2;
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
90 menu->spacew = (menu->w - reqw) / menu->ncols;
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
91 }
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
92
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
93 if (reqh > menu->h) {
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
94 tracef(_("gridmenu height is too small: %u < %u"), menu->h, reqh);
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
95 menu->spaceh = 1;
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
96 } else if (menu->nrows > 1) {
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
97 reqh -= theme->padding * 2;
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
98 menu->spaceh = (menu->h - reqh) / menu->nrows;
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
99 }
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
100 }
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
101
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
102 static void
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
103 draw_frame(const struct gridmenu *menu)
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
104 {
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
105 const struct frame f = {
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
106 .x = menu->x,
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
107 .y = menu->y,
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
108 .w = menu->w,
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
109 .h = menu->h,
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
110 .theme = menu->theme,
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
111 };
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
112
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
113 frame_draw(&f);
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
114 }
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
115
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
116 static void
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
117 draw_labels(const struct gridmenu *menu)
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
118 {
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
119 size_t pagesz, pagenr, item, c = 0, r = 0;
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
120 struct label label = {0};
396
c9769a77ad8c ui: avoid copying theme
David Demelier <markand@malikania.fr>
parents: 395
diff changeset
121 const struct theme *theme = THEME(menu);
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
122
396
c9769a77ad8c ui: avoid copying theme
David Demelier <markand@malikania.fr>
parents: 395
diff changeset
123 label.theme = theme;
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
124 label.flags = LABEL_FLAGS_SHADOW;
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
125
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
126 /*
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
127 * Select the first top-left column based on the current selection and
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
128 * the number of rows/columns.
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
129 */
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
130 pagesz = menu->nrows * menu->ncols;
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
131 pagenr = menu->selected / pagesz;
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
132
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
133 for (size_t i = 0; i < pagesz; ++i) {
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
134 item = i + pagenr * pagesz;
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
135
398
14ce7c4871e3 rpg: overhaul of battle bar
David Demelier <markand@malikania.fr>
parents: 396
diff changeset
136 if (item >= menu->itemsz || !menu->items[item])
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
137 continue;
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
138
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
139 label.text = menu->items[item];
396
c9769a77ad8c ui: avoid copying theme
David Demelier <markand@malikania.fr>
parents: 395
diff changeset
140 label.x = menu->x + theme->padding + (c * menu->eltw) + (c * menu->spacew);
c9769a77ad8c ui: avoid copying theme
David Demelier <markand@malikania.fr>
parents: 395
diff changeset
141 label.y = menu->y + theme->padding + (r * menu->elth) + (r * menu->spaceh);
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
142
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
143 if (i == menu->selected % pagesz)
396
c9769a77ad8c ui: avoid copying theme
David Demelier <markand@malikania.fr>
parents: 395
diff changeset
144 label.flags |= LABEL_FLAGS_SELECTED;
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
145 else
396
c9769a77ad8c ui: avoid copying theme
David Demelier <markand@malikania.fr>
parents: 395
diff changeset
146 label.flags &= ~(LABEL_FLAGS_SELECTED);
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
147
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
148 label_draw(&label);
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
149
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
150 if (++c >= menu->ncols) {
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
151 ++r;
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
152 c = 0;
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
153 }
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
154 }
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
155 }
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
156
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
157 static int
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
158 handle_keydown(struct gridmenu *menu, const struct event_key *key)
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
159 {
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
160 assert(key->type == EVENT_KEYDOWN);
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
161
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
162 const struct index idx = get_index(menu);
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
163 int validate = 0;
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
164
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
165 switch (key->key) {
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
166 case KEY_UP:
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
167 if (idx.row > 0)
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
168 menu->selected -= menu->ncols;
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
169 break;
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
170 case KEY_RIGHT:
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
171 if (menu->selected + 1U < menu->itemsz)
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
172 menu->selected += 1;
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
173 break;
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
174 case KEY_DOWN:
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
175 if (idx.row + 1U < menu->itemsz / menu->ncols)
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
176 menu->selected += menu->ncols;
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
177 else
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
178 menu->selected = menu->itemsz - 1;
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
179 break;
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
180 case KEY_LEFT:
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
181 if (idx.col > 0)
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
182 menu->selected -= 1;
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
183 break;
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
184 case KEY_ENTER:
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
185 validate = 1;
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
186 break;
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
187 default:
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
188 break;
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
189 }
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
190
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
191 return validate;
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
192 }
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
193
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
194 static int
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
195 handle_clickdown(struct gridmenu *menu, const struct event_click *click)
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
196 {
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
197 assert(click->type == EVENT_CLICKDOWN);
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
198
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
199 const struct theme *theme = THEME(menu);
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
200 size_t pagesz, pagenr, selected, c = 0, r = 0;
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
201 int x, y;
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
202
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
203 pagesz = menu->nrows * menu->ncols;
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
204 pagenr = menu->selected / pagesz;
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
205
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
206 for (size_t i = 0; i < pagesz; ++i) {
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
207 x = menu->x + theme->padding + (c * menu->eltw) + (c * menu->spacew);
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
208 y = menu->y + theme->padding + (r * menu->elth) + (r * menu->spaceh);
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
209
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
210 if (maths_is_boxed(x, y, menu->eltw, menu->elth, click->x, click->y)) {
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
211 selected = c + r * menu->ncols;
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
212 selected += pagesz * pagenr;
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
213
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
214 if (selected < menu->itemsz) {
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
215 menu->selected = selected;
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
216 return 1;
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
217 }
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
218 }
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
219
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
220 if (++c >= menu->ncols) {
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
221 ++r;
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
222 c = 0;
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
223 }
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
224 }
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
225
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
226 return 0;
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
227 }
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
228
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
229 void
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
230 gridmenu_init(struct gridmenu *menu,
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
231 unsigned int nr,
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
232 unsigned int nc,
401
df5e1fea1d2e ui: gridmenu should be fully constified
David Demelier <markand@malikania.fr>
parents: 398
diff changeset
233 const char * const *items,
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
234 size_t itemsz)
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
235 {
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
236 assert(menu);
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
237 assert(nr);
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
238 assert(nc);
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
239
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
240 memset(menu, 0, sizeof (*menu));
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
241
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
242 menu->nrows = nr;
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
243 menu->ncols = nc;
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
244 menu->items = items;
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
245 menu->itemsz = itemsz;
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
246 }
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
247
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
248 void
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
249 gridmenu_resize(struct gridmenu *menu, int x, int y, unsigned int w, unsigned int h)
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
250 {
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
251 assert(menu);
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
252
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
253 menu->x = x;
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
254 menu->y = y;
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
255 menu->w = w;
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
256 menu->h = h;
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
257
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
258 geometry(menu);
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
259 }
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
260
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
261 int
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
262 gridmenu_handle(struct gridmenu *menu, const union event *ev)
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
263 {
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
264 assert(menu);
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
265 assert(ev);
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
266
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
267 switch (ev->type) {
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
268 case EVENT_KEYDOWN:
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
269 return handle_keydown(menu, &ev->key);
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
270 break;
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
271 case EVENT_CLICKDOWN:
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
272 return handle_clickdown(menu, &ev->click);
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
273 break;
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
274 default:
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
275 break;
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
276 }
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
277
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
278 return 0;
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
279 }
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
280
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
281 void
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
282 gridmenu_draw(const struct gridmenu *menu)
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
283 {
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
284 assert(menu);
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
285
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
286 draw_frame(menu);
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
287 draw_labels(menu);
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
288 }