From 115c186cb7a624065620391a83be90c502827bb2 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sun, 7 Mar 2021 02:16:10 +0300 Subject: [PATCH 01/30] Move hit circle font from osu! ruleset --- osu.Game.Rulesets.Osu/Skinning/OsuSkinConfiguration.cs | 2 -- osu.Game/Skinning/LegacySkinConfiguration.cs | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Skinning/OsuSkinConfiguration.cs b/osu.Game.Rulesets.Osu/Skinning/OsuSkinConfiguration.cs index 63c9b53278..75a62a6f8e 100644 --- a/osu.Game.Rulesets.Osu/Skinning/OsuSkinConfiguration.cs +++ b/osu.Game.Rulesets.Osu/Skinning/OsuSkinConfiguration.cs @@ -5,8 +5,6 @@ namespace osu.Game.Rulesets.Osu.Skinning { public enum OsuSkinConfiguration { - HitCirclePrefix, - HitCircleOverlap, SliderBorderSize, SliderPathRadius, AllowSliderBallTint, diff --git a/osu.Game/Skinning/LegacySkinConfiguration.cs b/osu.Game/Skinning/LegacySkinConfiguration.cs index 84a834ec22..20d1da8aaa 100644 --- a/osu.Game/Skinning/LegacySkinConfiguration.cs +++ b/osu.Game/Skinning/LegacySkinConfiguration.cs @@ -19,6 +19,8 @@ namespace osu.Game.Skinning ComboOverlap, ScorePrefix, ScoreOverlap, + HitCirclePrefix, + HitCircleOverlap, AnimationFramerate, LayeredHitSounds } From 91741564e8e06926a36b49f1c15dba97a03564da Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sun, 7 Mar 2021 02:15:23 +0300 Subject: [PATCH 02/30] Add legacy font enum and extensions --- osu.Game/Skinning/LegacyFont.cs | 15 +++++++ osu.Game/Skinning/LegacySkinExtensions.cs | 48 ++++++++++++++++++++++- 2 files changed, 61 insertions(+), 2 deletions(-) create mode 100644 osu.Game/Skinning/LegacyFont.cs diff --git a/osu.Game/Skinning/LegacyFont.cs b/osu.Game/Skinning/LegacyFont.cs new file mode 100644 index 0000000000..d1971cb84c --- /dev/null +++ b/osu.Game/Skinning/LegacyFont.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. + +namespace osu.Game.Skinning +{ + /// + /// The type of legacy font to use for s. + /// + public enum LegacyFont + { + Score, + Combo, + HitCircle, + } +} diff --git a/osu.Game/Skinning/LegacySkinExtensions.cs b/osu.Game/Skinning/LegacySkinExtensions.cs index a7c084998d..d08f50bccb 100644 --- a/osu.Game/Skinning/LegacySkinExtensions.cs +++ b/osu.Game/Skinning/LegacySkinExtensions.cs @@ -1,6 +1,7 @@ // 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 System.Linq; using osu.Framework.Allocation; @@ -63,8 +64,51 @@ namespace osu.Game.Skinning } } - public static bool HasFont(this ISkin source, string fontPrefix) - => source.GetTexture($"{fontPrefix}-0") != null; + public static bool HasFont(this ISkin source, LegacyFont font) + { + return source.GetTexture($"{source.GetFontPrefix(font)}-0") != null; + } + + public static string GetFontPrefix(this ISkin source, LegacyFont font) + { + switch (font) + { + case LegacyFont.Score: + return source.GetConfig(LegacySetting.ScorePrefix)?.Value ?? "score"; + + case LegacyFont.Combo: + return source.GetConfig(LegacySetting.ComboPrefix)?.Value ?? "score"; + + case LegacyFont.HitCircle: + return source.GetConfig(LegacySetting.HitCirclePrefix)?.Value ?? "default"; + + default: + throw new ArgumentOutOfRangeException(nameof(font)); + } + } + + /// + /// Returns the numeric overlap of number sprites to use. + /// A positive number will bring the number sprites closer together, while a negative number + /// will split them apart more. + /// + public static float GetFontOverlap(this ISkin source, LegacyFont font) + { + switch (font) + { + case LegacyFont.Score: + return source.GetConfig(LegacySetting.ScoreOverlap)?.Value ?? -2f; + + case LegacyFont.Combo: + return source.GetConfig(LegacySetting.ComboOverlap)?.Value ?? -2f; + + case LegacyFont.HitCircle: + return source.GetConfig(LegacySetting.HitCircleOverlap)?.Value ?? -2f; + + default: + throw new ArgumentOutOfRangeException(nameof(font)); + } + } public class SkinnableTextureAnimation : TextureAnimation { From 64d1cb519324df2663aa85502ba6bed305ae1b0f Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sun, 7 Mar 2021 02:30:16 +0300 Subject: [PATCH 03/30] Remove text skin components in favour of plain `LegacySpriteText`s --- osu.Game/Skinning/HUDSkinComponents.cs | 2 -- osu.Game/Skinning/LegacySkin.cs | 21 +-------------------- 2 files changed, 1 insertion(+), 22 deletions(-) diff --git a/osu.Game/Skinning/HUDSkinComponents.cs b/osu.Game/Skinning/HUDSkinComponents.cs index b01be2d5a0..a345e060e5 100644 --- a/osu.Game/Skinning/HUDSkinComponents.cs +++ b/osu.Game/Skinning/HUDSkinComponents.cs @@ -9,7 +9,5 @@ namespace osu.Game.Skinning ScoreCounter, AccuracyCounter, HealthDisplay, - ScoreText, - ComboText, } } diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index e5d0217671..83854c592b 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -18,7 +18,6 @@ using osu.Game.Beatmaps.Formats; using osu.Game.IO; using osu.Game.Rulesets.Scoring; using osu.Game.Screens.Play.HUD; -using osuTK; using osuTK.Graphics; namespace osu.Game.Skinning @@ -327,19 +326,13 @@ namespace osu.Game.Skinning return null; } - private string scorePrefix => GetConfig(LegacySkinConfiguration.LegacySetting.ScorePrefix)?.Value ?? "score"; - - private string comboPrefix => GetConfig(LegacySkinConfiguration.LegacySetting.ComboPrefix)?.Value ?? "score"; - - private bool hasScoreFont => this.HasFont(scorePrefix); - public override Drawable GetDrawableComponent(ISkinComponent component) { switch (component) { case HUDSkinComponent hudComponent: { - if (!hasScoreFont) + if (!this.HasFont(LegacyFont.Score)) return null; switch (hudComponent.Component) @@ -355,18 +348,6 @@ namespace osu.Game.Skinning case HUDSkinComponents.HealthDisplay: return new LegacyHealthDisplay(this); - - case HUDSkinComponents.ComboText: - return new LegacySpriteText(this, comboPrefix) - { - Spacing = new Vector2(-(GetConfig(LegacySkinConfiguration.LegacySetting.ComboOverlap)?.Value ?? -2), 0) - }; - - case HUDSkinComponents.ScoreText: - return new LegacySpriteText(this, scorePrefix) - { - Spacing = new Vector2(-(GetConfig(LegacySkinConfiguration.LegacySetting.ScoreOverlap)?.Value ?? -2), 0) - }; } return null; From 2a2ee3fa5ea86bbfc875f5659c01b3463adb93fb Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sun, 7 Mar 2021 02:28:08 +0300 Subject: [PATCH 04/30] Update legacy sprite text constructor --- osu.Game/Skinning/LegacyRollingCounter.cs | 23 +++++------------------ osu.Game/Skinning/LegacySpriteText.cs | 7 +++++-- 2 files changed, 10 insertions(+), 20 deletions(-) diff --git a/osu.Game/Skinning/LegacyRollingCounter.cs b/osu.Game/Skinning/LegacyRollingCounter.cs index 8aa9d4e9af..0261db0e64 100644 --- a/osu.Game/Skinning/LegacyRollingCounter.cs +++ b/osu.Game/Skinning/LegacyRollingCounter.cs @@ -4,7 +4,6 @@ using System; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; -using osuTK; namespace osu.Game.Skinning { @@ -14,9 +13,7 @@ namespace osu.Game.Skinning public class LegacyRollingCounter : RollingCounter { private readonly ISkin skin; - - private readonly string fontName; - private readonly float fontOverlap; + private readonly LegacyFont font; protected override bool IsRollingProportional => true; @@ -24,17 +21,11 @@ namespace osu.Game.Skinning /// Creates a new . /// /// The from which to get counter number sprites. - /// The name of the legacy font to use. - /// - /// The numeric overlap of number sprites to use. - /// A positive number will bring the number sprites closer together, while a negative number - /// will split them apart more. - /// - public LegacyRollingCounter(ISkin skin, string fontName, float fontOverlap) + /// The legacy font to use for the counter. + public LegacyRollingCounter(ISkin skin, LegacyFont font) { this.skin = skin; - this.fontName = fontName; - this.fontOverlap = fontOverlap; + this.font = font; } protected override double GetProportionalDuration(int currentValue, int newValue) @@ -42,10 +33,6 @@ namespace osu.Game.Skinning return Math.Abs(newValue - currentValue) * 75.0; } - protected sealed override OsuSpriteText CreateSpriteText() => - new LegacySpriteText(skin, fontName) - { - Spacing = new Vector2(-fontOverlap, 0f) - }; + protected sealed override OsuSpriteText CreateSpriteText() => new LegacySpriteText(skin, font); } } diff --git a/osu.Game/Skinning/LegacySpriteText.cs b/osu.Game/Skinning/LegacySpriteText.cs index 5d0e312f7c..c55400e219 100644 --- a/osu.Game/Skinning/LegacySpriteText.cs +++ b/osu.Game/Skinning/LegacySpriteText.cs @@ -5,6 +5,7 @@ using System.Threading.Tasks; using osu.Framework.Graphics.Sprites; using osu.Framework.Text; using osu.Game.Graphics.Sprites; +using osuTK; namespace osu.Game.Skinning { @@ -16,12 +17,14 @@ namespace osu.Game.Skinning protected override char[] FixedWidthExcludeCharacters => new[] { ',', '.', '%', 'x' }; - public LegacySpriteText(ISkin skin, string font = "score") + public LegacySpriteText(ISkin skin, LegacyFont font) { Shadow = false; UseFullGlyphHeight = false; - Font = new FontUsage(font, 1, fixedWidth: true); + Font = new FontUsage(skin.GetFontPrefix(font), 1, fixedWidth: true); + Spacing = new Vector2(-skin.GetFontOverlap(font), 0); + glyphStore = new LegacyGlyphStore(skin); } From 43c1e1d217388f56fe5e1e616fb000c65f7d2382 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sun, 7 Mar 2021 02:18:31 +0300 Subject: [PATCH 05/30] Update existing usages Resolve post-conflict issues --- .../Legacy/CatchLegacySkinTransformer.cs | 4 +--- .../Legacy/LegacyCatchComboCounter.cs | 8 ++------ .../Legacy/OsuLegacySkinTransformer.cs | 17 +++++++---------- .../Screens/Play/HUD/LegacyComboCounter.cs | 19 ++++++++----------- osu.Game/Skinning/LegacyAccuracyCounter.cs | 8 +++++--- osu.Game/Skinning/LegacyScoreCounter.cs | 8 +++++--- 6 files changed, 28 insertions(+), 36 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Skinning/Legacy/CatchLegacySkinTransformer.cs b/osu.Game.Rulesets.Catch/Skinning/Legacy/CatchLegacySkinTransformer.cs index 41fd0fe776..1b48832ed6 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Legacy/CatchLegacySkinTransformer.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Legacy/CatchLegacySkinTransformer.cs @@ -5,7 +5,6 @@ using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Game.Skinning; using osuTK.Graphics; -using static osu.Game.Skinning.LegacySkinConfiguration; namespace osu.Game.Rulesets.Catch.Skinning.Legacy { @@ -14,7 +13,7 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy /// /// For simplicity, let's use legacy combo font texture existence as a way to identify legacy skins from default. /// - private bool providesComboCounter => this.HasFont(GetConfig(LegacySetting.ComboPrefix)?.Value ?? "score"); + private bool providesComboCounter => this.HasFont(LegacyFont.Combo); public CatchLegacySkinTransformer(ISkinSource source) : base(source) @@ -69,7 +68,6 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy this.GetAnimation("fruit-ryuuta", true, true, true); case CatchSkinComponents.CatchComboCounter: - if (providesComboCounter) return new LegacyCatchComboCounter(Source); diff --git a/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyCatchComboCounter.cs b/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyCatchComboCounter.cs index f797ae75c2..28ee7bd813 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyCatchComboCounter.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyCatchComboCounter.cs @@ -7,7 +7,6 @@ using osu.Game.Rulesets.Catch.UI; using osu.Game.Skinning; using osuTK; using osuTK.Graphics; -using static osu.Game.Skinning.LegacySkinConfiguration; namespace osu.Game.Rulesets.Catch.Skinning.Legacy { @@ -22,9 +21,6 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy public LegacyCatchComboCounter(ISkin skin) { - var fontName = skin.GetConfig(LegacySetting.ComboPrefix)?.Value ?? "score"; - var fontOverlap = skin.GetConfig(LegacySetting.ComboOverlap)?.Value ?? -2f; - AutoSizeAxes = Axes.Both; Alpha = 0f; @@ -34,7 +30,7 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy InternalChildren = new Drawable[] { - explosion = new LegacyRollingCounter(skin, fontName, fontOverlap) + explosion = new LegacyRollingCounter(skin, LegacyFont.Combo) { Alpha = 0.65f, Blending = BlendingParameters.Additive, @@ -42,7 +38,7 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy Origin = Anchor.Centre, Scale = new Vector2(1.5f), }, - counter = new LegacyRollingCounter(skin, fontName, fontOverlap) + counter = new LegacyRollingCounter(skin, LegacyFont.Combo) { Anchor = Anchor.Centre, Origin = Anchor.Centre, diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/OsuLegacySkinTransformer.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/OsuLegacySkinTransformer.cs index d74f885573..ffe238c507 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/OsuLegacySkinTransformer.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/OsuLegacySkinTransformer.cs @@ -97,17 +97,14 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy return null; case OsuSkinComponents.HitCircleText: - var font = GetConfig(OsuSkinConfiguration.HitCirclePrefix)?.Value ?? "default"; - var overlap = GetConfig(OsuSkinConfiguration.HitCircleOverlap)?.Value ?? -2; + if (!this.HasFont(LegacyFont.HitCircle)) + return null; - return !this.HasFont(font) - ? null - : new LegacySpriteText(Source, font) - { - // stable applies a blanket 0.8x scale to hitcircle fonts - Scale = new Vector2(0.8f), - Spacing = new Vector2(-overlap, 0) - }; + return new LegacySpriteText(Source, LegacyFont.HitCircle) + { + // stable applies a blanket 0.8x scale to hitcircle fonts + Scale = new Vector2(0.8f), + }; case OsuSkinComponents.SpinnerBody: bool hasBackground = Source.GetTexture("spinner-background") != null; diff --git a/osu.Game/Screens/Play/HUD/LegacyComboCounter.cs b/osu.Game/Screens/Play/HUD/LegacyComboCounter.cs index 81183a425a..b4604c0d01 100644 --- a/osu.Game/Screens/Play/HUD/LegacyComboCounter.cs +++ b/osu.Game/Screens/Play/HUD/LegacyComboCounter.cs @@ -6,7 +6,6 @@ using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; -using osu.Game.Graphics.Sprites; using osu.Game.Skinning; using osuTK; @@ -84,16 +83,16 @@ namespace osu.Game.Screens.Play.HUD { InternalChildren = new[] { - popOutCount = createSpriteText().With(s => + popOutCount = new LegacySpriteText(skin, LegacyFont.Combo) { - s.Alpha = 0; - s.Margin = new MarginPadding(0.05f); - s.Blending = BlendingParameters.Additive; - }), - displayedCountSpriteText = createSpriteText().With(s => + Alpha = 0, + Margin = new MarginPadding(0.05f), + Blending = BlendingParameters.Additive, + }, + displayedCountSpriteText = new LegacySpriteText(skin, LegacyFont.Combo) { - s.Alpha = 0; - }) + Alpha = 0, + }, }; Current.ValueChanged += combo => updateCount(combo.NewValue == 0); @@ -247,7 +246,5 @@ namespace osu.Game.Screens.Play.HUD double difference = currentValue > newValue ? currentValue - newValue : newValue - currentValue; return difference * rolling_duration; } - - private OsuSpriteText createSpriteText() => (OsuSpriteText)skin.GetDrawableComponent(new HUDSkinComponent(HUDSkinComponents.ComboText)); } } diff --git a/osu.Game/Skinning/LegacyAccuracyCounter.cs b/osu.Game/Skinning/LegacyAccuracyCounter.cs index 5eda374337..7d6f1dc916 100644 --- a/osu.Game/Skinning/LegacyAccuracyCounter.cs +++ b/osu.Game/Skinning/LegacyAccuracyCounter.cs @@ -29,9 +29,11 @@ namespace osu.Game.Skinning [Resolved(canBeNull: true)] private HUDOverlay hud { get; set; } - protected sealed override OsuSpriteText CreateSpriteText() - => (OsuSpriteText)skin?.GetDrawableComponent(new HUDSkinComponent(HUDSkinComponents.ScoreText)) - ?.With(s => s.Anchor = s.Origin = Anchor.TopRight); + protected sealed override OsuSpriteText CreateSpriteText() => new LegacySpriteText(skin, LegacyFont.Score) + { + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + }; protected override void Update() { diff --git a/osu.Game/Skinning/LegacyScoreCounter.cs b/osu.Game/Skinning/LegacyScoreCounter.cs index 5bffeff5a8..1d330ef495 100644 --- a/osu.Game/Skinning/LegacyScoreCounter.cs +++ b/osu.Game/Skinning/LegacyScoreCounter.cs @@ -33,8 +33,10 @@ namespace osu.Game.Skinning Margin = new MarginPadding(10); } - protected sealed override OsuSpriteText CreateSpriteText() - => (OsuSpriteText)skin.GetDrawableComponent(new HUDSkinComponent(HUDSkinComponents.ScoreText)) - .With(s => s.Anchor = s.Origin = Anchor.TopRight); + protected sealed override OsuSpriteText CreateSpriteText() => new LegacySpriteText(skin, LegacyFont.Score) + { + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + }; } } From 8046b5a818f8d2a69d7199e6cff6fa2a1db024d8 Mon Sep 17 00:00:00 2001 From: Nathan Alo Date: Wed, 17 Mar 2021 17:35:49 +0800 Subject: [PATCH 06/30] set text to platform clipboard on copy --- osu.Game/Screens/Edit/Editor.cs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 0ba202b082..88383bd3ed 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -21,6 +21,7 @@ using osu.Framework.Screens; using osu.Framework.Timing; using osu.Game.Beatmaps; using osu.Game.Configuration; +using osu.Game.Extensions; using osu.Game.Graphics; using osu.Game.Graphics.Cursor; using osu.Game.Graphics.UserInterface; @@ -29,6 +30,7 @@ using osu.Game.IO.Serialization; using osu.Game.Online.API; using osu.Game.Overlays; using osu.Game.Rulesets.Edit; +using osu.Game.Rulesets.Objects.Types; using osu.Game.Screens.Edit.Components; using osu.Game.Screens.Edit.Components.Menus; using osu.Game.Screens.Edit.Components.Timelines.Summary; @@ -60,6 +62,9 @@ namespace osu.Game.Screens.Edit protected bool HasUnsavedChanges => lastSavedHash != changeHandler.CurrentStateHash; + [Resolved] + private GameHost host { get; set; } + [Resolved] private BeatmapManager beatmapManager { get; set; } @@ -104,7 +109,7 @@ namespace osu.Game.Screens.Edit private MusicController music { get; set; } [BackgroundDependencyLoader] - private void load(OsuColour colours, GameHost host, OsuConfigManager config) + private void load(OsuColour colours, OsuConfigManager config) { if (Beatmap.Value is DummyWorkingBeatmap) { @@ -542,8 +547,12 @@ namespace osu.Game.Screens.Edit protected void Copy() { if (editorBeatmap.SelectedHitObjects.Count == 0) + { + host.GetClipboard()?.SetText($"{clock.CurrentTime.ToEditorFormattedString()} - "); return; + } + host.GetClipboard()?.SetText($"{editorBeatmap.SelectedHitObjects.FirstOrDefault().StartTime.ToEditorFormattedString()} ({string.Join(',', editorBeatmap.SelectedHitObjects.Select(h => ((h as IHasComboInformation)?.IndexInCurrentCombo + 1 ?? 0).ToString()))}) - "); clipboard.Value = new ClipboardContent(editorBeatmap).Serialize(); } From 133ff085a53711229834c0c3b3944f1c29d91b73 Mon Sep 17 00:00:00 2001 From: Nathan Alo Date: Wed, 17 Mar 2021 18:06:40 +0800 Subject: [PATCH 07/30] refactor code --- osu.Game/Screens/Edit/Editor.cs | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 88383bd3ed..fdb31a8b8c 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; +using System.Text; using osu.Framework; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -546,14 +547,24 @@ namespace osu.Game.Screens.Edit protected void Copy() { + var builder = new StringBuilder(); + const string suffix = " - "; + if (editorBeatmap.SelectedHitObjects.Count == 0) { - host.GetClipboard()?.SetText($"{clock.CurrentTime.ToEditorFormattedString()} - "); - return; + builder.Append(clock.CurrentTime.ToEditorFormattedString()); + } + else + { + var orderedHitObjects = editorBeatmap.SelectedHitObjects.OrderBy(h => h.StartTime); + builder.Append(orderedHitObjects.FirstOrDefault().StartTime.ToEditorFormattedString()); + builder.Append($" ({string.Join(',', orderedHitObjects.Cast().Select(h => h.IndexInCurrentCombo + 1))})"); + + clipboard.Value = new ClipboardContent(editorBeatmap).Serialize(); } - host.GetClipboard()?.SetText($"{editorBeatmap.SelectedHitObjects.FirstOrDefault().StartTime.ToEditorFormattedString()} ({string.Join(',', editorBeatmap.SelectedHitObjects.Select(h => ((h as IHasComboInformation)?.IndexInCurrentCombo + 1 ?? 0).ToString()))}) - "); - clipboard.Value = new ClipboardContent(editorBeatmap).Serialize(); + builder.Append(suffix); + host.GetClipboard()?.SetText(builder.ToString()); } protected void Paste() From 51e0304c54a604bab6d6c8007c59ec755b115b2d Mon Sep 17 00:00:00 2001 From: Nathan Alo Date: Wed, 17 Mar 2021 18:31:09 +0800 Subject: [PATCH 08/30] properly format strings per ruleset --- osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs | 2 ++ osu.Game.Rulesets.Mania/Objects/ManiaHitObject.cs | 2 ++ osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs | 2 ++ osu.Game/Rulesets/Objects/HitObject.cs | 2 ++ osu.Game/Screens/Edit/Editor.cs | 2 +- 5 files changed, 9 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs b/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs index ae45182960..631b50d686 100644 --- a/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs +++ b/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs @@ -120,5 +120,7 @@ namespace osu.Game.Rulesets.Catch.Objects } protected override HitWindows CreateHitWindows() => HitWindows.Empty; + + public override string ToEditorString() => (IndexInCurrentCombo + 1).ToString(); } } diff --git a/osu.Game.Rulesets.Mania/Objects/ManiaHitObject.cs b/osu.Game.Rulesets.Mania/Objects/ManiaHitObject.cs index 27bf50493d..c43d223335 100644 --- a/osu.Game.Rulesets.Mania/Objects/ManiaHitObject.cs +++ b/osu.Game.Rulesets.Mania/Objects/ManiaHitObject.cs @@ -22,6 +22,8 @@ namespace osu.Game.Rulesets.Mania.Objects protected override HitWindows CreateHitWindows() => new ManiaHitWindows(); + public override string ToEditorString() => $"{StartTime}|{Column}"; + #region LegacyBeatmapEncoder float IHasXPosition.X => Column; diff --git a/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs b/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs index 22b64af3df..e784d13084 100644 --- a/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs +++ b/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs @@ -130,5 +130,7 @@ namespace osu.Game.Rulesets.Osu.Objects } protected override HitWindows CreateHitWindows() => new OsuHitWindows(); + + public override string ToEditorString() => (IndexInCurrentCombo + 1).ToString(); } } diff --git a/osu.Game/Rulesets/Objects/HitObject.cs b/osu.Game/Rulesets/Objects/HitObject.cs index 826d411822..fa7b2811cc 100644 --- a/osu.Game/Rulesets/Objects/HitObject.cs +++ b/osu.Game/Rulesets/Objects/HitObject.cs @@ -168,6 +168,8 @@ namespace osu.Game.Rulesets.Objects /// [NotNull] protected virtual HitWindows CreateHitWindows() => new HitWindows(); + + public virtual string ToEditorString() => string.Empty; } public static class HitObjectExtensions diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index fdb31a8b8c..a6e84d59a7 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -558,7 +558,7 @@ namespace osu.Game.Screens.Edit { var orderedHitObjects = editorBeatmap.SelectedHitObjects.OrderBy(h => h.StartTime); builder.Append(orderedHitObjects.FirstOrDefault().StartTime.ToEditorFormattedString()); - builder.Append($" ({string.Join(',', orderedHitObjects.Cast().Select(h => h.IndexInCurrentCombo + 1))})"); + builder.Append($" ({string.Join(',', orderedHitObjects.Select(h => h.ToEditorString()))})"); clipboard.Value = new ClipboardContent(editorBeatmap).Serialize(); } From cb4ae6e61a87745a3204baa7459c5f895dc5b9e1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 25 Mar 2021 17:34:29 +0900 Subject: [PATCH 09/30] Fix very high accuracies feigning as "perfect" 100% plays when actually below --- osu.Game/Users/UserStatistics.cs | 2 +- osu.Game/Utils/FormatUtils.cs | 15 ++++++++------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/osu.Game/Users/UserStatistics.cs b/osu.Game/Users/UserStatistics.cs index dc926898fc..04a358436e 100644 --- a/osu.Game/Users/UserStatistics.cs +++ b/osu.Game/Users/UserStatistics.cs @@ -42,7 +42,7 @@ namespace osu.Game.Users public long RankedScore; [JsonProperty(@"hit_accuracy")] - public decimal Accuracy; + public double Accuracy; [JsonIgnore] public string DisplayAccuracy => Accuracy.FormatAccuracy(); diff --git a/osu.Game/Utils/FormatUtils.cs b/osu.Game/Utils/FormatUtils.cs index 2578d8d835..70a96367be 100644 --- a/osu.Game/Utils/FormatUtils.cs +++ b/osu.Game/Utils/FormatUtils.cs @@ -1,6 +1,7 @@ // 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 Humanizer; namespace osu.Game.Utils @@ -12,14 +13,14 @@ namespace osu.Game.Utils /// /// The accuracy to be formatted /// formatted accuracy in percentage - public static string FormatAccuracy(this double accuracy) => $"{accuracy:0.00%}"; + public static string FormatAccuracy(this double accuracy) + { + // we don't ever want to show 100% when the accuracy is below perfect, even if it rounds to 100%. + if (accuracy < 1 && accuracy > 0.9999) + accuracy = 0.9999; - /// - /// Turns the provided accuracy into a percentage with 2 decimal places. - /// - /// The accuracy to be formatted - /// formatted accuracy in percentage - public static string FormatAccuracy(this decimal accuracy) => $"{accuracy:0.00}%"; + return $"{accuracy:0.00%}"; + } /// /// Formats the supplied rank/leaderboard position in a consistent, simplified way. From 544117a49495a97c297f0253b0fcfa1725b9ce74 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 25 Mar 2021 17:34:41 +0900 Subject: [PATCH 10/30] Add test coverage of accuracy formatting function --- osu.Game.Tests/NonVisual/FormatUtilsTest.cs | 25 +++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 osu.Game.Tests/NonVisual/FormatUtilsTest.cs diff --git a/osu.Game.Tests/NonVisual/FormatUtilsTest.cs b/osu.Game.Tests/NonVisual/FormatUtilsTest.cs new file mode 100644 index 0000000000..eb738f5f67 --- /dev/null +++ b/osu.Game.Tests/NonVisual/FormatUtilsTest.cs @@ -0,0 +1,25 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using NUnit.Framework; +using osu.Game.Utils; + +namespace osu.Game.Tests.NonVisual +{ + [TestFixture] + public class FormatUtilsTest + { + [TestCase(0, "0.00%")] + [TestCase(0.01, "1.00%")] + [TestCase(0.9899, "98.99%")] + [TestCase(0.989999, "99.00%")] + [TestCase(0.99, "99.00%")] + [TestCase(0.9999, "99.99%")] + [TestCase(0.999999, "99.99%")] + [TestCase(1, "100.00%")] + public void TestAccuracyFormatting(double input, string expectedOutput) + { + Assert.AreEqual(expectedOutput, input.FormatAccuracy()); + } + } +} From 701342e03673b4e9d647484a4193418fbf64d107 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 25 Mar 2021 17:43:51 +0900 Subject: [PATCH 11/30] Remove accuracy rounding at a ScoreProcessor level --- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index 2024290460..b81fa79345 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -337,7 +337,7 @@ namespace osu.Game.Rulesets.Scoring score.TotalScore = (long)Math.Round(GetStandardisedScore()); score.Combo = Combo.Value; score.MaxCombo = HighestCombo.Value; - score.Accuracy = Math.Round(Accuracy.Value, 4); + score.Accuracy = Accuracy.Value; score.Rank = Rank.Value; score.Date = DateTimeOffset.Now; From 630faa3b56e5a3b36577c695f906d006088e61e3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 25 Mar 2021 17:50:21 +0900 Subject: [PATCH 12/30] Add TODO marking incorrect EF core data type As mentioned in the comment, we probably don't need to be storing this in the database in the first place (as it should be able to be calculated from the other statistics we have available to us). Something to consider when we refactor the database backend. --- osu.Game/Scoring/ScoreInfo.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Scoring/ScoreInfo.cs b/osu.Game/Scoring/ScoreInfo.cs index f5192f3a40..ef11c19e3f 100644 --- a/osu.Game/Scoring/ScoreInfo.cs +++ b/osu.Game/Scoring/ScoreInfo.cs @@ -30,7 +30,7 @@ namespace osu.Game.Scoring public long TotalScore { get; set; } [JsonProperty("accuracy")] - [Column(TypeName = "DECIMAL(1,4)")] + [Column(TypeName = "DECIMAL(1,4)")] // TODO: This data type is wrong (should contain more precision). But at the same time, we probably don't need to be storing this in the database. public double Accuracy { get; set; } [JsonIgnore] From 77888ae6402c669a0f6330d698b6794bc9ff5539 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 25 Mar 2021 17:51:20 +0900 Subject: [PATCH 13/30] Remove unnecessary using --- osu.Game/Utils/FormatUtils.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Utils/FormatUtils.cs b/osu.Game/Utils/FormatUtils.cs index 70a96367be..4c7702f04e 100644 --- a/osu.Game/Utils/FormatUtils.cs +++ b/osu.Game/Utils/FormatUtils.cs @@ -1,7 +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 Humanizer; namespace osu.Game.Utils From bada1e7189973f09452ad51419abbb79650f9972 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 25 Mar 2021 15:00:06 +0300 Subject: [PATCH 14/30] Update legacy spinner bonus counter usage --- .../Skinning/Legacy/LegacySpinner.cs | 40 +++++++------------ 1 file changed, 15 insertions(+), 25 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySpinner.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySpinner.cs index dd1c6cad77..064b7a4680 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySpinner.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySpinner.cs @@ -48,9 +48,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy DrawableSpinner = (DrawableSpinner)drawableHitObject; - Container overlayContainer; - - AddInternal(overlayContainer = new Container + AddInternal(new Container { Depth = float.MinValue, RelativeSizeAxes = Axes.Both, @@ -73,21 +71,16 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy Scale = new Vector2(SPRITE_SCALE), Y = SPINNER_TOP_OFFSET + 115, }, + bonusCounter = new LegacySpriteText(source, LegacyFont.Score) + { + Alpha = 0f, + Anchor = Anchor.TopCentre, + Origin = Anchor.Centre, + Scale = new Vector2(SPRITE_SCALE), + Y = SPINNER_TOP_OFFSET + 299, + }.With(s => s.Font = s.Font.With(fixedWidth: false)), } }); - - bonusCounter = (source.GetDrawableComponent(new HUDSkinComponent(HUDSkinComponents.ScoreText)) as LegacySpriteText)?.With(c => - { - c.Alpha = 0f; - c.Anchor = Anchor.TopCentre; - c.Origin = Anchor.Centre; - c.Font = c.Font.With(fixedWidth: false); - c.Scale = new Vector2(SPRITE_SCALE); - c.Y = SPINNER_TOP_OFFSET + 299; - }); - - if (bonusCounter != null) - overlayContainer.Add(bonusCounter); } private IBindable gainedBonus; @@ -98,16 +91,13 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy { base.LoadComplete(); - if (bonusCounter != null) + gainedBonus = DrawableSpinner.GainedBonus.GetBoundCopy(); + gainedBonus.BindValueChanged(bonus => { - gainedBonus = DrawableSpinner.GainedBonus.GetBoundCopy(); - gainedBonus.BindValueChanged(bonus => - { - bonusCounter.Text = bonus.NewValue.ToString(NumberFormatInfo.InvariantInfo); - bonusCounter.FadeOutFromOne(800, Easing.Out); - bonusCounter.ScaleTo(SPRITE_SCALE * 2f).Then().ScaleTo(SPRITE_SCALE * 1.28f, 800, Easing.Out); - }); - } + bonusCounter.Text = bonus.NewValue.ToString(NumberFormatInfo.InvariantInfo); + bonusCounter.FadeOutFromOne(800, Easing.Out); + bonusCounter.ScaleTo(SPRITE_SCALE * 2f).Then().ScaleTo(SPRITE_SCALE * 1.28f, 800, Easing.Out); + }); completed.BindValueChanged(onCompletedChanged, true); From 6a7f9261684602ab3b4633839a1bea1e0acd035c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 26 Mar 2021 13:06:30 +0900 Subject: [PATCH 15/30] Change rounding to use a more general flooring approach --- osu.Game.Tests/NonVisual/FormatUtilsTest.cs | 2 +- osu.Game/Utils/FormatUtils.cs | 9 ++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/osu.Game.Tests/NonVisual/FormatUtilsTest.cs b/osu.Game.Tests/NonVisual/FormatUtilsTest.cs index eb738f5f67..46d8f4fec4 100644 --- a/osu.Game.Tests/NonVisual/FormatUtilsTest.cs +++ b/osu.Game.Tests/NonVisual/FormatUtilsTest.cs @@ -12,7 +12,7 @@ namespace osu.Game.Tests.NonVisual [TestCase(0, "0.00%")] [TestCase(0.01, "1.00%")] [TestCase(0.9899, "98.99%")] - [TestCase(0.989999, "99.00%")] + [TestCase(0.989999, "98.99%")] [TestCase(0.99, "99.00%")] [TestCase(0.9999, "99.99%")] [TestCase(0.999999, "99.99%")] diff --git a/osu.Game/Utils/FormatUtils.cs b/osu.Game/Utils/FormatUtils.cs index 4c7702f04e..8312b9e756 100644 --- a/osu.Game/Utils/FormatUtils.cs +++ b/osu.Game/Utils/FormatUtils.cs @@ -1,6 +1,7 @@ // 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 Humanizer; namespace osu.Game.Utils @@ -14,9 +15,11 @@ namespace osu.Game.Utils /// formatted accuracy in percentage public static string FormatAccuracy(this double accuracy) { - // we don't ever want to show 100% when the accuracy is below perfect, even if it rounds to 100%. - if (accuracy < 1 && accuracy > 0.9999) - accuracy = 0.9999; + // for the sake of display purposes, we don't want to show a user a "rounded up" percentage to the next whole number. + // ie. a score which gets 89.99999% shouldn't ever show as 90%. + // the reasoning for this is that cutoffs for grade increases are at whole numbers and displaying the required + // percentile with a non-matching grade is confusing. + accuracy = Math.Floor(accuracy * 10000) / 10000; return $"{accuracy:0.00%}"; } From 4909eaf890715b10a6728270673a7c629f4a7493 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 26 Mar 2021 13:09:53 +0900 Subject: [PATCH 16/30] Add the ability to specify format provider (to make tests culture invariant) --- osu.Game.Tests/NonVisual/FormatUtilsTest.cs | 3 ++- osu.Game/Utils/FormatUtils.cs | 8 +++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/osu.Game.Tests/NonVisual/FormatUtilsTest.cs b/osu.Game.Tests/NonVisual/FormatUtilsTest.cs index 46d8f4fec4..df095ddee3 100644 --- a/osu.Game.Tests/NonVisual/FormatUtilsTest.cs +++ b/osu.Game.Tests/NonVisual/FormatUtilsTest.cs @@ -1,6 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System.Globalization; using NUnit.Framework; using osu.Game.Utils; @@ -19,7 +20,7 @@ namespace osu.Game.Tests.NonVisual [TestCase(1, "100.00%")] public void TestAccuracyFormatting(double input, string expectedOutput) { - Assert.AreEqual(expectedOutput, input.FormatAccuracy()); + Assert.AreEqual(expectedOutput, input.FormatAccuracy(CultureInfo.InvariantCulture)); } } } diff --git a/osu.Game/Utils/FormatUtils.cs b/osu.Game/Utils/FormatUtils.cs index 8312b9e756..df1b6cf00d 100644 --- a/osu.Game/Utils/FormatUtils.cs +++ b/osu.Game/Utils/FormatUtils.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Globalization; using Humanizer; namespace osu.Game.Utils @@ -11,9 +12,10 @@ namespace osu.Game.Utils /// /// Turns the provided accuracy into a percentage with 2 decimal places. /// - /// The accuracy to be formatted + /// The accuracy to be formatted. + /// An optional format provider. /// formatted accuracy in percentage - public static string FormatAccuracy(this double accuracy) + public static string FormatAccuracy(this double accuracy, IFormatProvider formatProvider = null) { // for the sake of display purposes, we don't want to show a user a "rounded up" percentage to the next whole number. // ie. a score which gets 89.99999% shouldn't ever show as 90%. @@ -21,7 +23,7 @@ namespace osu.Game.Utils // percentile with a non-matching grade is confusing. accuracy = Math.Floor(accuracy * 10000) / 10000; - return $"{accuracy:0.00%}"; + return accuracy.ToString("0.00%", formatProvider ?? CultureInfo.CurrentCulture); } /// From 7faca766e45b0d369326a9bdc26422bb065c825c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 26 Mar 2021 14:49:02 +0900 Subject: [PATCH 17/30] Fix crash on attempting to join lobby using key press during a pending join Closes https://github.com/ppy/osu/issues/12040. --- osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs b/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs index f13d623eae..5a28d0f968 100644 --- a/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs @@ -170,7 +170,9 @@ namespace osu.Game.Screens.OnlinePlay.Lounge private void joinRequested(Room room) { - Debug.Assert(joiningRoomOperation == null); + if (joiningRoomOperation != null) + return; + joiningRoomOperation = ongoingOperationTracker?.BeginOperation(); RoomManager?.JoinRoom(room, r => From 6a4157d1939f513d0ed1167192b9b7007e8db1d6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 26 Mar 2021 16:13:43 +0900 Subject: [PATCH 18/30] Remove unused using statement --- osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs b/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs index 5a28d0f968..f24577a8a5 100644 --- a/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using System; -using System.Diagnostics; using System.Linq; using JetBrains.Annotations; using osu.Framework.Allocation; From 2bea69456e8bfbcdf780bd6e8adab5002913f3e3 Mon Sep 17 00:00:00 2001 From: Nathan Alo Date: Fri, 26 Mar 2021 15:24:33 +0800 Subject: [PATCH 19/30] remove implementations --- .../Objects/CatchHitObject.cs | 2 -- .../Objects/ManiaHitObject.cs | 2 -- osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs | 2 -- osu.Game/Rulesets/Objects/HitObject.cs | 2 -- osu.Game/Screens/Edit/Editor.cs | 23 +++---------------- 5 files changed, 3 insertions(+), 28 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs b/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs index 631b50d686..ae45182960 100644 --- a/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs +++ b/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs @@ -120,7 +120,5 @@ namespace osu.Game.Rulesets.Catch.Objects } protected override HitWindows CreateHitWindows() => HitWindows.Empty; - - public override string ToEditorString() => (IndexInCurrentCombo + 1).ToString(); } } diff --git a/osu.Game.Rulesets.Mania/Objects/ManiaHitObject.cs b/osu.Game.Rulesets.Mania/Objects/ManiaHitObject.cs index c43d223335..27bf50493d 100644 --- a/osu.Game.Rulesets.Mania/Objects/ManiaHitObject.cs +++ b/osu.Game.Rulesets.Mania/Objects/ManiaHitObject.cs @@ -22,8 +22,6 @@ namespace osu.Game.Rulesets.Mania.Objects protected override HitWindows CreateHitWindows() => new ManiaHitWindows(); - public override string ToEditorString() => $"{StartTime}|{Column}"; - #region LegacyBeatmapEncoder float IHasXPosition.X => Column; diff --git a/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs b/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs index e784d13084..22b64af3df 100644 --- a/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs +++ b/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs @@ -130,7 +130,5 @@ namespace osu.Game.Rulesets.Osu.Objects } protected override HitWindows CreateHitWindows() => new OsuHitWindows(); - - public override string ToEditorString() => (IndexInCurrentCombo + 1).ToString(); } } diff --git a/osu.Game/Rulesets/Objects/HitObject.cs b/osu.Game/Rulesets/Objects/HitObject.cs index fa7b2811cc..826d411822 100644 --- a/osu.Game/Rulesets/Objects/HitObject.cs +++ b/osu.Game/Rulesets/Objects/HitObject.cs @@ -168,8 +168,6 @@ namespace osu.Game.Rulesets.Objects /// [NotNull] protected virtual HitWindows CreateHitWindows() => new HitWindows(); - - public virtual string ToEditorString() => string.Empty; } public static class HitObjectExtensions diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index a6e84d59a7..c2a9fd49b1 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -63,9 +63,6 @@ namespace osu.Game.Screens.Edit protected bool HasUnsavedChanges => lastSavedHash != changeHandler.CurrentStateHash; - [Resolved] - private GameHost host { get; set; } - [Resolved] private BeatmapManager beatmapManager { get; set; } @@ -110,7 +107,7 @@ namespace osu.Game.Screens.Edit private MusicController music { get; set; } [BackgroundDependencyLoader] - private void load(OsuColour colours, OsuConfigManager config) + private void load(OsuColour colours, GameHost host, OsuConfigManager config) { if (Beatmap.Value is DummyWorkingBeatmap) { @@ -547,24 +544,10 @@ namespace osu.Game.Screens.Edit protected void Copy() { - var builder = new StringBuilder(); - const string suffix = " - "; - if (editorBeatmap.SelectedHitObjects.Count == 0) - { - builder.Append(clock.CurrentTime.ToEditorFormattedString()); - } - else - { - var orderedHitObjects = editorBeatmap.SelectedHitObjects.OrderBy(h => h.StartTime); - builder.Append(orderedHitObjects.FirstOrDefault().StartTime.ToEditorFormattedString()); - builder.Append($" ({string.Join(',', orderedHitObjects.Select(h => h.ToEditorString()))})"); + return; - clipboard.Value = new ClipboardContent(editorBeatmap).Serialize(); - } - - builder.Append(suffix); - host.GetClipboard()?.SetText(builder.ToString()); + clipboard.Value = new ClipboardContent(editorBeatmap).Serialize(); } protected void Paste() From b8b7eb4c4b8e0af156ebdad46a83ecbe3427b0b2 Mon Sep 17 00:00:00 2001 From: Nathan Alo Date: Fri, 26 Mar 2021 15:25:20 +0800 Subject: [PATCH 20/30] refactor logic to its own component and handle hit object to string conversion to its ruleset-specific composers --- .../Edit/ManiaHitObjectComposer.cs | 3 ++ .../Edit/OsuHitObjectComposer.cs | 3 ++ osu.Game/Rulesets/Edit/HitObjectComposer.cs | 2 + .../Screens/Edit/Compose/ComposeScreen.cs | 23 +++++++++- osu.Game/Screens/Edit/SelectionHelper.cs | 46 +++++++++++++++++++ 5 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 osu.Game/Screens/Edit/SelectionHelper.cs diff --git a/osu.Game.Rulesets.Mania/Edit/ManiaHitObjectComposer.cs b/osu.Game.Rulesets.Mania/Edit/ManiaHitObjectComposer.cs index 324670c4b2..4cb34a217c 100644 --- a/osu.Game.Rulesets.Mania/Edit/ManiaHitObjectComposer.cs +++ b/osu.Game.Rulesets.Mania/Edit/ManiaHitObjectComposer.cs @@ -119,5 +119,8 @@ namespace osu.Game.Rulesets.Mania.Edit beatSnapGrid.SelectionTimeRange = null; } } + + public override IEnumerable ConvertSelectionToString() + => EditorBeatmap.SelectedHitObjects.Cast().Select(h => $"{h.StartTime}|{h.Column}"); } } diff --git a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs index 0490e8b8ce..1943f52c73 100644 --- a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs +++ b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs @@ -82,6 +82,9 @@ namespace osu.Game.Rulesets.Osu.Edit protected override ComposeBlueprintContainer CreateBlueprintContainer() => new OsuBlueprintContainer(this); + public override IEnumerable ConvertSelectionToString() + => selectedHitObjects.Cast().Select(h => (h.IndexInCurrentCombo + 1).ToString()); + private DistanceSnapGrid distanceSnapGrid; private Container distanceSnapGridContainer; diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs index e927951d0a..eee16043e4 100644 --- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs @@ -438,6 +438,8 @@ namespace osu.Game.Rulesets.Edit /// public abstract bool CursorInPlacementArea { get; } + public virtual IEnumerable ConvertSelectionToString() => Array.Empty(); + #region IPositionSnapProvider public abstract SnapResult SnapScreenSpacePositionToValidTime(Vector2 screenSpacePosition); diff --git a/osu.Game/Screens/Edit/Compose/ComposeScreen.cs b/osu.Game/Screens/Edit/Compose/ComposeScreen.cs index 81b1195a40..c63ef11c74 100644 --- a/osu.Game/Screens/Edit/Compose/ComposeScreen.cs +++ b/osu.Game/Screens/Edit/Compose/ComposeScreen.cs @@ -6,6 +6,8 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Input; +using osu.Framework.Input.Bindings; using osu.Game.Beatmaps; using osu.Game.Rulesets; using osu.Game.Rulesets.Edit; @@ -14,16 +16,19 @@ using osu.Game.Skinning; namespace osu.Game.Screens.Edit.Compose { - public class ComposeScreen : EditorScreenWithTimeline + public class ComposeScreen : EditorScreenWithTimeline, IKeyBindingHandler { [Resolved] private IBindable beatmap { get; set; } private HitObjectComposer composer; + private SelectionHelper helper; + public ComposeScreen() : base(EditorScreenMode.Compose) { + Add(helper = new SelectionHelper()); } private Ruleset ruleset; @@ -72,5 +77,21 @@ namespace osu.Game.Screens.Edit.Compose // this is intentionally done in two stages to ensure things are in a loaded state before exposing the ruleset to skin sources. return beatmapSkinProvider.WithChild(rulesetSkinProvider.WithChild(content)); } + + public bool OnPressed(PlatformAction action) + { + switch (action.ActionType) + { + case PlatformActionType.Copy: + helper.CopySelectionToClipboard(); + return false; + default: + return false; + }; + } + + public void OnReleased(PlatformAction action) + { + } } } diff --git a/osu.Game/Screens/Edit/SelectionHelper.cs b/osu.Game/Screens/Edit/SelectionHelper.cs new file mode 100644 index 0000000000..e0eb868c9f --- /dev/null +++ b/osu.Game/Screens/Edit/SelectionHelper.cs @@ -0,0 +1,46 @@ +using System.Linq; +using System.Text; +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Platform; +using osu.Game.Extensions; +using osu.Game.Rulesets.Edit; + +namespace osu.Game.Screens.Edit +{ + public class SelectionHelper : Component + { + [Resolved] + private GameHost host { get; set; } + + [Resolved] + private EditorClock clock { get; set; } + + [Resolved] + private EditorBeatmap editorBeatmap { get; set; } + + [Resolved(CanBeNull = true)] + private HitObjectComposer composer { get; set; } + + public void CopySelectionToClipboard() + { + host.GetClipboard().SetText(formatSelectionAsString()); + } + + private string formatSelectionAsString() + { + const string separator = " - "; + var builder = new StringBuilder(); + + if (!editorBeatmap.SelectedHitObjects.Any()) + { + builder.Append($"{clock.CurrentTime.ToEditorFormattedString()}{separator}"); + return builder.ToString(); + }; + + builder.Append(editorBeatmap.SelectedHitObjects.First().StartTime.ToEditorFormattedString()); + builder.Append($" ({string.Join(',', composer.ConvertSelectionToString())}){separator}"); + return builder.ToString(); + } + } +} From 374f8c5e229b314a2f7cf1de9b29285cccbff0d2 Mon Sep 17 00:00:00 2001 From: Nathan Alo Date: Fri, 26 Mar 2021 15:33:28 +0800 Subject: [PATCH 21/30] move to compose namespace and add license header --- osu.Game/Screens/Edit/{ => Compose}/SelectionHelper.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) rename osu.Game/Screens/Edit/{ => Compose}/SelectionHelper.cs (85%) diff --git a/osu.Game/Screens/Edit/SelectionHelper.cs b/osu.Game/Screens/Edit/Compose/SelectionHelper.cs similarity index 85% rename from osu.Game/Screens/Edit/SelectionHelper.cs rename to osu.Game/Screens/Edit/Compose/SelectionHelper.cs index e0eb868c9f..39d6d57a2a 100644 --- a/osu.Game/Screens/Edit/SelectionHelper.cs +++ b/osu.Game/Screens/Edit/Compose/SelectionHelper.cs @@ -1,4 +1,7 @@ -using System.Linq; +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Linq; using System.Text; using osu.Framework.Allocation; using osu.Framework.Graphics; @@ -6,7 +9,7 @@ using osu.Framework.Platform; using osu.Game.Extensions; using osu.Game.Rulesets.Edit; -namespace osu.Game.Screens.Edit +namespace osu.Game.Screens.Edit.Compose { public class SelectionHelper : Component { From 71a0616861916129456e0a301d0386269c51cd6c Mon Sep 17 00:00:00 2001 From: Nathan Alo Date: Fri, 26 Mar 2021 15:34:45 +0800 Subject: [PATCH 22/30] remove extra semi colons --- osu.Game/Screens/Edit/Compose/ComposeScreen.cs | 2 +- osu.Game/Screens/Edit/Compose/SelectionHelper.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/ComposeScreen.cs b/osu.Game/Screens/Edit/Compose/ComposeScreen.cs index c63ef11c74..b249ae9bcd 100644 --- a/osu.Game/Screens/Edit/Compose/ComposeScreen.cs +++ b/osu.Game/Screens/Edit/Compose/ComposeScreen.cs @@ -87,7 +87,7 @@ namespace osu.Game.Screens.Edit.Compose return false; default: return false; - }; + } } public void OnReleased(PlatformAction action) diff --git a/osu.Game/Screens/Edit/Compose/SelectionHelper.cs b/osu.Game/Screens/Edit/Compose/SelectionHelper.cs index 39d6d57a2a..2e172c12dc 100644 --- a/osu.Game/Screens/Edit/Compose/SelectionHelper.cs +++ b/osu.Game/Screens/Edit/Compose/SelectionHelper.cs @@ -39,7 +39,7 @@ namespace osu.Game.Screens.Edit.Compose { builder.Append($"{clock.CurrentTime.ToEditorFormattedString()}{separator}"); return builder.ToString(); - }; + } builder.Append(editorBeatmap.SelectedHitObjects.First().StartTime.ToEditorFormattedString()); builder.Append($" ({string.Join(',', composer.ConvertSelectionToString())}){separator}"); From 1b6e08b3eb34f80afc5126c2af1efb7ba16d8d19 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 26 Mar 2021 10:35:46 +0300 Subject: [PATCH 23/30] Fix incorrect default font overlap for score and combo --- osu.Game/Skinning/LegacySkinExtensions.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Skinning/LegacySkinExtensions.cs b/osu.Game/Skinning/LegacySkinExtensions.cs index d08f50bccb..d8fb1fa664 100644 --- a/osu.Game/Skinning/LegacySkinExtensions.cs +++ b/osu.Game/Skinning/LegacySkinExtensions.cs @@ -97,10 +97,10 @@ namespace osu.Game.Skinning switch (font) { case LegacyFont.Score: - return source.GetConfig(LegacySetting.ScoreOverlap)?.Value ?? -2f; + return source.GetConfig(LegacySetting.ScoreOverlap)?.Value ?? 0f; case LegacyFont.Combo: - return source.GetConfig(LegacySetting.ComboOverlap)?.Value ?? -2f; + return source.GetConfig(LegacySetting.ComboOverlap)?.Value ?? 0f; case LegacyFont.HitCircle: return source.GetConfig(LegacySetting.HitCircleOverlap)?.Value ?? -2f; From c96321206a0e5157d8864e5d84204706f918ce30 Mon Sep 17 00:00:00 2001 From: Nathan Alo Date: Fri, 26 Mar 2021 16:17:24 +0800 Subject: [PATCH 24/30] fix appveyor complaints --- osu.Game/Screens/Edit/Compose/ComposeScreen.cs | 3 ++- osu.Game/Screens/Edit/Editor.cs | 6 +----- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/ComposeScreen.cs b/osu.Game/Screens/Edit/Compose/ComposeScreen.cs index b249ae9bcd..16043ff64b 100644 --- a/osu.Game/Screens/Edit/Compose/ComposeScreen.cs +++ b/osu.Game/Screens/Edit/Compose/ComposeScreen.cs @@ -23,7 +23,7 @@ namespace osu.Game.Screens.Edit.Compose private HitObjectComposer composer; - private SelectionHelper helper; + private readonly SelectionHelper helper; public ComposeScreen() : base(EditorScreenMode.Compose) @@ -85,6 +85,7 @@ namespace osu.Game.Screens.Edit.Compose case PlatformActionType.Copy: helper.CopySelectionToClipboard(); return false; + default: return false; } diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index c2a9fd49b1..d9ba12d331 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -5,7 +5,6 @@ using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; -using System.Text; using osu.Framework; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -17,12 +16,10 @@ using osu.Framework.Input; using osu.Framework.Input.Bindings; using osu.Framework.Input.Events; using osu.Framework.Logging; -using osu.Framework.Platform; using osu.Framework.Screens; using osu.Framework.Timing; using osu.Game.Beatmaps; using osu.Game.Configuration; -using osu.Game.Extensions; using osu.Game.Graphics; using osu.Game.Graphics.Cursor; using osu.Game.Graphics.UserInterface; @@ -31,7 +28,6 @@ using osu.Game.IO.Serialization; using osu.Game.Online.API; using osu.Game.Overlays; using osu.Game.Rulesets.Edit; -using osu.Game.Rulesets.Objects.Types; using osu.Game.Screens.Edit.Components; using osu.Game.Screens.Edit.Components.Menus; using osu.Game.Screens.Edit.Components.Timelines.Summary; @@ -107,7 +103,7 @@ namespace osu.Game.Screens.Edit private MusicController music { get; set; } [BackgroundDependencyLoader] - private void load(OsuColour colours, GameHost host, OsuConfigManager config) + private void load(OsuColour colours, OsuConfigManager config) { if (Beatmap.Value is DummyWorkingBeatmap) { From 21398e25b5b939ae40e15be42bb6ffb93365d315 Mon Sep 17 00:00:00 2001 From: Nathan Alo Date: Sat, 27 Mar 2021 10:02:21 +0800 Subject: [PATCH 25/30] null check composer and ensure the correct start time from selected hit objects --- osu.Game/Screens/Edit/Compose/SelectionHelper.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/SelectionHelper.cs b/osu.Game/Screens/Edit/Compose/SelectionHelper.cs index 2e172c12dc..a01a9e0144 100644 --- a/osu.Game/Screens/Edit/Compose/SelectionHelper.cs +++ b/osu.Game/Screens/Edit/Compose/SelectionHelper.cs @@ -41,8 +41,10 @@ namespace osu.Game.Screens.Edit.Compose return builder.ToString(); } - builder.Append(editorBeatmap.SelectedHitObjects.First().StartTime.ToEditorFormattedString()); - builder.Append($" ({string.Join(',', composer.ConvertSelectionToString())}){separator}"); + string hitObjects = composer != null ? string.Join(',', composer.ConvertSelectionToString()) : string.Empty; + + builder.Append(editorBeatmap.SelectedHitObjects.Min(h => h.StartTime).ToEditorFormattedString()); + builder.Append($" ({hitObjects}){separator}"); return builder.ToString(); } } From 699a317b445ff557163d91143682ab6f6c5faf8d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 29 Mar 2021 18:07:47 +0900 Subject: [PATCH 26/30] Fix chat scroll sticking visually when scrolling beyond bottom extent --- osu.Game/Overlays/Chat/DrawableChannel.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Chat/DrawableChannel.cs b/osu.Game/Overlays/Chat/DrawableChannel.cs index 86ce724390..5f9c00b36a 100644 --- a/osu.Game/Overlays/Chat/DrawableChannel.cs +++ b/osu.Game/Overlays/Chat/DrawableChannel.cs @@ -275,7 +275,8 @@ namespace osu.Game.Overlays.Chat { if (!UserScrolling) { - ScrollToEnd(); + if (Current < ScrollableExtent) + ScrollToEnd(); lastExtent = ScrollableExtent; } }); From 9a02f3868c2105e51dbd7e64ce4443d08938d02e Mon Sep 17 00:00:00 2001 From: Nathan Alo Date: Mon, 29 Mar 2021 17:29:05 +0800 Subject: [PATCH 27/30] return a string instead --- osu.Game.Rulesets.Mania/Edit/ManiaHitObjectComposer.cs | 4 ++-- osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs | 4 ++-- osu.Game/Rulesets/Edit/HitObjectComposer.cs | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Edit/ManiaHitObjectComposer.cs b/osu.Game.Rulesets.Mania/Edit/ManiaHitObjectComposer.cs index 4cb34a217c..d9570bf8be 100644 --- a/osu.Game.Rulesets.Mania/Edit/ManiaHitObjectComposer.cs +++ b/osu.Game.Rulesets.Mania/Edit/ManiaHitObjectComposer.cs @@ -120,7 +120,7 @@ namespace osu.Game.Rulesets.Mania.Edit } } - public override IEnumerable ConvertSelectionToString() - => EditorBeatmap.SelectedHitObjects.Cast().Select(h => $"{h.StartTime}|{h.Column}"); + public override string ConvertSelectionToString() + => string.Join(',', EditorBeatmap.SelectedHitObjects.Cast().OrderBy(h => h.StartTime).Select(h => $"{h.StartTime}|{h.Column}")); } } diff --git a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs index 1943f52c73..396fd41377 100644 --- a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs +++ b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs @@ -82,8 +82,8 @@ namespace osu.Game.Rulesets.Osu.Edit protected override ComposeBlueprintContainer CreateBlueprintContainer() => new OsuBlueprintContainer(this); - public override IEnumerable ConvertSelectionToString() - => selectedHitObjects.Cast().Select(h => (h.IndexInCurrentCombo + 1).ToString()); + public override string ConvertSelectionToString() + => string.Join(',', selectedHitObjects.Cast().OrderBy(h => h.StartTime).Select(h => (h.IndexInCurrentCombo + 1).ToString())); private DistanceSnapGrid distanceSnapGrid; private Container distanceSnapGridContainer; diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs index eee16043e4..736fc47dee 100644 --- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs @@ -438,7 +438,7 @@ namespace osu.Game.Rulesets.Edit /// public abstract bool CursorInPlacementArea { get; } - public virtual IEnumerable ConvertSelectionToString() => Array.Empty(); + public virtual string ConvertSelectionToString() => string.Empty; #region IPositionSnapProvider From cdb779f764bb09dcba1784f66fc87aab9debfd8b Mon Sep 17 00:00:00 2001 From: Nathan Alo Date: Mon, 29 Mar 2021 17:30:23 +0800 Subject: [PATCH 28/30] move copy logic inside ComposeScreen --- .../Screens/Edit/Compose/ComposeScreen.cs | 37 ++++++++++---- .../Screens/Edit/Compose/SelectionHelper.cs | 51 ------------------- 2 files changed, 26 insertions(+), 62 deletions(-) delete mode 100644 osu.Game/Screens/Edit/Compose/SelectionHelper.cs diff --git a/osu.Game/Screens/Edit/Compose/ComposeScreen.cs b/osu.Game/Screens/Edit/Compose/ComposeScreen.cs index 16043ff64b..f6ce5a4e3d 100644 --- a/osu.Game/Screens/Edit/Compose/ComposeScreen.cs +++ b/osu.Game/Screens/Edit/Compose/ComposeScreen.cs @@ -2,13 +2,17 @@ // See the LICENCE file in the repository root for full licence text. using System.Diagnostics; +using System.Linq; +using System.Text; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Input; using osu.Framework.Input.Bindings; +using osu.Framework.Platform; using osu.Game.Beatmaps; +using osu.Game.Extensions; using osu.Game.Rulesets; using osu.Game.Rulesets.Edit; using osu.Game.Screens.Edit.Compose.Components.Timeline; @@ -21,14 +25,17 @@ namespace osu.Game.Screens.Edit.Compose [Resolved] private IBindable beatmap { get; set; } - private HitObjectComposer composer; + [Resolved] + private GameHost host { get; set; } - private readonly SelectionHelper helper; + [Resolved] + private EditorClock clock { get; set; } + + private HitObjectComposer composer; public ComposeScreen() : base(EditorScreenMode.Compose) { - Add(helper = new SelectionHelper()); } private Ruleset ruleset; @@ -78,17 +85,25 @@ namespace osu.Game.Screens.Edit.Compose return beatmapSkinProvider.WithChild(rulesetSkinProvider.WithChild(content)); } + private string formatSelectionAsString() + { + var builder = new StringBuilder(); + builder.Append(EditorBeatmap.SelectedHitObjects.OrderBy(h => h.StartTime).FirstOrDefault()?.StartTime.ToEditorFormattedString() ?? clock.CurrentTime.ToEditorFormattedString()); + + if (EditorBeatmap.SelectedHitObjects.Any() && composer != null) + builder.Append($" ({composer.ConvertSelectionToString()})"); + + builder.Append(" - "); + + return builder.ToString(); + } + public bool OnPressed(PlatformAction action) { - switch (action.ActionType) - { - case PlatformActionType.Copy: - helper.CopySelectionToClipboard(); - return false; + if (action.ActionType == PlatformActionType.Copy) + host.GetClipboard().SetText(formatSelectionAsString()); - default: - return false; - } + return false; } public void OnReleased(PlatformAction action) diff --git a/osu.Game/Screens/Edit/Compose/SelectionHelper.cs b/osu.Game/Screens/Edit/Compose/SelectionHelper.cs deleted file mode 100644 index a01a9e0144..0000000000 --- a/osu.Game/Screens/Edit/Compose/SelectionHelper.cs +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using System.Linq; -using System.Text; -using osu.Framework.Allocation; -using osu.Framework.Graphics; -using osu.Framework.Platform; -using osu.Game.Extensions; -using osu.Game.Rulesets.Edit; - -namespace osu.Game.Screens.Edit.Compose -{ - public class SelectionHelper : Component - { - [Resolved] - private GameHost host { get; set; } - - [Resolved] - private EditorClock clock { get; set; } - - [Resolved] - private EditorBeatmap editorBeatmap { get; set; } - - [Resolved(CanBeNull = true)] - private HitObjectComposer composer { get; set; } - - public void CopySelectionToClipboard() - { - host.GetClipboard().SetText(formatSelectionAsString()); - } - - private string formatSelectionAsString() - { - const string separator = " - "; - var builder = new StringBuilder(); - - if (!editorBeatmap.SelectedHitObjects.Any()) - { - builder.Append($"{clock.CurrentTime.ToEditorFormattedString()}{separator}"); - return builder.ToString(); - } - - string hitObjects = composer != null ? string.Join(',', composer.ConvertSelectionToString()) : string.Empty; - - builder.Append(editorBeatmap.SelectedHitObjects.Min(h => h.StartTime).ToEditorFormattedString()); - builder.Append($" ({hitObjects}){separator}"); - return builder.ToString(); - } - } -} From 90ab765cf519be8be956175f492f3c7aff4e0f0e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 29 Mar 2021 18:46:32 +0900 Subject: [PATCH 29/30] Reorder methods and surround with region --- .../Screens/Edit/Compose/ComposeScreen.cs | 26 +++++++++++-------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/ComposeScreen.cs b/osu.Game/Screens/Edit/Compose/ComposeScreen.cs index f6ce5a4e3d..1d52cc60fd 100644 --- a/osu.Game/Screens/Edit/Compose/ComposeScreen.cs +++ b/osu.Game/Screens/Edit/Compose/ComposeScreen.cs @@ -85,6 +85,20 @@ namespace osu.Game.Screens.Edit.Compose return beatmapSkinProvider.WithChild(rulesetSkinProvider.WithChild(content)); } + #region Input Handling + + public bool OnPressed(PlatformAction action) + { + if (action.ActionType == PlatformActionType.Copy) + host.GetClipboard().SetText(formatSelectionAsString()); + + return false; + } + + public void OnReleased(PlatformAction action) + { + } + private string formatSelectionAsString() { var builder = new StringBuilder(); @@ -98,16 +112,6 @@ namespace osu.Game.Screens.Edit.Compose return builder.ToString(); } - public bool OnPressed(PlatformAction action) - { - if (action.ActionType == PlatformActionType.Copy) - host.GetClipboard().SetText(formatSelectionAsString()); - - return false; - } - - public void OnReleased(PlatformAction action) - { - } + #endregion } } From 3909eda095ce5f6fcfdc7afa7e3ea4fdaf826540 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 29 Mar 2021 18:51:28 +0900 Subject: [PATCH 30/30] Avoid using a StringBuilder --- osu.Game/Screens/Edit/Compose/ComposeScreen.cs | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/ComposeScreen.cs b/osu.Game/Screens/Edit/Compose/ComposeScreen.cs index 1d52cc60fd..61056aeced 100644 --- a/osu.Game/Screens/Edit/Compose/ComposeScreen.cs +++ b/osu.Game/Screens/Edit/Compose/ComposeScreen.cs @@ -3,7 +3,6 @@ using System.Diagnostics; using System.Linq; -using System.Text; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -101,15 +100,15 @@ namespace osu.Game.Screens.Edit.Compose private string formatSelectionAsString() { - var builder = new StringBuilder(); - builder.Append(EditorBeatmap.SelectedHitObjects.OrderBy(h => h.StartTime).FirstOrDefault()?.StartTime.ToEditorFormattedString() ?? clock.CurrentTime.ToEditorFormattedString()); + if (composer == null) + return string.Empty; - if (EditorBeatmap.SelectedHitObjects.Any() && composer != null) - builder.Append($" ({composer.ConvertSelectionToString()})"); + double displayTime = EditorBeatmap.SelectedHitObjects.OrderBy(h => h.StartTime).FirstOrDefault()?.StartTime ?? clock.CurrentTime; + string selectionAsString = composer.ConvertSelectionToString(); - builder.Append(" - "); - - return builder.ToString(); + return !string.IsNullOrEmpty(selectionAsString) + ? $"{displayTime.ToEditorFormattedString()} ({selectionAsString}) - " + : $"{displayTime.ToEditorFormattedString()} - "; } #endregion