annotate libui/ui/gridmenu.c @ 191:633a25df450e

molko-js: miscellaneous fixes While here, import sphinx as experimental documentation.
author David Demelier <markand@malikania.fr>
date Sat, 07 Nov 2020 15:40:34 +0100
parents 867b60e6258a
children 4ad7420ab678
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 *
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
4 * Copyright (c) 2020 David Demelier <markand@malikania.fr>
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>
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
20 #include <string.h>
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
21
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
22 #include <core/event.h>
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
23 #include <core/maths.h>
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
24 #include <core/painter.h>
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
25 #include <core/panic.h>
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
26 #include <core/texture.h>
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
27 #include <core/trace.h>
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
28
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
29 #include "frame.h"
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
30 #include "label.h"
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
31 #include "gridmenu.h"
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
32 #include "theme.h"
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
33
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
34 #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
35
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
36 struct index {
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
37 unsigned int row;
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
38 unsigned int col;
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
39 };
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 static struct index
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
42 get_index(const struct gridmenu *menu)
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
43 {
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
44 return (struct index) {
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
45 .row = menu->selected / menu->ncols,
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
46 .col = menu->selected % menu->ncols
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
47 };
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 static void
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
51 positionate(struct gridmenu *menu)
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
52 {
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
53 const struct theme *theme = THEME(menu);
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
54 struct gridmenu_texture *gtex = &menu->tex;
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
55 unsigned int vreq, hreq;
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
56
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
57 /* Compute which item has the bigger width to create a spacing. */
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
58 for (size_t i = 0; i < GRIDMENU_ENTRY_MAX; ++i) {
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
59 unsigned int lw, lh;
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
60
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
61 gtex->labels[i].theme = theme;
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
62 gtex->labels[i].flags = LABEL_FLAGS_SHADOW;
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
63
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
64 if (!(gtex->labels[i].text = menu->menu[i]))
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
65 continue;
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
66
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
67 label_query(&gtex->labels[i], &lw, &lh);
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
68 gtex->eltw = lw > gtex->eltw ? lw : gtex->eltw;
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
69 gtex->elth = lh > gtex->elth ? lh : gtex->elth;
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
70 }
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
71
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
72 vreq = (theme->padding * 2) + (gtex->elth * menu->nrows);
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
73 hreq = (theme->padding * 2) + (gtex->eltw * menu->ncols);
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 /* Compute spacing between elements. */
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
76 if (hreq > menu->w) {
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
77 tracef("gridmenu width is too small: %u < %u", menu->w, vreq);
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
78 gtex->spaceh = 1;
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
79 } else {
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
80 hreq -= theme->padding * 2;
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
81 gtex->spaceh = (menu->w - hreq) / menu->ncols;
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
82 }
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
83
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
84 if (vreq > menu->h) {
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
85 tracef("gridmenu height is too small: %u < %u", menu->h, vreq);
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
86 gtex->spacev = 1;
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
87 } else {
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
88 vreq -= theme->padding * 2;
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
89 gtex->spacev = (menu->h - vreq) / menu->nrows;
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
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
92 /* This is the whole height. */
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
93 gtex->relh = theme->padding * 2;
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
94 gtex->relh += gtex->elth * (GRIDMENU_ENTRY_MAX / menu->ncols);
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
95 gtex->relh += gtex->spacev * (GRIDMENU_ENTRY_MAX / menu->ncols);
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
96 }
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
97
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
98 static void
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
99 repaint_frame(struct gridmenu *menu)
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 const struct frame f = {
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
102 .x = 0,
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
103 .y = menu->tex.rely,
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
104 .w = menu->w,
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
105 .h = menu->h,
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
106 .theme = menu->theme,
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
107 };
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
108
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
109 frame_draw(&f);
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 static void
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
113 repaint_labels(struct gridmenu *menu)
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 struct theme theme;
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
116 unsigned int r = 0, c = 0;
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
117
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
118 /* Copy theme to change color if selected. */
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
119 theme_shallow(&theme, THEME(menu));
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
120
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
121 for (size_t i = 0; i < GRIDMENU_ENTRY_MAX; ++i) {
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
122 struct label *l = &menu->tex.labels[i];
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
123
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
124 if (i == menu->selected)
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
125 theme.colors[THEME_COLOR_NORMAL] = THEME(menu)->colors[THEME_COLOR_SELECTED];
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
126 else
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
127 theme.colors[THEME_COLOR_NORMAL] = THEME(menu)->colors[THEME_COLOR_NORMAL];
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
128
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
129 l->theme = &theme;
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
130 l->x = theme.padding + (c * menu->tex.eltw) + (c * menu->tex.spaceh);
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
131 l->y = theme.padding + (r * menu->tex.elth) + (r * menu->tex.spacev);
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
132
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
133 if (++c >= menu->ncols) {
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
134 ++r;
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
135 c = 0;
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
136 }
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
137
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
138 if (l->text)
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
139 label_draw(l);
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
140 }
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
141 }
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
142
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
143 static void
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
144 repaint(struct gridmenu *menu)
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
145 {
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
146 struct texture *tex = &menu->tex.texture;
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
147
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
148 if (!texture_ok(tex) && !texture_new(tex, menu->w, menu->tex.relh))
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
149 panic();
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
150
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
151 PAINTER_BEGIN(tex);
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 painter_clear();
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
154 repaint_frame(menu);
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
155 repaint_labels(menu);
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
156
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
157 PAINTER_END();
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
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
160 static void
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
161 zoom(struct gridmenu *menu)
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
162 {
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
163 struct gridmenu_texture *tex = &menu->tex;
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
164 struct label *cur = &tex->labels[menu->selected];
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
165
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
166 /* Readjust relative position. */
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
167 if ((unsigned int)cur->y > tex->rely + menu->h || cur->y < tex->rely)
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
168 tex->rely = cur->y - THEME(menu)->padding;
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
169 }
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
170
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
171 static void
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
172 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
173 {
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
174 assert(key->type == EVENT_KEYDOWN);
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
175
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
176 const struct index idx = get_index(menu);
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
177 const unsigned int save = menu->selected;
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
178
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
179 switch (key->key) {
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
180 case KEY_UP:
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
181 if (idx.row > 0)
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
182 menu->selected -= menu->ncols;
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_RIGHT:
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
185 if (idx.col + 1U < menu->ncols)
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
186 menu->selected += 1;
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 case KEY_DOWN:
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
189 if (idx.row + 1U < GRIDMENU_ENTRY_MAX / menu->ncols)
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
190 menu->selected += menu->ncols;
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
191 break;
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
192 case KEY_LEFT:
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
193 if (idx.col > 0)
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
194 menu->selected -= 1;
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
195 break;
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
196 case KEY_ENTER:
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
197 menu->state = GRIDMENU_STATE_SELECTED;
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
198 break;
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
199 default:
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
200 break;
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
201 }
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
202
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
203 if (save != menu->selected)
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
204 gridmenu_repaint(menu);
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
205 }
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
206
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
207 static void
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
208 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
209 {
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
210 assert(click->type == EVENT_CLICKDOWN);
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
211
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
212 const unsigned int save = menu->selected;
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
213
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
214 for (size_t i = 0; i < GRIDMENU_ENTRY_MAX; ++i) {
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
215 const struct label *l = &menu->tex.labels[i];
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
216 const int x = menu->x + l->x;
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
217 const int y = menu->y + l->y - menu->tex.rely;
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
218 const unsigned int w = menu->tex.eltw;
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
219 const unsigned int h = menu->tex.elth;
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
220
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
221 if (maths_is_boxed(x, y, w, h, click->x, click->y)) {
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
222 menu->selected = i;
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
223 break;
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 }
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 if (save != menu->selected)
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
228 gridmenu_repaint(menu);
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
229 }
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
230
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
231 void
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
232 gridmenu_reset(struct gridmenu *menu)
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
233 {
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
234 assert(menu);
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 menu->state = GRIDMENU_STATE_NONE;
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
237 }
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
238
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
239 void
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
240 gridmenu_repaint(struct gridmenu *menu)
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
241 {
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
242 assert(menu);
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
243 assert(GRIDMENU_ENTRY_MAX % menu->ncols == 0);
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
244
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
245 /* Re-compute positions. */
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
246 positionate(menu);
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 /* Zoom to the appropriate y-relative. */
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
249 zoom(menu);
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 /* Redraw. */
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
252 repaint(menu);
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
253 }
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
254
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
255 void
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
256 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
257 {
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
258 assert(menu);
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
259 assert(ev);
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
260
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
261 switch (ev->type) {
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
262 case EVENT_KEYDOWN:
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
263 handle_keydown(menu, &ev->key);
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
264 break;
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
265 case EVENT_CLICKDOWN:
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
266 handle_clickdown(menu, &ev->click);
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
267 break;
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
268 default:
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 }
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
271 }
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
272
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
273 void
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
274 gridmenu_draw(const struct gridmenu *menu)
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
275 {
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
276 assert(menu);
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
277 assert(menu->nrows > 0 && menu->ncols > 0);
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
278 assert(texture_ok(&menu->tex.texture));
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 texture_scale(&menu->tex.texture,
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
281 0, menu->tex.rely, menu->w, menu->h,
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
282 menu->x, menu->y, menu->w, menu->h, 0.0);
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
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
285 void
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
286 gridmenu_finish(struct gridmenu *menu)
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
287 {
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
288 assert(menu);
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
289
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
290 if (texture_ok(&menu->tex.texture))
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
291 texture_finish(&menu->tex.texture);
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
292
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
293 memset(menu, 0, sizeof (*menu));
867b60e6258a ui: add gridmenu object, closes #2511 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
294 }