Enable mouse toggle buttons

master
german77 2021-03-06 13:27:02 +07:00
parent 4bcc5bacff
commit 41e94b7b99
5 changed files with 65 additions and 11 deletions

@ -19,16 +19,18 @@ public:
bool GetStatus() const override { bool GetStatus() const override {
if (toggle) { if (toggle) {
return toggled_status.load(); return toggled_status.load(std::memory_order_relaxed);
} }
return status.load(); return status.load();
} }
void ToggleButton() { void ToggleButton() {
if (!lock) { if (lock) {
lock = true; return;
toggled_status.store(!toggled_status.load());
} }
lock = true;
const bool old_toggle_status = toggled_status.load();
toggled_status.store(!old_toggle_status);
} }
void UnlockButton() { void UnlockButton() {
@ -41,7 +43,7 @@ private:
std::shared_ptr<KeyButtonList> key_button_list; std::shared_ptr<KeyButtonList> key_button_list;
std::atomic<bool> status{false}; std::atomic<bool> status{false};
std::atomic<bool> toggled_status{false}; std::atomic<bool> toggled_status{false};
bool lock = {}; bool lock{false};
const bool toggle; const bool toggle;
}; };

@ -157,6 +157,42 @@ void Mouse::EndConfiguration() {
configuring = false; configuring = false;
} }
bool Mouse::ToggleButton(std::size_t button_) {
if (button_ >= mouse_info.size()) {
return false;
}
const auto button = 1U << button_;
const bool button_state = (toggle_buttons & button) != 0;
const bool button_lock = (lock_buttons & button) != 0;
if (button_lock) {
return button_state;
}
lock_buttons |= static_cast<u16>(button);
if (button_state) {
toggle_buttons &= static_cast<u16>(0xFF - button);
} else {
toggle_buttons |= static_cast<u16>(button);
}
return !button_state;
}
bool Mouse::UnlockButton(std::size_t button_) {
if (button_ >= mouse_info.size()) {
return false;
}
const auto button = 1U << button_;
const bool button_state = (toggle_buttons & button) != 0;
lock_buttons &= static_cast<u16>(0xFF - button);
return button_state;
}
Common::SPSCQueue<MouseStatus>& Mouse::GetMouseQueue() { Common::SPSCQueue<MouseStatus>& Mouse::GetMouseQueue() {
return mouse_queue; return mouse_queue;
} }

@ -67,6 +67,9 @@ public:
*/ */
void ReleaseButton(int button_); void ReleaseButton(int button_);
[[nodiscard]] bool ToggleButton(std::size_t button_);
[[nodiscard]] bool UnlockButton(std::size_t button_);
[[nodiscard]] Common::SPSCQueue<MouseStatus>& GetMouseQueue(); [[nodiscard]] Common::SPSCQueue<MouseStatus>& GetMouseQueue();
[[nodiscard]] const Common::SPSCQueue<MouseStatus>& GetMouseQueue() const; [[nodiscard]] const Common::SPSCQueue<MouseStatus>& GetMouseQueue() const;
@ -92,6 +95,8 @@ private:
}; };
u16 buttons{}; u16 buttons{};
u16 toggle_buttons{};
u16 lock_buttons{};
std::thread update_thread; std::thread update_thread;
MouseButton last_button{MouseButton::Undefined}; MouseButton last_button{MouseButton::Undefined};
std::array<MouseInfo, 5> mouse_info; std::array<MouseInfo, 5> mouse_info;

@ -14,16 +14,25 @@ namespace InputCommon {
class MouseButton final : public Input::ButtonDevice { class MouseButton final : public Input::ButtonDevice {
public: public:
explicit MouseButton(u32 button_, const MouseInput::Mouse* mouse_input_) explicit MouseButton(u32 button_, bool toggle_, MouseInput::Mouse* mouse_input_)
: button(button_), mouse_input(mouse_input_) {} : button(button_), toggle(toggle_), mouse_input(mouse_input_) {}
bool GetStatus() const override { bool GetStatus() const override {
return mouse_input->GetMouseState(button).pressed; const bool button_state = mouse_input->GetMouseState(button).pressed;
if (!toggle) {
return button_state;
}
if (button_state) {
return mouse_input->ToggleButton(button);
}
return mouse_input->UnlockButton(button);
} }
private: private:
const u32 button; const u32 button;
const MouseInput::Mouse* mouse_input; const bool toggle;
MouseInput::Mouse* mouse_input;
}; };
MouseButtonFactory::MouseButtonFactory(std::shared_ptr<MouseInput::Mouse> mouse_input_) MouseButtonFactory::MouseButtonFactory(std::shared_ptr<MouseInput::Mouse> mouse_input_)
@ -32,8 +41,9 @@ MouseButtonFactory::MouseButtonFactory(std::shared_ptr<MouseInput::Mouse> mouse_
std::unique_ptr<Input::ButtonDevice> MouseButtonFactory::Create( std::unique_ptr<Input::ButtonDevice> MouseButtonFactory::Create(
const Common::ParamPackage& params) { const Common::ParamPackage& params) {
const auto button_id = params.Get("button", 0); const auto button_id = params.Get("button", 0);
const auto toggle = params.Get("toggle", false);
return std::make_unique<MouseButton>(button_id, mouse_input.get()); return std::make_unique<MouseButton>(button_id, toggle, mouse_input.get());
} }
Common::ParamPackage MouseButtonFactory::GetNextInput() const { Common::ParamPackage MouseButtonFactory::GetNextInput() const {

@ -158,7 +158,8 @@ QString ButtonToText(const Common::ParamPackage& param) {
if (param.Get("engine", "") == "mouse") { if (param.Get("engine", "") == "mouse") {
if (param.Has("button")) { if (param.Has("button")) {
const QString button_str = QString::number(int(param.Get("button", 0))); const QString button_str = QString::number(int(param.Get("button", 0)));
return QObject::tr("Click %1").arg(button_str); const QString toggle = QString::fromStdString(param.Get("toggle", false) ? "~" : "");
return QObject::tr("%1Click %2").arg(toggle, button_str);
} }
return GetKeyName(param.Get("code", 0)); return GetKeyName(param.Get("code", 0));
} }