Add the ability to add settings to skinnable elements

This commit is contained in:
Dean Herbert 2022-03-11 23:27:27 +09:00
parent 7a2a3528ef
commit c99397f75a
3 changed files with 47 additions and 0 deletions

View File

@ -1,8 +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 Humanizer;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Configuration;
using osu.Game.Screens.Play.HUD;
using osu.Game.Skinning;
using osuTK;
@ -59,8 +62,18 @@ namespace osu.Game.Extensions
component.Origin = info.Origin;
if (component is ISkinnableDrawable skinnable)
{
skinnable.UsesFixedAnchor = info.UsesFixedAnchor;
foreach (var (_, property) in component.GetSettingsSourceProperties())
{
if (!info.Settings.TryGetValue(property.Name.Underscore(), out object settingValue))
continue;
skinnable.CopyAdjustedSetting((IBindable)property.GetValue(component), settingValue);
}
}
if (component is Container container)
{
foreach (var child in info.Children)

View File

@ -4,11 +4,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Humanizer;
using Newtonsoft.Json;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Configuration;
using osu.Game.Extensions;
using osu.Game.Skinning;
using osu.Game.Utils;
using osuTK;
namespace osu.Game.Screens.Play.HUD
@ -34,6 +38,8 @@ namespace osu.Game.Screens.Play.HUD
/// <inheritdoc cref="ISkinnableDrawable.UsesFixedAnchor"/>
public bool UsesFixedAnchor { get; set; }
public Dictionary<string, object> Settings { get; set; } = new Dictionary<string, object>();
public List<SkinnableInfo> Children { get; } = new List<SkinnableInfo>();
[JsonConstructor]
@ -58,6 +64,14 @@ namespace osu.Game.Screens.Play.HUD
if (component is ISkinnableDrawable skinnable)
UsesFixedAnchor = skinnable.UsesFixedAnchor;
foreach (var (_, property) in component.GetSettingsSourceProperties())
{
var bindable = (IBindable)property.GetValue(component);
if (!bindable.IsDefault)
Settings.Add(property.Name.Underscore(), ModUtils.GetSettingUnderlyingValue(bindable));
}
if (component is Container<Drawable> container)
{
foreach (var child in container.OfType<ISkinnableDrawable>().OfType<Drawable>())

View File

@ -1,6 +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;
using osu.Framework.Bindables;
using osu.Framework.Extensions.TypeExtensions;
using osu.Framework.Graphics;
namespace osu.Game.Skinning
@ -21,5 +24,22 @@ namespace osu.Game.Skinning
/// If <see langword="true"/>, a fixed anchor point has been defined.
/// </summary>
bool UsesFixedAnchor { get; set; }
void CopyAdjustedSetting(IBindable target, object source)
{
if (source is IBindable sourceBindable)
{
// copy including transfer of default values.
target.BindTo(sourceBindable);
target.UnbindFrom(sourceBindable);
}
else
{
if (!(target is IParseable parseable))
throw new InvalidOperationException($"Bindable type {target.GetType().ReadableName()} is not {nameof(IParseable)}.");
parseable.Parse(source);
}
}
}
}