Files
Terminal.Gui/Terminal.Gui/ViewBase/Layout/PosCombine.cs
Copilot b43390a070 Fixes #4677 - Refactors DimAuto for less coupling and improves performance (#4678)
* Phase 5: Add IsFixed and RequiresTargetLayout categorization properties

Co-authored-by: tig <585482+tig@users.noreply.github.com>

* Further simplify DimAuto.Calculate using IsFixed property

Co-authored-by: tig <585482+tig@users.noreply.github.com>

* Refactor for-loops to foreach and clarify DimFill logic

Refactored multiple for-loops iterating over view lists to use foreach loops for improved readability and reduced boilerplate. Removed unused variables such as viewsNeedingLayout and index counters. Clarified DimFill handling by continuing early if the DimFill is not valid or lacks a To property, reducing nesting and improving intent. Made minor formatting and code style improvements for consistency.

* Refactor subview filtering and sizing logic

Refactored repeated LINQ queries for subview filtering into reusable helper methods (`GetViewsThatMatch`, `GetViewsThatHavePos<TPos>`, `GetViewsThatHaveDim<TDim>`), reducing duplication and improving readability. Moved max content size calculations for various subview types into new helper methods (`GetMaxSizePos<TPos>`, `GetMaxSizeDim<TDim>`). Updated main logic to use these helpers. Adornment thickness calculation now uses a switch expression. These changes improve modularity and maintainability.

* Refactor subview categorization for layout calculation

Refactored layout calculation to use a single-pass CategorizeSubViews method, grouping subviews by relevant Pos/Dim types into a new CategorizedViews struct. This replaces multiple helper methods and reduces redundant iterations. Updated main logic to use these categorized lists, and unified size calculation helpers to further reduce code duplication. Improves performance and maintainability by consolidating subview processing and removing obsolete methods.

* Revert perf POC commits and add missing overrides to Combine types

Co-authored-by: tig <585482+tig@users.noreply.github.com>

* Add helper methods and simplify DimAuto.Calculate with foreach loops

Co-authored-by: tig <585482+tig@users.noreply.github.com>

* Refactor layout calculation in DimAuto.cs

Removed commented-out code and unnecessary list declarations to clean up the layout calculation logic.

* removed old plan file

* Code cleanup

* Add performance analysis and improvement plan for DimAuto.Calculate

Co-authored-by: tig <585482+tig@users.noreply.github.com>

* Add DimAuto benchmarks and benchmark documentation

Co-authored-by: tig <585482+tig@users.noreply.github.com>

* Implement Phase 1 & 2 performance optimizations for DimAuto.Calculate

Co-authored-by: tig <585482+tig@users.noreply.github.com>

* Code cleanup

* Delete plans/dimauto-perf-plan.md

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: tig <585482+tig@users.noreply.github.com>
Co-authored-by: Tig <tig@users.noreply.github.com>
2026-02-06 12:33:47 -07:00

98 lines
2.9 KiB
C#

namespace Terminal.Gui.ViewBase;
/// <summary>
/// Represents a position that is a combination of two other positions.
/// </summary>
/// <remarks>
/// <para>
/// This is a low-level API that is typically used internally by the layout system. Use the various static
/// methods on the <see cref="Pos"/> class to create <see cref="Pos"/> objects instead.
/// </para>
/// </remarks>
/// <param name="Add">
/// Indicates whether the two positions are added or subtracted.
/// </param>
/// <param name="Left">The left position.</param>
/// <param name="Right">The right position.</param>
public record PosCombine (AddOrSubtract Add, Pos Left, Pos Right) : Pos
{
/// <summary>
/// Gets whether the two positions are added or subtracted.
/// </summary>
public AddOrSubtract Add { get; } = Add;
/// <summary>
/// Gets the left position.
/// </summary>
public new Pos Left { get; } = Left;
/// <summary>
/// Gets the right position.
/// </summary>
public new Pos Right { get; } = Right;
/// <inheritdoc/>
public override string ToString () => $"Combine({Left}{(Add == AddOrSubtract.Add ? '+' : '-')}{Right})";
internal override int GetAnchor (int size)
{
if (Add == AddOrSubtract.Add)
{
return Left.GetAnchor (size) + Right.GetAnchor (size);
}
return Left.GetAnchor (size) - Right.GetAnchor (size);
}
internal override int Calculate (int superviewDimension, Dim dim, View us, Dimension dimension)
{
if (Add == AddOrSubtract.Add)
{
return Left.Calculate (superviewDimension, dim, us, dimension) + Right.Calculate (superviewDimension, dim, us, dimension);
}
return Left.Calculate (superviewDimension, dim, us, dimension) - Right.Calculate (superviewDimension, dim, us, dimension);
}
internal override bool ReferencesOtherViews ()
{
if (Left.ReferencesOtherViews ())
{
return true;
}
if (Right.ReferencesOtherViews ())
{
return true;
}
return false;
}
/// <inheritdoc/>
internal override IEnumerable<View> GetReferencedViews ()
{
foreach (View view in Left.GetReferencedViews ())
{
yield return view;
}
foreach (View view in Right.GetReferencedViews ())
{
yield return view;
}
}
/// <inheritdoc/>
internal override bool DependsOnSuperViewContentSize => Left.DependsOnSuperViewContentSize || Right.DependsOnSuperViewContentSize;
/// <inheritdoc/>
internal override bool IsFixed => Left.IsFixed && Right.IsFixed;
/// <inheritdoc/>
internal override bool RequiresTargetLayout => Left.RequiresTargetLayout || Right.RequiresTargetLayout;
/// <inheritdoc/>
protected override bool HasInner<TPos> (out TPos pos) => Left.Has (out pos) || Right.Has (out pos);
}