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_panel.c
1#include "nuklear.h"
2#include "nuklear_internal.h"
3
4/* ===============================================================
5 *
6 * PANEL
7 *
8 * ===============================================================*/
9NK_LIB void*
10nk_create_panel(struct nk_context *ctx)
11{
12 struct nk_page_element *elem;
13 elem = nk_create_page_element(ctx);
14 if (!elem) return 0;
15 nk_zero_struct(*elem);
16 return &elem->data.pan;
17}
18NK_LIB void
19nk_free_panel(struct nk_context *ctx, struct nk_panel *pan)
20{
21 union nk_page_data *pd = NK_CONTAINER_OF(pan, union nk_page_data, pan);
22 struct nk_page_element *pe = NK_CONTAINER_OF(pd, struct nk_page_element, data);
23 nk_free_page_element(ctx, pe);
24}
25NK_LIB nk_bool
26nk_panel_has_header(nk_flags flags, const char *title)
27{
28 nk_bool active = 0;
29 active = (flags & (NK_WINDOW_CLOSABLE|NK_WINDOW_MINIMIZABLE));
30 active = active || (flags & NK_WINDOW_TITLE);
31 active = active && !(flags & NK_WINDOW_HIDDEN) && title;
32 return active;
33}
34NK_LIB struct nk_vec2
35nk_panel_get_padding(const struct nk_style *style, enum nk_panel_type type)
36{
37 switch (type) {
38 default:
39 case NK_PANEL_WINDOW: return style->window.padding;
40 case NK_PANEL_GROUP: return style->window.group_padding;
41 case NK_PANEL_POPUP: return style->window.popup_padding;
42 case NK_PANEL_CONTEXTUAL: return style->window.contextual_padding;
43 case NK_PANEL_COMBO: return style->window.combo_padding;
44 case NK_PANEL_MENU: return style->window.menu_padding;
45 case NK_PANEL_TOOLTIP: return style->window.menu_padding;}
46}
47NK_LIB float
48nk_panel_get_border(const struct nk_style *style, nk_flags flags,
49 enum nk_panel_type type)
50{
51 if (flags & NK_WINDOW_BORDER) {
52 switch (type) {
53 default:
54 case NK_PANEL_WINDOW: return style->window.border;
55 case NK_PANEL_GROUP: return style->window.group_border;
56 case NK_PANEL_POPUP: return style->window.popup_border;
57 case NK_PANEL_CONTEXTUAL: return style->window.contextual_border;
58 case NK_PANEL_COMBO: return style->window.combo_border;
59 case NK_PANEL_MENU: return style->window.menu_border;
60 case NK_PANEL_TOOLTIP: return style->window.menu_border;
61 }} else return 0;
62}
63NK_LIB struct nk_color
64nk_panel_get_border_color(const struct nk_style *style, enum nk_panel_type type)
65{
66 switch (type) {
67 default:
68 case NK_PANEL_WINDOW: return style->window.border_color;
69 case NK_PANEL_GROUP: return style->window.group_border_color;
70 case NK_PANEL_POPUP: return style->window.popup_border_color;
71 case NK_PANEL_CONTEXTUAL: return style->window.contextual_border_color;
72 case NK_PANEL_COMBO: return style->window.combo_border_color;
73 case NK_PANEL_MENU: return style->window.menu_border_color;
74 case NK_PANEL_TOOLTIP: return style->window.menu_border_color;}
75}
76NK_LIB nk_bool
77nk_panel_is_sub(enum nk_panel_type type)
78{
79 return ((int)type & (int)NK_PANEL_SET_SUB)?1:0;
80}
81NK_LIB nk_bool
82nk_panel_is_nonblock(enum nk_panel_type type)
83{
84 return ((int)type & (int)NK_PANEL_SET_NONBLOCK)?1:0;
85}
86NK_LIB nk_bool
87nk_panel_begin(struct nk_context *ctx, const char *title, enum nk_panel_type panel_type)
88{
89 struct nk_input *in;
90 struct nk_window *win;
91 struct nk_panel *layout;
92 struct nk_command_buffer *out;
93 const struct nk_style *style;
94 const struct nk_user_font *font;
95
96 struct nk_vec2 scrollbar_size;
97 struct nk_vec2 panel_padding;
98
99 NK_ASSERT(ctx);
100 NK_ASSERT(ctx->current);
101 NK_ASSERT(ctx->current->layout);
102 if (!ctx || !ctx->current || !ctx->current->layout) return 0;
103 nk_zero(ctx->current->layout, sizeof(*ctx->current->layout));
104 if ((ctx->current->flags & NK_WINDOW_HIDDEN) || (ctx->current->flags & NK_WINDOW_CLOSED)) {
105 nk_zero(ctx->current->layout, sizeof(struct nk_panel));
106 ctx->current->layout->type = panel_type;
107 return 0;
108 }
109 /* pull state into local stack */
110 style = &ctx->style;
111 font = style->font;
112 win = ctx->current;
113 layout = win->layout;
114 out = &win->buffer;
115 in = (win->flags & NK_WINDOW_NO_INPUT) ? 0: &ctx->input;
116#ifdef NK_INCLUDE_COMMAND_USERDATA
117 win->buffer.userdata = ctx->userdata;
118#endif
119 /* pull style configuration into local stack */
120 scrollbar_size = style->window.scrollbar_size;
121 panel_padding = nk_panel_get_padding(style, panel_type);
122
123 /* window movement */
124 if ((win->flags & NK_WINDOW_MOVABLE) && !(win->flags & NK_WINDOW_ROM)) {
125 nk_bool left_mouse_down;
126 unsigned int left_mouse_clicked;
127 int left_mouse_click_in_cursor;
128
129 /* calculate draggable window space */
130 struct nk_rect header;
131 header.x = win->bounds.x;
132 header.y = win->bounds.y;
133 header.w = win->bounds.w;
134 if (nk_panel_has_header(win->flags, title)) {
135 header.h = font->height + 2.0f * style->window.header.padding.y;
136 header.h += 2.0f * style->window.header.label_padding.y;
137 } else header.h = panel_padding.y;
138
139 /* window movement by dragging */
140 left_mouse_down = in->mouse.buttons[NK_BUTTON_LEFT].down;
141 left_mouse_clicked = in->mouse.buttons[NK_BUTTON_LEFT].clicked;
142 left_mouse_click_in_cursor = nk_input_has_mouse_click_down_in_rect(in,
143 NK_BUTTON_LEFT, header, nk_true);
144 if (left_mouse_down && left_mouse_click_in_cursor && !left_mouse_clicked) {
145 win->bounds.x = win->bounds.x + in->mouse.delta.x;
146 win->bounds.y = win->bounds.y + in->mouse.delta.y;
147 in->mouse.buttons[NK_BUTTON_LEFT].clicked_pos.x += in->mouse.delta.x;
148 in->mouse.buttons[NK_BUTTON_LEFT].clicked_pos.y += in->mouse.delta.y;
149 ctx->style.cursor_active = ctx->style.cursors[NK_CURSOR_MOVE];
150 }
151 }
152
153 /* setup panel */
154 layout->type = panel_type;
155 layout->flags = win->flags;
156 layout->bounds = win->bounds;
157 layout->bounds.x += panel_padding.x;
158 layout->bounds.w -= 2*panel_padding.x;
159 if (win->flags & NK_WINDOW_BORDER) {
160 layout->border = nk_panel_get_border(style, win->flags, panel_type);
161 layout->bounds = nk_shrink_rect(layout->bounds, layout->border);
162 } else layout->border = 0;
163 layout->at_y = layout->bounds.y;
164 layout->at_x = layout->bounds.x;
165 layout->max_x = 0;
166 layout->header_height = 0;
167 layout->footer_height = 0;
169 layout->row.index = 0;
170 layout->row.columns = 0;
171 layout->row.ratio = 0;
172 layout->row.item_width = 0;
173 layout->row.tree_depth = 0;
174 layout->row.height = panel_padding.y;
175 layout->has_scrolling = nk_true;
176 if (!(win->flags & NK_WINDOW_NO_SCROLLBAR))
177 layout->bounds.w -= scrollbar_size.x;
178 if (!nk_panel_is_nonblock(panel_type)) {
179 layout->footer_height = 0;
180 if (!(win->flags & NK_WINDOW_NO_SCROLLBAR) || win->flags & NK_WINDOW_SCALABLE)
181 layout->footer_height = scrollbar_size.y;
182 layout->bounds.h -= layout->footer_height;
183 }
184
185 /* panel header */
186 if (nk_panel_has_header(win->flags, title))
187 {
188 struct nk_text text;
189 struct nk_rect header;
190 const struct nk_style_item *background = 0;
191
192 /* calculate header bounds */
193 header.x = win->bounds.x;
194 header.y = win->bounds.y;
195 header.w = win->bounds.w;
196 header.h = font->height + 2.0f * style->window.header.padding.y;
197 header.h += (2.0f * style->window.header.label_padding.y);
198
199 /* shrink panel by header */
200 layout->header_height = header.h;
201 layout->bounds.y += header.h;
202 layout->bounds.h -= header.h;
203 layout->at_y += header.h;
204
205 /* select correct header background and text color */
206 if (ctx->active == win) {
207 background = &style->window.header.active;
208 text.text = style->window.header.label_active;
209 } else if (nk_input_is_mouse_hovering_rect(&ctx->input, header)) {
210 background = &style->window.header.hover;
211 text.text = style->window.header.label_hover;
212 } else {
213 background = &style->window.header.normal;
214 text.text = style->window.header.label_normal;
215 }
216
217 /* draw header background */
218 header.h += 1.0f;
219
220 switch(background->type) {
221 case NK_STYLE_ITEM_IMAGE:
222 text.background = nk_rgba(0,0,0,0);
223 nk_draw_image(&win->buffer, header, &background->data.image, nk_white);
224 break;
225 case NK_STYLE_ITEM_NINE_SLICE:
226 text.background = nk_rgba(0, 0, 0, 0);
227 nk_draw_nine_slice(&win->buffer, header, &background->data.slice, nk_white);
228 break;
229 case NK_STYLE_ITEM_COLOR:
230 text.background = background->data.color;
231 nk_fill_rect(out, header, 0, background->data.color);
232 break;
233 }
234
235 /* window close button */
236 {struct nk_rect button;
237 button.y = header.y + style->window.header.padding.y;
238 button.h = header.h - 2 * style->window.header.padding.y;
239 button.w = button.h;
240 if (win->flags & NK_WINDOW_CLOSABLE) {
241 nk_flags ws = 0;
242 if (style->window.header.align == NK_HEADER_RIGHT) {
243 button.x = (header.w + header.x) - (button.w + style->window.header.padding.x);
244 header.w -= button.w + style->window.header.spacing.x + style->window.header.padding.x;
245 } else {
246 button.x = header.x + style->window.header.padding.x;
247 header.x += button.w + style->window.header.spacing.x + style->window.header.padding.x;
248 }
249
250 if (nk_do_button_symbol(&ws, &win->buffer, button,
251 style->window.header.close_symbol, NK_BUTTON_DEFAULT,
252 &style->window.header.close_button, in, style->font) && !(win->flags & NK_WINDOW_ROM))
253 {
254 layout->flags |= NK_WINDOW_HIDDEN;
255 layout->flags &= (nk_flags)~NK_WINDOW_MINIMIZED;
256 }
257 }
258
259 /* window minimize button */
260 if (win->flags & NK_WINDOW_MINIMIZABLE) {
261 nk_flags ws = 0;
262 if (style->window.header.align == NK_HEADER_RIGHT) {
263 button.x = (header.w + header.x) - button.w;
264 if (!(win->flags & NK_WINDOW_CLOSABLE)) {
265 button.x -= style->window.header.padding.x;
266 header.w -= style->window.header.padding.x;
267 }
268 header.w -= button.w + style->window.header.spacing.x;
269 } else {
270 button.x = header.x;
271 header.x += button.w + style->window.header.spacing.x + style->window.header.padding.x;
272 }
273 if (nk_do_button_symbol(&ws, &win->buffer, button, (layout->flags & NK_WINDOW_MINIMIZED)?
274 style->window.header.maximize_symbol: style->window.header.minimize_symbol,
275 NK_BUTTON_DEFAULT, &style->window.header.minimize_button, in, style->font) && !(win->flags & NK_WINDOW_ROM))
276 layout->flags = (layout->flags & NK_WINDOW_MINIMIZED) ?
277 layout->flags & (nk_flags)~NK_WINDOW_MINIMIZED:
278 layout->flags | NK_WINDOW_MINIMIZED;
279 }}
280
281 {/* window header title */
282 int text_len = nk_strlen(title);
283 struct nk_rect label = {0,0,0,0};
284 float t = font->width(font->userdata, font->height, title, text_len);
285 text.padding = nk_vec2(0,0);
286
287 label.x = header.x + style->window.header.padding.x;
288 label.x += style->window.header.label_padding.x;
289 label.y = header.y + style->window.header.label_padding.y;
290 label.h = font->height + 2 * style->window.header.label_padding.y;
291 label.w = t + 2 * style->window.header.spacing.x;
292 label.w = NK_CLAMP(0, label.w, header.x + header.w - label.x);
293 nk_widget_text(out, label, (const char*)title, text_len, &text, NK_TEXT_LEFT, font);}
294 }
295
296 /* draw window background */
297 if (!(layout->flags & NK_WINDOW_MINIMIZED) && !(layout->flags & NK_WINDOW_DYNAMIC)) {
298 struct nk_rect body;
299 body.x = win->bounds.x;
300 body.w = win->bounds.w;
301 body.y = (win->bounds.y + layout->header_height);
302 body.h = (win->bounds.h - layout->header_height);
303
304 switch(style->window.fixed_background.type) {
305 case NK_STYLE_ITEM_IMAGE:
306 nk_draw_image(out, body, &style->window.fixed_background.data.image, nk_white);
307 break;
308 case NK_STYLE_ITEM_NINE_SLICE:
309 nk_draw_nine_slice(out, body, &style->window.fixed_background.data.slice, nk_white);
310 break;
311 case NK_STYLE_ITEM_COLOR:
312 nk_fill_rect(out, body, style->window.rounding, style->window.fixed_background.data.color);
313 break;
314 }
315 }
316
317 /* set clipping rectangle */
318 {struct nk_rect clip;
319 layout->clip = layout->bounds;
320 nk_unify(&clip, &win->buffer.clip, layout->clip.x, layout->clip.y,
321 layout->clip.x + layout->clip.w, layout->clip.y + layout->clip.h);
322 nk_push_scissor(out, clip);
323 layout->clip = clip;}
324 return !(layout->flags & NK_WINDOW_HIDDEN) && !(layout->flags & NK_WINDOW_MINIMIZED);
325}
326NK_LIB void
327nk_panel_end(struct nk_context *ctx)
328{
329 struct nk_input *in;
330 struct nk_window *window;
331 struct nk_panel *layout;
332 const struct nk_style *style;
333 struct nk_command_buffer *out;
334
335 struct nk_vec2 scrollbar_size;
336 struct nk_vec2 panel_padding;
337
338 NK_ASSERT(ctx);
339 NK_ASSERT(ctx->current);
340 NK_ASSERT(ctx->current->layout);
341 if (!ctx || !ctx->current || !ctx->current->layout)
342 return;
343
344 window = ctx->current;
345 layout = window->layout;
346 style = &ctx->style;
347 out = &window->buffer;
348 in = (layout->flags & NK_WINDOW_ROM || layout->flags & NK_WINDOW_NO_INPUT) ? 0 :&ctx->input;
349 if (!nk_panel_is_sub(layout->type))
350 nk_push_scissor(out, nk_null_rect);
351
352 /* cache configuration data */
353 scrollbar_size = style->window.scrollbar_size;
354 panel_padding = nk_panel_get_padding(style, layout->type);
355
356 /* update the current cursor Y-position to point over the last added widget */
357 layout->at_y += layout->row.height;
358
359 /* dynamic panels */
360 if (layout->flags & NK_WINDOW_DYNAMIC && !(layout->flags & NK_WINDOW_MINIMIZED))
361 {
362 /* update panel height to fit dynamic growth */
363 struct nk_rect empty_space;
364 if (layout->at_y < (layout->bounds.y + layout->bounds.h))
365 layout->bounds.h = layout->at_y - layout->bounds.y;
366
367 /* fill top empty space */
368 empty_space.x = window->bounds.x;
369 empty_space.y = layout->bounds.y;
370 empty_space.h = panel_padding.y;
371 empty_space.w = window->bounds.w;
372 nk_fill_rect(out, empty_space, 0, style->window.background);
373
374 /* fill left empty space */
375 empty_space.x = window->bounds.x;
376 empty_space.y = layout->bounds.y;
377 empty_space.w = panel_padding.x + layout->border;
378 empty_space.h = layout->bounds.h;
379 nk_fill_rect(out, empty_space, 0, style->window.background);
380
381 /* fill right empty space */
382 empty_space.x = layout->bounds.x + layout->bounds.w;
383 empty_space.y = layout->bounds.y;
384 empty_space.w = panel_padding.x + layout->border;
385 empty_space.h = layout->bounds.h;
386 if (*layout->offset_y == 0 && !(layout->flags & NK_WINDOW_NO_SCROLLBAR))
387 empty_space.w += scrollbar_size.x;
388 nk_fill_rect(out, empty_space, 0, style->window.background);
389
390 /* fill bottom empty space */
391 if (layout->footer_height > 0) {
392 empty_space.x = window->bounds.x;
393 empty_space.y = layout->bounds.y + layout->bounds.h;
394 empty_space.w = window->bounds.w;
395 empty_space.h = layout->footer_height;
396 nk_fill_rect(out, empty_space, 0, style->window.background);
397 }
398 }
399
400 /* scrollbars */
401 if (!(layout->flags & NK_WINDOW_NO_SCROLLBAR) &&
402 !(layout->flags & NK_WINDOW_MINIMIZED) &&
403 window->scrollbar_hiding_timer < NK_SCROLLBAR_HIDING_TIMEOUT)
404 {
405 struct nk_rect scroll;
406 int scroll_has_scrolling;
407 float scroll_target;
408 float scroll_offset;
409 float scroll_step;
410 float scroll_inc;
411
412 /* mouse wheel scrolling */
413 if (nk_panel_is_sub(layout->type))
414 {
415 /* sub-window mouse wheel scrolling */
416 struct nk_window *root_window = window;
417 struct nk_panel *root_panel = window->layout;
418 while (root_panel->parent)
419 root_panel = root_panel->parent;
420 while (root_window->parent)
421 root_window = root_window->parent;
422
423 /* only allow scrolling if parent window is active */
424 scroll_has_scrolling = nk_false;
425 if ((root_window == ctx->active) && layout->has_scrolling) {
426 /* and panel is being hovered and inside clip rect*/
427 if (nk_input_is_mouse_hovering_rect(in, layout->bounds) &&
428 NK_INTERSECT(layout->bounds.x, layout->bounds.y, layout->bounds.w, layout->bounds.h,
429 root_panel->clip.x, root_panel->clip.y, root_panel->clip.w, root_panel->clip.h))
430 {
431 /* deactivate all parent scrolling */
432 root_panel = window->layout;
433 while (root_panel->parent) {
434 root_panel->has_scrolling = nk_false;
435 root_panel = root_panel->parent;
436 }
437 root_panel->has_scrolling = nk_false;
438 scroll_has_scrolling = nk_true;
439 }
440 }
441 } else {
442 /* window mouse wheel scrolling */
443 scroll_has_scrolling = (window == ctx->active) && layout->has_scrolling;
444 if (in && (in->mouse.scroll_delta.y > 0 || in->mouse.scroll_delta.x > 0) && scroll_has_scrolling)
445 window->scrolled = nk_true;
446 else window->scrolled = nk_false;
447 }
448
449 {
450 /* vertical scrollbar */
451 nk_flags state = 0;
452 scroll.x = layout->bounds.x + layout->bounds.w + panel_padding.x;
453 scroll.y = layout->bounds.y;
454 scroll.w = scrollbar_size.x;
455 scroll.h = layout->bounds.h;
456
457 scroll_offset = (float)*layout->offset_y;
458 scroll_step = scroll.h * 0.10f;
459 scroll_inc = scroll.h * 0.01f;
460 scroll_target = (float)(int)(layout->at_y - scroll.y);
461 scroll_offset = nk_do_scrollbarv(&state, out, scroll, scroll_has_scrolling,
462 scroll_offset, scroll_target, scroll_step, scroll_inc,
463 &ctx->style.scrollv, in, style->font);
464 *layout->offset_y = (nk_uint)scroll_offset;
465 if (in && scroll_has_scrolling)
466 in->mouse.scroll_delta.y = 0;
467 }
468 {
469 /* horizontal scrollbar */
470 nk_flags state = 0;
471 scroll.x = layout->bounds.x;
472 scroll.y = layout->bounds.y + layout->bounds.h;
473 scroll.w = layout->bounds.w;
474 scroll.h = scrollbar_size.y;
475
476 scroll_offset = (float)*layout->offset_x;
477 scroll_target = (float)(int)(layout->max_x - scroll.x);
478 scroll_step = layout->max_x * 0.05f;
479 scroll_inc = layout->max_x * 0.005f;
480 scroll_offset = nk_do_scrollbarh(&state, out, scroll, scroll_has_scrolling,
481 scroll_offset, scroll_target, scroll_step, scroll_inc,
482 &ctx->style.scrollh, in, style->font);
483 *layout->offset_x = (nk_uint)scroll_offset;
484 }
485 }
486
487 /* hide scroll if no user input */
488 if (window->flags & NK_WINDOW_SCROLL_AUTO_HIDE) {
489 int has_input = ctx->input.mouse.delta.x != 0 || ctx->input.mouse.delta.y != 0 || ctx->input.mouse.scroll_delta.y != 0;
490 int is_window_hovered = nk_window_is_hovered(ctx);
491 int any_item_active = (ctx->last_widget_state & NK_WIDGET_STATE_MODIFIED);
492 if ((!has_input && is_window_hovered) || (!is_window_hovered && !any_item_active))
493 window->scrollbar_hiding_timer += ctx->delta_time_seconds;
494 else window->scrollbar_hiding_timer = 0;
495 } else window->scrollbar_hiding_timer = 0;
496
497 /* window border */
498 if (layout->flags & NK_WINDOW_BORDER)
499 {
500 struct nk_color border_color = nk_panel_get_border_color(style, layout->type);
501 const float padding_y = (layout->flags & NK_WINDOW_MINIMIZED)
502 ? (style->window.border + window->bounds.y + layout->header_height)
503 : ((layout->flags & NK_WINDOW_DYNAMIC)
504 ? (layout->bounds.y + layout->bounds.h + layout->footer_height)
505 : (window->bounds.y + window->bounds.h));
506 struct nk_rect b = window->bounds;
507 b.h = padding_y - window->bounds.y;
508 nk_stroke_rect(out, b, style->window.rounding, layout->border, border_color);
509 }
510
511 /* scaler */
512 if ((layout->flags & NK_WINDOW_SCALABLE) && in && !(layout->flags & NK_WINDOW_MINIMIZED))
513 {
514 /* calculate scaler bounds */
515 struct nk_rect scaler;
516 scaler.w = scrollbar_size.x;
517 scaler.h = scrollbar_size.y;
518 scaler.y = layout->bounds.y + layout->bounds.h;
519 if (layout->flags & NK_WINDOW_SCALE_LEFT)
520 scaler.x = layout->bounds.x - panel_padding.x * 0.5f;
521 else scaler.x = layout->bounds.x + layout->bounds.w + panel_padding.x;
522 if (layout->flags & NK_WINDOW_NO_SCROLLBAR)
523 scaler.x -= scaler.w;
524
525 /* draw scaler */
526 {const struct nk_style_item *item = &style->window.scaler;
527 if (item->type == NK_STYLE_ITEM_IMAGE)
528 nk_draw_image(out, scaler, &item->data.image, nk_white);
529 else {
530 if (layout->flags & NK_WINDOW_SCALE_LEFT) {
531 nk_fill_triangle(out, scaler.x, scaler.y, scaler.x,
532 scaler.y + scaler.h, scaler.x + scaler.w,
533 scaler.y + scaler.h, item->data.color);
534 } else {
535 nk_fill_triangle(out, scaler.x + scaler.w, scaler.y, scaler.x + scaler.w,
536 scaler.y + scaler.h, scaler.x, scaler.y + scaler.h, item->data.color);
537 }
538 }}
539
540 /* do window scaling */
541 if (!(window->flags & NK_WINDOW_ROM)) {
542 struct nk_vec2 window_size = style->window.min_size;
543 int left_mouse_down = in->mouse.buttons[NK_BUTTON_LEFT].down;
544 int left_mouse_click_in_scaler = nk_input_has_mouse_click_down_in_rect(in,
545 NK_BUTTON_LEFT, scaler, nk_true);
546
547 if (left_mouse_down && left_mouse_click_in_scaler) {
548 float delta_x = in->mouse.delta.x;
549 if (layout->flags & NK_WINDOW_SCALE_LEFT) {
550 delta_x = -delta_x;
551 window->bounds.x += in->mouse.delta.x;
552 }
553 /* dragging in x-direction */
554 if (window->bounds.w + delta_x >= window_size.x) {
555 if ((delta_x < 0) || (delta_x > 0 && in->mouse.pos.x >= scaler.x)) {
556 window->bounds.w = window->bounds.w + delta_x;
557 scaler.x += in->mouse.delta.x;
558 }
559 }
560 /* dragging in y-direction (only possible if static window) */
561 if (!(layout->flags & NK_WINDOW_DYNAMIC)) {
562 if (window_size.y < window->bounds.h + in->mouse.delta.y) {
563 if ((in->mouse.delta.y < 0) || (in->mouse.delta.y > 0 && in->mouse.pos.y >= scaler.y)) {
564 window->bounds.h = window->bounds.h + in->mouse.delta.y;
565 scaler.y += in->mouse.delta.y;
566 }
567 }
568 }
569 ctx->style.cursor_active = ctx->style.cursors[NK_CURSOR_RESIZE_TOP_RIGHT_DOWN_LEFT];
570 in->mouse.buttons[NK_BUTTON_LEFT].clicked_pos.x = scaler.x + scaler.w/2.0f;
571 in->mouse.buttons[NK_BUTTON_LEFT].clicked_pos.y = scaler.y + scaler.h/2.0f;
572 }
573 }
574 }
575 if (!nk_panel_is_sub(layout->type)) {
576 /* window is hidden so clear command buffer */
577 if (layout->flags & NK_WINDOW_HIDDEN)
578 nk_command_buffer_reset(&window->buffer);
579 /* window is visible and not tab */
580 else nk_finish(ctx, window);
581 }
582
583 /* NK_WINDOW_REMOVE_ROM flag was set so remove NK_WINDOW_ROM */
584 if (layout->flags & NK_WINDOW_REMOVE_ROM) {
585 layout->flags &= ~(nk_flags)NK_WINDOW_ROM;
586 layout->flags &= ~(nk_flags)NK_WINDOW_REMOVE_ROM;
587 }
588 window->flags = layout->flags;
589
590 /* property garbage collector */
591 if (window->property.active && window->property.old != window->property.seq &&
592 window->property.active == window->property.prev) {
593 nk_zero(&window->property, sizeof(window->property));
594 } else {
595 window->property.old = window->property.seq;
596 window->property.prev = window->property.active;
597 window->property.seq = 0;
598 }
599 /* edit garbage collector */
600 if (window->edit.active && window->edit.old != window->edit.seq &&
601 window->edit.active == window->edit.prev) {
602 nk_zero(&window->edit, sizeof(window->edit));
603 } else {
604 window->edit.old = window->edit.seq;
605 window->edit.prev = window->edit.active;
606 window->edit.seq = 0;
607 }
608 /* contextual garbage collector */
609 if (window->popup.active_con && window->popup.con_old != window->popup.con_count) {
610 window->popup.con_count = 0;
611 window->popup.con_old = 0;
612 window->popup.active_con = 0;
613 } else {
614 window->popup.con_old = window->popup.con_count;
615 window->popup.con_count = 0;
616 }
617 window->popup.combo_count = 0;
618 /* helper to make sure you have a 'nk_tree_push' for every 'nk_tree_pop' */
619 NK_ASSERT(!layout->row.tree_depth);
620}
621
main API and documentation file
@ NK_WINDOW_CLOSED
Directly closes and frees the window at the end of the frame.
Definition nuklear.h:5495
@ 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_WINDOW_DYNAMIC
special window type growing up in height while being filled to a certain maximum height
Definition nuklear.h:5491
@ NK_WINDOW_REMOVE_ROM
Removes read only mode at the end of the window.
Definition nuklear.h:5497
NK_API void nk_draw_image(struct nk_command_buffer *, struct nk_rect, const struct nk_image *, struct nk_color)
misc
NK_API nk_bool nk_window_is_hovered(const struct nk_context *ctx)
NK_API void nk_fill_rect(struct nk_command_buffer *, struct nk_rect, float rounding, struct nk_color)
filled shades
NK_API void nk_layout_reset_min_row_height(struct nk_context *)
Reset the currently used minimum row height back to font_height + text_padding + padding
nk_text_width_f width
!< max height of the font
Definition nuklear.h:4009
float height
!< user provided font handle
Definition nuklear.h:4008