mirror of
https://github.com/osukey/osukey.git
synced 2025-05-31 10:27:26 +09:00
Refactor skin configuration to be infinitely extensible
This commit is contained in:
parent
976f5020c0
commit
bebc3309ce
@ -14,6 +14,7 @@ using osu.Framework.Graphics.Shapes;
|
|||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osuTK.Graphics;
|
using osuTK.Graphics;
|
||||||
using osu.Framework.Audio.Sample;
|
using osu.Framework.Audio.Sample;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics.Textures;
|
using osu.Framework.Graphics.Textures;
|
||||||
using osu.Game.Audio;
|
using osu.Game.Audio;
|
||||||
|
|
||||||
@ -99,8 +100,7 @@ namespace osu.Game.Rulesets.Catch.Tests
|
|||||||
public Texture GetTexture(string componentName) =>
|
public Texture GetTexture(string componentName) =>
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
|
|
||||||
public TValue GetValue<TConfiguration, TValue>(Func<TConfiguration, TValue> query) where TConfiguration : SkinConfiguration =>
|
public IBindable<TValue> GetConfig<TLookup, TValue>(TLookup lookup) => throw new NotImplementedException();
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ using NUnit.Framework;
|
|||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Audio;
|
using osu.Framework.Audio;
|
||||||
using osu.Framework.Audio.Sample;
|
using osu.Framework.Audio.Sample;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Framework.Graphics.Textures;
|
using osu.Framework.Graphics.Textures;
|
||||||
@ -135,6 +136,7 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
public SampleChannel GetSample(ISampleInfo sampleInfo) => null;
|
public SampleChannel GetSample(ISampleInfo sampleInfo) => null;
|
||||||
|
|
||||||
public TValue GetValue<TConfiguration, TValue>(Func<TConfiguration, TValue> query) where TConfiguration : SkinConfiguration => default;
|
public TValue GetValue<TConfiguration, TValue>(Func<TConfiguration, TValue> query) where TConfiguration : SkinConfiguration => default;
|
||||||
|
public IBindable<TValue> GetConfig<TLookup, TValue>(TLookup lookup) => null;
|
||||||
|
|
||||||
public event Action SourceChanged;
|
public event Action SourceChanged;
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@ using osu.Framework.Bindables;
|
|||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.Osu.Configuration;
|
using osu.Game.Rulesets.Osu.Configuration;
|
||||||
|
using osu.Game.Rulesets.Osu.Skinning;
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
using osuTK.Graphics;
|
using osuTK.Graphics;
|
||||||
using osu.Game.Skinning;
|
using osu.Game.Skinning;
|
||||||
@ -166,12 +167,12 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
{
|
{
|
||||||
base.SkinChanged(skin, allowFallback);
|
base.SkinChanged(skin, allowFallback);
|
||||||
|
|
||||||
Body.BorderSize = skin.GetValue<SkinConfiguration, float?>(s => s.SliderBorderSize) ?? SliderBody.DEFAULT_BORDER_SIZE;
|
Body.BorderSize = skin.GetConfig<OsuSkinConfiguration, float>(OsuSkinConfiguration.SliderBorderSize)?.Value ?? SliderBody.DEFAULT_BORDER_SIZE;
|
||||||
sliderPathRadius = skin.GetValue<SkinConfiguration, float?>(s => s.SliderPathRadius) ?? OsuHitObject.OBJECT_RADIUS;
|
sliderPathRadius = skin.GetConfig<OsuSkinConfiguration, float>(OsuSkinConfiguration.SliderPathRadius)?.Value ?? OsuHitObject.OBJECT_RADIUS;
|
||||||
updatePathRadius();
|
updatePathRadius();
|
||||||
|
|
||||||
Body.AccentColour = skin.GetValue<SkinConfiguration, Color4?>(s => s.CustomColours.ContainsKey("SliderTrackOverride") ? s.CustomColours["SliderTrackOverride"] : (Color4?)null) ?? AccentColour.Value;
|
Body.AccentColour = skin.GetConfig<OsuSkinColour, Color4>(OsuSkinColour.SliderTrackOverride)?.Value ?? AccentColour.Value;
|
||||||
Body.BorderColour = skin.GetValue<SkinConfiguration, Color4?>(s => s.CustomColours.ContainsKey("SliderBorder") ? s.CustomColours["SliderBorder"] : (Color4?)null) ?? Color4.White;
|
Body.BorderColour = skin.GetConfig<OsuSkinColour, Color4>(OsuSkinColour.SliderBorder)?.Value ?? Color4.White;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updatePathRadius() => Body.PathRadius = slider.Scale * sliderPathRadius;
|
private void updatePathRadius() => Body.PathRadius = slider.Scale * sliderPathRadius;
|
||||||
|
@ -11,6 +11,7 @@ using osu.Framework.Input;
|
|||||||
using osu.Framework.Input.Events;
|
using osu.Framework.Input.Events;
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
using osu.Game.Rulesets.Objects.Types;
|
using osu.Game.Rulesets.Objects.Types;
|
||||||
|
using osu.Game.Rulesets.Osu.Skinning;
|
||||||
using osuTK.Graphics;
|
using osuTK.Graphics;
|
||||||
using osu.Game.Skinning;
|
using osu.Game.Skinning;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
@ -218,7 +219,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
|||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both;
|
RelativeSizeAxes = Axes.Both;
|
||||||
|
|
||||||
float radius = skin.GetValue<SkinConfiguration, float?>(s => s.SliderPathRadius) ?? OsuHitObject.OBJECT_RADIUS;
|
float radius = skin.GetConfig<OsuSkinConfiguration, float>(OsuSkinConfiguration.SliderPathRadius)?.Value ?? OsuHitObject.OBJECT_RADIUS;
|
||||||
|
|
||||||
InternalChild = new CircularContainer
|
InternalChild = new CircularContainer
|
||||||
{
|
{
|
||||||
|
@ -167,7 +167,7 @@ namespace osu.Game.Rulesets.Osu
|
|||||||
|
|
||||||
public override RulesetSettingsSubsection CreateSettings() => new OsuSettingsSubsection(this);
|
public override RulesetSettingsSubsection CreateSettings() => new OsuSettingsSubsection(this);
|
||||||
|
|
||||||
public override ISkin CreateLegacySkinProvider(ISkinSource source) => new OsuLegacySkin(source);
|
public override ISkin CreateLegacySkinProvider(ISkinSource source) => new OsuLegacySkinTransformer(source);
|
||||||
|
|
||||||
public override int? LegacyID => 0;
|
public override int? LegacyID => 0;
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ namespace osu.Game.Rulesets.Osu.Skinning
|
|||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(ISkinSource skin, DrawableHitObject drawableObject)
|
private void load(ISkinSource skin, DrawableHitObject drawableObject)
|
||||||
{
|
{
|
||||||
animationContent.Colour = skin.GetValue<SkinConfiguration, Color4?>(s => s.CustomColours.ContainsKey("SliderBall") ? s.CustomColours["SliderBall"] : (Color4?)null) ?? Color4.White;
|
animationContent.Colour = skin.GetConfig<OsuSkinColour, Color4>(OsuSkinColour.SliderBall)?.Value ?? Color4.White;
|
||||||
|
|
||||||
InternalChildren = new[]
|
InternalChildren = new[]
|
||||||
{
|
{
|
||||||
|
@ -3,21 +3,19 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using osu.Framework.Audio.Sample;
|
using osu.Framework.Audio.Sample;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Textures;
|
using osu.Framework.Graphics.Textures;
|
||||||
using osu.Game.Audio;
|
using osu.Game.Audio;
|
||||||
using osu.Game.Skinning;
|
using osu.Game.Skinning;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
using osuTK.Graphics;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Osu.Skinning
|
namespace osu.Game.Rulesets.Osu.Skinning
|
||||||
{
|
{
|
||||||
public class OsuLegacySkin : ISkin
|
public class OsuLegacySkinTransformer : ISkin
|
||||||
{
|
{
|
||||||
private readonly ISkin source;
|
private readonly ISkin source;
|
||||||
|
|
||||||
private Lazy<SkinConfiguration> configuration;
|
|
||||||
|
|
||||||
private Lazy<bool> hasHitCircle;
|
private Lazy<bool> hasHitCircle;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -27,7 +25,7 @@ namespace osu.Game.Rulesets.Osu.Skinning
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private const float legacy_circle_radius = 64 - 5;
|
private const float legacy_circle_radius = 64 - 5;
|
||||||
|
|
||||||
public OsuLegacySkin(ISkinSource source)
|
public OsuLegacySkinTransformer(ISkinSource source)
|
||||||
{
|
{
|
||||||
this.source = source;
|
this.source = source;
|
||||||
|
|
||||||
@ -37,21 +35,6 @@ namespace osu.Game.Rulesets.Osu.Skinning
|
|||||||
|
|
||||||
private void sourceChanged()
|
private void sourceChanged()
|
||||||
{
|
{
|
||||||
// these need to be lazy in order to ensure they aren't called before the dependencies have been loaded into our source.
|
|
||||||
configuration = new Lazy<SkinConfiguration>(() =>
|
|
||||||
{
|
|
||||||
var config = new SkinConfiguration();
|
|
||||||
if (hasHitCircle.Value)
|
|
||||||
config.SliderPathRadius = legacy_circle_radius;
|
|
||||||
|
|
||||||
// defaults should only be applied for non-beatmap skins (which are parsed via this constructor).
|
|
||||||
config.CustomColours["SliderBall"] =
|
|
||||||
source.GetValue<SkinConfiguration, Color4?>(s => s.CustomColours.TryGetValue("SliderBall", out var val) ? val : (Color4?)null)
|
|
||||||
?? new Color4(2, 170, 255, 255);
|
|
||||||
|
|
||||||
return config;
|
|
||||||
});
|
|
||||||
|
|
||||||
hasHitCircle = new Lazy<bool>(() => source.GetTexture("hitcircle") != null);
|
hasHitCircle = new Lazy<bool>(() => source.GetTexture("hitcircle") != null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,8 +79,8 @@ namespace osu.Game.Rulesets.Osu.Skinning
|
|||||||
return null;
|
return null;
|
||||||
|
|
||||||
case OsuSkinComponents.HitCircleText:
|
case OsuSkinComponents.HitCircleText:
|
||||||
string font = GetValue<SkinConfiguration, string>(config => config.HitCircleFont);
|
var font = GetConfig<OsuSkinConfiguration, string>(OsuSkinConfiguration.HitCircleFont)?.Value ?? "default";
|
||||||
var overlap = GetValue<SkinConfiguration, float>(config => config.HitCircleOverlap);
|
var overlap = GetConfig<OsuSkinConfiguration, float>(OsuSkinConfiguration.HitCircleOverlap)?.Value ?? 0;
|
||||||
|
|
||||||
return !hasFont(font)
|
return !hasFont(font)
|
||||||
? null
|
? null
|
||||||
@ -116,13 +99,27 @@ namespace osu.Game.Rulesets.Osu.Skinning
|
|||||||
|
|
||||||
public SampleChannel GetSample(ISampleInfo sample) => source.GetSample(sample);
|
public SampleChannel GetSample(ISampleInfo sample) => source.GetSample(sample);
|
||||||
|
|
||||||
public TValue GetValue<TConfiguration, TValue>(Func<TConfiguration, TValue> query) where TConfiguration : SkinConfiguration
|
public IBindable<TValue> GetConfig<TLookup, TValue>(TLookup lookup)
|
||||||
{
|
{
|
||||||
TValue val;
|
switch (lookup)
|
||||||
if (configuration.Value is TConfiguration conf && (val = query.Invoke(conf)) != null)
|
{
|
||||||
return val;
|
case OsuSkinColour colour:
|
||||||
|
return source.GetConfig<SkinCustomColourLookup, TValue>(new SkinCustomColourLookup(colour));
|
||||||
|
|
||||||
return source.GetValue(query);
|
case OsuSkinConfiguration osuLookup:
|
||||||
|
switch (osuLookup)
|
||||||
|
{
|
||||||
|
case OsuSkinConfiguration.SliderPathRadius:
|
||||||
|
if (hasHitCircle.Value)
|
||||||
|
return new BindableFloat(legacy_circle_radius) as Bindable<TValue>;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return source.GetConfig<TLookup, TValue>(lookup);
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool hasFont(string fontName) => source.GetTexture($"{fontName}-0") != null;
|
private bool hasFont(string fontName) => source.GetTexture($"{fontName}-0") != null;
|
12
osu.Game.Rulesets.Osu/Skinning/OsuSkinColour.cs
Normal file
12
osu.Game.Rulesets.Osu/Skinning/OsuSkinColour.cs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Osu.Skinning
|
||||||
|
{
|
||||||
|
public enum OsuSkinColour
|
||||||
|
{
|
||||||
|
SliderTrackOverride,
|
||||||
|
SliderBorder,
|
||||||
|
SliderBall
|
||||||
|
}
|
||||||
|
}
|
14
osu.Game.Rulesets.Osu/Skinning/OsuSkinConfiguration.cs
Normal file
14
osu.Game.Rulesets.Osu/Skinning/OsuSkinConfiguration.cs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Osu.Skinning
|
||||||
|
{
|
||||||
|
public enum OsuSkinConfiguration
|
||||||
|
{
|
||||||
|
HitCircleFont,
|
||||||
|
HitCircleOverlap,
|
||||||
|
SliderBorderSize,
|
||||||
|
SliderPathRadius,
|
||||||
|
CursorExpand,
|
||||||
|
}
|
||||||
|
}
|
@ -10,6 +10,7 @@ using osu.Framework.Graphics.Effects;
|
|||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
|
using osu.Game.Rulesets.Osu.Skinning;
|
||||||
using osu.Game.Skinning;
|
using osu.Game.Skinning;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
using osuTK.Graphics;
|
using osuTK.Graphics;
|
||||||
@ -38,7 +39,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
|
|||||||
|
|
||||||
protected override void SkinChanged(ISkinSource skin, bool allowFallback)
|
protected override void SkinChanged(ISkinSource skin, bool allowFallback)
|
||||||
{
|
{
|
||||||
cursorExpand = skin.GetValue<SkinConfiguration, bool>(s => s.CursorExpand ?? true);
|
cursorExpand = skin.GetConfig<OsuSkinConfiguration, bool>(OsuSkinConfiguration.CursorExpand)?.Value ?? true;
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
|
@ -6,6 +6,7 @@ using System.Globalization;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Audio.Sample;
|
using osu.Framework.Audio.Sample;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
@ -137,7 +138,8 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
{
|
{
|
||||||
public new Drawable Drawable => base.Drawable;
|
public new Drawable Drawable => base.Drawable;
|
||||||
|
|
||||||
public ExposedSkinnableDrawable(string name, Func<ISkinComponent, Drawable> defaultImplementation, Func<ISkinSource, bool> allowFallback = null, ConfineMode confineMode = ConfineMode.ScaleDownToFit)
|
public ExposedSkinnableDrawable(string name, Func<ISkinComponent, Drawable> defaultImplementation, Func<ISkinSource, bool> allowFallback = null,
|
||||||
|
ConfineMode confineMode = ConfineMode.ScaleDownToFit)
|
||||||
: base(new TestSkinComponent(name), defaultImplementation, allowFallback, confineMode)
|
: base(new TestSkinComponent(name), defaultImplementation, allowFallback, confineMode)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -256,7 +258,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
|
|
||||||
public SampleChannel GetSample(ISampleInfo sampleInfo) => throw new NotImplementedException();
|
public SampleChannel GetSample(ISampleInfo sampleInfo) => throw new NotImplementedException();
|
||||||
|
|
||||||
public TValue GetValue<TConfiguration, TValue>(Func<TConfiguration, TValue> query) where TConfiguration : SkinConfiguration => throw new NotImplementedException();
|
public IBindable<TValue> GetConfig<TLookup, TValue>(TLookup lookup) => throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
private class SecondarySource : ISkin
|
private class SecondarySource : ISkin
|
||||||
@ -267,7 +269,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
|
|
||||||
public SampleChannel GetSample(ISampleInfo sampleInfo) => throw new NotImplementedException();
|
public SampleChannel GetSample(ISampleInfo sampleInfo) => throw new NotImplementedException();
|
||||||
|
|
||||||
public TValue GetValue<TConfiguration, TValue>(Func<TConfiguration, TValue> query) where TConfiguration : SkinConfiguration => throw new NotImplementedException();
|
public IBindable<TValue> GetConfig<TLookup, TValue>(TLookup lookup) => throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
private class SkinSourceContainer : Container, ISkin
|
private class SkinSourceContainer : Container, ISkin
|
||||||
@ -278,7 +280,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
|
|
||||||
public SampleChannel GetSample(ISampleInfo sampleInfo) => throw new NotImplementedException();
|
public SampleChannel GetSample(ISampleInfo sampleInfo) => throw new NotImplementedException();
|
||||||
|
|
||||||
public TValue GetValue<TConfiguration, TValue>(Func<TConfiguration, TValue> query) where TConfiguration : SkinConfiguration => throw new NotImplementedException();
|
public IBindable<TValue> GetConfig<TLookup, TValue>(TLookup lookup) => throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
private class TestSkinComponent : ISkinComponent
|
private class TestSkinComponent : ISkinComponent
|
||||||
|
@ -241,7 +241,11 @@ namespace osu.Game.Rulesets.Objects.Drawables
|
|||||||
base.SkinChanged(skin, allowFallback);
|
base.SkinChanged(skin, allowFallback);
|
||||||
|
|
||||||
if (HitObject is IHasComboInformation combo)
|
if (HitObject is IHasComboInformation combo)
|
||||||
AccentColour.Value = skin.GetValue<SkinConfiguration, Color4?>(s => s.ComboColours.Count > 0 ? s.ComboColours[combo.ComboIndex % s.ComboColours.Count] : (Color4?)null) ?? Color4.White;
|
{
|
||||||
|
var comboColours = skin.GetConfig<GlobalSkinConfiguration, List<Color4>>(GlobalSkinConfiguration.ComboColours)?.Value;
|
||||||
|
|
||||||
|
AccentColour.Value = comboColours?.Count > 0 ? comboColours[combo.ComboIndex % comboColours.Count] : Color4.White;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -122,7 +122,7 @@ namespace osu.Game.Screens.Menu
|
|||||||
Color4 defaultColour = Color4.White.Opacity(0.2f);
|
Color4 defaultColour = Color4.White.Opacity(0.2f);
|
||||||
|
|
||||||
if (user.Value?.IsSupporter ?? false)
|
if (user.Value?.IsSupporter ?? false)
|
||||||
AccentColour = skin.Value.GetValue<SkinConfiguration, Color4?>(s => s.CustomColours.ContainsKey("MenuGlow") ? s.CustomColours["MenuGlow"] : (Color4?)null) ?? defaultColour;
|
AccentColour = skin.Value.GetConfig<GlobalSkinColour, Color4>(GlobalSkinColour.MenuGlow)?.Value ?? defaultColour;
|
||||||
else
|
else
|
||||||
AccentColour = defaultColour;
|
AccentColour = defaultColour;
|
||||||
}
|
}
|
||||||
|
@ -112,7 +112,7 @@ namespace osu.Game.Screens.Menu
|
|||||||
Color4 baseColour = colours.Blue;
|
Color4 baseColour = colours.Blue;
|
||||||
|
|
||||||
if (user.Value?.IsSupporter ?? false)
|
if (user.Value?.IsSupporter ?? false)
|
||||||
baseColour = skin.Value.GetValue<SkinConfiguration, Color4?>(s => s.CustomColours.ContainsKey("MenuGlow") ? s.CustomColours["MenuGlow"] : (Color4?)null) ?? baseColour;
|
baseColour = skin.Value.GetConfig<GlobalSkinColour, Color4>(GlobalSkinColour.MenuGlow)?.Value ?? baseColour;
|
||||||
|
|
||||||
// linear colour looks better in this case, so let's use it for now.
|
// linear colour looks better in this case, so let's use it for now.
|
||||||
Color4 gradientDark = baseColour.Opacity(0).ToLinear();
|
Color4 gradientDark = baseColour.Opacity(0).ToLinear();
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using osu.Framework.Audio.Sample;
|
using osu.Framework.Audio.Sample;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Textures;
|
using osu.Framework.Graphics.Textures;
|
||||||
using osu.Game.Audio;
|
using osu.Game.Audio;
|
||||||
@ -21,5 +22,7 @@ namespace osu.Game.Skinning
|
|||||||
public override Texture GetTexture(string componentName) => null;
|
public override Texture GetTexture(string componentName) => null;
|
||||||
|
|
||||||
public override SampleChannel GetSample(ISampleInfo sampleInfo) => null;
|
public override SampleChannel GetSample(ISampleInfo sampleInfo) => null;
|
||||||
|
|
||||||
|
public override IBindable<TValue> GetConfig<TLookup, TValue>(TLookup lookup) => null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,8 +12,6 @@ namespace osu.Game.Skinning
|
|||||||
{
|
{
|
||||||
public DefaultSkinConfiguration()
|
public DefaultSkinConfiguration()
|
||||||
{
|
{
|
||||||
HitCircleFont = "default";
|
|
||||||
|
|
||||||
ComboColours.AddRange(new[]
|
ComboColours.AddRange(new[]
|
||||||
{
|
{
|
||||||
new Color4(17, 136, 170, 255),
|
new Color4(17, 136, 170, 255),
|
||||||
@ -21,8 +19,6 @@ namespace osu.Game.Skinning
|
|||||||
new Color4(204, 102, 0, 255),
|
new Color4(204, 102, 0, 255),
|
||||||
new Color4(121, 9, 13, 255)
|
new Color4(121, 9, 13, 255)
|
||||||
});
|
});
|
||||||
|
|
||||||
CursorExpand = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ using System.Linq;
|
|||||||
|
|
||||||
namespace osu.Game.Skinning
|
namespace osu.Game.Skinning
|
||||||
{
|
{
|
||||||
public class GameplaySkinComponent<T> : ISkinComponent where T : struct
|
public class GameplaySkinComponent<T> : ISkinComponent
|
||||||
{
|
{
|
||||||
public readonly T Component;
|
public readonly T Component;
|
||||||
|
|
||||||
|
10
osu.Game/Skinning/GlobalSkinColour.cs
Normal file
10
osu.Game/Skinning/GlobalSkinColour.cs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
namespace osu.Game.Skinning
|
||||||
|
{
|
||||||
|
public enum GlobalSkinColour
|
||||||
|
{
|
||||||
|
MenuGlow
|
||||||
|
}
|
||||||
|
}
|
10
osu.Game/Skinning/GlobalSkinConfiguration.cs
Normal file
10
osu.Game/Skinning/GlobalSkinConfiguration.cs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
namespace osu.Game.Skinning
|
||||||
|
{
|
||||||
|
public enum GlobalSkinConfiguration
|
||||||
|
{
|
||||||
|
ComboColours
|
||||||
|
}
|
||||||
|
}
|
@ -1,8 +1,8 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
|
||||||
using osu.Framework.Audio.Sample;
|
using osu.Framework.Audio.Sample;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Textures;
|
using osu.Framework.Graphics.Textures;
|
||||||
using osu.Game.Audio;
|
using osu.Game.Audio;
|
||||||
@ -20,6 +20,6 @@ namespace osu.Game.Skinning
|
|||||||
|
|
||||||
SampleChannel GetSample(ISampleInfo sampleInfo);
|
SampleChannel GetSample(ISampleInfo sampleInfo);
|
||||||
|
|
||||||
TValue GetValue<TConfiguration, TValue>(Func<TConfiguration, TValue> query) where TConfiguration : SkinConfiguration;
|
IBindable<TValue> GetConfig<TLookup, TValue>(TLookup lookup);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Framework.Audio;
|
using osu.Framework.Audio;
|
||||||
using osu.Framework.Audio.Sample;
|
using osu.Framework.Audio.Sample;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Textures;
|
using osu.Framework.Graphics.Textures;
|
||||||
using osu.Framework.IO.Stores;
|
using osu.Framework.IO.Stores;
|
||||||
@ -48,6 +50,47 @@ namespace osu.Game.Skinning
|
|||||||
Samples?.Dispose();
|
Samples?.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override IBindable<TValue> GetConfig<TLookup, TValue>(TLookup lookup)
|
||||||
|
{
|
||||||
|
switch (lookup)
|
||||||
|
{
|
||||||
|
case GlobalSkinConfiguration global:
|
||||||
|
switch (global)
|
||||||
|
{
|
||||||
|
case GlobalSkinConfiguration.ComboColours:
|
||||||
|
return new Bindable<List<Color4>>(Configuration.ComboColours) as IBindable<TValue>;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GlobalSkinColour colour:
|
||||||
|
return getCustomColour(colour.ToString()) as IBindable<TValue>;
|
||||||
|
|
||||||
|
case SkinCustomColourLookup customColour:
|
||||||
|
return getCustomColour(customColour.Lookup.ToString()) as IBindable<TValue>;
|
||||||
|
|
||||||
|
default:
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (Configuration.ConfigDictionary.TryGetValue(lookup.ToString(), out var val))
|
||||||
|
{
|
||||||
|
var bindable = new Bindable<TValue>();
|
||||||
|
bindable.Parse(val);
|
||||||
|
return bindable;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private IBindable<Color4> getCustomColour(string lookup) => Configuration.CustomColours.TryGetValue(lookup, out var col) ? new Bindable<Color4>(col) : null;
|
||||||
|
|
||||||
public override Drawable GetDrawableComponent(ISkinComponent component)
|
public override Drawable GetDrawableComponent(ISkinComponent component)
|
||||||
{
|
{
|
||||||
switch (component)
|
switch (component)
|
||||||
|
@ -14,47 +14,31 @@ namespace osu.Game.Skinning
|
|||||||
|
|
||||||
protected override void ParseLine(DefaultSkinConfiguration skin, Section section, string line)
|
protected override void ParseLine(DefaultSkinConfiguration skin, Section section, string line)
|
||||||
{
|
{
|
||||||
line = StripComments(line);
|
if (section != Section.Colours)
|
||||||
|
|
||||||
var pair = SplitKeyVal(line);
|
|
||||||
|
|
||||||
switch (section)
|
|
||||||
{
|
{
|
||||||
case Section.General:
|
line = StripComments(line);
|
||||||
switch (pair.Key)
|
|
||||||
{
|
|
||||||
case @"Name":
|
|
||||||
skin.SkinInfo.Name = pair.Value;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case @"Author":
|
var pair = SplitKeyVal(line);
|
||||||
skin.SkinInfo.Creator = pair.Value;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case @"CursorExpand":
|
switch (section)
|
||||||
skin.CursorExpand = pair.Value != "0";
|
{
|
||||||
break;
|
case Section.General:
|
||||||
|
switch (pair.Key)
|
||||||
|
{
|
||||||
|
case @"Name":
|
||||||
|
skin.SkinInfo.Name = pair.Value;
|
||||||
|
return;
|
||||||
|
|
||||||
case @"SliderBorderSize":
|
case @"Author":
|
||||||
skin.SliderBorderSize = Parsing.ParseFloat(pair.Value);
|
skin.SkinInfo.Creator = pair.Value;
|
||||||
break;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case Section.Fonts:
|
if (!string.IsNullOrEmpty(pair.Key))
|
||||||
switch (pair.Key)
|
skin.ConfigDictionary[$"{section}/{pair.Key}"] = pair.Value;
|
||||||
{
|
|
||||||
case "HitCirclePrefix":
|
|
||||||
skin.HitCircleFont = pair.Value;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "HitCircleOverlap":
|
|
||||||
skin.HitCircleOverlap = int.Parse(pair.Value);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
base.ParseLine(skin, section, line);
|
base.ParseLine(skin, section, line);
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using osu.Framework.Audio.Sample;
|
using osu.Framework.Audio.Sample;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Textures;
|
using osu.Framework.Graphics.Textures;
|
||||||
using osu.Game.Audio;
|
using osu.Game.Audio;
|
||||||
@ -13,7 +14,7 @@ namespace osu.Game.Skinning
|
|||||||
{
|
{
|
||||||
public readonly SkinInfo SkinInfo;
|
public readonly SkinInfo SkinInfo;
|
||||||
|
|
||||||
public virtual SkinConfiguration Configuration { get; protected set; }
|
public SkinConfiguration Configuration { get; protected set; }
|
||||||
|
|
||||||
public abstract Drawable GetDrawableComponent(ISkinComponent componentName);
|
public abstract Drawable GetDrawableComponent(ISkinComponent componentName);
|
||||||
|
|
||||||
@ -21,8 +22,7 @@ namespace osu.Game.Skinning
|
|||||||
|
|
||||||
public abstract Texture GetTexture(string componentName);
|
public abstract Texture GetTexture(string componentName);
|
||||||
|
|
||||||
public TValue GetValue<TConfiguration, TValue>(Func<TConfiguration, TValue> query) where TConfiguration : SkinConfiguration
|
public abstract IBindable<TValue> GetConfig<TLookup, TValue>(TLookup lookup);
|
||||||
=> Configuration is TConfiguration conf ? query.Invoke(conf) : default;
|
|
||||||
|
|
||||||
protected Skin(SkinInfo skin)
|
protected Skin(SkinInfo skin)
|
||||||
{
|
{
|
||||||
|
16
osu.Game/Skinning/SkinConfigManager.cs
Normal file
16
osu.Game/Skinning/SkinConfigManager.cs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
using osu.Framework.Configuration;
|
||||||
|
|
||||||
|
namespace osu.Game.Skinning
|
||||||
|
{
|
||||||
|
public class SkinConfigManager<T> : ConfigManager<T> where T : struct
|
||||||
|
{
|
||||||
|
protected override void PerformLoad()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool PerformSave() => false;
|
||||||
|
}
|
||||||
|
}
|
@ -18,14 +18,6 @@ namespace osu.Game.Skinning
|
|||||||
|
|
||||||
public Dictionary<string, Color4> CustomColours { get; set; } = new Dictionary<string, Color4>();
|
public Dictionary<string, Color4> CustomColours { get; set; } = new Dictionary<string, Color4>();
|
||||||
|
|
||||||
public string HitCircleFont { get; set; }
|
public readonly Dictionary<string, string> ConfigDictionary = new Dictionary<string, string>();
|
||||||
|
|
||||||
public int HitCircleOverlap { get; set; }
|
|
||||||
|
|
||||||
public float? SliderBorderSize { get; set; }
|
|
||||||
|
|
||||||
public float? SliderPathRadius { get; set; }
|
|
||||||
|
|
||||||
public bool? CursorExpand { get; set; }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
15
osu.Game/Skinning/SkinCustomColourLookup.cs
Normal file
15
osu.Game/Skinning/SkinCustomColourLookup.cs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
namespace osu.Game.Skinning
|
||||||
|
{
|
||||||
|
public class SkinCustomColourLookup
|
||||||
|
{
|
||||||
|
public readonly object Lookup;
|
||||||
|
|
||||||
|
public SkinCustomColourLookup(object lookup)
|
||||||
|
{
|
||||||
|
Lookup = lookup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
@ -131,6 +131,6 @@ namespace osu.Game.Skinning
|
|||||||
|
|
||||||
public SampleChannel GetSample(ISampleInfo sampleInfo) => CurrentSkin.Value.GetSample(sampleInfo);
|
public SampleChannel GetSample(ISampleInfo sampleInfo) => CurrentSkin.Value.GetSample(sampleInfo);
|
||||||
|
|
||||||
public TValue GetValue<TConfiguration, TValue>(Func<TConfiguration, TValue> query) where TConfiguration : SkinConfiguration => CurrentSkin.Value.GetValue(query);
|
public IBindable<TValue> GetConfig<TLookup, TValue>(TLookup lookup) => CurrentSkin.Value.GetConfig<TLookup, TValue>(lookup);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Audio.Sample;
|
using osu.Framework.Audio.Sample;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Textures;
|
using osu.Framework.Graphics.Textures;
|
||||||
@ -64,13 +65,16 @@ namespace osu.Game.Skinning
|
|||||||
return fallbackSource?.GetSample(sampleInfo);
|
return fallbackSource?.GetSample(sampleInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TValue GetValue<TConfiguration, TValue>(Func<TConfiguration, TValue> query) where TConfiguration : SkinConfiguration
|
public IBindable<TValue> GetConfig<TLookup, TValue>(TLookup lookup)
|
||||||
{
|
{
|
||||||
TValue val;
|
if (AllowConfigurationLookup && skin != null)
|
||||||
if (AllowConfigurationLookup && skin != null && (val = skin.GetValue(query)) != null)
|
{
|
||||||
return val;
|
var bindable = skin.GetConfig<TLookup, TValue>(lookup);
|
||||||
|
if (bindable != null)
|
||||||
|
return bindable;
|
||||||
|
}
|
||||||
|
|
||||||
return fallbackSource == null ? default : fallbackSource.GetValue(query);
|
return fallbackSource?.GetConfig<TLookup, TValue>(lookup);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void TriggerSourceChanged() => SourceChanged?.Invoke();
|
protected virtual void TriggerSourceChanged() => SourceChanged?.Invoke();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user