Compare commits

...

79 Commits
1.4.1 ... 1.5.2

Author SHA1 Message Date
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
167 changed files with 7624 additions and 1338 deletions

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,9 @@ os: osx
osx_image: xcode8.2 osx_image: xcode8.2
language: cpp language: cpp
compiler: clang compiler: clang
cache:
directories:
- $HOME/Library/Caches/Homebrew
env: env:
- TARGET=c - TARGET=c
@@ -19,9 +22,13 @@ env:
- TARGET=android - TARGET=android
before_install: 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 update > /dev/null
- brew tap facebook/fb - brew install --HEAD facebook/fb/buck
- brew install buck
# Java # Java
- | - |
@@ -53,8 +60,8 @@ before_install:
if [[ $TARGET = "js" ]]; then if [[ $TARGET = "js" ]]; then
wget -O /tmp/emsdk-portable.tar.gz https://s3.amazonaws.com/mozilla-games/emscripten/releases/emsdk-portable.tar.gz && 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/ && tar xf /tmp/emsdk-portable.tar.gz -C /tmp/ &&
/tmp/emsdk_portable/emsdk install latest >& /dev/null && /tmp/emsdk-portable/emsdk install latest 2>&1 | grep -v '^x ' &&
/tmp/emsdk_portable/emsdk activate latest /tmp/emsdk-portable/emsdk activate latest
fi fi
# Android # Android
@@ -63,12 +70,9 @@ before_install:
brew cask install java; brew cask install java;
export JAVA_HOME=$(/usr/libexec/java_home -v 1.8); export JAVA_HOME=$(/usr/libexec/java_home -v 1.8);
export PATH=$JAVA_HOME/bin:$PATH; export PATH=$JAVA_HOME/bin:$PATH;
brew install android-sdk; export TERMINAL=dumb;
export ANDROID_SDK=/usr/local/Cellar/android-sdk/24.4.1_1; source scripts/android-setup.sh && installAndroidSDK
export ANDROID_HOME=/usr/local/Cellar/android-sdk/24.4.1_1; export ANDROID_SDK=$ANDROID_HOME
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;
fi fi
# JavaScript # JavaScript
@@ -77,7 +81,7 @@ before_install:
cd javascript && cd javascript &&
npm install && npm install &&
unset CC && unset CXX && unset LINK && unset CC && unset CXX && unset LINK &&
source /tmp/emsdk_portable/emsdk_env.sh && source /tmp/emsdk-portable/emsdk_env.sh &&
npm run build:browser npm run build:browser
) fi ) fi
@@ -114,7 +118,9 @@ script:
# Android # Android
- | - |
if [[ $TARGET = "android" ]]; then 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 fi
# JavaScript # JavaScript

View File

@@ -38,3 +38,26 @@ For the main C implementation of Yoga clang-format is used to ensure a consisten
## Benchmarks ## 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. 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' GTEST_TARGET = '//lib/gtest:gtest'
JNI_TARGET = '//lib/jni:jni' JNI_TARGET = '//lib/jni:jni'
FBJNI_TARGET = '//lib/fb:fbjni' FBJNI_TARGET = '//lib/fb:fbjni'
FBJNI_JAVA_TARGET = '//lib/fb/src/main/java/com/facebook/jni:jni'
APPCOMPAT_TARGET = '//lib/appcompat:appcompat' APPCOMPAT_TARGET = '//lib/appcompat:appcompat'
ANDROID_SUPPORT_TARGET = '//lib/android-support:android-support' ANDROID_SUPPORT_TARGET = '//lib/android-support:android-support'
ANDROID_TARGET = '//android:android' ANDROID_TARGET = '//android:android'

View File

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

View File

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

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/). YogaKit is available to install via [CocoaPods](https://cocoapods.org/).
``` ```
pod 'YogaKit', '~> 1.3' pod 'YogaKit', '~> 1.5'
``` ```
## Getting Started ## Getting Started

View File

@@ -9,6 +9,17 @@
#import <UIKit/UIKit.h> #import <UIKit/UIKit.h>
#import <yoga/YGEnums.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) { typedef NS_OPTIONS(NSInteger, YGDimensionFlexibility) {
YGDimensionFlexibilityFlexibleWidth = 1 << 0, YGDimensionFlexibilityFlexibleWidth = 1 << 0,
@@ -41,34 +52,34 @@ typedef NS_OPTIONS(NSInteger, YGDimensionFlexibility) {
@property (nonatomic, readwrite, assign) CGFloat flexGrow; @property (nonatomic, readwrite, assign) CGFloat flexGrow;
@property (nonatomic, readwrite, assign) CGFloat flexShrink; @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) YGValue left;
@property (nonatomic, readwrite, assign) CGFloat top; @property (nonatomic, readwrite, assign) YGValue top;
@property (nonatomic, readwrite, assign) CGFloat right; @property (nonatomic, readwrite, assign) YGValue right;
@property (nonatomic, readwrite, assign) CGFloat bottom; @property (nonatomic, readwrite, assign) YGValue bottom;
@property (nonatomic, readwrite, assign) CGFloat start; @property (nonatomic, readwrite, assign) YGValue start;
@property (nonatomic, readwrite, assign) CGFloat end; @property (nonatomic, readwrite, assign) YGValue end;
@property (nonatomic, readwrite, assign) CGFloat marginLeft; @property (nonatomic, readwrite, assign) YGValue marginLeft;
@property (nonatomic, readwrite, assign) CGFloat marginTop; @property (nonatomic, readwrite, assign) YGValue marginTop;
@property (nonatomic, readwrite, assign) CGFloat marginRight; @property (nonatomic, readwrite, assign) YGValue marginRight;
@property (nonatomic, readwrite, assign) CGFloat marginBottom; @property (nonatomic, readwrite, assign) YGValue marginBottom;
@property (nonatomic, readwrite, assign) CGFloat marginStart; @property (nonatomic, readwrite, assign) YGValue marginStart;
@property (nonatomic, readwrite, assign) CGFloat marginEnd; @property (nonatomic, readwrite, assign) YGValue marginEnd;
@property (nonatomic, readwrite, assign) CGFloat marginHorizontal; @property (nonatomic, readwrite, assign) YGValue marginHorizontal;
@property (nonatomic, readwrite, assign) CGFloat marginVertical; @property (nonatomic, readwrite, assign) YGValue marginVertical;
@property (nonatomic, readwrite, assign) CGFloat margin; @property (nonatomic, readwrite, assign) YGValue margin;
@property (nonatomic, readwrite, assign) CGFloat paddingLeft; @property (nonatomic, readwrite, assign) YGValue paddingLeft;
@property (nonatomic, readwrite, assign) CGFloat paddingTop; @property (nonatomic, readwrite, assign) YGValue paddingTop;
@property (nonatomic, readwrite, assign) CGFloat paddingRight; @property (nonatomic, readwrite, assign) YGValue paddingRight;
@property (nonatomic, readwrite, assign) CGFloat paddingBottom; @property (nonatomic, readwrite, assign) YGValue paddingBottom;
@property (nonatomic, readwrite, assign) CGFloat paddingStart; @property (nonatomic, readwrite, assign) YGValue paddingStart;
@property (nonatomic, readwrite, assign) CGFloat paddingEnd; @property (nonatomic, readwrite, assign) YGValue paddingEnd;
@property (nonatomic, readwrite, assign) CGFloat paddingHorizontal; @property (nonatomic, readwrite, assign) YGValue paddingHorizontal;
@property (nonatomic, readwrite, assign) CGFloat paddingVertical; @property (nonatomic, readwrite, assign) YGValue paddingVertical;
@property (nonatomic, readwrite, assign) CGFloat padding; @property (nonatomic, readwrite, assign) YGValue padding;
@property (nonatomic, readwrite, assign) CGFloat borderLeftWidth; @property (nonatomic, readwrite, assign) CGFloat borderLeftWidth;
@property (nonatomic, readwrite, assign) CGFloat borderTopWidth; @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 borderEndWidth;
@property (nonatomic, readwrite, assign) CGFloat borderWidth; @property (nonatomic, readwrite, assign) CGFloat borderWidth;
@property (nonatomic, readwrite, assign) CGFloat width; @property (nonatomic, readwrite, assign) YGValue width;
@property (nonatomic, readwrite, assign) CGFloat height; @property (nonatomic, readwrite, assign) YGValue height;
@property (nonatomic, readwrite, assign) CGFloat minWidth; @property (nonatomic, readwrite, assign) YGValue minWidth;
@property (nonatomic, readwrite, assign) CGFloat minHeight; @property (nonatomic, readwrite, assign) YGValue minHeight;
@property (nonatomic, readwrite, assign) CGFloat maxWidth; @property (nonatomic, readwrite, assign) YGValue maxWidth;
@property (nonatomic, readwrite, assign) CGFloat maxHeight; @property (nonatomic, readwrite, assign) YGValue maxHeight;
// Yoga specific properties, not compatible with flexbox specification // Yoga specific properties, not compatible with flexbox specification
@property (nonatomic, readwrite, assign) CGFloat aspectRatio; @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. 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}. 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:)); NS_SWIFT_NAME(applyLayout(preservingOrigin:dimensionFlexibility:));
/** /**
@@ -113,6 +125,12 @@ typedef NS_OPTIONS(NSInteger, YGDimensionFlexibility) {
*/ */
@property (nonatomic, readonly, assign) CGSize intrinsicSize; @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. Returns the number of children that are using Flexbox.
*/ */

View File

@@ -22,23 +22,27 @@
} }
#define YG_VALUE_PROPERTY(lowercased_name, capitalized_name) \ #define YG_VALUE_PROPERTY(lowercased_name, capitalized_name) \
- (CGFloat)lowercased_name \ - (YGValue)lowercased_name \
{ \ { \
YGValue value = YGNodeStyleGet##capitalized_name(self.node); \ return YGNodeStyleGet##capitalized_name(self.node); \
if (value.unit == YGUnitPoint) { \
return value.value; \
} else { \
return YGUndefined; \
} \
} \ } \
\ \
- (void)set##capitalized_name:(CGFloat)lowercased_name \ - (void)set##capitalized_name:(YGValue)lowercased_name \
{ \ { \
YGNodeStyleSet##capitalized_name(self.node, 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) \ #define YG_EDGE_PROPERTY_GETTER(type, lowercased_name, capitalized_name, property, edge) \
- (CGFloat)lowercased_name \ - (type)lowercased_name \
{ \ { \
return YGNodeStyleGet##property(self.node, edge); \ return YGNodeStyleGet##property(self.node, edge); \
} }
@@ -50,28 +54,26 @@
} }
#define YG_EDGE_PROPERTY(lowercased_name, capitalized_name, property, edge) \ #define YG_EDGE_PROPERTY(lowercased_name, capitalized_name, property, edge) \
YG_EDGE_PROPERTY_GETTER(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) 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) \ #define YG_VALUE_EDGE_PROPERTY_SETTER(objc_lowercased_name, objc_capitalized_name, c_name, edge) \
- (CGFloat)objc_lowercased_name \ - (void)set##objc_capitalized_name:(YGValue)objc_lowercased_name \
{ \ { \
YGValue value = YGNodeStyleGet##c_name(self.node, edge); \ switch (objc_lowercased_name.unit) { \
if (value.unit == YGUnitPoint) { \ case YGUnitPoint: \
return value.value; \ YGNodeStyleSet##c_name(self.node, edge, objc_lowercased_name.value); \
} else { \ break; \
return YGUndefined; \ 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) \ #define YG_VALUE_EDGE_PROPERTY(lowercased_name, capitalized_name, property, edge) \
YG_VALUE_EDGE_PROPERTY_GETTER(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) YG_VALUE_EDGE_PROPERTY_SETTER(lowercased_name, capitalized_name, property, edge)
#define YG_VALUE_EDGES_PROPERTIES(lowercased_name, capitalized_name) \ #define YG_VALUE_EDGES_PROPERTIES(lowercased_name, capitalized_name) \
@@ -85,6 +87,16 @@ YG_VALUE_EDGE_PROPERTY(lowercased_name##Horizontal, capitalized_name##Horizontal
YG_VALUE_EDGE_PROPERTY(lowercased_name##Vertical, capitalized_name##Vertical, capitalized_name, YGEdgeVertical) \ YG_VALUE_EDGE_PROPERTY(lowercased_name##Vertical, capitalized_name##Vertical, capitalized_name, YGEdgeVertical) \
YG_VALUE_EDGE_PROPERTY(lowercased_name, capitalized_name, capitalized_name, YGEdgeAll) 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; static YGConfigRef globalConfig;
@interface YGLayout () @interface YGLayout ()
@@ -103,6 +115,7 @@ static YGConfigRef globalConfig;
{ {
globalConfig = YGConfigNew(); globalConfig = YGConfigNew();
YGConfigSetExperimentalFeatureEnabled(globalConfig, YGExperimentalFeatureWebFlexBasis, true); YGConfigSetExperimentalFeatureEnabled(globalConfig, YGExperimentalFeatureWebFlexBasis, true);
YGConfigSetPointScaleFactor(globalConfig, [UIScreen mainScreen].scale);
} }
- (instancetype)initWithView:(UIView*)view - (instancetype)initWithView:(UIView*)view
@@ -245,7 +258,7 @@ YG_PROPERTY(CGFloat, aspectRatio, AspectRatio)
size.height = YGUndefined; size.height = YGUndefined;
} }
[self calculateLayoutWithSize:size]; [self calculateLayoutWithSize:size];
YGApplyLayoutToViewHierarchy(self.view, NO); YGApplyLayoutToViewHierarchy(self.view, preserveOrigin);
} }
@@ -258,8 +271,6 @@ YG_PROPERTY(CGFloat, aspectRatio, AspectRatio)
return [self calculateLayoutWithSize:constrainedSize]; return [self calculateLayoutWithSize:constrainedSize];
} }
#pragma mark - Private
- (CGSize)calculateLayoutWithSize:(CGSize)size - (CGSize)calculateLayoutWithSize:(CGSize)size
{ {
NSAssert([NSThread isMainThread], @"Yoga calculation must be done on main."); 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( static YGSize YGMeasureView(
YGNodeRef node, YGNodeRef node,
float width, float width,

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

View File

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

View File

@@ -12,6 +12,11 @@ import YogaKit
struct DemoItem { struct DemoItem {
let name: String 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 { final class SwiftViewController: UIViewController, IGListAdapterDataSource {

View File

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

View File

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

View File

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

View File

@@ -3,8 +3,8 @@ apply plugin: 'com.android.library'
apply plugin: 'com.github.dcendents.android-maven' apply plugin: 'com.github.dcendents.android-maven'
apply plugin: 'maven-publish' apply plugin: 'maven-publish'
version = '1.4.1' version = VERSION_NAME
group = 'com.facebook.yoga.android' group = GROUP
android { android {
compileSdkVersion rootProject.compileSdkVersion compileSdkVersion rootProject.compileSdkVersion
@@ -42,8 +42,4 @@ task javadocJar(type: Jar, dependsOn: javadoc) {
from javadoc.destinationDir from javadoc.destinationDir
} }
ext { apply from: rootProject.file('gradle/release.gradle')
bintrayName = 'com.facebook.yoga.android:yoga-layout'
}
apply from: rootProject.file('gradle/android-jcenter-install.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.content.Intent;
import android.os.Bundle; 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.FragmentPagerAdapter;
import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentManager;
import android.support.v4.app.Fragment; 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.samples.yoga.R;
import com.facebook.yoga.android.YogaViewLayoutFactory; import com.facebook.yoga.android.YogaViewLayoutFactory;
public class BenchmarkActivity extends ActionBarActivity { public class BenchmarkActivity extends AppCompatActivity {
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {

View File

@@ -10,7 +10,7 @@ package com.facebook.samples.yoga;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.support.v7.app.ActionBarActivity; import android.support.v7.app.AppCompatActivity;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.MenuInflater; import android.view.MenuInflater;
import android.view.MenuItem; 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 * {@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. * as well as some optimisations on layout systems that it facilitates.
*/ */
public class MainActivity extends ActionBarActivity { public class MainActivity extends AppCompatActivity {
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {

View File

@@ -5,7 +5,7 @@ buildscript {
jcenter() jcenter()
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:2.3.1' classpath 'com.android.tools.build:gradle:2.3.3'
classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3' classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3'
classpath 'com.github.dcendents:android-maven-gradle-plugin:1.4.1' classpath 'com.github.dcendents:android-maven-gradle-plugin:1.4.1'
classpath 'com.nabilhachicha:android-native-dependencies:0.1' classpath 'com.nabilhachicha:android-native-dependencies:0.1'
@@ -22,7 +22,7 @@ allprojects {
} }
ext { ext {
minSdkVersion = 15 minSdkVersion = 14
targetSdkVersion = 25 targetSdkVersion = 25
compileSdkVersion = 25 compileSdkVersion = 25
buildToolsVersion = '25.0.2' buildToolsVersion = '25.0.2'
@@ -30,6 +30,33 @@ ext {
targetCompatibilityVersion = 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) { task clean(type: Delete) {
delete rootProject.buildDir delete rootProject.buildDir
} }

3
csharp/.gitignore vendored
View File

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

View File

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

View File

@@ -4,17 +4,17 @@
<BuildDependsOn>NativeLibraryARMV7;NativeLibraryX86;$(BuildDependsOn)</BuildDependsOn> <BuildDependsOn>NativeLibraryARMV7;NativeLibraryX86;$(BuildDependsOn)</BuildDependsOn>
</PropertyGroup> </PropertyGroup>
<Target Name="NativeLibraryARMV7" Outputs="$(ProjectDir)/lib/armeabi-v7a/libyoga.so"> <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" /> <Copy SourceFiles="$(ProjectDir)../../../buck-out/gen/csharp/yoganet#android-armv7,shared/libyoga.so" DestinationFiles="$(ProjectDir)/lib/armeabi-v7a/libyoga.so" SkipUnchangedFiles="true" />
</Target> </Target>
<!-- <!--
<Target Name="NativeLibraryARM64" Outputs="$(ProjectDir)/lib/arm64-v8a/libyoga.so"> <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" /> <Copy SourceFiles="$(ProjectDir)../../../buck-out/gen/csharp/yoganet#android-arm64,shared/libyoga.so" DestinationFiles="$(ProjectDir)/lib/arm64-v8/libyoga.so" SkipUnchangedFiles="true" />
</Target> </Target>
--> -->
<Target Name="NativeLibraryX86" Outputs="$(ProjectDir)/lib/x86/libyoga.so"> <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" /> <Copy SourceFiles="$(ProjectDir)../../../buck-out/gen/csharp/yoganet#android-x86,shared/libyoga.so" DestinationFiles="$(ProjectDir)/lib/x86/libyoga.so" SkipUnchangedFiles="true" />
</Target> </Target>
</Project> </Project>

View File

@@ -10,9 +10,12 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Compile Include="$(MSBuildThisFileDirectory)BaselineFunction.cs" /> <Compile Include="$(MSBuildThisFileDirectory)BaselineFunction.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Logger.cs" />
<Compile Include="$(MSBuildThisFileDirectory)MeasureFunction.cs" /> <Compile Include="$(MSBuildThisFileDirectory)MeasureFunction.cs" />
<Compile Include="$(MSBuildThisFileDirectory)MeasureOutput.cs" /> <Compile Include="$(MSBuildThisFileDirectory)MeasureOutput.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Native.cs" /> <Compile Include="$(MSBuildThisFileDirectory)Native.cs" />
<Compile Include="$(MSBuildThisFileDirectory)YGConfigHandle.cs" />
<Compile Include="$(MSBuildThisFileDirectory)YGNodeHandle.cs" />
<Compile Include="$(MSBuildThisFileDirectory)YogaAlign.cs" /> <Compile Include="$(MSBuildThisFileDirectory)YogaAlign.cs" />
<Compile Include="$(MSBuildThisFileDirectory)YogaBaselineFunc.cs" /> <Compile Include="$(MSBuildThisFileDirectory)YogaBaselineFunc.cs" />
<Compile Include="$(MSBuildThisFileDirectory)YogaConfig.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"; private const string DllName = "yoga";
#endif #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)] [DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
public static extern void YGInteropSetLogger( public static extern void YGInteropSetLogger(
[MarshalAs(UnmanagedType.FunctionPtr)] YogaLogger.Func func); [MarshalAs(UnmanagedType.FunctionPtr)] YogaLogger logger);
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] [DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
public static extern YGNodeHandle YGNodeNew(); public static extern YGNodeHandle YGNodeNew();
@@ -129,6 +42,9 @@ namespace Facebook.Yoga
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] [DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
public static extern void YGNodeReset(YGNodeHandle node); 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)] [DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
public static extern YGConfigHandle YGConfigNew(); public static extern YGConfigHandle YGConfigNew();
@@ -445,15 +361,19 @@ namespace Facebook.Yoga
#endregion #endregion
#region AOT #region Context
#if (UNITY_IOS && !UNITY_EDITOR) || ENABLE_IL2CPP || __IOS__
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] [DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr YGNodeGetContext(IntPtr node); public static extern IntPtr YGNodeGetContext(IntPtr node);
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] [DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
public static extern void YGNodeSetContext(IntPtr node, IntPtr managed); 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 #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 namespace Facebook.Yoga
{ {
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [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;
using System.Runtime.InteropServices;
#if __IOS__
using ObjCRuntime;
#endif
#if ENABLE_IL2CPP
using AOT;
#endif
namespace Facebook.Yoga namespace Facebook.Yoga
{ {
public class YogaConfig 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) if (_ygConfig.IsInvalid)
{ {
throw new InvalidOperationException("Failed to allocate native memory"); 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 { get {
return _ygConfig; 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( public void SetExperimentalFeatureEnabled(
YogaExperimentalFeature feature, YogaExperimentalFeature feature,
bool enabled) bool enabled)
@@ -68,5 +131,10 @@ namespace Facebook.Yoga
{ {
return Native.YGConfigGetInstanceCount(); return Native.YGConfigGetInstanceCount();
} }
public static void SetDefaultLogger(Logger logger)
{
Default.Logger = logger;
}
} }
} }

View File

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

View File

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

View File

@@ -10,48 +10,12 @@
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
#if __IOS__
using ObjCRuntime;
#endif
#if ENABLE_IL2CPP
using AOT;
#endif
namespace Facebook.Yoga namespace Facebook.Yoga
{
internal static class YogaLogger
{ {
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void Func(YogaLogLevel level, string message); public delegate void YogaLogger(
IntPtr unmanagedConfigPtr,
private static bool _initialized; IntPtr unmanagedNotePtr,
private static Func _managedLogger = LoggerInternal; YogaLogLevel level,
string message);
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;
}
}
}
} }

View File

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

View File

@@ -10,11 +10,9 @@
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text; using System.Text;
#if (UNITY_IOS && !UNITY_EDITOR) || ENABLE_IL2CPP || __IOS__
using System.Runtime.InteropServices;
#endif
#if __IOS__ #if __IOS__
using ObjCRuntime; using ObjCRuntime;
#endif #endif
@@ -26,49 +24,26 @@ namespace Facebook.Yoga
{ {
public partial class YogaNode : IEnumerable<YogaNode> public partial class YogaNode : IEnumerable<YogaNode>
{ {
private readonly Native.YGNodeHandle _ygNode; private readonly YGNodeHandle _ygNode;
private readonly YogaConfig _config; private readonly YogaConfig _config;
private WeakReference _parent; private WeakReference _parent;
private List<YogaNode> _children; private List<YogaNode> _children;
private MeasureFunction _measureFunction; private MeasureFunction _measureFunction;
private BaselineFunction _baselineFunction; 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 YogaMeasureFunc _managedMeasure;
private YogaBaselineFunc _managedBaseline; private YogaBaselineFunc _managedBaseline;
#endif private object _data;
public YogaNode() public YogaNode(YogaConfig config = null)
{ {
YogaLogger.Initialize(); _config = config == null ? YogaConfig.Default : config;
_ygNode = Native.YGNodeNew();
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); _ygNode = Native.YGNodeNewWithConfig(_config.Handle);
}
else
{
_ygNode = Native.YGNodeNew();
}
if (_ygNode.IsInvalid) if (_ygNode.IsInvalid)
{ {
throw new InvalidOperationException("Failed to allocate native memory"); throw new InvalidOperationException("Failed to allocate native memory");
} }
_ygNode.SetContext(this);
} }
public YogaNode(YogaNode srcNode) public YogaNode(YogaNode srcNode)
@@ -83,10 +58,9 @@ namespace Facebook.Yoga
_baselineFunction = null; _baselineFunction = null;
_data = null; _data = null;
Native.YGNodeReset(_ygNode);
#if (UNITY_IOS && !UNITY_EDITOR) || ENABLE_IL2CPP || __IOS__
_ygNode.ReleaseManaged(); _ygNode.ReleaseManaged();
#endif Native.YGNodeReset(_ygNode);
_ygNode.SetContext(this);
} }
public bool IsDirty public bool IsDirty
@@ -609,38 +583,15 @@ namespace Facebook.Yoga
public void SetMeasureFunction(MeasureFunction measureFunction) public void SetMeasureFunction(MeasureFunction measureFunction)
{ {
_measureFunction = measureFunction; _measureFunction = measureFunction;
if (measureFunction != null) _managedMeasure = measureFunction != null ? MeasureInternal : (YogaMeasureFunc)null;
{
#if (UNITY_IOS && !UNITY_EDITOR) || ENABLE_IL2CPP || __IOS__
_managedMeasure = MeasureInternalAOT;
_ygNode.SetContext(this);
#else
_managedMeasure = MeasureInternal;
#endif
}
else
{
_managedMeasure = null;
}
Native.YGNodeSetMeasureFunc(_ygNode, _managedMeasure); Native.YGNodeSetMeasureFunc(_ygNode, _managedMeasure);
} }
public void SetBaselineFunction(BaselineFunction baselineFunction) public void SetBaselineFunction(BaselineFunction baselineFunction)
{ {
_baselineFunction = baselineFunction; _baselineFunction = baselineFunction;
if (baselineFunction != null) _managedBaseline =
{ baselineFunction != null ? BaselineInternal : (YogaBaselineFunc)null;
#if (UNITY_IOS && !UNITY_EDITOR) || ENABLE_IL2CPP || __IOS__
_managedBaseline = BaselineInternalAOT;
_ygNode.SetContext(this);
#else
_managedBaseline = BaselineInternal;
#endif
}
else
{
_managedBaseline = null;
}
Native.YGNodeSetBaselineFunc(_ygNode, _managedBaseline); Native.YGNodeSetBaselineFunc(_ygNode, _managedBaseline);
} }
@@ -655,63 +606,46 @@ namespace Facebook.Yoga
#if (UNITY_IOS && !UNITY_EDITOR) || ENABLE_IL2CPP || __IOS__ #if (UNITY_IOS && !UNITY_EDITOR) || ENABLE_IL2CPP || __IOS__
[MonoPInvokeCallback(typeof(YogaMeasureFunc))] [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 #endif
private static YogaSize MeasureInternal(
private YogaSize MeasureInternal( IntPtr unmanagedNodePtr,
IntPtr node,
float width, float width,
YogaMeasureMode widthMode, YogaMeasureMode widthMode,
float height, float height,
YogaMeasureMode heightMode) YogaMeasureMode heightMode)
{ {
if (_measureFunction == null) var node = YGNodeHandle.GetManaged(unmanagedNodePtr);
if (node == null || node._measureFunction == null)
{ {
throw new InvalidOperationException("Measure function is not defined."); throw new InvalidOperationException("Measure function is not defined.");
} }
return node._measureFunction(node, width, widthMode, height, heightMode);
return _measureFunction(this, width, widthMode, height, heightMode);
} }
#if (UNITY_IOS && !UNITY_EDITOR) || ENABLE_IL2CPP || __IOS__ #if (UNITY_IOS && !UNITY_EDITOR) || ENABLE_IL2CPP || __IOS__
[MonoPInvokeCallback(typeof(YogaBaselineFunc))] [MonoPInvokeCallback(typeof(YogaBaselineFunc))]
private static float BaselineInternalAOT( #endif
IntPtr ygNodePtr, private static float BaselineInternal(
IntPtr unmanagedNodePtr,
float width, float width,
float height) float height)
{ {
var node = Native.YGNodeHandle.GetManaged(ygNodePtr); var node = YGNodeHandle.GetManaged(unmanagedNodePtr);
return node.BaselineInternal(IntPtr.Zero, width, height); if (node == null || node._baselineFunction == null)
}
#endif
private float BaselineInternal(IntPtr node, float width, float height)
{
if (_baselineFunction == null)
{ {
throw new InvalidOperationException("Baseline function is not defined."); throw new InvalidOperationException("Baseline function is not defined.");
} }
return node._baselineFunction(node, width, height);
return _baselineFunction(this, width, height);
} }
public string Print(YogaPrintOptions options = public string Print(YogaPrintOptions options =
YogaPrintOptions.Layout|YogaPrintOptions.Style|YogaPrintOptions.Children) YogaPrintOptions.Layout|YogaPrintOptions.Style|YogaPrintOptions.Children)
{ {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
YogaLogger.Func orig = YogaLogger.Logger; Logger orig = _config.Logger;
YogaLogger.Logger = (level, message) => {sb.Append(message);}; _config.Logger = (config, node, level, message) => {sb.Append(message);};
Native.YGNodePrint(_ygNode, options); Native.YGNodePrint(_ygNode, options);
YogaLogger.Logger = orig; _config.Logger = orig;
return sb.ToString(); 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,7 +4,7 @@
<CompileDependsOn>NativeLibrary;$(CompileDependsOn)</CompileDependsOn> <CompileDependsOn>NativeLibrary;$(CompileDependsOn)</CompileDependsOn>
</PropertyGroup> </PropertyGroup>
<Target Name="NativeLibrary" Outputs="$(ProjectDir)libyoga.dylib"> <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" /> <Copy SourceFiles="$(ProjectDir)..\..\buck-out\gen\csharp\yoganet-macosx\libyoga.dylib" DestinationFiles="$(ProjectDir)libyoga.dylib" SkipUnchangedFiles="true" />
</Target> </Target>
</Project> </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 class NSRunLoopIntegration : NSObject, IMainLoopIntegration
{ {
public void InitializeToolkit() public void InitializeToolkit()
@@ -51,7 +54,7 @@ namespace Facebook.Yoga.Mac.Tests
public void Shutdown() 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" #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; int result = 0;
if (gManagedFunc) { if (gManagedLogger) {
char buffer[256]; char message[8192];
result = vsnprintf(buffer, sizeof(buffer), format, args); result = vsnprintf(message, sizeof(message), format, args);
(*gManagedFunc)(level, buffer); (*gManagedLogger)(config, node, level, message);
} }
return result; return result;
} }
void YGInteropSetLogger(YGInteropLoggerFunc managedFunc) { void YGInteropSetLogger(YGInteropLogger managedLogger) {
gManagedFunc = managedFunc; gManagedLogger = managedLogger;
YGSetLogger(&unmanagedLogger); YGConfigSetLogger(YGConfigGetDefault(), &unmanagedLogger);
} }

View File

@@ -13,8 +13,13 @@
YG_EXTERN_C_BEGIN 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 YG_EXTERN_C_END

View File

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

View File

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

View File

@@ -1,17 +1,25 @@
#!/bin/sh #!/bin/sh
cd `dirname "$0"`
echo $ANDROID_SDK 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!" echo "Building Buck!"
mkdir lib BUCK_PATH=buck-$BUCK_RELEASE
mkdir -p lib
cd lib cd lib
git clone https://github.com/facebook/buck.git --depth 1 rm -f $BUCK_PATH.tar.gz
cd buck 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 ant
cd .. cd ../..
cd ..
fi fi
buck build //:yoga
buck build //csharp:yoganet-ios $BUCK build \
buck build //csharp:yoganet-macosx //csharp:yoganet-ios \
buck build //csharp:yoganet#android-x86,shared //csharp:yoganet-macosx \
buck build //csharp:yoganet#android-armv7,shared //csharp:yoganet#android-armv7,shared \
//csharp:yoganet#android-x86,shared

View File

@@ -4,7 +4,7 @@
<CompileDependsOn>NativeLibrary;$(CompileDependsOn)</CompileDependsOn> <CompileDependsOn>NativeLibrary;$(CompileDependsOn)</CompileDependsOn>
</PropertyGroup> </PropertyGroup>
<Target Name="NativeLibrary" Outputs="$(ProjectDir)libyoga.a"> <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" /> <Copy SourceFiles="$(ProjectDir)..\..\..\buck-out\gen\csharp\yoganet-ios\libyoga.a" DestinationFiles="$(ProjectDir)libyoga.a" SkipUnchangedFiles="true" />
</Target> </Target>
</Project> </Project>

View File

@@ -285,6 +285,30 @@ namespace Facebook.Yoga
root_child1.Width = 50; root_child1.Width = 50;
root_child1.Height = 50; root_child1.Height = 50;
root.Insert(1, root_child1); 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.StyleDirection = YogaDirection.LTR;
root.CalculateLayout(); root.CalculateLayout();
@@ -303,6 +327,16 @@ namespace Facebook.Yoga
Assert.AreEqual(50f, root_child1.LayoutWidth); Assert.AreEqual(50f, root_child1.LayoutWidth);
Assert.AreEqual(50f, root_child1.LayoutHeight); 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.StyleDirection = YogaDirection.RTL;
root.CalculateLayout(); root.CalculateLayout();
@@ -320,6 +354,16 @@ namespace Facebook.Yoga
Assert.AreEqual(40f, root_child1.LayoutY); Assert.AreEqual(40f, root_child1.LayoutY);
Assert.AreEqual(50f, root_child1.LayoutWidth); Assert.AreEqual(50f, root_child1.LayoutWidth);
Assert.AreEqual(50f, root_child1.LayoutHeight); 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] [Test]
@@ -745,5 +789,253 @@ namespace Facebook.Yoga
Assert.AreEqual(52f, root.LayoutHeight); 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); 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); 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); 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() public void Test_flex_grow_to_min()
{ {
YogaConfig config = new YogaConfig(); YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.MinFlexFix, true);
YogaNode root = new YogaNode(config); YogaNode root = new YogaNode(config);
root.Width = 100; root.Width = 100;
@@ -422,7 +421,6 @@ namespace Facebook.Yoga
public void Test_flex_grow_in_at_most_container() public void Test_flex_grow_in_at_most_container()
{ {
YogaConfig config = new YogaConfig(); YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.MinFlexFix, true);
YogaNode root = new YogaNode(config); YogaNode root = new YogaNode(config);
root.FlexDirection = YogaFlexDirection.Row; root.FlexDirection = YogaFlexDirection.Row;
@@ -678,6 +676,203 @@ namespace Facebook.Yoga
Assert.AreEqual(20f, root_child0_child0.LayoutHeight); 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] [Test]
public void Test_flex_grow_within_constrained_min_row() public void Test_flex_grow_within_constrained_min_row()
{ {
@@ -907,6 +1102,64 @@ namespace Facebook.Yoga
Assert.AreEqual(50f, root_child1.LayoutHeight); 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] [Test]
public void Test_min_width_overrides_width() public void Test_min_width_overrides_width()
{ {

View File

@@ -21,7 +21,6 @@ namespace Facebook.Yoga
public void Test_percentage_width_height() public void Test_percentage_width_height()
{ {
YogaConfig config = new YogaConfig(); YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.Rounding, true);
YogaNode root = new YogaNode(config); YogaNode root = new YogaNode(config);
root.FlexDirection = YogaFlexDirection.Row; root.FlexDirection = YogaFlexDirection.Row;
@@ -63,7 +62,6 @@ namespace Facebook.Yoga
public void Test_percentage_position_left_top() public void Test_percentage_position_left_top()
{ {
YogaConfig config = new YogaConfig(); YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.Rounding, true);
YogaNode root = new YogaNode(config); YogaNode root = new YogaNode(config);
root.FlexDirection = YogaFlexDirection.Row; root.FlexDirection = YogaFlexDirection.Row;
@@ -107,7 +105,6 @@ namespace Facebook.Yoga
public void Test_percentage_position_bottom_right() public void Test_percentage_position_bottom_right()
{ {
YogaConfig config = new YogaConfig(); YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.Rounding, true);
YogaNode root = new YogaNode(config); YogaNode root = new YogaNode(config);
root.FlexDirection = YogaFlexDirection.Row; root.FlexDirection = YogaFlexDirection.Row;
@@ -151,7 +148,6 @@ namespace Facebook.Yoga
public void Test_percentage_flex_basis() public void Test_percentage_flex_basis()
{ {
YogaConfig config = new YogaConfig(); YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.Rounding, true);
YogaNode root = new YogaNode(config); YogaNode root = new YogaNode(config);
root.FlexDirection = YogaFlexDirection.Row; root.FlexDirection = YogaFlexDirection.Row;
@@ -208,7 +204,6 @@ namespace Facebook.Yoga
public void Test_percentage_flex_basis_cross() public void Test_percentage_flex_basis_cross()
{ {
YogaConfig config = new YogaConfig(); YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.Rounding, true);
YogaNode root = new YogaNode(config); YogaNode root = new YogaNode(config);
root.Width = 200; root.Width = 200;
@@ -264,7 +259,6 @@ namespace Facebook.Yoga
public void Test_percentage_flex_basis_cross_min_height() public void Test_percentage_flex_basis_cross_min_height()
{ {
YogaConfig config = new YogaConfig(); YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.Rounding, true);
YogaNode root = new YogaNode(config); YogaNode root = new YogaNode(config);
root.Width = 200; root.Width = 200;
@@ -320,7 +314,6 @@ namespace Facebook.Yoga
public void Test_percentage_flex_basis_main_max_height() public void Test_percentage_flex_basis_main_max_height()
{ {
YogaConfig config = new YogaConfig(); YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.Rounding, true);
YogaNode root = new YogaNode(config); YogaNode root = new YogaNode(config);
root.FlexDirection = YogaFlexDirection.Row; root.FlexDirection = YogaFlexDirection.Row;
@@ -379,7 +372,6 @@ namespace Facebook.Yoga
public void Test_percentage_flex_basis_cross_max_height() public void Test_percentage_flex_basis_cross_max_height()
{ {
YogaConfig config = new YogaConfig(); YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.Rounding, true);
YogaNode root = new YogaNode(config); YogaNode root = new YogaNode(config);
root.Width = 200; root.Width = 200;
@@ -437,7 +429,6 @@ namespace Facebook.Yoga
public void Test_percentage_flex_basis_main_max_width() public void Test_percentage_flex_basis_main_max_width()
{ {
YogaConfig config = new YogaConfig(); YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.Rounding, true);
YogaNode root = new YogaNode(config); YogaNode root = new YogaNode(config);
root.FlexDirection = YogaFlexDirection.Row; root.FlexDirection = YogaFlexDirection.Row;
@@ -496,7 +487,6 @@ namespace Facebook.Yoga
public void Test_percentage_flex_basis_cross_max_width() public void Test_percentage_flex_basis_cross_max_width()
{ {
YogaConfig config = new YogaConfig(); YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.Rounding, true);
YogaNode root = new YogaNode(config); YogaNode root = new YogaNode(config);
root.Width = 200; root.Width = 200;
@@ -554,7 +544,6 @@ namespace Facebook.Yoga
public void Test_percentage_flex_basis_main_min_width() public void Test_percentage_flex_basis_main_min_width()
{ {
YogaConfig config = new YogaConfig(); YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.Rounding, true);
YogaNode root = new YogaNode(config); YogaNode root = new YogaNode(config);
root.FlexDirection = YogaFlexDirection.Row; root.FlexDirection = YogaFlexDirection.Row;
@@ -613,7 +602,6 @@ namespace Facebook.Yoga
public void Test_percentage_flex_basis_cross_min_width() public void Test_percentage_flex_basis_cross_min_width()
{ {
YogaConfig config = new YogaConfig(); YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.Rounding, true);
YogaNode root = new YogaNode(config); YogaNode root = new YogaNode(config);
root.Width = 200; root.Width = 200;
@@ -671,7 +659,6 @@ namespace Facebook.Yoga
public void Test_percentage_multiple_nested_with_padding_margin_and_percentage_values() public void Test_percentage_multiple_nested_with_padding_margin_and_percentage_values()
{ {
YogaConfig config = new YogaConfig(); YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.Rounding, true);
YogaNode root = new YogaNode(config); YogaNode root = new YogaNode(config);
root.Width = 200; root.Width = 200;
@@ -781,7 +768,6 @@ namespace Facebook.Yoga
public void Test_percentage_margin_should_calculate_based_only_on_width() public void Test_percentage_margin_should_calculate_based_only_on_width()
{ {
YogaConfig config = new YogaConfig(); YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.Rounding, true);
YogaNode root = new YogaNode(config); YogaNode root = new YogaNode(config);
root.Width = 200; root.Width = 200;
@@ -840,7 +826,6 @@ namespace Facebook.Yoga
public void Test_percentage_padding_should_calculate_based_only_on_width() public void Test_percentage_padding_should_calculate_based_only_on_width()
{ {
YogaConfig config = new YogaConfig(); YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.Rounding, true);
YogaNode root = new YogaNode(config); YogaNode root = new YogaNode(config);
root.Width = 200; root.Width = 200;
@@ -899,7 +884,6 @@ namespace Facebook.Yoga
public void Test_percentage_absolute_position() public void Test_percentage_absolute_position()
{ {
YogaConfig config = new YogaConfig(); YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.Rounding, true);
YogaNode root = new YogaNode(config); YogaNode root = new YogaNode(config);
root.Width = 200; root.Width = 200;
@@ -1063,7 +1047,6 @@ namespace Facebook.Yoga
public void Test_percentage_container_in_wrapping_container() public void Test_percentage_container_in_wrapping_container()
{ {
YogaConfig config = new YogaConfig(); YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.MinFlexFix, true);
YogaNode root = new YogaNode(config); YogaNode root = new YogaNode(config);
root.JustifyContent = YogaJustify.Center; 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() public void Test_rounding_flex_basis_flex_grow_row_width_of_100()
{ {
YogaConfig config = new YogaConfig(); YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.Rounding, true);
YogaNode root = new YogaNode(config); YogaNode root = new YogaNode(config);
root.FlexDirection = YogaFlexDirection.Row; root.FlexDirection = YogaFlexDirection.Row;
@@ -90,7 +89,6 @@ namespace Facebook.Yoga
public void Test_rounding_flex_basis_flex_grow_row_prime_number_width() public void Test_rounding_flex_basis_flex_grow_row_prime_number_width()
{ {
YogaConfig config = new YogaConfig(); YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.Rounding, true);
YogaNode root = new YogaNode(config); YogaNode root = new YogaNode(config);
root.FlexDirection = YogaFlexDirection.Row; root.FlexDirection = YogaFlexDirection.Row;
@@ -187,7 +185,6 @@ namespace Facebook.Yoga
public void Test_rounding_flex_basis_flex_shrink_row() public void Test_rounding_flex_basis_flex_shrink_row()
{ {
YogaConfig config = new YogaConfig(); YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.Rounding, true);
YogaNode root = new YogaNode(config); YogaNode root = new YogaNode(config);
root.FlexDirection = YogaFlexDirection.Row; root.FlexDirection = YogaFlexDirection.Row;
@@ -257,7 +254,6 @@ namespace Facebook.Yoga
public void Test_rounding_flex_basis_overrides_main_size() public void Test_rounding_flex_basis_overrides_main_size()
{ {
YogaConfig config = new YogaConfig(); YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.Rounding, true);
YogaNode root = new YogaNode(config); YogaNode root = new YogaNode(config);
root.Width = 100; root.Width = 100;
@@ -329,7 +325,6 @@ namespace Facebook.Yoga
public void Test_rounding_total_fractial() public void Test_rounding_total_fractial()
{ {
YogaConfig config = new YogaConfig(); YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.Rounding, true);
YogaNode root = new YogaNode(config); YogaNode root = new YogaNode(config);
root.Width = 87.4f; root.Width = 87.4f;
@@ -401,7 +396,6 @@ namespace Facebook.Yoga
public void Test_rounding_total_fractial_nested() public void Test_rounding_total_fractial_nested()
{ {
YogaConfig config = new YogaConfig(); YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.Rounding, true);
YogaNode root = new YogaNode(config); YogaNode root = new YogaNode(config);
root.Width = 87.4f; root.Width = 87.4f;
@@ -507,7 +501,6 @@ namespace Facebook.Yoga
public void Test_rounding_fractial_input_1() public void Test_rounding_fractial_input_1()
{ {
YogaConfig config = new YogaConfig(); YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.Rounding, true);
YogaNode root = new YogaNode(config); YogaNode root = new YogaNode(config);
root.Width = 100; root.Width = 100;
@@ -579,7 +572,6 @@ namespace Facebook.Yoga
public void Test_rounding_fractial_input_2() public void Test_rounding_fractial_input_2()
{ {
YogaConfig config = new YogaConfig(); YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.Rounding, true);
YogaNode root = new YogaNode(config); YogaNode root = new YogaNode(config);
root.Width = 100; root.Width = 100;
@@ -651,7 +643,6 @@ namespace Facebook.Yoga
public void Test_rounding_fractial_input_3() public void Test_rounding_fractial_input_3()
{ {
YogaConfig config = new YogaConfig(); YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.Rounding, true);
YogaNode root = new YogaNode(config); YogaNode root = new YogaNode(config);
root.Top = 0.3f; root.Top = 0.3f;
@@ -724,7 +715,6 @@ namespace Facebook.Yoga
public void Test_rounding_fractial_input_4() public void Test_rounding_fractial_input_4()
{ {
YogaConfig config = new YogaConfig(); YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.Rounding, true);
YogaNode root = new YogaNode(config); YogaNode root = new YogaNode(config);
root.Top = 0.7f; root.Top = 0.7f;
@@ -797,7 +787,6 @@ namespace Facebook.Yoga
public void Test_rounding_inner_node_controversy_horizontal() public void Test_rounding_inner_node_controversy_horizontal()
{ {
YogaConfig config = new YogaConfig(); YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.Rounding, true);
YogaNode root = new YogaNode(config); YogaNode root = new YogaNode(config);
root.FlexDirection = YogaFlexDirection.Row; root.FlexDirection = YogaFlexDirection.Row;
@@ -883,7 +872,6 @@ namespace Facebook.Yoga
public void Test_rounding_inner_node_controversy_vertical() public void Test_rounding_inner_node_controversy_vertical()
{ {
YogaConfig config = new YogaConfig(); YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.Rounding, true);
YogaNode root = new YogaNode(config); YogaNode root = new YogaNode(config);
root.Height = 320; root.Height = 320;
@@ -968,7 +956,6 @@ namespace Facebook.Yoga
public void Test_rounding_inner_node_controversy_combined() public void Test_rounding_inner_node_controversy_combined()
{ {
YogaConfig config = new YogaConfig(); YogaConfig config = new YogaConfig();
config.SetExperimentalFeatureEnabled(YogaExperimentalFeature.Rounding, true);
YogaNode root = new YogaNode(config); YogaNode root = new YogaNode(config);
root.FlexDirection = YogaFlexDirection.Row; root.FlexDirection = YogaFlexDirection.Row;

View File

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

View File

@@ -164,6 +164,14 @@ namespace Facebook.Yoga
return MeasureOutput.Make(123.4f, 81.7f); return MeasureOutput.Make(123.4f, 81.7f);
}); });
node.CalculateLayout(); 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(123.4f, node.LayoutWidth);
Assert.AreEqual(81.7f, node.LayoutHeight); Assert.AreEqual(81.7f, node.LayoutHeight);
} }
@@ -240,6 +248,26 @@ namespace Facebook.Yoga
Assert.AreEqual(0, child2.LayoutY); 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] [Test]
public void TestPrint() public void TestPrint()
{ {
@@ -301,9 +329,10 @@ namespace Facebook.Yoga
Assert.AreEqual(90.Pt(), node4.MaxHeight); Assert.AreEqual(90.Pt(), node4.MaxHeight);
} }
#if !UNITY_5_4_OR_NEWER
public static void ForceGC() public static void ForceGC()
{ {
GC.Collect(GC.MaxGeneration); GC.Collect();
GC.WaitForPendingFinalizers(); GC.WaitForPendingFinalizers();
} }
@@ -430,6 +459,7 @@ namespace Facebook.Yoga
return MeasureOutput.Make(120, 130); return MeasureOutput.Make(120, 130);
}); });
} }
#endif
[Test] [Test]
public void TestLayoutMargin() { 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}'` DYLIB=`buck targets --show-output $TARGET|tail -1|awk '{print $2}'`
cp $ROOT/$DYLIB . 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 MONO_PATH=$NUNIT mono --arch=64 --debug $NUNIT/nunit-console.exe YogaTest.dll

View File

@@ -140,6 +140,3 @@ PLATFORMS
DEPENDENCIES DEPENDENCIES
github-pages (~> 104) 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: To include the java bindings and `.so` libraries, add to your build:
```java ```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: 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" xmlns:yoga="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
yoga:align_items="stretch" yoga:yg_alignItems="stretch"
> >
<YogaLayout <YogaLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="@drawable/sample_children_background" android:background="@drawable/sample_children_background"
yoga:margin_horizontal="10dp" yoga:yg_marginHorizontal="10dp"
yoga:margin_top="5dp" yoga:yg_marginTop="5dp"
yoga:flex_direction="row" yoga:yg_flexDirection="row"
yoga:align_items="center" yoga:yg_alignItems="center"
> >
<ImageView <ImageView
android:layout_width="50dp" android:layout_width="50dp"
android:layout_height="50dp" android:layout_height="50dp"
android:src="@drawable/ic_launcher" android:src="@drawable/ic_launcher"
yoga:flex="0" yoga:yg_flex="0"
/> />
<TextView <TextView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/child_1_text" android:text="@string/child_1_text"
android:textColor="@color/children_text" android:textColor="@color/children_text"
yoga:flex="1" yoga:yg_flex="1"
yoga:margin_start="8dp" yoga:yg_marginStart="8dp"
/> />
</YogaLayout> </YogaLayout>
</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: To include this in your project, add to your build:
```java ```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 ## 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 ## VirtualYogaLayout
@@ -67,11 +86,11 @@ Sometimes you will nest `YogaLayout`s within `YogaLayout`s in order to get your
## RTL locales ## 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 ## 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 ## 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 YGNodeInsertChild(YGNodeRef node, YGNodeRef child, uint32_t index);
void YGNodeRemoveChild(YGNodeRef node, YGNodeRef child); void YGNodeRemoveChild(YGNodeRef node, YGNodeRef child);
YGNodeRef YGNodeGetChild(YGNodeRef node, uint32_t index); YGNodeRef YGNodeGetChild(YGNodeRef node, uint32_t index);
uint32_t YGNodeChildCount(YGNodeRef node); uint32_t YGNodeGetChildCount(YGNodeRef node);
``` ```
### Style getters & setters ### Style getters & setters

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). > 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 ### 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. 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. 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> <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

@@ -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. 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`). 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

@@ -163,25 +163,25 @@ root.Insert(text, 1);
<YogaLayout <YogaLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
yoga:justify_content="stretch"> yoga:yg_justifyContent="stretch">
<ImageView <ImageView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
yoga:flex="1"/> yoga:yg_flex="1"/>
<VirtualYogaLayout <VirtualYogaLayout
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
yoga:padding_all="20px" yoga:yg_paddingAll="20px"
yoga:flex_direction="row" yoga:yg_flexDirection="row"
yoga:align_items="center"> yoga:yg_alignItems="center">
<ImageView <ImageView
android:layout_width="50dp" android:layout_width="50dp"
android:layout_height="50dp"/> android:layout_height="50dp"/>
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
yoga:flex="1" yoga:yg_flex="1"
yoga:margin_start="20px"/> yoga:yg_marginStart="20px"/>
</VirtualYogaLayout> </VirtualYogaLayout>
</YogaLayout> </YogaLayout>
``` ```

View File

@@ -84,18 +84,21 @@ ENUMS = {
'Vertical', 'Vertical',
'All', 'All',
], ],
'NodeType': [
'Default',
'Text',
],
'LogLevel': [ 'LogLevel': [
'Error', 'Error',
'Warn', 'Warn',
'Info', 'Info',
'Debug', 'Debug',
'Verbose', 'Verbose',
'Fatal',
], ],
'ExperimentalFeature': [ 'ExperimentalFeature': [
'Rounding',
# Mimic web flex-basis behavior. # Mimic web flex-basis behavior.
'WebFlexBasis', 'WebFlexBasis',
'MinFlexFix'
], ],
'PrintOptions': [ 'PrintOptions': [
('Layout', 1), ('Layout', 1),

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 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; 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; 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>
<div id="absolute_layout_align_items_and_justify_content_center" style="height: 100px; width: 110px; flex-grow: 1; align-items: center; justify-content: center;"> <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 id="position_root_with_rtl_should_position_withoutdirection" style="height: 52px; width: 52px; left: 72px; ">
</div> </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 style="width: 72px; height: 72px;"></div>
</div> </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 style="flex-grow:1; flex-shrink:1;"></div>
</div> </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 style="width: 80px; height: 80px;"></div>
</div> </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 style="width: 50px; height: 50px;"></div>
</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="flex-grow: 1; flex-shrink: 1;"></div>
<div style="height: 50px;"></div> <div style="height: 50px;"></div>
</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-direction: row;">
<div style="flex-grow: 1; flex-basis: 0px;"></div> <div style="flex-grow: 1; flex-basis: 0px;"></div>
</div> </div>
@@ -62,6 +62,25 @@
</div> </div>
</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 id="flex_grow_within_constrained_min_row" style="min-width: 100px; height:100px; flex-direction: row;">
<div style="flex-grow:1;"></div> <div style="flex-grow:1;"></div>
<div style="width: 50px;"></div> <div style="width: 50px;"></div>
@@ -84,6 +103,11 @@
<div style="height: 50px;"></div> <div style="height: 50px;"></div>
</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 id="min_width_overrides_width" style="min-width: 100px; width: 50px;">
</div> </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 style="width: 30%; height: 30%;"></div>
</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 style="width: 45%; height: 55%; left: 10%; top: 20%"></div>
</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 style="width: 55%; height: 15%; bottom: 10%; right: 20%"></div>
</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: 50%;"></div>
<div style="flex-grow: 1; flex-basis: 25%;"></div> <div style="flex-grow: 1; flex-basis: 25%;"></div>
</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: 50%;"></div>
<div style="flex-grow: 1; flex-basis: 25%;"></div> <div style="flex-grow: 1; flex-basis: 25%;"></div>
</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: 1; min-height: 60%;"></div>
<div style="flex-grow: 2; min-height: 10%;"></div> <div style="flex-grow: 2; min-height: 10%;"></div>
</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: 1; flex-basis: 10%; max-height: 60%;"></div>
<div style="flex-grow: 4; flex-basis: 10%; max-height: 20%;"></div> <div style="flex-grow: 4; flex-basis: 10%; max-height: 20%;"></div>
</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: 1; flex-basis: 10%; max-height: 60%;"></div>
<div style="flex-grow: 4; flex-basis: 10%; max-height: 20%;"></div> <div style="flex-grow: 4; flex-basis: 10%; max-height: 20%;"></div>
</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: 1; flex-basis: 15%; max-width: 60%;"></div>
<div style="flex-grow: 4; flex-basis: 10%; max-width: 20%;"></div> <div style="flex-grow: 4; flex-basis: 10%; max-width: 20%;"></div>
</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: 1; flex-basis: 10%; max-width: 60%;"></div>
<div style="flex-grow: 4; flex-basis: 15%; max-width: 20%;"></div> <div style="flex-grow: 4; flex-basis: 15%; max-width: 20%;"></div>
</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: 1; flex-basis: 15%; min-width: 60%;"></div>
<div style="flex-grow: 4; flex-basis: 10%; min-width: 20%;"></div> <div style="flex-grow: 4; flex-basis: 10%; min-width: 20%;"></div>
</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: 1; flex-basis: 10%; min-width: 60%;"></div>
<div style="flex-grow: 4; flex-basis: 15%; min-width: 20%;"></div> <div style="flex-grow: 4; flex-basis: 15%; min-width: 20%;"></div>
</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="flex-grow: 1; flex-basis: 10%; min-width: 60%; margin: 5px; padding: 3px;">
<div style="width: 50%; margin: 5px; padding: 3%;"> <div style="width: 50%; margin: 5px; padding: 3%;">
<div style="width: 45%; margin: 5%; padding: 3px;"></div> <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 style="flex-grow: 4; flex-basis: 15%; min-width: 20%;"></div>
</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="flex-grow: 1; margin: 10%;">
<div style="width: 10px; height: 10px;"></div> <div style="width: 10px; height: 10px;"></div>
</div> </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="flex-grow: 1; padding: 10%;">
<div style="width: 10px; height: 10px;"></div> <div style="width: 10px; height: 10px;"></div>
</div> </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 style="position: absolute; top: 10%; left: 30%; width: 10px; height: 10px;"></div>
</div> </div>
@@ -92,7 +92,7 @@
<div style="width: 100px;"></div> <div style="width: 100px;"></div>
</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>
<div style="alignItems: center; flex-direction: row; justify-content: center; width: 100%;"> <div style="alignItems: center; flex-direction: row; justify-content: center; width: 100%;">
<div style="width: 50px; height: 50px;"></div> <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 style="flex-grow: 1;"></div>
<div style="flex-grow: 1;"></div> <div style="flex-grow: 1;"></div>
</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> <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 style="flex-grow: 1;"></div>
</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: 100px; flex-shrink: 1;"></div>
<div style="flex-basis: 25px;"></div> <div style="flex-basis: 25px;"></div>
<div style="flex-basis: 25px;"></div> <div style="flex-basis: 25px;"></div>
</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: 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 style="height: 10px; flex-grow:1;"></div> <div style="height: 10px; flex-grow:1;"></div>
</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: 20.3px; flex-grow:0.7; flex-basis:50.3px;"></div>
<div style="height: 10px; flex-grow:1.6;"></div> <div style="height: 10px; flex-grow:1.6;"></div>
<div style="height: 10.7px; flex-grow:1.1;"></div> <div style="height: 10.7px; flex-grow:1.1;"></div>
</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="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="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> <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 style="height: 10.7px; flex-grow:1.1;"></div>
</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: 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 style="height: 10px; flex-grow:1;"></div> <div style="height: 10px; flex-grow:1;"></div>
</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: 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 style="height: 10px; flex-grow:1;"></div> <div style="height: 10px; flex-grow:1;"></div>
</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: 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 style="height: 10px; flex-grow:1;"></div> <div style="height: 10px; flex-grow:1;"></div>
</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: 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 style="height: 10px; flex-grow:1;"></div> <div style="height: 10px; flex-grow:1;"></div>
</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>
<div style="height: 10px; flex-grow:1;"> <div style="height: 10px; flex-grow:1;">
<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 style="height: 10px; flex-grow:1;"></div>
</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>
<div style="width: 10px; flex-grow:1;"> <div style="width: 10px; flex-grow:1;">
<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 style="width: 10px; flex-grow:1;"></div>
</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;"></div>
<div style="height: 100%; flex-grow:1; flex-direction: column;"> <div style="height: 100%; flex-grow:1; flex-direction: column;">
<div style="width: 100%; flex-grow:1;"></div> <div style="width: 100%; flex-grow:1;"></div>

View File

@@ -431,11 +431,6 @@ function getRoundedSize(node) {
function calculateTree(root, roundToPixelGrid) { function calculateTree(root, roundToPixelGrid) {
var rootLayout = []; 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++) { for (var i = 0; i < root.children.length; i++) {
var child = root.children[i]; var child = root.children[i];
var layout = { var layout = {
@@ -453,11 +448,9 @@ function calculateTree(root, roundToPixelGrid) {
: [], : [],
}; };
if (roundToPixelGrid) {
var size = getRoundedSize(child); var size = getRoundedSize(child);
layout.width = size.width; layout.width = size.width;
layout.height = size.height; layout.height = size.height;
}
rootLayout.push(layout); rootLayout.push(layout);
} }

View File

@@ -1,4 +1,14 @@
bintrayUsername= # Project-wide Gradle settings.
bintrayApiKey=
bintrayGpgPassword= org.gradle.jvmargs=-Xmx1536M
dryRun=false
VERSION_NAME=1.5.2-SNAPSHOT
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,8 +3,8 @@ apply plugin: 'com.android.library'
apply plugin: 'com.github.dcendents.android-maven' apply plugin: 'com.github.dcendents.android-maven'
apply plugin: 'maven-publish' apply plugin: 'maven-publish'
version = '1.4.2' group = GROUP
group = 'com.facebook.yoga' version = VERSION_NAME
android { android {
compileSdkVersion rootProject.compileSdkVersion compileSdkVersion rootProject.compileSdkVersion
@@ -41,7 +41,10 @@ android {
java.srcDir 'com' java.srcDir 'com'
manifest.srcFile 'AndroidManifest.xml' manifest.srcFile 'AndroidManifest.xml'
res.srcDirs = ['res'] res.srcDirs = ['res']
jniLibs.srcDirs = ['build/buck-out/jniLibs'] }
test {
java.srcDirs 'tests'
} }
} }
} }
@@ -50,6 +53,7 @@ dependencies {
compile 'com.google.code.findbugs:jsr305:3.0.1' compile 'com.google.code.findbugs:jsr305:3.0.1'
compile 'com.facebook.soloader:soloader:0.2.0' compile 'com.facebook.soloader:soloader:0.2.0'
provided project(':yoga:proguard-annotations') provided project(':yoga:proguard-annotations')
testCompile 'junit:junit:4.12'
} }
task sourcesJar(type: Jar) { task sourcesJar(type: Jar) {
@@ -73,4 +77,4 @@ ext {
bintrayName = 'com.facebook.yoga:yoga' 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. * Copyright (c) 2014-present, Facebook, Inc.
* All rights reserved. * All rights reserved.
* *

View File

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

View File

@@ -1,4 +1,4 @@
/** /*
* Copyright (c) 2014-present, Facebook, Inc. * Copyright (c) 2014-present, Facebook, Inc.
* All rights reserved. * All rights reserved.
* *
@@ -20,6 +20,7 @@ public class YogaConfig {
} }
long mNativePointer; long mNativePointer;
private YogaLogger mLogger;
private native long jni_YGConfigNew(); private native long jni_YGConfigNew();
public YogaConfig() { public YogaConfig() {
@@ -51,4 +52,30 @@ public class YogaConfig {
public void setUseWebDefaults(boolean useWebDefaults) { public void setUseWebDefaults(boolean useWebDefaults) {
jni_YGConfigSetUseWebDefaults(mNativePointer, 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. * Copyright (c) 2014-present, Facebook, Inc.
* All rights reserved. * All rights reserved.
* *

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,4 +1,4 @@
/** /*
* Copyright (c) 2014-present, Facebook, Inc. * Copyright (c) 2014-present, Facebook, Inc.
* All rights reserved. * All rights reserved.
* *
@@ -13,9 +13,7 @@ import com.facebook.proguard.annotations.DoNotStrip;
@DoNotStrip @DoNotStrip
public enum YogaExperimentalFeature { public enum YogaExperimentalFeature {
ROUNDING(0), WEB_FLEX_BASIS(0);
WEB_FLEX_BASIS(1),
MIN_FLEX_FIX(2);
private int mIntValue; private int mIntValue;
@@ -29,9 +27,7 @@ public enum YogaExperimentalFeature {
public static YogaExperimentalFeature fromInt(int value) { public static YogaExperimentalFeature fromInt(int value) {
switch (value) { switch (value) {
case 0: return ROUNDING; case 0: return WEB_FLEX_BASIS;
case 1: return WEB_FLEX_BASIS;
case 2: return MIN_FLEX_FIX;
default: throw new IllegalArgumentException("Unknown enum value: " + value); default: throw new IllegalArgumentException("Unknown enum value: " + value);
} }
} }

View File

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

View File

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

View File

@@ -1,4 +1,4 @@
/** /*
* Copyright (c) 2014-present, Facebook, Inc. * Copyright (c) 2014-present, Facebook, Inc.
* All rights reserved. * All rights reserved.
* *
@@ -17,7 +17,8 @@ public enum YogaLogLevel {
WARN(1), WARN(1),
INFO(2), INFO(2),
DEBUG(3), DEBUG(3),
VERBOSE(4); VERBOSE(4),
FATAL(5);
private int mIntValue; private int mIntValue;
@@ -36,6 +37,7 @@ public enum YogaLogLevel {
case 2: return INFO; case 2: return INFO;
case 3: return DEBUG; case 3: return DEBUG;
case 4: return VERBOSE; case 4: return VERBOSE;
case 5: return FATAL;
default: throw new IllegalArgumentException("Unknown enum value: " + value); default: throw new IllegalArgumentException("Unknown enum value: " + value);
} }
} }

View File

@@ -1,4 +1,4 @@
/** /*
* Copyright (c) 2014-present, Facebook, Inc. * Copyright (c) 2014-present, Facebook, Inc.
* All rights reserved. * All rights reserved.
* *
@@ -18,5 +18,5 @@ import com.facebook.proguard.annotations.DoNotStrip;
@DoNotStrip @DoNotStrip
public interface YogaLogger { public interface YogaLogger {
@DoNotStrip @DoNotStrip
void log(YogaLogLevel level, String message); void log(YogaNode node, YogaLogLevel level, String message);
} }

View File

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

View File

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

View File

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

View File

@@ -1,4 +1,4 @@
/** /*
* Copyright (c) 2014-present, Facebook, Inc. * Copyright (c) 2014-present, Facebook, Inc.
* All rights reserved. * All rights reserved.
* *
@@ -28,12 +28,6 @@ public class YogaNode {
* Get native instance count. Useful for testing only. * Get native instance count. Useful for testing only.
*/ */
static native int jni_YGNodeGetInstanceCount(); static native int jni_YGNodeGetInstanceCount();
static native void jni_YGLog(int level, String message);
private static native void jni_YGSetLogger(Object logger);
public static void setLogger(YogaLogger logger) {
jni_YGSetLogger(logger);
}
private YogaNode mParent; private YogaNode mParent;
private List<YogaNode> mChildren; private List<YogaNode> mChildren;
@@ -667,4 +661,14 @@ public class YogaNode {
public Object getData() { public Object getData() {
return mData; return mData;
} }
private native void jni_YGNodePrint(long nativePointer);
/**
* Use the set logger (defaults to adb log) to print out the styles, children, and computed
* layout of the tree rooted at this node.
*/
public void print() {
jni_YGNodePrint(mNativePointer);
}
} }

View File

@@ -0,0 +1,36 @@
/*
* 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.
*/
package com.facebook.yoga;
import com.facebook.proguard.annotations.DoNotStrip;
@DoNotStrip
public enum YogaNodeType {
DEFAULT(0),
TEXT(1);
private int mIntValue;
YogaNodeType(int intValue) {
mIntValue = intValue;
}
public int intValue() {
return mIntValue;
}
public static YogaNodeType fromInt(int value) {
switch (value) {
case 0: return DEFAULT;
case 1: return TEXT;
default: throw new IllegalArgumentException("Unknown enum value: " + value);
}
}
}

View File

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

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