diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs b/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs index f825e4f1e9..523de4e38f 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(TabControlOverlayHeader.OverlayHeaderTabControl), + typeof(TabControlOverlayHeader<>.OverlayHeaderTabControl), typeof(CentreHeaderContainer), typeof(BottomHeaderContainer), typeof(DetailHeaderContainer), diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayHeader.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayHeader.cs new file mode 100644 index 0000000000..be0933e9d4 --- /dev/null +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayHeader.cs @@ -0,0 +1,175 @@ +// 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.Containers; +using osu.Game.Overlays; +using System; +using System.Collections.Generic; +using osu.Framework.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Allocation; +using osu.Framework.Graphics.Textures; +using osu.Game.Graphics.UserInterface; +using osu.Framework.Graphics.Shapes; +using osuTK.Graphics; + +namespace osu.Game.Tests.Visual.UserInterface +{ + public class TestSceneOverlayHeader : OsuTestScene + { + public override IReadOnlyList RequiredTypes => new[] + { + typeof(OverlayHeader), + typeof(TabControlOverlayHeader<>), + typeof(BreadcrumbControlOverlayHeader), + typeof(TestNoControlHeader), + typeof(TestStringTabControlHeader), + typeof(TestEnumTabControlHeader), + typeof(TestBreadcrumbControlHeader), + }; + + private readonly FillFlowContainer flow; + + public TestSceneOverlayHeader() + { + AddRange(new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Black, + }, + new BasicScrollContainer + { + RelativeSizeAxes = Axes.Both, + Child = flow = new FillFlowContainer + { + AutoSizeAxes = Axes.Y, + RelativeSizeAxes = Axes.X, + Direction = FillDirection.Vertical + } + } + }); + + addHeader("Blue OverlayHeader", new TestNoControlHeader(), OverlayColourScheme.Blue); + addHeader("Green TabControlOverlayHeader (string)", new TestStringTabControlHeader(), OverlayColourScheme.Green); + addHeader("Pink TabControlOverlayHeader (enum)", new TestEnumTabControlHeader(), OverlayColourScheme.Pink); + addHeader("Red BreadcrumbControlOverlayHeader", new TestBreadcrumbControlHeader(), OverlayColourScheme.Red); + } + + private void addHeader(string name, OverlayHeader header, OverlayColourScheme colourScheme) + { + flow.Add(new FillFlowContainer + { + AutoSizeAxes = Axes.Y, + RelativeSizeAxes = Axes.X, + Direction = FillDirection.Vertical, + Children = new Drawable[] + { + new OsuSpriteText + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + Margin = new MarginPadding(20), + Text = name, + }, + new ColourProvidedContainer(colourScheme, header) + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + } + } + }); + } + + private class ColourProvidedContainer : Container + { + [Cached] + private readonly OverlayColourProvider colourProvider; + + public ColourProvidedContainer(OverlayColourScheme colourScheme, OverlayHeader header) + { + colourProvider = new OverlayColourProvider(colourScheme); + + AutoSizeAxes = Axes.Y; + RelativeSizeAxes = Axes.X; + Add(header); + } + } + + private class TestNoControlHeader : OverlayHeader + { + protected override Drawable CreateBackground() => new TestBackground(); + + protected override ScreenTitle CreateTitle() => new TestTitle(); + } + + private class TestStringTabControlHeader : TabControlOverlayHeader + { + protected override Drawable CreateBackground() => new TestBackground(); + + protected override ScreenTitle CreateTitle() => new TestTitle(); + + public TestStringTabControlHeader() + { + TabControl.AddItem("tab1"); + TabControl.AddItem("tab2"); + } + } + + private class TestEnumTabControlHeader : TabControlOverlayHeader + { + protected override Drawable CreateBackground() => new TestBackground(); + + protected override ScreenTitle CreateTitle() => new TestTitle(); + } + + private enum TestEnum + { + Some, + Cool, + Tabs + } + + private class TestBreadcrumbControlHeader : BreadcrumbControlOverlayHeader + { + protected override Drawable CreateBackground() => new TestBackground(); + + protected override ScreenTitle CreateTitle() => new TestTitle(); + + public TestBreadcrumbControlHeader() + { + TabControl.AddItem("tab1"); + TabControl.AddItem("tab2"); + TabControl.Current.Value = "tab2"; + } + } + + private class TestBackground : Sprite + { + public TestBackground() + { + RelativeSizeAxes = Axes.Both; + FillMode = FillMode.Fill; + } + + [BackgroundDependencyLoader] + private void load(TextureStore textures) + { + Texture = textures.Get(@"Headers/changelog"); + } + } + + private class TestTitle : ScreenTitle + { + public TestTitle() + { + Title = "title"; + Section = "section"; + } + + protected override Drawable CreateIcon() => new ScreenTitleTextureIcon(@"Icons/changelog"); + } + } +} diff --git a/osu.Game/Graphics/UserInterface/OsuTabControl.cs b/osu.Game/Graphics/UserInterface/OsuTabControl.cs index 1bfbee4a60..9fa6085035 100644 --- a/osu.Game/Graphics/UserInterface/OsuTabControl.cs +++ b/osu.Game/Graphics/UserInterface/OsuTabControl.cs @@ -21,6 +21,22 @@ namespace osu.Game.Graphics.UserInterface { public class OsuTabControl : TabControl { + private Color4 accentColour; + + public virtual Color4 AccentColour + { + get => accentColour; + set + { + accentColour = value; + + if (Dropdown is IHasAccentColour dropdown) + dropdown.AccentColour = value; + foreach (var i in TabContainer.Children.OfType()) + i.AccentColour = value; + } + } + private readonly Box strip; protected override Dropdown CreateDropdown() => new OsuTabDropdown(); @@ -62,21 +78,6 @@ namespace osu.Game.Graphics.UserInterface AccentColour = colours.Blue; } - private Color4 accentColour; - - public Color4 AccentColour - { - get => accentColour; - set - { - accentColour = value; - if (Dropdown is IHasAccentColour dropdown) - dropdown.AccentColour = value; - foreach (var i in TabContainer.Children.OfType()) - i.AccentColour = value; - } - } - public Color4 StripColour { get => strip.Colour; diff --git a/osu.Game/Overlays/BreadcrumbControlOverlayHeader.cs b/osu.Game/Overlays/BreadcrumbControlOverlayHeader.cs index c3f35b4313..1d8411dfcc 100644 --- a/osu.Game/Overlays/BreadcrumbControlOverlayHeader.cs +++ b/osu.Game/Overlays/BreadcrumbControlOverlayHeader.cs @@ -1,24 +1,15 @@ // 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.UserInterface; using osu.Game.Graphics.UserInterface; namespace osu.Game.Overlays { - public abstract class BreadcrumbControlOverlayHeader : OverlayHeader + public abstract class BreadcrumbControlOverlayHeader : TabControlOverlayHeader { - protected OverlayHeaderBreadcrumbControl BreadcrumbControl; - - protected override TabControl CreateTabControl() => BreadcrumbControl = new OverlayHeaderBreadcrumbControl(); - - [BackgroundDependencyLoader] - private void load(OverlayColourProvider colourProvider) - { - BreadcrumbControl.AccentColour = colourProvider.Highlight1; - } + protected override OsuTabControl CreateTabControl() => new OverlayHeaderBreadcrumbControl(); public class OverlayHeaderBreadcrumbControl : BreadcrumbControl { diff --git a/osu.Game/Overlays/Changelog/ChangelogHeader.cs b/osu.Game/Overlays/Changelog/ChangelogHeader.cs index 7755c0f64b..2fbfdec3d1 100644 --- a/osu.Game/Overlays/Changelog/ChangelogHeader.cs +++ b/osu.Game/Overlays/Changelog/ChangelogHeader.cs @@ -27,8 +27,8 @@ namespace osu.Game.Overlays.Changelog public ChangelogHeader() { - BreadcrumbControl.AddItem(listing_string); - BreadcrumbControl.Current.ValueChanged += e => + TabControl.AddItem(listing_string); + TabControl.Current.ValueChanged += e => { if (e.NewValue == listing_string) ListingSelected?.Invoke(); @@ -48,12 +48,12 @@ namespace osu.Game.Overlays.Changelog private void showBuild(ValueChangedEvent e) { if (e.OldValue != null) - BreadcrumbControl.RemoveItem(e.OldValue.ToString()); + TabControl.RemoveItem(e.OldValue.ToString()); if (e.NewValue != null) { - BreadcrumbControl.AddItem(e.NewValue.ToString()); - BreadcrumbControl.Current.Value = e.NewValue.ToString(); + TabControl.AddItem(e.NewValue.ToString()); + TabControl.Current.Value = e.NewValue.ToString(); updateCurrentStream(); @@ -61,7 +61,7 @@ namespace osu.Game.Overlays.Changelog } else { - BreadcrumbControl.Current.Value = listing_string; + TabControl.Current.Value = listing_string; Streams.Current.Value = null; title.Version = null; } diff --git a/osu.Game/Overlays/News/NewsHeader.cs b/osu.Game/Overlays/News/NewsHeader.cs index 1152d9044b..2f9cde1687 100644 --- a/osu.Game/Overlays/News/NewsHeader.cs +++ b/osu.Game/Overlays/News/NewsHeader.cs @@ -23,9 +23,9 @@ namespace osu.Game.Overlays.News public NewsHeader() { - BreadcrumbControl.AddItem(front_page_string); + TabControl.AddItem(front_page_string); - BreadcrumbControl.Current.ValueChanged += e => + TabControl.Current.ValueChanged += e => { if (e.NewValue == front_page_string) ShowFrontPage?.Invoke(); @@ -37,18 +37,18 @@ namespace osu.Game.Overlays.News private void showPost(ValueChangedEvent e) { if (e.OldValue != null) - BreadcrumbControl.RemoveItem(e.OldValue); + TabControl.RemoveItem(e.OldValue); if (e.NewValue != null) { - BreadcrumbControl.AddItem(e.NewValue); - BreadcrumbControl.Current.Value = e.NewValue; + TabControl.AddItem(e.NewValue); + TabControl.Current.Value = e.NewValue; title.IsReadingPost = true; } else { - BreadcrumbControl.Current.Value = front_page_string; + TabControl.Current.Value = front_page_string; title.IsReadingPost = false; } } diff --git a/osu.Game/Overlays/OverlayHeader.cs b/osu.Game/Overlays/OverlayHeader.cs index bc58a17401..0575f6f296 100644 --- a/osu.Game/Overlays/OverlayHeader.cs +++ b/osu.Game/Overlays/OverlayHeader.cs @@ -6,7 +6,6 @@ using osu.Framework.Allocation; 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; @@ -15,10 +14,11 @@ namespace osu.Game.Overlays public abstract class OverlayHeader : Container { private readonly Box titleBackground; - private readonly Box controlBackground; private readonly Container background; private readonly ScreenTitle title; + protected readonly FillFlowContainer HeaderInfo; + protected float BackgroundHeight { set => background.Height = value; @@ -36,46 +36,42 @@ namespace osu.Game.Overlays Direction = FillDirection.Vertical, Children = new[] { - background = new Container - { - RelativeSizeAxes = Axes.X, - Height = 80, - Masking = true, - Child = CreateBackground() - }, - new Container - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Children = new Drawable[] - { - titleBackground = new Box - { - RelativeSizeAxes = Axes.Both, - }, - title = CreateTitle().With(title => - { - title.Margin = new MarginPadding - { - Vertical = 10, - Left = UserProfileOverlay.CONTENT_X_MARGIN - }; - }) - } - }, - new Container + HeaderInfo = new FillFlowContainer { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, Depth = -float.MaxValue, Children = new Drawable[] { - controlBackground = new Box + background = new Container { - RelativeSizeAxes = Axes.Both, - Colour = Color4.Gray, + RelativeSizeAxes = Axes.X, + Height = 80, + Masking = true, + Child = CreateBackground() + }, + new Container + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Children = new Drawable[] + { + titleBackground = new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Gray, + }, + title = CreateTitle().With(title => + { + title.Margin = new MarginPadding + { + Vertical = 10, + Left = UserProfileOverlay.CONTENT_X_MARGIN + }; + }) + } }, - CreateTabControl().With(control => control.Margin = new MarginPadding { Left = UserProfileOverlay.CONTENT_X_MARGIN }) } }, CreateContent() @@ -88,7 +84,6 @@ namespace osu.Game.Overlays { titleBackground.Colour = colourProvider.Dark5; title.AccentColour = colourProvider.Highlight1; - controlBackground.Colour = colourProvider.Dark4; } protected abstract Drawable CreateBackground(); @@ -97,7 +92,5 @@ namespace osu.Game.Overlays protected virtual Drawable CreateContent() => new Container(); protected abstract ScreenTitle CreateTitle(); - - protected abstract TabControl CreateTabControl(); } } diff --git a/osu.Game/Overlays/OverlayTabControl.cs b/osu.Game/Overlays/OverlayTabControl.cs index 812f8963c9..aa96f0e19b 100644 --- a/osu.Game/Overlays/OverlayTabControl.cs +++ b/osu.Game/Overlays/OverlayTabControl.cs @@ -13,41 +13,25 @@ using osuTK.Graphics; namespace osu.Game.Overlays { - public abstract class OverlayTabControl : TabControl + public abstract class OverlayTabControl : OsuTabControl { private readonly Box bar; - private Color4 accentColour = Color4.White; - - public Color4 AccentColour - { - get => accentColour; - set - { - if (accentColour == value) - return; - - accentColour = value; - bar.Colour = value; - - foreach (TabItem tabItem in TabContainer) - { - ((OverlayTabItem)tabItem).AccentColour = value; - } - } - } - - public new MarginPadding Padding - { - get => TabContainer.Padding; - set => TabContainer.Padding = value; - } - protected float BarHeight { set => bar.Height = value; } + public override Color4 AccentColour + { + get => base.AccentColour; + set + { + base.AccentColour = value; + bar.Colour = value; + } + } + protected OverlayTabControl() { TabContainer.Masking = false; @@ -66,7 +50,7 @@ namespace osu.Game.Overlays protected override TabItem CreateTabItem(T value) => new OverlayTabItem(value); - protected class OverlayTabItem : TabItem + protected class OverlayTabItem : TabItem, IHasAccentColour { protected readonly ExpandingBar Bar; protected readonly OsuSpriteText Text; diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index f8eb03770a..203df2ec12 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -14,7 +14,7 @@ using osu.Game.Users; namespace osu.Game.Overlays.Profile { - public class ProfileHeader : TabControlOverlayHeader + public class ProfileHeader : TabControlOverlayHeader { private UserCoverBackground coverContainer; diff --git a/osu.Game/Overlays/TabControlOverlayHeader.cs b/osu.Game/Overlays/TabControlOverlayHeader.cs index 0c55b8383b..b410739b25 100644 --- a/osu.Game/Overlays/TabControlOverlayHeader.cs +++ b/osu.Game/Overlays/TabControlOverlayHeader.cs @@ -1,28 +1,56 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.UserInterface; using osu.Game.Graphics; +using osu.Game.Graphics.UserInterface; using osuTK; namespace osu.Game.Overlays { - public abstract class TabControlOverlayHeader : OverlayHeader + /// + /// An overlay header which contains a . + /// + /// The type of item to be represented by tabs. + public abstract class TabControlOverlayHeader : OverlayHeader { - protected OverlayHeaderTabControl TabControl; + protected OsuTabControl TabControl; - protected override TabControl CreateTabControl() => TabControl = new OverlayHeaderTabControl(); + private readonly Box controlBackground; + + protected TabControlOverlayHeader() + { + HeaderInfo.Add(new Container + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Children = new Drawable[] + { + controlBackground = new Box + { + RelativeSizeAxes = Axes.Both, + }, + TabControl = CreateTabControl().With(control => control.Margin = new MarginPadding { Left = UserProfileOverlay.CONTENT_X_MARGIN }) + } + }); + } [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) { TabControl.AccentColour = colourProvider.Highlight1; + controlBackground.Colour = colourProvider.Dark4; } - public class OverlayHeaderTabControl : OverlayTabControl + [NotNull] + protected virtual OsuTabControl CreateTabControl() => new OverlayHeaderTabControl(); + + public class OverlayHeaderTabControl : OverlayTabControl { public OverlayHeaderTabControl() { @@ -34,10 +62,7 @@ namespace osu.Game.Overlays Height = 35; } - protected override TabItem CreateTabItem(string value) => new OverlayHeaderTabItem(value) - { - AccentColour = AccentColour, - }; + protected override TabItem CreateTabItem(T value) => new OverlayHeaderTabItem(value); protected override TabFillFlowContainer CreateTabFlow() => new TabFillFlowContainer { @@ -49,10 +74,10 @@ namespace osu.Game.Overlays private class OverlayHeaderTabItem : OverlayTabItem { - public OverlayHeaderTabItem(string value) + public OverlayHeaderTabItem(T value) : base(value) { - Text.Text = value; + Text.Text = value.ToString().ToLower(); Text.Font = OsuFont.GetFont(size: 14); Bar.ExpandedSize = 5; }