1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-13 14:12:56 +08:00

Merge branch 'master' into fix-replays

This commit is contained in:
Dan Balasescu 2018-01-17 18:01:41 +09:00 committed by GitHub
commit be225eff90
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 322 additions and 23 deletions

@ -1 +1 @@
Subproject commit 49b563e2cf170eb19006b98dd5b69c2398362d9e Subproject commit 8f36ddab946ff538620081ede7719461d4732b79

View File

@ -31,7 +31,8 @@ namespace osu.Desktop.Overlays
private OsuConfigManager config; private OsuConfigManager config;
private OsuGameBase game; private OsuGameBase game;
public override bool HandleInput => false; public override bool HandleKeyboardInput => false;
public override bool HandleMouseInput => false;
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(NotificationOverlay notification, OsuColour colours, TextureStore textures, OsuGameBase game, OsuConfigManager config) private void load(NotificationOverlay notification, OsuColour colours, TextureStore textures, OsuGameBase game, OsuConfigManager config)

View File

@ -11,7 +11,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
{ {
public class SpinnerBackground : CircularContainer, IHasAccentColour public class SpinnerBackground : CircularContainer, IHasAccentColour
{ {
public override bool HandleInput => false; public override bool HandleKeyboardInput => false;
public override bool HandleMouseInput => false;
protected Box Disc; protected Box Disc;

View File

@ -0,0 +1,274 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Extensions.IEnumerableExtensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Cursor;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Input;
using osu.Framework.MathUtils;
using osu.Framework.Testing.Input;
using osu.Game.Graphics.Cursor;
using osu.Game.Graphics.Sprites;
using OpenTK;
using OpenTK.Graphics;
namespace osu.Game.Tests.Visual
{
public class TestCaseCursors : OsuTestCase
{
private readonly ManualInputManager inputManager;
private readonly CursorOverrideContainer cursorOverrideContainer;
private readonly CustomCursorBox[] cursorBoxes = new CustomCursorBox[6];
public TestCaseCursors()
{
Child = inputManager = new ManualInputManager
{
Child = cursorOverrideContainer = new CursorOverrideContainer
{
RelativeSizeAxes = Axes.Both,
Children = new[]
{
// Middle user
cursorBoxes[0] = new CustomCursorBox(Color4.Green)
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
RelativeSizeAxes = Axes.Both,
Size = new Vector2(0.5f),
},
// Top-left user
cursorBoxes[1] = new CustomCursorBox(Color4.Blue)
{
RelativeSizeAxes = Axes.Both,
Size = new Vector2(0.4f)
},
// Bottom-right user
cursorBoxes[2] = new CustomCursorBox(Color4.Red)
{
Anchor = Anchor.BottomRight,
Origin = Anchor.BottomRight,
RelativeSizeAxes = Axes.Both,
Size = new Vector2(0.4f)
},
// Bottom-left local
cursorBoxes[3] = new CustomCursorBox(Color4.Magenta, false)
{
Anchor = Anchor.BottomLeft,
Origin = Anchor.BottomLeft,
RelativeSizeAxes = Axes.Both,
Size = new Vector2(0.4f)
},
// Top-right local
cursorBoxes[4] = new CustomCursorBox(Color4.Cyan, false)
{
Anchor = Anchor.TopRight,
Origin = Anchor.TopRight,
RelativeSizeAxes = Axes.Both,
Size = new Vector2(0.4f)
},
// Left-local
cursorBoxes[5] = new CustomCursorBox(Color4.Yellow, false)
{
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
RelativeSizeAxes = Axes.Both,
Size = new Vector2(0.2f, 1),
},
}
}
};
returnUserInput();
AddToggleStep("Smooth transitions", b => cursorBoxes.ForEach(box => box.SmoothTransition = b));
testUserCursor();
testLocalCursor();
testUserCursorOverride();
testMultipleLocalCursors();
returnUserInput();
}
/// <summary>
/// Returns input back to the user.
/// </summary>
private void returnUserInput()
{
AddStep("Return user input", () => inputManager.UseParentState = true);
}
/// <summary>
/// -- Green Box --
/// Tests whether hovering in and out of a drawable that provides the user cursor (green)
/// results in the correct visibility state for that cursor.
/// </summary>
private void testUserCursor()
{
AddStep("Move to green area", () => inputManager.MoveMouseTo(cursorBoxes[0]));
AddAssert("Check green cursor visible", () => checkVisible(cursorBoxes[0].Cursor));
AddAssert("Check green cursor at mouse", () => checkAtMouse(cursorBoxes[0].Cursor));
AddStep("Move out", moveOut);
AddAssert("Check green cursor invisible", () => !checkVisible(cursorBoxes[0].Cursor));
AddAssert("Check global cursor visible", () => checkVisible(cursorOverrideContainer.Cursor));
}
/// <summary>
/// -- Purple Box --
/// Tests whether hovering in and out of a drawable that provides a local cursor (purple)
/// results in the correct visibility and state for that cursor.
/// </summary>
private void testLocalCursor()
{
AddStep("Move to purple area", () => inputManager.MoveMouseTo(cursorBoxes[3]));
AddAssert("Check purple cursor visible", () => checkVisible(cursorBoxes[3].Cursor));
AddAssert("Check purple cursor at mouse", () => checkAtMouse(cursorBoxes[3].Cursor));
AddAssert("Check global cursor visible", () => checkVisible(cursorOverrideContainer.Cursor));
AddAssert("Check global cursor at mouse", () => checkAtMouse(cursorOverrideContainer.Cursor));
AddStep("Move out", moveOut);
AddAssert("Check purple cursor visible", () => checkVisible(cursorBoxes[3].Cursor));
AddAssert("Check global cursor visible", () => checkVisible(cursorOverrideContainer.Cursor));
}
/// <summary>
/// -- Blue-Green Box Boundary --
/// Tests whether overriding a user cursor (green) with another user cursor (blue)
/// results in the correct visibility and states for the cursors.
/// </summary>
private void testUserCursorOverride()
{
AddStep("Move to blue-green boundary", () => inputManager.MoveMouseTo(cursorBoxes[1].ScreenSpaceDrawQuad.BottomRight - new Vector2(10)));
AddAssert("Check blue cursor visible", () => checkVisible(cursorBoxes[1].Cursor));
AddAssert("Check green cursor invisible", () => !checkVisible(cursorBoxes[0].Cursor));
AddAssert("Check blue cursor at mouse", () => checkAtMouse(cursorBoxes[1].Cursor));
AddStep("Move out", moveOut);
AddAssert("Check blue cursor not visible", () => !checkVisible(cursorBoxes[1].Cursor));
AddAssert("Check green cursor not visible", () => !checkVisible(cursorBoxes[0].Cursor));
}
/// <summary>
/// -- Yellow-Purple Box Boundary --
/// Tests whether multiple local cursors (purple + yellow) may be visible and at the mouse position at the same time.
/// </summary>
private void testMultipleLocalCursors()
{
AddStep("Move to yellow-purple boundary", () => inputManager.MoveMouseTo(cursorBoxes[5].ScreenSpaceDrawQuad.BottomRight - new Vector2(10)));
AddAssert("Check purple cursor visible", () => checkVisible(cursorBoxes[3].Cursor));
AddAssert("Check purple cursor at mouse", () => checkAtMouse(cursorBoxes[3].Cursor));
AddAssert("Check yellow cursor visible", () => checkVisible(cursorBoxes[5].Cursor));
AddAssert("Check yellow cursor at mouse", () => checkAtMouse(cursorBoxes[5].Cursor));
AddStep("Move out", moveOut);
AddAssert("Check purple cursor visible", () => checkVisible(cursorBoxes[3].Cursor));
AddAssert("Check yellow cursor visible", () => checkVisible(cursorBoxes[5].Cursor));
}
/// <summary>
/// -- Yellow-Blue Box Boundary --
/// Tests whether a local cursor (yellow) may be displayed along with a user cursor override (blue).
/// </summary>
private void testUserOverrideWithLocal()
{
AddStep("Move to yellow-blue boundary", () => inputManager.MoveMouseTo(cursorBoxes[5].ScreenSpaceDrawQuad.TopRight - new Vector2(10)));
AddAssert("Check blue cursor visible", () => checkVisible(cursorBoxes[1].Cursor));
AddAssert("Check blue cursor at mouse", () => checkAtMouse(cursorBoxes[1].Cursor));
AddAssert("Check yellow cursor visible", () => checkVisible(cursorBoxes[5].Cursor));
AddAssert("Check yellow cursor at mouse", () => checkAtMouse(cursorBoxes[5].Cursor));
AddStep("Move out", moveOut);
AddAssert("Check blue cursor invisible", () => !checkVisible(cursorBoxes[1].Cursor));
AddAssert("Check yellow cursor visible", () => checkVisible(cursorBoxes[5].Cursor));
}
/// <summary>
/// Moves the cursor to a point not covered by any cursor containers.
/// </summary>
private void moveOut()
=> inputManager.MoveMouseTo(new Vector2(inputManager.ScreenSpaceDrawQuad.Centre.X, inputManager.ScreenSpaceDrawQuad.TopLeft.Y));
/// <summary>
/// Checks if a cursor is visible.
/// </summary>
/// <param name="cursorContainer">The cursor to check.</param>
private bool checkVisible(CursorContainer cursorContainer) => cursorContainer.State == Visibility.Visible;
/// <summary>
/// Checks if a cursor is at the current inputmanager screen position.
/// </summary>
/// <param name="cursorContainer">The cursor to check.</param>
private bool checkAtMouse(CursorContainer cursorContainer)
=> Precision.AlmostEquals(inputManager.CurrentState.Mouse.NativeState.Position, cursorContainer.ToScreenSpace(cursorContainer.ActiveCursor.DrawPosition));
private class CustomCursorBox : Container, IProvideCursor
{
public bool SmoothTransition;
public CursorContainer Cursor { get; }
public bool ProvidingUserCursor { get; }
public override bool ReceiveMouseInputAt(Vector2 screenSpacePos) => base.ReceiveMouseInputAt(screenSpacePos) || SmoothTransition && !ProvidingUserCursor;
private readonly Box background;
public CustomCursorBox(Color4 cursorColour, bool providesUserCursor = true)
{
ProvidingUserCursor = providesUserCursor;
Colour = cursorColour;
Masking = true;
Children = new Drawable[]
{
background = new Box
{
RelativeSizeAxes = Axes.Both,
Alpha = 0.1f
},
new OsuSpriteText
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Text = providesUserCursor ? "User cursor" : "Local cursor"
},
Cursor = new TestCursorContainer
{
State = providesUserCursor ? Visibility.Hidden : Visibility.Visible,
}
};
}
protected override bool OnHover(InputState state)
{
background.FadeTo(0.4f, 250, Easing.OutQuint);
return false;
}
protected override void OnHoverLost(InputState state)
{
background.FadeTo(0.1f, 250);
base.OnHoverLost(state);
}
}
private class TestCursorContainer : CursorContainer
{
protected override Drawable CreateCursor() => new TestCursor();
private class TestCursor : CircularContainer
{
public TestCursor()
{
Origin = Anchor.Centre;
Size = new Vector2(50);
Masking = true;
Blending = BlendingMode.Additive;
Alpha = 0.5f;
Child = new Box { RelativeSizeAxes = Axes.Both };
}
}
}
}
}

View File

@ -104,6 +104,7 @@
<Compile Include="Visual\TestCaseBreakOverlay.cs" /> <Compile Include="Visual\TestCaseBreakOverlay.cs" />
<Compile Include="Visual\TestCaseChatDisplay.cs" /> <Compile Include="Visual\TestCaseChatDisplay.cs" />
<Compile Include="Visual\TestCaseContextMenu.cs" /> <Compile Include="Visual\TestCaseContextMenu.cs" />
<Compile Include="Visual\TestCaseCursors.cs" />
<Compile Include="Visual\TestCaseDialogOverlay.cs" /> <Compile Include="Visual\TestCaseDialogOverlay.cs" />
<Compile Include="Visual\TestCaseDirect.cs" /> <Compile Include="Visual\TestCaseDirect.cs" />
<Compile Include="Visual\TestCaseDrawableRoom.cs" /> <Compile Include="Visual\TestCaseDrawableRoom.cs" />

View File

@ -30,7 +30,9 @@ namespace osu.Game.Graphics.Backgrounds
/// </summary> /// </summary>
private const float edge_smoothness = 1; private const float edge_smoothness = 1;
public override bool HandleInput => false; public override bool HandleKeyboardInput => false;
public override bool HandleMouseInput => false;
public Color4 ColourLight = Color4.White; public Color4 ColourLight = Color4.White;
public Color4 ColourDark = Color4.Black; public Color4 ColourDark = Color4.Black;

View File

@ -20,7 +20,7 @@ namespace osu.Game.Graphics.Cursor
/// <summary> /// <summary>
/// Whether any cursors can be displayed. /// Whether any cursors can be displayed.
/// </summary> /// </summary>
public bool CanShowCursor; public bool CanShowCursor = true;
public CursorContainer Cursor { get; } public CursorContainer Cursor { get; }
public bool ProvidingUserCursor => true; public bool ProvidingUserCursor => true;

View File

@ -42,7 +42,9 @@ namespace osu.Game.Graphics.UserInterface
//don't allow clicking between transitions and don't make the chevron clickable //don't allow clicking between transitions and don't make the chevron clickable
public override bool ReceiveMouseInputAt(Vector2 screenSpacePos) => Alpha == 1f && Text.ReceiveMouseInputAt(screenSpacePos); public override bool ReceiveMouseInputAt(Vector2 screenSpacePos) => Alpha == 1f && Text.ReceiveMouseInputAt(screenSpacePos);
public override bool HandleInput => State == Visibility.Visible;
public override bool HandleKeyboardInput => State == Visibility.Visible;
public override bool HandleMouseInput => State == Visibility.Visible;
private Visibility state; private Visibility state;

View File

@ -157,6 +157,11 @@ namespace osu.Game
{ {
base.LoadComplete(); base.LoadComplete();
// The next time this is updated is in UpdateAfterChildren, which occurs too late and results
// in the cursor being shown for a few frames during the intro.
// This prevents the cursor from showing until we have a screen with CursorVisible = true
CursorOverrideContainer.CanShowCursor = currentScreen?.CursorVisible ?? false;
// hook up notifications to components. // hook up notifications to components.
BeatmapManager.PostNotification = n => notifications?.Post(n); BeatmapManager.PostNotification = n => notifications?.Post(n);
BeatmapManager.GetStableStorage = GetStorageForStableInstall; BeatmapManager.GetStableStorage = GetStorageForStableInstall;

View File

@ -22,7 +22,8 @@ namespace osu.Game.Overlays
{ {
private readonly Container box; private readonly Container box;
public override bool HandleInput => false; public override bool HandleKeyboardInput => false;
public override bool HandleMouseInput => false;
private readonly SpriteText textLine1; private readonly SpriteText textLine1;
private readonly SpriteText textLine2; private readonly SpriteText textLine2;

View File

@ -474,7 +474,8 @@ namespace osu.Game.Overlays.Profile
private class LinkFlowContainer : OsuTextFlowContainer private class LinkFlowContainer : OsuTextFlowContainer
{ {
public override bool HandleInput => true; public override bool HandleKeyboardInput => true;
public override bool HandleMouseInput => true;
public LinkFlowContainer(Action<SpriteText> defaultCreationParameters = null) : base(defaultCreationParameters) public LinkFlowContainer(Action<SpriteText> defaultCreationParameters = null) : base(defaultCreationParameters)
{ {
@ -488,7 +489,8 @@ namespace osu.Game.Overlays.Profile
{ {
private readonly OsuHoverContainer content; private readonly OsuHoverContainer content;
public override bool HandleInput => content.Action != null; public override bool HandleKeyboardInput => content.Action != null;
public override bool HandleMouseInput => content.Action != null;
protected override Container<Drawable> Content => content ?? (Container<Drawable>)this; protected override Container<Drawable> Content => content ?? (Container<Drawable>)this;

View File

@ -87,7 +87,8 @@ namespace osu.Game.Overlays.Toolbar
ruleset.Value = rulesets.AvailableRulesets.FirstOrDefault(); ruleset.Value = rulesets.AvailableRulesets.FirstOrDefault();
} }
public override bool HandleInput => !ruleset.Disabled; public override bool HandleKeyboardInput => !ruleset.Disabled;
public override bool HandleMouseInput => !ruleset.Disabled;
private void disabledChanged(bool isDisabled) => this.FadeColour(isDisabled ? Color4.Gray : Color4.White, 300); private void disabledChanged(bool isDisabled) => this.FadeColour(isDisabled ? Color4.Gray : Color4.White, 300);

View File

@ -165,7 +165,8 @@ namespace osu.Game.Rulesets.Edit.Layers.Selection
} }
private bool isActive = true; private bool isActive = true;
public override bool HandleInput => isActive; public override bool HandleKeyboardInput => isActive;
public override bool HandleMouseInput => isActive;
public override void Hide() public override void Hide()
{ {

View File

@ -68,7 +68,8 @@ namespace osu.Game.Rulesets.Objects.Drawables
private bool judgementFinalized => judgements.LastOrDefault()?.Final == true; private bool judgementFinalized => judgements.LastOrDefault()?.Final == true;
public bool Interactive = true; public bool Interactive = true;
public override bool HandleInput => Interactive; public override bool HandleKeyboardInput => Interactive;
public override bool HandleMouseInput => Interactive;
public override bool RemoveWhenNotAlive => false; public override bool RemoveWhenNotAlive => false;
public override bool RemoveCompletedTransforms => false; public override bool RemoveCompletedTransforms => false;

View File

@ -222,7 +222,8 @@ namespace osu.Game.Screens.Menu
boxHoverLayer.FadeOut(800, Easing.OutExpo); boxHoverLayer.FadeOut(800, Easing.OutExpo);
} }
public override bool HandleInput => state != ButtonState.Exploded && box.Scale.X >= 0.8f; public override bool HandleKeyboardInput => state != ButtonState.Exploded;
public override bool HandleMouseInput => state != ButtonState.Exploded && box.Scale.X >= 0.8f;
protected override void Update() protected override void Update()
{ {

View File

@ -199,7 +199,8 @@ namespace osu.Game.Screens.Menu
private MenuState state; private MenuState state;
public override bool HandleInput => state != MenuState.Exit; public override bool HandleKeyboardInput => state != MenuState.Exit;
public override bool HandleMouseInput => state != MenuState.Exit;
public MenuState State public MenuState State
{ {

View File

@ -64,7 +64,8 @@ namespace osu.Game.Screens.Menu
private readonly float[] frequencyAmplitudes = new float[256]; private readonly float[] frequencyAmplitudes = new float[256];
public override bool HandleInput => false; public override bool HandleKeyboardInput => false;
public override bool HandleMouseInput => false;
private Shader shader; private Shader shader;
private readonly Texture texture; private readonly Texture texture;

View File

@ -19,7 +19,8 @@ namespace osu.Game.Screens.Menu
{ {
public class MenuSideFlashes : BeatSyncedContainer public class MenuSideFlashes : BeatSyncedContainer
{ {
public override bool HandleInput => false; public override bool HandleKeyboardInput => false;
public override bool HandleMouseInput => false;
private readonly Bindable<WorkingBeatmap> beatmap = new Bindable<WorkingBeatmap>(); private readonly Bindable<WorkingBeatmap> beatmap = new Bindable<WorkingBeatmap>();

View File

@ -142,8 +142,6 @@ namespace osu.Game.Screens.Play
} }
} }
public override bool HandleInput => State == Visibility.Visible;
protected override void PopIn() => this.FadeIn(transition_duration, Easing.In); protected override void PopIn() => this.FadeIn(transition_duration, Easing.In);
protected override void PopOut() => this.FadeOut(transition_duration, Easing.In); protected override void PopOut() => this.FadeOut(transition_duration, Easing.In);

View File

@ -111,7 +111,8 @@ namespace osu.Game.Screens.Play
} }
} }
public override bool HandleInput => receptor == null; public override bool HandleKeyboardInput => receptor == null;
public override bool HandleMouseInput => receptor == null;
private Receptor receptor; private Receptor receptor;

View File

@ -31,7 +31,8 @@ namespace osu.Game.Screens.Play
public Action<double> OnSeek; public Action<double> OnSeek;
public override bool HandleInput => AllowSeeking; public override bool HandleKeyboardInput => AllowSeeking;
public override bool HandleMouseInput => AllowSeeking;
private IClock audioClock; private IClock audioClock;
public IClock AudioClock { set { audioClock = info.AudioClock = value; } } public IClock AudioClock { set { audioClock = info.AudioClock = value; } }

View File

@ -21,7 +21,8 @@ namespace osu.Game.Screens.Play
public int ColumnCount => columns.Length; public int ColumnCount => columns.Length;
public override bool HandleInput => false; public override bool HandleKeyboardInput => false;
public override bool HandleMouseInput => false;
private int progress; private int progress;
public int Progress public int Progress

View File

@ -51,7 +51,8 @@ namespace osu.Game.Screens.Select
/// </summary> /// </summary>
public Action<BeatmapInfo> SelectionChanged; public Action<BeatmapInfo> SelectionChanged;
public override bool HandleInput => AllowSelection; public override bool HandleKeyboardInput => AllowSelection;
public override bool HandleMouseInput => AllowSelection;
/// <summary> /// <summary>
/// Used to avoid firing null selections before the initial beatmaps have been loaded via <see cref="BeatmapSets"/>. /// Used to avoid firing null selections before the initial beatmaps have been loaded via <see cref="BeatmapSets"/>.

View File

@ -26,7 +26,8 @@ namespace osu.Game.Storyboards.Drawables
protected override Container<DrawableStoryboardLayer> Content => content; protected override Container<DrawableStoryboardLayer> Content => content;
protected override Vector2 DrawScale => new Vector2(Parent.DrawHeight / 480); protected override Vector2 DrawScale => new Vector2(Parent.DrawHeight / 480);
public override bool HandleInput => false; public override bool HandleKeyboardInput => false;
public override bool HandleMouseInput => false;
private bool passing = true; private bool passing = true;
public bool Passing public bool Passing