mirror of
https://github.com/ppy/osu.git
synced 2026-05-19 06:31:19 +08:00
e05b6f44b9
(partially) Closes: #36233 Surpasses: #36244 This PR meant to be one of the last steps that finally make editor use the new forms. Initially it meant to only change one SliderWithTextBoxInput in "Effects section" in timing screen, however soon after it was obvious that there's many other places that still using it. This currently won't affect IndeterminateSliderWithTextBoxInput that is being used in hitsounds, for example, since I think it needs more consideration. Anyways, with this PR, SliderWithTextBoxInput, will no longer be used at all, as it's going to be replaced with modern FormSliderBar Comparison: |master|this PR| |:---:|:---:| |<img width="510" height="316" alt="532203751-eb965923-d3a8-441d-a7c8-5c364a6328ad" src="https://github.com/user-attachments/assets/268b45b8-e235-494f-91a5-d00db057dba8" />|<img width="540" height="321" alt="535466527-3a700a8b-bc3c-4610-998f-a4e55ee03eed" src="https://github.com/user-attachments/assets/20cd4b58-b0bd-49bc-8c48-7de5cf8556b3" />| |<img width="694" height="639" alt="534509844-f00e4da4-53c4-45e8-80ea-1be62da6c83b" src="https://github.com/user-attachments/assets/398c4484-a867-4df1-9de3-0940aa748a01" />|<img width="720" height="433" alt="изображение" src="https://github.com/user-attachments/assets/b6359443-a224-4a55-b171-07e8f013cf46" />| |<img width="715" height="353" alt="534509421-a6ac950f-16e8-4a16-bca6-1a781f82135f" src="https://github.com/user-attachments/assets/4854312b-772f-4b81-a800-89e58d4c715d" />|<img width="710" height="296" alt="изображение" src="https://github.com/user-attachments/assets/a7fed53e-e006-4285-92c9-bb84cb603f60" />| |<img width="717" height="374" alt="534509478-80222623-7766-481d-8682-088276d415ee" src="https://github.com/user-attachments/assets/8143b6dc-4599-45d5-bd3b-f059caf3d93d" />|<img width="718" height="328" alt="изображение" src="https://github.com/user-attachments/assets/bffa04de-983c-45ae-a1ec-373701ea0e49" />| |<img width="702" height="446" alt="534509935-58954060-7ac1-4392-8754-a58f909e86aa" src="https://github.com/user-attachments/assets/2bb67a2d-3f57-42a1-96ce-b30b4891e1a4" />|<img width="722" height="386" alt="изображение" src="https://github.com/user-attachments/assets/01b7fff4-7f31-4aac-90c9-353b15f4964e" />|
206 lines
7.7 KiB
C#
206 lines
7.7 KiB
C#
// 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;
|
|
using System.Linq;
|
|
using osu.Framework.Allocation;
|
|
using osu.Framework.Bindables;
|
|
using osu.Framework.Extensions;
|
|
using osu.Framework.Graphics;
|
|
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;
|
|
using osu.Game.Screens.Edit.Components.RadioButtons;
|
|
using osu.Game.Screens.Edit.Compose.Components;
|
|
using osuTK;
|
|
|
|
namespace osu.Game.Rulesets.Osu.Edit
|
|
{
|
|
public partial class PreciseRotationPopover : OsuPopover
|
|
{
|
|
private readonly SelectionRotationHandler rotationHandler;
|
|
|
|
private readonly OsuGridToolboxGroup gridToolbox;
|
|
|
|
private readonly Bindable<PreciseRotationInfo> rotationInfo = new Bindable<PreciseRotationInfo>(new PreciseRotationInfo(0, EditorOrigin.GridCentre));
|
|
|
|
private FormSliderBar<float> angleInput { get; set; } = 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;
|
|
this.gridToolbox = gridToolbox;
|
|
|
|
AllowableAnchors = new[] { Anchor.CentreLeft, Anchor.CentreRight };
|
|
}
|
|
|
|
[BackgroundDependencyLoader]
|
|
private void load(OsuConfigManager config)
|
|
{
|
|
configRotationOrigin = config.GetBindable<EditorOrigin>(OsuSetting.EditorRotationOrigin);
|
|
|
|
Child = new FillFlowContainer
|
|
{
|
|
Width = 220,
|
|
AutoSizeAxes = Axes.Y,
|
|
Spacing = new Vector2(5),
|
|
Children = new Drawable[]
|
|
{
|
|
angleInput = new FormSliderBar<float>
|
|
{
|
|
Caption = "Angle (degrees)",
|
|
Current = new BindableNumber<float>
|
|
{
|
|
MinValue = -360,
|
|
MaxValue = 360,
|
|
Precision = 1
|
|
},
|
|
KeyboardStep = 1f,
|
|
TabbableContentContainer = this
|
|
},
|
|
rotationOrigin = new EditorRadioButtonCollection
|
|
{
|
|
RelativeSizeAxes = Axes.X,
|
|
Items = new[]
|
|
{
|
|
gridCentreButton = new RadioButton("Grid centre",
|
|
() => rotationInfo.Value = rotationInfo.Value with { Origin = EditorOrigin.GridCentre },
|
|
() => new SpriteIcon { Icon = FontAwesome.Regular.PlusSquare }),
|
|
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 = EditorOrigin.SelectionCentre },
|
|
() => new SpriteIcon { Icon = FontAwesome.Solid.VectorSquare })
|
|
}
|
|
}
|
|
}
|
|
};
|
|
selectionCentreButton.Selected.DisabledChanged += isDisabled =>
|
|
{
|
|
selectionCentreButton.TooltipText = isDisabled ? "Select more than one object to perform selection-based rotation." : string.Empty;
|
|
};
|
|
}
|
|
|
|
protected override void LoadComplete()
|
|
{
|
|
base.LoadComplete();
|
|
|
|
ScheduleAfterChildren(() => angleInput.TakeFocus());
|
|
angleInput.Current.BindValueChanged(angle => rotationInfo.Value = rotationInfo.Value with { Degrees = angle.NewValue });
|
|
|
|
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 =>
|
|
{
|
|
// can happen if the popover is dismissed by a keyboard key press while dragging UI controls
|
|
if (!rotationHandler.OperationInProgress.Value)
|
|
return;
|
|
|
|
rotationHandler.Update(rotation.NewValue.Degrees, getOriginPosition(rotation.NewValue));
|
|
});
|
|
}
|
|
|
|
private Vector2? getOriginPosition(PreciseRotationInfo rotation) =>
|
|
rotation.Origin switch
|
|
{
|
|
EditorOrigin.GridCentre => gridToolbox.StartPosition.Value,
|
|
EditorOrigin.PlayfieldCentre => OsuPlayfield.BASE_SIZE / 2,
|
|
EditorOrigin.SelectionCentre => null,
|
|
_ => throw new ArgumentOutOfRangeException(nameof(rotation))
|
|
};
|
|
|
|
protected override void PopIn()
|
|
{
|
|
base.PopIn();
|
|
rotationHandler.Begin();
|
|
}
|
|
|
|
protected override void PopOut()
|
|
{
|
|
base.PopOut();
|
|
|
|
if (IsLoaded)
|
|
rotationHandler.Commit();
|
|
}
|
|
|
|
public override bool OnPressed(KeyBindingPressEvent<GlobalAction> e)
|
|
{
|
|
if (e.Action == GlobalAction.Select && !e.Repeat)
|
|
{
|
|
this.HidePopover();
|
|
return true;
|
|
}
|
|
|
|
return base.OnPressed(e);
|
|
}
|
|
}
|
|
|
|
public record PreciseRotationInfo(float Degrees, EditorOrigin Origin);
|
|
}
|