diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/NumberPiece.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/NumberPiece.cs index 30140484de..acb3ee92ff 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/NumberPiece.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/NumberPiece.cs @@ -4,7 +4,6 @@ using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Sprites; using osu.Game.Graphics.Sprites; using OpenTK.Graphics; using osu.Framework.Graphics.Shapes; @@ -14,7 +13,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces { public class NumberPiece : Container { - private readonly SpriteText number; + private readonly SkinnableSpriteText number; public string Text { @@ -41,15 +40,14 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces }, Child = new Box() }, s => s.GetTexture("Play/osu/hitcircle") == null), - number = new OsuSpriteText + number = new SkinnableSpriteText("Play/osu/number-text", _ => new OsuSpriteText { - Text = @"1", Font = @"Venera", UseFullGlyphHeight = false, - Anchor = Anchor.Centre, - Origin = Anchor.Centre, TextSize = 40, - Alpha = 1 + }, restrictSize: false) + { + Text = @"1" } }; } diff --git a/osu.Game/Screens/Select/PlaySongSelect.cs b/osu.Game/Screens/Select/PlaySongSelect.cs index 917a08d172..285410ce20 100644 --- a/osu.Game/Screens/Select/PlaySongSelect.cs +++ b/osu.Game/Screens/Select/PlaySongSelect.cs @@ -16,7 +16,6 @@ using osu.Game.Graphics; using osu.Game.Overlays; using osu.Game.Overlays.Mods; using osu.Game.Rulesets.Mods; -using osu.Game.Screens.Edit; using osu.Game.Screens.Play; using osu.Game.Screens.Ranking; using osu.Game.Skinning; @@ -68,7 +67,7 @@ namespace osu.Game.Screens.Select BeatmapOptions.AddButton(@"Edit", @"beatmap", FontAwesome.fa_pencil, colours.Yellow, () => { ValidForResume = false; - Push(new Editor()); + Edit(); }, Key.Number3); if (dialogOverlay != null) diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index b4f552ce93..4288483caf 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -223,9 +223,9 @@ namespace osu.Game.Screens.Select Carousel.LoadBeatmapSetsFromManager(this.beatmaps); } - public void Edit(BeatmapInfo beatmap) + public void Edit(BeatmapInfo beatmap = null) { - Beatmap.Value = beatmaps.GetWorkingBeatmap(beatmap, Beatmap.Value); + Beatmap.Value = beatmaps.GetWorkingBeatmap(beatmap ?? beatmapNoDebounce); Push(new Editor()); } diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index ce7edf8683..bd7ca22fa1 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -12,6 +12,7 @@ using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; using osu.Framework.IO.Stores; using osu.Game.Database; +using osu.Game.Graphics.Sprites; using OpenTK; namespace osu.Game.Skinning @@ -56,30 +57,39 @@ namespace osu.Game.Skinning case "Play/Great": componentName = "hit300"; break; + case "Play/osu/number-text": + return !hasFont(Configuration.HitCircleFont) ? null : new LegacySpriteText(Textures, Configuration.HitCircleFont) { Scale = new Vector2(0.96f) }; } - float ratio = 0.72f; // brings sizing roughly in-line with stable + var texture = GetTexture(componentName); - var texture = GetTexture($"{componentName}@2x"); if (texture == null) - { - ratio *= 2; - texture = GetTexture(componentName); - } + return null; - if (texture == null) return null; - - return new Sprite - { - Texture = texture, - Scale = new Vector2(ratio), - }; + return new Sprite { Texture = texture }; } - public override Texture GetTexture(string componentName) => Textures.Get(componentName); + public override Texture GetTexture(string componentName) + { + float ratio = 2; + + var texture = Textures.Get($"{componentName}@2x"); + if (texture == null) + { + ratio = 1; + texture = Textures.Get(componentName); + } + + if (texture != null) + texture.ScaleAdjust = ratio / 0.72f; // brings sizing roughly in-line with stable + + return texture; + } public override SampleChannel GetSample(string sampleName) => Samples.Get(sampleName); + private bool hasFont(string fontName) => GetTexture($"{fontName}-0") != null; + protected class LegacySkinResourceStore : IResourceStore where T : INamedFileInfo { @@ -142,5 +152,40 @@ namespace osu.Game.Skinning #endregion } + + private class LegacySpriteText : OsuSpriteText + { + private readonly TextureStore textures; + private readonly string font; + + public LegacySpriteText(TextureStore textures, string font) + { + this.textures = textures; + this.font = font; + + Shadow = false; + UseFullGlyphHeight = false; + } + + protected override Texture GetTextureForCharacter(char c) + { + string textureName = $"{font}-{c}"; + + // Approximate value that brings character sizing roughly in-line with stable + float ratio = 36; + + var texture = textures.Get($"{textureName}@2x"); + if (texture == null) + { + ratio = 18; + texture = textures.Get(textureName); + } + + if (texture != null) + texture.ScaleAdjust = ratio; + + return texture; + } + } } } diff --git a/osu.Game/Skinning/LegacySkinDecoder.cs b/osu.Game/Skinning/LegacySkinDecoder.cs index d4f1c5c6f1..67a031fb50 100644 --- a/osu.Game/Skinning/LegacySkinDecoder.cs +++ b/osu.Game/Skinning/LegacySkinDecoder.cs @@ -19,6 +19,7 @@ namespace osu.Game.Skinning switch (section) { case Section.General: + { var pair = SplitKeyVal(line); switch (pair.Key) @@ -32,6 +33,20 @@ namespace osu.Game.Skinning } break; + } + case Section.Fonts: + { + var pair = SplitKeyVal(line); + + switch (pair.Key) + { + case "HitCirclePrefix": + skin.HitCircleFont = pair.Value; + break; + } + + break; + } } base.ParseLine(skin, section, line); diff --git a/osu.Game/Skinning/SkinConfiguration.cs b/osu.Game/Skinning/SkinConfiguration.cs index ac59fcc7db..40f5c158cc 100644 --- a/osu.Game/Skinning/SkinConfiguration.cs +++ b/osu.Game/Skinning/SkinConfiguration.cs @@ -14,5 +14,7 @@ namespace osu.Game.Skinning public List ComboColours { get; set; } = new List(); public Dictionary CustomColours { get; set; } = new Dictionary(); + + public string HitCircleFont { get; set; } = "default"; } } diff --git a/osu.Game/Skinning/SkinnableDrawable.cs b/osu.Game/Skinning/SkinnableDrawable.cs index a40c3da82d..5195daee65 100644 --- a/osu.Game/Skinning/SkinnableDrawable.cs +++ b/osu.Game/Skinning/SkinnableDrawable.cs @@ -18,6 +18,11 @@ namespace osu.Game.Skinning public class SkinnableDrawable : SkinReloadableDrawable where T : Drawable { + /// + /// The displayed component. May or may not be a type- member. + /// + protected Drawable Drawable { get; private set; } + private readonly Func createDefault; private readonly string componentName; @@ -31,7 +36,8 @@ namespace osu.Game.Skinning /// A function to create the default skin implementation of this element. /// A conditional to decide whether to allow fallback to the default implementation if a skinned element is not present. /// Whether a user-skin drawable should be limited to the size of our parent. - public SkinnableDrawable(string name, Func defaultImplementation, Func allowFallback = null, bool restrictSize = true) : base(allowFallback) + public SkinnableDrawable(string name, Func defaultImplementation, Func allowFallback = null, bool restrictSize = true) + : base(allowFallback) { componentName = name; createDefault = defaultImplementation; @@ -42,26 +48,27 @@ namespace osu.Game.Skinning protected override void SkinChanged(ISkinSource skin, bool allowFallback) { - var drawable = skin.GetDrawableComponent(componentName); - if (drawable != null) + Drawable = skin.GetDrawableComponent(componentName); + + if (Drawable != null) { if (restrictSize) { - drawable.RelativeSizeAxes = Axes.Both; - drawable.Size = Vector2.One; - drawable.Scale = Vector2.One; - drawable.FillMode = FillMode.Fit; + Drawable.RelativeSizeAxes = Axes.Both; + Drawable.Size = Vector2.One; + Drawable.Scale = Vector2.One; + Drawable.FillMode = FillMode.Fit; } } else if (allowFallback) - drawable = createDefault(componentName); + Drawable = createDefault(componentName); - if (drawable != null) + if (Drawable != null) { - drawable.Origin = Anchor.Centre; - drawable.Anchor = Anchor.Centre; + Drawable.Origin = Anchor.Centre; + Drawable.Anchor = Anchor.Centre; - InternalChild = drawable; + InternalChild = Drawable; } else ClearInternal(); diff --git a/osu.Game/Skinning/SkinnableSpriteText.cs b/osu.Game/Skinning/SkinnableSpriteText.cs new file mode 100644 index 0000000000..8b09417bed --- /dev/null +++ b/osu.Game/Skinning/SkinnableSpriteText.cs @@ -0,0 +1,40 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using osu.Framework.Graphics.Sprites; + +namespace osu.Game.Skinning +{ + public class SkinnableSpriteText : SkinnableDrawable, IHasText + { + public SkinnableSpriteText(string name, Func defaultImplementation, Func allowFallback = null, bool restrictSize = true) + : base(name, defaultImplementation, allowFallback, restrictSize) + { + } + + protected override void SkinChanged(ISkinSource skin, bool allowFallback) + { + base.SkinChanged(skin, allowFallback); + + if (Drawable is IHasText textDrawable) + textDrawable.Text = Text; + } + + private string text; + + public string Text + { + get => text; + set + { + if (text == value) + return; + text = value; + + if (Drawable is IHasText textDrawable) + textDrawable.Text = value; + } + } + } +}