mirror of
https://github.com/ppy/osu.git
synced 2024-12-15 22:22: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:
commit
a258059d43
@ -219,6 +219,51 @@ namespace osu.Game.Tests.Visual.Editing
|
||||
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]
|
||||
public void TestNearestSelection()
|
||||
{
|
||||
|
@ -196,6 +196,11 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
||||
|
||||
DragBox.HandleDrag(e);
|
||||
DragBox.Show();
|
||||
|
||||
selectionBeforeDrag.Clear();
|
||||
if (e.ControlPressed)
|
||||
selectionBeforeDrag.UnionWith(SelectedItems);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -217,6 +222,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
||||
}
|
||||
|
||||
DragBox.Hide();
|
||||
selectionBeforeDrag.Clear();
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
@ -227,7 +233,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
||||
{
|
||||
lastDragEvent.Target = this;
|
||||
DragBox.HandleDrag(lastDragEvent);
|
||||
UpdateSelectionFromDragBox();
|
||||
UpdateSelectionFromDragBox(selectionBeforeDrag);
|
||||
}
|
||||
}
|
||||
|
||||
@ -426,7 +432,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
||||
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 (clickSelectionHandled || doubleClickHandled || isDraggingBlueprint) return true;
|
||||
if (clickSelectionHandled || doubleClickHandled || isDraggingBlueprint || wasDragStarted) return true;
|
||||
|
||||
if (e.Button != MouseButton.Left) return false;
|
||||
|
||||
@ -442,7 +448,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
||||
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,
|
||||
// cycle between other blueprints which are also under the cursor.
|
||||
@ -472,7 +478,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
||||
/// <summary>
|
||||
/// Select all blueprints in a selection area specified by <see cref="DragBox"/>.
|
||||
/// </summary>
|
||||
protected virtual void UpdateSelectionFromDragBox()
|
||||
protected virtual void UpdateSelectionFromDragBox(HashSet<T> selectionBeforeDrag)
|
||||
{
|
||||
var quad = DragBox.Box.ScreenSpaceDrawQuad;
|
||||
|
||||
@ -482,7 +488,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
||||
{
|
||||
case SelectionState.Selected:
|
||||
// Selection is preserved even after blueprint becomes dead.
|
||||
if (!quad.Contains(blueprint.ScreenSpaceSelectionPoint))
|
||||
if (!quad.Contains(blueprint.ScreenSpaceSelectionPoint) && !selectionBeforeDrag.Contains(blueprint.Item))
|
||||
blueprint.Deselect();
|
||||
break;
|
||||
|
||||
@ -535,6 +541,8 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
||||
/// </summary>
|
||||
private bool wasDragStarted;
|
||||
|
||||
private readonly HashSet<T> selectionBeforeDrag = new HashSet<T>();
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to begin the movement of any selected blueprints.
|
||||
/// </summary>
|
||||
|
@ -173,7 +173,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
|
||||
|
||||
protected sealed override DragBox CreateDragBox() => new TimelineDragBox();
|
||||
|
||||
protected override void UpdateSelectionFromDragBox()
|
||||
protected override void UpdateSelectionFromDragBox(HashSet<HitObject> selectionBeforeDrag)
|
||||
{
|
||||
Composer.BlueprintContainer.CommitIfPlacementActive();
|
||||
|
||||
@ -191,6 +191,9 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
|
||||
|
||||
bool shouldBeSelected(HitObject hitObject)
|
||||
{
|
||||
if (selectionBeforeDrag.Contains(hitObject))
|
||||
return true;
|
||||
|
||||
double midTime = (hitObject.StartTime + hitObject.GetEndTime()) / 2;
|
||||
return minTime <= midTime && midTime <= maxTime;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user