internal static void AlignChildren(this CogaNode node) { if (node.Compute.Position.IsResolved() == false) { return; } switch (node.NodeConfiguration.Alignment) { case CogaAlign.Default: AlignFlexStart(node); break; case CogaAlign.FlexStart: AlignFlexStart(node); break; case CogaAlign.FlexEnd: AlignFlexEnd(node); break; case CogaAlign.Center: AlignCenter(node); break; default: AlignFlexStart(node); break; } }
internal static void LayoutChildren(this CogaNode node) { if (node.NeedsLayout == false || node.GetIsActive() == false || node.Children == null || node.Children.Count == 0) { node.TriggerLayout(); return; } node.RowLayout.Refresh(); StandardLayoutJustification.JustifyChildren(node); StandardLayoutAlignment.AlignChildren(node); foreach (var c in node.Children) { if (c.GetIsActive() == false) { continue; } if (c.NodeConfiguration.Layout == CogaLayout.Absolute) { c.CalculateAbsolutePositioning(); } c.LayoutChildren(); c.TriggerLayout(); } node.NeedsLayout = false; }
static void CalculateHeight(CogaNode node) { if (node.GetIsRoot()) { node.Compute.Size.Y.Complete(node.NodeConfiguration.Height.Value); return; } switch (node.NodeConfiguration.Height.ValueType) { // Flat pixel amounts are just passed through. case CogaValueMode.Pixel: node.Compute.Size.Y.Complete(node.NodeConfiguration.Height.Value); break; case CogaValueMode.Default: var pref = node.PreferredNodeSize(); if (pref.HasValue) { node.Compute.Size.Y.Complete(pref.Value.Y); } else { node.Compute.Size.Y.Complete(node.MinimumNodeSize().Y); } break; case CogaValueMode.Fill: node.Compute.Size.Y.Complete(node.MinimumNodeSize().Y); break; } }
static void AlignFlexStart(CogaNode node) { for (int y = 0; y < node.RowLayout.Rows.Count; y++) { var real_index = (node.RowLayout.Rows.Count - 1) - y; // Reverse accessor index. var row = node.RowLayout.Rows[y]; var totalChildrenInRow = row.Children.Count; var cumulative_height = node.RowLayout.CumulativeHeights[y]; var spacing = y * node.NodeConfiguration.Spacing; for (int x = 0; x < totalChildrenInRow; x++) { var child = row.Children[x]; if (child.NodeConfiguration.Layout == CogaLayout.Absolute) { continue; } var offset = 0f; if (node.ComputedPadding.ContainsKey(Edge.Top)) { offset = node.ComputedPadding[Edge.Top].Value; } child.Compute.Position.Y.Complete(offset + node.Compute.Y + cumulative_height + spacing); } } }
internal static void CalculatePadding(this CogaNode node) { // Conveniently compute the node edges without repeating code over and over. void AttemptCalculatePadding(Edge e) { switch (node.NodeConfiguration.Padding[e].ValueType) { case CogaValueMode.Pixel: node.ComputedPadding[e].Complete(node.NodeConfiguration.Padding[e].Value); break; } } AttemptCalculatePadding(Edge.Left); AttemptCalculatePadding(Edge.Top); AttemptCalculatePadding(Edge.Right); AttemptCalculatePadding(Edge.Bottom); // Resolve convenience edges. if (node.ComputedPadding[Edge.Top].Resolved || node.ComputedPadding[Edge.Bottom].Resolved) { var top = node.ComputedPadding.ContainsKey(Edge.Top) ? node.ComputedPadding[Edge.Bottom].Value : 0f; var bottom = node.ComputedPadding.ContainsKey(Edge.Right) ? node.ComputedPadding[Edge.Right].Value : 0f; node.ComputedPadding[Edge.Vertical].Complete(top + bottom); } if (node.ComputedPadding[Edge.Left].Resolved || node.ComputedPadding[Edge.Right].Resolved) { var left = node.ComputedPadding.ContainsKey(Edge.Left) ? node.ComputedPadding[Edge.Left].Value : 0f; var right = node.ComputedPadding.ContainsKey(Edge.Right) ? node.ComputedPadding[Edge.Right].Value : 0f; node.ComputedPadding[Edge.Horizontal].Complete(left + right); } }
static void JustifyFlexEnd(CogaNode node) { JustifyFlexStart(node); foreach (var row in node.RowLayout.Rows) { if (row.RemainingWidth > 0f) { foreach (var child in row.Children) { child.Compute.Position.X.Complete(child.Compute.X + row.RemainingWidth); } } } }
static void JustifyFlexStart(CogaNode node) { for (int y = 0; y < node.RowLayout.Rows.Count; y++) { var sum = 0f; var row = node.RowLayout.Rows[y]; for (int x = 0; x < row.Children.Count; x++) { var child = row.Children[x]; if (child.NodeConfiguration.Layout == CogaLayout.Absolute) { continue; } child.Compute.Position.X.Complete(node.Compute.X + node.ComputedPadding[Edge.Left].Value + sum); sum += child.Compute.Width + node.NodeConfiguration.Spacing; } } }
static void AlignCenter(CogaNode node) { AlignFlexStart(node); var offset = node.RowLayout.RemainingHeight * 0.5f; for (int y = 0; y < node.RowLayout.Rows.Count; y++) { var row = node.RowLayout.Rows[y]; for (int x = 0; x < row.Children.Count; x++) { var child = row.Children[x]; if (child.NodeConfiguration.Layout == CogaLayout.Absolute) { continue; } child.Compute.Position.Y.Complete(child.Compute.Y + offset); } } }
internal static void CalculateAbsolutePositioning(this CogaNode node) { if (node.Parent == null) { return; } // Calculate the left and right absolute positioning. if (node.NodeConfiguration.Left.ValueType != CogaValueMode.Undefined) { node.Compute.Position.X.Complete(node.Parent.Compute.X + node.NodeConfiguration.Left.Value); if (node.NodeConfiguration.Right.ValueType != CogaValueMode.Undefined) { node.Compute.Size.X.Complete((node.Parent.Compute.Width - node.NodeConfiguration.Right.Value) - node.Compute.X); } } else if (node.NodeConfiguration.Right.ValueType != CogaValueMode.Undefined) { if (node.Compute.Size.X.Resolved != false) { var right = node.Parent.Compute.X + node.Parent.Compute.Width - node.NodeConfiguration.Right.Value; node.Compute.Position.X.Complete(right - node.Compute.Width); } } // Then the up and down absolute positioning values. if (node.NodeConfiguration.Top.ValueType != CogaValueMode.Undefined) { node.Compute.Position.Y.Complete(node.Parent.Compute.Y + node.NodeConfiguration.Top.Value); if (node.NodeConfiguration.Bottom.ValueType != CogaValueMode.Undefined) { node.Compute.Size.Y.Complete((node.Parent.Compute.Height - node.NodeConfiguration.Bottom.Value) - node.Compute.Y); } } else if (node.NodeConfiguration.Bottom.ValueType != CogaValueMode.Undefined) { if (node.Compute.Size.Y.Resolved != false) { var bottom = node.Parent.Compute.Y + node.Parent.Compute.Height - node.NodeConfiguration.Bottom.Value; node.Compute.Position.Y.Complete(bottom - node.Compute.Height); } } }
internal static void JustifyChildren(CogaNode node) { switch (node.NodeConfiguration.Justification) { case CogaJustify.Default: JustifyFlexStart(node); break; case CogaJustify.FlexStart: JustifyFlexStart(node); break; case CogaJustify.FlexEnd: JustifyFlexEnd(node); break; case CogaJustify.Center: JustifyCenter(node); break; } }
internal static void CalculateSize(this CogaNode node) { // Now calculate the actual sizes. CalculateWidth(node); CalculateHeight(node); }
void StartDrag(CogaNode node) { }
void Drag(CogaNode node, Vector2 vec) { }
public CogaNode SetFocus(CogaNode newFocus) => Focus = newFocus as UIComponent;
public void SetHover(CogaNode node) { Hover = node as UIComponent; }