mirror of
https://github.com/ppy/osu.git
synced 2024-11-15 16:27:43 +08:00
Merge pull request #29942 from minetoblend/fix/slider-scale-origin
Fix scaling sliders ignoring the scale origin
This commit is contained in:
commit
145f2b6de7
@ -105,9 +105,7 @@ namespace osu.Game.Rulesets.Osu.Edit
|
|||||||
// is not looking to change the duration of the slider but expand the whole pattern.
|
// is not looking to change the duration of the slider but expand the whole pattern.
|
||||||
if (objectsInScale.Count == 1 && objectsInScale.First().Key is Slider slider)
|
if (objectsInScale.Count == 1 && objectsInScale.First().Key is Slider slider)
|
||||||
{
|
{
|
||||||
var originalInfo = objectsInScale[slider];
|
scaleSlider(slider, scale, actualOrigin, objectsInScale[slider], axisRotation);
|
||||||
Debug.Assert(originalInfo.PathControlPointPositions != null && originalInfo.PathControlPointTypes != null);
|
|
||||||
scaleSlider(slider, scale, originalInfo.PathControlPointPositions, originalInfo.PathControlPointTypes, axisRotation);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -159,21 +157,25 @@ namespace osu.Game.Rulesets.Osu.Edit
|
|||||||
return scale;
|
return scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void scaleSlider(Slider slider, Vector2 scale, Vector2[] originalPathPositions, PathType?[] originalPathTypes, float axisRotation = 0)
|
private void scaleSlider(Slider slider, Vector2 scale, Vector2 origin, OriginalHitObjectState originalInfo, float axisRotation = 0)
|
||||||
{
|
{
|
||||||
|
Debug.Assert(originalInfo.PathControlPointPositions != null && originalInfo.PathControlPointTypes != null);
|
||||||
|
|
||||||
scale = Vector2.ComponentMax(scale, new Vector2(Precision.FLOAT_EPSILON));
|
scale = Vector2.ComponentMax(scale, new Vector2(Precision.FLOAT_EPSILON));
|
||||||
|
|
||||||
// Maintain the path types in case they were defaulted to bezier at some point during scaling
|
// Maintain the path types in case they were defaulted to bezier at some point during scaling
|
||||||
for (int i = 0; i < slider.Path.ControlPoints.Count; i++)
|
for (int i = 0; i < slider.Path.ControlPoints.Count; i++)
|
||||||
{
|
{
|
||||||
slider.Path.ControlPoints[i].Position = GeometryUtils.GetScaledPosition(scale, Vector2.Zero, originalPathPositions[i], axisRotation);
|
slider.Path.ControlPoints[i].Position = GeometryUtils.GetScaledPosition(scale, Vector2.Zero, originalInfo.PathControlPointPositions[i], axisRotation);
|
||||||
slider.Path.ControlPoints[i].Type = originalPathTypes[i];
|
slider.Path.ControlPoints[i].Type = originalInfo.PathControlPointTypes[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Snap the slider's length to the current beat divisor
|
// Snap the slider's length to the current beat divisor
|
||||||
// to calculate the final resulting duration / bounding box before the final checks.
|
// to calculate the final resulting duration / bounding box before the final checks.
|
||||||
slider.SnapTo(snapProvider);
|
slider.SnapTo(snapProvider);
|
||||||
|
|
||||||
|
slider.Position = GeometryUtils.GetScaledPosition(scale, origin, originalInfo.Position, axisRotation);
|
||||||
|
|
||||||
//if sliderhead or sliderend end up outside playfield, revert scaling.
|
//if sliderhead or sliderend end up outside playfield, revert scaling.
|
||||||
Quad scaledQuad = GeometryUtils.GetSurroundingQuad(new OsuHitObject[] { slider });
|
Quad scaledQuad = GeometryUtils.GetSurroundingQuad(new OsuHitObject[] { slider });
|
||||||
(bool xInBounds, bool yInBounds) = isQuadInBounds(scaledQuad);
|
(bool xInBounds, bool yInBounds) = isQuadInBounds(scaledQuad);
|
||||||
@ -182,7 +184,9 @@ namespace osu.Game.Rulesets.Osu.Edit
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
for (int i = 0; i < slider.Path.ControlPoints.Count; i++)
|
for (int i = 0; i < slider.Path.ControlPoints.Count; i++)
|
||||||
slider.Path.ControlPoints[i].Position = originalPathPositions[i];
|
slider.Path.ControlPoints[i].Position = originalInfo.PathControlPointPositions[i];
|
||||||
|
|
||||||
|
slider.Position = originalInfo.Position;
|
||||||
|
|
||||||
// Snap the slider's length again to undo the potentially-invalid length applied by the previous snap.
|
// Snap the slider's length again to undo the potentially-invalid length applied by the previous snap.
|
||||||
slider.SnapTo(snapProvider);
|
slider.SnapTo(snapProvider);
|
||||||
|
@ -10,7 +10,10 @@ using osu.Framework.Graphics.Containers;
|
|||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Game.Graphics.UserInterface;
|
using osu.Game.Graphics.UserInterface;
|
||||||
using osu.Game.Graphics.UserInterfaceV2;
|
using osu.Game.Graphics.UserInterfaceV2;
|
||||||
|
using osu.Game.Rulesets.Objects;
|
||||||
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
using osu.Game.Rulesets.Osu.UI;
|
using osu.Game.Rulesets.Osu.UI;
|
||||||
|
using osu.Game.Screens.Edit;
|
||||||
using osu.Game.Screens.Edit.Components.RadioButtons;
|
using osu.Game.Screens.Edit.Components.RadioButtons;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
|
|
||||||
@ -35,6 +38,8 @@ namespace osu.Game.Rulesets.Osu.Edit
|
|||||||
private OsuCheckbox xCheckBox = null!;
|
private OsuCheckbox xCheckBox = null!;
|
||||||
private OsuCheckbox yCheckBox = null!;
|
private OsuCheckbox yCheckBox = null!;
|
||||||
|
|
||||||
|
private BindableList<HitObject> selectedItems { get; } = new BindableList<HitObject>();
|
||||||
|
|
||||||
public PreciseScalePopover(OsuSelectionScaleHandler scaleHandler, OsuGridToolboxGroup gridToolbox)
|
public PreciseScalePopover(OsuSelectionScaleHandler scaleHandler, OsuGridToolboxGroup gridToolbox)
|
||||||
{
|
{
|
||||||
this.scaleHandler = scaleHandler;
|
this.scaleHandler = scaleHandler;
|
||||||
@ -44,8 +49,10 @@ namespace osu.Game.Rulesets.Osu.Edit
|
|||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load()
|
private void load(EditorBeatmap editorBeatmap)
|
||||||
{
|
{
|
||||||
|
selectedItems.BindTo(editorBeatmap.SelectedHitObjects);
|
||||||
|
|
||||||
Child = new FillFlowContainer
|
Child = new FillFlowContainer
|
||||||
{
|
{
|
||||||
Width = 220,
|
Width = 220,
|
||||||
@ -191,14 +198,26 @@ namespace osu.Game.Rulesets.Osu.Edit
|
|||||||
updateAxisCheckBoxesEnabled();
|
updateAxisCheckBoxesEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Vector2? getOriginPosition(PreciseScaleInfo scale) =>
|
private Vector2? getOriginPosition(PreciseScaleInfo scale)
|
||||||
scale.Origin switch
|
{
|
||||||
|
switch (scale.Origin)
|
||||||
{
|
{
|
||||||
ScaleOrigin.GridCentre => gridToolbox.StartPosition.Value,
|
case ScaleOrigin.GridCentre:
|
||||||
ScaleOrigin.PlayfieldCentre => OsuPlayfield.BASE_SIZE / 2,
|
return gridToolbox.StartPosition.Value;
|
||||||
ScaleOrigin.SelectionCentre => null,
|
|
||||||
_ => throw new ArgumentOutOfRangeException(nameof(scale))
|
case ScaleOrigin.PlayfieldCentre:
|
||||||
};
|
return OsuPlayfield.BASE_SIZE / 2;
|
||||||
|
|
||||||
|
case ScaleOrigin.SelectionCentre:
|
||||||
|
if (selectedItems.Count == 1 && selectedItems.First() is Slider slider)
|
||||||
|
return slider.Position;
|
||||||
|
|
||||||
|
return null;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new ArgumentOutOfRangeException(nameof(scale));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private Axes getAdjustAxis(PreciseScaleInfo scale) => scale.XAxis ? scale.YAxis ? Axes.Both : Axes.X : Axes.Y;
|
private Axes getAdjustAxis(PreciseScaleInfo scale) => scale.XAxis ? scale.YAxis ? Axes.Both : Axes.X : Axes.Y;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user