From 9ed4c1dbdba69e9442b6583b3cf8f8f975f26433 Mon Sep 17 00:00:00 2001 From: bctix <51544115+bctix@users.noreply.github.com> Date: Thu, 12 Dec 2024 17:46:48 -0500 Subject: [PATCH] Add style options to dynamic skin elements --- osu.Game/Screens/Play/HUD/BPMCounter.cs | 51 +++++++++++++-- .../ClicksPerSecond/ClicksPerSecondCounter.cs | 65 ++++++++++++++++--- .../Screens/Play/HUD/LongestComboCounter.cs | 62 ++++++++++++++++-- .../Screens/Play/HUD/UnstableRateCounter.cs | 45 ++++++++++++- 4 files changed, 200 insertions(+), 23 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/BPMCounter.cs b/osu.Game/Screens/Play/HUD/BPMCounter.cs index 9cd285db4c..67da0aecf1 100644 --- a/osu.Game/Screens/Play/HUD/BPMCounter.cs +++ b/osu.Game/Screens/Play/HUD/BPMCounter.cs @@ -3,16 +3,21 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; +using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; +using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; using osu.Framework.Localisation; using osu.Game.Beatmaps; +using osu.Game.Configuration; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; +using osu.Game.Localisation.SkinComponents; using osu.Game.Skinning; using osuTK; +using Vortice.DXGI; namespace osu.Game.Screens.Play.HUD { @@ -20,6 +25,15 @@ namespace osu.Game.Screens.Play.HUD { protected override double RollingDuration => 375; + [SettingSource(typeof(SkinnableComponentStrings), nameof(SkinnableComponentStrings.Font), nameof(SkinnableComponentStrings.FontDescription))] + public Bindable Font { get; } = new Bindable(Typeface.Venera); + + [SettingSource(typeof(SkinnableComponentStrings), nameof(SkinnableComponentStrings.Colour), nameof(SkinnableComponentStrings.ColourDescription))] + public BindableColour4 TextColour { get; } = new BindableColour4(Color4Extensions.FromHex(@"ddffff")); + + [SettingSource(typeof(SkinnableComponentStrings), nameof(SkinnableComponentStrings.ShowLabel), nameof(SkinnableComponentStrings.ShowLabelDescription))] + public Bindable ShowLabel { get; } = new BindableBool(true); + [Resolved] private IBindable beatmap { get; set; } = null!; @@ -27,10 +41,10 @@ namespace osu.Game.Screens.Play.HUD private IGameplayClock gameplayClock { get; set; } = null!; [BackgroundDependencyLoader] - private void load(OsuColour colour) + private void load() { - Colour = colour.BlueLighter; Current.Value = DisplayedCount = 0; + TextColour.BindValueChanged(c => Colour = TextColour.Value, true); } protected override void Update() @@ -49,7 +63,11 @@ namespace osu.Game.Screens.Play.HUD return $@"{count:0}"; } - protected override IHasText CreateText() => new TextComponent(); + protected override IHasText CreateText() => new TextComponent() + { + ShowLabel = { BindTarget = ShowLabel }, + Font = { BindTarget = Font }, + }; private partial class TextComponent : CompositeDrawable, IHasText { @@ -58,8 +76,11 @@ namespace osu.Game.Screens.Play.HUD get => text.Text; set => text.Text = value; } + public Bindable ShowLabel { get; } = new BindableBool(); + public Bindable Font { get; } = new Bindable(); private readonly OsuSpriteText text; + private readonly OsuSpriteText label; public TextComponent() { @@ -77,7 +98,7 @@ namespace osu.Game.Screens.Play.HUD Origin = Anchor.BottomLeft, Font = OsuFont.Numeric.With(size: 16, fixedWidth: true) }, - new OsuSpriteText + label = new OsuSpriteText { Anchor = Anchor.BottomLeft, Origin = Anchor.BottomLeft, @@ -88,6 +109,28 @@ namespace osu.Game.Screens.Play.HUD } }; } + + protected override void LoadComplete() + { + base.LoadComplete(); + + ShowLabel.BindValueChanged(s => + { + label.Alpha = s.NewValue ? 1 : 0; + }, true); + + Font.BindValueChanged(typeface => + { + // We only have bold weight for venera, so let's force that. + FontWeight fontWeight = typeface.NewValue == Typeface.Venera ? FontWeight.Bold : FontWeight.Regular; + + FontUsage f = OsuFont.GetFont(typeface.NewValue, weight: fontWeight); + + // Fixed width looks better on venera only in my opinion. + text.Font = f.With(size: 16, fixedWidth: typeface.NewValue == Typeface.Venera); + label.Font = f.With(size: 8); + }, true); + } } public bool UsesFixedAnchor { get; set; } diff --git a/osu.Game/Screens/Play/HUD/ClicksPerSecond/ClicksPerSecondCounter.cs b/osu.Game/Screens/Play/HUD/ClicksPerSecond/ClicksPerSecondCounter.cs index a1cccdef0a..d6cbfa11a1 100644 --- a/osu.Game/Screens/Play/HUD/ClicksPerSecond/ClicksPerSecondCounter.cs +++ b/osu.Game/Screens/Play/HUD/ClicksPerSecond/ClicksPerSecondCounter.cs @@ -2,13 +2,17 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; +using osu.Framework.Bindables; +using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; using osu.Framework.Localisation; +using osu.Game.Configuration; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; +using osu.Game.Localisation.SkinComponents; using osu.Game.Skinning; using osuTK; @@ -19,6 +23,15 @@ namespace osu.Game.Screens.Play.HUD.ClicksPerSecond [Resolved] private ClicksPerSecondController controller { get; set; } = null!; + [SettingSource(typeof(SkinnableComponentStrings), nameof(SkinnableComponentStrings.Font), nameof(SkinnableComponentStrings.FontDescription))] + public Bindable Font { get; } = new Bindable(Typeface.Venera); + + [SettingSource(typeof(SkinnableComponentStrings), nameof(SkinnableComponentStrings.Colour), nameof(SkinnableComponentStrings.ColourDescription))] + public BindableColour4 TextColour { get; } = new BindableColour4(Color4Extensions.FromHex(@"ddffff")); + + [SettingSource(typeof(SkinnableComponentStrings), nameof(SkinnableComponentStrings.ShowLabel), nameof(SkinnableComponentStrings.ShowLabelDescription))] + public Bindable ShowLabel { get; } = new BindableBool(true); + protected override double RollingDuration => 175; public bool UsesFixedAnchor { get; set; } @@ -26,12 +39,7 @@ namespace osu.Game.Screens.Play.HUD.ClicksPerSecond public ClicksPerSecondCounter() { Current.Value = 0; - } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - Colour = colours.BlueLighter; + TextColour.BindValueChanged(c => Colour = TextColour.Value, true); } protected override void Update() @@ -41,7 +49,11 @@ namespace osu.Game.Screens.Play.HUD.ClicksPerSecond Current.Value = controller.Value; } - protected override IHasText CreateText() => new TextComponent(); + protected override IHasText CreateText() => new TextComponent() + { + ShowLabel = { BindTarget = ShowLabel }, + Font = { BindTarget = Font }, + }; private partial class TextComponent : CompositeDrawable, IHasText { @@ -51,7 +63,14 @@ namespace osu.Game.Screens.Play.HUD.ClicksPerSecond set => text.Text = value; } + public Bindable ShowLabel { get; } = new BindableBool(); + public Bindable Font { get; } = new Bindable(); + + private readonly FillFlowContainer labelContainer; + private readonly OsuSpriteText text; + private readonly OsuSpriteText clickLabel; + private readonly OsuSpriteText secLabel; public TextComponent() { @@ -69,7 +88,7 @@ namespace osu.Game.Screens.Play.HUD.ClicksPerSecond Origin = Anchor.BottomLeft, Font = OsuFont.Numeric.With(size: 16, fixedWidth: true) }, - new FillFlowContainer + labelContainer = new FillFlowContainer { Anchor = Anchor.BottomLeft, Origin = Anchor.BottomLeft, @@ -77,14 +96,14 @@ namespace osu.Game.Screens.Play.HUD.ClicksPerSecond AutoSizeAxes = Axes.Both, Children = new Drawable[] { - new OsuSpriteText + clickLabel = new OsuSpriteText { Anchor = Anchor.TopLeft, Origin = Anchor.TopLeft, Font = OsuFont.Numeric.With(size: 6, fixedWidth: false), Text = @"clicks", }, - new OsuSpriteText + secLabel = new OsuSpriteText { Anchor = Anchor.TopLeft, Origin = Anchor.TopLeft, @@ -97,6 +116,32 @@ namespace osu.Game.Screens.Play.HUD.ClicksPerSecond } }; } + + protected override void LoadComplete() + { + base.LoadComplete(); + + ShowLabel.BindValueChanged(s => + { + labelContainer.Alpha = s.NewValue ? 1 : 0; + }, true); + + Font.BindValueChanged(typeface => + { + // We only have bold weight for venera, so let's force that. + FontWeight fontWeight = typeface.NewValue == Typeface.Venera ? FontWeight.Bold : FontWeight.Regular; + + FontUsage f = OsuFont.GetFont(typeface.NewValue, weight: fontWeight); + + // align baseline with fonts that aren't venera + secLabel.Padding = new MarginPadding { Bottom = typeface.NewValue == Typeface.Venera ? 3f : 2f }; + + // Fixed width looks better on venera only in my opinion. + text.Font = f.With(size: 16, fixedWidth: typeface.NewValue == Typeface.Venera); + clickLabel.Font = f.With(size: 6, fixedWidth: false); + secLabel.Font = f.With(size: 6, fixedWidth: false); + }, true); + } } } } diff --git a/osu.Game/Screens/Play/HUD/LongestComboCounter.cs b/osu.Game/Screens/Play/HUD/LongestComboCounter.cs index fdc3768aab..fbbf6a7b9a 100644 --- a/osu.Game/Screens/Play/HUD/LongestComboCounter.cs +++ b/osu.Game/Screens/Play/HUD/LongestComboCounter.cs @@ -2,12 +2,16 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; +using osu.Framework.Bindables; +using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; using osu.Framework.Localisation; +using osu.Game.Configuration; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; +using osu.Game.Localisation.SkinComponents; using osu.Game.Rulesets.Scoring; using osuTK; @@ -15,14 +19,27 @@ namespace osu.Game.Screens.Play.HUD { public partial class LongestComboCounter : ComboCounter { + [SettingSource(typeof(SkinnableComponentStrings), nameof(SkinnableComponentStrings.Font), nameof(SkinnableComponentStrings.FontDescription))] + public Bindable Font { get; } = new Bindable(Typeface.Venera); + + [SettingSource(typeof(SkinnableComponentStrings), nameof(SkinnableComponentStrings.Colour), nameof(SkinnableComponentStrings.ColourDescription))] + public BindableColour4 TextColour { get; } = new BindableColour4(Color4Extensions.FromHex(@"ffffdd")); + + [SettingSource(typeof(SkinnableComponentStrings), nameof(SkinnableComponentStrings.ShowLabel), nameof(SkinnableComponentStrings.ShowLabelDescription))] + public Bindable ShowLabel { get; } = new BindableBool(true); + [BackgroundDependencyLoader] - private void load(OsuColour colours, ScoreProcessor scoreProcessor) + private void load(ScoreProcessor scoreProcessor) { - Colour = colours.YellowLighter; + TextColour.BindValueChanged(c => Colour = TextColour.Value, true); Current.BindTo(scoreProcessor.HighestCombo); } - protected override IHasText CreateText() => new TextComponent(); + protected override IHasText CreateText() => new TextComponent() + { + ShowLabel = { BindTarget = ShowLabel }, + Font = { BindTarget = Font }, + }; private partial class TextComponent : CompositeDrawable, IHasText { @@ -32,7 +49,14 @@ namespace osu.Game.Screens.Play.HUD set => text.Text = $"{value}x"; } + public Bindable ShowLabel { get; } = new BindableBool(); + public Bindable Font { get; } = new Bindable(); + + private readonly FillFlowContainer labelContainer; + private readonly OsuSpriteText text; + private readonly OsuSpriteText longestLabel; + private readonly OsuSpriteText comboLabel; public TextComponent() { @@ -50,7 +74,7 @@ namespace osu.Game.Screens.Play.HUD Origin = Anchor.BottomLeft, Font = OsuFont.Numeric.With(size: 20) }, - new FillFlowContainer + labelContainer = new FillFlowContainer { Anchor = Anchor.BottomLeft, Origin = Anchor.BottomLeft, @@ -58,14 +82,14 @@ namespace osu.Game.Screens.Play.HUD AutoSizeAxes = Axes.Both, Children = new Drawable[] { - new OsuSpriteText + longestLabel = new OsuSpriteText { Anchor = Anchor.TopLeft, Origin = Anchor.TopLeft, Font = OsuFont.Numeric.With(size: 8), Text = @"longest", }, - new OsuSpriteText + comboLabel = new OsuSpriteText { Anchor = Anchor.TopLeft, Origin = Anchor.TopLeft, @@ -78,6 +102,32 @@ namespace osu.Game.Screens.Play.HUD } }; } + + protected override void LoadComplete() + { + base.LoadComplete(); + + ShowLabel.BindValueChanged(s => + { + labelContainer.Alpha = s.NewValue ? 1 : 0; + }, true); + + Font.BindValueChanged(typeface => + { + // We only have bold weight for venera, so let's force that. + FontWeight fontWeight = typeface.NewValue == Typeface.Venera ? FontWeight.Bold : FontWeight.Regular; + + FontUsage f = OsuFont.GetFont(typeface.NewValue, weight: fontWeight); + + // align baseline with fonts that aren't venera + comboLabel.Padding = new MarginPadding { Bottom = typeface.NewValue == Typeface.Venera ? 3f : 1f }; + + // Fixed width looks better on venera only in my opinion. + text.Font = f.With(size: 16, fixedWidth: typeface.NewValue == Typeface.Venera); + longestLabel.Font = f.With(size: 6, fixedWidth: false); + comboLabel.Font = f.With(size: 6, fixedWidth: false); + }, true); + } } } } diff --git a/osu.Game/Screens/Play/HUD/UnstableRateCounter.cs b/osu.Game/Screens/Play/HUD/UnstableRateCounter.cs index a856a09388..70ca459ac3 100644 --- a/osu.Game/Screens/Play/HUD/UnstableRateCounter.cs +++ b/osu.Game/Screens/Play/HUD/UnstableRateCounter.cs @@ -4,14 +4,17 @@ using System; using osu.Framework.Allocation; using osu.Framework.Bindables; +using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; using osu.Framework.Localisation; +using osu.Game.Configuration; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; +using osu.Game.Localisation.SkinComponents; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Scoring; using osu.Game.Skinning; @@ -21,6 +24,15 @@ namespace osu.Game.Screens.Play.HUD { public partial class UnstableRateCounter : RollingCounter, ISerialisableDrawable { + [SettingSource(typeof(SkinnableComponentStrings), nameof(SkinnableComponentStrings.Font), nameof(SkinnableComponentStrings.FontDescription))] + public Bindable Font { get; } = new Bindable(Typeface.Venera); + + [SettingSource(typeof(SkinnableComponentStrings), nameof(SkinnableComponentStrings.Colour), nameof(SkinnableComponentStrings.ColourDescription))] + public BindableColour4 TextColour { get; } = new BindableColour4(Color4Extensions.FromHex(@"ddffff")); + + [SettingSource(typeof(SkinnableComponentStrings), nameof(SkinnableComponentStrings.ShowLabel), nameof(SkinnableComponentStrings.ShowLabelDescription))] + public Bindable ShowLabel { get; } = new BindableBool(true); + public bool UsesFixedAnchor { get; set; } protected override double RollingDuration => 375; @@ -39,9 +51,9 @@ namespace osu.Game.Screens.Play.HUD } [BackgroundDependencyLoader] - private void load(OsuColour colours) + private void load() { - Colour = colours.BlueLighter; + TextColour.BindValueChanged(c => Colour = TextColour.Value, true); valid.BindValueChanged(e => DrawableCount.FadeTo(e.NewValue ? 1 : alpha_when_invalid, 1000, Easing.OutQuint)); } @@ -76,6 +88,8 @@ namespace osu.Game.Screens.Play.HUD protected override IHasText CreateText() => new TextComponent { Alpha = alpha_when_invalid, + ShowLabel = { BindTarget = ShowLabel }, + Font = { BindTarget = Font }, }; protected override void Dispose(bool isDisposing) @@ -96,8 +110,11 @@ namespace osu.Game.Screens.Play.HUD get => text.Text; set => text.Text = value; } + public Bindable ShowLabel { get; } = new BindableBool(); + public Bindable Font { get; } = new Bindable(); private readonly OsuSpriteText text; + private readonly OsuSpriteText label; public TextComponent() { @@ -115,7 +132,7 @@ namespace osu.Game.Screens.Play.HUD Origin = Anchor.BottomLeft, Font = OsuFont.Numeric.With(size: 16, fixedWidth: true) }, - new OsuSpriteText + label = new OsuSpriteText { Anchor = Anchor.BottomLeft, Origin = Anchor.BottomLeft, @@ -126,6 +143,28 @@ namespace osu.Game.Screens.Play.HUD } }; } + + protected override void LoadComplete() + { + base.LoadComplete(); + + ShowLabel.BindValueChanged(s => + { + label.Alpha = s.NewValue ? 1 : 0; + }, true); + + Font.BindValueChanged(typeface => + { + // We only have bold weight for venera, so let's force that. + FontWeight fontWeight = typeface.NewValue == Typeface.Venera ? FontWeight.Bold : FontWeight.Regular; + + FontUsage f = OsuFont.GetFont(typeface.NewValue, weight: fontWeight); + + // Fixed width looks better on venera only in my opinion. + text.Font = f.With(size: 16, fixedWidth: typeface.NewValue == Typeface.Venera); + label.Font = f.With(size: 8, fixedWidth: typeface.NewValue == Typeface.Venera); + }, true); + } } } }