Compare commits

...

64 Commits

Author SHA1 Message Date
Lukas Wöhrl
4f5c7ed6af Fix align-content:strech overriding align-item
Summary:
Fix for #413. This was a hangover from a previous attept to fix other align-content problems.
Closes https://github.com/facebook/yoga/pull/417

Reviewed By: astreet

Differential Revision: D4604727

Pulled By: emilsjolander

fbshipit-source-id: 92fd31a385d8182c6b201c891d5ae478372d525d
2017-02-23 08:31:05 -08:00
Robert Spencer
60ffa1953b Gradle for android library
Summary: Adds a buildscript for gradle as well as bintray upload capabilities for the YogaLayout library

Reviewed By: emilsjolander

Differential Revision: D4604712

fbshipit-source-id: bacbcc20b7ed6ee8689130287a48bd5d3826298c
2017-02-23 05:07:20 -08:00
Robert Spencer
5519a73087 Gradle for java library
Summary: This builds the java bindings with gradle, and adds a script for Facebook employees to upload the generated artifacts to JCenter.

Reviewed By: emilsjolander

Differential Revision: D4597335

fbshipit-source-id: 4c01695a8638000a417bfb49deba4b9b9b4e114b
2017-02-23 05:07:20 -08:00
Lukas Wöhrl
67717a7872 Force scalefactor=1 for gentest to fix issues with test generation on hdpi devices
Summary:
Since my new main work maschine is a hdpi device, all the gentests with rounding are producing different outputs.

This PR force the scalefactor=1 for gentest to fix issues with generation on hdpi devices.
Closes https://github.com/facebook/yoga/pull/434

Differential Revision: D4604724

Pulled By: emilsjolander

fbshipit-source-id: ce4036ae71a45775280e0504f20c06a4622ccceb
2017-02-23 01:26:55 -08:00
Aljoscha Meyer
4522d4b8aa Fix a typo in C API documentation
Summary:
Change "Certain nodes need *to* ability to measure themselves" to "Certain nodes need *the* ability to measure themselves".
Closes https://github.com/facebook/yoga/pull/430

Differential Revision: D4600091

Pulled By: emilsjolander

fbshipit-source-id: d20693b47291e79bd8c5f76e57d6dff2444333d2
2017-02-22 12:57:21 -08:00
Robert Spencer
d7ca339c27 Fix android height attribute
Summary: The attribute for height was incorrectly assumed to be type `float` which led to it not being explicitly defined.  It is actually a dimension.

Reviewed By: emilsjolander

Differential Revision: D4588629

fbshipit-source-id: 56c7e460d27528823944852d682e7f26bf908292
2017-02-21 00:12:09 -08:00
Emil Sjolander
6b39165801 Fix behaviour of wrapping container within align-items: not stretch
Summary: When a container's children wrap the container should match the parent size and not wrap to the new size of the children. This is confirmed behavior in chrome.

Reviewed By: astreet

Differential Revision: D4578614

fbshipit-source-id: 5d22a3a673735587384d775189158a87bb1d457d
2017-02-20 07:28:42 -08:00
Maël Nison
78ade6cfb5 Improve JS Travis testing
Summary:
Build emscripten js file on travis
Closes https://github.com/facebook/yoga/pull/397

Reviewed By: arcanis

Differential Revision: D4579563

Pulled By: emilsjolander

fbshipit-source-id: fa5f92fd26f758fb617e428c07aabf2dccd63b37
2017-02-20 05:41:38 -08:00
Robert Spencer
3f68b4f76b Travis install android sdk and api for build
Summary:
Travis android build is failing with

    BUILD FAILED: Google APIs not found in /usr/local/opt/android-sdk/add-ons/addon-google_apis-google-19/libs.
    Please run '/usr/local/opt/android-sdk/tools/android sdk' and select both 'SDK Platform' and 'Google APIs' under Android (API 19)

This should fix that error

Reviewed By: emilsjolander

Differential Revision: D4588053

fbshipit-source-id: e57d635141e8aede5803b919ee5a28a60c5e667c
2017-02-20 02:26:16 -08:00
Robert Spencer
521aab5fcc Omptimisation on layout and measure children of YogaLayout
Summary:
You must measure children before you lay them out, and YogaLayout didn't do this.  This fixes that.

We also only recompute the yoga tree if the YogaLayout is laid out with a different size to what it's been measured as.

Reviewed By: emilsjolander

Differential Revision: D4572237

fbshipit-source-id: 6e86dbf939b06338c1dc2a37b7dafafd548dd390
2017-02-19 23:58:09 -08:00
Rui Marinho
42492596b3 Changes for nuget and CI support
Summary:
For now i setup the CI using VSTS (Visual Studio Team Services) , i m using my own account, but i want to move this to a Travis setup so it would be easy ported to Facebook own build system. We can also take a look on how buck can help with this.

Here's a overview of my dashboard for the build and release process on VSTS:

<img width="1084" alt="screen shot 2017-02-16 at 23 52 07" src="https://cloud.githubusercontent.com/assets/1235097/23046869/ff4dcada-f4a3-11e6-8d09-fb8974fb58d4.png">

The all process is pretty simple, there's a few tricks here and there, but the basic steps are:

<img width="1036" alt="builds" src="https://cloud.githubusercontent.com/assets/1235097/23046874/0cb95fc2-f4a4-11e6-8fd8-3048be7ffd9d.png">

These run for every commit and publish the artifacts, then the release lane takes that artifacts and builds a nuget, after that (and it's not implemented yet) we run UI Tests on devices Android , iOS for the nuget created and run tests on UWP and .net45 on both windows and OS X so
Closes https://github.com/facebook/yoga/pull/408

Reviewed By: emilsjolander

Differential Revision: D4576542

Pulled By: splhack

fbshipit-source-id: 66e0e4c1cb3721ed7aa7118e4e226b6ec575fea8
2017-02-17 10:41:47 -08:00
Eric Rozell
b24e728666 Adds UWP build for yoga.dll
Summary:
The existing Yoga.vcxproj works great for Desktop apps, but breaks when you try to use the resulting DLL on mobile, Xbox, etc. This change compiles the DLL for the UWP and the Windows Store.
Closes https://github.com/facebook/yoga/pull/401

Reviewed By: emilsjolander

Differential Revision: D4561354

Pulled By: splhack

fbshipit-source-id: 643ad4ed1ffc73719d35974e2d357c37d5b1d1c4
2017-02-16 11:42:30 -08:00
Kazuki Sakamoto
4fe0b810e1 Fix callbacks on AOT
Summary:
Based on the idea of #386 by rmarinho
Closes https://github.com/facebook/yoga/pull/388

Reviewed By: emilsjolander

Differential Revision: D4570778

Pulled By: splhack

fbshipit-source-id: 362983deaf6f040c42b3db8205b711e7e5e60eaf
2017-02-16 11:15:36 -08:00
Rui Marinho
8deed174f5 Fix callbacks on AOT
Summary:
When using AOT mode on Mono one can't use instance methods for callbacks, the compiler needs the MonoPInvokeCallback attribute on a static method to know how to get back to the managed world.
This worked fine without the change in JIT mode.

I not sure if we should use a __MONO__ flag for this stuff as this could be needed for other usage that not only on iOS.

~~The adicional change is that one should as good practice call Dispose on the YogaNode when using callbacks to make sure we remove the handler from our dictionary, i was trying to write a test for this.. but i saw TestMeasureFuncWithDestructor was already there, but it doesn't seem correct to me, can you check splhack.~~
Closes https://github.com/facebook/yoga/pull/386

Reviewed By: emilsjolander

Differential Revision: D4546030

Pulled By: splhack

fbshipit-source-id: 121d44a2ecd14d754b9614493db6ac15fca02da2
2017-02-16 11:15:36 -08:00
Kazuki Sakamoto
2184547094 Fix unit test for flexBasis
Summary: Fix unit test for flexBasis

Reviewed By: emilsjolander

Differential Revision: D4572394

fbshipit-source-id: ce0b3cd28b5c8a9910106308c561c95d1b3866e9
2017-02-16 10:26:33 -08:00
Lukas Wöhrl
8eda4dc040 Removed duplicate code by calculating with mainSize/crossSize
Summary:
This PR removes some duplicate code by calculating with ```mainSize```/```crossSize``` and converting that to ```width``` or ```height``` at the end. See #395 .
Closes https://github.com/facebook/yoga/pull/396

Reviewed By: astreet

Differential Revision: D4564713

Pulled By: emilsjolander

fbshipit-source-id: 0b24e69cc9dc75cdf93deeb6c076dcacf134c6d8
2017-02-16 07:41:32 -08:00
Kazuki Sakamoto
4d4db92a46 Fix unit test
Summary: Fix #406 #407

Reviewed By: emilsjolander

Differential Revision: D4569680

fbshipit-source-id: a7b78674ed483d8619bd4aaa6e463203ef619c9b
2017-02-16 07:41:32 -08:00
Emil Sjolander
ea8b7e0c91 Fix up some small issues with YGUnitAuto
Summary: There are still some pieces of RN which does not handle YGUnitAuto and makes use of either the value being nan or the unit being undefined. This diff makes this more robust to those kinds of situations.

Reviewed By: wwjholmes

Differential Revision: D4567045

fbshipit-source-id: ace5fd89bd534a6bb5ec7dba0c3afbf13d62d7c9
2017-02-16 06:58:47 -08:00
Robert Spencer
6928957096 Set ANDROID_SDK and ANDROID_HOME for Travis build
Summary: Travis builds are failing due to ANDROID_SDK not being set.  So we set both it and ANDROID_HOME to where homebrew should have created a link to the installation.

Reviewed By: emilsjolander

Differential Revision: D4571703

fbshipit-source-id: a6dc4eb07006dc8baefb6ca938111ff256c6f018
2017-02-16 02:58:45 -08:00
Robert Spencer
b680b726d1 Add Android Travis badge to README.md
Summary: Adds the Travis build badge for the android target to the README.md

Reviewed By: emilsjolander

Differential Revision: D4571693

fbshipit-source-id: a5110dac7d86989cc4a14b858c63d59332072869
2017-02-16 02:44:53 -08:00
Robert Spencer
fbd692c449 Remove splash screen activity from sample app
Summary: The yoga splash screen that runs at the beginning of the app is unnecessary and can be removed for simplicty.

Reviewed By: emilsjolander

Differential Revision: D4571624

fbshipit-source-id: 3eb12f7c3447805f4546bd192df9670c5427572a
2017-02-16 02:44:50 -08:00
Kazuki Sakamoto
2199a7908d Fix BUCK
Summary:
- Deleted a non-existent include
- Fix #404

Reviewed By: bolinfest

Differential Revision: D4569377

fbshipit-source-id: 34161b28be8bab476b30442596314899463814ef
2017-02-15 16:58:04 -08:00
Dustin Shahidehpour
59704f1508 Backed out changeset 762168ced81e
Summary: Acting weird with Xcode 8.2.1

Differential Revision: D4567880

fbshipit-source-id: e5a200b59780ac3dd8f75b6152054778b9fc786c
2017-02-15 14:35:46 -08:00
Lukas Wöhrl
20536923d6 flex-wrap: wrap-reverse support
Summary:
I couldn't resist to do this 😄 #394

This adds ```flex-wrap: wrap-reverse```

I think we hit a edge case here:
https://stackoverflow.com/questions/33891709/when-flexbox-items-wrap-in-column-mode-container-does-not-grow-its-width

as is differs here from chrome, but I think that yoga is here more correct.

So I haven't added this test yet as this would fail against chrome, as chrome outputs a width of 30 for root, whereas yoga gets a width of 60 here, which I think is correct. Strangely the output of ```flex-wrap:wrap``` is in jsfiddle also only with a (visual) width of 30 on chrome, while the tests gets generated with 60.

```html
<div id="wrap_reverse_column" style="height: 100px; flex-wrap: wrap-reverse">
  <div style="height: 30px; width: 30px;"></div>
  <div style="height: 30px; width: 30px;"></div>
  <div style="height: 30px; width: 30px;"></div>
  <div style="height: 30px; width: 30px;"></div>
</div>
```

Looking forward what you think here emilsjolander
Closes https://github.com/facebook/yoga/pull/398

Reviewed By: astreet

Differential Revision: D4564711

Pulled By: emilsjolander

fbshipit-source-id: 33dc055abd8444b2aa7796ef90bd7ec99e961bb8
2017-02-15 13:42:47 -08:00
Lukas Wöhrl
bba7289537 Remove no longer valid limitiation hints
Summary:
Remove no longer valid limitiation hints, according to percentag, auto margins and flex values.
Closes https://github.com/facebook/yoga/pull/402

Reviewed By: astreet

Differential Revision: D4564709

Pulled By: emilsjolander

fbshipit-source-id: ef7f37921644b4d315c7a84552861713061b33e1
2017-02-15 08:26:56 -08:00
Dustin Shahidehpour
04d1ccc085 Create Xcode project so it's much easier to run tests.
Summary:
I don't even know how people have been running tests (unless they install BUCK). This creates a workspace to make it much easier to run tests.
Closes https://github.com/facebook/yoga/pull/400

Differential Revision: D4565290

Pulled By: dshahidehpour

fbshipit-source-id: 762168ced81e517126ac05c92bb27ccad0d9d305
2017-02-15 08:11:36 -08:00
Joel Marcey
a7e7c5eb52 Add actual Google Analytics ID
Summary:
We still had the default one from the template.
Closes https://github.com/facebook/yoga/pull/403

Reviewed By: astreet

Differential Revision: D4564708

Pulled By: emilsjolander

fbshipit-source-id: ec76325e0dca34f89e5a920627ced7fa812827de
2017-02-15 07:47:25 -08:00
David Hart
9d2839f8ca Rename YGUnitPixel to YGPoint...
Summary:
...to reflect the modern world we live in with dynamic DPI platforms :)
Closes https://github.com/facebook/yoga/pull/375

Reviewed By: dshahidehpour

Differential Revision: D4528518

Pulled By: emilsjolander

fbshipit-source-id: e422bd4ae148e02c598a7b484a6adfa8c0e1e0c9
2017-02-14 14:27:48 -08:00
Lukas Wöhrl
1146013e9e Feature auto margin
Summary:
Even so I know there are some opinions against ```margin: 0 auto``` it's still part of the spec: https://www.w3.org/TR/css-flexbox-1/#auto-margins and pretty usefull if you have to position via ```justify-content```.

This PR adds an implementation for that.

It adds an additonal ```YGUnitAuto``` and margins got ```YGNodeStyleSetMarginAuto``` functions as well.
Closes https://github.com/facebook/yoga/pull/357

Reviewed By: astreet

Differential Revision: D4501142

Pulled By: emilsjolander

fbshipit-source-id: 86519f8632496f46e78a7c9dbc5b21e212e3e0c7
2017-02-14 14:27:48 -08:00
Michael Bolin
8a91c0a0e5 Attempt to fix open source Yoga build.
Reviewed By: emilsjolander

Differential Revision: D4557733

fbshipit-source-id: b99701e9c1ec56fb147aa4cc738549df90aa7016
2017-02-14 10:45:02 -08:00
Emil Sjolander
a1c75454e9 Fix align-content strech with multiple lines
Summary: This is an update of facebook/yoga#368 which was reverted. It fixes support for align-content: strech with multiple lines. The problem with the last attempt at solving this was that align-items:stretch was interfering. We handle this now by detecting when the flex basis of the children hints at them overflowing. This is not 100% correct as the size of the items could change when remeasuring but it will work in 99% of cases.

Reviewed By: astreet

Differential Revision: D4551234

fbshipit-source-id: 2964f19cf415991dc55dfa2caa4868cb00c56bd0
2017-02-14 09:26:10 -08:00
Robert Spencer
ad3963daa6 Travis build of sample app
Summary: Build the sample app in travis

Reviewed By: emilsjolander

Differential Revision: D4558310

fbshipit-source-id: b730a7bc9036054a17c6204a93c63ea2064e0943
2017-02-14 08:41:42 -08:00
Robert Spencer
a66339d63c Separate YogaLayout library from sample app
Summary: The sample app has library-like elements (i.e. the `YogaLayout` and associated files).  This separates them out into a separate tree.

Reviewed By: emilsjolander

Differential Revision: D4558263

fbshipit-source-id: 33f8cec99661ef20e0e882663b554c12ae33c12f
2017-02-14 08:13:22 -08:00
Robert Spencer
d0bdd4dc91 Adds Android docs to landing page
Summary: Adds a simple "photo with poster and comment" layout to the landing page as an example for Android, along with the XML.

Reviewed By: emilsjolander

Differential Revision: D4558478

fbshipit-source-id: c7302321a67e99f5853358e711ff538d192f06e9
2017-02-14 08:13:22 -08:00
Robert Spencer
d24078be31 Move res files to be more gradle-esque
Summary: Resources don't usually live under the package name.  We want to gradle build this soon, so making the directory structure as traditional as possible is best.

Reviewed By: emilsjolander

Differential Revision: D4557978

fbshipit-source-id: 7f80599201fe007a895e52bc5141425f9a83eb51
2017-02-14 03:14:59 -08:00
Robert Spencer
f251648726 Add android docs
Summary: Adds docs for how to build the Android sample app and use the `YogaLayout`.

Reviewed By: emilsjolander

Differential Revision: D4557955

fbshipit-source-id: 49a3b8fde20de81a895244ffcecbd5bf392455b0
2017-02-14 02:48:14 -08:00
Emil Sjolander
b587ecb30f Fix travis builds
Summary: && instead of ; and only update xctools if needed

Reviewed By: passy

Differential Revision: D4558044

fbshipit-source-id: 90d55bf0147026e527b238365835d803a4bee7fb
2017-02-14 02:28:49 -08:00
Robert Spencer
a580712b2f Move in yoga sample android app
Summary: The sample app is simply moved into the repo.  A few libraries are included and the buck targets rearranged.

Reviewed By: emilsjolander

Differential Revision: D4528129

fbshipit-source-id: 3e9e779857cd9219711a939876c9275d75e09929
2017-02-14 00:11:38 -08:00
Michael Bolin
ce5d52b54e Update a number of build files in fbandroid/xplat to use the py_sdk build defs.
Summary:
I'm cleaning up these files in their own revision because I want to trigger
dirsync sandcastle separately from my other cleanup.

Reviewed By: mzlee

Differential Revision: D4549131

fbshipit-source-id: 1d45118256d8b517dea7a2b6c9e50bca1ccc1b0c
2017-02-13 22:26:31 -08:00
Dustin Shahidehpour
55fe6f0bc9 Add isDirty property and make markDirty less crashy/more performant.
Summary: For some internal Instagram diffs, and some external ones (auto-detection of dirty nodes). We need to give the dirty properties a little love. This adds a getter to find out if your node is dirty, and makes sure that the leaf node is properly setup before it is marked dirty to prevent a crash.

Reviewed By: emilsjolander

Differential Revision: D4549241

fbshipit-source-id: 36eda6fdb4ea7f968d126aab6da67896f4a01d40
2017-02-13 10:26:58 -08:00
Emil Sjolander
abf142ea3f Fix more travis file errors
Summary: and add badges to readme

Reviewed By: passy

Differential Revision: D4551571

fbshipit-source-id: c6eafe480e3667252eadc96c548c3b3c85046389
2017-02-13 09:41:35 -08:00
Dustin Shahidehpour
ae9f89b5d1 Add helper function for bulk updates.
Summary:
Currently, our configuration of Views looks like this:

```objc
UIView *view = [[UIView alloc] initWithFrame:CGRectZero];
view.yoga.isEnabled = YES;
view.yoga.height = 50;
view.yoga.width = 50;
```

Every time that we access `view.yoga` we have to access the associated object on `UIView` to get the `YGLayout`. This adds an extra `objc_msgSend` which increases binary size, and is slight perf impact.

This diff creates a way to modify the `YGLayout` with only a single `objc_msgSend`. Here's the new syntax:

```objc
UIView *view = [[UIView alloc] initWithFrame:CGRectZero];
[view configureLayoutWithBlock:^void(YGLayout *layout){
  layout.isEnabled = YES
  layout.height = 50;
  layout.width = 50;
}];
```

Here's the Swift version:
```swift
let view = UIView(frame: .zero)
view.configureLayout { (layout) in
  layout.isEnabled = true
  layout.height = 50
  layout.width = 50
}
```
Closes https://github.com/facebook/yoga/pull/393

Reviewed By: emilsjolander

Differential Revision: D4550382

Pulled By: dshahidehpour

fbshipit-source-id: 76d797d1e0de8e5dc767e02180a7fc440a70212e
2017-02-13 09:28:12 -08:00
Dustin Shahidehpour
058761e16e Give YogaKitSample some love, Convert it to a Swift Project
Summary:
To date, our sample project was lacking. There is still a lot of work that can be done to improve, but, this is a step in the right direction.

Here are the changes in this commit:
1. The project is written in Swift.
2. Created new CollectionView (via [IGListKit](https://github.com/instagram/iglistkit)), making it very easy to add new examples.
3. New examples for basic layouts, and including/excluding layouts on the fly.

Here's a video!

![](https://media.giphy.com/media/l0ExcvTLa0ADdawRa/giphy.gif)
Closes https://github.com/facebook/yoga/pull/392

Reviewed By: emilsjolander

Differential Revision: D4550379

Pulled By: dshahidehpour

fbshipit-source-id: 64a07acf96c1887f1d2ad0c54971fcedb64334a0
2017-02-13 09:13:43 -08:00
Kazuki Sakamoto
ad8c6225fd Build i386 for iOS and macOS
Summary: Closes https://github.com/facebook/yoga/pull/391

Reviewed By: emilsjolander

Differential Revision: D4549469

Pulled By: splhack

fbshipit-source-id: 7500b7235218f9a4f564adb36044303dff520fd6
2017-02-13 08:26:20 -08:00
Emil Sjolander
1cbadf5f54 Fix mistakes in travis file
Summary: Fix yaml errors

Reviewed By: passy

Differential Revision: D4551330

fbshipit-source-id: d17087cf51f9556c7015ea0fc4ab11fec44917f2
2017-02-13 06:56:27 -08:00
Emil Sjolander
e7021715b8 Split travis builds into multiple runs
Summary: Split travis into one run per language. This should improve build speed as well as improve signal as to what is failing.

Reviewed By: dshahidehpour

Differential Revision: D4551194

fbshipit-source-id: 36bc60193b4b287352073ab62a7bd053b15eaedf
2017-02-13 05:27:03 -08:00
Emil Sjolander
0d2749a3fd Revert D4528559: [yoga][PR] Fix align-content strech with multiple lines
Summary: This reverts commit 019e6f85fa452d0c3412f711e3886f0c4452da47

Differential Revision: D4528559

fbshipit-source-id: 4bd82b399cb36acb348f2c6fedcae6b360513424
2017-02-13 01:11:16 -08:00
Dustin Shahidehpour
76fbd628e1 Use correct rounding function when rounding pixels.
Summary: While debugging something at Instagram, I kept seeing a UILabel be truncated when it clearly had enough room to display all its' text. What I realized is that during our pixel rounding, we were losing precision because we were using the incorrect rounding function for floats. Changing from `round()` (which is for doubles) to `roundf()` fixed it.

Reviewed By: amonshiz

Differential Revision: D4549069

fbshipit-source-id: 78a1bb33e315e7c066b7fb625b1f5a28def76515
2017-02-11 19:56:08 -08:00
Dustin Shahidehpour
15309d2bdd Update README.md
Summary: Closes https://github.com/facebook/yoga/pull/389

Differential Revision: D4549243

Pulled By: dshahidehpour

fbshipit-source-id: 2c8d6d78af9f98994ad2f5f028494ae743c354b4
2017-02-11 14:12:51 -08:00
Dustin Shahidehpour
4f6924a0c1 BREAKING CHANGE: rename applyLayout to applyLayoutPreservingOrigin.
Summary: Will update on Monday

Reviewed By: emilsjolander

Differential Revision: D4545786

fbshipit-source-id: f8189d82f1c64cd1eac532fd2dfaa9aea35d6004
2017-02-11 11:26:07 -08:00
Lukas Wöhrl
063f65d065 Fix align-content strech with multiple lines
Summary:
Fixes ```align-content:strech``` on nodes without specified cross dimension, if there are multiple lines. Currently it uses the full height of the parent, but it has to use the line height. As we don't know the number of lines until here, we need to realign the relevant children.
Closes https://github.com/facebook/yoga/pull/368

Reviewed By: gkassabli

Differential Revision: D4528559

Pulled By: emilsjolander

fbshipit-source-id: 019e6f85fa452d0c3412f711e3886f0c4452da47
2017-02-11 08:41:45 -08:00
Lukas Wöhrl
adf8691093 Fix resolving bug on changing layout and optimized memory usage
Summary:
Due to the changes in 46817a38. We have a bug if the layout changes.

This PR fixes this bug and adds a test for it.

Additionally it correctly marks negative percentage values as undefined dim.

It also changes the ```resolvedDimensions``` to use a reference instead of the full value in order to minimize the memory requirement of a ```YGNode``` and reduces the copying of the ```YGValue```.
Closes https://github.com/facebook/yoga/pull/379

Reviewed By: gkassabli

Differential Revision: D4528552

Pulled By: emilsjolander

fbshipit-source-id: c024fe3a009c3788af319b689858ea3374c46477
2017-02-11 08:41:45 -08:00
Lukas Wöhrl
6a7ad2125d Add support for space-between and space-around on align-content
Summary:
Adds the two missing alignments ```space-between``` and ```space-around``` for ```align-content``` . Those values are a noop on ```align-items``` in order to prevent a breaking changes for an additional enum.

Fix #229
Closes https://github.com/facebook/yoga/pull/364

Reviewed By: gkassabli

Differential Revision: D4528561

Pulled By: emilsjolander

fbshipit-source-id: ea6291b6dd22cef05d9eec03893250d50371236e
2017-02-11 08:41:45 -08:00
Lukas Wöhrl
247aa26d3e Make enums.py c header output resistent to format.sh
Summary:
This PR changes the enums.py to create the header the same as format.sh would layout it. Reduces the clutter due to missed format.sh calls after enums.py generation.
Closes https://github.com/facebook/yoga/pull/380

Reviewed By: gkassabli

Differential Revision: D4529593

Pulled By: emilsjolander

fbshipit-source-id: 7281e0d500f79459c19cc8fe6dbc8fd77f0a537c
2017-02-11 08:41:45 -08:00
Dustin Shahidehpour
3c9f620c77 BREAKING CHANGE: Computed edge values are no longer returned on concrete properties, fix tests.
Summary:
Now that the Yoga library supports percentage values, the results returned from it's API were changed.

`YGNodeStyleGetPadding` returns the explicit value that you set, whereas `YGNodeLayoutGetPadding` returns the computed value. Since we are planning to build support for percentages, I'm modifying our API so that it strictly returns the value that was set. As a result:

```
view.yoga.margin = 10;

// view.yoga.margin == 10
// view.yoga.marginLeftWidth == 0
// view.yoga.marginRightWidth == 0
// etc.
```

Reviewed By: emilsjolander

Differential Revision: D4543471

fbshipit-source-id: a731025cd4b47e9f1a559c766494fc5a259291ae
2017-02-11 08:28:50 -08:00
Emil Sjolander
e0e2a61dfc Use Float.compare in java equals
Summary: Handles nans. Also if the unit is undefined there is no need to check the value.

Reviewed By: astreet

Differential Revision: D4531805

fbshipit-source-id: 723e15381e9fa39837a4c99f726501eda26af11b
2017-02-11 06:27:15 -08:00
Emil Sjolander
168ae4099d Always return undefined value if nothing is set
Summary: This reflects a check to native code where style values will always return the value that was set on them and default to undefined.

Reviewed By: astreet

Differential Revision: D4531779

fbshipit-source-id: 97a789e70dcf0fb5174e2039991e7a2b27f45f01
2017-02-11 06:27:12 -08:00
Emil Sjolander
6ceb4af2d4 Expose layout border to java
Summary: Expose layout border to java

Reviewed By: astreet

Differential Revision: D4543284

fbshipit-source-id: 6030915fc6f758e785a688f94c8ffbec7fbac8b8
2017-02-11 06:27:04 -08:00
Emil Sjolander
240c2dd657 Fix min/max not overriding width/height
Summary:
Two bugs:
1. Min/Max width/height should have higher priority than width/height
2. custom measure nodes percentages should be based in parent size like everything else.

Differential Revision: D4537576

fbshipit-source-id: c003f723f424afbca63170d41e54fd5ff837926d
2017-02-11 05:28:10 -08:00
Rui Marinho
a5b94ebd0c Add YogaDisplay to shared project
Summary: Closes https://github.com/facebook/yoga/pull/383

Reviewed By: emilsjolander

Differential Revision: D4537332

Pulled By: splhack

fbshipit-source-id: d3068fc09e567c9f175bdcc8974c8069575ef5f7
2017-02-10 11:13:24 -08:00
Dustin Shahidehpour
5037c2f365 Preserve the origin of the root view.
Summary: Currently, we have an issue in YogaKit where it ignores the preexisting bounds a root view. There are multiple fixes for this, but the easiest one for developer experience is to apply the preexisting bounds of the root view to it's frame after layout calculation.

Reviewed By: emilsjolander

Differential Revision: D4537173

fbshipit-source-id: ccef8b1c1398ea299b4e5710abe597378347a48d
2017-02-09 13:10:59 -08:00
Dustin Shahidehpour
ef05404bee Bump YogaKit podspec.
Summary: See commit message. #accept2ship

Reviewed By: emilsjolander

Differential Revision: D4536585

fbshipit-source-id: 808e39e7a38f470c67459a42686e095d8b5e5fc6
2017-02-09 08:46:30 -08:00
Dustin Shahidehpour
3db493665e Bump podspec version.
Summary: See commit message. #accept2ship

Reviewed By: emilsjolander

Differential Revision: D4536570

fbshipit-source-id: 4fc72bd4d9418ea06d24a6ca0cdd6845def30465
2017-02-09 08:26:17 -08:00
Emil Sjolander
737f1cc67c Remove now not needed definition of allow_unsafe_import
Summary: not needed any more

Reviewed By: bolinfest

Differential Revision: D4532533

fbshipit-source-id: 43b4db9a21ae774f7d41187e4e4598e171b7a59c
2017-02-09 03:27:11 -08:00
175 changed files with 25175 additions and 8063 deletions

View File

@@ -1,2 +1,9 @@
[cxx]
gtest_dep = //lib/gtest:gtest
[android]
target = Google Inc.:Google APIs:19
[ndk]
ndk_version = r10e
compiler = clang
app_platform = android-19
cpu_abis = armv7, x86

3
.gitignore vendored
View File

@@ -60,3 +60,6 @@ Pods/
# Carthage/Checkouts
Carthage/Build
# Gradle
.gradle

View File

@@ -10,33 +10,109 @@ osx_image: xcode8.2
language: cpp
compiler: clang
env:
- TARGET=c
- TARGET=java
- TARGET=net
- TARGET=ios
- TARGET=js
- TARGET=android
before_install:
- brew update
- brew update > /dev/null
- brew tap facebook/fb
- brew install buck
- brew cask install java
- brew outdated xctool || brew upgrade xctool
- brew install mono
- export JAVA_HOME=$(/usr/libexec/java_home -v 1.8)
- export PATH=$JAVA_HOME/bin:$PATH
# Java
- |
if [[ $TARGET = "java" ]]; then
brew cask install java &&
export JAVA_HOME=$(/usr/libexec/java_home -v 1.8) &&
export PATH=$JAVA_HOME/bin:$PATH
fi
install:
- cd javascript
- npm install
- cd $TRAVIS_BUILD_DIR
# .NET
- |
if [[ $TARGET = "net" ]]; then
brew install mono
fi
# iOS
- |
if [[ $TARGET = "ios" ]]; then
brew outdated xctool || brew upgrade xctool
fi
# Emscripten (used for js tests)
# Note: cannot be ran on Linux (because it will compile Clang from its sources :|)
- |
if [[ $TARGET = "js" ]]; then
wget -O /tmp/emsdk-portable.tar.gz https://s3.amazonaws.com/mozilla-games/emscripten/releases/emsdk-portable.tar.gz &&
tar xf /tmp/emsdk-portable.tar.gz -C /tmp/ &&
/tmp/emsdk_portable/emsdk install latest >& /dev/null &&
/tmp/emsdk_portable/emsdk activate latest
fi
# Android
- |
if [[ $TARGET = "android" ]]; then
brew cask install java &&
export JAVA_HOME=$(/usr/libexec/java_home -v 1.8) &&
export PATH=$JAVA_HOME/bin:$PATH &&
brew install android-sdk &&
export ANDROID_SDK=/usr/local/opt/android-sdk &&
export ANDROID_HOME=/usr/local/opt/android-sdk
$ANDROID_SDK/tools/android update sdk --filter android-19,addon-google_apis-google-19
fi
# JavaScript
- |
if [[ $TARGET = "js" ]]; then (
cd javascript &&
npm install &&
unset CC && unset CXX && unset LINK &&
source /tmp/emsdk_portable/emsdk_env.sh &&
npm run build:browser
) fi
script:
- buck test //:yoga
- buck test //java:java
- buck test //YogaKit:YogaKitTests --config cxx.default_platform=iphonesimulator-x86_64
- sh csharp/tests/Facebook.Yoga/test_macos.sh
# C
- |
if [[ $TARGET = "c" ]]; then
buck test --verbose 0 //:yoga &&
buck run --verbose 0 //benchmark:benchmark &&
git checkout HEAD^ &&
buck run --verbose 0 //benchmark:benchmark
fi
- cd javascript
- npm run test:all
- npm run bench
- cd $TRAVIS_BUILD_DIR
# Java
- |
if [[ $TARGET = "java" ]]; then
buck test --verbose 0 //java:java
fi
- buck run //benchmark:benchmark
- git checkout HEAD^
- buck run //benchmark:benchmark
# .NET
- |
if [[ $TARGET = "net" ]]; then
sh csharp/tests/Facebook.Yoga/test_macos.sh
fi
# iOS
- |
if [[ $TARGET = "ios" ]]; then
buck test --verbose 0 //YogaKit:YogaKitTests --config cxx.default_platform=iphonesimulator-x86_64
fi
# Android
- |
if [[ $TARGET = "android" ]]; then
buck build --verbose 0 //android/sample:sample
fi
# JavaScript
- |
if [[ $TARGET = "js" ]]; then (
cd javascript &&
npm run test:all &&
npm run bench
) fi

View File

@@ -1,4 +1,11 @@
# Yoga [![Build Status](https://travis-ci.org/facebook/yoga.svg?branch=master)](https://travis-ci.org/facebook/yoga) [![CocoaPods](https://img.shields.io/cocoapods/v/YogaKit.svg)](http://cocoapods.org/pods/YogaKit) [![npm](https://img.shields.io/npm/v/yoga-layout.svg)](https://www.npmjs.com/package/yoga-layout)
# Yoga [![CocoaPods](https://img.shields.io/cocoapods/v/YogaKit.svg)](http://cocoapods.org/pods/YogaKit) [![npm](https://img.shields.io/npm/v/yoga-layout.svg)](https://www.npmjs.com/package/yoga-layout)
[![C Status](https://badges.herokuapp.com/travis/facebook/yoga?env=TARGET=c&label=C)](https://travis-ci.org/facebook/yoga)
[![Java Status](https://badges.herokuapp.com/travis/facebook/yoga?env=TARGET=java&label=Java)](https://travis-ci.org/facebook/yoga)
[![iOS Status](https://badges.herokuapp.com/travis/facebook/yoga?env=TARGET=ios&label=iOS)](https://travis-ci.org/facebook/yoga)
[![.NET Status](https://badges.herokuapp.com/travis/facebook/yoga?env=TARGET=net&label=.NET)](https://travis-ci.org/facebook/yoga)
[![JavaScript Status](https://badges.herokuapp.com/travis/facebook/yoga?env=TARGET=js&label=JavaScript)](https://travis-ci.org/facebook/yoga)
[![Android Status](https://badges.herokuapp.com/travis/facebook/yoga?env=TARGET=android&label=Android)](https://travis-ci.org/facebook/yoga)
## Building
Yoga builds with [buck](https://buckbuild.com). Make sure you install buck before contributing to Yoga. Yoga's main implementation is in C, with bindings to supported languages and frameworks. When making changes to Yoga please ensure the changes are also propagated to these bindings when applicable.

View File

@@ -1,5 +1,6 @@
YOGA_ROOT = '//...'
JAVA_TARGET = '//java:java'
INFER_ANNOTATIONS_TARGET = '//lib/infer-annotations:infer-annotations'
JSR_305_TARGET = '//lib/jsr-305:jsr-305'
JUNIT_TARGET = '//lib/junit:junit'
@@ -8,6 +9,13 @@ SOLOADER_TARGET = '//lib/soloader:soloader'
GTEST_TARGET = '//lib/gtest:gtest'
JNI_TARGET = '//lib/jni:jni'
FBJNI_TARGET = '//lib/fb:fbjni'
APPCOMPAT_TARGET = '//lib/appcompat:appcompat'
ANDROID_SUPPORT_TARGET = '//lib/android-support:android-support'
ANDROID_TARGET = '//android:android'
ANDROID_JAVA_TARGET = '//android/src/main/java/com/facebook/yoga/android:android'
ANDROID_RES_TARGET = '//android:res'
ANDROID_SAMPLE_JAVA_TARGET = '//android/sample/java/com/facebook/samples/yoga:yoga'
ANDROID_SAMPLE_RES_TARGET = '//android/sample:res'
THIS_IS_FBOBJC = False
@@ -28,8 +36,7 @@ BASE_COMPILER_FLAGS = [
def yoga_dep(dep):
return '//' + dep
class allow_unsafe_import:
def __enter__(self):
pass
def __exit__(self, type, value, traceback):
pass
with allow_unsafe_import():
import os.path
def isdir(filename):
return os.path.isdir(filename)

View File

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

View File

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

46
YogaKit/CHANGELOG.md Normal file
View File

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

View File

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

View File

@@ -10,8 +10,25 @@
#import "YGLayout.h"
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
typedef void (^YGLayoutConfigurationBlock)(YGLayout *);
@interface UIView (Yoga)
/**
The YGLayout that is attached to this view. It is lazily created.
*/
@property (nonatomic, readonly, strong) YGLayout *yoga;
/**
In ObjC land, every time you access `view.yoga.*` you are adding another `objc_msgSend`
to your code. If you plan on making multiple changes to YGLayout, it's more performant
to use this method, which uses a single objc_msgSend call.
*/
- (void)configureLayoutWithBlock:(YGLayoutConfigurationBlock)block
NS_SWIFT_NAME(configureLayout(block:));
@end
NS_ASSUME_NONNULL_END

View File

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

View File

@@ -89,9 +89,11 @@
@property (nonatomic, readonly, assign) YGDirection resolvedDirection;
/**
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}.
*/
- (void)applyLayout NS_SWIFT_NAME(applyLayout());
- (void)applyLayoutPreservingOrigin:(BOOL)preserveOrigin
NS_SWIFT_NAME(applyLayout(preservingOrigin:));
/**
Returns the size of the view if no constraints were given. This could equivalent to calling [self
@@ -110,6 +112,12 @@
*/
@property (nonatomic, readonly, assign) BOOL isLeaf;
/**
Return's a BOOL indicating if a view is dirty. When a node is dirty
it usually indicates that it will be remeasured on the next layout pass.
*/
@property (nonatomic, readonly, assign) BOOL isDirty;
/**
Mark that a view's layout needs to be recalculated. Only works for leaf views.
*/

View File

@@ -25,7 +25,7 @@
- (CGFloat)lowercased_name \
{ \
YGValue value = YGNodeStyleGet##capitalized_name(self.node); \
if (value.unit == YGUnitPixel) { \
if (value.unit == YGUnitPoint) { \
return value.value; \
} else { \
return YGUndefined; \
@@ -43,12 +43,6 @@
return YGNodeStyleGet##property(self.node, edge); \
}
#define YG_SHORTHAND_EDGE_PROPERTY_GETTER(lowercased_name) \
- (CGFloat)lowercased_name \
{ \
return YGUndefined; \
}
#define YG_EDGE_PROPERTY_SETTER(lowercased_name, capitalized_name, property, edge) \
- (void)set##capitalized_name:(CGFloat)lowercased_name \
{ \
@@ -59,15 +53,11 @@
YG_EDGE_PROPERTY_GETTER(lowercased_name, capitalized_name, property, edge) \
YG_EDGE_PROPERTY_SETTER(lowercased_name, capitalized_name, property, edge)
#define YG_SHORTHAND_EDGE_PROPERTY(lowercased_name, capitalized_name, property, edge) \
YG_SHORTHAND_EDGE_PROPERTY_GETTER(lowercased_name) \
YG_EDGE_PROPERTY_SETTER(lowercased_name, capitalized_name, property, edge)
#define YG_VALUE_EDGE_PROPERTY_GETTER(objc_lowercased_name, objc_capitalized_name, c_name, edge) \
- (CGFloat)objc_lowercased_name \
{ \
YGValue value = YGNodeStyleGet##c_name(self.node, edge); \
if (value.unit == YGUnitPixel) { \
if (value.unit == YGUnitPoint) { \
return value.value; \
} else { \
return YGUndefined; \
@@ -84,10 +74,6 @@ YG_EDGE_PROPERTY_SETTER(lowercased_name, capitalized_name, property, edge)
YG_VALUE_EDGE_PROPERTY_GETTER(lowercased_name, capitalized_name, property, edge) \
YG_VALUE_EDGE_PROPERTY_SETTER(lowercased_name, capitalized_name, property, edge)
#define YG_VALUE_SHORTHAND_EDGE_PROPERTY(lowercased_name, capitalized_name, property, edge) \
YG_SHORTHAND_EDGE_PROPERTY_GETTER(lowercased_name) \
YG_VALUE_EDGE_PROPERTY_SETTER(lowercased_name, capitalized_name, property, edge)
#define YG_VALUE_EDGES_PROPERTIES(lowercased_name, capitalized_name) \
YG_VALUE_EDGE_PROPERTY(lowercased_name##Left, capitalized_name##Left, capitalized_name, YGEdgeLeft) \
YG_VALUE_EDGE_PROPERTY(lowercased_name##Top, capitalized_name##Top, capitalized_name, YGEdgeTop) \
@@ -95,9 +81,9 @@ YG_VALUE_EDGE_PROPERTY(lowercased_name##Right, capitalized_name##Right, capitali
YG_VALUE_EDGE_PROPERTY(lowercased_name##Bottom, capitalized_name##Bottom, capitalized_name, YGEdgeBottom) \
YG_VALUE_EDGE_PROPERTY(lowercased_name##Start, capitalized_name##Start, capitalized_name, YGEdgeStart) \
YG_VALUE_EDGE_PROPERTY(lowercased_name##End, capitalized_name##End, capitalized_name, YGEdgeEnd) \
YG_VALUE_SHORTHAND_EDGE_PROPERTY(lowercased_name##Horizontal, capitalized_name##Horizontal, capitalized_name, YGEdgeHorizontal) \
YG_VALUE_SHORTHAND_EDGE_PROPERTY(lowercased_name##Vertical, capitalized_name##Vertical, capitalized_name, YGEdgeVertical) \
YG_VALUE_SHORTHAND_EDGE_PROPERTY(lowercased_name, capitalized_name, capitalized_name, YGEdgeAll)
YG_VALUE_EDGE_PROPERTY(lowercased_name##Horizontal, capitalized_name##Horizontal, capitalized_name, YGEdgeHorizontal) \
YG_VALUE_EDGE_PROPERTY(lowercased_name##Vertical, capitalized_name##Vertical, capitalized_name, YGEdgeVertical) \
YG_VALUE_EDGE_PROPERTY(lowercased_name, capitalized_name, capitalized_name, YGEdgeAll)
@interface YGLayout ()
@@ -134,11 +120,26 @@ YG_VALUE_SHORTHAND_EDGE_PROPERTY(lowercased_name, capitalized_name, capitalized_
YGNodeFree(self.node);
}
- (BOOL)isDirty
{
return YGNodeIsDirty(self.node);
}
- (void)markDirty
{
if (self.isLeaf) {
YGNodeMarkDirty(self.node);
if (self.isDirty || !self.isLeaf) {
return;
}
// Yoga is not happy if we try to mark a node as "dirty" before we have set
// the measure function. Since we already know that this is a leaf,
// this *should* be fine. Forgive me Hack Gods.
const YGNodeRef node = self.node;
if (YGNodeGetMeasureFunc(node) == NULL) {
YGNodeSetMeasureFunc(node, YGMeasureView);
}
YGNodeMarkDirty(node);
}
- (NSUInteger)numberOfChildren
@@ -202,7 +203,7 @@ YG_EDGE_PROPERTY(borderRightWidth, BorderRightWidth, Border, YGEdgeRight)
YG_EDGE_PROPERTY(borderBottomWidth, BorderBottomWidth, Border, YGEdgeBottom)
YG_EDGE_PROPERTY(borderStartWidth, BorderStartWidth, Border, YGEdgeStart)
YG_EDGE_PROPERTY(borderEndWidth, BorderEndWidth, Border, YGEdgeEnd)
YG_SHORTHAND_EDGE_PROPERTY(borderWidth, BorderWidth, Border, YGEdgeAll)
YG_EDGE_PROPERTY(borderWidth, BorderWidth, Border, YGEdgeAll)
YG_VALUE_PROPERTY(width, Width)
YG_VALUE_PROPERTY(height, Height)
@@ -222,7 +223,13 @@ YG_PROPERTY(CGFloat, aspectRatio, AspectRatio)
- (void)applyLayout
{
[self calculateLayoutWithSize:self.view.bounds.size];
YGApplyLayoutToViewHierarchy(self.view);
YGApplyLayoutToViewHierarchy(self.view, NO);
}
- (void)applyLayoutPreservingOrigin:(BOOL)preserveOrigin
{
[self calculateLayoutWithSize:self.view.bounds.size];
YGApplyLayoutToViewHierarchy(self.view, preserveOrigin);
}
- (CGSize)intrinsicSize
@@ -361,10 +368,10 @@ static CGFloat YGRoundPixelValue(CGFloat value)
scale = [UIScreen mainScreen].scale;
});
return round(value * scale) / scale;
return roundf(value * scale) / scale;
}
static void YGApplyLayoutToViewHierarchy(UIView *view)
static void YGApplyLayoutToViewHierarchy(UIView *view, BOOL preserveOrigin)
{
NSCAssert([NSThread isMainThread], @"Framesetting should only be done on the main thread.");
@@ -385,10 +392,11 @@ static void YGApplyLayoutToViewHierarchy(UIView *view)
topLeft.y + YGNodeLayoutGetHeight(node),
};
const CGPoint origin = preserveOrigin ? view.frame.origin : CGPointZero;
view.frame = (CGRect) {
.origin = {
.x = YGRoundPixelValue(topLeft.x),
.y = YGRoundPixelValue(topLeft.y),
.x = YGRoundPixelValue(topLeft.x + origin.x),
.y = YGRoundPixelValue(topLeft.y + origin.y),
},
.size = {
.width = YGRoundPixelValue(bottomRight.x) - YGRoundPixelValue(topLeft.x),
@@ -398,7 +406,7 @@ static void YGApplyLayoutToViewHierarchy(UIView *view)
if (!yoga.isLeaf) {
for (NSUInteger i=0; i<view.subviews.count; i++) {
YGApplyLayoutToViewHierarchy(view.subviews[i]);
YGApplyLayoutToViewHierarchy(view.subviews[i], NO);
}
}
}

View File

@@ -18,6 +18,25 @@
@implementation YogaKitTests
- (void)testConfigureLayoutIsNoOpWithNilBlock
{
UIView *view = [[UIView alloc] initWithFrame:CGRectZero];
XCTAssertNoThrow([view configureLayoutWithBlock:nil]);
}
- (void)testConfigureLayoutBlockWorksWithValidBlock
{
UIView *view = [[UIView alloc] initWithFrame:CGRectZero];
[view configureLayoutWithBlock:^(YGLayout *layout){
XCTAssertNotNil(layout);
layout.isEnabled = YES;
layout.width = 25;
}];
XCTAssertTrue(view.yoga.isEnabled);
XCTAssertEqual(view.yoga.width, 25);
}
- (void)testNodesAreDeallocedWithSingleView
{
__weak YGLayout *layoutRef = nil;
@@ -109,6 +128,49 @@
XCTAssertEqual(longTextLabelSize.width + textBadgeView.yoga.intrinsicSize.width, containerSize.width);
}
- (void)testPreservingOrigin
{
UIView *container = [[UIView alloc] initWithFrame:CGRectMake(0,0,50,75)];
container.yoga.isEnabled = YES;
UIView *view = [[UIView alloc] initWithFrame:CGRectZero];
view.yoga.isEnabled = YES;
view.yoga.flexBasis = 0;
view.yoga.flexGrow = 1;
[container addSubview:view];
UIView *view2 = [[UIView alloc] initWithFrame:CGRectZero];
view2.yoga.isEnabled = YES;
view2.yoga.marginTop = 25;
view2.yoga.flexBasis = 0;
view2.yoga.flexGrow = 1;
[container addSubview:view2];
[container.yoga applyLayoutPreservingOrigin:YES];
XCTAssertEqual(50, view2.frame.origin.y);
[view2.yoga applyLayoutPreservingOrigin:NO];
XCTAssertEqual(25, view2.frame.origin.y);
}
- (void)testMarkingDirtyOnlyWorksOnLeafNodes
{
UIView *container = [[UIView alloc] initWithFrame:CGRectZero];
container.yoga.isEnabled = YES;
UIView *subview = [[UIView alloc] initWithFrame:CGRectZero];
subview.yoga.isEnabled = YES;
[container addSubview:subview];
XCTAssertFalse(container.yoga.isDirty);
[container.yoga markDirty];
XCTAssertFalse(container.yoga.isDirty);
XCTAssertFalse(subview.yoga.isDirty);
[subview.yoga markDirty];
XCTAssertTrue(subview.yoga.isDirty);
}
- (void)testThatMarkingLeafsAsDirtyWillTriggerASizeRecalculation
{
UIView *container = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 50)];
@@ -116,22 +178,22 @@
container.yoga.flexDirection = YGFlexDirectionRow;
container.yoga.alignItems = YGAlignFlexStart;
UILabel *label = [[UILabel alloc] initWithFrame:CGRectZero];
label.text = @"This is a short text.";
label.numberOfLines = 1;
label.yoga.isEnabled = YES;
[container addSubview:label];
UILabel *view = [[UILabel alloc] initWithFrame:CGRectZero];
view.text = @"This is a short text.";
view.numberOfLines = 1;
view.yoga.isEnabled = YES;
[container addSubview:view];
[container.yoga applyLayout];
CGSize const labelSizeAfterFirstPass = label.frame.size;
[container.yoga applyLayoutPreservingOrigin:YES];
CGSize const viewSizeAfterFirstPass = view.frame.size;
label.text = @"This is a slightly longer text.";
XCTAssertTrue(CGSizeEqualToSize(label.frame.size, labelSizeAfterFirstPass));
view.text = @"This is a slightly longer text.";
XCTAssertTrue(CGSizeEqualToSize(view.frame.size, viewSizeAfterFirstPass));
[label.yoga markDirty];
[view.yoga markDirty];
[container.yoga applyLayout];
XCTAssertFalse(CGSizeEqualToSize(label.frame.size, labelSizeAfterFirstPass));
[container.yoga applyLayoutPreservingOrigin:YES];
XCTAssertFalse(CGSizeEqualToSize(view.frame.size, viewSizeAfterFirstPass));
}
- (void)testFrameAndOriginPlacement
@@ -157,7 +219,7 @@
subview3.yoga.flexGrow = 1;
[container addSubview:subview3];
[container.yoga applyLayout];
[container.yoga applyLayoutPreservingOrigin:YES];
XCTAssertEqualWithAccuracy(subview2.frame.origin.x, CGRectGetMaxX(subview1.frame), FLT_EPSILON);
XCTAssertEqualWithAccuracy(subview3.frame.origin.x, CGRectGetMaxX(subview2.frame), FLT_EPSILON);
@@ -193,7 +255,7 @@
subview3.yoga.flexGrow = 1;
[container addSubview:subview3];
[container.yoga applyLayout];
[container.yoga applyLayoutPreservingOrigin:YES];
XCTAssertTrue(CGRectEqualToRect(subview1.frame, CGRectMake(0, 0, 100, 50)));
XCTAssertTrue(CGRectEqualToRect(subview2.frame, CGRectMake(100, 0, 100, 50)));
@@ -201,7 +263,7 @@
[container exchangeSubviewAtIndex:2 withSubviewAtIndex:0];
subview2.yoga.isIncludedInLayout = NO;
[container.yoga applyLayout];
[container.yoga applyLayoutPreservingOrigin:YES];
XCTAssertTrue(CGRectEqualToRect(subview3.frame, CGRectMake(0, 0, 150, 50)));
XCTAssertTrue(CGRectEqualToRect(subview1.frame, CGRectMake(150, 0, 150, 50)));
@@ -233,14 +295,14 @@
subview3.yoga.flexGrow = 1;
[container addSubview:subview3];
[container.yoga applyLayout];
[container.yoga applyLayoutPreservingOrigin:YES];
for (UIView *subview in container.subviews) {
XCTAssertEqual(subview.bounds.size.width, 100);
}
subview3.yoga.isIncludedInLayout = NO;
[container.yoga applyLayout];
[container.yoga applyLayoutPreservingOrigin:YES];
XCTAssertEqual(subview1.bounds.size.width, 150);
XCTAssertEqual(subview2.bounds.size.width, 150);
@@ -270,11 +332,11 @@
subview3.yoga.isIncludedInLayout = YES;
[container addSubview:subview3];
[container.yoga applyLayout];
[container.yoga applyLayoutPreservingOrigin:YES];
XCTAssertEqual(container.yoga.numberOfChildren, 1);
subview2.yoga.isIncludedInLayout = YES;
[container.yoga applyLayout];
[container.yoga applyLayoutPreservingOrigin:YES];
XCTAssertEqual(container.yoga.numberOfChildren, 2);
}
@@ -300,14 +362,14 @@
subview3.yoga.isIncludedInLayout = NO;
[container addSubview:subview3];
[container.yoga applyLayout];
[container.yoga applyLayoutPreservingOrigin:YES];
XCTAssertEqual(subview1.bounds.size.width, 150);
XCTAssertEqual(subview2.bounds.size.width, 150);
XCTAssertEqual(subview3.bounds.size.width, 0);
subview3.yoga.isIncludedInLayout = YES;
[container.yoga applyLayout];
[container.yoga applyLayoutPreservingOrigin:YES];
XCTAssertEqual(subview1.bounds.size.width, 100);
XCTAssertEqual(subview2.bounds.size.width, 100);
@@ -361,7 +423,7 @@
someView.yoga.flexGrow = 1;
[view addSubview:someView];
}
[container.yoga applyLayout];
[container.yoga applyLayoutPreservingOrigin:YES];
// Add the same amount of new views, reapply layout.
for (UIView *view in @[subview1, subview2]) {
@@ -370,7 +432,7 @@
someView.yoga.flexGrow = 1;
[view addSubview:someView];
}
[container.yoga applyLayout];
[container.yoga applyLayoutPreservingOrigin:YES];
XCTAssertEqual(subview1.bounds.size.width, 100);
XCTAssertEqual(subview1.bounds.size.height, 25);
@@ -406,9 +468,9 @@
subview2.yoga.isEnabled = YES;
[subview1 addSubview:subview2];
[container.yoga applyLayout];
[container.yoga applyLayoutPreservingOrigin:YES];
[subview2 removeFromSuperview];
[container.yoga applyLayout];
[container.yoga applyLayoutPreservingOrigin:YES];
}
- (void)testPositionalPropertiesWork
@@ -417,32 +479,32 @@
view.yoga.left = 1;
XCTAssertEqual(YGNodeStyleGetPosition(view.yoga.node, YGEdgeLeft).value, 1);
XCTAssertEqual(YGNodeStyleGetPosition(view.yoga.node, YGEdgeLeft).unit, YGUnitPixel);
XCTAssertEqual(YGNodeStyleGetPosition(view.yoga.node, YGEdgeLeft).unit, YGUnitPoint);
XCTAssertEqual(view.yoga.left, 1);
view.yoga.right = 2;
XCTAssertEqual(YGNodeStyleGetPosition(view.yoga.node, YGEdgeRight).value, 2);
XCTAssertEqual(YGNodeStyleGetPosition(view.yoga.node, YGEdgeRight).unit, YGUnitPixel);
XCTAssertEqual(YGNodeStyleGetPosition(view.yoga.node, YGEdgeRight).unit, YGUnitPoint);
XCTAssertEqual(view.yoga.right, 2);
view.yoga.top = 3;
XCTAssertEqual(YGNodeStyleGetPosition(view.yoga.node, YGEdgeTop).value, 3);
XCTAssertEqual(YGNodeStyleGetPosition(view.yoga.node, YGEdgeTop).unit, YGUnitPixel);
XCTAssertEqual(YGNodeStyleGetPosition(view.yoga.node, YGEdgeTop).unit, YGUnitPoint);
XCTAssertEqual(view.yoga.top, 3);
view.yoga.bottom = 4;
XCTAssertEqual(YGNodeStyleGetPosition(view.yoga.node, YGEdgeBottom).value, 4);
XCTAssertEqual(YGNodeStyleGetPosition(view.yoga.node, YGEdgeBottom).unit, YGUnitPixel);
XCTAssertEqual(YGNodeStyleGetPosition(view.yoga.node, YGEdgeBottom).unit, YGUnitPoint);
XCTAssertEqual(view.yoga.bottom, 4);
view.yoga.start = 5;
XCTAssertEqual(YGNodeStyleGetPosition(view.yoga.node, YGEdgeStart).value, 5);
XCTAssertEqual(YGNodeStyleGetPosition(view.yoga.node, YGEdgeStart).unit, YGUnitPixel);
XCTAssertEqual(YGNodeStyleGetPosition(view.yoga.node, YGEdgeStart).unit, YGUnitPoint);
XCTAssertEqual(view.yoga.start, 5);
view.yoga.end = 6;
XCTAssertEqual(YGNodeStyleGetPosition(view.yoga.node, YGEdgeEnd).value, 6);
XCTAssertEqual(YGNodeStyleGetPosition(view.yoga.node, YGEdgeEnd).unit, YGUnitPixel);
XCTAssertEqual(YGNodeStyleGetPosition(view.yoga.node, YGEdgeEnd).unit, YGUnitPoint);
XCTAssertEqual(view.yoga.end, 6);
}
@@ -451,68 +513,56 @@
UIView *view = [[UIView alloc] initWithFrame:CGRectZero];
view.yoga.margin = 1;
XCTAssertEqual(view.yoga.marginLeft, 1);
XCTAssertEqual(YGNodeStyleGetMargin(view.yoga.node, YGEdgeLeft).unit, YGUnitPixel);
XCTAssertEqual(view.yoga.marginRight, 1);
XCTAssertEqual(YGNodeStyleGetMargin(view.yoga.node, YGEdgeRight).unit, YGUnitPixel);
XCTAssertEqual(view.yoga.marginStart, 1);
XCTAssertEqual(YGNodeStyleGetMargin(view.yoga.node, YGEdgeStart).unit, YGUnitPixel);
XCTAssertEqual(view.yoga.marginEnd, 1);
XCTAssertEqual(YGNodeStyleGetMargin(view.yoga.node, YGEdgeEnd).unit, YGUnitPixel);
XCTAssertEqual(view.yoga.marginTop, 1);
XCTAssertEqual(YGNodeStyleGetMargin(view.yoga.node, YGEdgeTop).unit, YGUnitPixel);
XCTAssertEqual(view.yoga.marginBottom, 1);
XCTAssertEqual(YGNodeStyleGetMargin(view.yoga.node, YGEdgeBottom).unit, YGUnitPixel);
XCTAssertEqual(view.yoga.margin, 1);
XCTAssertTrue(isnan(view.yoga.marginLeft));
XCTAssertTrue(isnan(view.yoga.marginRight));
XCTAssertTrue(isnan(view.yoga.marginStart));
XCTAssertTrue(isnan(view.yoga.marginEnd));
XCTAssertTrue(isnan(view.yoga.marginTop));
XCTAssertTrue(isnan(view.yoga.marginBottom));
XCTAssertTrue(isnan(view.yoga.marginHorizontal));
XCTAssertTrue(isnan(view.yoga.marginVertical));
XCTAssertTrue(isnan(view.yoga.margin));
view.yoga.marginHorizontal = 2;
XCTAssertEqual(view.yoga.marginLeft, 2);
XCTAssertEqual(YGNodeStyleGetMargin(view.yoga.node, YGEdgeLeft).unit, YGUnitPixel);
XCTAssertEqual(view.yoga.marginRight, 2);
XCTAssertEqual(YGNodeStyleGetMargin(view.yoga.node, YGEdgeRight).unit, YGUnitPixel);
XCTAssertEqual(view.yoga.marginStart, 2);
XCTAssertEqual(YGNodeStyleGetMargin(view.yoga.node, YGEdgeStart).unit, YGUnitPixel);
XCTAssertEqual(view.yoga.marginEnd, 2);
XCTAssertEqual(YGNodeStyleGetMargin(view.yoga.node, YGEdgeEnd).unit, YGUnitPixel);
XCTAssertTrue(isnan(view.yoga.marginHorizontal));
XCTAssertEqual(view.yoga.marginHorizontal, 2);
XCTAssertTrue(isnan(view.yoga.marginLeft));
XCTAssertTrue(isnan(view.yoga.marginRight));
XCTAssertTrue(isnan(view.yoga.marginStart));
XCTAssertTrue(isnan(view.yoga.marginEnd));
view.yoga.marginVertical = 3;
XCTAssertEqual(view.yoga.marginTop, 3);
XCTAssertEqual(YGNodeStyleGetMargin(view.yoga.node, YGEdgeTop).unit, YGUnitPixel);
XCTAssertEqual(view.yoga.marginBottom, 3);
XCTAssertEqual(YGNodeStyleGetMargin(view.yoga.node, YGEdgeBottom).unit, YGUnitPixel);
XCTAssertTrue(isnan(view.yoga.marginVertical));
XCTAssertEqual(view.yoga.marginVertical, 3);
XCTAssertTrue(isnan(view.yoga.marginTop));
XCTAssertTrue(isnan(view.yoga.marginBottom));
view.yoga.marginLeft = 4;
XCTAssertEqual(YGNodeStyleGetMargin(view.yoga.node, YGEdgeLeft).value, 4);
XCTAssertEqual(YGNodeStyleGetMargin(view.yoga.node, YGEdgeLeft).unit, YGUnitPixel);
XCTAssertEqual(YGNodeStyleGetMargin(view.yoga.node, YGEdgeLeft).unit, YGUnitPoint);
XCTAssertEqual(view.yoga.marginLeft, 4);
view.yoga.marginRight = 5;
XCTAssertEqual(YGNodeStyleGetMargin(view.yoga.node, YGEdgeRight).value, 5);
XCTAssertEqual(YGNodeStyleGetMargin(view.yoga.node, YGEdgeRight).unit, YGUnitPixel);
XCTAssertEqual(YGNodeStyleGetMargin(view.yoga.node, YGEdgeRight).unit, YGUnitPoint);
XCTAssertEqual(view.yoga.marginRight, 5);
view.yoga.marginTop = 6;
XCTAssertEqual(YGNodeStyleGetMargin(view.yoga.node, YGEdgeTop).value, 6);
XCTAssertEqual(YGNodeStyleGetMargin(view.yoga.node, YGEdgeTop).unit, YGUnitPixel);
XCTAssertEqual(YGNodeStyleGetMargin(view.yoga.node, YGEdgeTop).unit, YGUnitPoint);
XCTAssertEqual(view.yoga.marginTop, 6);
view.yoga.marginBottom = 7;
XCTAssertEqual(YGNodeStyleGetMargin(view.yoga.node, YGEdgeBottom).value, 7);
XCTAssertEqual(YGNodeStyleGetMargin(view.yoga.node, YGEdgeBottom).unit, YGUnitPixel);
XCTAssertEqual(YGNodeStyleGetMargin(view.yoga.node, YGEdgeBottom).unit, YGUnitPoint);
XCTAssertEqual(view.yoga.marginBottom, 7);
view.yoga.marginStart = 8;
XCTAssertEqual(YGNodeStyleGetMargin(view.yoga.node, YGEdgeStart).value, 8);
XCTAssertEqual(YGNodeStyleGetMargin(view.yoga.node, YGEdgeStart).unit, YGUnitPixel);
XCTAssertEqual(YGNodeStyleGetMargin(view.yoga.node, YGEdgeStart).unit, YGUnitPoint);
XCTAssertEqual(view.yoga.marginStart, 8);
view.yoga.marginEnd = 9;
XCTAssertEqual(YGNodeStyleGetMargin(view.yoga.node, YGEdgeEnd).value, 9);
XCTAssertEqual(YGNodeStyleGetMargin(view.yoga.node, YGEdgeEnd).unit, YGUnitPixel);
XCTAssertEqual(YGNodeStyleGetMargin(view.yoga.node, YGEdgeEnd).unit, YGUnitPoint);
XCTAssertEqual(view.yoga.marginEnd, 9);
}
@@ -521,68 +571,56 @@
UIView *view = [[UIView alloc] initWithFrame:CGRectZero];
view.yoga.padding = 1;
XCTAssertEqual(view.yoga.paddingLeft, 1);
XCTAssertEqual(YGNodeStyleGetPadding(view.yoga.node, YGEdgeLeft).unit, YGUnitPixel);
XCTAssertEqual(view.yoga.paddingRight, 1);
XCTAssertEqual(YGNodeStyleGetPadding(view.yoga.node, YGEdgeRight).unit, YGUnitPixel);
XCTAssertEqual(view.yoga.paddingStart, 1);
XCTAssertEqual(YGNodeStyleGetPadding(view.yoga.node, YGEdgeStart).unit, YGUnitPixel);
XCTAssertEqual(view.yoga.paddingEnd, 1);
XCTAssertEqual(YGNodeStyleGetPadding(view.yoga.node, YGEdgeEnd).unit, YGUnitPixel);
XCTAssertEqual(view.yoga.paddingTop, 1);
XCTAssertEqual(YGNodeStyleGetPadding(view.yoga.node, YGEdgeTop).unit, YGUnitPixel);
XCTAssertEqual(view.yoga.paddingBottom, 1);
XCTAssertEqual(YGNodeStyleGetPadding(view.yoga.node, YGEdgeBottom).unit, YGUnitPixel);
XCTAssertEqual(view.yoga.padding, 1);
XCTAssertTrue(isnan(view.yoga.paddingLeft));
XCTAssertTrue(isnan(view.yoga.paddingRight));
XCTAssertTrue(isnan(view.yoga.paddingStart));
XCTAssertTrue(isnan(view.yoga.paddingEnd));
XCTAssertTrue(isnan(view.yoga.paddingTop));
XCTAssertTrue(isnan(view.yoga.paddingBottom));
XCTAssertTrue(isnan(view.yoga.paddingHorizontal));
XCTAssertTrue(isnan(view.yoga.paddingVertical));
XCTAssertTrue(isnan(view.yoga.padding));
view.yoga.paddingHorizontal = 2;
XCTAssertEqual(view.yoga.paddingLeft, 2);
XCTAssertEqual(YGNodeStyleGetPadding(view.yoga.node, YGEdgeLeft).unit, YGUnitPixel);
XCTAssertEqual(view.yoga.paddingRight, 2);
XCTAssertEqual(YGNodeStyleGetPadding(view.yoga.node, YGEdgeRight).unit, YGUnitPixel);
XCTAssertEqual(view.yoga.paddingStart, 2);
XCTAssertEqual(YGNodeStyleGetPadding(view.yoga.node, YGEdgeStart).unit, YGUnitPixel);
XCTAssertEqual(view.yoga.paddingEnd, 2);
XCTAssertEqual(YGNodeStyleGetPadding(view.yoga.node, YGEdgeEnd).unit, YGUnitPixel);
XCTAssertTrue(isnan(view.yoga.paddingHorizontal));
XCTAssertEqual(view.yoga.paddingHorizontal, 2);
XCTAssertTrue(isnan(view.yoga.paddingLeft));
XCTAssertTrue(isnan(view.yoga.paddingRight));
XCTAssertTrue(isnan(view.yoga.paddingStart));
XCTAssertTrue(isnan(view.yoga.paddingEnd));
view.yoga.paddingVertical = 3;
XCTAssertEqual(view.yoga.paddingTop, 3);
XCTAssertEqual(YGNodeStyleGetPadding(view.yoga.node, YGEdgeTop).unit, YGUnitPixel);
XCTAssertEqual(view.yoga.paddingBottom, 3);
XCTAssertEqual(YGNodeStyleGetPadding(view.yoga.node, YGEdgeBottom).unit, YGUnitPixel);
XCTAssertTrue(isnan(view.yoga.paddingVertical));
XCTAssertEqual(view.yoga.paddingVertical, 3);
XCTAssertTrue(isnan(view.yoga.paddingTop));
XCTAssertTrue(isnan(view.yoga.paddingBottom));
view.yoga.paddingLeft = 4;
XCTAssertEqual(YGNodeStyleGetPadding(view.yoga.node, YGEdgeLeft).value, 4);
XCTAssertEqual(YGNodeStyleGetPadding(view.yoga.node, YGEdgeLeft).unit, YGUnitPixel);
XCTAssertEqual(YGNodeStyleGetPadding(view.yoga.node, YGEdgeLeft).unit, YGUnitPoint);
XCTAssertEqual(view.yoga.paddingLeft, 4);
view.yoga.paddingRight = 5;
XCTAssertEqual(YGNodeStyleGetPadding(view.yoga.node, YGEdgeRight).value, 5);
XCTAssertEqual(YGNodeStyleGetPadding(view.yoga.node, YGEdgeRight).unit, YGUnitPixel);
XCTAssertEqual(YGNodeStyleGetPadding(view.yoga.node, YGEdgeRight).unit, YGUnitPoint);
XCTAssertEqual(view.yoga.paddingRight, 5);
view.yoga.paddingTop = 6;
XCTAssertEqual(YGNodeStyleGetPadding(view.yoga.node, YGEdgeTop).value, 6);
XCTAssertEqual(YGNodeStyleGetPadding(view.yoga.node, YGEdgeTop).unit, YGUnitPixel);
XCTAssertEqual(YGNodeStyleGetPadding(view.yoga.node, YGEdgeTop).unit, YGUnitPoint);
XCTAssertEqual(view.yoga.paddingTop, 6);
view.yoga.paddingBottom = 7;
XCTAssertEqual(YGNodeStyleGetPadding(view.yoga.node, YGEdgeBottom).value, 7);
XCTAssertEqual(YGNodeStyleGetPadding(view.yoga.node, YGEdgeBottom).unit, YGUnitPixel);
XCTAssertEqual(YGNodeStyleGetPadding(view.yoga.node, YGEdgeBottom).unit, YGUnitPoint);
XCTAssertEqual(view.yoga.paddingBottom, 7);
view.yoga.paddingStart = 8;
XCTAssertEqual(YGNodeStyleGetPadding(view.yoga.node, YGEdgeStart).value, 8);
XCTAssertEqual(YGNodeStyleGetPadding(view.yoga.node, YGEdgeStart).unit, YGUnitPixel);
XCTAssertEqual(YGNodeStyleGetPadding(view.yoga.node, YGEdgeStart).unit, YGUnitPoint);
XCTAssertEqual(view.yoga.paddingStart, 8);
view.yoga.paddingEnd = 9;
XCTAssertEqual(YGNodeStyleGetPadding(view.yoga.node, YGEdgeEnd).value, 9);
XCTAssertEqual(YGNodeStyleGetPadding(view.yoga.node, YGEdgeEnd).unit, YGUnitPixel);
XCTAssertEqual(YGNodeStyleGetPadding(view.yoga.node, YGEdgeEnd).unit, YGUnitPoint);
XCTAssertEqual(view.yoga.paddingEnd, 9);
}
@@ -591,13 +629,13 @@
UIView *view = [[UIView alloc] initWithFrame:CGRectZero];
view.yoga.borderWidth = 1;
XCTAssertEqual(view.yoga.borderLeftWidth, 1);
XCTAssertEqual(view.yoga.borderRightWidth, 1);
XCTAssertEqual(view.yoga.borderStartWidth, 1);
XCTAssertEqual(view.yoga.borderEndWidth, 1);
XCTAssertEqual(view.yoga.borderTopWidth, 1);
XCTAssertEqual(view.yoga.borderBottomWidth, 1);
XCTAssertTrue(isnan(view.yoga.borderWidth));
XCTAssertEqual(view.yoga.borderWidth, 1);
XCTAssertTrue(isnan(view.yoga.borderLeftWidth));
XCTAssertTrue(isnan(view.yoga.borderRightWidth));
XCTAssertTrue(isnan(view.yoga.borderStartWidth));
XCTAssertTrue(isnan(view.yoga.borderEndWidth));
XCTAssertTrue(isnan(view.yoga.borderTopWidth));
XCTAssertTrue(isnan(view.yoga.borderBottomWidth));
view.yoga.borderLeftWidth = 2;
XCTAssertEqual(view.yoga.borderLeftWidth, 2);

View File

@@ -2,4 +2,5 @@ use_frameworks!
target 'YogaKitSample' do
pod 'YogaKit', :path => '../../YogaKit.podspec'
pod 'IGListKit', '~> 2.1.0'
end

View File

@@ -1,19 +1,26 @@
PODS:
- Yoga (1.0.2)
- YogaKit (1.0.3):
- Yoga (~> 1.0)
- IGListKit (2.1.0):
- IGListKit/Default (= 2.1.0)
- IGListKit/Default (2.1.0):
- IGListKit/Diffing
- IGListKit/Diffing (2.1.0)
- Yoga (1.1.0)
- YogaKit (1.1.0):
- Yoga (~> 1.1)
DEPENDENCIES:
- IGListKit (~> 2.1.0)
- YogaKit (from `../../YogaKit.podspec`)
EXTERNAL SOURCES:
YogaKit:
:path: "../../YogaKit.podspec"
:path: ../../YogaKit.podspec
SPEC CHECKSUMS:
Yoga: ef42f88b9bcbd7daf7267c0f19d8636ce3a50618
YogaKit: 6d9826a015c029b13731a33bf96fe6c1e33748a6
IGListKit: b826c68ef7a4ae1626c09d4d3e1ea7a169e6c36e
Yoga: 0bf083b7c485b20598020dbedcea869cbe53071e
YogaKit: 80df90de9ef2900baa111f2c93476a6f9e921385
PODFILE CHECKSUM: 9db3bdea7f1b4b715ad859a449b2dc87fb6226cc
PODFILE CHECKSUM: 216f8e7127767709e0e43f3711208d238fa5c404
COCOAPODS: 1.2.0

View File

@@ -7,14 +7,15 @@
objects = {
/* Begin PBXBuildFile section */
13687D481DF8748400E7C260 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13687D471DF8748400E7C260 /* main.m */; };
13687D4B1DF8748400E7C260 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13687D4A1DF8748400E7C260 /* AppDelegate.m */; };
13687D4E1DF8748400E7C260 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 13687D4D1DF8748400E7C260 /* ViewController.m */; };
13687D531DF8748400E7C260 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13687D521DF8748400E7C260 /* Assets.xcassets */; };
13687D851DF87D1E00E7C260 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 13687D841DF87D1E00E7C260 /* UIKit.framework */; };
13687D871DF87D2400E7C260 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 13687D861DF87D2400E7C260 /* Foundation.framework */; };
15A7CB5995C9DAB1C8803834 /* Pods_YogaKitSample.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C80A931E90C7F3088CB86822 /* Pods_YogaKitSample.framework */; };
638A94481E1F06D100A726AD /* SwiftViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 638A94471E1F06D100A726AD /* SwiftViewController.swift */; };
40BD9F461E477A09002790A9 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40BD9F451E477A09002790A9 /* AppDelegate.swift */; };
40BD9F4B1E47850C002790A9 /* BasicViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40BD9F4A1E47850C002790A9 /* BasicViewController.swift */; };
40BD9F501E479079002790A9 /* SingleLabelCollectionCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40BD9F4F1E479079002790A9 /* SingleLabelCollectionCell.swift */; };
40BD9F521E479173002790A9 /* LayoutInclusionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40BD9F511E479173002790A9 /* LayoutInclusionViewController.swift */; };
638A94481E1F06D100A726AD /* ExamplesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 638A94471E1F06D100A726AD /* ExamplesViewController.swift */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -52,17 +53,16 @@
/* Begin PBXFileReference section */
13687D431DF8748400E7C260 /* YogaKitSample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = YogaKitSample.app; sourceTree = BUILT_PRODUCTS_DIR; };
13687D471DF8748400E7C260 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
13687D491DF8748400E7C260 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
13687D4A1DF8748400E7C260 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
13687D4C1DF8748400E7C260 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = "<group>"; };
13687D4D1DF8748400E7C260 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = "<group>"; };
13687D521DF8748400E7C260 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
13687D571DF8748400E7C260 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
13687D841DF87D1E00E7C260 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
13687D861DF87D2400E7C260 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
1D2FF4D5FCA6A8C54A4074A3 /* Pods-YogaKitSample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-YogaKitSample.debug.xcconfig"; path = "Pods/Target Support Files/Pods-YogaKitSample/Pods-YogaKitSample.debug.xcconfig"; sourceTree = "<group>"; };
638A94471E1F06D100A726AD /* SwiftViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SwiftViewController.swift; sourceTree = "<group>"; };
40BD9F451E477A09002790A9 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
40BD9F4A1E47850C002790A9 /* BasicViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = BasicViewController.swift; path = ViewControllers/BasicViewController.swift; sourceTree = "<group>"; };
40BD9F4F1E479079002790A9 /* SingleLabelCollectionCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SingleLabelCollectionCell.swift; path = Views/SingleLabelCollectionCell.swift; sourceTree = "<group>"; };
40BD9F511E479173002790A9 /* LayoutInclusionViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = LayoutInclusionViewController.swift; path = ViewControllers/LayoutInclusionViewController.swift; sourceTree = "<group>"; };
638A94471E1F06D100A726AD /* ExamplesViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ExamplesViewController.swift; sourceTree = "<group>"; };
638A944F1E215CC800A726AD /* YogaKitSampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = YogaKitSampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
82F0896A88112E957EF37C7F /* Pods-YogaKitSample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-YogaKitSample.release.xcconfig"; path = "Pods/Target Support Files/Pods-YogaKitSample/Pods-YogaKitSample.release.xcconfig"; sourceTree = "<group>"; };
C80A931E90C7F3088CB86822 /* Pods_YogaKitSample.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_YogaKitSample.framework; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -111,26 +111,16 @@
13687D451DF8748400E7C260 /* YogaKitSample */ = {
isa = PBXGroup;
children = (
13687D491DF8748400E7C260 /* AppDelegate.h */,
13687D4A1DF8748400E7C260 /* AppDelegate.m */,
13687D4C1DF8748400E7C260 /* ViewController.h */,
13687D4D1DF8748400E7C260 /* ViewController.m */,
638A94471E1F06D100A726AD /* SwiftViewController.swift */,
40BD9F4E1E47902F002790A9 /* Views */,
40BD9F481E4784B3002790A9 /* ViewControllers */,
638A94471E1F06D100A726AD /* ExamplesViewController.swift */,
13687D521DF8748400E7C260 /* Assets.xcassets */,
13687D571DF8748400E7C260 /* Info.plist */,
13687D461DF8748400E7C260 /* Supporting Files */,
40BD9F451E477A09002790A9 /* AppDelegate.swift */,
);
path = YogaKitSample;
sourceTree = "<group>";
};
13687D461DF8748400E7C260 /* Supporting Files */ = {
isa = PBXGroup;
children = (
13687D471DF8748400E7C260 /* main.m */,
);
name = "Supporting Files";
sourceTree = "<group>";
};
13687D831DF87D1E00E7C260 /* Frameworks */ = {
isa = PBXGroup;
children = (
@@ -141,6 +131,23 @@
name = Frameworks;
sourceTree = "<group>";
};
40BD9F481E4784B3002790A9 /* ViewControllers */ = {
isa = PBXGroup;
children = (
40BD9F4A1E47850C002790A9 /* BasicViewController.swift */,
40BD9F511E479173002790A9 /* LayoutInclusionViewController.swift */,
);
name = ViewControllers;
sourceTree = "<group>";
};
40BD9F4E1E47902F002790A9 /* Views */ = {
isa = PBXGroup;
children = (
40BD9F4F1E479079002790A9 /* SingleLabelCollectionCell.swift */,
);
name = Views;
sourceTree = "<group>";
};
E1C759E3C8E84821213ECE8D /* Pods */ = {
isa = PBXGroup;
children = (
@@ -304,10 +311,11 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
638A94481E1F06D100A726AD /* SwiftViewController.swift in Sources */,
13687D4E1DF8748400E7C260 /* ViewController.m in Sources */,
13687D4B1DF8748400E7C260 /* AppDelegate.m in Sources */,
13687D481DF8748400E7C260 /* main.m in Sources */,
40BD9F501E479079002790A9 /* SingleLabelCollectionCell.swift in Sources */,
40BD9F521E479173002790A9 /* LayoutInclusionViewController.swift in Sources */,
638A94481E1F06D100A726AD /* ExamplesViewController.swift in Sources */,
40BD9F4B1E47850C002790A9 /* BasicViewController.swift in Sources */,
40BD9F461E477A09002790A9 /* AppDelegate.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View File

@@ -1,15 +0,0 @@
/**
* Copyright 2014-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE-examples file in the root directory of this source tree.
*/
#import <UIKit/UIKit.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@end

View File

@@ -1,27 +0,0 @@
/**
* Copyright 2014-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE-examples file in the root directory of this source tree.
*/
#import "AppDelegate.h"
#import "ViewController.h"
@interface AppDelegate ()
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.rootViewController = [ViewController new];
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}
@end

View File

@@ -0,0 +1,27 @@
/**
* Copyright 2014-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE-examples file in the root directory of this source tree.
*/
import Foundation
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func applicationDidFinishLaunching(_ application: UIApplication) {
self.window = UIWindow(frame: UIScreen.main.bounds)
if let window = self.window {
let navigationController = UINavigationController(rootViewController: ExamplesViewController())
navigationController.navigationBar.isTranslucent = false
window.rootViewController = navigationController
window.backgroundColor = .white
window.makeKeyAndVisible()
}
}
}

View File

@@ -0,0 +1,100 @@
/**
* Copyright 2014-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE-examples file in the root directory of this source tree.
*/
import UIKit
import IGListKit
private final class ExampleModel {
let title: String
let controllerClass: UIViewController.Type
init(title: String, controllerClass: UIViewController.Type) {
self.title = title
self.controllerClass = controllerClass
}
}
extension ExampleModel: IGListDiffable {
fileprivate func diffIdentifier() -> NSObjectProtocol {
return title as NSString
}
fileprivate func isEqual(toDiffableObject object: IGListDiffable?) -> Bool {
guard let otherObj = object as? ExampleModel else { return false }
return (title == otherObj.title) &&
(controllerClass == otherObj.controllerClass)
}
}
final class ExamplesViewController: UIViewController, IGListAdapterDataSource, IGListSingleSectionControllerDelegate {
private lazy var adapter: IGListAdapter = {
return IGListAdapter(updater: IGListAdapterUpdater(), viewController: self, workingRangeSize: 0)
}()
private let collectionView = IGListCollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout())
// Update this to array to create more examples.
private let models: [ExampleModel] = [ExampleModel(title: "Basic Layout", controllerClass: BasicViewController.self),
ExampleModel(title: "Exclude Views in Layout", controllerClass: LayoutInclusionViewController.self)]
//MARK: UIViewController
override func viewDidLoad() {
super.viewDidLoad()
title = "Examples"
view.addSubview(collectionView)
adapter.collectionView = collectionView
adapter.dataSource = self
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
collectionView.frame = view.bounds
}
//MARK: IGListAdapterDataSource
func objects(for listAdapter: IGListAdapter) -> [IGListDiffable] {
return models as [IGListDiffable]
}
func listAdapter(_ listAdapter: IGListAdapter, sectionControllerFor object: Any) -> IGListSectionController {
let sizeBlock: IGListSingleSectionCellSizeBlock = { (model, context) in
return CGSize(width: (context?.containerSize.width)!, height: 75.0)
}
let configureBlock: IGListSingleSectionCellConfigureBlock = { (model, cell) in
guard let m = model as? ExampleModel, let c = cell as? SingleLabelCollectionCell else {
return
}
c.label.text = m.title
}
let sectionController = IGListSingleSectionController(cellClass: SingleLabelCollectionCell.self,
configureBlock: configureBlock,
sizeBlock: sizeBlock)
sectionController.selectionDelegate = self
return sectionController
}
func emptyView(for listAdapter: IGListAdapter) -> UIView? { return nil }
//MARK: IGListSingleSectionControllerDelegate
func didSelect(_ sectionController: IGListSingleSectionController) {
let section = adapter.section(for: sectionController)
let model = models[section]
let controller = model.controllerClass.init()
controller.title = model.title
self.navigationController?.pushViewController(controller, animated: true)
}
}

View File

@@ -7,35 +7,60 @@
*/
import UIKit
import IGListKit
import YogaKit
class SwiftViewController: UIViewController {
override func viewDidLoad() {
let root = self.view!
root.backgroundColor = .red
root.yoga.isEnabled = true
root.yoga.width = self.view.bounds.size.width
root.yoga.height = self.view.bounds.size.height
root.yoga.alignItems = .center
root.yoga.justifyContent = .center
let child1 = UIView()
child1.backgroundColor = .blue
child1.yoga.isEnabled = true
child1.yoga.width = 100
child1.yoga.height = 10
let child2 = UIView()
child2.backgroundColor = .green
child2.frame = CGRect(x: 0, y: 0, width: 200, height: 100)
let child3 = UIView()
child3.backgroundColor = .yellow
child3.frame = CGRect(x: 0, y: 0, width: 100, height: 100)
child2.addSubview(child3)
root.addSubview(child1)
root.addSubview(child2)
root.yoga.applyLayout()
}
struct DemoItem {
let name: String
}
final class SwiftViewController: UIViewController, IGListAdapterDataSource {
lazy var adapter: IGListAdapter = {
return IGListAdapter(updater: IGListAdapterUpdater(), viewController: self, workingRangeSize: 0)
}()
let collectionView = IGListCollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout())
//MARK: UIViewController
override func viewDidLoad() {
super.viewDidLoad()
title = "YogaKit Examples"
view.addSubview(collectionView)
adapter.collectionView = collectionView
adapter.dataSource = self
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
collectionView.frame = view.bounds
}
//MARK: IGListAdapterDataSource
func objects(for listAdapter: IGListAdapter) -> [IGListDiffable] {
return ["Dustin" as IGListDiffable, "Ryan" as IGListDiffable]
}
func listAdapter(_ listAdapter: IGListAdapter, sectionControllerFor object: Any) -> IGListSectionController {
let sizeBlock: IGListSingleSectionCellSizeBlock = { (model, context) in
return CGSize(width: (context?.containerSize.width)!, height: 100.0)
}
let configureBlock: IGListSingleSectionCellConfigureBlock = { (model, cell) in
guard let m = model as? String else {
return
}
cell.backgroundColor = (m == "Dustin") ? .blue : .red
}
return IGListSingleSectionController(cellClass: UICollectionViewCell.self,
configureBlock: configureBlock,
sizeBlock: sizeBlock)
}
func emptyView(for listAdapter: IGListAdapter) -> UIView? {
return nil
}
}

View File

@@ -1,13 +0,0 @@
/**
* Copyright 2014-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE-examples file in the root directory of this source tree.
*/
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController
@end

View File

@@ -10,10 +10,6 @@
#import <YogaKit/UIView+Yoga.h>
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad
@@ -53,7 +49,7 @@
[child2 addSubview:child3];
[root addSubview:child1];
[root addSubview:child2];
[root.yoga applyLayout];
[root.yoga applyLayoutPreservingOrigin:NO];
}

View File

@@ -0,0 +1,48 @@
/**
* Copyright 2014-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE-examples file in the root directory of this source tree.
*/
import UIKit
import YogaKit
final class BasicViewController: UIViewController {
override func viewDidLoad() {
let containerSize = self.view.bounds.size
let root = self.view!
root.backgroundColor = .white
root.yoga.isEnabled = true
root.yoga.width = containerSize.width
root.yoga.height = containerSize.height
root.yoga.alignItems = .center
root.yoga.justifyContent = .center
let child1 = UIView()
child1.backgroundColor = .blue
child1.yoga.isEnabled = true
child1.yoga.width = 100
child1.yoga.height = 10
child1.yoga.marginBottom = 25
root.addSubview(child1)
let child2 = UIView()
child2.yoga.isEnabled = true
child2.yoga.alignSelf = .flexEnd
child2.backgroundColor = .green
child2.frame = CGRect(x: 0, y: 0, width: 200, height: 100)
root.addSubview(child2)
let child3 = UIView()
child3.yoga.isEnabled = true
child3.yoga.alignSelf = .flexStart
child3.backgroundColor = .yellow
child3.frame = CGRect(x: 0, y: 0, width: 100, height: 100)
root.addSubview(child3)
root.yoga.applyLayout(preservingOrigin: true)
}
}

View File

@@ -0,0 +1,70 @@
/**
* Copyright 2014-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE-examples file in the root directory of this source tree.
*/
import UIKit
import YogaKit
final class LayoutInclusionViewController: UIViewController {
private let button: UIButton = UIButton(type: .system)
private let disappearingView: UIView = UIView(frame: .zero)
private let contentView: UIView = UIView(frame: .zero)
override func viewDidLoad() {
let root = self.view!
root.backgroundColor = .white
root.yoga.isEnabled = true
root.yoga.flexDirection = .column
root.yoga.justifyContent = .spaceAround
contentView.backgroundColor = .clear
contentView.layer.borderColor = UIColor.lightGray.cgColor
contentView.layer.borderWidth = 1.0
contentView.yoga.isEnabled = true
contentView.yoga.height = 300
contentView.yoga.width = self.view.bounds.size.width
contentView.yoga.flexDirection = .row
contentView.yoga.justifyContent = .center
contentView.yoga.paddingHorizontal = 25
self.view.addSubview(contentView)
let redView = UIView(frame: .zero)
redView.backgroundColor = .red
redView.yoga.isEnabled = true
redView.yoga.flexGrow = 1
redView.yoga.flexShrink = 1
contentView.addSubview(redView)
disappearingView.backgroundColor = .blue
disappearingView.yoga.isEnabled = true
disappearingView.yoga.flexGrow = 1
contentView.addSubview(disappearingView)
button.setTitle("Add Blue View", for: UIControlState.selected)
button.setTitle("Remove Blue View", for: UIControlState.normal)
button.addTarget(self, action: #selector(buttonWasTapped), for: UIControlEvents.touchUpInside)
button.yoga.isEnabled = true
button.yoga.height = 300
button.yoga.width = 300
button.yoga.alignSelf = .center
root.addSubview(button)
root.yoga.applyLayout(preservingOrigin: false)
}
// MARK - UIButton Action
func buttonWasTapped() {
button.isSelected = !button.isSelected
button.isUserInteractionEnabled = false
disappearingView.yoga.isIncludedInLayout = !disappearingView.yoga.isIncludedInLayout
disappearingView.isHidden = !disappearingView.isHidden
contentView.yoga.applyLayout(preservingOrigin: true)
button.isUserInteractionEnabled = true
}
}

View File

@@ -0,0 +1,45 @@
/**
* Copyright 2014-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE-examples file in the root directory of this source tree.
*/
import UIKit
import YogaKit
final class SingleLabelCollectionCell: UICollectionViewCell {
let label: UILabel = UILabel(frame: .zero)
override init(frame: CGRect) {
super.init(frame: frame)
contentView.yoga.isEnabled = true
contentView.yoga.flexDirection = .column
contentView.yoga.justifyContent = .flexEnd
label.textAlignment = .center
label.numberOfLines = 1
label.yoga.isIncludedInLayout = false
contentView.addSubview(label)
let border = UIView(frame: .zero)
border.backgroundColor = .lightGray
border.yoga.isEnabled = true
border.yoga.height = 0.5
border.yoga.marginHorizontal = 25
contentView.addSubview(border)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func layoutSubviews() {
super.layoutSubviews()
contentView.yoga.applyLayout(preservingOrigin: false)
label.frame = contentView.bounds
}
}

View File

@@ -1,16 +0,0 @@
/**
* Copyright 2014-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE-examples file in the root directory of this source tree.
*/
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
int main(int argc, char * argv[]) {
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}

36
android/BUCK Normal file
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.
include_defs('//YOGA_DEFS')
android_aar(
name = 'android',
manifest_skeleton = 'src/main/AndroidManifest.xml',
deps = [
ANDROID_JAVA_TARGET,
ANDROID_RES_TARGET,
INFER_ANNOTATIONS_TARGET,
JAVA_TARGET,
PROGRUARD_ANNOTATIONS_TARGET,
],
visibility = [
'PUBLIC',
],
)
android_resource(
name = 'res',
res = 'src/main/res',
package = 'com.facebook.yoga.android',
visibility = [
'PUBLIC',
],
)
project_config(
src_target = ':android',
)

59
android/build.gradle Normal file
View File

@@ -0,0 +1,59 @@
apply plugin: "com.jfrog.bintray"
apply plugin: 'com.android.library'
apply plugin: 'com.github.dcendents.android-maven'
apply plugin: 'maven-publish'
targetCompatibility = '1.7'
sourceCompatibility = '1.7'
version = '1.0.0'
group = 'com.facebook.yoga.android'
android {
compileSdkVersion 19
buildToolsVersion "19.1.0"
defaultConfig {
minSdkVersion 15
targetSdkVersion 19
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
sourceSets.main {
jni.srcDirs = [] // disalbe NDK auto build (not sure why this is necessary)
// The alternative, fat-aar does an equivalent thing to this hack
// seehttps://github.com/adwiv/android-fat-aar/blob/master/fat-aar.gradle#L307
jniLibs.srcDirs = ['build/intermediates/exploded-aar/com.facebook.yoga/yoga/1.0.0/jni']
}
}
dependencies {
compile project(':yoga')
}
task sourcesJar(type: Jar) {
classifier = 'source'
from android.sourceSets.main.java.srcDirs
}
task javadoc(type: Javadoc) {
failOnError false
source = android.sourceSets.main.java.sourceFiles
classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
classpath += configurations.compile
}
task javadocJar(type: Jar, dependsOn: javadoc) {
classifier = 'javadoc'
from javadoc.destinationDir
}
ext {
bintrayName = "com.facebook.yoga.android:yoga-layout"
}
apply from: rootProject.file('gradle/android-jcenter-install.gradle')

View File

@@ -0,0 +1,46 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2014-present, Facebook, Inc.
All rights reserved.
This source code is licensed under the license found in the
LICENSE-examples file in the root directory of this source tree.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.facebook.samples.yoga"
android:versionCode="1"
android:versionName="1.0"
>
<variable name="applicationId" value="com.facebook.yoga"/>
<variable name="app_label" value="Yoga Sample App"/>
<uses-sdk
android:minSdkVersion="15"
android:targetSdkVersion="19"
/>
<application
android:label="@string/app_name"
android:icon="@drawable/ic_launcher"
android:allowBackup="false"
android:theme="@style/NoTitleBarWhiteBG"
>
<activity
android:name=".MainActivity"
android:exported="true"
>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>

39
android/sample/BUCK Normal file
View File

@@ -0,0 +1,39 @@
# Copyright 2014-present, Facebook, Inc.
# All rights reserved.
#
# This source code is licensed under the license found in the
# LICENSE-examples file in the root directory of this source tree.
include_defs('//YOGA_DEFS')
android_binary(
name = 'sample',
manifest = 'AndroidManifest.xml',
keystore = ':debug_keystore',
deps = [
ANDROID_SAMPLE_JAVA_TARGET,
ANDROID_SAMPLE_RES_TARGET,
],
)
android_resource(
name = 'res',
res = 'res',
package = 'com.facebook.samples.yoga',
deps = [
ANDROID_RES_TARGET,
],
visibility = [
'PUBLIC',
],
)
keystore(
name='debug_keystore',
store='debug.keystore',
properties='debug.keystore.properties',
)
project_config(
src_target = ':sample',
)

Binary file not shown.

View File

@@ -0,0 +1,3 @@
key.alias=androiddebugkey
key.store.password=android
key.alias.password=android

View File

@@ -0,0 +1,23 @@
# 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.
include_defs('//YOGA_DEFS')
android_library(
name = 'yoga',
srcs = glob(['**/*.java']),
deps = [
ANDROID_JAVA_TARGET,
ANDROID_SAMPLE_RES_TARGET,
ANDROID_SUPPORT_TARGET,
APPCOMPAT_TARGET,
SOLOADER_TARGET,
],
visibility = [
'PUBLIC',
]
)

View File

@@ -0,0 +1,34 @@
/**
* Copyright 2014-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE-examples file in the root directory of this source tree.
*/
package com.facebook.samples.yoga;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.LayoutInflater;
import com.facebook.samples.yoga.R;
import com.facebook.soloader.SoLoader;
import com.facebook.yoga.android.YogaViewLayoutFactory;
/**
* An activity to show off Yoga in Android. This activity shows a simple layout (defined in
* {@code main_layout.xml}) that shows off the awesome functionality of the Yoga layout engine
* as well as some optimisations on layout systems that it facilitates.
*/
public class MainActivity extends ActionBarActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
LayoutInflater.from(this).setFactory(YogaViewLayoutFactory.getInstance());
super.onCreate(savedInstanceState);
SoLoader.init(this, false);
setContentView(R.layout.main_layout);
}
}

View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8" ?>
<!--
Copyright 2014-present, Facebook, Inc.
All rights reserved.
This source code is licensed under the license found in the
LICENSE-examples file in the root directory of this source tree.
-->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle"
>
<solid
android:color="@color/yoga_grey"
/>
</shape>

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

View File

@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8" ?>
<!--
Copyright 2014-present, Facebook, Inc.
All rights reserved.
This source code is licensed under the license found in the
LICENSE-examples file in the root directory of this source tree.
-->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle"
>
<corners
android:radius="4dp"
/>
<stroke
android:width="1dp"
android:color="@color/children_stroke"
/>
<padding
android:top="6dp"
android:bottom="6dp"
android:left="8dp"
android:right="8dp"
/>
<solid
android:color="@color/children_background"
/>
</shape>

View File

@@ -0,0 +1,137 @@
<?xml version="1.0" encoding="utf-8" ?>
<!--
Copyright 2014-present, Facebook, Inc.
All rights reserved.
This source code is licensed under the license found in the
LICENSE-examples file in the root directory of this source tree.
-->
<YogaLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:yoga="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<YogaLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/sample_children_background"
yoga:margin_horizontal="10dp"
yoga:margin_top="5dp"
yoga:flex_direction="row"
yoga:align_items="center"
>
<ImageView
android:layout_width="50dp"
android:layout_height="50dp"
android:src="@drawable/ic_launcher"
yoga:flex="0"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/child_1_text"
android:textColor="@color/children_text"
yoga:flex="1"
yoga:margin_start="8dp"
/>
</YogaLayout>
<YogaLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/sample_children_background"
yoga:margin_horizontal="10dp"
yoga:margin_top="5dp"
yoga:flex_direction="row"
yoga:align_items="center"
>
<ImageView
android:layout_width="50dp"
android:layout_height="50dp"
android:src="@drawable/ic_launcher"
yoga:flex="0"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/child_2_text"
android:textColor="@color/children_text"
yoga:flex="1"
yoga:margin_start="8dp"
/>
</YogaLayout>
<YogaLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/sample_children_background"
yoga:margin_horizontal="10dp"
yoga:margin_top="5dp"
yoga:flex_direction="row"
yoga:align_items="center"
>
<ImageView
android:layout_width="50dp"
android:layout_height="50dp"
android:src="@drawable/ic_launcher"
yoga:flex="0"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/child_3_text"
android:textColor="@color/children_text"
yoga:flex="1"
yoga:margin_start="8dp"
/>
</YogaLayout>
<YogaLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/sample_children_background"
yoga:margin_horizontal="10dp"
yoga:margin_top="5dp"
yoga:flex_direction="row"
yoga:align_items="center"
>
<ImageView
android:layout_width="50dp"
android:layout_height="50dp"
android:src="@drawable/ic_launcher"
yoga:flex="0"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/child_4_text"
android:textColor="@color/children_text"
yoga:flex="1"
yoga:margin_start="8dp"
/>
</YogaLayout>
<YogaLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/sample_children_background"
yoga:margin_horizontal="10dp"
yoga:margin_top="5dp"
yoga:flex_direction="row"
yoga:align_items="center"
>
<ImageView
android:layout_width="50dp"
android:layout_height="50dp"
android:src="@drawable/ic_launcher"
yoga:flex="0"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/child_5_text"
android:textColor="@color/children_text"
yoga:flex="1"
yoga:margin_start="10dp"
/>
</YogaLayout>
</YogaLayout>

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2014-present, Facebook, Inc.
All rights reserved.
This source code is licensed under the license found in the
LICENSE-examples file in the root directory of this source tree.
-->
<resources>
<color name="yoga_grey">#FF303846</color>
<color name="yoga_blue">#FF97DCCF</color>
<color name="children_background">#FFFFFFFF</color>
<color name="children_stroke">#665890ff</color>
<color name="children_text">#FF23355b</color>
</resources>

View File

@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2014-present, Facebook, Inc.
All rights reserved.
This source code is licensed under the license found in the
LICENSE-examples file in the root directory of this source tree.
-->
<resources>
<string name="app_name">Yoga</string>
<string
name="child_1_text"
description="Placeholder text for the first element in the layout"
>Hello. I am Yoga!</string>
<string
name="child_2_text"
description="Placeholder text for the second element in the layout"
>I am a layout engine!</string>
<string
name="child_3_text"
description="Placeholder text for the third element in the layout"
>I run natively.</string>
<string
name="child_4_text"
description="Placeholder text for the fourth element in the layout"
>So I\'m fast.</string>
<string
name="child_5_text"
description="Placeholder text for the fifth element in the layout"
>Who are you?</string>
</resources>

View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2014-present, Facebook, Inc.
All rights reserved.
This source code is licensed under the license found in the
LICENSE-examples file in the root directory of this source tree.
-->
<resources>
<style name="NoTitleBarWhiteBG" parent="Theme.AppCompat.Light">
<item name="android:actionBarStyle">@style/MyActionBar</item>
<item name="android:textDirection">locale</item>
</style>
<style name="MyActionBar" parent="Widget.AppCompat.Light.ActionBar">
<item name="android:titleTextStyle">@style/MyTitleText</item>
<item name="android:background">@drawable/action_bar_background</item>
</style>
<style name="MyTitleText" parent="TextAppearance.AppCompat.Widget.ActionBar.Title">
<item name="android:textColor">@color/yoga_blue</item>
</style>
</resources>

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
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.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.facebook.yoga.android"
android:versionCode="1"
android:versionName="1.0"
>
<uses-sdk
android:minSdkVersion="15"
android:targetSdkVersion="19"
/>
<application/>
</manifest>

View File

@@ -0,0 +1,23 @@
# 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.
include_defs('//YOGA_DEFS')
android_library(
name = 'android',
srcs = glob(['**/*.java']),
deps = [
ANDROID_RES_TARGET,
INFER_ANNOTATIONS_TARGET,
JAVA_TARGET,
JSR_305_TARGET,
SOLOADER_TARGET,
],
visibility = [
'PUBLIC',
]
)

View File

@@ -0,0 +1,150 @@
/**
* 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.android;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import com.facebook.yoga.YogaNode;
/**
* Much like a {@link YogaLayout}, except this class does not render itself (the container) to the
* screen. As a result, <i>do not use this if you wish the container to have a background or
* foreground</i>. However, all of its children will still render as expected.
*
* <p>
* In practice, this class never added to the View tree, and all its children become children of its
* parent. As a result, all the layout (such as the traversal of the tree) is performed by Yoga
* (and so natively) increasing performance.
*/
public class VirtualYogaLayout extends ViewGroup {
final private List<View> mChildren = new LinkedList<>();
final private Map<View, YogaNode> mYogaNodes = new HashMap<>();
final private YogaNode mYogaNode = new YogaNode();
public VirtualYogaLayout(Context context) {
super(context);
}
public VirtualYogaLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public VirtualYogaLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
YogaLayout.LayoutParams lp = new YogaLayout.LayoutParams(context, attrs);
YogaLayout.applyLayoutParams(lp, mYogaNode, this);
}
public YogaNode getYogaNode() {
return mYogaNode;
}
/**
* Called to add a view, creating a new yoga node for it and adding that yoga node to the parent.
* If the child is a {@link VirtualYogaLayout}, we simply transfer all its children to this one
* in a manner that maintains the tree, and add its root to the tree.
*
* @param child the View to add
* @param index the position at which to add it (ignored)
* @param params the layout parameters to apply
*/
@Override
public void addView(View child, int index, ViewGroup.LayoutParams params) {
if (child instanceof VirtualYogaLayout) {
((VirtualYogaLayout) child).transferChildren(this);
final YogaNode childNode = ((VirtualYogaLayout) child).getYogaNode();
mYogaNode.addChildAt(childNode, mYogaNode.getChildCount());
return;
}
YogaNode node = new YogaNode();
YogaLayout.LayoutParams lp = new YogaLayout.LayoutParams(params);
YogaLayout.applyLayoutParams(lp, node, child);
node.setData(child);
node.setMeasureFunction(new YogaLayout.ViewMeasureFunction());
mYogaNode.addChildAt(node, mYogaNode.getChildCount());
addView(child, node);
}
/**
* Called to add a view with a corresponding node, but not to change the Yoga tree in any way.
*
* @param child the View to add
* @param node the corresponding yoga node
*/
public void addView(View child, YogaNode node) {
mChildren.add(child);
mYogaNodes.put(child, node);
}
/**
* Gives up children {@code View}s to the parent, maintaining the Yoga tree. This function calls
* {@link YogaLayout#addView(View, YogaNode)} or {@link VirtualYogaLayout#addView(View, YogaNode)}
* on the parent to add the {@code View} without generating new yoga nodes.
*
* @param parent the parent to pass children to (must be a YogaLayout or a VirtualYogaLayout)
*/
protected void transferChildren(ViewGroup parent) {
if (parent instanceof VirtualYogaLayout) {
for (View child : mChildren) {
((VirtualYogaLayout) parent).addView(child, mYogaNodes.get(child));
}
} else if (parent instanceof YogaLayout) {
for (View child : mChildren) {
((YogaLayout) parent).addView(child, mYogaNodes.get(child));
}
} else {
throw new RuntimeException("VirtualYogaLayout cannot transfer children to ViewGroup of type "
+parent.getClass().getCanonicalName()+". Must either be a VirtualYogaLayout or a " +
"YogaLayout.");
}
mChildren.clear();
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
throw new RuntimeException("Attempting to layout a VirtualYogaLayout");
}
@Override
public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) {
return new YogaLayout.LayoutParams(getContext(), attrs);
}
@Override
protected ViewGroup.LayoutParams generateDefaultLayoutParams() {
return new YogaLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT);
}
@Override
protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
return new YogaLayout.LayoutParams(p);
}
@Override
protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
return p instanceof YogaLayout.LayoutParams;
}
}

View File

@@ -0,0 +1,746 @@
/**
* 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.android;
import java.util.HashMap;
import java.util.Map;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.util.AttributeSet;
import android.util.SparseArray;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;
import com.facebook.yoga.android.R;
import com.facebook.yoga.YogaAlign;
import com.facebook.yoga.YogaConstants;
import com.facebook.yoga.YogaDirection;
import com.facebook.yoga.YogaEdge;
import com.facebook.yoga.YogaFlexDirection;
import com.facebook.yoga.YogaJustify;
import com.facebook.yoga.YogaMeasureFunction;
import com.facebook.yoga.YogaMeasureMode;
import com.facebook.yoga.YogaMeasureOutput;
import com.facebook.yoga.YogaNode;
import com.facebook.yoga.YogaNodeAPI;
import com.facebook.yoga.YogaOverflow;
import com.facebook.yoga.YogaPositionType;
import com.facebook.yoga.YogaWrap;
/**
* A {@code ViewGroup} based on the Yoga layout engine.
*
* <p>
* This class is designed to be as "plug and play" as possible. That is, you can use it in XML
* like this (note: to use {@code YogaLayout} you need to use the {@link YogaViewLayoutFactory}):
* <p>
* <pre>{@code
* <YogaLayout
* xmlns:android="http://schemas.android.com/apk/res/android"
* xmlns:yoga="http://schemas.android.com/apk/res-auto"
* android:layout_width="match_parent"
* android:layout_height="match_parent"
* yoga:flex_direction="row"
* yoga:padding_all="10dp"
* >
* <TextView
* android:layout_width="match_parent"
* android:layout_height="match_parent"
* android:text="Hello, World!"
* yoga:flex="1"
* />
* </YogaLayout>
* }</pre>
*
* Under the hood, all views added to this {@code ViewGroup} are laid out using flexbox rules
* and the Yoga engine.
*/
public class YogaLayout extends ViewGroup {
private final Map<View, YogaNode> mYogaNodes;
private final YogaNode mYogaNode;
public YogaLayout(Context context) {
this(context, null, 0);
}
public YogaLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public YogaLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mYogaNode = new YogaNode();
mYogaNodes = new HashMap<>();
mYogaNode.setData(this);
mYogaNode.setMeasureFunction(new ViewMeasureFunction());
final LayoutParams layoutParams = new LayoutParams(context, attrs);
applyLayoutParams(layoutParams, mYogaNode, this);
}
YogaNode getYogaNode() {
return mYogaNode;
}
YogaNode getYogaNodeForView(View view) {
return mYogaNodes.get(view);
}
/**
* Adds a child view with the specified layout parameters.
*
* In the typical View is added, this constructs a {@code YogaNode} for this child and applies all
* the {@code yoga:*} attributes. The Toga node is added to the Yoga tree and the child is added
* to this ViewGroup.
*
* If the child is a {@link YogaLayout} itself, we do not construct a new Yoga node for that
* child, but use its root node instead.
*
* If the child is a {@link VirtualYogaLayout}, we also use its Yoga node, but we also instruct it
* to transfer all of its children to this {@link YogaLayout} while preserving the Yoga tree (so
* that the layout of its children is correct). The {@link VirtualYogaLayout} is then not added
* to the View hierarchy.
*
* <p><strong>Note:</strong> do not invoke this method from
* {@code #draw(android.graphics.Canvas)}, {@code onDraw(android.graphics.Canvas)},
* {@code #dispatchDraw(android.graphics.Canvas)} or any related method.</p>
*
* @param child the child view to add
* @param index the position at which to add the child or -1 to add last
* @param params the layout parameters to set on the child
*/
@Override
public void addView(View child, int index, ViewGroup.LayoutParams params) {
// Internal nodes (which this is now) cannot have measure functions
mYogaNode.setMeasureFunction(null);
if (child instanceof VirtualYogaLayout) {
((VirtualYogaLayout) child).transferChildren(this);
final YogaNode childNode = ((VirtualYogaLayout) child).getYogaNode();
mYogaNode.addChildAt(childNode, mYogaNode.getChildCount());
return;
}
super.addView(child, index, params);
// It is possible that addView is being called as part of a transferal of children, in which
// case we already know about the YogaNode and only need the Android View tree to be aware
// that we now own this child. If so, we don't need to do anything further
if (mYogaNodes.containsKey(child)) {
return;
}
YogaNode childNode;
if (child instanceof YogaLayout) {
childNode = ((YogaLayout) child).getYogaNode();
} else {
childNode = new YogaNode();
childNode.setData(child);
childNode.setMeasureFunction(new ViewMeasureFunction());
}
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
applyLayoutParams(lp, childNode, child);
mYogaNodes.put(child, childNode);
mYogaNode.addChildAt(childNode, mYogaNode.getChildCount());
}
/**
* Adds a view to this {@code ViewGroup} with an already given {@code YogaNode}. Use
* this function if you already have a Yoga node (and perhaps tree) associated with the view you
* are adding, that you would like to preserve.
*
* @param child The view to add
* @param node The Yoga node belonging to the view
*/
public void addView(View child, YogaNode node) {
mYogaNodes.put(child, node);
addView(child);
}
@Override
public void removeView(View view) {
removeViewFromYogaTree(view, false);
super.removeView(view);
}
@Override
public void removeViewAt(int index) {
removeViewFromYogaTree(getChildAt(index), false);
super.removeViewAt(index);
}
@Override
public void removeViewInLayout(View view) {
removeViewFromYogaTree(view, true);
super.removeViewInLayout(view);
}
@Override
public void removeViews(int start, int count) {
for (int i = start; i < start + count; i++) {
removeViewFromYogaTree(getChildAt(i), false);
}
super.removeViews(start, count);
}
@Override
public void removeViewsInLayout(int start, int count) {
for (int i = start; i < start + count; i++) {
removeViewFromYogaTree(getChildAt(i), true);
}
super.removeViewsInLayout(start, count);
}
@Override
public void removeAllViews() {
final int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
removeViewFromYogaTree(getChildAt(i), false);
}
super.removeAllViews();
}
@Override
public void removeAllViewsInLayout() {
final int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
removeViewFromYogaTree(getChildAt(i), true);
}
super.removeAllViewsInLayout();
}
private void removeViewFromYogaTree(View view, boolean inLayout) {
final YogaNode node = mYogaNodes.get(view);
if (node == null) {
return;
}
final YogaNode parent = node.getParent();
for (int i = 0; i < parent.getChildCount(); i++) {
if (parent.getChildAt(i).equals(node)) {
parent.removeChildAt(i);
break;
}
}
node.setData(null);
mYogaNodes.remove(view);
if (inLayout) {
mYogaNode.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED);
}
}
private void applyLayoutRecursive(YogaNode node, float xOffset, float yOffset) {
View view = (View) node.getData();
if (view != null && view != this) {
if (view.getVisibility() == GONE) {
return;
}
view.measure(
View.MeasureSpec.makeMeasureSpec(
Math.round(node.getLayoutWidth()),
View.MeasureSpec.EXACTLY),
View.MeasureSpec.makeMeasureSpec(
Math.round(node.getLayoutHeight()),
View.MeasureSpec.EXACTLY));
view.layout(
Math.round(xOffset + node.getLayoutX()),
Math.round(yOffset + node.getLayoutY()),
Math.round(xOffset + node.getLayoutX() + node.getLayoutWidth()),
Math.round(yOffset + node.getLayoutY() + node.getLayoutHeight()));
}
final int childrenCount = node.getChildCount();
for (int i = 0; i < childrenCount; i++) {
if (this.equals(view)) {
applyLayoutRecursive(node.getChildAt(i), xOffset, yOffset);
} else if (view instanceof YogaLayout) {
continue;
} else {
applyLayoutRecursive(
node.getChildAt(i),
xOffset + node.getLayoutX(),
yOffset + node.getLayoutY());
}
}
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
// Either we are a root of a tree, or this function is called by our parent's onLayout, in which
// case our r-l and b-t are the size of our node.
if (!(getParent() instanceof YogaLayout) &&
Math.round(mYogaNode.getLayoutHeight()) != b-t &&
Math.round(mYogaNode.getLayoutWidth()) != r-l) {
createLayout(
MeasureSpec.makeMeasureSpec(r - l, MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(b - t, MeasureSpec.EXACTLY));
}
applyLayoutRecursive(mYogaNode, 0, 0);
}
/**
* This function is mostly unneeded, because Yoga is doing the measuring. Hence we only need to
* return accurate results if we are the root.
*
* @param widthMeasureSpec the suggested specification for the width
* @param heightMeasureSpec the suggested specification for the height
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (!(getParent() instanceof YogaLayout)) {
createLayout(widthMeasureSpec, heightMeasureSpec);
}
setMeasuredDimension(
Math.round(mYogaNode.getLayoutWidth()),
Math.round(mYogaNode.getLayoutHeight()));
}
private void createLayout(int widthMeasureSpec, int heightMeasureSpec) {
final int widthSize = MeasureSpec.getSize(widthMeasureSpec);
final int heightSize = MeasureSpec.getSize(heightMeasureSpec);
final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
if (heightMode == MeasureSpec.EXACTLY) {
mYogaNode.setHeight(heightSize);
}
if (widthMode == MeasureSpec.EXACTLY) {
mYogaNode.setWidth(widthSize);
}
if (heightMode == MeasureSpec.AT_MOST) {
mYogaNode.setMaxHeight(heightSize);
}
if (widthMode == MeasureSpec.AT_MOST) {
mYogaNode.setMaxWidth(widthSize);
}
mYogaNode.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED);
}
/**
* Applies the layout parameters to the YogaNode. That is, this function is a translator from
* {@code yoga:X="Y"} to {@code yogaNode.setX(Y);}, with some reasonable defaults.
*
* <p>
* If the SDK version is high enough, and the {@code yoga:direction} is not set on
* the component, the direction (LTR or RTL) is set according to the locale.
*
* <p>
* The attributes {@code padding_top}, {@code padding_right} etc. default to those of the view's
* drawable background, if it has one.
*
* @param layoutParameters The source set of params
* @param node The destination node
*/
protected static void applyLayoutParams(LayoutParams layoutParameters, YogaNode node, View view) {
// JELLY_BEAN_MR1 (17) is the first version supporting getLayoutDirection()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
Configuration configuration = view.getResources().getConfiguration();
if (configuration.getLayoutDirection() == LAYOUT_DIRECTION_RTL) {
node.setDirection(YogaDirection.RTL);
}
}
Drawable background = view.getBackground();
if (background != null) {
final Rect backgroundPadding = new Rect();
if (background.getPadding(backgroundPadding)) {
node.setPadding(YogaEdge.LEFT, backgroundPadding.left);
node.setPadding(YogaEdge.TOP, backgroundPadding.top);
node.setPadding(YogaEdge.RIGHT, backgroundPadding.right);
node.setPadding(YogaEdge.BOTTOM, backgroundPadding.bottom);
}
}
for (int i = 0; i < layoutParameters.attributes.size(); i++) {
final int attribute = layoutParameters.attributes.keyAt(i);
final float value = layoutParameters.attributes.valueAt(i);
if (attribute == R.styleable.yoga_align_content) {
node.setAlignContent(YogaAlign.fromInt(Math.round(value)));
} else if (attribute == R.styleable.yoga_align_items) {
node.setAlignItems(YogaAlign.fromInt(Math.round(value)));
} else if (attribute == R.styleable.yoga_align_self) {
node.setAlignSelf(YogaAlign.fromInt(Math.round(value)));
} else if (attribute == R.styleable.yoga_aspect_ratio) {
node.setAspectRatio(value);
} else if (attribute == R.styleable.yoga_border_left) {
node.setBorder(YogaEdge.LEFT, value);
} else if (attribute == R.styleable.yoga_border_top) {
node.setBorder(YogaEdge.TOP, value);
} else if (attribute == R.styleable.yoga_border_right) {
node.setBorder(YogaEdge.RIGHT, value);
} else if (attribute == R.styleable.yoga_border_bottom) {
node.setBorder(YogaEdge.BOTTOM, value);
} else if (attribute == R.styleable.yoga_border_start) {
node.setBorder(YogaEdge.START, value);
} else if (attribute == R.styleable.yoga_border_end) {
node.setBorder(YogaEdge.END, value);
} else if (attribute == R.styleable.yoga_border_horizontal) {
node.setBorder(YogaEdge.HORIZONTAL, value);
} else if (attribute == R.styleable.yoga_border_vertical) {
node.setBorder(YogaEdge.VERTICAL, value);
} else if (attribute == R.styleable.yoga_border_all) {
node.setBorder(YogaEdge.ALL, value);
} else if (attribute == R.styleable.yoga_direction) {
node.setDirection(YogaDirection.fromInt(Math.round(value)));
} else if (attribute == R.styleable.yoga_flex) {
node.setFlex(value);
} else if (attribute == R.styleable.yoga_flex_basis) {
node.setFlexBasis(value);
} else if (attribute == R.styleable.yoga_flex_basis_percent) {
node.setFlexBasisPercent(value);
} else if (attribute == R.styleable.yoga_flex_direction) {
node.setFlexDirection(YogaFlexDirection.fromInt(Math.round(value)));
} else if (attribute == R.styleable.yoga_flex_grow) {
node.setFlexGrow(value);
} else if (attribute == R.styleable.yoga_flex_shrink) {
node.setFlexShrink(value);
} else if (attribute == R.styleable.yoga_height) {
node.setHeight(value);
} else if (attribute == R.styleable.yoga_height_percent) {
node.setHeightPercent(value);
} else if (attribute == R.styleable.yoga_margin_left) {
node.setMargin(YogaEdge.LEFT, value);
} else if (attribute == R.styleable.yoga_justify_content) {
node.setJustifyContent(YogaJustify.fromInt(Math.round(value)));
} else if (attribute == R.styleable.yoga_margin_top) {
node.setMargin(YogaEdge.TOP, value);
} else if (attribute == R.styleable.yoga_margin_right) {
node.setMargin(YogaEdge.RIGHT, value);
} else if (attribute == R.styleable.yoga_margin_bottom) {
node.setMargin(YogaEdge.BOTTOM, value);
} else if (attribute == R.styleable.yoga_margin_start) {
node.setMargin(YogaEdge.START, value);
} else if (attribute == R.styleable.yoga_margin_end) {
node.setMargin(YogaEdge.END, value);
} else if (attribute == R.styleable.yoga_margin_horizontal) {
node.setMargin(YogaEdge.HORIZONTAL, value);
} else if (attribute == R.styleable.yoga_margin_vertical) {
node.setMargin(YogaEdge.VERTICAL, value);
} else if (attribute == R.styleable.yoga_margin_all) {
node.setMargin(YogaEdge.ALL, value);
} else if (attribute == R.styleable.yoga_margin_percent_left) {
node.setMarginPercent(YogaEdge.LEFT, value);
} else if (attribute == R.styleable.yoga_margin_percent_top) {
node.setMarginPercent(YogaEdge.TOP, value);
} else if (attribute == R.styleable.yoga_margin_percent_right) {
node.setMarginPercent(YogaEdge.RIGHT, value);
} else if (attribute == R.styleable.yoga_margin_percent_bottom) {
node.setMarginPercent(YogaEdge.BOTTOM, value);
} else if (attribute == R.styleable.yoga_margin_percent_start) {
node.setMarginPercent(YogaEdge.START, value);
} else if (attribute == R.styleable.yoga_margin_percent_end) {
node.setMarginPercent(YogaEdge.END, value);
} else if (attribute == R.styleable.yoga_margin_percent_horizontal) {
node.setMarginPercent(YogaEdge.HORIZONTAL, value);
} else if (attribute == R.styleable.yoga_margin_percent_vertical) {
node.setMarginPercent(YogaEdge.VERTICAL, value);
} else if (attribute == R.styleable.yoga_margin_percent_all) {
node.setMarginPercent(YogaEdge.ALL, value);
} else if (attribute == R.styleable.yoga_max_height) {
node.setMaxHeight(value);
} else if (attribute == R.styleable.yoga_max_height_percent) {
node.setMaxHeightPercent(value);
} else if (attribute == R.styleable.yoga_max_width) {
node.setMaxWidth(value);
} else if (attribute == R.styleable.yoga_max_width_percent) {
node.setMaxWidthPercent(value);
} else if (attribute == R.styleable.yoga_min_height) {
node.setMinHeight(value);
} else if (attribute == R.styleable.yoga_min_height_percent) {
node.setMinHeightPercent(value);
} else if (attribute == R.styleable.yoga_min_width) {
node.setMinWidth(value);
} else if (attribute == R.styleable.yoga_min_width_percent) {
node.setMinWidthPercent(value);
} else if (attribute == R.styleable.yoga_overflow) {
node.setOverflow(YogaOverflow.fromInt(Math.round(value)));
} else if (attribute == R.styleable.yoga_padding_left) {
node.setPadding(YogaEdge.LEFT, value);
} else if (attribute == R.styleable.yoga_padding_top) {
node.setPadding(YogaEdge.TOP, value);
} else if (attribute == R.styleable.yoga_padding_right) {
node.setPadding(YogaEdge.RIGHT, value);
} else if (attribute == R.styleable.yoga_padding_bottom) {
node.setPadding(YogaEdge.BOTTOM, value);
} else if (attribute == R.styleable.yoga_padding_start) {
node.setPadding(YogaEdge.START, value);
} else if (attribute == R.styleable.yoga_padding_end) {
node.setPadding(YogaEdge.END, value);
} else if (attribute == R.styleable.yoga_padding_horizontal) {
node.setPadding(YogaEdge.HORIZONTAL, value);
} else if (attribute == R.styleable.yoga_padding_vertical) {
node.setPadding(YogaEdge.VERTICAL, value);
} else if (attribute == R.styleable.yoga_padding_all) {
node.setPadding(YogaEdge.ALL, value);
} else if (attribute == R.styleable.yoga_padding_percent_left) {
node.setPaddingPercent(YogaEdge.LEFT, value);
} else if (attribute == R.styleable.yoga_padding_percent_top) {
node.setPaddingPercent(YogaEdge.TOP, value);
} else if (attribute == R.styleable.yoga_padding_percent_right) {
node.setPaddingPercent(YogaEdge.RIGHT, value);
} else if (attribute == R.styleable.yoga_padding_percent_bottom) {
node.setPaddingPercent(YogaEdge.BOTTOM, value);
} else if (attribute == R.styleable.yoga_padding_percent_start) {
node.setPaddingPercent(YogaEdge.START, value);
} else if (attribute == R.styleable.yoga_padding_percent_end) {
node.setPaddingPercent(YogaEdge.END, value);
} else if (attribute == R.styleable.yoga_padding_percent_horizontal) {
node.setPaddingPercent(YogaEdge.HORIZONTAL, value);
} else if (attribute == R.styleable.yoga_padding_percent_vertical) {
node.setPaddingPercent(YogaEdge.VERTICAL, value);
} else if (attribute == R.styleable.yoga_padding_percent_all) {
node.setPaddingPercent(YogaEdge.ALL, value);
} else if (attribute == R.styleable.yoga_position_left) {
node.setPosition(YogaEdge.LEFT, value);
} else if (attribute == R.styleable.yoga_position_top) {
node.setPosition(YogaEdge.TOP, value);
} else if (attribute == R.styleable.yoga_position_right) {
node.setPosition(YogaEdge.RIGHT, value);
} else if (attribute == R.styleable.yoga_position_bottom) {
node.setPosition(YogaEdge.BOTTOM, value);
} else if (attribute == R.styleable.yoga_position_start) {
node.setPosition(YogaEdge.START, value);
} else if (attribute == R.styleable.yoga_position_end) {
node.setPosition(YogaEdge.END, value);
} else if (attribute == R.styleable.yoga_position_horizontal) {
node.setPosition(YogaEdge.HORIZONTAL, value);
} else if (attribute == R.styleable.yoga_position_vertical) {
node.setPosition(YogaEdge.VERTICAL, value);
} else if (attribute == R.styleable.yoga_position_all) {
node.setPosition(YogaEdge.ALL, value);
} else if (attribute == R.styleable.yoga_position_percent_left) {
node.setPositionPercent(YogaEdge.LEFT, value);
} else if (attribute == R.styleable.yoga_position_percent_top) {
node.setPositionPercent(YogaEdge.TOP, value);
} else if (attribute == R.styleable.yoga_position_percent_right) {
node.setPositionPercent(YogaEdge.RIGHT, value);
} else if (attribute == R.styleable.yoga_position_percent_bottom) {
node.setPositionPercent(YogaEdge.BOTTOM, value);
} else if (attribute == R.styleable.yoga_position_percent_start) {
node.setPositionPercent(YogaEdge.START, value);
} else if (attribute == R.styleable.yoga_position_percent_end) {
node.setPositionPercent(YogaEdge.END, value);
} else if (attribute == R.styleable.yoga_position_percent_horizontal) {
node.setPositionPercent(YogaEdge.HORIZONTAL, value);
} else if (attribute == R.styleable.yoga_position_percent_vertical) {
node.setPositionPercent(YogaEdge.VERTICAL, value);
} else if (attribute == R.styleable.yoga_position_percent_all) {
node.setPositionPercent(YogaEdge.ALL, value);
} else if (attribute == R.styleable.yoga_position_type) {
node.setPositionType(YogaPositionType.fromInt(Math.round(value)));
} else if (attribute == R.styleable.yoga_width) {
node.setWidth(value);
} else if (attribute == R.styleable.yoga_width_percent) {
node.setWidthPercent(value);
} else if (attribute == R.styleable.yoga_wrap) {
node.setWrap(YogaWrap.fromInt(Math.round(value)));
}
}
}
@Override
public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) {
return new YogaLayout.LayoutParams(getContext(), attrs);
}
@Override
protected ViewGroup.LayoutParams generateDefaultLayoutParams() {
return new YogaLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT);
}
@Override
protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
return new YogaLayout.LayoutParams(p);
}
@Override
protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
return p instanceof LayoutParams;
}
/**
* {@code YogaLayout.LayoutParams} are used by views to tell {@link YogaLayout} how they want to
* be laid out. More precisely, the specify the yoga parameters of the view.
*
* <p>
* This is actually mostly a wrapper around a {@code SparseArray} that holds a mapping between
* styleable id's ({@code R.styleable.yoga_*}) and the float of their values. In cases where the
* value is an enum or an integer, they should first be cast to int (with rounding) before using.
*/
public static class LayoutParams extends ViewGroup.LayoutParams {
/**
* A mapping from attribute keys ({@code R.styleable.yoga_*}) to the float of their values.
* For attributes like position_percent_left (float), this is the native type. For attributes
* like align_self (enums), the integer enum value is cast (rounding is used on the other side
* to prevent precision errors). Dimension attributes are stored as float pixels.
*/
SparseArray<Float> attributes;
/**
* Constructs a set of layout params from a source set. In the case that the source set is
* actually a {@link YogaLayout.LayoutParams}, we can copy all the yoga attributes. Otherwise
* we start with a blank slate.
*
* @param source The layout params to copy from
*/
public LayoutParams(ViewGroup.LayoutParams source) {
super(source);
if (source instanceof LayoutParams) {
attributes = ((LayoutParams) source).attributes.clone();
} else {
attributes = new SparseArray<>();
// Negative values include MATCH_PARENT and WRAP_CONTENT
if (source.width >= 0) {
attributes.put(R.styleable.yoga_width, (float) width);
}
if (source.height >= 0) {
attributes.put(R.styleable.yoga_height, (float) height);
}
}
}
/**
* Constructs a set of layout params, given width and height specs. In this case, we can set
* the {@code yoga:width} and {@code yoga:height} if we are given them explicitly. If other
* options (such as {@code match_parent} or {@code wrap_content} are given, then the parent
* LayoutParams will store them, and we deal with them during layout. (see
* {@link YogaLayout#createLayout})
*
* @param width the requested width, either a pixel size, {@code WRAP_CONTENT} or
* {@code MATCH_PARENT}.
* @param height the requested height, either a pixel size, {@code WRAP_CONTENT} or
* {@code MATCH_PARENT}.
*/
public LayoutParams(int width, int height) {
super(width, height);
attributes = new SparseArray<>();
// Negative values include MATCH_PARENT and WRAP_CONTENT
if (width >= 0) {
attributes.put(R.styleable.yoga_width, (float) width);
}
if (height >= 0) {
attributes.put(R.styleable.yoga_height, (float) height);
}
}
/**
* Constructs a set of layout params, given attributes. Grabs all the {@code yoga:*}
* defined in {@code ALL_YOGA_ATTRIBUTES} and collects the ones that are set in {@code attrs}.
*
* @param context the application environment
* @param attrs the set of attributes from which to extract the yoga specific attributes
*/
public LayoutParams(Context context, AttributeSet attrs) {
super(context, attrs);
attributes = new SparseArray<>();
final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.yoga);
// Negative values include MATCH_PARENT and WRAP_CONTENT
if (width >= 0) {
attributes.put(R.styleable.yoga_width, (float) width);
}
if (height >= 0) {
attributes.put(R.styleable.yoga_height, (float) height);
}
final int attributeCount = a.getIndexCount();
for (int i = 0; i < attributeCount; i++) {
final int attribute = a.getIndex(i);
final TypedValue val = new TypedValue();
a.getValue(attribute, val);
if (val.type == TypedValue.TYPE_DIMENSION) {
attributes.put(
attribute,
(float) a.getDimensionPixelSize(attribute, 0));
} else {
attributes.put(attribute, a.getFloat(attribute, 0));
}
}
a.recycle();
}
}
/**
* Wrapper around measure function for yoga leaves.
*/
public static class ViewMeasureFunction implements YogaMeasureFunction {
/**
* A function to measure leaves of the Yoga tree. Yoga needs some way to know how large
* elements want to be. This function passes that question directly through to the relevant
* {@code View}'s measure function.
*
* @param node The yoga node to measure
* @param width The suggested width from the parent
* @param widthMode The type of suggestion for the width
* @param height The suggested height from the parent
* @param heightMode The type of suggestion for the height
* @return A measurement output ({@code YogaMeasureOutput}) for the node
*/
public long measure(
YogaNodeAPI node,
float width,
YogaMeasureMode widthMode,
float height,
YogaMeasureMode heightMode) {
final View view = (View) node.getData();
if (view == null || view instanceof YogaLayout) {
return YogaMeasureOutput.make(0, 0);
}
final int widthMeasureSpec = MeasureSpec.makeMeasureSpec(
(int) width,
viewMeasureSpecFromYogaMeasureMode(widthMode));
final int heightMeasureSpec = MeasureSpec.makeMeasureSpec(
(int) height,
viewMeasureSpecFromYogaMeasureMode(heightMode));
view.measure(widthMeasureSpec, heightMeasureSpec);
return YogaMeasureOutput.make(view.getMeasuredWidth(), view.getMeasuredHeight());
}
private int viewMeasureSpecFromYogaMeasureMode(YogaMeasureMode mode) {
if (mode == YogaMeasureMode.AT_MOST) {
return MeasureSpec.AT_MOST;
} else if (mode == YogaMeasureMode.EXACTLY) {
return MeasureSpec.EXACTLY;
} else {
return MeasureSpec.UNSPECIFIED;
}
}
}
}

View File

@@ -0,0 +1,59 @@
/**
* 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.android;
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
/**
* A layout inflater factory. This provides our custom {@link YogaViewLayoutFactory#onCreateView}
* to the XML inflation system, allowing us to replace XML tags.
*/
public class YogaViewLayoutFactory implements LayoutInflater.Factory {
private static YogaViewLayoutFactory sYogaViewLayoutFactory;
/**
* Obtains (and initialises if necessary) the singleton {@link YogaViewLayoutFactory}.
*
* @return The singleton instance
*/
public static YogaViewLayoutFactory getInstance() {
if (sYogaViewLayoutFactory == null) {
sYogaViewLayoutFactory = new YogaViewLayoutFactory();
}
return sYogaViewLayoutFactory;
}
YogaViewLayoutFactory() {}
/**
* Hook for inflating from a LayoutInflater. This hook replaces the cumbersome
* {@code com.facebook.etc.YogaLayout} with simply {@code YogaLayout} in your XML and the same
* with {@code VirtualYogaLayout}.
*
* @param name Tag name to be inflated.
* @param context The context the view is being created in.
* @param attrs Inflation attributes as specified in XML file.
*
* @return View Newly created view. Return null for the default behavior.
*/
@Override
public View onCreateView(String name, Context context, AttributeSet attrs) {
if (YogaLayout.class.getSimpleName().equals(name)) {
return new YogaLayout(context, attrs);
}
if (VirtualYogaLayout.class.getSimpleName().equals(name)) {
return new VirtualYogaLayout(context, attrs);
}
return null;
}
}

View File

@@ -0,0 +1,185 @@
<?xml version="1.0" encoding="utf-8" ?>
<!--
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.
-->
<resources>
<declare-styleable name="yoga">
<attr name="align_content" format="enum">
<enum name="auto" value="0"/>
<enum name="flex_start" value="1"/>
<enum name="center" value="2"/>
<enum name="flex_end" value="3"/>
<enum name="stretch" value="4"/>
<enum name="baseline" value="5"/>
</attr>
<attr name="align_items" format="enum">
<enum name="auto" value="0"/>
<enum name="flex_start" value="1"/>
<enum name="center" value="2"/>
<enum name="flex_end" value="3"/>
<enum name="stretch" value="4"/>
<enum name="baseline" value="5"/>
</attr>
<attr name="align_self" format="enum">
<enum name="auto" value="0"/>
<enum name="flex_start" value="1"/>
<enum name="center" value="2"/>
<enum name="flex_end" value="3"/>
<enum name="stretch" value="4"/>
<enum name="baseline" value="5"/>
</attr>
<attr name="aspect_ratio" format="float"/>
<attr name="border_left" format="dimension"/>
<attr name="border_top" format="dimension"/>
<attr name="border_right" format="dimension"/>
<attr name="border_bottom" format="dimension"/>
<attr name="border_start" format="dimension"/>
<attr name="border_end" format="dimension"/>
<attr name="border_horizontal" format="dimension"/>
<attr name="border_vertical" format="dimension"/>
<attr name="border_all" format="dimension"/>
<attr name="direction" format="enum">
<enum name="inherit" value="0"/>
<enum name="ltr" value="1"/>
<enum name="rtl" value="2"/>
</attr>
<attr name="flex" format="float"/>
<attr name="flex_basis" format="float"/>
<attr name="flex_basis_percent" format="float"/>
<attr name="flex_direction" format="enum">
<enum name="column" value="0"/>
<enum name="column_reverse" value="1"/>
<enum name="row" value="2"/>
<enum name="row_reverse" value="3"/>
</attr>
<attr name="flex_grow" format="float"/>
<attr name="flex_shrink" format="float"/>
<attr name="height" format="dimension"/>
<attr name="height_percent" format="float"/>
<attr name="justify_content" format="enum">
<enum name="flex_start" value="0"/>
<enum name="center" value="1"/>
<enum name="flex_end" value="2"/>
<enum name="space_between" value="3"/>
<enum name="space_around" value="4"/>
</attr>
<attr name="margin_left" format="dimension"/>
<attr name="margin_top" format="dimension"/>
<attr name="margin_right" format="dimension"/>
<attr name="margin_bottom" format="dimension"/>
<attr name="margin_start" format="dimension"/>
<attr name="margin_end" format="dimension"/>
<attr name="margin_horizontal" format="dimension"/>
<attr name="margin_vertical" format="dimension"/>
<attr name="margin_all" format="dimension"/>
<attr name="margin_percent_left" format="dimension"/>
<attr name="margin_percent_top" format="dimension"/>
<attr name="margin_percent_right" format="dimension"/>
<attr name="margin_percent_bottom" format="dimension"/>
<attr name="margin_percent_start" format="dimension"/>
<attr name="margin_percent_end" format="dimension"/>
<attr name="margin_percent_horizontal" format="dimension"/>
<attr name="margin_percent_vertical" format="dimension"/>
<attr name="margin_percent_all" format="dimension"/>
<attr name="max_height" format="dimension"/>
<attr name="max_height_percent" format="float"/>
<attr name="max_width" format="dimension"/>
<attr name="max_width_percent" format="float"/>
<attr name="min_height" format="dimension"/>
<attr name="min_height_percent" format="float"/>
<attr name="min_width" format="dimension"/>
<attr name="min_width_percent" format="float"/>
<attr name="overflow" format="enum">
<enum name="visible" value="0"/>
<enum name="hidden" value="1"/>
<enum name="scroll" value="2"/>
</attr>
<attr name="padding_left" format="dimension"/>
<attr name="padding_top" format="dimension"/>
<attr name="padding_right" format="dimension"/>
<attr name="padding_bottom" format="dimension"/>
<attr name="padding_start" format="dimension"/>
<attr name="padding_end" format="dimension"/>
<attr name="padding_horizontal" format="dimension"/>
<attr name="padding_vertical" format="dimension"/>
<attr name="padding_all" format="dimension"/>
<attr name="padding_percent_left" format="float"/>
<attr name="padding_percent_top" format="float"/>
<attr name="padding_percent_right" format="float"/>
<attr name="padding_percent_bottom" format="float"/>
<attr name="padding_percent_start" format="float"/>
<attr name="padding_percent_end" format="float"/>
<attr name="padding_percent_horizontal" format="float"/>
<attr name="padding_percent_vertical" format="float"/>
<attr name="padding_percent_all" format="float"/>
<attr name="position_left" format="dimension"/>
<attr name="position_top" format="dimension"/>
<attr name="position_right" format="dimension"/>
<attr name="position_bottom" format="dimension"/>
<attr name="position_start" format="dimension"/>
<attr name="position_end" format="dimension"/>
<attr name="position_horizontal" format="dimension"/>
<attr name="position_vertical" format="dimension"/>
<attr name="position_all" format="dimension"/>
<attr name="position_percent_left" format="float"/>
<attr name="position_percent_top" format="float"/>
<attr name="position_percent_right" format="float"/>
<attr name="position_percent_bottom" format="float"/>
<attr name="position_percent_start" format="float"/>
<attr name="position_percent_end" format="float"/>
<attr name="position_percent_horizontal" format="float"/>
<attr name="position_percent_vertical" format="float"/>
<attr name="position_percent_all" format="float"/>
<attr name="position_type" format="enum">
<enum name="relative" value="0"/>
<enum name="absolute" value="1"/>
</attr>
<attr name="width" format="dimension"/>
<attr name="width_percent" format="float"/>
<attr name="wrap" format="enum">
<enum name="no_wrap" value="0"/>
<enum name="wrap" value="1"/>
</attr>
</declare-styleable>
</resources>

31
build.gradle Normal file
View File

@@ -0,0 +1,31 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.2.2'
classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3'
classpath 'com.github.dcendents:android-maven-gradle-plugin:1.4.1'
classpath 'com.nabilhachicha:android-native-dependencies:0.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
flatDir {
dirs "${rootDir}/lib/jsr-305"
dirs "${rootDir}/lib/soloader"
dirs "${rootDir}/lib/appcompat"
dirs "${rootDir}/lib/android-support"
}
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}

View File

@@ -8,7 +8,7 @@
<OutputType>Library</OutputType>
<RootNamespace>Facebook.Yoga.Android.Tests</RootNamespace>
<AssemblyName>Facebook.Yoga.Android.Tests</AssemblyName>
<TargetFrameworkVersion>v7.0</TargetFrameworkVersion>
<TargetFrameworkVersion>v7.1</TargetFrameworkVersion>
<AndroidApplication>True</AndroidApplication>
<AndroidResgenFile>Resources\Resource.designer.cs</AndroidResgenFile>
<AndroidResgenClass>Resource</AndroidResgenClass>
@@ -16,6 +16,7 @@
<MonoAndroidAssetsPrefix>Assets</MonoAndroidAssetsPrefix>
<AndroidUseLatestPlatformSdk>true</AndroidUseLatestPlatformSdk>
<AndroidManifest>Properties\AndroidManifest.xml</AndroidManifest>
<AndroidTlsProvider></AndroidTlsProvider>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>

View File

@@ -7,13 +7,14 @@
<ProjectTypeGuids>{EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<OutputType>Library</OutputType>
<RootNamespace>Facebook.Yoga.Android</RootNamespace>
<AssemblyName>Facebook.Yoga.Android</AssemblyName>
<TargetFrameworkVersion>v7.0</TargetFrameworkVersion>
<AssemblyName>Facebook.Yoga</AssemblyName>
<TargetFrameworkVersion>v7.1</TargetFrameworkVersion>
<AndroidResgenFile>Resources\Resource.designer.cs</AndroidResgenFile>
<AndroidResgenClass>Resource</AndroidResgenClass>
<MonoAndroidResourcePrefix>Resources</MonoAndroidResourcePrefix>
<MonoAndroidAssetsPrefix>Assets</MonoAndroidAssetsPrefix>
<AndroidUseLatestPlatformSdk>true</AndroidUseLatestPlatformSdk>
<AndroidTlsProvider></AndroidTlsProvider>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>

View File

@@ -34,12 +34,11 @@ cxx_library(
visibility = ['PUBLIC'],
)
with allow_unsafe_import():
import os
if os.path.isdir('/Applications/Xcode.app'):
if isdir('/Applications/Xcode.app'):
yoganet_ios_srcs = []
for arch in ['iphonesimulator-x86_64', 'iphoneos-arm64', 'iphoneos-armv7']:
for arch in [
'iphonesimulator-x86_64', 'iphonesimulator-i386', 'iphoneos-arm64', 'iphoneos-armv7'
]:
name = 'yoganet-' + arch
yoganet_ios_srcs.append(':' + name)
genrule(
@@ -61,3 +60,15 @@ if os.path.isdir('/Applications/Xcode.app'):
cmd = 'lipo $SRCS -create -output $OUT',
visibility = ['PUBLIC'],
)
yoganet_macosx_target = 'csharp:yoganet#macosx-%s,dynamic'
genrule(
name = 'yoganet-macosx',
srcs = [
yoga_dep(yoganet_macosx_target % 'x86_64'),
yoga_dep(yoganet_macosx_target % 'i386'),
],
out = 'libyoga.dylib',
cmd = 'lipo $SRCS -create -output $OUT',
visibility = ['PUBLIC'],
)

View File

@@ -0,0 +1,130 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2012
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Android", "Android", "{B674A497-DC8E-4286-A889-0C004235AA18}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "iOS", "iOS", "{AC14A7DE-A180-46EC-8A88-77F60E73A099}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared", "Shared", "{09905D88-652D-4A72-8521-6CB1AF347795}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "macOS", "macOS", "{9BDE3670-188E-470F-9B89-CEC0EB042AB5}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Facebook.Yoga.iOS", "iOS\Facebook.Yoga.iOS\Facebook.Yoga.iOS.csproj", "{128FB32A-C4A1-4363-BF06-0A36E700B7FA}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Facebook.Yoga.iOS.Tests", "iOS\Facebook.Yoga.iOS.Tests\Facebook.Yoga.iOS.Tests.csproj", "{FCF0BE59-AE56-4D4F-8524-94532B2DFC71}"
EndProject
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Facebook.Yoga.Shared", "Facebook.Yoga\Facebook.Yoga.Shared.shproj", "{91C42D32-291D-4B72-90B4-551663D60B8B}"
EndProject
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Facebook.Yoga.Shared.Tests", "tests\Facebook.Yoga\Facebook.Yoga.Shared.Tests.shproj", "{4EDC82D9-A201-4831-8FE0-98F468F8E4AE}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Facebook.Yoga.Android", "Android\Facebook.Yoga.Android\Facebook.Yoga.Android.csproj", "{EDF7CF8B-5640-4E1D-A2C7-E4BC8BE44363}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Facebook.Yoga.Android.Tests", "Android\Facebook.Yoga.Android.Tests\Facebook.Yoga.Android.Tests.csproj", "{2021459E-8FB1-44A4-89F1-E291769CD2C6}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "nuspec", "nuspec", "{2C3685DB-91B9-4207-9446-1C513DB36978}"
ProjectSection(SolutionItems) = preProject
nuget\Facebook.Yoga.dll.config = nuget\Facebook.Yoga.dll.config
nuget\Facebook.Yoga.nuspec = nuget\Facebook.Yoga.nuspec
nuget\Facebook.Yoga.OSX.targets = nuget\Facebook.Yoga.OSX.targets
nuget\Facebook.Yoga.targets = nuget\Facebook.Yoga.targets
nuget\Facebook.Yoga.Universal.targets = nuget\Facebook.Yoga.Universal.targets
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Facebook.Yoga.Mac", "Mac\Facebook.Yoga.Mac.csproj", "{19A1C7D7-C9CC-476A-B604-DF6A3DE1BA71}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Facebook.Yoga.Mac.Tests", "Mac\Facebook.Yoga.Mac.Tests\Facebook.Yoga.Mac.Tests.csproj", "{9FCB6149-DFA8-4EAA-B4DB-2E91A5D8FF77}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
Debug|iPhoneSimulator = Debug|iPhoneSimulator
Release|iPhone = Release|iPhone
Release|iPhoneSimulator = Release|iPhoneSimulator
Debug|iPhone = Debug|iPhone
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{128FB32A-C4A1-4363-BF06-0A36E700B7FA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{128FB32A-C4A1-4363-BF06-0A36E700B7FA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{128FB32A-C4A1-4363-BF06-0A36E700B7FA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{128FB32A-C4A1-4363-BF06-0A36E700B7FA}.Release|Any CPU.Build.0 = Release|Any CPU
{128FB32A-C4A1-4363-BF06-0A36E700B7FA}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{128FB32A-C4A1-4363-BF06-0A36E700B7FA}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{128FB32A-C4A1-4363-BF06-0A36E700B7FA}.Release|iPhone.ActiveCfg = Release|Any CPU
{128FB32A-C4A1-4363-BF06-0A36E700B7FA}.Release|iPhone.Build.0 = Release|Any CPU
{128FB32A-C4A1-4363-BF06-0A36E700B7FA}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{128FB32A-C4A1-4363-BF06-0A36E700B7FA}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{128FB32A-C4A1-4363-BF06-0A36E700B7FA}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{128FB32A-C4A1-4363-BF06-0A36E700B7FA}.Debug|iPhone.Build.0 = Debug|Any CPU
{FCF0BE59-AE56-4D4F-8524-94532B2DFC71}.Debug|Any CPU.ActiveCfg = Debug|iPhoneSimulator
{FCF0BE59-AE56-4D4F-8524-94532B2DFC71}.Debug|Any CPU.Build.0 = Debug|iPhoneSimulator
{FCF0BE59-AE56-4D4F-8524-94532B2DFC71}.Release|Any CPU.ActiveCfg = Release|iPhone
{FCF0BE59-AE56-4D4F-8524-94532B2DFC71}.Release|Any CPU.Build.0 = Release|iPhone
{FCF0BE59-AE56-4D4F-8524-94532B2DFC71}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator
{FCF0BE59-AE56-4D4F-8524-94532B2DFC71}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator
{FCF0BE59-AE56-4D4F-8524-94532B2DFC71}.Release|iPhone.ActiveCfg = Release|iPhone
{FCF0BE59-AE56-4D4F-8524-94532B2DFC71}.Release|iPhone.Build.0 = Release|iPhone
{FCF0BE59-AE56-4D4F-8524-94532B2DFC71}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator
{FCF0BE59-AE56-4D4F-8524-94532B2DFC71}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator
{FCF0BE59-AE56-4D4F-8524-94532B2DFC71}.Debug|iPhone.ActiveCfg = Debug|iPhone
{FCF0BE59-AE56-4D4F-8524-94532B2DFC71}.Debug|iPhone.Build.0 = Debug|iPhone
{EDF7CF8B-5640-4E1D-A2C7-E4BC8BE44363}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EDF7CF8B-5640-4E1D-A2C7-E4BC8BE44363}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EDF7CF8B-5640-4E1D-A2C7-E4BC8BE44363}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EDF7CF8B-5640-4E1D-A2C7-E4BC8BE44363}.Release|Any CPU.Build.0 = Release|Any CPU
{EDF7CF8B-5640-4E1D-A2C7-E4BC8BE44363}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{EDF7CF8B-5640-4E1D-A2C7-E4BC8BE44363}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{EDF7CF8B-5640-4E1D-A2C7-E4BC8BE44363}.Release|iPhone.ActiveCfg = Release|Any CPU
{EDF7CF8B-5640-4E1D-A2C7-E4BC8BE44363}.Release|iPhone.Build.0 = Release|Any CPU
{EDF7CF8B-5640-4E1D-A2C7-E4BC8BE44363}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{EDF7CF8B-5640-4E1D-A2C7-E4BC8BE44363}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{EDF7CF8B-5640-4E1D-A2C7-E4BC8BE44363}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{EDF7CF8B-5640-4E1D-A2C7-E4BC8BE44363}.Debug|iPhone.Build.0 = Debug|Any CPU
{2021459E-8FB1-44A4-89F1-E291769CD2C6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2021459E-8FB1-44A4-89F1-E291769CD2C6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2021459E-8FB1-44A4-89F1-E291769CD2C6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2021459E-8FB1-44A4-89F1-E291769CD2C6}.Release|Any CPU.Build.0 = Release|Any CPU
{2021459E-8FB1-44A4-89F1-E291769CD2C6}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{2021459E-8FB1-44A4-89F1-E291769CD2C6}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{2021459E-8FB1-44A4-89F1-E291769CD2C6}.Release|iPhone.ActiveCfg = Release|Any CPU
{2021459E-8FB1-44A4-89F1-E291769CD2C6}.Release|iPhone.Build.0 = Release|Any CPU
{2021459E-8FB1-44A4-89F1-E291769CD2C6}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{2021459E-8FB1-44A4-89F1-E291769CD2C6}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{2021459E-8FB1-44A4-89F1-E291769CD2C6}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{2021459E-8FB1-44A4-89F1-E291769CD2C6}.Debug|iPhone.Build.0 = Debug|Any CPU
{19A1C7D7-C9CC-476A-B604-DF6A3DE1BA71}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{19A1C7D7-C9CC-476A-B604-DF6A3DE1BA71}.Debug|Any CPU.Build.0 = Debug|Any CPU
{19A1C7D7-C9CC-476A-B604-DF6A3DE1BA71}.Release|Any CPU.ActiveCfg = Release|Any CPU
{19A1C7D7-C9CC-476A-B604-DF6A3DE1BA71}.Release|Any CPU.Build.0 = Release|Any CPU
{19A1C7D7-C9CC-476A-B604-DF6A3DE1BA71}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{19A1C7D7-C9CC-476A-B604-DF6A3DE1BA71}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{19A1C7D7-C9CC-476A-B604-DF6A3DE1BA71}.Release|iPhone.ActiveCfg = Release|Any CPU
{19A1C7D7-C9CC-476A-B604-DF6A3DE1BA71}.Release|iPhone.Build.0 = Release|Any CPU
{19A1C7D7-C9CC-476A-B604-DF6A3DE1BA71}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{19A1C7D7-C9CC-476A-B604-DF6A3DE1BA71}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{19A1C7D7-C9CC-476A-B604-DF6A3DE1BA71}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{19A1C7D7-C9CC-476A-B604-DF6A3DE1BA71}.Debug|iPhone.Build.0 = Debug|Any CPU
{9FCB6149-DFA8-4EAA-B4DB-2E91A5D8FF77}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9FCB6149-DFA8-4EAA-B4DB-2E91A5D8FF77}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9FCB6149-DFA8-4EAA-B4DB-2E91A5D8FF77}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9FCB6149-DFA8-4EAA-B4DB-2E91A5D8FF77}.Release|Any CPU.Build.0 = Release|Any CPU
{9FCB6149-DFA8-4EAA-B4DB-2E91A5D8FF77}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{9FCB6149-DFA8-4EAA-B4DB-2E91A5D8FF77}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{9FCB6149-DFA8-4EAA-B4DB-2E91A5D8FF77}.Release|iPhone.ActiveCfg = Release|Any CPU
{9FCB6149-DFA8-4EAA-B4DB-2E91A5D8FF77}.Release|iPhone.Build.0 = Release|Any CPU
{9FCB6149-DFA8-4EAA-B4DB-2E91A5D8FF77}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{9FCB6149-DFA8-4EAA-B4DB-2E91A5D8FF77}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{9FCB6149-DFA8-4EAA-B4DB-2E91A5D8FF77}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{9FCB6149-DFA8-4EAA-B4DB-2E91A5D8FF77}.Debug|iPhone.Build.0 = Debug|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{128FB32A-C4A1-4363-BF06-0A36E700B7FA} = {AC14A7DE-A180-46EC-8A88-77F60E73A099}
{FCF0BE59-AE56-4D4F-8524-94532B2DFC71} = {AC14A7DE-A180-46EC-8A88-77F60E73A099}
{91C42D32-291D-4B72-90B4-551663D60B8B} = {09905D88-652D-4A72-8521-6CB1AF347795}
{4EDC82D9-A201-4831-8FE0-98F468F8E4AE} = {09905D88-652D-4A72-8521-6CB1AF347795}
{EDF7CF8B-5640-4E1D-A2C7-E4BC8BE44363} = {B674A497-DC8E-4286-A889-0C004235AA18}
{2021459E-8FB1-44A4-89F1-E291769CD2C6} = {B674A497-DC8E-4286-A889-0C004235AA18}
{19A1C7D7-C9CC-476A-B604-DF6A3DE1BA71} = {9BDE3670-188E-470F-9B89-CEC0EB042AB5}
{9FCB6149-DFA8-4EAA-B4DB-2E91A5D8FF77} = {9BDE3670-188E-470F-9B89-CEC0EB042AB5}
EndGlobalSection
EndGlobal

View File

@@ -18,6 +18,7 @@
<Compile Include="$(MSBuildThisFileDirectory)YogaConstants.cs" />
<Compile Include="$(MSBuildThisFileDirectory)YogaDimension.cs" />
<Compile Include="$(MSBuildThisFileDirectory)YogaDirection.cs" />
<Compile Include="$(MSBuildThisFileDirectory)YogaDisplay.cs" />
<Compile Include="$(MSBuildThisFileDirectory)YogaEdge.cs" />
<Compile Include="$(MSBuildThisFileDirectory)YogaExperimentalFeature.cs" />
<Compile Include="$(MSBuildThisFileDirectory)YogaFlexDirection.cs" />
@@ -37,4 +38,4 @@
<Compile Include="$(MSBuildThisFileDirectory)YogaValueExtensions.cs" />
<Compile Include="$(MSBuildThisFileDirectory)YogaWrap.cs" />
</ItemGroup>
</Project>
</Project>

View File

@@ -22,6 +22,10 @@ namespace Facebook.Yoga
internal class YGNodeHandle : SafeHandle
{
#if (UNITY_IOS && !UNITY_EDITOR) || __IOS__
private GCHandle _managed;
#endif
private YGNodeHandle() : base(IntPtr.Zero, true)
{
}
@@ -36,10 +40,39 @@ namespace Facebook.Yoga
protected override bool ReleaseHandle()
{
#if (UNITY_IOS && !UNITY_EDITOR) || __IOS__
if (_managed.IsAllocated)
{
_managed.Free();
}
#endif
Native.YGNodeFree(this.handle);
GC.KeepAlive(this);
return true;
}
#if (UNITY_IOS && !UNITY_EDITOR) || __IOS__
public void SetContext(YogaNode node)
{
if (!_managed.IsAllocated)
{
_managed = GCHandle.Alloc(node, GCHandleType.Weak);
Native.YGNodeSetContext(this.handle, GCHandle.ToIntPtr(_managed));
}
}
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
}
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
@@ -68,16 +101,20 @@ namespace Facebook.Yoga
YogaExperimentalFeature feature);
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
public static extern void YGNodeInsertChild(YGNodeHandle node, YGNodeHandle child, uint index);
public static extern void YGNodeInsertChild(
YGNodeHandle node,
YGNodeHandle child,
uint index);
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
public static extern void YGNodeRemoveChild(YGNodeHandle node, YGNodeHandle child);
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
public static extern void YGNodeCalculateLayout(YGNodeHandle node,
float availableWidth,
float availableHeight,
YogaDirection parentDirection);
public static extern void YGNodeCalculateLayout(
YGNodeHandle node,
float availableWidth,
float availableHeight,
YogaDirection parentDirection);
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
public static extern void YGNodeMarkDirty(YGNodeHandle node);
@@ -105,7 +142,9 @@ namespace Facebook.Yoga
[MarshalAs(UnmanagedType.FunctionPtr)] YogaBaselineFunc baselineFunc);
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
public static extern void YGNodeSetHasNewLayout(YGNodeHandle node, [MarshalAs(UnmanagedType.I1)] bool hasNewLayout);
public static extern void YGNodeSetHasNewLayout(
YGNodeHandle node,
[MarshalAs(UnmanagedType.I1)] bool hasNewLayout);
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
@@ -196,6 +235,9 @@ namespace Facebook.Yoga
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
public static extern void YGNodeStyleSetFlexBasisPercent(YGNodeHandle node, float flexBasis);
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
public static extern void YGNodeStyleSetFlexBasisAuto(YGNodeHandle node);
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
public static extern YogaValue YGNodeStyleGetFlexBasis(YGNodeHandle node);
@@ -205,6 +247,9 @@ namespace Facebook.Yoga
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
public static extern void YGNodeStyleSetWidthPercent(YGNodeHandle node, float width);
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
public static extern void YGNodeStyleSetWidthAuto(YGNodeHandle node);
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
public static extern YogaValue YGNodeStyleGetWidth(YGNodeHandle node);
@@ -213,6 +258,9 @@ namespace Facebook.Yoga
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
public static extern void YGNodeStyleSetHeightPercent(YGNodeHandle node, float height);
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
public static extern void YGNodeStyleSetHeightAuto(YGNodeHandle node);
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
public static extern YogaValue YGNodeStyleGetHeight(YGNodeHandle node);
@@ -278,6 +326,9 @@ namespace Facebook.Yoga
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
public static extern void YGNodeStyleSetMarginPercent(YGNodeHandle node, YogaEdge edge, float margin);
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
public static extern void YGNodeStyleSetMarginAuto(YGNodeHandle node, YogaEdge edge);
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
public static extern YogaValue YGNodeStyleGetMargin(YGNodeHandle node, YogaEdge edge);
@@ -328,5 +379,17 @@ namespace Facebook.Yoga
public static extern YogaDirection YGNodeLayoutGetDirection(YGNodeHandle node);
#endregion
#region IOS
#if (UNITY_IOS && !UNITY_EDITOR) || __IOS__
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr YGNodeGetContext(IntPtr node);
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
public static extern void YGNodeSetContext(IntPtr node, IntPtr managed);
#endif
#endregion
}
}

View File

@@ -17,5 +17,7 @@ namespace Facebook.Yoga
FlexEnd,
Stretch,
Baseline,
SpaceBetween,
SpaceAround,
}
}

View File

@@ -10,6 +10,10 @@
using System;
using System.Runtime.InteropServices;
#if __IOS__
using ObjCRuntime;
#endif
namespace Facebook.Yoga
{
internal static class YogaLogger
@@ -18,25 +22,30 @@ namespace Facebook.Yoga
public delegate void Func(YogaLogLevel level, string message);
private static bool _initialized;
private static Func _managedLogger = null;
private static Func _managedLogger = LoggerInternal;
public static Func Logger = null;
#if (UNITY_IOS && !UNITY_EDITOR) || __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)
{
_managedLogger = (level, message) => {
if (Logger != null)
{
Logger(level, message);
}
if (level == YogaLogLevel.Error)
{
throw new InvalidOperationException(message);
}
};
Native.YGInteropSetLogger(_managedLogger);
_initialized = true;
}

View File

@@ -226,6 +226,10 @@ namespace Facebook.Yoga
{
Native.YGNodeStyleSetMarginPercent(_ygNode, edge, value.Value);
}
else if (value.Unit == YogaUnit.Auto)
{
Native.YGNodeStyleSetMarginAuto(_ygNode, edge);
}
else
{
Native.YGNodeStyleSetMargin(_ygNode, edge, value.Value);

View File

@@ -12,6 +12,13 @@ using System.Collections;
using System.Collections.Generic;
using System.Text;
#if (UNITY_IOS && !UNITY_EDITOR) || __IOS__
using System.Runtime.InteropServices;
#endif
#if __IOS__
using ObjCRuntime;
#endif
namespace Facebook.Yoga
{
public partial class YogaNode : IEnumerable<YogaNode>
@@ -20,10 +27,15 @@ namespace Facebook.Yoga
private WeakReference _parent;
private List<YogaNode> _children;
private MeasureFunction _measureFunction;
private YogaMeasureFunc _ygMeasureFunc;
private BaselineFunction _baselineFunction;
private YogaBaselineFunc _ygBaselineFunc;
private object _data;
#if (UNITY_IOS && !UNITY_EDITOR) || __IOS__
private static YogaMeasureFunc _managedMeasure = MeasureInternalIOS;
private static YogaBaselineFunc _managedBaseline = BaselineInternalIOS;
#else
private YogaMeasureFunc _managedMeasure;
private YogaBaselineFunc _managedBaseline;
#endif
public YogaNode()
{
@@ -270,6 +282,10 @@ namespace Facebook.Yoga
{
Native.YGNodeStyleSetFlexBasisPercent(_ygNode, value.Value);
}
else if (value.Unit == YogaUnit.Auto)
{
Native.YGNodeStyleSetFlexBasisAuto(_ygNode);
}
else
{
Native.YGNodeStyleSetFlexBasis(_ygNode, value.Value);
@@ -290,6 +306,10 @@ namespace Facebook.Yoga
{
Native.YGNodeStyleSetWidthPercent(_ygNode, value.Value);
}
else if (value.Unit == YogaUnit.Auto)
{
Native.YGNodeStyleSetWidthAuto(_ygNode);
}
else
{
Native.YGNodeStyleSetWidth(_ygNode, value.Value);
@@ -310,6 +330,10 @@ namespace Facebook.Yoga
{
Native.YGNodeStyleSetHeightPercent(_ygNode, value.Value);
}
else if (value.Unit == YogaUnit.Auto)
{
Native.YGNodeStyleSetHeightAuto(_ygNode);
}
else
{
Native.YGNodeStyleSetHeight(_ygNode, value.Value);
@@ -545,15 +569,29 @@ namespace Facebook.Yoga
public void SetMeasureFunction(MeasureFunction measureFunction)
{
_measureFunction = measureFunction;
_ygMeasureFunc = measureFunction != null ? MeasureInternal : (YogaMeasureFunc)null;
Native.YGNodeSetMeasureFunc(_ygNode, _ygMeasureFunc);
if (measureFunction != null)
{
#if (UNITY_IOS && !UNITY_EDITOR) || __IOS__
_ygNode.SetContext(this);
#else
_managedMeasure = MeasureInternal;
#endif
}
Native.YGNodeSetMeasureFunc(_ygNode, _managedMeasure);
}
public void SetBaselineFunction(BaselineFunction baselineFunction)
{
_baselineFunction = baselineFunction;
_ygBaselineFunc = baselineFunction != null ? BaselineInternal : (YogaBaselineFunc)null;
Native.YGNodeSetBaselineFunc(_ygNode, _ygBaselineFunc);
if (baselineFunction != null)
{
#if (UNITY_IOS && !UNITY_EDITOR) || __IOS__
_ygNode.SetContext(this);
#else
_managedBaseline = BaselineInternal;
#endif
}
Native.YGNodeSetBaselineFunc(_ygNode, _managedBaseline);
}
public void CalculateLayout()
@@ -565,6 +603,20 @@ namespace Facebook.Yoga
Native.YGNodeStyleGetDirection(_ygNode));
}
#if (UNITY_IOS && !UNITY_EDITOR) || __IOS__
[MonoPInvokeCallback(typeof(YogaMeasureFunc))]
private static YogaSize MeasureInternalIOS(
IntPtr ygNodePtr,
float width,
YogaMeasureMode widthMode,
float height,
YogaMeasureMode heightMode)
{
var node = Native.YGNodeHandle.GetManaged(ygNodePtr);
return node.MeasureInternal(IntPtr.Zero, width, widthMode, height, heightMode);
}
#endif
private YogaSize MeasureInternal(
IntPtr node,
float width,
@@ -580,6 +632,18 @@ namespace Facebook.Yoga
return _measureFunction(this, width, widthMode, height, heightMode);
}
#if (UNITY_IOS && !UNITY_EDITOR) || __IOS__
[MonoPInvokeCallback(typeof(YogaBaselineFunc))]
private static float BaselineInternalIOS(
IntPtr ygNodePtr,
float width,
float height)
{
var node = Native.YGNodeHandle.GetManaged(ygNodePtr);
return node.BaselineInternal(IntPtr.Zero, width, height);
}
#endif
private float BaselineInternal(IntPtr node, float width, float height)
{
if (_baselineFunction == null)

View File

@@ -12,7 +12,8 @@ namespace Facebook.Yoga
public enum YogaUnit
{
Undefined,
Pixel,
Point,
Percent,
Auto,
}
}

View File

@@ -33,12 +33,12 @@ namespace Facebook.Yoga
}
}
public static YogaValue Pixel(float value)
public static YogaValue Point(float value)
{
return new YogaValue
{
value = value,
unit = YogaConstants.IsUndefined(value) ? YogaUnit.Undefined : YogaUnit.Pixel
unit = YogaConstants.IsUndefined(value) ? YogaUnit.Undefined : YogaUnit.Point
};
}
@@ -70,6 +70,15 @@ namespace Facebook.Yoga
};
}
public static YogaValue Auto()
{
return new YogaValue
{
value = 0f,
unit = YogaUnit.Auto
};
}
public static YogaValue Percent(float value)
{
return new YogaValue
@@ -79,9 +88,9 @@ namespace Facebook.Yoga
};
}
public static implicit operator YogaValue(float pixelValue)
public static implicit operator YogaValue(float pointValue)
{
return Pixel(pixelValue);
return Point(pointValue);
}
}
}

View File

@@ -16,9 +16,9 @@ namespace Facebook.Yoga
return YogaValue.Percent(value);
}
public static YogaValue Px(this float value)
public static YogaValue Pt(this float value)
{
return YogaValue.Pixel(value);
return YogaValue.Point(value);
}
public static YogaValue Percent(this int value)
@@ -26,9 +26,9 @@ namespace Facebook.Yoga
return YogaValue.Percent(value);
}
public static YogaValue Px(this int value)
public static YogaValue Pt(this int value)
{
return YogaValue.Pixel(value);
return YogaValue.Point(value);
}
}
}

View File

@@ -13,5 +13,6 @@ namespace Facebook.Yoga
{
NoWrap,
Wrap,
WrapReverse,
}
}

View File

@@ -854,9 +854,9 @@ namespace Facebook.YogaKit
}
}
static double RoundPixelValue(float value)
static double RoundPointValue(float value)
{
float scale = NativePixelScale;
float scale = NativePointScale;
return Math.Round(value * scale) / scale;
}

View File

@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<CompileDependsOn>NativeLibrary;$(CompileDependsOn)</CompileDependsOn>
</PropertyGroup>
<Target Name="NativeLibrary" Outputs="$(ProjectDir)libyoga.dylib">
<Exec WorkingDirectory="$(ProjectDir)" Command="$(ProjectDir)buck-build.sh //csharp:yoganet#default,shared" />
<Copy SourceFiles="$(ProjectDir)..\..\buck-out\gen\csharp\yoganet#default,shared\libyoga.dylib" DestinationFiles="$(ProjectDir)libyoga.dylib" SkipUnchangedFiles="true" />
</Target>
</Project>
<PropertyGroup>
<CompileDependsOn>NativeLibrary;$(CompileDependsOn)</CompileDependsOn>
</PropertyGroup>
<Target Name="NativeLibrary" Outputs="$(ProjectDir)libyoga.dylib">
<Exec WorkingDirectory="$(ProjectDir)" Command="$(ProjectDir)buck-build.sh //csharp:yoganet-macosx" />
<Copy SourceFiles="$(ProjectDir)..\..\buck-out\gen\csharp\yoganet-macosx\libyoga.dylib" DestinationFiles="$(ProjectDir)libyoga.dylib" SkipUnchangedFiles="true" />
</Target>
</Project>

View File

@@ -1,78 +1,78 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{9FCB6149-DFA8-4EAA-B4DB-2E91A5D8FF77}</ProjectGuid>
<ProjectTypeGuids>{A3F8F2AB-B479-4A4A-A458-A89E7DC349F1};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<OutputType>Exe</OutputType>
<RootNamespace>Facebook.Yoga.Mac.Tests</RootNamespace>
<AssemblyName>Facebook.Yoga.Mac.Tests</AssemblyName>
<TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
<TargetFrameworkIdentifier>Xamarin.Mac</TargetFrameworkIdentifier>
<MonoMacResourcePrefix>Resources</MonoMacResourcePrefix>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug</OutputPath>
<DefineConstants>DEBUG;</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<EnableCodeSigning>false</EnableCodeSigning>
<CodeSigningKey>Mac Developer</CodeSigningKey>
<CreatePackage>false</CreatePackage>
<EnablePackageSigning>false</EnablePackageSigning>
<IncludeMonoRuntime>false</IncludeMonoRuntime>
<UseSGen>true</UseSGen>
<UseRefCounting>true</UseRefCounting>
<Profiling>true</Profiling>
<HttpClientHandler>HttpClientHandler</HttpClientHandler>
<TlsProvider>Default</TlsProvider>
<LinkMode>None</LinkMode>
<XamMacArch>x86_64</XamMacArch>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release</OutputPath>
<DefineConstants></DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<EnableCodeSigning>false</EnableCodeSigning>
<CreatePackage>true</CreatePackage>
<EnablePackageSigning>false</EnablePackageSigning>
<IncludeMonoRuntime>true</IncludeMonoRuntime>
<UseSGen>true</UseSGen>
<UseRefCounting>true</UseRefCounting>
<LinkMode>SdkOnly</LinkMode>
<HttpClientHandler>HttpClientHandler</HttpClientHandler>
<TlsProvider>Default</TlsProvider>
<XamMacArch></XamMacArch>
</PropertyGroup>
<ItemGroup>
<Reference Include="nunit.framework">
<HintPath>..\packages\NUnit.2.6.4\lib\nunit.framework.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Folder Include="Resources\" />
</ItemGroup>
<ItemGroup>
<None Include="Info.plist" />
<None Include="Entitlements.plist" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Compile Include="Main.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Facebook.Yoga.Mac.csproj">
<Project>{19A1C7D7-C9CC-476A-B604-DF6A3DE1BA71}</Project>
<Name>Facebook.Yoga.Mac</Name>
</ProjectReference>
</ItemGroup>
<Import Project="..\..\tests\Facebook.Yoga\Facebook.Yoga.Shared.Tests.projitems" Label="Shared" Condition="Exists('..\..\tests\Facebook.Yoga\Facebook.Yoga.Shared.Tests.projitems')" />
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Mac\Xamarin.Mac.CSharp.targets" />
</Project>
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{9FCB6149-DFA8-4EAA-B4DB-2E91A5D8FF77}</ProjectGuid>
<ProjectTypeGuids>{A3F8F2AB-B479-4A4A-A458-A89E7DC349F1};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<OutputType>Exe</OutputType>
<RootNamespace>Facebook.Yoga.Mac.Tests</RootNamespace>
<AssemblyName>Facebook.Yoga.Mac.Tests</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<MonoMacResourcePrefix>Resources</MonoMacResourcePrefix>
<UseXamMacFullFramework>true</UseXamMacFullFramework>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug</OutputPath>
<DefineConstants>DEBUG;</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<EnableCodeSigning>false</EnableCodeSigning>
<CodeSigningKey>Mac Developer</CodeSigningKey>
<CreatePackage>false</CreatePackage>
<EnablePackageSigning>false</EnablePackageSigning>
<IncludeMonoRuntime>false</IncludeMonoRuntime>
<UseSGen>true</UseSGen>
<UseRefCounting>true</UseRefCounting>
<Profiling>true</Profiling>
<HttpClientHandler>HttpClientHandler</HttpClientHandler>
<TlsProvider>Default</TlsProvider>
<LinkMode>None</LinkMode>
<XamMacArch>x86_64</XamMacArch>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release</OutputPath>
<DefineConstants>
</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<EnableCodeSigning>false</EnableCodeSigning>
<CreatePackage>true</CreatePackage>
<EnablePackageSigning>false</EnablePackageSigning>
<IncludeMonoRuntime>true</IncludeMonoRuntime>
<UseSGen>true</UseSGen>
<UseRefCounting>true</UseRefCounting>
<LinkMode>None</LinkMode>
<HttpClientHandler>HttpClientHandler</HttpClientHandler>
<TlsProvider>Default</TlsProvider>
<XamMacArch>
</XamMacArch>
</PropertyGroup>
<ItemGroup>
<Reference Include="Xamarin.Mac" />
<Reference Include="GuiUnit">
<HintPath>..\..\packages\MonoDevelop.Addins.GuiUnit.0.1.1\lib\net45\GuiUnit.exe</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<None Include="Info.plist" />
<None Include="Entitlements.plist" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Compile Include="Main.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Facebook.Yoga.Mac.csproj">
<Project>{19A1C7D7-C9CC-476A-B604-DF6A3DE1BA71}</Project>
<Name>Facebook.Yoga.Mac</Name>
</ProjectReference>
</ItemGroup>
<Import Project="..\..\tests\Facebook.Yoga\Facebook.Yoga.Shared.Tests.projitems" Label="Shared" Condition="Exists('..\..\tests\Facebook.Yoga\Facebook.Yoga.Shared.Tests.projitems')" />
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Mac\Xamarin.Mac.CSharp.targets" />
</Project>

View File

@@ -7,14 +7,52 @@
*/
using System;
using System.Reflection;
using System.Collections.Generic;
using AppKit;
using Foundation;
using GuiUnit;
using NUnit.Framework;
namespace Facebook.Yoga.Mac.Tests
{
static class MainClass
{
static void Main(string[] args)
{
}
}
static class MainClass
{
static void Main(string[] args)
{
NSApplication.Init();
RunTests();
}
static void RunTests()
{
TestRunner.MainLoop = new NSRunLoopIntegration();
List<string> args = new List<string>() { typeof(MainClass).Assembly.Location, "-labels", "-noheader", "-result=TEST-Mac.xml" };
TestRunner.Main(args.ToArray());
}
class NSRunLoopIntegration : NSObject, IMainLoopIntegration
{
public void InitializeToolkit()
{
}
public void RunMainLoop()
{
NSApplication.SharedApplication.Run();
}
public void InvokeOnMainLoop(InvokerHelper helper)
{
NSApplication.SharedApplication.InvokeOnMainThread(helper.Invoke);
}
public void Shutdown()
{
Environment.Exit(TestRunner.ExitCode);
}
}
}
}

View File

@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="NUnit" version="2.6.4" targetFramework="xamarinmac20" />
<package id="MonoDevelop.Addins.GuiUnit" version="0.1.1" targetFramework="net45" />
</packages>

View File

@@ -7,7 +7,7 @@
<ProjectTypeGuids>{810C163F-4746-4721-8B8E-88A3673A62EA};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<OutputType>Library</OutputType>
<RootNamespace>Facebook.Yoga.Mac</RootNamespace>
<AssemblyName>Facebook.Yoga.Mac</AssemblyName>
<AssemblyName>Facebook.Yoga</AssemblyName>
<MacResourcePrefix>Resources</MacResourcePrefix>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">

2
csharp/Mac/run-tests.sh Executable file
View File

@@ -0,0 +1,2 @@
#!/bin/sh
./csharp/Mac/Facebook.Yoga.Mac.Tests/bin/Release/Facebook.Yoga.Mac.Tests.app/Contents/MacOS/Facebook.Yoga.Mac.Tests

View File

@@ -0,0 +1,131 @@
<?xml version="1.0" encoding="utf-8" ?>
<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<NativeRootPath>$(SolutionDir)..\Yoga\bin\Universal\</NativeRootPath>
<NativeX86Path>$(NativeRootPath)x86\</NativeX86Path>
<NativeX64Path>$(NativeRootPath)x64\</NativeX64Path>
<NativeARMPath>$(NativeRootPath)ARM\</NativeARMPath>
<NativeDLLMoniker>Yoga</NativeDLLMoniker>
<CurrentPlatform Condition="$(PROCESSOR_ARCHITECTURE) =='AMD64' or $(PROCESSOR_ARCHITECTURE) == 'IA64' or $(PROCESSOR_ARCHITEW6432) == 'AMD64'">AMD64</CurrentPlatform>
<CurrentPlatform Condition="$(PROCESSOR_ARCHITECTURE) =='ARM'">ARM</CurrentPlatform>
</PropertyGroup>
<Choose>
<When Condition="$(Platform) == 'AnyCPU'">
<Choose>
<When Condition="$(Prefer32Bit) == 'true'">
<ItemGroup Condition="$(CurrentPlatform) == 'x86' Or $(CurrentPlatform) == 'AMD64'">
<Content Include="$(NativeX86Path)$(Configuration)\$(NativeDLLMoniker).dll">
<Link>$(NativeDLLMoniker).dll</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<Visible>False</Visible>
</Content>
<Content Include="$(NativeX86Path)$(Configuration)\$(NativeDLLMoniker).pdb">
<Link>$(NativeDLLMoniker).pdb</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<Visible>False</Visible>
</Content>
</ItemGroup>
<ItemGroup Condition="$(CurrentPlatform) == 'ARM'">
<Content Include="$(NativeARMPath)$(Configuration)\$(NativeDLLMoniker).dll">
<Link>$(NativeDLLMoniker).dll</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<Visible>False</Visible>
</Content>
<Content Include="$(NativeARMPath)$(Configuration)\$(NativeDLLMoniker).pdb">
<Link>$(NativeDLLMoniker).pdb</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<Visible>False</Visible>
</Content>
</ItemGroup>
</When>
<Otherwise>
<ItemGroup Condition="$(CurrentPlatform) == 'x86'">
<Content Include="$(NativeX86Path)$(Configuration)\$(NativeDLLMoniker).dll">
<Link>$(NativeDLLMoniker).dll</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<Visible>False</Visible>
</Content>
<Content Include="$(NativeX86Path)$(Configuration)\$(NativeDLLMoniker).pdb">
<Link>$(NativeDLLMoniker).pdb</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<Visible>False</Visible>
</Content>
</ItemGroup>
<ItemGroup Condition="$(CurrentPlatform) == 'AMD64'">
<Content Include="$(NativeX64Path)$(Configuration)\$(NativeDLLMoniker).dll">
<Link>$(NativeDLLMoniker).dll</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<Visible>False</Visible>
</Content>
<Content Include="$(NativeX64Path)$(Configuration)\$(NativeDLLMoniker).pdb">
<Link>$(NativeDLLMoniker).pdb</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<Visible>False</Visible>
</Content>
</ItemGroup>
<ItemGroup Condition="$(CurrentPlatform) == 'ARM'">
<Content Include="$(NativeARMPath)$(Configuration)\$(NativeDLLMoniker).dll">
<Link>$(NativeDLLMoniker).dll</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<Visible>False</Visible>
</Content>
<Content Include="$(NativeARMPath)$(Configuration)\$(NativeDLLMoniker).pdb">
<Link>$(NativeDLLMoniker).pdb</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<Visible>False</Visible>
</Content>
</ItemGroup>
</Otherwise>
</Choose>
</When>
<Otherwise>
<ItemGroup Condition="$(PlatformTarget) == 'x86'">
<Content Include="$(NativeX86Path)$(Configuration)\$(NativeDLLMoniker).dll">
<Link>$(NativeDLLMoniker).dll</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<Visible>False</Visible>
</Content>
<Content Include="$(NativeX86Path)$(Configuration)\$(NativeDLLMoniker).pdb">
<Link>$(NativeDLLMoniker).pdb</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<Visible>False</Visible>
</Content>
</ItemGroup>
<ItemGroup Condition="$(PlatformTarget) == 'x64'">
<Content Include="$(NativeX64Path)$(Configuration)\$(NativeDLLMoniker).dll">
<Link>$(NativeDLLMoniker).dll</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<Visible>False</Visible>
</Content>
<Content Include="$(NativeX64Path)$(Configuration)\$(NativeDLLMoniker).pdb">
<Link>$(NativeDLLMoniker).pdb</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<Visible>False</Visible>
</Content>
</ItemGroup>
<ItemGroup Condition="$(PlatformTarget) == 'ARM'">
<!--<Content Include="$(NativeARMPath)$(Configuration)\$(NativeDLLMoniker).dll">
<Link>$(NativeDLLMoniker).dll</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<Visible>False</Visible>
</Content>
<Content Include="$(NativeARMPath)$(Configuration)\$(NativeDLLMoniker).pdb">
<Link>$(NativeDLLMoniker).pdb</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<Visible>False</Visible>
</Content>-->
<Content Include="$(NativeX86Path)$(Configuration)\$(NativeDLLMoniker).dll">
<Link>$(NativeDLLMoniker).dll</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<Visible>False</Visible>
</Content>
<Content Include="$(NativeX86Path)$(Configuration)\$(NativeDLLMoniker).pdb">
<Link>$(NativeDLLMoniker).pdb</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<Visible>False</Visible>
</Content>
</ItemGroup>
</Otherwise>
</Choose>
</Project>

View File

@@ -92,7 +92,6 @@
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="..\..\tests\Facebook.Yoga\Facebook.Yoga.Shared.Tests.projitems" Label="Shared" />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="$(SolutionDir)Build\Facebook.Yoga.NativeInterop.targets" Condition="Exists('$(SolutionDir)Build\Facebook.Yoga.NativeInterop.targets')" Label="ImportNativeInteropTargets" />
<Target Name="EnsureNativeInteropImports" BeforeTargets="PrepareForBuild">

View File

@@ -129,15 +129,18 @@
<Name>Facebook.Yoga</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
</ItemGroup>
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' &lt; '14.0' ">
<VisualStudioVersion>14.0</VisualStudioVersion>
</PropertyGroup>
<Import Project="$(MSBuildExtensionsPath)\Microsoft\WindowsXaml\v$(VisualStudioVersion)\Microsoft.Windows.UI.Xaml.CSharp.targets" />
<Import Project="$(SolutionDir)Build\Facebook.Yoga.NativeInterop.targets" Condition="Exists('$(SolutionDir)Build\Facebook.Yoga.NativeInterop.targets')" Label="ImportNativeInteropTargets" />
<Import Project="$(SolutionDir)Build\Facebook.Yoga.NativeInterop.Universal.targets" Condition="Exists('$(SolutionDir)Build\Facebook.Yoga.NativeInterop.Universal.targets')" Label="ImportNativeInteropTargets" />
<Target Name="EnsureNativeInteropImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references a native interop target that is missing. The missing build target is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('$(SolutionDir)Build\Facebook.Yoga.NativeInterop.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)Build\Facebook.Yoga.NativeInterop.targets'))" />
<Error Condition="!Exists('$(SolutionDir)Build\Facebook.Yoga.NativeInterop.Universal.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)Build\Facebook.Yoga.NativeInterop.Universal.targets'))" />
</Target>
</Project>

View File

@@ -9,7 +9,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Native", "Native", "{51A8E8
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "NETStandard", "NETStandard", "{DCF7899B-A487-49C0-BCDE-DC088B6750C2}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "yoga", "..\Yoga\Yoga.vcxproj", "{0446C86B-F47B-4C46-B673-C7AE0CFF35D5}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "yoga.uwp", "..\Yoga\Yoga.Universal.vcxproj", "{2EACF721-73B5-46AE-9775-4A8674D05A9C}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared", "Shared", "{39A2FFDA-C093-4FA6-8143-45B5019E7DAC}"
EndProject
@@ -17,7 +17,7 @@ Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Facebook.Yoga.Shared", "..\
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Facebook.Yoga", "Facebook.Yoga\Facebook.Yoga.csproj", "{3AACE384-FDEC-4D91-A3B2-EEB21B46C9AD}"
ProjectSection(ProjectDependencies) = postProject
{0446C86B-F47B-4C46-B673-C7AE0CFF35D5} = {0446C86B-F47B-4C46-B673-C7AE0CFF35D5}
{2EACF721-73B5-46AE-9775-4A8674D05A9C} = {2EACF721-73B5-46AE-9775-4A8674D05A9C}
EndProjectSection
EndProject
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Facebook.Yoga.Shared.Tests", "..\tests\Facebook.Yoga\Facebook.Yoga.Shared.Tests.shproj", "{4EDC82D9-A201-4831-8FE0-98F468F8E4AE}"
@@ -41,20 +41,20 @@ Global
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{0446C86B-F47B-4C46-B673-C7AE0CFF35D5}.Debug|Any CPU.ActiveCfg = Debug|Win32
{0446C86B-F47B-4C46-B673-C7AE0CFF35D5}.Debug|ARM.ActiveCfg = Debug|ARM
{0446C86B-F47B-4C46-B673-C7AE0CFF35D5}.Debug|ARM.Build.0 = Debug|ARM
{0446C86B-F47B-4C46-B673-C7AE0CFF35D5}.Debug|x64.ActiveCfg = Debug|x64
{0446C86B-F47B-4C46-B673-C7AE0CFF35D5}.Debug|x64.Build.0 = Debug|x64
{0446C86B-F47B-4C46-B673-C7AE0CFF35D5}.Debug|x86.ActiveCfg = Debug|Win32
{0446C86B-F47B-4C46-B673-C7AE0CFF35D5}.Debug|x86.Build.0 = Debug|Win32
{0446C86B-F47B-4C46-B673-C7AE0CFF35D5}.Release|Any CPU.ActiveCfg = Release|Win32
{0446C86B-F47B-4C46-B673-C7AE0CFF35D5}.Release|ARM.ActiveCfg = Release|ARM
{0446C86B-F47B-4C46-B673-C7AE0CFF35D5}.Release|ARM.Build.0 = Release|ARM
{0446C86B-F47B-4C46-B673-C7AE0CFF35D5}.Release|x64.ActiveCfg = Release|x64
{0446C86B-F47B-4C46-B673-C7AE0CFF35D5}.Release|x64.Build.0 = Release|x64
{0446C86B-F47B-4C46-B673-C7AE0CFF35D5}.Release|x86.ActiveCfg = Release|Win32
{0446C86B-F47B-4C46-B673-C7AE0CFF35D5}.Release|x86.Build.0 = Release|Win32
{2EACF721-73B5-46AE-9775-4A8674D05A9C}.Debug|Any CPU.ActiveCfg = Debug|Win32
{2EACF721-73B5-46AE-9775-4A8674D05A9C}.Debug|ARM.ActiveCfg = Debug|ARM
{2EACF721-73B5-46AE-9775-4A8674D05A9C}.Debug|ARM.Build.0 = Debug|ARM
{2EACF721-73B5-46AE-9775-4A8674D05A9C}.Debug|x64.ActiveCfg = Debug|x64
{2EACF721-73B5-46AE-9775-4A8674D05A9C}.Debug|x64.Build.0 = Debug|x64
{2EACF721-73B5-46AE-9775-4A8674D05A9C}.Debug|x86.ActiveCfg = Debug|Win32
{2EACF721-73B5-46AE-9775-4A8674D05A9C}.Debug|x86.Build.0 = Debug|Win32
{2EACF721-73B5-46AE-9775-4A8674D05A9C}.Release|Any CPU.ActiveCfg = Release|Win32
{2EACF721-73B5-46AE-9775-4A8674D05A9C}.Release|ARM.ActiveCfg = Release|ARM
{2EACF721-73B5-46AE-9775-4A8674D05A9C}.Release|ARM.Build.0 = Release|ARM
{2EACF721-73B5-46AE-9775-4A8674D05A9C}.Release|x64.ActiveCfg = Release|x64
{2EACF721-73B5-46AE-9775-4A8674D05A9C}.Release|x64.Build.0 = Release|x64
{2EACF721-73B5-46AE-9775-4A8674D05A9C}.Release|x86.ActiveCfg = Release|Win32
{2EACF721-73B5-46AE-9775-4A8674D05A9C}.Release|x86.Build.0 = Release|Win32
{3AACE384-FDEC-4D91-A3B2-EEB21B46C9AD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3AACE384-FDEC-4D91-A3B2-EEB21B46C9AD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3AACE384-FDEC-4D91-A3B2-EEB21B46C9AD}.Debug|ARM.ActiveCfg = Debug|ARM
@@ -96,7 +96,7 @@ Global
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{0446C86B-F47B-4C46-B673-C7AE0CFF35D5} = {51A8E803-C084-431F-9130-F277481C2BB2}
{2EACF721-73B5-46AE-9775-4A8674D05A9C} = {51A8E803-C084-431F-9130-F277481C2BB2}
{91C42D32-291D-4B72-90B4-551663D60B8B} = {39A2FFDA-C093-4FA6-8143-45B5019E7DAC}
{3AACE384-FDEC-4D91-A3B2-EEB21B46C9AD} = {DCF7899B-A487-49C0-BCDE-DC088B6750C2}
{4EDC82D9-A201-4831-8FE0-98F468F8E4AE} = {39A2FFDA-C093-4FA6-8143-45B5019E7DAC}

View File

@@ -11,6 +11,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "NETStandard", "NETStandard"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "yoga", "..\Yoga\Yoga.vcxproj", "{0446C86B-F47B-4C46-B673-C7AE0CFF35D5}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "yoga.uwp", "..\Yoga\Yoga.Universal.vcxproj", "{2EACF721-73B5-46AE-9775-4A8674D05A9C}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared", "Shared", "{39A2FFDA-C093-4FA6-8143-45B5019E7DAC}"
EndProject
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Facebook.Yoga.Shared", "..\Facebook.Yoga\Facebook.Yoga.Shared.shproj", "{91C42D32-291D-4B72-90B4-551663D60B8B}"
@@ -18,6 +20,7 @@ EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Facebook.Yoga", "Facebook.Yoga\Facebook.Yoga.csproj", "{3AACE384-FDEC-4D91-A3B2-EEB21B46C9AD}"
ProjectSection(ProjectDependencies) = postProject
{0446C86B-F47B-4C46-B673-C7AE0CFF35D5} = {0446C86B-F47B-4C46-B673-C7AE0CFF35D5}
{2EACF721-73B5-46AE-9775-4A8674D05A9C} = {2EACF721-73B5-46AE-9775-4A8674D05A9C}
EndProjectSection
EndProject
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Facebook.Yoga.Shared.Tests", "..\tests\Facebook.Yoga\Facebook.Yoga.Shared.Tests.shproj", "{4EDC82D9-A201-4831-8FE0-98F468F8E4AE}"
@@ -31,7 +34,6 @@ Global
..\Facebook.Yoga\Facebook.Yoga.Shared.projitems*{3aace384-fdec-4d91-a3b2-eeb21b46c9ad}*SharedItemsImports = 4
..\tests\Facebook.Yoga\Facebook.Yoga.Shared.Tests.projitems*{4edc82d9-a201-4831-8fe0-98f468f8e4ae}*SharedItemsImports = 13
..\Facebook.Yoga\Facebook.Yoga.Shared.projitems*{91c42d32-291d-4b72-90b4-551663d60b8b}*SharedItemsImports = 13
..\tests\Facebook.Yoga\Facebook.Yoga.Shared.Tests.projitems*{ac23f444-5545-4196-8b9f-5c1f6b3e7fb3}*SharedItemsImports = 4
EndGlobalSection
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -52,12 +54,28 @@ Global
{0446C86B-F47B-4C46-B673-C7AE0CFF35D5}.Debug|x86.ActiveCfg = Debug|Win32
{0446C86B-F47B-4C46-B673-C7AE0CFF35D5}.Debug|x86.Build.0 = Debug|Win32
{0446C86B-F47B-4C46-B673-C7AE0CFF35D5}.Release|Any CPU.ActiveCfg = Release|Win32
{0446C86B-F47B-4C46-B673-C7AE0CFF35D5}.Release|Any CPU.Build.0 = Release|Win32
{0446C86B-F47B-4C46-B673-C7AE0CFF35D5}.Release|ARM.ActiveCfg = Release|ARM
{0446C86B-F47B-4C46-B673-C7AE0CFF35D5}.Release|ARM.Build.0 = Release|ARM
{0446C86B-F47B-4C46-B673-C7AE0CFF35D5}.Release|x64.ActiveCfg = Release|x64
{0446C86B-F47B-4C46-B673-C7AE0CFF35D5}.Release|x64.Build.0 = Release|x64
{0446C86B-F47B-4C46-B673-C7AE0CFF35D5}.Release|x86.ActiveCfg = Release|Win32
{0446C86B-F47B-4C46-B673-C7AE0CFF35D5}.Release|x86.Build.0 = Release|Win32
{2EACF721-73B5-46AE-9775-4A8674D05A9C}.Debug|Any CPU.ActiveCfg = Debug|Win32
{2EACF721-73B5-46AE-9775-4A8674D05A9C}.Debug|ARM.ActiveCfg = Debug|ARM
{2EACF721-73B5-46AE-9775-4A8674D05A9C}.Debug|ARM.Build.0 = Debug|ARM
{2EACF721-73B5-46AE-9775-4A8674D05A9C}.Debug|x64.ActiveCfg = Debug|x64
{2EACF721-73B5-46AE-9775-4A8674D05A9C}.Debug|x64.Build.0 = Debug|x64
{2EACF721-73B5-46AE-9775-4A8674D05A9C}.Debug|x86.ActiveCfg = Debug|Win32
{2EACF721-73B5-46AE-9775-4A8674D05A9C}.Debug|x86.Build.0 = Debug|Win32
{2EACF721-73B5-46AE-9775-4A8674D05A9C}.Release|Any CPU.ActiveCfg = Release|Win32
{2EACF721-73B5-46AE-9775-4A8674D05A9C}.Release|Any CPU.Build.0 = Release|Win32
{2EACF721-73B5-46AE-9775-4A8674D05A9C}.Release|ARM.ActiveCfg = Release|ARM
{2EACF721-73B5-46AE-9775-4A8674D05A9C}.Release|ARM.Build.0 = Release|ARM
{2EACF721-73B5-46AE-9775-4A8674D05A9C}.Release|x64.ActiveCfg = Release|x64
{2EACF721-73B5-46AE-9775-4A8674D05A9C}.Release|x64.Build.0 = Release|x64
{2EACF721-73B5-46AE-9775-4A8674D05A9C}.Release|x86.ActiveCfg = Release|Win32
{2EACF721-73B5-46AE-9775-4A8674D05A9C}.Release|x86.Build.0 = Release|Win32
{3AACE384-FDEC-4D91-A3B2-EEB21B46C9AD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3AACE384-FDEC-4D91-A3B2-EEB21B46C9AD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3AACE384-FDEC-4D91-A3B2-EEB21B46C9AD}.Debug|ARM.ActiveCfg = Debug|ARM
@@ -83,13 +101,9 @@ Global
{AC23F444-5545-4196-8B9F-5C1F6B3E7FB3}.Debug|x86.ActiveCfg = Debug|x86
{AC23F444-5545-4196-8B9F-5C1F6B3E7FB3}.Debug|x86.Build.0 = Debug|x86
{AC23F444-5545-4196-8B9F-5C1F6B3E7FB3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AC23F444-5545-4196-8B9F-5C1F6B3E7FB3}.Release|Any CPU.Build.0 = Release|Any CPU
{AC23F444-5545-4196-8B9F-5C1F6B3E7FB3}.Release|ARM.ActiveCfg = Release|Any CPU
{AC23F444-5545-4196-8B9F-5C1F6B3E7FB3}.Release|ARM.Build.0 = Release|Any CPU
{AC23F444-5545-4196-8B9F-5C1F6B3E7FB3}.Release|x64.ActiveCfg = Release|x64
{AC23F444-5545-4196-8B9F-5C1F6B3E7FB3}.Release|x64.Build.0 = Release|x64
{AC23F444-5545-4196-8B9F-5C1F6B3E7FB3}.Release|x86.ActiveCfg = Release|x86
{AC23F444-5545-4196-8B9F-5C1F6B3E7FB3}.Release|x86.Build.0 = Release|x86
{0C76D2FE-6767-44FE-B03D-21B2076BAA73}.Debug|Any CPU.ActiveCfg = Debug|x86
{0C76D2FE-6767-44FE-B03D-21B2076BAA73}.Debug|ARM.ActiveCfg = Debug|ARM
{0C76D2FE-6767-44FE-B03D-21B2076BAA73}.Debug|ARM.Build.0 = Debug|ARM
@@ -102,20 +116,15 @@ Global
{0C76D2FE-6767-44FE-B03D-21B2076BAA73}.Debug|x86.Deploy.0 = Debug|x86
{0C76D2FE-6767-44FE-B03D-21B2076BAA73}.Release|Any CPU.ActiveCfg = Release|x86
{0C76D2FE-6767-44FE-B03D-21B2076BAA73}.Release|ARM.ActiveCfg = Release|ARM
{0C76D2FE-6767-44FE-B03D-21B2076BAA73}.Release|ARM.Build.0 = Release|ARM
{0C76D2FE-6767-44FE-B03D-21B2076BAA73}.Release|ARM.Deploy.0 = Release|ARM
{0C76D2FE-6767-44FE-B03D-21B2076BAA73}.Release|x64.ActiveCfg = Release|x64
{0C76D2FE-6767-44FE-B03D-21B2076BAA73}.Release|x64.Build.0 = Release|x64
{0C76D2FE-6767-44FE-B03D-21B2076BAA73}.Release|x64.Deploy.0 = Release|x64
{0C76D2FE-6767-44FE-B03D-21B2076BAA73}.Release|x86.ActiveCfg = Release|x86
{0C76D2FE-6767-44FE-B03D-21B2076BAA73}.Release|x86.Build.0 = Release|x86
{0C76D2FE-6767-44FE-B03D-21B2076BAA73}.Release|x86.Deploy.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{0446C86B-F47B-4C46-B673-C7AE0CFF35D5} = {51A8E803-C084-431F-9130-F277481C2BB2}
{2EACF721-73B5-46AE-9775-4A8674D05A9C} = {51A8E803-C084-431F-9130-F277481C2BB2}
{91C42D32-291D-4B72-90B4-551663D60B8B} = {39A2FFDA-C093-4FA6-8143-45B5019E7DAC}
{3AACE384-FDEC-4D91-A3B2-EEB21B46C9AD} = {DCF7899B-A487-49C0-BCDE-DC088B6750C2}
{4EDC82D9-A201-4831-8FE0-98F468F8E4AE} = {39A2FFDA-C093-4FA6-8143-45B5019E7DAC}

View File

@@ -93,6 +93,8 @@
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<DocumentationFile>
</DocumentationFile>
</PropertyGroup>
<ItemGroup>
<!-- A reference to the entire .NET Framework is automatically included -->

View File

@@ -1,12 +1,12 @@
{
"dependencies": {
"Microsoft.NETCore.Portable.Compatibility": "1.0.1",
"NETStandard.Library": "1.6.0"
},
"frameworks": {
"netstandard1.1": {}
},
"language": "en",
"supports": {},
"version": "3.0.0-*"
"dependencies": {
"Microsoft.NETCore.Portable.Compatibility": "1.0.1",
"NETStandard.Library": "1.6.1"
},
"frameworks": {
"netstandard1.1": {}
},
"language": "en",
"supports": {},
"version": "3.0.0-*"
}

View File

@@ -0,0 +1,285 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|ARM">
<Configuration>Debug</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM">
<Configuration>Release</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{2EACF721-73B5-46AE-9775-4A8674D05A9C}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<ProjectName>yoga.uwp</ProjectName>
<RootNamespace>Yoga</RootNamespace>
<AppContainerApplication>true</AppContainerApplication>
<ApplicationType>Windows Store</ApplicationType>
<WindowsTargetPlatformVersion>10.0.10586.0</WindowsTargetPlatformVersion>
<WindowsTargetPlatformMinVersion>10.0.10240.0</WindowsTargetPlatformMinVersion>
<ApplicationTypeRevision>10.0</ApplicationTypeRevision>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<OutDir>bin\Universal\$(PlatformTarget)\$(Configuration)\</OutDir>
<IntDir>obj\$(PlatformTarget)\$(Configuration)\</IntDir>
<TargetName>yoga</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
<LinkIncremental>true</LinkIncremental>
<OutDir>bin\Universal\$(PlatformTarget)\$(Configuration)\</OutDir>
<IntDir>obj\$(PlatformTarget)\$(Configuration)\</IntDir>
<TargetName>yoga</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<OutDir>bin\Universal\$(PlatformTarget)\$(Configuration)\</OutDir>
<IntDir>obj\$(PlatformTarget)\$(Configuration)\</IntDir>
<TargetName>yoga</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>bin\Universal\$(PlatformTarget)\$(Configuration)\</OutDir>
<IntDir>obj\$(PlatformTarget)\$(Configuration)\</IntDir>
<TargetName>yoga</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
<LinkIncremental>false</LinkIncremental>
<OutDir>bin\Universal\$(PlatformTarget)\$(Configuration)\</OutDir>
<IntDir>obj\$(PlatformTarget)\$(Configuration)\</IntDir>
<TargetName>yoga</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>bin\Universal\$(PlatformTarget)\$(Configuration)\</OutDir>
<IntDir>obj\$(PlatformTarget)\$(Configuration)\</IntDir>
<TargetName>yoga</TargetName>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;YOGA_EXPORTS;FB_ASSERTIONS_ENABLED=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>$(ProjectDir)..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAsWinRT>false</CompileAsWinRT>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;YOGA_EXPORTS;FB_ASSERTIONS_ENABLED=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>$(ProjectDir)..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAsWinRT>false</CompileAsWinRT>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_DEBUG;_WINDOWS;_USRDLL;YOGA_EXPORTS;FB_ASSERTIONS_ENABLED=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>$(ProjectDir)..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAsWinRT>false</CompileAsWinRT>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;YOGA_EXPORTS;FB_ASSERTIONS_ENABLED=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>$(ProjectDir)..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAsWinRT>false</CompileAsWinRT>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;YOGA_EXPORTS;FB_ASSERTIONS_ENABLED=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>$(ProjectDir)..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAsWinRT>false</CompileAsWinRT>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>NDEBUG;_WINDOWS;_USRDLL;YOGA_EXPORTS;FB_ASSERTIONS_ENABLED=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>$(ProjectDir)..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAsWinRT>false</CompileAsWinRT>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="..\..\yoga\Yoga.h" />
<ClInclude Include="..\..\yoga\YGMacros.h" />
<ClInclude Include="..\..\yoga\YGNodeList.h" />
<ClInclude Include="resource.h" />
<ClInclude Include="YGInterop.h" />
<ClInclude Include="stdafx.h" />
<ClInclude Include="targetver.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\yoga\Yoga.c" />
<ClCompile Include="..\..\yoga\YGNodeList.c" />
<ClCompile Include="YGInterop.cpp" />
<ClCompile Include="dllmain.cpp">
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsManaged>
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">false</CompileAsManaged>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
</PrecompiledHeader>
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</CompileAsManaged>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
</PrecompiledHeader>
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsManaged>
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">false</CompileAsManaged>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
</PrecompiledHeader>
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</CompileAsManaged>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
</PrecompiledHeader>
</ClCompile>
<ClCompile Include="stdafx.cpp" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="Yoga.rc" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@@ -0,0 +1,62 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="stdafx.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="targetver.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\yoga\Yoga.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\yoga\YGMacros.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\yoga\YGNodeList.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="YGInterop.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="resource.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="stdafx.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="dllmain.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\yoga\Yoga.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\yoga\YGNodeList.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="YGInterop.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="Yoga.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
</Project>

16
csharp/build-native.sh Executable file
View File

@@ -0,0 +1,16 @@
#!/bin/sh
if buck --version >/dev/null 2>&1; then true; else
echo "Building Buck!"
mkdir lib
cd lib
git clone https://github.com/facebook/buck.git --depth 1
cd buck
ant
cd ..
cd ..
fi
buck build //:yoga
buck build //csharp:yoganet-ios
buck build //csharp:yoganet-macosx
buck build //csharp:yoganet#android-x86,shared
buck build //csharp:yoganet#android-armv7,shared

View File

@@ -7,7 +7,7 @@
<ProjectTypeGuids>{8FFB629D-F513-41CE-95D2-7ECE97B6EEEC};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<OutputType>Library</OutputType>
<RootNamespace>Facebook.Yoga.iOS</RootNamespace>
<AssemblyName>Facebook.Yoga.iOS</AssemblyName>
<AssemblyName>Facebook.Yoga</AssemblyName>
<IPhoneResourcePrefix>Resources</IPhoneResourcePrefix>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">

View File

@@ -30,7 +30,7 @@ namespace Facebook.YogaKit
{
var topLeft = new CGPoint(node.LayoutX, node.LayoutY);
var bottomRight = new CGPoint(topLeft.X + node.LayoutWidth, topLeft.Y + node.LayoutHeight);
view.Frame = new CGRect(RoundPixelValue((float)topLeft.X), RoundPixelValue((float)topLeft.Y), RoundPixelValue((float)bottomRight.X) - RoundPixelValue((float)topLeft.X), RoundPixelValue((float)bottomRight.Y) - RoundPixelValue((float)topLeft.Y));
view.Frame = new CGRect(RoundPointValue((float)topLeft.X), RoundPointValue((float)topLeft.Y), RoundPointValue((float)bottomRight.X) - RoundPointValue((float)topLeft.X), RoundPointValue((float)bottomRight.Y) - RoundPointValue((float)topLeft.Y));
}
bool _disposed;

View File

@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="utf-8" ?>
<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Condition=" (Exists('packages.config') Or Exists('packages.$(MSBuildProjectName).config')) And '$(Platform)' == 'AnyCPU'">
<Content Include="$(MSBuildThisFileDirectory)..\..\runtimes\uap-x86\native\*">
<Link>x86\%(Filename)%(Extension)</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<Visible>False</Visible>
</Content>
<Content Include="$(MSBuildThisFileDirectory)..\..\runtimes\uap-x64\native\*">
<Link>x64\%(Filename)%(Extension)</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<Visible>False</Visible>
</Content>
</ItemGroup>
<ItemGroup Condition=" (Exists('packages.config') Or Exists('packages.$(MSBuildProjectName).config')) And '$(Platform)' == 'x86'">
<Content Include="$(MSBuildThisFileDirectory)..\..\runtimes\uap-x86\native\*">
<Link>%(Filename)%(Extension)</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<Visible>False</Visible>
</Content>
</ItemGroup>
<ItemGroup Condition=" (Exists('packages.config') Or Exists('packages.$(MSBuildProjectName).config')) And '$(Platform)' == 'x64'">
<Content Include="$(MSBuildThisFileDirectory)..\..\runtimes\uap-x64\native\*">
<Link>%(Filename)%(Extension)</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<Visible>False</Visible>
</Content>
</ItemGroup>
<ItemGroup Condition=" (Exists('packages.config') Or Exists('packages.$(MSBuildProjectName).config')) And '$(Platform)' == 'ARM'">
<Content Include="$(MSBuildThisFileDirectory)..\..\runtimes\uap-arm\native\*">
<Link>%(Filename)%(Extension)</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<Visible>False</Visible>
</Content>
</ItemGroup>
</Project>

View File

@@ -14,15 +14,18 @@
<tags>native flexbox flex-box css layout css-layout yoga facebook</tags>
<dependencies>
<group targetFramework=".NETStandard1.0" />
<group targetFramework="uap10.0" />
</dependencies>
</metadata>
<files>
<!-- build -->
<file src="Facebook.Yoga.Native.targets" target="build\netstandard1.0"/>
<file src="Facebook.Yoga.Native.targets" target="build\uap10.0"/>
<!-- lib -->
<file src="_._" target="lib\netstandard1.0"/>
<file src="_._" target="lib\uap10.0"/>
<!-- Native -->
<file src="..\Yoga\bin\x86\Release\Yoga.dll" target="runtimes\win-x86\native"/>
@@ -33,6 +36,15 @@
<file src="..\Yoga\bin\ARM\Release\Yoga.dll" target="runtimes\win8-arm\native"/>
<file src="..\Yoga\bin\ARM\Release\Yoga.pdb" target="runtimes\win8-arm\native"/>
<file src="..\Yoga\bin\Universal\x86\Release\Yoga.dll" target="runtimes\win10-x86\native"/>
<file src="..\Yoga\bin\Universal\x86\Release\Yoga.pdb" target="runtimes\win10-x86\native"/>
<file src="..\Yoga\bin\Universal\x64\Release\Yoga.dll" target="runtimes\win10-x64\native"/>
<file src="..\Yoga\bin\Universal\x64\Release\Yoga.pdb" target="runtimes\win10-x64\native"/>
<file src="..\Yoga\bin\Universal\ARM\Release\Yoga.dll" target="runtimes\win10-arm\native"/>
<file src="..\Yoga\bin\Universal\ARM\Release\Yoga.pdb" target="runtimes\win10-arm\native"/>
</files>
</package>

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8" ?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<NativeReference Include="$(MSBuildThisFileDirectory)..\..\runtimes\osx\native\libyoga.dylib">
<IsCxx>False</IsCxx>
<Kind>Dynamic</Kind>
</NativeReference>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,51 @@
<?xml version="1.0" encoding="utf-8" ?>
<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Condition=" (Exists('packages.config') Or Exists('packages.$(MSBuildProjectName).config')) And '$(Platform)' == 'AnyCPU'">
<Content Include="$(MSBuildThisFileDirectory)..\..\runtimes\win10-x86\native\*">
<Link>x86\%(Filename)%(Extension)</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<Visible>False</Visible>
</Content>
<Content Include="$(MSBuildThisFileDirectory)..\..\runtimes\win10-x64\native\*">
<Link>x64\%(Filename)%(Extension)</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<Visible>False</Visible>
</Content>
</ItemGroup>
<ItemGroup Condition=" (Exists('packages.config') Or Exists('packages.$(MSBuildProjectName).config')) And '$(Platform)' == 'x86'">
<Content Include="$(MSBuildThisFileDirectory)..\..\runtimes\win10-x86\lib\netstandard\*">
<Link>%(Filename)%(Extension)</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<Visible>False</Visible>
</Content>
<Content Include="$(MSBuildThisFileDirectory)..\..\runtimes\win10-x86\native\*">
<Link>%(Filename)%(Extension)</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<Visible>False</Visible>
</Content>
</ItemGroup>
<ItemGroup Condition=" (Exists('packages.config') Or Exists('packages.$(MSBuildProjectName).config')) And '$(Platform)' == 'x64'">
<Content Include="$(MSBuildThisFileDirectory)..\..\runtimes\win10-x64\lib\netstandard\*">
<Link>%(Filename)%(Extension)</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<Visible>False</Visible>
</Content>
<Content Include="$(MSBuildThisFileDirectory)..\..\runtimes\win10-x64\native\*">
<Link>%(Filename)%(Extension)</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<Visible>False</Visible>
</Content>
</ItemGroup>
<ItemGroup Condition=" (Exists('packages.config') Or Exists('packages.$(MSBuildProjectName).config')) And '$(Platform)' == 'ARM'">
<Content Include="$(MSBuildThisFileDirectory)..\..\runtimes\win10-arm\lib\netstandard\*">
<Link>%(Filename)%(Extension)</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<Visible>False</Visible>
</Content>
<Content Include="$(MSBuildThisFileDirectory)..\..\runtimes\win10-arm\native\*">
<Link>%(Filename)%(Extension)</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<Visible>False</Visible>
</Content>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<dllmap dll="yoga.dll" target="libyoga.dylib" os="!windows" />
</configuration>

View File

@@ -14,33 +14,76 @@
<tags>flexbox flex-box css layout css-layout yoga facebook native</tags>
<dependencies>
<group targetFramework=".NETStandard1.1" />
<group targetFramework="uap10.0" />
</dependencies>
</metadata>
<files>
<!-- build -->
<file src="Facebook.Yoga.targets" target="build\netstandard"/>
<file src="Facebook.Yoga.OSX.targets" target="build\XamarinMac" />
<file src="Facebook.Yoga.targets" target="build\net45" />
<file src="Facebook.Yoga.dll.config" target="build\net45" />
<file src="Facebook.Yoga.Universal.targets" target="build\uap10.0"/>
<!-- lib -->
<file src="..\Windows\Facebook.Yoga\bin\Release\Facebook.Yoga.dll" target="lib\netstandard"/>
<file src="..\yoga_windows\bin\Release\Facebook.Yoga.dll" target="lib\netstandard"/>
<!-- UAP -->
<file src="..\yoga_windows\bin\Release\Facebook.Yoga.dll" target="lib\uap10.0"/>
<!-- net45 -->
<file src="..\yoga_windows\bin\Release\Facebook.Yoga.dll" target="lib\net45" />
<file src="Facebook.Yoga.dll.config" target="lib\net45" />
<!-- iOS -->
<file src="..\yoga_ios\bin\Release\Facebook.Yoga.dll" target="lib\Xamarin.iOS10" />
<!-- macOS -->
<file src="..\yoga_mac\bin\Release\Facebook.Yoga.dll" target="lib\XamarinMac" />
<!-- Android -->
<file src="..\yoga_android\bin\Release\Facebook.Yoga.dll" target="lib\MonoAndroid" />
<!-- runtimes -->
<file src="..\Windows\Facebook.Yoga\bin\x86\Release\Facebook.Yoga.dll" target="runtimes\win-x86\lib\netstandard"/>
<file src="..\Windows\Facebook.Yoga\bin\x86\Release\Facebook.Yoga.pdb" target="runtimes\win-x86\lib\netstandard"/>
<file src="..\yoga_windows\bin\x86\Release\Facebook.Yoga.dll" target="runtimes\win10-x86\lib\netstandard"/>
<file src="..\yoga_windows\bin\x86\Release\Facebook.Yoga.pdb" target="runtimes\win10-x86\lib\netstandard"/>
<file src="..\Windows\Facebook.Yoga\bin\x64\Release\Facebook.Yoga.dll" target="runtimes\win-x64\lib\netstandard"/>
<file src="..\Windows\Facebook.Yoga\bin\x64\Release\Facebook.Yoga.pdb" target="runtimes\win-x64\lib\netstandard"/>
<file src="..\yoga_windows\bin\x64\Release\Facebook.Yoga.dll" target="runtimes\win10-x64\lib\netstandard"/>
<file src="..\yoga_windows\bin\x64\Release\Facebook.Yoga.pdb" target="runtimes\win10-x64\lib\netstandard"/>
<file src="..\Windows\Facebook.Yoga\bin\ARM\Release\Facebook.Yoga.dll" target="runtimes\win8-arm\lib\netstandard"/>
<file src="..\Windows\Facebook.Yoga\bin\ARM\Release\Facebook.Yoga.pdb" target="runtimes\win8-arm\lib\netstandard"/>
<file src="..\yoga_windows\bin\ARM\Release\Facebook.Yoga.dll" target="runtimes\win10-arm\lib\netstandard"/>
<file src="..\yoga_windows\bin\ARM\Release\Facebook.Yoga.pdb" target="runtimes\win10-arm\lib\netstandard"/>
<file src="..\yoga_windows\bin\x86\Release\Facebook.Yoga.dll" target="runtimes\win-x86\lib\netstandard"/>
<file src="..\yoga_windows\bin\x86\Release\Facebook.Yoga.pdb" target="runtimes\win-x86\lib\netstandard"/>
<file src="..\yoga_windows\bin\x64\Release\Facebook.Yoga.dll" target="runtimes\win-x64\lib\netstandard"/>
<file src="..\yoga_windows\bin\x64\Release\Facebook.Yoga.pdb" target="runtimes\win-x64\lib\netstandard"/>
<file src="..\yoga_windows\bin\ARM\Release\Facebook.Yoga.dll" target="runtimes\win8-arm\lib\netstandard"/>
<file src="..\yoga_windows\bin\ARM\Release\Facebook.Yoga.pdb" target="runtimes\win8-arm\lib\netstandard"/>
<!-- Native -->
<file src="..\Yoga\bin\x86\Release\Yoga.dll" target="runtimes\win-x86\native"/>
<file src="..\Yoga\bin\x86\Release\Yoga.pdb" target="runtimes\win-x86\native"/>
<file src="..\yoga_native\bin\Universal\x86\Release\Yoga.dll" target="runtimes\win10-x86\native"/>
<file src="..\yoga_native\bin\Universal\x86\Release\Yoga.pdb" target="runtimes\win10-x86\native"/>
<file src="..\Yoga\bin\x64\Release\Yoga.dll" target="runtimes\win-x64\native"/>
<file src="..\Yoga\bin\x64\Release\Yoga.pdb" target="runtimes\win-x64\native"/>
<file src="..\yoga_native\bin\Universal\x64\Release\Yoga.dll" target="runtimes\win10-x64\native"/>
<file src="..\yoga_native\bin\Universal\x64\Release\Yoga.pdb" target="runtimes\win10-x64\native"/>
<file src="..\Yoga\bin\ARM\Release\Yoga.dll" target="runtimes\win8-arm\native"/>
<file src="..\Yoga\bin\ARM\Release\Yoga.pdb" target="runtimes\win8-arm\native"/>
<file src="..\yoga_native\bin\Universal\ARM\Release\Yoga.dll" target="runtimes\win10-arm\native"/>
<file src="..\yoga_native\bin\Universal\ARM\Release\Yoga.pdb" target="runtimes\win10-arm\native"/>
<file src="..\yoga_mac\libyoga.dylib" target="runtimes\osx\native\" />
<file src="..\yoga_native\bin\x86\Release\Yoga.dll" target="runtimes\win-x86\native"/>
<file src="..\yoga_native\bin\x86\Release\Yoga.pdb" target="runtimes\win-x86\native"/>
<file src="..\yoga_native\bin\x64\Release\Yoga.dll" target="runtimes\win-x64\native"/>
<file src="..\yoga_native\bin\x64\Release\Yoga.pdb" target="runtimes\win-x64\native"/>
<file src="..\yoga_native\bin\ARM\Release\Yoga.dll" target="runtimes\win8-arm\native"/>
<file src="..\yoga_native\bin\ARM\Release\Yoga.pdb" target="runtimes\win8-arm\native"/>
</files>
</package>

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Condition=" (Exists('packages.config') Or Exists('packages.$(MSBuildProjectName).config')) And '$(Platform)' == 'AnyCPU'">
<ItemGroup Condition=" (Exists('packages.config') Or Exists('packages.$(MSBuildProjectName).config')) And '$(PlatformTarget)' == 'AnyCPU' and '$(OS)' != 'Unix'">
<Content Include="$(MSBuildThisFileDirectory)..\..\runtimes\win-x86\native\*">
<Link>x86\%(Filename)%(Extension)</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
@@ -12,7 +12,7 @@
<Visible>False</Visible>
</Content>
</ItemGroup>
<ItemGroup Condition=" (Exists('packages.config') Or Exists('packages.$(MSBuildProjectName).config')) And '$(Platform)' == 'x86'">
<ItemGroup Condition=" (Exists('packages.config') Or Exists('packages.$(MSBuildProjectName).config')) And '$(PlatformTarget)' == 'x86' and '$(OS)' != 'Unix'">
<Content Include="$(MSBuildThisFileDirectory)..\..\runtimes\win-x86\lib\netstandard\*">
<Link>%(Filename)%(Extension)</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
@@ -24,7 +24,7 @@
<Visible>False</Visible>
</Content>
</ItemGroup>
<ItemGroup Condition=" (Exists('packages.config') Or Exists('packages.$(MSBuildProjectName).config')) And '$(Platform)' == 'x64'">
<ItemGroup Condition=" (Exists('packages.config') Or Exists('packages.$(MSBuildProjectName).config')) And '$(PlatformTarget)' == 'x64' and '$(OS)' != 'Unix'">
<Content Include="$(MSBuildThisFileDirectory)..\..\runtimes\win-x64\lib\netstandard\*">
<Link>%(Filename)%(Extension)</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
@@ -36,7 +36,7 @@
<Visible>False</Visible>
</Content>
</ItemGroup>
<ItemGroup Condition=" (Exists('packages.config') Or Exists('packages.$(MSBuildProjectName).config')) And '$(Platform)' == 'ARM'">
<ItemGroup Condition=" (Exists('packages.config') Or Exists('packages.$(MSBuildProjectName).config')) And '$(PlatformTarget)' == 'ARM' and '$(OS)' != 'Unix' ">
<Content Include="$(MSBuildThisFileDirectory)..\..\runtimes\win8-arm\lib\netstandard\*">
<Link>%(Filename)%(Extension)</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
@@ -48,4 +48,14 @@
<Visible>False</Visible>
</Content>
</ItemGroup>
<ItemGroup Condition=" '$(OS)' == 'Unix' ">
<None Include="$(MSBuildThisFileDirectory)..\..\runtimes\osx\native\libyoga.dylib">
<Link>libyoga.dylib</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="$(MSBuildThisFileDirectory)Facebook.Yoga.dll.config">
<Link>Facebook.Yoga.dll.config</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>

File diff suppressed because it is too large Load Diff

View File

@@ -410,5 +410,944 @@ namespace Facebook.Yoga
Assert.AreEqual(50f, root_child1.LayoutHeight);
}
[Test]
public void Test_flex_wrap_wrap_to_child_height()
{
YogaNode root = new YogaNode();
YogaNode root_child0 = new YogaNode();
root_child0.FlexDirection = YogaFlexDirection.Row;
root_child0.AlignItems = YogaAlign.FlexStart;
root_child0.Wrap = YogaWrap.Wrap;
root.Insert(0, root_child0);
YogaNode root_child0_child0 = new YogaNode();
root_child0_child0.Width = 100;
root_child0.Insert(0, root_child0_child0);
YogaNode root_child0_child0_child0 = new YogaNode();
root_child0_child0_child0.Width = 100;
root_child0_child0_child0.Height = 100;
root_child0_child0.Insert(0, root_child0_child0_child0);
YogaNode root_child1 = new YogaNode();
root_child1.Width = 100;
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(200f, root.LayoutHeight);
Assert.AreEqual(0f, root_child0.LayoutX);
Assert.AreEqual(0f, root_child0.LayoutY);
Assert.AreEqual(100f, root_child0.LayoutWidth);
Assert.AreEqual(100f, 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(100f, root_child0_child0.LayoutHeight);
Assert.AreEqual(0f, root_child0_child0_child0.LayoutX);
Assert.AreEqual(0f, root_child0_child0_child0.LayoutY);
Assert.AreEqual(100f, root_child0_child0_child0.LayoutWidth);
Assert.AreEqual(100f, root_child0_child0_child0.LayoutHeight);
Assert.AreEqual(0f, root_child1.LayoutX);
Assert.AreEqual(100f, 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(200f, root.LayoutHeight);
Assert.AreEqual(0f, root_child0.LayoutX);
Assert.AreEqual(0f, root_child0.LayoutY);
Assert.AreEqual(100f, root_child0.LayoutWidth);
Assert.AreEqual(100f, 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(100f, root_child0_child0.LayoutHeight);
Assert.AreEqual(0f, root_child0_child0_child0.LayoutX);
Assert.AreEqual(0f, root_child0_child0_child0.LayoutY);
Assert.AreEqual(100f, root_child0_child0_child0.LayoutWidth);
Assert.AreEqual(100f, root_child0_child0_child0.LayoutHeight);
Assert.AreEqual(0f, root_child1.LayoutX);
Assert.AreEqual(100f, root_child1.LayoutY);
Assert.AreEqual(100f, root_child1.LayoutWidth);
Assert.AreEqual(100f, root_child1.LayoutHeight);
}
[Test]
public void Test_flex_wrap_align_stretch_fits_one_row()
{
YogaNode root = new YogaNode();
root.FlexDirection = YogaFlexDirection.Row;
root.Wrap = YogaWrap.Wrap;
root.Width = 150;
root.Height = 100;
YogaNode root_child0 = new YogaNode();
root_child0.Width = 50;
root.Insert(0, root_child0);
YogaNode root_child1 = new YogaNode();
root_child1.Width = 50;
root.Insert(1, root_child1);
root.StyleDirection = YogaDirection.LTR;
root.CalculateLayout();
Assert.AreEqual(0f, root.LayoutX);
Assert.AreEqual(0f, root.LayoutY);
Assert.AreEqual(150f, root.LayoutWidth);
Assert.AreEqual(100f, root.LayoutHeight);
Assert.AreEqual(0f, root_child0.LayoutX);
Assert.AreEqual(0f, root_child0.LayoutY);
Assert.AreEqual(50f, root_child0.LayoutWidth);
Assert.AreEqual(100f, root_child0.LayoutHeight);
Assert.AreEqual(50f, root_child1.LayoutX);
Assert.AreEqual(0f, root_child1.LayoutY);
Assert.AreEqual(50f, 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(150f, root.LayoutWidth);
Assert.AreEqual(100f, root.LayoutHeight);
Assert.AreEqual(100f, root_child0.LayoutX);
Assert.AreEqual(0f, root_child0.LayoutY);
Assert.AreEqual(50f, root_child0.LayoutWidth);
Assert.AreEqual(100f, root_child0.LayoutHeight);
Assert.AreEqual(50f, root_child1.LayoutX);
Assert.AreEqual(0f, root_child1.LayoutY);
Assert.AreEqual(50f, root_child1.LayoutWidth);
Assert.AreEqual(100f, root_child1.LayoutHeight);
}
[Test]
public void Test_wrap_reverse_row_align_content_flex_start()
{
YogaNode root = new YogaNode();
root.FlexDirection = YogaFlexDirection.Row;
root.Wrap = YogaWrap.WrapReverse;
root.Width = 100;
YogaNode root_child0 = new YogaNode();
root_child0.Width = 30;
root_child0.Height = 10;
root.Insert(0, root_child0);
YogaNode root_child1 = new YogaNode();
root_child1.Width = 30;
root_child1.Height = 20;
root.Insert(1, root_child1);
YogaNode root_child2 = new YogaNode();
root_child2.Width = 30;
root_child2.Height = 30;
root.Insert(2, root_child2);
YogaNode root_child3 = new YogaNode();
root_child3.Width = 30;
root_child3.Height = 40;
root.Insert(3, root_child3);
YogaNode root_child4 = new YogaNode();
root_child4.Width = 30;
root_child4.Height = 50;
root.Insert(4, root_child4);
root.StyleDirection = YogaDirection.LTR;
root.CalculateLayout();
Assert.AreEqual(0f, root.LayoutX);
Assert.AreEqual(0f, root.LayoutY);
Assert.AreEqual(100f, root.LayoutWidth);
Assert.AreEqual(80f, root.LayoutHeight);
Assert.AreEqual(0f, root_child0.LayoutX);
Assert.AreEqual(70f, root_child0.LayoutY);
Assert.AreEqual(30f, root_child0.LayoutWidth);
Assert.AreEqual(10f, root_child0.LayoutHeight);
Assert.AreEqual(30f, root_child1.LayoutX);
Assert.AreEqual(60f, root_child1.LayoutY);
Assert.AreEqual(30f, root_child1.LayoutWidth);
Assert.AreEqual(20f, root_child1.LayoutHeight);
Assert.AreEqual(60f, root_child2.LayoutX);
Assert.AreEqual(50f, root_child2.LayoutY);
Assert.AreEqual(30f, root_child2.LayoutWidth);
Assert.AreEqual(30f, root_child2.LayoutHeight);
Assert.AreEqual(0f, root_child3.LayoutX);
Assert.AreEqual(10f, root_child3.LayoutY);
Assert.AreEqual(30f, root_child3.LayoutWidth);
Assert.AreEqual(40f, root_child3.LayoutHeight);
Assert.AreEqual(30f, root_child4.LayoutX);
Assert.AreEqual(0f, root_child4.LayoutY);
Assert.AreEqual(30f, root_child4.LayoutWidth);
Assert.AreEqual(50f, root_child4.LayoutHeight);
root.StyleDirection = YogaDirection.RTL;
root.CalculateLayout();
Assert.AreEqual(0f, root.LayoutX);
Assert.AreEqual(0f, root.LayoutY);
Assert.AreEqual(100f, root.LayoutWidth);
Assert.AreEqual(80f, root.LayoutHeight);
Assert.AreEqual(70f, root_child0.LayoutX);
Assert.AreEqual(70f, root_child0.LayoutY);
Assert.AreEqual(30f, root_child0.LayoutWidth);
Assert.AreEqual(10f, root_child0.LayoutHeight);
Assert.AreEqual(40f, root_child1.LayoutX);
Assert.AreEqual(60f, root_child1.LayoutY);
Assert.AreEqual(30f, root_child1.LayoutWidth);
Assert.AreEqual(20f, root_child1.LayoutHeight);
Assert.AreEqual(10f, root_child2.LayoutX);
Assert.AreEqual(50f, root_child2.LayoutY);
Assert.AreEqual(30f, root_child2.LayoutWidth);
Assert.AreEqual(30f, root_child2.LayoutHeight);
Assert.AreEqual(70f, root_child3.LayoutX);
Assert.AreEqual(10f, root_child3.LayoutY);
Assert.AreEqual(30f, root_child3.LayoutWidth);
Assert.AreEqual(40f, root_child3.LayoutHeight);
Assert.AreEqual(40f, root_child4.LayoutX);
Assert.AreEqual(0f, root_child4.LayoutY);
Assert.AreEqual(30f, root_child4.LayoutWidth);
Assert.AreEqual(50f, root_child4.LayoutHeight);
}
[Test]
public void Test_wrap_reverse_row_align_content_center()
{
YogaNode root = new YogaNode();
root.FlexDirection = YogaFlexDirection.Row;
root.AlignContent = YogaAlign.Center;
root.Wrap = YogaWrap.WrapReverse;
root.Width = 100;
YogaNode root_child0 = new YogaNode();
root_child0.Width = 30;
root_child0.Height = 10;
root.Insert(0, root_child0);
YogaNode root_child1 = new YogaNode();
root_child1.Width = 30;
root_child1.Height = 20;
root.Insert(1, root_child1);
YogaNode root_child2 = new YogaNode();
root_child2.Width = 30;
root_child2.Height = 30;
root.Insert(2, root_child2);
YogaNode root_child3 = new YogaNode();
root_child3.Width = 30;
root_child3.Height = 40;
root.Insert(3, root_child3);
YogaNode root_child4 = new YogaNode();
root_child4.Width = 30;
root_child4.Height = 50;
root.Insert(4, root_child4);
root.StyleDirection = YogaDirection.LTR;
root.CalculateLayout();
Assert.AreEqual(0f, root.LayoutX);
Assert.AreEqual(0f, root.LayoutY);
Assert.AreEqual(100f, root.LayoutWidth);
Assert.AreEqual(80f, root.LayoutHeight);
Assert.AreEqual(0f, root_child0.LayoutX);
Assert.AreEqual(70f, root_child0.LayoutY);
Assert.AreEqual(30f, root_child0.LayoutWidth);
Assert.AreEqual(10f, root_child0.LayoutHeight);
Assert.AreEqual(30f, root_child1.LayoutX);
Assert.AreEqual(60f, root_child1.LayoutY);
Assert.AreEqual(30f, root_child1.LayoutWidth);
Assert.AreEqual(20f, root_child1.LayoutHeight);
Assert.AreEqual(60f, root_child2.LayoutX);
Assert.AreEqual(50f, root_child2.LayoutY);
Assert.AreEqual(30f, root_child2.LayoutWidth);
Assert.AreEqual(30f, root_child2.LayoutHeight);
Assert.AreEqual(0f, root_child3.LayoutX);
Assert.AreEqual(10f, root_child3.LayoutY);
Assert.AreEqual(30f, root_child3.LayoutWidth);
Assert.AreEqual(40f, root_child3.LayoutHeight);
Assert.AreEqual(30f, root_child4.LayoutX);
Assert.AreEqual(0f, root_child4.LayoutY);
Assert.AreEqual(30f, root_child4.LayoutWidth);
Assert.AreEqual(50f, root_child4.LayoutHeight);
root.StyleDirection = YogaDirection.RTL;
root.CalculateLayout();
Assert.AreEqual(0f, root.LayoutX);
Assert.AreEqual(0f, root.LayoutY);
Assert.AreEqual(100f, root.LayoutWidth);
Assert.AreEqual(80f, root.LayoutHeight);
Assert.AreEqual(70f, root_child0.LayoutX);
Assert.AreEqual(70f, root_child0.LayoutY);
Assert.AreEqual(30f, root_child0.LayoutWidth);
Assert.AreEqual(10f, root_child0.LayoutHeight);
Assert.AreEqual(40f, root_child1.LayoutX);
Assert.AreEqual(60f, root_child1.LayoutY);
Assert.AreEqual(30f, root_child1.LayoutWidth);
Assert.AreEqual(20f, root_child1.LayoutHeight);
Assert.AreEqual(10f, root_child2.LayoutX);
Assert.AreEqual(50f, root_child2.LayoutY);
Assert.AreEqual(30f, root_child2.LayoutWidth);
Assert.AreEqual(30f, root_child2.LayoutHeight);
Assert.AreEqual(70f, root_child3.LayoutX);
Assert.AreEqual(10f, root_child3.LayoutY);
Assert.AreEqual(30f, root_child3.LayoutWidth);
Assert.AreEqual(40f, root_child3.LayoutHeight);
Assert.AreEqual(40f, root_child4.LayoutX);
Assert.AreEqual(0f, root_child4.LayoutY);
Assert.AreEqual(30f, root_child4.LayoutWidth);
Assert.AreEqual(50f, root_child4.LayoutHeight);
}
[Test]
public void Test_wrap_reverse_row_single_line_different_size()
{
YogaNode root = new YogaNode();
root.FlexDirection = YogaFlexDirection.Row;
root.Wrap = YogaWrap.WrapReverse;
root.Width = 300;
YogaNode root_child0 = new YogaNode();
root_child0.Width = 30;
root_child0.Height = 10;
root.Insert(0, root_child0);
YogaNode root_child1 = new YogaNode();
root_child1.Width = 30;
root_child1.Height = 20;
root.Insert(1, root_child1);
YogaNode root_child2 = new YogaNode();
root_child2.Width = 30;
root_child2.Height = 30;
root.Insert(2, root_child2);
YogaNode root_child3 = new YogaNode();
root_child3.Width = 30;
root_child3.Height = 40;
root.Insert(3, root_child3);
YogaNode root_child4 = new YogaNode();
root_child4.Width = 30;
root_child4.Height = 50;
root.Insert(4, root_child4);
root.StyleDirection = YogaDirection.LTR;
root.CalculateLayout();
Assert.AreEqual(0f, root.LayoutX);
Assert.AreEqual(0f, root.LayoutY);
Assert.AreEqual(300f, root.LayoutWidth);
Assert.AreEqual(50f, root.LayoutHeight);
Assert.AreEqual(0f, root_child0.LayoutX);
Assert.AreEqual(40f, root_child0.LayoutY);
Assert.AreEqual(30f, root_child0.LayoutWidth);
Assert.AreEqual(10f, root_child0.LayoutHeight);
Assert.AreEqual(30f, root_child1.LayoutX);
Assert.AreEqual(30f, root_child1.LayoutY);
Assert.AreEqual(30f, root_child1.LayoutWidth);
Assert.AreEqual(20f, root_child1.LayoutHeight);
Assert.AreEqual(60f, root_child2.LayoutX);
Assert.AreEqual(20f, root_child2.LayoutY);
Assert.AreEqual(30f, root_child2.LayoutWidth);
Assert.AreEqual(30f, root_child2.LayoutHeight);
Assert.AreEqual(90f, root_child3.LayoutX);
Assert.AreEqual(10f, root_child3.LayoutY);
Assert.AreEqual(30f, root_child3.LayoutWidth);
Assert.AreEqual(40f, root_child3.LayoutHeight);
Assert.AreEqual(120f, root_child4.LayoutX);
Assert.AreEqual(0f, root_child4.LayoutY);
Assert.AreEqual(30f, root_child4.LayoutWidth);
Assert.AreEqual(50f, root_child4.LayoutHeight);
root.StyleDirection = YogaDirection.RTL;
root.CalculateLayout();
Assert.AreEqual(0f, root.LayoutX);
Assert.AreEqual(0f, root.LayoutY);
Assert.AreEqual(300f, root.LayoutWidth);
Assert.AreEqual(50f, root.LayoutHeight);
Assert.AreEqual(270f, root_child0.LayoutX);
Assert.AreEqual(40f, root_child0.LayoutY);
Assert.AreEqual(30f, root_child0.LayoutWidth);
Assert.AreEqual(10f, root_child0.LayoutHeight);
Assert.AreEqual(240f, root_child1.LayoutX);
Assert.AreEqual(30f, root_child1.LayoutY);
Assert.AreEqual(30f, root_child1.LayoutWidth);
Assert.AreEqual(20f, root_child1.LayoutHeight);
Assert.AreEqual(210f, root_child2.LayoutX);
Assert.AreEqual(20f, root_child2.LayoutY);
Assert.AreEqual(30f, root_child2.LayoutWidth);
Assert.AreEqual(30f, root_child2.LayoutHeight);
Assert.AreEqual(180f, root_child3.LayoutX);
Assert.AreEqual(10f, root_child3.LayoutY);
Assert.AreEqual(30f, root_child3.LayoutWidth);
Assert.AreEqual(40f, root_child3.LayoutHeight);
Assert.AreEqual(150f, root_child4.LayoutX);
Assert.AreEqual(0f, root_child4.LayoutY);
Assert.AreEqual(30f, root_child4.LayoutWidth);
Assert.AreEqual(50f, root_child4.LayoutHeight);
}
[Test]
public void Test_wrap_reverse_row_align_content_stretch()
{
YogaNode root = new YogaNode();
root.FlexDirection = YogaFlexDirection.Row;
root.AlignContent = YogaAlign.Stretch;
root.Wrap = YogaWrap.WrapReverse;
root.Width = 100;
YogaNode root_child0 = new YogaNode();
root_child0.Width = 30;
root_child0.Height = 10;
root.Insert(0, root_child0);
YogaNode root_child1 = new YogaNode();
root_child1.Width = 30;
root_child1.Height = 20;
root.Insert(1, root_child1);
YogaNode root_child2 = new YogaNode();
root_child2.Width = 30;
root_child2.Height = 30;
root.Insert(2, root_child2);
YogaNode root_child3 = new YogaNode();
root_child3.Width = 30;
root_child3.Height = 40;
root.Insert(3, root_child3);
YogaNode root_child4 = new YogaNode();
root_child4.Width = 30;
root_child4.Height = 50;
root.Insert(4, root_child4);
root.StyleDirection = YogaDirection.LTR;
root.CalculateLayout();
Assert.AreEqual(0f, root.LayoutX);
Assert.AreEqual(0f, root.LayoutY);
Assert.AreEqual(100f, root.LayoutWidth);
Assert.AreEqual(80f, root.LayoutHeight);
Assert.AreEqual(0f, root_child0.LayoutX);
Assert.AreEqual(70f, root_child0.LayoutY);
Assert.AreEqual(30f, root_child0.LayoutWidth);
Assert.AreEqual(10f, root_child0.LayoutHeight);
Assert.AreEqual(30f, root_child1.LayoutX);
Assert.AreEqual(60f, root_child1.LayoutY);
Assert.AreEqual(30f, root_child1.LayoutWidth);
Assert.AreEqual(20f, root_child1.LayoutHeight);
Assert.AreEqual(60f, root_child2.LayoutX);
Assert.AreEqual(50f, root_child2.LayoutY);
Assert.AreEqual(30f, root_child2.LayoutWidth);
Assert.AreEqual(30f, root_child2.LayoutHeight);
Assert.AreEqual(0f, root_child3.LayoutX);
Assert.AreEqual(10f, root_child3.LayoutY);
Assert.AreEqual(30f, root_child3.LayoutWidth);
Assert.AreEqual(40f, root_child3.LayoutHeight);
Assert.AreEqual(30f, root_child4.LayoutX);
Assert.AreEqual(0f, root_child4.LayoutY);
Assert.AreEqual(30f, root_child4.LayoutWidth);
Assert.AreEqual(50f, root_child4.LayoutHeight);
root.StyleDirection = YogaDirection.RTL;
root.CalculateLayout();
Assert.AreEqual(0f, root.LayoutX);
Assert.AreEqual(0f, root.LayoutY);
Assert.AreEqual(100f, root.LayoutWidth);
Assert.AreEqual(80f, root.LayoutHeight);
Assert.AreEqual(70f, root_child0.LayoutX);
Assert.AreEqual(70f, root_child0.LayoutY);
Assert.AreEqual(30f, root_child0.LayoutWidth);
Assert.AreEqual(10f, root_child0.LayoutHeight);
Assert.AreEqual(40f, root_child1.LayoutX);
Assert.AreEqual(60f, root_child1.LayoutY);
Assert.AreEqual(30f, root_child1.LayoutWidth);
Assert.AreEqual(20f, root_child1.LayoutHeight);
Assert.AreEqual(10f, root_child2.LayoutX);
Assert.AreEqual(50f, root_child2.LayoutY);
Assert.AreEqual(30f, root_child2.LayoutWidth);
Assert.AreEqual(30f, root_child2.LayoutHeight);
Assert.AreEqual(70f, root_child3.LayoutX);
Assert.AreEqual(10f, root_child3.LayoutY);
Assert.AreEqual(30f, root_child3.LayoutWidth);
Assert.AreEqual(40f, root_child3.LayoutHeight);
Assert.AreEqual(40f, root_child4.LayoutX);
Assert.AreEqual(0f, root_child4.LayoutY);
Assert.AreEqual(30f, root_child4.LayoutWidth);
Assert.AreEqual(50f, root_child4.LayoutHeight);
}
[Test]
public void Test_wrap_reverse_row_align_content_space_around()
{
YogaNode root = new YogaNode();
root.FlexDirection = YogaFlexDirection.Row;
root.AlignContent = YogaAlign.SpaceAround;
root.Wrap = YogaWrap.WrapReverse;
root.Width = 100;
YogaNode root_child0 = new YogaNode();
root_child0.Width = 30;
root_child0.Height = 10;
root.Insert(0, root_child0);
YogaNode root_child1 = new YogaNode();
root_child1.Width = 30;
root_child1.Height = 20;
root.Insert(1, root_child1);
YogaNode root_child2 = new YogaNode();
root_child2.Width = 30;
root_child2.Height = 30;
root.Insert(2, root_child2);
YogaNode root_child3 = new YogaNode();
root_child3.Width = 30;
root_child3.Height = 40;
root.Insert(3, root_child3);
YogaNode root_child4 = new YogaNode();
root_child4.Width = 30;
root_child4.Height = 50;
root.Insert(4, root_child4);
root.StyleDirection = YogaDirection.LTR;
root.CalculateLayout();
Assert.AreEqual(0f, root.LayoutX);
Assert.AreEqual(0f, root.LayoutY);
Assert.AreEqual(100f, root.LayoutWidth);
Assert.AreEqual(80f, root.LayoutHeight);
Assert.AreEqual(0f, root_child0.LayoutX);
Assert.AreEqual(70f, root_child0.LayoutY);
Assert.AreEqual(30f, root_child0.LayoutWidth);
Assert.AreEqual(10f, root_child0.LayoutHeight);
Assert.AreEqual(30f, root_child1.LayoutX);
Assert.AreEqual(60f, root_child1.LayoutY);
Assert.AreEqual(30f, root_child1.LayoutWidth);
Assert.AreEqual(20f, root_child1.LayoutHeight);
Assert.AreEqual(60f, root_child2.LayoutX);
Assert.AreEqual(50f, root_child2.LayoutY);
Assert.AreEqual(30f, root_child2.LayoutWidth);
Assert.AreEqual(30f, root_child2.LayoutHeight);
Assert.AreEqual(0f, root_child3.LayoutX);
Assert.AreEqual(10f, root_child3.LayoutY);
Assert.AreEqual(30f, root_child3.LayoutWidth);
Assert.AreEqual(40f, root_child3.LayoutHeight);
Assert.AreEqual(30f, root_child4.LayoutX);
Assert.AreEqual(0f, root_child4.LayoutY);
Assert.AreEqual(30f, root_child4.LayoutWidth);
Assert.AreEqual(50f, root_child4.LayoutHeight);
root.StyleDirection = YogaDirection.RTL;
root.CalculateLayout();
Assert.AreEqual(0f, root.LayoutX);
Assert.AreEqual(0f, root.LayoutY);
Assert.AreEqual(100f, root.LayoutWidth);
Assert.AreEqual(80f, root.LayoutHeight);
Assert.AreEqual(70f, root_child0.LayoutX);
Assert.AreEqual(70f, root_child0.LayoutY);
Assert.AreEqual(30f, root_child0.LayoutWidth);
Assert.AreEqual(10f, root_child0.LayoutHeight);
Assert.AreEqual(40f, root_child1.LayoutX);
Assert.AreEqual(60f, root_child1.LayoutY);
Assert.AreEqual(30f, root_child1.LayoutWidth);
Assert.AreEqual(20f, root_child1.LayoutHeight);
Assert.AreEqual(10f, root_child2.LayoutX);
Assert.AreEqual(50f, root_child2.LayoutY);
Assert.AreEqual(30f, root_child2.LayoutWidth);
Assert.AreEqual(30f, root_child2.LayoutHeight);
Assert.AreEqual(70f, root_child3.LayoutX);
Assert.AreEqual(10f, root_child3.LayoutY);
Assert.AreEqual(30f, root_child3.LayoutWidth);
Assert.AreEqual(40f, root_child3.LayoutHeight);
Assert.AreEqual(40f, root_child4.LayoutX);
Assert.AreEqual(0f, root_child4.LayoutY);
Assert.AreEqual(30f, root_child4.LayoutWidth);
Assert.AreEqual(50f, root_child4.LayoutHeight);
}
[Test]
public void Test_wrap_reverse_column_fixed_size()
{
YogaNode root = new YogaNode();
root.AlignItems = YogaAlign.Center;
root.Wrap = YogaWrap.WrapReverse;
root.Width = 200;
root.Height = 100;
YogaNode root_child0 = new YogaNode();
root_child0.Width = 30;
root_child0.Height = 10;
root.Insert(0, root_child0);
YogaNode root_child1 = new YogaNode();
root_child1.Width = 30;
root_child1.Height = 20;
root.Insert(1, root_child1);
YogaNode root_child2 = new YogaNode();
root_child2.Width = 30;
root_child2.Height = 30;
root.Insert(2, root_child2);
YogaNode root_child3 = new YogaNode();
root_child3.Width = 30;
root_child3.Height = 40;
root.Insert(3, root_child3);
YogaNode root_child4 = new YogaNode();
root_child4.Width = 30;
root_child4.Height = 50;
root.Insert(4, root_child4);
root.StyleDirection = YogaDirection.LTR;
root.CalculateLayout();
Assert.AreEqual(0f, root.LayoutX);
Assert.AreEqual(0f, root.LayoutY);
Assert.AreEqual(200f, root.LayoutWidth);
Assert.AreEqual(100f, root.LayoutHeight);
Assert.AreEqual(170f, root_child0.LayoutX);
Assert.AreEqual(0f, root_child0.LayoutY);
Assert.AreEqual(30f, root_child0.LayoutWidth);
Assert.AreEqual(10f, root_child0.LayoutHeight);
Assert.AreEqual(170f, root_child1.LayoutX);
Assert.AreEqual(10f, root_child1.LayoutY);
Assert.AreEqual(30f, root_child1.LayoutWidth);
Assert.AreEqual(20f, root_child1.LayoutHeight);
Assert.AreEqual(170f, root_child2.LayoutX);
Assert.AreEqual(30f, root_child2.LayoutY);
Assert.AreEqual(30f, root_child2.LayoutWidth);
Assert.AreEqual(30f, root_child2.LayoutHeight);
Assert.AreEqual(170f, root_child3.LayoutX);
Assert.AreEqual(60f, root_child3.LayoutY);
Assert.AreEqual(30f, root_child3.LayoutWidth);
Assert.AreEqual(40f, root_child3.LayoutHeight);
Assert.AreEqual(140f, root_child4.LayoutX);
Assert.AreEqual(0f, root_child4.LayoutY);
Assert.AreEqual(30f, root_child4.LayoutWidth);
Assert.AreEqual(50f, root_child4.LayoutHeight);
root.StyleDirection = YogaDirection.RTL;
root.CalculateLayout();
Assert.AreEqual(0f, root.LayoutX);
Assert.AreEqual(0f, root.LayoutY);
Assert.AreEqual(200f, root.LayoutWidth);
Assert.AreEqual(100f, root.LayoutHeight);
Assert.AreEqual(0f, root_child0.LayoutX);
Assert.AreEqual(0f, root_child0.LayoutY);
Assert.AreEqual(30f, root_child0.LayoutWidth);
Assert.AreEqual(10f, root_child0.LayoutHeight);
Assert.AreEqual(0f, root_child1.LayoutX);
Assert.AreEqual(10f, root_child1.LayoutY);
Assert.AreEqual(30f, root_child1.LayoutWidth);
Assert.AreEqual(20f, root_child1.LayoutHeight);
Assert.AreEqual(0f, root_child2.LayoutX);
Assert.AreEqual(30f, root_child2.LayoutY);
Assert.AreEqual(30f, root_child2.LayoutWidth);
Assert.AreEqual(30f, root_child2.LayoutHeight);
Assert.AreEqual(0f, root_child3.LayoutX);
Assert.AreEqual(60f, root_child3.LayoutY);
Assert.AreEqual(30f, root_child3.LayoutWidth);
Assert.AreEqual(40f, root_child3.LayoutHeight);
Assert.AreEqual(30f, root_child4.LayoutX);
Assert.AreEqual(0f, root_child4.LayoutY);
Assert.AreEqual(30f, root_child4.LayoutWidth);
Assert.AreEqual(50f, root_child4.LayoutHeight);
}
[Test]
public void Test_wrapped_row_within_align_items_center()
{
YogaNode root = new YogaNode();
root.AlignItems = YogaAlign.Center;
root.Width = 200;
root.Height = 200;
YogaNode root_child0 = new YogaNode();
root_child0.FlexDirection = YogaFlexDirection.Row;
root_child0.Wrap = YogaWrap.Wrap;
root.Insert(0, root_child0);
YogaNode root_child0_child0 = new YogaNode();
root_child0_child0.Width = 150;
root_child0_child0.Height = 80;
root_child0.Insert(0, root_child0_child0);
YogaNode root_child0_child1 = new YogaNode();
root_child0_child1.Width = 80;
root_child0_child1.Height = 80;
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(200f, root.LayoutWidth);
Assert.AreEqual(200f, root.LayoutHeight);
Assert.AreEqual(0f, root_child0.LayoutX);
Assert.AreEqual(0f, root_child0.LayoutY);
Assert.AreEqual(200f, root_child0.LayoutWidth);
Assert.AreEqual(160f, root_child0.LayoutHeight);
Assert.AreEqual(0f, root_child0_child0.LayoutX);
Assert.AreEqual(0f, root_child0_child0.LayoutY);
Assert.AreEqual(150f, root_child0_child0.LayoutWidth);
Assert.AreEqual(80f, root_child0_child0.LayoutHeight);
Assert.AreEqual(0f, root_child0_child1.LayoutX);
Assert.AreEqual(80f, root_child0_child1.LayoutY);
Assert.AreEqual(80f, root_child0_child1.LayoutWidth);
Assert.AreEqual(80f, root_child0_child1.LayoutHeight);
root.StyleDirection = YogaDirection.RTL;
root.CalculateLayout();
Assert.AreEqual(0f, root.LayoutX);
Assert.AreEqual(0f, root.LayoutY);
Assert.AreEqual(200f, root.LayoutWidth);
Assert.AreEqual(200f, root.LayoutHeight);
Assert.AreEqual(0f, root_child0.LayoutX);
Assert.AreEqual(0f, root_child0.LayoutY);
Assert.AreEqual(200f, root_child0.LayoutWidth);
Assert.AreEqual(160f, root_child0.LayoutHeight);
Assert.AreEqual(50f, root_child0_child0.LayoutX);
Assert.AreEqual(0f, root_child0_child0.LayoutY);
Assert.AreEqual(150f, root_child0_child0.LayoutWidth);
Assert.AreEqual(80f, root_child0_child0.LayoutHeight);
Assert.AreEqual(120f, root_child0_child1.LayoutX);
Assert.AreEqual(80f, root_child0_child1.LayoutY);
Assert.AreEqual(80f, root_child0_child1.LayoutWidth);
Assert.AreEqual(80f, root_child0_child1.LayoutHeight);
}
[Test]
public void Test_wrapped_row_within_align_items_center2()
{
YogaNode root = new YogaNode();
root.AlignItems = YogaAlign.FlexStart;
root.Width = 200;
root.Height = 200;
YogaNode root_child0 = new YogaNode();
root_child0.FlexDirection = YogaFlexDirection.Row;
root_child0.Wrap = YogaWrap.Wrap;
root.Insert(0, root_child0);
YogaNode root_child0_child0 = new YogaNode();
root_child0_child0.Width = 150;
root_child0_child0.Height = 80;
root_child0.Insert(0, root_child0_child0);
YogaNode root_child0_child1 = new YogaNode();
root_child0_child1.Width = 80;
root_child0_child1.Height = 80;
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(200f, root.LayoutWidth);
Assert.AreEqual(200f, root.LayoutHeight);
Assert.AreEqual(0f, root_child0.LayoutX);
Assert.AreEqual(0f, root_child0.LayoutY);
Assert.AreEqual(200f, root_child0.LayoutWidth);
Assert.AreEqual(160f, root_child0.LayoutHeight);
Assert.AreEqual(0f, root_child0_child0.LayoutX);
Assert.AreEqual(0f, root_child0_child0.LayoutY);
Assert.AreEqual(150f, root_child0_child0.LayoutWidth);
Assert.AreEqual(80f, root_child0_child0.LayoutHeight);
Assert.AreEqual(0f, root_child0_child1.LayoutX);
Assert.AreEqual(80f, root_child0_child1.LayoutY);
Assert.AreEqual(80f, root_child0_child1.LayoutWidth);
Assert.AreEqual(80f, root_child0_child1.LayoutHeight);
root.StyleDirection = YogaDirection.RTL;
root.CalculateLayout();
Assert.AreEqual(0f, root.LayoutX);
Assert.AreEqual(0f, root.LayoutY);
Assert.AreEqual(200f, root.LayoutWidth);
Assert.AreEqual(200f, root.LayoutHeight);
Assert.AreEqual(0f, root_child0.LayoutX);
Assert.AreEqual(0f, root_child0.LayoutY);
Assert.AreEqual(200f, root_child0.LayoutWidth);
Assert.AreEqual(160f, root_child0.LayoutHeight);
Assert.AreEqual(50f, root_child0_child0.LayoutX);
Assert.AreEqual(0f, root_child0_child0.LayoutY);
Assert.AreEqual(150f, root_child0_child0.LayoutWidth);
Assert.AreEqual(80f, root_child0_child0.LayoutHeight);
Assert.AreEqual(120f, root_child0_child1.LayoutX);
Assert.AreEqual(80f, root_child0_child1.LayoutY);
Assert.AreEqual(80f, root_child0_child1.LayoutWidth);
Assert.AreEqual(80f, root_child0_child1.LayoutHeight);
}
[Test]
public void Test_wrapped_row_within_align_items_center3()
{
YogaNode root = new YogaNode();
root.AlignItems = YogaAlign.FlexEnd;
root.Width = 200;
root.Height = 200;
YogaNode root_child0 = new YogaNode();
root_child0.FlexDirection = YogaFlexDirection.Row;
root_child0.Wrap = YogaWrap.Wrap;
root.Insert(0, root_child0);
YogaNode root_child0_child0 = new YogaNode();
root_child0_child0.Width = 150;
root_child0_child0.Height = 80;
root_child0.Insert(0, root_child0_child0);
YogaNode root_child0_child1 = new YogaNode();
root_child0_child1.Width = 80;
root_child0_child1.Height = 80;
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(200f, root.LayoutWidth);
Assert.AreEqual(200f, root.LayoutHeight);
Assert.AreEqual(0f, root_child0.LayoutX);
Assert.AreEqual(0f, root_child0.LayoutY);
Assert.AreEqual(200f, root_child0.LayoutWidth);
Assert.AreEqual(160f, root_child0.LayoutHeight);
Assert.AreEqual(0f, root_child0_child0.LayoutX);
Assert.AreEqual(0f, root_child0_child0.LayoutY);
Assert.AreEqual(150f, root_child0_child0.LayoutWidth);
Assert.AreEqual(80f, root_child0_child0.LayoutHeight);
Assert.AreEqual(0f, root_child0_child1.LayoutX);
Assert.AreEqual(80f, root_child0_child1.LayoutY);
Assert.AreEqual(80f, root_child0_child1.LayoutWidth);
Assert.AreEqual(80f, root_child0_child1.LayoutHeight);
root.StyleDirection = YogaDirection.RTL;
root.CalculateLayout();
Assert.AreEqual(0f, root.LayoutX);
Assert.AreEqual(0f, root.LayoutY);
Assert.AreEqual(200f, root.LayoutWidth);
Assert.AreEqual(200f, root.LayoutHeight);
Assert.AreEqual(0f, root_child0.LayoutX);
Assert.AreEqual(0f, root_child0.LayoutY);
Assert.AreEqual(200f, root_child0.LayoutWidth);
Assert.AreEqual(160f, root_child0.LayoutHeight);
Assert.AreEqual(50f, root_child0_child0.LayoutX);
Assert.AreEqual(0f, root_child0_child0.LayoutY);
Assert.AreEqual(150f, root_child0_child0.LayoutWidth);
Assert.AreEqual(80f, root_child0_child0.LayoutHeight);
Assert.AreEqual(120f, root_child0_child1.LayoutX);
Assert.AreEqual(80f, root_child0_child1.LayoutY);
Assert.AreEqual(80f, root_child0_child1.LayoutWidth);
Assert.AreEqual(80f, root_child0_child1.LayoutHeight);
}
}
}

View File

@@ -436,5 +436,759 @@ namespace Facebook.Yoga
Assert.AreEqual(45f, root_child1.LayoutHeight);
}
[Test]
public void Test_margin_auto_bottom()
{
YogaNode root = new YogaNode();
root.AlignItems = YogaAlign.Center;
root.Width = 200;
root.Height = 200;
YogaNode root_child0 = new YogaNode();
root_child0.MarginBottom = YogaValue.Auto();
root_child0.Width = 50;
root_child0.Height = 50;
root.Insert(0, root_child0);
YogaNode root_child1 = new YogaNode();
root_child1.Width = 50;
root_child1.Height = 50;
root.Insert(1, root_child1);
root.StyleDirection = YogaDirection.LTR;
root.CalculateLayout();
Assert.AreEqual(0f, root.LayoutX);
Assert.AreEqual(0f, root.LayoutY);
Assert.AreEqual(200f, root.LayoutWidth);
Assert.AreEqual(200f, root.LayoutHeight);
Assert.AreEqual(75f, root_child0.LayoutX);
Assert.AreEqual(0f, root_child0.LayoutY);
Assert.AreEqual(50f, root_child0.LayoutWidth);
Assert.AreEqual(50f, root_child0.LayoutHeight);
Assert.AreEqual(75f, root_child1.LayoutX);
Assert.AreEqual(150f, root_child1.LayoutY);
Assert.AreEqual(50f, 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(200f, root.LayoutWidth);
Assert.AreEqual(200f, root.LayoutHeight);
Assert.AreEqual(75f, root_child0.LayoutX);
Assert.AreEqual(0f, root_child0.LayoutY);
Assert.AreEqual(50f, root_child0.LayoutWidth);
Assert.AreEqual(50f, root_child0.LayoutHeight);
Assert.AreEqual(75f, root_child1.LayoutX);
Assert.AreEqual(150f, root_child1.LayoutY);
Assert.AreEqual(50f, root_child1.LayoutWidth);
Assert.AreEqual(50f, root_child1.LayoutHeight);
}
[Test]
public void Test_margin_auto_top()
{
YogaNode root = new YogaNode();
root.AlignItems = YogaAlign.Center;
root.Width = 200;
root.Height = 200;
YogaNode root_child0 = new YogaNode();
root_child0.MarginTop = YogaValue.Auto();
root_child0.Width = 50;
root_child0.Height = 50;
root.Insert(0, root_child0);
YogaNode root_child1 = new YogaNode();
root_child1.Width = 50;
root_child1.Height = 50;
root.Insert(1, root_child1);
root.StyleDirection = YogaDirection.LTR;
root.CalculateLayout();
Assert.AreEqual(0f, root.LayoutX);
Assert.AreEqual(0f, root.LayoutY);
Assert.AreEqual(200f, root.LayoutWidth);
Assert.AreEqual(200f, root.LayoutHeight);
Assert.AreEqual(75f, root_child0.LayoutX);
Assert.AreEqual(100f, root_child0.LayoutY);
Assert.AreEqual(50f, root_child0.LayoutWidth);
Assert.AreEqual(50f, root_child0.LayoutHeight);
Assert.AreEqual(75f, root_child1.LayoutX);
Assert.AreEqual(150f, root_child1.LayoutY);
Assert.AreEqual(50f, 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(200f, root.LayoutWidth);
Assert.AreEqual(200f, root.LayoutHeight);
Assert.AreEqual(75f, root_child0.LayoutX);
Assert.AreEqual(100f, root_child0.LayoutY);
Assert.AreEqual(50f, root_child0.LayoutWidth);
Assert.AreEqual(50f, root_child0.LayoutHeight);
Assert.AreEqual(75f, root_child1.LayoutX);
Assert.AreEqual(150f, root_child1.LayoutY);
Assert.AreEqual(50f, root_child1.LayoutWidth);
Assert.AreEqual(50f, root_child1.LayoutHeight);
}
[Test]
public void Test_margin_auto_bottom_and_top()
{
YogaNode root = new YogaNode();
root.AlignItems = YogaAlign.Center;
root.Width = 200;
root.Height = 200;
YogaNode root_child0 = new YogaNode();
root_child0.MarginTop = YogaValue.Auto();
root_child0.MarginBottom = YogaValue.Auto();
root_child0.Width = 50;
root_child0.Height = 50;
root.Insert(0, root_child0);
YogaNode root_child1 = new YogaNode();
root_child1.Width = 50;
root_child1.Height = 50;
root.Insert(1, root_child1);
root.StyleDirection = YogaDirection.LTR;
root.CalculateLayout();
Assert.AreEqual(0f, root.LayoutX);
Assert.AreEqual(0f, root.LayoutY);
Assert.AreEqual(200f, root.LayoutWidth);
Assert.AreEqual(200f, root.LayoutHeight);
Assert.AreEqual(75f, root_child0.LayoutX);
Assert.AreEqual(50f, root_child0.LayoutY);
Assert.AreEqual(50f, root_child0.LayoutWidth);
Assert.AreEqual(50f, root_child0.LayoutHeight);
Assert.AreEqual(75f, root_child1.LayoutX);
Assert.AreEqual(150f, root_child1.LayoutY);
Assert.AreEqual(50f, 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(200f, root.LayoutWidth);
Assert.AreEqual(200f, root.LayoutHeight);
Assert.AreEqual(75f, root_child0.LayoutX);
Assert.AreEqual(50f, root_child0.LayoutY);
Assert.AreEqual(50f, root_child0.LayoutWidth);
Assert.AreEqual(50f, root_child0.LayoutHeight);
Assert.AreEqual(75f, root_child1.LayoutX);
Assert.AreEqual(150f, root_child1.LayoutY);
Assert.AreEqual(50f, root_child1.LayoutWidth);
Assert.AreEqual(50f, root_child1.LayoutHeight);
}
[Test]
public void Test_margin_auto_bottom_and_top_justify_center()
{
YogaNode root = new YogaNode();
root.JustifyContent = YogaJustify.Center;
root.Width = 200;
root.Height = 200;
YogaNode root_child0 = new YogaNode();
root_child0.MarginTop = YogaValue.Auto();
root_child0.MarginBottom = YogaValue.Auto();
root_child0.Width = 50;
root_child0.Height = 50;
root.Insert(0, root_child0);
YogaNode root_child1 = new YogaNode();
root_child1.Width = 50;
root_child1.Height = 50;
root.Insert(1, root_child1);
root.StyleDirection = YogaDirection.LTR;
root.CalculateLayout();
Assert.AreEqual(0f, root.LayoutX);
Assert.AreEqual(0f, root.LayoutY);
Assert.AreEqual(200f, root.LayoutWidth);
Assert.AreEqual(200f, root.LayoutHeight);
Assert.AreEqual(0f, root_child0.LayoutX);
Assert.AreEqual(50f, root_child0.LayoutY);
Assert.AreEqual(50f, root_child0.LayoutWidth);
Assert.AreEqual(50f, root_child0.LayoutHeight);
Assert.AreEqual(0f, root_child1.LayoutX);
Assert.AreEqual(150f, root_child1.LayoutY);
Assert.AreEqual(50f, 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(200f, root.LayoutWidth);
Assert.AreEqual(200f, root.LayoutHeight);
Assert.AreEqual(150f, root_child0.LayoutX);
Assert.AreEqual(50f, root_child0.LayoutY);
Assert.AreEqual(50f, root_child0.LayoutWidth);
Assert.AreEqual(50f, root_child0.LayoutHeight);
Assert.AreEqual(150f, root_child1.LayoutX);
Assert.AreEqual(150f, root_child1.LayoutY);
Assert.AreEqual(50f, root_child1.LayoutWidth);
Assert.AreEqual(50f, root_child1.LayoutHeight);
}
[Test]
public void Test_margin_auto_mutiple_children_column()
{
YogaNode root = new YogaNode();
root.AlignItems = YogaAlign.Center;
root.Width = 200;
root.Height = 200;
YogaNode root_child0 = new YogaNode();
root_child0.MarginTop = YogaValue.Auto();
root_child0.Width = 50;
root_child0.Height = 50;
root.Insert(0, root_child0);
YogaNode root_child1 = new YogaNode();
root_child1.MarginTop = YogaValue.Auto();
root_child1.Width = 50;
root_child1.Height = 50;
root.Insert(1, root_child1);
YogaNode root_child2 = new YogaNode();
root_child2.Width = 50;
root_child2.Height = 50;
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(200f, root.LayoutHeight);
Assert.AreEqual(75f, root_child0.LayoutX);
Assert.AreEqual(25f, root_child0.LayoutY);
Assert.AreEqual(50f, root_child0.LayoutWidth);
Assert.AreEqual(50f, root_child0.LayoutHeight);
Assert.AreEqual(75f, root_child1.LayoutX);
Assert.AreEqual(100f, root_child1.LayoutY);
Assert.AreEqual(50f, root_child1.LayoutWidth);
Assert.AreEqual(50f, root_child1.LayoutHeight);
Assert.AreEqual(75f, root_child2.LayoutX);
Assert.AreEqual(150f, root_child2.LayoutY);
Assert.AreEqual(50f, root_child2.LayoutWidth);
Assert.AreEqual(50f, 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(200f, root.LayoutHeight);
Assert.AreEqual(75f, root_child0.LayoutX);
Assert.AreEqual(25f, root_child0.LayoutY);
Assert.AreEqual(50f, root_child0.LayoutWidth);
Assert.AreEqual(50f, root_child0.LayoutHeight);
Assert.AreEqual(75f, root_child1.LayoutX);
Assert.AreEqual(100f, root_child1.LayoutY);
Assert.AreEqual(50f, root_child1.LayoutWidth);
Assert.AreEqual(50f, root_child1.LayoutHeight);
Assert.AreEqual(75f, root_child2.LayoutX);
Assert.AreEqual(150f, root_child2.LayoutY);
Assert.AreEqual(50f, root_child2.LayoutWidth);
Assert.AreEqual(50f, root_child2.LayoutHeight);
}
[Test]
public void Test_margin_auto_mutiple_children_row()
{
YogaNode root = new YogaNode();
root.FlexDirection = YogaFlexDirection.Row;
root.AlignItems = YogaAlign.Center;
root.Width = 200;
root.Height = 200;
YogaNode root_child0 = new YogaNode();
root_child0.MarginRight = YogaValue.Auto();
root_child0.Width = 50;
root_child0.Height = 50;
root.Insert(0, root_child0);
YogaNode root_child1 = new YogaNode();
root_child1.MarginRight = YogaValue.Auto();
root_child1.Width = 50;
root_child1.Height = 50;
root.Insert(1, root_child1);
YogaNode root_child2 = new YogaNode();
root_child2.Width = 50;
root_child2.Height = 50;
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(200f, root.LayoutHeight);
Assert.AreEqual(0f, root_child0.LayoutX);
Assert.AreEqual(75f, root_child0.LayoutY);
Assert.AreEqual(50f, root_child0.LayoutWidth);
Assert.AreEqual(50f, root_child0.LayoutHeight);
Assert.AreEqual(75f, root_child1.LayoutX);
Assert.AreEqual(75f, root_child1.LayoutY);
Assert.AreEqual(50f, root_child1.LayoutWidth);
Assert.AreEqual(50f, root_child1.LayoutHeight);
Assert.AreEqual(150f, root_child2.LayoutX);
Assert.AreEqual(75f, root_child2.LayoutY);
Assert.AreEqual(50f, root_child2.LayoutWidth);
Assert.AreEqual(50f, 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(200f, root.LayoutHeight);
Assert.AreEqual(125f, root_child0.LayoutX);
Assert.AreEqual(75f, root_child0.LayoutY);
Assert.AreEqual(50f, root_child0.LayoutWidth);
Assert.AreEqual(50f, root_child0.LayoutHeight);
Assert.AreEqual(50f, root_child1.LayoutX);
Assert.AreEqual(75f, root_child1.LayoutY);
Assert.AreEqual(50f, root_child1.LayoutWidth);
Assert.AreEqual(50f, root_child1.LayoutHeight);
Assert.AreEqual(0f, root_child2.LayoutX);
Assert.AreEqual(75f, root_child2.LayoutY);
Assert.AreEqual(50f, root_child2.LayoutWidth);
Assert.AreEqual(50f, root_child2.LayoutHeight);
}
[Test]
public void Test_margin_auto_left_and_right_column()
{
YogaNode root = new YogaNode();
root.FlexDirection = YogaFlexDirection.Row;
root.AlignItems = YogaAlign.Center;
root.Width = 200;
root.Height = 200;
YogaNode root_child0 = new YogaNode();
root_child0.MarginLeft = YogaValue.Auto();
root_child0.MarginRight = YogaValue.Auto();
root_child0.Width = 50;
root_child0.Height = 50;
root.Insert(0, root_child0);
YogaNode root_child1 = new YogaNode();
root_child1.Width = 50;
root_child1.Height = 50;
root.Insert(1, root_child1);
root.StyleDirection = YogaDirection.LTR;
root.CalculateLayout();
Assert.AreEqual(0f, root.LayoutX);
Assert.AreEqual(0f, root.LayoutY);
Assert.AreEqual(200f, root.LayoutWidth);
Assert.AreEqual(200f, root.LayoutHeight);
Assert.AreEqual(50f, root_child0.LayoutX);
Assert.AreEqual(75f, root_child0.LayoutY);
Assert.AreEqual(50f, root_child0.LayoutWidth);
Assert.AreEqual(50f, root_child0.LayoutHeight);
Assert.AreEqual(150f, root_child1.LayoutX);
Assert.AreEqual(75f, root_child1.LayoutY);
Assert.AreEqual(50f, 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(200f, root.LayoutWidth);
Assert.AreEqual(200f, root.LayoutHeight);
Assert.AreEqual(100f, root_child0.LayoutX);
Assert.AreEqual(75f, root_child0.LayoutY);
Assert.AreEqual(50f, root_child0.LayoutWidth);
Assert.AreEqual(50f, root_child0.LayoutHeight);
Assert.AreEqual(0f, root_child1.LayoutX);
Assert.AreEqual(75f, root_child1.LayoutY);
Assert.AreEqual(50f, root_child1.LayoutWidth);
Assert.AreEqual(50f, root_child1.LayoutHeight);
}
[Test]
public void Test_margin_auto_left_and_right()
{
YogaNode root = new YogaNode();
root.Width = 200;
root.Height = 200;
YogaNode root_child0 = new YogaNode();
root_child0.MarginLeft = YogaValue.Auto();
root_child0.MarginRight = YogaValue.Auto();
root_child0.Width = 50;
root_child0.Height = 50;
root.Insert(0, root_child0);
YogaNode root_child1 = new YogaNode();
root_child1.Width = 50;
root_child1.Height = 50;
root.Insert(1, root_child1);
root.StyleDirection = YogaDirection.LTR;
root.CalculateLayout();
Assert.AreEqual(0f, root.LayoutX);
Assert.AreEqual(0f, root.LayoutY);
Assert.AreEqual(200f, root.LayoutWidth);
Assert.AreEqual(200f, root.LayoutHeight);
Assert.AreEqual(75f, root_child0.LayoutX);
Assert.AreEqual(0f, root_child0.LayoutY);
Assert.AreEqual(50f, root_child0.LayoutWidth);
Assert.AreEqual(50f, root_child0.LayoutHeight);
Assert.AreEqual(0f, root_child1.LayoutX);
Assert.AreEqual(50f, root_child1.LayoutY);
Assert.AreEqual(50f, 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(200f, root.LayoutWidth);
Assert.AreEqual(200f, root.LayoutHeight);
Assert.AreEqual(75f, root_child0.LayoutX);
Assert.AreEqual(0f, root_child0.LayoutY);
Assert.AreEqual(50f, root_child0.LayoutWidth);
Assert.AreEqual(50f, root_child0.LayoutHeight);
Assert.AreEqual(150f, root_child1.LayoutX);
Assert.AreEqual(50f, root_child1.LayoutY);
Assert.AreEqual(50f, root_child1.LayoutWidth);
Assert.AreEqual(50f, root_child1.LayoutHeight);
}
[Test]
public void Test_margin_auto_left_and_right_column_and_center()
{
YogaNode root = new YogaNode();
root.AlignItems = YogaAlign.Center;
root.Width = 200;
root.Height = 200;
YogaNode root_child0 = new YogaNode();
root_child0.MarginLeft = YogaValue.Auto();
root_child0.MarginRight = YogaValue.Auto();
root_child0.Width = 50;
root_child0.Height = 50;
root.Insert(0, root_child0);
YogaNode root_child1 = new YogaNode();
root_child1.Width = 50;
root_child1.Height = 50;
root.Insert(1, root_child1);
root.StyleDirection = YogaDirection.LTR;
root.CalculateLayout();
Assert.AreEqual(0f, root.LayoutX);
Assert.AreEqual(0f, root.LayoutY);
Assert.AreEqual(200f, root.LayoutWidth);
Assert.AreEqual(200f, root.LayoutHeight);
Assert.AreEqual(75f, root_child0.LayoutX);
Assert.AreEqual(0f, root_child0.LayoutY);
Assert.AreEqual(50f, root_child0.LayoutWidth);
Assert.AreEqual(50f, root_child0.LayoutHeight);
Assert.AreEqual(75f, root_child1.LayoutX);
Assert.AreEqual(50f, root_child1.LayoutY);
Assert.AreEqual(50f, 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(200f, root.LayoutWidth);
Assert.AreEqual(200f, root.LayoutHeight);
Assert.AreEqual(75f, root_child0.LayoutX);
Assert.AreEqual(0f, root_child0.LayoutY);
Assert.AreEqual(50f, root_child0.LayoutWidth);
Assert.AreEqual(50f, root_child0.LayoutHeight);
Assert.AreEqual(75f, root_child1.LayoutX);
Assert.AreEqual(50f, root_child1.LayoutY);
Assert.AreEqual(50f, root_child1.LayoutWidth);
Assert.AreEqual(50f, root_child1.LayoutHeight);
}
[Test]
public void Test_margin_auto_left()
{
YogaNode root = new YogaNode();
root.AlignItems = YogaAlign.Center;
root.Width = 200;
root.Height = 200;
YogaNode root_child0 = new YogaNode();
root_child0.MarginLeft = YogaValue.Auto();
root_child0.Width = 50;
root_child0.Height = 50;
root.Insert(0, root_child0);
YogaNode root_child1 = new YogaNode();
root_child1.Width = 50;
root_child1.Height = 50;
root.Insert(1, root_child1);
root.StyleDirection = YogaDirection.LTR;
root.CalculateLayout();
Assert.AreEqual(0f, root.LayoutX);
Assert.AreEqual(0f, root.LayoutY);
Assert.AreEqual(200f, root.LayoutWidth);
Assert.AreEqual(200f, root.LayoutHeight);
Assert.AreEqual(150f, root_child0.LayoutX);
Assert.AreEqual(0f, root_child0.LayoutY);
Assert.AreEqual(50f, root_child0.LayoutWidth);
Assert.AreEqual(50f, root_child0.LayoutHeight);
Assert.AreEqual(75f, root_child1.LayoutX);
Assert.AreEqual(50f, root_child1.LayoutY);
Assert.AreEqual(50f, 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(200f, root.LayoutWidth);
Assert.AreEqual(200f, root.LayoutHeight);
Assert.AreEqual(150f, root_child0.LayoutX);
Assert.AreEqual(0f, root_child0.LayoutY);
Assert.AreEqual(50f, root_child0.LayoutWidth);
Assert.AreEqual(50f, root_child0.LayoutHeight);
Assert.AreEqual(75f, root_child1.LayoutX);
Assert.AreEqual(50f, root_child1.LayoutY);
Assert.AreEqual(50f, root_child1.LayoutWidth);
Assert.AreEqual(50f, root_child1.LayoutHeight);
}
[Test]
public void Test_margin_auto_right()
{
YogaNode root = new YogaNode();
root.AlignItems = YogaAlign.Center;
root.Width = 200;
root.Height = 200;
YogaNode root_child0 = new YogaNode();
root_child0.MarginRight = YogaValue.Auto();
root_child0.Width = 50;
root_child0.Height = 50;
root.Insert(0, root_child0);
YogaNode root_child1 = new YogaNode();
root_child1.Width = 50;
root_child1.Height = 50;
root.Insert(1, root_child1);
root.StyleDirection = YogaDirection.LTR;
root.CalculateLayout();
Assert.AreEqual(0f, root.LayoutX);
Assert.AreEqual(0f, root.LayoutY);
Assert.AreEqual(200f, root.LayoutWidth);
Assert.AreEqual(200f, root.LayoutHeight);
Assert.AreEqual(0f, root_child0.LayoutX);
Assert.AreEqual(0f, root_child0.LayoutY);
Assert.AreEqual(50f, root_child0.LayoutWidth);
Assert.AreEqual(50f, root_child0.LayoutHeight);
Assert.AreEqual(75f, root_child1.LayoutX);
Assert.AreEqual(50f, root_child1.LayoutY);
Assert.AreEqual(50f, 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(200f, root.LayoutWidth);
Assert.AreEqual(200f, root.LayoutHeight);
Assert.AreEqual(0f, root_child0.LayoutX);
Assert.AreEqual(0f, root_child0.LayoutY);
Assert.AreEqual(50f, root_child0.LayoutWidth);
Assert.AreEqual(50f, root_child0.LayoutHeight);
Assert.AreEqual(75f, root_child1.LayoutX);
Assert.AreEqual(50f, root_child1.LayoutY);
Assert.AreEqual(50f, root_child1.LayoutWidth);
Assert.AreEqual(50f, root_child1.LayoutHeight);
}
[Test]
public void Test_margin_auto_left_and_right_strech()
{
YogaNode root = new YogaNode();
root.FlexDirection = YogaFlexDirection.Row;
root.Width = 200;
root.Height = 200;
YogaNode root_child0 = new YogaNode();
root_child0.MarginLeft = YogaValue.Auto();
root_child0.MarginRight = YogaValue.Auto();
root_child0.Width = 50;
root_child0.Height = 50;
root.Insert(0, root_child0);
YogaNode root_child1 = new YogaNode();
root_child1.Width = 50;
root_child1.Height = 50;
root.Insert(1, root_child1);
root.StyleDirection = YogaDirection.LTR;
root.CalculateLayout();
Assert.AreEqual(0f, root.LayoutX);
Assert.AreEqual(0f, root.LayoutY);
Assert.AreEqual(200f, root.LayoutWidth);
Assert.AreEqual(200f, root.LayoutHeight);
Assert.AreEqual(50f, root_child0.LayoutX);
Assert.AreEqual(0f, root_child0.LayoutY);
Assert.AreEqual(50f, root_child0.LayoutWidth);
Assert.AreEqual(50f, root_child0.LayoutHeight);
Assert.AreEqual(150f, root_child1.LayoutX);
Assert.AreEqual(0f, root_child1.LayoutY);
Assert.AreEqual(50f, 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(200f, root.LayoutWidth);
Assert.AreEqual(200f, root.LayoutHeight);
Assert.AreEqual(100f, root_child0.LayoutX);
Assert.AreEqual(0f, root_child0.LayoutY);
Assert.AreEqual(50f, root_child0.LayoutWidth);
Assert.AreEqual(50f, root_child0.LayoutHeight);
Assert.AreEqual(0f, root_child1.LayoutX);
Assert.AreEqual(0f, root_child1.LayoutY);
Assert.AreEqual(50f, root_child1.LayoutWidth);
Assert.AreEqual(50f, root_child1.LayoutHeight);
}
[Test]
public void Test_margin_auto_top_and_bottom_strech()
{
YogaNode root = new YogaNode();
root.Width = 200;
root.Height = 200;
YogaNode root_child0 = new YogaNode();
root_child0.MarginTop = YogaValue.Auto();
root_child0.MarginBottom = YogaValue.Auto();
root_child0.Width = 50;
root_child0.Height = 50;
root.Insert(0, root_child0);
YogaNode root_child1 = new YogaNode();
root_child1.Width = 50;
root_child1.Height = 50;
root.Insert(1, root_child1);
root.StyleDirection = YogaDirection.LTR;
root.CalculateLayout();
Assert.AreEqual(0f, root.LayoutX);
Assert.AreEqual(0f, root.LayoutY);
Assert.AreEqual(200f, root.LayoutWidth);
Assert.AreEqual(200f, root.LayoutHeight);
Assert.AreEqual(0f, root_child0.LayoutX);
Assert.AreEqual(50f, root_child0.LayoutY);
Assert.AreEqual(50f, root_child0.LayoutWidth);
Assert.AreEqual(50f, root_child0.LayoutHeight);
Assert.AreEqual(0f, root_child1.LayoutX);
Assert.AreEqual(150f, root_child1.LayoutY);
Assert.AreEqual(50f, 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(200f, root.LayoutWidth);
Assert.AreEqual(200f, root.LayoutHeight);
Assert.AreEqual(150f, root_child0.LayoutX);
Assert.AreEqual(50f, root_child0.LayoutY);
Assert.AreEqual(50f, root_child0.LayoutWidth);
Assert.AreEqual(50f, root_child0.LayoutHeight);
Assert.AreEqual(150f, root_child1.LayoutX);
Assert.AreEqual(150f, root_child1.LayoutY);
Assert.AreEqual(50f, root_child1.LayoutWidth);
Assert.AreEqual(50f, root_child1.LayoutHeight);
}
}
}

View File

@@ -675,5 +675,138 @@ namespace Facebook.Yoga
Assert.AreEqual(50f, root_child1.LayoutHeight);
}
[Test]
public void Test_min_width_overrides_width()
{
YogaNode root = new YogaNode();
root.Width = 50;
root.MinWidth = 100;
root.StyleDirection = YogaDirection.LTR;
root.CalculateLayout();
Assert.AreEqual(0f, root.LayoutX);
Assert.AreEqual(0f, root.LayoutY);
Assert.AreEqual(100f, root.LayoutWidth);
Assert.AreEqual(0f, root.LayoutHeight);
root.StyleDirection = YogaDirection.RTL;
root.CalculateLayout();
Assert.AreEqual(0f, root.LayoutX);
Assert.AreEqual(0f, root.LayoutY);
Assert.AreEqual(100f, root.LayoutWidth);
Assert.AreEqual(0f, root.LayoutHeight);
}
[Test]
public void Test_max_width_overrides_width()
{
YogaNode root = new YogaNode();
root.Width = 200;
root.MaxWidth = 100;
root.StyleDirection = YogaDirection.LTR;
root.CalculateLayout();
Assert.AreEqual(0f, root.LayoutX);
Assert.AreEqual(0f, root.LayoutY);
Assert.AreEqual(100f, root.LayoutWidth);
Assert.AreEqual(0f, root.LayoutHeight);
root.StyleDirection = YogaDirection.RTL;
root.CalculateLayout();
Assert.AreEqual(0f, root.LayoutX);
Assert.AreEqual(0f, root.LayoutY);
Assert.AreEqual(100f, root.LayoutWidth);
Assert.AreEqual(0f, root.LayoutHeight);
}
[Test]
public void Test_min_height_overrides_height()
{
YogaNode root = new YogaNode();
root.Height = 50;
root.MinHeight = 100;
root.StyleDirection = YogaDirection.LTR;
root.CalculateLayout();
Assert.AreEqual(0f, root.LayoutX);
Assert.AreEqual(0f, root.LayoutY);
Assert.AreEqual(0f, root.LayoutWidth);
Assert.AreEqual(100f, root.LayoutHeight);
root.StyleDirection = YogaDirection.RTL;
root.CalculateLayout();
Assert.AreEqual(0f, root.LayoutX);
Assert.AreEqual(0f, root.LayoutY);
Assert.AreEqual(0f, root.LayoutWidth);
Assert.AreEqual(100f, root.LayoutHeight);
}
[Test]
public void Test_max_height_overrides_height()
{
YogaNode root = new YogaNode();
root.Height = 200;
root.MaxHeight = 100;
root.StyleDirection = YogaDirection.LTR;
root.CalculateLayout();
Assert.AreEqual(0f, root.LayoutX);
Assert.AreEqual(0f, root.LayoutY);
Assert.AreEqual(0f, root.LayoutWidth);
Assert.AreEqual(100f, root.LayoutHeight);
root.StyleDirection = YogaDirection.RTL;
root.CalculateLayout();
Assert.AreEqual(0f, root.LayoutX);
Assert.AreEqual(0f, root.LayoutY);
Assert.AreEqual(0f, root.LayoutWidth);
Assert.AreEqual(100f, root.LayoutHeight);
}
[Test]
public void Test_min_max_percent_no_width_height()
{
YogaNode root = new YogaNode();
root.AlignItems = YogaAlign.FlexStart;
root.Width = 100;
root.Height = 100;
YogaNode root_child0 = new YogaNode();
root_child0.MinWidth = 10.Percent();
root_child0.MaxWidth = 10.Percent();
root_child0.MinHeight = 10.Percent();
root_child0.MaxHeight = 10.Percent();
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(10f, root_child0.LayoutWidth);
Assert.AreEqual(10f, 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(90f, root_child0.LayoutX);
Assert.AreEqual(0f, root_child0.LayoutY);
Assert.AreEqual(10f, root_child0.LayoutWidth);
Assert.AreEqual(10f, root_child0.LayoutHeight);
}
}
}

View File

@@ -44,20 +44,20 @@ namespace Facebook.Yoga
BorderRightWidth = 16,
};
Assert.AreEqual(1.Px(), node.Top);
Assert.AreEqual(2.Px(), node.Bottom);
Assert.AreEqual(3.Px(), node.Left);
Assert.AreEqual(4.Px(), node.Right);
Assert.AreEqual(1.Pt(), node.Top);
Assert.AreEqual(2.Pt(), node.Bottom);
Assert.AreEqual(3.Pt(), node.Left);
Assert.AreEqual(4.Pt(), node.Right);
Assert.AreEqual(5.Px(), node.MarginTop);
Assert.AreEqual(6.Px(), node.MarginBottom);
Assert.AreEqual(7.Px(), node.MarginLeft);
Assert.AreEqual(8.Px(), node.MarginRight);
Assert.AreEqual(5.Pt(), node.MarginTop);
Assert.AreEqual(6.Pt(), node.MarginBottom);
Assert.AreEqual(7.Pt(), node.MarginLeft);
Assert.AreEqual(8.Pt(), node.MarginRight);
Assert.AreEqual(9.Px(), node.PaddingTop);
Assert.AreEqual(10.Px(), node.PaddingBottom);
Assert.AreEqual(11.Px(), node.PaddingLeft);
Assert.AreEqual(12.Px(), node.PaddingRight);
Assert.AreEqual(9.Pt(), node.PaddingTop);
Assert.AreEqual(10.Pt(), node.PaddingBottom);
Assert.AreEqual(11.Pt(), node.PaddingLeft);
Assert.AreEqual(12.Pt(), node.PaddingRight);
Assert.AreEqual(13, node.BorderTopWidth);
Assert.AreEqual(14, node.BorderBottomWidth);
@@ -90,20 +90,20 @@ namespace Facebook.Yoga
node.BorderLeftWidth = 15;
node.BorderRightWidth = 16;
Assert.AreEqual(1.Px(), node.Top);
Assert.AreEqual(2.Px(), node.Bottom);
Assert.AreEqual(3.Px(), node.Left);
Assert.AreEqual(4.Px(), node.Right);
Assert.AreEqual(1.Pt(), node.Top);
Assert.AreEqual(2.Pt(), node.Bottom);
Assert.AreEqual(3.Pt(), node.Left);
Assert.AreEqual(4.Pt(), node.Right);
Assert.AreEqual(5.Px(), node.MarginTop);
Assert.AreEqual(6.Px(), node.MarginBottom);
Assert.AreEqual(7.Px(), node.MarginLeft);
Assert.AreEqual(8.Px(), node.MarginRight);
Assert.AreEqual(5.Pt(), node.MarginTop);
Assert.AreEqual(6.Pt(), node.MarginBottom);
Assert.AreEqual(7.Pt(), node.MarginLeft);
Assert.AreEqual(8.Pt(), node.MarginRight);
Assert.AreEqual(9.Px(), node.PaddingTop);
Assert.AreEqual(10.Px(), node.PaddingBottom);
Assert.AreEqual(11.Px(), node.PaddingLeft);
Assert.AreEqual(12.Px(), node.PaddingRight);
Assert.AreEqual(9.Pt(), node.PaddingTop);
Assert.AreEqual(10.Pt(), node.PaddingBottom);
Assert.AreEqual(11.Pt(), node.PaddingLeft);
Assert.AreEqual(12.Pt(), node.PaddingRight);
Assert.AreEqual(13, node.BorderTopWidth);
Assert.AreEqual(14, node.BorderBottomWidth);

View File

@@ -260,7 +260,7 @@ namespace Facebook.Yoga
parent.Insert(0, child0);
parent.Insert(0, child1);
parent.CalculateLayout();
Assert.AreEqual("{layout: {width: 100, height: 120, top: 0, left: 0}, flexDirection: 'column', alignItems: 'stretch', flexGrow: 0, flexShrink: 0, overflow: 'visible', width: 100px, height: 120px, children: [\n {layout: {width: 35, height: 45, top: 0, left: 0}, flexDirection: 'column', alignItems: 'stretch', flexGrow: 0, flexShrink: 0, overflow: 'visible', width: 35px, height: 45px, },\n {layout: {width: 30, height: 40, top: 45, left: 0}, flexDirection: 'column', alignItems: 'stretch', flexGrow: 0, flexShrink: 0, overflow: 'visible', width: 30px, height: 40px, },\n]},\n", parent.Print());
Assert.AreEqual("{layout: {width: 100, height: 120, top: 0, left: 0}, flexDirection: 'column', alignItems: 'stretch', flexGrow: 0, flexShrink: 0, flexBasis: nan%, overflow: 'visible', width: 100pt, height: 120pt, children: [\n {layout: {width: 35, height: 45, top: 0, left: 0}, flexDirection: 'column', alignItems: 'stretch', flexGrow: 0, flexShrink: 0, flexBasis: nan%, overflow: 'visible', width: 35pt, height: 45pt, },\n {layout: {width: 30, height: 40, top: 45, left: 0}, flexDirection: 'column', alignItems: 'stretch', flexGrow: 0, flexShrink: 0, flexBasis: nan%, overflow: 'visible', width: 30pt, height: 40pt, },\n]},\n", parent.Print());
}
[Test]
@@ -273,7 +273,7 @@ namespace Facebook.Yoga
node1.MaxHeight = 100;
node0.CopyStyle(node1);
Assert.AreEqual(100.Px(), node0.MaxHeight);
Assert.AreEqual(100.Pt(), node0.MaxHeight);
}
[Test]
@@ -283,27 +283,27 @@ namespace Facebook.Yoga
node0.MaxWidth = 80;
YogaNode node1 = new YogaNode(node0);
Assert.AreEqual(80.Px(), node1.MaxWidth);
Assert.AreEqual(80.Pt(), node1.MaxWidth);
YogaNode node2 = new YogaNode(node1)
{
MaxHeight = 90,
};
Assert.AreEqual(80.Px(), node2.MaxWidth);
Assert.AreEqual(90.Px(), node2.MaxHeight);
Assert.AreEqual(80.Pt(), node2.MaxWidth);
Assert.AreEqual(90.Pt(), node2.MaxHeight);
YogaNode node3 = new YogaNode(node0)
{
MaxWidth = 100,
};
Assert.AreEqual(100.Px(), node3.MaxWidth);
Assert.AreEqual(100.Pt(), node3.MaxWidth);
YogaNode node4 = new YogaNode(node2)
{
MaxWidth = 100,
};
Assert.AreEqual(100.Px(), node4.MaxWidth);
Assert.AreEqual(90.Px(), node4.MaxHeight);
Assert.AreEqual(100.Pt(), node4.MaxWidth);
Assert.AreEqual(90.Pt(), node4.MaxHeight);
}
private void ForceGC()

View File

@@ -4,7 +4,7 @@ title: YOGA
tagline: A cross-platform layout engine
fbappid: "1615782811974223"
gacode: "UA-12345-6"
gacode: "UA-44373548-24"
# baseurl determines the subpath of your site. For example if you're using an
# organisation.github.io/reponame/ basic site URL, then baseurl would be set

View File

@@ -21,5 +21,6 @@
- id: c
- id: yogakit
- id: java
- id: android
- id: csharp
- id: javascript

28
docs/_docs/api/android.md Normal file
View File

@@ -0,0 +1,28 @@
---
docid: android
title: Android
layout: docs
permalink: /docs/api/android/
---
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
<script src="https://gist.github.com/rspencer01/c1964b98f0c60de7c49683a049ed0640.js"></script>
Note that there are some caveats, such as requiring the custom `YogaLayoutViewFactory` in order to have tags `YogaLayout` instead of `com.facebook.samples.yoga.YogaLayout`.
## 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.
## VirtualYogaLayout
Sometimes you will nest `YogaLayout`s within `YogaLayout`s in order to get your layout to be perfect, but some of the `YogaLayout`s are just there to control position: they don't render or anything. If so, then they are unnecessary (since Yoga stores the view hierarchy itself) and `VirtualYogaLayout` is a ViewGroup that fixes this. It will never get drawn, but all its children will be placed appropriately.
## 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!
## 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.

View File

@@ -35,7 +35,7 @@ Once you have set up a tree of nodes with styles you will want to get the result
### Custom measurements
Certain nodes need to ability to measure themselves, the most common example is nodes which represent text. Text has an intrinsic size and requires measuring itself to determine that size. This is not something Yoga can do as it requires relying on the host system's text rendering engine.
Certain nodes need the ability to measure themselves, the most common example is nodes which represent text. Text has an intrinsic size and requires measuring itself to determine that size. This is not something Yoga can do as it requires relying on the host system's text rendering engine.
- Call `YGNodeMarkDirty` if a node with a custom text measurement function needs to be re-measured during the next layout pass.

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