1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-13 10:03:05 +08:00

Simplify the whole Templating process

This commit is contained in:
C0D3 M4513R 2022-11-07 07:55:42 +01:00
parent 0c17571c58
commit 28ab092b6f
No known key found for this signature in database
GPG Key ID: 3FF32B5F41A39834

View File

@ -27,29 +27,11 @@ namespace osu.Game.Skinning.Components
private const BeatmapInfo default_beatmap_info = BeatmapInfo.StarRating;
public bool UsesFixedAnchor { get; set; }
[SettingSource("Tracked Beatmap Info/Label", "Which part of the BeatmapInformation should be displayed. Gets overridden by complex changes to ValueFormat")]
[SettingSource("Tracked Beatmap Info/Label", "Which part of the BeatmapInformation should be displayed.")]
public Bindable<BeatmapInfo> Type { get; } = new Bindable<BeatmapInfo>(default_beatmap_info);
[SettingSource("Show Label", "Should a Label be shown, as to which status is currently Displayed?")]
public BindableBool ShowLabel { get; } = new BindableBool(true);
[SettingSource("Show Value first?", "Should the Value be shown first?")]
public BindableBool ValueBeforeLabel { get; } = new BindableBool();
[SettingSource("Label Prefix", "Add something to be shown before the label")]
public Bindable<string> LabelPrefix { get; set; } = new Bindable<string>("");
[SettingSource("Show Label Prefix", "Should the Label Prefix be included?")]
public BindableBool ShowLabelPrefix { get; } = new BindableBool();
[SettingSource("Label Suffix", "Add something to be shown after the label")]
public Bindable<string> LabelSuffix { get; set; } = new Bindable<string>(": ");
[SettingSource("Show Label Suffix", "Should the Label Suffix be included?")]
public BindableBool ShowLabelSuffix { get; } = new BindableBool(true);
[SettingSource("Value Formatting", "Bypass the restriction of 1 Info per element. Format is '{'+Type+'}' to substitue values. e.g. '{Song}' ")]
public Bindable<string> ValueFormat { get; set; } = new Bindable<string>("{" + default_beatmap_info + "}");
[SettingSource("Template", "Bypass the restriction of 1 Info per element. Format is '{'+Type+'}' to substitue values. e.g. '{Song}' ")]
public Bindable<string> Template { get; set; } = new Bindable<string>("{Label}: {Value}");
[Resolved]
private IBindable<WorkingBeatmap> beatmap { get; set; } = null!;
@ -76,7 +58,7 @@ namespace osu.Game.Skinning.Components
[BeatmapInfo.Length] = ArtistStrings.TracklistLength,
[BeatmapInfo.Status] = BeatmapDiscussionsStrings.IndexFormBeatmapsetStatusDefault,
[BeatmapInfo.BPM] = BeatmapsetsStrings.ShowStatsBpm,
[BeatmapInfo.Custom] = BeatmapInfo.Custom.ToString()
[BeatmapInfo.None] = BeatmapInfo.None.ToString()
}.ToImmutableDictionary();
}
@ -99,102 +81,29 @@ namespace osu.Game.Skinning.Components
}
}
/// <summary>
/// This will return the if the format-String contains of a singular replacement of type info, or not.
/// If there is only one one replacement of type info, it will also return the prefix/suffix (or null if no prefix/suffix exists).
/// </summary>
/// <param name="format">The format-String to work on</param>
/// <param name="info">The replacement Type to look for</param>
/// <returns>(true, prefix, suffix), if there is only one replacement of type info. Else (false, null, null)</returns>
private static (bool, string?, string?) isOnlyPrefixedOrSuffixed(string format, BeatmapInfo info)
{
string[] s = format.Split("{" + info + "}");
foreach (string si in s)
{
foreach (var type in Enum.GetValues(typeof(BeatmapInfo)).Cast<BeatmapInfo>())
{
if (si.Contains("{" + type + "}")) return (false, null, null);
}
}
//Debug.WriteLine($"format:'{format}', type:{info} is only prefixed/suffixed");
return (true,
s.Length >= 1 ? s[0] : null, //prefix
s.Length >= 2 ? s[1] : null //suffix
);
}
protected override void LoadComplete()
{
base.LoadComplete();
Type.BindValueChanged(v =>
{
string newDefault = "{" + v.NewValue + "}";
bool custom = v.NewValue == BeatmapInfo.Custom;
//If the ValueFormat is Default and the user did not change anything we should be able to just swap the strings.
//If it was Default before, it should be default after the Type is changed.
if (ValueFormat.IsDefault && !custom)
ValueFormat.Value = newDefault;
else
{
//In this if statement we decide if the ValueFormat has been trivially changed (so only been prefixed or suffixed)
(bool preOrSuffixed, string? prefix, string? suffix) = isOnlyPrefixedOrSuffixed(ValueFormat.Value, v.OldValue);
if (preOrSuffixed)
//If it has, we can keep the prefix and suffix and just change the thing that would be substituted.
ValueFormat.Value = (prefix ?? "") + newDefault + (suffix ?? "");
//else we just keep the ValueFormat. I determine here, that the user probably knows what they are doing, and how the ValueFormat works.
}
//Only if we could preserve the ValueFormat (so nothing was changed except a static prefix/suffix) I want to set the new Default.
ValueFormat.Default = newDefault;
updateLabel();
});
ValueFormat.BindValueChanged(f => updateLabel(), true);
Type.BindValueChanged(_ => updateLabel());
Template.BindValueChanged(f => updateLabel(), true);
beatmap.BindValueChanged(b =>
{
UpdateBeatmapContent(b.NewValue);
updateLabel();
}, true);
ShowLabel.BindValueChanged(_ => updateLabel());
ValueBeforeLabel.BindValueChanged(_ => updateLabel());
LabelPrefix.BindValueChanged(_ => updateLabel());
ShowLabelPrefix.BindValueChanged(_ => updateLabel());
LabelSuffix.BindValueChanged(_ => updateLabel());
ShowLabelSuffix.BindValueChanged(_ => updateLabel());
}
private LocalisableString getLabelText()
{
if (!ShowLabel.Value) return new LocalisableString("");
return LocalisableString.Format("{0}{1}{2}",
ShowLabelPrefix.Value ? LabelPrefix.Value : "",
label_dictionary[Type.Value],
ShowLabelSuffix.Value ? LabelSuffix.Value : "");
}
private LocalisableString getValueText()
{
string value = ValueFormat.Value;
foreach (var type in Enum.GetValues(typeof(BeatmapInfo)).Cast<BeatmapInfo>())
{
value = value.Replace("{" + type + "}", valueDictionary[type].ToString());
}
return value;
}
private void updateLabel()
{
text.Text = LocalisableString.Format(
ValueBeforeLabel.Value ? "{1}{0}" : "{0}{1}",
getLabelText(),
getValueText()
);
string newText = Template.Value.Replace("{Label}", label_dictionary[Type.Value].ToString())
.Replace("{Value}", valueDictionary[Type.Value].ToString());
foreach (var type in Enum.GetValues(typeof(BeatmapInfo)).Cast<BeatmapInfo>())
{
newText = newText.Replace("{" + type + "}", valueDictionary[type].ToString());
}
text.Text = newText;
Width = text.Width;
Height = text.Height;
}
@ -230,7 +139,7 @@ namespace osu.Game.Skinning.Components
valueDictionary[BeatmapInfo.Status] = GetBetmapStatus(workingBeatmap.BeatmapInfo.Status);
//update BPM
valueDictionary[BeatmapInfo.BPM] = workingBeatmap.BeatmapInfo.BPM.ToString("F2");
valueDictionary[BeatmapInfo.Custom] = BeatmapInfo.Custom.ToString();
valueDictionary[BeatmapInfo.None] = string.Empty;
}
public static LocalisableString GetBetmapStatus(BeatmapOnlineStatus status)
@ -284,6 +193,6 @@ namespace osu.Game.Skinning.Components
Length,
Status,
BPM,
Custom,
None,
}
}