From 067ff0e0ad4051ceaa7a8726d8f38d3ce884a8d6 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 6 Aug 2021 18:38:14 +0300 Subject: [PATCH 01/17] Store last opened settings subpanel rather than relying on LINQ --- osu.Game/Overlays/SettingsOverlay.cs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/osu.Game/Overlays/SettingsOverlay.cs b/osu.Game/Overlays/SettingsOverlay.cs index 54b780615d..050502b3be 100644 --- a/osu.Game/Overlays/SettingsOverlay.cs +++ b/osu.Game/Overlays/SettingsOverlay.cs @@ -9,7 +9,6 @@ using osu.Game.Overlays.Settings.Sections; using osu.Game.Overlays.Settings.Sections.Input; using osuTK.Graphics; using System.Collections.Generic; -using System.Linq; using osu.Framework.Bindables; using osu.Framework.Localisation; using osu.Game.Localisation; @@ -38,6 +37,8 @@ namespace osu.Game.Overlays private readonly List subPanels = new List(); + private SettingsSubPanel lastOpenedSubPanel; + protected override Drawable CreateHeader() => new SettingsHeader(Title, Description); protected override Drawable CreateFooter() => new SettingsFooter(); @@ -46,21 +47,21 @@ namespace osu.Game.Overlays { } - public override bool AcceptsFocus => subPanels.All(s => s.State.Value != Visibility.Visible); + public override bool AcceptsFocus => lastOpenedSubPanel == null || lastOpenedSubPanel.State.Value == Visibility.Hidden; private T createSubPanel(T subPanel) where T : SettingsSubPanel { subPanel.Depth = 1; subPanel.Anchor = Anchor.TopRight; - subPanel.State.ValueChanged += subPanelStateChanged; + subPanel.State.ValueChanged += e => subPanelStateChanged(subPanel, e); subPanels.Add(subPanel); return subPanel; } - private void subPanelStateChanged(ValueChangedEvent state) + private void subPanelStateChanged(SettingsSubPanel panel, ValueChangedEvent state) { switch (state.NewValue) { @@ -69,6 +70,8 @@ namespace osu.Game.Overlays SectionsContainer.FadeOut(300, Easing.OutQuint); ContentContainer.MoveToX(-WIDTH, 500, Easing.OutQuint); + + lastOpenedSubPanel = panel; break; case Visibility.Hidden: @@ -80,7 +83,7 @@ namespace osu.Game.Overlays } } - protected override float ExpandedPosition => subPanels.Any(s => s.State.Value == Visibility.Visible) ? -WIDTH : base.ExpandedPosition; + protected override float ExpandedPosition => lastOpenedSubPanel?.State.Value == Visibility.Visible ? -WIDTH : base.ExpandedPosition; [BackgroundDependencyLoader] private void load() From 8e8e0fb8d8c9abce26fe64a0098507c8967d0739 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 6 Aug 2021 18:36:43 +0300 Subject: [PATCH 02/17] Add placement-dependent horizontal screen offset properties --- osu.Game/Overlays/NotificationOverlay.cs | 5 +++++ osu.Game/Overlays/SettingsOverlay.cs | 2 ++ osu.Game/Overlays/SettingsPanel.cs | 6 ++++++ 3 files changed, 13 insertions(+) diff --git a/osu.Game/Overlays/NotificationOverlay.cs b/osu.Game/Overlays/NotificationOverlay.cs index b26e17b34c..af4f41901f 100644 --- a/osu.Game/Overlays/NotificationOverlay.cs +++ b/osu.Game/Overlays/NotificationOverlay.cs @@ -30,6 +30,11 @@ namespace osu.Game.Overlays private FlowContainer sections; + /// + /// A horizontal offset to apply to the game-wide screen. + /// + public float HorizontalScreenOffset => -width + X; + /// /// Provide a source for the toolbar height. /// diff --git a/osu.Game/Overlays/SettingsOverlay.cs b/osu.Game/Overlays/SettingsOverlay.cs index 050502b3be..9ed1d950e3 100644 --- a/osu.Game/Overlays/SettingsOverlay.cs +++ b/osu.Game/Overlays/SettingsOverlay.cs @@ -21,6 +21,8 @@ namespace osu.Game.Overlays public LocalisableString Title => SettingsStrings.HeaderTitle; public LocalisableString Description => SettingsStrings.HeaderDescription; + public override float HorizontalScreenOffset => base.HorizontalScreenOffset + (lastOpenedSubPanel?.HorizontalScreenOffset ?? 0f); + protected override IEnumerable CreateSections() => new SettingsSection[] { new GeneralSection(), diff --git a/osu.Game/Overlays/SettingsPanel.cs b/osu.Game/Overlays/SettingsPanel.cs index eae828c142..2916ea013f 100644 --- a/osu.Game/Overlays/SettingsPanel.cs +++ b/osu.Game/Overlays/SettingsPanel.cs @@ -34,6 +34,11 @@ namespace osu.Game.Overlays protected override Container Content => ContentContainer; + /// + /// A horizontal offset to apply to the game-wide screen. + /// + public virtual float HorizontalScreenOffset => (WIDTH + Content?.X) ?? 0f; + protected Sidebar Sidebar; private SidebarButton selectedSidebarButton; @@ -64,6 +69,7 @@ namespace osu.Game.Overlays { InternalChild = ContentContainer = new NonMaskedContent { + X = -WIDTH + ExpandedPosition, Width = WIDTH, RelativeSizeAxes = Axes.Y, Children = new Drawable[] From f77037ef57d6df00845867ae436ceb77e3f525dd Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 6 Aug 2021 18:38:48 +0300 Subject: [PATCH 03/17] Replace state-based screen offsetting logic with `HorizontalScreenOffset`s --- osu.Game/OsuGame.cs | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 3cfa2cc755..85428a12e3 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -828,21 +828,6 @@ namespace osu.Game { if (mode.NewValue != OverlayActivation.All) CloseAllOverlays(); }; - - void updateScreenOffset() - { - float offset = 0; - - if (Settings.State.Value == Visibility.Visible) - offset += Toolbar.HEIGHT / 2; - if (notifications.State.Value == Visibility.Visible) - offset -= Toolbar.HEIGHT / 2; - - screenOffsetContainer.MoveToX(offset, SettingsPanel.TRANSITION_LENGTH, Easing.OutQuint); - } - - Settings.State.ValueChanged += _ => updateScreenOffset(); - notifications.State.ValueChanged += _ => updateScreenOffset(); } private void showOverlayAboveOthers(OverlayContainer overlay, OverlayContainer[] otherOverlays) @@ -1026,6 +1011,9 @@ namespace osu.Game screenOffsetContainer.Padding = new MarginPadding { Top = ToolbarOffset }; overlayContent.Padding = new MarginPadding { Top = ToolbarOffset }; + screenOffsetContainer.X = Settings.HorizontalScreenOffset * 0.125f + + notifications.HorizontalScreenOffset * 0.125f; + MenuCursorContainer.CanShowCursor = (ScreenStack.CurrentScreen as IOsuScreen)?.CursorVisible ?? false; } From ac157f6cef91f35252599059451fa315819180cf Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 6 Aug 2021 22:10:03 +0300 Subject: [PATCH 04/17] Fix settings panel children not processing transforms while masked away --- osu.Game/Overlays/SettingsPanel.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/osu.Game/Overlays/SettingsPanel.cs b/osu.Game/Overlays/SettingsPanel.cs index 2916ea013f..79d78e6805 100644 --- a/osu.Game/Overlays/SettingsPanel.cs +++ b/osu.Game/Overlays/SettingsPanel.cs @@ -34,6 +34,12 @@ namespace osu.Game.Overlays protected override Container Content => ContentContainer; + /// + /// The always needs to be present for to process transforms while overlay is masked away. + /// todo: there may be a better solution for this and the existing , likely requires a refactor. + /// + public override bool IsPresent => true; + /// /// A horizontal offset to apply to the game-wide screen. /// From 8dc0650ca71d9143d0268268a6f21f826d658679 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 6 Aug 2021 22:36:40 +0300 Subject: [PATCH 05/17] Add test coverage --- .../Visual/Menus/TestSceneSideOverlays.cs | 62 +++++++++++++++++++ .../Visual/Navigation/OsuGameTestScene.cs | 7 ++- osu.Game/OsuGame.cs | 33 +++++----- osu.Game/Overlays/NotificationOverlay.cs | 8 +-- 4 files changed, 90 insertions(+), 20 deletions(-) create mode 100644 osu.Game.Tests/Visual/Menus/TestSceneSideOverlays.cs diff --git a/osu.Game.Tests/Visual/Menus/TestSceneSideOverlays.cs b/osu.Game.Tests/Visual/Menus/TestSceneSideOverlays.cs new file mode 100644 index 0000000000..34259574f3 --- /dev/null +++ b/osu.Game.Tests/Visual/Menus/TestSceneSideOverlays.cs @@ -0,0 +1,62 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Linq; +using NUnit.Framework; +using osu.Framework.Graphics.Containers; +using osu.Framework.Testing; +using osu.Game.Overlays; +using osu.Game.Overlays.Settings.Sections.Input; +using osu.Game.Tests.Visual.Navigation; + +namespace osu.Game.Tests.Visual.Menus +{ + public class TestSceneSideOverlays : OsuGameTestScene + { + [SetUpSteps] + public override void SetUpSteps() + { + base.SetUpSteps(); + + AddAssert("no screen offset applied", () => Game.ScreenOffsetContainer.X == 0f); + } + + [Test] + public void TestScreenOffsettingOnSettingsOverlay() + { + AddStep("open settings", () => Game.Settings.Show()); + AddUntilStep("right screen offset applied", () => Game.ScreenOffsetContainer.X == SettingsPanel.WIDTH * OsuGame.SCREEN_OFFSET_RATIO); + + AddStep("hide settings", () => Game.Settings.Hide()); + AddUntilStep("screen offset removed", () => Game.ScreenOffsetContainer.X == 0f); + } + + [Test] + public void TestScreenOffsettingAccountsForKeyBindingPanel() + { + AddStep("open settings", () => Game.Settings.Show()); + AddStep("open key binding panel", () => Game.Settings.ChildrenOfType().Single().Show()); + AddUntilStep("right screen offset applied", () => Game.ScreenOffsetContainer.X == SettingsPanel.WIDTH * OsuGame.SCREEN_OFFSET_RATIO); + + AddStep("hide key binding", () => Game.Settings.ChildrenOfType().Single().Show()); + AddUntilStep("right screen offset still applied", () => Game.ScreenOffsetContainer.X == SettingsPanel.WIDTH * OsuGame.SCREEN_OFFSET_RATIO); + + AddStep("open key binding", () => Game.Settings.Show()); + AddUntilStep("right screen offset still applied", () => Game.ScreenOffsetContainer.X == SettingsPanel.WIDTH * OsuGame.SCREEN_OFFSET_RATIO); + + AddStep("hide settings", () => Game.Settings.Hide()); + AddAssert("key binding panel still open", () => Game.Settings.ChildrenOfType().Single().State.Value == Visibility.Visible); + AddUntilStep("screen offset removed", () => Game.ScreenOffsetContainer.X == 0f); + } + + [Test] + public void TestScreenOffsettingOnNotificationOverlay() + { + AddStep("open notifications", () => Game.Notifications.Show()); + AddUntilStep("right screen offset applied", () => Game.ScreenOffsetContainer.X == -NotificationOverlay.WIDTH * OsuGame.SCREEN_OFFSET_RATIO); + + AddStep("hide notifications", () => Game.Notifications.Hide()); + AddUntilStep("screen offset removed", () => Game.ScreenOffsetContainer.X == 0f); + } + } +} diff --git a/osu.Game.Tests/Visual/Navigation/OsuGameTestScene.cs b/osu.Game.Tests/Visual/Navigation/OsuGameTestScene.cs index f9a991f756..5cd55ed233 100644 --- a/osu.Game.Tests/Visual/Navigation/OsuGameTestScene.cs +++ b/osu.Game.Tests/Visual/Navigation/OsuGameTestScene.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Platform; using osu.Framework.Screens; @@ -103,7 +104,11 @@ namespace osu.Game.Tests.Visual.Navigation public new ScoreManager ScoreManager => base.ScoreManager; - public new SettingsPanel Settings => base.Settings; + public new Container ScreenOffsetContainer => base.ScreenOffsetContainer; + + public new SettingsOverlay Settings => base.Settings; + + public new NotificationOverlay Notifications => base.Notifications; public new MusicController MusicController => base.MusicController; diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 85428a12e3..d2f86f812e 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -64,6 +64,8 @@ namespace osu.Game /// public class OsuGame : OsuGameBase, IKeyBindingHandler { + public const float SCREEN_OFFSET_RATIO = 0.125f; + public Toolbar Toolbar; private ChatOverlay chatOverlay; @@ -71,7 +73,7 @@ namespace osu.Game private ChannelManager channelManager; [NotNull] - private readonly NotificationOverlay notifications = new NotificationOverlay(); + protected readonly NotificationOverlay Notifications = new NotificationOverlay(); private BeatmapListingOverlay beatmapListing; @@ -97,7 +99,7 @@ namespace osu.Game private ScalingContainer screenContainer; - private Container screenOffsetContainer; + protected Container ScreenOffsetContainer; [Resolved] private FrameworkConfigManager frameworkConfig { get; set; } @@ -312,7 +314,7 @@ namespace osu.Game case LinkAction.OpenEditorTimestamp: case LinkAction.JoinMultiplayerMatch: case LinkAction.Spectate: - waitForReady(() => notifications, _ => notifications.Post(new SimpleNotification + waitForReady(() => Notifications, _ => Notifications.Post(new SimpleNotification { Text = @"This link type is not yet supported!", Icon = FontAwesome.Solid.LifeRing, @@ -611,12 +613,12 @@ namespace osu.Game MenuCursorContainer.CanShowCursor = menuScreen?.CursorVisible ?? false; // todo: all archive managers should be able to be looped here. - SkinManager.PostNotification = n => notifications.Post(n); + SkinManager.PostNotification = n => Notifications.Post(n); - BeatmapManager.PostNotification = n => notifications.Post(n); + BeatmapManager.PostNotification = n => Notifications.Post(n); BeatmapManager.PresentImport = items => PresentBeatmap(items.First()); - ScoreManager.PostNotification = n => notifications.Post(n); + ScoreManager.PostNotification = n => Notifications.Post(n); ScoreManager.PresentImport = items => PresentScore(items.First()); // make config aware of how to lookup skins for on-screen display purposes. @@ -655,7 +657,7 @@ namespace osu.Game ActionRequested = action => volume.Adjust(action), ScrollActionRequested = (action, amount, isPrecise) => volume.Adjust(action, amount, isPrecise), }, - screenOffsetContainer = new Container + ScreenOffsetContainer = new Container { RelativeSizeAxes = Axes.Both, Children = new Drawable[] @@ -724,7 +726,7 @@ namespace osu.Game loadComponentSingleFile(onScreenDisplay, Add, true); - loadComponentSingleFile(notifications.With(d => + loadComponentSingleFile(Notifications.With(d => { d.GetToolbarHeight = () => ToolbarOffset; d.Anchor = Anchor.TopRight; @@ -733,7 +735,7 @@ namespace osu.Game loadComponentSingleFile(new CollectionManager(Storage) { - PostNotification = n => notifications.Post(n), + PostNotification = n => Notifications.Post(n), }, Add, true); loadComponentSingleFile(stableImportManager, Add); @@ -785,7 +787,7 @@ namespace osu.Game Add(new MusicKeyBindingHandler()); // side overlays which cancel each other. - var singleDisplaySideOverlays = new OverlayContainer[] { Settings, notifications }; + var singleDisplaySideOverlays = new OverlayContainer[] { Settings, Notifications }; foreach (var overlay in singleDisplaySideOverlays) { @@ -859,7 +861,7 @@ namespace osu.Game if (recentLogCount < short_term_display_limit) { - Schedule(() => notifications.Post(new SimpleErrorNotification + Schedule(() => Notifications.Post(new SimpleErrorNotification { Icon = entry.Level == LogLevel.Important ? FontAwesome.Solid.ExclamationCircle : FontAwesome.Solid.Bomb, Text = entry.Message.Truncate(256) + (entry.Exception != null && IsDeployedBuild ? "\n\nThis error has been automatically reported to the devs." : string.Empty), @@ -867,7 +869,7 @@ namespace osu.Game } else if (recentLogCount == short_term_display_limit) { - Schedule(() => notifications.Post(new SimpleNotification + Schedule(() => Notifications.Post(new SimpleNotification { Icon = FontAwesome.Solid.EllipsisH, Text = "Subsequent messages have been logged. Click to view log files.", @@ -1008,11 +1010,12 @@ namespace osu.Game { base.UpdateAfterChildren(); - screenOffsetContainer.Padding = new MarginPadding { Top = ToolbarOffset }; + ScreenOffsetContainer.Padding = new MarginPadding { Top = ToolbarOffset }; overlayContent.Padding = new MarginPadding { Top = ToolbarOffset }; - screenOffsetContainer.X = Settings.HorizontalScreenOffset * 0.125f + - notifications.HorizontalScreenOffset * 0.125f; + var settingsOffset = Settings.HorizontalScreenOffset * SCREEN_OFFSET_RATIO; + var notificationsOffset = Notifications.HorizontalScreenOffset * SCREEN_OFFSET_RATIO; + ScreenOffsetContainer.X = settingsOffset + notificationsOffset; MenuCursorContainer.CanShowCursor = (ScreenStack.CurrentScreen as IOsuScreen)?.CursorVisible ?? false; } diff --git a/osu.Game/Overlays/NotificationOverlay.cs b/osu.Game/Overlays/NotificationOverlay.cs index af4f41901f..9be3212159 100644 --- a/osu.Game/Overlays/NotificationOverlay.cs +++ b/osu.Game/Overlays/NotificationOverlay.cs @@ -24,7 +24,7 @@ namespace osu.Game.Overlays public LocalisableString Title => NotificationsStrings.HeaderTitle; public LocalisableString Description => NotificationsStrings.HeaderDescription; - private const float width = 320; + public const float WIDTH = 320; public const float TRANSITION_LENGTH = 600; @@ -33,7 +33,7 @@ namespace osu.Game.Overlays /// /// A horizontal offset to apply to the game-wide screen. /// - public float HorizontalScreenOffset => -width + X; + public float HorizontalScreenOffset => -WIDTH + X; /// /// Provide a source for the toolbar height. @@ -43,7 +43,7 @@ namespace osu.Game.Overlays [BackgroundDependencyLoader] private void load() { - Width = width; + Width = WIDTH; RelativeSizeAxes = Axes.Y; Children = new Drawable[] @@ -157,7 +157,7 @@ namespace osu.Game.Overlays markAllRead(); - this.MoveToX(width, TRANSITION_LENGTH, Easing.OutQuint); + this.MoveToX(WIDTH, TRANSITION_LENGTH, Easing.OutQuint); this.FadeTo(0, TRANSITION_LENGTH, Easing.OutQuint); } From ae733e202ff574b9a3065b9bc72fca71b8960580 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sat, 7 Aug 2021 00:36:52 +0300 Subject: [PATCH 06/17] Fix tests executing before overlays load --- osu.Game.Tests/Visual/Menus/TestSceneSideOverlays.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game.Tests/Visual/Menus/TestSceneSideOverlays.cs b/osu.Game.Tests/Visual/Menus/TestSceneSideOverlays.cs index 34259574f3..598998586d 100644 --- a/osu.Game.Tests/Visual/Menus/TestSceneSideOverlays.cs +++ b/osu.Game.Tests/Visual/Menus/TestSceneSideOverlays.cs @@ -19,6 +19,7 @@ namespace osu.Game.Tests.Visual.Menus base.SetUpSteps(); AddAssert("no screen offset applied", () => Game.ScreenOffsetContainer.X == 0f); + AddUntilStep("wait for overlays", () => Game.Settings.IsLoaded && Game.Notifications.IsLoaded); } [Test] From 9ac5c9aa2f8d426d1733140702ab3d3c518bce99 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sat, 7 Aug 2021 01:27:54 +0300 Subject: [PATCH 07/17] Fix notification overlay having incorrect initial X --- osu.Game/Overlays/NotificationOverlay.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Overlays/NotificationOverlay.cs b/osu.Game/Overlays/NotificationOverlay.cs index 9be3212159..cb5d4d57c6 100644 --- a/osu.Game/Overlays/NotificationOverlay.cs +++ b/osu.Game/Overlays/NotificationOverlay.cs @@ -43,6 +43,7 @@ namespace osu.Game.Overlays [BackgroundDependencyLoader] private void load() { + X = WIDTH; Width = WIDTH; RelativeSizeAxes = Axes.Y; From e924ea8d934d043a446d92a0ffeea7885cee46ec Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sat, 7 Aug 2021 18:52:27 +0300 Subject: [PATCH 08/17] Make `ScreenOffsetContainer` privatly settable only --- osu.Game/OsuGame.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index d2f86f812e..6fb884f80a 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -99,7 +99,7 @@ namespace osu.Game private ScalingContainer screenContainer; - protected Container ScreenOffsetContainer; + protected Container ScreenOffsetContainer { get; private set; } [Resolved] private FrameworkConfigManager frameworkConfig { get; set; } From 9f3013e2c89a1ea018008cb6221d9165e72f13a2 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sat, 7 Aug 2021 19:30:12 +0300 Subject: [PATCH 09/17] Remove all `HorizontalScreenOffset` calculations from overlays --- osu.Game/Overlays/NotificationOverlay.cs | 5 ----- osu.Game/Overlays/SettingsOverlay.cs | 2 -- osu.Game/Overlays/SettingsPanel.cs | 5 ----- 3 files changed, 12 deletions(-) diff --git a/osu.Game/Overlays/NotificationOverlay.cs b/osu.Game/Overlays/NotificationOverlay.cs index cb5d4d57c6..e3956089c2 100644 --- a/osu.Game/Overlays/NotificationOverlay.cs +++ b/osu.Game/Overlays/NotificationOverlay.cs @@ -30,11 +30,6 @@ namespace osu.Game.Overlays private FlowContainer sections; - /// - /// A horizontal offset to apply to the game-wide screen. - /// - public float HorizontalScreenOffset => -WIDTH + X; - /// /// Provide a source for the toolbar height. /// diff --git a/osu.Game/Overlays/SettingsOverlay.cs b/osu.Game/Overlays/SettingsOverlay.cs index 9ed1d950e3..050502b3be 100644 --- a/osu.Game/Overlays/SettingsOverlay.cs +++ b/osu.Game/Overlays/SettingsOverlay.cs @@ -21,8 +21,6 @@ namespace osu.Game.Overlays public LocalisableString Title => SettingsStrings.HeaderTitle; public LocalisableString Description => SettingsStrings.HeaderDescription; - public override float HorizontalScreenOffset => base.HorizontalScreenOffset + (lastOpenedSubPanel?.HorizontalScreenOffset ?? 0f); - protected override IEnumerable CreateSections() => new SettingsSection[] { new GeneralSection(), diff --git a/osu.Game/Overlays/SettingsPanel.cs b/osu.Game/Overlays/SettingsPanel.cs index 79d78e6805..64c3be4b9a 100644 --- a/osu.Game/Overlays/SettingsPanel.cs +++ b/osu.Game/Overlays/SettingsPanel.cs @@ -40,11 +40,6 @@ namespace osu.Game.Overlays /// public override bool IsPresent => true; - /// - /// A horizontal offset to apply to the game-wide screen. - /// - public virtual float HorizontalScreenOffset => (WIDTH + Content?.X) ?? 0f; - protected Sidebar Sidebar; private SidebarButton selectedSidebarButton; From 19a19f915cde29015df6e085406af348c487bba4 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sat, 7 Aug 2021 19:56:51 +0300 Subject: [PATCH 10/17] Adjust settings panel to autosize to zero when hiding it Previously, when hiding the settings overlay, it remains to have a width of `56` (sidebar width), this is due to the panel content being placed next to the sidebar, so therefore the content has to move 400 (PANEL_WIDTH) + 56 (sidebar_width) backwards, for the overlay to have a width of 0 on hide. --- .../Visual/Settings/TestSceneTabletSettings.cs | 2 +- osu.Game/Overlays/SettingsOverlay.cs | 4 ++-- osu.Game/Overlays/SettingsPanel.cs | 12 ++++++++++-- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/osu.Game.Tests/Visual/Settings/TestSceneTabletSettings.cs b/osu.Game.Tests/Visual/Settings/TestSceneTabletSettings.cs index a62980addf..da474a64ba 100644 --- a/osu.Game.Tests/Visual/Settings/TestSceneTabletSettings.cs +++ b/osu.Game.Tests/Visual/Settings/TestSceneTabletSettings.cs @@ -27,7 +27,7 @@ namespace osu.Game.Tests.Visual.Settings new TabletSettings(tabletHandler) { RelativeSizeAxes = Axes.None, - Width = SettingsPanel.WIDTH, + Width = SettingsPanel.PANEL_WIDTH, Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, } diff --git a/osu.Game/Overlays/SettingsOverlay.cs b/osu.Game/Overlays/SettingsOverlay.cs index 050502b3be..55e8aee266 100644 --- a/osu.Game/Overlays/SettingsOverlay.cs +++ b/osu.Game/Overlays/SettingsOverlay.cs @@ -69,7 +69,7 @@ namespace osu.Game.Overlays Sidebar?.FadeColour(Color4.DarkGray, 300, Easing.OutQuint); SectionsContainer.FadeOut(300, Easing.OutQuint); - ContentContainer.MoveToX(-WIDTH, 500, Easing.OutQuint); + ContentContainer.MoveToX(-PANEL_WIDTH, 500, Easing.OutQuint); lastOpenedSubPanel = panel; break; @@ -83,7 +83,7 @@ namespace osu.Game.Overlays } } - protected override float ExpandedPosition => lastOpenedSubPanel?.State.Value == Visibility.Visible ? -WIDTH : base.ExpandedPosition; + protected override float ExpandedPosition => lastOpenedSubPanel?.State.Value == Visibility.Visible ? -PANEL_WIDTH : base.ExpandedPosition; [BackgroundDependencyLoader] private void load() diff --git a/osu.Game/Overlays/SettingsPanel.cs b/osu.Game/Overlays/SettingsPanel.cs index 64c3be4b9a..8b953e8655 100644 --- a/osu.Game/Overlays/SettingsPanel.cs +++ b/osu.Game/Overlays/SettingsPanel.cs @@ -28,7 +28,15 @@ namespace osu.Game.Overlays private const float sidebar_width = Sidebar.DEFAULT_WIDTH; - public const float WIDTH = 400; + /// + /// The width of the settings panel content, excluding the sidebar. + /// + public const float PANEL_WIDTH = 400; + + /// + /// The full width of the settings panel, including the sidebar. + /// + public const float WIDTH = sidebar_width + PANEL_WIDTH; protected Container ContentContainer; @@ -71,7 +79,7 @@ namespace osu.Game.Overlays InternalChild = ContentContainer = new NonMaskedContent { X = -WIDTH + ExpandedPosition, - Width = WIDTH, + Width = PANEL_WIDTH, RelativeSizeAxes = Axes.Y, Children = new Drawable[] { From d099bb8ab631424f6a841d4f9947dc1ca3ba45bf Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sat, 7 Aug 2021 19:33:22 +0300 Subject: [PATCH 11/17] Calculate offsets from overlay `ScreenSpaceDrawQuad`s instead --- .../Visual/Menus/TestSceneSideOverlays.cs | 21 ------------------- osu.Game/OsuGame.cs | 7 ++++--- 2 files changed, 4 insertions(+), 24 deletions(-) diff --git a/osu.Game.Tests/Visual/Menus/TestSceneSideOverlays.cs b/osu.Game.Tests/Visual/Menus/TestSceneSideOverlays.cs index 598998586d..21db7e2802 100644 --- a/osu.Game.Tests/Visual/Menus/TestSceneSideOverlays.cs +++ b/osu.Game.Tests/Visual/Menus/TestSceneSideOverlays.cs @@ -1,12 +1,9 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System.Linq; using NUnit.Framework; -using osu.Framework.Graphics.Containers; using osu.Framework.Testing; using osu.Game.Overlays; -using osu.Game.Overlays.Settings.Sections.Input; using osu.Game.Tests.Visual.Navigation; namespace osu.Game.Tests.Visual.Menus @@ -32,24 +29,6 @@ namespace osu.Game.Tests.Visual.Menus AddUntilStep("screen offset removed", () => Game.ScreenOffsetContainer.X == 0f); } - [Test] - public void TestScreenOffsettingAccountsForKeyBindingPanel() - { - AddStep("open settings", () => Game.Settings.Show()); - AddStep("open key binding panel", () => Game.Settings.ChildrenOfType().Single().Show()); - AddUntilStep("right screen offset applied", () => Game.ScreenOffsetContainer.X == SettingsPanel.WIDTH * OsuGame.SCREEN_OFFSET_RATIO); - - AddStep("hide key binding", () => Game.Settings.ChildrenOfType().Single().Show()); - AddUntilStep("right screen offset still applied", () => Game.ScreenOffsetContainer.X == SettingsPanel.WIDTH * OsuGame.SCREEN_OFFSET_RATIO); - - AddStep("open key binding", () => Game.Settings.Show()); - AddUntilStep("right screen offset still applied", () => Game.ScreenOffsetContainer.X == SettingsPanel.WIDTH * OsuGame.SCREEN_OFFSET_RATIO); - - AddStep("hide settings", () => Game.Settings.Hide()); - AddAssert("key binding panel still open", () => Game.Settings.ChildrenOfType().Single().State.Value == Visibility.Visible); - AddUntilStep("screen offset removed", () => Game.ScreenOffsetContainer.X == 0f); - } - [Test] public void TestScreenOffsettingOnNotificationOverlay() { diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 6fb884f80a..1539d984ae 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -1013,9 +1013,10 @@ namespace osu.Game ScreenOffsetContainer.Padding = new MarginPadding { Top = ToolbarOffset }; overlayContent.Padding = new MarginPadding { Top = ToolbarOffset }; - var settingsOffset = Settings.HorizontalScreenOffset * SCREEN_OFFSET_RATIO; - var notificationsOffset = Notifications.HorizontalScreenOffset * SCREEN_OFFSET_RATIO; - ScreenOffsetContainer.X = settingsOffset + notificationsOffset; + ScreenOffsetContainer.X = 0f; + + if (Settings.IsLoaded) ScreenOffsetContainer.X += (ToLocalSpace(Settings.ScreenSpaceDrawQuad.TopRight).X) * SCREEN_OFFSET_RATIO; + if (Notifications.IsLoaded) ScreenOffsetContainer.X += (ToLocalSpace(Notifications.ScreenSpaceDrawQuad.TopLeft).X - DrawWidth) * SCREEN_OFFSET_RATIO; MenuCursorContainer.CanShowCursor = (ScreenStack.CurrentScreen as IOsuScreen)?.CursorVisible ?? false; } From b58b5ec2b47af2376b9ff355c5591629af397d55 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 12 Aug 2021 12:14:39 +0300 Subject: [PATCH 12/17] Apply horizontal offset changing once per frame The previous way was causing every-frame invalidation when an overlay is visible. --- osu.Game/OsuGame.cs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 1539d984ae..b6809c0290 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -1013,10 +1013,14 @@ namespace osu.Game ScreenOffsetContainer.Padding = new MarginPadding { Top = ToolbarOffset }; overlayContent.Padding = new MarginPadding { Top = ToolbarOffset }; - ScreenOffsetContainer.X = 0f; + var horizontalOffset = 0f; - if (Settings.IsLoaded) ScreenOffsetContainer.X += (ToLocalSpace(Settings.ScreenSpaceDrawQuad.TopRight).X) * SCREEN_OFFSET_RATIO; - if (Notifications.IsLoaded) ScreenOffsetContainer.X += (ToLocalSpace(Notifications.ScreenSpaceDrawQuad.TopLeft).X - DrawWidth) * SCREEN_OFFSET_RATIO; + if (Settings.IsLoaded) + horizontalOffset += (ToLocalSpace(Settings.ScreenSpaceDrawQuad.TopRight).X) * SCREEN_OFFSET_RATIO; + if (Notifications.IsLoaded) + horizontalOffset += (ToLocalSpace(Notifications.ScreenSpaceDrawQuad.TopLeft).X - DrawWidth) * SCREEN_OFFSET_RATIO; + + ScreenOffsetContainer.X = horizontalOffset; MenuCursorContainer.CanShowCursor = (ScreenStack.CurrentScreen as IOsuScreen)?.CursorVisible ?? false; } From 3d7866e82da57bc422af3bb0cc22557653d10964 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 12 Aug 2021 14:14:54 +0300 Subject: [PATCH 13/17] Calculate horizontal offset on present overlays only --- osu.Game/OsuGame.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index b6809c0290..b8a4388282 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -1015,9 +1015,9 @@ namespace osu.Game var horizontalOffset = 0f; - if (Settings.IsLoaded) + if (Settings.IsLoaded && Settings.IsPresent) horizontalOffset += (ToLocalSpace(Settings.ScreenSpaceDrawQuad.TopRight).X) * SCREEN_OFFSET_RATIO; - if (Notifications.IsLoaded) + if (Notifications.IsLoaded && Notifications.IsPresent) horizontalOffset += (ToLocalSpace(Notifications.ScreenSpaceDrawQuad.TopLeft).X - DrawWidth) * SCREEN_OFFSET_RATIO; ScreenOffsetContainer.X = horizontalOffset; From bb1d74255e70081a806f9f3a9db773b6a3b06262 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 12 Aug 2021 14:15:51 +0300 Subject: [PATCH 14/17] Remove unrequired parenthesis --- osu.Game/OsuGame.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index b8a4388282..f92f7e9e8c 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -1016,7 +1016,7 @@ namespace osu.Game var horizontalOffset = 0f; if (Settings.IsLoaded && Settings.IsPresent) - horizontalOffset += (ToLocalSpace(Settings.ScreenSpaceDrawQuad.TopRight).X) * SCREEN_OFFSET_RATIO; + horizontalOffset += ToLocalSpace(Settings.ScreenSpaceDrawQuad.TopRight).X * SCREEN_OFFSET_RATIO; if (Notifications.IsLoaded && Notifications.IsPresent) horizontalOffset += (ToLocalSpace(Notifications.ScreenSpaceDrawQuad.TopLeft).X - DrawWidth) * SCREEN_OFFSET_RATIO; From c1d67976e6accf5ca2980a6aa116e791e8e9432a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 13 Aug 2021 16:29:36 +0900 Subject: [PATCH 15/17] Rename const, add xmldoc and make protected --- osu.Game.Tests/Visual/Menus/TestSceneSideOverlays.cs | 4 ++-- osu.Game.Tests/Visual/Navigation/OsuGameTestScene.cs | 2 ++ osu.Game/OsuGame.cs | 9 ++++++--- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/osu.Game.Tests/Visual/Menus/TestSceneSideOverlays.cs b/osu.Game.Tests/Visual/Menus/TestSceneSideOverlays.cs index 21db7e2802..e58f85b0b3 100644 --- a/osu.Game.Tests/Visual/Menus/TestSceneSideOverlays.cs +++ b/osu.Game.Tests/Visual/Menus/TestSceneSideOverlays.cs @@ -23,7 +23,7 @@ namespace osu.Game.Tests.Visual.Menus public void TestScreenOffsettingOnSettingsOverlay() { AddStep("open settings", () => Game.Settings.Show()); - AddUntilStep("right screen offset applied", () => Game.ScreenOffsetContainer.X == SettingsPanel.WIDTH * OsuGame.SCREEN_OFFSET_RATIO); + AddUntilStep("right screen offset applied", () => Game.ScreenOffsetContainer.X == SettingsPanel.WIDTH * TestOsuGame.SIDE_OVERLAY_OFFSET_RATIO); AddStep("hide settings", () => Game.Settings.Hide()); AddUntilStep("screen offset removed", () => Game.ScreenOffsetContainer.X == 0f); @@ -33,7 +33,7 @@ namespace osu.Game.Tests.Visual.Menus public void TestScreenOffsettingOnNotificationOverlay() { AddStep("open notifications", () => Game.Notifications.Show()); - AddUntilStep("right screen offset applied", () => Game.ScreenOffsetContainer.X == -NotificationOverlay.WIDTH * OsuGame.SCREEN_OFFSET_RATIO); + AddUntilStep("right screen offset applied", () => Game.ScreenOffsetContainer.X == -NotificationOverlay.WIDTH * TestOsuGame.SIDE_OVERLAY_OFFSET_RATIO); AddStep("hide notifications", () => Game.Notifications.Hide()); AddUntilStep("screen offset removed", () => Game.ScreenOffsetContainer.X == 0f); diff --git a/osu.Game.Tests/Visual/Navigation/OsuGameTestScene.cs b/osu.Game.Tests/Visual/Navigation/OsuGameTestScene.cs index 5cd55ed233..c9a1471e41 100644 --- a/osu.Game.Tests/Visual/Navigation/OsuGameTestScene.cs +++ b/osu.Game.Tests/Visual/Navigation/OsuGameTestScene.cs @@ -96,6 +96,8 @@ namespace osu.Game.Tests.Visual.Navigation public class TestOsuGame : OsuGame { + public new const float SIDE_OVERLAY_OFFSET_RATIO = OsuGame.SIDE_OVERLAY_OFFSET_RATIO; + public new ScreenStack ScreenStack => base.ScreenStack; public new BackButton BackButton => base.BackButton; diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index f92f7e9e8c..6d76fec7c1 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -64,7 +64,10 @@ namespace osu.Game /// public class OsuGame : OsuGameBase, IKeyBindingHandler { - public const float SCREEN_OFFSET_RATIO = 0.125f; + /// + /// The amount of global offset to apply when a left/right anchored overlay is displayed (ie. settings or notifications). + /// + protected const float SIDE_OVERLAY_OFFSET_RATIO = 0.125f; public Toolbar Toolbar; @@ -1016,9 +1019,9 @@ namespace osu.Game var horizontalOffset = 0f; if (Settings.IsLoaded && Settings.IsPresent) - horizontalOffset += ToLocalSpace(Settings.ScreenSpaceDrawQuad.TopRight).X * SCREEN_OFFSET_RATIO; + horizontalOffset += ToLocalSpace(Settings.ScreenSpaceDrawQuad.TopRight).X * SIDE_OVERLAY_OFFSET_RATIO; if (Notifications.IsLoaded && Notifications.IsPresent) - horizontalOffset += (ToLocalSpace(Notifications.ScreenSpaceDrawQuad.TopLeft).X - DrawWidth) * SCREEN_OFFSET_RATIO; + horizontalOffset += (ToLocalSpace(Notifications.ScreenSpaceDrawQuad.TopLeft).X - DrawWidth) * SIDE_OVERLAY_OFFSET_RATIO; ScreenOffsetContainer.X = horizontalOffset; From da18c399e2d7cd531e019c8b140155a02135a4dd Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 13 Aug 2021 16:33:00 +0900 Subject: [PATCH 16/17] Remove unnecessary `IsPresent` override --- osu.Game/Overlays/SettingsPanel.cs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/osu.Game/Overlays/SettingsPanel.cs b/osu.Game/Overlays/SettingsPanel.cs index 8b953e8655..f1c41c4b50 100644 --- a/osu.Game/Overlays/SettingsPanel.cs +++ b/osu.Game/Overlays/SettingsPanel.cs @@ -42,12 +42,6 @@ namespace osu.Game.Overlays protected override Container Content => ContentContainer; - /// - /// The always needs to be present for to process transforms while overlay is masked away. - /// todo: there may be a better solution for this and the existing , likely requires a refactor. - /// - public override bool IsPresent => true; - protected Sidebar Sidebar; private SidebarButton selectedSidebarButton; From 93b97e5110774787b27ba91cb595158a65491cbf Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 13 Aug 2021 16:35:22 +0900 Subject: [PATCH 17/17] Adjust ratio to match previous behaviour --- osu.Game/OsuGame.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 6d76fec7c1..fb682e0909 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -67,7 +67,7 @@ namespace osu.Game /// /// The amount of global offset to apply when a left/right anchored overlay is displayed (ie. settings or notifications). /// - protected const float SIDE_OVERLAY_OFFSET_RATIO = 0.125f; + protected const float SIDE_OVERLAY_OFFSET_RATIO = 0.05f; public Toolbar Toolbar;