mirror of
https://github.com/gui-cs/Terminal.Gui.git
synced 2026-01-02 01:03:29 +01:00
Manual checkout from v2_develop
This commit is contained in:
@@ -1,57 +1,147 @@
|
||||
namespace Terminal.Gui;
|
||||
|
||||
/// <summary>
|
||||
/// Toplevel views are used for both an application's main view (filling the entire screen and
|
||||
/// for modal (pop-up) views such as <see cref="Dialog"/>, <see cref="MessageBox"/>, and
|
||||
/// <see cref="Wizard"/>).
|
||||
/// Toplevel views are used for both an application's main view (filling the entire screen and for modal (pop-up)
|
||||
/// views such as <see cref="Dialog"/>, <see cref="MessageBox"/>, and <see cref="Wizard"/>).
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// Toplevels can run as modal (popup) views, started by calling
|
||||
/// <see cref="Application.Run(Toplevel, Func{Exception,bool})"/>.
|
||||
/// They return control to the caller when <see cref="Application.RequestStop(Toplevel)"/> has
|
||||
/// been called (which sets the <see cref="Toplevel.Running"/> property to <c>false</c>).
|
||||
/// <see cref="Application.Run(Toplevel, Func{Exception,bool})"/>. They return control to the caller when
|
||||
/// <see cref="Application.RequestStop(Toplevel)"/> has been called (which sets the <see cref="Toplevel.Running"/>
|
||||
/// property to <c>false</c>).
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// A Toplevel is created when an application initializes Terminal.Gui by calling
|
||||
/// <see cref="Application.Init"/>.
|
||||
/// The application Toplevel can be accessed via <see cref="Application.Top"/>. Additional
|
||||
/// Toplevels can be created
|
||||
/// and run (e.g. <see cref="Dialog"/>s. To run a Toplevel, create the <see cref="Toplevel"/> and
|
||||
/// call <see cref="Application.Run(Toplevel, Func{Exception,bool})"/>.
|
||||
/// A Toplevel is created when an application initializes Terminal.Gui by calling <see cref="Application.Init"/>.
|
||||
/// The application Toplevel can be accessed via <see cref="Application.Top"/>. Additional Toplevels can be created
|
||||
/// and run (e.g. <see cref="Dialog"/>s. To run a Toplevel, create the <see cref="Toplevel"/> and call
|
||||
/// <see cref="Application.Run(Toplevel, Func{Exception,bool})"/>.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public partial class Toplevel : View
|
||||
{
|
||||
internal static Point? _dragPosition;
|
||||
|
||||
private Point _startGrabPoint;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Toplevel"/> class with the specified
|
||||
/// <see cref="LayoutStyle.Absolute"/> layout.
|
||||
/// </summary>
|
||||
/// <param name="frame">
|
||||
/// A Superview-relative rectangle specifying the location and size for the new
|
||||
/// Toplevel
|
||||
/// </param>
|
||||
public Toplevel (Rect frame) : base (frame) { SetInitialProperties (); }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Toplevel"/> class with
|
||||
/// <see cref="LayoutStyle.Computed"/> layout, defaulting to full screen. The <see cref="View.Width"/> and
|
||||
/// <see cref="View.Height"/> properties
|
||||
/// will be set to the dimensions of the terminal using <see cref="Dim.Fill"/>.
|
||||
/// Initializes a new instance of the <see cref="Toplevel"/> class with <see cref="LayoutStyle.Computed"/> layout,
|
||||
/// defaulting to full screen. The <see cref="View.Width"/> and <see cref="View.Height"/> properties will be set to the
|
||||
/// dimensions of the terminal using <see cref="Dim.Fill"/>.
|
||||
/// </summary>
|
||||
public Toplevel ()
|
||||
{
|
||||
SetInitialProperties ();
|
||||
Width = Dim.Fill ();
|
||||
Height = Dim.Fill ();
|
||||
|
||||
ColorScheme = Colors.ColorSchemes ["TopLevel"];
|
||||
|
||||
Application.GrabbingMouse += Application_GrabbingMouse;
|
||||
Application.UnGrabbingMouse += Application_UnGrabbingMouse;
|
||||
|
||||
// TODO: v2 - ALL Views (Responders??!?!) should support the commands related to
|
||||
// - Focus
|
||||
// Move the appropriate AddCommand calls to `Responder`
|
||||
|
||||
// Things this view knows how to do
|
||||
AddCommand (
|
||||
Command.QuitToplevel,
|
||||
() =>
|
||||
{
|
||||
QuitToplevel ();
|
||||
|
||||
return true;
|
||||
}
|
||||
);
|
||||
|
||||
AddCommand (
|
||||
Command.Suspend,
|
||||
() =>
|
||||
{
|
||||
Driver.Suspend ();
|
||||
;
|
||||
|
||||
return true;
|
||||
}
|
||||
);
|
||||
|
||||
AddCommand (
|
||||
Command.NextView,
|
||||
() =>
|
||||
{
|
||||
MoveNextView ();
|
||||
|
||||
return true;
|
||||
}
|
||||
);
|
||||
|
||||
AddCommand (
|
||||
Command.PreviousView,
|
||||
() =>
|
||||
{
|
||||
MovePreviousView ();
|
||||
|
||||
return true;
|
||||
}
|
||||
);
|
||||
|
||||
AddCommand (
|
||||
Command.NextViewOrTop,
|
||||
() =>
|
||||
{
|
||||
MoveNextViewOrTop ();
|
||||
|
||||
return true;
|
||||
}
|
||||
);
|
||||
|
||||
AddCommand (
|
||||
Command.PreviousViewOrTop,
|
||||
() =>
|
||||
{
|
||||
MovePreviousViewOrTop ();
|
||||
|
||||
return true;
|
||||
}
|
||||
);
|
||||
|
||||
AddCommand (
|
||||
Command.Refresh,
|
||||
() =>
|
||||
{
|
||||
Application.Refresh ();
|
||||
|
||||
return true;
|
||||
}
|
||||
);
|
||||
|
||||
// Default keybindings for this view
|
||||
KeyBindings.Add (Application.QuitKey, Command.QuitToplevel);
|
||||
|
||||
KeyBindings.Add (Key.CursorRight, Command.NextView);
|
||||
KeyBindings.Add (Key.CursorDown, Command.NextView);
|
||||
KeyBindings.Add (Key.CursorLeft, Command.PreviousView);
|
||||
KeyBindings.Add (Key.CursorUp, Command.PreviousView);
|
||||
|
||||
KeyBindings.Add (Key.Tab, Command.NextView);
|
||||
KeyBindings.Add (Key.Tab.WithShift, Command.PreviousView);
|
||||
KeyBindings.Add (Key.Tab.WithCtrl, Command.NextViewOrTop);
|
||||
KeyBindings.Add (Key.Tab.WithShift.WithCtrl, Command.PreviousViewOrTop);
|
||||
|
||||
KeyBindings.Add (Key.F5, Command.Refresh);
|
||||
KeyBindings.Add (Application.AlternateForwardKey, Command.NextViewOrTop); // Needed on Unix
|
||||
KeyBindings.Add (Application.AlternateBackwardKey, Command.PreviousViewOrTop); // Needed on Unix
|
||||
|
||||
#if UNIX_KEY_BINDINGS
|
||||
KeyBindings.Add (Key.Z.WithCtrl, Command.Suspend);
|
||||
KeyBindings.Add (Key.L.WithCtrl, Command.Refresh); // Unix
|
||||
KeyBindings.Add (Key.F.WithCtrl, Command.NextView); // Unix
|
||||
KeyBindings.Add (Key.I.WithCtrl, Command.NextView); // Unix
|
||||
KeyBindings.Add (Key.B.WithCtrl, Command.PreviousView); // Unix
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this <see cref="Toplevel"/> can focus.
|
||||
/// </summary>
|
||||
/// <summary>Gets or sets a value indicating whether this <see cref="Toplevel"/> can focus.</summary>
|
||||
/// <value><c>true</c> if can focus; otherwise, <c>false</c>.</value>
|
||||
public override bool CanFocus => SuperView == null ? true : base.CanFocus;
|
||||
|
||||
@@ -61,14 +151,11 @@ public partial class Toplevel : View
|
||||
/// </summary>
|
||||
public bool IsLoaded { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the menu for this Toplevel.
|
||||
/// </summary>
|
||||
/// <summary>Gets or sets the menu for this Toplevel.</summary>
|
||||
public virtual MenuBar MenuBar { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the <see cref="Toplevel"/> is modal or not.
|
||||
/// If set to <c>false</c> (the default):
|
||||
/// Determines whether the <see cref="Toplevel"/> is modal or not. If set to <c>false</c> (the default):
|
||||
/// <list type="bullet">
|
||||
/// <item>
|
||||
/// <description><see cref="View.OnKeyDown"/> events will propagate keys upwards.</description>
|
||||
@@ -83,36 +170,23 @@ public partial class Toplevel : View
|
||||
/// <description><see cref="View.OnKeyDown"/> events will NOT propagate keys upwards.</description>
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <description>
|
||||
/// The Toplevel will and look like a modal (pop-up) (e.g. see
|
||||
/// <see cref="Dialog"/>.
|
||||
/// </description>
|
||||
/// <description>The Toplevel will and look like a modal (pop-up) (e.g. see <see cref="Dialog"/>.</description>
|
||||
/// </item>
|
||||
/// </list>
|
||||
/// </summary>
|
||||
public bool Modal { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets whether the main loop for this <see cref="Toplevel"/> is running or not.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Setting this property directly is discouraged. Use <see cref="Application.RequestStop"/>
|
||||
/// instead.
|
||||
/// </remarks>
|
||||
/// <summary>Gets or sets whether the main loop for this <see cref="Toplevel"/> is running or not.</summary>
|
||||
/// <remarks>Setting this property directly is discouraged. Use <see cref="Application.RequestStop"/> instead.</remarks>
|
||||
public bool Running { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the status bar for this Toplevel.
|
||||
/// </summary>
|
||||
/// <summary>Gets or sets the status bar for this Toplevel.</summary>
|
||||
public virtual StatusBar StatusBar { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when the Toplevel <see cref="RunState"/> becomes the <see cref="Application.Current"/>
|
||||
/// Toplevel.
|
||||
/// </summary>
|
||||
/// <summary>Invoked when the Toplevel <see cref="RunState"/> becomes the <see cref="Application.Current"/> Toplevel.</summary>
|
||||
public event EventHandler<ToplevelEventArgs> Activate;
|
||||
|
||||
///<inheritdoc/>
|
||||
/// <inheritdoc/>
|
||||
public override void Add (View view)
|
||||
{
|
||||
CanFocus = true;
|
||||
@@ -121,19 +195,15 @@ public partial class Toplevel : View
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when the last child of the Toplevel <see cref="RunState"/> is closed from
|
||||
/// by <see cref="Application.End(RunState)"/>.
|
||||
/// Invoked when the last child of the Toplevel <see cref="RunState"/> is closed from by
|
||||
/// <see cref="Application.End(RunState)"/>.
|
||||
/// </summary>
|
||||
public event EventHandler AllChildClosed;
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when the <see cref="Application.AlternateBackwardKey"/> is changed.
|
||||
/// </summary>
|
||||
/// <summary>Invoked when the <see cref="Application.AlternateBackwardKey"/> is changed.</summary>
|
||||
public event EventHandler<KeyChangedEventArgs> AlternateBackwardKeyChanged;
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when the <see cref="Application.AlternateForwardKey"/> is changed.
|
||||
/// </summary>
|
||||
/// <summary>Invoked when the <see cref="Application.AlternateForwardKey"/> is changed.</summary>
|
||||
public event EventHandler<KeyChangedEventArgs> AlternateForwardKeyChanged;
|
||||
|
||||
/// <summary>
|
||||
@@ -142,20 +212,13 @@ public partial class Toplevel : View
|
||||
/// </summary>
|
||||
public event EventHandler<ToplevelEventArgs> ChildClosed;
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when a child Toplevel's <see cref="RunState"/> has been loaded.
|
||||
/// </summary>
|
||||
/// <summary>Invoked when a child Toplevel's <see cref="RunState"/> has been loaded.</summary>
|
||||
public event EventHandler<ToplevelEventArgs> ChildLoaded;
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when a cjhild Toplevel's <see cref="RunState"/> has been unloaded.
|
||||
/// </summary>
|
||||
/// <summary>Invoked when a cjhild Toplevel's <see cref="RunState"/> has been unloaded.</summary>
|
||||
public event EventHandler<ToplevelEventArgs> ChildUnloaded;
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when the Toplevel's <see cref="RunState"/> is closed by
|
||||
/// <see cref="Application.End(RunState)"/>.
|
||||
/// </summary>
|
||||
/// <summary>Invoked when the Toplevel's <see cref="RunState"/> is closed by <see cref="Application.End(RunState)"/>.</summary>
|
||||
public event EventHandler<ToplevelEventArgs> Closed;
|
||||
|
||||
/// <summary>
|
||||
@@ -164,20 +227,16 @@ public partial class Toplevel : View
|
||||
/// </summary>
|
||||
public event EventHandler<ToplevelClosingEventArgs> Closing;
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when the Toplevel<see cref="RunState"/> ceases to be the <see cref="Application.Current"/>
|
||||
/// Toplevel.
|
||||
/// </summary>
|
||||
/// <summary>Invoked when the Toplevel<see cref="RunState"/> ceases to be the <see cref="Application.Current"/> Toplevel.</summary>
|
||||
public event EventHandler<ToplevelEventArgs> Deactivate;
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when the <see cref="Toplevel"/> <see cref="RunState"/> has begun to be loaded.
|
||||
/// A Loaded event handler is a good place to finalize initialization before calling
|
||||
/// <see cref="Application.RunLoop(RunState)"/>.
|
||||
/// Invoked when the <see cref="Toplevel"/> <see cref="RunState"/> has begun to be loaded. A Loaded event handler
|
||||
/// is a good place to finalize initialization before calling <see cref="Application.RunLoop(RunState)"/>.
|
||||
/// </summary>
|
||||
public event EventHandler Loaded;
|
||||
|
||||
///<inheritdoc/>
|
||||
/// <inheritdoc/>
|
||||
public override bool MouseEvent (MouseEvent mouseEvent)
|
||||
{
|
||||
if (!CanFocus)
|
||||
@@ -234,12 +293,19 @@ public partial class Toplevel : View
|
||||
// BUGBUG: Assumes Frame == Border?
|
||||
GetLocationThatFits (
|
||||
this,
|
||||
mouseEvent.X + (SuperView == null ? mouseEvent.OfX - _startGrabPoint.X : Frame.X - _startGrabPoint.X),
|
||||
mouseEvent.Y + (SuperView == null ? mouseEvent.OfY - _startGrabPoint.Y : Frame.Y - _startGrabPoint.Y),
|
||||
mouseEvent.X
|
||||
+ (SuperView == null
|
||||
? mouseEvent.OfX - _startGrabPoint.X
|
||||
: Frame.X - _startGrabPoint.X),
|
||||
mouseEvent.Y
|
||||
+ (SuperView == null
|
||||
? mouseEvent.OfY - _startGrabPoint.Y
|
||||
: Frame.Y - _startGrabPoint.Y),
|
||||
out nx,
|
||||
out ny,
|
||||
out _,
|
||||
out _);
|
||||
out _
|
||||
);
|
||||
|
||||
_dragPosition = new Point (nx, ny);
|
||||
X = nx;
|
||||
@@ -264,9 +330,7 @@ public partial class Toplevel : View
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Virtual method to invoke the <see cref="AlternateBackwardKeyChanged"/> event.
|
||||
/// </summary>
|
||||
/// <summary>Virtual method to invoke the <see cref="AlternateBackwardKeyChanged"/> event.</summary>
|
||||
/// <param name="e"></param>
|
||||
public virtual void OnAlternateBackwardKeyChanged (KeyChangedEventArgs e)
|
||||
{
|
||||
@@ -274,9 +338,7 @@ public partial class Toplevel : View
|
||||
AlternateBackwardKeyChanged?.Invoke (this, e);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Virtual method to invoke the <see cref="AlternateForwardKeyChanged"/> event.
|
||||
/// </summary>
|
||||
/// <summary>Virtual method to invoke the <see cref="AlternateForwardKeyChanged"/> event.</summary>
|
||||
/// <param name="e"></param>
|
||||
public virtual void OnAlternateForwardKeyChanged (KeyChangedEventArgs e)
|
||||
{
|
||||
@@ -284,7 +346,7 @@ public partial class Toplevel : View
|
||||
AlternateForwardKeyChanged?.Invoke (this, e);
|
||||
}
|
||||
|
||||
///<inheritdoc/>
|
||||
/// <inheritdoc/>
|
||||
public override void OnDrawContent (Rect contentArea)
|
||||
{
|
||||
if (!Visible)
|
||||
@@ -338,15 +400,15 @@ public partial class Toplevel : View
|
||||
}
|
||||
}
|
||||
|
||||
///<inheritdoc/>
|
||||
/// <inheritdoc/>
|
||||
public override bool OnEnter (View view) { return MostFocused?.OnEnter (view) ?? base.OnEnter (view); }
|
||||
|
||||
///<inheritdoc/>
|
||||
/// <inheritdoc/>
|
||||
public override bool OnLeave (View view) { return MostFocused?.OnLeave (view) ?? base.OnLeave (view); }
|
||||
|
||||
/// <summary>
|
||||
/// Called from <see cref="Application.Begin(Toplevel)"/> before the <see cref="Toplevel"/> redraws for
|
||||
/// the first time.
|
||||
/// Called from <see cref="Application.Begin(Toplevel)"/> before the <see cref="Toplevel"/> redraws for the first
|
||||
/// time.
|
||||
/// </summary>
|
||||
public virtual void OnLoaded ()
|
||||
{
|
||||
@@ -360,9 +422,7 @@ public partial class Toplevel : View
|
||||
Loaded?.Invoke (this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Virtual method to invoke the <see cref="QuitKeyChanged"/> event.
|
||||
/// </summary>
|
||||
/// <summary>Virtual method to invoke the <see cref="QuitKeyChanged"/> event.</summary>
|
||||
/// <param name="e"></param>
|
||||
public virtual void OnQuitKeyChanged (KeyChangedEventArgs e)
|
||||
{
|
||||
@@ -370,7 +430,7 @@ public partial class Toplevel : View
|
||||
QuitKeyChanged?.Invoke (this, e);
|
||||
}
|
||||
|
||||
///<inheritdoc/>
|
||||
/// <inheritdoc/>
|
||||
public override void PositionCursor ()
|
||||
{
|
||||
if (!IsOverlappedContainer)
|
||||
@@ -412,9 +472,8 @@ public partial class Toplevel : View
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adjusts the location and size of <paramref name="top"/> within this Toplevel.
|
||||
/// Virtual method enabling implementation of specific positions for inherited <see cref="Toplevel"/>
|
||||
/// views.
|
||||
/// Adjusts the location and size of <paramref name="top"/> within this Toplevel. Virtual method enabling
|
||||
/// implementation of specific positions for inherited <see cref="Toplevel"/> views.
|
||||
/// </summary>
|
||||
/// <param name="top">The Toplevel to adjust.</param>
|
||||
public virtual void PositionToplevel (Toplevel top)
|
||||
@@ -426,7 +485,8 @@ public partial class Toplevel : View
|
||||
out int nx,
|
||||
out int ny,
|
||||
out _,
|
||||
out StatusBar sb);
|
||||
out StatusBar sb
|
||||
);
|
||||
var layoutSubviews = false;
|
||||
var maxWidth = 0;
|
||||
|
||||
@@ -475,16 +535,12 @@ public partial class Toplevel : View
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when the <see cref="Application.QuitKey"/> is changed.
|
||||
/// </summary>
|
||||
/// <summary>Invoked when the <see cref="Application.QuitKey"/> is changed.</summary>
|
||||
public event EventHandler<KeyChangedEventArgs> QuitKeyChanged;
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when the <see cref="Toplevel"/> main loop has started it's first iteration.
|
||||
/// Subscribe to this event to perform tasks when the <see cref="Toplevel"/> has been laid out and
|
||||
/// focus has been set.
|
||||
/// changes.
|
||||
/// Invoked when the <see cref="Toplevel"/> main loop has started it's first iteration. Subscribe to this event to
|
||||
/// perform tasks when the <see cref="Toplevel"/> has been laid out and focus has been set. changes.
|
||||
/// <para>
|
||||
/// A Ready event handler is a good place to finalize initialization after calling
|
||||
/// <see cref="Application.Run(Func{Exception, bool})"/> on this <see cref="Toplevel"/>.
|
||||
@@ -492,7 +548,7 @@ public partial class Toplevel : View
|
||||
/// </summary>
|
||||
public event EventHandler Ready;
|
||||
|
||||
///<inheritdoc/>
|
||||
/// <inheritdoc/>
|
||||
public override void Remove (View view)
|
||||
{
|
||||
if (this is Toplevel Toplevel && Toplevel.MenuBar != null)
|
||||
@@ -503,7 +559,7 @@ public partial class Toplevel : View
|
||||
base.Remove (view);
|
||||
}
|
||||
|
||||
///<inheritdoc/>
|
||||
/// <inheritdoc/>
|
||||
public override void RemoveAll ()
|
||||
{
|
||||
if (this == Application.Top)
|
||||
@@ -575,26 +631,23 @@ public partial class Toplevel : View
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stops and closes the <see cref="Toplevel"/> specified by <paramref name="top"/>. If
|
||||
/// <paramref name="top"/> is the top-most Toplevel,
|
||||
/// <see cref="Application.RequestStop(Toplevel)"/> will be called, causing the application to exit.
|
||||
/// Stops and closes the <see cref="Toplevel"/> specified by <paramref name="top"/>. If <paramref name="top"/> is
|
||||
/// the top-most Toplevel, <see cref="Application.RequestStop(Toplevel)"/> will be called, causing the application to
|
||||
/// exit.
|
||||
/// </summary>
|
||||
/// <param name="top">The Toplevel to request stop.</param>
|
||||
public virtual void RequestStop (Toplevel top) { top.RequestStop (); }
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when the terminal has been resized. The new <see cref="Size"/> of the terminal is provided.
|
||||
/// </summary>
|
||||
/// <summary>Invoked when the terminal has been resized. The new <see cref="Size"/> of the terminal is provided.</summary>
|
||||
public event EventHandler<SizeChangedEventArgs> SizeChanging;
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when the Toplevel <see cref="RunState"/> has been unloaded.
|
||||
/// A Unloaded event handler is a good place to dispose objects after calling
|
||||
/// <see cref="Application.End(RunState)"/>.
|
||||
/// Invoked when the Toplevel <see cref="RunState"/> has been unloaded. A Unloaded event handler is a good place
|
||||
/// to dispose objects after calling <see cref="Application.End(RunState)"/>.
|
||||
/// </summary>
|
||||
public event EventHandler Unloaded;
|
||||
|
||||
///<inheritdoc/>
|
||||
/// <inheritdoc/>
|
||||
protected override void Dispose (bool disposing)
|
||||
{
|
||||
Application.GrabbingMouse -= Application_GrabbingMouse;
|
||||
@@ -618,15 +671,12 @@ public partial class Toplevel : View
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a new location of the <see cref="Toplevel"/> that is within the Bounds of the
|
||||
/// <paramref name="top"/>'s
|
||||
/// <see cref="View.SuperView"/> (e.g. for dragging a Window).
|
||||
/// The `out` parameters are the new X and Y coordinates.
|
||||
/// Gets a new location of the <see cref="Toplevel"/> that is within the Bounds of the <paramref name="top"/>'s
|
||||
/// <see cref="View.SuperView"/> (e.g. for dragging a Window). The `out` parameters are the new X and Y coordinates.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// If <paramref name="top"/> does not have a <see cref="View.SuperView"/> or it's SuperView is not
|
||||
/// <see cref="Application.Top"/>
|
||||
/// the position will be bound by the <see cref="ConsoleDriver.Cols"/> and
|
||||
/// <see cref="Application.Top"/> the position will be bound by the <see cref="ConsoleDriver.Cols"/> and
|
||||
/// <see cref="ConsoleDriver.Rows"/>.
|
||||
/// </remarks>
|
||||
/// <param name="top">The Toplevel that is to be moved.</param>
|
||||
@@ -638,8 +688,7 @@ public partial class Toplevel : View
|
||||
/// <param name="statusBar">The new top most statusBar</param>
|
||||
/// <returns>
|
||||
/// Either <see cref="Application.Top"/> (if <paramref name="top"/> does not have a Super View) or
|
||||
/// <paramref name="top"/>'s SuperView. This can be used to ensure LayoutSubviews is called on the
|
||||
/// correct View.
|
||||
/// <paramref name="top"/>'s SuperView. This can be used to ensure LayoutSubviews is called on the correct View.
|
||||
/// </returns>
|
||||
internal View GetLocationThatFits (
|
||||
Toplevel top,
|
||||
@@ -754,7 +803,9 @@ public partial class Toplevel : View
|
||||
|
||||
if (top.Frame.Height <= maxWidth)
|
||||
{
|
||||
ny = ny + top.Frame.Height > maxWidth ? Math.Max (maxWidth - top.Frame.Height, menuVisible ? 1 : 0) : ny;
|
||||
ny = ny + top.Frame.Height > maxWidth
|
||||
? Math.Max (maxWidth - top.Frame.Height, menuVisible ? 1 : 0)
|
||||
: ny;
|
||||
|
||||
if (ny > top.Frame.Y + top.Frame.Height)
|
||||
{
|
||||
@@ -768,7 +819,6 @@ public partial class Toplevel : View
|
||||
}
|
||||
|
||||
internal virtual void OnActivate (Toplevel deactivated) { Activate?.Invoke (this, new ToplevelEventArgs (deactivated)); }
|
||||
|
||||
internal virtual void OnAllChildClosed () { AllChildClosed?.Invoke (this, EventArgs.Empty); }
|
||||
|
||||
internal virtual void OnChildClosed (Toplevel top)
|
||||
@@ -782,9 +832,7 @@ public partial class Toplevel : View
|
||||
}
|
||||
|
||||
internal virtual void OnChildLoaded (Toplevel top) { ChildLoaded?.Invoke (this, new ToplevelEventArgs (top)); }
|
||||
|
||||
internal virtual void OnChildUnloaded (Toplevel top) { ChildUnloaded?.Invoke (this, new ToplevelEventArgs (top)); }
|
||||
|
||||
internal virtual void OnClosed (Toplevel top) { Closed?.Invoke (this, new ToplevelEventArgs (top)); }
|
||||
|
||||
internal virtual bool OnClosing (ToplevelClosingEventArgs ev)
|
||||
@@ -797,8 +845,8 @@ public partial class Toplevel : View
|
||||
internal virtual void OnDeactivate (Toplevel activated) { Deactivate?.Invoke (this, new ToplevelEventArgs (activated)); }
|
||||
|
||||
/// <summary>
|
||||
/// Called from <see cref="Application.RunLoop"/> after the <see cref="Toplevel"/> has entered the
|
||||
/// first iteration of the loop.
|
||||
/// Called from <see cref="Application.RunLoop"/> after the <see cref="Toplevel"/> has entered the first iteration
|
||||
/// of the loop.
|
||||
/// </summary>
|
||||
internal virtual void OnReady ()
|
||||
{
|
||||
@@ -813,9 +861,7 @@ public partial class Toplevel : View
|
||||
// TODO: Make cancelable?
|
||||
internal virtual void OnSizeChanging (SizeChangedEventArgs size) { SizeChanging?.Invoke (this, size); }
|
||||
|
||||
/// <summary>
|
||||
/// Called from <see cref="Application.End(RunState)"/> before the <see cref="Toplevel"/> is disposed.
|
||||
/// </summary>
|
||||
/// <summary>Called from <see cref="Application.End(RunState)"/> before the <see cref="Toplevel"/> is disposed.</summary>
|
||||
internal virtual void OnUnloaded ()
|
||||
{
|
||||
foreach (Toplevel tl in Subviews.Where (v => v is Toplevel))
|
||||
@@ -871,7 +917,7 @@ public partial class Toplevel : View
|
||||
}
|
||||
}
|
||||
|
||||
private void FocusNearestView (IEnumerable<View> views, Direction direction)
|
||||
private void FocusNearestView (IEnumerable<View> views, NavigationDirection direction)
|
||||
{
|
||||
if (views == null)
|
||||
{
|
||||
@@ -891,7 +937,7 @@ public partial class Toplevel : View
|
||||
|
||||
if (found && v != this)
|
||||
{
|
||||
if (direction == Direction.Forward)
|
||||
if (direction == NavigationDirection.Forward)
|
||||
{
|
||||
SuperView?.FocusNext ();
|
||||
}
|
||||
@@ -950,7 +996,7 @@ public partial class Toplevel : View
|
||||
}
|
||||
else
|
||||
{
|
||||
FocusNearestView (SuperView?.TabIndexes, Direction.Forward);
|
||||
FocusNearestView (SuperView?.TabIndexes, NavigationDirection.Forward);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -991,7 +1037,7 @@ public partial class Toplevel : View
|
||||
}
|
||||
else
|
||||
{
|
||||
FocusNearestView (SuperView?.TabIndexes?.Reverse (), Direction.Backward);
|
||||
FocusNearestView (SuperView?.TabIndexes?.Reverse (), NavigationDirection.Backward);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1037,122 +1083,18 @@ public partial class Toplevel : View
|
||||
Application.RequestStop ();
|
||||
}
|
||||
}
|
||||
|
||||
private void SetInitialProperties ()
|
||||
{
|
||||
ColorScheme = Colors.ColorSchemes ["TopLevel"];
|
||||
|
||||
Application.GrabbingMouse += Application_GrabbingMouse;
|
||||
Application.UnGrabbingMouse += Application_UnGrabbingMouse;
|
||||
|
||||
// TODO: v2 - ALL Views (Responders??!?!) should support the commands related to
|
||||
// - Focus
|
||||
// Move the appropriate AddCommand calls to `Responder`
|
||||
|
||||
// Things this view knows how to do
|
||||
AddCommand (
|
||||
Command.QuitToplevel,
|
||||
() =>
|
||||
{
|
||||
QuitToplevel ();
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
AddCommand (
|
||||
Command.Suspend,
|
||||
() =>
|
||||
{
|
||||
Driver.Suspend ();
|
||||
;
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
AddCommand (
|
||||
Command.NextView,
|
||||
() =>
|
||||
{
|
||||
MoveNextView ();
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
AddCommand (
|
||||
Command.PreviousView,
|
||||
() =>
|
||||
{
|
||||
MovePreviousView ();
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
AddCommand (
|
||||
Command.NextViewOrTop,
|
||||
() =>
|
||||
{
|
||||
MoveNextViewOrTop ();
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
AddCommand (
|
||||
Command.PreviousViewOrTop,
|
||||
() =>
|
||||
{
|
||||
MovePreviousViewOrTop ();
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
AddCommand (
|
||||
Command.Refresh,
|
||||
() =>
|
||||
{
|
||||
Application.Refresh ();
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
// Default keybindings for this view
|
||||
KeyBindings.Add (Application.QuitKey, Command.QuitToplevel);
|
||||
|
||||
KeyBindings.Add (Key.CursorRight, Command.NextView);
|
||||
KeyBindings.Add (Key.CursorDown, Command.NextView);
|
||||
KeyBindings.Add (Key.CursorLeft, Command.PreviousView);
|
||||
KeyBindings.Add (Key.CursorUp, Command.PreviousView);
|
||||
|
||||
KeyBindings.Add (Key.Tab, Command.NextView);
|
||||
KeyBindings.Add (Key.Tab.WithShift, Command.PreviousView);
|
||||
KeyBindings.Add (Key.Tab.WithCtrl, Command.NextViewOrTop);
|
||||
KeyBindings.Add (Key.Tab.WithShift.WithCtrl, Command.PreviousViewOrTop);
|
||||
|
||||
KeyBindings.Add (Key.F5, Command.Refresh);
|
||||
KeyBindings.Add (Application.AlternateForwardKey, Command.NextViewOrTop); // Needed on Unix
|
||||
KeyBindings.Add (Application.AlternateBackwardKey, Command.PreviousViewOrTop); // Needed on Unix
|
||||
|
||||
#if UNIX_KEY_BINDINGS
|
||||
KeyBindings.Add (Key.Z.WithCtrl, Command.Suspend);
|
||||
KeyBindings.Add (Key.L.WithCtrl, Command.Refresh);// Unix
|
||||
KeyBindings.Add (Key.F.WithCtrl, Command.NextView);// Unix
|
||||
KeyBindings.Add (Key.I.WithCtrl, Command.NextView); // Unix
|
||||
KeyBindings.Add (Key.B.WithCtrl, Command.PreviousView);// Unix
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implements the <see cref="IEqualityComparer{T}"/> for comparing two <see cref="Toplevel"/>s
|
||||
/// used by <see cref="StackExtensions"/>.
|
||||
/// Implements the <see cref="IEqualityComparer{T}"/> for comparing two <see cref="Toplevel"/>s used by
|
||||
/// <see cref="StackExtensions"/>.
|
||||
/// </summary>
|
||||
public class ToplevelEqualityComparer : IEqualityComparer<Toplevel>
|
||||
{
|
||||
/// <summary>Determines whether the specified objects are equal.</summary>
|
||||
/// <param name="x">The first object of type <see cref="Toplevel"/> to compare.</param>
|
||||
/// <param name="y">The second object of type <see cref="Toplevel"/> to compare.</param>
|
||||
/// <returns>
|
||||
/// <see langword="true"/> if the specified objects are equal; otherwise, <see langword="false"/>.
|
||||
/// </returns>
|
||||
/// <returns><see langword="true"/> if the specified objects are equal; otherwise, <see langword="false"/>.</returns>
|
||||
public bool Equals (Toplevel x, Toplevel y)
|
||||
{
|
||||
if (y == null && x == null)
|
||||
@@ -1177,8 +1119,8 @@ public class ToplevelEqualityComparer : IEqualityComparer<Toplevel>
|
||||
/// <param name="obj">The <see cref="Toplevel"/> for which a hash code is to be returned.</param>
|
||||
/// <returns>A hash code for the specified object.</returns>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// The type of <paramref name="obj"/>
|
||||
/// is a reference type and <paramref name="obj"/> is <see langword="null"/>.
|
||||
/// The type of <paramref name="obj"/> is a reference type and
|
||||
/// <paramref name="obj"/> is <see langword="null"/>.
|
||||
/// </exception>
|
||||
public int GetHashCode (Toplevel obj)
|
||||
{
|
||||
@@ -1199,23 +1141,22 @@ public class ToplevelEqualityComparer : IEqualityComparer<Toplevel>
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implements the <see cref="IComparer{T}"/> to sort the <see cref="Toplevel"/>
|
||||
/// from the <see cref="Application.OverlappedChildren"/> if needed.
|
||||
/// Implements the <see cref="IComparer{T}"/> to sort the <see cref="Toplevel"/> from the
|
||||
/// <see cref="Application.OverlappedChildren"/> if needed.
|
||||
/// </summary>
|
||||
public sealed class ToplevelComparer : IComparer<Toplevel>
|
||||
{
|
||||
/// <summary>
|
||||
/// Compares two objects and returns a value indicating whether one is less than, equal to, or
|
||||
/// greater than the other.
|
||||
/// Compares two objects and returns a value indicating whether one is less than, equal to, or greater than the
|
||||
/// other.
|
||||
/// </summary>
|
||||
/// <param name="x">The first object to compare.</param>
|
||||
/// <param name="y">The second object to compare.</param>
|
||||
/// <returns>
|
||||
/// A signed integer that indicates the relative values of <paramref name="x"/> and
|
||||
/// <paramref name="y"/>, as shown in the following table.Value Meaning Less than zero
|
||||
/// <paramref name="x"/> is less than <paramref name="y"/>.Zero
|
||||
/// <paramref name="x"/> equals <paramref name="y"/>.Greater than zero
|
||||
/// <paramref name="x"/> is greater than <paramref name="y"/>.
|
||||
/// A signed integer that indicates the relative values of <paramref name="x"/> and <paramref name="y"/>, as shown
|
||||
/// in the following table.Value Meaning Less than zero <paramref name="x"/> is less than <paramref name="y"/>.Zero
|
||||
/// <paramref name="x"/> equals <paramref name="y"/> .Greater than zero <paramref name="x"/> is greater than
|
||||
/// <paramref name="y"/>.
|
||||
/// </returns>
|
||||
public int Compare (Toplevel x, Toplevel y)
|
||||
{
|
||||
|
||||
@@ -12,124 +12,122 @@ public class Dialogs : Scenario
|
||||
|
||||
public override void Setup ()
|
||||
{
|
||||
var frame = new FrameView ("Dialog Options")
|
||||
{
|
||||
X = Pos.Center (),
|
||||
Y = 1,
|
||||
Width = Dim.Percent (75),
|
||||
Height = Dim.Auto ()
|
||||
};
|
||||
var frame = new FrameView { X = Pos.Center (), Y = 1, Width = Dim.Percent (75), Title = "Dialog Options" };
|
||||
|
||||
var label = new Label ("Width:")
|
||||
{
|
||||
X = 0,
|
||||
Y = 0,
|
||||
Width = 15,
|
||||
Height = 1,
|
||||
TextAlignment = TextAlignment.Right
|
||||
};
|
||||
var label = new Label { X = 0, Y = 0, TextAlignment = TextAlignment.Right, Text = "Width:" };
|
||||
frame.Add (label);
|
||||
|
||||
var widthEdit = new TextField ("0")
|
||||
var widthEdit = new TextField
|
||||
{
|
||||
X = Pos.Right (label) + 1,
|
||||
Y = Pos.Top (label),
|
||||
Width = 5,
|
||||
Height = 1
|
||||
Height = 1,
|
||||
Text = "0"
|
||||
};
|
||||
frame.Add (widthEdit);
|
||||
|
||||
label = new Label ("Height:")
|
||||
label = new Label
|
||||
{
|
||||
AutoSize = false,
|
||||
X = 0,
|
||||
Y = Pos.Bottom (label),
|
||||
Width = Dim.Width (label),
|
||||
Height = 1,
|
||||
TextAlignment = TextAlignment.Right
|
||||
TextAlignment = TextAlignment.Right,
|
||||
Text = "Height:"
|
||||
};
|
||||
frame.Add (label);
|
||||
|
||||
var heightEdit = new TextField ("0")
|
||||
var heightEdit = new TextField
|
||||
{
|
||||
X = Pos.Right (label) + 1,
|
||||
Y = Pos.Top (label),
|
||||
Width = 5,
|
||||
Height = 1
|
||||
Height = 1,
|
||||
Text = "0"
|
||||
};
|
||||
frame.Add (heightEdit);
|
||||
|
||||
frame.Add (
|
||||
new Label ("If height & width are both 0,")
|
||||
{
|
||||
X = Pos.Right (widthEdit) + 2,
|
||||
Y = Pos.Top (widthEdit)
|
||||
});
|
||||
new Label { X = Pos.Right (widthEdit) + 2, Y = Pos.Top (widthEdit), Text = "If height & width are both 0," }
|
||||
);
|
||||
|
||||
frame.Add (
|
||||
new Label ("the Dialog will size to 80% of container.")
|
||||
new Label
|
||||
{
|
||||
X = Pos.Right (heightEdit) + 2,
|
||||
Y = Pos.Top (heightEdit)
|
||||
});
|
||||
Y = Pos.Top (heightEdit),
|
||||
Text = "the Dialog will size to 80% of container."
|
||||
}
|
||||
);
|
||||
|
||||
label = new Label ("Title:")
|
||||
label = new Label
|
||||
{
|
||||
AutoSize = false,
|
||||
X = 0,
|
||||
Y = Pos.Bottom (label),
|
||||
Width = Dim.Width (label),
|
||||
Height = 1,
|
||||
TextAlignment = TextAlignment.Right
|
||||
TextAlignment = TextAlignment.Right,
|
||||
Text = "Title:"
|
||||
};
|
||||
frame.Add (label);
|
||||
|
||||
var titleEdit = new TextField ("Title")
|
||||
var titleEdit = new TextField
|
||||
{
|
||||
X = Pos.Right (label) + 1,
|
||||
Y = Pos.Top (label),
|
||||
Width = Dim.Fill (),
|
||||
Height = 1
|
||||
Height = 1,
|
||||
Text = "Title"
|
||||
};
|
||||
frame.Add (titleEdit);
|
||||
|
||||
label = new Label ("Num Buttons:")
|
||||
label = new Label
|
||||
{
|
||||
AutoSize = false,
|
||||
X = 0,
|
||||
Y = Pos.Bottom (label), // BUGBUG: if this is Pos.Bottom (titleEdit) the initial LayoutSubviews does not work correctly?!?!
|
||||
Y = Pos.Bottom (label),
|
||||
Width = Dim.Width (label),
|
||||
Height = 1,
|
||||
TextAlignment = TextAlignment.Right
|
||||
TextAlignment = TextAlignment.Right,
|
||||
Text = "Num Buttons:"
|
||||
};
|
||||
frame.Add (label);
|
||||
|
||||
var numButtonsEdit = new TextField ("3")
|
||||
var numButtonsEdit = new TextField
|
||||
{
|
||||
X = Pos.Right (label) + 1,
|
||||
Y = Pos.Top (label),
|
||||
Width = 5,
|
||||
Height = 1
|
||||
Height = 1,
|
||||
Text = "3"
|
||||
};
|
||||
frame.Add (numButtonsEdit);
|
||||
|
||||
var glyphsNotWords = new CheckBox ($"Add {char.ConvertFromUtf32 (CODE_POINT)} to button text to stress wide char support")
|
||||
var glyphsNotWords = new CheckBox
|
||||
{
|
||||
X = Pos.Left (numButtonsEdit),
|
||||
Y = Pos.Bottom (label),
|
||||
TextAlignment = TextAlignment.Right
|
||||
TextAlignment = TextAlignment.Right,
|
||||
Text =
|
||||
$"Add {char.ConvertFromUtf32 (CODE_POINT)} to button text to stress wide char support",
|
||||
Checked = false
|
||||
};
|
||||
frame.Add (glyphsNotWords);
|
||||
|
||||
label = new Label ("Button Style:")
|
||||
label = new Label
|
||||
{
|
||||
X = 0,
|
||||
Y = Pos.Bottom (glyphsNotWords),
|
||||
TextAlignment = TextAlignment.Right
|
||||
X = 0, Y = Pos.Bottom (glyphsNotWords), TextAlignment = TextAlignment.Right, Text = "Button Style:"
|
||||
};
|
||||
frame.Add (label);
|
||||
|
||||
var styleRadioGroup = new RadioGroup (new [] { "_Center", "_Justify", "_Left", "_Right" })
|
||||
var styleRadioGroup = new RadioGroup
|
||||
{
|
||||
X = Pos.Right (label) + 1,
|
||||
Y = Pos.Top (label)
|
||||
Y = Pos.Top (label),
|
||||
RadioLabels = new [] { "_Center", "_Justify", "_Left", "_Right" }
|
||||
};
|
||||
frame.Add (styleRadioGroup);
|
||||
|
||||
@@ -151,22 +149,15 @@ public class Dialogs : Scenario
|
||||
|
||||
Win.Add (frame);
|
||||
|
||||
label = new Label ("Button Pressed:")
|
||||
label = new Label
|
||||
{
|
||||
X = Pos.Center (),
|
||||
Y = Pos.Bottom (frame) + 4,
|
||||
Height = 1,
|
||||
TextAlignment = TextAlignment.Right
|
||||
X = Pos.Center (), Y = Pos.Bottom (frame) + 4, TextAlignment = TextAlignment.Right, Text = "Button Pressed:"
|
||||
};
|
||||
Win.Add (label);
|
||||
|
||||
var buttonPressedLabel = new Label (" ")
|
||||
var buttonPressedLabel = new Label
|
||||
{
|
||||
X = Pos.Center (),
|
||||
Y = Pos.Bottom (frame) + 5,
|
||||
Width = 25,
|
||||
Height = 1,
|
||||
ColorScheme = Colors.ColorSchemes ["Error"]
|
||||
X = Pos.Center (), Y = Pos.Bottom (frame) + 5, ColorScheme = Colors.ColorSchemes ["Error"], Text = " "
|
||||
};
|
||||
|
||||
// glyphsNotWords
|
||||
@@ -174,11 +165,9 @@ public class Dialogs : Scenario
|
||||
// true: var btnText = new [] { "0", "\u2780", "➁", "\u2783", "\u2784", "\u2785", "\u2786", "\u2787", "\u2788", "\u2789" };
|
||||
// \u2781 is ➁ dingbats \ufb70 is
|
||||
|
||||
var showDialogButton = new Button ("_Show Dialog")
|
||||
var showDialogButton = new Button
|
||||
{
|
||||
X = Pos.Center (),
|
||||
Y = Pos.Bottom (frame) + 2,
|
||||
IsDefault = true
|
||||
X = Pos.Center (), Y = Pos.Bottom (frame) + 2, IsDefault = true, Text = "_Show Dialog"
|
||||
};
|
||||
|
||||
showDialogButton.Clicked += (s, e) =>
|
||||
@@ -190,7 +179,8 @@ public class Dialogs : Scenario
|
||||
numButtonsEdit,
|
||||
glyphsNotWords,
|
||||
styleRadioGroup,
|
||||
buttonPressedLabel);
|
||||
buttonPressedLabel
|
||||
);
|
||||
Application.Run (dlg);
|
||||
};
|
||||
|
||||
@@ -220,7 +210,7 @@ public class Dialogs : Scenario
|
||||
var numButtons = 3;
|
||||
int.TryParse (numButtonsEdit.Text, out numButtons);
|
||||
|
||||
List<Button> buttons = new List<Button> ();
|
||||
List<Button> buttons = new ();
|
||||
int clicked = -1;
|
||||
|
||||
for (var i = 0; i < numButtons; i++)
|
||||
@@ -232,15 +222,15 @@ public class Dialogs : Scenario
|
||||
{
|
||||
buttonId = i;
|
||||
|
||||
button = new Button (
|
||||
NumberToWords.Convert (buttonId) + " " + char.ConvertFromUtf32 (buttonId + CODE_POINT),
|
||||
buttonId == 0);
|
||||
button = new Button
|
||||
{
|
||||
Text = NumberToWords.Convert (buttonId) + " " + char.ConvertFromUtf32 (buttonId + CODE_POINT),
|
||||
IsDefault = buttonId == 0
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
button = new Button (
|
||||
NumberToWords.Convert (buttonId),
|
||||
buttonId == 0);
|
||||
button = new Button { Text = NumberToWords.Convert (buttonId), IsDefault = buttonId == 0 };
|
||||
}
|
||||
|
||||
button.Clicked += (s, e) =>
|
||||
@@ -261,10 +251,11 @@ public class Dialogs : Scenario
|
||||
|
||||
// This tests dynamically adding buttons; ensuring the dialog resizes if needed and
|
||||
// the buttons are laid out correctly
|
||||
dialog = new Dialog (buttons.ToArray ())
|
||||
dialog = new Dialog
|
||||
{
|
||||
Title = titleEdit.Text,
|
||||
ButtonAlignment = (Dialog.ButtonAlignments)styleRadioGroup.SelectedItem
|
||||
ButtonAlignment = (Dialog.ButtonAlignments)styleRadioGroup.SelectedItem,
|
||||
Buttons = buttons.ToArray ()
|
||||
};
|
||||
|
||||
if (height != 0 || width != 0)
|
||||
@@ -273,11 +264,7 @@ public class Dialogs : Scenario
|
||||
dialog.Width = width;
|
||||
}
|
||||
|
||||
var add = new Button ("Add a button")
|
||||
{
|
||||
X = Pos.Center (),
|
||||
Y = 10 //Pos.Center ()
|
||||
};
|
||||
var add = new Button { X = Pos.Center (), Y = Pos.Center (), Text = "Add a button" };
|
||||
|
||||
add.Clicked += (s, e) =>
|
||||
{
|
||||
@@ -286,15 +273,15 @@ public class Dialogs : Scenario
|
||||
|
||||
if (glyphsNotWords.Checked == true)
|
||||
{
|
||||
button = new Button (
|
||||
NumberToWords.Convert (buttonId) + " " + char.ConvertFromUtf32 (buttonId + CODE_POINT),
|
||||
buttonId == 0);
|
||||
button = new Button
|
||||
{
|
||||
Text = NumberToWords.Convert (buttonId) + " " + char.ConvertFromUtf32 (buttonId + CODE_POINT),
|
||||
IsDefault = buttonId == 0
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
button = new Button (
|
||||
NumberToWords.Convert (buttonId),
|
||||
buttonId == 0);
|
||||
button = new Button { Text = NumberToWords.Convert (buttonId), IsDefault = buttonId == 0 };
|
||||
}
|
||||
|
||||
button.Clicked += (s, e) =>
|
||||
@@ -312,10 +299,11 @@ public class Dialogs : Scenario
|
||||
};
|
||||
dialog.Add (add);
|
||||
|
||||
var addChar = new Button ($"Add a {char.ConvertFromUtf32 (CODE_POINT)} to each button")
|
||||
var addChar = new Button
|
||||
{
|
||||
X = Pos.Center (),
|
||||
Y = 11 //Pos.Center () + 1
|
||||
Y = Pos.Center () + 1,
|
||||
Text = $"Add a {char.ConvertFromUtf32 (CODE_POINT)} to each button"
|
||||
};
|
||||
|
||||
addChar.Clicked += (s, e) =>
|
||||
|
||||
@@ -21,29 +21,21 @@ using RuntimeEnvironment = Microsoft.DotNet.PlatformAbstractions.RuntimeEnvironm
|
||||
namespace UICatalog;
|
||||
|
||||
/// <summary>
|
||||
/// UI Catalog is a comprehensive sample library for Terminal.Gui. It provides a simple UI for adding to the catalog of
|
||||
/// scenarios.
|
||||
/// UI Catalog is a comprehensive sample library for Terminal.Gui. It provides a simple UI for adding to the
|
||||
/// catalog of scenarios.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// UI Catalog attempts to satisfy the following goals:
|
||||
/// </para>
|
||||
/// <para>UI Catalog attempts to satisfy the following goals:</para>
|
||||
/// <para>
|
||||
/// <list type="number">
|
||||
/// <item>
|
||||
/// <description>
|
||||
/// Be an easy to use showcase for Terminal.Gui concepts and features.
|
||||
/// </description>
|
||||
/// <description>Be an easy to use showcase for Terminal.Gui concepts and features.</description>
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <description>
|
||||
/// Provide sample code that illustrates how to properly implement said concepts & features.
|
||||
/// </description>
|
||||
/// <description>Provide sample code that illustrates how to properly implement said concepts & features.</description>
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <description>
|
||||
/// Make it easy for contributors to add additional samples in a structured way.
|
||||
/// </description>
|
||||
/// <description>Make it easy for contributors to add additional samples in a structured way.</description>
|
||||
/// </item>
|
||||
/// </list>
|
||||
/// </para>
|
||||
@@ -63,22 +55,17 @@ internal class UICatalogApp
|
||||
private static int _cachedScenarioIndex;
|
||||
private static string? _cachedTheme = string.Empty;
|
||||
private static List<string>? _categories;
|
||||
|
||||
private static readonly FileSystemWatcher _currentDirWatcher = new ();
|
||||
private static ConsoleDriver.DiagnosticFlags _diagnosticFlags;
|
||||
|
||||
private static string _forceDriver = string.Empty;
|
||||
private static readonly FileSystemWatcher _homeDirWatcher = new ();
|
||||
private static bool _isFirstRunning = true;
|
||||
|
||||
private static Options _options;
|
||||
|
||||
private static List<Scenario>? _scenarios;
|
||||
|
||||
// If set, holds the scenario the user selected
|
||||
private static Scenario? _selectedScenario;
|
||||
private static MenuBarItem? _themeMenuBarItem;
|
||||
|
||||
private static MenuItem []? _themeMenuItems;
|
||||
private static string _topLevelColorScheme = string.Empty;
|
||||
|
||||
@@ -114,10 +101,12 @@ internal class UICatalogApp
|
||||
// Process command line args
|
||||
// "UICatalog [-driver <driver>] [scenario name]"
|
||||
// If no driver is provided, the default driver is used.
|
||||
Option<string> driverOption = new Option<string> (
|
||||
"--driver",
|
||||
"The ConsoleDriver to use."
|
||||
).FromAmong (Application.GetDriverTypes ().Select (d => d.Name).ToArray ());
|
||||
Option<string> driverOption = new Option<string> ("--driver", "The ConsoleDriver to use.").FromAmong (
|
||||
Application.GetDriverTypes ()
|
||||
.Select (d => d.Name)
|
||||
.ToArray ()
|
||||
);
|
||||
|
||||
driverOption.AddAlias ("-d");
|
||||
driverOption.AddAlias ("--d");
|
||||
|
||||
@@ -125,28 +114,29 @@ internal class UICatalogApp
|
||||
"scenario",
|
||||
description: "The name of the scenario to run.",
|
||||
getDefaultValue: () => "none"
|
||||
).FromAmong (_scenarios.Select (s => s.GetName ()).Append ("none").ToArray ());
|
||||
).FromAmong (
|
||||
_scenarios.Select (s => s.GetName ())
|
||||
.Append ("none")
|
||||
.ToArray ()
|
||||
);
|
||||
|
||||
var rootCommand = new RootCommand ("A comprehensive sample library for Terminal.Gui")
|
||||
{
|
||||
scenarioArgument,
|
||||
driverOption
|
||||
};
|
||||
var rootCommand =
|
||||
new RootCommand ("A comprehensive sample library for Terminal.Gui") { scenarioArgument, driverOption };
|
||||
|
||||
rootCommand.SetHandler (
|
||||
context =>
|
||||
{
|
||||
var options = new Options
|
||||
{
|
||||
Driver = context.ParseResult.GetValueForOption (driverOption) ?? string.Empty,
|
||||
Driver = context.ParseResult.GetValueForOption (driverOption),
|
||||
Scenario = context.ParseResult.GetValueForArgument (scenarioArgument)
|
||||
/* etc. */
|
||||
};
|
||||
|
||||
// See https://github.com/dotnet/command-line-api/issues/796 for the rationale behind this hackery
|
||||
_options = options;
|
||||
;
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
rootCommand.Invoke (args);
|
||||
|
||||
@@ -185,9 +175,8 @@ internal class UICatalogApp
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Shows the UI Catalog selection UI. When the user selects a Scenario to run, the
|
||||
/// UI Catalog main app UI is killed and the Scenario is run as though it were Application.Top.
|
||||
/// When the Scenario exits, this function exits.
|
||||
/// Shows the UI Catalog selection UI. When the user selects a Scenario to run, the UI Catalog main app UI is
|
||||
/// killed and the Scenario is run as though it were Application.Top. When the Scenario exits, this function exits.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private static Scenario RunUICatalogTopLevel ()
|
||||
@@ -291,7 +280,11 @@ internal class UICatalogApp
|
||||
{
|
||||
_topLevelColorScheme = "Base";
|
||||
|
||||
int item = _scenarios!.FindIndex (s => s.GetName ().Equals (options.Scenario, StringComparison.OrdinalIgnoreCase));
|
||||
int item = _scenarios!.FindIndex (
|
||||
s =>
|
||||
s.GetName ()
|
||||
.Equals (options.Scenario, StringComparison.OrdinalIgnoreCase)
|
||||
);
|
||||
_selectedScenario = (Scenario)Activator.CreateInstance (_scenarios [item].GetType ())!;
|
||||
|
||||
Application.Init (driverName: _forceDriver);
|
||||
@@ -378,7 +371,6 @@ internal class UICatalogApp
|
||||
public class UICatalogTopLevel : Toplevel
|
||||
{
|
||||
public ListView CategoryList;
|
||||
|
||||
public StatusItem DriverName;
|
||||
public MenuItem? miForce16Colors;
|
||||
public MenuItem? miIsMenuBorderDisabled;
|
||||
@@ -390,6 +382,7 @@ internal class UICatalogApp
|
||||
// TableView works. There's no real reason not to use ListView. Because we use TableView, and TableView
|
||||
// doesn't (currently) have CollectionNavigator support built in, we implement it here, within the app.
|
||||
public TableView ScenarioList;
|
||||
|
||||
private readonly CollectionNavigator _scenarioCollectionNav = new ();
|
||||
|
||||
public UICatalogTopLevel ()
|
||||
@@ -397,46 +390,66 @@ internal class UICatalogApp
|
||||
_themeMenuItems = CreateThemeMenuItems ();
|
||||
_themeMenuBarItem = new MenuBarItem ("_Themes", _themeMenuItems);
|
||||
|
||||
MenuBar = new MenuBar (
|
||||
new []
|
||||
{
|
||||
new (
|
||||
"_File",
|
||||
new MenuItem []
|
||||
{
|
||||
new ("_Quit", "Quit UI Catalog", RequestStop)
|
||||
}),
|
||||
_themeMenuBarItem,
|
||||
new ("Diag_nostics", CreateDiagnosticMenuItems ()),
|
||||
new (
|
||||
"_Help",
|
||||
new MenuItem []
|
||||
{
|
||||
new (
|
||||
"_Documentation",
|
||||
"",
|
||||
() => OpenUrl ("https://gui-cs.github.io/Terminal.GuiV2Docs"),
|
||||
null,
|
||||
null,
|
||||
(KeyCode)Key.F1),
|
||||
new ("_README", "", () => OpenUrl ("https://github.com/gui-cs/Terminal.Gui"), null, null, (KeyCode)Key.F2),
|
||||
new (
|
||||
"_About...",
|
||||
"About UI Catalog",
|
||||
() => MessageBox.Query ("About UI Catalog", _aboutMessage!.ToString (), 0, false, "_Ok"),
|
||||
null,
|
||||
null,
|
||||
(KeyCode)Key.A.WithCtrl)
|
||||
})
|
||||
});
|
||||
MenuBar = new MenuBar
|
||||
{
|
||||
Menus =
|
||||
[
|
||||
new MenuBarItem (
|
||||
"_File",
|
||||
new MenuItem []
|
||||
{
|
||||
new (
|
||||
"_Quit",
|
||||
"Quit UI Catalog",
|
||||
RequestStop
|
||||
)
|
||||
}
|
||||
),
|
||||
_themeMenuBarItem,
|
||||
new MenuBarItem ("Diag_nostics", CreateDiagnosticMenuItems ()),
|
||||
new MenuBarItem (
|
||||
"_Help",
|
||||
new MenuItem []
|
||||
{
|
||||
new (
|
||||
"_Documentation",
|
||||
"",
|
||||
() => OpenUrl ("https://gui-cs.github.io/Terminal.GuiV2Docs"),
|
||||
null,
|
||||
null,
|
||||
(KeyCode)Key.F1
|
||||
),
|
||||
new (
|
||||
"_README",
|
||||
"",
|
||||
() => OpenUrl ("https://github.com/gui-cs/Terminal.Gui"),
|
||||
null,
|
||||
null,
|
||||
(KeyCode)Key.F2
|
||||
),
|
||||
new (
|
||||
"_About...",
|
||||
"About UI Catalog",
|
||||
() => MessageBox.Query (
|
||||
"About UI Catalog",
|
||||
_aboutMessage!.ToString (),
|
||||
0,
|
||||
false,
|
||||
"_Ok"
|
||||
),
|
||||
null,
|
||||
null,
|
||||
(KeyCode)Key.A.WithCtrl
|
||||
)
|
||||
}
|
||||
)
|
||||
]
|
||||
};
|
||||
|
||||
DriverName = new StatusItem (Key.Empty, "Driver:", null);
|
||||
OS = new StatusItem (Key.Empty, "OS:", null);
|
||||
|
||||
StatusBar = new StatusBar
|
||||
{
|
||||
Visible = ShowStatusBar
|
||||
};
|
||||
StatusBar = new StatusBar { Visible = ShowStatusBar };
|
||||
|
||||
StatusBar.Items = new []
|
||||
{
|
||||
@@ -455,7 +468,8 @@ internal class UICatalogApp
|
||||
{
|
||||
_selectedScenario.RequestStop ();
|
||||
}
|
||||
}),
|
||||
}
|
||||
),
|
||||
new (
|
||||
Key.F10,
|
||||
"~F10~ Status Bar",
|
||||
@@ -466,13 +480,14 @@ internal class UICatalogApp
|
||||
//ContentPane!.Height = Dim.Fill(StatusBar.Visible ? 1 : 0);
|
||||
LayoutSubviews ();
|
||||
SetSubViewNeedsDisplay ();
|
||||
}),
|
||||
}
|
||||
),
|
||||
DriverName,
|
||||
OS
|
||||
};
|
||||
|
||||
// Create the Category list view. This list never changes.
|
||||
CategoryList = new ListView (_categories)
|
||||
CategoryList = new ListView
|
||||
{
|
||||
X = 0,
|
||||
Y = 1,
|
||||
@@ -482,7 +497,8 @@ internal class UICatalogApp
|
||||
CanFocus = true,
|
||||
Title = "Categories",
|
||||
BorderStyle = LineStyle.Single,
|
||||
SuperViewRendersLineCanvas = true
|
||||
SuperViewRendersLineCanvas = true,
|
||||
Source = new ListWrapper (_categories)
|
||||
};
|
||||
CategoryList.OpenSelectedItem += (s, a) => { ScenarioList!.SetFocus (); };
|
||||
CategoryList.SelectedItemChanged += CategoryView_SelectedChanged;
|
||||
@@ -528,7 +544,11 @@ internal class UICatalogApp
|
||||
* max widths as ColumnStyles
|
||||
*/
|
||||
int longestName = _scenarios!.Max (s => s.GetName ().Length);
|
||||
ScenarioList.Style.ColumnStyles.Add (0, new ColumnStyle { MaxWidth = longestName, MinWidth = longestName, MinAcceptableWidth = longestName });
|
||||
|
||||
ScenarioList.Style.ColumnStyles.Add (
|
||||
0,
|
||||
new ColumnStyle { MaxWidth = longestName, MinWidth = longestName, MinAcceptableWidth = longestName }
|
||||
);
|
||||
ScenarioList.Style.ColumnStyles.Add (1, new ColumnStyle { MaxWidth = 1 });
|
||||
|
||||
// Enable user to find & select a scenario by typing text
|
||||
@@ -538,7 +558,11 @@ internal class UICatalogApp
|
||||
{
|
||||
if (CollectionNavigatorBase.IsCompatibleKey (a))
|
||||
{
|
||||
int? newItem = _scenarioCollectionNav?.GetNextMatchingItem (ScenarioList.SelectedRow, (char)a);
|
||||
int? newItem =
|
||||
_scenarioCollectionNav?.GetNextMatchingItem (
|
||||
ScenarioList.SelectedRow,
|
||||
(char)a
|
||||
);
|
||||
|
||||
if (newItem is int v && newItem != -1)
|
||||
{
|
||||
@@ -626,7 +650,8 @@ internal class UICatalogApp
|
||||
var item = new MenuItem
|
||||
{
|
||||
Title = $"_{theme.Key}",
|
||||
Shortcut = (KeyCode)new Key ((KeyCode)((uint)KeyCode.D1 + schemeCount++)).WithCtrl
|
||||
Shortcut = (KeyCode)new Key ((KeyCode)((uint)KeyCode.D1 + schemeCount++))
|
||||
.WithCtrl
|
||||
};
|
||||
item.CheckType |= MenuItemCheckStyle.Checked;
|
||||
item.Checked = theme.Key == _cachedTheme; // CM.Themes.Theme;
|
||||
@@ -643,11 +668,7 @@ internal class UICatalogApp
|
||||
|
||||
foreach (KeyValuePair<string, ColorScheme> sc in Colors.ColorSchemes)
|
||||
{
|
||||
var item = new MenuItem
|
||||
{
|
||||
Title = $"_{sc.Key}",
|
||||
Data = sc.Key
|
||||
};
|
||||
var item = new MenuItem { Title = $"_{sc.Key}", Data = sc.Key };
|
||||
item.CheckType |= MenuItemCheckStyle.Radio;
|
||||
item.Checked = sc.Key == _topLevelColorScheme;
|
||||
|
||||
@@ -657,7 +678,8 @@ internal class UICatalogApp
|
||||
|
||||
foreach (MenuItem schemeMenuItem in schemeMenuItems)
|
||||
{
|
||||
schemeMenuItem.Checked = (string)schemeMenuItem.Data == _topLevelColorScheme;
|
||||
schemeMenuItem.Checked =
|
||||
(string)schemeMenuItem.Data == _topLevelColorScheme;
|
||||
}
|
||||
|
||||
ColorScheme = Colors.ColorSchemes [_topLevelColorScheme];
|
||||
@@ -693,9 +715,9 @@ internal class UICatalogApp
|
||||
newlist,
|
||||
new Dictionary<string, Func<Scenario, object>>
|
||||
{
|
||||
{ "Name", s => s.GetName () },
|
||||
{ "Description", s => s.GetDescription () }
|
||||
});
|
||||
{ "Name", s => s.GetName () }, { "Description", s => s.GetDescription () }
|
||||
}
|
||||
);
|
||||
|
||||
// Create a collection of just the scenario names (the 1st column in our TableView)
|
||||
// for CollectionNavigator.
|
||||
@@ -724,8 +746,7 @@ internal class UICatalogApp
|
||||
{
|
||||
var item = new MenuItem
|
||||
{
|
||||
Title = GetDiagnosticsTitle (diag),
|
||||
Shortcut = (KeyCode)new Key (index.ToString () [0]).WithAlt
|
||||
Title = GetDiagnosticsTitle (diag), Shortcut = (KeyCode)new Key (index.ToString () [0]).WithAlt
|
||||
};
|
||||
index++;
|
||||
item.CheckType |= MenuItemCheckStyle.Checked;
|
||||
@@ -734,7 +755,8 @@ internal class UICatalogApp
|
||||
{
|
||||
item.Checked = (_diagnosticFlags
|
||||
& (ConsoleDriver.DiagnosticFlags.FramePadding
|
||||
| ConsoleDriver.DiagnosticFlags.FrameRuler))
|
||||
| ConsoleDriver.DiagnosticFlags
|
||||
.FrameRuler))
|
||||
== 0;
|
||||
}
|
||||
else
|
||||
@@ -774,12 +796,19 @@ internal class UICatalogApp
|
||||
{
|
||||
if (menuItem.Title == t)
|
||||
{
|
||||
menuItem.Checked = !_diagnosticFlags.HasFlag (ConsoleDriver.DiagnosticFlags.FrameRuler)
|
||||
&& !_diagnosticFlags.HasFlag (ConsoleDriver.DiagnosticFlags.FramePadding);
|
||||
menuItem.Checked =
|
||||
!_diagnosticFlags.HasFlag (
|
||||
ConsoleDriver.DiagnosticFlags
|
||||
.FrameRuler
|
||||
)
|
||||
&& !_diagnosticFlags.HasFlag (ConsoleDriver.DiagnosticFlags.FramePadding);
|
||||
}
|
||||
else if (menuItem.Title != t)
|
||||
{
|
||||
menuItem.Checked = _diagnosticFlags.HasFlag (GetDiagnosticsEnumValue (menuItem.Title));
|
||||
menuItem.Checked =
|
||||
_diagnosticFlags.HasFlag (
|
||||
GetDiagnosticsEnumValue (menuItem.Title)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -848,7 +877,7 @@ internal class UICatalogApp
|
||||
|
||||
private List<MenuItem []> CreateDiagnosticMenuItems ()
|
||||
{
|
||||
List<MenuItem []> menuItems = new()
|
||||
List<MenuItem []> menuItems = new ()
|
||||
{
|
||||
CreateDiagnosticFlagsMenuItems (),
|
||||
new MenuItem [] { null! },
|
||||
@@ -865,18 +894,20 @@ internal class UICatalogApp
|
||||
private MenuItem [] CreateDisabledEnabledMenuBorder ()
|
||||
{
|
||||
List<MenuItem> menuItems = new ();
|
||||
miIsMenuBorderDisabled = new MenuItem { Title = "Disable Menu _Border" };
|
||||
|
||||
miIsMenuBorderDisabled = new MenuItem
|
||||
{
|
||||
Title = "Disable Menu _Border"
|
||||
};
|
||||
miIsMenuBorderDisabled.Shortcut = (KeyCode)new Key (miIsMenuBorderDisabled!.Title!.Substring (14, 1) [0]).WithAlt.WithCtrl;
|
||||
miIsMenuBorderDisabled.Shortcut =
|
||||
(KeyCode)new Key (miIsMenuBorderDisabled!.Title!.Substring (14, 1) [0]).WithAlt
|
||||
.WithCtrl;
|
||||
miIsMenuBorderDisabled.CheckType |= MenuItemCheckStyle.Checked;
|
||||
|
||||
miIsMenuBorderDisabled.Action += () =>
|
||||
{
|
||||
miIsMenuBorderDisabled.Checked = (bool)!miIsMenuBorderDisabled.Checked!;
|
||||
MenuBar.MenusBorderStyle = !(bool)miIsMenuBorderDisabled.Checked ? LineStyle.Single : LineStyle.None;
|
||||
|
||||
MenuBar.MenusBorderStyle = !(bool)miIsMenuBorderDisabled.Checked
|
||||
? LineStyle.Single
|
||||
: LineStyle.None;
|
||||
};
|
||||
menuItems.Add (miIsMenuBorderDisabled);
|
||||
|
||||
@@ -886,14 +917,17 @@ internal class UICatalogApp
|
||||
private MenuItem [] CreateDisabledEnabledMouseItems ()
|
||||
{
|
||||
List<MenuItem> menuItems = new ();
|
||||
miIsMouseDisabled = new MenuItem { Title = "_Disable Mouse" };
|
||||
|
||||
miIsMouseDisabled = new MenuItem
|
||||
{
|
||||
Title = "_Disable Mouse"
|
||||
};
|
||||
miIsMouseDisabled.Shortcut = (KeyCode)new Key (miIsMouseDisabled!.Title!.Substring (1, 1) [0]).WithAlt.WithCtrl;
|
||||
miIsMouseDisabled.Shortcut =
|
||||
(KeyCode)new Key (miIsMouseDisabled!.Title!.Substring (1, 1) [0]).WithAlt.WithCtrl;
|
||||
miIsMouseDisabled.CheckType |= MenuItemCheckStyle.Checked;
|
||||
miIsMouseDisabled.Action += () => { miIsMouseDisabled.Checked = Application.IsMouseDisabled = (bool)!miIsMouseDisabled.Checked!; };
|
||||
|
||||
miIsMouseDisabled.Action += () =>
|
||||
{
|
||||
miIsMouseDisabled.Checked =
|
||||
Application.IsMouseDisabled = (bool)!miIsMouseDisabled.Checked!;
|
||||
};
|
||||
menuItems.Add (miIsMouseDisabled);
|
||||
|
||||
return menuItems.ToArray ();
|
||||
@@ -903,12 +937,12 @@ internal class UICatalogApp
|
||||
private MenuItem [] CreateDisabledEnableUseSubMenusSingleFrame ()
|
||||
{
|
||||
List<MenuItem> menuItems = new ();
|
||||
miUseSubMenusSingleFrame = new MenuItem { Title = "Enable _Sub-Menus Single Frame" };
|
||||
|
||||
miUseSubMenusSingleFrame = new MenuItem
|
||||
{
|
||||
Title = "Enable _Sub-Menus Single Frame"
|
||||
};
|
||||
miUseSubMenusSingleFrame.Shortcut = KeyCode.CtrlMask | KeyCode.AltMask | (KeyCode)miUseSubMenusSingleFrame!.Title!.Substring (8, 1) [0];
|
||||
miUseSubMenusSingleFrame.Shortcut = KeyCode.CtrlMask
|
||||
| KeyCode.AltMask
|
||||
| (KeyCode)miUseSubMenusSingleFrame!.Title!.Substring (8, 1) [
|
||||
0];
|
||||
miUseSubMenusSingleFrame.CheckType |= MenuItemCheckStyle.Checked;
|
||||
|
||||
miUseSubMenusSingleFrame.Action += () =>
|
||||
@@ -947,12 +981,7 @@ internal class UICatalogApp
|
||||
private MenuItem [] CreateKeyBindingsMenuItems ()
|
||||
{
|
||||
List<MenuItem> menuItems = new ();
|
||||
|
||||
var item = new MenuItem
|
||||
{
|
||||
Title = "_Key Bindings",
|
||||
Help = "Change which keys do what"
|
||||
};
|
||||
var item = new MenuItem { Title = "_Key Bindings", Help = "Change which keys do what" };
|
||||
|
||||
item.Action += () =>
|
||||
{
|
||||
@@ -972,7 +1001,9 @@ internal class UICatalogApp
|
||||
|
||||
miIsMouseDisabled!.Checked = Application.IsMouseDisabled;
|
||||
DriverName.Title = $"Driver: {Driver.GetVersionInfo ()}";
|
||||
OS.Title = $"OS: {RuntimeEnvironment.OperatingSystem} {RuntimeEnvironment.OperatingSystemVersion}";
|
||||
|
||||
OS.Title =
|
||||
$"OS: {RuntimeEnvironment.OperatingSystem} {RuntimeEnvironment.OperatingSystemVersion}";
|
||||
|
||||
if (_selectedScenario != null)
|
||||
{
|
||||
@@ -1003,9 +1034,7 @@ internal class UICatalogApp
|
||||
ScenarioList.EnsureSelectedCellIsVisible ();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Launches the selected scenario, setting the global _selectedScenario
|
||||
/// </summary>
|
||||
/// <summary>Launches the selected scenario, setting the global _selectedScenario</summary>
|
||||
/// <param name="e"></param>
|
||||
private void ScenarioView_OpenSelectedItem (object? sender, EventArgs? e)
|
||||
{
|
||||
@@ -1017,7 +1046,14 @@ internal class UICatalogApp
|
||||
|
||||
// Create new instance of scenario (even though Scenarios contains instances)
|
||||
var selectedScenarioName = (string)ScenarioList.Table [ScenarioList.SelectedRow, 0];
|
||||
_selectedScenario = (Scenario)Activator.CreateInstance (_scenarios!.FirstOrDefault (s => s.GetName () == selectedScenarioName)!.GetType ())!;
|
||||
|
||||
_selectedScenario = (Scenario)Activator.CreateInstance (
|
||||
_scenarios!.FirstOrDefault (
|
||||
s => s.GetName ()
|
||||
== selectedScenarioName
|
||||
)!
|
||||
.GetType ()
|
||||
)!;
|
||||
|
||||
// Tell the main app to stop
|
||||
Application.RequestStop ();
|
||||
|
||||
@@ -5,7 +5,6 @@ namespace Terminal.Gui.TextTests;
|
||||
public class AppendAutocompleteTests
|
||||
{
|
||||
private readonly ITestOutputHelper output;
|
||||
|
||||
public AppendAutocompleteTests (ITestOutputHelper output) { this.output = output; }
|
||||
|
||||
[Fact]
|
||||
@@ -225,16 +224,8 @@ public class AppendAutocompleteTests
|
||||
|
||||
private TextField GetTextFieldsInView ()
|
||||
{
|
||||
var tf = new TextField
|
||||
{
|
||||
Width = 10
|
||||
};
|
||||
|
||||
var tf2 = new TextField
|
||||
{
|
||||
Y = 1,
|
||||
Width = 10
|
||||
};
|
||||
var tf = new TextField { Width = 10 };
|
||||
var tf2 = new TextField { Y = 1, Width = 10 };
|
||||
|
||||
Toplevel top = Application.Top;
|
||||
top.Add (tf);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -5,23 +5,19 @@ namespace Terminal.Gui.ViewsTests;
|
||||
public class WindowTests
|
||||
{
|
||||
private readonly ITestOutputHelper _output;
|
||||
|
||||
public WindowTests (ITestOutputHelper output) { _output = output; }
|
||||
|
||||
[Fact]
|
||||
[AutoInitShutdown]
|
||||
public void Activating_MenuBar_By_Alt_Key_Does_Not_Throw ()
|
||||
{
|
||||
var menu = new MenuBar (
|
||||
new MenuBarItem []
|
||||
{
|
||||
new (
|
||||
"Child",
|
||||
new MenuItem []
|
||||
{
|
||||
new ("_Create Child", "", null)
|
||||
})
|
||||
});
|
||||
var menu = new MenuBar
|
||||
{
|
||||
Menus =
|
||||
[
|
||||
new MenuBarItem ("Child", new MenuItem [] { new ("_Create Child", "", null) })
|
||||
]
|
||||
};
|
||||
var win = new Window ();
|
||||
win.Add (menu);
|
||||
Application.Top.Add (win);
|
||||
@@ -35,23 +31,17 @@ public class WindowTests
|
||||
[AutoInitShutdown]
|
||||
public void MenuBar_And_StatusBar_Inside_Window ()
|
||||
{
|
||||
var menu = new MenuBar (
|
||||
new MenuBarItem []
|
||||
{
|
||||
new (
|
||||
"File",
|
||||
new MenuItem []
|
||||
{
|
||||
new ("Open", "", null),
|
||||
new ("Quit", "", null)
|
||||
}),
|
||||
new (
|
||||
"Edit",
|
||||
new MenuItem []
|
||||
{
|
||||
new ("Copy", "", null)
|
||||
})
|
||||
});
|
||||
var menu = new MenuBar
|
||||
{
|
||||
Menus =
|
||||
[
|
||||
new MenuBarItem ("File", new MenuItem [] { new ("Open", "", null), new ("Quit", "", null) }),
|
||||
new MenuBarItem (
|
||||
"Edit",
|
||||
new MenuItem [] { new ("Copy", "", null) }
|
||||
)
|
||||
]
|
||||
};
|
||||
|
||||
var sb = new StatusBar (
|
||||
new StatusItem []
|
||||
@@ -59,14 +49,10 @@ public class WindowTests
|
||||
new (KeyCode.CtrlMask | KeyCode.Q, "~^Q~ Quit", null),
|
||||
new (KeyCode.CtrlMask | KeyCode.O, "~^O~ Open", null),
|
||||
new (KeyCode.CtrlMask | KeyCode.C, "~^C~ Copy", null)
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
var fv = new FrameView ("Frame View")
|
||||
{
|
||||
Y = 1,
|
||||
Width = Dim.Fill (),
|
||||
Height = Dim.Fill (1)
|
||||
};
|
||||
var fv = new FrameView { Y = 1, Width = Dim.Fill (), Height = Dim.Fill (1), Title = "Frame View" };
|
||||
var win = new Window ();
|
||||
win.Add (menu, sb, fv);
|
||||
Toplevel top = Application.Top;
|
||||
@@ -86,7 +72,8 @@ public class WindowTests
|
||||
│└────────────────┘│
|
||||
│ ^Q Quit │ ^O Open│
|
||||
└──────────────────┘",
|
||||
_output);
|
||||
_output
|
||||
);
|
||||
|
||||
((FakeDriver)Application.Driver).SetBufferSize (40, 20);
|
||||
|
||||
@@ -112,7 +99,8 @@ public class WindowTests
|
||||
│└────────────────────────────────────┘│
|
||||
│ ^Q Quit │ ^O Open │ ^C Copy │
|
||||
└──────────────────────────────────────┘",
|
||||
_output);
|
||||
_output
|
||||
);
|
||||
|
||||
((FakeDriver)Application.Driver).SetBufferSize (20, 10);
|
||||
|
||||
@@ -128,7 +116,8 @@ public class WindowTests
|
||||
│└────────────────┘│
|
||||
│ ^Q Quit │ ^O Open│
|
||||
└──────────────────┘",
|
||||
_output);
|
||||
_output
|
||||
);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -163,7 +152,7 @@ public class WindowTests
|
||||
Assert.Equal (TextDirection.LeftRight_TopBottom, r.TextDirection);
|
||||
|
||||
// Empty Rect
|
||||
r = new Window (Rect.Empty) { Title = "title" };
|
||||
r = new Window { Frame = Rect.Empty, Title = "title" };
|
||||
Assert.NotNull (r);
|
||||
Assert.Equal ("title", r.Title);
|
||||
Assert.Equal (LayoutStyle.Absolute, r.LayoutStyle);
|
||||
@@ -189,7 +178,7 @@ public class WindowTests
|
||||
Assert.Equal (TextDirection.LeftRight_TopBottom, r.TextDirection);
|
||||
|
||||
// Rect with values
|
||||
r = new Window (new Rect (1, 2, 3, 4)) { Title = "title" };
|
||||
r = new Window { Frame = new Rect (1, 2, 3, 4), Title = "title" };
|
||||
Assert.Equal ("title", r.Title);
|
||||
Assert.NotNull (r);
|
||||
Assert.Equal (LayoutStyle.Absolute, r.LayoutStyle);
|
||||
|
||||
Reference in New Issue
Block a user