#nullable enable
namespace Terminal.Gui;
///
/// Helper class for implementing .
///
///
///
/// Implements the standard pattern for changing/changed events.
///
///
///
///
/// private class OrientedView : View, IOrientation
/// {
/// private readonly OrientationHelper _orientationHelper;
///
/// public OrientedView ()
/// {
/// _orientationHelper = new (this);
/// Orientation = Orientation.Vertical;
/// _orientationHelper.OrientationChanging += (sender, e) => OrientationChanging?.Invoke (this, e);
/// _orientationHelper.OrientationChanged += (sender, e) => OrientationChanged?.Invoke (this, e);
/// }
///
/// public Orientation Orientation
/// {
/// get => _orientationHelper.Orientation;
/// set => _orientationHelper.Orientation = value;
/// }
///
/// public event EventHandler<CancelEventArgs<Orientation>> OrientationChanging;
/// public event EventHandler<EventArgs<Orientation>> OrientationChanged;
///
/// public bool OnOrientationChanging (Orientation currentOrientation, Orientation newOrientation)
/// {
/// // Custom logic before orientation changes
/// return false; // Return true to cancel the change
/// }
///
/// public void OnOrientationChanged (Orientation newOrientation)
/// {
/// // Custom logic after orientation has changed
/// }
/// }
///
///
public class OrientationHelper
{
private Orientation _orientation;
private readonly IOrientation _owner;
///
/// Initializes a new instance of the class.
///
/// Specifies the object that owns this helper instance and implements .
public OrientationHelper (IOrientation owner) { _owner = owner; }
///
/// Gets or sets the orientation of the View.
///
public Orientation Orientation
{
get => _orientation;
set
{
if (_orientation == value)
{
return;
}
// Best practice is to invoke the virtual method first.
// This allows derived classes to handle the event and potentially cancel it.
if (_owner?.OnOrientationChanging (value, _orientation) ?? false)
{
return;
}
// If the event is not canceled by the virtual method, raise the event to notify any external subscribers.
CancelEventArgs args = new (in _orientation, ref value);
OrientationChanging?.Invoke (_owner, args);
if (args.Cancel)
{
return;
}
// If the event is not canceled, update the value.
Orientation old = _orientation;
if (_orientation != value)
{
_orientation = value;
if (_owner is { })
{
_owner.Orientation = value;
}
}
// Best practice is to invoke the virtual method first.
_owner?.OnOrientationChanged (_orientation);
// Even though Changed is not cancelable, it is still a good practice to raise the event after.
OrientationChanged?.Invoke (_owner, new (in _orientation));
}
}
///
/// Raised when the orientation is changing. This is cancelable.
///
///
///
/// Views that implement should raise
/// after the orientation has changed
/// (_orientationHelper.OrientationChanging += (sender, e) => OrientationChanging?.Invoke (this, e);
).
///
///
/// This event will be raised after the method is called (assuming
/// it was not canceled).
///
///
public event EventHandler>? OrientationChanging;
///
/// Raised when the orientation has changed.
///
///
///
/// Views that implement should raise
/// after the orientation has changed
/// (_orientationHelper.OrientationChanged += (sender, e) => OrientationChanged?.Invoke (this, e);
).
///
///
/// This event will be raised after the method is called.
///
///
public event EventHandler>? OrientationChanged;
}