1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-30 22:22:55 +08:00
osu-lazer/osu.Game/Graphics/UserInterface/StatefulMenuItem.cs

107 lines
4.9 KiB
C#
Raw Normal View History

// 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;
using osu.Framework.Bindables;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Localisation;
namespace osu.Game.Graphics.UserInterface
{
2019-11-08 12:14:23 +08:00
/// <summary>
/// An <see cref="OsuMenuItem"/> which contains and displays a state.
/// </summary>
public abstract class StatefulMenuItem : OsuMenuItem
{
2019-11-08 12:14:23 +08:00
/// <summary>
/// The current state that should be displayed.
/// </summary>
public readonly Bindable<object> State = new Bindable<object>();
2019-11-08 12:14:23 +08:00
/// <summary>
/// Creates a new <see cref="StatefulMenuItem"/>.
/// </summary>
/// <param name="text">The text to display.</param>
/// <param name="changeStateFunc">A function that mutates a state to another state after this <see cref="StatefulMenuItem"/> is pressed.</param>
/// <param name="type">The type of action which this <see cref="StatefulMenuItem"/> performs.</param>
protected StatefulMenuItem(LocalisableString text, Func<object, object> changeStateFunc, MenuItemType type = MenuItemType.Standard)
2019-11-08 11:55:22 +08:00
: this(text, changeStateFunc, type, null)
{
}
2019-11-08 12:14:23 +08:00
/// <summary>
/// Creates a new <see cref="StatefulMenuItem"/>.
/// </summary>
/// <param name="text">The text to display.</param>
/// <param name="changeStateFunc">A function that mutates a state to another state after this <see cref="StatefulMenuItem"/> is pressed.</param>
/// <param name="type">The type of action which this <see cref="StatefulMenuItem"/> performs.</param>
/// <param name="action">A delegate to be invoked when this <see cref="StatefulMenuItem"/> is pressed.</param>
protected StatefulMenuItem(LocalisableString text, Func<object, object>? changeStateFunc, MenuItemType type, Action<object>? action)
: base(text, type)
{
2019-11-08 11:55:22 +08:00
Action.Value = () =>
{
State.Value = changeStateFunc?.Invoke(State.Value) ?? State.Value;
action?.Invoke(State.Value);
};
}
2019-11-08 12:14:23 +08:00
/// <summary>
/// Retrieves the icon to be displayed for a state.
/// </summary>
/// <param name="state">The state to retrieve the relevant icon for.</param>
/// <returns>The icon to be displayed for <paramref name="state"/>.</returns>
public abstract IconUsage? GetIconForState(object state);
}
public abstract class StatefulMenuItem<T> : StatefulMenuItem
where T : struct
{
2019-11-08 12:14:23 +08:00
/// <summary>
/// The current state that should be displayed.
/// </summary>
public new readonly Bindable<T> State = new Bindable<T>();
2019-11-08 12:14:23 +08:00
/// <summary>
/// Creates a new <see cref="StatefulMenuItem"/>.
/// </summary>
/// <param name="text">The text to display.</param>
/// <param name="changeStateFunc">A function that mutates a state to another state after this <see cref="StatefulMenuItem"/> is pressed.</param>
/// <param name="type">The type of action which this <see cref="StatefulMenuItem"/> performs.</param>
protected StatefulMenuItem(LocalisableString text, Func<T, T>? changeStateFunc, MenuItemType type = MenuItemType.Standard)
2019-11-08 11:55:22 +08:00
: this(text, changeStateFunc, type, null)
{
}
2019-11-08 12:14:23 +08:00
/// <summary>
/// Creates a new <see cref="StatefulMenuItem"/>.
/// </summary>
/// <param name="text">The text to display.</param>
/// <param name="changeStateFunc">A function that mutates a state to another state after this <see cref="StatefulMenuItem"/> is pressed.</param>
/// <param name="type">The type of action which this <see cref="StatefulMenuItem"/> performs.</param>
/// <param name="action">A delegate to be invoked when this <see cref="StatefulMenuItem"/> is pressed.</param>
protected StatefulMenuItem(LocalisableString text, Func<T, T>? changeStateFunc, MenuItemType type, Action<T>? action)
2019-11-08 11:55:22 +08:00
: base(text, o => changeStateFunc?.Invoke((T)o) ?? o, type, o => action?.Invoke((T)o))
{
base.State.BindValueChanged(state =>
{
if (state.NewValue == null)
base.State.Value = default(T);
State.Value = (T)base.State.Value;
}, true);
State.BindValueChanged(state => base.State.Value = state.NewValue);
}
public sealed override IconUsage? GetIconForState(object state) => GetIconForState((T)state);
2019-11-08 12:14:23 +08:00
/// <summary>
/// Retrieves the icon to be displayed for a state.
/// </summary>
/// <param name="state">The state to retrieve the relevant icon for.</param>
/// <returns>The icon to be displayed for <paramref name="state"/>.</returns>
public abstract IconUsage? GetIconForState(T state);
}
}