annotate src/libmlk-ui/ui/gridmenu.c @ 431:8f59201dc76b

core: cleanup hierarchy
author David Demelier <markand@malikania.fr>
date Sat, 15 Oct 2022 20:23:14 +0200
parents d74f53299252
children
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
431
8f59201dc76b core: cleanup hierarchy
David Demelier <markand@malikania.fr>
parents: 411
diff changeset
23 #include <mlk/core/event.h>
8f59201dc76b core: cleanup hierarchy
David Demelier <markand@malikania.fr>
parents: 411
diff changeset
24 #include <mlk/core/maths.h>
8f59201dc76b core: cleanup hierarchy
David Demelier <markand@malikania.fr>
parents: 411
diff changeset
25 #include <mlk/core/painter.h>
8f59201dc76b core: cleanup hierarchy
David Demelier <markand@malikania.fr>
parents: 411
diff changeset
26 #include <mlk/core/panic.h>
8f59201dc76b core: cleanup hierarchy
David Demelier <markand@malikania.fr>
parents: 411
diff changeset
27 #include <mlk/core/texture.h>
8f59201dc76b core: cleanup hierarchy
David Demelier <markand@malikania.fr>
parents: 411
diff changeset
28 #include <mlk/core/trace.h>
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
29
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
30 #include "frame.h"
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
31 #include "label.h"
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
32 #include "gridmenu.h"
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
33 #include "theme.h"
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
34
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
35 #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
36
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
37 struct index {
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
38 unsigned int row;
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
39 unsigned int col;
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
40 };
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 static struct index
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
43 get_index(const struct gridmenu *menu)
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
44 {
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
45 return (struct index) {
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
46 .row = menu->selected / menu->ncols,
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
47 .col = menu->selected % menu->ncols
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
48 };
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 static void
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
52 geometry(struct gridmenu *menu)
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
53 {
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
54 const struct theme *theme = THEME(menu);
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
55 struct label label = {
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
56 .theme = theme,
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
57 .flags = LABEL_FLAGS_SHADOW
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
58 };
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
59 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
60
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
61 /* 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
62 menu->eltw = menu->elth = 0;
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
63 menu->spacew = menu->spaceh = 0;
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
64
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
65 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
66 if (!(label.text = menu->items[i]))
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
67 continue;
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
68
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
69
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
70 label_query(&label, &lw, &lh);
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
71
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
72 menu->eltw = fmax(menu->eltw, lw);
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
73 menu->elth = fmax(menu->elth, lh);
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
74 }
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
75
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
76 /* Total texture size required to draw items. */
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
77 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
78 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
79
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
80 /*
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
81 * 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
82 * is outside of the elements.
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
83 */
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
84 if (reqw > menu->w) {
411
d74f53299252 make: add basic GNU make support
David Demelier <markand@malikania.fr>
parents: 401
diff changeset
85 tracef("gridmenu width is too small: %u < %u", menu->w, reqw);
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
86 menu->spacew = 1;
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
87 } else if (menu->ncols > 1) {
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
88 reqw -= theme->padding * 2;
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
89 menu->spacew = (menu->w - reqw) / menu->ncols;
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
90 }
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
91
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
92 if (reqh > menu->h) {
411
d74f53299252 make: add basic GNU make support
David Demelier <markand@malikania.fr>
parents: 401
diff changeset
93 tracef("gridmenu height is too small: %u < %u", menu->h, reqh);
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
94 menu->spaceh = 1;
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
95 } else if (menu->nrows > 1) {
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
96 reqh -= theme->padding * 2;
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
97 menu->spaceh = (menu->h - reqh) / menu->nrows;
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
98 }
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 static void
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
102 draw_frame(const struct gridmenu *menu)
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
103 {
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
104 const struct frame f = {
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
105 .x = menu->x,
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
106 .y = menu->y,
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
107 .w = menu->w,
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
108 .h = menu->h,
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
109 .theme = menu->theme,
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
110 };
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 frame_draw(&f);
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
113 }
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 static void
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
116 draw_labels(const struct gridmenu *menu)
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
117 {
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
118 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
119 struct label label = {0};
396
c9769a77ad8c ui: avoid copying theme
David Demelier <markand@malikania.fr>
parents: 395
diff changeset
120 const struct theme *theme = THEME(menu);
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
121
396
c9769a77ad8c ui: avoid copying theme
David Demelier <markand@malikania.fr>
parents: 395
diff changeset
122 label.theme = theme;
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
123 label.flags = LABEL_FLAGS_SHADOW;
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
124
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
125 /*
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
126 * 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
127 * the number of rows/columns.
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
128 */
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
129 pagesz = menu->nrows * menu->ncols;
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
130 pagenr = menu->selected / pagesz;
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
131
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
132 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
133 item = i + pagenr * pagesz;
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
134
398
14ce7c4871e3 rpg: overhaul of battle bar
David Demelier <markand@malikania.fr>
parents: 396
diff changeset
135 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
136 continue;
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
137
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
138 label.text = menu->items[item];
396
c9769a77ad8c ui: avoid copying theme
David Demelier <markand@malikania.fr>
parents: 395
diff changeset
139 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
140 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
141
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
142 if (i == menu->selected % pagesz)
396
c9769a77ad8c ui: avoid copying theme
David Demelier <markand@malikania.fr>
parents: 395
diff changeset
143 label.flags |= LABEL_FLAGS_SELECTED;
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
144 else
396
c9769a77ad8c ui: avoid copying theme
David Demelier <markand@malikania.fr>
parents: 395
diff changeset
145 label.flags &= ~(LABEL_FLAGS_SELECTED);
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
146
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
147 label_draw(&label);
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
148
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
149 if (++c >= menu->ncols) {
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
150 ++r;
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
151 c = 0;
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
152 }
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
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
156 static int
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
157 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
158 {
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
159 assert(key->type == EVENT_KEYDOWN);
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
160
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
161 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
162 int validate = 0;
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
163
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
164 switch (key->key) {
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
165 case KEY_UP:
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
166 if (idx.row > 0)
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
167 menu->selected -= menu->ncols;
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
168 break;
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
169 case KEY_RIGHT:
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
170 if (menu->selected + 1U < menu->itemsz)
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
171 menu->selected += 1;
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
172 break;
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
173 case KEY_DOWN:
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
174 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
175 menu->selected += menu->ncols;
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
176 else
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
177 menu->selected = menu->itemsz - 1;
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
178 break;
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
179 case KEY_LEFT:
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
180 if (idx.col > 0)
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
181 menu->selected -= 1;
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
182 break;
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
183 case KEY_ENTER:
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
184 validate = 1;
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
185 break;
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
186 default:
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
187 break;
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
188 }
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
189
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
190 return validate;
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
191 }
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
192
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
193 static int
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
194 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
195 {
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
196 assert(click->type == EVENT_CLICKDOWN);
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
197
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
198 const struct theme *theme = THEME(menu);
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
199 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
200 int x, y;
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
201
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
202 pagesz = menu->nrows * menu->ncols;
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
203 pagenr = menu->selected / pagesz;
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
204
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
205 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
206 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
207 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
208
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
209 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
210 selected = c + r * menu->ncols;
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
211 selected += pagesz * pagenr;
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
212
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
213 if (selected < menu->itemsz) {
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
214 menu->selected = selected;
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
215 return 1;
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
216 }
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 if (++c >= menu->ncols) {
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
220 ++r;
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
221 c = 0;
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
222 }
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
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
225 return 0;
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
226 }
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 void
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
229 gridmenu_init(struct gridmenu *menu,
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
230 unsigned int nr,
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
231 unsigned int nc,
401
df5e1fea1d2e ui: gridmenu should be fully constified
David Demelier <markand@malikania.fr>
parents: 398
diff changeset
232 const char * const *items,
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
233 size_t itemsz)
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
234 {
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
235 assert(menu);
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
236 assert(nr);
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
237 assert(nc);
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
238
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
239 memset(menu, 0, sizeof (*menu));
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
240
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
241 menu->nrows = nr;
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
242 menu->ncols = nc;
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
243 menu->items = items;
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
244 menu->itemsz = itemsz;
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
245 }
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 void
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
248 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
249 {
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
250 assert(menu);
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
251
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
252 menu->x = x;
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
253 menu->y = y;
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
254 menu->w = w;
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
255 menu->h = h;
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
256
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
257 geometry(menu);
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
258 }
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
259
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
260 int
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
261 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
262 {
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
263 assert(menu);
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
264 assert(ev);
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
265
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
266 switch (ev->type) {
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
267 case EVENT_KEYDOWN:
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
268 return handle_keydown(menu, &ev->key);
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
269 break;
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
270 case EVENT_CLICKDOWN:
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
271 return handle_clickdown(menu, &ev->click);
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
272 break;
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
273 default:
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
274 break;
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
275 }
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
276
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
277 return 0;
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
278 }
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 void
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
281 gridmenu_draw(const struct gridmenu *menu)
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
282 {
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
283 assert(menu);
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
284
395
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
285 draw_frame(menu);
ef2fc4442ed5 ui: don't use fixed size arrays
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
286 draw_labels(menu);
181
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
287 }