// Copyright (c) Wojciech Figat. All rights reserved. #pragma once #include "InputDevice.h" /// /// Represents a single hardware mouse device. Used by the Input to report raw mouse input events. /// /// /// The mouse device position is in screen-space (not game client window space). /// API_CLASS(NoSpawn) class FLAXENGINE_API Mouse : public InputDevice { DECLARE_SCRIPTING_TYPE_NO_SPAWN(Mouse); public: /// /// The mouse state. /// struct State { /// /// The mouse position. /// Float2 MousePosition; /// /// The mouse wheel delta. /// float MouseWheelDelta; /// /// The mouse buttons state. /// bool MouseButtons[(int32)MouseButton::MAX]; /// /// Clears the state. /// void Clear() { Platform::MemoryClear(this, sizeof(State)); } }; protected: State _state; State _prevState; bool _relativeMode; explicit Mouse() : InputDevice(SpawnParams(Guid::New(), TypeInitializer), TEXT("Mouse")) { _state.Clear(); _prevState.Clear(); _relativeMode = false; } public: /// /// Gets the position of the mouse in the screen-space coordinates. /// API_PROPERTY() FORCE_INLINE Float2 GetPosition() const { return _state.MousePosition; } /// /// Checks if any mouse button is currently pressed. /// API_PROPERTY() bool IsAnyButtonDown() const; /// /// Gets the delta position of the mouse in the screen-space coordinates. /// API_PROPERTY() FORCE_INLINE Float2 GetPositionDelta() const { return _state.MousePosition - _prevState.MousePosition; } /// /// Gets the mouse wheel change during the last frame. /// API_PROPERTY() FORCE_INLINE float GetScrollDelta() const { return _state.MouseWheelDelta; } /// /// Gets the mouse button state (true if being pressed during the current frame). /// /// Mouse button to check /// True if user holds down the button, otherwise false. API_FUNCTION() FORCE_INLINE bool GetButton(MouseButton button) const { return _state.MouseButtons[static_cast(button)]; } /// /// Gets the mouse button down state (true if was pressed during the current frame). /// /// Mouse button to check /// True if user starts pressing down the button, otherwise false. API_FUNCTION() FORCE_INLINE bool GetButtonDown(MouseButton button) const { return _state.MouseButtons[static_cast(button)] && !_prevState.MouseButtons[static_cast(button)]; } /// /// Gets the mouse button up state (true if was released during the current frame). /// /// Mouse button to check /// True if user releases the button, otherwise false. API_FUNCTION() FORCE_INLINE bool GetButtonUp(MouseButton button) const { return !_state.MouseButtons[static_cast(button)] && _prevState.MouseButtons[static_cast(button)]; } /// /// Gets the current state of mouse relative mode. /// /// The window to check against, or null to check for any window. /// True if mouse is in relative mode, otherwise false. API_FUNCTION() virtual bool IsRelative(Window* window = nullptr) const { return _relativeMode; } public: /// /// Sets the mouse position. /// /// The new position. virtual void SetMousePosition(const Float2& newPosition) = 0; /// /// Sets the mouse relative mode state. While enabled, the mouse movement tracking becomes more accurate. /// The cursor will be hidden while in relative mode. /// /// The new relative mode state. /// The window. virtual void SetRelativeMode(bool relativeMode, Window* window) { _relativeMode = relativeMode; } /// /// Called when mouse cursor gets moved by the application. Invalidates the previous cached mouse position to prevent mouse jitter when locking the cursor programmatically. /// /// The new mouse position. void OnMouseMoved(const Float2& newPosition); /// /// Called when mouse button goes down. /// /// The mouse position. /// The button. /// The target window to receive this event, otherwise input system will pick the window automatically. void OnMouseDown(const Float2& position, const MouseButton button, Window* target = nullptr); /// /// Called when mouse button goes up. /// /// The mouse position. /// The button. /// The target window to receive this event, otherwise input system will pick the window automatically. void OnMouseUp(const Float2& position, const MouseButton button, Window* target = nullptr); /// /// Called when mouse double clicks. /// /// The mouse position. /// The button. /// The target window to receive this event, otherwise input system will pick the window automatically. void OnMouseDoubleClick(const Float2& position, const MouseButton button, Window* target = nullptr); /// /// Called when mouse moves. /// /// The mouse position. /// The target window to receive this event, otherwise input system will pick the window automatically. void OnMouseMove(const Float2& position, Window* target = nullptr); /// /// Called when mouse moves in relative mode. /// /// The mouse position change. /// The target window to receive this event, otherwise input system will pick the window automatically. void OnMouseMoveRelative(const Float2& positionRelative, Window* target = nullptr); /// /// Called when mouse leaves the input source area. /// /// The target window to receive this event, otherwise input system will pick the window automatically. void OnMouseLeave(Window* target = nullptr); /// /// Called when mouse wheel moves. /// /// The mouse position. /// The normalized delta (range [-1;1]). /// The target window to receive this event, otherwise input system will pick the window automatically. void OnMouseWheel(const Float2& position, float delta, Window* target = nullptr); public: // [InputDevice] void ResetState() override; bool Update(EventQueue& queue) final override; };