diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableDrawable.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableDrawable.cs
index 96418f6d28..77966e925a 100644
--- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableDrawable.cs
+++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableDrawable.cs
@@ -167,7 +167,7 @@ namespace osu.Game.Tests.Visual.Gameplay
public void Disable()
{
allow = false;
- TriggerSourceChanged();
+ OnSourceChanged();
}
public SwitchableSkinProvidingContainer(ISkin skin)
diff --git a/osu.Game/Skinning/BeatmapSkinProvidingContainer.cs b/osu.Game/Skinning/BeatmapSkinProvidingContainer.cs
index 57c08a903f..f12f44e347 100644
--- a/osu.Game/Skinning/BeatmapSkinProvidingContainer.cs
+++ b/osu.Game/Skinning/BeatmapSkinProvidingContainer.cs
@@ -83,9 +83,9 @@ namespace osu.Game.Skinning
[BackgroundDependencyLoader]
private void load()
{
- beatmapSkins.BindValueChanged(_ => TriggerSourceChanged());
- beatmapColours.BindValueChanged(_ => TriggerSourceChanged());
- beatmapHitsounds.BindValueChanged(_ => TriggerSourceChanged());
+ beatmapSkins.BindValueChanged(_ => OnSourceChanged());
+ beatmapColours.BindValueChanged(_ => OnSourceChanged());
+ beatmapHitsounds.BindValueChanged(_ => OnSourceChanged());
}
}
}
diff --git a/osu.Game/Skinning/SkinProvidingContainer.cs b/osu.Game/Skinning/SkinProvidingContainer.cs
index 0e16cf43ee..cc9d8d0e8d 100644
--- a/osu.Game/Skinning/SkinProvidingContainer.cs
+++ b/osu.Game/Skinning/SkinProvidingContainer.cs
@@ -2,6 +2,7 @@
// See the LICENCE file in the repository root for full licence text.
using System;
+using System.Collections.Generic;
using JetBrains.Annotations;
using osu.Framework.Allocation;
using osu.Framework.Audio.Sample;
@@ -21,8 +22,10 @@ namespace osu.Game.Skinning
{
public event Action SourceChanged;
- [CanBeNull]
- private readonly ISkin skin;
+ ///
+ /// The list of skins provided by this .
+ ///
+ protected readonly List SkinLayers = new List();
[CanBeNull]
private ISkinSource fallbackSource;
@@ -38,23 +41,30 @@ namespace osu.Game.Skinning
protected virtual bool AllowColourLookup => true;
public SkinProvidingContainer(ISkin skin)
+ : this()
{
- this.skin = skin;
+ SkinLayers.Add(skin);
+ }
+ protected SkinProvidingContainer()
+ {
RelativeSizeAxes = Axes.Both;
}
public ISkin FindProvider(Func lookupFunction)
{
- if (skin is ISkinSource source)
+ foreach (var skin in SkinLayers)
{
- if (source.FindProvider(lookupFunction) is ISkin found)
- return found;
- }
- else if (skin != null)
- {
- if (lookupFunction(skin))
- return skin;
+ if (skin is ISkinSource source)
+ {
+ if (source.FindProvider(lookupFunction) is ISkin found)
+ return found;
+ }
+ else if (skin != null)
+ {
+ if (lookupFunction(skin))
+ return skin;
+ }
}
return fallbackSource?.FindProvider(lookupFunction);
@@ -62,57 +72,73 @@ namespace osu.Game.Skinning
public Drawable GetDrawableComponent(ISkinComponent component)
{
- Drawable sourceDrawable;
- if (AllowDrawableLookup(component) && (sourceDrawable = skin?.GetDrawableComponent(component)) != null)
- return sourceDrawable;
+ if (AllowDrawableLookup(component))
+ {
+ foreach (var skin in SkinLayers)
+ {
+ Drawable sourceDrawable;
+ if ((sourceDrawable = skin?.GetDrawableComponent(component)) != null)
+ return sourceDrawable;
+ }
+ }
return fallbackSource?.GetDrawableComponent(component);
}
public Texture GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT)
{
- Texture sourceTexture;
- if (AllowTextureLookup(componentName) && (sourceTexture = skin?.GetTexture(componentName, wrapModeS, wrapModeT)) != null)
- return sourceTexture;
+ if (AllowTextureLookup(componentName))
+ {
+ foreach (var skin in SkinLayers)
+ {
+ Texture sourceTexture;
+ if ((sourceTexture = skin?.GetTexture(componentName, wrapModeS, wrapModeT)) != null)
+ return sourceTexture;
+ }
+ }
return fallbackSource?.GetTexture(componentName, wrapModeS, wrapModeT);
}
public ISample GetSample(ISampleInfo sampleInfo)
{
- ISample sourceChannel;
- if (AllowSampleLookup(sampleInfo) && (sourceChannel = skin?.GetSample(sampleInfo)) != null)
- return sourceChannel;
+ if (AllowSampleLookup(sampleInfo))
+ {
+ foreach (var skin in SkinLayers)
+ {
+ ISample sourceSample;
+ if ((sourceSample = skin?.GetSample(sampleInfo)) != null)
+ return sourceSample;
+ }
+ }
return fallbackSource?.GetSample(sampleInfo);
}
public IBindable GetConfig(TLookup lookup)
{
- if (skin != null)
- {
- if (lookup is GlobalSkinColours || lookup is SkinCustomColourLookup)
- return lookupWithFallback(lookup, AllowColourLookup);
+ if (lookup is GlobalSkinColours || lookup is SkinCustomColourLookup)
+ return lookupWithFallback(lookup, AllowColourLookup);
- return lookupWithFallback(lookup, AllowConfigurationLookup);
- }
-
- return fallbackSource?.GetConfig(lookup);
+ return lookupWithFallback(lookup, AllowConfigurationLookup);
}
private IBindable lookupWithFallback(TLookup lookup, bool canUseSkinLookup)
{
if (canUseSkinLookup)
{
- var bindable = skin?.GetConfig(lookup);
- if (bindable != null)
- return bindable;
+ foreach (var skin in SkinLayers)
+ {
+ IBindable bindable;
+ if ((bindable = skin?.GetConfig(lookup)) != null)
+ return bindable;
+ }
}
return fallbackSource?.GetConfig(lookup);
}
- protected virtual void TriggerSourceChanged() => SourceChanged?.Invoke();
+ protected virtual void OnSourceChanged() => SourceChanged?.Invoke();
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
{
@@ -120,7 +146,7 @@ namespace osu.Game.Skinning
fallbackSource = dependencies.Get();
if (fallbackSource != null)
- fallbackSource.SourceChanged += TriggerSourceChanged;
+ fallbackSource.SourceChanged += OnSourceChanged;
dependencies.CacheAs(this);
@@ -135,7 +161,7 @@ namespace osu.Game.Skinning
base.Dispose(isDisposing);
if (fallbackSource != null)
- fallbackSource.SourceChanged -= TriggerSourceChanged;
+ fallbackSource.SourceChanged -= OnSourceChanged;
}
}
}