Merge "Relayout again for LTR / RTL order when layout direction is changed." into...
authorjoogab yun <joogab.yun@samsung.com>
Mon, 26 Nov 2018 05:15:22 +0000 (05:15 +0000)
committerGerrit Code Review <gerrit@review.ap-northeast-2.compute.internal>
Mon, 26 Nov 2018 05:15:22 +0000 (05:15 +0000)
42 files changed:
README.md
automated-tests/resources/insta_camera.json [new file with mode: 0644]
automated-tests/src/dali-toolkit-internal/utc-Dali-Visuals-internal.cpp
automated-tests/src/dali-toolkit/CMakeLists.txt
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-adaptor.cpp
automated-tests/src/dali-toolkit/utc-Dali-AnimatedVectorImageVisual.cpp [new file with mode: 0644]
automated-tests/src/dali-toolkit/utc-Dali-LayoutingAnimation.cpp
automated-tests/src/dali-toolkit/utc-Dali-LayoutingNesting.cpp
dali-toolkit/devel-api/file.list
dali-toolkit/devel-api/layouting/layout-controller.cpp
dali-toolkit/devel-api/layouting/layout-controller.h
dali-toolkit/devel-api/layouting/layout-group-impl.cpp
dali-toolkit/devel-api/layouting/layout-item-impl.cpp
dali-toolkit/devel-api/layouting/layout-item-impl.h
dali-toolkit/devel-api/layouting/layout-item.cpp
dali-toolkit/devel-api/layouting/layout-item.h
dali-toolkit/devel-api/layouting/layout-transition-data.cpp
dali-toolkit/devel-api/layouting/layout-transition-data.h
dali-toolkit/devel-api/visuals/animated-vector-image-visual-actions-devel.h [new file with mode: 0644]
dali-toolkit/devel-api/visuals/visual-properties-devel.h
dali-toolkit/internal/controls/scene3d-view/scene3d-view-impl.cpp
dali-toolkit/internal/file.list
dali-toolkit/internal/layouting/layout-controller-impl.cpp
dali-toolkit/internal/layouting/layout-controller-impl.h
dali-toolkit/internal/layouting/layout-group-data-impl.cpp
dali-toolkit/internal/layouting/layout-group-data-impl.h
dali-toolkit/internal/layouting/layout-item-data-impl.h
dali-toolkit/internal/layouting/layout-transition-data-impl.cpp
dali-toolkit/internal/layouting/layout-transition-data-impl.h
dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.cpp [new file with mode: 0644]
dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.h [new file with mode: 0644]
dali-toolkit/internal/visuals/animated-vector-image/vector-image-rasterize-thread.cpp [new file with mode: 0644]
dali-toolkit/internal/visuals/animated-vector-image/vector-image-rasterize-thread.h [new file with mode: 0644]
dali-toolkit/internal/visuals/visual-factory-impl.cpp
dali-toolkit/internal/visuals/visual-string-constants.cpp
dali-toolkit/internal/visuals/visual-url.cpp
dali-toolkit/internal/visuals/visual-url.h
dali-toolkit/public-api/dali-toolkit-version.cpp
docs/content/main.md
docs/content/programming-guide/viewing-modes.h [deleted file]
node-addon/dali-addon.cpp
packaging/dali-toolkit.spec

index 0c20358..01c32a9 100644 (file)
--- a/README.md
+++ b/README.md
 
 ## 1. Building for Ubuntu desktop
 
-### Minimum Requirements
+### Requirements
 
  - Ubuntu 14.04 or later
  - Environment created using dali_env script in dali-core repository
+ - GCC version 6
+
+DALi requires a compiler supporting C++11 features.
+Ubuntu 16.04 is the first version to offer this by default (GCC v5.4.0).
+
+GCC version 6 is recommended since it has fixes for issues in version 5
+e.g. it avoids spurious 'defined but not used' warnings in header files.
 
 ### Building the Repository
 
diff --git a/automated-tests/resources/insta_camera.json b/automated-tests/resources/insta_camera.json
new file mode 100644 (file)
index 0000000..945c3b2
--- /dev/null
@@ -0,0 +1 @@
+{"v":"5.0.1","fr":30.0000305175781,"ip":0,"op":124.000126139323,"w":800,"h":600,"nm":"Camera_003_render","ddd":0,"assets":[{"id":"comp_4","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"flash ring","parent":19,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[133,-67,0],"ix":2},"a":{"a":0,"k":[74,-135,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.09,0.09],"y":[1,1]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p09_1_0p167_0p167","0p09_1_0p167_0p167"],"t":73,"s":[0,0],"e":[148,148]},{"t":79.0000803629557}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.992156982422,1,0.988234994926,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.09],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p09_1_0p167_0p167"],"t":73,"s":[23],"e":[0]},{"t":82.0000834147135}],"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[74,-135],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":73.0000742594401,"op":83.0000844319661,"st":73.0000742594401,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"button lines","parent":19,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-35.5,-60.5,0],"ix":2},"a":{"a":0,"k":[72.5,-149.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[91,-152.25],[108,-160.75]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.992156982422,1,0.988234994926,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 5","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[60.25,-161.75],[49,-177.25]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.992156982422,1,0.988234994926,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[4.25,2.75],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 6","np":3,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[73.75,-162.5],[80.75,-179]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.992156982422,1,0.988234994926,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[4.25,2.75],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 4","np":3,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[53,-150.5],[34.25,-159.5]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.992156982422,1,0.988234994926,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 2","np":3,"cix":2,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.08],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p08_1_0p167_0p167"],"t":73.539,"s":[0],"e":[100]},{"t":80.0000813802083}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.08],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p08_1_0p167_0p167"],"t":71,"s":[0],"e":[100]},{"t":80.0000813802083}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":5,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":71.0000722249349,"op":81.0000823974609,"st":71.0000722249349,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"flash light","parent":19,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":71,"s":[35.264],"e":[102.264]},{"t":80.0000813802083}],"ix":10},"p":{"a":0,"k":[132,-68,0],"ix":2},"a":{"a":0,"k":[-340,-162,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"sr","sy":1,"d":1,"pt":{"a":0,"k":4,"ix":3},"p":{"a":0,"k":[0,0],"ix":4},"r":{"a":0,"k":143.286,"ix":5},"ir":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":71,"s":[0],"e":[25]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":76,"s":[25],"e":[0]},{"t":80.0000813802083}],"ix":6},"is":{"a":0,"k":193,"ix":8},"or":{"a":0,"k":73.6,"ix":7},"os":{"a":0,"k":0,"ix":9},"ix":1,"nm":"Polystar Path 1","mn":"ADBE Vector Shape - Star","hd":false},{"ty":"st","c":{"a":0,"k":[0.992156982422,1,0.988234994926,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.992156862745,1,0.988235294118,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-340,-162],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Polystar 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":71.0000722249349,"op":81.0000823974609,"st":71.0000722249349,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"face button mask","parent":19,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.45],"y":[0]},"n":["0p833_0p833_0p45_0"],"t":0,"s":[0],"e":[-90]},{"t":17.0000172932943}],"ix":10,"x":"var $bm_rt;\nvar amp, freq, decay, n, t;\ntry {\n    amp = div(effect('Rotation - Overshoot')('ADBE Slider Control-0001'), 2.5), freq = div(effect('Rotation - Bounce')('ADBE Slider Control-0001'), 20), decay = div(effect('Rotation - Friction')('ADBE Slider Control-0001'), 20), n = 0, 0 < numKeys && (n = nearestKey(time).index, key(n).time > time && n--), t = 0 === n ? 0 : time - key(n).time, $bm_rt = 0 < n ? (v = velocityAtTime(sub(key(n).time, div(thisComp.frameDuration, 10))), sum(value, div(mul(mul(div(v, 100), amp), Math.sin(mul(mul(mul(freq, t), 2), Math.PI))), Math.exp(mul(decay, t))))) : value;\n} catch (e$$4) {\n    $bm_rt = value = value;\n}"},"p":{"a":0,"k":[60,60,0],"ix":2},"a":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":-27,"s":[-2,-6.5,0],"e":[-2,-6.5,0],"to":[0,0,0],"ti":[0,0,0]},{"t":56,"s":[-2,-6.5,0],"h":1},{"t":66.0000671386719,"s":[-2,-6.5,0],"h":1}],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"Rotation - Overshoot","np":3,"mn":"ADBE Slider Control","ix":1,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":10,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]},{"ty":5,"nm":"Rotation - Bounce","np":3,"mn":"ADBE Slider Control","ix":2,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":30,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]},{"ty":5,"nm":"Rotation - Friction","np":3,"mn":"ADBE Slider Control","ix":3,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":126,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]}],"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":1,"k":[{"i":{"x":[0.14,0.14],"y":[1,1]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p14_1_0p167_0p167","0p14_1_0p167_0p167"],"t":-27,"s":[0,0],"e":[200,1]},{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.45,0.45],"y":[0,0]},"n":["0p833_0p833_0p45_0","0p833_0p833_0p45_0"],"t":0,"s":[200,1],"e":[216,302]},{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":17,"s":[216,302],"e":[216,302]},{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":101,"s":[216,302],"e":[0,302]},{"t":110.000111897786}],"ix":2,"x":"var $bm_rt;\n$bm_rt = thisComp.layer('body').content('Rectangle 1').content('Rectangle Path 1').size;"},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":20,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.992156982422,1,0.988234994926,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.204152006261,0.019608000213,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-2,-6.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":124.000126139323,"st":-27.0000274658203,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"face button","parent":20,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":89.999,"ix":10},"p":{"a":0,"k":[34.724,96.498,0],"ix":2},"a":{"a":0,"k":[3,4,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.35,0.35],"y":[1,1]},"o":{"x":[0.54,0.54],"y":[0,0]},"n":["0p35_1_0p54_0","0p35_1_0p54_0"],"t":28,"s":[0,0],"e":[32,32]},{"i":{"x":[0.833,0.833],"y":[1,1]},"o":{"x":[0.167,0.167],"y":[0,0]},"n":["0p833_1_0p167_0","0p833_1_0p167_0"],"t":48,"s":[32,32],"e":[32,32]},{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.53,0.53],"y":[0,0]},"n":["0p833_0p833_0p53_0","0p833_0p833_0p53_0"],"t":97,"s":[32,32],"e":[105,105]},{"t":135.000137329102}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.992156982422,1,0.988234994926,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[3,4],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":28.0000284830729,"op":124.000126139323,"st":28.0000284830729,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"line mask","parent":19,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.45],"y":[0]},"n":["0p833_0p833_0p45_0"],"t":0,"s":[0],"e":[-90]},{"t":17.0000172932943}],"ix":10,"x":"var $bm_rt;\nvar amp, freq, decay, n, t;\ntry {\n    amp = div(effect('Rotation - Overshoot')('ADBE Slider Control-0001'), 2.5), freq = div(effect('Rotation - Bounce')('ADBE Slider Control-0001'), 20), decay = div(effect('Rotation - Friction')('ADBE Slider Control-0001'), 20), n = 0, 0 < numKeys && (n = nearestKey(time).index, key(n).time > time && n--), t = 0 === n ? 0 : time - key(n).time, $bm_rt = 0 < n ? (v = velocityAtTime(sub(key(n).time, div(thisComp.frameDuration, 10))), sum(value, div(mul(mul(div(v, 100), amp), Math.sin(mul(mul(mul(freq, t), 2), Math.PI))), Math.exp(mul(decay, t))))) : value;\n} catch (e$$4) {\n    $bm_rt = value = value;\n}"},"p":{"a":0,"k":[60,60,0],"ix":2},"a":{"a":0,"k":[-2,-6.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"Rotation - Overshoot","np":3,"mn":"ADBE Slider Control","ix":1,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":10,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]},{"ty":5,"nm":"Rotation - Bounce","np":3,"mn":"ADBE Slider Control","ix":2,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":30,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]},{"ty":5,"nm":"Rotation - Friction","np":3,"mn":"ADBE Slider Control","ix":3,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":126,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]}],"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":1,"k":[{"i":{"x":[0.14,0.14],"y":[1,1]},"o":{"x":[0.54,0.54],"y":[0,0]},"n":["0p14_1_0p54_0","0p14_1_0p54_0"],"t":-27,"s":[0,0],"e":[200,1]},{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.45,0.45],"y":[0,0]},"n":["0p833_0p833_0p45_0","0p833_0p833_0p45_0"],"t":0,"s":[200,1],"e":[216,302]},{"t":17.0000172932943}],"ix":2,"x":"var $bm_rt;\n$bm_rt = thisComp.layer('body').content('Rectangle 1').content('Rectangle Path 1').size;"},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":20,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.992156982422,1,0.988234994926,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.929412004059,0.929412004059,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-2,-6.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":124.000126139323,"st":-27.0000274658203,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"line","parent":20,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":90.084,"ix":10},"p":{"a":0,"k":[68.999,-5.896,0],"ix":2},"a":{"a":0,"k":[0.5,-56,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-171.5,-56],[165.5,-56]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.59],"y":[1]},"o":{"x":[0.29],"y":[0]},"n":["0p59_1_0p29_0"],"t":16,"s":[50],"e":[0]},{"t":33.0000335693359}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.59],"y":[1]},"o":{"x":[0.29],"y":[0]},"n":["0p59_1_0p29_0"],"t":16,"s":[50],"e":[100]},{"t":33.0000335693359}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[0.992156982422,1,0.988234994926,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.929412004059,0.929412004059,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":4,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":16.0000162760417,"op":124.000126139323,"st":16.0000162760417,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"flash mask","parent":19,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.45],"y":[0]},"n":["0p833_0p833_0p45_0"],"t":0,"s":[0],"e":[-90]},{"t":17.0000172932943}],"ix":10,"x":"var $bm_rt;\nvar amp, freq, decay, n, t;\ntry {\n    amp = div(effect('Rotation - Overshoot')('ADBE Slider Control-0001'), 2.5), freq = div(effect('Rotation - Bounce')('ADBE Slider Control-0001'), 20), decay = div(effect('Rotation - Friction')('ADBE Slider Control-0001'), 20), n = 0, 0 < numKeys && (n = nearestKey(time).index, key(n).time > time && n--), t = 0 === n ? 0 : time - key(n).time, $bm_rt = 0 < n ? (v = velocityAtTime(sub(key(n).time, div(thisComp.frameDuration, 10))), sum(value, div(mul(mul(div(v, 100), amp), Math.sin(mul(mul(mul(freq, t), 2), Math.PI))), Math.exp(mul(decay, t))))) : value;\n} catch (e$$4) {\n    $bm_rt = value = value;\n}"},"p":{"a":0,"k":[60,60,0],"ix":2},"a":{"a":0,"k":[-2,-6.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"Rotation - Overshoot","np":3,"mn":"ADBE Slider Control","ix":1,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":10,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]},{"ty":5,"nm":"Rotation - Bounce","np":3,"mn":"ADBE Slider Control","ix":2,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":30,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]},{"ty":5,"nm":"Rotation - Friction","np":3,"mn":"ADBE Slider Control","ix":3,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":126,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]}],"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":1,"k":[{"i":{"x":[0.14,0.14],"y":[1,1]},"o":{"x":[0.54,0.54],"y":[0,0]},"n":["0p14_1_0p54_0","0p14_1_0p54_0"],"t":-27,"s":[0,0],"e":[200,1]},{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.45,0.45],"y":[0,0]},"n":["0p833_0p833_0p45_0","0p833_0p833_0p45_0"],"t":0,"s":[200,1],"e":[216,302]},{"t":17.0000172932943}],"ix":2,"x":"var $bm_rt;\n$bm_rt = thisComp.layer('body').content('Rectangle 1').content('Rectangle Path 1').size;"},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":20,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.992156982422,1,0.988234994926,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.929412004059,0.929412004059,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-2,-6.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":124.000126139323,"st":-27.0000274658203,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"button","parent":20,"tt":2,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":90.004,"ix":10},"p":{"s":true,"x":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":29,"s":[70.511],"e":[102.512]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":47,"s":[102.512],"e":[102.512]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":71,"s":[102.512],"e":[92.512]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":74,"s":[92.512],"e":[102.512]},{"i":{"x":[0.823],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p823_1_0p167_0"],"t":77,"s":[102.512],"e":[102.512]},{"i":{"x":[0.745],"y":[1]},"o":{"x":[1],"y":[-0.47]},"n":["0p745_1_1_-0p47"],"t":93,"s":[102.512],"e":[72.512]},{"t":105.000106811523}],"ix":3,"x":"var $bm_rt;\nvar amp, freq, decay, n, t;\ntry {\n    amp = div(effect('X Position - Overshoot')('ADBE Slider Control-0001'), 2.5), freq = div(effect('X Position - Bounce')('ADBE Slider Control-0001'), 20), decay = div(effect('X Position - Friction')('ADBE Slider Control-0001'), 20), n = 0, 0 < numKeys && (n = nearestKey(time).index, key(n).time > time && n--), t = 0 === n ? 0 : time - key(n).time, $bm_rt = 0 < n ? (v = velocityAtTime(sub(key(n).time, div(thisComp.frameDuration, 10))), sum(value, div(mul(mul(div(v, 100), amp), Math.sin(mul(mul(mul(freq, t), 2), Math.PI))), Math.exp(mul(decay, t))))) : value;\n} catch (e$$4) {\n    $bm_rt = value = value;\n}"},"y":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":29,"s":[-176.891],"e":[-176.421]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":47,"s":[-176.421],"e":[-176.421]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":71,"s":[-176.421],"e":[-176.421]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":74,"s":[-176.421],"e":[-176.421]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":77,"s":[-176.421],"e":[-176.421]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":93,"s":[-176.421],"e":[-176.421]},{"t":105.000106811523}],"ix":4}},"a":{"a":0,"k":[94,-107.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"X Position - Overshoot","np":3,"mn":"ADBE Slider Control","ix":1,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":10,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]},{"ty":5,"nm":"X Position - Bounce","np":3,"mn":"ADBE Slider Control","ix":2,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":30,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]},{"ty":5,"nm":"X Position - Friction","np":3,"mn":"ADBE Slider Control","ix":3,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":100,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]}],"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[26,86],"ix":2},"p":{"a":0,"k":[74,24],"ix":3},"r":{"a":0,"k":24,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.992156982422,1,0.988234994926,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[94,-107.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":29.0000295003255,"op":106.000107828776,"st":29.0000295003255,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"body mask","parent":19,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.45],"y":[0]},"n":["0p833_0p833_0p45_0"],"t":0,"s":[0],"e":[-90]},{"t":17.0000172932943}],"ix":10,"x":"var $bm_rt;\nvar amp, freq, decay, n, t;\ntry {\n    amp = div(effect('Rotation - Overshoot')('ADBE Slider Control-0001'), 2.5), freq = div(effect('Rotation - Bounce')('ADBE Slider Control-0001'), 20), decay = div(effect('Rotation - Friction')('ADBE Slider Control-0001'), 20), n = 0, 0 < numKeys && (n = nearestKey(time).index, key(n).time > time && n--), t = 0 === n ? 0 : time - key(n).time, $bm_rt = 0 < n ? (v = velocityAtTime(sub(key(n).time, div(thisComp.frameDuration, 10))), sum(value, div(mul(mul(div(v, 100), amp), Math.sin(mul(mul(mul(freq, t), 2), Math.PI))), Math.exp(mul(decay, t))))) : value;\n} catch (e$$4) {\n    $bm_rt = value = value;\n}"},"p":{"a":0,"k":[60,60,0],"ix":2},"a":{"a":0,"k":[-2,-6.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"Rotation - Overshoot","np":3,"mn":"ADBE Slider Control","ix":1,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":10,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]},{"ty":5,"nm":"Rotation - Bounce","np":3,"mn":"ADBE Slider Control","ix":2,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":30,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]},{"ty":5,"nm":"Rotation - Friction","np":3,"mn":"ADBE Slider Control","ix":3,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":126,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]}],"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":1,"k":[{"i":{"x":[0.14,0.14],"y":[1,1]},"o":{"x":[0.54,0.54],"y":[0,0]},"n":["0p14_1_0p54_0","0p14_1_0p54_0"],"t":-27,"s":[0,0],"e":[200,1]},{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.45,0.45],"y":[0,0]},"n":["0p833_0p833_0p45_0","0p833_0p833_0p45_0"],"t":0,"s":[200,1],"e":[216,302]},{"t":17.0000172932943}],"ix":2,"x":"var $bm_rt;\n$bm_rt = thisComp.layer('body').content('Rectangle 1').content('Rectangle Path 1').size;"},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":20,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.992156982422,1,0.988234994926,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.929412004059,0.929412004059,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-2,-6.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":124.000126139323,"st":-27.0000274658203,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"flash","parent":20,"tt":2,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":90.004,"ix":10},"p":{"s":true,"x":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[71.498],"e":[129.499]},{"i":{"x":[0.885],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p885_1_0p167_0"],"t":39,"s":[129.499],"e":[129.499]},{"i":{"x":[0.683],"y":[1]},"o":{"x":[0.688],"y":[-0.339]},"n":["0p683_1_0p688_-0p339"],"t":99,"s":[129.499],"e":[69.499]},{"t":110.000111897786}],"ix":3,"x":"var $bm_rt;\nvar amp, freq, decay, n, t;\ntry {\n    amp = div(effect('X Position - Overshoot')('ADBE Slider Control-0001'), 2.5), freq = div(effect('X Position - Bounce')('ADBE Slider Control-0001'), 20), decay = div(effect('X Position - Friction')('ADBE Slider Control-0001'), 20), n = 0, 0 < numKeys && (n = nearestKey(time).index, key(n).time > time && n--), t = 0 === n ? 0 : time - key(n).time, $bm_rt = 0 < n ? (v = velocityAtTime(sub(key(n).time, div(thisComp.frameDuration, 10))), sum(value, div(mul(mul(div(v, 100), amp), Math.sin(mul(mul(mul(freq, t), 2), Math.PI))), Math.exp(mul(decay, t))))) : value;\n} catch (e$$4) {\n    $bm_rt = value = value;\n}"},"y":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.59],"y":[0]},"n":["0p833_0p833_0p59_0"],"t":27,"s":[-6.965],"e":[-6.42]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":39,"s":[-6.42],"e":[-6.42]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":99,"s":[-6.42],"e":[-6.42]},{"t":110.000111897786}],"ix":4,"x":"var $bm_rt;\nvar amp, freq, decay, n, t;\ntry {\n    amp = div(effect('Y Position - Overshoot')('ADBE Slider Control-0001'), 2.5), freq = div(effect('Y Position - Bounce')('ADBE Slider Control-0001'), 20), decay = div(effect('Y Position - Friction')('ADBE Slider Control-0001'), 20), n = 0, 0 < numKeys && (n = nearestKey(time).index, key(n).time > time && n--), t = 0 === n ? 0 : time - key(n).time, $bm_rt = 0 < n ? (v = velocityAtTime(sub(key(n).time, div(thisComp.frameDuration, 10))), sum(value, div(mul(mul(div(v, 100), amp), Math.sin(mul(mul(mul(freq, t), 2), Math.PI))), Math.exp(mul(decay, t))))) : value;\n} catch (e$$4) {\n    $bm_rt = value = value;\n}"}},"a":{"a":0,"k":[94,-107.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"Y Position - Overshoot","np":3,"mn":"ADBE Slider Control","ix":1,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":10,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]},{"ty":5,"nm":"Y Position - Bounce","np":3,"mn":"ADBE Slider Control","ix":2,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":30,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]},{"ty":5,"nm":"Y Position - Friction","np":3,"mn":"ADBE Slider Control","ix":3,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":100,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]},{"ty":5,"nm":"X Position - Overshoot","np":3,"mn":"ADBE Slider Control","ix":4,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":10,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]},{"ty":5,"nm":"X Position - Bounce","np":3,"mn":"ADBE Slider Control","ix":5,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":30,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]},{"ty":5,"nm":"X Position - Friction","np":3,"mn":"ADBE Slider Control","ix":6,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":100,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]}],"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[79,72.861],"ix":2},"p":{"a":0,"k":[72,22],"ix":3},"r":{"a":0,"k":9,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.992156982422,1,0.988234994926,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[94,-107.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":27.0000274658203,"op":107.000108846029,"st":27.0000274658203,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"lens mask 2","parent":19,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.45],"y":[0]},"n":["0p833_0p833_0p45_0"],"t":0,"s":[0],"e":[-90]},{"t":17.0000172932943}],"ix":10,"x":"var $bm_rt;\nvar amp, freq, decay, n, t;\ntry {\n    amp = div(effect('Rotation - Overshoot')('ADBE Slider Control-0001'), 2.5), freq = div(effect('Rotation - Bounce')('ADBE Slider Control-0001'), 20), decay = div(effect('Rotation - Friction')('ADBE Slider Control-0001'), 20), n = 0, 0 < numKeys && (n = nearestKey(time).index, key(n).time > time && n--), t = 0 === n ? 0 : time - key(n).time, $bm_rt = 0 < n ? (v = velocityAtTime(sub(key(n).time, div(thisComp.frameDuration, 10))), sum(value, div(mul(mul(div(v, 100), amp), Math.sin(mul(mul(mul(freq, t), 2), Math.PI))), Math.exp(mul(decay, t))))) : value;\n} catch (e$$4) {\n    $bm_rt = value = value;\n}"},"p":{"a":0,"k":[60,60,0],"ix":2},"a":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":-27,"s":[-2,-6.5,0],"e":[-2,-6.5,0],"to":[0,0,0],"ti":[0,0,0]},{"t":56,"s":[-2,-6.5,0],"h":1},{"t":66.0000671386719,"s":[-2,-6.5,0],"h":1}],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"Rotation - Overshoot","np":3,"mn":"ADBE Slider Control","ix":1,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":10,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]},{"ty":5,"nm":"Rotation - Bounce","np":3,"mn":"ADBE Slider Control","ix":2,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":30,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]},{"ty":5,"nm":"Rotation - Friction","np":3,"mn":"ADBE Slider Control","ix":3,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":126,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]}],"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":1,"k":[{"i":{"x":[0.14,0.14],"y":[1,1]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p14_1_0p167_0p167","0p14_1_0p167_0p167"],"t":-27,"s":[0,0],"e":[200,1]},{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.45,0.45],"y":[0,0]},"n":["0p833_0p833_0p45_0","0p833_0p833_0p45_0"],"t":0,"s":[200,1],"e":[216,302]},{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":17,"s":[216,302],"e":[216,302]},{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":101,"s":[216,302],"e":[0,302]},{"t":110.000111897786}],"ix":2,"x":"var $bm_rt;\n$bm_rt = thisComp.layer('body').content('Rectangle 1').content('Rectangle Path 1').size;"},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":20,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.992156982422,1,0.988234994926,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.204152006261,0.019608000213,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-2,-6.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":124.000126139323,"st":-27.0000274658203,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":"lens","parent":20,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":0,"k":[-22,-28.5,0],"ix":2},"a":{"a":0,"k":[3,4,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"Size - Ellipse Path 1 - Overshoot","np":3,"mn":"ADBE Slider Control","ix":1,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":10,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]},{"ty":5,"nm":"Size - Ellipse Path 1 - Bounce","np":3,"mn":"ADBE Slider Control","ix":2,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":30,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]},{"ty":5,"nm":"Size - Ellipse Path 1 - Friction","np":3,"mn":"ADBE Slider Control","ix":3,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":100,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]}],"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.54,0.54],"y":[0,0]},"n":["0p833_0p833_0p54_0","0p833_0p833_0p54_0"],"t":21,"s":[0,0],"e":[94,94]},{"i":{"x":[0.833,0.833],"y":[1,1]},"o":{"x":[0.167,0.167],"y":[0,0]},"n":["0p833_1_0p167_0","0p833_1_0p167_0"],"t":41,"s":[94,94],"e":[94,94]},{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.87,0.87],"y":[0,0]},"n":["0p833_0p833_0p87_0","0p833_0p833_0p87_0"],"t":97,"s":[94,94],"e":[183,183]},{"t":123.00012512207}],"ix":2,"x":"var $bm_rt;\nvar amp, freq, decay, n, t;\ntry {\n    amp = div(effect('Size - Ellipse Path 1 - Overshoot')('ADBE Slider Control-0001'), 2.5), freq = div(effect('Size - Ellipse Path 1 - Bounce')('ADBE Slider Control-0001'), 20), decay = div(effect('Size - Ellipse Path 1 - Friction')('ADBE Slider Control-0001'), 20), n = 0, 0 < numKeys && (n = nearestKey(time).index, key(n).time > time && n--), t = 0 === n ? 0 : time - key(n).time, $bm_rt = 0 < n ? (v = velocityAtTime(sub(key(n).time, div(thisComp.frameDuration, 10))), sum(value, div(mul(mul(div(v, 100), amp), Math.sin(mul(mul(mul(freq, t), 2), Math.PI))), Math.exp(mul(decay, t))))) : value;\n} catch (e$$4) {\n    $bm_rt = value = value;\n}"},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.992156982422,1,0.988234994926,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[3,4],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":21.0000213623047,"op":124.000126139323,"st":21.0000213623047,"bm":0},{"ddd":0,"ind":16,"ty":4,"nm":"lens mask","parent":19,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.45],"y":[0]},"n":["0p833_0p833_0p45_0"],"t":0,"s":[0],"e":[-90]},{"t":17.0000172932943}],"ix":10,"x":"var $bm_rt;\nvar amp, freq, decay, n, t;\ntry {\n    amp = div(effect('Rotation - Overshoot')('ADBE Slider Control-0001'), 2.5), freq = div(effect('Rotation - Bounce')('ADBE Slider Control-0001'), 20), decay = div(effect('Rotation - Friction')('ADBE Slider Control-0001'), 20), n = 0, 0 < numKeys && (n = nearestKey(time).index, key(n).time > time && n--), t = 0 === n ? 0 : time - key(n).time, $bm_rt = 0 < n ? (v = velocityAtTime(sub(key(n).time, div(thisComp.frameDuration, 10))), sum(value, div(mul(mul(div(v, 100), amp), Math.sin(mul(mul(mul(freq, t), 2), Math.PI))), Math.exp(mul(decay, t))))) : value;\n} catch (e$$4) {\n    $bm_rt = value = value;\n}"},"p":{"a":0,"k":[60,60,0],"ix":2},"a":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":-27,"s":[-2,-6.5,0],"e":[-2,-6.5,0],"to":[0,0,0],"ti":[0,0,0]},{"t":56,"s":[-2,-6.5,0],"h":1},{"t":66.0000671386719,"s":[-2,-6.5,0],"h":1}],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"Rotation - Overshoot","np":3,"mn":"ADBE Slider Control","ix":1,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":10,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]},{"ty":5,"nm":"Rotation - Bounce","np":3,"mn":"ADBE Slider Control","ix":2,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":30,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]},{"ty":5,"nm":"Rotation - Friction","np":3,"mn":"ADBE Slider Control","ix":3,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":126,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]}],"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":1,"k":[{"i":{"x":[0.14,0.14],"y":[1,1]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p14_1_0p167_0p167","0p14_1_0p167_0p167"],"t":-27,"s":[0,0],"e":[200,1]},{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.45,0.45],"y":[0,0]},"n":["0p833_0p833_0p45_0","0p833_0p833_0p45_0"],"t":0,"s":[200,1],"e":[216,302]},{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":17,"s":[216,302],"e":[216,302]},{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":101,"s":[216,302],"e":[0,302]},{"t":110.000111897786}],"ix":2,"x":"var $bm_rt;\n$bm_rt = thisComp.layer('body').content('Rectangle 1').content('Rectangle Path 1').size;"},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":20,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.992156982422,1,0.988234994926,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.204152006261,0.019608000213,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-2,-6.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":124.000126139323,"st":-27.0000274658203,"bm":0},{"ddd":0,"ind":17,"ty":4,"nm":"lens","parent":20,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":0,"k":[-22,-28.5,0],"ix":2},"a":{"a":0,"k":[3,4,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"Size - Ellipse Path 1 - Overshoot","np":3,"mn":"ADBE Slider Control","ix":1,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":10,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]},{"ty":5,"nm":"Size - Ellipse Path 1 - Bounce","np":3,"mn":"ADBE Slider Control","ix":2,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":30,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]},{"ty":5,"nm":"Size - Ellipse Path 1 - Friction","np":3,"mn":"ADBE Slider Control","ix":3,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":100,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]}],"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.54,0.54],"y":[0,0]},"n":["0p833_0p833_0p54_0","0p833_0p833_0p54_0"],"t":15,"s":[0,0],"e":[136,136]},{"i":{"x":[0.833,0.833],"y":[1,1]},"o":{"x":[0.167,0.167],"y":[0,0]},"n":["0p833_1_0p167_0","0p833_1_0p167_0"],"t":35,"s":[136,136],"e":[136,136]},{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.87,0.87],"y":[0,0]},"n":["0p833_0p833_0p87_0","0p833_0p833_0p87_0"],"t":97,"s":[136,136],"e":[212,212]},{"t":123.00012512207}],"ix":2,"x":"var $bm_rt;\nvar amp, freq, decay, n, t;\ntry {\n    amp = div(effect('Size - Ellipse Path 1 - Overshoot')('ADBE Slider Control-0001'), 2.5), freq = div(effect('Size - Ellipse Path 1 - Bounce')('ADBE Slider Control-0001'), 20), decay = div(effect('Size - Ellipse Path 1 - Friction')('ADBE Slider Control-0001'), 20), n = 0, 0 < numKeys && (n = nearestKey(time).index, key(n).time > time && n--), t = 0 === n ? 0 : time - key(n).time, $bm_rt = 0 < n ? (v = velocityAtTime(sub(key(n).time, div(thisComp.frameDuration, 10))), sum(value, div(mul(mul(div(v, 100), amp), Math.sin(mul(mul(mul(freq, t), 2), Math.PI))), Math.exp(mul(decay, t))))) : value;\n} catch (e$$4) {\n    $bm_rt = value = value;\n}"},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.992156982422,1,0.988234994926,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[3,4],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":15.0000152587891,"op":124.000126139323,"st":15.0000152587891,"bm":0},{"ddd":0,"ind":18,"ty":4,"nm":".gannon-gram","cl":"gannon-gram","parent":20,"sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":90.004,"ix":10},"p":{"a":0,"k":[85.672,-6.451,0],"ix":2},"a":{"a":0,"k":[-0.257,-6.362,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-4.887],[-4.517,0],[-1.575,1.76],[0,0],[0,0],[0,0],[0,0],[0,0],[1.413,0],[0,2.919],[-2.803,0],[-0.718,-1.089],[0,0],[3.196,0]],"o":[[0,4.864],[2.803,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.672,0.602],[-2.803,0],[0,-2.919],[1.621,0],[0,0],[-1.181,-1.83],[-4.517,0]],"v":[[-101.849,-7.713],[-93.626,0.301],[-87.048,-2.617],[-87.048,-8.524],[-94.414,-8.524],[-94.414,-5.698],[-90.291,-5.698],[-90.291,-3.822],[-93.626,-2.641],[-98.467,-7.713],[-93.626,-12.786],[-89.966,-10.84],[-87.233,-12.323],[-93.626,-15.704]],"c":true},"ix":2},"nm":"G","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.988235294118,0.976470588235,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"G","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-69.614,0],[-66.024,0],[-71.976,-15.45],[-76.099,-15.45],[-82.075,0],[-78.462,0],[-77.489,-2.664],[-70.587,-2.664]],"c":true},"ix":2},"nm":"A","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-74.038,-12.601],[-71.49,-5.513],[-76.609,-5.513]],"c":true},"ix":2},"nm":"A","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.988235294118,0.976470588235,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"A","np":5,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-49.766,0],[-46.593,0],[-46.593,-15.45],[-49.882,-15.45],[-49.882,-5.443],[-57.039,-15.45],[-60.421,-15.45],[-60.421,0],[-57.132,0],[-57.132,-10.377]],"c":true},"ix":2},"nm":"N","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.988235294118,0.976470588235,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"N","np":3,"cix":2,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-28.721,0],[-25.548,0],[-25.548,-15.45],[-28.837,-15.45],[-28.837,-5.443],[-35.995,-15.45],[-39.376,-15.45],[-39.376,0],[-36.087,0],[-36.087,-10.377]],"c":true},"ix":2},"nm":"N","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.988235294118,0.976470588235,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"N","np":3,"cix":2,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-4.656],[-4.656,0],[0,4.656],[4.679,0]],"o":[[0,4.656],[4.679,0],[0,-4.656],[-4.656,0]],"v":[[-19.073,-7.713],[-11.012,0.278],[-2.928,-7.713],[-11.012,-15.704]],"c":true},"ix":2},"nm":"O","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,-2.895],[2.849,0],[0,2.872],[-2.849,0]],"o":[[0,2.872],[-2.849,0],[0,-2.895],[2.849,0]],"v":[[-6.31,-7.713],[-11.012,-2.641],[-15.691,-7.713],[-11.012,-12.786]],"c":true},"ix":2},"nm":"O","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.988235294118,0.976470588235,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"O","np":5,"cix":2,"ix":5,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[14.196,0],[17.37,0],[17.37,-15.45],[14.081,-15.45],[14.081,-5.443],[6.923,-15.45],[3.541,-15.45],[3.541,0],[6.831,0],[6.831,-10.377]],"c":true},"ix":2},"nm":"N","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.988235294118,0.976470588235,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"N","np":3,"cix":2,"ix":6,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-4.887],[-4.517,0],[-1.575,1.76],[0,0],[0,0],[0,0],[0,0],[0,0],[1.413,0],[0,2.919],[-2.803,0],[-0.718,-1.089],[0,0],[3.196,0]],"o":[[0,4.864],[2.803,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.672,0.602],[-2.803,0],[0,-2.919],[1.621,0],[0,0],[-1.181,-1.83],[-4.517,0]],"v":[[23.845,-7.713],[32.068,0.301],[38.646,-2.617],[38.646,-8.524],[31.28,-8.524],[31.28,-5.698],[35.403,-5.698],[35.403,-3.822],[32.068,-2.641],[27.227,-7.713],[32.068,-12.786],[35.727,-10.84],[38.461,-12.323],[32.068,-15.704]],"c":true},"ix":2},"nm":"G","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.988235294118,0.976470588235,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"G","np":3,"cix":2,"ix":7,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,2.733],[3.22,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[1.668,-0.394],[0,-2.872],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[54.156,0],[57.932,0],[54.457,-5.883],[57.839,-10.47],[52.651,-15.45],[45.424,-15.45],[45.424,0],[48.713,0],[48.713,-5.536],[51.122,-5.536]],"c":true},"ix":2},"nm":"R","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,-1.297],[1.32,0],[0,0],[0,0],[0,0]],"o":[[0,1.297],[0,0],[0,0],[0,0],[1.32,0]],"v":[[54.48,-10.493],[52.164,-8.362],[48.713,-8.362],[48.713,-12.624],[52.164,-12.624]],"c":true},"ix":2},"nm":"R","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.988235294118,0.976470588235,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"R","np":5,"cix":2,"ix":8,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[75.308,0],[78.898,0],[72.945,-15.45],[68.822,-15.45],[62.846,0],[66.459,0],[67.432,-2.664],[74.335,-2.664]],"c":true},"ix":2},"nm":"A","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[70.884,-12.601],[73.431,-5.513],[68.312,-5.513]],"c":true},"ix":2},"nm":"A","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.988235294118,0.976470588235,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"A","np":5,"cix":2,"ix":9,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[97.935,0],[101.247,0],[101.247,-15.45],[96.615,-15.45],[92.862,-5.814],[89.11,-15.45],[84.5,-15.45],[84.5,0],[87.79,0],[87.79,-11.118],[92.144,0],[93.58,0],[97.935,-11.118]],"c":true},"ix":2},"nm":"M","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.988235294118,0.976470588235,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"M","np":3,"cix":2,"ix":10,"mn":"ADBE Vector Group","hd":false}],"ip":16.0000162760417,"op":110.000111897786,"st":0,"bm":0},{"ddd":0,"ind":19,"ty":3,"nm":".chris-gannon-lottie-animation","cl":"chris-gannon-lottie-animation","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.45],"y":[1]},"o":{"x":[0.55],"y":[0]},"n":["0p45_1_0p55_0"],"t":72,"s":[0],"e":[-2]},{"i":{"x":[0.45],"y":[1]},"o":{"x":[0.55],"y":[0]},"n":["0p45_1_0p55_0"],"t":74,"s":[-2],"e":[0]},{"t":84.0000854492187}],"ix":10},"p":{"a":0,"k":[518,386,0],"ix":2},"a":{"a":0,"k":[178,146,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":124.000126139323,"st":-27.0000274658203,"bm":0},{"ddd":0,"ind":20,"ty":4,"nm":"body","parent":19,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.45],"y":[0]},"n":["0p833_0p833_0p45_0"],"t":0,"s":[0],"e":[-90]},{"t":17.0000172932943}],"ix":10,"x":"var $bm_rt;\nvar amp, freq, decay, n, t;\ntry {\n    amp = div(effect('Rotation - Overshoot')('ADBE Slider Control-0001'), 2.5), freq = div(effect('Rotation - Bounce')('ADBE Slider Control-0001'), 20), decay = div(effect('Rotation - Friction')('ADBE Slider Control-0001'), 20), n = 0, 0 < numKeys && (n = nearestKey(time).index, key(n).time > time && n--), t = 0 === n ? 0 : time - key(n).time, $bm_rt = 0 < n ? (v = velocityAtTime(sub(key(n).time, div(thisComp.frameDuration, 10))), sum(value, div(mul(mul(div(v, 100), amp), Math.sin(mul(mul(mul(freq, t), 2), Math.PI))), Math.exp(mul(decay, t))))) : value;\n} catch (e$$4) {\n    $bm_rt = value = value;\n}"},"p":{"a":0,"k":[60,60,0],"ix":2},"a":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":-27,"s":[-2,-6.5,0],"e":[-2,-6.5,0],"to":[0,0,0],"ti":[0,0,0]},{"t":56,"s":[-2,-6.5,0],"h":1},{"t":66.0000671386719,"s":[-2,-6.5,0],"h":1}],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"Rotation - Overshoot","np":3,"mn":"ADBE Slider Control","ix":1,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":10,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]},{"ty":5,"nm":"Rotation - Bounce","np":3,"mn":"ADBE Slider Control","ix":2,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":30,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]},{"ty":5,"nm":"Rotation - Friction","np":3,"mn":"ADBE Slider Control","ix":3,"en":1,"ef":[{"ty":0,"nm":"Slider","mn":"ADBE Slider Control-0001","ix":1,"v":{"a":0,"k":126,"ix":1,"x":"var $bm_rt;\n$bm_rt = clamp(value, 0, 100);"}}]}],"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":1,"k":[{"i":{"x":[0.14,0.14],"y":[1,1]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p14_1_0p167_0p167","0p14_1_0p167_0p167"],"t":-27,"s":[0,0],"e":[200,1]},{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.45,0.45],"y":[0,0]},"n":["0p833_0p833_0p45_0","0p833_0p833_0p45_0"],"t":0,"s":[200,1],"e":[216,302]},{"i":{"x":[0.833,0.833],"y":[1,1]},"o":{"x":[0.167,0.167],"y":[0,0]},"n":["0p833_1_0p167_0","0p833_1_0p167_0"],"t":17,"s":[216,302],"e":[216,302]},{"i":{"x":[0.197,0.45],"y":[1,1]},"o":{"x":[0.872,0.59],"y":[-0.522,0]},"n":["0p197_1_0p872_-0p522","0p45_1_0p59_0"],"t":97,"s":[216,302],"e":[0,200]},{"t":123.00012512207}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":20,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.992156982422,1,0.988234994926,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[-2,-6.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":124.000126139323,"st":-27.0000274658203,"bm":0}]}],"layers":[{"ddd":0,"ind":3,"ty":0,"nm":".chris-gannon-instagram-lottie","cl":"chris-gannon-instagram-lottie","refId":"comp_4","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[400,323,0],"ix":2},"a":{"a":0,"k":[400,300,0],"ix":1},"s":{"a":0,"k":[129,129,100],"ix":6}},"ao":0,"w":800,"h":600,"ip":0,"op":124.000126139323,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"blueToPurple","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[400,300,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[800,600],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"gf","o":{"a":0,"k":100,"ix":10},"r":1,"g":{"p":5,"k":{"a":0,"k":[0.007,0.298,0.404,0.851,0.307,0.431,0.308,0.735,0.6,0.565,0.212,0.62,0.8,0.565,0.212,0.62,1,0.565,0.212,0.62,0,1,0.199,1,0.397,1,0.592,0.5,0.788,0],"ix":9}},"s":{"a":0,"k":[-258,-522],"ix":5},"e":{"a":0,"k":[-943,-866],"ix":6},"t":2,"h":{"a":0,"k":18.494,"ix":7},"a":{"a":0,"k":-100.276,"ix":8},"nm":"Gradient Fill 1","mn":"ADBE Vector Graphic - G-Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":124.000126139323,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"yellowToOrange","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[400,300,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[800,600],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"gf","o":{"a":0,"k":100,"ix":10},"r":1,"g":{"p":7,"k":{"a":0,"k":[0.007,0.984,0.847,0.482,0.193,0.969,0.657,0.325,0.375,0.953,0.467,0.169,0.545,0.882,0.263,0.314,0.715,0.812,0.059,0.459,0.857,0.688,0.135,0.539,1,0.565,0.212,0.62,0,1,0.259,1,0.517,1,0.75,0.5,0.983,0],"ix":9}},"s":{"a":0,"k":[-140,330],"ix":5},"e":{"a":0,"k":[-637,989],"ix":6},"t":2,"h":{"a":0,"k":0,"ix":7},"a":{"a":0,"k":0,"ix":8},"nm":"Gradient Fill 1","mn":"ADBE Vector Graphic - G-Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":124.000126139323,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"bg","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[400,300,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[800,600],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.811764705882,0.058823529412,0.458823529412,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":124.000126139323,"st":0,"bm":0}]}
\ No newline at end of file
index 7e396e1..8c31999 100644 (file)
 using namespace Dali;
 using namespace Toolkit;
 
+namespace
+{
+
+const char* TEST_VECTOR_IMAGE_FILE_NAME =  TEST_RESOURCE_DIR  "/insta_camera.json";
+
+}
+
 int UtcDaliVisualAction(void)
 {
   ToolkitTestApplication application;
@@ -290,3 +297,26 @@ int UtcDaliNPatchBufferGetRedOffsetAndMask(void)
 
   END_TEST;
 }
+
+int UtcDaliAnimatedVectorImageVisualCreateInstancePropertyMap(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline( "UtcDaliAnimatedVectorImageVisualCreateInstancePropertyMap" );
+
+  Property::Map propertyMap;
+  propertyMap.Add( Toolkit::Visual::Property::TYPE,  DevelVisual::ANIMATED_VECTOR_IMAGE )
+             .Add( ImageVisual::Property::URL, TEST_VECTOR_IMAGE_FILE_NAME  );
+
+  // request AnimatedVectorImageVisual with a property map
+  VisualFactory factory = VisualFactory::Get();
+  Visual::Base visual = factory.CreateVisual( propertyMap );
+  Toolkit::Internal::Visual::Base& visualImpl = GetImplementation( visual );
+
+  Property::Map resultMap;
+  visualImpl.CreateInstancePropertyMap( resultMap );
+
+  // check the property values from the returned map from a visual
+  DALI_TEST_CHECK( resultMap.Empty() );   // Now the map is empty
+
+  END_TEST;
+}
index fe9102e..c8215a5 100755 (executable)
@@ -10,6 +10,7 @@ SET(TC_SOURCES
   utc-Dali-AbsoluteLayout.cpp
   utc-Dali-Alignment.cpp
   utc-Dali-AnimatedImageVisual.cpp
+  utc-Dali-AnimatedVectorImageVisual.cpp
   utc-Dali-BinLayout.cpp
   utc-Dali-BloomView.cpp
   utc-Dali-BubbleEmitter.cpp
index eb1f2b8..dcf0560 100644 (file)
@@ -204,15 +204,6 @@ void Adaptor::SceneCreated()
 {
 }
 
-void Adaptor::SetViewMode( ViewMode mode )
-{
-}
-
-void Adaptor::SetStereoBase(  float stereoBase )
-{
-}
-
-
 class LogFactory : public LogFactoryInterface
 {
 public:
diff --git a/automated-tests/src/dali-toolkit/utc-Dali-AnimatedVectorImageVisual.cpp b/automated-tests/src/dali-toolkit/utc-Dali-AnimatedVectorImageVisual.cpp
new file mode 100644 (file)
index 0000000..57733dd
--- /dev/null
@@ -0,0 +1,326 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <iostream>
+#include <stdlib.h>
+#include <dali-toolkit-test-suite-utils.h>
+#include <toolkit-timer.h>
+#include <toolkit-event-thread-callback.h>
+#include <dali-toolkit/dali-toolkit.h>
+#include <dali-toolkit/devel-api/visual-factory/visual-factory.h>
+#include <dali-toolkit/devel-api/controls/control-devel.h>
+#include <dali-toolkit/devel-api/visuals/visual-properties-devel.h>
+#include <dali-toolkit/devel-api/visuals/image-visual-properties-devel.h>
+#include <dali-toolkit/devel-api/visuals/animated-vector-image-visual-actions-devel.h>
+#include "dummy-control.h"
+
+using namespace Dali;
+using namespace Dali::Toolkit;
+
+void dali_animated_vector_image_visual_startup(void)
+{
+  test_return_value = TET_UNDEF;
+}
+
+void dali_animated_vector_image_visual_cleanup(void)
+{
+  test_return_value = TET_PASS;
+}
+
+namespace
+{
+
+const char* TEST_VECTOR_IMAGE_FILE_NAME =  TEST_RESOURCE_DIR  "/insta_camera.json";
+
+}
+
+int UtcDaliVisualFactoryGetAnimatedVectorImageVisual01(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline( "UtcDaliVisualFactoryGetAnimatedVectorImageVisual01: Request animated vector image visual with a json url" );
+
+  VisualFactory factory = VisualFactory::Get();
+  Visual::Base visual = factory.CreateVisual( TEST_VECTOR_IMAGE_FILE_NAME, ImageDimensions() );
+  DALI_TEST_CHECK( visual );
+
+  DummyControl actor = DummyControl::New( true );
+  DummyControlImpl& dummyImpl = static_cast< DummyControlImpl& >( actor.GetImplementation() );
+  dummyImpl.RegisterVisual( DummyControl::Property::TEST_VISUAL, visual );
+  actor.SetSize( 200.0f, 200.0f );
+  Stage::GetCurrent().Add( actor );
+
+  application.SendNotification();
+  application.Render();
+
+  // Wait for resource ready event callback
+  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
+
+  // renderer is added to actor
+  DALI_TEST_CHECK( actor.GetRendererCount() == 1u );
+  Renderer renderer = actor.GetRendererAt( 0u );
+  DALI_TEST_CHECK( renderer );
+
+  // Test SetOffStage().
+  actor.Unparent();
+  DALI_TEST_CHECK( actor.GetRendererCount() == 0u );
+
+  END_TEST;
+}
+
+int UtcDaliVisualFactoryGetAnimatedVectorImageVisual02(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline( "UtcDaliVisualFactoryGetAnimatedVectorImageVisual02: Request animated vector image visual with a Property::Map" );
+
+  Property::Map propertyMap;
+  propertyMap.Add( Toolkit::Visual::Property::TYPE, DevelVisual::ANIMATED_VECTOR_IMAGE )
+             .Add( ImageVisual::Property::URL, TEST_VECTOR_IMAGE_FILE_NAME  );
+
+  Visual::Base visual = VisualFactory::Get().CreateVisual( propertyMap );
+  DALI_TEST_CHECK( visual );
+
+  DummyControl actor = DummyControl::New( true );
+  DummyControlImpl& dummyImpl = static_cast< DummyControlImpl& >( actor.GetImplementation() );
+  dummyImpl.RegisterVisual( DummyControl::Property::TEST_VISUAL, visual );
+  actor.SetSize( 200.0f, 200.0f );
+  Stage::GetCurrent().Add( actor );
+
+  application.SendNotification();
+  application.Render();
+
+  // Wait for resource ready event callback
+  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
+
+  // renderer is added to actor
+  DALI_TEST_CHECK( actor.GetRendererCount() == 1u );
+  Renderer renderer = actor.GetRendererAt( 0u );
+  DALI_TEST_CHECK( renderer );
+
+  actor.Unparent( );
+  DALI_TEST_CHECK( actor.GetRendererCount() == 0u );
+
+  END_TEST;
+}
+
+int UtcDaliAnimatedVectorImageVisualGetPropertyMap01(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline( "UtcDaliAnimatedVectorImageVisualGetPropertyMap01" );
+
+  Property::Map propertyMap;
+  propertyMap.Add( Toolkit::Visual::Property::TYPE,  DevelVisual::ANIMATED_VECTOR_IMAGE )
+             .Add( ImageVisual::Property::URL, TEST_VECTOR_IMAGE_FILE_NAME  );
+
+  // request AnimatedVectorImageVisual with a property map
+  VisualFactory factory = VisualFactory::Get();
+  Visual::Base visual = factory.CreateVisual( propertyMap );
+
+  Property::Map resultMap;
+  visual.CreatePropertyMap( resultMap );
+
+  // check the property values from the returned map from a visual
+  Property::Value* value = resultMap.Find( Toolkit::Visual::Property::TYPE, Property::INTEGER );
+  DALI_TEST_CHECK( value );
+  DALI_TEST_CHECK( value->Get< int >() == DevelVisual::ANIMATED_VECTOR_IMAGE );
+
+  value = resultMap.Find( ImageVisual::Property::URL, Property::STRING );
+  DALI_TEST_CHECK( value );
+  DALI_TEST_CHECK( value->Get< std::string >() == TEST_VECTOR_IMAGE_FILE_NAME );
+
+  // request AnimatedVectorImageVisual with an URL
+  Visual::Base visual2 = factory.CreateVisual( TEST_VECTOR_IMAGE_FILE_NAME, ImageDimensions() );
+
+  resultMap.Clear();
+  visual2.CreatePropertyMap( resultMap );
+
+  // check the property values from the returned map from a visual
+  value = resultMap.Find( Toolkit::Visual::Property::TYPE, Property::INTEGER );
+  DALI_TEST_CHECK( value );
+  DALI_TEST_CHECK( value->Get< int >() == DevelVisual::ANIMATED_VECTOR_IMAGE );
+
+  value = resultMap.Find( ImageVisual::Property::URL, Property::STRING );
+  DALI_TEST_CHECK( value );
+  DALI_TEST_CHECK( value->Get< std::string >() == TEST_VECTOR_IMAGE_FILE_NAME );
+
+  END_TEST;
+}
+
+int UtcDaliAnimatedVectorImageVisualPlayback(void)
+{
+  ToolkitTestApplication application;
+
+  tet_infoline( "UtcDaliAnimatedVectorImageVisualPlayback" );
+
+  {
+    // request AnimatedVectorImageVisual with a property map
+    VisualFactory factory = VisualFactory::Get();
+    Visual::Base visual = factory.CreateVisual(
+      Property::Map()
+      .Add( Toolkit::Visual::Property::TYPE, DevelVisual::ANIMATED_VECTOR_IMAGE )
+      .Add( ImageVisual::Property::URL, TEST_VECTOR_IMAGE_FILE_NAME ) );
+
+    DummyControl dummyControl = DummyControl::New( true );
+    Impl::DummyControl& dummyImpl = static_cast< Impl::DummyControl& >( dummyControl.GetImplementation() );
+    dummyImpl.RegisterVisual( DummyControl::Property::TEST_VISUAL, visual );
+    dummyControl.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
+
+    Property::Map attributes;
+    tet_infoline( "Test Play action" );
+    DevelControl::DoAction( dummyControl, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::PLAY, attributes );
+
+    Stage::GetCurrent().Add( dummyControl );
+    application.SendNotification();
+    application.Render( 16 );
+
+    DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
+
+    // test
+
+    tet_infoline( "Test Pause action" );
+    DevelControl::DoAction( dummyControl, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::PAUSE, attributes );
+
+    application.SendNotification();
+    application.Render(16);
+
+    // test
+
+    tet_infoline( "Test Resume action" );
+    DevelControl::DoAction( dummyControl, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::RESUME, attributes );
+
+    application.SendNotification();
+    application.Render(16);
+
+    // test
+
+    tet_infoline( "Test Stop action" );
+    DevelControl::DoAction( dummyControl, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::STOP, attributes );
+
+    application.SendNotification();
+    application.Render(16);
+
+    // test
+
+    tet_infoline( "Test Stop action again" );
+    DevelControl::DoAction( dummyControl, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::STOP, attributes );
+
+    application.SendNotification();
+    application.Render(16);
+
+    // test
+
+    tet_infoline( "Test Play action" );
+    DevelControl::DoAction( dummyControl, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::PLAY, attributes );
+
+    application.SendNotification();
+    application.Render(16);
+
+    // test
+
+    dummyControl.SetSize( 100.0f, 100.0f );
+
+    application.SendNotification();
+    application.Render(16);
+
+    // test
+    // Size should be changed
+
+    dummyControl.Unparent();
+  }
+
+  END_TEST;
+}
+
+int UtcDaliAnimatedVectorImageVisualCustomShader(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline( "UtcDaliAnimatedVectorImageVisualCustomShader Test custom shader" );
+
+  VisualFactory factory = VisualFactory::Get();
+  Property::Map properties;
+  Property::Map shader;
+  const std::string vertexShader = "Foobar";
+  const std::string fragmentShader = "Foobar sampler2D Foobar";
+  shader[Visual::Shader::Property::FRAGMENT_SHADER] = fragmentShader;
+  shader[Visual::Shader::Property::VERTEX_SHADER] = vertexShader;
+
+  properties[Visual::Property::TYPE] = Visual::IMAGE;
+  properties[Visual::Property::SHADER] = shader;
+  properties[ImageVisual::Property::URL] = TEST_VECTOR_IMAGE_FILE_NAME;
+
+  Visual::Base visual = factory.CreateVisual( properties );
+
+  // trigger creation through setting on stage
+  DummyControl dummy = DummyControl::New( true );
+  Impl::DummyControl& dummyImpl = static_cast< Impl::DummyControl& >( dummy.GetImplementation() );
+  dummyImpl.RegisterVisual( DummyControl::Property::TEST_VISUAL, visual );
+
+  dummy.SetSize( 200.f, 200.f );
+  dummy.SetParentOrigin( ParentOrigin::CENTER );
+  Stage::GetCurrent().Add( dummy );
+
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
+
+  Renderer renderer = dummy.GetRendererAt( 0 );
+  Shader shader2 = renderer.GetShader();
+  Property::Value value = shader2.GetProperty( Shader::Property::PROGRAM );
+  Property::Map* map = value.GetMap();
+  DALI_TEST_CHECK( map );
+
+  std::string resultFragmentShader, resultVertexShader;
+  Property::Value* fragment = map->Find( "fragment" ); // fragment key name from shader-impl.cpp
+  fragment->Get( resultFragmentShader );
+  DALI_TEST_CHECK( resultFragmentShader.find( fragmentShader ) != std::string::npos );
+
+  Property::Value* vertex = map->Find( "vertex" ); // vertex key name from shader-impl.cpp
+  vertex->Get( resultVertexShader );
+  DALI_TEST_CHECK( resultVertexShader.find( vertexShader ) != std::string::npos );
+
+  END_TEST;
+}
+
+int UtcDaliAnimatedVectorImageVisualNaturalSize(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline( "UtcDaliAnimatedVectorImageVisualNaturalSize" );
+
+  VisualFactory factory = VisualFactory::Get();
+  Visual::Base visual = factory.CreateVisual( TEST_VECTOR_IMAGE_FILE_NAME, ImageDimensions() );
+  DALI_TEST_CHECK( visual );
+
+  DummyControl actor = DummyControl::New( true );
+  DummyControlImpl& dummyImpl = static_cast< DummyControlImpl& >( actor.GetImplementation() );
+  dummyImpl.RegisterVisual( DummyControl::Property::TEST_VISUAL, visual );
+
+  Vector2 controlSize( 20.f, 30.f );
+  Vector2 naturalSize;
+
+  actor.SetSize( controlSize );
+  Stage::GetCurrent().Add( actor );
+
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
+
+  visual.GetNaturalSize( naturalSize );
+
+  DALI_TEST_EQUALS( naturalSize, controlSize, TEST_LOCATION );
+
+  END_TEST;
+}
index ead839d..c7e2e4f 100644 (file)
@@ -21,6 +21,7 @@
 #include <toolkit-event-thread-callback.h>
 
 #include <dali-toolkit/dali-toolkit.h>
+#include <dali-toolkit/devel-api/focus-manager/keyinput-focus-manager.h>
 #include <dali-toolkit/devel-api/controls/control-devel.h>
 #include <dali-toolkit/devel-api/layouting/absolute-layout.h>
 #include <dali-toolkit/devel-api/layouting/grid.h>
@@ -56,7 +57,7 @@ struct LayoutTransitionFinishCheck
   {
   }
 
-  void operator()( LayoutTransitionData::LayoutTransitionType type, LayoutTransitionData& layoutTransitionData )
+  void operator()( LayoutTransitionData::Type type, LayoutTransitionData& layoutTransitionData )
   {
     mSignalReceived = true;
   }
@@ -153,22 +154,44 @@ int UtcDaliLayouting_LayoutTransitionDataSetGetTransition(void)
   auto layout = LinearLayout::New();
   auto layoutTransitionData = LayoutTransitionData::New();
 
-  layout.SetTransitionData( LayoutTransitionData::ON_OWNER_SET, layoutTransitionData );
-  DALI_TEST_CHECK( layout.GetTransitionData( LayoutTransitionData::ON_OWNER_SET ) == layoutTransitionData );
-  DALI_TEST_CHECK( layout.GetTransitionData( LayoutTransitionData::ON_CHILD_ADD ) == LayoutTransitionData() );
-  DALI_TEST_CHECK( layout.GetTransitionData( LayoutTransitionData::ON_CHILD_REMOVE ) == LayoutTransitionData() );
-
-  layout.SetTransitionData( LayoutTransitionData::ON_OWNER_SET, LayoutTransitionData() );
   layout.SetTransitionData( LayoutTransitionData::ON_CHILD_ADD, layoutTransitionData );
-  DALI_TEST_CHECK( layout.GetTransitionData( LayoutTransitionData::ON_OWNER_SET ) == LayoutTransitionData() );
   DALI_TEST_CHECK( layout.GetTransitionData( LayoutTransitionData::ON_CHILD_ADD ) == layoutTransitionData );
   DALI_TEST_CHECK( layout.GetTransitionData( LayoutTransitionData::ON_CHILD_REMOVE ) == LayoutTransitionData() );
+  DALI_TEST_CHECK( layout.GetTransitionData( LayoutTransitionData::ON_CHILD_FOCUS ) == LayoutTransitionData() );
+  DALI_TEST_CHECK( layout.GetTransitionData( LayoutTransitionData::ON_OWNER_SET ) == LayoutTransitionData() );
+  DALI_TEST_CHECK( layout.GetTransitionData( LayoutTransitionData::ON_LAYOUT_CHANGE ) == LayoutTransitionData() );
 
   layout.SetTransitionData( LayoutTransitionData::ON_CHILD_ADD, LayoutTransitionData() );
   layout.SetTransitionData( LayoutTransitionData::ON_CHILD_REMOVE, layoutTransitionData );
-  DALI_TEST_CHECK( layout.GetTransitionData( LayoutTransitionData::ON_OWNER_SET ) == LayoutTransitionData() );
   DALI_TEST_CHECK( layout.GetTransitionData( LayoutTransitionData::ON_CHILD_ADD ) == LayoutTransitionData() );
   DALI_TEST_CHECK( layout.GetTransitionData( LayoutTransitionData::ON_CHILD_REMOVE ) == layoutTransitionData );
+  DALI_TEST_CHECK( layout.GetTransitionData( LayoutTransitionData::ON_CHILD_FOCUS ) == LayoutTransitionData() );
+  DALI_TEST_CHECK( layout.GetTransitionData( LayoutTransitionData::ON_OWNER_SET ) == LayoutTransitionData() );
+  DALI_TEST_CHECK( layout.GetTransitionData( LayoutTransitionData::ON_LAYOUT_CHANGE ) == LayoutTransitionData() );
+
+  layout.SetTransitionData( LayoutTransitionData::ON_CHILD_REMOVE, LayoutTransitionData() );
+  layout.SetTransitionData( LayoutTransitionData::ON_CHILD_FOCUS, layoutTransitionData );
+  DALI_TEST_CHECK( layout.GetTransitionData( LayoutTransitionData::ON_CHILD_ADD ) == LayoutTransitionData() );
+  DALI_TEST_CHECK( layout.GetTransitionData( LayoutTransitionData::ON_CHILD_REMOVE ) == LayoutTransitionData() );
+  DALI_TEST_CHECK( layout.GetTransitionData( LayoutTransitionData::ON_CHILD_FOCUS ) == layoutTransitionData );
+  DALI_TEST_CHECK( layout.GetTransitionData( LayoutTransitionData::ON_OWNER_SET ) == LayoutTransitionData() );
+  DALI_TEST_CHECK( layout.GetTransitionData( LayoutTransitionData::ON_LAYOUT_CHANGE ) == LayoutTransitionData() );
+
+  layout.SetTransitionData( LayoutTransitionData::ON_CHILD_FOCUS, LayoutTransitionData() );
+  layout.SetTransitionData( LayoutTransitionData::ON_OWNER_SET, layoutTransitionData );
+  DALI_TEST_CHECK( layout.GetTransitionData( LayoutTransitionData::ON_CHILD_ADD ) == LayoutTransitionData() );
+  DALI_TEST_CHECK( layout.GetTransitionData( LayoutTransitionData::ON_CHILD_REMOVE ) == LayoutTransitionData() );
+  DALI_TEST_CHECK( layout.GetTransitionData( LayoutTransitionData::ON_CHILD_FOCUS ) == LayoutTransitionData() );
+  DALI_TEST_CHECK( layout.GetTransitionData( LayoutTransitionData::ON_OWNER_SET ) == layoutTransitionData );
+  DALI_TEST_CHECK( layout.GetTransitionData( LayoutTransitionData::ON_LAYOUT_CHANGE ) == LayoutTransitionData() );
+
+  layout.SetTransitionData( LayoutTransitionData::ON_OWNER_SET, LayoutTransitionData() );
+  layout.SetTransitionData( LayoutTransitionData::ON_LAYOUT_CHANGE, layoutTransitionData );
+  DALI_TEST_CHECK( layout.GetTransitionData( LayoutTransitionData::ON_CHILD_ADD ) == LayoutTransitionData() );
+  DALI_TEST_CHECK( layout.GetTransitionData( LayoutTransitionData::ON_CHILD_REMOVE ) == LayoutTransitionData() );
+  DALI_TEST_CHECK( layout.GetTransitionData( LayoutTransitionData::ON_CHILD_FOCUS ) == LayoutTransitionData() );
+  DALI_TEST_CHECK( layout.GetTransitionData( LayoutTransitionData::ON_OWNER_SET ) == LayoutTransitionData() );
+  DALI_TEST_CHECK( layout.GetTransitionData( LayoutTransitionData::ON_LAYOUT_CHANGE ) == layoutTransitionData );
 
   END_TEST;
 }
@@ -181,11 +204,11 @@ int UtcDaliLayouting_SetLayoutTransition01(void)
   Stage stage = Stage::GetCurrent();
   auto container = Control::New();
   auto horizontalLayout = LinearLayout::New();
-  horizontalLayout.SetAnimateLayout( true );
+  horizontalLayout.SetAnimateLayout( false );
   horizontalLayout.SetOrientation( LinearLayout::Orientation::HORIZONTAL );
 
   auto verticalLayout = LinearLayout::New();
-  verticalLayout.SetAnimateLayout( true );
+  verticalLayout.SetAnimateLayout( false );
   verticalLayout.SetOrientation( LinearLayout::Orientation::VERTICAL );
 
   DevelControl::SetLayout( container, horizontalLayout );
@@ -198,9 +221,6 @@ int UtcDaliLayouting_SetLayoutTransition01(void)
   {
     container.Add( iter );
   }
-
-  container.SetParentOrigin( ParentOrigin::CENTER );
-  container.SetAnchorPoint( AnchorPoint::CENTER );
   stage.Add( container );
 
   auto layoutTransitionData = LayoutTransitionData::New();
@@ -257,12 +277,11 @@ int UtcDaliLayouting_SetLayoutTransition01(void)
   application.Render();
 
   // First round, no animation
-  // TODO: container size (0, 0) after it is added to the stage should be fixed with HQ patch soon
   DALI_TEST_EQUALS( container.GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
   DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 350.0f, 0.0f ), 0.0001f, TEST_LOCATION );
   DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 100.0f, 350.0f, 0.0f ), 0.0001f, TEST_LOCATION );
 
-  DALI_TEST_EQUALS( container.GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( container.GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 480.0f, 800.0f, 0.0f ), 0.0001f, TEST_LOCATION );
   DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
   DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
 
@@ -270,6 +289,9 @@ int UtcDaliLayouting_SetLayoutTransition01(void)
   LayoutTransitionFinishCheck finishCheck(signalReceived);
   layoutTransitionData.FinishedSignal().Connect(&application, finishCheck);
 
+  horizontalLayout.SetAnimateLayout( true );
+  verticalLayout.SetAnimateLayout( true );
+
   // Change a layout, start transition
   verticalLayout.SetTransitionData( LayoutTransitionData::ON_OWNER_SET, layoutTransitionData );
   DevelControl::SetLayout( container, verticalLayout );
@@ -373,8 +395,6 @@ int UtcDaliLayouting_AddChildLayoutTransition01(void)
 
   std::vector< Control > controls;
   controls.push_back( CreateLeafControl( 100, 100 ) );
-  container.SetParentOrigin( ParentOrigin::CENTER );
-  container.SetAnchorPoint( AnchorPoint::CENTER );
   stage.Add( container );
 
   auto layoutTransitionData = LayoutTransitionData::New();
@@ -393,6 +413,7 @@ int UtcDaliLayouting_AddChildLayoutTransition01(void)
   {
     // Instant position for a child
     Property::Map map;
+    map[ LayoutTransitionData::AnimatorKey::CONDITION ] = LayoutTransitionData::Condition::NONE;
     map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = "position";
     map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map()
        .Add( LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION, "LINEAR")
@@ -404,6 +425,7 @@ int UtcDaliLayouting_AddChildLayoutTransition01(void)
   {
     // Grow a child from (0,0) size to full size (captured)
     Property::Map map;
+    map[ LayoutTransitionData::AnimatorKey::CONDITION ] = LayoutTransitionData::Condition::ON_ADD;
     map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = "size";
     map[ LayoutTransitionData::AnimatorKey::INITIAL_VALUE ] = Vector3( 0.0f, 0.0f, 0 );
     map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map()
@@ -411,7 +433,7 @@ int UtcDaliLayouting_AddChildLayoutTransition01(void)
       .Add( LayoutTransitionData::AnimatorKey::TIME_PERIOD, Property::Map()
         .Add( LayoutTransitionData::AnimatorKey::DELAY, 0.0f)
         .Add( LayoutTransitionData::AnimatorKey::DURATION, 0.5f));
-    layoutTransitionData.AddPropertyAnimator( controls[0], map );
+    layoutTransitionData.AddPropertyAnimator( Actor(), map ); // apply to an added child
   }
 
   horizontalLayout.SetTransitionData( LayoutTransitionData::ON_CHILD_ADD, layoutTransitionData );
@@ -462,17 +484,16 @@ int UtcDaliLayouting_RemoveChildLayoutTransition01(void)
   Stage stage = Stage::GetCurrent();
   auto container = Control::New();
   auto horizontalLayout = LinearLayout::New();
-  horizontalLayout.SetAnimateLayout( true );
+  horizontalLayout.SetAnimateLayout( false );
   horizontalLayout.SetOrientation( LinearLayout::Orientation::HORIZONTAL );
 
   DevelControl::SetLayout( container, horizontalLayout );
-  container.SetName( "Container");
+  container.SetName( "Container" );
 
   std::vector< Control > controls;
   controls.push_back( CreateLeafControl( 100, 100 ) );
   controls.push_back( CreateLeafControl( 100, 100 ) );
-  container.SetParentOrigin( ParentOrigin::CENTER );
-  container.SetAnchorPoint( AnchorPoint::CENTER );
+
   stage.Add( container );
   container.Add( controls[0] );
   container.Add( controls[1] );
@@ -481,6 +502,8 @@ int UtcDaliLayouting_RemoveChildLayoutTransition01(void)
   application.SendNotification();
   application.Render();
 
+  horizontalLayout.SetAnimateLayout( true );
+
   auto layoutTransitionData = LayoutTransitionData::New();
   {
     // Instant resize for parent width
@@ -561,7 +584,21 @@ int UtcDaliLayouting_RemoveChildLayoutTransition01(void)
     layoutTransitionData.AddPropertyAnimator( Actor(), map );
   }
   {
-    // Instant position for a child
+    // Shrink the removed child
+    Property::Map map;
+    map[ LayoutTransitionData::AnimatorKey::CONDITION ] = LayoutTransitionData::Condition::ON_REMOVE;
+    map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::SIZE;
+    map[ LayoutTransitionData::AnimatorKey::TARGET_VALUE ] = Size( 0.0f, 0.0f );
+    map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map()
+      .Add( LayoutTransitionData::AnimatorKey::TYPE, "ANIMATE_TO" )
+      .Add( LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION, "LINEAR")
+      .Add( LayoutTransitionData::AnimatorKey::TIME_PERIOD, Property::Map()
+        .Add( LayoutTransitionData::AnimatorKey::DELAY, 0.0f)
+        .Add( LayoutTransitionData::AnimatorKey::DURATION, 0.5f));
+    layoutTransitionData.AddPropertyAnimator( Actor(), map );
+  }
+  {
+    // Instant position for children
     Property::Map map;
     map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::POSITION_X;
     map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map()
@@ -573,7 +610,7 @@ int UtcDaliLayouting_RemoveChildLayoutTransition01(void)
     layoutTransitionData.AddPropertyAnimator( Actor(), map ); // apply to all children except parent
   }
   {
-    // Instant position for a child
+    // Instant position for children
     Property::Map map;
     map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::POSITION_Y;
     map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map()
@@ -602,7 +639,7 @@ int UtcDaliLayouting_RemoveChildLayoutTransition01(void)
   DALI_TEST_EQUALS( controls[1].GetCurrentPosition(), Vector3( 100.0f, 350.0f, 0.0f ), 0.0001f, TEST_LOCATION );
 
   DALI_TEST_EQUALS( container.GetCurrentSize(), Vector3( 480.0f, 800.0f, 0.0f ), 0.0001f, TEST_LOCATION );
-  DALI_TEST_EQUALS( controls[0].GetCurrentSize(), Vector3( 0.0f, 0.0f, 0.0f ), 1.0f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[0].GetCurrentSize(), Vector3( 100.0f, 100.0f, 0.0f ), 1.0f, TEST_LOCATION );
   // this control is already removed from the tree.
   DALI_TEST_EQUALS( controls[1].GetCurrentSize(), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
 
@@ -613,7 +650,7 @@ int UtcDaliLayouting_RemoveChildLayoutTransition01(void)
   DALI_TEST_EQUALS( container.GetCurrentPosition(), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
   DALI_TEST_EQUALS( controls[0].GetCurrentPosition(), Vector3( 0.0f, 350.0f, 0.0f ), 0.0001f, TEST_LOCATION );
   // this control is already removed from the tree.
-  DALI_TEST_EQUALS( controls[1].GetCurrentPosition(), Vector3( 100.0f, 350.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[1].GetCurrentPosition(), Vector3( 100.0f, 350.0f, 0.0f ), 1.0f, TEST_LOCATION );
 
   DALI_TEST_EQUALS( container.GetCurrentSize(), Vector3( 480.0f, 800.0f, 0.0f ), 0.0001f, TEST_LOCATION );
   DALI_TEST_EQUALS( controls[0].GetCurrentSize(), Vector3( 0.0f, 0.0f, 0.0f ), 1.0f, TEST_LOCATION );
@@ -627,13 +664,153 @@ int UtcDaliLayouting_RemoveChildLayoutTransition01(void)
   DALI_TEST_EQUALS( container.GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
   DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 350.0f, 0.0f ), 0.0001f, TEST_LOCATION );
   // this control is already removed from the tree.
+  DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 100.0f, 350.0f, 0.0f ), 1.0f, TEST_LOCATION );
+
+  DALI_TEST_EQUALS( container.GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 480.0f, 800.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  // this control is already removed from the tree.
+  DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 1.0f, TEST_LOCATION );
+
+  finishCheck.CheckSignalReceived();
+
+  END_TEST;
+}
+
+int UtcDaliLayouting_FocusChildLayoutTransition01(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliLayouting_FocusChildLayoutTransition01");
+
+  Stage stage = Stage::GetCurrent();
+  auto container = Control::New();
+  auto horizontalLayout = LinearLayout::New();
+  horizontalLayout.SetAnimateLayout( false );
+  horizontalLayout.SetOrientation( LinearLayout::Orientation::HORIZONTAL );
+
+  DevelControl::SetLayout( container, horizontalLayout );
+  container.SetName( "Container" );
+
+  std::vector< Control > controls;
+  controls.push_back( CreateLeafControl( 100, 100 ) );
+  controls.push_back( CreateLeafControl( 100, 100 ) );
+
+  stage.Add( container );
+  container.Add( controls[0] );
+  container.Add( controls[1] );
+
+  KeyInputFocusManager manager = KeyInputFocusManager::Get();
+  manager.SetFocus( controls[0] );
+
+  // Initial rendering done
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( container.GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 350.0f, 0.0f ), 0.0001f, TEST_LOCATION );
   DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 100.0f, 350.0f, 0.0f ), 0.0001f, TEST_LOCATION );
 
   DALI_TEST_EQUALS( container.GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 480.0f, 800.0f, 0.0f ), 0.0001f, TEST_LOCATION );
   DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
-  // this control is already removed from the tree.
   DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
 
+  horizontalLayout.SetAnimateLayout( true );
+
+  auto layoutTransitionData = LayoutTransitionData::New();
+  {
+    // Instant resize for parent
+    Property::Map map;
+    map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::SIZE;
+    map[ LayoutTransitionData::AnimatorKey::TARGET_VALUE ] = Property::Value(); // capture from layout update
+    map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map()
+      .Add( LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION, "LINEAR" )
+      .Add( LayoutTransitionData::AnimatorKey::TIME_PERIOD, Property::Map()
+        .Add( LayoutTransitionData::AnimatorKey::DELAY, 0.0f )
+        .Add( LayoutTransitionData::AnimatorKey::DURATION, 0.0f ) );
+    layoutTransitionData.AddPropertyAnimator( container, map );
+  }
+  {
+    // Instant position for parent
+    Property::Map map;
+    map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::POSITION;
+    map[ LayoutTransitionData::AnimatorKey::TARGET_VALUE ] = Property::Value(); // capture from layout update
+    map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map()
+       .Add( LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION, "LINEAR")
+       .Add( LayoutTransitionData::AnimatorKey::TIME_PERIOD, Property::Map()
+         .Add( LayoutTransitionData::AnimatorKey::DELAY, 0.0f )
+         .Add( LayoutTransitionData::AnimatorKey::DURATION, 0.0f ) );
+    layoutTransitionData.AddPropertyAnimator( Actor(), map ); // apply to all children except parent
+  }
+  {
+    // Shrink the lost focus child
+    Property::Map map;
+    map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::SIZE;
+    map[ LayoutTransitionData::AnimatorKey::CONDITION ] = LayoutTransitionData::Condition::ON_FOCUS_LOST;
+    map[ LayoutTransitionData::AnimatorKey::TARGET_VALUE ] = Vector3( 80.0f, 80.0f, 0 );
+    map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map()
+         .Add( LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION, "LINEAR")
+         .Add( LayoutTransitionData::AnimatorKey::TIME_PERIOD, Property::Map()
+           .Add( LayoutTransitionData::AnimatorKey::DELAY, 0.0f)
+           .Add( LayoutTransitionData::AnimatorKey::DURATION, 0.5f));
+    layoutTransitionData.AddPropertyAnimator( Actor(), map ); // apply to on focus lost child
+  }
+  {
+    // Grow the gained focus child
+    Property::Map map;
+    map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::SIZE;
+    map[ LayoutTransitionData::AnimatorKey::CONDITION ] = LayoutTransitionData::Condition::ON_FOCUS_GAINED;
+    map[ LayoutTransitionData::AnimatorKey::TARGET_VALUE ] = Vector3( 120.0f, 120.0f, 0 );
+    map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map()
+         .Add( LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION, "LINEAR")
+         .Add( LayoutTransitionData::AnimatorKey::TIME_PERIOD, Property::Map()
+           .Add( LayoutTransitionData::AnimatorKey::DELAY, 0.0f)
+           .Add( LayoutTransitionData::AnimatorKey::DURATION, 0.5f));
+    layoutTransitionData.AddPropertyAnimator( Actor(), map ); // apply to on focus gained child
+  }
+
+  horizontalLayout.SetTransitionData( LayoutTransitionData::ON_CHILD_FOCUS, layoutTransitionData );
+
+  bool signalReceived(false);
+  LayoutTransitionFinishCheck finishCheck(signalReceived);
+  layoutTransitionData.FinishedSignal().Connect(&application, finishCheck);
+  manager.SetFocus( controls[1] );
+
+  application.SendNotification();
+  application.Render( 1u /*just very beginning of the animation*/ );
+
+  finishCheck.CheckSignalNotReceived();
+  // Animation just started
+  DALI_TEST_EQUALS( container.GetCurrentPosition(), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[0].GetCurrentPosition(), Vector3( 0.0f, 350.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[1].GetCurrentPosition(), Vector3( 100.0f, 350.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  DALI_TEST_EQUALS( container.GetCurrentSize(), Vector3( 480.0f, 800.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[0].GetCurrentSize(), Vector3( 100.0f, 100.0f, 0.0f ), 1.0f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[1].GetCurrentSize(), Vector3( 100.0f, 100.0f, 0.0f ), 1.0f, TEST_LOCATION );
+
+  application.SendNotification();
+  application.Render(static_cast<unsigned int>( 0.5f * 1000.0f ) + 1u /*just after the end of the animation*/ );
+
+  // Animation just finished
+  DALI_TEST_EQUALS( container.GetCurrentPosition(), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[0].GetCurrentPosition(), Vector3( 0.0f, 350.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[1].GetCurrentPosition(), Vector3( 100.0f, 350.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  DALI_TEST_EQUALS( container.GetCurrentSize(), Vector3( 480.0f, 800.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[0].GetCurrentSize(), Vector3( 80.0f, 80.0f, 0.0f ), 1.0f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[1].GetCurrentSize(), Vector3( 120.0f, 120.0f, 0.0f ), 1.0f, TEST_LOCATION );
+
+  application.SendNotification();
+  application.Render( 10u /* wait a bit more for a signal */ );
+
+  // Now sizes and positions are finally set
+  DALI_TEST_EQUALS( container.GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 350.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 100.0f, 350.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  DALI_TEST_EQUALS( container.GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 480.0f, 800.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 80.0f, 80.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 120.0f, 120.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
   finishCheck.CheckSignalReceived();
 
   END_TEST;
@@ -655,8 +832,6 @@ int UtcDaliLayouting_AddChildLayoutTransition02_KeyFrames(void)
 
   std::vector< Control > controls;
   controls.push_back( CreateLeafControl( 100, 100 ) );
-  container.SetParentOrigin( ParentOrigin::CENTER );
-  container.SetAnchorPoint( AnchorPoint::CENTER );
   stage.Add( container );
 
   auto layoutTransitionData = LayoutTransitionData::New();
@@ -690,14 +865,15 @@ int UtcDaliLayouting_AddChildLayoutTransition02_KeyFrames(void)
     keyFrames.Add( 0.5f, Vector3( 100.0f, 100.0f, 0 ) );
 
     Property::Map map;
-    map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::SIZE;
-    map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map()
-      .Add( LayoutTransitionData::AnimatorKey::TYPE, "ANIMATE_BETWEEN")
-      .Add( LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION, "LINEAR")
-      .Add( LayoutTransitionData::AnimatorKey::TIME_PERIOD, Property::Map()
-        .Add( LayoutTransitionData::AnimatorKey::DELAY, 0.0f)
-        .Add( LayoutTransitionData::AnimatorKey::DURATION, 0.5f));
-    layoutTransitionData.AddPropertyAnimator( controls[0], map, keyFrames, Animation::Interpolation::Linear );
+    map[ "property" ] = Actor::Property::SIZE;
+    map[ "condition" ] = LayoutTransitionData::Condition::ON_ADD;
+    map[ "animator" ] = Property::Map()
+      .Add( "type", "ANIMATE_BETWEEN")
+      .Add( "alphaFunction", "LINEAR")
+      .Add( "timePeriod", Property::Map()
+        .Add( "delay", 0.0f)
+        .Add( "duration", 0.5f));
+    layoutTransitionData.AddPropertyAnimator( Actor(), map, keyFrames, Animation::Interpolation::Linear );
   }
 
   horizontalLayout.SetTransitionData( LayoutTransitionData::ON_CHILD_ADD, layoutTransitionData );
@@ -756,8 +932,6 @@ int UtcDaliLayouting_AddChildLayoutTransition03_Path(void)
 
   std::vector< Control > controls;
   controls.push_back( CreateLeafControl( 100, 100 ) );
-  container.SetParentOrigin( ParentOrigin::CENTER );
-  container.SetAnchorPoint( AnchorPoint::CENTER );
   stage.Add( container );
 
   auto layoutTransitionData = LayoutTransitionData::New();
@@ -886,8 +1060,6 @@ int UtcDaliLayouting_AddChildLayoutTransition04_AnimateBy(void)
 
   std::vector< Control > controls;
   controls.push_back( CreateLeafControl( 100, 100 ) );
-  container.SetParentOrigin( ParentOrigin::CENTER );
-  container.SetAnchorPoint( AnchorPoint::CENTER );
   stage.Add( container );
 
   auto layoutTransitionData = LayoutTransitionData::New();
@@ -983,8 +1155,6 @@ int UtcDaliLayouting_AddChildLayoutTransition05(void)
 
   std::vector< Control > controls;
   controls.push_back( CreateLeafControl( 100, 100 ) );
-  container.SetParentOrigin( ParentOrigin::CENTER );
-  container.SetAnchorPoint( AnchorPoint::CENTER );
   stage.Add( container );
 
   auto layoutTransitionData = LayoutTransitionData::New();
@@ -1209,3 +1379,119 @@ int UtcDaliLayouting_AddChildLayoutTransition05(void)
   END_TEST;
 }
 
+int UtcDaliLayouting_DefaultTransition01(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliLayouting_DefaultTransition01");
+
+  Stage stage = Stage::GetCurrent();
+  auto container = Control::New();
+  auto horizontalLayout = LinearLayout::New();
+  horizontalLayout.SetAnimateLayout( false );
+  horizontalLayout.SetOrientation( LinearLayout::Orientation::HORIZONTAL );
+
+  DevelControl::SetLayout( container, horizontalLayout );
+  container.SetName( "Container" );
+
+  std::vector< Control > controls;
+  controls.push_back( CreateLeafControl( 100, 100 ) );
+  controls.push_back( CreateLeafControl( 100, 100 ) );
+
+  stage.Add( container );
+  container.Add( controls[0] );
+  container.Add( controls[1] );
+
+  // Initial rendering done
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( container.GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 350.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 100.0f, 350.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  DALI_TEST_EQUALS( container.GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 480.0f, 800.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  horizontalLayout.SetAnimateLayout( true );
+
+  auto layoutTransitionData0 = LayoutTransitionData::New();
+  {
+    // Default instant resize
+    Property::Map map;
+    map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::SIZE;
+    map[ LayoutTransitionData::AnimatorKey::TARGET_VALUE ] = Property::Value(); // capture from layout update
+    map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map()
+      .Add( LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION, AlphaFunction::LINEAR )
+      .Add( LayoutTransitionData::AnimatorKey::TIME_PERIOD, Property::Map()
+        .Add( LayoutTransitionData::AnimatorKey::DELAY, 0.0f )
+        .Add( LayoutTransitionData::AnimatorKey::DURATION, 0.0f ) );
+    layoutTransitionData0.AddPropertyAnimator( controls[0], map );
+  }
+  {
+    // Instant instant position
+    Property::Map map;
+    map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::POSITION;
+    map[ LayoutTransitionData::AnimatorKey::TARGET_VALUE ] = Property::Value(); // capture from layout update
+    map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map()
+       .Add( LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION, AlphaFunction::LINEAR )
+       .Add( LayoutTransitionData::AnimatorKey::TIME_PERIOD, Property::Map()
+         .Add( LayoutTransitionData::AnimatorKey::DELAY, 0.0f )
+         .Add( LayoutTransitionData::AnimatorKey::DURATION, 0.0f ) );
+    layoutTransitionData0.AddPropertyAnimator( controls[0], map );
+  }
+  DevelControl::GetLayout( controls[0] ).SetTransitionData(LayoutTransitionData::Type::ON_LAYOUT_CHANGE, layoutTransitionData0 );
+
+  auto layoutTransitionData1 = LayoutTransitionData::New();
+  {
+    // Default instant resize
+    Property::Map map;
+    map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::SIZE;
+    map[ LayoutTransitionData::AnimatorKey::TARGET_VALUE ] = Property::Value(); // capture from layout update
+    map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map()
+      .Add( LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION, AlphaFunction::LINEAR )
+      .Add( LayoutTransitionData::AnimatorKey::TIME_PERIOD, Property::Map()
+        .Add( LayoutTransitionData::AnimatorKey::DELAY, 0.0f )
+        .Add( LayoutTransitionData::AnimatorKey::DURATION, 0.0f ) );
+    layoutTransitionData1.AddPropertyAnimator( controls[1], map );
+  }
+  {
+    // Instant instant position
+    Property::Map map;
+    map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::POSITION;
+    map[ LayoutTransitionData::AnimatorKey::TARGET_VALUE ] = Property::Value(); // capture from layout update
+    map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map()
+       .Add( LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION, AlphaFunction::LINEAR )
+       .Add( LayoutTransitionData::AnimatorKey::TIME_PERIOD, Property::Map()
+         .Add( LayoutTransitionData::AnimatorKey::DELAY, 0.0f )
+         .Add( LayoutTransitionData::AnimatorKey::DURATION, 0.0f ) );
+    layoutTransitionData0.AddPropertyAnimator( controls[1], map );
+  }
+  DevelControl::GetLayout( controls[1] ).SetTransitionData(LayoutTransitionData::Type::ON_LAYOUT_CHANGE, layoutTransitionData1 );
+
+  horizontalLayout.SetOrientation( LinearLayout::Orientation::VERTICAL );
+
+  application.SendNotification();
+  application.Render( 10u /*just very beginning of the animation*/ );
+
+  // Animation just finished
+  DALI_TEST_EQUALS( container.GetCurrentPosition(), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[0].GetCurrentPosition(), Vector3( 0.0f, 300.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[1].GetCurrentPosition(), Vector3( 0.0f, 400.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  DALI_TEST_EQUALS( container.GetCurrentSize(), Vector3( 480.0f, 800.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[0].GetCurrentSize(), Vector3( 100.0f, 100.0f, 0.0f ), 1.0f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[0].GetCurrentSize(), Vector3( 100.0f, 100.0f, 0.0f ), 1.0f, TEST_LOCATION );
+
+  // Now sizes and positions are set
+  DALI_TEST_EQUALS( container.GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 300.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 400.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  DALI_TEST_EQUALS( container.GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 480.0f, 800.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  END_TEST;
+}
+
index 155b54a..a21b1b8 100644 (file)
@@ -71,9 +71,7 @@ int UtcDaliLayoutingNesting_01(void)
     |
   Control (LinearLayout Horizontal)
     |
-  Control (LayoutingRequired)
-    |
-  Control (LinearLayout Horizontal)
+  Control (LinearLayout Vertical)
     |
   LeafControl
 
@@ -82,8 +80,6 @@ int UtcDaliLayoutingNesting_01(void)
   ToolkitTestApplication application;
   tet_infoline("UtcDaliLayoutingNesting_01 - Nesting a LinearLayout (MATCH_PARENT) containing a leaf control within a LinearLayout");
 
-  Stage stage = Stage::GetCurrent();
-
   auto rootControl = Control::New();
   SetupRootLayoutControl( rootControl );
 
@@ -110,7 +106,7 @@ int UtcDaliLayoutingNesting_01(void)
 
   for( auto&& iter : controls )
   {
-    hbox.Add( iter );
+    vbox.Add( iter );
   }
 
   rootControl.Add( hbox );
@@ -134,10 +130,8 @@ int UtcDaliLayoutingNesting_02(void)
   Root
     |
   Control (LinearLayout Horizontal)
-    |
-  Control (LayoutingRequired)
-    |
-  Control (LinearLayout Horizontal)
+    |    |
+  Control (LinearLayout Vertical)
     |    |
   LeafControl
 
@@ -147,8 +141,6 @@ int UtcDaliLayoutingNesting_02(void)
   tet_infoline("UtcDaliLayoutingNesting_02 - Nesting a LinearLayout (MATCH_PARENT) containing a leaf control within a LinearLayout");
   tet_infoline("Then change the parent's size and test child responded correctly");
 
-  Stage stage = Stage::GetCurrent();
-
   auto rootControl = Control::New();
   SetupRootLayoutControl( rootControl );
 
@@ -175,7 +167,7 @@ int UtcDaliLayoutingNesting_02(void)
 
   for( auto&& iter : controls )
   {
-    hbox.Add( iter );
+    vbox.Add( iter );
   }
 
   rootControl.Add( hbox );
@@ -200,4 +192,63 @@ int UtcDaliLayoutingNesting_02(void)
   DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 40.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION );
 
   END_TEST;
+}
+
+int UtcDaliLayoutingNesting_LeafSizeChange(void)
+{
+ /*
+  Root
+    |
+  Control (LayoutingRequired)
+    |
+  Control (LinearLayout Horizontal)  (WRAP_CONTENT)
+    |    |
+  TextLabel
+  */
+
+  ToolkitTestApplication application;
+  tet_infoline("UtcDaliLayoutingNesting_LeafSizeChange - Nesting a TextLabel within a layout that is parented to a control");
+  tet_infoline("Then change the TextLabels size and test the parent resized to wrap the new size");
+
+  auto rootControl = Control::New();
+  SetupRootLayoutControl( rootControl );
+
+  auto control = Control::New();
+  DevelControl::SetLayoutingRequired( control, true );
+  control.SetName( "control" );
+
+  auto hbox = Control::New();
+  auto hboxLayout = LinearLayout::New();
+  hboxLayout.SetOrientation( LinearLayout::Orientation::HORIZONTAL );
+  DevelControl::SetLayout( hbox, hboxLayout );
+  hbox.SetName( "hBox" );
+  hbox.SetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION, ChildLayoutData::WRAP_CONTENT );
+  hbox.SetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, ChildLayoutData::WRAP_CONTENT );
+
+  control.Add( hbox );
+
+  TextLabel textLabel = CreateTextLabel("SmallText" );
+
+  hbox.Add( textLabel );
+
+  rootControl.Add( control );
+
+  // Ensure layouting happens
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( hbox.GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 260.0f, 64.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( textLabel.GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 260.0f, 64.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  tet_infoline("Changing to longer text");
+  textLabel.SetProperty( TextLabel::Property::TEXT, "muchlongerText" );
+
+  // Ensure layouting happens
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( hbox.GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 432.0f, 64.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( textLabel.GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 432.0f, 64.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  END_TEST;
 }
\ No newline at end of file
index 1cad2f5..2ddabe9 100755 (executable)
@@ -130,6 +130,7 @@ devel_api_visual_factory_header_files = \
 devel_api_visuals_header_files = \
   $(devel_api_src_dir)/visuals/animated-gradient-visual-properties-devel.h \
   $(devel_api_src_dir)/visuals/animated-image-visual-actions-devel.h \
+  $(devel_api_src_dir)/visuals/animated-vector-image-visual-actions-devel.h \
   $(devel_api_src_dir)/visuals/color-visual-properties-devel.h \
   $(devel_api_src_dir)/visuals/image-visual-properties-devel.h \
   $(devel_api_src_dir)/visuals/image-visual-actions-devel.h \
index ba87af2..95a2619 100644 (file)
@@ -68,12 +68,17 @@ LayoutController LayoutController::Get()
 
 void LayoutController::RequestLayout( LayoutItem layout )
 {
-  GetImpl( *this ).RequestLayout( GetImplementation( layout ), -1 );
+  GetImpl( *this ).RequestLayout( GetImplementation( layout ), -1, Actor(), Actor() );
 }
 
-void LayoutController::RequestLayout( LayoutItem layout, Dali::Toolkit::LayoutTransitionData::LayoutTransitionType layoutTransitionType  )
+void LayoutController::RequestLayout( LayoutItem layout, Dali::Toolkit::LayoutTransitionData::Type layoutTransitionType )
 {
-  GetImpl( *this ).RequestLayout( GetImplementation( layout ), layoutTransitionType );
+  GetImpl( *this ).RequestLayout( GetImplementation( layout ), layoutTransitionType, Actor(), Actor() );
+}
+
+void LayoutController::RequestLayout( LayoutItem layout, Dali::Toolkit::LayoutTransitionData::Type layoutTransitionType, Actor gainedChild, Actor lostChild  )
+{
+  GetImpl( *this ).RequestLayout( GetImplementation( layout ), layoutTransitionType, gainedChild, lostChild );
 }
 
 LayoutController::LayoutController( Internal::LayoutController *impl )
index 062793d..951a4fc 100755 (executable)
@@ -74,7 +74,17 @@ public:
    * @param[in] layout The layout to measure & relayout.
    * @param[in] layoutTransitionType The layout transition type.
    */
-  void RequestLayout( LayoutItem layout, Dali::Toolkit::LayoutTransitionData::LayoutTransitionType layoutTransitionType );
+  void RequestLayout( LayoutItem layout, Dali::Toolkit::LayoutTransitionData::Type layoutTransitionType );
+
+  /**
+   * @brief Request for a particular layout (wrapping a control or a visual) to be measured and laid out. A specified layout transition
+   * will be triggered during the layout.
+   * @param[in] layout The layout to measure & relayout.
+   * @param[in] layoutTransitionType The layout transition type.
+   * @param[in] gainedChild The gained layout owner's child.
+   * @param[in] lostChild The lost layout owner's child.
+   */
+  void RequestLayout( LayoutItem layout, Dali::Toolkit::LayoutTransitionData::Type layoutTransitionType, Actor gainedChild, Actor lostChild );
 
 public:
   /// @cond internal
index 06305bd..8ddc819 100644 (file)
@@ -552,7 +552,7 @@ void LayoutGroup::OnInitialize()
       }
     }
 
-    RequestLayout( Dali::Toolkit::LayoutTransitionData::LayoutTransitionType::ON_OWNER_SET );
+    RequestLayout( Dali::Toolkit::LayoutTransitionData::Type::ON_OWNER_SET );
   }
 }
 
@@ -585,7 +585,7 @@ void LayoutGroup::RemoveChild( LayoutItem& item )
 void LayoutGroup::ChildAddedToOwner( Actor child )
 {
   ChildAddedToOwnerImpl( child );
-  RequestLayout( Dali::Toolkit::LayoutTransitionData::LayoutTransitionType::ON_CHILD_ADD );
+  RequestLayout( Dali::Toolkit::LayoutTransitionData::Type::ON_CHILD_ADD, child, Actor() );
 }
 
 void LayoutGroup::ChildAddedToOwnerImpl( Actor child )
@@ -670,7 +670,7 @@ void LayoutGroup::ChildRemovedFromOwner( Actor child )
     if( childLayout )
     {
       Remove( *childLayout.Get() );
-      RequestLayout( Dali::Toolkit::LayoutTransitionData::LayoutTransitionType::ON_CHILD_REMOVE );
+      RequestLayout( Dali::Toolkit::LayoutTransitionData::Type::ON_CHILD_REMOVE, child, Actor() );
     }
   }
 }
@@ -784,11 +784,13 @@ void LayoutGroup::OnMeasure( MeasureSpec widthMeasureSpec, MeasureSpec heightMea
         // Check below will be true for legacy containers and controls with layout required set.
         // Other layouts will have their own OnMeasure (a checked requirement) hence not execute LayoutGroup::OnMeasure.
         // Controls which have set layout required will not be legacy controls hence should not have a ResizePolicy set.
-        if( childControl.GetChildCount() > 0 )
+        // Only need to map the resize policy the first time as the Layouting system will then set it to FIXED.
+        if( childControl.GetChildCount() > 0 && ! mImpl->mResizePolicyMapped )
         {
           // First pass, Static mappings that are not dependant on parent
           SizeNegotiationMapper::SetLayoutParametersUsingResizePolicy( childControl, childLayout, Dimension::WIDTH );
           SizeNegotiationMapper::SetLayoutParametersUsingResizePolicy( childControl, childLayout, Dimension::HEIGHT );
+          mImpl->mResizePolicyMapped = true;
         }
 
         // Second pass, if any mappings were not possible due to parent size dependancies then calculate an exact desired size for child
index cd4cf40..0b638de 100644 (file)
@@ -152,9 +152,15 @@ void LayoutItem::SetTransitionData( int layoutTransitionType, Internal::LayoutTr
   case Dali::Toolkit::LayoutTransitionData::ON_CHILD_REMOVE:
     mImpl->mOnChildRemoveTransitionData = layoutTransitionDataPtr;
     break;
+  case Dali::Toolkit::LayoutTransitionData::ON_CHILD_FOCUS:
+    mImpl->mOnChildFocusTransitionData = layoutTransitionDataPtr;
+    break;
   case Dali::Toolkit::LayoutTransitionData::ON_OWNER_SET:
     mImpl->mOnOwnerSetTransitionData = layoutTransitionDataPtr;
     break;
+  case Dali::Toolkit::LayoutTransitionData::ON_LAYOUT_CHANGE:
+    mImpl->mOnLayoutChangeTransitionData = layoutTransitionDataPtr;
+    break;
   default:
     break;
   }
@@ -168,8 +174,12 @@ Internal::LayoutTransitionDataPtr LayoutItem::GetTransitionData( int layoutTrans
     return mImpl->mOnChildAddTransitionData.Get();
   case Dali::Toolkit::LayoutTransitionData::ON_CHILD_REMOVE:
     return mImpl->mOnChildRemoveTransitionData.Get();
+  case Dali::Toolkit::LayoutTransitionData::ON_CHILD_FOCUS:
+    return mImpl->mOnChildFocusTransitionData.Get();
   case Dali::Toolkit::LayoutTransitionData::ON_OWNER_SET:
     return mImpl->mOnOwnerSetTransitionData.Get();
+  case Dali::Toolkit::LayoutTransitionData::ON_LAYOUT_CHANGE:
+    return mImpl->mOnLayoutChangeTransitionData.Get();
   default:
     return LayoutTransitionDataPtr();
   }
@@ -417,7 +427,7 @@ void LayoutItem::RequestLayout()
   layoutController.RequestLayout( Toolkit::LayoutItem( this ) );
 }
 
-void LayoutItem::RequestLayout( Dali::Toolkit::LayoutTransitionData::LayoutTransitionType layoutAnimationType )
+void LayoutItem::RequestLayout( Dali::Toolkit::LayoutTransitionData::Type layoutAnimationType )
 {
   Toolkit::Control control = Toolkit::Control::DownCast( mImpl->mOwner );
   if ( control )
@@ -431,6 +441,20 @@ void LayoutItem::RequestLayout( Dali::Toolkit::LayoutTransitionData::LayoutTrans
   layoutController.RequestLayout( Toolkit::LayoutItem(this), layoutAnimationType );
 }
 
+void LayoutItem::RequestLayout( Dali::Toolkit::LayoutTransitionData::Type layoutAnimationType, Actor gainedChild, Actor lostChild )
+{
+  Toolkit::Control control = Toolkit::Control::DownCast( mImpl->mOwner );
+  if ( control )
+  {
+    DALI_LOG_INFO( gLayoutFilter, Debug::Verbose, "LayoutItem::RequestLayout control(%s) layoutTranstionType(%d)\n",
+        control.GetName().c_str(), (int)layoutAnimationType );
+  }
+  // @todo Enforce failure if called in Measure/Layout passes.
+  mImpl->SetPrivateFlag( Impl::PRIVATE_FLAG_FORCE_LAYOUT );
+  Toolkit::LayoutController layoutController = Toolkit::LayoutController::Get();
+  layoutController.RequestLayout( Toolkit::LayoutItem(this), layoutAnimationType, gainedChild, lostChild );
+}
+
 bool LayoutItem::IsLayoutRequested() const
 {
   return mImpl->GetPrivateFlag( Impl::PRIVATE_FLAG_FORCE_LAYOUT );
@@ -579,7 +603,6 @@ bool LayoutItem::SetFrame( LayoutLength left, LayoutLength top, LayoutLength rig
   {
     if( mImpl->mAnimated && !layoutData.speculativeLayout )
     {
-
       LayoutItem* transitionOwner = layoutData.layoutTransition.layoutItem.Get();
       LayoutTransitionDataPtr layoutTransitionDataPtr = GetTransitionData( layoutData.layoutTransition.layoutTransitionType );
 
@@ -595,9 +618,25 @@ bool LayoutItem::SetFrame( LayoutLength left, LayoutLength top, LayoutLength rig
       {
         if( changed )
         {
-          DALI_LOG_INFO( gLayoutFilter, Debug::Verbose, "LayoutItem::SetFrame apply default transition to (%s), transition type (%d)\n", actor.GetName().c_str(), layoutData.layoutTransition.layoutTransitionType );
+          layoutTransitionDataPtr = GetTransitionData( Dali::Toolkit::LayoutTransitionData::ON_LAYOUT_CHANGE );
+          if ( layoutTransitionDataPtr )
+          {
+            DALI_LOG_INFO( gLayoutFilter, Debug::Verbose, "LayoutItem::SetFrame apply custom default transition to (%s), transition type (%d)\n", actor.GetName().c_str(), Dali::Toolkit::LayoutTransitionData::ON_LAYOUT_CHANGE );
+            layoutData.layoutPositionDataArray.push_back( LayoutPositionData( actor, left.AsDecimal(), top.AsDecimal(), right.AsDecimal(), bottom.AsDecimal(), true ) );
+            layoutTransitionDataPtr->ConvertToLayoutDataElements( actor, layoutData );
+          }
+          else
+          {
+            DALI_LOG_INFO( gLayoutFilter, Debug::Verbose, "LayoutItem::SetFrame apply default transition to (%s), transition type (%d)\n", actor.GetName().c_str(), layoutData.layoutTransition.layoutTransitionType );
+            layoutData.layoutPositionDataArray.push_back( LayoutPositionData( actor, left.AsDecimal(), top.AsDecimal(), right.AsDecimal(), bottom.AsDecimal(), true ) );
+            GetDefaultTransition()->ConvertToLayoutDataElements( actor, layoutData );
+          }
+        }
+        else
+        {
+          DALI_LOG_INFO( gLayoutFilter, Debug::Verbose, "LayoutItem::SetFrame apply children animators to (%s), transition type (%d)\n", actor.GetName().c_str(), layoutData.layoutTransition.layoutTransitionType );
           layoutData.layoutPositionDataArray.push_back( LayoutPositionData( actor, left.AsDecimal(), top.AsDecimal(), right.AsDecimal(), bottom.AsDecimal(), true ) );
-          GetDefaultTransition()->ConvertToLayoutDataElements( actor, layoutData );
+          LayoutTransitionData::ConvertChildrenAnimatorsToLayoutDataElements( actor, layoutData );
         }
       }
     }
index 19b61d5..47d65cc 100644 (file)
@@ -209,7 +209,17 @@ public:
    *
    * This will make this layout and all it's parent layouts dirty and set the transition queued.
    */
-  void RequestLayout( Dali::Toolkit::LayoutTransitionData::LayoutTransitionType layoutTranstionType );
+  void RequestLayout( Dali::Toolkit::LayoutTransitionData::Type layoutTranstionType );
+
+  /**
+   * @brief Request that this layout is re-laid out with particular transition.
+   * @param[in] layoutTranstionType The transition type
+   * @param[in] gainedChild The gained owners's child due to add/remove or focus gained/lost
+   * @param[in] lostChild The lost owners's child due to add/remove or focus gained/lost
+   *
+   * This will make this layout and all it's parent layouts dirty and set the transition queued.
+   */
+  void RequestLayout( Dali::Toolkit::LayoutTransitionData::Type layoutTranstionType, Actor gainedChild, Actor lostChild );
 
   /**
    * @brief Predicate to determine if this layout has been requested to re-layout
index a84b45d..315faa4 100644 (file)
@@ -55,7 +55,7 @@ bool LayoutItem::IsLayoutAnimated() const
   return GetImplementation( *this ).IsLayoutAnimated();
 }
 
-void LayoutItem::SetTransitionData( LayoutTransitionData::LayoutTransitionType layoutTransitionType, LayoutTransitionData layoutTransitionData )
+void LayoutItem::SetTransitionData( LayoutTransitionData::Type layoutTransitionType, LayoutTransitionData layoutTransitionData )
 {
   Toolkit::Internal::LayoutTransitionDataPtr layoutTransitionDataPtr = Toolkit::Internal::LayoutTransitionDataPtr();
   if ( layoutTransitionData )
@@ -65,7 +65,7 @@ void LayoutItem::SetTransitionData( LayoutTransitionData::LayoutTransitionType l
   GetImplementation( *this ).SetTransitionData( layoutTransitionType, layoutTransitionDataPtr );
 }
 
-LayoutTransitionData LayoutItem::GetTransitionData( LayoutTransitionData::LayoutTransitionType layoutTransitionType ) const
+LayoutTransitionData LayoutItem::GetTransitionData( LayoutTransitionData::Type layoutTransitionType ) const
 {
   return LayoutTransitionData( GetImplementation( *this ).GetTransitionData( layoutTransitionType ).Get() );
 }
index 1ad32ed..3513182 100755 (executable)
@@ -123,7 +123,7 @@ public:
    * @param[in] layoutTransitionType The type of the layout transition
    * @param[in] layoutTransitionData The layout transition data
    */
-  void SetTransitionData( LayoutTransitionData::LayoutTransitionType layoutTransitionType, LayoutTransitionData layoutTransitionData );
+  void SetTransitionData( LayoutTransitionData::Type layoutTransitionType, LayoutTransitionData layoutTransitionData );
 
   /**
    * @brief Get the layout transition data
@@ -132,7 +132,7 @@ public:
    *
    * @return The layout transition data
    */
-  LayoutTransitionData GetTransitionData( LayoutTransitionData::LayoutTransitionType layoutTransitionType ) const;
+  LayoutTransitionData GetTransitionData( LayoutTransitionData::Type layoutTransitionType ) const;
 
 public:
   /// @cond internal
index c01b2dd..ad36ca8 100644 (file)
@@ -48,7 +48,7 @@ void LayoutTransitionData::AddPropertyAnimator( Actor actor, Property::Map map )
   GetImplementation( *this ).AddPropertyAnimator( actor, map );
 }
 
-void LayoutTransitionData::AddPropertyAnimator(  Actor actor, Property::Map map, KeyFrames keyFrames, Animation::Interpolation interpolation )
+void LayoutTransitionData::AddPropertyAnimator( Actor actor, Property::Map map, KeyFrames keyFrames, Animation::Interpolation interpolation )
 {
   GetImplementation( *this ).AddPropertyAnimator( actor, map, keyFrames, interpolation );
 }
index 5bd509a..d51d28a 100644 (file)
@@ -36,6 +36,9 @@ namespace Internal
 class LayoutTransitionData;
 }
 
+/**
+ * @brief The LayoutTransitionData class to collect the actors properties animators for layout transitions.
+ */
 class DALI_TOOLKIT_API LayoutTransitionData final : public BaseHandle
 {
 public:
@@ -47,6 +50,7 @@ public:
   {
     enum Type
     {
+      CONDITION,          ///< A condition triggering the transition animation (the actor is added/removed/focus gained/focus lost)
       PROPERTY,           ///< A property to animate
       INITIAL_VALUE,      ///< Initial value of an animated property
       TARGET_VALUE,       ///< Target value of an animated property
@@ -60,14 +64,30 @@ public:
     };
   };
 
-  enum LayoutTransitionType
+  struct Condition
+  {
+    enum Type
+    {
+      NONE,            ///< Default, no conditions to animate property. The property is animated for all relevant animations related to a control
+      ON_ADD,          ///< A condition to animate property when a control is added to the container
+      ON_REMOVE,       ///< A condition to animate property when a control is removed from the container
+      ON_FOCUS_GAINED, ///< A condition to animate property when a control focus is gained
+      ON_FOCUS_LOST,   ///< A condition to animate property when a control focus is lost
+    };
+  };
+
+  enum Type
   {
-    ON_CHILD_ADD,
-    ON_CHILD_REMOVE,
-    ON_OWNER_SET
+    // Children related transitions
+    ON_CHILD_ADD,          ///< A transition is triggered when a control is added to the container
+    ON_CHILD_REMOVE,       ///< A transition is triggered when a control is removed from the container
+    ON_CHILD_FOCUS,        ///< A transition is triggered when a control focus is changed in the container
+    // Layout related transitions
+    ON_OWNER_SET,          ///< A transition is triggered when a layout is set to a new container
+    ON_LAYOUT_CHANGE,      ///< A transition is triggered when a layout geometry is changed
   };
 
-  typedef Signal< void (LayoutTransitionData::LayoutTransitionType, LayoutTransitionData&) > LayoutTransitionSignalType; ///< Transition finished signal
+  typedef Signal< void (LayoutTransitionData::Type, LayoutTransitionData&) > LayoutTransitionSignalType; ///< Transition finished signal
 
   /**
    * Create an uninitialized handle
@@ -102,7 +122,8 @@ public:
   /**
    * @brief Add a property animator for an actor
    *
-   * @param[in] actor An owner of the animated property
+   * @param[in] actor An owner of the animated property.
+   *                  If actor is empty then the property animator is generic and apply to all children excluding the parent if the condition is met.
    * @param[in] map The animated property map including animator map
    */
   void AddPropertyAnimator( Actor actor, Property::Map map );
@@ -111,6 +132,7 @@ public:
    * @brief Add a property animator for an actor
    *
    * @param[in] actor An owner of the animated property
+   *                  If actor is empty then the property animator is generic and apply to all children excluding the parent if the condition is met.
    * @param[in] map The properties map
    * @param[in] keyFrames key frames
    * @param[in] interpolation An interpolation
@@ -121,6 +143,7 @@ public:
    * @brief Add a property animator for an actor
    *
    * @param[in] actor An owner of the animated property
+   *                  If actor is empty then the property animator is generic and apply to all children excluding the parent if the condition is met.
    * @param[in] map A properties map
    * @param[in] path An animation path
    * @param[in] forward A forward vector for the path
diff --git a/dali-toolkit/devel-api/visuals/animated-vector-image-visual-actions-devel.h b/dali-toolkit/devel-api/visuals/animated-vector-image-visual-actions-devel.h
new file mode 100644 (file)
index 0000000..6e40c69
--- /dev/null
@@ -0,0 +1,54 @@
+#ifndef DALI_TOOLKIT_DEVEL_API_VISUALS_ANIMATED_VECTOR_IMAGE_VISUAL_ACTIONS_DEVEL_H
+#define DALI_TOOLKIT_DEVEL_API_VISUALS_ANIMATED_VECTOR_IMAGE_VISUAL_ACTIONS_DEVEL_H
+
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace DevelAnimatedVectorImageVisual
+{
+
+/**
+ * @brief Actions that the animated vector image visual can perform.  These actions are called through the Visual::Base::DoAction API.
+ */
+namespace Action
+{
+/**
+ * @brief The available actions for this visual
+ */
+enum Type
+{
+  PLAY,        ///< Play the animated vector image.
+  PAUSE,       ///< Pause the animated vector image.
+  RESUME,      ///< Resume the animated vector image.
+  STOP         ///< Stop the animated vector image. This is also Default playback mode.
+};
+
+} // namespace Action
+
+} // namespace DevelAnimatedVectorImageVisual
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_DEVEL_API_VISUALS_ANIMATED_VECTOR_IMAGE_VISUAL_ACTIONS_DEVEL_H
index ec53128..709b12a 100644 (file)
@@ -47,7 +47,8 @@ enum Type
   SVG            = Dali::Toolkit::Visual::SVG,
   ANIMATED_IMAGE = Dali::Toolkit::Visual::ANIMATED_IMAGE,
 
-  ANIMATED_GRADIENT = ANIMATED_IMAGE + 1,  //< Renders an animated gradient.
+  ANIMATED_GRADIENT     = ANIMATED_IMAGE + 1,  ///< Renders an animated gradient.
+  ANIMATED_VECTOR_IMAGE = ANIMATED_IMAGE + 2,  ///< Renders an animated vector image.
 };
 
 /**
index 3ec462b..2f7bd6b 100644 (file)
@@ -281,7 +281,7 @@ uint32_t Scene3dView::GetCameraCount()
 CameraActor Scene3dView::GetCamera( uint32_t cameraIndex )
 {
   CameraActor cameraActor;
-  if( cameraIndex < 0 || cameraIndex >= mCameraActorArray.size() )
+  if( cameraIndex >= mCameraActorArray.size() )
   {
     return cameraActor;
   }
index 8fab9fd..44be18c 100755 (executable)
@@ -28,6 +28,8 @@ toolkit_src_files = \
    $(toolkit_src_dir)/visuals/animated-image/fixed-image-cache.cpp \
    $(toolkit_src_dir)/visuals/animated-image/rolling-image-cache.cpp \
    $(toolkit_src_dir)/visuals/animated-image/rolling-gif-image-cache.cpp \
+   $(toolkit_src_dir)/visuals/animated-vector-image/animated-vector-image-visual.cpp \
+   $(toolkit_src_dir)/visuals/animated-vector-image/vector-image-rasterize-thread.cpp \
    $(toolkit_src_dir)/visuals/border/border-visual.cpp \
    $(toolkit_src_dir)/visuals/color/color-visual.cpp \
    $(toolkit_src_dir)/visuals/gradient/gradient-visual.cpp \
index 17a75a6..d2e0119 100644 (file)
@@ -23,6 +23,7 @@
 #include <dali-toolkit/public-api/controls/control-impl.h>
 #include <dali-toolkit/internal/controls/control/control-data-impl.h>
 #include <dali-toolkit/internal/layouting/layout-controller-debug.h>
+#include <dali-toolkit/devel-api/focus-manager/keyinput-focus-manager.h>
 
 using namespace Dali;
 
@@ -44,6 +45,7 @@ namespace Internal
 
 LayoutController::LayoutController()
 : mLayoutRequested( false ),
+  mFocusChangedFunctor( *this ),
   mSlotDelegate( this )
 {
 }
@@ -55,14 +57,32 @@ LayoutController::~LayoutController()
 void LayoutController::Initialize()
 {
   mAnimation = Animation::New( 0.0f );
+
+  Dali::Toolkit::KeyInputFocusManager manager = Dali::Toolkit::KeyInputFocusManager::Get();
+  manager.KeyInputFocusChangedSignal().Connect( mSlotDelegate.GetConnectionTracker(), mFocusChangedFunctor );
+}
+
+void LayoutController::FocusChangedFunctor::operator() ( Dali::Toolkit::Control gainingControl, Dali::Toolkit::Control lostControl )
+{
+  Toolkit::LayoutItem layoutItem = Toolkit::DevelControl::GetLayout( gainingControl );
+  if( layoutItem )
+  {
+    Toolkit::Internal::LayoutItem& layoutItemImpl = GetImplementation( layoutItem );
+    LayoutParent* layoutParent = layoutItemImpl.GetParent();
+    if( layoutParent )
+    {
+      LayoutGroup* layoutGroup = static_cast< LayoutGroup* >( layoutParent );
+      layoutController.RequestLayout( dynamic_cast< Toolkit::Internal::LayoutItem& >( *layoutGroup ), Dali::Toolkit::LayoutTransitionData::ON_CHILD_FOCUS, gainingControl, lostControl );
+    }
+  }
 }
 
-void LayoutController::RequestLayout( LayoutItem& layoutItem, int layoutTransitionType )
+void LayoutController::RequestLayout( LayoutItem& layoutItem, int layoutTransitionType, Actor gainedChild, Actor lostChild )
 {
   auto actor = Actor::DownCast( layoutItem.GetOwner() );
   if ( actor )
   {
-    DALI_LOG_INFO( gLogFilter, Debug::Concise, "LayoutController::RequestLayout owner[%s] layoutItem[%p] layoutAnimationType(%d)\n", actor.GetName().c_str(), &layoutItem, layoutTransitionType );
+    DALI_LOG_INFO( gLogFilter, Debug::Concise, "LayoutController::RequestLayout owner[%s] layoutItem[%p] layoutTransitionType(%d)\n", actor.GetName().c_str(), &layoutItem, layoutTransitionType );
   }
   else
   {
@@ -72,9 +92,10 @@ void LayoutController::RequestLayout( LayoutItem& layoutItem, int layoutTransiti
   mLayoutRequested = true;
   if( layoutTransitionType != -1 )
   {
-    LayoutTransition layoutTransition = LayoutTransition( layoutItem, layoutTransitionType );
+    LayoutTransition layoutTransition = LayoutTransition( layoutItem, layoutTransitionType, gainedChild, lostChild );
     if( std::find( mLayoutTransitions.begin(), mLayoutTransitions.end(), layoutTransition ) == mLayoutTransitions.end() && layoutItem.GetTransitionData( layoutTransitionType ).Get() )
     {
+      DALI_LOG_INFO( gLogFilter, Debug::Concise, "LayoutController::RequestLayout Add transition layoutTransitionType(%d)\n", layoutTransitionType );
       mLayoutTransitions.push_back( layoutTransition );
     }
   }
@@ -215,8 +236,16 @@ void LayoutController::PerformLayoutPositioning( LayoutPositionDataArray& layout
     if( actor && ( !layoutPositionData.animated || all ) )
     {
       DALI_LOG_INFO( gLogFilter, Debug::Verbose, "LayoutController::PerformLayoutPositioning %s\n", actor.GetName().c_str() );
-      actor.SetPosition( layoutPositionData.left, layoutPositionData.top );
-      actor.SetSize( layoutPositionData.right - layoutPositionData.left, layoutPositionData.bottom - layoutPositionData.top );
+      if ( !layoutPositionData.animated )
+      {
+        actor.SetPosition( layoutPositionData.left, layoutPositionData.top );
+        actor.SetSize( layoutPositionData.right - layoutPositionData.left, layoutPositionData.bottom - layoutPositionData.top );
+      }
+      else
+      {
+        actor.SetPosition( actor.GetCurrentPosition() );
+        actor.SetSize( actor.GetCurrentSize() );
+      }
     }
   }
 }
@@ -328,13 +357,8 @@ void LayoutController::PerformLayoutAnimation( LayoutTransition& layoutTransitio
   {
     if( mAnimation.GetState() == Animation::PLAYING )
     {
-      mAnimation.Clear();
-      if( mAnimationFinishedFunctors.size() != 0 )
-      {
-        mAnimationFinishedFunctors.front()( mAnimation );
-      }
+      mAnimation.SetCurrentProgress( 1.0f );
     }
-
     mAnimation = animation;
     mAnimationFinishedFunctors.push_back( AnimationFinishedFunctor( *this, layoutTransition, layoutPositionDataArray ) );
     mAnimation.FinishedSignal().Connect( mSlotDelegate.GetConnectionTracker(), mAnimationFinishedFunctors.back() );
index 1c3130d..71c947c 100644 (file)
@@ -57,7 +57,7 @@ public:
   /**
    * This marks the given layout and all its parents as dirty and triggers a transition if set.
    */
-  void RequestLayout( LayoutItem& layout, int layoutTransitionType );
+  void RequestLayout( LayoutItem& layout, int layoutTransitionType, Actor gainedChild, Actor lostChild );
 
   /**
    * Measures next level of layouts in the actor hierarchy.
@@ -79,6 +79,11 @@ public:
    */
   void PerformLayoutAnimation( LayoutTransition& layoutTransition, LayoutPositionDataArray& layoutPositionDataArray, LayoutDataArray& layoutDataArray, LayoutAnimatorArray& layoutAnimatorArray );
 
+  /**
+   * Focus change callback.
+   */
+  void KeyInputFocusChangedCallback( Control gainingActor, Control lostActor );
+
 protected: // Implementation of Processor
 
   /**
@@ -120,6 +125,18 @@ private:
   Animation mAnimation;
   std::list< AnimationFinishedFunctor > mAnimationFinishedFunctors;
 
+  struct FocusChangedFunctor
+  {
+    FocusChangedFunctor( LayoutController& layoutController )
+    : layoutController( layoutController )
+    {
+    }
+
+    void operator() ( Dali::Toolkit::Control gainingControl, Dali::Toolkit::Control lostActor );
+    LayoutController& layoutController;
+  };
+  FocusChangedFunctor mFocusChangedFunctor;
+
   SlotDelegate<LayoutController> mSlotDelegate;
 };
 
index f1d7fea..56e92a3 100644 (file)
@@ -26,7 +26,8 @@ namespace Internal
 
 LayoutGroup::Impl::Impl()
 : mChildren(),
-  mNextLayoutId(1)
+  mNextLayoutId(1),
+  mResizePolicyMapped( false )
 {
 }
 
index 231cc09..02a4716 100644 (file)
@@ -44,6 +44,7 @@ public:
 
   std::vector<ChildLayout> mChildren;
   Toolkit::LayoutGroup::LayoutId mNextLayoutId;
+  bool mResizePolicyMapped;
 };
 
 
index 0e68977..0b415ad 100644 (file)
@@ -80,9 +80,13 @@ public:
 
   static bool sUseZeroUnspecifiedMeasureSpec;
 
+  // Custom transitions
   LayoutTransitionDataPtr mOnChildAddTransitionData;
   LayoutTransitionDataPtr mOnChildRemoveTransitionData;
+  LayoutTransitionDataPtr mOnChildFocusTransitionData;
   LayoutTransitionDataPtr mOnOwnerSetTransitionData;
+  LayoutTransitionDataPtr mOnLayoutChangeTransitionData;
+  // Default transition
   LayoutTransitionDataPtr mDefaultTransitionData;
 
   // To pass layout data during perform layout
index f43ee79..f65f874 100644 (file)
 
 namespace
 {
+#if defined(DEBUG_ENABLED)
+Debug::Filter* gLayoutFilter = Debug::Filter::New( Debug::NoLogging, false, "LOG_LAYOUT" );
+#endif
+
 // Key tokens
+const char* TOKEN_CONDITION("condition");
 const char* TOKEN_PROPERTY("property");
 const char* TOKEN_INITIAL_VALUE("initialValue");
 const char* TOKEN_TARGET_VALUE("targetValue");
@@ -209,6 +214,10 @@ bool LayoutTransitionData::ConvertToLayoutAnimator( const Property::Map& animato
         Vector2 controlPoint2( controlPoints.z, controlPoints.w );
         layoutDataAnimator.alphaFunction = AlphaFunction( controlPoint1, controlPoint2 );
       }
+      else if ( value.GetType() == Property::INTEGER )
+      {
+        layoutDataAnimator.alphaFunction = AlphaFunction( static_cast<AlphaFunction::BuiltinFunction>( value.Get<int>() ) );
+      }
       else if ( value.GetType() == Property::STRING )
       {
         std::string alphaFunctionValue = value.Get<std::string>();
@@ -371,6 +380,10 @@ bool LayoutTransitionData::ConvertToLayoutDataElement( const PropertyAnimator& p
     if ( pair.first.type == Property::Key::STRING )
     {
       const std::string& key( pair.first.stringKey );
+      if ( key == TOKEN_CONDITION )
+      {
+        indexKey = Dali::Toolkit::LayoutTransitionData::AnimatorKey::CONDITION;
+      }
       if ( key == TOKEN_PROPERTY )
       {
         indexKey = Dali::Toolkit::LayoutTransitionData::AnimatorKey::PROPERTY;
@@ -393,7 +406,11 @@ bool LayoutTransitionData::ConvertToLayoutDataElement( const PropertyAnimator& p
       indexKey = pair.first.indexKey;
     }
 
-    if( indexKey == Dali::Toolkit::LayoutTransitionData::AnimatorKey::PROPERTY )
+    if( indexKey == Dali::Toolkit::LayoutTransitionData::AnimatorKey::CONDITION )
+    {
+      layoutDataElement.condition = value.Get<int>();
+    }
+    else if( indexKey == Dali::Toolkit::LayoutTransitionData::AnimatorKey::PROPERTY )
     {
       if( value.GetType() == Property::STRING )
       {
@@ -449,21 +466,63 @@ bool LayoutTransitionData::ConvertToLayoutDataElement( const PropertyAnimator& p
   return propertyFound;
 }
 
-void LayoutTransitionData::ConvertToLayoutDataElements( Actor owner, LayoutData& layoutData )
+void LayoutTransitionData::ConvertChildrenAnimatorsToLayoutDataElements( Actor child, LayoutData& layoutData )
 {
   LayoutDataArray& layoutDataArray = layoutData.layoutDataArray;
   // Add the children animators
   for( const PropertyAnimator& iter : layoutData.childrenPropertyAnimators )
   {
     LayoutDataElement layoutDataElement;
-    layoutDataElement.handle = owner;
+    layoutDataElement.handle = child;
     layoutDataElement.positionDataIndex = layoutData.layoutPositionDataArray.size() - 1;
 
     if( ConvertToLayoutDataElement( iter, layoutDataElement, layoutData ) )
     {
+      switch ( layoutDataElement.condition )
+      {
+      case Dali::Toolkit::LayoutTransitionData::Condition::ON_ADD:
+        if ( layoutData.layoutTransition.layoutTransitionType != Dali::Toolkit::LayoutTransitionData::ON_CHILD_ADD
+            || layoutData.layoutTransition.gainedChild != child )
+        {
+          continue;
+        }
+        break;
+      case Dali::Toolkit::LayoutTransitionData::Condition::ON_REMOVE:
+        if( layoutData.layoutTransition.layoutTransitionType != Dali::Toolkit::LayoutTransitionData::ON_CHILD_REMOVE
+            || layoutData.layoutTransition.lostChild != child )
+        {
+          continue;
+        }
+        break;
+      case Dali::Toolkit::LayoutTransitionData::Condition::ON_FOCUS_GAINED:
+        if( layoutData.layoutTransition.layoutTransitionType != Dali::Toolkit::LayoutTransitionData::ON_CHILD_FOCUS
+            || layoutData.layoutTransition.gainedChild != child )
+        {
+          continue;
+        }
+        break;
+      case Dali::Toolkit::LayoutTransitionData::Condition::ON_FOCUS_LOST:
+        if( layoutData.layoutTransition.layoutTransitionType != Dali::Toolkit::LayoutTransitionData::ON_CHILD_FOCUS
+            || layoutData.layoutTransition.lostChild != child )
+        {
+          continue;
+        }
+        break;
+      default:
+        break;
+      }
+
       layoutDataArray.push_back( layoutDataElement );
     }
   }
+}
+
+void LayoutTransitionData::ConvertToLayoutDataElements( Actor owner, LayoutData& layoutData )
+{
+  LayoutDataArray& layoutDataArray = layoutData.layoutDataArray;
+
+  // Add the children animators
+  ConvertChildrenAnimatorsToLayoutDataElements( owner, layoutData );
 
   // Add the transition animators
   for( const PropertyAnimator& iter : mPropertyAnimators )
@@ -493,7 +552,7 @@ void LayoutTransitionData::EmitSignalFinish( int layoutTransitionType )
   if ( !mFinishedSignal.Empty() )
   {
     Dali::Toolkit::LayoutTransitionData handle( this );
-    mFinishedSignal.Emit( static_cast<Dali::Toolkit::LayoutTransitionData::LayoutTransitionType>(layoutTransitionType), handle );
+    mFinishedSignal.Emit( static_cast<Dali::Toolkit::LayoutTransitionData::Type>(layoutTransitionType), handle );
   }
 }
 
index eb9e9d9..dec0b76 100644 (file)
@@ -37,9 +37,11 @@ namespace Internal
 
 struct LayoutTransition
 {
-  LayoutTransition( LayoutItem& layoutItem, int layoutTransitionType )
+  LayoutTransition( LayoutItem& layoutItem, int layoutTransitionType, Actor gainedChild, Actor lostChild )
   : layoutItem( &layoutItem )
   , layoutTransitionType( layoutTransitionType )
+  , gainedChild( gainedChild )
+  , lostChild( lostChild )
   {
   }
 
@@ -50,11 +52,16 @@ struct LayoutTransition
 
   bool operator==( const LayoutTransition& rhs )
   {
-    return ( ( layoutItem.Get() == rhs.layoutItem.Get() ) && layoutTransitionType == rhs.layoutTransitionType );
+    return ( layoutItem.Get() == rhs.layoutItem.Get()
+        && layoutTransitionType == rhs.layoutTransitionType
+        && gainedChild == rhs.gainedChild
+        && lostChild == rhs.lostChild );
   }
 
   LayoutItemPtr layoutItem;
   int layoutTransitionType;
+  Actor gainedChild;
+  Actor lostChild;
 };
 
 const float DEFAULT_TRANSITION_DURATION( 0.5f );
@@ -111,16 +118,10 @@ using LayoutPositionDataArray = std::vector< LayoutPositionData >;
 struct LayoutDataElement
 {
   LayoutDataElement()
-  : propertyIndex( Property::INVALID_KEY ), animatorIndex( -1 ), positionDataIndex(-1 )
-  {
-  };
-
-  LayoutDataElement( Actor actor, Property::Index propertyIndex, Property::Value value )
-  : handle( actor ),
-    propertyIndex( propertyIndex ),
-    targetValue( value ),
+  : propertyIndex( Property::INVALID_KEY ),
     animatorIndex( -1 ),
-    positionDataIndex( -1 )
+    positionDataIndex(-1 ),
+    condition( Dali::Toolkit::LayoutTransitionData::Condition::NONE )
   {
   };
 
@@ -130,6 +131,7 @@ struct LayoutDataElement
   Property::Value targetValue;
   int animatorIndex;
   int positionDataIndex;
+  int condition;
 };
 
 class LayoutTransitionData;
@@ -166,22 +168,86 @@ public:
   LayoutTransitionData( const LayoutTransitionData& ) = delete;
   LayoutTransitionData& operator=( const LayoutTransitionData& ) = delete;
 
+  /**
+   * @brief Add a property animator for an actor in the transition
+   * @param[in] actor The actor
+   * @param[in] map The map containing the transition animator keys
+   *
+   * This will add the property animator to the list of animators related to this transition
+   */
   void AddPropertyAnimator( Actor actor, Property::Map map );
+
+  /**
+   * @brief Add a property animator for an actor in the transition
+   * @param[in] actor The actor
+   * @param[in] map The map containing the transition animator keys
+   * @param[in] keyFrames The key frames used by the property animator
+   * @param[in] interpolation The interpolation used by the property animator
+   *
+   * This will add the property animator to the list of animators related to this transition
+   */
   void AddPropertyAnimator( Actor actor, Property::Map map, KeyFrames keyFrames, Animation::Interpolation interpolation );
+
+  /**
+   * @brief Add a property animator for an actor in the transition
+   * @param[in] actor The actor
+   * @param[in] map The map containing the transition animator keys
+   * @param[in] path The path for the property animator
+   * @param[in] forward The forward vector for the property animator
+   *
+   * This will add the property animator to the list of animators related to this transition
+   */
   void AddPropertyAnimator( Actor actor, Property::Map map, Path path, Vector3 forward );
 
+  /**
+   * @brief Convert the transition property animators to the layout data elements
+   * @param[in] actor The actor the transition property animators are applied to
+   * @param[in] layoutData The layout data containing layout data elements array for the layout update
+   *
+   * This will parse the property animators and add the layout data elements to the layout data elements array
+   */
   void ConvertToLayoutDataElements( Actor, LayoutData& layoutData );
 
   /**
-   * @copydoc Dali::Animation::FinishedSignal()
+   * @brief Convert the transition children property animators to the layout data elements
+   * @param[in] actor The actor the transition property animators are applied to
+   * @param[in] layoutData The layout data containing layout data elements array for the layout update
+   *
+   * This will parse the children property animators and add the layout data elements to the layout data elements array
+   */
+  static void ConvertChildrenAnimatorsToLayoutDataElements( Actor, LayoutData& layoutData );
+
+  /**
+   * @copydoc Dali::Toolkit::LayoutTransitionData::FinishedSignal()
    */
   Dali::Toolkit::LayoutTransitionData::LayoutTransitionSignalType& FinishedSignal();
 
+  /**
+   * @brief Emit the transition finish signal
+   * @param[in] layoutTransitionType The transition type
+   */
   void EmitSignalFinish( int layoutTransitionType );
 
 private:
-  bool ConvertToLayoutAnimator( const Property::Map& animatorData, const PropertyAnimator& propertyAnimator, LayoutDataAnimator& layoutAnimator );
-  bool ConvertToLayoutDataElement( const PropertyAnimator& propertyAnimator, LayoutDataElement& layoutDataElement, LayoutData& layoutData );
+  /**
+   * @brief Convert the property animator data to the layout data animator
+   * @param[in] animatorData The animator data map
+   * @param[in] propertyAnimator The property animator
+   * @param[in] layoutAnimator The layout animator
+   *
+   * This will parse the property animator data and add the layout data element animator
+   */
+  static bool ConvertToLayoutAnimator( const Property::Map& animatorData, const PropertyAnimator& propertyAnimator, LayoutDataAnimator& layoutAnimator );
+
+  /**
+   * @brief Convert the property animator to the layout data element
+   * @param[in] propertyAnimator The property animator
+   * @param[in] layoutDataElement The layout data element
+   * @param[in] layoutDataElement The layout data
+   *
+   * This will parse the children property animators and add the layout data elements to the layout data elements array
+   */
+  static bool ConvertToLayoutDataElement( const PropertyAnimator& propertyAnimator, LayoutDataElement& layoutDataElement, LayoutData& layoutData );
 
   PropertyAnimatorArray mPropertyAnimators;
 
diff --git a/dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.cpp b/dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.cpp
new file mode 100644 (file)
index 0000000..11f2f24
--- /dev/null
@@ -0,0 +1,290 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.h>
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/common/stage.h>
+#include <dali/devel-api/common/stage-devel.h>
+#include <dali/integration-api/debug.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/public-api/visuals/image-visual-properties.h>
+#include <dali-toolkit/public-api/visuals/visual-properties.h>
+#include <dali-toolkit/internal/visuals/image-visual-shader-factory.h>
+#include <dali-toolkit/internal/visuals/visual-factory-cache.h>
+#include <dali-toolkit/internal/visuals/visual-string-constants.h>
+#include <dali-toolkit/internal/visuals/visual-base-data-impl.h>
+#include <dali-toolkit/internal/visuals/animated-vector-image/vector-image-rasterize-thread.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+namespace
+{
+
+const Dali::Vector4 FULL_TEXTURE_RECT( 0.f, 0.f, 1.f, 1.f );
+
+} // unnamed namespace
+
+AnimatedVectorImageVisualPtr AnimatedVectorImageVisual::New( VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl, const Property::Map& properties )
+{
+  AnimatedVectorImageVisualPtr visual( new AnimatedVectorImageVisual( factoryCache, shaderFactory, imageUrl ) );
+  visual->SetProperties( properties );
+
+  return visual;
+}
+
+AnimatedVectorImageVisualPtr AnimatedVectorImageVisual::New( VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl )
+{
+  AnimatedVectorImageVisualPtr visual( new AnimatedVectorImageVisual( factoryCache, shaderFactory, imageUrl ) );
+
+  return visual;
+}
+
+AnimatedVectorImageVisual::AnimatedVectorImageVisual( VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl )
+: Visual::Base( factoryCache, Visual::FittingMode::FILL ),
+  mImageVisualShaderFactory( shaderFactory ),
+  mUrl( imageUrl ),
+  mVisualSize(),
+  mPlacementActor(),
+  mVectorRasterizeThread(),
+  mActionStatus( DevelAnimatedVectorImageVisual::Action::STOP )
+{
+  // the rasterized image is with pre-multiplied alpha format
+  mImpl->mFlags |= Impl::IS_PREMULTIPLIED_ALPHA;
+}
+
+AnimatedVectorImageVisual::~AnimatedVectorImageVisual()
+{
+}
+
+void AnimatedVectorImageVisual::GetNaturalSize( Vector2& naturalSize )
+{
+  naturalSize = mVisualSize;
+}
+
+void AnimatedVectorImageVisual::DoCreatePropertyMap( Property::Map& map ) const
+{
+  map.Clear();
+  map.Insert( Toolkit::Visual::Property::TYPE, Toolkit::DevelVisual::ANIMATED_VECTOR_IMAGE );
+  if( mUrl.IsValid() )
+  {
+    map.Insert( Toolkit::ImageVisual::Property::URL, mUrl.GetUrl() );
+  }
+}
+
+void AnimatedVectorImageVisual::DoCreateInstancePropertyMap( Property::Map& map ) const
+{
+  // Do nothing
+}
+
+void AnimatedVectorImageVisual::DoSetProperties( const Property::Map& propertyMap )
+{
+  // url already passed in from constructor
+  for( Property::Map::SizeType iter = 0; iter < propertyMap.Count(); ++iter )
+  {
+    KeyValuePair keyValue = propertyMap.GetKeyValue( iter );
+    if( keyValue.first.type == Property::Key::INDEX )
+    {
+      DoSetProperty( keyValue.first.indexKey, keyValue.second );
+    }
+  }
+}
+
+void AnimatedVectorImageVisual::DoSetProperty( Property::Index index, const Property::Value& value )
+{
+}
+
+void AnimatedVectorImageVisual::DoSetOnStage( Actor& actor )
+{
+  Shader shader;
+
+  if( mImpl->mCustomShader )
+  {
+    shader = Shader::New( mImpl->mCustomShader->mVertexShader.empty() ? mImageVisualShaderFactory.GetVertexShaderSource() : mImpl->mCustomShader->mVertexShader,
+                          mImpl->mCustomShader->mFragmentShader.empty() ? mImageVisualShaderFactory.GetFragmentShaderSource() : mImpl->mCustomShader->mFragmentShader,
+                          mImpl->mCustomShader->mHints );
+
+    shader.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT );
+  }
+  else
+  {
+    shader = mImageVisualShaderFactory.GetShader( mFactoryCache, false, true );
+  }
+
+  Geometry geometry = mFactoryCache.GetGeometry( VisualFactoryCache::QUAD_GEOMETRY );
+
+  mImpl->mRenderer = Renderer::New( geometry, shader );
+
+  TextureSet textureSet = TextureSet::New();
+  mImpl->mRenderer.SetTextures( textureSet );
+
+  // Register transform properties
+  mImpl->mTransform.RegisterUniforms( mImpl->mRenderer, Direction::LEFT_TO_RIGHT );
+
+  // Defer the rasterisation task until we get given a size (by Size Negotiation algorithm)
+
+  // Hold the weak handle of the placement actor and delay the adding of renderer until the rasterization is finished.
+  mPlacementActor = actor;
+
+  // This visual needs it's size set before it can be rasterized hence set ResourceReady once on stage
+  ResourceReady( Toolkit::Visual::ResourceStatus::READY );
+}
+
+void AnimatedVectorImageVisual::DoSetOffStage( Actor& actor )
+{
+  if( mVectorRasterizeThread )
+  {
+    mVectorRasterizeThread->PauseAnimation();
+    DevelStage::SetRenderingBehavior( Stage::GetCurrent(), DevelStage::Rendering::IF_REQUIRED );
+    mActionStatus = DevelAnimatedVectorImageVisual::Action::PAUSE;
+  }
+
+  if( mImpl->mRenderer )
+  {
+    actor.RemoveRenderer( mImpl->mRenderer );
+    mImpl->mRenderer.Reset();
+  }
+
+  mPlacementActor.Reset();
+
+  // Reset the visual size to zero so that when adding the actor back to stage the rasterization is forced
+  mVisualSize = Vector2::ZERO;
+}
+
+void AnimatedVectorImageVisual::OnSetTransform()
+{
+  Vector2 visualSize = mImpl->mTransform.GetVisualSize( mImpl->mControlSize );
+
+  if( IsOnStage() )
+  {
+    if( visualSize != mVisualSize )
+    {
+      mVisualSize = visualSize;
+
+      if( !mVectorRasterizeThread )
+      {
+        uint32_t width = static_cast< uint32_t >( visualSize.width );
+        uint32_t height = static_cast< uint32_t >( visualSize.height );
+
+        mVectorRasterizeThread = std::unique_ptr< VectorRasterizeThread >( new VectorRasterizeThread( mUrl.GetUrl(), mImpl->mRenderer, width, height ) );
+
+        mVectorRasterizeThread->SetResourceReadyCallback( new EventThreadCallback( MakeCallback( this, &AnimatedVectorImageVisual::OnResourceReady ) ) );
+        mVectorRasterizeThread->Start();
+
+        if( mActionStatus == DevelAnimatedVectorImageVisual::Action::PLAY )
+        {
+          mVectorRasterizeThread->StartAnimation();
+          DevelStage::SetRenderingBehavior( Stage::GetCurrent(), DevelStage::Rendering::CONTINUOUSLY );
+        }
+        else
+        {
+          // Render one frame
+          mVectorRasterizeThread->RenderFrame();
+        }
+      }
+      else
+      {
+        // TODO: change size
+      }
+    }
+  }
+}
+
+void AnimatedVectorImageVisual::OnDoAction( const Property::Index actionId, const Property::Value& attributes )
+{
+  if( actionId == mActionStatus )
+  {
+    return;
+  }
+
+  // Check if action is valid for this visual type and perform action if possible
+  switch( actionId )
+  {
+    case DevelAnimatedVectorImageVisual::Action::PLAY:
+    {
+      if( IsOnStage())
+      {
+        if( mVectorRasterizeThread )
+        {
+          mVectorRasterizeThread->StartAnimation();
+          DevelStage::SetRenderingBehavior( Stage::GetCurrent(), DevelStage::Rendering::CONTINUOUSLY );   //TODO: Should manage this globally
+        }
+      }
+      mActionStatus = DevelAnimatedVectorImageVisual::Action::PLAY;
+      break;
+    }
+    case DevelAnimatedVectorImageVisual::Action::PAUSE:
+    {
+      if( mVectorRasterizeThread )
+      {
+        mVectorRasterizeThread->PauseAnimation();
+        DevelStage::SetRenderingBehavior( Stage::GetCurrent(), DevelStage::Rendering::IF_REQUIRED );
+      }
+      mActionStatus = DevelAnimatedVectorImageVisual::Action::PAUSE;
+      break;
+    }
+    case DevelAnimatedVectorImageVisual::Action::RESUME:
+    {
+      if( mVectorRasterizeThread )
+      {
+        mVectorRasterizeThread->ResumeAnimation();
+        DevelStage::SetRenderingBehavior( Stage::GetCurrent(), DevelStage::Rendering::CONTINUOUSLY );
+      }
+      mActionStatus = DevelAnimatedVectorImageVisual::Action::RESUME;
+      break;
+    }
+    case DevelAnimatedVectorImageVisual::Action::STOP:
+    {
+      if( mVectorRasterizeThread )
+      {
+        mVectorRasterizeThread->StopAnimation();
+        DevelStage::SetRenderingBehavior( Stage::GetCurrent(), DevelStage::Rendering::IF_REQUIRED );
+      }
+      mActionStatus = DevelAnimatedVectorImageVisual::Action::STOP;
+      break;
+    }
+  }
+}
+
+void AnimatedVectorImageVisual::OnResourceReady()
+{
+  // If weak handle is holding a placement actor, it is the time to add the renderer to actor.
+  Actor actor = mPlacementActor.GetHandle();
+  if( actor )
+  {
+    actor.AddRenderer( mImpl->mRenderer );
+    // reset the weak handle so that the renderer only get added to actor once
+    mPlacementActor.Reset();
+
+    Stage::GetCurrent().KeepRendering( 0.0f );
+  }
+}
+
+} // namespace Internal
+
+} // namespace Toolkit
+
+} // namespace Dali
diff --git a/dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.h b/dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.h
new file mode 100644 (file)
index 0000000..33c46b6
--- /dev/null
@@ -0,0 +1,174 @@
+#ifndef DALI_TOOLKIT_INTERNAL_ANIMATED_VECTOR_IMAGE_VISUAL_H
+#define DALI_TOOLKIT_INTERNAL_ANIMATED_VECTOR_IMAGE_VISUAL_H
+
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/common/intrusive-ptr.h>
+#include <dali/public-api/object/weak-handle.h>
+#include <memory>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/visuals/visual-base-impl.h>
+#include <dali-toolkit/internal/visuals/visual-url.h>
+#include <dali-toolkit/devel-api/visuals/animated-vector-image-visual-actions-devel.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+class ImageVisualShaderFactory;
+class VectorRasterizeThread;
+class AnimatedVectorImageVisual;
+using AnimatedVectorImageVisualPtr = IntrusivePtr< AnimatedVectorImageVisual >;
+
+/**
+ * The visual which renders an animated vector image using VectorAnimationRenderer.
+ * VectorAnimationRenderer renders the animation image and this visuall controls the images.
+ *
+ * The following property is essential
+ *
+ * | %Property Name           | Type             |
+ * |--------------------------|------------------|
+ * | url                      | STRING           |
+ *
+ */
+class AnimatedVectorImageVisual: public Visual::Base
+{
+public:
+
+  /**
+   * @brief Create the AnimatedVectorImageVisual using the image URL.
+   *
+   * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object
+   * @param[in] shaderFactory The ImageVisualShaderFactory object
+   * @param[in] imageUrl The URL to an animated vector image to use
+   * @param[in] properties A Property::Map containing settings for this visual
+   * @return A smart-pointer to the newly allocated visual.
+   */
+  static AnimatedVectorImageVisualPtr New( VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl, const Property::Map& properties );
+
+  /**
+   * @brief Create the AnimatedVectorImageVisual using the image URL.
+   *
+   * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object
+   * @param[in] shaderFactory The ImageVisualShaderFactory object
+   * @param[in] imageUrl The URL to an animated vector image to use
+   * @return A smart-pointer to the newly allocated visual.
+   */
+  static AnimatedVectorImageVisualPtr New( VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl );
+
+public:  // from Visual
+
+  /**
+   * @copydoc Visual::Base::GetNaturalSize
+   */
+  virtual void GetNaturalSize( Vector2& naturalSize ) override;
+
+  /**
+   * @copydoc Visual::Base::CreatePropertyMap
+   */
+  virtual void DoCreatePropertyMap( Property::Map& map ) const override;
+
+  /**
+   * @copydoc Visual::Base::CreateInstancePropertyMap
+   */
+  virtual void DoCreateInstancePropertyMap( Property::Map& map ) const override;
+
+protected:
+
+  /**
+   * @brief Constructor.
+   *
+   * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object
+   * @param[in] shaderFactory The ImageVisualShaderFactory object
+   * @param[in] imageUrl The URL to an animated vector image to use
+   */
+  AnimatedVectorImageVisual( VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl );
+
+  /**
+   * @brief A reference counted object may only be deleted by calling Unreference().
+   */
+  virtual ~AnimatedVectorImageVisual();
+
+  /**
+   * @copydoc Visual::Base::DoSetProperties
+   */
+  virtual void DoSetProperties( const Property::Map& propertyMap ) override;
+
+  /**
+   * @copydoc Visual::Base::DoSetOnStage
+   */
+  virtual void DoSetOnStage( Actor& actor ) override;
+
+  /**
+   * @copydoc Visual::Base::DoSetOffStage
+   */
+  virtual void DoSetOffStage( Actor& actor ) override;
+
+  /**
+   * @copydoc Visual::Base::OnSetTransform
+   */
+  virtual void OnSetTransform() override;
+
+  /**
+   * @copydoc Visual::Base::OnDoAction
+   */
+  virtual void OnDoAction( const Property::Index actionId, const Property::Value& attributes ) override;
+
+private:
+
+  /**
+   * Helper method to set individual values by index key.
+   * @param[in] index The index key of the value
+   * @param[in] value The value
+   */
+  void DoSetProperty( Property::Index index, const Property::Value& value );
+
+  /**
+   * @brief Event callback from rasterize thread. This is called after the first frame is ready.
+   */
+  void OnResourceReady();
+
+  // Undefined
+  AnimatedVectorImageVisual( const AnimatedVectorImageVisual& visual ) = delete;
+
+  // Undefined
+  AnimatedVectorImageVisual& operator=( const AnimatedVectorImageVisual& visual ) = delete;
+
+private:
+  ImageVisualShaderFactory&                    mImageVisualShaderFactory;
+  VisualUrl                                    mUrl;
+  Vector2                                      mVisualSize;
+  WeakHandle< Actor >                          mPlacementActor;
+  std::unique_ptr< VectorRasterizeThread >     mVectorRasterizeThread;
+  DevelAnimatedVectorImageVisual::Action::Type mActionStatus;
+};
+
+} // namespace Internal
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_INTERNAL_ANIMATED_VECTOR_IMAGE_VISUAL_H
diff --git a/dali-toolkit/internal/visuals/animated-vector-image/vector-image-rasterize-thread.cpp b/dali-toolkit/internal/visuals/animated-vector-image/vector-image-rasterize-thread.cpp
new file mode 100644 (file)
index 0000000..50bf304
--- /dev/null
@@ -0,0 +1,223 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali-toolkit/internal/visuals/animated-vector-image/vector-image-rasterize-thread.h>
+
+// EXTERNAL INCLUDES
+#include <dali/devel-api/adaptor-framework/thread-settings.h>
+#include <dali/integration-api/adaptors/adaptor.h>
+#include <dali/integration-api/debug.h>
+
+// INTERNAL INCLUDES
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+namespace
+{
+
+#if defined(DEBUG_ENABLED)
+Debug::Filter* gVectorAnimationLogFilter = Debug::Filter::New( Debug::NoLogging, false, "LOG_VECTOR_ANIMATION" );
+#endif
+
+} // unnamed namespace
+
+VectorRasterizeThread::VectorRasterizeThread( const std::string& url, Renderer renderer, uint32_t width, uint32_t height )
+: mUrl( url ),
+  mVectorRenderer(),
+  mResourceReadyTrigger( NULL ),
+  mCurrentFrame( 0 ),
+  mTotalFrame( 0 ),
+  mWidth( width ),
+  mHeight( height ),
+  mNeedRender( false ),
+  mPlaying( false ),
+  mPaused( false ),
+  mDestroyThread( false ),
+  mResourceReady( false ),
+  mLogFactory( Dali::Adaptor::Get().GetLogFactory() )
+{
+  mVectorRenderer = VectorAnimationRenderer::New( mUrl, renderer, width, height );
+}
+
+VectorRasterizeThread::~VectorRasterizeThread()
+{
+  // Stop the thread
+  {
+    ConditionalWait::ScopedLock lock( mConditionalWait );
+    mDestroyThread = true;
+    mConditionalWait.Notify( lock );
+
+    // This should be called in the main thread to stop waiting for the dequeuable buffer.
+    mVectorRenderer.StopRender();
+  }
+
+  DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::~VectorRasterizeThread: Join\n" );
+
+  Join();
+
+  delete mResourceReadyTrigger;
+}
+
+void VectorRasterizeThread::Run()
+{
+  SetThreadName( "VectorImageThread" );
+  mLogFactory.InstallLogFunction();
+
+  //TODO: check the return value
+  StartRender();
+
+  while( IsThreadReady() )
+  {
+    Rasterize();
+  }
+}
+
+void VectorRasterizeThread::StartAnimation()
+{
+  ConditionalWait::ScopedLock lock( mConditionalWait );
+  if( !mPlaying )
+  {
+    mPlaying = true;
+    mPaused = false;
+    mConditionalWait.Notify( lock );
+
+    DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::StartAnimation: Start\n" );
+  }
+}
+
+void VectorRasterizeThread::StopAnimation()
+{
+  ConditionalWait::ScopedLock lock( mConditionalWait );
+  if( mPlaying )
+  {
+    mPlaying = false;
+    mPaused = false;
+
+    DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::StopAnimation: Stop\n" );
+  }
+}
+
+void VectorRasterizeThread::PauseAnimation()
+{
+  ConditionalWait::ScopedLock lock( mConditionalWait );
+  if( mPlaying && !mPaused )
+  {
+    mPaused = true;
+
+    DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::PauseAnimation: Pause\n" );
+  }
+}
+
+void VectorRasterizeThread::ResumeAnimation()
+{
+  ConditionalWait::ScopedLock lock( mConditionalWait );
+  if( mPlaying && mPaused )
+  {
+    mPaused = false;
+    mConditionalWait.Notify( lock );
+
+    DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::ResumeAnimation: Resume\n" );
+  }
+}
+
+void VectorRasterizeThread::RenderFrame()
+{
+  ConditionalWait::ScopedLock lock( mConditionalWait );
+  mNeedRender = true;
+  mConditionalWait.Notify( lock );
+
+  DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::RenderFrame: Render\n" );
+}
+
+void VectorRasterizeThread::SetResourceReadyCallback( EventThreadCallback* callback )
+{
+  mResourceReadyTrigger = callback;
+}
+
+bool VectorRasterizeThread::IsThreadReady()
+{
+  ConditionalWait::ScopedLock lock( mConditionalWait );
+
+  if( ( !mPlaying || mPaused ) && !mNeedRender && !mDestroyThread )
+  {
+    DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::IsThreadReady: Wait\n" );
+
+    if( !mPlaying )
+    {
+      mCurrentFrame = 0;
+    }
+
+    mConditionalWait.Wait( lock );
+  }
+
+  // Keep the thread alive if this thread is NOT to be destroyed
+  return !mDestroyThread;
+}
+
+bool VectorRasterizeThread::StartRender()
+{
+  //TODO: check the return value
+  mVectorRenderer.StartRender();
+
+  mTotalFrame = mVectorRenderer.GetTotalFrameNumber();
+
+  DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::StartRender: Renderer is started [%d]\n", mTotalFrame );
+
+  return true;
+}
+
+void VectorRasterizeThread::Rasterize()
+{
+  DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::Rasterize: [%d]\n", mCurrentFrame );
+
+  // Rasterize
+  mVectorRenderer.Render( mCurrentFrame );
+
+  if( mPlaying && !mPaused )
+  {
+    mCurrentFrame++;
+
+    if( mCurrentFrame >= mTotalFrame )
+    {
+      mCurrentFrame = 0;
+    }
+  }
+
+  mNeedRender = false;
+
+  if( !mResourceReady )
+  {
+    DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::Rasterize: Resource ready trigger\n" );
+
+    mResourceReadyTrigger->Trigger();
+    mResourceReady = true;
+  }
+}
+
+} // namespace Internal
+
+} // namespace Toolkit
+
+} // namespace Dali
diff --git a/dali-toolkit/internal/visuals/animated-vector-image/vector-image-rasterize-thread.h b/dali-toolkit/internal/visuals/animated-vector-image/vector-image-rasterize-thread.h
new file mode 100644 (file)
index 0000000..05a5bba
--- /dev/null
@@ -0,0 +1,149 @@
+#ifndef DALI_TOOLKIT_VECTOR_IMAGE_RASTERIZE_THREAD_H
+#define DALI_TOOLKIT_VECTOR_IMAGE_RASTERIZE_THREAD_H
+
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/devel-api/adaptor-framework/event-thread-callback.h>
+#include <dali/devel-api/adaptor-framework/vector-animation-renderer.h>
+#include <dali/devel-api/threading/conditional-wait.h>
+#include <dali/devel-api/threading/mutex.h>
+#include <dali/devel-api/threading/thread.h>
+#include <dali/integration-api/adaptors/log-factory-interface.h>
+#include <string>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+/**
+ * The worker thread for vector image rasterization.
+ */
+class VectorRasterizeThread : public Thread
+{
+public:
+
+  /**
+   * @brief Constructor.
+   *
+   * @param[in] url The url of the vector animation file
+   * @param[in] renderer The renderer used to render the image
+   * @param[in] width The width of the content
+   * @param[in] height The height of the content
+   */
+  VectorRasterizeThread( const std::string& url, Renderer renderer, uint32_t width, uint32_t height );
+
+  /**
+   * @brief Destructor.
+   */
+  virtual ~VectorRasterizeThread();
+
+  /**
+   * @brief Play the vector animation
+   */
+  void StartAnimation();
+
+  /**
+   * @brief Stop the vector animation
+   */
+  void StopAnimation();
+
+  /**
+   * @brief Pause the vector animation
+   */
+  void PauseAnimation();
+
+  /**
+   * @brief Resume the vector animation
+   */
+  void ResumeAnimation();
+
+  /**
+   * @brief Render one frame. The current frame number will be increased.
+   */
+  void RenderFrame();
+
+  /**
+   * @brief This callback is called after the first frame is ready.
+   * @param callback The resource ready callback
+   */
+  void SetResourceReadyCallback( EventThreadCallback* callback );
+
+protected:
+
+  /**
+   * @brief The entry function of the worker thread.
+   *        It rasterizes the vector image.
+   */
+  void Run() override;
+
+private:
+
+  /**
+   * @brief Called by the rasterize thread which ensures a wait if required.
+   * @return false if the thread should stop.
+   */
+  bool IsThreadReady();
+
+  /**
+   * @brief Start rendering
+   */
+  bool StartRender();
+
+  /**
+   * @brief Rasterize the current frame.
+   */
+  void Rasterize();
+
+  // Undefined
+  VectorRasterizeThread( const VectorRasterizeThread& thread ) = delete;
+
+  // Undefined
+  VectorRasterizeThread& operator=( const VectorRasterizeThread& thread ) = delete;
+
+private:
+
+  std::string                mUrl;
+  VectorAnimationRenderer    mVectorRenderer;
+  ConditionalWait            mConditionalWait;
+  Dali::Mutex                mMutex;
+  EventThreadCallback*       mResourceReadyTrigger;
+  uint32_t                   mCurrentFrame;
+  uint32_t                   mTotalFrame;
+  uint32_t                   mWidth;
+  uint32_t                   mHeight;
+  bool                       mNeedRender;
+  bool                       mPlaying;
+  bool                       mPaused;
+  bool                       mDestroyThread;  ///< Whether the thread be destroyed
+  bool                       mResourceReady;
+  const Dali::LogFactoryInterface& mLogFactory; ///< The log factory
+
+};
+
+} // namespace Internal
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_VECTOR_IMAGE_RASTERIZE_THREAD_H
index 4afade9..d30729b 100644 (file)
@@ -41,6 +41,7 @@
 #include <dali-toolkit/internal/visuals/svg/svg-visual.h>
 #include <dali-toolkit/internal/visuals/text/text-visual.h>
 #include <dali-toolkit/internal/visuals/animated-image/animated-image-visual.h>
+#include <dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.h>
 #include <dali-toolkit/internal/visuals/wireframe/wireframe-visual.h>
 #include <dali-toolkit/internal/visuals/visual-factory-cache.h>
 #include <dali-toolkit/internal/visuals/visual-url.h>
@@ -161,6 +162,11 @@ Toolkit::Visual::Base VisualFactory::CreateVisual( const Property::Map& property
                 visualPtr = AnimatedImageVisual::New( GetFactoryCache(), GetImageVisualShaderFactory(), visualUrl, propertyMap );
                 break;
               }
+              case VisualUrl::JSON:
+              {
+                visualPtr = AnimatedVectorImageVisual::New( GetFactoryCache(),  GetImageVisualShaderFactory(), imageUrl, propertyMap );
+                break;
+              }
               case VisualUrl::REGULAR_IMAGE:
               {
                 visualPtr = ImageVisual::New( GetFactoryCache(), GetImageVisualShaderFactory(), visualUrl, propertyMap );
@@ -254,6 +260,17 @@ Toolkit::Visual::Base VisualFactory::CreateVisual( const Property::Map& property
       visualPtr = AnimatedGradientVisual::New( GetFactoryCache(), propertyMap );
       break;
     }
+
+    case Toolkit::DevelVisual::ANIMATED_VECTOR_IMAGE:
+    {
+      Property::Value* imageURLValue = propertyMap.Find( Toolkit::ImageVisual::Property::URL, IMAGE_URL_NAME );
+      std::string imageUrl;
+      if( imageURLValue && imageURLValue->Get( imageUrl ) )
+      {
+        visualPtr = AnimatedVectorImageVisual::New( GetFactoryCache(),  GetImageVisualShaderFactory(), imageUrl, propertyMap );
+      }
+      break;
+    }
   }
 
   if( !visualPtr )
@@ -321,6 +338,11 @@ Toolkit::Visual::Base VisualFactory::CreateVisual( const std::string& url, Image
         visualPtr = AnimatedImageVisual::New( GetFactoryCache(), GetImageVisualShaderFactory(), visualUrl );
         break;
       }
+      case VisualUrl::JSON:
+      {
+        visualPtr = AnimatedVectorImageVisual::New( GetFactoryCache(),  GetImageVisualShaderFactory(), visualUrl );
+        break;
+      }
       case VisualUrl::REGULAR_IMAGE:
       {
         visualPtr = ImageVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), visualUrl, size );
index ad5b4ae..9257a74 100644 (file)
@@ -44,6 +44,7 @@ DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::Visual, SVG )
 DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::Visual, ANIMATED_IMAGE )
 DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::Visual, WIREFRAME )
 DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::DevelVisual, ANIMATED_GRADIENT )
+DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::DevelVisual, ANIMATED_VECTOR_IMAGE )
 DALI_ENUM_TO_STRING_TABLE_END( VISUAL_TYPE )
 
 // Visual Type
index b1f5f3e..731ed20 100644 (file)
@@ -99,8 +99,10 @@ VisualUrl::Type ResolveType( const std::string& url )
     enum { SUFFIX, HASH, HASH_DOT } state = SUFFIX;
     char SVG[ 4 ] = { 'g', 'v', 's', '.' };
     char GIF[ 4 ] = { 'f', 'i', 'g', '.' };
+    char JSON[ 5 ] = { 'n', 'o', 's', 'j', '.' };
     unsigned int svgScore = 0;
     unsigned int gifScore = 0;
+    unsigned int jsonScore = 0;
     int index = count;
     while( --index >= 0 )
     {
@@ -122,6 +124,14 @@ VisualUrl::Type ResolveType( const std::string& url )
           return VisualUrl::GIF;
         }
       }
+      if( ( offsetFromEnd < sizeof(JSON) )&&( currentChar == JSON[ offsetFromEnd ] ) )
+      {
+        // early out if JSON as can't be used in N patch for now
+        if( ++jsonScore == sizeof(JSON) )
+        {
+          return VisualUrl::JSON;
+        }
+      }
       switch( state )
       {
         case SUFFIX:
index aac605c..f3af2e0 100644 (file)
@@ -40,7 +40,8 @@ public:
     REGULAR_IMAGE,
     N_PATCH,
     SVG,
-    GIF
+    GIF,
+    JSON
   };
 
   enum ProtocolType
index 245d4b7..aea1103 100644 (file)
@@ -31,7 +31,7 @@ namespace Toolkit
 
 const unsigned int TOOLKIT_MAJOR_VERSION = 1;
 const unsigned int TOOLKIT_MINOR_VERSION = 3;
-const unsigned int TOOLKIT_MICRO_VERSION = 48;
+const unsigned int TOOLKIT_MICRO_VERSION = 51;
 const char * const TOOLKIT_BUILD_DATE    = __DATE__ " " __TIME__;
 
 #ifdef DEBUG_ENABLED
index aa253df..c7b88f6 100644 (file)
@@ -79,9 +79,6 @@
  + [Visual Debug Rendering](@ref debugrendering)
  + [Stagehand - DALi Visual Debugger](@ref stagehand)
 
-### Viewing Modes
- + [Overview](@ref viewing-modes)
-
 ### Extending DALi
  + [How to write Custom UI Components](@ref creating-custom-controls)
   + [Size Negotiation for Controls](@ref size-negotiation-controls)
diff --git a/docs/content/programming-guide/viewing-modes.h b/docs/content/programming-guide/viewing-modes.h
deleted file mode 100644 (file)
index f2cad16..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/*! \page viewing-modes Viewing modes
- *
- *
- * <h2 class="pg">Introduction</h2>
- *
- * DALi supports multiple viewing modes: <br>
-* <ul>
-*  <li>MONO <br>
-*  <li>STEREO_HORIZONTAL <br>
-*  <li>STEREO_VERTICAL <br>
-* </ul>
-* MONO is the default viewing mode. When using MONO mode, only one image of the scene is produced in every update. In this  setup, DALi will create a default render task, which will render everything added to the stage root layer, and one default camera for that render task.<br><br>
-* STEREO_HORIZONTAL and STEREO_VERTICAL allow the application to produce stereo images. Stereo rendering techniques produce two images of the scene with an slight offset between them which will be presented to the left and the right eye independently. In this setup, DALi will create two additional render tasks, one for the right eye and one for the left, each with it's own camera. Those cameras will be parented to the default camera. The method to generate the projection transformation for each camera is known as "parallel axis asymmetric frustum perspective projection" and is illustrated in the image below.<br><br>
-
-* \image html viewing-modes/stereo-projection.png
-
-* <br>The separation between the two cameras is configurable, but, typically, it should range between 50 and 70 millimeters. Too large a separation can be hard to resolve and is known as hyperstereo. The convergence plane for both frustums is the 2D plane, so, the projection of anything lying in the 2D plane will be coincident for both left and right eyes, hence zero parallax. Objects that lie in front of the projection plane will appear to be in front of the screen and object behind the projection plane will appear to be "into" the screen. Object behind the projection plane ( positive parallax ) are easier to look and minimises eye strain.<br>
-
- * In order to view stereoscopic images correctly, each image must be presented to each eye independently. There exist devices in the market for this, like head-mounted displays, which is a display device, worn in the head, that have two small displays, one for each eye. A cheaper alternative to this often expensive devices is Google's cardboard viewer.<br>
- * \image html viewing-modes/google-cardboard.png
- *<br>With Google cardboard, or some similar device, you can transform your phone into a basic virtual reality headset.
- *
- * <h2 class="pg">Stereoscopic rendering in DALi</h2>
- * STEREO_HORIZONTAL mode will present the left image on the top half of the screen and the right image on the bottom half. It is intended  to be used in landspace orientation, so the images are rotated 90 degrees counterclockwise. STEREO_VERTICAL mode, on the other hand, will render the left image on the left half of the screen and the right image on the right side.<br><br>
-*
-*To define the viewing mode to be used, applications can use the function Dali::Application::SetViewMode defined in the Application class, passing as the parameter which mode to use. It is possible for an application to query which view mode is being used by calling the funcion Dali::Application::GetViewMode. To define the separation between the left and right cameras, the application can use the function Dali::Application::SetStereoBase, passing as a parameter the distance in millimeters. This distance can be queried using Dali::Application::GetStereoBase.<br>
-*It is also possible to set the viewing mode and offset at initialization time using two command-line arguments for this purpose: --view-mode ( or -v ) and 0 for MONO, 1 for STEREO_HORIZONTAL, 2 for STEREO_VERTICAL, and --stereo-base ( or --s ) and the separation in millimeters.<br><br>
-
-* <h2 class="pg">Considerations</h2>
-*There are a some restrictions to be aware of when writing stereoscopic applications using DALi.
-
-<ul>
-*  <li>When stereo mode is selected, the default's render task source actor will be set to an uninitialized actor so it doesn't render anything. Changing the default's render task source actor later on will produce undesired results, as you, typically, do not want to see anything rendered by the default camera when stereo mode is on.<br>
-
-*  <li>Stereo cameras are parented to the default camera, so if the application need to change camera position or orientation it will need to change the default camera transformation. The handle to the default camera can be obtained form the default render task as shown below.<br>
- * @code
- * Dali::RenderTask defaultRenderTask = Dali::Stage::GetCurrent().GetRenderTaskList().GetTask(0);
- * Dali::CameraActor defaultCamera = defaultRenderTask.GetCameraActor();
- * @endcode
-
-*  <li>Stereo render tasks will render everything added to the stage's root layer. If the application need to render any object hierarchy to an off-screen buffer, it will have to set the exclusive flag on that render task so stereo tasks doesn't render that particular subtree. To set the exclusive flag in a render task, the application can call the method Dali::RenderTask::SetExclusive defined in the render task.<br>
-*</ul>
- *
- */
index 8f750dd..0cb3e5c 100644 (file)
@@ -73,14 +73,6 @@ public:
       // 3. start the adaptor
       adaptor->Start();
 
-      // Set the view modes
-
-      if( options.stereo.viewMode > Dali::MONO )
-      {
-        adaptor->SetStereoBase( options.stereo.stereoBase );
-        adaptor->SetViewMode( options.stereo.viewMode );
-      }
-
       // fire the scene create signal
       adaptor->NotifySceneCreated();
 
index 77a78bf..5ac7ff8 100644 (file)
@@ -1,6 +1,6 @@
 Name:       dali-toolkit
 Summary:    Dali 3D engine Toolkit
-Version:    1.3.48
+Version:    1.3.51
 Release:    1
 Group:      System/Libraries
 License:    Apache-2.0 and BSD-3-Clause and MIT