Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes #1785. Adds Pos.Align - Align sets of views horizontally or vertically #3415

Merged
merged 187 commits into from
May 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
187 commits
Select commit Hold shift + click to select a range
4ed5ed8
Initial commit. Just a prototype
tig Apr 17, 2024
f2a16dc
Added Justifier class with robust unit tests
tig Apr 19, 2024
bb16808
Merge branch 'v2_develop' into v2_1785-PosJustify
tig Apr 19, 2024
48cf0db
Working on Centered
tig Apr 19, 2024
292ebfb
WIP
tig Apr 21, 2024
3f71592
Finished Justifier
tig Apr 21, 2024
13134df
Prototype Pos.Justify
tig Apr 21, 2024
1c26307
Prototype Pos.Justify 2
tig Apr 21, 2024
44cc57b
Rebased onto dim.auto
tig Apr 21, 2024
ba59cfc
Prototype basically works. Not idea - needs work.
tig Apr 21, 2024
745af27
totalSize -> containerSize
tig Apr 21, 2024
7cb9d3e
Odd dlg thing
tig Apr 21, 2024
f132281
Support items wider than containerSize
tig Apr 21, 2024
04f75dc
Merge branch 'v2_1785-PosJustify' of tig:tig/Terminal.Gui into v2_178…
tig Apr 21, 2024
a89ffaf
Messing with Pos.Justify
tig Apr 21, 2024
3585e92
Put error handling code in sep method.
tig Apr 22, 2024
4b4c3ae
Code cleanup
tig Apr 22, 2024
c9830de
Got Dialog working. AnchorEnd has a bug
tig Apr 22, 2024
bf15da3
Code cleanup
tig Apr 22, 2024
7fc4f5a
Aded PosJusityf scenario . fixed issues. WIP
tig Apr 22, 2024
cb678f3
Merge branch 'v2_develop' of tig:gui-cs/Terminal.Gui into v2_develop
tig Apr 27, 2024
bb37689
rebased and fixed
tig May 9, 2024
467c745
Tweaks
tig May 9, 2024
ee4d526
Tweaks
tig May 9, 2024
a8ebb5b
Added property change notification to Justifyer
tig May 9, 2024
34f591d
Merge branch 'v2_1785-PosJustify' of tig:tig/Terminal.Gui into v2_178…
tig May 9, 2024
64b3554
Added 3x3 demo
tig May 9, 2024
a19b024
Unit test issue
tig May 10, 2024
cd104e9
Dialog/MessageBox use new Justifier
tig May 10, 2024
147fdb4
Removed dead code from Dialog
tig May 10, 2024
831eecb
Default button just is now Right
tig May 10, 2024
c84dade
WIP -> Getting rid of old TextAlignment enums
tig May 10, 2024
37073d2
Alignment->Justification
tig May 10, 2024
40f72db
Alignment->Justification
tig May 10, 2024
7bf2bf4
more Alignment->Justification
tig May 10, 2024
0df5133
Updated docs
tig May 10, 2024
c5a6c90
Justifier->Aligner
tig May 10, 2024
ce1e243
Justification->Alignment
tig May 10, 2024
c595e40
text in Dialogs
tig May 10, 2024
26a4601
Added Pos.Align unit tests (scaffolding)
tig May 10, 2024
dba6221
Merge branch 'v2_develop' into v2_1785-PosJustify
tig May 10, 2024
2ea438c
Tweaked Wizard
tig May 10, 2024
b75bfb2
Updated ProgressBarstyles to use vertical alignment
tig May 10, 2024
175c2fc
Changed Alignment enum to have distinct values. Updated related code.
tig May 11, 2024
5f96f8a
Alignment round trip unit test
tig May 11, 2024
3dd34ee
Improved API docs
tig May 11, 2024
a138ad8
PosDim code clean up and APIU doc improvements
tig May 11, 2024
ff2d579
Dim code clean up and APIU doc improvements
tig May 11, 2024
56cd7b0
Dim code cleanup - fix warnings
tig May 11, 2024
cd2df54
Fix warnings
tig May 11, 2024
630dd56
Dialogs scenario upgrade
tig May 11, 2024
a59c44d
Rebased latest
tig May 11, 2024
bea82a2
Identified and worked around Issue #3469
tig May 11, 2024
bc40c9d
Partial fix
tig May 13, 2024
ce28b2a
WIP fixing 3469
tig May 13, 2024
65caf28
Merge branch 'v2_develop' of tig:gui-cs/Terminal.Gui into v2_develop
tig May 13, 2024
a8b9ddb
Partial fix
tig May 13, 2024
ba4139f
WIP fixing 3469
tig May 13, 2024
c8690af
Fixed AnchorEnd issue
tig May 13, 2024
4e01779
Moved AutoSizeTrue tests to more logical locations; nuked invalid tests
tig May 13, 2024
e28b12e
Moved AutoSizeFalse tests to more logical locations; nuked invalid tests
tig May 13, 2024
c80f606
Moved AutoSizeFalse tests to more logical locations; nuked invalid te…
tig May 13, 2024
922d3cb
Moved up TextTests.cs
tig May 13, 2024
ef9ee5a
Checkbox now uses DimAuto for Height
tig May 13, 2024
d27b0b6
Added // BUGBUG: Views should avoid setting Height as doing so implie…
tig May 13, 2024
7786938
Fixed ProgressBar to not set Height
tig May 13, 2024
36b9171
Removed ContentSize setter, replaced with SetContentSize
tig May 13, 2024
a5eca55
Removed nullable from ContentSize
tig May 13, 2024
82e681c
Clarified what dimauot min/max mean.
tig May 14, 2024
070d31d
Modernized RadioGroup to use Dim.Auto.
tig May 14, 2024
e6f883b
Modernized RadioGroup to use Dim.Auto.
tig May 14, 2024
05935f7
Fixed checkbox dependency on internal API
tig May 14, 2024
67f6ea8
Broke Pos & Dim out to separate .cs files
tig May 14, 2024
3e287c4
Moved PosXXX to not be nested classes
tig May 14, 2024
e28f73f
Pos / Dim code cleanup
tig May 14, 2024
d9abfc7
Updated migration doc
tig May 14, 2024
1c01556
PosAbsoulte to public.
tig May 15, 2024
90c8f83
PosAnchorEnd now public
tig May 15, 2024
8d4f706
PosCenter -> public
tig May 15, 2024
746e8e6
PosCombine -> public
tig May 15, 2024
dbd575e
PosFactor -> PosPercent (for consistency) and -> public
tig May 15, 2024
643f2a7
PosFunc -> public
tig May 15, 2024
6994bf3
PosView -> public
tig May 15, 2024
d6e641e
DimAbsolute -> public
tig May 15, 2024
c26e62f
DimAuto -> public
tig May 15, 2024
2c4fd4a
DimCombine -> public
tig May 15, 2024
3d2e8d9
DimFactor -> PosPercent -> public
tig May 15, 2024
b69d3ea
DimFill -> public
tig May 15, 2024
07ac849
DimFunc -> public
tig May 15, 2024
560a573
DimView -> public
tig May 15, 2024
65cbb06
Added API docs indicating low-level nature of pos/dom classes
tig May 15, 2024
71e1d99
Fixed all views tester unit test
tig May 15, 2024
08199f8
Fixed spelling error
tig May 15, 2024
d2e2499
Dim.Sized -> Dim.Absolute
tig May 15, 2024
a5609cc
Fixed Factor->Percent issue
tig May 15, 2024
7bfefd2
Rebased with #3480
tig May 15, 2024
12f5bde
fixed dialog
tig May 15, 2024
f0865e8
TextField modernization
tig May 15, 2024
d21489c
TextView modernization
tig May 15, 2024
11da4cf
DatePicker now uses DimAuto with caveats
tig May 15, 2024
a4bb63a
LineView uses DimAuto
tig May 15, 2024
6bc5ac4
Code cleanup
tig May 15, 2024
617960d
Spinner upgrade
tig May 15, 2024
9766ee0
Removed bad Checkbox code.
tig May 15, 2024
e4e3804
UICatalog Category list use dimauto
tig May 15, 2024
87a7666
Fixed broken unit tests.
tig May 15, 2024
c738d2b
Tweaked validation logic
tig May 15, 2024
63b60e2
Upgrade Dialogs scenario
tig May 15, 2024
edeb11e
Tweaked validation logic
tig May 15, 2024
6cdb4c4
Code cleanup
tig May 15, 2024
0b969d9
Revamped Slider - Make it a showcase for how to build a View that use…
tig May 16, 2024
ace119e
Fixed unit tests after changing defining of DimAuto 'min:'
tig May 16, 2024
6e640ef
Rebased with #3480
tig May 16, 2024
358acc6
Fixed bug in Adornments editor
tig May 16, 2024
c12c206
Pos API Doc improvements and code cleanup
tig May 16, 2024
80d9a97
Renamed Dim.Function->Func to align iwth C# Func type.
tig May 16, 2024
f7b75cd
Renamed Dim.Function->Func moar
tig May 16, 2024
00daccf
Renamed Pos.Function->Func to align iwth C# Func type.
tig May 16, 2024
d05544b
Dim API Doc improvements and code cleanup
tig May 16, 2024
f5abf3d
Broke out PosAbsoulte tests. Test reorg
tig May 16, 2024
9000ad9
Broke out PosAbsoulte tests. Test reorg
tig May 16, 2024
c473d80
Broke out PosView tests.
tig May 16, 2024
aa1b5ed
Broke out DimView tests.
tig May 16, 2024
ec36787
Revamped Slider - fixed multiple issues
tig May 16, 2024
fb96ea0
Commented diag code
tig May 16, 2024
02593ae
Slider code cleanup
tig May 16, 2024
327a8ff
Updated developer docs
tig May 16, 2024
c372c06
Fixed mouse scenario
tig May 16, 2024
01c30ef
WIP: Fixing MessagBox to use Dim.Auto
tig May 17, 2024
5cebe96
WIP: Fixing MessagBox to use Dim.Auto - Disabled some tests
tig May 17, 2024
1129fd4
Added =0 to enum
tig May 17, 2024
dc614f5
Addressed warning
tig May 17, 2024
334f7fa
fixed nullability
tig May 17, 2024
44e496d
Anchor -> GetAnchor
tig May 17, 2024
c035426
Pos & Dim -> abstract
tig May 17, 2024
a89db3c
Removed Equal/GetHashCode from base classes
tig May 17, 2024
40e0d87
Removed unnecesary comment
tig May 17, 2024
3d92acd
DimAuto.Equals readability
tig May 17, 2024
61ccc5b
Simplified DimAuto.GetHashCode
tig May 17, 2024
59201cf
Fixed comments
tig May 17, 2024
084c735
DimAuto -> use required on properties
tig May 17, 2024
27a347e
Use switch
tig May 17, 2024
d4d2c92
Pos/DimCombine now use AddOrSubtract enum instead of bool
tig May 17, 2024
d151267
AddOrSubtract.cs (one type per file!) <g>
tig May 17, 2024
18f2ee3
One type per file!
tig May 17, 2024
7ac767a
Layout/View.cs back to ViewLayout.cs
tig May 17, 2024
7ece3bc
Inlined code
tig May 17, 2024
dfc8c01
DimPercent -> int vs. float
tig May 17, 2024
8969127
PosPercent -> int vs. float
tig May 17, 2024
61c9b5c
DimPercentMode vs UsePosition
tig May 17, 2024
01a4de6
xml doc tweak
tig May 17, 2024
b1aa34b
backported XML doc fix from #3451
tig May 17, 2024
38a92ad
Added = 0 to enum
tig May 17, 2024
f361746
ProgressBarStyle fix.
tig May 17, 2024
ddd7e27
Merge/rebase with #3480
tig May 17, 2024
a355f34
Merged
tig May 17, 2024
b64f10c
Slider - one type per file
tig May 17, 2024
e0c07c1
Aligner - one type per file
tig May 17, 2024
a7cb676
API doc fix
tig May 17, 2024
a70d87e
Cleanup
tig May 17, 2024
8906bec
Modernized AllViewsTester
tig May 17, 2024
354d02d
DatePicker tweaks
tig May 18, 2024
c877c18
Simplified Alignment enum
tig May 18, 2024
7be2104
Added FlowModes enum
tig May 18, 2024
dabb106
Refactor to simplify
tig May 19, 2024
fde6bfd
Revamped scenarios to demo Pos.Align
tig May 19, 2024
d4ee1b0
Fixed Dialog/Messagebox issues
tig May 19, 2024
6785828
Aligner code cleanup
tig May 19, 2024
0c7f97c
Made methods internal for unit testing
tig May 20, 2024
dfda16c
Claned up TF scenario
tig May 20, 2024
e966125
Claned up TF scenario
tig May 20, 2024
f21d525
fixed center issue - if contentsize is too small, pos can be negative
tig May 20, 2024
c7039a6
Removed debug code.
tig May 22, 2024
0a60ce3
Added [GenerateEnumExtensionMethods] to all Layout enums
tig May 22, 2024
675ef57
ViewportSettings enum to sep file
tig May 22, 2024
6df35c0
Code cleanup
tig May 22, 2024
f08f9c9
Fixed FastFlags thing
tig May 23, 2024
1cfa2de
Merge pull request #3480 from tig/v2_3469-DimAuto-Absolute
tig May 23, 2024
4ba8f04
Rebased with v2_develop
tig May 23, 2024
bbb3174
Adjusted unit tests
tig May 23, 2024
408d41a
Made default for Aligner to not add spaces
tig May 23, 2024
86139e1
Enabled EndToStart.
tig May 23, 2024
f6e5caf
AlignmentModes -> GenerateEnumExtensionMethods
tig May 23, 2024
e59311b
Fixed EndToStart issues
tig May 23, 2024
b3c008d
Added constructor->Initalizere topic to upgrade guide
tig May 23, 2024
113f788
Fixed conceptual docs links
tig May 23, 2024
671fdea
Fixed a slew of Dim.Auto(Content) issues preventing Pos.Align to work…
tig May 23, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
369 changes: 369 additions & 0 deletions Terminal.Gui/Drawing/Aligner.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,369 @@
using System.ComponentModel;

namespace Terminal.Gui;

/// <summary>
/// Aligns items within a container based on the specified <see cref="Gui.Alignment"/>. Both horizontal and vertical
/// alignments are supported.
/// </summary>
public class Aligner : INotifyPropertyChanged
{
private Alignment _alignment;

/// <summary>
/// Gets or sets how the <see cref="Aligner"/> aligns items within a container.
/// </summary>
/// <remarks>
/// <para>
/// <see cref="AlignmentModes"/> provides additional options for aligning items in a container.
/// </para>
/// </remarks>
public Alignment Alignment
{
get => _alignment;
set
{
_alignment = value;
PropertyChanged?.Invoke (this, new (nameof (Alignment)));
}
}

private AlignmentModes _alignmentMode = AlignmentModes.StartToEnd;

/// <summary>
/// Gets or sets the modes controlling <see cref="Alignment"/>.
/// </summary>
public AlignmentModes AlignmentModes
{
get => _alignmentMode;
set
{
_alignmentMode = value;
PropertyChanged?.Invoke (this, new (nameof (AlignmentModes)));
}
}

private int _containerSize;

/// <summary>
/// The size of the container.
/// </summary>
public int ContainerSize
{
get => _containerSize;
set
{
_containerSize = value;
PropertyChanged?.Invoke (this, new (nameof (ContainerSize)));
}
}

/// <inheritdoc/>
public event PropertyChangedEventHandler PropertyChanged;

/// <summary>
/// Takes a list of item sizes and returns a list of the positions of those items when aligned within
/// <see name="ContainerSize"/>
/// using the <see cref="Alignment"/> and <see cref="AlignmentModes"/> settings.
/// </summary>
/// <param name="sizes">The sizes of the items to align.</param>
/// <returns>The locations of the items, from left/top to right/bottom.</returns>
public int [] Align (int [] sizes) { return Align (Alignment, AlignmentModes, ContainerSize, sizes); }

/// <summary>
/// Takes a list of item sizes and returns a list of the positions of those items when aligned within
/// <paramref name="containerSize"/>
/// using specified parameters.
/// </summary>
/// <param name="alignment">Specifies how the items will be aligned.</param>
/// <param name="alignmentMode"></param>
/// <param name="containerSize">The size of the container.</param>
/// <param name="sizes">The sizes of the items to align.</param>
/// <returns>The positions of the items, from left/top to right/bottom.</returns>
public static int [] Align (in Alignment alignment, in AlignmentModes alignmentMode, in int containerSize, in int [] sizes)
{
if (sizes.Length == 0)
{
return [];
}

var sizesCopy = sizes;
if (alignmentMode.FastHasFlags (AlignmentModes.EndToStart))
{
sizesCopy = sizes.Reverse ().ToArray ();
}

int maxSpaceBetweenItems = alignmentMode.FastHasFlags (AlignmentModes.AddSpaceBetweenItems) ? 1 : 0;
int totalItemsSize = sizes.Sum ();
int totalGaps = sizes.Length - 1; // total gaps between items
int totalItemsAndSpaces = totalItemsSize + totalGaps * maxSpaceBetweenItems; // total size of items and spacesToGive if we had enough room
int spacesToGive = totalGaps * maxSpaceBetweenItems; // We'll decrement this below to place one space between each item until we run out

if (totalItemsSize >= containerSize)
{
spacesToGive = 0;
}
else if (totalItemsAndSpaces > containerSize)
{
spacesToGive = containerSize - totalItemsSize;
}

switch (alignment)
{
case Alignment.Start:
switch (alignmentMode & ~AlignmentModes.AddSpaceBetweenItems)
{
case AlignmentModes.StartToEnd:
return Start (in sizesCopy, maxSpaceBetweenItems, spacesToGive);

case AlignmentModes.StartToEnd | AlignmentModes.IgnoreFirstOrLast:
return IgnoreLast (in sizesCopy, containerSize, totalItemsSize, maxSpaceBetweenItems, spacesToGive);

case AlignmentModes.EndToStart:
return End (in sizesCopy, containerSize, totalItemsSize, maxSpaceBetweenItems, spacesToGive).Reverse ().ToArray ();

case AlignmentModes.EndToStart | AlignmentModes.IgnoreFirstOrLast:
return IgnoreFirst (in sizesCopy, containerSize, totalItemsSize, maxSpaceBetweenItems, spacesToGive).Reverse ().ToArray (); ;
}

break;

case Alignment.End:
switch (alignmentMode & ~AlignmentModes.AddSpaceBetweenItems)
{
case AlignmentModes.StartToEnd:
return End (in sizesCopy, containerSize, totalItemsSize, maxSpaceBetweenItems, spacesToGive);

case AlignmentModes.StartToEnd | AlignmentModes.IgnoreFirstOrLast:
return IgnoreFirst (in sizesCopy, containerSize, totalItemsSize, maxSpaceBetweenItems, spacesToGive);

case AlignmentModes.EndToStart:
return Start (in sizesCopy, maxSpaceBetweenItems, spacesToGive).Reverse ().ToArray ();

case AlignmentModes.EndToStart | AlignmentModes.IgnoreFirstOrLast:
return IgnoreLast (in sizesCopy, containerSize, totalItemsSize, maxSpaceBetweenItems, spacesToGive).Reverse ().ToArray (); ;
}

break;

case Alignment.Center:
switch (alignmentMode & ~AlignmentModes.AddSpaceBetweenItems)
{
case AlignmentModes.StartToEnd:
return Center (in sizesCopy, containerSize, totalItemsSize, maxSpaceBetweenItems, spacesToGive);

case AlignmentModes.EndToStart:
return Center (in sizesCopy, containerSize, totalItemsSize, maxSpaceBetweenItems, spacesToGive).Reverse ().ToArray ();
}

break;

case Alignment.Fill:
switch (alignmentMode & ~AlignmentModes.AddSpaceBetweenItems)
{
case AlignmentModes.StartToEnd:
return Fill (in sizesCopy, containerSize, totalItemsSize);

case AlignmentModes.EndToStart:
return Fill (in sizesCopy, containerSize, totalItemsSize).Reverse ().ToArray ();
}

break;

default:
throw new ArgumentOutOfRangeException (nameof (alignment), alignment, null);
}

return [];
}

internal static int [] Start (ref readonly int [] sizes, int maxSpaceBetweenItems, int spacesToGive)
{
var positions = new int [sizes.Length]; // positions of the items. the return value.

for (var i = 0; i < sizes.Length; i++)
{
CheckSizeCannotBeNegative (i, in sizes);
tig marked this conversation as resolved.
Show resolved Hide resolved

if (i == 0)
{
positions [0] = 0; // first item position

continue;
}

int spaceBefore = spacesToGive-- > 0 ? maxSpaceBetweenItems : 0;

// subsequent items are placed one space after the previous item
positions [i] = positions [i - 1] + sizes [i - 1] + spaceBefore;
}

return positions;
}

internal static int [] IgnoreFirst (
ref readonly int [] sizes,
int containerSize,
int totalItemsSize,
int maxSpaceBetweenItems,
int spacesToGive
)
{
var positions = new int [sizes.Length]; // positions of the items. the return value.

if (sizes.Length > 1)
{
var currentPosition = 0;
positions [0] = currentPosition; // first item is flush left

for (int i = sizes.Length - 1; i >= 0; i--)
{
CheckSizeCannotBeNegative (i, in sizes);

if (i == sizes.Length - 1)
{
// start at right
currentPosition = Math.Max (totalItemsSize, containerSize) - sizes [i];
positions [i] = currentPosition;
}

if (i < sizes.Length - 1 && i > 0)
{
int spaceBefore = spacesToGive-- > 0 ? maxSpaceBetweenItems : 0;

positions [i] = currentPosition - sizes [i] - spaceBefore;
currentPosition = positions [i];
}
}
}
else if (sizes.Length == 1)
{
CheckSizeCannotBeNegative (0, in sizes);
positions [0] = 0; // single item is flush left
}

return positions;
}

internal static int [] IgnoreLast (
ref readonly int [] sizes,
int containerSize,
int totalItemsSize,
int maxSpaceBetweenItems,
int spacesToGive
)
{
var positions = new int [sizes.Length]; // positions of the items. the return value.

if (sizes.Length > 1)
{
var currentPosition = 0;
if (totalItemsSize > containerSize)
{
currentPosition = containerSize - totalItemsSize - spacesToGive;
}

for (var i = 0; i < sizes.Length; i++)
{
CheckSizeCannotBeNegative (i, in sizes);

if (i < sizes.Length - 1)
{
int spaceBefore = spacesToGive-- > 0 ? maxSpaceBetweenItems : 0;

positions [i] = currentPosition;
currentPosition += sizes [i] + spaceBefore;
}
}

positions [sizes.Length - 1] = containerSize - sizes [^1];
}
else if (sizes.Length == 1)
{
CheckSizeCannotBeNegative (0, in sizes);

positions [0] = containerSize - sizes [0]; // single item is flush right
}

return positions;
}

internal static int [] Fill (ref readonly int [] sizes, int containerSize, int totalItemsSize)
{
var positions = new int [sizes.Length]; // positions of the items. the return value.

int spaceBetween = sizes.Length > 1 ? (containerSize - totalItemsSize) / (sizes.Length - 1) : 0;
int remainder = sizes.Length > 1 ? (containerSize - totalItemsSize) % (sizes.Length - 1) : 0;
var currentPosition = 0;

for (var i = 0; i < sizes.Length; i++)
{
CheckSizeCannotBeNegative (i, in sizes);
positions [i] = currentPosition;
int extraSpace = i < remainder ? 1 : 0;
currentPosition += sizes [i] + spaceBetween + extraSpace;
}

return positions;
}

internal static int [] Center (ref readonly int [] sizes, int containerSize, int totalItemsSize, int maxSpaceBetweenItems, int spacesToGive)
{
var positions = new int [sizes.Length]; // positions of the items. the return value.

if (sizes.Length > 1)
{
// remaining space to be distributed before first and after the items
int remainingSpace = containerSize - totalItemsSize - spacesToGive;

for (var i = 0; i < sizes.Length; i++)
{
CheckSizeCannotBeNegative (i, in sizes);

if (i == 0)
{
positions [i] = remainingSpace / 2; // first item position

continue;
}

int spaceBefore = spacesToGive-- > 0 ? maxSpaceBetweenItems : 0;

// subsequent items are placed one space after the previous item
positions [i] = positions [i - 1] + sizes [i - 1] + spaceBefore;
}
}
else if (sizes.Length == 1)
{
CheckSizeCannotBeNegative (0, in sizes);
positions [0] = (containerSize - sizes [0]) / 2; // single item is centered
}

return positions;
}

internal static int [] End (ref readonly int [] sizes, int containerSize, int totalItemsSize, int maxSpaceBetweenItems, int spacesToGive)
{
var positions = new int [sizes.Length]; // positions of the items. the return value.
int currentPosition = containerSize - totalItemsSize - spacesToGive;

for (var i = 0; i < sizes.Length; i++)
{
CheckSizeCannotBeNegative (i, in sizes);
int spaceBefore = spacesToGive-- > 0 ? maxSpaceBetweenItems : 0;

positions [i] = currentPosition;
currentPosition += sizes [i] + spaceBefore;
}

return positions;
}

private static void CheckSizeCannotBeNegative (int i, ref readonly int [] sizes)
tig marked this conversation as resolved.
Show resolved Hide resolved
{
if (sizes [i] < 0)
{
throw new ArgumentException ("The size of an item cannot be negative.");
}
}
}
Loading
Loading