2023-07-24 00:09:07 +08:00
// 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.Bindables ;
2023-07-31 01:39:30 +08:00
using osu.Framework.Graphics ;
2023-07-24 00:09:07 +08:00
using osuTK ;
namespace osu.Game.Screens.Edit.Compose.Components
{
/// <summary>
/// Base handler for editor rotation operations.
/// </summary>
2023-07-31 01:39:30 +08:00
public partial class SelectionRotationHandler : Component
2023-07-24 00:09:07 +08:00
{
2024-06-25 21:01:43 +08:00
/// <summary>
/// Whether there is any ongoing scale operation right now.
/// </summary>
public Bindable < bool > OperationInProgress { get ; private set ; } = new BindableBool ( ) ;
2023-07-24 00:09:07 +08:00
/// <summary>
2024-01-25 13:09:39 +08:00
/// Whether rotation anchored by the selection origin can currently be performed.
2023-07-24 00:09:07 +08:00
/// </summary>
2024-05-29 15:40:29 +08:00
public Bindable < bool > CanRotateAroundSelectionOrigin { get ; private set ; } = new BindableBool ( ) ;
2023-07-24 00:09:07 +08:00
2024-01-25 17:56:59 +08:00
/// <summary>
/// Whether rotation anchored by the center of the playfield can currently be performed.
/// </summary>
2024-05-29 15:40:29 +08:00
public Bindable < bool > CanRotateAroundPlayfieldOrigin { get ; private set ; } = new BindableBool ( ) ;
2024-01-25 17:56:59 +08:00
2024-09-20 07:07:47 +08:00
/// <summary>
/// Implementation-defined origin point to rotate around when no explicit origin is provided.
/// This field is only assigned during a rotation operation.
/// </summary>
public Vector2 ? DefaultOrigin { get ; protected set ; }
2023-07-24 02:09:31 +08:00
/// <summary>
/// Performs a single, instant, atomic rotation operation.
/// </summary>
/// <remarks>
/// This method is intended to be used in atomic contexts (such as when pressing a single button).
/// For continuous operations, see the <see cref="Begin"/>-<see cref="Update"/>-<see cref="Commit"/> flow.
/// </remarks>
/// <param name="rotation">Rotation to apply in degrees.</param>
/// <param name="origin">
/// The origin point to rotate around.
/// If the default <see langword="null"/> value is supplied, a sane implementation-defined default will be used.
/// </param>
2023-07-24 02:01:30 +08:00
public void Rotate ( float rotation , Vector2 ? origin = null )
{
Begin ( ) ;
Update ( rotation , origin ) ;
Commit ( ) ;
}
2023-07-24 02:09:31 +08:00
/// <summary>
/// Begins a continuous rotation operation.
/// </summary>
/// <remarks>
/// This flow is intended to be used when a rotation operation is made incrementally (such as when dragging a rotation handle or slider).
/// For instantaneous, atomic operations, use the convenience <see cref="Rotate"/> method.
/// </remarks>
2023-07-24 00:09:07 +08:00
public virtual void Begin ( )
{
2024-06-25 21:01:43 +08:00
OperationInProgress . Value = true ;
2023-07-24 00:09:07 +08:00
}
2023-07-24 02:09:31 +08:00
/// <summary>
/// Updates a continuous rotation operation.
/// Must be preceded by a <see cref="Begin"/> call.
/// </summary>
/// <remarks>
/// <para>
/// This flow is intended to be used when a rotation operation is made incrementally (such as when dragging a rotation handle or slider).
/// As such, the values of <paramref name="rotation"/> and <paramref name="origin"/> supplied should be relative to the state of the objects being rotated
/// when <see cref="Begin"/> was called, rather than instantaneous deltas.
/// </para>
/// <para>
/// For instantaneous, atomic operations, use the convenience <see cref="Rotate"/> method.
/// </para>
/// </remarks>
/// <param name="rotation">Rotation to apply in degrees.</param>
/// <param name="origin">
/// The origin point to rotate around.
/// If the default <see langword="null"/> value is supplied, a sane implementation-defined default will be used.
/// </param>
2023-07-24 02:01:30 +08:00
public virtual void Update ( float rotation , Vector2 ? origin = null )
2023-07-24 00:09:07 +08:00
{
}
2023-07-24 02:09:31 +08:00
/// <summary>
/// Ends a continuous rotation operation.
/// Must be preceded by a <see cref="Begin"/> call.
/// </summary>
/// <remarks>
/// This flow is intended to be used when a rotation operation is made incrementally (such as when dragging a rotation handle or slider).
/// For instantaneous, atomic operations, use the convenience <see cref="Rotate"/> method.
/// </remarks>
2023-07-24 00:09:07 +08:00
public virtual void Commit ( )
{
2024-06-25 21:01:43 +08:00
OperationInProgress . Value = false ;
2023-07-24 00:09:07 +08:00
}
}
}