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

Merge pull request #18088 from peppy/fix-editor-toolbox-click-through

Fix clicks and drags around editor toolboxes resulting in unexpected interactions
This commit is contained in:
Dean Herbert 2022-05-04 19:42:32 +09:00 committed by GitHub
commit e4ac714c6d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 103 additions and 65 deletions

View File

@ -19,6 +19,7 @@ using osu.Game.Rulesets.Osu.Edit;
using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Screens.Edit;
using osu.Game.Screens.Edit.Components.RadioButtons;
using osu.Game.Screens.Edit.Components.TernaryButtons;
using osu.Game.Screens.Edit.Compose.Components;
using osuTK;
using osuTK.Input;
@ -70,6 +71,11 @@ namespace osu.Game.Tests.Visual.Editing
Child = editorBeatmapContainer = new EditorBeatmapContainer(Beatmap.Value)
{
Child = hitObjectComposer = new OsuHitObjectComposer(new OsuRuleset())
{
// force the composer to fully overlap the playfield area by setting a 4:3 aspect ratio.
FillMode = FillMode.Fit,
FillAspectRatio = 4 / 3f
}
};
});
}
@ -87,6 +93,65 @@ namespace osu.Game.Tests.Visual.Editing
AddAssert("Tool changed", () => hitObjectComposer.ChildrenOfType<ComposeBlueprintContainer>().First().CurrentTool is HitCircleCompositionTool);
}
[Test]
public void TestPlacementFailsWhenClickingButton()
{
AddStep("clear all control points and hitobjects", () =>
{
editorBeatmap.ControlPointInfo.Clear();
editorBeatmap.Clear();
});
AddStep("Add timing point", () => editorBeatmap.ControlPointInfo.Add(0, new TimingControlPoint()));
AddStep("Change to hitcircle", () => hitObjectComposer.ChildrenOfType<EditorRadioButton>().First(d => d.Button.Label == "HitCircle").TriggerClick());
AddStep("move mouse to overlapping toggle button", () =>
{
var playfield = hitObjectComposer.Playfield.ScreenSpaceDrawQuad;
var button = hitObjectComposer
.ChildrenOfType<ExpandingToolboxContainer>().First()
.ChildrenOfType<DrawableTernaryButton>().First(b => playfield.Contains(b.ScreenSpaceDrawQuad.Centre));
InputManager.MoveMouseTo(button);
});
AddAssert("no circles placed", () => editorBeatmap.HitObjects.Count == 0);
AddStep("attempt place circle", () => InputManager.Click(MouseButton.Left));
AddAssert("no circles placed", () => editorBeatmap.HitObjects.Count == 0);
}
[Test]
public void TestPlacementWithinToolboxScrollArea()
{
AddStep("clear all control points and hitobjects", () =>
{
editorBeatmap.ControlPointInfo.Clear();
editorBeatmap.Clear();
});
AddStep("Add timing point", () => editorBeatmap.ControlPointInfo.Add(0, new TimingControlPoint()));
AddStep("Change to hitcircle", () => hitObjectComposer.ChildrenOfType<EditorRadioButton>().First(d => d.Button.Label == "HitCircle").TriggerClick());
AddStep("move mouse to scroll area", () =>
{
// Specifically wanting to test the area of overlap between the left expanding toolbox container
// and the playfield/composer.
var scrollArea = hitObjectComposer.ChildrenOfType<ExpandingToolboxContainer>().First().ScreenSpaceDrawQuad;
var playfield = hitObjectComposer.Playfield.ScreenSpaceDrawQuad;
InputManager.MoveMouseTo(new Vector2(scrollArea.TopLeft.X + 1, playfield.Centre.Y));
});
AddAssert("no circles placed", () => editorBeatmap.HitObjects.Count == 0);
AddStep("place circle", () => InputManager.Click(MouseButton.Left));
AddAssert("circle placed", () => editorBeatmap.HitObjects.Count == 1);
}
[Test]
public void TestDistanceSpacingHotkeys()
{

View File

@ -10,14 +10,12 @@ using osu.Framework.Input.Bindings;
using osu.Framework.Input.Events;
using osu.Framework.Localisation;
using osu.Game.Configuration;
using osu.Game.Graphics.Containers;
using osu.Game.Graphics.UserInterface;
using osu.Game.Input.Bindings;
using osu.Game.Overlays;
using osu.Game.Overlays.OSD;
using osu.Game.Overlays.Settings.Sections;
using osu.Game.Rulesets.Objects;
using osuTK;
namespace osu.Game.Rulesets.Edit
{
@ -53,8 +51,9 @@ namespace osu.Game.Rulesets.Edit
[BackgroundDependencyLoader]
private void load()
{
AddInternal(RightSideToolboxContainer = new ExpandingToolboxContainer
AddInternal(RightSideToolboxContainer = new ExpandingToolboxContainer(130, 250)
{
Padding = new MarginPadding { Right = 10 },
Alpha = DistanceSpacingMultiplier.Disabled ? 0 : 1,
Anchor = Anchor.TopRight,
Origin = Anchor.TopRight,
@ -168,20 +167,6 @@ namespace osu.Game.Rulesets.Edit
return DurationToDistance(referenceObject, snappedEndTime - startTime);
}
protected class ExpandingToolboxContainer : ExpandingContainer
{
protected override double HoverExpansionDelay => 250;
public ExpandingToolboxContainer()
: base(130, 250)
{
RelativeSizeAxes = Axes.Y;
Padding = new MarginPadding { Left = 10 };
FillFlow.Spacing = new Vector2(10);
}
}
private class DistanceSpacingToast : Toast
{
private readonly ValueChangedEvent<double> change;

View File

@ -0,0 +1,34 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System.Linq;
using osu.Framework.Graphics;
using osu.Framework.Input.Events;
using osu.Game.Graphics.Containers;
using osuTK;
namespace osu.Game.Rulesets.Edit
{
public class ExpandingToolboxContainer : ExpandingContainer
{
protected override double HoverExpansionDelay => 250;
public ExpandingToolboxContainer(float contractedWidth, float expandedWidth)
: base(contractedWidth, expandedWidth)
{
RelativeSizeAxes = Axes.Y;
FillFlow.Spacing = new Vector2(10);
}
protected override bool ReceivePositionalInputAtSubTree(Vector2 screenSpacePos) => base.ReceivePositionalInputAtSubTree(screenSpacePos) && anyToolboxHovered(screenSpacePos);
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => base.ReceivePositionalInputAt(screenSpacePos) && anyToolboxHovered(screenSpacePos);
private bool anyToolboxHovered(Vector2 screenSpacePos) => FillFlow.Children.Any(d => d.ScreenSpaceDrawQuad.Contains(screenSpacePos));
protected override bool OnMouseDown(MouseDownEvent e) => true;
protected override bool OnClick(ClickEvent e) => true;
}
}

View File

@ -13,7 +13,6 @@ using osu.Framework.Input;
using osu.Framework.Input.Events;
using osu.Framework.Logging;
using osu.Game.Beatmaps;
using osu.Game.Graphics.Containers;
using osu.Game.Rulesets.Configuration;
using osu.Game.Rulesets.Edit.Tools;
using osu.Game.Rulesets.Mods;
@ -115,8 +114,9 @@ namespace osu.Game.Rulesets.Edit
.WithChild(BlueprintContainer = CreateBlueprintContainer())
}
},
new LeftToolboxFlow
new ExpandingToolboxContainer(80, 200)
{
Padding = new MarginPadding { Left = 10 },
Children = new Drawable[]
{
new EditorToolboxGroup("toolbox (1-9)")
@ -382,18 +382,6 @@ namespace osu.Game.Rulesets.Edit
}
#endregion
private class LeftToolboxFlow : ExpandingButtonContainer
{
public LeftToolboxFlow()
: base(80, 200)
{
RelativeSizeAxes = Axes.Y;
Padding = new MarginPadding { Right = 10 };
FillFlow.Spacing = new Vector2(10);
}
}
}
/// <summary>

View File

@ -1,34 +0,0 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Graphics.Containers;
namespace osu.Game.Rulesets.Edit
{
public class ScrollingToolboxGroup : EditorToolboxGroup
{
protected readonly OsuScrollContainer Scroll;
protected readonly FillFlowContainer FillFlow;
protected override Container<Drawable> Content { get; }
public ScrollingToolboxGroup(string title, float scrollAreaHeight)
: base(title)
{
base.Content.Add(Scroll = new OsuScrollContainer
{
RelativeSizeAxes = Axes.X,
Height = scrollAreaHeight,
Child = Content = FillFlow = new FillFlowContainer
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Direction = FillDirection.Vertical,
},
});
}
}
}