1 #include "nuklear.h"
2 #include "nuklear_internal.h"
3
4 /* ==============================================================
5 *
6 * COMBO
7 *
8 * ===============================================================*/
9 NK_INTERN int
nk_combo_begin(struct nk_context * ctx,struct nk_window * win,struct nk_vec2 size,int is_clicked,struct nk_rect header)10 nk_combo_begin(struct nk_context *ctx, struct nk_window *win,
11 struct nk_vec2 size, int 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 }
43 NK_API int
nk_combo_begin_text(struct nk_context * ctx,const char * selected,int len,struct nk_vec2 size)44 nk_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
51 enum nk_widget_layout_states s;
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_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 if (background->type == NK_STYLE_ITEM_IMAGE) {
86 text.background = nk_rgba(0,0,0,0);
87 nk_draw_image(&win->buffer, header, &background->data.image, nk_white);
88 } else {
89 text.background = background->data.color;
90 nk_fill_rect(&win->buffer, header, style->combo.rounding, background->data.color);
91 nk_stroke_rect(&win->buffer, header, style->combo.rounding, style->combo.border, style->combo.border_color);
92 }
93 {
94 /* print currently selected text item */
95 struct nk_rect label;
96 struct nk_rect button;
97 struct nk_rect content;
98
99 enum nk_symbol_type sym;
100 if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER)
101 sym = style->combo.sym_hover;
102 else if (is_clicked)
103 sym = style->combo.sym_active;
104 else sym = style->combo.sym_normal;
105
106 /* calculate button */
107 button.w = header.h - 2 * style->combo.button_padding.y;
108 button.x = (header.x + header.w - header.h) - style->combo.button_padding.x;
109 button.y = header.y + style->combo.button_padding.y;
110 button.h = button.w;
111
112 content.x = button.x + style->combo.button.padding.x;
113 content.y = button.y + style->combo.button.padding.y;
114 content.w = button.w - 2 * style->combo.button.padding.x;
115 content.h = button.h - 2 * style->combo.button.padding.y;
116
117 /* draw selected label */
118 text.padding = nk_vec2(0,0);
119 label.x = header.x + style->combo.content_padding.x;
120 label.y = header.y + style->combo.content_padding.y;
121 label.w = button.x - (style->combo.content_padding.x + style->combo.spacing.x) - label.x;;
122 label.h = header.h - 2 * style->combo.content_padding.y;
123 nk_widget_text(&win->buffer, label, selected, len, &text,
124 NK_TEXT_LEFT, ctx->style.font);
125
126 /* draw open/close button */
127 nk_draw_button_symbol(&win->buffer, &button, &content, ctx->last_widget_state,
128 &ctx->style.combo.button, sym, style->font);
129 }
130 return nk_combo_begin(ctx, win, size, is_clicked, header);
131 }
132 NK_API int
nk_combo_begin_label(struct nk_context * ctx,const char * selected,struct nk_vec2 size)133 nk_combo_begin_label(struct nk_context *ctx, const char *selected, struct nk_vec2 size)
134 {
135 return nk_combo_begin_text(ctx, selected, nk_strlen(selected), size);
136 }
137 NK_API int
nk_combo_begin_color(struct nk_context * ctx,struct nk_color color,struct nk_vec2 size)138 nk_combo_begin_color(struct nk_context *ctx, struct nk_color color, struct nk_vec2 size)
139 {
140 struct nk_window *win;
141 struct nk_style *style;
142 const struct nk_input *in;
143
144 struct nk_rect header;
145 int is_clicked = nk_false;
146 enum nk_widget_layout_states s;
147 const struct nk_style_item *background;
148
149 NK_ASSERT(ctx);
150 NK_ASSERT(ctx->current);
151 NK_ASSERT(ctx->current->layout);
152 if (!ctx || !ctx->current || !ctx->current->layout)
153 return 0;
154
155 win = ctx->current;
156 style = &ctx->style;
157 s = nk_widget(&header, ctx);
158 if (s == NK_WIDGET_INVALID)
159 return 0;
160
161 in = (win->layout->flags & NK_WINDOW_ROM || s == NK_WIDGET_ROM)? 0: &ctx->input;
162 if (nk_button_behavior(&ctx->last_widget_state, header, in, NK_BUTTON_DEFAULT))
163 is_clicked = nk_true;
164
165 /* draw combo box header background and border */
166 if (ctx->last_widget_state & NK_WIDGET_STATE_ACTIVED)
167 background = &style->combo.active;
168 else if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER)
169 background = &style->combo.hover;
170 else background = &style->combo.normal;
171
172 if (background->type == NK_STYLE_ITEM_IMAGE) {
173 nk_draw_image(&win->buffer, header, &background->data.image,nk_white);
174 } else {
175 nk_fill_rect(&win->buffer, header, style->combo.rounding, background->data.color);
176 nk_stroke_rect(&win->buffer, header, style->combo.rounding, style->combo.border, style->combo.border_color);
177 }
178 {
179 struct nk_rect content;
180 struct nk_rect button;
181 struct nk_rect bounds;
182
183 enum nk_symbol_type sym;
184 if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER)
185 sym = style->combo.sym_hover;
186 else if (is_clicked)
187 sym = style->combo.sym_active;
188 else sym = style->combo.sym_normal;
189
190 /* calculate button */
191 button.w = header.h - 2 * style->combo.button_padding.y;
192 button.x = (header.x + header.w - header.h) - style->combo.button_padding.x;
193 button.y = header.y + style->combo.button_padding.y;
194 button.h = button.w;
195
196 content.x = button.x + style->combo.button.padding.x;
197 content.y = button.y + style->combo.button.padding.y;
198 content.w = button.w - 2 * style->combo.button.padding.x;
199 content.h = button.h - 2 * style->combo.button.padding.y;
200
201 /* draw color */
202 bounds.h = header.h - 4 * style->combo.content_padding.y;
203 bounds.y = header.y + 2 * style->combo.content_padding.y;
204 bounds.x = header.x + 2 * style->combo.content_padding.x;
205 bounds.w = (button.x - (style->combo.content_padding.x + style->combo.spacing.x)) - bounds.x;
206 nk_fill_rect(&win->buffer, bounds, 0, color);
207
208 /* draw open/close button */
209 nk_draw_button_symbol(&win->buffer, &button, &content, ctx->last_widget_state,
210 &ctx->style.combo.button, sym, style->font);
211 }
212 return nk_combo_begin(ctx, win, size, is_clicked, header);
213 }
214 NK_API int
nk_combo_begin_symbol(struct nk_context * ctx,enum nk_symbol_type symbol,struct nk_vec2 size)215 nk_combo_begin_symbol(struct nk_context *ctx, enum nk_symbol_type symbol, struct nk_vec2 size)
216 {
217 struct nk_window *win;
218 struct nk_style *style;
219 const struct nk_input *in;
220
221 struct nk_rect header;
222 int is_clicked = nk_false;
223 enum nk_widget_layout_states s;
224 const struct nk_style_item *background;
225 struct nk_color sym_background;
226 struct nk_color symbol_color;
227
228 NK_ASSERT(ctx);
229 NK_ASSERT(ctx->current);
230 NK_ASSERT(ctx->current->layout);
231 if (!ctx || !ctx->current || !ctx->current->layout)
232 return 0;
233
234 win = ctx->current;
235 style = &ctx->style;
236 s = nk_widget(&header, ctx);
237 if (s == NK_WIDGET_INVALID)
238 return 0;
239
240 in = (win->layout->flags & NK_WINDOW_ROM || s == NK_WIDGET_ROM)? 0: &ctx->input;
241 if (nk_button_behavior(&ctx->last_widget_state, header, in, NK_BUTTON_DEFAULT))
242 is_clicked = nk_true;
243
244 /* draw combo box header background and border */
245 if (ctx->last_widget_state & NK_WIDGET_STATE_ACTIVED) {
246 background = &style->combo.active;
247 symbol_color = style->combo.symbol_active;
248 } else if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER) {
249 background = &style->combo.hover;
250 symbol_color = style->combo.symbol_hover;
251 } else {
252 background = &style->combo.normal;
253 symbol_color = style->combo.symbol_hover;
254 }
255
256 if (background->type == NK_STYLE_ITEM_IMAGE) {
257 sym_background = nk_rgba(0,0,0,0);
258 nk_draw_image(&win->buffer, header, &background->data.image, nk_white);
259 } else {
260 sym_background = background->data.color;
261 nk_fill_rect(&win->buffer, header, style->combo.rounding, background->data.color);
262 nk_stroke_rect(&win->buffer, header, style->combo.rounding, style->combo.border, style->combo.border_color);
263 }
264 {
265 struct nk_rect bounds = {0,0,0,0};
266 struct nk_rect content;
267 struct nk_rect button;
268
269 enum nk_symbol_type sym;
270 if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER)
271 sym = style->combo.sym_hover;
272 else if (is_clicked)
273 sym = style->combo.sym_active;
274 else sym = style->combo.sym_normal;
275
276 /* calculate button */
277 button.w = header.h - 2 * style->combo.button_padding.y;
278 button.x = (header.x + header.w - header.h) - style->combo.button_padding.y;
279 button.y = header.y + style->combo.button_padding.y;
280 button.h = button.w;
281
282 content.x = button.x + style->combo.button.padding.x;
283 content.y = button.y + style->combo.button.padding.y;
284 content.w = button.w - 2 * style->combo.button.padding.x;
285 content.h = button.h - 2 * style->combo.button.padding.y;
286
287 /* draw symbol */
288 bounds.h = header.h - 2 * style->combo.content_padding.y;
289 bounds.y = header.y + style->combo.content_padding.y;
290 bounds.x = header.x + style->combo.content_padding.x;
291 bounds.w = (button.x - style->combo.content_padding.y) - bounds.x;
292 nk_draw_symbol(&win->buffer, symbol, bounds, sym_background, symbol_color,
293 1.0f, style->font);
294
295 /* draw open/close button */
296 nk_draw_button_symbol(&win->buffer, &bounds, &content, ctx->last_widget_state,
297 &ctx->style.combo.button, sym, style->font);
298 }
299 return nk_combo_begin(ctx, win, size, is_clicked, header);
300 }
301 NK_API int
nk_combo_begin_symbol_text(struct nk_context * ctx,const char * selected,int len,enum nk_symbol_type symbol,struct nk_vec2 size)302 nk_combo_begin_symbol_text(struct nk_context *ctx, const char *selected, int len,
303 enum nk_symbol_type symbol, struct nk_vec2 size)
304 {
305 struct nk_window *win;
306 struct nk_style *style;
307 struct nk_input *in;
308
309 struct nk_rect header;
310 int is_clicked = nk_false;
311 enum nk_widget_layout_states s;
312 const struct nk_style_item *background;
313 struct nk_color symbol_color;
314 struct nk_text text;
315
316 NK_ASSERT(ctx);
317 NK_ASSERT(ctx->current);
318 NK_ASSERT(ctx->current->layout);
319 if (!ctx || !ctx->current || !ctx->current->layout)
320 return 0;
321
322 win = ctx->current;
323 style = &ctx->style;
324 s = nk_widget(&header, ctx);
325 if (!s) return 0;
326
327 in = (win->layout->flags & NK_WINDOW_ROM || s == NK_WIDGET_ROM)? 0: &ctx->input;
328 if (nk_button_behavior(&ctx->last_widget_state, header, in, NK_BUTTON_DEFAULT))
329 is_clicked = nk_true;
330
331 /* draw combo box header background and border */
332 if (ctx->last_widget_state & NK_WIDGET_STATE_ACTIVED) {
333 background = &style->combo.active;
334 symbol_color = style->combo.symbol_active;
335 text.text = style->combo.label_active;
336 } else if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER) {
337 background = &style->combo.hover;
338 symbol_color = style->combo.symbol_hover;
339 text.text = style->combo.label_hover;
340 } else {
341 background = &style->combo.normal;
342 symbol_color = style->combo.symbol_normal;
343 text.text = style->combo.label_normal;
344 }
345 if (background->type == NK_STYLE_ITEM_IMAGE) {
346 text.background = nk_rgba(0,0,0,0);
347 nk_draw_image(&win->buffer, header, &background->data.image, nk_white);
348 } else {
349 text.background = background->data.color;
350 nk_fill_rect(&win->buffer, header, style->combo.rounding, background->data.color);
351 nk_stroke_rect(&win->buffer, header, style->combo.rounding, style->combo.border, style->combo.border_color);
352 }
353 {
354 struct nk_rect content;
355 struct nk_rect button;
356 struct nk_rect label;
357 struct nk_rect image;
358
359 enum nk_symbol_type sym;
360 if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER)
361 sym = style->combo.sym_hover;
362 else if (is_clicked)
363 sym = style->combo.sym_active;
364 else sym = style->combo.sym_normal;
365
366 /* calculate button */
367 button.w = header.h - 2 * style->combo.button_padding.y;
368 button.x = (header.x + header.w - header.h) - style->combo.button_padding.x;
369 button.y = header.y + style->combo.button_padding.y;
370 button.h = button.w;
371
372 content.x = button.x + style->combo.button.padding.x;
373 content.y = button.y + style->combo.button.padding.y;
374 content.w = button.w - 2 * style->combo.button.padding.x;
375 content.h = button.h - 2 * style->combo.button.padding.y;
376 nk_draw_button_symbol(&win->buffer, &button, &content, ctx->last_widget_state,
377 &ctx->style.combo.button, sym, style->font);
378
379 /* draw symbol */
380 image.x = header.x + style->combo.content_padding.x;
381 image.y = header.y + style->combo.content_padding.y;
382 image.h = header.h - 2 * style->combo.content_padding.y;
383 image.w = image.h;
384 nk_draw_symbol(&win->buffer, symbol, image, text.background, symbol_color,
385 1.0f, style->font);
386
387 /* draw label */
388 text.padding = nk_vec2(0,0);
389 label.x = image.x + image.w + style->combo.spacing.x + style->combo.content_padding.x;
390 label.y = header.y + style->combo.content_padding.y;
391 label.w = (button.x - style->combo.content_padding.x) - label.x;
392 label.h = header.h - 2 * style->combo.content_padding.y;
393 nk_widget_text(&win->buffer, label, selected, len, &text, NK_TEXT_LEFT, style->font);
394 }
395 return nk_combo_begin(ctx, win, size, is_clicked, header);
396 }
397 NK_API int
nk_combo_begin_image(struct nk_context * ctx,struct nk_image img,struct nk_vec2 size)398 nk_combo_begin_image(struct nk_context *ctx, struct nk_image img, struct nk_vec2 size)
399 {
400 struct nk_window *win;
401 struct nk_style *style;
402 const struct nk_input *in;
403
404 struct nk_rect header;
405 int is_clicked = nk_false;
406 enum nk_widget_layout_states s;
407 const struct nk_style_item *background;
408
409 NK_ASSERT(ctx);
410 NK_ASSERT(ctx->current);
411 NK_ASSERT(ctx->current->layout);
412 if (!ctx || !ctx->current || !ctx->current->layout)
413 return 0;
414
415 win = ctx->current;
416 style = &ctx->style;
417 s = nk_widget(&header, ctx);
418 if (s == NK_WIDGET_INVALID)
419 return 0;
420
421 in = (win->layout->flags & NK_WINDOW_ROM || s == NK_WIDGET_ROM)? 0: &ctx->input;
422 if (nk_button_behavior(&ctx->last_widget_state, header, in, NK_BUTTON_DEFAULT))
423 is_clicked = nk_true;
424
425 /* draw combo box header background and border */
426 if (ctx->last_widget_state & NK_WIDGET_STATE_ACTIVED)
427 background = &style->combo.active;
428 else if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER)
429 background = &style->combo.hover;
430 else background = &style->combo.normal;
431
432 if (background->type == NK_STYLE_ITEM_IMAGE) {
433 nk_draw_image(&win->buffer, header, &background->data.image, nk_white);
434 } else {
435 nk_fill_rect(&win->buffer, header, style->combo.rounding, background->data.color);
436 nk_stroke_rect(&win->buffer, header, style->combo.rounding, style->combo.border, style->combo.border_color);
437 }
438 {
439 struct nk_rect bounds = {0,0,0,0};
440 struct nk_rect content;
441 struct nk_rect button;
442
443 enum nk_symbol_type sym;
444 if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER)
445 sym = style->combo.sym_hover;
446 else if (is_clicked)
447 sym = style->combo.sym_active;
448 else sym = style->combo.sym_normal;
449
450 /* calculate button */
451 button.w = header.h - 2 * style->combo.button_padding.y;
452 button.x = (header.x + header.w - header.h) - style->combo.button_padding.y;
453 button.y = header.y + style->combo.button_padding.y;
454 button.h = button.w;
455
456 content.x = button.x + style->combo.button.padding.x;
457 content.y = button.y + style->combo.button.padding.y;
458 content.w = button.w - 2 * style->combo.button.padding.x;
459 content.h = button.h - 2 * style->combo.button.padding.y;
460
461 /* draw image */
462 bounds.h = header.h - 2 * style->combo.content_padding.y;
463 bounds.y = header.y + style->combo.content_padding.y;
464 bounds.x = header.x + style->combo.content_padding.x;
465 bounds.w = (button.x - style->combo.content_padding.y) - bounds.x;
466 nk_draw_image(&win->buffer, bounds, &img, nk_white);
467
468 /* draw open/close button */
469 nk_draw_button_symbol(&win->buffer, &bounds, &content, ctx->last_widget_state,
470 &ctx->style.combo.button, sym, style->font);
471 }
472 return nk_combo_begin(ctx, win, size, is_clicked, header);
473 }
474 NK_API int
nk_combo_begin_image_text(struct nk_context * ctx,const char * selected,int len,struct nk_image img,struct nk_vec2 size)475 nk_combo_begin_image_text(struct nk_context *ctx, const char *selected, int len,
476 struct nk_image img, struct nk_vec2 size)
477 {
478 struct nk_window *win;
479 struct nk_style *style;
480 struct nk_input *in;
481
482 struct nk_rect header;
483 int is_clicked = nk_false;
484 enum nk_widget_layout_states s;
485 const struct nk_style_item *background;
486 struct nk_text text;
487
488 NK_ASSERT(ctx);
489 NK_ASSERT(ctx->current);
490 NK_ASSERT(ctx->current->layout);
491 if (!ctx || !ctx->current || !ctx->current->layout)
492 return 0;
493
494 win = ctx->current;
495 style = &ctx->style;
496 s = nk_widget(&header, ctx);
497 if (!s) return 0;
498
499 in = (win->layout->flags & NK_WINDOW_ROM || s == NK_WIDGET_ROM)? 0: &ctx->input;
500 if (nk_button_behavior(&ctx->last_widget_state, header, in, NK_BUTTON_DEFAULT))
501 is_clicked = nk_true;
502
503 /* draw combo box header background and border */
504 if (ctx->last_widget_state & NK_WIDGET_STATE_ACTIVED) {
505 background = &style->combo.active;
506 text.text = style->combo.label_active;
507 } else if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER) {
508 background = &style->combo.hover;
509 text.text = style->combo.label_hover;
510 } else {
511 background = &style->combo.normal;
512 text.text = style->combo.label_normal;
513 }
514 if (background->type == NK_STYLE_ITEM_IMAGE) {
515 text.background = nk_rgba(0,0,0,0);
516 nk_draw_image(&win->buffer, header, &background->data.image, nk_white);
517 } else {
518 text.background = background->data.color;
519 nk_fill_rect(&win->buffer, header, style->combo.rounding, background->data.color);
520 nk_stroke_rect(&win->buffer, header, style->combo.rounding, style->combo.border, style->combo.border_color);
521 }
522 {
523 struct nk_rect content;
524 struct nk_rect button;
525 struct nk_rect label;
526 struct nk_rect image;
527
528 enum nk_symbol_type sym;
529 if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER)
530 sym = style->combo.sym_hover;
531 else if (is_clicked)
532 sym = style->combo.sym_active;
533 else sym = style->combo.sym_normal;
534
535 /* calculate button */
536 button.w = header.h - 2 * style->combo.button_padding.y;
537 button.x = (header.x + header.w - header.h) - style->combo.button_padding.x;
538 button.y = header.y + style->combo.button_padding.y;
539 button.h = button.w;
540
541 content.x = button.x + style->combo.button.padding.x;
542 content.y = button.y + style->combo.button.padding.y;
543 content.w = button.w - 2 * style->combo.button.padding.x;
544 content.h = button.h - 2 * style->combo.button.padding.y;
545 nk_draw_button_symbol(&win->buffer, &button, &content, ctx->last_widget_state,
546 &ctx->style.combo.button, sym, style->font);
547
548 /* draw image */
549 image.x = header.x + style->combo.content_padding.x;
550 image.y = header.y + style->combo.content_padding.y;
551 image.h = header.h - 2 * style->combo.content_padding.y;
552 image.w = image.h;
553 nk_draw_image(&win->buffer, image, &img, nk_white);
554
555 /* draw label */
556 text.padding = nk_vec2(0,0);
557 label.x = image.x + image.w + style->combo.spacing.x + style->combo.content_padding.x;
558 label.y = header.y + style->combo.content_padding.y;
559 label.w = (button.x - style->combo.content_padding.x) - label.x;
560 label.h = header.h - 2 * style->combo.content_padding.y;
561 nk_widget_text(&win->buffer, label, selected, len, &text, NK_TEXT_LEFT, style->font);
562 }
563 return nk_combo_begin(ctx, win, size, is_clicked, header);
564 }
565 NK_API int
nk_combo_begin_symbol_label(struct nk_context * ctx,const char * selected,enum nk_symbol_type type,struct nk_vec2 size)566 nk_combo_begin_symbol_label(struct nk_context *ctx,
567 const char *selected, enum nk_symbol_type type, struct nk_vec2 size)
568 {
569 return nk_combo_begin_symbol_text(ctx, selected, nk_strlen(selected), type, size);
570 }
571 NK_API int
nk_combo_begin_image_label(struct nk_context * ctx,const char * selected,struct nk_image img,struct nk_vec2 size)572 nk_combo_begin_image_label(struct nk_context *ctx,
573 const char *selected, struct nk_image img, struct nk_vec2 size)
574 {
575 return nk_combo_begin_image_text(ctx, selected, nk_strlen(selected), img, size);
576 }
577 NK_API int
nk_combo_item_text(struct nk_context * ctx,const char * text,int len,nk_flags align)578 nk_combo_item_text(struct nk_context *ctx, const char *text, int len,nk_flags align)
579 {
580 return nk_contextual_item_text(ctx, text, len, align);
581 }
582 NK_API int
nk_combo_item_label(struct nk_context * ctx,const char * label,nk_flags align)583 nk_combo_item_label(struct nk_context *ctx, const char *label, nk_flags align)
584 {
585 return nk_contextual_item_label(ctx, label, align);
586 }
587 NK_API int
nk_combo_item_image_text(struct nk_context * ctx,struct nk_image img,const char * text,int len,nk_flags alignment)588 nk_combo_item_image_text(struct nk_context *ctx, struct nk_image img, const char *text,
589 int len, nk_flags alignment)
590 {
591 return nk_contextual_item_image_text(ctx, img, text, len, alignment);
592 }
593 NK_API int
nk_combo_item_image_label(struct nk_context * ctx,struct nk_image img,const char * text,nk_flags alignment)594 nk_combo_item_image_label(struct nk_context *ctx, struct nk_image img,
595 const char *text, nk_flags alignment)
596 {
597 return nk_contextual_item_image_label(ctx, img, text, alignment);
598 }
599 NK_API int
nk_combo_item_symbol_text(struct nk_context * ctx,enum nk_symbol_type sym,const char * text,int len,nk_flags alignment)600 nk_combo_item_symbol_text(struct nk_context *ctx, enum nk_symbol_type sym,
601 const char *text, int len, nk_flags alignment)
602 {
603 return nk_contextual_item_symbol_text(ctx, sym, text, len, alignment);
604 }
605 NK_API int
nk_combo_item_symbol_label(struct nk_context * ctx,enum nk_symbol_type sym,const char * label,nk_flags alignment)606 nk_combo_item_symbol_label(struct nk_context *ctx, enum nk_symbol_type sym,
607 const char *label, nk_flags alignment)
608 {
609 return nk_contextual_item_symbol_label(ctx, sym, label, alignment);
610 }
nk_combo_end(struct nk_context * ctx)611 NK_API void nk_combo_end(struct nk_context *ctx)
612 {
613 nk_contextual_end(ctx);
614 }
nk_combo_close(struct nk_context * ctx)615 NK_API void nk_combo_close(struct nk_context *ctx)
616 {
617 nk_contextual_close(ctx);
618 }
619 NK_API int
nk_combo(struct nk_context * ctx,const char ** items,int count,int selected,int item_height,struct nk_vec2 size)620 nk_combo(struct nk_context *ctx, const char **items, int count,
621 int selected, int item_height, struct nk_vec2 size)
622 {
623 int i = 0;
624 int max_height;
625 struct nk_vec2 item_spacing;
626 struct nk_vec2 window_padding;
627
628 NK_ASSERT(ctx);
629 NK_ASSERT(items);
630 NK_ASSERT(ctx->current);
631 if (!ctx || !items ||!count)
632 return selected;
633
634 item_spacing = ctx->style.window.spacing;
635 window_padding = nk_panel_get_padding(&ctx->style, ctx->current->layout->type);
636 max_height = count * item_height + count * (int)item_spacing.y;
637 max_height += (int)item_spacing.y * 2 + (int)window_padding.y * 2;
638 size.y = NK_MIN(size.y, (float)max_height);
639 if (nk_combo_begin_label(ctx, items[selected], size)) {
640 nk_layout_row_dynamic(ctx, (float)item_height, 1);
641 for (i = 0; i < count; ++i) {
642 if (nk_combo_item_label(ctx, items[i], NK_TEXT_LEFT))
643 selected = i;
644 }
645 nk_combo_end(ctx);
646 }
647 return selected;
648 }
649 NK_API int
nk_combo_separator(struct nk_context * ctx,const char * items_separated_by_separator,int separator,int selected,int count,int item_height,struct nk_vec2 size)650 nk_combo_separator(struct nk_context *ctx, const char *items_separated_by_separator,
651 int separator, int selected, int count, int item_height, struct nk_vec2 size)
652 {
653 int i;
654 int max_height;
655 struct nk_vec2 item_spacing;
656 struct nk_vec2 window_padding;
657 const char *current_item;
658 const char *iter;
659 int length = 0;
660
661 NK_ASSERT(ctx);
662 NK_ASSERT(items_separated_by_separator);
663 if (!ctx || !items_separated_by_separator)
664 return selected;
665
666 /* calculate popup window */
667 item_spacing = ctx->style.window.spacing;
668 window_padding = nk_panel_get_padding(&ctx->style, ctx->current->layout->type);
669 max_height = count * item_height + count * (int)item_spacing.y;
670 max_height += (int)item_spacing.y * 2 + (int)window_padding.y * 2;
671 size.y = NK_MIN(size.y, (float)max_height);
672
673 /* find selected item */
674 current_item = items_separated_by_separator;
675 for (i = 0; i < count; ++i) {
676 iter = current_item;
677 while (*iter && *iter != separator) iter++;
678 length = (int)(iter - current_item);
679 if (i == selected) break;
680 current_item = iter + 1;
681 }
682
683 if (nk_combo_begin_text(ctx, current_item, length, size)) {
684 current_item = items_separated_by_separator;
685 nk_layout_row_dynamic(ctx, (float)item_height, 1);
686 for (i = 0; i < count; ++i) {
687 iter = current_item;
688 while (*iter && *iter != separator) iter++;
689 length = (int)(iter - current_item);
690 if (nk_combo_item_text(ctx, current_item, length, NK_TEXT_LEFT))
691 selected = i;
692 current_item = current_item + length + 1;
693 }
694 nk_combo_end(ctx);
695 }
696 return selected;
697 }
698 NK_API int
nk_combo_string(struct nk_context * ctx,const char * items_separated_by_zeros,int selected,int count,int item_height,struct nk_vec2 size)699 nk_combo_string(struct nk_context *ctx, const char *items_separated_by_zeros,
700 int selected, int count, int item_height, struct nk_vec2 size)
701 {
702 return nk_combo_separator(ctx, items_separated_by_zeros, '\0', selected, count, item_height, size);
703 }
704 NK_API int
nk_combo_callback(struct nk_context * ctx,void (* item_getter)(void *,int,const char **),void * userdata,int selected,int count,int item_height,struct nk_vec2 size)705 nk_combo_callback(struct nk_context *ctx, void(*item_getter)(void*, int, const char**),
706 void *userdata, int selected, int count, int item_height, struct nk_vec2 size)
707 {
708 int i;
709 int max_height;
710 struct nk_vec2 item_spacing;
711 struct nk_vec2 window_padding;
712 const char *item;
713
714 NK_ASSERT(ctx);
715 NK_ASSERT(item_getter);
716 if (!ctx || !item_getter)
717 return selected;
718
719 /* calculate popup window */
720 item_spacing = ctx->style.window.spacing;
721 window_padding = nk_panel_get_padding(&ctx->style, ctx->current->layout->type);
722 max_height = count * item_height + count * (int)item_spacing.y;
723 max_height += (int)item_spacing.y * 2 + (int)window_padding.y * 2;
724 size.y = NK_MIN(size.y, (float)max_height);
725
726 item_getter(userdata, selected, &item);
727 if (nk_combo_begin_label(ctx, item, size)) {
728 nk_layout_row_dynamic(ctx, (float)item_height, 1);
729 for (i = 0; i < count; ++i) {
730 item_getter(userdata, i, &item);
731 if (nk_combo_item_label(ctx, item, NK_TEXT_LEFT))
732 selected = i;
733 }
734 nk_combo_end(ctx);
735 } return selected;
736 }
737 NK_API void
nk_combobox(struct nk_context * ctx,const char ** items,int count,int * selected,int item_height,struct nk_vec2 size)738 nk_combobox(struct nk_context *ctx, const char **items, int count,
739 int *selected, int item_height, struct nk_vec2 size)
740 {
741 *selected = nk_combo(ctx, items, count, *selected, item_height, size);
742 }
743 NK_API void
nk_combobox_string(struct nk_context * ctx,const char * items_separated_by_zeros,int * selected,int count,int item_height,struct nk_vec2 size)744 nk_combobox_string(struct nk_context *ctx, const char *items_separated_by_zeros,
745 int *selected, int count, int item_height, struct nk_vec2 size)
746 {
747 *selected = nk_combo_string(ctx, items_separated_by_zeros, *selected, count, item_height, size);
748 }
749 NK_API void
nk_combobox_separator(struct nk_context * ctx,const char * items_separated_by_separator,int separator,int * selected,int count,int item_height,struct nk_vec2 size)750 nk_combobox_separator(struct nk_context *ctx, const char *items_separated_by_separator,
751 int separator,int *selected, int count, int item_height, struct nk_vec2 size)
752 {
753 *selected = nk_combo_separator(ctx, items_separated_by_separator, separator,
754 *selected, count, item_height, size);
755 }
756 NK_API void
nk_combobox_callback(struct nk_context * ctx,void (* item_getter)(void * data,int id,const char ** out_text),void * userdata,int * selected,int count,int item_height,struct nk_vec2 size)757 nk_combobox_callback(struct nk_context *ctx,
758 void(*item_getter)(void* data, int id, const char **out_text),
759 void *userdata, int *selected, int count, int item_height, struct nk_vec2 size)
760 {
761 *selected = nk_combo_callback(ctx, item_getter, userdata, *selected, count, item_height, size);
762 }
763
764