diff --git a/osu.Game/Extensions/DrawableExtensions.cs b/osu.Game/Extensions/DrawableExtensions.cs
index 3d2ffe0ea1..289b305c27 100644
--- a/osu.Game/Extensions/DrawableExtensions.cs
+++ b/osu.Game/Extensions/DrawableExtensions.cs
@@ -45,6 +45,15 @@ namespace osu.Game.Extensions
public static Vector2 ScreenSpaceDeltaToParentSpace(this Drawable drawable, Vector2 delta) =>
drawable.Parent.ToLocalSpace(drawable.Parent.ToScreenSpace(Vector2.Zero) + delta);
- public static StoredSkinnableInfo CreateSerialisedInformation(this Drawable component) => new StoredSkinnableInfo(component);
+ public static SkinnableInfo CreateSerialisedInformation(this Drawable component) => new SkinnableInfo(component);
+
+ public static void ApplySerialisedInformation(this Drawable component, ISkinnableInfo info)
+ {
+ // todo: can probably make this better via deserialisation directly using a common interface.
+ component.Position = info.Position;
+ component.Rotation = info.Rotation;
+ component.Scale = info.Scale;
+ component.Anchor = info.Anchor;
+ }
}
}
diff --git a/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs b/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs
index 2e84c9c97d..0e147f9238 100644
--- a/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs
+++ b/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs
@@ -13,13 +13,12 @@ using osu.Framework.Graphics.Sprites;
using osu.Game.Graphics;
using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Scoring;
-using osu.Game.Skinning;
using osuTK;
using osuTK.Graphics;
namespace osu.Game.Screens.Play.HUD.HitErrorMeters
{
- public class BarHitErrorMeter : HitErrorMeter, ISkinnableComponent
+ public class BarHitErrorMeter : HitErrorMeter
{
private readonly Anchor alignment;
diff --git a/osu.Game/Screens/Play/HUD/ISkinnableInfo.cs b/osu.Game/Screens/Play/HUD/ISkinnableInfo.cs
index 0e571b5cb4..fc4e9680a8 100644
--- a/osu.Game/Screens/Play/HUD/ISkinnableInfo.cs
+++ b/osu.Game/Screens/Play/HUD/ISkinnableInfo.cs
@@ -4,6 +4,7 @@
using System;
using osu.Framework.Graphics;
using osu.Game.IO.Serialization;
+using osu.Game.Skinning;
using osuTK;
namespace osu.Game.Screens.Play.HUD
@@ -12,7 +13,7 @@ namespace osu.Game.Screens.Play.HUD
{
public Type Type { get; set; }
- public Type Target { get; set; }
+ public SkinnableTarget? Target { get; set; }
public Vector2 Position { get; set; }
@@ -22,11 +23,4 @@ namespace osu.Game.Screens.Play.HUD
public Anchor Anchor { get; set; }
}
-
- ///
- /// A container which supports skinnable components being added to it.
- ///
- public interface ISkinnableTarget
- {
- }
}
diff --git a/osu.Game/Screens/Play/HUD/ISkinnableTarget.cs b/osu.Game/Screens/Play/HUD/ISkinnableTarget.cs
new file mode 100644
index 0000000000..6cd269333a
--- /dev/null
+++ b/osu.Game/Screens/Play/HUD/ISkinnableTarget.cs
@@ -0,0 +1,15 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using osu.Game.Skinning;
+
+namespace osu.Game.Screens.Play.HUD
+{
+ ///
+ /// A container which supports skinnable components being added to it.
+ ///
+ public interface ISkinnableTarget
+ {
+ public SkinnableTarget Target { get; }
+ }
+}
diff --git a/osu.Game/Screens/Play/HUD/SkinnableElementTargetContainer.cs b/osu.Game/Screens/Play/HUD/SkinnableElementTargetContainer.cs
index 8da7950c57..bd82533823 100644
--- a/osu.Game/Screens/Play/HUD/SkinnableElementTargetContainer.cs
+++ b/osu.Game/Screens/Play/HUD/SkinnableElementTargetContainer.cs
@@ -1,24 +1,28 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-using System;
-using System.Collections.Generic;
-using osu.Framework.Graphics;
using osu.Game.Skinning;
namespace osu.Game.Screens.Play.HUD
{
public class SkinnableElementTargetContainer : SkinReloadableDrawable, ISkinnableTarget
{
+ public SkinnableTarget Target { get; }
+
+ public SkinnableElementTargetContainer(SkinnableTarget target)
+ {
+ Target = target;
+ }
+
protected override void SkinChanged(ISkinSource skin, bool allowFallback)
{
base.SkinChanged(skin, allowFallback);
- var loadable = skin.GetConfig>(this.GetType());
+ var loadable = skin.GetDrawableComponent(new SkinnableTargetComponent(Target));
ClearInternal();
if (loadable != null)
- LoadComponentsAsync(loadable.Value, AddRangeInternal);
+ LoadComponentAsync(loadable, AddInternal);
}
}
}
diff --git a/osu.Game/Screens/Play/HUD/StoredSkinnableInfo.cs b/osu.Game/Screens/Play/HUD/SkinnableInfo.cs
similarity index 51%
rename from osu.Game/Screens/Play/HUD/StoredSkinnableInfo.cs
rename to osu.Game/Screens/Play/HUD/SkinnableInfo.cs
index e4ec035e68..5b1f840efd 100644
--- a/osu.Game/Screens/Play/HUD/StoredSkinnableInfo.cs
+++ b/osu.Game/Screens/Play/HUD/SkinnableInfo.cs
@@ -2,7 +2,11 @@
// See the LICENCE file in the repository root for full licence text.
using System;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Converters;
using osu.Framework.Graphics;
+using osu.Game.Extensions;
+using osu.Game.Skinning;
using osuTK;
namespace osu.Game.Screens.Play.HUD
@@ -10,17 +14,20 @@ namespace osu.Game.Screens.Play.HUD
///
/// Serialised information governing custom changes to an .
///
- public class StoredSkinnableInfo : ISkinnableInfo
+ [Serializable]
+ public class SkinnableInfo : ISkinnableInfo
{
- public StoredSkinnableInfo(Drawable component)
+ public SkinnableInfo()
+ {
+ }
+
+ public SkinnableInfo(Drawable component)
{
Type = component.GetType();
- var target = component.Parent as ISkinnableTarget
- // todo: this is temporary until we serialise the default layouts out of SkinnableDrawables.
- ?? component.Parent?.Parent as ISkinnableTarget;
+ ISkinnableTarget target = component.Parent as ISkinnableTarget;
- Target = target?.GetType();
+ Target = target?.Target;
Position = component.Position;
Rotation = component.Rotation;
@@ -30,7 +37,8 @@ namespace osu.Game.Screens.Play.HUD
public Type Type { get; set; }
- public Type Target { get; set; }
+ [JsonConverter(typeof(StringEnumConverter))]
+ public SkinnableTarget? Target { get; set; }
public Vector2 Position { get; set; }
@@ -40,4 +48,14 @@ namespace osu.Game.Screens.Play.HUD
public Anchor Anchor { get; set; }
}
+
+ public static class SkinnableInfoExtensions
+ {
+ public static Drawable CreateInstance(this ISkinnableInfo info)
+ {
+ Drawable d = (Drawable)Activator.CreateInstance(info.Type);
+ d.ApplySerialisedInformation(info);
+ return d;
+ }
+ }
}
diff --git a/osu.Game/Screens/Play/HUDOverlay.cs b/osu.Game/Screens/Play/HUDOverlay.cs
index 13449e3a2b..1a12ca4cbd 100644
--- a/osu.Game/Screens/Play/HUDOverlay.cs
+++ b/osu.Game/Screens/Play/HUDOverlay.cs
@@ -91,16 +91,37 @@ namespace osu.Game.Screens.Play
{
new Drawable[]
{
- new MainHUDElements
+ new Container
{
RelativeSizeAxes = Axes.Both,
Children = new Drawable[]
{
- HealthDisplay = new SkinnableHealthDisplay(),
- AccuracyCounter = new SkinnableAccuracyCounter(),
- ScoreCounter = new SkinnableScoreCounter(),
- new SkinnableComboCounter(),
- new HitErrorDisplay(this.drawableRuleset?.FirstAvailableHitWindows),
+ new SkinnableElementTargetContainer(SkinnableTarget.MainHUDComponents)
+ {
+ RelativeSizeAxes = Axes.Both,
+ },
+ new Container
+ {
+ RelativeSizeAxes = Axes.Both,
+ Alpha = 0,
+ Children = new Drawable[]
+ {
+ // remaining cross-dependencies need tidying.
+ // kept to ensure non-null, but hidden for testing.
+ HealthDisplay = new SkinnableHealthDisplay(),
+ AccuracyCounter = new SkinnableAccuracyCounter(),
+ ScoreCounter = new SkinnableScoreCounter(),
+ }
+ },
+ new Container
+ {
+ RelativeSizeAxes = Axes.Both,
+ Children = new Drawable[]
+ {
+ // still need to be migrated; a bit more involved.
+ new HitErrorDisplay(this.drawableRuleset?.FirstAvailableHitWindows),
+ }
+ },
}
},
},
@@ -337,9 +358,5 @@ namespace osu.Game.Screens.Play
break;
}
}
-
- public class MainHUDElements : SkinnableElementTargetContainer
- {
- }
}
}
diff --git a/osu.Game/Skinning/DefaultSkin.cs b/osu.Game/Skinning/DefaultSkin.cs
index 0b3f5f3cde..48da841c45 100644
--- a/osu.Game/Skinning/DefaultSkin.cs
+++ b/osu.Game/Skinning/DefaultSkin.cs
@@ -2,12 +2,17 @@
// See the LICENCE file in the repository root for full licence text.
using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using Newtonsoft.Json;
using osu.Framework.Audio.Sample;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
+using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.OpenGL.Textures;
using osu.Framework.Graphics.Textures;
using osu.Game.Audio;
+using osu.Game.Screens.Play.HUD;
using osuTK.Graphics;
namespace osu.Game.Skinning
@@ -20,7 +25,29 @@ namespace osu.Game.Skinning
Configuration = new DefaultSkinConfiguration();
}
- public override Drawable GetDrawableComponent(ISkinComponent component) => null;
+ public override Drawable GetDrawableComponent(ISkinComponent component)
+ {
+ switch (component)
+ {
+ case SkinnableTargetComponent target:
+ switch (target.Target)
+ {
+ case SkinnableTarget.MainHUDComponents:
+ var infos = JsonConvert.DeserializeObject>(File.ReadAllText("/Users/Dean/json-out.json")).Where(i => i.Target == SkinnableTarget.MainHUDComponents);
+
+ var container = new SkinnableTargetWrapper(target.Target)
+ {
+ ChildrenEnumerable = infos.Select(i => i.CreateInstance())
+ };
+
+ return container;
+ }
+
+ break;
+ }
+
+ return null;
+ }
public override Texture GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) => null;
@@ -45,4 +72,14 @@ namespace osu.Game.Skinning
return null;
}
}
+
+ public class SkinnableTargetWrapper : Container, ISkinnableTarget
+ {
+ public SkinnableTarget Target { get; }
+
+ public SkinnableTargetWrapper(SkinnableTarget target)
+ {
+ Target = target;
+ }
+ }
}
diff --git a/osu.Game/Skinning/ISkin.cs b/osu.Game/Skinning/ISkin.cs
index 5371893882..73f7cf6d39 100644
--- a/osu.Game/Skinning/ISkin.cs
+++ b/osu.Game/Skinning/ISkin.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-using System;
-using System.Collections.Generic;
using JetBrains.Annotations;
using osu.Framework.Audio.Sample;
using osu.Framework.Bindables;
diff --git a/osu.Game/Skinning/SkinnableTarget.cs b/osu.Game/Skinning/SkinnableTarget.cs
new file mode 100644
index 0000000000..7b1eae126c
--- /dev/null
+++ b/osu.Game/Skinning/SkinnableTarget.cs
@@ -0,0 +1,10 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+namespace osu.Game.Skinning
+{
+ public enum SkinnableTarget
+ {
+ MainHUDComponents
+ }
+}
diff --git a/osu.Game/Skinning/SkinnableTargetComponent.cs b/osu.Game/Skinning/SkinnableTargetComponent.cs
new file mode 100644
index 0000000000..a17aafe6e7
--- /dev/null
+++ b/osu.Game/Skinning/SkinnableTargetComponent.cs
@@ -0,0 +1,17 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+namespace osu.Game.Skinning
+{
+ public class SkinnableTargetComponent : ISkinComponent
+ {
+ public readonly SkinnableTarget Target;
+
+ public string LookupName => Target.ToString();
+
+ public SkinnableTargetComponent(SkinnableTarget target)
+ {
+ Target = target;
+ }
+ }
+}