From b265888f182935035a372d5f6558f8895b90b2c5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 16 Jan 2023 19:35:55 +0900 Subject: [PATCH] Add bare minimum touch support to osu! ruleset --- osu.Game.Rulesets.Osu/OsuInputManager.cs | 11 ++- .../UI/OsuTouchInputMapper.cs | 76 +++++++++++++++++++ 2 files changed, 85 insertions(+), 2 deletions(-) create mode 100644 osu.Game.Rulesets.Osu/UI/OsuTouchInputMapper.cs diff --git a/osu.Game.Rulesets.Osu/OsuInputManager.cs b/osu.Game.Rulesets.Osu/OsuInputManager.cs index 7dede9e283..28b4f70c10 100644 --- a/osu.Game.Rulesets.Osu/OsuInputManager.cs +++ b/osu.Game.Rulesets.Osu/OsuInputManager.cs @@ -1,16 +1,17 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using System.ComponentModel; using System.Linq; +using osu.Framework.Allocation; +using osu.Framework.Graphics; using osu.Framework.Input; using osu.Framework.Input.Bindings; using osu.Framework.Input.Events; using osu.Framework.Input.StateChanges.Events; using osu.Game.Input.Bindings; +using osu.Game.Rulesets.Osu.UI; using osu.Game.Rulesets.UI; namespace osu.Game.Rulesets.Osu @@ -45,6 +46,12 @@ namespace osu.Game.Rulesets.Osu { } + [BackgroundDependencyLoader] + private void load() + { + Add(new OsuTouchInputMapper(this) { RelativeSizeAxes = Axes.Both }); + } + protected override bool Handle(UIEvent e) { if ((e is MouseMoveEvent || e is TouchMoveEvent) && !AllowUserCursorMovement) return false; diff --git a/osu.Game.Rulesets.Osu/UI/OsuTouchInputMapper.cs b/osu.Game.Rulesets.Osu/UI/OsuTouchInputMapper.cs new file mode 100644 index 0000000000..f4ed70f790 --- /dev/null +++ b/osu.Game.Rulesets.Osu/UI/OsuTouchInputMapper.cs @@ -0,0 +1,76 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Collections.Generic; +using System.Linq; +using osu.Framework.Graphics; +using osu.Framework.Input; +using osu.Framework.Input.Events; + +namespace osu.Game.Rulesets.Osu.UI +{ + public partial class OsuTouchInputMapper : Drawable + { + /// + /// This is our parent . + /// + private readonly OsuInputManager osuInputManager; + + /// + /// All the active s and the that it triggered (if any). + /// Ordered from oldest to newest touch chronologically. + /// + private readonly List trackedTouches = new List(); + + public OsuTouchInputMapper(OsuInputManager inputManager) + { + osuInputManager = inputManager; + } + + private OsuAction? lastAction; + + protected override bool OnTouchDown(TouchDownEvent e) + { + OsuAction action = lastAction == OsuAction.LeftButton && trackedTouches.Count > 0 ? OsuAction.RightButton : OsuAction.LeftButton; + + if (trackedTouches.All(t => t.Action != action)) + { + trackedTouches.Add(new TrackedTouch(e.Touch, action)); + osuInputManager.KeyBindingContainer.TriggerPressed(action); + lastAction = action; + } + else + { + // Ignore any taps which trigger an action which is already handled. But track them for potential positional input in the future. + trackedTouches.Add(new TrackedTouch(e.Touch, null)); + } + + return true; + } + + protected override void OnTouchUp(TouchUpEvent e) + { + var tracked = trackedTouches.First(t => t.Touch.Source == e.Touch.Source); + + if (tracked.Action is OsuAction action) + osuInputManager.KeyBindingContainer.TriggerReleased(action); + + trackedTouches.Remove(tracked); + + base.OnTouchUp(e); + } + + private class TrackedTouch + { + public readonly Touch Touch; + + public readonly OsuAction? Action; + + public TrackedTouch(Touch touch, OsuAction? action) + { + Touch = touch; + Action = action; + } + } + } +}