From ae032cbf2376bce33f29bf4b34dc9471b8585323 Mon Sep 17 00:00:00 2001 From: TocoToucan Date: Sun, 7 Jan 2018 23:40:00 +0300 Subject: [PATCH 01/11] Support HandleKeyboardInput, HandleMouseInput, CanReceiveKeyboardInput, CanReceiveMouseInput properties --- osu.Desktop/Overlays/VersionManager.cs | 3 ++- .../Objects/Drawables/Pieces/SpinnerBackground.cs | 3 ++- osu.Game/Graphics/Backgrounds/Triangles.cs | 4 +++- osu.Game/Graphics/UserInterface/BreadcrumbControl.cs | 4 +++- osu.Game/Overlays/OnScreenDisplay.cs | 3 ++- osu.Game/Overlays/Profile/ProfileHeader.cs | 7 +++++-- osu.Game/Overlays/Toolbar/ToolbarModeSelector.cs | 4 +++- .../Edit/Layers/Selection/HitObjectSelectionBox.cs | 3 ++- osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs | 3 ++- osu.Game/Screens/Menu/Button.cs | 4 +++- osu.Game/Screens/Menu/ButtonSystem.cs | 4 +++- osu.Game/Screens/Menu/LogoVisualisation.cs | 3 ++- osu.Game/Screens/Menu/MenuSideFlashes.cs | 3 ++- osu.Game/Screens/Play/GameplayMenuOverlay.cs | 4 +++- osu.Game/Screens/Play/KeyCounterCollection.cs | 4 +++- osu.Game/Screens/Play/SongProgress.cs | 3 ++- osu.Game/Screens/Play/SquareGraph.cs | 3 ++- osu.Game/Screens/Select/BeatmapCarousel.cs | 3 ++- osu.Game/Storyboards/Drawables/DrawableStoryboard.cs | 3 ++- 19 files changed, 48 insertions(+), 20 deletions(-) diff --git a/osu.Desktop/Overlays/VersionManager.cs b/osu.Desktop/Overlays/VersionManager.cs index 923356c610..090173f38d 100644 --- a/osu.Desktop/Overlays/VersionManager.cs +++ b/osu.Desktop/Overlays/VersionManager.cs @@ -31,7 +31,8 @@ namespace osu.Desktop.Overlays private OsuConfigManager config; private OsuGameBase game; - public override bool HandleInput => false; + public override bool HandleKeyboardInput => false; + public override bool HandleMouseInput => false; [BackgroundDependencyLoader] private void load(NotificationOverlay notification, OsuColour colours, TextureStore textures, OsuGameBase game, OsuConfigManager config) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerBackground.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerBackground.cs index 7c96a2a8cf..c44d7594ad 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerBackground.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerBackground.cs @@ -11,7 +11,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces { public class SpinnerBackground : CircularContainer, IHasAccentColour { - public override bool HandleInput => false; + public override bool HandleKeyboardInput => false; + public override bool HandleMouseInput => false; protected Box Disc; diff --git a/osu.Game/Graphics/Backgrounds/Triangles.cs b/osu.Game/Graphics/Backgrounds/Triangles.cs index 5e23389b89..6f9d83473f 100644 --- a/osu.Game/Graphics/Backgrounds/Triangles.cs +++ b/osu.Game/Graphics/Backgrounds/Triangles.cs @@ -30,7 +30,9 @@ namespace osu.Game.Graphics.Backgrounds /// 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 ColourDark = Color4.Black; diff --git a/osu.Game/Graphics/UserInterface/BreadcrumbControl.cs b/osu.Game/Graphics/UserInterface/BreadcrumbControl.cs index 99afc02d5d..566254886e 100644 --- a/osu.Game/Graphics/UserInterface/BreadcrumbControl.cs +++ b/osu.Game/Graphics/UserInterface/BreadcrumbControl.cs @@ -42,7 +42,9 @@ namespace osu.Game.Graphics.UserInterface //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 HandleInput => State == Visibility.Visible; + public override bool HandleKeyboardInput => handleInput; + public override bool HandleMouseInput => handleInput; + private bool handleInput => State == Visibility.Visible; private Visibility state; diff --git a/osu.Game/Overlays/OnScreenDisplay.cs b/osu.Game/Overlays/OnScreenDisplay.cs index 6a1bd8e182..ce31f10fc4 100644 --- a/osu.Game/Overlays/OnScreenDisplay.cs +++ b/osu.Game/Overlays/OnScreenDisplay.cs @@ -22,7 +22,8 @@ namespace osu.Game.Overlays { 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 textLine2; diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index 6a9f4b84b0..450979a261 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -474,7 +474,8 @@ namespace osu.Game.Overlays.Profile private class LinkFlowContainer : OsuTextFlowContainer { - public override bool HandleInput => true; + public override bool HandleKeyboardInput => true; + public override bool HandleMouseInput => true; public LinkFlowContainer(Action defaultCreationParameters = null) : base(defaultCreationParameters) { @@ -488,7 +489,9 @@ namespace osu.Game.Overlays.Profile { private readonly OsuHoverContainer content; - public override bool HandleInput => content.Action != null; + public override bool HandleKeyboardInput => handleInput; + public override bool HandleMouseInput => handleInput; + private bool handleInput => content.Action != null; protected override Container Content => content ?? (Container)this; diff --git a/osu.Game/Overlays/Toolbar/ToolbarModeSelector.cs b/osu.Game/Overlays/Toolbar/ToolbarModeSelector.cs index 0fa6fa23a2..2acc1075a3 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarModeSelector.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarModeSelector.cs @@ -87,7 +87,9 @@ namespace osu.Game.Overlays.Toolbar ruleset.Value = rulesets.AvailableRulesets.FirstOrDefault(); } - public override bool HandleInput => !ruleset.Disabled; + public override bool HandleKeyboardInput => handleInput; + public override bool HandleMouseInput => handleInput; + private bool handleInput => !ruleset.Disabled; private void disabledChanged(bool isDisabled) => this.FadeColour(isDisabled ? Color4.Gray : Color4.White, 300); diff --git a/osu.Game/Rulesets/Edit/Layers/Selection/HitObjectSelectionBox.cs b/osu.Game/Rulesets/Edit/Layers/Selection/HitObjectSelectionBox.cs index c840cb0c38..fcb2f8f57f 100644 --- a/osu.Game/Rulesets/Edit/Layers/Selection/HitObjectSelectionBox.cs +++ b/osu.Game/Rulesets/Edit/Layers/Selection/HitObjectSelectionBox.cs @@ -165,7 +165,8 @@ namespace osu.Game.Rulesets.Edit.Layers.Selection } private bool isActive = true; - public override bool HandleInput => isActive; + public override bool HandleKeyboardInput => isActive; + public override bool HandleMouseInput => isActive; public override void Hide() { diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index 34c34e1d33..546281df44 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -61,7 +61,8 @@ namespace osu.Game.Rulesets.Objects.Drawables public new readonly TObject HitObject; - public override bool HandleInput => Interactive; + public override bool HandleKeyboardInput => Interactive; + public override bool HandleMouseInput => Interactive; public bool Interactive = true; /// diff --git a/osu.Game/Screens/Menu/Button.cs b/osu.Game/Screens/Menu/Button.cs index f5dd5cb500..fff2435cb4 100644 --- a/osu.Game/Screens/Menu/Button.cs +++ b/osu.Game/Screens/Menu/Button.cs @@ -222,7 +222,9 @@ namespace osu.Game.Screens.Menu boxHoverLayer.FadeOut(800, Easing.OutExpo); } - public override bool HandleInput => state != ButtonState.Exploded && box.Scale.X >= 0.8f; + public override bool HandleKeyboardInput => handleInput; + public override bool HandleMouseInput => handleInput; + private bool handleInput => state != ButtonState.Exploded && box.Scale.X >= 0.8f; protected override void Update() { diff --git a/osu.Game/Screens/Menu/ButtonSystem.cs b/osu.Game/Screens/Menu/ButtonSystem.cs index 72fe4368f0..b77dc4a656 100644 --- a/osu.Game/Screens/Menu/ButtonSystem.cs +++ b/osu.Game/Screens/Menu/ButtonSystem.cs @@ -200,7 +200,9 @@ namespace osu.Game.Screens.Menu private MenuState state; - public override bool HandleInput => state != MenuState.Exit; + public override bool HandleKeyboardInput => handleInput; + public override bool HandleMouseInput => handleInput; + private bool handleInput=> state != MenuState.Exit; public MenuState State { diff --git a/osu.Game/Screens/Menu/LogoVisualisation.cs b/osu.Game/Screens/Menu/LogoVisualisation.cs index 3fb5cc6d0d..3a3f3d4650 100644 --- a/osu.Game/Screens/Menu/LogoVisualisation.cs +++ b/osu.Game/Screens/Menu/LogoVisualisation.cs @@ -64,7 +64,8 @@ namespace osu.Game.Screens.Menu 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 readonly Texture texture; diff --git a/osu.Game/Screens/Menu/MenuSideFlashes.cs b/osu.Game/Screens/Menu/MenuSideFlashes.cs index 3cf2ce8e89..f94e2bddc1 100644 --- a/osu.Game/Screens/Menu/MenuSideFlashes.cs +++ b/osu.Game/Screens/Menu/MenuSideFlashes.cs @@ -19,7 +19,8 @@ namespace osu.Game.Screens.Menu { public class MenuSideFlashes : BeatSyncedContainer { - public override bool HandleInput => false; + public override bool HandleKeyboardInput => false; + public override bool HandleMouseInput => false; private readonly Bindable beatmap = new Bindable(); diff --git a/osu.Game/Screens/Play/GameplayMenuOverlay.cs b/osu.Game/Screens/Play/GameplayMenuOverlay.cs index af222b82e2..8fa76e2e51 100644 --- a/osu.Game/Screens/Play/GameplayMenuOverlay.cs +++ b/osu.Game/Screens/Play/GameplayMenuOverlay.cs @@ -142,7 +142,9 @@ namespace osu.Game.Screens.Play } } - public override bool HandleInput => State == Visibility.Visible; + public override bool HandleKeyboardInput => handleInput; + public override bool HandleMouseInput => handleInput; + private bool handleInput => State == Visibility.Visible; protected override void PopIn() => this.FadeIn(transition_duration, Easing.In); protected override void PopOut() => this.FadeOut(transition_duration, Easing.In); diff --git a/osu.Game/Screens/Play/KeyCounterCollection.cs b/osu.Game/Screens/Play/KeyCounterCollection.cs index 554fbbaf61..c716841861 100644 --- a/osu.Game/Screens/Play/KeyCounterCollection.cs +++ b/osu.Game/Screens/Play/KeyCounterCollection.cs @@ -111,7 +111,9 @@ namespace osu.Game.Screens.Play } } - public override bool HandleInput => receptor == null; + public override bool HandleKeyboardInput => handleInput; + public override bool HandleMouseInput => handleInput; + private bool handleInput => receptor == null; private Receptor receptor; diff --git a/osu.Game/Screens/Play/SongProgress.cs b/osu.Game/Screens/Play/SongProgress.cs index 897fe4bba7..8aad741ad1 100644 --- a/osu.Game/Screens/Play/SongProgress.cs +++ b/osu.Game/Screens/Play/SongProgress.cs @@ -28,7 +28,8 @@ namespace osu.Game.Screens.Play public Action OnSeek; - public override bool HandleInput => AllowSeeking; + public override bool HandleKeyboardInput => AllowSeeking; + public override bool HandleMouseInput => AllowSeeking; private IClock audioClock; public IClock AudioClock { set { audioClock = info.AudioClock = value; } } diff --git a/osu.Game/Screens/Play/SquareGraph.cs b/osu.Game/Screens/Play/SquareGraph.cs index 7bccad0c34..48013f7943 100644 --- a/osu.Game/Screens/Play/SquareGraph.cs +++ b/osu.Game/Screens/Play/SquareGraph.cs @@ -21,7 +21,8 @@ namespace osu.Game.Screens.Play public int ColumnCount => columns.Length; - public override bool HandleInput => false; + public override bool HandleKeyboardInput => false; + public override bool HandleMouseInput => false; private int progress; public int Progress diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index 7a47bb9631..93b77fe1c4 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -51,7 +51,8 @@ namespace osu.Game.Screens.Select /// public Action SelectionChanged; - public override bool HandleInput => AllowSelection; + public override bool HandleKeyboardInput => AllowSelection; + public override bool HandleMouseInput => AllowSelection; /// /// Used to avoid firing null selections before the initial beatmaps have been loaded via . diff --git a/osu.Game/Storyboards/Drawables/DrawableStoryboard.cs b/osu.Game/Storyboards/Drawables/DrawableStoryboard.cs index 7e8a80d86a..2489369493 100644 --- a/osu.Game/Storyboards/Drawables/DrawableStoryboard.cs +++ b/osu.Game/Storyboards/Drawables/DrawableStoryboard.cs @@ -26,7 +26,8 @@ namespace osu.Game.Storyboards.Drawables protected override Container Content => content; 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; public bool Passing From 0459f0a0696cadc1ec4cf4212eff6adcb22c98ff Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 16 Jan 2018 13:40:02 +0900 Subject: [PATCH 02/11] Invert CanShowCursor conditional to fix cursor not showing in VisualTests --- osu.Game/Graphics/Cursor/CursorOverrideContainer.cs | 2 +- osu.Game/OsuGame.cs | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/osu.Game/Graphics/Cursor/CursorOverrideContainer.cs b/osu.Game/Graphics/Cursor/CursorOverrideContainer.cs index 4b29414990..0fae4579fa 100644 --- a/osu.Game/Graphics/Cursor/CursorOverrideContainer.cs +++ b/osu.Game/Graphics/Cursor/CursorOverrideContainer.cs @@ -20,7 +20,7 @@ namespace osu.Game.Graphics.Cursor /// /// Whether any cursors can be displayed. /// - public bool CanShowCursor; + public bool CanShowCursor = true; public CursorContainer Cursor { get; } public bool ProvidingUserCursor => true; diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 124b9364b3..b48e25f1fe 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -157,6 +157,11 @@ namespace osu.Game { 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. BeatmapManager.PostNotification = n => notifications?.Post(n); BeatmapManager.GetStableStorage = GetStorageForStableInstall; From d230fd486e2cc023c59e024287a9422de00c58d1 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 16 Jan 2018 15:28:00 +0900 Subject: [PATCH 03/11] Add automated cursor testcase --- osu.Game.Tests/Visual/TestCaseCursors.cs | 250 +++++++++++++++++++++++ osu.Game.Tests/osu.Game.Tests.csproj | 1 + 2 files changed, 251 insertions(+) create mode 100644 osu.Game.Tests/Visual/TestCaseCursors.cs diff --git a/osu.Game.Tests/Visual/TestCaseCursors.cs b/osu.Game.Tests/Visual/TestCaseCursors.cs new file mode 100644 index 0000000000..e0ce5fad77 --- /dev/null +++ b/osu.Game.Tests/Visual/TestCaseCursors.cs @@ -0,0 +1,250 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Cursor; +using osu.Framework.Graphics.Shapes; +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(); + testUserCursor(); + testLocalCursor(); + testUserCursorOverride(); + testMultipleLocalCursors(); + } + + /// + /// Returns input back to the user. + /// + private void returnUserInput() + { + AddStep("Return user input", () => inputManager.UseParentState = true); + } + + /// + /// -- 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. + /// + 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)); + } + + /// + /// -- 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. + /// + 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)); + } + + /// + /// -- 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. + /// + 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)); + } + + /// + /// -- Yellow-Purple Box Boundary -- + /// Tests whether multiple local cursors (purple + yellow) may be visible and at the mouse position at the same time. + /// + 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)); + } + + /// + /// -- Yellow-Blue Box Boundary -- + /// Tests whether a local cursor (yellow) may be displayed along with a user cursor override (blue). + /// + 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)); + } + + /// + /// Moves the cursor to a point not covered by any cursor containers. + /// + private void moveOut() + => inputManager.MoveMouseTo(new Vector2(inputManager.ScreenSpaceDrawQuad.Centre.X, inputManager.ScreenSpaceDrawQuad.TopLeft.Y)); + + /// + /// Checks if a cursor is visible. + /// + /// The cursor to check. + private bool checkVisible(CursorContainer cursorContainer) => cursorContainer.State == Visibility.Visible; + + /// + /// Checks if a cursor is at the current inputmanager screen position. + /// + /// The cursor to check. + private bool checkAtMouse(CursorContainer cursorContainer) + => Precision.AlmostEquals(inputManager.CurrentState.Mouse.NativeState.Position, cursorContainer.ToScreenSpace(cursorContainer.ActiveCursor.DrawPosition)); + + private class CustomCursorBox : Container, IProvideCursor + { + public CursorContainer Cursor { get; } + public bool ProvidingUserCursor { get; } + + public CustomCursorBox(Color4 cursorColour, bool providesUserCursor = true) + { + ProvidingUserCursor = providesUserCursor; + + Colour = cursorColour; + Masking = true; + + Children = new Drawable[] + { + 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, + } + }; + } + } + + 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 }; + } + } + } + } +} diff --git a/osu.Game.Tests/osu.Game.Tests.csproj b/osu.Game.Tests/osu.Game.Tests.csproj index 2eb79f6b35..76b426bf5d 100644 --- a/osu.Game.Tests/osu.Game.Tests.csproj +++ b/osu.Game.Tests/osu.Game.Tests.csproj @@ -104,6 +104,7 @@ + From 4f7ccb8d939878b3646648348de917e10ab97bc9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 16 Jan 2018 18:38:47 +0900 Subject: [PATCH 04/11] Update framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index 49b563e2cf..95bd66da12 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 49b563e2cf170eb19006b98dd5b69c2398362d9e +Subproject commit 95bd66da12276f39335873972f713774306b4894 From 1174f344896a2670d41cabf79fda5b191572bbcb Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 16 Jan 2018 20:21:09 +0900 Subject: [PATCH 05/11] Update framework post-merge --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index 95bd66da12..023a0abe17 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 95bd66da12276f39335873972f713774306b4894 +Subproject commit 023a0abe17490a118fe1ca85ea487462bff4277e From 39af9321cf3e1957a92d4bd233d7b00ca0a555a2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 16 Jan 2018 20:29:11 +0900 Subject: [PATCH 06/11] Remove unnecessary overrides --- osu.Game/Screens/Play/GameplayMenuOverlay.cs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/osu.Game/Screens/Play/GameplayMenuOverlay.cs b/osu.Game/Screens/Play/GameplayMenuOverlay.cs index 8fa76e2e51..615c124ea7 100644 --- a/osu.Game/Screens/Play/GameplayMenuOverlay.cs +++ b/osu.Game/Screens/Play/GameplayMenuOverlay.cs @@ -142,10 +142,6 @@ namespace osu.Game.Screens.Play } } - public override bool HandleKeyboardInput => handleInput; - public override bool HandleMouseInput => handleInput; - private bool handleInput => State == Visibility.Visible; - protected override void PopIn() => this.FadeIn(transition_duration, Easing.In); protected override void PopOut() => this.FadeOut(transition_duration, Easing.In); From e7a0a024664ee09989e308a08928c435ed21d680 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 16 Jan 2018 20:29:28 +0900 Subject: [PATCH 07/11] Don't limit keyboard input based on menu button scale --- osu.Game/Screens/Menu/Button.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Menu/Button.cs b/osu.Game/Screens/Menu/Button.cs index fff2435cb4..268be51347 100644 --- a/osu.Game/Screens/Menu/Button.cs +++ b/osu.Game/Screens/Menu/Button.cs @@ -222,9 +222,8 @@ namespace osu.Game.Screens.Menu boxHoverLayer.FadeOut(800, Easing.OutExpo); } - public override bool HandleKeyboardInput => handleInput; - public override bool HandleMouseInput => handleInput; - private 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() { From 5e1cd8ddc4c569c07ed31d69d1ed80eff93e6ee3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 16 Jan 2018 20:34:14 +0900 Subject: [PATCH 08/11] Apply conditionals directly rather than using an in-between property --- osu.Game/Graphics/UserInterface/BreadcrumbControl.cs | 6 +++--- osu.Game/Overlays/Profile/ProfileHeader.cs | 5 ++--- osu.Game/Overlays/Toolbar/ToolbarModeSelector.cs | 5 ++--- osu.Game/Screens/Menu/ButtonSystem.cs | 5 ++--- osu.Game/Screens/Play/KeyCounterCollection.cs | 5 ++--- 5 files changed, 11 insertions(+), 15 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/BreadcrumbControl.cs b/osu.Game/Graphics/UserInterface/BreadcrumbControl.cs index 566254886e..5ee0aba9cf 100644 --- a/osu.Game/Graphics/UserInterface/BreadcrumbControl.cs +++ b/osu.Game/Graphics/UserInterface/BreadcrumbControl.cs @@ -42,9 +42,9 @@ namespace osu.Game.Graphics.UserInterface //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 HandleKeyboardInput => handleInput; - public override bool HandleMouseInput => handleInput; - private bool handleInput => State == Visibility.Visible; + + public override bool HandleKeyboardInput => State == Visibility.Visible; + public override bool HandleMouseInput => State == Visibility.Visible; private Visibility state; diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index c4819c5bc7..924b5d6c9d 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -489,9 +489,8 @@ namespace osu.Game.Overlays.Profile { private readonly OsuHoverContainer content; - public override bool HandleKeyboardInput => handleInput; - public override bool HandleMouseInput => handleInput; - private bool handleInput => content.Action != null; + public override bool HandleKeyboardInput => content.Action != null; + public override bool HandleMouseInput => content.Action != null; protected override Container Content => content ?? (Container)this; diff --git a/osu.Game/Overlays/Toolbar/ToolbarModeSelector.cs b/osu.Game/Overlays/Toolbar/ToolbarModeSelector.cs index 2acc1075a3..6d58c78c37 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarModeSelector.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarModeSelector.cs @@ -87,9 +87,8 @@ namespace osu.Game.Overlays.Toolbar ruleset.Value = rulesets.AvailableRulesets.FirstOrDefault(); } - public override bool HandleKeyboardInput => handleInput; - public override bool HandleMouseInput => handleInput; - private 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); diff --git a/osu.Game/Screens/Menu/ButtonSystem.cs b/osu.Game/Screens/Menu/ButtonSystem.cs index a45f4429c4..72c26af2a6 100644 --- a/osu.Game/Screens/Menu/ButtonSystem.cs +++ b/osu.Game/Screens/Menu/ButtonSystem.cs @@ -199,9 +199,8 @@ namespace osu.Game.Screens.Menu private MenuState state; - public override bool HandleKeyboardInput => handleInput; - public override bool HandleMouseInput => handleInput; - private bool handleInput=> state != MenuState.Exit; + public override bool HandleKeyboardInput => state != MenuState.Exit; + public override bool HandleMouseInput => state != MenuState.Exit; public MenuState State { diff --git a/osu.Game/Screens/Play/KeyCounterCollection.cs b/osu.Game/Screens/Play/KeyCounterCollection.cs index c716841861..e40776ae4a 100644 --- a/osu.Game/Screens/Play/KeyCounterCollection.cs +++ b/osu.Game/Screens/Play/KeyCounterCollection.cs @@ -111,9 +111,8 @@ namespace osu.Game.Screens.Play } } - public override bool HandleKeyboardInput => handleInput; - public override bool HandleMouseInput => handleInput; - private bool handleInput => receptor == null; + public override bool HandleKeyboardInput => receptor == null; + public override bool HandleMouseInput => receptor == null; private Receptor receptor; From a5415b99aecb21ed74f8c9feb048288878325cf2 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 16 Jan 2018 20:35:07 +0900 Subject: [PATCH 09/11] Visualise the hovered drawabe --- osu.Game.Tests/Visual/TestCaseCursors.cs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/TestCaseCursors.cs b/osu.Game.Tests/Visual/TestCaseCursors.cs index e0ce5fad77..20e6103436 100644 --- a/osu.Game.Tests/Visual/TestCaseCursors.cs +++ b/osu.Game.Tests/Visual/TestCaseCursors.cs @@ -5,6 +5,7 @@ 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; @@ -198,6 +199,8 @@ namespace osu.Game.Tests.Visual public CursorContainer Cursor { get; } public bool ProvidingUserCursor { get; } + private readonly Box background; + public CustomCursorBox(Color4 cursorColour, bool providesUserCursor = true) { ProvidingUserCursor = providesUserCursor; @@ -207,7 +210,7 @@ namespace osu.Game.Tests.Visual Children = new Drawable[] { - new Box + background = new Box { RelativeSizeAxes = Axes.Both, Alpha = 0.1f @@ -224,6 +227,18 @@ namespace osu.Game.Tests.Visual } }; } + + 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 From 06f0f2093c71f678b61faa4d9aef4748694b7f47 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 16 Jan 2018 20:35:39 +0900 Subject: [PATCH 10/11] Add a sample way to have local cursors move beyond their bounds --- osu.Game.Tests/Visual/TestCaseCursors.cs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/osu.Game.Tests/Visual/TestCaseCursors.cs b/osu.Game.Tests/Visual/TestCaseCursors.cs index 20e6103436..363f6b53f0 100644 --- a/osu.Game.Tests/Visual/TestCaseCursors.cs +++ b/osu.Game.Tests/Visual/TestCaseCursors.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // 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; @@ -81,10 +82,14 @@ namespace osu.Game.Tests.Visual }; returnUserInput(); + + AddToggleStep("Smooth transitions", b => cursorBoxes.ForEach(box => box.SmoothTransition = b)); + testUserCursor(); testLocalCursor(); testUserCursorOverride(); testMultipleLocalCursors(); + returnUserInput(); } /// @@ -196,9 +201,13 @@ namespace osu.Game.Tests.Visual 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) From 87d2cce61d3aaf1d1da59d4ee330660c2987a81b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 17 Jan 2018 00:47:14 +0900 Subject: [PATCH 11/11] Update framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index 023a0abe17..8f36ddab94 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 023a0abe17490a118fe1ca85ea487462bff4277e +Subproject commit 8f36ddab946ff538620081ede7719461d4732b79