diff --git a/.gitignore b/.gitignore
index b46551486..1929d8960 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,4 +8,7 @@ packages
# User-specific files
*.user
-docfx/api
\ No newline at end of file
+docfx/api
+
+#git merge files
+*.orig
\ No newline at end of file
diff --git a/Example/demo.cs b/Example/demo.cs
index 7f81d9e98..0e431422a 100644
--- a/Example/demo.cs
+++ b/Example/demo.cs
@@ -30,7 +30,7 @@ static class Demo {
throw new NotImplementedException ();
}
- public override void Redraw (Rect region)
+ public override void Redraw (Rect bounds)
{
//Point pos = new Point (region.X, region.Y);
Driver.SetAttribute (ColorScheme.Focus);
@@ -53,7 +53,7 @@ static class Demo {
{
}
- public override void Redraw (Rect region)
+ public override void Redraw (Rect bounds)
{
Driver.SetAttribute (ColorScheme.Focus);
var f = Frame;
@@ -520,7 +520,7 @@ static class Demo {
//Application.UseSystemConsole = true;
- Application.Init ();
+ Application.Init();
var top = Application.Top;
@@ -638,7 +638,7 @@ static class Demo {
var bottom2 = new Label ("This should go on the bottom of another top-level!");
top.Add (bottom2);
- Application.Loaded += (sender, e) => {
+ top.LayoutComplete += (sender, e) => {
bottom.X = win.X;
bottom.Y = Pos.Bottom (win) - Pos.Top (win) - margin;
bottom2.X = Pos.Left (win);
diff --git a/Terminal.Gui/Core/Application.cs b/Terminal.Gui/Core/Application.cs
index 3c41d67db..ca42eb848 100644
--- a/Terminal.Gui/Core/Application.cs
+++ b/Terminal.Gui/Core/Application.cs
@@ -434,7 +434,7 @@ namespace Terminal.Gui {
Current = toplevel;
Driver.PrepareToRun (MainLoop, ProcessKeyEvent, ProcessKeyDownEvent, ProcessKeyUpEvent, ProcessMouseEvent);
if (toplevel.LayoutStyle == LayoutStyle.Computed)
- toplevel.RelativeLayout (new Rect (0, 0, Driver.Cols, Driver.Rows));
+ toplevel.SetRelativeLayout (new Rect (0, 0, Driver.Cols, Driver.Rows));
toplevel.LayoutSubviews ();
Loaded?.Invoke (null, new ResizedEventArgs () { Rows = Driver.Rows, Cols = Driver.Cols });
toplevel.WillPresent ();
@@ -481,6 +481,7 @@ namespace Terminal.Gui {
if (closeDriver) {
MainLoop = null;
Driver.End ();
+ Driver = null;
}
_initialized = false;
@@ -670,7 +671,7 @@ namespace Terminal.Gui {
Driver.Clip = full;
foreach (var t in toplevels) {
t.PositionToplevels ();
- t.RelativeLayout (full);
+ t.SetRelativeLayout (full);
t.LayoutSubviews ();
}
Refresh ();
diff --git a/Terminal.Gui/Core/ConsoleDriver.cs b/Terminal.Gui/Core/ConsoleDriver.cs
index fb3015893..72bd854b1 100644
--- a/Terminal.Gui/Core/ConsoleDriver.cs
+++ b/Terminal.Gui/Core/ConsoleDriver.cs
@@ -562,7 +562,7 @@ namespace Terminal.Gui {
const char bottomChar = clearChar;
#endif
///
- /// Draws a frame for a window with padding aand n optional visible border inside the padding.
+ /// Draws a frame for a window with padding and an optional visible border inside the padding.
///
/// Screen relative region where the frame will be drawn.
/// Number of columns to pad on the left (if 0 the border will not appear on the left).
@@ -724,7 +724,7 @@ namespace Terminal.Gui {
// DrawFrame assumes the border is always at least one row/col thick
// DrawWindowFrame assumes a padding of 0 means NO padding and no frame
DrawWindowFrame (new Rect (region.X, region.Y, region.Width, region.Height),
- padding + 1, padding + 1, padding + 1, padding + 1, fill: fill);
+ padding + 1, padding + 1, padding + 1, padding + 1, border: false, fill: fill);
}
diff --git a/Terminal.Gui/Core/Toplevel.cs b/Terminal.Gui/Core/Toplevel.cs
index 3386d7f03..4e2c6ca1d 100644
--- a/Terminal.Gui/Core/Toplevel.cs
+++ b/Terminal.Gui/Core/Toplevel.cs
@@ -13,19 +13,18 @@ namespace Terminal.Gui {
///
///
///
- /// Toplevels can be modally executing views, and they return control
- /// to the caller when the "Running" property is set to false, or
- /// by calling
+ /// Toplevels can be modally executing views, started by calling .
+ /// They return control to the caller when has
+ /// been called (which sets the property to false).
///
///
- /// There will be a toplevel created for you on the first time use
- /// and can be accessed from the property ,
- /// but new toplevels can be created and ran on top of it. To run, create the
- /// toplevel and then invoke with the
- /// new toplevel.
+ /// A Toplevel is created when an application initialzies Terminal.Gui by callling .
+ /// The application Toplevel can be accessed via . Additional Toplevels can be created
+ /// and run (e.g. s. To run a Toplevel, create the and
+ /// call .
///
///
- /// TopLevels can also opt-in to more sophisticated initialization
+ /// Toplevels can also opt-in to more sophisticated initialization
/// by implementing . When they do
/// so, the and
/// methods will be called
@@ -33,27 +32,29 @@ namespace Terminal.Gui {
/// If first-run-only initialization is preferred, the
/// can be implemented too, in which case the
/// methods will only be called if
- /// is . This allows proper View inheritance hierarchies
+ /// is . This allows proper inheritance hierarchies
/// to override base class layout code optimally by doing so only on first run,
/// instead of on every run.
///
///
public class Toplevel : View {
///
- /// Gets or sets whether the Mainloop for this is running or not. Setting
- /// this property to false will cause the MainLoop to exit.
+ /// Gets or sets whether the for this is running or not.
///
+ ///
+ /// Setting this property directly is discouraged. Use instead.
+ ///
public bool Running { get; set; }
///
- /// Fired once the Toplevel's MainLoop has started it's first iteration.
+ /// Fired once the Toplevel's has started it's first iteration.
/// Subscribe to this event to perform tasks when the has been laid out and focus has been set.
/// changes. A Ready event handler is a good place to finalize initialization after calling `(topLevel)`.
///
public event EventHandler Ready;
///
- /// Called from Application.RunLoop after the has entered it's first iteration of the loop.
+ /// Called from after the has entered it's first iteration of the loop.
///
internal virtual void OnReady ()
{
@@ -70,7 +71,7 @@ namespace Terminal.Gui {
}
///
- /// Initializes a new instance of the class with Computed layout, defaulting to full screen.
+ /// Initializes a new instance of the class with layout, defaulting to full screen.
///
public Toplevel () : base ()
{
@@ -85,7 +86,7 @@ namespace Terminal.Gui {
}
///
- /// Convenience factory method that creates a new toplevel with the current terminal dimensions.
+ /// Convenience factory method that creates a new Toplevel with the current terminal dimensions.
///
/// The create.
public static Toplevel Create ()
@@ -109,12 +110,12 @@ namespace Terminal.Gui {
public bool Modal { get; set; }
///
- /// Check id current toplevel has menu bar
+ /// Gets or sets the menu for this Toplevel
///
public MenuBar MenuBar { get; set; }
///
- /// Check id current toplevel has status bar
+ /// Gets or sets the status bar for this Toplevel
///
public StatusBar StatusBar { get; set; }
@@ -256,18 +257,18 @@ namespace Terminal.Gui {
}
///
- public override void Redraw (Rect region)
+ public override void Redraw (Rect bounds)
{
Application.CurrentView = this;
if (IsCurrentTop || this == Application.Top) {
if (NeedDisplay != null && !NeedDisplay.IsEmpty) {
Driver.SetAttribute (Colors.TopLevel.Normal);
- Clear (region);
+ Clear (Frame);
Driver.SetAttribute (Colors.Base.Normal);
}
foreach (var view in Subviews) {
- if (view.Frame.IntersectsWith (region)) {
+ if (view.Frame.IntersectsWith (bounds)) {
view.SetNeedsLayout ();
view.SetNeedsDisplay (view.Bounds);
}
@@ -280,7 +281,7 @@ namespace Terminal.Gui {
}
///
- /// This method is invoked by Application.Begin as part of the Application.Run after
+ /// Invoked by as part of the after
/// the views have been laid out, and before the views are drawn for the first time.
///
public virtual void WillPresent ()
diff --git a/Terminal.Gui/Core/View.cs b/Terminal.Gui/Core/View.cs
index b426a9a06..1d50cfe5b 100644
--- a/Terminal.Gui/Core/View.cs
+++ b/Terminal.Gui/Core/View.cs
@@ -20,7 +20,7 @@ namespace Terminal.Gui {
///
/// Determines the LayoutStyle for a view, if Absolute, during LayoutSubviews, the
- /// value from the Frame will be used, if the value is Computer, then the Frame
+ /// value from the Frame will be used, if the value is Computed, then the Frame
/// will be updated from the X, Y Pos objects and the Width and Height Dim objects.
///
public enum LayoutStyle {
@@ -41,68 +41,73 @@ namespace Terminal.Gui {
///
///
///
- /// The View defines the base functionality for user interface elements in Terminal/gui.cs. Views
+ /// The View defines the base functionality for user interface elements in Terminal.Gui. Views
/// can contain one or more subviews, can respond to user input and render themselves on the screen.
///
///
- /// Views can either be created with an absolute position, by calling the constructor that takes a
- /// Rect parameter to specify the absolute position and size (the Frame of the View) or by setting the
- /// X, Y, Width and Height properties on the view. Both approaches use coordinates that are relative
- /// to the container they are being added to.
+ /// Views supports two layout styles: Absolute or Computed. The choice as to which layout style is used by the View
+ /// is determined when the View is initizlied. To create a View using Absolute layout, call a constructor that takes a
+ /// Rect parameter to specify the absolute position and size (the View.)/. To create a View
+ /// using Computed layout use a constructor that does not take a Rect parametr and set the X, Y, Width and Height
+ /// properties on the view. Both approaches use coordinates that are relative to the container they are being added to.
///
///
- /// When you do not specify a Rect frame you can use the more flexible
- /// Dim and Pos objects that can dynamically update the position of a view.
+ /// To switch between Absolute and Computed layout, use the property.
+ ///
+ ///
+ /// Computed layout is more flexible and supports dynamic console apps where controls adjust layout
+ /// as the terminal resizes or other Views change size or position. The X, Y, Width and Height
+ /// properties are Dim and Pos objects that dynamically update the position of a view.
/// The X and Y properties are of type
/// and you can use either absolute positions, percentages or anchor
/// points. The Width and Height properties are of type
/// and can use absolute position,
/// percentages and anchors. These are useful as they will take
- /// care of repositioning your views if your view's frames are resized
- /// or if the terminal size changes.
+ /// care of repositioning views when view's frames are resized or
+ /// if the terminal size changes.
///
///
- /// When you specify the Rect parameter to a view, you are setting the LayoutStyle to Absolute, and the
- /// view will always stay in the position that you placed it. To change the position change the
- /// Frame property to the new position.
+ /// Absolute layout requires specifying coordiantes and sizes of Views explicitly, and the
+ /// View will typcialy stay in a fixed position and size. To change the position and size use the
+ /// property.
///
///
- /// Subviews can be added to a View by calling the Add method. The container of a view is the
- /// Superview.
+ /// Subviews (child views) can be added to a View by calling the method.
+ /// The container of a View can be accessed with the property.
///
///
- /// Developers can call the SetNeedsDisplay method on the view to flag a region or the entire view
+ /// The method flags a region or the entire view
/// as requiring to be redrawn.
///
///
- /// Views have a ColorScheme property that defines the default colors that subviews
+ /// Views have a property that defines the default colors that subviews
/// should use for rendering. This ensures that the views fit in the context where
/// they are being used, and allows for themes to be plugged in. For example, the
/// default colors for windows and toplevels uses a blue background, while it uses
/// a white background for dialog boxes and a red background for errors.
///
///
- /// If a ColorScheme is not set on a view, the result of the ColorScheme is the
- /// value of the SuperView and the value might only be valid once a view has been
- /// added to a SuperView, so your subclasses should not rely on ColorScheme being
- /// set at construction time.
+ /// Subclasses should not rely on being
+ /// set at construction time. If a is not set on a view, the view will inherit the
+ /// value from its and the value might only be valid once a view has been
+ /// added to a SuperView.
///
///
- /// Using ColorSchemes has the advantage that your application will work both
+ /// By using applications will work both
/// in color as well as black and white displays.
///
///
- /// Views that are focusable should implement the PositionCursor to make sure that
- /// the cursor is placed in a location that makes sense. Unix terminals do not have
+ /// Views that are focusable should implement the to make sure that
+ /// the cursor is placed in a location that makes sense. Unix terminals do not have
/// a way of hiding the cursor, so it can be distracting to have the cursor left at
/// the last focused view. So views should make sure that they place the cursor
/// in a visually sensible place.
///
///
- /// The metnod LayoutSubviews is invoked when the size or layout of a view has
+ /// The method is invoked when the size or layout of a view has
/// changed. The default processing system will keep the size and dimensions
- /// for views that use the LayoutKind.Absolute, and will recompute the
- /// frames for the vies that use LayoutKind.Computed.
+ /// for views that use the , and will recompute the
+ /// frames for the vies that use .
///
///
public class View : Responder, IEnumerable {
@@ -111,17 +116,18 @@ namespace Terminal.Gui {
Backward
}
+ // container == SuperView
View container = null;
View focused = null;
Direction focusDirection;
///
- /// Event fired when the view get focus.
+ /// Event fired when the view gets focus.
///
public event EventHandler Enter;
///
- /// Event fired when the view lost focus.
+ /// Event fired when the view looses focus.
///
public event EventHandler Leave;
@@ -131,7 +137,7 @@ namespace Terminal.Gui {
public event EventHandler MouseEnter;
///
- /// Event fired when the view loses mouse event for the last time.
+ /// Event fired when the view receives a mouse event for the last time.
///
public event EventHandler MouseLeave;
@@ -173,13 +179,14 @@ namespace Terminal.Gui {
internal Rect NeedDisplay { get; private set; } = Rect.Empty;
- // The frame for the object
+ // The frame for the object. Superview relative.
Rect frame;
///
/// Gets or sets an identifier for the view;
///
/// The identifier.
+ /// The id should be unique across all Views that share a SuperView.
public ustring Id { get; set; } = "";
///
@@ -192,7 +199,7 @@ namespace Terminal.Gui {
}
///
- /// Gets or sets a value indicating whether this want mouse position reports.
+ /// Gets or sets a value indicating whether this wants mouse position reports.
///
/// true if want mouse position reports; otherwise, false.
public virtual bool WantMousePositionReports { get; set; } = false;
@@ -201,13 +208,19 @@ namespace Terminal.Gui {
/// Gets or sets a value indicating whether this want continuous button pressed event.
///
public virtual bool WantContinuousButtonPressed { get; set; } = false;
+
///
- /// Gets or sets the frame for the view.
+ /// Gets or sets the frame for the view. The frame is relative to the .
///
/// The frame.
///
+ ///
+ /// Change the Frame when using the layout style to move or resize views.
+ ///
+ ///
/// Altering the Frame of a view will trigger the redrawing of the
- /// view as well as the redrawing of the affected regions in the superview.
+ /// view as well as the redrawing of the affected regions in the .
+ ///
///
public virtual Rect Frame {
get => frame;
@@ -236,9 +249,9 @@ namespace Terminal.Gui {
LayoutStyle layoutStyle;
///
- /// Controls how the view's Frame is computed during the LayoutSubviews method, if Absolute, then
- /// LayoutSubviews does not change the Frame properties, otherwise the Frame is updated from the
- /// values in X, Y, Width and Height properties.
+ /// Controls how the View's is computed during the LayoutSubviews method, if the style is set to ,
+ /// LayoutSubviews does not change the . If the style is the is updated using
+ /// the , , , and properties.
///
/// The layout style.
public LayoutStyle LayoutStyle {
@@ -250,7 +263,7 @@ namespace Terminal.Gui {
}
///
- /// The bounds represent the View-relative rectangle used for this view. Updates to the Bounds update the Frame, and has the same side effects as updating the frame.
+ /// The bounds represent the View-relative rectangle used for this view. Updates to the Bounds update the , and has the same side effects as updating the .
///
/// The bounds.
public Rect Bounds {
@@ -262,10 +275,12 @@ namespace Terminal.Gui {
Pos x, y;
///
- /// Gets or sets the X position for the view (the column). This is only used when the LayoutStyle is Computed, if the
- /// LayoutStyle is set to Absolute, this value is ignored.
+ /// Gets or sets the X position for the view (the column). Only used whe is .
///
/// The X Position.
+ ///
+ /// If is changing this property has no effect and its value is indeterminate.
+ ///
public Pos X {
get => x;
set {
@@ -275,10 +290,12 @@ namespace Terminal.Gui {
}
///
- /// Gets or sets the Y position for the view (line). This is only used when the LayoutStyle is Computed, if the
- /// LayoutStyle is set to Absolute, this value is ignored.
+ /// Gets or sets the Y position for the view (the row). Only used whe is .
///
/// The y position (line).
+ ///
+ /// If is changing this property has no effect and its value is indeterminate.
+ ///
public Pos Y {
get => y;
set {
@@ -290,10 +307,12 @@ namespace Terminal.Gui {
Dim width, height;
///
- /// Gets or sets the width for the view. This is only used when the LayoutStyle is Computed, if the
- /// LayoutStyle is set to Absolute, this value is ignored.
+ /// Gets or sets the width of the view. Only used whe is .
///
/// The width.
+ ///
+ /// If is changing this property has no effect and its value is indeterminate.
+ ///
public Dim Width {
get => width;
set {
@@ -303,10 +322,10 @@ namespace Terminal.Gui {
}
///
- /// Gets or sets the height for the view. This is only used when the LayoutStyle is Computed, if the
- /// LayoutStyle is set to Absolute, this value is ignored.
+ /// Gets or sets the height of the view. Only used whe is .
///
/// The height.
+ /// If is changing this property has no effect and its value is indeterminate.
public Dim Height {
get => height;
set {
@@ -322,11 +341,14 @@ namespace Terminal.Gui {
public View SuperView => container;
///
- /// Initializes a new instance of the class with the absolute
- /// dimensions specified in the frame. If you want to have Views that can be positioned with
- /// Pos and Dim properties on X, Y, Width and Height, use the empty constructor.
+ /// Initializes a new instance of a class with the absolute
+ /// dimensions specified in the frame parameter.
///
/// The region covered by this view.
+ ///
+ /// This constructor intitalize a View with a of . Use to
+ /// initialize a View with of
+ ///
public View (Rect frame)
{
this.Frame = frame;
@@ -335,10 +357,15 @@ namespace Terminal.Gui {
}
///
- /// Initializes a new instance of the class and sets the
- /// view up for Computed layout, which will use the values in X, Y, Width and Height to
- /// compute the View's Frame.
+ /// Initializes a new instance of class.
///
+ ///
+ /// Use , , , and properties to dynamically control the size and location of the view.
+ ///
+ ///
+ /// This constructor intitalize a View with a of .
+ /// Use , , , and properties to dynamically control the size and location of the view.
+ ///
public View ()
{
CanFocus = false;
@@ -346,8 +373,7 @@ namespace Terminal.Gui {
}
///
- /// Invoke to flag that this view needs to be redisplayed, by any code
- /// that alters the state of the view.
+ /// Sets a flag indicating this view needs to be redisplayed because its state has changed.
///
public void SetNeedsDisplay ()
{
@@ -367,9 +393,9 @@ namespace Terminal.Gui {
}
///
- /// Flags the specified rectangle region on this view as needing to be repainted.
+ /// Flags the view-relative region on this View as needing to be repainted.
///
- /// The region that must be flagged for repaint.
+ /// The view-relative region that must be flagged for repaint.
public void SetNeedsDisplay (Rect region)
{
if (NeedDisplay == null || NeedDisplay.IsEmpty)
@@ -397,7 +423,7 @@ namespace Terminal.Gui {
internal bool childNeedsDisplay;
///
- /// Flags this view for requiring the children views to be repainted.
+ /// Indicates that any child views (in the list) need to be repainted.
///
public void ChildNeedsDisplay ()
{
@@ -407,9 +433,10 @@ namespace Terminal.Gui {
}
///
- /// Adds a subview to this view.
+ /// Adds a subview (child) to this view.
///
///
+ /// The Views that have been added to this view can be retrieved via the property. See also
///
public virtual void Add (View view)
{
@@ -426,9 +453,12 @@ namespace Terminal.Gui {
}
///
- /// Adds the specified views to the view.
+ /// Adds the specified views (children) to the view.
///
/// Array of one or more views (can be optional parameter).
+ ///
+ /// The Views that have been added to this view can be retrieved via the property. See also
+ ///
public void Add (params View [] views)
{
if (views == null)
@@ -438,10 +468,8 @@ namespace Terminal.Gui {
}
///
- /// Removes all the widgets from this container.
+ /// Removes all subviews (children) added via or from this View.
///
- ///
- ///
public virtual void RemoveAll ()
{
if (subviews == null)
@@ -453,7 +481,7 @@ namespace Terminal.Gui {
}
///
- /// Removes a widget from this container.
+ /// Removes a subview added via or from this View.
///
///
///
@@ -573,27 +601,30 @@ namespace Terminal.Gui {
}
///
- /// Clears the specified rectangular region with the current color
+ /// Clears the specified region with the current color.
///
- public void Clear (Rect r)
+ ///
+ ///
+ /// The screen-relative region to clear.
+ public void Clear (Rect regionScreen)
{
- var h = r.Height;
- var w = r.Width;
- for (int line = r.Y; line < r.Y + h; line++) {
- Driver.Move (r.X, line);
+ var h = regionScreen.Height;
+ var w = regionScreen.Width;
+ for (int line = regionScreen.Y; line < regionScreen.Y + h; line++) {
+ Driver.Move (regionScreen.X, line);
for (int col = 0; col < w; col++)
Driver.AddRune (' ');
}
}
///
- /// Converts the (col,row) position from the view into a screen (col,row). The values are clamped to (0..ScreenDim-1)
+ /// Converts a view-relative (col,row) position to a screen-relative position (col,row). The values are optionally clamped to the screen dimensions.
///
- /// View-based column.
- /// View-based row.
- /// Absolute column, display relative.
- /// Absolute row, display relative.
- /// Whether to clip the result of the ViewToScreen method, if set to true, the rcol, rrow values are clamped to the screen dimensions.
+ /// View-relative column.
+ /// View-relative row.
+ /// Absolute column; screen-relative.
+ /// Absolute row; screen-relative.
+ /// Whether to clip the result of the ViewToScreen method, if set to true, the rcol, rrow values are clamped to the screen (terminal) dimensions (0..TerminalDim-1).
internal void ViewToScreen (int col, int row, out int rcol, out int rrow, bool clipped = true)
{
// Computes the real row, col relative to the screen.
@@ -614,7 +645,7 @@ namespace Terminal.Gui {
}
///
- /// Converts a point from screen coordinates into the view coordinate space.
+ /// Converts a point from screen-relative coordinates to view-relative coordinates.
///
/// The mapped point.
/// X screen-coordinate point.
@@ -629,66 +660,72 @@ namespace Terminal.Gui {
}
}
- // Converts a rectangle in view coordinates to screen coordinates.
- internal Rect RectToScreen (Rect rect)
+ ///
+ /// Converts a region in view-relative coordinates to screen-relative coordinates.
+ ///
+ internal Rect ViewToScreen (Rect region)
{
- ViewToScreen (rect.X, rect.Y, out var x, out var y, clipped: false);
- return new Rect (x, y, rect.Width, rect.Height);
+ ViewToScreen (region.X, region.Y, out var x, out var y, clipped: false);
+ return new Rect (x, y, region.Width, region.Height);
}
// Clips a rectangle in screen coordinates to the dimensions currently available on the screen
- internal Rect ScreenClip (Rect rect)
+ internal Rect ScreenClip (Rect regionScreen)
{
- var x = rect.X < 0 ? 0 : rect.X;
- var y = rect.Y < 0 ? 0 : rect.Y;
- var w = rect.X + rect.Width >= Driver.Cols ? Driver.Cols - rect.X : rect.Width;
- var h = rect.Y + rect.Height >= Driver.Rows ? Driver.Rows - rect.Y : rect.Height;
+ var x = regionScreen.X < 0 ? 0 : regionScreen.X;
+ var y = regionScreen.Y < 0 ? 0 : regionScreen.Y;
+ var w = regionScreen.X + regionScreen.Width >= Driver.Cols ? Driver.Cols - regionScreen.X : regionScreen.Width;
+ var h = regionScreen.Y + regionScreen.Height >= Driver.Rows ? Driver.Rows - regionScreen.Y : regionScreen.Height;
return new Rect (x, y, w, h);
}
///
- /// Sets the Console driver's clip region to the current View's Bounds.
+ /// Sets the 's clip region to the current View's .
///
- /// The existing driver's Clip region, which can be then set by setting the Driver.Clip property.
+ /// The existing driver's clip region, which can be then re-eapplied by setting .Clip ().
+ ///
+ /// is View-relative.
+ ///
public Rect ClipToBounds ()
{
return SetClip (Bounds);
}
///
- /// Sets the clipping region to the specified region, the region is view-relative
+ /// Sets the clip region to the specified view-relative region.
///
- /// The previous clip region.
- /// Rectangle region to clip into, the region is view-relative.
- public Rect SetClip (Rect rect)
+ /// The previous screen-relative clip region.
+ /// View-relative clip region.
+ public Rect SetClip (Rect region)
{
- var bscreen = RectToScreen (rect);
var previous = Driver.Clip;
- Driver.Clip = ScreenClip (RectToScreen (Bounds));
+ Driver.Clip = Rect.Intersect (previous, ViewToScreen (region));
return previous;
}
///
/// Draws a frame in the current view, clipped by the boundary of this view
///
- /// Rectangular region for the frame to be drawn.
- /// The padding to add to the drawn frame.
+ /// View-relative region for the frame to be drawn.
+ /// The padding to add around the outside of the drawn frame.
/// If set to true it fill will the contents.
- public void DrawFrame (Rect rect, int padding = 0, bool fill = false)
+ public void DrawFrame (Rect region, int padding = 0, bool fill = false)
{
- var scrRect = RectToScreen (rect);
+ var scrRect = ViewToScreen (region);
var savedClip = ClipToBounds ();
- Driver.DrawFrame (scrRect, padding, fill);
+ Driver.DrawWindowFrame (scrRect, padding + 1, padding + 1, padding + 1, padding + 1, border: true, fill: fill);
Driver.Clip = savedClip;
}
///
- /// Utility function to draw strings that contain a hotkey
+ /// Utility function to draw strings that contain a hotkey.
///
/// String to display, the underscoore before a letter flags the next letter as the hotkey.
/// Hot color.
/// Normal color.
+ ///
+ /// The hotkey is any character following an underscore ('_') character.
public void DrawHotString (ustring text, Attribute hotColor, Attribute normalColor)
{
Driver.SetAttribute (normalColor);
@@ -703,7 +740,7 @@ namespace Terminal.Gui {
}
///
- /// Utility function to draw strings that contains a hotkey using a colorscheme and the "focused" state.
+ /// Utility function to draw strings that contains a hotkey using a and the "focused" state.
///
/// String to display, the underscoore before a letter flags the next letter as the hotkey.
/// If set to true this uses the focused colors from the color scheme, otherwise the regular ones.
@@ -720,8 +757,8 @@ namespace Terminal.Gui {
/// This moves the cursor to the specified column and row in the view.
///
/// The move.
- /// Col.
- /// Row.
+ /// Col (view-relative).
+ /// Row (view-relative).
public void Move (int col, int row)
{
ViewToScreen (col, row, out var rcol, out var rrow);
@@ -731,6 +768,11 @@ namespace Terminal.Gui {
///
/// Positions the cursor in the right position based on the currently focused view in the chain.
///
+ /// Views that are focusable should override to ensure
+ /// the cursor is placed in a location that makes sense. Unix terminals do not have
+ /// a way of hiding the cursor, so it can be distracting to have the cursor left at
+ /// the last focused view. Views should make sure that they place the cursor
+ /// in a visually sensible place.
public virtual void PositionCursor ()
{
if (focused != null)
@@ -763,7 +805,7 @@ namespace Terminal.Gui {
}
///
- /// Specifies the event arguments for
+ /// Defines the event arguments for
///
public class FocusEventArgs : EventArgs {
///
@@ -825,7 +867,7 @@ namespace Terminal.Gui {
}
///
- /// The color scheme for this view, if it is not defined, it returns the parent's
+ /// The color scheme for this view, if it is not defined, it returns the 's
/// color scheme.
///
public ColorScheme ColorScheme {
@@ -842,10 +884,10 @@ namespace Terminal.Gui {
ColorScheme colorScheme;
///
- /// Displays the specified character in the specified column and row.
+ /// Displays the specified character in the specified column and row of the View.
///
- /// Col.
- /// Row.
+ /// Column (view-relative).
+ /// Row (view-relative).
/// Ch.
public void AddRune (int col, int row, Rune ch)
{
@@ -858,7 +900,7 @@ namespace Terminal.Gui {
}
///
- /// Removes the SetNeedsDisplay and the ChildNeedsDisplay setting on this view.
+ /// Removes the and the setting on this view.
///
protected void ClearNeedsDisplay ()
{
@@ -867,37 +909,40 @@ namespace Terminal.Gui {
}
///
- /// Performs a redraw of this view and its subviews, only redraws the views that have been flagged for a re-display.
+ /// Redraws this view and its subviews; only redraws the views that have been flagged for a re-display.
///
- /// The region to redraw, this is relative to the view itself.
+ /// The bounds (view-relative region) to redraw.
///
///
+ /// Always use (view-relative) when calling , NOT (superview-relative).
+ ///
+ ///
/// Views should set the color that they want to use on entry, as otherwise this will inherit
/// the last color that was set globaly on the driver.
///
+ ///
+ /// Overrides of must ensure they do not set Driver.Clip to a clip region
+ /// larger than the region parameter.
+ ///
///
- public virtual void Redraw (Rect region)
+ public virtual void Redraw (Rect bounds)
{
var clipRect = new Rect (Point.Empty, frame.Size);
if (subviews != null) {
foreach (var view in subviews) {
if (view.NeedDisplay != null && (!view.NeedDisplay.IsEmpty || view.childNeedsDisplay)) {
- if (view.Frame.IntersectsWith (clipRect) && view.Frame.IntersectsWith (region)) {
+ if (view.Frame.IntersectsWith (clipRect) && view.Frame.IntersectsWith (bounds)) {
// FIXED: optimize this by computing the intersection of region and view.Bounds
if (view.layoutNeeded)
view.LayoutSubviews ();
Application.CurrentView = view;
- // Ensure we don't make the Driver's clip rect any bigger
- if (Driver.Clip.IsEmpty || Driver.Clip.Contains(RectToScreen (view.Frame))) {
- var savedClip = view.ClipToBounds ();
- view.Redraw (view.Bounds);
- Driver.Clip = savedClip;
- } else {
- view.Redraw (view.Bounds);
- }
+ // Clip the sub-view
+ var savedClip = ClipToBounds ();
+ view.Redraw (view.Bounds);
+ Driver.Clip = savedClip;
}
view.NeedDisplay = Rect.Empty;
view.childNeedsDisplay = false;
@@ -908,7 +953,7 @@ namespace Terminal.Gui {
}
///
- /// Focuses the specified sub-view.
+ /// Causes the specified subview to have focus.
///
/// View.
public void SetFocus (View view)
@@ -941,7 +986,7 @@ namespace Terminal.Gui {
}
///
- /// Specifies the event arguments for
+ /// Defines the event arguments for
///
public class KeyEventEventArgs : EventArgs {
///
@@ -1187,10 +1232,13 @@ namespace Terminal.Gui {
}
///
- /// Computes the RelativeLayout for the view, given the frame for its container.
+ /// Sets the View's to the relative coordinates if its container, given the for its container.
///
- /// The Frame for the host.
- internal void RelativeLayout (Rect hostFrame)
+ /// The screen-relative frame for the host.
+ ///
+ /// Reminder: is superview-relative; is view-relative.
+ ///
+ internal void SetRelativeLayout (Rect hostFrame)
{
int w, h, _x, _y;
@@ -1228,7 +1276,6 @@ namespace Terminal.Gui {
h = height.Anchor (hostFrame.Height - _y);
}
Frame = new Rect (_x, _y, w, h);
- // layoutNeeded = false;
}
// https://en.wikipedia.org/wiki/Topological_sorting
@@ -1274,15 +1321,45 @@ namespace Terminal.Gui {
}
///
- /// This virtual method is invoked when a view starts executing or
- /// when the dimensions of the view have changed, for example in
+ /// Event arguments for the event.
+ ///
+ public class LayoutEventArgs : EventArgs {
+ ///
+ /// The view-relative bounds of the before it was laid out.
+ ///
+ public Rect OldBounds { get; set; }
+ }
+
+ ///
+ /// Fired after the Views's method has completed.
+ ///
+ ///
+ /// Subscribe to this event to perform tasks when the has been resized or the layout has otherwise changed.
+ ///
+ public event EventHandler LayoutComplete;
+
+ ///
+ /// Raises the event. Called from after all sub-views have been laid out.
+ ///
+ internal virtual void OnLayoutComplete (LayoutEventArgs args)
+ {
+ LayoutComplete?.Invoke (this, args);
+ }
+
+ ///
+ /// Invoked when a view starts executing or when the dimensions of the view have changed, for example in
/// response to the container view or terminal resizing.
///
+ ///
+ /// Calls (which raises the event) before it returns.
+ ///
public virtual void LayoutSubviews ()
{
if (!layoutNeeded)
return;
+ Rect oldBounds = Bounds;
+
// Sort out the dependencies of the X, Y, Width, Height properties
var nodes = new HashSet ();
var edges = new HashSet<(View, View)> ();
@@ -1307,7 +1384,7 @@ namespace Terminal.Gui {
foreach (var v in ordered) {
if (v.LayoutStyle == LayoutStyle.Computed)
- v.RelativeLayout (Frame);
+ v.SetRelativeLayout (Frame);
v.LayoutSubviews ();
v.layoutNeeded = false;
@@ -1315,10 +1392,12 @@ namespace Terminal.Gui {
}
if (SuperView == Application.Top && layoutNeeded && ordered.Count == 0 && LayoutStyle == LayoutStyle.Computed) {
- RelativeLayout (Frame);
+ SetRelativeLayout (Frame);
}
layoutNeeded = false;
+
+ OnLayoutComplete (new LayoutEventArgs () { OldBounds = oldBounds });
}
///
diff --git a/Terminal.Gui/Core/Window.cs b/Terminal.Gui/Core/Window.cs
index 3544fc2e5..37184cbf0 100644
--- a/Terminal.Gui/Core/Window.cs
+++ b/Terminal.Gui/Core/Window.cs
@@ -7,7 +7,7 @@ using NStack;
namespace Terminal.Gui {
///
- /// A that draws a frame around its region and has a "ContentView" subview where the contents are added.
+ /// A that draws a frame around its region and has a "Content" subview where the contents are added.
///
public class Window : Toplevel, IEnumerable {
View contentView;
@@ -29,7 +29,7 @@ namespace Terminal.Gui {
public ContentView (Rect frame) : base (frame) { }
public ContentView () : base () { }
#if false
- public override void Redraw (Rect region)
+ public override void Redraw (Rect bounds)
{
Driver.SetAttribute (ColorScheme.Focus);
@@ -50,6 +50,10 @@ namespace Terminal.Gui {
///
/// Frame.
/// Title.
+ ///
+ /// This constructor intitalizes a Window with a of . Use constructors
+ /// that do not take Rect parameters to initialize a Window with of
+ ///
public Window (Rect frame, ustring title = null) : this (frame, title, padding: 0)
{
}
@@ -58,19 +62,26 @@ namespace Terminal.Gui {
/// Initializes a new instance of the class with an optional title.
///
/// Title.
+ ///
+ /// This constructor intitalize a View with a of .
+ /// Use , , , and properties to dynamically control the size and location of the view.
+ ///
public Window (ustring title = null) : this (title, padding: 0)
{
}
int padding;
///
- /// Initializes a new instance of the with
- /// the specified frame for its location, with the specified border
- /// an optional title.
+ /// Initializes a new instance of the with the specified frame for its location, with the specified border,
+ /// and an optional title.
///
/// Frame.
/// Number of characters to use for padding of the drawn frame.
/// Title.
+ ///
+ /// This constructor intitalizes a Window with a of . Use constructors
+ /// that do not take Rect parameters to initialize a Window with of
+ ///
public Window (Rect frame, ustring title = null, int padding = 0) : base (frame)
{
this.Title = title;
@@ -82,12 +93,15 @@ namespace Terminal.Gui {
}
///
- /// Initializes a new instance of the with
- /// the specified frame for its location, with the specified border
- /// an optional title.
+ /// Initializes a new instance of the with the specified frame for its location, with the specified border,
+ /// and an optional title.
///
/// Number of characters to use for padding of the drawn frame.
/// Title.
+ ///
+ /// This constructor intitalize a View with a of .
+ /// Use , , , and properties to dynamically control the size and location of the view.
+ ///
public Window (ustring title = null, int padding = 0) : base ()
{
this.Title = title;
@@ -111,10 +125,7 @@ namespace Terminal.Gui {
return contentView.GetEnumerator ();
}
- ///
- /// Add the specified view to the .
- ///
- /// View to add to the window.
+ ///
public override void Add (View view)
{
contentView.Add (view);
@@ -123,11 +134,7 @@ namespace Terminal.Gui {
}
- ///
- /// Removes a widget from this container.
- ///
- ///
- ///
+ ///
public override void Remove (View view)
{
if (view == null)
@@ -141,11 +148,7 @@ namespace Terminal.Gui {
this.CanFocus = false;
}
- ///
- /// Removes all widgets from this container.
- ///
- ///
- ///
+ ///
public override void RemoveAll ()
{
contentView.RemoveAll ();
@@ -156,24 +159,21 @@ namespace Terminal.Gui {
{
//var padding = 0;
Application.CurrentView = this;
- var scrRect = RectToScreen (new Rect(0, 0, Frame.Width, Frame.Height));
+ var scrRect = ViewToScreen (new Rect (0, 0, Frame.Width, Frame.Height));
// BUGBUG: Why do we draw the frame twice? This call is here to clear the content area, I think. Why not just clear that area?
if (NeedDisplay != null && !NeedDisplay.IsEmpty) {
Driver.SetAttribute (ColorScheme.Normal);
- Driver.DrawFrame (scrRect, padding, true);
+ Driver.DrawWindowFrame (scrRect, padding + 1, padding + 1, padding + 1, padding + 1, border: true, fill: true);
}
- if (Driver.Clip.IsEmpty || Driver.Clip.Contains (contentView.RectToScreen (contentView.Frame))) {
- var savedClip = ClipToBounds ();
- contentView.Redraw (contentView.Bounds);
- Driver.Clip = savedClip;
- } else {
- contentView.Redraw (contentView.Bounds);
- }
+ var savedClip = ClipToBounds ();
+ contentView.Redraw (contentView.Bounds);
+ Driver.Clip = savedClip;
+
ClearNeedsDisplay ();
Driver.SetAttribute (ColorScheme.Normal);
- Driver.DrawFrame (scrRect, padding, false);
+ Driver.DrawWindowFrame (scrRect, padding + 1, padding + 1, padding + 1, padding + 1, border: true, fill: false);
if (HasFocus)
Driver.SetAttribute (ColorScheme.HotNormal);
@@ -187,6 +187,7 @@ namespace Terminal.Gui {
//
internal static Point? dragPosition;
Point start;
+
///
public override bool MouseEvent (MouseEvent mouseEvent)
{
@@ -200,7 +201,7 @@ namespace Terminal.Gui {
if (dragPosition.HasValue) {
if (SuperView == null) {
Application.Top.SetNeedsDisplay (Frame);
- Application.Top.Redraw (Frame);
+ Application.Top.Redraw (Bounds);
} else {
SuperView.SetNeedsDisplay (Frame);
}
@@ -241,6 +242,5 @@ namespace Terminal.Gui {
//Demo.ml.Text = me.ToString ();
return false;
}
-
}
}
diff --git a/Terminal.Gui/Terminal.Gui.csproj b/Terminal.Gui/Terminal.Gui.csproj
index 01697a423..77c3a2342 100644
--- a/Terminal.Gui/Terminal.Gui.csproj
+++ b/Terminal.Gui/Terminal.Gui.csproj
@@ -5,11 +5,12 @@
Terminal.Guibin\Release\Terminal.Gui.xmltrue
+ 0.82.0.0trueTerminal.Gui
- 0.81
+ 0.82Miguel de IcazaMIThttps://github.com/migueldeicaza/gui.cs/
@@ -18,80 +19,141 @@
Miguel de IcazaApplication framework for creating modern console applications using .NET Gui.cs is a framework for creating console user interfaces
- 0.81: Fix ncurses engine for macOS/Linux, it works again
+
+ 0.82: Many fixes
+ * API documentation completely revamped and updated. Readme upated. Contributors guide added (Thanks @tig!)
+ * New sample/demo app - UI Catalog - Replaces demo.cs with an easy to use and extend set of demo scenarios. (Thanks @tig!)
+ * MenuBar can now have MenuItems directly (enables top-level menu items with no submenu). (Thanks @tig!)
+ * Apps can now get KeyUp/KeyDown events. (Thanks @tig!)
+ * Fixes #396 - Text alignnment issues. (Thanks @tig!)
+ * Fixes #423 - Fix putting results of ocgv on command line erases cursor. (Thanks @tig!)
+ * Example/Designer csproj files updated to latest Visual Studio model. (Thanks @tig!)
+ * Adjusted the default colors for Windows to make more readable. (Thanks @tig!)
+ * Toplevel.Ready event - Fired once the Toplevel's MainLoop has started (#445). (Thanks @tig!)
+ * Refactored several events to use event vs. Action. (BREAKING CHANGE) (Thanks @tig!)
+ * All compile warnings fixed. (Thanks @tig!)
+ * Fixed a crash in EnsureVisibleBounds. (Thanks @tig!)
+ * Application.Init/Shutdown are more robust. (Thanks @tig!)
+ * New "Draw Window Frame" code; consistent across Window, FrameView, and Menu. Fixes many drawing bugs. (Thanks @tig!)
+ * The project has been refactored an reorganized to reduce risk of bugs and make it easier to contribute #541. (Thanks @tig!)
+ * Fixes #522 - Last view of Frameview not drawn. (Thanks @tig!)
+ * Clipping has been fixed/restored - it now works properly. (#586) (Thanks @tig!)
+ * Added a View.LayoutComplete event (#569). (Thanks @tig!)
+ * Fixes #299 - MessageBox now auto sizes. (Thanks @tig!)
+ * Fixes #557 - MessageBoxes on small screens. (Thanks @tig!)
+ * Fixes #432 - MessageBox does not deal with long text; width/height params are goofy. (Thanks @tig!)
+ * Fixes #35 - Dialog should have 1 char padding. (Thanks @tig!)
+ * `MessageBox.Query` called with `width` and `height` == 0 get auto-size behavior. A new constructor is added making this easy to use. (Thanks @tig!)
+ * Multi-line `MessageBox`es are now supported. Just use `\n` to add lines. The height of the MessageBox will adjust automatically. (Thanks @tig!)
+ * The `MessageBoxes` Scenario in UI Catalog provides a full demo/test-case. (Thanks @tig!)
+ * `Dialog` called with `width` and `height` == 0 are sized to 85% container. A new constructor is added making this easy to use. (Thanks @tig!)
+ * Dialog (and MessageBox `Buttons` are now dynamically laid out using Computed layout. (Thanks @tig!)
+ * A `Dialogs` Scenario has been added to UI Catalog making it easy to test the API. (Thanks @tig!)
+ * `Button` now supports BOTH specifying a hotkey with '_' and the old behavior of using the first uppercase char (if '_' is not found). (Thanks @tig!)
+ * All UI Catalog scenarios that use `Dialog` or `MessageBox` now use the simplified API. (Thanks @tig!)
+ * `Terminal.Gui.dll` now has version metadata and UI Catalog's about box displays it as a test case. (Thanks @tig!)
+ * Button, Dialog, and MessageBox API documentation has been updated/revised. (Thanks @tig!)
+ * `View`, `Window`, `FrameView`, and `Dialog` have been upgraded to use the new `ConsoleDriver.DrawFrameWindow` API directly. (Thanks @tig!)
+ * New ComboBox control (Thanks @fergusonr!)
+ * ConsoleDriver now supports improved KeyModifers (shift keys) with an expanded Keys Sceanrio in UI Catalog. (Thanks @bdisp!)
+ * Tons of mouse handling improvements. (Thanks @bdisp!)
+ * Fsharp sample updated. (Thanks @bdisp!)
+ * Fixes #562 - Background drawing issue. (Thanks @bdisp!)
+ * Fixes #517 - Focus and mouse handlers enahced (BREAKING CHANGE). (Thanks @bdisp!)
+ * Fixed resizing update and correct Toplevel colors without colors. (Thanks @bdisp!)
+ * Fixed #515, #518, #536, #540. (Thanks @bdisp!)
+ * Added Threading Scenario to UI catalog. (Thanks @bdisp!)
+ * Added support for F11 and F12 keys. (Thanks @bdisp!)
+ * Multiple improvements to Date/TimeField. (Thanks @bdisp!)
+ * Fixes #409 - Invoke does not cause Wakeup #501. (Thanks @bdisp!)
+ * Fixed Label text alignemnt. (Thanks @bdisp!)
+ * Added mouse features in the Unix version. Supports xterm-1006. (Thanks @bdisp!)
+ * Several StatusBar fixes. (Thanks @bdisp!)
+ * Tons of mouse improvements including mouse wheel support (e.g. #404, #409). (Thanks @bdisp!)
+ * Added a CloseFile method to the TextView as stated in #452. (Thanks @bdisp)
+ * Added a OpenSelectedItem event to the ListView #429. (Thanks @bdisp!)
+ * Fixes the return value of the position cursor in the TextField. (Thanks @bdisp!)
+ * Updates screen on Unix window resizing. (Thanks @bdisp!)
+ * Fixes the functions of the Edit->Copy-Cut-Paste menu for the TextField that was not working well. (Thanks @bdisp!)
+ * More robust error handing in Pos/Dim. Fixes #355 stack overflow with Pos based on the size of windows at startup. Added a OnResized action to set the Pos after the terminal are resized. (Thanks @bdisp!)
+ * Fixes #389 Window layouting breaks when resizing. (Thanks @bdisp!)
+ * Fixes #557 MessageBox needs to take ustrings (BREAKING CHANGE). (Thanks @tig!)
-* Fixes an issue with referencing views that have not been allocated yet causing a stack overflow
-* New OnCloseMenu event on menus
-* Button cursor position looks better
-* Listview in single-selection mode uses a radio-button look
-* Fixes a couple of crashes (356)
-* Default the samples to work on Catalina
+ 0.81:
+ * Fix ncurses engine for macOS/Linux, it works again
+ * Fixes an issue with referencing views that have not been allocated yet causing a stack overflow
+ * New OnCloseMenu event on menus
+ * Button cursor position looks better
+ * Listview in single-selection mode uses a radio-button look
+ * Fixes a couple of crashes (356)
+ * Default the samples to work on Catalina
-0.80: Jumbo update from BDisp:
+ 0.80: Jumbo update from BDisp:
-* Fixed key events traversal for modal dialogs
-* Fixes culture info of DataField from pr
-* Fixes the rectangle drawing issue
-* Redraw issue when setting coordinates of label
-* Added sub menus into menu bar with mouse and key navigation
-* Added Colors.Menu.Disabled to CursesDriver.cs
-* Mouse text selection with cut, copy and paste on text fields
-* Change sepChar from char to string in DateField
-* Adding a disabled menu item in the demo file
-* Fixes Button repainting issue when changing the text length to one smaller
-* Fixes Redraw issue when setting coordinates of label
-* Fixes ScrollView does not render some content
-* Fixed bug in Button that caused a loop redraw calling TerminalResized
-* Fixes a repaint issue (282)
-* Mouse features added to FileDialog including wheel support.
-* Switch netcoreapp target to netstandard2.0
-* Added TextView.TextChanged event
-* Fixes issue #306 async/await hang (#312)
-* Replaced static driver initialization with property getter for reference passing in Core.cs::View class, this allows the library to be reinitialized at any time.
-* Made the Shutdown method on Core.cs::Application class public, since there is no reason to keep it private. Applications can shutdown the library and revert the console to the initial stage by calling it.
-* Fixed a memory-leak on Drivers/WindowsDriver class by destroying the generated screen buffers at library shutdown by calling CloseHandle.
-* Minor change to Core.cs::Application.Init(Func) for better initialization status tracking, via backend property instead of relying on the Top field.
-* Moved `ListView.ListWrapper` out of `ListView` migueldeicaza/gui.cs#313` (#315)
-* Resizing the MessageBox width to accommodate all message text (#299)
-* Timefield format with bounds values (#303)
-* Implemented lower and upper bounds to TimeField
-* Passing old text to the Changed event handler
-* Extract methods on ListView to make it controlable from other controls
+ * Fixed key events traversal for modal dialogs
+ * Fixes culture info of DataField from pr
+ * Fixes the rectangle drawing issue
+ * Redraw issue when setting coordinates of label
+ * Added sub menus into menu bar with mouse and key navigation
+ * Added Colors.Menu.Disabled to CursesDriver.cs
+ * Mouse text selection with cut, copy and paste on text fields
+ * Change sepChar from char to string in DateField
+ * Adding a disabled menu item in the demo file
+ * Fixes Button repainting issue when changing the text length to one smaller
+ * Fixes Redraw issue when setting coordinates of label
+ * Fixes ScrollView does not render some content
+ * Fixed bug in Button that caused a loop redraw calling TerminalResized
+ * Fixes a repaint issue (282)
+ * Mouse features added to FileDialog including wheel support.
+ * Switch netcoreapp target to netstandard2.0
+ * Added TextView.TextChanged event
+ * Fixes issue #306 async/await hang (#312)
+ * Replaced static driver initialization with property getter for reference passing in Core.cs::View class, this allows the library to be reinitialized at any time.
+ * Made the Shutdown method on Core.cs::Application class public, since there is no reason to keep it private. Applications can shutdown the library and revert the console to the initial stage by calling it.
+ * Fixed a memory-leak on Drivers/WindowsDriver class by destroying the generated screen buffers at library shutdown by calling CloseHandle.
+ * Minor change to Core.cs::Application.Init(Func) for better initialization status tracking, via backend property instead of relying on the Top field.
+ * Moved `ListView.ListWrapper` out of `ListView` migueldeicaza/gui.cs#313` (#315)
+ * Resizing the MessageBox width to accommodate all message text (#299)
+ * Timefield format with bounds values (#303)
+ * Implemented lower and upper bounds to TimeField
+ * Passing old text to the Changed event handler
+ * Extract methods on ListView to make it controlable from other controls
-0.70: Bug fixes (320, 321, 306, 304, 291, 299, 303); Surface ListView.ListWrapper, surface various internal methods for use in ListView; Allow list item selection; ; 0.65: Added new TimeField from Jörg Preiß; Fixes for Backtab by Martin Björkström; ListView now supports simple selection; Bug fixes by giladlevi, Daniel Cazzulino and Marius Ungureanu; New Application.Run of T entry point by Daniel Cazzulino; Added various View methods to bring forward, backwards and move views in the hierarchy; Switch to Portable PDBs by Daniel Cazzulino; Dims can now be compared by Daniel Cazzulino; OnMenuOpen handler by giladlevi; Various memory usage optimizations by giladlevi; FileDialog.FilePath is now a full path by Yanwei Wang; ISupportInitialize/ISupportInitializeNotification is now supported thanks to the work from Daniel Cazzulino; Support for non-modal TopLevels by Daniel Cazzulino and Adrian Alonso; 0.24: the Windows driver implements WakeUp, allowing some scenarios like bug #207 to be fixed;
-0.23: Better support for disabled menu items; Raises text changed event after the internals have been updated; Fix Caps-NumLock; Alt-HotKey now work on menus
-0.22: Correct vertical scrollview behavior, Small curses driver fix for terminals without mouse support, TextView support for scrolling, Surface Used property on TextField, Surface Cursor on RadioGroup.
+ 0.70: Bug fixes (320, 321, 306, 304, 291, 299, 303); Surface ListView.ListWrapper, surface various internal methods for use in ListView; Allow list item selection; ; 0.65: Added new TimeField from Jörg Preiß; Fixes for Backtab by Martin Björkström; ListView now supports simple selection; Bug fixes by giladlevi, Daniel Cazzulino and Marius Ungureanu; New Application.Run of T entry point by Daniel Cazzulino; Added various View methods to bring forward, backwards and move views in the hierarchy; Switch to Portable PDBs by Daniel Cazzulino; Dims can now be compared by Daniel Cazzulino; OnMenuOpen handler by giladlevi; Various memory usage optimizations by giladlevi; FileDialog.FilePath is now a full path by Yanwei Wang; ISupportInitialize/ISupportInitializeNotification is now supported thanks to the work from Daniel Cazzulino; Support for non-modal TopLevels by Daniel Cazzulino and Adrian Alonso; 0.24: the Windows driver implements WakeUp, allowing some scenarios like bug #207 to be fixed;
+ 0.23: Better support for disabled menu items; Raises text changed event after the internals have been updated; Fix Caps-NumLock; Alt-HotKey now work on menus
+ 0.22: Correct vertical scrollview behavior, Small curses driver fix for terminals without mouse support, TextView support for scrolling, Surface Used property on TextField, Surface Cursor on RadioGroup.
-0.21: Introudce Attribute.Make to more easily create attributes, and fix a bug in the file panel.
-0.20: Expose some of the CursesDriver APIs
-0.19: PageUpDown updates (GaikwadPratik); Fixes in multi-line labels (hlfrye@gmail.com); Support Delete char in TextView (Greg Amidon); Prevent empty TextViews from crashing; Allow TextFields to be updated on the Changed event.
-0.18: Fixes hotkeys for menus (Sang Kil); Fixes RemoveAll for all containers; Allows Toplevels with no views; Fixes FileDialog layout; Prevent crash in TextView
-0.17: Unix, dynamically load ncurses library to support different configurations, and not require -dev on Linux, various bug fixes.
+ 0.21: Introudce Attribute.Make to more easily create attributes, and fix a bug in the file panel.
+ 0.20: Expose some of the CursesDriver APIs
+ 0.19: PageUpDown updates (GaikwadPratik); Fixes in multi-line labels (hlfrye@gmail.com); Support Delete char in TextView (Greg Amidon); Prevent empty TextViews from crashing; Allow TextFields to be updated on the Changed event.
+ 0.18: Fixes hotkeys for menus (Sang Kil); Fixes RemoveAll for all containers; Allows Toplevels with no views; Fixes FileDialog layout; Prevent crash in TextView
+ 0.17: Unix, dynamically load ncurses library to support different configurations, and not require -dev on Linux, various bug fixes.
-0.16: Support for Shift-Tab on Windows (fix by @mholo65)
+ 0.16: Support for Shift-Tab on Windows (fix by @mholo65)
-0.15: WindowsDriver fix for Legacy Console keyboard input (issue #105)
+ 0.15: WindowsDriver fix for Legacy Console keyboard input (issue #105)
-0.14: WindowsDriver fix for EventType size.
+ 0.14: WindowsDriver fix for EventType size.
-0.13: Fixes keyboard input for Alt-Gr and numbers.
+ 0.13: Fixes keyboard input for Alt-Gr and numbers.
-0.12: Fixes the text editor merge line command.
+ 0.12: Fixes the text editor merge line command.
-0.11: Simplify TextField implementation, fixes a couple of editing bugs.
+ 0.11: Simplify TextField implementation, fixes a couple of editing bugs.
-0.10: Fix unicode rendering for TextField, and bring F# example
+ 0.10: Fix unicode rendering for TextField, and bring F# example
-0.9: File Open/File Save dialogs, HexView, Windows Driver allows resizing, mouse events, faster (thanks to Nick Van Dyck, nickvdyck for the contribution!), smaller bug fixes,
+ 0.9: File Open/File Save dialogs, HexView, Windows Driver allows resizing, mouse events, faster (thanks to Nick Van Dyck, nickvdyck for the contribution!), smaller bug fixes,
-0.8: Completes keyboard support on Windows; Fixes delete on Windows, some layout fixes.
-0.7: terminal resizing on Linux propagates sizes with new layout system, and new features on the layout system (documented)
-0.6: new layout system, multi-line textview editor, Linux bug fix for .NET Core
-0.5: support Linux with .NET Core, Windows driver fixes.
-0.4: hotkey handling fix for RadioButtons
-0.3: Fix Windows key input to not echo characters on console, proper Fkey mapping
-0.2: Auto-detect the best console
+ 0.8: Completes keyboard support on Windows; Fixes delete on Windows, some layout fixes.
+ 0.7: terminal resizing on Linux propagates sizes with new layout system, and new features on the layout system (documented)
+ 0.6: new layout system, multi-line textview editor, Linux bug fix for .NET Core
+ 0.5: support Linux with .NET Core, Windows driver fixes.
+ 0.4: hotkey handling fix for RadioButtons
+ 0.3: Fix Windows key input to not echo characters on console, proper Fkey mapping
+ 0.2: Auto-detect the best console
+
diff --git a/Terminal.Gui/Views/Button.cs b/Terminal.Gui/Views/Button.cs
index 54298d093..eaf56b62f 100644
--- a/Terminal.Gui/Views/Button.cs
+++ b/Terminal.Gui/Views/Button.cs
@@ -55,29 +55,32 @@ namespace Terminal.Gui {
public Action Clicked;
///
- /// Initializes a new instance of based on the given text at position 0,0
+ /// Initializes a new instance of using layout.
///
///
- /// The size of the is computed based on the
- /// text length.
+ /// The width of the is computed based on the
+ /// text length. The height will always be 1.
///
/// The button's text
- /// If set, this makes the button the default button in the current view.
+ ///
+ /// If true, a special decoration is used, and the user pressing the enter key
+ /// in a will implicitly activate this button.
+ ///
public Button (ustring text, bool is_default = false) : base ()
{
CanFocus = true;
Text = text ?? string.Empty;
this.IsDefault = is_default;
int w = SetWidthHeight (text, is_default);
- Frame = new Rect (0, 0, w, 1);
+ Frame = new Rect (Frame.Location, new Size (w, 1));
}
///
- /// Initializes a new instance of at the given coordinates, based on the given text
+ /// Initializes a new instance of using layout, based on the given text
///
///
- /// The size of the is computed based on the
- /// text length.
+ /// The width of the is computed based on the
+ /// text length. The height will always be 1.
///
/// X position where the button will be shown.
/// Y position where the button will be shown.
@@ -85,17 +88,19 @@ namespace Terminal.Gui {
public Button (int x, int y, ustring text) : this (x, y, text, false) { }
///
- /// Initializes a new instance of at the given coordinates, based on the given text, and with the specified value
+ /// Initializes a new instance of using layout, based on the given text.
///
///
- /// If the value for is_default is true, a special
- /// decoration is used, and the enter key on a
- /// dialog would implicitly activate this button.
+ /// The width of the is computed based on the
+ /// text length. The height will always be 1.
///
/// X position where the button will be shown.
/// Y position where the button will be shown.
/// The button's text
- /// If set, this makes the button the default button in the current view, which means that if the user presses return on a view that does not handle return, it will be treated as if he had clicked on the button
+ ///
+ /// If true, a special decoration is used, and the user pressing the enter key
+ /// in a will implicitly activate this button.
+ ///
public Button (int x, int y, ustring text, bool is_default)
: base (new Rect (x, y, text.Length + 4 + (is_default ? 2 : 0), 1))
{
@@ -110,6 +115,7 @@ namespace Terminal.Gui {
int w = text.Length + 4 + (is_default ? 2 : 0);
Width = w;
Height = 1;
+ Frame = new Rect (Frame.Location, new Size (w, 1));
return w;
}
@@ -137,22 +143,32 @@ namespace Terminal.Gui {
else
shown_text = "[ " + text + " ]";
- hot_pos = -1;
hot_key = (Rune)0;
- int i = 0;
- foreach (Rune c in shown_text) {
- if (Rune.IsUpper (c)) {
- hot_key = c;
- hot_pos = i;
- break;
+ hot_pos = shown_text.IndexOf ('_');
+
+ if (hot_pos == -1) {
+ // Use first upper-case char
+ int i = 0;
+ foreach (Rune c in shown_text) {
+ if (Rune.IsUpper (c)) {
+ hot_key = c;
+ hot_pos = i;
+ break;
+ }
+ i++;
}
- i++;
+ } else {
+ // Use char after '_'
+ var start = shown_text [0, hot_pos];
+ shown_text = start + shown_text [hot_pos + 1, shown_text.Length];
+ hot_key = Char.ToUpper((char)shown_text [hot_pos]);
}
+
SetNeedsDisplay ();
}
///
- public override void Redraw (Rect region)
+ public override void Redraw (Rect bounds)
{
Driver.SetAttribute (HasFocus ? ColorScheme.Focus : ColorScheme.Normal);
Move (0, 0);
@@ -214,7 +230,7 @@ namespace Terminal.Gui {
}
///
- public override bool MouseEvent(MouseEvent me)
+ public override bool MouseEvent (MouseEvent me)
{
if (me.Flags == MouseFlags.Button1Clicked) {
SuperView.SetFocus (this);
diff --git a/Terminal.Gui/Views/Checkbox.cs b/Terminal.Gui/Views/Checkbox.cs
index 056846b40..57421db73 100644
--- a/Terminal.Gui/Views/Checkbox.cs
+++ b/Terminal.Gui/Views/Checkbox.cs
@@ -98,7 +98,7 @@ namespace Terminal.Gui {
}
///
- public override void Redraw (Rect region)
+ public override void Redraw (Rect bounds)
{
Driver.SetAttribute (HasFocus ? ColorScheme.Focus : ColorScheme.Normal);
Move (0, 0);
diff --git a/Terminal.Gui/Views/ComboBox.cs b/Terminal.Gui/Views/ComboBox.cs
index e5ff53dce..a89879f8d 100644
--- a/Terminal.Gui/Views/ComboBox.cs
+++ b/Terminal.Gui/Views/ComboBox.cs
@@ -58,7 +58,7 @@ namespace Terminal.Gui {
SetValue (searchset [listview.SelectedItem]);
};
- Application.Loaded += (object sender, Application.ResizedEventArgs e) => {
+ LayoutComplete += (sender, a) => {
// Determine if this view is hosted inside a dialog
for (View view = this.SuperView; view != null; view = view.SuperView) {
if (view is Dialog) {
diff --git a/Terminal.Gui/Views/FrameView.cs b/Terminal.Gui/Views/FrameView.cs
index a08646ba0..b2d44bb57 100644
--- a/Terminal.Gui/Views/FrameView.cs
+++ b/Terminal.Gui/Views/FrameView.cs
@@ -136,23 +136,20 @@ namespace Terminal.Gui {
{
var padding = 0;
Application.CurrentView = this;
- var scrRect = RectToScreen (new Rect (0, 0, Frame.Width, Frame.Height));
+ var scrRect = ViewToScreen (new Rect (0, 0, Frame.Width, Frame.Height));
if (NeedDisplay != null && !NeedDisplay.IsEmpty) {
Driver.SetAttribute (ColorScheme.Normal);
- Driver.DrawFrame (scrRect, padding, true);
+ Driver.DrawWindowFrame (scrRect, padding + 1, padding + 1, padding + 1, padding + 1, border: true, fill: true);
}
- if (Driver.Clip.IsEmpty || Driver.Clip.Contains (contentView.RectToScreen (contentView.Frame))) {
- var savedClip = ClipToBounds ();
- contentView.Redraw (contentView.Bounds);
- Driver.Clip = savedClip;
- } else {
- contentView.Redraw (contentView.Bounds);
- }
+ var savedClip = ClipToBounds ();
+ contentView.Redraw (contentView.Bounds);
+ Driver.Clip = savedClip;
+
ClearNeedsDisplay ();
Driver.SetAttribute (ColorScheme.Normal);
- Driver.DrawFrame (scrRect, padding, false);
+ Driver.DrawWindowFrame (scrRect, padding + 1, padding + 1, padding + 1, padding + 1, border: true, fill: false);
if (HasFocus)
Driver.SetAttribute (ColorScheme.HotNormal);
diff --git a/Terminal.Gui/Views/HexView.cs b/Terminal.Gui/Views/HexView.cs
index 08609731b..45ece2349 100644
--- a/Terminal.Gui/Views/HexView.cs
+++ b/Terminal.Gui/Views/HexView.cs
@@ -130,7 +130,7 @@ namespace Terminal.Gui {
}
///
- public override void Redraw (Rect region)
+ public override void Redraw (Rect bounds)
{
Attribute currentAttribute;
var current = ColorScheme.Focus;
@@ -149,7 +149,7 @@ namespace Terminal.Gui {
for (int line = 0; line < frame.Height; line++) {
var lineRect = new Rect (0, line, frame.Width, 1);
- if (!region.Contains (lineRect))
+ if (!bounds.Contains (lineRect))
continue;
Move (0, line);
diff --git a/Terminal.Gui/Views/Label.cs b/Terminal.Gui/Views/Label.cs
index b1d2a575a..af56003c2 100644
--- a/Terminal.Gui/Views/Label.cs
+++ b/Terminal.Gui/Views/Label.cs
@@ -99,6 +99,8 @@ namespace Terminal.Gui {
static ustring ClipAndJustify (ustring str, int width, TextAlignment talign)
{
+ // Get rid of any '\r' added by Windows
+ str = str.Replace ("\r", ustring.Empty);
int slen = str.RuneCount;
if (slen > width){
var uints = str.ToRunes (width);
@@ -161,7 +163,7 @@ namespace Terminal.Gui {
}
///
- public override void Redraw (Rect region)
+ public override void Redraw (Rect bounds)
{
if (recalcPending)
Recalc ();
@@ -173,7 +175,7 @@ namespace Terminal.Gui {
Clear ();
for (int line = 0; line < lines.Count; line++) {
- if (line < region.Top || line > region.Bottom)
+ if (line < bounds.Top || line > bounds.Bottom)
continue;
var str = lines [line];
int x;
diff --git a/Terminal.Gui/Views/ListView.cs b/Terminal.Gui/Views/ListView.cs
index c325485cb..44ec32f20 100644
--- a/Terminal.Gui/Views/ListView.cs
+++ b/Terminal.Gui/Views/ListView.cs
@@ -272,7 +272,7 @@ namespace Terminal.Gui {
}
///
- public override void Redraw (Rect region)
+ public override void Redraw (Rect bounds)
{
var current = ColorScheme.Focus;
Driver.SetAttribute (current);
diff --git a/Terminal.Gui/Views/Menu.cs b/Terminal.Gui/Views/Menu.cs
index 5f25cb797..5c5de6c8f 100644
--- a/Terminal.Gui/Views/Menu.cs
+++ b/Terminal.Gui/Views/Menu.cs
@@ -276,10 +276,10 @@ namespace Terminal.Gui {
return ColorScheme.Normal;
}
- public override void Redraw (Rect region)
+ public override void Redraw (Rect bounds)
{
Driver.SetAttribute (ColorScheme.Normal);
- DrawFrame (region, padding: 0, fill: true);
+ DrawFrame (bounds, padding: 0, fill: true);
for (int i = 0; i < barItems.Children.Length; i++) {
var item = barItems.Children [i];
@@ -624,7 +624,7 @@ namespace Terminal.Gui {
}
///
- public override void Redraw (Rect region)
+ public override void Redraw (Rect bounds)
{
Move (0, 0);
Driver.SetAttribute (Colors.Menu.Normal);
diff --git a/Terminal.Gui/Views/RadioGroup.cs b/Terminal.Gui/Views/RadioGroup.cs
index c86ea2259..d3cf2e659 100644
--- a/Terminal.Gui/Views/RadioGroup.cs
+++ b/Terminal.Gui/Views/RadioGroup.cs
@@ -108,7 +108,7 @@ namespace Terminal.Gui {
}
///
- public override void Redraw (Rect region)
+ public override void Redraw (Rect bounds)
{
for (int i = 0; i < radioLabels.Length; i++) {
Move (0, i);
@@ -116,7 +116,7 @@ namespace Terminal.Gui {
Driver.AddStr (i == selected ? "(o) " : "( ) ");
DrawHotString (radioLabels [i], HasFocus && i == cursor, ColorScheme);
}
- base.Redraw (region);
+ base.Redraw (bounds);
}
///
diff --git a/Terminal.Gui/Views/ScrollView.cs b/Terminal.Gui/Views/ScrollView.cs
index 0d1358784..2e9c8e74d 100644
--- a/Terminal.Gui/Views/ScrollView.cs
+++ b/Terminal.Gui/Views/ScrollView.cs
@@ -400,7 +400,6 @@ namespace Terminal.Gui {
/// This event is raised when the contents have scrolled
///
//public event Action Scrolled;
-
public override void Redraw(Rect region)
{
SetViewsNeedsDisplay ();
@@ -409,6 +408,8 @@ namespace Terminal.Gui {
var savedClip = ClipToBounds ();
contentView.Redraw (contentView.Bounds);
+ Driver.Clip = savedClip;
+
vertical.Redraw (vertical.Bounds);
horizontal.Redraw (horizontal.Bounds);
Driver.Clip = savedClip;
diff --git a/Terminal.Gui/Views/StatusBar.cs b/Terminal.Gui/Views/StatusBar.cs
index 70618f228..1fd3448d6 100644
--- a/Terminal.Gui/Views/StatusBar.cs
+++ b/Terminal.Gui/Views/StatusBar.cs
@@ -120,7 +120,7 @@ namespace Terminal.Gui {
Width = Dim.Fill ();
Height = 1;
- Application.Loaded += (sender, e) => {
+ LayoutComplete += (sender, e) => {
X = 0;
Height = 1;
#if SNAP_TO_TOP
@@ -132,7 +132,7 @@ namespace Terminal.Gui {
case StatusBarStyle.SnapToBottom:
#endif
if (Parent == null) {
- Y = e.Rows - 1;
+ Y = Driver.Rows - 1;
} else {
Y = Pos.Bottom (Parent);
}
@@ -151,7 +151,7 @@ namespace Terminal.Gui {
}
///
- public override void Redraw (Rect region)
+ public override void Redraw (Rect bounds)
{
//if (Frame.Y != Driver.Rows - 1) {
// Frame = new Rect (Frame.X, Driver.Rows - 1, Frame.Width, Frame.Height);
diff --git a/Terminal.Gui/Views/TextField.cs b/Terminal.Gui/Views/TextField.cs
index 79e3b2400..afd94d408 100644
--- a/Terminal.Gui/Views/TextField.cs
+++ b/Terminal.Gui/Views/TextField.cs
@@ -184,7 +184,7 @@ namespace Terminal.Gui {
}
///
- public override void Redraw (Rect region)
+ public override void Redraw (Rect bounds)
{
ColorScheme color = Colors.Menu;
SetSelectedStartSelectedLength ();
diff --git a/Terminal.Gui/Views/TextView.cs b/Terminal.Gui/Views/TextView.cs
index 6c5baedac..a6d782fe4 100644
--- a/Terminal.Gui/Views/TextView.cs
+++ b/Terminal.Gui/Views/TextView.cs
@@ -525,31 +525,31 @@ namespace Terminal.Gui {
}
///
- public override void Redraw (Rect region)
+ public override void Redraw (Rect bounds)
{
ColorNormal ();
- int bottom = region.Bottom;
- int right = region.Right;
- for (int row = region.Top; row < bottom; row++)
+ int bottom = bounds.Bottom;
+ int right = bounds.Right;
+ for (int row = bounds.Top; row < bottom; row++)
{
int textLine = topRow + row;
if (textLine >= model.Count)
{
ColorNormal ();
- ClearRegion (region.Left, row, region.Right, row + 1);
+ ClearRegion (bounds.Left, row, bounds.Right, row + 1);
continue;
}
var line = model.GetLine (textLine);
int lineRuneCount = line.Count;
- if (line.Count < region.Left)
+ if (line.Count < bounds.Left)
{
- ClearRegion (region.Left, row, region.Right, row + 1);
+ ClearRegion (bounds.Left, row, bounds.Right, row + 1);
continue;
}
- Move (region.Left, row);
- for (int col = region.Left; col < right; col++)
+ Move (bounds.Left, row);
+ for (int col = bounds.Left; col < right; col++)
{
var lineCol = leftColumn + col;
var rune = lineCol >= lineRuneCount ? ' ' : line [lineCol];
diff --git a/Terminal.Gui/Windows/Dialog.cs b/Terminal.Gui/Windows/Dialog.cs
index 82d696d73..1455ebacd 100644
--- a/Terminal.Gui/Windows/Dialog.cs
+++ b/Terminal.Gui/Windows/Dialog.cs
@@ -4,15 +4,15 @@
// Authors:
// Miguel de Icaza (miguel@gnome.org)
//
-
using System;
using System.Collections.Generic;
+using System.Linq;
using NStack;
namespace Terminal.Gui {
///
/// The is a that by default is centered and contains one
- /// or more . It defaults to the color scheme and has a 1 cell padding around the edges.
+ /// or more s. It defaults to the color scheme and has a 1 cell padding around the edges.
///
///
/// To run the modally, create the , and pass it to .
@@ -21,21 +21,37 @@ namespace Terminal.Gui {
///
public class Dialog : Window {
List