From b104ca358ae6f8cda5465402afedb1ee7c652844 Mon Sep 17 00:00:00 2001 From: Oskar Wallgren Date: Fri, 16 Aug 2024 19:21:44 +0200 Subject: [PATCH 1/7] Use middle mouse button to spin models * Make grab/spin action consistent and default to middle mouse button. * Option to use left mouse button in cases where no middle mouse button is available such as on a laptop. --- data/lang/ui-core/en.json | 8 ++++++++ data/pigui/modules/settings-window.lua | 4 ++++ src/GameConfig.cpp | 1 + src/Input.cpp | 11 +++++++++++ src/Input.h | 4 ++++ src/SectorMap.cpp | 3 ++- src/SystemView.cpp | 3 ++- src/lua/LuaInput.cpp | 20 ++++++++++++++++++++ src/pigui/ModelSpinner.cpp | 5 ++++- src/pigui/ModelSpinner.h | 3 +++ src/ship/ShipViewController.cpp | 3 ++- 11 files changed, 61 insertions(+), 4 deletions(-) diff --git a/data/lang/ui-core/en.json b/data/lang/ui-core/en.json index 75c62398d6c..35f05df87f1 100644 --- a/data/lang/ui-core/en.json +++ b/data/lang/ui-core/en.json @@ -1335,6 +1335,14 @@ "description": "", "message": "Invert Mouse Y" }, + "NO_MIDDLE_MOUSE_BUTTON": { + "description": "", + "message": "No middle mouse button available" + }, + "NO_MIDDLE_MOUSE_BUTTON_DESC": { + "description": "", + "message": "Use left mouse button to grab/spin objects when there is no middle mouse button available" + }, "IN_CARGO_HOLD": { "description": "", "message": "In cargo hold" diff --git a/data/pigui/modules/settings-window.lua b/data/pigui/modules/settings-window.lua index c1dfeb7348c..873c72fe8ae 100644 --- a/data/pigui/modules/settings-window.lua +++ b/data/pigui/modules/settings-window.lua @@ -574,6 +574,7 @@ local function showControlsOptions() ui.text(lui.CONTROL_OPTIONS) local mouseYInvert = Input.GetMouseYInverted() + local middleMouseButton = Input.IsMiddleMouseButton() local joystickEnabled = Input.GetJoystickEnabled() binding_pages = Input.GetBindingPages() local c @@ -581,6 +582,9 @@ local function showControlsOptions() c,mouseYInvert = checkbox(lui.INVERT_MOUSE_Y, mouseYInvert) if c then Input.SetMouseYInverted(mouseYInvert) end + c,middleMouseButton = checkbox(lui.NO_MIDDLE_MOUSE_BUTTON, middleMouseButton, lui.NO_MIDDLE_MOUSE_BUTTON_DESC) + if c then Input.SetMiddleMouseButton(middleMouseButton) end + c,joystickEnabled = checkbox(lui.ENABLE_JOYSTICK, joystickEnabled) if c then Input.SetJoystickEnabled(joystickEnabled) end diff --git a/src/GameConfig.cpp b/src/GameConfig.cpp index 11f84f926a3..4bb0eacb11a 100644 --- a/src/GameConfig.cpp +++ b/src/GameConfig.cpp @@ -21,6 +21,7 @@ GameConfig::GameConfig(const map_string &override_) map["SfxVolume"] = "0.8"; map["EnableJoystick"] = "1"; map["InvertMouseY"] = "0"; + map["noMiddleMouseButton"] = "0"; map["FOVVertical"] = "65"; map["DisplayNavTunnel"] = "0"; map["CompactRadar"] = "1"; diff --git a/src/Input.cpp b/src/Input.cpp index 0ddcbbe432e..35399d5eff6 100644 --- a/src/Input.cpp +++ b/src/Input.cpp @@ -251,11 +251,13 @@ Manager::Manager(IniConfig *config, SDL_Window *window) : m_capturingMouse(false), joystickEnabled(true), mouseYInvert(false), + noMiddleMouseButton(false), // Which means a middle mouse button is expected by default m_enableBindings(true), m_frameListChanged(false) { joystickEnabled = (m_config->Int("EnableJoystick")) ? true : false; mouseYInvert = (m_config->Int("InvertMouseY")) ? true : false; + noMiddleMouseButton = (m_config->Int("noMiddleMouseButton")) ? true : false; Input::InitJoysticks(m_config); } @@ -517,6 +519,15 @@ void Manager::SetMouseYInvert(bool state) } } +void Manager::SetMiddleMouseButton(bool state) +{ + noMiddleMouseButton = state; + if (m_enableConfigSaving) { + m_config->SetInt("noMiddleMouseButton", noMiddleMouseButton); + m_config->Save(); + } +} + void Manager::GetMousePosition(int position[2]) { SDL_GetMouseState(&position[0], &position[1]); diff --git a/src/Input.h b/src/Input.h index d79fba3e130..d83bd8e2706 100644 --- a/src/Input.h +++ b/src/Input.h @@ -191,6 +191,9 @@ class Input::Manager { bool IsMouseYInvert() { return mouseYInvert; } void SetMouseYInvert(bool state); + bool IsMiddleMouseButton() { return noMiddleMouseButton; } + void SetMiddleMouseButton(bool state); + bool IsMouseButtonPressed(int button) { return mouseButton[button] == 1; } bool IsMouseButtonReleased(int button) { return mouseButton[button] == 4; } @@ -246,6 +249,7 @@ class Input::Manager { bool joystickEnabled; bool mouseYInvert; + bool noMiddleMouseButton; std::map bindingPages; std::map actionBindings; diff --git a/src/SectorMap.cpp b/src/SectorMap.cpp index 7ff95804c9b..4a3fbc7a0a8 100644 --- a/src/SectorMap.cpp +++ b/src/SectorMap.cpp @@ -1151,7 +1151,8 @@ void SectorMap::Update(float frameTime) if (InputBindings.mapViewPitch->IsActive()) m_rotXMovingTo += 0.5f * moveSpeed * InputBindings.mapViewPitch->GetValue(); // to capture mouse when button was pressed and release when released - if (input->MouseButtonState(SDL_BUTTON_MIDDLE) != m_rotateWithMouseButton) { + const int mouseButton = (input->IsMiddleMouseButton() ? SDL_BUTTON_LEFT : SDL_BUTTON_MIDDLE); + if (input->MouseButtonState(mouseButton) != m_rotateWithMouseButton) { m_rotateWithMouseButton = !m_rotateWithMouseButton; input->SetCapturingMouse(m_rotateWithMouseButton); } diff --git a/src/SystemView.cpp b/src/SystemView.cpp index aa423dccec2..2d17a57e965 100644 --- a/src/SystemView.cpp +++ b/src/SystemView.cpp @@ -843,7 +843,8 @@ void SystemMapViewport::HandleInput(float ft) Input::Manager *inputMgr = m_app->GetInput(); // to capture mouse when button was pressed and release when released - if (inputMgr->MouseButtonState(SDL_BUTTON_MIDDLE) != m_rotateWithMouseButton) { + const int mouseButton = (inputMgr->IsMiddleMouseButton() ? SDL_BUTTON_LEFT : SDL_BUTTON_MIDDLE); + if (inputMgr->MouseButtonState(mouseButton) != m_rotateWithMouseButton) { m_rotateWithMouseButton = !m_rotateWithMouseButton; inputMgr->SetCapturingMouse(m_rotateWithMouseButton); } diff --git a/src/lua/LuaInput.cpp b/src/lua/LuaInput.cpp index 19442857c8e..db21df15f8c 100644 --- a/src/lua/LuaInput.cpp +++ b/src/lua/LuaInput.cpp @@ -890,6 +890,24 @@ static int l_input_set_mouse_y_inverted(lua_State *l) return 0; } + +static int l_input_is_middle_mouse_button(lua_State *l) +{ + lua_pushboolean(l, Pi::input->IsMiddleMouseButton()); + return 1; +} + +static int l_input_set_middle_mouse_button(lua_State *l) +{ + if (lua_isnone(l, 1)) + return luaL_error(l, "SetMiddleMouseButton takes one boolean argument"); + const bool mousebutton = lua_toboolean(l, 1); + Pi::config->SetInt("noMiddleMouseButton", (mousebutton ? 1 : 0)); + Pi::config->Save(); + Pi::input->SetMiddleMouseButton(mousebutton); + return 0; +} + static int l_input_get_mouse_captured(lua_State *l) { LuaPush(l, Pi::input->IsCapturingMouse()); @@ -1122,6 +1140,8 @@ void LuaInput::Register() { "SaveBinding", l_input_save_binding }, { "GetMouseYInverted", l_input_get_mouse_y_inverted }, { "SetMouseYInverted", l_input_set_mouse_y_inverted }, + { "IsMiddleMouseButton", l_input_is_middle_mouse_button }, + { "SetMiddleMouseButton", l_input_set_middle_mouse_button }, { "GetJoystickEnabled", l_input_get_joystick_enabled }, { "SetJoystickEnabled", l_input_set_joystick_enabled }, diff --git a/src/pigui/ModelSpinner.cpp b/src/pigui/ModelSpinner.cpp index f6c9aeece7e..54d80f8ae26 100644 --- a/src/pigui/ModelSpinner.cpp +++ b/src/pigui/ModelSpinner.cpp @@ -9,6 +9,7 @@ #include "graphics/RenderTarget.h" #include "graphics/Renderer.h" #include "graphics/Texture.h" +#include "Input.h" #include "scenegraph/Tag.h" #include @@ -17,6 +18,7 @@ using namespace PiGui; ModelSpinner::ModelSpinner() : m_spinning(true), + m_middleMouseButton(false), m_pauseTime(.0f), m_rot(vector2f(DEG2RAD(-15.0), DEG2RAD(120.0))), m_zoom(1.0f), @@ -136,7 +138,8 @@ void ModelSpinner::DrawPiGui() const ImGuiIO &io = ImGui::GetIO(); bool hovered = ImGui::IsItemHovered(); - if (hovered && ImGui::IsMouseDown(0)) { + const int mouseButton = (Pi::input->IsMiddleMouseButton() ? 0 : 2); // 0 : 2 = ImGui mouse button Left and Middle. + if (hovered && ImGui::IsMouseDown(mouseButton)) { m_rot.x -= 0.005 * io.MouseDelta.y; m_rot.y -= 0.005 * io.MouseDelta.x; m_pauseTime = 1.0f; diff --git a/src/pigui/ModelSpinner.h b/src/pigui/ModelSpinner.h index a4c3851ad71..875b507a10d 100644 --- a/src/pigui/ModelSpinner.h +++ b/src/pigui/ModelSpinner.h @@ -71,6 +71,9 @@ namespace PiGui { // Shoulde we spinne? bool m_spinning; + // Is there a middle mouse button? + bool m_middleMouseButton; + // After the user manually rotates the model, hold that orientation for // a second to let them look at it. Assumes Update() is called every // frame while visible. diff --git a/src/ship/ShipViewController.cpp b/src/ship/ShipViewController.cpp index 2677f038879..0a46c3f4d35 100644 --- a/src/ship/ShipViewController.cpp +++ b/src/ship/ShipViewController.cpp @@ -273,7 +273,8 @@ void ShipViewController::Update() Pi::input->GetMouseMotion(mouseMotion); // external camera mouselook - bool mouse_down = Pi::input->MouseButtonState(SDL_BUTTON_MIDDLE); + const int mouseButton = (Pi::input->IsMiddleMouseButton() ? SDL_BUTTON_LEFT : SDL_BUTTON_MIDDLE); + bool mouse_down = Pi::input->MouseButtonState(mouseButton); if (mouse_down && !headtracker_input_priority) { if (!m_mouseActive) { m_mouseActive = true; From 33027e6eaa1cd1791ab48d07373e840b22b4f433 Mon Sep 17 00:00:00 2001 From: Oskar Wallgren Date: Fri, 16 Aug 2024 19:44:36 +0200 Subject: [PATCH 2/7] IsMiddleMouseButton -> EmulateMiddleMouseButton --- data/pigui/modules/settings-window.lua | 2 +- src/Input.h | 2 +- src/SectorMap.cpp | 2 +- src/SystemView.cpp | 2 +- src/lua/LuaInput.cpp | 4 ++-- src/pigui/ModelSpinner.cpp | 2 +- src/ship/ShipViewController.cpp | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/data/pigui/modules/settings-window.lua b/data/pigui/modules/settings-window.lua index 873c72fe8ae..387be221b6d 100644 --- a/data/pigui/modules/settings-window.lua +++ b/data/pigui/modules/settings-window.lua @@ -574,7 +574,7 @@ local function showControlsOptions() ui.text(lui.CONTROL_OPTIONS) local mouseYInvert = Input.GetMouseYInverted() - local middleMouseButton = Input.IsMiddleMouseButton() + local middleMouseButton = Input.EmulateMiddleMouseButton() local joystickEnabled = Input.GetJoystickEnabled() binding_pages = Input.GetBindingPages() local c diff --git a/src/Input.h b/src/Input.h index d83bd8e2706..a647135943e 100644 --- a/src/Input.h +++ b/src/Input.h @@ -191,7 +191,7 @@ class Input::Manager { bool IsMouseYInvert() { return mouseYInvert; } void SetMouseYInvert(bool state); - bool IsMiddleMouseButton() { return noMiddleMouseButton; } + bool EmulateMiddleMouseButton() { return noMiddleMouseButton; } void SetMiddleMouseButton(bool state); bool IsMouseButtonPressed(int button) { return mouseButton[button] == 1; } diff --git a/src/SectorMap.cpp b/src/SectorMap.cpp index 4a3fbc7a0a8..c382aad5aa6 100644 --- a/src/SectorMap.cpp +++ b/src/SectorMap.cpp @@ -1151,7 +1151,7 @@ void SectorMap::Update(float frameTime) if (InputBindings.mapViewPitch->IsActive()) m_rotXMovingTo += 0.5f * moveSpeed * InputBindings.mapViewPitch->GetValue(); // to capture mouse when button was pressed and release when released - const int mouseButton = (input->IsMiddleMouseButton() ? SDL_BUTTON_LEFT : SDL_BUTTON_MIDDLE); + const int mouseButton = (input->EmulateMiddleMouseButton() ? SDL_BUTTON_LEFT : SDL_BUTTON_MIDDLE); if (input->MouseButtonState(mouseButton) != m_rotateWithMouseButton) { m_rotateWithMouseButton = !m_rotateWithMouseButton; input->SetCapturingMouse(m_rotateWithMouseButton); diff --git a/src/SystemView.cpp b/src/SystemView.cpp index 2d17a57e965..0d6eb2fd9c9 100644 --- a/src/SystemView.cpp +++ b/src/SystemView.cpp @@ -843,7 +843,7 @@ void SystemMapViewport::HandleInput(float ft) Input::Manager *inputMgr = m_app->GetInput(); // to capture mouse when button was pressed and release when released - const int mouseButton = (inputMgr->IsMiddleMouseButton() ? SDL_BUTTON_LEFT : SDL_BUTTON_MIDDLE); + const int mouseButton = (inputMgr->EmulateMiddleMouseButton() ? SDL_BUTTON_LEFT : SDL_BUTTON_MIDDLE); if (inputMgr->MouseButtonState(mouseButton) != m_rotateWithMouseButton) { m_rotateWithMouseButton = !m_rotateWithMouseButton; inputMgr->SetCapturingMouse(m_rotateWithMouseButton); diff --git a/src/lua/LuaInput.cpp b/src/lua/LuaInput.cpp index db21df15f8c..034a1477033 100644 --- a/src/lua/LuaInput.cpp +++ b/src/lua/LuaInput.cpp @@ -891,7 +891,7 @@ static int l_input_set_mouse_y_inverted(lua_State *l) } -static int l_input_is_middle_mouse_button(lua_State *l) +static int l_input_emulate_middle_mouse_button(lua_State *l) { lua_pushboolean(l, Pi::input->IsMiddleMouseButton()); return 1; @@ -1140,7 +1140,7 @@ void LuaInput::Register() { "SaveBinding", l_input_save_binding }, { "GetMouseYInverted", l_input_get_mouse_y_inverted }, { "SetMouseYInverted", l_input_set_mouse_y_inverted }, - { "IsMiddleMouseButton", l_input_is_middle_mouse_button }, + { "EmulateMiddleMouseButton", l_input_emulate_middle_mouse_button }, { "SetMiddleMouseButton", l_input_set_middle_mouse_button }, { "GetJoystickEnabled", l_input_get_joystick_enabled }, { "SetJoystickEnabled", l_input_set_joystick_enabled }, diff --git a/src/pigui/ModelSpinner.cpp b/src/pigui/ModelSpinner.cpp index 54d80f8ae26..953b7c2c050 100644 --- a/src/pigui/ModelSpinner.cpp +++ b/src/pigui/ModelSpinner.cpp @@ -138,7 +138,7 @@ void ModelSpinner::DrawPiGui() const ImGuiIO &io = ImGui::GetIO(); bool hovered = ImGui::IsItemHovered(); - const int mouseButton = (Pi::input->IsMiddleMouseButton() ? 0 : 2); // 0 : 2 = ImGui mouse button Left and Middle. + const int mouseButton = (Pi::input->EmulateMiddleMouseButton() ? 0 : 2); // 0 : 2 = ImGui mouse button Left and Middle. if (hovered && ImGui::IsMouseDown(mouseButton)) { m_rot.x -= 0.005 * io.MouseDelta.y; m_rot.y -= 0.005 * io.MouseDelta.x; diff --git a/src/ship/ShipViewController.cpp b/src/ship/ShipViewController.cpp index 0a46c3f4d35..5ebb07970c8 100644 --- a/src/ship/ShipViewController.cpp +++ b/src/ship/ShipViewController.cpp @@ -273,7 +273,7 @@ void ShipViewController::Update() Pi::input->GetMouseMotion(mouseMotion); // external camera mouselook - const int mouseButton = (Pi::input->IsMiddleMouseButton() ? SDL_BUTTON_LEFT : SDL_BUTTON_MIDDLE); + const int mouseButton = (Pi::input->EmulateMiddleMouseButton() ? SDL_BUTTON_LEFT : SDL_BUTTON_MIDDLE); bool mouse_down = Pi::input->MouseButtonState(mouseButton); if (mouse_down && !headtracker_input_priority) { if (!m_mouseActive) { From efc26d823a36d01945371fb1343960d6378d9359 Mon Sep 17 00:00:00 2001 From: Oskar Wallgren Date: Fri, 16 Aug 2024 20:50:01 +0200 Subject: [PATCH 3/7] fixup --- src/lua/LuaInput.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lua/LuaInput.cpp b/src/lua/LuaInput.cpp index 034a1477033..3850f0b23c9 100644 --- a/src/lua/LuaInput.cpp +++ b/src/lua/LuaInput.cpp @@ -893,7 +893,7 @@ static int l_input_set_mouse_y_inverted(lua_State *l) static int l_input_emulate_middle_mouse_button(lua_State *l) { - lua_pushboolean(l, Pi::input->IsMiddleMouseButton()); + lua_pushboolean(l, Pi::input->EmulateMiddleMouseButton()); return 1; } From 180cef017299fef661ec8e202761dd493af44645 Mon Sep 17 00:00:00 2001 From: Michael Werle Date: Fri, 22 Nov 2024 12:28:41 +0900 Subject: [PATCH 4/7] ui(spin): unify mouse rotation in map views --- src/Input.cpp | 6 ++++++ src/Input.h | 5 +++++ src/SectorMap.cpp | 3 +-- src/SystemView.cpp | 5 ++--- 4 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/Input.cpp b/src/Input.cpp index 35399d5eff6..9c5c4a79975 100644 --- a/src/Input.cpp +++ b/src/Input.cpp @@ -857,6 +857,12 @@ void Manager::DispatchEvents() */ +bool Manager::IsMouseRotatePressed() +{ + return MouseButtonState(SDL_BUTTON_MIDDLE) || + ((keyModState & KMOD_LCTRL) && MouseButtonState(SDL_BUTTON_LEFT)); +} + void Manager::SetCapturingMouse(bool grabbed) { // early-out to avoid changing (possibly) expensive WM state diff --git a/src/Input.h b/src/Input.h index a647135943e..bd84d60d577 100644 --- a/src/Input.h +++ b/src/Input.h @@ -209,6 +209,11 @@ class Input::Manager { int GetMouseWheel() { return mouseWheel; } + // Here for unified UI experience. + // Returns true if the mouse button(s)/modifier(s) required to enable + // rotation are currently pressed. + bool IsMouseRotatePressed(); + // Capturing the mouse hides the cursor, puts the mouse into relative mode, // and passes all mouse inputs to the input system, regardless of whether // ImGui is using them or not. diff --git a/src/SectorMap.cpp b/src/SectorMap.cpp index c382aad5aa6..7b5b499b3e7 100644 --- a/src/SectorMap.cpp +++ b/src/SectorMap.cpp @@ -1151,8 +1151,7 @@ void SectorMap::Update(float frameTime) if (InputBindings.mapViewPitch->IsActive()) m_rotXMovingTo += 0.5f * moveSpeed * InputBindings.mapViewPitch->GetValue(); // to capture mouse when button was pressed and release when released - const int mouseButton = (input->EmulateMiddleMouseButton() ? SDL_BUTTON_LEFT : SDL_BUTTON_MIDDLE); - if (input->MouseButtonState(mouseButton) != m_rotateWithMouseButton) { + if (input->IsMouseRotatePressed() != m_rotateWithMouseButton) { m_rotateWithMouseButton = !m_rotateWithMouseButton; input->SetCapturingMouse(m_rotateWithMouseButton); } diff --git a/src/SystemView.cpp b/src/SystemView.cpp index 0d6eb2fd9c9..b72174bc9fd 100644 --- a/src/SystemView.cpp +++ b/src/SystemView.cpp @@ -843,13 +843,12 @@ void SystemMapViewport::HandleInput(float ft) Input::Manager *inputMgr = m_app->GetInput(); // to capture mouse when button was pressed and release when released - const int mouseButton = (inputMgr->EmulateMiddleMouseButton() ? SDL_BUTTON_LEFT : SDL_BUTTON_MIDDLE); - if (inputMgr->MouseButtonState(mouseButton) != m_rotateWithMouseButton) { + if (inputMgr->IsMouseRotatePressed() != m_rotateWithMouseButton) { m_rotateWithMouseButton = !m_rotateWithMouseButton; inputMgr->SetCapturingMouse(m_rotateWithMouseButton); } - float speedMod = inputMgr->KeyState(SDLK_LSHIFT) ? 10.f : (inputMgr->KeyState(SDLK_LCTRL) ? 0.1f : 1.f); + float speedMod = inputMgr->KeyState(SDLK_LSHIFT) ? 10.f : (inputMgr->KeyState(SDLK_LALT) ? 0.1f : 1.f); if (m_rotateWithMouseButton || m_rotateView) { int motion[2]; From a89f28044987f298f1d094286c2405f1dced7b5b Mon Sep 17 00:00:00 2001 From: Michael Werle Date: Fri, 22 Nov 2024 12:42:57 +0900 Subject: [PATCH 5/7] ui(spin): add same spin handling to ModelSpinner Since the ModelSpinner is using ImGUi, it appears that it blocks the underlying "Input::Manager" input system, so we have to duplicate the "IsMouseRotatePressed()" function here using ImGui inputs instead. TODO: Figure out how we can unify these to avoid duplicating this. --- src/pigui/ModelSpinner.cpp | 10 ++++++++-- src/pigui/ModelSpinner.h | 3 +++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/pigui/ModelSpinner.cpp b/src/pigui/ModelSpinner.cpp index 953b7c2c050..c15378bcfee 100644 --- a/src/pigui/ModelSpinner.cpp +++ b/src/pigui/ModelSpinner.cpp @@ -19,6 +19,7 @@ using namespace PiGui; ModelSpinner::ModelSpinner() : m_spinning(true), m_middleMouseButton(false), + m_rotateWithMouseButton(false), m_pauseTime(.0f), m_rot(vector2f(DEG2RAD(-15.0), DEG2RAD(120.0))), m_zoom(1.0f), @@ -138,8 +139,13 @@ void ModelSpinner::DrawPiGui() const ImGuiIO &io = ImGui::GetIO(); bool hovered = ImGui::IsItemHovered(); - const int mouseButton = (Pi::input->EmulateMiddleMouseButton() ? 0 : 2); // 0 : 2 = ImGui mouse button Left and Middle. - if (hovered && ImGui::IsMouseDown(mouseButton)) { + // TODO: This should be unified with Input::Manager::IsMouseRotatePressed() + bool isMouseRotatePressed = ImGui::IsMouseDown(2) || ImGui::IsKeyDown(ImGuiKey_LeftCtrl) && ImGui::IsMouseDown(0); + if (hovered && isMouseRotatePressed != m_rotateWithMouseButton) { + m_rotateWithMouseButton = !m_rotateWithMouseButton; + Pi::input->SetCapturingMouse(m_rotateWithMouseButton); + } + if (m_rotateWithMouseButton) { m_rot.x -= 0.005 * io.MouseDelta.y; m_rot.y -= 0.005 * io.MouseDelta.x; m_pauseTime = 1.0f; diff --git a/src/pigui/ModelSpinner.h b/src/pigui/ModelSpinner.h index 875b507a10d..7b2ec2af33b 100644 --- a/src/pigui/ModelSpinner.h +++ b/src/pigui/ModelSpinner.h @@ -74,6 +74,9 @@ namespace PiGui { // Is there a middle mouse button? bool m_middleMouseButton; + // Is the user rotating the model? + bool m_rotateWithMouseButton; + // After the user manually rotates the model, hold that orientation for // a second to let them look at it. Assumes Update() is called every // frame while visible. From 15366b59f84b2e6116cd80a28f9fc2b6927dce3a Mon Sep 17 00:00:00 2001 From: Michael Werle Date: Fri, 22 Nov 2024 12:59:52 +0900 Subject: [PATCH 6/7] ui(spin): fix deselecting objects in SystemView With the new spinning code using Ctrl+LMB as an alternative way to spin the view, a selected object in the SystemView was deselected whenever the user tries to spin the view. By also checking against the Ctrl key when selecting/deselecting objects in the SystemView this issue is resolved. TODO: unify the modifier key with Input::Manager::IsMouseRotatePressed() --- data/pigui/modules/system-view-ui.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/data/pigui/modules/system-view-ui.lua b/data/pigui/modules/system-view-ui.lua index b4d42127693..1bb72dd7568 100644 --- a/data/pigui/modules/system-view-ui.lua +++ b/data/pigui/modules/system-view-ui.lua @@ -707,7 +707,9 @@ local function displayOnScreenObjects() -- click once: select or deselect a body -- double click: zoom to body or reset viewpoint - local clicked = not ui.isAnyWindowHovered() and (ui.isMouseClicked(0) or ui.isMouseDoubleClicked(0)) + local clicked = not ui.isAnyWindowHovered() + and not ui.ctrlHeld() + and (ui.isMouseClicked(0) or ui.isMouseDoubleClicked(0)) if clicked then if hoveredObject then selectedObject = hoveredObject.ref From 265265610b6bf9d458ea8ef90d10f7a75853d909 Mon Sep 17 00:00:00 2001 From: Michael Werle Date: Fri, 22 Nov 2024 13:52:30 +0900 Subject: [PATCH 7/7] ui(spin): fix WorldView spinning and weapon discharge Mouse rotation is restricted to only when the relevant bindings are active; that is, either Ctrl+LMB, or MMB. If another mouse-button is pressed at the same time, it no longer counts as activating rotation. It still allows for additional modifiers to be pressed, which is required when used in conjunction with the rotation speed modifiers. This prevents the issue from having the ShipView rotating while also firing the laser. ALSO: unify rotation speed modifiers (in all but the Model Spinner). ALSO: use the Left-Alt key instead of the Right-Shift key for the secondary speed modifier; using both Shift-keys is a bit cumbersome. --- src/Input.cpp | 19 ++++++++++++++++--- src/Input.h | 4 ++++ src/SectorMap.cpp | 5 +++-- src/SystemView.cpp | 2 +- src/ship/ShipViewController.cpp | 8 ++++---- 5 files changed, 28 insertions(+), 10 deletions(-) diff --git a/src/Input.cpp b/src/Input.cpp index 9c5c4a79975..c0ea649bf0c 100644 --- a/src/Input.cpp +++ b/src/Input.cpp @@ -857,10 +857,16 @@ void Manager::DispatchEvents() */ +// Mouse rotation is enabled if: +// MMB is pressed, or Ctrl+LMB is pressed, AND no other mouse buttons are pressed bool Manager::IsMouseRotatePressed() { - return MouseButtonState(SDL_BUTTON_MIDDLE) || - ((keyModState & KMOD_LCTRL) && MouseButtonState(SDL_BUTTON_LEFT)); + int state = keyModState & KMOD_LCTRL ? 0x01 : 0x00; + state |= MouseButtonState(SDL_BUTTON_LEFT) ? 0x02 : 0x00; + state |= MouseButtonState(SDL_BUTTON_MIDDLE) ? 0x04 : 0x00; + state |= MouseButtonState(SDL_BUTTON_RIGHT) ? 0x08 : 0x00; + + return state == 0x03 || state == 0x04; } void Manager::SetCapturingMouse(bool grabbed) @@ -884,6 +890,13 @@ float Manager::GetMoveSpeedShiftModifier() { // Suggestion: make x1000 speed on pressing both keys? if (KeyState(SDLK_LSHIFT)) return 100.f; - if (KeyState(SDLK_RSHIFT)) return 10.f; + if (KeyState(SDLK_LALT)) return 10.f; + return 1; +} + +float Manager::GetRotateSpeedShiftModifier() +{ + if (KeyState(SDLK_LSHIFT)) return 10.f; + if (KeyState(SDLK_LALT)) return 0.1f; return 1; } diff --git a/src/Input.h b/src/Input.h index bd84d60d577..651cc87517d 100644 --- a/src/Input.h +++ b/src/Input.h @@ -229,6 +229,10 @@ class Input::Manager { // This is a default value only, centralized here to promote uniform user expericience. float GetMoveSpeedShiftModifier(); + // Get the default speed modifier to apply to rotation depending on the "shift" keys. + // This is a default value only, centralized here to promote uniform user expericience. + float GetRotateSpeedShiftModifier(); + sigc::signal onKeyPress; sigc::signal onKeyRelease; sigc::signal onMouseButtonUp; diff --git a/src/SectorMap.cpp b/src/SectorMap.cpp index 7b5b499b3e7..ccffa243150 100644 --- a/src/SectorMap.cpp +++ b/src/SectorMap.cpp @@ -1159,8 +1159,9 @@ void SectorMap::Update(float frameTime) if (m_rotateWithMouseButton || m_rotateView) { int motion[2]; input->GetMouseMotion(motion); - m_rotXMovingTo += 0.2f * float(motion[1]); - m_rotZMovingTo += 0.2f * float(motion[0]); + float speed = 0.2f * input->GetRotateSpeedShiftModifier(); + m_rotXMovingTo += speed * float(motion[1]); + m_rotZMovingTo += speed * float(motion[0]); } else if (m_zoomView) { input->SetCapturingMouse(true); int motion[2]; diff --git a/src/SystemView.cpp b/src/SystemView.cpp index b72174bc9fd..48d06500657 100644 --- a/src/SystemView.cpp +++ b/src/SystemView.cpp @@ -848,7 +848,7 @@ void SystemMapViewport::HandleInput(float ft) inputMgr->SetCapturingMouse(m_rotateWithMouseButton); } - float speedMod = inputMgr->KeyState(SDLK_LSHIFT) ? 10.f : (inputMgr->KeyState(SDLK_LALT) ? 0.1f : 1.f); + float speedMod = inputMgr->GetRotateSpeedShiftModifier(); if (m_rotateWithMouseButton || m_rotateView) { int motion[2]; diff --git a/src/ship/ShipViewController.cpp b/src/ship/ShipViewController.cpp index 5ebb07970c8..96faf56daee 100644 --- a/src/ship/ShipViewController.cpp +++ b/src/ship/ShipViewController.cpp @@ -273,8 +273,7 @@ void ShipViewController::Update() Pi::input->GetMouseMotion(mouseMotion); // external camera mouselook - const int mouseButton = (Pi::input->EmulateMiddleMouseButton() ? SDL_BUTTON_LEFT : SDL_BUTTON_MIDDLE); - bool mouse_down = Pi::input->MouseButtonState(mouseButton); + bool mouse_down = Pi::input->IsMouseRotatePressed(); if (mouse_down && !headtracker_input_priority) { if (!m_mouseActive) { m_mouseActive = true; @@ -283,8 +282,9 @@ void ShipViewController::Update() // invert the mouse input to convert between screen coordinates and // right-hand coordinate system rotation. - cam->YawCamera(float(-mouseMotion[0]) * MOUSELOOK_SPEED / M_PI); - cam->PitchCamera(float(-mouseMotion[1]) * MOUSELOOK_SPEED / M_PI); + float speed = MOUSELOOK_SPEED * Pi::input->GetRotateSpeedShiftModifier(); + cam->YawCamera(float(-mouseMotion[0]) * speed / M_PI); + cam->PitchCamera(float(-mouseMotion[1]) * speed / M_PI); } if (!mouse_down && m_mouseActive) {