|
@@ -118,7 +118,7 @@ namespace Terminal.Gui {
|
|
/// in color as well as black and white displays.
|
|
/// in color as well as black and white displays.
|
|
/// </para>
|
|
/// </para>
|
|
/// <para>
|
|
/// <para>
|
|
- /// Views that are focusable should implement the <see cref="PositionCursor"/> to make sure that
|
|
|
|
|
|
+ /// Views that are focusable should implement the <see cref="PositionCursor ()"/> to make sure that
|
|
/// the cursor is placed in a location that makes sense. Unix terminals do not have
|
|
/// 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
|
|
/// 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
|
|
/// the last focused view. So views should make sure that they place the cursor
|
|
@@ -667,7 +667,8 @@ namespace Terminal.Gui {
|
|
/// <param name="rcol">Absolute column; screen-relative.</param>
|
|
/// <param name="rcol">Absolute column; screen-relative.</param>
|
|
/// <param name="rrow">Absolute row; screen-relative.</param>
|
|
/// <param name="rrow">Absolute row; screen-relative.</param>
|
|
/// <param name="clipped">Whether to clip the result of the ViewToScreen method, if set to <c>true</c>, the rcol, rrow values are clamped to the screen (terminal) dimensions (0..TerminalDim-1).</param>
|
|
/// <param name="clipped">Whether to clip the result of the ViewToScreen method, if set to <c>true</c>, the rcol, rrow values are clamped to the screen (terminal) dimensions (0..TerminalDim-1).</param>
|
|
- internal void ViewToScreen (int col, int row, out int rcol, out int rrow, bool clipped = true)
|
|
|
|
|
|
+ /// <param name="force">If <true/>force negative coordinates <false/>otherwise.</param>
|
|
|
|
+ internal void ViewToScreen (int col, int row, out int rcol, out int rrow, bool clipped = true, bool force = true)
|
|
{
|
|
{
|
|
// Computes the real row, col relative to the screen.
|
|
// Computes the real row, col relative to the screen.
|
|
rrow = row + frame.Y;
|
|
rrow = row + frame.Y;
|
|
@@ -680,10 +681,14 @@ namespace Terminal.Gui {
|
|
}
|
|
}
|
|
|
|
|
|
// The following ensures that the cursor is always in the screen boundaries.
|
|
// The following ensures that the cursor is always in the screen boundaries.
|
|
- if (clipped) {
|
|
|
|
|
|
+ if (clipped && !force) {
|
|
rrow = Math.Max (0, Math.Min (rrow, Driver.Rows - 1));
|
|
rrow = Math.Max (0, Math.Min (rrow, Driver.Rows - 1));
|
|
rcol = Math.Max (0, Math.Min (rcol, Driver.Cols - 1));
|
|
rcol = Math.Max (0, Math.Min (rcol, Driver.Cols - 1));
|
|
}
|
|
}
|
|
|
|
+ if (clipped && force) {
|
|
|
|
+ rrow = Math.Min (rrow, Driver.Rows - 1);
|
|
|
|
+ rcol = Math.Min (rcol, Driver.Cols - 1);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// <summary>
|
|
@@ -799,18 +804,31 @@ namespace Terminal.Gui {
|
|
/// This moves the cursor to the specified column and row in the view.
|
|
/// This moves the cursor to the specified column and row in the view.
|
|
/// </summary>
|
|
/// </summary>
|
|
/// <returns>The move.</returns>
|
|
/// <returns>The move.</returns>
|
|
- /// <param name="col">Col (view-relative).</param>
|
|
|
|
- /// <param name="row">Row (view-relative).</param>
|
|
|
|
- public void Move (int col, int row)
|
|
|
|
|
|
+ /// <param name="col">Col.</param>
|
|
|
|
+ /// <param name="row">Row.</param>
|
|
|
|
+ /// <param name="force">If <true/>force move <false/>otherwise.</param>
|
|
|
|
+ public void Move (int col, int row, bool force = true)
|
|
{
|
|
{
|
|
- ViewToScreen (col, row, out var rcol, out var rrow);
|
|
|
|
|
|
+ int c = 0, r = 0;
|
|
|
|
+
|
|
|
|
+ if (!force && SuperView != null) {
|
|
|
|
+ if (col == 0)
|
|
|
|
+ c = SuperView.Frame.X;
|
|
|
|
+ if (row == 0)
|
|
|
|
+ r = SuperView.Frame.Y;
|
|
|
|
+ } else if (SuperView != null) {
|
|
|
|
+ c = col;
|
|
|
|
+ r = row;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ViewToScreen (c, r, out var rcol, out var rrow, force);
|
|
Driver.Move (rcol, rrow);
|
|
Driver.Move (rcol, rrow);
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// <summary>
|
|
/// Positions the cursor in the right position based on the currently focused view in the chain.
|
|
/// Positions the cursor in the right position based on the currently focused view in the chain.
|
|
/// </summary>
|
|
/// </summary>
|
|
- /// Views that are focusable should override <see cref="PositionCursor"/> to ensure
|
|
|
|
|
|
+ /// Views that are focusable should override <see cref="PositionCursor ()"/> to ensure
|
|
/// the cursor is placed in a location that makes sense. Unix terminals do not have
|
|
/// 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
|
|
/// 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
|
|
/// the last focused view. Views should make sure that they place the cursor
|
|
@@ -823,6 +841,23 @@ namespace Terminal.Gui {
|
|
Move (frame.X, frame.Y);
|
|
Move (frame.X, frame.Y);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /// <summary>
|
|
|
|
+ /// Positions the cursor in the right position based on the currently focused view in the chain.
|
|
|
|
+ /// </summary>
|
|
|
|
+ /// <param name="force">If <true/>force move <false/>otherwise.</param>
|
|
|
|
+ /// Views that are focusable should override <see cref="PositionCursor (bool)"/> 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 (bool force = true)
|
|
|
|
+ {
|
|
|
|
+ if (focused != null)
|
|
|
|
+ focused.PositionCursor (force);
|
|
|
|
+ else
|
|
|
|
+ Move (frame.X, frame.Y, force);
|
|
|
|
+ }
|
|
|
|
+
|
|
/// <inheritdoc/>
|
|
/// <inheritdoc/>
|
|
public override bool HasFocus {
|
|
public override bool HasFocus {
|
|
get {
|
|
get {
|
|
@@ -977,7 +1012,7 @@ namespace Terminal.Gui {
|
|
if (subviews != null) {
|
|
if (subviews != null) {
|
|
foreach (var view in subviews) {
|
|
foreach (var view in subviews) {
|
|
if (view.NeedDisplay != null && (!view.NeedDisplay.IsEmpty || view.childNeedsDisplay)) {
|
|
if (view.NeedDisplay != null && (!view.NeedDisplay.IsEmpty || view.childNeedsDisplay)) {
|
|
- if (view.Frame.IntersectsWith (clipRect) && view.Frame.IntersectsWith (bounds)) {
|
|
|
|
|
|
+ if (view.Frame.IntersectsWith (clipRect) && (view.Frame.IntersectsWith (bounds) || bounds.X < 0 || bounds.Y < 0)) {
|
|
|
|
|
|
// FIXED: optimize this by computing the intersection of region and view.Bounds
|
|
// FIXED: optimize this by computing the intersection of region and view.Bounds
|
|
if (view.layoutNeeded)
|
|
if (view.layoutNeeded)
|