forked from gui-cs/Terminal.Gui
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request gui-cs#3625 from tig/v2-IOrientation
Adds `IOrientation` and `OrientationHelper` - opinionated changing/changed event pattern
- Loading branch information
Showing
16 changed files
with
997 additions
and
426 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
| ||
namespace Terminal.Gui; | ||
using System; | ||
|
||
/// <summary> | ||
/// Implement this interface to provide orientation support. | ||
/// </summary> | ||
/// <remarks> | ||
/// See <see cref="OrientationHelper"/> for a helper class that implements this interface. | ||
/// </remarks> | ||
public interface IOrientation | ||
{ | ||
/// <summary> | ||
/// Gets or sets the orientation of the View. | ||
/// </summary> | ||
Orientation Orientation { get; set; } | ||
|
||
/// <summary> | ||
/// Raised when <see cref="Orientation"/> is changing. Can be cancelled. | ||
/// </summary> | ||
public event EventHandler<CancelEventArgs<Orientation>> OrientationChanging; | ||
|
||
/// <summary> | ||
/// Called when <see cref="Orientation"/> is changing. | ||
/// </summary> | ||
/// <param name="currentOrientation">The current orientation.</param> | ||
/// <param name="newOrientation">The new orientation.</param> | ||
/// <returns><see langword="true"/> to cancel the change.</returns> | ||
public bool OnOrientationChanging (Orientation currentOrientation, Orientation newOrientation) { return false; } | ||
|
||
/// <summary> | ||
/// Raised when <see cref="Orientation"/> has changed. | ||
/// </summary> | ||
public event EventHandler<EventArgs<Orientation>> OrientationChanged; | ||
|
||
/// <summary> | ||
/// Called when <see cref="Orientation"/> has been changed. | ||
/// </summary> | ||
/// <param name="newOrientation"></param> | ||
/// <returns></returns> | ||
public void OnOrientationChanged (Orientation newOrientation) { return; } | ||
} |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
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; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.