2022-11-01 20:46:32 +01:00
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
2022-11-02 13:00:45 +01:00
using System ;
2022-11-03 18:54:55 +01:00
using System.Collections.Generic ;
using System.Collections.Immutable ;
using System.Linq ;
2022-11-01 20:46:32 +01:00
using JetBrains.Annotations ;
using osu.Framework.Allocation ;
using osu.Framework.Bindables ;
2022-11-23 16:39:13 +09:00
using osu.Framework.Extensions ;
using osu.Framework.Extensions.LocalisationExtensions ;
2022-11-01 20:46:32 +01:00
using osu.Framework.Graphics ;
using osu.Framework.Graphics.Containers ;
2022-11-02 13:00:45 +01:00
using osu.Framework.Localisation ;
2022-11-01 21:19:01 +01:00
using osu.Game.Beatmaps ;
2022-11-01 20:46:32 +01:00
using osu.Game.Configuration ;
2022-11-02 13:00:45 +01:00
using osu.Game.Extensions ;
2022-11-01 20:46:32 +01:00
using osu.Game.Graphics ;
using osu.Game.Graphics.Sprites ;
2022-11-02 13:00:45 +01:00
using osu.Game.Localisation ;
using osu.Game.Resources.Localisation.Web ;
2022-11-01 20:46:32 +01:00
namespace osu.Game.Skinning.Components
{
[UsedImplicitly]
2022-11-23 16:31:50 +09:00
public partial class BeatmapAttributeText : Container , ISkinnableDrawable
2022-11-01 20:46:32 +01:00
{
public bool UsesFixedAnchor { get ; set ; }
2022-11-23 16:31:50 +09:00
[SettingSource("Attribute", "The attribute to be displayed.")]
public Bindable < BeatmapAttribute > Attribute { get ; } = new Bindable < BeatmapAttribute > ( BeatmapAttribute . StarRating ) ;
2022-11-01 20:46:32 +01:00
2022-11-23 16:31:50 +09:00
[SettingSource("Template", "Supports {Label} and {Value}, but also including arbitrary attributes like {StarRating} (see attribute list for supported values).")]
2022-11-07 07:55:42 +01:00
public Bindable < string > Template { get ; set ; } = new Bindable < string > ( "{Label}: {Value}" ) ;
2022-11-02 13:00:45 +01:00
2022-11-01 20:46:32 +01:00
[Resolved]
2022-11-02 13:00:45 +01:00
private IBindable < WorkingBeatmap > beatmap { get ; set ; } = null ! ;
2022-11-01 20:46:32 +01:00
2022-11-23 16:31:50 +09:00
private readonly Dictionary < BeatmapAttribute , LocalisableString > valueDictionary = new Dictionary < BeatmapAttribute , LocalisableString > ( ) ;
2022-11-23 16:39:13 +09:00
2022-11-23 16:49:39 +09:00
private static readonly ImmutableDictionary < BeatmapAttribute , LocalisableString > label_dictionary = new Dictionary < BeatmapAttribute , LocalisableString >
{
[BeatmapAttribute.CircleSize] = BeatmapsetsStrings . ShowStatsCs ,
[BeatmapAttribute.Accuracy] = BeatmapsetsStrings . ShowStatsAccuracy ,
[BeatmapAttribute.HPDrain] = BeatmapsetsStrings . ShowStatsDrain ,
[BeatmapAttribute.ApproachRate] = BeatmapsetsStrings . ShowStatsAr ,
[BeatmapAttribute.StarRating] = BeatmapsetsStrings . ShowStatsStars ,
[BeatmapAttribute.Title] = EditorSetupStrings . Title ,
[BeatmapAttribute.Artist] = EditorSetupStrings . Artist ,
[BeatmapAttribute.DifficultyName] = EditorSetupStrings . DifficultyHeader ,
[BeatmapAttribute.Creator] = EditorSetupStrings . Creator ,
[BeatmapAttribute.Length] = ArtistStrings . TracklistLength . ToTitle ( ) ,
[BeatmapAttribute.RankedStatus] = BeatmapDiscussionsStrings . IndexFormBeatmapsetStatusDefault ,
[BeatmapAttribute.BPM] = BeatmapsetsStrings . ShowStatsBpm ,
} . ToImmutableDictionary ( ) ;
2022-11-03 18:54:55 +01:00
2022-11-01 20:46:32 +01:00
private readonly OsuSpriteText text ;
2022-11-23 16:31:50 +09:00
public BeatmapAttributeText ( )
2022-11-01 20:46:32 +01:00
{
2022-11-07 15:22:20 +01:00
AutoSizeAxes = Axes . Both ;
2022-11-23 16:56:40 +09:00
2022-11-01 20:46:32 +01:00
InternalChildren = new Drawable [ ]
{
text = new OsuSpriteText
{
2022-11-02 13:00:45 +01:00
Anchor = Anchor . CentreLeft ,
Origin = Anchor . CentreLeft ,
2022-11-01 20:46:32 +01:00
Font = OsuFont . Default . With ( size : 40 )
}
} ;
2022-11-03 18:54:55 +01:00
}
2022-11-01 20:46:32 +01:00
protected override void LoadComplete ( )
{
base . LoadComplete ( ) ;
2022-11-23 16:56:40 +09:00
2022-11-23 16:31:50 +09:00
Attribute . BindValueChanged ( _ = > updateLabel ( ) ) ;
2022-11-23 16:56:40 +09:00
Template . BindValueChanged ( _ = > updateLabel ( ) ) ;
2022-11-03 18:54:55 +01:00
beatmap . BindValueChanged ( b = >
{
2022-11-23 16:56:40 +09:00
updateBeatmapContent ( b . NewValue ) ;
2022-11-03 18:54:55 +01:00
updateLabel ( ) ;
} , true ) ;
2022-11-02 13:00:45 +01:00
}
2022-11-23 16:56:40 +09:00
private void updateBeatmapContent ( WorkingBeatmap workingBeatmap )
2022-11-03 18:54:55 +01:00
{
2022-11-23 16:39:13 +09:00
valueDictionary [ BeatmapAttribute . Title ] = workingBeatmap . BeatmapInfo . Metadata . Title ;
2022-11-23 16:31:50 +09:00
valueDictionary [ BeatmapAttribute . Artist ] = workingBeatmap . BeatmapInfo . Metadata . Artist ;
2022-11-23 16:39:13 +09:00
valueDictionary [ BeatmapAttribute . DifficultyName ] = workingBeatmap . BeatmapInfo . DifficultyName ;
valueDictionary [ BeatmapAttribute . Creator ] = workingBeatmap . BeatmapInfo . Metadata . Author . Username ;
2022-11-23 16:31:50 +09:00
valueDictionary [ BeatmapAttribute . Length ] = TimeSpan . FromMilliseconds ( workingBeatmap . BeatmapInfo . Length ) . ToFormattedDuration ( ) ;
2022-11-23 16:49:51 +09:00
valueDictionary [ BeatmapAttribute . RankedStatus ] = workingBeatmap . BeatmapInfo . Status . GetLocalisableDescription ( ) ;
2022-11-23 21:02:43 +01:00
valueDictionary [ BeatmapAttribute . BPM ] = workingBeatmap . BeatmapInfo . BPM . ToLocalisableString ( @"F2" ) ;
valueDictionary [ BeatmapAttribute . CircleSize ] = ( ( double ) workingBeatmap . BeatmapInfo . Difficulty . CircleSize ) . ToLocalisableString ( @"F2" ) ;
valueDictionary [ BeatmapAttribute . HPDrain ] = ( ( double ) workingBeatmap . BeatmapInfo . Difficulty . DrainRate ) . ToLocalisableString ( @"F2" ) ;
valueDictionary [ BeatmapAttribute . Accuracy ] = ( ( double ) workingBeatmap . BeatmapInfo . Difficulty . OverallDifficulty ) . ToLocalisableString ( @"F2" ) ;
valueDictionary [ BeatmapAttribute . ApproachRate ] = ( ( double ) workingBeatmap . BeatmapInfo . Difficulty . ApproachRate ) . ToLocalisableString ( @"F2" ) ;
valueDictionary [ BeatmapAttribute . StarRating ] = workingBeatmap . BeatmapInfo . StarRating . ToLocalisableString ( @"F2" ) ;
2022-11-03 18:54:55 +01:00
}
2022-11-23 16:56:40 +09:00
private void updateLabel ( )
{
2022-11-23 21:02:43 +01:00
string numberedTemplate = Template . Value
. Replace ( "{" , "{{" )
. Replace ( "}" , "}}" )
. Replace ( @"{{Label}}" , "{0}" )
. Replace ( @"{{Value}}" , $"{{{1 + (int)Attribute.Value}}}" ) ;
object? [ ] args = valueDictionary . OrderBy ( pair = > pair . Key )
. Select ( pair = > pair . Value )
. Prepend ( label_dictionary [ Attribute . Value ] )
. Cast < object? > ( )
. ToArray ( ) ;
2022-11-23 16:56:40 +09:00
foreach ( var type in Enum . GetValues ( typeof ( BeatmapAttribute ) ) . Cast < BeatmapAttribute > ( ) )
{
2022-11-23 21:02:43 +01:00
numberedTemplate = numberedTemplate . Replace ( $"{{{{{type}}}}}" , $"{{{1 + (int)type}}}" ) ;
2022-11-23 16:56:40 +09:00
}
2022-11-23 21:02:43 +01:00
text . Text = LocalisableString . Format ( numberedTemplate , args ) ;
2022-11-23 16:56:40 +09:00
}
2022-11-01 20:46:32 +01:00
}
2022-11-23 16:31:50 +09:00
public enum BeatmapAttribute
2022-11-01 20:46:32 +01:00
{
CircleSize ,
HPDrain ,
2022-11-01 20:54:52 +01:00
Accuracy ,
2022-11-01 20:46:32 +01:00
ApproachRate ,
StarRating ,
2022-11-23 16:39:13 +09:00
Title ,
2022-11-01 20:46:32 +01:00
Artist ,
2022-11-23 16:39:13 +09:00
DifficultyName ,
Creator ,
2022-11-01 20:46:32 +01:00
Length ,
2022-11-23 16:39:13 +09:00
RankedStatus ,
2022-11-01 20:46:32 +01:00
BPM ,
}
}