From 68cc0c9df991dedbdfcf71a17c4b8ca1737609da Mon Sep 17 00:00:00 2001 From: MysterD Date: Tue, 22 Jun 2021 21:28:12 -0700 Subject: [PATCH] DJUI: Improved keyboard/gamepad input --- src/pc/djui/djui_cursor.c | 35 +++++++++++++++--------- src/pc/djui/djui_cursor.h | 1 + src/pc/djui/djui_panel_main.c | 1 + src/pc/djui/djui_panel_options.c | 16 ++++++++--- src/pc/djui/djui_panel_quit.c | 46 +++++++++++++++++++++++--------- 5 files changed, 70 insertions(+), 29 deletions(-) diff --git a/src/pc/djui/djui_cursor.c b/src/pc/djui/djui_cursor.c index e4d79937..6aaa60a1 100644 --- a/src/pc/djui/djui_cursor.c +++ b/src/pc/djui/djui_cursor.c @@ -14,6 +14,8 @@ ALIGNED8 static u8 texture_hand_closed[] = { static struct DjuiImage* sMouseCursor = NULL; static bool sCursorMouseControlled = false; +static struct DjuiBase* sInputControlledBase = NULL; + static f32 sSavedMouseX = 0; static f32 sSavedMouseY = 0; static f32 sCursorX = 0; @@ -33,6 +35,17 @@ static void djui_cursor_base_hover_location(struct DjuiBase* base, f32* x, f32* *y = (base->elem.y + base->elem.height * 3.0f / 4.0f); } +void djui_cursor_input_controlled_center(struct DjuiBase* base) { + if (!sCursorMouseControlled) { + sInputControlledBase = base; + if (sMouseCursor != NULL) { + djui_base_set_visible(&sMouseCursor->base, (base != NULL)); + } + sSavedMouseX = mouse_window_x; + sSavedMouseY = mouse_window_y; + } +} + static f32 djui_cursor_base_distance(struct DjuiBase* base) { f32 x, y; djui_cursor_base_hover_location(base, &x, &y); @@ -80,12 +93,8 @@ void djui_cursor_move(s8 xDir, s8 yDir) { struct DjuiBase* pick = NULL; djui_cursor_move_check(xDir, yDir, &pick, &gDjuiRoot->base); if (pick != NULL) { - if (sCursorMouseControlled) { - sCursorMouseControlled = false; - sSavedMouseX = sCursorX; - sSavedMouseY = sCursorY; - } - djui_cursor_base_hover_location(pick, &sCursorX, &sCursorY); + sCursorMouseControlled = false; + djui_cursor_input_controlled_center(pick); } } @@ -94,16 +103,18 @@ void djui_cursor_update(void) { controller_sdl_read_mouse_window(); // adjust mouse cursor - if (!sCursorMouseControlled) { - f32 dist = sqrtf(powf(mouse_window_x - sSavedMouseX, 2) + powf(mouse_window_y - sSavedMouseY, 2)); - if (dist > 2) { - sCursorMouseControlled = true; - } - } if (sCursorMouseControlled) { sCursorX = mouse_window_x; sCursorY = mouse_window_y; + } else if (sInputControlledBase != NULL) { + djui_cursor_base_hover_location(sInputControlledBase, &sCursorX, &sCursorY); + f32 dist = sqrtf(powf(mouse_window_x - sSavedMouseX, 2) + powf(mouse_window_y - sSavedMouseY, 2)); + if (dist > 5) { + sCursorMouseControlled = true; + djui_base_set_visible(&sMouseCursor->base, true); + } } + djui_base_set_location(&sMouseCursor->base, sCursorX - 13, sCursorY - 13); if (mouse_window_buttons & 0b0001) { diff --git a/src/pc/djui/djui_cursor.h b/src/pc/djui/djui_cursor.h index 690b5d4a..6b902499 100644 --- a/src/pc/djui/djui_cursor.h +++ b/src/pc/djui/djui_cursor.h @@ -3,6 +3,7 @@ #include "djui_base.h" bool djui_cursor_inside_base(struct DjuiBase* base); +void djui_cursor_input_controlled_center(struct DjuiBase* base); void djui_cursor_move(s8 xDir, s8 yDir); void djui_cursor_update(void); void djui_cursor_create(void); diff --git a/src/pc/djui/djui_panel_main.c b/src/pc/djui/djui_panel_main.c index b226b4aa..ccc8bee0 100644 --- a/src/pc/djui/djui_panel_main.c +++ b/src/pc/djui/djui_panel_main.c @@ -30,6 +30,7 @@ void djui_panel_main_create(void) { struct DjuiButton* button1 = djui_button_create(&sButtonContainer->base, "Host"); djui_base_set_size_type(&button1->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); djui_base_set_size(&button1->base, 1.0f, 64); + djui_cursor_input_controlled_center(&button1->base); struct DjuiButton* button2 = djui_button_create(&sButtonContainer->base, "Join"); djui_base_set_size_type(&button2->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); diff --git a/src/pc/djui/djui_panel_options.c b/src/pc/djui/djui_panel_options.c index bcb88fdb..b8f2d6a0 100644 --- a/src/pc/djui/djui_panel_options.c +++ b/src/pc/djui/djui_panel_options.c @@ -4,6 +4,8 @@ static struct DjuiRect* sPanelOptions = NULL; static struct DjuiFlowLayout* sButtonContainer = NULL; static struct DjuiText* sTitleText = NULL; +static struct DjuiButton* sButtonBack = NULL; +static struct DjuiBase* sCaller = NULL; static bool sOpening = false; static bool sClosing = false; @@ -18,6 +20,7 @@ static void djui_panel_options_render_pre(struct DjuiBase* base, bool* skipRende movement = yMove; sOpening = false; djui_base_set_enabled(&sPanelOptions->base, true); + djui_cursor_input_controlled_center(&sButtonBack->base); } } else if (sClosing) { movement -= yMove / 10.0f; @@ -29,11 +32,13 @@ static void djui_panel_options_render_pre(struct DjuiBase* base, bool* skipRende *skipRender = true; djui_base_set_enabled(&gPanelMainMenu->base, true); gPanelMainMenu->base.y.value = 0; + djui_cursor_input_controlled_center(sCaller); return; } } else { movement = yMove; } + gPanelMainMenu->base.y.value = yMove * smoothstep(0, yMove, movement); sPanelOptions->base.y.value = gPanelMainMenu->base.elem.y - sPanelOptions->base.elem.height; } @@ -41,6 +46,7 @@ static void djui_panel_options_render_pre(struct DjuiBase* base, bool* skipRende static void djui_panel_options_back(struct DjuiBase* base) { sClosing = true; djui_base_set_enabled(&sPanelOptions->base, false); + djui_cursor_input_controlled_center(NULL); } void djui_panel_options_create(void) { @@ -83,10 +89,10 @@ void djui_panel_options_create(void) { djui_base_set_size_type(&button5->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); djui_base_set_size(&button5->base, 1.0f, 64); - struct DjuiButton* button6 = djui_button_create(&sButtonContainer->base, "Back"); - djui_base_set_size_type(&button6->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); - djui_base_set_size(&button6->base, 1.0f, 64); - button6->base.interactable->on_click = djui_panel_options_back; + sButtonBack = djui_button_create(&sButtonContainer->base, "Back"); + djui_base_set_size_type(&sButtonBack->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); + djui_base_set_size(&sButtonBack->base, 1.0f, 64); + sButtonBack->base.interactable->on_click = djui_panel_options_back; } sTitleText = djui_text_create(&sPanelOptions->base, "\\#ff0800\\O\\#1be700\\P\\#00b3ff\\T\\#ffef00\\I\\#ff0800\\O\\#1be700\\N\\#00b3ff\\S"); @@ -101,6 +107,8 @@ void djui_panel_options_create(void) { } void djui_panel_options_open(struct DjuiBase* caller) { + sCaller = caller; + djui_cursor_input_controlled_center(NULL); djui_base_set_enabled(&gPanelMainMenu->base, false); djui_panel_options_create(); } diff --git a/src/pc/djui/djui_panel_quit.c b/src/pc/djui/djui_panel_quit.c index 0cf42823..ad001fb6 100644 --- a/src/pc/djui/djui_panel_quit.c +++ b/src/pc/djui/djui_panel_quit.c @@ -2,10 +2,16 @@ #include "src/pc/utils/misc.h" static struct DjuiRect* sPanelQuit = NULL; +static struct DjuiFlowLayout* sButtonContainer = NULL; +static struct DjuiText* sTitleText = NULL; +static struct DjuiButton* sButtonNo = NULL; +static struct DjuiBase* sCaller = NULL; static bool sOpening = false; static bool sClosing = false; static void djui_panel_quit_render_pre(struct DjuiBase* base, bool* skipRender) { + sTitleText->base.height.value = sButtonContainer->base.clip.y - sPanelQuit->base.comp.y; + float yMove = gPanelMainMenu->base.elem.height; static float movement = 0; if (sOpening) { @@ -14,6 +20,7 @@ static void djui_panel_quit_render_pre(struct DjuiBase* base, bool* skipRender) movement = yMove; sOpening = false; djui_base_set_enabled(&sPanelQuit->base, true); + djui_cursor_input_controlled_center(&sButtonNo->base); } } else if (sClosing) { movement -= yMove / 10.0f; @@ -25,6 +32,7 @@ static void djui_panel_quit_render_pre(struct DjuiBase* base, bool* skipRender) *skipRender = true; djui_base_set_enabled(&gPanelMainMenu->base, true); gPanelMainMenu->base.y.value = 0; + djui_cursor_input_controlled_center(sCaller); return; } } else { @@ -41,6 +49,7 @@ static void djui_panel_quit_yes(struct DjuiBase* base) { static void djui_panel_quit_no(struct DjuiBase* base) { sClosing = true; djui_base_set_enabled(&sPanelQuit->base, false); + djui_cursor_input_controlled_center(NULL); } static void djui_panel_quit_create(void) { @@ -56,34 +65,45 @@ static void djui_panel_quit_create(void) { djui_base_set_enabled(&sPanelQuit->base, false); sPanelQuit->base.on_render_pre = djui_panel_quit_render_pre; { - struct DjuiFlowLayout* quitContainer = djui_flow_layout_create(&sPanelQuit->base); - djui_base_set_alignment(&quitContainer->base, DJUI_HALIGN_CENTER, DJUI_VALIGN_CENTER); - djui_base_set_size_type(&quitContainer->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); - djui_base_set_size(&quitContainer->base, 1.0f, 64 * 3 + 16 * 2); - djui_base_set_color(&quitContainer->base, 0, 0, 0, 0); - djui_flow_layout_set_margin(quitContainer, 16); - djui_flow_layout_set_flow_direction(quitContainer, DJUI_FLOW_DIR_DOWN); + sButtonContainer = djui_flow_layout_create(&sPanelQuit->base); + djui_base_set_alignment(&sButtonContainer->base, DJUI_HALIGN_CENTER, DJUI_VALIGN_CENTER); + djui_base_set_size_type(&sButtonContainer->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); + djui_base_set_size(&sButtonContainer->base, 1.0f, 64 * 3 + 16 * 2); + djui_base_set_color(&sButtonContainer->base, 0, 0, 0, 0); + djui_flow_layout_set_margin(sButtonContainer, 16); + djui_flow_layout_set_flow_direction(sButtonContainer, DJUI_FLOW_DIR_DOWN); { - struct DjuiText* text = djui_text_create(&quitContainer->base, "Are you sure you want to quit?"); + struct DjuiText* text = djui_text_create(&sButtonContainer->base, "Are you sure you want to quit?"); djui_base_set_size_type(&text->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); djui_base_set_size(&text->base, 1.0f, 64); djui_base_set_color(&text->base, 200, 200, 200, 255); djui_text_set_alignment(text, DJUI_HALIGN_CENTER, DJUI_VALIGN_CENTER); - struct DjuiButton* button1 = djui_button_create(&quitContainer->base, "Yes"); + struct DjuiButton* button1 = djui_button_create(&sButtonContainer->base, "Yes"); djui_base_set_size_type(&button1->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); djui_base_set_size(&button1->base, 1.0f, 64); button1->base.interactable->on_click = djui_panel_quit_yes; - struct DjuiButton* button2 = djui_button_create(&quitContainer->base, "No"); - djui_base_set_size_type(&button2->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); - djui_base_set_size(&button2->base, 1.0f, 64); - button2->base.interactable->on_click = djui_panel_quit_no; + sButtonNo = djui_button_create(&sButtonContainer->base, "No"); + djui_base_set_size_type(&sButtonNo->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); + djui_base_set_size(&sButtonNo->base, 1.0f, 64); + sButtonNo->base.interactable->on_click = djui_panel_quit_no; } + + sTitleText = djui_text_create(&sPanelQuit->base, "\\#ff0800\\Q\\#1be700\\U\\#00b3ff\\I\\#ffef00\\T"); + djui_base_set_alignment(&sTitleText->base, DJUI_HALIGN_CENTER, DJUI_VALIGN_TOP); + djui_base_set_size_type(&sTitleText->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); + djui_base_set_size(&sTitleText->base, 1.0f, 1.0f); + djui_base_set_color(&sTitleText->base, 255, 8, 0, 255); + djui_text_set_alignment(sTitleText, DJUI_HALIGN_CENTER, DJUI_VALIGN_CENTER); + djui_text_set_font(sTitleText, &gDjuiFonts[1]); + djui_text_set_font_scale(sTitleText, gDjuiFonts[1].defaultFontScale); } } void djui_panel_quit_open(struct DjuiBase* caller) { + sCaller = caller; + djui_cursor_input_controlled_center(NULL); djui_base_set_enabled(&gPanelMainMenu->base, false); djui_panel_quit_create(); }