From 77980196c5e6473ae1c9ff70ac95f85050a107a0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 6 Jan 2022 17:15:42 +0900 Subject: [PATCH 1/7] Split out expanding container logic from settings sidebar --- ...Sidebar.cs => ExpandingButtonContainer.cs} | 56 +++++++------------ osu.Game/Overlays/Settings/SettingsSidebar.cs | 37 ++++++++++++ .../Overlays/Settings/SidebarIconButton.cs | 4 +- osu.Game/Overlays/SettingsPanel.cs | 8 +-- osu.Game/Overlays/SettingsSubPanel.cs | 2 +- 5 files changed, 65 insertions(+), 42 deletions(-) rename osu.Game/Overlays/{Settings/Sidebar.cs => ExpandingButtonContainer.cs} (67%) create mode 100644 osu.Game/Overlays/Settings/SettingsSidebar.cs diff --git a/osu.Game/Overlays/Settings/Sidebar.cs b/osu.Game/Overlays/ExpandingButtonContainer.cs similarity index 67% rename from osu.Game/Overlays/Settings/Sidebar.cs rename to osu.Game/Overlays/ExpandingButtonContainer.cs index 93b1b19b17..a49f0493f6 100644 --- a/osu.Game/Overlays/Settings/Sidebar.cs +++ b/osu.Game/Overlays/ExpandingButtonContainer.cs @@ -1,47 +1,47 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using System; using System.Linq; using osu.Framework; -using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Shapes; using osu.Framework.Input.Events; +using osu.Framework.Testing; using osu.Framework.Threading; -using osu.Game.Graphics; using osu.Game.Graphics.Containers; +using osu.Game.Graphics.UserInterface; +using osu.Game.Overlays.Settings; using osuTK; -namespace osu.Game.Overlays.Settings +namespace osu.Game.Overlays { - public class Sidebar : Container, IStateful + public abstract class ExpandingButtonContainer : Container, IStateful { - private readonly Box background; - private readonly FillFlowContainer content; - public const float DEFAULT_WIDTH = 70; - public const int EXPANDED_WIDTH = 200; + private readonly float contractedWidth; + private readonly float expandedWidth; public event Action StateChanged; - protected override Container Content => content; + protected override Container Content => FillFlow; - public Sidebar() + protected FillFlowContainer FillFlow { get; } + + protected ExpandingButtonContainer(float contractedWidth, float expandedWidth) { + this.contractedWidth = contractedWidth; + this.expandedWidth = expandedWidth; + RelativeSizeAxes = Axes.Y; + Width = contractedWidth; + InternalChildren = new Drawable[] { - background = new Box - { - Colour = OsuColour.Gray(0.02f), - RelativeSizeAxes = Axes.Both, - }, new SidebarScrollContainer { Children = new[] { - content = new FillFlowContainer + FillFlow = new FillFlowContainer { Origin = Anchor.CentreLeft, Anchor = Anchor.CentreLeft, @@ -54,12 +54,6 @@ namespace osu.Game.Overlays.Settings }; } - [BackgroundDependencyLoader] - private void load(OverlayColourProvider colourProvider) - { - background.Colour = colourProvider.Background5; - } - private ScheduledDelegate expandEvent; private ExpandedState state; @@ -107,11 +101,11 @@ namespace osu.Game.Overlays.Settings switch (state) { default: - this.ResizeTo(new Vector2(DEFAULT_WIDTH, Height), 500, Easing.OutQuint); + this.ResizeTo(new Vector2(contractedWidth, Height), 500, Easing.OutQuint); break; case ExpandedState.Expanded: - this.ResizeTo(new Vector2(EXPANDED_WIDTH, Height), 500, Easing.OutQuint); + this.ResizeTo(new Vector2(expandedWidth, Height), 500, Easing.OutQuint); break; } @@ -121,15 +115,13 @@ namespace osu.Game.Overlays.Settings private Drawable lastHoveredButton; - private Drawable hoveredButton => content.Children.FirstOrDefault(c => c.IsHovered); + private Drawable hoveredButton => FillFlow.ChildrenOfType().FirstOrDefault(c => c.IsHovered); private void queueExpandIfHovering() { // only expand when we hover a different button. if (lastHoveredButton == hoveredButton) return; - if (!IsHovered) return; - if (State != ExpandedState.Expanded) { expandEvent?.Cancel(); @@ -139,10 +131,4 @@ namespace osu.Game.Overlays.Settings lastHoveredButton = hoveredButton; } } - - public enum ExpandedState - { - Contracted, - Expanded, - } } diff --git a/osu.Game/Overlays/Settings/SettingsSidebar.cs b/osu.Game/Overlays/Settings/SettingsSidebar.cs new file mode 100644 index 0000000000..5aa2e61162 --- /dev/null +++ b/osu.Game/Overlays/Settings/SettingsSidebar.cs @@ -0,0 +1,37 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Shapes; + +namespace osu.Game.Overlays.Settings +{ + public class SettingsSidebar : ExpandingButtonContainer + { + public const float DEFAULT_WIDTH = 70; + public const int EXPANDED_WIDTH = 200; + + public SettingsSidebar() + : base(DEFAULT_WIDTH, EXPANDED_WIDTH) + { + } + + [BackgroundDependencyLoader] + private void load(OverlayColourProvider colourProvider) + { + AddInternal(new Box + { + Colour = colourProvider.Background5, + RelativeSizeAxes = Axes.Both, + Depth = float.MaxValue + }); + } + } + + public enum ExpandedState + { + Contracted, + Expanded, + } +} diff --git a/osu.Game/Overlays/Settings/SidebarIconButton.cs b/osu.Game/Overlays/Settings/SidebarIconButton.cs index fd57996b1b..6f3d3d5d52 100644 --- a/osu.Game/Overlays/Settings/SidebarIconButton.cs +++ b/osu.Game/Overlays/Settings/SidebarIconButton.cs @@ -62,14 +62,14 @@ namespace osu.Game.Overlays.Settings { textIconContent = new Container { - Width = Sidebar.DEFAULT_WIDTH, + Width = SettingsSidebar.DEFAULT_WIDTH, RelativeSizeAxes = Axes.Y, Colour = OsuColour.Gray(0.6f), Children = new Drawable[] { headerText = new OsuSpriteText { - Position = new Vector2(Sidebar.DEFAULT_WIDTH + 10, 0), + Position = new Vector2(SettingsSidebar.DEFAULT_WIDTH + 10, 0), Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, }, diff --git a/osu.Game/Overlays/SettingsPanel.cs b/osu.Game/Overlays/SettingsPanel.cs index 0ceb7fc50d..ba7118cffe 100644 --- a/osu.Game/Overlays/SettingsPanel.cs +++ b/osu.Game/Overlays/SettingsPanel.cs @@ -27,7 +27,7 @@ namespace osu.Game.Overlays public const float TRANSITION_LENGTH = 600; - private const float sidebar_width = Sidebar.DEFAULT_WIDTH; + private const float sidebar_width = SettingsSidebar.DEFAULT_WIDTH; /// /// The width of the settings panel content, excluding the sidebar. @@ -43,7 +43,7 @@ namespace osu.Game.Overlays protected override Container Content => ContentContainer; - protected Sidebar Sidebar; + protected SettingsSidebar Sidebar; private SidebarIconButton selectedSidebarButton; public SettingsSectionsContainer SectionsContainer { get; private set; } @@ -129,7 +129,7 @@ namespace osu.Game.Overlays if (showSidebar) { - AddInternal(Sidebar = new Sidebar { Width = sidebar_width }); + AddInternal(Sidebar = new SettingsSidebar { Width = sidebar_width }); } CreateSections()?.ForEach(AddSection); @@ -244,7 +244,7 @@ namespace osu.Game.Overlays if (selectedSidebarButton != null) selectedSidebarButton.Selected = false; - selectedSidebarButton = Sidebar.Children.FirstOrDefault(b => b.Section == section.NewValue); + selectedSidebarButton = Sidebar.Children.OfType().FirstOrDefault(b => b.Section == section.NewValue); if (selectedSidebarButton != null) selectedSidebarButton.Selected = true; diff --git a/osu.Game/Overlays/SettingsSubPanel.cs b/osu.Game/Overlays/SettingsSubPanel.cs index a65d792a9f..da806c09d3 100644 --- a/osu.Game/Overlays/SettingsSubPanel.cs +++ b/osu.Game/Overlays/SettingsSubPanel.cs @@ -39,7 +39,7 @@ namespace osu.Game.Overlays [BackgroundDependencyLoader] private void load() { - Size = new Vector2(Sidebar.DEFAULT_WIDTH); + Size = new Vector2(SettingsSidebar.DEFAULT_WIDTH); AddRange(new Drawable[] { From 5baaf356aac038145197dc8f5524a83ae5ad50d4 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 6 Jan 2022 21:05:00 +0900 Subject: [PATCH 2/7] Split out `SettingsToolboxGroup` from `PlayerSettingsGroup` --- osu.Game/Overlays/SettingsToolboxGroup.cs | 165 ++++++++++++++++++ .../PlayerSettings/PlayerSettingsGroup.cs | 155 +--------------- 2 files changed, 172 insertions(+), 148 deletions(-) create mode 100644 osu.Game/Overlays/SettingsToolboxGroup.cs diff --git a/osu.Game/Overlays/SettingsToolboxGroup.cs b/osu.Game/Overlays/SettingsToolboxGroup.cs new file mode 100644 index 0000000000..c154284fb9 --- /dev/null +++ b/osu.Game/Overlays/SettingsToolboxGroup.cs @@ -0,0 +1,165 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Input.Events; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Game.Graphics.UserInterface; +using osuTK; +using osuTK.Graphics; + +namespace osu.Game.Overlays +{ + public abstract class SettingsToolboxGroup : Container + { + private const float transition_duration = 250; + private const int container_width = 270; + private const int border_thickness = 2; + private const int header_height = 30; + private const int corner_radius = 5; + + private readonly FillFlowContainer content; + private readonly IconButton button; + + private bool expanded = true; + + public bool Expanded + { + get => expanded; + set + { + if (expanded == value) return; + + expanded = value; + + content.ClearTransforms(); + + if (expanded) + content.AutoSizeAxes = Axes.Y; + else + { + content.AutoSizeAxes = Axes.None; + content.ResizeHeightTo(0, transition_duration, Easing.OutQuint); + } + + updateExpanded(); + } + } + + private Color4 expandedColour; + + /// + /// Create a new instance. + /// + /// The title to be displayed in the header of this group. + protected SettingsToolboxGroup(string title) + { + AutoSizeAxes = Axes.Y; + Width = container_width; + Masking = true; + CornerRadius = corner_radius; + BorderColour = Color4.Black; + BorderThickness = border_thickness; + + InternalChildren = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Black, + Alpha = 0.5f, + }, + new FillFlowContainer + { + Direction = FillDirection.Vertical, + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Children = new Drawable[] + { + new Container + { + Name = @"Header", + Origin = Anchor.TopCentre, + Anchor = Anchor.TopCentre, + RelativeSizeAxes = Axes.X, + Height = header_height, + Children = new Drawable[] + { + new OsuSpriteText + { + Origin = Anchor.CentreLeft, + Anchor = Anchor.CentreLeft, + Text = title.ToUpperInvariant(), + Font = OsuFont.GetFont(weight: FontWeight.Bold, size: 17), + Margin = new MarginPadding { Left = 10 }, + }, + button = new IconButton + { + Origin = Anchor.Centre, + Anchor = Anchor.CentreRight, + Position = new Vector2(-15, 0), + Icon = FontAwesome.Solid.Bars, + Scale = new Vector2(0.75f), + Action = () => Expanded = !Expanded, + }, + } + }, + content = new FillFlowContainer + { + Name = @"Content", + Origin = Anchor.TopCentre, + Anchor = Anchor.TopCentre, + Direction = FillDirection.Vertical, + RelativeSizeAxes = Axes.X, + AutoSizeDuration = transition_duration, + AutoSizeEasing = Easing.OutQuint, + AutoSizeAxes = Axes.Y, + Padding = new MarginPadding(15), + Spacing = new Vector2(0, 15), + } + } + }, + }; + } + + private const float fade_duration = 800; + private const float inactive_alpha = 0.5f; + + protected override void LoadComplete() + { + base.LoadComplete(); + this.Delay(600).FadeTo(inactive_alpha, fade_duration, Easing.OutQuint); + } + + protected override bool OnHover(HoverEvent e) + { + this.FadeIn(fade_duration, Easing.OutQuint); + return false; + } + + protected override void OnHoverLost(HoverLostEvent e) + { + this.FadeTo(inactive_alpha, fade_duration, Easing.OutQuint); + base.OnHoverLost(e); + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + expandedColour = colours.Yellow; + + updateExpanded(); + } + + private void updateExpanded() => button.FadeColour(expanded ? expandedColour : Color4.White, 200, Easing.InOutQuint); + + protected override Container Content => content; + + protected override bool OnMouseDown(MouseDownEvent e) => true; + } +} diff --git a/osu.Game/Screens/Play/PlayerSettings/PlayerSettingsGroup.cs b/osu.Game/Screens/Play/PlayerSettings/PlayerSettingsGroup.cs index 7928d41e3b..0bbe6902f4 100644 --- a/osu.Game/Screens/Play/PlayerSettings/PlayerSettingsGroup.cs +++ b/osu.Game/Screens/Play/PlayerSettings/PlayerSettingsGroup.cs @@ -1,165 +1,24 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using osu.Framework.Allocation; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Shapes; -using osu.Framework.Graphics.Sprites; using osu.Framework.Input.Events; -using osu.Game.Graphics; -using osu.Game.Graphics.Sprites; -using osu.Game.Graphics.UserInterface; -using osuTK; -using osuTK.Graphics; +using osu.Game.Overlays; namespace osu.Game.Screens.Play.PlayerSettings { - public abstract class PlayerSettingsGroup : Container + public class PlayerSettingsGroup : SettingsToolboxGroup { - private const float transition_duration = 250; - private const int container_width = 270; - private const int border_thickness = 2; - private const int header_height = 30; - private const int corner_radius = 5; - - private readonly FillFlowContainer content; - private readonly IconButton button; - - private bool expanded = true; - - public bool Expanded + public PlayerSettingsGroup(string title) + : base(title) { - get => expanded; - set - { - if (expanded == value) return; - - expanded = value; - - content.ClearTransforms(); - - if (expanded) - content.AutoSizeAxes = Axes.Y; - else - { - content.AutoSizeAxes = Axes.None; - content.ResizeHeightTo(0, transition_duration, Easing.OutQuint); - } - - updateExpanded(); - } - } - - private Color4 expandedColour; - - /// - /// Create a new instance. - /// - /// The title to be displayed in the header of this group. - protected PlayerSettingsGroup(string title) - { - AutoSizeAxes = Axes.Y; - Width = container_width; - Masking = true; - CornerRadius = corner_radius; - BorderColour = Color4.Black; - BorderThickness = border_thickness; - - InternalChildren = new Drawable[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = Color4.Black, - Alpha = 0.5f, - }, - new FillFlowContainer - { - Direction = FillDirection.Vertical, - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Children = new Drawable[] - { - new Container - { - Name = @"Header", - Origin = Anchor.TopCentre, - Anchor = Anchor.TopCentre, - RelativeSizeAxes = Axes.X, - Height = header_height, - Children = new Drawable[] - { - new OsuSpriteText - { - Origin = Anchor.CentreLeft, - Anchor = Anchor.CentreLeft, - Text = title.ToUpperInvariant(), - Font = OsuFont.GetFont(weight: FontWeight.Bold, size: 17), - Margin = new MarginPadding { Left = 10 }, - }, - button = new IconButton - { - Origin = Anchor.Centre, - Anchor = Anchor.CentreRight, - Position = new Vector2(-15, 0), - Icon = FontAwesome.Solid.Bars, - Scale = new Vector2(0.75f), - Action = () => Expanded = !Expanded, - }, - } - }, - content = new FillFlowContainer - { - Name = @"Content", - Origin = Anchor.TopCentre, - Anchor = Anchor.TopCentre, - Direction = FillDirection.Vertical, - RelativeSizeAxes = Axes.X, - AutoSizeDuration = transition_duration, - AutoSizeEasing = Easing.OutQuint, - AutoSizeAxes = Axes.Y, - Padding = new MarginPadding(15), - Spacing = new Vector2(0, 15), - } - } - }, - }; - } - - private const float fade_duration = 800; - private const float inactive_alpha = 0.5f; - - protected override void LoadComplete() - { - base.LoadComplete(); - this.Delay(600).FadeTo(inactive_alpha, fade_duration, Easing.OutQuint); } protected override bool OnHover(HoverEvent e) { - this.FadeIn(fade_duration, Easing.OutQuint); + base.OnHover(e); + + // Importantly, return true to correctly take focus away from PlayerLoader. return true; } - - protected override void OnHoverLost(HoverLostEvent e) - { - this.FadeTo(inactive_alpha, fade_duration, Easing.OutQuint); - base.OnHoverLost(e); - } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - expandedColour = colours.Yellow; - - updateExpanded(); - } - - private void updateExpanded() => button.FadeColour(expanded ? expandedColour : Color4.White, 200, Easing.InOutQuint); - - protected override Container Content => content; - - protected override bool OnMouseDown(MouseDownEvent e) => true; } } From cea9cab4dcca4da45b98cb868e89a65e391869c9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 6 Jan 2022 21:10:45 +0900 Subject: [PATCH 3/7] Use `ExpandingButtonContainer` in editor composer --- osu.Game/Overlays/SettingsToolboxGroup.cs | 4 ++- ...{ToolboxGroup.cs => EditorToolboxGroup.cs} | 6 ++--- osu.Game/Rulesets/Edit/HitObjectComposer.cs | 26 ++++++++++++------- .../Rulesets/Edit/ScrollingToolboxGroup.cs | 2 +- 4 files changed, 23 insertions(+), 15 deletions(-) rename osu.Game/Rulesets/Edit/{ToolboxGroup.cs => EditorToolboxGroup.cs} (71%) diff --git a/osu.Game/Overlays/SettingsToolboxGroup.cs b/osu.Game/Overlays/SettingsToolboxGroup.cs index c154284fb9..02b5bdc1e1 100644 --- a/osu.Game/Overlays/SettingsToolboxGroup.cs +++ b/osu.Game/Overlays/SettingsToolboxGroup.cs @@ -94,9 +94,11 @@ namespace osu.Game.Overlays { Origin = Anchor.CentreLeft, Anchor = Anchor.CentreLeft, + RelativeSizeAxes = Axes.X, + Truncate = true, Text = title.ToUpperInvariant(), Font = OsuFont.GetFont(weight: FontWeight.Bold, size: 17), - Margin = new MarginPadding { Left = 10 }, + Padding = new MarginPadding { Left = 10, Right = 30 }, }, button = new IconButton { diff --git a/osu.Game/Rulesets/Edit/ToolboxGroup.cs b/osu.Game/Rulesets/Edit/EditorToolboxGroup.cs similarity index 71% rename from osu.Game/Rulesets/Edit/ToolboxGroup.cs rename to osu.Game/Rulesets/Edit/EditorToolboxGroup.cs index 22b2b05657..bde426f56a 100644 --- a/osu.Game/Rulesets/Edit/ToolboxGroup.cs +++ b/osu.Game/Rulesets/Edit/EditorToolboxGroup.cs @@ -2,13 +2,13 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Graphics; -using osu.Game.Screens.Play.PlayerSettings; +using osu.Game.Overlays; namespace osu.Game.Rulesets.Edit { - public class ToolboxGroup : PlayerSettingsGroup + public class EditorToolboxGroup : SettingsToolboxGroup { - public ToolboxGroup(string title) + public EditorToolboxGroup(string title) : base(title) { RelativeSizeAxes = Axes.X; diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs index cbc2415603..92ea2db338 100644 --- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs @@ -13,6 +13,7 @@ using osu.Framework.Input; using osu.Framework.Input.Events; using osu.Framework.Logging; using osu.Game.Beatmaps; +using osu.Game.Overlays; using osu.Game.Rulesets.Configuration; using osu.Game.Rulesets.Edit.Tools; using osu.Game.Rulesets.Mods; @@ -98,8 +99,6 @@ namespace osu.Game.Rulesets.Edit dependencies.CacheAs(Playfield); - const float toolbar_width = 200; - InternalChildren = new Drawable[] { new Container @@ -116,20 +115,15 @@ namespace osu.Game.Rulesets.Edit .WithChild(BlueprintContainer = CreateBlueprintContainer()) } }, - new FillFlowContainer + new LeftToolboxFlow { - Name = "Sidebar", - RelativeSizeAxes = Axes.Y, - Width = toolbar_width, - Padding = new MarginPadding { Right = 10 }, - Spacing = new Vector2(10), Children = new Drawable[] { - new ToolboxGroup("toolbox (1-9)") + new EditorToolboxGroup("toolbox (1-9)") { Child = toolboxCollection = new EditorRadioButtonCollection { RelativeSizeAxes = Axes.X } }, - new ToolboxGroup("toggles (Q~P)") + new EditorToolboxGroup("toggles (Q~P)") { Child = togglesCollection = new FillFlowContainer { @@ -426,6 +420,18 @@ namespace osu.Game.Rulesets.Edit } #endregion + + private class LeftToolboxFlow : ExpandingButtonContainer + { + public LeftToolboxFlow() + : base(80, 200) + { + RelativeSizeAxes = Axes.Y; + Padding = new MarginPadding { Right = 10 }; + + FillFlow.Spacing = new Vector2(10); + } + } } /// diff --git a/osu.Game/Rulesets/Edit/ScrollingToolboxGroup.cs b/osu.Game/Rulesets/Edit/ScrollingToolboxGroup.cs index a54f574bff..9998a997b3 100644 --- a/osu.Game/Rulesets/Edit/ScrollingToolboxGroup.cs +++ b/osu.Game/Rulesets/Edit/ScrollingToolboxGroup.cs @@ -7,7 +7,7 @@ using osu.Game.Graphics.Containers; namespace osu.Game.Rulesets.Edit { - public class ScrollingToolboxGroup : ToolboxGroup + public class ScrollingToolboxGroup : EditorToolboxGroup { protected readonly OsuScrollContainer Scroll; From 690b425380cfb0c7e6bcb74066ccbf164fbc09da Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 6 Jan 2022 22:56:56 +0900 Subject: [PATCH 4/7] Move enum local to usage --- osu.Game/Overlays/ExpandingButtonContainer.cs | 7 ++++++- osu.Game/Overlays/Settings/SettingsSidebar.cs | 6 ------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/osu.Game/Overlays/ExpandingButtonContainer.cs b/osu.Game/Overlays/ExpandingButtonContainer.cs index a49f0493f6..5964f7f263 100644 --- a/osu.Game/Overlays/ExpandingButtonContainer.cs +++ b/osu.Game/Overlays/ExpandingButtonContainer.cs @@ -11,7 +11,6 @@ using osu.Framework.Testing; using osu.Framework.Threading; using osu.Game.Graphics.Containers; using osu.Game.Graphics.UserInterface; -using osu.Game.Overlays.Settings; using osuTK; namespace osu.Game.Overlays @@ -131,4 +130,10 @@ namespace osu.Game.Overlays lastHoveredButton = hoveredButton; } } + + public enum ExpandedState + { + Contracted, + Expanded, + } } diff --git a/osu.Game/Overlays/Settings/SettingsSidebar.cs b/osu.Game/Overlays/Settings/SettingsSidebar.cs index 5aa2e61162..e6ce90c33e 100644 --- a/osu.Game/Overlays/Settings/SettingsSidebar.cs +++ b/osu.Game/Overlays/Settings/SettingsSidebar.cs @@ -28,10 +28,4 @@ namespace osu.Game.Overlays.Settings }); } } - - public enum ExpandedState - { - Contracted, - Expanded, - } } From 5aca2dd4ce17a4d39375e6b6577490b7f67abe46 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 6 Jan 2022 23:08:50 +0900 Subject: [PATCH 5/7] Hide header text when it won't fit in the toolbox group --- osu.Game/Overlays/SettingsToolboxGroup.cs | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/SettingsToolboxGroup.cs b/osu.Game/Overlays/SettingsToolboxGroup.cs index 02b5bdc1e1..fcc7ff2504 100644 --- a/osu.Game/Overlays/SettingsToolboxGroup.cs +++ b/osu.Game/Overlays/SettingsToolboxGroup.cs @@ -2,11 +2,13 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; +using osu.Framework.Extensions.EnumExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; using osu.Framework.Input.Events; +using osu.Framework.Layout; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; @@ -53,6 +55,8 @@ namespace osu.Game.Overlays private Color4 expandedColour; + private readonly OsuSpriteText headerText; + /// /// Create a new instance. /// @@ -90,12 +94,10 @@ namespace osu.Game.Overlays Height = header_height, Children = new Drawable[] { - new OsuSpriteText + headerText = new OsuSpriteText { Origin = Anchor.CentreLeft, Anchor = Anchor.CentreLeft, - RelativeSizeAxes = Axes.X, - Truncate = true, Text = title.ToUpperInvariant(), Font = OsuFont.GetFont(weight: FontWeight.Bold, size: 17), Padding = new MarginPadding { Left = 10, Right = 30 }, @@ -132,6 +134,16 @@ namespace osu.Game.Overlays private const float fade_duration = 800; private const float inactive_alpha = 0.5f; + protected override bool OnInvalidate(Invalidation invalidation, InvalidationSource source) + { + // These toolbox grouped may be contracted to only show icons. + // For now, let's hide the header to avoid text truncation weirdness in such cases. + if (invalidation.HasFlagFast(Invalidation.DrawSize)) + headerText.FadeTo(headerText.DrawWidth < DrawWidth ? 1 : 0, 150, Easing.OutQuint); + + return base.OnInvalidate(invalidation, source); + } + protected override void LoadComplete() { base.LoadComplete(); From f703c5f03879f68a8996e7e30959f4cf0fa4f97f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 6 Jan 2022 23:38:54 +0900 Subject: [PATCH 6/7] Add comment and reduce how often `ChildrenOfType` is invoked in `ExpandingButtonContainer` --- osu.Game/Overlays/ExpandingButtonContainer.cs | 26 ++++++++++--------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/osu.Game/Overlays/ExpandingButtonContainer.cs b/osu.Game/Overlays/ExpandingButtonContainer.cs index 5964f7f263..4eb8c47a1f 100644 --- a/osu.Game/Overlays/ExpandingButtonContainer.cs +++ b/osu.Game/Overlays/ExpandingButtonContainer.cs @@ -65,7 +65,7 @@ namespace osu.Game.Overlays protected override void OnHoverLost(HoverLostEvent e) { expandEvent?.Cancel(); - lastHoveredButton = null; + hoveredButton = null; State = ExpandedState.Contracted; base.OnHoverLost(e); @@ -112,22 +112,24 @@ namespace osu.Game.Overlays } } - private Drawable lastHoveredButton; - - private Drawable hoveredButton => FillFlow.ChildrenOfType().FirstOrDefault(c => c.IsHovered); + private Drawable hoveredButton; private void queueExpandIfHovering() { - // only expand when we hover a different button. - if (lastHoveredButton == hoveredButton) return; + // if the same button is hovered, let the scheduled expand play out.. + if (hoveredButton?.IsHovered == true) + return; - if (State != ExpandedState.Expanded) - { - expandEvent?.Cancel(); + // ..otherwise check whether a new button is hovered, and if so, queue a new hover operation. + + // usually we wouldn't use ChildrenOfType in implementations, but this is the simplest way + // to handle cases like the editor where the buttons may be nested within a child hierarchy. + hoveredButton = FillFlow.ChildrenOfType().FirstOrDefault(c => c.IsHovered); + + expandEvent?.Cancel(); + + if (hoveredButton?.IsHovered == true && State != ExpandedState.Expanded) expandEvent = Scheduler.AddDelayed(() => State = ExpandedState.Expanded, 750); - } - - lastHoveredButton = hoveredButton; } } From e02863f7806e4ddeb49564aef48ac68bb537569b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 7 Jan 2022 01:24:30 +0900 Subject: [PATCH 7/7] Avoid accessing `DrawWidth` from invalidation --- osu.Game/Overlays/SettingsToolboxGroup.cs | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/osu.Game/Overlays/SettingsToolboxGroup.cs b/osu.Game/Overlays/SettingsToolboxGroup.cs index fcc7ff2504..ff8966d55f 100644 --- a/osu.Game/Overlays/SettingsToolboxGroup.cs +++ b/osu.Game/Overlays/SettingsToolboxGroup.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; +using osu.Framework.Caching; using osu.Framework.Extensions.EnumExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -25,6 +26,11 @@ namespace osu.Game.Overlays private const int header_height = 30; private const int corner_radius = 5; + private const float fade_duration = 800; + private const float inactive_alpha = 0.5f; + + private readonly Cached headerTextVisibilityCache = new Cached(); + private readonly FillFlowContainer content; private readonly IconButton button; @@ -131,19 +137,24 @@ namespace osu.Game.Overlays }; } - private const float fade_duration = 800; - private const float inactive_alpha = 0.5f; - protected override bool OnInvalidate(Invalidation invalidation, InvalidationSource source) { - // These toolbox grouped may be contracted to only show icons. - // For now, let's hide the header to avoid text truncation weirdness in such cases. if (invalidation.HasFlagFast(Invalidation.DrawSize)) - headerText.FadeTo(headerText.DrawWidth < DrawWidth ? 1 : 0, 150, Easing.OutQuint); + headerTextVisibilityCache.Invalidate(); return base.OnInvalidate(invalidation, source); } + protected override void Update() + { + base.Update(); + + if (!headerTextVisibilityCache.IsValid) + // These toolbox grouped may be contracted to only show icons. + // For now, let's hide the header to avoid text truncation weirdness in such cases. + headerText.FadeTo(headerText.DrawWidth < DrawWidth ? 1 : 0, 150, Easing.OutQuint); + } + protected override void LoadComplete() { base.LoadComplete();