// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using System; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Extensions.LocalisationExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.UserInterface; using osu.Framework.Localisation; using osu.Framework.Utils; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; using osu.Game.Rulesets.Mods; using osuTK.Graphics; namespace osu.Game.Overlays.Mods { public partial class VerticalAttributeDisplay : Container, IHasCurrentValue { public Bindable Current { get => current.Current; set => current.Current = value; } private readonly BindableWithCurrent current = new BindableWithCurrent(); public Bindable AdjustType = new Bindable(); /// /// Text to display in the top area of the display. /// public LocalisableString Label { get; protected set; } private readonly EffectCounter counter; private readonly OsuSpriteText text; [Resolved] private OsuColour colours { get; set; } = null!; private void updateTextColor() { Color4 newColor; switch (AdjustType.Value) { case ModEffect.NotChanged: newColor = Color4.White; break; case ModEffect.DifficultyReduction: newColor = colours.ForModType(ModType.DifficultyReduction); break; case ModEffect.DifficultyIncrease: newColor = colours.ForModType(ModType.DifficultyIncrease); break; default: throw new ArgumentOutOfRangeException(nameof(AdjustType.Value)); } text.Colour = newColor; counter.Colour = newColor; } public VerticalAttributeDisplay(LocalisableString label) { Label = label; AutoSizeAxes = Axes.X; Origin = Anchor.CentreLeft; Anchor = Anchor.CentreLeft; AdjustType.BindValueChanged(_ => updateTextColor()); InternalChild = new FillFlowContainer { Origin = Anchor.CentreLeft, Anchor = Anchor.CentreLeft, AutoSizeAxes = Axes.Both, Direction = FillDirection.Vertical, Children = new Drawable[] { text = new OsuSpriteText { Origin = Anchor.Centre, Anchor = Anchor.Centre, Text = Label, Margin = new MarginPadding { Horizontal = 15 }, // to reserve space for 0.XX value Font = OsuFont.Default.With(size: 20, weight: FontWeight.Bold) }, counter = new EffectCounter { Origin = Anchor.Centre, Anchor = Anchor.Centre, Current = { BindTarget = Current }, } } }; } public static ModEffect CalculateEffect(double oldValue, double newValue) { if (Precision.AlmostEquals(newValue, oldValue, 0.01)) return ModEffect.NotChanged; if (newValue < oldValue) return ModEffect.DifficultyReduction; return ModEffect.DifficultyIncrease; } public enum ModEffect { NotChanged, DifficultyReduction, DifficultyIncrease, } private partial class EffectCounter : RollingCounter { protected override double RollingDuration => 500; protected override LocalisableString FormatCount(double count) => count.ToLocalisableString("0.0#"); protected override OsuSpriteText CreateSpriteText() => new OsuSpriteText { Font = OsuFont.Default.With(size: 18, weight: FontWeight.SemiBold) }; } } }