Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remember origin for editor scale/rotation popover #30484

Merged
merged 3 commits into from
Nov 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 69 additions & 19 deletions osu.Game.Rulesets.Osu/Edit/PreciseRotationPopover.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Input.Events;
using osu.Game.Configuration;
using osu.Game.Graphics.UserInterfaceV2;
using osu.Game.Input.Bindings;
using osu.Game.Rulesets.Osu.UI;
Expand All @@ -25,13 +26,17 @@ public partial class PreciseRotationPopover : OsuPopover

private readonly OsuGridToolboxGroup gridToolbox;

private readonly Bindable<PreciseRotationInfo> rotationInfo = new Bindable<PreciseRotationInfo>(new PreciseRotationInfo(0, RotationOrigin.GridCentre));
private readonly Bindable<PreciseRotationInfo> rotationInfo = new Bindable<PreciseRotationInfo>(new PreciseRotationInfo(0, EditorOrigin.GridCentre));

private SliderWithTextBoxInput<float> angleInput = null!;
private EditorRadioButtonCollection rotationOrigin = null!;

private RadioButton gridCentreButton = null!;
private RadioButton playfieldCentreButton = null!;
private RadioButton selectionCentreButton = null!;

private Bindable<EditorOrigin> configRotationOrigin = null!;

public PreciseRotationPopover(SelectionRotationHandler rotationHandler, OsuGridToolboxGroup gridToolbox)
{
this.rotationHandler = rotationHandler;
Expand All @@ -41,8 +46,10 @@ public PreciseRotationPopover(SelectionRotationHandler rotationHandler, OsuGridT
}

[BackgroundDependencyLoader]
private void load()
private void load(OsuConfigManager config)
{
configRotationOrigin = config.GetBindable<EditorOrigin>(OsuSetting.EditorRotationOrigin);

Child = new FillFlowContainer
{
Width = 220,
Expand All @@ -66,14 +73,14 @@ private void load()
RelativeSizeAxes = Axes.X,
Items = new[]
{
new RadioButton("Grid centre",
() => rotationInfo.Value = rotationInfo.Value with { Origin = RotationOrigin.GridCentre },
gridCentreButton = new RadioButton("Grid centre",
() => rotationInfo.Value = rotationInfo.Value with { Origin = EditorOrigin.GridCentre },
() => new SpriteIcon { Icon = FontAwesome.Regular.PlusSquare }),
new RadioButton("Playfield centre",
() => rotationInfo.Value = rotationInfo.Value with { Origin = RotationOrigin.PlayfieldCentre },
playfieldCentreButton = new RadioButton("Playfield centre",
() => rotationInfo.Value = rotationInfo.Value with { Origin = EditorOrigin.PlayfieldCentre },
() => new SpriteIcon { Icon = FontAwesome.Regular.Square }),
selectionCentreButton = new RadioButton("Selection centre",
() => rotationInfo.Value = rotationInfo.Value with { Origin = RotationOrigin.SelectionCentre },
() => rotationInfo.Value = rotationInfo.Value with { Origin = EditorOrigin.SelectionCentre },
() => new SpriteIcon { Icon = FontAwesome.Solid.VectorSquare })
}
}
Expand All @@ -95,13 +102,63 @@ protected override void LoadComplete()
angleInput.SelectAll();
});
angleInput.Current.BindValueChanged(angle => rotationInfo.Value = rotationInfo.Value with { Degrees = angle.NewValue });
rotationOrigin.Items.First().Select();

rotationHandler.CanRotateAroundSelectionOrigin.BindValueChanged(e =>
{
selectionCentreButton.Selected.Disabled = !e.NewValue;
}, true);

bool didSelect = false;

configRotationOrigin.BindValueChanged(val =>
{
switch (configRotationOrigin.Value)
{
case EditorOrigin.GridCentre:
if (!gridCentreButton.Selected.Disabled)
{
gridCentreButton.Select();
didSelect = true;
}

break;

case EditorOrigin.PlayfieldCentre:
if (!playfieldCentreButton.Selected.Disabled)
{
playfieldCentreButton.Select();
didSelect = true;
}

break;

case EditorOrigin.SelectionCentre:
if (!selectionCentreButton.Selected.Disabled)
{
selectionCentreButton.Select();
didSelect = true;
}

break;
}
}, true);

if (!didSelect)
rotationOrigin.Items.First(b => !b.Selected.Disabled).Select();

gridCentreButton.Selected.BindValueChanged(b =>
{
if (b.NewValue) configRotationOrigin.Value = EditorOrigin.GridCentre;
});
playfieldCentreButton.Selected.BindValueChanged(b =>
{
if (b.NewValue) configRotationOrigin.Value = EditorOrigin.PlayfieldCentre;
});
selectionCentreButton.Selected.BindValueChanged(b =>
{
if (b.NewValue) configRotationOrigin.Value = EditorOrigin.SelectionCentre;
});

rotationInfo.BindValueChanged(rotation =>
{
rotationHandler.Update(rotation.NewValue.Degrees, getOriginPosition(rotation.NewValue));
Expand All @@ -111,9 +168,9 @@ protected override void LoadComplete()
private Vector2? getOriginPosition(PreciseRotationInfo rotation) =>
rotation.Origin switch
{
RotationOrigin.GridCentre => gridToolbox.StartPosition.Value,
RotationOrigin.PlayfieldCentre => OsuPlayfield.BASE_SIZE / 2,
RotationOrigin.SelectionCentre => null,
EditorOrigin.GridCentre => gridToolbox.StartPosition.Value,
EditorOrigin.PlayfieldCentre => OsuPlayfield.BASE_SIZE / 2,
EditorOrigin.SelectionCentre => null,
_ => throw new ArgumentOutOfRangeException(nameof(rotation))
};

Expand Down Expand Up @@ -143,12 +200,5 @@ public override bool OnPressed(KeyBindingPressEvent<GlobalAction> e)
}
}

public enum RotationOrigin
{
GridCentre,
PlayfieldCentre,
SelectionCentre
}

public record PreciseRotationInfo(float Degrees, RotationOrigin Origin);
public record PreciseRotationInfo(float Degrees, EditorOrigin Origin);
}
88 changes: 68 additions & 20 deletions osu.Game.Rulesets.Osu/Edit/PreciseScalePopover.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Input.Events;
using osu.Game.Configuration;
using osu.Game.Graphics.UserInterface;
using osu.Game.Graphics.UserInterfaceV2;
using osu.Game.Input.Bindings;
Expand All @@ -18,6 +19,7 @@
using osu.Game.Rulesets.Osu.UI;
using osu.Game.Screens.Edit;
using osu.Game.Screens.Edit.Components.RadioButtons;
using osu.Game.Screens.Edit.Compose.Components;
using osuTK;

namespace osu.Game.Rulesets.Osu.Edit
Expand All @@ -28,7 +30,7 @@ public partial class PreciseScalePopover : OsuPopover

private readonly OsuGridToolboxGroup gridToolbox;

private readonly Bindable<PreciseScaleInfo> scaleInfo = new Bindable<PreciseScaleInfo>(new PreciseScaleInfo(1, ScaleOrigin.GridCentre, true, true));
private readonly Bindable<PreciseScaleInfo> scaleInfo = new Bindable<PreciseScaleInfo>(new PreciseScaleInfo(1, EditorOrigin.GridCentre, true, true));

private SliderWithTextBoxInput<float> scaleInput = null!;
private BindableNumber<float> scaleInputBindable = null!;
Expand All @@ -41,6 +43,8 @@ public partial class PreciseScalePopover : OsuPopover
private OsuCheckbox xCheckBox = null!;
private OsuCheckbox yCheckBox = null!;

private Bindable<EditorOrigin> configScaleOrigin = null!;

private BindableList<HitObject> selectedItems { get; } = new BindableList<HitObject>();

public PreciseScalePopover(OsuSelectionScaleHandler scaleHandler, OsuGridToolboxGroup gridToolbox)
Expand All @@ -52,10 +56,12 @@ public PreciseScalePopover(OsuSelectionScaleHandler scaleHandler, OsuGridToolbox
}

[BackgroundDependencyLoader]
private void load(EditorBeatmap editorBeatmap)
private void load(EditorBeatmap editorBeatmap, OsuConfigManager config)
{
selectedItems.BindTo(editorBeatmap.SelectedHitObjects);

configScaleOrigin = config.GetBindable<EditorOrigin>(OsuSetting.EditorScaleOrigin);

Child = new FillFlowContainer
{
Width = 220,
Expand All @@ -82,13 +88,13 @@ private void load(EditorBeatmap editorBeatmap)
Items = new[]
{
gridCentreButton = new RadioButton("Grid centre",
() => setOrigin(ScaleOrigin.GridCentre),
() => setOrigin(EditorOrigin.GridCentre),
() => new SpriteIcon { Icon = FontAwesome.Regular.PlusSquare }),
playfieldCentreButton = new RadioButton("Playfield centre",
() => setOrigin(ScaleOrigin.PlayfieldCentre),
() => setOrigin(EditorOrigin.PlayfieldCentre),
() => new SpriteIcon { Icon = FontAwesome.Regular.Square }),
selectionCentreButton = new RadioButton("Selection centre",
() => setOrigin(ScaleOrigin.SelectionCentre),
() => setOrigin(EditorOrigin.SelectionCentre),
() => new SpriteIcon { Icon = FontAwesome.Solid.VectorSquare })
}
},
Expand Down Expand Up @@ -165,7 +171,56 @@ protected override void LoadComplete()
playfieldCentreButton.Selected.Disabled = scaleHandler.IsScalingSlider.Value && !selectionCentreButton.Selected.Disabled;
gridCentreButton.Selected.Disabled = playfieldCentreButton.Selected.Disabled;

scaleOrigin.Items.First(b => !b.Selected.Disabled).Select();
bool didSelect = false;

configScaleOrigin.BindValueChanged(val =>
{
switch (configScaleOrigin.Value)
{
case EditorOrigin.GridCentre:
if (!gridCentreButton.Selected.Disabled)
{
gridCentreButton.Select();
didSelect = true;
}

break;

case EditorOrigin.PlayfieldCentre:
if (!playfieldCentreButton.Selected.Disabled)
{
playfieldCentreButton.Select();
didSelect = true;
}

break;

case EditorOrigin.SelectionCentre:
if (!selectionCentreButton.Selected.Disabled)
{
selectionCentreButton.Select();
didSelect = true;
}

break;
}
}, true);

if (!didSelect)
scaleOrigin.Items.First(b => !b.Selected.Disabled).Select();

gridCentreButton.Selected.BindValueChanged(b =>
{
if (b.NewValue) configScaleOrigin.Value = EditorOrigin.GridCentre;
});
playfieldCentreButton.Selected.BindValueChanged(b =>
{
if (b.NewValue) configScaleOrigin.Value = EditorOrigin.PlayfieldCentre;
});
selectionCentreButton.Selected.BindValueChanged(b =>
{
if (b.NewValue) configScaleOrigin.Value = EditorOrigin.SelectionCentre;
});

scaleInfo.BindValueChanged(scale =>
{
Expand All @@ -182,7 +237,7 @@ private void updateAxes()

private void updateAxisCheckBoxesEnabled()
{
if (scaleInfo.Value.Origin != ScaleOrigin.SelectionCentre)
if (scaleInfo.Value.Origin != EditorOrigin.SelectionCentre)
{
toggleAxisAvailable(xCheckBox.Current, true);
toggleAxisAvailable(yCheckBox.Current, true);
Expand Down Expand Up @@ -230,7 +285,7 @@ private void updateMinMaxScale()
scaleInputBindable.MinValue = MathF.Min(1, MathF.Max(scale.X, scale.Y));
}

private void setOrigin(ScaleOrigin origin)
private void setOrigin(EditorOrigin origin)
{
scaleInfo.Value = scaleInfo.Value with { Origin = origin };
updateMinMaxScale();
Expand All @@ -241,13 +296,13 @@ private void setOrigin(ScaleOrigin origin)
{
switch (scale.Origin)
{
case ScaleOrigin.GridCentre:
case EditorOrigin.GridCentre:
return gridToolbox.StartPosition.Value;

case ScaleOrigin.PlayfieldCentre:
case EditorOrigin.PlayfieldCentre:
return OsuPlayfield.BASE_SIZE / 2;

case ScaleOrigin.SelectionCentre:
case EditorOrigin.SelectionCentre:
if (selectedItems.Count == 1 && selectedItems.First() is Slider slider)
return slider.Position;

Expand All @@ -271,7 +326,7 @@ private Axes getAdjustAxis(PreciseScaleInfo scale)
return result;
}

private float getRotation(PreciseScaleInfo scale) => scale.Origin == ScaleOrigin.GridCentre ? gridToolbox.GridLinesRotation.Value : 0;
private float getRotation(PreciseScaleInfo scale) => scale.Origin == EditorOrigin.GridCentre ? gridToolbox.GridLinesRotation.Value : 0;

protected override void PopIn()
{
Expand Down Expand Up @@ -299,12 +354,5 @@ public override bool OnPressed(KeyBindingPressEvent<GlobalAction> e)
}
}

public enum ScaleOrigin
{
GridCentre,
PlayfieldCentre,
SelectionCentre
}

public record PreciseScaleInfo(float Scale, ScaleOrigin Origin, bool XAxis, bool YAxis);
public record PreciseScaleInfo(float Scale, EditorOrigin Origin, bool XAxis, bool YAxis);
}
7 changes: 6 additions & 1 deletion osu.Game/Configuration/OsuConfigManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
using osu.Game.Overlays;
using osu.Game.Overlays.Mods.Input;
using osu.Game.Rulesets.Scoring;
using osu.Game.Screens.Edit.Compose.Components;
using osu.Game.Screens.OnlinePlay.Lounge.Components;
using osu.Game.Screens.Select;
using osu.Game.Screens.Select.Filter;
Expand Down Expand Up @@ -193,6 +194,8 @@ protected override void InitialiseDefaults()
SetDefault(OsuSetting.EditorAutoSeekOnPlacement, true);
SetDefault(OsuSetting.EditorLimitedDistanceSnap, false);
SetDefault(OsuSetting.EditorShowSpeedChanges, false);
SetDefault(OsuSetting.EditorScaleOrigin, EditorOrigin.GridCentre);
SetDefault(OsuSetting.EditorRotationOrigin, EditorOrigin.GridCentre);

SetDefault(OsuSetting.HideCountryFlags, false);

Expand Down Expand Up @@ -434,6 +437,8 @@ public enum OsuSetting
EditorTimelineShowTimingChanges,
EditorTimelineShowTicks,
AlwaysShowHoldForMenuButton,
EditorContractSidebars
EditorContractSidebars,
EditorScaleOrigin,
EditorRotationOrigin
}
}
12 changes: 12 additions & 0 deletions osu.Game/Screens/Edit/Compose/Components/EditorOrigin.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Copyright (c) ppy Pty Ltd <[email protected]>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

namespace osu.Game.Screens.Edit.Compose.Components
{
public enum EditorOrigin
{
GridCentre,
PlayfieldCentre,
SelectionCentre
}
}
Loading