From 31c1ccab0b3e0ef912197c7320b9ac559399e72e Mon Sep 17 00:00:00 2001 From: Matias Cudich Date: Mon, 13 Jul 2015 16:51:29 -0700 Subject: [PATCH 01/11] Support Xcode 7 Beta 3 and remove unused variable --- Generated/Layout.c | 1 - SwiftBox/Layout+View.swift | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/Generated/Layout.c b/Generated/Layout.c index 97fc5fe..3e126e0 100644 --- a/Generated/Layout.c +++ b/Generated/Layout.c @@ -438,7 +438,6 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth) { // We want to execute the next two loops one per line with flex-wrap int startLine = 0; int endLine = 0; - int nextOffset = 0; int alreadyComputedNextLayout = 0; // We aggregate the total dimensions of the container in those two variables float linesCrossDim = 0; diff --git a/SwiftBox/Layout+View.swift b/SwiftBox/Layout+View.swift index d93f484..ce6dcda 100644 --- a/SwiftBox/Layout+View.swift +++ b/SwiftBox/Layout+View.swift @@ -21,7 +21,7 @@ extension Layout { public func apply(view: ViewType) { view.frame = CGRectIntegral(frame) - for (s, layout) in Zip2(view.subviews, children) { + for (s, layout) in Zip2Sequence(view.subviews, children) { let subview = s as ViewType layout.apply(subview) } From 49479c109b811df3ecff7bc61b2287fde8847988 Mon Sep 17 00:00:00 2001 From: Matias Cudich Date: Mon, 20 Jul 2015 08:29:07 -0700 Subject: [PATCH 02/11] Follow-up changes --- Generated/Layout.c | 1 + SwiftBox/Layout+View.swift | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Generated/Layout.c b/Generated/Layout.c index 3e126e0..97fc5fe 100644 --- a/Generated/Layout.c +++ b/Generated/Layout.c @@ -438,6 +438,7 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth) { // We want to execute the next two loops one per line with flex-wrap int startLine = 0; int endLine = 0; + int nextOffset = 0; int alreadyComputedNextLayout = 0; // We aggregate the total dimensions of the container in those two variables float linesCrossDim = 0; diff --git a/SwiftBox/Layout+View.swift b/SwiftBox/Layout+View.swift index ce6dcda..88b0add 100644 --- a/SwiftBox/Layout+View.swift +++ b/SwiftBox/Layout+View.swift @@ -21,7 +21,7 @@ extension Layout { public func apply(view: ViewType) { view.frame = CGRectIntegral(frame) - for (s, layout) in Zip2Sequence(view.subviews, children) { + for (s, layout) in zip(view.subviews, children) { let subview = s as ViewType layout.apply(subview) } From 87d25a83ab26569081a322c0e3c2adeb92687128 Mon Sep 17 00:00:00 2001 From: Matias Cudich Date: Tue, 25 Aug 2015 09:49:57 -0700 Subject: [PATCH 03/11] xcode 7 beta 6 fixes --- SwiftBox/Layout.swift | 2 +- SwiftBoxTests/SwiftBoxTests.swift | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/SwiftBox/Layout.swift b/SwiftBox/Layout.swift index 672332d..6176302 100644 --- a/SwiftBox/Layout.swift +++ b/SwiftBox/Layout.swift @@ -31,7 +31,7 @@ extension Layout: CustomStringConvertible { let selfDescription = "{origin={\(frame.origin.x), \(frame.origin.y)}, size={\(frame.size.width), \(frame.size.height)}}" if children.count > 0 { let indentation = (0...depth).reduce("\n") { accum, _ in accum + "\t" } - let childrenDescription = indentation.join(children.map { $0.descriptionForDepth(depth + 1) }) + let childrenDescription = children.map { $0.descriptionForDepth(depth + 1) }.joinWithSeparator(indentation) return "\(selfDescription)\(indentation)\(childrenDescription)" } else { return selfDescription diff --git a/SwiftBoxTests/SwiftBoxTests.swift b/SwiftBoxTests/SwiftBoxTests.swift index 32af61e..e4e68a8 100644 --- a/SwiftBoxTests/SwiftBoxTests.swift +++ b/SwiftBoxTests/SwiftBoxTests.swift @@ -64,21 +64,21 @@ class SwiftBoxTests: XCTestCase { } func testUndefinedPoint() { - XCTAssertFalse(CGPoint.zeroPoint.isUndefined, "ordinary point is not undefined") + XCTAssertFalse(CGPoint.zero.isUndefined, "ordinary point is not undefined") XCTAssert(CGPoint(x: 0, y: Node.Undefined).isUndefined, "detects undefined point.y") XCTAssert(CGPoint(x: Node.Undefined, y: 0).isUndefined, "detects undefined point.x") } func testUndefinedSize() { - XCTAssertFalse(CGSize.zeroSize.isUndefined, "ordinary size is not undefined") + XCTAssertFalse(CGSize.zero.isUndefined, "ordinary size is not undefined") XCTAssert(CGSize(width: 0, height: Node.Undefined).isUndefined, "detects undefined size.height") XCTAssert(CGSize(width: Node.Undefined, height: 0).isUndefined, "detects undefined size.width") } func testUndefinedRect() { - XCTAssertFalse(CGRect.infiniteRect.isUndefined, "infinite rect is not undefined") - XCTAssertFalse(CGRect.nullRect.isUndefined, "null rect is not undefined") - XCTAssertFalse(CGRect.zeroRect.isUndefined, "zero rect is not undefined") + XCTAssertFalse(CGRect.infinite.isUndefined, "infinite rect is not undefined") + XCTAssertFalse(CGRect.null.isUndefined, "null rect is not undefined") + XCTAssertFalse(CGRect.zero.isUndefined, "zero rect is not undefined") XCTAssert(CGRect(x: 0, y: 0, width: Node.Undefined, height: 0).isUndefined, "detects undefined size in rect") XCTAssert(CGRect(x: Node.Undefined, y: 0, width: 1, height: 1).isUndefined, "detects undefined origin in rect") } From d518d73ab6c5c64372f95079b67f3cfc2e31aab9 Mon Sep 17 00:00:00 2001 From: Matias Cudich Date: Fri, 28 Aug 2015 17:15:18 -0700 Subject: [PATCH 04/11] Update to latest css-layout commit --- External/css-layout | 2 +- Generated/Layout.c | 610 ++++++++++++++---- Generated/Layout.h | 38 +- .../UserInterfaceState.xcuserstate | Bin 0 -> 24210 bytes .../xcschemes/xcschememanagement.plist | 24 + SwiftBox/Node.swift | 37 +- SwiftBox/NodeImpl.h | 2 +- SwiftBox/NodeImpl.m | 6 +- SwiftBoxTests/SwiftBoxTests.swift | 2 +- 9 files changed, 564 insertions(+), 157 deletions(-) create mode 100644 SwiftBox.xcodeproj/project.xcworkspace/xcuserdata/mcudich.xcuserdatad/UserInterfaceState.xcuserstate create mode 100644 SwiftBox.xcodeproj/xcuserdata/mcudich.xcuserdatad/xcschemes/xcschememanagement.plist diff --git a/External/css-layout b/External/css-layout index 99c7ce2..e6d3aea 160000 --- a/External/css-layout +++ b/External/css-layout @@ -1 +1 @@ -Subproject commit 99c7ce24b1bacee8ddf6224d840a664f39dd2088 +Subproject commit e6d3aea73deebb971540b5c7bc1d808815f527da diff --git a/Generated/Layout.c b/Generated/Layout.c index 97fc5fe..c4da1d7 100644 --- a/Generated/Layout.c +++ b/Generated/Layout.c @@ -11,9 +11,23 @@ #include #include #include -#include +// in concatenated header, don't include Layout.h it's already at the top +#ifndef CSS_LAYOUT_IMPLEMENTATION #include "Layout.h" +#endif + +#ifdef _MSC_VER +#include +#define isnan _isnan + +/* define fmaxf if < VC12 */ +#if _MSC_VER < 1800 +__forceinline const float fmaxf(const float a, const float b) { + return (a > b) ? a : b; +} +#endif +#endif bool isUndefined(float value) { return isnan(value); @@ -28,16 +42,33 @@ static bool eq(float a, float b) { void init_css_node(css_node_t *node) { node->style.align_items = CSS_ALIGN_STRETCH; + node->style.align_content = CSS_ALIGN_FLEX_START; + + node->style.direction = CSS_DIRECTION_INHERIT; + node->style.flex_direction = CSS_FLEX_DIRECTION_COLUMN; // Some of the fields default to undefined and not 0 node->style.dimensions[CSS_WIDTH] = CSS_UNDEFINED; node->style.dimensions[CSS_HEIGHT] = CSS_UNDEFINED; + node->style.minDimensions[CSS_WIDTH] = CSS_UNDEFINED; + node->style.minDimensions[CSS_HEIGHT] = CSS_UNDEFINED; + + node->style.maxDimensions[CSS_WIDTH] = CSS_UNDEFINED; + node->style.maxDimensions[CSS_HEIGHT] = CSS_UNDEFINED; + node->style.position[CSS_LEFT] = CSS_UNDEFINED; node->style.position[CSS_TOP] = CSS_UNDEFINED; node->style.position[CSS_RIGHT] = CSS_UNDEFINED; node->style.position[CSS_BOTTOM] = CSS_UNDEFINED; + node->style.margin[CSS_START] = CSS_UNDEFINED; + node->style.margin[CSS_END] = CSS_UNDEFINED; + node->style.padding[CSS_START] = CSS_UNDEFINED; + node->style.padding[CSS_END] = CSS_UNDEFINED; + node->style.border[CSS_START] = CSS_UNDEFINED; + node->style.border[CSS_END] = CSS_UNDEFINED; + node->layout.dimensions[CSS_WIDTH] = CSS_UNDEFINED; node->layout.dimensions[CSS_HEIGHT] = CSS_UNDEFINED; @@ -45,11 +76,12 @@ void init_css_node(css_node_t *node) { node->layout.last_requested_dimensions[CSS_WIDTH] = -1; node->layout.last_requested_dimensions[CSS_HEIGHT] = -1; node->layout.last_parent_max_width = -1; + node->layout.last_direction = (css_direction_t)-1; node->layout.should_update = true; } css_node_t *new_css_node() { - css_node_t *node = calloc(1, sizeof(*node)); + css_node_t *node = (css_node_t *)calloc(1, sizeof(*node)); init_css_node(node); return node; } @@ -106,8 +138,14 @@ static void print_css_node_rec( } if (options & CSS_PRINT_STYLE) { - if (node->style.flex_direction == CSS_FLEX_DIRECTION_ROW) { + if (node->style.flex_direction == CSS_FLEX_DIRECTION_COLUMN) { + printf("flexDirection: 'column', "); + } else if (node->style.flex_direction == CSS_FLEX_DIRECTION_COLUMN_REVERSE) { + printf("flexDirection: 'columnReverse', "); + } else if (node->style.flex_direction == CSS_FLEX_DIRECTION_ROW) { printf("flexDirection: 'row', "); + } else if (node->style.flex_direction == CSS_FLEX_DIRECTION_ROW_REVERSE) { + printf("flexDirection: 'rowReverse', "); } if (node->style.justify_content == CSS_JUSTIFY_CENTER) { @@ -128,6 +166,14 @@ static void print_css_node_rec( printf("alignItems: 'stretch', "); } + if (node->style.align_content == CSS_ALIGN_CENTER) { + printf("alignContent: 'center', "); + } else if (node->style.align_content == CSS_ALIGN_FLEX_END) { + printf("alignContent: 'flex-end', "); + } else if (node->style.align_content == CSS_ALIGN_STRETCH) { + printf("alignContent: 'stretch', "); + } + if (node->style.align_self == CSS_ALIGN_FLEX_START) { printf("alignSelf: 'flex-start', "); } else if (node->style.align_self == CSS_ALIGN_CENTER) { @@ -147,6 +193,8 @@ static void print_css_node_rec( print_number_0("marginRight", node->style.margin[CSS_RIGHT]); print_number_0("marginTop", node->style.margin[CSS_TOP]); print_number_0("marginBottom", node->style.margin[CSS_BOTTOM]); + print_number_0("marginStart", node->style.margin[CSS_START]); + print_number_0("marginEnd", node->style.margin[CSS_END]); } if (four_equal(node->style.padding)) { @@ -156,6 +204,8 @@ static void print_css_node_rec( print_number_0("paddingRight", node->style.padding[CSS_RIGHT]); print_number_0("paddingTop", node->style.padding[CSS_TOP]); print_number_0("paddingBottom", node->style.padding[CSS_BOTTOM]); + print_number_0("paddingStart", node->style.padding[CSS_START]); + print_number_0("paddingEnd", node->style.padding[CSS_END]); } if (four_equal(node->style.border)) { @@ -165,6 +215,8 @@ static void print_css_node_rec( print_number_0("borderRightWidth", node->style.border[CSS_RIGHT]); print_number_0("borderTopWidth", node->style.border[CSS_TOP]); print_number_0("borderBottomWidth", node->style.border[CSS_BOTTOM]); + print_number_0("borderStartWidth", node->style.border[CSS_START]); + print_number_0("borderEndWidth", node->style.border[CSS_END]); } print_number_nan("width", node->style.dimensions[CSS_WIDTH]); @@ -197,53 +249,131 @@ void print_css_node(css_node_t *node, css_print_options_t options) { } -static css_position_t leading[2] = { +static css_position_t leading[4] = { /* CSS_FLEX_DIRECTION_COLUMN = */ CSS_TOP, - /* CSS_FLEX_DIRECTION_ROW = */ CSS_LEFT + /* CSS_FLEX_DIRECTION_COLUMN_REVERSE = */ CSS_BOTTOM, + /* CSS_FLEX_DIRECTION_ROW = */ CSS_LEFT, + /* CSS_FLEX_DIRECTION_ROW_REVERSE = */ CSS_RIGHT }; -static css_position_t trailing[2] = { +static css_position_t trailing[4] = { /* CSS_FLEX_DIRECTION_COLUMN = */ CSS_BOTTOM, - /* CSS_FLEX_DIRECTION_ROW = */ CSS_RIGHT + /* CSS_FLEX_DIRECTION_COLUMN_REVERSE = */ CSS_TOP, + /* CSS_FLEX_DIRECTION_ROW = */ CSS_RIGHT, + /* CSS_FLEX_DIRECTION_ROW_REVERSE = */ CSS_LEFT }; -static css_position_t pos[2] = { +static css_position_t pos[4] = { /* CSS_FLEX_DIRECTION_COLUMN = */ CSS_TOP, - /* CSS_FLEX_DIRECTION_ROW = */ CSS_LEFT + /* CSS_FLEX_DIRECTION_COLUMN_REVERSE = */ CSS_BOTTOM, + /* CSS_FLEX_DIRECTION_ROW = */ CSS_LEFT, + /* CSS_FLEX_DIRECTION_ROW_REVERSE = */ CSS_RIGHT }; -static css_dimension_t dim[2] = { +static css_dimension_t dim[4] = { /* CSS_FLEX_DIRECTION_COLUMN = */ CSS_HEIGHT, - /* CSS_FLEX_DIRECTION_ROW = */ CSS_WIDTH + /* CSS_FLEX_DIRECTION_COLUMN_REVERSE = */ CSS_HEIGHT, + /* CSS_FLEX_DIRECTION_ROW = */ CSS_WIDTH, + /* CSS_FLEX_DIRECTION_ROW_REVERSE = */ CSS_WIDTH }; +static bool isRowDirection(css_flex_direction_t flex_direction) { + return flex_direction == CSS_FLEX_DIRECTION_ROW || + flex_direction == CSS_FLEX_DIRECTION_ROW_REVERSE; +} + +static bool isColumnDirection(css_flex_direction_t flex_direction) { + return flex_direction == CSS_FLEX_DIRECTION_COLUMN || + flex_direction == CSS_FLEX_DIRECTION_COLUMN_REVERSE; +} +static float getLeadingMargin(css_node_t *node, css_flex_direction_t axis) { + if (isRowDirection(axis) && !isUndefined(node->style.margin[CSS_START])) { + return node->style.margin[CSS_START]; + } -static float getMargin(css_node_t *node, int location) { - return node->style.margin[location]; + return node->style.margin[leading[axis]]; } -static float getPadding(css_node_t *node, int location) { - if (node->style.padding[location] >= 0) { - return node->style.padding[location]; +static float getTrailingMargin(css_node_t *node, css_flex_direction_t axis) { + if (isRowDirection(axis) && !isUndefined(node->style.margin[CSS_END])) { + return node->style.margin[CSS_END]; } + + return node->style.margin[trailing[axis]]; +} + +static float getLeadingPadding(css_node_t *node, css_flex_direction_t axis) { + if (isRowDirection(axis) && + !isUndefined(node->style.padding[CSS_START]) && + node->style.padding[CSS_START] >= 0) { + return node->style.padding[CSS_START]; + } + + if (node->style.padding[leading[axis]] >= 0) { + return node->style.padding[leading[axis]]; + } + return 0; } -static float getBorder(css_node_t *node, int location) { - if (node->style.border[location] >= 0) { - return node->style.border[location]; +static float getTrailingPadding(css_node_t *node, css_flex_direction_t axis) { + if (isRowDirection(axis) && + !isUndefined(node->style.padding[CSS_END]) && + node->style.padding[CSS_END] >= 0) { + return node->style.padding[CSS_END]; } + + if (node->style.padding[trailing[axis]] >= 0) { + return node->style.padding[trailing[axis]]; + } + return 0; } -static float getPaddingAndBorder(css_node_t *node, int location) { - return getPadding(node, location) + getBorder(node, location); +static float getLeadingBorder(css_node_t *node, css_flex_direction_t axis) { + if (isRowDirection(axis) && + !isUndefined(node->style.border[CSS_START]) && + node->style.border[CSS_START] >= 0) { + return node->style.border[CSS_START]; + } + + if (node->style.border[leading[axis]] >= 0) { + return node->style.border[leading[axis]]; + } + + return 0; +} + +static float getTrailingBorder(css_node_t *node, css_flex_direction_t axis) { + if (isRowDirection(axis) && + !isUndefined(node->style.border[CSS_END]) && + node->style.border[CSS_END] >= 0) { + return node->style.border[CSS_END]; + } + + if (node->style.border[trailing[axis]] >= 0) { + return node->style.border[trailing[axis]]; + } + + return 0; +} + +static float getLeadingPaddingAndBorder(css_node_t *node, css_flex_direction_t axis) { + return getLeadingPadding(node, axis) + getLeadingBorder(node, axis); +} + +static float getTrailingPaddingAndBorder(css_node_t *node, css_flex_direction_t axis) { + return getTrailingPadding(node, axis) + getTrailingBorder(node, axis); +} + +static float getBorderAxis(css_node_t *node, css_flex_direction_t axis) { + return getLeadingBorder(node, axis) + getTrailingBorder(node, axis); } static float getMarginAxis(css_node_t *node, css_flex_direction_t axis) { - return getMargin(node, leading[axis]) + getMargin(node, trailing[axis]); + return getLeadingMargin(node, axis) + getTrailingMargin(node, axis); } static float getPaddingAndBorderAxis(css_node_t *node, css_flex_direction_t axis) { - return getPaddingAndBorder(node, leading[axis]) + getPaddingAndBorder(node, trailing[axis]); + return getLeadingPaddingAndBorder(node, axis) + getTrailingPaddingAndBorder(node, axis); } static css_position_type_t getPositionType(css_node_t *node) { @@ -254,6 +384,10 @@ static css_justify_t getJustifyContent(css_node_t *node) { return node->style.justify_content; } +static css_align_t getAlignContent(css_node_t *node) { + return node->style.align_content; +} + static css_align_t getAlignItem(css_node_t *node, css_node_t *child) { if (child->style.align_self != CSS_ALIGN_AUTO) { return child->style.align_self; @@ -261,10 +395,40 @@ static css_align_t getAlignItem(css_node_t *node, css_node_t *child) { return node->style.align_items; } +static css_direction_t resolveDirection(css_node_t *node, css_direction_t parentDirection) { + css_direction_t direction = node->style.direction; + + if (direction == CSS_DIRECTION_INHERIT) { + direction = parentDirection > CSS_DIRECTION_INHERIT ? parentDirection : CSS_DIRECTION_LTR; + } + + return direction; +} + static css_flex_direction_t getFlexDirection(css_node_t *node) { return node->style.flex_direction; } +static css_flex_direction_t resolveAxis(css_flex_direction_t flex_direction, css_direction_t direction) { + if (direction == CSS_DIRECTION_RTL) { + if (flex_direction == CSS_FLEX_DIRECTION_ROW) { + return CSS_FLEX_DIRECTION_ROW_REVERSE; + } else if (flex_direction == CSS_FLEX_DIRECTION_ROW_REVERSE) { + return CSS_FLEX_DIRECTION_ROW; + } + } + + return flex_direction; +} + +static css_flex_direction_t getCrossFlexDirection(css_flex_direction_t flex_direction, css_direction_t direction) { + if (isColumnDirection(flex_direction)) { + return resolveAxis(CSS_FLEX_DIRECTION_ROW, direction); + } else { + return CSS_FLEX_DIRECTION_COLUMN; + } +} + static float getFlex(css_node_t *node) { return node->style.flex; } @@ -282,12 +446,13 @@ static bool isFlexWrap(css_node_t *node) { static float getDimWithMargin(css_node_t *node, css_flex_direction_t axis) { return node->layout.dimensions[dim[axis]] + - getMargin(node, leading[axis]) + - getMargin(node, trailing[axis]); + getLeadingMargin(node, axis) + + getTrailingMargin(node, axis); } static bool isDimDefined(css_node_t *node, css_flex_direction_t axis) { - return !isUndefined(node->style.dimensions[dim[axis]]); + float value = node->style.dimensions[dim[axis]]; + return !isUndefined(value) && value > 0.0; } static bool isPosDefined(css_node_t *node, css_position_t position) { @@ -306,6 +471,30 @@ static float getPosition(css_node_t *node, css_position_t position) { return 0; } +static float boundAxis(css_node_t *node, css_flex_direction_t axis, float value) { + float min = CSS_UNDEFINED; + float max = CSS_UNDEFINED; + + if (isColumnDirection(axis)) { + min = node->style.minDimensions[CSS_HEIGHT]; + max = node->style.maxDimensions[CSS_HEIGHT]; + } else if (isRowDirection(axis)) { + min = node->style.minDimensions[CSS_WIDTH]; + max = node->style.maxDimensions[CSS_WIDTH]; + } + + float boundValue = value; + + if (!isUndefined(max) && max >= 0.0 && boundValue > max) { + boundValue = max; + } + if (!isUndefined(min) && min >= 0.0 && boundValue < min) { + boundValue = min; + } + + return boundValue; +} + // When the user specifically sets a value for width or height static void setDimensionFromStyle(css_node_t *node, css_flex_direction_t axis) { // The parent already computed us a width or height. We just skip it @@ -319,11 +508,16 @@ static void setDimensionFromStyle(css_node_t *node, css_flex_direction_t axis) { // The dimensions can never be smaller than the padding and border node->layout.dimensions[dim[axis]] = fmaxf( - node->style.dimensions[dim[axis]], + boundAxis(node, axis, node->style.dimensions[dim[axis]]), getPaddingAndBorderAxis(node, axis) ); } +static void setTrailingPosition(css_node_t *node, css_node_t *child, css_flex_direction_t axis) { + child->layout.position[trailing[axis]] = node->layout.dimensions[dim[axis]] - + child->layout.dimensions[dim[axis]] - child->layout.position[pos[axis]]; + } + // If both left and right are defined, then use left. Otherwise return // +left or -right depending on which is defined. static float getRelativePosition(css_node_t *node, css_flex_direction_t axis) { @@ -334,65 +528,80 @@ static float getRelativePosition(css_node_t *node, css_flex_direction_t axis) { return -getPosition(node, trailing[axis]); } -static void layoutNodeImpl(css_node_t *node, float parentMaxWidth) { +static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, css_direction_t parentDirection) { /** START_GENERATED **/ - css_flex_direction_t mainAxis = getFlexDirection(node); - css_flex_direction_t crossAxis = mainAxis == CSS_FLEX_DIRECTION_ROW ? - CSS_FLEX_DIRECTION_COLUMN : - CSS_FLEX_DIRECTION_ROW; + css_direction_t direction = resolveDirection(node, parentDirection); + css_flex_direction_t mainAxis = resolveAxis(getFlexDirection(node), direction); + css_flex_direction_t crossAxis = getCrossFlexDirection(mainAxis, direction); + css_flex_direction_t resolvedRowAxis = resolveAxis(CSS_FLEX_DIRECTION_ROW, direction); // Handle width and height style attributes setDimensionFromStyle(node, mainAxis); setDimensionFromStyle(node, crossAxis); + // Set the resolved resolution in the node's layout + node->layout.direction = direction; + // The position is set by the parent, but we need to complete it with a // delta composed of the margin and left/top/right/bottom - node->layout.position[leading[mainAxis]] += getMargin(node, leading[mainAxis]) + + node->layout.position[leading[mainAxis]] += getLeadingMargin(node, mainAxis) + getRelativePosition(node, mainAxis); - node->layout.position[leading[crossAxis]] += getMargin(node, leading[crossAxis]) + + node->layout.position[trailing[mainAxis]] += getTrailingMargin(node, mainAxis) + + getRelativePosition(node, mainAxis); + node->layout.position[leading[crossAxis]] += getLeadingMargin(node, crossAxis) + + getRelativePosition(node, crossAxis); + node->layout.position[trailing[crossAxis]] += getTrailingMargin(node, crossAxis) + getRelativePosition(node, crossAxis); if (isMeasureDefined(node)) { float width = CSS_UNDEFINED; - if (isDimDefined(node, CSS_FLEX_DIRECTION_ROW)) { + if (isDimDefined(node, resolvedRowAxis)) { width = node->style.dimensions[CSS_WIDTH]; - } else if (!isUndefined(node->layout.dimensions[dim[CSS_FLEX_DIRECTION_ROW]])) { - width = node->layout.dimensions[dim[CSS_FLEX_DIRECTION_ROW]]; + } else if (!isUndefined(node->layout.dimensions[dim[resolvedRowAxis]])) { + width = node->layout.dimensions[dim[resolvedRowAxis]]; } else { width = parentMaxWidth - - getMarginAxis(node, CSS_FLEX_DIRECTION_ROW); + getMarginAxis(node, resolvedRowAxis); } - width -= getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_ROW); + width -= getPaddingAndBorderAxis(node, resolvedRowAxis); // We only need to give a dimension for the text if we haven't got any // for it computed yet. It can either be from the style attribute or because // the element is flexible. - bool isRowUndefined = !isDimDefined(node, CSS_FLEX_DIRECTION_ROW) && - isUndefined(node->layout.dimensions[dim[CSS_FLEX_DIRECTION_ROW]]); + bool isRowUndefined = !isDimDefined(node, resolvedRowAxis) && + isUndefined(node->layout.dimensions[dim[resolvedRowAxis]]); bool isColumnUndefined = !isDimDefined(node, CSS_FLEX_DIRECTION_COLUMN) && isUndefined(node->layout.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]]); // Let's not measure the text if we already know both dimensions if (isRowUndefined || isColumnUndefined) { - css_dim_t measure_dim = node->measure( + css_dim_t measureDim = node->measure( node->context, + width ); if (isRowUndefined) { - node->layout.dimensions[CSS_WIDTH] = measure_dim.dimensions[CSS_WIDTH] + - getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_ROW); + node->layout.dimensions[CSS_WIDTH] = measureDim.dimensions[CSS_WIDTH] + + getPaddingAndBorderAxis(node, resolvedRowAxis); } if (isColumnUndefined) { - node->layout.dimensions[CSS_HEIGHT] = measure_dim.dimensions[CSS_HEIGHT] + + node->layout.dimensions[CSS_HEIGHT] = measureDim.dimensions[CSS_HEIGHT] + getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_COLUMN); } } - return; + if (node->children_count == 0) { + return; + } } + int i; + int ii; + css_node_t* child; + css_flex_direction_t axis; + // Pre-fill some dimensions straight from the parent - for (int i = 0; i < node->children_count; ++i) { - css_node_t* child = node->get_child(node->context, i); + for (i = 0; i < node->children_count; ++i) { + child = node->get_child(node->context, i); // Pre-fill cross axis dimensions when the child is using stretch before // we call the recursive layout pass if (getAlignItem(node, child) == CSS_ALIGN_STRETCH && @@ -400,27 +609,27 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth) { !isUndefined(node->layout.dimensions[dim[crossAxis]]) && !isDimDefined(child, crossAxis)) { child->layout.dimensions[dim[crossAxis]] = fmaxf( - node->layout.dimensions[dim[crossAxis]] - + boundAxis(child, crossAxis, node->layout.dimensions[dim[crossAxis]] - getPaddingAndBorderAxis(node, crossAxis) - - getMarginAxis(child, crossAxis), + getMarginAxis(child, crossAxis)), // You never want to go smaller than padding getPaddingAndBorderAxis(child, crossAxis) ); } else if (getPositionType(child) == CSS_POSITION_ABSOLUTE) { // Pre-fill dimensions when using absolute position and both offsets for the axis are defined (either both // left and right or top and bottom). - for (int ii = 0; ii < 2; ii++) { - css_flex_direction_t axis = (ii != 0) ? CSS_FLEX_DIRECTION_ROW : CSS_FLEX_DIRECTION_COLUMN; + for (ii = 0; ii < 2; ii++) { + axis = (ii != 0) ? CSS_FLEX_DIRECTION_ROW : CSS_FLEX_DIRECTION_COLUMN; if (!isUndefined(node->layout.dimensions[dim[axis]]) && !isDimDefined(child, axis) && isPosDefined(child, leading[axis]) && isPosDefined(child, trailing[axis])) { child->layout.dimensions[dim[axis]] = fmaxf( - node->layout.dimensions[dim[axis]] - - getPaddingAndBorderAxis(node, axis) - - getMarginAxis(child, axis) - - getPosition(child, leading[axis]) - - getPosition(child, trailing[axis]), + boundAxis(child, axis, node->layout.dimensions[dim[axis]] - + getPaddingAndBorderAxis(node, axis) - + getMarginAxis(child, axis) - + getPosition(child, leading[axis]) - + getPosition(child, trailing[axis])), // You never want to go smaller than padding getPaddingAndBorderAxis(child, axis) ); @@ -438,11 +647,12 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth) { // We want to execute the next two loops one per line with flex-wrap int startLine = 0; int endLine = 0; - int nextOffset = 0; + // int nextOffset = 0; int alreadyComputedNextLayout = 0; // We aggregate the total dimensions of the container in those two variables float linesCrossDim = 0; float linesMainDim = 0; + int linesCount = 0; while (endLine < node->children_count) { // Layout non flexible children and count children by type @@ -457,8 +667,10 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth) { int flexibleChildrenCount = 0; float totalFlexible = 0; int nonFlexibleChildrenCount = 0; - for (int i = startLine; i < node->children_count; ++i) { - css_node_t* child = node->get_child(node->context, i); + + float maxWidth; + for (i = startLine; i < node->children_count; ++i) { + child = node->get_child(node->context, i); float nextContentDim = 0; // It only makes sense to consider a child flexible if we have a computed @@ -468,27 +680,28 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth) { totalFlexible += getFlex(child); // Even if we don't know its exact size yet, we already know the padding, - // border and margin. We'll use this partial information to compute the - // remaining space. + // border and margin. We'll use this partial information, which represents + // the smallest possible size for the child, to compute the remaining + // available space. nextContentDim = getPaddingAndBorderAxis(child, mainAxis) + getMarginAxis(child, mainAxis); } else { - float maxWidth = CSS_UNDEFINED; - if (mainAxis == CSS_FLEX_DIRECTION_ROW) { - // do nothing - } else if (isDimDefined(node, CSS_FLEX_DIRECTION_ROW)) { - maxWidth = node->layout.dimensions[dim[CSS_FLEX_DIRECTION_ROW]] - - getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_ROW); - } else { + maxWidth = CSS_UNDEFINED; + if (!isRowDirection(mainAxis)) { maxWidth = parentMaxWidth - - getMarginAxis(node, CSS_FLEX_DIRECTION_ROW) - - getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_ROW); + getMarginAxis(node, resolvedRowAxis) - + getPaddingAndBorderAxis(node, resolvedRowAxis); + + if (isDimDefined(node, resolvedRowAxis)) { + maxWidth = node->layout.dimensions[dim[resolvedRowAxis]] - + getPaddingAndBorderAxis(node, resolvedRowAxis); + } } // This is the main recursive call. We layout non flexible children. if (alreadyComputedNextLayout == 0) { - layoutNode(child, maxWidth); + layoutNode(child, maxWidth, direction); } // Absolute positioned elements do not take part of the layout, so we @@ -507,6 +720,7 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth) { // If there's only one element, then it's bigger than the content // and needs its own line i != startLine) { + nonFlexibleChildrenCount--; alreadyComputedNextLayout = 1; break; } @@ -535,6 +749,26 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth) { // remaining space if (flexibleChildrenCount != 0) { float flexibleMainDim = remainingMainDim / totalFlexible; + float baseMainDim; + float boundMainDim; + + // Iterate over every child in the axis. If the flex share of remaining + // space doesn't meet min/max bounds, remove this child from flex + // calculations. + for (i = startLine; i < endLine; ++i) { + child = node->get_child(node->context, i); + if (isFlex(child)) { + baseMainDim = flexibleMainDim * getFlex(child) + + getPaddingAndBorderAxis(child, mainAxis); + boundMainDim = boundAxis(child, mainAxis, baseMainDim); + + if (baseMainDim != boundMainDim) { + remainingMainDim -= boundMainDim; + totalFlexible -= getFlex(child); + } + } + } + flexibleMainDim = remainingMainDim / totalFlexible; // The non flexible children can overflow the container, in this case // we should just assume that there is no space available. @@ -544,28 +778,27 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth) { // We iterate over the full array and only apply the action on flexible // children. This is faster than actually allocating a new array that // contains only flexible children. - for (int i = startLine; i < endLine; ++i) { - css_node_t* child = node->get_child(node->context, i); + for (i = startLine; i < endLine; ++i) { + child = node->get_child(node->context, i); if (isFlex(child)) { // At this point we know the final size of the element in the main // dimension - child->layout.dimensions[dim[mainAxis]] = flexibleMainDim * getFlex(child) + - getPaddingAndBorderAxis(child, mainAxis); - - float maxWidth = CSS_UNDEFINED; - if (mainAxis == CSS_FLEX_DIRECTION_ROW) { - // do nothing - } else if (isDimDefined(node, CSS_FLEX_DIRECTION_ROW)) { - maxWidth = node->layout.dimensions[dim[CSS_FLEX_DIRECTION_ROW]] - - getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_ROW); - } else { + child->layout.dimensions[dim[mainAxis]] = boundAxis(child, mainAxis, + flexibleMainDim * getFlex(child) + getPaddingAndBorderAxis(child, mainAxis) + ); + + maxWidth = CSS_UNDEFINED; + if (isDimDefined(node, resolvedRowAxis)) { + maxWidth = node->layout.dimensions[dim[resolvedRowAxis]] - + getPaddingAndBorderAxis(node, resolvedRowAxis); + } else if (!isRowDirection(mainAxis)) { maxWidth = parentMaxWidth - - getMarginAxis(node, CSS_FLEX_DIRECTION_ROW) - - getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_ROW); + getMarginAxis(node, resolvedRowAxis) - + getPaddingAndBorderAxis(node, resolvedRowAxis); } // And we recursively call the layout algorithm for this child - layoutNode(child, maxWidth); + layoutNode(child, maxWidth, direction); } } @@ -573,9 +806,7 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth) { // space available } else { css_justify_t justifyContent = getJustifyContent(node); - if (justifyContent == CSS_JUSTIFY_FLEX_START) { - // Do nothing - } else if (justifyContent == CSS_JUSTIFY_CENTER) { + if (justifyContent == CSS_JUSTIFY_CENTER) { leadingMainDim = remainingMainDim / 2; } else if (justifyContent == CSS_JUSTIFY_FLEX_END) { leadingMainDim = remainingMainDim; @@ -603,10 +834,11 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth) { // container! float crossDim = 0; float mainDim = leadingMainDim + - getPaddingAndBorder(node, leading[mainAxis]); + getLeadingPaddingAndBorder(node, mainAxis); - for (int i = startLine; i < endLine; ++i) { - css_node_t* child = node->get_child(node->context, i); + for (i = startLine; i < endLine; ++i) { + child = node->get_child(node->context, i); + child->line_index = linesCount; if (getPositionType(child) == CSS_POSITION_ABSOLUTE && isPosDefined(child, leading[mainAxis])) { @@ -614,12 +846,17 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth) { // defined, we override the position to whatever the user said // (and margin/border). child->layout.position[pos[mainAxis]] = getPosition(child, leading[mainAxis]) + - getBorder(node, leading[mainAxis]) + - getMargin(child, leading[mainAxis]); + getLeadingBorder(node, mainAxis) + + getLeadingMargin(child, mainAxis); } else { // If the child is position absolute (without top/left) or relative, // we put it at the current accumulated offset. child->layout.position[pos[mainAxis]] += mainDim; + + // Define the trailing position accordingly. + if (!isUndefined(node->layout.dimensions[dim[mainAxis]])) { + setTrailingPosition(node, child, mainAxis); + } } // Now that we placed the element, we need to update the variables @@ -631,38 +868,24 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth) { mainDim += betweenMainDim + getDimWithMargin(child, mainAxis); // The cross dimension is the max of the elements dimension since there // can only be one element in that cross dimension. - crossDim = fmaxf(crossDim, getDimWithMargin(child, crossAxis)); + crossDim = fmaxf(crossDim, boundAxis(child, crossAxis, getDimWithMargin(child, crossAxis))); } } - float containerMainAxis = node->layout.dimensions[dim[mainAxis]]; - // If the user didn't specify a width or height, and it has not been set - // by the container, then we set it via the children. - if (isUndefined(node->layout.dimensions[dim[mainAxis]])) { - containerMainAxis = fmaxf( - // We're missing the last padding at this point to get the final - // dimension - mainDim + getPaddingAndBorder(node, trailing[mainAxis]), - // We can never assign a width smaller than the padding and borders - getPaddingAndBorderAxis(node, mainAxis) - ); - } - float containerCrossAxis = node->layout.dimensions[dim[crossAxis]]; if (isUndefined(node->layout.dimensions[dim[crossAxis]])) { containerCrossAxis = fmaxf( // For the cross dim, we add both sides at the end because the value // is aggregate via a max function. Intermediate negative values // can mess this computation otherwise - crossDim + getPaddingAndBorderAxis(node, crossAxis), + boundAxis(node, crossAxis, crossDim + getPaddingAndBorderAxis(node, crossAxis)), getPaddingAndBorderAxis(node, crossAxis) ); } // Position elements in the cross axis - - for (int i = startLine; i < endLine; ++i) { - css_node_t* child = node->get_child(node->context, i); + for (i = startLine; i < endLine; ++i) { + child = node->get_child(node->context, i); if (getPositionType(child) == CSS_POSITION_ABSOLUTE && isPosDefined(child, leading[crossAxis])) { @@ -670,31 +893,29 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth) { // top/left/bottom/right being set, we override all the previously // computed positions to set it correctly. child->layout.position[pos[crossAxis]] = getPosition(child, leading[crossAxis]) + - getBorder(node, leading[crossAxis]) + - getMargin(child, leading[crossAxis]); + getLeadingBorder(node, crossAxis) + + getLeadingMargin(child, crossAxis); } else { - float leadingCrossDim = getPaddingAndBorder(node, leading[crossAxis]); + float leadingCrossDim = getLeadingPaddingAndBorder(node, crossAxis); // For a relative children, we're either using alignItems (parent) or // alignSelf (child) in order to determine the position in the cross axis if (getPositionType(child) == CSS_POSITION_RELATIVE) { css_align_t alignItem = getAlignItem(node, child); - if (alignItem == CSS_ALIGN_FLEX_START) { - // Do nothing - } else if (alignItem == CSS_ALIGN_STRETCH) { + if (alignItem == CSS_ALIGN_STRETCH) { // You can only stretch if the dimension has not already been set // previously. if (!isDimDefined(child, crossAxis)) { child->layout.dimensions[dim[crossAxis]] = fmaxf( - containerCrossAxis - + boundAxis(child, crossAxis, containerCrossAxis - getPaddingAndBorderAxis(node, crossAxis) - - getMarginAxis(child, crossAxis), + getMarginAxis(child, crossAxis)), // You never want to go smaller than padding getPaddingAndBorderAxis(child, crossAxis) ); } - } else { + } else if (alignItem != CSS_ALIGN_FLEX_START) { // The remaining space between the parent dimensions+padding and child // dimensions+margin. float remainingCrossDim = containerCrossAxis - @@ -711,24 +932,117 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth) { // And we apply the position child->layout.position[pos[crossAxis]] += linesCrossDim + leadingCrossDim; + + // Define the trailing position accordingly. + if (!isUndefined(node->layout.dimensions[dim[crossAxis]])) { + setTrailingPosition(node, child, crossAxis); + } } } linesCrossDim += crossDim; linesMainDim = fmaxf(linesMainDim, mainDim); + linesCount += 1; startLine = endLine; } + // + // + // Note(prenaux): More than one line, we need to layout the crossAxis + // according to alignContent. + // + // Note that we could probably remove and handle the one line case + // here too, but for the moment this is safer since it won't interfere with + // previously working code. + // + // See specs: + // http://www.w3.org/TR/2012/CR-css3-flexbox-20120918/#layout-algorithm + // section 9.4 + // + if (linesCount > 1 && + !isUndefined(node->layout.dimensions[dim[crossAxis]])) { + float nodeCrossAxisInnerSize = node->layout.dimensions[dim[crossAxis]] - + getPaddingAndBorderAxis(node, crossAxis); + float remainingAlignContentDim = nodeCrossAxisInnerSize - linesCrossDim; + + float crossDimLead = 0; + float currentLead = getLeadingPaddingAndBorder(node, crossAxis); + + css_align_t alignContent = getAlignContent(node); + if (alignContent == CSS_ALIGN_FLEX_END) { + currentLead += remainingAlignContentDim; + } else if (alignContent == CSS_ALIGN_CENTER) { + currentLead += remainingAlignContentDim / 2; + } else if (alignContent == CSS_ALIGN_STRETCH) { + if (nodeCrossAxisInnerSize > linesCrossDim) { + crossDimLead = (remainingAlignContentDim / linesCount); + } + } + + int endIndex = 0; + for (i = 0; i < linesCount; ++i) { + int startIndex = endIndex; + + // compute the line's height and find the endIndex + float lineHeight = 0; + for (ii = startIndex; ii < node->children_count; ++ii) { + child = node->get_child(node->context, ii); + if (getPositionType(child) != CSS_POSITION_RELATIVE) { + continue; + } + if (child->line_index != i) { + break; + } + if (!isUndefined(child->layout.dimensions[dim[crossAxis]])) { + lineHeight = fmaxf( + lineHeight, + child->layout.dimensions[dim[crossAxis]] + getMarginAxis(child, crossAxis) + ); + } + } + endIndex = ii; + lineHeight += crossDimLead; + + for (ii = startIndex; ii < endIndex; ++ii) { + child = node->get_child(node->context, ii); + if (getPositionType(child) != CSS_POSITION_RELATIVE) { + continue; + } + + css_align_t alignContentAlignItem = getAlignItem(node, child); + if (alignContentAlignItem == CSS_ALIGN_FLEX_START) { + child->layout.position[pos[crossAxis]] = currentLead + getLeadingMargin(child, crossAxis); + } else if (alignContentAlignItem == CSS_ALIGN_FLEX_END) { + child->layout.position[pos[crossAxis]] = currentLead + lineHeight - getTrailingMargin(child, crossAxis) - child->layout.dimensions[dim[crossAxis]]; + } else if (alignContentAlignItem == CSS_ALIGN_CENTER) { + float childHeight = child->layout.dimensions[dim[crossAxis]]; + child->layout.position[pos[crossAxis]] = currentLead + (lineHeight - childHeight) / 2; + } else if (alignContentAlignItem == CSS_ALIGN_STRETCH) { + child->layout.position[pos[crossAxis]] = currentLead + getLeadingMargin(child, crossAxis); + // TODO(prenaux): Correctly set the height of items with undefined + // (auto) crossAxis dimension. + } + } + + currentLead += lineHeight; + } + } + + bool needsMainTrailingPos = false; + bool needsCrossTrailingPos = false; + // If the user didn't specify a width or height, and it has not been set // by the container, then we set it via the children. if (isUndefined(node->layout.dimensions[dim[mainAxis]])) { node->layout.dimensions[dim[mainAxis]] = fmaxf( // We're missing the last padding at this point to get the final // dimension - linesMainDim + getPaddingAndBorder(node, trailing[mainAxis]), + boundAxis(node, mainAxis, linesMainDim + getTrailingPaddingAndBorder(node, mainAxis)), // We can never assign a width smaller than the padding and borders getPaddingAndBorderAxis(node, mainAxis) ); + + needsMainTrailingPos = true; } if (isUndefined(node->layout.dimensions[dim[crossAxis]])) { @@ -736,37 +1050,54 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth) { // For the cross dim, we add both sides at the end because the value // is aggregate via a max function. Intermediate negative values // can mess this computation otherwise - linesCrossDim + getPaddingAndBorderAxis(node, crossAxis), + boundAxis(node, crossAxis, linesCrossDim + getPaddingAndBorderAxis(node, crossAxis)), getPaddingAndBorderAxis(node, crossAxis) ); + + needsCrossTrailingPos = true; } - // Calculate dimensions for absolutely positioned elements + // Set trailing position if necessary + if (needsMainTrailingPos || needsCrossTrailingPos) { + for (i = 0; i < node->children_count; ++i) { + child = node->get_child(node->context, i); - for (int i = 0; i < node->children_count; ++i) { - css_node_t* child = node->get_child(node->context, i); + if (needsMainTrailingPos) { + setTrailingPosition(node, child, mainAxis); + } + + if (needsCrossTrailingPos) { + setTrailingPosition(node, child, crossAxis); + } + } + } + + // Calculate dimensions for absolutely positioned elements + for (i = 0; i < node->children_count; ++i) { + child = node->get_child(node->context, i); if (getPositionType(child) == CSS_POSITION_ABSOLUTE) { // Pre-fill dimensions when using absolute position and both offsets for the axis are defined (either both // left and right or top and bottom). - for (int ii = 0; ii < 2; ii++) { - css_flex_direction_t axis = (ii != 0) ? CSS_FLEX_DIRECTION_ROW : CSS_FLEX_DIRECTION_COLUMN; + for (ii = 0; ii < 2; ii++) { + axis = (ii != 0) ? CSS_FLEX_DIRECTION_ROW : CSS_FLEX_DIRECTION_COLUMN; if (!isUndefined(node->layout.dimensions[dim[axis]]) && !isDimDefined(child, axis) && isPosDefined(child, leading[axis]) && isPosDefined(child, trailing[axis])) { child->layout.dimensions[dim[axis]] = fmaxf( - node->layout.dimensions[dim[axis]] - - getPaddingAndBorderAxis(node, axis) - - getMarginAxis(child, axis) - - getPosition(child, leading[axis]) - - getPosition(child, trailing[axis]), + boundAxis(child, axis, node->layout.dimensions[dim[axis]] - + getBorderAxis(node, axis) - + getMarginAxis(child, axis) - + getPosition(child, leading[axis]) - + getPosition(child, trailing[axis]) + ), // You never want to go smaller than padding getPaddingAndBorderAxis(child, axis) ); } } - for (int ii = 0; ii < 2; ii++) { - css_flex_direction_t axis = (ii != 0) ? CSS_FLEX_DIRECTION_ROW : CSS_FLEX_DIRECTION_COLUMN; + for (ii = 0; ii < 2; ii++) { + axis = (ii != 0) ? CSS_FLEX_DIRECTION_ROW : CSS_FLEX_DIRECTION_COLUMN; if (isPosDefined(child, trailing[axis]) && !isPosDefined(child, leading[axis])) { child->layout.position[leading[axis]] = @@ -780,8 +1111,9 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth) { /** END_GENERATED **/ } -void layoutNode(css_node_t *node, float parentMaxWidth) { +void layoutNode(css_node_t *node, float parentMaxWidth, css_direction_t parentDirection) { css_layout_t *layout = &node->layout; + css_direction_t direction = node->style.direction; layout->should_update = true; bool skipLayout = @@ -789,6 +1121,7 @@ void layoutNode(css_node_t *node, float parentMaxWidth) { eq(layout->last_requested_dimensions[CSS_WIDTH], layout->dimensions[CSS_WIDTH]) && eq(layout->last_requested_dimensions[CSS_HEIGHT], layout->dimensions[CSS_HEIGHT]) && eq(layout->last_parent_max_width, parentMaxWidth); + eq(layout->last_direction, direction); if (skipLayout) { layout->dimensions[CSS_WIDTH] = layout->last_dimensions[CSS_WIDTH]; @@ -799,8 +1132,9 @@ void layoutNode(css_node_t *node, float parentMaxWidth) { layout->last_requested_dimensions[CSS_WIDTH] = layout->dimensions[CSS_WIDTH]; layout->last_requested_dimensions[CSS_HEIGHT] = layout->dimensions[CSS_HEIGHT]; layout->last_parent_max_width = parentMaxWidth; + layout->last_direction = direction; - layoutNodeImpl(node, parentMaxWidth); + layoutNodeImpl(node, parentMaxWidth, parentDirection); layout->last_dimensions[CSS_WIDTH] = layout->dimensions[CSS_WIDTH]; layout->last_dimensions[CSS_HEIGHT] = layout->dimensions[CSS_HEIGHT]; diff --git a/Generated/Layout.h b/Generated/Layout.h index d5a815c..54d3158 100644 --- a/Generated/Layout.h +++ b/Generated/Layout.h @@ -11,12 +11,29 @@ #define __LAYOUT_H #include +#ifndef __cplusplus #include +#endif + +// Not defined in MSVC++ +#ifndef NAN +static const unsigned long __nan[2] = {0xffffffff, 0x7fffffff}; +#define NAN (*(const float *)__nan) +#endif + #define CSS_UNDEFINED NAN +typedef enum { + CSS_DIRECTION_INHERIT = 0, + CSS_DIRECTION_LTR, + CSS_DIRECTION_RTL +} css_direction_t; + typedef enum { CSS_FLEX_DIRECTION_COLUMN = 0, - CSS_FLEX_DIRECTION_ROW + CSS_FLEX_DIRECTION_COLUMN_REVERSE, + CSS_FLEX_DIRECTION_ROW, + CSS_FLEX_DIRECTION_ROW_REVERSE } css_flex_direction_t; typedef enum { @@ -54,6 +71,8 @@ typedef enum { CSS_TOP, CSS_RIGHT, CSS_BOTTOM, + CSS_START, + CSS_END, CSS_POSITION_COUNT } css_position_t; @@ -63,8 +82,9 @@ typedef enum { } css_dimension_t; typedef struct { - float position[2]; + float position[4]; float dimensions[2]; + css_direction_t direction; // Instead of recomputing the entire layout every single time, we // cache some information to break early when nothing changed @@ -73,6 +93,7 @@ typedef struct { float last_parent_max_width; float last_dimensions[2]; float last_position[2]; + css_direction_t last_direction; } css_layout_t; typedef struct { @@ -80,14 +101,16 @@ typedef struct { } css_dim_t; typedef struct { + css_direction_t direction; css_flex_direction_t flex_direction; css_justify_t justify_content; + css_align_t align_content; css_align_t align_items; css_align_t align_self; css_position_type_t position_type; css_wrap_type_t flex_wrap; float flex; - float margin[4]; + float margin[6]; float position[4]; /** * You should skip all the rules that contain negative values for the @@ -99,15 +122,18 @@ typedef struct { * {left: -5 ...} * {left: 0 ...} */ - float padding[4]; - float border[4]; + float padding[6]; + float border[6]; float dimensions[2]; + float minDimensions[2]; + float maxDimensions[2]; } css_style_t; typedef struct css_node { css_style_t style; css_layout_t layout; int children_count; + int line_index; css_dim_t (*measure)(void *context, float width); void (*print)(void *context); @@ -131,7 +157,7 @@ typedef enum { void print_css_node(css_node_t *node, css_print_options_t options); // Function that computes the layout! -void layoutNode(css_node_t *node, float maxWidth); +void layoutNode(css_node_t *node, float maxWidth, css_direction_t parentDirection); bool isUndefined(float value); #endif diff --git a/SwiftBox.xcodeproj/project.xcworkspace/xcuserdata/mcudich.xcuserdatad/UserInterfaceState.xcuserstate b/SwiftBox.xcodeproj/project.xcworkspace/xcuserdata/mcudich.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000000000000000000000000000000000000..ad099d3e4db2e7268e11b0b6340aad7e51cc8e13 GIT binary patch literal 24210 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 eWXwoawW)eUb$NBQKe$c_pQ5NxtA{ZF literal 0 HcmV?d00001 diff --git a/SwiftBox.xcodeproj/xcuserdata/mcudich.xcuserdatad/xcschemes/xcschememanagement.plist b/SwiftBox.xcodeproj/xcuserdata/mcudich.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..50a91ed --- /dev/null +++ b/SwiftBox.xcodeproj/xcuserdata/mcudich.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,24 @@ + + + + + SuppressBuildableAutocreation + + 882D60671A7F05E1001C5181 + + primary + + + 882D60721A7F05E1001C5181 + + primary + + + 889865B21AAFD89B009C19D1 + + primary + + + + + diff --git a/SwiftBox/Node.swift b/SwiftBox/Node.swift index e0883e6..e7267e7 100644 --- a/SwiftBox/Node.swift +++ b/SwiftBox/Node.swift @@ -13,16 +13,20 @@ public struct Edges { public let right: CGFloat public let bottom: CGFloat public let top: CGFloat + public let start: CGFloat + public let end: CGFloat - private var asTuple: (Float, Float, Float, Float) { - return (Float(left), Float(top), Float(right), Float(bottom)) + private var asTuple: (Float, Float, Float, Float, Float, Float) { + return (Float(left), Float(top), Float(right), Float(bottom), Float(start), Float(end)) } - public init(left: CGFloat = 0, right: CGFloat = 0, bottom: CGFloat = 0, top: CGFloat = 0) { + public init(left: CGFloat = 0, right: CGFloat = 0, bottom: CGFloat = 0, top: CGFloat = 0, start: CGFloat = 0, end: CGFloat = 0) { self.left = left self.right = right self.bottom = bottom self.top = top + self.start = start; + self.end = end; } public init(uniform: CGFloat) { @@ -30,12 +34,16 @@ public struct Edges { self.right = uniform self.bottom = uniform self.top = uniform + self.start = uniform; + self.end = uniform; } } -public enum Direction: UInt32 { +public enum FlexDirection: UInt32 { case Column = 0 case Row = 1 + case ColumnReverse = 2 + case RowReverse = 3 } public enum Justification: UInt32 { @@ -61,6 +69,12 @@ public enum SelfAlignment: UInt32 { case Stretch = 4 } +public enum Direction: UInt32 { + case Inherit = 0 + case LeftToRight = 1 + case RightToLeft = 2 +} + /// A node in a layout hierarchy. public struct Node { /// Indicates that the value is undefined, for the flexbox algorithm to @@ -68,7 +82,10 @@ public struct Node { public static let Undefined: CGFloat = nan("SwiftBox.Node.Undefined") public let size: CGSize + public let minSize: CGSize + public let maxSize: CGSize public let children: [Node] + public let flexDirection: FlexDirection public let direction: Direction public let margin: Edges public let padding: Edges @@ -79,9 +96,12 @@ public struct Node { public let flex: CGFloat public let measure: (CGFloat -> CGSize)? - public init(size: CGSize = CGSize(width: Undefined, height: Undefined), children: [Node] = [], direction: Direction = .Column, margin: Edges = Edges(), padding: Edges = Edges(), wrap: Bool = false, justification: Justification = .FlexStart, selfAlignment: SelfAlignment = .Auto, childAlignment: ChildAlignment = .Stretch, flex: CGFloat = 0, measure: (CGFloat -> CGSize)? = nil) { + public init(size: CGSize = CGSize(width: Undefined, height: Undefined), minSize: CGSize = CGSize(width: 0, height: 0), maxSize: CGSize = CGSize(width: Undefined, height: Undefined), children: [Node] = [], flexDirection: FlexDirection = .Column, direction: Direction = .Inherit, margin: Edges = Edges(), padding: Edges = Edges(), wrap: Bool = false, justification: Justification = .FlexStart, selfAlignment: SelfAlignment = .Auto, childAlignment: ChildAlignment = .Stretch, flex: CGFloat = 0, measure: (CGFloat -> CGSize)? = nil) { self.size = size + self.minSize = minSize + self.maxSize = maxSize self.children = children + self.flexDirection = flexDirection self.direction = direction self.margin = margin self.padding = padding @@ -96,10 +116,13 @@ public struct Node { private func createUnderlyingNode() -> NodeImpl { let node = NodeImpl() node.node.memory.style.dimensions = (Float(size.width), Float(size.height)) + node.node.memory.style.minDimensions = (Float(minSize.width), Float(minSize.height)) + node.node.memory.style.maxDimensions = (Float(maxSize.width), Float(maxSize.height)) node.node.memory.style.margin = margin.asTuple node.node.memory.style.padding = padding.asTuple node.node.memory.style.flex = Float(flex) - node.node.memory.style.flex_direction = css_flex_direction_t(direction.rawValue) + node.node.memory.style.flex_direction = css_flex_direction_t(flexDirection.rawValue) + node.node.memory.style.direction = css_direction_t(direction.rawValue) node.node.memory.style.flex_wrap = css_wrap_type_t(wrap ? 1 : 0) node.node.memory.style.justify_content = css_justify_t(justification.rawValue) node.node.memory.style.align_self = css_align_t(selfAlignment.rawValue) @@ -115,7 +138,7 @@ public struct Node { public func layout(maxWidth: CGFloat? = nil) -> Layout { let node = createUnderlyingNode() if let maxWidth = maxWidth { - node.layoutWithMaxWidth(maxWidth) + node.layoutWithMaxWidth(maxWidth, parentDirection: node.node.memory.style.direction) } else { node.layout() } diff --git a/SwiftBox/NodeImpl.h b/SwiftBox/NodeImpl.h index 19fd881..5e1b22e 100644 --- a/SwiftBox/NodeImpl.h +++ b/SwiftBox/NodeImpl.h @@ -26,6 +26,6 @@ - (void)layout; -- (void)layoutWithMaxWidth:(CGFloat)maxWidth; +- (void)layoutWithMaxWidth:(CGFloat)maxWidth parentDirection:(css_direction_t)parentDirection; @end diff --git a/SwiftBox/NodeImpl.m b/SwiftBox/NodeImpl.m index 3160710..1ed227f 100644 --- a/SwiftBox/NodeImpl.m +++ b/SwiftBox/NodeImpl.m @@ -62,13 +62,13 @@ - (void)prepareForLayout { } - (void)layout { - [self layoutWithMaxWidth:CSS_UNDEFINED]; + [self layoutWithMaxWidth:CSS_UNDEFINED parentDirection:CSS_DIRECTION_INHERIT]; } -- (void)layoutWithMaxWidth:(CGFloat)maxWidth { +- (void)layoutWithMaxWidth:(CGFloat)maxWidth parentDirection:(css_direction_t)parentDirection { [self prepareForLayout]; - layoutNode(self.node, maxWidth); + layoutNode(self.node, maxWidth, parentDirection); } - (CGRect)frame { diff --git a/SwiftBoxTests/SwiftBoxTests.swift b/SwiftBoxTests/SwiftBoxTests.swift index e4e68a8..1fca489 100644 --- a/SwiftBoxTests/SwiftBoxTests.swift +++ b/SwiftBoxTests/SwiftBoxTests.swift @@ -14,7 +14,7 @@ class SwiftBoxTests: XCTestCase { func testDescription() { let parent = Node(size: CGSize(width: 300, height: 300), childAlignment: .Center, - direction: .Row, + flexDirection: .Row, children: [ Node(flex: 75, margin: Edges(left: 10, right: 10), From c1e4df5f483ddfd6e8c1a2c08bd2c687dc0093ee Mon Sep 17 00:00:00 2001 From: Matias Cudich Date: Fri, 28 Aug 2015 17:21:44 -0700 Subject: [PATCH 05/11] Fix enum order --- .../UserInterfaceState.xcuserstate | Bin 24210 -> 24202 bytes SwiftBox/Node.swift | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/SwiftBox.xcodeproj/project.xcworkspace/xcuserdata/mcudich.xcuserdatad/UserInterfaceState.xcuserstate b/SwiftBox.xcodeproj/project.xcworkspace/xcuserdata/mcudich.xcuserdatad/UserInterfaceState.xcuserstate index ad099d3e4db2e7268e11b0b6340aad7e51cc8e13..897ab71a4efd94b48c075dd9389efd94c59f87fa 100644 GIT binary patch delta 2209 zcmZXJYg8500)QnKzM7dmue0|#^VsvCkV{8J^vvuzGc}``D5hkh^jO_8Qd2}sLXDb5GbAUiFu!dS^=@~VxqL$Z0}oeN_Q0r~+269Cd9b2?#(*|MtVsFKd*W*8|Gzf- zC7c*Wji&OcDO534MLkQ+qZUvLsYO&h)k1Bgwo>iX9%?VOpE^kWM0L_hbT=B%chH&i zC_0~>Ko`+fbPc_XUO_j|jdU~pI^9O^p!d@I>4Wrf`Xqgd{))az|4v`0Z_qcHB&I8q z%yegZG75tkoiUl)nA8N5#-uY*rZ1Dhj9?yRikWJrk$Igtz?@^Qf-WElbOjWM03D=) zejo#60vCATE|3L=fow1a%bPU1MCJLfW6=lI08Nf$G{no_!e9SKZ2jY6>tr7f}#3B^K*P$^Ui)xuoiIbng&EF2I%6}yN%#gM3p1H~+HoH$vWC(aiW&x-VAkw_Jw{5{Rz84 z9*PjcFf?Fq7=tgIEPNbJf|FqZoDOHenQ#`I3!jH8U=v&gUxqEP6|RFD;8yq^ z+y@UN;30Sfo`9#|X?O;ng%{vOcnMyHov0_e710PF4hblP5K2X9C>=#nUzC9|(LiLO z5$FLl9_6D6XcC%?W}um97AiyKXf~RM7NOOs8LdHU(R#EIZAIHrJL*6?(INB^I*N{? zljzg%EnyH&@L@5G!jZ5XP7RL^KNOx6o*XU+7e-1V<&pZxE0I?tEs@s98<967TO)5p zjz&I@d>#2Faxro#@^j?Z$d$;oNT<|Q>L&G&dPzu1mC~eiDJu1qGNeptpmeu%kCY`1 zmqth$%Cs!Wx660PedK;}f7z4olC$KAa)G>1eoz>ci?IYK7XMwyVe0^XgaX1@)qONxh7dFoQWP zV2Hz5!YMcnr{gH@i(MSx!FUKBjz{2;I0rv~C*Ub~DxQXmaS1NPPvdG_hZiUC5?qg8 z!OeILUWYf}O?VrA2fvGV;9dAIK8BCullTlii_hWn_!9nAOVYY&J+xjL&^S%dLRxPv zLmQ-x)23@RTCG;6Ez#<=P1-i?U2UIsNxQ23u3gt|Xg76Hhk96-bVbK{Z#~cl>qGRR z`Y=5)TF=$T=@01R^%{M#{*Jy|zo`FUh=ywDhH2bp^fvs^FecpS!hl-i_H?V%&agg z%{k^$bGg}IHkmJ(tId{#xz^lZZZfxx6a6I&FPneQkYfeP<;uTR&RY>?HeEJ8T%>|(pbF14SwE9|-Ue0!n2$gZ=O*o}6pz1i-tKeYGR2kb-k z5&M+=nSItiXP>vfw7<8nkgkLx3}FdRM4}R%q>$T58c8Puh)3>8ko(EQA+M1)$QIH@wvip=J+g;y97shMjb@BJ(XX97mH{D(??Xs@mLO0^d zZkpTA&2(cfaea5NdyhNJ&3233)$U>Uq;xsZ@f3ntMID5dENrA##`zw_Zqw=Z9A7&Hg1!Mb2W&=!o|7aRx<2OkHY1Sf;j!I|Lm;C%2^a3T05_${~^ nbPm6s-6OkKHkA!>`{fSG9h!S@m;Z9hEq^tc`K$kP?x=qQEuyS} delta 2191 zcmZw6dw3030swGH>$PU)%*>s8&b{+E^N8APdy#}Y=gghyH$%0E3e{A-LU*^e;*mxK z&4cS1f@UKkh!UYziC3ChtLUeiYAKCZeOiyIR;w>nWxM?p`|bbx`}eoxU`oxwl-&Wt zYI_=3F0BmYL!7ju}}_M%Jv6Wtmx7EwWUW_P><4 z|C3E*Jx=B@&olW^_m=0!xgeiz@&xAK?x+d`@k6}k!uAy1ep zlna%@GNDRXF02q%3I~N_!U>^GI4ztN&IuQU>%vdM&%!Ulouu%)a9?aEriu@X8R7u( z1uL1DrO$<#7O%Kfsm4wPd3qlp4#i1pkWudCj*3ik&WvPP%BvtArxl)dlClyM|q$(*{ zE!9Z1Qk~QwZICufP10^@pL9ezEnSo@OIM_;VI|x(oCy2j=fY#dmEo%JzHn=}E&LzY z9~jqr8&57-2Ez+JEz z?uQ@3Hh3xt&%jUMMR*xrfmh*I@JDzP-h#JL3gVH7Bm_|e$w);Qbw@o>ChCRah#&{K z=y5a*jYAXAL^K%{ph8rF%Fry7M03%6v<$64Z=h{xJKBkMqc_ohbO;?rt>_3kgU+Gz z=mNTgK96*cz(_J0Q6e~EM65{n$cV_FBL$JdNKvFXS{|Jnt&eVrZjClYcSQdg-51>- zJs3S7y%zl;dLw!>dMo-{^ltQC^nsir|3PMDAPX{WJ}kG&N8}IXWAg7x zdxcRrg;zvHQcNYLWGTHBTcOGm%9BctGDRs;mMiO(4a!F4b!CV0wsJsuM>(V%Rn95r zmCuxmYFMpS*QpI^qq<4muI^Hs)fV-*`l)(V{Yw2>y{>+zCVx@ysK2Vesdv?TS_h5S z6s?yQXaluD+F)&n_KY@48>5ZYUeNxcy{OI88nnaO1?{@_z4oJaQ@f?z#+`5&N3e`F ztYZ^DihJTr+zZEXU)&!L#DnlqJPhaJ;dmULjHlvhcsee{<#;xpgDY_zUX{eFaXsFG zx8d!07jDKa_yB$vzlYz)AKgmIq-K9J+Z=2THJ>$ynwB}h0 zt;Nou#v+GuUI-msdI)=sP0YOxMkhpkrY1M5K=lg6d-X`vX3b&Yk4rN|3++XArM=XywO85o z_G@;7-Dq#K_u7Z;Hv7E&nSIf|Y+tdzwSTaGvVXRdx9xx14@f5>5}l-zM@fwIAQ{9V z9`Q*Z(vLhvhLF+ZMKYC?l5#Se%pvp0Qc^{hlNF?ntR{_QC;1n7pL|SClGEfYIY&Mx zSIIT<4f&RQPi~X@v0`7z&7fJ-rTysOBppTnO2^ZeXg-}pi|I^S zO3P`I&ZSFeEp4FN=^nb5?xXwZL3)H9rN`;V^b|cqFVb)5E&9Mob=o_foGuRQC{DT) zcb;+vI!`-8oMFy$&Io6;GuC<8DRPRP8BU2)?j)Ug&H|^xsdm;nZ#f@1SDfUX1e@rV z$Vxn)7@HWEn2?yBC{H94^AZaa%MyQ2)Ff6WRwa%lt|jif9bM54yAfA$v1__%ZiY+T zg!{M~xc%L1cd$Fu9p;v~Tis9G%kDMzhI`jb_1b%#ye^*Tg}sQUc$(MEOZR$suGiOl z(i`9n@`fe7=e!Z#XfMzEo0sp+@aB6~Hap`#%Rt@MMq^JRgh;CIpj$ z;-D;;6RZeU1{;H>U}vy9cr(}^WS$I82cHDzgA2js;EUkP;OpSq;D_Kwa5uOYJm`~} b{ZKZaEoMvED3|08%+1NoT`_U2o-+Kur;M{9 diff --git a/SwiftBox/Node.swift b/SwiftBox/Node.swift index e7267e7..3a40597 100644 --- a/SwiftBox/Node.swift +++ b/SwiftBox/Node.swift @@ -41,8 +41,8 @@ public struct Edges { public enum FlexDirection: UInt32 { case Column = 0 - case Row = 1 - case ColumnReverse = 2 + case ColumnReverse = 1 + case Row = 2 case RowReverse = 3 } From 9ed79682f62f955e3560fbc88a70197d0db857ff Mon Sep 17 00:00:00 2001 From: Matias Cudich Date: Fri, 28 Aug 2015 17:31:22 -0700 Subject: [PATCH 06/11] ws --- SwiftBox/Node.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/SwiftBox/Node.swift b/SwiftBox/Node.swift index 3a40597..e43d061 100644 --- a/SwiftBox/Node.swift +++ b/SwiftBox/Node.swift @@ -137,6 +137,7 @@ public struct Node { /// Lay out the receiver and all its children with an optional max width. public func layout(maxWidth: CGFloat? = nil) -> Layout { let node = createUnderlyingNode() + if let maxWidth = maxWidth { node.layoutWithMaxWidth(maxWidth, parentDirection: node.node.memory.style.direction) } else { From d6ec373e29bb38bc958827ef239c1cfff9862ca1 Mon Sep 17 00:00:00 2001 From: Matias Cudich Date: Fri, 28 Aug 2015 18:43:04 -0700 Subject: [PATCH 07/11] rm semicolons --- SwiftBox/Node.swift | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/SwiftBox/Node.swift b/SwiftBox/Node.swift index e43d061..4731a14 100644 --- a/SwiftBox/Node.swift +++ b/SwiftBox/Node.swift @@ -25,8 +25,8 @@ public struct Edges { self.right = right self.bottom = bottom self.top = top - self.start = start; - self.end = end; + self.start = start + self.end = end } public init(uniform: CGFloat) { @@ -34,8 +34,8 @@ public struct Edges { self.right = uniform self.bottom = uniform self.top = uniform - self.start = uniform; - self.end = uniform; + self.start = uniform + self.end = uniform } } From 7780b82717e8fd74bdfde63cce4991c875b4076b Mon Sep 17 00:00:00 2001 From: Matias Cudich Date: Mon, 31 Aug 2015 10:08:49 -0700 Subject: [PATCH 08/11] Fill out interface --- .../UserInterfaceState.xcuserstate | Bin 24202 -> 26034 bytes .../xcschemes/xcschememanagement.plist | 24 -------- SwiftBox/Node.swift | 52 ++++++++++-------- 3 files changed, 29 insertions(+), 47 deletions(-) delete mode 100644 SwiftBox.xcodeproj/xcuserdata/mcudich.xcuserdatad/xcschemes/xcschememanagement.plist diff --git a/SwiftBox.xcodeproj/project.xcworkspace/xcuserdata/mcudich.xcuserdatad/UserInterfaceState.xcuserstate b/SwiftBox.xcodeproj/project.xcworkspace/xcuserdata/mcudich.xcuserdatad/UserInterfaceState.xcuserstate index 897ab71a4efd94b48c075dd9389efd94c59f87fa..e0f2472a25a2c95c34e269f353233575a7fb886a 100644 GIT binary patch delta 8174 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 delta 6753 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 - - - - SuppressBuildableAutocreation - - 882D60671A7F05E1001C5181 - - primary - - - 882D60721A7F05E1001C5181 - - primary - - - 889865B21AAFD89B009C19D1 - - primary - - - - - diff --git a/SwiftBox/Node.swift b/SwiftBox/Node.swift index 4731a14..8a93f13 100644 --- a/SwiftBox/Node.swift +++ b/SwiftBox/Node.swift @@ -13,20 +13,20 @@ public struct Edges { public let right: CGFloat public let bottom: CGFloat public let top: CGFloat - public let start: CGFloat - public let end: CGFloat + public let start: CGFloat + public let end: CGFloat private var asTuple: (Float, Float, Float, Float, Float, Float) { return (Float(left), Float(top), Float(right), Float(bottom), Float(start), Float(end)) } - public init(left: CGFloat = 0, right: CGFloat = 0, bottom: CGFloat = 0, top: CGFloat = 0, start: CGFloat = 0, end: CGFloat = 0) { + public init(left: CGFloat = 0, right: CGFloat = 0, bottom: CGFloat = 0, top: CGFloat = 0, start: CGFloat = 0, end: CGFloat = 0) { self.left = left self.right = right self.bottom = bottom self.top = top - self.start = start - self.end = end + self.start = start + self.end = end } public init(uniform: CGFloat) { @@ -34,16 +34,16 @@ public struct Edges { self.right = uniform self.bottom = uniform self.top = uniform - self.start = uniform - self.end = uniform + self.start = uniform + self.end = uniform } } public enum FlexDirection: UInt32 { case Column = 0 - case ColumnReverse = 1 + case ColumnReverse = 1 case Row = 2 - case RowReverse = 3 + case RowReverse = 3 } public enum Justification: UInt32 { @@ -70,9 +70,9 @@ public enum SelfAlignment: UInt32 { } public enum Direction: UInt32 { - case Inherit = 0 - case LeftToRight = 1 - case RightToLeft = 2 + case Inherit = 0 + case LeftToRight = 1 + case RightToLeft = 2 } /// A node in a layout hierarchy. @@ -82,33 +82,37 @@ public struct Node { public static let Undefined: CGFloat = nan("SwiftBox.Node.Undefined") public let size: CGSize - public let minSize: CGSize - public let maxSize: CGSize + public let minSize: CGSize + public let maxSize: CGSize public let children: [Node] - public let flexDirection: FlexDirection + public let flexDirection: FlexDirection public let direction: Direction public let margin: Edges public let padding: Edges + public let border: Edges public let wrap: Bool public let justification: Justification public let selfAlignment: SelfAlignment public let childAlignment: ChildAlignment + public let contentAlignment: ChildAlignment public let flex: CGFloat public let measure: (CGFloat -> CGSize)? - public init(size: CGSize = CGSize(width: Undefined, height: Undefined), minSize: CGSize = CGSize(width: 0, height: 0), maxSize: CGSize = CGSize(width: Undefined, height: Undefined), children: [Node] = [], flexDirection: FlexDirection = .Column, direction: Direction = .Inherit, margin: Edges = Edges(), padding: Edges = Edges(), wrap: Bool = false, justification: Justification = .FlexStart, selfAlignment: SelfAlignment = .Auto, childAlignment: ChildAlignment = .Stretch, flex: CGFloat = 0, measure: (CGFloat -> CGSize)? = nil) { + public init(size: CGSize = CGSize(width: Undefined, height: Undefined), minSize: CGSize = CGSize(width: 0, height: 0), maxSize: CGSize = CGSize(width: Undefined, height: Undefined), children: [Node] = [], flexDirection: FlexDirection = .Column, direction: Direction = .Inherit, margin: Edges = Edges(), padding: Edges = Edges(), border: Edges = Edges(), wrap: Bool = false, justification: Justification = .FlexStart, selfAlignment: SelfAlignment = .Auto, childAlignment: ChildAlignment = .Stretch, contentAlignment: ChildAlignment = .Stretch, flex: CGFloat = 0, measure: (CGFloat -> CGSize)? = nil) { self.size = size - self.minSize = minSize - self.maxSize = maxSize + self.minSize = minSize + self.maxSize = maxSize self.children = children - self.flexDirection = flexDirection + self.flexDirection = flexDirection self.direction = direction self.margin = margin self.padding = padding + self.border = border self.wrap = wrap self.justification = justification self.selfAlignment = selfAlignment self.childAlignment = childAlignment + self.contentAlignment = contentAlignment self.flex = flex self.measure = measure } @@ -116,17 +120,19 @@ public struct Node { private func createUnderlyingNode() -> NodeImpl { let node = NodeImpl() node.node.memory.style.dimensions = (Float(size.width), Float(size.height)) - node.node.memory.style.minDimensions = (Float(minSize.width), Float(minSize.height)) - node.node.memory.style.maxDimensions = (Float(maxSize.width), Float(maxSize.height)) + node.node.memory.style.minDimensions = (Float(minSize.width), Float(minSize.height)) + node.node.memory.style.maxDimensions = (Float(maxSize.width), Float(maxSize.height)) node.node.memory.style.margin = margin.asTuple node.node.memory.style.padding = padding.asTuple + node.node.memory.style.border = border.asTuple node.node.memory.style.flex = Float(flex) node.node.memory.style.flex_direction = css_flex_direction_t(flexDirection.rawValue) - node.node.memory.style.direction = css_direction_t(direction.rawValue) + node.node.memory.style.direction = css_direction_t(direction.rawValue) node.node.memory.style.flex_wrap = css_wrap_type_t(wrap ? 1 : 0) node.node.memory.style.justify_content = css_justify_t(justification.rawValue) node.node.memory.style.align_self = css_align_t(selfAlignment.rawValue) node.node.memory.style.align_items = css_align_t(childAlignment.rawValue) + node.node.memory.style.align_content = css_align_t(contentAlignment.rawValue) if let measure = measure { node.measure = measure } @@ -139,7 +145,7 @@ public struct Node { let node = createUnderlyingNode() if let maxWidth = maxWidth { - node.layoutWithMaxWidth(maxWidth, parentDirection: node.node.memory.style.direction) + node.layoutWithMaxWidth(maxWidth, parentDirection: node.node.memory.style.direction) } else { node.layout() } From a1a34f73122bfa4a960d9b8eac934c0fba294568 Mon Sep 17 00:00:00 2001 From: Matias Cudich Date: Mon, 31 Aug 2015 10:10:15 -0700 Subject: [PATCH 09/11] rm more user data --- .../UserInterfaceState.xcuserstate | Bin 26034 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 SwiftBox.xcodeproj/project.xcworkspace/xcuserdata/mcudich.xcuserdatad/UserInterfaceState.xcuserstate diff --git a/SwiftBox.xcodeproj/project.xcworkspace/xcuserdata/mcudich.xcuserdatad/UserInterfaceState.xcuserstate b/SwiftBox.xcodeproj/project.xcworkspace/xcuserdata/mcudich.xcuserdatad/UserInterfaceState.xcuserstate deleted file mode 100644 index e0f2472a25a2c95c34e269f353233575a7fb886a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 26034 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 DT@j3c From 6e05bc4080f073c36a60ef404034f83e4eecca5b Mon Sep 17 00:00:00 2001 From: Matias Cudich Date: Thu, 3 Sep 2015 15:27:53 -0700 Subject: [PATCH 10/11] Add position type --- SwiftBox/Node.swift | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/SwiftBox/Node.swift b/SwiftBox/Node.swift index 8a93f13..dfaeb80 100644 --- a/SwiftBox/Node.swift +++ b/SwiftBox/Node.swift @@ -75,6 +75,11 @@ public enum Direction: UInt32 { case RightToLeft = 2 } +public enum PositionType: UInt32 { + case Relative = 0 + case Absolute = 1 +} + /// A node in a layout hierarchy. public struct Node { /// Indicates that the value is undefined, for the flexbox algorithm to @@ -96,9 +101,10 @@ public struct Node { public let childAlignment: ChildAlignment public let contentAlignment: ChildAlignment public let flex: CGFloat + public let positionType: PositionType public let measure: (CGFloat -> CGSize)? - public init(size: CGSize = CGSize(width: Undefined, height: Undefined), minSize: CGSize = CGSize(width: 0, height: 0), maxSize: CGSize = CGSize(width: Undefined, height: Undefined), children: [Node] = [], flexDirection: FlexDirection = .Column, direction: Direction = .Inherit, margin: Edges = Edges(), padding: Edges = Edges(), border: Edges = Edges(), wrap: Bool = false, justification: Justification = .FlexStart, selfAlignment: SelfAlignment = .Auto, childAlignment: ChildAlignment = .Stretch, contentAlignment: ChildAlignment = .Stretch, flex: CGFloat = 0, measure: (CGFloat -> CGSize)? = nil) { + public init(size: CGSize = CGSize(width: Undefined, height: Undefined), minSize: CGSize = CGSize(width: 0, height: 0), maxSize: CGSize = CGSize(width: Undefined, height: Undefined), children: [Node] = [], flexDirection: FlexDirection = .Column, direction: Direction = .Inherit, margin: Edges = Edges(), padding: Edges = Edges(), border: Edges = Edges(), wrap: Bool = false, justification: Justification = .FlexStart, selfAlignment: SelfAlignment = .Auto, childAlignment: ChildAlignment = .Stretch, contentAlignment: ChildAlignment = .Stretch, flex: CGFloat = 0, positionType: PositionType = .Relative, measure: (CGFloat -> CGSize)? = nil) { self.size = size self.minSize = minSize self.maxSize = maxSize @@ -114,6 +120,7 @@ public struct Node { self.childAlignment = childAlignment self.contentAlignment = contentAlignment self.flex = flex + self.positionType = positionType self.measure = measure } @@ -125,6 +132,7 @@ public struct Node { node.node.memory.style.margin = margin.asTuple node.node.memory.style.padding = padding.asTuple node.node.memory.style.border = border.asTuple + node.node.memory.style.position_type = css_position_type_t(positionType.rawValue) node.node.memory.style.flex = Float(flex) node.node.memory.style.flex_direction = css_flex_direction_t(flexDirection.rawValue) node.node.memory.style.direction = css_direction_t(direction.rawValue) From 890f5b84d185bdef28b6460fd14cffd770d086fd Mon Sep 17 00:00:00 2001 From: Matias Cudich Date: Fri, 4 Sep 2015 09:39:23 -0700 Subject: [PATCH 11/11] Add position support --- SwiftBox/Node.swift | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/SwiftBox/Node.swift b/SwiftBox/Node.swift index dfaeb80..72ae0c1 100644 --- a/SwiftBox/Node.swift +++ b/SwiftBox/Node.swift @@ -20,6 +20,10 @@ public struct Edges { return (Float(left), Float(top), Float(right), Float(bottom), Float(start), Float(end)) } + private var asCompactTuple: (Float, Float, Float, Float) { + return (Float(left), Float(top), Float(right), Float(bottom)) + } + public init(left: CGFloat = 0, right: CGFloat = 0, bottom: CGFloat = 0, top: CGFloat = 0, start: CGFloat = 0, end: CGFloat = 0) { self.left = left self.right = right @@ -95,6 +99,7 @@ public struct Node { public let margin: Edges public let padding: Edges public let border: Edges + public let position: Edges public let wrap: Bool public let justification: Justification public let selfAlignment: SelfAlignment @@ -104,7 +109,7 @@ public struct Node { public let positionType: PositionType public let measure: (CGFloat -> CGSize)? - public init(size: CGSize = CGSize(width: Undefined, height: Undefined), minSize: CGSize = CGSize(width: 0, height: 0), maxSize: CGSize = CGSize(width: Undefined, height: Undefined), children: [Node] = [], flexDirection: FlexDirection = .Column, direction: Direction = .Inherit, margin: Edges = Edges(), padding: Edges = Edges(), border: Edges = Edges(), wrap: Bool = false, justification: Justification = .FlexStart, selfAlignment: SelfAlignment = .Auto, childAlignment: ChildAlignment = .Stretch, contentAlignment: ChildAlignment = .Stretch, flex: CGFloat = 0, positionType: PositionType = .Relative, measure: (CGFloat -> CGSize)? = nil) { + public init(size: CGSize = CGSize(width: Undefined, height: Undefined), minSize: CGSize = CGSize(width: 0, height: 0), maxSize: CGSize = CGSize(width: Undefined, height: Undefined), children: [Node] = [], flexDirection: FlexDirection = .Column, direction: Direction = .Inherit, margin: Edges = Edges(), padding: Edges = Edges(), border: Edges = Edges(), position: Edges = Edges(), wrap: Bool = false, justification: Justification = .FlexStart, selfAlignment: SelfAlignment = .Auto, childAlignment: ChildAlignment = .Stretch, contentAlignment: ChildAlignment = .Stretch, flex: CGFloat = 0, positionType: PositionType = .Relative, measure: (CGFloat -> CGSize)? = nil) { self.size = size self.minSize = minSize self.maxSize = maxSize @@ -114,6 +119,7 @@ public struct Node { self.margin = margin self.padding = padding self.border = border + self.position = position self.wrap = wrap self.justification = justification self.selfAlignment = selfAlignment @@ -132,6 +138,7 @@ public struct Node { node.node.memory.style.margin = margin.asTuple node.node.memory.style.padding = padding.asTuple node.node.memory.style.border = border.asTuple + node.node.memory.style.position = position.asCompactTuple node.node.memory.style.position_type = css_position_type_t(positionType.rawValue) node.node.memory.style.flex = Float(flex) node.node.memory.style.flex_direction = css_flex_direction_t(flexDirection.rawValue)