|
@@ -59,242 +59,507 @@ public class DimAuto () : Dim
|
|
internal override int Calculate (int location, int superviewContentSize, View us, Dimension dimension)
|
|
internal override int Calculate (int location, int superviewContentSize, View us, Dimension dimension)
|
|
{
|
|
{
|
|
var textSize = 0;
|
|
var textSize = 0;
|
|
- var subviewsSize = 0;
|
|
|
|
|
|
+ var maxCalculatedSize = 0;
|
|
|
|
|
|
int autoMin = MinimumContentDim?.GetAnchor (superviewContentSize) ?? 0;
|
|
int autoMin = MinimumContentDim?.GetAnchor (superviewContentSize) ?? 0;
|
|
- int autoMax = MaximumContentDim?.GetAnchor (superviewContentSize) ?? int.MaxValue;
|
|
|
|
|
|
+ int autoMax = MaximumContentDim?.GetAnchor (superviewContentSize) ?? (dimension == Dimension.Width ? Application.Driver.Screen.Width : Application.Driver.Screen.Height);
|
|
|
|
|
|
if (Style.FastHasFlags (DimAutoStyle.Text))
|
|
if (Style.FastHasFlags (DimAutoStyle.Text))
|
|
{
|
|
{
|
|
- textSize = int.Max (autoMin, dimension == Dimension.Width ? us.TextFormatter.Size.Width : us.TextFormatter.Size.Height);
|
|
|
|
|
|
+ if (dimension == Dimension.Width)
|
|
|
|
+ {
|
|
|
|
+ //us.TextFormatter.Size = us.GetContentSize ();
|
|
|
|
+ textSize = int.Max (autoMin, us.TextFormatter.FormatAndGetSize ().Width);
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ us.TextFormatter.Size = us.GetContentSize () with { Height = Application.Driver.Screen.Height };
|
|
|
|
+ textSize = int.Max (autoMin, us.TextFormatter.FormatAndGetSize ().Height);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
if (Style.FastHasFlags (DimAutoStyle.Content))
|
|
if (Style.FastHasFlags (DimAutoStyle.Content))
|
|
{
|
|
{
|
|
if (!us.ContentSizeTracksViewport)
|
|
if (!us.ContentSizeTracksViewport)
|
|
{
|
|
{
|
|
- // ContentSize was explicitly set. Ignore subviews.
|
|
|
|
- subviewsSize = dimension == Dimension.Width ? us.GetContentSize ().Width : us.GetContentSize ().Height;
|
|
|
|
|
|
+ // ContentSize was explicitly set. Use `us.ContentSize` to determine size.
|
|
|
|
+ maxCalculatedSize = dimension == Dimension.Width ? us.GetContentSize ().Width : us.GetContentSize ().Height;
|
|
}
|
|
}
|
|
else
|
|
else
|
|
{
|
|
{
|
|
- // ContentSize was NOT explicitly set. Use subviews to determine size.
|
|
|
|
-
|
|
|
|
- // 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> 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
|
|
|
|
- // [ ] PosCenter
|
|
|
|
- // [ ] PosPercent
|
|
|
|
- // [ ] PosView
|
|
|
|
- // [ ] PosFunc
|
|
|
|
- // [x] DimFill
|
|
|
|
- // [ ] DimPercent
|
|
|
|
- // [ ] DimFunc
|
|
|
|
- // [ ] DimView
|
|
|
|
|
|
+ maxCalculatedSize = textSize;
|
|
|
|
+ // ContentSize was NOT explicitly set. Use `us.Subviews` to determine size.
|
|
|
|
+
|
|
|
|
+ List<View> includedSubviews = us.Subviews.ToList ();
|
|
|
|
+
|
|
|
|
+ // If [x] it can cause `us.ContentSize` to change.
|
|
|
|
+ // If [ ] it doesn't need special processing for us to determine `us.ContentSize`.
|
|
|
|
+
|
|
|
|
+ // -------------------- Pos types that are dependent on `us.Subviews`
|
|
|
|
+ // [ ] PosAlign - Position is dependent on other views with `GroupId` AND `us.ContentSize`
|
|
|
|
+ // [x] PosView - Position is dependent on `subview.Target` - it can cause a change in `us.ContentSize`
|
|
|
|
+ // [x] PosCombine - Position is dependent if `Pos.Has ([one of the above]` - it can cause a change in `us.ContentSize`
|
|
|
|
+
|
|
|
|
+ // -------------------- Pos types that are dependent on `us.ContentSize`
|
|
|
|
+ // [ ] PosAlign - Position is dependent on other views with `GroupId` AND `us.ContentSize`
|
|
|
|
+ // [x] PosAnchorEnd - Position is dependent on `us.ContentSize` AND `subview.Frame` - it can cause a change in `us.ContentSize`
|
|
|
|
+ // [ ] PosCenter - Position is dependent `us.ContentSize` AND `subview.Frame`
|
|
|
|
+ // [ ] PosPercent - Position is dependent `us.ContentSize`
|
|
|
|
+ // [x] PosCombine - Position is dependent if `Pos.Has ([one of the above]` - it can cause a change in `us.ContentSize`
|
|
|
|
+
|
|
|
|
+ // -------------------- Pos types that are not dependent on either `us.Subviews` or `us.ContentSize`
|
|
|
|
+ // [ ] PosAbsolute - Position is fixed.
|
|
|
|
+ // [ ] PosFunc - Position is internally calculated.
|
|
|
|
+
|
|
|
|
+ // -------------------- Dim types that are dependent on `us.Subviews`
|
|
|
|
+ // [x] DimView - Dimension is dependent on `subview.Target`
|
|
|
|
+ // [x] DimCombine - Dimension is dependent if `Dim.Has ([one of the above]` - it can cause a change in `us.ContentSize`
|
|
|
|
+
|
|
|
|
+ // -------------------- Dim types that are dependent on `us.ContentSize`
|
|
|
|
+ // [ ] DimFill - Dimension is dependent on `us.ContentSize`
|
|
|
|
+ // [ ] DimPercent - Dimension is dependent on `us.ContentSize`
|
|
|
|
+ // [ ] DimCombine - Dimension is dependent if `Dim.Has ([one of the above]`
|
|
|
|
+
|
|
|
|
+ // -------------------- Dim types that are not dependent on either `us.Subviews` or `us.ContentSize`
|
|
|
|
+ // [ ] DimAuto - Dimension is internally calculated
|
|
|
|
+ // [ ] DimAbsolute - Dimension is fixed
|
|
|
|
+ // [ ] DimFunc - Dimension is internally calculated
|
|
|
|
+
|
|
|
|
+ // ======================================================
|
|
|
|
+ // Do the easy stuff first - subviews whose position and size are not dependent on other views or content size
|
|
|
|
+ // ======================================================
|
|
|
|
+ // [ ] PosAbsolute - Position is fixed.
|
|
|
|
+ // [ ] PosFunc - Position is internally calculated
|
|
|
|
+ // [ ] DimAuto - Dimension is internally calculated
|
|
|
|
+ // [ ] DimAbsolute - Dimension is fixed
|
|
|
|
+ // [ ] DimFunc - Dimension is internally calculated
|
|
|
|
+ List<View> notDependentSubViews;
|
|
if (dimension == Dimension.Width)
|
|
if (dimension == Dimension.Width)
|
|
{
|
|
{
|
|
- 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 ();
|
|
|
|
|
|
+ notDependentSubViews = includedSubviews.Where (v => v.Width is { } &&
|
|
|
|
+ (v.X is PosAbsolute or PosFunc || v.Width is DimAuto or DimAbsolute or DimFunc) &&
|
|
|
|
+ !v.X.Has (typeof (PosAnchorEnd), out _) &&
|
|
|
|
+ !v.X.Has (typeof (PosAlign), out _) &&
|
|
|
|
+ !v.X.Has (typeof (PosView), out _) &&
|
|
|
|
+ !v.Width.Has (typeof (DimView), out _) &&
|
|
|
|
+ !v.X.Has (typeof (PosCenter), out _)).ToList ();
|
|
}
|
|
}
|
|
else
|
|
else
|
|
{
|
|
{
|
|
- 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 ();
|
|
|
|
|
|
+ notDependentSubViews = includedSubviews.Where (v => v.Height is { } &&
|
|
|
|
+ (v.Y is PosAbsolute or PosFunc || v.Height is DimAuto or DimAbsolute or DimFunc) &&
|
|
|
|
+ !v.Y.Has (typeof (PosAnchorEnd), out _) &&
|
|
|
|
+ !v.Y.Has (typeof (PosAlign), out _) &&
|
|
|
|
+ !v.Y.Has (typeof (PosView), out _) &&
|
|
|
|
+ !v.Height.Has (typeof (DimView), out _) &&
|
|
|
|
+ !v.Y.Has (typeof (PosCenter), out _)).ToList ();
|
|
}
|
|
}
|
|
|
|
|
|
- for (var i = 0; i < subviews.Count; i++)
|
|
|
|
|
|
+ for (var i = 0; i < notDependentSubViews.Count; i++)
|
|
{
|
|
{
|
|
- View v = subviews [i];
|
|
|
|
|
|
+ View v = notDependentSubViews [i];
|
|
|
|
|
|
- int size = dimension == Dimension.Width ? v.Frame.X + v.Frame.Width : v.Frame.Y + v.Frame.Height;
|
|
|
|
|
|
+ int size = dimension == Dimension.Width ? v.X.GetAnchor (maxCalculatedSize) + v.Width.GetAnchor (maxCalculatedSize) : v.Y.GetAnchor (maxCalculatedSize) + v.Height.GetAnchor (maxCalculatedSize);
|
|
|
|
|
|
- if (size > subviewsSize)
|
|
|
|
|
|
+ if (size > maxCalculatedSize)
|
|
{
|
|
{
|
|
- // BUGBUG: Should we break here? Or choose min/max?
|
|
|
|
- subviewsSize = size;
|
|
|
|
|
|
+ maxCalculatedSize = size;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- #endregion Not Anchored and Are Not Dependent
|
|
|
|
|
|
|
|
- #region Anchored
|
|
|
|
- // Now, handle subviews that are anchored to the end
|
|
|
|
- // [x] PosAnchorEnd
|
|
|
|
|
|
+ // ************** We now have some idea of `us.ContentSize` ***************
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ // [ ] PosCenter - Position is dependent `us.ContentSize` AND `subview.Frame`
|
|
|
|
+ List<View> centeredSubViews;
|
|
if (dimension == Dimension.Width)
|
|
if (dimension == Dimension.Width)
|
|
{
|
|
{
|
|
- subviews = includedSubviews.Where (v => v.X is PosAnchorEnd).ToList ();
|
|
|
|
|
|
+ centeredSubViews = us.Subviews.Where (v => v.X.Has (typeof (PosCenter), out _)).ToList ();
|
|
}
|
|
}
|
|
else
|
|
else
|
|
{
|
|
{
|
|
- subviews = includedSubviews.Where (v => v.Y is PosAnchorEnd).ToList ();
|
|
|
|
|
|
+ centeredSubViews = us.Subviews.Where (v => v.Y.Has (typeof (PosCenter), out _)).ToList ();
|
|
}
|
|
}
|
|
|
|
|
|
- int maxAnchorEnd = 0;
|
|
|
|
- for (var i = 0; i < subviews.Count; i++)
|
|
|
|
|
|
+ for (var i = 0; i < centeredSubViews.Count; i++)
|
|
{
|
|
{
|
|
- View v = subviews [i];
|
|
|
|
- maxAnchorEnd = dimension == Dimension.Width ? v.Frame.Width : v.Frame.Height;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- subviewsSize += maxAnchorEnd;
|
|
|
|
- #endregion Anchored
|
|
|
|
|
|
+ View v = centeredSubViews [i];
|
|
|
|
|
|
- //#region Aligned
|
|
|
|
|
|
+ int maxCentered = dimension == Dimension.Width ?/* v.X.GetAnchor (maxCalculatedSize) +*/ v.Width.GetAnchor (maxCalculatedSize) : /*v.Y.GetAnchor (maxCalculatedSize) + */v.Height.GetAnchor(maxCalculatedSize);
|
|
|
|
|
|
- //// 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 ();
|
|
|
|
|
|
+ if (maxCentered > maxCalculatedSize)
|
|
|
|
+ {
|
|
|
|
+ maxCalculatedSize = maxCentered;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
|
|
- // 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;
|
|
|
|
- // }
|
|
|
|
|
|
+ #region Anchored
|
|
|
|
+ // [x] PosAnchorEnd - Position is dependent on `us.ContentSize` AND `subview.Frame`
|
|
|
|
+ List<View> anchoredSubViews;
|
|
|
|
+ if (dimension == Dimension.Width)
|
|
|
|
+ {
|
|
|
|
+ anchoredSubViews = includedSubviews.Where (v => v.X.Has (typeof (PosAnchorEnd), out _)).ToList ();
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ anchoredSubViews = includedSubviews.Where (v => v.Y.Has (typeof (PosAnchorEnd), out _)).ToList ();
|
|
|
|
+ }
|
|
|
|
|
|
- // maxAlign = PosAlign.CalculateMinDimension (groupId, includedSubviews, dimension);
|
|
|
|
- // }
|
|
|
|
- //}
|
|
|
|
- //else
|
|
|
|
- //{
|
|
|
|
- // subviews = includedSubviews.Where (v => v.Y is PosAlign).ToList ();
|
|
|
|
- //}
|
|
|
|
|
|
+ int maxAnchorEnd = 0;
|
|
|
|
+ for (var i = 0; i < anchoredSubViews.Count; i++)
|
|
|
|
+ {
|
|
|
|
+ View v = anchoredSubViews [i];
|
|
|
|
|
|
- //subviewsSize = int.Max (subviewsSize, maxAlign);
|
|
|
|
- //#endregion Aligned
|
|
|
|
|
|
+ // Need to set the relative layout for PosAnchorEnd subviews to calculate the size
|
|
|
|
+ if (dimension == Dimension.Width)
|
|
|
|
+ {
|
|
|
|
+ v.SetRelativeLayout (new Size (maxCalculatedSize, 0));
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ v.SetRelativeLayout (new Size (0, maxCalculatedSize));
|
|
|
|
+ }
|
|
|
|
+ maxAnchorEnd = dimension == Dimension.Width ? v.X.GetAnchor (maxCalculatedSize) + v.Frame.Width : v.Y.GetAnchor (maxCalculatedSize) + v.Frame.Height;
|
|
|
|
+ }
|
|
|
|
|
|
|
|
+ maxCalculatedSize = Math.Max (maxCalculatedSize, maxAnchorEnd);
|
|
|
|
+ #endregion Anchored
|
|
|
|
|
|
- #region Auto
|
|
|
|
|
|
|
|
|
|
+ #region PosView
|
|
|
|
+ // [x] PosView - Position is dependent on `subview.Target` - it can cause a change in `us.ContentSize`
|
|
|
|
+ List<View> posViewSubViews;
|
|
if (dimension == Dimension.Width)
|
|
if (dimension == Dimension.Width)
|
|
{
|
|
{
|
|
- subviews = includedSubviews.Where (v => v.Width is DimAuto).ToList ();
|
|
|
|
|
|
+ posViewSubViews = includedSubviews.Where (v => v.X.Has (typeof (PosView), out _)).ToList ();
|
|
}
|
|
}
|
|
else
|
|
else
|
|
{
|
|
{
|
|
- subviews = includedSubviews.Where (v => v.Height is DimAuto).ToList ();
|
|
|
|
|
|
+ posViewSubViews = includedSubviews.Where (v => v.Y.Has (typeof (PosView), out _)).ToList ();
|
|
}
|
|
}
|
|
|
|
|
|
- int maxAuto = 0;
|
|
|
|
- for (var i = 0; i < subviews.Count; i++)
|
|
|
|
|
|
+ for (var i = 0; i < posViewSubViews.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;
|
|
|
|
-
|
|
|
|
- if (maxAuto > subviewsSize)
|
|
|
|
|
|
+ View v = posViewSubViews [i];
|
|
|
|
+
|
|
|
|
+ // BUGBUG: The order may not be correct. May need to call TopologicalSort?
|
|
|
|
+ if (dimension == Dimension.Width)
|
|
{
|
|
{
|
|
- // BUGBUG: Should we break here? Or choose min/max?
|
|
|
|
- subviewsSize = maxAuto;
|
|
|
|
|
|
+ v.SetRelativeLayout (new Size (maxCalculatedSize, 0));
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ v.SetRelativeLayout (new Size (0, maxCalculatedSize));
|
|
|
|
+ }
|
|
|
|
+ int maxPosView = dimension == Dimension.Width ? v.Frame.X + v.Frame.Width : v.Frame.Y + v.Frame.Height;
|
|
|
|
+
|
|
|
|
+ if (maxPosView > maxCalculatedSize)
|
|
|
|
+ {
|
|
|
|
+ maxCalculatedSize = maxPosView;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+ #endregion PosView
|
|
|
|
+
|
|
|
|
+ // [x] PosCombine - Position is dependent if `Pos.Has ([one of the above]` - it can cause a change in `us.ContentSize`
|
|
|
|
|
|
-// 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 ();
|
|
|
|
- //}
|
|
|
|
-
|
|
|
|
- //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;
|
|
|
|
- //}
|
|
|
|
-
|
|
|
|
- //subviewsSize += maxCenter;
|
|
|
|
- //#endregion Center
|
|
|
|
-
|
|
|
|
- #region Are Dependent
|
|
|
|
- // Now, go back to those that are dependent on content size
|
|
|
|
- // [x] DimFill
|
|
|
|
- // [ ] DimPercent
|
|
|
|
|
|
+ #region DimView
|
|
|
|
+ // [x] DimView - Dimension is dependent on `subview.Target` - it can cause a change in `us.ContentSize`
|
|
|
|
+ List<View> dimViewSubViews;
|
|
if (dimension == Dimension.Width)
|
|
if (dimension == Dimension.Width)
|
|
{
|
|
{
|
|
- subviews = includedSubviews.Where (v => v.Width is DimFill).ToList ();
|
|
|
|
|
|
+ dimViewSubViews = includedSubviews.Where (v => v.Width is { } && v.Width.Has (typeof (DimView), out _)).ToList ();
|
|
}
|
|
}
|
|
else
|
|
else
|
|
{
|
|
{
|
|
- subviews = includedSubviews.Where (v => v.Height is DimFill).ToList ();
|
|
|
|
|
|
+ dimViewSubViews = includedSubviews.Where (v => v.Height is { } && v.Height.Has (typeof (DimView), out _)).ToList ();
|
|
}
|
|
}
|
|
|
|
|
|
- int maxFill = 0;
|
|
|
|
- for (var i = 0; i < subviews.Count; i++)
|
|
|
|
|
|
+ for (var i = 0; i < dimViewSubViews.Count; i++)
|
|
{
|
|
{
|
|
- View v = subviews [i];
|
|
|
|
|
|
+ View v = dimViewSubViews [i];
|
|
|
|
|
|
- if (autoMax == int.MaxValue)
|
|
|
|
- {
|
|
|
|
- autoMax = superviewContentSize;
|
|
|
|
- }
|
|
|
|
|
|
+ // BUGBUG: The order may not be correct. May need to call TopologicalSort?
|
|
if (dimension == Dimension.Width)
|
|
if (dimension == Dimension.Width)
|
|
{
|
|
{
|
|
- v.SetRelativeLayout (new Size (autoMax - subviewsSize, 0));
|
|
|
|
|
|
+ v.SetRelativeLayout (new Size (maxCalculatedSize, 0));
|
|
}
|
|
}
|
|
else
|
|
else
|
|
{
|
|
{
|
|
- v.SetRelativeLayout (new Size (0, autoMax - subviewsSize));
|
|
|
|
|
|
+ v.SetRelativeLayout (new Size (0, maxCalculatedSize));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ int maxDimView = dimension == Dimension.Width ? v.Frame.X + v.Frame.Width : v.Frame.Y + v.Frame.Height;
|
|
|
|
+
|
|
|
|
+ if (maxDimView > maxCalculatedSize)
|
|
|
|
+ {
|
|
|
|
+ maxCalculatedSize = maxDimView;
|
|
}
|
|
}
|
|
- maxFill = dimension == Dimension.Width ? v.Frame.Width : v.Frame.Height;
|
|
|
|
}
|
|
}
|
|
|
|
+ #endregion DimView
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ // [x] DimCombine - Dimension is dependent if `Dim.Has ([one of the above]` - it can cause a change in `us.ContentSize`
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ // // ======================================================
|
|
|
|
+ // // Now do PosAlign - It's dependent on other views with `GroupId` AND `us.ContentSize`
|
|
|
|
+ // // ======================================================
|
|
|
|
+ // // [ ] PosAlign - Position is dependent on other views with `GroupId` AND `us.ContentSize`
|
|
|
|
+ // #region Aligned
|
|
|
|
+
|
|
|
|
+ // 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;
|
|
|
|
+ // }
|
|
|
|
+ // // BUGBUG: ignores adornments
|
|
|
|
+
|
|
|
|
+ // maxAlign = PosAlign.CalculateMinDimension (groupId, includedSubviews, dimension);
|
|
|
|
+ // }
|
|
|
|
+ // }
|
|
|
|
+ // else
|
|
|
|
+ // {
|
|
|
|
+
|
|
|
|
+ // // BUGBUG: Incompletge
|
|
|
|
+ // subviews = includedSubviews.Where (v => v.Y is PosAlign).ToList ();
|
|
|
|
+ // }
|
|
|
|
+
|
|
|
|
+ // maxCalculatedSize = int.Max (maxCalculatedSize, maxAlign);
|
|
|
|
+ // #endregion Aligned
|
|
|
|
+
|
|
|
|
+ // // TODO: This whole body of code is a WIP (forhttps://github.com/gui-cs/Terminal.Gui/issues/3499).
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ // 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
|
|
|
|
+ // // [ ] PosCenter
|
|
|
|
+ // // [ ] PosPercent
|
|
|
|
+ // // [ ] PosView
|
|
|
|
+ // // [ ] PosFunc
|
|
|
|
+ // // [x] DimFill
|
|
|
|
+ // // [ ] DimPercent
|
|
|
|
+ // // [ ] DimFunc
|
|
|
|
+ // // [ ] DimView
|
|
|
|
+ // if (dimension == Dimension.Width)
|
|
|
|
+ // {
|
|
|
|
+ // 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 ();
|
|
|
|
+ // }
|
|
|
|
+ // else
|
|
|
|
+ // {
|
|
|
|
+ // 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 ();
|
|
|
|
+ // }
|
|
|
|
+
|
|
|
|
+ // for (var i = 0; i < subviews.Count; i++)
|
|
|
|
+ // {
|
|
|
|
+ // View v = subviews [i];
|
|
|
|
+
|
|
|
|
+ // int size = dimension == Dimension.Width ? v.Frame.X + v.Frame.Width : v.Frame.Y + v.Frame.Height;
|
|
|
|
+
|
|
|
|
+ // if (size > maxCalculatedSize)
|
|
|
|
+ // {
|
|
|
|
+ // // BUGBUG: Should we break here? Or choose min/max?
|
|
|
|
+ // maxCalculatedSize = size;
|
|
|
|
+ // }
|
|
|
|
+ // }
|
|
|
|
+ // #endregion Not Anchored and Are Not Dependent
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ // //#region Aligned
|
|
|
|
+
|
|
|
|
+ // //// Now, handle subviews that are aligned
|
|
|
|
+ // //// [x] PosAlign
|
|
|
|
+ // //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;
|
|
|
|
+ // // }
|
|
|
|
+ // // BUGBUG: ignores adornments
|
|
|
|
+
|
|
|
|
+ // // maxAlign = PosAlign.CalculateMinDimension (groupId, includedSubviews, dimension);
|
|
|
|
+ // // }
|
|
|
|
+ // //}
|
|
|
|
+ // //else
|
|
|
|
+ // //{
|
|
|
|
+ // // subviews = includedSubviews.Where (v => v.Y is PosAlign).ToList ();
|
|
|
|
+ // //}
|
|
|
|
+
|
|
|
|
+ // //subviewsSize = int.Max (subviewsSize, maxAlign);
|
|
|
|
+ // //#endregion Aligned
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ // #region Auto
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ // #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 ();
|
|
|
|
+ // //}
|
|
|
|
+
|
|
|
|
+ // //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;
|
|
|
|
+ // //}
|
|
|
|
+
|
|
|
|
+ // //subviewsSize += maxCenter;
|
|
|
|
+ // //#endregion Center
|
|
|
|
+
|
|
|
|
+ // #region Are Dependent
|
|
|
|
+ // // Now, go back to those that are dependent on content size
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ // // Set relative layout for all DimAuto subviews
|
|
|
|
+ // List<View> dimAutoSubViews;
|
|
|
|
+ // int maxAuto = 0;
|
|
|
|
+ // if (dimension == Dimension.Width)
|
|
|
|
+ // {
|
|
|
|
+ // dimAutoSubViews = includedSubviews.Where (v => v.Width is DimAuto).ToList ();
|
|
|
|
+ // }
|
|
|
|
+ // else
|
|
|
|
+ // {
|
|
|
|
+ // dimAutoSubViews = includedSubviews.Where (v => v.Height is DimAuto).ToList ();
|
|
|
|
+ // }
|
|
|
|
+ // for (var i = 0; i < dimAutoSubViews.Count; i++)
|
|
|
|
+ // {
|
|
|
|
+ // View v = dimAutoSubViews [i];
|
|
|
|
+
|
|
|
|
+ // if (dimension == Dimension.Width)
|
|
|
|
+ // {
|
|
|
|
+ // // BUGBUG: ignores adornments
|
|
|
|
|
|
- subviewsSize += maxFill;
|
|
|
|
- #endregion Are Dependent
|
|
|
|
|
|
+ // v.SetRelativeLayout (new Size (autoMax - maxCalculatedSize, 0));
|
|
|
|
+ // }
|
|
|
|
+ // else
|
|
|
|
+ // {
|
|
|
|
+ // // BUGBUG: ignores adornments
|
|
|
|
+
|
|
|
|
+ // v.SetRelativeLayout (new Size (0, autoMax - maxCalculatedSize));
|
|
|
|
+ // }
|
|
|
|
+
|
|
|
|
+ // maxAuto = dimension == Dimension.Width ? v.Frame.X + v.Frame.Width : v.Frame.Y + v.Frame.Height;
|
|
|
|
+
|
|
|
|
+ // if (maxAuto > maxCalculatedSize)
|
|
|
|
+ // {
|
|
|
|
+ // // BUGBUG: Should we break here? Or choose min/max?
|
|
|
|
+ // maxCalculatedSize = maxAuto;
|
|
|
|
+ // }
|
|
|
|
+ // }
|
|
|
|
+
|
|
|
|
+ // // [x] DimFill
|
|
|
|
+ // // [ ] DimPercent
|
|
|
|
+ // if (dimension == Dimension.Width)
|
|
|
|
+ // {
|
|
|
|
+ // subviews = includedSubviews.Where (v => v.Width is DimFill).ToList ();
|
|
|
|
+ // }
|
|
|
|
+ // else
|
|
|
|
+ // {
|
|
|
|
+ // subviews = includedSubviews.Where (v => v.Height is DimFill).ToList ();
|
|
|
|
+ // }
|
|
|
|
+
|
|
|
|
+ // int maxFill = 0;
|
|
|
|
+ // for (var i = 0; i < subviews.Count; i++)
|
|
|
|
+ // {
|
|
|
|
+ // View v = subviews [i];
|
|
|
|
+
|
|
|
|
+ // if (autoMax == int.MaxValue)
|
|
|
|
+ // {
|
|
|
|
+ // autoMax = superviewContentSize;
|
|
|
|
+ // }
|
|
|
|
+ // if (dimension == Dimension.Width)
|
|
|
|
+ // {
|
|
|
|
+ // // BUGBUG: ignores adornments
|
|
|
|
+ // v.SetRelativeLayout (new Size (autoMax - maxCalculatedSize, 0));
|
|
|
|
+ // }
|
|
|
|
+ // else
|
|
|
|
+ // {
|
|
|
|
+ // // BUGBUG: ignores adornments
|
|
|
|
+ // v.SetRelativeLayout (new Size (0, autoMax - maxCalculatedSize));
|
|
|
|
+ // }
|
|
|
|
+ // maxFill = dimension == Dimension.Width ? v.Frame.Width : v.Frame.Height;
|
|
|
|
+ // }
|
|
|
|
+
|
|
|
|
+ // maxCalculatedSize += maxFill;
|
|
|
|
+ // #endregion Are Dependent
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// All sizes here are content-relative; ignoring adornments.
|
|
// All sizes here are content-relative; ignoring adornments.
|
|
// We take the largest of text and content.
|
|
// We take the largest of text and content.
|
|
- int max = int.Max (textSize, subviewsSize);
|
|
|
|
|
|
+ int max = int.Max (textSize, maxCalculatedSize);
|
|
|
|
|
|
// And, if min: is set, it wins if larger
|
|
// And, if min: is set, it wins if larger
|
|
max = int.Max (max, autoMin);
|
|
max = int.Max (max, autoMin);
|
|
@@ -302,9 +567,24 @@ public class DimAuto () : Dim
|
|
// And, if max: is set, it wins if smaller
|
|
// And, if max: is set, it wins if smaller
|
|
max = int.Min (max, autoMax);
|
|
max = int.Min (max, autoMax);
|
|
|
|
|
|
|
|
+
|
|
|
|
+ // ************** We now definitively know `us.ContentSize` ***************
|
|
|
|
+
|
|
|
|
+ foreach (var v in us.Subviews)
|
|
|
|
+ {
|
|
|
|
+ if (dimension == Dimension.Width)
|
|
|
|
+ {
|
|
|
|
+ v.SetRelativeLayout (new Size (max, Application.Driver.Screen.Width));
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ v.SetRelativeLayout (new Size (Application.Driver.Screen.Height, max));
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
// Factor in adornments
|
|
// Factor in adornments
|
|
Thickness thickness = us.GetAdornmentsThickness ();
|
|
Thickness thickness = us.GetAdornmentsThickness ();
|
|
- max += dimension switch
|
|
|
|
|
|
+ var adornmentThickness = dimension switch
|
|
{
|
|
{
|
|
Dimension.Width => thickness.Horizontal,
|
|
Dimension.Width => thickness.Horizontal,
|
|
Dimension.Height => thickness.Vertical,
|
|
Dimension.Height => thickness.Vertical,
|
|
@@ -312,6 +592,8 @@ public class DimAuto () : Dim
|
|
_ => throw new ArgumentOutOfRangeException (nameof (dimension), dimension, null)
|
|
_ => throw new ArgumentOutOfRangeException (nameof (dimension), dimension, null)
|
|
};
|
|
};
|
|
|
|
|
|
|
|
+ max += adornmentThickness;
|
|
|
|
+
|
|
return max;
|
|
return max;
|
|
}
|
|
}
|
|
|
|
|