mirror of
https://github.com/gui-cs/Terminal.Gui.git
synced 2025-12-30 09:47:58 +01:00
Fixes #2503. PosCombine and DimCombine is wrongly looking into the from.InternalSubviews.
This commit is contained in:
@@ -1395,7 +1395,8 @@ namespace Terminal.Gui {
|
||||
public Point ScreenToBounds (int x, int y)
|
||||
{
|
||||
if (SuperView == null) {
|
||||
return new Point (x - Frame.X + GetBoundsOffset ().X, y - Frame.Y + GetBoundsOffset ().Y);
|
||||
var boundsOffset = GetBoundsOffset ();
|
||||
return new Point (x - Frame.X + boundsOffset.X, y - Frame.Y + boundsOffset.Y);
|
||||
} else {
|
||||
var parent = SuperView.ScreenToView (x, y);
|
||||
return new Point (parent.X - frame.X, parent.Y - frame.Y);
|
||||
@@ -1414,13 +1415,15 @@ namespace Terminal.Gui {
|
||||
/// <see cref="ConsoleDriver.Rows"/>, respectively.</param>
|
||||
public virtual void ViewToScreen (int col, int row, out int rcol, out int rrow, bool clamped = true)
|
||||
{
|
||||
rcol = col + Frame.X + GetBoundsOffset ().X;
|
||||
rrow = row + Frame.Y + GetBoundsOffset ().Y;
|
||||
var boundsOffset = GetBoundsOffset ();
|
||||
rcol = col + Frame.X + boundsOffset.X;
|
||||
rrow = row + Frame.Y + boundsOffset.Y;
|
||||
|
||||
var super = SuperView;
|
||||
while (super != null) {
|
||||
rcol += super.Frame.X + super.GetBoundsOffset ().X;
|
||||
rrow += super.Frame.Y + super.GetBoundsOffset ().Y;
|
||||
boundsOffset = super.GetBoundsOffset ();
|
||||
rcol += super.Frame.X + boundsOffset.X;
|
||||
rrow += super.Frame.Y + boundsOffset.Y;
|
||||
super = super.SuperView;
|
||||
}
|
||||
|
||||
@@ -2577,10 +2580,8 @@ namespace Terminal.Gui {
|
||||
}
|
||||
return;
|
||||
case Pos.PosCombine pc:
|
||||
foreach (var v in from.InternalSubviews) {
|
||||
CollectPos (pc.left, from, ref nNodes, ref nEdges);
|
||||
CollectPos (pc.right, from, ref nNodes, ref nEdges);
|
||||
}
|
||||
CollectPos (pc.left, from, ref nNodes, ref nEdges);
|
||||
CollectPos (pc.right, from, ref nNodes, ref nEdges);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -2601,10 +2602,8 @@ namespace Terminal.Gui {
|
||||
}
|
||||
return;
|
||||
case Dim.DimCombine dc:
|
||||
foreach (var v in from.InternalSubviews) {
|
||||
CollectDim (dc.left, from, ref nNodes, ref nEdges);
|
||||
CollectDim (dc.right, from, ref nNodes, ref nEdges);
|
||||
}
|
||||
CollectDim (dc.left, from, ref nNodes, ref nEdges);
|
||||
CollectDim (dc.right, from, ref nNodes, ref nEdges);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -2658,15 +2657,11 @@ namespace Terminal.Gui {
|
||||
|
||||
if (edges.Any ()) {
|
||||
(var from, var to) = edges.First ();
|
||||
if (from != superView?.GetTopSuperView (to, from)) {
|
||||
if (!ReferenceEquals (from, to)) {
|
||||
if (ReferenceEquals (from.SuperView, to)) {
|
||||
throw new InvalidOperationException ($"ComputedLayout for \"{superView}\": \"{to}\" references a SubView (\"{from}\").");
|
||||
} else {
|
||||
throw new InvalidOperationException ($"ComputedLayout for \"{superView}\": \"{from}\" linked with \"{to}\" was not found. Did you forget to add it to {superView}?");
|
||||
}
|
||||
if (from != superView?.GetTopSuperView (to, from) && !ReferenceEquals (from, to)) {
|
||||
if (ReferenceEquals (from.SuperView, to)) {
|
||||
throw new InvalidOperationException ($"ComputedLayout for \"{superView}\": \"{to}\" references a SubView (\"{from}\").");
|
||||
} else {
|
||||
throw new InvalidOperationException ($"ComputedLayout for \"{superView}\": A recursive cycle was found in the relative Pos/Dim of the SubViews.");
|
||||
throw new InvalidOperationException ($"ComputedLayout for \"{superView}\": \"{from}\" linked with \"{to}\" was not found. Did you forget to add it to {superView}?");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3508,8 +3503,9 @@ namespace Terminal.Gui {
|
||||
if (start.InternalSubviews != null) {
|
||||
int count = start.InternalSubviews.Count;
|
||||
if (count > 0) {
|
||||
var rx = x - (startFrame.X + start.GetBoundsOffset ().X);
|
||||
var ry = y - (startFrame.Y + start.GetBoundsOffset ().Y);
|
||||
var boundsOffset = start.GetBoundsOffset ();
|
||||
var rx = x - (startFrame.X + boundsOffset.X);
|
||||
var ry = y - (startFrame.Y + boundsOffset.Y);
|
||||
for (int i = count - 1; i >= 0; i--) {
|
||||
View v = start.InternalSubviews [i];
|
||||
if (v.Visible && v.Frame.Contains (rx, ry)) {
|
||||
|
||||
@@ -1266,5 +1266,49 @@ namespace Terminal.Gui.ViewTests {
|
||||
Assert.Equal (51, label.Frame.Height);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Dim_Referencing_SuperView_Throws ()
|
||||
{
|
||||
var super = new View ("super") {
|
||||
Width = 10,
|
||||
Height = 10
|
||||
};
|
||||
var view = new View ("view") {
|
||||
Width = Dim.Width (super), // this is allowed
|
||||
Height = Dim.Height (super), // this is allowed
|
||||
};
|
||||
|
||||
super.Add (view);
|
||||
super.BeginInit ();
|
||||
super.EndInit ();
|
||||
|
||||
var exception = Record.Exception (super.LayoutSubviews);
|
||||
Assert.Null (exception);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Dim_SyperView_Referencing_SubView_Does_Not_Throws ()
|
||||
{
|
||||
var super = new View ("super") {
|
||||
Width = 10,
|
||||
Height = 10
|
||||
};
|
||||
var view2 = new View ("view2") {
|
||||
Width = 10,
|
||||
Height = 10,
|
||||
};
|
||||
var view = new View ("view") {
|
||||
Width = Dim.Width (view2), // this is not allowed
|
||||
Height = Dim.Height (view2), // this is not allowed
|
||||
};
|
||||
|
||||
view.Add (view2);
|
||||
super.Add (view);
|
||||
super.BeginInit ();
|
||||
super.EndInit ();
|
||||
|
||||
Assert.Throws<InvalidOperationException> (super.LayoutSubviews);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +43,9 @@ namespace Terminal.Gui.ViewTests {
|
||||
var sub2 = new View ();
|
||||
root.Add (sub2);
|
||||
sub2.Width = Dim.Width (sub2);
|
||||
Assert.Throws<InvalidOperationException> (() => root.LayoutSubviews ());
|
||||
|
||||
var exception = Record.Exception (root.LayoutSubviews);
|
||||
Assert.Null (exception);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -1693,7 +1695,7 @@ Y
|
||||
|
||||
switch (width) {
|
||||
case 1:
|
||||
//Assert.Equal (new Rect (0, 0, 17, 0), subview.Frame);
|
||||
Assert.Equal (new Rect (0, 0, 0, 4), subview.Frame);
|
||||
expected = @"
|
||||
│
|
||||
│
|
||||
@@ -1704,7 +1706,7 @@ Y
|
||||
│";
|
||||
break;
|
||||
case 2:
|
||||
//Assert.Equal (new Rect (0, 0, 17, 1), subview.Frame);
|
||||
Assert.Equal (new Rect (0, 0, 0, 4), subview.Frame);
|
||||
expected = @"
|
||||
┌┐
|
||||
││
|
||||
@@ -1715,7 +1717,7 @@ Y
|
||||
└┘";
|
||||
break;
|
||||
case 3:
|
||||
//Assert.Equal (new Rect (0, 0, 17, 2), subview.Frame);
|
||||
Assert.Equal (new Rect (0, 0, 0, 4), subview.Frame);
|
||||
expected = @"
|
||||
┌─┐
|
||||
│ │
|
||||
@@ -1727,7 +1729,7 @@ Y
|
||||
";
|
||||
break;
|
||||
case 4:
|
||||
//Assert.Equal (new Rect (0, 0, 17, 3), subview.Frame);
|
||||
Assert.Equal (new Rect (0, 0, 1, 4), subview.Frame);
|
||||
expected = @"
|
||||
┌──┐
|
||||
││ │
|
||||
@@ -1738,7 +1740,7 @@ Y
|
||||
└──┘";
|
||||
break;
|
||||
case 5:
|
||||
//Assert.Equal (new Rect (0, 0, 17, 3), subview.Frame);
|
||||
Assert.Equal (new Rect (0, 0, 2, 4), subview.Frame);
|
||||
expected = @"
|
||||
┌───┐
|
||||
│┌┐ │
|
||||
@@ -1749,7 +1751,7 @@ Y
|
||||
└───┘";
|
||||
break;
|
||||
case 6:
|
||||
//Assert.Equal (new Rect (0, 0, 17, 3), subview.Frame);
|
||||
Assert.Equal (new Rect (0, 0, 3, 4), subview.Frame);
|
||||
expected = @"
|
||||
┌────┐
|
||||
│┌─┐ │
|
||||
@@ -1760,7 +1762,7 @@ Y
|
||||
└────┘";
|
||||
break;
|
||||
case 7:
|
||||
//Assert.Equal (new Rect (0, 0, 17, 3), subview.Frame);
|
||||
Assert.Equal (new Rect (0, 0, 4, 4), subview.Frame);
|
||||
expected = @"
|
||||
┌─────┐
|
||||
│┌──┐ │
|
||||
@@ -1771,7 +1773,7 @@ Y
|
||||
└─────┘";
|
||||
break;
|
||||
case 8:
|
||||
//Assert.Equal (new Rect (0, 0, 17, 3), subview.Frame);
|
||||
Assert.Equal (new Rect (0, 0, 5, 4), subview.Frame);
|
||||
expected = @"
|
||||
┌──────┐
|
||||
│┌───┐ │
|
||||
@@ -1782,7 +1784,7 @@ Y
|
||||
└──────┘";
|
||||
break;
|
||||
case 9:
|
||||
//Assert.Equal (new Rect (0, 0, 17, 3), subview.Frame);
|
||||
Assert.Equal (new Rect (1, 0, 5, 4), subview.Frame);
|
||||
expected = @"
|
||||
┌───────┐
|
||||
│ ┌───┐ │
|
||||
@@ -1793,7 +1795,7 @@ Y
|
||||
└───────┘";
|
||||
break;
|
||||
case 10:
|
||||
//Assert.Equal (new Rect (0, 0, 17, 3), subview.Frame);
|
||||
Assert.Equal (new Rect (1, 0, 6, 4), subview.Frame);
|
||||
expected = @"
|
||||
┌────────┐
|
||||
│ ┌────┐ │
|
||||
@@ -1805,7 +1807,57 @@ Y
|
||||
break;
|
||||
}
|
||||
_ = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
|
||||
}
|
||||
|
||||
[Fact, AutoInitShutdown]
|
||||
public void PosConbine_DimCombine_View_With_SubViews ()
|
||||
{
|
||||
var clicked = false;
|
||||
var top = Application.Top;
|
||||
var win1 = new Window () { Id = "win1", Width = 20, Height = 10 };
|
||||
var btn = new Button ("ok");
|
||||
var win2 = new Window () { Id = "win2", Y = Pos.Bottom (btn) + 1, Width = 10, Height = 3 };
|
||||
var view1 = new View () { Id = "view1", Width = Dim.Fill (), Height = 1, CanFocus = true };
|
||||
view1.MouseClick += (sender, e) => clicked = true;
|
||||
var view2 = new View () { Id = "view2", Width = Dim.Fill (1), Height = 1, CanFocus = true };
|
||||
|
||||
view1.Add (view2);
|
||||
win2.Add (view1);
|
||||
win1.Add (btn, win2);
|
||||
top.Add (win1);
|
||||
|
||||
var rs = Application.Begin (top);
|
||||
|
||||
TestHelpers.AssertDriverContentsWithFrameAre (@"
|
||||
┌──────────────────┐
|
||||
│[ ok ] │
|
||||
│ │
|
||||
│┌────────┐ │
|
||||
││ │ │
|
||||
│└────────┘ │
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
└──────────────────┘", output);
|
||||
Assert.Equal (new Rect (0, 0, 80, 25), top.Frame);
|
||||
Assert.Equal (new Rect (0, 0, 6, 1), btn.Frame);
|
||||
Assert.Equal (new Rect (0, 0, 20, 10), win1.Frame);
|
||||
Assert.Equal (new Rect (0, 2, 10, 3), win2.Frame);
|
||||
Assert.Equal (new Rect (0, 0, 8, 1), view1.Frame);
|
||||
Assert.Equal (new Rect (0, 0, 7, 1), view2.Frame);
|
||||
var foundView = View.FindDeepestView (top, 9, 4, out int rx, out int ry);
|
||||
Assert.Equal (foundView, view1);
|
||||
ReflectionTools.InvokePrivate (
|
||||
typeof (Application),
|
||||
"ProcessMouseEvent",
|
||||
new MouseEvent () {
|
||||
X = 9,
|
||||
Y = 4,
|
||||
Flags = MouseFlags.Button1Clicked
|
||||
});
|
||||
Assert.True (clicked);
|
||||
|
||||
Application.End (rs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user