Skip to content

Commit

Permalink
Allow invalidating mouse position state
Browse files Browse the repository at this point in the history
  • Loading branch information
frenzibyte committed Dec 15, 2024
1 parent d0b288d commit d95cc56
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 12 deletions.
26 changes: 16 additions & 10 deletions osu.Framework/Input/InputManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ public Drawable DraggedDrawable
/// <remarks>
/// This collection should not be retained as a reference. The contents is not stable outside of local usage.
/// </remarks>
public SlimReadOnlyListWrapper<Drawable> PositionalInputQueue => buildPositionalInputQueue(CurrentState.Mouse.Position);
public SlimReadOnlyListWrapper<Drawable> PositionalInputQueue => buildPositionalInputQueue(!CurrentState.Mouse.IsPositionValid ? null : CurrentState.Mouse.Position);

/// <summary>
/// Contains all <see cref="Drawable"/>s in top-down order which are considered
Expand Down Expand Up @@ -627,10 +627,13 @@ private SlimReadOnlyListWrapper<Drawable> buildNonPositionalInputQueue()

private readonly List<Drawable> positionalInputQueue = new List<Drawable>();

private SlimReadOnlyListWrapper<Drawable> buildPositionalInputQueue(Vector2 screenSpacePos)
private SlimReadOnlyListWrapper<Drawable> buildPositionalInputQueue(Vector2? screenSpacePos)
{
positionalInputQueue.Clear();

if (screenSpacePos == null)
return positionalInputQueue.AsSlimReadOnly();

if (this is UserInputManager)
FrameStatistics.Increment(StatisticsCounterType.PositionalIQ);

Expand All @@ -639,7 +642,7 @@ private SlimReadOnlyListWrapper<Drawable> buildPositionalInputQueue(Vector2 scre
for (int i = 0; i < children.Count; i++)
{
if (ShouldBeConsideredForInput(children[i]))
children[i].BuildPositionalInputQueue(screenSpacePos, positionalInputQueue);
children[i].BuildPositionalInputQueue(screenSpacePos.Value, positionalInputQueue);
}

positionalInputQueue.Reverse();
Expand Down Expand Up @@ -959,16 +962,19 @@ protected virtual void HandleMousePositionChange(MousePositionChangeEvent e)
var state = e.State;
var mouse = state.Mouse;

foreach (var h in InputHandlers)
if (e.LastPosition != null)
{
if (h.Enabled.Value && h is INeedsMousePositionFeedback handler)
handler.FeedbackMousePositionChange(mouse.Position, h == mouseSource);
}
foreach (var h in InputHandlers)
{
if (h.Enabled.Value && h is INeedsMousePositionFeedback handler)
handler.FeedbackMousePositionChange(mouse.Position, h == mouseSource);
}

handleMouseMove(state, e.LastPosition);
handleMouseMove(state, e.LastPosition.Value);

foreach (var manager in mouseButtonEventManagers.Values)
manager.HandlePositionChange(state, e.LastPosition);
foreach (var manager in mouseButtonEventManagers.Values)
manager.HandlePositionChange(state, e.LastPosition.Value);
}

updateHoverEvents(state);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ namespace osu.Framework.Input.StateChanges.Events
public class MousePositionChangeEvent : InputStateChangeEvent
{
/// <summary>
/// The last mouse position.
/// The last mouse position, or null if the event is invalidation of the mouse position state.
/// </summary>
public readonly Vector2 LastPosition;
public readonly Vector2? LastPosition;

public MousePositionChangeEvent(InputState state, IInput input, Vector2 lastPosition)
: base(state, input)
Expand Down
28 changes: 28 additions & 0 deletions osu.Framework/Input/StateChanges/MouseInvalidatePositionInput.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright (c) ppy Pty Ltd <[email protected]>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

using osu.Framework.Input.StateChanges.Events;
using osu.Framework.Input.States;

namespace osu.Framework.Input.StateChanges
{
/// <summary>
/// Denotes an invalidation of the current mouse position,
/// mainly used when a single remaining touch source is released,
/// or a hovering pen (e.g. Apple Pencil) leaves the screen area.
/// </summary>
public class MouseInvalidatePositionInput : IInput
{
public void Apply(InputState state, IInputStateChangeHandler handler)
{
var mouse = state.Mouse;

if (mouse.IsPositionValid)
{
mouse.IsPositionValid = false;
mouse.LastSource = this;
handler.HandleInputStateChange(new MousePositionChangeEvent(state, this, mouse.Position));
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright (c) ppy Pty Ltd <[email protected]>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

using osu.Framework.Input.StateChanges.Events;

namespace osu.Framework.Input.StateChanges
{
public class MouseInvalidatePositionInputFromTouch : MouseInvalidatePositionInput, ISourcedFromTouch
{
public MouseInvalidatePositionInputFromTouch(TouchStateChangeEvent touchEvent)
{
TouchEvent = touchEvent;
}

public TouchStateChangeEvent TouchEvent { get; }
}
}

0 comments on commit d95cc56

Please sign in to comment.