Enable mouse toggle buttons
This commit is contained in:
		@@ -19,16 +19,18 @@ public:
 | 
			
		||||
 | 
			
		||||
    bool GetStatus() const override {
 | 
			
		||||
        if (toggle) {
 | 
			
		||||
            return toggled_status.load();
 | 
			
		||||
            return toggled_status.load(std::memory_order_relaxed);
 | 
			
		||||
        }
 | 
			
		||||
        return status.load();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void ToggleButton() {
 | 
			
		||||
        if (!lock) {
 | 
			
		||||
            lock = true;
 | 
			
		||||
            toggled_status.store(!toggled_status.load());
 | 
			
		||||
        if (lock) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        lock = true;
 | 
			
		||||
        const bool old_toggle_status = toggled_status.load();
 | 
			
		||||
        toggled_status.store(!old_toggle_status);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void UnlockButton() {
 | 
			
		||||
@@ -41,7 +43,7 @@ private:
 | 
			
		||||
    std::shared_ptr<KeyButtonList> key_button_list;
 | 
			
		||||
    std::atomic<bool> status{false};
 | 
			
		||||
    std::atomic<bool> toggled_status{false};
 | 
			
		||||
    bool lock = {};
 | 
			
		||||
    bool lock{false};
 | 
			
		||||
    const bool toggle;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -157,6 +157,42 @@ void Mouse::EndConfiguration() {
 | 
			
		||||
    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() {
 | 
			
		||||
    return mouse_queue;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -67,6 +67,9 @@ public:
 | 
			
		||||
     */
 | 
			
		||||
    void ReleaseButton(int button_);
 | 
			
		||||
 | 
			
		||||
    [[nodiscard]] bool ToggleButton(std::size_t button_);
 | 
			
		||||
    [[nodiscard]] bool UnlockButton(std::size_t button_);
 | 
			
		||||
 | 
			
		||||
    [[nodiscard]] Common::SPSCQueue<MouseStatus>& GetMouseQueue();
 | 
			
		||||
    [[nodiscard]] const Common::SPSCQueue<MouseStatus>& GetMouseQueue() const;
 | 
			
		||||
 | 
			
		||||
@@ -92,6 +95,8 @@ private:
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    u16 buttons{};
 | 
			
		||||
    u16 toggle_buttons{};
 | 
			
		||||
    u16 lock_buttons{};
 | 
			
		||||
    std::thread update_thread;
 | 
			
		||||
    MouseButton last_button{MouseButton::Undefined};
 | 
			
		||||
    std::array<MouseInfo, 5> mouse_info;
 | 
			
		||||
 
 | 
			
		||||
@@ -14,16 +14,25 @@ namespace InputCommon {
 | 
			
		||||
 | 
			
		||||
class MouseButton final : public Input::ButtonDevice {
 | 
			
		||||
public:
 | 
			
		||||
    explicit MouseButton(u32 button_, const MouseInput::Mouse* mouse_input_)
 | 
			
		||||
        : button(button_), mouse_input(mouse_input_) {}
 | 
			
		||||
    explicit MouseButton(u32 button_, bool toggle_, MouseInput::Mouse* mouse_input_)
 | 
			
		||||
        : button(button_), toggle(toggle_), mouse_input(mouse_input_) {}
 | 
			
		||||
 | 
			
		||||
    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:
 | 
			
		||||
    const u32 button;
 | 
			
		||||
    const MouseInput::Mouse* mouse_input;
 | 
			
		||||
    const bool toggle;
 | 
			
		||||
    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(
 | 
			
		||||
    const Common::ParamPackage& params) {
 | 
			
		||||
    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 {
 | 
			
		||||
 
 | 
			
		||||
@@ -158,7 +158,8 @@ QString ButtonToText(const Common::ParamPackage& param) {
 | 
			
		||||
    if (param.Get("engine", "") == "mouse") {
 | 
			
		||||
        if (param.Has("button")) {
 | 
			
		||||
            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));
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user