diff --git a/data/lang/ui-core/en.json b/data/lang/ui-core/en.json index 2750a328c2e..1ba7220ca76 100644 --- a/data/lang/ui-core/en.json +++ b/data/lang/ui-core/en.json @@ -1163,6 +1163,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 809c840134c..39c6dd8b1b2 100644 --- a/data/pigui/modules/settings-window.lua +++ b/data/pigui/modules/settings-window.lua @@ -578,6 +578,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 @@ -585,6 +586,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 82ba812f3dc..24f7ad967f5 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 60fc61fbda3..af30275cc5b 100644 --- a/src/Input.cpp +++ b/src/Input.cpp @@ -248,10 +248,12 @@ 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) { 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); } @@ -500,6 +502,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 e3c3f45c635..ee4fa2ffb12 100644 --- a/src/Input.h +++ b/src/Input.h @@ -194,6 +194,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; } @@ -245,6 +248,7 @@ class Input::Manager { bool joystickEnabled; bool mouseYInvert; + bool noMiddleMouseButton; std::map bindingPages; std::map actionBindings; diff --git a/src/SectorView.cpp b/src/SectorView.cpp index 26984a5487a..01ae336b446 100644 --- a/src/SectorView.cpp +++ b/src/SectorView.cpp @@ -1555,7 +1555,8 @@ void SectorView::Update() if (InputBindings.mapViewPitch->IsActive()) m_rotXMovingTo += 0.5f * moveSpeed * InputBindings.mapViewPitch->GetValue(); // to capture mouse when button was pressed and release when released - if (Pi::input->MouseButtonState(SDL_BUTTON_MIDDLE) != m_rotateWithMouseButton) { + const int mouseButton = (Pi::input->IsMiddleMouseButton() ? SDL_BUTTON_LEFT : SDL_BUTTON_MIDDLE); + if (Pi::input->MouseButtonState(mouseButton) != m_rotateWithMouseButton) { m_rotateWithMouseButton = !m_rotateWithMouseButton; Pi::input->SetCapturingMouse(m_rotateWithMouseButton); } diff --git a/src/SystemView.cpp b/src/SystemView.cpp index 4ac97a17d7a..27bbd9e84a6 100644 --- a/src/SystemView.cpp +++ b/src/SystemView.cpp @@ -737,7 +737,8 @@ void SystemView::Update() } // to capture mouse when button was pressed and release when released - if (Pi::input->MouseButtonState(SDL_BUTTON_MIDDLE) != m_rotateWithMouseButton) { + const int mouseButton = (Pi::input->IsMiddleMouseButton() ? SDL_BUTTON_LEFT : SDL_BUTTON_MIDDLE); + if (Pi::input->MouseButtonState(mouseButton) != m_rotateWithMouseButton) { m_rotateWithMouseButton = !m_rotateWithMouseButton; Pi::input->SetCapturingMouse(m_rotateWithMouseButton); } diff --git a/src/lua/LuaInput.cpp b/src/lua/LuaInput.cpp index 25beac5d2c3..2e1647457c8 100644 --- a/src/lua/LuaInput.cpp +++ b/src/lua/LuaInput.cpp @@ -565,6 +565,23 @@ 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()); @@ -716,6 +733,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 b2e725dc302..67d651e732d 100644 --- a/src/pigui/ModelSpinner.cpp +++ b/src/pigui/ModelSpinner.cpp @@ -8,6 +8,7 @@ #include "graphics/Graphics.h" #include "graphics/RenderTarget.h" #include "graphics/Renderer.h" +#include "Input.h" #include "scenegraph/MatrixTransform.h" #include @@ -16,6 +17,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), @@ -118,7 +120,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 c3df02254dc..ed82ca3c4a1 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 37e08bd02ab..b791aae7acd 100644 --- a/src/ship/ShipViewController.cpp +++ b/src/ship/ShipViewController.cpp @@ -272,7 +272,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;