Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve Android mouse input and restructure Android input handlers #4971

Merged
merged 10 commits into from
Jan 5, 2022
2 changes: 2 additions & 0 deletions osu.Framework.Android/AndroidGameActivity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@ public abstract class AndroidGameActivity : Activity
{
protected const ConfigChanges DEFAULT_CONFIG_CHANGES = ConfigChanges.Keyboard
| ConfigChanges.KeyboardHidden
| ConfigChanges.Navigation
| ConfigChanges.Orientation
| ConfigChanges.ScreenLayout
| ConfigChanges.ScreenSize
| ConfigChanges.SmallestScreenSize
| ConfigChanges.Touchscreen
| ConfigChanges.UiMode;

protected const LaunchMode DEFAULT_LAUNCH_MODE = LaunchMode.SingleInstance;
Expand Down
1 change: 1 addition & 0 deletions osu.Framework.Android/AndroidGameHost.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ protected override void SetupConfig(IDictionary<FrameworkSetting, object> defaul
protected override IEnumerable<InputHandler> CreateAvailableInputHandlers() =>
new InputHandler[]
{
new AndroidMouseHandler(gameView),
new AndroidKeyboardHandler(gameView),
new AndroidTouchHandler(gameView),
new MidiHandler()
Expand Down
35 changes: 29 additions & 6 deletions osu.Framework.Android/AndroidGameView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,6 @@ public class AndroidGameView : osuTK.Android.AndroidGameView

private readonly Game game;

public new event Action<Keycode, KeyEvent> KeyDown;
public new event Action<Keycode, KeyEvent> KeyUp;
public event Action<Keycode, KeyEvent> KeyLongPress;
public event Action<string> CommitText;
public event Action<AndroidGameHost> HostStarted;

public AndroidGameView(Context context, Game game)
: base(context)
{
Expand Down Expand Up @@ -141,5 +135,34 @@ public override IInputConnection OnCreateInputConnection(EditorInfo outAttrs)
outAttrs.InputType = InputTypes.TextVariationVisiblePassword | InputTypes.TextFlagNoSuggestions;
return new AndroidInputConnection(this, true);
}

#region Events

/// <summary>
/// Invoked on a key down event.
/// </summary>
public new event Action<Keycode, KeyEvent> KeyDown;

/// <summary>
/// Invoked on a key up event.
/// </summary>
public new event Action<Keycode, KeyEvent> KeyUp;

/// <summary>
/// Invoked on a key long press event.
/// </summary>
public event Action<Keycode, KeyEvent> KeyLongPress;

/// <summary>
/// Invoked when text is committed by an <see cref="AndroidInputConnection"/>.
/// </summary>
public event Action<string> CommitText;

/// <summary>
/// Invoked when the <see cref="game"/> has been started on the <see cref="Host"/>.
/// </summary>
public event Action<AndroidGameHost> HostStarted;

#endregion
}
}
65 changes: 65 additions & 0 deletions osu.Framework.Android/Input/AndroidInputExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// 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 System;
using Android.Views;
using osuTK.Input;

namespace osu.Framework.Android.Input
{
public static class AndroidInputExtensions
{
/// <summary>
/// Returns the corresponding <see cref="MouseButton"/> for a mouse button given as a <see cref="MotionEventButtonState"/>.
/// </summary>
/// <param name="motionEventMouseButton">The given button. Must not be a raw state or a non-mouse button.</param>
/// <returns>The corresponding <see cref="MouseButton"/>.</returns>
/// <exception cref="ArgumentOutOfRangeException">Thrown if the provided button <paramref name="motionEventMouseButton"/> is not a </exception>
public static MouseButton ToMouseButton(this MotionEventButtonState motionEventMouseButton)
{
switch (motionEventMouseButton)
{
case MotionEventButtonState.Primary:
return MouseButton.Left;

case MotionEventButtonState.Secondary:
return MouseButton.Right;

case MotionEventButtonState.Tertiary:
return MouseButton.Middle;

case MotionEventButtonState.Back:
return MouseButton.Button1;

case MotionEventButtonState.Forward:
return MouseButton.Button2;

default:
throw new ArgumentOutOfRangeException(nameof(motionEventMouseButton), motionEventMouseButton, "Given button is not a mouse button.");
}
}

/// <summary>
/// Returns the corresponding <see cref="MouseButton"/> for a mouse button given as a <see cref="Keycode"/>.
/// </summary>
/// <param name="keycode">The given keycode. Should be <see cref="Keycode.Back"/> or <see cref="Keycode.Forward"/>.</param>
/// <param name="button">The corresponding <see cref="MouseButton"/>.</param>
/// <returns><c>true</c> if this <paramref name="keycode"/> is a valid <see cref="MouseButton"/>.</returns>
public static bool TryGetMouseButton(this Keycode keycode, out MouseButton button)
{
switch (keycode)
{
case Keycode.Back:
button = MouseButton.Button1;
return true;

case Keycode.Forward:
button = MouseButton.Button2;
return true;
}

button = MouseButton.LastButton;
return false;
}
}
}
Loading