2022-11-02 03:46:32 +08: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 20:00:45 +08:00
using System ;
2022-11-04 01:54:55 +08:00
using System.Collections.Generic ;
using System.Collections.Immutable ;
using System.Linq ;
2022-11-02 03:46:32 +08:00
using JetBrains.Annotations ;
using osu.Framework.Allocation ;
using osu.Framework.Bindables ;
2022-11-23 15:39:13 +08:00
using osu.Framework.Extensions ;
using osu.Framework.Extensions.LocalisationExtensions ;
2022-11-02 03:46:32 +08:00
using osu.Framework.Graphics ;
using osu.Framework.Graphics.Containers ;
2022-11-02 20:00:45 +08:00
using osu.Framework.Localisation ;
2022-11-02 04:19:01 +08:00
using osu.Game.Beatmaps ;
2022-11-02 03:46:32 +08:00
using osu.Game.Configuration ;
2022-11-02 20:00:45 +08:00
using osu.Game.Extensions ;
2022-11-02 03:46:32 +08:00
using osu.Game.Graphics ;
using osu.Game.Graphics.Sprites ;
2022-11-02 20:00:45 +08:00
using osu.Game.Localisation ;
using osu.Game.Resources.Localisation.Web ;
2022-11-02 03:46:32 +08:00
namespace osu.Game.Skinning.Components
{
[UsedImplicitly]
2022-11-26 23:30:10 +08:00
public partial class BeatmapAttributeText : Container , ISkinnableDrawable
2022-11-02 03:46:32 +08:00
{
public bool UsesFixedAnchor { get ; set ; }
2022-11-23 15:31:50 +08:00
[SettingSource("Attribute", "The attribute to be displayed.")]
public Bindable < BeatmapAttribute > Attribute { get ; } = new Bindable < BeatmapAttribute > ( BeatmapAttribute . StarRating ) ;
2022-11-02 03:46:32 +08:00
2022-11-23 15:31:50 +08:00
[SettingSource("Template", "Supports {Label} and {Value}, but also including arbitrary attributes like {StarRating} (see attribute list for supported values).")]
2022-11-07 14:55:42 +08:00
public Bindable < string > Template { get ; set ; } = new Bindable < string > ( "{Label}: {Value}" ) ;
2022-11-02 20:00:45 +08:00
2022-11-02 03:46:32 +08:00
[Resolved]
2022-11-02 20:00:45 +08:00
private IBindable < WorkingBeatmap > beatmap { get ; set ; } = null ! ;
2022-11-02 03:46:32 +08:00
2022-11-23 15:31:50 +08:00
private readonly Dictionary < BeatmapAttribute , LocalisableString > valueDictionary = new Dictionary < BeatmapAttribute , LocalisableString > ( ) ;
2022-11-23 15:39:13 +08:00
2022-11-23 15:49:39 +08: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-04 01:54:55 +08:00
2022-11-02 03:46:32 +08:00
private readonly OsuSpriteText text ;
2022-11-23 15:31:50 +08:00
public BeatmapAttributeText ( )
2022-11-02 03:46:32 +08:00
{
2022-11-07 22:22:20 +08:00
AutoSizeAxes = Axes . Both ;
2022-11-23 15:56:40 +08:00
2022-11-02 03:46:32 +08:00
InternalChildren = new Drawable [ ]
{
text = new OsuSpriteText
{
2022-11-02 20:00:45 +08:00
Anchor = Anchor . CentreLeft ,
Origin = Anchor . CentreLeft ,
2022-11-02 03:46:32 +08:00
Font = OsuFont . Default . With ( size : 40 )
}
} ;
2022-11-04 01:54:55 +08:00
}
2022-11-02 03:46:32 +08:00
protected override void LoadComplete ( )
{
base . LoadComplete ( ) ;
2022-11-23 15:56:40 +08:00
2022-11-23 15:31:50 +08:00
Attribute . BindValueChanged ( _ = > updateLabel ( ) ) ;
2022-11-23 15:56:40 +08:00
Template . BindValueChanged ( _ = > updateLabel ( ) ) ;
2022-11-04 01:54:55 +08:00
beatmap . BindValueChanged ( b = >
{
2022-11-23 15:56:40 +08:00
updateBeatmapContent ( b . NewValue ) ;
2022-11-04 01:54:55 +08:00
updateLabel ( ) ;
} , true ) ;
2022-11-02 20:00:45 +08:00
}
2022-11-23 15:56:40 +08:00
private void updateBeatmapContent ( WorkingBeatmap workingBeatmap )
2022-11-04 01:54:55 +08:00
{
2022-11-23 15:39:13 +08:00
valueDictionary [ BeatmapAttribute . Title ] = workingBeatmap . BeatmapInfo . Metadata . Title ;
2022-11-23 15:31:50 +08:00
valueDictionary [ BeatmapAttribute . Artist ] = workingBeatmap . BeatmapInfo . Metadata . Artist ;
2022-11-23 15:39:13 +08:00
valueDictionary [ BeatmapAttribute . DifficultyName ] = workingBeatmap . BeatmapInfo . DifficultyName ;
valueDictionary [ BeatmapAttribute . Creator ] = workingBeatmap . BeatmapInfo . Metadata . Author . Username ;
2022-11-23 15:31:50 +08:00
valueDictionary [ BeatmapAttribute . Length ] = TimeSpan . FromMilliseconds ( workingBeatmap . BeatmapInfo . Length ) . ToFormattedDuration ( ) ;
2022-11-23 15:49:51 +08:00
valueDictionary [ BeatmapAttribute . RankedStatus ] = workingBeatmap . BeatmapInfo . Status . GetLocalisableDescription ( ) ;
2022-11-24 04:02:43 +08: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-04 01:54:55 +08:00
}
2022-11-23 15:56:40 +08:00
private void updateLabel ( )
{
2022-11-24 04:02:43 +08: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 15:56:40 +08:00
foreach ( var type in Enum . GetValues ( typeof ( BeatmapAttribute ) ) . Cast < BeatmapAttribute > ( ) )
{
2022-11-24 04:02:43 +08:00
numberedTemplate = numberedTemplate . Replace ( $"{{{{{type}}}}}" , $"{{{1 + (int)type}}}" ) ;
2022-11-23 15:56:40 +08:00
}
2022-11-24 04:02:43 +08:00
text . Text = LocalisableString . Format ( numberedTemplate , args ) ;
2022-11-23 15:56:40 +08:00
}
2022-11-02 03:46:32 +08:00
}
2022-11-23 15:31:50 +08:00
public enum BeatmapAttribute
2022-11-02 03:46:32 +08:00
{
CircleSize ,
HPDrain ,
2022-11-02 03:54:52 +08:00
Accuracy ,
2022-11-02 03:46:32 +08:00
ApproachRate ,
StarRating ,
2022-11-23 15:39:13 +08:00
Title ,
2022-11-02 03:46:32 +08:00
Artist ,
2022-11-23 15:39:13 +08:00
DifficultyName ,
Creator ,
2022-11-02 03:46:32 +08:00
Length ,
2022-11-23 15:39:13 +08:00
RankedStatus ,
2022-11-02 03:46:32 +08:00
BPM ,
}
}