All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.mini2Dx.ui.layout.FlexDirection Maven / Gradle / Ivy

/*******************************************************************************
 * Copyright 2019 See AUTHORS file
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 ******************************************************************************/
package org.mini2Dx.ui.layout;

import org.mini2Dx.gdx.utils.Array;
import org.mini2Dx.ui.render.ParentRenderNode;
import org.mini2Dx.ui.render.RenderNode;

import org.mini2Dx.gdx.math.MathUtils;

/**
 * Controls the order of child elements
 */
public enum FlexDirection {
	/**
	 * Child elements are ordered left-to-right, top-to-bottom
	 */
	COLUMN {
		@Override
		public void layout(LayoutState layoutState, ParentRenderNode parentNode, Array> children) {
			float startX = parentNode.getStyle().getPaddingLeft();
			float startY = parentNode.getStyle().getPaddingTop();
			
			for (int i = 0; i < children.size; i++) {
				RenderNode node = children.get(i);
				node.layout(layoutState);
				if (!node.isIncludedInLayout()) {
					continue;
				}
				
				if(startX - parentNode.getStyle().getPaddingLeft() + node.getXOffset() + node.getPreferredOuterWidth() > parentNode.getPreferredContentWidth()) {
					float maxHeight = 0f;
					for (int j = i - 1; j >= 0; j--) {
						RenderNode previousNode = children.get(j);
						if (!previousNode.isIncludedInLayout()) {
							continue;
						}
						if (previousNode.getRelativeY() == startY + previousNode.getYOffset()) {
							float height = previousNode.getPreferredOuterHeight() + node.getYOffset();
							if (height > maxHeight) {
								maxHeight = height;
							}
						}
					}
					startY += maxHeight;
					startX = parentNode.getStyle().getPaddingLeft();
				}

				node.setRelativeX(startX + node.getXOffset());
				node.setRelativeY(startY + node.getYOffset());
				LayoutRuleset.setElementSize(parentNode, node);

				startX += node.getPreferredOuterWidth() + node.getXOffset();
			}
		}
	},
	/**
	 * Child elements are ordered right-to-left, top-to-bottom
	 */
	COLUMN_REVERSE {
		@Override
		public void layout(LayoutState layoutState, ParentRenderNode parentNode,
						   Array> children) {
			float startX = parentNode.getStyle().getPaddingLeft() + parentNode.getPreferredContentWidth();
			float startY = parentNode.getStyle().getPaddingTop();
			
			for (int i = 0; i < children.size; i++) {
				RenderNode node = children.get(i);
				node.layout(layoutState);
				if (!node.isIncludedInLayout()) {
					continue;
				}
				
				if(startX - parentNode.getStyle().getPaddingLeft() - node.getXOffset() - node.getPreferredOuterWidth() < 0f) {
					float maxHeight = 0f;
					for (int j = i - 1; j >= 0; j--) {
						RenderNode previousNode = children.get(j);
						if (!previousNode.isIncludedInLayout()) {
							continue;
						}
						if (previousNode.getRelativeY() == startY + previousNode.getYOffset()) {
							float height = previousNode.getPreferredOuterHeight() + node.getYOffset();
							if (height > maxHeight) {
								maxHeight = height;
							}
						}
					}
					startY += maxHeight;
					startX = parentNode.getStyle().getPaddingLeft() + parentNode.getPreferredContentWidth();
				}

				node.setRelativeX(startX - (node.getXOffset() + node.getPreferredOuterWidth()));
				node.setRelativeY(startY + node.getYOffset());

				LayoutRuleset.setElementSize(parentNode, node);
				startX -= node.getPreferredOuterWidth() + node.getXOffset();
			}
		}
	},
	/**
	 * Child elements are ordered top-to-bottom
	 */
	ROW {
		@Override
		public void layout(LayoutState layoutState, ParentRenderNode parentNode,
						   Array> children) {
			float startX = parentNode.getStyle().getPaddingLeft();
			float startY = parentNode.getStyle().getPaddingTop();
			
			for (int i = 0; i < children.size; i++) {
				RenderNode node = children.get(i);
				node.layout(layoutState);
				if (!node.isIncludedInLayout()) {
					continue;
				}

				node.setRelativeX(startX + node.getXOffset());
				node.setRelativeY(startY + node.getYOffset());
				LayoutRuleset.setElementSize(parentNode, node);
				startY += node.getPreferredOuterHeight() + node.getYOffset();
			}
		}
	},
	/**
	 * Child elements are ordered bottom-to-top
	 */
	ROW_REVERSE {
		@Override
		public void layout(LayoutState layoutState, ParentRenderNode parentNode,
						   Array> children) {
			final float startX = parentNode.getStyle().getPaddingLeft();
			if(parentNode.getLayoutRuleset().getCurrentHeightRule().isAutoSize()) {
				float startY = parentNode.getStyle().getPaddingTop();
				
				for (int i = children.size - 1; i >= 0; i--) {
					RenderNode node = children.get(i);
					node.layout(layoutState);
					if (!node.isIncludedInLayout()) {
						continue;
					}

					node.setRelativeX(startX + node.getXOffset());
					node.setRelativeY(startY + node.getYOffset());
					LayoutRuleset.setElementSize(parentNode, node);
					startY += node.getPreferredOuterHeight() + node.getYOffset();
				}
			} else {
				float startY = parentNode.getPreferredContentHeight();
				
				for (int i = 0; i < children.size; i++) {
					RenderNode node = children.get(i);
					node.layout(layoutState);
					if (!node.isIncludedInLayout()) {
						continue;
					}
					startY -= node.getPreferredOuterHeight() + node.getYOffset();

					node.setRelativeX(startX + node.getXOffset());
					node.setRelativeY(startY + node.getYOffset());
					LayoutRuleset.setElementSize(parentNode, node);
				}
			}
		}
	},
	/**
	 * Child elements are placed on top of each other in the center of the parent
	 */
	CENTER {
		@Override
		public void layout(LayoutState layoutState, final ParentRenderNode parentNode,
						   Array> children) {
			final float paddingLeft = parentNode.getStyle().getPaddingLeft();
			final float paddingRight = parentNode.getStyle().getPaddingRight();
			final float paddingTop = parentNode.getStyle().getPaddingTop();
			final float paddingBottom = parentNode.getStyle().getPaddingBottom();
			
			int maxHeight = 0;
			if(parentNode.getLayoutRuleset().getCurrentHeightRule().isAutoSize()) {
				for (int i = 0; i < children.size; i++) {
					RenderNode node = children.get(i);
					node.layout(layoutState);
					if (!node.isIncludedInLayout()) {
						continue;
					}
					if(node.getOuterRenderHeight() > maxHeight) {
						maxHeight = node.getOuterRenderHeight();
					}
				}
			} else {
				for (int i = 0; i < children.size; i++) {
					RenderNode node = children.get(i);
					node.layout(layoutState);
				}
				maxHeight = MathUtils.round(parentNode.getPreferredContentHeight());
			}
			
			int centerX = MathUtils.round((paddingLeft + paddingRight + parentNode.getPreferredContentWidth()) / 2f);
			int centerY = MathUtils.round((paddingTop + paddingBottom + maxHeight) / 2);
			for (int i = 0; i < children.size; i++) {
				final RenderNode node = children.get(i);
				if (!node.isIncludedInLayout()) {
					continue;
				}
				node.setRelativeX(centerX - (node.getXOffset() / 2f) - (node.getPreferredOuterWidth() / 2f));
				node.setRelativeY(centerY - (node.getYOffset() / 2f) - (node.getPreferredOuterHeight() / 2f));
				LayoutRuleset.setElementSize(parentNode, node);
			}
		}
	};
	
	/**
	 * Executes the layout of children inside a parent render node
	 * 
	 * @param layoutState The current {@link LayoutState}
	 * @param parentNode The parent render node
	 * @param children The children of the parent that require layout
	 */
	public abstract void layout(LayoutState layoutState, ParentRenderNode parentNode, Array> children);
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy