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.
nuklear_layout.c
1 #include "nuklear.h"
2 #include "nuklear_internal.h"
3 
4 /* ===============================================================
5  *
6  * LAYOUT
7  *
8  * ===============================================================*/
9 NK_API void
10 nk_layout_set_min_row_height(struct nk_context *ctx, float height)
11 {
12  struct nk_window *win;
13  struct nk_panel *layout;
14 
15  NK_ASSERT(ctx);
16  NK_ASSERT(ctx->current);
17  NK_ASSERT(ctx->current->layout);
18  if (!ctx || !ctx->current || !ctx->current->layout)
19  return;
20 
21  win = ctx->current;
22  layout = win->layout;
23  layout->row.min_height = height;
24 }
25 NK_API void
27 {
28  struct nk_window *win;
29  struct nk_panel *layout;
30 
31  NK_ASSERT(ctx);
32  NK_ASSERT(ctx->current);
33  NK_ASSERT(ctx->current->layout);
34  if (!ctx || !ctx->current || !ctx->current->layout)
35  return;
36 
37  win = ctx->current;
38  layout = win->layout;
39  layout->row.min_height = ctx->style.font->height;
40  layout->row.min_height += ctx->style.text.padding.y*2;
41  layout->row.min_height += ctx->style.window.min_row_height_padding*2;
42 }
43 NK_LIB float
44 nk_layout_row_calculate_usable_space(const struct nk_style *style, enum nk_panel_type type,
45  float total_space, int columns)
46 {
47  float panel_spacing;
48  float panel_space;
49 
50  struct nk_vec2 spacing;
51 
52  NK_UNUSED(type);
53 
54  spacing = style->window.spacing;
55 
56  /* calculate the usable panel space */
57  panel_spacing = (float)NK_MAX(columns - 1, 0) * spacing.x;
58  panel_space = total_space - panel_spacing;
59  return panel_space;
60 }
61 NK_LIB void
62 nk_panel_layout(const struct nk_context *ctx, struct nk_window *win,
63  float height, int cols)
64 {
65  struct nk_panel *layout;
66  const struct nk_style *style;
67  struct nk_command_buffer *out;
68 
69  struct nk_vec2 item_spacing;
70  struct nk_color color;
71 
72  NK_ASSERT(ctx);
73  NK_ASSERT(ctx->current);
74  NK_ASSERT(ctx->current->layout);
75  if (!ctx || !ctx->current || !ctx->current->layout)
76  return;
77 
78  /* prefetch some configuration data */
79  layout = win->layout;
80  style = &ctx->style;
81  out = &win->buffer;
82  color = style->window.background;
83  item_spacing = style->window.spacing;
84 
85  /* if one of these triggers you forgot to add an `if` condition around either
86  a window, group, popup, combobox or contextual menu `begin` and `end` block.
87  Example:
88  if (nk_begin(...) {...} nk_end(...); or
89  if (nk_group_begin(...) { nk_group_end(...);} */
90  NK_ASSERT(!(layout->flags & NK_WINDOW_MINIMIZED));
91  NK_ASSERT(!(layout->flags & NK_WINDOW_HIDDEN));
92  NK_ASSERT(!(layout->flags & NK_WINDOW_CLOSED));
93 
94  /* update the current row and set the current row layout */
95  layout->row.index = 0;
96  layout->at_y += layout->row.height;
97  layout->row.columns = cols;
98  if (height == 0.0f)
99  layout->row.height = NK_MAX(height, layout->row.min_height) + item_spacing.y;
100  else layout->row.height = height + item_spacing.y;
101 
102  layout->row.item_offset = 0;
103  if (layout->flags & NK_WINDOW_DYNAMIC) {
104  /* draw background for dynamic panels */
105  struct nk_rect background;
106  background.x = win->bounds.x;
107  background.w = win->bounds.w;
108  background.y = layout->at_y - 1.0f;
109  background.h = layout->row.height + 1.0f;
110  nk_fill_rect(out, background, 0, color);
111  }
112 }
113 NK_LIB void
114 nk_row_layout(struct nk_context *ctx, enum nk_layout_format fmt,
115  float height, int cols, int width)
116 {
117  /* update the current row and set the current row layout */
118  struct nk_window *win;
119  NK_ASSERT(ctx);
120  NK_ASSERT(ctx->current);
121  NK_ASSERT(ctx->current->layout);
122  if (!ctx || !ctx->current || !ctx->current->layout)
123  return;
124 
125  win = ctx->current;
126  nk_panel_layout(ctx, win, height, cols);
127  if (fmt == NK_DYNAMIC)
128  win->layout->row.type = NK_LAYOUT_DYNAMIC_FIXED;
129  else win->layout->row.type = NK_LAYOUT_STATIC_FIXED;
130 
131  win->layout->row.ratio = 0;
132  win->layout->row.filled = 0;
133  win->layout->row.item_offset = 0;
134  win->layout->row.item_width = (float)width;
135 }
136 NK_API float
137 nk_layout_ratio_from_pixel(const struct nk_context *ctx, float pixel_width)
138 {
139  struct nk_window *win;
140  NK_ASSERT(ctx);
141  NK_ASSERT(pixel_width);
142  if (!ctx || !ctx->current || !ctx->current->layout) return 0;
143  win = ctx->current;
144  return NK_CLAMP(0.0f, pixel_width/win->bounds.x, 1.0f);
145 }
146 NK_API void
147 nk_layout_row_dynamic(struct nk_context *ctx, float height, int cols)
148 {
149  nk_row_layout(ctx, NK_DYNAMIC, height, cols, 0);
150 }
151 NK_API void
152 nk_layout_row_static(struct nk_context *ctx, float height, int item_width, int cols)
153 {
154  nk_row_layout(ctx, NK_STATIC, height, cols, item_width);
155 }
156 NK_API void
157 nk_layout_row_begin(struct nk_context *ctx, enum nk_layout_format fmt,
158  float row_height, int cols)
159 {
160  struct nk_window *win;
161  struct nk_panel *layout;
162 
163  NK_ASSERT(ctx);
164  NK_ASSERT(ctx->current);
165  NK_ASSERT(ctx->current->layout);
166  if (!ctx || !ctx->current || !ctx->current->layout)
167  return;
168 
169  win = ctx->current;
170  layout = win->layout;
171  nk_panel_layout(ctx, win, row_height, cols);
172  if (fmt == NK_DYNAMIC)
173  layout->row.type = NK_LAYOUT_DYNAMIC_ROW;
174  else layout->row.type = NK_LAYOUT_STATIC_ROW;
175 
176  layout->row.ratio = 0;
177  layout->row.filled = 0;
178  layout->row.item_width = 0;
179  layout->row.item_offset = 0;
180  layout->row.columns = cols;
181 }
182 NK_API void
183 nk_layout_row_push(struct nk_context *ctx, float ratio_or_width)
184 {
185  struct nk_window *win;
186  struct nk_panel *layout;
187 
188  NK_ASSERT(ctx);
189  NK_ASSERT(ctx->current);
190  NK_ASSERT(ctx->current->layout);
191  if (!ctx || !ctx->current || !ctx->current->layout)
192  return;
193 
194  win = ctx->current;
195  layout = win->layout;
196  NK_ASSERT(layout->row.type == NK_LAYOUT_STATIC_ROW || layout->row.type == NK_LAYOUT_DYNAMIC_ROW);
197  if (layout->row.type != NK_LAYOUT_STATIC_ROW && layout->row.type != NK_LAYOUT_DYNAMIC_ROW)
198  return;
199 
200  if (layout->row.type == NK_LAYOUT_DYNAMIC_ROW) {
201  float ratio = ratio_or_width;
202  if ((ratio + layout->row.filled) > 1.0f) return;
203  if (ratio > 0.0f)
204  layout->row.item_width = NK_SATURATE(ratio);
205  else layout->row.item_width = 1.0f - layout->row.filled;
206  } else layout->row.item_width = ratio_or_width;
207 }
208 NK_API void
210 {
211  struct nk_window *win;
212  struct nk_panel *layout;
213 
214  NK_ASSERT(ctx);
215  NK_ASSERT(ctx->current);
216  NK_ASSERT(ctx->current->layout);
217  if (!ctx || !ctx->current || !ctx->current->layout)
218  return;
219 
220  win = ctx->current;
221  layout = win->layout;
222  NK_ASSERT(layout->row.type == NK_LAYOUT_STATIC_ROW || layout->row.type == NK_LAYOUT_DYNAMIC_ROW);
223  if (layout->row.type != NK_LAYOUT_STATIC_ROW && layout->row.type != NK_LAYOUT_DYNAMIC_ROW)
224  return;
225  layout->row.item_width = 0;
226  layout->row.item_offset = 0;
227 }
228 NK_API void
229 nk_layout_row(struct nk_context *ctx, enum nk_layout_format fmt,
230  float height, int cols, const float *ratio)
231 {
232  int i;
233  int n_undef = 0;
234  struct nk_window *win;
235  struct nk_panel *layout;
236 
237  NK_ASSERT(ctx);
238  NK_ASSERT(ctx->current);
239  NK_ASSERT(ctx->current->layout);
240  if (!ctx || !ctx->current || !ctx->current->layout)
241  return;
242 
243  win = ctx->current;
244  layout = win->layout;
245  nk_panel_layout(ctx, win, height, cols);
246  if (fmt == NK_DYNAMIC) {
247  /* calculate width of undefined widget ratios */
248  float r = 0;
249  layout->row.ratio = ratio;
250  for (i = 0; i < cols; ++i) {
251  if (ratio[i] < 0.0f)
252  n_undef++;
253  else r += ratio[i];
254  }
255  r = NK_SATURATE(1.0f - r);
256  layout->row.type = NK_LAYOUT_DYNAMIC;
257  layout->row.item_width = (r > 0 && n_undef > 0) ? (r / (float)n_undef):0;
258  } else {
259  layout->row.ratio = ratio;
260  layout->row.type = NK_LAYOUT_STATIC;
261  layout->row.item_width = 0;
262  layout->row.item_offset = 0;
263  }
264  layout->row.item_offset = 0;
265  layout->row.filled = 0;
266 }
267 NK_API void
268 nk_layout_row_template_begin(struct nk_context *ctx, float height)
269 {
270  struct nk_window *win;
271  struct nk_panel *layout;
272 
273  NK_ASSERT(ctx);
274  NK_ASSERT(ctx->current);
275  NK_ASSERT(ctx->current->layout);
276  if (!ctx || !ctx->current || !ctx->current->layout)
277  return;
278 
279  win = ctx->current;
280  layout = win->layout;
281  nk_panel_layout(ctx, win, height, 1);
282  layout->row.type = NK_LAYOUT_TEMPLATE;
283  layout->row.columns = 0;
284  layout->row.ratio = 0;
285  layout->row.item_width = 0;
286  layout->row.item_height = 0;
287  layout->row.item_offset = 0;
288  layout->row.filled = 0;
289  layout->row.item.x = 0;
290  layout->row.item.y = 0;
291  layout->row.item.w = 0;
292  layout->row.item.h = 0;
293 }
294 NK_API void
296 {
297  struct nk_window *win;
298  struct nk_panel *layout;
299 
300  NK_ASSERT(ctx);
301  NK_ASSERT(ctx->current);
302  NK_ASSERT(ctx->current->layout);
303  if (!ctx || !ctx->current || !ctx->current->layout)
304  return;
305 
306  win = ctx->current;
307  layout = win->layout;
308  NK_ASSERT(layout->row.type == NK_LAYOUT_TEMPLATE);
309  NK_ASSERT(layout->row.columns < NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS);
310  if (layout->row.type != NK_LAYOUT_TEMPLATE) return;
311  if (layout->row.columns >= NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS) return;
312  layout->row.templates[layout->row.columns++] = -1.0f;
313 }
314 NK_API void
316 {
317  struct nk_window *win;
318  struct nk_panel *layout;
319 
320  NK_ASSERT(ctx);
321  NK_ASSERT(ctx->current);
322  NK_ASSERT(ctx->current->layout);
323  if (!ctx || !ctx->current || !ctx->current->layout)
324  return;
325 
326  win = ctx->current;
327  layout = win->layout;
328  NK_ASSERT(layout->row.type == NK_LAYOUT_TEMPLATE);
329  NK_ASSERT(layout->row.columns < NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS);
330  if (layout->row.type != NK_LAYOUT_TEMPLATE) return;
331  if (layout->row.columns >= NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS) return;
332  layout->row.templates[layout->row.columns++] = -min_width;
333 }
334 NK_API void
336 {
337  struct nk_window *win;
338  struct nk_panel *layout;
339 
340  NK_ASSERT(ctx);
341  NK_ASSERT(ctx->current);
342  NK_ASSERT(ctx->current->layout);
343  if (!ctx || !ctx->current || !ctx->current->layout)
344  return;
345 
346  win = ctx->current;
347  layout = win->layout;
348  NK_ASSERT(layout->row.type == NK_LAYOUT_TEMPLATE);
349  NK_ASSERT(layout->row.columns < NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS);
350  if (layout->row.type != NK_LAYOUT_TEMPLATE) return;
351  if (layout->row.columns >= NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS) return;
352  layout->row.templates[layout->row.columns++] = width;
353 }
354 NK_API void
356 {
357  struct nk_window *win;
358  struct nk_panel *layout;
359 
360  int i = 0;
361  int variable_count = 0;
362  int min_variable_count = 0;
363  float min_fixed_width = 0.0f;
364  float total_fixed_width = 0.0f;
365  float max_variable_width = 0.0f;
366 
367  NK_ASSERT(ctx);
368  NK_ASSERT(ctx->current);
369  NK_ASSERT(ctx->current->layout);
370  if (!ctx || !ctx->current || !ctx->current->layout)
371  return;
372 
373  win = ctx->current;
374  layout = win->layout;
375  NK_ASSERT(layout->row.type == NK_LAYOUT_TEMPLATE);
376  if (layout->row.type != NK_LAYOUT_TEMPLATE) return;
377  for (i = 0; i < layout->row.columns; ++i) {
378  float width = layout->row.templates[i];
379  if (width >= 0.0f) {
380  total_fixed_width += width;
381  min_fixed_width += width;
382  } else if (width < -1.0f) {
383  width = -width;
384  total_fixed_width += width;
385  max_variable_width = NK_MAX(max_variable_width, width);
386  variable_count++;
387  } else {
388  min_variable_count++;
389  variable_count++;
390  }
391  }
392  if (variable_count) {
393  float space = nk_layout_row_calculate_usable_space(&ctx->style, layout->type,
394  layout->bounds.w, layout->row.columns);
395  float var_width = (NK_MAX(space-min_fixed_width,0.0f)) / (float)variable_count;
396  int enough_space = var_width >= max_variable_width;
397  if (!enough_space)
398  var_width = (NK_MAX(space-total_fixed_width,0)) / (float)min_variable_count;
399  for (i = 0; i < layout->row.columns; ++i) {
400  float *width = &layout->row.templates[i];
401  *width = (*width >= 0.0f)? *width: (*width < -1.0f && !enough_space)? -(*width): var_width;
402  }
403  }
404 }
405 NK_API void
406 nk_layout_space_begin(struct nk_context *ctx, enum nk_layout_format fmt,
407  float height, int widget_count)
408 {
409  struct nk_window *win;
410  struct nk_panel *layout;
411 
412  NK_ASSERT(ctx);
413  NK_ASSERT(ctx->current);
414  NK_ASSERT(ctx->current->layout);
415  if (!ctx || !ctx->current || !ctx->current->layout)
416  return;
417 
418  win = ctx->current;
419  layout = win->layout;
420  nk_panel_layout(ctx, win, height, widget_count);
421  if (fmt == NK_STATIC)
422  layout->row.type = NK_LAYOUT_STATIC_FREE;
423  else layout->row.type = NK_LAYOUT_DYNAMIC_FREE;
424 
425  layout->row.ratio = 0;
426  layout->row.filled = 0;
427  layout->row.item_width = 0;
428  layout->row.item_offset = 0;
429 }
430 NK_API void
432 {
433  struct nk_window *win;
434  struct nk_panel *layout;
435 
436  NK_ASSERT(ctx);
437  NK_ASSERT(ctx->current);
438  NK_ASSERT(ctx->current->layout);
439  if (!ctx || !ctx->current || !ctx->current->layout)
440  return;
441 
442  win = ctx->current;
443  layout = win->layout;
444  layout->row.item_width = 0;
445  layout->row.item_height = 0;
446  layout->row.item_offset = 0;
447  nk_zero(&layout->row.item, sizeof(layout->row.item));
448 }
449 NK_API void
450 nk_layout_space_push(struct nk_context *ctx, struct nk_rect rect)
451 {
452  struct nk_window *win;
453  struct nk_panel *layout;
454 
455  NK_ASSERT(ctx);
456  NK_ASSERT(ctx->current);
457  NK_ASSERT(ctx->current->layout);
458  if (!ctx || !ctx->current || !ctx->current->layout)
459  return;
460 
461  win = ctx->current;
462  layout = win->layout;
463  layout->row.item = rect;
464 }
465 NK_API struct nk_rect
466 nk_layout_space_bounds(const struct nk_context *ctx)
467 {
468  struct nk_rect ret;
469  struct nk_window *win;
470  struct nk_panel *layout;
471 
472  NK_ASSERT(ctx);
473  NK_ASSERT(ctx->current);
474  NK_ASSERT(ctx->current->layout);
475  win = ctx->current;
476  layout = win->layout;
477 
478  ret.x = layout->clip.x;
479  ret.y = layout->clip.y;
480  ret.w = layout->clip.w;
481  ret.h = layout->row.height;
482  return ret;
483 }
484 NK_API struct nk_rect
485 nk_layout_widget_bounds(const struct nk_context *ctx)
486 {
487  struct nk_rect ret;
488  struct nk_window *win;
489  struct nk_panel *layout;
490 
491  NK_ASSERT(ctx);
492  NK_ASSERT(ctx->current);
493  NK_ASSERT(ctx->current->layout);
494  win = ctx->current;
495  layout = win->layout;
496 
497  ret.x = layout->at_x;
498  ret.y = layout->at_y;
499  ret.w = layout->bounds.w - NK_MAX(layout->at_x - layout->bounds.x,0);
500  ret.h = layout->row.height;
501  return ret;
502 }
503 NK_API struct nk_vec2
504 nk_layout_space_to_screen(const struct nk_context *ctx, struct nk_vec2 ret)
505 {
506  struct nk_window *win;
507  struct nk_panel *layout;
508 
509  NK_ASSERT(ctx);
510  NK_ASSERT(ctx->current);
511  NK_ASSERT(ctx->current->layout);
512  win = ctx->current;
513  layout = win->layout;
514 
515  ret.x += layout->at_x - (float)*layout->offset_x;
516  ret.y += layout->at_y - (float)*layout->offset_y;
517  return ret;
518 }
519 NK_API struct nk_vec2
520 nk_layout_space_to_local(const struct nk_context *ctx, struct nk_vec2 ret)
521 {
522  struct nk_window *win;
523  struct nk_panel *layout;
524 
525  NK_ASSERT(ctx);
526  NK_ASSERT(ctx->current);
527  NK_ASSERT(ctx->current->layout);
528  win = ctx->current;
529  layout = win->layout;
530 
531  ret.x += -layout->at_x + (float)*layout->offset_x;
532  ret.y += -layout->at_y + (float)*layout->offset_y;
533  return ret;
534 }
535 NK_API struct nk_rect
536 nk_layout_space_rect_to_screen(const struct nk_context *ctx, struct nk_rect ret)
537 {
538  struct nk_window *win;
539  struct nk_panel *layout;
540 
541  NK_ASSERT(ctx);
542  NK_ASSERT(ctx->current);
543  NK_ASSERT(ctx->current->layout);
544  win = ctx->current;
545  layout = win->layout;
546 
547  ret.x += layout->at_x - (float)*layout->offset_x;
548  ret.y += layout->at_y - (float)*layout->offset_y;
549  return ret;
550 }
551 NK_API struct nk_rect
552 nk_layout_space_rect_to_local(const struct nk_context *ctx, struct nk_rect ret)
553 {
554  struct nk_window *win;
555  struct nk_panel *layout;
556 
557  NK_ASSERT(ctx);
558  NK_ASSERT(ctx->current);
559  NK_ASSERT(ctx->current->layout);
560  win = ctx->current;
561  layout = win->layout;
562 
563  ret.x += -layout->at_x + (float)*layout->offset_x;
564  ret.y += -layout->at_y + (float)*layout->offset_y;
565  return ret;
566 }
567 NK_LIB void
568 nk_panel_alloc_row(const struct nk_context *ctx, struct nk_window *win)
569 {
570  struct nk_panel *layout = win->layout;
571  struct nk_vec2 spacing = ctx->style.window.spacing;
572  const float row_height = layout->row.height - spacing.y;
573  nk_panel_layout(ctx, win, row_height, layout->row.columns);
574 }
575 NK_LIB void
576 nk_layout_widget_space(struct nk_rect *bounds, const struct nk_context *ctx,
577  struct nk_window *win, int modify)
578 {
579  struct nk_panel *layout;
580  const struct nk_style *style;
581 
582  struct nk_vec2 spacing;
583 
584  float item_offset = 0;
585  float item_width = 0;
586  float item_spacing = 0;
587  float panel_space = 0;
588 
589  NK_ASSERT(ctx);
590  NK_ASSERT(ctx->current);
591  NK_ASSERT(ctx->current->layout);
592  if (!ctx || !ctx->current || !ctx->current->layout)
593  return;
594 
595  win = ctx->current;
596  layout = win->layout;
597  style = &ctx->style;
598  NK_ASSERT(bounds);
599 
600  spacing = style->window.spacing;
601  panel_space = nk_layout_row_calculate_usable_space(&ctx->style, layout->type,
602  layout->bounds.w, layout->row.columns);
603 
604  #define NK_FRAC(x) (x - (float)(int)nk_roundf(x)) /* will be used to remove fookin gaps */
605  /* calculate the width of one item inside the current layout space */
606  switch (layout->row.type) {
607  case NK_LAYOUT_DYNAMIC_FIXED: {
608  /* scaling fixed size widgets item width */
609  float w = NK_MAX(1.0f,panel_space) / (float)layout->row.columns;
610  item_offset = (float)layout->row.index * w;
611  item_width = w + NK_FRAC(item_offset);
612  item_spacing = (float)layout->row.index * spacing.x;
613  } break;
614  case NK_LAYOUT_DYNAMIC_ROW: {
615  /* scaling single ratio widget width */
616  float w = layout->row.item_width * panel_space;
617  item_offset = layout->row.item_offset;
618  item_width = w + NK_FRAC(item_offset);
619  item_spacing = 0;
620 
621  if (modify) {
622  layout->row.item_offset += w + spacing.x;
623  layout->row.filled += layout->row.item_width;
624  layout->row.index = 0;
625  }
626  } break;
627  case NK_LAYOUT_DYNAMIC_FREE: {
628  /* panel width depended free widget placing */
629  bounds->x = layout->at_x + (layout->bounds.w * layout->row.item.x);
630  bounds->x -= (float)*layout->offset_x;
631  bounds->y = layout->at_y + (layout->row.height * layout->row.item.y);
632  bounds->y -= (float)*layout->offset_y;
633  bounds->w = layout->bounds.w * layout->row.item.w + NK_FRAC(bounds->x);
634  bounds->h = layout->row.height * layout->row.item.h + NK_FRAC(bounds->y);
635  return;
636  }
637  case NK_LAYOUT_DYNAMIC: {
638  /* scaling arrays of panel width ratios for every widget */
639  float ratio, w;
640  NK_ASSERT(layout->row.ratio);
641  ratio = (layout->row.ratio[layout->row.index] < 0) ?
642  layout->row.item_width : layout->row.ratio[layout->row.index];
643 
644  w = (ratio * panel_space);
645  item_spacing = (float)layout->row.index * spacing.x;
646  item_offset = layout->row.item_offset;
647  item_width = w + NK_FRAC(item_offset);
648 
649  if (modify) {
650  layout->row.item_offset += w;
651  layout->row.filled += ratio;
652  }
653  } break;
654  case NK_LAYOUT_STATIC_FIXED: {
655  /* non-scaling fixed widgets item width */
656  item_width = layout->row.item_width;
657  item_offset = (float)layout->row.index * item_width;
658  item_spacing = (float)layout->row.index * spacing.x;
659  } break;
660  case NK_LAYOUT_STATIC_ROW: {
661  /* scaling single ratio widget width */
662  item_width = layout->row.item_width;
663  item_offset = layout->row.item_offset;
664  item_spacing = (float)layout->row.index * spacing.x;
665  if (modify) layout->row.item_offset += item_width;
666  } break;
667  case NK_LAYOUT_STATIC_FREE: {
668  /* free widget placing */
669  bounds->x = layout->at_x + layout->row.item.x;
670  bounds->w = layout->row.item.w;
671  if (((bounds->x + bounds->w) > layout->max_x) && modify)
672  layout->max_x = (bounds->x + bounds->w);
673  bounds->x -= (float)*layout->offset_x;
674  bounds->y = layout->at_y + layout->row.item.y;
675  bounds->y -= (float)*layout->offset_y;
676  bounds->h = layout->row.item.h;
677  return;
678  }
679  case NK_LAYOUT_STATIC: {
680  /* non-scaling array of panel pixel width for every widget */
681  item_spacing = (float)layout->row.index * spacing.x;
682  item_width = layout->row.ratio[layout->row.index];
683  item_offset = layout->row.item_offset;
684  if (modify) layout->row.item_offset += item_width;
685  } break;
686  case NK_LAYOUT_TEMPLATE: {
687  /* stretchy row layout with combined dynamic/static widget width*/
688  float w;
689  NK_ASSERT(layout->row.index < layout->row.columns);
690  NK_ASSERT(layout->row.index < NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS);
691  w = layout->row.templates[layout->row.index];
692  item_offset = layout->row.item_offset;
693  item_width = w + NK_FRAC(item_offset);
694  item_spacing = (float)layout->row.index * spacing.x;
695  if (modify) layout->row.item_offset += w;
696  } break;
697  #undef NK_FRAC
698  default: NK_ASSERT(0); break;
699  };
700 
701  /* set the bounds of the newly allocated widget */
702  bounds->w = item_width;
703  bounds->h = layout->row.height - spacing.y;
704  bounds->y = layout->at_y - (float)*layout->offset_y;
705  bounds->x = layout->at_x + item_offset + item_spacing;
706  if (((bounds->x + bounds->w) > layout->max_x) && modify)
707  layout->max_x = bounds->x + bounds->w;
708  bounds->x -= (float)*layout->offset_x;
709 }
710 NK_LIB void
711 nk_panel_alloc_space(struct nk_rect *bounds, const struct nk_context *ctx)
712 {
713  struct nk_window *win;
714  struct nk_panel *layout;
715 
716  NK_ASSERT(ctx);
717  NK_ASSERT(ctx->current);
718  NK_ASSERT(ctx->current->layout);
719  if (!ctx || !ctx->current || !ctx->current->layout)
720  return;
721 
722  /* check if the end of the row has been hit and begin new row if so */
723  win = ctx->current;
724  layout = win->layout;
725  if (layout->row.index >= layout->row.columns)
726  nk_panel_alloc_row(ctx, win);
727 
728  /* calculate widget position and size */
729  nk_layout_widget_space(bounds, ctx, win, nk_true);
730  layout->row.index++;
731 }
732 NK_LIB void
733 nk_layout_peek(struct nk_rect *bounds, const struct nk_context *ctx)
734 {
735  float y;
736  int index;
737  struct nk_window *win;
738  struct nk_panel *layout;
739 
740  NK_ASSERT(ctx);
741  NK_ASSERT(ctx->current);
742  NK_ASSERT(ctx->current->layout);
743  if (!ctx || !ctx->current || !ctx->current->layout) {
744  *bounds = nk_rect(0,0,0,0);
745  return;
746  }
747 
748  win = ctx->current;
749  layout = win->layout;
750  y = layout->at_y;
751  index = layout->row.index;
752  if (layout->row.index >= layout->row.columns) {
753  layout->at_y += layout->row.height;
754  layout->row.index = 0;
755  }
756  nk_layout_widget_space(bounds, ctx, win, nk_false);
757  if (!layout->row.index) {
758  bounds->x -= layout->row.item_offset;
759  }
760  layout->at_y = y;
761  layout->row.index = index;
762 }
763 NK_API void
764 nk_spacer(struct nk_context *ctx )
765 {
766  struct nk_rect dummy_rect = { 0, 0, 0, 0 };
767  nk_panel_alloc_space( &dummy_rect, ctx );
768 }
main API and documentation file
NK_API void nk_layout_row_end(struct nk_context *)
Finished previously started row.
NK_API void nk_spacer(struct nk_context *ctx)
NK_API void nk_layout_space_end(struct nk_context *)
@ 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_DYNAMIC
special window type growing up in height while being filled to a certain maximum height
Definition: nuklear.h:5491
NK_API void nk_layout_row(struct nk_context *, enum nk_layout_format, float height, int cols, const float *ratio)
Specifies row columns in array as either window ratio or size.
NK_API struct nk_vec2 nk_layout_space_to_screen(const struct nk_context *ctx, struct nk_vec2 vec)
NK_API void nk_layout_row_template_push_dynamic(struct nk_context *)
NK_API struct nk_vec2 nk_layout_space_to_local(const struct nk_context *ctx, struct nk_vec2 vec)
NK_API void nk_fill_rect(struct nk_command_buffer *, struct nk_rect, float rounding, struct nk_color)
filled shades
Definition: nuklear_draw.c:152
NK_API void nk_layout_row_template_push_static(struct nk_context *, float width)
NK_API void nk_layout_row_dynamic(struct nk_context *ctx, float height, int cols)
Sets current row layout to share horizontal space between @cols number of widgets evenly.
NK_API void nk_layout_row_template_end(struct nk_context *)
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_API struct nk_rect nk_layout_space_rect_to_local(const struct nk_context *ctx, struct nk_rect bounds)
NK_API void nk_layout_set_min_row_height(struct nk_context *, float height)
Sets the currently used minimum row height.
NK_API void nk_layout_row_begin(struct nk_context *ctx, enum nk_layout_format fmt, float row_height, int cols)
Starts a new dynamic or fixed row with given height and columns.
NK_API void nk_layout_space_push(struct nk_context *, struct nk_rect bounds)
NK_API void nk_layout_row_template_begin(struct nk_context *, float row_height)
NK_API float nk_layout_ratio_from_pixel(const struct nk_context *ctx, float pixel_width)
Utility functions to calculate window ratio from pixel size.
NK_API void nk_layout_row_push(struct nk_context *, float value)
\breif Specifies either window ratio or width of a single column
NK_API struct nk_rect nk_layout_widget_bounds(const struct nk_context *ctx)
Returns the width of the next row allocate by one of the layouting functions.
NK_API struct nk_rect nk_layout_space_rect_to_screen(const struct nk_context *ctx, struct nk_rect bounds)
NK_API void nk_layout_space_begin(struct nk_context *, enum nk_layout_format, float height, int widget_count)
NK_API struct nk_rect nk_layout_space_bounds(const struct nk_context *ctx)
NK_API void nk_layout_row_template_push_variable(struct nk_context *, float min_width)
NK_API void nk_layout_row_static(struct nk_context *ctx, float height, int item_width, int cols)
Sets current row layout to fill @cols number of widgets in row with same @item_width horizontal size.
float height
!< user provided font handle
Definition: nuklear.h:4008