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

Convert 'grid from points' button to placement tool

This commit is contained in:
OliBomby 2024-09-23 16:36:11 +02:00
parent 1a81e12192
commit 0a5a463380
5 changed files with 105 additions and 96 deletions

View File

@ -0,0 +1,83 @@
// 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.Allocation;
using osu.Framework.Input.Events;
using osu.Game.Rulesets.Edit;
using osuTK;
using osuTK.Input;
namespace osu.Game.Rulesets.Osu.Edit.Blueprints
{
public partial class GridPlacementBlueprint : PlacementBlueprint
{
[Resolved]
private HitObjectComposer? hitObjectComposer { get; set; }
private OsuGridToolboxGroup gridToolboxGroup = null!;
private Vector2 originalOrigin;
private float originalSpacing;
private float originalRotation;
[BackgroundDependencyLoader]
private void load(OsuGridToolboxGroup gridToolboxGroup)
{
this.gridToolboxGroup = gridToolboxGroup;
originalOrigin = gridToolboxGroup.StartPosition.Value;
originalSpacing = gridToolboxGroup.Spacing.Value;
originalRotation = gridToolboxGroup.GridLinesRotation.Value;
}
public override void EndPlacement(bool commit)
{
if (!commit && PlacementActive != PlacementState.Finished)
{
gridToolboxGroup.StartPosition.Value = originalOrigin;
gridToolboxGroup.Spacing.Value = originalSpacing;
gridToolboxGroup.GridLinesRotation.Value = originalRotation;
}
base.EndPlacement(commit);
// You typically only place the grid once, so we switch back to the select tool after placement.
if (commit && hitObjectComposer is OsuHitObjectComposer osuHitObjectComposer)
osuHitObjectComposer.SetSelectTool();
}
protected override bool OnMouseDown(MouseDownEvent e)
{
switch (e.Button)
{
case MouseButton.Right:
EndPlacement(true);
return true;
case MouseButton.Left:
switch (PlacementActive)
{
case PlacementState.Waiting:
BeginPlacement(true);
return true;
case PlacementState.Active:
EndPlacement(true);
return true;
}
break;
}
return base.OnMouseDown(e);
}
public override void UpdateTimeAndPosition(SnapResult result)
{
var pos = ToLocalSpace(result.ScreenSpacePosition);
if (PlacementActive != PlacementState.Active)
gridToolboxGroup.StartPosition.Value = pos;
else
gridToolboxGroup.SetGridFromPoints(gridToolboxGroup.StartPosition.Value, pos);
}
}
}

View File

@ -1,79 +1,29 @@
// 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.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Input.Events;
using osu.Framework.Graphics.Sprites;
using osu.Game.Graphics;
using osu.Game.Rulesets.Edit;
using osuTK;
using osuTK.Input;
using osu.Game.Rulesets.Edit.Tools;
using osu.Game.Rulesets.Osu.Edit.Blueprints;
namespace osu.Game.Rulesets.Osu.Edit
{
public partial class GridFromPointsTool : Drawable
public partial class GridFromPointsTool : CompositionTool
{
[Resolved]
private OsuGridToolboxGroup gridToolboxGroup { get; set; } = null!;
[Resolved(canBeNull: true)]
private IPositionSnapProvider? snapProvider { get; set; }
public bool IsPlacing { get; private set; }
private Vector2? startPosition;
protected override void LoadComplete()
public GridFromPointsTool()
: base("Change grid")
{
base.LoadComplete();
gridToolboxGroup.GridFromPointsClicked += BeginPlacement;
TooltipText = """
Left click to set the origin.
Left click again to set the rotation and spacing.
Right click to only set the origin.
""";
}
public void BeginPlacement()
{
IsPlacing = true;
startPosition = null;
}
public override Drawable CreateIcon() => new SpriteIcon { Icon = OsuIcon.EditorGridSnap };
protected override bool OnMouseDown(MouseDownEvent e)
{
if (!IsPlacing)
return base.OnMouseDown(e);
var pos = snappedLocalPosition(e);
if (!startPosition.HasValue)
startPosition = pos;
else
{
gridToolboxGroup.SetGridFromPoints(startPosition.Value, pos);
IsPlacing = false;
}
if (e.Button == MouseButton.Right)
IsPlacing = false;
return true;
}
protected override bool OnMouseMove(MouseMoveEvent e)
{
if (!IsPlacing)
return base.OnMouseMove(e);
var pos = snappedLocalPosition(e);
if (!startPosition.HasValue)
gridToolboxGroup.StartPosition.Value = pos;
else
gridToolboxGroup.SetGridFromPoints(startPosition.Value, pos);
return true;
}
private Vector2 snappedLocalPosition(UIEvent e)
{
return ToLocalSpace(snapProvider?.FindSnappedPositionAndTime(e.ScreenSpaceMousePosition, ~SnapType.GlobalGrids).ScreenSpacePosition ?? e.ScreenSpaceMousePosition);
}
public override PlacementBlueprint CreatePlacementBlueprint() => new GridPlacementBlueprint();
}
}

View File

@ -13,7 +13,6 @@ using osu.Framework.Input.Bindings;
using osu.Framework.Input.Events;
using osu.Game.Graphics.Containers;
using osu.Game.Graphics.UserInterface;
using osu.Game.Graphics.UserInterfaceV2;
using osu.Game.Input.Bindings;
using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Osu.UI;
@ -86,11 +85,8 @@ namespace osu.Game.Rulesets.Osu.Edit
private ExpandableSlider<float> startPositionYSlider = null!;
private ExpandableSlider<float> spacingSlider = null!;
private ExpandableSlider<float> gridLinesRotationSlider = null!;
private RoundedButton gridFromPointsButton = null!;
private EditorRadioButtonCollection gridTypeButtons = null!;
public event Action? GridFromPointsClicked;
public OsuGridToolboxGroup()
: base("grid")
{
@ -149,12 +145,6 @@ namespace osu.Game.Rulesets.Osu.Edit
Spacing = new Vector2(0f, 10f),
Children = new Drawable[]
{
gridFromPointsButton = new RoundedButton
{
Action = () => GridFromPointsClicked?.Invoke(),
RelativeSizeAxes = Axes.X,
Text = "Grid from points",
},
gridTypeButtons = new EditorRadioButtonCollection
{
RelativeSizeAxes = Axes.X,
@ -220,8 +210,6 @@ namespace osu.Game.Rulesets.Osu.Edit
expandingContainer?.Expanded.BindValueChanged(v =>
{
gridFromPointsButton.FadeTo(v.NewValue ? 1f : 0f, 500, Easing.OutQuint);
gridFromPointsButton.BypassAutoSizeAxes = !v.NewValue ? Axes.Y : Axes.None;
gridTypeButtons.FadeTo(v.NewValue ? 1f : 0f, 500, Easing.OutQuint);
gridTypeButtons.BypassAutoSizeAxes = !v.NewValue ? Axes.Y : Axes.None;
}, true);

View File

@ -45,7 +45,8 @@ namespace osu.Game.Rulesets.Osu.Edit
{
new HitCircleCompositionTool(),
new SliderCompositionTool(),
new SpinnerCompositionTool()
new SpinnerCompositionTool(),
new GridFromPointsTool(),
};
private readonly Bindable<TernaryState> rectangularGridSnapToggle = new Bindable<TernaryState>();
@ -61,8 +62,6 @@ namespace osu.Game.Rulesets.Osu.Edit
private Bindable<HitObject> placementObject;
private GridFromPointsTool gridFromPointsTool;
[Cached(typeof(IDistanceSnapProvider))]
public readonly OsuDistanceSnapProvider DistanceSnapProvider = new OsuDistanceSnapProvider();
@ -100,14 +99,6 @@ namespace osu.Game.Rulesets.Osu.Edit
OsuGridToolboxGroup.GridType.BindValueChanged(updatePositionSnapGrid, true);
LayerAboveRuleset.Add(
// Place it above the playfield and blueprints, so it takes priority when handling input.
gridFromPointsTool = new GridFromPointsTool
{
RelativeSizeAxes = Axes.Both,
}
);
RightToolbox.AddRange(new Drawable[]
{
OsuGridToolboxGroup,
@ -291,7 +282,7 @@ namespace osu.Game.Rulesets.Osu.Edit
foreach (var b in blueprints)
{
if (b.IsSelected && !gridFromPointsTool.IsPlacing)
if (b.IsSelected)
continue;
var snapPositions = b.ScreenSpaceSnapPoints;

View File

@ -77,8 +77,6 @@ namespace osu.Game.Rulesets.Edit
protected readonly Container LayerBelowRuleset = new Container { RelativeSizeAxes = Axes.Both };
protected readonly Container LayerAboveRuleset = new Container { RelativeSizeAxes = Axes.Both };
protected InputManager InputManager { get; private set; }
private Box leftToolboxBackground;
@ -145,8 +143,7 @@ namespace osu.Game.Rulesets.Edit
drawableRulesetWrapper,
// layers above playfield
drawableRulesetWrapper.CreatePlayfieldAdjustmentContainer()
.WithChild(blueprintContainer = CreateBlueprintContainer()),
drawableRulesetWrapper.CreatePlayfieldAdjustmentContainer().WithChild(LayerAboveRuleset),
.WithChild(blueprintContainer = CreateBlueprintContainer())
}
},
new Container
@ -234,7 +231,7 @@ namespace osu.Game.Rulesets.Edit
sampleBankTogglesCollection.AddRange(BlueprintContainer.SampleBankTernaryStates.Select(b => new DrawableTernaryButton(b)));
setSelectTool();
SetSelectTool();
EditorBeatmap.SelectedHitObjects.CollectionChanged += selectionChanged;
}
@ -259,7 +256,7 @@ namespace osu.Game.Rulesets.Edit
{
// it's important this is performed before the similar code in EditorRadioButton disables the button.
if (!timing.NewValue)
setSelectTool();
SetSelectTool();
});
EditorBeatmap.HasTiming.BindValueChanged(hasTiming =>
@ -463,11 +460,11 @@ namespace osu.Game.Rulesets.Edit
if (EditorBeatmap.SelectedHitObjects.Any())
{
// ensure in selection mode if a selection is made.
setSelectTool();
SetSelectTool();
}
}
private void setSelectTool() => toolboxCollection.Items.First().Select();
public void SetSelectTool() => toolboxCollection.Items.First().Select();
private void toolSelected(CompositionTool tool)
{