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_widget.c
1#include "nuklear.h"
2#include "nuklear_internal.h"
3
4/* ===============================================================
5 *
6 * WIDGET
7 *
8 * ===============================================================*/
9NK_API struct nk_rect
10nk_widget_bounds(const struct nk_context *ctx)
11{
12 struct nk_rect bounds;
13 NK_ASSERT(ctx);
14 NK_ASSERT(ctx->current);
15 if (!ctx || !ctx->current)
16 return nk_rect(0,0,0,0);
17 nk_layout_peek(&bounds, ctx);
18 return bounds;
19}
20NK_API struct nk_vec2
21nk_widget_position(const struct nk_context *ctx)
22{
23 struct nk_rect bounds;
24 NK_ASSERT(ctx);
25 NK_ASSERT(ctx->current);
26 if (!ctx || !ctx->current)
27 return nk_vec2(0,0);
28
29 nk_layout_peek(&bounds, ctx);
30 return nk_vec2(bounds.x, bounds.y);
31}
32NK_API struct nk_vec2
33nk_widget_size(const struct nk_context *ctx)
34{
35 struct nk_rect bounds;
36 NK_ASSERT(ctx);
37 NK_ASSERT(ctx->current);
38 if (!ctx || !ctx->current)
39 return nk_vec2(0,0);
40
41 nk_layout_peek(&bounds, ctx);
42 return nk_vec2(bounds.w, bounds.h);
43}
44NK_API float
45nk_widget_width(const struct nk_context *ctx)
46{
47 struct nk_rect bounds;
48 NK_ASSERT(ctx);
49 NK_ASSERT(ctx->current);
50 if (!ctx || !ctx->current)
51 return 0;
52
53 nk_layout_peek(&bounds, ctx);
54 return bounds.w;
55}
56NK_API float
57nk_widget_height(const struct nk_context *ctx)
58{
59 struct nk_rect bounds;
60 NK_ASSERT(ctx);
61 NK_ASSERT(ctx->current);
62 if (!ctx || !ctx->current)
63 return 0;
64
65 nk_layout_peek(&bounds, ctx);
66 return bounds.h;
67}
68NK_API nk_bool
69nk_widget_is_hovered(const struct nk_context *ctx)
70{
71 struct nk_rect c, v;
72 struct nk_rect bounds;
73 NK_ASSERT(ctx);
74 NK_ASSERT(ctx->current);
75 NK_ASSERT(ctx->current->layout);
76 if (!ctx || !ctx->current || !ctx->current->layout || (ctx->active != ctx->current && !((int)ctx->current->layout->type & (int)NK_PANEL_SET_POPUP)))
77 return 0;
78
79 c = ctx->current->layout->clip;
80 c.x = (float)((int)c.x);
81 c.y = (float)((int)c.y);
82 c.w = (float)((int)c.w);
83 c.h = (float)((int)c.h);
84
85 nk_layout_peek(&bounds, ctx);
86 nk_unify(&v, &c, bounds.x, bounds.y, bounds.x + bounds.w, bounds.y + bounds.h);
87 if (!NK_INTERSECT(c.x, c.y, c.w, c.h, bounds.x, bounds.y, bounds.w, bounds.h))
88 return 0;
89 return nk_input_is_mouse_hovering_rect(&ctx->input, bounds);
90}
91NK_API nk_bool
92nk_widget_is_mouse_clicked(const struct nk_context *ctx, enum nk_buttons btn)
93{
94 struct nk_rect c, v;
95 struct nk_rect bounds;
96 NK_ASSERT(ctx);
97 NK_ASSERT(ctx->current);
98 NK_ASSERT(ctx->current->layout);
99 if (!ctx || !ctx->current || !ctx->current->layout || (ctx->active != ctx->current && !((int)ctx->current->layout->type & (int)NK_PANEL_SET_POPUP)))
100 return 0;
101
102 c = ctx->current->layout->clip;
103 c.x = (float)((int)c.x);
104 c.y = (float)((int)c.y);
105 c.w = (float)((int)c.w);
106 c.h = (float)((int)c.h);
107
108 nk_layout_peek(&bounds, ctx);
109 nk_unify(&v, &c, bounds.x, bounds.y, bounds.x + bounds.w, bounds.y + bounds.h);
110 if (!NK_INTERSECT(c.x, c.y, c.w, c.h, bounds.x, bounds.y, bounds.w, bounds.h))
111 return 0;
112 return nk_input_mouse_clicked(&ctx->input, btn, bounds);
113}
114NK_API nk_bool
115nk_widget_has_mouse_click_down(const struct nk_context *ctx, enum nk_buttons btn, nk_bool down)
116{
117 struct nk_rect c, v;
118 struct nk_rect bounds;
119 NK_ASSERT(ctx);
120 NK_ASSERT(ctx->current);
121 NK_ASSERT(ctx->current->layout);
122 if (!ctx || !ctx->current || !ctx->current->layout || (ctx->active != ctx->current && !((int)ctx->current->layout->type & (int)NK_PANEL_SET_POPUP)))
123 return 0;
124
125 c = ctx->current->layout->clip;
126 c.x = (float)((int)c.x);
127 c.y = (float)((int)c.y);
128 c.w = (float)((int)c.w);
129 c.h = (float)((int)c.h);
130
131 nk_layout_peek(&bounds, ctx);
132 nk_unify(&v, &c, bounds.x, bounds.y, bounds.x + bounds.w, bounds.y + bounds.h);
133 if (!NK_INTERSECT(c.x, c.y, c.w, c.h, bounds.x, bounds.y, bounds.w, bounds.h))
134 return 0;
135 return nk_input_has_mouse_click_down_in_rect(&ctx->input, btn, bounds, down);
136}
137NK_API enum nk_widget_layout_states
138nk_widget(struct nk_rect *bounds, const struct nk_context *ctx)
139{
140 struct nk_rect c, v;
141 struct nk_window *win;
142 struct nk_panel *layout;
143 const struct nk_input *in;
144
145 NK_ASSERT(ctx);
146 NK_ASSERT(ctx->current);
147 NK_ASSERT(ctx->current->layout);
148 if (!ctx || !ctx->current || !ctx->current->layout)
149 return NK_WIDGET_INVALID;
150
151 /* allocate space and check if the widget needs to be updated and drawn */
152 nk_panel_alloc_space(bounds, ctx);
153 win = ctx->current;
154 layout = win->layout;
155 in = &ctx->input;
156 c = layout->clip;
157
158 /* if one of these triggers you forgot to add an `if` condition around either
159 a window, group, popup, combobox or contextual menu `begin` and `end` block.
160 Example:
161 if (nk_begin(...) {...} nk_end(...); or
162 if (nk_group_begin(...) { nk_group_end(...);} */
163 NK_ASSERT(!(layout->flags & NK_WINDOW_MINIMIZED));
164 NK_ASSERT(!(layout->flags & NK_WINDOW_HIDDEN));
165 NK_ASSERT(!(layout->flags & NK_WINDOW_CLOSED));
166
167 /* need to convert to int here to remove floating point errors */
168 bounds->x = (float)((int)bounds->x);
169 bounds->y = (float)((int)bounds->y);
170 bounds->w = (float)((int)bounds->w);
171 bounds->h = (float)((int)bounds->h);
172
173 c.x = (float)((int)c.x);
174 c.y = (float)((int)c.y);
175 c.w = (float)((int)c.w);
176 c.h = (float)((int)c.h);
177
178 nk_unify(&v, &c, bounds->x, bounds->y, bounds->x + bounds->w, bounds->y + bounds->h);
179 if (!NK_INTERSECT(c.x, c.y, c.w, c.h, bounds->x, bounds->y, bounds->w, bounds->h))
180 return NK_WIDGET_INVALID;
181 if (win->widgets_disabled)
182 return NK_WIDGET_DISABLED;
183 if (!NK_INBOX(in->mouse.pos.x, in->mouse.pos.y, v.x, v.y, v.w, v.h))
184 return NK_WIDGET_ROM;
185 return NK_WIDGET_VALID;
186}
187NK_API enum nk_widget_layout_states
188nk_widget_fitting(struct nk_rect *bounds, const struct nk_context *ctx,
189 struct nk_vec2 item_padding)
190{
191 /* update the bounds to stand without padding */
192 enum nk_widget_layout_states state;
193 NK_UNUSED(item_padding);
194
195 NK_ASSERT(ctx);
196 NK_ASSERT(ctx->current);
197 NK_ASSERT(ctx->current->layout);
198 if (!ctx || !ctx->current || !ctx->current->layout)
199 return NK_WIDGET_INVALID;
200
201 state = nk_widget(bounds, ctx);
202 return state;
203}
204NK_API void
205nk_spacing(struct nk_context *ctx, int cols)
206{
207 struct nk_window *win;
208 struct nk_panel *layout;
209 struct nk_rect none;
210 int i, index, rows;
211
212 NK_ASSERT(ctx);
213 NK_ASSERT(ctx->current);
214 NK_ASSERT(ctx->current->layout);
215 if (!ctx || !ctx->current || !ctx->current->layout)
216 return;
217
218 /* spacing over row boundaries */
219 win = ctx->current;
220 layout = win->layout;
221 index = (layout->row.index + cols) % layout->row.columns;
222 rows = (layout->row.index + cols) / layout->row.columns;
223 if (rows) {
224 for (i = 0; i < rows; ++i)
225 nk_panel_alloc_row(ctx, win);
226 cols = index;
227 }
228 /* non table layout need to allocate space */
229 if (layout->row.type != NK_LAYOUT_DYNAMIC_FIXED &&
230 layout->row.type != NK_LAYOUT_STATIC_FIXED) {
231 for (i = 0; i < cols; ++i)
232 nk_panel_alloc_space(&none, ctx);
233 } layout->row.index = index;
234}
235NK_API void
236nk_widget_disable_begin(struct nk_context* ctx)
237{
238 struct nk_window* win;
239 struct nk_style* style;
240
241 NK_ASSERT(ctx);
242 NK_ASSERT(ctx->current);
243
244 if (!ctx || !ctx->current)
245 return;
246
247 win = ctx->current;
248 style = &ctx->style;
249
250 win->widgets_disabled = nk_true;
251
252 style->button.color_factor_text = style->button.disabled_factor;
253 style->button.color_factor_background = style->button.disabled_factor;
254 style->chart.color_factor = style->chart.disabled_factor;
255 style->checkbox.color_factor = style->checkbox.disabled_factor;
256 style->combo.color_factor = style->combo.disabled_factor;
257 style->combo.button.color_factor_text = style->combo.button.disabled_factor;
258 style->combo.button.color_factor_background = style->combo.button.disabled_factor;
259 style->contextual_button.color_factor_text = style->contextual_button.disabled_factor;
260 style->contextual_button.color_factor_background = style->contextual_button.disabled_factor;
261 style->edit.color_factor = style->edit.disabled_factor;
262 style->edit.scrollbar.color_factor = style->edit.scrollbar.disabled_factor;
263 style->menu_button.color_factor_text = style->menu_button.disabled_factor;
264 style->menu_button.color_factor_background = style->menu_button.disabled_factor;
265 style->option.color_factor = style->option.disabled_factor;
266 style->progress.color_factor = style->progress.disabled_factor;
267 style->property.color_factor = style->property.disabled_factor;
268 style->property.inc_button.color_factor_text = style->property.inc_button.disabled_factor;
269 style->property.inc_button.color_factor_background = style->property.inc_button.disabled_factor;
270 style->property.dec_button.color_factor_text = style->property.dec_button.disabled_factor;
271 style->property.dec_button.color_factor_background = style->property.dec_button.disabled_factor;
272 style->property.edit.color_factor = style->property.edit.disabled_factor;
273 style->scrollh.color_factor = style->scrollh.disabled_factor;
274 style->scrollh.inc_button.color_factor_text = style->scrollh.inc_button.disabled_factor;
275 style->scrollh.inc_button.color_factor_background = style->scrollh.inc_button.disabled_factor;
276 style->scrollh.dec_button.color_factor_text = style->scrollh.dec_button.disabled_factor;
277 style->scrollh.dec_button.color_factor_background = style->scrollh.dec_button.disabled_factor;
278 style->scrollv.color_factor = style->scrollv.disabled_factor;
279 style->scrollv.inc_button.color_factor_text = style->scrollv.inc_button.disabled_factor;
280 style->scrollv.inc_button.color_factor_background = style->scrollv.inc_button.disabled_factor;
281 style->scrollv.dec_button.color_factor_text = style->scrollv.dec_button.disabled_factor;
282 style->scrollv.dec_button.color_factor_background = style->scrollv.dec_button.disabled_factor;
283 style->selectable.color_factor = style->selectable.disabled_factor;
284 style->slider.color_factor = style->slider.disabled_factor;
285 style->slider.inc_button.color_factor_text = style->slider.inc_button.disabled_factor;
286 style->slider.inc_button.color_factor_background = style->slider.inc_button.disabled_factor;
287 style->slider.dec_button.color_factor_text = style->slider.dec_button.disabled_factor;
288 style->slider.dec_button.color_factor_background = style->slider.dec_button.disabled_factor;
289 style->tab.color_factor = style->tab.disabled_factor;
290 style->tab.node_maximize_button.color_factor_text = style->tab.node_maximize_button.disabled_factor;
291 style->tab.node_minimize_button.color_factor_text = style->tab.node_minimize_button.disabled_factor;
292 style->tab.tab_maximize_button.color_factor_text = style->tab.tab_maximize_button.disabled_factor;
293 style->tab.tab_maximize_button.color_factor_background = style->tab.tab_maximize_button.disabled_factor;
294 style->tab.tab_minimize_button.color_factor_text = style->tab.tab_minimize_button.disabled_factor;
295 style->tab.tab_minimize_button.color_factor_background = style->tab.tab_minimize_button.disabled_factor;
296 style->text.color_factor = style->text.disabled_factor;
297}
298NK_API void
299nk_widget_disable_end(struct nk_context* ctx)
300{
301 struct nk_window* win;
302 struct nk_style* style;
303
304 NK_ASSERT(ctx);
305 NK_ASSERT(ctx->current);
306
307 if (!ctx || !ctx->current)
308 return;
309
310 win = ctx->current;
311 style = &ctx->style;
312
313 win->widgets_disabled = nk_false;
314
315 style->button.color_factor_text = 1.0f;
316 style->button.color_factor_background = 1.0f;
317 style->chart.color_factor = 1.0f;
318 style->checkbox.color_factor = 1.0f;
319 style->combo.color_factor = 1.0f;
320 style->combo.button.color_factor_text = 1.0f;
321 style->combo.button.color_factor_background = 1.0f;
322 style->contextual_button.color_factor_text = 1.0f;
323 style->contextual_button.color_factor_background = 1.0f;
324 style->edit.color_factor = 1.0f;
325 style->edit.scrollbar.color_factor = 1.0f;
326 style->menu_button.color_factor_text = 1.0f;
327 style->menu_button.color_factor_background = 1.0f;
328 style->option.color_factor = 1.0f;
329 style->progress.color_factor = 1.0f;
330 style->property.color_factor = 1.0f;
331 style->property.inc_button.color_factor_text = 1.0f;
332 style->property.inc_button.color_factor_background = 1.0f;
333 style->property.dec_button.color_factor_text = 1.0f;
334 style->property.dec_button.color_factor_background = 1.0f;
335 style->property.edit.color_factor = 1.0f;
336 style->scrollh.color_factor = 1.0f;
337 style->scrollh.inc_button.color_factor_text = 1.0f;
338 style->scrollh.inc_button.color_factor_background = 1.0f;
339 style->scrollh.dec_button.color_factor_text = 1.0f;
340 style->scrollh.dec_button.color_factor_background = 1.0f;
341 style->scrollv.color_factor = 1.0f;
342 style->scrollv.inc_button.color_factor_text = 1.0f;
343 style->scrollv.inc_button.color_factor_background = 1.0f;
344 style->scrollv.dec_button.color_factor_text = 1.0f;
345 style->scrollv.dec_button.color_factor_background = 1.0f;
346 style->selectable.color_factor = 1.0f;
347 style->slider.color_factor = 1.0f;
348 style->slider.inc_button.color_factor_text = 1.0f;
349 style->slider.inc_button.color_factor_background = 1.0f;
350 style->slider.dec_button.color_factor_text = 1.0f;
351 style->slider.dec_button.color_factor_background = 1.0f;
352 style->tab.color_factor = 1.0f;
353 style->tab.node_maximize_button.color_factor_text = 1.0f;
354 style->tab.node_minimize_button.color_factor_text = 1.0f;
355 style->tab.tab_maximize_button.color_factor_text = 1.0f;
356 style->tab.tab_maximize_button.color_factor_background = 1.0f;
357 style->tab.tab_minimize_button.color_factor_text = 1.0f;
358 style->tab.tab_minimize_button.color_factor_background = 1.0f;
359 style->text.color_factor = 1.0f;
360}
main API and documentation file
@ NK_WINDOW_CLOSED
Directly closes and frees the window at the end of the frame.
Definition nuklear.h:5496
@ NK_WINDOW_MINIMIZED
marks the window as minimized
Definition nuklear.h:5497
@ NK_WINDOW_HIDDEN
Hides window and stops any window interaction and drawing.
Definition nuklear.h:5495
nk_widget_layout_states
Definition nuklear.h:3081
@ 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
@ NK_WIDGET_VALID
The widget is completely inside the window and can be updated and drawn.
Definition nuklear.h:3083
@ NK_WIDGET_INVALID
The widget cannot be seen and is completely out of view.
Definition nuklear.h:3082