Nuklear
This is a minimal-state, immediate-mode graphical user interface toolkit written in ANSI C and licensed under public domain. It was designed as a simple embeddable user interface for application and does not have any dependencies, a default render backend or OS window/input handling but instead provides a highly modular, library-based approach, with simple input state for input and draw commands describing primitive shapes as output. So instead of providing a layered library that tries to abstract over a number of platform and render backends, it focuses only on the actual UI.
 
Loading...
Searching...
No Matches
nuklear_menu.c
1#include "nuklear.h"
2#include "nuklear_internal.h"
3
4/* ===============================================================
5 *
6 * MENU
7 *
8 * ===============================================================*/
9NK_API void
10nk_menubar_begin(struct nk_context *ctx)
11{
12 struct nk_panel *layout;
13 NK_ASSERT(ctx);
14 NK_ASSERT(ctx->current);
15 NK_ASSERT(ctx->current->layout);
16 if (!ctx || !ctx->current || !ctx->current->layout)
17 return;
18
19 layout = ctx->current->layout;
20 NK_ASSERT(layout->at_y == layout->bounds.y);
21 /* if this assert triggers you allocated space between nk_begin and nk_menubar_begin.
22 If you want a menubar the first nuklear function after `nk_begin` has to be a
23 `nk_menubar_begin` call. Inside the menubar you then have to allocate space for
24 widgets (also supports multiple rows).
25 Example:
26 if (nk_begin(...)) {
27 nk_menubar_begin(...);
28 nk_layout_xxxx(...);
29 nk_button(...);
30 nk_layout_xxxx(...);
31 nk_button(...);
32 nk_menubar_end(...);
33 }
34 nk_end(...);
35 */
36 if (layout->flags & NK_WINDOW_HIDDEN || layout->flags & NK_WINDOW_MINIMIZED)
37 return;
38
39 layout->menu.x = layout->at_x;
40 layout->menu.y = layout->at_y + layout->row.height;
41 layout->menu.w = layout->bounds.w;
42 layout->menu.offset.x = *layout->offset_x;
43 layout->menu.offset.y = *layout->offset_y;
44 *layout->offset_y = 0;
45}
46NK_API void
47nk_menubar_end(struct nk_context *ctx)
48{
49 struct nk_window *win;
50 struct nk_panel *layout;
51 struct nk_command_buffer *out;
52
53 NK_ASSERT(ctx);
54 NK_ASSERT(ctx->current);
55 NK_ASSERT(ctx->current->layout);
56 if (!ctx || !ctx->current || !ctx->current->layout)
57 return;
58
59 win = ctx->current;
60 out = &win->buffer;
61 layout = win->layout;
62 if (layout->flags & NK_WINDOW_HIDDEN || layout->flags & NK_WINDOW_MINIMIZED)
63 return;
64
65 layout->menu.h = layout->at_y - layout->menu.y;
66 layout->menu.h += layout->row.height + ctx->style.window.spacing.y;
67
68 layout->bounds.y += layout->menu.h;
69 layout->bounds.h -= layout->menu.h;
70
71 *layout->offset_x = layout->menu.offset.x;
72 *layout->offset_y = layout->menu.offset.y;
73 layout->at_y = layout->bounds.y - layout->row.height;
74
75 layout->clip.y = layout->bounds.y;
76 layout->clip.h = layout->bounds.h;
77 nk_push_scissor(out, layout->clip);
78}
79NK_INTERN int
80nk_menu_begin(struct nk_context *ctx, struct nk_window *win,
81 const char *id, int is_clicked, struct nk_rect header, struct nk_vec2 size)
82{
83 int is_open = 0;
84 int is_active = 0;
85 struct nk_rect body;
86 struct nk_window *popup;
87 nk_hash hash = nk_murmur_hash(id, (int)nk_strlen(id), NK_PANEL_MENU);
88
89 NK_ASSERT(ctx);
90 NK_ASSERT(ctx->current);
91 NK_ASSERT(ctx->current->layout);
92 if (!ctx || !ctx->current || !ctx->current->layout)
93 return 0;
94
95 body.x = header.x;
96 body.w = size.x;
97 body.y = header.y + header.h;
98 body.h = size.y;
99
100 popup = win->popup.win;
101 is_open = popup ? nk_true : nk_false;
102 is_active = (popup && (win->popup.name == hash) && win->popup.type == NK_PANEL_MENU);
103 if ((is_clicked && is_open && !is_active) || (is_open && !is_active) ||
104 (!is_open && !is_active && !is_clicked)) return 0;
105 if (!nk_nonblock_begin(ctx, NK_WINDOW_NO_SCROLLBAR, body, header, NK_PANEL_MENU))
106 return 0;
107
108 win->popup.type = NK_PANEL_MENU;
109 win->popup.name = hash;
110 return 1;
111}
112NK_API nk_bool
113nk_menu_begin_text(struct nk_context *ctx, const char *title, int len,
114 nk_flags align, struct nk_vec2 size)
115{
116 struct nk_window *win;
117 const struct nk_input *in;
118 struct nk_rect header;
119 int is_clicked = nk_false;
120 nk_flags state;
121
122 NK_ASSERT(ctx);
123 NK_ASSERT(ctx->current);
124 NK_ASSERT(ctx->current->layout);
125 if (!ctx || !ctx->current || !ctx->current->layout)
126 return 0;
127
128 win = ctx->current;
129 state = nk_widget(&header, ctx);
130 if (!state) return 0;
131 in = (state == NK_WIDGET_ROM || state == NK_WIDGET_DISABLED || win->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
132 if (nk_do_button_text(&ctx->last_widget_state, &win->buffer, header,
133 title, len, align, NK_BUTTON_DEFAULT, &ctx->style.menu_button, in, ctx->style.font))
134 is_clicked = nk_true;
135 return nk_menu_begin(ctx, win, title, is_clicked, header, size);
136}
137NK_API nk_bool nk_menu_begin_label(struct nk_context *ctx,
138 const char *text, nk_flags align, struct nk_vec2 size)
139{
140 return nk_menu_begin_text(ctx, text, nk_strlen(text), align, size);
141}
142NK_API nk_bool
143nk_menu_begin_image(struct nk_context *ctx, const char *id, struct nk_image img,
144 struct nk_vec2 size)
145{
146 struct nk_window *win;
147 struct nk_rect header;
148 const struct nk_input *in;
149 int is_clicked = nk_false;
150 nk_flags state;
151
152 NK_ASSERT(ctx);
153 NK_ASSERT(ctx->current);
154 NK_ASSERT(ctx->current->layout);
155 if (!ctx || !ctx->current || !ctx->current->layout)
156 return 0;
157
158 win = ctx->current;
159 state = nk_widget(&header, ctx);
160 if (!state) return 0;
161 in = (state == NK_WIDGET_ROM || state == NK_WIDGET_DISABLED || win->layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
162 if (nk_do_button_image(&ctx->last_widget_state, &win->buffer, header,
163 img, NK_BUTTON_DEFAULT, &ctx->style.menu_button, in))
164 is_clicked = nk_true;
165 return nk_menu_begin(ctx, win, id, is_clicked, header, size);
166}
167NK_API nk_bool
168nk_menu_begin_symbol(struct nk_context *ctx, const char *id,
169 enum nk_symbol_type sym, struct nk_vec2 size)
170{
171 struct nk_window *win;
172 const struct nk_input *in;
173 struct nk_rect header;
174 int is_clicked = nk_false;
175 nk_flags state;
176
177 NK_ASSERT(ctx);
178 NK_ASSERT(ctx->current);
179 NK_ASSERT(ctx->current->layout);
180 if (!ctx || !ctx->current || !ctx->current->layout)
181 return 0;
182
183 win = ctx->current;
184 state = nk_widget(&header, ctx);
185 if (!state) return 0;
186 in = (state == NK_WIDGET_ROM || state == NK_WIDGET_DISABLED || win->layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
187 if (nk_do_button_symbol(&ctx->last_widget_state, &win->buffer, header,
188 sym, NK_BUTTON_DEFAULT, &ctx->style.menu_button, in, ctx->style.font))
189 is_clicked = nk_true;
190 return nk_menu_begin(ctx, win, id, is_clicked, header, size);
191}
192NK_API nk_bool
193nk_menu_begin_image_text(struct nk_context *ctx, const char *title, int len,
194 nk_flags align, struct nk_image img, struct nk_vec2 size)
195{
196 struct nk_window *win;
197 struct nk_rect header;
198 const struct nk_input *in;
199 int is_clicked = nk_false;
200 nk_flags state;
201
202 NK_ASSERT(ctx);
203 NK_ASSERT(ctx->current);
204 NK_ASSERT(ctx->current->layout);
205 if (!ctx || !ctx->current || !ctx->current->layout)
206 return 0;
207
208 win = ctx->current;
209 state = nk_widget(&header, ctx);
210 if (!state) return 0;
211 in = (state == NK_WIDGET_ROM || state == NK_WIDGET_DISABLED || win->layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
212 if (nk_do_button_text_image(&ctx->last_widget_state, &win->buffer,
213 header, img, title, len, align, NK_BUTTON_DEFAULT, &ctx->style.menu_button,
214 ctx->style.font, in))
215 is_clicked = nk_true;
216 return nk_menu_begin(ctx, win, title, is_clicked, header, size);
217}
218NK_API nk_bool
219nk_menu_begin_image_label(struct nk_context *ctx,
220 const char *title, nk_flags align, struct nk_image img, struct nk_vec2 size)
221{
222 return nk_menu_begin_image_text(ctx, title, nk_strlen(title), align, img, size);
223}
224NK_API nk_bool
225nk_menu_begin_symbol_text(struct nk_context *ctx, const char *title, int len,
226 nk_flags align, enum nk_symbol_type sym, struct nk_vec2 size)
227{
228 struct nk_window *win;
229 struct nk_rect header;
230 const struct nk_input *in;
231 int is_clicked = nk_false;
232 nk_flags state;
233
234 NK_ASSERT(ctx);
235 NK_ASSERT(ctx->current);
236 NK_ASSERT(ctx->current->layout);
237 if (!ctx || !ctx->current || !ctx->current->layout)
238 return 0;
239
240 win = ctx->current;
241 state = nk_widget(&header, ctx);
242 if (!state) return 0;
243
244 in = (state == NK_WIDGET_ROM || state == NK_WIDGET_DISABLED || win->layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
245 if (nk_do_button_text_symbol(&ctx->last_widget_state, &win->buffer,
246 header, sym, title, len, align, NK_BUTTON_DEFAULT, &ctx->style.menu_button,
247 ctx->style.font, in)) is_clicked = nk_true;
248 return nk_menu_begin(ctx, win, title, is_clicked, header, size);
249}
250NK_API nk_bool
251nk_menu_begin_symbol_label(struct nk_context *ctx,
252 const char *title, nk_flags align, enum nk_symbol_type sym, struct nk_vec2 size )
253{
254 return nk_menu_begin_symbol_text(ctx, title, nk_strlen(title), align,sym,size);
255}
256NK_API nk_bool
257nk_menu_item_text(struct nk_context *ctx, const char *title, int len, nk_flags align)
258{
259 return nk_contextual_item_text(ctx, title, len, align);
260}
261NK_API nk_bool
262nk_menu_item_label(struct nk_context *ctx, const char *label, nk_flags align)
263{
264 return nk_contextual_item_label(ctx, label, align);
265}
266NK_API nk_bool
267nk_menu_item_image_label(struct nk_context *ctx, struct nk_image img,
268 const char *label, nk_flags align)
269{
270 return nk_contextual_item_image_label(ctx, img, label, align);
271}
272NK_API nk_bool
273nk_menu_item_image_text(struct nk_context *ctx, struct nk_image img,
274 const char *text, int len, nk_flags align)
275{
276 return nk_contextual_item_image_text(ctx, img, text, len, align);
277}
278NK_API nk_bool nk_menu_item_symbol_text(struct nk_context *ctx, enum nk_symbol_type sym,
279 const char *text, int len, nk_flags align)
280{
281 return nk_contextual_item_symbol_text(ctx, sym, text, len, align);
282}
283NK_API nk_bool nk_menu_item_symbol_label(struct nk_context *ctx, enum nk_symbol_type sym,
284 const char *label, nk_flags align)
285{
286 return nk_contextual_item_symbol_label(ctx, sym, label, align);
287}
288NK_API void nk_menu_close(struct nk_context *ctx)
289{
290 nk_contextual_close(ctx);
291}
292NK_API void
293nk_menu_end(struct nk_context *ctx)
294{
295 nk_contextual_end(ctx);
296}
297
main API and documentation file
@ NK_WINDOW_MINIMIZED
marks the window as minimized
Definition nuklear.h:5496
@ NK_WINDOW_HIDDEN
Hides window and stops any window interaction and drawing.
Definition nuklear.h:5494
@ NK_WINDOW_ROM
sets window widgets into a read only mode and does not allow input changes
Definition nuklear.h:5492
@ NK_WIDGET_DISABLED
The widget is manually disabled and acts like NK_WIDGET_ROM.
Definition nuklear.h:3085
@ NK_WIDGET_ROM
The widget is partially visible and cannot be updated.
Definition nuklear.h:3084