From 0077ba72ecac49a7b79916a76956c7dd02f89038 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marvin=20Sch=C3=BCrz?= Date: Sat, 21 Sep 2024 14:59:47 +0200 Subject: [PATCH 1/3] Freeze select box buttons in place as long as they are hovered --- .../Edit/Compose/Components/SelectionBox.cs | 26 +++++++++++++++++++ .../Compose/Components/SelectionBoxButton.cs | 9 +++++++ 2 files changed, 35 insertions(+) diff --git a/osu.Game/Screens/Edit/Compose/Components/SelectionBox.cs b/osu.Game/Screens/Edit/Compose/Components/SelectionBox.cs index 0cc8a8273f15..39f0011a12b2 100644 --- a/osu.Game/Screens/Edit/Compose/Components/SelectionBox.cs +++ b/osu.Game/Screens/Edit/Compose/Components/SelectionBox.cs @@ -6,6 +6,7 @@ using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Primitives; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; using osu.Framework.Input.Events; @@ -284,8 +285,12 @@ private SelectionBoxButton addButton(IconUsage icon, string tooltip, Action acti Action = action }; + button.OperationStarted += freezeButtonPosition; + button.HoverLost += unfreezeButtonPosition; + button.OperationStarted += operationStarted; button.OperationEnded += operationEnded; + buttons.Add(button); return button; @@ -357,8 +362,29 @@ private void operationStarted() OperationStarted?.Invoke(); } + private Quad? frozenButtonsDrawQuad; + + private void freezeButtonPosition() + { + frozenButtonsDrawQuad = buttons.ScreenSpaceDrawQuad; + } + + private void unfreezeButtonPosition() + { + frozenButtonsDrawQuad = null; + } + private void ensureButtonsOnScreen() { + if (frozenButtonsDrawQuad != null) + { + buttons.Anchor = Anchor.TopLeft; + buttons.Origin = Anchor.TopLeft; + + buttons.Position = ToLocalSpace(frozenButtonsDrawQuad.Value.TopLeft) - new Vector2(button_padding); + return; + } + buttons.Position = Vector2.Zero; var thisQuad = ScreenSpaceDrawQuad; diff --git a/osu.Game/Screens/Edit/Compose/Components/SelectionBoxButton.cs b/osu.Game/Screens/Edit/Compose/Components/SelectionBoxButton.cs index 6108d44c81b0..e355add40bfc 100644 --- a/osu.Game/Screens/Edit/Compose/Components/SelectionBoxButton.cs +++ b/osu.Game/Screens/Edit/Compose/Components/SelectionBoxButton.cs @@ -21,6 +21,8 @@ public sealed partial class SelectionBoxButton : SelectionBoxControl, IHasToolti public Action? Action; + public event Action? HoverLost; + public SelectionBoxButton(IconUsage iconUsage, string tooltip) { this.iconUsage = iconUsage; @@ -61,6 +63,13 @@ protected override void UpdateHoverState() icon.FadeColour(!IsHeld && IsHovered ? Color4.White : Color4.Black, TRANSFORM_DURATION, Easing.OutQuint); } + protected override void OnHoverLost(HoverLostEvent e) + { + base.OnHoverLost(e); + + HoverLost?.Invoke(); + } + public LocalisableString TooltipText { get; } } } From 1095f35025603ca1e948483e732d6d4346f6c51c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marvin=20Sch=C3=BCrz?= Date: Sat, 21 Sep 2024 15:25:37 +0200 Subject: [PATCH 2/3] Only store position instead of entire draw quad --- .../Screens/Edit/Compose/Components/SelectionBox.cs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/SelectionBox.cs b/osu.Game/Screens/Edit/Compose/Components/SelectionBox.cs index 39f0011a12b2..4eae2b77f623 100644 --- a/osu.Game/Screens/Edit/Compose/Components/SelectionBox.cs +++ b/osu.Game/Screens/Edit/Compose/Components/SelectionBox.cs @@ -6,7 +6,6 @@ using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Primitives; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; using osu.Framework.Input.Events; @@ -362,26 +361,26 @@ private void operationStarted() OperationStarted?.Invoke(); } - private Quad? frozenButtonsDrawQuad; + private Vector2? frozenButtonsPosition; private void freezeButtonPosition() { - frozenButtonsDrawQuad = buttons.ScreenSpaceDrawQuad; + frozenButtonsPosition = buttons.ScreenSpaceDrawQuad.TopLeft; } private void unfreezeButtonPosition() { - frozenButtonsDrawQuad = null; + frozenButtonsPosition = null; } private void ensureButtonsOnScreen() { - if (frozenButtonsDrawQuad != null) + if (frozenButtonsPosition != null) { buttons.Anchor = Anchor.TopLeft; buttons.Origin = Anchor.TopLeft; - buttons.Position = ToLocalSpace(frozenButtonsDrawQuad.Value.TopLeft) - new Vector2(button_padding); + buttons.Position = ToLocalSpace(frozenButtonsPosition.Value) - new Vector2(button_padding); return; } From 99a80b399cbeb1ac3a95bbec1a1ca2639f920caf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marvin=20Sch=C3=BCrz?= Date: Tue, 24 Sep 2024 16:42:37 +0200 Subject: [PATCH 3/3] Animate SelectionBox buttons on unfreeze --- .../Edit/Compose/Components/SelectionBox.cs | 55 +++++++++++++++---- 1 file changed, 44 insertions(+), 11 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/SelectionBox.cs b/osu.Game/Screens/Edit/Compose/Components/SelectionBox.cs index 4eae2b77f623..d685fe74b0d3 100644 --- a/osu.Game/Screens/Edit/Compose/Components/SelectionBox.cs +++ b/osu.Game/Screens/Edit/Compose/Components/SelectionBox.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -370,10 +371,14 @@ private void freezeButtonPosition() private void unfreezeButtonPosition() { - frozenButtonsPosition = null; + if (frozenButtonsPosition != null) + { + frozenButtonsPosition = null; + ensureButtonsOnScreen(true); + } } - private void ensureButtonsOnScreen() + private void ensureButtonsOnScreen(bool animated = false) { if (frozenButtonsPosition != null) { @@ -384,7 +389,8 @@ private void ensureButtonsOnScreen() return; } - buttons.Position = Vector2.Zero; + if (!animated && buttons.Transforms.Any()) + return; var thisQuad = ScreenSpaceDrawQuad; @@ -399,24 +405,51 @@ private void ensureButtonsOnScreen() float minHeight = buttons.ScreenSpaceDrawQuad.Height; + Anchor targetAnchor; + Anchor targetOrigin; + Vector2 targetPosition = Vector2.Zero; + if (topExcess < minHeight && bottomExcess < minHeight) { - buttons.Anchor = Anchor.BottomCentre; - buttons.Origin = Anchor.BottomCentre; - buttons.Y = Math.Min(0, ToLocalSpace(Parent!.ScreenSpaceDrawQuad.BottomLeft).Y - DrawHeight); + targetAnchor = Anchor.BottomCentre; + targetOrigin = Anchor.BottomCentre; + targetPosition.Y = Math.Min(0, ToLocalSpace(Parent!.ScreenSpaceDrawQuad.BottomLeft).Y - DrawHeight); } else if (topExcess > bottomExcess) { - buttons.Anchor = Anchor.TopCentre; - buttons.Origin = Anchor.BottomCentre; + targetAnchor = Anchor.TopCentre; + targetOrigin = Anchor.BottomCentre; } else { - buttons.Anchor = Anchor.BottomCentre; - buttons.Origin = Anchor.TopCentre; + targetAnchor = Anchor.BottomCentre; + targetOrigin = Anchor.TopCentre; } - buttons.X += ToLocalSpace(thisQuad.TopLeft - new Vector2(Math.Min(0, leftExcess)) + new Vector2(Math.Min(0, rightExcess))).X; + targetPosition.X += ToLocalSpace(thisQuad.TopLeft - new Vector2(Math.Min(0, leftExcess)) + new Vector2(Math.Min(0, rightExcess))).X; + + if (animated) + { + var originalPosition = ToLocalSpace(buttons.ScreenSpaceDrawQuad.TopLeft); + + buttons.Origin = targetOrigin; + buttons.Anchor = targetAnchor; + buttons.Position = targetPosition; + + var newPosition = ToLocalSpace(buttons.ScreenSpaceDrawQuad.TopLeft); + + var delta = newPosition - originalPosition; + + buttons.Position -= delta; + + buttons.MoveTo(targetPosition, 300, Easing.OutQuint); + } + else + { + buttons.Anchor = targetAnchor; + buttons.Origin = targetOrigin; + buttons.Position = targetPosition; + } } } }