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; } } }