2019-01-24 08:43:03 +00:00
// 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.
2018-04-13 09:19:50 +00:00
using System ;
using osu.Framework.Graphics ;
2018-11-20 07:51:59 +00:00
using osuTK ;
2018-04-13 09:19:50 +00:00
namespace osu.Game.Skinning
{
public class SkinnableDrawable : SkinnableDrawable < Drawable >
{
2019-07-18 03:10:28 +00:00
public SkinnableDrawable ( string name , Func < string , Drawable > defaultImplementation , Func < ISkinSource , bool > allowFallback = null , ConfineMode confineMode = ConfineMode . ScaleDownToFit )
: base ( name , defaultImplementation , allowFallback , confineMode )
2018-04-13 09:19:50 +00:00
{
}
}
2019-06-24 06:25:01 +00:00
/// <summary>
/// A drawable which can be skinned via an <see cref="ISkinSource"/>.
/// </summary>
/// <typeparam name="T">The type of drawable.</typeparam>
2018-04-13 09:19:50 +00:00
public class SkinnableDrawable < T > : SkinReloadableDrawable
where T : Drawable
{
2018-09-27 08:33:27 +00:00
/// <summary>
/// The displayed component. May or may not be a type-<typeparamref name="T"/> member.
/// </summary>
2018-09-27 07:27:11 +00:00
protected Drawable Drawable { get ; private set ; }
2018-04-13 09:19:50 +00:00
private readonly string componentName ;
2019-07-18 03:10:28 +00:00
private readonly ConfineMode confineMode ;
2018-04-13 09:19:50 +00:00
/// <summary>
2019-06-24 06:25:01 +00:00
/// Create a new skinnable drawable.
2018-04-13 09:19:50 +00:00
/// </summary>
/// <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="allowFallback">A conditional to decide whether to allow fallback to the default implementation if a skinned element is not present.</param>
2019-07-18 03:10:28 +00:00
/// <param name="confineMode">How (if at all) the <see cref="Drawable"/> should be resize to fit within our own bounds.</param>
public SkinnableDrawable ( string name , Func < string , T > defaultImplementation , Func < ISkinSource , bool > allowFallback = null , ConfineMode confineMode = ConfineMode . ScaleDownToFit )
: this ( name , allowFallback , confineMode )
2019-06-24 05:39:20 +00:00
{
createDefault = defaultImplementation ;
}
2019-07-18 03:10:28 +00:00
protected SkinnableDrawable ( string name , Func < ISkinSource , bool > allowFallback = null , ConfineMode confineMode = ConfineMode . ScaleDownToFit )
2018-09-27 07:27:11 +00:00
: base ( allowFallback )
2018-04-13 09:19:50 +00:00
{
componentName = name ;
2019-07-18 03:10:28 +00:00
this . confineMode = confineMode ;
2018-04-13 09:19:50 +00:00
RelativeSizeAxes = Axes . Both ;
}
2019-06-24 06:27:46 +00:00
private readonly Func < string , T > createDefault ;
protected virtual T CreateDefault ( string name ) = > createDefault ( name ) ;
2019-06-24 06:25:01 +00:00
/// <summary>
2019-07-18 03:10:28 +00:00
/// Whether to apply size restrictions (specified via <see cref="confineMode"/>) to the default implementation.
2019-06-24 06:25:01 +00:00
/// </summary>
protected virtual bool ApplySizeRestrictionsToDefault = > false ;
2019-06-24 05:39:20 +00:00
2018-04-13 09:19:50 +00:00
protected override void SkinChanged ( ISkinSource skin , bool allowFallback )
{
2018-09-27 07:27:11 +00:00
Drawable = skin . GetDrawableComponent ( componentName ) ;
2019-06-24 05:39:20 +00:00
bool isDefault = false ;
if ( Drawable = = null & & allowFallback )
{
Drawable = CreateDefault ( componentName ) ;
isDefault = true ;
}
2018-09-27 07:27:11 +00:00
if ( Drawable ! = null )
2018-04-13 09:19:50 +00:00
{
2019-07-18 03:10:28 +00:00
if ( confineMode ! = ConfineMode . NoScaling & & ( ! isDefault | | ApplySizeRestrictionsToDefault ) )
2018-04-13 09:19:50 +00:00
{
2019-07-18 03:10:28 +00:00
bool applyScaling = confineMode = = ConfineMode . ScaleToFit | |
( confineMode = = ConfineMode . ScaleDownToFit & & ( Drawable . DrawSize . X > DrawSize . X | | Drawable . DrawSize . Y > DrawSize . Y ) ) ;
if ( applyScaling )
{
Drawable . RelativeSizeAxes = Axes . Both ;
Drawable . Size = Vector2 . One ;
Drawable . Scale = Vector2 . One ;
Drawable . FillMode = FillMode . Fit ;
}
2018-04-13 09:19:50 +00:00
}
2018-09-27 07:27:11 +00:00
Drawable . Origin = Anchor . Centre ;
Drawable . Anchor = Anchor . Centre ;
2018-04-13 09:19:50 +00:00
2018-09-27 07:27:11 +00:00
InternalChild = Drawable ;
2018-04-13 09:19:50 +00:00
}
else
ClearInternal ( ) ;
}
}
2019-07-18 03:10:28 +00:00
public enum ConfineMode
{
/// <summary>
/// Don't apply any scaling. This allows the user element to be of any size, exceeding specified bounds.
/// </summary>
NoScaling ,
ScaleDownToFit ,
ScaleToFit ,
}
2018-04-13 09:19:50 +00:00
}