mirror of
https://github.com/gui-cs/Terminal.Gui.git
synced 2025-12-26 15:57:56 +01:00
Refresh works, Dialogs close
This commit is contained in:
99
Core.cs
99
Core.cs
@@ -16,6 +16,7 @@ using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Linq;
|
||||
|
||||
namespace Terminal {
|
||||
|
||||
@@ -66,6 +67,12 @@ namespace Terminal {
|
||||
/// keystroke will be passed using the ProcessColdKey
|
||||
/// method to other views to process.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// The View implementation does nothing but return false,
|
||||
/// so it is not necessary to call base.ProcessKey if you
|
||||
/// derive directly from View, but you should if you derive
|
||||
/// other View subclasses.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public virtual bool ProcessKey (KeyEvent kb)
|
||||
{
|
||||
@@ -439,6 +446,12 @@ namespace Terminal {
|
||||
Driver.AddCh (ch);
|
||||
}
|
||||
|
||||
protected void ClearNeedsDisplay ()
|
||||
{
|
||||
NeedDisplay = Rect.Empty;
|
||||
childNeedsDisplay = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs a redraw of this view and its subviews, only redraws the views that have been flagged for a re-display.
|
||||
/// </summary>
|
||||
@@ -462,8 +475,7 @@ namespace Terminal {
|
||||
}
|
||||
}
|
||||
}
|
||||
NeedDisplay = Rect.Empty;
|
||||
childNeedsDisplay = false;
|
||||
ClearNeedsDisplay ();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -669,6 +681,12 @@ namespace Terminal {
|
||||
/// <summary>
|
||||
/// Toplevel views can be modally executed.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// Toplevels can be modally executing views, and they return control
|
||||
/// to the caller when the "Running" property is set to false.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public class Toplevel : View {
|
||||
public bool Running;
|
||||
|
||||
@@ -708,7 +726,7 @@ namespace Terminal {
|
||||
}
|
||||
return true;
|
||||
case Key.BackTab:
|
||||
old = Focused;
|
||||
old = Focused;
|
||||
if (!FocusPrev ())
|
||||
FocusPrev ();
|
||||
if (old != Focused) {
|
||||
@@ -717,26 +735,15 @@ namespace Terminal {
|
||||
}
|
||||
return true;
|
||||
case Key.ControlL:
|
||||
SetNeedsDisplay();
|
||||
Application.Refresh ();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#if false
|
||||
public override void Redraw ()
|
||||
{
|
||||
base.Redraw ();
|
||||
for (int i = 0; i < Driver.Cols; i++) {
|
||||
Driver.Move (0, i);
|
||||
Driver.AddStr ("Line: " + i);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A toplevel view that draws a frame around its region
|
||||
/// A toplevel view that draws a frame around its region and has a "ContentView" subview where the contents are added.
|
||||
/// </summary>
|
||||
public class Window : Toplevel, IEnumerable {
|
||||
View contentView;
|
||||
@@ -754,6 +761,11 @@ namespace Terminal {
|
||||
public ContentView (Rect frame) : base (frame) { }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="T:Terminal.Window"/> class with an optioanl title
|
||||
/// </summary>
|
||||
/// <param name="frame">Frame.</param>
|
||||
/// <param name="title">Title.</param>
|
||||
public Window (Rect frame, string title = null) : base (frame)
|
||||
{
|
||||
this.Title = title;
|
||||
@@ -762,6 +774,10 @@ namespace Terminal {
|
||||
base.Add (contentView);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enumerates the various views in the ContentView.
|
||||
/// </summary>
|
||||
/// <returns>The enumerator.</returns>
|
||||
public new IEnumerator GetEnumerator ()
|
||||
{
|
||||
return contentView.GetEnumerator ();
|
||||
@@ -772,6 +788,10 @@ namespace Terminal {
|
||||
DrawFrame (new Rect (0, 0, Frame.Width, Frame.Height), true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add the specified view to the ContentView.
|
||||
/// </summary>
|
||||
/// <param name="view">View to add to the window.</param>
|
||||
public override void Add (View view)
|
||||
{
|
||||
contentView.Add (view);
|
||||
@@ -795,9 +815,27 @@ namespace Terminal {
|
||||
Driver.SetAttribute (Colors.Dialog.Normal);
|
||||
}
|
||||
contentView.Redraw (contentView.Bounds);
|
||||
ClearNeedsDisplay ();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The application driver for gui.cs
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// You can hook up to the Iteration event to have your method
|
||||
/// invoked on each iteration of the mainloop.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// Creates a mainloop to process input events, handle timers and
|
||||
/// other sources of data. It is accessible via the MainLoop property.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// When invoked sets the SynchronizationContext to one that is tied
|
||||
/// to the mainloop, allowing user code to use async/await.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public class Application {
|
||||
public static ConsoleDriver Driver = new CursesDriver ();
|
||||
public static Toplevel Top { get; private set; }
|
||||
@@ -805,7 +843,6 @@ namespace Terminal {
|
||||
public static Mono.Terminal.MainLoop MainLoop { get; private set; }
|
||||
|
||||
static Stack<View> toplevels = new Stack<View> ();
|
||||
static Responder focus;
|
||||
|
||||
/// <summary>
|
||||
/// This event is raised on each iteration of the
|
||||
@@ -826,6 +863,10 @@ namespace Terminal {
|
||||
return new Rect (new Point ((Driver.Cols - size.Width) / 2, (Driver.Rows - size.Height) / 2), size);
|
||||
}
|
||||
|
||||
//
|
||||
// provides the sync context set while executing code in gui.cs, to let
|
||||
// users use async/await on their code
|
||||
//
|
||||
class MainLoopSyncContext : SynchronizationContext {
|
||||
Mono.Terminal.MainLoop mainLoop;
|
||||
|
||||
@@ -868,7 +909,6 @@ namespace Terminal {
|
||||
SynchronizationContext.SetSynchronizationContext (new MainLoopSyncContext (MainLoop));
|
||||
Top = Toplevel.Create ();
|
||||
Current = Top;
|
||||
focus = Top;
|
||||
}
|
||||
|
||||
public class RunState : IDisposable {
|
||||
@@ -906,7 +946,6 @@ namespace Terminal {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static public RunState Begin (Toplevel toplevel)
|
||||
{
|
||||
if (toplevel == null)
|
||||
@@ -930,6 +969,7 @@ namespace Terminal {
|
||||
{
|
||||
if (rs == null)
|
||||
throw new ArgumentNullException (nameof (rs));
|
||||
|
||||
rs.Dispose ();
|
||||
}
|
||||
|
||||
@@ -950,16 +990,19 @@ namespace Terminal {
|
||||
Driver.Refresh ();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Triggers a refresh of the entire display.
|
||||
/// </summary>
|
||||
public static void Refresh ()
|
||||
{
|
||||
Driver.RedrawTop ();
|
||||
View last = null;
|
||||
foreach (var v in toplevels) {
|
||||
foreach (var v in toplevels.Reverse ()) {
|
||||
v.SetNeedsDisplay ();
|
||||
v.Redraw (v.Bounds);
|
||||
last = v;
|
||||
}
|
||||
if (last != null)
|
||||
last.PositionCursor ();
|
||||
last?.PositionCursor ();
|
||||
Driver.Refresh ();
|
||||
}
|
||||
|
||||
@@ -1014,9 +1057,15 @@ namespace Terminal {
|
||||
/// Runs the main loop on the given container.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This method is used to start processing events
|
||||
/// for the main application, but it is also used to
|
||||
/// run modal dialog boxes.
|
||||
/// <para>
|
||||
/// This method is used to start processing events
|
||||
/// for the main application, but it is also used to
|
||||
/// run modal dialog boxes.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// To make a toplevel stop execution, set the "Running"
|
||||
/// property to false.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public static void Run (Toplevel view)
|
||||
{
|
||||
|
||||
@@ -124,6 +124,7 @@ namespace Terminal {
|
||||
}
|
||||
}
|
||||
|
||||
static bool sync;
|
||||
public override void AddCh (int ch)
|
||||
{
|
||||
if (Clip.Contains (ccol, crow)) {
|
||||
@@ -134,6 +135,8 @@ namespace Terminal {
|
||||
Curses.addch (ch);
|
||||
} else
|
||||
needMove = true;
|
||||
if (sync)
|
||||
Application.Driver.Refresh ();
|
||||
ccol++;
|
||||
}
|
||||
|
||||
|
||||
4
TODO.md
4
TODO.md
@@ -33,6 +33,10 @@ Widgets should not use Colors.Base or Colors.Dialog, they should likely use
|
||||
the colors defined in the toplevel container, so that the Dialog vs Toplevel
|
||||
colors are set there only.
|
||||
|
||||
## Focus
|
||||
|
||||
Use left/right/up/down to switch focus as well when nothing handles the event
|
||||
|
||||
## Views
|
||||
|
||||
Checkbox, ListView, Menu.
|
||||
|
||||
@@ -168,7 +168,7 @@ namespace Terminal {
|
||||
Clicked (this, EventArgs.Empty);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return base.ProcessKey (kb);
|
||||
}
|
||||
|
||||
#if false
|
||||
|
||||
@@ -110,7 +110,7 @@ namespace Terminal {
|
||||
SetNeedsDisplay ();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return base.ProcessKey (kb);
|
||||
}
|
||||
|
||||
#if false
|
||||
|
||||
@@ -47,5 +47,15 @@ namespace Terminal {
|
||||
start += bf.Width + 1;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool ProcessKey (KeyEvent kb)
|
||||
{
|
||||
switch (kb.Key) {
|
||||
case Key.Esc:
|
||||
Running = false;
|
||||
return true;
|
||||
}
|
||||
return base.ProcessKey (kb);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,7 +190,7 @@ namespace Terminal {
|
||||
}
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
return base.ProcessKey (kb);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -134,10 +134,8 @@ namespace Terminal {
|
||||
case Key.Space:
|
||||
Selected = cursor;
|
||||
return true;
|
||||
default:
|
||||
|
||||
return false;
|
||||
}
|
||||
return base.ProcessKey (kb);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user