mirror of
https://github.com/ppy/osu.git
synced 2026-05-13 19:54:15 +08:00
Merge pull request #32540 from frenzibyte/mod-rich-tooltip
Display mod tooltips in rich form
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
// 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.
|
||||
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Localisation;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Configuration;
|
||||
using osu.Game.Rulesets.Catch.Beatmaps;
|
||||
@@ -35,21 +36,21 @@ namespace osu.Game.Rulesets.Catch.Mods
|
||||
[SettingSource("Spicy Patterns", "Adjust the patterns as if Hard Rock is enabled.")]
|
||||
public BindableBool HardRockOffsets { get; } = new BindableBool();
|
||||
|
||||
public override string SettingDescription
|
||||
public override IEnumerable<(LocalisableString setting, LocalisableString value)> SettingDescription
|
||||
{
|
||||
get
|
||||
{
|
||||
string circleSize = CircleSize.IsDefault ? string.Empty : $"CS {CircleSize.Value:N1}";
|
||||
string approachRate = ApproachRate.IsDefault ? string.Empty : $"AR {ApproachRate.Value:N1}";
|
||||
string spicyPatterns = HardRockOffsets.IsDefault ? string.Empty : "Spicy patterns";
|
||||
if (!CircleSize.IsDefault)
|
||||
yield return ("Circle size", $"{CircleSize.Value:N1}");
|
||||
|
||||
return string.Join(", ", new[]
|
||||
{
|
||||
circleSize,
|
||||
base.SettingDescription,
|
||||
approachRate,
|
||||
spicyPatterns,
|
||||
}.Where(s => !string.IsNullOrEmpty(s)));
|
||||
foreach (var setting in base.SettingDescription)
|
||||
yield return setting;
|
||||
|
||||
if (!ApproachRate.IsDefault)
|
||||
yield return ("Approach rate", $"{ApproachRate.Value:N1}");
|
||||
|
||||
if (!HardRockOffsets.IsDefault)
|
||||
yield return ("Spicy patterns", "On");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// 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.
|
||||
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Localisation;
|
||||
using osu.Game.Beatmaps;
|
||||
@@ -36,19 +36,18 @@ namespace osu.Game.Rulesets.Osu.Mods
|
||||
ReadCurrentFromDifficulty = diff => diff.ApproachRate,
|
||||
};
|
||||
|
||||
public override string SettingDescription
|
||||
public override IEnumerable<(LocalisableString setting, LocalisableString value)> SettingDescription
|
||||
{
|
||||
get
|
||||
{
|
||||
string circleSize = CircleSize.IsDefault ? string.Empty : $"CS {CircleSize.Value:N1}";
|
||||
string approachRate = ApproachRate.IsDefault ? string.Empty : $"AR {ApproachRate.Value:N1}";
|
||||
if (!CircleSize.IsDefault)
|
||||
yield return ("Circle size", $"{CircleSize.Value:N1}");
|
||||
|
||||
return string.Join(", ", new[]
|
||||
{
|
||||
circleSize,
|
||||
base.SettingDescription,
|
||||
approachRate
|
||||
}.Where(s => !string.IsNullOrEmpty(s)));
|
||||
foreach (var setting in base.SettingDescription)
|
||||
yield return setting;
|
||||
|
||||
if (!ApproachRate.IsDefault)
|
||||
yield return ("Approach rate", $"{ApproachRate.Value:N1}");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
// 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.
|
||||
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using osu.Framework.Localisation;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Configuration;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
@@ -19,17 +20,15 @@ namespace osu.Game.Rulesets.Taiko.Mods
|
||||
ReadCurrentFromDifficulty = _ => 1,
|
||||
};
|
||||
|
||||
public override string SettingDescription
|
||||
public override IEnumerable<(LocalisableString setting, LocalisableString value)> SettingDescription
|
||||
{
|
||||
get
|
||||
{
|
||||
string scrollSpeed = ScrollSpeed.IsDefault ? string.Empty : $"Scroll x{ScrollSpeed.Value:N2}";
|
||||
foreach (var setting in base.SettingDescription)
|
||||
yield return setting;
|
||||
|
||||
return string.Join(", ", new[]
|
||||
{
|
||||
base.SettingDescription,
|
||||
scrollSpeed
|
||||
}.Where(s => !string.IsNullOrEmpty(s)));
|
||||
if (!ScrollSpeed.IsDefault)
|
||||
yield return ("Scroll speed", $"x{ScrollSpeed.Value:N2}");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// 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.
|
||||
|
||||
using System.Linq;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
@@ -219,15 +220,20 @@ namespace osu.Game.Online.Leaderboards
|
||||
}
|
||||
};
|
||||
|
||||
container.Add(new OsuSpriteText
|
||||
string description = string.Join(", ", mod.SettingDescription.Select(svp => $"{svp.setting}: {svp.value}"));
|
||||
|
||||
if (!string.IsNullOrEmpty(description))
|
||||
{
|
||||
RelativeSizeAxes = Axes.Y,
|
||||
Font = OsuFont.GetFont(size: 12, weight: FontWeight.SemiBold),
|
||||
Text = mod.IconTooltip,
|
||||
Origin = Anchor.CentreLeft,
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Margin = new MarginPadding { Top = 1 },
|
||||
});
|
||||
container.Add(new OsuSpriteText
|
||||
{
|
||||
RelativeSizeAxes = Axes.Y,
|
||||
Font = OsuFont.GetFont(size: 12, weight: FontWeight.SemiBold),
|
||||
Text = description,
|
||||
Origin = Anchor.CentreLeft,
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Margin = new MarginPadding { Top = 1 },
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ using osu.Framework.Bindables;
|
||||
using osu.Framework.Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Input.Events;
|
||||
using osu.Game.Database;
|
||||
using osu.Game.Graphics;
|
||||
@@ -75,17 +76,31 @@ namespace osu.Game.Overlays.Mods
|
||||
TabbableContentContainer = this,
|
||||
Current = { Value = preset.PerformRead(p => p.Description) },
|
||||
},
|
||||
new OsuScrollContainer
|
||||
new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Height = 100,
|
||||
Padding = new MarginPadding(7),
|
||||
Child = scrollContent = new FillFlowContainer
|
||||
CornerRadius = 10,
|
||||
Masking = true,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Padding = new MarginPadding(7),
|
||||
Spacing = new Vector2(7),
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = colourProvider.Background5,
|
||||
},
|
||||
new OsuScrollContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Padding = new MarginPadding(7),
|
||||
Child = scrollContent = new FillFlowContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Padding = new MarginPadding(7),
|
||||
Spacing = new Vector2(7),
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
new FillFlowContainer
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
// 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.
|
||||
|
||||
using System.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Rulesets.UI;
|
||||
@@ -14,12 +15,20 @@ namespace osu.Game.Overlays.Mods
|
||||
{
|
||||
public partial class ModPresetRow : FillFlowContainer
|
||||
{
|
||||
private readonly Mod mod;
|
||||
|
||||
public ModPresetRow(Mod mod)
|
||||
{
|
||||
this.mod = mod;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OverlayColourProvider colourProvider)
|
||||
{
|
||||
RelativeSizeAxes = Axes.X;
|
||||
AutoSizeAxes = Axes.Y;
|
||||
Direction = FillDirection.Vertical;
|
||||
Spacing = new Vector2(4);
|
||||
Spacing = new Vector2(5);
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
new FillFlowContainer
|
||||
@@ -39,26 +48,47 @@ namespace osu.Game.Overlays.Mods
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
Text = mod.Name,
|
||||
Font = OsuFont.Default.With(size: 16, weight: FontWeight.SemiBold),
|
||||
Origin = Anchor.CentreLeft,
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Margin = new MarginPadding { Bottom = 2 }
|
||||
}
|
||||
Origin = Anchor.CentreLeft,
|
||||
Font = OsuFont.Torus.With(size: 16f, weight: FontWeight.SemiBold),
|
||||
Colour = colourProvider.Content1,
|
||||
UseFullGlyphHeight = false,
|
||||
Text = mod.Name,
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (!string.IsNullOrEmpty(mod.SettingDescription))
|
||||
{
|
||||
AddInternal(new OsuTextFlowContainer
|
||||
},
|
||||
new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Padding = new MarginPadding { Left = 14 },
|
||||
Text = mod.SettingDescription
|
||||
});
|
||||
}
|
||||
Padding = new MarginPadding { Horizontal = 10f },
|
||||
Alpha = mod.SettingDescription.Any() ? 1 : 0,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new TextFlowContainer(t =>
|
||||
{
|
||||
t.Font = OsuFont.Torus.With(size: 12f, weight: FontWeight.SemiBold);
|
||||
})
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Colour = colourProvider.Content2,
|
||||
Text = string.Join('\n', mod.SettingDescription.Select(svp => svp.setting)),
|
||||
},
|
||||
new TextFlowContainer(t =>
|
||||
{
|
||||
t.Font = OsuFont.Torus.With(size: 12f, weight: FontWeight.SemiBold);
|
||||
})
|
||||
{
|
||||
Anchor = Anchor.TopRight,
|
||||
Origin = Anchor.TopRight,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Colour = colourProvider.Content1,
|
||||
TextAnchor = Anchor.TopRight,
|
||||
Text = string.Join('\n', mod.SettingDescription.Select(svp => svp.value)),
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Cursor;
|
||||
@@ -14,6 +15,9 @@ namespace osu.Game.Overlays.Mods
|
||||
{
|
||||
public partial class ModPresetTooltip : VisibilityContainer, ITooltip<ModPreset>
|
||||
{
|
||||
[Cached]
|
||||
private readonly OverlayColourProvider colourProvider;
|
||||
|
||||
protected override Container<Drawable> Content { get; }
|
||||
|
||||
private const double transition_duration = 200;
|
||||
@@ -22,6 +26,8 @@ namespace osu.Game.Overlays.Mods
|
||||
|
||||
public ModPresetTooltip(OverlayColourProvider colourProvider)
|
||||
{
|
||||
this.colourProvider = colourProvider;
|
||||
|
||||
Width = 250;
|
||||
AutoSizeAxes = Axes.Y;
|
||||
|
||||
@@ -39,7 +45,7 @@ namespace osu.Game.Overlays.Mods
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Padding = new MarginPadding { Left = 10, Right = 10, Top = 5, Bottom = 5 },
|
||||
Padding = new MarginPadding(10f),
|
||||
Spacing = new Vector2(7),
|
||||
Children = new[]
|
||||
{
|
||||
@@ -51,6 +57,7 @@ namespace osu.Game.Overlays.Mods
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Margin = new MarginPadding { Bottom = 5f },
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -64,7 +71,13 @@ namespace osu.Game.Overlays.Mods
|
||||
if (ReferenceEquals(preset, lastPreset))
|
||||
return;
|
||||
|
||||
descriptionText.Text = preset.Description;
|
||||
if (!string.IsNullOrEmpty(preset.Description))
|
||||
{
|
||||
descriptionText.Show();
|
||||
descriptionText.Text = preset.Description;
|
||||
}
|
||||
else
|
||||
descriptionText.Hide();
|
||||
|
||||
lastPreset = preset;
|
||||
|
||||
|
||||
@@ -14,7 +14,6 @@ using osu.Framework.Graphics.Sprites;
|
||||
using osu.Framework.Localisation;
|
||||
using osu.Game.Configuration;
|
||||
using osu.Game.Extensions;
|
||||
using osu.Game.Rulesets.UI;
|
||||
using osu.Game.Utils;
|
||||
|
||||
namespace osu.Game.Rulesets.Mods
|
||||
@@ -43,36 +42,16 @@ namespace osu.Game.Rulesets.Mods
|
||||
public abstract LocalisableString Description { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The tooltip to display for this mod when used in a <see cref="ModIcon"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Differs from <see cref="Name"/>, as the value of attributes (AR, CS, etc) changeable via the mod
|
||||
/// are displayed in the tooltip.
|
||||
/// </remarks>
|
||||
[JsonIgnore]
|
||||
public string IconTooltip
|
||||
{
|
||||
get
|
||||
{
|
||||
string description = SettingDescription;
|
||||
|
||||
return string.IsNullOrEmpty(description) ? Name : $"{Name} ({description})";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The description of editable settings of a mod to use in the <see cref="IconTooltip"/>.
|
||||
/// The description of editable settings of a mod.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Parentheses are added to the tooltip, surrounding the value of this property. If this property is <c>string.Empty</c>,
|
||||
/// the tooltip will not have parentheses.
|
||||
/// </remarks>
|
||||
public virtual string SettingDescription
|
||||
public virtual IEnumerable<(LocalisableString setting, LocalisableString value)> SettingDescription
|
||||
{
|
||||
get
|
||||
{
|
||||
var tooltipTexts = new List<string>();
|
||||
|
||||
foreach ((SettingSourceAttribute attr, PropertyInfo property) in this.GetOrderedSettingsSourceProperties())
|
||||
{
|
||||
var bindable = (IBindable)property.GetValue(this)!;
|
||||
@@ -82,7 +61,7 @@ namespace osu.Game.Rulesets.Mods
|
||||
switch (bindable)
|
||||
{
|
||||
case Bindable<bool> b:
|
||||
valueText = b.Value ? "on" : "off";
|
||||
valueText = b.Value ? "On" : "Off";
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -91,10 +70,8 @@ namespace osu.Game.Rulesets.Mods
|
||||
}
|
||||
|
||||
if (!bindable.IsDefault)
|
||||
tooltipTexts.Add($"{attr.Label}: {valueText}");
|
||||
yield return (attr.Label, valueText);
|
||||
}
|
||||
|
||||
return string.Join(", ", tooltipTexts.Where(s => !string.IsNullOrEmpty(s)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,9 +2,10 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Extensions.LocalisationExtensions;
|
||||
using osu.Framework.Localisation;
|
||||
using osu.Game.Configuration;
|
||||
using osu.Game.Localisation.HUD;
|
||||
@@ -33,7 +34,20 @@ namespace osu.Game.Rulesets.Mods
|
||||
|
||||
public override bool Ranked => true;
|
||||
|
||||
public override string SettingDescription => base.SettingDescription.Replace(MinimumAccuracy.ToString(), MinimumAccuracy.Value.ToString("##%", NumberFormatInfo.InvariantInfo));
|
||||
public override IEnumerable<(LocalisableString setting, LocalisableString value)> SettingDescription
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!MinimumAccuracy.IsDefault)
|
||||
yield return ("Minimum accuracy", $"{MinimumAccuracy.Value:##%}");
|
||||
|
||||
if (!AccuracyJudgeMode.IsDefault)
|
||||
yield return ("Accuracy mode", AccuracyJudgeMode.Value.ToLocalisableString());
|
||||
|
||||
if (!Restart.IsDefault)
|
||||
yield return ("Restart on fail", "On");
|
||||
}
|
||||
}
|
||||
|
||||
[SettingSource("Minimum accuracy", "Trigger a failure if your accuracy goes below this value.", SettingControlType = typeof(SettingsPercentageSlider<double>))]
|
||||
public BindableNumber<double> MinimumAccuracy { get; } = new BindableDouble
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
@@ -38,7 +39,14 @@ namespace osu.Game.Rulesets.Mods
|
||||
public override LocalisableString Description => "The whole playfield is on a wheel!";
|
||||
public override double ScoreMultiplier => 1;
|
||||
|
||||
public override string SettingDescription => $"{SpinSpeed.Value:N2} rpm {Direction.Value.GetDescription().ToLowerInvariant()}";
|
||||
public override IEnumerable<(LocalisableString setting, LocalisableString value)> SettingDescription
|
||||
{
|
||||
get
|
||||
{
|
||||
yield return ("Roll speed", $"{SpinSpeed.Value:N2} rpm");
|
||||
yield return ("Direction", Direction.Value.GetDescription());
|
||||
}
|
||||
}
|
||||
|
||||
private PlayfieldAdjustmentContainer playfieldAdjustmentContainer = null!;
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Framework.Localisation;
|
||||
@@ -65,18 +65,15 @@ namespace osu.Game.Rulesets.Mods
|
||||
}
|
||||
}
|
||||
|
||||
public override string SettingDescription
|
||||
public override IEnumerable<(LocalisableString setting, LocalisableString value)> SettingDescription
|
||||
{
|
||||
get
|
||||
{
|
||||
string drainRate = DrainRate.IsDefault ? string.Empty : $"HP {DrainRate.Value:N1}";
|
||||
string overallDifficulty = OverallDifficulty.IsDefault ? string.Empty : $"OD {OverallDifficulty.Value:N1}";
|
||||
if (!DrainRate.IsDefault)
|
||||
yield return ("HP drain", $"{DrainRate.Value:N1}");
|
||||
|
||||
return string.Join(", ", new[]
|
||||
{
|
||||
drainRate,
|
||||
overallDifficulty
|
||||
}.Where(s => !string.IsNullOrEmpty(s)));
|
||||
if (!OverallDifficulty.IsDefault)
|
||||
yield return ("Accuracy", $"{OverallDifficulty.Value:N1}");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,9 +2,11 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Humanizer;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Localisation;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Configuration;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
@@ -20,7 +22,15 @@ namespace osu.Game.Rulesets.Mods
|
||||
MaxValue = 10
|
||||
};
|
||||
|
||||
public override string SettingDescription => Retries.IsDefault ? string.Empty : $"{"lives".ToQuantity(Retries.Value)}";
|
||||
public override IEnumerable<(LocalisableString setting, LocalisableString value)> SettingDescription
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!Retries.IsDefault)
|
||||
yield return ("Extra lives", "lives".ToQuantity(Retries.Value));
|
||||
}
|
||||
}
|
||||
|
||||
public override Type[] IncompatibleMods => base.IncompatibleMods.Append(typeof(ModAccuracyChallenge)).ToArray();
|
||||
|
||||
private int retries;
|
||||
|
||||
@@ -2,8 +2,10 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using osu.Framework.Audio;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Localisation;
|
||||
|
||||
namespace osu.Game.Rulesets.Mods
|
||||
{
|
||||
@@ -24,8 +26,13 @@ namespace osu.Game.Rulesets.Mods
|
||||
|
||||
public override Type[] IncompatibleMods => new[] { typeof(ModTimeRamp), typeof(ModAdaptiveSpeed), typeof(ModRateAdjust) };
|
||||
|
||||
public override string SettingDescription => SpeedChange.IsDefault ? string.Empty : $"{SpeedChange.Value:N2}x";
|
||||
|
||||
public override string ExtendedIconInformation => SettingDescription;
|
||||
public override IEnumerable<(LocalisableString setting, LocalisableString value)> SettingDescription
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!SpeedChange.IsDefault)
|
||||
yield return ("Speed change", $"{SpeedChange.Value:N2}x");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,9 +2,11 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using osu.Framework.Audio;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Localisation;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Configuration;
|
||||
using osu.Game.Overlays.Settings;
|
||||
@@ -34,7 +36,13 @@ namespace osu.Game.Rulesets.Mods
|
||||
|
||||
public override Type[] IncompatibleMods => new[] { typeof(ModRateAdjust), typeof(ModAdaptiveSpeed) };
|
||||
|
||||
public override string SettingDescription => $"{InitialRate.Value:N2}x to {FinalRate.Value:N2}x";
|
||||
public override IEnumerable<(LocalisableString setting, LocalisableString value)> SettingDescription
|
||||
{
|
||||
get
|
||||
{
|
||||
yield return ("Speed change", $"{InitialRate.Value:N2}x to {FinalRate.Value:N2}x");
|
||||
}
|
||||
}
|
||||
|
||||
private double finalRateTime;
|
||||
private double beginRampTime;
|
||||
|
||||
@@ -10,11 +10,11 @@ using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Cursor;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Framework.Graphics.Textures;
|
||||
using osu.Framework.Localisation;
|
||||
using osu.Framework.Utils;
|
||||
using osu.Game.Configuration;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Overlays;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
@@ -24,7 +24,7 @@ namespace osu.Game.Rulesets.UI
|
||||
/// <summary>
|
||||
/// Display the specified mod at a fixed size.
|
||||
/// </summary>
|
||||
public partial class ModIcon : Container, IHasTooltip
|
||||
public partial class ModIcon : Container, IHasCustomTooltip<Mod>
|
||||
{
|
||||
public readonly BindableBool Selected = new BindableBool();
|
||||
|
||||
@@ -34,7 +34,7 @@ namespace osu.Game.Rulesets.UI
|
||||
|
||||
public static readonly Vector2 MOD_ICON_SIZE = new Vector2(80);
|
||||
|
||||
public virtual LocalisableString TooltipText => showTooltip ? ((mod as Mod)?.IconTooltip ?? mod.Name) : string.Empty;
|
||||
public Mod? TooltipContent { get; private set; }
|
||||
|
||||
private IMod mod;
|
||||
|
||||
@@ -70,6 +70,9 @@ namespace osu.Game.Rulesets.UI
|
||||
[Resolved]
|
||||
private OsuColour colours { get; set; } = null!;
|
||||
|
||||
[Resolved]
|
||||
private OverlayColourProvider? colourProvider { get; set; }
|
||||
|
||||
private Color4 backgroundColour;
|
||||
|
||||
private Sprite extendedBackground = null!;
|
||||
@@ -188,6 +191,7 @@ namespace osu.Game.Rulesets.UI
|
||||
|
||||
modAcronym.Text = value.Acronym;
|
||||
modIcon.Icon = value.Icon ?? FontAwesome.Solid.Question;
|
||||
TooltipContent = showTooltip ? value as Mod : null;
|
||||
|
||||
if (value.Icon == null)
|
||||
{
|
||||
@@ -227,5 +231,7 @@ namespace osu.Game.Rulesets.UI
|
||||
base.Dispose(isDisposing);
|
||||
modSettingsChangeTracker?.Dispose();
|
||||
}
|
||||
|
||||
public ITooltip<Mod> GetCustomTooltip() => new ModTooltip(colourProvider);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,141 @@
|
||||
// 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.
|
||||
|
||||
using System.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Cursor;
|
||||
using osu.Framework.Graphics.Effects;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Overlays;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Rulesets.UI
|
||||
{
|
||||
public partial class ModTooltip : VisibilityContainer, ITooltip<Mod>
|
||||
{
|
||||
private readonly OverlayColourProvider colourProvider;
|
||||
|
||||
private OsuSpriteText nameText = null!;
|
||||
private TextFlowContainer settingsLabelsFlow = null!;
|
||||
private TextFlowContainer settingsValuesFlow = null!;
|
||||
|
||||
public ModTooltip(OverlayColourProvider? colourProvider = null)
|
||||
{
|
||||
this.colourProvider = colourProvider ?? new OverlayColourProvider(OverlayColourScheme.Aquamarine);
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
AutoSizeAxes = Axes.Both;
|
||||
CornerRadius = 7;
|
||||
Masking = true;
|
||||
|
||||
EdgeEffect = new EdgeEffectParameters
|
||||
{
|
||||
Type = EdgeEffectType.Shadow,
|
||||
Colour = Color4.Black.Opacity(0.2f),
|
||||
Radius = 10f,
|
||||
};
|
||||
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = colourProvider.Background6,
|
||||
},
|
||||
new FillFlowContainer
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Horizontal,
|
||||
Padding = new MarginPadding(10f),
|
||||
Spacing = new Vector2(20f, 0f),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new FillFlowContainer
|
||||
{
|
||||
Anchor = Anchor.BottomLeft,
|
||||
Origin = Anchor.BottomLeft,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Vertical,
|
||||
Spacing = new Vector2(0f, 5f),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
nameText = new OsuSpriteText
|
||||
{
|
||||
Font = OsuFont.Torus.With(size: 16f, weight: FontWeight.SemiBold),
|
||||
Colour = colourProvider.Content1,
|
||||
UseFullGlyphHeight = false,
|
||||
},
|
||||
settingsLabelsFlow = new TextFlowContainer(t =>
|
||||
{
|
||||
t.Font = OsuFont.Torus.With(size: 12f, weight: FontWeight.SemiBold);
|
||||
})
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Colour = colourProvider.Content2,
|
||||
},
|
||||
},
|
||||
},
|
||||
settingsValuesFlow = new TextFlowContainer(t =>
|
||||
{
|
||||
t.Font = OsuFont.Torus.With(size: 12f, weight: FontWeight.SemiBold);
|
||||
})
|
||||
{
|
||||
Anchor = Anchor.BottomLeft,
|
||||
Origin = Anchor.BottomLeft,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Colour = colourProvider.Content1,
|
||||
TextAnchor = Anchor.TopRight,
|
||||
},
|
||||
},
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private Mod? displayedContent;
|
||||
|
||||
public void SetContent(Mod content)
|
||||
{
|
||||
if (content == displayedContent)
|
||||
return;
|
||||
|
||||
displayedContent = content;
|
||||
nameText.Text = content.Name;
|
||||
settingsLabelsFlow.Clear();
|
||||
settingsValuesFlow.Clear();
|
||||
|
||||
if (content.SettingDescription.Any())
|
||||
{
|
||||
settingsLabelsFlow.Show();
|
||||
settingsValuesFlow.Show();
|
||||
|
||||
foreach (var part in content.SettingDescription)
|
||||
{
|
||||
settingsLabelsFlow.AddText(part.setting);
|
||||
settingsLabelsFlow.NewLine();
|
||||
|
||||
settingsValuesFlow.AddText(part.value);
|
||||
settingsValuesFlow.NewLine();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
settingsLabelsFlow.Hide();
|
||||
settingsValuesFlow.Hide();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void PopIn() => this.FadeIn(300, Easing.OutQuint);
|
||||
protected override void PopOut() => this.FadeOut(300, Easing.OutQuint);
|
||||
public void Move(Vector2 pos) => Position = pos;
|
||||
}
|
||||
}
|
||||
@@ -244,18 +244,18 @@ namespace osu.Game.Screens.SelectV2.Footer
|
||||
Mods.BindValueChanged(v => Text = ModSelectOverlayStrings.Mods(v.NewValue.Count).ToUpper(), true);
|
||||
}
|
||||
|
||||
public ITooltip<IReadOnlyList<Mod>> GetCustomTooltip() => new ModTooltip(colourProvider);
|
||||
public ITooltip<IReadOnlyList<Mod>> GetCustomTooltip() => new ModOverflowTooltip(colourProvider);
|
||||
|
||||
public IReadOnlyList<Mod>? TooltipContent => Mods.Value;
|
||||
|
||||
public partial class ModTooltip : VisibilityContainer, ITooltip<IReadOnlyList<Mod>>
|
||||
public partial class ModOverflowTooltip : VisibilityContainer, ITooltip<IReadOnlyList<Mod>>
|
||||
{
|
||||
private ModDisplay extendedModDisplay = null!;
|
||||
|
||||
[Cached]
|
||||
private OverlayColourProvider colourProvider;
|
||||
|
||||
public ModTooltip(OverlayColourProvider colourProvider)
|
||||
public ModOverflowTooltip(OverlayColourProvider colourProvider)
|
||||
{
|
||||
this.colourProvider = colourProvider;
|
||||
}
|
||||
|
||||
@@ -715,18 +715,21 @@ namespace osu.Game.Screens.SelectV2.Leaderboards
|
||||
public LocalisableString TooltipText { get; }
|
||||
}
|
||||
|
||||
private sealed partial class ColouredModSwitchTiny : ModSwitchTiny, IHasTooltip
|
||||
private sealed partial class ColouredModSwitchTiny : ModSwitchTiny, IHasCustomTooltip<Mod>
|
||||
{
|
||||
private readonly IMod mod;
|
||||
public Mod? TooltipContent { get; }
|
||||
|
||||
public ColouredModSwitchTiny(IMod mod)
|
||||
[Resolved]
|
||||
private OverlayColourProvider colourProvider { get; set; } = null!;
|
||||
|
||||
public ColouredModSwitchTiny(Mod mod)
|
||||
: base(mod)
|
||||
{
|
||||
this.mod = mod;
|
||||
TooltipContent = mod;
|
||||
Active.Value = true;
|
||||
}
|
||||
|
||||
public LocalisableString TooltipText => (mod as Mod)?.IconTooltip ?? mod.Name;
|
||||
public ITooltip<Mod> GetCustomTooltip() => new ModTooltip(colourProvider);
|
||||
}
|
||||
|
||||
private sealed partial class MoreModSwitchTiny : CompositeDrawable
|
||||
|
||||
Reference in New Issue
Block a user