From 3b9e1e8a9491c8db305320951c58360622f57846 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 24 May 2023 19:16:51 +0900 Subject: [PATCH 1/3] Ensure editor selection buttons remain on screen when selection is near edge Addresses https://github.com/ppy/osu/discussions/23599. --- .../Edit/Compose/Components/SelectionBox.cs | 40 +++++++++++++++++-- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/SelectionBox.cs b/osu.Game/Screens/Edit/Compose/Components/SelectionBox.cs index 17790547ed..677b0cd76e 100644 --- a/osu.Game/Screens/Edit/Compose/Components/SelectionBox.cs +++ b/osu.Game/Screens/Edit/Compose/Components/SelectionBox.cs @@ -22,6 +22,8 @@ namespace osu.Game.Screens.Edit.Compose.Components { public const float BORDER_RADIUS = 3; + private const float button_padding = 5; + public Func OnRotation; public Func OnScale; public Func OnFlip; @@ -182,6 +184,13 @@ namespace osu.Game.Screens.Edit.Compose.Components return base.OnKeyDown(e); } + protected override void Update() + { + base.Update(); + + ensureButtonsOnScreen(); + } + private void recreate() { if (LoadState < LoadState.Loading) @@ -234,11 +243,12 @@ namespace osu.Game.Screens.Edit.Compose.Components }, buttons = new FillFlowContainer { - Y = 20, - AutoSizeAxes = Axes.Both, + AutoSizeAxes = Axes.X, + Height = 30, Direction = FillDirection.Horizontal, + Margin = new MarginPadding(button_padding), Anchor = Anchor.BottomCentre, - Origin = Anchor.Centre + Origin = Anchor.TopCentre } }; @@ -352,5 +362,29 @@ namespace osu.Game.Screens.Edit.Compose.Components if (activeOperations++ == 0) OperationStarted?.Invoke(); } + + private void ensureButtonsOnScreen() + { + buttons.Position = Vector2.Zero; + + var buttonsQuad = buttons.ScreenSpaceDrawQuad; + var thisQuad = ScreenSpaceDrawQuad; + + // Shrink the parent quad to give a bit of padding so the buttons don't stick *right* on the border. + // AABBFloat assumes no rotation. one would hope the whole editor is not being rotated. + var parentQuad = Parent.ScreenSpaceDrawQuad.AABBFloat.Shrink(ToLocalSpace(thisQuad.TopLeft + new Vector2(button_padding * 2))); + + float leftExcess = buttonsQuad.TopLeft.X - parentQuad.TopLeft.X; + float rightExcess = parentQuad.TopRight.X - buttonsQuad.TopRight.X; + float bottomExcess = thisQuad.BottomLeft.Y + buttonsQuad.Height - parentQuad.BottomLeft.Y; + + if (leftExcess < 0) + buttons.X += ToLocalSpace(thisQuad.TopLeft - new Vector2(leftExcess)).X; + else if (rightExcess < 0) + buttons.X -= ToLocalSpace(thisQuad.TopLeft - new Vector2(rightExcess)).X; + + if (bottomExcess > 0) + buttons.Y += ToLocalSpace(thisQuad.TopLeft - new Vector2(bottomExcess)).X; + } } } From beeca5a8dd1bc84f036f25caa5f4e00d4204d417 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Thu, 25 May 2023 16:17:44 +0200 Subject: [PATCH 2/3] Use alternative layouting implementation --- .../Edit/Compose/Components/SelectionBox.cs | 28 +++++++++++-------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/SelectionBox.cs b/osu.Game/Screens/Edit/Compose/Components/SelectionBox.cs index 677b0cd76e..fc57cbf17f 100644 --- a/osu.Game/Screens/Edit/Compose/Components/SelectionBox.cs +++ b/osu.Game/Screens/Edit/Compose/Components/SelectionBox.cs @@ -247,8 +247,6 @@ namespace osu.Game.Screens.Edit.Compose.Components Height = 30, Direction = FillDirection.Horizontal, Margin = new MarginPadding(button_padding), - Anchor = Anchor.BottomCentre, - Origin = Anchor.TopCentre } }; @@ -367,24 +365,30 @@ namespace osu.Game.Screens.Edit.Compose.Components { buttons.Position = Vector2.Zero; - var buttonsQuad = buttons.ScreenSpaceDrawQuad; var thisQuad = ScreenSpaceDrawQuad; // Shrink the parent quad to give a bit of padding so the buttons don't stick *right* on the border. // AABBFloat assumes no rotation. one would hope the whole editor is not being rotated. var parentQuad = Parent.ScreenSpaceDrawQuad.AABBFloat.Shrink(ToLocalSpace(thisQuad.TopLeft + new Vector2(button_padding * 2))); - float leftExcess = buttonsQuad.TopLeft.X - parentQuad.TopLeft.X; - float rightExcess = parentQuad.TopRight.X - buttonsQuad.TopRight.X; - float bottomExcess = thisQuad.BottomLeft.Y + buttonsQuad.Height - parentQuad.BottomLeft.Y; + float topExcess = thisQuad.TopLeft.Y - parentQuad.TopLeft.Y; + float bottomExcess = parentQuad.BottomLeft.Y - thisQuad.BottomLeft.Y; + float leftExcess = thisQuad.TopLeft.X - parentQuad.TopLeft.X; + float rightExcess = parentQuad.TopRight.X - thisQuad.TopRight.X; - if (leftExcess < 0) - buttons.X += ToLocalSpace(thisQuad.TopLeft - new Vector2(leftExcess)).X; - else if (rightExcess < 0) - buttons.X -= ToLocalSpace(thisQuad.TopLeft - new Vector2(rightExcess)).X; + if (topExcess > bottomExcess) + { + buttons.Anchor = Anchor.TopCentre; + buttons.Origin = Anchor.BottomCentre; + } + else + { + buttons.Anchor = Anchor.BottomCentre; + buttons.Origin = Anchor.TopCentre; + } - if (bottomExcess > 0) - buttons.Y += ToLocalSpace(thisQuad.TopLeft - new Vector2(bottomExcess)).X; + if (leftExcess < 0) buttons.X += ToLocalSpace(thisQuad.TopLeft - new Vector2(leftExcess)).X; + if (rightExcess < 0) buttons.X += ToLocalSpace(thisQuad.TopLeft + new Vector2(rightExcess)).X; } } } From 3ad5f8b9c9973788780e540cb98e5b260367df98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Thu, 25 May 2023 16:39:54 +0200 Subject: [PATCH 3/3] Polish a few extreme edge cases --- .../Screens/Edit/Compose/Components/SelectionBox.cs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/SelectionBox.cs b/osu.Game/Screens/Edit/Compose/Components/SelectionBox.cs index fc57cbf17f..1c5faed0e5 100644 --- a/osu.Game/Screens/Edit/Compose/Components/SelectionBox.cs +++ b/osu.Game/Screens/Edit/Compose/Components/SelectionBox.cs @@ -376,7 +376,12 @@ namespace osu.Game.Screens.Edit.Compose.Components float leftExcess = thisQuad.TopLeft.X - parentQuad.TopLeft.X; float rightExcess = parentQuad.TopRight.X - thisQuad.TopRight.X; - if (topExcess > bottomExcess) + if (topExcess + bottomExcess < buttons.Height + button_padding) + { + buttons.Anchor = Anchor.BottomCentre; + buttons.Origin = Anchor.BottomCentre; + } + else if (topExcess > bottomExcess) { buttons.Anchor = Anchor.TopCentre; buttons.Origin = Anchor.BottomCentre; @@ -387,8 +392,7 @@ namespace osu.Game.Screens.Edit.Compose.Components buttons.Origin = Anchor.TopCentre; } - if (leftExcess < 0) buttons.X += ToLocalSpace(thisQuad.TopLeft - new Vector2(leftExcess)).X; - if (rightExcess < 0) buttons.X += ToLocalSpace(thisQuad.TopLeft + new Vector2(rightExcess)).X; + buttons.X += ToLocalSpace(thisQuad.TopLeft - new Vector2(Math.Min(0, leftExcess)) + new Vector2(Math.Min(0, rightExcess))).X; } } }