Merge "Fix for text cursor." into devel/master
authorPaul Wisbey <p.wisbey@samsung.com>
Thu, 31 Mar 2016 13:58:36 +0000 (06:58 -0700)
committerGerrit Code Review <gerrit@review.vlan103.tizen.org>
Thu, 31 Mar 2016 13:58:37 +0000 (06:58 -0700)
16 files changed:
automated-tests/src/dali-toolkit/CMakeLists.txt
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-animation-data.cpp [new file with mode: 0644]
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-animation-data.h [new file with mode: 0644]
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-button.cpp [new file with mode: 0644]
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-button.h [new file with mode: 0644]
automated-tests/src/dali-toolkit/utc-Dali-Builder.cpp
dali-toolkit/devel-api/builder/tree-node.cpp
dali-toolkit/devel-api/builder/tree-node.h
dali-toolkit/internal/builder/builder-get-is.inl.h
dali-toolkit/internal/builder/builder-impl-debug.cpp [new file with mode: 0644]
dali-toolkit/internal/builder/builder-impl-debug.h [new file with mode: 0644]
dali-toolkit/internal/builder/builder-impl.cpp
dali-toolkit/internal/builder/builder-impl.h
dali-toolkit/internal/builder/builder-set-property.cpp
dali-toolkit/internal/builder/builder-set-property.h [new file with mode: 0644]
dali-toolkit/internal/file.list

index 10ef2a0..bf5f24b 100644 (file)
@@ -72,6 +72,8 @@ LIST(APPEND TC_SOURCES
    dali-toolkit-test-utils/toolkit-tts-player.cpp
    dali-toolkit-test-utils/dummy-control.cpp
    dali-toolkit-test-utils/dali-test-suite-utils.cpp
+   dali-toolkit-test-utils/test-animation-data.cpp
+   dali-toolkit-test-utils/test-button.cpp
    dali-toolkit-test-utils/test-application.cpp
    dali-toolkit-test-utils/test-platform-abstraction.cpp
    dali-toolkit-test-utils/test-gesture-manager.cpp
diff --git a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-animation-data.cpp b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-animation-data.cpp
new file mode 100644 (file)
index 0000000..57c1e41
--- /dev/null
@@ -0,0 +1,190 @@
+/*
+ * Copyright (c) 2016 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 <dali/dali.h>
+#include <test-animation-data.h>
+
+using namespace Dali;
+
+namespace Test
+{
+
+TestAnimationData::TestAnimationData()
+{
+}
+
+TestAnimationData::~TestAnimationData()
+{
+}
+
+TestAnimationData::AnimationDataElement::AnimationDataElement()
+: alphaFunction( AlphaFunction::DEFAULT ),
+  timePeriodDelay( 0.0f ),
+  timePeriodDuration( 1.0f )
+{
+}
+
+void TestAnimationData::Add( AnimationDataElement* animationDataElement )
+{
+  mAnimationDataList.PushBack( animationDataElement );
+}
+
+std::size_t TestAnimationData::Size() const
+{
+  return mAnimationDataList.Size();
+}
+
+void TestAnimationData::Clear()
+{
+  AnimationDataList::Iterator end = mAnimationDataList.End();
+  for( AnimationDataList::Iterator iter = mAnimationDataList.Begin(); iter != end; ++iter )
+  {
+    delete ( *iter );
+  }
+  mAnimationDataList.Clear();
+}
+
+
+void NewAnimator( const Property::Map& map, TestAnimationData::AnimationDataElement& element )
+{
+  // Now set the properties, or create children
+  for( unsigned int i = 0, animationMapCount = map.Count(); i < animationMapCount; ++i )
+  {
+    const StringValuePair& pair( map.GetPair( i ) );
+    const std::string& key( pair.first );
+    const Property::Value& value( pair.second );
+
+    if( key == "actor" || key == "target" )
+    {
+      element.target = value.Get< std::string >();
+    }
+    else if( key == "property" )
+    {
+      element.property = value.Get< std::string >();
+    }
+    else if( key == "value" )
+    {
+      element.value = value;
+    }
+    else if( key == "alphaFunction" )
+    {
+      std::string alphaFunctionValue = value.Get< std::string >();
+
+      if( alphaFunctionValue == "LINEAR" )
+      {
+        element.alphaFunction = AlphaFunction::LINEAR;
+      }
+      else if( alphaFunctionValue == "REVERSE" )
+      {
+        element.alphaFunction = AlphaFunction::REVERSE;
+      }
+      else if( alphaFunctionValue == "EASE_IN_SQUARE" )
+      {
+        element.alphaFunction = AlphaFunction::EASE_IN_SQUARE;
+      }
+      else if( alphaFunctionValue == "EASE_OUT_SQUARE" )
+      {
+        element.alphaFunction = AlphaFunction::EASE_OUT_SQUARE;
+      }
+      else if( alphaFunctionValue == "EASE_IN" )
+      {
+        element.alphaFunction = AlphaFunction::EASE_IN;
+      }
+      else if( alphaFunctionValue == "EASE_OUT" )
+      {
+        element.alphaFunction = AlphaFunction::EASE_OUT;
+      }
+      else if( alphaFunctionValue == "EASE_IN_OUT" )
+      {
+        element.alphaFunction = AlphaFunction::EASE_IN_OUT;
+      }
+      else if( alphaFunctionValue == "EASE_IN_SINE" )
+      {
+        element.alphaFunction = AlphaFunction::EASE_IN_SINE;
+      }
+      else if( alphaFunctionValue == "EASE_OUT_SINE" )
+      {
+        element.alphaFunction = AlphaFunction::EASE_OUT_SINE;
+      }
+      else if( alphaFunctionValue == "EASE_IN_OUT_SINE" )
+      {
+        element.alphaFunction = AlphaFunction::EASE_IN_OUT_SINE;
+      }
+      else if( alphaFunctionValue == "BOUNCE" )
+      {
+        element.alphaFunction = AlphaFunction::BOUNCE;
+      }
+      else if( alphaFunctionValue == "SIN" )
+      {
+        element.alphaFunction = AlphaFunction::SIN;
+      }
+      else if( alphaFunctionValue == "EASE_OUT_BACK" )
+      {
+        element.alphaFunction = AlphaFunction::EASE_OUT_BACK;
+      }
+    }
+    else if( key == "timePeriod" )
+    {
+      Property::Map timeMap = value.Get< Property::Map >();
+      for( unsigned int i = 0; i < timeMap.Count(); ++i )
+      {
+        const StringValuePair& pair( timeMap.GetPair( i ) );
+        if( pair.first == "delay" )
+        {
+          element.timePeriodDelay = pair.second.Get< float >();
+        }
+        else if( pair.first == "duration" )
+        {
+          element.timePeriodDuration = pair.second.Get< float >();
+        }
+      }
+    }
+    else if( key == "animator" )
+    {
+      if( value.GetType() == Property::MAP )
+      {
+        Property::Map* map = value.GetMap();
+        const Property::Map& mapref = *map;
+        NewAnimator( mapref, element ); // Merge the map into element
+      }
+    }
+  }
+}
+
+void NewAnimation( const Property::Map& map, TestAnimationData& outputAnimationData )
+{
+  TestAnimationData::AnimationDataElement* element = new TestAnimationData::AnimationDataElement();
+  NewAnimator( map, *element );
+
+  outputAnimationData.Add( element );
+}
+
+void NewAnimation( const Property::Array& array, TestAnimationData& outputAnimationData )
+{
+  for(unsigned int i=0; i<array.Size(); ++i )
+  {
+    TestAnimationData::AnimationDataElement* element = new TestAnimationData::AnimationDataElement();
+    const Property::Value& value = array.GetElementAt(i);
+    if( value.GetType() == Property::MAP )
+    {
+      Property::Map* map = value.GetMap();
+      NewAnimator( *map, *element );
+      outputAnimationData.Add( element );
+    }
+  }
+}
+
+} // Test
diff --git a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-animation-data.h b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-animation-data.h
new file mode 100644 (file)
index 0000000..ffd5b17
--- /dev/null
@@ -0,0 +1,71 @@
+#ifndef DALI_TOOLKIT_TEST_TEST_ANIMATION_DATA_H
+#define DALI_TOOLKIT_TEST_TEST_ANIMATION_DATA_H
+
+/*
+ * Copyright (c) 2016 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 <dali/dali.h>
+#include <string>
+
+namespace Test
+{
+
+class TestAnimationData
+{
+public:
+  TestAnimationData();
+  ~TestAnimationData();
+
+  /**
+   * @brief AnimationDataElement Describes one part of an animation.
+   */
+  struct AnimationDataElement
+  {
+    std::string target;
+    std::string property;
+    Dali::Property::Value value;
+    Dali::AlphaFunction::BuiltinFunction alphaFunction;
+    float timePeriodDelay;
+    float timePeriodDuration;
+
+    AnimationDataElement();
+  };
+
+  /**
+   * @brief AnimationData holds the required data required to define an
+   * animation to be performed on a property source.
+   */
+  typedef Dali::Vector< AnimationDataElement* > AnimationDataList;
+
+  /**
+   * @brief Adds one AnimationDataElement to the list to describe one animation.
+   * @param[in] animationDataElement A pre-populated struct to add
+   */
+  void Add( AnimationDataElement* animationDataElement );
+
+  std::size_t Size() const;
+
+  void Clear();
+
+  AnimationDataList mAnimationDataList;
+};
+
+void NewAnimator( const Dali::Property::Map& map, TestAnimationData::AnimationDataElement& element );
+void NewAnimation( const Dali::Property::Map& map, TestAnimationData& outputAnimationData );
+void NewAnimation( const Dali::Property::Array& array, TestAnimationData& outputAnimationData );
+} // Test
+
+#endif  //DALI_TOOLKIT_TEST_TEST_ANIMATION_DATA_H
diff --git a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-button.cpp b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-button.cpp
new file mode 100644 (file)
index 0000000..cbecb9b
--- /dev/null
@@ -0,0 +1,194 @@
+/*
+ * Copyright (c) 2016 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 <dali/dali.h>
+#include <dali-toolkit/dali-toolkit.h>
+#include <test-button.h>
+#include <dali/devel-api/object/type-registry-helper.h>
+
+using namespace Dali;
+using namespace Dali::Toolkit;
+
+namespace
+{
+Property::Value ConvertAnimationMap( const Test::TestAnimationData& animationMap )
+{
+  // We have a data structure. Now convert it back into an array:
+  Property::Array animators;
+  for( unsigned int i=0; i<animationMap.Size(); ++i )
+  {
+    Property::Map animator;
+    animator.Insert( "target", Property::Value(animationMap.mAnimationDataList[i]->target ));
+    animator.Insert( "property", Property::Value(animationMap.mAnimationDataList[i]->property ));
+    animator.Insert( "value", Property::Value(animationMap.mAnimationDataList[i]->value ));
+    animator.Insert( "alphaFunction", Property::Value(animationMap.mAnimationDataList[i]->alphaFunction ));
+    animator.Insert( "timePeriodDelay", Property::Value(animationMap.mAnimationDataList[i]->timePeriodDelay ));
+    animator.Insert( "timePeriodDuration", Property::Value(animationMap.mAnimationDataList[i]->timePeriodDuration ));
+    animators.PushBack( animator );
+  }
+  Property::Value animation( animators );
+  return animation;
+}
+}
+
+namespace Test
+{
+namespace Impl
+{
+
+Test::TestButton TestButton::New()
+{
+  IntrusivePtr<TestButton> internalTestButton = new TestButton();
+  Test::TestButton button( *internalTestButton );
+  internalTestButton->Initialize();
+  return button;
+}
+
+TestButton::TestButton()
+: Control( ControlBehaviour( REQUIRES_TOUCH_EVENTS|REQUIRES_STYLE_CHANGE_SIGNALS ) )
+{
+}
+
+TestButton::~TestButton()
+{
+}
+
+void TestButton::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
+{
+  Test::TestButton button = Test::TestButton::DownCast( Dali::BaseHandle( object ) );
+
+  if ( button )
+  {
+    switch ( index )
+    {
+      case Test::TestButton::Property::PRESS_TRANSITION:
+      {
+        if( value.GetType() == Property::MAP )
+        {
+          Property::Map* valueMap = value.GetMap();
+          TestButton& buttonImpl = GetImpl(button);
+          buttonImpl.mPressTransitionData.Clear();
+          NewAnimation( *valueMap, buttonImpl.mPressTransitionData );
+        }
+        else if( value.GetType() == Property::ARRAY )
+        {
+          Property::Array* valueArray = value.GetArray();
+          TestButton& buttonImpl = GetImpl(button);
+          buttonImpl.mPressTransitionData.Clear();
+          NewAnimation( *valueArray, buttonImpl.mPressTransitionData );
+        }
+        break;
+      }
+    }
+  }
+}
+
+Property::Value TestButton::GetProperty( BaseObject* object, Property::Index propertyIndex )
+{
+  Test::TestButton button = Test::TestButton::DownCast( Dali::BaseHandle( object ) );
+
+  if ( button )
+  {
+    TestButton& buttonImpl = GetImpl(button);
+    switch ( propertyIndex )
+    {
+      case Test::TestButton::Property::PRESS_TRANSITION:
+      {
+        return ConvertAnimationMap(buttonImpl.mPressTransitionData);
+        break;
+      }
+      case Test::TestButton::Property::RELEASE_TRANSITION:
+      {
+        return ConvertAnimationMap(buttonImpl.mReleaseTransitionData);
+        break;
+      }
+      case Test::TestButton::Property::DISABLED_TRANSITION:
+      {
+        return ConvertAnimationMap(buttonImpl.mDisabledTransitionData);
+        break;
+      }
+      case Test::TestButton::Property::ENABLED_TRANSITION:
+      {
+        return ConvertAnimationMap(buttonImpl.mEnabledTransitionData);
+        break;
+      }
+    }
+  }
+  return Property::Value();
+}
+
+BaseHandle Create()
+{
+  return TestButton::New();
+}
+
+// Generates typeRegistration static variable.
+DALI_TYPE_REGISTRATION_BEGIN( Test::TestButton, Dali::Toolkit::Control, Create )
+
+DALI_PROPERTY_REGISTRATION( Test, TestButton, "pressTransition", ARRAY, PRESS_TRANSITION )
+DALI_PROPERTY_REGISTRATION( Test, TestButton, "releaseTransition", ARRAY, RELEASE_TRANSITION)
+DALI_PROPERTY_REGISTRATION( Test, TestButton, "disabledTransition", ARRAY, DISABLED_TRANSITION )
+DALI_PROPERTY_REGISTRATION( Test, TestButton, "enabledTransition", ARRAY, ENABLED_TRANSITION )
+
+DALI_TYPE_REGISTRATION_END()
+
+} // Impl Namespace
+
+TestButton::TestButton()
+: Control()
+{
+}
+
+TestButton::TestButton(const TestButton& button)
+: Control( button )
+{
+}
+
+TestButton::TestButton(Impl::TestButton& impl)
+: Control(impl)
+{
+}
+
+TestButton::TestButton(Dali::Internal::CustomActor* internal)
+: Control(internal)
+{
+  VerifyCustomActorPointer<Impl::TestButton>(internal);
+}
+
+TestButton& TestButton::operator=( const TestButton& button)
+{
+  if(&button != this)
+  {
+    Control::operator=(button);
+  }
+  return *this;
+}
+
+TestButton::~TestButton()
+{
+}
+
+TestButton TestButton::New()
+{
+  return Impl::TestButton::New();
+}
+
+TestButton TestButton::DownCast( BaseHandle handle )
+{
+  return Control::DownCast<TestButton,Impl::TestButton>(handle);
+}
+
+} // namespace Test
diff --git a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-button.h b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-button.h
new file mode 100644 (file)
index 0000000..5dd5ac3
--- /dev/null
@@ -0,0 +1,103 @@
+#ifndef DALI_TOOLKIT_TEST_TEST_BUTTON_H
+#define DALI_TOOLKIT_TEST_TEST_BUTTON_H
+
+/*
+ * Copyright (c) 2016 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 <dali-toolkit/dali-toolkit.h>
+#include <test-animation-data.h>
+
+namespace Test
+{
+namespace Impl
+{
+class TestButton;
+}
+
+class TestButton : public Dali::Toolkit::Control
+{
+public:
+  enum PropertyRange
+  {
+    PROPERTY_START_INDEX = Dali::Toolkit::Control::CONTROL_PROPERTY_END_INDEX + 1,
+    PROPERTY_END_INDEX =   PROPERTY_START_INDEX + 1000
+  };
+  struct Property
+  {
+    enum
+    {
+      PRESS_TRANSITION = PROPERTY_START_INDEX,
+      RELEASE_TRANSITION,
+      DISABLED_TRANSITION,
+      ENABLED_TRANSITION
+    };
+  };
+  TestButton();
+  TestButton(const TestButton& button);
+  TestButton(Impl::TestButton& impl);
+  TestButton(Dali::Internal::CustomActor* internal);
+  TestButton& operator=( const TestButton& button);
+  ~TestButton();
+  static TestButton New();
+  static TestButton DownCast( Dali::BaseHandle handle );
+};
+
+namespace Impl
+{
+
+class TestButton : public Dali::Toolkit::Internal::Control
+{
+public:
+  static Test::TestButton New();
+
+  static void SetProperty( Dali::BaseObject* object,
+                           Dali::Property::Index index,
+                           const Dali::Property::Value& value );
+
+  static Dali::Property::Value GetProperty( Dali::BaseObject* object,
+                                            Dali::Property::Index propertyIndex );
+
+protected:
+  TestButton();
+  virtual ~TestButton();
+
+public:
+  Test::TestAnimationData mPressTransitionData;
+  Test::TestAnimationData mReleaseTransitionData;
+  Test::TestAnimationData mDisabledTransitionData;
+  Test::TestAnimationData mEnabledTransitionData;
+};
+
+inline TestButton& GetImpl( Test::TestButton& handle )
+{
+  DALI_ASSERT_ALWAYS( handle );
+  Dali::RefObject& object = handle.GetImplementation();
+  return static_cast<TestButton&>( object );
+}
+
+inline const TestButton& GetImpl( const Test::TestButton& handle )
+{
+  DALI_ASSERT_ALWAYS( handle );
+  const Dali::RefObject& object = handle.GetImplementation();
+  return static_cast<const TestButton&>( object );
+}
+
+} // Impl
+} // Test
+
+
+
+#endif // DALI_TOOLKIT_TEST_TEST_BUTTON_H
index 653325c..8b06fd1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2014-2016 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.
 #include <dali-toolkit-test-suite-utils.h>
 #include <dali-toolkit/devel-api/builder/builder.h>
 #include <dali/integration-api/events/touch-event-integ.h>
+#include <dali-toolkit/dali-toolkit.h>
+#include <dali/devel-api/object/type-registry-helper.h>
+#include <test-button.h>
+#include <test-animation-data.h>
 
 #define STRINGIFY(A)#A
 
@@ -1455,3 +1459,194 @@ int UtcDaliBuilderPathConstraintsP(void)
 
   END_TEST;
 }
+
+#define CHECK_MAP_ELEMENT( xMap, xKey, xType, xPropType, xExpected, xLocation ) \
+  {                                                                       \
+    Property::Value* value = xMap->Find( xKey );                          \
+    DALI_TEST_EQUALS( value==NULL, false, xLocation);                     \
+    if( value != NULL )                                                   \
+    {                                                                     \
+      DALI_TEST_EQUALS( value->GetType(), xPropType, xLocation );         \
+      xType result;                                                       \
+      value->Get(result);                                                 \
+      DALI_TEST_EQUALS( result, xExpected, TEST_LOCATION );               \
+      std::ostringstream oss;                                             \
+      oss << "Animation element " << xKey << "= " << result << std::endl; \
+      tet_printf( oss.str().c_str() );                                    \
+    }                                                                     \
+    else                                                                  \
+    {                                                                     \
+      tet_printf("Can't find map element " xKey "\n");                    \
+    }                                                                     \
+  }
+
+
+int UtcDaliBuilderMapping01(void)
+{
+  ToolkitTestApplication application;
+
+  const char* json =
+    "{\n"
+    "  \"mappings\":\n"
+    "  {\n"
+    "    \"buttonPressFadeOut\":{\n"
+    "      \"alphaFunction\":\"EASE_OUT\",\n"
+    "      \"timePeriod\":{\n"
+    "        \"delay\":0.0,\n"
+    "        \"duration\":0.4\n"
+    "      }\n"
+    "    },\n"
+    "    \"buttonPressFadeIn\":{\n"
+    "      \"alphaFunction\":\"EASE_IN\",\n"
+    "      \"timePeriod\":{\n"
+    "        \"delay\":0.4,\n"
+    "        \"duration\":0.5\n"
+    "      }\n"
+    "    },\n"
+    "    \"transition:buttonPressed\":\n"
+    "    [\n"
+    "      {\n"
+    "        \"target\": \"unselectedBackgroundRenderer\",\n"
+    "        \"property\": \"opacity\",\n"
+    "        \"value\": 0,\n"
+    "        \"animator\":\"<buttonPressFadeOut>\"\n"
+    "      }\n"
+    "    ],\n"
+    "    \"transition:buttonReleased\":\n"
+    "    [\n"
+    "      {\n"
+    "        \"target\": \"unselectedBackgroundRenderer\",\n"
+    "        \"property\": \"opacity\",\n"
+    "        \"value\": 1,\n"
+    "        \"animator\":\"<buttonPressFadeIn>\"\n"
+    "      },\n"
+    "      {\n"
+    "        \"target\": \"unselectedForegroundRenderer\",\n"
+    "        \"property\": \"scale\",\n"
+    "        \"value\": [ 1, 1, 1 ],\n"
+    "        \"animator\":\"<buttonPressFadeIn>\"\n"
+    "      },\n"
+    "      {\n"
+    "        \"target\": \"selectedBackgroundRenderer\",\n"
+    "        \"property\": \"opacity\",\n"
+    "        \"value\": 0,\n"
+    "        \"animator\": \"<buttonPressFadeOut>\"\n"
+    "      },\n"
+    "      {\n"
+    "        \"target\": \"selectedForegroundRenderer\",\n"
+    "        \"property\": \"scale\",\n"
+    "        \"value\": [ 0, 0, 0 ],\n"
+    "        \"animator\":\"<buttonPressFadeOut>\"\n"
+    "      }\n"
+    "    ]\n"
+    "  },\n"
+    "  \"styles\":\n"
+    "  {\n"
+    "    \"testbutton\":\n"
+    "    {\n"
+    "      \"pressTransition\":\"<transition:buttonPressed>\",\n"
+    "      \"releaseTransition\":\"<transition:buttonReleased>\"\n"
+    "    }\n"
+    "  }\n"
+    "}\n";
+
+  Builder builder = Builder::New();
+  builder.LoadFromString( json );
+
+  Test::TestButton testButton = Test::TestButton::New();
+  Stage::GetCurrent().Add( testButton );
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_CHECK( builder.ApplyStyle( "testbutton", testButton ) );
+
+  // Now check that it has loaded the transition correctly:
+  Property::Value transition = testButton.GetProperty(Test::TestButton::Property::PRESS_TRANSITION);
+  DALI_TEST_EQUALS( transition.GetType(), Property::ARRAY, TEST_LOCATION );
+  Property::Array* array = transition.GetArray();
+
+  DALI_TEST_EQUALS( array->Size(), 1, TEST_LOCATION );
+  Property::Value element = array->GetElementAt(0);
+  DALI_TEST_CHECK( element.GetType() == Property::MAP );
+  Property::Map* map = element.GetMap();
+
+  CHECK_MAP_ELEMENT(map, "target", std::string, Property::STRING, "unselectedBackgroundRenderer", TEST_LOCATION);
+  CHECK_MAP_ELEMENT(map, "property", std::string, Property::STRING, "opacity", TEST_LOCATION);
+  CHECK_MAP_ELEMENT(map, "alphaFunction", int, Property::INTEGER, (int)Dali::AlphaFunction::EASE_OUT, TEST_LOCATION);
+  CHECK_MAP_ELEMENT(map, "timePeriodDelay", float, Property::FLOAT, 0.0f, TEST_LOCATION);
+  CHECK_MAP_ELEMENT(map, "timePeriodDuration", float, Property::FLOAT, 0.4f, TEST_LOCATION);
+
+  END_TEST;
+}
+
+
+int UtcDaliBuilderMappingCycleCheck(void)
+{
+  ToolkitTestApplication application;
+
+  std::string json(
+    "{\n"
+    "  \"mappings\":\n"
+    "  {\n"
+    "    \"cyclicKey1\":\"<cyclicKey1>\",\n"
+    "    \"cyclicKey2\":\"<cyclicKey3>\",\n"
+    "    \"cyclicKey3\":\"<cyclicKey2>\",\n"
+    "    \"FadeOut\":{\n"
+    "      \"alphaFunction\":\"EASE_IN\",\n"
+    "      \"timePeriod\":{\n"
+    "        \"delay\":\"<cyclicKey3>\",\n"
+    "        \"duration\":0.6\n"
+    "      }\n"
+    "    },\n"
+    "    \"transition:buttonPressed\":\n"
+    "    [\n"
+    "      {\n"
+    "        \"target\": \"<cyclicKey1>\",\n"
+    "        \"property\": \"<cyclicKey2>\",\n"
+    "        \"value\": 0,\n"
+    "        \"animator\":\"<FadeOut>\"\n"
+    "      }\n"
+    "    ]\n"
+    "  },\n"
+    "  \"styles\":\n"
+    "  {\n"
+    "    \"testbutton\":\n"
+    "    {\n"
+    "      \"pressTransition\":\"<transition:buttonPressed>\",\n"
+    "      \"releaseTransition\":\"<cyclicKey2>\",\n"
+    "      \"disabledTransition\":\"<cyclicKey3>\",\n"
+    "      \"enabledTransition\":\"<unknownKey>\"\n"
+    "    }\n"
+    "  }\n"
+    "}\n");
+
+  Builder builder = Builder::New();
+  builder.LoadFromString( json );
+
+  Test::TestButton testButton = Test::TestButton::New();
+  Stage::GetCurrent().Add( testButton );
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_CHECK( builder.ApplyStyle( "testbutton", testButton ) );
+
+  // Now check that it has loaded the transition correctly:
+  Property::Value transition = testButton.GetProperty(Test::TestButton::Property::PRESS_TRANSITION);
+  DALI_TEST_EQUALS( transition.GetType(), Property::ARRAY, TEST_LOCATION );
+  Property::Array* array = transition.GetArray();
+
+  DALI_TEST_EQUALS( array->Size(), 1, TEST_LOCATION );
+  Property::Value element = array->GetElementAt(0);
+  DALI_TEST_CHECK( element.GetType() == Property::MAP );
+  Property::Map* map = element.GetMap();
+
+  CHECK_MAP_ELEMENT(map, "target", std::string, Property::STRING, "", TEST_LOCATION);
+  CHECK_MAP_ELEMENT(map, "property", std::string, Property::STRING, "", TEST_LOCATION);
+  CHECK_MAP_ELEMENT(map, "timePeriodDuration", float, Property::FLOAT, 0.6f, TEST_LOCATION);
+
+  END_TEST;
+}
index 3ecb1d5..8515280 100644 (file)
@@ -195,4 +195,3 @@ bool TreeNode::ConstIterator::operator!=( const TreeNode::ConstIterator& rhs ) c
 } // namespace Toolkit
 
 } // namespace Dali
-
index 893caee..6da465a 100644 (file)
@@ -56,7 +56,7 @@ public:
     STRING,
     INTEGER,
     FLOAT,
-    BOOLEAN,
+    BOOLEAN
   };
 
   /*
index 2efc4db..d13b70b 100644 (file)
@@ -57,6 +57,7 @@ inline OptionalString IsString(const OptionalChild& node)
     return OptionalString();
   }
 }
+
 inline OptionalFloat IsFloat(const OptionalChild& node)
 {
   OptionalFloat ret;
@@ -109,6 +110,7 @@ inline OptionalBoolean IsBoolean(const OptionalChild& node)
   }
 }
 
+
 // copy N Numbers
 template <typename T>
 inline bool CopyNumbers(TreeNode::ConstIterator iter, int N, T& vector)
diff --git a/dali-toolkit/internal/builder/builder-impl-debug.cpp b/dali-toolkit/internal/builder/builder-impl-debug.cpp
new file mode 100644 (file)
index 0000000..2e89d71
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2016 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.
+ */
+
+#ifdef DEBUG_ENABLED
+#include <dali-toolkit/internal/builder/builder-impl-debug.h>
+#include <dali-toolkit/internal/builder/builder-impl.h>
+#include <dali-toolkit/internal/builder/builder-get-is.inl.h>
+#include <iostream>
+#include <cstring>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Internal
+{
+
+void LogTree( const Toolkit::JsonParser& parser )
+{
+  if( OptionalChild constants = IsChild(parser.GetRoot(), "constants") )
+  {
+    for(TreeNode::ConstIterator iter = (*constants).CBegin();
+        iter != (*constants).CEnd(); ++iter)
+    {
+      if( ( (*iter).first && strcmp( (*iter).first, "DUMP_TREE" ) == 0 ) ||
+          ( (*iter).second.GetType() == TreeNode::STRING && strcmp( (*iter).second.GetString(), "DUMP_TREE" ) == 0 ) )
+      {
+        std::ostringstream oss;
+        parser.Write(oss, 2);
+        std::cout << oss.str() << std::endl;
+      }
+    }
+  }
+}
+
+std::string PropertyValueToString( const Property::Value& value )
+{
+  std::ostringstream oss;
+  oss << value;
+
+  return oss.str();
+}
+
+} // Internal
+} // Toolkit
+} // Dali
+
+#endif // DEBUG_ENABLED
diff --git a/dali-toolkit/internal/builder/builder-impl-debug.h b/dali-toolkit/internal/builder/builder-impl-debug.h
new file mode 100644 (file)
index 0000000..8d30929
--- /dev/null
@@ -0,0 +1,68 @@
+#ifndef DALI_TOOLKIT_INTERNAL_BUILDER_IMPL_DEBUG_H
+#define DALI_TOOLKIT_INTERNAL_BUILDER_IMPL_DEBUG_H
+
+/*
+ * Copyright (c) 2016 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 <dali/integration-api/debug.h>
+#include <dali-toolkit/devel-api/builder/json-parser.h>
+
+#if defined( DEBUG_ENABLED )
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Internal
+{
+
+#define DUMP_PARSE_TREE(parser)  LogTree(parser)
+#define DUMP_TEST_MAPPINGS(parser)                                      \
+  OptionalChild mappings = IsChild( parser.GetRoot(), KEYNAME_MAPPINGS ); \
+  if( mappings )                                                        \
+  {                                                                     \
+    std::ostringstream oss;                                             \
+    oss << "Mappings: {" << std::endl;                                  \
+    for( TreeNode::ConstIterator iter = (*mappings).CBegin(); iter != (*mappings).CEnd(); ++iter ) \
+    {                                                                   \
+      Property::Value value;                                            \
+      bool converted = GetPropertyMap(*mappings, (*iter).first, Property::NONE, value ); \
+      if( converted )                                                   \
+      {                                                                 \
+        oss << "  " << (*iter).first << ":" << value << std::endl;      \
+      }                                                                 \
+    }                                                                   \
+    oss << "}" << std::endl;                                            \
+    DALI_LOG_INFO( gFilterScript, Debug::Verbose, oss.str().c_str() );  \
+  }
+
+
+void LogTree( const Toolkit::JsonParser& mParser );
+
+std::string PropertyValueToString( const Property::Value& value );
+
+
+} // Internal
+} // Toolkit
+} // Dali
+
+#else
+
+#define DUMP_PARSE_TREE(parser)
+#define DUMP_TEST_MAPPINGS(parser)
+
+#endif // DEBUG_ENABLED
+#endif // DALI_TOOLKIT_INTERNAL_BUILDER_IMPL_DEBUG_H
index f7b89e1..2cf23db 100644 (file)
@@ -21,6 +21,7 @@
 // EXTERNAL INCLUDES
 #include <sys/stat.h>
 #include <sstream>
+
 #include <dali/public-api/render-tasks/render-task-list.h>
 #include <dali/public-api/object/type-info.h>
 #include <dali/public-api/object/type-registry.h>
 #include <dali-toolkit/internal/builder/builder-get-is.inl.h>
 #include <dali-toolkit/internal/builder/builder-filesystem.h>
 #include <dali-toolkit/internal/builder/builder-declarations.h>
+#include <dali-toolkit/internal/builder/builder-set-property.h>
 #include <dali-toolkit/internal/builder/replacement.h>
+#include <dali-toolkit/internal/builder/tree-node-manipulator.h>
+
+#include <dali-toolkit/internal/builder/builder-impl-debug.h>
 
 namespace Dali
 {
@@ -52,10 +57,6 @@ namespace Internal
 class Replacement;
 
 extern Animation CreateAnimation(const TreeNode& child, const Replacement& replacements, const Dali::Actor searchRoot, Builder* const builder );
-extern void DeterminePropertyFromNode( const TreeNode& node, Property::Value& value );
-extern void DeterminePropertyFromNode( const TreeNode& node, Property::Value& value, const Replacement& replacements );
-extern bool DeterminePropertyFromNode( const TreeNode& node, Property::Type type, Property::Value& value );
-extern bool DeterminePropertyFromNode( const TreeNode& node, Property::Type type, Property::Value& value, const Replacement& replacements );
 extern Actor SetupSignalAction(ConnectionTracker* tracker, const TreeNode &root, const TreeNode &child, Actor actor, Dali::Toolkit::Internal::Builder* const builder);
 extern Actor SetupPropertyNotification(ConnectionTracker* tracker, const TreeNode &root, const TreeNode &child, Actor actor, Dali::Toolkit::Internal::Builder* const builder);
 extern Actor SetupActor( const TreeNode& node, Actor& actor, const Replacement& constant );
@@ -76,108 +77,28 @@ const std::string KEYNAME_SIGNALS   = "signals";
 const std::string KEYNAME_NAME      = "name";
 const std::string KEYNAME_TEMPLATES = "templates";
 const std::string KEYNAME_INCLUDES  = "includes";
+const std::string KEYNAME_MAPPINGS  = "mappings";
 
 typedef std::vector<const TreeNode*> TreeNodeList;
 
-template <typename T>
-std::string ToString(const T& value)
-{
-  std::stringstream ss;
-  ss << value;
-  return ss.str();
-}
-
-template <>
-std::string ToString(const Rect<int>& value)
-{
-  std::stringstream ss;
-  ss << value.x << "," << value.y << "," << value.width << "," << value.height;
-  return ss.str();
-}
-
-#if defined(DEBUG_ENABLED)
 
-std::string PropertyValueToString( const Property::Value& value )
+bool GetMappingKey( const std::string& str, std::string& key )
 {
-  std::string ret;
-
-  switch( value.GetType() )
+  bool result = false;
+  std::string test( str );
+  if( ! test.empty() )
   {
-    case Property::NONE:
-    {
-      ret = "NONE";
-      break;
-    }            ///< No type
-    case Property::BOOLEAN:
-    {
-      ret = value.Get<bool>() ? "True" : "False";
-      break;
-    }
-    case Property::FLOAT:
-    {
-
-      ret = ToString( value.Get<float>() );
-      break;
-    }
-    case Property::INTEGER:
-    {
-      ret = ToString( value.Get<int>() );
-      break;
-    }
-    case Property::VECTOR2:
-    {
-      ret = ToString( value.Get<Vector2>() );
-      break;
-    }
-    case Property::VECTOR3:
-    {
-      ret = ToString( value.Get<Vector3>() );
-      break;
-    }
-    case Property::VECTOR4:
-    {
-      ret = ToString( value.Get<Vector4>() );
-      break;
-    }
-    case Property::MATRIX3:
-    {
-      ret = ToString( value.Get<Matrix3>() );
-      break;
-    }
-    case Property::MATRIX:
+    if( test.at(0) == '<' )
     {
-      ret = ToString( value.Get<Matrix>() );
-      break;
-    }
-    case Property::RECTANGLE:
-    {
-      ret = ToString( value.Get< Rect<int> >() );
-      break;
-    }
-    case Property::ROTATION:
-    {
-      break;
-    }
-    case Property::STRING:
-    {
-      ret = value.Get<std::string>();
-      break;
-    }
-    case Property::ARRAY:
-    {
-      ret = std::string("Array Size=") + ToString( value.Get<Property::Array>().Size() );
-      break;
-    }
-    case Property::MAP:
-    {
-      ret = std::string("Map Size=") + ToString( value.Get<Property::Map>().Count() );
-      break;
+      if( test.at(test.length()-1) == '>' )
+      {
+        key = test.substr( 1, test.length()-2 );
+        result = true;
+      }
     }
   }
-
-  return ret;
+  return result;
 }
-#endif // DEBUG_ENABLED
 
 /*
  * Recursively collects all stylesin a node (An array of style names).
@@ -219,6 +140,7 @@ void Builder::SetProperties( const TreeNode& node, Handle& handle, const Replace
 {
   if( handle )
   {
+
     for( TreeNode::ConstIterator iter = node.CBegin(); iter != node.CEnd(); ++iter )
     {
       const TreeNode::KeyNodePair& keyChild = *iter;
@@ -226,16 +148,16 @@ void Builder::SetProperties( const TreeNode& node, Handle& handle, const Replace
       std::string key( keyChild.first );
 
       // ignore special fields; type,actors,signals,styles
-      if(key == KEYNAME_TYPE || key == KEYNAME_ACTORS || key == KEYNAME_SIGNALS || key == KEYNAME_STYLES)
+      if(key == KEYNAME_TYPE || key == KEYNAME_ACTORS || key == KEYNAME_SIGNALS || key == KEYNAME_STYLES || key == KEYNAME_MAPPINGS )
       {
         continue;
       }
 
       // special field 'image' usually contains an json object description
       // although sometimes refers to a framebuffer
-      if( 0 == keyChild.second.Size() )
+      if( key == "image" )
       {
-        if(key == "image")
+        if( 0 == keyChild.second.Size() )
         {
           ImageActor imageActor = ImageActor::DownCast(handle);
           if(imageActor)
@@ -253,7 +175,7 @@ void Builder::SetProperties( const TreeNode& node, Handle& handle, const Replace
       }
 
       // special field 'effect' references the shader effect instances
-      if(key == "effect")
+      if( key == "effect" )
       {
         ImageActor actor = ImageActor::DownCast(handle);
         if( actor )
@@ -296,15 +218,30 @@ void Builder::SetProperties( const TreeNode& node, Handle& handle, const Replace
       if( Property::INVALID_INDEX != index )
       {
         Property::Type type = propertyObject.GetPropertyType(index);
-
         Property::Value value;
-        if( !DeterminePropertyFromNode( keyChild.second, type, value, constant ) )
+        bool mapped = false;
+
+        // if node.value is a mapping, get the property value from the "mappings" table
+        if( keyChild.second.GetType() == TreeNode::STRING )
         {
-          // verbose as this might not be a problem
-          // eg parentOrigin can be a string which is picked up later
-          DALI_SCRIPT_VERBOSE("Could not convert property:%s\n", key.c_str());
+          std::string mappingKey;
+          if( GetMappingKey(keyChild.second.GetString(), mappingKey) )
+          {
+            OptionalChild mappingRoot = IsChild( mParser.GetRoot(), KEYNAME_MAPPINGS );
+            mapped = GetPropertyMap( *mappingRoot, mappingKey.c_str(), type, value );
+          }
         }
-        else
+        if( ! mapped )
+        {
+          mapped = DeterminePropertyFromNode( keyChild.second, type, value, constant );
+          if( ! mapped )
+          {
+            // verbose as this might not be a problem
+            // eg parentOrigin can be a string which is picked up later
+            DALI_SCRIPT_VERBOSE("Could not convert property:%s\n", key.c_str());
+          }
+        }
+        if( mapped )
         {
           DALI_SCRIPT_VERBOSE("SetProperty '%s' Index=:%d Value Type=%d Value '%s'\n", key.c_str(), index, value.GetType(), PropertyValueToString(value).c_str() );
 
@@ -972,7 +909,7 @@ Dali::LinearConstrainer Builder::GetLinearConstrainer( const std::string& name )
 
 bool Builder::IsLinearConstrainer( const std::string& name )
 {
-  //Search the LinearConstrainer in the LUT
+  // Search the LinearConstrainer in the LUT
   size_t count( mLinearConstrainerLut.size() );
   for( size_t i(0); i!=count; ++i )
   {
@@ -1104,6 +1041,118 @@ Animation Builder::CreateAnimation( const std::string& animationName )
   return CreateAnimation( animationName, replacement, Dali::Stage::GetCurrent().GetRootLayer() );
 }
 
+bool Builder::ConvertChildValue( const TreeNode& mappingRoot, KeyStack& keyStack, Property::Value& child )
+{
+  bool result = false;
+
+  switch( child.GetType() )
+  {
+    case Property::STRING:
+    {
+      std::string value;
+      if( child.Get( value ) )
+      {
+        std::string key;
+        if( GetMappingKey( value, key ) )
+        {
+          // Check key for cycles:
+          result=true;
+          for( KeyStack::iterator iter = keyStack.begin() ; iter != keyStack.end(); ++iter )
+          {
+            if( key.compare(*iter) == 0 )
+            {
+              // key is already in stack; stop.
+              DALI_LOG_WARNING("Detected cycle in stylesheet mapping table:%s\n", key.c_str());
+              child = Property::Value("");
+              result=false;
+              break;
+            }
+          }
+
+          if( result )
+          {
+            // The following call will overwrite the child with the value
+            // from the mapping.
+            RecursePropertyMap( mappingRoot, keyStack, key.c_str(), Property::NONE, child );
+            result = true;
+          }
+        }
+      }
+      break;
+    }
+
+    case Property::MAP:
+    {
+      Property::Map* map = child.GetMap();
+      for( Property::Map::SizeType i=0; i < map->Count(); ++i )
+      {
+        Property::Value& child = map->GetValue(i);
+        ConvertChildValue(mappingRoot, keyStack, child);
+      }
+      break;
+    }
+
+    case Property::ARRAY:
+    {
+      Property::Array* array = child.GetArray();
+      for( Property::Array::SizeType i=0; i < array->Count(); ++i )
+      {
+        Property::Value& child = array->GetElementAt(i);
+        ConvertChildValue(mappingRoot, keyStack, child);
+      }
+      break;
+    }
+
+    default:
+      // Ignore other types.
+      break;
+  }
+
+  return result;
+}
+
+bool Builder::RecursePropertyMap( const TreeNode& mappingRoot, KeyStack& keyStack, const char* theKey, Property::Type propertyType, Property::Value& value )
+{
+  Replacement replacer( mReplacementMap );
+  bool result = false;
+
+  keyStack.push_back( theKey );
+
+  for( TreeNode::ConstIterator iter = mappingRoot.CBegin(); iter != mappingRoot.CEnd(); ++iter )
+  {
+    std::string aKey( (*iter).first );
+    if( aKey.compare( theKey ) == 0 )
+    {
+      if( propertyType == Property::NONE )
+      {
+        DeterminePropertyFromNode( (*iter).second, value, replacer );
+        result = true;
+      }
+      else
+      {
+        result = DeterminePropertyFromNode( (*iter).second, propertyType, value, replacer );
+      }
+
+      if( result )
+      {
+        ConvertChildValue(mappingRoot, keyStack, value);
+      }
+      break;
+    }
+  }
+  keyStack.pop_back();
+
+  return result;
+}
+
+
+bool Builder::GetPropertyMap( const TreeNode& mappingRoot, const char* theKey, Property::Type propertyType, Property::Value& value )
+{
+  KeyStack keyStack;
+  return RecursePropertyMap( mappingRoot, keyStack, theKey, propertyType, value );
+}
+
+
 void Builder::LoadFromString( std::string const& data, Dali::Toolkit::Builder::UIFormat format )
 {
   // parser to get constants and includes only
@@ -1153,6 +1202,9 @@ void Builder::LoadFromString( std::string const& data, Dali::Toolkit::Builder::U
     }
   }
 
+  DUMP_PARSE_TREE(parser); // This macro only writes out if DEBUG is enabled and the "DUMP_TREE" constant is defined in the stylesheet.
+  DUMP_TEST_MAPPINGS(parser);
+
   DALI_ASSERT_ALWAYS(mParser.GetRoot() && "Cannot parse JSON");
 }
 
index f046504..a5d6f06 100644 (file)
@@ -258,6 +258,9 @@ private:
 
   Property::Map mReplacementMap;
 
+  typedef std::vector< TreeNode::KeyNodePair > MappingsLut;
+  MappingsLut mCompleteMappings;
+
   BaseHandle Create( const std::string& templateName, const Replacement& constant );
 
   BaseHandle DoCreate( const TreeNode& root, const TreeNode& node, Actor parent, const Replacement& replacements );
@@ -270,6 +273,39 @@ private:
 
   Animation CreateAnimation( const std::string& animationName, const Replacement& replacement, Dali::Actor sourceActor );
 
+  typedef std::vector<const char*> KeyStack;
+
+  /**
+   * Tests if the value is a string delimited by <>. If it is, then it attempts to
+   * change the value to the mapping from a matching key in the mappings table.
+   * @param[in] mappingRoot The JSON node containing the mappings
+   * @param[in,out] keyStack the stack of visited keys
+   * @param[in,out] value The string value to test and write back to.
+   * @return true if the value was converted, false otherwise.
+   */
+  bool ConvertChildValue( const TreeNode& mappingRoot, KeyStack& keyStack, Property::Value& value );
+
+  /**
+   * Find the key in the mapping table, if it's present, then generate a property value for it (of the given type if available), recursing as necessary, and stopping if any cycles
+   * are detected.
+   * @param[in] mappingRoot The JSON node containing the mappings
+   * @param[in] theKey The key to search for
+   * @param[in,out] keyStack the stack of visited keys
+   * @param[in] propertyType The property type if known, or NONE
+   * @param[in,out] value The string value to test and write back to.
+   */
+  bool RecursePropertyMap( const TreeNode& mappingRoot, KeyStack& keyStack, const char* theKey, Property::Type propertyType, Property::Value& value );
+
+  /**
+   * Find the key in the mapping table, if it's present, then generate a property value for it (of the given type if available), recursing as necessary, and stopping if any cycles
+   * are detected.
+   * @param[in] mappingRoot The JSON node containing the mappings
+   * @param[in] theKey The key to search for
+   * @param[in] propertyType The property type if known, or NONE
+   * @param[in,out] value The string value to test and write back to.
+   */
+  bool GetPropertyMap( const TreeNode& mappingRoot, const char* theKey, Property::Type propertyType, Property::Value& value );
+
   void ApplyProperties( const TreeNode& root, const TreeNode& node,
                         Dali::Handle& handle, const Replacement& constant );
 
index d17a392..d64a04c 100644 (file)
@@ -25,7 +25,7 @@
 #include <dali-toolkit/internal/builder/builder-impl.h>
 #include <dali-toolkit/internal/builder/builder-get-is.inl.h>
 #include <dali-toolkit/internal/builder/replacement.h>
-
+#include <dali-toolkit/internal/builder/builder-set-property.h>
 
 namespace Dali
 {
@@ -36,46 +36,6 @@ namespace Toolkit
 namespace Internal
 {
 
-/*
- * Set a property value from a tree node.
- * This function determines the type of the property from the format of the string in the node.
- * This is not always possible and if the type cannot be determined then then the type will default to Array.
- * @param node  The node string to convert from
- * @param value The property value to set
- */
-void DeterminePropertyFromNode( const TreeNode& node, Property::Value& value );
-
-/*
- * Set a property value from a tree node as SetPropertyFromNode() above
- * This function determines the type of the property from the format of the string in the node.
- * This is not always possible and if the type cannot be determined then then the type will default to Array.
- * @param node  The node string to convert from
- * @param value The property value to set
- * @param replacement The overriding replacement map (if any)
- */
-void DeterminePropertyFromNode( const TreeNode& node, Property::Value& value,
-                          const Replacement& replacement );
-
-/*
- * Set a property value as the given type from a tree node.
- * @param node The node string to convert from
- * @param type The property type to convert to.
- * @param value The property value to set
- * @return true if the string could be converted to the correct type.
- */
-bool DeterminePropertyFromNode( const TreeNode& node, Property::Type type, Property::Value& value );
-
-/*
- * Set a property value as the given type from a tree node as SetPropertyFromNode() above
- * @param node The node string to convert from
- * @param type The property type to convert to.
- * @param value The property value to set
- * @param replacement The overriding replacement map (if any)
- * @return true if the string could be converted to the correct type.
- */
-bool DeterminePropertyFromNode( const TreeNode& node, Property::Type type, Property::Value& value,
-                          const Replacement& replacement );
-
 
 namespace
 {
@@ -103,13 +63,12 @@ Vector4 HexStringToVector4( const char* s )
  * A property value type can be forced when its unknown by a disambiguation convention in the json
  * ie  "myarray": [1,2,3,4] ; would be a vector but
  *     "myarray": {"typeCast":"array", "value":[1,2,3,4]} would be an array
- * @param child The node whos string to search for a disambiguated type
+ * @param child The node whose string to search for a disambiguated type
  * @param value The value to set
- * @param overrideMap The user overriding constant map
- * @param defaultMap The default map.
+ * @param replacement The user overriding constant map
  * @return True if child contained a disambiguated string that could be converted.
  */
-bool Disambiguated(const TreeNode& child, // ConstantLut& constantLut,
+bool Disambiguated(const TreeNode& child,
                    Dali::Property::Value& value,
                    const Replacement& replacement )
 {
@@ -175,7 +134,7 @@ bool DeterminePropertyFromNode( const TreeNode& node, Property::Type type, Prope
 }
 
 bool DeterminePropertyFromNode( const TreeNode& node, Property::Type type, Property::Value& value,
-                          const Replacement& replacer )
+                                const Replacement& replacer )
 {
   bool done = false;
 
@@ -406,7 +365,7 @@ void DeterminePropertyFromNode( const TreeNode& node, Property::Value& value )
 }
 
 void DeterminePropertyFromNode( const TreeNode& node, Property::Value& value,
-                          const Replacement& replacer )
+                                const Replacement& replacer )
 {
 
   TreeNode::NodeType nodeType = node.GetType();
@@ -517,7 +476,6 @@ void DeterminePropertyFromNode( const TreeNode& node, Property::Value& value,
         }
         else
         {
-          // string always succeeds with the current json parser so its last
           value = *aString;
         }
       } // if aBool
diff --git a/dali-toolkit/internal/builder/builder-set-property.h b/dali-toolkit/internal/builder/builder-set-property.h
new file mode 100644 (file)
index 0000000..a9ae431
--- /dev/null
@@ -0,0 +1,78 @@
+#ifndef DALI_TOOLKIT_INTERNAL_BUILDER_SET_PROPERTY_H
+#define DALI_TOOLKIT_INTERNAL_BUILDER_SET_PROPERTY_H
+
+/*
+ * Copyright (c) 2016 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 Internal
+{
+
+/**
+ * Set a property value from a tree node.
+ * This function determines the type of the property from the format of the string in the node.
+ * This is not always possible and if the type cannot be determined then then the type will default to Array.
+ * @param node  The node string to convert from
+ * @param value The property value to set
+ */
+void DeterminePropertyFromNode( const TreeNode&  node,
+                                Property::Value& value );
+
+/**
+ * Set a property value from a tree node as DeterminePropertyFromNode() above
+ * This function determines the type of the property from the format of the string in the node.
+ * This is not always possible and if the type cannot be determined then then the type will default to Array.
+ * @param node  The node string to convert from
+ * @param value The property value to set
+ * @param replacement The overriding replacement map (if any)
+ */
+void DeterminePropertyFromNode( const TreeNode&    node,
+                                Property::Value&   value,
+                                const Replacement& replacement );
+
+/**
+ * Set a property value as the given type from a tree node.
+ * @param node The node string to convert from
+ * @param type The property type to convert to.
+ * @param value The property value to set
+ * @return true if the string could be converted to the correct type.
+ */
+bool DeterminePropertyFromNode( const TreeNode&  node,
+                                Property::Type   type,
+                                Property::Value& value );
+
+/**
+ * Set a property value as the given type from a tree node as DeterminePropertyFromNode() above
+ * @param node The node string to convert from
+ * @param type The property type to convert to.
+ * @param value The property value to set
+ * @param replacement The overriding replacement map (if any)
+ * @return true if the string could be converted to the correct type.
+ */
+bool DeterminePropertyFromNode( const TreeNode&    node,
+                                Property::Type     type,
+                                Property::Value&   value,
+                                const Replacement& replacement );
+
+
+} // Internal namespace
+} // Toolkit namespace
+} // Dali namespace
+
+#endif //DALI_TOOLKIT_INTERNAL_BUILDER_SET_PROPERTY_H
index 31487fe..293531d 100644 (file)
@@ -4,6 +4,7 @@ toolkit_src_files = \
    $(toolkit_src_dir)/builder/builder-actor.cpp \
    $(toolkit_src_dir)/builder/builder-animations.cpp \
    $(toolkit_src_dir)/builder/builder-impl.cpp \
+   $(toolkit_src_dir)/builder/builder-impl-debug.cpp \
    $(toolkit_src_dir)/builder/builder-set-property.cpp \
    $(toolkit_src_dir)/builder/builder-signals.cpp \
    $(toolkit_src_dir)/builder/json-parser-state.cpp \
@@ -123,5 +124,3 @@ toolkit_src_files = \
    $(toolkit_src_dir)/transition-effects/cube-transition-wave-effect-impl.cpp \
    $(toolkit_src_dir)/scripting/script-impl.cpp \
    $(toolkit_src_dir)/scripting/script-plugin-proxy.cpp
-
-