1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-15 03:22:55 +08:00

Improve drag box selection logic

`AllowDeselectionDuringDrag` is remove.
Instead, selected hit objects are not automatically deselected
when clock is seeked to a later time (the hit object is dead).
Update drag box selection even if mouse is not moved
(in case clock is running or scroll wheel is used).
This commit is contained in:
ekrctb 2022-10-11 14:11:45 +09:00
parent cb21126623
commit 1a24762f9b
2 changed files with 31 additions and 12 deletions

View File

@ -15,6 +15,7 @@ using osu.Framework.Graphics.Containers;
using osu.Framework.Input; using osu.Framework.Input;
using osu.Framework.Input.Bindings; using osu.Framework.Input.Bindings;
using osu.Framework.Input.Events; using osu.Framework.Input.Events;
using osu.Game.Graphics.UserInterface;
using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Edit;
using osuTK; using osuTK;
using osuTK.Input; using osuTK.Input;
@ -106,11 +107,6 @@ namespace osu.Game.Screens.Edit.Compose.Components
protected virtual DragBox CreateDragBox() => new DragBox(); protected virtual DragBox CreateDragBox() => new DragBox();
/// <summary>
/// Whether this component is in a state where items outside a drag selection should be deselected. If false, selection will only be added to.
/// </summary>
protected virtual bool AllowDeselectionDuringDrag => true;
protected override bool OnMouseDown(MouseDownEvent e) protected override bool OnMouseDown(MouseDownEvent e)
{ {
bool selectionPerformed = performMouseDownActions(e); bool selectionPerformed = performMouseDownActions(e);
@ -389,12 +385,19 @@ namespace osu.Game.Screens.Edit.Compose.Components
foreach (var blueprint in SelectionBlueprints) foreach (var blueprint in SelectionBlueprints)
{ {
if (blueprint.IsSelected && !AllowDeselectionDuringDrag) switch (blueprint.State)
continue; {
case SelectionState.Selected:
// Selection is preserved even after blueprint becomes dead.
if (!quad.Contains(blueprint.ScreenSpaceSelectionPoint))
blueprint.Deselect();
break;
bool shouldBeSelected = blueprint.IsAlive && blueprint.IsPresent && quad.Contains(blueprint.ScreenSpaceSelectionPoint); case SelectionState.NotSelected:
if (blueprint.IsSelected != shouldBeSelected) if (blueprint.IsAlive && blueprint.IsPresent && quad.Contains(blueprint.ScreenSpaceSelectionPoint))
blueprint.ToggleSelection(); blueprint.Select();
break;
}
} }
} }

View File

@ -39,6 +39,8 @@ namespace osu.Game.Screens.Edit.Compose.Components
private PlacementBlueprint currentPlacement; private PlacementBlueprint currentPlacement;
private InputManager inputManager; private InputManager inputManager;
private DragEvent lastDragEvent;
/// <remarks> /// <remarks>
/// Positional input must be received outside the container's bounds, /// Positional input must be received outside the container's bounds,
/// in order to handle composer blueprints which are partially offscreen. /// in order to handle composer blueprints which are partially offscreen.
@ -83,8 +85,6 @@ namespace osu.Game.Screens.Edit.Compose.Components
} }
} }
protected override bool AllowDeselectionDuringDrag => !EditorClock.IsRunning;
protected override void TransferBlueprintFor(HitObject hitObject, DrawableHitObject drawableObject) protected override void TransferBlueprintFor(HitObject hitObject, DrawableHitObject drawableObject)
{ {
base.TransferBlueprintFor(hitObject, drawableObject); base.TransferBlueprintFor(hitObject, drawableObject);
@ -120,6 +120,18 @@ namespace osu.Game.Screens.Edit.Compose.Components
return false; return false;
} }
protected override void OnDrag(DragEvent e)
{
base.OnDrag(e);
lastDragEvent = e;
}
protected override void OnDragEnd(DragEndEvent e)
{
base.OnDragEnd(e);
lastDragEvent = null;
}
/// <summary> /// <summary>
/// Move the current selection spatially by the specified delta, in gamefield coordinates (ie. the same coordinates as the blueprints). /// Move the current selection spatially by the specified delta, in gamefield coordinates (ie. the same coordinates as the blueprints).
/// </summary> /// </summary>
@ -236,6 +248,10 @@ namespace osu.Game.Screens.Edit.Compose.Components
{ {
base.Update(); base.Update();
// trigger every frame so drags continue to update selection while seeking time.
if (lastDragEvent != null)
OnDrag(lastDragEvent);
if (currentPlacement != null) if (currentPlacement != null)
{ {
switch (currentPlacement.PlacementActive) switch (currentPlacement.PlacementActive)