comparison nuklear_ui/nuklear.h @ 1841:5d10b8494b02

WIP keyboard nav for Nuklear menus
author Michael Pavone <pavone@retrodev.com>
date Fri, 19 Apr 2019 21:09:46 -0700
parents c5c022c7aa54
children 7a9e6fd94d61
comparison
equal deleted inserted replaced
1840:3d0b20e9a187 1841:5d10b8494b02
1843 NK_WIDGET_STATE_ACTIVED = NK_FLAG(5),/* widget is currently activated */ 1843 NK_WIDGET_STATE_ACTIVED = NK_FLAG(5),/* widget is currently activated */
1844 NK_WIDGET_STATE_LEFT = NK_FLAG(6), /* widget is from this frame on not hovered anymore */ 1844 NK_WIDGET_STATE_LEFT = NK_FLAG(6), /* widget is from this frame on not hovered anymore */
1845 NK_WIDGET_STATE_HOVERED = NK_WIDGET_STATE_HOVER|NK_WIDGET_STATE_MODIFIED, /* widget is being hovered */ 1845 NK_WIDGET_STATE_HOVERED = NK_WIDGET_STATE_HOVER|NK_WIDGET_STATE_MODIFIED, /* widget is being hovered */
1846 NK_WIDGET_STATE_ACTIVE = NK_WIDGET_STATE_ACTIVED|NK_WIDGET_STATE_MODIFIED /* widget is currently activated */ 1846 NK_WIDGET_STATE_ACTIVE = NK_WIDGET_STATE_ACTIVED|NK_WIDGET_STATE_MODIFIED /* widget is currently activated */
1847 }; 1847 };
1848 NK_API enum nk_widget_layout_states nk_widget(struct nk_rect*, const struct nk_context*); 1848 NK_API enum nk_widget_layout_states nk_widget(struct nk_rect*, struct nk_context*);
1849 NK_API enum nk_widget_layout_states nk_keynav_widget(struct nk_rect *, struct nk_context *);
1849 NK_API enum nk_widget_layout_states nk_widget_fitting(struct nk_rect*, struct nk_context*, struct nk_vec2); 1850 NK_API enum nk_widget_layout_states nk_widget_fitting(struct nk_rect*, struct nk_context*, struct nk_vec2);
1850 NK_API struct nk_rect nk_widget_bounds(struct nk_context*); 1851 NK_API struct nk_rect nk_widget_bounds(struct nk_context*);
1851 NK_API struct nk_vec2 nk_widget_position(struct nk_context*); 1852 NK_API struct nk_vec2 nk_widget_position(struct nk_context*);
1852 NK_API struct nk_vec2 nk_widget_size(struct nk_context*); 1853 NK_API struct nk_vec2 nk_widget_size(struct nk_context*);
1853 NK_API float nk_widget_width(struct nk_context*); 1854 NK_API float nk_widget_width(struct nk_context*);
3190 }; 3191 };
3191 3192
3192 struct nk_input { 3193 struct nk_input {
3193 struct nk_keyboard keyboard; 3194 struct nk_keyboard keyboard;
3194 struct nk_mouse mouse; 3195 struct nk_mouse mouse;
3196 int widget_counter;
3197 int selected_widget;
3195 }; 3198 };
3196 3199
3197 NK_API int nk_input_has_mouse_click(const struct nk_input*, enum nk_buttons); 3200 NK_API int nk_input_has_mouse_click(const struct nk_input*, enum nk_buttons);
3198 NK_API int nk_input_has_mouse_click_in_rect(const struct nk_input*, enum nk_buttons, struct nk_rect); 3201 NK_API int nk_input_has_mouse_click_in_rect(const struct nk_input*, enum nk_buttons, struct nk_rect);
3199 NK_API int nk_input_has_mouse_click_down_in_rect(const struct nk_input*, enum nk_buttons, struct nk_rect, int down); 3202 NK_API int nk_input_has_mouse_click_down_in_rect(const struct nk_input*, enum nk_buttons, struct nk_rect, int down);
12554 in->mouse.prev.y = in->mouse.pos.y; 12557 in->mouse.prev.y = in->mouse.pos.y;
12555 in->mouse.delta.x = 0; 12558 in->mouse.delta.x = 0;
12556 in->mouse.delta.y = 0; 12559 in->mouse.delta.y = 0;
12557 for (i = 0; i < NK_KEY_MAX; i++) 12560 for (i = 0; i < NK_KEY_MAX; i++)
12558 in->keyboard.keys[i].clicked = 0; 12561 in->keyboard.keys[i].clicked = 0;
12562 in->widget_counter = -1;
12559 } 12563 }
12560 12564
12561 NK_API void 12565 NK_API void
12562 nk_input_end(struct nk_context *ctx) 12566 nk_input_end(struct nk_context *ctx)
12563 { 12567 {
12678 struct nk_rect b) 12682 struct nk_rect b)
12679 { 12683 {
12680 const struct nk_mouse_button *btn; 12684 const struct nk_mouse_button *btn;
12681 if (!i) return nk_false; 12685 if (!i) return nk_false;
12682 btn = &i->mouse.buttons[id]; 12686 btn = &i->mouse.buttons[id];
12683 if (!NK_INBOX(btn->clicked_pos.x,btn->clicked_pos.y,b.x,b.y,b.w,b.h)) 12687 if (NK_INBOX(btn->clicked_pos.x,btn->clicked_pos.y,b.x,b.y,b.w,b.h))
12684 return nk_false; 12688 return nk_true;
12685 return nk_true; 12689 if (i->selected_widget == i->widget_counter && i->keyboard.keys[NK_KEY_ENTER].clicked)
12690 return nk_true;
12691 return nk_false;
12686 } 12692 }
12687 12693
12688 NK_API int 12694 NK_API int
12689 nk_input_has_mouse_click_down_in_rect(const struct nk_input *i, enum nk_buttons id, 12695 nk_input_has_mouse_click_down_in_rect(const struct nk_input *i, enum nk_buttons id,
12690 struct nk_rect b, int down) 12696 struct nk_rect b, int down)
12728 12734
12729 NK_API int 12735 NK_API int
12730 nk_input_is_mouse_hovering_rect(const struct nk_input *i, struct nk_rect rect) 12736 nk_input_is_mouse_hovering_rect(const struct nk_input *i, struct nk_rect rect)
12731 { 12737 {
12732 if (!i) return nk_false; 12738 if (!i) return nk_false;
12733 return NK_INBOX(i->mouse.pos.x, i->mouse.pos.y, rect.x, rect.y, rect.w, rect.h); 12739 return i->selected_widget == i->widget_counter || NK_INBOX(i->mouse.pos.x, i->mouse.pos.y, rect.x, rect.y, rect.w, rect.h);
12734 } 12740 }
12735 12741
12736 NK_API int 12742 NK_API int
12737 nk_input_is_mouse_prev_hovering_rect(const struct nk_input *i, struct nk_rect rect) 12743 nk_input_is_mouse_prev_hovering_rect(const struct nk_input *i, struct nk_rect rect)
12738 { 12744 {
12750 12756
12751 NK_API int 12757 NK_API int
12752 nk_input_is_mouse_down(const struct nk_input *i, enum nk_buttons id) 12758 nk_input_is_mouse_down(const struct nk_input *i, enum nk_buttons id)
12753 { 12759 {
12754 if (!i) return nk_false; 12760 if (!i) return nk_false;
12755 return i->mouse.buttons[id].down; 12761 return i->mouse.buttons[id].down || (
12762 id == NK_BUTTON_LEFT && i->widget_counter == i->selected_widget && i->keyboard.keys[NK_KEY_ENTER].down
12763 );
12756 } 12764 }
12757 12765
12758 NK_API int 12766 NK_API int
12759 nk_input_is_mouse_pressed(const struct nk_input *i, enum nk_buttons id) 12767 nk_input_is_mouse_pressed(const struct nk_input *i, enum nk_buttons id)
12760 { 12768 {
12761 const struct nk_mouse_button *b; 12769 const struct nk_mouse_button *b;
12762 if (!i) return nk_false; 12770 if (!i) return nk_false;
12763 b = &i->mouse.buttons[id]; 12771 b = &i->mouse.buttons[id];
12764 if (b->down && b->clicked) 12772 if (b->down && b->clicked)
12765 return nk_true; 12773 return nk_true;
12774 if (
12775 id == NK_BUTTON_LEFT && i->widget_counter == i->selected_widget
12776 && i->keyboard.keys[NK_KEY_ENTER].down && i->keyboard.keys[NK_KEY_ENTER].clicked
12777 )
12778 return nk_true;
12766 return nk_false; 12779 return nk_false;
12767 } 12780 }
12768 12781
12769 NK_API int 12782 NK_API int
12770 nk_input_is_mouse_released(const struct nk_input *i, enum nk_buttons id) 12783 nk_input_is_mouse_released(const struct nk_input *i, enum nk_buttons id)
12771 { 12784 {
12772 if (!i) return nk_false; 12785 if (!i) return nk_false;
12773 return (!i->mouse.buttons[id].down && i->mouse.buttons[id].clicked); 12786 if (!i->mouse.buttons[id].down && i->mouse.buttons[id].clicked)
12787 return nk_true;
12788 if (
12789 id == NK_BUTTON_LEFT && i->widget_counter == i->selected_widget
12790 && !i->keyboard.keys[NK_KEY_ENTER].down && i->keyboard.keys[NK_KEY_ENTER].clicked
12791 )
12792 return nk_true;
12793 return nk_false;
12774 } 12794 }
12775 12795
12776 NK_API int 12796 NK_API int
12777 nk_input_is_key_pressed(const struct nk_input *i, enum nk_keys key) 12797 nk_input_is_key_pressed(const struct nk_input *i, enum nk_keys key)
12778 { 12798 {
14622 touch.h = bounds.h + style->touch_padding.y * 2; 14642 touch.h = bounds.h + style->touch_padding.y * 2;
14623 14643
14624 /* update button */ 14644 /* update button */
14625 if (nk_button_behavior(state, touch, in, NK_BUTTON_DEFAULT)) 14645 if (nk_button_behavior(state, touch, in, NK_BUTTON_DEFAULT))
14626 *value = !(*value); 14646 *value = !(*value);
14647
14648 if (!old_value && !(*value) && in && in->selected_widget == in->widget_counter) {
14649 *value = 1;
14650 }
14627 14651
14628 /* draw selectable */ 14652 /* draw selectable */
14629 if (style->draw_begin) style->draw_begin(out, style->userdata); 14653 if (style->draw_begin) style->draw_begin(out, style->userdata);
14630 nk_draw_selectable(out, *state, style, *value, &bounds, 0,0, str, len, align, font); 14654 nk_draw_selectable(out, *state, style, *value, &bounds, 0,0, str, len, align, font);
14631 if (style->draw_end) style->draw_end(out, style->userdata); 14655 if (style->draw_end) style->draw_end(out, style->userdata);
17245 ctx->seq = 1; 17269 ctx->seq = 1;
17246 if (font) ctx->style.font = font; 17270 if (font) ctx->style.font = font;
17247 #ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT 17271 #ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT
17248 nk_draw_list_init(&ctx->draw_list); 17272 nk_draw_list_init(&ctx->draw_list);
17249 #endif 17273 #endif
17274 ctx->input.widget_counter = -1;
17250 } 17275 }
17251 17276
17252 #ifdef NK_INCLUDE_DEFAULT_ALLOCATOR 17277 #ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
17253 NK_API int 17278 NK_API int
17254 nk_init_default(struct nk_context *ctx, const struct nk_user_font *font) 17279 nk_init_default(struct nk_context *ctx, const struct nk_user_font *font)
20224 return 0; 20249 return 0;
20225 return nk_input_has_mouse_click_down_in_rect(&ctx->input, btn, bounds, down); 20250 return nk_input_has_mouse_click_down_in_rect(&ctx->input, btn, bounds, down);
20226 } 20251 }
20227 20252
20228 NK_API enum nk_widget_layout_states 20253 NK_API enum nk_widget_layout_states
20229 nk_widget(struct nk_rect *bounds, const struct nk_context *ctx) 20254 nk_widget_gen(struct nk_rect *bounds, struct nk_context *ctx, nk_byte is_keynav)
20230 { 20255 {
20231 struct nk_rect c, v; 20256 struct nk_rect c, v;
20232 struct nk_window *win; 20257 struct nk_window *win;
20233 struct nk_panel *layout; 20258 struct nk_panel *layout;
20234 const struct nk_input *in; 20259 const struct nk_input *in;
20263 20288
20264 c.x = (float)((int)c.x); 20289 c.x = (float)((int)c.x);
20265 c.y = (float)((int)c.y); 20290 c.y = (float)((int)c.y);
20266 c.w = (float)((int)c.w); 20291 c.w = (float)((int)c.w);
20267 c.h = (float)((int)c.h); 20292 c.h = (float)((int)c.h);
20293 if (is_keynav) {
20294 ctx->input.widget_counter++;
20295 if (ctx->input.selected_widget == ctx->input.widget_counter) {
20296 if (ctx->input.keyboard.keys[NK_KEY_UP].clicked && ctx->input.keyboard.keys[NK_KEY_UP].down && ctx->input.selected_widget) {
20297 ctx->input.selected_widget--;
20298 ctx->input.keyboard.keys[NK_KEY_UP].clicked = 0;
20299 } else if (ctx->input.keyboard.keys[NK_KEY_DOWN].clicked && ctx->input.keyboard.keys[NK_KEY_DOWN].down) {
20300 ctx->input.keyboard.keys[NK_KEY_DOWN].clicked = 0;
20301 ctx->input.selected_widget++;
20302 }
20303 }
20304 }
20268 20305
20269 nk_unify(&v, &c, bounds->x, bounds->y, bounds->x + bounds->w, bounds->y + bounds->h); 20306 nk_unify(&v, &c, bounds->x, bounds->y, bounds->x + bounds->w, bounds->y + bounds->h);
20270 if (!NK_INTERSECT(c.x, c.y, c.w, c.h, bounds->x, bounds->y, bounds->w, bounds->h)) 20307 if (!NK_INTERSECT(c.x, c.y, c.w, c.h, bounds->x, bounds->y, bounds->w, bounds->h))
20271 return NK_WIDGET_INVALID; 20308 return NK_WIDGET_INVALID;
20272 if (!NK_INBOX(in->mouse.pos.x, in->mouse.pos.y, v.x, v.y, v.w, v.h)) 20309 if ((is_keynav && ctx->input.selected_widget == ctx->input.widget_counter ) || NK_INBOX(in->mouse.pos.x, in->mouse.pos.y, v.x, v.y, v.w, v.h))
20273 return NK_WIDGET_ROM; 20310 return NK_WIDGET_VALID;
20274 return NK_WIDGET_VALID; 20311 return NK_WIDGET_ROM;
20312 }
20313
20314 NK_API enum nk_widget_layout_states
20315 nk_widget(struct nk_rect *bounds, struct nk_context *ctx)
20316 {
20317 return nk_widget_gen(bounds, ctx, 0);
20318 }
20319
20320 NK_API enum nk_widget_layout_states
20321 nk_keynav_widget(struct nk_rect *bounds, struct nk_context *ctx)
20322 {
20323 return nk_widget_gen(bounds, ctx, 1);
20275 } 20324 }
20276 20325
20277 NK_API enum nk_widget_layout_states 20326 NK_API enum nk_widget_layout_states
20278 nk_widget_fitting(struct nk_rect *bounds, struct nk_context *ctx, 20327 nk_widget_fitting(struct nk_rect *bounds, struct nk_context *ctx,
20279 struct nk_vec2 item_padding) 20328 struct nk_vec2 item_padding)
20613 NK_ASSERT(ctx->current->layout); 20662 NK_ASSERT(ctx->current->layout);
20614 if (!style || !ctx || !ctx->current || !ctx->current->layout) return 0; 20663 if (!style || !ctx || !ctx->current || !ctx->current->layout) return 0;
20615 20664
20616 win = ctx->current; 20665 win = ctx->current;
20617 layout = win->layout; 20666 layout = win->layout;
20618 state = nk_widget(&bounds, ctx); 20667 state = nk_keynav_widget(&bounds, ctx);
20619 20668
20620 if (!state) return 0; 20669 if (!state) return 0;
20621 in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input; 20670 in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
20622 return nk_do_button_text(&ctx->last_widget_state, &win->buffer, bounds, 20671 return nk_do_button_text(&ctx->last_widget_state, &win->buffer, bounds,
20623 title, len, style->text_alignment, ctx->button_behavior, 20672 title, len, style->text_alignment, ctx->button_behavior,
20659 return 0; 20708 return 0;
20660 20709
20661 win = ctx->current; 20710 win = ctx->current;
20662 layout = win->layout; 20711 layout = win->layout;
20663 20712
20664 state = nk_widget(&bounds, ctx); 20713 state = nk_keynav_widget(&bounds, ctx);
20665 if (!state) return 0; 20714 if (!state) return 0;
20666 in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input; 20715 in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
20667 20716
20668 button = ctx->style.button; 20717 button = ctx->style.button;
20669 button.normal = nk_style_item_color(color); 20718 button.normal = nk_style_item_color(color);
20692 if (!ctx || !ctx->current || !ctx->current->layout) 20741 if (!ctx || !ctx->current || !ctx->current->layout)
20693 return 0; 20742 return 0;
20694 20743
20695 win = ctx->current; 20744 win = ctx->current;
20696 layout = win->layout; 20745 layout = win->layout;
20697 state = nk_widget(&bounds, ctx); 20746 state = nk_keynav_widget(&bounds, ctx);
20698 if (!state) return 0; 20747 if (!state) return 0;
20699 in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input; 20748 in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
20700 return nk_do_button_symbol(&ctx->last_widget_state, &win->buffer, bounds, 20749 return nk_do_button_symbol(&ctx->last_widget_state, &win->buffer, bounds,
20701 symbol, ctx->button_behavior, style, in, ctx->style.font); 20750 symbol, ctx->button_behavior, style, in, ctx->style.font);
20702 } 20751 }
20727 return 0; 20776 return 0;
20728 20777
20729 win = ctx->current; 20778 win = ctx->current;
20730 layout = win->layout; 20779 layout = win->layout;
20731 20780
20732 state = nk_widget(&bounds, ctx); 20781 state = nk_keynav_widget(&bounds, ctx);
20733 if (!state) return 0; 20782 if (!state) return 0;
20734 in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input; 20783 in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
20735 return nk_do_button_image(&ctx->last_widget_state, &win->buffer, bounds, 20784 return nk_do_button_image(&ctx->last_widget_state, &win->buffer, bounds,
20736 img, ctx->button_behavior, style, in); 20785 img, ctx->button_behavior, style, in);
20737 } 20786 }
20763 return 0; 20812 return 0;
20764 20813
20765 win = ctx->current; 20814 win = ctx->current;
20766 layout = win->layout; 20815 layout = win->layout;
20767 20816
20768 state = nk_widget(&bounds, ctx); 20817 state = nk_keynav_widget(&bounds, ctx);
20769 if (!state) return 0; 20818 if (!state) return 0;
20770 in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input; 20819 in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
20771 return nk_do_button_text_symbol(&ctx->last_widget_state, &win->buffer, bounds, 20820 return nk_do_button_text_symbol(&ctx->last_widget_state, &win->buffer, bounds,
20772 symbol, text, len, align, ctx->button_behavior, 20821 symbol, text, len, align, ctx->button_behavior,
20773 style, ctx->style.font, in); 20822 style, ctx->style.font, in);
20810 return 0; 20859 return 0;
20811 20860
20812 win = ctx->current; 20861 win = ctx->current;
20813 layout = win->layout; 20862 layout = win->layout;
20814 20863
20815 state = nk_widget(&bounds, ctx); 20864 state = nk_keynav_widget(&bounds, ctx);
20816 if (!state) return 0; 20865 if (!state) return 0;
20817 in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input; 20866 in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
20818 return nk_do_button_text_image(&ctx->last_widget_state, &win->buffer, 20867 return nk_do_button_text_image(&ctx->last_widget_state, &win->buffer,
20819 bounds, img, text, len, align, ctx->button_behavior, 20868 bounds, img, text, len, align, ctx->button_behavior,
20820 style, ctx->style.font, in); 20869 style, ctx->style.font, in);
20861 20910
20862 win = ctx->current; 20911 win = ctx->current;
20863 layout = win->layout; 20912 layout = win->layout;
20864 style = &ctx->style; 20913 style = &ctx->style;
20865 20914
20866 state = nk_widget(&bounds, ctx); 20915 state = nk_keynav_widget(&bounds, ctx);
20867 if (!state) return 0; 20916 if (!state) return 0;
20868 in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input; 20917 in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
20869 return nk_do_selectable(&ctx->last_widget_state, &win->buffer, bounds, 20918 return nk_do_selectable(&ctx->last_widget_state, &win->buffer, bounds,
20870 str, len, align, value, &style->selectable, in, style->font); 20919 str, len, align, value, &style->selectable, in, style->font);
20871 } 20920 }