From af248457b02b9380c49dc09d8dd2085b9ebe7766 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 1 Jan 2020 22:49:04 +0300 Subject: [PATCH 01/10] Implement OverlayRulesetSelector --- .../TestSceneOverlayRulesetSelector.cs | 68 +++++++++++++ osu.Game/Overlays/OverlayRulesetSelector.cs | 44 +++++++++ osu.Game/Overlays/OverlayRulesetTabItem.cs | 98 +++++++++++++++++++ 3 files changed, 210 insertions(+) create mode 100644 osu.Game.Tests/Visual/UserInterface/TestSceneOverlayRulesetSelector.cs create mode 100644 osu.Game/Overlays/OverlayRulesetSelector.cs create mode 100644 osu.Game/Overlays/OverlayRulesetTabItem.cs diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayRulesetSelector.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayRulesetSelector.cs new file mode 100644 index 0000000000..6c921b13b4 --- /dev/null +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayRulesetSelector.cs @@ -0,0 +1,68 @@ +// 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 System; +using System.Collections.Generic; +using osu.Game.Rulesets.Catch; +using osu.Game.Rulesets.Mania; +using osu.Game.Rulesets.Osu; +using osu.Game.Rulesets.Taiko; +using osu.Framework.Bindables; +using osu.Game.Overlays; +using osu.Game.Rulesets; +using NUnit.Framework; +using osu.Game.Graphics; +using osu.Framework.Allocation; + +namespace osu.Game.Tests.Visual.UserInterface +{ + public class TestSceneOverlayRulesetSelector : OsuTestScene + { + public override IReadOnlyList RequiredTypes => new[] + { + typeof(OverlayRulesetSelector), + typeof(OverlayRulesetTabItem), + }; + + private readonly OverlayRulesetSelector selector; + private readonly Bindable ruleset = new Bindable(); + + public TestSceneOverlayRulesetSelector() + { + Add(selector = new OverlayRulesetSelector + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Current = ruleset, + }); + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + selector.AccentColour = colours.Lime; + } + + [Test] + public void TestSelection() + { + var osuRuleset = new OsuRuleset().RulesetInfo; + var maniaRuleset = new ManiaRuleset().RulesetInfo; + var taikoRuleset = new TaikoRuleset().RulesetInfo; + var catchRuleset = new CatchRuleset().RulesetInfo; + + AddStep("Select osu!", () => ruleset.Value = osuRuleset); + AddAssert("Check osu! selected", () => selector.Current.Value == osuRuleset); + + AddStep("Select mania", () => ruleset.Value = maniaRuleset); + AddAssert("Check mania selected", () => selector.Current.Value == maniaRuleset); + + AddStep("Select taiko", () => ruleset.Value = taikoRuleset); + AddAssert("Check taiko selected", () => selector.Current.Value == taikoRuleset); + + AddStep("Select catch", () => ruleset.Value = catchRuleset); + AddAssert("Check catch selected", () => selector.Current.Value == catchRuleset); + } + } +} diff --git a/osu.Game/Overlays/OverlayRulesetSelector.cs b/osu.Game/Overlays/OverlayRulesetSelector.cs new file mode 100644 index 0000000000..1dcfc97562 --- /dev/null +++ b/osu.Game/Overlays/OverlayRulesetSelector.cs @@ -0,0 +1,44 @@ +// 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 osu.Game.Rulesets; +using osuTK; +using osuTK.Graphics; +using System.Linq; + +namespace osu.Game.Overlays +{ + public class OverlayRulesetSelector : RulesetSelector + { + private Color4 accentColour; + + public Color4 AccentColour + { + get => accentColour; + set + { + accentColour = value; + foreach (var i in TabContainer.Children.OfType()) + i.AccentColour = value; + } + } + + public OverlayRulesetSelector() + { + AutoSizeAxes = Axes.Both; + } + + protected override TabItem CreateTabItem(RulesetInfo value) => new OverlayRulesetTabItem(value); + + protected override TabFillFlowContainer CreateTabFlow() => new TabFillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(25, 0), + }; + } +} diff --git a/osu.Game/Overlays/OverlayRulesetTabItem.cs b/osu.Game/Overlays/OverlayRulesetTabItem.cs new file mode 100644 index 0000000000..9d6d28a81f --- /dev/null +++ b/osu.Game/Overlays/OverlayRulesetTabItem.cs @@ -0,0 +1,98 @@ +// 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.Framework.Input.Events; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Game.Graphics.UserInterface; +using osu.Game.Rulesets; +using osuTK.Graphics; +using osuTK; + +namespace osu.Game.Overlays +{ + public class OverlayRulesetTabItem : TabItem, IHasAccentColour + { + protected readonly OsuSpriteText Text; + private readonly FillFlowContainer content; + + public override bool PropagatePositionalInputSubTree => Enabled.Value && !Active.Value && base.PropagatePositionalInputSubTree; + + private Color4 accentColour; + + public Color4 AccentColour + { + get => accentColour; + set + { + if (accentColour == value) + return; + + accentColour = value; + + UpdateState(); + } + } + + protected override Container Content => content; + + public OverlayRulesetTabItem(RulesetInfo value) + : base(value) + { + AutoSizeAxes = Axes.Both; + + AddRangeInternal(new Drawable[] + { + content = new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(3, 0), + Child = Text = new OsuSpriteText + { + Origin = Anchor.Centre, + Anchor = Anchor.Centre, + Text = value.Name, + } + }, + new HoverClickSounds() + }); + + Enabled.Value = true; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + Enabled.BindValueChanged(_ => UpdateState(), true); + } + + protected override bool OnHover(HoverEvent e) + { + base.OnHover(e); + UpdateState(); + return true; + } + + protected override void OnHoverLost(HoverLostEvent e) + { + base.OnHoverLost(e); + UpdateState(); + } + + protected override void OnActivated() => UpdateState(); + + protected override void OnDeactivated() => UpdateState(); + + protected virtual void UpdateState() + { + Text.Font = Text.Font.With(weight: Active.Value ? FontWeight.Bold : FontWeight.Medium); + Text.FadeColour(GetColour(), 120, Easing.OutQuint); + } + + protected Color4 GetColour() => IsHovered || Active.Value ? Color4.White : Enabled.Value ? AccentColour : Color4.DimGray; + } +} From b016238c16f8ac0d8e2c6e97d1e2559c6c58930e Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 1 Jan 2020 22:55:28 +0300 Subject: [PATCH 02/10] Make ProfileRulesetSelector inherit from OverlayRulesetSelector --- .../Online/TestSceneProfileRulesetSelector.cs | 2 +- .../Components/ProfileRulesetSelector.cs | 33 +------ .../Components/ProfileRulesetTabItem.cs | 97 +++---------------- 3 files changed, 20 insertions(+), 112 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneProfileRulesetSelector.cs b/osu.Game.Tests/Visual/Online/TestSceneProfileRulesetSelector.cs index 1f5ba67e03..a36b6880d2 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneProfileRulesetSelector.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneProfileRulesetSelector.cs @@ -25,7 +25,7 @@ public class TestSceneProfileRulesetSelector : OsuTestScene public TestSceneProfileRulesetSelector() { ProfileRulesetSelector selector; - Bindable user = new Bindable(); + var user = new Bindable(); Child = selector = new ProfileRulesetSelector { diff --git a/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs index 2c9a3dd5f9..e63102f989 100644 --- a/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs +++ b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs @@ -3,37 +3,21 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.UserInterface; using osu.Game.Graphics; using osu.Game.Rulesets; using osu.Game.Users; -using osuTK; -using osuTK.Graphics; namespace osu.Game.Overlays.Profile.Header.Components { - public class ProfileRulesetSelector : RulesetSelector + public class ProfileRulesetSelector : OverlayRulesetSelector { - private Color4 accentColour = Color4.White; - public readonly Bindable User = new Bindable(); - public ProfileRulesetSelector() - { - TabContainer.Masking = false; - TabContainer.Spacing = new Vector2(10, 0); - AutoSizeAxes = Axes.Both; - } - [BackgroundDependencyLoader] private void load(OsuColour colours) { - accentColour = colours.Seafoam; - - foreach (TabItem tabItem in TabContainer) - ((ProfileRulesetTabItem)tabItem).AccentColour = accentColour; + AccentColour = colours.Seafoam; } protected override void LoadComplete() @@ -45,19 +29,10 @@ protected override void LoadComplete() public void SetDefaultRuleset(RulesetInfo ruleset) { - foreach (TabItem tabItem in TabContainer) + foreach (var tabItem in TabContainer) ((ProfileRulesetTabItem)tabItem).IsDefault = ((ProfileRulesetTabItem)tabItem).Value.ID == ruleset.ID; } - protected override TabItem CreateTabItem(RulesetInfo value) => new ProfileRulesetTabItem(value) - { - AccentColour = accentColour - }; - - protected override TabFillFlowContainer CreateTabFlow() => new TabFillFlowContainer - { - Direction = FillDirection.Horizontal, - AutoSizeAxes = Axes.Both, - }; + protected override TabItem CreateTabItem(RulesetInfo value) => new ProfileRulesetTabItem(value); } } diff --git a/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetTabItem.cs b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetTabItem.cs index b5170ea3a2..adf324b259 100644 --- a/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetTabItem.cs +++ b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetTabItem.cs @@ -2,38 +2,21 @@ // 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.Sprites; -using osu.Framework.Graphics.UserInterface; -using osu.Framework.Input.Events; -using osu.Game.Graphics; -using osu.Game.Graphics.Sprites; -using osu.Game.Graphics.UserInterface; using osu.Game.Rulesets; using osuTK; using osuTK.Graphics; namespace osu.Game.Overlays.Profile.Header.Components { - public class ProfileRulesetTabItem : TabItem, IHasAccentColour + public class ProfileRulesetTabItem : OverlayRulesetTabItem { - private readonly OsuSpriteText text; private readonly SpriteIcon icon; - private Color4 accentColour; - - public Color4 AccentColour + public new Color4 AccentColour { - get => accentColour; - set - { - if (accentColour == value) - return; - - accentColour = value; - - updateState(); - } + get => base.AccentColour; + set => base.AccentColour = icon.Colour = value; } private bool isDefault; @@ -55,71 +38,21 @@ public bool IsDefault public ProfileRulesetTabItem(RulesetInfo value) : base(value) { - AutoSizeAxes = Axes.Both; - - Children = new Drawable[] + Add(icon = new SpriteIcon { - new FillFlowContainer - { - AutoSizeAxes = Axes.Both, - Origin = Anchor.BottomLeft, - Anchor = Anchor.BottomLeft, - Direction = FillDirection.Horizontal, - Spacing = new Vector2(3, 0), - Children = new Drawable[] - { - text = new OsuSpriteText - { - Origin = Anchor.Centre, - Anchor = Anchor.Centre, - Text = value.Name, - }, - icon = new SpriteIcon - { - Origin = Anchor.Centre, - Anchor = Anchor.Centre, - Alpha = 0, - AlwaysPresent = true, - Icon = FontAwesome.Solid.Star, - Size = new Vector2(12), - }, - } - }, - new HoverClickSounds() - }; + Origin = Anchor.Centre, + Anchor = Anchor.Centre, + Alpha = 0, + AlwaysPresent = true, + Icon = FontAwesome.Solid.Star, + Size = new Vector2(12), + }); } - protected override bool OnHover(HoverEvent e) + protected override void UpdateState() { - base.OnHover(e); - updateState(); - return true; - } - - protected override void OnHoverLost(HoverLostEvent e) - { - base.OnHoverLost(e); - updateState(); - } - - protected override void OnActivated() => updateState(); - - protected override void OnDeactivated() => updateState(); - - private void updateState() - { - text.Font = text.Font.With(weight: Active.Value ? FontWeight.Bold : FontWeight.Medium); - - if (IsHovered || Active.Value) - { - text.FadeColour(Color4.White, 120, Easing.InQuad); - icon.FadeColour(Color4.White, 120, Easing.InQuad); - } - else - { - text.FadeColour(AccentColour, 120, Easing.InQuad); - icon.FadeColour(AccentColour, 120, Easing.InQuad); - } + base.UpdateState(); + icon.FadeColour(GetColour(), 120, Easing.OutQuint); } } } From 2d6a07e970420893feea193e778f1ff3cc28e4f9 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 1 Jan 2020 23:14:26 +0300 Subject: [PATCH 03/10] Fix OverlayRulesetSelector don't have default colour --- .../TestSceneOverlayRulesetSelector.cs | 35 +++++++++---------- osu.Game/Overlays/OverlayRulesetSelector.cs | 8 +++++ 2 files changed, 25 insertions(+), 18 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayRulesetSelector.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayRulesetSelector.cs index 6c921b13b4..93aa414c94 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayRulesetSelector.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayRulesetSelector.cs @@ -25,6 +25,9 @@ public class TestSceneOverlayRulesetSelector : OsuTestScene typeof(OverlayRulesetTabItem), }; + [Resolved] + private OsuColour colours { get; set; } + private readonly OverlayRulesetSelector selector; private readonly Bindable ruleset = new Bindable(); @@ -38,31 +41,27 @@ public TestSceneOverlayRulesetSelector() }); } - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - selector.AccentColour = colours.Lime; - } - [Test] public void TestSelection() { - var osuRuleset = new OsuRuleset().RulesetInfo; - var maniaRuleset = new ManiaRuleset().RulesetInfo; - var taikoRuleset = new TaikoRuleset().RulesetInfo; - var catchRuleset = new CatchRuleset().RulesetInfo; + AddStep("Select osu!", () => ruleset.Value = new OsuRuleset().RulesetInfo); + AddAssert("Check osu! selected", () => selector.Current.Value.Equals(new OsuRuleset().RulesetInfo)); - AddStep("Select osu!", () => ruleset.Value = osuRuleset); - AddAssert("Check osu! selected", () => selector.Current.Value == osuRuleset); + AddStep("Select mania", () => ruleset.Value = new ManiaRuleset().RulesetInfo); + AddAssert("Check mania selected", () => selector.Current.Value.Equals(new ManiaRuleset().RulesetInfo)); - AddStep("Select mania", () => ruleset.Value = maniaRuleset); - AddAssert("Check mania selected", () => selector.Current.Value == maniaRuleset); + AddStep("Select taiko", () => ruleset.Value = new TaikoRuleset().RulesetInfo); + AddAssert("Check taiko selected", () => selector.Current.Value.Equals(new TaikoRuleset().RulesetInfo)); - AddStep("Select taiko", () => ruleset.Value = taikoRuleset); - AddAssert("Check taiko selected", () => selector.Current.Value == taikoRuleset); + AddStep("Select catch", () => ruleset.Value = new CatchRuleset().RulesetInfo); + AddAssert("Check catch selected", () => selector.Current.Value.Equals(new CatchRuleset().RulesetInfo)); + } - AddStep("Select catch", () => ruleset.Value = catchRuleset); - AddAssert("Check catch selected", () => selector.Current.Value == catchRuleset); + [Test] + public void TestColours() + { + AddStep("Set colour to blue", () => selector.AccentColour = colours.Blue); + AddAssert("Check colour is blue", () => selector.AccentColour == colours.Blue); } } } diff --git a/osu.Game/Overlays/OverlayRulesetSelector.cs b/osu.Game/Overlays/OverlayRulesetSelector.cs index 1dcfc97562..da49335250 100644 --- a/osu.Game/Overlays/OverlayRulesetSelector.cs +++ b/osu.Game/Overlays/OverlayRulesetSelector.cs @@ -1,6 +1,7 @@ // 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.UserInterface; @@ -32,6 +33,13 @@ public OverlayRulesetSelector() AutoSizeAxes = Axes.Both; } + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + if (accentColour == default) + AccentColour = colours.Pink; + } + protected override TabItem CreateTabItem(RulesetInfo value) => new OverlayRulesetTabItem(value); protected override TabFillFlowContainer CreateTabFlow() => new TabFillFlowContainer From 904b068a15c5bb55629d70c8bb5ca035a1d65649 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 2 Jan 2020 13:18:18 +0300 Subject: [PATCH 04/10] Simplify colour setting for additional elements in OverlayRulesetTabItem --- osu.Game/Overlays/OverlayRulesetTabItem.cs | 23 +++++++++++-------- .../Components/ProfileRulesetTabItem.cs | 13 +---------- 2 files changed, 14 insertions(+), 22 deletions(-) diff --git a/osu.Game/Overlays/OverlayRulesetTabItem.cs b/osu.Game/Overlays/OverlayRulesetTabItem.cs index 9d6d28a81f..e1cc1de8de 100644 --- a/osu.Game/Overlays/OverlayRulesetTabItem.cs +++ b/osu.Game/Overlays/OverlayRulesetTabItem.cs @@ -11,6 +11,7 @@ using osu.Game.Rulesets; using osuTK.Graphics; using osuTK; +using System; namespace osu.Game.Overlays { @@ -33,10 +34,12 @@ public Color4 AccentColour accentColour = value; - UpdateState(); + updateState(); } } + protected Action OnStateUpdated; + protected override Container Content => content; public OverlayRulesetTabItem(RulesetInfo value) @@ -67,32 +70,32 @@ public OverlayRulesetTabItem(RulesetInfo value) protected override void LoadComplete() { base.LoadComplete(); - Enabled.BindValueChanged(_ => UpdateState(), true); + Enabled.BindValueChanged(_ => updateState(), true); } protected override bool OnHover(HoverEvent e) { base.OnHover(e); - UpdateState(); + updateState(); return true; } protected override void OnHoverLost(HoverLostEvent e) { base.OnHoverLost(e); - UpdateState(); + updateState(); } - protected override void OnActivated() => UpdateState(); + protected override void OnActivated() => updateState(); - protected override void OnDeactivated() => UpdateState(); + protected override void OnDeactivated() => updateState(); - protected virtual void UpdateState() + private void updateState() { + var updatedColour = IsHovered || Active.Value ? Color4.White : Enabled.Value ? AccentColour : Color4.DimGray; Text.Font = Text.Font.With(weight: Active.Value ? FontWeight.Bold : FontWeight.Medium); - Text.FadeColour(GetColour(), 120, Easing.OutQuint); + Text.FadeColour(updatedColour, 120, Easing.OutQuint); + OnStateUpdated?.Invoke(updatedColour); } - - protected Color4 GetColour() => IsHovered || Active.Value ? Color4.White : Enabled.Value ? AccentColour : Color4.DimGray; } } diff --git a/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetTabItem.cs b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetTabItem.cs index adf324b259..d416e98b31 100644 --- a/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetTabItem.cs +++ b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetTabItem.cs @@ -5,7 +5,6 @@ using osu.Framework.Graphics.Sprites; using osu.Game.Rulesets; using osuTK; -using osuTK.Graphics; namespace osu.Game.Overlays.Profile.Header.Components { @@ -13,12 +12,6 @@ public class ProfileRulesetTabItem : OverlayRulesetTabItem { private readonly SpriteIcon icon; - public new Color4 AccentColour - { - get => base.AccentColour; - set => base.AccentColour = icon.Colour = value; - } - private bool isDefault; public bool IsDefault @@ -47,12 +40,8 @@ public ProfileRulesetTabItem(RulesetInfo value) Icon = FontAwesome.Solid.Star, Size = new Vector2(12), }); - } - protected override void UpdateState() - { - base.UpdateState(); - icon.FadeColour(GetColour(), 120, Easing.OutQuint); + OnStateUpdated += colour => icon.FadeColour(colour, 120, Easing.OutQuint); } } } From 79a6655e1f6d64cb4246fc197560e607cccbbe87 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Fri, 3 Jan 2020 21:02:56 +0300 Subject: [PATCH 05/10] Use bindables for colour updates --- osu.Game/Overlays/OverlayRulesetTabItem.cs | 31 +++++++++---------- .../Components/ProfileRulesetTabItem.cs | 12 +++++-- 2 files changed, 23 insertions(+), 20 deletions(-) diff --git a/osu.Game/Overlays/OverlayRulesetTabItem.cs b/osu.Game/Overlays/OverlayRulesetTabItem.cs index e1cc1de8de..bf24895306 100644 --- a/osu.Game/Overlays/OverlayRulesetTabItem.cs +++ b/osu.Game/Overlays/OverlayRulesetTabItem.cs @@ -11,7 +11,7 @@ using osu.Game.Rulesets; using osuTK.Graphics; using osuTK; -using System; +using osu.Framework.Bindables; namespace osu.Game.Overlays { @@ -22,24 +22,15 @@ public class OverlayRulesetTabItem : TabItem, IHasAccentColour public override bool PropagatePositionalInputSubTree => Enabled.Value && !Active.Value && base.PropagatePositionalInputSubTree; - private Color4 accentColour; + private readonly Bindable accentColour = new Bindable(); + private readonly Bindable currentColour = new Bindable(); public Color4 AccentColour { - get => accentColour; - set - { - if (accentColour == value) - return; - - accentColour = value; - - updateState(); - } + get => accentColour.Value; + set => accentColour.Value = value; } - protected Action OnStateUpdated; - protected override Container Content => content; public OverlayRulesetTabItem(RulesetInfo value) @@ -70,6 +61,9 @@ public OverlayRulesetTabItem(RulesetInfo value) protected override void LoadComplete() { base.LoadComplete(); + + currentColour.BindValueChanged(OnCurrentColourChanged); + accentColour.BindValueChanged(_ => updateState()); Enabled.BindValueChanged(_ => updateState(), true); } @@ -92,10 +86,13 @@ protected override void OnHoverLost(HoverLostEvent e) private void updateState() { - var updatedColour = IsHovered || Active.Value ? Color4.White : Enabled.Value ? AccentColour : Color4.DimGray; Text.Font = Text.Font.With(weight: Active.Value ? FontWeight.Bold : FontWeight.Medium); - Text.FadeColour(updatedColour, 120, Easing.OutQuint); - OnStateUpdated?.Invoke(updatedColour); + + currentColour.Value = IsHovered || Active.Value + ? Color4.White + : Enabled.Value ? AccentColour : Color4.DimGray; } + + protected virtual void OnCurrentColourChanged(ValueChangedEvent colour) => Text.FadeColour(colour.NewValue, 120, Easing.OutQuint); } } diff --git a/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetTabItem.cs b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetTabItem.cs index d416e98b31..038509d371 100644 --- a/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetTabItem.cs +++ b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetTabItem.cs @@ -1,17 +1,17 @@ // 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.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; using osu.Game.Rulesets; using osuTK; +using osuTK.Graphics; namespace osu.Game.Overlays.Profile.Header.Components { public class ProfileRulesetTabItem : OverlayRulesetTabItem { - private readonly SpriteIcon icon; - private bool isDefault; public bool IsDefault @@ -28,6 +28,8 @@ public bool IsDefault } } + private readonly SpriteIcon icon; + public ProfileRulesetTabItem(RulesetInfo value) : base(value) { @@ -40,8 +42,12 @@ public ProfileRulesetTabItem(RulesetInfo value) Icon = FontAwesome.Solid.Star, Size = new Vector2(12), }); + } - OnStateUpdated += colour => icon.FadeColour(colour, 120, Easing.OutQuint); + protected override void OnCurrentColourChanged(ValueChangedEvent colour) + { + base.OnCurrentColourChanged(colour); + icon.FadeColour(colour.NewValue, 120, Easing.OutQuint); } } } From bd5140c3fa72b79d8f03b6e1eda6ccbd919e12f8 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Fri, 3 Jan 2020 21:20:31 +0300 Subject: [PATCH 06/10] Add missing line breaks --- osu.Game/Overlays/OverlayRulesetTabItem.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/OverlayRulesetTabItem.cs b/osu.Game/Overlays/OverlayRulesetTabItem.cs index bf24895306..91cf2d6b96 100644 --- a/osu.Game/Overlays/OverlayRulesetTabItem.cs +++ b/osu.Game/Overlays/OverlayRulesetTabItem.cs @@ -90,7 +90,9 @@ private void updateState() currentColour.Value = IsHovered || Active.Value ? Color4.White - : Enabled.Value ? AccentColour : Color4.DimGray; + : Enabled.Value + ? AccentColour + : Color4.DimGray; } protected virtual void OnCurrentColourChanged(ValueChangedEvent colour) => Text.FadeColour(colour.NewValue, 120, Easing.OutQuint); From 11e7c8be3f3f3da461a65a22d1be2b5ec8017a7d Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 20 Jan 2020 08:34:46 +0300 Subject: [PATCH 07/10] Use colour schemes for OverlayRulesetSelector --- .../Online/TestSceneProfileRulesetSelector.cs | 3 +- .../TestSceneOverlayRulesetSelector.cs | 28 ++++++++++--------- osu.Game/Overlays/OverlayRulesetSelector.cs | 9 ++++-- .../Components/ProfileRulesetSelector.cs | 7 ++--- 4 files changed, 25 insertions(+), 22 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneProfileRulesetSelector.cs b/osu.Game.Tests/Visual/Online/TestSceneProfileRulesetSelector.cs index a36b6880d2..1a9dca51c9 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneProfileRulesetSelector.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneProfileRulesetSelector.cs @@ -11,6 +11,7 @@ using osu.Game.Rulesets.Taiko; using osu.Game.Users; using osu.Framework.Bindables; +using osu.Game.Graphics; namespace osu.Game.Tests.Visual.Online { @@ -27,7 +28,7 @@ public TestSceneProfileRulesetSelector() ProfileRulesetSelector selector; var user = new Bindable(); - Child = selector = new ProfileRulesetSelector + Child = selector = new ProfileRulesetSelector(OverlayColourScheme.Green) { Anchor = Anchor.Centre, Origin = Anchor.Centre, diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayRulesetSelector.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayRulesetSelector.cs index 93aa414c94..bc5f66da0b 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayRulesetSelector.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayRulesetSelector.cs @@ -13,7 +13,8 @@ using osu.Game.Rulesets; using NUnit.Framework; using osu.Game.Graphics; -using osu.Framework.Allocation; +using osu.Framework.Graphics.Containers; +using osuTK; namespace osu.Game.Tests.Visual.UserInterface { @@ -25,19 +26,27 @@ public class TestSceneOverlayRulesetSelector : OsuTestScene typeof(OverlayRulesetTabItem), }; - [Resolved] - private OsuColour colours { get; set; } - private readonly OverlayRulesetSelector selector; private readonly Bindable ruleset = new Bindable(); public TestSceneOverlayRulesetSelector() { - Add(selector = new OverlayRulesetSelector + Add(new FillFlowContainer { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Current = ruleset, + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 5), + Children = new[] + { + selector = new OverlayRulesetSelector(OverlayColourScheme.Green) { Current = ruleset }, + new OverlayRulesetSelector(OverlayColourScheme.Blue) { Current = ruleset }, + new OverlayRulesetSelector(OverlayColourScheme.Orange) { Current = ruleset }, + new OverlayRulesetSelector(OverlayColourScheme.Pink) { Current = ruleset }, + new OverlayRulesetSelector(OverlayColourScheme.Purple) { Current = ruleset }, + new OverlayRulesetSelector(OverlayColourScheme.Red) { Current = ruleset } + } }); } @@ -56,12 +65,5 @@ public void TestSelection() AddStep("Select catch", () => ruleset.Value = new CatchRuleset().RulesetInfo); AddAssert("Check catch selected", () => selector.Current.Value.Equals(new CatchRuleset().RulesetInfo)); } - - [Test] - public void TestColours() - { - AddStep("Set colour to blue", () => selector.AccentColour = colours.Blue); - AddAssert("Check colour is blue", () => selector.AccentColour == colours.Blue); - } } } diff --git a/osu.Game/Overlays/OverlayRulesetSelector.cs b/osu.Game/Overlays/OverlayRulesetSelector.cs index da49335250..b70d6a08f2 100644 --- a/osu.Game/Overlays/OverlayRulesetSelector.cs +++ b/osu.Game/Overlays/OverlayRulesetSelector.cs @@ -28,16 +28,19 @@ public Color4 AccentColour } } - public OverlayRulesetSelector() + protected OverlayColourScheme ColourScheme { get; } + + public OverlayRulesetSelector(OverlayColourScheme colourScheme) { + ColourScheme = colourScheme; + AutoSizeAxes = Axes.Both; } [BackgroundDependencyLoader] private void load(OsuColour colours) { - if (accentColour == default) - AccentColour = colours.Pink; + AccentColour = colours.ForOverlayElement(ColourScheme, 1, 0.7f); } protected override TabItem CreateTabItem(RulesetInfo value) => new OverlayRulesetTabItem(value); diff --git a/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs index e63102f989..f7e8d4b1f5 100644 --- a/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs +++ b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs @@ -1,7 +1,6 @@ // 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.Bindables; using osu.Framework.Graphics.UserInterface; using osu.Game.Graphics; @@ -14,16 +13,14 @@ public class ProfileRulesetSelector : OverlayRulesetSelector { public readonly Bindable User = new Bindable(); - [BackgroundDependencyLoader] - private void load(OsuColour colours) + public ProfileRulesetSelector(OverlayColourScheme colourScheme) + : base(colourScheme) { - AccentColour = colours.Seafoam; } protected override void LoadComplete() { base.LoadComplete(); - User.BindValueChanged(u => SetDefaultRuleset(Rulesets.GetRuleset(u.NewValue?.PlayMode ?? "osu")), true); } From 7cd60e3193a615c4ce71311693762ec6c01aa57e Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 26 Jan 2020 17:07:17 +0300 Subject: [PATCH 08/10] Make OverlayRulesetSelector use colour provider --- .../Online/TestSceneProfileRulesetSelector.cs | 8 ++++-- .../TestSceneOverlayRulesetSelector.cs | 27 ++++++++++++++----- osu.Game/Overlays/OverlayRulesetSelector.cs | 10 +++---- .../Components/ProfileRulesetSelector.cs | 6 ----- 4 files changed, 29 insertions(+), 22 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneProfileRulesetSelector.cs b/osu.Game.Tests/Visual/Online/TestSceneProfileRulesetSelector.cs index 1a9dca51c9..826624f686 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneProfileRulesetSelector.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneProfileRulesetSelector.cs @@ -11,7 +11,8 @@ using osu.Game.Rulesets.Taiko; using osu.Game.Users; using osu.Framework.Bindables; -using osu.Game.Graphics; +using osu.Game.Overlays; +using osu.Framework.Allocation; namespace osu.Game.Tests.Visual.Online { @@ -23,12 +24,15 @@ public class TestSceneProfileRulesetSelector : OsuTestScene typeof(ProfileRulesetTabItem), }; + [Cached] + private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Green); + public TestSceneProfileRulesetSelector() { ProfileRulesetSelector selector; var user = new Bindable(); - Child = selector = new ProfileRulesetSelector(OverlayColourScheme.Green) + Child = selector = new ProfileRulesetSelector { Anchor = Anchor.Centre, Origin = Anchor.Centre, diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayRulesetSelector.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayRulesetSelector.cs index bc5f66da0b..8a98127793 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayRulesetSelector.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayRulesetSelector.cs @@ -12,9 +12,9 @@ using osu.Game.Overlays; using osu.Game.Rulesets; using NUnit.Framework; -using osu.Game.Graphics; using osu.Framework.Graphics.Containers; using osuTK; +using osu.Framework.Allocation; namespace osu.Game.Tests.Visual.UserInterface { @@ -40,16 +40,29 @@ public TestSceneOverlayRulesetSelector() Spacing = new Vector2(0, 5), Children = new[] { - selector = new OverlayRulesetSelector(OverlayColourScheme.Green) { Current = ruleset }, - new OverlayRulesetSelector(OverlayColourScheme.Blue) { Current = ruleset }, - new OverlayRulesetSelector(OverlayColourScheme.Orange) { Current = ruleset }, - new OverlayRulesetSelector(OverlayColourScheme.Pink) { Current = ruleset }, - new OverlayRulesetSelector(OverlayColourScheme.Purple) { Current = ruleset }, - new OverlayRulesetSelector(OverlayColourScheme.Red) { Current = ruleset } + new ColourProvidedContainer(OverlayColourScheme.Green, selector = new OverlayRulesetSelector { Current = ruleset }), + new ColourProvidedContainer(OverlayColourScheme.Blue, new OverlayRulesetSelector { Current = ruleset }), + new ColourProvidedContainer(OverlayColourScheme.Orange, new OverlayRulesetSelector { Current = ruleset }), + new ColourProvidedContainer(OverlayColourScheme.Pink, new OverlayRulesetSelector { Current = ruleset }), + new ColourProvidedContainer(OverlayColourScheme.Purple, new OverlayRulesetSelector { Current = ruleset }), + new ColourProvidedContainer(OverlayColourScheme.Red, new OverlayRulesetSelector { Current = ruleset }), } }); } + private class ColourProvidedContainer : Container + { + [Cached] + private readonly OverlayColourProvider colourProvider; + + public ColourProvidedContainer(OverlayColourScheme colourScheme, OverlayRulesetSelector rulesetSelector) + { + colourProvider = new OverlayColourProvider(colourScheme); + AutoSizeAxes = Axes.Both; + Add(rulesetSelector); + } + } + [Test] public void TestSelection() { diff --git a/osu.Game/Overlays/OverlayRulesetSelector.cs b/osu.Game/Overlays/OverlayRulesetSelector.cs index b70d6a08f2..0c87686f6f 100644 --- a/osu.Game/Overlays/OverlayRulesetSelector.cs +++ b/osu.Game/Overlays/OverlayRulesetSelector.cs @@ -28,19 +28,15 @@ public Color4 AccentColour } } - protected OverlayColourScheme ColourScheme { get; } - - public OverlayRulesetSelector(OverlayColourScheme colourScheme) + public OverlayRulesetSelector() { - ColourScheme = colourScheme; - AutoSizeAxes = Axes.Both; } [BackgroundDependencyLoader] - private void load(OsuColour colours) + private void load(OverlayColourProvider colourProvider) { - AccentColour = colours.ForOverlayElement(ColourScheme, 1, 0.7f); + AccentColour = colourProvider.Highlight1; } protected override TabItem CreateTabItem(RulesetInfo value) => new OverlayRulesetTabItem(value); diff --git a/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs index f7e8d4b1f5..41a3ee8ad6 100644 --- a/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs +++ b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs @@ -3,7 +3,6 @@ using osu.Framework.Bindables; using osu.Framework.Graphics.UserInterface; -using osu.Game.Graphics; using osu.Game.Rulesets; using osu.Game.Users; @@ -13,11 +12,6 @@ public class ProfileRulesetSelector : OverlayRulesetSelector { public readonly Bindable User = new Bindable(); - public ProfileRulesetSelector(OverlayColourScheme colourScheme) - : base(colourScheme) - { - } - protected override void LoadComplete() { base.LoadComplete(); From ea2f66da1d9d10a9608a87cfed312b46a95afc4d Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 30 Jan 2020 10:34:22 +0300 Subject: [PATCH 09/10] Simplify OverlayRulesetTabItem.AccentColour --- osu.Game/Overlays/OverlayRulesetSelector.cs | 23 ----------- osu.Game/Overlays/OverlayRulesetTabItem.cs | 40 ++++++++----------- .../Components/ProfileRulesetTabItem.cs | 17 ++++---- 3 files changed, 27 insertions(+), 53 deletions(-) diff --git a/osu.Game/Overlays/OverlayRulesetSelector.cs b/osu.Game/Overlays/OverlayRulesetSelector.cs index 0c87686f6f..b73d38eeb3 100644 --- a/osu.Game/Overlays/OverlayRulesetSelector.cs +++ b/osu.Game/Overlays/OverlayRulesetSelector.cs @@ -1,44 +1,21 @@ // 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.UserInterface; -using osu.Game.Graphics; using osu.Game.Rulesets; using osuTK; -using osuTK.Graphics; -using System.Linq; namespace osu.Game.Overlays { public class OverlayRulesetSelector : RulesetSelector { - private Color4 accentColour; - - public Color4 AccentColour - { - get => accentColour; - set - { - accentColour = value; - foreach (var i in TabContainer.Children.OfType()) - i.AccentColour = value; - } - } - public OverlayRulesetSelector() { AutoSizeAxes = Axes.Both; } - [BackgroundDependencyLoader] - private void load(OverlayColourProvider colourProvider) - { - AccentColour = colourProvider.Highlight1; - } - protected override TabItem CreateTabItem(RulesetInfo value) => new OverlayRulesetTabItem(value); protected override TabFillFlowContainer CreateTabFlow() => new TabFillFlowContainer diff --git a/osu.Game/Overlays/OverlayRulesetTabItem.cs b/osu.Game/Overlays/OverlayRulesetTabItem.cs index 91cf2d6b96..5b53d9d1fa 100644 --- a/osu.Game/Overlays/OverlayRulesetTabItem.cs +++ b/osu.Game/Overlays/OverlayRulesetTabItem.cs @@ -11,27 +11,31 @@ using osu.Game.Rulesets; using osuTK.Graphics; using osuTK; -using osu.Framework.Bindables; +using osu.Framework.Allocation; namespace osu.Game.Overlays { - public class OverlayRulesetTabItem : TabItem, IHasAccentColour + public class OverlayRulesetTabItem : TabItem { protected readonly OsuSpriteText Text; private readonly FillFlowContainer content; - public override bool PropagatePositionalInputSubTree => Enabled.Value && !Active.Value && base.PropagatePositionalInputSubTree; + protected override Container Content => content; - private readonly Bindable accentColour = new Bindable(); - private readonly Bindable currentColour = new Bindable(); + private Color4 accentColour; - public Color4 AccentColour + protected virtual Color4 AccentColour { - get => accentColour.Value; - set => accentColour.Value = value; + get => accentColour; + set + { + accentColour = value; + Text.FadeColour(value, 120, Easing.OutQuint); + } } - protected override Container Content => content; + [Resolved] + private OverlayColourProvider colourProvider { get; set; } public OverlayRulesetTabItem(RulesetInfo value) : base(value) @@ -58,13 +62,10 @@ public OverlayRulesetTabItem(RulesetInfo value) Enabled.Value = true; } - protected override void LoadComplete() + [BackgroundDependencyLoader] + private void load() { - base.LoadComplete(); - - currentColour.BindValueChanged(OnCurrentColourChanged); - accentColour.BindValueChanged(_ => updateState()); - Enabled.BindValueChanged(_ => updateState(), true); + updateState(); } protected override bool OnHover(HoverEvent e) @@ -87,14 +88,7 @@ protected override void OnHoverLost(HoverLostEvent e) private void updateState() { Text.Font = Text.Font.With(weight: Active.Value ? FontWeight.Bold : FontWeight.Medium); - - currentColour.Value = IsHovered || Active.Value - ? Color4.White - : Enabled.Value - ? AccentColour - : Color4.DimGray; + AccentColour = IsHovered || Active.Value ? Color4.White : colourProvider.Highlight1; } - - protected virtual void OnCurrentColourChanged(ValueChangedEvent colour) => Text.FadeColour(colour.NewValue, 120, Easing.OutQuint); } } diff --git a/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetTabItem.cs b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetTabItem.cs index 038509d371..3d20fba542 100644 --- a/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetTabItem.cs +++ b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetTabItem.cs @@ -1,7 +1,6 @@ // 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.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; using osu.Game.Rulesets; @@ -28,6 +27,16 @@ public bool IsDefault } } + protected override Color4 AccentColour + { + get => base.AccentColour; + set + { + base.AccentColour = value; + icon.FadeColour(value, 120, Easing.OutQuint); + } + } + private readonly SpriteIcon icon; public ProfileRulesetTabItem(RulesetInfo value) @@ -43,11 +52,5 @@ public ProfileRulesetTabItem(RulesetInfo value) Size = new Vector2(12), }); } - - protected override void OnCurrentColourChanged(ValueChangedEvent colour) - { - base.OnCurrentColourChanged(colour); - icon.FadeColour(colour.NewValue, 120, Easing.OutQuint); - } } } From d9d8712360b3093c76bf0cb6f7f1f3922de45578 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 3 Feb 2020 15:13:21 +0900 Subject: [PATCH 10/10] Refactor class layout for readability --- osu.Game/Overlays/OverlayRulesetTabItem.cs | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/osu.Game/Overlays/OverlayRulesetTabItem.cs b/osu.Game/Overlays/OverlayRulesetTabItem.cs index 5b53d9d1fa..f8a9d14f62 100644 --- a/osu.Game/Overlays/OverlayRulesetTabItem.cs +++ b/osu.Game/Overlays/OverlayRulesetTabItem.cs @@ -17,11 +17,6 @@ namespace osu.Game.Overlays { public class OverlayRulesetTabItem : TabItem { - protected readonly OsuSpriteText Text; - private readonly FillFlowContainer content; - - protected override Container Content => content; - private Color4 accentColour; protected virtual Color4 AccentColour @@ -30,13 +25,17 @@ protected virtual Color4 AccentColour set { accentColour = value; - Text.FadeColour(value, 120, Easing.OutQuint); + text.FadeColour(value, 120, Easing.OutQuint); } } + protected override Container Content { get; } + [Resolved] private OverlayColourProvider colourProvider { get; set; } + private readonly OsuSpriteText text; + public OverlayRulesetTabItem(RulesetInfo value) : base(value) { @@ -44,12 +43,12 @@ public OverlayRulesetTabItem(RulesetInfo value) AddRangeInternal(new Drawable[] { - content = new FillFlowContainer + Content = new FillFlowContainer { AutoSizeAxes = Axes.Both, Direction = FillDirection.Horizontal, Spacing = new Vector2(3, 0), - Child = Text = new OsuSpriteText + Child = text = new OsuSpriteText { Origin = Anchor.Centre, Anchor = Anchor.Centre, @@ -87,7 +86,7 @@ protected override void OnHoverLost(HoverLostEvent e) private void updateState() { - Text.Font = Text.Font.With(weight: Active.Value ? FontWeight.Bold : FontWeight.Medium); + text.Font = text.Font.With(weight: Active.Value ? FontWeight.Bold : FontWeight.Medium); AccentColour = IsHovered || Active.Value ? Color4.White : colourProvider.Highlight1; } }