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_combo.c
1#include "nuklear.h"
2#include "nuklear_internal.h"
3
4/* ==============================================================
5 *
6 * COMBO
7 *
8 * ===============================================================*/
9NK_INTERN nk_bool
10nk_combo_begin(struct nk_context *ctx, struct nk_window *win,
11 struct nk_vec2 size, nk_bool is_clicked, struct nk_rect header)
12{
13 struct nk_window *popup;
14 int is_open = 0;
15 int is_active = 0;
16 struct nk_rect body;
17 nk_hash hash;
18
19 NK_ASSERT(ctx);
20 NK_ASSERT(ctx->current);
21 NK_ASSERT(ctx->current->layout);
22 if (!ctx || !ctx->current || !ctx->current->layout)
23 return 0;
24
25 popup = win->popup.win;
26 body.x = header.x;
27 body.w = size.x;
28 body.y = header.y + header.h-ctx->style.window.combo_border;
29 body.h = size.y;
30
31 hash = win->popup.combo_count++;
32 is_open = (popup) ? nk_true:nk_false;
33 is_active = (popup && (win->popup.name == hash) && win->popup.type == NK_PANEL_COMBO);
34 if ((is_clicked && is_open && !is_active) || (is_open && !is_active) ||
35 (!is_open && !is_active && !is_clicked)) return 0;
36 if (!nk_nonblock_begin(ctx, 0, body,
37 (is_clicked && is_open)?nk_rect(0,0,0,0):header, NK_PANEL_COMBO)) return 0;
38
39 win->popup.type = NK_PANEL_COMBO;
40 win->popup.name = hash;
41 return 1;
42}
43NK_API nk_bool
44nk_combo_begin_text(struct nk_context *ctx, const char *selected, int len,
45 struct nk_vec2 size)
46{
47 const struct nk_input *in;
48 struct nk_window *win;
49 struct nk_style *style;
50
52 int is_clicked = nk_false;
53 struct nk_rect header;
54 const struct nk_style_item *background;
55 struct nk_text text;
56
57 NK_ASSERT(ctx);
58 NK_ASSERT(selected);
59 NK_ASSERT(ctx->current);
60 NK_ASSERT(ctx->current->layout);
61 if (!ctx || !ctx->current || !ctx->current->layout || !selected)
62 return 0;
63
64 win = ctx->current;
65 style = &ctx->style;
66 s = nk_widget(&header, ctx);
67 if (s == NK_WIDGET_INVALID)
68 return 0;
69
70 in = (win->layout->flags & NK_WINDOW_ROM || s == NK_WIDGET_DISABLED || s == NK_WIDGET_ROM)? 0: &ctx->input;
71 if (nk_button_behavior(&ctx->last_widget_state, header, in, NK_BUTTON_DEFAULT))
72 is_clicked = nk_true;
73
74 /* draw combo box header background and border */
75 if (ctx->last_widget_state & NK_WIDGET_STATE_ACTIVED) {
76 background = &style->combo.active;
77 text.text = style->combo.label_active;
78 } else if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER) {
79 background = &style->combo.hover;
80 text.text = style->combo.label_hover;
81 } else {
82 background = &style->combo.normal;
83 text.text = style->combo.label_normal;
84 }
85
86 text.text = nk_rgb_factor(text.text, style->combo.color_factor);
87
88 switch(background->type) {
89 case NK_STYLE_ITEM_IMAGE:
90 text.background = nk_rgba(0, 0, 0, 0);
91 nk_draw_image(&win->buffer, header, &background->data.image, nk_rgb_factor(nk_white, style->combo.color_factor));
92 break;
93 case NK_STYLE_ITEM_NINE_SLICE:
94 text.background = nk_rgba(0, 0, 0, 0);
95 nk_draw_nine_slice(&win->buffer, header, &background->data.slice, nk_rgb_factor(nk_white, style->combo.color_factor));
96 break;
97 case NK_STYLE_ITEM_COLOR:
98 text.background = background->data.color;
99 nk_fill_rect(&win->buffer, header, style->combo.rounding, nk_rgb_factor(background->data.color, style->combo.color_factor));
100 nk_stroke_rect(&win->buffer, header, style->combo.rounding, style->combo.border, nk_rgb_factor(style->combo.border_color, style->combo.color_factor));
101 break;
102 }
103 {
104 /* print currently selected text item */
105 struct nk_rect label;
106 struct nk_rect button;
107 struct nk_rect content;
108 int draw_button_symbol;
109
110 enum nk_symbol_type sym;
111 if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER)
112 sym = style->combo.sym_hover;
113 else if (is_clicked)
114 sym = style->combo.sym_active;
115 else
116 sym = style->combo.sym_normal;
117
118 /* represents whether or not the combo's button symbol should be drawn */
119 draw_button_symbol = sym != NK_SYMBOL_NONE;
120
121 /* calculate button */
122 button.w = header.h - 2 * style->combo.button_padding.y;
123 button.x = (header.x + header.w - header.h) - style->combo.button_padding.x;
124 button.y = header.y + style->combo.button_padding.y;
125 button.h = button.w;
126
127 content.x = button.x + style->combo.button.padding.x;
128 content.y = button.y + style->combo.button.padding.y;
129 content.w = button.w - 2 * style->combo.button.padding.x;
130 content.h = button.h - 2 * style->combo.button.padding.y;
131
132 /* draw selected label */
133 text.padding = nk_vec2(0,0);
134 label.x = header.x + style->combo.content_padding.x;
135 label.y = header.y + style->combo.content_padding.y;
136 label.h = header.h - 2 * style->combo.content_padding.y;
137 if (draw_button_symbol)
138 label.w = button.x - (style->combo.content_padding.x + style->combo.spacing.x) - label.x;
139 else
140 label.w = header.w - 2 * style->combo.content_padding.x;
141 nk_widget_text(&win->buffer, label, selected, len, &text,
142 NK_TEXT_LEFT, ctx->style.font);
143
144 /* draw open/close button */
145 if (draw_button_symbol)
146 nk_draw_button_symbol(&win->buffer, &button, &content, ctx->last_widget_state,
147 &ctx->style.combo.button, sym, style->font);
148 }
149 return nk_combo_begin(ctx, win, size, is_clicked, header);
150}
151NK_API nk_bool
152nk_combo_begin_label(struct nk_context *ctx, const char *selected, struct nk_vec2 size)
153{
154 return nk_combo_begin_text(ctx, selected, nk_strlen(selected), size);
155}
156NK_API nk_bool
157nk_combo_begin_color(struct nk_context *ctx, struct nk_color color, struct nk_vec2 size)
158{
159 struct nk_window *win;
160 struct nk_style *style;
161 const struct nk_input *in;
162
163 struct nk_rect header;
164 int is_clicked = nk_false;
166 const struct nk_style_item *background;
167
168 NK_ASSERT(ctx);
169 NK_ASSERT(ctx->current);
170 NK_ASSERT(ctx->current->layout);
171 if (!ctx || !ctx->current || !ctx->current->layout)
172 return 0;
173
174 win = ctx->current;
175 style = &ctx->style;
176 s = nk_widget(&header, ctx);
177 if (s == NK_WIDGET_INVALID)
178 return 0;
179
180 in = (win->layout->flags & NK_WINDOW_ROM || s == NK_WIDGET_DISABLED || s == NK_WIDGET_ROM)? 0: &ctx->input;
181 if (nk_button_behavior(&ctx->last_widget_state, header, in, NK_BUTTON_DEFAULT))
182 is_clicked = nk_true;
183
184 /* draw combo box header background and border */
185 if (ctx->last_widget_state & NK_WIDGET_STATE_ACTIVED)
186 background = &style->combo.active;
187 else if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER)
188 background = &style->combo.hover;
189 else background = &style->combo.normal;
190
191 switch(background->type) {
192 case NK_STYLE_ITEM_IMAGE:
193 nk_draw_image(&win->buffer, header, &background->data.image, nk_rgb_factor(nk_white, style->combo.color_factor));
194 break;
195 case NK_STYLE_ITEM_NINE_SLICE:
196 nk_draw_nine_slice(&win->buffer, header, &background->data.slice, nk_rgb_factor(nk_white, style->combo.color_factor));
197 break;
198 case NK_STYLE_ITEM_COLOR:
199 nk_fill_rect(&win->buffer, header, style->combo.rounding, nk_rgb_factor(background->data.color, style->combo.color_factor));
200 nk_stroke_rect(&win->buffer, header, style->combo.rounding, style->combo.border, nk_rgb_factor(style->combo.border_color, style->combo.color_factor));
201 break;
202 }
203 {
204 struct nk_rect content;
205 struct nk_rect button;
206 struct nk_rect bounds;
207 int draw_button_symbol;
208
209 enum nk_symbol_type sym;
210 if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER)
211 sym = style->combo.sym_hover;
212 else if (is_clicked)
213 sym = style->combo.sym_active;
214 else sym = style->combo.sym_normal;
215
216 /* represents whether or not the combo's button symbol should be drawn */
217 draw_button_symbol = sym != NK_SYMBOL_NONE;
218
219 /* calculate button */
220 button.w = header.h - 2 * style->combo.button_padding.y;
221 button.x = (header.x + header.w - header.h) - style->combo.button_padding.x;
222 button.y = header.y + style->combo.button_padding.y;
223 button.h = button.w;
224
225 content.x = button.x + style->combo.button.padding.x;
226 content.y = button.y + style->combo.button.padding.y;
227 content.w = button.w - 2 * style->combo.button.padding.x;
228 content.h = button.h - 2 * style->combo.button.padding.y;
229
230 /* draw color */
231 bounds.h = header.h - 4 * style->combo.content_padding.y;
232 bounds.y = header.y + 2 * style->combo.content_padding.y;
233 bounds.x = header.x + 2 * style->combo.content_padding.x;
234 if (draw_button_symbol)
235 bounds.w = (button.x - (style->combo.content_padding.x + style->combo.spacing.x)) - bounds.x;
236 else
237 bounds.w = header.w - 4 * style->combo.content_padding.x;
238 nk_fill_rect(&win->buffer, bounds, 0, nk_rgb_factor(color, style->combo.color_factor));
239
240 /* draw open/close button */
241 if (draw_button_symbol)
242 nk_draw_button_symbol(&win->buffer, &button, &content, ctx->last_widget_state,
243 &ctx->style.combo.button, sym, style->font);
244 }
245 return nk_combo_begin(ctx, win, size, is_clicked, header);
246}
247NK_API nk_bool
248nk_combo_begin_symbol(struct nk_context *ctx, enum nk_symbol_type symbol, struct nk_vec2 size)
249{
250 struct nk_window *win;
251 struct nk_style *style;
252 const struct nk_input *in;
253
254 struct nk_rect header;
255 int is_clicked = nk_false;
257 const struct nk_style_item *background;
258 struct nk_color sym_background;
259 struct nk_color symbol_color;
260
261 NK_ASSERT(ctx);
262 NK_ASSERT(ctx->current);
263 NK_ASSERT(ctx->current->layout);
264 if (!ctx || !ctx->current || !ctx->current->layout)
265 return 0;
266
267 win = ctx->current;
268 style = &ctx->style;
269 s = nk_widget(&header, ctx);
270 if (s == NK_WIDGET_INVALID)
271 return 0;
272
273 in = (win->layout->flags & NK_WINDOW_ROM || s == NK_WIDGET_DISABLED || s == NK_WIDGET_ROM)? 0: &ctx->input;
274 if (nk_button_behavior(&ctx->last_widget_state, header, in, NK_BUTTON_DEFAULT))
275 is_clicked = nk_true;
276
277 /* draw combo box header background and border */
278 if (ctx->last_widget_state & NK_WIDGET_STATE_ACTIVED) {
279 background = &style->combo.active;
280 symbol_color = style->combo.symbol_active;
281 } else if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER) {
282 background = &style->combo.hover;
283 symbol_color = style->combo.symbol_hover;
284 } else {
285 background = &style->combo.normal;
286 symbol_color = style->combo.symbol_hover;
287 }
288
289 symbol_color = nk_rgb_factor(symbol_color, style->combo.color_factor);
290
291 switch(background->type) {
292 case NK_STYLE_ITEM_IMAGE:
293 sym_background = nk_rgba(0, 0, 0, 0);
294 nk_draw_image(&win->buffer, header, &background->data.image, nk_rgb_factor(nk_white, style->combo.color_factor));
295 break;
296 case NK_STYLE_ITEM_NINE_SLICE:
297 sym_background = nk_rgba(0, 0, 0, 0);
298 nk_draw_nine_slice(&win->buffer, header, &background->data.slice, nk_rgb_factor(nk_white, style->combo.color_factor));
299 break;
300 case NK_STYLE_ITEM_COLOR:
301 sym_background = background->data.color;
302 nk_fill_rect(&win->buffer, header, style->combo.rounding, nk_rgb_factor(background->data.color, style->combo.color_factor));
303 nk_stroke_rect(&win->buffer, header, style->combo.rounding, style->combo.border, nk_rgb_factor(style->combo.border_color, style->combo.color_factor));
304 break;
305 }
306 {
307 struct nk_rect bounds = {0,0,0,0};
308 struct nk_rect content;
309 struct nk_rect button;
310
311 enum nk_symbol_type sym;
312 if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER)
313 sym = style->combo.sym_hover;
314 else if (is_clicked)
315 sym = style->combo.sym_active;
316 else sym = style->combo.sym_normal;
317
318 /* calculate button */
319 button.w = header.h - 2 * style->combo.button_padding.y;
320 button.x = (header.x + header.w - header.h) - style->combo.button_padding.y;
321 button.y = header.y + style->combo.button_padding.y;
322 button.h = button.w;
323
324 content.x = button.x + style->combo.button.padding.x;
325 content.y = button.y + style->combo.button.padding.y;
326 content.w = button.w - 2 * style->combo.button.padding.x;
327 content.h = button.h - 2 * style->combo.button.padding.y;
328
329 /* draw symbol */
330 bounds.h = header.h - 2 * style->combo.content_padding.y;
331 bounds.y = header.y + style->combo.content_padding.y;
332 bounds.x = header.x + style->combo.content_padding.x;
333 bounds.w = (button.x - style->combo.content_padding.y) - bounds.x;
334 nk_draw_symbol(&win->buffer, symbol, bounds, sym_background, symbol_color,
335 1.0f, style->font);
336
337 /* draw open/close button */
338 nk_draw_button_symbol(&win->buffer, &bounds, &content, ctx->last_widget_state,
339 &ctx->style.combo.button, sym, style->font);
340 }
341 return nk_combo_begin(ctx, win, size, is_clicked, header);
342}
343NK_API nk_bool
344nk_combo_begin_symbol_text(struct nk_context *ctx, const char *selected, int len,
345 enum nk_symbol_type symbol, struct nk_vec2 size)
346{
347 struct nk_window *win;
348 struct nk_style *style;
349 struct nk_input *in;
350
351 struct nk_rect header;
352 int is_clicked = nk_false;
354 const struct nk_style_item *background;
355 struct nk_color symbol_color;
356 struct nk_text text;
357
358 NK_ASSERT(ctx);
359 NK_ASSERT(ctx->current);
360 NK_ASSERT(ctx->current->layout);
361 if (!ctx || !ctx->current || !ctx->current->layout)
362 return 0;
363
364 win = ctx->current;
365 style = &ctx->style;
366 s = nk_widget(&header, ctx);
367 if (!s) return 0;
368
369 in = (win->layout->flags & NK_WINDOW_ROM || s == NK_WIDGET_DISABLED || s == NK_WIDGET_ROM)? 0: &ctx->input;
370 if (nk_button_behavior(&ctx->last_widget_state, header, in, NK_BUTTON_DEFAULT))
371 is_clicked = nk_true;
372
373 /* draw combo box header background and border */
374 if (ctx->last_widget_state & NK_WIDGET_STATE_ACTIVED) {
375 background = &style->combo.active;
376 symbol_color = style->combo.symbol_active;
377 text.text = style->combo.label_active;
378 } else if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER) {
379 background = &style->combo.hover;
380 symbol_color = style->combo.symbol_hover;
381 text.text = style->combo.label_hover;
382 } else {
383 background = &style->combo.normal;
384 symbol_color = style->combo.symbol_normal;
385 text.text = style->combo.label_normal;
386 }
387
388 text.text = nk_rgb_factor(text.text, style->combo.color_factor);
389 symbol_color = nk_rgb_factor(symbol_color, style->combo.color_factor);
390
391 switch(background->type) {
392 case NK_STYLE_ITEM_IMAGE:
393 text.background = nk_rgba(0, 0, 0, 0);
394 nk_draw_image(&win->buffer, header, &background->data.image, nk_rgb_factor(nk_white, style->combo.color_factor));
395 break;
396 case NK_STYLE_ITEM_NINE_SLICE:
397 text.background = nk_rgba(0, 0, 0, 0);
398 nk_draw_nine_slice(&win->buffer, header, &background->data.slice, nk_rgb_factor(nk_white, style->combo.color_factor));
399 break;
400 case NK_STYLE_ITEM_COLOR:
401 text.background = background->data.color;
402 nk_fill_rect(&win->buffer, header, style->combo.rounding, nk_rgb_factor(background->data.color, style->combo.color_factor));
403 nk_stroke_rect(&win->buffer, header, style->combo.rounding, style->combo.border, nk_rgb_factor(style->combo.border_color, style->combo.color_factor));
404 break;
405 }
406 {
407 struct nk_rect content;
408 struct nk_rect button;
409 struct nk_rect label;
410 struct nk_rect image;
411
412 enum nk_symbol_type sym;
413 if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER)
414 sym = style->combo.sym_hover;
415 else if (is_clicked)
416 sym = style->combo.sym_active;
417 else sym = style->combo.sym_normal;
418
419 /* calculate button */
420 button.w = header.h - 2 * style->combo.button_padding.y;
421 button.x = (header.x + header.w - header.h) - style->combo.button_padding.x;
422 button.y = header.y + style->combo.button_padding.y;
423 button.h = button.w;
424
425 content.x = button.x + style->combo.button.padding.x;
426 content.y = button.y + style->combo.button.padding.y;
427 content.w = button.w - 2 * style->combo.button.padding.x;
428 content.h = button.h - 2 * style->combo.button.padding.y;
429 nk_draw_button_symbol(&win->buffer, &button, &content, ctx->last_widget_state,
430 &ctx->style.combo.button, sym, style->font);
431
432 /* draw symbol */
433 image.x = header.x + style->combo.content_padding.x;
434 image.y = header.y + style->combo.content_padding.y;
435 image.h = header.h - 2 * style->combo.content_padding.y;
436 image.w = image.h;
437 nk_draw_symbol(&win->buffer, symbol, image, text.background, symbol_color,
438 1.0f, style->font);
439
440 /* draw label */
441 text.padding = nk_vec2(0,0);
442 label.x = image.x + image.w + style->combo.spacing.x + style->combo.content_padding.x;
443 label.y = header.y + style->combo.content_padding.y;
444 label.w = (button.x - style->combo.content_padding.x) - label.x;
445 label.h = header.h - 2 * style->combo.content_padding.y;
446 nk_widget_text(&win->buffer, label, selected, len, &text, NK_TEXT_LEFT, style->font);
447 }
448 return nk_combo_begin(ctx, win, size, is_clicked, header);
449}
450NK_API nk_bool
451nk_combo_begin_image(struct nk_context *ctx, struct nk_image img, struct nk_vec2 size)
452{
453 struct nk_window *win;
454 struct nk_style *style;
455 const struct nk_input *in;
456
457 struct nk_rect header;
458 int is_clicked = nk_false;
460 const struct nk_style_item *background;
461
462 NK_ASSERT(ctx);
463 NK_ASSERT(ctx->current);
464 NK_ASSERT(ctx->current->layout);
465 if (!ctx || !ctx->current || !ctx->current->layout)
466 return 0;
467
468 win = ctx->current;
469 style = &ctx->style;
470 s = nk_widget(&header, ctx);
471 if (s == NK_WIDGET_INVALID)
472 return 0;
473
474 in = (win->layout->flags & NK_WINDOW_ROM || s == NK_WIDGET_DISABLED || s == NK_WIDGET_ROM)? 0: &ctx->input;
475 if (nk_button_behavior(&ctx->last_widget_state, header, in, NK_BUTTON_DEFAULT))
476 is_clicked = nk_true;
477
478 /* draw combo box header background and border */
479 if (ctx->last_widget_state & NK_WIDGET_STATE_ACTIVED)
480 background = &style->combo.active;
481 else if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER)
482 background = &style->combo.hover;
483 else background = &style->combo.normal;
484
485 switch (background->type) {
486 case NK_STYLE_ITEM_IMAGE:
487 nk_draw_image(&win->buffer, header, &background->data.image, nk_rgb_factor(nk_white, style->combo.color_factor));
488 break;
489 case NK_STYLE_ITEM_NINE_SLICE:
490 nk_draw_nine_slice(&win->buffer, header, &background->data.slice, nk_rgb_factor(nk_white, style->combo.color_factor));
491 break;
492 case NK_STYLE_ITEM_COLOR:
493 nk_fill_rect(&win->buffer, header, style->combo.rounding, nk_rgb_factor(background->data.color, style->combo.color_factor));
494 nk_stroke_rect(&win->buffer, header, style->combo.rounding, style->combo.border, nk_rgb_factor(style->combo.border_color, style->combo.color_factor));
495 break;
496 }
497 {
498 struct nk_rect bounds = {0,0,0,0};
499 struct nk_rect content;
500 struct nk_rect button;
501 int draw_button_symbol;
502
503 enum nk_symbol_type sym;
504 if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER)
505 sym = style->combo.sym_hover;
506 else if (is_clicked)
507 sym = style->combo.sym_active;
508 else sym = style->combo.sym_normal;
509
510 /* represents whether or not the combo's button symbol should be drawn */
511 draw_button_symbol = sym != NK_SYMBOL_NONE;
512
513 /* calculate button */
514 button.w = header.h - 2 * style->combo.button_padding.y;
515 button.x = (header.x + header.w - header.h) - style->combo.button_padding.y;
516 button.y = header.y + style->combo.button_padding.y;
517 button.h = button.w;
518
519 content.x = button.x + style->combo.button.padding.x;
520 content.y = button.y + style->combo.button.padding.y;
521 content.w = button.w - 2 * style->combo.button.padding.x;
522 content.h = button.h - 2 * style->combo.button.padding.y;
523
524 /* draw image */
525 bounds.h = header.h - 2 * style->combo.content_padding.y;
526 bounds.y = header.y + style->combo.content_padding.y;
527 bounds.x = header.x + style->combo.content_padding.x;
528 if (draw_button_symbol)
529 bounds.w = (button.x - style->combo.content_padding.y) - bounds.x;
530 else
531 bounds.w = header.w - 2 * style->combo.content_padding.x;
532 nk_draw_image(&win->buffer, bounds, &img, nk_rgb_factor(nk_white, style->combo.color_factor));
533
534 /* draw open/close button */
535 if (draw_button_symbol)
536 nk_draw_button_symbol(&win->buffer, &bounds, &content, ctx->last_widget_state,
537 &ctx->style.combo.button, sym, style->font);
538 }
539 return nk_combo_begin(ctx, win, size, is_clicked, header);
540}
541NK_API nk_bool
542nk_combo_begin_image_text(struct nk_context *ctx, const char *selected, int len,
543 struct nk_image img, struct nk_vec2 size)
544{
545 struct nk_window *win;
546 struct nk_style *style;
547 struct nk_input *in;
548
549 struct nk_rect header;
550 int is_clicked = nk_false;
552 const struct nk_style_item *background;
553 struct nk_text text;
554
555 NK_ASSERT(ctx);
556 NK_ASSERT(ctx->current);
557 NK_ASSERT(ctx->current->layout);
558 if (!ctx || !ctx->current || !ctx->current->layout)
559 return 0;
560
561 win = ctx->current;
562 style = &ctx->style;
563 s = nk_widget(&header, ctx);
564 if (!s) return 0;
565
566 in = (win->layout->flags & NK_WINDOW_ROM || s == NK_WIDGET_DISABLED || s == NK_WIDGET_ROM)? 0: &ctx->input;
567 if (nk_button_behavior(&ctx->last_widget_state, header, in, NK_BUTTON_DEFAULT))
568 is_clicked = nk_true;
569
570 /* draw combo box header background and border */
571 if (ctx->last_widget_state & NK_WIDGET_STATE_ACTIVED) {
572 background = &style->combo.active;
573 text.text = style->combo.label_active;
574 } else if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER) {
575 background = &style->combo.hover;
576 text.text = style->combo.label_hover;
577 } else {
578 background = &style->combo.normal;
579 text.text = style->combo.label_normal;
580 }
581
582 text.text = nk_rgb_factor(text.text, style->combo.color_factor);
583
584 switch(background->type) {
585 case NK_STYLE_ITEM_IMAGE:
586 text.background = nk_rgba(0, 0, 0, 0);
587 nk_draw_image(&win->buffer, header, &background->data.image, nk_rgb_factor(nk_white, style->combo.color_factor));
588 break;
589 case NK_STYLE_ITEM_NINE_SLICE:
590 text.background = nk_rgba(0, 0, 0, 0);
591 nk_draw_nine_slice(&win->buffer, header, &background->data.slice, nk_rgb_factor(nk_white, style->combo.color_factor));
592 break;
593 case NK_STYLE_ITEM_COLOR:
594 text.background = background->data.color;
595 nk_fill_rect(&win->buffer, header, style->combo.rounding, nk_rgb_factor(background->data.color, style->combo.color_factor));
596 nk_stroke_rect(&win->buffer, header, style->combo.rounding, style->combo.border, nk_rgb_factor(style->combo.border_color, style->combo.color_factor));
597 break;
598 }
599 {
600 struct nk_rect content;
601 struct nk_rect button;
602 struct nk_rect label;
603 struct nk_rect image;
604 int draw_button_symbol;
605
606 enum nk_symbol_type sym;
607 if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER)
608 sym = style->combo.sym_hover;
609 else if (is_clicked)
610 sym = style->combo.sym_active;
611 else sym = style->combo.sym_normal;
612
613 /* represents whether or not the combo's button symbol should be drawn */
614 draw_button_symbol = sym != NK_SYMBOL_NONE;
615
616 /* calculate button */
617 button.w = header.h - 2 * style->combo.button_padding.y;
618 button.x = (header.x + header.w - header.h) - style->combo.button_padding.x;
619 button.y = header.y + style->combo.button_padding.y;
620 button.h = button.w;
621
622 content.x = button.x + style->combo.button.padding.x;
623 content.y = button.y + style->combo.button.padding.y;
624 content.w = button.w - 2 * style->combo.button.padding.x;
625 content.h = button.h - 2 * style->combo.button.padding.y;
626 if (draw_button_symbol)
627 nk_draw_button_symbol(&win->buffer, &button, &content, ctx->last_widget_state,
628 &ctx->style.combo.button, sym, style->font);
629
630 /* draw image */
631 image.x = header.x + style->combo.content_padding.x;
632 image.y = header.y + style->combo.content_padding.y;
633 image.h = header.h - 2 * style->combo.content_padding.y;
634 image.w = image.h;
635 nk_draw_image(&win->buffer, image, &img, nk_rgb_factor(nk_white, style->combo.color_factor));
636
637 /* draw label */
638 text.padding = nk_vec2(0,0);
639 label.x = image.x + image.w + style->combo.spacing.x + style->combo.content_padding.x;
640 label.y = header.y + style->combo.content_padding.y;
641 label.h = header.h - 2 * style->combo.content_padding.y;
642 if (draw_button_symbol)
643 label.w = (button.x - style->combo.content_padding.x) - label.x;
644 else
645 label.w = (header.x + header.w - style->combo.content_padding.x) - label.x;
646 nk_widget_text(&win->buffer, label, selected, len, &text, NK_TEXT_LEFT, style->font);
647 }
648 return nk_combo_begin(ctx, win, size, is_clicked, header);
649}
650NK_API nk_bool
651nk_combo_begin_symbol_label(struct nk_context *ctx,
652 const char *selected, enum nk_symbol_type type, struct nk_vec2 size)
653{
654 return nk_combo_begin_symbol_text(ctx, selected, nk_strlen(selected), type, size);
655}
656NK_API nk_bool
657nk_combo_begin_image_label(struct nk_context *ctx,
658 const char *selected, struct nk_image img, struct nk_vec2 size)
659{
660 return nk_combo_begin_image_text(ctx, selected, nk_strlen(selected), img, size);
661}
662NK_API nk_bool
663nk_combo_item_text(struct nk_context *ctx, const char *text, int len,nk_flags align)
664{
665 return nk_contextual_item_text(ctx, text, len, align);
666}
667NK_API nk_bool
668nk_combo_item_label(struct nk_context *ctx, const char *label, nk_flags align)
669{
670 return nk_contextual_item_label(ctx, label, align);
671}
672NK_API nk_bool
673nk_combo_item_image_text(struct nk_context *ctx, struct nk_image img, const char *text,
674 int len, nk_flags alignment)
675{
676 return nk_contextual_item_image_text(ctx, img, text, len, alignment);
677}
678NK_API nk_bool
679nk_combo_item_image_label(struct nk_context *ctx, struct nk_image img,
680 const char *text, nk_flags alignment)
681{
682 return nk_contextual_item_image_label(ctx, img, text, alignment);
683}
684NK_API nk_bool
685nk_combo_item_symbol_text(struct nk_context *ctx, enum nk_symbol_type sym,
686 const char *text, int len, nk_flags alignment)
687{
688 return nk_contextual_item_symbol_text(ctx, sym, text, len, alignment);
689}
690NK_API nk_bool
691nk_combo_item_symbol_label(struct nk_context *ctx, enum nk_symbol_type sym,
692 const char *label, nk_flags alignment)
693{
694 return nk_contextual_item_symbol_label(ctx, sym, label, alignment);
695}
696NK_API void nk_combo_end(struct nk_context *ctx)
697{
698 nk_contextual_end(ctx);
699}
700NK_API void nk_combo_close(struct nk_context *ctx)
701{
702 nk_contextual_close(ctx);
703}
704NK_API int
705nk_combo(struct nk_context *ctx, const char *const *items, int count,
706 int selected, int item_height, struct nk_vec2 size)
707{
708 int i = 0;
709 int max_height;
710 struct nk_vec2 item_spacing;
711 struct nk_vec2 window_padding;
712
713 NK_ASSERT(ctx);
714 NK_ASSERT(items);
715 NK_ASSERT(ctx->current);
716 if (!ctx || !items ||!count)
717 return selected;
718
719 item_spacing = ctx->style.window.spacing;
720 window_padding = nk_panel_get_padding(&ctx->style, ctx->current->layout->type);
721 max_height = count * item_height + count * (int)item_spacing.y;
722 max_height += (int)item_spacing.y * 2 + (int)window_padding.y * 2;
723 size.y = NK_MIN(size.y, (float)max_height);
724 if (nk_combo_begin_label(ctx, items[selected], size)) {
725 nk_layout_row_dynamic(ctx, (float)item_height, 1);
726 for (i = 0; i < count; ++i) {
727 if (nk_combo_item_label(ctx, items[i], NK_TEXT_LEFT))
728 selected = i;
729 }
730 nk_combo_end(ctx);
731 }
732 return selected;
733}
734NK_API int
735nk_combo_separator(struct nk_context *ctx, const char *items_separated_by_separator,
736 int separator, int selected, int count, int item_height, struct nk_vec2 size)
737{
738 int i;
739 int max_height;
740 struct nk_vec2 item_spacing;
741 struct nk_vec2 window_padding;
742 const char *current_item;
743 const char *iter;
744 int length = 0;
745
746 NK_ASSERT(ctx);
747 NK_ASSERT(items_separated_by_separator);
748 if (!ctx || !items_separated_by_separator)
749 return selected;
750
751 /* calculate popup window */
752 item_spacing = ctx->style.window.spacing;
753 window_padding = nk_panel_get_padding(&ctx->style, ctx->current->layout->type);
754 max_height = count * item_height + count * (int)item_spacing.y;
755 max_height += (int)item_spacing.y * 2 + (int)window_padding.y * 2;
756 size.y = NK_MIN(size.y, (float)max_height);
757
758 /* find selected item */
759 current_item = items_separated_by_separator;
760 for (i = 0; i < count; ++i) {
761 iter = current_item;
762 while (*iter && *iter != separator) iter++;
763 length = (int)(iter - current_item);
764 if (i == selected) break;
765 current_item = iter + 1;
766 }
767
768 if (nk_combo_begin_text(ctx, current_item, length, size)) {
769 current_item = items_separated_by_separator;
770 nk_layout_row_dynamic(ctx, (float)item_height, 1);
771 for (i = 0; i < count; ++i) {
772 iter = current_item;
773 while (*iter && *iter != separator) iter++;
774 length = (int)(iter - current_item);
775 if (nk_combo_item_text(ctx, current_item, length, NK_TEXT_LEFT))
776 selected = i;
777 current_item = current_item + length + 1;
778 }
779 nk_combo_end(ctx);
780 }
781 return selected;
782}
783NK_API int
784nk_combo_string(struct nk_context *ctx, const char *items_separated_by_zeros,
785 int selected, int count, int item_height, struct nk_vec2 size)
786{
787 return nk_combo_separator(ctx, items_separated_by_zeros, '\0', selected, count, item_height, size);
788}
789NK_API int
790nk_combo_callback(struct nk_context *ctx, void(*item_getter)(void*, int, const char**),
791 void *userdata, int selected, int count, int item_height, struct nk_vec2 size)
792{
793 int i;
794 int max_height;
795 struct nk_vec2 item_spacing;
796 struct nk_vec2 window_padding;
797 const char *item;
798
799 NK_ASSERT(ctx);
800 NK_ASSERT(item_getter);
801 if (!ctx || !item_getter)
802 return selected;
803
804 /* calculate popup window */
805 item_spacing = ctx->style.window.spacing;
806 window_padding = nk_panel_get_padding(&ctx->style, ctx->current->layout->type);
807 max_height = count * item_height + count * (int)item_spacing.y;
808 max_height += (int)item_spacing.y * 2 + (int)window_padding.y * 2;
809 size.y = NK_MIN(size.y, (float)max_height);
810
811 item_getter(userdata, selected, &item);
812 if (nk_combo_begin_label(ctx, item, size)) {
813 nk_layout_row_dynamic(ctx, (float)item_height, 1);
814 for (i = 0; i < count; ++i) {
815 item_getter(userdata, i, &item);
816 if (nk_combo_item_label(ctx, item, NK_TEXT_LEFT))
817 selected = i;
818 }
819 nk_combo_end(ctx);
820 } return selected;
821}
822NK_API void
823nk_combobox(struct nk_context *ctx, const char *const *items, int count,
824 int *selected, int item_height, struct nk_vec2 size)
825{
826 *selected = nk_combo(ctx, items, count, *selected, item_height, size);
827}
828NK_API void
829nk_combobox_string(struct nk_context *ctx, const char *items_separated_by_zeros,
830 int *selected, int count, int item_height, struct nk_vec2 size)
831{
832 *selected = nk_combo_string(ctx, items_separated_by_zeros, *selected, count, item_height, size);
833}
834NK_API void
835nk_combobox_separator(struct nk_context *ctx, const char *items_separated_by_separator,
836 int separator, int *selected, int count, int item_height, struct nk_vec2 size)
837{
838 *selected = nk_combo_separator(ctx, items_separated_by_separator, separator,
839 *selected, count, item_height, size);
840}
841NK_API void
842nk_combobox_callback(struct nk_context *ctx,
843 void(*item_getter)(void* data, int id, const char **out_text),
844 void *userdata, int *selected, int count, int item_height, struct nk_vec2 size)
845{
846 *selected = nk_combo_callback(ctx, item_getter, userdata, *selected, count, item_height, size);
847}
main API and documentation file
@ NK_WINDOW_ROM
sets window widgets into a read only mode and does not allow input changes
Definition nuklear.h:5492
NK_API void nk_draw_image(struct nk_command_buffer *, struct nk_rect, const struct nk_image *, struct nk_color)
misc
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_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_WIDGET_STATE_ACTIVED
!< widget is being hovered
Definition nuklear.h:3092
@ NK_WIDGET_STATE_HOVER
!< widget has been hovered on the current frame
Definition nuklear.h:3091
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_INVALID
The widget cannot be seen and is completely out of view.
Definition nuklear.h:3082