Files
Juliet/Juliet/src/Core/HAL/Event/Mouse.cpp
2025-01-08 19:55:38 -05:00

145 lines
4.4 KiB
C++

#include <pch.h>
#include <Core/Common/EnumUtils.h>
#include <Core/HAL/Display/Window.h>
#include <Core/HAL/Event/Mouse_Private.h>
#include <Core/HAL/Event/SystemEvent.h>
#include <Core/HAL/Mouse/Mouse.h>
namespace Juliet
{
namespace
{
Mouse MouseState;
void ConstraintMousePositionToWindow(Mouse& mouseState, Window* window, float& x, float& y)
{
float x_min = 0.f, x_max = (float)(window->Width - 1);
float y_min = 0.f, y_max = (float)(window->Height - 1);
if (x >= (x_max + 1))
{
x = std::max(x_max, mouseState.X_Previous);
}
x = std::max(x, x_min);
if (y >= (y_max + 1))
{
y = std::max(y_max, mouseState.Y_Previous);
}
y = std::max(y, y_min);
}
void SendMouseMotion_Internal(uint64 timestamp, Window* window, MouseID mouseID, float x, float y)
{
auto& mouseState = GetMouseState();
float xDisplacement = 0.0f;
float yDisplacement = 0.0f;
ConstraintMousePositionToWindow(mouseState, window, x, y);
if (mouseState.HasPosition)
{
xDisplacement = x - mouseState.X_Previous;
yDisplacement = y - mouseState.Y_Previous;
}
if (mouseState.HasPosition && xDisplacement == 0.0f && yDisplacement == 0.0f)
{
// Skip it because state didnt change
return;
}
mouseState.X = x;
mouseState.Y = y;
mouseState.HasPosition = true;
mouseState.X_Previous = x;
mouseState.Y_Previous = y;
SystemEvent evt;
evt.Type = EventType::Mouse_Move;
evt.Timestamp = timestamp;
evt.Data.MouseMovement.WindowID = window->ID;
evt.Data.MouseMovement.AssociatedMouseID = mouseID;
evt.Data.MouseMovement.X = x;
evt.Data.MouseMovement.Y = y;
evt.Data.MouseMovement.X_Displacement = xDisplacement;
evt.Data.MouseMovement.Y_Displacement = yDisplacement;
evt.Data.MouseMovement.ButtonState = mouseState.ButtonState;
AddEvent(evt);
}
} // namespace
constexpr MouseID kGlobalMouseID = 0;
Mouse& GetMouseState()
{
return MouseState;
}
void SendMouseMotion(uint64 timestamp, NonNullPtr<Window> window, MouseID ID, float x, float y)
{
// TODO : Update Mouse focus and send Mouse Enter / Mouse Leave event
SendMouseMotion_Internal(timestamp, window, ID, x, y);
}
void SendMouseButton(uint64 timestamp, NonNullPtr<Window> window, MouseID mouseID, MouseButton button, bool pressed)
{
Mouse& mouseState = GetMouseState();
MouseButton flags = mouseState.ButtonState;
auto type = EventType::None;
if (pressed)
{
type = EventType::Mouse_ButtonPressed;
flags |= button;
}
else
{
type = EventType::Mouse_ButtonReleased;
flags = flags & ~button;
}
if (flags == mouseState.ButtonState)
{
return;
}
mouseState.ButtonState = flags;
// TODO : Send Event!
SystemEvent evt;
evt.Timestamp = timestamp;
evt.Type = type;
evt.Data.MouseButton.AssociatedMouseID = mouseID;
evt.Data.MouseButton.WindowID = window->ID;
evt.Data.MouseButton.ButtonState = button;
evt.Data.MouseButton.X = mouseState.X;
evt.Data.MouseButton.Y = mouseState.Y;
evt.Data.MouseButton.IsPressed = pressed;
AddEvent(evt);
}
bool IsMouseButtonDown(MouseButton button)
{
auto& mouseState = GetMouseState();
return (mouseState.ButtonState & button) != MouseButton::None;
}
MousePosition GetMousePosition()
{
auto& mouseState = GetMouseState();
return { .X = mouseState.X, .Y = mouseState.Y };
}
MouseButton GetMouseButtonState()
{
const auto& mouseState = GetMouseState();
return mouseState.ButtonState;
}
} // namespace Juliet