2021-05-06 14:16:16 +08: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.
2021-05-11 16:48:08 +08:00
using System ;
2021-05-10 21:36:20 +08:00
using System.Collections.Generic ;
using System.Linq ;
2021-05-11 16:48:08 +08:00
using osu.Framework.Bindables ;
2021-05-11 10:56:14 +08:00
using osu.Framework.Graphics ;
2021-05-10 21:36:20 +08:00
using osu.Game.Extensions ;
2021-05-12 14:59:33 +08:00
using osu.Game.Screens.Play.HUD ;
2021-05-06 14:16:16 +08:00
2021-05-12 14:59:33 +08:00
namespace osu.Game.Skinning
2021-05-06 14:16:16 +08:00
{
2021-05-07 17:18:29 +08:00
public class SkinnableElementTargetContainer : SkinReloadableDrawable , ISkinnableTarget
2021-05-06 14:16:16 +08:00
{
2021-05-10 21:36:20 +08:00
private SkinnableTargetWrapper content ;
2021-05-07 18:13:38 +08:00
public SkinnableTarget Target { get ; }
2021-05-11 16:48:08 +08:00
public IBindableList < ISkinnableComponent > Components = > components ;
private readonly BindableList < ISkinnableComponent > components = new BindableList < ISkinnableComponent > ( ) ;
2021-05-07 18:13:38 +08:00
public SkinnableElementTargetContainer ( SkinnableTarget target )
{
Target = target ;
}
2021-05-13 12:13:22 +08:00
/// <summary>
/// Reload all components in this container from the current skin.
/// </summary>
2021-05-11 10:56:14 +08:00
public void Reload ( )
{
ClearInternal ( ) ;
2021-05-11 16:48:08 +08:00
components . Clear ( ) ;
content = CurrentSkin . GetDrawableComponent ( new SkinnableTargetComponent ( Target ) ) as SkinnableTargetWrapper ;
2021-05-11 10:56:14 +08:00
if ( content ! = null )
2021-05-11 16:48:08 +08:00
{
LoadComponentAsync ( content , wrapper = >
{
AddInternal ( wrapper ) ;
components . AddRange ( wrapper . Children . OfType < ISkinnableComponent > ( ) ) ;
} ) ;
}
2021-05-11 10:56:14 +08:00
}
2021-05-13 12:13:22 +08:00
/// <summary>
/// Add a new skinnable component to this target.
/// </summary>
/// <param name="component">The component to add.</param>
/// <exception cref="NotSupportedException">Thrown when attempting to add an element to a target which is not supported by the current skin.</exception>
/// <exception cref="ArgumentException">Thrown if the provided instance is not a <see cref="Drawable"/>.</exception>
2021-05-11 16:48:08 +08:00
public void Add ( ISkinnableComponent component )
2021-05-11 10:56:14 +08:00
{
2021-05-11 16:48:08 +08:00
if ( content = = null )
throw new NotSupportedException ( "Attempting to add a new component to a target container which is not supported by the current skin." ) ;
if ( ! ( component is Drawable drawable ) )
throw new ArgumentException ( "Provided argument must be of type {nameof(ISkinnableComponent)}." , nameof ( drawable ) ) ;
2021-05-11 10:56:14 +08:00
content . Add ( drawable ) ;
2021-05-11 16:48:08 +08:00
components . Add ( component ) ;
2021-05-11 10:56:14 +08:00
}
2021-05-13 12:14:49 +08:00
/// <summary>
/// Serialise all children as <see cref="SkinnableInfo"/>.
/// </summary>
/// <returns>The serialised content.</returns>
public IEnumerable < SkinnableInfo > CreateSkinnableInfo ( ) = > components . Select ( d = > ( ( Drawable ) d ) . CreateSkinnableInfo ( ) ) ;
2021-05-10 21:36:20 +08:00
2021-05-07 17:18:29 +08:00
protected override void SkinChanged ( ISkinSource skin , bool allowFallback )
{
base . SkinChanged ( skin , allowFallback ) ;
2021-05-11 10:56:14 +08:00
Reload ( ) ;
2021-05-07 17:18:29 +08:00
}
2021-05-06 14:16:16 +08:00
}
}