#pragma once #include "InputDevice.hpp" #include "../Base/Logger.hpp" namespace openVulkanoCpp { class IWindow; namespace Input { class InputDeviceMouse : public InputDevice { float axes[InputKey::Mouse::Axis::AXIS_LAST + 2] = { 0 }; uint8_t pressedButtons = 0, lastPressedButtons = 0; double mousePosX = 0, mousePosY = 0; IWindow* lastWindow = nullptr; protected: InputDeviceMouse() = default; void Init(const int index, const std::string& name) { InputDevice::Init(InputDeviceType::MOUSE, index, name); ClearAxes(); pressedButtons = 0; lastPressedButtons = 0; mousePosX = 0; mousePosY = 0; lastWindow = nullptr; } void UpdateButtons(uint8_t newPressedButtons) { lastPressedButtons = pressedButtons; pressedButtons = newPressedButtons; if (lastPressedButtons != pressedButtons) Logger::INPUT->info("Mouse button state changed {0:08b}", pressedButtons); } void UpdatePosition(double posX, double posY) { axes[InputKey::Mouse::AXIS_X] = static_cast(posX - mousePosX); axes[InputKey::Mouse::AXIS_Y] = static_cast(posY - mousePosY); mousePosX = posX; mousePosY = posY; Logger::INPUT->info("Mouse moved posX: {0} posY: {1}, relativeX: {2}, relativeY: {3}", posX, posY, axes[InputKey::Mouse::AXIS_X], axes[InputKey::Mouse::AXIS_Y]); } void UpdateWheel(float wheelX, float wheelY) { axes[InputKey::Mouse::AXIS_WHEEL_X] = wheelX; axes[InputKey::Mouse::AXIS_WHEEL_Y] = wheelY; Logger::INPUT->info("Mouse scrolled x: {0} y: {1}", wheelX, wheelY); } void UpdateActiveWindow(IWindow* window) { axes[InputKey::Mouse::AXIS_X] = 0; axes[InputKey::Mouse::AXIS_Y] = 0; lastWindow = window; } void ClearAxes() { for (float& axis : axes) { axis = 0; } } private: bool GetLastButton(InputKey::Mouse::Button button) const { return lastPressedButtons & (1 << button); } protected: float ReadAxis(int16_t key) const override final { return GetAxis(static_cast(key)); } bool ReadButton(int16_t key) const override final { return GetButton(static_cast(key)); } bool ReadButtonUp(int16_t key) const override final { return GetButtonUp(static_cast(key)); } bool ReadButtonDown(int16_t key) const override final { return GetButtonDown(static_cast(key)); } public: bool GetButton(const InputKey::Mouse::Button button) const { return pressedButtons & (1 << button); } bool GetButtonUp(const InputKey::Mouse::Button button) const { return !GetButton(button) && GetLastButton(button); } bool GetButtonDown(const InputKey::Mouse::Button button) const { return GetButton(button) && !GetLastButton(button); } float GetAxis(const InputKey::Mouse::Axis axis) const { return axes[axis]; } float GetWheel() const { return GetAxis(InputKey::Mouse::Axis::AXIS_WHEEL_Y); } float GetWheelX() const { return GetAxis(InputKey::Mouse::Axis::AXIS_WHEEL_X); } float GetWheelY() const { return GetAxis(InputKey::Mouse::Axis::AXIS_WHEEL_Y); } glm::vec2 GetMousePosition() const { return { mousePosX, mousePosY }; } void GetMousePosition(double& posX, double& posY) const { posX = mousePosX; posY = mousePosY; } glm::vec2 GetMousePosition(const IWindow* window) const { if (window == lastWindow) { return { mousePosX, mousePosY }; } return { std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN() }; } void GetMousePosition(const IWindow* window, double& posX, double& posY) const { if (window == lastWindow) { posX = mousePosX; posY = mousePosY; } else { posX = std::numeric_limits::quiet_NaN(); posY = std::numeric_limits::quiet_NaN(); } } IWindow* GetActiveWindow() const { return lastWindow; } bool IsInWindow(const IWindow* window) const { return window == lastWindow; } }; } }