Skip to content

Commit

Permalink
Merge pull request #30947 from bdach/undesirable-deselect-on-control-…
Browse files Browse the repository at this point in the history
…click

Do not deselect objects when control-clicking without hitting anything
  • Loading branch information
peppy authored Dec 2, 2024
2 parents 6c0ccc5 + b505ecc commit ce8e412
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,36 @@ public void TestControlClickDoesNotAddSliderControlPointsIfMultipleObjectsSelect
AddAssert("slider still has 2 anchors", () => secondSlider.Path.ControlPoints.Count, () => Is.EqualTo(2));
}

[Test]
public void TestControlClickDoesNotDiscardExistingSelectionEvenIfNothingHit()
{
var firstSlider = new Slider
{
StartTime = 0,
Position = new Vector2(0, 0),
Path = new SliderPath
{
ControlPoints =
{
new PathControlPoint(),
new PathControlPoint(new Vector2(100))
}
}
};

AddStep("add object", () => EditorBeatmap.AddRange([firstSlider]));
AddStep("select first slider", () => EditorBeatmap.SelectedHitObjects.AddRange([firstSlider]));

AddStep("move mouse to middle of playfield", () => InputManager.MoveMouseTo(blueprintContainer.ScreenSpaceDrawQuad.Centre));
AddStep("control-click left mouse", () =>
{
InputManager.PressKey(Key.ControlLeft);
InputManager.Click(MouseButton.Left);
InputManager.ReleaseKey(Key.ControlLeft);
});
AddAssert("selection preserved", () => EditorBeatmap.SelectedHitObjects.Count, () => Is.EqualTo(1));
}

private ComposeBlueprintContainer blueprintContainer
=> Editor.ChildrenOfType<ComposeBlueprintContainer>().First();

Expand Down
13 changes: 9 additions & 4 deletions osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -433,7 +433,10 @@ bool runForBlueprint(SelectionBlueprint<T> blueprint)
/// Finishes the current blueprint selection.
/// </summary>
/// <param name="e">The mouse event which triggered end of selection.</param>
/// <returns>Whether a click selection was active.</returns>
/// <returns>
/// Whether the mouse event is considered to be fully handled.
/// If the return value is <see langword="false"/>, the standard click / mouse up action will follow.
/// </returns>
private bool endClickSelection(MouseButtonEvent e)
{
// If already handled a selection, double-click, or drag, we don't want to perform a mouse up / click action.
Expand All @@ -443,14 +446,16 @@ private bool endClickSelection(MouseButtonEvent e)

if (e.ControlPressed)
{
// if a selection didn't occur, we may want to trigger a deselection.

// Iterate from the top of the input stack (blueprints closest to the front of the screen first).
// Priority is given to already-selected blueprints.
foreach (SelectionBlueprint<T> blueprint in SelectionBlueprints.AliveChildren.Where(b => b.IsHovered).OrderByDescending(b => b.IsSelected))
return clickSelectionHandled = SelectionHandler.MouseUpSelectionRequested(blueprint, e);

return false;
// can only be reached if there are no hovered blueprints.
// in that case, we still want to suppress mouse up / click handling, because when control is pressed,
// it is presumed we want to add to existing selection, not remove from it
// (unless explicitly control-clicking a selected object, which is handled above).
return true;
}

if (selectedBlueprintAlreadySelectedOnMouseDown && SelectedItems.Count == 1)
Expand Down

0 comments on commit ce8e412

Please sign in to comment.