void printNumberIfNotZero(Node node, string str, Value number) { if (!Flex.FloatsEqual(number.value, 0)) { printNumberIfNotUndefined(node, str, number); } }
public void ResetBridgeRootElement() { // reset root root = Flex.CreateDefaultNode(); var ra = CreateRuntimeNodeAttribute(root, templateRoot); // copy style var ctxs = GenerateContextStack(); ProcessStyleBind(root, ctxs); // el-bind var elBindDict = new Dictionary <string, object>(); if (templateRoot.attributeDataBindExpressList != null) { foreach (var attr in templateRoot.attributeDataBindExpressList) { if (attr.TryEvaluate(ctxs, out var obj)) { elBindDict[attr.TargetName] = obj; } } } var eleRoot = bridge.CreateElement(root, templateRoot.TagName, elBindDict); ra.element = eleRoot; bridge.OnSetRoot(eleRoot); }
Node RenderTemplateTree(TemplateNode tnode, ContextStack contextStack, object forContext) { Node node = Flex.CreateDefaultNode(); var ra = CreateRuntimeNodeAttribute(node, tnode); // set el-for value ra.forExpressItemCurrentValue = forContext; // copy style Style.Copy(node.nodeStyle, tnode.nodeStyle); // process node el-bind var originalAttrs = ra.attributes; foreach (var attr in tnode.attributeDataBindExpressList) { if (attr.TryEvaluate(contextStack, out var attrValue)) { if (originalAttrs.TryGetValue(attr, out var oldValue) && oldValue == attrValue) { // equal and not // Console.WriteLine("no need to process style"); } else { ra.attributes[attr] = attrValue; ProcessNodeStyle(node, attr.TargetName, attrValue != null ? attrValue.ToString() : ""); } } else { ra.attributes.Remove(attr); } } // process innerText if (tnode.textDataBindExpress != null) { ra.textDataBindExpressCurrentValue = tnode.textDataBindExpress.Evaluate(contextStack); } // render children ra.ResetChildren((appendChild) => { foreach (var vchild in tnode.Children) { foreach (var child in RenderTemplateTreeExpand(vchild, contextStack)) { node.AddChild(child); appendChild(vchild, child); } } }); return(node); }
// // Reset resets a node public static void Reset(ref Node node) { Flex.assertWithNode(node, node.Children.Count == 0, "Cannot reset a node which still has children attached"); Flex.assertWithNode(node, node.Parent == null, "Cannot reset a node still attached to a parent"); node.Children.Clear(); var config = node.config; node = CreateDefaultNode(); if (config.UseWebDefaults) { node.nodeStyle.FlexDirection = FlexDirection.Row; node.nodeStyle.AlignContent = Align.Stretch; } node.config = config; }
void printEdges(Node node, string str, Value[] edges) { if (fourValuesEqual(edges)) { printNumberIfNotZero(node, str, edges[(int)Edge.Left]); // bugfix for issue #5 // if we set EdgeAll, the values are // [{NaN 0} {NaN 0} {NaN 0} {NaN 0} {NaN 0} {NaN 0} {NaN 0} {NaN 0} {20 1}] // so EdgeLeft is not printed and we won't print padding // for simplicity, I assume that EdgeAll is exclusive with setting specific edges // so we can print both and only one should show up // C code has this bug: https://github.com/facebook/yoga/blob/26481a6553a33d9c005f2b8d24a7952fc58df32c/yoga/Yoga.c#L1036 printNumberIfNotZero(node, str, edges[(int)Edge.All]); } else { for (var edge = (int)Edge.Left; edge < Constant.EdgeCount; edge++) { var buf = $"{str}-{Flex.EdgeToString((Edge)edge)}"; printNumberIfNotZero(node, buf, edges[edge]); } } }
public void CalculateLayout(float parentWidth, float parentHeight, Direction parentDirection) { Flex.CalculateLayout(this, parentWidth, parentHeight, parentDirection); }
bool ProcessTemplateStyle(Style style, string attrKey, string attrValue) { switch (attrKey) { case "direction": if (Flex.StringToDirection(attrValue, out Direction direction)) { style.Direction = direction; } break; case "flex-direction": if (Flex.StringToFlexDirection(attrValue, out FlexDirection flexDirection)) { style.FlexDirection = flexDirection; } break; case "justify-content": if (Flex.StringToJustify(attrValue, out Justify justifyContent)) { style.JustifyContent = justifyContent; } break; case "align-content": if (Flex.StringToAlign(attrValue, out Align alignContent)) { style.AlignContent = alignContent; } break; case "align-items": if (Flex.StringToAlign(attrValue, out Align alignItem)) { style.AlignItems = alignItem; } break; case "align-self": if (Flex.StringToAlign(attrValue, out Align alignSelf)) { style.AlignSelf = alignSelf; } break; case "flex-wrap": if (Flex.StringToWrap(attrValue, out Wrap flexWrap)) { style.FlexWrap = flexWrap; } break; case "overflow": if (Flex.StringToOverflow(attrValue, out Overflow overflow)) { style.Overflow = overflow; } break; case "display": if (Flex.StringToDisplay(attrValue, out Display display)) { style.Display = display; } break; case "flex": if (float.TryParse(attrValue, out float flex)) { style.Flex = flex; } break; case "flex-grow": if (float.TryParse(attrValue, out float flexGrow)) { style.FlexGrow = flexGrow; } break; case "flex-shrink": if (float.TryParse(attrValue, out float flexShrink)) { style.FlexShrink = flexShrink; } break; case "flex-basis": style.FlexBasis = ParseValueFromString(attrValue); break; case "position": if (Flex.StringToPositionType(attrValue, out PositionType position)) { style.PositionType = position; } break; case "width": style.Dimensions[(int)Dimension.Width] = ParseValueFromString(attrValue); break; case "height": style.Dimensions[(int)Dimension.Height] = ParseValueFromString(attrValue); break; case "min-width": style.MinDimensions[(int)Dimension.Width] = ParseValueFromString(attrValue); break; case "min-height": style.MinDimensions[(int)Dimension.Height] = ParseValueFromString(attrValue); break; case "max-width": style.MaxDimensions[(int)Dimension.Width] = ParseValueFromString(attrValue); break; case "max-height": style.MaxDimensions[(int)Dimension.Height] = ParseValueFromString(attrValue); break; default: // parse [margin|padding|border|pos]-[Edgexxxx] if (ParseBreakWork(attrKey, out string head, out string tail)) { Value[] valuesToSet = null; switch (head) { case "margin": valuesToSet = style.Margin; break; case "padding": valuesToSet = style.Padding; break; case "border": valuesToSet = style.Border; break; case "pos": valuesToSet = style.Position; break; default: return(false); } if (valuesToSet == null) { break; } if (tail == "") { var valueArray = ParseFourValueFromString(attrValue); if (valueArray != null) { for (int i = 0; i < valueArray.Length; i++) { valuesToSet[i] = valueArray[i]; } } } else if (Flex.StringToEdge(tail, out Edge edge)) { valuesToSet[(int)edge] = ParseValueFromString(attrValue); } } else { return(false); } break; }
internal void ProcessNodeStyle(Node node, string attrKey, string attrValue) { switch (attrKey) { case "position": if (Flex.StringToPositionType(attrValue, out PositionType position)) { node.StyleSetPositionType(position); } break; case "align-content": if (Flex.StringToAlign(attrValue, out Align alignContent)) { node.StyleSetAlignContent(alignContent); } break; case "align-items": if (Flex.StringToAlign(attrValue, out Align alignItem)) { node.StyleSetAlignItems(alignItem); } break; case "align-self": if (Flex.StringToAlign(attrValue, out Align alignSelf)) { node.StyleSetAlignSelf(alignSelf); } break; case "flex-direction": if (Flex.StringToFlexDirection(attrValue, out FlexDirection flexDirection)) { node.StyleSetFlexDirection(flexDirection); } break; case "flex-wrap": if (Flex.StringToWrap(attrValue, out Wrap flexWrap)) { node.StyleSetFlexWrap(flexWrap); } break; case "flex-basis": var flexBasisValue = ParseValueFromString(attrValue); if (flexBasisValue.unit == Unit.Auto) { node.NodeStyleSetFlexBasisAuto(); } else if (flexBasisValue.unit == Unit.Point) { node.StyleSetFlexBasis(flexBasisValue.value); } else if (flexBasisValue.unit == Unit.Percent) { node.StyleSetFlexBasisPercent(flexBasisValue.value); } break; case "flex-shrink": if (float.TryParse(attrValue, out float flexShrink)) { node.StyleSetFlexShrink(flexShrink); } break; case "flex-grow": if (float.TryParse(attrValue, out float flexGrow)) { node.StyleSetFlexGrow(flexGrow); } break; case "justify-content": if (Flex.StringToJustify(attrValue, out Justify justifyContent)) { node.StyleSetJustifyContent(justifyContent); } break; case "direction": if (Flex.StringToDirection(attrValue, out Direction direction)) { node.StyleSetDirection(direction); } break; case "width": node.Helper_SetDimensions(ParseValueFromString(attrValue), Dimension.Width); break; case "height": node.Helper_SetDimensions(ParseValueFromString(attrValue), Dimension.Height); break; case "min-width": node.Helper_SetMinDimensions(ParseValueFromString(attrValue), Dimension.Width); break; case "min-height": node.Helper_SetMinDimensions(ParseValueFromString(attrValue), Dimension.Height); break; case "max-width": node.Helper_SetMaxDimensions(ParseValueFromString(attrValue), Dimension.Width); break; case "max-height": node.Helper_SetMaxDimensions(ParseValueFromString(attrValue), Dimension.Height); break; default: // parse [margin|padding|border]-[Edgexxxx] if (ParseBreakWork(attrKey, out string head, out string tail)) { if (head == "margin" || head == "padding" || head == "border" || head == "pos") { if (tail == "") { var valueArray = ParseFourValueFromString(attrValue); if (valueArray != null) { for (int i = 0; i < valueArray.Length; i++) { node.Helper_SetMarginPaddingBorder(head, (Edge)i, valueArray[i]); } } } else if (Flex.StringToEdge(tail, out Edge edge)) { node.Helper_SetMarginPaddingBorder(head, edge, ParseValueFromString(attrValue)); } } } break; } }
void PrintNode(Node node, int level) { var printer = this; printer.printIndent(level); printer.printf("<div "); if (node.printFunc != null) { node.printFunc(node); } if (PrintOptionsLayout) { printer.printf($"layout=\""); printer.printf($"width: {node.LayoutGetWidth()}; "); printer.printf($"height: {node.LayoutGetHeight()}; "); printer.printf($"top: {node.LayoutGetTop()}; "); printer.printf($"left: {node.LayoutGetLeft()};"); printer.printf("\" "); } if (PrintOptionsStyle) { printer.printf("style=\""); if (node.nodeStyle.FlexDirection != Constant.nodeDefaults.nodeStyle.FlexDirection) { printer.printf($"flex-direction: {Flex.FlexDirectionToString(node.nodeStyle.FlexDirection)}; "); } if (node.nodeStyle.JustifyContent != Constant.nodeDefaults.nodeStyle.JustifyContent) { printer.printf($"justify-content: {Flex.JustifyToString(node.nodeStyle.JustifyContent)}; "); } if (node.nodeStyle.AlignItems != Constant.nodeDefaults.nodeStyle.AlignItems) { printer.printf($"align-items: {Flex.AlignToString(node.nodeStyle.AlignItems)}; "); } if (node.nodeStyle.AlignContent != Constant.nodeDefaults.nodeStyle.AlignContent) { printer.printf($"align-content: {Flex.AlignToString(node.nodeStyle.AlignContent)}; "); } if (node.nodeStyle.AlignSelf != Constant.nodeDefaults.nodeStyle.AlignSelf) { printer.printf($"align-self: {Flex.AlignToString(node.nodeStyle.AlignSelf)}; "); } printer.printFloatIfNotUndefined(node, "flex-grow", node.nodeStyle.FlexGrow); printer.printFloatIfNotUndefined(node, "flex-shrink", node.nodeStyle.FlexShrink); printer.printNumberIfNotAuto(node, "flex-basis", node.nodeStyle.FlexBasis); printer.printFloatIfNotUndefined(node, "flex", node.nodeStyle.Flex); if (node.nodeStyle.FlexWrap != Constant.nodeDefaults.nodeStyle.FlexWrap) { printer.printf($"flexWrap: {Flex.WrapToString(node.nodeStyle.FlexWrap)}; "); } if (node.nodeStyle.Overflow != Constant.nodeDefaults.nodeStyle.Overflow) { printer.printf($"overflow: {Flex.OverflowToString(node.nodeStyle.Overflow)}; "); } if (node.nodeStyle.Display != Constant.nodeDefaults.nodeStyle.Display) { printer.printf($"display: {Flex.DisplayToString(node.nodeStyle.Display)}; "); } printer.printEdges(node, "margin", node.nodeStyle.Margin); printer.printEdges(node, "padding", node.nodeStyle.Padding); printer.printEdges(node, "border", node.nodeStyle.Border); printer.printNumberIfNotAuto(node, "width", node.nodeStyle.Dimensions[(int)Dimension.Width]); printer.printNumberIfNotAuto(node, "height", node.nodeStyle.Dimensions[(int)Dimension.Height]); printer.printNumberIfNotAuto(node, "max-width", node.nodeStyle.MaxDimensions[(int)Dimension.Width]); printer.printNumberIfNotAuto(node, "max-height", node.nodeStyle.MaxDimensions[(int)Dimension.Height]); printer.printNumberIfNotAuto(node, "min-width", node.nodeStyle.MinDimensions[(int)Dimension.Width]); printer.printNumberIfNotAuto(node, "min-height", node.nodeStyle.MinDimensions[(int)Dimension.Height]); if (node.nodeStyle.PositionType != Constant.nodeDefaults.nodeStyle.PositionType) { printer.printf($"position: {Flex.PositionTypeToString(node.nodeStyle.PositionType)}; "); } printer.printEdgeIfNotUndefined(node, "left", node.nodeStyle.Position, Edge.Left); printer.printEdgeIfNotUndefined(node, "right", node.nodeStyle.Position, Edge.Right); printer.printEdgeIfNotUndefined(node, "top", node.nodeStyle.Position, Edge.Top); printer.printEdgeIfNotUndefined(node, "bottom", node.nodeStyle.Position, Edge.Bottom); printer.printf("\""); if (node.measureFunc != null) { printer.printf(" has-custom-measure=\"true\""); } } printer.printf(">"); var childCount = (node.Children.Count); if (PrintOptionsChildren && childCount > 0) { for (int i = 0; i < childCount; i++) { printer.printf("\n"); printer.PrintNode(node.Children[(int)i], level + 1); } printer.printIndent(level); printer.printf("\n"); } if (childCount != 0) { printer.printIndent(level); } printer.printf("</div>"); }
bool fourValuesEqual(Value[] four) { return(Flex.ValueEqual(four[0], four[1]) && Flex.ValueEqual(four[0], four[2]) && Flex.ValueEqual(four[0], four[3])); }
void printEdgeIfNotUndefined(Node node, string str, Value[] edges, Edge edge) { printNumberIfNotUndefined(node, str, Flex.computedEdgeValue(edges, edge, Value.UndefinedValue)); }