mirror of
https://github.com/gui-cs/Terminal.Gui.git
synced 2026-01-02 01:03:29 +01:00
Fixes 2142. Dim.Combine wasn't calculating well.
This commit is contained in:
@@ -593,7 +593,7 @@ namespace Terminal.Gui {
|
||||
|
||||
internal class DimCombine : Dim {
|
||||
internal Dim left, right;
|
||||
bool add;
|
||||
internal bool add;
|
||||
public DimCombine (bool add, Dim left, Dim right)
|
||||
{
|
||||
this.left = left;
|
||||
|
||||
@@ -348,7 +348,7 @@ namespace Terminal.Gui {
|
||||
}
|
||||
if (base.CanFocus != value) {
|
||||
base.CanFocus = value;
|
||||
|
||||
|
||||
switch (value) {
|
||||
case false when tabIndex > -1:
|
||||
TabIndex = -1;
|
||||
@@ -357,7 +357,7 @@ namespace Terminal.Gui {
|
||||
SuperView.CanFocus = true;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (value && tabIndex == -1) {
|
||||
TabIndex = SuperView != null ? SuperView.tabIndexes.IndexOf (this) : -1;
|
||||
}
|
||||
@@ -881,10 +881,10 @@ namespace Terminal.Gui {
|
||||
NeedDisplay = new Rect (x, y, w, h);
|
||||
}
|
||||
container?.SetChildNeedsDisplay ();
|
||||
|
||||
|
||||
if (subviews == null)
|
||||
return;
|
||||
|
||||
|
||||
foreach (var view in subviews)
|
||||
if (view.Frame.IntersectsWith (region)) {
|
||||
var childRegion = Rect.Intersect (view.Frame, region);
|
||||
@@ -1132,7 +1132,7 @@ namespace Terminal.Gui {
|
||||
// Computes the real row, col relative to the screen.
|
||||
rrow = row + frame.Y;
|
||||
rcol = col + frame.X;
|
||||
|
||||
|
||||
var curContainer = container;
|
||||
while (curContainer != null) {
|
||||
rrow += curContainer.frame.Y;
|
||||
@@ -1303,7 +1303,7 @@ namespace Terminal.Gui {
|
||||
}
|
||||
|
||||
bool hasFocus;
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override bool HasFocus => hasFocus;
|
||||
|
||||
@@ -1694,7 +1694,7 @@ namespace Terminal.Gui {
|
||||
if (args.Handled)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
return Focused?.Enabled == true && Focused?.ProcessKey (keyEvent) == true;
|
||||
}
|
||||
|
||||
@@ -1870,7 +1870,7 @@ namespace Terminal.Gui {
|
||||
return true;
|
||||
if (subviews == null || subviews.Count == 0)
|
||||
return false;
|
||||
|
||||
|
||||
foreach (var view in subviews)
|
||||
if (view.Enabled && view.ProcessHotKey (keyEvent))
|
||||
return true;
|
||||
@@ -1897,7 +1897,7 @@ namespace Terminal.Gui {
|
||||
return true;
|
||||
if (subviews == null || subviews.Count == 0)
|
||||
return false;
|
||||
|
||||
|
||||
foreach (var view in subviews)
|
||||
if (view.Enabled && view.ProcessColdKey (keyEvent))
|
||||
return true;
|
||||
@@ -2043,7 +2043,7 @@ namespace Terminal.Gui {
|
||||
FocusLast ();
|
||||
return focused != null;
|
||||
}
|
||||
|
||||
|
||||
var focusedIdx = -1;
|
||||
for (var i = tabIndexes.Count; i > 0;) {
|
||||
i--;
|
||||
@@ -2153,20 +2153,8 @@ namespace Terminal.Gui {
|
||||
actX = x.Anchor (hostFrame.Width - actW);
|
||||
} else {
|
||||
actX = x?.Anchor (hostFrame.Width) ?? 0;
|
||||
|
||||
switch (width) {
|
||||
case null:
|
||||
actW = AutoSize ? s.Width : hostFrame.Width;
|
||||
break;
|
||||
case Dim.DimFactor factor when !factor.IsFromRemaining ():
|
||||
actW = width.Anchor (hostFrame.Width);
|
||||
actW = AutoSize && s.Width > actW ? s.Width : actW;
|
||||
break;
|
||||
default:
|
||||
actW = Math.Max (width.Anchor (hostFrame.Width - actX), 0);
|
||||
actW = AutoSize && s.Width > actW ? s.Width : actW;
|
||||
break;
|
||||
}
|
||||
|
||||
actW = Math.Max (CalculateActualWidth (width, hostFrame, actX, s), 0);
|
||||
}
|
||||
|
||||
if (y is Pos.PosCenter) {
|
||||
@@ -2179,22 +2167,10 @@ namespace Terminal.Gui {
|
||||
actY = y.Anchor (hostFrame.Height - actH);
|
||||
} else {
|
||||
actY = y?.Anchor (hostFrame.Height) ?? 0;
|
||||
|
||||
switch (height) {
|
||||
case null:
|
||||
actH = AutoSize ? s.Height : hostFrame.Height;
|
||||
break;
|
||||
case Dim.DimFactor factor when !factor.IsFromRemaining ():
|
||||
actH = height.Anchor (hostFrame.Height);
|
||||
actH = AutoSize && s.Height > actH ? s.Height : actH;
|
||||
break;
|
||||
default:
|
||||
actH = Math.Max (height.Anchor (hostFrame.Height - actY), 0);
|
||||
actH = AutoSize && s.Height > actH ? s.Height : actH;
|
||||
break;
|
||||
}
|
||||
|
||||
actH = Math.Max (CalculateActualHight (height, hostFrame, actY, s), 0);
|
||||
}
|
||||
|
||||
|
||||
var r = new Rect (actX, actY, actW, actH);
|
||||
if (Frame != r) {
|
||||
Frame = new Rect (actX, actY, actW, actH);
|
||||
@@ -2203,6 +2179,66 @@ namespace Terminal.Gui {
|
||||
}
|
||||
}
|
||||
|
||||
private int CalculateActualWidth (Dim width, Rect hostFrame, int actX, Size s)
|
||||
{
|
||||
int actW;
|
||||
switch (width) {
|
||||
case null:
|
||||
actW = AutoSize ? s.Width : hostFrame.Width;
|
||||
break;
|
||||
case Dim.DimCombine combine:
|
||||
int leftActW = CalculateActualWidth (combine.left, hostFrame, actX, s);
|
||||
int rightActW = CalculateActualWidth (combine.right, hostFrame, actX, s);
|
||||
if (combine.add) {
|
||||
actW = leftActW + rightActW;
|
||||
} else {
|
||||
actW = leftActW - rightActW;
|
||||
}
|
||||
actW = AutoSize && s.Width > actW ? s.Width : actW;
|
||||
break;
|
||||
case Dim.DimFactor factor when !factor.IsFromRemaining ():
|
||||
actW = width.Anchor (hostFrame.Width);
|
||||
actW = AutoSize && s.Width > actW ? s.Width : actW;
|
||||
break;
|
||||
default:
|
||||
actW = Math.Max (width.Anchor (hostFrame.Width - actX), 0);
|
||||
actW = AutoSize && s.Width > actW ? s.Width : actW;
|
||||
break;
|
||||
}
|
||||
|
||||
return actW;
|
||||
}
|
||||
|
||||
private int CalculateActualHight (Dim height, Rect hostFrame, int actY, Size s)
|
||||
{
|
||||
int actH;
|
||||
switch (height) {
|
||||
case null:
|
||||
actH = AutoSize ? s.Height : hostFrame.Height;
|
||||
break;
|
||||
case Dim.DimCombine combine:
|
||||
int leftActH = CalculateActualHight (combine.left, hostFrame, actY, s);
|
||||
int rightActH = CalculateActualHight (combine.right, hostFrame, actY, s);
|
||||
if (combine.add) {
|
||||
actH = leftActH + rightActH;
|
||||
} else {
|
||||
actH = leftActH - rightActH;
|
||||
}
|
||||
actH = AutoSize && s.Height > actH ? s.Height : actH;
|
||||
break;
|
||||
case Dim.DimFactor factor when !factor.IsFromRemaining ():
|
||||
actH = height.Anchor (hostFrame.Height);
|
||||
actH = AutoSize && s.Height > actH ? s.Height : actH;
|
||||
break;
|
||||
default:
|
||||
actH = Math.Max (height.Anchor (hostFrame.Height - actY), 0);
|
||||
actH = AutoSize && s.Height > actH ? s.Height : actH;
|
||||
break;
|
||||
}
|
||||
|
||||
return actH;
|
||||
}
|
||||
|
||||
// https://en.wikipedia.org/wiki/Topological_sorting
|
||||
List<View> TopologicalSort (IEnumerable<View> nodes, ICollection<(View From, View To)> edges)
|
||||
{
|
||||
@@ -2326,7 +2362,6 @@ namespace Terminal.Gui {
|
||||
{
|
||||
switch (pos) {
|
||||
case Pos.PosView pv:
|
||||
{
|
||||
if (pv.Target != this) {
|
||||
nEdges.Add ((pv.Target, from));
|
||||
}
|
||||
@@ -2334,23 +2369,19 @@ namespace Terminal.Gui {
|
||||
CollectAll (v, ref nNodes, ref nEdges);
|
||||
}
|
||||
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);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CollectDim (Dim dim, View from, ref HashSet<View> nNodes, ref HashSet<(View, View)> nEdges)
|
||||
{
|
||||
switch (dim) {
|
||||
case Dim.DimView dv:
|
||||
{
|
||||
if (dv.Target != this) {
|
||||
nEdges.Add ((dv.Target, from));
|
||||
}
|
||||
@@ -2358,16 +2389,13 @@ namespace Terminal.Gui {
|
||||
CollectAll (v, ref nNodes, ref nEdges);
|
||||
}
|
||||
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);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CollectAll (View from, ref HashSet<View> nNodes, ref HashSet<(View, View)> nEdges)
|
||||
@@ -2759,14 +2787,14 @@ namespace Terminal.Gui {
|
||||
/// The <see cref="MouseEvent"/> for the event.
|
||||
/// </summary>
|
||||
public MouseEvent MouseEvent { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Indicates if the current mouse event has already been processed and the driver should stop notifying any other event subscriber.
|
||||
/// Its important to set this value to true specially when updating any View's layout from inside the subscriber method.
|
||||
/// </summary>
|
||||
/// <remarks>This property forwards to the <see cref="MouseEvent.Handled"/> property and is provided as a convenience and for
|
||||
/// backwards compatibility</remarks>
|
||||
public bool Handled {
|
||||
public bool Handled {
|
||||
get => MouseEvent.Handled;
|
||||
set => MouseEvent.Handled = value;
|
||||
}
|
||||
@@ -2785,7 +2813,7 @@ namespace Terminal.Gui {
|
||||
|
||||
var args = new MouseEventArgs (mouseEvent);
|
||||
MouseEnter?.Invoke (args);
|
||||
|
||||
|
||||
return args.Handled || base.OnMouseEnter (mouseEvent);
|
||||
}
|
||||
|
||||
@@ -2802,7 +2830,7 @@ namespace Terminal.Gui {
|
||||
|
||||
var args = new MouseEventArgs (mouseEvent);
|
||||
MouseLeave?.Invoke (args);
|
||||
|
||||
|
||||
return args.Handled || base.OnMouseLeave (mouseEvent);
|
||||
}
|
||||
|
||||
@@ -2956,7 +2984,6 @@ namespace Terminal.Gui {
|
||||
canSetHeight = !ForceValidatePosDim;
|
||||
break;
|
||||
case Dim.DimFactor factor:
|
||||
{
|
||||
// Tries to get the SuperView height otherwise the view height.
|
||||
var sh = SuperView != null ? SuperView.Frame.Height : h;
|
||||
if (factor.IsFromRemaining ()) {
|
||||
@@ -2965,7 +2992,6 @@ namespace Terminal.Gui {
|
||||
h = Height.Anchor (sh);
|
||||
canSetHeight = !ForceValidatePosDim;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
canSetHeight = true;
|
||||
break;
|
||||
|
||||
@@ -1246,5 +1246,42 @@ namespace Terminal.Gui.Core {
|
||||
dim2 = Dim.Function (f2);
|
||||
Assert.NotEqual (dim1, dim2);
|
||||
}
|
||||
|
||||
[Theory, AutoInitShutdown]
|
||||
[InlineData (0, true)]
|
||||
[InlineData (0, false)]
|
||||
[InlineData (50, true)]
|
||||
[InlineData (50, false)]
|
||||
|
||||
public void DimPercentPlusOne (int startingDistance, bool testHorizontal)
|
||||
{
|
||||
var container = new View {
|
||||
Width = 100,
|
||||
Height = 100,
|
||||
};
|
||||
|
||||
var label = new Label {
|
||||
X = testHorizontal ? startingDistance : 0,
|
||||
Y = testHorizontal ? 0 : startingDistance,
|
||||
Width = testHorizontal ? Dim.Percent (50) + 1 : 1,
|
||||
Height = testHorizontal ? 1 : Dim.Percent (50) + 1,
|
||||
};
|
||||
|
||||
container.Add (label);
|
||||
Application.Top.Add (container);
|
||||
Application.Top.LayoutSubviews ();
|
||||
|
||||
|
||||
Assert.Equal (100, container.Frame.Width);
|
||||
Assert.Equal (100, container.Frame.Height);
|
||||
|
||||
if (testHorizontal) {
|
||||
Assert.Equal (51, label.Frame.Width);
|
||||
Assert.Equal (1, label.Frame.Height);
|
||||
} else {
|
||||
Assert.Equal (1, label.Frame.Width);
|
||||
Assert.Equal (51, label.Frame.Height);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user