diff --git a/osu.Game.Tests/Visual/Gameplay/TestScenePause.cs b/osu.Game.Tests/Visual/Gameplay/TestScenePause.cs index 5bd0a29308..71cc1f7b23 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestScenePause.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestScenePause.cs @@ -31,7 +31,7 @@ namespace osu.Game.Tests.Visual.Gameplay public TestScenePause() { - base.Content.Add(content = new MenuCursorContainer { RelativeSizeAxes = Axes.Both }); + base.Content.Add(content = new GlobalCursorDisplay { RelativeSizeAxes = Axes.Both }); } [SetUpSteps] diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneCursors.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneCursors.cs index 0fa7c5303c..bcbe146456 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneCursors.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneCursors.cs @@ -21,12 +21,12 @@ namespace osu.Game.Tests.Visual.UserInterface [TestFixture] public class TestSceneCursors : OsuManualInputManagerTestScene { - private readonly MenuCursorContainer menuCursorContainer; + private readonly GlobalCursorDisplay globalCursorDisplay; private readonly CustomCursorBox[] cursorBoxes = new CustomCursorBox[6]; public TestSceneCursors() { - Child = menuCursorContainer = new MenuCursorContainer + Child = globalCursorDisplay = new GlobalCursorDisplay { RelativeSizeAxes = Axes.Both, Children = new[] @@ -96,11 +96,11 @@ namespace osu.Game.Tests.Visual.UserInterface 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)); + AddAssert("Check green cursor visible", () => checkVisible(cursorBoxes[0].MenuCursor)); + AddAssert("Check green cursor at mouse", () => checkAtMouse(cursorBoxes[0].MenuCursor)); AddStep("Move out", moveOut); - AddAssert("Check green cursor invisible", () => !checkVisible(cursorBoxes[0].Cursor)); - AddAssert("Check global cursor visible", () => checkVisible(menuCursorContainer.Cursor)); + AddAssert("Check green cursor invisible", () => !checkVisible(cursorBoxes[0].MenuCursor)); + AddAssert("Check global cursor visible", () => checkVisible(globalCursorDisplay.MenuCursor)); } /// @@ -111,13 +111,13 @@ namespace osu.Game.Tests.Visual.UserInterface 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(menuCursorContainer.Cursor)); - AddAssert("Check global cursor at mouse", () => checkAtMouse(menuCursorContainer.Cursor)); + AddAssert("Check purple cursor visible", () => checkVisible(cursorBoxes[3].MenuCursor)); + AddAssert("Check purple cursor at mouse", () => checkAtMouse(cursorBoxes[3].MenuCursor)); + AddAssert("Check global cursor visible", () => checkVisible(globalCursorDisplay.MenuCursor)); + AddAssert("Check global cursor at mouse", () => checkAtMouse(globalCursorDisplay.MenuCursor)); AddStep("Move out", moveOut); - AddAssert("Check purple cursor visible", () => checkVisible(cursorBoxes[3].Cursor)); - AddAssert("Check global cursor visible", () => checkVisible(menuCursorContainer.Cursor)); + AddAssert("Check purple cursor visible", () => checkVisible(cursorBoxes[3].MenuCursor)); + AddAssert("Check global cursor visible", () => checkVisible(globalCursorDisplay.MenuCursor)); } /// @@ -128,12 +128,12 @@ namespace osu.Game.Tests.Visual.UserInterface 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)); + AddAssert("Check blue cursor visible", () => checkVisible(cursorBoxes[1].MenuCursor)); + AddAssert("Check green cursor invisible", () => !checkVisible(cursorBoxes[0].MenuCursor)); + AddAssert("Check blue cursor at mouse", () => checkAtMouse(cursorBoxes[1].MenuCursor)); AddStep("Move out", moveOut); - AddAssert("Check blue cursor not visible", () => !checkVisible(cursorBoxes[1].Cursor)); - AddAssert("Check green cursor not visible", () => !checkVisible(cursorBoxes[0].Cursor)); + AddAssert("Check blue cursor not visible", () => !checkVisible(cursorBoxes[1].MenuCursor)); + AddAssert("Check green cursor not visible", () => !checkVisible(cursorBoxes[0].MenuCursor)); } /// @@ -143,13 +143,13 @@ namespace osu.Game.Tests.Visual.UserInterface 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)); + AddAssert("Check purple cursor visible", () => checkVisible(cursorBoxes[3].MenuCursor)); + AddAssert("Check purple cursor at mouse", () => checkAtMouse(cursorBoxes[3].MenuCursor)); + AddAssert("Check yellow cursor visible", () => checkVisible(cursorBoxes[5].MenuCursor)); + AddAssert("Check yellow cursor at mouse", () => checkAtMouse(cursorBoxes[5].MenuCursor)); AddStep("Move out", moveOut); - AddAssert("Check purple cursor visible", () => checkVisible(cursorBoxes[3].Cursor)); - AddAssert("Check yellow cursor visible", () => checkVisible(cursorBoxes[5].Cursor)); + AddAssert("Check purple cursor visible", () => checkVisible(cursorBoxes[3].MenuCursor)); + AddAssert("Check yellow cursor visible", () => checkVisible(cursorBoxes[5].MenuCursor)); } /// @@ -159,13 +159,13 @@ namespace osu.Game.Tests.Visual.UserInterface 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)); + AddAssert("Check blue cursor visible", () => checkVisible(cursorBoxes[1].MenuCursor)); + AddAssert("Check blue cursor at mouse", () => checkAtMouse(cursorBoxes[1].MenuCursor)); + AddAssert("Check yellow cursor visible", () => checkVisible(cursorBoxes[5].MenuCursor)); + AddAssert("Check yellow cursor at mouse", () => checkAtMouse(cursorBoxes[5].MenuCursor)); AddStep("Move out", moveOut); - AddAssert("Check blue cursor invisible", () => !checkVisible(cursorBoxes[1].Cursor)); - AddAssert("Check yellow cursor visible", () => checkVisible(cursorBoxes[5].Cursor)); + AddAssert("Check blue cursor invisible", () => !checkVisible(cursorBoxes[1].MenuCursor)); + AddAssert("Check yellow cursor visible", () => checkVisible(cursorBoxes[5].MenuCursor)); } /// @@ -191,7 +191,7 @@ namespace osu.Game.Tests.Visual.UserInterface { public bool SmoothTransition; - public CursorContainer Cursor { get; } + public CursorContainer MenuCursor { get; } public bool ProvidingUserCursor { get; } public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => base.ReceivePositionalInputAt(screenSpacePos) || (SmoothTransition && !ProvidingUserCursor); @@ -218,7 +218,7 @@ namespace osu.Game.Tests.Visual.UserInterface Origin = Anchor.Centre, Text = providesUserCursor ? "User cursor" : "Local cursor" }, - Cursor = new TestCursorContainer + MenuCursor = new TestCursorContainer { State = { Value = providesUserCursor ? Visibility.Hidden : Visibility.Visible }, } diff --git a/osu.Game.Tournament/TournamentGameBase.cs b/osu.Game.Tournament/TournamentGameBase.cs index 063b62bf08..1861e39c60 100644 --- a/osu.Game.Tournament/TournamentGameBase.cs +++ b/osu.Game.Tournament/TournamentGameBase.cs @@ -70,10 +70,10 @@ namespace osu.Game.Tournament protected override void LoadComplete() { - MenuCursorContainer.Cursor.AlwaysPresent = true; // required for tooltip display + GlobalCursorDisplay.MenuCursor.AlwaysPresent = true; // required for tooltip display // we don't want to show the menu cursor as it would appear on stream output. - MenuCursorContainer.Cursor.Alpha = 0; + GlobalCursorDisplay.MenuCursor.Alpha = 0; base.LoadComplete(); diff --git a/osu.Game/Graphics/Cursor/MenuCursorContainer.cs b/osu.Game/Graphics/Cursor/GlobalCursorDisplay.cs similarity index 52% rename from osu.Game/Graphics/Cursor/MenuCursorContainer.cs rename to osu.Game/Graphics/Cursor/GlobalCursorDisplay.cs index e03dc4df6f..6613e18cbe 100644 --- a/osu.Game/Graphics/Cursor/MenuCursorContainer.cs +++ b/osu.Game/Graphics/Cursor/GlobalCursorDisplay.cs @@ -1,8 +1,6 @@ // 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 osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -15,48 +13,48 @@ using osu.Game.Configuration; namespace osu.Game.Graphics.Cursor { /// - /// A container which provides a . - /// It also handles cases where a more localised cursor is provided by another component (via ). + /// A container which provides the main . + /// Also handles cases where a more localised cursor is provided by another component (via ). /// - public class MenuCursorContainer : Container, IProvideCursor + public class GlobalCursorDisplay : Container, IProvideCursor { - protected override Container Content => content; - private readonly Container content; - /// - /// Whether any cursors can be displayed. + /// Control whether any cursor should be displayed. /// - internal bool CanShowCursor = true; + internal bool ShowCursor = true; + + public CursorContainer MenuCursor { get; } - public CursorContainer Cursor { get; } public bool ProvidingUserCursor => true; - public MenuCursorContainer() + protected override Container Content { get; } = new Container { RelativeSizeAxes = Axes.Both }; + + private Bindable showDuringTouch = null!; + + private InputManager inputManager = null!; + + private IProvideCursor? currentOverrideProvider; + + [Resolved] + private OsuConfigManager config { get; set; } = null!; + + public GlobalCursorDisplay() { AddRangeInternal(new Drawable[] { - Cursor = new MenuCursor { State = { Value = Visibility.Hidden } }, - content = new Container { RelativeSizeAxes = Axes.Both } + MenuCursor = new MenuCursor { State = { Value = Visibility.Hidden } }, + Content = new Container { RelativeSizeAxes = Axes.Both } }); } - private Bindable showDuringTouch; - - private InputManager inputManager; - - [Resolved] - private OsuConfigManager config { get; set; } - protected override void LoadComplete() { base.LoadComplete(); - inputManager = GetContainingInputManager(); + inputManager = GetContainingInputManager(); showDuringTouch = config.GetBindable(OsuSetting.GameplayCursorDuringTouch); } - private IProvideCursor currentTarget; - protected override void Update() { base.Update(); @@ -64,31 +62,31 @@ namespace osu.Game.Graphics.Cursor var lastMouseSource = inputManager.CurrentState.Mouse.LastSource; bool hasValidInput = lastMouseSource != null && (showDuringTouch.Value || lastMouseSource is not ISourcedFromTouch); - if (!hasValidInput || !CanShowCursor) + if (!hasValidInput || !ShowCursor) { - currentTarget?.Cursor?.Hide(); - currentTarget = null; + currentOverrideProvider?.MenuCursor?.Hide(); + currentOverrideProvider = null; return; } - IProvideCursor newTarget = this; + IProvideCursor newOverrideProvider = this; foreach (var d in inputManager.HoveredDrawables) { if (d is IProvideCursor p && p.ProvidingUserCursor) { - newTarget = p; + newOverrideProvider = p; break; } } - if (currentTarget == newTarget) + if (currentOverrideProvider == newOverrideProvider) return; - currentTarget?.Cursor?.Hide(); - newTarget.Cursor?.Show(); + currentOverrideProvider?.MenuCursor?.Hide(); + newOverrideProvider.MenuCursor?.Show(); - currentTarget = newTarget; + currentOverrideProvider = newOverrideProvider; } } } diff --git a/osu.Game/Graphics/Cursor/IProvideCursor.cs b/osu.Game/Graphics/Cursor/IProvideCursor.cs index 9f01e5da6d..f7f7b75bc8 100644 --- a/osu.Game/Graphics/Cursor/IProvideCursor.cs +++ b/osu.Game/Graphics/Cursor/IProvideCursor.cs @@ -17,10 +17,10 @@ namespace osu.Game.Graphics.Cursor /// The cursor provided by this . /// May be null if no cursor should be visible. /// - CursorContainer Cursor { get; } + CursorContainer MenuCursor { get; } /// - /// Whether should be displayed as the singular user cursor. This will temporarily hide any other user cursor. + /// Whether should be displayed as the singular user cursor. This will temporarily hide any other user cursor. /// This value is checked every frame and may be used to control whether multiple cursors are displayed (e.g. watching replays). /// bool ProvidingUserCursor { get; } diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 4f08511783..1ee53e2848 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -716,7 +716,7 @@ namespace osu.Game // 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 - MenuCursorContainer.CanShowCursor = menuScreen?.CursorVisible ?? false; + GlobalCursorDisplay.ShowCursor = menuScreen?.CursorVisible ?? false; // todo: all archive managers should be able to be looped here. SkinManager.PostNotification = n => Notifications.Post(n); @@ -1231,7 +1231,7 @@ namespace osu.Game ScreenOffsetContainer.X = horizontalOffset; overlayContent.X = horizontalOffset * 1.2f; - MenuCursorContainer.CanShowCursor = (ScreenStack.CurrentScreen as IOsuScreen)?.CursorVisible ?? false; + GlobalCursorDisplay.ShowCursor = (ScreenStack.CurrentScreen as IOsuScreen)?.CursorVisible ?? false; } private void screenChanged(IScreen current, IScreen newScreen) diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 3b81b5c8cd..7b6cda17a2 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -138,7 +138,7 @@ namespace osu.Game protected RealmKeyBindingStore KeyBindingStore { get; private set; } - protected MenuCursorContainer MenuCursorContainer { get; private set; } + protected GlobalCursorDisplay GlobalCursorDisplay { get; private set; } protected MusicController MusicController { get; private set; } @@ -340,10 +340,10 @@ namespace osu.Game RelativeSizeAxes = Axes.Both, Child = CreateScalingContainer().WithChildren(new Drawable[] { - (MenuCursorContainer = new MenuCursorContainer + (GlobalCursorDisplay = new GlobalCursorDisplay { RelativeSizeAxes = Axes.Both - }).WithChild(content = new OsuTooltipContainer(MenuCursorContainer.Cursor) + }).WithChild(content = new OsuTooltipContainer(GlobalCursorDisplay.MenuCursor) { RelativeSizeAxes = Axes.Both }), diff --git a/osu.Game/Rulesets/UI/DrawableRuleset.cs b/osu.Game/Rulesets/UI/DrawableRuleset.cs index 95cb02c477..f7f62d2af0 100644 --- a/osu.Game/Rulesets/UI/DrawableRuleset.cs +++ b/osu.Game/Rulesets/UI/DrawableRuleset.cs @@ -380,7 +380,7 @@ namespace osu.Game.Rulesets.UI // only show the cursor when within the playfield, by default. public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => Playfield.ReceivePositionalInputAt(screenSpacePos); - CursorContainer IProvideCursor.Cursor => Playfield.Cursor; + CursorContainer IProvideCursor.MenuCursor => Playfield.Cursor; public override GameplayCursorContainer Cursor => Playfield.Cursor; diff --git a/osu.Game/Screens/Utility/LatencyArea.cs b/osu.Game/Screens/Utility/LatencyArea.cs index b7d45ba642..c8e0bf93a2 100644 --- a/osu.Game/Screens/Utility/LatencyArea.cs +++ b/osu.Game/Screens/Utility/LatencyArea.cs @@ -36,7 +36,7 @@ namespace osu.Game.Screens.Utility public readonly Bindable VisualMode = new Bindable(); - public CursorContainer? Cursor { get; private set; } + public CursorContainer? MenuCursor { get; private set; } public bool ProvidingUserCursor => IsActiveArea.Value; @@ -91,7 +91,7 @@ namespace osu.Game.Screens.Utility { RelativeSizeAxes = Axes.Both, }, - Cursor = new LatencyCursorContainer + MenuCursor = new LatencyCursorContainer { RelativeSizeAxes = Axes.Both, }, @@ -105,7 +105,7 @@ namespace osu.Game.Screens.Utility { RelativeSizeAxes = Axes.Both, }, - Cursor = new LatencyCursorContainer + MenuCursor = new LatencyCursorContainer { RelativeSizeAxes = Axes.Both, }, @@ -119,7 +119,7 @@ namespace osu.Game.Screens.Utility { RelativeSizeAxes = Axes.Both, }, - Cursor = new LatencyCursorContainer + MenuCursor = new LatencyCursorContainer { RelativeSizeAxes = Axes.Both, }, diff --git a/osu.Game/Tests/Visual/OsuManualInputManagerTestScene.cs b/osu.Game/Tests/Visual/OsuManualInputManagerTestScene.cs index eccd2efa96..9082ca9c58 100644 --- a/osu.Game/Tests/Visual/OsuManualInputManagerTestScene.cs +++ b/osu.Game/Tests/Visual/OsuManualInputManagerTestScene.cs @@ -38,11 +38,11 @@ namespace osu.Game.Tests.Visual protected OsuManualInputManagerTestScene() { - MenuCursorContainer cursorContainer; + GlobalCursorDisplay cursorDisplay; - CompositeDrawable mainContent = cursorContainer = new MenuCursorContainer { RelativeSizeAxes = Axes.Both }; + CompositeDrawable mainContent = cursorDisplay = new GlobalCursorDisplay { RelativeSizeAxes = Axes.Both }; - cursorContainer.Child = content = new OsuTooltipContainer(cursorContainer.Cursor) + cursorDisplay.Child = content = new OsuTooltipContainer(cursorDisplay.MenuCursor) { RelativeSizeAxes = Axes.Both };