Skip to content

Commit

Permalink
Map pen to touch input when touching the screen
Browse files Browse the repository at this point in the history
  • Loading branch information
frenzibyte committed Jan 25, 2025
1 parent 804df9b commit aa95565
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 17 deletions.
7 changes: 0 additions & 7 deletions osu.Framework/Input/Handlers/Pen/PenHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,11 @@ public override bool Initialize(GameHost host)
if (enabled.NewValue)
{
window.PenMove += handlePenMove;
window.PenTouch += handlePenTouch;
window.PenButton += handlePenButton;
}
else
{
window.PenMove -= handlePenMove;
window.PenTouch -= handlePenTouch;
window.PenButton -= handlePenButton;
}
}, true);
Expand All @@ -58,11 +56,6 @@ private void handlePenMove(Vector2 position)
});
}

private void handlePenTouch(bool pressed)
{
enqueueInput(new MouseButtonInputFromPen(pressed) { DeviceType = device_type });
}

private void handlePenButton(TabletPenButton button, bool pressed)
{
enqueueInput(new TabletPenButtonInput(button, pressed));
Expand Down
11 changes: 8 additions & 3 deletions osu.Framework/Input/States/TouchState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,14 @@ namespace osu.Framework.Input.States
public class TouchState
{
/// <summary>
/// The maximum amount of touches this can handle.
/// The maximum amount of touches this can handle (excluding <see cref="TouchSource.PenTouch"/>).
/// </summary>
public static readonly int MAX_TOUCH_COUNT = Enum.GetValues<TouchSource>().Length;
public static readonly int MAX_TOUCH_COUNT = 10;

/// <summary>
/// The maximum number of <see cref="TouchSource"/>s.
/// </summary>
public static readonly int MAX_SOURCES_COUNT = Enum.GetValues<TouchSource>().Length;

/// <summary>
/// The list of currently active touch sources.
Expand All @@ -25,7 +30,7 @@ public class TouchState
/// Using <see cref="GetTouchPosition"/> is recommended for retrieving
/// logically correct values, as this may contain already stale values.
/// </remarks>
public readonly Vector2[] TouchPositions = new Vector2[MAX_TOUCH_COUNT];
public readonly Vector2[] TouchPositions = new Vector2[MAX_SOURCES_COUNT];

/// <summary>
/// Retrieves the current touch position of a specified <paramref name="source"/>.
Expand Down
5 changes: 5 additions & 0 deletions osu.Framework/Input/TouchSource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,5 +57,10 @@ public enum TouchSource
/// The tenth and last available touch source.
/// </summary>
Touch10,

/// <summary>
/// A touch source that represents a pen/stylus.
/// </summary>
PenTouch,
}
}
24 changes: 17 additions & 7 deletions osu.Framework/Platform/SDL3/SDL3Window_Input.cs
Original file line number Diff line number Diff line change
Expand Up @@ -524,14 +524,29 @@ private void handleKeyboardEvent(SDL_KeyboardEvent evtKey)

private void handleKeymapChangedEvent() => KeymapChanged?.Invoke();

// pen input events should ultimately have its own input flow with code from InputManager to fall back to mouse input,
// but as the current structure of InputManager completely disallows that, synthesize touch input on pen events
// so it still works correctly for our use case (consider OsuTouchInputMapper in osu!).

private void handlePenMotionEvent(SDL_PenMotionEvent evtPenMotion)
{
PenMove?.Invoke(new Vector2(evtPenMotion.x, evtPenMotion.y) * Scale);
var pos = new Vector2(evtPenMotion.x, evtPenMotion.y) * Scale;

if (evtPenMotion.pen_state.HasFlagFast(SDL_PenInputFlags.SDL_PEN_INPUT_DOWN))
TouchDown?.Invoke(new Touch(TouchSource.PenTouch, pos));
else
PenMove?.Invoke(pos);
}

private void handlePenTouchEvent(SDL_PenTouchEvent evtPenTouch)
{
PenTouch?.Invoke(evtPenTouch.down);
var pos = new Vector2(evtPenTouch.x, evtPenTouch.y) * Scale;
var touch = new Touch(TouchSource.PenTouch, pos);

if (evtPenTouch.down)
TouchDown?.Invoke(touch);
else
TouchUp?.Invoke(touch);
}

/// <summary>
Expand Down Expand Up @@ -741,11 +756,6 @@ private void updateConfineMode()
/// </summary>
public event Action<Vector2>? PenMove;

/// <summary>
/// Invoked when a pen touches (<c>true</c>) or lifts (<c>false</c>) from the tablet surface.
/// </summary>
public event Action<bool>? PenTouch;

/// <summary>
/// Invoked when a <see cref="TabletPenButton">pen button</see> is pressed (<c>true</c>) or released (<c>false</c>).
/// </summary>
Expand Down

0 comments on commit aa95565

Please sign in to comment.