From cfaffbdbe9c2b114075c76db333e7896c7647f71 Mon Sep 17 00:00:00 2001 From: scribam Date: Tue, 21 Jan 2025 18:45:40 +0100 Subject: [PATCH] WIP: gui: refactor control dialogs events handling --- vita3k/gui/include/gui/state.h | 4 +- vita3k/gui/src/controls_dialog.cpp | 136 +++++++++++++---------------- vita3k/interface.cpp | 21 ++--- 3 files changed, 67 insertions(+), 94 deletions(-) diff --git a/vita3k/gui/include/gui/state.h b/vita3k/gui/include/gui/state.h index c13d53b66e..3c24d4a291 100644 --- a/vita3k/gui/include/gui/state.h +++ b/vita3k/gui/include/gui/state.h @@ -272,9 +272,7 @@ struct GuiState { std::vector disassembly; bool is_capturing_keys = false; - bool is_key_capture_dropped = false; - int old_captured_key = 0; - int captured_key = 0; + int *captured_key = nullptr; std::vector> modules; ImGuiTextFilter module_search_bar; diff --git a/vita3k/gui/src/controls_dialog.cpp b/vita3k/gui/src/controls_dialog.cpp index 514b2b262c..e40325206b 100644 --- a/vita3k/gui/src/controls_dialog.cpp +++ b/vita3k/gui/src/controls_dialog.cpp @@ -22,28 +22,11 @@ #include #include #include +#include #include namespace gui { -static constexpr std::array SDL_key_to_string{ "[unset]", "[unknown]", "[unknown]", "[unknown]", "A", "B", "C", "D", "E", "F", "G", - "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", - "Return/Enter", "Escape", "Backspace", "Tab", "Space", "-", "=", "[", "]", "\\", "NonUS #", ";", "'", "Grave", ",", ".", "/", "CapsLock", "F1", - "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12", "PrtScrn", "ScrlLock", "Pause", "Insert", "Home", "PgUp", "Delete", - "End", "PgDown", "Ar Right", "Ar Left", "Ar Down", "Ar Up", "NumLock/Clear", "Keypad /", "Keypad *", "Keypad -", "Keypad +", - "Keypad Enter", "Keypad 1", "Keypad 2", "Keypad 3", "Keypad 4", "Keypad 5", "Keypad 6", "Keypad 7", "Keypad 8", "Keypad 9", "Keypad 0", - "Keypad .", "NonUs \\", "App", "Power", "Keypad =", "F13", "F14", "F15", "F16", "F17", "F18", "F19", "F20", "F21", "F22", "F23", "F24", "Execute", - "Help", "Menu", "Select", "Stop", "Again", "Undo", "Cut", "Copy", "Paste", "Find", "Mute", "VolUp", "VolDown", "[unset]", "[unset]", "[unset]", - "Keypad ,", "Kp = As400", "International1", "International2", "International3", "International4", "International5", "International6", - "International7", "International8", "International9", "Lang1", "Lang2", "Lang3", "Lang4", "Lang5", "Lang6", "Lang7", "Lang8", "Lang9", "Alt Erase", - "SysReq", "Cancel", "Clear", "Prior", "Return2", "Separator", "Out", "Oper", "ClearAgain", "Crsel", "Exsel", "[unset]", "[unset]", "[unset]", - "[unset]", "[unset]", "[unset]", "[unset]", "[unset]", "[unset]", "[unset]", "[unset]", "Keypad 00", "Keypad 000", "ThousSeparat", "DecSeparat", - "CurrencyUnit", "CurrencySubUnit", "Keypad (", "Keypad )", "Keypad {", "Keypad }", "Keypad Tab", "Keypad Backspace", "Keypad A", "Keypad B", - "Keypad C", "Keypad D", "Keypad E", "Keypad F", "Keypad XOR", "Keypad Power", "Keypad %", "Keypad <", "Keypad >", "Keypad &", "Keypad &&", - "Keypad |", "Keypad ||", "Keypad :", "Keypad #", "Keypad Space", "Keypad @", "Keypad !", "Keypad MemStr", "Keypad MemRec", "Keypad MemClr", - "Keypad Mem+", "Keypad Mem-", "Keypad Mem*", "Keypad Mem/", "Keypad +/-", "Keypad Clear", "Keypad ClearEntry", "Keypad Binary", "Keypad Octal", - "Keypad Dec", "Keypad HexaDec", "[unset]", "[unset]", "LCtrl", "LShift", "LAlt", "Win/Cmd", "RCtrl", "RShift", "RAlt", "RWin/Cmd" }; - #define CALC_KEYBOARD_MEMBERS(option_type, option_name, option_default, member_name) \ +(std::string_view(#member_name).starts_with("keyboard_") ? 1 : 0) // NOLINT(bugprone-macro-parentheses) @@ -69,37 +52,19 @@ static void prepare_map_array(EmuEnvState &emuenv, std::array(*button)))) { + // TODO: Only allow keyboard events + // TODO: Use ImGui::NavHighlightActivated to maintain button visual appearance + gui.captured_key = button; gui.is_capturing_keys = true; - // capture the original state - std::array original_state; - prepare_map_array(emuenv, original_state); - while (gui.is_capturing_keys) { - handle_events(emuenv, gui); - *button = gui.captured_key; - if (*button < 0 || *button > 231) - *button = 0; - else if (gui.is_key_capture_dropped || (!gui.is_capturing_keys && *button != key_association && vector_utils::contains(original_state, *button))) { - // undo the changes - *button = key_association; - gui.is_key_capture_dropped = false; - need_open_error_duplicate_key_popup = true; - } - } - config::serialize_config(emuenv.cfg, emuenv.cfg.config_path); } ImGui::PopID(); } @@ -135,27 +100,27 @@ void draw_controls_dialog(GuiState &gui, EmuEnvState &emuenv) { ImGui::TableSetColumnIndex(1); ImGui::TextColored(GUI_COLOR_TEXT_TITLE, "%s", lang["mapped_button"].c_str()); - remapper_button(gui, emuenv, &emuenv.cfg.keyboard_leftstick_up, lang["left_stick_up"].c_str()); - remapper_button(gui, emuenv, &emuenv.cfg.keyboard_leftstick_down, lang["left_stick_down"].c_str()); - remapper_button(gui, emuenv, &emuenv.cfg.keyboard_leftstick_right, lang["left_stick_right"].c_str()); - remapper_button(gui, emuenv, &emuenv.cfg.keyboard_leftstick_left, lang["left_stick_left"].c_str()); - remapper_button(gui, emuenv, &emuenv.cfg.keyboard_rightstick_up, lang["right_stick_up"].c_str()); - remapper_button(gui, emuenv, &emuenv.cfg.keyboard_rightstick_down, lang["right_stick_down"].c_str()); - remapper_button(gui, emuenv, &emuenv.cfg.keyboard_rightstick_right, lang["right_stick_right"].c_str()); - remapper_button(gui, emuenv, &emuenv.cfg.keyboard_rightstick_left, lang["right_stick_left"].c_str()); - remapper_button(gui, emuenv, &emuenv.cfg.keyboard_button_up, lang["d_pad_up"].c_str()); - remapper_button(gui, emuenv, &emuenv.cfg.keyboard_button_down, lang["d_pad_down"].c_str()); - remapper_button(gui, emuenv, &emuenv.cfg.keyboard_button_right, lang["d_pad_right"].c_str()); - remapper_button(gui, emuenv, &emuenv.cfg.keyboard_button_left, lang["d_pad_left"].c_str()); - remapper_button(gui, emuenv, &emuenv.cfg.keyboard_button_square, lang["square_button"].c_str()); - remapper_button(gui, emuenv, &emuenv.cfg.keyboard_button_cross, lang["cross_button"].c_str()); - remapper_button(gui, emuenv, &emuenv.cfg.keyboard_button_circle, lang["circle_button"].c_str()); - remapper_button(gui, emuenv, &emuenv.cfg.keyboard_button_triangle, lang["triangle_button"].c_str()); - remapper_button(gui, emuenv, &emuenv.cfg.keyboard_button_start, lang["start_button"].c_str()); - remapper_button(gui, emuenv, &emuenv.cfg.keyboard_button_select, lang["select_button"].c_str()); - remapper_button(gui, emuenv, &emuenv.cfg.keyboard_button_psbutton, lang["ps_button"].c_str()); - remapper_button(gui, emuenv, &emuenv.cfg.keyboard_button_l1, lang["l1_button"].c_str()); - remapper_button(gui, emuenv, &emuenv.cfg.keyboard_button_r1, lang["r1_button"].c_str()); + remapper_button(gui, &emuenv.cfg.keyboard_leftstick_up, lang["left_stick_up"].c_str()); + remapper_button(gui, &emuenv.cfg.keyboard_leftstick_down, lang["left_stick_down"].c_str()); + remapper_button(gui, &emuenv.cfg.keyboard_leftstick_right, lang["left_stick_right"].c_str()); + remapper_button(gui, &emuenv.cfg.keyboard_leftstick_left, lang["left_stick_left"].c_str()); + remapper_button(gui, &emuenv.cfg.keyboard_rightstick_up, lang["right_stick_up"].c_str()); + remapper_button(gui, &emuenv.cfg.keyboard_rightstick_down, lang["right_stick_down"].c_str()); + remapper_button(gui, &emuenv.cfg.keyboard_rightstick_right, lang["right_stick_right"].c_str()); + remapper_button(gui, &emuenv.cfg.keyboard_rightstick_left, lang["right_stick_left"].c_str()); + remapper_button(gui, &emuenv.cfg.keyboard_button_up, lang["d_pad_up"].c_str()); + remapper_button(gui, &emuenv.cfg.keyboard_button_down, lang["d_pad_down"].c_str()); + remapper_button(gui, &emuenv.cfg.keyboard_button_right, lang["d_pad_right"].c_str()); + remapper_button(gui, &emuenv.cfg.keyboard_button_left, lang["d_pad_left"].c_str()); + remapper_button(gui, &emuenv.cfg.keyboard_button_square, lang["square_button"].c_str()); + remapper_button(gui, &emuenv.cfg.keyboard_button_cross, lang["cross_button"].c_str()); + remapper_button(gui, &emuenv.cfg.keyboard_button_circle, lang["circle_button"].c_str()); + remapper_button(gui, &emuenv.cfg.keyboard_button_triangle, lang["triangle_button"].c_str()); + remapper_button(gui, &emuenv.cfg.keyboard_button_start, lang["start_button"].c_str()); + remapper_button(gui, &emuenv.cfg.keyboard_button_select, lang["select_button"].c_str()); + remapper_button(gui, &emuenv.cfg.keyboard_button_psbutton, lang["ps_button"].c_str()); + remapper_button(gui, &emuenv.cfg.keyboard_button_l1, lang["l1_button"].c_str()); + remapper_button(gui, &emuenv.cfg.keyboard_button_r1, lang["r1_button"].c_str()); ImGui::EndTable(); } @@ -166,10 +131,10 @@ void draw_controls_dialog(GuiState &gui, EmuEnvState &emuenv) { if (ImGui::BeginTable("PSTV_mode", 2)) { ImGui::TableSetupColumn("button"); ImGui::TableSetupColumn("mapped_button"); - remapper_button(gui, emuenv, &emuenv.cfg.keyboard_button_l2, lang["l2_button"].c_str()); - remapper_button(gui, emuenv, &emuenv.cfg.keyboard_button_r2, lang["r2_button"].c_str()); - remapper_button(gui, emuenv, &emuenv.cfg.keyboard_button_l3, lang["l3_button"].c_str()); - remapper_button(gui, emuenv, &emuenv.cfg.keyboard_button_r3, lang["r3_button"].c_str()); + remapper_button(gui, &emuenv.cfg.keyboard_button_l2, lang["l2_button"].c_str()); + remapper_button(gui, &emuenv.cfg.keyboard_button_r2, lang["r2_button"].c_str()); + remapper_button(gui, &emuenv.cfg.keyboard_button_l3, lang["l3_button"].c_str()); + remapper_button(gui, &emuenv.cfg.keyboard_button_r3, lang["r3_button"].c_str()); ImGui::EndTable(); } ImGui::Separator(); @@ -178,9 +143,9 @@ void draw_controls_dialog(GuiState &gui, EmuEnvState &emuenv) { if (ImGui::BeginTable("gui", 2)) { ImGui::TableSetupColumn("button"); ImGui::TableSetupColumn("mapped_button"); - remapper_button(gui, emuenv, &emuenv.cfg.keyboard_gui_fullscreen, lang["full_screen"].c_str()); - remapper_button(gui, emuenv, &emuenv.cfg.keyboard_gui_toggle_touch, lang["toggle_touch"].c_str(), lang["toggle_touch_description"].c_str()); - remapper_button(gui, emuenv, &emuenv.cfg.keyboard_gui_toggle_gui, lang["toggle_gui_visibility"].c_str(), lang["toggle_gui_visibility_description"].c_str()); + remapper_button(gui, &emuenv.cfg.keyboard_gui_fullscreen, lang["full_screen"].c_str()); + remapper_button(gui, &emuenv.cfg.keyboard_gui_toggle_touch, lang["toggle_touch"].c_str(), lang["toggle_touch_description"].c_str()); + remapper_button(gui, &emuenv.cfg.keyboard_gui_toggle_gui, lang["toggle_gui_visibility"].c_str(), lang["toggle_gui_visibility_description"].c_str()); ImGui::EndTable(); } @@ -190,15 +155,11 @@ void draw_controls_dialog(GuiState &gui, EmuEnvState &emuenv) { if (ImGui::BeginTable("misc", 2)) { ImGui::TableSetupColumn("button"); ImGui::TableSetupColumn("mapped_button"); - remapper_button(gui, emuenv, &emuenv.cfg.keyboard_toggle_texture_replacement, lang["toggle_texture_replacement"].c_str()); - remapper_button(gui, emuenv, &emuenv.cfg.keyboard_take_screenshot, lang["take_a_screenshot"].c_str()); + remapper_button(gui, &emuenv.cfg.keyboard_toggle_texture_replacement, lang["toggle_texture_replacement"].c_str()); + remapper_button(gui, &emuenv.cfg.keyboard_take_screenshot, lang["take_a_screenshot"].c_str()); ImGui::EndTable(); } - if (need_open_error_duplicate_key_popup) { - ImGui::OpenPopup(gui.lang.controls["error"].c_str()); - need_open_error_duplicate_key_popup = false; - } ImGui::SetNextWindowPos(ImVec2(ImGui::GetIO().DisplaySize.x / 2.f, ImGui::GetIO().DisplaySize.y / 2.f), ImGuiCond_Always, ImVec2(0.5f, 0.5f)); if (ImGui::BeginPopupModal(lang["error"].c_str(), nullptr, ImGuiWindowFlags_AlwaysAutoResize)) { ImGui::Text("%s", lang["error_duplicate_key"].c_str()); @@ -217,6 +178,31 @@ void draw_controls_dialog(GuiState &gui, EmuEnvState &emuenv) { if (ImGui::Button(common["close"].c_str(), BUTTON_SIZE)) gui.controls_menu.controls_dialog = false; + if (gui.is_capturing_keys) { + if (ImGui::IsKeyDown(ImGuiKey_Escape)) { + ImGui::OpenPopup(gui.lang.controls["error"].c_str()); + gui.captured_key = nullptr; + gui.is_capturing_keys = false; + } else { + for (ImGuiKey key = ImGuiKey_NamedKey_BEGIN; key < ImGuiKey_GamepadStart; key = static_cast(key + 1)) { + if (ImGui::IsKeyDown(key)) { + if (*gui.captured_key != key) { + std::array original_state; + prepare_map_array(emuenv, original_state); + if (vector_utils::contains(original_state, key)) { + ImGui::OpenPopup(gui.lang.controls["error"].c_str()); + } else { + *gui.captured_key = key; + config::serialize_config(emuenv.cfg, emuenv.cfg.config_path); + } + } + gui.captured_key = nullptr; + gui.is_capturing_keys = false; + } + } + } + } + ImGui::End(); } diff --git a/vita3k/interface.cpp b/vita3k/interface.cpp index 9e86adbe16..2cf55802cc 100644 --- a/vita3k/interface.cpp +++ b/vita3k/interface.cpp @@ -20,6 +20,7 @@ #include "module/load_module.h" #include +#include #include #include #include @@ -697,31 +698,19 @@ bool handle_events(EmuEnvState &emuenv, GuiState &gui) { // Get Sce Ctrl button from key const auto sce_ctrl_btn = get_sce_ctrl_btn_from_scancode(event.key.keysym.scancode); - if (gui.is_capturing_keys && event.key.keysym.scancode) { - gui.is_key_capture_dropped = false; - if (event.key.keysym.scancode == SDL_SCANCODE_ESCAPE) { - LOG_ERROR("Key is reserved!"); - gui.captured_key = gui.old_captured_key; - gui.is_key_capture_dropped = true; - } else { - gui.captured_key = static_cast(event.key.keysym.scancode); - } - gui.is_capturing_keys = false; - } - if (ImGui::GetIO().WantTextInput || gui.is_key_locked) continue; // toggle gui state if (allow_switch_state && (event.key.keysym.scancode == emuenv.cfg.keyboard_gui_toggle_gui)) emuenv.display.imgui_render = !emuenv.display.imgui_render; - if (event.key.keysym.scancode == emuenv.cfg.keyboard_gui_toggle_touch && !gui.is_key_capture_dropped) + if (event.key.keysym.scancode == emuenv.cfg.keyboard_gui_toggle_touch && !gui.is_capturing_keys) toggle_touchscreen(); - if (event.key.keysym.scancode == emuenv.cfg.keyboard_gui_fullscreen && !gui.is_key_capture_dropped) + if (event.key.keysym.scancode == emuenv.cfg.keyboard_gui_fullscreen && !gui.is_capturing_keys) switch_full_screen(emuenv); - if (event.key.keysym.scancode == emuenv.cfg.keyboard_toggle_texture_replacement && !gui.is_key_capture_dropped) + if (event.key.keysym.scancode == emuenv.cfg.keyboard_toggle_texture_replacement && !gui.is_capturing_keys) toggle_texture_replacement(emuenv); - if (event.key.keysym.scancode == emuenv.cfg.keyboard_take_screenshot && !gui.is_key_capture_dropped) + if (event.key.keysym.scancode == emuenv.cfg.keyboard_take_screenshot && !gui.is_capturing_keys) take_screenshot(emuenv); if (sce_ctrl_btn != 0) {