From b84994e64398dc174d020c7bb2d08d2915823311 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 27 Sep 2018 15:29:22 +0900 Subject: [PATCH 1/9] Make GetTexture return the post-scaled texture --- osu.Game/Skinning/LegacySkin.cs | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index ce7edf8683..58b1117598 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -58,25 +58,29 @@ namespace osu.Game.Skinning break; } - float ratio = 0.72f; // brings sizing roughly in-line with stable - - var texture = GetTexture($"{componentName}@2x"); - if (texture == null) - { - ratio *= 2; - texture = GetTexture(componentName); - } + var texture = GetTexture(componentName); 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); From 0d8276c5f86a811b49d252271d6781f5ab48b708 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 27 Sep 2018 16:27:11 +0900 Subject: [PATCH 2/9] Implement skinnable sprite text --- .../Objects/Drawables/Pieces/NumberPiece.cs | 12 +++-- osu.Game/Skinning/LegacySkin.cs | 44 ++++++++++++++++++- osu.Game/Skinning/SkinnableDrawable.cs | 29 +++++++----- osu.Game/Skinning/SkinnableSpriteText.cs | 40 +++++++++++++++++ 4 files changed, 104 insertions(+), 21 deletions(-) create mode 100644 osu.Game/Skinning/SkinnableSpriteText.cs 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/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index 58b1117598..160cc412b4 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -12,7 +12,7 @@ using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; using osu.Framework.IO.Stores; using osu.Game.Database; -using OpenTK; +using osu.Game.Graphics.Sprites; namespace osu.Game.Skinning { @@ -56,11 +56,15 @@ namespace osu.Game.Skinning case "Play/Great": componentName = "hit300"; break; + case "Play/osu/number-text": + // Todo: Not necessarily default font + return hasFont("default") ? new LegacySpriteText(Textures, "default") : null; } var texture = GetTexture(componentName); - if (texture == null) return null; + if (texture == null) + return null; return new Sprite { Texture = texture }; } @@ -84,6 +88,8 @@ namespace osu.Game.Skinning 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 { @@ -146,5 +152,39 @@ 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}"; + + 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/SkinnableDrawable.cs b/osu.Game/Skinning/SkinnableDrawable.cs index a40c3da82d..9ecd9e647a 100644 --- a/osu.Game/Skinning/SkinnableDrawable.cs +++ b/osu.Game/Skinning/SkinnableDrawable.cs @@ -18,6 +18,8 @@ namespace osu.Game.Skinning public class SkinnableDrawable : SkinReloadableDrawable where T : Drawable { + protected Drawable Drawable { get; private set; } + private readonly Func createDefault; private readonly string componentName; @@ -31,7 +33,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 +45,28 @@ namespace osu.Game.Skinning protected override void SkinChanged(ISkinSource skin, bool allowFallback) { - var drawable = skin.GetDrawableComponent(componentName); - if (drawable != null) + 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; + } + } + } +} From 8191f03503b5ee06bcb1e64345c643a52de9db3a Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 27 Sep 2018 17:27:24 +0900 Subject: [PATCH 3/9] Implement HitCircleFont skin configuration --- osu.Game/Skinning/LegacySkin.cs | 3 +-- osu.Game/Skinning/LegacySkinDecoder.cs | 15 +++++++++++++++ osu.Game/Skinning/SkinConfiguration.cs | 2 ++ 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index 160cc412b4..bb37531c3e 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -57,8 +57,7 @@ namespace osu.Game.Skinning componentName = "hit300"; break; case "Play/osu/number-text": - // Todo: Not necessarily default font - return hasFont("default") ? new LegacySpriteText(Textures, "default") : null; + return hasFont(Configuration.HitCircleFont) ? new LegacySpriteText(Textures, Configuration.HitCircleFont) : null; } var texture = GetTexture(componentName); 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"; } } From 1c242556ca73c5d3044c713d3138242a2bb049ea Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 27 Sep 2018 17:33:27 +0900 Subject: [PATCH 4/9] Add comments + cleanup --- osu.Game/Skinning/LegacySkin.cs | 1 + osu.Game/Skinning/SkinnableDrawable.cs | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index bb37531c3e..67a498730a 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -170,6 +170,7 @@ namespace osu.Game.Skinning { string textureName = $"{font}-{c}"; + // Approximate value that brings character sizing roughly in-line with stable float ratio = 36; var texture = textures.Get($"{textureName}@2x"); diff --git a/osu.Game/Skinning/SkinnableDrawable.cs b/osu.Game/Skinning/SkinnableDrawable.cs index 9ecd9e647a..5195daee65 100644 --- a/osu.Game/Skinning/SkinnableDrawable.cs +++ b/osu.Game/Skinning/SkinnableDrawable.cs @@ -18,6 +18,9 @@ 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; @@ -45,7 +48,6 @@ namespace osu.Game.Skinning protected override void SkinChanged(ISkinSource skin, bool allowFallback) { - Drawable = null; Drawable = skin.GetDrawableComponent(componentName); if (Drawable != null) From 3539874262e7d512206f057b4d0a55d1af023973 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 28 Sep 2018 11:01:53 +0900 Subject: [PATCH 5/9] Add missing scale Makes about a 1px difference. --- osu.Game/Skinning/LegacySkin.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index 67a498730a..bd7ca22fa1 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -13,6 +13,7 @@ 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 { @@ -57,7 +58,7 @@ namespace osu.Game.Skinning componentName = "hit300"; break; case "Play/osu/number-text": - return hasFont(Configuration.HitCircleFont) ? new LegacySpriteText(Textures, Configuration.HitCircleFont) : null; + return !hasFont(Configuration.HitCircleFont) ? null : new LegacySpriteText(Textures, Configuration.HitCircleFont) { Scale = new Vector2(0.96f) }; } var texture = GetTexture(componentName); From f8a8c7cb6bc229170f5715ea4463d1c8542c7d1c Mon Sep 17 00:00:00 2001 From: Kyle Chang Date: Sun, 28 Oct 2018 12:43:19 -0400 Subject: [PATCH 6/9] Stop transferring track when editing --- osu.Game/Screens/Select/SongSelect.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index b4f552ce93..9d7e84aa04 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -225,7 +225,7 @@ namespace osu.Game.Screens.Select public void Edit(BeatmapInfo beatmap) { - Beatmap.Value = beatmaps.GetWorkingBeatmap(beatmap, Beatmap.Value); + Beatmap.Value = beatmaps.GetWorkingBeatmap(beatmap); Push(new Editor()); } From 2b736c3cd64727a720e0b8e23973804facb295ba Mon Sep 17 00:00:00 2001 From: Kyle Chang Date: Sun, 28 Oct 2018 13:04:45 -0400 Subject: [PATCH 7/9] Make beatmap edit button reload beatmap without mods --- osu.Game/Screens/Select/PlaySongSelect.cs | 2 +- osu.Game/Screens/Select/SongSelect.cs | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Select/PlaySongSelect.cs b/osu.Game/Screens/Select/PlaySongSelect.cs index 917a08d172..fdb82f9e7f 100644 --- a/osu.Game/Screens/Select/PlaySongSelect.cs +++ b/osu.Game/Screens/Select/PlaySongSelect.cs @@ -68,7 +68,7 @@ namespace osu.Game.Screens.Select BeatmapOptions.AddButton(@"Edit", @"beatmap", FontAwesome.fa_pencil, colours.Yellow, () => { ValidForResume = false; - Push(new Editor()); + EditSelected(); }, Key.Number3); if (dialogOverlay != null) diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 9d7e84aa04..32e77bb914 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -229,6 +229,8 @@ namespace osu.Game.Screens.Select Push(new Editor()); } + protected void EditSelected() => Edit(beatmapNoDebounce); + /// /// Call to make a selection and perform the default action for this SongSelect. /// From 886dd0f0d46fe2ba4f1192f2d01024a4e95d5560 Mon Sep 17 00:00:00 2001 From: Kyle Chang Date: Sun, 28 Oct 2018 13:21:12 -0400 Subject: [PATCH 8/9] Remove unneeded using directive --- osu.Game/Screens/Select/PlaySongSelect.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Screens/Select/PlaySongSelect.cs b/osu.Game/Screens/Select/PlaySongSelect.cs index fdb82f9e7f..1c4a0c58e9 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; From c7e950af7f86ebaf2693b3f46eb035869fbe504d Mon Sep 17 00:00:00 2001 From: Kyle Chang Date: Mon, 29 Oct 2018 00:04:51 -0400 Subject: [PATCH 9/9] Remove EditSelected in favor in inlining beatmapNoDebounce in Edit --- osu.Game/Screens/Select/PlaySongSelect.cs | 2 +- osu.Game/Screens/Select/SongSelect.cs | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/osu.Game/Screens/Select/PlaySongSelect.cs b/osu.Game/Screens/Select/PlaySongSelect.cs index 1c4a0c58e9..285410ce20 100644 --- a/osu.Game/Screens/Select/PlaySongSelect.cs +++ b/osu.Game/Screens/Select/PlaySongSelect.cs @@ -67,7 +67,7 @@ namespace osu.Game.Screens.Select BeatmapOptions.AddButton(@"Edit", @"beatmap", FontAwesome.fa_pencil, colours.Yellow, () => { ValidForResume = false; - EditSelected(); + Edit(); }, Key.Number3); if (dialogOverlay != null) diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 32e77bb914..4288483caf 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -223,14 +223,12 @@ 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 = beatmaps.GetWorkingBeatmap(beatmap ?? beatmapNoDebounce); Push(new Editor()); } - protected void EditSelected() => Edit(beatmapNoDebounce); - /// /// Call to make a selection and perform the default action for this SongSelect. ///