Merge pull request #18649 from frenzibyte/selection-context-outside-bounds

Fix context menus not appearing when clicking outside of editor playfield's bounds
This commit is contained in:
Dean Herbert 2022-06-15 17:08:09 +09:00 committed by GitHub
commit 87bf53485a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 30 additions and 12 deletions

View File

@ -10,6 +10,7 @@ using osu.Framework.Graphics.UserInterface;
using osu.Game.Beatmaps;
using osu.Game.Graphics.UserInterface;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Osu;
using osu.Game.Rulesets.Osu.Objects;
@ -61,6 +62,21 @@ namespace osu.Game.Tests.Visual.Editing
AddUntilStep("context menu is visible", () => contextMenuContainer.ChildrenOfType<OsuContextMenu>().Single().State == MenuState.Open);
}
[Test]
public void TestSelectAndShowContextMenuOutsideBounds()
{
var addedObject = new HitCircle { StartTime = 100, Position = OsuPlayfield.BASE_SIZE };
AddStep("add hitobject", () => EditorBeatmap.Add(addedObject));
AddStep("descale blueprint container", () => this.ChildrenOfType<HitObjectComposer>().Single().Scale = new Vector2(0.5f));
AddStep("move mouse to bottom-right", () => InputManager.MoveMouseTo(blueprintContainer.ToScreenSpace(blueprintContainer.LayoutRectangle.BottomRight + new Vector2(10))));
AddStep("right click", () => InputManager.Click(MouseButton.Right));
AddUntilStep("hitobject selected", () => EditorBeatmap.SelectedHitObjects.Single() == addedObject);
AddUntilStep("context menu is visible", () => contextMenuContainer.ChildrenOfType<OsuContextMenu>().Single().State == MenuState.Open);
}
[Test]
public void TestNudgeSelection()
{

View File

@ -106,6 +106,13 @@ namespace osu.Game.Screens.Edit.Compose.Components
/// </summary>
protected virtual bool AllowDeselectionDuringDrag => true;
/// <remarks>
/// Positional input must be received outside the container's bounds,
/// in order to handle blueprints which are partially offscreen.
/// </remarks>
/// <seealso cref="SelectionHandler{T}.ReceivePositionalInputAt"/>
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => true;
protected override bool OnMouseDown(MouseDownEvent e)
{
bool selectionPerformed = performMouseDownActions(e);

View File

@ -30,8 +30,6 @@ namespace osu.Game.Screens.Edit.Compose.Components
/// </summary>
public class ComposeBlueprintContainer : EditorBlueprintContainer
{
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => true;
private readonly Container<PlacementBlueprint> placementBlueprintContainer;
protected new EditorSelectionHandler SelectionHandler => (EditorSelectionHandler)base.SelectionHandler;

View File

@ -97,6 +97,13 @@ namespace osu.Game.Screens.Edit.Compose.Components
#region User Input Handling
/// <remarks>
/// Positional input must be received outside the container's bounds,
/// in order to handle blueprints which are partially offscreen.
/// </remarks>
/// <seealso cref="BlueprintContainer{T}.ReceivePositionalInputAt"/>
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => true;
/// <summary>
/// Handles the selected items being moved.
/// </summary>

View File

@ -33,9 +33,6 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
private Bindable<HitObject> placement;
private SelectionBlueprint<HitObject> placementBlueprint;
// We want children within the timeline to be interactable
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => timeline.ScreenSpaceDrawQuad.Contains(screenSpacePos);
public TimelineBlueprintContainer(HitObjectComposer composer)
: base(composer)
{

View File

@ -6,23 +6,16 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using JetBrains.Annotations;
using osu.Framework.Allocation;
using osu.Framework.Input.Events;
using osu.Game.Input.Bindings;
using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Objects;
using osuTK;
using osuTK.Input;
namespace osu.Game.Screens.Edit.Compose.Components.Timeline
{
internal class TimelineSelectionHandler : EditorSelectionHandler
{
[Resolved]
private Timeline timeline { get; set; }
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => timeline.ScreenSpaceDrawQuad.Contains(screenSpacePos);
// for now we always allow movement. snapping is provided by the Timeline's "distance" snap implementation
public override bool HandleMovement(MoveSelectionEvent<HitObject> moveEvent) => true;