1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-16 17:02:55 +08:00

Merge pull request #29918 from bdach/control-drag

Add to existing selection when dragging with control pressed
This commit is contained in:
Dean Herbert 2024-09-30 14:00:36 +09:00 committed by GitHub
commit a258059d43
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 62 additions and 6 deletions

View File

@ -219,6 +219,51 @@ namespace osu.Game.Tests.Visual.Editing
AddAssert("2 hitobjects selected", () => EditorBeatmap.SelectedHitObjects.Count == 2 && !EditorBeatmap.SelectedHitObjects.Contains(addedObjects[1])); AddAssert("2 hitobjects selected", () => EditorBeatmap.SelectedHitObjects.Count == 2 && !EditorBeatmap.SelectedHitObjects.Contains(addedObjects[1]));
} }
[Test]
public void TestMultiSelectWithDragBox()
{
var addedObjects = new[]
{
new HitCircle { StartTime = 100 },
new HitCircle { StartTime = 200, Position = new Vector2(100) },
new HitCircle { StartTime = 300, Position = new Vector2(512, 0) },
new HitCircle { StartTime = 400, Position = new Vector2(412, 100) },
};
AddStep("add hitobjects", () => EditorBeatmap.AddRange(addedObjects));
AddStep("start dragging", () =>
{
InputManager.MoveMouseTo(blueprintContainer.ScreenSpaceDrawQuad.Centre);
InputManager.PressButton(MouseButton.Left);
});
AddStep("drag to left corner", () => InputManager.MoveMouseTo(blueprintContainer.ScreenSpaceDrawQuad.TopLeft - new Vector2(5)));
AddStep("end dragging", () => InputManager.ReleaseButton(MouseButton.Left));
AddAssert("2 hitobjects selected", () => EditorBeatmap.SelectedHitObjects, () => Has.Count.EqualTo(2));
AddStep("start dragging with control", () =>
{
InputManager.MoveMouseTo(blueprintContainer.ScreenSpaceDrawQuad.Centre);
InputManager.PressButton(MouseButton.Left);
InputManager.PressKey(Key.ControlLeft);
});
AddStep("drag to left corner", () => InputManager.MoveMouseTo(blueprintContainer.ScreenSpaceDrawQuad.TopRight + new Vector2(5, -5)));
AddStep("end dragging", () => InputManager.ReleaseButton(MouseButton.Left));
AddStep("release control", () => InputManager.ReleaseKey(Key.ControlLeft));
AddAssert("4 hitobjects selected", () => EditorBeatmap.SelectedHitObjects, () => Has.Count.EqualTo(4));
AddStep("start dragging without control", () =>
{
InputManager.MoveMouseTo(blueprintContainer.ScreenSpaceDrawQuad.Centre);
InputManager.PressButton(MouseButton.Left);
});
AddStep("drag to left corner", () => InputManager.MoveMouseTo(blueprintContainer.ScreenSpaceDrawQuad.TopRight + new Vector2(5, -5)));
AddStep("end dragging", () => InputManager.ReleaseButton(MouseButton.Left));
AddAssert("2 hitobjects selected", () => EditorBeatmap.SelectedHitObjects, () => Has.Count.EqualTo(2));
}
[Test] [Test]
public void TestNearestSelection() public void TestNearestSelection()
{ {

View File

@ -196,6 +196,11 @@ namespace osu.Game.Screens.Edit.Compose.Components
DragBox.HandleDrag(e); DragBox.HandleDrag(e);
DragBox.Show(); DragBox.Show();
selectionBeforeDrag.Clear();
if (e.ControlPressed)
selectionBeforeDrag.UnionWith(SelectedItems);
return true; return true;
} }
@ -217,6 +222,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
} }
DragBox.Hide(); DragBox.Hide();
selectionBeforeDrag.Clear();
} }
protected override void Update() protected override void Update()
@ -227,7 +233,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
{ {
lastDragEvent.Target = this; lastDragEvent.Target = this;
DragBox.HandleDrag(lastDragEvent); DragBox.HandleDrag(lastDragEvent);
UpdateSelectionFromDragBox(); UpdateSelectionFromDragBox(selectionBeforeDrag);
} }
} }
@ -426,7 +432,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
private bool endClickSelection(MouseButtonEvent e) 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. // If already handled a selection, double-click, or drag, we don't want to perform a mouse up / click action.
if (clickSelectionHandled || doubleClickHandled || isDraggingBlueprint) return true; if (clickSelectionHandled || doubleClickHandled || isDraggingBlueprint || wasDragStarted) return true;
if (e.Button != MouseButton.Left) return false; if (e.Button != MouseButton.Left) return false;
@ -442,7 +448,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
return false; return false;
} }
if (!wasDragStarted && selectedBlueprintAlreadySelectedOnMouseDown && SelectedItems.Count == 1) if (selectedBlueprintAlreadySelectedOnMouseDown && SelectedItems.Count == 1)
{ {
// If a click occurred and was handled by the currently selected blueprint but didn't result in a drag, // If a click occurred and was handled by the currently selected blueprint but didn't result in a drag,
// cycle between other blueprints which are also under the cursor. // cycle between other blueprints which are also under the cursor.
@ -472,7 +478,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
/// <summary> /// <summary>
/// Select all blueprints in a selection area specified by <see cref="DragBox"/>. /// Select all blueprints in a selection area specified by <see cref="DragBox"/>.
/// </summary> /// </summary>
protected virtual void UpdateSelectionFromDragBox() protected virtual void UpdateSelectionFromDragBox(HashSet<T> selectionBeforeDrag)
{ {
var quad = DragBox.Box.ScreenSpaceDrawQuad; var quad = DragBox.Box.ScreenSpaceDrawQuad;
@ -482,7 +488,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
{ {
case SelectionState.Selected: case SelectionState.Selected:
// Selection is preserved even after blueprint becomes dead. // Selection is preserved even after blueprint becomes dead.
if (!quad.Contains(blueprint.ScreenSpaceSelectionPoint)) if (!quad.Contains(blueprint.ScreenSpaceSelectionPoint) && !selectionBeforeDrag.Contains(blueprint.Item))
blueprint.Deselect(); blueprint.Deselect();
break; break;
@ -535,6 +541,8 @@ namespace osu.Game.Screens.Edit.Compose.Components
/// </summary> /// </summary>
private bool wasDragStarted; private bool wasDragStarted;
private readonly HashSet<T> selectionBeforeDrag = new HashSet<T>();
/// <summary> /// <summary>
/// Attempts to begin the movement of any selected blueprints. /// Attempts to begin the movement of any selected blueprints.
/// </summary> /// </summary>

View File

@ -173,7 +173,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
protected sealed override DragBox CreateDragBox() => new TimelineDragBox(); protected sealed override DragBox CreateDragBox() => new TimelineDragBox();
protected override void UpdateSelectionFromDragBox() protected override void UpdateSelectionFromDragBox(HashSet<HitObject> selectionBeforeDrag)
{ {
Composer.BlueprintContainer.CommitIfPlacementActive(); Composer.BlueprintContainer.CommitIfPlacementActive();
@ -191,6 +191,9 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
bool shouldBeSelected(HitObject hitObject) bool shouldBeSelected(HitObject hitObject)
{ {
if (selectionBeforeDrag.Contains(hitObject))
return true;
double midTime = (hitObject.StartTime + hitObject.GetEndTime()) / 2; double midTime = (hitObject.StartTime + hitObject.GetEndTime()) / 2;
return minTime <= midTime && midTime <= maxTime; return minTime <= midTime && midTime <= maxTime;
} }