Compare commits

..

122 Commits
1.4.1 ... 1.7.0

Author SHA1 Message Date
Pascal Hartig
0c3168f150 v1.7.0
Summary: Version bumps.

Reviewed By: emilsjolander

Differential Revision: D6284124

fbshipit-source-id: 08f6116bb0237791210847976533206055376f1a
2017-11-16 03:15:52 -08:00
Pascal Hartig
40861c699e Modernize Android build system, bump dependencies
Summary:
- Build against Android SDK 26
- Upgrade to Gradle 4
- Upgrade to Android Plugin 3.0, adjust dependency management accordingly
- Upgrade Maven deployment plugin

Reviewed By: emilsjolander

Differential Revision: D6272007

fbshipit-source-id: b198b4c8e1a94e2ee031ad26193fdfdf5b52adf1
2017-11-08 09:47:26 -08:00
Daniel Tsuan
d8fee24778 Set link_whole true for YogaKit and IGListKit
Summary: For our -objc efforts we'll be excluding vendorlibs from these changes for now and then working on getting them to not have to be fully linked as a second effort. The way -objc flag works is its an all or nothing flag for the app and thus for any library we still want to link completely we'll have to add a link_whole = True to the BUCK file. (Otherwise we'll have crashes in these libraries :P).

Reviewed By: kastiglione

Differential Revision: D6252740

fbshipit-source-id: fe074977a11b70c4aa63a4c69cb7518906c98eb9
2017-11-07 14:36:48 -08:00
Richard Ross
5c617a5947 Mirror AsyncExecutor, yoga, and nanosvg to fbcode.
Summary: We'll need these libraries for rainbow, and none of them exist in fbcode.

Reviewed By: mzlee

Differential Revision: D5897801

fbshipit-source-id: c379b76fef2ab204555ceded0834efc6ba932f90
2017-11-01 16:42:21 -07:00
Chandra Patni
ff0a3f39d9 use > || YGFloatsEqual instead of >= for computing round value to pixel grid
Summary: YGRoundValueToPixelGrid does not handle float point values correctly. It causes layout bugs in arm 32 devices. The way values are rounded to pixel grid is the following: if value is close to the left pixel - discard error and set it equal to left pixel. If value is close to right pixel - set it equal to the right pixel. Otherwise if value is closer to the left - set it equal to the left, closer to the right - set it equal to the right. The problem is when values are close to the middle. Old implementation could produce either left or right boundaries. This patch moves all values that are close to the middle to right boundary. This way results are consistent.

Reviewed By: emilsjolander

Differential Revision: D6202484

fbshipit-source-id: bb80235452208caec388775574cc4f07bfd649c4
2017-11-01 15:52:49 -07:00
Georgiy Kassabli
bfb4dabf0c Fixing the edge case in Yoga with percentage absolute position and infinite constraint
Summary: Yoga has an edge case that cause layout to return NaN. This happened when we used absolute position with percentage and infinite constraint in that dimension. This diff fixes that case to default to border+padding

Reviewed By: emilsjolander

Differential Revision: D6199731

fbshipit-source-id: f40ddf00614b2f507848fb35f348a9dfef14b323
2017-11-01 06:40:10 -07:00
Pritesh Nandgaonkar
58d14ee557 Reverting the dirty child optimization
Summary: Reverting D6134754

Reviewed By: emilsjolander

Differential Revision: D6203290

fbshipit-source-id: 8e42abb70e55f0fac90faaa21ecdbe0fbb76ce6b
2017-10-31 23:23:01 -07:00
Pritesh Nandgaonkar
c5182c4bf5 Used hasDirtyChildren tag for the optimization
Summary:
More fine grained dirty marking

Currently a node's dirty flag propagates to the root of the tree ensuring that when any node is invalidated its whole subtree will be re-calculated. This is often times not needed. There are many properties which only effects a node's children and would not need to propagate all the way to the root such as align-items. Also in cases where the style does change layout it may not need to propagate all the way to the root but can often stop at the nearest position: absolute parent.

This change has the potential of greatly improving performance of re-calculating a tree.

This might require adding a second dirty flag named hasDirtyDescendants ensuring that traversal still works even though a parent is not marked as dirty.

Reviewed By: emilsjolander

Differential Revision: D6134754

fbshipit-source-id: bbcfee14058140b946401de756a3f130de0f51cd
2017-10-31 08:22:29 -07:00
Jonathan Keljo
132b016bae Automated fixups for Instagram
Summary:
Source-only ABIs are a new feature of Buck that allows massive parallelism
by generating ABI jars from just the source code (without looking at most
dependencies). Because dependencies are not available, the generator
makes assumptions about how we write Java code. This commit updates
Instagram's code to conform to those assumptions.

These changes were generated by Buck's automatic migration script.

Reviewed By: dreiss

Differential Revision: D6168048

fbshipit-source-id: 0e51319d93fd697db01ea3933f48cd06a6ffac12
2017-10-27 01:14:24 -07:00
Sebastian Markbage
4785e95a0c Persistent Yoga
Summary:
This is meant to show a possible route format for a persistent form of Yoga. Where previous layouts can remain intact while still taking advantage of incremental layout by reusing previous subtrees.

```c
YGNodeRef YGNodeClone(const YGNodeRef node);
```

The core of this functionality is a new API to clone an existing node. This makes a new detached node with all the same values as the previous one. Conceptually this makes the original node "frozen" from that point on. It's now immutable. (This is not yet enforced at runtime in this PR but something we should add.)

Since the original is frozen, we reuse the children set from the original node. Their parent pointers still point back to the original tree though.

The cloned node is still mutable. It can have its styles updated, and nodes can be inserted or deleted. If an insertion/deletion happens on a cloned node whose children were reused, it'll first shallow clone its children automatically.

As a convenience I also added an API to clear all children:

```c
void YGNodeRemoveAllChildren(const YGNodeRef node);
```

During insert/delete, or as a result of layout a set of reused children may need to be first cloned. A kind of copy-on-write. When that happens, the host may want to respond. E.g. by updating the `context` such as by cloning any wrapper objects and attaching them to the new node.

```c
typedef void (*YGNodeClonedFunc)(YGNodeRef oldNode,
                                 YGNodeRef newNode,
                                 YGNodeRef parent,
                                 int childIndex);

void YGConfigSetNodeClonedFunc(YGConfigRef config,
                               YGNodeClonedFunc callback);
```

This PR doesn't change any existing semantics for trees that are not first cloned.

It's possible for a single node to exist in two trees at once and be used by multiple threads. Therefore it's not safe to recursively free a whole tree when you use persistence. To solve this, any user of the library has to manually manage ref counting or tracing GC. E.g. by replicating the tree structure in a wrapper.

In a follow up we could consider moving ref counting into Yoga.
Closes https://github.com/facebook/yoga/pull/636

Reviewed By: emilsjolander

Differential Revision: D5941921

Pulled By: sebmarkbage

fbshipit-source-id: c8e93421824c112d09c4773bed4e3141b6491ccf
2017-10-17 01:11:11 -07:00
Pascal Hartig
be94a5ef8d Fix NDK download in Travis
Summary:
After about 500MB, Travis seems to kill the TLS connection. Could be a traffic
limit, could be a timeout. I've only seen this for their MacOS boxes. We're now
retrying a few times with curl, which seems to work.

Reviewed By: emilsjolander

Differential Revision: D6051024

fbshipit-source-id: feb73bfb9fd81b2a8b9b4d33d4e9f230a9899a66
2017-10-13 06:56:18 -07:00
Pascal Hartig
208b70a93c Fix license check
Summary: This seems to have changed upstream.

Reviewed By: emilsjolander

Differential Revision: D6050471

fbshipit-source-id: b453831c1d5a5974572265a78da40b0612b1d1f2
2017-10-13 03:56:35 -07:00
Pascal Hartig
6c3155ae3b Download right NDK for Travis
Summary:
I'm a big dummy.

https://travis-ci.org/facebook/yoga/jobs/257605319

Reviewed By: emilsjolander

Differential Revision: D6040274

fbshipit-source-id: e73225e6e2e1e899c25326030ac522d5a7aa06a5
2017-10-12 08:41:55 -07:00
Pascal Hartig
32f071c2ad Fix NDK download
Summary: Fix NDK download for Travis.

Reviewed By: emilsjolander

Differential Revision: D6020352

fbshipit-source-id: c7523c0afb18d675fc2443e133d5ab63109fec7b
2017-10-11 08:19:51 -07:00
Pascal Hartig
fdd1dbe3a9 Update buildScript deps
Summary:
The native-dependencies plugin seems unused. Upgrade to the latest
gradle-bintray-plugin version that's supported for the current Gradle version.

I'll hold back the upgrade to Gradle 4 until the Gradle Android Plugin for the
version hits stable.

Reviewed By: IanChilds

Differential Revision: D5986549

fbshipit-source-id: d26aa19e9eba40a2b30b20d5ffa9d2b006450f95
2017-10-06 02:26:15 -07:00
Pascal Hartig
1ca5bb694d Use NDK 15c
Summary: To match internal config.

Reviewed By: emilsjolander

Differential Revision: D5986514

fbshipit-source-id: b0e7dbc060c106f17f8e1c5e54e5b951d9e3e350
2017-10-06 02:26:15 -07:00
Marko Novakovic
b4cfaa916c Un-inline-ing a method declared as export
Reviewed By: compnerd

Differential Revision: D5909847

fbshipit-source-id: 7108dd88271e640e1881b20c0cbf1ad28bbf63c9
2017-09-26 19:12:42 -07:00
Michael Lee
fc6c85996e Reformat BUCK files
Summary: Reformat BUCK files to better conform with style.

Reviewed By: zertosh

Differential Revision: D5901515

fbshipit-source-id: 93e8c56450f65b691af9017d880e6cf2a2cdb7af
2017-09-25 10:16:22 -07:00
Andrew Gallagher
969f055f47 Deprecate older API uses of prebuilt_cxx_library
Summary:
Use the `deprecated_prebuilt_cxx_library` wrapper instead of the deprecated
API of `prebuilt_cxx_library`.

Reviewed By: ttsugriy

Differential Revision: D5878523

fbshipit-source-id: 2c8c1fd1d19597ff7459bbd527c89573520db74b
2017-09-22 13:27:32 -07:00
Bin Yu
58328d01ef Add 'useYoga' property to indicate whether UIView uses Yoga for layout or not
Summary: Now developer could check whether UIView uses Yoga for layout.

Reviewed By: emilsjolander

Differential Revision: D5881242

fbshipit-source-id: 4d1cf0b489b759ff0b9c5091cc51534fd12dcf60
2017-09-21 10:18:52 -07:00
Mingwei Pan
d90914f3dc Improve formatting of YogaNode.print() on Android
Summary:
The Android logger adds newline automatically, which makes the log ugly on Android.
To avoid that, wrap the android logger, print to a memory buffer.  Call __android_log_write() when '\n' is detected.

Reviewed By: emilsjolander

Differential Revision: D5842889

fbshipit-source-id: 8ecc829dc43614934c47fd3a68317259e403325a
2017-09-21 07:41:37 -07:00
Emil Sjolander
3a0a86788e Revert D5874862: [yoga][PR] Fix shrinking in non strech alignments
Summary:
This reverts commit 1426aa6b60f6ba42c2be702e6f24cea935ab7acb

bypass-lint

Differential Revision: D5874862

fbshipit-source-id: 24517d26b18c11fb9f75c6d3b5faae360711ea9e
2017-09-21 03:41:19 -07:00
Lukas Wöhrl
a77aa9a41e Fix shrinking in non strech alignments
Summary:
This fixes shrinking of elements which are in a non stretch alignment

Fixes #633
Closes https://github.com/facebook/yoga/pull/634

Differential Revision: D5874862

Pulled By: emilsjolander

fbshipit-source-id: 1426aa6b60f6ba42c2be702e6f24cea935ab7acb
2017-09-20 13:30:39 -07:00
Shaddix
7217471427 fix build, correctly size UIScrollViews
Summary: Closes https://github.com/facebook/yoga/pull/626

Reviewed By: emilsjolander

Differential Revision: D5824425

Pulled By: splhack

fbshipit-source-id: e1a8dda5e86e2705afa7f6630a6757491a94c6d6
2017-09-19 09:41:41 -07:00
Mingwei Pan
bcc36cc1b2 Zero out all fields in YGZeroOutLayoutRecursivly using memset
Summary:
Add a new test named YGZeroOutLayoutRecursivlyTest, which verifies that padding and margin of a child node should be set to 0 when the display is set to none.
Modify YGZeroOutLayoutRecursivly function, use memset to clear the layout struct of the node.

Reviewed By: emilsjolander

Differential Revision: D5842351

fbshipit-source-id: d2c2b6f829588a200525b7ccbdb63003cb4dcc4e
2017-09-15 08:32:36 -07:00
Amir Shalem
16052085d0 Fix YogaLogger leakage when removing it from YogaConfig
Summary: -

Reviewed By: emilsjolander

Differential Revision: D5802035

fbshipit-source-id: 79c1f8c3cc5ddf3abd51206f23e076f2410cfc0c
2017-09-11 03:14:11 -07:00
Lukas Wöhrl
c20f2864ab Only add UIView nodes to Yoga where they are enabled
Summary:
Only add UIView nodes to Yoga where they are enabled.

We check for it in `isLeaf` but I think we should also check for them in the check for sub views.
Closes https://github.com/facebook/yoga/pull/609

Reviewed By: emilsjolander

Differential Revision: D5643387

Pulled By: dshahidehpour

fbshipit-source-id: a85c62b6b2e0120b2913e7f2df8b094d43ca49a6
2017-08-23 15:46:51 -07:00
Lukas Wöhrl
4185a44393 Fix const declaration mismatch and double/float mix
Summary:
This PR fixes a declaration mismatch for `YGNodeCanUseCachedMeasurement` where the last argument is declared non `const` in `.h` and `const` in `.c`.

Additionally it uses explicit `float` for fraction calculation do avoid usage of `double` assignment.
Closes https://github.com/facebook/yoga/pull/607

Differential Revision: D5677931

Pulled By: emilsjolander

fbshipit-source-id: 502da957089e4439ed956987ff8dec10bd033ba3
2017-08-23 03:02:16 -07:00
Scott Wolchok
c79c5e3c9d Make gYGNodeDefaults const
Summary: At least one compiler seems to care about it.

Reviewed By: emilsjolander

Differential Revision: D5675518

fbshipit-source-id: 72a6e208263dde0b6bb46a78fedb2796d0e0a600
2017-08-22 11:56:21 -07:00
Emil Sjolander
35a9f33abb BREAKING: Change aspect ratio behavior
Summary:
@public

== Before ==
- Aspect ratio would do its best to fit within it's parent constraints
- Aspect ratio would prioritize `alignItems: stretch` over other sizing properties.

== After ==
- Aspect ratio is allowed to make a node grow past its parent constraints. This matches many other aspects of flexbox where parent constraints are not treated as hard constraints but rather as suggestions.
- Aspect ratio only takes `alignItems: stretch` into account if no other size definition is defined. This matches the interaction of other properties with `alignItems: stretch`.

== Updating your code ==

**You probably don't need to do anything** but in case something does break in your product it should be as easy as  adding `{width: '100%', height: '100%', flexShrink: 1}` to the style declaring the `aspectRatio`.

Reviewed By: gkassabli

Differential Revision: D5639187

fbshipit-source-id: 603e8fcc3373f0b7f2461da2dad1625ab59dcb19
2017-08-21 03:12:00 -07:00
Hoa Dinh
32f128640b Revert D5643382: [yoga][PR] Fix a typo in YogaKit,
Summary:
This reverts commit 127b0c11dbfd76d298db823e65fd2f6e365642e7

bypass-lint

Differential Revision: D5643382

fbshipit-source-id: f25b04680428bcd4515c44741ed72a004be43ef1
2017-08-17 15:48:47 -07:00
Luc Dion
18d19af7ec Fix a typo in YogaKit,
Summary:
`YGDimensionFlexibilityFlexibleHeight` it was wrongly spelled `YGDimensionFlexibilityFlexibleHeigth`.

[X] Test suite passes
[X] Contributor License Agreement
Closes https://github.com/facebook/yoga/pull/605

Reviewed By: amonshiz

Differential Revision: D5643382

Pulled By: dshahidehpour

fbshipit-source-id: 127b0c11dbfd76d298db823e65fd2f6e365642e7
2017-08-17 14:42:03 -07:00
Levi McCallum
2ee2dd439f Fix link to YGLayout header in docs
Summary: Closes https://github.com/facebook/yoga/pull/595

Reviewed By: amonshiz

Differential Revision: D5643379

Pulled By: dshahidehpour

fbshipit-source-id: ae972f270ee26fe7755ba5dee4d357d150a27c2a
2017-08-17 13:56:37 -07:00
Lior Tubi
5edfb679e7 Add a java binary buck target
Summary: .

Reviewed By: amir-shalem

Differential Revision: D5619667

fbshipit-source-id: e956190be0c6a7ea573e5511231de28aab5586fe
2017-08-13 07:32:11 -07:00
Georgiy Kassabli
f45059e1e6 Fixing edge case issue in Yoga where text node was unnecessary rounded down
Summary: There was an uncovered edge case where number close to the whole was forced to round down because it was considered non-whole and had forced flooring. This diff covers that + adds a bunch of test cases to cover rounding function

Reviewed By: emilsjolander

Differential Revision: D5465632

fbshipit-source-id: 57e11092a97eba5dd76daad15fa8619535ff9c1b
2017-07-26 19:38:31 -07:00
Pascal Hartig
c9384762ee Fix NDK build, Take II
Summary:
There was one incorrect path and some caching problems. I hope this will take
care of it for good.

Reviewed By: emilsjolander

Differential Revision: D5470120

fbshipit-source-id: 17c9e783c952c92fa5c2ccfb18107a59d8a80e3d
2017-07-21 08:29:43 -07:00
Pascal Hartig
7ea50439ce Fix travis NDK setup
Summary:
Phew, this took a while. Buck had some changes in how it picks up SDK/NDK
configs.

In order to satisfy the new demands, I'm now installing the NDK manually and no
longer through the SDK manager. I'm also trying to cache as much as possible to
reduce the flakiness here.

Reviewed By: emilsjolander

Differential Revision: D5465206

fbshipit-source-id: 61a4b9006fe96fc9a99fb9d75b822589064a9d1a
2017-07-21 03:14:21 -07:00
Pascal Hartig
154e67adbc Bump to 1.6.1-SNAPSHOT
Summary:
Set to the next snapshot version so automatic snapshot publishing is reenabled.
We need those to keep in sync with the Litho snapshots.

Reviewed By: emilsjolander

Differential Revision: D5442493

fbshipit-source-id: ecb92071ec8edb9c3c6b625c08f5aad20368d0a3
2017-07-18 11:46:10 -07:00
Lukas Wöhrl
570a193b7e Update c# docs to use object initializer
Summary:
Updates the C# docs to use the object initializer instead of `Create` which doesn't exist anymore.

Fixes facebook/yoga#550.
Closes https://github.com/facebook/yoga/pull/601

Reviewed By: emilsjolander

Differential Revision: D5427217

Pulled By: splhack

fbshipit-source-id: 9a2f036335e5ab475d5c1ee8308701ccb5a3b4e4
2017-07-14 16:13:07 -07:00
Emil Sjolander
79e294c927 1.6.0 version bumps
Reviewed By: passy

Differential Revision: D5415450

fbshipit-source-id: cf3c42303c4a63adf114199618d42dabdb123c42
2017-07-13 08:27:10 -07:00
Georgiy Kassabli
5d75c7c4c8 Fixing the issue with node dimensions rounding in Yoga
Summary: Yoga had a bug in Rounding calculation that caused text nodes dimensions to be rounded up even when the dimensions didn't need rounding

Reviewed By: emilsjolander

Differential Revision: D5406211

fbshipit-source-id: df1d54ed0805dfc3abbd8f0ceae30f6d8c26d61a
2017-07-12 09:33:51 -07:00
vincentriemer
7c688cea68 Add babel processing to browser build to remove references to node builtins
Summary:
Currently the nbind asm.js output generates boilerplate code which can conditionally load node's `fs` and `path` modules. If this output is run directly in the browser there are no issues but if you run it through a bundler the build step will fail trying to resolve the node builtins.

Workarounds currently exist for bundlers like webpack (mentioned in #444) but this is not a safe assumption to make (for example such workarounds don't exist for `metro-bundler`).

I am by no means suggesting that this is the perfect solution but this might provide a stop-gap fix for people who are currently blocked by this issue (like I am).
Closes https://github.com/facebook/yoga/pull/585

Differential Revision: D5388660

Pulled By: emilsjolander

fbshipit-source-id: d3a51eb852df35e3d0610158fe7d9f5754e4e684
2017-07-10 12:00:37 -07:00
Lukas Wöhrl
7640cd667f Reset the hadOverflow flag at the beginning of the algorithm
Summary:
This fixes the case where we change the layout, so that it doesn't overflow anymore.

This also improves the readability by using `|=` instead of referencing the value twice.
Closes https://github.com/facebook/yoga/pull/587

Differential Revision: D5388657

Pulled By: emilsjolander

fbshipit-source-id: ce1b1ded1feed7314a2c16bf695f62b866c19ea0
2017-07-10 12:00:37 -07:00
Lukas Wöhrl
24e2fc95dd Fix text node rounding with fractional dimensions matching the rounding factor
Summary:
If we have a fractional measure output which matches the subpixel rounding factor, we still should round both dimension into the same direction.

Fixes facebook/yoga#580.
Closes https://github.com/facebook/yoga/pull/583

Reviewed By: marco-cova

Differential Revision: D5274212

Pulled By: emilsjolander

fbshipit-source-id: 1febf9194210437ab77f91319d10d4da9b284b79
2017-07-04 06:27:24 -07:00
Andrey Mishanin
ce3f99939f Overflow detection in Yoga
Summary:
We need to provide Yoga clients with means of detecting overflow in flexbox layout. This information can be used later to identify a non-overflowing layout variant among others.

Flexbox layout considered overflown if (this is *not* an exhaustive list):

- if any child node overflows
- [no-wrap] total flex basis of all child nodes is greater than available space in parent and there are no flexible children
- [no-wrap] after flexing there is still not enough space to layout all child nodes

Reviewed By: gkassabli

Differential Revision: D5336645

fbshipit-source-id: c4f87d1754d7bac848e8d347b31d619393b94d2c
2017-06-30 09:26:57 -07:00
Lior Tubi
11bc97b16c Don't load fb native library
Summary: We don't bundle this library with the yoga source, and it isn't needed.

Reviewed By: emilsjolander

Differential Revision: D5274172

fbshipit-source-id: fec47d2700da86498410fe445d2980f31a563551
2017-06-19 05:42:52 -07:00
Matthew Jarjoura
4804bcd594 make sure YGPointValue works in Obj-C++
Summary:
This is an easy diff to wrap YGPointValue() in an extern "C" block to make sure it compiles
when we are using inside of Objective-C++ classes.

Reviewed By: emilsjolander

Differential Revision: D5242366

fbshipit-source-id: 772aaac056b3a20041926d5f35128716848a271a
2017-06-16 11:12:31 -07:00
Lukas Wöhrl
ca2c607f90 The total flex factores need to be a minimum of 1 if any
Summary:
The only thing I found in the spec for this change is the following. Not exactly sure if this is the thing this PR is about:

> For each flex item, subtract its outer flex base size from its max-content contribution size. If that result is not zero, divide it by (if the result was positive) its **flex grow factor floored at 1** or (if the result was negative) by its scaled flex shrink factor, having **floored the flex shrink factor at 1**. This is the item’s max-content flex fraction.

But at least it seems a required change.

Fixes facebook/yoga#566
Closes https://github.com/facebook/yoga/pull/572

Differential Revision: D5264388

Pulled By: emilsjolander

fbshipit-source-id: 0004d1c3b9bad070a98cd6766c1adc06a54475f8
2017-06-16 07:46:06 -07:00
sospartan
6c67684fa6 Change android minimum SDK version to 14
Summary:
The library(yoga) has no dependency on android framework. As a matter of
fact this version can change to a lower number which will make yoga
support more old systems.

According to I/O 17, support library has change its minimum SDK version
 to 14, so I think 14 is a reasonable min support version for yoga as well.

See
https://developer.android.com/topic/libraries/support-library/revisions.html
Closes https://github.com/facebook/yoga/pull/573

Differential Revision: D5264385

Pulled By: emilsjolander

fbshipit-source-id: cb813a3b643a3f4e2034c6c0ab8b488f94d6a7d0
2017-06-16 06:43:28 -07:00
Pascal Hartig
835b2bbae8 Fix license headers
Summary:
They were set up as javadocs (double-asterisk at the start) but should be normal
block headers.

Reviewed By: IanChilds

Differential Revision: D5255424

fbshipit-source-id: 23439ac035f74f2fd1c756b8185e39199e748e33
2017-06-15 07:41:44 -07:00
Pascal Hartig
47edd2586c Bump gradle plugin version
Summary:
Same as litho, just for compat with Android Studio. Shouldn't affect the
project.

Reviewed By: emilsjolander

Differential Revision: D5217956

fbshipit-source-id: 32cfec0bf4ab4e51f5e4116149ee091cf1245e95
2017-06-10 08:28:58 -07:00
Marco Cova
ca483cae00 Rounding error in width/height fixed
Summary: If the width has an exact dimension, while the left and right edges have a decimal part, that means the decimal part is equal and we can round both down instead of rounding left down and right up. Same for top and bottom.

Reviewed By: emilsjolander

Differential Revision:
D5209073

Tags: accept2ship

fbshipit-source-id: a3a6a43767aa707ebfa5eee62a83adcdd88d7ce6
2017-06-10 05:45:35 -07:00
Lukas Wöhrl
a20bde8444 Fix absolute position if wrap-reverse and align-items: flex-end
Summary:
This is a fix on top of 56b10fc. It takes the case into account were you have `wrap-reverse` and `align-items: flex-end` set.
Closes https://github.com/facebook/yoga/pull/568

Differential Revision: D5155521

Pulled By: emilsjolander

fbshipit-source-id: 7e5fcfa2fbb48b6c6279da46cc648a071ff2b079
2017-06-01 05:41:25 -07:00
Christian Oliff
ac885626b3 Correct capitalization of JavaScript
Summary:
Correct capitalization of JavaScript
Closes https://github.com/facebook/yoga/pull/569

Differential Revision: D5155524

Pulled By: emilsjolander

fbshipit-source-id: 48d9a28a61bb96af42241aa2ed6ac3d070adeaf9
2017-05-31 10:27:00 -07:00
Emil Sjolander
976ecc6816 Version bump
Summary: Version bump

Reviewed By: passy

Differential Revision: D5155064

fbshipit-source-id: a6d896b6b8741ea947cb5cc36c2a2f9333edfb2a
2017-05-31 08:27:41 -07:00
Emil Sjolander
d2f22283bb Fix confusing variable name
Summary: Variable name suggest it does not constrain to min dimension but it did indeed. Changing that to match variable name. This required updating code to use fully constraint value again. gkassabli this seems wrong, do you know what is going on?

Reviewed By: gkassabli

Differential Revision: D5144146

fbshipit-source-id: a5d711f8ad7049b0d96ee0f0f3eef1165ab3b4e8
2017-05-29 07:57:00 -07:00
Emil Sjolander
56b10fc35b Fix absolute positioning in reverse wrapping container
Summary: aligning with odd web behaviour

Reviewed By: gkassabli

Differential Revision: D5144145

fbshipit-source-id: da6ef999ec0aabacf499017d1cfa81fc8f66e4bd
2017-05-29 07:57:00 -07:00
Eduardo Gonzalez
5a3ceffba1 Add .editorconfig
Summary:
Just add .editorconfig into yoga 😄
Closes https://github.com/facebook/yoga/pull/562

Differential Revision: D5144025

Pulled By: emilsjolander

fbshipit-source-id: 9f28caaff276b266ac2aa514097fda6972b85f7c
2017-05-27 09:12:22 -07:00
Georgiy Kassabli
b378a685a4 Changed pointScaleFactor usage to avoid accumulating error
Summary: Previously pointScaleFactor was stored as a divider that opened way to accumulating difference. For instance in ScreenScale=3, pointScaleFactor = 0.3333343 (0.000001 error). When used for width = 300 that error was multiplied by the number of times pointScale contained in width (300 *3 = 900) and we had almost 0.001 error accumulated. With this change Yoga will avoid such issue

Reviewed By: shergin

Differential Revision: D5137923

fbshipit-source-id: 652b59bc3da3f35ee93ffa3695936f623298a023
2017-05-26 10:57:12 -07:00
Pascal Hartig
fa50f048f1 Only decrypt if keys are present
Summary:
Travis doesn't set encrypted variables in pull requests (for very good reasons),
but openssl fails rather loudly if it doesn't get them. Our artifact publishing
script happily skips PRs anyway, so we don't need these variables in that case.

Reviewed By: emilsjolander

Differential Revision:
D5137092

Tags: accept2ship

fbshipit-source-id: b14d61feba0bb98a1705b2f8232f52ba59a2c734
2017-05-26 04:13:01 -07:00
Emil Sjolander
f68b50bb4b Parse YogaValue from string. inverse of toString()
Summary: Implement the inverse of toString. This allows us to parse a YogaValue from a string inputted from the user in debugging tools.

Reviewed By: kittens

Differential Revision: D5120456

fbshipit-source-id: 6ac7cff2a040778e63a953070e1bd7e768fedaa7
2017-05-24 07:56:49 -07:00
Brian Cooke
aad1c3055c Move sdks = out to YOGA_DEFS
Summary: To fix builds where `sdks =` is not supported.

Reviewed By: splhack

Differential Revision: D5113020

fbshipit-source-id: b716acd6fb88ccb55c72b24f9fcdf20a2ea3693e
2017-05-23 12:12:45 -07:00
Georgiy Kassabli
cd1dbc3f0f Fixing potential measure call with negative size value
Summary: There is a case when measure() function will be called with negative width/height because of margin/padding. This diff fixes that scenario

Reviewed By: emilsjolander

Differential Revision: D5111534

fbshipit-source-id: 99f09b85f0c6a0e5dec89a26baba8f9d560100da
2017-05-23 11:12:10 -07:00
Pascal Hartig
bf4ff0769d Use 'dumb' terminal for Gradle
Summary: This makes the output less messy.

Reviewed By: emilsjolander

Differential Revision: D5111279

fbshipit-source-id: c65c7f275e57312fb56c2edfec429cc3d2373e3f
2017-05-23 03:57:34 -07:00
Pascal Hartig
a141ebfb50 Run Android tests with Gradle
Summary:
Make sure that the gradle tests pass before publishing the snapshot. Also makes
sure that we don't break the gradle build.

Reviewed By: emilsjolander

Differential Revision: D5020044

fbshipit-source-id: dfebd829701717eac3ed078a807cd10f489f4348
2017-05-23 03:57:33 -07:00
Jernej Strasner
2fb01daf70 Expose calculateLayoutWithSize in YogaKit
Summary:
calculateLayoutWithSize: can be useful when calculating table/collection view sizes before the views are fully laid out by UIKit.
Closes https://github.com/facebook/yoga/pull/558

Differential Revision: D5104863

Pulled By: emilsjolander

fbshipit-source-id: e0e0c6d502f6745be8d84de8c1b6e24cc25a0352
2017-05-22 11:41:55 -07:00
Pascal Hartig
e9e1e084da Enable unit tests with Gradle
Summary:
This adds the same logic that we have in place with Litho for Yoga, allowing
unit tests to run with Gradle for Yoga. It'll still shell out to Buck to build
the native library, but that's hopefully only until we have found a way to reuse
the NDK build. For CI this shouldn't matter as we want to run `buck build`
anyway and the build step should be a no-op.

FB-Only:
This should unlock D5020044.

Reviewed By: emilsjolander

Differential Revision: D5104154

fbshipit-source-id: 48732fff6c1d100a155452f675de343aaf06427b
2017-05-22 10:11:49 -07:00
yihuang
629e401deb Fix right/bottom in absolute layout.
Summary:
1, Change bottom to be based� on height of parent.
2, Respect margin value when layout with right/bottom.
Closes https://github.com/facebook/yoga/pull/552

Differential Revision: D5102090

Pulled By: emilsjolander

fbshipit-source-id: dca291413ffc2027d7628f4c8b8eeeb0b4823bc2
2017-05-22 02:56:41 -07:00
Chiamaka Nwolisa
f4c2b6ae63 Fix Typo
Summary: Closes https://github.com/facebook/yoga/pull/556

Differential Revision: D5102089

Pulled By: emilsjolander

fbshipit-source-id: 340cab34189628318c08ec45fe8c50a5c1970a17
2017-05-22 02:33:05 -07:00
yihuang
4487862227 fix print edge value.
Summary: Closes https://github.com/facebook/yoga/pull/551

Differential Revision: D5069358

Pulled By: emilsjolander

fbshipit-source-id: 8a8f07043d43f9f2d846a645217a52913cffe31b
2017-05-21 07:00:25 -07:00
Brian Cooke
927eca6604 Enable YogaKit for tvOS
Summary:
This is used in a stack where I'm using YogaKit on tvOS. fb_apple_library needs `sdks = ` to get buck to do its thing for tvOS.

This seems like it should be OK since apple_library is a nop on non apple platforms (which makes sense since this is ObjC only) - I think that makes sense anyway?

Reviewed By: emilsjolander

Differential Revision: D5080261

fbshipit-source-id: f08d7e6d2599b9af25fb964ade485aef552f306b
2017-05-18 06:03:25 -07:00
Georgiy Kassabli
f2612192c5 Fixing using flex in root node
Summary: We should always try to make root node as small as possible, while previously this wasn't functioning this way

Reviewed By: emilsjolander

Differential Revision: D5071164

fbshipit-source-id: b8afef42477d0ed87d0c9fcfd26349e0a0babd6e
2017-05-17 07:28:30 -07:00
Rui Marinho
49bccf47fa Fix windows and osx builds
Summary: Closes https://github.com/facebook/yoga/pull/555

Reviewed By: emilsjolander

Differential Revision: D5071045

Pulled By: splhack

fbshipit-source-id: f9e387242055e0a4a7c330c7bf99ed4a4b4057be
2017-05-16 12:42:08 -07:00
cregnier
fa54167a20 fixes #411 - add npm config platform env var in order to set which js…
Summary:
… platform will be built
Closes https://github.com/facebook/yoga/pull/537

Differential Revision: D5069356

Pulled By: emilsjolander

fbshipit-source-id: eaa67d17fe9d5ed9d0959781ed12a238cb3d95f2
2017-05-16 10:57:03 -07:00
Rui Marinho
50feb21cb3 Centralize native dependencies build script
Summary: Closes https://github.com/facebook/yoga/pull/554

Differential Revision: D5069362

Pulled By: emilsjolander

fbshipit-source-id: 7cf65233928c11010337ee21c633173ea919cc94
2017-05-16 09:59:13 -07:00
Kazuki Sakamoto
52ce5828c9 Use buck release for csharp/build-native.sh
Summary: Closes https://github.com/facebook/yoga/pull/553

Differential Revision: D5069363

Pulled By: emilsjolander

fbshipit-source-id: 2a88f0f53147b5abf1d4eb26f05108c2c001a8f5
2017-05-16 08:11:46 -07:00
Georgiy Kassabli
9cdaedfcb5 Correct YGNodeCanUseCachedMeasurement to account for non-existent scale factor
Summary: When config was added to YGNodeCanUseCachedMeasurement we didn't account for default 0 scale factor. This diff fixes that

Reviewed By: emilsjolander

Differential Revision: D5061016

fbshipit-source-id: 907ef987bd0ead29cf02f6945a3f03d4ffb58a2e
2017-05-15 08:41:30 -07:00
Georgiy Kassabli
adad054cad Adding ability to account for rounding in YGNodeCanUseCachedMeasurement
Summary: We want to be able to use YGConfig to account for possible rounding of width/height

Reviewed By: emilsjolander

Differential Revision: D5059560

fbshipit-source-id: d729e991758a8c668a4b373105b71337961875cd
2017-05-15 06:28:39 -07:00
Emil Sjolander
b2b0c7ee37 Fix typo causing wrapped children to be sized by wrong axis margin
Summary: Fixes https://github.com/facebook/yoga/issues/548

Reviewed By: passy

Differential Revision: D5044470

fbshipit-source-id: 7d203dd48b258a5fe5c4b3c493099092a1d334db
2017-05-12 09:12:51 -07:00
Emil Sjolander
488a7c1fe0 Include margin when calculating if children overflow
Summary: Include margin when calculating if children overflow

Reviewed By: passy

Differential Revision: D5044471

fbshipit-source-id: e7c1eb694445ffb898bcf375d9deefc558c49f11
2017-05-12 09:12:51 -07:00
Emil Sjolander
85c2e406e4 Fix flex basis not accounting for max size constraint
Summary: Fix flex basis not being constraint to the max size in the main direction. Previously this caused the added test to fail due to NaN in child dimensions.

Reviewed By: gkassabli

Differential Revision: D5044314

fbshipit-source-id: d9f9db832e4943a57a89c9d162ff6077b709795a
2017-05-12 09:12:51 -07:00
Emil Sjolander
dcf57d2f7e Big refactor moving most logic into DebugComponent
Summary: This adds very little (no?) new features and mostly just refactors code to live in a singular place. Instead of users having to worry about DebugComponent as well as the DebugInfo object and attaching it correctly to a tree now user's of the DebugComponent API only need to worry about a single class, greatly simplifying its usage.

Reviewed By: passy

Differential Revision: D5027780

fbshipit-source-id: 95a95b3572747aa2088f8f9b35a160257eb59269
2017-05-12 03:57:10 -07:00
Georgiy Kassabli
3fefe9fc49 Adding node type and moving rounding dependency to rely on that type
Summary: This diff adds node type definition to Yoga and moves rounding to rely on the node type. If the node has measure function we consider that node to be text node, otherwise we have default behavior.

Reviewed By: emilsjolander

Differential Revision: D5025107

fbshipit-source-id: a8d66e2f9c5d02ab080784cc474be583a09b92e2
2017-05-11 08:15:46 -07:00
Pascal Hartig
626a05fb6f Update docs for SNAPSHOTs
Summary: Also bumped the version number for the existing dependency examples.

Reviewed By: emilsjolander

Differential Revision: D5044190

fbshipit-source-id: 4199ab114450a256efaa30a811822923beafb378
2017-05-11 05:27:02 -07:00
Pascal Hartig
ffcd2cfc8a Fix android build and enable snapshots
Summary:
Fix some long-standing issues with the android build on Travis (and elsewhere)
and enable automatic publishing of snapshots.

Reviewed By: emilsjolander

Differential Revision: D5044001

fbshipit-source-id: f00be07f33c8018573af0b98233068ebd93360b4
2017-05-11 03:47:16 -07:00
Pascal Hartig
181101c92d Bump snapshot version
Summary: Per title

Reviewed By: emilsjolander

Differential Revision: D5044000

fbshipit-source-id: f1058700daff115bdff52ff62b859b4b3f2e469e
2017-05-11 03:47:16 -07:00
Pascal Hartig
3db6804202 Fix sample app oss build
Summary: The appcompat library was way outdated and failed CI: https://travis-ci.org/facebook/yoga/builds/231065300

Reviewed By: emilsjolander

Differential Revision: D5043967

fbshipit-source-id: a5bb02110cf016972d983f511cf8c31dd9d667e1
2017-05-11 03:47:15 -07:00
Emil Sjolander
3fb135829d Release 1.5.0
Summary: Bump version and fix small issues blocking release

Reviewed By: passy

Differential Revision: D5036755

fbshipit-source-id: 65fa2cd09dad8108bdd21067fb44107b059732e8
2017-05-10 09:32:26 -07:00
Pieter De Baets
2c91e1e7d2 Mark ByteBuffer methods as const
Summary: So I can use them from JSBigString whose methods are marked const.

Reviewed By: emilsjolander

Differential Revision: D5020648

fbshipit-source-id: 6e60b80cb3d4718bab25dd6ca9627aee862117db
2017-05-10 04:26:22 -07:00
Pascal Hartig
c3982b6c1e Set up for automatic snapshot publishing
Summary:
Gets all the pieces in place to automatically publish snapshot artifacts after
successful travis build.

I'll test the actual publishing in a separate branch and then flip the switch in
a separate diff when it's ready.

Reviewed By: emilsjolander

Differential Revision: D5028239

fbshipit-source-id: c57d02a1dee41c84001bd17821b050c8c9aa4134
2017-05-09 08:52:36 -07:00
Pascal Hartig
ae33c6c19c Update Maven release scripts
Summary:
Reuse the gradle setup we've built for Litho which allows for parallel publishing to Bintray and Maven Central in addition to Sonatype Snapshots.

This appears not to break the existing jcenter deploy script which is pretty great.

Reviewed By: emilsjolander

Differential Revision: D5020576

fbshipit-source-id: 3ef163ccbfe91c6858b051d39dcf237ca388e18d
2017-05-09 03:41:51 -07:00
Pascal Hartig
bcd68b997f Add missing fbjni deps
Summary:
fbjni was previously dependency-free but now requires some annotations and
soloader. This unbreaks the gradle build.

Reviewed By: emilsjolander

Differential Revision: D5020069

fbshipit-source-id: b8bde83ce6a70b06e04491f1d70c2a6b568bc99c
2017-05-09 01:56:44 -07:00
Emil Sjolander
fcfa1b9f01 Update pod lock
Summary: run pod install

Reviewed By: gkassabli

Differential Revision: D5019525

fbshipit-source-id: 9cf5d22d8542560e377ab5c3be80ba3ea7ec3de2
2017-05-08 04:48:49 -07:00
Emil Sjolander
d9a0822517 Update formula location for android-sdk
Summary: follow brews instructions on changed location of android sdk

Reviewed By: passy

Differential Revision: D5010781

fbshipit-source-id: 8c39116c821befadb8a153870f365cd0d3a1140d
2017-05-05 10:16:08 -07:00
Emil Sjolander
097e99b699 Always use latest buck
Summary: Always use latest buck

Reviewed By: aiked

Differential Revision: D5010762

fbshipit-source-id: d0c7d36665fab0c58ea5e05d9880b849b3ccf745
2017-05-05 09:19:22 -07:00
Kazuki Sakamoto
ff7bec703b Fix build and test
Summary: Closes https://github.com/facebook/yoga/pull/543

Reviewed By: emilsjolander

Differential Revision: D4997389

Pulled By: splhack

fbshipit-source-id: b4b3aa4cba29063df93fd2a57f96031a8fa393de
2017-05-04 09:19:40 -07:00
Maël Nison
c7ab004922 Fixes Travis error reporting
Summary:
Just cherry-picked my commit from #508
Closes https://github.com/facebook/yoga/pull/542

Differential Revision: D5002335

Pulled By: emilsjolander

fbshipit-source-id: 3f61a235c41627e9cfb90dce150323f11892e65f
2017-05-04 07:45:28 -07:00
Lukas Wöhrl
91230ae177 Move YGLogger into YGConfig and associate YGNodeRef with log events
Summary:
Moves the `YGLogger` into `YGConfig` and pass the `YGNodeRef` into the logger to be able to associate the log messages and assertions with the specific node.

Tackles facebook/yoga#530 and facebook/yoga#446
Closes https://github.com/facebook/yoga/pull/531

Reviewed By: astreet

Differential Revision: D4970149

Pulled By: emilsjolander

fbshipit-source-id: b7fcdaa273143ea2fa35861620b2e4d79f04f0af
2017-05-03 09:30:25 -07:00
Aurimas
40eba60cf5 Move from ActionBarActivity to AppCompatActivity
Summary:
ActionBarActivity has been deprecated for 2+ years now.
Closes https://github.com/facebook/yoga/pull/538

Differential Revision: D4985973

Pulled By: emilsjolander

fbshipit-source-id: 09f2a8a12943c9b3ccdaee9cac684276b42ff843
2017-05-02 09:27:18 -07:00
Aurimas
fb4cfed20d Move from ActionBarActivity to AppCompatActivity
Summary:
ActionBarActivity has been deprecated for 2+ years now.
Closes https://github.com/facebook/yoga/pull/539

Differential Revision: D4985970

Pulled By: emilsjolander

fbshipit-source-id: 2e2fcc5188c08ef1cd78f7e1be71917f0395ff2c
2017-05-02 09:27:18 -07:00
Emil Sjolander
d3a9a84ac4 use java_library instead of android_library
Summary: fbjni doesn't have android deps anyways.

Reviewed By: passy

Differential Revision: D4985285

fbshipit-source-id: 95a5942d89210568b74caa9f3c976a8ae6e9601c
2017-05-02 04:17:14 -07:00
cregnier
accad5366f fixes #535 - changes unneeded js require expression to a static strin…
Summary:
fixes #535 - changes unneeded js require expression to a static string to clean up webpack warnings
Closes https://github.com/facebook/yoga/pull/536

Differential Revision: D4977993

Pulled By: emilsjolander

fbshipit-source-id: 92fe3a278391f37e44ac816d662885df6b4ea11f
2017-05-01 05:21:32 -07:00
Emil Sjolander
8eca67e257 Fix useLegacyStretchBehaviour flag by simplifying its usage
Summary: See blame revision. we are still passing all the added tests from that pull request but with much simpler logic.

Reviewed By: gkassabli

Differential Revision: D4977923

fbshipit-source-id: cb488e63c7c2e15e4c0f0133a16df36580c646fd
2017-05-01 04:32:40 -07:00
Emil Sjolander
40e1bf6ce3 Treat measured nodes size as a minimun contraint when rounding
Summary: We need to treat measurements from nodes with measure functions as minimum values as to not truncate text.

Reviewed By: shergin

Differential Revision: D4972290

fbshipit-source-id: 0a7bcc7f47b3e5acb8745da5286abcb9c4e44a38
2017-04-30 03:11:58 -07:00
David Hart
7b89a1dd48 Implemented percentage values in YogaKit
Summary:
We still need to wait for the `YGUnitPoint` PR to be merged :) But please let me know what you think. One caveat: because of a limitation of Swift, a literal value can be automatically understood as a point-based `YGValue`, but variables have to be explicitly cast. I haven't found a way around it yet:

```
view.yoga.width = 10 // value == 10, unit == YGUnitPixel

let a: CGFloat = 100
view.yoga.height = a // Compiler error
view.yoga.height = YGValue(a) // works, not great
```
Closes https://github.com/facebook/yoga/pull/390

Reviewed By: emilsjolander

Differential Revision: D4954021

Pulled By: maxoll

fbshipit-source-id: 5eff6aeb6dd969d0d5dc557b149bb5819b0e31de
2017-04-28 10:51:31 -07:00
Lukas Wöhrl
203577724e Fix sizing of non strech items
Summary:
Fixes the sizing of items so that under most scenarios it calcultes its height by it's content for non exact measurings. This introduces a new useLegacyStretchBehaviour flag on the config to opt out of this change as it is breaking.

See facebook/yoga#505
Closes https://github.com/facebook/yoga/pull/506

Reviewed By: astreet

Differential Revision: D4954016

Pulled By: emilsjolander

fbshipit-source-id: d28bd5d174cd76951fb94df85e3b0cfab7f81ff7
2017-04-28 06:27:14 -07:00
Emil Sjolander
e3dbef7cbd Revert D4957570: [yoga] Consolidate measure cache for layout nodes and leaf nodes
Summary: This reverts commit 5c5f39b67bd3f72d92b939ecee2d9a46c80b583f

Differential Revision: D4957570

fbshipit-source-id: 4d30de37c6911aac2dc1243a54914515aabfb229
2017-04-28 04:19:33 -07:00
Ivan Persidskiy
0ee3303791 Configure YogaKit with main screen scale factor
Summary:
Hi! After merging 3db38f2a80 the rounding algorithm become broken in YogaKit because it doesn't configure scale factor.
Closes https://github.com/facebook/yoga/pull/534

Differential Revision: D4969481

Pulled By: emilsjolander

fbshipit-source-id: 57ea42a3b1f37007b2392cda724d509e0b28c4cb
2017-04-28 03:12:12 -07:00
Emil Sjolander
83fddd8af6 Expose print function to java
Summary: Allow printing a node from java

Reviewed By: astreet

Differential Revision: D4962456

fbshipit-source-id: 8f62ed6724490e621fbc11573b2a9b25c56e51f1
2017-04-27 16:28:34 -07:00
Emil Sjolander
77c05b5ff6 Consolidate measure cache for layout nodes and leaf nodes
Summary: Re-use advanced changing logic of leaf nodes in layout nodes. //benchmark:benchmark nested flex test shows a ~15% improvement in layout performance!

Reviewed By: astreet

Differential Revision: D4957570

fbshipit-source-id: 5c5f39b67bd3f72d92b939ecee2d9a46c80b583f
2017-04-27 13:11:50 -07:00
Kazuki Sakamoto
7c324f058c Fix C# MeasureFunc test
Summary: Closes https://github.com/facebook/yoga/pull/533

Reviewed By: emilsjolander

Differential Revision: D4962771

Pulled By: splhack

fbshipit-source-id: 96919da73f0f35c027097259fa189b5658fb11b7
2017-04-27 09:30:20 -07:00
Emil Sjolander
3db38f2a80 Remove rounding from experimental features
Summary: Rounding has been successfully adopted by multiple products and frameworks. Time to move it out of experimental mode. Rounding can still be turned of by setting the point scale factor to 0 on the config.

Reviewed By: gkassabli

Differential Revision: D4953838

fbshipit-source-id: 3ee5f27d92f95b3ed4a01c98bc35e9157f2e91c5
2017-04-27 07:14:29 -07:00
Lukas Wöhrl
f6b17183c5 Let measure behave more like on the web
Summary:
Nodes with a measure function needs to be measured even so it seems there is no available space. So it behaves more like on the web. Fix facebook/yoga#488
Closes https://github.com/facebook/yoga/pull/499

Reviewed By: astreet

Differential Revision: D4954008

Pulled By: emilsjolander

fbshipit-source-id: 5b6d9afae0cdebe33f8b82b67620b3b4527d1efc
2017-04-27 07:14:29 -07:00
Emil Sjolander
8f9d7e243e Expose setPointScaleFactor to java
Summary: Expose setPointScaleFactor to java

Reviewed By: gkassabli

Differential Revision: D4953835

fbshipit-source-id: b1f97d9ec1bb78ccf7f53131fce87955fe66eb02
2017-04-26 12:35:00 -07:00
Cheng Zhao
fde4db9383 Add YGConfigCopy
Summary: Closes https://github.com/facebook/yoga/pull/525

Differential Revision: D4953723

Pulled By: emilsjolander

fbshipit-source-id: 1c54f40dfae5054822a440edf9d0aafb22a465d9
2017-04-26 11:57:01 -07:00
Lukas Wöhrl
3178e3bf15 Fix flex-wrap with max constraint
Summary:
Fixes `flex-wrap` with a max constraint and `justify-content`. Fixes facebook/yoga#514.
Closes https://github.com/facebook/yoga/pull/519

Differential Revision: D4953727

Pulled By: emilsjolander

fbshipit-source-id: 32dec48220be1392ea8dac5f34871d407eb8d49b
2017-04-26 11:46:23 -07:00
ChengWei
cdfd05c742 Fix the parameter error
Summary: Closes https://github.com/facebook/yoga/pull/528

Differential Revision: D4953974

Pulled By: emilsjolander

fbshipit-source-id: eda4770d4eb6cf52304d40a1b7ac17c2f0e17148
2017-04-26 11:27:52 -07:00
Emil Sjolander
76f6a54327 Update fbjni
Summary: Update yoga's copy of fbjni to include some missing java files.

Reviewed By: IanChilds

Differential Revision: D4953841

fbshipit-source-id: 74d5c617a6fcd11e82c86f03e61448b14a34b86b
2017-04-26 07:42:40 -07:00
Robert Spencer
c91e4b3566 Correct android attribute link in docs
Summary:
Addresses issue #523
Closes https://github.com/facebook/yoga/pull/529

Differential Revision: D4953973

Pulled By: emilsjolander

fbshipit-source-id: b6e64f30ad615ba65152f19e775bd6c890e6c6b6
2017-04-26 06:27:17 -07:00
Robert Spencer
e24561bcef Update Android XML attribute names in docs
Summary:
Fixes #507 .  The attribute name format got changed and the docs were left behind.
Closes https://github.com/facebook/yoga/pull/510

Differential Revision: D4953733

Pulled By: emilsjolander

fbshipit-source-id: 6eb02d6745d08fdd8cce669c691794351bd6fbc7
2017-04-26 03:12:51 -07:00
Uldéric KIBONGUI
363e941867 Fixed doc mismatch with the implementation
Summary: Closes https://github.com/facebook/yoga/pull/518

Differential Revision: D4953729

Pulled By: emilsjolander

fbshipit-source-id: 6693a0e44e8f12f07af5c3fe7c0475f8553a1df2
2017-04-26 03:12:51 -07:00
Ivan Persidskiy
3fb2c1888c Downgrade deployment target to ios 7
Summary:
Hey there, lets downgrade deployment target of YogaKit pod to iOS7. This days there is a lot of apps that still have support of ios7 (and  i'm working on one of them :)). And I didnt't find any reason why it couldn't be done.

Thanks
Closes https://github.com/facebook/yoga/pull/524

Differential Revision: D4953726

Pulled By: emilsjolander

fbshipit-source-id: 9e17a40caaa0a3ae26779c0d08acb59f71df2b23
2017-04-26 03:12:51 -07:00
192 changed files with 9019 additions and 1541 deletions

View File

@@ -1,9 +1,10 @@
[cxx]
gtest_dep = //lib/gtest:gtest
[android]
target = android-23
target = android-25
build_tools_version = 26.0.2
[ndk]
ndk_version = 13.1.3345770
ndk_version = 15.2.4203891
compiler = clang
app_platform = android-21
cpu_abis = arm64, armv7, x86, x86_64

11
.editorconfig Normal file
View File

@@ -0,0 +1,11 @@
root = true
[*]
indent_style = space
indent_size = 2
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.md]
trim_trailing_whitespace = false

View File

@@ -9,6 +9,11 @@ os: osx
osx_image: xcode8.2
language: cpp
compiler: clang
cache:
directories:
- $HOME/Library/Caches/Homebrew
- $HOME/android-sdk
- $HOME/android-ndk
env:
- TARGET=c
@@ -19,9 +24,13 @@ env:
- TARGET=android
before_install:
- |
if [[ -n "$encrypted_d27e803291ff_iv" ]]; then
openssl aes-256-cbc -K $encrypted_d27e803291ff_key -iv $encrypted_d27e803291ff_iv -in scripts/setup-keys.enc -d >> gradle.properties;
fi
- brew update > /dev/null
- brew tap facebook/fb
- brew install buck
- brew install --HEAD facebook/fb/buck
# Java
- |
@@ -53,8 +62,8 @@ before_install:
if [[ $TARGET = "js" ]]; then
wget -O /tmp/emsdk-portable.tar.gz https://s3.amazonaws.com/mozilla-games/emscripten/releases/emsdk-portable.tar.gz &&
tar xf /tmp/emsdk-portable.tar.gz -C /tmp/ &&
/tmp/emsdk_portable/emsdk install latest >& /dev/null &&
/tmp/emsdk_portable/emsdk activate latest
/tmp/emsdk-portable/emsdk install latest 2>&1 | grep -v '^x ' &&
/tmp/emsdk-portable/emsdk activate latest
fi
# Android
@@ -63,12 +72,11 @@ before_install:
brew cask install java;
export JAVA_HOME=$(/usr/libexec/java_home -v 1.8);
export PATH=$JAVA_HOME/bin:$PATH;
brew install android-sdk;
export ANDROID_SDK=/usr/local/Cellar/android-sdk/24.4.1_1;
export ANDROID_HOME=/usr/local/Cellar/android-sdk/24.4.1_1;
brew install lib32stdc++6 lib32z1;
echo y | $ANDROID_SDK/tools/android update sdk --filter android-19,addon-google_apis-google-19,build-tools-19.1.0 --no-ui;
echo y | $ANDROID_SDK/tools/android update sdk -u;
export TERMINAL=dumb;
source scripts/android-setup.sh && installAndroidSDK
export ANDROID_SDK=$ANDROID_HOME
export ANDROID_NDK_REPOSITORY=$HOME/android-ndk
export ANDROID_NDK_HOME=$ANDROID_NDK_REPOSITORY/android-ndk-r15c
fi
# JavaScript
@@ -77,7 +85,7 @@ before_install:
cd javascript &&
npm install &&
unset CC && unset CXX && unset LINK &&
source /tmp/emsdk_portable/emsdk_env.sh &&
source /tmp/emsdk-portable/emsdk_env.sh &&
npm run build:browser
) fi
@@ -114,7 +122,9 @@ script:
# Android
- |
if [[ $TARGET = "android" ]]; then
buck build --verbose 0 //android/sample:sample
buck build --verbose 0 //android/sample:sample &&
./gradlew testDebugUnit &&
scripts/publish-snapshot.sh
fi
# JavaScript

4
BUCK
View File

@@ -21,9 +21,9 @@ TEST_COMPILER_FLAGS = BASE_COMPILER_FLAGS + GMOCK_OVERRIDE_FLAGS + ["-std=c++11"
cxx_library(
name = "yoga",
srcs = glob(["yoga/*.c"]),
compiler_flags = COMPILER_FLAGS,
exported_headers = subdir_glob([("", "yoga/*.h")]),
header_namespace = "",
exported_headers = subdir_glob([("", "yoga/*.h")]),
compiler_flags = COMPILER_FLAGS,
soname = "libyogacore.$(ext)",
tests = [":YogaTests"],
visibility = ["PUBLIC"],

View File

@@ -38,3 +38,26 @@ For the main C implementation of Yoga clang-format is used to ensure a consisten
## Benchmarks
Benchmarks are located in `benchmark/YGBenchmark.c` and can be run with `buck run //benchmark:benchmark`. If you think your change has affected performance please run this before and after your change to validate that nothing has regressed. Benchmarks are run on every commit in CI.
### JavaScript
Installing through NPM
```sh
npm install yoga-layout
```
By default this will install the library and try to build for all platforms (node, browser asm, and standalone webpack). You may receive errors if you do not have the required platform development tools already installed. To preset the platform you'd like to build for you can set a .npmrc property first.
```sh
npm config set yoga-layout:platform standalone
```
This will now only run the standalone webpack build upon install.
## Build Platforms
| name | description |
|----------------|-------------------------------------------------|
| all (default) | Builds all of these platforms. |
| browser | Builds asm js browser version. |
| node | Builds node js version. |
| standalone | Runs webpack. |
| none | Does nothing. You can use the prepackaged libs. |

View File

@@ -9,6 +9,7 @@ SOLOADER_TARGET = '//lib/soloader:soloader'
GTEST_TARGET = '//lib/gtest:gtest'
JNI_TARGET = '//lib/jni:jni'
FBJNI_TARGET = '//lib/fb:fbjni'
FBJNI_JAVA_TARGET = '//lib/fb/src/main/java/com/facebook/jni:jni'
APPCOMPAT_TARGET = '//lib/appcompat:appcompat'
ANDROID_SUPPORT_TARGET = '//lib/android-support:android-support'
ANDROID_TARGET = '//android:android'

View File

@@ -1,6 +1,6 @@
Pod::Spec.new do |spec|
spec.name = 'Yoga'
spec.version = '1.3.0'
spec.version = '1.7.0'
spec.license = { :type => 'BSD', :file => "LICENSE" }
spec.homepage = 'https://facebook.github.io/yoga/'
spec.documentation_url = 'https://facebook.github.io/yoga/docs/api/c/'
@@ -11,7 +11,7 @@ Pod::Spec.new do |spec|
spec.authors = 'Facebook'
spec.source = {
:git => 'https://github.com/facebook/yoga.git',
:tag => '1.3.0',
:tag => '1.7.0',
}
spec.module_name = 'yoga'

View File

@@ -1,6 +1,6 @@
podspec = Pod::Spec.new do |spec|
spec.name = 'YogaKit'
spec.version = '1.3.0'
spec.version = '1.7.0'
spec.license = { :type => 'BSD', :file => "LICENSE" }
spec.homepage = 'https://facebook.github.io/yoga/'
spec.documentation_url = 'https://facebook.github.io/yoga/docs/api/yogakit/'
@@ -11,15 +11,15 @@ podspec = Pod::Spec.new do |spec|
spec.authors = 'Facebook'
spec.source = {
:git => 'https://github.com/facebook/yoga.git',
:tag => '1.3.0',
:tag => '1.7.0',
}
spec.platform = :ios
spec.ios.deployment_target = '8.0'
spec.ios.frameworks = 'UIKit'
spec.dependency 'Yoga', '~> 1.3'
spec.source_files = 'YogaKit/Source/*.{h,m}'
spec.dependency 'Yoga', '~> 1.7'
spec.source_files = 'YogaKit/Source/*.{h,m,swift}'
spec.public_header_files = 'YogaKit/Source/{YGLayout,UIView+Yoga}.h'
spec.private_header_files = 'YogaKit/Source/YGLayout+Private.h'
end

View File

@@ -30,12 +30,13 @@ COMPILER_FLAGS = [
apple_library(
name = "YogaKit",
srcs = glob(["Source/**/*.m"]),
compiler_flags = COMPILER_FLAGS,
exported_headers = glob(["Source/**/*.h"]),
compiler_flags = COMPILER_FLAGS,
frameworks = [
"$SDKROOT/System/Library/Frameworks/Foundation.framework",
"$SDKROOT/System/Library/Frameworks/UIKit.framework",
],
link_whole = True,
visibility = ["PUBLIC"],
deps = [
yoga_dep(":yoga"),

View File

@@ -1,46 +0,0 @@
# CHANGELOG
The changelog for `YogaKit`.
1.2.0 (**upcoming release**)
-----
### Breaking Changes
- `applyLayout()` has now been changed to `applyLayout(preservingOrigin:)`.
- Computed properties are no longer reflected in getter's of the affected properties.
```swift
// OLD
view.yoga.margin = 10
view.yoga.marginTop // 10
view.yoga.marginLeft // 10
// NEW
view.yoga.margin = 10
view.yoga.marginTop // 0
view.yoga.marginLeft // 0
```
### Enhancements
- Pixel Rounding now uses `roundf()` instead of `round()`.
- There is now a method that allows "bulk" updates to YGLayout.
```objc
[view configureLayoutWithBlock:^(YGLayout *layout) {
layout.isEnabled = YES;
layout.width = 50;
layout.height = 50;
}];
```
```swift
view.configureLayout { (layout) in
layout.isEnabled = true
layout.width = 50
layout.height = 50
}
```
- Added new `isDirty` property, and make `markDirty` a little more performant.

View File

@@ -8,7 +8,7 @@
YogaKit is available to install via [CocoaPods](https://cocoapods.org/).
```
pod 'YogaKit', '~> 1.3'
pod 'YogaKit', '~> 1.7'
```
## Getting Started

View File

@@ -20,6 +20,10 @@ typedef void (^YGLayoutConfigurationBlock)(YGLayout *);
The YGLayout that is attached to this view. It is lazily created.
*/
@property (nonatomic, readonly, strong) YGLayout *yoga;
/**
Indicates whether or not Yoga is enabled
*/
@property (nonatomic, readonly, assign) BOOL isYogaEnabled;
/**
In ObjC land, every time you access `view.yoga.*` you are adding another `objc_msgSend`

View File

@@ -26,6 +26,11 @@ static const void *kYGYogaAssociatedKey = &kYGYogaAssociatedKey;
return yoga;
}
- (BOOL)isYogaEnabled
{
return objc_getAssociatedObject(self, kYGYogaAssociatedKey) != nil;
}
- (void)configureLayoutWithBlock:(YGLayoutConfigurationBlock)block
{
if (block != nil) {

View File

@@ -9,6 +9,17 @@
#import <UIKit/UIKit.h>
#import <yoga/YGEnums.h>
#import <yoga/Yoga.h>
#import <yoga/YGMacros.h>
YG_EXTERN_C_BEGIN
extern YGValue YGPointValue(CGFloat value)
NS_SWIFT_UNAVAILABLE("Use the swift Int and FloatingPoint extensions instead");
extern YGValue YGPercentValue(CGFloat value)
NS_SWIFT_UNAVAILABLE("Use the swift Int and FloatingPoint extensions instead");
YG_EXTERN_C_END
typedef NS_OPTIONS(NSInteger, YGDimensionFlexibility) {
YGDimensionFlexibilityFlexibleWidth = 1 << 0,
@@ -41,34 +52,34 @@ typedef NS_OPTIONS(NSInteger, YGDimensionFlexibility) {
@property (nonatomic, readwrite, assign) CGFloat flexGrow;
@property (nonatomic, readwrite, assign) CGFloat flexShrink;
@property (nonatomic, readwrite, assign) CGFloat flexBasis;
@property (nonatomic, readwrite, assign) YGValue flexBasis;
@property (nonatomic, readwrite, assign) CGFloat left;
@property (nonatomic, readwrite, assign) CGFloat top;
@property (nonatomic, readwrite, assign) CGFloat right;
@property (nonatomic, readwrite, assign) CGFloat bottom;
@property (nonatomic, readwrite, assign) CGFloat start;
@property (nonatomic, readwrite, assign) CGFloat end;
@property (nonatomic, readwrite, assign) YGValue left;
@property (nonatomic, readwrite, assign) YGValue top;
@property (nonatomic, readwrite, assign) YGValue right;
@property (nonatomic, readwrite, assign) YGValue bottom;
@property (nonatomic, readwrite, assign) YGValue start;
@property (nonatomic, readwrite, assign) YGValue end;
@property (nonatomic, readwrite, assign) CGFloat marginLeft;
@property (nonatomic, readwrite, assign) CGFloat marginTop;
@property (nonatomic, readwrite, assign) CGFloat marginRight;
@property (nonatomic, readwrite, assign) CGFloat marginBottom;
@property (nonatomic, readwrite, assign) CGFloat marginStart;
@property (nonatomic, readwrite, assign) CGFloat marginEnd;
@property (nonatomic, readwrite, assign) CGFloat marginHorizontal;
@property (nonatomic, readwrite, assign) CGFloat marginVertical;
@property (nonatomic, readwrite, assign) CGFloat margin;
@property (nonatomic, readwrite, assign) YGValue marginLeft;
@property (nonatomic, readwrite, assign) YGValue marginTop;
@property (nonatomic, readwrite, assign) YGValue marginRight;
@property (nonatomic, readwrite, assign) YGValue marginBottom;
@property (nonatomic, readwrite, assign) YGValue marginStart;
@property (nonatomic, readwrite, assign) YGValue marginEnd;
@property (nonatomic, readwrite, assign) YGValue marginHorizontal;
@property (nonatomic, readwrite, assign) YGValue marginVertical;
@property (nonatomic, readwrite, assign) YGValue margin;
@property (nonatomic, readwrite, assign) CGFloat paddingLeft;
@property (nonatomic, readwrite, assign) CGFloat paddingTop;
@property (nonatomic, readwrite, assign) CGFloat paddingRight;
@property (nonatomic, readwrite, assign) CGFloat paddingBottom;
@property (nonatomic, readwrite, assign) CGFloat paddingStart;
@property (nonatomic, readwrite, assign) CGFloat paddingEnd;
@property (nonatomic, readwrite, assign) CGFloat paddingHorizontal;
@property (nonatomic, readwrite, assign) CGFloat paddingVertical;
@property (nonatomic, readwrite, assign) CGFloat padding;
@property (nonatomic, readwrite, assign) YGValue paddingLeft;
@property (nonatomic, readwrite, assign) YGValue paddingTop;
@property (nonatomic, readwrite, assign) YGValue paddingRight;
@property (nonatomic, readwrite, assign) YGValue paddingBottom;
@property (nonatomic, readwrite, assign) YGValue paddingStart;
@property (nonatomic, readwrite, assign) YGValue paddingEnd;
@property (nonatomic, readwrite, assign) YGValue paddingHorizontal;
@property (nonatomic, readwrite, assign) YGValue paddingVertical;
@property (nonatomic, readwrite, assign) YGValue padding;
@property (nonatomic, readwrite, assign) CGFloat borderLeftWidth;
@property (nonatomic, readwrite, assign) CGFloat borderTopWidth;
@@ -78,12 +89,12 @@ typedef NS_OPTIONS(NSInteger, YGDimensionFlexibility) {
@property (nonatomic, readwrite, assign) CGFloat borderEndWidth;
@property (nonatomic, readwrite, assign) CGFloat borderWidth;
@property (nonatomic, readwrite, assign) CGFloat width;
@property (nonatomic, readwrite, assign) CGFloat height;
@property (nonatomic, readwrite, assign) CGFloat minWidth;
@property (nonatomic, readwrite, assign) CGFloat minHeight;
@property (nonatomic, readwrite, assign) CGFloat maxWidth;
@property (nonatomic, readwrite, assign) CGFloat maxHeight;
@property (nonatomic, readwrite, assign) YGValue width;
@property (nonatomic, readwrite, assign) YGValue height;
@property (nonatomic, readwrite, assign) YGValue minWidth;
@property (nonatomic, readwrite, assign) YGValue minHeight;
@property (nonatomic, readwrite, assign) YGValue maxWidth;
@property (nonatomic, readwrite, assign) YGValue maxHeight;
// Yoga specific properties, not compatible with flexbox specification
@property (nonatomic, readwrite, assign) CGFloat aspectRatio;
@@ -104,7 +115,8 @@ typedef NS_OPTIONS(NSInteger, YGDimensionFlexibility) {
Perform a layout calculation and update the frames of the views in the hierarchy with the results.
If the origin is not preserved, the root view's layout results will applied from {0,0}.
*/
- (void)applyLayoutPreservingOrigin:(BOOL)preserveOrigin dimensionFlexibility:(YGDimensionFlexibility)dimensionFlexibility
- (void)applyLayoutPreservingOrigin:(BOOL)preserveOrigin
dimensionFlexibility:(YGDimensionFlexibility)dimensionFlexibility
NS_SWIFT_NAME(applyLayout(preservingOrigin:dimensionFlexibility:));
/**
@@ -113,6 +125,12 @@ typedef NS_OPTIONS(NSInteger, YGDimensionFlexibility) {
*/
@property (nonatomic, readonly, assign) CGSize intrinsicSize;
/**
Returns the size of the view based on provided constraints. Pass NaN for an unconstrained dimension.
*/
- (CGSize)calculateLayoutWithSize:(CGSize)size
NS_SWIFT_NAME(calculateLayout(with:));
/**
Returns the number of children that are using Flexbox.
*/

View File

@@ -21,26 +21,30 @@
YGNodeStyleSet##capitalized_name(self.node, lowercased_name); \
}
#define YG_VALUE_PROPERTY(lowercased_name, capitalized_name) \
- (CGFloat)lowercased_name \
{ \
YGValue value = YGNodeStyleGet##capitalized_name(self.node); \
if (value.unit == YGUnitPoint) { \
return value.value; \
} else { \
return YGUndefined; \
} \
} \
\
- (void)set##capitalized_name:(CGFloat)lowercased_name \
{ \
YGNodeStyleSet##capitalized_name(self.node, lowercased_name); \
#define YG_VALUE_PROPERTY(lowercased_name, capitalized_name) \
- (YGValue)lowercased_name \
{ \
return YGNodeStyleGet##capitalized_name(self.node); \
} \
\
- (void)set##capitalized_name:(YGValue)lowercased_name \
{ \
switch (lowercased_name.unit) { \
case YGUnitPoint: \
YGNodeStyleSet##capitalized_name(self.node, lowercased_name.value); \
break; \
case YGUnitPercent: \
YGNodeStyleSet##capitalized_name##Percent(self.node, lowercased_name.value); \
break; \
default: \
NSAssert(NO, @"Not implemented"); \
} \
}
#define YG_EDGE_PROPERTY_GETTER(lowercased_name, capitalized_name, property, edge) \
- (CGFloat)lowercased_name \
{ \
return YGNodeStyleGet##property(self.node, edge); \
#define YG_EDGE_PROPERTY_GETTER(type, lowercased_name, capitalized_name, property, edge) \
- (type)lowercased_name \
{ \
return YGNodeStyleGet##property(self.node, edge); \
}
#define YG_EDGE_PROPERTY_SETTER(lowercased_name, capitalized_name, property, edge) \
@@ -49,42 +53,50 @@
YGNodeStyleSet##property(self.node, edge, lowercased_name); \
}
#define YG_EDGE_PROPERTY(lowercased_name, capitalized_name, property, edge) \
YG_EDGE_PROPERTY_GETTER(lowercased_name, capitalized_name, property, edge) \
#define YG_EDGE_PROPERTY(lowercased_name, capitalized_name, property, edge) \
YG_EDGE_PROPERTY_GETTER(CGFloat, lowercased_name, capitalized_name, property, edge) \
YG_EDGE_PROPERTY_SETTER(lowercased_name, capitalized_name, property, edge)
#define YG_VALUE_EDGE_PROPERTY_GETTER(objc_lowercased_name, objc_capitalized_name, c_name, edge) \
- (CGFloat)objc_lowercased_name \
#define YG_VALUE_EDGE_PROPERTY_SETTER(objc_lowercased_name, objc_capitalized_name, c_name, edge) \
- (void)set##objc_capitalized_name:(YGValue)objc_lowercased_name \
{ \
YGValue value = YGNodeStyleGet##c_name(self.node, edge); \
if (value.unit == YGUnitPoint) { \
return value.value; \
} else { \
return YGUndefined; \
switch (objc_lowercased_name.unit) { \
case YGUnitPoint: \
YGNodeStyleSet##c_name(self.node, edge, objc_lowercased_name.value); \
break; \
case YGUnitPercent: \
YGNodeStyleSet##c_name##Percent(self.node, edge, objc_lowercased_name.value); \
break; \
default: \
NSAssert(NO, @"Not implemented"); \
} \
}
#define YG_VALUE_EDGE_PROPERTY_SETTER(objc_lowercased_name, objc_capitalized_name, c_name, edge) \
- (void)set##objc_capitalized_name:(CGFloat)objc_lowercased_name \
{ \
YGNodeStyleSet##c_name(self.node, edge, objc_lowercased_name); \
}
#define YG_VALUE_EDGE_PROPERTY(lowercased_name, capitalized_name, property, edge) \
YG_VALUE_EDGE_PROPERTY_GETTER(lowercased_name, capitalized_name, property, edge) \
#define YG_VALUE_EDGE_PROPERTY(lowercased_name, capitalized_name, property, edge) \
YG_EDGE_PROPERTY_GETTER(YGValue, lowercased_name, capitalized_name, property, edge) \
YG_VALUE_EDGE_PROPERTY_SETTER(lowercased_name, capitalized_name, property, edge)
#define YG_VALUE_EDGES_PROPERTIES(lowercased_name, capitalized_name) \
YG_VALUE_EDGE_PROPERTY(lowercased_name##Left, capitalized_name##Left, capitalized_name, YGEdgeLeft) \
YG_VALUE_EDGE_PROPERTY(lowercased_name##Top, capitalized_name##Top, capitalized_name, YGEdgeTop) \
YG_VALUE_EDGE_PROPERTY(lowercased_name##Right, capitalized_name##Right, capitalized_name, YGEdgeRight) \
YG_VALUE_EDGE_PROPERTY(lowercased_name##Bottom, capitalized_name##Bottom, capitalized_name, YGEdgeBottom) \
YG_VALUE_EDGE_PROPERTY(lowercased_name##Start, capitalized_name##Start, capitalized_name, YGEdgeStart) \
YG_VALUE_EDGE_PROPERTY(lowercased_name##End, capitalized_name##End, capitalized_name, YGEdgeEnd) \
#define YG_VALUE_EDGES_PROPERTIES(lowercased_name, capitalized_name) \
YG_VALUE_EDGE_PROPERTY(lowercased_name##Left, capitalized_name##Left, capitalized_name, YGEdgeLeft) \
YG_VALUE_EDGE_PROPERTY(lowercased_name##Top, capitalized_name##Top, capitalized_name, YGEdgeTop) \
YG_VALUE_EDGE_PROPERTY(lowercased_name##Right, capitalized_name##Right, capitalized_name, YGEdgeRight) \
YG_VALUE_EDGE_PROPERTY(lowercased_name##Bottom, capitalized_name##Bottom, capitalized_name, YGEdgeBottom) \
YG_VALUE_EDGE_PROPERTY(lowercased_name##Start, capitalized_name##Start, capitalized_name, YGEdgeStart) \
YG_VALUE_EDGE_PROPERTY(lowercased_name##End, capitalized_name##End, capitalized_name, YGEdgeEnd) \
YG_VALUE_EDGE_PROPERTY(lowercased_name##Horizontal, capitalized_name##Horizontal, capitalized_name, YGEdgeHorizontal) \
YG_VALUE_EDGE_PROPERTY(lowercased_name##Vertical, capitalized_name##Vertical, capitalized_name, YGEdgeVertical) \
YG_VALUE_EDGE_PROPERTY(lowercased_name, capitalized_name, capitalized_name, YGEdgeAll)
YGValue YGPointValue(CGFloat value)
{
return (YGValue) { .value = value, .unit = YGUnitPoint };
}
YGValue YGPercentValue(CGFloat value)
{
return (YGValue) { .value = value, .unit = YGUnitPercent };
}
static YGConfigRef globalConfig;
@interface YGLayout ()
@@ -103,6 +115,7 @@ static YGConfigRef globalConfig;
{
globalConfig = YGConfigNew();
YGConfigSetExperimentalFeatureEnabled(globalConfig, YGExperimentalFeatureWebFlexBasis, true);
YGConfigSetPointScaleFactor(globalConfig, [UIScreen mainScreen].scale);
}
- (instancetype)initWithView:(UIView*)view
@@ -245,7 +258,7 @@ YG_PROPERTY(CGFloat, aspectRatio, AspectRatio)
size.height = YGUndefined;
}
[self calculateLayoutWithSize:size];
YGApplyLayoutToViewHierarchy(self.view, NO);
YGApplyLayoutToViewHierarchy(self.view, preserveOrigin);
}
@@ -258,8 +271,6 @@ YG_PROPERTY(CGFloat, aspectRatio, AspectRatio)
return [self calculateLayoutWithSize:constrainedSize];
}
#pragma mark - Private
- (CGSize)calculateLayoutWithSize:(CGSize)size
{
NSAssert([NSThread isMainThread], @"Yoga calculation must be done on main.");
@@ -280,6 +291,8 @@ YG_PROPERTY(CGFloat, aspectRatio, AspectRatio)
};
}
#pragma mark - Private
static YGSize YGMeasureView(
YGNodeRef node,
float width,
@@ -348,7 +361,7 @@ static void YGAttachNodesFromViewHierachy(UIView *const view)
NSMutableArray<UIView *> *subviewsToInclude = [[NSMutableArray alloc] initWithCapacity:view.subviews.count];
for (UIView *subview in view.subviews) {
if (subview.yoga.isIncludedInLayout) {
if (subview.yoga.isEnabled && subview.yoga.isIncludedInLayout) {
[subviewsToInclude addObject:subview];
}
}

View File

@@ -0,0 +1,46 @@
/**
* Copyright (c) 2014-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
postfix operator %
extension Int {
public static postfix func %(value: Int) -> YGValue {
return YGValue(value: Float(value), unit: .percent)
}
}
extension Float {
public static postfix func %(value: Float) -> YGValue {
return YGValue(value: value, unit: .percent)
}
}
extension CGFloat {
public static postfix func %(value: CGFloat) -> YGValue {
return YGValue(value: Float(value), unit: .percent)
}
}
extension YGValue : ExpressibleByIntegerLiteral, ExpressibleByFloatLiteral {
public init(integerLiteral value: Int) {
self = YGValue(value: Float(value), unit: .point)
}
public init(floatLiteral value: Float) {
self = YGValue(value: value, unit: .point)
}
public init(_ value: Float) {
self = YGValue(value: value, unit: .point)
}
public init(_ value: CGFloat) {
self = YGValue(value: Float(value), unit: .point)
}
}

View File

@@ -31,11 +31,11 @@
[view configureLayoutWithBlock:^(YGLayout *layout){
XCTAssertNotNil(layout);
layout.isEnabled = YES;
layout.width = 25;
layout.width = YGPointValue(25);
}];
XCTAssertTrue(view.yoga.isEnabled);
XCTAssertEqual(view.yoga.width, 25);
XCTAssertEqual(view.yoga.width.value, 25);
}
- (void)testNodesAreDeallocedWithSingleView
@@ -44,7 +44,7 @@
@autoreleasepool {
UIView *view = [[UIView alloc] initWithFrame:CGRectZero];
view.yoga.flexBasis = 1;
view.yoga.flexBasis = YGPointValue(1);
layoutRef = view.yoga;
XCTAssertNotNil(layoutRef);
@@ -63,11 +63,11 @@
@autoreleasepool {
UIView *view = [[UIView alloc] initWithFrame:CGRectZero];
topLayout = view.yoga;
topLayout.flexBasis = 1;
topLayout.flexBasis = YGPointValue(1);
UIView *subview = [[UIView alloc] initWithFrame:CGRectZero];
subviewLayout = subview.yoga;
subviewLayout.flexBasis = 1;
subviewLayout.flexBasis = YGPointValue(1);
view = nil;
}
@@ -113,9 +113,9 @@
UIView *textBadgeView = [[UIView alloc] initWithFrame:CGRectZero];
textBadgeView.yoga.isEnabled = YES;
textBadgeView.yoga.margin = 0;
textBadgeView.yoga.width = 10;
textBadgeView.yoga.height = 10;
textBadgeView.yoga.margin = YGPointValue(0);
textBadgeView.yoga.width = YGPointValue(10);
textBadgeView.yoga.height = YGPointValue(10);
[container addSubview:textBadgeView];
const CGSize textBadgeViewSize = textBadgeView.yoga.intrinsicSize;
@@ -136,14 +136,14 @@
UIView *view = [[UIView alloc] initWithFrame:CGRectZero];
view.yoga.isEnabled = YES;
view.yoga.flexBasis = 0;
view.yoga.flexBasis = YGPointValue(0);
view.yoga.flexGrow = 1;
[container addSubview:view];
UIView *view2 = [[UIView alloc] initWithFrame:CGRectZero];
view2.yoga.isEnabled = YES;
view2.yoga.marginTop = 25;
view2.yoga.flexBasis = 0;
view2.yoga.marginTop = YGPointValue(25);
view2.yoga.flexBasis = YGPointValue(0);
view2.yoga.flexGrow = 1;
[container addSubview:view2];
@@ -161,8 +161,8 @@
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
view.yoga.isEnabled = YES;
view.yoga.width = 100;
view.yoga.height = 100;
view.yoga.width = YGPointValue(100);
view.yoga.height = YGPointValue(100);
[container addSubview:view];
[container.yoga applyLayoutPreservingOrigin:YES dimensionFlexibility:YGDimensionFlexibilityFlexibleWidth];
@@ -177,8 +177,8 @@
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
view.yoga.isEnabled = YES;
view.yoga.width = 100;
view.yoga.height = 100;
view.yoga.width = YGPointValue(100);
view.yoga.height = YGPointValue(100);
[container addSubview:view];
[container.yoga applyLayoutPreservingOrigin:YES dimensionFlexibility:YGDimensionFlexibilityFlexibleHeigth];
@@ -193,8 +193,8 @@
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
view.yoga.isEnabled = YES;
view.yoga.width = 100;
view.yoga.height = 100;
view.yoga.width = YGPointValue(100);
view.yoga.height = YGPointValue(100);
[container addSubview:view];
[container.yoga applyLayoutPreservingOrigin:YES dimensionFlexibility:YGDimensionFlexibilityFlexibleWidth | YGDimensionFlexibilityFlexibleHeigth];
@@ -437,12 +437,12 @@
XCTAssertTrue(view.yoga.isLeaf);
view.yoga.isEnabled = YES;
view.yoga.width = 50.0;
view.yoga.width = YGPointValue(50);
XCTAssertTrue(view.yoga.isLeaf);
UIView *const subview = view.subviews[0];
subview.yoga.isEnabled = YES;
subview.yoga.width = 50.0;
subview.yoga.width = YGPointValue(50);
XCTAssertFalse(view.yoga.isLeaf);
}
@@ -454,14 +454,14 @@
UIView *subview1 = [[UIView alloc] initWithFrame:CGRectZero];
subview1.yoga.isEnabled = YES;
subview1.yoga.width = 100;
subview1.yoga.width = YGPointValue(100);
subview1.yoga.flexGrow = 1;
subview1.yoga.flexDirection = YGFlexDirectionColumn;
[container addSubview:subview1];
UIView *subview2 = [[UIView alloc] initWithFrame:CGRectZero];
subview2.yoga.isEnabled = YES;
subview2.yoga.width = 150;
subview2.yoga.width = YGPointValue(150);
subview2.yoga.flexGrow = 1;
subview2.yoga.flexDirection = YGFlexDirectionColumn;
[container addSubview:subview2];
@@ -522,155 +522,195 @@
[container.yoga applyLayoutPreservingOrigin:YES];
}
- (void)testPointPercent
{
XCTAssertEqual(YGPointValue(1).value, 1);
XCTAssertEqual(YGPointValue(1).unit, YGUnitPoint);
XCTAssertEqual(YGPercentValue(2).value, 2);
XCTAssertEqual(YGPercentValue(2).unit, YGUnitPercent);
}
- (void)testPositionalPropertiesWork
{
UIView *view = [[UIView alloc] initWithFrame:CGRectZero];
view.yoga.left = 1;
XCTAssertEqual(YGNodeStyleGetPosition(view.yoga.node, YGEdgeLeft).value, 1);
XCTAssertEqual(YGNodeStyleGetPosition(view.yoga.node, YGEdgeLeft).unit, YGUnitPoint);
XCTAssertEqual(view.yoga.left, 1);
view.yoga.left = YGPointValue(1);
XCTAssertEqual(view.yoga.left.value, 1);
XCTAssertEqual(view.yoga.left.unit, YGUnitPoint);
view.yoga.left = YGPercentValue(2);
XCTAssertEqual(view.yoga.left.value, 2);
XCTAssertEqual(view.yoga.left.unit, YGUnitPercent);
view.yoga.right = 2;
XCTAssertEqual(YGNodeStyleGetPosition(view.yoga.node, YGEdgeRight).value, 2);
XCTAssertEqual(YGNodeStyleGetPosition(view.yoga.node, YGEdgeRight).unit, YGUnitPoint);
XCTAssertEqual(view.yoga.right, 2);
view.yoga.right = YGPointValue(3);
XCTAssertEqual(view.yoga.right.value, 3);
XCTAssertEqual(view.yoga.right.unit, YGUnitPoint);
view.yoga.right = YGPercentValue(4);
XCTAssertEqual(view.yoga.right.value, 4);
XCTAssertEqual(view.yoga.right.unit, YGUnitPercent);
view.yoga.top = 3;
XCTAssertEqual(YGNodeStyleGetPosition(view.yoga.node, YGEdgeTop).value, 3);
XCTAssertEqual(YGNodeStyleGetPosition(view.yoga.node, YGEdgeTop).unit, YGUnitPoint);
XCTAssertEqual(view.yoga.top, 3);
view.yoga.top = YGPointValue(5);
XCTAssertEqual(view.yoga.top.value, 5);
XCTAssertEqual(view.yoga.top.unit, YGUnitPoint);
view.yoga.top = YGPercentValue(6);
XCTAssertEqual(view.yoga.top.value, 6);
XCTAssertEqual(view.yoga.top.unit, YGUnitPercent);
view.yoga.bottom = 4;
XCTAssertEqual(YGNodeStyleGetPosition(view.yoga.node, YGEdgeBottom).value, 4);
XCTAssertEqual(YGNodeStyleGetPosition(view.yoga.node, YGEdgeBottom).unit, YGUnitPoint);
XCTAssertEqual(view.yoga.bottom, 4);
view.yoga.bottom = YGPointValue(7);
XCTAssertEqual(view.yoga.bottom.value, 7);
XCTAssertEqual(view.yoga.bottom.unit, YGUnitPoint);
view.yoga.bottom = YGPercentValue(8);
XCTAssertEqual(view.yoga.bottom.value, 8);
XCTAssertEqual(view.yoga.bottom.unit, YGUnitPercent);
view.yoga.start = 5;
XCTAssertEqual(YGNodeStyleGetPosition(view.yoga.node, YGEdgeStart).value, 5);
XCTAssertEqual(YGNodeStyleGetPosition(view.yoga.node, YGEdgeStart).unit, YGUnitPoint);
XCTAssertEqual(view.yoga.start, 5);
view.yoga.start = YGPointValue(9);
XCTAssertEqual(view.yoga.start.value, 9);
XCTAssertEqual(view.yoga.start.unit, YGUnitPoint);
view.yoga.start = YGPercentValue(10);
XCTAssertEqual(view.yoga.start.value, 10);
XCTAssertEqual(view.yoga.start.unit, YGUnitPercent);
view.yoga.end = 6;
XCTAssertEqual(YGNodeStyleGetPosition(view.yoga.node, YGEdgeEnd).value, 6);
XCTAssertEqual(YGNodeStyleGetPosition(view.yoga.node, YGEdgeEnd).unit, YGUnitPoint);
XCTAssertEqual(view.yoga.end, 6);
view.yoga.end = YGPointValue(11);
XCTAssertEqual(view.yoga.end.value, 11);
XCTAssertEqual(view.yoga.end.unit, YGUnitPoint);
view.yoga.end = YGPercentValue(12);
XCTAssertEqual(view.yoga.end.value, 12);
XCTAssertEqual(view.yoga.end.unit, YGUnitPercent);
}
- (void)testMarginPropertiesWork
{
UIView *view = [[UIView alloc] initWithFrame:CGRectZero];
view.yoga.margin = 1;
XCTAssertEqual(view.yoga.margin, 1);
XCTAssertTrue(isnan(view.yoga.marginLeft));
XCTAssertTrue(isnan(view.yoga.marginRight));
XCTAssertTrue(isnan(view.yoga.marginStart));
XCTAssertTrue(isnan(view.yoga.marginEnd));
XCTAssertTrue(isnan(view.yoga.marginTop));
XCTAssertTrue(isnan(view.yoga.marginBottom));
XCTAssertTrue(isnan(view.yoga.marginHorizontal));
XCTAssertTrue(isnan(view.yoga.marginVertical));
view.yoga.margin = YGPointValue(1);
XCTAssertEqual(view.yoga.margin.value, 1);
XCTAssertEqual(view.yoga.margin.unit, YGUnitPoint);
view.yoga.margin = YGPercentValue(2);
XCTAssertEqual(view.yoga.margin.value, 2);
XCTAssertEqual(view.yoga.margin.unit, YGUnitPercent);
view.yoga.marginHorizontal = 2;
XCTAssertEqual(view.yoga.marginHorizontal, 2);
XCTAssertTrue(isnan(view.yoga.marginLeft));
XCTAssertTrue(isnan(view.yoga.marginRight));
XCTAssertTrue(isnan(view.yoga.marginStart));
XCTAssertTrue(isnan(view.yoga.marginEnd));
view.yoga.marginHorizontal = YGPointValue(3);
XCTAssertEqual(view.yoga.marginHorizontal.value, 3);
XCTAssertEqual(view.yoga.marginHorizontal.unit, YGUnitPoint);
view.yoga.marginHorizontal = YGPercentValue(4);
XCTAssertEqual(view.yoga.marginHorizontal.value, 4);
XCTAssertEqual(view.yoga.marginHorizontal.unit, YGUnitPercent);
view.yoga.marginVertical = 3;
XCTAssertEqual(view.yoga.marginVertical, 3);
XCTAssertTrue(isnan(view.yoga.marginTop));
XCTAssertTrue(isnan(view.yoga.marginBottom));
view.yoga.marginVertical = YGPointValue(5);
XCTAssertEqual(view.yoga.marginVertical.value, 5);
XCTAssertEqual(view.yoga.marginVertical.unit, YGUnitPoint);
view.yoga.marginVertical = YGPercentValue(6);
XCTAssertEqual(view.yoga.marginVertical.value, 6);
XCTAssertEqual(view.yoga.marginVertical.unit, YGUnitPercent);
view.yoga.marginLeft = 4;
XCTAssertEqual(YGNodeStyleGetMargin(view.yoga.node, YGEdgeLeft).value, 4);
XCTAssertEqual(YGNodeStyleGetMargin(view.yoga.node, YGEdgeLeft).unit, YGUnitPoint);
XCTAssertEqual(view.yoga.marginLeft, 4);
view.yoga.marginLeft = YGPointValue(7);
XCTAssertEqual(view.yoga.marginLeft.value, 7);
XCTAssertEqual(view.yoga.marginLeft.unit, YGUnitPoint);
view.yoga.marginLeft = YGPercentValue(8);
XCTAssertEqual(view.yoga.marginLeft.value, 8);
XCTAssertEqual(view.yoga.marginLeft.unit, YGUnitPercent);
view.yoga.marginRight = 5;
XCTAssertEqual(YGNodeStyleGetMargin(view.yoga.node, YGEdgeRight).value, 5);
XCTAssertEqual(YGNodeStyleGetMargin(view.yoga.node, YGEdgeRight).unit, YGUnitPoint);
XCTAssertEqual(view.yoga.marginRight, 5);
view.yoga.marginRight = YGPointValue(9);
XCTAssertEqual(view.yoga.marginRight.value, 9);
XCTAssertEqual(view.yoga.marginRight.unit, YGUnitPoint);
view.yoga.marginRight = YGPercentValue(10);
XCTAssertEqual(view.yoga.marginRight.value, 10);
XCTAssertEqual(view.yoga.marginRight.unit, YGUnitPercent);
view.yoga.marginTop = 6;
XCTAssertEqual(YGNodeStyleGetMargin(view.yoga.node, YGEdgeTop).value, 6);
XCTAssertEqual(YGNodeStyleGetMargin(view.yoga.node, YGEdgeTop).unit, YGUnitPoint);
XCTAssertEqual(view.yoga.marginTop, 6);
view.yoga.marginTop = YGPointValue(11);
XCTAssertEqual(view.yoga.marginTop.value, 11);
XCTAssertEqual(view.yoga.marginTop.unit, YGUnitPoint);
view.yoga.marginTop = YGPercentValue(12);
XCTAssertEqual(view.yoga.marginTop.value, 12);
XCTAssertEqual(view.yoga.marginTop.unit, YGUnitPercent);
view.yoga.marginBottom = 7;
XCTAssertEqual(YGNodeStyleGetMargin(view.yoga.node, YGEdgeBottom).value, 7);
XCTAssertEqual(YGNodeStyleGetMargin(view.yoga.node, YGEdgeBottom).unit, YGUnitPoint);
XCTAssertEqual(view.yoga.marginBottom, 7);
view.yoga.marginBottom = YGPointValue(13);
XCTAssertEqual(view.yoga.marginBottom.value, 13);
XCTAssertEqual(view.yoga.marginBottom.unit, YGUnitPoint);
view.yoga.marginBottom = YGPercentValue(14);
XCTAssertEqual(view.yoga.marginBottom.value, 14);
XCTAssertEqual(view.yoga.marginBottom.unit, YGUnitPercent);
view.yoga.marginStart = 8;
XCTAssertEqual(YGNodeStyleGetMargin(view.yoga.node, YGEdgeStart).value, 8);
XCTAssertEqual(YGNodeStyleGetMargin(view.yoga.node, YGEdgeStart).unit, YGUnitPoint);
XCTAssertEqual(view.yoga.marginStart, 8);
view.yoga.marginStart = YGPointValue(15);
XCTAssertEqual(view.yoga.marginStart.value, 15);
XCTAssertEqual(view.yoga.marginStart.unit, YGUnitPoint);
view.yoga.marginStart = YGPercentValue(16);
XCTAssertEqual(view.yoga.marginStart.value, 16);
XCTAssertEqual(view.yoga.marginStart.unit, YGUnitPercent);
view.yoga.marginEnd = 9;
XCTAssertEqual(YGNodeStyleGetMargin(view.yoga.node, YGEdgeEnd).value, 9);
XCTAssertEqual(YGNodeStyleGetMargin(view.yoga.node, YGEdgeEnd).unit, YGUnitPoint);
XCTAssertEqual(view.yoga.marginEnd, 9);
view.yoga.marginEnd = YGPointValue(17);
XCTAssertEqual(view.yoga.marginEnd.value, 17);
XCTAssertEqual(view.yoga.marginEnd.unit, YGUnitPoint);
view.yoga.marginEnd = YGPercentValue(18);
XCTAssertEqual(view.yoga.marginEnd.value, 18);
XCTAssertEqual(view.yoga.marginEnd.unit, YGUnitPercent);
}
- (void)testPaddingPropertiesWork
{
UIView *view = [[UIView alloc] initWithFrame:CGRectZero];
view.yoga.padding = 1;
XCTAssertEqual(view.yoga.padding, 1);
XCTAssertTrue(isnan(view.yoga.paddingLeft));
XCTAssertTrue(isnan(view.yoga.paddingRight));
XCTAssertTrue(isnan(view.yoga.paddingStart));
XCTAssertTrue(isnan(view.yoga.paddingEnd));
XCTAssertTrue(isnan(view.yoga.paddingTop));
XCTAssertTrue(isnan(view.yoga.paddingBottom));
XCTAssertTrue(isnan(view.yoga.paddingHorizontal));
XCTAssertTrue(isnan(view.yoga.paddingVertical));
view.yoga.padding = YGPointValue(1);
XCTAssertEqual(view.yoga.padding.value, 1);
XCTAssertEqual(view.yoga.padding.unit, YGUnitPoint);
view.yoga.padding = YGPercentValue(2);
XCTAssertEqual(view.yoga.padding.value, 2);
XCTAssertEqual(view.yoga.padding.unit, YGUnitPercent);
view.yoga.paddingHorizontal = 2;
XCTAssertEqual(view.yoga.paddingHorizontal, 2);
XCTAssertTrue(isnan(view.yoga.paddingLeft));
XCTAssertTrue(isnan(view.yoga.paddingRight));
XCTAssertTrue(isnan(view.yoga.paddingStart));
XCTAssertTrue(isnan(view.yoga.paddingEnd));
view.yoga.paddingHorizontal = YGPointValue(3);
XCTAssertEqual(view.yoga.paddingHorizontal.value, 3);
XCTAssertEqual(view.yoga.paddingHorizontal.unit, YGUnitPoint);
view.yoga.paddingHorizontal = YGPercentValue(4);
XCTAssertEqual(view.yoga.paddingHorizontal.value, 4);
XCTAssertEqual(view.yoga.paddingHorizontal.unit, YGUnitPercent);
view.yoga.paddingVertical = 3;
XCTAssertEqual(view.yoga.paddingVertical, 3);
XCTAssertTrue(isnan(view.yoga.paddingTop));
XCTAssertTrue(isnan(view.yoga.paddingBottom));
view.yoga.paddingVertical = YGPointValue(5);
XCTAssertEqual(view.yoga.paddingVertical.value, 5);
XCTAssertEqual(view.yoga.paddingVertical.unit, YGUnitPoint);
view.yoga.paddingVertical = YGPercentValue(6);
XCTAssertEqual(view.yoga.paddingVertical.value, 6);
XCTAssertEqual(view.yoga.paddingVertical.unit, YGUnitPercent);
view.yoga.paddingLeft = 4;
XCTAssertEqual(YGNodeStyleGetPadding(view.yoga.node, YGEdgeLeft).value, 4);
XCTAssertEqual(YGNodeStyleGetPadding(view.yoga.node, YGEdgeLeft).unit, YGUnitPoint);
XCTAssertEqual(view.yoga.paddingLeft, 4);
view.yoga.paddingLeft = YGPointValue(7);
XCTAssertEqual(view.yoga.paddingLeft.value, 7);
XCTAssertEqual(view.yoga.paddingLeft.unit, YGUnitPoint);
view.yoga.paddingLeft = YGPercentValue(8);
XCTAssertEqual(view.yoga.paddingLeft.value, 8);
XCTAssertEqual(view.yoga.paddingLeft.unit, YGUnitPercent);
view.yoga.paddingRight = 5;
XCTAssertEqual(YGNodeStyleGetPadding(view.yoga.node, YGEdgeRight).value, 5);
XCTAssertEqual(YGNodeStyleGetPadding(view.yoga.node, YGEdgeRight).unit, YGUnitPoint);
XCTAssertEqual(view.yoga.paddingRight, 5);
view.yoga.paddingRight = YGPointValue(9);
XCTAssertEqual(view.yoga.paddingRight.value, 9);
XCTAssertEqual(view.yoga.paddingRight.unit, YGUnitPoint);
view.yoga.paddingRight = YGPercentValue(10);
XCTAssertEqual(view.yoga.paddingRight.value, 10);
XCTAssertEqual(view.yoga.paddingRight.unit, YGUnitPercent);
view.yoga.paddingTop = 6;
XCTAssertEqual(YGNodeStyleGetPadding(view.yoga.node, YGEdgeTop).value, 6);
XCTAssertEqual(YGNodeStyleGetPadding(view.yoga.node, YGEdgeTop).unit, YGUnitPoint);
XCTAssertEqual(view.yoga.paddingTop, 6);
view.yoga.paddingTop = YGPointValue(11);
XCTAssertEqual(view.yoga.paddingTop.value, 11);
XCTAssertEqual(view.yoga.paddingTop.unit, YGUnitPoint);
view.yoga.paddingTop = YGPercentValue(12);
XCTAssertEqual(view.yoga.paddingTop.value, 12);
XCTAssertEqual(view.yoga.paddingTop.unit, YGUnitPercent);
view.yoga.paddingBottom = 7;
XCTAssertEqual(YGNodeStyleGetPadding(view.yoga.node, YGEdgeBottom).value, 7);
XCTAssertEqual(YGNodeStyleGetPadding(view.yoga.node, YGEdgeBottom).unit, YGUnitPoint);
XCTAssertEqual(view.yoga.paddingBottom, 7);
view.yoga.paddingBottom = YGPointValue(13);
XCTAssertEqual(view.yoga.paddingBottom.value, 13);
XCTAssertEqual(view.yoga.paddingBottom.unit, YGUnitPoint);
view.yoga.paddingBottom = YGPercentValue(14);
XCTAssertEqual(view.yoga.paddingBottom.value, 14);
XCTAssertEqual(view.yoga.paddingBottom.unit, YGUnitPercent);
view.yoga.paddingStart = 8;
XCTAssertEqual(YGNodeStyleGetPadding(view.yoga.node, YGEdgeStart).value, 8);
XCTAssertEqual(YGNodeStyleGetPadding(view.yoga.node, YGEdgeStart).unit, YGUnitPoint);
XCTAssertEqual(view.yoga.paddingStart, 8);
view.yoga.paddingStart = YGPointValue(15);
XCTAssertEqual(view.yoga.paddingStart.value, 15);
XCTAssertEqual(view.yoga.paddingStart.unit, YGUnitPoint);
view.yoga.paddingStart = YGPercentValue(16);
XCTAssertEqual(view.yoga.paddingStart.value, 16);
XCTAssertEqual(view.yoga.paddingStart.unit, YGUnitPercent);
view.yoga.paddingEnd = 9;
XCTAssertEqual(YGNodeStyleGetPadding(view.yoga.node, YGEdgeEnd).value, 9);
XCTAssertEqual(YGNodeStyleGetPadding(view.yoga.node, YGEdgeEnd).unit, YGUnitPoint);
XCTAssertEqual(view.yoga.paddingEnd, 9);
view.yoga.paddingEnd = YGPointValue(17);
XCTAssertEqual(view.yoga.paddingEnd.value, 17);
XCTAssertEqual(view.yoga.paddingEnd.unit, YGUnitPoint);
view.yoga.paddingEnd = YGPercentValue(18);
XCTAssertEqual(view.yoga.paddingEnd.value, 18);
XCTAssertEqual(view.yoga.paddingEnd.unit, YGUnitPercent);
}
- (void)testBorderWidthPropertiesWork
@@ -679,12 +719,6 @@
view.yoga.borderWidth = 1;
XCTAssertEqual(view.yoga.borderWidth, 1);
XCTAssertTrue(isnan(view.yoga.borderLeftWidth));
XCTAssertTrue(isnan(view.yoga.borderRightWidth));
XCTAssertTrue(isnan(view.yoga.borderStartWidth));
XCTAssertTrue(isnan(view.yoga.borderEndWidth));
XCTAssertTrue(isnan(view.yoga.borderTopWidth));
XCTAssertTrue(isnan(view.yoga.borderBottomWidth));
view.yoga.borderLeftWidth = 2;
XCTAssertEqual(view.yoga.borderLeftWidth, 2);

View File

@@ -4,9 +4,9 @@ PODS:
- IGListKit/Default (2.1.0):
- IGListKit/Diffing
- IGListKit/Diffing (2.1.0)
- Yoga (1.3.0)
- YogaKit (1.3.0):
- Yoga (~> 1.3)
- Yoga (1.7.0)
- YogaKit (1.7.0):
- Yoga (~> 1.7)
DEPENDENCIES:
- IGListKit (~> 2.1.0)
@@ -14,13 +14,13 @@ DEPENDENCIES:
EXTERNAL SOURCES:
YogaKit:
:path: "../../YogaKit.podspec"
:path: ../../YogaKit.podspec
SPEC CHECKSUMS:
IGListKit: b826c68ef7a4ae1626c09d4d3e1ea7a169e6c36e
Yoga: 2ed1d7accfef3610a67f58c0cf101a0662137f2c
YogaKit: cddeccc6a8d2aff563e4c738d3bddb290a6de4cb
YogaKit: 31576530e8fcae3175469719ec3212397403330b
PODFILE CHECKSUM: 216f8e7127767709e0e43f3711208d238fa5c404
COCOAPODS: 1.2.0
COCOAPODS: 1.1.1

View File

@@ -12,6 +12,11 @@ import YogaKit
struct DemoItem {
let name: String
root.backgroundColor = .red
root.yoga.isEnabled = true
root.yoga.width = YGValue(self.view.bounds.size.width)
root.yoga.height = YGValue(self.view.bounds.size.height)
root.yoga.alignItems = .center
}
final class SwiftViewController: UIViewController, IGListAdapterDataSource {

View File

@@ -17,16 +17,16 @@
UIView *root = self.view;
root.backgroundColor = [UIColor redColor];
root.yoga.isEnabled = YES;
root.yoga.width = self.view.bounds.size.width;
root.yoga.height = self.view.bounds.size.height;
root.yoga.width = YGPointValue(self.view.bounds.size.width);
root.yoga.height = YGPointValue(self.view.bounds.size.height);
root.yoga.alignItems = YGAlignCenter;
root.yoga.justifyContent = YGJustifyCenter;
UIView *child1 = [UIView new];
child1.backgroundColor = [UIColor blueColor];
child1.yoga.isEnabled = YES;
child1.yoga.width = 100;
child1.yoga.height = 100;
child1.yoga.width = YGPointValue(100);
child1.yoga.height = YGPointValue(100);
UIView *child2 = [UIView new];
child2.backgroundColor = [UIColor greenColor];

View File

@@ -17,8 +17,8 @@ final class BasicViewController: UIViewController {
root.backgroundColor = .white
root.configureLayout { (layout) in
layout.isEnabled = true
layout.width = containerSize.width
layout.height = containerSize.height
layout.width = YGValue(containerSize.width)
layout.height = YGValue(containerSize.height)
layout.alignItems = .center
layout.justifyContent = .center
}

View File

@@ -29,7 +29,7 @@ final class LayoutInclusionViewController: UIViewController {
contentView.configureLayout { (layout) in
layout.isEnabled = true
layout.height = 300
layout.width = self.view.bounds.size.width
layout.width = YGValue(self.view.bounds.size.width)
layout.flexDirection = .row
layout.justifyContent = .center
layout.paddingHorizontal = 25

View File

@@ -3,8 +3,8 @@ apply plugin: 'com.android.library'
apply plugin: 'com.github.dcendents.android-maven'
apply plugin: 'maven-publish'
version = '1.4.1'
group = 'com.facebook.yoga.android'
version = VERSION_NAME
group = GROUP
android {
compileSdkVersion rootProject.compileSdkVersion
@@ -22,7 +22,7 @@ android {
}
dependencies {
compile project(':yoga')
api project(':yoga')
}
task sourcesJar(type: Jar) {
@@ -42,8 +42,4 @@ task javadocJar(type: Jar, dependsOn: javadoc) {
from javadoc.destinationDir
}
ext {
bintrayName = 'com.facebook.yoga.android:yoga-layout'
}
apply from: rootProject.file('gradle/android-jcenter-install.gradle')
apply from: rootProject.file('gradle/release.gradle')

View File

@@ -0,0 +1,5 @@
GROUP=com.facebook.yoga.android
POM_NAME=YogaLayout
POM_DESCRIPTION=YogaLayout
POM_ARTIFACT_ID=yoga-layout
POM_PACKAGING=aar

View File

@@ -4,7 +4,7 @@ package com.facebook.samples.yoga;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.app.AppCompatActivity;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.Fragment;
@@ -19,7 +19,7 @@ import android.support.v7.app.ActionBar;
import com.facebook.samples.yoga.R;
import com.facebook.yoga.android.YogaViewLayoutFactory;
public class BenchmarkActivity extends ActionBarActivity {
public class BenchmarkActivity extends AppCompatActivity {
@Override
public void onCreate(Bundle savedInstanceState) {

View File

@@ -10,7 +10,7 @@ package com.facebook.samples.yoga;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.app.AppCompatActivity;
import android.view.LayoutInflater;
import android.view.MenuInflater;
import android.view.MenuItem;
@@ -25,7 +25,7 @@ import com.facebook.yoga.android.YogaViewLayoutFactory;
* {@code main_layout.xml}) that shows off the awesome functionality of the Yoga layout engine
* as well as some optimisations on layout systems that it facilitates.
*/
public class MainActivity extends ActionBarActivity {
public class MainActivity extends AppCompatActivity {
@Override
public void onCreate(Bundle savedInstanceState) {

View File

@@ -10,6 +10,8 @@ include_defs("//YOGA_DEFS")
cxx_binary(
name = "benchmark",
srcs = glob(["*.c"]),
headers = subdir_glob([("", "*.h")]),
header_namespace = "",
compiler_flags = [
"-fno-omit-frame-pointer",
"-fexceptions",
@@ -18,8 +20,6 @@ cxx_binary(
"-O3",
"-std=c11",
],
header_namespace = "",
headers = subdir_glob([("", "*.h")]),
visibility = ["PUBLIC"],
deps = [
yoga_dep(":yoga"),

View File

@@ -3,12 +3,12 @@
buildscript {
repositories {
jcenter()
maven { url 'https://maven.google.com/' }
}
dependencies {
classpath 'com.android.tools.build:gradle:2.3.1'
classpath 'com.android.tools.build:gradle:3.0.0'
classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3'
classpath 'com.github.dcendents:android-maven-gradle-plugin:1.4.1'
classpath 'com.nabilhachicha:android-native-dependencies:0.1'
classpath 'com.github.dcendents:android-maven-gradle-plugin:2.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
@@ -22,14 +22,41 @@ allprojects {
}
ext {
minSdkVersion = 15
minSdkVersion = 14
targetSdkVersion = 25
compileSdkVersion = 25
buildToolsVersion = '25.0.2'
compileSdkVersion = 26
buildToolsVersion = '26.0.2'
sourceCompatibilityVersion = JavaVersion.VERSION_1_7
targetCompatibilityVersion = JavaVersion.VERSION_1_7
}
// If you have an idea on how to avoid this, please get in touch or
// answer https://stackoverflow.com/questions/43867014/how-to-use-the-gradle-ndk-build-to-compile-for-the-host-machine.
task copyNativeLibs(type: Copy, dependsOn: ':buckBuildNative') {
from "${rootDir}/buck-out/gen/java/tests#default,shared-library-symlink-tree/"
include '*.so'
include '*.dylib'
into "$buildDir/jniLibs"
}
task buckBuildNative(type: Exec) {
workingDir rootDir
environment BUCKVERSION: 'last'
commandLine 'buck', 'build', '//java/...'
}
allprojects {
afterEvaluate {
tasks.withType(Test) {
dependsOn copyNativeLibs
def libDir = "${rootDir}/build/jniLibs"
systemProperty 'java.library.path', libDir
environment 'LD_LIBRARY_PATH', libDir
environment 'DYLD_LIBRARY_PATH', libDir
}
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}

3
csharp/.gitignore vendored
View File

@@ -267,3 +267,6 @@ paket-files/
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# local buck build
lib/

View File

@@ -267,3 +267,6 @@ paket-files/
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# local buck build
lib/

View File

@@ -4,17 +4,17 @@
<BuildDependsOn>NativeLibraryARMV7;NativeLibraryX86;$(BuildDependsOn)</BuildDependsOn>
</PropertyGroup>
<Target Name="NativeLibraryARMV7" Outputs="$(ProjectDir)/lib/armeabi-v7a/libyoga.so">
<Exec WorkingDirectory="$(ProjectDir)" Command="$(ProjectDir)../../Mac/buck-build.sh //csharp:yoganet#android-armv7,shared" />
<Exec WorkingDirectory="$(ProjectDir)" Command="$(ProjectDir)../../build-native.sh" />
<Copy SourceFiles="$(ProjectDir)../../../buck-out/gen/csharp/yoganet#android-armv7,shared/libyoga.so" DestinationFiles="$(ProjectDir)/lib/armeabi-v7a/libyoga.so" SkipUnchangedFiles="true" />
</Target>
<!--
<Target Name="NativeLibraryARM64" Outputs="$(ProjectDir)/lib/arm64-v8a/libyoga.so">
<Exec WorkingDirectory="$(ProjectDir)" Command="$(ProjectDir)../../Mac/buck-build.sh //csharp:yoganet#android-arm64,shared" />
<Exec WorkingDirectory="$(ProjectDir)" Command="$(ProjectDir)../../build-native.sh" />
<Copy SourceFiles="$(ProjectDir)../../../buck-out/gen/csharp/yoganet#android-arm64,shared/libyoga.so" DestinationFiles="$(ProjectDir)/lib/arm64-v8/libyoga.so" SkipUnchangedFiles="true" />
</Target>
-->
<Target Name="NativeLibraryX86" Outputs="$(ProjectDir)/lib/x86/libyoga.so">
<Exec WorkingDirectory="$(ProjectDir)" Command="$(ProjectDir)../../Mac/buck-build.sh //csharp:yoganet#android-x86,shared" />
<Exec WorkingDirectory="$(ProjectDir)" Command="$(ProjectDir)../../build-native.sh" />
<Copy SourceFiles="$(ProjectDir)../../../buck-out/gen/csharp/yoganet#android-x86,shared/libyoga.so" DestinationFiles="$(ProjectDir)/lib/x86/libyoga.so" SkipUnchangedFiles="true" />
</Target>
</Project>

View File

@@ -10,9 +10,12 @@
</PropertyGroup>
<ItemGroup>
<Compile Include="$(MSBuildThisFileDirectory)BaselineFunction.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Logger.cs" />
<Compile Include="$(MSBuildThisFileDirectory)MeasureFunction.cs" />
<Compile Include="$(MSBuildThisFileDirectory)MeasureOutput.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Native.cs" />
<Compile Include="$(MSBuildThisFileDirectory)YGConfigHandle.cs" />
<Compile Include="$(MSBuildThisFileDirectory)YGNodeHandle.cs" />
<Compile Include="$(MSBuildThisFileDirectory)YogaAlign.cs" />
<Compile Include="$(MSBuildThisFileDirectory)YogaBaselineFunc.cs" />
<Compile Include="$(MSBuildThisFileDirectory)YogaConfig.cs" />

View File

@@ -0,0 +1,17 @@
/**
* Copyright (c) 2014-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
namespace Facebook.Yoga
{
public delegate void Logger(
YogaConfig config,
YogaNode node,
YogaLogLevel level,
string message);
}

View File

@@ -26,96 +26,9 @@ namespace Facebook.Yoga
private const string DllName = "yoga";
#endif
internal class YGNodeHandle : SafeHandle
{
#if (UNITY_IOS && !UNITY_EDITOR) || ENABLE_IL2CPP || __IOS__
private GCHandle _managed;
#endif
private YGNodeHandle() : base(IntPtr.Zero, true)
{
}
public override bool IsInvalid
{
get
{
return this.handle == IntPtr.Zero;
}
}
protected override bool ReleaseHandle()
{
#if (UNITY_IOS && !UNITY_EDITOR) || ENABLE_IL2CPP || __IOS__
ReleaseManaged();
#endif
Native.YGNodeFree(this.handle);
GC.KeepAlive(this);
return true;
}
#if (UNITY_IOS && !UNITY_EDITOR) || ENABLE_IL2CPP || __IOS__
public void SetContext(YogaNode node)
{
if (!_managed.IsAllocated)
{
#if ENABLE_IL2CPP
// Weak causes 'GCHandle value belongs to a different domain' error
_managed = GCHandle.Alloc(node);
#else
_managed = GCHandle.Alloc(node, GCHandleType.Weak);
#endif
Native.YGNodeSetContext(this.handle, GCHandle.ToIntPtr(_managed));
}
}
public void ReleaseManaged()
{
if (_managed.IsAllocated)
{
_managed.Free();
}
}
public static YogaNode GetManaged(IntPtr ygNodePtr)
{
var node =
GCHandle.FromIntPtr(Native.YGNodeGetContext(ygNodePtr)).Target as YogaNode;
if (node == null)
{
throw new InvalidOperationException("YogaNode is already deallocated");
}
return node;
}
#endif
}
internal class YGConfigHandle : SafeHandle
{
private YGConfigHandle() : base(IntPtr.Zero, true)
{
}
public override bool IsInvalid
{
get
{
return this.handle == IntPtr.Zero;
}
}
protected override bool ReleaseHandle()
{
Native.YGConfigFree(this.handle);
GC.KeepAlive(this);
return true;
}
}
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
public static extern void YGInteropSetLogger(
[MarshalAs(UnmanagedType.FunctionPtr)] YogaLogger.Func func);
[MarshalAs(UnmanagedType.FunctionPtr)] YogaLogger logger);
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
public static extern YGNodeHandle YGNodeNew();
@@ -129,6 +42,9 @@ namespace Facebook.Yoga
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
public static extern void YGNodeReset(YGNodeHandle node);
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
public static extern YGConfigHandle YGConfigGetDefault();
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
public static extern YGConfigHandle YGConfigNew();
@@ -445,15 +361,19 @@ namespace Facebook.Yoga
#endregion
#region AOT
#region Context
#if (UNITY_IOS && !UNITY_EDITOR) || ENABLE_IL2CPP || __IOS__
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr YGNodeGetContext(IntPtr node);
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
public static extern void YGNodeSetContext(IntPtr node, IntPtr managed);
#endif
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr YGConfigGetContext(IntPtr config);
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
public static extern void YGConfigSetContext(IntPtr config, IntPtr managed);
#endregion
}

View File

@@ -0,0 +1,84 @@
/**
* Copyright (c) 2014-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
using System;
using System.Runtime.InteropServices;
namespace Facebook.Yoga
{
internal class YGConfigHandle : SafeHandle
{
internal static readonly YGConfigHandle Default = Native.YGConfigGetDefault();
private GCHandle _managedConfigHandle;
private YGConfigHandle() : base(IntPtr.Zero, true)
{
}
public override bool IsInvalid
{
get
{
return this.handle == IntPtr.Zero;
}
}
protected override bool ReleaseHandle()
{
if (this.handle != Default.handle)
{
ReleaseManaged();
if (!IsInvalid)
{
Native.YGConfigFree(this.handle);
}
}
GC.KeepAlive(this);
return true;
}
public void SetContext(YogaConfig config)
{
if (!_managedConfigHandle.IsAllocated)
{
#if UNITY_5_4_OR_NEWER
// Weak causes 'GCHandle value belongs to a different domain' error
_managedConfigHandle = GCHandle.Alloc(config);
#else
_managedConfigHandle = GCHandle.Alloc(config, GCHandleType.Weak);
#endif
var managedConfigPtr = GCHandle.ToIntPtr(_managedConfigHandle);
Native.YGConfigSetContext(this.handle, managedConfigPtr);
}
}
private void ReleaseManaged()
{
if (_managedConfigHandle.IsAllocated)
{
_managedConfigHandle.Free();
}
}
public static YogaConfig GetManaged(IntPtr unmanagedConfigPtr)
{
if (unmanagedConfigPtr != IntPtr.Zero)
{
var managedConfigPtr = Native.YGConfigGetContext(unmanagedConfigPtr);
var config = GCHandle.FromIntPtr(managedConfigPtr).Target as YogaConfig;
if (config == null)
{
throw new InvalidOperationException("YogaConfig is already deallocated");
}
return config;
}
return null;
}
}
}

View File

@@ -0,0 +1,80 @@
/**
* Copyright (c) 2014-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
using System;
using System.Runtime.InteropServices;
namespace Facebook.Yoga
{
internal class YGNodeHandle : SafeHandle
{
private GCHandle _managedNodeHandle;
private YGNodeHandle() : base(IntPtr.Zero, true)
{
}
public override bool IsInvalid
{
get
{
return this.handle == IntPtr.Zero;
}
}
protected override bool ReleaseHandle()
{
ReleaseManaged();
if (!IsInvalid)
{
Native.YGNodeFree(this.handle);
GC.KeepAlive(this);
}
return true;
}
public void SetContext(YogaNode node)
{
if (!_managedNodeHandle.IsAllocated)
{
#if UNITY_5_4_OR_NEWER
// Weak causes 'GCHandle value belongs to a different domain' error
_managedNodeHandle = GCHandle.Alloc(node);
#else
_managedNodeHandle = GCHandle.Alloc(node, GCHandleType.Weak);
#endif
var managedNodePtr = GCHandle.ToIntPtr(_managedNodeHandle);
Native.YGNodeSetContext(this.handle, managedNodePtr);
}
}
public void ReleaseManaged()
{
if (_managedNodeHandle.IsAllocated)
{
_managedNodeHandle.Free();
}
}
public static YogaNode GetManaged(IntPtr unmanagedNodePtr)
{
if (unmanagedNodePtr != IntPtr.Zero)
{
var managedNodePtr = Native.YGNodeGetContext(unmanagedNodePtr);
var node = GCHandle.FromIntPtr(managedNodePtr).Target as YogaNode;
if (node == null)
{
throw new InvalidOperationException("YogaNode is already deallocated");
}
return node;
}
return null;
}
}
}

View File

@@ -13,5 +13,5 @@ using System.Runtime.InteropServices;
namespace Facebook.Yoga
{
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate float YogaBaselineFunc(IntPtr node, float width, float height);
public delegate float YogaBaselineFunc(IntPtr unmanagedNodePtr, float width, float height);
}

View File

@@ -8,29 +8,92 @@
*/
using System;
using System.Runtime.InteropServices;
#if __IOS__
using ObjCRuntime;
#endif
#if ENABLE_IL2CPP
using AOT;
#endif
namespace Facebook.Yoga
{
public class YogaConfig
{
private Native.YGConfigHandle _ygConfig;
internal static readonly YogaConfig Default = new YogaConfig(YGConfigHandle.Default);
private static YogaLogger _managedLogger;
public YogaConfig()
private YGConfigHandle _ygConfig;
private Logger _logger;
private YogaConfig(YGConfigHandle ygConfig)
{
_ygConfig = Native.YGConfigNew();
_ygConfig = ygConfig;
if (_ygConfig.IsInvalid)
{
throw new InvalidOperationException("Failed to allocate native memory");
}
_ygConfig.SetContext(this);
if (_ygConfig == YGConfigHandle.Default)
{
_managedLogger = LoggerInternal;
Native.YGInteropSetLogger(_managedLogger);
}
}
internal Native.YGConfigHandle Handle
public YogaConfig()
: this(Native.YGConfigNew())
{
}
internal YGConfigHandle Handle
{
get {
return _ygConfig;
}
}
#if (UNITY_IOS && !UNITY_EDITOR) || ENABLE_IL2CPP || __IOS__
[MonoPInvokeCallback(typeof(YogaLogger))]
#endif
private static void LoggerInternal(
IntPtr unmanagedConfigPtr,
IntPtr unmanagedNodePtr,
YogaLogLevel level,
string message)
{
var config = YGConfigHandle.GetManaged(unmanagedConfigPtr);
if (config == null || config._logger == null)
{
// Default logger
System.Diagnostics.Debug.WriteLine(message);
}
else
{
var node = YGNodeHandle.GetManaged(unmanagedNodePtr);
config._logger(config, node, level, message);
}
if (level == YogaLogLevel.Error || level == YogaLogLevel.Fatal)
{
throw new InvalidOperationException(message);
}
}
public Logger Logger
{
get {
return _logger;
}
set {
_logger = value;
}
}
public void SetExperimentalFeatureEnabled(
YogaExperimentalFeature feature,
bool enabled)
@@ -68,5 +131,10 @@ namespace Facebook.Yoga
{
return Native.YGConfigGetInstanceCount();
}
public static void SetDefaultLogger(Logger logger)
{
Default.Logger = logger;
}
}
}

View File

@@ -11,8 +11,6 @@ namespace Facebook.Yoga
{
public enum YogaExperimentalFeature
{
Rounding,
WebFlexBasis,
MinFlexFix,
}
}

View File

@@ -16,5 +16,6 @@ namespace Facebook.Yoga
Info,
Debug,
Verbose,
Fatal,
}
}

View File

@@ -10,48 +10,12 @@
using System;
using System.Runtime.InteropServices;
#if __IOS__
using ObjCRuntime;
#endif
#if ENABLE_IL2CPP
using AOT;
#endif
namespace Facebook.Yoga
{
internal static class YogaLogger
{
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void Func(YogaLogLevel level, string message);
private static bool _initialized;
private static Func _managedLogger = LoggerInternal;
public static Func Logger = null;
#if (UNITY_IOS && !UNITY_EDITOR) || ENABLE_IL2CPP || __IOS__
[MonoPInvokeCallback(typeof(Func))]
#endif
public static void LoggerInternal(YogaLogLevel level, string message)
{
if (Logger != null)
{
Logger(level, message);
}
if (level == YogaLogLevel.Error)
{
throw new InvalidOperationException(message);
}
}
public static void Initialize()
{
if (!_initialized)
{
Native.YGInteropSetLogger(_managedLogger);
_initialized = true;
}
}
}
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void YogaLogger(
IntPtr unmanagedConfigPtr,
IntPtr unmanagedNotePtr,
YogaLogLevel level,
string message);
}

View File

@@ -14,7 +14,7 @@ namespace Facebook.Yoga
{
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate YogaSize YogaMeasureFunc(
IntPtr node,
IntPtr unmanagedNodePtr,
float width,
YogaMeasureMode widthMode,
float height,

View File

@@ -10,11 +10,9 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
#if (UNITY_IOS && !UNITY_EDITOR) || ENABLE_IL2CPP || __IOS__
using System.Runtime.InteropServices;
#endif
#if __IOS__
using ObjCRuntime;
#endif
@@ -26,49 +24,26 @@ namespace Facebook.Yoga
{
public partial class YogaNode : IEnumerable<YogaNode>
{
private readonly Native.YGNodeHandle _ygNode;
private readonly YGNodeHandle _ygNode;
private readonly YogaConfig _config;
private WeakReference _parent;
private List<YogaNode> _children;
private MeasureFunction _measureFunction;
private BaselineFunction _baselineFunction;
private object _data;
#if (UNITY_IOS && !UNITY_EDITOR) || ENABLE_IL2CPP || __IOS__
private static YogaMeasureFunc _managedMeasure;
private static YogaBaselineFunc _managedBaseline;
#else
private YogaMeasureFunc _managedMeasure;
private YogaBaselineFunc _managedBaseline;
#endif
private object _data;
public YogaNode()
public YogaNode(YogaConfig config = null)
{
YogaLogger.Initialize();
_ygNode = Native.YGNodeNew();
_config = config == null ? YogaConfig.Default : config;
_ygNode = Native.YGNodeNewWithConfig(_config.Handle);
if (_ygNode.IsInvalid)
{
throw new InvalidOperationException("Failed to allocate native memory");
}
}
public YogaNode(YogaConfig config)
{
YogaLogger.Initialize();
if (config != null)
{
_config = config;
_ygNode = Native.YGNodeNewWithConfig(_config.Handle);
}
else
{
_ygNode = Native.YGNodeNew();
}
if (_ygNode.IsInvalid)
{
throw new InvalidOperationException("Failed to allocate native memory");
}
_ygNode.SetContext(this);
}
public YogaNode(YogaNode srcNode)
@@ -83,10 +58,9 @@ namespace Facebook.Yoga
_baselineFunction = null;
_data = null;
Native.YGNodeReset(_ygNode);
#if (UNITY_IOS && !UNITY_EDITOR) || ENABLE_IL2CPP || __IOS__
_ygNode.ReleaseManaged();
#endif
Native.YGNodeReset(_ygNode);
_ygNode.SetContext(this);
}
public bool IsDirty
@@ -609,109 +583,71 @@ namespace Facebook.Yoga
public void SetMeasureFunction(MeasureFunction measureFunction)
{
_measureFunction = measureFunction;
if (measureFunction != null)
{
#if (UNITY_IOS && !UNITY_EDITOR) || ENABLE_IL2CPP || __IOS__
_managedMeasure = MeasureInternalAOT;
_ygNode.SetContext(this);
#else
_managedMeasure = MeasureInternal;
#endif
}
else
{
_managedMeasure = null;
}
_managedMeasure = measureFunction != null ? MeasureInternal : (YogaMeasureFunc)null;
Native.YGNodeSetMeasureFunc(_ygNode, _managedMeasure);
}
public void SetBaselineFunction(BaselineFunction baselineFunction)
{
_baselineFunction = baselineFunction;
if (baselineFunction != null)
{
#if (UNITY_IOS && !UNITY_EDITOR) || ENABLE_IL2CPP || __IOS__
_managedBaseline = BaselineInternalAOT;
_ygNode.SetContext(this);
#else
_managedBaseline = BaselineInternal;
#endif
}
else
{
_managedBaseline = null;
}
_managedBaseline =
baselineFunction != null ? BaselineInternal : (YogaBaselineFunc)null;
Native.YGNodeSetBaselineFunc(_ygNode, _managedBaseline);
}
public void CalculateLayout()
public void CalculateLayout(
float width = YogaConstants.Undefined,
float height = YogaConstants.Undefined)
{
Native.YGNodeCalculateLayout(
_ygNode,
YogaConstants.Undefined,
YogaConstants.Undefined,
width,
height,
Native.YGNodeStyleGetDirection(_ygNode));
}
#if (UNITY_IOS && !UNITY_EDITOR) || ENABLE_IL2CPP || __IOS__
[MonoPInvokeCallback(typeof(YogaMeasureFunc))]
private static YogaSize MeasureInternalAOT(
IntPtr ygNodePtr,
float width,
YogaMeasureMode widthMode,
float height,
YogaMeasureMode heightMode)
{
var node = Native.YGNodeHandle.GetManaged(ygNodePtr);
return node.MeasureInternal(IntPtr.Zero, width, widthMode, height, heightMode);
}
#endif
private YogaSize MeasureInternal(
IntPtr node,
private static YogaSize MeasureInternal(
IntPtr unmanagedNodePtr,
float width,
YogaMeasureMode widthMode,
float height,
YogaMeasureMode heightMode)
{
if (_measureFunction == null)
var node = YGNodeHandle.GetManaged(unmanagedNodePtr);
if (node == null || node._measureFunction == null)
{
throw new InvalidOperationException("Measure function is not defined.");
}
return _measureFunction(this, width, widthMode, height, heightMode);
return node._measureFunction(node, width, widthMode, height, heightMode);
}
#if (UNITY_IOS && !UNITY_EDITOR) || ENABLE_IL2CPP || __IOS__
[MonoPInvokeCallback(typeof(YogaBaselineFunc))]
private static float BaselineInternalAOT(
IntPtr ygNodePtr,
#endif
private static float BaselineInternal(
IntPtr unmanagedNodePtr,
float width,
float height)
{
var node = Native.YGNodeHandle.GetManaged(ygNodePtr);
return node.BaselineInternal(IntPtr.Zero, width, height);
}
#endif
private float BaselineInternal(IntPtr node, float width, float height)
{
if (_baselineFunction == null)
var node = YGNodeHandle.GetManaged(unmanagedNodePtr);
if (node == null || node._baselineFunction == null)
{
throw new InvalidOperationException("Baseline function is not defined.");
}
return _baselineFunction(this, width, height);
return node._baselineFunction(node, width, height);
}
public string Print(YogaPrintOptions options =
YogaPrintOptions.Layout|YogaPrintOptions.Style|YogaPrintOptions.Children)
{
StringBuilder sb = new StringBuilder();
YogaLogger.Func orig = YogaLogger.Logger;
YogaLogger.Logger = (level, message) => {sb.Append(message);};
Logger orig = _config.Logger;
_config.Logger = (config, node, level, message) => {sb.Append(message);};
Native.YGNodePrint(_ygNode, options);
YogaLogger.Logger = orig;
_config.Logger = orig;
return sb.ToString();
}

View File

@@ -0,0 +1,17 @@
/**
* Copyright (c) 2014-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
namespace Facebook.Yoga
{
public enum YogaNodeType
{
Default,
Text,
}
}

View File

@@ -4,6 +4,7 @@ using System.Collections.Generic;
using System.Drawing;
#if __IOS__
using NativeView = UIKit.UIView;
using NativeScrollView = UIKit.UIScrollView;
#endif
namespace Facebook.YogaKit
@@ -699,12 +700,12 @@ namespace Facebook.YogaKit
{
get
{
return _node.StyleAspectRatio;
return _node.AspectRatio;
}
set
{
_node.StyleAspectRatio = value;
_node.AspectRatio = value;
}
}
@@ -716,6 +717,17 @@ namespace Facebook.YogaKit
float width = 0;
float height = 0;
GetWidthHeightOfNativeView(view, out width, out height);
if (view is NativeScrollView)
{
if (FlexDirection == YogaFlexDirection.Column || FlexDirection == YogaFlexDirection.ColumnReverse)
{
height = float.NaN;
}
else
{
width = float.NaN;
}
}
CalculateLayoutWithSize(this, width, height);
ApplyLayoutToViewHierarchy(view);
}
@@ -743,9 +755,7 @@ namespace Facebook.YogaKit
var node = layout._node;
node.Width = width;
node.Height = height;
node.CalculateLayout();
node.CalculateLayout(width, height);
return new SizeF { Width = node.LayoutWidth, Height = node.LayoutHeight };
}
@@ -775,14 +785,14 @@ namespace Facebook.YogaKit
float result;
if (measureMode == YogaMeasureMode.Exactly)
{
result = (float)constrainedSize;
result = constrainedSize;
}
else if (measureMode == YogaMeasureMode.AtMost)
{
result = (float)Math.Min(constrainedSize, measuredSize);
result = Math.Min(constrainedSize, measuredSize);
}
else {
result = (float)measuredSize;
result = measuredSize;
}
return result;
@@ -820,7 +830,7 @@ namespace Facebook.YogaKit
var subviewsToInclude = new List<NativeView>();
foreach (var subview in view.Subviews)
{
if (subview.Yoga().IsIncludeInLayout)
if (subview.Yoga().IsEnabled && subview.Yoga().IsIncludeInLayout)
{
subviewsToInclude.Add(subview);
}
@@ -856,7 +866,7 @@ namespace Facebook.YogaKit
static double RoundPointValue(float value)
{
float scale = NativePointScale;
float scale = NativePixelScale;
return Math.Round(value * scale) / scale;
}

View File

@@ -4,7 +4,7 @@
<CompileDependsOn>NativeLibrary;$(CompileDependsOn)</CompileDependsOn>
</PropertyGroup>
<Target Name="NativeLibrary" Outputs="$(ProjectDir)libyoga.dylib">
<Exec WorkingDirectory="$(ProjectDir)" Command="$(ProjectDir)buck-build.sh //csharp:yoganet-macosx" />
<Exec WorkingDirectory="$(ProjectDir)" Command="$(ProjectDir)../build-native.sh" />
<Copy SourceFiles="$(ProjectDir)..\..\buck-out\gen\csharp\yoganet-macosx\libyoga.dylib" DestinationFiles="$(ProjectDir)libyoga.dylib" SkipUnchangedFiles="true" />
</Target>
</Project>

View File

@@ -33,6 +33,9 @@ namespace Facebook.Yoga.Mac.Tests
}
[System.Runtime.InteropServices.DllImport("/usr/lib/libSystem.dylib")]
static extern void _exit(int exit_code);
class NSRunLoopIntegration : NSObject, IMainLoopIntegration
{
public void InitializeToolkit()
@@ -51,7 +54,7 @@ namespace Facebook.Yoga.Mac.Tests
public void Shutdown()
{
Environment.Exit(TestRunner.ExitCode);
_exit(TestRunner.ExitCode);
}
}
}

View File

@@ -1,6 +0,0 @@
#!/bin/sh
if buck --version >/dev/null 2>&1; then true; else
echo "SKIP: Need to install buck https://buckbuild.com/setup/getting_started.html"
exit 0
fi
buck build $1

View File

@@ -9,19 +9,23 @@
#include "YGInterop.h"
static YGInteropLoggerFunc gManagedFunc;
static YGInteropLogger gManagedLogger;
static int unmanagedLogger(YGLogLevel level, const char *format, va_list args) {
static int unmanagedLogger(const YGConfigRef config,
const YGNodeRef node,
YGLogLevel level,
const char *format,
va_list args) {
int result = 0;
if (gManagedFunc) {
char buffer[256];
result = vsnprintf(buffer, sizeof(buffer), format, args);
(*gManagedFunc)(level, buffer);
if (gManagedLogger) {
char message[8192];
result = vsnprintf(message, sizeof(message), format, args);
(*gManagedLogger)(config, node, level, message);
}
return result;
}
void YGInteropSetLogger(YGInteropLoggerFunc managedFunc) {
gManagedFunc = managedFunc;
YGSetLogger(&unmanagedLogger);
void YGInteropSetLogger(YGInteropLogger managedLogger) {
gManagedLogger = managedLogger;
YGConfigSetLogger(YGConfigGetDefault(), &unmanagedLogger);
}

View File

@@ -13,8 +13,13 @@
YG_EXTERN_C_BEGIN
typedef void (*YGInteropLoggerFunc)(YGLogLevel level, const char *message);
typedef int (*YGInteropLogger)(const void *unmanagedConfigPtr,
const void *unmanagedNodePtr,
YGLogLevel level,
const char *message);
WIN_EXPORT void YGInteropSetLogger(YGInteropLoggerFunc managedFunc);
WIN_EXPORT YGConfigRef YGConfigGetDefault();
WIN_EXPORT void YGInteropSetLogger(YGInteropLogger managedLogger);
YG_EXTERN_C_END

View File

@@ -104,7 +104,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<OutDir>bin\Universal\$(PlatformTarget)\$(Configuration)\</OutDir>
<IntDir>obj\$(PlatformTarget)\$(Configuration)\</IntDir>
<IntDir>obj\Universal\$(PlatformTarget)\$(Configuration)\</IntDir>
<TargetName>yoga</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
@@ -242,8 +242,8 @@
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="..\..\yoga\YGEnums.h" />
<ClInclude Include="..\..\yoga\Yoga.h" />
<ClInclude Include="..\..\yoga\YGEnums.c" />
<ClInclude Include="..\..\yoga\YGMacros.h" />
<ClInclude Include="..\..\yoga\YGNodeList.h" />
<ClInclude Include="resource.h" />
@@ -252,8 +252,8 @@
<ClInclude Include="targetver.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\yoga\Yoga.c" />
<ClCompile Include="..\..\yoga\YGEnums.c" />
<ClCompile Include="..\..\yoga\Yoga.c" />
<ClCompile Include="..\..\yoga\YGNodeList.c" />
<ClCompile Include="YGInterop.cpp" />
<ClCompile Include="dllmain.cpp">

View File

@@ -36,6 +36,9 @@
<ClInclude Include="resource.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\yoga\YGEnums.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="stdafx.cpp">
@@ -53,6 +56,9 @@
<ClCompile Include="YGInterop.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\yoga\YGEnums.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="Yoga.rc">

View File

@@ -1,17 +1,25 @@
#!/bin/sh
cd `dirname "$0"`
echo $ANDROID_SDK
if buck --version >/dev/null 2>&1; then true; else
BUCK_RELEASE=2017.05.09.01
echo "buck $BUCK_RELEASE"
BUCK=lib/buck-$BUCK_RELEASE/bin/buck
if $BUCK --version >/dev/null 2>&1; then true; else
echo "Building Buck!"
mkdir lib
BUCK_PATH=buck-$BUCK_RELEASE
mkdir -p lib
cd lib
git clone https://github.com/facebook/buck.git --depth 1
cd buck
rm -f $BUCK_PATH.tar.gz
curl -O -J -L https://github.com/facebook/buck/archive/v$BUCK_RELEASE.tar.gz
tar xzf $BUCK_PATH.tar.gz
cd $BUCK_PATH
ant
cd ..
cd ..
cd ../..
fi
buck build //:yoga
buck build //csharp:yoganet-ios
buck build //csharp:yoganet-macosx
buck build //csharp:yoganet#android-x86,shared
buck build //csharp:yoganet#android-armv7,shared
$BUCK build \
//csharp:yoganet-ios \
//csharp:yoganet-macosx \
//csharp:yoganet#android-armv7,shared \
//csharp:yoganet#android-x86,shared

View File

@@ -4,7 +4,7 @@
<CompileDependsOn>NativeLibrary;$(CompileDependsOn)</CompileDependsOn>
</PropertyGroup>
<Target Name="NativeLibrary" Outputs="$(ProjectDir)libyoga.a">
<Exec WorkingDirectory="$(ProjectDir)" Command="$(ProjectDir)../../Mac/buck-build.sh //csharp:yoganet-ios" />
<Exec WorkingDirectory="$(ProjectDir)" Command="$(ProjectDir)../../build-native.sh" />
<Copy SourceFiles="$(ProjectDir)..\..\..\buck-out\gen\csharp\yoganet-ios\libyoga.a" DestinationFiles="$(ProjectDir)libyoga.a" SkipUnchangedFiles="true" />
</Target>
</Project>

View File

@@ -22,8 +22,6 @@
<MtouchDebug>true</MtouchDebug>
<MtouchFastDev>true</MtouchFastDev>
<MtouchProfiling>true</MtouchProfiling>
<MtouchUseSGen>true</MtouchUseSGen>
<MtouchUseRefCounting>true</MtouchUseRefCounting>
<IOSDebuggerPort>17481</IOSDebuggerPort>
<MtouchLink>None</MtouchLink>
<MtouchArch>x86_64</MtouchArch>
@@ -39,8 +37,6 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodesignKey>iPhone Developer</CodesignKey>
<MtouchUseSGen>true</MtouchUseSGen>
<MtouchUseRefCounting>true</MtouchUseRefCounting>
<MtouchFloat32>true</MtouchFloat32>
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements>
<MtouchLink>SdkOnly</MtouchLink>
@@ -56,8 +52,6 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodesignKey>iPhone Developer</CodesignKey>
<MtouchUseSGen>true</MtouchUseSGen>
<MtouchUseRefCounting>true</MtouchUseRefCounting>
<MtouchLink>None</MtouchLink>
<MtouchArch>x86_64</MtouchArch>
<MtouchHttpClientHandler>HttpClientHandler</MtouchHttpClientHandler>
@@ -76,8 +70,6 @@
<MtouchDebug>true</MtouchDebug>
<MtouchFastDev>true</MtouchFastDev>
<MtouchProfiling>true</MtouchProfiling>
<MtouchUseSGen>true</MtouchUseSGen>
<MtouchUseRefCounting>true</MtouchUseRefCounting>
<MtouchFloat32>true</MtouchFloat32>
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements>
<MtouchLink>SdkOnly</MtouchLink>
@@ -102,6 +94,7 @@
<ItemGroup>
<Compile Include="Main.cs" />
<Compile Include="UnitTestAppDelegate.cs" />
<Compile Include="YogaKitNativeTest.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Facebook.YogaKit.iOS\Facebook.YogaKit.iOS.csproj">

View File

@@ -0,0 +1,51 @@
using System.Drawing;
using Facebook.Yoga;
using NUnit.Framework;
using System;
using UIKit;
using CoreGraphics;
namespace Facebook.YogaKit.iOS.Tests
{
[TestFixture]
public class YogaKitNativeTest
{
[Test]
public void ScrollViewVertical()
{
var view = new UIScrollView() {
Frame = new CGRect(0, 0, 100, 100),
};
view.Yoga().Overflow = YogaOverflow.Scroll;
var subview = new UIView();
subview.Yoga().Height = 1000;
subview.Yoga().IsEnabled = true;
view.AddSubview(subview);
view.Yoga().IsEnabled = true;
view.Yoga().ApplyLayout();
Assert.True(view.ContentSize.Height == 1000);
}
[Test]
public void NormalViewVertical()
{
var view = new UIView() {
Frame = new CGRect(0,0, 100, 100),
};
var subview = new UIView();
subview.Yoga().Height = 1000;
subview.Yoga().Width = 2;
subview.Yoga().IsEnabled = true;
view.AddSubview(subview);
view.Yoga().IsEnabled = true;
view.Yoga().ApplyLayout();
Assert.True(view.Bounds.Height == 100);
}
}
}

View File

@@ -23,14 +23,21 @@ namespace Facebook.YogaKit
height = (float)view.Bounds.Height;
}
static float NativePixelScale => (float)UIScreen.MainScreen.Scale;
static float NativePixelScale => (float)UIScreen.MainScreen.Scale;
static void ApplyLayoutToNativeView(UIView view, YogaNode node)
{
var topLeft = new CGPoint(node.LayoutX, node.LayoutY);
var bottomRight = new CGPoint(topLeft.X + node.LayoutWidth, topLeft.Y + node.LayoutHeight);
view.Frame = new CGRect(RoundPointValue((float)topLeft.X), RoundPointValue((float)topLeft.Y), RoundPointValue((float)bottomRight.X) - RoundPointValue((float)topLeft.X), RoundPointValue((float)bottomRight.Y) - RoundPointValue((float)topLeft.Y));
if (view is UIScrollView scrollView)
{
scrollView.ContentSize = new CGSize(RoundPointValue((float)bottomRight.X) - RoundPointValue((float)topLeft.X), RoundPointValue((float)bottomRight.Y) - RoundPointValue((float)topLeft.Y));
}
else
{
view.Frame = new CGRect(RoundPointValue((float)topLeft.X), RoundPointValue((float)topLeft.Y), RoundPointValue((float)bottomRight.X) - RoundPointValue((float)topLeft.X), RoundPointValue((float)bottomRight.Y) - RoundPointValue((float)topLeft.Y));
}
}
bool _disposed;

View File

@@ -285,6 +285,30 @@ namespace Facebook.Yoga
root_child1.Width = 50;
root_child1.Height = 50;
root.Insert(1, root_child1);
YogaNode root_child2 = new YogaNode(config);
root_child2.PositionType = YogaPositionType.Absolute;
root_child2.Left = 0;
root_child2.Top = 0;
root_child2.MarginLeft = 10;
root_child2.MarginTop = 10;
root_child2.MarginRight = 10;
root_child2.MarginBottom = 10;
root_child2.Width = 50;
root_child2.Height = 50;
root.Insert(2, root_child2);
YogaNode root_child3 = new YogaNode(config);
root_child3.PositionType = YogaPositionType.Absolute;
root_child3.Right = 0;
root_child3.Bottom = 0;
root_child3.MarginLeft = 10;
root_child3.MarginTop = 10;
root_child3.MarginRight = 10;
root_child3.MarginBottom = 10;
root_child3.Width = 50;
root_child3.Height = 50;
root.Insert(3, root_child3);
root.StyleDirection = YogaDirection.LTR;
root.CalculateLayout();
@@ -303,6 +327,16 @@ namespace Facebook.Yoga
Assert.AreEqual(50f, root_child1.LayoutWidth);
Assert.AreEqual(50f, root_child1.LayoutHeight);
Assert.AreEqual(20f, root_child2.LayoutX);
Assert.AreEqual(20f, root_child2.LayoutY);
Assert.AreEqual(50f, root_child2.LayoutWidth);
Assert.AreEqual(50f, root_child2.LayoutHeight);
Assert.AreEqual(30f, root_child3.LayoutX);
Assert.AreEqual(30f, root_child3.LayoutY);
Assert.AreEqual(50f, root_child3.LayoutWidth);
Assert.AreEqual(50f, root_child3.LayoutHeight);
root.StyleDirection = YogaDirection.RTL;
root.CalculateLayout();
@@ -320,6 +354,16 @@ namespace Facebook.Yoga
Assert.AreEqual(40f, root_child1.LayoutY);
Assert.AreEqual(50f, root_child1.LayoutWidth);
Assert.AreEqual(50f, root_child1.LayoutHeight);
Assert.AreEqual(20f, root_child2.LayoutX);
Assert.AreEqual(20f, root_child2.LayoutY);
Assert.AreEqual(50f, root_child2.LayoutWidth);
Assert.AreEqual(50f, root_child2.LayoutHeight);
Assert.AreEqual(30f, root_child3.LayoutX);
Assert.AreEqual(30f, root_child3.LayoutY);
Assert.AreEqual(50f, root_child3.LayoutWidth);
Assert.AreEqual(50f, root_child3.LayoutHeight);
}
[Test]
@@ -745,5 +789,253 @@ namespace Facebook.Yoga
Assert.AreEqual(52f, root.LayoutHeight);
}
[Test]
public void Test_absolute_layout_percentage_bottom_based_on_parent_height()
{
YogaConfig config = new YogaConfig();
YogaNode root = new YogaNode(config);
root.Width = 100;
root.Height = 200;
YogaNode root_child0 = new YogaNode(config);
root_child0.PositionType = YogaPositionType.Absolute;
root_child0.Top = 50.Percent();
root_child0.Width = 10;
root_child0.Height = 10;
root.Insert(0, root_child0);
YogaNode root_child1 = new YogaNode(config);
root_child1.PositionType = YogaPositionType.Absolute;
root_child1.Bottom = 50.Percent();
root_child1.Width = 10;
root_child1.Height = 10;
root.Insert(1, root_child1);
YogaNode root_child2 = new YogaNode(config);
root_child2.PositionType = YogaPositionType.Absolute;
root_child2.Top = 10.Percent();
root_child2.Bottom = 10.Percent();
root_child2.Width = 10;
root.Insert(2, root_child2);
root.StyleDirection = YogaDirection.LTR;
root.CalculateLayout();
Assert.AreEqual(0f, root.LayoutX);
Assert.AreEqual(0f, root.LayoutY);
Assert.AreEqual(100f, root.LayoutWidth);
Assert.AreEqual(200f, root.LayoutHeight);
Assert.AreEqual(0f, root_child0.LayoutX);
Assert.AreEqual(100f, root_child0.LayoutY);
Assert.AreEqual(10f, root_child0.LayoutWidth);
Assert.AreEqual(10f, root_child0.LayoutHeight);
Assert.AreEqual(0f, root_child1.LayoutX);
Assert.AreEqual(90f, root_child1.LayoutY);
Assert.AreEqual(10f, root_child1.LayoutWidth);
Assert.AreEqual(10f, root_child1.LayoutHeight);
Assert.AreEqual(0f, root_child2.LayoutX);
Assert.AreEqual(20f, root_child2.LayoutY);
Assert.AreEqual(10f, root_child2.LayoutWidth);
Assert.AreEqual(160f, root_child2.LayoutHeight);
root.StyleDirection = YogaDirection.RTL;
root.CalculateLayout();
Assert.AreEqual(0f, root.LayoutX);
Assert.AreEqual(0f, root.LayoutY);
Assert.AreEqual(100f, root.LayoutWidth);
Assert.AreEqual(200f, root.LayoutHeight);
Assert.AreEqual(90f, root_child0.LayoutX);
Assert.AreEqual(100f, root_child0.LayoutY);
Assert.AreEqual(10f, root_child0.LayoutWidth);
Assert.AreEqual(10f, root_child0.LayoutHeight);
Assert.AreEqual(90f, root_child1.LayoutX);
Assert.AreEqual(90f, root_child1.LayoutY);
Assert.AreEqual(10f, root_child1.LayoutWidth);
Assert.AreEqual(10f, root_child1.LayoutHeight);
Assert.AreEqual(90f, root_child2.LayoutX);
Assert.AreEqual(20f, root_child2.LayoutY);
Assert.AreEqual(10f, root_child2.LayoutWidth);
Assert.AreEqual(160f, root_child2.LayoutHeight);
}
[Test]
public void Test_absolute_layout_in_wrap_reverse_column_container()
{
YogaConfig config = new YogaConfig();
YogaNode root = new YogaNode(config);
root.Wrap = YogaWrap.WrapReverse;
root.Width = 100;
root.Height = 100;
YogaNode root_child0 = new YogaNode(config);
root_child0.PositionType = YogaPositionType.Absolute;
root_child0.Width = 20;
root_child0.Height = 20;
root.Insert(0, root_child0);
root.StyleDirection = YogaDirection.LTR;
root.CalculateLayout();
Assert.AreEqual(0f, root.LayoutX);
Assert.AreEqual(0f, root.LayoutY);
Assert.AreEqual(100f, root.LayoutWidth);
Assert.AreEqual(100f, root.LayoutHeight);
Assert.AreEqual(80f, root_child0.LayoutX);
Assert.AreEqual(0f, root_child0.LayoutY);
Assert.AreEqual(20f, root_child0.LayoutWidth);
Assert.AreEqual(20f, root_child0.LayoutHeight);
root.StyleDirection = YogaDirection.RTL;
root.CalculateLayout();
Assert.AreEqual(0f, root.LayoutX);
Assert.AreEqual(0f, root.LayoutY);
Assert.AreEqual(100f, root.LayoutWidth);
Assert.AreEqual(100f, root.LayoutHeight);
Assert.AreEqual(0f, root_child0.LayoutX);
Assert.AreEqual(0f, root_child0.LayoutY);
Assert.AreEqual(20f, root_child0.LayoutWidth);
Assert.AreEqual(20f, root_child0.LayoutHeight);
}
[Test]
public void Test_absolute_layout_in_wrap_reverse_row_container()
{
YogaConfig config = new YogaConfig();
YogaNode root = new YogaNode(config);
root.FlexDirection = YogaFlexDirection.Row;
root.Wrap = YogaWrap.WrapReverse;
root.Width = 100;
root.Height = 100;
YogaNode root_child0 = new YogaNode(config);
root_child0.PositionType = YogaPositionType.Absolute;
root_child0.Width = 20;
root_child0.Height = 20;
root.Insert(0, root_child0);
root.StyleDirection = YogaDirection.LTR;
root.CalculateLayout();
Assert.AreEqual(0f, root.LayoutX);
Assert.AreEqual(0f, root.LayoutY);
Assert.AreEqual(100f, root.LayoutWidth);
Assert.AreEqual(100f, root.LayoutHeight);
Assert.AreEqual(0f, root_child0.LayoutX);
Assert.AreEqual(80f, root_child0.LayoutY);
Assert.AreEqual(20f, root_child0.LayoutWidth);
Assert.AreEqual(20f, root_child0.LayoutHeight);
root.StyleDirection = YogaDirection.RTL;
root.CalculateLayout();
Assert.AreEqual(0f, root.LayoutX);
Assert.AreEqual(0f, root.LayoutY);
Assert.AreEqual(100f, root.LayoutWidth);
Assert.AreEqual(100f, root.LayoutHeight);
Assert.AreEqual(80f, root_child0.LayoutX);
Assert.AreEqual(80f, root_child0.LayoutY);
Assert.AreEqual(20f, root_child0.LayoutWidth);
Assert.AreEqual(20f, root_child0.LayoutHeight);
}
[Test]
public void Test_absolute_layout_in_wrap_reverse_column_container_flex_end()
{
YogaConfig config = new YogaConfig();
YogaNode root = new YogaNode(config);
root.Wrap = YogaWrap.WrapReverse;
root.Width = 100;
root.Height = 100;
YogaNode root_child0 = new YogaNode(config);
root_child0.AlignSelf = YogaAlign.FlexEnd;
root_child0.PositionType = YogaPositionType.Absolute;
root_child0.Width = 20;
root_child0.Height = 20;
root.Insert(0, root_child0);
root.StyleDirection = YogaDirection.LTR;
root.CalculateLayout();
Assert.AreEqual(0f, root.LayoutX);
Assert.AreEqual(0f, root.LayoutY);
Assert.AreEqual(100f, root.LayoutWidth);
Assert.AreEqual(100f, root.LayoutHeight);
Assert.AreEqual(0f, root_child0.LayoutX);
Assert.AreEqual(0f, root_child0.LayoutY);
Assert.AreEqual(20f, root_child0.LayoutWidth);
Assert.AreEqual(20f, root_child0.LayoutHeight);
root.StyleDirection = YogaDirection.RTL;
root.CalculateLayout();
Assert.AreEqual(0f, root.LayoutX);
Assert.AreEqual(0f, root.LayoutY);
Assert.AreEqual(100f, root.LayoutWidth);
Assert.AreEqual(100f, root.LayoutHeight);
Assert.AreEqual(80f, root_child0.LayoutX);
Assert.AreEqual(0f, root_child0.LayoutY);
Assert.AreEqual(20f, root_child0.LayoutWidth);
Assert.AreEqual(20f, root_child0.LayoutHeight);
}
[Test]
public void Test_absolute_layout_in_wrap_reverse_row_container_flex_end()
{
YogaConfig config = new YogaConfig();
YogaNode root = new YogaNode(config);
root.FlexDirection = YogaFlexDirection.Row;
root.Wrap = YogaWrap.WrapReverse;
root.Width = 100;
root.Height = 100;
YogaNode root_child0 = new YogaNode(config);
root_child0.AlignSelf = YogaAlign.FlexEnd;
root_child0.PositionType = YogaPositionType.Absolute;
root_child0.Width = 20;
root_child0.Height = 20;
root.Insert(0, root_child0);
root.StyleDirection = YogaDirection.LTR;
root.CalculateLayout();
Assert.AreEqual(0f, root.LayoutX);
Assert.AreEqual(0f, root.LayoutY);
Assert.AreEqual(100f, root.LayoutWidth);
Assert.AreEqual(100f, root.LayoutHeight);
Assert.AreEqual(0f, root_child0.LayoutX);
Assert.AreEqual(0f, root_child0.LayoutY);
Assert.AreEqual(20f, root_child0.LayoutWidth);
Assert.AreEqual(20f, root_child0.LayoutHeight);
root.StyleDirection = YogaDirection.RTL;
root.CalculateLayout();
Assert.AreEqual(0f, root.LayoutX);
Assert.AreEqual(0f, root.LayoutY);
Assert.AreEqual(100f, root.LayoutWidth);
Assert.AreEqual(100f, root.LayoutHeight);
Assert.AreEqual(80f, root_child0.LayoutX);
Assert.AreEqual(0f, root_child0.LayoutY);
Assert.AreEqual(20f, root_child0.LayoutWidth);
Assert.AreEqual(20f, root_child0.LayoutHeight);
}
}
}

View File

@@ -1815,5 +1815,148 @@ namespace Facebook.Yoga
Assert.AreEqual(72f, root_child0_child0.LayoutHeight);
}
[Test]
public void Test_align_center_should_size_based_on_content()
{
YogaConfig config = new YogaConfig();
YogaNode root = new YogaNode(config);
root.AlignItems = YogaAlign.Center;
root.MarginTop = 20;
root.Width = 100;
root.Height = 100;
YogaNode root_child0 = new YogaNode(config);
root_child0.JustifyContent = YogaJustify.Center;
root_child0.FlexShrink = 1;
root.Insert(0, root_child0);
YogaNode root_child0_child0 = new YogaNode(config);
root_child0_child0.FlexGrow = 1;
root_child0_child0.FlexShrink = 1;
root_child0.Insert(0, root_child0_child0);
YogaNode root_child0_child0_child0 = new YogaNode(config);
root_child0_child0_child0.Width = 20;
root_child0_child0_child0.Height = 20;
root_child0_child0.Insert(0, root_child0_child0_child0);
root.StyleDirection = YogaDirection.LTR;
root.CalculateLayout();
Assert.AreEqual(0f, root.LayoutX);
Assert.AreEqual(20f, root.LayoutY);
Assert.AreEqual(100f, root.LayoutWidth);
Assert.AreEqual(100f, root.LayoutHeight);
Assert.AreEqual(40f, root_child0.LayoutX);
Assert.AreEqual(0f, root_child0.LayoutY);
Assert.AreEqual(20f, root_child0.LayoutWidth);
Assert.AreEqual(20f, root_child0.LayoutHeight);
Assert.AreEqual(0f, root_child0_child0.LayoutX);
Assert.AreEqual(0f, root_child0_child0.LayoutY);
Assert.AreEqual(20f, root_child0_child0.LayoutWidth);
Assert.AreEqual(20f, root_child0_child0.LayoutHeight);
Assert.AreEqual(0f, root_child0_child0_child0.LayoutX);
Assert.AreEqual(0f, root_child0_child0_child0.LayoutY);
Assert.AreEqual(20f, root_child0_child0_child0.LayoutWidth);
Assert.AreEqual(20f, root_child0_child0_child0.LayoutHeight);
root.StyleDirection = YogaDirection.RTL;
root.CalculateLayout();
Assert.AreEqual(0f, root.LayoutX);
Assert.AreEqual(20f, root.LayoutY);
Assert.AreEqual(100f, root.LayoutWidth);
Assert.AreEqual(100f, root.LayoutHeight);
Assert.AreEqual(40f, root_child0.LayoutX);
Assert.AreEqual(0f, root_child0.LayoutY);
Assert.AreEqual(20f, root_child0.LayoutWidth);
Assert.AreEqual(20f, root_child0.LayoutHeight);
Assert.AreEqual(0f, root_child0_child0.LayoutX);
Assert.AreEqual(0f, root_child0_child0.LayoutY);
Assert.AreEqual(20f, root_child0_child0.LayoutWidth);
Assert.AreEqual(20f, root_child0_child0.LayoutHeight);
Assert.AreEqual(0f, root_child0_child0_child0.LayoutX);
Assert.AreEqual(0f, root_child0_child0_child0.LayoutY);
Assert.AreEqual(20f, root_child0_child0_child0.LayoutWidth);
Assert.AreEqual(20f, root_child0_child0_child0.LayoutHeight);
}
[Test]
public void Test_align_strech_should_size_based_on_parent()
{
YogaConfig config = new YogaConfig();
YogaNode root = new YogaNode(config);
root.MarginTop = 20;
root.Width = 100;
root.Height = 100;
YogaNode root_child0 = new YogaNode(config);
root_child0.JustifyContent = YogaJustify.Center;
root_child0.FlexShrink = 1;
root.Insert(0, root_child0);
YogaNode root_child0_child0 = new YogaNode(config);
root_child0_child0.FlexGrow = 1;
root_child0_child0.FlexShrink = 1;
root_child0.Insert(0, root_child0_child0);
YogaNode root_child0_child0_child0 = new YogaNode(config);
root_child0_child0_child0.Width = 20;
root_child0_child0_child0.Height = 20;
root_child0_child0.Insert(0, root_child0_child0_child0);
root.StyleDirection = YogaDirection.LTR;
root.CalculateLayout();
Assert.AreEqual(0f, root.LayoutX);
Assert.AreEqual(20f, root.LayoutY);
Assert.AreEqual(100f, root.LayoutWidth);
Assert.AreEqual(100f, root.LayoutHeight);
Assert.AreEqual(0f, root_child0.LayoutX);
Assert.AreEqual(0f, root_child0.LayoutY);
Assert.AreEqual(100f, root_child0.LayoutWidth);
Assert.AreEqual(20f, root_child0.LayoutHeight);
Assert.AreEqual(0f, root_child0_child0.LayoutX);
Assert.AreEqual(0f, root_child0_child0.LayoutY);
Assert.AreEqual(100f, root_child0_child0.LayoutWidth);
Assert.AreEqual(20f, root_child0_child0.LayoutHeight);
Assert.AreEqual(0f, root_child0_child0_child0.LayoutX);
Assert.AreEqual(0f, root_child0_child0_child0.LayoutY);
Assert.AreEqual(20f, root_child0_child0_child0.LayoutWidth);
Assert.AreEqual(20f, root_child0_child0_child0.LayoutHeight);
root.StyleDirection = YogaDirection.RTL;
root.CalculateLayout();
Assert.AreEqual(0f, root.LayoutX);
Assert.AreEqual(20f, root.LayoutY);
Assert.AreEqual(100f, root.LayoutWidth);
Assert.AreEqual(100f, root.LayoutHeight);
Assert.AreEqual(0f, root_child0.LayoutX);
Assert.AreEqual(0f, root_child0.LayoutY);
Assert.AreEqual(100f, root_child0.LayoutWidth);
Assert.AreEqual(20f, root_child0.LayoutHeight);
Assert.AreEqual(0f, root_child0_child0.LayoutX);
Assert.AreEqual(0f, root_child0_child0.LayoutY);
Assert.AreEqual(100f, root_child0_child0.LayoutWidth);
Assert.AreEqual(20f, root_child0_child0.LayoutHeight);
Assert.AreEqual(80f, root_child0_child0_child0.LayoutX);
Assert.AreEqual(0f, root_child0_child0_child0.LayoutY);
Assert.AreEqual(20f, root_child0_child0_child0.LayoutWidth);
Assert.AreEqual(20f, root_child0_child0_child0.LayoutHeight);
}
}
}

View File

@@ -429,5 +429,73 @@ namespace Facebook.Yoga
Assert.AreEqual(0f, root_child0_child0.LayoutHeight);
}
[Test]
public void Test_flex_grow_less_than_factor_one()
{
YogaConfig config = new YogaConfig();
YogaNode root = new YogaNode(config);
root.Width = 200;
root.Height = 500;
YogaNode root_child0 = new YogaNode(config);
root_child0.FlexGrow = 0.2f;
root_child0.FlexBasis = 40;
root.Insert(0, root_child0);
YogaNode root_child1 = new YogaNode(config);
root_child1.FlexGrow = 0.2f;
root.Insert(1, root_child1);
YogaNode root_child2 = new YogaNode(config);
root_child2.FlexGrow = 0.4f;
root.Insert(2, root_child2);
root.StyleDirection = YogaDirection.LTR;
root.CalculateLayout();
Assert.AreEqual(0f, root.LayoutX);
Assert.AreEqual(0f, root.LayoutY);
Assert.AreEqual(200f, root.LayoutWidth);
Assert.AreEqual(500f, root.LayoutHeight);
Assert.AreEqual(0f, root_child0.LayoutX);
Assert.AreEqual(0f, root_child0.LayoutY);
Assert.AreEqual(200f, root_child0.LayoutWidth);
Assert.AreEqual(132f, root_child0.LayoutHeight);
Assert.AreEqual(0f, root_child1.LayoutX);
Assert.AreEqual(132f, root_child1.LayoutY);
Assert.AreEqual(200f, root_child1.LayoutWidth);
Assert.AreEqual(92f, root_child1.LayoutHeight);
Assert.AreEqual(0f, root_child2.LayoutX);
Assert.AreEqual(224f, root_child2.LayoutY);
Assert.AreEqual(200f, root_child2.LayoutWidth);
Assert.AreEqual(184f, root_child2.LayoutHeight);
root.StyleDirection = YogaDirection.RTL;
root.CalculateLayout();
Assert.AreEqual(0f, root.LayoutX);
Assert.AreEqual(0f, root.LayoutY);
Assert.AreEqual(200f, root.LayoutWidth);
Assert.AreEqual(500f, root.LayoutHeight);
Assert.AreEqual(0f, root_child0.LayoutX);
Assert.AreEqual(0f, root_child0.LayoutY);
Assert.AreEqual(200f, root_child0.LayoutWidth);
Assert.AreEqual(132f, root_child0.LayoutHeight);
Assert.AreEqual(0f, root_child1.LayoutX);
Assert.AreEqual(132f, root_child1.LayoutY);
Assert.AreEqual(200f, root_child1.LayoutWidth);
Assert.AreEqual(92f, root_child1.LayoutHeight);
Assert.AreEqual(0f, root_child2.LayoutX);
Assert.AreEqual(224f, root_child2.LayoutY);
Assert.AreEqual(200f, root_child2.LayoutWidth);
Assert.AreEqual(184f, root_child2.LayoutHeight);
}
}
}

View File

@@ -1381,5 +1381,365 @@ namespace Facebook.Yoga
Assert.AreEqual(80f, root_child0_child1.LayoutHeight);
}
[Test]
public void Test_wrapped_column_max_height()
{
YogaConfig config = new YogaConfig();
YogaNode root = new YogaNode(config);
root.JustifyContent = YogaJustify.Center;
root.AlignContent = YogaAlign.Center;
root.AlignItems = YogaAlign.Center;
root.Wrap = YogaWrap.Wrap;
root.Width = 700;
root.Height = 500;
YogaNode root_child0 = new YogaNode(config);
root_child0.Width = 100;
root_child0.Height = 500;
root_child0.MaxHeight = 200;
root.Insert(0, root_child0);
YogaNode root_child1 = new YogaNode(config);
root_child1.MarginLeft = 20;
root_child1.MarginTop = 20;
root_child1.MarginRight = 20;
root_child1.MarginBottom = 20;
root_child1.Width = 200;
root_child1.Height = 200;
root.Insert(1, root_child1);
YogaNode root_child2 = new YogaNode(config);
root_child2.Width = 100;
root_child2.Height = 100;
root.Insert(2, root_child2);
root.StyleDirection = YogaDirection.LTR;
root.CalculateLayout();
Assert.AreEqual(0f, root.LayoutX);
Assert.AreEqual(0f, root.LayoutY);
Assert.AreEqual(700f, root.LayoutWidth);
Assert.AreEqual(500f, root.LayoutHeight);
Assert.AreEqual(250f, root_child0.LayoutX);
Assert.AreEqual(30f, root_child0.LayoutY);
Assert.AreEqual(100f, root_child0.LayoutWidth);
Assert.AreEqual(200f, root_child0.LayoutHeight);
Assert.AreEqual(200f, root_child1.LayoutX);
Assert.AreEqual(250f, root_child1.LayoutY);
Assert.AreEqual(200f, root_child1.LayoutWidth);
Assert.AreEqual(200f, root_child1.LayoutHeight);
Assert.AreEqual(420f, root_child2.LayoutX);
Assert.AreEqual(200f, root_child2.LayoutY);
Assert.AreEqual(100f, root_child2.LayoutWidth);
Assert.AreEqual(100f, root_child2.LayoutHeight);
root.StyleDirection = YogaDirection.RTL;
root.CalculateLayout();
Assert.AreEqual(0f, root.LayoutX);
Assert.AreEqual(0f, root.LayoutY);
Assert.AreEqual(700f, root.LayoutWidth);
Assert.AreEqual(500f, root.LayoutHeight);
Assert.AreEqual(350f, root_child0.LayoutX);
Assert.AreEqual(30f, root_child0.LayoutY);
Assert.AreEqual(100f, root_child0.LayoutWidth);
Assert.AreEqual(200f, root_child0.LayoutHeight);
Assert.AreEqual(300f, root_child1.LayoutX);
Assert.AreEqual(250f, root_child1.LayoutY);
Assert.AreEqual(200f, root_child1.LayoutWidth);
Assert.AreEqual(200f, root_child1.LayoutHeight);
Assert.AreEqual(180f, root_child2.LayoutX);
Assert.AreEqual(200f, root_child2.LayoutY);
Assert.AreEqual(100f, root_child2.LayoutWidth);
Assert.AreEqual(100f, root_child2.LayoutHeight);
}
[Test]
public void Test_wrapped_column_max_height_flex()
{
YogaConfig config = new YogaConfig();
YogaNode root = new YogaNode(config);
root.JustifyContent = YogaJustify.Center;
root.AlignContent = YogaAlign.Center;
root.AlignItems = YogaAlign.Center;
root.Wrap = YogaWrap.Wrap;
root.Width = 700;
root.Height = 500;
YogaNode root_child0 = new YogaNode(config);
root_child0.FlexGrow = 1;
root_child0.FlexShrink = 1;
root_child0.FlexBasis = 0.Percent();
root_child0.Width = 100;
root_child0.Height = 500;
root_child0.MaxHeight = 200;
root.Insert(0, root_child0);
YogaNode root_child1 = new YogaNode(config);
root_child1.FlexGrow = 1;
root_child1.FlexShrink = 1;
root_child1.FlexBasis = 0.Percent();
root_child1.MarginLeft = 20;
root_child1.MarginTop = 20;
root_child1.MarginRight = 20;
root_child1.MarginBottom = 20;
root_child1.Width = 200;
root_child1.Height = 200;
root.Insert(1, root_child1);
YogaNode root_child2 = new YogaNode(config);
root_child2.Width = 100;
root_child2.Height = 100;
root.Insert(2, root_child2);
root.StyleDirection = YogaDirection.LTR;
root.CalculateLayout();
Assert.AreEqual(0f, root.LayoutX);
Assert.AreEqual(0f, root.LayoutY);
Assert.AreEqual(700f, root.LayoutWidth);
Assert.AreEqual(500f, root.LayoutHeight);
Assert.AreEqual(300f, root_child0.LayoutX);
Assert.AreEqual(0f, root_child0.LayoutY);
Assert.AreEqual(100f, root_child0.LayoutWidth);
Assert.AreEqual(180f, root_child0.LayoutHeight);
Assert.AreEqual(250f, root_child1.LayoutX);
Assert.AreEqual(200f, root_child1.LayoutY);
Assert.AreEqual(200f, root_child1.LayoutWidth);
Assert.AreEqual(180f, root_child1.LayoutHeight);
Assert.AreEqual(300f, root_child2.LayoutX);
Assert.AreEqual(400f, root_child2.LayoutY);
Assert.AreEqual(100f, root_child2.LayoutWidth);
Assert.AreEqual(100f, root_child2.LayoutHeight);
root.StyleDirection = YogaDirection.RTL;
root.CalculateLayout();
Assert.AreEqual(0f, root.LayoutX);
Assert.AreEqual(0f, root.LayoutY);
Assert.AreEqual(700f, root.LayoutWidth);
Assert.AreEqual(500f, root.LayoutHeight);
Assert.AreEqual(300f, root_child0.LayoutX);
Assert.AreEqual(0f, root_child0.LayoutY);
Assert.AreEqual(100f, root_child0.LayoutWidth);
Assert.AreEqual(180f, root_child0.LayoutHeight);
Assert.AreEqual(250f, root_child1.LayoutX);
Assert.AreEqual(200f, root_child1.LayoutY);
Assert.AreEqual(200f, root_child1.LayoutWidth);
Assert.AreEqual(180f, root_child1.LayoutHeight);
Assert.AreEqual(300f, root_child2.LayoutX);
Assert.AreEqual(400f, root_child2.LayoutY);
Assert.AreEqual(100f, root_child2.LayoutWidth);
Assert.AreEqual(100f, root_child2.LayoutHeight);
}
[Test]
public void Test_wrap_nodes_with_content_sizing_overflowing_margin()
{
YogaConfig config = new YogaConfig();
YogaNode root = new YogaNode(config);
root.Width = 500;
root.Height = 500;
YogaNode root_child0 = new YogaNode(config);
root_child0.FlexDirection = YogaFlexDirection.Row;
root_child0.Wrap = YogaWrap.Wrap;
root_child0.Width = 85;
root.Insert(0, root_child0);
YogaNode root_child0_child0 = new YogaNode(config);
root_child0.Insert(0, root_child0_child0);
YogaNode root_child0_child0_child0 = new YogaNode(config);
root_child0_child0_child0.Width = 40;
root_child0_child0_child0.Height = 40;
root_child0_child0.Insert(0, root_child0_child0_child0);
YogaNode root_child0_child1 = new YogaNode(config);
root_child0_child1.MarginRight = 10;
root_child0.Insert(1, root_child0_child1);
YogaNode root_child0_child1_child0 = new YogaNode(config);
root_child0_child1_child0.Width = 40;
root_child0_child1_child0.Height = 40;
root_child0_child1.Insert(0, root_child0_child1_child0);
root.StyleDirection = YogaDirection.LTR;
root.CalculateLayout();
Assert.AreEqual(0f, root.LayoutX);
Assert.AreEqual(0f, root.LayoutY);
Assert.AreEqual(500f, root.LayoutWidth);
Assert.AreEqual(500f, root.LayoutHeight);
Assert.AreEqual(0f, root_child0.LayoutX);
Assert.AreEqual(0f, root_child0.LayoutY);
Assert.AreEqual(85f, root_child0.LayoutWidth);
Assert.AreEqual(80f, root_child0.LayoutHeight);
Assert.AreEqual(0f, root_child0_child0.LayoutX);
Assert.AreEqual(0f, root_child0_child0.LayoutY);
Assert.AreEqual(40f, root_child0_child0.LayoutWidth);
Assert.AreEqual(40f, root_child0_child0.LayoutHeight);
Assert.AreEqual(0f, root_child0_child0_child0.LayoutX);
Assert.AreEqual(0f, root_child0_child0_child0.LayoutY);
Assert.AreEqual(40f, root_child0_child0_child0.LayoutWidth);
Assert.AreEqual(40f, root_child0_child0_child0.LayoutHeight);
Assert.AreEqual(0f, root_child0_child1.LayoutX);
Assert.AreEqual(40f, root_child0_child1.LayoutY);
Assert.AreEqual(40f, root_child0_child1.LayoutWidth);
Assert.AreEqual(40f, root_child0_child1.LayoutHeight);
Assert.AreEqual(0f, root_child0_child1_child0.LayoutX);
Assert.AreEqual(0f, root_child0_child1_child0.LayoutY);
Assert.AreEqual(40f, root_child0_child1_child0.LayoutWidth);
Assert.AreEqual(40f, root_child0_child1_child0.LayoutHeight);
root.StyleDirection = YogaDirection.RTL;
root.CalculateLayout();
Assert.AreEqual(0f, root.LayoutX);
Assert.AreEqual(0f, root.LayoutY);
Assert.AreEqual(500f, root.LayoutWidth);
Assert.AreEqual(500f, root.LayoutHeight);
Assert.AreEqual(415f, root_child0.LayoutX);
Assert.AreEqual(0f, root_child0.LayoutY);
Assert.AreEqual(85f, root_child0.LayoutWidth);
Assert.AreEqual(80f, root_child0.LayoutHeight);
Assert.AreEqual(45f, root_child0_child0.LayoutX);
Assert.AreEqual(0f, root_child0_child0.LayoutY);
Assert.AreEqual(40f, root_child0_child0.LayoutWidth);
Assert.AreEqual(40f, root_child0_child0.LayoutHeight);
Assert.AreEqual(0f, root_child0_child0_child0.LayoutX);
Assert.AreEqual(0f, root_child0_child0_child0.LayoutY);
Assert.AreEqual(40f, root_child0_child0_child0.LayoutWidth);
Assert.AreEqual(40f, root_child0_child0_child0.LayoutHeight);
Assert.AreEqual(35f, root_child0_child1.LayoutX);
Assert.AreEqual(40f, root_child0_child1.LayoutY);
Assert.AreEqual(40f, root_child0_child1.LayoutWidth);
Assert.AreEqual(40f, root_child0_child1.LayoutHeight);
Assert.AreEqual(0f, root_child0_child1_child0.LayoutX);
Assert.AreEqual(0f, root_child0_child1_child0.LayoutY);
Assert.AreEqual(40f, root_child0_child1_child0.LayoutWidth);
Assert.AreEqual(40f, root_child0_child1_child0.LayoutHeight);
}
[Test]
public void Test_wrap_nodes_with_content_sizing_margin_cross()
{
YogaConfig config = new YogaConfig();
YogaNode root = new YogaNode(config);
root.Width = 500;
root.Height = 500;
YogaNode root_child0 = new YogaNode(config);
root_child0.FlexDirection = YogaFlexDirection.Row;
root_child0.Wrap = YogaWrap.Wrap;
root_child0.Width = 70;
root.Insert(0, root_child0);
YogaNode root_child0_child0 = new YogaNode(config);
root_child0.Insert(0, root_child0_child0);
YogaNode root_child0_child0_child0 = new YogaNode(config);
root_child0_child0_child0.Width = 40;
root_child0_child0_child0.Height = 40;
root_child0_child0.Insert(0, root_child0_child0_child0);
YogaNode root_child0_child1 = new YogaNode(config);
root_child0_child1.MarginTop = 10;
root_child0.Insert(1, root_child0_child1);
YogaNode root_child0_child1_child0 = new YogaNode(config);
root_child0_child1_child0.Width = 40;
root_child0_child1_child0.Height = 40;
root_child0_child1.Insert(0, root_child0_child1_child0);
root.StyleDirection = YogaDirection.LTR;
root.CalculateLayout();
Assert.AreEqual(0f, root.LayoutX);
Assert.AreEqual(0f, root.LayoutY);
Assert.AreEqual(500f, root.LayoutWidth);
Assert.AreEqual(500f, root.LayoutHeight);
Assert.AreEqual(0f, root_child0.LayoutX);
Assert.AreEqual(0f, root_child0.LayoutY);
Assert.AreEqual(70f, root_child0.LayoutWidth);
Assert.AreEqual(90f, root_child0.LayoutHeight);
Assert.AreEqual(0f, root_child0_child0.LayoutX);
Assert.AreEqual(0f, root_child0_child0.LayoutY);
Assert.AreEqual(40f, root_child0_child0.LayoutWidth);
Assert.AreEqual(40f, root_child0_child0.LayoutHeight);
Assert.AreEqual(0f, root_child0_child0_child0.LayoutX);
Assert.AreEqual(0f, root_child0_child0_child0.LayoutY);
Assert.AreEqual(40f, root_child0_child0_child0.LayoutWidth);
Assert.AreEqual(40f, root_child0_child0_child0.LayoutHeight);
Assert.AreEqual(0f, root_child0_child1.LayoutX);
Assert.AreEqual(50f, root_child0_child1.LayoutY);
Assert.AreEqual(40f, root_child0_child1.LayoutWidth);
Assert.AreEqual(40f, root_child0_child1.LayoutHeight);
Assert.AreEqual(0f, root_child0_child1_child0.LayoutX);
Assert.AreEqual(0f, root_child0_child1_child0.LayoutY);
Assert.AreEqual(40f, root_child0_child1_child0.LayoutWidth);
Assert.AreEqual(40f, root_child0_child1_child0.LayoutHeight);
root.StyleDirection = YogaDirection.RTL;
root.CalculateLayout();
Assert.AreEqual(0f, root.LayoutX);
Assert.AreEqual(0f, root.LayoutY);
Assert.AreEqual(500f, root.LayoutWidth);
Assert.AreEqual(500f, root.LayoutHeight);
Assert.AreEqual(430f, root_child0.LayoutX);
Assert.AreEqual(0f, root_child0.LayoutY);
Assert.AreEqual(70f, root_child0.LayoutWidth);
Assert.AreEqual(90f, root_child0.LayoutHeight);
Assert.AreEqual(30f, root_child0_child0.LayoutX);
Assert.AreEqual(0f, root_child0_child0.LayoutY);
Assert.AreEqual(40f, root_child0_child0.LayoutWidth);
Assert.AreEqual(40f, root_child0_child0.LayoutHeight);
Assert.AreEqual(0f, root_child0_child0_child0.LayoutX);
Assert.AreEqual(0f, root_child0_child0_child0.LayoutY);
Assert.AreEqual(40f, root_child0_child0_child0.LayoutWidth);
Assert.AreEqual(40f, root_child0_child0_child0.LayoutHeight);
Assert.AreEqual(30f, root_child0_child1.LayoutX);
Assert.AreEqual(50f, root_child0_child1.LayoutY);
Assert.AreEqual(40f, root_child0_child1.LayoutWidth);
Assert.AreEqual(40f, root_child0_child1.LayoutHeight);
Assert.AreEqual(0f, root_child0_child1_child0.LayoutX);
Assert.AreEqual(0f, root_child0_child1_child0.LayoutY);
Assert.AreEqual(40f, root_child0_child1_child0.LayoutWidth);
Assert.AreEqual(40f, root_child0_child1_child0.LayoutHeight);
}
}
}

View File

@@ -366,7 +366,6 @@ namespace Facebook.Yoga
public void Test_flex_grow_to_min()
{
YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.MinFlexFix, true);
YogaNode root = new YogaNode(config);
root.Width = 100;
@@ -422,7 +421,6 @@ namespace Facebook.Yoga
public void Test_flex_grow_in_at_most_container()
{
YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.MinFlexFix, true);
YogaNode root = new YogaNode(config);
root.FlexDirection = YogaFlexDirection.Row;
@@ -678,6 +676,203 @@ namespace Facebook.Yoga
Assert.AreEqual(20f, root_child0_child0.LayoutHeight);
}
[Test]
public void Test_flex_root_ignored()
{
YogaConfig config = new YogaConfig();
YogaNode root = new YogaNode(config);
root.FlexGrow = 1;
root.Width = 100;
root.MinHeight = 100;
root.MaxHeight = 500;
YogaNode root_child0 = new YogaNode(config);
root_child0.FlexGrow = 1;
root_child0.FlexBasis = 200;
root.Insert(0, root_child0);
YogaNode root_child1 = new YogaNode(config);
root_child1.Height = 100;
root.Insert(1, root_child1);
root.StyleDirection = YogaDirection.LTR;
root.CalculateLayout();
Assert.AreEqual(0f, root.LayoutX);
Assert.AreEqual(0f, root.LayoutY);
Assert.AreEqual(100f, root.LayoutWidth);
Assert.AreEqual(300f, root.LayoutHeight);
Assert.AreEqual(0f, root_child0.LayoutX);
Assert.AreEqual(0f, root_child0.LayoutY);
Assert.AreEqual(100f, root_child0.LayoutWidth);
Assert.AreEqual(200f, root_child0.LayoutHeight);
Assert.AreEqual(0f, root_child1.LayoutX);
Assert.AreEqual(200f, root_child1.LayoutY);
Assert.AreEqual(100f, root_child1.LayoutWidth);
Assert.AreEqual(100f, root_child1.LayoutHeight);
root.StyleDirection = YogaDirection.RTL;
root.CalculateLayout();
Assert.AreEqual(0f, root.LayoutX);
Assert.AreEqual(0f, root.LayoutY);
Assert.AreEqual(100f, root.LayoutWidth);
Assert.AreEqual(300f, root.LayoutHeight);
Assert.AreEqual(0f, root_child0.LayoutX);
Assert.AreEqual(0f, root_child0.LayoutY);
Assert.AreEqual(100f, root_child0.LayoutWidth);
Assert.AreEqual(200f, root_child0.LayoutHeight);
Assert.AreEqual(0f, root_child1.LayoutX);
Assert.AreEqual(200f, root_child1.LayoutY);
Assert.AreEqual(100f, root_child1.LayoutWidth);
Assert.AreEqual(100f, root_child1.LayoutHeight);
}
[Test]
public void Test_flex_grow_root_minimized()
{
YogaConfig config = new YogaConfig();
YogaNode root = new YogaNode(config);
root.Width = 100;
root.MinHeight = 100;
root.MaxHeight = 500;
YogaNode root_child0 = new YogaNode(config);
root_child0.FlexGrow = 1;
root_child0.MinHeight = 100;
root_child0.MaxHeight = 500;
root.Insert(0, root_child0);
YogaNode root_child0_child0 = new YogaNode(config);
root_child0_child0.FlexGrow = 1;
root_child0_child0.FlexBasis = 200;
root_child0.Insert(0, root_child0_child0);
YogaNode root_child0_child1 = new YogaNode(config);
root_child0_child1.Height = 100;
root_child0.Insert(1, root_child0_child1);
root.StyleDirection = YogaDirection.LTR;
root.CalculateLayout();
Assert.AreEqual(0f, root.LayoutX);
Assert.AreEqual(0f, root.LayoutY);
Assert.AreEqual(100f, root.LayoutWidth);
Assert.AreEqual(300f, root.LayoutHeight);
Assert.AreEqual(0f, root_child0.LayoutX);
Assert.AreEqual(0f, root_child0.LayoutY);
Assert.AreEqual(100f, root_child0.LayoutWidth);
Assert.AreEqual(300f, root_child0.LayoutHeight);
Assert.AreEqual(0f, root_child0_child0.LayoutX);
Assert.AreEqual(0f, root_child0_child0.LayoutY);
Assert.AreEqual(100f, root_child0_child0.LayoutWidth);
Assert.AreEqual(200f, root_child0_child0.LayoutHeight);
Assert.AreEqual(0f, root_child0_child1.LayoutX);
Assert.AreEqual(200f, root_child0_child1.LayoutY);
Assert.AreEqual(100f, root_child0_child1.LayoutWidth);
Assert.AreEqual(100f, root_child0_child1.LayoutHeight);
root.StyleDirection = YogaDirection.RTL;
root.CalculateLayout();
Assert.AreEqual(0f, root.LayoutX);
Assert.AreEqual(0f, root.LayoutY);
Assert.AreEqual(100f, root.LayoutWidth);
Assert.AreEqual(300f, root.LayoutHeight);
Assert.AreEqual(0f, root_child0.LayoutX);
Assert.AreEqual(0f, root_child0.LayoutY);
Assert.AreEqual(100f, root_child0.LayoutWidth);
Assert.AreEqual(300f, root_child0.LayoutHeight);
Assert.AreEqual(0f, root_child0_child0.LayoutX);
Assert.AreEqual(0f, root_child0_child0.LayoutY);
Assert.AreEqual(100f, root_child0_child0.LayoutWidth);
Assert.AreEqual(200f, root_child0_child0.LayoutHeight);
Assert.AreEqual(0f, root_child0_child1.LayoutX);
Assert.AreEqual(200f, root_child0_child1.LayoutY);
Assert.AreEqual(100f, root_child0_child1.LayoutWidth);
Assert.AreEqual(100f, root_child0_child1.LayoutHeight);
}
[Test]
public void Test_flex_grow_height_maximized()
{
YogaConfig config = new YogaConfig();
YogaNode root = new YogaNode(config);
root.Width = 100;
root.Height = 500;
YogaNode root_child0 = new YogaNode(config);
root_child0.FlexGrow = 1;
root_child0.MinHeight = 100;
root_child0.MaxHeight = 500;
root.Insert(0, root_child0);
YogaNode root_child0_child0 = new YogaNode(config);
root_child0_child0.FlexGrow = 1;
root_child0_child0.FlexBasis = 200;
root_child0.Insert(0, root_child0_child0);
YogaNode root_child0_child1 = new YogaNode(config);
root_child0_child1.Height = 100;
root_child0.Insert(1, root_child0_child1);
root.StyleDirection = YogaDirection.LTR;
root.CalculateLayout();
Assert.AreEqual(0f, root.LayoutX);
Assert.AreEqual(0f, root.LayoutY);
Assert.AreEqual(100f, root.LayoutWidth);
Assert.AreEqual(500f, root.LayoutHeight);
Assert.AreEqual(0f, root_child0.LayoutX);
Assert.AreEqual(0f, root_child0.LayoutY);
Assert.AreEqual(100f, root_child0.LayoutWidth);
Assert.AreEqual(500f, root_child0.LayoutHeight);
Assert.AreEqual(0f, root_child0_child0.LayoutX);
Assert.AreEqual(0f, root_child0_child0.LayoutY);
Assert.AreEqual(100f, root_child0_child0.LayoutWidth);
Assert.AreEqual(400f, root_child0_child0.LayoutHeight);
Assert.AreEqual(0f, root_child0_child1.LayoutX);
Assert.AreEqual(400f, root_child0_child1.LayoutY);
Assert.AreEqual(100f, root_child0_child1.LayoutWidth);
Assert.AreEqual(100f, root_child0_child1.LayoutHeight);
root.StyleDirection = YogaDirection.RTL;
root.CalculateLayout();
Assert.AreEqual(0f, root.LayoutX);
Assert.AreEqual(0f, root.LayoutY);
Assert.AreEqual(100f, root.LayoutWidth);
Assert.AreEqual(500f, root.LayoutHeight);
Assert.AreEqual(0f, root_child0.LayoutX);
Assert.AreEqual(0f, root_child0.LayoutY);
Assert.AreEqual(100f, root_child0.LayoutWidth);
Assert.AreEqual(500f, root_child0.LayoutHeight);
Assert.AreEqual(0f, root_child0_child0.LayoutX);
Assert.AreEqual(0f, root_child0_child0.LayoutY);
Assert.AreEqual(100f, root_child0_child0.LayoutWidth);
Assert.AreEqual(400f, root_child0_child0.LayoutHeight);
Assert.AreEqual(0f, root_child0_child1.LayoutX);
Assert.AreEqual(400f, root_child0_child1.LayoutY);
Assert.AreEqual(100f, root_child0_child1.LayoutWidth);
Assert.AreEqual(100f, root_child0_child1.LayoutHeight);
}
[Test]
public void Test_flex_grow_within_constrained_min_row()
{
@@ -907,6 +1102,64 @@ namespace Facebook.Yoga
Assert.AreEqual(50f, root_child1.LayoutHeight);
}
[Test]
public void Test_child_min_max_width_flexing()
{
YogaConfig config = new YogaConfig();
YogaNode root = new YogaNode(config);
root.FlexDirection = YogaFlexDirection.Row;
root.Width = 120;
root.Height = 50;
YogaNode root_child0 = new YogaNode(config);
root_child0.FlexGrow = 1;
root_child0.FlexBasis = 0;
root_child0.MinWidth = 60;
root.Insert(0, root_child0);
YogaNode root_child1 = new YogaNode(config);
root_child1.FlexGrow = 1;
root_child1.FlexBasis = 50.Percent();
root_child1.MaxWidth = 20;
root.Insert(1, root_child1);
root.StyleDirection = YogaDirection.LTR;
root.CalculateLayout();
Assert.AreEqual(0f, root.LayoutX);
Assert.AreEqual(0f, root.LayoutY);
Assert.AreEqual(120f, root.LayoutWidth);
Assert.AreEqual(50f, root.LayoutHeight);
Assert.AreEqual(0f, root_child0.LayoutX);
Assert.AreEqual(0f, root_child0.LayoutY);
Assert.AreEqual(100f, root_child0.LayoutWidth);
Assert.AreEqual(50f, root_child0.LayoutHeight);
Assert.AreEqual(100f, root_child1.LayoutX);
Assert.AreEqual(0f, root_child1.LayoutY);
Assert.AreEqual(20f, root_child1.LayoutWidth);
Assert.AreEqual(50f, root_child1.LayoutHeight);
root.StyleDirection = YogaDirection.RTL;
root.CalculateLayout();
Assert.AreEqual(0f, root.LayoutX);
Assert.AreEqual(0f, root.LayoutY);
Assert.AreEqual(120f, root.LayoutWidth);
Assert.AreEqual(50f, root.LayoutHeight);
Assert.AreEqual(20f, root_child0.LayoutX);
Assert.AreEqual(0f, root_child0.LayoutY);
Assert.AreEqual(100f, root_child0.LayoutWidth);
Assert.AreEqual(50f, root_child0.LayoutHeight);
Assert.AreEqual(0f, root_child1.LayoutX);
Assert.AreEqual(0f, root_child1.LayoutY);
Assert.AreEqual(20f, root_child1.LayoutWidth);
Assert.AreEqual(50f, root_child1.LayoutHeight);
}
[Test]
public void Test_min_width_overrides_width()
{

View File

@@ -21,7 +21,6 @@ namespace Facebook.Yoga
public void Test_percentage_width_height()
{
YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.Rounding, true);
YogaNode root = new YogaNode(config);
root.FlexDirection = YogaFlexDirection.Row;
@@ -63,7 +62,6 @@ namespace Facebook.Yoga
public void Test_percentage_position_left_top()
{
YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.Rounding, true);
YogaNode root = new YogaNode(config);
root.FlexDirection = YogaFlexDirection.Row;
@@ -107,7 +105,6 @@ namespace Facebook.Yoga
public void Test_percentage_position_bottom_right()
{
YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.Rounding, true);
YogaNode root = new YogaNode(config);
root.FlexDirection = YogaFlexDirection.Row;
@@ -151,7 +148,6 @@ namespace Facebook.Yoga
public void Test_percentage_flex_basis()
{
YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.Rounding, true);
YogaNode root = new YogaNode(config);
root.FlexDirection = YogaFlexDirection.Row;
@@ -208,7 +204,6 @@ namespace Facebook.Yoga
public void Test_percentage_flex_basis_cross()
{
YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.Rounding, true);
YogaNode root = new YogaNode(config);
root.Width = 200;
@@ -264,7 +259,6 @@ namespace Facebook.Yoga
public void Test_percentage_flex_basis_cross_min_height()
{
YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.Rounding, true);
YogaNode root = new YogaNode(config);
root.Width = 200;
@@ -320,7 +314,6 @@ namespace Facebook.Yoga
public void Test_percentage_flex_basis_main_max_height()
{
YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.Rounding, true);
YogaNode root = new YogaNode(config);
root.FlexDirection = YogaFlexDirection.Row;
@@ -379,7 +372,6 @@ namespace Facebook.Yoga
public void Test_percentage_flex_basis_cross_max_height()
{
YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.Rounding, true);
YogaNode root = new YogaNode(config);
root.Width = 200;
@@ -437,7 +429,6 @@ namespace Facebook.Yoga
public void Test_percentage_flex_basis_main_max_width()
{
YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.Rounding, true);
YogaNode root = new YogaNode(config);
root.FlexDirection = YogaFlexDirection.Row;
@@ -496,7 +487,6 @@ namespace Facebook.Yoga
public void Test_percentage_flex_basis_cross_max_width()
{
YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.Rounding, true);
YogaNode root = new YogaNode(config);
root.Width = 200;
@@ -554,7 +544,6 @@ namespace Facebook.Yoga
public void Test_percentage_flex_basis_main_min_width()
{
YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.Rounding, true);
YogaNode root = new YogaNode(config);
root.FlexDirection = YogaFlexDirection.Row;
@@ -613,7 +602,6 @@ namespace Facebook.Yoga
public void Test_percentage_flex_basis_cross_min_width()
{
YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.Rounding, true);
YogaNode root = new YogaNode(config);
root.Width = 200;
@@ -671,7 +659,6 @@ namespace Facebook.Yoga
public void Test_percentage_multiple_nested_with_padding_margin_and_percentage_values()
{
YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.Rounding, true);
YogaNode root = new YogaNode(config);
root.Width = 200;
@@ -781,7 +768,6 @@ namespace Facebook.Yoga
public void Test_percentage_margin_should_calculate_based_only_on_width()
{
YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.Rounding, true);
YogaNode root = new YogaNode(config);
root.Width = 200;
@@ -840,7 +826,6 @@ namespace Facebook.Yoga
public void Test_percentage_padding_should_calculate_based_only_on_width()
{
YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.Rounding, true);
YogaNode root = new YogaNode(config);
root.Width = 200;
@@ -899,7 +884,6 @@ namespace Facebook.Yoga
public void Test_percentage_absolute_position()
{
YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.Rounding, true);
YogaNode root = new YogaNode(config);
root.Width = 200;
@@ -1063,7 +1047,6 @@ namespace Facebook.Yoga
public void Test_percentage_container_in_wrapping_container()
{
YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.MinFlexFix, true);
YogaNode root = new YogaNode(config);
root.JustifyContent = YogaJustify.Center;

View File

@@ -21,7 +21,6 @@ namespace Facebook.Yoga
public void Test_rounding_flex_basis_flex_grow_row_width_of_100()
{
YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.Rounding, true);
YogaNode root = new YogaNode(config);
root.FlexDirection = YogaFlexDirection.Row;
@@ -90,7 +89,6 @@ namespace Facebook.Yoga
public void Test_rounding_flex_basis_flex_grow_row_prime_number_width()
{
YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.Rounding, true);
YogaNode root = new YogaNode(config);
root.FlexDirection = YogaFlexDirection.Row;
@@ -187,7 +185,6 @@ namespace Facebook.Yoga
public void Test_rounding_flex_basis_flex_shrink_row()
{
YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.Rounding, true);
YogaNode root = new YogaNode(config);
root.FlexDirection = YogaFlexDirection.Row;
@@ -257,7 +254,6 @@ namespace Facebook.Yoga
public void Test_rounding_flex_basis_overrides_main_size()
{
YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.Rounding, true);
YogaNode root = new YogaNode(config);
root.Width = 100;
@@ -329,7 +325,6 @@ namespace Facebook.Yoga
public void Test_rounding_total_fractial()
{
YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.Rounding, true);
YogaNode root = new YogaNode(config);
root.Width = 87.4f;
@@ -401,7 +396,6 @@ namespace Facebook.Yoga
public void Test_rounding_total_fractial_nested()
{
YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.Rounding, true);
YogaNode root = new YogaNode(config);
root.Width = 87.4f;
@@ -507,7 +501,6 @@ namespace Facebook.Yoga
public void Test_rounding_fractial_input_1()
{
YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.Rounding, true);
YogaNode root = new YogaNode(config);
root.Width = 100;
@@ -579,7 +572,6 @@ namespace Facebook.Yoga
public void Test_rounding_fractial_input_2()
{
YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.Rounding, true);
YogaNode root = new YogaNode(config);
root.Width = 100;
@@ -651,7 +643,6 @@ namespace Facebook.Yoga
public void Test_rounding_fractial_input_3()
{
YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.Rounding, true);
YogaNode root = new YogaNode(config);
root.Top = 0.3f;
@@ -724,7 +715,6 @@ namespace Facebook.Yoga
public void Test_rounding_fractial_input_4()
{
YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.Rounding, true);
YogaNode root = new YogaNode(config);
root.Top = 0.7f;
@@ -797,7 +787,6 @@ namespace Facebook.Yoga
public void Test_rounding_inner_node_controversy_horizontal()
{
YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.Rounding, true);
YogaNode root = new YogaNode(config);
root.FlexDirection = YogaFlexDirection.Row;
@@ -883,7 +872,6 @@ namespace Facebook.Yoga
public void Test_rounding_inner_node_controversy_vertical()
{
YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.Rounding, true);
YogaNode root = new YogaNode(config);
root.Height = 320;
@@ -968,7 +956,6 @@ namespace Facebook.Yoga
public void Test_rounding_inner_node_controversy_combined()
{
YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.Rounding, true);
YogaNode root = new YogaNode(config);
root.FlexDirection = YogaFlexDirection.Row;

View File

@@ -69,6 +69,7 @@ namespace Facebook.Yoga
Assert.AreEqual(YogaFlexDirection.Row, node1.FlexDirection);
}
#if !UNITY_5_4_OR_NEWER
public static void ForceGC()
{
YogaNodeTest.ForceGC();
@@ -132,5 +133,6 @@ namespace Facebook.Yoga
return node;
}
#endif
}
}

View File

@@ -164,6 +164,14 @@ namespace Facebook.Yoga
return MeasureOutput.Make(123.4f, 81.7f);
});
node.CalculateLayout();
Assert.AreEqual(124.0f, node.LayoutWidth);
Assert.AreEqual(82.0f, node.LayoutHeight);
node = new YogaNode(new YogaConfig{PointScaleFactor = 0});
node.SetMeasureFunction((_, width, widthMode, height, heightMode) => {
return MeasureOutput.Make(123.4f, 81.7f);
});
node.CalculateLayout();
Assert.AreEqual(123.4f, node.LayoutWidth);
Assert.AreEqual(81.7f, node.LayoutHeight);
}
@@ -240,6 +248,26 @@ namespace Facebook.Yoga
Assert.AreEqual(0, child2.LayoutY);
}
[Test]
public void TestPrintOneNode()
{
YogaNode node = new YogaNode();
node.Width = 100;
node.Height = 120;
node.CalculateLayout();
Assert.AreEqual("<div layout=\"width: 100; height: 120; top: 0; left: 0;\" style=\"width: 100px; height: 120px; \" ></div>", node.Print());
}
[Test]
public void TestPrintWithLogger()
{
YogaNode node = new YogaNode(new YogaConfig{Logger = (c, n, l, m) => {}});
node.Width = 110;
node.Height = 105;
node.CalculateLayout();
Assert.AreEqual("<div layout=\"width: 110; height: 105; top: 0; left: 0;\" style=\"width: 110px; height: 105px; \" ></div>", node.Print());
}
[Test]
public void TestPrint()
{
@@ -301,9 +329,10 @@ namespace Facebook.Yoga
Assert.AreEqual(90.Pt(), node4.MaxHeight);
}
#if !UNITY_5_4_OR_NEWER
public static void ForceGC()
{
GC.Collect(GC.MaxGeneration);
GC.Collect();
GC.WaitForPendingFinalizers();
}
@@ -430,6 +459,7 @@ namespace Facebook.Yoga
return MeasureOutput.Make(120, 130);
});
}
#endif
[Test]
public void TestLayoutMargin() {

View File

@@ -24,5 +24,5 @@ ROOT=`buck root|tail -1`
DYLIB=`buck targets --show-output $TARGET|tail -1|awk '{print $2}'`
cp $ROOT/$DYLIB .
mcs -debug -t:library -r:$NUNIT/nunit.framework.dll -out:YogaTest.dll *.cs ../../../csharp/Facebook.Yoga/*cs
mcs -debug -d:YOGA_ENABLE_GC_TEST -t:library -r:$NUNIT/nunit.framework.dll -out:YogaTest.dll *.cs ../../../csharp/Facebook.Yoga/*cs
MONO_PATH=$NUNIT mono --arch=64 --debug $NUNIT/nunit-console.exe YogaTest.dll

View File

@@ -140,6 +140,3 @@ PLATFORMS
DEPENDENCIES
github-pages (~> 104)
BUNDLED WITH
1.14.6

View File

@@ -8,7 +8,7 @@ permalink: /docs/api/android/
To include the java bindings and `.so` libraries, add to your build:
```java
compile 'com.facebook.yoga:yoga:1.2.0'
compile 'com.facebook.yoga:yoga:1.5.0'
```
There is an easy interface to Yoga called `YogaLayout`. This is a view group that lays out its children using Yoga. We recommend looking at the sample app for details on its usage. However, as an overview you can simply define XML layouts such as:
@@ -20,30 +20,30 @@ There is an easy interface to Yoga called `YogaLayout`. This is a view group th
xmlns:yoga="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
yoga:align_items="stretch"
yoga:yg_alignItems="stretch"
>
<YogaLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/sample_children_background"
yoga:margin_horizontal="10dp"
yoga:margin_top="5dp"
yoga:flex_direction="row"
yoga:align_items="center"
yoga:yg_marginHorizontal="10dp"
yoga:yg_marginTop="5dp"
yoga:yg_flexDirection="row"
yoga:yg_alignItems="center"
>
<ImageView
android:layout_width="50dp"
android:layout_height="50dp"
android:src="@drawable/ic_launcher"
yoga:flex="0"
yoga:yg_flex="0"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/child_1_text"
android:textColor="@color/children_text"
yoga:flex="1"
yoga:margin_start="8dp"
yoga:yg_flex="1"
yoga:yg_marginStart="8dp"
/>
</YogaLayout>
</YogaLayout>
@@ -54,12 +54,31 @@ Note that there are some caveats, such as requiring the custom `YogaLayoutViewFa
To include this in your project, add to your build:
```java
compile 'com.facebook.yoga.android:yoga-layout:1.2.0'
compile 'com.facebook.yoga.android:yoga-layout:1.5.0'
```
## Snapshot releases
> IMPORTANT: This will break and may set your house on fire. Snapshots are unsigned and automatically published by our CI system. Use them for testing purposes only.
If you want to live on the bleeding edge, you can use the SNAPSHOT releases
which represent the most recent commit on `master` by adding these targets to
your gradle config:
```gradle
repositories {
maven { url "https://oss.sonatype.org/content/repositories/snapshots/" }
}
dependencies {
compile 'com.facebook.yoga:yoga:1.5.1-SNAPSHOT'
compile 'com.facebook.yoga.android:yoga-layout:1.5.1-SNAPSHOT'
}
```
## layout\_width and layout\_height
If either are set to an actual size (in px or dp etc) then this is taken as a default for `yoga:height` or `yoga:width`. Otherwise they are ignored.
If either are set to an actual size (in px or dp etc) then this is taken as a default for `yoga:yg_height` or `yoga:ygWidth`. Otherwise they are ignored.
## VirtualYogaLayout
@@ -67,11 +86,11 @@ Sometimes you will nest `YogaLayout`s within `YogaLayout`s in order to get your
## RTL locales
RTL locales are supported by default. That is, unless you explicitly set the `yoga:direction="ltr|rtl|inherit"` attribute on a view, it will obtain the locale direction _at runtime_. This means that the layout will rearrange properly, even if the locale changes while your app is running!
RTL locales are supported by default. That is, unless you explicitly set the `yoga:yg_direction="ltr|rtl|inherit"` attribute on a view, it will obtain the locale direction At runtime_. This means that the layout will rearrange properly, even if the locale changes while your app is running!
## Attributes
The list of all attributes can be found in [attrs.xml](https://github.com/facebook/yoga/blob/master/android/sample/res/com/facebook/samples/yoga/res/values/attrs.xml), but logically map from the Yoga properties.
The list of all attributes can be found in [attrs.xml](https://github.com/facebook/yoga/blob/master/android/src/main/res/values/attrs.xml), but logically map from the Yoga properties.
## Auto margins

View File

@@ -28,7 +28,7 @@ The following functions help manage the children of a node.
void YGNodeInsertChild(YGNodeRef node, YGNodeRef child, uint32_t index);
void YGNodeRemoveChild(YGNodeRef node, YGNodeRef child);
YGNodeRef YGNodeGetChild(YGNodeRef node, uint32_t index);
uint32_t YGNodeChildCount(YGNodeRef node);
uint32_t YGNodeGetChildCount(YGNodeRef node);
```
### Style getters & setters

View File

@@ -8,36 +8,11 @@ permalink: /docs/api/csharp/
### Lifecycle
Create a `YogaNode` via its default constructor or the static `Create()` builder method and use `Reset` if you want to pool and re-use nodes. The native memory of a `YogaNode` will automatically be freed when the node is garbage collected.
Create a `YogaNode` via its default constructor and use `Reset` if you want to pool and re-use nodes. The native memory of a `YogaNode` will automatically be freed when the node is garbage collected.
```csharp
YogaNode();
void Reset();
static YogaNode Create(
YogaDirection? styleDirection = null,
YogaFlexDirection? flexDirection = null,
YogaJustify? justifyContent = null,
YogaAlign? alignContent = null,
YogaAlign? alignItems = null,
YogaAlign? alignSelf = null,
YogaPositionType? positionType = null,
YogaWrap? wrap = null,
YogaOverflow? overflow = null,
float? flex = null,
float? flexGrow = null,
float? flexShrink = null,
float? flexBasis = null,
Spacing position = null,
Spacing margin = null,
Spacing padding = null,
Spacing border = null,
float? Width = null,
float? Height = null,
float? MaxWidth = null,
float? MaxHeight = null,
float? MinWidth = null,
float? MinHeight = null);
```
### Children
@@ -95,6 +70,9 @@ enum YogaAlign
Center,
FlexEnd,
Stretch,
Baseline,
SpaceBetween,
SpaceAround
}
YogaAlign AlignItems {get, set};
@@ -113,6 +91,7 @@ enum YogaWrap
{
NoWrap,
Wrap,
WrapReverse
}
YogaWrap Wrap {get, set};
@@ -197,18 +176,13 @@ enum YogaMeasureMode
AtMost,
}
public delegate long MeasureFunction(
public delegate YogaSize MeasureFunction(
YogaNode node,
float width,
YogaMeasureMode widthMode,
float height,
YogaMeasureMode heightMode);
class MeasureOutput
{
public static long Make(int width, int height);
}
void SetMeasureFunction(MeasureFunction measureFunction);
bool IsMeasureDefined();

View File

@@ -9,6 +9,27 @@ The `yoga-layout` module offers two different implementations of Yoga. The first
> Because this module is compiled from a C++ codebase, the function prototypes below will use the C++-syntax. Nevertheless, the corresponding methods all exist on the JS side, with the same arguments (`Node *` being a node object).
### Installing
Installing through NPM
```sh
npm install yoga-layout
```
By default this will install the library and try to build for all platforms (node, browser asm, and standalone webpack). You may receive errors if you do not have the required platform development tools already installed. To preset the platform you'd like to build for you can set a .npmrc property first.
```sh
npm config set yoga-layout:platform standalone
```
This will now only run the standalone webpack build upon install.
### Build Platforms
| name | description |
|----------------|-------------------------------------------------|
| all (default) | Builds all of these platforms. |
| browser | Builds asm js browser version. |
| node | Builds node js version. |
| standalone | Runs webpack. |
| none | Does nothing. You can use the prepackaged libs. |
### Lifecycle
Create a node via `Yoga.Node.create()`, and destroy it by using its `free()` or `freeRecursive()` method. Note that unlike most objects in your Javascript applications, your nodes will not get automatically garbage collected, which means that it is especially important you keep track of them so you can free them when you no longer need them.
@@ -51,3 +72,63 @@ Certain nodes need to ability to measure themselves, the most common example is
Yoga has the concept of experiments. An experiment is a feature which is not yet stable. To enable a feature use the following functions. Once a feature has been tested and is ready to be released as a stable API we will remove its feature flag.
<script src="http://gist-it.appspot.com/facebook/yoga/raw/master/javascript/sources/global.hh?slice=3:4"></script>
### Example Usage
```javascript
import yoga, { Node } from 'yoga-layout';
let rootNode = Node.create();
rootNode.setWidth(1024);
rootNode.setHeight(768);
rootNode.setPadding(yoga.EDGE_ALL, 20);
rootNode.setDisplay(yoga.DISPLAY_FLEX);
rootNode.setFlexDirection(yoga.FLEX_DIRECTION_ROW);
let child1 = Node.create();
child1.setWidth(250);
child1.setHeight(400);
child1.setFlex(0);
let child2 = Node.create();
child2.setWidth(400);
child2.setHeight(500);
child2.setFlex(1);
rootNode.insertChild(child1, 0);
rootNode.insertChild(child2, 1);
rootNode.calculateLayout(1024, 768, yoga.DIRECTION_LTR);
console.log(`root pos: {${rootNode.getComputedLeft()}, ${rootNode.getComputedTop()}, ${rootNode.getComputedWidth()}, ${rootNode.getComputedHeight()}}`);
for (let i = 0, l = rootNode.getChildCount(); i < l; ++i) {
let child = rootNode.getChild(i);
console.log(`child ${i} pos: {${child.getComputedLeft()}, ${child.getComputedTop()}, ${child.getComputedWidth()}, ${child.getComputedHeight()}}`);
console.log(child.getComputedLayout().toString());
}
rootNode.removeChild(child1);
rootNode.removeChild(child2);
console.log(`There are ${yoga.getInstanceCount()} nodes`);
Node.destroy(child2);
console.log(`There are ${yoga.getInstanceCount()} nodes left`);
child1.free();
console.log(`There are ${yoga.getInstanceCount()} nodes left`);
rootNode.freeRecursive();
console.log(`There are ${yoga.getInstanceCount()} nodes left`);
---------------------------------
Output:
root pos: {0, 0, 1024, 768}
child 0 pos: {20, 20, 250, 400}
<Layout#20:0;20:0;250:400>
child 1 pos: {270, 20, 734, 500}
<Layout#270:0;20:0;734:500>
There are 3 nodes
There are 2 nodes left
There are 1 nodes left
There are 0 nodes left
```

View File

@@ -9,7 +9,7 @@ permalink: /docs/api/yogakit/
YogaKit is a Objective-C (and Swift-compatible) wrapper for Yoga. It allows iOS Developers to manage the layout of their views using the power of Yoga.
Layout configuration is done via the [YGLayout](https://github.com/facebook/yoga/blob/master/YogaKit/YGLayout.h) object. YogaKit exposes `YGLayout` via a [category](https://developer.apple.com/library/content/documentation/General/Conceptual/DevPedia-CocoaCore/Category.html) on [UIView](https://developer.apple.com/reference/uikit/uiview).
Layout configuration is done via the [YGLayout](https://github.com/facebook/yoga/blob/master/YogaKit/Source/YGLayout.h) object. YogaKit exposes `YGLayout` via a [category](https://developer.apple.com/library/content/documentation/General/Conceptual/DevPedia-CocoaCore/Category.html) on [UIView](https://developer.apple.com/reference/uikit/uiview).
### Lifecycle

View File

@@ -7,7 +7,7 @@ permalink: /docs/min-max-dimen/
Using `MinWidth`, `MinHeight`, `MaxWidth`, and `MaxHeight` gives you increased control over the final size of items in a layout. By mixing these properties with `FlexGrow`, `FlexShrink`, and `AlignItems = Stretch`, you are able to have items with dynamic size within a range which you control.
An example of when `Max` properties can be useful is if you are using `AlignItems = Stretch` but your know that your item won't look good after it increases past a certain point. In this case, your item will stretch to the size of its parent or until it is as big as specified in the `Max` property.
An example of when `Max` properties can be useful is if you are using `AlignItems = Stretch` but you know that your item won't look good after it increases past a certain point. In this case, your item will stretch to the size of its parent or until it is as big as specified in the `Max` property.
Same goes for the `Min` properties when using `FlexShrink`. For example, you may want children of a container to shrink to fit on one row, but if you specify a minimum width, they will break to the next line after a certain point (if you are using `FlexWrap = Wrap`).

View File

@@ -124,18 +124,20 @@ root.addChildAt(image, 1);
<div class="blockContent">
<div markdown="1" style="width: 700px; max-width: 100%;">
```csharp
YogaNode root = YogaNode.Create(
width: 500,
height: 300,
);
YogaNode root = new YogaNode {
Width = 500,
Height = 300
};
YogaNode image = YogaNode.Create(flexGrow: 1);
YogaNode image = new YogaNode {
FlexGrow = 1
};
YogaNode text = YogaNode.Create(
width: 300,
height: 25,
margin: new Spacing(left: 20, top: 20, right: 20, bottom: 20),
);
YogaNode text = new YogaNode {
Width = 300,
Height = 25,
Margin = 20
};
root.Insert(image, 0);
root.Insert(text, 1);
@@ -163,25 +165,25 @@ root.Insert(text, 1);
<YogaLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
yoga:justify_content="stretch">
yoga:yg_justifyContent="stretch">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
yoga:flex="1"/>
yoga:yg_flex="1"/>
<VirtualYogaLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
yoga:padding_all="20px"
yoga:flex_direction="row"
yoga:align_items="center">
yoga:yg_paddingAll="20px"
yoga:yg_flexDirection="row"
yoga:yg_alignItems="center">
<ImageView
android:layout_width="50dp"
android:layout_height="50dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
yoga:flex="1"
yoga:margin_start="20px"/>
yoga:yg_flex="1"
yoga:yg_marginStart="20px"/>
</VirtualYogaLayout>
</YogaLayout>
```

View File

@@ -84,18 +84,21 @@ ENUMS = {
'Vertical',
'All',
],
'NodeType': [
'Default',
'Text',
],
'LogLevel': [
'Error',
'Warn',
'Info',
'Debug',
'Verbose',
'Fatal',
],
'ExperimentalFeature': [
'Rounding',
# Mimic web flex-basis behavior.
'WebFlexBasis',
'MinFlexFix'
],
'PrintOptions': [
('Layout', 1),
@@ -145,7 +148,7 @@ with open(root + '/yoga/YGEnums.h', 'w') as f:
f.write('#include "YGMacros.h"\n\n')
f.write('YG_EXTERN_C_BEGIN\n\n')
for name, values in sorted(ENUMS.items()):
f.write('#define YG%sCount %s\n' % (name, len(values)))
f.write('#define YG%sCount %s\n' % (name, len(values)))
f.write('typedef YG_ENUM_BEGIN(YG%s) {\n' % name)
for value in values:
if isinstance(value, tuple):

View File

@@ -23,6 +23,8 @@
<div id="absolute_layout_within_border" style="height:100px; width:100px; border-width: 10px; margin: 10px; padding: 10px;">
<div style="position: absolute; width: 50px; height: 50px; left: 0px; top: 0px;"></div>
<div style="position: absolute; width: 50px; height: 50px; right: 0px; bottom: 0px;"></div>
<div style="position: absolute; width: 50px; height: 50px; left: 0px; top: 0px; margin: 10px;"></div>
<div style="position: absolute; width: 50px; height: 50px; right: 0px; bottom: 0px; margin: 10px;"></div>
</div>
<div id="absolute_layout_align_items_and_justify_content_center" style="height: 100px; width: 110px; flex-grow: 1; align-items: center; justify-content: center;">
@@ -63,3 +65,26 @@
<div id="position_root_with_rtl_should_position_withoutdirection" style="height: 52px; width: 52px; left: 72px; ">
</div>
<div id="absolute_layout_percentage_bottom_based_on_parent_height" style="width: 100px; height: 200px;">
<div style="position: absolute; top: 50%; width: 10px; height: 10px;"></div>
<div style="position: absolute; bottom: 50%; width: 10px; height: 10px;"></div>
<div style="position: absolute; top: 10%; width: 10px; bottom: 10%;"></div>
</div>
<div id="absolute_layout_in_wrap_reverse_column_container" style="flex-direction:column; width:100px; height:100px; flex-wrap: wrap-reverse;">
<div style="width:20px; height:20px; position: absolute;"></div>
</div>
<div id="absolute_layout_in_wrap_reverse_row_container" style="flex-direction:row; width:100px; height:100px; flex-wrap: wrap-reverse;">
<div style="width:20px; height:20px; position: absolute;"></div>
</div>
<div id="absolute_layout_in_wrap_reverse_column_container_flex_end" style="flex-direction:column; width:100px; height:100px; flex-wrap: wrap-reverse;">
<div style="width:20px; height:20px; position: absolute; align-self: flex-end;"></div>
</div>
<div id="absolute_layout_in_wrap_reverse_row_container_flex_end" style="flex-direction:row; width:100px; height:100px; flex-wrap: wrap-reverse;">
<div style="width:20px; height:20px; position: absolute; align-self: flex-end;"></div>
</div>

View File

@@ -167,3 +167,20 @@
<div style="width: 72px; height: 72px;"></div>
</div>
</div>
<div id="align_center_should_size_based_on_content" style="width: 100px; height: 100px; align-items: center; margin-top: 20px;">
<div style="flex-grow: 0; flex-shrink: 1; justify-content: center;">
<div style="flex-grow: 1; flex-shrink: 1;">
<div style="width: 20px; height: 20px;"></div>
</div>
</div>
</div>
<div id="align_strech_should_size_based_on_parent" style="width: 100px; height: 100px; align-items: strech; margin-top: 20px;">
<div style="flex-grow: 0; flex-shrink: 1; justify-content: center;">
<div style="flex-grow: 1; flex-shrink: 1;">
<div style="width: 20px; height: 20px;"></div>
</div>
</div>
</div>

View File

@@ -35,3 +35,9 @@
<div style="flex-grow:1; flex-shrink:1;"></div>
</div>
</div>
<div id="flex_grow_less_than_factor_one" style="height: 500px; width: 200px; flex-direction:column;">
<div style="flex-grow:0.2; flex-shrink:0; flex-basis: 40px;"></div>
<div style="flex-grow:0.2; flex-shrink:0;"></div>
<div style="flex-grow:0.4; flex-shrink:0;"></div>
</div>

View File

@@ -113,3 +113,37 @@
<div style="width: 80px; height: 80px;"></div>
</div>
</div>
<div id="wrapped_column_max_height" style="height: 500px; width: 700px; flex-direction: column;align-items: center; justify-content: center; align-content: center; flex-wrap:wrap;">
<div style="width: 100px; height: 500px; max-height: 200px;"></div>
<div style="width: 200px; height: 200px; margin: 20px;"></div>
<div style="width: 100px; height: 100px;"></div>
</div>
<div id="wrapped_column_max_height_flex" style="height: 500px; width: 700px; flex-direction: column;align-items: center; justify-content: center; align-content: center; flex-wrap:wrap;">
<div style="width: 100px; height: 500px; max-height: 200px; flex: 1;"></div>
<div style="width: 200px; height: 200px; margin: 20px; flex: 1"></div>
<div style="width: 100px; height: 100px;"></div>
</div>
<div id="wrap_nodes_with_content_sizing_overflowing_margin" style="width: 500px; height: 500px;">
<div style="flex-direction: row; flex-wrap: wrap; width: 85px;">
<div>
<div style="height: 40px; width: 40px;"></div>
</div>
<div style="margin-right: 10px;">
<div style="height: 40px; width: 40px;"></div>
</div>
</div>
</div>
<div id="wrap_nodes_with_content_sizing_margin_cross" style="width: 500px; height: 500px;">
<div style="flex-direction: row; flex-wrap: wrap; width: 70px;">
<div>
<div style="height: 40px; width: 40px;"></div>
</div>
<div style="margin-top: 10px;">
<div style="height: 40px; width: 40px;"></div>
</div>
</div>
</div>

View File

@@ -30,12 +30,12 @@
<div style="width: 50px; height: 50px;"></div>
</div>
<div id="flex_grow_to_min" experiments="MinFlexFix" style="min-height: 100px; max-height: 500px; width: 100px;">
<div id="flex_grow_to_min" style="min-height: 100px; max-height: 500px; width: 100px;">
<div style="flex-grow: 1; flex-shrink: 1;"></div>
<div style="height: 50px;"></div>
</div>
<div id="flex_grow_in_at_most_container" experiments="MinFlexFix" style="width: 100px; height: 100px; background-color: white; flex-direction: row; align-items: flex-start;">
<div id="flex_grow_in_at_most_container" style="width: 100px; height: 100px; background-color: white; flex-direction: row; align-items: flex-start;">
<div style="flex-direction: row;">
<div style="flex-grow: 1; flex-basis: 0px;"></div>
</div>
@@ -62,6 +62,25 @@
</div>
</div>
<div id="flex_root_ignored" style="width: 100px; min-height: 100px; max-height:500px;flex-grow:1">
<div style="flex-basis:200px; flex-grow:1;"></div>
<div style="height:100px; "></div>
</div>
<div id="flex_grow_root_minimized" style="width: 100px; min-height: 100px; max-height:500px">
<div style="min-height: 100px; max-height:500px;flex-grow:1">
<div style="flex-basis:200px; flex-grow:1;"></div>
<div style="height:100px; "></div>
</div>
</div>
<div id="flex_grow_height_maximized" style="width: 100px; height:500px">
<div style="min-height: 100px; max-height:500px;flex-grow:1">
<div style="flex-basis:200px; flex-grow:1;"></div>
<div style="height:100px; "></div>
</div>
</div>
<div id="flex_grow_within_constrained_min_row" style="min-width: 100px; height:100px; flex-direction: row;">
<div style="flex-grow:1;"></div>
<div style="width: 50px;"></div>
@@ -84,6 +103,11 @@
<div style="height: 50px;"></div>
</div>
<div id="child_min_max_width_flexing" style="width: 120px; height: 50px; flex-direction: row; align-items:stretch">
<div style="min-width: 60px; flex-grow:1; flex-shrink:0; flex-basis: 0px"></div>
<div style="max-width: 20px; flex-grow:1; flex-shrink:0; flex-basis: 50%"></div>
</div>
<div id="min_width_overrides_width" style="min-width: 100px; width: 50px;">
</div>

View File

@@ -1,61 +1,61 @@
<div id="percentage_width_height" experiments="Rounding" style="width: 200px; height: 200px; flex-direction: row;">
<div id="percentage_width_height" style="width: 200px; height: 200px; flex-direction: row;">
<div style="width: 30%; height: 30%;"></div>
</div>
<div id="percentage_position_left_top" experiments="Rounding" style="width: 400px; height: 400px; flex-direction: row;">
<div id="percentage_position_left_top" style="width: 400px; height: 400px; flex-direction: row;">
<div style="width: 45%; height: 55%; left: 10%; top: 20%"></div>
</div>
<div id="percentage_position_bottom_right" experiments="Rounding" style="width: 500px; height: 500px; flex-direction: row;">
<div id="percentage_position_bottom_right" style="width: 500px; height: 500px; flex-direction: row;">
<div style="width: 55%; height: 15%; bottom: 10%; right: 20%"></div>
</div>
<div id="percentage_flex_basis" experiments="Rounding" style="width: 200px; height: 200px; flex-direction: row;">
<div id="percentage_flex_basis" style="width: 200px; height: 200px; flex-direction: row;">
<div style="flex-grow: 1; flex-basis: 50%;"></div>
<div style="flex-grow: 1; flex-basis: 25%;"></div>
</div>
<div id="percentage_flex_basis_cross" experiments="Rounding" style="width: 200px; height: 200px; flex-direction: column;">
<div id="percentage_flex_basis_cross" style="width: 200px; height: 200px; flex-direction: column;">
<div style="flex-grow: 1; flex-basis: 50%;"></div>
<div style="flex-grow: 1; flex-basis: 25%;"></div>
</div>
<div id="percentage_flex_basis_cross_min_height" experiments="Rounding" style="width: 200px; height: 200px; flex-direction: column;">
<div id="percentage_flex_basis_cross_min_height" style="width: 200px; height: 200px; flex-direction: column;">
<div style="flex-grow: 1; min-height: 60%;"></div>
<div style="flex-grow: 2; min-height: 10%;"></div>
</div>
<div id="percentage_flex_basis_main_max_height" experiments="Rounding" style="width: 200px; height: 200px; flex-direction: row;">
<div id="percentage_flex_basis_main_max_height" style="width: 200px; height: 200px; flex-direction: row;">
<div style="flex-grow: 1; flex-basis: 10%; max-height: 60%;"></div>
<div style="flex-grow: 4; flex-basis: 10%; max-height: 20%;"></div>
</div>
<div id="percentage_flex_basis_cross_max_height" experiments="Rounding" style="width: 200px; height: 200px; flex-direction: column;">
<div id="percentage_flex_basis_cross_max_height" style="width: 200px; height: 200px; flex-direction: column;">
<div style="flex-grow: 1; flex-basis: 10%; max-height: 60%;"></div>
<div style="flex-grow: 4; flex-basis: 10%; max-height: 20%;"></div>
</div>
<div id="percentage_flex_basis_main_max_width" experiments="Rounding" style="width: 200px; height: 200px; flex-direction: row;">
<div id="percentage_flex_basis_main_max_width" style="width: 200px; height: 200px; flex-direction: row;">
<div style="flex-grow: 1; flex-basis: 15%; max-width: 60%;"></div>
<div style="flex-grow: 4; flex-basis: 10%; max-width: 20%;"></div>
</div>
<div id="percentage_flex_basis_cross_max_width" experiments="Rounding" style="width: 200px; height: 200px; flex-direction: column;">
<div id="percentage_flex_basis_cross_max_width" style="width: 200px; height: 200px; flex-direction: column;">
<div style="flex-grow: 1; flex-basis: 10%; max-width: 60%;"></div>
<div style="flex-grow: 4; flex-basis: 15%; max-width: 20%;"></div>
</div>
<div id="percentage_flex_basis_main_min_width" experiments="Rounding" style="width: 200px; height: 200px; flex-direction: row;">
<div id="percentage_flex_basis_main_min_width" style="width: 200px; height: 200px; flex-direction: row;">
<div style="flex-grow: 1; flex-basis: 15%; min-width: 60%;"></div>
<div style="flex-grow: 4; flex-basis: 10%; min-width: 20%;"></div>
</div>
<div id="percentage_flex_basis_cross_min_width" experiments="Rounding" style="width: 200px; height: 200px; flex-direction: column;">
<div id="percentage_flex_basis_cross_min_width" style="width: 200px; height: 200px; flex-direction: column;">
<div style="flex-grow: 1; flex-basis: 10%; min-width: 60%;"></div>
<div style="flex-grow: 4; flex-basis: 15%; min-width: 20%;"></div>
</div>
<div id="percentage_multiple_nested_with_padding_margin_and_percentage_values" experiments="Rounding" style="width: 200px; height: 200px; flex-direction: column;">
<div id="percentage_multiple_nested_with_padding_margin_and_percentage_values" style="width: 200px; height: 200px; flex-direction: column;">
<div style="flex-grow: 1; flex-basis: 10%; min-width: 60%; margin: 5px; padding: 3px;">
<div style="width: 50%; margin: 5px; padding: 3%;">
<div style="width: 45%; margin: 5%; padding: 3px;"></div>
@@ -64,19 +64,19 @@
<div style="flex-grow: 4; flex-basis: 15%; min-width: 20%;"></div>
</div>
<div id="percentage_margin_should_calculate_based_only_on_width" experiments="Rounding" style="width: 200px; height: 100px;">
<div id="percentage_margin_should_calculate_based_only_on_width" style="width: 200px; height: 100px;">
<div style="flex-grow: 1; margin: 10%;">
<div style="width: 10px; height: 10px;"></div>
</div>
</div>
<div id="percentage_padding_should_calculate_based_only_on_width" experiments="Rounding" style="width: 200px; height: 100px;">
<div id="percentage_padding_should_calculate_based_only_on_width" style="width: 200px; height: 100px;">
<div style="flex-grow: 1; padding: 10%;">
<div style="width: 10px; height: 10px;"></div>
</div>
</div>
<div id="percentage_absolute_position" experiments="Rounding" style="width: 200px; height: 100px;">
<div id="percentage_absolute_position" style="width: 200px; height: 100px;">
<div style="position: absolute; top: 10%; left: 30%; width: 10px; height: 10px;"></div>
</div>
@@ -92,7 +92,7 @@
<div style="width: 100px;"></div>
</div>
<div id="percentage_container_in_wrapping_container" experiments="MinFlexFix" style="align-items: center; width: 200px; height: 200px; justify-content: center;">
<div id="percentage_container_in_wrapping_container" style="align-items: center; width: 200px; height: 200px; justify-content: center;">
<div>
<div style="alignItems: center; flex-direction: row; justify-content: center; width: 100%;">
<div style="width: 50px; height: 50px;"></div>

View File

@@ -1,10 +1,10 @@
<div id="rounding_flex_basis_flex_grow_row_width_of_100" experiments="Rounding" style="width: 100px; height: 100px; flex-direction: row;">
<div id="rounding_flex_basis_flex_grow_row_width_of_100" style="width: 100px; height: 100px; flex-direction: row;">
<div style="flex-grow: 1;"></div>
<div style="flex-grow: 1;"></div>
<div style="flex-grow: 1;"></div>
</div>
<div id="rounding_flex_basis_flex_grow_row_prime_number_width" experiments="Rounding" style="width: 113px; height: 100px; flex-direction: row;">
<div id="rounding_flex_basis_flex_grow_row_prime_number_width" style="width: 113px; height: 100px; flex-direction: row;">
<div style="flex-grow: 1;"></div>
<div style="flex-grow: 1;"></div>
<div style="flex-grow: 1;"></div>
@@ -12,25 +12,25 @@
<div style="flex-grow: 1;"></div>
</div>
<div id="rounding_flex_basis_flex_shrink_row" experiments="Rounding" style="width: 101px; height: 100px; flex-direction: row;">
<div id="rounding_flex_basis_flex_shrink_row" style="width: 101px; height: 100px; flex-direction: row;">
<div style="flex-basis: 100px; flex-shrink: 1;"></div>
<div style="flex-basis: 25px;"></div>
<div style="flex-basis: 25px;"></div>
</div>
<div id="rounding_flex_basis_overrides_main_size" experiments="Rounding" style="height: 113px; width: 100px;">
<div id="rounding_flex_basis_overrides_main_size" style="height: 113px; width: 100px;">
<div style="height: 20px; flex-grow:1; flex-basis:50px;"></div>
<div style="height: 10px; flex-grow:1;"></div>
<div style="height: 10px; flex-grow:1;"></div>
</div>
<div id="rounding_total_fractial" experiments="Rounding" style="height: 113.4px; width: 87.4px;">
<div id="rounding_total_fractial" style="height: 113.4px; width: 87.4px;">
<div style="height: 20.3px; flex-grow:0.7; flex-basis:50.3px;"></div>
<div style="height: 10px; flex-grow:1.6;"></div>
<div style="height: 10.7px; flex-grow:1.1;"></div>
</div>
<div id="rounding_total_fractial_nested" experiments="Rounding" style="height: 113.4px; width: 87.4px;">
<div id="rounding_total_fractial_nested" style="height: 113.4px; width: 87.4px;">
<div style="height: 20.3px; flex-grow:0.7; flex-basis:50.3px;">
<div style="bottom: 13.3px; height: 9.9px; flex-grow:1; flex-basis:0.3px;"></div>
<div style="top: 13.3px; height: 1.1px; flex-grow:4; flex-basis:0.3px;"></div>
@@ -39,31 +39,31 @@
<div style="height: 10.7px; flex-grow:1.1;"></div>
</div>
<div id="rounding_fractial_input_1" experiments="Rounding" style="height: 113.4px; width: 100px;">
<div id="rounding_fractial_input_1" style="height: 113.4px; width: 100px;">
<div style="height: 20px; flex-grow:1; flex-basis:50px;"></div>
<div style="height: 10px; flex-grow:1;"></div>
<div style="height: 10px; flex-grow:1;"></div>
</div>
<div id="rounding_fractial_input_2" experiments="Rounding" style="height: 113.6px; width: 100px;">
<div id="rounding_fractial_input_2" style="height: 113.6px; width: 100px;">
<div style="height: 20px; flex-grow:1; flex-basis:50px;"></div>
<div style="height: 10px; flex-grow:1;"></div>
<div style="height: 10px; flex-grow:1;"></div>
</div>
<div id="rounding_fractial_input_3" experiments="Rounding" style="top: 0.3px; height: 113.4px; width: 100px;">
<div id="rounding_fractial_input_3" style="top: 0.3px; height: 113.4px; width: 100px;">
<div style="height: 20px; flex-grow:1; flex-basis:50px;"></div>
<div style="height: 10px; flex-grow:1;"></div>
<div style="height: 10px; flex-grow:1;"></div>
</div>
<div id="rounding_fractial_input_4" experiments="Rounding" style="top: 0.7px; height: 113.4px; width: 100px;">
<div id="rounding_fractial_input_4" style="top: 0.7px; height: 113.4px; width: 100px;">
<div style="height: 20px; flex-grow:1; flex-basis:50px;"></div>
<div style="height: 10px; flex-grow:1;"></div>
<div style="height: 10px; flex-grow:1;"></div>
</div>
<div id="rounding_inner_node_controversy_horizontal" experiments="Rounding" style="width: 320px; flex-direction: row;">
<div id="rounding_inner_node_controversy_horizontal" style="width: 320px; flex-direction: row;">
<div style="height: 10px; flex-grow:1;"></div>
<div style="height: 10px; flex-grow:1;">
<div style="height: 10px; flex-grow:1;">
@@ -72,7 +72,7 @@
<div style="height: 10px; flex-grow:1;"></div>
</div>
<div id="rounding_inner_node_controversy_vertical" experiments="Rounding" style="height: 320px;">
<div id="rounding_inner_node_controversy_vertical" style="height: 320px;">
<div style="width: 10px; flex-grow:1;"></div>
<div style="width: 10px; flex-grow:1;">
<div style="width: 10px; flex-grow:1;">
@@ -81,7 +81,7 @@
<div style="width: 10px; flex-grow:1;"></div>
</div>
<div id="rounding_inner_node_controversy_combined" experiments="Rounding" style="width: 640px; height: 320px; flex-direction: row;">
<div id="rounding_inner_node_controversy_combined" style="width: 640px; height: 320px; flex-direction: row;">
<div style="height: 100%; flex-grow:1;"></div>
<div style="height: 100%; flex-grow:1; flex-direction: column;">
<div style="width: 100%; flex-grow:1;"></div>

View File

@@ -431,11 +431,6 @@ function getRoundedSize(node) {
function calculateTree(root, roundToPixelGrid) {
var rootLayout = [];
// Any occurrence of "Rounding" mark during node tree traverse turns this feature on for whole subtree.
if ((root.getAttribute('experiments') || '').split(' ').indexOf('Rounding') != -1) {
roundToPixelGrid = true;
}
for (var i = 0; i < root.children.length; i++) {
var child = root.children[i];
var layout = {
@@ -453,11 +448,9 @@ function calculateTree(root, roundToPixelGrid) {
: [],
};
if (roundToPixelGrid) {
var size = getRoundedSize(child);
layout.width = size.width;
layout.height = size.height;
}
var size = getRoundedSize(child);
layout.width = size.width;
layout.height = size.height;
rootLayout.push(layout);
}

View File

@@ -1,4 +1,14 @@
bintrayUsername=
bintrayApiKey=
bintrayGpgPassword=
dryRun=false
# Project-wide Gradle settings.
org.gradle.jvmargs=-Xmx1536M
VERSION_NAME=1.7.0
POM_URL=https://github.com/facebook/yoga
POM_SCM_URL=https://github.com/facebook/yoga.git
POM_SCM_CONNECTION=scm:git:https://github.com/facebook/yoga.git
POM_SCM_DEV_CONNECTION=scm:git:git@github.com:facebook/yoga.git
POM_LICENSE_NAME=BSD License
POM_LICENSE_URL=https://github.com/facebook/yoga/blob/master/LICENSE
POM_LICENSE_DIST=repo
POM_DEVELOPER_ID=facebook
POM_DEVELOPER_NAME=facebook

View File

@@ -1,92 +0,0 @@
ext {
bintrayUserOrg = 'facebook'
bintrayRepo = 'maven'
siteURL = "https://facebook.github.io/yoga/"
projectLicenses = {
license {
name 'BSD License'
url 'https://github.com/facebook/yoga/blob/master/LICENSE'
distribution 'repo'
}
}
}
def getBintrayUsername() {
return property('bintrayUsername') || System.getenv('BINTRAY_USERNAME')
}
def getBintrayApiKey() {
return property('bintrayApiKey') || System.getenv('BINTRAY_API_KEY')
}
def getBintrayGpgPassword() {
return property('bintrayGpgPassword') || System.getenv('BINTRAY_GPG_PASSWORD')
}
def dryRunOnly() {
return hasProperty('dryRun') ? property('dryRun').toBoolean() : false
}
def pomConfig = {
licenses {
// TODO Can we grab this from above?
license {
name 'BSD License'
url 'https://github.com/facebook/yoga/blob/master/LICENSE'
distribution 'repo'
}
}
}
publishing {
publications {
primaryPublication(MavenPublication) {
groupId group
artifact(sourcesJar)
artifact(javadocJar)
pom.packaging='aar'
pom.withXml {
def root = asNode()
root.appendNode('name', 'Yoga')
root.appendNode('url', siteURL)
root.children().last() + pomConfig
def dependenciesNode = root.appendNode('dependencies')
//Iterate over the compile dependencies (we don't want the test ones), adding a <dependency> node for each
configurations.compile.allDependencies.each {
if(it.group != null && (it.name != null || "unspecified".equals(it.name)) && it.version != null) {
def dependencyNode = dependenciesNode.appendNode('dependency')
dependencyNode.appendNode('groupId', it.group)
dependencyNode.appendNode('artifactId', it.name)
dependencyNode.appendNode('version', it.version)
}
}
}
}
}
}
bintray {
user = getBintrayUsername()
key = getBintrayApiKey()
publications = ['primaryPublication']
configurations = ['archives']
pkg {
repo = bintrayRepo
userOrg = bintrayUserOrg
name = project.bintrayName
dryRun = dryRunOnly()
licenses = projectLicenses
override = true
publish = true
publicDownloadNumbers = true
version {
name = project.version
released = new Date()
gpg {
sign = true
passphrase = getBintrayGpgPassword()
}
}
}
}

View File

@@ -0,0 +1,37 @@
// Configure the Android maven publication
apply plugin: 'com.github.dcendents.android-maven'
version = VERSION_NAME
group = GROUP
// Set the .aar / .jar base file name to match the artifact ID
// in case the module has a different name
project.archivesBaseName = POM_ARTIFACT_ID
install {
repositories.mavenInstaller {
// This generates POM.xml with proper parameters
pom.project {
name POM_NAME
artifactId POM_ARTIFACT_ID
packaging POM_PACKAGING
description POM_DESCRIPTION
url projectUrl
scm {
url scmUrl
connection scmConnection
developerConnection scmDeveloperConnection
}
licenses projectLicenses
developers {
developer {
id developerId
name developerName
}
}
}
}
}

View File

@@ -0,0 +1,47 @@
// Android tasks for Javadoc and sources.jar generation
afterEvaluate { project ->
if (POM_PACKAGING == 'aar') {
task androidJavadoc(type: Javadoc) {
source = android.sourceSets.main.java.srcDirs
exclude '**/pom.xml'
exclude '**/proguard_annotations.pro'
classpath += files(android.bootClasspath)
}
task androidJavadocJar(type: Jar) {
classifier = 'javadoc'
from androidJavadoc.destinationDir
}
task androidSourcesJar(type: Jar) {
classifier = 'sources'
from android.sourceSets.main.java.srcDirs
}
android.libraryVariants.all { variant ->
def name = variant.name.capitalize()
task "jar${name}"(type: Jar, dependsOn: variant.javaCompile) {
from variant.javaCompile.destinationDir
}
}
artifacts.add('archives', androidJavadocJar)
artifacts.add('archives', androidSourcesJar)
}
if (POM_PACKAGING == 'jar') {
task javadocJar(type: Jar, dependsOn: javadoc) {
classifier = 'javadoc'
from javadoc.destinationDir
}
task sourcesJar(type: Jar, dependsOn: classes) {
classifier = 'sources'
from sourceSets.main.allSource
}
artifacts.add('archives', javadocJar)
artifacts.add('archives', sourcesJar)
}
}

63
gradle/bintray.gradle Normal file
View File

@@ -0,0 +1,63 @@
// Upload to Bintray
apply plugin: 'com.jfrog.bintray'
def getBintrayUsername() {
return project.hasProperty('bintrayUsername') ? property('bintrayUsername') : System.getenv('BINTRAY_USERNAME')
}
def getBintrayApiKey() {
return project.hasProperty('bintrayApiKey') ? property('bintrayApiKey') : System.getenv('BINTRAY_API_KEY')
}
def getBintrayGpgPassword() {
return project.hasProperty('bintrayGpgPassword') ? property('bintrayGpgPassword') : System.getenv('BINTRAY_GPG_PASSWORD')
}
def getMavenCentralUsername() {
return project.hasProperty('mavenCentralUsername') ? property('mavenCentralUsername') : System.getenv('MAVEN_CENTRAL_USERNAME')
}
def getMavenCentralPassword() {
return project.hasProperty('mavenCentralPassword') ? property('mavenCentralPassword') : System.getenv('MAVEN_CENTRAL_PASSWORD')
}
def shouldSyncWithMavenCentral() {
return project.hasProperty('syncWithMavenCentral') ? property('syncWithMavenCentral').toBoolean() : false
}
def dryRunOnly() {
return project.hasProperty('dryRun') ? property('dryRun').toBoolean() : false
}
bintray {
user = getBintrayUsername()
key = getBintrayApiKey()
configurations = ['archives']
pkg {
repo = bintrayRepo
userOrg = bintrayUserOrg
name = bintrayName
desc = bintrayDescription
websiteUrl = projectUrl
issueTrackerUrl = issuesUrl
vcsUrl = scmUrl
licenses = projectLicenses
dryRun = dryRunOnly()
override = true
publish = true
publicDownloadNumbers = true
version {
desc = bintrayDescription
gpg {
sign = true
passphrase = getBintrayGpgPassword()
}
mavenCentralSync {
sync = shouldSyncWithMavenCentral()
user = getMavenCentralUsername()
password = getMavenCentralPassword()
close = '1' // If set to 0, you have to manually click release
}
}
}
}

View File

@@ -0,0 +1,96 @@
/*
* Copyright 2013 Chris Banes
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
apply plugin: 'signing'
version = VERSION_NAME
group = GROUP
def isReleaseBuild() {
return VERSION_NAME.contains('SNAPSHOT') == false
}
def getReleaseRepositoryUrl() {
return hasProperty('RELEASE_REPOSITORY_URL') ? RELEASE_REPOSITORY_URL
: "https://oss.sonatype.org/service/local/staging/deploy/maven2/"
}
def getSnapshotRepositoryUrl() {
return hasProperty('SNAPSHOT_REPOSITORY_URL') ? SNAPSHOT_REPOSITORY_URL
: "https://oss.sonatype.org/content/repositories/snapshots/"
}
def getRepositoryUsername() {
return hasProperty('SONATYPE_NEXUS_USERNAME') ? SONATYPE_NEXUS_USERNAME : ""
}
def getRepositoryPassword() {
return hasProperty('SONATYPE_NEXUS_PASSWORD') ? SONATYPE_NEXUS_PASSWORD : ""
}
afterEvaluate { project ->
uploadArchives {
repositories {
mavenDeployer {
beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) }
pom.groupId = GROUP
pom.artifactId = POM_ARTIFACT_ID
pom.version = VERSION_NAME
repository(url: getReleaseRepositoryUrl()) {
authentication(userName: getRepositoryUsername(), password: getRepositoryPassword())
}
snapshotRepository(url: getSnapshotRepositoryUrl()) {
authentication(userName: getRepositoryUsername(), password: getRepositoryPassword())
}
pom.project {
name POM_NAME
packaging POM_PACKAGING
description POM_DESCRIPTION
url POM_URL
scm {
url POM_SCM_URL
connection POM_SCM_CONNECTION
developerConnection POM_SCM_DEV_CONNECTION
}
licenses {
license {
name POM_LICENSE_NAME
url POM_LICENSE_URL
distribution POM_LICENSE_DIST
}
}
developers {
developer {
id POM_DEVELOPER_ID
name POM_DEVELOPER_NAME
}
}
}
}
}
}
signing {
required { isReleaseBuild() && gradle.taskGraph.hasTask('uploadArchives') }
sign configurations.archives
}
}

View File

@@ -0,0 +1,33 @@
// Set up everything required for releasing on Bintray
ext {
bintrayRepo = 'maven'
bintrayUserOrg = 'facebook'
bintrayName = "${GROUP}:${POM_ARTIFACT_ID}"
bintrayDescription = POM_DESCRIPTION
projectUrl = POM_URL
issuesUrl = 'https://github.com/facebook/yoga/issues'
scmUrl = POM_SCM_URL
scmConnection = POM_SCM_CONNECTION
scmDeveloperConnection = POM_SCM_DEV_CONNECTION
publishedGroupId = GROUP
libraryName = 'yoga'
artifact = 'yoga'
developerId = POM_DEVELOPER_ID
developerName = POM_DEVELOPER_NAME
projectLicenses = {
license {
name = POM_LICENSE_NAME
url = POM_LICENSE_URL
distribution = POM_LICENSE_DIST
}
}
}
// Set up the Android Maven publication (POM etc.)
apply from: rootProject.file('gradle/android-maven-install.gradle')
// Upload to Bintray
apply from: rootProject.file('gradle/bintray.gradle')

8
gradle/release.gradle Normal file
View File

@@ -0,0 +1,8 @@
// Common Android tasks for all releases that generate Javadocs, sources, etc.
apply from: rootProject.file('gradle/android-tasks.gradle')
// Upload to Bintray
apply from: rootProject.file('gradle/release-bintray.gradle')
// Upload directly to standard Maven Central (for SNAPSHOTs)
apply from: rootProject.file('gradle/gradle-mvn-push.gradle')

View File

@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-3.5-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-4.2-bin.zip

View File

@@ -10,6 +10,7 @@ include_defs("//YOGA_DEFS")
cxx_library(
name = "jni",
srcs = glob(["jni/*.cpp"]),
header_namespace = "",
compiler_flags = [
"-fno-omit-frame-pointer",
"-fexceptions",
@@ -19,7 +20,6 @@ cxx_library(
"-O3",
"-std=c++11",
],
header_namespace = "",
soname = "libyoga.$(ext)",
visibility = ["PUBLIC"],
deps = [
@@ -32,6 +32,7 @@ cxx_library(
java_library(
name = "java",
srcs = glob(["com/facebook/yoga/*.java"]),
required_for_source_only_abi = True,
source = "1.7",
target = "1.7",
tests = [
@@ -58,3 +59,11 @@ java_test(
JUNIT_TARGET,
],
)
java_binary(
name = "yoga",
deps = [
":java",
FBJNI_JAVA_TARGET,
],
)

View File

@@ -3,8 +3,8 @@ apply plugin: 'com.android.library'
apply plugin: 'com.github.dcendents.android-maven'
apply plugin: 'maven-publish'
version = '1.4.2'
group = 'com.facebook.yoga'
group = GROUP
version = VERSION_NAME
android {
compileSdkVersion rootProject.compileSdkVersion
@@ -41,15 +41,19 @@ android {
java.srcDir 'com'
manifest.srcFile 'AndroidManifest.xml'
res.srcDirs = ['res']
jniLibs.srcDirs = ['build/buck-out/jniLibs']
}
test {
java.srcDirs 'tests'
}
}
}
dependencies {
compile 'com.google.code.findbugs:jsr305:3.0.1'
compile 'com.facebook.soloader:soloader:0.2.0'
provided project(':yoga:proguard-annotations')
compileOnly 'com.google.code.findbugs:jsr305:3.0.1'
compileOnly project(':yoga:proguard-annotations')
implementation 'com.facebook.soloader:soloader:0.2.0'
testImplementation 'junit:junit:4.12'
}
task sourcesJar(type: Jar) {
@@ -73,4 +77,4 @@ ext {
bintrayName = 'com.facebook.yoga:yoga'
}
apply from: rootProject.file('gradle/android-jcenter-install.gradle')
apply from: rootProject.file('gradle/release.gradle')

View File

@@ -1,4 +1,4 @@
/**
/*
* Copyright (c) 2014-present, Facebook, Inc.
* All rights reserved.
*

View File

@@ -1,4 +1,4 @@
/**
/*
* Copyright (c) 2014-present, Facebook, Inc.
* All rights reserved.
*

View File

@@ -1,4 +1,4 @@
/**
/*
* Copyright (c) 2014-present, Facebook, Inc.
* All rights reserved.
*
@@ -20,6 +20,7 @@ public class YogaConfig {
}
long mNativePointer;
private YogaLogger mLogger;
private native long jni_YGConfigNew();
public YogaConfig() {
@@ -51,4 +52,30 @@ public class YogaConfig {
public void setUseWebDefaults(boolean useWebDefaults) {
jni_YGConfigSetUseWebDefaults(mNativePointer, useWebDefaults);
}
private native void jni_YGConfigSetPointScaleFactor(long nativePointer, float pixelsInPoint);
public void setPointScaleFactor(float pixelsInPoint) {
jni_YGConfigSetPointScaleFactor(mNativePointer, pixelsInPoint);
}
private native void jni_YGConfigSetUseLegacyStretchBehaviour(long nativePointer, boolean useLegacyStretchBehaviour);
/**
* Yoga previously had an error where containers would take the maximum space possible instead of the minimum
* like they are supposed to. In practice this resulted in implicit behaviour similar to align-self: stretch;
* Because this was such a long-standing bug we must allow legacy users to switch back to this behaviour.
*/
public void setUseLegacyStretchBehaviour(boolean useLegacyStretchBehaviour) {
jni_YGConfigSetUseLegacyStretchBehaviour(mNativePointer, useLegacyStretchBehaviour);
}
private native void jni_YGConfigSetLogger(long nativePointer, Object logger);
public void setLogger(YogaLogger logger) {
mLogger = logger;
jni_YGConfigSetLogger(mNativePointer, logger);
}
public YogaLogger getLogger() {
return mLogger;
}
}

View File

@@ -1,4 +1,4 @@
/**
/*
* Copyright (c) 2014-present, Facebook, Inc.
* All rights reserved.
*

View File

@@ -1,4 +1,4 @@
/**
/*
* Copyright (c) 2014-present, Facebook, Inc.
* All rights reserved.
*

Some files were not shown because too many files have changed in this diff Show More