2#include "nuklear_internal.h"
15 if (border_width <= 0.0f) {
20 float pad_x = content.w * 0.2f;
21 float pad_y = content.h * 0.2f;
22 float x0 = content.x + pad_x;
23 float y0 = content.y + pad_y;
24 float x1 = content.x + content.w - pad_x;
25 float y1 = content.y + content.h - pad_y;
26 nk_stroke_line(out, x0, y0, x1, y1, border_width, foreground);
27 nk_stroke_line(out, x1, y0, x0, y1, border_width, foreground);
29 case NK_SYMBOL_UNDERSCORE:
31 case NK_SYMBOL_MINUS: {
33 const char *character = (type == NK_SYMBOL_UNDERSCORE) ?
"_":
34 (type == NK_SYMBOL_PLUS) ?
"+":
"-";
37 text.background = background;
38 text.text = foreground;
39 nk_widget_text(out, content, character, 1, &text, NK_TEXT_CENTERED, font);
41 case NK_SYMBOL_CIRCLE_SOLID:
42 case NK_SYMBOL_CIRCLE_OUTLINE:
43 case NK_SYMBOL_RECT_SOLID:
44 case NK_SYMBOL_RECT_OUTLINE: {
46 if (type == NK_SYMBOL_RECT_SOLID || type == NK_SYMBOL_RECT_OUTLINE) {
47 nk_fill_rect(out, content, 0, foreground);
48 if (type == NK_SYMBOL_RECT_OUTLINE)
49 nk_fill_rect(out, nk_shrink_rect(content, border_width), 0, background);
51 nk_fill_circle(out, content, foreground);
52 if (type == NK_SYMBOL_CIRCLE_OUTLINE)
53 nk_fill_circle(out, nk_shrink_rect(content, border_width), background);
56 case NK_SYMBOL_TRIANGLE_UP:
57 case NK_SYMBOL_TRIANGLE_DOWN:
58 case NK_SYMBOL_TRIANGLE_LEFT:
59 case NK_SYMBOL_TRIANGLE_RIGHT: {
60 enum nk_heading heading;
62 heading = (type == NK_SYMBOL_TRIANGLE_RIGHT) ? NK_RIGHT :
63 (type == NK_SYMBOL_TRIANGLE_LEFT) ? NK_LEFT:
64 (type == NK_SYMBOL_TRIANGLE_UP) ? NK_UP: NK_DOWN;
65 nk_triangle_from_direction(points, content, 0, 0, heading);
66 nk_fill_triangle(out, points[0].x, points[0].y, points[1].x, points[1].y,
67 points[2].x, points[2].y, foreground);
69 case NK_SYMBOL_TRIANGLE_UP_OUTLINE:
70 case NK_SYMBOL_TRIANGLE_DOWN_OUTLINE:
71 case NK_SYMBOL_TRIANGLE_LEFT_OUTLINE:
72 case NK_SYMBOL_TRIANGLE_RIGHT_OUTLINE: {
73 enum nk_heading heading;
75 heading = (type == NK_SYMBOL_TRIANGLE_RIGHT_OUTLINE) ? NK_RIGHT :
76 (type == NK_SYMBOL_TRIANGLE_LEFT_OUTLINE) ? NK_LEFT:
77 (type == NK_SYMBOL_TRIANGLE_UP_OUTLINE) ? NK_UP: NK_DOWN;
78 nk_triangle_from_direction(points, content, 0, 0, heading);
79 nk_stroke_triangle(out, points[0].x, points[0].y, points[1].x, points[1].y,
80 points[2].x, points[2].y, border_width, foreground);
82 case NK_SYMBOL_CHEVRON_UP:
83 case NK_SYMBOL_CHEVRON_RIGHT:
84 case NK_SYMBOL_CHEVRON_DOWN:
85 case NK_SYMBOL_CHEVRON_LEFT: {
88 case NK_SYMBOL_CHEVRON_RIGHT:
89 points[0].x = content.x;
90 points[0].y = content.y;
91 points[1].x = content.x + content.w;
92 points[1].y = content.y + content.h * 0.5f;
93 points[2].x = content.x;
94 points[2].y = content.y + content.h;
96 case NK_SYMBOL_CHEVRON_LEFT:
97 points[0].x = content.x + content.w;
98 points[0].y = content.y;
99 points[1].x = content.x;
100 points[1].y = content.y + content.h * 0.5f;
101 points[2].x = content.x + content.w;
102 points[2].y = content.y + content.h;
104 case NK_SYMBOL_CHEVRON_UP:
105 points[0].x = content.x;
106 points[0].y = content.y + content.h;
107 points[1].x = content.x + content.w * 0.5f;
108 points[1].y = content.y;
109 points[2].x = content.x + content.w;
110 points[2].y = content.y + content.h;
112 case NK_SYMBOL_CHEVRON_DOWN:
113 points[0].x = content.x;
114 points[0].y = content.y;
115 points[1].x = content.x + content.w * 0.5f;
116 points[1].y = content.y + content.h;
117 points[2].x = content.x + content.w;
118 points[2].y = content.y;
123 nk_stroke_line(out, points[0].x, points[0].y, points[1].x, points[1].y, border_width, foreground);
124 nk_stroke_line(out, points[1].x, points[1].y, points[2].x, points[2].y, border_width, foreground);
126 case NK_SYMBOL_HAMBURGER: {
127 float y2 = content.y + content.h * 0.5f;
128 float y3 = content.y + content.h - border_width;
129 float x1 = content.x + content.w;
130 nk_stroke_line(out, content.x, content.y, x1, content.y, border_width, foreground);
131 nk_stroke_line(out, content.x, y2, x1, y2, border_width, foreground);
132 nk_stroke_line(out, content.x, y3, x1, y3, border_width, foreground);
136 case NK_SYMBOL_MAX:
break;
140nk_button_behavior(nk_flags *state,
struct nk_rect r,
141 const struct nk_input *i,
enum nk_button_behavior behavior)
144 nk_widget_state_reset(state);
146 if (nk_input_is_mouse_hovering_rect(i, r)) {
147 *state = NK_WIDGET_STATE_HOVERED;
148 if (nk_input_is_mouse_down(i, NK_BUTTON_LEFT))
149 *state = NK_WIDGET_STATE_ACTIVE;
150 if (nk_input_has_mouse_click_in_button_rect(i, NK_BUTTON_LEFT, r)) {
151 ret = (behavior != NK_BUTTON_DEFAULT) ?
152 nk_input_is_mouse_down(i, NK_BUTTON_LEFT):
153#ifdef NK_BUTTON_TRIGGER_ON_RELEASE
154 nk_input_is_mouse_released(i, NK_BUTTON_LEFT);
156 nk_input_is_mouse_pressed(i, NK_BUTTON_LEFT);
160 if (*state & NK_WIDGET_STATE_HOVER && !nk_input_is_mouse_prev_hovering_rect(i, r))
161 *state |= NK_WIDGET_STATE_ENTERED;
162 else if (nk_input_is_mouse_prev_hovering_rect(i, r))
163 *state |= NK_WIDGET_STATE_LEFT;
168 const struct nk_rect *bounds, nk_flags state,
172 if (state & NK_WIDGET_STATE_HOVER)
173 background = &style->hover;
174 else if (state & NK_WIDGET_STATE_ACTIVED)
175 background = &style->active;
176 else background = &style->normal;
178 switch (background->type) {
179 case NK_STYLE_ITEM_IMAGE:
180 nk_draw_image(out, *bounds, &background->data.image, nk_rgb_factor(nk_white, style->color_factor_background));
182 case NK_STYLE_ITEM_NINE_SLICE:
183 nk_draw_nine_slice(out, *bounds, &background->data.slice, nk_rgb_factor(nk_white, style->color_factor_background));
185 case NK_STYLE_ITEM_COLOR:
186 nk_fill_rect(out, *bounds, style->rounding, nk_rgb_factor(background->data.color, style->color_factor_background));
187 nk_stroke_rect(out, *bounds, style->rounding, style->border, nk_rgb_factor(style->border_color, style->color_factor_background));
195 enum nk_button_behavior behavior,
struct nk_rect *content)
205 content->x = r.x + style->padding.x + style->border + style->rounding;
206 content->y = r.y + style->padding.y + style->border + style->rounding;
207 content->w = r.w - (2 * (style->padding.x + style->border + style->rounding));
208 content->h = r.h - (2 * (style->padding.y + style->border + style->rounding));
211 bounds.x = r.x - style->touch_padding.x;
212 bounds.y = r.y - style->touch_padding.y;
213 bounds.w = r.w + 2 * style->touch_padding.x;
214 bounds.h = r.h + 2 * style->touch_padding.y;
215 return nk_button_behavior(state, bounds, in, behavior);
219 const struct nk_rect *bounds,
const struct nk_rect *content, nk_flags state,
221 nk_flags text_alignment,
const struct nk_user_font *font)
225 background = nk_draw_button(out, bounds, state, style);
228 if (background->type == NK_STYLE_ITEM_COLOR)
229 text.background = background->data.color;
230 else text.background = style->text_background;
231 if (state & NK_WIDGET_STATE_HOVER)
232 text.text = style->text_hover;
233 else if (state & NK_WIDGET_STATE_ACTIVED)
234 text.text = style->text_active;
235 else text.text = style->text_normal;
237 text.text = nk_rgb_factor(text.text, style->color_factor_text);
240 nk_widget_text(out, *content, txt, len, &text, text_alignment, font);
243nk_do_button_text(nk_flags *state,
245 const char *
string,
int len, nk_flags align,
enum nk_button_behavior behavior,
257 if (!out || !style || !font || !
string)
260 ret = nk_do_button(state, out, bounds, style, in, behavior, &content);
261 if (style->draw_begin) style->draw_begin(out, style->userdata);
262 nk_draw_button_text(out, &bounds, &content, *state, style,
string, len, align, font);
263 if (style->draw_end) style->draw_end(out, style->userdata);
270 enum nk_symbol_type type,
const struct nk_user_font *font)
276 background = nk_draw_button(out, bounds, state, style);
277 if (background->type == NK_STYLE_ITEM_COLOR)
278 bg = background->data.color;
279 else bg = style->text_background;
281 if (state & NK_WIDGET_STATE_HOVER)
282 sym = style->text_hover;
283 else if (state & NK_WIDGET_STATE_ACTIVED)
284 sym = style->text_active;
285 else sym = style->text_normal;
287 sym = nk_rgb_factor(sym, style->color_factor_text);
288 nk_draw_symbol(out, type, *content, bg, sym, style->border, font);
291nk_do_button_symbol(nk_flags *state,
293 enum nk_symbol_type symbol,
enum nk_button_behavior behavior,
304 if (!out || !style || !font || !state)
307 ret = nk_do_button(state, out, bounds, style, in, behavior, &content);
308 if (style->draw_begin) style->draw_begin(out, style->userdata);
309 nk_draw_button_symbol(out, &bounds, &content, *state, style, symbol, font);
310 if (style->draw_end) style->draw_end(out, style->userdata);
318 nk_draw_button(out, bounds, state, style);
319 nk_draw_image(out, *content, img, nk_rgb_factor(nk_white, style->color_factor_background));
322nk_do_button_image(nk_flags *state,
324 struct nk_image img,
enum nk_button_behavior b,
333 if (!out || !style || !state)
336 ret = nk_do_button(state, out, bounds, style, in, b, &content);
337 content.x += style->image_padding.x;
338 content.y += style->image_padding.y;
339 content.w -= 2 * style->image_padding.x;
340 content.h -= 2 * style->image_padding.y;
342 if (style->draw_begin) style->draw_begin(out, style->userdata);
343 nk_draw_button_image(out, &bounds, &content, *state, style, &img);
344 if (style->draw_end) style->draw_end(out, style->userdata);
351 const char *str,
int len,
enum nk_symbol_type type,
359 background = nk_draw_button(out, bounds, state, style);
360 if (background->type == NK_STYLE_ITEM_COLOR)
361 text.background = background->data.color;
362 else text.background = style->text_background;
365 if (state & NK_WIDGET_STATE_HOVER) {
366 sym = style->text_hover;
367 text.text = style->text_hover;
368 }
else if (state & NK_WIDGET_STATE_ACTIVED) {
369 sym = style->text_active;
370 text.text = style->text_active;
372 sym = style->text_normal;
373 text.text = style->text_normal;
376 sym = nk_rgb_factor(sym, style->color_factor_text);
377 text.text = nk_rgb_factor(text.text, style->color_factor_text);
379 nk_draw_symbol(out, type, *symbol, style->text_background, sym, style->border, font);
380 nk_widget_text(out, *label, str, len, &text, NK_TEXT_CENTERED, font);
383nk_do_button_text_symbol(nk_flags *state,
385 enum nk_symbol_type symbol,
const char *str,
int len, nk_flags align,
390 struct nk_rect tri = {0,0,0,0};
396 if (!out || !style || !font)
399 ret = nk_do_button(state, out, bounds, style, in, behavior, &content);
400 tri.y = content.y + (content.h/2) - font->
height/2;
402 if (align & NK_TEXT_ALIGN_LEFT) {
403 tri.x = (content.x + content.w) - (2 * style->padding.x + tri.w);
404 tri.x = NK_MAX(tri.x, 0);
405 }
else tri.x = content.x + 2 * style->padding.x;
408 if (style->draw_begin) style->draw_begin(out, style->userdata);
409 nk_draw_button_text_symbol(out, &bounds, &content, &tri,
410 *state, style, str, len, symbol, font);
411 if (style->draw_end) style->draw_end(out, style->userdata);
418 const char *str,
int len,
const struct nk_user_font *font,
423 background = nk_draw_button(out, bounds, state, style);
426 if (background->type == NK_STYLE_ITEM_COLOR)
427 text.background = background->data.color;
428 else text.background = style->text_background;
429 if (state & NK_WIDGET_STATE_HOVER)
430 text.text = style->text_hover;
431 else if (state & NK_WIDGET_STATE_ACTIVED)
432 text.text = style->text_active;
433 else text.text = style->text_normal;
435 text.text = nk_rgb_factor(text.text, style->color_factor_text);
437 nk_widget_text(out, *label, str, len, &text, NK_TEXT_CENTERED, font);
438 nk_draw_image(out, *image, img, nk_rgb_factor(nk_white, style->color_factor_background));
441nk_do_button_text_image(nk_flags *state,
443 struct nk_image img,
const char* str,
int len, nk_flags align,
455 if (!out || !font || !style || !str)
458 ret = nk_do_button(state, out, bounds, style, in, behavior, &content);
459 icon.y = bounds.y + style->padding.y;
460 icon.w = icon.h = bounds.h - 2 * style->padding.y;
461 if (align & NK_TEXT_ALIGN_LEFT) {
462 icon.x = (bounds.x + bounds.w) - (2 * style->padding.x + icon.w);
463 icon.x = NK_MAX(icon.x, 0);
464 }
else icon.x = bounds.x + 2 * style->padding.x;
466 icon.x += style->image_padding.x;
467 icon.y += style->image_padding.y;
468 icon.w -= 2 * style->image_padding.x;
469 icon.h -= 2 * style->image_padding.y;
471 if (style->draw_begin) style->draw_begin(out, style->userdata);
472 nk_draw_button_text_image(out, &bounds, &content, &icon, *state, style, str, len, font, &img);
473 if (style->draw_end) style->draw_end(out, style->userdata);
477nk_button_set_behavior(
struct nk_context *ctx,
enum nk_button_behavior behavior)
481 ctx->button_behavior = behavior;
484nk_button_push_behavior(
struct nk_context *ctx,
enum nk_button_behavior behavior)
486 struct nk_config_stack_button_behavior *button_stack;
487 struct nk_config_stack_button_behavior_element *element;
492 button_stack = &ctx->stacks.button_behaviors;
493 NK_ASSERT(button_stack->head < (
int)NK_LEN(button_stack->elements));
494 if (button_stack->head >= (
int)NK_LEN(button_stack->elements))
497 element = &button_stack->elements[button_stack->head++];
498 element->address = &ctx->button_behavior;
499 element->old_value = ctx->button_behavior;
500 ctx->button_behavior = behavior;
506 struct nk_config_stack_button_behavior *button_stack;
507 struct nk_config_stack_button_behavior_element *element;
512 button_stack = &ctx->stacks.button_behaviors;
513 NK_ASSERT(button_stack->head > 0);
514 if (button_stack->head < 1)
517 element = &button_stack->elements[--button_stack->head];
518 *element->address = element->old_value;
530 enum nk_widget_layout_states state;
534 NK_ASSERT(ctx->current);
535 NK_ASSERT(ctx->current->layout);
536 if (!style || !ctx || !ctx->current || !ctx->current->layout)
return 0;
539 layout = win->layout;
540 state = nk_widget(&bounds, ctx);
542 if (!state)
return 0;
543 in = (state == NK_WIDGET_ROM || state == NK_WIDGET_DISABLED || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
544 return nk_do_button_text(&ctx->last_widget_state, &win->buffer, bounds,
545 title, len, style->text_alignment, ctx->button_behavior,
546 style, in, ctx->style.font);
549nk_button_text(
struct nk_context *ctx,
const char *title,
int len)
553 return nk_button_text_styled(ctx, &ctx->style.button, title, len);
555NK_API nk_bool nk_button_label_styled(
struct nk_context *ctx,
558 return nk_button_text_styled(ctx, style, title, nk_strlen(title));
560NK_API nk_bool nk_button_label(
struct nk_context *ctx,
const char *title)
562 return nk_button_text(ctx, title, nk_strlen(title));
575 enum nk_widget_layout_states state;
578 NK_ASSERT(ctx->current);
579 NK_ASSERT(ctx->current->layout);
580 if (!ctx || !ctx->current || !ctx->current->layout)
584 layout = win->layout;
586 state = nk_widget(&bounds, ctx);
587 if (!state)
return 0;
588 in = (state == NK_WIDGET_ROM || state == NK_WIDGET_DISABLED || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
590 button = ctx->style.button;
591 button.normal = nk_style_item_color(color);
592 button.hover = nk_style_item_color(color);
593 button.active = nk_style_item_color(color);
594 ret = nk_do_button(&ctx->last_widget_state, &win->buffer, bounds,
595 &button, in, ctx->button_behavior, &content);
596 nk_draw_button(&win->buffer, &bounds, ctx->last_widget_state, &button);
600nk_button_symbol_styled(
struct nk_context *ctx,
608 enum nk_widget_layout_states state;
611 NK_ASSERT(ctx->current);
612 NK_ASSERT(ctx->current->layout);
613 if (!ctx || !ctx->current || !ctx->current->layout)
617 layout = win->layout;
618 state = nk_widget(&bounds, ctx);
619 if (!state)
return 0;
620 in = (state == NK_WIDGET_ROM || state == NK_WIDGET_DISABLED || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
621 return nk_do_button_symbol(&ctx->last_widget_state, &win->buffer, bounds,
622 symbol, ctx->button_behavior, style, in, ctx->style.font);
625nk_button_symbol(
struct nk_context *ctx,
enum nk_symbol_type symbol)
629 return nk_button_symbol_styled(ctx, &ctx->style.button, symbol);
640 enum nk_widget_layout_states state;
643 NK_ASSERT(ctx->current);
644 NK_ASSERT(ctx->current->layout);
645 if (!ctx || !ctx->current || !ctx->current->layout)
649 layout = win->layout;
651 state = nk_widget(&bounds, ctx);
652 if (!state)
return 0;
653 in = (state == NK_WIDGET_ROM || state == NK_WIDGET_DISABLED || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
654 return nk_do_button_image(&ctx->last_widget_state, &win->buffer, bounds,
655 img, ctx->button_behavior, style, in);
662 return nk_button_image_styled(ctx, &ctx->style.button, img);
665nk_button_symbol_text_styled(
struct nk_context *ctx,
667 const char *text,
int len, nk_flags align)
674 enum nk_widget_layout_states state;
677 NK_ASSERT(ctx->current);
678 NK_ASSERT(ctx->current->layout);
679 if (!ctx || !ctx->current || !ctx->current->layout)
683 layout = win->layout;
685 state = nk_widget(&bounds, ctx);
686 if (!state)
return 0;
687 in = (state == NK_WIDGET_ROM || state == NK_WIDGET_DISABLED || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
688 return nk_do_button_text_symbol(&ctx->last_widget_state, &win->buffer, bounds,
689 symbol, text, len, align, ctx->button_behavior,
690 style, ctx->style.font, in);
693nk_button_symbol_text(
struct nk_context *ctx,
enum nk_symbol_type symbol,
694 const char* text,
int len, nk_flags align)
698 return nk_button_symbol_text_styled(ctx, &ctx->style.button, symbol, text, len, align);
700NK_API nk_bool nk_button_symbol_label(
struct nk_context *ctx,
enum nk_symbol_type symbol,
701 const char *label, nk_flags align)
703 return nk_button_symbol_text(ctx, symbol, label, nk_strlen(label), align);
705NK_API nk_bool nk_button_symbol_label_styled(
struct nk_context *ctx,
707 const char *title, nk_flags align)
709 return nk_button_symbol_text_styled(ctx, style, symbol, title, nk_strlen(title), align);
712nk_button_image_text_styled(
struct nk_context *ctx,
714 int len, nk_flags align)
721 enum nk_widget_layout_states state;
724 NK_ASSERT(ctx->current);
725 NK_ASSERT(ctx->current->layout);
726 if (!ctx || !ctx->current || !ctx->current->layout)
730 layout = win->layout;
732 state = nk_widget(&bounds, ctx);
733 if (!state)
return 0;
734 in = (state == NK_WIDGET_ROM || state == NK_WIDGET_DISABLED || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
735 return nk_do_button_text_image(&ctx->last_widget_state, &win->buffer,
736 bounds, img, text, len, align, ctx->button_behavior,
737 style, ctx->style.font, in);
741 const char *text,
int len, nk_flags align)
743 return nk_button_image_text_styled(ctx, &ctx->style.button,img, text, len, align);
746 const char *label, nk_flags align)
748 return nk_button_image_text(ctx, img, label, nk_strlen(label), align);
750NK_API nk_bool nk_button_image_label_styled(
struct nk_context *ctx,
752 const char *label, nk_flags text_alignment)
754 return nk_button_image_text_styled(ctx, style, img, label, nk_strlen(label), text_alignment);
float height
!< user provided font handle