Merge pull request #1057 from BDisp/window-superview-redraw-fix

Fixes #1056. Window doesn't redraw his SuperView properly.
This commit is contained in:
Charlie Kindel
2020-12-27 11:31:30 -07:00
committed by GitHub
7 changed files with 104 additions and 32 deletions

View File

@@ -363,14 +363,24 @@ namespace Terminal.Gui {
internal void EnsureVisibleBounds (Toplevel top, int x, int y, out int nx, out int ny)
{
nx = Math.Max (x, 0);
nx = nx + top.Frame.Width > Driver.Cols ? Math.Max (Driver.Cols - top.Frame.Width, 0) : nx;
int l;
if (SuperView == null || SuperView is Toplevel) {
l = Driver.Cols;
} else {
l = SuperView.Frame.Width;
}
nx = nx + top.Frame.Width > l ? Math.Max (l - top.Frame.Width, 0) : nx;
SetWidth (top.Frame.Width, out int rWidth);
if (rWidth < 0 && nx >= top.Frame.X) {
nx = Math.Max (top.Frame.Right - 2, 0);
}
//System.Diagnostics.Debug.WriteLine ($"nx:{nx}, rWidth:{rWidth}");
bool m, s;
if (SuperView == null || SuperView.GetType () != typeof (Toplevel)) {
m = Application.Top.MenuBar != null;
} else {
m = ((Toplevel)SuperView).MenuBar != null;
}
int l;
if (SuperView == null || SuperView is Toplevel) {
l = m ? 1 : 0;
} else {
@@ -389,6 +399,11 @@ namespace Terminal.Gui {
}
ny = Math.Min (ny, l);
ny = ny + top.Frame.Height > l ? Math.Max (l - top.Frame.Height, m ? 1 : 0) : ny;
SetHeight (top.Frame.Height, out int rHeight);
if (rHeight < 0 && ny >= top.Frame.Y) {
ny = Math.Max (top.Frame.Bottom - 2, 0);
}
//System.Diagnostics.Debug.WriteLine ($"ny:{ny}, rHeight:{rHeight}");
}
internal void PositionToplevels ()

View File

@@ -1125,10 +1125,10 @@ namespace Terminal.Gui {
return;
}
if (focused != null) {
if (focused?.Frame.Width > 0 && focused.Frame.Height > 0) {
focused.PositionCursor ();
} else {
if (CanFocus && HasFocus && Visible) {
if (CanFocus && HasFocus && Visible && Frame.Width > 0 && Frame.Height > 0) {
Move (textFormatter.HotKeyPos == -1 ? 0 : textFormatter.CursorPosition, 0);
} else {
Move (frame.X, frame.Y);
@@ -1344,7 +1344,7 @@ namespace Terminal.Gui {
// Draw the subview
// Use the view's bounds (view-relative; Location will always be (0,0)
if (view.Visible) {
if (view.Visible && view.Frame.Width > 0 && view.Frame.Height > 0) {
view.Redraw (view.Bounds);
}
}
@@ -2144,5 +2144,65 @@ namespace Terminal.Gui {
return true;
}
/// <summary>
/// Calculate the width based on the <see cref="Width"/> settings.
/// </summary>
/// <param name="desiredWidth">The desired width.</param>
/// <param name="resultWidth">The real result width.</param>
/// <returns>True if the width can be directly assigned, false otherwise.</returns>
public bool SetWidth (int desiredWidth, out int resultWidth)
{
int w = desiredWidth;
bool canSetWidth;
if (Width is Dim.DimCombine || Width is Dim.DimView || Width is Dim.DimFill) {
// It's a Dim.DimCombine and so can't be assigned. Let it have it's width anchored.
w = Width.Anchor (w);
canSetWidth = false;
} else if (Width is Dim.DimFactor factor) {
// Tries to get the SuperView width otherwise the view width.
var sw = SuperView != null ? SuperView.Frame.Width : w;
if (factor.IsFromRemaining ()) {
sw -= Frame.X;
}
w = Width.Anchor (sw);
canSetWidth = false;
} else {
canSetWidth = true;
}
resultWidth = w;
return canSetWidth;
}
/// <summary>
/// Calculate the height based on the <see cref="Height"/> settings.
/// </summary>
/// <param name="desiredHeight">The desired height.</param>
/// <param name="resultHeight">The real result height.</param>
/// <returns>True if the height can be directly assigned, false otherwise.</returns>
public bool SetHeight (int desiredHeight, out int resultHeight)
{
int h = desiredHeight;
bool canSetHeight;
if (Height is Dim.DimCombine || Height is Dim.DimView || Height is Dim.DimFill) {
// It's a Dim.DimCombine and so can't be assigned. Let it have it's height anchored.
h = Height.Anchor (h);
canSetHeight = false;
} else if (Height is Dim.DimFactor factor) {
// Tries to get the SuperView height otherwise the view height.
var sh = SuperView != null ? SuperView.Frame.Height : h;
if (factor.IsFromRemaining ()) {
sh -= Frame.Y;
}
h = Height.Anchor (sh);
canSetHeight = false;
} else {
canSetHeight = true;
}
resultHeight = h;
return canSetHeight;
}
}
}

View File

@@ -196,12 +196,8 @@ namespace Terminal.Gui {
// Checks if there are any SuperView view which intersect with this window.
if (SuperView != null) {
foreach (var view in SuperView.Subviews) {
if (view != this && view.Frame.IntersectsWith (Bounds)) {
view.SetNeedsLayout ();
view.SetNeedsDisplay (view.Bounds);
}
}
SuperView.SetNeedsLayout ();
SuperView.SetNeedsDisplay ();
}
}
@@ -231,7 +227,7 @@ namespace Terminal.Gui {
Application.GrabMouse (this);
}
//Demo.ml2.Text = $"Starting at {dragPosition}";
//System.Diagnostics.Debug.WriteLine ($"Starting at {dragPosition}");
return true;
} else if (mouseEvent.Flags == (MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition) ||
mouseEvent.Flags == MouseFlags.Button3Pressed) {
@@ -249,10 +245,11 @@ namespace Terminal.Gui {
mouseEvent.Y + (SuperView == null ? mouseEvent.OfY : Frame.Y), out nx, out ny);
dragPosition = new Point (nx, ny);
LayoutSubviews ();
Frame = new Rect (nx, ny, Frame.Width, Frame.Height);
X = nx;
Y = ny;
//Demo.ml2.Text = $"{dx},{dy}";
//System.Diagnostics.Debug.WriteLine ($"nx:{nx},ny:{ny}");
// FIXED: optimize, only SetNeedsDisplay on the before/after regions.
SetNeedsDisplay ();
@@ -266,7 +263,7 @@ namespace Terminal.Gui {
dragPosition = null;
}
//Demo.ml.Text = me.ToString ();
//System.Diagnostics.Debug.WriteLine (mouseEvent.ToString ());
return false;
}

View File

@@ -146,19 +146,10 @@ namespace Terminal.Gui {
base.Text = ustring.Make (_leftBracket) + " " + text + " " + ustring.Make (_rightBracket);
int w = base.Text.RuneCount - (base.Text.Contains (HotKeySpecifier) ? 1 : 0);
if (Width is Dim.DimCombine || Width is Dim.DimView || Width is Dim.DimFill) {
// It's a Dim.DimCombine and so can't be assigned. Let it have it's width anchored.
w = Width.Anchor (w);
} else if (Width is Dim.DimFactor) {
// Tries to get the SuperView width otherwise the button width.
var sw = SuperView != null ? SuperView.Frame.Width : w;
if (((Dim.DimFactor)Width).IsFromRemaining ()) {
sw -= Frame.X;
}
w = Width.Anchor (sw);
} else {
Width = w;
if (SetWidth (w, out int rWidth)) {
Width = rWidth;
}
w = rWidth;
var layout = LayoutStyle;
bool layoutChanged = false;
if (!(Height is Dim.DimAbsolute)) {

View File

@@ -927,6 +927,9 @@ namespace Terminal.Gui {
///<inheritdoc/>
public override void PositionCursor ()
{
if (selected == -1 && HasFocus && Menus.Length > 0) {
selected = 0;
}
int pos = 0;
for (int i = 0; i < Menus.Length; i++) {
if (i == selected) {

View File

@@ -32,7 +32,7 @@ namespace UICatalog {
//Win.Y = 2;
//Win.Width = Dim.Fill () - 4;
//Win.Height = Dim.Fill () - 2;
var label = new Label ("ScrollView (new Rect (5, 5, 100, 60)) with a 200, 100 ContentSize...") {
var label = new Label ("ScrollView (new Rect (3, 3, 50, 20)) with a 200, 100 ContentSize...") {
X = 0, Y = 0,
//ColorScheme = Colors.Dialog
};
@@ -40,10 +40,10 @@ namespace UICatalog {
var scrollView = new ScrollView (new Rect (3, 3, 50, 20));
scrollView.ColorScheme = Colors.Menu;
scrollView.ContentSize = new Size (100, 60);
scrollView.ContentSize = new Size (200, 100);
//ContentOffset = new Point (0, 0),
scrollView.ShowVerticalScrollIndicator = true;
scrollView.ShowHorizontalScrollIndicator = true;
//scrollView.ShowVerticalScrollIndicator = true;
//scrollView.ShowHorizontalScrollIndicator = true;
var embedded1 = new Window ("1") {
X = 3,
@@ -78,7 +78,7 @@ namespace UICatalog {
embedded2.Add (embedded3);
scrollView.Add (embedded1);
Top.Add (scrollView);
}
}

View File

@@ -92,7 +92,13 @@ namespace UICatalog {
_btnQuit.Clicked += Application.RequestStop;
Win.Add (_itemsList, _btnActionCancel, _logJob, text, _btnAction, _btnLambda, _btnHandler, _btnSync, _btnMethod, _btnClearData, _btnQuit);
_btnActionCancel.SetFocus ();
void Top_Loaded ()
{
_btnActionCancel.SetFocus ();
Top.Loaded -= Top_Loaded;
}
Top.Loaded += Top_Loaded;
}
private async void LoadData ()