From 9f24cdb355bff38f788c6b2cb6e1f8bfce0b7e5b Mon Sep 17 00:00:00 2001 From: Denrage Date: Mon, 19 Apr 2021 16:53:44 +0200 Subject: [PATCH 01/19] Added Author Link in BeatmapInfoWedge --- osu.Game/Screens/Select/BeatmapInfoWedge.cs | 29 +++++++++------------ 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs index 4069dc82ed..14e5831ef9 100644 --- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs +++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs @@ -29,6 +29,7 @@ using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.UI; using osu.Game.Screens.Ranking.Expanded; +using osu.Game.Graphics.Containers; namespace osu.Game.Screens.Select { @@ -307,7 +308,7 @@ namespace osu.Game.Screens.Select Margin = new MarginPadding { Top = 10 }, Direction = FillDirection.Horizontal, AutoSizeAxes = Axes.Both, - Children = getMapper(metadata) + Children = new[] { getMapper(metadata) }, }, infoLabelContainer = new FillFlowContainer { @@ -430,24 +431,20 @@ namespace osu.Game.Screens.Select ForceRedraw(); } - private OsuSpriteText[] getMapper(BeatmapMetadata metadata) + private LinkFlowContainer getMapper(BeatmapMetadata metadata) { - if (string.IsNullOrEmpty(metadata.Author?.Username)) - return Array.Empty(); + if (metadata.Author == null) + return new LinkFlowContainer(); - return new[] + return new LinkFlowContainer(s => { - new OsuSpriteText - { - Text = "mapped by ", - Font = OsuFont.GetFont(size: 15), - }, - new OsuSpriteText - { - Text = metadata.Author.Username, - Font = OsuFont.GetFont(weight: FontWeight.Bold, size: 15), - } - }; + s.Font = OsuFont.GetFont(weight: FontWeight.Bold, size: 15); + }).With(d => + { + d.AutoSizeAxes = Axes.Both; + d.AddText("mapped by "); + d.AddUserLink(metadata.Author); + }); } protected override void Dispose(bool isDisposing) From eb977312ed71bee57676714afb2a81c0522bdd9d Mon Sep 17 00:00:00 2001 From: Denrage Date: Mon, 19 Apr 2021 16:54:29 +0200 Subject: [PATCH 02/19] Added Author link in BeatmapSet Overlay --- osu.Game/Overlays/BeatmapSet/AuthorInfo.cs | 23 +++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/BeatmapSet/AuthorInfo.cs b/osu.Game/Overlays/BeatmapSet/AuthorInfo.cs index 31c1439c8f..1ffcf9722a 100644 --- a/osu.Game/Overlays/BeatmapSet/AuthorInfo.cs +++ b/osu.Game/Overlays/BeatmapSet/AuthorInfo.cs @@ -13,6 +13,8 @@ using osuTK.Graphics; using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Sprites; using osu.Game.Graphics; +using osu.Game.Users; +using osu.Game.Graphics.Containers; namespace osu.Game.Overlays.BeatmapSet { @@ -50,7 +52,7 @@ namespace osu.Game.Overlays.BeatmapSet fields.Children = new Drawable[] { - new Field("mapped by", BeatmapSet.Metadata.Author.Username, OsuFont.GetFont(weight: FontWeight.Regular, italics: true)), + new Field("mapped by", BeatmapSet.Metadata.Author, OsuFont.GetFont(weight: FontWeight.Regular, italics: true)), new Field("submitted", online.Submitted, OsuFont.GetFont(weight: FontWeight.Bold)) { Margin = new MarginPadding { Top = 5 }, @@ -146,6 +148,25 @@ namespace osu.Game.Overlays.BeatmapSet } }; } + + public Field(string first, User second, FontUsage secondFont) + { + AutoSizeAxes = Axes.Both; + Direction = FillDirection.Horizontal; + + Children = new[] + { + new LinkFlowContainer(s => + { + s.Font = OsuFont.GetFont(size: 11); + }).With(d => + { + d.AutoSizeAxes = Axes.Both; + d.AddText($"{first} "); + d.AddUserLink(second, s => s.Font = secondFont.With(size: 11)); + }), + }; + } } } } From 6bf6084ae9c3129d8a5672946e33205e8eabfcd3 Mon Sep 17 00:00:00 2001 From: Denrage Date: Mon, 19 Apr 2021 19:24:46 +0200 Subject: [PATCH 03/19] fixed according to suggestions --- osu.Game/Screens/Select/BeatmapInfoWedge.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs index 14e5831ef9..deb77c27de 100644 --- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs +++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs @@ -308,7 +308,7 @@ namespace osu.Game.Screens.Select Margin = new MarginPadding { Top = 10 }, Direction = FillDirection.Horizontal, AutoSizeAxes = Axes.Both, - Children = new[] { getMapper(metadata) }, + Child = getMapper(metadata), }, infoLabelContainer = new FillFlowContainer { @@ -431,10 +431,10 @@ namespace osu.Game.Screens.Select ForceRedraw(); } - private LinkFlowContainer getMapper(BeatmapMetadata metadata) + private Drawable getMapper(BeatmapMetadata metadata) { if (metadata.Author == null) - return new LinkFlowContainer(); + return Empty(); return new LinkFlowContainer(s => { From c73bbf0aa7566c1bf33784caacb91fc786a7a2cc Mon Sep 17 00:00:00 2001 From: Denrage Date: Mon, 19 Apr 2021 19:24:58 +0200 Subject: [PATCH 04/19] Fixed Tests --- osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapInfoWedge.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapInfoWedge.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapInfoWedge.cs index 7ea6373763..16afc5ace7 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapInfoWedge.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapInfoWedge.cs @@ -107,7 +107,7 @@ namespace osu.Game.Tests.Visual.SongSelect AddAssert("check version", () => infoWedge.Info.VersionLabel.Current.Value == $"{ruleset.ShortName}Version"); AddAssert("check title", () => infoWedge.Info.TitleLabel.Current.Value == $"{ruleset.ShortName}Source — {ruleset.ShortName}Title"); AddAssert("check artist", () => infoWedge.Info.ArtistLabel.Current.Value == $"{ruleset.ShortName}Artist"); - AddAssert("check author", () => infoWedge.Info.MapperContainer.Children.OfType().Any(s => s.Current.Value == $"{ruleset.ShortName}Author")); + AddAssert("check author", () => infoWedge.Info.MapperContainer.ChildrenOfType().Any(s => s.Current.Value == $"{ruleset.ShortName}Author")); } private void testInfoLabels(int expectedCount) @@ -123,7 +123,7 @@ namespace osu.Game.Tests.Visual.SongSelect AddAssert("check empty version", () => string.IsNullOrEmpty(infoWedge.Info.VersionLabel.Current.Value)); AddAssert("check default title", () => infoWedge.Info.TitleLabel.Current.Value == Beatmap.Default.BeatmapInfo.Metadata.Title); AddAssert("check default artist", () => infoWedge.Info.ArtistLabel.Current.Value == Beatmap.Default.BeatmapInfo.Metadata.Artist); - AddAssert("check empty author", () => !infoWedge.Info.MapperContainer.Children.Any()); + AddAssert("check empty author", () => !infoWedge.Info.MapperContainer.ChildrenOfType().Any()); AddAssert("check no info labels", () => !infoWedge.Info.ChildrenOfType().Any()); } From 39067e6926e0950303e137140dded1f2eb2f5dd7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 6 May 2021 17:19:18 +0900 Subject: [PATCH 05/19] Fix slider input handling potentially being offset after composer area resize Closes https://github.com/ppy/osu/issues/12671. --- .../Edit/Blueprints/Sliders/Components/SliderBodyPiece.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/SliderBodyPiece.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/SliderBodyPiece.cs index 1c3d270c95..6e22c35ab3 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/SliderBodyPiece.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/SliderBodyPiece.cs @@ -26,6 +26,10 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components { AccentColour = Color4.Transparent }; + + // SliderSelectionBlueprint relies on calling ReceivePositionalInputAt on this drawable to determine whether selection should occur. + // Without AlwaysPresent, a movement in a parent container (ie. the editor composer area resizing) could cause incorrect input handling. + AlwaysPresent = true; } [BackgroundDependencyLoader] From 54fe10c82a855a16c88f8781a9ae12dc42df7b0e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 7 May 2021 10:36:03 +0900 Subject: [PATCH 06/19] Refactor `SliderSelectionBlueprint` to not reference blueprint pieces for input handling --- .../Edit/Blueprints/Sliders/Components/SliderBodyPiece.cs | 6 ------ .../Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs | 4 ++-- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/SliderBodyPiece.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/SliderBodyPiece.cs index 6e22c35ab3..ece9c7a757 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/SliderBodyPiece.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/SliderBodyPiece.cs @@ -26,10 +26,6 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components { AccentColour = Color4.Transparent }; - - // SliderSelectionBlueprint relies on calling ReceivePositionalInputAt on this drawable to determine whether selection should occur. - // Without AlwaysPresent, a movement in a parent container (ie. the editor composer area resizing) could cause incorrect input handling. - AlwaysPresent = true; } [BackgroundDependencyLoader] @@ -54,7 +50,5 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components } public void RecyclePath() => body.RecyclePath(); - - public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => body.ReceivePositionalInputAt(screenSpacePos); } } diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs index 88fcb1e715..32d2fba25e 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs @@ -240,10 +240,10 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders new OsuMenuItem("Add control point", MenuItemType.Standard, () => addControlPoint(rightClickPosition)), }; - public override Vector2 ScreenSpaceSelectionPoint => BodyPiece.ToScreenSpace(BodyPiece.PathStartLocation); + public override Vector2 ScreenSpaceSelectionPoint => this.ToScreenSpace(slider.HitObject.StackedPosition); public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => - BodyPiece.ReceivePositionalInputAt(screenSpacePos) || ControlPointVisualiser?.Pieces.Any(p => p.ReceivePositionalInputAt(screenSpacePos)) == true; + slider.ReceivePositionalInputAt(screenSpacePos) || ControlPointVisualiser?.Pieces.Any(p => p.ReceivePositionalInputAt(screenSpacePos)) == true; protected virtual SliderCircleSelectionBlueprint CreateCircleSelectionBlueprint(DrawableSlider slider, SliderPosition position) => new SliderCircleSelectionBlueprint(slider, position); } From 84da24700204724cde9a8b90506b078add49c964 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 7 May 2021 05:32:55 +0300 Subject: [PATCH 07/19] Fix editor clock using the wrong beatmap track on creation --- osu.Game/Screens/Edit/Editor.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index da0e9ebbaf..138d8cfaff 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -145,7 +145,7 @@ namespace osu.Game.Screens.Edit // Todo: should probably be done at a DrawableRuleset level to share logic with Player. clock = new EditorClock(playableBeatmap, beatDivisor) { IsCoupled = false }; - UpdateClockSource(); + updateClockSource(loadableBeatmap); dependencies.CacheAs(clock); AddInternal(clock); @@ -308,9 +308,11 @@ namespace osu.Game.Screens.Edit /// /// If the beatmap's track has changed, this method must be called to keep the editor in a valid state. /// - public void UpdateClockSource() + public void UpdateClockSource() => updateClockSource(Beatmap.Value); + + private void updateClockSource(WorkingBeatmap beatmap) { - var sourceClock = (IAdjustableClock)Beatmap.Value.Track ?? new StopwatchClock(); + var sourceClock = (IAdjustableClock)beatmap.Track ?? new StopwatchClock(); clock.ChangeSource(sourceClock); } From 539643c72b390b1c40b8fb8340b37f33ef91d7d5 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 7 May 2021 07:18:43 +0300 Subject: [PATCH 08/19] Set loadable beatmap track to clock immediately in BDL This reverts commit 84da24700204724cde9a8b90506b078add49c964. Use loadable beatmap track for clock directly in BDL --- osu.Game/Screens/Edit/Editor.cs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 138d8cfaff..a4c331c4e0 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -144,8 +144,7 @@ namespace osu.Game.Screens.Edit // Todo: should probably be done at a DrawableRuleset level to share logic with Player. clock = new EditorClock(playableBeatmap, beatDivisor) { IsCoupled = false }; - - updateClockSource(loadableBeatmap); + clock.ChangeSource(loadableBeatmap.Track); dependencies.CacheAs(clock); AddInternal(clock); @@ -308,11 +307,9 @@ namespace osu.Game.Screens.Edit /// /// If the beatmap's track has changed, this method must be called to keep the editor in a valid state. /// - public void UpdateClockSource() => updateClockSource(Beatmap.Value); - - private void updateClockSource(WorkingBeatmap beatmap) + public void UpdateClockSource() { - var sourceClock = (IAdjustableClock)beatmap.Track ?? new StopwatchClock(); + var sourceClock = (IAdjustableClock)Beatmap.Value.Track ?? new StopwatchClock(); clock.ChangeSource(sourceClock); } From f9d99a98826525b58d8a076f772da6a9a77329ec Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 7 May 2021 07:25:14 +0300 Subject: [PATCH 09/19] Mark `WorkingBeatmap.Track` as not null --- osu.Game/Beatmaps/WorkingBeatmap.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index e0eeaf6db0..bef258753e 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -298,6 +298,7 @@ namespace osu.Game.Beatmaps /// Get the loaded audio track instance. must have first been called. /// This generally happens via MusicController when changing the global beatmap. /// + [NotNull] public Track Track { get From 71547bece0dcd99cfbe6ba95bd2e42066b6eb686 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 7 May 2021 07:43:06 +0300 Subject: [PATCH 10/19] Remove any null-coalescing/conditionals in `WorkingBeatmap.Track` usages --- osu.Game/Screens/Edit/Editor.cs | 9 ++------- osu.Game/Tests/Visual/EditorClockTestScene.cs | 3 +-- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index a4c331c4e0..434683a016 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -17,7 +17,6 @@ using osu.Framework.Input.Bindings; using osu.Framework.Input.Events; using osu.Framework.Logging; using osu.Framework.Screens; -using osu.Framework.Timing; using osu.Game.Beatmaps; using osu.Game.Configuration; using osu.Game.Graphics; @@ -307,11 +306,7 @@ namespace osu.Game.Screens.Edit /// /// If the beatmap's track has changed, this method must be called to keep the editor in a valid state. /// - public void UpdateClockSource() - { - var sourceClock = (IAdjustableClock)Beatmap.Value.Track ?? new StopwatchClock(); - clock.ChangeSource(sourceClock); - } + public void UpdateClockSource() => clock.ChangeSource(Beatmap.Value.Track); protected void Save() { @@ -582,7 +577,7 @@ namespace osu.Game.Screens.Edit private void resetTrack(bool seekToStart = false) { - Beatmap.Value.Track?.Stop(); + Beatmap.Value.Track.Stop(); if (seekToStart) { diff --git a/osu.Game/Tests/Visual/EditorClockTestScene.cs b/osu.Game/Tests/Visual/EditorClockTestScene.cs index 79cfee8518..34393fba7d 100644 --- a/osu.Game/Tests/Visual/EditorClockTestScene.cs +++ b/osu.Game/Tests/Visual/EditorClockTestScene.cs @@ -4,7 +4,6 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Input.Events; -using osu.Framework.Timing; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Screens.Edit; @@ -46,7 +45,7 @@ namespace osu.Game.Tests.Visual private void beatmapChanged(ValueChangedEvent e) { Clock.ControlPointInfo = e.NewValue.Beatmap.ControlPointInfo; - Clock.ChangeSource((IAdjustableClock)e.NewValue.Track ?? new StopwatchClock()); + Clock.ChangeSource(e.NewValue.Track); Clock.ProcessFrame(); } From 37f44d2e37602ec557ed7fda6ca7afced0bfec81 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 7 May 2021 08:27:56 +0300 Subject: [PATCH 11/19] Revert wrong not-null track changes This reverts commit f9d99a98826525b58d8a076f772da6a9a77329ec. This reverts commit 71547bece0dcd99cfbe6ba95bd2e42066b6eb686. --- osu.Game/Beatmaps/WorkingBeatmap.cs | 1 - osu.Game/Screens/Edit/Editor.cs | 9 +++++++-- osu.Game/Tests/Visual/EditorClockTestScene.cs | 3 ++- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index bef258753e..e0eeaf6db0 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -298,7 +298,6 @@ namespace osu.Game.Beatmaps /// Get the loaded audio track instance. must have first been called. /// This generally happens via MusicController when changing the global beatmap. /// - [NotNull] public Track Track { get diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 434683a016..a4c331c4e0 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -17,6 +17,7 @@ using osu.Framework.Input.Bindings; using osu.Framework.Input.Events; using osu.Framework.Logging; using osu.Framework.Screens; +using osu.Framework.Timing; using osu.Game.Beatmaps; using osu.Game.Configuration; using osu.Game.Graphics; @@ -306,7 +307,11 @@ namespace osu.Game.Screens.Edit /// /// If the beatmap's track has changed, this method must be called to keep the editor in a valid state. /// - public void UpdateClockSource() => clock.ChangeSource(Beatmap.Value.Track); + public void UpdateClockSource() + { + var sourceClock = (IAdjustableClock)Beatmap.Value.Track ?? new StopwatchClock(); + clock.ChangeSource(sourceClock); + } protected void Save() { @@ -577,7 +582,7 @@ namespace osu.Game.Screens.Edit private void resetTrack(bool seekToStart = false) { - Beatmap.Value.Track.Stop(); + Beatmap.Value.Track?.Stop(); if (seekToStart) { diff --git a/osu.Game/Tests/Visual/EditorClockTestScene.cs b/osu.Game/Tests/Visual/EditorClockTestScene.cs index 34393fba7d..79cfee8518 100644 --- a/osu.Game/Tests/Visual/EditorClockTestScene.cs +++ b/osu.Game/Tests/Visual/EditorClockTestScene.cs @@ -4,6 +4,7 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Input.Events; +using osu.Framework.Timing; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Screens.Edit; @@ -45,7 +46,7 @@ namespace osu.Game.Tests.Visual private void beatmapChanged(ValueChangedEvent e) { Clock.ControlPointInfo = e.NewValue.Beatmap.ControlPointInfo; - Clock.ChangeSource(e.NewValue.Track); + Clock.ChangeSource((IAdjustableClock)e.NewValue.Track ?? new StopwatchClock()); Clock.ProcessFrame(); } From b1134c3857980e5f473dc3ba3f57d1ab7bdcabdb Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 7 May 2021 08:30:50 +0300 Subject: [PATCH 12/19] Guard against potentially null track if ever --- osu.Game/Screens/Edit/Editor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index a4c331c4e0..78d5c24108 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -144,7 +144,7 @@ namespace osu.Game.Screens.Edit // Todo: should probably be done at a DrawableRuleset level to share logic with Player. clock = new EditorClock(playableBeatmap, beatDivisor) { IsCoupled = false }; - clock.ChangeSource(loadableBeatmap.Track); + clock.ChangeSource((IAdjustableClock)loadableBeatmap.Track ?? new StopwatchClock()); dependencies.CacheAs(clock); AddInternal(clock); From 7c4e54a1d43990996e015affd03911514dc18952 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 7 May 2021 09:53:54 +0300 Subject: [PATCH 13/19] Unrevert null-colaescing/conditionals removal --- osu.Game/Screens/Edit/Editor.cs | 8 ++------ osu.Game/Tests/Visual/EditorClockTestScene.cs | 3 +-- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 78d5c24108..50dcb84235 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -307,11 +307,7 @@ namespace osu.Game.Screens.Edit /// /// If the beatmap's track has changed, this method must be called to keep the editor in a valid state. /// - public void UpdateClockSource() - { - var sourceClock = (IAdjustableClock)Beatmap.Value.Track ?? new StopwatchClock(); - clock.ChangeSource(sourceClock); - } + public void UpdateClockSource() => clock.ChangeSource(Beatmap.Value.Track); protected void Save() { @@ -582,7 +578,7 @@ namespace osu.Game.Screens.Edit private void resetTrack(bool seekToStart = false) { - Beatmap.Value.Track?.Stop(); + Beatmap.Value.Track.Stop(); if (seekToStart) { diff --git a/osu.Game/Tests/Visual/EditorClockTestScene.cs b/osu.Game/Tests/Visual/EditorClockTestScene.cs index 79cfee8518..34393fba7d 100644 --- a/osu.Game/Tests/Visual/EditorClockTestScene.cs +++ b/osu.Game/Tests/Visual/EditorClockTestScene.cs @@ -4,7 +4,6 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Input.Events; -using osu.Framework.Timing; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Screens.Edit; @@ -46,7 +45,7 @@ namespace osu.Game.Tests.Visual private void beatmapChanged(ValueChangedEvent e) { Clock.ControlPointInfo = e.NewValue.Beatmap.ControlPointInfo; - Clock.ChangeSource((IAdjustableClock)e.NewValue.Track ?? new StopwatchClock()); + Clock.ChangeSource(e.NewValue.Track); Clock.ProcessFrame(); } From fc2a527e9d419040697cd4e075c7ae04d1cd2c82 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 7 May 2021 09:54:58 +0300 Subject: [PATCH 14/19] Revert "Guard against potentially null track if ever" This reverts commit b1134c3857980e5f473dc3ba3f57d1ab7bdcabdb. --- osu.Game/Screens/Edit/Editor.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 50dcb84235..434683a016 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -17,7 +17,6 @@ using osu.Framework.Input.Bindings; using osu.Framework.Input.Events; using osu.Framework.Logging; using osu.Framework.Screens; -using osu.Framework.Timing; using osu.Game.Beatmaps; using osu.Game.Configuration; using osu.Game.Graphics; @@ -144,7 +143,7 @@ namespace osu.Game.Screens.Edit // Todo: should probably be done at a DrawableRuleset level to share logic with Player. clock = new EditorClock(playableBeatmap, beatDivisor) { IsCoupled = false }; - clock.ChangeSource((IAdjustableClock)loadableBeatmap.Track ?? new StopwatchClock()); + clock.ChangeSource(loadableBeatmap.Track); dependencies.CacheAs(clock); AddInternal(clock); From a2e4fb5b6b0cc7cd97fa439a9e2e1b13dcb6f10e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 7 May 2021 16:10:57 +0900 Subject: [PATCH 15/19] Update `ScoreCounter` components to bind outwards --- .../TestSceneSkinnableScoreCounter.cs | 26 ++++------ .../Graphics/UserInterface/ScoreCounter.cs | 3 +- .../Screens/Play/HUD/DefaultScoreCounter.cs | 3 +- .../Screens/Play/HUD/GameplayScoreCounter.cs | 46 ++++++++++++++++++ osu.Game/Screens/Play/HUD/IScoreCounter.cs | 25 ---------- .../Screens/Play/HUD/SkinnableScoreCounter.cs | 47 +------------------ osu.Game/Screens/Play/HUDOverlay.cs | 1 - osu.Game/Skinning/LegacyScoreCounter.cs | 4 +- 8 files changed, 60 insertions(+), 95 deletions(-) create mode 100644 osu.Game/Screens/Play/HUD/GameplayScoreCounter.cs delete mode 100644 osu.Game/Screens/Play/HUD/IScoreCounter.cs diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableScoreCounter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableScoreCounter.cs index e212ceeba7..4f2183711e 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableScoreCounter.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableScoreCounter.cs @@ -4,10 +4,12 @@ using System.Collections.Generic; using System.Linq; using NUnit.Framework; +using osu.Framework.Allocation; using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Testing; using osu.Game.Rulesets; using osu.Game.Rulesets.Osu; +using osu.Game.Rulesets.Scoring; using osu.Game.Screens.Play.HUD; namespace osu.Game.Tests.Visual.Gameplay @@ -18,37 +20,27 @@ namespace osu.Game.Tests.Visual.Gameplay protected override Ruleset CreateRulesetForSkinProvider() => new OsuRuleset(); + [Cached] + private ScoreProcessor scoreProcessor = new ScoreProcessor(); + [SetUpSteps] public void SetUpSteps() { - AddStep("Create combo counters", () => SetContents(() => - { - var comboCounter = new SkinnableScoreCounter(); - comboCounter.Current.Value = 1; - return comboCounter; - })); + AddStep("Create score counters", () => SetContents(() => new SkinnableScoreCounter())); } [Test] public void TestScoreCounterIncrementing() { - AddStep(@"Reset all", delegate - { - foreach (var s in scoreCounters) - s.Current.Value = 0; - }); + AddStep(@"Reset all", () => scoreProcessor.TotalScore.Value = 0); - AddStep(@"Hit! :D", delegate - { - foreach (var s in scoreCounters) - s.Current.Value += 300; - }); + AddStep(@"Hit! :D", () => scoreProcessor.TotalScore.Value += 300); } [Test] public void TestVeryLargeScore() { - AddStep("set large score", () => scoreCounters.ForEach(counter => counter.Current.Value = 1_000_000_000)); + AddStep("set large score", () => scoreCounters.ForEach(counter => scoreProcessor.TotalScore.Value = 1_000_000_000)); } } } diff --git a/osu.Game/Graphics/UserInterface/ScoreCounter.cs b/osu.Game/Graphics/UserInterface/ScoreCounter.cs index d75e49a4ce..5747c846eb 100644 --- a/osu.Game/Graphics/UserInterface/ScoreCounter.cs +++ b/osu.Game/Graphics/UserInterface/ScoreCounter.cs @@ -4,11 +4,10 @@ using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Game.Graphics.Sprites; -using osu.Game.Screens.Play.HUD; namespace osu.Game.Graphics.UserInterface { - public abstract class ScoreCounter : RollingCounter, IScoreCounter + public abstract class ScoreCounter : RollingCounter { protected override double RollingDuration => 1000; protected override Easing RollingEasing => Easing.Out; diff --git a/osu.Game/Screens/Play/HUD/DefaultScoreCounter.cs b/osu.Game/Screens/Play/HUD/DefaultScoreCounter.cs index 1dcfe2e067..84db605d53 100644 --- a/osu.Game/Screens/Play/HUD/DefaultScoreCounter.cs +++ b/osu.Game/Screens/Play/HUD/DefaultScoreCounter.cs @@ -4,11 +4,10 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Game.Graphics; -using osu.Game.Graphics.UserInterface; namespace osu.Game.Screens.Play.HUD { - public class DefaultScoreCounter : ScoreCounter + public class DefaultScoreCounter : GameplayScoreCounter { public DefaultScoreCounter() : base(6) diff --git a/osu.Game/Screens/Play/HUD/GameplayScoreCounter.cs b/osu.Game/Screens/Play/HUD/GameplayScoreCounter.cs new file mode 100644 index 0000000000..e09630d2c4 --- /dev/null +++ b/osu.Game/Screens/Play/HUD/GameplayScoreCounter.cs @@ -0,0 +1,46 @@ +// 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 osu.Framework.Allocation; +using osu.Framework.Bindables; +using osu.Game.Configuration; +using osu.Game.Graphics.UserInterface; +using osu.Game.Rulesets.Scoring; + +namespace osu.Game.Screens.Play.HUD +{ + public abstract class GameplayScoreCounter : ScoreCounter + { + private Bindable scoreDisplayMode; + + protected GameplayScoreCounter(int leading = 0, bool useCommaSeparator = false) + : base(leading, useCommaSeparator) + { + } + + [BackgroundDependencyLoader] + private void load(OsuConfigManager config, ScoreProcessor scoreProcessor) + { + scoreDisplayMode = config.GetBindable(OsuSetting.ScoreDisplayMode); + scoreDisplayMode.BindValueChanged(scoreMode => + { + switch (scoreMode.NewValue) + { + case ScoringMode.Standardised: + RequiredDisplayDigits.Value = 6; + break; + + case ScoringMode.Classic: + RequiredDisplayDigits.Value = 8; + break; + + default: + throw new ArgumentOutOfRangeException(nameof(scoreMode)); + } + }, true); + + Current.BindTo(scoreProcessor.TotalScore); + } + } +} diff --git a/osu.Game/Screens/Play/HUD/IScoreCounter.cs b/osu.Game/Screens/Play/HUD/IScoreCounter.cs deleted file mode 100644 index 7f5e81d5ef..0000000000 --- a/osu.Game/Screens/Play/HUD/IScoreCounter.cs +++ /dev/null @@ -1,25 +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 osu.Framework.Bindables; -using osu.Framework.Graphics; - -namespace osu.Game.Screens.Play.HUD -{ - /// - /// An interface providing a set of methods to update a score counter. - /// - public interface IScoreCounter : IDrawable - { - /// - /// The current score to be displayed. - /// - Bindable Current { get; } - - /// - /// The number of digits required to display most sane scores. - /// This may be exceeded in very rare cases, but is useful to pad or space the display to avoid it jumping around. - /// - Bindable RequiredDisplayDigits { get; } - } -} diff --git a/osu.Game/Screens/Play/HUD/SkinnableScoreCounter.cs b/osu.Game/Screens/Play/HUD/SkinnableScoreCounter.cs index b46f5684b1..cc9a712e97 100644 --- a/osu.Game/Screens/Play/HUD/SkinnableScoreCounter.cs +++ b/osu.Game/Screens/Play/HUD/SkinnableScoreCounter.cs @@ -1,61 +1,16 @@ // 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 osu.Framework.Allocation; -using osu.Framework.Bindables; -using osu.Game.Configuration; -using osu.Game.Rulesets.Scoring; using osu.Game.Skinning; namespace osu.Game.Screens.Play.HUD { - public class SkinnableScoreCounter : SkinnableDrawable, IScoreCounter + public class SkinnableScoreCounter : SkinnableDrawable { - public Bindable Current { get; } = new Bindable(); - - private Bindable scoreDisplayMode; - - public Bindable RequiredDisplayDigits { get; } = new Bindable(); - public SkinnableScoreCounter() : base(new HUDSkinComponent(HUDSkinComponents.ScoreCounter), _ => new DefaultScoreCounter()) { CentreComponent = false; } - - [BackgroundDependencyLoader] - private void load(OsuConfigManager config) - { - scoreDisplayMode = config.GetBindable(OsuSetting.ScoreDisplayMode); - scoreDisplayMode.BindValueChanged(scoreMode => - { - switch (scoreMode.NewValue) - { - case ScoringMode.Standardised: - RequiredDisplayDigits.Value = 6; - break; - - case ScoringMode.Classic: - RequiredDisplayDigits.Value = 8; - break; - - default: - throw new ArgumentOutOfRangeException(nameof(scoreMode)); - } - }, true); - } - - private IScoreCounter skinnedCounter; - - protected override void SkinChanged(ISkinSource skin, bool allowFallback) - { - base.SkinChanged(skin, allowFallback); - - skinnedCounter = Drawable as IScoreCounter; - - skinnedCounter?.Current.BindTo(Current); - skinnedCounter?.RequiredDisplayDigits.BindTo(RequiredDisplayDigits); - } } } diff --git a/osu.Game/Screens/Play/HUDOverlay.cs b/osu.Game/Screens/Play/HUDOverlay.cs index 83897c5167..c887fb78e0 100644 --- a/osu.Game/Screens/Play/HUDOverlay.cs +++ b/osu.Game/Screens/Play/HUDOverlay.cs @@ -320,7 +320,6 @@ namespace osu.Game.Screens.Play protected virtual void BindScoreProcessor(ScoreProcessor processor) { - ScoreCounter?.Current.BindTo(processor.TotalScore); AccuracyCounter?.Current.BindTo(processor.Accuracy); if (HealthDisplay is IHealthDisplay shd) diff --git a/osu.Game/Skinning/LegacyScoreCounter.cs b/osu.Game/Skinning/LegacyScoreCounter.cs index 1d330ef495..e385caf304 100644 --- a/osu.Game/Skinning/LegacyScoreCounter.cs +++ b/osu.Game/Skinning/LegacyScoreCounter.cs @@ -4,12 +4,12 @@ using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Game.Graphics.Sprites; -using osu.Game.Graphics.UserInterface; +using osu.Game.Screens.Play.HUD; using osuTK; namespace osu.Game.Skinning { - public class LegacyScoreCounter : ScoreCounter + public class LegacyScoreCounter : GameplayScoreCounter { private readonly ISkin skin; From 5b2f786f971ef65100be176ebc828b87e87f8c3f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 7 May 2021 19:16:00 +0900 Subject: [PATCH 16/19] Update framework --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index 99cda7693d..80b1c5b52f 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -52,6 +52,6 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index e448972066..29189781a7 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -29,7 +29,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index 43ed2d7dc8..c4eb7aefba 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -70,7 +70,7 @@ - + @@ -93,7 +93,7 @@ - + From df630d94282250064ba396d06b518b3ab369447d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 8 May 2021 14:53:19 +0200 Subject: [PATCH 17/19] Trim redundant `this` qualifier --- .../Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs index 32d2fba25e..d57acd005b 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs @@ -240,7 +240,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders new OsuMenuItem("Add control point", MenuItemType.Standard, () => addControlPoint(rightClickPosition)), }; - public override Vector2 ScreenSpaceSelectionPoint => this.ToScreenSpace(slider.HitObject.StackedPosition); + public override Vector2 ScreenSpaceSelectionPoint => ToScreenSpace(slider.HitObject.StackedPosition); public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => slider.ReceivePositionalInputAt(screenSpacePos) || ControlPointVisualiser?.Pieces.Any(p => p.ReceivePositionalInputAt(screenSpacePos)) == true; From 63e267a3beefbb0c7344521af93d1a340a5a454c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 8 May 2021 23:32:52 +0900 Subject: [PATCH 18/19] Revert "Trim redundant `this` qualifier" This reverts commit df630d94282250064ba396d06b518b3ab369447d. --- .../Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs index d57acd005b..32d2fba25e 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs @@ -240,7 +240,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders new OsuMenuItem("Add control point", MenuItemType.Standard, () => addControlPoint(rightClickPosition)), }; - public override Vector2 ScreenSpaceSelectionPoint => ToScreenSpace(slider.HitObject.StackedPosition); + public override Vector2 ScreenSpaceSelectionPoint => this.ToScreenSpace(slider.HitObject.StackedPosition); public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => slider.ReceivePositionalInputAt(screenSpacePos) || ControlPointVisualiser?.Pieces.Any(p => p.ReceivePositionalInputAt(screenSpacePos)) == true; From 01d732bb65202f66737d478457d62f1af1cd1884 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 8 May 2021 23:33:03 +0900 Subject: [PATCH 19/19] Revert "Refactor `SliderSelectionBlueprint` to not reference blueprint pieces for input handling" This reverts commit 54fe10c82a855a16c88f8781a9ae12dc42df7b0e. --- .../Edit/Blueprints/Sliders/Components/SliderBodyPiece.cs | 6 ++++++ .../Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/SliderBodyPiece.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/SliderBodyPiece.cs index ece9c7a757..6e22c35ab3 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/SliderBodyPiece.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/SliderBodyPiece.cs @@ -26,6 +26,10 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components { AccentColour = Color4.Transparent }; + + // SliderSelectionBlueprint relies on calling ReceivePositionalInputAt on this drawable to determine whether selection should occur. + // Without AlwaysPresent, a movement in a parent container (ie. the editor composer area resizing) could cause incorrect input handling. + AlwaysPresent = true; } [BackgroundDependencyLoader] @@ -50,5 +54,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components } public void RecyclePath() => body.RecyclePath(); + + public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => body.ReceivePositionalInputAt(screenSpacePos); } } diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs index 32d2fba25e..88fcb1e715 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs @@ -240,10 +240,10 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders new OsuMenuItem("Add control point", MenuItemType.Standard, () => addControlPoint(rightClickPosition)), }; - public override Vector2 ScreenSpaceSelectionPoint => this.ToScreenSpace(slider.HitObject.StackedPosition); + public override Vector2 ScreenSpaceSelectionPoint => BodyPiece.ToScreenSpace(BodyPiece.PathStartLocation); public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => - slider.ReceivePositionalInputAt(screenSpacePos) || ControlPointVisualiser?.Pieces.Any(p => p.ReceivePositionalInputAt(screenSpacePos)) == true; + BodyPiece.ReceivePositionalInputAt(screenSpacePos) || ControlPointVisualiser?.Pieces.Any(p => p.ReceivePositionalInputAt(screenSpacePos)) == true; protected virtual SliderCircleSelectionBlueprint CreateCircleSelectionBlueprint(DrawableSlider slider, SliderPosition position) => new SliderCircleSelectionBlueprint(slider, position); }