Dim.Auto (Content) is pretty horked. Broke Bar

This commit is contained in:
Tig
2024-06-08 12:25:26 -06:00
parent 236374b8c0
commit 9abfb1ae46
5 changed files with 215 additions and 167 deletions

View File

@@ -22,6 +22,7 @@ public class DimAuto () : Dim
/// <summary>
/// Gets the maximum dimension the View's ContentSize will be fit to. NOT CURRENTLY SUPPORTED.
/// </summary>
// ReSharper disable once ConvertToAutoProperty
public required Dim? MaximumContentDim
{
@@ -34,6 +35,7 @@ public class DimAuto () : Dim
/// <summary>
/// Gets the minimum dimension the View's ContentSize will be constrained to.
/// </summary>
// ReSharper disable once ConvertToAutoProperty
public required Dim? MinimumContentDim
{
@@ -46,6 +48,7 @@ public class DimAuto () : Dim
/// <summary>
/// Gets the style of the DimAuto.
/// </summary>
// ReSharper disable once ConvertToAutoProperty
public required DimAutoStyle Style
{
@@ -62,7 +65,7 @@ public class DimAuto () : Dim
var subviewsSize = 0;
int autoMin = MinimumContentDim?.GetAnchor (superviewContentSize) ?? 0;
int autoMax = MaximumContentDim?.GetAnchor (superviewContentSize) ?? int.MaxValue;
int autoMax = MaximumContentDim?.GetAnchor (superviewContentSize) ?? superviewContentSize;
if (Style.FastHasFlags (DimAutoStyle.Text))
{
@@ -83,10 +86,11 @@ public class DimAuto () : Dim
// TODO: This whole body of code is a WIP (for https://github.com/gui-cs/Terminal.Gui/pull/3451).
subviewsSize = 0;
List<View> includedSubviews = us.Subviews.ToList ();//.Where (v => !v.ExcludeFromLayout).ToList ();
List<View> includedSubviews = us.Subviews.ToList (); //.Where (v => !v.ExcludeFromLayout).ToList ();
List<View> subviews;
#region Not Anchored and Are Not Dependent
// Start with subviews that are not anchored to the end, aligned, or dependent on content size
// [x] PosAnchorEnd
// [x] PosAlign
@@ -100,19 +104,25 @@ public class DimAuto () : Dim
// [ ] DimView
if (dimension == Dimension.Width)
{
subviews = includedSubviews.Where (v => v.X is not PosAnchorEnd
&& v.X is not PosAlign
subviews = includedSubviews.Where (
v => v.X is not PosAnchorEnd
&& v.X is not PosAlign
// && v.X is not PosCenter
&& v.Width is not DimAuto
&& v.Width is not DimFill).ToList ();
&& v.Width is not DimFill)
.ToList ();
}
else
{
subviews = includedSubviews.Where (v => v.Y is not PosAnchorEnd
&& v.Y is not PosAlign
subviews = includedSubviews.Where (
v => v.Y is not PosAnchorEnd
&& v.Y is not PosAlign
// && v.Y is not PosCenter
&& v.Height is not DimAuto
&& v.Height is not DimFill).ToList ();
&& v.Height is not DimFill)
.ToList ();
}
for (var i = 0; i < subviews.Count; i++)
@@ -127,9 +137,11 @@ public class DimAuto () : Dim
subviewsSize = size;
}
}
#endregion Not Anchored and Are Not Dependent
#region Anchored
// Now, handle subviews that are anchored to the end
// [x] PosAnchorEnd
if (dimension == Dimension.Width)
@@ -142,6 +154,7 @@ public class DimAuto () : Dim
}
int maxAnchorEnd = 0;
for (var i = 0; i < subviews.Count; i++)
{
View v = subviews [i];
@@ -149,52 +162,9 @@ public class DimAuto () : Dim
}
subviewsSize += maxAnchorEnd;
#endregion Anchored
#region Aligned
// Now, handle subviews that are anchored to the end
// [x] PosAnchorEnd
int maxAlign = 0;
if (dimension == Dimension.Width)
{
// Use Linq to get a list of distinct GroupIds from the subviews
List<int> groupIds = includedSubviews.Select (v => v.X is PosAlign posAlign ? posAlign.GroupId : -1).Distinct ().ToList ();
foreach (var groupId in groupIds)
{
List<int> dimensionsList = new ();
// PERF: If this proves a perf issue, consider caching a ref to this list in each item
List<PosAlign?> posAlignsInGroup = includedSubviews.Where (
v =>
{
return dimension switch
{
Dimension.Width when v.X is PosAlign alignX => alignX.GroupId == groupId,
Dimension.Height when v.Y is PosAlign alignY => alignY.GroupId == groupId,
_ => false
};
})
.Select (v => dimension == Dimension.Width ? v.X as PosAlign : v.Y as PosAlign)
.ToList ();
if (posAlignsInGroup.Count == 0)
{
continue;
}
maxAlign = posAlignsInGroup [0].CalculateMinDimension (groupId, includedSubviews, dimension);
}
}
else
{
subviews = includedSubviews.Where (v => v.Y is PosAlign).ToList ();
}
subviewsSize = int.Max (subviewsSize, maxAlign);
#endregion Aligned
#region Auto
@@ -208,19 +178,12 @@ public class DimAuto () : Dim
}
int maxAuto = 0;
for (var i = 0; i < subviews.Count; i++)
{
View v = subviews [i];
//if (dimension == Dimension.Width)
//{
// v.SetRelativeLayout (new Size (autoMax - subviewsSize, 0));
//}
//else
//{
// v.SetRelativeLayout (new Size (0, autoMax - subviewsSize));
//}
maxAuto = dimension == Dimension.Width ? v.Frame.X + v.Frame.Width : v.Frame.Y + v.Frame.Height;
maxAuto = CalculateMinDimension (us, dimension);
if (maxAuto > subviewsSize)
{
@@ -229,32 +192,40 @@ public class DimAuto () : Dim
}
}
// subviewsSize += maxAuto;
// subviewsSize += maxAuto;
#endregion Auto
//#region Center
//// Now, handle subviews that are Centered
//if (dimension == Dimension.Width)
//{
// subviews = us.Subviews.Where (v => v.X is PosCenter).ToList ();
//}
//else
//{
// subviews = us.Subviews.Where (v => v.Y is PosCenter).ToList ();
//}
#region Center
//int maxCenter = 0;
//for (var i = 0; i < subviews.Count; i++)
//{
// View v = subviews [i];
// maxCenter = dimension == Dimension.Width ? v.Frame.Width : v.Frame.Height;
//}
// Now, handle subviews that are Centered
if (dimension == Dimension.Width)
{
subviews = us.Subviews.Where (v => v.X is PosCenter).ToList ();
}
else
{
subviews = us.Subviews.Where (v => v.Y is PosCenter).ToList ();
}
//subviewsSize += maxCenter;
//#endregion Center
int maxCenter = 0;
for (var i = 0; i < subviews.Count; i++)
{
View v = subviews [i];
maxCenter = dimension == Dimension.Width ? v.Frame.Width : v.Frame.Height;
if (maxCenter > subviewsSize)
{
// BUGBUG: Should we break here? Or choose min/max?
subviewsSize = maxCenter;
}
}
#endregion Center
#region Are Dependent
// Now, go back to those that are dependent on content size
// [x] DimFill
// [ ] DimPercent
@@ -268,6 +239,7 @@ public class DimAuto () : Dim
}
int maxFill = 0;
for (var i = 0; i < subviews.Count; i++)
{
View v = subviews [i];
@@ -280,10 +252,12 @@ public class DimAuto () : Dim
{
v.SetRelativeLayout (new Size (0, autoMax - subviewsSize));
}
maxFill = dimension == Dimension.Width ? v.Frame.Width : v.Frame.Height;
}
subviewsSize += maxFill;
#endregion Are Dependent
}
}
@@ -309,6 +283,16 @@ public class DimAuto () : Dim
return int.Min (max, autoMax);
}
internal int CalculateMinDimension (View us, Dimension dimension)
{
int min = dimension == Dimension.Width ? us.Frame.Width : us.Frame.Height;
return min;
}
internal override bool ReferencesOtherViews ()
{
// BUGBUG: This is not correct. _contentSize may be null.

View File

@@ -198,6 +198,7 @@ public class PosAlign : Pos
for (var index = 0; index < viewsInGroup.Count; index++)
{
View view = viewsInGroup [index];
PosAlign? posAlign = dimension == Dimension.Width ? view.X as PosAlign : view.Y as PosAlign;
if (posAlign is { })

View File

@@ -99,13 +99,45 @@ public class Bar : View
}
barItem.Y = Pos.Center ();
barItem.SetRelativeLayout(new Size(int.MaxValue, int.MaxValue));
barItem.SetRelativeLayout (new Size (int.MaxValue, int.MaxValue));
prevBarItem = barItem;
}
break;
case Orientation.Vertical:
// CommandView is aligned left, HelpView is aligned right, KeyView is aligned right
// All CommandView's are the same width, all HelpView's are the same width,
// all KeyView's are the same width
int maxCommandWidth = 0;
int maxHelpWidth = 0;
List<Shortcut> shortcuts = Subviews.Where (s => s is Shortcut && s.Visible).Cast<Shortcut> ().ToList ();
foreach (Shortcut shortcut in shortcuts)
{
// Let AutoSize do its thing to get the minimum width of each CommandView and HelpView
shortcut.CommandView.SetRelativeLayout (new Size (int.MaxValue, int.MaxValue));
shortcut.KeyView.SetRelativeLayout (new Size (int.MaxValue, int.MaxValue));
shortcut.HelpView.SetRelativeLayout (new Size (int.MaxValue, int.MaxValue));
}
maxCommandWidth = shortcuts.Max (s => s.CommandView.Frame.Width);
maxHelpWidth = shortcuts.Max (s => s.HelpView.Frame.Width);
// Set the width of all CommandView's and HelpView's to the max width
foreach (Shortcut shortcut in shortcuts)
{
shortcut.CommandView.Width = Dim.Auto (minimumContentDim: maxCommandWidth);
shortcut.KeyView.Width = Dim.Auto ();
shortcut.HelpView.Width = Dim.Auto (minimumContentDim: maxHelpWidth);
// shortcut.LayoutSubviews ();
}
// Set the overall size of the Bar and arrange the views vertically
var maxBarItemWidth = 0;
for (var index = 0; index < Subviews.Count; index++)
@@ -128,6 +160,7 @@ public class Bar : View
}
prevBarItem = barItem;
if (barItem is Shortcut shortcut)
{
//shortcut.SetRelativeLayout (new (int.MaxValue, int.MaxValue));
@@ -137,32 +170,51 @@ public class Bar : View
{
maxBarItemWidth = Math.Max (maxBarItemWidth, barItem.Frame.Width);
}
barItem.X = 0;
}
for (var index = 0; index < Subviews.Count; index++)
foreach (Shortcut shortcut in shortcuts)
{
var shortcut = Subviews [index] as Shortcut;
if (shortcut is { Visible: false })
{
continue;
}
if (Width is DimAuto)
{
shortcut._container.Width = Dim.Auto (DimAutoStyle.Content, minimumContentDim: maxBarItemWidth);
shortcut.Width = Dim.Auto (DimAutoStyle.Content, minimumContentDim: maxBarItemWidth);
}
else
{
shortcut._container.Width = Dim.Fill ();
shortcut.Width = Dim.Fill ();
//shortcut._container.Width = Dim.Fill ();
// shortcut.Width = Dim.Fill ();
}
//shortcut.SetContentSize (new (maxBarItemWidth, 1));
//shortcut.Width = Dim.Auto (DimAutoStyle.Content, minimumContentDim: int.Max(maxBarItemWidth, GetContentSize().Width));
shortcut.LayoutSubviews ();
}
//for (var index = 0; index < Subviews.Count; index++)
//{
// var shortcut = Subviews [index] as Shortcut;
// if (shortcut is { Visible: false })
// {
// continue;
// }
// if (Width is DimAuto)
// {
// shortcut._container.Width = Dim.Auto (DimAutoStyle.Content, minimumContentDim: maxBarItemWidth);
// }
// else
// {
// shortcut._container.Width = Dim.Fill ();
// shortcut.Width = Dim.Fill ();
// }
// //shortcut.SetContentSize (new (maxBarItemWidth, 1));
// //shortcut.Width = Dim.Auto (DimAutoStyle.Content, minimumContentDim: int.Max(maxBarItemWidth, GetContentSize().Width));
//}
break;
}

View File

@@ -59,7 +59,8 @@ public class Shortcut : View
// Only the Shortcut (_container) should be able to have focus, not any subviews.
CanFocus = true,
Width = Dim.Auto (DimAutoStyle.Content, 1),
Height = Dim.Auto (DimAutoStyle.Content, 1)
Height = Dim.Auto (DimAutoStyle.Content, 1),
BorderStyle = LineStyle.Dashed
};
CommandView = new ();
@@ -71,8 +72,11 @@ public class Shortcut : View
CanFocus = false,
X = Pos.Align (Alignment.End, AlignmentModes.IgnoreFirstOrLast | AlignmentModes.AddSpaceBetweenItems),
Y = Pos.Center (),
// Helpview is the only subview that doesn't have a min width
Width = Dim.Auto (DimAutoStyle.Text),
Height = Dim.Auto (DimAutoStyle.Text)
Height = Dim.Auto (DimAutoStyle.Text),
ColorScheme = Colors.ColorSchemes ["Error"]
};
_container.Add (HelpView);
@@ -86,8 +90,10 @@ public class Shortcut : View
CanFocus = false,
X = Pos.Align (Alignment.End, AlignmentModes.IgnoreFirstOrLast | AlignmentModes.AddSpaceBetweenItems),
Y = Pos.Center (),
// Bar will set the width of all KeyViews to the width of the widest KeyView.
Width = Dim.Auto (DimAutoStyle.Text),
Height = Dim.Auto (DimAutoStyle.Text)
Height = Dim.Auto (DimAutoStyle.Text),
};
_container.Add (KeyView);
@@ -259,6 +265,7 @@ public class Shortcut : View
// Right now, we don't set CanFocus to false here.
_commandView.CanFocus = false;
// Bar will set the width of all CommandViews to the width of the widest CommandViews.
_commandView.Width = Dim.Auto (DimAutoStyle.Text);
_commandView.Height = Dim.Auto (DimAutoStyle.Text);
_commandView.X = X = Pos.Align (Alignment.End, AlignmentModes.IgnoreFirstOrLast | AlignmentModes.AddSpaceBetweenItems);

View File

@@ -40,17 +40,21 @@ public class Bars : Scenario
};
Application.Top.Add (eventLog);
//var shortcut1 = new Shortcut
//{
// Title = "_Zigzag",
// Key = Key.Z.WithAlt,
// Text = "Gonna zig zag",
// KeyBindingScope = KeyBindingScope.HotKey,
// Command = Command.Accept,
// X = 10,// Pos.Center (),
// Y = 10,//Pos.Center ()
// //Width = Dim.Auto(DimAutoStyle.Content, minimumContentDim: 50),
//};
var shortcut1 = new Shortcut
{
Title = "_Zigzag",
Key = Key.Z.WithAlt,
Text = "Gonna zig zag",
KeyBindingScope = KeyBindingScope.HotKey,
Command = Command.Accept,
};
shortcut1.Accept += (s, e) =>
{
eventSource.Add ($"Accept: {s}");
eventLog.MoveDown ();
};
Application.Top.Add (shortcut1);
shortcut1.SetFocus ();
//var shortcut2 = new Shortcut
//{
@@ -64,74 +68,74 @@ public class Bars : Scenario
// //Width = 50,
//};
//Application.Top.Add (shortcut1, shortcut2);
//shortcut1.SetFocus ();
var shortcut3 = new Shortcut
{
Title = "Shortcut3",
Key = Key.D3.WithCtrl,
Text = "Number Three",
KeyBindingScope = KeyBindingScope.Application,
Command = Command.Accept,
};
//var shortcut3 = new Shortcut
//{
// Title = "Shortcut3",
// Key = Key.D3.WithCtrl,
// Text = "Number Three",
// KeyBindingScope = KeyBindingScope.Application,
// Command = Command.Accept,
//};
shortcut3.Accept += (s, e) =>
{
eventSource.Add ($"Accept: {s}");
eventLog.MoveDown ();
};
//shortcut3.Accept += (s, e) =>
// {
// eventSource.Add ($"Accept: {s}");
// eventLog.MoveDown ();
// };
var shortcut4 = new Shortcut
{
Title = "Shortcut4",
Text = "Number 4",
Key = Key.F4,
KeyBindingScope = KeyBindingScope.Application,
Command = Command.Accept,
};
//var shortcut4 = new Shortcut
//{
// Title = "Shortcut4",
// Text = "Number 4",
// Key = Key.F4,
// KeyBindingScope = KeyBindingScope.Application,
// Command = Command.Accept,
//};
var cb = new CheckBox ()
{
Title = "Hello",// shortcut4.Text
};
//var cb = new CheckBox ()
//{
// Title = "Hello",// shortcut4.Text
//};
cb.Toggled += (s, e) =>
{
eventSource.Add ($"Toggled: {s}");
eventLog.MoveDown ();
};
//cb.Toggled += (s, e) =>
// {
// eventSource.Add ($"Toggled: {s}");
// eventLog.MoveDown ();
// };
shortcut4.CommandView = cb;
//shortcut4.CommandView = cb;
shortcut4.Accept += (s, e) =>
{
eventSource.Add ($"Accept: {s}");
eventLog.MoveDown ();
};
//shortcut4.Accept += (s, e) =>
// {
// eventSource.Add ($"Accept: {s}");
// eventLog.MoveDown ();
// };
var bar = new Bar
{
X = 2,
Y = 2,
Orientation = Orientation.Vertical,
StatusBarStyle = false,
Width = Dim.Percent(40)
};
bar.Add (shortcut3, shortcut4);
//var bar = new Bar
//{
// X = 2,
// Y = Pos.Bottom(shortcut1),
// Orientation = Orientation.Vertical,
// StatusBarStyle = false,
// Width = Dim.Percent(40)
//};
//bar.Add (shortcut3, shortcut4);
CheckBox hello = new ()
{
Title = "Hello",
};
Application.Top.Add (hello);
hello.Toggled += (s, e) =>
{
eventSource.Add ($"Toggled: {s}");
eventLog.MoveDown ();
};
////CheckBox hello = new ()
////{
//// Title = "Hello",
//// X = 0,
//// Y = 1,
////};
////Application.Top.Add (hello);
////hello.Toggled += (s, e) =>
//// {
//// eventSource.Add ($"Toggled: {s}");
//// eventLog.MoveDown ();
//// };
Application.Top.Add (bar);
//Application.Top.Add (bar);
// BUGBUG: This should not be needed
//Application.Top.LayoutSubviews ();