44import com .cleanroommc .modularui .api .layout .ILayoutWidget ;
55import com .cleanroommc .modularui .api .widget .IWidget ;
66import com .cleanroommc .modularui .utils .Alignment ;
7- import com .cleanroommc .modularui .widget .AbstractParentWidget ;
87import com .cleanroommc .modularui .widget .ParentWidget ;
98import com .cleanroommc .modularui .widget .sizer .Box ;
109
@@ -35,6 +34,10 @@ public static Flow column() {
3534 * Does not work with {@link Alignment.MainAxis#SPACE_BETWEEN} and {@link Alignment.MainAxis#SPACE_AROUND}.
3635 */
3736 private int spaceBetween = 0 ;
37+ /**
38+ * Whether disabled child widgets should be collapsed for display.
39+ */
40+ private boolean collapseDisabledChild = false ;
3841
3942 public Flow (GuiAxis axis ) {
4043 this .axis = axis ;
@@ -44,52 +47,54 @@ public Flow(GuiAxis axis) {
4447 @ Override
4548 public void layoutWidgets () {
4649 if (!hasChildren ()) return ;
47- boolean hasSize = resizer ().isSizeCalculated (this .axis );
48- int size = getArea ().getSize ( axis );
49- Box padding = getArea ().getPadding ( );
50+ final boolean hasSize = resizer ().isSizeCalculated (this .axis );
51+ final Box padding = getArea ().getPadding ( );
52+ final int size = getArea ().getSize ( axis ) - padding . getTotal ( this . axis );
5053 Alignment .MainAxis maa = this .maa ;
5154 if (!hasSize && maa != Alignment .MainAxis .START ) {
52- if (flex ().dependsOnChildren (axis )) {
53- maa = Alignment .MainAxis .START ;
54- } else {
55- throw new IllegalStateException ("Alignment.MainAxis other than start need the size to be calculated!" );
56- }
57- }
58- if (maa == Alignment .MainAxis .SPACE_BETWEEN && getChildren ().size () == 1 ) {
59- maa = Alignment .MainAxis .CENTER ;
55+ maa = Alignment .MainAxis .START ;
6056 }
6157 int space = this .spaceBetween ;
6258
63- int totalSize = 0 ;
59+ int childrenSize = 0 ;
6460 int expandedAmount = 0 ;
6561 int amount = 0 ;
6662
67- // calculate total size and maximum width
63+ // calculate total size
6864 for (IWidget widget : getChildren ()) {
69- // exclude self positioned (Y) children
65+ // ignore disabled child if configured as such
66+ if (shouldIgnoreChildSize (widget )) continue ;
67+ // exclude children whose position of main axis is fixed
7068 if (widget .flex ().hasPos (this .axis )) continue ;
7169 amount ++;
7270 if (widget .flex ().isExpanded ()) {
7371 expandedAmount ++;
74- totalSize += widget .getArea ().getMargin ().getTotal (this .axis );
72+ childrenSize += widget .getArea ().getMargin ().getTotal (this .axis );
7573 continue ;
7674 }
77- totalSize += widget .getArea ().requestedSize (this .axis );
75+ childrenSize += widget .getArea ().requestedSize (this .axis );
7876 }
7977
78+ if (amount <= 1 && maa == Alignment .MainAxis .SPACE_BETWEEN ) {
79+ maa = Alignment .MainAxis .CENTER ;
80+ }
81+ final int spaceCount = Math .max (amount - 1 , 0 );
82+
8083 if (maa == Alignment .MainAxis .SPACE_BETWEEN || maa == Alignment .MainAxis .SPACE_AROUND ) {
8184 if (expandedAmount > 0 ) {
8285 maa = Alignment .MainAxis .START ;
8386 } else {
8487 space = 0 ;
8588 }
8689 }
87- totalSize += space * ( getChildren (). size () - 1 ) ;
90+ childrenSize += space * spaceCount ;
8891
8992 if (expandedAmount > 0 && hasSize ) {
90- int newSize = (size - totalSize - padding . getTotal ( this . axis ) ) / expandedAmount ;
93+ int newSize = (size - childrenSize ) / expandedAmount ;
9194 for (IWidget widget : getChildren ()) {
92- // exclude self positioned (Y) children
95+ // ignore disabled child if configured as such
96+ if (shouldIgnoreChildSize (widget )) continue ;
97+ // exclude children whose position of main axis is fixed
9398 if (widget .flex ().hasPos (this .axis )) continue ;
9499 if (widget .flex ().isExpanded ()) {
95100 widget .getArea ().setSize (this .axis , newSize );
@@ -102,25 +107,27 @@ public void layoutWidgets() {
102107 int lastP = padding .getStart (this .axis );
103108 if (hasSize ) {
104109 if (maa == Alignment .MainAxis .CENTER ) {
105- lastP = (int ) (size / 2f - totalSize / 2f );
110+ lastP + = (int ) (size / 2f - childrenSize / 2f );
106111 } else if (maa == Alignment .MainAxis .END ) {
107- lastP = size - totalSize ;
112+ lastP + = size - childrenSize ;
108113 }
109114 }
110115
111116 for (IWidget widget : getChildren ()) {
112- // exclude self positioned (Y) children
117+ // ignore disabled child if configured as such
118+ if (shouldIgnoreChildSize (widget )) continue ;
119+ // exclude children whose position of main axis is fixed
113120 if (widget .flex ().hasPos (this .axis )) continue ;
114121 Box margin = widget .getArea ().getMargin ();
115122
116- // set calculated relative Y pos and set bottom margin for next widget
123+ // set calculated relative main axis pos and set end margin for next widget
117124 widget .getArea ().setRelativePoint (this .axis , lastP + margin .getStart (this .axis ));
118125 widget .resizer ().setPosResized (this .axis , true );
119126 widget .resizer ().setMarginPaddingApplied (this .axis , true );
120127
121128 lastP += widget .getArea ().requestedSize (this .axis ) + space ;
122129 if (hasSize && maa == Alignment .MainAxis .SPACE_BETWEEN ) {
123- lastP += (size - totalSize ) / ( getChildren (). size () - 1 ) ;
130+ lastP += (size - childrenSize ) / spaceCount ;
124131 }
125132 }
126133 }
@@ -132,26 +139,31 @@ public void postLayoutWidgets() {
132139 Box padding = getArea ().getPadding ();
133140 boolean hasWidth = resizer ().isSizeCalculated (other );
134141 for (IWidget widget : getChildren ()) {
135- // exclude self positioned (Y) children
142+ // exclude children whose position of main axis is fixed
136143 if (widget .flex ().hasPos (this .axis )) continue ;
137144 Box margin = widget .getArea ().getMargin ();
138- // don't align auto positioned (X) children in X
145+ // don't align auto positioned children in cross axis
139146 if (!widget .flex ().hasPos (other ) && widget .resizer ().isSizeCalculated (other )) {
140- int x = margin .getStart (other ) + padding .getStart (other );
147+ int crossAxisPos = margin .getStart (other ) + padding .getStart (other );
141148 if (hasWidth ) {
142149 if (this .caa == Alignment .CrossAxis .CENTER ) {
143- x = (int ) (width / 2f - widget .getArea ().getSize (other ) / 2f );
150+ crossAxisPos = (int ) (width / 2f - widget .getArea ().getSize (other ) / 2f );
144151 } else if (this .caa == Alignment .CrossAxis .END ) {
145- x = width - widget .getArea ().getSize (other ) - margin .getEnd (other ) - padding .getStart (other );
152+ crossAxisPos = width - widget .getArea ().getSize (other ) - margin .getEnd (other ) - padding .getStart (other );
146153 }
147154 }
148- widget .getArea ().setRelativePoint (other , x );
155+ widget .getArea ().setRelativePoint (other , crossAxisPos );
149156 widget .resizer ().setPosResized (other , true );
150157 widget .resizer ().setMarginPaddingApplied (other , true );
151158 }
152159 }
153160 }
154161
162+ @ Override
163+ public boolean shouldIgnoreChildSize (IWidget child ) {
164+ return this .collapseDisabledChild && !child .isEnabled ();
165+ }
166+
155167 public Flow crossAxisAlignment (Alignment .CrossAxis caa ) {
156168 this .caa = caa ;
157169 return this ;
@@ -167,6 +179,14 @@ public Flow childPadding(int spaceBetween) {
167179 return this ;
168180 }
169181
182+ /**
183+ * Configures this widget to collapse disabled child widgets.
184+ */
185+ public Flow collapseDisabledChild () {
186+ this .collapseDisabledChild = true ;
187+ return this ;
188+ }
189+
170190 public GuiAxis getAxis () {
171191 return axis ;
172192 }
0 commit comments