diff --git a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs index 7b872eef38..b0ac8467c1 100644 --- a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs +++ b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs @@ -84,10 +84,6 @@ namespace osu.Game.Rulesets.Osu.Edit LayerBelowRuleset.AddRange(new Drawable[] { distanceSnapGridContainer = new Container - { - RelativeSizeAxes = Axes.Both - }, - rectangularPositionSnapGrid = new RectangularPositionSnapGrid { RelativeSizeAxes = Axes.Both } @@ -103,12 +99,7 @@ namespace osu.Game.Rulesets.Osu.Edit // we may be entering the screen with a selection already active updateDistanceSnapGrid(); - OsuGridToolboxGroup.StartPositionX.BindValueChanged(x => - rectangularPositionSnapGrid.StartPosition = new Vector2(x.NewValue, rectangularPositionSnapGrid.StartPosition.Y), true); - OsuGridToolboxGroup.StartPositionY.BindValueChanged(y => - rectangularPositionSnapGrid.StartPosition = new Vector2(rectangularPositionSnapGrid.StartPosition.X, y.NewValue), true); - OsuGridToolboxGroup.Spacing.BindValueChanged(s => rectangularPositionSnapGrid.Spacing = new Vector2(s.NewValue), true); - OsuGridToolboxGroup.GridLinesRotation.BindValueChanged(r => rectangularPositionSnapGrid.GridLineRotation = r.NewValue, true); + OsuGridToolboxGroup.GridType.BindValueChanged(updatePositionSnapGrid, true); RightToolbox.AddRange(new EditorToolboxGroup[] { @@ -119,6 +110,49 @@ namespace osu.Game.Rulesets.Osu.Edit ); } + private void updatePositionSnapGrid(ValueChangedEvent obj) + { + if (positionSnapGrid != null) + LayerBelowRuleset.Remove(positionSnapGrid, true); + + switch (obj.NewValue) + { + case PositionSnapGridType.Square: + var rectangularPositionSnapGrid = new RectangularPositionSnapGrid(); + + OsuGridToolboxGroup.Spacing.BindValueChanged(s => rectangularPositionSnapGrid.Spacing = new Vector2(s.NewValue), true); + OsuGridToolboxGroup.GridLinesRotation.BindValueChanged(r => rectangularPositionSnapGrid.GridLineRotation = r.NewValue, true); + + positionSnapGrid = rectangularPositionSnapGrid; + break; + + case PositionSnapGridType.Triangle: + var triangularPositionSnapGrid = new TriangularPositionSnapGrid(); + + OsuGridToolboxGroup.Spacing.BindValueChanged(s => triangularPositionSnapGrid.Spacing = s.NewValue, true); + OsuGridToolboxGroup.GridLinesRotation.BindValueChanged(r => triangularPositionSnapGrid.GridLineRotation = r.NewValue, true); + + positionSnapGrid = triangularPositionSnapGrid; + break; + + default: + throw new NotImplementedException($"{OsuGridToolboxGroup.GridType} has an incorrect value."); + } + + bindPositionSnapGridStartPosition(positionSnapGrid); + positionSnapGrid.RelativeSizeAxes = Axes.Both; + LayerBelowRuleset.Add(positionSnapGrid); + return; + + void bindPositionSnapGridStartPosition(PositionSnapGrid snapGrid) + { + OsuGridToolboxGroup.StartPositionX.BindValueChanged(x => + snapGrid.StartPosition = new Vector2(x.NewValue, snapGrid.StartPosition.Y), true); + OsuGridToolboxGroup.StartPositionY.BindValueChanged(y => + snapGrid.StartPosition = new Vector2(snapGrid.StartPosition.X, y.NewValue), true); + } + } + protected override ComposeBlueprintContainer CreateBlueprintContainer() => new OsuBlueprintContainer(this); @@ -159,7 +193,7 @@ namespace osu.Game.Rulesets.Osu.Edit private readonly Cached distanceSnapGridCache = new Cached(); private double? lastDistanceSnapGridTime; - private RectangularPositionSnapGrid rectangularPositionSnapGrid; + private PositionSnapGrid positionSnapGrid; protected override void Update() { @@ -217,13 +251,13 @@ namespace osu.Game.Rulesets.Osu.Edit { if (rectangularGridSnapToggle.Value == TernaryState.True) { - Vector2 pos = rectangularPositionSnapGrid.GetSnappedPosition(rectangularPositionSnapGrid.ToLocalSpace(result.ScreenSpacePosition)); + Vector2 pos = positionSnapGrid.GetSnappedPosition(positionSnapGrid.ToLocalSpace(result.ScreenSpacePosition)); // A grid which doesn't perfectly fit the playfield can produce a position that is outside of the playfield. // We need to clamp the position to the playfield bounds to ensure that the snapped position is always in bounds. pos = Vector2.Clamp(pos, Vector2.Zero, OsuPlayfield.BASE_SIZE); - result.ScreenSpacePosition = rectangularPositionSnapGrid.ToScreenSpace(pos); + result.ScreenSpacePosition = positionSnapGrid.ToScreenSpace(pos); } } diff --git a/osu.Game/Screens/Edit/Compose/Components/LinedPositionSnapGrid.cs b/osu.Game/Screens/Edit/Compose/Components/LinedPositionSnapGrid.cs index 3616bc1ca1..9ab12e4b71 100644 --- a/osu.Game/Screens/Edit/Compose/Components/LinedPositionSnapGrid.cs +++ b/osu.Game/Screens/Edit/Compose/Components/LinedPositionSnapGrid.cs @@ -5,61 +5,18 @@ using System; using System.Collections.Generic; using System.Linq; using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -using osu.Framework.Layout; using osu.Framework.Utils; using osuTK; namespace osu.Game.Screens.Edit.Compose.Components { - public abstract partial class LinedPositionSnapGrid : CompositeDrawable + public abstract partial class LinedPositionSnapGrid : PositionSnapGrid { - private Vector2 startPosition; - - /// - /// The position of the origin of this in local coordinates. - /// - public Vector2 StartPosition - { - get => startPosition; - set - { - startPosition = value; - GridCache.Invalidate(); - } - } - - protected readonly LayoutValue GridCache = new LayoutValue(Invalidation.RequiredParentSizeToFit); - - protected LinedPositionSnapGrid() - { - Masking = true; - - AddLayout(GridCache); - } - - protected override void Update() - { - base.Update(); - - if (!GridCache.IsValid) - { - ClearInternal(); - - if (DrawWidth > 0 && DrawHeight > 0) - CreateContent(); - - GridCache.Validate(); - } - } - - protected abstract void CreateContent(); - protected void GenerateGridLines(Vector2 step, Vector2 drawSize) { int index = 0; - var currentPosition = startPosition; + var currentPosition = StartPosition; // Make lines the same width independent of display resolution. float lineWidth = DrawWidth / ScreenSpaceDrawQuad.Width; @@ -85,7 +42,7 @@ namespace osu.Game.Screens.Edit.Compose.Components generatedLines.Add(gridLine); index += 1; - currentPosition = startPosition + index * step; + currentPosition = StartPosition + index * step; } if (generatedLines.Count == 0) @@ -120,53 +77,5 @@ namespace osu.Game.Screens.Edit.Compose.Components !Precision.AlmostEquals(b, 0) && Math.Sign(a) != Math.Sign(b); } - - protected void GenerateOutline(Vector2 drawSize) - { - // Make lines the same width independent of display resolution. - float lineWidth = DrawWidth / ScreenSpaceDrawQuad.Width; - - AddRangeInternal(new[] - { - new Box - { - Colour = Colour4.White, - Alpha = 0.3f, - Origin = Anchor.CentreLeft, - RelativeSizeAxes = Axes.X, - Height = lineWidth, - Y = 0, - }, - new Box - { - Colour = Colour4.White, - Alpha = 0.3f, - Origin = Anchor.CentreLeft, - RelativeSizeAxes = Axes.X, - Height = lineWidth, - Y = drawSize.Y, - }, - new Box - { - Colour = Colour4.White, - Alpha = 0.3f, - Origin = Anchor.TopCentre, - RelativeSizeAxes = Axes.Y, - Width = lineWidth, - X = 0, - }, - new Box - { - Colour = Colour4.White, - Alpha = 0.3f, - Origin = Anchor.TopCentre, - RelativeSizeAxes = Axes.Y, - Width = lineWidth, - X = drawSize.X, - }, - }); - } - - public abstract Vector2 GetSnappedPosition(Vector2 original); } } diff --git a/osu.Game/Screens/Edit/Compose/Components/PositionSnapGrid.cs b/osu.Game/Screens/Edit/Compose/Components/PositionSnapGrid.cs new file mode 100644 index 0000000000..dd412e3cd3 --- /dev/null +++ b/osu.Game/Screens/Edit/Compose/Components/PositionSnapGrid.cs @@ -0,0 +1,102 @@ +// Copyright (c) ppy Pty Ltd . 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.Framework.Graphics.Shapes; +using osu.Framework.Layout; +using osuTK; + +namespace osu.Game.Screens.Edit.Compose.Components +{ + public abstract partial class PositionSnapGrid : CompositeDrawable + { + private Vector2 startPosition; + + /// + /// The position of the origin of this in local coordinates. + /// + public Vector2 StartPosition + { + get => startPosition; + set + { + startPosition = value; + GridCache.Invalidate(); + } + } + + protected readonly LayoutValue GridCache = new LayoutValue(Invalidation.RequiredParentSizeToFit); + + protected PositionSnapGrid() + { + Masking = true; + + AddLayout(GridCache); + } + + protected override void Update() + { + base.Update(); + + if (GridCache.IsValid) return; + + ClearInternal(); + + if (DrawWidth > 0 && DrawHeight > 0) + CreateContent(); + + GridCache.Validate(); + } + + protected abstract void CreateContent(); + + protected void GenerateOutline(Vector2 drawSize) + { + // Make lines the same width independent of display resolution. + float lineWidth = DrawWidth / ScreenSpaceDrawQuad.Width; + + AddRangeInternal(new[] + { + new Box + { + Colour = Colour4.White, + Alpha = 0.3f, + Origin = Anchor.CentreLeft, + RelativeSizeAxes = Axes.X, + Height = lineWidth, + Y = 0, + }, + new Box + { + Colour = Colour4.White, + Alpha = 0.3f, + Origin = Anchor.CentreLeft, + RelativeSizeAxes = Axes.X, + Height = lineWidth, + Y = drawSize.Y, + }, + new Box + { + Colour = Colour4.White, + Alpha = 0.3f, + Origin = Anchor.TopCentre, + RelativeSizeAxes = Axes.Y, + Width = lineWidth, + X = 0, + }, + new Box + { + Colour = Colour4.White, + Alpha = 0.3f, + Origin = Anchor.TopCentre, + RelativeSizeAxes = Axes.Y, + Width = lineWidth, + X = drawSize.X, + }, + }); + } + + public abstract Vector2 GetSnappedPosition(Vector2 original); + } +}