Add SkinnableSprite class (#5137)

Add SkinnableSprite class
This commit is contained in:
Dean Herbert 2019-06-24 17:11:21 +09:00 committed by GitHub
commit 303fb508af
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 58 additions and 12 deletions

View File

@ -4,7 +4,6 @@
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Textures; using osu.Framework.Graphics.Textures;
using osu.Game.Skinning; using osu.Game.Skinning;
@ -25,7 +24,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(TextureStore textures) private void load(TextureStore textures)
{ {
Child = new SkinnableDrawable("Play/osu/approachcircle", name => new Sprite { Texture = textures.Get(name) }); Child = new SkinnableSprite("Play/osu/approachcircle");
} }
} }
} }

View File

@ -15,6 +15,10 @@ namespace osu.Game.Skinning
} }
} }
/// <summary>
/// A drawable which can be skinned via an <see cref="ISkinSource"/>.
/// </summary>
/// <typeparam name="T">The type of drawable.</typeparam>
public class SkinnableDrawable<T> : SkinReloadableDrawable public class SkinnableDrawable<T> : SkinReloadableDrawable
where T : Drawable where T : Drawable
{ {
@ -23,48 +27,63 @@ namespace osu.Game.Skinning
/// </summary> /// </summary>
protected Drawable Drawable { get; private set; } protected Drawable Drawable { get; private set; }
private readonly Func<string, T> createDefault;
private readonly string componentName; private readonly string componentName;
private readonly bool restrictSize; private readonly bool restrictSize;
/// <summary> /// <summary>
/// /// Create a new skinnable drawable.
/// </summary> /// </summary>
/// <param name="name">The namespace-complete resource name for this skinnable element.</param> /// <param name="name">The namespace-complete resource name for this skinnable element.</param>
/// <param name="defaultImplementation">A function to create the default skin implementation of this element.</param> /// <param name="defaultImplementation">A function to create the default skin implementation of this element.</param>
/// <param name="allowFallback">A conditional to decide whether to allow fallback to the default implementation if a skinned element is not present.</param> /// <param name="allowFallback">A conditional to decide whether to allow fallback to the default implementation if a skinned element is not present.</param>
/// <param name="restrictSize">Whether a user-skin drawable should be limited to the size of our parent.</param> /// <param name="restrictSize">Whether a user-skin drawable should be limited to the size of our parent.</param>
public SkinnableDrawable(string name, Func<string, T> defaultImplementation, Func<ISkinSource, bool> allowFallback = null, bool restrictSize = true) public SkinnableDrawable(string name, Func<string, T> defaultImplementation, Func<ISkinSource, bool> allowFallback = null, bool restrictSize = true)
: this(name, allowFallback, restrictSize)
{
createDefault = defaultImplementation;
}
protected SkinnableDrawable(string name, Func<ISkinSource, bool> allowFallback = null, bool restrictSize = true)
: base(allowFallback) : base(allowFallback)
{ {
componentName = name; componentName = name;
createDefault = defaultImplementation;
this.restrictSize = restrictSize; this.restrictSize = restrictSize;
RelativeSizeAxes = Axes.Both; RelativeSizeAxes = Axes.Both;
} }
private readonly Func<string, T> createDefault;
protected virtual T CreateDefault(string name) => createDefault(name);
/// <summary>
/// Whether to apply size restrictions (specified via <see cref="restrictSize"/>) to the default implementation.
/// </summary>
protected virtual bool ApplySizeRestrictionsToDefault => false;
protected override void SkinChanged(ISkinSource skin, bool allowFallback) protected override void SkinChanged(ISkinSource skin, bool allowFallback)
{ {
Drawable = skin.GetDrawableComponent(componentName); Drawable = skin.GetDrawableComponent(componentName);
bool isDefault = false;
if (Drawable == null && allowFallback)
{
Drawable = CreateDefault(componentName);
isDefault = true;
}
if (Drawable != null) if (Drawable != null)
{ {
if (restrictSize) if (restrictSize && (!isDefault || ApplySizeRestrictionsToDefault))
{ {
Drawable.RelativeSizeAxes = Axes.Both; Drawable.RelativeSizeAxes = Axes.Both;
Drawable.Size = Vector2.One; Drawable.Size = Vector2.One;
Drawable.Scale = Vector2.One; Drawable.Scale = Vector2.One;
Drawable.FillMode = FillMode.Fit; Drawable.FillMode = FillMode.Fit;
} }
}
else if (allowFallback)
Drawable = createDefault(componentName);
if (Drawable != null)
{
Drawable.Origin = Anchor.Centre; Drawable.Origin = Anchor.Centre;
Drawable.Anchor = Anchor.Centre; Drawable.Anchor = Anchor.Centre;

View File

@ -0,0 +1,28 @@
// 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.Allocation;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Textures;
namespace osu.Game.Skinning
{
/// <summary>
/// A skinnable element which uses a stable sprite and can therefore share implementation logic.
/// </summary>
public class SkinnableSprite : SkinnableDrawable<Sprite>
{
protected override bool ApplySizeRestrictionsToDefault => true;
[Resolved]
private TextureStore textures { get; set; }
public SkinnableSprite(string name, Func<ISkinSource, bool> allowFallback = null, bool restrictSize = true)
: base(name, allowFallback, restrictSize)
{
}
protected override Sprite CreateDefault(string name) => new Sprite { Texture = textures.Get(name) };
}
}