123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139 |
- #nullable enable
- namespace Terminal.Gui;
- /// <summary>
- /// Helper class for implementing <see cref="IOrientation"/>.
- /// </summary>
- /// <remarks>
- /// <para>
- /// Implements the standard pattern for changing/changed events.
- /// </para>
- /// </remarks>
- /// <example>
- /// <code>
- /// 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
- /// }
- /// }
- /// </code>
- /// </example>
- public class OrientationHelper
- {
- private Orientation _orientation;
- private readonly IOrientation _owner;
- /// <summary>
- /// Initializes a new instance of the <see cref="OrientationHelper"/> class.
- /// </summary>
- /// <param name="owner">Specifies the object that owns this helper instance and implements <see cref="IOrientation"/>.</param>
- public OrientationHelper (IOrientation owner) { _owner = owner; }
- /// <summary>
- /// Gets or sets the orientation of the View.
- /// </summary>
- 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<Orientation> 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));
- }
- }
- /// <summary>
- /// Raised when the orientation is changing. This is cancelable.
- /// </summary>
- /// <remarks>
- /// <para>
- /// Views that implement <see cref="IOrientation"/> should raise <see cref="IOrientation.OrientationChanging"/>
- /// after the orientation has changed
- /// (<code>_orientationHelper.OrientationChanging += (sender, e) => OrientationChanging?.Invoke (this, e);</code>).
- /// </para>
- /// <para>
- /// This event will be raised after the <see cref="IOrientation.OnOrientationChanging"/> method is called (assuming
- /// it was not canceled).
- /// </para>
- /// </remarks>
- public event EventHandler<CancelEventArgs<Orientation>>? OrientationChanging;
- /// <summary>
- /// Raised when the orientation has changed.
- /// </summary>
- /// <remarks>
- /// <para>
- /// Views that implement <see cref="IOrientation"/> should raise <see cref="IOrientation.OrientationChanged"/>
- /// after the orientation has changed
- /// (<code>_orientationHelper.OrientationChanged += (sender, e) => OrientationChanged?.Invoke (this, e);</code>).
- /// </para>
- /// <para>
- /// This event will be raised after the <see cref="IOrientation.OnOrientationChanged"/> method is called.
- /// </para>
- /// </remarks>
- public event EventHandler<EventArgs<Orientation>>? OrientationChanged;
- }
|