浏览代码

View Draw API docs and code cleanup

Tig 9 月之前
父节点
当前提交
ee29ed87ed
共有 2 个文件被更改,包括 70 次插入26 次删除
  1. 53 21
      Terminal.Gui/View/View.Drawing.cs
  2. 17 5
      docfx/docs/drawing.md

+ 53 - 21
Terminal.Gui/View/View.Drawing.cs

@@ -1,4 +1,5 @@
 #nullable enable
+using System.ComponentModel;
 using System.Diagnostics;
 
 namespace Terminal.Gui;
@@ -26,12 +27,7 @@ public partial class View // Drawing APIs
         }
 
         DoDrawAdornments ();
-
-        // Set the color scheme for the view after adornments have been drawn
-        if (ColorScheme is { })
-        {
-            Driver?.SetAttribute (GetNormalColor ());
-        }
+        DoSetAttribute ();
 
         // By default, we clip to the viewport preventing drawing outside the viewport
         // We also clip to the content, but if a developer wants to draw outside the viewport, they can do
@@ -130,6 +126,52 @@ public partial class View // Drawing APIs
 
     #endregion DrawAdornments
 
+    #region SetAttribute
+
+    private void DoSetAttribute ()
+    {
+        if (OnSettingAttribute ())
+        {
+            return;
+        }
+
+        var args = new CancelEventArgs ();
+        SettingAttribute?.Invoke (this, args);
+
+        if (args.Cancel)
+        {
+            return;
+        }
+
+        SetNormalAttribute ();
+    }
+
+
+    /// <summary>
+    ///     Called when the normal attribute for the View is to be set. This is called before the View is drawn.
+    /// </summary>
+    /// <returns><see langword="true"/> to stop default behavior.</returns>
+    protected virtual bool OnSettingAttribute () { return false; }
+
+    /// <summary>Raised  when the normal attribute for the View is to be set. This is raised before the View is drawn.</summary>
+    /// <returns>
+    ///     Set <see cref="CancelEventArgs.Cancel"/> to <see langword="true"/> to stop default behavior.
+    /// </returns>
+    public event EventHandler<CancelEventArgs>? SettingAttribute;
+
+    /// <summary>
+    ///     Sets the attribute for the View. This is called before the View is drawn.
+    /// </summary>
+    public void SetNormalAttribute ()
+    {
+        if (ColorScheme is { })
+        {
+            Driver?.SetAttribute (GetNormalColor ());
+        }
+    }
+
+
+    #endregion
     #region ClearViewport
 
     private void DoClearViewport (Rectangle viewport)
@@ -465,20 +507,11 @@ public partial class View // Drawing APIs
 
     #region DrawComplete
 
-    private void DoDrawComplete (Rectangle viewport)
+    private void DoDrawComplete ()
     {
-        Debug.Assert (viewport == Viewport);
+        OnDrawComplete ();
 
-        if (OnDrawComplete (Viewport))
-        {
-            return;
-        }
-
-        var dev = new DrawEventArgs (Viewport, Rectangle.Empty);
-        DrawComplete?.Invoke (this, dev);
-
-        if (dev.Cancel)
-        { }
+        DrawComplete?.Invoke (this, EventArgs.Empty);
 
         // Default implementation does nothing.
     }
@@ -486,13 +519,12 @@ public partial class View // Drawing APIs
     /// <summary>
     ///     Called when the View is completed drawing.
     /// </summary>
-    /// <param name="viewport"></param>
-    protected virtual bool OnDrawComplete (Rectangle viewport) { return false; }
+    protected virtual void OnDrawComplete () { }
 
     /// <summary>Raised when the View is completed drawing.</summary>
     /// <remarks>
     /// </remarks>
-    public event EventHandler<DrawEventArgs>? DrawComplete;
+    public event EventHandler<EventArgs>? DrawComplete;
 
     #endregion DrawComplete
 

+ 17 - 5
docfx/docs/drawing.md

@@ -6,13 +6,13 @@ Color is supported on all platforms, including Windows, Mac, and Linux. The defa
 
 ## View Drawing API
 
-A @Terminal.Gui.View will typically draw text when the @Terminal.Gui.Border.OnDrawContent(System.Drawing.Rectangle) is called (or the `DrawContent` event is received).
+Terminal.Gui apps draw using the @Terminal.Gui.View.Move and @Terminal.Gui.View.AddRune APIs. @Terminal.Gui.View.Move selects the column and row of the @Terminal.Gui.Cell and @Terminal.Gui.AddRune places the specified glyph in that cell using the @Terminal.Gui.Attribute that was most recently set via @Terminal.Gui.SetAttribute. The @Terminal.Gui.ConsoleDriver caches all changed Cells and efficiently outputs them to the terminal each iteration of the Application. In other words, Terminal.Gui uses deferred rendering. 
 
 Outputting unformatted text involves:
 
-a) Moving the draw cursor using the `Move` API.
-b) Setting the attributes using `SetAttribute`.
-c) Outputting glyphs by calling `AddRune` or `AddStr`.
+a) Moving the draw cursor using @Terminal.Gui.ViewMove.
+b) Setting the attributes using @Terminal.Gui.ViewSetAttribute`
+c) Outputting glyphs by calling @Terminal.Gui.View.AddRune or @Terminal.Gui.View.AddStr
 
 Outputting formatted text involves:
 
@@ -25,9 +25,21 @@ Line drawing is accomplished using the @Terminal.Gui.LineCanvas API:
 a) Add the lines via @Terminal.Gui.LineCanvas.Add.
 b) Either render the line canvas via @Terminal.Gui.LineCanvas.GetMap() or let the @Terminal.Gui.View do so automatically (which enables automatic line joining across Views).
 
+The @Terminal.Gui.Application MainLoop will iterate over all Views in an application looking for views have their @Terminal.Gui.View.NeedsDisplay property set. The @Terminal.Gui.View.Draw method will be called which, in turn.
+
+1) Draws the Adornments (e.g. @Terminal.Gui.View.Border).
+2) Sets the Normal color scheme.
+3) Clears the @Terminal.Gui.View.Viewport.
+4) Draws @Terminal.Gui.View.Text.
+5) Draws any non-text or Subview content.
+6) Draws @Terminal.Gui.View.Subviews.
+7) Draws @Terminal.Gui.View.LineCanvas (which may have been added to by any of the steps above).
+
+Each of these steps can be overridden by developers using the standard [Terminal.Gui cancellable event pattern](events.md). For example, the base @Terminal.Gui.View always clears the viewport. To override this, a subclass can override @Terminal.Gui.View.OnClearingViewport to simply return `true`. Or, a user of `View` can subscribe to the @Terminal.Gui.View.ClearingViewport event and set the `Cancel` argument to `true`.
+
 ## Coordinate System for Drawing
 
-The @Terminal.Gui.View draw APIs, including the `OnDrawContent` method, the `DrawContent` event, and the @Terminal.Gui.View.Move method, all take coordinates specified in *Viewport-Relative* coordinates. That is, `0, 0` is the top-left cell visible to the user.
+The @Terminal.Gui.View draw APIs all take coordinates specified in *Viewport-Relative* coordinates. That is, `0, 0` is the top-left cell visible to the user.
 
 See [Layout](layout.md) for more details of the Terminal.Gui coordinate system.