diff --git a/osu.Game/Overlays/Settings/ISettingsItem.cs b/osu.Game/Overlays/Settings/ISettingsItem.cs
index e7afa48502..fe21f0664a 100644
--- a/osu.Game/Overlays/Settings/ISettingsItem.cs
+++ b/osu.Game/Overlays/Settings/ISettingsItem.cs
@@ -2,12 +2,17 @@
// See the LICENCE file in the repository root for full licence text.
using System;
-using osu.Framework.Graphics;
namespace osu.Game.Overlays.Settings
{
- public interface ISettingsItem : IDrawable, IDisposable
+ ///
+ /// A non-generic interface for s.
+ ///
+ public interface ISettingsItem : IExpandable, IDisposable
{
+ ///
+ /// Invoked when the setting value has changed.
+ ///
event Action SettingChanged;
}
}
diff --git a/osu.Game/Overlays/Settings/SettingsItem.cs b/osu.Game/Overlays/Settings/SettingsItem.cs
index e709be1343..cc8d5b36d0 100644
--- a/osu.Game/Overlays/Settings/SettingsItem.cs
+++ b/osu.Game/Overlays/Settings/SettingsItem.cs
@@ -30,7 +30,7 @@ namespace osu.Game.Overlays.Settings
protected readonly FillFlowContainer FlowContent;
- private SpriteText labelText;
+ private SpriteText label;
private OsuTextFlowContainer warningText;
@@ -42,21 +42,34 @@ namespace osu.Game.Overlays.Settings
[Resolved]
private OsuColour colours { get; set; }
+ private LocalisableString labelText;
+
public virtual LocalisableString LabelText
{
- get => labelText?.Text ?? string.Empty;
+ get => labelText;
set
{
- if (labelText == null)
- {
- // construct lazily for cases where the label is not needed (may be provided by the Control).
- FlowContent.Insert(-1, labelText = new OsuSpriteText());
+ ensureLabelCreated();
- updateDisabled();
- }
+ labelText = value;
+ updateLabelText();
+ }
+ }
- labelText.Text = value;
- updateLayout();
+ private LocalisableString? contractedLabelText;
+
+ ///
+ /// Text to be displayed in place of when this is in a contracted state.
+ ///
+ public LocalisableString? ContractedLabelText
+ {
+ get => contractedLabelText;
+ set
+ {
+ ensureLabelCreated();
+
+ contractedLabelText = value;
+ updateLabelText();
}
}
@@ -90,6 +103,10 @@ namespace osu.Game.Overlays.Settings
set => controlWithCurrent.Current = value;
}
+ public BindableBool Expanded { get; } = new BindableBool(true);
+
+ public event Action SettingChanged;
+
public virtual IEnumerable FilterTerms => Keywords == null ? new[] { LabelText.ToString() } : new List(Keywords) { LabelText.ToString() }.ToArray();
public IEnumerable Keywords { get; set; }
@@ -101,8 +118,6 @@ namespace osu.Game.Overlays.Settings
public bool FilteringActive { get; set; }
- public event Action SettingChanged;
-
protected SettingsItem()
{
RelativeSizeAxes = Axes.X;
@@ -151,23 +166,59 @@ namespace osu.Game.Overlays.Settings
Anchor = Anchor.Centre,
Origin = Anchor.Centre
});
- updateLayout();
}
}
- private void updateLayout()
- {
- bool hasLabel = labelText != null && !string.IsNullOrEmpty(labelText.Text.ToString());
+ [Resolved(canBeNull: true)]
+ private IExpandingContainer expandingContainer { get; set; }
- // if the settings item is providing a label, the default value indicator should be centred vertically to the left of the label.
+ protected override void LoadComplete()
+ {
+ base.LoadComplete();
+
+ expandingContainer?.Expanded.BindValueChanged(containerExpanded => Expanded.Value = containerExpanded.NewValue, true);
+
+ Expanded.BindValueChanged(v =>
+ {
+ updateLabelText();
+
+ Control.FadeTo(v.NewValue ? 1 : 0, 500, Easing.OutQuint);
+ Control.BypassAutoSizeAxes = v.NewValue ? Axes.None : Axes.Both;
+ }, true);
+
+ FinishTransforms(true);
+ }
+
+ private void ensureLabelCreated()
+ {
+ if (label != null)
+ return;
+
+ // construct lazily for cases where the label is not needed (may be provided by the Control).
+ FlowContent.Insert(-1, label = new OsuSpriteText());
+
+ updateDisabled();
+ }
+
+ private void updateLabelText()
+ {
+ if (label != null)
+ {
+ if (contractedLabelText is LocalisableString contractedText)
+ label.Text = Expanded.Value ? labelText : contractedText;
+ else
+ label.Text = labelText;
+ }
+
+ // if the settings item is providing a non-empty label, the default value indicator should be centred vertically to the left of the label.
// otherwise, it should be centred vertically to the left of the main control of the settings item.
- defaultValueIndicatorContainer.Height = hasLabel ? labelText.DrawHeight : Control.DrawHeight;
+ defaultValueIndicatorContainer.Height = !string.IsNullOrEmpty(label?.Text.ToString()) ? label.DrawHeight : Control.DrawHeight;
}
private void updateDisabled()
{
- if (labelText != null)
- labelText.Alpha = controlWithCurrent.Current.Disabled ? 0.3f : 1;
+ if (label != null)
+ label.Alpha = controlWithCurrent.Current.Disabled ? 0.3f : 1;
}
}
}