Compare commits
174 Commits
v2017.02.0
...
1.4.1
Author | SHA1 | Date | |
---|---|---|---|
|
aa5b296ac7 | ||
|
f2b5d0fef7 | ||
|
0684795a89 | ||
|
2ffc23f400 | ||
|
dc4d16401f | ||
|
849de89a58 | ||
|
f8a2903d02 | ||
|
60977de242 | ||
|
cb612bcfbe | ||
|
6be1c2cdb4 | ||
|
034ab0b3b1 | ||
|
8c50347f3c | ||
|
9f76fb6980 | ||
|
8b0ff0a25c | ||
|
8891ea1a7a | ||
|
ede2ad94bc | ||
|
eacf3cdbb4 | ||
|
3569a13b74 | ||
|
b2a96ec744 | ||
|
a505adb2b7 | ||
|
906b6e52f8 | ||
|
3292337754 | ||
|
eb4af86e3c | ||
|
1b3e971549 | ||
|
4615eee2d8 | ||
|
7c57245943 | ||
|
0d100ad7e9 | ||
|
0235789863 | ||
|
c080a46571 | ||
|
5f050cb590 | ||
|
25f14a1917 | ||
|
e9927377b5 | ||
|
3ea76f8a9b | ||
|
8a45ed9671 | ||
|
1520749351 | ||
|
f66f52d1ba | ||
|
49e18738c3 | ||
|
586b57009a | ||
|
5112564f08 | ||
|
34726a9926 | ||
|
5884ab7b76 | ||
|
60db018ce4 | ||
|
6b002bad3d | ||
|
5b173c1b61 | ||
|
bc2fb5c7ab | ||
|
ebdf82f491 | ||
|
36f6fa9861 | ||
|
91a34bb875 | ||
|
d342fb1879 | ||
|
b283572453 | ||
|
62a74a5ef9 | ||
|
a14aeb27bb | ||
|
249d010dad | ||
|
9b13fdeae4 | ||
|
794b6b35ce | ||
|
dcff4d3db2 | ||
|
b94466e502 | ||
|
11052053d8 | ||
|
6ab3984bba | ||
|
136e0c7e52 | ||
|
7e2ef926ea | ||
|
061981fb23 | ||
|
3d6fb2f2e5 | ||
|
a8e6123d47 | ||
|
406c8a2117 | ||
|
0445962bd4 | ||
|
09f0c2d8ce | ||
|
8dea884a69 | ||
|
57898762a2 | ||
|
01bf8d7b6c | ||
|
af8d55c08e | ||
|
53398b42c6 | ||
|
1bf142e048 | ||
|
0405c4f77d | ||
|
61595763b0 | ||
|
f6ecc8da7b | ||
|
32792a0de5 | ||
|
c3d60b55bd | ||
|
17be6718ee | ||
|
abf912b729 | ||
|
5bc0197c78 | ||
|
62f47190fb | ||
|
a706f4c97c | ||
|
feb365a77b | ||
|
b2a4e67fee | ||
|
e7d2792009 | ||
|
0fde1424f0 | ||
|
29fd447f0c | ||
|
7047d96087 | ||
|
6336e641f4 | ||
|
ecabe757a2 | ||
|
37c48257ae | ||
|
8668e43f6d | ||
|
785713c9c0 | ||
|
b523402eda | ||
|
3790635af1 | ||
|
b940fadb7e | ||
|
3ef2970032 | ||
|
4372aa16d3 | ||
|
3346f9511a | ||
|
1cd7363bea | ||
|
17e3dca9f9 | ||
|
533f560ce0 | ||
|
6a60d4893e | ||
|
51dd082682 | ||
|
47d8d9d22b | ||
|
d6d4dcb141 | ||
|
37ec1774a7 | ||
|
3ad4d7dd6e | ||
|
e596091fa2 | ||
|
4f5c7ed6af | ||
|
60ffa1953b | ||
|
5519a73087 | ||
|
67717a7872 | ||
|
4522d4b8aa | ||
|
d7ca339c27 | ||
|
6b39165801 | ||
|
78ade6cfb5 | ||
|
3f68b4f76b | ||
|
521aab5fcc | ||
|
42492596b3 | ||
|
b24e728666 | ||
|
4fe0b810e1 | ||
|
8deed174f5 | ||
|
2184547094 | ||
|
8eda4dc040 | ||
|
4d4db92a46 | ||
|
ea8b7e0c91 | ||
|
6928957096 | ||
|
b680b726d1 | ||
|
fbd692c449 | ||
|
2199a7908d | ||
|
59704f1508 | ||
|
20536923d6 | ||
|
bba7289537 | ||
|
04d1ccc085 | ||
|
a7e7c5eb52 | ||
|
9d2839f8ca | ||
|
1146013e9e | ||
|
8a91c0a0e5 | ||
|
a1c75454e9 | ||
|
ad3963daa6 | ||
|
a66339d63c | ||
|
d0bdd4dc91 | ||
|
d24078be31 | ||
|
f251648726 | ||
|
b587ecb30f | ||
|
a580712b2f | ||
|
ce5d52b54e | ||
|
55fe6f0bc9 | ||
|
abf142ea3f | ||
|
ae9f89b5d1 | ||
|
058761e16e | ||
|
ad8c6225fd | ||
|
1cbadf5f54 | ||
|
e7021715b8 | ||
|
0d2749a3fd | ||
|
76fbd628e1 | ||
|
15309d2bdd | ||
|
4f6924a0c1 | ||
|
063f65d065 | ||
|
adf8691093 | ||
|
6a7ad2125d | ||
|
247aa26d3e | ||
|
3c9f620c77 | ||
|
e0e2a61dfc | ||
|
168ae4099d | ||
|
6ceb4af2d4 | ||
|
240c2dd657 | ||
|
a5b94ebd0c | ||
|
5037c2f365 | ||
|
ef05404bee | ||
|
3db493665e | ||
|
737f1cc67c |
@@ -1,2 +1,9 @@
|
||||
[cxx]
|
||||
gtest_dep = //lib/gtest:gtest
|
||||
[android]
|
||||
target = android-23
|
||||
[ndk]
|
||||
ndk_version = 13.1.3345770
|
||||
compiler = clang
|
||||
app_platform = android-21
|
||||
cpu_abis = arm64, armv7, x86, x86_64
|
||||
|
5
.gitignore
vendored
5
.gitignore
vendored
@@ -60,3 +60,8 @@ Pods/
|
||||
# Carthage/Checkouts
|
||||
|
||||
Carthage/Build
|
||||
|
||||
# Gradle
|
||||
.gradle
|
||||
# NDK/CMake
|
||||
.externalNativeBuild
|
||||
|
126
.travis.yml
126
.travis.yml
@@ -10,33 +10,117 @@ 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;
|
||||
gem install xcpretty --no-document --quiet;
|
||||
gem install cocoapods --pre --no-document --quiet;
|
||||
pod repo update --silent;
|
||||
pod install --project-directory=YogaKit/YogaKitSample/;
|
||||
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/Cellar/android-sdk/24.4.1_1;
|
||||
export ANDROID_HOME=/usr/local/Cellar/android-sdk/24.4.1_1;
|
||||
brew install lib32stdc++6 lib32z1;
|
||||
echo y | $ANDROID_SDK/tools/android update sdk --filter android-19,addon-google_apis-google-19,build-tools-19.1.0 --no-ui;
|
||||
echo y | $ANDROID_SDK/tools/android update sdk -u;
|
||||
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 &&
|
||||
set -o pipefail &&
|
||||
xcodebuild build -workspace YogaKit/YogaKitSample/YogaKitSample.xcworkspace -scheme YogaKitSample -sdk iphonesimulator | xcpretty -c
|
||||
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
|
||||
|
53
BUCK
53
BUCK
@@ -5,38 +5,41 @@
|
||||
# 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')
|
||||
include_defs("//YOGA_DEFS")
|
||||
|
||||
GMOCK_OVERRIDE_FLAGS = [
|
||||
# gmock does not mark mocked methods as override, ignore the warnings in tests
|
||||
'-Wno-inconsistent-missing-override',
|
||||
# gmock does not mark mocked methods as override, ignore the warnings in tests
|
||||
"-Wno-inconsistent-missing-override",
|
||||
]
|
||||
|
||||
COMPILER_FLAGS = BASE_COMPILER_FLAGS + ['-std=c11', '-fPIC']
|
||||
TEST_COMPILER_FLAGS = BASE_COMPILER_FLAGS + GMOCK_OVERRIDE_FLAGS + ['-std=c++11']
|
||||
COMPILER_FLAGS = LIBRARY_COMPILER_FLAGS + [
|
||||
"-std=c11",
|
||||
]
|
||||
|
||||
TEST_COMPILER_FLAGS = BASE_COMPILER_FLAGS + GMOCK_OVERRIDE_FLAGS + ["-std=c++11"]
|
||||
|
||||
cxx_library(
|
||||
name = 'yoga',
|
||||
soname = 'libyogacore.$(ext)',
|
||||
srcs = glob(['yoga/*.c']),
|
||||
tests=[':YogaTests'],
|
||||
exported_headers = subdir_glob([('', 'yoga/*.h')]),
|
||||
header_namespace = '',
|
||||
compiler_flags = COMPILER_FLAGS,
|
||||
deps = [] if THIS_IS_FBOBJC else [
|
||||
yoga_dep('lib/fb:ndklog'),
|
||||
],
|
||||
visibility = ['PUBLIC'],
|
||||
name = "yoga",
|
||||
srcs = glob(["yoga/*.c"]),
|
||||
compiler_flags = COMPILER_FLAGS,
|
||||
exported_headers = subdir_glob([("", "yoga/*.h")]),
|
||||
header_namespace = "",
|
||||
soname = "libyogacore.$(ext)",
|
||||
tests = [":YogaTests"],
|
||||
visibility = ["PUBLIC"],
|
||||
deps = [] if THIS_IS_FBOBJC else [
|
||||
yoga_dep("lib/fb:ndklog"),
|
||||
],
|
||||
)
|
||||
|
||||
cxx_test(
|
||||
name = 'YogaTests',
|
||||
contacts = ['emilsj@fb.com'],
|
||||
srcs = glob(['tests/*.cpp']),
|
||||
compiler_flags = TEST_COMPILER_FLAGS,
|
||||
deps = [
|
||||
':yoga',
|
||||
GTEST_TARGET,
|
||||
],
|
||||
visibility = ['PUBLIC'],
|
||||
name = "YogaTests",
|
||||
srcs = glob(["tests/*.cpp"]),
|
||||
compiler_flags = TEST_COMPILER_FLAGS,
|
||||
contacts = ["emilsj@fb.com"],
|
||||
visibility = ["PUBLIC"],
|
||||
deps = [
|
||||
":yoga",
|
||||
GTEST_TARGET,
|
||||
],
|
||||
)
|
||||
|
17
CMakeLists.txt
Normal file
17
CMakeLists.txt
Normal file
@@ -0,0 +1,17 @@
|
||||
#
|
||||
# Copyright (c) 2014-present, Facebook, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# This source code is licensed under the BSD-style license found in the
|
||||
# LICENSE file in the root directory of this source tree. An additional grant
|
||||
# of patent rights can be found in the PATENTS file in the same directory.
|
||||
#
|
||||
|
||||
cmake_minimum_required(VERSION 3.4.1)
|
||||
|
||||
set(CMAKE_VERBOSE_MAKEFILE on)
|
||||
|
||||
file(GLOB yogacore_SRC yoga/*.c)
|
||||
add_library(yogacore STATIC ${yogacore_SRC})
|
||||
|
||||
target_link_libraries(yogacore android log)
|
12
README.md
12
README.md
@@ -1,4 +1,14 @@
|
||||
# Yoga [](https://travis-ci.org/facebook/yoga) [](http://cocoapods.org/pods/YogaKit) [](https://www.npmjs.com/package/yoga-layout)
|
||||
# Yoga [](http://cocoapods.org/pods/YogaKit) [](https://www.npmjs.com/package/yoga-layout) [](https://bintray.com/facebook/maven/com.facebook.yoga%3Ayoga/_latestVersion) [](https://www.nuget.org/packages/Facebook.Yoga)
|
||||
|
||||
[](https://travis-ci.org/facebook/yoga)
|
||||
[](https://travis-ci.org/facebook/yoga)
|
||||
[](https://travis-ci.org/facebook/yoga)
|
||||
[](https://travis-ci.org/facebook/yoga)
|
||||
[](https://travis-ci.org/facebook/yoga)
|
||||
[](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.
|
||||
|
25
YOGA_DEFS
25
YOGA_DEFS
@@ -1,13 +1,21 @@
|
||||
|
||||
YOGA_ROOT = '//...'
|
||||
YOGA_ROOTS = ['//...']
|
||||
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'
|
||||
PROGRUARD_ANNOTATIONS_TARGET = '//java/com/facebook/proguard/annotations:annotations'
|
||||
PROGRUARD_ANNOTATIONS_TARGET = '//java/proguard-annotations/src/main/java/com/facebook/proguard/annotations:annotations'
|
||||
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
|
||||
|
||||
@@ -25,11 +33,14 @@ BASE_COMPILER_FLAGS = [
|
||||
'-O3',
|
||||
]
|
||||
|
||||
LIBRARY_COMPILER_FLAGS = BASE_COMPILER_FLAGS + [
|
||||
'-fPIC',
|
||||
]
|
||||
|
||||
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)
|
||||
|
@@ -1,6 +1,6 @@
|
||||
Pod::Spec.new do |spec|
|
||||
spec.name = 'Yoga'
|
||||
spec.version = '1.0.2'
|
||||
spec.version = '1.3.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 => '1.3.0',
|
||||
}
|
||||
|
||||
spec.module_name = 'yoga'
|
||||
|
@@ -1,6 +1,6 @@
|
||||
podspec = Pod::Spec.new do |spec|
|
||||
spec.name = 'YogaKit'
|
||||
spec.version = '1.0.3'
|
||||
spec.version = '1.3.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 => '1.3.0',
|
||||
}
|
||||
|
||||
spec.platform = :ios
|
||||
spec.ios.deployment_target = '8.0'
|
||||
spec.ios.frameworks = 'UIKit'
|
||||
|
||||
spec.dependency 'Yoga', '~> 1.0'
|
||||
spec.dependency 'Yoga', '~> 1.3'
|
||||
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'
|
||||
|
84
YogaKit/BUCK
84
YogaKit/BUCK
@@ -5,54 +5,54 @@
|
||||
# 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')
|
||||
include_defs("//YOGA_DEFS")
|
||||
|
||||
COMPILER_FLAGS = [
|
||||
'-fobjc-arc',
|
||||
'-Wconditional-uninitialized',
|
||||
'-Wdangling-else',
|
||||
'-Wdeprecated-declarations',
|
||||
'-Wimplicit-retain-self',
|
||||
'-Wincomplete-implementation',
|
||||
'-Wobjc-method-access',
|
||||
'-Wobjc-missing-super-calls',
|
||||
'-Wmismatched-return-types',
|
||||
'-Wreturn-type',
|
||||
'-Wno-global-constructors',
|
||||
'-Wno-shadow',
|
||||
'-Wunused-const-variable',
|
||||
'-Wunused-function',
|
||||
'-Wunused-property-ivar',
|
||||
'-Wunused-result',
|
||||
'-Wunused-value',
|
||||
"-fobjc-arc",
|
||||
"-Wconditional-uninitialized",
|
||||
"-Wdangling-else",
|
||||
"-Wdeprecated-declarations",
|
||||
"-Wimplicit-retain-self",
|
||||
"-Wincomplete-implementation",
|
||||
"-Wobjc-method-access",
|
||||
"-Wobjc-missing-super-calls",
|
||||
"-Wmismatched-return-types",
|
||||
"-Wreturn-type",
|
||||
"-Wno-global-constructors",
|
||||
"-Wno-shadow",
|
||||
"-Wunused-const-variable",
|
||||
"-Wunused-function",
|
||||
"-Wunused-property-ivar",
|
||||
"-Wunused-result",
|
||||
"-Wunused-value",
|
||||
]
|
||||
|
||||
apple_library(
|
||||
name = 'YogaKit',
|
||||
compiler_flags = COMPILER_FLAGS,
|
||||
srcs = glob(['Source/**/*.m']),
|
||||
exported_headers = glob(['Source/**/*.h']),
|
||||
frameworks = [
|
||||
'$SDKROOT/System/Library/Frameworks/Foundation.framework',
|
||||
'$SDKROOT/System/Library/Frameworks/UIKit.framework',
|
||||
],
|
||||
deps = [
|
||||
yoga_dep(':yoga'),
|
||||
],
|
||||
visibility = ['PUBLIC'],
|
||||
name = "YogaKit",
|
||||
srcs = glob(["Source/**/*.m"]),
|
||||
compiler_flags = COMPILER_FLAGS,
|
||||
exported_headers = glob(["Source/**/*.h"]),
|
||||
frameworks = [
|
||||
"$SDKROOT/System/Library/Frameworks/Foundation.framework",
|
||||
"$SDKROOT/System/Library/Frameworks/UIKit.framework",
|
||||
],
|
||||
visibility = ["PUBLIC"],
|
||||
deps = [
|
||||
yoga_dep(":yoga"),
|
||||
],
|
||||
)
|
||||
|
||||
apple_test(
|
||||
name = 'YogaKitTests',
|
||||
compiler_flags = COMPILER_FLAGS,
|
||||
info_plist = 'Tests/Info.plist',
|
||||
srcs = glob(['Tests/**/*.m']),
|
||||
frameworks = [
|
||||
'$SDKROOT/System/Library/Frameworks/CoreGraphics.framework',
|
||||
'$PLATFORM_DIR/Developer/Library/Frameworks/XCTest.framework',
|
||||
],
|
||||
deps = [
|
||||
':YogaKit',
|
||||
],
|
||||
visibility = ['PUBLIC'],
|
||||
name = "YogaKitTests",
|
||||
srcs = glob(["Tests/**/*.m"]),
|
||||
compiler_flags = COMPILER_FLAGS,
|
||||
frameworks = [
|
||||
"$PLATFORM_DIR/Developer/Library/Frameworks/XCTest.framework",
|
||||
"$SDKROOT/System/Library/Frameworks/CoreGraphics.framework",
|
||||
],
|
||||
info_plist = "Tests/Info.plist",
|
||||
visibility = ["PUBLIC"],
|
||||
deps = [
|
||||
":YogaKit",
|
||||
],
|
||||
)
|
||||
|
46
YogaKit/CHANGELOG.md
Normal file
46
YogaKit/CHANGELOG.md
Normal 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.
|
@@ -8,7 +8,7 @@
|
||||
YogaKit is available to install via [CocoaPods](https://cocoapods.org/).
|
||||
|
||||
```
|
||||
pod 'YogaKit', '~> 1.0.2'
|
||||
pod 'YogaKit', '~> 1.3'
|
||||
```
|
||||
|
||||
## Getting Started
|
||||
@@ -19,4 +19,4 @@ We also have a sample project. To try it out, clone this repo and open `YogaKitS
|
||||
## Contributing
|
||||
We welcome all pull-requests! At Facebook we sync the open source version of `YogaKit` daily, so we're always testing the latest changes.
|
||||
|
||||
See the [CONTRIBUTING](https://github.com/facebook/yoga/blob/master/CONTRIBUTING) file for how to help out.
|
||||
See the [CONTRIBUTING.md](https://github.com/facebook/yoga/blob/master/CONTRIBUTING.md) file for how to help out.
|
||||
|
@@ -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
|
||||
|
@@ -26,5 +26,11 @@ static const void *kYGYogaAssociatedKey = &kYGYogaAssociatedKey;
|
||||
return yoga;
|
||||
}
|
||||
|
||||
- (void)configureLayoutWithBlock:(YGLayoutConfigurationBlock)block
|
||||
{
|
||||
if (block != nil) {
|
||||
block(self.yoga);
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
@@ -10,6 +10,11 @@
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <yoga/YGEnums.h>
|
||||
|
||||
typedef NS_OPTIONS(NSInteger, YGDimensionFlexibility) {
|
||||
YGDimensionFlexibilityFlexibleWidth = 1 << 0,
|
||||
YGDimensionFlexibilityFlexibleHeigth = 1 << 1,
|
||||
};
|
||||
|
||||
@interface YGLayout : NSObject
|
||||
|
||||
/**
|
||||
@@ -89,9 +94,18 @@
|
||||
@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:));
|
||||
|
||||
/**
|
||||
Perform a layout calculation and update the frames of the views in the hierarchy with the results.
|
||||
If the origin is not preserved, the root view's layout results will applied from {0,0}.
|
||||
*/
|
||||
- (void)applyLayoutPreservingOrigin:(BOOL)preserveOrigin dimensionFlexibility:(YGDimensionFlexibility)dimensionFlexibility
|
||||
NS_SWIFT_NAME(applyLayout(preservingOrigin:dimensionFlexibility:));
|
||||
|
||||
/**
|
||||
Returns the size of the view if no constraints were given. This could equivalent to calling [self
|
||||
@@ -110,6 +124,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.
|
||||
*/
|
||||
|
@@ -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,11 @@ 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)
|
||||
|
||||
static YGConfigRef globalConfig;
|
||||
|
||||
@interface YGLayout ()
|
||||
|
||||
@@ -113,14 +101,15 @@ YG_VALUE_SHORTHAND_EDGE_PROPERTY(lowercased_name, capitalized_name, capitalized_
|
||||
|
||||
+ (void)initialize
|
||||
{
|
||||
YGSetExperimentalFeatureEnabled(YGExperimentalFeatureWebFlexBasis, true);
|
||||
globalConfig = YGConfigNew();
|
||||
YGConfigSetExperimentalFeatureEnabled(globalConfig, YGExperimentalFeatureWebFlexBasis, true);
|
||||
}
|
||||
|
||||
- (instancetype)initWithView:(UIView*)view
|
||||
{
|
||||
if (self = [super init]) {
|
||||
_view = view;
|
||||
_node = YGNodeNew();
|
||||
_node = YGNodeNewWithConfig(globalConfig);
|
||||
YGNodeSetContext(_node, (__bridge void *) view);
|
||||
_isEnabled = NO;
|
||||
_isIncludedInLayout = YES;
|
||||
@@ -134,11 +123,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 +206,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,9 +226,29 @@ 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);
|
||||
}
|
||||
|
||||
- (void)applyLayoutPreservingOrigin:(BOOL)preserveOrigin dimensionFlexibility:(YGDimensionFlexibility)dimensionFlexibility
|
||||
{
|
||||
CGSize size = self.view.bounds.size;
|
||||
if (dimensionFlexibility & YGDimensionFlexibilityFlexibleWidth) {
|
||||
size.width = YGUndefined;
|
||||
}
|
||||
if (dimensionFlexibility & YGDimensionFlexibilityFlexibleHeigth) {
|
||||
size.height = YGUndefined;
|
||||
}
|
||||
[self calculateLayoutWithSize:size];
|
||||
YGApplyLayoutToViewHierarchy(self.view, NO);
|
||||
}
|
||||
|
||||
|
||||
- (CGSize)intrinsicSize
|
||||
{
|
||||
const CGSize constrainedSize = {
|
||||
@@ -361,10 +385,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 +409,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 +423,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -18,6 +18,26 @@
|
||||
|
||||
@implementation YogaKitTests
|
||||
|
||||
- (void)testConfigureLayoutIsNoOpWithNilBlock
|
||||
{
|
||||
UIView *view = [[UIView alloc] initWithFrame:CGRectZero];
|
||||
id block = nil;
|
||||
XCTAssertNoThrow([view configureLayoutWithBlock:block]);
|
||||
}
|
||||
|
||||
- (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 +129,97 @@
|
||||
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)testContainerWithFlexibleWidthGetsCorrectlySized
|
||||
{
|
||||
UIView *container = [[UIView alloc] initWithFrame:CGRectMake(0,0,200,200)];
|
||||
container.yoga.isEnabled = YES;
|
||||
|
||||
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
|
||||
view.yoga.isEnabled = YES;
|
||||
view.yoga.width = 100;
|
||||
view.yoga.height = 100;
|
||||
[container addSubview:view];
|
||||
|
||||
[container.yoga applyLayoutPreservingOrigin:YES dimensionFlexibility:YGDimensionFlexibilityFlexibleWidth];
|
||||
XCTAssertEqual(100, container.frame.size.width);
|
||||
XCTAssertEqual(200, container.frame.size.height);
|
||||
}
|
||||
|
||||
- (void)testContainerWithFlexibleHeightGetsCorrectlySized
|
||||
{
|
||||
UIView *container = [[UIView alloc] initWithFrame:CGRectMake(0,0,200,200)];
|
||||
container.yoga.isEnabled = YES;
|
||||
|
||||
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
|
||||
view.yoga.isEnabled = YES;
|
||||
view.yoga.width = 100;
|
||||
view.yoga.height = 100;
|
||||
[container addSubview:view];
|
||||
|
||||
[container.yoga applyLayoutPreservingOrigin:YES dimensionFlexibility:YGDimensionFlexibilityFlexibleHeigth];
|
||||
XCTAssertEqual(200, container.frame.size.width);
|
||||
XCTAssertEqual(100, container.frame.size.height);
|
||||
}
|
||||
|
||||
- (void)testContainerWithFlexibleWidthAndHeightGetsCorrectlySized
|
||||
{
|
||||
UIView *container = [[UIView alloc] initWithFrame:CGRectMake(0,0,200,200)];
|
||||
container.yoga.isEnabled = YES;
|
||||
|
||||
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
|
||||
view.yoga.isEnabled = YES;
|
||||
view.yoga.width = 100;
|
||||
view.yoga.height = 100;
|
||||
[container addSubview:view];
|
||||
|
||||
[container.yoga applyLayoutPreservingOrigin:YES dimensionFlexibility:YGDimensionFlexibilityFlexibleWidth | YGDimensionFlexibilityFlexibleHeigth];
|
||||
XCTAssertEqual(100, container.frame.size.width);
|
||||
XCTAssertEqual(100, container.frame.size.height);
|
||||
}
|
||||
|
||||
- (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 +227,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 +268,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 +304,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 +312,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 +344,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 +381,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 +411,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 +472,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 +481,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 +517,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 +528,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 +562,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 +620,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 +678,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);
|
||||
|
@@ -2,4 +2,5 @@ use_frameworks!
|
||||
|
||||
target 'YogaKitSample' do
|
||||
pod 'YogaKit', :path => '../../YogaKit.podspec'
|
||||
pod 'IGListKit', '~> 2.1.0'
|
||||
end
|
||||
|
@@ -1,9 +1,15 @@
|
||||
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.3.0)
|
||||
- YogaKit (1.3.0):
|
||||
- Yoga (~> 1.3)
|
||||
|
||||
DEPENDENCIES:
|
||||
- IGListKit (~> 2.1.0)
|
||||
- YogaKit (from `../../YogaKit.podspec`)
|
||||
|
||||
EXTERNAL SOURCES:
|
||||
@@ -11,9 +17,10 @@ EXTERNAL SOURCES:
|
||||
:path: "../../YogaKit.podspec"
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
Yoga: ef42f88b9bcbd7daf7267c0f19d8636ce3a50618
|
||||
YogaKit: 6d9826a015c029b13731a33bf96fe6c1e33748a6
|
||||
IGListKit: b826c68ef7a4ae1626c09d4d3e1ea7a169e6c36e
|
||||
Yoga: 2ed1d7accfef3610a67f58c0cf101a0662137f2c
|
||||
YogaKit: cddeccc6a8d2aff563e4c738d3bddb290a6de4cb
|
||||
|
||||
PODFILE CHECKSUM: 9db3bdea7f1b4b715ad859a449b2dc87fb6226cc
|
||||
PODFILE CHECKSUM: 216f8e7127767709e0e43f3711208d238fa5c404
|
||||
|
||||
COCOAPODS: 1.2.0
|
||||
|
@@ -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;
|
||||
};
|
||||
|
@@ -0,0 +1,101 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0820"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "13687D421DF8748300E7C260"
|
||||
BuildableName = "YogaKitSample.app"
|
||||
BlueprintName = "YogaKitSample"
|
||||
ReferencedContainer = "container:YogaKitSample.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
<TestableReference
|
||||
skipped = "NO">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "638A944E1E215CC800A726AD"
|
||||
BuildableName = "YogaKitSampleTests.xctest"
|
||||
BlueprintName = "YogaKitSampleTests"
|
||||
ReferencedContainer = "container:YogaKitSample.xcodeproj">
|
||||
</BuildableReference>
|
||||
</TestableReference>
|
||||
</Testables>
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "13687D421DF8748300E7C260"
|
||||
BuildableName = "YogaKitSample.app"
|
||||
BlueprintName = "YogaKitSample"
|
||||
ReferencedContainer = "container:YogaKitSample.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "13687D421DF8748300E7C260"
|
||||
BuildableName = "YogaKitSample.app"
|
||||
BlueprintName = "YogaKitSample"
|
||||
ReferencedContainer = "container:YogaKitSample.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "13687D421DF8748300E7C260"
|
||||
BuildableName = "YogaKitSample.app"
|
||||
BlueprintName = "YogaKitSample"
|
||||
ReferencedContainer = "container:YogaKitSample.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
@@ -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
|
@@ -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
|
27
YogaKit/YogaKitSample/YogaKitSample/AppDelegate.swift
Normal file
27
YogaKit/YogaKitSample/YogaKitSample/AppDelegate.swift
Normal 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()
|
||||
}
|
||||
}
|
||||
}
|
100
YogaKit/YogaKitSample/YogaKitSample/ExamplesViewController.swift
Normal file
100
YogaKit/YogaKitSample/YogaKitSample/ExamplesViewController.swift
Normal 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)
|
||||
}
|
||||
}
|
@@ -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
|
||||
}
|
||||
}
|
||||
|
@@ -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
|
@@ -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];
|
||||
}
|
||||
|
||||
|
||||
|
@@ -0,0 +1,54 @@
|
||||
/**
|
||||
* 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.configureLayout { (layout) in
|
||||
layout.isEnabled = true
|
||||
layout.width = containerSize.width
|
||||
layout.height = containerSize.height
|
||||
layout.alignItems = .center
|
||||
layout.justifyContent = .center
|
||||
}
|
||||
|
||||
let child1 = UIView()
|
||||
child1.backgroundColor = .blue
|
||||
child1.configureLayout { (layout) in
|
||||
layout.isEnabled = true
|
||||
layout.width = 100
|
||||
layout.height = 10
|
||||
layout.marginBottom = 25
|
||||
}
|
||||
root.addSubview(child1)
|
||||
|
||||
let child2 = UIView(frame: CGRect(x: 0, y: 0, width: 200, height: 200))
|
||||
child2.backgroundColor = .green
|
||||
child2.configureLayout { (layout) in
|
||||
layout.isEnabled = true
|
||||
layout.alignSelf = .flexEnd
|
||||
}
|
||||
root.addSubview(child2)
|
||||
|
||||
let child3 = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
|
||||
child3.backgroundColor = .yellow
|
||||
child3.configureLayout { (layout) in
|
||||
layout.isEnabled = true
|
||||
layout.alignSelf = .flexStart
|
||||
}
|
||||
root.addSubview(child3)
|
||||
|
||||
root.yoga.applyLayout(preservingOrigin: true)
|
||||
}
|
||||
}
|
@@ -0,0 +1,80 @@
|
||||
/**
|
||||
* 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.configureLayout { (layout) in
|
||||
layout.isEnabled = true
|
||||
layout.flexDirection = .column
|
||||
layout.justifyContent = .spaceAround
|
||||
}
|
||||
|
||||
contentView.backgroundColor = .clear
|
||||
contentView.layer.borderColor = UIColor.lightGray.cgColor
|
||||
contentView.layer.borderWidth = 1.0
|
||||
contentView.configureLayout { (layout) in
|
||||
layout.isEnabled = true
|
||||
layout.height = 300
|
||||
layout.width = self.view.bounds.size.width
|
||||
layout.flexDirection = .row
|
||||
layout.justifyContent = .center
|
||||
layout.paddingHorizontal = 25
|
||||
}
|
||||
self.view.addSubview(contentView)
|
||||
|
||||
let redView = UIView(frame: .zero)
|
||||
redView.backgroundColor = .red
|
||||
redView.configureLayout { (layout) in
|
||||
layout.isEnabled = true
|
||||
layout.flexGrow = 1
|
||||
layout.flexShrink = 1
|
||||
}
|
||||
contentView.addSubview(redView)
|
||||
|
||||
disappearingView.backgroundColor = .blue
|
||||
disappearingView.configureLayout { (layout) in
|
||||
layout.isEnabled = true
|
||||
layout.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.configureLayout { (layout) in
|
||||
layout.isEnabled = true
|
||||
layout.height = 300
|
||||
layout.width = 300
|
||||
layout.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
|
||||
}
|
||||
}
|
@@ -0,0 +1,49 @@
|
||||
/**
|
||||
* 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.configureLayout { (layout) in
|
||||
layout.isEnabled = true
|
||||
layout.flexDirection = .column
|
||||
layout.justifyContent = .flexEnd
|
||||
}
|
||||
|
||||
label.textAlignment = .center
|
||||
label.numberOfLines = 1
|
||||
label.yoga.isIncludedInLayout = false
|
||||
contentView.addSubview(label)
|
||||
|
||||
let border = UIView(frame: .zero)
|
||||
border.backgroundColor = .lightGray
|
||||
border.configureLayout { (layout) in
|
||||
layout.isEnabled = true
|
||||
layout.height = 0.5
|
||||
layout.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
|
||||
}
|
||||
}
|
@@ -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]));
|
||||
}
|
||||
}
|
32
android/BUCK
Normal file
32
android/BUCK
Normal file
@@ -0,0 +1,32 @@
|
||||
# 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",
|
||||
visibility = [
|
||||
"PUBLIC",
|
||||
],
|
||||
deps = [
|
||||
ANDROID_JAVA_TARGET,
|
||||
ANDROID_RES_TARGET,
|
||||
INFER_ANNOTATIONS_TARGET,
|
||||
JAVA_TARGET,
|
||||
PROGRUARD_ANNOTATIONS_TARGET,
|
||||
],
|
||||
)
|
||||
|
||||
android_resource(
|
||||
name = "res",
|
||||
package = "com.facebook.yoga.android",
|
||||
res = "src/main/res",
|
||||
visibility = [
|
||||
"PUBLIC",
|
||||
],
|
||||
)
|
21
android/README.md
Normal file
21
android/README.md
Normal file
@@ -0,0 +1,21 @@
|
||||
# YogaLayout [](https://facebook.github.io/yoga/docs/api/android/) [](https://facebook.github.io/yoga/docs/api/android/) [](https://bintray.com/facebook/maven/com.facebook.yoga.android%3Ayoga-layout/_latestVersion)
|
||||
|
||||
## Installation
|
||||
|
||||
YogaLayout is available via jcenter:
|
||||
|
||||
compile 'com.facebook.yoga.android:yoga-layout:1.2.0'
|
||||
|
||||
## Getting Started
|
||||
|
||||
Check out the docs [here](https://facebook.github.io/yoga/docs/api/android/).
|
||||
|
||||
We also have a sample project. To try it, clone the repo and run (with a device attached)
|
||||
|
||||
buck install -r android/sample
|
||||
|
||||
## Contributing
|
||||
|
||||
We welcome all pull-requests! At Facebook we sync the open source version of YogaKit daily, so we're always testing the latest changes.
|
||||
|
||||
See the CONTRIBUTING file for how to help out.
|
49
android/build.gradle
Normal file
49
android/build.gradle
Normal file
@@ -0,0 +1,49 @@
|
||||
apply plugin: 'com.jfrog.bintray'
|
||||
apply plugin: 'com.android.library'
|
||||
apply plugin: 'com.github.dcendents.android-maven'
|
||||
apply plugin: 'maven-publish'
|
||||
|
||||
version = '1.4.1'
|
||||
group = 'com.facebook.yoga.android'
|
||||
|
||||
android {
|
||||
compileSdkVersion rootProject.compileSdkVersion
|
||||
buildToolsVersion rootProject.buildToolsVersion
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion rootProject.minSdkVersion
|
||||
targetSdkVersion rootProject.targetSdkVersion
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
targetCompatibility rootProject.targetCompatibilityVersion
|
||||
sourceCompatibility rootProject.sourceCompatibilityVersion
|
||||
}
|
||||
}
|
||||
|
||||
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')
|
54
android/sample/AndroidManifest.xml
Normal file
54
android/sample/AndroidManifest.xml
Normal file
@@ -0,0 +1,54 @@
|
||||
<?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"
|
||||
/>
|
||||
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
|
||||
<application
|
||||
android:label="@string/app_name"
|
||||
android:icon="@drawable/ic_launcher"
|
||||
android:allowBackup="false"
|
||||
android:theme="@style/NoTitleBarWhiteBG"
|
||||
android:supportsRtl="true"
|
||||
>
|
||||
|
||||
<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>
|
||||
|
||||
<activity
|
||||
android:name=".BenchmarkActivity"
|
||||
android:exported="false"
|
||||
/>
|
||||
|
||||
</application>
|
||||
|
||||
</manifest>
|
35
android/sample/BUCK
Normal file
35
android/sample/BUCK
Normal file
@@ -0,0 +1,35 @@
|
||||
# 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",
|
||||
keystore = ":debug_keystore",
|
||||
manifest = "AndroidManifest.xml",
|
||||
deps = [
|
||||
ANDROID_SAMPLE_JAVA_TARGET,
|
||||
ANDROID_SAMPLE_RES_TARGET,
|
||||
],
|
||||
)
|
||||
|
||||
android_resource(
|
||||
name = "res",
|
||||
package = "com.facebook.samples.yoga",
|
||||
res = "res",
|
||||
visibility = [
|
||||
"PUBLIC",
|
||||
],
|
||||
deps = [
|
||||
ANDROID_RES_TARGET,
|
||||
],
|
||||
)
|
||||
|
||||
keystore(
|
||||
name = "debug_keystore",
|
||||
properties = "debug.keystore.properties",
|
||||
store = "debug.keystore",
|
||||
)
|
BIN
android/sample/debug.keystore
Normal file
BIN
android/sample/debug.keystore
Normal file
Binary file not shown.
3
android/sample/debug.keystore.properties
Normal file
3
android/sample/debug.keystore.properties
Normal file
@@ -0,0 +1,3 @@
|
||||
key.alias=androiddebugkey
|
||||
key.store.password=android
|
||||
key.alias.password=android
|
23
android/sample/java/com/facebook/samples/yoga/BUCK
Normal file
23
android/sample/java/com/facebook/samples/yoga/BUCK
Normal 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"]),
|
||||
visibility = [
|
||||
"PUBLIC",
|
||||
],
|
||||
deps = [
|
||||
ANDROID_JAVA_TARGET,
|
||||
ANDROID_SAMPLE_RES_TARGET,
|
||||
ANDROID_SUPPORT_TARGET,
|
||||
APPCOMPAT_TARGET,
|
||||
SOLOADER_TARGET,
|
||||
],
|
||||
)
|
@@ -0,0 +1,113 @@
|
||||
// Copyright 2004-present Facebook. All Rights Reserved.
|
||||
|
||||
package com.facebook.samples.yoga;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.app.ActionBarActivity;
|
||||
import android.support.v4.app.FragmentPagerAdapter;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentTransaction;
|
||||
import android.support.v4.view.ViewPager;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.Menu;
|
||||
import android.support.v7.app.ActionBar;
|
||||
|
||||
import com.facebook.samples.yoga.R;
|
||||
import com.facebook.yoga.android.YogaViewLayoutFactory;
|
||||
|
||||
public class BenchmarkActivity extends ActionBarActivity {
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
LayoutInflater.from(this).setFactory(YogaViewLayoutFactory.getInstance());
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
setContentView(R.layout.benchmark_select_layout);
|
||||
|
||||
ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
|
||||
viewPager.setAdapter(new PagerAdapter(getSupportFragmentManager()));
|
||||
|
||||
final ActionBar actionBar = getSupportActionBar();
|
||||
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
|
||||
|
||||
ActionBar.TabListener tabListener = new ActionBar.TabListener() {
|
||||
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
|
||||
ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
|
||||
viewPager.setCurrentItem(tab.getPosition());
|
||||
}
|
||||
|
||||
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) {
|
||||
}
|
||||
|
||||
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) {
|
||||
}
|
||||
};
|
||||
actionBar.addTab(
|
||||
actionBar.newTab()
|
||||
.setText("Inflate")
|
||||
.setTabListener(tabListener));
|
||||
actionBar.addTab(
|
||||
actionBar.newTab()
|
||||
.setText("Measure")
|
||||
.setTabListener(tabListener));
|
||||
actionBar.addTab(
|
||||
actionBar.newTab()
|
||||
.setText("Layout")
|
||||
.setTabListener(tabListener));
|
||||
|
||||
viewPager.setOnPageChangeListener(
|
||||
new ViewPager.SimpleOnPageChangeListener() {
|
||||
@Override
|
||||
public void onPageSelected(int position) {
|
||||
// When swiping between pages, select the
|
||||
// corresponding tab.
|
||||
actionBar.setSelectedNavigationItem(position);
|
||||
}
|
||||
});
|
||||
|
||||
viewPager.setOffscreenPageLimit(3);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
MenuInflater inflater = getMenuInflater();
|
||||
inflater.inflate(R.menu.action_bar_benchmark, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
// There is only one option
|
||||
Intent intent = new Intent(this, MainActivity.class);
|
||||
startActivity(intent);
|
||||
this.finish();
|
||||
return true;
|
||||
}
|
||||
|
||||
public static class PagerAdapter extends FragmentPagerAdapter {
|
||||
public PagerAdapter(FragmentManager fm) {
|
||||
super(fm);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Fragment getItem(int i) {
|
||||
switch (i) {
|
||||
case 0:
|
||||
return new BenchmarkInflate();
|
||||
case 1:
|
||||
return new BenchmarkMeasure();
|
||||
default:
|
||||
return new BenchmarkLayout();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,193 @@
|
||||
// Copyright 2004-present Facebook. All Rights Reserved.
|
||||
|
||||
package com.facebook.samples.yoga;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.PrintWriter;
|
||||
import java.lang.Math;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.text.DateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
import android.os.Environment;
|
||||
|
||||
import static java.util.Collections.sort;
|
||||
|
||||
public class BenchmarkAggregator {
|
||||
|
||||
private final int GRAPH_WIDTH = 30;
|
||||
private final int GRAPH_HEIGHT = 6;
|
||||
|
||||
private List<Long> times;
|
||||
private boolean tracing;
|
||||
private long lastTraceStart;
|
||||
|
||||
private boolean statsFresh;
|
||||
private long mean;
|
||||
private long variance;
|
||||
private long stddev;
|
||||
private long min;
|
||||
private long max;
|
||||
private long p10;
|
||||
private long p50;
|
||||
private long p90;
|
||||
|
||||
private String name;
|
||||
|
||||
public BenchmarkAggregator(String name) {
|
||||
times = new ArrayList<>();
|
||||
tracing = false;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public void startTrace() {
|
||||
if (tracing) {
|
||||
throw new RuntimeException("Cannot start trace while running previous one");
|
||||
}
|
||||
tracing = true;
|
||||
lastTraceStart = System.nanoTime();
|
||||
}
|
||||
|
||||
public void endTrace() {
|
||||
if (!tracing) {
|
||||
throw new RuntimeException("Cannot stop trace if none are running!");
|
||||
}
|
||||
times.add(System.nanoTime() - lastTraceStart);
|
||||
tracing = false;
|
||||
statsFresh = false;
|
||||
}
|
||||
|
||||
private void computeStats() {
|
||||
if (statsFresh) {
|
||||
return;
|
||||
}
|
||||
|
||||
sort(times);
|
||||
|
||||
min = Long.MAX_VALUE;
|
||||
max = -1;
|
||||
mean = 0;
|
||||
for (long f: times) {
|
||||
mean += f;
|
||||
if (f < min) {
|
||||
min = f;
|
||||
}
|
||||
if (f > max) {
|
||||
max = f;
|
||||
}
|
||||
}
|
||||
mean /= times.size();
|
||||
|
||||
variance = 0;
|
||||
for (long f: times) {
|
||||
variance += (f-mean)*(f-mean);
|
||||
}
|
||||
variance /= times.size();
|
||||
stddev = (long) Math.sqrt((double) variance);
|
||||
|
||||
p10 = times.get(times.size()*10/100);
|
||||
p50 = times.get(times.size()*50/100);
|
||||
p90 = times.get(times.size()*90/100);
|
||||
|
||||
statsFresh = true;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
computeStats();
|
||||
return String.format(
|
||||
"%s:\n" +
|
||||
"| %d samples\n" +
|
||||
"| Mean %.3f\u00B1%.3fms\n" + // plusminus
|
||||
"| Min %.3fms ; Max %.3fms\n" +
|
||||
"| p10 %.3fms ; p50 %.3fms ; p90 %.3fms\n" +
|
||||
"%s",
|
||||
name,
|
||||
times.size(),
|
||||
mean/10e6,
|
||||
stddev/10e6,
|
||||
min/10e6,
|
||||
max/10e6,
|
||||
p10/10e6,
|
||||
p50/10e6,
|
||||
p90/10e6,
|
||||
makeGraph());
|
||||
}
|
||||
|
||||
private String makeGraph() {
|
||||
char canvas[][] = new char[GRAPH_HEIGHT][GRAPH_WIDTH];
|
||||
for (int i = 0; i < GRAPH_HEIGHT; i++)
|
||||
for (int j = 0; j < GRAPH_WIDTH; j++)
|
||||
canvas[i][j] = ' ';
|
||||
|
||||
long bucketSize = (p90 - p10) / GRAPH_WIDTH+1;
|
||||
int bucketCount[] = new int[GRAPH_WIDTH];
|
||||
for (long time : times) {
|
||||
if (time<p90 && time>p10) {
|
||||
bucketCount[(int) ((time - p10) / bucketSize)]++;
|
||||
}
|
||||
}
|
||||
|
||||
int maxBucket = 0;
|
||||
for (int i = 0; i < GRAPH_WIDTH; i++)
|
||||
if (bucketCount[i] > maxBucket) {
|
||||
maxBucket = bucketCount[i];
|
||||
}
|
||||
|
||||
for (int i = 0; i < GRAPH_HEIGHT; i++)
|
||||
for (int j = 0; j < GRAPH_WIDTH; j++)
|
||||
if (i < bucketCount[j] * GRAPH_HEIGHT / maxBucket) {
|
||||
canvas[i][j] = 'Z';
|
||||
}
|
||||
|
||||
String graph = new String();
|
||||
for (int i = 0; i < GRAPH_HEIGHT; i++)
|
||||
{
|
||||
int percentage = 100 * (GRAPH_HEIGHT - i - 1) * maxBucket / (times.size() * GRAPH_HEIGHT);
|
||||
graph += String.format("| %2d%% ", percentage);
|
||||
for (int j = 0; j < GRAPH_WIDTH; j++)
|
||||
graph += canvas[GRAPH_HEIGHT-1-i][j];
|
||||
graph += '\n';
|
||||
}
|
||||
|
||||
graph += "| p10";
|
||||
for (int i = 0; i < GRAPH_WIDTH-6; i++)
|
||||
graph += " ";
|
||||
graph += "p90\n";
|
||||
return graph;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dumps the collected times to a file on the device. This allows us to grab the raw data
|
||||
* and perform more in-depth analysis.
|
||||
*/
|
||||
public void dump(Context context) {
|
||||
String state = Environment.getExternalStorageState();
|
||||
if (!Environment.MEDIA_MOUNTED.equals(state)) {
|
||||
Log.e("YogaLayoutBenchmark","No external file storage");
|
||||
return;
|
||||
}
|
||||
|
||||
SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
|
||||
String filename = format.format(new Date()) + "_" + name.replace(' ','_');
|
||||
File file = new File(context.getExternalFilesDir(
|
||||
Environment.DIRECTORY_DOCUMENTS), filename);
|
||||
|
||||
try {
|
||||
PrintWriter printWriter = new PrintWriter(file);
|
||||
for (long l : times) {
|
||||
printWriter.println(l);
|
||||
}
|
||||
printWriter.close();
|
||||
|
||||
Log.i("YogaLayoutBenchmark","Benchmark data saved in "+file.getPath());
|
||||
} catch (java.io.IOException e) {
|
||||
Log.e("YogaLayoutBenchmark", "Could not save benchmark data", e);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,110 @@
|
||||
// Copyright 2004-present Facebook. All Rights Reserved.
|
||||
|
||||
package com.facebook.samples.yoga;
|
||||
|
||||
|
||||
import java.util.Random;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewParent;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.TextView;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.AdapterView;
|
||||
|
||||
import com.facebook.samples.yoga.R;
|
||||
import com.facebook.yoga.android.YogaLayout;
|
||||
|
||||
public class BenchmarkFragment extends Fragment implements AdapterView.OnItemSelectedListener {
|
||||
private LayoutInflater mInflater;
|
||||
|
||||
protected com.facebook.yoga.android.YogaLayout rootLayout;
|
||||
protected int yogaLayout;
|
||||
protected int linearLayout;
|
||||
|
||||
static final Random random = new Random();
|
||||
|
||||
static void randomizeText(View root) {
|
||||
if (root instanceof TextView) {
|
||||
((TextView) root).setText("" + random.nextInt(1000));
|
||||
((TextView) root).setTextSize(10 + random.nextInt(20));
|
||||
ViewParent parent = root.getParent();
|
||||
if (parent instanceof YogaLayout) {
|
||||
((YogaLayout) parent).invalidate(root);
|
||||
}
|
||||
} else if (root instanceof ViewGroup) {
|
||||
for (int i = 0; i < ((ViewGroup) root).getChildCount(); i++) {
|
||||
randomizeText(((ViewGroup) root).getChildAt(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public BenchmarkFragment() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(
|
||||
LayoutInflater inflater,
|
||||
ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
mInflater = inflater;
|
||||
|
||||
rootLayout = (YogaLayout) inflater.inflate(
|
||||
R.layout.benchmark_fragment,
|
||||
container,
|
||||
false);
|
||||
|
||||
Spinner benchmarkSelect = (Spinner) rootLayout.findViewById(R.id.benchmarkSelect);
|
||||
String[] items = new String[]{"Basic", "Typical", "Nested"};
|
||||
ArrayAdapter<String> adapter = new ArrayAdapter<>(getActivity(), android.R.layout.simple_spinner_dropdown_item, items);
|
||||
benchmarkSelect.setAdapter(adapter);
|
||||
benchmarkSelect.setOnItemSelectedListener(this);
|
||||
return rootLayout;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
|
||||
switch (pos) {
|
||||
case 0:
|
||||
yogaLayout = R.layout.benchmark_layout_1;
|
||||
linearLayout = R.layout.benchmark_layout_1_linear;
|
||||
break;
|
||||
case 1:
|
||||
yogaLayout = R.layout.benchmark_layout_2;
|
||||
linearLayout = R.layout.benchmark_layout_2_linear;
|
||||
break;
|
||||
case 2:
|
||||
default:
|
||||
yogaLayout = R.layout.benchmark_layout_3;
|
||||
linearLayout = R.layout.benchmark_layout_3_linear;
|
||||
break;
|
||||
}
|
||||
updatePreview();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> parent) {
|
||||
yogaLayout = R.layout.benchmark_layout_1;
|
||||
linearLayout = R.layout.benchmark_layout_1_linear;
|
||||
updatePreview();
|
||||
}
|
||||
|
||||
private void updatePreview() {
|
||||
LinearLayout previewLayout = (LinearLayout) rootLayout.findViewById(R.id.preview);
|
||||
View v = mInflater.inflate(yogaLayout, rootLayout, false);
|
||||
v.setLayoutParams(new LinearLayout.LayoutParams(
|
||||
LinearLayout.LayoutParams.MATCH_PARENT,
|
||||
LinearLayout.LayoutParams.MATCH_PARENT));
|
||||
previewLayout.removeAllViews();
|
||||
previewLayout.addView(v);
|
||||
}
|
||||
}
|
@@ -0,0 +1,65 @@
|
||||
// Copyright 2004-present Facebook. All Rights Reserved.
|
||||
|
||||
package com.facebook.samples.yoga;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Button;
|
||||
import android.view.ViewGroup;
|
||||
import android.util.Log;
|
||||
import com.facebook.samples.yoga.R;
|
||||
|
||||
public class BenchmarkInflate extends BenchmarkFragment {
|
||||
|
||||
@Override
|
||||
public View onCreateView(
|
||||
LayoutInflater inflater,
|
||||
ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
super.onCreateView(inflater, container, savedInstanceState);
|
||||
|
||||
Button b = (Button) rootLayout.findViewById(R.id.btn);
|
||||
b.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
startBenchmark();
|
||||
}
|
||||
});
|
||||
|
||||
return rootLayout;
|
||||
}
|
||||
|
||||
protected void startBenchmark() {
|
||||
LayoutInflater inflater = LayoutInflater.from(getActivity());
|
||||
TextView textView = (TextView) rootLayout.findViewById(R.id.text);
|
||||
|
||||
final int ITERATIONS = 500;
|
||||
|
||||
inflater.inflate(yogaLayout, null);
|
||||
inflater.inflate(linearLayout, null);
|
||||
|
||||
BenchmarkAggregator yogaInflationAggregator = new BenchmarkAggregator("Yoga Inflate");
|
||||
BenchmarkAggregator linearInflationAggregator = new BenchmarkAggregator("Linear Inflate");
|
||||
for (int i = 0; i < ITERATIONS; i++) {
|
||||
yogaInflationAggregator.startTrace();
|
||||
inflater.inflate(yogaLayout, null);
|
||||
yogaInflationAggregator.endTrace();
|
||||
linearInflationAggregator.startTrace();
|
||||
inflater.inflate(linearLayout, null);
|
||||
linearInflationAggregator.endTrace();
|
||||
}
|
||||
|
||||
textView.setText(
|
||||
yogaInflationAggregator.toString()+
|
||||
"\n"+
|
||||
linearInflationAggregator.toString());
|
||||
Log.i(
|
||||
"YogaLayoutBenchmark",
|
||||
yogaInflationAggregator.toString()+
|
||||
"\n"+
|
||||
linearInflationAggregator.toString());
|
||||
rootLayout.invalidate();
|
||||
}
|
||||
}
|
@@ -0,0 +1,74 @@
|
||||
// Copyright 2004-present Facebook. All Rights Reserved.
|
||||
|
||||
package com.facebook.samples.yoga;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
import com.facebook.samples.yoga.R;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class BenchmarkLayout extends BenchmarkFragment {
|
||||
|
||||
@Override
|
||||
public View onCreateView(
|
||||
LayoutInflater inflater,
|
||||
ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
super.onCreateView(inflater, container, savedInstanceState);
|
||||
|
||||
Button b = (Button) rootLayout.findViewById(R.id.btn);
|
||||
b.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
startBenchmark();
|
||||
}
|
||||
});
|
||||
|
||||
return rootLayout;
|
||||
}
|
||||
|
||||
protected void startBenchmark() {
|
||||
LayoutInflater inflater = LayoutInflater.from(getActivity());
|
||||
TextView textView = (TextView) rootLayout.findViewById(R.id.text);
|
||||
Random random = new Random();
|
||||
|
||||
final int ITERATIONS = 500;
|
||||
|
||||
BenchmarkAggregator yogaInflationAggregator = new BenchmarkAggregator("Yoga Layout");
|
||||
BenchmarkAggregator linearInflationAggregator = new BenchmarkAggregator("Linear Layout");
|
||||
View yogaView = inflater.inflate(yogaLayout, null);
|
||||
View linearView = inflater.inflate(linearLayout, null);
|
||||
for (int i = 0; i < ITERATIONS; i++) {
|
||||
randomizeText(yogaView);
|
||||
randomizeText(linearView);
|
||||
yogaView.measure(
|
||||
View.MeasureSpec.makeMeasureSpec(1000, View.MeasureSpec.EXACTLY),
|
||||
View.MeasureSpec.makeMeasureSpec(1000, View.MeasureSpec.EXACTLY));
|
||||
linearView.measure(
|
||||
View.MeasureSpec.makeMeasureSpec(1000, View.MeasureSpec.EXACTLY),
|
||||
View.MeasureSpec.makeMeasureSpec(1000, View.MeasureSpec.EXACTLY));
|
||||
yogaInflationAggregator.startTrace();
|
||||
yogaView.layout(0, 0, yogaView.getMeasuredWidth(), yogaView.getMeasuredHeight());
|
||||
yogaInflationAggregator.endTrace();
|
||||
linearInflationAggregator.startTrace();
|
||||
linearView.layout(0, 0, linearView.getMeasuredWidth(), linearView.getMeasuredHeight());
|
||||
linearInflationAggregator.endTrace();
|
||||
}
|
||||
|
||||
textView.setText(
|
||||
yogaInflationAggregator.toString()+
|
||||
"\n"+
|
||||
linearInflationAggregator.toString());
|
||||
Log.i(
|
||||
"YogaLayoutBenchmark",
|
||||
yogaInflationAggregator.toString()+
|
||||
"\n"+
|
||||
linearInflationAggregator.toString());
|
||||
}
|
||||
}
|
@@ -0,0 +1,75 @@
|
||||
// Copyright 2004-present Facebook. All Rights Reserved.
|
||||
|
||||
package com.facebook.samples.yoga;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
import com.facebook.samples.yoga.R;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class BenchmarkMeasure extends BenchmarkFragment {
|
||||
|
||||
@Override
|
||||
public View onCreateView(
|
||||
LayoutInflater inflater,
|
||||
ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
super.onCreateView(inflater, container, savedInstanceState);
|
||||
|
||||
Button b = (Button) rootLayout.findViewById(R.id.btn);
|
||||
b.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
startBenchmark();
|
||||
}
|
||||
});
|
||||
|
||||
return rootLayout;
|
||||
}
|
||||
|
||||
protected void startBenchmark() {
|
||||
LayoutInflater inflater = LayoutInflater.from(getActivity());
|
||||
TextView textView = (TextView) rootLayout.findViewById(R.id.text);
|
||||
Random random = new Random();
|
||||
|
||||
final int ITERATIONS = 500;
|
||||
|
||||
BenchmarkAggregator yogaMeasureAggregator = new BenchmarkAggregator("Yoga Measure");
|
||||
BenchmarkAggregator linearMeasureAggregator = new BenchmarkAggregator("Linear Measure");
|
||||
View yogaView = inflater.inflate(yogaLayout, null);
|
||||
View linearView = inflater.inflate(linearLayout, null);
|
||||
for (int i = 0; i < ITERATIONS; i++) {
|
||||
randomizeText(yogaView);
|
||||
randomizeText(linearView);
|
||||
yogaMeasureAggregator.startTrace();
|
||||
yogaView.measure(
|
||||
View.MeasureSpec.makeMeasureSpec(1000, View.MeasureSpec.EXACTLY),
|
||||
View.MeasureSpec.makeMeasureSpec(1000, View.MeasureSpec.EXACTLY));
|
||||
yogaMeasureAggregator.endTrace();
|
||||
linearMeasureAggregator.startTrace();
|
||||
linearView.measure(
|
||||
View.MeasureSpec.makeMeasureSpec(1000, View.MeasureSpec.EXACTLY),
|
||||
View.MeasureSpec.makeMeasureSpec(1000, View.MeasureSpec.EXACTLY));
|
||||
linearMeasureAggregator.endTrace();
|
||||
}
|
||||
|
||||
textView.setText(
|
||||
yogaMeasureAggregator.toString()+
|
||||
"\n"+
|
||||
linearMeasureAggregator.toString());
|
||||
Log.i(
|
||||
"YogaLayoutBenchmark",
|
||||
yogaMeasureAggregator.toString()+
|
||||
"\n"+
|
||||
linearMeasureAggregator.toString());
|
||||
|
||||
yogaMeasureAggregator.dump(getActivity());
|
||||
linearMeasureAggregator.dump(getActivity());
|
||||
}
|
||||
}
|
@@ -0,0 +1,54 @@
|
||||
/**
|
||||
* 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.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.app.ActionBarActivity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.Menu;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
MenuInflater inflater = getMenuInflater();
|
||||
inflater.inflate(R.menu.action_bar_home, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
// There is only one option
|
||||
Intent intent = new Intent(this, BenchmarkActivity.class);
|
||||
startActivity(intent);
|
||||
this.finish();
|
||||
return true;
|
||||
}
|
||||
}
|
17
android/sample/res/drawable/action_bar_background.xml
Normal file
17
android/sample/res/drawable/action_bar_background.xml
Normal 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>
|
BIN
android/sample/res/drawable/ic_launcher.png
Normal file
BIN
android/sample/res/drawable/ic_launcher.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 28 KiB |
34
android/sample/res/drawable/sample_children_background.xml
Normal file
34
android/sample/res/drawable/sample_children_background.xml
Normal 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>
|
50
android/sample/res/layout/benchmark_fragment.xml
Normal file
50
android/sample/res/layout/benchmark_fragment.xml
Normal file
@@ -0,0 +1,50 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<YogaLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:yoga="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/rt"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
yoga:yg_flexDirection="column"
|
||||
>
|
||||
<VirtualYogaLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
yoga:yg_flexDirection="row"
|
||||
yoga:yg_height="50dp"
|
||||
>
|
||||
<Button
|
||||
android:id="@+id/btn"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:text="Run benchmark"
|
||||
yoga:yg_flex="1"
|
||||
/>
|
||||
<Spinner
|
||||
android:id="@+id/benchmarkSelect"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:spinnerMode="dropdown"
|
||||
/>
|
||||
</VirtualYogaLayout>
|
||||
<TextView
|
||||
android:id="@+id/text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:textSize="10sp"
|
||||
android:fontFamily="monospace"
|
||||
yoga:yg_flex="1"
|
||||
/>
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="2dp"
|
||||
android:background="@color/yoga_grey"
|
||||
/>
|
||||
<LinearLayout
|
||||
android:id="@+id/preview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="60dp"
|
||||
android:orientation="horizontal"
|
||||
/>
|
||||
</YogaLayout>
|
30
android/sample/res/layout/benchmark_layout_1.xml
Normal file
30
android/sample/res/layout/benchmark_layout_1.xml
Normal file
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<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="60dp"
|
||||
yoga:yg_flexDirection="row"
|
||||
yoga:yg_alignItems="center"
|
||||
>
|
||||
<View
|
||||
android:layout_width="50dp"
|
||||
android:layout_height="50dp"
|
||||
android:background="@color/yoga_blue"
|
||||
yoga:yg_flex="0"
|
||||
yoga:yg_marginAll="5dp"
|
||||
/>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/child_1_text"
|
||||
yoga:yg_flex="0"
|
||||
/>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/child_2_text"
|
||||
yoga:yg_flex="1"
|
||||
yoga:yg_marginHorizontal="5dp"
|
||||
/>
|
||||
</YogaLayout>
|
28
android/sample/res/layout/benchmark_layout_1_linear.xml
Normal file
28
android/sample/res/layout/benchmark_layout_1_linear.xml
Normal file
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center"
|
||||
>
|
||||
<ImageView
|
||||
android:layout_width="50dp"
|
||||
android:layout_height="50dp"
|
||||
android:layout_margin="5dp"
|
||||
android:src="@drawable/ic_launcher"
|
||||
/>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/child_1_text"
|
||||
/>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:layout_marginLeft="5dp"
|
||||
android:layout_marginRight="5dp"
|
||||
android:text="@string/child_2_text"
|
||||
/>
|
||||
</LinearLayout>
|
104
android/sample/res/layout/benchmark_layout_2.xml
Normal file
104
android/sample/res/layout/benchmark_layout_2.xml
Normal file
@@ -0,0 +1,104 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<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="60dp"
|
||||
yoga:yg_flexDirection="column"
|
||||
yoga:yg_alignItems="stretch"
|
||||
>
|
||||
<View
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/yoga_blue"
|
||||
yoga:yg_flex="1"
|
||||
/>
|
||||
<VirtualYogaLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
yoga:height="40dp"
|
||||
yoga:yg_flexDirection="row"
|
||||
yoga:yg_alignItems="stretch"
|
||||
>
|
||||
<View
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/yoga_blue"
|
||||
yoga:yg_marginAll="10dp"
|
||||
yoga:yg_aspectRatio="1"
|
||||
/>
|
||||
<VirtualYogaLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
yoga:height="40dp"
|
||||
yoga:yg_flexDirection="column"
|
||||
yoga:yg_alignItems="stretch"
|
||||
yoga:yg_flex="1"
|
||||
yoga:yg_justifyContent="space_around"
|
||||
>
|
||||
<VirtualYogaLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
yoga:height="8dp"
|
||||
yoga:yg_flexDirection="row"
|
||||
yoga:yg_alignItems="stretch"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/child_1_text"
|
||||
android:textSize="5sp"
|
||||
yoga:yg_flex="1"
|
||||
/>
|
||||
<View
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/yoga_blue"
|
||||
yoga:yg_aspectRatio="1"
|
||||
/>
|
||||
</VirtualYogaLayout>
|
||||
<VirtualYogaLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
yoga:height="8dp"
|
||||
yoga:yg_flexDirection="row"
|
||||
yoga:yg_alignItems="stretch"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/child_1_text"
|
||||
android:textSize="5sp"
|
||||
yoga:yg_flex="1"
|
||||
/>
|
||||
<View
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/yoga_blue"
|
||||
yoga:yg_aspectRatio="1"
|
||||
/>
|
||||
</VirtualYogaLayout>
|
||||
<VirtualYogaLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
yoga:height="8dp"
|
||||
yoga:yg_flexDirection="row"
|
||||
yoga:yg_alignItems="stretch"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/child_1_text"
|
||||
android:textSize="5sp"
|
||||
yoga:yg_flex="1"
|
||||
/>
|
||||
<View
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/yoga_blue"
|
||||
yoga:yg_aspectRatio="1"
|
||||
/>
|
||||
</VirtualYogaLayout>
|
||||
</VirtualYogaLayout>
|
||||
</VirtualYogaLayout>
|
||||
</YogaLayout>
|
96
android/sample/res/layout/benchmark_layout_2_linear.xml
Normal file
96
android/sample/res/layout/benchmark_layout_2_linear.xml
Normal file
@@ -0,0 +1,96 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<LinearLayout
|
||||
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="60dp"
|
||||
android:orientation="vertical"
|
||||
>
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:src="@drawable/ic_launcher"
|
||||
android:background="@color/yoga_blue"
|
||||
android:layout_weight="1"
|
||||
/>
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="40dp"
|
||||
android:orientation="horizontal"
|
||||
>
|
||||
<View
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
android:src="@drawable/ic_launcher"
|
||||
android:background="@color/yoga_blue"
|
||||
android:layout_margin="10dp"
|
||||
/>
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="40dp"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical"
|
||||
>
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="8dp"
|
||||
android:orientation="horizontal"
|
||||
android:layout_marginTop="4dp"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/child_1_text"
|
||||
android:textSize="5sp"
|
||||
android:layout_weight="1"
|
||||
/>
|
||||
<View
|
||||
android:layout_width="8dp"
|
||||
android:layout_height="8dp"
|
||||
android:src="@drawable/ic_launcher"
|
||||
android:background="@color/yoga_blue"
|
||||
/>
|
||||
</LinearLayout>
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="8dp"
|
||||
android:orientation="horizontal"
|
||||
android:layout_marginTop="4dp"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/child_1_text"
|
||||
android:textSize="5sp"
|
||||
android:layout_weight="1"
|
||||
/>
|
||||
<View
|
||||
android:layout_width="8dp"
|
||||
android:layout_height="8dp"
|
||||
android:src="@drawable/ic_launcher"
|
||||
android:background="@color/yoga_blue"
|
||||
/>
|
||||
</LinearLayout>
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="8dp"
|
||||
android:orientation="horizontal"
|
||||
android:layout_marginTop="4dp"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/child_1_text"
|
||||
android:textSize="5sp"
|
||||
android:layout_weight="1"
|
||||
/>
|
||||
<View
|
||||
android:layout_width="8dp"
|
||||
android:layout_height="8dp"
|
||||
android:src="@drawable/ic_launcher"
|
||||
android:background="@color/yoga_blue"
|
||||
/>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
206
android/sample/res/layout/benchmark_layout_3.xml
Normal file
206
android/sample/res/layout/benchmark_layout_3.xml
Normal file
@@ -0,0 +1,206 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<YogaLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:yoga="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
yoga:yg_alignItems="center"
|
||||
yoga:yg_flexDirection="row"
|
||||
yoga:yg_justifyContent="center"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/yoga_blue"
|
||||
yoga:yg_marginLeft="10dp"
|
||||
/>
|
||||
<VirtualYogaLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
yoga:yg_flexDirection="column"
|
||||
yoga:yg_flex="1"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/yoga_grey"
|
||||
yoga:yg_marginLeft="10dp"
|
||||
/>
|
||||
<VirtualYogaLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
yoga:yg_flexDirection="row"
|
||||
yoga:yg_flex="1"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/yoga_grey"
|
||||
yoga:yg_marginLeft="10dp"
|
||||
/>
|
||||
<VirtualYogaLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
yoga:yg_flexDirection="row"
|
||||
yoga:yg_flex="1"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/yoga_blue"
|
||||
yoga:yg_marginLeft="10dp"
|
||||
/>
|
||||
<VirtualYogaLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
yoga:yg_flexDirection="row"
|
||||
yoga:yg_flex="1"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/yoga_grey"
|
||||
yoga:yg_marginLeft="10dp"
|
||||
/>
|
||||
<VirtualYogaLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
yoga:yg_flexDirection="row"
|
||||
yoga:yg_flex="1"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/yoga_grey"
|
||||
yoga:yg_marginLeft="10dp"
|
||||
/>
|
||||
<VirtualYogaLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
yoga:yg_flexDirection="column"
|
||||
yoga:yg_flex="1"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/yoga_blue"
|
||||
yoga:yg_marginLeft="10dp"
|
||||
/>
|
||||
<VirtualYogaLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
yoga:yg_flexDirection="row"
|
||||
yoga:yg_flex="1"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/yoga_grey"
|
||||
yoga:yg_marginLeft="10dp"
|
||||
/>
|
||||
<VirtualYogaLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
yoga:yg_flexDirection="row"
|
||||
yoga:yg_flex="1"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/yoga_grey"
|
||||
yoga:yg_marginLeft="10dp"
|
||||
/>
|
||||
<VirtualYogaLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
yoga:yg_flexDirection="row"
|
||||
yoga:yg_flex="1"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/yoga_blue"
|
||||
yoga:yg_marginLeft="10dp"
|
||||
/>
|
||||
<VirtualYogaLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
yoga:yg_flexDirection="row"
|
||||
yoga:yg_flex="1"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/yoga_grey"
|
||||
yoga:yg_marginLeft="10dp"
|
||||
/>
|
||||
<VirtualYogaLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
yoga:yg_flexDirection="column"
|
||||
yoga:yg_flex="1"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/yoga_grey"
|
||||
yoga:yg_marginLeft="10dp"
|
||||
/>
|
||||
<VirtualYogaLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
yoga:yg_flexDirection="row"
|
||||
yoga:yg_flex="1"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/yoga_blue"
|
||||
yoga:yg_marginLeft="10dp"
|
||||
/>
|
||||
<VirtualYogaLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
yoga:yg_flexDirection="row"
|
||||
yoga:yg_flex="1"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/yoga_grey"
|
||||
yoga:yg_marginLeft="10dp"
|
||||
/>
|
||||
<VirtualYogaLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
yoga:yg_flexDirection="row"
|
||||
yoga:yg_flex="1"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/yoga_grey"
|
||||
yoga:yg_marginLeft="10dp"
|
||||
/>
|
||||
<VirtualYogaLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
yoga:yg_flexDirection="row"
|
||||
yoga:yg_flex="1"
|
||||
>
|
||||
</VirtualYogaLayout>
|
||||
</VirtualYogaLayout>
|
||||
</VirtualYogaLayout>
|
||||
</VirtualYogaLayout>
|
||||
</VirtualYogaLayout>
|
||||
</VirtualYogaLayout>
|
||||
</VirtualYogaLayout>
|
||||
</VirtualYogaLayout>
|
||||
</VirtualYogaLayout>
|
||||
</VirtualYogaLayout>
|
||||
</VirtualYogaLayout>
|
||||
</VirtualYogaLayout>
|
||||
</VirtualYogaLayout>
|
||||
</VirtualYogaLayout>
|
||||
</VirtualYogaLayout>
|
||||
</YogaLayout>
|
204
android/sample/res/layout/benchmark_layout_3_linear.xml
Normal file
204
android/sample/res/layout/benchmark_layout_3_linear.xml
Normal file
@@ -0,0 +1,204 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:orientation="horizontal"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:background="@color/yoga_blue"
|
||||
/>
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:background="@color/yoga_grey"
|
||||
/>
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:orientation="horizontal"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:background="@color/yoga_grey"
|
||||
/>
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:orientation="horizontal"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:background="@color/yoga_blue"
|
||||
/>
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:orientation="horizontal"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:background="@color/yoga_grey"
|
||||
/>
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:orientation="horizontal"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:background="@color/yoga_grey"
|
||||
/>
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:background="@color/yoga_blue"
|
||||
/>
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:orientation="horizontal"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:background="@color/yoga_grey"
|
||||
/>
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:orientation="horizontal"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:background="@color/yoga_grey"
|
||||
/>
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:orientation="horizontal"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:background="@color/yoga_blue"
|
||||
/>
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:orientation="horizontal"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:background="@color/yoga_grey"
|
||||
/>
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:background="@color/yoga_grey"
|
||||
/>
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:orientation="horizontal"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:background="@color/yoga_blue"
|
||||
/>
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:orientation="horizontal"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:background="@color/yoga_grey"
|
||||
/>
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:orientation="horizontal"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:background="@color/yoga_grey"
|
||||
/>
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:orientation="horizontal"
|
||||
>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
7
android/sample/res/layout/benchmark_select_layout.xml
Normal file
7
android/sample/res/layout/benchmark_select_layout.xml
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<android.support.v4.view.ViewPager
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/viewpager"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
/>
|
137
android/sample/res/layout/main_layout.xml
Normal file
137
android/sample/res/layout/main_layout.xml
Normal 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/com.facebook.samples.yoga"
|
||||
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:yg_marginHorizontal="10dp"
|
||||
yoga:yg_marginTop="5dp"
|
||||
yoga:yg_flexDirection="row"
|
||||
yoga:yg_alignItems="center"
|
||||
>
|
||||
<ImageView
|
||||
android:layout_width="50dp"
|
||||
android:layout_height="50dp"
|
||||
android:src="@drawable/ic_launcher"
|
||||
yoga:yg_flex="0"
|
||||
/>
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/child_1_text"
|
||||
android:textColor="@color/children_text"
|
||||
yoga:yg_flex="1"
|
||||
yoga:yg_marginStart="8dp"
|
||||
/>
|
||||
</YogaLayout>
|
||||
<YogaLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/sample_children_background"
|
||||
yoga:yg_marginHorizontal="10dp"
|
||||
yoga:yg_marginTop="5dp"
|
||||
yoga:yg_flexDirection="row"
|
||||
yoga:yg_alignItems="center"
|
||||
>
|
||||
<ImageView
|
||||
android:layout_width="50dp"
|
||||
android:layout_height="50dp"
|
||||
android:src="@drawable/ic_launcher"
|
||||
yoga:yg_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:yg_flex="1"
|
||||
yoga:yg_marginStart="8dp"
|
||||
/>
|
||||
</YogaLayout>
|
||||
<YogaLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/sample_children_background"
|
||||
yoga:yg_marginHorizontal="10dp"
|
||||
yoga:yg_marginTop="5dp"
|
||||
yoga:yg_flexDirection="row"
|
||||
yoga:yg_alignItems="center"
|
||||
>
|
||||
<ImageView
|
||||
android:layout_width="50dp"
|
||||
android:layout_height="50dp"
|
||||
android:src="@drawable/ic_launcher"
|
||||
yoga:yg_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:yg_flex="1"
|
||||
yoga:yg_marginStart="8dp"
|
||||
/>
|
||||
</YogaLayout>
|
||||
<YogaLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/sample_children_background"
|
||||
yoga:yg_marginHorizontal="10dp"
|
||||
yoga:yg_marginTop="5dp"
|
||||
yoga:yg_flexDirection="row"
|
||||
yoga:yg_alignItems="center"
|
||||
>
|
||||
<ImageView
|
||||
android:layout_width="50dp"
|
||||
android:layout_height="50dp"
|
||||
android:src="@drawable/ic_launcher"
|
||||
yoga:yg_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:yg_flex="1"
|
||||
yoga:yg_marginStart="8dp"
|
||||
/>
|
||||
</YogaLayout>
|
||||
<YogaLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/sample_children_background"
|
||||
yoga:yg_marginHorizontal="10dp"
|
||||
yoga:yg_marginTop="5dp"
|
||||
yoga:yg_flexDirection="row"
|
||||
yoga:yg_alignItems="center"
|
||||
>
|
||||
<ImageView
|
||||
android:layout_width="50dp"
|
||||
android:layout_height="50dp"
|
||||
android:src="@drawable/ic_launcher"
|
||||
yoga:yg_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:yg_flex="1"
|
||||
yoga:yg_marginStart="10dp"
|
||||
/>
|
||||
</YogaLayout>
|
||||
</YogaLayout>
|
19
android/sample/res/menu/action_bar_benchmark.xml
Normal file
19
android/sample/res/menu/action_bar_benchmark.xml
Normal file
@@ -0,0 +1,19 @@
|
||||
<?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.
|
||||
-->
|
||||
|
||||
<menu
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
>
|
||||
<item
|
||||
android:id="@+id/action_home"
|
||||
android:title="Home"
|
||||
android:showAsAction="always"
|
||||
/>
|
||||
</menu>
|
19
android/sample/res/menu/action_bar_home.xml
Normal file
19
android/sample/res/menu/action_bar_home.xml
Normal file
@@ -0,0 +1,19 @@
|
||||
<?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.
|
||||
-->
|
||||
|
||||
<menu
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
>
|
||||
<item
|
||||
android:id="@+id/action_benchmark"
|
||||
android:title="Benchmark"
|
||||
android:showAsAction="always"
|
||||
/>
|
||||
</menu>
|
20
android/sample/res/values/colors.xml
Normal file
20
android/sample/res/values/colors.xml
Normal 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>
|
33
android/sample/res/values/strings.xml
Normal file
33
android/sample/res/values/strings.xml
Normal 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>
|
23
android/sample/res/values/styles.xml
Normal file
23
android/sample/res/values/styles.xml
Normal 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>
|
25
android/src/main/AndroidManifest.xml
Normal file
25
android/src/main/AndroidManifest.xml
Normal 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="21"
|
||||
/>
|
||||
|
||||
<application/>
|
||||
|
||||
</manifest>
|
23
android/src/main/java/com/facebook/yoga/android/BUCK
Normal file
23
android/src/main/java/com/facebook/yoga/android/BUCK
Normal 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"]),
|
||||
visibility = [
|
||||
"PUBLIC",
|
||||
],
|
||||
deps = [
|
||||
ANDROID_RES_TARGET,
|
||||
INFER_ANNOTATIONS_TARGET,
|
||||
JAVA_TARGET,
|
||||
JSR_305_TARGET,
|
||||
SOLOADER_TARGET,
|
||||
],
|
||||
)
|
@@ -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;
|
||||
}
|
||||
}
|
824
android/src/main/java/com/facebook/yoga/android/YogaLayout.java
Normal file
824
android/src/main/java/com/facebook/yoga/android/YogaLayout.java
Normal file
@@ -0,0 +1,824 @@
|
||||
/**
|
||||
* 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.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 android.util.Log;
|
||||
|
||||
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.YogaDisplay;
|
||||
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.YogaNode;
|
||||
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/com.facebook.yoga.android"
|
||||
* 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());
|
||||
|
||||
LayoutParams layoutParams = null;
|
||||
if (attrs != null) {
|
||||
layoutParams = new LayoutParams(context, attrs);
|
||||
} else {
|
||||
layoutParams = (LayoutParams) generateDefaultLayoutParams();
|
||||
}
|
||||
applyLayoutParams(layoutParams, mYogaNode, this);
|
||||
}
|
||||
|
||||
public YogaNode getYogaNode() {
|
||||
return mYogaNode;
|
||||
}
|
||||
|
||||
public 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 Yoga 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 {
|
||||
if(mYogaNodes.containsKey(child)) {
|
||||
childNode = mYogaNodes.get(child);
|
||||
} 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();
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks a particular view as "dirty" and to be relaid out. If the view is not a child of this
|
||||
* {@link YogaLayout}, the entire tree is traversed to find it.
|
||||
*
|
||||
* @param view the view to mark as dirty
|
||||
*/
|
||||
public void invalidate(View view) {
|
||||
if (mYogaNodes.containsKey(view)) {
|
||||
mYogaNodes.get(view).dirty();
|
||||
return;
|
||||
}
|
||||
|
||||
final int childCount = mYogaNode.getChildCount();
|
||||
for (int i = 0; i < childCount; i++) {
|
||||
final YogaNode yogaNode = mYogaNode.getChildAt(i);
|
||||
if (yogaNode.getData() instanceof YogaLayout) {
|
||||
((YogaLayout) yogaNode.getData()).invalidate(view);
|
||||
}
|
||||
}
|
||||
invalidate();
|
||||
}
|
||||
|
||||
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)) {
|
||||
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.numericAttributes.size(); i++) {
|
||||
final int attribute = layoutParameters.numericAttributes.keyAt(i);
|
||||
final float value = layoutParameters.numericAttributes.valueAt(i);
|
||||
|
||||
if (attribute == R.styleable.yoga_yg_alignContent) {
|
||||
node.setAlignContent(YogaAlign.fromInt(Math.round(value)));
|
||||
} else if (attribute == R.styleable.yoga_yg_alignItems) {
|
||||
node.setAlignItems(YogaAlign.fromInt(Math.round(value)));
|
||||
} else if (attribute == R.styleable.yoga_yg_alignSelf) {
|
||||
node.setAlignSelf(YogaAlign.fromInt(Math.round(value)));
|
||||
} else if (attribute == R.styleable.yoga_yg_aspectRatio) {
|
||||
node.setAspectRatio(value);
|
||||
} else if (attribute == R.styleable.yoga_yg_borderLeft) {
|
||||
node.setBorder(YogaEdge.LEFT, value);
|
||||
} else if (attribute == R.styleable.yoga_yg_borderTop) {
|
||||
node.setBorder(YogaEdge.TOP, value);
|
||||
} else if (attribute == R.styleable.yoga_yg_borderRight) {
|
||||
node.setBorder(YogaEdge.RIGHT, value);
|
||||
} else if (attribute == R.styleable.yoga_yg_borderBottom) {
|
||||
node.setBorder(YogaEdge.BOTTOM, value);
|
||||
} else if (attribute == R.styleable.yoga_yg_borderStart) {
|
||||
node.setBorder(YogaEdge.START, value);
|
||||
} else if (attribute == R.styleable.yoga_yg_borderEnd) {
|
||||
node.setBorder(YogaEdge.END, value);
|
||||
} else if (attribute == R.styleable.yoga_yg_borderHorizontal) {
|
||||
node.setBorder(YogaEdge.HORIZONTAL, value);
|
||||
} else if (attribute == R.styleable.yoga_yg_borderVertical) {
|
||||
node.setBorder(YogaEdge.VERTICAL, value);
|
||||
} else if (attribute == R.styleable.yoga_yg_borderAll) {
|
||||
node.setBorder(YogaEdge.ALL, value);
|
||||
} else if (attribute == R.styleable.yoga_yg_direction) {
|
||||
node.setDirection(YogaDirection.fromInt(Math.round(value)));
|
||||
} else if (attribute == R.styleable.yoga_yg_display) {
|
||||
node.setDisplay(YogaDisplay.fromInt(Math.round(value)));
|
||||
} else if (attribute == R.styleable.yoga_yg_flex) {
|
||||
node.setFlex(value);
|
||||
} else if (attribute == R.styleable.yoga_yg_flexBasis) {
|
||||
node.setFlexBasis(value);
|
||||
} else if (attribute == R.styleable.yoga_yg_flexDirection) {
|
||||
node.setFlexDirection(YogaFlexDirection.fromInt(Math.round(value)));
|
||||
} else if (attribute == R.styleable.yoga_yg_flexGrow) {
|
||||
node.setFlexGrow(value);
|
||||
} else if (attribute == R.styleable.yoga_yg_flexShrink) {
|
||||
node.setFlexShrink(value);
|
||||
} else if (attribute == R.styleable.yoga_yg_height) {
|
||||
node.setHeight(value);
|
||||
} else if (attribute == R.styleable.yoga_yg_marginLeft) {
|
||||
node.setMargin(YogaEdge.LEFT, value);
|
||||
} else if (attribute == R.styleable.yoga_yg_justifyContent) {
|
||||
node.setJustifyContent(YogaJustify.fromInt(Math.round(value)));
|
||||
} else if (attribute == R.styleable.yoga_yg_marginTop) {
|
||||
node.setMargin(YogaEdge.TOP, value);
|
||||
} else if (attribute == R.styleable.yoga_yg_marginRight) {
|
||||
node.setMargin(YogaEdge.RIGHT, value);
|
||||
} else if (attribute == R.styleable.yoga_yg_marginBottom) {
|
||||
node.setMargin(YogaEdge.BOTTOM, value);
|
||||
} else if (attribute == R.styleable.yoga_yg_marginStart) {
|
||||
node.setMargin(YogaEdge.START, value);
|
||||
} else if (attribute == R.styleable.yoga_yg_marginEnd) {
|
||||
node.setMargin(YogaEdge.END, value);
|
||||
} else if (attribute == R.styleable.yoga_yg_marginHorizontal) {
|
||||
node.setMargin(YogaEdge.HORIZONTAL, value);
|
||||
} else if (attribute == R.styleable.yoga_yg_marginVertical) {
|
||||
node.setMargin(YogaEdge.VERTICAL, value);
|
||||
} else if (attribute == R.styleable.yoga_yg_marginAll) {
|
||||
node.setMargin(YogaEdge.ALL, value);
|
||||
} else if (attribute == R.styleable.yoga_yg_maxHeight) {
|
||||
node.setMaxHeight(value);
|
||||
} else if (attribute == R.styleable.yoga_yg_maxWidth) {
|
||||
node.setMaxWidth(value);
|
||||
} else if (attribute == R.styleable.yoga_yg_minHeight) {
|
||||
node.setMinHeight(value);
|
||||
} else if (attribute == R.styleable.yoga_yg_minWidth) {
|
||||
node.setMinWidth(value);
|
||||
} else if (attribute == R.styleable.yoga_yg_overflow) {
|
||||
node.setOverflow(YogaOverflow.fromInt(Math.round(value)));
|
||||
} else if (attribute == R.styleable.yoga_yg_paddingLeft) {
|
||||
node.setPadding(YogaEdge.LEFT, value);
|
||||
} else if (attribute == R.styleable.yoga_yg_paddingTop) {
|
||||
node.setPadding(YogaEdge.TOP, value);
|
||||
} else if (attribute == R.styleable.yoga_yg_paddingRight) {
|
||||
node.setPadding(YogaEdge.RIGHT, value);
|
||||
} else if (attribute == R.styleable.yoga_yg_paddingBottom) {
|
||||
node.setPadding(YogaEdge.BOTTOM, value);
|
||||
} else if (attribute == R.styleable.yoga_yg_paddingStart) {
|
||||
node.setPadding(YogaEdge.START, value);
|
||||
} else if (attribute == R.styleable.yoga_yg_paddingEnd) {
|
||||
node.setPadding(YogaEdge.END, value);
|
||||
} else if (attribute == R.styleable.yoga_yg_paddingHorizontal) {
|
||||
node.setPadding(YogaEdge.HORIZONTAL, value);
|
||||
} else if (attribute == R.styleable.yoga_yg_paddingVertical) {
|
||||
node.setPadding(YogaEdge.VERTICAL, value);
|
||||
} else if (attribute == R.styleable.yoga_yg_paddingAll) {
|
||||
node.setPadding(YogaEdge.ALL, value);
|
||||
} else if (attribute == R.styleable.yoga_yg_positionLeft) {
|
||||
node.setPosition(YogaEdge.LEFT, value);
|
||||
} else if (attribute == R.styleable.yoga_yg_positionTop) {
|
||||
node.setPosition(YogaEdge.TOP, value);
|
||||
} else if (attribute == R.styleable.yoga_yg_positionRight) {
|
||||
node.setPosition(YogaEdge.RIGHT, value);
|
||||
} else if (attribute == R.styleable.yoga_yg_positionBottom) {
|
||||
node.setPosition(YogaEdge.BOTTOM, value);
|
||||
} else if (attribute == R.styleable.yoga_yg_positionStart) {
|
||||
node.setPosition(YogaEdge.START, value);
|
||||
} else if (attribute == R.styleable.yoga_yg_positionEnd) {
|
||||
node.setPosition(YogaEdge.END, value);
|
||||
} else if (attribute == R.styleable.yoga_yg_positionHorizontal) {
|
||||
node.setPosition(YogaEdge.HORIZONTAL, value);
|
||||
} else if (attribute == R.styleable.yoga_yg_positionVertical) {
|
||||
node.setPosition(YogaEdge.VERTICAL, value);
|
||||
} else if (attribute == R.styleable.yoga_yg_positionAll) {
|
||||
node.setPosition(YogaEdge.ALL, value);
|
||||
} else if (attribute == R.styleable.yoga_yg_positionType) {
|
||||
node.setPositionType(YogaPositionType.fromInt(Math.round(value)));
|
||||
} else if (attribute == R.styleable.yoga_yg_width) {
|
||||
node.setWidth(value);
|
||||
} else if (attribute == R.styleable.yoga_yg_wrap) {
|
||||
node.setWrap(YogaWrap.fromInt(Math.round(value)));
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < layoutParameters.stringAttributes.size(); i++) {
|
||||
final int attribute = layoutParameters.stringAttributes.keyAt(i);
|
||||
final String value = layoutParameters.stringAttributes.valueAt(i);
|
||||
|
||||
if (value.equals("auto")) {
|
||||
if (attribute == R.styleable.yoga_yg_marginLeft) {
|
||||
node.setMarginAuto(YogaEdge.LEFT);
|
||||
} else if (attribute == R.styleable.yoga_yg_marginTop) {
|
||||
node.setMarginAuto(YogaEdge.TOP);
|
||||
} else if (attribute == R.styleable.yoga_yg_marginRight) {
|
||||
node.setMarginAuto(YogaEdge.RIGHT);
|
||||
} else if (attribute == R.styleable.yoga_yg_marginBottom) {
|
||||
node.setMarginAuto(YogaEdge.BOTTOM);
|
||||
} else if (attribute == R.styleable.yoga_yg_marginStart) {
|
||||
node.setMarginAuto(YogaEdge.START);
|
||||
} else if (attribute == R.styleable.yoga_yg_marginEnd) {
|
||||
node.setMarginAuto(YogaEdge.END);
|
||||
} else if (attribute == R.styleable.yoga_yg_marginHorizontal) {
|
||||
node.setMarginAuto(YogaEdge.HORIZONTAL);
|
||||
} else if (attribute == R.styleable.yoga_yg_marginVertical) {
|
||||
node.setMarginAuto(YogaEdge.VERTICAL);
|
||||
} else if (attribute == R.styleable.yoga_yg_marginAll) {
|
||||
node.setMarginAuto(YogaEdge.ALL);
|
||||
}
|
||||
}
|
||||
|
||||
if (value.endsWith("%")) {
|
||||
final float numericValue = Float.parseFloat(value.substring(0, value.length()-1));
|
||||
|
||||
if (attribute == R.styleable.yoga_yg_flexBasis) {
|
||||
node.setFlexBasisPercent(numericValue);
|
||||
} else if (attribute == R.styleable.yoga_yg_height) {
|
||||
node.setHeightPercent(numericValue);
|
||||
} else if (attribute == R.styleable.yoga_yg_marginLeft) {
|
||||
node.setMarginPercent(YogaEdge.LEFT, numericValue);
|
||||
} else if (attribute == R.styleable.yoga_yg_marginTop) {
|
||||
node.setMarginPercent(YogaEdge.TOP, numericValue);
|
||||
} else if (attribute == R.styleable.yoga_yg_marginRight) {
|
||||
node.setMarginPercent(YogaEdge.RIGHT, numericValue);
|
||||
} else if (attribute == R.styleable.yoga_yg_marginBottom) {
|
||||
node.setMarginPercent(YogaEdge.BOTTOM, numericValue);
|
||||
} else if (attribute == R.styleable.yoga_yg_marginStart) {
|
||||
node.setMarginPercent(YogaEdge.START, numericValue);
|
||||
} else if (attribute == R.styleable.yoga_yg_marginEnd) {
|
||||
node.setMarginPercent(YogaEdge.END, numericValue);
|
||||
} else if (attribute == R.styleable.yoga_yg_marginHorizontal) {
|
||||
node.setMarginPercent(YogaEdge.HORIZONTAL, numericValue);
|
||||
} else if (attribute == R.styleable.yoga_yg_marginVertical) {
|
||||
node.setMarginPercent(YogaEdge.VERTICAL, numericValue);
|
||||
} else if (attribute == R.styleable.yoga_yg_marginAll) {
|
||||
node.setMarginPercent(YogaEdge.ALL, numericValue);
|
||||
} else if (attribute == R.styleable.yoga_yg_maxHeight) {
|
||||
node.setMaxHeightPercent(numericValue);
|
||||
} else if (attribute == R.styleable.yoga_yg_maxWidth) {
|
||||
node.setMaxWidthPercent(numericValue);
|
||||
} else if (attribute == R.styleable.yoga_yg_minHeight) {
|
||||
node.setMinHeightPercent(numericValue);
|
||||
} else if (attribute == R.styleable.yoga_yg_minWidth) {
|
||||
node.setMinWidthPercent(numericValue);
|
||||
} else if (attribute == R.styleable.yoga_yg_paddingLeft) {
|
||||
node.setPaddingPercent(YogaEdge.LEFT, numericValue);
|
||||
} else if (attribute == R.styleable.yoga_yg_paddingTop) {
|
||||
node.setPaddingPercent(YogaEdge.TOP, numericValue);
|
||||
} else if (attribute == R.styleable.yoga_yg_paddingRight) {
|
||||
node.setPaddingPercent(YogaEdge.RIGHT, numericValue);
|
||||
} else if (attribute == R.styleable.yoga_yg_paddingBottom) {
|
||||
node.setPaddingPercent(YogaEdge.BOTTOM, numericValue);
|
||||
} else if (attribute == R.styleable.yoga_yg_paddingStart) {
|
||||
node.setPaddingPercent(YogaEdge.START, numericValue);
|
||||
} else if (attribute == R.styleable.yoga_yg_paddingEnd) {
|
||||
node.setPaddingPercent(YogaEdge.END, numericValue);
|
||||
} else if (attribute == R.styleable.yoga_yg_paddingHorizontal) {
|
||||
node.setPaddingPercent(YogaEdge.HORIZONTAL, numericValue);
|
||||
} else if (attribute == R.styleable.yoga_yg_paddingVertical) {
|
||||
node.setPaddingPercent(YogaEdge.VERTICAL, numericValue);
|
||||
} else if (attribute == R.styleable.yoga_yg_paddingAll) {
|
||||
node.setPaddingPercent(YogaEdge.ALL, numericValue);
|
||||
} else if (attribute == R.styleable.yoga_yg_positionLeft) {
|
||||
node.setPositionPercent(YogaEdge.LEFT, numericValue);
|
||||
} else if (attribute == R.styleable.yoga_yg_positionTop) {
|
||||
node.setPositionPercent(YogaEdge.TOP, numericValue);
|
||||
} else if (attribute == R.styleable.yoga_yg_positionRight) {
|
||||
node.setPositionPercent(YogaEdge.RIGHT, numericValue);
|
||||
} else if (attribute == R.styleable.yoga_yg_positionBottom) {
|
||||
node.setPositionPercent(YogaEdge.BOTTOM, numericValue);
|
||||
} else if (attribute == R.styleable.yoga_yg_positionStart) {
|
||||
node.setPositionPercent(YogaEdge.START, numericValue);
|
||||
} else if (attribute == R.styleable.yoga_yg_positionEnd) {
|
||||
node.setPositionPercent(YogaEdge.END, numericValue);
|
||||
} else if (attribute == R.styleable.yoga_yg_positionHorizontal) {
|
||||
node.setPositionPercent(YogaEdge.HORIZONTAL, numericValue);
|
||||
} else if (attribute == R.styleable.yoga_yg_positionVertical) {
|
||||
node.setPositionPercent(YogaEdge.VERTICAL, numericValue);
|
||||
} else if (attribute == R.styleable.yoga_yg_positionAll) {
|
||||
node.setPositionPercent(YogaEdge.ALL, numericValue);
|
||||
} else if (attribute == R.styleable.yoga_yg_width) {
|
||||
node.setWidthPercent(numericValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@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_yg_*}) 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_yg_*}) 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> numericAttributes;
|
||||
|
||||
/**
|
||||
* A mapping from attribute keys ({@code R.styleable.yoga_yg_*}) with string values to those
|
||||
* strings. This is used for values such as "auto".
|
||||
*/
|
||||
SparseArray<String> stringAttributes;
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
numericAttributes = ((LayoutParams) source).numericAttributes.clone();
|
||||
stringAttributes = ((LayoutParams) source).stringAttributes.clone();
|
||||
} else {
|
||||
numericAttributes = new SparseArray<>();
|
||||
stringAttributes = new SparseArray<>();
|
||||
|
||||
// Negative values include MATCH_PARENT and WRAP_CONTENT
|
||||
if (source.width >= 0) {
|
||||
numericAttributes.put(R.styleable.yoga_yg_width, (float) width);
|
||||
}
|
||||
if (source.height >= 0) {
|
||||
numericAttributes.put(R.styleable.yoga_yg_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);
|
||||
numericAttributes = new SparseArray<>();
|
||||
stringAttributes = new SparseArray<>();
|
||||
// Negative values include MATCH_PARENT and WRAP_CONTENT
|
||||
if (width >= 0) {
|
||||
numericAttributes.put(R.styleable.yoga_yg_width, (float) width);
|
||||
}
|
||||
if (height >= 0) {
|
||||
numericAttributes.put(R.styleable.yoga_yg_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);
|
||||
numericAttributes = new SparseArray<>();
|
||||
stringAttributes = new SparseArray<>();
|
||||
final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.yoga);
|
||||
|
||||
// Negative values include MATCH_PARENT and WRAP_CONTENT
|
||||
if (width >= 0) {
|
||||
numericAttributes.put(R.styleable.yoga_yg_width, (float) width);
|
||||
}
|
||||
if (height >= 0) {
|
||||
numericAttributes.put(R.styleable.yoga_yg_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) {
|
||||
numericAttributes.put(
|
||||
attribute,
|
||||
(float) a.getDimensionPixelSize(attribute, 0));
|
||||
} else if (val.type == TypedValue.TYPE_STRING) {
|
||||
stringAttributes.put(attribute, a.getString(attribute));
|
||||
} else {
|
||||
numericAttributes.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(
|
||||
YogaNode 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -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;
|
||||
}
|
||||
}
|
146
android/src/main/res/values/attrs.xml
Normal file
146
android/src/main/res/values/attrs.xml
Normal file
@@ -0,0 +1,146 @@
|
||||
<?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="yg_alignContent" 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="yg_alignItems" 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="yg_alignSelf" 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="yg_aspectRatio" format="float"/>
|
||||
|
||||
<attr name="yg_borderLeft" format="dimension"/>
|
||||
<attr name="yg_borderTop" format="dimension"/>
|
||||
<attr name="yg_borderRight" format="dimension"/>
|
||||
<attr name="yg_borderBottom" format="dimension"/>
|
||||
<attr name="yg_borderStart" format="dimension"/>
|
||||
<attr name="yg_borderEnd" format="dimension"/>
|
||||
<attr name="yg_borderHorizontal" format="dimension"/>
|
||||
<attr name="yg_borderVertical" format="dimension"/>
|
||||
<attr name="yg_borderAll" format="dimension"/>
|
||||
|
||||
<attr name="yg_direction" format="enum">
|
||||
<enum name="inherit" value="0"/>
|
||||
<enum name="ltr" value="1"/>
|
||||
<enum name="rtl" value="2"/>
|
||||
</attr>
|
||||
|
||||
<attr name="yg_display" format="enum">
|
||||
<enum name="flex" value="0"/>
|
||||
<enum name="none" value="1"/>
|
||||
</attr>
|
||||
|
||||
<attr name="yg_flex" format="float"/>
|
||||
|
||||
<attr name="yg_flexBasis" format="float|string"/>
|
||||
|
||||
<attr name="yg_flexDirection" 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="yg_flexGrow" format="float"/>
|
||||
|
||||
<attr name="yg_flexShrink" format="float"/>
|
||||
|
||||
<attr name="yg_height" format="dimension|string"/>
|
||||
|
||||
<attr name="yg_justifyContent" 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="yg_marginLeft" format="dimension|string"/>
|
||||
<attr name="yg_marginTop" format="dimension|string"/>
|
||||
<attr name="yg_marginRight" format="dimension|string"/>
|
||||
<attr name="yg_marginBottom" format="dimension|string"/>
|
||||
<attr name="yg_marginStart" format="dimension|string"/>
|
||||
<attr name="yg_marginEnd" format="dimension|string"/>
|
||||
<attr name="yg_marginHorizontal" format="dimension|string"/>
|
||||
<attr name="yg_marginVertical" format="dimension|string"/>
|
||||
<attr name="yg_marginAll" format="dimension|string"/>
|
||||
|
||||
<attr name="yg_maxHeight" format="dimension|string"/>
|
||||
|
||||
<attr name="yg_maxWidth" format="dimension|string"/>
|
||||
|
||||
<attr name="yg_minHeight" format="dimension|string"/>
|
||||
|
||||
<attr name="yg_minWidth" format="dimension|string"/>
|
||||
|
||||
<attr name="yg_overflow" format="enum">
|
||||
<enum name="visible" value="0"/>
|
||||
<enum name="hidden" value="1"/>
|
||||
<enum name="scroll" value="2"/>
|
||||
</attr>
|
||||
|
||||
<attr name="yg_paddingLeft" format="dimension|string"/>
|
||||
<attr name="yg_paddingTop" format="dimension|string"/>
|
||||
<attr name="yg_paddingRight" format="dimension|string"/>
|
||||
<attr name="yg_paddingBottom" format="dimension|string"/>
|
||||
<attr name="yg_paddingStart" format="dimension|string"/>
|
||||
<attr name="yg_paddingEnd" format="dimension|string"/>
|
||||
<attr name="yg_paddingHorizontal" format="dimension|string"/>
|
||||
<attr name="yg_paddingVertical" format="dimension|string"/>
|
||||
<attr name="yg_paddingAll" format="dimension|string"/>
|
||||
|
||||
<attr name="yg_positionLeft" format="dimension|string"/>
|
||||
<attr name="yg_positionTop" format="dimension|string"/>
|
||||
<attr name="yg_positionRight" format="dimension|string"/>
|
||||
<attr name="yg_positionBottom" format="dimension|string"/>
|
||||
<attr name="yg_positionStart" format="dimension|string"/>
|
||||
<attr name="yg_positionEnd" format="dimension|string"/>
|
||||
<attr name="yg_positionHorizontal" format="dimension|string"/>
|
||||
<attr name="yg_positionVertical" format="dimension|string"/>
|
||||
<attr name="yg_positionAll" format="dimension|string"/>
|
||||
|
||||
<attr name="yg_positionType" format="enum">
|
||||
<enum name="relative" value="0"/>
|
||||
<enum name="absolute" value="1"/>
|
||||
</attr>
|
||||
|
||||
<attr name="yg_width" format="dimension|string"/>
|
||||
|
||||
<attr name="yg_wrap" format="enum">
|
||||
<enum name="no_wrap" value="0"/>
|
||||
<enum name="wrap" value="1"/>
|
||||
</attr>
|
||||
</declare-styleable>
|
||||
</resources>
|
@@ -5,23 +5,23 @@
|
||||
# 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')
|
||||
include_defs("//YOGA_DEFS")
|
||||
|
||||
cxx_binary(
|
||||
name = 'benchmark',
|
||||
srcs = glob(['*.c']),
|
||||
headers = subdir_glob([('', '*.h')]),
|
||||
header_namespace = '',
|
||||
compiler_flags = [
|
||||
'-fno-omit-frame-pointer',
|
||||
'-fexceptions',
|
||||
'-Wall',
|
||||
'-Werror',
|
||||
'-O3',
|
||||
'-std=c11',
|
||||
],
|
||||
deps = [
|
||||
yoga_dep(':yoga'),
|
||||
],
|
||||
visibility = ['PUBLIC'],
|
||||
name = "benchmark",
|
||||
srcs = glob(["*.c"]),
|
||||
compiler_flags = [
|
||||
"-fno-omit-frame-pointer",
|
||||
"-fexceptions",
|
||||
"-Wall",
|
||||
"-Werror",
|
||||
"-O3",
|
||||
"-std=c11",
|
||||
],
|
||||
header_namespace = "",
|
||||
headers = subdir_glob([("", "*.h")]),
|
||||
visibility = ["PUBLIC"],
|
||||
deps = [
|
||||
yoga_dep(":yoga"),
|
||||
],
|
||||
)
|
||||
|
35
build.gradle
Normal file
35
build.gradle
Normal file
@@ -0,0 +1,35 @@
|
||||
// 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.3.1'
|
||||
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 {
|
||||
jcenter()
|
||||
}
|
||||
}
|
||||
|
||||
ext {
|
||||
minSdkVersion = 15
|
||||
targetSdkVersion = 25
|
||||
compileSdkVersion = 25
|
||||
buildToolsVersion = '25.0.2'
|
||||
sourceCompatibilityVersion = JavaVersion.VERSION_1_7
|
||||
targetCompatibilityVersion = JavaVersion.VERSION_1_7
|
||||
}
|
||||
|
||||
task clean(type: Delete) {
|
||||
delete rootProject.buildDir
|
||||
}
|
@@ -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>
|
||||
|
@@ -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>
|
||||
|
57
csharp/BUCK
57
csharp/BUCK
@@ -5,41 +5,40 @@
|
||||
# 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')
|
||||
include_defs("//YOGA_DEFS")
|
||||
|
||||
COMPILER_FLAGS = BASE_COMPILER_FLAGS + ['-std=c++11']
|
||||
COMPILER_FLAGS = BASE_COMPILER_FLAGS + ["-std=c++11"]
|
||||
|
||||
csharp_library(
|
||||
name = 'yogalibnet46',
|
||||
dll_name = 'Facebook.Yoga.dll',
|
||||
framework_ver = 'net46',
|
||||
srcs = glob(['**/*.cs']),
|
||||
name = "yogalibnet46",
|
||||
srcs = glob(["**/*.cs"]),
|
||||
dll_name = "Facebook.Yoga.dll",
|
||||
framework_ver = "net46",
|
||||
)
|
||||
|
||||
csharp_library(
|
||||
name = 'yogalibnet45',
|
||||
dll_name = 'Facebook.Yoga.dll',
|
||||
framework_ver = 'net45',
|
||||
srcs = glob(['**/*.cs']),
|
||||
name = "yogalibnet45",
|
||||
srcs = glob(["**/*.cs"]),
|
||||
dll_name = "Facebook.Yoga.dll",
|
||||
framework_ver = "net45",
|
||||
)
|
||||
|
||||
cxx_library(
|
||||
name = 'yoganet',
|
||||
soname = 'libyoga.$(ext)',
|
||||
srcs = glob(['Yoga/YGInterop.cpp']),
|
||||
compiler_flags = COMPILER_FLAGS,
|
||||
link_style = 'static',
|
||||
link_whole = True,
|
||||
deps = [yoga_dep(':yoga')],
|
||||
visibility = ['PUBLIC'],
|
||||
name = "yoganet",
|
||||
srcs = glob(["Yoga/YGInterop.cpp"]),
|
||||
compiler_flags = COMPILER_FLAGS,
|
||||
link_style = "static",
|
||||
link_whole = True,
|
||||
soname = "libyoga.$(ext)",
|
||||
visibility = ["PUBLIC"],
|
||||
deps = [yoga_dep(":yoga")],
|
||||
)
|
||||
|
||||
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'],
|
||||
)
|
||||
|
130
csharp/Facebook.Yoga.Xamarin.sln
Normal file
130
csharp/Facebook.Yoga.Xamarin.sln
Normal 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
|
@@ -15,9 +15,11 @@
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Native.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)YogaAlign.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)YogaBaselineFunc.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)YogaConfig.cs" />
|
||||
<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 +39,4 @@
|
||||
<Compile Include="$(MSBuildThisFileDirectory)YogaValueExtensions.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)YogaWrap.cs" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
@@ -12,6 +12,12 @@ using System.Runtime.InteropServices;
|
||||
|
||||
namespace Facebook.Yoga
|
||||
{
|
||||
#if WINDOWS_UWP_ARM
|
||||
using YogaValueType = IntPtr;
|
||||
#else
|
||||
using YogaValueType = YogaValue;
|
||||
#endif
|
||||
|
||||
internal static class Native
|
||||
{
|
||||
#if (UNITY_IOS && !UNITY_EDITOR) || __IOS__
|
||||
@@ -22,6 +28,10 @@ namespace Facebook.Yoga
|
||||
|
||||
internal class YGNodeHandle : SafeHandle
|
||||
{
|
||||
#if (UNITY_IOS && !UNITY_EDITOR) || ENABLE_IL2CPP || __IOS__
|
||||
private GCHandle _managed;
|
||||
#endif
|
||||
|
||||
private YGNodeHandle() : base(IntPtr.Zero, true)
|
||||
{
|
||||
}
|
||||
@@ -36,10 +46,71 @@ namespace Facebook.Yoga
|
||||
|
||||
protected override bool ReleaseHandle()
|
||||
{
|
||||
#if (UNITY_IOS && !UNITY_EDITOR) || ENABLE_IL2CPP || __IOS__
|
||||
ReleaseManaged();
|
||||
#endif
|
||||
Native.YGNodeFree(this.handle);
|
||||
GC.KeepAlive(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
#if (UNITY_IOS && !UNITY_EDITOR) || ENABLE_IL2CPP || __IOS__
|
||||
public void SetContext(YogaNode node)
|
||||
{
|
||||
if (!_managed.IsAllocated)
|
||||
{
|
||||
#if ENABLE_IL2CPP
|
||||
// Weak causes 'GCHandle value belongs to a different domain' error
|
||||
_managed = GCHandle.Alloc(node);
|
||||
#else
|
||||
_managed = GCHandle.Alloc(node, GCHandleType.Weak);
|
||||
#endif
|
||||
Native.YGNodeSetContext(this.handle, GCHandle.ToIntPtr(_managed));
|
||||
}
|
||||
}
|
||||
|
||||
public void ReleaseManaged()
|
||||
{
|
||||
if (_managed.IsAllocated)
|
||||
{
|
||||
_managed.Free();
|
||||
}
|
||||
}
|
||||
|
||||
public static YogaNode GetManaged(IntPtr ygNodePtr)
|
||||
{
|
||||
var node =
|
||||
GCHandle.FromIntPtr(Native.YGNodeGetContext(ygNodePtr)).Target as YogaNode;
|
||||
if (node == null)
|
||||
{
|
||||
throw new InvalidOperationException("YogaNode is already deallocated");
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
internal class YGConfigHandle : SafeHandle
|
||||
{
|
||||
private YGConfigHandle() : base(IntPtr.Zero, true)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool IsInvalid
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.handle == IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
|
||||
protected override bool ReleaseHandle()
|
||||
{
|
||||
Native.YGConfigFree(this.handle);
|
||||
GC.KeepAlive(this);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
||||
@@ -49,35 +120,66 @@ namespace Facebook.Yoga
|
||||
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern YGNodeHandle YGNodeNew();
|
||||
|
||||
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern YGNodeHandle YGNodeNewWithConfig(YGConfigHandle config);
|
||||
|
||||
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void YGNodeFree(IntPtr node);
|
||||
|
||||
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void YGNodeReset(YGNodeHandle node);
|
||||
|
||||
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern YGConfigHandle YGConfigNew();
|
||||
|
||||
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void YGConfigFree(IntPtr node);
|
||||
|
||||
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int YGNodeGetInstanceCount();
|
||||
|
||||
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void YGSetExperimentalFeatureEnabled(
|
||||
public static extern int YGConfigGetInstanceCount();
|
||||
|
||||
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void YGConfigSetExperimentalFeatureEnabled(
|
||||
YGConfigHandle config,
|
||||
YogaExperimentalFeature feature,
|
||||
bool enabled);
|
||||
|
||||
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern bool YGIsExperimentalFeatureEnabled(
|
||||
public static extern bool YGConfigIsExperimentalFeatureEnabled(
|
||||
YGConfigHandle config,
|
||||
YogaExperimentalFeature feature);
|
||||
|
||||
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void YGNodeInsertChild(YGNodeHandle node, YGNodeHandle child, uint index);
|
||||
public static extern void YGConfigSetUseWebDefaults(
|
||||
YGConfigHandle config,
|
||||
bool useWebDefaults);
|
||||
|
||||
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern bool YGConfigGetUseWebDefaults(YGConfigHandle config);
|
||||
|
||||
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void YGConfigSetPointScaleFactor(
|
||||
YGConfigHandle config,
|
||||
float pixelsInPoint);
|
||||
|
||||
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
||||
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);
|
||||
@@ -92,7 +194,7 @@ namespace Facebook.Yoga
|
||||
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void YGNodeCopyStyle(YGNodeHandle dstNode, YGNodeHandle srcNode);
|
||||
|
||||
#region YG_NODE_PROPERTY
|
||||
#region YG_NODE_PROPERTY
|
||||
|
||||
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void YGNodeSetMeasureFunc(
|
||||
@@ -105,15 +207,17 @@ 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)]
|
||||
public static extern bool YGNodeGetHasNewLayout(YGNodeHandle node);
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region YG_NODE_STYLE_PROPERTY
|
||||
#region YG_NODE_STYLE_PROPERTY
|
||||
|
||||
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void YGNodeStyleSetDirection(YGNodeHandle node, YogaDirection direction);
|
||||
@@ -197,7 +301,10 @@ namespace Facebook.Yoga
|
||||
public static extern void YGNodeStyleSetFlexBasisPercent(YGNodeHandle node, float flexBasis);
|
||||
|
||||
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern YogaValue YGNodeStyleGetFlexBasis(YGNodeHandle node);
|
||||
public static extern void YGNodeStyleSetFlexBasisAuto(YGNodeHandle node);
|
||||
|
||||
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern YogaValueType YGNodeStyleGetFlexBasis(YGNodeHandle node);
|
||||
|
||||
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void YGNodeStyleSetWidth(YGNodeHandle node, float width);
|
||||
@@ -206,7 +313,10 @@ namespace Facebook.Yoga
|
||||
public static extern void YGNodeStyleSetWidthPercent(YGNodeHandle node, float width);
|
||||
|
||||
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern YogaValue YGNodeStyleGetWidth(YGNodeHandle node);
|
||||
public static extern void YGNodeStyleSetWidthAuto(YGNodeHandle node);
|
||||
|
||||
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern YogaValueType YGNodeStyleGetWidth(YGNodeHandle node);
|
||||
|
||||
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void YGNodeStyleSetHeight(YGNodeHandle node, float height);
|
||||
@@ -215,7 +325,10 @@ namespace Facebook.Yoga
|
||||
public static extern void YGNodeStyleSetHeightPercent(YGNodeHandle node, float height);
|
||||
|
||||
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern YogaValue YGNodeStyleGetHeight(YGNodeHandle node);
|
||||
public static extern void YGNodeStyleSetHeightAuto(YGNodeHandle node);
|
||||
|
||||
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern YogaValueType YGNodeStyleGetHeight(YGNodeHandle node);
|
||||
|
||||
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void YGNodeStyleSetMinWidth(YGNodeHandle node, float minWidth);
|
||||
@@ -224,7 +337,7 @@ namespace Facebook.Yoga
|
||||
public static extern void YGNodeStyleSetMinWidthPercent(YGNodeHandle node, float minWidth);
|
||||
|
||||
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern YogaValue YGNodeStyleGetMinWidth(YGNodeHandle node);
|
||||
public static extern YogaValueType YGNodeStyleGetMinWidth(YGNodeHandle node);
|
||||
|
||||
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void YGNodeStyleSetMinHeight(YGNodeHandle node, float minHeight);
|
||||
@@ -233,7 +346,7 @@ namespace Facebook.Yoga
|
||||
public static extern void YGNodeStyleSetMinHeightPercent(YGNodeHandle node, float minHeight);
|
||||
|
||||
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern YogaValue YGNodeStyleGetMinHeight(YGNodeHandle node);
|
||||
public static extern YogaValueType YGNodeStyleGetMinHeight(YGNodeHandle node);
|
||||
|
||||
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void YGNodeStyleSetMaxWidth(YGNodeHandle node, float maxWidth);
|
||||
@@ -242,7 +355,7 @@ namespace Facebook.Yoga
|
||||
public static extern void YGNodeStyleSetMaxWidthPercent(YGNodeHandle node, float maxWidth);
|
||||
|
||||
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern YogaValue YGNodeStyleGetMaxWidth(YGNodeHandle node);
|
||||
public static extern YogaValueType YGNodeStyleGetMaxWidth(YGNodeHandle node);
|
||||
|
||||
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void YGNodeStyleSetMaxHeight(YGNodeHandle node, float maxHeight);
|
||||
@@ -251,7 +364,7 @@ namespace Facebook.Yoga
|
||||
public static extern void YGNodeStyleSetMaxHeightPercent(YGNodeHandle node, float maxHeight);
|
||||
|
||||
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern YogaValue YGNodeStyleGetMaxHeight(YGNodeHandle node);
|
||||
public static extern YogaValueType YGNodeStyleGetMaxHeight(YGNodeHandle node);
|
||||
|
||||
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void YGNodeStyleSetAspectRatio(YGNodeHandle node, float aspectRatio);
|
||||
@@ -259,9 +372,9 @@ namespace Facebook.Yoga
|
||||
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern float YGNodeStyleGetAspectRatio(YGNodeHandle node);
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region YG_NODE_STYLE_EDGE_PROPERTY
|
||||
#region YG_NODE_STYLE_EDGE_PROPERTY
|
||||
|
||||
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void YGNodeStyleSetPosition(YGNodeHandle node, YogaEdge edge, float position);
|
||||
@@ -270,7 +383,7 @@ namespace Facebook.Yoga
|
||||
public static extern void YGNodeStyleSetPositionPercent(YGNodeHandle node, YogaEdge edge, float position);
|
||||
|
||||
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern YogaValue YGNodeStyleGetPosition(YGNodeHandle node, YogaEdge edge);
|
||||
public static extern YogaValueType YGNodeStyleGetPosition(YGNodeHandle node, YogaEdge edge);
|
||||
|
||||
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void YGNodeStyleSetMargin(YGNodeHandle node, YogaEdge edge, float margin);
|
||||
@@ -279,7 +392,10 @@ namespace Facebook.Yoga
|
||||
public static extern void YGNodeStyleSetMarginPercent(YGNodeHandle node, YogaEdge edge, float margin);
|
||||
|
||||
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern YogaValue YGNodeStyleGetMargin(YGNodeHandle node, YogaEdge edge);
|
||||
public static extern void YGNodeStyleSetMarginAuto(YGNodeHandle node, YogaEdge edge);
|
||||
|
||||
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern YogaValueType YGNodeStyleGetMargin(YGNodeHandle node, YogaEdge edge);
|
||||
|
||||
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void YGNodeStyleSetPadding(YGNodeHandle node, YogaEdge edge, float padding);
|
||||
@@ -288,7 +404,7 @@ namespace Facebook.Yoga
|
||||
public static extern void YGNodeStyleSetPaddingPercent(YGNodeHandle node, YogaEdge edge, float padding);
|
||||
|
||||
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern YogaValue YGNodeStyleGetPadding(YGNodeHandle node, YogaEdge edge);
|
||||
public static extern YogaValueType YGNodeStyleGetPadding(YGNodeHandle node, YogaEdge edge);
|
||||
|
||||
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void YGNodeStyleSetBorder(YGNodeHandle node, YogaEdge edge, float border);
|
||||
@@ -296,9 +412,9 @@ namespace Facebook.Yoga
|
||||
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern float YGNodeStyleGetBorder(YGNodeHandle node, YogaEdge edge);
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region YG_NODE_LAYOUT_PROPERTY
|
||||
#region YG_NODE_LAYOUT_PROPERTY
|
||||
|
||||
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern float YGNodeLayoutGetLeft(YGNodeHandle node);
|
||||
@@ -327,6 +443,18 @@ namespace Facebook.Yoga
|
||||
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern YogaDirection YGNodeLayoutGetDirection(YGNodeHandle node);
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region AOT
|
||||
|
||||
#if (UNITY_IOS && !UNITY_EDITOR) || ENABLE_IL2CPP || __IOS__
|
||||
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern IntPtr YGNodeGetContext(IntPtr node);
|
||||
|
||||
[DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void YGNodeSetContext(IntPtr node, IntPtr managed);
|
||||
#endif
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
@@ -17,5 +17,7 @@ namespace Facebook.Yoga
|
||||
FlexEnd,
|
||||
Stretch,
|
||||
Baseline,
|
||||
SpaceBetween,
|
||||
SpaceAround,
|
||||
}
|
||||
}
|
||||
|
72
csharp/Facebook.Yoga/YogaConfig.cs
Normal file
72
csharp/Facebook.Yoga/YogaConfig.cs
Normal file
@@ -0,0 +1,72 @@
|
||||
/**
|
||||
* Copyright (c) 2014-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
using System;
|
||||
|
||||
namespace Facebook.Yoga
|
||||
{
|
||||
public class YogaConfig
|
||||
{
|
||||
private Native.YGConfigHandle _ygConfig;
|
||||
|
||||
public YogaConfig()
|
||||
{
|
||||
_ygConfig = Native.YGConfigNew();
|
||||
if (_ygConfig.IsInvalid)
|
||||
{
|
||||
throw new InvalidOperationException("Failed to allocate native memory");
|
||||
}
|
||||
}
|
||||
|
||||
internal Native.YGConfigHandle Handle
|
||||
{
|
||||
get {
|
||||
return _ygConfig;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetExperimentalFeatureEnabled(
|
||||
YogaExperimentalFeature feature,
|
||||
bool enabled)
|
||||
{
|
||||
Native.YGConfigSetExperimentalFeatureEnabled(_ygConfig, feature, enabled);
|
||||
}
|
||||
|
||||
public bool IsExperimentalFeatureEnabled(YogaExperimentalFeature feature)
|
||||
{
|
||||
return Native.YGConfigIsExperimentalFeatureEnabled(_ygConfig, feature);
|
||||
}
|
||||
|
||||
public bool UseWebDefaults
|
||||
{
|
||||
get
|
||||
{
|
||||
return Native.YGConfigGetUseWebDefaults(_ygConfig);
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
Native.YGConfigSetUseWebDefaults(_ygConfig, value);
|
||||
}
|
||||
}
|
||||
|
||||
public float PointScaleFactor
|
||||
{
|
||||
set
|
||||
{
|
||||
Native.YGConfigSetPointScaleFactor(_ygConfig, value);
|
||||
}
|
||||
}
|
||||
|
||||
public static int GetInstanceCount()
|
||||
{
|
||||
return Native.YGConfigGetInstanceCount();
|
||||
}
|
||||
}
|
||||
}
|
@@ -13,5 +13,6 @@ namespace Facebook.Yoga
|
||||
{
|
||||
Rounding,
|
||||
WebFlexBasis,
|
||||
MinFlexFix,
|
||||
}
|
||||
}
|
||||
|
@@ -10,6 +10,13 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
#if __IOS__
|
||||
using ObjCRuntime;
|
||||
#endif
|
||||
#if ENABLE_IL2CPP
|
||||
using AOT;
|
||||
#endif
|
||||
|
||||
namespace Facebook.Yoga
|
||||
{
|
||||
internal static class YogaLogger
|
||||
@@ -18,25 +25,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) || ENABLE_IL2CPP || __IOS__
|
||||
[MonoPInvokeCallback(typeof(Func))]
|
||||
#endif
|
||||
public static void LoggerInternal(YogaLogLevel level, string message)
|
||||
{
|
||||
if (Logger != null)
|
||||
{
|
||||
Logger(level, message);
|
||||
}
|
||||
|
||||
if (level == YogaLogLevel.Error)
|
||||
{
|
||||
throw new InvalidOperationException(message);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
if (!_initialized)
|
||||
{
|
||||
_managedLogger = (level, message) => {
|
||||
if (Logger != null)
|
||||
{
|
||||
Logger(level, message);
|
||||
}
|
||||
|
||||
if (level == YogaLogLevel.Error)
|
||||
{
|
||||
throw new InvalidOperationException(message);
|
||||
}
|
||||
};
|
||||
Native.YGInteropSetLogger(_managedLogger);
|
||||
_initialized = true;
|
||||
}
|
||||
|
@@ -7,8 +7,6 @@
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
using System;
|
||||
|
||||
namespace Facebook.Yoga
|
||||
{
|
||||
public partial class YogaNode
|
||||
@@ -17,7 +15,7 @@ namespace Facebook.Yoga
|
||||
{
|
||||
get
|
||||
{
|
||||
return Native.YGNodeStyleGetPosition(_ygNode, YogaEdge.Left);
|
||||
return YogaValue.MarshalValue(Native.YGNodeStyleGetPosition(_ygNode, YogaEdge.Left));
|
||||
}
|
||||
|
||||
set
|
||||
@@ -30,7 +28,7 @@ namespace Facebook.Yoga
|
||||
{
|
||||
get
|
||||
{
|
||||
return Native.YGNodeStyleGetPosition(_ygNode, YogaEdge.Top);
|
||||
return YogaValue.MarshalValue(Native.YGNodeStyleGetPosition(_ygNode, YogaEdge.Top));
|
||||
}
|
||||
|
||||
set
|
||||
@@ -43,7 +41,7 @@ namespace Facebook.Yoga
|
||||
{
|
||||
get
|
||||
{
|
||||
return Native.YGNodeStyleGetPosition(_ygNode, YogaEdge.Right);
|
||||
return YogaValue.MarshalValue(Native.YGNodeStyleGetPosition(_ygNode, YogaEdge.Right));
|
||||
}
|
||||
|
||||
set
|
||||
@@ -56,7 +54,7 @@ namespace Facebook.Yoga
|
||||
{
|
||||
get
|
||||
{
|
||||
return Native.YGNodeStyleGetPosition(_ygNode, YogaEdge.Bottom);
|
||||
return YogaValue.MarshalValue(Native.YGNodeStyleGetPosition(_ygNode, YogaEdge.Bottom));
|
||||
}
|
||||
|
||||
set
|
||||
@@ -69,7 +67,7 @@ namespace Facebook.Yoga
|
||||
{
|
||||
get
|
||||
{
|
||||
return Native.YGNodeStyleGetPosition(_ygNode, YogaEdge.Start);
|
||||
return YogaValue.MarshalValue(Native.YGNodeStyleGetPosition(_ygNode, YogaEdge.Start));
|
||||
}
|
||||
|
||||
set
|
||||
@@ -82,7 +80,7 @@ namespace Facebook.Yoga
|
||||
{
|
||||
get
|
||||
{
|
||||
return Native.YGNodeStyleGetPosition(_ygNode, YogaEdge.End);
|
||||
return YogaValue.MarshalValue(Native.YGNodeStyleGetPosition(_ygNode, YogaEdge.End));
|
||||
}
|
||||
|
||||
set
|
||||
@@ -107,7 +105,7 @@ namespace Facebook.Yoga
|
||||
{
|
||||
get
|
||||
{
|
||||
return Native.YGNodeStyleGetMargin(_ygNode, YogaEdge.Left);
|
||||
return YogaValue.MarshalValue(Native.YGNodeStyleGetMargin(_ygNode, YogaEdge.Left));
|
||||
}
|
||||
|
||||
set
|
||||
@@ -120,7 +118,7 @@ namespace Facebook.Yoga
|
||||
{
|
||||
get
|
||||
{
|
||||
return Native.YGNodeStyleGetMargin(_ygNode, YogaEdge.Top);
|
||||
return YogaValue.MarshalValue(Native.YGNodeStyleGetMargin(_ygNode, YogaEdge.Top));
|
||||
}
|
||||
|
||||
set
|
||||
@@ -133,7 +131,7 @@ namespace Facebook.Yoga
|
||||
{
|
||||
get
|
||||
{
|
||||
return Native.YGNodeStyleGetMargin(_ygNode, YogaEdge.Right);
|
||||
return YogaValue.MarshalValue(Native.YGNodeStyleGetMargin(_ygNode, YogaEdge.Right));
|
||||
}
|
||||
|
||||
set
|
||||
@@ -146,7 +144,7 @@ namespace Facebook.Yoga
|
||||
{
|
||||
get
|
||||
{
|
||||
return Native.YGNodeStyleGetMargin(_ygNode, YogaEdge.Bottom);
|
||||
return YogaValue.MarshalValue(Native.YGNodeStyleGetMargin(_ygNode, YogaEdge.Bottom));
|
||||
}
|
||||
|
||||
set
|
||||
@@ -159,7 +157,7 @@ namespace Facebook.Yoga
|
||||
{
|
||||
get
|
||||
{
|
||||
return Native.YGNodeStyleGetMargin(_ygNode, YogaEdge.Start);
|
||||
return YogaValue.MarshalValue(Native.YGNodeStyleGetMargin(_ygNode, YogaEdge.Start));
|
||||
}
|
||||
|
||||
set
|
||||
@@ -172,7 +170,7 @@ namespace Facebook.Yoga
|
||||
{
|
||||
get
|
||||
{
|
||||
return Native.YGNodeStyleGetMargin(_ygNode, YogaEdge.End);
|
||||
return YogaValue.MarshalValue(Native.YGNodeStyleGetMargin(_ygNode, YogaEdge.End));
|
||||
}
|
||||
|
||||
set
|
||||
@@ -185,7 +183,7 @@ namespace Facebook.Yoga
|
||||
{
|
||||
get
|
||||
{
|
||||
return Native.YGNodeStyleGetMargin(_ygNode, YogaEdge.Horizontal);
|
||||
return YogaValue.MarshalValue(Native.YGNodeStyleGetMargin(_ygNode, YogaEdge.Horizontal));
|
||||
}
|
||||
|
||||
set
|
||||
@@ -198,7 +196,7 @@ namespace Facebook.Yoga
|
||||
{
|
||||
get
|
||||
{
|
||||
return Native.YGNodeStyleGetMargin(_ygNode, YogaEdge.Vertical);
|
||||
return YogaValue.MarshalValue(Native.YGNodeStyleGetMargin(_ygNode, YogaEdge.Vertical));
|
||||
}
|
||||
|
||||
set
|
||||
@@ -211,7 +209,7 @@ namespace Facebook.Yoga
|
||||
{
|
||||
get
|
||||
{
|
||||
return Native.YGNodeStyleGetMargin(_ygNode, YogaEdge.All);
|
||||
return YogaValue.MarshalValue(Native.YGNodeStyleGetMargin(_ygNode, YogaEdge.All));
|
||||
}
|
||||
|
||||
set
|
||||
@@ -226,6 +224,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);
|
||||
@@ -236,7 +238,7 @@ namespace Facebook.Yoga
|
||||
{
|
||||
get
|
||||
{
|
||||
return Native.YGNodeStyleGetPadding(_ygNode, YogaEdge.Left);
|
||||
return YogaValue.MarshalValue(Native.YGNodeStyleGetPadding(_ygNode, YogaEdge.Left));
|
||||
}
|
||||
|
||||
set
|
||||
@@ -249,7 +251,7 @@ namespace Facebook.Yoga
|
||||
{
|
||||
get
|
||||
{
|
||||
return Native.YGNodeStyleGetPadding(_ygNode, YogaEdge.Top);
|
||||
return YogaValue.MarshalValue(Native.YGNodeStyleGetPadding(_ygNode, YogaEdge.Top));
|
||||
}
|
||||
|
||||
set
|
||||
@@ -262,7 +264,7 @@ namespace Facebook.Yoga
|
||||
{
|
||||
get
|
||||
{
|
||||
return Native.YGNodeStyleGetPadding(_ygNode, YogaEdge.Right);
|
||||
return YogaValue.MarshalValue(Native.YGNodeStyleGetPadding(_ygNode, YogaEdge.Right));
|
||||
}
|
||||
|
||||
set
|
||||
@@ -275,7 +277,7 @@ namespace Facebook.Yoga
|
||||
{
|
||||
get
|
||||
{
|
||||
return Native.YGNodeStyleGetPadding(_ygNode, YogaEdge.Bottom);
|
||||
return YogaValue.MarshalValue(Native.YGNodeStyleGetPadding(_ygNode, YogaEdge.Bottom));
|
||||
}
|
||||
|
||||
set
|
||||
@@ -288,7 +290,7 @@ namespace Facebook.Yoga
|
||||
{
|
||||
get
|
||||
{
|
||||
return Native.YGNodeStyleGetPadding(_ygNode, YogaEdge.Start);
|
||||
return YogaValue.MarshalValue(Native.YGNodeStyleGetPadding(_ygNode, YogaEdge.Start));
|
||||
}
|
||||
|
||||
set
|
||||
@@ -301,7 +303,7 @@ namespace Facebook.Yoga
|
||||
{
|
||||
get
|
||||
{
|
||||
return Native.YGNodeStyleGetPadding(_ygNode, YogaEdge.End);
|
||||
return YogaValue.MarshalValue(Native.YGNodeStyleGetPadding(_ygNode, YogaEdge.End));
|
||||
}
|
||||
|
||||
set
|
||||
@@ -314,7 +316,7 @@ namespace Facebook.Yoga
|
||||
{
|
||||
get
|
||||
{
|
||||
return Native.YGNodeStyleGetPadding(_ygNode, YogaEdge.Horizontal);
|
||||
return YogaValue.MarshalValue(Native.YGNodeStyleGetPadding(_ygNode, YogaEdge.Horizontal));
|
||||
}
|
||||
|
||||
set
|
||||
@@ -327,7 +329,7 @@ namespace Facebook.Yoga
|
||||
{
|
||||
get
|
||||
{
|
||||
return Native.YGNodeStyleGetPadding(_ygNode, YogaEdge.Vertical);
|
||||
return YogaValue.MarshalValue(Native.YGNodeStyleGetPadding(_ygNode, YogaEdge.Vertical));
|
||||
}
|
||||
|
||||
set
|
||||
@@ -340,7 +342,7 @@ namespace Facebook.Yoga
|
||||
{
|
||||
get
|
||||
{
|
||||
return Native.YGNodeStyleGetPadding(_ygNode, YogaEdge.All);
|
||||
return YogaValue.MarshalValue(Native.YGNodeStyleGetPadding(_ygNode, YogaEdge.All));
|
||||
}
|
||||
|
||||
set
|
||||
|
@@ -12,18 +12,34 @@ using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
#if (UNITY_IOS && !UNITY_EDITOR) || ENABLE_IL2CPP || __IOS__
|
||||
using System.Runtime.InteropServices;
|
||||
#endif
|
||||
#if __IOS__
|
||||
using ObjCRuntime;
|
||||
#endif
|
||||
#if ENABLE_IL2CPP
|
||||
using AOT;
|
||||
#endif
|
||||
|
||||
namespace Facebook.Yoga
|
||||
{
|
||||
public partial class YogaNode : IEnumerable<YogaNode>
|
||||
{
|
||||
private Native.YGNodeHandle _ygNode;
|
||||
private readonly Native.YGNodeHandle _ygNode;
|
||||
private readonly YogaConfig _config;
|
||||
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) || ENABLE_IL2CPP || __IOS__
|
||||
private static YogaMeasureFunc _managedMeasure;
|
||||
private static YogaBaselineFunc _managedBaseline;
|
||||
#else
|
||||
private YogaMeasureFunc _managedMeasure;
|
||||
private YogaBaselineFunc _managedBaseline;
|
||||
#endif
|
||||
|
||||
public YogaNode()
|
||||
{
|
||||
@@ -36,8 +52,27 @@ namespace Facebook.Yoga
|
||||
}
|
||||
}
|
||||
|
||||
public YogaNode(YogaConfig config)
|
||||
{
|
||||
YogaLogger.Initialize();
|
||||
|
||||
if (config != null)
|
||||
{
|
||||
_config = config;
|
||||
_ygNode = Native.YGNodeNewWithConfig(_config.Handle);
|
||||
}
|
||||
else
|
||||
{
|
||||
_ygNode = Native.YGNodeNew();
|
||||
}
|
||||
if (_ygNode.IsInvalid)
|
||||
{
|
||||
throw new InvalidOperationException("Failed to allocate native memory");
|
||||
}
|
||||
}
|
||||
|
||||
public YogaNode(YogaNode srcNode)
|
||||
: this()
|
||||
: this(srcNode._config)
|
||||
{
|
||||
CopyStyle(srcNode);
|
||||
}
|
||||
@@ -49,6 +84,9 @@ namespace Facebook.Yoga
|
||||
_data = null;
|
||||
|
||||
Native.YGNodeReset(_ygNode);
|
||||
#if (UNITY_IOS && !UNITY_EDITOR) || ENABLE_IL2CPP || __IOS__
|
||||
_ygNode.ReleaseManaged();
|
||||
#endif
|
||||
}
|
||||
|
||||
public bool IsDirty
|
||||
@@ -261,7 +299,7 @@ namespace Facebook.Yoga
|
||||
{
|
||||
get
|
||||
{
|
||||
return Native.YGNodeStyleGetFlexBasis(_ygNode);
|
||||
return YogaValue.MarshalValue(Native.YGNodeStyleGetFlexBasis(_ygNode));
|
||||
}
|
||||
|
||||
set
|
||||
@@ -270,6 +308,10 @@ namespace Facebook.Yoga
|
||||
{
|
||||
Native.YGNodeStyleSetFlexBasisPercent(_ygNode, value.Value);
|
||||
}
|
||||
else if (value.Unit == YogaUnit.Auto)
|
||||
{
|
||||
Native.YGNodeStyleSetFlexBasisAuto(_ygNode);
|
||||
}
|
||||
else
|
||||
{
|
||||
Native.YGNodeStyleSetFlexBasis(_ygNode, value.Value);
|
||||
@@ -281,7 +323,7 @@ namespace Facebook.Yoga
|
||||
{
|
||||
get
|
||||
{
|
||||
return Native.YGNodeStyleGetWidth(_ygNode);
|
||||
return YogaValue.MarshalValue(Native.YGNodeStyleGetWidth(_ygNode));
|
||||
}
|
||||
|
||||
set
|
||||
@@ -290,6 +332,10 @@ namespace Facebook.Yoga
|
||||
{
|
||||
Native.YGNodeStyleSetWidthPercent(_ygNode, value.Value);
|
||||
}
|
||||
else if (value.Unit == YogaUnit.Auto)
|
||||
{
|
||||
Native.YGNodeStyleSetWidthAuto(_ygNode);
|
||||
}
|
||||
else
|
||||
{
|
||||
Native.YGNodeStyleSetWidth(_ygNode, value.Value);
|
||||
@@ -301,7 +347,7 @@ namespace Facebook.Yoga
|
||||
{
|
||||
get
|
||||
{
|
||||
return Native.YGNodeStyleGetHeight(_ygNode);
|
||||
return YogaValue.MarshalValue(Native.YGNodeStyleGetHeight(_ygNode));
|
||||
}
|
||||
|
||||
set
|
||||
@@ -310,6 +356,10 @@ namespace Facebook.Yoga
|
||||
{
|
||||
Native.YGNodeStyleSetHeightPercent(_ygNode, value.Value);
|
||||
}
|
||||
else if (value.Unit == YogaUnit.Auto)
|
||||
{
|
||||
Native.YGNodeStyleSetHeightAuto(_ygNode);
|
||||
}
|
||||
else
|
||||
{
|
||||
Native.YGNodeStyleSetHeight(_ygNode, value.Value);
|
||||
@@ -321,7 +371,7 @@ namespace Facebook.Yoga
|
||||
{
|
||||
get
|
||||
{
|
||||
return Native.YGNodeStyleGetMaxWidth(_ygNode);
|
||||
return YogaValue.MarshalValue(Native.YGNodeStyleGetMaxWidth(_ygNode));
|
||||
}
|
||||
|
||||
set
|
||||
@@ -341,7 +391,7 @@ namespace Facebook.Yoga
|
||||
{
|
||||
get
|
||||
{
|
||||
return Native.YGNodeStyleGetMaxHeight(_ygNode);
|
||||
return YogaValue.MarshalValue(Native.YGNodeStyleGetMaxHeight(_ygNode));
|
||||
}
|
||||
|
||||
set
|
||||
@@ -361,7 +411,7 @@ namespace Facebook.Yoga
|
||||
{
|
||||
get
|
||||
{
|
||||
return Native.YGNodeStyleGetMinWidth(_ygNode);
|
||||
return YogaValue.MarshalValue(Native.YGNodeStyleGetMinWidth(_ygNode));
|
||||
}
|
||||
|
||||
set
|
||||
@@ -381,7 +431,7 @@ namespace Facebook.Yoga
|
||||
{
|
||||
get
|
||||
{
|
||||
return Native.YGNodeStyleGetMinHeight(_ygNode);
|
||||
return YogaValue.MarshalValue(Native.YGNodeStyleGetMinHeight(_ygNode));
|
||||
}
|
||||
|
||||
set
|
||||
@@ -397,7 +447,7 @@ namespace Facebook.Yoga
|
||||
}
|
||||
}
|
||||
|
||||
public float StyleAspectRatio
|
||||
public float AspectRatio
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -526,6 +576,20 @@ namespace Facebook.Yoga
|
||||
Native.YGNodeRemoveChild(_ygNode, child._ygNode);
|
||||
}
|
||||
|
||||
public void AddChild(YogaNode child)
|
||||
{
|
||||
Insert(Count, child);
|
||||
}
|
||||
|
||||
public void RemoveChild(YogaNode child)
|
||||
{
|
||||
int index = IndexOf(child);
|
||||
if (index >= 0)
|
||||
{
|
||||
RemoveAt(index);
|
||||
}
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
if (_children != null)
|
||||
@@ -545,15 +609,39 @@ 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) || ENABLE_IL2CPP || __IOS__
|
||||
_managedMeasure = MeasureInternalAOT;
|
||||
_ygNode.SetContext(this);
|
||||
#else
|
||||
_managedMeasure = MeasureInternal;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
_managedMeasure = null;
|
||||
}
|
||||
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) || ENABLE_IL2CPP || __IOS__
|
||||
_managedBaseline = BaselineInternalAOT;
|
||||
_ygNode.SetContext(this);
|
||||
#else
|
||||
_managedBaseline = BaselineInternal;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
_managedBaseline = null;
|
||||
}
|
||||
Native.YGNodeSetBaselineFunc(_ygNode, _managedBaseline);
|
||||
}
|
||||
|
||||
public void CalculateLayout()
|
||||
@@ -565,6 +653,20 @@ namespace Facebook.Yoga
|
||||
Native.YGNodeStyleGetDirection(_ygNode));
|
||||
}
|
||||
|
||||
#if (UNITY_IOS && !UNITY_EDITOR) || ENABLE_IL2CPP || __IOS__
|
||||
[MonoPInvokeCallback(typeof(YogaMeasureFunc))]
|
||||
private static YogaSize MeasureInternalAOT(
|
||||
IntPtr ygNodePtr,
|
||||
float width,
|
||||
YogaMeasureMode widthMode,
|
||||
float height,
|
||||
YogaMeasureMode heightMode)
|
||||
{
|
||||
var node = Native.YGNodeHandle.GetManaged(ygNodePtr);
|
||||
return node.MeasureInternal(IntPtr.Zero, width, widthMode, height, heightMode);
|
||||
}
|
||||
#endif
|
||||
|
||||
private YogaSize MeasureInternal(
|
||||
IntPtr node,
|
||||
float width,
|
||||
@@ -580,6 +682,18 @@ namespace Facebook.Yoga
|
||||
return _measureFunction(this, width, widthMode, height, heightMode);
|
||||
}
|
||||
|
||||
#if (UNITY_IOS && !UNITY_EDITOR) || ENABLE_IL2CPP || __IOS__
|
||||
[MonoPInvokeCallback(typeof(YogaBaselineFunc))]
|
||||
private static float BaselineInternalAOT(
|
||||
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)
|
||||
@@ -617,17 +731,5 @@ namespace Facebook.Yoga
|
||||
{
|
||||
return Native.YGNodeGetInstanceCount();
|
||||
}
|
||||
|
||||
public static void SetExperimentalFeatureEnabled(
|
||||
YogaExperimentalFeature feature,
|
||||
bool enabled)
|
||||
{
|
||||
Native.YGSetExperimentalFeatureEnabled(feature, enabled);
|
||||
}
|
||||
|
||||
public static bool IsExperimentalFeatureEnabled(YogaExperimentalFeature feature)
|
||||
{
|
||||
return Native.YGIsExperimentalFeatureEnabled(feature);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -9,6 +9,7 @@
|
||||
|
||||
namespace Facebook.Yoga
|
||||
{
|
||||
[System.Flags]
|
||||
public enum YogaPrintOptions
|
||||
{
|
||||
Layout = 1,
|
||||
|
@@ -12,7 +12,8 @@ namespace Facebook.Yoga
|
||||
public enum YogaUnit
|
||||
{
|
||||
Undefined,
|
||||
Pixel,
|
||||
Point,
|
||||
Percent,
|
||||
Auto,
|
||||
}
|
||||
}
|
||||
|
@@ -7,6 +7,7 @@
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Facebook.Yoga
|
||||
@@ -33,12 +34,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 +71,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 +89,21 @@ namespace Facebook.Yoga
|
||||
};
|
||||
}
|
||||
|
||||
public static implicit operator YogaValue(float pixelValue)
|
||||
public static implicit operator YogaValue(float pointValue)
|
||||
{
|
||||
return Pixel(pixelValue);
|
||||
return Point(pointValue);
|
||||
}
|
||||
|
||||
#if WINDOWS_UWP_ARM
|
||||
internal static YogaValue MarshalValue(IntPtr ptr)
|
||||
{
|
||||
return Marshal.PtrToStructure<YogaValue>(ptr);
|
||||
}
|
||||
#else
|
||||
internal static YogaValue MarshalValue(YogaValue value)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@@ -13,5 +13,6 @@ namespace Facebook.Yoga
|
||||
{
|
||||
NoWrap,
|
||||
Wrap,
|
||||
WrapReverse,
|
||||
}
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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>
|
@@ -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>
|
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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>
|
@@ -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
2
csharp/Mac/run-tests.sh
Executable 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
|
@@ -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>
|
@@ -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">
|
||||
|
@@ -129,15 +129,18 @@
|
||||
<Name>Facebook.Yoga</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' < '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>
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user