diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs b/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs index 63b8acb234..63b46c991f 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs @@ -24,7 +24,7 @@ namespace osu.Game.Tests.Visual.Online typeof(ProfileHeader), typeof(RankGraph), typeof(LineGraph), - typeof(OverlayHeaderTabControl), + typeof(TabControlOverlayHeader.OverlayHeaderTabControl), typeof(CentreHeaderContainer), typeof(BottomHeaderContainer), typeof(DetailHeaderContainer), diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneBreadcrumbs.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneBreadcrumbControl.cs similarity index 92% rename from osu.Game.Tests/Visual/UserInterface/TestSceneBreadcrumbs.cs rename to osu.Game.Tests/Visual/UserInterface/TestSceneBreadcrumbControl.cs index 554696765e..19eebc89b6 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneBreadcrumbs.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneBreadcrumbControl.cs @@ -10,11 +10,11 @@ using osu.Game.Graphics.UserInterface; namespace osu.Game.Tests.Visual.UserInterface { [TestFixture] - public class TestSceneBreadcrumbs : OsuTestScene + public class TestSceneBreadcrumbControl : OsuTestScene { private readonly BreadcrumbControl breadcrumbs; - public TestSceneBreadcrumbs() + public TestSceneBreadcrumbControl() { Add(breadcrumbs = new BreadcrumbControl { diff --git a/osu.Game/Graphics/UserInterface/BreadcrumbControl.cs b/osu.Game/Graphics/UserInterface/BreadcrumbControl.cs index 93ea6bbbe6..e2438cc4cd 100644 --- a/osu.Game/Graphics/UserInterface/BreadcrumbControl.cs +++ b/osu.Game/Graphics/UserInterface/BreadcrumbControl.cs @@ -15,14 +15,13 @@ namespace osu.Game.Graphics.UserInterface public class BreadcrumbControl : OsuTabControl { private const float padding = 10; - private const float item_chevron_size = 10; protected override TabItem CreateTabItem(T value) => new BreadcrumbTabItem(value) { AccentColour = AccentColour, }; - protected override float StripWidth() => base.StripWidth() - (padding + item_chevron_size); + protected override float StripWidth => base.StripWidth - TabContainer.FirstOrDefault()?.Padding.Right ?? 0; public BreadcrumbControl() { @@ -41,8 +40,10 @@ namespace osu.Game.Graphics.UserInterface }; } - private class BreadcrumbTabItem : OsuTabItem, IStateful + protected class BreadcrumbTabItem : OsuTabItem, IStateful { + protected virtual float ChevronSize => 10; + public event Action StateChanged; public readonly SpriteIcon Chevron; @@ -90,12 +91,12 @@ namespace osu.Game.Graphics.UserInterface { Text.Font = Text.Font.With(size: 18); Text.Margin = new MarginPadding { Vertical = 8 }; - Padding = new MarginPadding { Right = padding + item_chevron_size }; + Padding = new MarginPadding { Right = padding + ChevronSize }; Add(Chevron = new SpriteIcon { Anchor = Anchor.CentreRight, Origin = Anchor.CentreLeft, - Size = new Vector2(item_chevron_size), + Size = new Vector2(ChevronSize), Icon = FontAwesome.Solid.ChevronRight, Margin = new MarginPadding { Left = padding }, Alpha = 0f, diff --git a/osu.Game/Graphics/UserInterface/OsuTabControl.cs b/osu.Game/Graphics/UserInterface/OsuTabControl.cs index 064cba6adf..ed8904db7e 100644 --- a/osu.Game/Graphics/UserInterface/OsuTabControl.cs +++ b/osu.Game/Graphics/UserInterface/OsuTabControl.cs @@ -28,8 +28,7 @@ namespace osu.Game.Graphics.UserInterface protected override TabItem CreateTabItem(T value) => new OsuTabItem(value); - protected virtual float StripWidth() => TabContainer.Children.Sum(c => c.IsPresent ? c.DrawWidth + TabContainer.Spacing.X : 0) - TabContainer.Spacing.X; - protected virtual float StripHeight() => 1; + protected virtual float StripWidth => TabContainer.Children.Sum(c => c.IsPresent ? c.DrawWidth + TabContainer.Spacing.X : 0) - TabContainer.Spacing.X; /// /// Whether entries should be automatically populated if is an type. @@ -46,7 +45,7 @@ namespace osu.Game.Graphics.UserInterface { Anchor = Anchor.BottomLeft, Origin = Anchor.BottomLeft, - Height = StripHeight(), + Height = 1, Colour = Color4.White.Opacity(0), }); @@ -99,7 +98,7 @@ namespace osu.Game.Graphics.UserInterface // dont bother calculating if the strip is invisible if (strip.Colour.MaxAlpha > 0) - strip.Width = Interpolation.ValueAt(Math.Clamp(Clock.ElapsedFrameTime, 0, 1000), strip.Width, StripWidth(), 0, 500, Easing.OutQuint); + strip.Width = Interpolation.ValueAt(Math.Clamp(Clock.ElapsedFrameTime, 0, 1000), strip.Width, StripWidth, 0, 500, Easing.OutQuint); } public class OsuTabItem : TabItem, IHasAccentColour diff --git a/osu.Game/Overlays/BreadcrumbControlOverlayHeader.cs b/osu.Game/Overlays/BreadcrumbControlOverlayHeader.cs new file mode 100644 index 0000000000..8a82b1f0c0 --- /dev/null +++ b/osu.Game/Overlays/BreadcrumbControlOverlayHeader.cs @@ -0,0 +1,39 @@ +// 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.Graphics; +using osu.Framework.Graphics.UserInterface; +using osu.Game.Graphics.UserInterface; + +namespace osu.Game.Overlays +{ + public abstract class BreadcrumbControlOverlayHeader : OverlayHeader + { + protected OverlayHeaderBreadcrumbControl BreadcrumbControl; + + protected override TabControl CreateTabControl() => BreadcrumbControl = new OverlayHeaderBreadcrumbControl(); + + public class OverlayHeaderBreadcrumbControl : BreadcrumbControl + { + public OverlayHeaderBreadcrumbControl() + { + RelativeSizeAxes = Axes.X; + } + + protected override TabItem CreateTabItem(string value) => new ControlTabItem(value); + + private class ControlTabItem : BreadcrumbTabItem + { + protected override float ChevronSize => 8; + + public ControlTabItem(string value) + : base(value) + { + Text.Font = Text.Font.With(size: 14); + Chevron.Y = 3; + Bar.Height = 0; + } + } + } + } +} diff --git a/osu.Game/Overlays/Changelog/ChangelogHeader.cs b/osu.Game/Overlays/Changelog/ChangelogHeader.cs index 3b6f0d778d..7e47a3e29f 100644 --- a/osu.Game/Overlays/Changelog/ChangelogHeader.cs +++ b/osu.Game/Overlays/Changelog/ChangelogHeader.cs @@ -15,7 +15,7 @@ using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Overlays.Changelog { - public class ChangelogHeader : OverlayHeader + public class ChangelogHeader : BreadcrumbControlOverlayHeader { public readonly Bindable Current = new Bindable(); @@ -23,12 +23,12 @@ namespace osu.Game.Overlays.Changelog public UpdateStreamBadgeArea Streams; - private const string listing_string = "Listing"; + private const string listing_string = "listing"; public ChangelogHeader() { - TabControl.AddItem(listing_string); - TabControl.Current.ValueChanged += e => + BreadcrumbControl.AddItem(listing_string); + BreadcrumbControl.Current.ValueChanged += e => { if (e.NewValue == listing_string) ListingSelected?.Invoke(); @@ -46,7 +46,7 @@ namespace osu.Game.Overlays.Changelog [BackgroundDependencyLoader] private void load(OsuColour colours) { - TabControl.AccentColour = colours.Violet; + BreadcrumbControl.AccentColour = colours.Violet; TitleBackgroundColour = colours.GreyVioletDarker; ControlBackgroundColour = colours.GreyVioletDark; } @@ -56,12 +56,12 @@ namespace osu.Game.Overlays.Changelog private void showBuild(ValueChangedEvent e) { if (e.OldValue != null) - TabControl.RemoveItem(e.OldValue.ToString()); + BreadcrumbControl.RemoveItem(e.OldValue.ToString()); if (e.NewValue != null) { - TabControl.AddItem(e.NewValue.ToString()); - TabControl.Current.Value = e.NewValue.ToString(); + BreadcrumbControl.AddItem(e.NewValue.ToString()); + BreadcrumbControl.Current.Value = e.NewValue.ToString(); Streams.Current.Value = Streams.Items.FirstOrDefault(s => s.Name == e.NewValue.UpdateStream.Name); @@ -69,7 +69,7 @@ namespace osu.Game.Overlays.Changelog } else { - TabControl.Current.Value = listing_string; + BreadcrumbControl.Current.Value = listing_string; Streams.Current.Value = null; title.Version = null; } diff --git a/osu.Game/Overlays/ChangelogOverlay.cs b/osu.Game/Overlays/ChangelogOverlay.cs index fbc9dfcbd9..15b0079277 100644 --- a/osu.Game/Overlays/ChangelogOverlay.cs +++ b/osu.Game/Overlays/ChangelogOverlay.cs @@ -158,7 +158,8 @@ namespace osu.Game.Overlays private Task initialFetchTask; - private void performAfterFetch(Action action) => fetchListing()?.ContinueWith(_ => Schedule(action)); + private void performAfterFetch(Action action) => fetchListing()?.ContinueWith(_ => + Schedule(action), TaskContinuationOptions.OnlyOnRanToCompletion); private Task fetchListing() { @@ -185,10 +186,10 @@ namespace osu.Game.Overlays tcs.SetResult(true); }); - req.Failure += _ => + req.Failure += e => { initialFetchTask = null; - tcs.SetResult(false); + tcs.SetException(e); }; await API.PerformAsync(req); diff --git a/osu.Game/Overlays/News/NewsHeader.cs b/osu.Game/Overlays/News/NewsHeader.cs index e3cf58ed0a..fc88c86df2 100644 --- a/osu.Game/Overlays/News/NewsHeader.cs +++ b/osu.Game/Overlays/News/NewsHeader.cs @@ -12,7 +12,7 @@ using System; namespace osu.Game.Overlays.News { - public class NewsHeader : OverlayHeader + public class NewsHeader : BreadcrumbControlOverlayHeader { private const string front_page_string = "frontpage"; @@ -24,9 +24,9 @@ namespace osu.Game.Overlays.News public NewsHeader() { - TabControl.AddItem(front_page_string); + BreadcrumbControl.AddItem(front_page_string); - TabControl.Current.ValueChanged += e => + BreadcrumbControl.Current.ValueChanged += e => { if (e.NewValue == front_page_string) ShowFrontPage?.Invoke(); @@ -38,7 +38,7 @@ namespace osu.Game.Overlays.News [BackgroundDependencyLoader] private void load(OsuColour colours) { - TabControl.AccentColour = colours.Violet; + BreadcrumbControl.AccentColour = colours.Violet; TitleBackgroundColour = colours.GreyVioletDarker; ControlBackgroundColour = colours.GreyVioletDark; } @@ -46,18 +46,18 @@ namespace osu.Game.Overlays.News private void showPost(ValueChangedEvent e) { if (e.OldValue != null) - TabControl.RemoveItem(e.OldValue); + BreadcrumbControl.RemoveItem(e.OldValue); if (e.NewValue != null) { - TabControl.AddItem(e.NewValue); - TabControl.Current.Value = e.NewValue; + BreadcrumbControl.AddItem(e.NewValue); + BreadcrumbControl.Current.Value = e.NewValue; title.IsReadingPost = true; } else { - TabControl.Current.Value = front_page_string; + BreadcrumbControl.Current.Value = front_page_string; title.IsReadingPost = false; } } diff --git a/osu.Game/Overlays/OverlayHeader.cs b/osu.Game/Overlays/OverlayHeader.cs index 7a397d10c6..53da2da634 100644 --- a/osu.Game/Overlays/OverlayHeader.cs +++ b/osu.Game/Overlays/OverlayHeader.cs @@ -5,6 +5,7 @@ using JetBrains.Annotations; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.UserInterface; using osu.Game.Graphics.UserInterface; using osuTK.Graphics; @@ -12,8 +13,6 @@ namespace osu.Game.Overlays { public abstract class OverlayHeader : Container { - protected readonly OverlayHeaderTabControl TabControl; - private readonly Box titleBackground; private readonly Box controlBackground; private readonly Container background; @@ -85,14 +84,7 @@ namespace osu.Game.Overlays RelativeSizeAxes = Axes.Both, Colour = Color4.Gray, }, - TabControl = new OverlayHeaderTabControl - { - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - RelativeSizeAxes = Axes.X, - Height = 30, - Padding = new MarginPadding { Left = UserProfileOverlay.CONTENT_X_MARGIN }, - } + CreateTabControl().With(control => control.Margin = new MarginPadding { Left = UserProfileOverlay.CONTENT_X_MARGIN }) } }, CreateContent() @@ -106,5 +98,7 @@ namespace osu.Game.Overlays protected virtual Drawable CreateContent() => new Container(); protected abstract ScreenTitle CreateTitle(); + + protected abstract TabControl CreateTabControl(); } } diff --git a/osu.Game/Overlays/OverlayHeaderTabControl.cs b/osu.Game/Overlays/OverlayHeaderTabControl.cs deleted file mode 100644 index 7d0cdad6d8..0000000000 --- a/osu.Game/Overlays/OverlayHeaderTabControl.cs +++ /dev/null @@ -1,24 +0,0 @@ -// 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.Graphics.UserInterface; - -namespace osu.Game.Overlays -{ - public class OverlayHeaderTabControl : OverlayTabControl - { - protected override TabItem CreateTabItem(string value) => new OverlayHeaderTabItem(value) - { - AccentColour = AccentColour, - }; - - private class OverlayHeaderTabItem : OverlayTabItem - { - public OverlayHeaderTabItem(string value) - : base(value) - { - Text.Text = value; - } - } - } -} diff --git a/osu.Game/Overlays/OverlayTabControl.cs b/osu.Game/Overlays/OverlayTabControl.cs index 4c396eabc1..812f8963c9 100644 --- a/osu.Game/Overlays/OverlayTabControl.cs +++ b/osu.Game/Overlays/OverlayTabControl.cs @@ -43,6 +43,11 @@ namespace osu.Game.Overlays set => TabContainer.Padding = value; } + protected float BarHeight + { + set => bar.Height = value; + } + protected OverlayTabControl() { TabContainer.Masking = false; @@ -63,8 +68,7 @@ namespace osu.Game.Overlays protected class OverlayTabItem : TabItem { - private readonly ExpandingBar bar; - + protected readonly ExpandingBar Bar; protected readonly OsuSpriteText Text; private Color4 accentColour; @@ -78,7 +82,7 @@ namespace osu.Game.Overlays return; accentColour = value; - bar.Colour = value; + Bar.Colour = value; updateState(); } @@ -99,7 +103,7 @@ namespace osu.Game.Overlays Anchor = Anchor.BottomLeft, Font = OsuFont.GetFont(), }, - bar = new ExpandingBar + Bar = new ExpandingBar { Anchor = Anchor.BottomCentre, ExpandedSize = 7.5f, @@ -149,13 +153,13 @@ namespace osu.Game.Overlays protected virtual void HoverAction() { - bar.Expand(); + Bar.Expand(); Text.FadeColour(Color4.White, 120, Easing.InQuad); } protected virtual void UnhoverAction() { - bar.Collapse(); + Bar.Collapse(); Text.FadeColour(AccentColour, 120, Easing.InQuad); } } diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index 4a792f7375..59e64dfc26 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -15,7 +15,7 @@ using osu.Game.Users; namespace osu.Game.Overlays.Profile { - public class ProfileHeader : OverlayHeader + public class ProfileHeader : TabControlOverlayHeader { private UserCoverBackground coverContainer; @@ -30,8 +30,8 @@ namespace osu.Game.Overlays.Profile User.ValueChanged += e => updateDisplay(e.NewValue); - TabControl.AddItem("Info"); - TabControl.AddItem("Modding"); + TabControl.AddItem("info"); + TabControl.AddItem("modding"); centreHeaderContainer.DetailsVisible.BindValueChanged(visible => detailHeaderContainer.Expanded = visible.NewValue, true); } diff --git a/osu.Game/Overlays/TabControlOverlayHeader.cs b/osu.Game/Overlays/TabControlOverlayHeader.cs new file mode 100644 index 0000000000..f3521b66c8 --- /dev/null +++ b/osu.Game/Overlays/TabControlOverlayHeader.cs @@ -0,0 +1,55 @@ +// 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.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.UserInterface; +using osu.Game.Graphics; +using osuTK; + +namespace osu.Game.Overlays +{ + public abstract class TabControlOverlayHeader : OverlayHeader + { + protected OverlayHeaderTabControl TabControl; + + protected override TabControl CreateTabControl() => TabControl = new OverlayHeaderTabControl(); + + public class OverlayHeaderTabControl : OverlayTabControl + { + public OverlayHeaderTabControl() + { + BarHeight = 1; + RelativeSizeAxes = Axes.None; + AutoSizeAxes = Axes.X; + Anchor = Anchor.BottomLeft; + Origin = Anchor.BottomLeft; + Height = 35; + } + + protected override TabItem CreateTabItem(string value) => new OverlayHeaderTabItem(value) + { + AccentColour = AccentColour, + }; + + protected override TabFillFlowContainer CreateTabFlow() => new TabFillFlowContainer + { + RelativeSizeAxes = Axes.Y, + AutoSizeAxes = Axes.X, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(5, 0), + }; + + private class OverlayHeaderTabItem : OverlayTabItem + { + public OverlayHeaderTabItem(string value) + : base(value) + { + Text.Text = value; + Text.Font = OsuFont.GetFont(size: 14); + Bar.ExpandedSize = 5; + } + } + } + } +}