From b069372b2952cf95b0928c87ba3939dba6617967 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 3 Nov 2020 17:49:48 +0900 Subject: [PATCH 01/11] Fix skin changes resulting in incorrectly applied transforms in MainCirclePiece --- .../Drawables/Pieces/MainCirclePiece.cs | 50 +++++++++++-------- 1 file changed, 28 insertions(+), 22 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/MainCirclePiece.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/MainCirclePiece.cs index cb3787a493..e2345de886 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/MainCirclePiece.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/MainCirclePiece.cs @@ -42,10 +42,13 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces private readonly IBindable accentColour = new Bindable(); private readonly IBindable indexInCurrentCombo = new Bindable(); + [Resolved] + private DrawableHitObject drawableObject { get; set; } + [BackgroundDependencyLoader] - private void load(DrawableHitObject drawableObject) + private void load() { - OsuHitObject osuObject = (OsuHitObject)drawableObject.HitObject; + var osuObject = (OsuHitObject)drawableObject.HitObject; state.BindTo(drawableObject.State); state.BindValueChanged(updateState, true); @@ -64,32 +67,35 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces private void updateState(ValueChangedEvent state) { - glow.FadeOut(400); - - switch (state.NewValue) + using (BeginAbsoluteSequence(drawableObject.HitObject.StartTime + (drawableObject.Result?.TimeOffset ?? 0), true)) { - case ArmedState.Hit: - const double flash_in = 40; - const double flash_out = 100; + glow.FadeOut(400); - flash.FadeTo(0.8f, flash_in) - .Then() - .FadeOut(flash_out); + switch (state.NewValue) + { + case ArmedState.Hit: + const double flash_in = 40; + const double flash_out = 100; - explode.FadeIn(flash_in); - this.ScaleTo(1.5f, 400, Easing.OutQuad); + flash.FadeTo(0.8f, flash_in) + .Then() + .FadeOut(flash_out); - using (BeginDelayedSequence(flash_in, true)) - { - // after the flash, we can hide some elements that were behind it - ring.FadeOut(); - circle.FadeOut(); - number.FadeOut(); + explode.FadeIn(flash_in); + this.ScaleTo(1.5f, 400, Easing.OutQuad); - this.FadeOut(800); - } + using (BeginDelayedSequence(flash_in, true)) + { + // after the flash, we can hide some elements that were behind it + ring.FadeOut(); + circle.FadeOut(); + number.FadeOut(); - break; + this.FadeOut(800); + } + + break; + } } } } From 9f333ac58a379164ece8af22302cd09d639b8480 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 3 Nov 2020 20:45:48 +0900 Subject: [PATCH 02/11] Add the ability to delete slider control points using shift+right click Closes https://github.com/ppy/osu/issues/10672. In two minds about how this should be implemented but went in this direction initially. The other way would be to add local handling of Shift-Right Click inside PathControlPointPiece (which is already doing mouse handling itself). --- .../Components/PathControlPointVisualiser.cs | 10 +++++++--- .../Sliders/SliderSelectionBlueprint.cs | 16 +++++++++++++++- osu.Game/Rulesets/Edit/SelectionBlueprint.cs | 6 ++++++ .../Compose/Components/BlueprintContainer.cs | 11 ++++++++--- .../Edit/Compose/Components/SelectionHandler.cs | 14 ++++++++++++-- 5 files changed, 48 insertions(+), 9 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs index f6354bc612..13dc7886ed 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs @@ -18,6 +18,7 @@ using osu.Game.Graphics.UserInterface; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Osu.Objects; +using osuTK; using osuTK.Input; namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components @@ -105,7 +106,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components switch (action.ActionMethod) { case PlatformActionMethod.Delete: - return deleteSelected(); + return DeleteSelected(); } return false; @@ -115,6 +116,9 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components { } + public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => + Pieces.Any(p => p.ReceivePositionalInputAt(screenSpacePos)); + private void selectPiece(PathControlPointPiece piece, MouseButtonEvent e) { if (e.Button == MouseButton.Left && inputManager.CurrentState.Keyboard.ControlPressed) @@ -126,7 +130,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components } } - private bool deleteSelected() + public bool DeleteSelected() { List toRemove = Pieces.Where(p => p.IsSelected.Value).Select(p => p.ControlPoint).ToList(); @@ -169,7 +173,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components return new MenuItem[] { - new OsuMenuItem($"Delete {"control point".ToQuantity(count, count > 1 ? ShowQuantityAs.Numeric : ShowQuantityAs.None)}", MenuItemType.Destructive, () => deleteSelected()), + new OsuMenuItem($"Delete {"control point".ToQuantity(count, count > 1 ? ShowQuantityAs.Numeric : ShowQuantityAs.None)}", MenuItemType.Destructive, () => DeleteSelected()), new OsuMenuItem("Curve type") { Items = items diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs index d3fb5defae..59b087f68f 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Diagnostics; +using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -72,6 +73,18 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders BodyPiece.UpdateFrom(HitObject); } + public override bool HandleQuickDeletion() + { + var hoveredControlPoint = ControlPointVisualiser.Pieces.FirstOrDefault(p => p.IsHovered); + + if (hoveredControlPoint == null) + return false; + + hoveredControlPoint.IsSelected.Value = true; + ControlPointVisualiser.DeleteSelected(); + return true; + } + protected override void Update() { base.Update(); @@ -216,7 +229,8 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders public override Vector2 ScreenSpaceSelectionPoint => BodyPiece.ToScreenSpace(BodyPiece.PathStartLocation); - public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => BodyPiece.ReceivePositionalInputAt(screenSpacePos); + public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => + BodyPiece.ReceivePositionalInputAt(screenSpacePos) || ControlPointVisualiser?.ReceivePositionalInputAt(screenSpacePos) == true; protected virtual SliderCircleSelectionBlueprint CreateCircleSelectionBlueprint(DrawableSlider slider, SliderPosition position) => new SliderCircleSelectionBlueprint(slider, position); } diff --git a/osu.Game/Rulesets/Edit/SelectionBlueprint.cs b/osu.Game/Rulesets/Edit/SelectionBlueprint.cs index f3816f6218..99cdca045b 100644 --- a/osu.Game/Rulesets/Edit/SelectionBlueprint.cs +++ b/osu.Game/Rulesets/Edit/SelectionBlueprint.cs @@ -143,5 +143,11 @@ namespace osu.Game.Rulesets.Edit public virtual Quad SelectionQuad => ScreenSpaceDrawQuad; public virtual Vector2 GetInstantDelta(Vector2 screenSpacePosition) => Parent.ToLocalSpace(screenSpacePosition) - Position; + + /// + /// Handle to perform a partial deletion when the user requests a quick delete (Shift+Right Click). + /// + /// True if the deletion operation was handled by this blueprint. Returning false will delete the full blueprint. + public virtual bool HandleQuickDeletion() => false; } } diff --git a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs index fa98358dbe..d8f7137fa6 100644 --- a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs @@ -116,7 +116,8 @@ namespace osu.Game.Screens.Edit.Compose.Components protected override bool OnMouseDown(MouseDownEvent e) { - beginClickSelection(e); + if (beginClickSelection(e)) return true; + prepareSelectionMovement(); return e.Button == MouseButton.Left; @@ -291,19 +292,23 @@ namespace osu.Game.Screens.Edit.Compose.Components /// Attempts to select any hovered blueprints. /// /// The input event that triggered this selection. - private void beginClickSelection(MouseButtonEvent e) + private bool beginClickSelection(MouseButtonEvent e) { Debug.Assert(!clickSelectionBegan); + bool rightClickHandled = false; + foreach (SelectionBlueprint blueprint in SelectionBlueprints.AliveChildren) { if (blueprint.IsHovered) { - SelectionHandler.HandleSelectionRequested(blueprint, e.CurrentState); + rightClickHandled |= SelectionHandler.HandleSelectionRequested(blueprint, e.CurrentState); clickSelectionBegan = true; break; } } + + return rightClickHandled; } /// diff --git a/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs b/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs index c2441b31a9..5bf6c52e11 100644 --- a/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs +++ b/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs @@ -219,18 +219,28 @@ namespace osu.Game.Screens.Edit.Compose.Components /// /// The blueprint. /// The input state at the point of selection. - internal void HandleSelectionRequested(SelectionBlueprint blueprint, InputState state) + /// Whether right click was handled. + internal bool HandleSelectionRequested(SelectionBlueprint blueprint, InputState state) { if (state.Keyboard.ShiftPressed && state.Mouse.IsPressed(MouseButton.Right)) + { handleQuickDeletion(blueprint); - else if (state.Keyboard.ControlPressed && state.Mouse.IsPressed(MouseButton.Left)) + return true; + } + + if (state.Keyboard.ControlPressed && state.Mouse.IsPressed(MouseButton.Left)) blueprint.ToggleSelection(); else ensureSelected(blueprint); + + return false; } private void handleQuickDeletion(SelectionBlueprint blueprint) { + if (blueprint.HandleQuickDeletion()) + return; + if (!blueprint.IsSelected) EditorBeatmap.Remove(blueprint.HitObject); else From 65fb8628e0f4f8d41d15e6fc1f2d4cb21a87bcc4 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 4 Nov 2020 17:30:11 +0900 Subject: [PATCH 03/11] Use HitStateUpdateTime --- .../Objects/Drawables/Pieces/MainCirclePiece.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/MainCirclePiece.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/MainCirclePiece.cs index e2345de886..bb92f8afb8 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/MainCirclePiece.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/MainCirclePiece.cs @@ -67,7 +67,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces private void updateState(ValueChangedEvent state) { - using (BeginAbsoluteSequence(drawableObject.HitObject.StartTime + (drawableObject.Result?.TimeOffset ?? 0), true)) + using (BeginAbsoluteSequence(drawableObject.HitStateUpdateTime, true)) { glow.FadeOut(400); From f9fc58c45c01c2547f410e7b1564464c3cb834ca Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 4 Nov 2020 17:30:23 +0900 Subject: [PATCH 04/11] Apply same fix to LegacyMainCirclePiece --- .../Skinning/LegacyMainCirclePiece.cs | 44 +++++++++++-------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs b/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs index 382d6e53cc..a2ae6f4021 100644 --- a/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs @@ -41,11 +41,14 @@ namespace osu.Game.Rulesets.Osu.Skinning private readonly Bindable accentColour = new Bindable(); private readonly IBindable indexInCurrentCombo = new Bindable(); + [Resolved] + private DrawableHitObject drawableObject { get; set; } + [Resolved] private ISkinSource skin { get; set; } [BackgroundDependencyLoader] - private void load(DrawableHitObject drawableObject) + private void load() { OsuHitObject osuObject = (OsuHitObject)drawableObject.HitObject; @@ -143,28 +146,31 @@ namespace osu.Game.Rulesets.Osu.Skinning { const double legacy_fade_duration = 240; - switch (state.NewValue) + using (BeginAbsoluteSequence(drawableObject.HitStateUpdateTime, true)) { - case ArmedState.Hit: - circleSprites.FadeOut(legacy_fade_duration, Easing.Out); - circleSprites.ScaleTo(1.4f, legacy_fade_duration, Easing.Out); + switch (state.NewValue) + { + case ArmedState.Hit: + circleSprites.FadeOut(legacy_fade_duration, Easing.Out); + circleSprites.ScaleTo(1.4f, legacy_fade_duration, Easing.Out); - if (hasNumber) - { - var legacyVersion = skin.GetConfig(LegacySetting.Version)?.Value; - - if (legacyVersion >= 2.0m) - // legacy skins of version 2.0 and newer only apply very short fade out to the number piece. - hitCircleText.FadeOut(legacy_fade_duration / 4, Easing.Out); - else + if (hasNumber) { - // old skins scale and fade it normally along other pieces. - hitCircleText.FadeOut(legacy_fade_duration, Easing.Out); - hitCircleText.ScaleTo(1.4f, legacy_fade_duration, Easing.Out); - } - } + var legacyVersion = skin.GetConfig(LegacySetting.Version)?.Value; - break; + if (legacyVersion >= 2.0m) + // legacy skins of version 2.0 and newer only apply very short fade out to the number piece. + hitCircleText.FadeOut(legacy_fade_duration / 4, Easing.Out); + else + { + // old skins scale and fade it normally along other pieces. + hitCircleText.FadeOut(legacy_fade_duration, Easing.Out); + hitCircleText.ScaleTo(1.4f, legacy_fade_duration, Easing.Out); + } + } + + break; + } } } } From d19b799f44edafd9b04c362a7e00bc65c38c0c69 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 4 Nov 2020 17:53:03 +0900 Subject: [PATCH 05/11] Invert boolean logic --- .../Edit/Compose/Components/BlueprintContainer.cs | 9 +++++---- .../Screens/Edit/Compose/Components/SelectionHandler.cs | 6 +++--- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs index d8f7137fa6..e7da220946 100644 --- a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs @@ -116,7 +116,7 @@ namespace osu.Game.Screens.Edit.Compose.Components protected override bool OnMouseDown(MouseDownEvent e) { - if (beginClickSelection(e)) return true; + if (!beginClickSelection(e)) return true; prepareSelectionMovement(); @@ -292,23 +292,24 @@ namespace osu.Game.Screens.Edit.Compose.Components /// Attempts to select any hovered blueprints. /// /// The input event that triggered this selection. + /// Whether a selection was performed. private bool beginClickSelection(MouseButtonEvent e) { Debug.Assert(!clickSelectionBegan); - bool rightClickHandled = false; + bool selectedPerformed = true; foreach (SelectionBlueprint blueprint in SelectionBlueprints.AliveChildren) { if (blueprint.IsHovered) { - rightClickHandled |= SelectionHandler.HandleSelectionRequested(blueprint, e.CurrentState); + selectedPerformed &= SelectionHandler.HandleSelectionRequested(blueprint, e.CurrentState); clickSelectionBegan = true; break; } } - return rightClickHandled; + return selectedPerformed; } /// diff --git a/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs b/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs index 5bf6c52e11..d5c83576e2 100644 --- a/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs +++ b/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs @@ -219,13 +219,13 @@ namespace osu.Game.Screens.Edit.Compose.Components /// /// The blueprint. /// The input state at the point of selection. - /// Whether right click was handled. + /// Whether a selection was performed. internal bool HandleSelectionRequested(SelectionBlueprint blueprint, InputState state) { if (state.Keyboard.ShiftPressed && state.Mouse.IsPressed(MouseButton.Right)) { handleQuickDeletion(blueprint); - return true; + return false; } if (state.Keyboard.ControlPressed && state.Mouse.IsPressed(MouseButton.Left)) @@ -233,7 +233,7 @@ namespace osu.Game.Screens.Edit.Compose.Components else ensureSelected(blueprint); - return false; + return true; } private void handleQuickDeletion(SelectionBlueprint blueprint) From eed9894d3a0bb0d4b68282a171fb286e2d9b176b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 5 Nov 2020 13:58:41 +0900 Subject: [PATCH 06/11] Remove usage of case-when (caught me off-gaurd) --- .../Blueprints/Sliders/SliderSelectionBlueprint.cs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs index 59b087f68f..1644d5aa4b 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs @@ -122,9 +122,14 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders rightClickPosition = e.MouseDownPosition; return false; // Allow right click to be handled by context menu - case MouseButton.Left when e.ControlPressed && IsSelected: - placementControlPointIndex = addControlPoint(e.MousePosition); - return true; // Stop input from being handled and modifying the selection + case MouseButton.Left: + if (e.ControlPressed && IsSelected) + { + placementControlPointIndex = addControlPoint(e.MousePosition); + return true; // Stop input from being handled and modifying the selection + } + + break; } return false; From 242ec1ca826eb3ed72a52cc686a3cf60f8630289 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 5 Nov 2020 13:58:52 +0900 Subject: [PATCH 07/11] Don't override PathControlPointVisualiser's positional handling It turns out it was relying on this to deselect control points on clicking away from them. --- .../Sliders/Components/PathControlPointVisualiser.cs | 4 ---- .../Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs index 13dc7886ed..b4fc9c2fb9 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs @@ -18,7 +18,6 @@ using osu.Game.Graphics.UserInterface; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Osu.Objects; -using osuTK; using osuTK.Input; namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components @@ -116,9 +115,6 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components { } - public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => - Pieces.Any(p => p.ReceivePositionalInputAt(screenSpacePos)); - private void selectPiece(PathControlPointPiece piece, MouseButtonEvent e) { if (e.Button == MouseButton.Left && inputManager.CurrentState.Keyboard.ControlPressed) diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs index 1644d5aa4b..1ad2eb83bf 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs @@ -235,7 +235,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders public override Vector2 ScreenSpaceSelectionPoint => BodyPiece.ToScreenSpace(BodyPiece.PathStartLocation); public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => - BodyPiece.ReceivePositionalInputAt(screenSpacePos) || ControlPointVisualiser?.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); } From 3f24fabb575e9806d8fbecffce35d4c15b47e295 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 5 Nov 2020 15:05:43 +0900 Subject: [PATCH 08/11] Add change handler support for contorl point deletion --- .../Sliders/Components/PathControlPointVisualiser.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs index b4fc9c2fb9..17541866ec 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Collections.Specialized; using System.Linq; using Humanizer; +using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -18,6 +19,7 @@ using osu.Game.Graphics.UserInterface; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Osu.Objects; +using osu.Game.Screens.Edit; using osuTK.Input; namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components @@ -126,6 +128,9 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components } } + [Resolved(CanBeNull = true)] + private IEditorChangeHandler changeHandler { get; set; } + public bool DeleteSelected() { List toRemove = Pieces.Where(p => p.IsSelected.Value).Select(p => p.ControlPoint).ToList(); @@ -134,7 +139,9 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components if (toRemove.Count == 0) return false; + changeHandler?.BeginChange(); RemoveControlPointsRequested?.Invoke(toRemove); + changeHandler?.EndChange(); // Since pieces are re-used, they will not point to the deleted control points while remaining selected foreach (var piece in Pieces) From 71253cb5e9aeba420d4d8062f41d80917abeb8db Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 5 Nov 2020 19:35:32 +0900 Subject: [PATCH 09/11] Add support for spinner "clear" text in legacy skins --- .../Skinning/LegacySpinner.cs | 36 ++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Skinning/LegacySpinner.cs b/osu.Game.Rulesets.Osu/Skinning/LegacySpinner.cs index 31350791e3..6c276f951e 100644 --- a/osu.Game.Rulesets.Osu/Skinning/LegacySpinner.cs +++ b/osu.Game.Rulesets.Osu/Skinning/LegacySpinner.cs @@ -3,6 +3,7 @@ using System; using osu.Framework.Allocation; +using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; @@ -20,6 +21,7 @@ namespace osu.Game.Rulesets.Osu.Skinning protected DrawableSpinner DrawableSpinner { get; private set; } private Sprite spin; + private Sprite clear; [BackgroundDependencyLoader] private void load(DrawableHitObject drawableHitObject, ISkinSource source) @@ -39,17 +41,50 @@ namespace osu.Game.Rulesets.Osu.Skinning Scale = new Vector2(SPRITE_SCALE), Y = 120 - 45 // offset temporarily to avoid overlapping default spin counter }, + clear = new Sprite + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Depth = float.MinValue, + Alpha = 0, + Texture = source.GetTexture("spinner-clear"), + Scale = new Vector2(SPRITE_SCALE), + Y = -60 + }, }); } + private readonly Bindable completed = new Bindable(); + protected override void LoadComplete() { base.LoadComplete(); + completed.BindTo(DrawableSpinner.RotationTracker.Complete); + completed.BindValueChanged(onCompletedChanged, true); + DrawableSpinner.ApplyCustomUpdateState += UpdateStateTransforms; UpdateStateTransforms(DrawableSpinner, DrawableSpinner.State.Value); } + private void onCompletedChanged(ValueChangedEvent completed) + { + if (completed.NewValue) + { + clear.FadeInFromZero(400, Easing.Out); + clear.ScaleTo(SPRITE_SCALE * 2).Then().ScaleTo(SPRITE_SCALE, 400, Easing.OutElastic); + + const double fade_out_duration = 50; + using (BeginAbsoluteSequence(DrawableSpinner.HitStateUpdateTime - fade_out_duration, true)) + clear.FadeOut(fade_out_duration); + } + else + { + clear.ClearTransforms(); + clear.Alpha = 0; + } + } + protected virtual void UpdateStateTransforms(DrawableHitObject drawableHitObject, ArmedState state) { switch (drawableHitObject) @@ -59,7 +94,6 @@ namespace osu.Game.Rulesets.Osu.Skinning using (BeginAbsoluteSequence(drawableHitObject.HitStateUpdateTime - fadeOutLength, true)) spin.FadeOutFromOne(fadeOutLength); - break; case DrawableSpinnerTick d: From d7a912a0d2784b5096e8607388730ee61492af9a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 5 Nov 2020 19:44:34 +0900 Subject: [PATCH 10/11] Match stable's transform 1:1 --- osu.Game.Rulesets.Osu/Skinning/LegacySpinner.cs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Skinning/LegacySpinner.cs b/osu.Game.Rulesets.Osu/Skinning/LegacySpinner.cs index 6c276f951e..eb9fa85fde 100644 --- a/osu.Game.Rulesets.Osu/Skinning/LegacySpinner.cs +++ b/osu.Game.Rulesets.Osu/Skinning/LegacySpinner.cs @@ -71,8 +71,16 @@ namespace osu.Game.Rulesets.Osu.Skinning { if (completed.NewValue) { - clear.FadeInFromZero(400, Easing.Out); - clear.ScaleTo(SPRITE_SCALE * 2).Then().ScaleTo(SPRITE_SCALE, 400, Easing.OutElastic); + double startTime = Math.Min(Time.Current, DrawableSpinner.HitStateUpdateTime - 400); + + using (BeginAbsoluteSequence(startTime, true)) + { + clear.FadeInFromZero(400, Easing.Out); + + clear.ScaleTo(SPRITE_SCALE * 2) + .Then().ScaleTo(SPRITE_SCALE * 0.8f, 240, Easing.Out) + .Then().ScaleTo(SPRITE_SCALE, 160); + } const double fade_out_duration = 50; using (BeginAbsoluteSequence(DrawableSpinner.HitStateUpdateTime - fade_out_duration, true)) From 1ca8b03aa5a2ba9be0bd2e813bd5cf01e5677f09 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 6 Nov 2020 17:26:23 +0900 Subject: [PATCH 11/11] Never disable pause button on now playing overlay --- osu.Game/Overlays/NowPlayingOverlay.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Overlays/NowPlayingOverlay.cs b/osu.Game/Overlays/NowPlayingOverlay.cs index 55adf02a45..9beb859f28 100644 --- a/osu.Game/Overlays/NowPlayingOverlay.cs +++ b/osu.Game/Overlays/NowPlayingOverlay.cs @@ -308,7 +308,6 @@ namespace osu.Game.Overlays if (disabled) playlist.Hide(); - playButton.Enabled.Value = !disabled; prevButton.Enabled.Value = !disabled; nextButton.Enabled.Value = !disabled; playlistButton.Enabled.Value = !disabled;