Implement relative mouse mode (raw input) for SDL platform
This commit is contained in:
@@ -93,6 +93,7 @@ Delegate<const Float2&, MouseButton> Input::MouseUp;
|
||||
Delegate<const Float2&, MouseButton> Input::MouseDoubleClick;
|
||||
Delegate<const Float2&, float> Input::MouseWheel;
|
||||
Delegate<const Float2&> Input::MouseMove;
|
||||
Delegate<const Float2&> Input::MouseMoveRelative;
|
||||
Action Input::MouseLeave;
|
||||
Delegate<const Float2&, int32> Input::TouchDown;
|
||||
Delegate<const Float2&, int32> Input::TouchMove;
|
||||
@@ -221,6 +222,14 @@ void Mouse::OnMouseMove(const Float2& position, Window* target)
|
||||
e.MouseData.Position = position;
|
||||
}
|
||||
|
||||
void Mouse::OnMouseMoveRelative(const Float2& positionRelative, Window* target)
|
||||
{
|
||||
Event& e = _queue.AddOne();
|
||||
e.Type = EventType::MouseMoveRelative;
|
||||
e.Target = target;
|
||||
e.MouseMovementData.PositionRelative = positionRelative;
|
||||
}
|
||||
|
||||
void Mouse::OnMouseLeave(Window* target)
|
||||
{
|
||||
Event& e = _queue.AddOne();
|
||||
@@ -286,6 +295,11 @@ bool Mouse::Update(EventQueue& queue)
|
||||
_state.MousePosition = e.MouseData.Position;
|
||||
break;
|
||||
}
|
||||
case EventType::MouseMoveRelative:
|
||||
{
|
||||
_state.MousePosition += e.MouseMovementData.PositionRelative;
|
||||
break;
|
||||
}
|
||||
case EventType::MouseLeave:
|
||||
{
|
||||
break;
|
||||
@@ -710,11 +724,16 @@ void InputService::Update()
|
||||
|
||||
// Send input events for the focused window
|
||||
WindowsManager::WindowsLocker.Lock();
|
||||
bool mouseRelativeMode = Input::Mouse->IsRelative();
|
||||
for (const auto& e : InputEvents)
|
||||
{
|
||||
auto window = e.Target ? e.Target : defaultWindow;
|
||||
if (!window || !WindowsManager::Windows.Contains(window))
|
||||
continue;
|
||||
|
||||
bool handleRelativeModeInputOnly = mouseRelativeMode;
|
||||
if (handleRelativeModeInputOnly && window->GetCursor() == CursorType::Hidden && window->IsMouseTracking())
|
||||
handleRelativeModeInputOnly = false;
|
||||
switch (e.Type)
|
||||
{
|
||||
// Keyboard events
|
||||
@@ -729,32 +748,43 @@ void InputService::Update()
|
||||
break;
|
||||
// Mouse events
|
||||
case InputDevice::EventType::MouseDown:
|
||||
window->OnMouseDown(window->ScreenToClient(e.MouseData.Position), e.MouseData.Button);
|
||||
if (!handleRelativeModeInputOnly)
|
||||
window->OnMouseDown(window->ScreenToClient(e.MouseData.Position), e.MouseData.Button);
|
||||
break;
|
||||
case InputDevice::EventType::MouseUp:
|
||||
window->OnMouseUp(window->ScreenToClient(e.MouseData.Position), e.MouseData.Button);
|
||||
if (!handleRelativeModeInputOnly)
|
||||
window->OnMouseUp(window->ScreenToClient(e.MouseData.Position), e.MouseData.Button);
|
||||
break;
|
||||
case InputDevice::EventType::MouseDoubleClick:
|
||||
window->OnMouseDoubleClick(window->ScreenToClient(e.MouseData.Position), e.MouseData.Button);
|
||||
if (!handleRelativeModeInputOnly)
|
||||
window->OnMouseDoubleClick(window->ScreenToClient(e.MouseData.Position), e.MouseData.Button);
|
||||
break;
|
||||
case InputDevice::EventType::MouseWheel:
|
||||
window->OnMouseWheel(window->ScreenToClient(e.MouseWheelData.Position), e.MouseWheelData.WheelDelta);
|
||||
if (!handleRelativeModeInputOnly)
|
||||
window->OnMouseWheel(window->ScreenToClient(e.MouseWheelData.Position), e.MouseWheelData.WheelDelta);
|
||||
break;
|
||||
case InputDevice::EventType::MouseMove:
|
||||
window->OnMouseMove(window->ScreenToClient(e.MouseData.Position));
|
||||
if (!handleRelativeModeInputOnly)
|
||||
window->OnMouseMove(window->ScreenToClient(e.MouseData.Position));
|
||||
break;
|
||||
case InputDevice::EventType::MouseMoveRelative:
|
||||
window->OnMouseMoveRelative(e.MouseMovementData.PositionRelative);
|
||||
break;
|
||||
case InputDevice::EventType::MouseLeave:
|
||||
window->OnMouseLeave();
|
||||
break;
|
||||
// Touch events
|
||||
case InputDevice::EventType::TouchDown:
|
||||
window->OnTouchDown(window->ScreenToClient(e.TouchData.Position), e.TouchData.PointerId);
|
||||
if (!handleRelativeModeInputOnly)
|
||||
window->OnTouchDown(window->ScreenToClient(e.TouchData.Position), e.TouchData.PointerId);
|
||||
break;
|
||||
case InputDevice::EventType::TouchMove:
|
||||
window->OnTouchMove(window->ScreenToClient(e.TouchData.Position), e.TouchData.PointerId);
|
||||
if (!handleRelativeModeInputOnly)
|
||||
window->OnTouchMove(window->ScreenToClient(e.TouchData.Position), e.TouchData.PointerId);
|
||||
break;
|
||||
case InputDevice::EventType::TouchUp:
|
||||
window->OnTouchUp(window->ScreenToClient(e.TouchData.Position), e.TouchData.PointerId);
|
||||
if (!handleRelativeModeInputOnly)
|
||||
window->OnTouchUp(window->ScreenToClient(e.TouchData.Position), e.TouchData.PointerId);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -799,6 +829,9 @@ void InputService::Update()
|
||||
case InputDevice::EventType::MouseMove:
|
||||
Input::MouseMove(e.MouseData.Position);
|
||||
break;
|
||||
case InputDevice::EventType::MouseMoveRelative:
|
||||
Input::MouseMoveRelative(e.MouseMovementData.PositionRelative);
|
||||
break;
|
||||
case InputDevice::EventType::MouseLeave:
|
||||
Input::MouseLeave();
|
||||
break;
|
||||
@@ -1011,12 +1044,14 @@ void InputService::Update()
|
||||
}
|
||||
}
|
||||
|
||||
#if !PLATFORM_SDL
|
||||
// Lock mouse if need to
|
||||
const auto lockMode = Screen::GetCursorLock();
|
||||
if (lockMode == CursorLockMode::Locked)
|
||||
{
|
||||
Input::SetMousePosition(Screen::GetSize() * 0.5f);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Send events for the active actions and axes (send events only in play mode)
|
||||
if (!Time::GetGamePaused())
|
||||
|
||||
Reference in New Issue
Block a user