From ee220feecf09781876973366ea136b22c6d5b809 Mon Sep 17 00:00:00 2001 From: Derrick Timmermans Date: Sun, 18 Jul 2021 16:04:23 +0200 Subject: [PATCH] Avoid using guesses to determine whether inputs blocked --- .../Compose/Components/BlueprintContainer.cs | 12 ++++--- .../Timeline/TimelineBlueprintContainer.cs | 33 +++++-------------- 2 files changed, 15 insertions(+), 30 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs index 185f029d14..06cbf7c2e0 100644 --- a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs @@ -110,9 +110,9 @@ namespace osu.Game.Screens.Edit.Compose.Components bool selectionPerformed = performMouseDownActions(e); // even if a selection didn't occur, a drag event may still move the selection. - prepareSelectionMovement(); + bool movementPossible = prepareSelectionMovement(); - return selectionPerformed || e.Button == MouseButton.Left; + return selectionPerformed || movementPossible; } protected SelectionBlueprint ClickedBlueprint { get; private set; } @@ -427,19 +427,21 @@ namespace osu.Game.Screens.Edit.Compose.Components /// /// Attempts to begin the movement of any selected blueprints. /// - private void prepareSelectionMovement() + /// Whether a movement is possible. + private bool prepareSelectionMovement() { if (!SelectionHandler.SelectedBlueprints.Any()) - return; + return false; // Any selected blueprint that is hovered can begin the movement of the group, however only the first item (according to SortForMovement) is used for movement. // A special case is added for when a click selection occurred before the drag if (!clickSelectionBegan && !SelectionHandler.SelectedBlueprints.Any(b => b.IsHovered)) - return; + return false; // Movement is tracked from the blueprint of the earliest item, since it only makes sense to distance snap from that item movementBlueprints = SortForMovement(SelectionHandler.SelectedBlueprints).ToArray(); movementBlueprintOriginalPositions = movementBlueprints.Select(m => m.ScreenSpaceSelectionPoint).ToArray(); + return true; } /// diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineBlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineBlueprintContainer.cs index abd7f5923c..ae33eaa355 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineBlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineBlueprintContainer.cs @@ -35,15 +35,10 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline private Bindable placement; private SelectionBlueprint placementBlueprint; - // We want children to be able to be clicked and dragged - public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => true; + private SelectableAreaBackground backgroundBox; - // This drawable itself should still check whether the mouse is over it - private bool shouldHandleInputAt(Vector2 screenSpacePos) - { - float localY = ToLocalSpace(screenSpacePos).Y; - return DrawRectangle.Top <= localY && DrawRectangle.Bottom >= localY; - } + // We want children to be able to be clicked and dragged, regardless of this drawable's size + public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => true; public TimelineBlueprintContainer(HitObjectComposer composer) : base(composer) @@ -58,7 +53,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline [BackgroundDependencyLoader] private void load() { - AddInternal(new SelectableAreaBackground + AddInternal(backgroundBox = new SelectableAreaBackground { Colour = Color4.Black, Depth = float.MaxValue, @@ -97,25 +92,13 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline protected override Container> CreateSelectionBlueprintContainer() => new TimelineSelectionBlueprintContainer { RelativeSizeAxes = Axes.Both }; - protected override bool OnMouseDown(MouseDownEvent e) - { - int selectionCount = SelectedItems.Count; - - // We let BlueprintContainer attempt a HitObject selection - // If it fails, we'll pass it this input back to the timeline so it can be dragged - // We know it failed if the selection count is unchanged after the selection attempt - if (base.OnMouseDown(e) && selectionCount != SelectedItems.Count) - return true; - - return false; - } - protected override bool OnDragStart(DragStartEvent e) { - if (!shouldHandleInputAt(e.ScreenSpaceMouseDownPosition)) - return false; + // We should only allow BlueprintContainer to create a drag box if the mouse is within selection bounds + if (backgroundBox.ReceivePositionalInputAt(e.ScreenSpaceMouseDownPosition)) + return base.OnDragStart(e); - return base.OnDragStart(e); + return false; } protected override void OnDrag(DragEvent e)