1
0
mirror of https://github.com/ppy/osu.git synced 2026-05-13 20:33:35 +08:00

Merge pull request #32540 from frenzibyte/mod-rich-tooltip

Display mod tooltips in rich form
This commit is contained in:
Dean Herbert
2025-03-25 16:44:43 +09:00
committed by GitHub
Unverified
18 changed files with 353 additions and 119 deletions
@@ -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,11 +220,15 @@ namespace osu.Game.Online.Leaderboards
}
};
string description = string.Join(", ", mod.SettingDescription.Select(svp => $"{svp.setting}: {svp.value}"));
if (!string.IsNullOrEmpty(description))
{
container.Add(new OsuSpriteText
{
RelativeSizeAxes = Axes.Y,
Font = OsuFont.GetFont(size: 12, weight: FontWeight.SemiBold),
Text = mod.IconTooltip,
Text = description,
Origin = Anchor.CentreLeft,
Anchor = Anchor.CentreLeft,
Margin = new MarginPadding { Top = 1 },
@@ -232,3 +237,4 @@ namespace osu.Game.Online.Leaderboards
}
}
}
}
+16 -1
View File
@@ -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,10 +76,22 @@ namespace osu.Game.Overlays.Mods
TabbableContentContainer = this,
Current = { Value = preset.PerformRead(p => p.Description) },
},
new OsuScrollContainer
new Container
{
RelativeSizeAxes = Axes.X,
Height = 100,
CornerRadius = 10,
Masking = true,
Children = new Drawable[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = colourProvider.Background5,
},
new OsuScrollContainer
{
RelativeSizeAxes = Axes.Both,
Padding = new MarginPadding(7),
Child = scrollContent = new FillFlowContainer
{
@@ -88,6 +101,8 @@ namespace osu.Game.Overlays.Mods
Spacing = new Vector2(7),
}
},
}
},
new FillFlowContainer
{
Anchor = Anchor.TopCentre,
+46 -16
View File
@@ -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)),
},
}
}
};
}
}
}
+14 -1
View File
@@ -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;
if (!string.IsNullOrEmpty(preset.Description))
{
descriptionText.Show();
descriptionText.Text = preset.Description;
}
else
descriptionText.Hide();
lastPreset = preset;
+4 -27
View File
@@ -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)));
}
}
+16 -2
View File
@@ -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
+9 -1
View File
@@ -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;
+10 -3
View File
@@ -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");
}
}
}
}
+9 -1
View File
@@ -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;
+9 -3
View File
@@ -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);
}
}
+141
View File
@@ -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