Merge "Update the refined dali c# application to support more argument options" into...
authordongsug song <dongsug.song@samsung.com>
Tue, 25 Oct 2016 03:50:51 +0000 (20:50 -0700)
committerGerrit Code Review <gerrit@review.vlan103.tizen.org>
Tue, 25 Oct 2016 03:50:52 +0000 (20:50 -0700)
151 files changed:
automated-tests/src/dali-toolkit-internal/CMakeLists.txt
automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Controller.cpp
automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Markup.cpp [new file with mode: 0644]
automated-tests/src/dali-toolkit-internal/utc-Dali-Visuals.cpp [new file with mode: 0644]
automated-tests/src/dali-toolkit/CMakeLists.txt
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/dummy-control.cpp
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/dummy-control.h
automated-tests/src/dali-toolkit/utc-Dali-AsyncImageLoader.cpp
automated-tests/src/dali-toolkit/utc-Dali-ControlImpl.cpp
automated-tests/src/dali-toolkit/utc-Dali-ImageAtlas.cpp
automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp
automated-tests/src/dali-toolkit/utc-Dali-TextEditor.cpp
automated-tests/src/dali-toolkit/utc-Dali-TextField.cpp
automated-tests/src/dali-toolkit/utc-Dali-TextLabel.cpp
automated-tests/src/dali-toolkit/utc-Dali-TransitionData.cpp [new file with mode: 0644]
automated-tests/src/dali-toolkit/utc-Dali-Visual.cpp
automated-tests/src/dali-toolkit/utc-Dali-VisualFactory.cpp
dali-toolkit/dali-toolkit.h
dali-toolkit/devel-api/file.list
dali-toolkit/devel-api/image-loader/atlas-upload-observer.cpp [new file with mode: 0644]
dali-toolkit/devel-api/image-loader/atlas-upload-observer.h [new file with mode: 0644]
dali-toolkit/devel-api/image-loader/image-atlas.cpp
dali-toolkit/devel-api/image-loader/image-atlas.h
dali-toolkit/devel-api/visual-factory/transition-data.cpp [new file with mode: 0644]
dali-toolkit/devel-api/visual-factory/transition-data.h [new file with mode: 0644]
dali-toolkit/devel-api/visual-factory/visual-base.cpp
dali-toolkit/devel-api/visual-factory/visual-base.h
dali-toolkit/internal/builder/replacement.cpp
dali-toolkit/internal/controls/text-controls/text-editor-impl.cpp
dali-toolkit/internal/controls/text-controls/text-editor-impl.h
dali-toolkit/internal/controls/text-controls/text-field-impl.cpp
dali-toolkit/internal/controls/text-controls/text-field-impl.h
dali-toolkit/internal/controls/text-controls/text-label-impl.cpp
dali-toolkit/internal/controls/text-controls/text-label-impl.h
dali-toolkit/internal/file.list
dali-toolkit/internal/image-loader/image-atlas-impl.cpp
dali-toolkit/internal/image-loader/image-atlas-impl.h
dali-toolkit/internal/text/markup-processor-helper-functions.cpp
dali-toolkit/internal/text/markup-processor-helper-functions.h
dali-toolkit/internal/text/property-string-parser.cpp
dali-toolkit/internal/text/property-string-parser.h
dali-toolkit/internal/text/text-control-interface.h
dali-toolkit/internal/text/text-controller-impl.cpp
dali-toolkit/internal/text/text-controller-impl.h
dali-toolkit/internal/text/text-controller.cpp
dali-toolkit/internal/text/text-controller.h
dali-toolkit/internal/text/text-editable-control-interface.h [new file with mode: 0644]
dali-toolkit/internal/text/text-effects-style.cpp
dali-toolkit/internal/text/text-effects-style.h
dali-toolkit/internal/text/text-font-style.cpp
dali-toolkit/internal/text/text-font-style.h
dali-toolkit/internal/text/text-scroller-data.cpp [moved from dali-toolkit/internal/text/text-control-interface.cpp with 65% similarity]
dali-toolkit/internal/text/text-scroller-data.h [new file with mode: 0644]
dali-toolkit/internal/text/text-scroller.cpp
dali-toolkit/internal/text/text-scroller.h
dali-toolkit/internal/visuals/border/border-visual.cpp
dali-toolkit/internal/visuals/border/border-visual.h
dali-toolkit/internal/visuals/color/color-visual.cpp
dali-toolkit/internal/visuals/color/color-visual.h
dali-toolkit/internal/visuals/gradient/gradient-visual.cpp
dali-toolkit/internal/visuals/gradient/gradient-visual.h
dali-toolkit/internal/visuals/image-atlas-manager.cpp
dali-toolkit/internal/visuals/image-atlas-manager.h
dali-toolkit/internal/visuals/image/batch-image-visual.cpp
dali-toolkit/internal/visuals/image/batch-image-visual.h
dali-toolkit/internal/visuals/image/image-visual.cpp
dali-toolkit/internal/visuals/image/image-visual.h
dali-toolkit/internal/visuals/mesh/mesh-visual.cpp
dali-toolkit/internal/visuals/mesh/mesh-visual.h
dali-toolkit/internal/visuals/npatch/npatch-visual.cpp
dali-toolkit/internal/visuals/npatch/npatch-visual.h
dali-toolkit/internal/visuals/primitive/primitive-visual.cpp
dali-toolkit/internal/visuals/primitive/primitive-visual.h
dali-toolkit/internal/visuals/svg/svg-visual.cpp
dali-toolkit/internal/visuals/svg/svg-visual.h
dali-toolkit/internal/visuals/text/text-visual.cpp [new file with mode: 0644]
dali-toolkit/internal/visuals/text/text-visual.h [new file with mode: 0644]
dali-toolkit/internal/visuals/transition-data-impl.cpp [new file with mode: 0644]
dali-toolkit/internal/visuals/transition-data-impl.h [new file with mode: 0644]
dali-toolkit/internal/visuals/visual-base-data-impl.h
dali-toolkit/internal/visuals/visual-base-impl.cpp
dali-toolkit/internal/visuals/visual-base-impl.h
dali-toolkit/internal/visuals/visual-factory-impl.cpp
dali-toolkit/internal/visuals/visual-factory-impl.h
dali-toolkit/internal/visuals/wireframe/wireframe-visual.cpp
dali-toolkit/internal/visuals/wireframe/wireframe-visual.h
dali-toolkit/public-api/controls/control-impl.cpp
dali-toolkit/public-api/controls/control-impl.h
dali-toolkit/public-api/controls/text-controls/text-label.h
dali-toolkit/public-api/dali-toolkit-version.cpp
dali-toolkit/public-api/file.list
dali-toolkit/public-api/visuals/text-visual-properties.h [new file with mode: 0644]
dali-toolkit/public-api/visuals/visual-properties.h
packaging/dali-addon.spec
packaging/dali-csharp-wrapper.spec
packaging/dali-toolkit.spec
plugins/dali-swig/SWIG/dali-operator.i
plugins/dali-swig/SWIG/events/animation-event.i
plugins/dali-swig/examples/dali-test.cs
plugins/dali-swig/examples/firstscreen/App.cs [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/Constants.cs [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/FocusData.cs [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/FocusEffect.cs [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/IFocusEffect.cs [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/Program.cs [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/ScrollContainer.cs [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/0-normal.png [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/1-normal.png [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/2-normal.png [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/background.png [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/focus_grid.9.png [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/focus_launcher_shadow.9.png [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/focus_launcher_shadow_n.png [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/focuseffect/halo.png [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/focuseffect/horizontalFrame.png [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/focuseffect/verticalFrame.png [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/highlight_spot.png [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/highlight_stroke.9.png [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/menu/0.png [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/menu/1.png [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/menu/2.png [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/menu/3.png [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/menu/4.png [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/menu/5.png [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/menu/6.png [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/poster0/0.jpg [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/poster0/1.jpg [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/poster0/10.jpg [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/poster0/11.jpg [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/poster0/12.jpg [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/poster0/13.jpg [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/poster0/2.jpg [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/poster0/3.jpg [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/poster0/4.jpg [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/poster0/5.jpg [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/poster0/6.jpg [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/poster0/7.jpg [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/poster0/8.jpg [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/poster0/9.jpg [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/poster1/0.jpg [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/poster1/1.jpg [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/poster1/2.jpg [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/poster1/3.jpg [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/poster1/4.jpg [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/poster1/5.jpg [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/star-dim.png [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/star-highlight.png [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/thumbnail_shadow.9.png [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/white-pixel.png [new file with mode: 0644]
plugins/dali-swig/examples/hello-world.cs
plugins/dali-swig/property-wrapper.rb

index d2316e8..4a9a003 100644 (file)
@@ -19,6 +19,8 @@ SET(TC_SOURCES
  utc-Dali-Text-Layout.cpp
  utc-Dali-Text-Controller.cpp
  utc-Dali-VisualFactoryResolveUrl.cpp
+ utc-Dali-Visuals.cpp
+ utc-Dali-Text-Markup.cpp
 )
 
 # Append list of test harness files (Won't get parsed for test cases)
index 7480435..f2e761f 100644 (file)
 
 #include <stdlib.h>
 #include <limits>
+#include <unistd.h>
 
 #include <dali-toolkit-test-suite-utils.h>
 #include <dali-toolkit/dali-toolkit.h>
 #include <dali-toolkit/internal/text/text-controller.h>
+#include <dali-toolkit/internal/text/text-control-interface.h>
+#include <dali-toolkit/internal/text/text-editable-control-interface.h>
+#include <dali-toolkit/internal/text/text-scroller-data.h>
 
 using namespace Dali;
 using namespace Toolkit;
@@ -40,7 +44,9 @@ const char* const OPTION_CLIPBOARD("optionClipboard");      // "Clipboard" popup
 
 const Size CONTROL_SIZE( 300.f, 60.f );
 
-class ControlImpl : public ControlInterface
+const std::string DEFAULT_FONT_DIR( "/resources/fonts" );
+
+class ControlImpl : public ControlInterface, public Text::EditableControlInterface
 {
 public:
   ControlImpl()
@@ -80,8 +86,7 @@ int UtcDaliTextController(void)
   ToolkitTestApplication application;
 
   // Creates a text controller.
-  ControlImpl controlImpl;
-  ControllerPtr controller = Controller::New( controlImpl );
+  ControllerPtr controller = Controller::New();
 
   DALI_TEST_CHECK( controller );
 
@@ -95,8 +100,7 @@ int UtcDaliTextControllerEnableCursorBlinking(void)
   ToolkitTestApplication application;
 
   // Creates a text controller.
-  ControlImpl controlImpl;
-  ControllerPtr controller = Controller::New( controlImpl );
+  ControllerPtr controller = Controller::New();
 
   DALI_TEST_CHECK( controller );
 
@@ -131,8 +135,7 @@ int UtcDaliTextControllerImfEvent(void)
   ToolkitTestApplication application;
 
   // Creates a text controller.
-  ControlImpl controlImpl;
-  ControllerPtr controller = Controller::New( controlImpl );
+  ControllerPtr controller = Controller::New();
 
   std::string text;
   ImfManager::ImfEventData imfEvent;
@@ -214,8 +217,7 @@ int UtcDaliTextControllerTextPopupButtonTouched(void)
   ToolkitTestApplication application;
 
   // Creates a text controller.
-  ControlImpl controlImpl;
-  ControllerPtr controller = Controller::New( controlImpl );
+  ControllerPtr controller = Controller::New();
 
   DALI_TEST_CHECK( controller );
 
@@ -330,3 +332,193 @@ int UtcDaliTextControllerTextPopupButtonTouched(void)
   tet_result(TET_PASS);
   END_TEST;
 }
+
+int UtcDaliTextControllerGetInputShadowProperty(void)
+{
+  tet_infoline(" UtcDaliTextControllerGetInputShadowProperty");
+  ToolkitTestApplication application;
+
+  // Creates a text controller.
+  ControllerPtr controller = Controller::New();
+
+  DALI_TEST_CHECK( controller );
+
+  const std::string& shadowProperties = controller->GetInputShadowProperties();
+
+  DALI_TEST_CHECK( shadowProperties.empty() );
+
+  tet_result(TET_PASS);
+  END_TEST;
+}
+
+int UtcDaliTextControllerGetInputUnderlineProperty(void)
+{
+  tet_infoline(" UtcDaliTextControllerGetInputUnderlineProperty");
+  ToolkitTestApplication application;
+
+  // Creates a text controller.
+  ControllerPtr controller = Controller::New();
+
+  DALI_TEST_CHECK( controller );
+
+  const std::string& underlineProperties = controller->GetInputUnderlineProperties();
+
+  DALI_TEST_CHECK( underlineProperties.empty() );
+
+  tet_result(TET_PASS);
+  END_TEST;
+}
+
+int UtcDaliTextControllerSetGetAutoScrollEnabled(void)
+{
+  tet_infoline(" UtcDaliTextControllerSetGetAutoScrollEnabled");
+  ToolkitTestApplication application;
+
+  // Creates a text controller.
+  ControllerPtr controller = Controller::New();
+
+  DALI_TEST_CHECK( controller );
+
+  DALI_TEST_CHECK( !controller->IsAutoScrollEnabled() );
+
+  // The auto scrolling shouldn't be enabled if the multi-line is enabled.
+
+  // Enable multi-line.
+  controller->SetMultiLineEnabled( true );
+
+  // Enable text scrolling.
+  controller->SetAutoScrollEnabled( true );
+
+  DALI_TEST_CHECK( !controller->IsAutoScrollEnabled() );
+
+  // Disable multi-line.
+  controller->SetMultiLineEnabled( false );
+
+  // Enable text scrolling.
+  controller->SetAutoScrollEnabled( true );
+
+  // Should be ebabled now.
+  DALI_TEST_CHECK( controller->IsAutoScrollEnabled() );
+
+  tet_result(TET_PASS);
+  END_TEST;
+}
+
+int UtcDaliTextControllerSetGetAutoScrollSpeed(void)
+{
+  tet_infoline(" UtcDaliTextControllerSetGetAutoScrollSpeed");
+  ToolkitTestApplication application;
+
+  // Creates a text controller.
+  ControllerPtr controller = Controller::New();
+
+  DALI_TEST_CHECK( controller );
+
+  // Check the default value.
+  DALI_TEST_EQUALS( 0, controller->GetAutoScrollSpeed(), TEST_LOCATION );
+
+  // Set the auto scroll speed.
+  controller->SetAutoscrollSpeed( 10 );
+
+  DALI_TEST_EQUALS( 10, controller->GetAutoScrollSpeed(), TEST_LOCATION );
+
+  tet_result(TET_PASS);
+  END_TEST;
+}
+
+int UtcDaliTextControllerSetGetAutoScrollLoopCount(void)
+{
+  tet_infoline(" UtcDaliTextControllerSetGetAutoScrollLoopCount");
+  ToolkitTestApplication application;
+
+  // Creates a text controller.
+  ControllerPtr controller = Controller::New();
+
+  DALI_TEST_CHECK( controller );
+
+  // Check the default value.
+  DALI_TEST_EQUALS( 0, controller->GetAutoScrollLoopCount(), TEST_LOCATION );
+
+  // Set the auto scroll loop count.
+  controller->SetAutoScrollLoopCount( 5 );
+
+  DALI_TEST_EQUALS( 5, controller->GetAutoScrollLoopCount(), TEST_LOCATION );
+
+  tet_result(TET_PASS);
+  END_TEST;
+}
+
+int UtcDaliTextControllerSetGetAutoScrollWrapGap(void)
+{
+  tet_infoline(" UtcDaliTextControllerSetGetAutoScrollWrapGap");
+  ToolkitTestApplication application;
+
+  // Creates a text controller.
+  ControllerPtr controller = Controller::New();
+
+  DALI_TEST_CHECK( controller );
+
+  // Check the default value.
+  DALI_TEST_EQUALS( 0.f, controller->GetAutoScrollWrapGap(), Math::MACHINE_EPSILON_1000, TEST_LOCATION );
+
+  // Set the auto scroll loop count.
+  controller->SetAutoScrollWrapGap( 25.f );
+
+  DALI_TEST_EQUALS( 25.f, controller->GetAutoScrollWrapGap(), Math::MACHINE_EPSILON_1000, TEST_LOCATION );
+
+  tet_result(TET_PASS);
+  END_TEST;
+}
+
+int UtcDaliTextControllerGetAutoScrollData(void)
+{
+  tet_infoline(" UtcDaliTextControllerGetAutoScrollData");
+  ToolkitTestApplication application;
+
+  // Load some fonts to get the same metrics on different platforms.
+  TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
+  fontClient.SetDpi( 96u, 96u );
+
+  char* pathNamePtr = get_current_dir_name();
+  const std::string pathName( pathNamePtr );
+  free( pathNamePtr );
+
+  fontClient.GetFontId( pathName + DEFAULT_FONT_DIR + "/tizen/TizenSansRegular.ttf" );
+
+  // Creates a text controller.
+  ControllerPtr controller = Controller::New();
+
+  DALI_TEST_CHECK( controller );
+
+  DALI_TEST_CHECK( NULL == controller->GetAutoScrollData() );
+
+  // Set and check some values.
+  controller->SetAutoscrollSpeed( 10 );
+  controller->SetAutoScrollLoopCount( 5 );
+  controller->SetAutoScrollWrapGap( 25.f );
+
+  const ScrollerData* scrollerData = controller->GetAutoScrollData();
+  DALI_TEST_CHECK( NULL != controller->GetAutoScrollData() );
+
+  DALI_TEST_EQUALS( Size::ZERO, scrollerData->mControlSize, TEST_LOCATION );
+  DALI_TEST_EQUALS( Size::ZERO, scrollerData->mOffscreenSize, TEST_LOCATION );
+  DALI_TEST_EQUALS( 10, scrollerData->mScrollSpeed, TEST_LOCATION );
+  DALI_TEST_EQUALS( 5, scrollerData->mLoopCount, TEST_LOCATION );
+  DALI_TEST_EQUALS( 25.f, scrollerData->mWrapGap, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
+  DALI_TEST_EQUALS( 0.f, scrollerData->mAlignmentOffset, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
+  DALI_TEST_CHECK( !scrollerData->mAutoScrollDirectionRTL );
+
+  // Set some text and layout.
+  controller->SetMarkupProcessorEnabled( true );
+  controller->SetHorizontalAlignment( LayoutEngine::HORIZONTAL_ALIGN_END );
+  controller->SetText( "<font family='TizenSans' size='12'>Hello world</font>" );
+  controller->Relayout( Size( 100.f, 20.f ) );
+
+  scrollerData = controller->GetAutoScrollData();
+  DALI_TEST_EQUALS( Size( 100.f, 20.f ), scrollerData->mControlSize, TEST_LOCATION );
+  DALI_TEST_EQUALS( Size( 80.f, 20.f ), scrollerData->mOffscreenSize, TEST_LOCATION );
+  DALI_TEST_EQUALS( 20.f, scrollerData->mAlignmentOffset, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
+
+  tet_result(TET_PASS);
+  END_TEST;
+}
diff --git a/automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Markup.cpp b/automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Markup.cpp
new file mode 100644 (file)
index 0000000..23f7e51
--- /dev/null
@@ -0,0 +1,453 @@
+/*
+ * 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 <iostream>
+
+#include <stdlib.h>
+#include <limits>
+
+#include <dali-toolkit-test-suite-utils.h>
+#include <dali-toolkit/dali-toolkit.h>
+#include <toolkit-text-model.h>
+#include <dali-toolkit/internal/text/markup-processor.h>
+#include <dali-toolkit/internal/text/markup-processor-helper-functions.h>
+#include <dali-toolkit/internal/text/color-run.h>
+#include <dali-toolkit/internal/text/font-description-run.h>
+#include <dali-toolkit/internal/text/text-definitions.h>
+#include <dali-toolkit/internal/text/text-io.h>
+
+using namespace Dali;
+using namespace Toolkit;
+using namespace Text;
+
+namespace
+{
+  ///////////////////////////////////////////////////////////
+
+  struct TokenComparisonData
+  {
+    std::string description;
+    std::string string1; ///< must be in lower case!!!!
+    std::string string2;
+    bool expectedResult;
+  };
+
+  bool TokenComparisonTest( const TokenComparisonData& data )
+  {
+    std::cout << "  testing " << data.description << std::endl;
+
+    const bool result = TokenComparison( data.string1,
+                                         data.string2.c_str(),
+                                         data.string2.size() );
+
+    if( result != data.expectedResult )
+    {
+      std::cout << "  different conparison result : " << result << ", expected : " << data.expectedResult << std::endl;
+      std::cout << "  comparing : [" << data.string1 << "] and [" << data.string2 << "]" << std::endl;
+
+      return false;
+    }
+
+    return true;
+  }
+
+  ///////////////////////////////////////////////////////////
+
+  struct ColorStringToVector4Data
+  {
+    std::string description;
+    std::string colorStr;
+    Vector4 expectedColor;
+  };
+
+  bool ColorStringToVector4Test( const ColorStringToVector4Data& data )
+  {
+    std::cout << "  testing " << data.description << std::endl;
+
+    Vector4 color;
+    ColorStringToVector4( data.colorStr.c_str(), data.colorStr.size(), color );
+
+    if( color != data.expectedColor )
+    {
+      std::cout << "  different color : " << color << ", expected : " << data.expectedColor << std::endl;
+      return false;
+    }
+
+    return true;
+  }
+
+  ///////////////////////////////////////////////////////////
+
+  struct Vector4ToColorStringData
+  {
+    std::string description;
+    Vector4 color;
+    std::string expectedColorStr;
+  };
+
+  bool Vector4ToColorStringTest( const Vector4ToColorStringData& data )
+  {
+    std::cout << "  testing " << data.description << std::endl;
+
+    std::string colorStr;
+    Vector4ToColorString( data.color, colorStr );
+
+    if( colorStr != data.expectedColorStr )
+    {
+      std::cout << "  different color : [" << colorStr << "], expected : [" << data.expectedColorStr << "]" << std::endl;
+      return false;
+    }
+
+    return true;
+  }
+
+  ///////////////////////////////////////////////////////////
+
+  struct StringToVector2Data
+  {
+    std::string description;
+    std::string vector2Str;
+    Vector2 expectedVector2;
+  };
+
+  bool StringToVector2Test( const StringToVector2Data& data )
+  {
+    std::cout << "  testing " << data.description << std::endl;
+
+    Vector2 vector2;
+    StringToVector2( data.vector2Str.c_str(), data.vector2Str.size(), vector2 );
+
+    if( vector2 != data.expectedVector2 )
+    {
+      std::cout << "  different vector2 : " << vector2 << ", expected : " << data.expectedVector2 << std::endl;
+      return false;
+    }
+
+    return true;
+  }
+
+  ///////////////////////////////////////////////////////////
+
+
+  struct Vector2ToStringData
+  {
+    std::string description;
+    Vector2 vector2;
+    std::string expectedVector2Str;
+  };
+
+  bool Vector2ToStringTest( const Vector2ToStringData& data )
+  {
+    std::cout << "  testing " << data.description << std::endl;
+
+    std::string vector2Str;
+    Vector2ToString( data.vector2, vector2Str );
+
+    if( vector2Str != data.expectedVector2Str )
+    {
+      std::cout << "  different vector2 : [" << vector2Str << "], expected : [" << data.expectedVector2Str << "]" << std::endl;
+      return false;
+    }
+
+    return true;
+  }
+
+} // namespace
+
+int UtcDaliTextTokenComparison(void)
+{
+  tet_infoline(" UtcDaliTextTokenComparison");
+
+  const TokenComparisonData data[] =
+  {
+    {
+      "void texts",
+      "",
+      "",
+      true
+    },
+    {
+      "different size text",
+      "hello",
+      "world!",
+      false
+    },
+    {
+      "different texts",
+      "hello",
+      "world",
+      false
+    },
+    {
+      "same texts",
+      "world",
+      "wOrLD",
+      true
+    },
+    {
+      "some punctuation characters, numbers, ...",
+      "hello0123456789.![?]",
+      "Hello0123456789.![?]",
+      true
+    }
+
+  };
+  const unsigned int numberOfTests = 5u;
+
+  for( unsigned int index = 0u; index < numberOfTests; ++index )
+  {
+    ToolkitTestApplication application;
+    if( !TokenComparisonTest( data[index] ) )
+    {
+      tet_result(TET_FAIL);
+    }
+  }
+
+  tet_result(TET_PASS);
+  END_TEST;
+}
+
+int UtcDaliTextColorStringToVector4(void)
+{
+  tet_infoline(" UtcDaliTextColorStringToVector4");
+
+  const ColorStringToVector4Data data[] =
+  {
+    {
+      "black string",
+      "bLack",
+      Color::BLACK
+    },
+    {
+      "white string",
+      "White",
+      Color::WHITE
+    },
+    {
+      "red string",
+      "reD",
+      Color::RED
+    },
+    {
+      "green string",
+      "green",
+      Color::GREEN
+    },
+    {
+      "blue string",
+      "blue",
+      Color::BLUE
+    },
+    {
+      "yellow string",
+      "yeLloW",
+      Color::YELLOW
+    },
+    {
+      "magenta string",
+      "MagEnta",
+      Color::MAGENTA
+    },
+    {
+      "cyan string",
+      "CyaN",
+      Color::CYAN
+    },
+    {
+      "transparent string",
+      "transparent",
+      Color::TRANSPARENT
+    },
+    {
+      "3 component web color",
+      "#F00",
+      Color::RED
+    },
+    {
+      "6 component web color",
+      "#fF0000",
+      Color::RED
+    },
+    {
+      "hex color red (ARGB)",
+      "0xffff0000",
+      Color::RED
+    },
+    {
+      "hex color green (ARGB)",
+      "0xFf00FF00",
+      Color::GREEN
+    },
+    {
+      "undefined color",
+      "undefined",
+      Vector4::ZERO
+    },
+  };
+  const unsigned int numberOfTests = 14u;
+
+  for( unsigned int index = 0u; index < numberOfTests; ++index )
+  {
+    ToolkitTestApplication application;
+    if( !ColorStringToVector4Test( data[index] ) )
+    {
+      tet_result(TET_FAIL);
+    }
+  }
+
+  tet_result(TET_PASS);
+  END_TEST;
+}
+
+int UtcDaliTextVector4ToColorString(void)
+{
+  tet_infoline(" UtcDaliTextVector4ToColorString");
+
+  const Vector4ToColorStringData data[] =
+  {
+    {
+      "black color",
+      Color::BLACK,
+      "black"
+    },
+    {
+      "white string",
+      Color::WHITE,
+      "white"
+    },
+    {
+      "red string",
+      Color::RED,
+      "red"
+    },
+    {
+      "green string",
+      Color::GREEN,
+      "green"
+    },
+    {
+      "blue string",
+      Color::BLUE,
+      "blue"
+    },
+    {
+      "yellow string",
+      Color::YELLOW,
+      "yellow"
+    },
+    {
+      "magenta string",
+      Color::MAGENTA,
+      "magenta",
+    },
+    {
+      "cyan string",
+      Color::CYAN,
+      "cyan"
+    },
+    {
+      "transparent string",
+      Color::TRANSPARENT,
+      "transparent"
+    },
+    {
+      "hex color",
+      Vector4( 0.4f, 0.5f, 0.6f, 1.f ),
+      "0xff667f99"
+    },
+  };
+  const unsigned int numberOfTests = 10u;
+
+  for( unsigned int index = 0u; index < numberOfTests; ++index )
+  {
+    ToolkitTestApplication application;
+    if( !Vector4ToColorStringTest( data[index] ) )
+    {
+      tet_result(TET_FAIL);
+    }
+  }
+
+  tet_result(TET_PASS);
+  END_TEST;
+}
+
+int UtcDaliTextStringToVector2(void)
+{
+  tet_infoline(" UtcDaliTextStringToVector2");
+  const StringToVector2Data data[] =
+  {
+    {
+      "void text",
+      "",
+      Vector2::ZERO
+    },
+    {
+      "zero zero",
+      "0 0",
+      Vector2::ZERO
+    },
+    {
+      "five four",
+      "5 4",
+      Vector2(5.f, 4.f)
+    }
+  };
+  const unsigned int numberOfTests = 3u;
+
+  for( unsigned int index = 0u; index < numberOfTests; ++index )
+  {
+    ToolkitTestApplication application;
+    if( !StringToVector2Test( data[index] ) )
+    {
+      tet_result(TET_FAIL);
+    }
+  }
+
+  tet_result(TET_PASS);
+  END_TEST;
+}
+
+int UtcDaliTextVector2ToString(void)
+{
+  tet_infoline(" UtcDaliTextVector2ToString");
+  const Vector2ToStringData data[] =
+  {
+    {
+      "zero zero",
+      Vector2::ZERO,
+      "0 0",
+    },
+    {
+      "five four",
+      Vector2(5.f, 4.f),
+      "5 4",
+    }
+  };
+  const unsigned int numberOfTests = 2u;
+
+  for( unsigned int index = 0u; index < numberOfTests; ++index )
+  {
+    ToolkitTestApplication application;
+    if( !Vector2ToStringTest( data[index] ) )
+    {
+      tet_result(TET_FAIL);
+    }
+  }
+
+  tet_result(TET_PASS);
+  END_TEST;
+}
diff --git a/automated-tests/src/dali-toolkit-internal/utc-Dali-Visuals.cpp b/automated-tests/src/dali-toolkit-internal/utc-Dali-Visuals.cpp
new file mode 100644 (file)
index 0000000..a4bfbcb
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * 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 <iostream>
+
+#include <stdlib.h>
+
+#include <dali-toolkit-test-suite-utils.h>
+#include <dali-toolkit/public-api/visuals/visual-properties.h>
+#include <dali-toolkit/internal/visuals/visual-factory-cache.h>
+#include <dali-toolkit/internal/visuals/wireframe/wireframe-visual.h>
+
+using namespace Dali::Toolkit::Internal;
+
+namespace
+{
+
+class DummyWireframeVisual : public WireframeVisual
+{
+public:
+
+  DummyWireframeVisual( VisualFactoryCache& factoryCache )
+  : WireframeVisual( factoryCache )
+  {}
+
+  virtual ~DummyWireframeVisual()
+  {}
+
+  void DoSetProperty( Dali::Property::Index index, const Dali::Property::Value& propertyValue )
+  {
+    WireframeVisual::DoSetProperty( index, propertyValue );
+  }
+
+  Dali::Property::Value DoGetProperty( Dali::Property::Index index )
+  {
+    return WireframeVisual::DoGetProperty( index );
+  }
+};
+
+} // namespace
+
+int UtcDaliWireframeVisual(void)
+{
+  // The goal of this test case is to cover the WireframeVisual::DoSetProperty() and
+  // WireframeVisual::DoGetProperty() which are unreachable from the public API.
+
+  tet_infoline( " UtcDaliWireframeVisual" );
+
+  VisualFactoryCache* visualFactoryCache = new VisualFactoryCache();
+
+  DummyWireframeVisual visual( *visualFactoryCache );
+
+  visual.DoSetProperty( Dali::Toolkit::Visual::Property::TYPE, Dali::Toolkit::Visual::WIREFRAME );
+  Dali::Property::Value value = visual.DoGetProperty( Dali::Toolkit::Visual::Property::TYPE );
+
+  tet_result(TET_PASS);
+  END_TEST;
+}
index 6031392..1c6f3c9 100644 (file)
@@ -33,6 +33,7 @@ SET(TC_SOURCES
    utc-Dali-TextLabel.cpp
    utc-Dali-TextSelectionPopup.cpp
    utc-Dali-ToolBar.cpp
+   utc-Dali-TransitionData.cpp
    utc-Dali-Button.cpp
    utc-Dali-Control.cpp
    utc-Dali-ControlImpl.cpp
index 80fb6ec..a100a1f 100644 (file)
@@ -70,7 +70,6 @@ DummyControlImpl::DummyControlImpl()
 {
 }
 
-
 DummyControlImpl::~DummyControlImpl()
 {
 }
@@ -80,6 +79,11 @@ void DummyControlImpl::RegisterVisual( Property::Index index, Actor placementAct
   Control::RegisterVisual( index, placementActor, visual );
 }
 
+void DummyControlImpl::RegisterVisual( Property::Index index, Actor placementActor, Toolkit::Visual::Base visual, bool enabled )
+{
+  Control::RegisterVisual( index, placementActor, visual, enabled );
+}
+
 void DummyControlImpl::UnregisterVisual( Property::Index index )
 {
   Control::UnregisterVisual( index );
@@ -90,11 +94,26 @@ Toolkit::Visual::Base DummyControlImpl::GetVisual( Property::Index index )
   return Control::GetVisual( index );
 }
 
+void DummyControlImpl::EnableVisual( Property::Index index, bool enabled )
+{
+  Control::EnableVisual( index, enabled );
+}
+
+bool DummyControlImpl::IsVisualEnabled( Property::Index index )
+{
+  return Control::IsVisualEnabled( index );
+}
+
 Actor DummyControlImpl::GetPlacementActor( Property::Index index )
 {
   return Control::GetPlacementActor( index );
 }
 
+Animation DummyControlImpl::CreateTransition( const Toolkit::TransitionData& transition )
+{
+  return Control::CreateTransition( transition );
+}
+
 DummyControl DummyControlImplOverride::New()
 {
   IntrusivePtr< DummyControlImplOverride > impl = new DummyControlImplOverride;
index 3c88685..d63b853 100644 (file)
@@ -72,9 +72,14 @@ public:
   inline LongPressGestureDetector GetLongPressGestureDetector() const { return Internal::Control::GetLongPressGestureDetector(); }
 
   void RegisterVisual( Property::Index index, Actor placementActor, Toolkit::Visual::Base visual);
+  void RegisterVisual( Property::Index index, Actor placementActor, Toolkit::Visual::Base visual, bool enabled );
   void UnregisterVisual( Property::Index index );
+  void EnableVisual( Property::Index index, bool enabled );
+  bool IsVisualEnabled( Property::Index index );
+
   Toolkit::Visual::Base GetVisual( Property::Index index );
   Actor GetPlacementActor( Property::Index index );
+  Animation CreateTransition( const Toolkit::TransitionData& transition );
 
   // Used to test signal connections
   void CustomSlot1( Actor actor );
index 21603f3..3ee9a77 100644 (file)
@@ -206,7 +206,30 @@ int UtcDaliAsyncImageLoaderCancel(void)
   END_TEST;
 }
 
-int UtcDaliAsyncImageLoaderCancelAll(void)
+int UtcDaliAsncImageLoaderCancelAll01(void)
+{
+  ToolkitTestApplication application;
+
+  AsyncImageLoader loader = AsyncImageLoader::New();
+
+  // Test that it is safe to call CancelAll even there is no loading task requested.
+  try
+  {
+    loader.CancelAll();
+  }
+  catch(Dali::DaliException& e)
+  {
+    DALI_TEST_ASSERT(e, "AsyncImageLoader::LoadAll", TEST_LOCATION);
+  }
+
+  // Test that cancelling a non-existing loading task will return false
+  uint32_t id = 1;
+  DALI_TEST_CHECK( !(loader.Cancel( id )) );
+
+  END_TEST;
+}
+
+int UtcDaliAsyncImageLoaderCancelAll02(void)
 {
   ToolkitTestApplication application;
 
index 2e691af..6fe4af6 100644 (file)
@@ -1054,6 +1054,7 @@ int UtcDaliControlImplRegisterVisualToSelf(void)
 
     // Register to self
     dummyImpl.RegisterVisual( index, dummy, visual );
+
     DALI_TEST_EQUALS( objectDestructionTracker.IsDestroyed(), false, TEST_LOCATION ); // Control not destroyed yet
     DALI_TEST_CHECK( dummyImpl.GetVisual( index ) == visual );
     DALI_TEST_CHECK( dummyImpl.GetPlacementActor( index ) == dummy );
@@ -1144,3 +1145,215 @@ int UtcDaliControlImplRegisterUnregisterVisual(void)
 
   END_TEST;
 }
+
+int UtcDaliControlImplRegisterDisabledVisual(void)
+{
+  ToolkitTestApplication application;
+
+  DummyControl dummy = DummyControl::New();
+  DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(dummy.GetImplementation());
+
+  Property::Index TEST_PROPERTY =1;
+
+  Toolkit::VisualFactory visualFactory = Toolkit::VisualFactory::Get();
+  Toolkit::Visual::Base visual;
+
+  Property::Map map;
+  map[Visual::Property::TYPE] = Visual::COLOR;
+  map[ColorVisual::Property::MIX_COLOR] = Color::RED;
+
+  visual = visualFactory.CreateVisual( map );
+  DALI_TEST_CHECK(visual);
+
+  // Register index with a color visual
+  dummyImpl.RegisterVisual( TEST_PROPERTY, dummy, visual, false );
+
+  DALI_TEST_CHECK( dummyImpl.GetVisual( TEST_PROPERTY ) == visual );
+  DALI_TEST_CHECK( dummyImpl.IsVisualEnabled( TEST_PROPERTY ) == false );
+
+  Stage::GetCurrent().Add(dummy);
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_CHECK( dummyImpl.IsVisualEnabled( TEST_PROPERTY ) == false );
+
+  DALI_TEST_CHECK( dummy.OnStage() == true );
+
+  dummyImpl.EnableVisual( TEST_PROPERTY, true );
+
+  DALI_TEST_CHECK( dummyImpl.IsVisualEnabled( TEST_PROPERTY ) == true );
+
+  END_TEST;
+}
+
+int UtcDaliControlImplDisableRegisteredVisual(void)
+{
+  ToolkitTestApplication application;
+
+  DummyControl dummy = DummyControl::New();
+  DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(dummy.GetImplementation());
+
+  Property::Index TEST_PROPERTY =1;
+
+  Toolkit::VisualFactory visualFactory = Toolkit::VisualFactory::Get();
+  Toolkit::Visual::Base visual;
+
+  Property::Map map;
+  map[Visual::Property::TYPE] = Visual::COLOR;
+  map[ColorVisual::Property::MIX_COLOR] = Color::RED;
+
+  visual = visualFactory.CreateVisual( map );
+  DALI_TEST_CHECK(visual);
+
+  // Register index with a color visual
+  dummyImpl.RegisterVisual( TEST_PROPERTY, dummy, visual );
+
+  Stage::GetCurrent().Add(dummy);
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_CHECK( dummyImpl.IsVisualEnabled( TEST_PROPERTY ) == true);
+
+  DALI_TEST_CHECK( dummy.OnStage() == true );
+
+  dummyImpl.EnableVisual( TEST_PROPERTY, false );
+
+  DALI_TEST_CHECK( dummyImpl.IsVisualEnabled( TEST_PROPERTY ) == false );
+
+  END_TEST;
+}
+
+int UtcDaliControlImplEnabledVisualParentRemovedFromStage(void)
+{
+  // Visual enabled but then parent removed from stage, test ensures visual/renderer are also removed from stage.
+  // Then adding parent back to stage should automatically put visual/renderer back
+
+  ToolkitTestApplication application;
+
+  DummyControl dummy = DummyControl::New();
+  DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(dummy.GetImplementation());
+
+  Property::Index TEST_PROPERTY =1;
+
+  Toolkit::VisualFactory visualFactory = Toolkit::VisualFactory::Get();
+  Toolkit::Visual::Base visual;
+
+  Property::Map map;
+  map[Visual::Property::TYPE] = Visual::COLOR;
+  map[ColorVisual::Property::MIX_COLOR] = Color::RED;
+
+  visual = visualFactory.CreateVisual( map );
+  DALI_TEST_CHECK(visual);
+
+  // Register index with a color visual
+  dummyImpl.RegisterVisual( TEST_PROPERTY, dummy, visual, false );
+
+  Stage::GetCurrent().Add(dummy);
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_CHECK( dummyImpl.IsVisualEnabled( TEST_PROPERTY ) == false );
+  DALI_TEST_CHECK( dummy.OnStage() == true );
+  dummyImpl.EnableVisual( TEST_PROPERTY, true );
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+  DALI_TEST_CHECK( dummy.GetRendererCount() == 1u );
+
+  // Remove control from stage, visual should be removed from stage too
+  Stage::GetCurrent().Remove(dummy);
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+  DALI_TEST_CHECK( dummy.GetRendererCount() == 0u );
+
+  Stage::GetCurrent().Add(dummy);
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+  DALI_TEST_CHECK( dummy.GetRendererCount() == 1u );
+
+  DALI_TEST_CHECK( dummyImpl.IsVisualEnabled( TEST_PROPERTY ) == true );
+
+  END_TEST;
+}
+
+int UtcDaliControlImplRegisterTwoVisualsAndEnableOnlyOne(void)
+{
+  // Register 2 visuals and enable by default
+  // Disable 1 visual
+  // Remove control from stage then put it back
+  // Check that only 1 visual/renderer is staged.
+
+  ToolkitTestApplication application;
+
+  DummyControl dummy = DummyControl::New();
+  DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(dummy.GetImplementation());
+
+  Property::Index TEST_PROPERTY1 =1;
+  Property::Index TEST_PROPERTY2 =2;
+
+  Toolkit::VisualFactory visualFactory = Toolkit::VisualFactory::Get();
+  Toolkit::Visual::Base visual1;
+  Toolkit::Visual::Base visual2;
+
+  Property::Map map;
+  map[Visual::Property::TYPE] = Visual::COLOR;
+  map[ColorVisual::Property::MIX_COLOR] = Color::RED;
+
+  Property::Map map2;
+  map[Visual::Property::TYPE] = Visual::COLOR;
+  map[ColorVisual::Property::MIX_COLOR] = Color::BLUE;
+
+  visual1 = visualFactory.CreateVisual( map );
+  DALI_TEST_CHECK(visual1);
+
+  visual2 = visualFactory.CreateVisual( map );
+  DALI_TEST_CHECK(visual2);
+
+  // Register index with a color visual
+  dummyImpl.RegisterVisual( TEST_PROPERTY1, dummy, visual1 );
+  // Register second index with a color visual
+  dummyImpl.RegisterVisual( TEST_PROPERTY2, dummy, visual2 );
+
+  Stage::GetCurrent().Add(dummy);
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_CHECK( dummy.GetRendererCount() == 2u );
+  DALI_TEST_CHECK( dummyImpl.IsVisualEnabled( TEST_PROPERTY1 ) == true );
+  DALI_TEST_CHECK( dummyImpl.IsVisualEnabled( TEST_PROPERTY1 ) == true);
+  DALI_TEST_CHECK( dummy.OnStage() == true );
+  dummyImpl.EnableVisual( TEST_PROPERTY2, false );
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+  DALI_TEST_CHECK( dummy.GetRendererCount() == 1u );
+
+  // Remove control from stage, visual should be removed from stage too
+  Stage::GetCurrent().Remove(dummy);
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+  DALI_TEST_CHECK( dummy.GetRendererCount() == 0u );
+
+  Stage::GetCurrent().Add(dummy);
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+  DALI_TEST_CHECK( dummy.GetRendererCount() == 1u );
+
+  DALI_TEST_CHECK( dummyImpl.IsVisualEnabled( TEST_PROPERTY1 ) == true );
+  DALI_TEST_CHECK( dummyImpl.IsVisualEnabled( TEST_PROPERTY2 ) == false );
+
+  END_TEST;
+}
+
index a945850..5fe744f 100644 (file)
@@ -60,6 +60,22 @@ bool IsOverlap( Rect<int> rect1, Rect<int> rect2 )
      && rect2.y < rect1.y+rect1.height;
 }
 
+static unsigned int gCountOfTestFuncCall;
+class TestUploadObserver : public AtlasUploadObserver
+{
+public:
+  TestUploadObserver()
+  {}
+
+  virtual ~TestUploadObserver()
+  {}
+
+  void UploadCompleted()
+  {
+    gCountOfTestFuncCall++;
+  }
+};
+
 } // anonymous namespace
 
 void dali_image_atlas_startup(void)
@@ -241,6 +257,100 @@ int UtcDaliImageAtlasUploadP(void)
   END_TEST;
 }
 
+int UtcDaliImageAtlasUploadWithObserver01(void)
+{
+  TestApplication application;
+  ImageAtlas atlas = ImageAtlas::New( 200, 200 );
+
+  EventThreadCallback* eventTrigger = EventThreadCallback::Get();
+  CallbackBase* callback = eventTrigger->GetCallback();
+
+  gCountOfTestFuncCall = 0;
+  TestUploadObserver uploadObserver;
+
+  Vector4 textureRect1;
+  atlas.Upload( textureRect1, gImage_34_RGBA, ImageDimensions(34, 34), FittingMode::DEFAULT, true, &uploadObserver );
+  Vector4 textureRect2;
+  atlas.Upload( textureRect2, gImage_50_RGBA, ImageDimensions(50, 50), FittingMode::DEFAULT, true, NULL );
+  Vector4 textureRect3;
+  atlas.Upload( textureRect3, gImage_128_RGB, ImageDimensions(128, 128), FittingMode::DEFAULT, true, &uploadObserver );
+
+  // waiting until all three images are loaded and uploaded to atlas
+  eventTrigger->WaitingForTrigger( 3 );
+  CallbackBase::Execute( *callback );
+  application.SendNotification();
+  application.Render(RENDER_FRAME_INTERVAL);
+
+  // Check that TestFunc is called twice
+  DALI_TEST_EQUALS( gCountOfTestFuncCall, 2, TEST_LOCATION );
+
+  END_TEST;
+}
+
+int UtcDaliImageAtlasUploadWithObserver02(void)
+{
+  TestApplication application;
+  ImageAtlas atlas = ImageAtlas::New( 200, 200 );
+
+  EventThreadCallback* eventTrigger = EventThreadCallback::Get();
+  CallbackBase* callback = eventTrigger->GetCallback();
+
+  gCountOfTestFuncCall = 0;
+  TestUploadObserver* uploadObserver = new TestUploadObserver;
+
+  Vector4 textureRect1;
+  atlas.Upload( textureRect1, gImage_34_RGBA, ImageDimensions(34, 34), FittingMode::DEFAULT, true, uploadObserver );
+  Vector4 textureRect2;
+  atlas.Upload( textureRect2, gImage_50_RGBA, ImageDimensions(50, 50), FittingMode::DEFAULT, true, uploadObserver );
+  Vector4 textureRect3;
+  atlas.Upload( textureRect3, gImage_128_RGB, ImageDimensions(128, 128), FittingMode::DEFAULT, true, uploadObserver );
+
+  // destroy the object.
+  delete uploadObserver;
+
+ // waiting until all three images are loaded and uploaded to atlas
+  eventTrigger->WaitingForTrigger( 3 );
+  CallbackBase::Execute( *callback );
+  application.Render(RENDER_FRAME_INTERVAL);
+  application.SendNotification();
+
+  // Check that TestFunc is called twice
+  DALI_TEST_EQUALS( gCountOfTestFuncCall, 0, TEST_LOCATION );
+
+  END_TEST;
+}
+
+int UtcDaliImageAtlasUploadWithObserver03(void)
+{
+  TestApplication application;
+
+  gCountOfTestFuncCall = 0;
+  TestUploadObserver* uploadObserver = new TestUploadObserver;
+
+  {
+    ImageAtlas atlas = ImageAtlas::New( 200, 200 );
+
+    Vector4 textureRect1;
+    atlas.Upload( textureRect1, gImage_34_RGBA, ImageDimensions(34, 34), FittingMode::DEFAULT, true, uploadObserver );
+    Vector4 textureRect2;
+    atlas.Upload( textureRect2, gImage_50_RGBA, ImageDimensions(50, 50), FittingMode::DEFAULT, true, uploadObserver );
+    Vector4 textureRect3;
+    atlas.Upload( textureRect3, gImage_128_RGB, ImageDimensions(128, 128), FittingMode::DEFAULT, true, uploadObserver );
+  }
+
+  //ImageAtlas is out of scope, so it will get destroyed
+
+  application.Render(RENDER_FRAME_INTERVAL);
+  application.SendNotification();
+  application.SendNotification();
+  application.Render(RENDER_FRAME_INTERVAL);
+
+  // Check that TestFunc is called twice
+  DALI_TEST_EQUALS( gCountOfTestFuncCall, 0, TEST_LOCATION );
+
+  END_TEST;
+}
+
 int UtcDaliImageAtlasRemove(void)
 {
   TestApplication application;
index 779259d..12c3f17 100644 (file)
@@ -393,6 +393,7 @@ int UtcDaliImageViewAsyncLoadingWithAltasing(void)
   callStack.Reset();
   callStack.Enable(true);
 
+  BitmapLoader::ResetLatestCreated();
   ImageView imageView = ImageView::New( gImage_34_RGBA, ImageDimensions( 34, 34 ) );
 
   // By default, Aysnc loading is used
index 83744f3..b6b638c 100644 (file)
@@ -441,16 +441,16 @@ int UtcDaliTextEditorSetPropertyP(void)
   DALI_TEST_EQUALS( editor.GetProperty<float>( TextEditor::Property::INPUT_LINE_SPACING ), 20.0f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
 
   // Check the underline property
-  editor.SetProperty( TextEditor::Property::UNDERLINE, "Underline properties" );
-  DALI_TEST_EQUALS( editor.GetProperty<std::string>( TextEditor::Property::UNDERLINE ), std::string("Underline properties"), TEST_LOCATION );
+  editor.SetProperty( TextEditor::Property::UNDERLINE, "{\"enable\":\"true\",\"color\":\"red\",\"height\":\"1\"}" );
+  DALI_TEST_EQUALS( editor.GetProperty<std::string>( TextEditor::Property::UNDERLINE ), std::string("{\"enable\":\"true\",\"color\":\"red\",\"height\":\"1\"}"), TEST_LOCATION );
 
   // Check the input underline property
   editor.SetProperty( TextEditor::Property::INPUT_UNDERLINE, "Underline input properties" );
   DALI_TEST_EQUALS( editor.GetProperty<std::string>( TextEditor::Property::INPUT_UNDERLINE ), std::string("Underline input properties"), TEST_LOCATION );
 
   // Check the shadow property
-  editor.SetProperty( TextEditor::Property::SHADOW, "Shadow properties" );
-  DALI_TEST_EQUALS( editor.GetProperty<std::string>( TextEditor::Property::SHADOW ), std::string("Shadow properties"), TEST_LOCATION );
+  editor.SetProperty( TextEditor::Property::SHADOW, "{\"color\":\"green\",\"offset\":\"2 2\"}" );
+  DALI_TEST_EQUALS( editor.GetProperty<std::string>( TextEditor::Property::SHADOW ), std::string("{\"color\":\"green\",\"offset\":\"2 2\"}"), TEST_LOCATION );
 
   // Check the input shadow property
   editor.SetProperty( TextEditor::Property::INPUT_SHADOW, "Shadow input properties" );
index 0335e4e..80ed1d7 100644 (file)
@@ -612,16 +612,16 @@ int UtcDaliTextFieldSetPropertyP(void)
   DALI_TEST_EQUALS( field.GetProperty<std::string>( TextField::Property::INPUT_FONT_STYLE ), std::string(""), TEST_LOCATION );
 
   // Check the underline property
-  field.SetProperty( TextField::Property::UNDERLINE, "Underline properties" );
-  DALI_TEST_EQUALS( field.GetProperty<std::string>( TextField::Property::UNDERLINE ), std::string("Underline properties"), TEST_LOCATION );
+  field.SetProperty( TextField::Property::UNDERLINE, "{\"enable\":\"true\",\"color\":\"red\",\"height\":\"1\"}" );
+  DALI_TEST_EQUALS( field.GetProperty<std::string>( TextField::Property::UNDERLINE ), std::string("{\"enable\":\"true\",\"color\":\"red\",\"height\":\"1\"}"), TEST_LOCATION );
 
   // Check the input underline property
   field.SetProperty( TextField::Property::INPUT_UNDERLINE, "Underline input properties" );
   DALI_TEST_EQUALS( field.GetProperty<std::string>( TextField::Property::INPUT_UNDERLINE ), std::string("Underline input properties"), TEST_LOCATION );
 
   // Check the shadow property
-  field.SetProperty( TextField::Property::SHADOW, "Shadow properties" );
-  DALI_TEST_EQUALS( field.GetProperty<std::string>( TextField::Property::SHADOW ), std::string("Shadow properties"), TEST_LOCATION );
+  field.SetProperty( TextField::Property::SHADOW, "{\"color\":\"green\",\"offset\":\"2 2\"}" );
+  DALI_TEST_EQUALS( field.GetProperty<std::string>( TextField::Property::SHADOW ), std::string("{\"color\":\"green\",\"offset\":\"2 2\"}"), TEST_LOCATION );
 
   // Check the input shadow property
   field.SetProperty( TextField::Property::INPUT_SHADOW, "Shadow input properties" );
index 5f9a710..0f0072e 100644 (file)
@@ -222,6 +222,8 @@ int UtcDaliToolkitTextLabelSetPropertyP(void)
   // The underline color is changed as well.
   DALI_TEST_EQUALS( label.GetProperty<Vector4>( TextLabel::Property::UNDERLINE_COLOR ), Color::BLUE, TEST_LOCATION );
 
+  DALI_TEST_EQUALS( label.GetProperty<std::string>( TextLabel::Property::UNDERLINE ), std::string("{\"enable\":\"false\",\"color\":\"blue\",\"height\":\"0\"}"), TEST_LOCATION );
+
   // Check that shadow parameters can be correctly set
   label.SetProperty( TextLabel::Property::SHADOW_OFFSET, Vector2( 3.0f, 3.0f ) );
   DALI_TEST_EQUALS( label.GetProperty<Vector2>( TextLabel::Property::SHADOW_OFFSET ), Vector2( 3.0f, 3.0f ), TEST_LOCATION );
@@ -266,12 +268,18 @@ int UtcDaliToolkitTextLabelSetPropertyP(void)
   DALI_TEST_EQUALS( label.GetProperty<float>( TextLabel::Property::LINE_SPACING ), 10.0f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
 
   // Check the underline property
-  label.SetProperty( TextLabel::Property::UNDERLINE, "Underline properties" );
-  DALI_TEST_EQUALS( label.GetProperty<std::string>( TextLabel::Property::UNDERLINE ), std::string("Underline properties"), TEST_LOCATION );
+  label.SetProperty( TextLabel::Property::UNDERLINE, "{\"enable\":\"true\",\"color\":\"red\",\"height\":\"1\"}" );
+  DALI_TEST_EQUALS( label.GetProperty<std::string>( TextLabel::Property::UNDERLINE ), std::string("{\"enable\":\"true\",\"color\":\"red\",\"height\":\"1\"}"), TEST_LOCATION );
+
+  label.SetProperty( TextLabel::Property::UNDERLINE, "" );
+  DALI_TEST_EQUALS( label.GetProperty<std::string>( TextLabel::Property::UNDERLINE ), std::string("{\"enable\":\"false\",\"color\":\"red\",\"height\":\"1\"}"), TEST_LOCATION );
 
   // Check the shadow property
-  label.SetProperty( TextLabel::Property::SHADOW, "Shadow properties" );
-  DALI_TEST_EQUALS( label.GetProperty<std::string>( TextLabel::Property::SHADOW ), std::string("Shadow properties"), TEST_LOCATION );
+  label.SetProperty( TextLabel::Property::SHADOW, "{\"color\":\"green\",\"offset\":\"2 2\"}" );
+  DALI_TEST_EQUALS( label.GetProperty<std::string>( TextLabel::Property::SHADOW ), std::string("{\"color\":\"green\",\"offset\":\"2 2\"}"), TEST_LOCATION );
+
+  label.SetProperty( TextLabel::Property::SHADOW, "" );
+  DALI_TEST_EQUALS( label.GetProperty<std::string>( TextLabel::Property::SHADOW ), std::string("{\"color\":\"green\",\"offset\":\"0 0\"}"), TEST_LOCATION );
 
   // Check the emboss property
   label.SetProperty( TextLabel::Property::EMBOSS, "Emboss properties" );
@@ -395,14 +403,14 @@ int UtcDaliToolkitTextlabelScrollingP(void)
   Stage::GetCurrent().Add( label );
   // Turn on all the effects
   label.SetProperty( TextLabel::Property::MULTI_LINE, false );
-  label.SetProperty(  TextLabel::Property::AUTO_SCROLL_GAP, 50.0f );
-  label.SetProperty(  TextLabel::Property::AUTO_SCROLL_LOOP_COUNT, 3 );
-  label.SetProperty(  TextLabel::Property::AUTO_SCROLL_SPEED, 80.0f);
+  label.SetProperty( TextLabel::Property::AUTO_SCROLL_GAP, 50.0f );
+  label.SetProperty( TextLabel::Property::AUTO_SCROLL_LOOP_COUNT, 3 );
+  label.SetProperty( TextLabel::Property::AUTO_SCROLL_SPEED, 80.0f );
 
   try
   {
     // Render some text with the shared atlas backend
-    label.SetProperty(  TextLabel::Property::ENABLE_AUTO_SCROLL, true );
+    label.SetProperty( TextLabel::Property::ENABLE_AUTO_SCROLL, true );
     application.SendNotification();
     application.Render();
   }
@@ -414,6 +422,37 @@ int UtcDaliToolkitTextlabelScrollingP(void)
   END_TEST;
 }
 
+int UtcDaliToolkitTextlabelScrollingN(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliToolkitTextlabelScrollingN");
+
+  TextLabel label = TextLabel::New("Some text to scroll");
+  DALI_TEST_CHECK( label );
+
+  Stage::GetCurrent().Add( label );
+
+  // Avoid a crash when core load gl resources.
+  application.GetGlAbstraction().SetCheckFramebufferStatusResult( GL_FRAMEBUFFER_COMPLETE );
+
+  // The text scrolling works only on single line text.
+  label.SetProperty( TextLabel::Property::MULTI_LINE, true );
+
+  // Turn on all the effects.
+  label.SetProperty( TextLabel::Property::AUTO_SCROLL_GAP, 50.0f );
+  label.SetProperty( TextLabel::Property::AUTO_SCROLL_LOOP_COUNT, 3 );
+  label.SetProperty( TextLabel::Property::AUTO_SCROLL_SPEED, 80.0f );
+
+  // Enable the auto scrolling effect.
+  label.SetProperty( TextLabel::Property::ENABLE_AUTO_SCROLL, true );
+
+  // The auto scrolling shouldn't be enabled.
+  const bool enabled = label.GetProperty( TextLabel::Property::ENABLE_AUTO_SCROLL ).Get<bool>();
+  DALI_TEST_CHECK( !enabled );
+
+  END_TEST;
+}
+
 int UtcDaliToolkitTextlabelEllipsis(void)
 {
   ToolkitTestApplication application;
diff --git a/automated-tests/src/dali-toolkit/utc-Dali-TransitionData.cpp b/automated-tests/src/dali-toolkit/utc-Dali-TransitionData.cpp
new file mode 100644 (file)
index 0000000..71851de
--- /dev/null
@@ -0,0 +1,916 @@
+/*
+ * 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 <iostream>
+#include <stdlib.h>
+#include <dali-toolkit-test-suite-utils.h>
+#include <dali.h>
+#include <dali-toolkit/dali-toolkit.h>
+#include <dali-toolkit/devel-api/visual-factory/transition-data.h>
+#include <dali-toolkit/devel-api/visual-factory/visual-factory.h>
+#include "dummy-control.h"
+
+using namespace Dali;
+using namespace Toolkit;
+
+
+void utc_dali_toolkit_transition_data_startup(void)
+{
+  test_return_value = TET_UNDEF;
+}
+
+void utc_dali_toolkit_transition_data_cleanup(void)
+{
+  test_return_value = TET_PASS;
+}
+
+Property::Map CreateMap()
+{
+  Property::Map map;
+
+  map["target"] = "Actor1";
+  map["property"] = "color";
+  map["initialValue"] = Color::MAGENTA;
+  map["targetValue"] = Color::RED;
+  map["animator"] = Property::Map()
+    .Add("alphaFunction", "EASE_IN_OUT_BACK")
+    .Add("timePeriod", Property::Map()
+         .Add("delay", 0.5f)
+         .Add("duration", 1.0f));
+  return map;
+}
+
+void CHECK_ARRAY_EQUALS( Property::Array test, Property::Value result )
+{
+  if( result.GetType() == Property::ARRAY )
+  {
+    // Compare arrays
+    Property::Array *resultArray = result.GetArray();
+    DALI_TEST_EQUALS( test.Count(), resultArray->Count(), TEST_LOCATION );
+    for( size_t i=0; i < std::min(test.Count(), resultArray->Count()); ++i )
+    {
+      Property::Value a = test.GetElementAt(i);
+      Property::Value b = resultArray->GetElementAt(i);
+      DALI_TEST_EQUALS( a.GetType(), b.GetType(), TEST_LOCATION );
+      DALI_TEST_EQUALS( a, b, 0.001, TEST_LOCATION );
+    }
+  }
+  else if( result.GetType() == Property::VECTOR4 )
+  {
+    Vector4 value = result.Get<Vector4>();
+    DALI_TEST_CHECK( test.Count() >= 4 );
+    for( size_t i=0; i < 4; ++i )
+    {
+      Property::Value a = test.GetElementAt(i);
+      DALI_TEST_EQUALS( a.GetType(), Property::FLOAT, TEST_LOCATION );
+      DALI_TEST_EQUALS( a.Get<float>(), value[i], 0.001, TEST_LOCATION );
+    }
+  }
+  else
+  {
+    DALI_TEST_CHECK( 0 );
+  }
+}
+
+void CHECK_MAP_EQUALS( Property::Map test, Property::Map result )
+{
+  DALI_TEST_EQUALS(test.Count(), result.Count(), TEST_LOCATION);
+
+  for( unsigned int i=0; i< test.Count(); ++i )
+  {
+    KeyValuePair keyValue = test.GetKeyValue(i);
+    Property::Value* value;
+
+    if( keyValue.first.type == Property::Key::STRING )
+    {
+      value = result.Find(keyValue.first.stringKey);
+    }
+    else
+    {
+      value = result.Find(keyValue.first.indexKey);
+    }
+
+    DALI_TEST_CHECK( value != NULL );
+    if( value != NULL )
+    {
+      if( keyValue.second.GetType() == Property::MAP )
+      {
+        DALI_TEST_EQUALS( keyValue.second.GetType(), value->GetType(), TEST_LOCATION );
+        CHECK_MAP_EQUALS( *(keyValue.second.GetMap()), *(value->GetMap()) );
+      }
+      else if( keyValue.second.GetType() == Property::ARRAY )
+      {
+        CHECK_ARRAY_EQUALS( *(keyValue.second.GetArray()), *value );
+      }
+      else if( keyValue.second.GetType() == Property::STRING )
+      {
+        DALI_TEST_EQUALS( keyValue.second.GetType(), value->GetType(), TEST_LOCATION );
+        std::string str;
+        value->Get(str);
+        DALI_TEST_EQUALS( keyValue.second, str.c_str(), TEST_LOCATION );
+      }
+      else
+      {
+        DALI_TEST_EQUALS( keyValue.second.GetType(), value->GetType(), TEST_LOCATION );
+        DALI_TEST_EQUALS( keyValue.second, *value, 0.001f, TEST_LOCATION );
+      }
+    }
+  }
+}
+
+
+int UtcDaliTransitionDataNew(void)
+{
+  TestApplication application;
+
+  Property::Map map = CreateMap();
+  Dali::Toolkit::TransitionData transition = TransitionData::New( map );
+  DALI_TEST_CHECK( transition );
+
+  END_TEST;
+}
+
+int UtcDaliTransitionDataDownCast(void)
+{
+  TestApplication application;
+
+  Property::Map map = CreateMap();
+
+  BaseHandle handle = TransitionData::New( map );
+  DALI_TEST_CHECK( handle );
+
+  TransitionData transitionData = TransitionData::DownCast( handle );
+  DALI_TEST_CHECK( transitionData );
+  END_TEST;
+}
+
+int UtcDaliTransitionDataCopyConstructor(void)
+{
+  TestApplication application;
+
+  Property::Map map = CreateMap();
+
+  TransitionData transitionData = TransitionData::New( map );
+  DALI_TEST_CHECK( transitionData );
+
+  TransitionData td2( transitionData );
+  DALI_TEST_CHECK( td2 );
+  DALI_TEST_EQUALS( td2.Count(), 1, TEST_LOCATION );
+  END_TEST;
+}
+
+int UtcDaliTransitionDataAssignmentOperator(void)
+{
+  TestApplication application;
+
+  Property::Map map = CreateMap();
+
+  TransitionData transitionData = TransitionData::New( map );
+  DALI_TEST_CHECK( transitionData );
+
+  TransitionData td2;
+  DALI_TEST_CHECK( !td2 );
+
+  td2 = transitionData;
+  DALI_TEST_CHECK( td2 );
+
+  DALI_TEST_EQUALS( td2.Count(), 1, TEST_LOCATION );
+  END_TEST;
+}
+
+int UtcDaliTransitionDataCount(void)
+{
+  TestApplication application;
+
+  Property::Map map = CreateMap();
+  TransitionData transitionData = TransitionData::New( map );
+  DALI_TEST_CHECK( transitionData );
+  DALI_TEST_EQUALS( transitionData.Count(), 1, TEST_LOCATION );
+
+  Property::Array array;
+  array.PushBack( map );
+  array.PushBack( map );
+  array.PushBack( map );
+
+  TransitionData transitionData2 = TransitionData::New( array );
+  DALI_TEST_CHECK( transitionData2 );
+  DALI_TEST_EQUALS( transitionData2.Count(), 3, TEST_LOCATION );
+
+  END_TEST;
+}
+
+int UtcDaliTransitionDataMap1P(void)
+{
+  TestApplication application;
+
+  tet_printf("Testing animation of a visual property using stylesheet equivalent maps\n");
+
+  Property::Map map;
+  map["target"] = "visual1";
+  map["property"] = "mixColor";
+  map["initialValue"] = Color::MAGENTA;
+  map["targetValue"] = Color::RED;
+  map["animator"] = Property::Map()
+    .Add("alphaFunction", "EASE_IN_OUT")
+    .Add("timePeriod", Property::Map()
+         .Add("delay", 0.5f)
+         .Add("duration", 1.0f));
+
+  Dali::Toolkit::TransitionData transition = TransitionData::New( map );
+
+  DummyControl actor = DummyControl::New();
+  actor.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS);
+  actor.SetName("Actor1");
+  actor.SetColor(Color::CYAN);
+  Stage::GetCurrent().Add(actor);
+
+  DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(actor.GetImplementation());
+
+  Property::Map visualMap;
+  visualMap[Visual::Property::TYPE] = Visual::COLOR;
+  visualMap[ColorVisual::Property::MIX_COLOR] = Color::MAGENTA;
+  Visual::Base visual = VisualFactory::Get().CreateVisual( visualMap );
+  visual.SetName( "visual1" );
+
+  Property::Index visualIndex = Control::CONTROL_PROPERTY_END_INDEX + 1;
+  dummyImpl.RegisterVisual( visualIndex, actor, visual );
+
+  Animation anim = dummyImpl.CreateTransition( transition );
+  DALI_TEST_CHECK( anim );
+
+  Renderer renderer = actor.GetRendererAt(0);
+  Property::Index mixColorIndex = renderer.GetPropertyIndex( ColorVisual::Property::MIX_COLOR );
+  application.SendNotification();
+  application.Render(0);
+
+  DALI_TEST_EQUALS( renderer.GetProperty<Vector4>(mixColorIndex), Color::MAGENTA, TEST_LOCATION);
+
+  anim.Play();
+
+  application.SendNotification();
+  application.Render(0);
+  application.Render(500); // Start animation
+  application.Render(500); // Halfway thru anim
+  application.SendNotification();
+  DALI_TEST_EQUALS( renderer.GetProperty<Vector4>(mixColorIndex), (Color::MAGENTA+Color::RED)*0.5f, TEST_LOCATION);
+
+  application.Render(500); // End of anim
+  application.SendNotification();
+  DALI_TEST_EQUALS( renderer.GetProperty<Vector4>(mixColorIndex), Color::RED, TEST_LOCATION );
+
+  END_TEST;
+}
+
+int UtcDaliTransitionDataMap2P(void)
+{
+  TestApplication application;
+
+  tet_printf("Testing animation of a visual property using programmatic maps\n");
+
+  Property::Map map;
+  map["target"] = "visual1";
+  //Control::CONTROL_PROPERTY_END_INDEX + 1
+  map["property"] = ColorVisual::Property::MIX_COLOR;
+  map["initialValue"] = Color::MAGENTA;
+  map["targetValue"] = Color::RED;
+  map["animator"] = Property::Map()
+    .Add("alphaFunction", "LINEAR")
+    .Add("timePeriod", Property::Map()
+         .Add("delay", 0.5f)
+         .Add("duration", 1.0f));
+
+  Dali::Toolkit::TransitionData transition = TransitionData::New( map );
+
+  DummyControl actor = DummyControl::New();
+  actor.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS);
+  actor.SetName("Actor1");
+  actor.SetColor(Color::CYAN);
+  Stage::GetCurrent().Add(actor);
+
+  DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(actor.GetImplementation());
+
+  Property::Map visualMap;
+  visualMap[Visual::Property::TYPE] = Visual::COLOR;
+  visualMap[ColorVisual::Property::MIX_COLOR] = Color::MAGENTA;
+  Visual::Base visual = VisualFactory::Get().CreateVisual( visualMap );
+  visual.SetName( "visual1" );
+
+  Property::Index visualIndex = Control::CONTROL_PROPERTY_END_INDEX + 1;
+  dummyImpl.RegisterVisual( visualIndex, actor, visual );
+
+  Animation anim = dummyImpl.CreateTransition( transition );
+  DALI_TEST_CHECK( anim );
+
+  Renderer renderer = actor.GetRendererAt(0);
+  Property::Index mixColorIndex = renderer.GetPropertyIndex( ColorVisual::Property::MIX_COLOR );
+  application.SendNotification();
+  application.Render(0);
+
+  DALI_TEST_EQUALS( renderer.GetProperty<Vector4>(mixColorIndex), Color::MAGENTA, TEST_LOCATION);
+
+  anim.Play();
+
+  application.SendNotification();
+  application.Render(0);
+  application.Render(500); // Start animation
+  application.Render(500); // Halfway thru anim
+  application.SendNotification();
+  DALI_TEST_EQUALS( renderer.GetProperty<Vector4>(mixColorIndex), (Color::MAGENTA+Color::RED)*0.5f, TEST_LOCATION);
+
+  application.Render(500); // End of anim
+  application.SendNotification();
+  DALI_TEST_EQUALS( renderer.GetProperty<Vector4>(mixColorIndex), Color::RED, TEST_LOCATION );
+
+  END_TEST;
+}
+
+
+int UtcDaliTransitionDataMap3P(void)
+{
+  TestApplication application;
+
+  tet_printf("Testing animation of a visual's placement actor property\n");
+
+  Property::Map map;
+  map["target"] = "visual1";
+  map["property"] = "color";
+  map["initialValue"] = Color::MAGENTA;
+  map["targetValue"] = Color::RED;
+  map["animator"] = Property::Map()
+    .Add("alphaFunction", "EASE_IN_OUT")
+    .Add("timePeriod", Property::Map()
+         .Add("delay", 0.5f)
+         .Add("duration", 1.0f));
+
+  Dali::Toolkit::TransitionData transition = TransitionData::New( map );
+
+  DummyControl actor = DummyControl::New();
+  actor.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS);
+  actor.SetName("Actor1");
+  actor.SetColor(Color::CYAN);
+  Stage::GetCurrent().Add(actor);
+
+  DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(actor.GetImplementation());
+
+  Property::Map visualMap;
+  visualMap[Visual::Property::TYPE] = Visual::COLOR;
+  visualMap[ColorVisual::Property::MIX_COLOR] = Color::MAGENTA;
+  Visual::Base visual = VisualFactory::Get().CreateVisual( visualMap );
+  visual.SetName( "visual1" );
+
+  Property::Index visualIndex = Control::CONTROL_PROPERTY_END_INDEX + 1;
+  dummyImpl.RegisterVisual( visualIndex, actor, visual );
+
+  Animation anim = dummyImpl.CreateTransition( transition );
+  DALI_TEST_CHECK( anim );
+
+  application.SendNotification();
+  application.Render(0);
+  DALI_TEST_EQUALS( actor.GetCurrentColor(), Color::MAGENTA, TEST_LOCATION);
+
+  anim.Play();
+
+  application.SendNotification();
+  application.Render(0);
+  application.Render(500);
+  application.Render(500); // Halfway thru map1 anim
+  application.SendNotification();
+  DALI_TEST_EQUALS( actor.GetCurrentColor(), (Color::MAGENTA+Color::RED)*0.5f, TEST_LOCATION);
+
+  application.Render(500); // End of map1 anim
+  application.SendNotification();
+  DALI_TEST_EQUALS( actor.GetCurrentColor(), Color::RED, TEST_LOCATION );
+  END_TEST;
+}
+
+
+int UtcDaliTransitionDataMap4P(void)
+{
+  TestApplication application;
+
+  tet_printf("Testing animation of a visual's placement actor property using bezier curve\n");
+
+  Property::Map map;
+  map["target"] = "Actor1";
+  map["property"] = "position";
+  map["initialValue"] = Vector3(0, 0, 0);
+  map["targetValue"] = Vector3(100, 100, 0);
+  map["animator"] = Property::Map()
+    .Add("alphaFunction", Vector4(0.71, -0.57, 0.42, 1.38) )
+    .Add("timePeriod", Property::Map()
+         .Add("delay", 0.0f)
+         .Add("duration", 1.0f));
+
+  Dali::Toolkit::TransitionData transition = TransitionData::New( map );
+
+  DummyControl actor = DummyControl::New();
+  actor.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS);
+  actor.SetName("Actor1");
+  Stage::GetCurrent().Add(actor);
+
+  DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(actor.GetImplementation());
+  Animation anim = dummyImpl.CreateTransition( transition );
+  DALI_TEST_CHECK( anim );
+
+  application.SendNotification();
+  application.Render(0);
+  DALI_TEST_EQUALS( actor.GetCurrentPosition(), Vector3(0,0,0), 0.001f, TEST_LOCATION);
+
+  anim.Play();
+
+  application.SendNotification();
+  application.Render(0);
+
+  application.Render(250); // 25%
+  application.SendNotification();
+  DALI_TEST_EQUALS( actor.GetCurrentPosition(), Vector3(-10,-10,0), 1.0, TEST_LOCATION); // High epsilon as we don't have exact figure for bezier curve at 50%
+
+  application.Render(250); // Halfway thru map1 anim
+  application.SendNotification();
+  DALI_TEST_EQUALS( actor.GetCurrentPosition(), Vector3(24,24,0), 1.0, TEST_LOCATION); // High epsilon as we don't have exact figure for bezier curve at 50%
+
+  application.Render(250); // End of map1 anim
+  application.SendNotification();
+  DALI_TEST_EQUALS( actor.GetCurrentPosition(), Vector3(100,100,0), 1.0, TEST_LOCATION); // High epsilon as we don't have exact figure for bezier curve
+
+  application.Render(250); // End of map1 anim
+  application.SendNotification();
+  DALI_TEST_EQUALS( actor.GetCurrentPosition(), Vector3(100,100,0), TEST_LOCATION );
+  END_TEST;
+}
+
+int UtcDaliTransitionDataMap1N(void)
+{
+  TestApplication application;
+
+  Property::Map map;
+  map["target"] = "Actor1";
+  map["property"] = "randomProperty";
+  map["initialValue"] = Color::MAGENTA;
+  map["targetValue"] = Color::RED;
+  map["animator"] = Property::Map()
+    .Add("alphaFunction", "EASE_OUT")
+    .Add("timePeriod", Property::Map()
+         .Add("delay", 0.5f)
+         .Add("duration", 1.0f));
+
+  Dali::Toolkit::TransitionData transition = TransitionData::New( map );
+
+  DummyControl actor = DummyControl::New();
+  actor.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS);
+  actor.SetName("Actor1");
+  actor.SetColor(Color::CYAN);
+  Stage::GetCurrent().Add(actor);
+
+  DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(actor.GetImplementation());
+  Animation anim = dummyImpl.CreateTransition( transition );
+  DALI_TEST_CHECK( ! anim );
+
+  CHECK_MAP_EQUALS( map, transition.GetAnimatorAt(0) );
+  END_TEST;
+}
+
+
+int UtcDaliTransitionDataMapN3(void)
+{
+  TestApplication application;
+
+  tet_printf("Testing visual lookup with no renderers\n");
+
+  Property::Map map;
+  map["target"] = "visual1";
+  map["property"] = "mixColor";
+  map["initialValue"] = Color::MAGENTA;
+  map["targetValue"] = Color::RED;
+  map["animator"] = Property::Map()
+    .Add("alphaFunction", "EASE_OUT_BACK")
+    .Add("timePeriod", Property::Map()
+         .Add("delay", 0.5f)
+         .Add("duration", 1.0f));
+
+  Dali::Toolkit::TransitionData transition = TransitionData::New( map );
+  CHECK_MAP_EQUALS( map, transition.GetAnimatorAt(0) );
+
+  DummyControl actor = DummyControl::New();
+  actor.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS);
+  actor.SetName("Actor1");
+  actor.SetColor(Color::CYAN);
+  // Don't stage actor
+
+  DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(actor.GetImplementation());
+  Property::Map visualMap;
+  visualMap[Visual::Property::TYPE] = Visual::COLOR;
+  visualMap[ColorVisual::Property::MIX_COLOR] = Color::MAGENTA;
+  Visual::Base visual = VisualFactory::Get().CreateVisual( visualMap );
+  visual.SetName( "visual1" );
+
+  Property::Index visualIndex = Control::CONTROL_PROPERTY_END_INDEX + 1;
+  dummyImpl.RegisterVisual( visualIndex, actor, visual );
+
+  Animation anim = dummyImpl.CreateTransition( transition );
+  DALI_TEST_CHECK( !anim );
+  END_TEST;
+}
+
+
+int UtcDaliTransitionDataMapN4(void)
+{
+  TestApplication application;
+
+  tet_printf("Testing visual doesn't animate with duff bezier data \n");
+
+  Property::Map map;
+  map["target"] = "visual1";
+  map["property"] = "mixColor";
+  map["initialValue"] = Color::MAGENTA;
+  map["targetValue"] = Color::RED;
+  map["animator"] = Property::Map()
+    .Add("alphaFunction", Vector3(.1f,1.0f,0.5f))
+    .Add("timePeriod", Property::Map()
+         .Add("delay", 0.5f)
+         .Add("duration", 1.0f));
+
+  Dali::Toolkit::TransitionData transition = TransitionData::New( map );
+
+  DummyControl actor = DummyControl::New();
+  actor.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS);
+  actor.SetName("Actor1");
+  actor.SetColor(Color::CYAN);
+  Stage::GetCurrent().Add(actor);
+
+  DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(actor.GetImplementation());
+  Property::Map visualMap;
+  visualMap[Visual::Property::TYPE] = Visual::COLOR;
+  visualMap[ColorVisual::Property::MIX_COLOR] = Color::MAGENTA;
+  Visual::Base visual = VisualFactory::Get().CreateVisual( visualMap );
+  visual.SetName( "visual1" );
+
+  Property::Index visualIndex = Control::CONTROL_PROPERTY_END_INDEX + 1;
+  dummyImpl.RegisterVisual( visualIndex, actor, visual );
+
+  Animation anim = dummyImpl.CreateTransition( transition );
+  DALI_TEST_CHECK( !anim );
+
+  application.SendNotification();
+  application.Render(0);
+  application.SendNotification();
+
+  Renderer renderer = actor.GetRendererAt(0);
+  Property::Index mixColorIdx = renderer.GetPropertyIndex(ColorVisual::Property::MIX_COLOR);
+
+  tet_printf( "Test that the property has been set to target value\n");
+  DALI_TEST_EQUALS(renderer.GetProperty<Vector4>(mixColorIdx), Color::RED, 0.001, TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliTransitionDataMapN5(void)
+{
+  TestApplication application;
+
+  tet_printf("Testing visual doesn't animate with duff bezier data \n");
+
+  Property::Map map;
+  map["target"] = "visual1";
+  map["property"] = "mixColor";
+  map["initialValue"] = Color::MAGENTA;
+  map["targetValue"] = Color::RED;
+  map["animator"] = Property::Map()
+    .Add("alphaFunction", Property::Array().Add(.1f).Add(1.0f).Add(0.5f))
+    .Add("timePeriod", Property::Map()
+         .Add("delay", 0.5f)
+         .Add("duration", 1.0f));
+
+  Dali::Toolkit::TransitionData transition = TransitionData::New( map );
+
+  DummyControl actor = DummyControl::New();
+  actor.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS);
+  actor.SetName("Actor1");
+  actor.SetColor(Color::CYAN);
+  Stage::GetCurrent().Add(actor);
+
+  DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(actor.GetImplementation());
+  Property::Map visualMap;
+  visualMap[Visual::Property::TYPE] = Visual::COLOR;
+  visualMap[ColorVisual::Property::MIX_COLOR] = Color::MAGENTA;
+  Visual::Base visual = VisualFactory::Get().CreateVisual( visualMap );
+  visual.SetName( "visual1" );
+
+  Property::Index visualIndex = Control::CONTROL_PROPERTY_END_INDEX + 1;
+  dummyImpl.RegisterVisual( visualIndex, actor, visual );
+
+  Animation anim = dummyImpl.CreateTransition( transition );
+  DALI_TEST_CHECK( !anim );
+
+  application.SendNotification();
+  application.Render(0);
+  application.SendNotification();
+
+  Renderer renderer = actor.GetRendererAt(0);
+  Property::Index mixColorIdx = renderer.GetPropertyIndex(ColorVisual::Property::MIX_COLOR);
+
+  tet_printf( "Test that the property has been set to target value\n");
+  DALI_TEST_EQUALS(renderer.GetProperty<Vector4>(mixColorIdx), Color::RED, 0.001, TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliTransitionDataMapN6(void)
+{
+  TestApplication application;
+
+  tet_printf("Testing visual doesn't animate with duff bezier data \n");
+
+  Property::Map map;
+  map["target"] = "visual1";
+  map["property"] = "mixColor";
+  map["initialValue"] = Color::MAGENTA;
+  map["targetValue"] = Color::RED;
+  map["animator"] = Property::Map()
+    .Add("alphaFunction", Property::Array().Add("1").Add("Two").Add("3").Add("4"))
+    .Add("timePeriod", Property::Map()
+         .Add("delay", 0.5f)
+         .Add("duration", 1.0f));
+
+  Dali::Toolkit::TransitionData transition = TransitionData::New( map );
+
+  DummyControl actor = DummyControl::New();
+  actor.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS);
+  actor.SetName("Actor1");
+  actor.SetColor(Color::CYAN);
+  Stage::GetCurrent().Add(actor);
+
+  DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(actor.GetImplementation());
+  Property::Map visualMap;
+  visualMap[Visual::Property::TYPE] = Visual::COLOR;
+  visualMap[ColorVisual::Property::MIX_COLOR] = Color::MAGENTA;
+  Visual::Base visual = VisualFactory::Get().CreateVisual( visualMap );
+  visual.SetName( "visual1" );
+
+  Property::Index visualIndex = Control::CONTROL_PROPERTY_END_INDEX + 1;
+  dummyImpl.RegisterVisual( visualIndex, actor, visual );
+
+  Animation anim = dummyImpl.CreateTransition( transition );
+  DALI_TEST_CHECK( !anim );
+
+  application.SendNotification();
+  application.Render(0);
+  application.SendNotification();
+
+  Renderer renderer = actor.GetRendererAt(0);
+  Property::Index mixColorIdx = renderer.GetPropertyIndex(ColorVisual::Property::MIX_COLOR);
+
+  tet_printf( "Test that the property has been set to target value\n");
+  DALI_TEST_EQUALS(renderer.GetProperty<Vector4>(mixColorIdx), Color::RED, 0.001, TEST_LOCATION);
+
+  END_TEST;
+}
+
+
+int UtcDaliTransitionDataArrayP(void)
+{
+  TestApplication application;
+
+  Property::Map map1;
+  map1["target"] = "Actor1";
+  map1["property"] = "color";
+  map1["initialValue"] = Color::MAGENTA;
+  map1["targetValue"] = Color::RED;
+  map1["animator"] = Property::Map()
+    .Add("alphaFunction", "EASE_IN_OUT")
+    .Add("timePeriod", Property::Map()
+         .Add("delay", 0.5f)
+         .Add("duration", 1.0f));
+
+  Property::Map map2;
+  map2["target"] = "Actor1";
+  map2["property"] = "position";
+  map2["initialValue"] = Vector3(100,0,0);
+  map2["targetValue"] = Vector3(0,100,0);
+  map2["animator"] = Property::Map()
+    .Add("alphaFunction", "EASE_IN_OUT")
+    .Add("timePeriod", Property::Map()
+         .Add("delay", 0.0f)
+         .Add("duration", 1.0f));
+
+  Property::Map map3;
+  map3["target"] = "Actor1";
+  map3["property"] = "orientation";
+  map3["targetValue"] = Quaternion( Radian(Math::PI_2), Vector3::ZAXIS );
+
+  Property::Array array;
+  array.PushBack(map1);
+  array.PushBack(map2);
+  array.PushBack(map3);
+
+  Dali::Toolkit::TransitionData transition = TransitionData::New( array );
+
+  DummyControl actor = DummyControl::New();
+  actor.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS);
+  actor.SetName("Actor1");
+  actor.SetColor(Color::CYAN);
+  Stage::GetCurrent().Add(actor);
+  DALI_TEST_EQUALS( actor.GetCurrentOrientation(), Quaternion(Radian(0), Vector3::ZAXIS), TEST_LOCATION);
+
+  DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(actor.GetImplementation());
+  Animation anim = dummyImpl.CreateTransition( transition );
+  DALI_TEST_CHECK( anim );
+  application.SendNotification();
+  application.Render(0);
+  DALI_TEST_EQUALS( actor.GetCurrentColor(), Color::MAGENTA, TEST_LOCATION);
+  DALI_TEST_EQUALS( actor.GetCurrentOrientation(), Quaternion(Radian(Math::PI_2), Vector3::ZAXIS), TEST_LOCATION);
+  anim.Play();
+
+  application.SendNotification();
+  application.Render(0);   // start map2 anim
+  application.SendNotification();
+  DALI_TEST_EQUALS( actor.GetCurrentPosition(), Vector3(100,0,0), TEST_LOCATION);
+
+  application.Render(500); // Start map1 animation, halfway thru map2 anim
+  application.SendNotification();
+  DALI_TEST_EQUALS( actor.GetCurrentPosition(), Vector3(50,50,0), TEST_LOCATION);
+
+  application.Render(500); // Halfway thru map1 anim, end of map2 anim
+  application.SendNotification();
+  DALI_TEST_EQUALS( actor.GetCurrentPosition(), Vector3(0,100,0), TEST_LOCATION);
+  DALI_TEST_EQUALS( actor.GetCurrentColor(), (Color::MAGENTA+Color::RED)*0.5f, TEST_LOCATION);
+
+  application.Render(500); // End of map1 anim
+  application.SendNotification();
+  DALI_TEST_EQUALS( actor.GetCurrentColor(), Color::RED, TEST_LOCATION );
+
+  END_TEST;
+}
+
+
+int UtcDaliTransitionDataGetAnimatorP(void)
+{
+  TestApplication application;
+
+  Property::Map map1;
+  map1["target"] = "Actor1";
+  map1["property"] = "color";
+  map1["initialValue"] = Color::MAGENTA;
+  map1["targetValue"] = Color::RED;
+  map1["animator"] = Property::Map()
+    .Add("alphaFunction", "EASE_IN_SQUARE")
+    .Add("timePeriod", Property::Map()
+         .Add("delay", 0.5f)
+         .Add("duration", 0.5f));
+
+  Property::Map map2;
+  map2["target"] = "Actor1";
+  map2["property"] = "position";
+  map2["initialValue"] = Vector3(100,0,0);
+  map2["targetValue"] = Vector3(0,100,0);
+  map2["animator"] = Property::Map()
+    .Add("alphaFunction", "EASE_OUT_SQUARE")
+    .Add("timePeriod", Property::Map()
+         .Add("delay", 0.2f)
+         .Add("duration", 2.0f));
+
+  Property::Map map3;
+  map3["target"] = "Actor1";
+  map3["property"] = "size";
+  map3["initialValue"] = Vector2(10,10);
+  map3["targetValue"] = Vector2(100,100);
+  map3["animator"] = Property::Map()
+    .Add("alphaFunction", "EASE_OUT_SINE")
+    .Add("timePeriod", Property::Map()
+         .Add("delay", 0.4f)
+         .Add("duration", 3.0f));
+
+  Property::Map map4;
+  map4["target"] = "Actor2";
+  map4["property"] = "color";
+  map4["initialValue"] = Color::BLACK;
+  map4["targetValue"] = Color::GREEN;
+  map4["animator"] = Property::Map()
+    .Add("alphaFunction", "EASE_IN_OUT_SINE")
+    .Add("timePeriod", Property::Map()
+         .Add("delay", 0.5f)
+         .Add("duration", 0.5f));
+
+  Property::Map map5;
+  map5["target"] = "Actor2";
+  map5["property"] = "position";
+  map5["initialValue"] = Vector3(100,0,0);
+  map5["targetValue"] = Vector3(0,100,0);
+  map5["animator"] = Property::Map()
+    .Add("alphaFunction", "BOUNCE")
+    .Add("timePeriod", Property::Map()
+         .Add("delay", 0.2f)
+         .Add("duration", 2.0f));
+
+  Property::Map map6;
+  map6["target"] = "Actor2";
+  map6["property"] = "size";
+  map6["initialValue"] = Vector2(10,10);
+  map6["targetValue"] = Vector2(100,100);
+  map6["animator"] = Property::Map()
+    .Add("alphaFunction", "SIN")
+    .Add("timePeriod", Property::Map()
+         .Add("delay", 0.4f)
+         .Add("duration", 3.0f));
+
+  Property::Map map7;
+  map7["target"] = "Actor4";
+  map7["property"] = "sizeModeFactor";
+  map7["initialValue"] = Vector3(1,1,1);
+  map7["targetValue"] = Vector3(2,2,2);
+  map7["animator"] = Property::Map()
+    .Add("alphaFunction", "EASE_IN_SINE")
+    .Add("timePeriod", Property::Map()
+         .Add("delay", 0.0f)
+         .Add("duration", 1.0f));
+
+  Property::Map map8;
+  map8["target"] = "Visual1";
+  map8["property"] = "colorAlpha";
+  map8["targetValue"] = 1.0f;
+  map8["animator"] = Property::Map()
+    .Add("alphaFunction", "EASE_IN")
+    .Add("timePeriod", Property::Map()
+         .Add("delay", 0.3f)
+         .Add("duration", 9.0f));
+
+  Property::Map map9;
+  map9["target"] = "Actor2";
+  map9["property"] = "scale";
+  map9["initialValue"] = Vector3(0,0,0);
+  map9["targetValue"] = Vector3(1,1,1);
+  map9["animator"] = Property::Map()
+    .Add("alphaFunction", "REVERSE")
+    .Add("timePeriod", Property::Map()
+         .Add("delay", 0.0f)
+         .Add("duration", 1.0f));
+
+  Property::Map map10;
+  map10["target"] = "Actor2";
+  map10["property"] = "scale";
+  map10["initialValue"] = Vector3(0,0,0);
+  map10["targetValue"] = Vector3(1,1,1);
+  map10["animator"] = Property::Map()
+    .Add("alphaFunction", Vector4(.23,.4,.8,1.2))
+    .Add("timePeriod", Property::Map()
+         .Add("delay", 0.0f)
+         .Add("duration", 1.0f));
+
+  Property::Map map11;
+  map11["target"] = "Actor2";
+  map11["property"] = "scale";
+  map11["initialValue"] = Vector3(0,0,0);
+  map11["targetValue"] = Vector3(1,1,1);
+  map11["animator"] = Property::Map()
+    .Add("alphaFunction", Property::Array().Add(.23f).Add(.4f).Add(.8f).Add(.2f))
+    .Add("timePeriod", Property::Map()
+         .Add("delay", 0.0f)
+         .Add("duration", 1.0f));
+
+  Property::Map map12;
+  map12["target"] = "Actor1";
+  map12["property"] = "orientation";
+  map12["targetValue"] = Quaternion( Radian(Math::PI_2), Vector3::ZAXIS );
+
+  Property::Array array;
+  array.PushBack(map1);
+  array.PushBack(map2);
+  array.PushBack(map3);
+  array.PushBack(map4);
+  array.PushBack(map5);
+  array.PushBack(map6);
+  array.PushBack(map7);
+  array.PushBack(map8);
+  array.PushBack(map9);
+  array.PushBack(map10);
+  array.PushBack(map11);
+  array.PushBack(map12);
+
+  Dali::Toolkit::TransitionData transition = TransitionData::New( array );
+
+  DALI_TEST_EQUALS( transition.Count(), array.Count(), TEST_LOCATION );
+
+  for( unsigned int i=0; i < array.Count(); ++i )
+  {
+    Property::Map animatorMap = transition.GetAnimatorAt(i);
+    Property::Value& value = array.GetElementAt(i);
+    Property::Map* inputMap = value.GetMap();
+    DALI_TEST_CHECK( inputMap );
+    CHECK_MAP_EQUALS( *inputMap, animatorMap );
+  }
+
+  END_TEST;
+}
index 6de8e23..35c224e 100644 (file)
 
 #include <iostream>
 #include <stdlib.h>
+#include <unistd.h>
+
 #include <dali-toolkit-test-suite-utils.h>
 #include <dali/public-api/rendering/renderer.h>
 #include <dali/public-api/rendering/texture-set.h>
 #include <dali/public-api/rendering/shader.h>
 #include <dali-toolkit/devel-api/visual-factory/visual-factory.h>
 #include <dali-toolkit/dali-toolkit.h>
+#include "dummy-control.h"
 
 using namespace Dali;
 using namespace Dali::Toolkit;
@@ -34,6 +37,8 @@ const char* TEST_SVG_FILE_NAME = TEST_RESOURCE_DIR "/svg1.svg";
 const char* TEST_OBJ_FILE_NAME = TEST_RESOURCE_DIR "/Cube.obj";
 const char* TEST_MTL_FILE_NAME = TEST_RESOURCE_DIR "/ToyRobot-Metal.mtl";
 const char* TEST_RESOURCE_LOCATION = TEST_RESOURCE_DIR "/";
+
+const std::string DEFAULT_FONT_DIR( "/resources/fonts" );
 }
 
 void dali_visual_startup(void)
@@ -79,6 +84,25 @@ int UtcDaliVisualCopyAndAssignment(void)
   END_TEST;
 }
 
+int UtcDaliVisualSetName01(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline( "UtcDaliVisualSetName" );
+
+  VisualFactory factory = VisualFactory::Get();
+  Property::Map propertyMap;
+  propertyMap.Insert(Visual::Property::TYPE,  Visual::COLOR);
+  propertyMap.Insert(ColorVisual::Property::MIX_COLOR,  Color::BLUE);
+  Visual::Base visual = factory.CreateVisual( propertyMap );
+
+  const char* visualName = "backgroundVisual";
+  visual.SetName( visualName );
+
+  DALI_TEST_EQUALS( visual.GetName(), visualName, TEST_LOCATION );
+
+  END_TEST;
+}
+
 int UtcDaliVisualSetGetDepthIndex(void)
 {
   ToolkitTestApplication application;
@@ -188,6 +212,12 @@ int UtcDaliVisualSize(void)
   //  </svg>
   DALI_TEST_EQUALS( naturalSize, Vector2(100.f, 100.f), TEST_LOCATION );
 
+  // svg visual with a size
+  Visual::Base svgVisual2 = factory.CreateVisual( TEST_SVG_FILE_NAME, ImageDimensions(200, 200) );
+  DALI_TEST_EQUALS( svgVisual2.GetSize(), Vector2( 200.f, 200.f ), TEST_LOCATION );
+  svgVisual2.GetNaturalSize(naturalSize);
+  DALI_TEST_EQUALS( naturalSize, Vector2(100.f, 100.f), TEST_LOCATION ); // Natural size should still be 100, 100
+
   // Batch Image visual
   propertyMap.Clear();
   propertyMap.Insert( Visual::Property::TYPE, Visual::IMAGE );
@@ -199,6 +229,31 @@ int UtcDaliVisualSize(void)
   batchImageVisual.GetNaturalSize( naturalSize );
   DALI_TEST_EQUALS( naturalSize, Vector2( 80.0f, 160.0f ), TEST_LOCATION );
 
+  // Text visual.
+
+  // Load some fonts to get the same metrics on different platforms.
+  TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
+  fontClient.SetDpi( 96u, 96u );
+
+  char* pathNamePtr = get_current_dir_name();
+  const std::string pathName( pathNamePtr );
+  free( pathNamePtr );
+
+  fontClient.GetFontId( pathName + DEFAULT_FONT_DIR + "/tizen/TizenSansRegular.ttf" );
+
+  propertyMap.Clear();
+  propertyMap.Insert( Visual::Property::TYPE, Visual::TEXT );
+  propertyMap.Insert( TextVisual::Property::ENABLE_MARKUP, true );
+  propertyMap.Insert( TextVisual::Property::TEXT, "<font family='TizenSans' size='12'>Hello world</font>" );
+  propertyMap.Insert( TextVisual::Property::MULTI_LINE, true );
+
+  Visual::Base textVisual = factory.CreateVisual( propertyMap );
+  textVisual.GetNaturalSize( naturalSize );
+  DALI_TEST_EQUALS( naturalSize, Size( 80.f, 20.f ), TEST_LOCATION );
+
+  const float height = textVisual.GetHeightForWidth( 40.f );
+  DALI_TEST_EQUALS( height, 40.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
+
   END_TEST;
 }
 
@@ -308,6 +363,10 @@ int UtcDaliVisualGetPropertyMap1(void)
   DALI_TEST_CHECK( colorValue );
   DALI_TEST_CHECK( colorValue->Get<Vector4>() == Color::CYAN );
 
+  // Test the properties. TODO: to be completed.
+  colorVisual.SetProperty( ColorVisual::Property::MIX_COLOR, Color::RED );
+  Property::Value value = colorVisual.GetProperty( ColorVisual::Property::MIX_COLOR );
+
   END_TEST;
 }
 
@@ -358,6 +417,10 @@ int UtcDaliVisualGetPropertyMap2(void)
   DALI_TEST_CHECK( colorValue );
   DALI_TEST_CHECK( colorValue->Get<float>() == 10.f );
 
+  // Test the properties. TODO: to be completed.
+  borderVisual.SetProperty( BorderVisual::Property::COLOR, Color::RED );
+  Property::Value value = borderVisual.GetProperty( BorderVisual::Property::COLOR );
+
   END_TEST;
 }
 
@@ -425,6 +488,10 @@ int UtcDaliVisualGetPropertyMap3(void)
   DALI_TEST_EQUALS( colorArray->GetElementAt(0).Get<Vector4>(), Color::RED , Math::MACHINE_EPSILON_100, TEST_LOCATION );
   DALI_TEST_EQUALS( colorArray->GetElementAt(1).Get<Vector4>(), Color::GREEN , Math::MACHINE_EPSILON_100, TEST_LOCATION );
 
+  // Test the properties. TODO: to be completed.
+  gradientVisual.SetProperty( GradientVisual::Property::STOP_COLOR, Color::RED );
+  Property::Value gradientValue = gradientVisual.GetProperty( GradientVisual::Property::STOP_COLOR );
+
   END_TEST;
 }
 
@@ -609,6 +676,10 @@ int UtcDaliVisualGetPropertyMap5(void)
   DALI_TEST_CHECK( value );
   DALI_TEST_CHECK( value->Get<bool>() == false );
 
+  // Test the properties. TODO: to be completed.
+  imageVisual.SetProperty( ImageVisual::Property::URL, TEST_IMAGE_FILE_NAME );
+  Property::Value imageValue = imageVisual.GetProperty( ImageVisual::Property::URL );
+
   END_TEST;
 }
 
@@ -640,6 +711,10 @@ int UtcDaliVisualGetPropertyMap6(void)
   DALI_TEST_CHECK( value );
   DALI_TEST_CHECK( value->Get<bool>() );
 
+  // Test the properties. TODO: to be completed.
+  nPatchVisual.SetProperty( ImageVisual::Property::URL, TEST_NPATCH_FILE_NAME );
+  Property::Value nPatchValue = nPatchVisual.GetProperty( ImageVisual::Property::URL );
+
   END_TEST;
 }
 
@@ -652,7 +727,7 @@ int UtcDaliVisualGetPropertyMap7(void)
   VisualFactory factory = VisualFactory::Get();
   Property::Map propertyMap;
   propertyMap.Insert( Visual::Property::TYPE,  Visual::IMAGE );
-  propertyMap.Insert( ImageVisual::Property::URL,  TEST_SVG_FILE_NAME );
+  propertyMap.Insert( ImageVisual::Property::URL, TEST_SVG_FILE_NAME );
   Visual::Base svgVisual = factory.CreateVisual( propertyMap );
 
   Property::Map resultMap;
@@ -679,6 +754,10 @@ int UtcDaliVisualGetPropertyMap7(void)
   DALI_TEST_CHECK( value );
   DALI_TEST_CHECK( value->Get<std::string>() == TEST_SVG_FILE_NAME );
 
+  // Test the properties. TODO: to be completed.
+  svgVisual.SetProperty( ImageVisual::Property::URL, TEST_SVG_FILE_NAME );
+  Property::Value svgValue = svgVisual.GetProperty( ImageVisual::Property::URL );
+
   END_TEST;
 }
 
@@ -727,6 +806,10 @@ int UtcDaliVisualGetPropertyMap8(void)
   DALI_TEST_CHECK( value );
   DALI_TEST_EQUALS( value->Get<Vector3>(), Vector3( 5.0f, 10.0f, 15.0f), Math::MACHINE_EPSILON_100, TEST_LOCATION );
 
+  // Test the properties. TODO: to be completed.
+  meshVisual.SetProperty( MeshVisual::Property::OBJECT_URL, TEST_OBJ_FILE_NAME );
+  Property::Value meshValue = meshVisual.GetProperty( MeshVisual::Property::OBJECT_URL );
+
   END_TEST;
 }
 
@@ -814,6 +897,10 @@ int UtcDaliVisualGetPropertyMap9(void)
   DALI_TEST_CHECK( value );
   DALI_TEST_EQUALS( value->Get<Vector3>(), Vector3( 5.0f, 10.0f, 15.0f), Math::MACHINE_EPSILON_100, TEST_LOCATION );
 
+  // Test the properties. TODO: to be completed.
+  primitiveVisual.SetProperty( PrimitiveVisual::Property::SHAPE, PrimitiveVisual::Shape::CUBE );
+  Property::Value primitiveValue = primitiveVisual.GetProperty( PrimitiveVisual::Property::SHAPE );
+
   END_TEST;
 }
 
@@ -853,6 +940,99 @@ int UtcDaliVisualGetPropertyMapBatchImageVisual(void)
   DALI_TEST_CHECK( value );
   DALI_TEST_CHECK( value->Get<int>() == 30 );
 
+  // Test the properties. TODO: to be completed.
+  batchImageVisual.SetProperty( ImageVisual::Property::URL, TEST_IMAGE_FILE_NAME );
+  Property::Value primitiveValue = batchImageVisual.GetProperty( ImageVisual::Property::URL );
+
+  END_TEST;
+}
+
+//Text shape visual
+int UtcDaliVisualGetPropertyMap10(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline( "UtcDaliVisualGetPropertyMap10: TextVisual" );
+
+  //Request PrimitiveVisual using a property map.
+  VisualFactory factory = VisualFactory::Get();
+
+  Property::Map propertyMap;
+  propertyMap.Insert( Visual::Property::TYPE, Visual::TEXT );
+  propertyMap.Insert( "renderingBackend", static_cast<int>( Toolkit::Text::DEFAULT_RENDERING_BACKEND ) );
+  propertyMap.Insert( "text", "Hello world" );
+  propertyMap.Insert( "fontFamily", "TizenSans" );
+  propertyMap.Insert( "fontStyle", "{\"weight\":\"bold\"}" );
+  propertyMap.Insert( "pointSize", 12.f );
+  propertyMap.Insert( "multiLine", true );
+  propertyMap.Insert( "horizontalAlignment", "CENTER" );
+  propertyMap.Insert( "verticalAlignment", "CENTER" );
+  propertyMap.Insert( "textColor", Color::RED );
+  propertyMap.Insert( "enableMarkup", false );
+  propertyMap.Insert( "enableAutoScroll", false );
+  propertyMap.Insert( "lineSpacing", 0.f );
+  propertyMap.Insert( "batchingEnabled", false );
+  Visual::Base textVisual = factory.CreateVisual( propertyMap );
+
+  Property::Map resultMap;
+  textVisual.CreatePropertyMap( resultMap );
+
+  //Check values in the result map are identical to the initial map's values.
+  Property::Value* value = resultMap.Find( Visual::Property::TYPE, Property::INTEGER );
+  DALI_TEST_CHECK( value );
+  DALI_TEST_EQUALS( value->Get<int>(), (int)Visual::TEXT, TEST_LOCATION );
+
+  value = resultMap.Find( TextVisual::Property::RENDERING_BACKEND, Property::INTEGER );
+  DALI_TEST_CHECK( value );
+  DALI_TEST_EQUALS( value->Get<int>(), Toolkit::Text::DEFAULT_RENDERING_BACKEND, TEST_LOCATION );
+
+  value = resultMap.Find( TextVisual::Property::TEXT, Property::STRING );
+  DALI_TEST_CHECK( value );
+  DALI_TEST_EQUALS( value->Get<std::string>(), "Hello world", TEST_LOCATION );
+
+  value = resultMap.Find( TextVisual::Property::FONT_FAMILY, Property::STRING );
+  DALI_TEST_CHECK( value );
+  DALI_TEST_EQUALS( value->Get<std::string>(), "TizenSans", TEST_LOCATION );
+
+  value = resultMap.Find( TextVisual::Property::FONT_STYLE, Property::STRING );
+  DALI_TEST_CHECK( value );
+  DALI_TEST_EQUALS( value->Get<std::string>(), "{\"weight\":\"bold\"}", TEST_LOCATION );
+
+  value = resultMap.Find( TextVisual::Property::POINT_SIZE, Property::FLOAT );
+  DALI_TEST_CHECK( value );
+  DALI_TEST_EQUALS( value->Get<float>(), 12.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
+
+  value = resultMap.Find( TextVisual::Property::MULTI_LINE, Property::BOOLEAN );
+  DALI_TEST_CHECK( value );
+  DALI_TEST_CHECK( value->Get<bool>() );
+
+  value = resultMap.Find( TextVisual::Property::HORIZONTAL_ALIGNMENT, Property::STRING );
+  DALI_TEST_CHECK( value );
+  DALI_TEST_EQUALS( value->Get<std::string>(), "CENTER", TEST_LOCATION );
+
+  value = resultMap.Find( TextVisual::Property::VERTICAL_ALIGNMENT, Property::STRING );
+  DALI_TEST_CHECK( value );
+  DALI_TEST_EQUALS( value->Get<std::string>(), "CENTER", TEST_LOCATION );
+
+  value = resultMap.Find( TextVisual::Property::TEXT_COLOR, Property::VECTOR4 );
+  DALI_TEST_CHECK( value );
+  DALI_TEST_EQUALS( value->Get<Vector4>(), Color::RED, TEST_LOCATION );
+
+  value = resultMap.Find( TextVisual::Property::ENABLE_MARKUP, Property::BOOLEAN );
+  DALI_TEST_CHECK( value );
+  DALI_TEST_CHECK( !value->Get<bool>() );
+
+  value = resultMap.Find( TextVisual::Property::ENABLE_AUTO_SCROLL, Property::BOOLEAN );
+  DALI_TEST_CHECK( value );
+  DALI_TEST_CHECK( !value->Get<bool>() );
+
+  value = resultMap.Find( TextVisual::Property::LINE_SPACING, Property::FLOAT );
+  DALI_TEST_CHECK( value );
+  DALI_TEST_EQUALS( value->Get<float>(), 0.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
+
+  value = resultMap.Find( TextVisual::Property::BATCHING_ENABLED, Property::BOOLEAN );
+  DALI_TEST_CHECK( value );
+  DALI_TEST_CHECK( !value->Get<bool>() );
+
   END_TEST;
 }
 
@@ -1088,5 +1268,9 @@ int UtcDaliVisualWireframeVisual(void)
   Property::Value* value = resultMap.Find( Visual::Property::TYPE, Property::INTEGER );
   DALI_TEST_CHECK( value );
   DALI_TEST_CHECK( value->Get<int>() == Visual::WIREFRAME );
+
+  // Test the properties. TODO: to be completed.
+  Property::Value primitiveValue = visual.GetProperty( Visual::Property::TYPE );
+
   END_TEST;
 }
index 40e37c9..3fe52b4 100644 (file)
@@ -1139,6 +1139,46 @@ int UtcDaliVisualFactoryGetSvgVisual(void)
   END_TEST;
 }
 
+int UtcDaliVisualFactoryGetSvgVisualLarge(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline( "UtcDaliVisualFactoryGetSvgVisual: Request svg visual with a svg url" );
+
+  VisualFactory factory = VisualFactory::Get();
+  Visual::Base visual = factory.CreateVisual( TEST_SVG_FILE_NAME, ImageDimensions( 2000, 2000 ) );
+  DALI_TEST_CHECK( visual );
+
+  TestGlAbstraction& gl = application.GetGlAbstraction();
+  TraceCallStack& textureTrace = gl.GetTextureTrace();
+  textureTrace.Enable(true);
+
+  Actor actor = Actor::New();
+  Stage::GetCurrent().Add( actor );
+  visual.SetOnStage( actor );
+  application.SendNotification();
+  application.Render();
+
+  // renderer is not added to actor until the rasterization is completed.
+  DALI_TEST_CHECK( actor.GetRendererCount() == 0u );
+
+  EventThreadCallback* eventTrigger = EventThreadCallback::Get();
+  CallbackBase* callback = eventTrigger->GetCallback();
+
+  eventTrigger->WaitingForTrigger( 1 );// waiting until the svg image is rasterized.
+  CallbackBase::Execute( *callback );
+
+  // renderer is added to actor
+  DALI_TEST_CHECK( actor.GetRendererCount() == 1u );
+
+  // waiting for the resource uploading
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION );
+
+  END_TEST;
+}
+
 //Creates a mesh visual from the given propertyMap and tries to load it on stage in the given application.
 //This is expected to succeed, which will then pass the test.
 void MeshVisualLoadsCorrectlyTest( Property::Map& propertyMap, ToolkitTestApplication& application )
index 4e39d12..be46ddd 100644 (file)
@@ -61,6 +61,7 @@
 #include <dali-toolkit/public-api/visuals/image-visual-properties.h>
 #include <dali-toolkit/public-api/visuals/mesh-visual-properties.h>
 #include <dali-toolkit/public-api/visuals/primitive-visual-properties.h>
+#include <dali-toolkit/public-api/visuals/text-visual-properties.h>
 #include <dali-toolkit/public-api/visuals/visual-properties.h>
 
 #include <dali-toolkit/public-api/dali-toolkit-version.h>
index 188ed1b..5bcf750 100755 (executable)
@@ -22,12 +22,14 @@ devel_api_src_files = \
   $(devel_api_src_dir)/controls/tool-bar/tool-bar.cpp \
   $(devel_api_src_dir)/focus-manager/keyinput-focus-manager.cpp \
   $(devel_api_src_dir)/image-loader/async-image-loader.cpp \
+  $(devel_api_src_dir)/image-loader/atlas-upload-observer.cpp \
   $(devel_api_src_dir)/image-loader/image-atlas.cpp \
   $(devel_api_src_dir)/scripting/script.cpp \
   $(devel_api_src_dir)/transition-effects/cube-transition-cross-effect.cpp \
   $(devel_api_src_dir)/transition-effects/cube-transition-effect.cpp \
   $(devel_api_src_dir)/transition-effects/cube-transition-fold-effect.cpp \
   $(devel_api_src_dir)/transition-effects/cube-transition-wave-effect.cpp \
+  $(devel_api_src_dir)/visual-factory/transition-data.cpp \
   $(devel_api_src_dir)/visual-factory/visual-factory.cpp \
   $(devel_api_src_dir)/visual-factory/visual-base.cpp \
   $(devel_api_src_dir)/controls/gaussian-blur-view/gaussian-blur-view.cpp
@@ -71,6 +73,7 @@ devel_api_progress_bar_header_files = \
   $(devel_api_src_dir)/controls/progress-bar/progress-bar.h
 
 devel_api_visual_factory_header_files = \
+  $(devel_api_src_dir)/visual-factory/transition-data.h \
   $(devel_api_src_dir)/visual-factory/visual-factory.h \
   $(devel_api_src_dir)/visual-factory/visual-base.h
 
@@ -82,6 +85,7 @@ devel_api_focus_manager_header_files = \
 
 devel_api_image_loader_header_files = \
   $(devel_api_src_dir)/image-loader/async-image-loader.h \
+  $(devel_api_src_dir)/image-loader/atlas-upload-observer.h \
   $(devel_api_src_dir)/image-loader/image-atlas.h
 
 devel_api_scripting_header_files = \
diff --git a/dali-toolkit/devel-api/image-loader/atlas-upload-observer.cpp b/dali-toolkit/devel-api/image-loader/atlas-upload-observer.cpp
new file mode 100644 (file)
index 0000000..f362edc
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * 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.
+ *
+ */
+
+// CLASS HEADER
+#include "atlas-upload-observer.h"
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/image-loader/image-atlas-impl.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+AtlasUploadObserver::AtlasUploadObserver()
+{}
+
+AtlasUploadObserver::~AtlasUploadObserver()
+{
+  // Notify the registerd ImageAtlas object about the destruction of observer.
+  const std::size_t size( mAtlasList.Count() );
+  for( std::size_t i = 0; i < size; ++i )
+  {
+    if( mAtlasList[i] )
+    {
+      mAtlasList[i]->ObserverDestroyed( this );
+    }
+  }
+  mAtlasList.Clear();
+}
+
+void AtlasUploadObserver::Register( Internal::ImageAtlas& imageAtlas )
+{
+  // Add to the list so that the ImageAtlas could get notified in the destructor.
+  // If the same atlas is exist in the list already, we would still save the duplicated copy.
+  mAtlasList.PushBack( &imageAtlas );
+}
+
+void AtlasUploadObserver::Unregister( Internal::ImageAtlas& imageAtlas )
+{
+  const std::size_t size( mAtlasList.Count() );
+  for( std::size_t i = 0; i < size; i++ )
+  {
+    if( mAtlasList[i] == &imageAtlas )
+    {
+      // Remove from list
+      mAtlasList.Erase( mAtlasList.Begin() + i );
+      // If there are duplicated copies of same pointer, only the first one is removed
+      return;
+    }
+  }
+}
+
+}
+
+}
diff --git a/dali-toolkit/devel-api/image-loader/atlas-upload-observer.h b/dali-toolkit/devel-api/image-loader/atlas-upload-observer.h
new file mode 100644 (file)
index 0000000..2688c1a
--- /dev/null
@@ -0,0 +1,85 @@
+#ifndef DALI_TOOLKIT_ATLAS_UPLOAD_OBSERVER_H
+#define DALI_TOOLKIT_ATLAS_UPLOAD_OBSERVER_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/public-api/common/dali-common.h>
+#include <dali/public-api/common/dali-vector.h>
+#include <dali/public-api/signals/callback.h>
+
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+class ImageAtlas;
+}
+
+/**
+ * @brief Base class used to observe the upload status of the ImageAtlas when requesting an image atlasing.
+ *
+ * Derived class should implement the UploadCompleted method which would get executed once the texture is ready.
+ */
+class DALI_IMPORT_API AtlasUploadObserver
+{
+public:
+
+  /**
+   * @brief Constructor.
+   */
+  AtlasUploadObserver();
+
+  /**
+   * @brief Virtual destructor.
+   */
+  virtual ~AtlasUploadObserver();
+
+  /**
+   * The action to be taken once the upload is completed.
+   */
+  virtual void UploadCompleted() = 0;
+
+public: // not intended for developer, called by ImageAtlas internally to get notified when this observer dies
+
+  /**
+   * @brief Register an ImageAtlas which be notified when the observer is destructing.
+   * @param[in] imageAtlas The ImageAtlas object to get notification about the destruction of the observer.
+   */
+  void Register( Internal::ImageAtlas& imageAtlas );
+
+  /**
+   * @brief Unregister an ImageAtlas which be notified when the observer is destructing.
+   * @param[in] imageAtlas The ImageAtlas object to get notification about the destruction of the observer.
+   */
+  void Unregister( Internal::ImageAtlas& imageAtlas );
+
+private:
+
+  Vector<Internal::ImageAtlas*> mAtlasList; ///< The list of the registered ImageAtlas object
+
+};
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif /* DALI_TOOLKIT_ATLAS_UPLOAD_OBSERVER_H */
index a7174d5..fd6825e 100644 (file)
@@ -80,7 +80,17 @@ bool ImageAtlas::Upload( Vector4& textureRect,
                          FittingMode::Type fittingMode,
                          bool orientationCorrection )
 {
-  return GetImplementation(*this).Upload( textureRect, url, size, fittingMode, orientationCorrection );
+  return Upload( textureRect, url, size, fittingMode, orientationCorrection, NULL );
+}
+
+bool ImageAtlas::Upload( Vector4& textureRect,
+                         const std::string& url,
+                         ImageDimensions size,
+                         FittingMode::Type fittingMode,
+                         bool orientationCorrection,
+                         AtlasUploadObserver* atlasUploadObserver )
+{
+  return GetImplementation(*this).Upload( textureRect, url, size, fittingMode, orientationCorrection, atlasUploadObserver );
 }
 
 bool ImageAtlas::Upload( Vector4& textureRect, PixelData pixelData )
index c85194f..98796bd 100644 (file)
@@ -26,6 +26,9 @@
 #include <dali/public-api/images/pixel-data.h>
 #include <dali/public-api/rendering/texture.h>
 
+// INTERNAL INCLUDES
+#include <dali-toolkit/devel-api/image-loader/atlas-upload-observer.h>
+
 namespace Dali
 {
 
@@ -114,7 +117,7 @@ public:
   /**
    * @brief Upload a resource image to the atlas.
    *
-   * @note To make the atlasing efficient, an valid size should be provided.
+   * @note To make the atlasing efficient, a valid size should be provided.
    *       If size is not provided, then the image file will be opened to read the actual size for loading.
    *       Do not set a size that is bigger than the actual image size, as the up-scaling is not available,
    *       the content of the area not covered by actual image is undefined, it will not be cleared.
@@ -135,6 +138,32 @@ public:
                bool orientationCorrection = true );
 
   /**
+   * @brief Upload a resource image to the atlas.
+   *
+   * @note To make the atlasing efficient, a valid size should be provided.
+   *       If size is not provided, then the image file will be opened to read the actual size for loading.
+   *       Do not set a size that is bigger than the actual image size, as the up-scaling is not available,
+   *       the content of the area not covered by actual image is undefined, it will not be cleared.
+   *
+   * SamplingMode::BOX_THEN_LINEAR is used to sampling pixels from the input image while fitting it to desired size.
+   *
+   * @param [out] textureRect The texture area of the resource image in the atlas.
+   * @param [in] url The URL of the resource image file to use.
+   * @param [in] size The width and height to fit the loaded image to.
+   * @param [in] fittingMode The method used to fit the shape of the image before loading to the shape defined by the size parameter.
+   * @param [in] orientationCorrection Reorient the image to respect any orientation metadata in its header.
+   * @param[in] atlasUploadObserver The observer to observe the upload state inside the ImageAtlas.
+   * @return True if there is enough space to fit this image in,false otherwise.
+   * @note The valid callback function here is required to have the signature of void( void ).
+   */
+  bool Upload( Vector4& textureRect,
+               const std::string& url,
+               ImageDimensions size,
+               FittingMode::Type fittingMode,
+               bool orientationCorrection,
+               AtlasUploadObserver* atlasUploadObserver );
+
+  /**
    * @brief Upload a pixel buffer to atlas
    *
    * @param [out] textureRect The texture area of the resource image in the atlas.
diff --git a/dali-toolkit/devel-api/visual-factory/transition-data.cpp b/dali-toolkit/devel-api/visual-factory/transition-data.cpp
new file mode 100644 (file)
index 0000000..86d6128
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * 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/devel-api/visual-factory/transition-data.h>
+#include <dali-toolkit/internal/visuals/transition-data-impl.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+
+TransitionData::TransitionData()
+{
+}
+
+TransitionData::~TransitionData()
+{
+}
+
+TransitionData TransitionData::New( const Property::Array& transition )
+{
+  Internal::TransitionDataPtr transitionData = Internal::TransitionData::New( transition );
+  return TransitionData( transitionData.Get() );
+}
+
+TransitionData TransitionData::New( const Property::Map& transition )
+{
+  Internal::TransitionDataPtr transitionData = Internal::TransitionData::New( transition );
+  return TransitionData( transitionData.Get() );
+}
+
+TransitionData TransitionData::DownCast( BaseHandle handle )
+{
+  return TransitionData( dynamic_cast<Dali::Toolkit::Internal::TransitionData*>(handle.GetObjectPtr()));
+}
+
+TransitionData::TransitionData( const TransitionData& handle )
+: BaseHandle( handle )
+{
+}
+
+TransitionData& TransitionData::operator=( const TransitionData& handle )
+{
+  BaseHandle::operator=( handle );
+  return *this;
+}
+
+size_t TransitionData::Count() const
+{
+  return GetImplementation( *this ).Count();
+}
+
+Property::Map TransitionData::GetAnimatorAt( size_t index )
+{
+  return GetImplementation( *this ).GetAnimatorAt( index );
+}
+
+TransitionData::TransitionData( Internal::TransitionData* pointer )
+: BaseHandle( pointer )
+{
+}
+
+} // namespace Toolkit
+} // namespace Dali
diff --git a/dali-toolkit/devel-api/visual-factory/transition-data.h b/dali-toolkit/devel-api/visual-factory/transition-data.h
new file mode 100644 (file)
index 0000000..23dfb2c
--- /dev/null
@@ -0,0 +1,156 @@
+#ifndef __DALI_TOOLKIT_TRANSITION_DATA_H__
+#define __DALI_TOOLKIT_TRANSITION_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.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/object/base-handle.h>
+#include <dali/public-api/animation/alpha-function.h>
+#include <dali/public-api/object/property-array.h>
+#include <dali/public-api/object/property-map.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+class TransitionData;
+}
+
+/**
+ * @brief This object translates data from a property array of maps
+ * into an array of animators.
+ *
+ * Each animator describes a named object and a named property of that object
+ * to be animated. Internally, these are translated into object instances and
+ * property indices to be animated.
+ * @see Dali::Toolkit::Internal::Control::CreateTransition()
+ *
+ * The animators can each be retrieved as a Property::Map by using Count() and
+ * GetAnimatorAt().
+ *
+ * In psuedo-JSON, the property array can be represented as follows:
+ *
+ * [
+ *   {
+ *     "target": "objectName",
+ *     "property": "propertyKey",
+ *     "initialValue": <value>,  # The property value can be one of several types
+ *     "targetValue":  <value>,
+ *     "animator": {
+ *       "alphaFunction":<easing-function>",
+ *       "timePeriod":{
+ *         "duration": 1.0,
+ *         "delay":    0.0
+ *       }
+ *     }
+ *   },
+ *   # more animators
+ * ]
+ *
+ */
+class DALI_IMPORT_API TransitionData : public BaseHandle
+{
+public:
+  /**
+   * Create an uninitialized handle
+   *
+   * @SINCE_1_2.12
+   */
+  TransitionData();
+
+  /**
+   * Destructor - non virtual
+   *
+   * @SINCE_1_2.12
+   */
+  ~TransitionData();
+
+  /**
+   * @brief Creates a TransitionData object
+   *
+   * @SINCE_1_2.12
+   * @param[in] transition The transition data to store (a single animator)
+   * @return A handle to an initialized data.
+   */
+  static TransitionData New( const Property::Map& transition );
+
+  /**
+   * @brief Creates a TransitionData object
+   *
+   * @SINCE_1_2.12
+   * @param[in] transition The transition data to store (an array of maps of animators)
+   * @return A handle to an initialized data.
+   */
+  static TransitionData New( const Property::Array& transition );
+
+  /**
+   * @brief Downcast to a TransitionData handle
+   *
+   * @SINCE_1_2.12
+   * If handle is not a TransitionData, the returned handle is left uninitialized.
+   * @param[in] handle Handle to an object
+   * @return TransitionData handle or an uninitialized handle.
+   */
+  static TransitionData DownCast( BaseHandle handle );
+
+  /**
+   * @brief Copy constructor
+   *
+   * @SINCE_1_2.12
+   * @param[in] handle Handle to an object
+   */
+  TransitionData( const TransitionData& handle );
+
+  /**
+   * @brief Assignment Operator
+   *
+   * @SINCE_1_2.12
+   * @param[in] handle Handle to an object
+   * @return A reference to this object.
+   */
+  TransitionData& operator=( const TransitionData& handle );
+
+  /**
+   * @brief returns the count of the individual property transitions
+   * stored within this handle.
+   *
+   * @SINCE_1_2.12
+   * @return The count of individual transitions
+   */
+  size_t Count() const;
+
+  /**
+   * @brief Return the animator at the given index as a property map.
+   * @param[in] index The index of the animator ( Must be less than Count() )
+   * @return A property map representing the animator
+   */
+  Property::Map GetAnimatorAt( size_t index );
+
+public: // Not intended for application developers
+
+  explicit DALI_INTERNAL TransitionData( Internal::TransitionData *impl );
+};
+
+} // namespace Toolkit
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_TRANSITION_DATA_H__
index 072ea6b..c40bc41 100644 (file)
@@ -51,6 +51,16 @@ Visual::Base::Base(Internal::Visual::Base *impl)
 {
 }
 
+void Visual::Base::SetName( const std::string& name )
+{
+  GetImplementation( *this ).SetName( name );
+}
+
+const std::string& Visual::Base::GetName()
+{
+  return GetImplementation( *this ).GetName();
+}
+
 void Visual::Base::SetSize( const Vector2& size )
 {
   GetImplementation( *this ).SetSize( size );
@@ -61,6 +71,11 @@ const Vector2& Visual::Base::GetSize() const
   return GetImplementation( *this ).GetSize();
 }
 
+float Visual::Base::GetHeightForWidth( float width ) const
+{
+  return GetImplementation( *this ).GetHeightForWidth( width );
+}
+
 void Visual::Base::GetNaturalSize(Vector2& naturalSize ) const
 {
   GetImplementation( *this ).GetNaturalSize( naturalSize );
@@ -100,6 +115,16 @@ void Visual::Base::CreatePropertyMap( Property::Map& map ) const
   GetImplementation( *this ).CreatePropertyMap( map );
 }
 
+void Visual::Base::SetProperty( Dali::Property::Index index, const Dali::Property::Value& propertyValue )
+{
+  GetImplementation( *this ).SetProperty( index, propertyValue );
+}
+
+Dali::Property::Value Visual::Base::GetProperty( Dali::Property::Index index )
+{
+  return GetImplementation( *this ).GetProperty( index );
+}
+
 } // namespace Toolkit
 
 } // namespace Dali
index 74ca640..2cbb0b7 100644 (file)
@@ -76,6 +76,22 @@ public:
   Base& operator=( const Base& handle );
 
   /**
+   * @brief Set the name of the visual
+   *
+   * Used by the styling system to animate properties
+   * @param[in] name The name to give the visual
+   */
+  void SetName( const std::string& name );
+
+  /**
+   * @brief Get the name of the visual
+   *
+   * Used by the styling system to animate properties
+   * @return The name of the visual
+   */
+  const std::string& GetName();
+
+  /**
    * @brief Set the size of the painting area.
    *
    * @param[in] size The size of the painting area.
@@ -90,6 +106,15 @@ public:
   const Vector2& GetSize() const;
 
   /**
+   * @brief Returns the height for a given width.
+   *
+   * @param[in] width Width to use.
+   *
+   * @return The height based on the width.
+   */
+  float GetHeightForWidth( float width ) const;
+
+  /**
    * @brief Return the natural size of the visual.
    *
    * Deriving classes stipulate the natural size and by default a visual has a ZERO natural size.
@@ -150,6 +175,23 @@ public:
    */
   void CreatePropertyMap( Dali::Property::Map& map ) const;
 
+  /**
+   * @brief Sets the value of an existing property.
+   *
+   * @param [in] index The index of the property.
+   * @param [in] propertyValue The new value of the property.
+   */
+  void SetProperty( Dali::Property::Index index, const Dali::Property::Value& propertyValue );
+
+  /**
+   * @brief Retrieves a property value.
+   *
+   * @param [in] index The index of the property.
+   *
+   * @return The property value.
+   */
+  Dali::Property::Value GetProperty( Dali::Property::Index index );
+
 public: // Not intended for application developers
 
   explicit DALI_INTERNAL Base(Internal::Visual::Base *impl);
index 446a014..07240be 100644 (file)
@@ -583,4 +583,3 @@ bool Replacement::IsArray( OptionalChild child, Property::Value& out ) const
 } // namespace Toolkit
 
 } // namespace Dali
-
index ddcb8d5..9d59568 100644 (file)
@@ -933,7 +933,7 @@ void TextEditor::OnInitialize()
 {
   Actor self = Self();
 
-  mController = Text::Controller::New( *this );
+  mController = Text::Controller::New( this, this );
 
   mDecorator = Text::Decorator::New( *mController,
                                      *mController );
@@ -949,6 +949,7 @@ void TextEditor::OnInitialize()
   // Disables the horizontal scrolling.
   mController->SetHorizontalScrollEnabled( false );
 
+  // Sets the maximum number of characters.
   mController->SetMaximumNumberOfCharacters( std::numeric_limits<Length>::max() );
 
   // Enable the smooth handle panning.
@@ -1042,7 +1043,7 @@ void TextEditor::OnRelayout( const Vector2& size, RelayoutContainer& container )
       mRenderer = Backend::Get().NewRenderer( mRenderingBackend );
     }
 
-    EnableClipping( true, size );
+    EnableClipping( size );
     RenderText( updateTextType );
   }
 
@@ -1235,21 +1236,6 @@ bool TextEditor::OnKeyEvent( const KeyEvent& event )
   return mController->KeyEvent( event );
 }
 
-void TextEditor::AddDecoration( Actor& actor, bool needsClipping )
-{
-  if( actor )
-  {
-    if( needsClipping )
-    {
-      mClippingDecorationActors.push_back( actor );
-    }
-    else
-    {
-      Self().Add( actor );
-    }
-  }
-}
-
 void TextEditor::RequestTextRelayout()
 {
   RelayoutRequest();
@@ -1261,6 +1247,11 @@ void TextEditor::TextChanged()
   mTextChangedSignal.Emit( handle );
 }
 
+void TextEditor::MaxLengthReached()
+{
+  // Nothing to do as TextEditor doesn't emit a max length reached signal.
+}
+
 void TextEditor::InputStyleChanged( Text::InputStyle::Mask inputStyleMask )
 {
   Dali::Toolkit::TextEditor handle( GetOwner() );
@@ -1315,9 +1306,19 @@ void TextEditor::InputStyleChanged( Text::InputStyle::Mask inputStyleMask )
   mInputStyleChangedSignal.Emit( handle, editorInputStyleMask );
 }
 
-void TextEditor::MaxLengthReached()
+void TextEditor::AddDecoration( Actor& actor, bool needsClipping )
 {
-  // Nothing to do as TextEditor doesn't emit a max length reached signal.
+  if( actor )
+  {
+    if( needsClipping )
+    {
+      mClippingDecorationActors.push_back( actor );
+    }
+    else
+    {
+      Self().Add( actor );
+    }
+  }
 }
 
 void TextEditor::OnStageConnect( Dali::Actor actor )
@@ -1353,31 +1354,23 @@ void TextEditor::GetHandleImagePropertyValue(  Property::Value& value, Text::Han
   }
 }
 
-void TextEditor::EnableClipping( bool clipping, const Vector2& size )
+void TextEditor::EnableClipping( const Vector2& size )
 {
-  if( clipping )
+  // Not worth to created clip actor if width or height is equal to zero.
+  if( size.width > Math::MACHINE_EPSILON_1000 && size.height > Math::MACHINE_EPSILON_1000 )
   {
-    // Not worth to created clip actor if width or height is equal to zero.
-    if( size.width > Math::MACHINE_EPSILON_1000 && size.height > Math::MACHINE_EPSILON_1000 )
+    if( !mClipper )
     {
-      if( !mClipper )
-      {
-        Actor self = Self();
+      Actor self = Self();
 
-        mClipper = Clipper::New( size );
-        self.Add( mClipper->GetRootActor() );
-        self.Add( mClipper->GetImageView() );
-      }
-      else if ( mClipper )
-      {
-        mClipper->Refresh( size );
-      }
+      mClipper = Clipper::New( size );
+      self.Add( mClipper->GetRootActor() );
+      self.Add( mClipper->GetImageView() );
+    }
+    else if ( mClipper )
+    {
+      mClipper->Refresh( size );
     }
-  }
-  else
-  {
-    // Note - this will automatically remove the root actor & the image view
-    mClipper.Reset();
   }
 }
 
index cb40406..2d7190b 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __DALI_TOOLKIT_INTERNAL_TEXT_EDITOR_H__
-#define __DALI_TOOLKIT_INTERNAL_TEXT_EDITOR_H__
+#ifndef DALI_TOOLKIT_INTERNAL_TEXT_EDITOR_H
+#define DALI_TOOLKIT_INTERNAL_TEXT_EDITOR_H
 
 /*
  * Copyright (c) 2016 Samsung Electronics Co., Ltd.
  *
  */
 
+// EXTERNAL INCLUDES
+#include <dali/devel-api/adaptor-framework/clipboard-event-notifier.h>
+
 // INTERNAL INCLUDES
 #include <dali-toolkit/public-api/controls/control-impl.h>
 #include <dali-toolkit/public-api/controls/text-controls/text-editor.h>
 #include <dali-toolkit/internal/text/clipping/text-clipper.h>
 #include <dali-toolkit/internal/text/decorator/text-decorator.h>
 #include <dali-toolkit/internal/text/text-control-interface.h>
+#include <dali-toolkit/internal/text/text-editable-control-interface.h>
 #include <dali-toolkit/internal/text/text-controller.h>
 #include <dali-toolkit/internal/text/rendering/text-renderer.h>
 
-// EXTERNAL INCLUDES
-#include <dali/devel-api/adaptor-framework/clipboard-event-notifier.h>
-
 namespace Dali
 {
 
@@ -42,7 +43,7 @@ namespace Internal
 /**
  * @brief A control which renders a long text string with styles.
  */
-class TextEditor : public Control, public Text::ControlInterface
+class TextEditor : public Control, public Text::ControlInterface, public Text::EditableControlInterface
 {
 public:
 
@@ -157,15 +158,12 @@ private: // From Control
 // From ControlInterface
 
   /**
-   * @copydoc Text::ControlInterface::AddDecoration()
-   */
-  virtual void AddDecoration( Actor& actor, bool needsClipping );
-
-  /**
    * @copydoc Text::ControlInterface::RequestTextRelayout()
    */
   virtual void RequestTextRelayout();
 
+// From EditableControlInterface
+
   /**
    * @copydoc Text::ControlInterface::TextChanged()
    */
@@ -181,6 +179,11 @@ private: // From Control
    */
   virtual void InputStyleChanged( Text::InputStyle::Mask inputStyleMask );
 
+  /**
+   * @copydoc Text::ControlInterface::AddDecoration()
+   */
+  virtual void AddDecoration( Actor& actor, bool needsClipping );
+
 private: // Implementation
 
   /**
@@ -205,10 +208,9 @@ private: // Implementation
   /**
    * @brief Enable or disable clipping.
    *
-   * @param[in] clipping True if clipping should be enabled.
    * @param[in] size The area to clip within.
    */
-  void EnableClipping( bool clipping, const Vector2& size );
+  void EnableClipping( const Vector2& size );
 
   /**
    * @brief Callback when keyboard is shown/hidden.
@@ -299,4 +301,4 @@ inline const Toolkit::Internal::TextEditor& GetImpl( const Toolkit::TextEditor&
 
 } // namespace Dali
 
-#endif // __DALI_TOOLKIT_INTERNAL_TEXT_EDITOR_H__
+#endif // DALI_TOOLKIT_INTERNAL_TEXT_EDITOR_H
index e0d75ce..6e679e3 100644 (file)
@@ -1114,7 +1114,7 @@ void TextField::OnInitialize()
 {
   Actor self = Self();
 
-  mController = Text::Controller::New( *this );
+  mController = Text::Controller::New( this, this );
 
   // When using the vector-based rendering, the size of the GLyphs are different
   TextAbstraction::GlyphType glyphType = (Text::RENDERING_VECTOR_BASED == mRenderingBackend) ? TextAbstraction::VECTOR_GLYPH : TextAbstraction::BITMAP_GLYPH;
@@ -1222,7 +1222,7 @@ void TextField::OnRelayout( const Vector2& size, RelayoutContainer& container )
       mRenderer = Backend::Get().NewRenderer( mRenderingBackend );
     }
 
-    EnableClipping( ( Dali::Toolkit::TextField::EXCEED_POLICY_CLIP == mExceedPolicy ), size );
+    EnableClipping( size );
     RenderText( updateTextType );
   }
 
@@ -1246,7 +1246,7 @@ void TextField::OnRelayout( const Vector2& size, RelayoutContainer& container )
   }
 }
 
-  void TextField::RenderText( Text::Controller::UpdateTextType updateTextType )
+void TextField::RenderText( Text::Controller::UpdateTextType updateTextType )
 {
   Actor self = Self();
   Actor renderableActor;
@@ -1416,21 +1416,6 @@ bool TextField::OnKeyEvent( const KeyEvent& event )
   return mController->KeyEvent( event );
 }
 
-void TextField::AddDecoration( Actor& actor, bool needsClipping )
-{
-  if( actor )
-  {
-    if( needsClipping )
-    {
-      mClippingDecorationActors.push_back( actor );
-    }
-    else
-    {
-      Self().Add( actor );
-    }
-  }
-}
-
 void TextField::RequestTextRelayout()
 {
   RelayoutRequest();
@@ -1442,6 +1427,12 @@ void TextField::TextChanged()
   mTextChangedSignal.Emit( handle );
 }
 
+void TextField::MaxLengthReached()
+{
+  Dali::Toolkit::TextField handle( GetOwner() );
+  mMaxLengthReachedSignal.Emit( handle );
+}
+
 void TextField::InputStyleChanged( Text::InputStyle::Mask inputStyleMask )
 {
   Dali::Toolkit::TextField handle( GetOwner() );
@@ -1492,6 +1483,21 @@ void TextField::InputStyleChanged( Text::InputStyle::Mask inputStyleMask )
   mInputStyleChangedSignal.Emit( handle, fieldInputStyleMask );
 }
 
+void TextField::AddDecoration( Actor& actor, bool needsClipping )
+{
+  if( actor )
+  {
+    if( needsClipping )
+    {
+      mClippingDecorationActors.push_back( actor );
+    }
+    else
+    {
+      Self().Add( actor );
+    }
+  }
+}
+
 void TextField::OnStageConnect( Dali::Actor actor )
 {
   if ( mHasBeenStaged )
@@ -1504,12 +1510,6 @@ void TextField::OnStageConnect( Dali::Actor actor )
   }
 }
 
-void TextField::MaxLengthReached()
-{
-  Dali::Toolkit::TextField handle( GetOwner() );
-  mMaxLengthReachedSignal.Emit( handle );
-}
-
 ImfManager::ImfCallbackData TextField::OnImfEvent( Dali::ImfManager& imfManager, const ImfManager::ImfEventData& imfEvent )
 {
   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField::OnImfEvent %p eventName %d\n", mController.Get(), imfEvent.eventName );
@@ -1531,9 +1531,9 @@ void TextField::GetHandleImagePropertyValue(  Property::Value& value, Text::Hand
   }
 }
 
-void TextField::EnableClipping( bool clipping, const Vector2& size )
+void TextField::EnableClipping( const Vector2& size )
 {
-  if( clipping )
+  if( Dali::Toolkit::TextField::EXCEED_POLICY_CLIP == mExceedPolicy )
   {
     // Not worth to created clip actor if width or height is equal to zero.
     if( size.width > Math::MACHINE_EPSILON_1000 && size.height > Math::MACHINE_EPSILON_1000 )
index 558cced..e40c647 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __DALI_TOOLKIT_INTERNAL_TEXT_FIELD_H__
-#define __DALI_TOOLKIT_INTERNAL_TEXT_FIELD_H__
+#ifndef DALI_TOOLKIT_INTERNAL_TEXT_FIELD_H
+#define DALI_TOOLKIT_INTERNAL_TEXT_FIELD_H
 
 /*
  * Copyright (c) 2016 Samsung Electronics Co., Ltd.
  *
  */
 
+// EXTERNAL INCLUDES
+#include <dali/devel-api/adaptor-framework/clipboard-event-notifier.h>
+
 // INTERNAL INCLUDES
 #include <dali-toolkit/public-api/controls/control-impl.h>
 #include <dali-toolkit/public-api/controls/text-controls/text-field.h>
 #include <dali-toolkit/internal/text/clipping/text-clipper.h>
 #include <dali-toolkit/internal/text/decorator/text-decorator.h>
 #include <dali-toolkit/internal/text/text-control-interface.h>
+#include <dali-toolkit/internal/text/text-editable-control-interface.h>
 #include <dali-toolkit/internal/text/text-controller.h>
 #include <dali-toolkit/internal/text/rendering/text-renderer.h>
 
-// EXTERNAL INCLUDES
-#include <dali/devel-api/adaptor-framework/clipboard-event-notifier.h>
-
 namespace Dali
 {
 
@@ -42,7 +43,7 @@ namespace Internal
 /**
  * @brief A control which renders a short text string.
  */
-class TextField : public Control, public Text::ControlInterface
+class TextField : public Control, public Text::ControlInterface, public Text::EditableControlInterface
 {
 public:
 
@@ -162,15 +163,12 @@ private: // From Control
 // From ControlInterface
 
   /**
-   * @copydoc Text::ControlInterface::AddDecoration()
-   */
-  virtual void AddDecoration( Actor& actor, bool needsClipping );
-
-  /**
    * @copydoc Text::ControlInterface::RequestTextRelayout()
    */
   virtual void RequestTextRelayout();
 
+// From EditableControlInterface
+
   /**
    * @copydoc Text::ControlInterface::TextChanged()
    */
@@ -186,6 +184,11 @@ private: // From Control
    */
   virtual void InputStyleChanged( Text::InputStyle::Mask inputStyleMask );
 
+  /**
+   * @copydoc Text::ControlInterface::AddDecoration()
+   */
+  virtual void AddDecoration( Actor& actor, bool needsClipping );
+
 private: // Implementation
 
   /**
@@ -210,10 +213,9 @@ private: // Implementation
   /**
    * @brief Enable or disable clipping.
    *
-   * @param[in] clipping True if clipping should be enabled.
    * @param[in] size The area to clip within.
    */
-  void EnableClipping( bool clipping, const Vector2& size );
+  void EnableClipping( const Vector2& size );
 
   /**
    * @brief Callback when keyboard is shown/hidden.
@@ -306,4 +308,4 @@ inline const Toolkit::Internal::TextField& GetImpl( const Toolkit::TextField& te
 
 } // namespace Dali
 
-#endif // __DALI_TOOLKIT_INTERNAL_TEXT_FIELD_H__
+#endif // DALI_TOOLKIT_INTERNAL_TEXT_FIELD_H
index bf8c866..955e0f2 100644 (file)
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/public-api/text/rendering-backend.h>
-#include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
-#include <dali-toolkit/internal/text/property-string-parser.h>
-#include <dali-toolkit/internal/text/rendering/text-backend.h>
+#include <dali-toolkit/public-api/visuals/text-visual-properties.h>
 #include <dali-toolkit/internal/text/text-effects-style.h>
-#include <dali-toolkit/internal/text/text-font-style.h>
-#include <dali-toolkit/internal/text/text-view.h>
-#include <dali-toolkit/internal/text/text-definitions.h>
 #include <dali-toolkit/internal/styling/style-manager-impl.h>
 
 using Dali::Toolkit::Text::LayoutEngine;
-using Dali::Toolkit::Text::Backend;
 
 namespace Dali
 {
@@ -57,22 +51,6 @@ namespace
   Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, true, "LOG_TEXT_CONTROLS");
 #endif
 
-const Scripting::StringEnum HORIZONTAL_ALIGNMENT_STRING_TABLE[] =
-{
-  { "BEGIN",  Toolkit::Text::LayoutEngine::HORIZONTAL_ALIGN_BEGIN  },
-  { "CENTER", Toolkit::Text::LayoutEngine::HORIZONTAL_ALIGN_CENTER },
-  { "END",    Toolkit::Text::LayoutEngine::HORIZONTAL_ALIGN_END    },
-};
-const unsigned int HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT = sizeof( HORIZONTAL_ALIGNMENT_STRING_TABLE ) / sizeof( HORIZONTAL_ALIGNMENT_STRING_TABLE[0] );
-
-const Scripting::StringEnum VERTICAL_ALIGNMENT_STRING_TABLE[] =
-{
-  { "TOP",    Toolkit::Text::LayoutEngine::VERTICAL_ALIGN_TOP    },
-  { "CENTER", Toolkit::Text::LayoutEngine::VERTICAL_ALIGN_CENTER },
-  { "BOTTOM", Toolkit::Text::LayoutEngine::VERTICAL_ALIGN_BOTTOM },
-};
-const unsigned int VERTICAL_ALIGNMENT_STRING_TABLE_COUNT = sizeof( VERTICAL_ALIGNMENT_STRING_TABLE ) / sizeof( VERTICAL_ALIGNMENT_STRING_TABLE[0] );
-
 // Type registration
 BaseHandle Create()
 {
@@ -109,7 +87,33 @@ DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "outline",              STRING,
 
 DALI_TYPE_REGISTRATION_END()
 
-
+const int TEXT_VISUAL_PROPERTY_TABLE[] = {
+  Dali::Toolkit::TextVisual::Property::RENDERING_BACKEND,
+  Dali::Toolkit::TextVisual::Property::TEXT,
+  Dali::Toolkit::TextVisual::Property::FONT_FAMILY,
+  Dali::Toolkit::TextVisual::Property::FONT_STYLE,
+  Dali::Toolkit::TextVisual::Property::POINT_SIZE,
+  Dali::Toolkit::TextVisual::Property::MULTI_LINE,
+  Dali::Toolkit::TextVisual::Property::HORIZONTAL_ALIGNMENT,
+  Dali::Toolkit::TextVisual::Property::VERTICAL_ALIGNMENT,
+  Dali::Toolkit::TextVisual::Property::TEXT_COLOR,
+  Dali::Toolkit::TextVisual::Property::SHADOW,
+  Dali::Toolkit::TextVisual::Property::SHADOW,
+  Dali::Toolkit::TextVisual::Property::UNDERLINE,
+  Dali::Toolkit::TextVisual::Property::UNDERLINE,
+  Dali::Toolkit::TextVisual::Property::UNDERLINE,
+  Dali::Toolkit::TextVisual::Property::ENABLE_MARKUP,
+  Dali::Toolkit::TextVisual::Property::ENABLE_AUTO_SCROLL,
+  Dali::Toolkit::TextVisual::Property::AUTO_SCROLL_SPEED,
+  Dali::Toolkit::TextVisual::Property::AUTO_SCROLL_LOOP_COUNT,
+  Dali::Toolkit::TextVisual::Property::AUTO_SCROLL_GAP,
+  Dali::Toolkit::TextVisual::Property::LINE_SPACING,
+  Dali::Toolkit::TextVisual::Property::UNDERLINE,
+  Dali::Toolkit::TextVisual::Property::SHADOW,
+  Dali::Toolkit::TextVisual::Property::EMBOSS,
+  Dali::Toolkit::TextVisual::Property::OUTLINE,
+  Dali::Toolkit::TextVisual::Property::BATCHING_ENABLED
+};
 
 } // namespace
 
@@ -134,298 +138,10 @@ void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Pr
 
   if( label )
   {
-    TextLabel& impl( GetImpl( label ) );
-    switch( index )
-    {
-      case Toolkit::TextLabel::Property::RENDERING_BACKEND:
-      {
-        int backend = value.Get< int >();
-
-#ifndef ENABLE_VECTOR_BASED_TEXT_RENDERING
-        if( Text::RENDERING_VECTOR_BASED == backend )
-        {
-          backend = TextAbstraction::BITMAP_GLYPH; // Fallback to bitmap-based rendering
-        }
-#endif
-        if( impl.mRenderingBackend != backend )
-        {
-          impl.mRenderingBackend = backend;
-          impl.mRenderer.Reset();
-
-          if( impl.mController )
-          {
-            // When using the vector-based rendering, the size of the GLyphs are different
-            TextAbstraction::GlyphType glyphType = (Text::RENDERING_VECTOR_BASED == impl.mRenderingBackend) ? TextAbstraction::VECTOR_GLYPH : TextAbstraction::BITMAP_GLYPH;
-            impl.mController->SetGlyphType( glyphType );
-          }
-        }
-        break;
-      }
-      case Toolkit::TextLabel::Property::TEXT:
-      {
-        if( impl.mController )
-        {
-          impl.mController->SetText( value.Get< std::string >() );
-        }
-        break;
-      }
-      case Toolkit::TextLabel::Property::FONT_FAMILY:
-      {
-        if( impl.mController )
-        {
-          const std::string fontFamily = value.Get< std::string >();
-
-          DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextLabel::SetProperty Property::FONT_FAMILY newFont(%s)\n", fontFamily.c_str() );
-          impl.mController->SetDefaultFontFamily( fontFamily );
-        }
-        break;
-      }
-      case Toolkit::TextLabel::Property::FONT_STYLE:
-      {
-        SetFontStyleProperty( impl.mController, value, Text::FontStyle::DEFAULT );
-        break;
-      }
-      case Toolkit::TextLabel::Property::POINT_SIZE:
-      {
-        if( impl.mController )
-        {
-          const float pointSize = value.Get< float >();
-
-          if( !Equals( impl.mController->GetDefaultPointSize(), pointSize ) )
-          {
-            impl.mController->SetDefaultPointSize( pointSize );
-          }
-        }
-        break;
-      }
-      case Toolkit::TextLabel::Property::MULTI_LINE:
-      {
-        if( impl.mController )
-        {
-          impl.mController->SetMultiLineEnabled( value.Get< bool >() );
-        }
-        break;
-      }
-      case Toolkit::TextLabel::Property::HORIZONTAL_ALIGNMENT:
-      {
-        if( impl.mController )
-        {
-          LayoutEngine::HorizontalAlignment alignment( LayoutEngine::HORIZONTAL_ALIGN_BEGIN );
-          if( Scripting::GetEnumeration< Toolkit::Text::LayoutEngine::HorizontalAlignment >( value.Get< std::string >().c_str(),
-                                                                                             HORIZONTAL_ALIGNMENT_STRING_TABLE,
-                                                                                             HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT,
-                                                                                             alignment ) )
-          {
-            impl.mController->SetHorizontalAlignment( alignment );
-          }
-        }
-        break;
-      }
-      case Toolkit::TextLabel::Property::VERTICAL_ALIGNMENT:
-      {
-        if( impl.mController )
-        {
-          LayoutEngine::VerticalAlignment alignment( LayoutEngine::VERTICAL_ALIGN_BOTTOM );
-          if( Scripting::GetEnumeration< Toolkit::Text::LayoutEngine::VerticalAlignment >( value.Get< std::string >().c_str(),
-                                                                                           VERTICAL_ALIGNMENT_STRING_TABLE,
-                                                                                           VERTICAL_ALIGNMENT_STRING_TABLE_COUNT,
-                                                                                           alignment ) )
-          {
-            impl.mController->SetVerticalAlignment( alignment );
-          }
-        }
-        break;
-      }
-
-      case Toolkit::TextLabel::Property::TEXT_COLOR:
-      {
-        if( impl.mController )
-        {
-          const Vector4 textColor = value.Get< Vector4 >();
-          if( impl.mController->GetTextColor() != textColor )
-          {
-            impl.mController->SetTextColor( textColor );
-            impl.mRenderer.Reset();
-          }
-        }
-        break;
-      }
-
-      case Toolkit::TextLabel::Property::SHADOW_OFFSET:
-      {
-        if( impl.mController )
-        {
-          const Vector2 shadowOffset = value.Get< Vector2 >();
-          if ( impl.mController->GetShadowOffset() != shadowOffset )
-          {
-            impl.mController->SetShadowOffset( shadowOffset );
-            impl.mRenderer.Reset();
-          }
-        }
-        break;
-      }
-      case Toolkit::TextLabel::Property::SHADOW_COLOR:
-      {
-        if( impl.mController )
-        {
-          const Vector4 shadowColor = value.Get< Vector4 >();
-          if ( impl.mController->GetShadowColor() != shadowColor )
-          {
-            impl.mController->SetShadowColor( shadowColor );
-            impl.mRenderer.Reset();
-          }
-        }
-        break;
-      }
-      case Toolkit::TextLabel::Property::UNDERLINE_COLOR:
-      {
-        if( impl.mController )
-        {
-          const Vector4 color = value.Get< Vector4 >();
-          if ( impl.mController->GetUnderlineColor() != color )
-          {
-            impl.mController->SetUnderlineColor( color );
-            impl.mRenderer.Reset();
-          }
-        }
-        break;
-      }
-      case Toolkit::TextLabel::Property::UNDERLINE_ENABLED:
-      {
-        if( impl.mController )
-        {
-          const bool enabled = value.Get< bool >();
-          if ( impl.mController->IsUnderlineEnabled() != enabled )
-          {
-            impl.mController->SetUnderlineEnabled( enabled );
-            impl.mRenderer.Reset();
-          }
-        }
-        break;
-      }
+    TextLabel& impl = GetImpl( label );
 
-      case Toolkit::TextLabel::Property::UNDERLINE_HEIGHT:
-      {
-        if( impl.mController )
-        {
-          float height = value.Get< float >();
-          if( fabsf( impl.mController->GetUnderlineHeight() - height ) > Math::MACHINE_EPSILON_1000 )
-          {
-            impl.mController->SetUnderlineHeight( height );
-            impl.mRenderer.Reset();
-          }
-        }
-        break;
-      }
-      case Toolkit::TextLabel::Property::ENABLE_MARKUP:
-      {
-        if( impl.mController )
-        {
-          const bool enableMarkup = value.Get<bool>();
-          impl.mController->SetMarkupProcessorEnabled( enableMarkup );
-        }
-        break;
-      }
-      case Toolkit::TextLabel::Property::ENABLE_AUTO_SCROLL:
-      {
-        if( impl.mController )
-        {
-          const bool enableAutoScroll = value.Get<bool>();
-          // If request to auto scroll is the same as current state then do nothing.
-          if ( enableAutoScroll != impl.mController->IsAutoScrollEnabled() )
-          {
-             // If request is disable (false) and auto scrolling is enabled then need to stop it
-             if ( enableAutoScroll == false )
-             {
-               if( impl.mTextScroller )
-               {
-                 impl.mTextScroller->SetLoopCount( 0 ); // Causes the current animation to finish playing (0)
-               }
-             }
-             // If request is enable (true) then start autoscroll as not already running
-             else
-             {
-               impl.mController->GetLayoutEngine().SetTextEllipsisEnabled( false );
-               impl.mController->SetAutoScrollEnabled( enableAutoScroll );
-             }
-          }
-        }
-        break;
-      }
-      case Toolkit::TextLabel::Property::AUTO_SCROLL_SPEED:
-      {
-        if( !impl.mTextScroller )
-        {
-          impl.mTextScroller = Text::TextScroller::New( impl );
-        }
-        impl.mTextScroller->SetSpeed( value.Get<int>() );
-        break;
-      }
-      case Toolkit::TextLabel::Property::AUTO_SCROLL_LOOP_COUNT:
-      {
-        if( !impl.mTextScroller )
-        {
-          impl.mTextScroller = Text::TextScroller::New( impl );
-        }
-        impl.mTextScroller->SetLoopCount( value.Get<int>() );
-        break;
-      }
-      case Toolkit::TextLabel::Property::AUTO_SCROLL_GAP:
-      {
-        if( !impl.mTextScroller )
-        {
-          impl.mTextScroller = Text::TextScroller::New( impl );
-        }
-        impl.mTextScroller->SetGap( value.Get<float>() );
-        break;
-      }
-      case Toolkit::TextLabel::Property::LINE_SPACING:
-      {
-        if( impl.mController )
-        {
-          const float lineSpacing = value.Get<float>();
-          impl.mController->SetDefaultLineSpacing( lineSpacing );
-          impl.mRenderer.Reset();
-        }
-        break;
-      }
-      case Toolkit::TextLabel::Property::UNDERLINE:
-      {
-        const bool update = SetUnderlineProperties( impl.mController, value, Text::EffectStyle::DEFAULT );
-        if( update )
-        {
-          impl.mRenderer.Reset();
-        }
-        break;
-      }
-      case Toolkit::TextLabel::Property::SHADOW:
-      {
-        const bool update = SetShadowProperties( impl.mController, value, Text::EffectStyle::DEFAULT );
-        if( update )
-        {
-          impl.mRenderer.Reset();
-        }
-        break;
-      }
-      case Toolkit::TextLabel::Property::EMBOSS:
-      {
-        const bool update = SetEmbossProperties( impl.mController, value, Text::EffectStyle::DEFAULT );
-        if( update )
-        {
-          impl.mRenderer.Reset();
-        }
-        break;
-      }
-      case Toolkit::TextLabel::Property::OUTLINE:
-      {
-        const bool update = SetOutlineProperties( impl.mController, value, Text::EffectStyle::DEFAULT );
-        if( update )
-        {
-          impl.mRenderer.Reset();
-        }
-        break;
-      }
-    }
+    // Sets the property to the to the text visual.
+    impl.mVisual.SetProperty( TEXT_VISUAL_PROPERTY_TABLE[index - Toolkit::TextLabel::PROPERTY_START_INDEX], value );
   }
 }
 
@@ -437,204 +153,127 @@ Property::Value TextLabel::GetProperty( BaseObject* object, Property::Index inde
 
   if( label )
   {
-    TextLabel& impl( GetImpl( label ) );
-    switch( index )
+    TextLabel& impl = GetImpl( label );
+
+    if( ( Toolkit::TextLabel::Property::SHADOW_OFFSET == index ) ||
+        ( Toolkit::TextLabel::Property::SHADOW_COLOR == index ) ||
+        ( Toolkit::TextLabel::Property::UNDERLINE_ENABLED == index ) ||
+        ( Toolkit::TextLabel::Property::UNDERLINE_COLOR == index ) ||
+        ( Toolkit::TextLabel::Property::UNDERLINE_HEIGHT == index ) )
     {
-      case Toolkit::TextLabel::Property::RENDERING_BACKEND:
-      {
-        value = impl.mRenderingBackend;
-        break;
-      }
-      case Toolkit::TextLabel::Property::TEXT:
-      {
-        if( impl.mController )
-        {
-          std::string text;
-          impl.mController->GetText( text );
-          value = text;
-        }
-        break;
-      }
-      case Toolkit::TextLabel::Property::FONT_FAMILY:
-      {
-        if( impl.mController )
-        {
-          value = impl.mController->GetDefaultFontFamily();
-        }
-        break;
-      }
-      case Toolkit::TextLabel::Property::FONT_STYLE:
-      {
-        GetFontStyleProperty( impl.mController, value, Text::FontStyle::DEFAULT );
-        break;
-      }
-      case Toolkit::TextLabel::Property::POINT_SIZE:
-      {
-        if( impl.mController )
-        {
-          value = impl.mController->GetDefaultPointSize();
-        }
-        break;
-      }
-      case Toolkit::TextLabel::Property::MULTI_LINE:
-      {
-        if( impl.mController )
-        {
-          value = impl.mController->IsMultiLineEnabled();
-        }
-        break;
-      }
-      case Toolkit::TextLabel::Property::HORIZONTAL_ALIGNMENT:
+      // TODO : Branch to be removed when the deprecated properties are finally removed.
+      value = impl.mVisual.GetProperty( TEXT_VISUAL_PROPERTY_TABLE[index - Toolkit::TextLabel::PROPERTY_START_INDEX] );
+
+      switch( index )
       {
-        if( impl.mController )
+        case Toolkit::TextLabel::Property::SHADOW_OFFSET: // Converts the deprecated property to the new one.
         {
-          const char* name = Scripting::GetEnumerationName< Toolkit::Text::LayoutEngine::HorizontalAlignment >( impl.mController->GetHorizontalAlignment(),
-                                                                                                                HORIZONTAL_ALIGNMENT_STRING_TABLE,
-                                                                                                                HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT );
-          if( name )
+          bool colorDefined = false;
+          Vector4 color;
+          bool offsetDefined = false;
+          Vector2 offset;
+          const bool empty = Text::ParseProperties( value.Get<std::string>(),
+                                                    colorDefined,
+                                                    color,
+                                                    offsetDefined,
+                                                    offset );
+
+          if( !empty )
           {
-            value = std::string( name );
+            value = offset;
           }
+          break;
         }
-        break;
-      }
-      case Toolkit::TextLabel::Property::VERTICAL_ALIGNMENT:
-      {
-        if( impl.mController )
+        case Toolkit::TextLabel::Property::SHADOW_COLOR: // Converts the deprecated property to the new one.
         {
-          const char* name = Scripting::GetEnumerationName< Toolkit::Text::LayoutEngine::VerticalAlignment >( impl.mController->GetVerticalAlignment(),
-                                                                                                              VERTICAL_ALIGNMENT_STRING_TABLE,
-                                                                                                              VERTICAL_ALIGNMENT_STRING_TABLE_COUNT );
-          if( name )
+          bool colorDefined = false;
+          Vector4 color;
+          bool offsetDefined = false;
+          Vector2 offset;
+          const bool empty = Text::ParseProperties( value.Get<std::string>(),
+                                                    colorDefined,
+                                                    color,
+                                                    offsetDefined,
+                                                    offset );
+
+          if( !empty )
           {
-            value = std::string( name );
+            value = color;
           }
-        }
-        break;
-      }
-      case Toolkit::TextLabel::Property::TEXT_COLOR:
-      {
-        if ( impl.mController )
-        {
-          value = impl.mController->GetTextColor();
-        }
-        break;
-      }
-      case Toolkit::TextLabel::Property::SHADOW_OFFSET:
-      {
-        if ( impl.mController )
-        {
-          value = impl.mController->GetShadowOffset();
-        }
-        break;
-      }
-      case Toolkit::TextLabel::Property::SHADOW_COLOR:
-      {
-        if ( impl.mController )
-        {
-          value = impl.mController->GetShadowColor();
-        }
-        break;
-      }
-      case Toolkit::TextLabel::Property::UNDERLINE_COLOR:
-      {
-        if ( impl.mController )
-        {
-          value = impl.mController->GetUnderlineColor();
-        }
-        break;
-      }
-      case Toolkit::TextLabel::Property::UNDERLINE_ENABLED:
-      {
-        if ( impl.mController )
-        {
-          value = impl.mController->IsUnderlineEnabled();
-        }
-        break;
-      }
-      case Toolkit::TextLabel::Property::UNDERLINE_HEIGHT:
-      {
-        if ( impl.mController )
-        {
-          value = impl.mController->GetUnderlineHeight();
-        }
-        break;
-      }
-      case Toolkit::TextLabel::Property::ENABLE_MARKUP:
-      {
-        if( impl.mController )
-        {
-          value = impl.mController->IsMarkupProcessorEnabled();
-        }
-        break;
-      }
-      case Toolkit::TextLabel::Property::ENABLE_AUTO_SCROLL:
-      {
-        if( impl.mController )
-        {
-          value = impl.mController->IsAutoScrollEnabled();
-        }
-        break;
-      }
-      case Toolkit::TextLabel::Property::AUTO_SCROLL_SPEED:
-      {
-        TextLabel& impl( GetImpl( label ) );
-        if ( impl.mTextScroller )
-        {
-          value = impl.mTextScroller->GetSpeed();
-        }
-        break;
-      }
-      case Toolkit::TextLabel::Property::AUTO_SCROLL_LOOP_COUNT:
-      {
-        if( impl.mController )
-        {
-          TextLabel& impl( GetImpl( label ) );
-          if ( impl.mTextScroller )
+          break;
+        }
+        case Toolkit::TextLabel::Property::UNDERLINE_ENABLED: // Converts the deprecated property to the new one.
+        {
+          bool enabled = false;
+          bool colorDefined = false;
+          Vector4 color;
+          bool heightDefined = false;
+          float height = 0.f;
+          const bool empty = Text::ParseProperties( value.Get<std::string>(),
+                                                    enabled,
+                                                    colorDefined,
+                                                    color,
+                                                    heightDefined,
+                                                    height );
+
+          if( !empty )
           {
-            value = impl.mTextScroller->GetLoopCount();
+            value = enabled;
           }
+          break;
+        }
+        case Toolkit::TextLabel::Property::UNDERLINE_COLOR: // Converts the deprecated property to the new one.
+        {
+          bool enabled = false;
+          bool colorDefined = false;
+          Vector4 color;
+          bool heightDefined = false;
+          float height = 0.f;
+          const bool empty = Text::ParseProperties( value.Get<std::string>(),
+                                                    enabled,
+                                                    colorDefined,
+                                                    color,
+                                                    heightDefined,
+                                                    height );
+
+          if( !empty && colorDefined )
+          {
+            value = color;
+          }
+          break;
+        }
+        case Toolkit::TextLabel::Property::UNDERLINE_HEIGHT: // Converts the deprecated property to the new one.
+        {
+          bool enabled = false;
+          bool colorDefined = false;
+          Vector4 color;
+          bool heightDefined = false;
+          float height = 0.f;
+          const bool empty = Text::ParseProperties( value.Get<std::string>(),
+                                                    enabled,
+                                                    colorDefined,
+                                                    color,
+                                                    heightDefined,
+                                                    height );
+
+          if( !empty && heightDefined )
+          {
+            value = height;
+          }
+          break;
         }
-        break;
-      }
-      case Toolkit::TextLabel::Property::AUTO_SCROLL_GAP:
-      {
-        TextLabel& impl( GetImpl( label ) );
-        if ( impl.mTextScroller )
-        {
-          value = impl.mTextScroller->GetGap();
-        }
-        break;
-      }
-      case Toolkit::TextLabel::Property::LINE_SPACING:
-      {
-        if( impl.mController )
+        default:
         {
-          value = impl.mController->GetDefaultLineSpacing();
+          // Nothing to do.
+          break;
         }
-        break;
-      }
-      case Toolkit::TextLabel::Property::UNDERLINE:
-      {
-        GetUnderlineProperties( impl.mController, value, Text::EffectStyle::DEFAULT );
-        break;
-      }
-      case Toolkit::TextLabel::Property::SHADOW:
-      {
-        GetShadowProperties( impl.mController, value, Text::EffectStyle::DEFAULT );
-        break;
-      }
-      case Toolkit::TextLabel::Property::EMBOSS:
-      {
-        GetEmbossProperties( impl.mController, value, Text::EffectStyle::DEFAULT );
-        break;
-      }
-      case Toolkit::TextLabel::Property::OUTLINE:
-      {
-        GetOutlineProperties( impl.mController, value, Text::EffectStyle::DEFAULT );
-        break;
       }
     }
+    else
+    {
+      // Retrieves the property from the text visual.
+      value = impl.mVisual.GetProperty( TEXT_VISUAL_PROPERTY_TABLE[index - Toolkit::TextLabel::PROPERTY_START_INDEX] );
+    }
   }
 
   return value;
@@ -644,23 +283,23 @@ void TextLabel::OnInitialize()
 {
   Actor self = Self();
 
-  mController = Text::Controller::New( *this );
+  // Creates the text's visual.
+  Property::Map visualMap;
+  visualMap[Toolkit::Visual::Property::TYPE] = Toolkit::Visual::TEXT;
+  visualMap[Toolkit::TextVisual::Property::RENDERING_BACKEND] = static_cast<int>( DEFAULT_RENDERING_BACKEND );
+
+  mVisual =  Toolkit::VisualFactory::Get().CreateVisual( visualMap );
+  RegisterVisual( Toolkit::TextLabel::Property::TEXT, self, mVisual );
 
-  // When using the vector-based rendering, the size of the GLyphs are different
-  TextAbstraction::GlyphType glyphType = (Text::RENDERING_VECTOR_BASED == mRenderingBackend) ? TextAbstraction::VECTOR_GLYPH : TextAbstraction::BITMAP_GLYPH;
-  mController->SetGlyphType( glyphType );
+  Internal::Visual::Base& visualBase = Toolkit::GetImplementation( mVisual );
+  TextVisual* textVisual = static_cast<TextVisual*>( &visualBase );
+
+  // Sets the text's control interface.
+  textVisual->SetTextControlInterface( this );
 
   // Use height-for-width negotiation by default
   self.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH );
   self.SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::HEIGHT );
-
-  // Enable the text ellipsis.
-  LayoutEngine& engine = mController->GetLayoutEngine();
-
-  engine.SetTextEllipsisEnabled( true );   // If false then text larger than control will overflow
-  engine.SetCursorWidth( 0u ); // Do not layout space for the cursor.
-
-  self.OnStageSignal().Connect( this, &TextLabel::OnStageConnect );
 }
 
 void TextLabel::OnStyleChange( Toolkit::StyleManager styleManager, StyleChange::Type change )
@@ -674,10 +313,11 @@ void TextLabel::OnStyleChange( Toolkit::StyleManager styleManager, StyleChange::
       // Property system did not set the font so should update it.
       const std::string& newFont = GetImpl( styleManager ).GetDefaultFontFamily();
       DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel::OnStyleChange StyleChange::DEFAULT_FONT_CHANGE newFont(%s)\n", newFont.c_str() );
-      mController->UpdateAfterFontChange( newFont );
+
+      const std::string fontString = "{\"family\":\"" + newFont + "\",\"type\":\"system\"}";
+      mVisual.SetProperty( Toolkit::TextVisual::Property::FONT_FAMILY, fontString );
       break;
     }
-
     case StyleChange::DEFAULT_FONT_SIZE_CHANGE:
     {
       GetImpl( styleManager ).ApplyThemeStyle( Toolkit::Control( GetOwner() ) );
@@ -693,29 +333,22 @@ void TextLabel::OnStyleChange( Toolkit::StyleManager styleManager, StyleChange::
 
 Vector3 TextLabel::GetNaturalSize()
 {
-  return mController->GetNaturalSize();
+  Vector2 naturalSize;
+  mVisual.GetNaturalSize( naturalSize );
+
+  return Vector3( naturalSize );
 }
 
 float TextLabel::GetHeightForWidth( float width )
 {
-  return mController->GetHeightForWidth( width );
+  return mVisual.GetHeightForWidth( width );
 }
 
 void TextLabel::OnRelayout( const Vector2& size, RelayoutContainer& container )
 {
   DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel::OnRelayout\n" );
 
-  const Text::Controller::UpdateTextType updateTextType = mController->Relayout( size );
-
-  if( ( Text::Controller::NONE_UPDATED != ( Text::Controller::MODEL_UPDATED & updateTextType ) ) ||
-      !mRenderer )
-  {
-    if( !mRenderer )
-    {
-      mRenderer = Backend::Get().NewRenderer( mRenderingBackend );
-    }
-    RenderText();
-  }
+  mVisual.SetSize( size );
 }
 
 void TextLabel::RequestTextRelayout()
@@ -723,115 +356,16 @@ void TextLabel::RequestTextRelayout()
   RelayoutRequest();
 }
 
-void TextLabel::RenderText()
-{
-  DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel::RenderText IsAutoScrollEnabled[%s] [%p]\n", ( mController->IsAutoScrollEnabled())?"true":"false", this );
-
-  Actor self = Self();
-  Actor renderableActor;
-
-  if( mRenderer )
-  {
-    renderableActor = mRenderer->Render( mController->GetView(), DepthIndex::TEXT );
-  }
-
-  if( renderableActor != mRenderableActor )
-  {
-    UnparentAndReset( mRenderableActor );
-
-    if( renderableActor )
-    {
-      const Vector2& scrollOffset = mController->GetScrollPosition();
-      renderableActor.SetPosition( scrollOffset.x, scrollOffset.y );
-
-      self.Add( renderableActor );
-    }
-    mRenderableActor = renderableActor;
-
-    if ( mController->IsAutoScrollEnabled() )
-    {
-      SetUpAutoScrolling();
-    }
-  }
-}
-
-void TextLabel::SetUpAutoScrolling()
-{
-  const Size& controlSize = mController->GetView().GetControlSize();
-  const Size offScreenSize = GetNaturalSize().GetVectorXY(); // As relayout of text may not be done at this point natural size is used to get size. Single line scrolling only.
-  const float alignmentOffset = mController->GetAutoScrollLineAlignment();
-  const Text::CharacterDirection direction = mController->GetAutoScrollDirection();
-
-  DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel::SetUpAutoScrolling alignmentOffset[%f] offScreenSize[%f,%f] controlSize[%f,%f]\n",
-                 alignmentOffset, offScreenSize.x,offScreenSize.y , controlSize.x,controlSize.y );
-
-  if ( !mTextScroller )
-  {
-    DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel::SetUpAutoScrolling Creating default TextScoller\n" );
-
-    // If speed, loopCount or gap not set via property system then will need to create a TextScroller with defaults
-    mTextScroller = Text::TextScroller::New( *this );
-  }
-  mTextScroller->SetParameters( mRenderableActor, controlSize, offScreenSize, direction, alignmentOffset );
-
-  Actor self = Self();
-  self.Add( mTextScroller->GetScrollingText() );
-  self.Add( mTextScroller->GetSourceCamera() );
-}
-
-void TextLabel::OnStageConnect( Dali::Actor actor )
-{
-  if ( mHasBeenStaged )
-  {
-    RenderText();
-  }
-  else
-  {
-    mHasBeenStaged = true;
-  }
-}
-
-void TextLabel::AddDecoration( Actor& actor, bool needsClipping )
-{
-  // TextLabel does not show decorations
-}
-
 void TextLabel::OnStageConnection( int depth )
 {
   // Call the Control::OnStageConnection() to set the depth of the background.
   Control::OnStageConnection( depth );
 
-  // The depth of the text renderer is set in the RenderText() called from OnRelayout().
-}
-
-void TextLabel::TextChanged()
-{
-  // TextLabel does not provide a signal for this.
-}
-
-void TextLabel::MaxLengthReached()
-{
-  // Pure Virtual from TextController Interface, only needed when inputting text
-}
-
-void TextLabel::InputStyleChanged( Text::InputStyle::Mask inputStyleMask )
-{
-  // TextLabel does not provide a signal for this.
-}
-
-void TextLabel::ScrollingFinished()
-{
-  // Pure Virtual from TextScroller Interface
-  DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel::ScrollingFinished\n");
-  mController->SetAutoScrollEnabled( false );
-  mController->GetLayoutEngine().SetTextEllipsisEnabled( true );
-  RequestTextRelayout();
+  // The depth of the text renderer is set by the text-visual called from OnRelayout().
 }
 
 TextLabel::TextLabel()
-: Control( ControlBehaviour( CONTROL_BEHAVIOUR_DEFAULT ) ),
-  mRenderingBackend( DEFAULT_RENDERING_BACKEND ),
-  mHasBeenStaged( false )
+: Control( ControlBehaviour( CONTROL_BEHAVIOUR_DEFAULT ) )
 {
 }
 
index 298ba1a..bdc587d 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __DALI_TOOLKIT_INTERNAL_TEXT_LABEL_H__
-#define __DALI_TOOLKIT_INTERNAL_TEXT_LABEL_H__
+#ifndef DALI_TOOLKIT_INTERNAL_TEXT_LABEL_H
+#define DALI_TOOLKIT_INTERNAL_TEXT_LABEL_H
 
 /*
  * Copyright (c) 2016 Samsung Electronics Co., Ltd.
 // INTERNAL INCLUDES
 #include <dali-toolkit/public-api/controls/control-impl.h>
 #include <dali-toolkit/public-api/controls/text-controls/text-label.h>
-#include <dali-toolkit/internal/text/text-controller.h>
-#include <dali-toolkit/internal/text/text-scroller-interface.h>
-#include <dali-toolkit/internal/text/rendering/text-renderer.h>
-#include <dali-toolkit/internal/text/text-scroller.h>
+#include <dali-toolkit/internal/text/text-control-interface.h>
+#include <dali-toolkit/internal/visuals/text/text-visual.h>
 
 namespace Dali
 {
@@ -38,7 +36,7 @@ namespace Internal
 /**
  * @brief A control which renders a short text string.
  */
-class TextLabel : public Control, public Text::ControlInterface, public Text::ScrollerInterface
+class TextLabel : public Control, public Text::ControlInterface
 {
 public:
 
@@ -95,42 +93,17 @@ private: // From Control
   virtual float GetHeightForWidth( float width );
 
   /**
-   * @copydoc Text::ControlInterface::AddDecoration()
-   */
-  virtual void AddDecoration( Actor& actor, bool needsClipping );
-
-  /**
    * @copydoc Control::OnStageConnection()
    */
   virtual void OnStageConnection( int depth );
 
+// From ControlInterface
+
   /**
    * @copydoc Text::ControlInterface::RequestTextRelayout()
    */
   virtual void RequestTextRelayout();
 
-  /**
-   * @copydoc Text::ControlInterface::TextChanged()
-   */
-  virtual void TextChanged();
-
-  /**
-   * @copydoc Text::ControlInterface::MaxLengthReached()
-   */
-  virtual void MaxLengthReached();
-
-  /**
-   * @copydoc Text::ControlInterface::InputStyleChanged()
-   */
-  virtual void InputStyleChanged( Text::InputStyle::Mask inputStyleMask );
-
-private: // from TextScroller
-
-  /**
-   * @copydoc Text::ScrollerInterface::ScrollingFinished()
-   */
-  virtual void ScrollingFinished();
-
 private: // Implementation
 
   /**
@@ -149,27 +122,9 @@ private:
   TextLabel(const TextLabel&);
   TextLabel& operator=(const TextLabel& rhs);
 
-  // Connection needed to re-render text, when a Text Label returns to the stage
-  void OnStageConnect( Dali::Actor actor );
-
-  /**
-   * @brief Render view, create and attach actor(s) to this Text Label
-   */
-  void RenderText();
-
-  /**
-   * @brief Set up Autoscrolling
-   */
-  void SetUpAutoScrolling();
-
 private: // Data
 
-  Text::ControllerPtr mController;
-  Text::RendererPtr mRenderer;
-  Text::TextScrollerPtr mTextScroller;
-  Actor mRenderableActor;
-  int mRenderingBackend;
-  bool mHasBeenStaged:1;
+  Toolkit::Visual::Base mVisual;
 };
 
 } // namespace Internal
@@ -198,4 +153,4 @@ inline const Toolkit::Internal::TextLabel& GetImpl( const Toolkit::TextLabel& te
 
 } // namespace Dali
 
-#endif // __DALI_TOOLKIT_INTERNAL_TEXT_LABEL_H__
+#endif // DALI_TOOLKIT_INTERNAL_TEXT_LABEL_H
index 5a52371..57b4dbf 100644 (file)
@@ -29,7 +29,9 @@ toolkit_src_files = \
    $(toolkit_src_dir)/visuals/primitive/primitive-visual.cpp \
    $(toolkit_src_dir)/visuals/svg/svg-rasterize-thread.cpp \
    $(toolkit_src_dir)/visuals/svg/svg-visual.cpp \
+   $(toolkit_src_dir)/visuals/text/text-visual.cpp \
    $(toolkit_src_dir)/visuals/wireframe/wireframe-visual.cpp \
+   $(toolkit_src_dir)/visuals/transition-data-impl.cpp \
    $(toolkit_src_dir)/controls/alignment/alignment-impl.cpp \
    $(toolkit_src_dir)/controls/bloom-view/bloom-view-impl.cpp \
    $(toolkit_src_dir)/controls/bubble-effect/bubble-emitter-impl.cpp \
@@ -106,13 +108,13 @@ toolkit_src_files = \
    $(toolkit_src_dir)/text/property-string-parser.cpp \
    $(toolkit_src_dir)/text/segmentation.cpp \
    $(toolkit_src_dir)/text/shaper.cpp \
-   $(toolkit_src_dir)/text/text-control-interface.cpp \
    $(toolkit_src_dir)/text/text-controller.cpp \
    $(toolkit_src_dir)/text/text-controller-impl.cpp \
    $(toolkit_src_dir)/text/text-effects-style.cpp \
    $(toolkit_src_dir)/text/text-font-style.cpp \
    $(toolkit_src_dir)/text/text-io.cpp \
    $(toolkit_src_dir)/text/text-scroller.cpp \
+   $(toolkit_src_dir)/text/text-scroller-data.cpp \
    $(toolkit_src_dir)/text/text-scroller-interface.cpp \
    $(toolkit_src_dir)/text/text-view.cpp \
    $(toolkit_src_dir)/text/text-view-interface.cpp \
index 67f257c..bdd2780 100644 (file)
@@ -49,7 +49,19 @@ ImageAtlas::ImageAtlas( SizeType width, SizeType height, Pixel::Format pixelForm
 
 ImageAtlas::~ImageAtlas()
 {
-  mIdRectContainer.Clear();
+  const std::size_t count = mLoadingTaskInfoContainer.Count();
+  for( std::size_t i=0; i < count; ++i )
+  {
+    // Call unregister to every observer in the list.
+    // Note that, the Atlas can be registered to same observer multiple times, and the Unregister method only remove one item each time.
+    // In this way, the atlas is actually detached from a observer either every upload call invoked by this observer is completed or atlas is destroyed.
+    if( mLoadingTaskInfoContainer[i]->observer )
+    {
+      mLoadingTaskInfoContainer[i]->observer->Unregister( *this );
+    }
+  }
+
+  mLoadingTaskInfoContainer.Clear();
 }
 
 IntrusivePtr<ImageAtlas> ImageAtlas::New( SizeType width, SizeType height, Pixel::Format pixelFormat )
@@ -82,7 +94,8 @@ bool ImageAtlas::Upload( Vector4& textureRect,
                          const std::string& url,
                          ImageDimensions size,
                          FittingMode::Type fittingMode,
-                         bool orientationCorrection )
+                         bool orientationCorrection,
+                         AtlasUploadObserver* atlasUploadObserver )
 {
   ImageDimensions dimensions = size;
   ImageDimensions zero;
@@ -93,7 +106,7 @@ bool ImageAtlas::Upload( Vector4& textureRect,
     {
       if( !mBrokenImageUrl.empty() )
       {
-        return Upload( textureRect, mBrokenImageUrl, mBrokenImageSize, FittingMode::DEFAULT, true );
+        return Upload( textureRect, mBrokenImageUrl, mBrokenImageSize, FittingMode::DEFAULT, true, atlasUploadObserver );
       }
       else
       {
@@ -108,14 +121,20 @@ bool ImageAtlas::Upload( Vector4& textureRect,
   if( mPacker.Pack( dimensions.GetWidth(), dimensions.GetHeight(), packPositionX, packPositionY ) )
   {
     unsigned short loadId = mAsyncLoader.Load( url, size, fittingMode, SamplingMode::BOX_THEN_LINEAR, orientationCorrection );
-    mIdRectContainer.PushBack( new IdRectPair( loadId, packPositionX, packPositionY, dimensions.GetWidth(), dimensions.GetHeight() ) );
-
+    mLoadingTaskInfoContainer.PushBack( new LoadingTaskInfo( loadId, packPositionX, packPositionY, dimensions.GetWidth(), dimensions.GetHeight(), atlasUploadObserver ) );
     // apply the half pixel correction
     textureRect.x = ( static_cast<float>( packPositionX ) +0.5f ) / mWidth; // left
     textureRect.y = ( static_cast<float>( packPositionY ) +0.5f ) / mHeight; // right
     textureRect.z = ( static_cast<float>( packPositionX + dimensions.GetX() )-0.5f ) / mWidth; // right
     textureRect.w = ( static_cast<float>( packPositionY + dimensions.GetY() )-0.5f ) / mHeight;// bottom
 
+    if( atlasUploadObserver )
+    {
+      // register to the observer,
+      // Not that a matching unregister call should be invoked in UploadToAtlas if the observer is still alive by then.
+      atlasUploadObserver->Register( *this );
+    }
+
     return true;
   }
 
@@ -150,33 +169,51 @@ void ImageAtlas::Remove( const Vector4& textureRect )
                        static_cast<SizeType>((textureRect.w-textureRect.y)*mHeight+1.f) );
 }
 
-void ImageAtlas::UploadToAtlas( unsigned int id, PixelData pixelData )
+void ImageAtlas::ObserverDestroyed( AtlasUploadObserver* observer )
 {
-  if(  mIdRectContainer[0]->loadTaskId == id)
+  const std::size_t count = mLoadingTaskInfoContainer.Count();
+  for( std::size_t i=0; i < count; ++i )
   {
+    if( mLoadingTaskInfoContainer[i]->observer == observer )
+    {
+      // the observer is destructing, so its member function should not be called anymore
+      mLoadingTaskInfoContainer[i]->observer = NULL;
+    }
+  }
+}
+
+void ImageAtlas::UploadToAtlas( uint32_t id, PixelData pixelData )
+{
+  if(  mLoadingTaskInfoContainer[0]->loadTaskId == id)
+  {
+    Rect<unsigned int> packRect( mLoadingTaskInfoContainer[0]->packRect  );
     if( !pixelData || ( pixelData.GetWidth() ==0 && pixelData.GetHeight() == 0 ))
     {
       if(!mBrokenImageUrl.empty()) // replace with the broken image
       {
-        UploadBrokenImage( mIdRectContainer[0]->packRect );
+        UploadBrokenImage( packRect );
       }
     }
     else
     {
-      if( pixelData.GetWidth() < mIdRectContainer[0]->packRect.width || pixelData.GetHeight() < mIdRectContainer[0]->packRect.height  )
+      if( pixelData.GetWidth() < packRect.width || pixelData.GetHeight() < packRect.height  )
       {
         DALI_LOG_ERROR( "Can not upscale the image from actual loaded size [ %d, %d ] to specified size [ %d, %d ]\n",
-                        pixelData.GetWidth(), pixelData.GetHeight(),
-                        mIdRectContainer[0]->packRect.width,  mIdRectContainer[0]->packRect.height );
+            pixelData.GetWidth(), pixelData.GetHeight(),
+            packRect.width, packRect.height );
       }
 
-      mAtlas.Upload( pixelData, 0u, 0u,
-                    mIdRectContainer[0]->packRect.x, mIdRectContainer[0]->packRect.y,
-                    mIdRectContainer[0]->packRect.width, mIdRectContainer[0]->packRect.height );
+      mAtlas.Upload( pixelData, 0u, 0u, packRect.x, packRect.y, packRect.width, packRect.height );
     }
-  }
 
-  mIdRectContainer.Erase( mIdRectContainer.Begin() );
+    if( mLoadingTaskInfoContainer[0]->observer )
+    {
+      mLoadingTaskInfoContainer[0]->observer->UploadCompleted();
+      mLoadingTaskInfoContainer[0]->observer->Unregister( *this );
+    }
+
+    mLoadingTaskInfoContainer.Erase( mLoadingTaskInfoContainer.Begin() );
+  }
 }
 
 void ImageAtlas::UploadBrokenImage( const Rect<unsigned int>& area )
index 34924d3..a773ea7 100644 (file)
@@ -23,6 +23,7 @@
 #include <dali/public-api/signals/connection-tracker.h>
 #include <dali/devel-api/common/owner-container.h>
 #include <dali/devel-api/images/atlas.h>
+#include <dali/devel-api/common/owner-container.h>
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/devel-api/image-loader/image-atlas.h>
@@ -80,7 +81,8 @@ public:
                const std::string& url,
                ImageDimensions size,
                FittingMode::Type fittingMode,
-               bool orientationCorrection);
+               bool orientationCorrection,
+               AtlasUploadObserver* atlasUploadObserver );
 
   /**
    * @copydoc Toolkit::ImageAtlas::Upload( Vector4&, PixelData )
@@ -92,6 +94,11 @@ public:
    */
   void Remove( const Vector4& textureRect );
 
+  /**
+   * Resets the destroying observer pointer so that we know not to call methods of this object any more.
+   */
+  void ObserverDestroyed( AtlasUploadObserver* observer );
+
 protected:
 
   /**
@@ -104,7 +111,7 @@ private:
   /**
    * @copydoc PixelDataRequester::ProcessPixels
    */
-  void UploadToAtlas( unsigned int id, PixelData pixelData );
+  void UploadToAtlas( uint32_t id, PixelData pixelData );
 
   /**
    * Upload broken image
@@ -121,22 +128,29 @@ private:
 
 private:
 
-  struct IdRectPair
+  /**
+   * Each loading task( identified with an ID ) is associated with a rect region for packing the loaded pixel data into the atlas,
+   * and an AtlasUploadObserver whose UploadCompleted method should get executed once the sub texture is ready.
+   */
+  struct LoadingTaskInfo
   {
-    IdRectPair( unsigned short loadTaskId,
-                unsigned int packPositionX,
-                unsigned int packPositionY,
-                unsigned int width,
-                unsigned int height )
+    LoadingTaskInfo( unsigned short loadTaskId,
+                     unsigned int packPositionX,
+                     unsigned int packPositionY,
+                     unsigned int width,
+                     unsigned int height,
+                     AtlasUploadObserver* observer )
     : loadTaskId( loadTaskId ),
-      packRect( packPositionX, packPositionY, width, height )
+      packRect( packPositionX, packPositionY, width, height ),
+      observer( observer )
     {}
 
     unsigned short loadTaskId;
     Rect<unsigned int> packRect;
+    AtlasUploadObserver* observer;
   };
 
-  OwnerContainer<IdRectPair*> mIdRectContainer;
+  OwnerContainer<LoadingTaskInfo*> mLoadingTaskInfoContainer;
 
   Texture                   mAtlas;
   AtlasPacker               mPacker;
@@ -147,6 +161,7 @@ private:
   float                     mHeight;
   Pixel::Format             mPixelFormat;
 
+
 };
 
 } // namespace Internal
index 3c02c27..8af6140 100644 (file)
 
 // EXTERNAL INCLUDES
 #include <dali/public-api/common/constants.h>
+#include <dali/public-api/math/vector2.h>
 #include <stdlib.h>
+#include <sstream>
+#include <iomanip>
 
 namespace Dali
 {
@@ -33,9 +36,10 @@ namespace Text
 
 namespace
 {
-const char WHITE_SPACE       = 0x20; // ASCII value of the white space.
-const char LAST_UPPER_CASE   = 0x5b; // ASCII value of the one after the last upper case character (Z).
-const char TO_LOWER_CASE     = 32;   // Value to add to a upper case character to transform it into a lower case.
+const char WHITE_SPACE      = 0x20; // ASCII value of the white space.
+const char FIRST_UPPER_CASE = 0x41; // ASCII value of the one after the first upper case character (A).
+const char LAST_UPPER_CASE  = 0x5b; // ASCII value of the one after the last upper case character (Z).
+const char TO_LOWER_CASE    = 32;   // Value to add to a upper case character to transform it into a lower case.
 
 const char WEB_COLOR_TOKEN( '#' );
 const char* const HEX_COLOR_TOKEN( "0x" );
@@ -65,8 +69,9 @@ bool TokenComparison( const std::string& string1, const char* const stringBuffer
 
   for( std::size_t index = 0; index < stringSize; ++index )
   {
-    char character = *( stringBuffer2 + index );
-    if( *( stringBuffer1 + index ) != ( ( ( character < LAST_UPPER_CASE ) && ( '0' != character ) ) ? character + TO_LOWER_CASE : character ) )
+    const char character = *( stringBuffer2 + index );
+    const bool toLower = ( character < LAST_UPPER_CASE ) && ( character >= FIRST_UPPER_CASE );
+    if( *( stringBuffer1 + index ) != ( toLower ? character + TO_LOWER_CASE : character ) )
     {
       return false;
     }
@@ -75,10 +80,16 @@ bool TokenComparison( const std::string& string1, const char* const stringBuffer
   return true;
 }
 
-void SkipWhiteSpace( const char*& markupStringBuffer,
-                     const char* const markupStringEndBuffer )
+void SkipWhiteSpace( const char*& stringBuffer,
+                     const char* const stringEndBuffer )
 {
-  for( ; ( WHITE_SPACE >= *markupStringBuffer ) && ( markupStringBuffer < markupStringEndBuffer ); ++markupStringBuffer );
+  for( ; ( WHITE_SPACE >= *stringBuffer ) && ( stringBuffer < stringEndBuffer ); ++stringBuffer );
+}
+
+void JumpToWhiteSpace( const char*& stringBuffer,
+                       const char* const stringEndBuffer )
+{
+  for( ; ( WHITE_SPACE != *stringBuffer ) && ( stringBuffer < stringEndBuffer ); ++stringBuffer );
 }
 
 unsigned int StringToHex( const char* const uintStr )
@@ -91,6 +102,13 @@ float StringToFloat( const char* const floatStr )
   return static_cast<float>( strtod( floatStr, NULL ) );
 }
 
+void FloatToString( float value, std::string& floatStr )
+{
+  std::stringstream ss;
+  ss << value;
+  floatStr = ss.str();
+}
+
 void UintColorToVector4( unsigned int color, Vector4& retColor )
 {
   retColor.a = static_cast<float>( ( color & 0xFF000000 ) >> 24u ) / 255.f;
@@ -160,6 +178,112 @@ void ColorStringToVector4( const char* const colorStr, Length length, Vector4& r
   }
 }
 
+void Vector4ToColorString( const Vector4& value, std::string& vector2Str )
+{
+  if( Color::BLACK == value )
+  {
+    vector2Str = BLACK_COLOR;
+    return;
+  }
+
+  if( Color::WHITE == value )
+  {
+    vector2Str = WHITE_COLOR;
+    return;
+  }
+
+  if( Color::RED == value )
+  {
+    vector2Str = RED_COLOR;
+    return;
+  }
+
+  if( Color::GREEN == value )
+  {
+    vector2Str = GREEN_COLOR;
+    return;
+  }
+
+  if( Color::BLUE == value )
+  {
+    vector2Str = BLUE_COLOR;
+    return;
+  }
+
+  if( Color::YELLOW == value )
+  {
+    vector2Str = YELLOW_COLOR;
+    return;
+  }
+
+  if( Color::MAGENTA == value )
+  {
+    vector2Str = MAGENTA_COLOR;
+    return;
+  }
+
+  if( Color::CYAN == value )
+  {
+    vector2Str = CYAN_COLOR;
+    return;
+  }
+
+  if( Color::TRANSPARENT == value )
+  {
+    vector2Str = TRANSPARENT_COLOR;
+    return;
+  }
+
+  const unsigned int alpha = static_cast<unsigned int>( 255.f * value.a );
+  const unsigned int red = static_cast<unsigned int>( 255.f * value.r );
+  const unsigned int green = static_cast<unsigned int>( 255.f * value.g );
+  const unsigned int blue = static_cast<unsigned int>( 255.f * value.b );
+
+  std::stringstream ss;
+  const unsigned int size = 2u * sizeof( unsigned char );
+
+  ss << "0x"
+     << std::setfill('0') << std::setw( size )
+     << std::hex << alpha
+     << std::setfill('0') << std::setw( size )
+     << std::hex << red
+     << std::setfill('0') << std::setw( size )
+     << std::hex << green
+     << std::setfill('0') << std::setw( size )
+     << std::hex << blue;
+  vector2Str = ss.str();
+}
+
+void StringToVector2( const char* const vectorStr, Length length, Vector2& vector2 )
+{
+  // Points to the first character of the string.
+  const char* strBuffer = vectorStr;
+
+  // Points to the first character of the 'x' value.
+  const char* const xBuffer = strBuffer;
+
+  // Jumps to the next white space.
+  JumpToWhiteSpace( strBuffer, strBuffer + length );
+
+  // Points to the first character of the 'y' value.
+  const char* const yBuffer = strBuffer;
+
+  // Converts the shadow's offset to float.
+  vector2.x = StringToFloat( xBuffer );
+  vector2.y = StringToFloat( yBuffer );
+}
+
+void Vector2ToString( const Vector2& value, std::string& vector2Str )
+{
+  FloatToString( value.x, vector2Str );
+  vector2Str += " ";
+
+  std::string yStr;
+  FloatToString( value.y, yStr );
+
+  vector2Str += yStr;
+}
+
 } // namespace Text
 
 } // namespace Toolkit
index 62be6c8..45f586c 100644 (file)
@@ -28,6 +28,7 @@
 namespace Dali
 {
 
+struct Vector2;
 struct Vector4;
 
 namespace Toolkit
@@ -78,11 +79,20 @@ bool TokenComparison( const std::string& string1, const char* const stringBuffer
 /**
  * @brief Skips any unnecessary white space.
  *
- * @param[in,out] markupStringBuffer The mark-up string buffer. It's a const iterator pointing the current character.
- * @param[in] markupStringEndBuffer Pointer to one character after the end of the mark-up string buffer.
+ * @param[in,out] stringBuffer The string buffer. It's a const iterator pointing the current character.
+ * @param[in] stringEndBuffer Pointer to one character after the end of the string buffer.
  */
-void SkipWhiteSpace( const char*& markupStringBuffer,
-                     const char* const markupStringEndBuffer );
+void SkipWhiteSpace( const char*& stringBuffer,
+                     const char* const stringEndBuffer );
+
+/**
+ * @Brief Jumps to the next white space.
+ *
+ * @param[in,out] stringBuffer The string buffer. It's a const iterator pointing the current character.
+ * @param[in] stringEndBuffer Pointer to one character after the end of the string buffer.
+ */
+void JumpToWhiteSpace( const char*& stringBuffer,
+                       const char* const stringEndBuffer );
 
 /**
  * @brief Converts a string into an hexadecimal unsigned int.
@@ -103,6 +113,14 @@ unsigned int StringToHex( const char* const uintStr );
 float StringToFloat( const char* const floatStr );
 
 /**
+ * @brief Converts a float into a string.
+ *
+ * @param[in] value The float value.
+ * @param[out] floatStr The string.
+ */
+void FloatToString( float value, std::string& floatStr );
+
+/**
  * @brief Converts an ARGB color packed in 4 byte unsigned int into a Vector4 color used in Dali.
  *
  * @param[in] color An ARGB color packed in an unsigned int.
@@ -114,7 +132,7 @@ void UintColorToVector4( unsigned int color, Vector4& retColor );
  * @brief Converts a color packed inside a string into an ARGB Vector4 color.
  *
  * The string color could be in hexadecimal ( 0xFF0000FF ), webcolor ( #0000FF or #00F ) or some constant values:
- * black, white, red, green, blue, yellow, magenta, cyan, transparent.
+ * black, white, red, green, blue, yellow, magenta, cyan or transparent.
  *
  * @param[in] colorStr A color packed inside a string.
  * @param[in] length The length of the color string.
@@ -122,6 +140,35 @@ void UintColorToVector4( unsigned int color, Vector4& retColor );
  */
 void ColorStringToVector4( const char* const colorStr, Length length, Vector4& retColor );
 
+/**
+ * @brief Converts a color packed in a Vector4 into a string.
+ *
+ * Constant colors will be converted to the strings black, white, red, green, blue, yellow, magenta, cyan or transparent.
+ *
+ * If is not a constant color it will be converted to a string with hexadecimal ARGB content.
+ *
+ * @param[in] value The color value.
+ * @param[out] colorStr The string.
+ */
+void Vector4ToColorString( const Vector4& value, std::string& vector2Str );
+
+/**
+ * @brief Converts a two dimension vector packed inside a string into a Vector2.
+ *
+ * @param[in] vectorStr The two dimension vector packed inside a string.
+ * @param[in] length The length of the string.
+ * @param[out] vector2 The Vector2.
+ */
+void StringToVector2( const char* const vectorStr, Length length, Vector2& vector2 );
+
+/**
+ * @brief Converts a Vector2 into a string.
+ *
+ * @param[in] value The vector2 value.
+ * @param[out] vector2Str The string.
+ */
+void Vector2ToString( const Vector2& value, std::string& vector2Str );
+
 } // namespace Text
 
 } // namespace Toolkit
index 42b1050..2aa05e9 100644 (file)
@@ -79,27 +79,6 @@ void ParsePropertyString( const std::string& property, Property::Map& map )
   }
 }
 
-void StringOffsetToVector2( const std::string& offsetStr,
-                            Vector2& offset )
-{
-  offset = Vector2::ZERO;
-
-  unsigned int wsIndex = 0u;
-  for( std::string::const_iterator it = offsetStr.begin(),
-         endIt = offsetStr.end();
-       it != endIt;
-       ++it, ++wsIndex )
-  {
-    if( *it == ' ' )
-    {
-      break;
-    }
-  }
-
-  offset[0] = StringToFloat( offsetStr.c_str() );
-  offset[1] = StringToFloat( offsetStr.c_str() + wsIndex );
-}
-
 } //namespace Text
 
 } //namespace Toolkit
index b6ebf27..19d78b7 100644 (file)
@@ -56,16 +56,6 @@ void CreatePropertyMap( const TreeNode* const node, Property::Map& map );
  */
 void ParsePropertyString( const std::string& property, Property::Map& map );
 
-/**
- * @brief Converts an offset packed inside a string into a Vector2.
- *
- * @param[in] offsetStr The offset packed inside a string.
- * @param[out] offset The offset packed in a Vector2.
- *
- */
-void StringOffsetToVector2( const std::string& offsetStr,
-                            Vector2& offset );
-
 } //namespace Text
 
 } //namespace Toolkit
index f5346e0..ce5af88 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __DALI_TOOLKIT_TEXT_CONTROL_INTERFACE_H__
-#define __DALI_TOOLKIT_TEXT_CONTROL_INTERFACE_H__
+#ifndef DALI_TOOLKIT_TEXT_CONTROL_INTERFACE_H
+#define DALI_TOOLKIT_TEXT_CONTROL_INTERFACE_H
 
 /*
  * Copyright (c) 2016 Samsung Electronics Co., Ltd.
  *
  */
 
-// INTERNAL INCLUDES
-#include <dali-toolkit/internal/text/input-style.h>
-
 namespace Dali
 {
 
-class Actor;
-
 namespace Toolkit
 {
 
@@ -40,44 +35,15 @@ class ControlInterface
 public:
 
   /**
-   * @brief Constructor.
-   */
-  ControlInterface();
-
-  /**
    * @brief Virtual destructor.
    */
-  virtual ~ControlInterface();
-
-  /**
-   * @brief Add a decoration.
-   *
-   * @param[in] decoration The actor displaying a decoration.
-   * @param[in] needsClipping Whether the actor needs clipping.
-   */
-  virtual void AddDecoration( Actor& actor, bool needsClipping ) = 0;
+  virtual ~ControlInterface()
+  {}
 
   /**
    * @brief Called to request a text relayout.
    */
   virtual void RequestTextRelayout() = 0;
-
-  /**
-   * @brief Called to signal that text has been inserted or deleted.
-   */
-  virtual void TextChanged() = 0;
-
-  /**
-   * @brief Called when the number of characters to be inserted exceeds the maximum limit
-   */
-  virtual void MaxLengthReached() = 0;
-
-  /**
-   * @brief Called to signal that input style has been changed.
-   *
-   * @param[in] inputStyleMask Mask with the bits of the input style that has changed.
-   */
-  virtual void InputStyleChanged( InputStyle::Mask inputStyleMask ) = 0;
 };
 
 } // namespace Text
@@ -86,4 +52,4 @@ public:
 
 } // namespace Dali
 
-#endif // __DALI_TOOLKIT_TEXT_CONTROL_INTERFACE_H__
+#endif // DALI_TOOLKIT_TEXT_CONTROL_INTERFACE_H
index 5769fac..dcb2901 100644 (file)
@@ -31,6 +31,7 @@
 #include <dali-toolkit/internal/text/multi-language-support.h>
 #include <dali-toolkit/internal/text/segmentation.h>
 #include <dali-toolkit/internal/text/shaper.h>
+#include <dali-toolkit/internal/text/text-control-interface.h>
 #include <dali-toolkit/internal/text/text-run-container.h>
 
 namespace
@@ -2682,6 +2683,12 @@ void Controller::Impl::ClampHorizontalScroll( const Vector2& layoutSize )
 
 void Controller::Impl::ClampVerticalScroll( const Vector2& layoutSize )
 {
+  if( LayoutEngine::SINGLE_LINE_BOX == mLayoutEngine.GetLayout() )
+  {
+    // Nothing to do if the text is single line.
+    return;
+  }
+
   // Clamp between -space & 0.
   if( layoutSize.height > mVisualModel->mControlSize.height )
   {
@@ -2749,7 +2756,10 @@ void Controller::Impl::ScrollTextToMatchCursor( const CursorInfo& cursorInfo )
 
 void Controller::Impl::RequestRelayout()
 {
-  mControlInterface.RequestTextRelayout();
+  if( NULL != mControlInterface )
+  {
+    mControlInterface->RequestTextRelayout();
+  }
 }
 
 } // namespace Text
index 9b17fa7..608ea7d 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __DALI_TOOLKIT_TEXT_CONTROLLER_IMPL_H__
-#define __DALI_TOOLKIT_TEXT_CONTROLLER_IMPL_H__
+#ifndef DALI_TOOLKIT_TEXT_CONTROLLER_IMPL_H
+#define DALI_TOOLKIT_TEXT_CONTROLLER_IMPL_H
 
 /*
  * Copyright (c) 2016 Samsung Electronics Co., Ltd.
@@ -26,6 +26,7 @@
 #include <dali-toolkit/internal/text/input-style.h>
 #include <dali-toolkit/internal/text/layouts/layout-engine.h>
 #include <dali-toolkit/internal/text/logical-model-impl.h>
+#include <dali-toolkit/internal/text/text-scroller-data.h>
 #include <dali-toolkit/internal/text/text-controller.h>
 #include <dali-toolkit/internal/text/text-view.h>
 #include <dali-toolkit/internal/text/visual-model-impl.h>
@@ -285,8 +286,10 @@ struct OutlineDefaults
 
 struct Controller::Impl
 {
-  Impl( ControlInterface& controlInterface )
+  Impl( ControlInterface* controlInterface,
+        EditableControlInterface* editableControlInterface )
   : mControlInterface( controlInterface ),
+    mEditableControlInterface( editableControlInterface ),
     mLogicalModel(),
     mVisualModel(),
     mFontDefaults( NULL ),
@@ -295,6 +298,7 @@ struct Controller::Impl
     mEmbossDefaults( NULL ),
     mOutlineDefaults( NULL ),
     mEventData( NULL ),
+    mAutoScrollData( NULL ),
     mFontClient(),
     mClipboard(),
     mView(),
@@ -302,14 +306,14 @@ struct Controller::Impl
     mLayoutEngine(),
     mModifyEvents(),
     mTextColor( Color::BLACK ),
+    mScrollPosition(),
     mTextUpdateInfo(),
     mOperationsPending( NO_OPERATION ),
     mMaximumNumberOfCharacters( 50u ),
     mRecalculateNaturalSize( true ),
     mMarkupProcessorEnabled( false ),
     mClipboardHideEnabled( true ),
-    mAutoScrollEnabled( false ),
-    mAutoScrollDirectionRTL( false )
+    mIsAutoScrollEnabled( false )
   {
     mLogicalModel = LogicalModel::New();
     mVisualModel  = VisualModel::New();
@@ -336,10 +340,13 @@ struct Controller::Impl
     delete mEmbossDefaults;
     delete mOutlineDefaults;
     delete mEventData;
+    delete mAutoScrollData;
   }
 
+  // Text Controller Implementation.
+
   /**
-   * @brief Request a relayout using the ControlInterface.
+   * @copydoc Text::Controller::RequestRelayout()
    */
   void RequestRelayout();
 
@@ -686,7 +693,8 @@ private:
 
 public:
 
-  ControlInterface& mControlInterface;     ///< Reference to the text controller.
+  ControlInterface* mControlInterface;     ///< Reference to the text controller.
+  EditableControlInterface* mEditableControlInterface; ///< Reference to the editable text controller.
   LogicalModelPtr mLogicalModel;           ///< Pointer to the logical model.
   VisualModelPtr  mVisualModel;            ///< Pointer to the visual model.
   FontDefaults* mFontDefaults;             ///< Avoid allocating this when the user does not specify a font.
@@ -695,6 +703,7 @@ public:
   EmbossDefaults* mEmbossDefaults;         ///< Avoid allocating this when the user does not specify emboss parameters.
   OutlineDefaults* mOutlineDefaults;       ///< Avoid allocating this when the user does not specify outline parameters.
   EventData* mEventData;                   ///< Avoid allocating everything for text input until EnableTextInput().
+  ScrollerData* mAutoScrollData;           ///< Avoid allocating this when the user does not specify the auto text scrolling feature.
   TextAbstraction::FontClient mFontClient; ///< Handle to the font client.
   Clipboard mClipboard;                    ///< Handle to the system clipboard
   View mView;                              ///< The view interface to the rendering back-end.
@@ -713,10 +722,8 @@ public:
 
   bool mRecalculateNaturalSize:1;          ///< Whether the natural size needs to be recalculated.
   bool mMarkupProcessorEnabled:1;          ///< Whether the mark-up procesor is enabled.
-  bool mClipboardHideEnabled:1;            ///< Whether the ClipboardHide function work or not
-  bool mAutoScrollEnabled:1;               ///< Whether auto text scrolling is enabled.
-  CharacterDirection mAutoScrollDirectionRTL:1;  ///< Direction of auto scrolling, true if rtl
-
+  bool mClipboardHideEnabled:1;            ///< Whether the ClipboardHide function work or not.
+  bool mIsAutoScrollEnabled:1;             ///< Whether auto text scrolling is enabled.
 };
 
 } // namespace Text
@@ -725,4 +732,4 @@ public:
 
 } // namespace Dali
 
-#endif // __DALI_TOOLKIT_TEXT_CONTROLLER_H__
+#endif // DALI_TOOLKIT_TEXT_CONTROLLER_H
index 6dfb99e..769d0e0 100644 (file)
@@ -31,6 +31,7 @@
 #include <dali-toolkit/internal/text/layouts/layout-parameters.h>
 #include <dali-toolkit/internal/text/markup-processor.h>
 #include <dali-toolkit/internal/text/text-controller-impl.h>
+#include <dali-toolkit/internal/text/text-editable-control-interface.h>
 
 namespace
 {
@@ -100,11 +101,28 @@ FontDescriptionRun& UpdateSelectionFontStyleRun( EventData* eventData,
 
 // public : Constructor.
 
-ControllerPtr Controller::New( ControlInterface& controlInterface )
+ControllerPtr Controller::New()
+{
+  return ControllerPtr( new Controller() );
+}
+
+ControllerPtr Controller::New( ControlInterface* controlInterface )
 {
   return ControllerPtr( new Controller( controlInterface ) );
 }
 
+ControllerPtr Controller::New( ControlInterface* controlInterface,
+                               EditableControlInterface* editableControlInterface )
+{
+  return ControllerPtr( new Controller( controlInterface,
+                                        editableControlInterface ) );
+}
+
+void Controller::SetTextControlInterface( ControlInterface* controlInterface )
+{
+  mImpl->mControlInterface = controlInterface;
+}
+
 // public : Configure the text controller.
 
 void Controller::EnableTextInput( DecoratorPtr decorator )
@@ -140,9 +158,9 @@ void Controller::SetAutoScrollEnabled( bool enable )
 {
   DALI_LOG_INFO( gLogFilter, Debug::General, "Controller::SetAutoScrollEnabled[%s] SingleBox[%s]-> [%p]\n", (enable)?"true":"false", ( mImpl->mLayoutEngine.GetLayout() == LayoutEngine::SINGLE_LINE_BOX)?"true":"false", this );
 
-  if ( mImpl->mLayoutEngine.GetLayout() == LayoutEngine::SINGLE_LINE_BOX )
+  if( mImpl->mLayoutEngine.GetLayout() == LayoutEngine::SINGLE_LINE_BOX )
   {
-    if ( enable )
+    if( enable )
     {
       DALI_LOG_INFO( gLogFilter, Debug::General, "Controller::SetAutoScrollEnabled for SINGLE_LINE_BOX\n" );
       mImpl->mOperationsPending = static_cast<OperationsMask>( mImpl->mOperationsPending |
@@ -152,6 +170,10 @@ void Controller::SetAutoScrollEnabled( bool enable )
                                                                UPDATE_DIRECTION          |
                                                                REORDER );
 
+      if( NULL == mImpl->mAutoScrollData )
+      {
+        mImpl->mAutoScrollData = new ScrollerData();
+      }
     }
     else
     {
@@ -163,39 +185,104 @@ void Controller::SetAutoScrollEnabled( bool enable )
                                                                REORDER );
     }
 
-    mImpl->mAutoScrollEnabled = enable;
+    mImpl->mIsAutoScrollEnabled = enable;
     mImpl->RequestRelayout();
   }
   else
   {
     DALI_LOG_WARNING( "Attempted AutoScrolling on a non SINGLE_LINE_BOX, request ignored\n" );
-    mImpl->mAutoScrollEnabled = false;
+    mImpl->mIsAutoScrollEnabled = false;
   }
 }
 
 bool Controller::IsAutoScrollEnabled() const
 {
-  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Controller::IsAutoScrollEnabled[%s]\n", (mImpl->mAutoScrollEnabled)?"true":"false" );
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Controller::IsAutoScrollEnabled[%s]\n", mImpl->mIsAutoScrollEnabled?"true":"false" );
+
+  return mImpl->mIsAutoScrollEnabled;
+}
+
+void Controller::SetAutoscrollSpeed( int scrollSpeed )
+{
+  if( NULL == mImpl->mAutoScrollData )
+  {
+    mImpl->mAutoScrollData = new ScrollerData();
+  }
+
+  mImpl->mAutoScrollData->mScrollSpeed = scrollSpeed;
+}
+
+int Controller::GetAutoScrollSpeed() const
+{
+  if( NULL != mImpl->mAutoScrollData )
+  {
+    return mImpl->mAutoScrollData->mScrollSpeed;
+  }
+
+  return 0;
+}
+
+void Controller::SetAutoScrollLoopCount( int loopCount )
+{
+  if( NULL == mImpl->mAutoScrollData )
+  {
+    mImpl->mAutoScrollData = new ScrollerData();
+  }
+
+  mImpl->mAutoScrollData->mLoopCount = loopCount;
+}
+
+int Controller::GetAutoScrollLoopCount() const
+{
+  if( NULL != mImpl->mAutoScrollData )
+  {
+    return mImpl->mAutoScrollData->mLoopCount;
+  }
 
-  return mImpl->mAutoScrollEnabled;
+  return 0;
 }
 
-CharacterDirection Controller::GetAutoScrollDirection() const
+void Controller::SetAutoScrollWrapGap( float wrapGap )
 {
-  return mImpl->mAutoScrollDirectionRTL;
+  if( NULL == mImpl->mAutoScrollData )
+  {
+    mImpl->mAutoScrollData = new ScrollerData();
+  }
+
+  mImpl->mAutoScrollData->mWrapGap = wrapGap;
 }
 
-float Controller::GetAutoScrollLineAlignment() const
+float Controller::GetAutoScrollWrapGap() const
 {
-  float offset = 0.f;
+  if( NULL != mImpl->mAutoScrollData )
+  {
+    return mImpl->mAutoScrollData->mWrapGap;
+  }
+
+  return 0.f;
+}
 
-  if( mImpl->mVisualModel &&
-      ( 0u != mImpl->mVisualModel->mLines.Count() ) )
+const ScrollerData* const Controller::GetAutoScrollData()
+{
+  if( NULL != mImpl->mAutoScrollData )
   {
-    offset = ( *mImpl->mVisualModel->mLines.Begin() ).alignmentOffset;
+    // Need to update the data with the latest layout.
+    if( mImpl->mVisualModel )
+    {
+      mImpl->mAutoScrollData->mControlSize = mImpl->mVisualModel->mControlSize;
+      mImpl->mAutoScrollData->mOffscreenSize = GetNaturalSize().GetVectorXY();
+
+      mImpl->mAutoScrollData->mAlignmentOffset = 0.f;
+      if( 0u != mImpl->mVisualModel->mLines.Count() )
+      {
+        mImpl->mAutoScrollData->mAlignmentOffset = ( *mImpl->mVisualModel->mLines.Begin() ).alignmentOffset;
+      }
+    }
+
+    return mImpl->mAutoScrollData;
   }
 
-  return offset;
+  return NULL;
 }
 
 void Controller::SetHorizontalScrollEnabled( bool enable )
@@ -460,8 +547,11 @@ void Controller::SetText( const std::string& text )
     mImpl->mEventData->mEventQueue.clear();
   }
 
-  // Do this last since it provides callbacks into application code
-  mImpl->mControlInterface.TextChanged();
+  // Do this last since it provides callbacks into application code.
+  if( NULL != mImpl->mEditableControlInterface )
+  {
+    mImpl->mEditableControlInterface->TextChanged();
+  }
 }
 
 void Controller::GetText( std::string& text ) const
@@ -742,26 +832,6 @@ const Vector4& Controller::GetShadowColor() const
   return mImpl->mVisualModel->GetShadowColor();
 }
 
-void Controller::SetDefaultShadowProperties( const std::string& shadowProperties )
-{
-  if( NULL == mImpl->mShadowDefaults )
-  {
-    mImpl->mShadowDefaults = new ShadowDefaults();
-  }
-
-  mImpl->mShadowDefaults->properties = shadowProperties;
-}
-
-const std::string& Controller::GetDefaultShadowProperties() const
-{
-  if( NULL != mImpl->mShadowDefaults )
-  {
-    return mImpl->mShadowDefaults->properties;
-  }
-
-  return EMPTY_STRING;
-}
-
 void Controller::SetUnderlineColor( const Vector4& color )
 {
   mImpl->mVisualModel->SetUnderlineColor( color );
@@ -798,26 +868,6 @@ float Controller::GetUnderlineHeight() const
   return mImpl->mVisualModel->GetUnderlineHeight();
 }
 
-void Controller::SetDefaultUnderlineProperties( const std::string& underlineProperties )
-{
-  if( NULL == mImpl->mUnderlineDefaults )
-  {
-    mImpl->mUnderlineDefaults = new UnderlineDefaults();
-  }
-
-  mImpl->mUnderlineDefaults->properties = underlineProperties;
-}
-
-const std::string& Controller::GetDefaultUnderlineProperties() const
-{
-  if( NULL != mImpl->mUnderlineDefaults )
-  {
-    return mImpl->mUnderlineDefaults->properties;
-  }
-
-  return EMPTY_STRING;
-}
-
 void Controller::SetDefaultEmbossProperties( const std::string& embossProperties )
 {
   if( NULL == mImpl->mEmbossDefaults )
@@ -1262,7 +1312,7 @@ const std::string& Controller::GetInputShadowProperties() const
     return mImpl->mEventData->mInputStyle.shadowProperties;
   }
 
-  return GetDefaultShadowProperties();
+  return EMPTY_STRING;
 }
 
 void Controller::SetInputUnderlineProperties( const std::string& underlineProperties )
@@ -1280,7 +1330,7 @@ const std::string& Controller::GetInputUnderlineProperties() const
     return mImpl->mEventData->mInputStyle.underlineProperties;
   }
 
-  return GetDefaultUnderlineProperties();
+  return EMPTY_STRING;
 }
 
 void Controller::SetInputEmbossProperties( const std::string& embossProperties )
@@ -1477,7 +1527,7 @@ float Controller::GetHeightForWidth( float width )
 
 Controller::UpdateTextType Controller::Relayout( const Size& size )
 {
-  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "-->Controller::Relayout %p size %f,%f, autoScroll[%s]\n", this, size.width, size.height, (mImpl->mAutoScrollEnabled)?"true":"false"  );
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "-->Controller::Relayout %p size %f,%f, autoScroll[%s]\n", this, size.width, size.height, mImpl->mIsAutoScrollEnabled ?"true":"false"  );
 
   UpdateTextType updateTextType = NONE_UPDATED;
 
@@ -1583,6 +1633,11 @@ Controller::UpdateTextType Controller::Relayout( const Size& size )
   return updateTextType;
 }
 
+void Controller::RequestRelayout()
+{
+  mImpl->RequestRelayout();
+}
+
 // public : Input style change signals.
 
 bool Controller::IsInputStyleChangedSignalsQueueEmpty()
@@ -1605,8 +1660,11 @@ void Controller::ProcessInputStyleChangedSignals()
   {
     const InputStyle::Mask mask = *it;
 
-    // Emit the input style changed signal.
-    mImpl->mControlInterface.InputStyleChanged( mask );
+    if( NULL != mImpl->mEditableControlInterface )
+    {
+      // Emit the input style changed signal.
+      mImpl->mEditableControlInterface->InputStyleChanged( mask );
+    }
   }
 
   mImpl->mEventData->mInputStyleChangedQueue.Clear();
@@ -1731,10 +1789,11 @@ bool Controller::KeyEvent( const Dali::KeyEvent& keyEvent )
     mImpl->RequestRelayout();
   }
 
-  if( textChanged )
+  if( textChanged &&
+      ( NULL != mImpl->mEditableControlInterface ) )
   {
     // Do this last since it provides callbacks into application code
-    mImpl->mControlInterface.TextChanged();
+    mImpl->mEditableControlInterface->TextChanged();
   }
 
   return true;
@@ -1965,10 +2024,11 @@ ImfManager::ImfCallbackData Controller::OnImfEvent( ImfManager& imfManager, cons
 
   ImfManager::ImfCallbackData callbackData( ( retrieveText || retrieveCursor ), cursorPosition, text, false );
 
-  if( requestRelayout )
+  if( requestRelayout &&
+      ( NULL != mImpl->mEditableControlInterface ) )
   {
     // Do this last since it provides callbacks into application code
-    mImpl->mControlInterface.TextChanged();
+    mImpl->mEditableControlInterface->TextChanged();
   }
 
   return callbackData;
@@ -2001,7 +2061,10 @@ void Controller::GetTargetSize( Vector2& targetSize )
 
 void Controller::AddDecoration( Actor& actor, bool needsClipping )
 {
-  mImpl->mControlInterface.AddDecoration( actor, needsClipping );
+  if( NULL != mImpl->mEditableControlInterface )
+  {
+    mImpl->mEditableControlInterface->AddDecoration( actor, needsClipping );
+  }
 }
 
 void Controller::DecorationEvent( HandleType handleType, HandleState state, float x, float y )
@@ -2088,7 +2151,11 @@ void Controller::TextPopupButtonTouched( Dali::Toolkit::TextSelectionPopup::Butt
       mImpl->mEventData->mScrollAfterDelete = true;
 
       mImpl->RequestRelayout();
-      mImpl->mControlInterface.TextChanged();
+
+      if( NULL != mImpl->mEditableControlInterface )
+      {
+        mImpl->mEditableControlInterface->TextChanged();
+      }
       break;
     }
     case Toolkit::TextSelectionPopup::COPY:
@@ -2135,6 +2202,17 @@ void Controller::TextPopupButtonTouched( Dali::Toolkit::TextSelectionPopup::Butt
   }
 }
 
+// private : Inherit from TextScroller.
+
+void Controller::ScrollingFinished()
+{
+  // Pure Virtual from TextScroller Interface
+  SetAutoScrollEnabled( false );
+  GetLayoutEngine().SetTextEllipsisEnabled( true );
+
+  mImpl->RequestRelayout();
+}
+
 // private : Update.
 
 void Controller::InsertText( const std::string& text, Controller::InsertType type )
@@ -2375,8 +2453,11 @@ void Controller::InsertText( const std::string& text, Controller::InsertType typ
 
     mImpl->ResetImfManager();
 
-    // Do this last since it provides callbacks into application code
-    mImpl->mControlInterface.MaxLengthReached();
+    if( NULL != mImpl->mEditableControlInterface )
+    {
+      // Do this last since it provides callbacks into application code
+      mImpl->mEditableControlInterface->MaxLengthReached();
+    }
   }
 }
 
@@ -2386,8 +2467,11 @@ void Controller::PasteText( const std::string& stringToPaste )
   mImpl->ChangeState( EventData::EDITING );
   mImpl->RequestRelayout();
 
-  // Do this last since it provides callbacks into application code
-  mImpl->mControlInterface.TextChanged();
+  if( NULL != mImpl->mEditableControlInterface )
+  {
+    // Do this last since it provides callbacks into application code
+    mImpl->mEditableControlInterface->TextChanged();
+  }
 }
 
 bool Controller::RemoveText( int cursorOffset,
@@ -2594,7 +2678,10 @@ bool Controller::DoRelayout( const Size& size,
 
       if ( NO_OPERATION != ( UPDATE_DIRECTION & operations ) )
       {
-        mImpl->mAutoScrollDirectionRTL = false;
+        if( NULL != mImpl->mAutoScrollData )
+        {
+          mImpl->mAutoScrollData->mAutoScrollDirectionRTL = false;
+        }
       }
 
       // Reorder the lines
@@ -2630,9 +2717,11 @@ bool Controller::DoRelayout( const Size& size,
           if ( ( NO_OPERATION != ( UPDATE_DIRECTION & operations ) ) && ( numberOfLines > 0 ) )
           {
             const LineRun* const firstline = mImpl->mVisualModel->mLines.Begin();
-            if ( firstline )
+            if( firstline &&
+                mImpl->mIsAutoScrollEnabled &&
+                ( NULL != mImpl->mAutoScrollData ) )
             {
-              mImpl->mAutoScrollDirectionRTL = firstline->direction;
+              mImpl->mAutoScrollData->mAutoScrollDirectionRTL = firstline->direction;
             }
           }
         }
@@ -2664,7 +2753,7 @@ bool Controller::DoRelayout( const Size& size,
 #if defined(DEBUG_ENABLED)
   std::string currentText;
   GetText( currentText );
-  DALI_LOG_INFO( gLogFilter, Debug::Concise, "Controller::DoRelayout [%p] mImpl->mAutoScrollDirectionRTL[%s] [%s]\n", this, (mImpl->mAutoScrollDirectionRTL)?"true":"false",  currentText.c_str() );
+  DALI_LOG_INFO( gLogFilter, Debug::Concise, "Controller::DoRelayout [%p] mImpl->mAutoScrollDirectionRTL[%s] [%s]\n", this, ( ( NULL != mImpl->mAutoScrollData ) && mImpl->mAutoScrollData->mAutoScrollDirectionRTL)?"true":"false",  currentText.c_str() );
 #endif
   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "<--Controller::DoRelayout, view updated %s\n", ( viewUpdated ? "true" : "false" ) );
   return viewUpdated;
@@ -3011,10 +3100,22 @@ void Controller::ResetScrollPosition()
 
 // private : Private contructors & copy operator.
 
-Controller::Controller( ControlInterface& controlInterface )
+Controller::Controller()
 : mImpl( NULL )
 {
-  mImpl = new Controller::Impl( controlInterface );
+  mImpl = new Controller::Impl( NULL, NULL );
+}
+
+Controller::Controller( ControlInterface* controlInterface )
+{
+  mImpl = new Controller::Impl( controlInterface, NULL );
+}
+
+Controller::Controller( ControlInterface* controlInterface,
+                        EditableControlInterface* editableControlInterface )
+{
+  mImpl = new Controller::Impl( controlInterface,
+                                editableControlInterface );
 }
 
 // The copy constructor and operator are left unimplemented.
index 07e1665..ce5c51a 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __DALI_TOOLKIT_TEXT_CONTROLLER_H__
-#define __DALI_TOOLKIT_TEXT_CONTROLLER_H__
+#ifndef DALI_TOOLKIT_TEXT_CONTROLLER_H
+#define DALI_TOOLKIT_TEXT_CONTROLLER_H
 
 /*
  * Copyright (c) 2016 Samsung Electronics Co., Ltd.
@@ -26,7 +26,7 @@
 #include <dali-toolkit/devel-api/controls/text-controls/text-selection-popup-callback-interface.h>
 #include <dali-toolkit/internal/text/decorator/text-decorator.h>
 #include <dali-toolkit/internal/text/layouts/layout-engine.h>
-#include <dali-toolkit/internal/text/text-control-interface.h>
+#include <dali-toolkit/internal/text/text-scroller-interface.h>
 
 namespace Dali
 {
@@ -38,10 +38,12 @@ namespace Text
 {
 
 class Controller;
+class ControlInterface;
+class EditableControlInterface;
 class View;
+struct ScrollerData;
 
 typedef IntrusivePtr<Controller> ControllerPtr;
-typedef Dali::Toolkit::Text::ControlInterface ControlInterface;
 
 /**
  * @brief A Text Controller is used by UI Controls which display text.
@@ -54,7 +56,7 @@ typedef Dali::Toolkit::Text::ControlInterface ControlInterface;
  *
  * The text selection popup button callbacks are as well handled via the TextSelectionPopupCallbackInterface interface.
  */
-class Controller : public RefObject, public Decorator::ControllerInterface, public TextSelectionPopupCallbackInterface
+class Controller : public RefObject, public Decorator::ControllerInterface, public TextSelectionPopupCallbackInterface, public Text::ScrollerInterface
 {
 public: // Enumerated types.
 
@@ -123,10 +125,36 @@ public: // Constructor.
   /**
    * @brief Create a new instance of a Controller.
    *
-   * @param[in] controlInterface An interface used to request a text relayout.
    * @return A pointer to a new Controller.
    */
-  static ControllerPtr New( ControlInterface& controlInterface );
+  static ControllerPtr New();
+
+  /**
+   * @brief Create a new instance of a Controller.
+   *
+   * @param[in] controlInterface The control's interface.
+   *
+   * @return A pointer to a new Controller.
+   */
+  static ControllerPtr New( ControlInterface* controlInterface );
+
+  /**
+   * @brief Create a new instance of a Controller.
+   *
+   * @param[in] controlInterface The control's interface.
+   * @param[in] editableControlInterface The editable control's interface.
+   *
+   * @return A pointer to a new Controller.
+   */
+  static ControllerPtr New( ControlInterface* controlInterface,
+                            EditableControlInterface* editableControlInterface );
+
+  /**
+   * @brief Sets the text-control interface.
+   *
+   * @param[in] controlInterface The text-control interface.
+   */
+  void SetTextControlInterface( ControlInterface* controlInterface );
 
 public: // Configure the text controller.
 
@@ -182,17 +210,53 @@ public: // Configure the text controller.
   bool IsAutoScrollEnabled() const;
 
   /**
-   * @brief Get direction of the text from the first line of text,
-   * @return bool rtl (right to left) is true
+   * @brief Sets the speed the text should automatically scroll at.
+   *
+   * @param[in] scrollSpeed The speed of scrolling in pixels per second.
+   */
+  void SetAutoscrollSpeed( int scrollSpeed );
+
+  /**
+   * @brief Retrieves the auto scroll speed.
+   *
+   * @return The auto scroll speed in pixels per second.
+   */
+  int GetAutoScrollSpeed() const;
+
+  /**
+   * @brief Sets the number of loops the text should scroll.
+   *
+   * @param[in] loopCount The number of loops.
+   */
+  void SetAutoScrollLoopCount( int loopCount );
+
+  /**
+   * @brief Retrieves the number of loops the text should scroll.
+   *
+   * @return The numebr of loops.
+   */
+  int GetAutoScrollLoopCount() const;
+
+  /**
+   * @brief Sets the gap before text wraps around when scrolling.
+   *
+   * @param[in] wrapGap The gap in pixels.
+   */
+  void SetAutoScrollWrapGap( float wrapGap );
+
+  /**
+   * @brief Retrieves the gap before text wraps around when scrolling.
+   *
+   * @return The gap in pixels.
    */
-  CharacterDirection GetAutoScrollDirection() const;
+  float GetAutoScrollWrapGap() const;
 
   /**
-   * @brief Get the alignment offset of the first line of text.
+   * @brief Retrieves the text's autoscroll data.
    *
-   * @return The alignment offset.
+   * @return The text's autoscroll data.
    */
-  float GetAutoScrollLineAlignment() const;
+  const ScrollerData* const GetAutoScrollData();
 
   /**
    * @brief Enables the horizontal scrolling.
@@ -480,22 +544,6 @@ public: // Default style & Input style
   const Vector4& GetShadowColor() const;
 
   /**
-   * @brief Sets the shadow's properties string.
-   *
-   * @note The string is stored to be recovered.
-   *
-   * @param[in] shadowProperties The shadow's properties string.
-   */
-  void SetDefaultShadowProperties( const std::string& shadowProperties );
-
-  /**
-   * @brief Retrieves the shadow's properties string.
-   *
-   * @return The shadow's properties string.
-   */
-  const std::string& GetDefaultShadowProperties() const;
-
-  /**
    * @brief Set the underline color.
    *
    * @param[in] color color of underline.
@@ -538,22 +586,6 @@ public: // Default style & Input style
   float GetUnderlineHeight() const;
 
   /**
-   * @brief Sets the underline's properties string.
-   *
-   * @note The string is stored to be recovered.
-   *
-   * @param[in] underlineProperties The underline's properties string.
-   */
-  void SetDefaultUnderlineProperties( const std::string& underlineProperties );
-
-  /**
-   * @brief Retrieves the underline's properties string.
-   *
-   * @return The underline's properties string.
-   */
-  const std::string& GetDefaultUnderlineProperties() const;
-
-  /**
    * @brief Sets the emboss's properties string.
    *
    * @note The string is stored to be recovered.
@@ -821,6 +853,11 @@ public: // Relayout.
    */
   UpdateTextType Relayout( const Size& size );
 
+  /**
+   * @brief Request a relayout using the ControlInterface.
+   */
+  void RequestRelayout();
+
 public: // Input style change signals.
 
   /**
@@ -919,6 +956,13 @@ protected: // Inherit from TextSelectionPopup::TextPopupButtonCallbackInterface.
    */
   virtual void TextPopupButtonTouched( Dali::Toolkit::TextSelectionPopup::Buttons button );
 
+private: // Inherit from TextScroller
+
+  /**
+   * @copydoc Text::ScrollerInterface::ScrollingFinished()
+   */
+  virtual void ScrollingFinished();
+
 private: // Update.
 
   /**
@@ -1058,7 +1102,18 @@ private: // Private contructors & copy operator.
   /**
    * @brief Private constructor.
    */
-  Controller( ControlInterface& controlInterface );
+  Controller();
+
+  /**
+   * @brief Private constructor.
+   */
+  Controller( ControlInterface* controlInterface );
+
+  /**
+   * @brief Private constructor.
+   */
+  Controller( ControlInterface* controlInterface,
+              EditableControlInterface* editableControlInterface );
 
   // Undefined
   Controller( const Controller& handle );
@@ -1085,4 +1140,4 @@ private:
 
 } // namespace Dali
 
-#endif // __DALI_TOOLKIT_TEXT_CONTROLLER_H__
+#endif // DALI_TOOLKIT_TEXT_CONTROLLER_H
diff --git a/dali-toolkit/internal/text/text-editable-control-interface.h b/dali-toolkit/internal/text/text-editable-control-interface.h
new file mode 100644 (file)
index 0000000..e54704c
--- /dev/null
@@ -0,0 +1,80 @@
+#ifndef DALI_TOOLKIT_TEXT_EDITABLE_CONTROL_INTERFACE_H
+#define DALI_TOOLKIT_TEXT_EDITABLE_CONTROL_INTERFACE_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.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/input-style.h>
+
+namespace Dali
+{
+
+class Actor;
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+/**
+ * @brief An interface that the Text::Controller uses to notify about text changes and add decoration to the text control.
+ */
+class EditableControlInterface
+{
+public:
+
+  /**
+   * @brief Virtual destructor.
+   */
+  virtual ~EditableControlInterface()
+  {}
+
+  /**
+   * @brief Called to signal that text has been inserted or deleted.
+   */
+  virtual void TextChanged() = 0;
+
+  /**
+   * @brief Called when the number of characters to be inserted exceeds the maximum limit
+   */
+  virtual void MaxLengthReached() = 0;
+
+  /**
+   * @brief Called to signal that input style has been changed.
+   *
+   * @param[in] inputStyleMask Mask with the bits of the input style that has changed.
+   */
+  virtual void InputStyleChanged( InputStyle::Mask inputStyleMask ) = 0;
+
+  /**
+   * @brief Add a decoration.
+   *
+   * @param[in] decoration The actor displaying a decoration.
+   * @param[in] needsClipping Whether the actor needs clipping.
+   */
+  virtual void AddDecoration( Actor& actor, bool needsClipping ) = 0;
+};
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_TEXT_EDITABLE_CONTROL_INTERFACE_H
index 31580a2..083cf47 100644 (file)
@@ -35,72 +35,137 @@ namespace
 {
 const std::string COLOR_KEY( "color" );
 const std::string OFFSET_KEY( "offset" );
-const std::string THICKNESS_KEY( "thickness" );
+const std::string HEIGHT_KEY( "height" );
+const std::string ENABLE_KEY( "enable" );
+const std::string TRUE_TOKEN( "true" );
 }
 
-bool SetUnderlineProperties( ControllerPtr controller, const Property::Value& value, EffectStyle::Type type )
+bool ParseProperties( const std::string& shadowProperties,
+                      bool& colorDefined,
+                      Vector4& color,
+                      bool& offsetDefined,
+                      Vector2& offset )
 {
-  bool update = false;
+  // Parses and applies the style.
+  Property::Map map;
+  Text::ParsePropertyString( shadowProperties, map );
 
-  if( controller )
+  const bool empty = map.Empty();
+
+  if( !empty )
   {
-    const std::string properties = value.Get< std::string >();
+    /// Color key.
+    Property::Value* colorValue = map.Find( COLOR_KEY );
 
-    switch( type )
+    colorDefined = colorValue != NULL;
+    if( colorDefined )
     {
-      case EffectStyle::DEFAULT:
-      {
-        // Stores the default underline's properties string to be recovered by the GetUnderlineProperties() function.
-        controller->SetDefaultUnderlineProperties( properties );
-        break;
-      }
-      case EffectStyle::INPUT:
-      {
-        // Stores the input underline's properties string to be recovered by the GetUnderlineProperties() function.
-        controller->SetInputUnderlineProperties( properties );
-        break;
-      }
+      const std::string colorStr = colorValue->Get<std::string>();
+
+      Text::ColorStringToVector4( colorStr.c_str(), colorStr.size(), color );
     }
 
-    // Parses and applies the style.
-    Property::Map map;
-    ParsePropertyString( properties, map );
+    /// Offset key.
+    Property::Value* offsetValue = map.Find( OFFSET_KEY );
 
-    if( !map.Empty() )
+    offsetDefined = offsetValue != NULL;
+    if( offsetDefined )
     {
-      /// Color key
-      Property::Value* colorValue = map.Find( COLOR_KEY );
+      const std::string offsetStr = offsetValue->Get<std::string>();
 
-      Vector4 color;
-      const bool colorDefined = colorValue != NULL;
-      if( colorDefined )
-      {
-        const std::string colorStr = colorValue->Get<std::string>();
+      StringToVector2( offsetStr.c_str(), offsetStr.size(), offset );
+    }
+  }
 
-        ColorStringToVector4( colorStr.c_str(), colorStr.size(), color );
-      }
+  return empty;
+}
+
+bool ParseProperties( const std::string& underlineProperties,
+                      bool& enabled,
+                      bool& colorDefined,
+                      Vector4& color,
+                      bool& heightDefined,
+                      float& height )
+{
+  // Parses and applies the style.
+  Property::Map map;
+  Text::ParsePropertyString( underlineProperties, map );
 
-      /// Thickness key
-      Property::Value* thicknessValue = map.Find( THICKNESS_KEY );
+  const bool empty = map.Empty();
 
-      float thickness = 0.f;
-      const bool thicknessDefined = thicknessValue != NULL;
-      if( thicknessDefined )
-      {
-        const std::string thicknessStr = thicknessValue->Get<std::string>();
+  if( !empty )
+  {
+    /// Enable key.
+    Property::Value* enableValue = map.Find( ENABLE_KEY );
 
-        thickness = StringToFloat( thicknessStr.c_str() );
-      }
+    enabled = false;
+    const bool enabledDefined = enableValue != NULL;
+    if( enabledDefined )
+    {
+      const std::string enableStr = enableValue->Get<std::string>();
+      enabled = Text::TokenComparison( TRUE_TOKEN, enableStr.c_str(), enableStr.size() );
+    }
+
+    /// Color key.
+    Property::Value* colorValue = map.Find( COLOR_KEY );
 
+    colorDefined = colorValue != NULL;
+    if( colorDefined )
+    {
+      const std::string colorStr = colorValue->Get<std::string>();
+
+      Text::ColorStringToVector4( colorStr.c_str(), colorStr.size(), color );
+    }
+
+    /// Height key.
+    Property::Value* heightValue = map.Find( HEIGHT_KEY );
+
+    height = 0.f;
+    heightDefined = heightValue != NULL;
+    if( heightDefined )
+    {
+      const std::string heightStr = heightValue->Get<std::string>();
+
+      height = StringToFloat( heightStr.c_str() );
+    }
+  }
+
+  return empty;
+}
+
+bool SetUnderlineProperties( ControllerPtr controller, const Property::Value& value, EffectStyle::Type type )
+{
+  bool update = false;
+
+  if( controller )
+  {
+    const std::string properties = value.Get<std::string>();
+
+    bool enabled = false;
+    bool colorDefined = false;
+    Vector4 color;
+    bool heightDefined = false;
+    float height = 0.f;
+
+    const bool empty = ParseProperties( properties,
+                                        enabled,
+                                        colorDefined,
+                                        color,
+                                        heightDefined,
+                                        height );
+
+    if( !empty )
+    {
       switch( type )
       {
         case EffectStyle::DEFAULT:
         {
-          if( !controller->IsUnderlineEnabled() )
+          if( enabled != controller->IsUnderlineEnabled() )
           {
-            controller->SetUnderlineEnabled( true );
+            controller->SetUnderlineEnabled( enabled );
             update = true;
           }
+
           // Sets the default underline values.
           if( colorDefined && ( controller->GetUnderlineColor() != color ) )
           {
@@ -108,9 +173,9 @@ bool SetUnderlineProperties( ControllerPtr controller, const Property::Value& va
             update = true;
           }
 
-          if( thicknessDefined &&  fabsf( controller->GetUnderlineHeight() - thickness ) > Math::MACHINE_EPSILON_1000 )
+          if( heightDefined && ( fabsf( controller->GetUnderlineHeight() - height ) > Math::MACHINE_EPSILON_1000 ) )
           {
-            controller->SetUnderlineHeight( thickness );
+            controller->SetUnderlineHeight( height );
             update = true;
           }
           break;
@@ -125,11 +190,25 @@ bool SetUnderlineProperties( ControllerPtr controller, const Property::Value& va
     }
     else
     {
-      // Disable underline.
-      if( controller->IsUnderlineEnabled() )
+      switch( type )
       {
-        controller->SetUnderlineEnabled( false );
-        update = true;
+        case EffectStyle::DEFAULT:
+        {
+          // Disable underline.
+          if( controller->IsUnderlineEnabled() )
+          {
+            controller->SetUnderlineEnabled( false );
+            update = true;
+          }
+          break;
+        }
+        case EffectStyle::INPUT:
+        {
+          // Sets the input underline values.
+          // TODO: to be implemented.
+          controller->SetInputUnderlineProperties( properties );
+          break;
+        }
       }
     }
   }
@@ -145,7 +224,23 @@ void GetUnderlineProperties( ControllerPtr controller, Property::Value& value, E
     {
       case EffectStyle::DEFAULT:
       {
-        value = controller->GetDefaultUnderlineProperties();
+        const bool enabled = controller->IsUnderlineEnabled();
+        const Vector4& color = controller->GetUnderlineColor();
+        const float height = controller->GetUnderlineHeight();
+
+        std::string underlineProperties = "{\"enable\":";
+        const std::string enabledStr = enabled ? "true" : "false";
+        underlineProperties += "\"" + enabledStr + "\",";
+
+        std::string colorStr;
+        Vector4ToColorString( color, colorStr );
+        underlineProperties += "\"color\":\"" + colorStr + "\",";
+
+        std::string heightStr;
+        FloatToString( height, heightStr );
+        underlineProperties += "\"height\":\"" + heightStr + "\"}";
+
+        value = underlineProperties;
         break;
       }
       case EffectStyle::INPUT:
@@ -165,52 +260,19 @@ bool SetShadowProperties( ControllerPtr controller, const Property::Value& value
   {
     const std::string properties = value.Get< std::string >();
 
-    switch( type )
-    {
-      case EffectStyle::DEFAULT:
-      {
-        // Stores the default shadow's properties string to be recovered by the GetShadowProperties() function.
-        controller->SetDefaultShadowProperties( properties );
-        break;
-      }
-      case EffectStyle::INPUT:
-      {
-        // Stores the input shadow's properties string to be recovered by the GetShadowProperties() function.
-        controller->SetInputShadowProperties( properties );
-        break;
-      }
-    }
+    bool colorDefined = false;
+    Vector4 color;
+    bool offsetDefined = false;
+    Vector2 offset;
 
-    // Parses and applies the style.
-    Property::Map map;
-    ParsePropertyString( properties, map );
+    const bool empty = ParseProperties( properties,
+                                        colorDefined,
+                                        color,
+                                        offsetDefined,
+                                        offset );
 
-    if( !map.Empty() )
+    if( !empty )
     {
-      /// Color key
-      Property::Value* colorValue = map.Find( COLOR_KEY );
-
-      Vector4 color;
-      const bool colorDefined = colorValue != NULL;
-      if( colorDefined )
-      {
-        const std::string colorStr = colorValue->Get<std::string>();
-
-        ColorStringToVector4( colorStr.c_str(), colorStr.size(), color );
-      }
-
-      /// Offset key
-      Property::Value* offsetValue = map.Find( OFFSET_KEY );
-
-      Vector2 offset;
-      const bool offsetDefined = offsetValue != NULL;
-      if( offsetDefined )
-      {
-        const std::string offsetStr = offsetValue->Get<std::string>();
-
-        StringOffsetToVector2( offsetStr, offset );
-      }
-
       switch( type )
       {
         case EffectStyle::DEFAULT:
@@ -237,6 +299,28 @@ bool SetShadowProperties( ControllerPtr controller, const Property::Value& value
         }
       }
     }
+    else
+    {
+      switch( type )
+      {
+        case EffectStyle::DEFAULT:
+        {
+          // Disable shadow.
+          if( Vector2::ZERO != controller->GetShadowOffset() )
+          {
+            controller->SetShadowOffset( Vector2::ZERO );
+          }
+          break;
+        }
+        case EffectStyle::INPUT:
+        {
+          // Sets the input shadow values.
+          // TODO: to be implemented.
+          controller->SetInputShadowProperties( properties );
+          break;
+        }
+      }
+    }
   }
 
   return update;
@@ -250,7 +334,20 @@ void GetShadowProperties( ControllerPtr controller, Property::Value& value, Effe
     {
       case EffectStyle::DEFAULT:
       {
-        value = controller->GetDefaultShadowProperties();
+        const Vector4& color = controller->GetShadowColor();
+        const Vector2& offset = controller->GetShadowOffset();
+
+        std::string shadowProperties = "{";
+
+        std::string colorStr;
+        Vector4ToColorString( color, colorStr );
+        shadowProperties += "\"color\":\"" + colorStr + "\",";
+
+        std::string offsetStr;
+        Vector2ToString( offset, offsetStr );
+        shadowProperties += "\"offset\":\"" + offsetStr + "\"}";
+
+        value = shadowProperties;
         break;
       }
       case EffectStyle::INPUT:
index 9feb75c..fb21fe9 100644 (file)
  *
  */
 
-// EXTERNAL INCLUDES
-#include <dali/devel-api/scripting/scripting.h>
-
 // INTERNAL INCLUDES
 #include <dali-toolkit/internal/text/text-controller.h>
-#include <dali-toolkit/internal/text/text-definitions.h>
 
 namespace Dali
 {
@@ -44,6 +40,36 @@ namespace EffectStyle
 };
 
 /**
+ * @brief Parses the shadow properties.
+ *
+ * @param[out] colorDefined Whether the shadow's color is defined.
+ * @param[out] color The shadow's color.
+ * @param[out] offsetDefined Whether the shadow's offset is defined.
+ * @param[out] offset The shadow's offset.
+ */
+bool ParseProperties( const std::string& shadowProperties,
+                      bool& colorDefined,
+                      Vector4& color,
+                      bool& offsetDefined,
+                      Vector2& offset );
+
+/**
+ * @brief Parses the underline properties.
+ *
+ * @param[out] enabled Whether the underline is enabled.
+ * @param[out] colorDefined Whether the underline's color is defined.
+ * @param[out] color The underline's color.
+ * @param[out] heightDefined Whether the underline's height is defined.
+ * @param[out] height The underline's height.
+ */
+bool ParseProperties( const std::string& underlineProperties,
+                      bool& enabled,
+                      bool& colorDefined,
+                      Vector4& color,
+                      bool& heightDefined,
+                      float& height );
+
+/**
  * @brief Sets the underline properties.
  *
  * @param[in] controller The text's controller.
index 6fff87e..b3b9e84 100644 (file)
@@ -23,6 +23,7 @@
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/internal/text/property-string-parser.h>
+#include <dali-toolkit/internal/text/markup-processor-helper-functions.h>
 
 namespace Dali
 {
@@ -39,6 +40,10 @@ const std::string STYLE_KEY( "style" );
 const std::string WEIGHT_KEY( "weight" );
 const std::string WIDTH_KEY( "width" );
 const std::string SLANT_KEY( "slant" );
+const std::string FAMILY_KEY( "family" );
+const std::string TYPE_KEY( "type" );
+
+const std::string SYSTEM_TOKEN( "system" );
 
 #if defined(DEBUG_ENABLED)
 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::Concise, true, "LOG_TEXT_CONTROLS");
@@ -46,6 +51,59 @@ Debug::Filter* gLogFilter = Debug::Filter::New(Debug::Concise, true, "LOG_TEXT_C
 
 } // namespace
 
+void SetFontFamilyProperty( ControllerPtr controller, const Property::Value& value )
+{
+  if( controller )
+  {
+    const std::string fontFamilyValue = value.Get<std::string>();
+
+    if( fontFamilyValue.empty() )
+    {
+      // Resets the default's font family name.
+      controller->SetDefaultFontFamily( "" );
+      return;
+    }
+
+    Property::Map map;
+    ParsePropertyString( fontFamilyValue, map );
+
+    if( map.Empty() )
+    {
+      // There is no map. The font has been passed as a font's family name with no format.
+      controller->SetDefaultFontFamily( fontFamilyValue );
+    }
+    else
+    {
+      /// Family key
+      Property::Value* familyValue = map.Find( FAMILY_KEY );
+
+      std::string fontFamilyName;
+      if( NULL != familyValue )
+      {
+        fontFamilyName = familyValue->Get<std::string>();
+      }
+
+      /// Type key
+      Property::Value* typeValue = map.Find( TYPE_KEY );
+
+      std::string typeStr;
+      if( NULL != typeValue )
+      {
+        typeStr = typeValue->Get<std::string>();
+      }
+
+      if( TokenComparison( SYSTEM_TOKEN, typeStr.c_str(), typeStr.size() ) )
+      {
+        controller->UpdateAfterFontChange( fontFamilyName );
+      }
+      else
+      {
+        controller->SetDefaultFontFamily( fontFamilyName );
+      }
+    }
+  }
+}
+
 void SetFontStyleProperty( ControllerPtr controller, const Property::Value& value, FontStyle::Type type )
 {
   if( controller )
index 425131d..e74bcfb 100644 (file)
@@ -23,7 +23,6 @@
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/internal/text/text-controller.h>
-#include <dali-toolkit/internal/text/text-definitions.h>
 
 namespace Dali
 {
@@ -90,6 +89,14 @@ namespace FontStyle
 };
 
 /**
+ * @brief Sets the font family property.
+ *
+ * @param[in] controller The text's controller.
+ * @param[in] value The value of the font's family.
+ */
+void SetFontFamilyProperty( ControllerPtr controller, const Property::Value& value );
+
+/**
  * @brief Sets the font's style property.
  *
  * @param[in] controller The text's controller.
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ * 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.
@@ -15,8 +15,8 @@
  *
  */
 
-// CLASS HEADER
-#include <dali-toolkit/internal/text/text-control-interface.h>
+// FILE HEADER
+#include <dali-toolkit/internal/text/text-scroller-data.h>
 
 namespace Dali
 {
@@ -27,13 +27,18 @@ namespace Toolkit
 namespace Text
 {
 
-ControlInterface::ControlInterface()
-{
-}
+const int MINIMUM_SCROLL_SPEED = 1;
 
-ControlInterface::~ControlInterface()
-{
-}
+ScrollerData::ScrollerData()
+: mScrollSpeed( MINIMUM_SCROLL_SPEED ),
+  mLoopCount( 1 ),
+  mWrapGap( 0.f ),
+  mAlignmentOffset( 0.f ),
+  mAutoScrollDirectionRTL( false )
+{}
+
+ScrollerData::~ScrollerData()
+{}
 
 } // namespace Text
 
diff --git a/dali-toolkit/internal/text/text-scroller-data.h b/dali-toolkit/internal/text/text-scroller-data.h
new file mode 100644 (file)
index 0000000..3ba08c9
--- /dev/null
@@ -0,0 +1,62 @@
+#ifndef DALI_TOOLKIT_TEXT_SCROLLER_DATA_H
+#define DALI_TOOLKIT_TEXT_SCROLLER_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.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/math/vector2.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/text-definitions.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+extern const int MINIMUM_SCROLL_SPEED; // Speed should be set by Property system.
+
+/**
+ * @brief Stores the autoscroll data.
+ */
+struct ScrollerData
+{
+  ScrollerData();
+  ~ScrollerData();
+
+  Size               mControlSize;            ///< The size of the control to scroll within.
+  Size               mOffscreenSize;          ///< The size of the sourceActor.
+  int                mScrollSpeed;            ///< Speed which text should automatically scroll at.
+  int                mLoopCount;              ///< Number of time the text should scroll.
+  float              mWrapGap;                ///< Gap before text wraps around when scrolling.
+  float              mAlignmentOffset;        ///< The alignment offset of the first line of text to be scrolled.
+  CharacterDirection mAutoScrollDirectionRTL; ///< Direction of auto scrolling, true if rtl.
+};
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_TEXT_SCROLLER_H
+
index d2f9348..ee1d241 100644 (file)
@@ -31,6 +31,7 @@
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/internal/text/text-scroller-interface.h>
+#include <dali-toolkit/internal/text/text-scroller-data.h>
 
 namespace Dali
 {
@@ -38,6 +39,11 @@ namespace Dali
 namespace Toolkit
 {
 
+namespace Text
+{
+extern const int MINIMUM_SCROLL_SPEED;
+} // namespace
+
 namespace
 {
 
@@ -45,8 +51,6 @@ namespace
   Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, true, "LOG_TEXT_SCROLLING");
 #endif
 
-const int MINIMUM_SCROLL_SPEED = 1; // Speed should be set by Property system.
-
 const char* VERTEX_SHADER_SCROLL = DALI_COMPOSE_SHADER(
   attribute mediump vec2 aPosition;\n
   varying highp vec2 vTexCoord;\n
@@ -195,50 +199,6 @@ TextScrollerPtr TextScroller::New( ScrollerInterface& scrollerInterface )
   return textScroller;
 }
 
-void TextScroller::SetGap( int gap )
-{
-  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextScroller::SetGap gap[%d]\n", gap );
-  mWrapGap = static_cast<float>(gap);
-}
-
-int TextScroller::GetGap() const
-{
-  return static_cast<int>(mWrapGap);
-}
-
-void TextScroller::SetSpeed( int scrollSpeed )
-{
-  mScrollSpeed = std::max( MINIMUM_SCROLL_SPEED, scrollSpeed );
-}
-
-int TextScroller::GetSpeed() const
-{
-  return mScrollSpeed;
-}
-
-void TextScroller::SetLoopCount( int loopCount )
-{
-  if ( loopCount > 0 )
-  {
-    mLoopCount = loopCount;
-  }
-
-  if (  mScrollAnimation && mScrollAnimation.GetState() == Animation::PLAYING )
-  {
-    if ( loopCount == 0 ) // Request to stop looping
-    {
-      DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextScroller::SetLoopCount Single loop forced\n" );
-      mScrollAnimation.SetLoopCount( 1 ); // As animation already playing this allows the current animation to finish instead of trying to stop mid-way
-    }
-  }
-  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextScroller::SetLoopCount [%d] Status[%s]\n", mLoopCount, (loopCount)?"looping":"stop" );
-}
-
-int TextScroller::GetLoopCount() const
-{
-  return mLoopCount;
-}
-
 Actor TextScroller::GetSourceCamera() const
 {
   return mOffscreenCameraActor;
@@ -249,11 +209,9 @@ Actor TextScroller::GetScrollingText() const
   return mScrollingTextActor;
 }
 
-TextScroller::TextScroller( ScrollerInterface& scrollerInterface ) : mScrollerInterface( scrollerInterface ),
-                            mScrollDeltaIndex( Property::INVALID_INDEX ),
-                            mScrollSpeed( MINIMUM_SCROLL_SPEED ),
-                            mLoopCount( 1 ),
-                            mWrapGap( 0.0f )
+TextScroller::TextScroller( ScrollerInterface& scrollerInterface )
+: mScrollerInterface( scrollerInterface ),
+  mScrollDeltaIndex( Property::INVALID_INDEX )
 {
   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextScroller Default Constructor\n" );
 }
@@ -263,49 +221,71 @@ TextScroller::~TextScroller()
   CleanUp();
 }
 
-void TextScroller::SetParameters( Actor sourceActor, const Size& controlSize, const Size& offScreenSize, CharacterDirection direction, float alignmentOffset )
+void TextScroller::StartScrolling( Actor sourceActor,
+                                   const ScrollerData& data )
 {
-  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextScroller::SetParameters controlSize[%f,%f] offscreenSize[%f,%f] direction[%d] alignmentOffset[%f]\n",
-                 controlSize.x, controlSize.y, offScreenSize.x, offScreenSize.y, direction, alignmentOffset );
-
-  FrameBufferImage offscreenRenderTargetForText = FrameBufferImage::New( offScreenSize.width, offScreenSize.height, Pixel::RGBA8888 );
+  DALI_LOG_INFO( gLogFilter,
+                 Debug::Verbose,
+                 "TextScroller::StartScrolling controlSize[%f,%f] offscreenSize[%f,%f] direction[%d] alignmentOffset[%f]\n",
+                 data.mControlSize.x, data.mControlSize.y,
+                 data.mOffscreenSize.x, data.mOffscreenSize.y,
+                 data.mAutoScrollDirectionRTL,
+                 data.mAlignmentOffset );
+
+  FrameBufferImage offscreenRenderTargetForText = FrameBufferImage::New( data.mOffscreenSize.width, data.mOffscreenSize.height, Pixel::RGBA8888 );
   Renderer renderer;
 
-  CreateCameraActor( offScreenSize, mOffscreenCameraActor );
+  CreateCameraActor( data.mOffscreenSize, mOffscreenCameraActor );
   CreateRenderer( offscreenRenderTargetForText, renderer );
   CreateRenderTask( sourceActor, mOffscreenCameraActor, offscreenRenderTargetForText, mRenderTask );
 
   // Reposition camera to match alignment of target, RTL text has direction=true
-  if ( direction )
+  if( data.mAutoScrollDirectionRTL )
   {
-    mOffscreenCameraActor.SetX( alignmentOffset + offScreenSize.width*0.5f );
+    mOffscreenCameraActor.SetX( data.mAlignmentOffset + data.mOffscreenSize.width * 0.5f );
   }
   else
   {
-    mOffscreenCameraActor.SetX( offScreenSize.width * 0.5f );
+    mOffscreenCameraActor.SetX( data.mOffscreenSize.width * 0.5f );
   }
 
-  mOffscreenCameraActor.SetY( offScreenSize.height * 0.5f );
+  mOffscreenCameraActor.SetY( data.mOffscreenSize.height * 0.5f );
 
-  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextScroller::SetParameters mWrapGap[%f]\n", mWrapGap )
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextScroller::SetParameters mWrapGap[%f]\n", data.mWrapGap )
 
   mScrollingTextActor = Actor::New();
   mScrollingTextActor.AddRenderer( renderer );
-  mScrollingTextActor.RegisterProperty( "uTextureSize", offScreenSize );
-  mScrollingTextActor.RegisterProperty( "uRtl", ((direction)?1.0f:0.0f) );
-  mScrollingTextActor.RegisterProperty( "uGap", mWrapGap );
-  mScrollingTextActor.SetSize( controlSize.width, std::min( offScreenSize.height, controlSize.height ) );
+  mScrollingTextActor.RegisterProperty( "uTextureSize", data.mOffscreenSize );
+  mScrollingTextActor.RegisterProperty( "uRtl", ( data.mAutoScrollDirectionRTL ? 1.f : 0.f ) );
+  mScrollingTextActor.RegisterProperty( "uGap", data.mWrapGap );
+  mScrollingTextActor.SetSize( data.mControlSize.width, std::min( data.mOffscreenSize.height, data.mControlSize.height ) );
   mScrollDeltaIndex = mScrollingTextActor.RegisterProperty( "uDelta", 0.0f );
 
-  float scrollAmount = std::max( offScreenSize.width + mWrapGap, controlSize.width );
-  float scrollDuration =  scrollAmount / mScrollSpeed;
+  float scrollAmount = std::max( data.mOffscreenSize.width + data.mWrapGap, data.mControlSize.width );
+  float scrollSpeed = std::max( MINIMUM_SCROLL_SPEED, data.mScrollSpeed );
+  float scrollDuration =  scrollAmount / scrollSpeed;
 
-  if ( direction  )
+  if( data.mAutoScrollDirectionRTL )
   {
      scrollAmount = -scrollAmount; // reverse direction of scrollung
   }
 
-  StartScrolling( scrollAmount, scrollDuration, mLoopCount );
+  mScrollAnimation = Animation::New( scrollDuration );
+  mScrollAnimation.AnimateTo( Property( mScrollingTextActor, mScrollDeltaIndex ), scrollAmount );
+  mScrollAnimation.SetEndAction( Animation::Discard );
+  mScrollAnimation.SetLoopCount( data.mLoopCount );
+  mScrollAnimation.FinishedSignal().Connect( this, &TextScroller::AutoScrollAnimationFinished );
+  mScrollAnimation.Play();
+}
+
+void TextScroller::StopScrolling()
+{
+  if( mScrollAnimation &&
+      ( mScrollAnimation.GetState() == Animation::PLAYING ) )
+  {
+    DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextScroller::SetLoopCount Single loop forced\n" );
+    mScrollAnimation.SetLoopCount( 1 ); // As animation already playing this allows the current animation to finish instead of trying to stop mid-way
+  }
 }
 
 void TextScroller::AutoScrollAnimationFinished( Dali::Animation& animation )
@@ -315,18 +295,6 @@ void TextScroller::AutoScrollAnimationFinished( Dali::Animation& animation )
   mScrollerInterface.ScrollingFinished();
 }
 
-void TextScroller::StartScrolling( float scrollAmount, float scrollDuration, int loopCount )
-{
-  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextScroller::StartScrolling scrollAmount[%f] scrollDuration[%f], loop[%d] speed[%d]\n", scrollAmount, scrollDuration, loopCount, mScrollSpeed );
-
-  mScrollAnimation = Animation::New( scrollDuration );
-  mScrollAnimation.AnimateTo( Property( mScrollingTextActor, mScrollDeltaIndex ), scrollAmount );
-  mScrollAnimation.SetEndAction( Animation::Discard );
-  mScrollAnimation.SetLoopCount( loopCount );
-  mScrollAnimation.FinishedSignal().Connect( this, &TextScroller::AutoScrollAnimationFinished );
-  mScrollAnimation.Play();
-}
-
 void TextScroller::CleanUp()
 {
   if ( Stage::IsInstalled() )
index 17824b6..a40be3f 100644 (file)
@@ -37,6 +37,7 @@ namespace Text
 
 class TextScroller;
 class ScrollerInterface;
+struct ScrollerData;
 
 typedef IntrusivePtr<TextScroller> TextScrollerPtr;
 
@@ -46,7 +47,6 @@ typedef IntrusivePtr<TextScroller> TextScrollerPtr;
 class TextScroller : public RefObject, public ConnectionTracker
 {
 public:
-
   /**
    * @brief Text Scrolling helper, used to automatically scroll text, SetParameters should be called before scrolling is needed.
    * CleanUp removes the Scrolling actors from stage whilst keeping the Scroller object alive and preserving Speed, Gap and Loop count.
@@ -56,52 +56,19 @@ public:
   static TextScrollerPtr New( ScrollerInterface& scrollerInterface );
 
   /**
-   * @brief Set parameters relating to source required for scrolling
+   * @brief Starts the text scrolling.
    *
    * @param[in] sourceActor source actor to be scrolled
-   * @param[in] controlSize size of the control to scroll within
-   * @param[in] offScreenSize size of the sourceActor
-   * @param[in] direction text direction true for right to left text
-   * @param[in] alignmentOffset alignment of source text
+   * @param[in] data Parameters needed to set up the text scrolling.
    *
    */
-  void SetParameters( Actor sourceActor, const Size& controlSize, const Size& offScreenSize, CharacterDirection direction, float alignmentOffset );
-
-  /**
-   * @brief Set the gap distance to elapse before the text wraps around
-   * @param[in] gap distance to elapse
-   */
-  void SetGap( int gap );
-
-  /**
-   * @brief Get the distance before scrolling wraps
-   * @return gap distance to elapse
-   */
-  int GetGap() const;
-
-  /**
-   * @brief Set speed the text should scroll
-   * @param[in] scrollSpeed pixels per second
-   */
-  void SetSpeed( int scrollSpeed );
+  void StartScrolling( Actor sourceActor,
+                       const ScrollerData& data );
 
   /**
-   * @brief Get the speed of text scrolling
-   * @return speed in pixels per second
+   * @brief Stops the text scrolling.
    */
-  int GetSpeed() const;
-
-  /**
-   * @brief Set the number of times the text scrolling should loop, can stop current scrolling by passing in 0;
-   * @param[in] loopCount number of times the scrolled text should loop, 0 to stop scrolling
-   */
-  void SetLoopCount( int loopCount );
-
-  /**
-   * @brief Get the number of loops
-   * @return int number of loops
-   */
-  int GetLoopCount() const;
+  void StopScrolling();
 
   /**
    * @brief Get the camera used to look at source, should be added to the parent of target actor.
@@ -140,14 +107,6 @@ private: // Implementation
   void AutoScrollAnimationFinished( Dali::Animation& animation );
 
   /**
-   * @brief variables required to set up scrolling animation
-   * @param[in] scrollAmount distance to animate text for the given duration
-   * @param[in] scrollDuration duration of aninmation
-   * @param[in] loopCount number of times to loop the scrolling text
-   */
-  void StartScrolling( float scrollAmount, float scrollDuration, int loopCount );
-
-  /**
    * @brief When scrolling ended, the actors are cleaned up so no longer staged.
    */
   void CleanUp();
@@ -161,10 +120,6 @@ private:
   Property::Index    mScrollDeltaIndex;         // Property used by shader to represent distance to scroll
   Animation          mScrollAnimation;          // Animation used to update the mScrollDeltaIndex
 
-  int   mScrollSpeed;            ///< Speed which text should automatically scroll at
-  int   mLoopCount;              ///< Number of time the text should scroll
-  float mWrapGap;                ///< Gap before text wraps around when scrolling
-
 }; // TextScroller class
 
 } // namespace Text
index 7f7c7b5..764d178 100644 (file)
@@ -102,6 +102,11 @@ const char* FRAGMENT_SHADER_ANTI_ALIASING = DALI_COMPOSE_SHADER(
 );
 }
 
+BorderVisualPtr BorderVisual::New( VisualFactoryCache& factoryCache )
+{
+  return new BorderVisual( factoryCache );
+}
+
 BorderVisual::BorderVisual( VisualFactoryCache& factoryCache )
 : Visual::Base( factoryCache ),
   mBorderColor( Color::TRANSPARENT ),
@@ -116,7 +121,7 @@ BorderVisual::~BorderVisual()
 {
 }
 
-void BorderVisual::DoInitialize( Actor& actor, const Property::Map& propertyMap )
+void BorderVisual::DoSetProperties( const Property::Map& propertyMap )
 {
   Property::Value* color = propertyMap.Find( Toolkit::BorderVisual::Property::COLOR, COLOR_NAME );
   if( !( color && color->Get(mBorderColor) ) )
@@ -160,6 +165,17 @@ void BorderVisual::DoCreatePropertyMap( Property::Map& map ) const
   map.Insert( Toolkit::BorderVisual::Property::ANTI_ALIASING, mAntiAliasing );
 }
 
+void BorderVisual::DoSetProperty( Dali::Property::Index index, const Dali::Property::Value& propertyValue )
+{
+  // TODO
+}
+
+Dali::Property::Value BorderVisual::DoGetProperty( Dali::Property::Index index )
+{
+  // TODO
+  return Dali::Property::Value();
+}
+
 void BorderVisual::InitializeRenderer()
 {
   Geometry geometry = mFactoryCache.GetGeometry( VisualFactoryCache::BORDER_GEOMETRY );
index 8a44250..4f999b4 100644 (file)
@@ -20,6 +20,7 @@
 
 // EXTERNAL INCLUDES
 #include <dali/public-api/rendering/geometry.h>
+#include <dali/public-api/common/intrusive-ptr.h>
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/internal/visuals/visual-base-impl.h>
@@ -33,6 +34,9 @@ namespace Toolkit
 namespace Internal
 {
 
+class BorderVisual;
+typedef IntrusivePtr< BorderVisual > BorderVisualPtr;
+
 /**
  * The visual which renders a solid color to the control's quad border fixed to a specified size.
  *
@@ -44,12 +48,21 @@ namespace Internal
  * | borderSize      | FLOAT       |
  * | antiAliasing    | BOOLEAN     |
  */
-
 class BorderVisual : public Visual::Base
 {
 public:
 
   /**
+   * @brief Create a new border visual.
+   *
+   * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object
+   * @return A smart-pointer to the newly allocated visual.
+   */
+  static BorderVisualPtr New( VisualFactoryCache& factoryCache );
+
+protected:
+
+  /**
    * @brief Constructor.
    *
    * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object
@@ -61,12 +74,10 @@ public:
    */
   virtual ~BorderVisual();
 
-protected:
-
   /**
-   * @copydoc Visual::Base::DoInitialize
+   * @copydoc Visual::Base::DoSetProperties
    */
-  virtual void DoInitialize( Actor& actor, const Property::Map& propertyMap );
+  virtual void DoSetProperties( const Property::Map& propertyMap );
 
   /**
    * @copydoc Visual::Base::DoSetOnStage
@@ -78,6 +89,16 @@ protected:
    */
   virtual void DoCreatePropertyMap( Property::Map& map ) const;
 
+  /**
+   * @copydoc Visual::Base::DoSetProperty
+   */
+  virtual void DoSetProperty( Dali::Property::Index index, const Dali::Property::Value& propertyValue );
+
+  /**
+   * @copydoc Visual::Base::DoGetProperty
+   */
+  virtual Dali::Property::Value DoGetProperty( Dali::Property::Index index );
+
 public:
 
   /**
index 6406bcc..cbe0036 100644 (file)
@@ -65,6 +65,11 @@ const char* FRAGMENT_SHADER = DALI_COMPOSE_SHADER(
 );
 }
 
+ColorVisualPtr ColorVisual::New( VisualFactoryCache& factoryCache )
+{
+  return new ColorVisual( factoryCache );
+}
+
 ColorVisual::ColorVisual( VisualFactoryCache& factoryCache )
 : Visual::Base( factoryCache ),
   mMixColorIndex( Property::INVALID_INDEX )
@@ -75,7 +80,7 @@ ColorVisual::~ColorVisual()
 {
 }
 
-void ColorVisual::DoInitialize( Actor& actor, const Property::Map& propertyMap )
+void ColorVisual::DoSetProperties( const Property::Map& propertyMap )
 {
   Property::Value* color = propertyMap.Find( Toolkit::ColorVisual::Property::MIX_COLOR, COLOR_NAME );
   if( !( color && color->Get(mMixColor) ) )
@@ -105,6 +110,27 @@ void ColorVisual::DoCreatePropertyMap( Property::Map& map ) const
   map.Insert( Toolkit::ColorVisual::Property::MIX_COLOR, mMixColor );
 }
 
+void ColorVisual::DoSetProperty( Dali::Property::Index index, const Dali::Property::Value& propertyValue )
+{
+  // TODO
+  /* David Steele comented :
+
+     Some things to bear in mind:
+
+     We currently keep a copy of the mix color in the ColorVisual object, which is then used to instantiate the registered property on the renderer.
+
+     The user can get the renderer and animate the mixColor property (it's registered, so is automatically a scene-graph property).
+
+     The GetProperty method will have to read from the renderer, or from the cached value in the Visual, and the SetProperty will have to write to cache and to the renderer if present.
+  */
+}
+
+Dali::Property::Value ColorVisual::DoGetProperty( Dali::Property::Index index )
+{
+  // TODO
+  return Dali::Property::Value();
+}
+
 void ColorVisual::InitializeRenderer()
 {
   Geometry geometry = mFactoryCache.GetGeometry( VisualFactoryCache::QUAD_GEOMETRY );
index 2805d6a..cf2b057 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_INTERNAL_COLOR_VISUAL_H
 
 /*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ * 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.
@@ -18,6 +18,9 @@
  *
  */
 
+// EXTERNAL INCLUDES
+#include <dali/public-api/common/intrusive-ptr.h>
+
 // INTERNAL INCLUDES
 #include <dali-toolkit/internal/visuals/visual-base-impl.h>
 
@@ -30,6 +33,9 @@ namespace Toolkit
 namespace Internal
 {
 
+class ColorVisual;
+typedef IntrusivePtr< ColorVisual > ColorVisualPtr;
+
 /**
  * The visual which renders a solid color to the control's quad
  *
@@ -44,16 +50,12 @@ class ColorVisual: public Visual::Base
 public:
 
   /**
-   * @brief Constructor.
+   * @brief Create a new color visual.
    *
    * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object
+   * @return A smart-pointer to the newly allocated visual.
    */
-  ColorVisual( VisualFactoryCache& factoryCache );
-
-  /**
-   * @brief A reference counted object may only be deleted by calling Unreference().
-   */
-  virtual ~ColorVisual();
+  static ColorVisualPtr New( VisualFactoryCache& factoryCache );
 
 public:  // from Visual
 
@@ -67,12 +69,34 @@ public:  // from Visual
    */
   virtual void DoCreatePropertyMap( Property::Map& map ) const;
 
+  /**
+   * @copydoc Visual::Base::DoSetProperty
+   */
+  virtual void DoSetProperty( Dali::Property::Index index, const Dali::Property::Value& propertyValue );
+
+  /**
+   * @copydoc Visual::Base::DoGetProperty
+   */
+  virtual Dali::Property::Value DoGetProperty( Dali::Property::Index index );
+
 protected:
 
   /**
-   * @copydoc Visual::Base::DoInitialize
+   * @brief Constructor.
+   *
+   * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object
+   */
+  ColorVisual( VisualFactoryCache& factoryCache );
+
+  /**
+   * @brief A reference counted object may only be deleted by calling Unreference().
+   */
+  virtual ~ColorVisual();
+
+  /**
+   * @copydoc Visual::Base::DoSetProperties
    */
-  virtual void DoInitialize( Actor& actor, const Property::Map& propertyMap );
+  virtual void DoSetProperties( const Property::Map& propertyMap );
 
   /**
    * @copydoc Visual::Base::DoSetOnStage
index 41999cc..ee2b150 100644 (file)
@@ -185,6 +185,10 @@ Dali::WrapMode::Type GetWrapMode( Toolkit::GradientVisual::SpreadMethod::Type sp
 
 } // unnamed namespace
 
+GradientVisualPtr GradientVisual::New( VisualFactoryCache& factoryCache )
+{
+  return new GradientVisual( factoryCache );
+}
 
 GradientVisual::GradientVisual( VisualFactoryCache& factoryCache )
 : Visual::Base( factoryCache ),
@@ -197,7 +201,7 @@ GradientVisual::~GradientVisual()
 {
 }
 
-void GradientVisual::DoInitialize( Actor& actor, const Property::Map& propertyMap )
+void GradientVisual::DoSetProperties( const Property::Map& propertyMap )
 {
   Toolkit::GradientVisual::Units::Type gradientUnits = Toolkit::GradientVisual::Units::OBJECT_BOUNDING_BOX;
 
@@ -279,6 +283,17 @@ void GradientVisual::DoCreatePropertyMap( Property::Map& map ) const
   }
 }
 
+void GradientVisual::DoSetProperty( Dali::Property::Index index, const Dali::Property::Value& propertyValue )
+{
+  // TODO
+}
+
+Dali::Property::Value GradientVisual::DoGetProperty( Dali::Property::Index index )
+{
+  // TODO
+  return Dali::Property::Value();
+}
+
 void GradientVisual::InitializeRenderer()
 {
   Geometry geometry = mFactoryCache.GetGeometry( VisualFactoryCache::QUAD_GEOMETRY );
index 2f5d06c..f7f47ee 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_INTERNAL_GRADIENT_VISUAL_H
 
 /*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ * 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.
@@ -18,6 +18,9 @@
  *
  */
 
+// EXTERNAL INCLUDES
+#include <dali/public-api/common/intrusive-ptr.h>
+
 // INTERNAL INCLUDES
 #include <dali-toolkit/internal/visuals/visual-base-impl.h>
 #include <dali-toolkit/internal/visuals/gradient/gradient.h>
@@ -33,6 +36,8 @@ namespace Internal
 {
 
 class Gradient;
+class GradientVisual;
+typedef IntrusivePtr< GradientVisual > GradientVisualPtr;
 
 /**
  * The visual which renders smooth transition of colors to the control's quad.
@@ -80,16 +85,12 @@ public:
   };
 
   /**
-   * @brief Constructor.
+   * @brief Create a new gradient visual.
    *
    * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object
+   * @return A smart-pointer to the newly allocated visual.
    */
-  GradientVisual( VisualFactoryCache& factoryCache );
-
-  /**
-   * @brief A reference counted object may only be deleted by calling Unreference().
-   */
-  ~GradientVisual();
+  static GradientVisualPtr New( VisualFactoryCache& factoryCache );
 
 public:  // from Visual
 
@@ -103,11 +104,34 @@ public:  // from Visual
    */
   virtual void DoCreatePropertyMap( Property::Map& map ) const;
 
+  /**
+   * @copydoc Visual::Base::DoSetProperty
+   */
+  virtual void DoSetProperty( Dali::Property::Index index, const Dali::Property::Value& propertyValue );
+
+  /**
+   * @copydoc Visual::Base::DoGetProperty
+   */
+  virtual Dali::Property::Value DoGetProperty( Dali::Property::Index index );
+
 protected:
+
+  /**
+   * @brief Constructor.
+   *
+   * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object
+   */
+  GradientVisual( VisualFactoryCache& factoryCache );
+
+  /**
+   * @brief A reference counted object may only be deleted by calling Unreference().
+   */
+  virtual ~GradientVisual();
+
   /**
-   * @copydoc Visual::Base::DoInitialize
+   * @copydoc Visual::Base::DoSetProperties
    */
-  virtual void DoInitialize( Actor& actor, const Property::Map& propertyMap );
+  virtual void DoSetProperties( const Property::Map& propertyMap );
 
   /**
    * @copydoc Visual::Base::DoSetOnStage
index 66897e4..fe01571 100644 (file)
@@ -51,7 +51,8 @@ TextureSet ImageAtlasManager::Add( Vector4& textureRect,
                                  const std::string& url,
                                  ImageDimensions size,
                                  FittingMode::Type fittingMode,
-                                 bool orientationCorrection )
+                                 bool orientationCorrection,
+                                 AtlasUploadObserver* atlasUploadObserver )
 {
   ImageDimensions dimensions = size;
   ImageDimensions zero;
@@ -71,7 +72,7 @@ TextureSet ImageAtlasManager::Add( Vector4& textureRect,
   unsigned int i = 0;
   for( AtlasContainer::iterator iter = mAtlasList.begin(); iter != mAtlasList.end(); ++iter)
   {
-    if( (*iter).Upload( textureRect, url, size, fittingMode, orientationCorrection ) )
+    if( (*iter).Upload( textureRect, url, size, fittingMode, orientationCorrection, atlasUploadObserver ) )
     {
       return mTextureSetList[i];
     }
@@ -79,12 +80,12 @@ TextureSet ImageAtlasManager::Add( Vector4& textureRect,
   }
 
   CreateNewAtlas();
-  mAtlasList.back().Upload( textureRect, url, size, fittingMode, orientationCorrection );
+  mAtlasList.back().Upload( textureRect, url, size, fittingMode, orientationCorrection, atlasUploadObserver );
   return mTextureSetList.back();
 }
 
 TextureSet ImageAtlasManager::Add( Vector4& textureRect,
-                                 PixelData pixelData )
+                                   PixelData pixelData )
 {
 
   // big buffer, atlasing is not applied
index 4586236..5907ca2 100644 (file)
@@ -32,6 +32,8 @@ namespace Dali
 namespace Toolkit
 {
 
+class AtlasUploadObserver;
+
 namespace Internal
 {
 
@@ -65,14 +67,15 @@ public:
    * @param [in] size The width and height to fit the loaded image to.
    * @param [in] fittingMode The method used to fit the shape of the image before loading to the shape defined by the size parameter.
    * @param [in] orientationCorrection Reorient the image to respect any orientation metadata in its header.
+   * @param [in] atlasUploadObserver The object to observe the uploading state inside ImageAtlas.
    * @return The texture set containing the image.
    */
   TextureSet Add( Vector4& textureRect,
-                const std::string& url,
-                ImageDimensions size = ImageDimensions(),
-                FittingMode::Type fittingMode = FittingMode::DEFAULT,
-                bool orientationCorrection = true );
-
+                  const std::string& url,
+                  ImageDimensions size = ImageDimensions(),
+                  FittingMode::Type fittingMode = FittingMode::DEFAULT,
+                  bool orientationCorrection = true,
+                  AtlasUploadObserver* atlasUploadObserver = NULL );
   /**
    * @brief Add a pixel buffer to the atlas
    *
index 10418b7..eecef34 100644 (file)
@@ -85,11 +85,16 @@ const char* FRAGMENT_SHADER = DALI_COMPOSE_SHADER(
   }\n
 );
 
-} //unnamed namespace
+} // unnamed namespace
+
+BatchImageVisualPtr BatchImageVisual::New( VisualFactoryCache& factoryCache )
+{
+  return new BatchImageVisual( factoryCache );
+}
 
 BatchImageVisual::BatchImageVisual( VisualFactoryCache& factoryCache )
-  : Visual::Base( factoryCache ),
-    mDesiredSize()
+: Visual::Base( factoryCache ),
+  mDesiredSize()
 {
 }
 
@@ -97,7 +102,7 @@ BatchImageVisual::~BatchImageVisual()
 {
 }
 
-void BatchImageVisual::DoInitialize( Actor& actor, const Property::Map& propertyMap )
+void BatchImageVisual::DoSetProperties( const Property::Map& propertyMap )
 {
   std::string oldImageUrl = mImageUrl;
   Property::Value* imageURLValue = propertyMap.Find( Dali::Toolkit::ImageVisual::Property::URL, Dali::Toolkit::Internal::IMAGE_URL_NAME );
@@ -122,25 +127,6 @@ void BatchImageVisual::DoInitialize( Actor& actor, const Property::Map& property
 
     mDesiredSize = ImageDimensions( desiredWidth, desiredHeight );
   }
-
-  // Remove old renderer if exit.
-  if( mImpl->mRenderer )
-  {
-    if( actor ) // Remove old renderer from actor.
-    {
-      actor.RemoveRenderer( mImpl->mRenderer );
-    }
-    if( !oldImageUrl.empty() ) // Clean old renderer from cache.
-    {
-      CleanCache( oldImageUrl );
-    }
-  }
-
-  // If actor is on stage, create new renderer and apply to actor.
-  if( actor && actor.OnStage() )
-  {
-    SetOnStage( actor );
-  }
 }
 
 void BatchImageVisual::SetSize( const Vector2& size )
@@ -259,6 +245,17 @@ void BatchImageVisual::DoCreatePropertyMap( Property::Map& map ) const
   }
 }
 
+void BatchImageVisual::DoSetProperty( Dali::Property::Index index, const Dali::Property::Value& propertyValue )
+{
+  // TODO
+}
+
+Dali::Property::Value BatchImageVisual::DoGetProperty( Dali::Property::Index index )
+{
+  // TODO
+  return Dali::Property::Value();
+}
+
 Shader BatchImageVisual::GetBatchShader( VisualFactoryCache& factoryCache )
 {
   Shader shader = factoryCache.GetShader( VisualFactoryCache::BATCH_IMAGE_SHADER );
index 646dad7..be84aab 100644 (file)
  *
  */
 
+// EXTERNAL INCLUDES
+#include <dali/public-api/common/intrusive-ptr.h>
+
 // INTERNAL HEADER
 #include <dali-toolkit/internal/visuals/visual-base-impl.h>
 #include <dali-toolkit/internal/visuals/image-atlas-manager.h>
 
-// EXTERNAL INCLUDES
-#include <dali/public-api/images/resource-image.h>
-
 namespace Dali
 {
 namespace Toolkit
@@ -32,21 +32,20 @@ namespace Toolkit
 namespace Internal
 {
 
+class BatchImageVisual;
+typedef IntrusivePtr< BatchImageVisual > BatchImageVisualPtr;
+
 class BatchImageVisual: public Visual::Base, public ConnectionTracker
 {
 public:
 
   /**
-   * @brief Constructor.
+   * @brief Create a new batch-image visual.
    *
-   * @param[in] factoryCache The VisualFactoryCache object
-   */
-  BatchImageVisual( VisualFactoryCache& factoryCache );
-
-  /**
-   * @brief A reference counted object may only be deleted by calling Unreference().
+   * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object
+   * @return A smart-pointer to the newly allocated visual.
    */
-  ~BatchImageVisual();
+  static BatchImageVisualPtr New( VisualFactoryCache& factoryCache );
 
 public:  // from Visual
 
@@ -65,12 +64,34 @@ public:  // from Visual
    */
   virtual void DoCreatePropertyMap( Property::Map& map ) const;
 
+  /**
+   * @copydoc Visual::Base::DoSetProperty
+   */
+  virtual void DoSetProperty( Dali::Property::Index index, const Dali::Property::Value& propertyValue );
+
+  /**
+   * @copydoc Visual::Base::DoGetProperty
+   */
+  virtual Dali::Property::Value DoGetProperty( Dali::Property::Index index );
+
 protected:
 
   /**
-   * @copydoc Visua::Base::DoInitialize
+   * @brief Constructor.
+   *
+   * @param[in] factoryCache The VisualFactoryCache object
+   */
+  BatchImageVisual( VisualFactoryCache& factoryCache );
+
+  /**
+   * @brief A reference counted object may only be deleted by calling Unreference().
+   */
+  ~BatchImageVisual();
+
+  /**
+   * @copydoc Visua::Base::DoSetProperties
    */
-  virtual void DoInitialize( Actor& actor, const Property::Map& propertyMap );
+  virtual void DoSetProperties( const Property::Map& propertyMap );
 
   /**
    * @copydoc Visual::Base::DoSetOnStage
index 540f7c2..21bbc63 100644 (file)
@@ -16,7 +16,7 @@
  */
 
 // CLASS HEADER
-#include "image-visual.h"
+#include <dali-toolkit/internal/visuals/image/image-visual.h>
 
 // EXTERNAL HEADER
 #include <cstring> // for strncasecmp
@@ -186,29 +186,82 @@ Geometry CreateGeometry( VisualFactoryCache& factoryCache, ImageDimensions gridS
   return geometry;
 }
 
-} //unnamed namespace
+} // unnamed namespace
+
+ImageVisualPtr ImageVisual::New( VisualFactoryCache& factoryCache )
+{
+  return new ImageVisual( factoryCache );
+}
+
+ImageVisualPtr ImageVisual::New( VisualFactoryCache& factoryCache,
+                                 const std::string& imageUrl,
+                                 ImageDimensions size,
+                                 FittingMode::Type fittingMode,
+                                 Dali::SamplingMode::Type samplingMode )
+{
+  return new ImageVisual( factoryCache, imageUrl, size, fittingMode, samplingMode );
+}
+
+ImageVisualPtr ImageVisual::New( VisualFactoryCache& factoryCache, const Image& image )
+{
+  return new ImageVisual( factoryCache, image );
+}
 
 ImageVisual::ImageVisual( VisualFactoryCache& factoryCache )
 : Visual::Base( factoryCache ),
+  mImage(),
+  mPixels(),
   mPixelArea( FULL_TEXTURE_RECT ),
+  mPlacementActor(),
+  mImageUrl(),
   mDesiredSize(),
   mFittingMode( FittingMode::DEFAULT ),
   mSamplingMode( SamplingMode::DEFAULT ),
   mWrapModeU( WrapMode::DEFAULT ),
-  mWrapModeV( WrapMode::DEFAULT ),
-  mNativeFragmentShaderCode( ),
-  mNativeImageFlag( false )
+  mWrapModeV( WrapMode::DEFAULT )
 {
 }
 
-ImageVisual::~ImageVisual()
+ImageVisual::ImageVisual( VisualFactoryCache& factoryCache,
+                          const std::string& imageUrl,
+                          ImageDimensions size,
+                          FittingMode::Type fittingMode,
+                          Dali::SamplingMode::Type samplingMode )
+: Visual::Base( factoryCache ),
+  mImage(),
+  mPixels(),
+  mPixelArea( FULL_TEXTURE_RECT ),
+  mPlacementActor(),
+  mImageUrl( imageUrl ),
+  mDesiredSize( size ),
+  mFittingMode( fittingMode ),
+  mSamplingMode( samplingMode ),
+  mWrapModeU( WrapMode::DEFAULT ),
+  mWrapModeV( WrapMode::DEFAULT )
 {
 }
 
-void ImageVisual::DoInitialize( Actor& actor, const Property::Map& propertyMap )
+ImageVisual::ImageVisual( VisualFactoryCache& factoryCache, const Image& image )
+: Visual::Base( factoryCache ),
+  mImage( image ),
+  mPixels(),
+  mPixelArea( FULL_TEXTURE_RECT ),
+  mPlacementActor(),
+  mImageUrl(),
+  mDesiredSize(),
+  mFittingMode( FittingMode::DEFAULT ),
+  mSamplingMode( SamplingMode::DEFAULT ),
+  mWrapModeU( WrapMode::DEFAULT ),
+  mWrapModeV( WrapMode::DEFAULT )
 {
-  std::string oldImageUrl = mImageUrl;
+}
 
+ImageVisual::~ImageVisual()
+{
+}
+
+void ImageVisual::DoSetProperties( const Property::Map& propertyMap )
+{
   Property::Value* imageURLValue = propertyMap.Find( Toolkit::ImageVisual::Property::URL, IMAGE_URL_NAME );
   if( imageURLValue )
   {
@@ -221,13 +274,17 @@ void ImageVisual::DoInitialize( Actor& actor, const Property::Map& propertyMap )
     Property::Value* fittingValue = propertyMap.Find( Toolkit::ImageVisual::Property::FITTING_MODE, IMAGE_FITTING_MODE );
     if( fittingValue )
     {
-      Scripting::GetEnumerationProperty( *fittingValue, FITTING_MODE_TABLE, FITTING_MODE_TABLE_COUNT, mFittingMode );
+      int value;
+      Scripting::GetEnumerationProperty( *fittingValue, FITTING_MODE_TABLE, FITTING_MODE_TABLE_COUNT, value );
+      mFittingMode = Dali::FittingMode::Type( value );
     }
 
     Property::Value* samplingValue = propertyMap.Find( Toolkit::ImageVisual::Property::SAMPLING_MODE, IMAGE_SAMPLING_MODE );
     if( samplingValue )
     {
-      Scripting::GetEnumerationProperty( *samplingValue, SAMPLING_MODE_TABLE, SAMPLING_MODE_TABLE_COUNT, mSamplingMode );
+      int value;
+      Scripting::GetEnumerationProperty( *samplingValue, SAMPLING_MODE_TABLE, SAMPLING_MODE_TABLE_COUNT, value );
+      mSamplingMode = Dali::SamplingMode::Type( value );
     }
 
     int desiredWidth = 0;
@@ -253,13 +310,17 @@ void ImageVisual::DoInitialize( Actor& actor, const Property::Map& propertyMap )
     Property::Value* wrapModeValueU = propertyMap.Find( Toolkit::ImageVisual::Property::WRAP_MODE_U, IMAGE_WRAP_MODE_U );
     if( wrapModeValueU )
     {
-      Scripting::GetEnumerationProperty( *wrapModeValueU, WRAP_MODE_TABLE, WRAP_MODE_TABLE_COUNT, mWrapModeU );
+      int value;
+      Scripting::GetEnumerationProperty( *wrapModeValueU, WRAP_MODE_TABLE, WRAP_MODE_TABLE_COUNT, value );
+      mWrapModeU = Dali::WrapMode::Type( value );
     }
 
     Property::Value* wrapModeValueV = propertyMap.Find( Toolkit::ImageVisual::Property::WRAP_MODE_V, IMAGE_WRAP_MODE_V );
     if( wrapModeValueV )
     {
-      Scripting::GetEnumerationProperty( *wrapModeValueV, WRAP_MODE_TABLE, WRAP_MODE_TABLE_COUNT, mWrapModeV );
+      int value;
+      Scripting::GetEnumerationProperty( *wrapModeValueV, WRAP_MODE_TABLE, WRAP_MODE_TABLE_COUNT, value );
+      mWrapModeV = Dali::WrapMode::Type( value );
     }
 
     mDesiredSize = ImageDimensions( desiredWidth, desiredHeight );
@@ -273,45 +334,18 @@ void ImageVisual::DoInitialize( Actor& actor, const Property::Map& propertyMap )
     if( sync )
     {
       mImpl->mFlags |= Impl::IS_SYNCHRONOUS_RESOURCE_LOADING;
+      // if sync loading is required, the loading should start immediately when new image url is set or the actor is off stage
+      // ( for on-stage actor with image url unchanged, resource loading is already finished)
+      if( imageURLValue )
+      {
+        LoadResourceSynchronously();
+      }
     }
     else
     {
       mImpl->mFlags &= ~Impl::IS_SYNCHRONOUS_RESOURCE_LOADING;
     }
   }
-
-  // if sync loading is required, the loading should start immediately when new image url is set or the actor is off stage
-  // ( for on-stage actor with image url unchanged, resource loading is already finished)
-  if( ( !mImpl->mRenderer || imageURLValue) && IsSynchronousResourceLoading() )
-  {
-    DoSynchronousResourceLoading();
-  }
-
-  // remove old renderer if exit
-  if( mImpl->mRenderer )
-  {
-    if( actor ) //remove old renderer from actor
-    {
-      actor.RemoveRenderer( mImpl->mRenderer );
-    }
-    if( !oldImageUrl.empty() ) //clean old renderer from cache
-    {
-      CleanCache( oldImageUrl );
-    }
-  }
-
-  NativeImage nativeImage = NativeImage::DownCast( mImage );
-
-  if( nativeImage )
-  {
-    SetNativeFragmentShaderCode( nativeImage );
-  }
-
-  // if actor is on stage, create new renderer and apply to actor
-  if( actor && actor.OnStage() )
-  {
-    SetOnStage( actor );
-  }
 }
 
 void ImageVisual::GetNaturalSize( Vector2& naturalSize ) const
@@ -339,18 +373,11 @@ void ImageVisual::GetNaturalSize( Vector2& naturalSize ) const
   naturalSize = Vector2::ZERO;
 }
 
-Renderer ImageVisual::CreateRenderer() const
+void ImageVisual::CreateRenderer( TextureSet& textures )
 {
   Geometry geometry;
   Shader shader;
 
-  // If mImage is nativeImage with custom sampler or prefix, mNativeFragmentShaderCode will be applied.
-  // Renderer can't be shared between NativeImage and other image types.
-  if( !mNativeFragmentShaderCode.empty() )
-  {
-    return CreateNativeImageRenderer();
-  }
-
   if( !mImpl->mCustomShader )
   {
     geometry = CreateGeometry( mFactoryCache, ImageDimensions( 1, 1 ) );
@@ -364,7 +391,7 @@ Renderer ImageVisual::CreateRenderer() const
     geometry = CreateGeometry( mFactoryCache, mImpl->mCustomShader->mGridSize );
     if( mImpl->mCustomShader->mVertexShader.empty() && mImpl->mCustomShader->mFragmentShader.empty() )
     {
-      shader = GetImageShader(mFactoryCache, false, true);
+      shader = GetImageShader( mFactoryCache, false, true );
     }
     else
     {
@@ -378,28 +405,49 @@ Renderer ImageVisual::CreateRenderer() const
     }
   }
 
-  Renderer renderer = Renderer::New( geometry, shader );
-
-  return renderer;
+  mImpl->mRenderer = Renderer::New( geometry, shader );
+  DALI_ASSERT_DEBUG( textures );
+  mImpl->mRenderer.SetTextures( textures );
 }
 
-Renderer ImageVisual::CreateNativeImageRenderer() const
+void ImageVisual::CreateNativeImageRenderer( NativeImage& nativeImage )
 {
   Geometry geometry;
   Shader shader;
 
+  std::string fragmentShader;
+  const char* fragmentPreFix = nativeImage.GetCustomFragmentPreFix();
+  const char* customSamplerTypename = nativeImage.GetCustomSamplerTypename();
+  if( fragmentPreFix )
+  {
+    fragmentShader = fragmentPreFix;
+    fragmentShader += "\n";
+  }
+  if( mImpl->mCustomShader && !mImpl->mCustomShader->mFragmentShader.empty() )
+  {
+    fragmentShader += mImpl->mCustomShader->mFragmentShader;
+  }
+  else
+  {
+    fragmentShader += FRAGMENT_SHADER_NO_ATLAS;
+  }
+  if( customSamplerTypename )
+  {
+    fragmentShader.replace( fragmentShader.find( DEFAULT_SAMPLER_TYPENAME ), strlen( DEFAULT_SAMPLER_TYPENAME ), customSamplerTypename );
+  }
+
   if( !mImpl->mCustomShader )
   {
     geometry = CreateGeometry( mFactoryCache, ImageDimensions( 1, 1 ) );
 
-    shader  = Shader::New( VERTEX_SHADER, mNativeFragmentShaderCode );
+    shader  = Shader::New( VERTEX_SHADER, fragmentShader );
     shader.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT );
   }
   else
   {
     geometry = CreateGeometry( mFactoryCache, mImpl->mCustomShader->mGridSize );
     shader  = Shader::New( mImpl->mCustomShader->mVertexShader.empty() ? VERTEX_SHADER : mImpl->mCustomShader->mVertexShader,
-                           mNativeFragmentShaderCode,
+                           fragmentShader,
                            mImpl->mCustomShader->mHints );
     if( mImpl->mCustomShader->mVertexShader.empty() )
     {
@@ -407,10 +455,7 @@ Renderer ImageVisual::CreateNativeImageRenderer() const
     }
   }
 
-  TextureSet textureSet = TextureSet::New();
-  Renderer renderer = Renderer::New( geometry, shader );
-  renderer.SetTextures( textureSet );
-  return renderer;
+  mImpl->mRenderer = Renderer::New( geometry, shader );
 }
 
 
@@ -419,7 +464,7 @@ bool ImageVisual::IsSynchronousResourceLoading() const
   return mImpl->mFlags & Impl::IS_SYNCHRONOUS_RESOURCE_LOADING;
 }
 
-void ImageVisual::DoSynchronousResourceLoading()
+void ImageVisual::LoadResourceSynchronously()
 {
   if( !mImageUrl.empty() )
   {
@@ -429,28 +474,7 @@ void ImageVisual::DoSynchronousResourceLoading()
   }
 }
 
-Image ImageVisual::LoadImage( const std::string& url, bool synchronousLoading )
-{
-  if( synchronousLoading )
-  {
-    if( !mPixels )
-    {
-      // use broken image
-      return VisualFactoryCache::GetBrokenVisualImage();
-    }
-    Atlas image = Atlas::New( mPixels.GetWidth(), mPixels.GetHeight(), mPixels.GetPixelFormat() );
-    image.Upload( mPixels, 0, 0 );
-    return image;
-  }
-  else
-  {
-    ResourceImage resourceImage = Dali::ResourceImage::New( url, mDesiredSize, mFittingMode, mSamplingMode );
-    resourceImage.LoadingFinishedSignal().Connect( this, &ImageVisual::OnImageLoaded );
-    return resourceImage;
-  }
-}
-
-TextureSet ImageVisual::CreateTextureSet( Vector4& textureRect, const std::string& url, bool synchronousLoading )
+TextureSet ImageVisual::CreateTextureSet( Vector4& textureRect, const std::string& url, bool synchronousLoading, bool attemptAtlasing )
 {
   TextureSet textureSet;
   textureRect = FULL_TEXTURE_RECT;
@@ -464,23 +488,30 @@ TextureSet ImageVisual::CreateTextureSet( Vector4& textureRect, const std::strin
     }
     else
     {
-      textureSet = mFactoryCache.GetAtlasManager()->Add(textureRect, mPixels );
-      mImpl->mFlags |= Impl::IS_ATLASING_APPLIED;
-      if( !textureSet ) // big image, no atlasing
+      if( attemptAtlasing )
+      {
+        textureSet = mFactoryCache.GetAtlasManager()->Add(textureRect, mPixels );
+        mImpl->mFlags |= Impl::IS_ATLASING_APPLIED;
+      }
+      if( !textureSet ) // big image, no atlasing or atlasing failed
       {
         mImpl->mFlags &= ~Impl::IS_ATLASING_APPLIED;
-        Atlas image = Atlas::New( mPixels.GetWidth(), mPixels.GetHeight(), mPixels.GetPixelFormat() );
-        image.Upload( mPixels, 0, 0 );
+        Texture texture = Texture::New( Dali::TextureType::TEXTURE_2D, mPixels.GetPixelFormat(),
+                                        mPixels.GetWidth(), mPixels.GetHeight() );
+        texture.Upload( mPixels );
         textureSet = TextureSet::New();
-        TextureSetImage( textureSet, 0u, image );
+        textureSet.SetTexture( 0u, texture );
       }
     }
   }
   else
   {
-    textureSet = mFactoryCache.GetAtlasManager()->Add(textureRect, url, mDesiredSize, mFittingMode, mSamplingMode );
-    mImpl->mFlags |= Impl::IS_ATLASING_APPLIED;
-    if( !textureSet ) // big image, no atlasing
+    if( attemptAtlasing )
+    {
+      textureSet = mFactoryCache.GetAtlasManager()->Add(textureRect, url, mDesiredSize, mFittingMode, true, this );
+      mImpl->mFlags |= Impl::IS_ATLASING_APPLIED;
+    }
+    if( !textureSet ) // big image, no atlasing or atlasing failed
     {
       mImpl->mFlags &= ~Impl::IS_ATLASING_APPLIED;
       ResourceImage resourceImage = Dali::ResourceImage::New( url, mDesiredSize, mFittingMode, mSamplingMode );
@@ -496,7 +527,6 @@ TextureSet ImageVisual::CreateTextureSet( Vector4& textureRect, const std::strin
     sampler.SetWrapMode(  mWrapModeU, mWrapModeV  );
     textureSet.SetSampler( 0u, sampler );
   }
-
   return textureSet;
 }
 
@@ -509,6 +539,7 @@ void ImageVisual::InitializeRenderer( const std::string& imageUrl )
 
   mImageUrl = imageUrl;
   mImpl->mRenderer.Reset();
+  mImpl->mFlags &= ~Impl::IS_ATLASING_APPLIED;
 
   if( !mImpl->mCustomShader &&
       ( strncasecmp( imageUrl.c_str(), HTTP_URL,  sizeof(HTTP_URL)  -1 ) != 0 ) && // ignore remote images
@@ -527,11 +558,10 @@ void ImageVisual::InitializeRenderer( const std::string& imageUrl )
     if( !mImpl->mRenderer ) // new renderer is needed
     {
       Vector4 atlasRect;
-      TextureSet textureSet = CreateTextureSet(atlasRect, imageUrl, IsSynchronousResourceLoading() );
-      Geometry geometry = CreateGeometry( mFactoryCache, ImageDimensions( 1, 1 ) );
-      Shader shader( GetImageShader(mFactoryCache, mImpl->mFlags & Impl::IS_ATLASING_APPLIED, defaultWrapMode) );
-      mImpl->mRenderer = Renderer::New( geometry, shader );
-      mImpl->mRenderer.SetTextures( textureSet );
+      // texture set has to be created first as we need to know if atlasing succeeded or not
+      // when selecting the shader
+      TextureSet textures = CreateTextureSet( atlasRect, imageUrl, IsSynchronousResourceLoading(), true );
+      CreateRenderer( textures );
 
       if( mImpl->mFlags & Impl::IS_ATLASING_APPLIED ) // the texture is packed inside atlas
       {
@@ -555,9 +585,9 @@ void ImageVisual::InitializeRenderer( const std::string& imageUrl )
   {
     // for custom shader or remote image, renderer is not cached and atlas is not applied
     mImpl->mFlags &= ~Impl::IS_FROM_CACHE;
-    mImpl->mRenderer = CreateRenderer();
-    Image image = LoadImage( imageUrl, IsSynchronousResourceLoading() );
-    ApplyImageToSampler( image );
+    Vector4 atlasRect; // ignored in this case
+    TextureSet textures = CreateTextureSet( atlasRect, imageUrl, IsSynchronousResourceLoading(), false );
+    CreateRenderer( textures );
   }
 }
 
@@ -565,7 +595,21 @@ void ImageVisual::InitializeRenderer( const Image& image )
 {
   mImpl->mFlags &= ~Impl::IS_FROM_CACHE;
 
-  mImpl->mRenderer = CreateRenderer();
+  // don't reuse CreateTextureSet
+  TextureSet textures = TextureSet::New();
+  // Renderer can't be shared if mImage is NativeImage
+  NativeImage nativeImage = NativeImage::DownCast( image );
+  if( nativeImage )
+  {
+    CreateNativeImageRenderer( nativeImage );
+    DALI_ASSERT_DEBUG( textures );
+    mImpl->mRenderer.SetTextures( textures );
+  }
+  else
+  {
+    // reuse existing code for regular images
+    CreateRenderer( textures );
+  }
 
   if( image )
   {
@@ -573,8 +617,22 @@ void ImageVisual::InitializeRenderer( const Image& image )
   }
 }
 
+void ImageVisual::UploadCompleted()
+{
+  // Resource image is loaded. 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();
+  }
+}
+
 void ImageVisual::DoSetOnStage( Actor& actor )
 {
+  mPlacementActor = actor;
+
   if( !mImageUrl.empty() )
   {
     InitializeRenderer( mImageUrl );
@@ -589,7 +647,11 @@ void ImageVisual::DoSetOnStage( Actor& actor )
     mImpl->mRenderer.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, mPixelArea );
   }
 
-  actor.AddRenderer( mImpl->mRenderer );
+  if( IsSynchronousResourceLoading() || !(mImpl->mFlags & Impl::IS_ATLASING_APPLIED) )
+  {
+    actor.AddRenderer( mImpl->mRenderer );
+    mPlacementActor.Reset();
+  }
 }
 
 void ImageVisual::DoSetOffStage( Actor& actor )
@@ -606,6 +668,7 @@ void ImageVisual::DoSetOffStage( Actor& actor )
     actor.RemoveRenderer( mImpl->mRenderer );
     mImpl->mRenderer.Reset();
   }
+  mPlacementActor.Reset();
 }
 
 void ImageVisual::DoCreatePropertyMap( Property::Map& map ) const
@@ -641,6 +704,17 @@ void ImageVisual::DoCreatePropertyMap( Property::Map& map ) const
   map.Insert( Toolkit::ImageVisual::Property::WRAP_MODE_V, mWrapModeV );
 }
 
+void ImageVisual::DoSetProperty( Dali::Property::Index index, const Dali::Property::Value& propertyValue )
+{
+  // TODO
+}
+
+Dali::Property::Value ImageVisual::DoGetProperty( Dali::Property::Index index )
+{
+  // TODO
+  return Dali::Property::Value();
+}
+
 Shader ImageVisual::GetImageShader( VisualFactoryCache& factoryCache, bool atlasing, bool defaultTextureWrapping )
 {
   Shader shader;
@@ -678,141 +752,13 @@ Shader ImageVisual::GetImageShader( VisualFactoryCache& factoryCache, bool atlas
   return shader;
 }
 
-void ImageVisual::SetImage( Actor& actor, const std::string& imageUrl, ImageDimensions size, Dali::FittingMode::Type fittingMode, Dali::SamplingMode::Type samplingMode )
-{
-  if( mImageUrl != imageUrl )
-  {
-    std::string oldImageUrl = mImageUrl;
-    mImageUrl = imageUrl;
-    mDesiredSize = size;
-    mFittingMode = fittingMode;
-    mSamplingMode = samplingMode;
-    mImage.Reset();
-
-    if( IsSynchronousResourceLoading() )
-    {
-      DoSynchronousResourceLoading();
-    }
-
-    if( mImpl->mRenderer )
-    {
-      if( GetIsFromCache() ) // if renderer is from cache, remove the old one
-      {
-        //remove old renderer
-        if( actor )
-        {
-          actor.RemoveRenderer( mImpl->mRenderer );
-        }
-
-        //clean the cache
-        if( !oldImageUrl.empty() )
-        {
-          CleanCache(oldImageUrl);
-        }
-
-        if( actor && actor.OnStage() ) // if actor on stage, create a new renderer and apply to actor
-        {
-          SetOnStage(actor);
-        }
-      }
-      else // if renderer is not from cache, reuse the same renderer and only change the texture
-      {
-        Image image = LoadImage( imageUrl, IsSynchronousResourceLoading() );
-        ApplyImageToSampler( image );
-      }
-    }
-  }
-}
-
-void ImageVisual::SetImage( Actor& actor, const Image& image )
-{
-  if( mImage != image )
-  {
-    NativeImage newNativeImage = NativeImage::DownCast( image );
-    bool newRendererFlag = true;
-
-    if( newNativeImage && !mNativeImageFlag )
-    {
-      SetNativeFragmentShaderCode( newNativeImage );
-    }
-
-    if( ( newNativeImage && mNativeImageFlag ) || ( !newNativeImage && !mNativeImageFlag ) )
-    {
-      newRendererFlag = false;
-    }
-
-    if( newNativeImage )
-    {
-      mNativeImageFlag = true;
-    }
-    else
-    {
-      mNativeFragmentShaderCode.clear();
-      mNativeImageFlag = false;
-    }
-
-    mImage = image;
-
-    if( mImpl->mRenderer )
-    {
-      // if renderer is from cache, remove the old one, and create new renderer
-      if( GetIsFromCache() )
-      {
-        //remove old renderer
-        if( actor )
-        {
-          actor.RemoveRenderer( mImpl->mRenderer );
-        }
-
-        //clean the cache
-        if( !mImageUrl.empty() )
-        {
-          CleanCache(mImageUrl);
-        }
-        mImageUrl.clear();
-
-        if( actor && actor.OnStage() ) // if actor on stage, create a new renderer and apply to actor
-        {
-          SetOnStage(actor);
-        }
-      }
-      // if input image is nativeImage and mImage is regular image or the reverse, remove the old one, and create new renderer
-      else if( newRendererFlag )
-      {
-        //remove old renderer
-        if( actor )
-        {
-          actor.RemoveRenderer( mImpl->mRenderer );
-        }
-
-        if( actor && actor.OnStage() ) // if actor on stage, create a new renderer and apply to actor
-        {
-          SetOnStage(actor);
-        }
-      }
-      else // if renderer is not from cache, reuse the same renderer and only change the texture
-      {
-        ApplyImageToSampler( image );
-      }
-    }
-
-    mImageUrl.clear();
-    mDesiredSize = ImageDimensions();
-    mFittingMode = FittingMode::DEFAULT;
-    mSamplingMode = SamplingMode::DEFAULT;
-  }
-}
-
 void ImageVisual::ApplyImageToSampler( const Image& image )
 {
   if( image )
   {
     TextureSet textureSet = mImpl->mRenderer.GetTextures();
-    if( !textureSet )
-    {
-      textureSet = TextureSet::New();
-      mImpl->mRenderer.SetTextures( textureSet );
-    }
+    DALI_ASSERT_DEBUG( textureSet ); // texture set should always exist by this time
+
     TextureSetImage( textureSet, 0u, image );
     Sampler sampler = Sampler::New();
     sampler.SetWrapMode(  mWrapModeU, mWrapModeV  );
@@ -834,46 +780,22 @@ void ImageVisual::OnImageLoaded( ResourceImage image )
 
 void ImageVisual::CleanCache(const std::string& url)
 {
-  TextureSet textureSet = mImpl->mRenderer.GetTextures();
-
-  Vector4 atlasRect( 0.f, 0.f, 1.f, 1.f );
-  Property::Index index = mImpl->mRenderer.GetPropertyIndex( ATLAS_RECT_UNIFORM_NAME );
-  if( index != Property::INVALID_INDEX )
-  {
-    Property::Value atlasRectValue = mImpl->mRenderer.GetProperty( index );
-    atlasRectValue.Get( atlasRect );
-  }
-
-  mImpl->mRenderer.Reset();
-  if( mFactoryCache.CleanRendererCache( url ) && index != Property::INVALID_INDEX )
+  if( IsFromCache() )
   {
-    mFactoryCache.GetAtlasManager()->Remove( textureSet, atlasRect );
-  }
-}
-
-void ImageVisual::SetNativeFragmentShaderCode( Dali::NativeImage& nativeImage )
-{
-  const char* fragmentPreFix = nativeImage.GetCustomFragmentPreFix();
-  const char* customSamplerTypename = nativeImage.GetCustomSamplerTypename();
-
-  if( fragmentPreFix )
-  {
-    mNativeFragmentShaderCode = fragmentPreFix;
-    mNativeFragmentShaderCode += "\n";
-  }
-
-  if( mImpl->mCustomShader && !mImpl->mCustomShader->mFragmentShader.empty() )
-  {
-    mNativeFragmentShaderCode += mImpl->mCustomShader->mFragmentShader;
-  }
-  else
-  {
-    mNativeFragmentShaderCode += FRAGMENT_SHADER_NO_ATLAS;
-  }
+    Vector4 atlasRect( 0.f, 0.f, 1.f, 1.f );
+    Property::Index index = mImpl->mRenderer.GetPropertyIndex( ATLAS_RECT_UNIFORM_NAME );
+    if( index != Property::INVALID_INDEX )
+    {
+      Property::Value atlasRectValue = mImpl->mRenderer.GetProperty( index );
+      atlasRectValue.Get( atlasRect );
+    }
 
-  if( customSamplerTypename )
-  {
-    mNativeFragmentShaderCode.replace( mNativeFragmentShaderCode.find( DEFAULT_SAMPLER_TYPENAME ), strlen( DEFAULT_SAMPLER_TYPENAME ), customSamplerTypename );
+    TextureSet textureSet = mImpl->mRenderer.GetTextures();
+    mImpl->mRenderer.Reset();
+    if( mFactoryCache.CleanRendererCache( url ) && index != Property::INVALID_INDEX )
+    {
+      mFactoryCache.GetAtlasManager()->Remove( textureSet, atlasRect );
+    }
   }
 }
 
index 2c48913..c2eca0e 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_INTERNAL_IMAGE_VISUAL_H
 
 /*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ * 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.
  *
  */
 
-// INTERNAL INCLUDES
-#include <dali-toolkit/internal/visuals/visual-base-impl.h>
-
 // EXTERNAL INCLUDES
+#include <dali/public-api/common/intrusive-ptr.h>
 #include <dali/public-api/images/image.h>
 #include <dali/public-api/images/image-operations.h>
 #include <dali/public-api/images/resource-image.h>
+#include <dali/devel-api/object/weak-handle.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/visuals/visual-base-impl.h>
+#include <dali-toolkit/devel-api/image-loader/atlas-upload-observer.h>
 
 namespace Dali
 {
@@ -72,21 +75,42 @@ typedef IntrusivePtr< ImageVisual > ImageVisualPtr;
  *   "DEFAULT"
  *
  */
-class ImageVisual: public Visual::Base, public ConnectionTracker
+class ImageVisual: public Visual::Base, public ConnectionTracker, public AtlasUploadObserver
 {
 public:
 
   /**
-   * @brief Constructor.
+   * @brief Create a new image visual.
+   *
+   * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object
+   * @return A smart-pointer to the newly allocated visual.
+   */
+  static ImageVisualPtr New( VisualFactoryCache& factoryCache );
+
+  /**
+   * @brief Create a new image visual with a URL.
+   *
+   * The visual will load the Image asynchronously when the associated actor is put on stage, and destroy the image when it is off stage
    *
    * @param[in] factoryCache The VisualFactoryCache object
+   * @param[in] imageUrl The URL of the image resource to use
+   * @param[in] size The width and height to fit the loaded image to.
+   * @param[in] fittingMode The FittingMode of the resource to load
+   * @param[in] samplingMode The SamplingMode of the resource to load
    */
-  ImageVisual( VisualFactoryCache& factoryCache );
+  static ImageVisualPtr New( VisualFactoryCache& factoryCache,
+                             const std::string& imageUrl,
+                             ImageDimensions size = ImageDimensions(),
+                             FittingMode::Type fittingMode = FittingMode::DEFAULT,
+                             Dali::SamplingMode::Type samplingMode = SamplingMode::BOX_THEN_LINEAR );
 
   /**
-   * @brief A reference counted object may only be deleted by calling Unreference().
+   * @brief Create a new image visual with an Image type.
+   *
+   * @param[in] factoryCache The VisualFactoryCache object
+   * @param[in] image The image to use
    */
-  ~ImageVisual();
+  static ImageVisualPtr New( VisualFactoryCache& factoryCache, const Image& image );
 
 public:  // from Visual
 
@@ -100,11 +124,59 @@ public:  // from Visual
    */
   virtual void DoCreatePropertyMap( Property::Map& map ) const;
 
+  /**
+   * @copydoc Visual::Base::DoSetProperty
+   */
+  virtual void DoSetProperty( Dali::Property::Index index, const Dali::Property::Value& propertyValue );
+
+  /**
+   * @copydoc Visual::Base::DoGetProperty
+   */
+  virtual Dali::Property::Value DoGetProperty( Dali::Property::Index index );
+
 protected:
+
   /**
-   * @copydoc Visual::Base::DoInitialize
+   * @brief Constructor.
+   *
+   * @param[in] factoryCache The VisualFactoryCache object
    */
-  virtual void DoInitialize( Actor& actor, const Property::Map& propertyMap );
+  ImageVisual( VisualFactoryCache& factoryCache );
+
+  /**
+   * @brief Constructor with a URL.
+   *
+   * The visual will load the Image asynchronously when the associated actor is put on stage, and destroy the image when it is off stage
+   *
+   * @param[in] factoryCache The VisualFactoryCache object
+   * @param[in] imageUrl The URL of the image resource to use
+   * @param[in] size The width and height to fit the loaded image to.
+   * @param[in] fittingMode The FittingMode of the resource to load
+   * @param[in] samplingMode The SamplingMode of the resource to load
+   */
+  ImageVisual( VisualFactoryCache& factoryCache,
+               const std::string& imageUrl,
+               ImageDimensions size,
+               FittingMode::Type fittingMode,
+               Dali::SamplingMode::Type samplingMode );
+
+  /**
+   * @brief Constructor with an Image type.
+   *
+   * @param[in] factoryCache The VisualFactoryCache object
+   * @param[in] image The image to use
+   */
+  ImageVisual( VisualFactoryCache& factoryCache, const Image& image );
+
+  /**
+   * @brief A reference counted object may only be deleted by calling Unreference().
+   */
+  virtual ~ImageVisual();
+
+  /**
+   * @copydoc Visual::Base::DoSetProperties
+   */
+  virtual void DoSetProperties( const Property::Map& propertyMap );
 
   /**
    * @copydoc Visual::Base::DoSetOnStage
@@ -127,28 +199,12 @@ public:
   static Shader GetImageShader( VisualFactoryCache& factoryCache, bool atlasing, bool defaultTextureWrapping );
 
   /**
-   * @brief Sets the image of this visual to the resource at imageUrl
-   * The visual will load the Image asynchronously when the associated actor is put on stage, and destroy the image when it is off stage
-   *
-   * @param[in] actor The Actor the renderer is applied to if, empty if the renderer has not been applied to any Actor
-   * @param[in] imageUrl The URL of the image resource to use
-   * @param[in] size The width and height to fit the loaded image to.
-   * @param[in] fittingMode The FittingMode of the resource to load
-   * @param[in] samplingMode The SamplingMode of the resource to load
-   */
-  void SetImage( Actor& actor,
-                 const std::string& imageUrl,
-                 ImageDimensions size=ImageDimensions(),
-                 FittingMode::Type fittingMode = FittingMode::DEFAULT,
-                 Dali::SamplingMode::Type samplingMode = SamplingMode::BOX_THEN_LINEAR );
-
-  /**
-   * @brief Sets the image to be rendered by this visual
+   * @copydoc AtlasUploadObserver::UploadCompleted
    *
-   * @param[in] actor The Actor the renderer is applied to if, empty if the renderer has not been applied to any Actor
-   * @param[in] image The image to use
+   * To avoid rendering garbage pixels, renderer should be added to actor after the resources are ready.
+   * This callback is the place to add the renderer as it would be called once the loading is finished.
    */
-  void SetImage( Actor& actor, const Image& image );
+  virtual void UploadCompleted();
 
 private:
 
@@ -175,43 +231,36 @@ private:
 
   /**
    * @brief Creates the Dali::Renderer (potentially from the renderer cache), initializing it
-   *
-   * @return Returns the created Dali::Renderer
+   * @param[in] textures to use
    */
-  Renderer CreateRenderer() const;
+  void CreateRenderer( TextureSet& textures );
 
   /**
    * @brief Creates the Dali::Renderer for NativeImage with custom sampler type and prefix, initializing it
-   *
-   * @return Returns the created Dali::Renderer
+   * @param NativeImageRenderer
    */
-  Renderer CreateNativeImageRenderer() const;
+  void CreateNativeImageRenderer( NativeImage& nativeImage );
 
   /**
    * @brief Query whether resources requires to be loaded synchronously.
-   * @return Returns true if synchronoud resource loading is required, false otherwise.
+   * @return Returns true if synchronous resource loading is required, false otherwise.
    */
   bool IsSynchronousResourceLoading() const;
 
   /**
-   * @brief Do the synchronous resource loading
-   */
-  void DoSynchronousResourceLoading();
-
-  /**
-   * Load the image.
-   * @param[in] url The URL of the image resource to use.
-   * @param[in] synchronousLoading If true, the resource is loaded synchronously, otherwise asynchronously.
+   * @brief Load the resource synchronously
    */
-  Image LoadImage( const std::string& url, bool synchronousLoading );
+  void LoadResourceSynchronously();
 
   /**
-   * Load the image and create a texture set to hold the texture, with automatic atlasing applied.
-   * @param [out] textureRect The texture area of the resource image in the atlas.
+   * Creates the texture set and adds the texture to it
+   * @param[out] textureRect The texture area of the texture in the atlas.
    * @param[in] url The URL of the image resource to use.
    * @param[in] synchronousLoading If true, the resource is loaded synchronously, otherwise asynchronously.
+   * @param[in] attemptAtlasing If true will attempt atlasing, otherwise create unique texture
+   * @return the texture set to use
    */
-  TextureSet CreateTextureSet( Vector4& textureRect, const std::string& url, bool synchronousLoading );
+  TextureSet CreateTextureSet( Vector4& textureRect, const std::string& url, bool synchronousLoading, bool attemptAtlasing );
 
   /**
    * Callback function of image resource loading succeed
@@ -230,25 +279,20 @@ private:
    */
   void CleanCache(const std::string& url);
 
-  /**
-   * Set shader code for nativeimage if it exists
-   */
-  void SetNativeFragmentShaderCode( Dali::NativeImage& nativeImage );
-
 private:
+
   Image mImage;
   PixelData mPixels;
   Vector4 mPixelArea;
-
+  WeakHandle<Actor> mPlacementActor;
   std::string mImageUrl;
+
   Dali::ImageDimensions mDesiredSize;
-  Dali::FittingMode::Type mFittingMode;
-  Dali::SamplingMode::Type mSamplingMode;
-  Dali::WrapMode::Type mWrapModeU;
-  Dali::WrapMode::Type mWrapModeV;
+  Dali::FittingMode::Type mFittingMode:3;
+  Dali::SamplingMode::Type mSamplingMode:4;
+  Dali::WrapMode::Type mWrapModeU:3;
+  Dali::WrapMode::Type mWrapModeV:3;
 
-  std::string mNativeFragmentShaderCode;
-  bool mNativeImageFlag;
 };
 
 } // namespace Internal
index eafe9e8..3e94f9e 100644 (file)
@@ -288,7 +288,12 @@ const char* NORMAL_MAP_FRAGMENT_SHADER = DALI_COMPOSE_SHADER(
   }\n
 );
 
-} // namespace
+} // unnamed namespace
+
+MeshVisualPtr MeshVisual::New( VisualFactoryCache& factoryCache )
+{
+  return new MeshVisual( factoryCache );
+}
 
 MeshVisual::MeshVisual( VisualFactoryCache& factoryCache )
 : Visual::Base( factoryCache ),
@@ -303,7 +308,7 @@ MeshVisual::~MeshVisual()
 {
 }
 
-void MeshVisual::DoInitialize( Actor& actor, const Property::Map& propertyMap )
+void MeshVisual::DoSetProperties( const Property::Map& propertyMap )
 {
   Property::Value* objectUrl = propertyMap.Find( Toolkit::MeshVisual::Property::OBJECT_URL, OBJECT_URL_NAME );
   if( !objectUrl || !objectUrl->Get( mObjectUrl ) )
@@ -389,6 +394,17 @@ void MeshVisual::DoCreatePropertyMap( Property::Map& map ) const
   map.Insert( Toolkit::MeshVisual::Property::LIGHT_POSITION, mLightPosition );
 }
 
+void MeshVisual::DoSetProperty( Dali::Property::Index index, const Dali::Property::Value& propertyValue )
+{
+  // TODO
+}
+
+Dali::Property::Value MeshVisual::DoGetProperty( Dali::Property::Index index )
+{
+  // TODO
+  return Dali::Property::Value();
+}
+
 void MeshVisual::InitializeRenderer()
 {
   //Try to load the geometry from the file.
index 4a2927c..4c0441a 100644 (file)
@@ -21,6 +21,7 @@
 // EXTERNAL INCLUDES
 #include <fstream>
 #include <string.h>
+#include <dali/public-api/common/intrusive-ptr.h>
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/public-api/visuals/mesh-visual-properties.h>
@@ -36,6 +37,9 @@ namespace Toolkit
 namespace Internal
 {
 
+class MeshVisual;
+typedef IntrusivePtr< MeshVisual > MeshVisualPtr;
+
 /**
  * The visual which renders a 3D object to the control's quad
  *
@@ -56,16 +60,12 @@ class MeshVisual: public Visual::Base
 public:
 
   /**
-   * @brief Constructor.
+   * @brief Create a new mesh visual.
    *
    * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object
+   * @return A smart-pointer to the newly allocated visual.
    */
-  MeshVisual( VisualFactoryCache& factoryCache );
-
-  /**
-   * @brief A reference counted object may only be deleted by calling Unreference().
-   */
-  virtual ~MeshVisual();
+  static MeshVisualPtr New( VisualFactoryCache& factoryCache );
 
 public:  // from Visual
 
@@ -79,12 +79,34 @@ public:  // from Visual
    */
   virtual void DoCreatePropertyMap( Property::Map& map ) const;
 
+  /**
+   * @copydoc Visual::Base::DoSetProperty
+   */
+  virtual void DoSetProperty( Dali::Property::Index index, const Dali::Property::Value& propertyValue );
+
+  /**
+   * @copydoc Visual::Base::DoGetProperty
+   */
+  virtual Dali::Property::Value DoGetProperty( Dali::Property::Index index );
+
 protected:
 
   /**
-   * @copydoc Visual::Base::DoInitialize
+   * @brief Constructor.
+   *
+   * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object
+   */
+  MeshVisual( VisualFactoryCache& factoryCache );
+
+  /**
+   * @brief A reference counted object may only be deleted by calling Unreference().
+   */
+  virtual ~MeshVisual();
+
+  /**
+   * @copydoc Visual::Base::DoSetProperties
    */
-  virtual void DoInitialize( Actor& actor, const Property::Map& propertyMap );
+  virtual void DoSetProperties( const Property::Map& propertyMap );
 
   /**
    * @copydoc Visual::Base::DoSetOnStage
index 3bf5728..da73b33 100644 (file)
@@ -200,9 +200,41 @@ void RegisterStretchProperties( Renderer& renderer, const char * uniformName, co
 
 /////////////////NPatchVisual////////////////
 
-NPatchVisual::NPatchVisual( VisualFactoryCache& factoryCache )
+NPatchVisualPtr NPatchVisual::New( VisualFactoryCache& factoryCache )
+{
+  return new NPatchVisual( factoryCache );
+}
+
+NPatchVisualPtr NPatchVisual::New( VisualFactoryCache& factoryCache, const std::string& imageUrl, bool borderOnly )
+{
+  NPatchVisual* nPatchVisual = new NPatchVisual( factoryCache, borderOnly );
+  nPatchVisual->mImageUrl = imageUrl;
+
+  NinePatchImage image = NinePatchImage::New( imageUrl );
+  nPatchVisual->InitializeFromImage( image );
+
+  return nPatchVisual;
+}
+
+NPatchVisualPtr NPatchVisual::New( VisualFactoryCache& factoryCache, NinePatchImage image, bool borderOnly )
+{
+  NPatchVisual* nPatchVisual = new NPatchVisual( factoryCache, borderOnly );
+  nPatchVisual->mImage = image;
+
+  nPatchVisual->InitializeFromImage( image );
+
+  return nPatchVisual;
+}
+
+NPatchVisual::NPatchVisual( VisualFactoryCache& factoryCache, bool borderOnly )
 : Visual::Base( factoryCache ),
-  mBorderOnly( false )
+  mImage(),
+  mCroppedImage(),
+  mImageUrl(),
+  mStretchPixelsX(),
+  mStretchPixelsY(),
+  mImageSize(),
+  mBorderOnly( borderOnly )
 {
 }
 
@@ -210,7 +242,7 @@ NPatchVisual::~NPatchVisual()
 {
 }
 
-void NPatchVisual::DoInitialize( Actor& actor, const Property::Map& propertyMap )
+void NPatchVisual::DoSetProperties( const Property::Map& propertyMap )
 {
   Property::Value* imageURLValue = propertyMap.Find( Toolkit::ImageVisual::Property::URL, IMAGE_URL_NAME );
   if( imageURLValue )
@@ -405,6 +437,17 @@ void NPatchVisual::DoCreatePropertyMap( Property::Map& map ) const
   map.Insert( Toolkit::ImageVisual::Property::BORDER_ONLY, mBorderOnly );
 }
 
+void NPatchVisual::DoSetProperty( Dali::Property::Index index, const Dali::Property::Value& propertyValue )
+{
+  // TODO
+}
+
+Dali::Property::Value NPatchVisual::DoGetProperty( Dali::Property::Index index )
+{
+  // TODO
+  return Dali::Property::Value();
+}
+
 void NPatchVisual::ChangeRenderer( bool oldBorderOnly, size_t oldGridX, size_t oldGridY )
 {
   //check to see if the border style has changed
@@ -441,60 +484,6 @@ void NPatchVisual::ChangeRenderer( bool oldBorderOnly, size_t oldGridX, size_t o
   }
 }
 
-void NPatchVisual::SetImage( const std::string& imageUrl, bool borderOnly )
-{
-  bool oldBorderOnly = mBorderOnly;
-  size_t oldGridX = mStretchPixelsX.Size();
-  size_t oldGridY = mStretchPixelsY.Size();
-
-  mBorderOnly = borderOnly;
-  mImage.Reset();
-  if( mImageUrl == imageUrl )
-  {
-    return;
-  }
-
-  mImageUrl = imageUrl;
-  if( mImpl->mRenderer )
-  {
-    NinePatchImage nPatch = NinePatchImage::New( mImageUrl );
-    InitializeFromImage( nPatch );
-
-    ChangeRenderer( oldBorderOnly, oldGridX, oldGridY );
-
-    if( mCroppedImage )
-    {
-      ApplyImageToSampler();
-    }
-  }
-}
-
-void NPatchVisual::SetImage( NinePatchImage image, bool borderOnly )
-{
-  bool oldBorderOnly = mBorderOnly;
-  size_t oldGridX = mStretchPixelsX.Size();
-  size_t oldGridY = mStretchPixelsY.Size();
-
-  mBorderOnly = borderOnly;
-  mImageUrl.empty();
-  if( mImage == image )
-  {
-    return;
-  }
-
-  mImage = image;
-  if( mImpl->mRenderer )
-  {
-    InitializeFromImage( mImage );
-    ChangeRenderer( oldBorderOnly, oldGridX, oldGridY );
-
-    if( mCroppedImage )
-    {
-      ApplyImageToSampler();
-    }
-  }
-}
-
 void NPatchVisual::InitializeFromImage( NinePatchImage nPatch )
 {
   mCroppedImage = nPatch.CreateCroppedBufferImage();
index e6c4872..b3210b9 100644 (file)
  *
  */
 
-// INTERNAL INCLUDES
-#include <dali-toolkit/internal/visuals/visual-base-impl.h>
-
 // EXTERNAL INCLUDES
+#include <dali/public-api/common/intrusive-ptr.h>
 #include <dali/public-api/images/image.h>
 #include <dali/public-api/images/image-operations.h>
 #include <dali/devel-api/images/nine-patch-image.h>
@@ -29,6 +27,9 @@
 #include <dali/public-api/rendering/sampler.h>
 #include <dali/public-api/rendering/shader.h>
 
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/visuals/visual-base-impl.h>
+
 namespace Dali
 {
 
@@ -38,6 +39,9 @@ namespace Toolkit
 namespace Internal
 {
 
+class NPatchVisual;
+typedef IntrusivePtr< NPatchVisual > NPatchVisualPtr;
+
 /**
  * The visual which renders an 9 patch image to the control's quad
  *
@@ -54,16 +58,32 @@ class NPatchVisual: public Visual::Base
 public:
 
   /**
-   * @brief Constructor.
+   * @brief Create a new n-patch visual.
    *
    * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object
+   * @return A smart-pointer to the newly allocated visual.
    */
-  NPatchVisual( VisualFactoryCache& factoryCache );
+  static NPatchVisualPtr New( VisualFactoryCache& factoryCache );
 
   /**
-   * @brief A reference counted object may only be deleted by calling Unreference().
+   * @brief Create an N-patch visual using an image URL.
+   *
+   * The visual will load the image synchronously when the associated actor is put on stage, and destroy the image when it is off stage
+   *
+   * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object
+   * @param[in] imageUrl The URL to 9 patch image resource to use
+   * @param[in] borderOnly A Flag to indicate if the image should omit the centre of the n-patch and only render the border
+   */
+  static NPatchVisualPtr New( VisualFactoryCache& factoryCache, const std::string& imageUrl, bool borderOnly = false );
+
+  /**
+   * @brief Create an N-patch visual with a NinePatchImage resource.
+   *
+   * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object
+   * @param[in] image The NinePatchImage to use
+   * @param[in] borderOnly A Flag to indicate if the image should omit the centre of the n-patch and only render the border
    */
-  ~NPatchVisual();
+  static NPatchVisualPtr New( VisualFactoryCache& factoryCache, NinePatchImage image, bool borderOnly = false );
 
 public:  // from Visual
 
@@ -77,41 +97,45 @@ public:  // from Visual
    */
   virtual void DoCreatePropertyMap( Property::Map& map ) const;
 
-protected:
+  /**
+   * @copydoc Visual::Base::DoSetProperty
+   */
+  virtual void DoSetProperty( Dali::Property::Index index, const Dali::Property::Value& propertyValue );
 
   /**
-   * @copydoc Visual::Base::DoInitialize
+   * @copydoc Visual::Base::DoGetProperty
    */
-  virtual void DoInitialize( Actor& actor, const Property::Map& propertyMap );
+  virtual Dali::Property::Value DoGetProperty( Dali::Property::Index index );
+
+protected:
 
   /**
-   * @copydoc Visual::Base::DoSetOnStage
+   * @brief Constructor.
+   *
+   * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object
+   * @param[in] borderOnly A Flag to indicate if the image should omit the centre of the n-patch and only render the border
    */
-  virtual void DoSetOnStage( Actor& actor );
+  NPatchVisual( VisualFactoryCache& factoryCache, bool borderOnly = false );
 
   /**
-   * @copydoc Visual::Base::DoSetOffStage
+   * @brief A reference counted object may only be deleted by calling Unreference().
    */
-  virtual void DoSetOffStage( Actor& actor );
+  virtual ~NPatchVisual();
 
-public:
+  /**
+   * @copydoc Visual::Base::DoSetProperties
+   */
+  virtual void DoSetProperties( const Property::Map& propertyMap );
 
   /**
-   * @brief Sets the 9 patch image of this visual to the resource at imageUrl
-   * The visual will load the image synchronously when the associated actor is put on stage, and destroy the image when it is off stage
-   *
-   * @param[in] imageUrl The URL to 9 patch image resource to use
-   * @param[in] borderOnly A Flag to indicate if the image should omit the centre of the n-patch and only render the border
+   * @copydoc Visual::Base::DoSetOnStage
    */
-  void SetImage( const std::string& imageUrl, bool borderOnly = false );
+  virtual void DoSetOnStage( Actor& actor );
 
   /**
-   * @brief Sets the 9 patch image of this viusal to the 9 patch image
-   *
-   * @param[in] image The NinePatchImage to use
-   * @param[in] borderOnly A Flag to indicate if the image should omit the centre of the n-patch and only render the border
+   * @copydoc Visual::Base::DoSetOffStage
    */
-  void SetImage( NinePatchImage image, bool borderOnly = false );
+  virtual void DoSetOffStage( Actor& actor );
 
 private:
 
index 325a9cd..6938eef 100644 (file)
@@ -160,7 +160,12 @@ const char* FRAGMENT_SHADER = DALI_COMPOSE_SHADER(
   }\n
 );
 
-} // namespace
+} // unnamed namespace
+
+PrimitiveVisualPtr PrimitiveVisual::New( VisualFactoryCache& factoryCache )
+{
+  return new PrimitiveVisual( factoryCache );
+}
 
 PrimitiveVisual::PrimitiveVisual( VisualFactoryCache& factoryCache )
 : Visual::Base( factoryCache ),
@@ -182,7 +187,7 @@ PrimitiveVisual::~PrimitiveVisual()
 {
 }
 
-void PrimitiveVisual::DoInitialize( Actor& actor, const Property::Map& propertyMap )
+void PrimitiveVisual::DoSetProperties( const Property::Map& propertyMap )
 {
   //Find out which shape to renderer.
   Property::Value* primitiveTypeValue = propertyMap.Find( Toolkit::PrimitiveVisual::Property::SHAPE, PRIMITIVE_SHAPE );
@@ -405,6 +410,17 @@ void PrimitiveVisual::DoCreatePropertyMap( Property::Map& map ) const
   map.Insert( Toolkit::PrimitiveVisual::Property::LIGHT_POSITION, mLightPosition );
 }
 
+void PrimitiveVisual::DoSetProperty( Dali::Property::Index index, const Dali::Property::Value& propertyValue )
+{
+  // TODO
+}
+
+Dali::Property::Value PrimitiveVisual::DoGetProperty( Dali::Property::Index index )
+{
+  // TODO
+  return Dali::Property::Value();
+}
+
 void PrimitiveVisual::InitializeRenderer()
 {
   if( !mGeometry )
index 054e9f0..c06d55c 100644 (file)
@@ -44,6 +44,8 @@
  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  */
 
+// EXTERNAL INCLUDES
+#include <dali/public-api/common/intrusive-ptr.h>
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/public-api/visuals/primitive-visual-properties.h>
@@ -58,6 +60,9 @@ namespace Toolkit
 namespace Internal
 {
 
+class PrimitiveVisual;
+typedef IntrusivePtr< PrimitiveVisual > PrimitiveVisualPtr;
+
 /**
  * The visual which renders a simple 3D shape to the control's quad
  *
@@ -97,16 +102,12 @@ class PrimitiveVisual: public Visual::Base
 public:
 
   /**
-   * @brief Constructor.
+   * @brief Create a new primitive visual.
    *
    * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object
+   * @return A smart-pointer to the newly allocated visual.
    */
-  PrimitiveVisual( VisualFactoryCache& factoryCache );
-
-  /**
-   * @brief A reference counted object may only be deleted by calling Unreference().
-   */
-  virtual ~PrimitiveVisual();
+  static PrimitiveVisualPtr New( VisualFactoryCache& factoryCache );
 
 public:  // from Visual
 
@@ -125,12 +126,34 @@ public:  // from Visual
    */
   virtual void DoCreatePropertyMap( Property::Map& map ) const;
 
+  /**
+   * @copydoc Visual::Base::DoSetProperty
+   */
+  virtual void DoSetProperty( Dali::Property::Index index, const Dali::Property::Value& propertyValue );
+
+  /**
+   * @copydoc Visual::Base::DoGetProperty
+   */
+  virtual Dali::Property::Value DoGetProperty( Dali::Property::Index index );
+
 protected:
 
   /**
-   * @copydoc Visual::Base::DoInitialize
+   * @brief Constructor.
+   *
+   * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object
+   */
+  PrimitiveVisual( VisualFactoryCache& factoryCache );
+
+  /**
+   * @brief A reference counted object may only be deleted by calling Unreference().
+   */
+  virtual ~PrimitiveVisual();
+
+  /**
+   * @copydoc Visual::Base::DoSetProperties
    */
-  virtual void DoInitialize( Actor& actor, const Property::Map& propertyMap );
+  virtual void DoSetProperties( const Property::Map& propertyMap );
 
   /**
    * @copydoc Visual::Base::DoSetOnStage
index 832fd19..efa3582 100644 (file)
@@ -53,10 +53,24 @@ namespace Toolkit
 namespace Internal
 {
 
+SvgVisualPtr SvgVisual::New( VisualFactoryCache& factoryCache )
+{
+  return new SvgVisual( factoryCache );
+}
+
+SvgVisualPtr SvgVisual::New( VisualFactoryCache& factoryCache, const std::string& imageUrl, ImageDimensions size )
+{
+  SvgVisual* svgVisual = new SvgVisual( factoryCache );
+  svgVisual->ParseFromUrl( imageUrl, size );
+  return svgVisual;
+}
+
 SvgVisual::SvgVisual( VisualFactoryCache& factoryCache )
 : Visual::Base( factoryCache ),
   mAtlasRect( FULL_TEXTURE_RECT ),
-  mParsedImage( NULL )
+  mImageUrl(),
+  mParsedImage( NULL ),
+  mPlacementActor()
 {
   // the rasterized image is with pre-multiplied alpha format
   mImpl->mFlags |= Impl::IS_PREMULTIPLIED_ALPHA;
@@ -70,7 +84,7 @@ SvgVisual::~SvgVisual()
   }
 }
 
-void SvgVisual::DoInitialize( Actor& actor, const Property::Map& propertyMap )
+void SvgVisual::DoSetProperties( const Property::Map& propertyMap )
 {
   Property::Value* imageURLValue = propertyMap.Find( Toolkit::ImageVisual::Property::URL, IMAGE_URL_NAME );
   if( imageURLValue )
@@ -78,7 +92,7 @@ void SvgVisual::DoInitialize( Actor& actor, const Property::Map& propertyMap )
     std::string imageUrl;
     if( imageURLValue->Get( imageUrl ) )
     {
-      SetImage( imageUrl );
+      ParseFromUrl( imageUrl );
     }
     else
     {
@@ -133,7 +147,7 @@ void SvgVisual::GetNaturalSize( Vector2& naturalSize ) const
 
 void SvgVisual::SetSize( const Vector2& size )
 {
-  if(mImpl->mSize != size && mParsedImage && GetIsOnStage() )
+  if(mImpl->mSize != size && mParsedImage && IsOnStage() )
   {
     AddRasterizationTask( size );
   }
@@ -150,30 +164,29 @@ void SvgVisual::DoCreatePropertyMap( Property::Map& map ) const
   }
 }
 
-void SvgVisual::SetImage( const std::string& imageUrl, ImageDimensions size )
+void SvgVisual::DoSetProperty( Dali::Property::Index index, const Dali::Property::Value& propertyValue )
 {
-  if( mImageUrl != imageUrl )
-  {
-    mImageUrl = imageUrl;
-
-    NSVGimage* parsedImageOld = mParsedImage;
+  // TODO
+}
 
-    Vector2 dpi = Stage::GetCurrent().GetDpi();
-    float meanDpi = (dpi.height + dpi.width) * 0.5f;
-    mParsedImage = nsvgParseFromFile(mImageUrl.c_str(), UNITS, meanDpi);
+Dali::Property::Value SvgVisual::DoGetProperty( Dali::Property::Index index )
+{
+  // TODO
+  return Dali::Property::Value();
+}
 
-    if( size.GetWidth() != 0u && size.GetHeight() != 0u)
-    {
-      mImpl->mSize.x = size.GetWidth();
-      mImpl->mSize.y = size.GetHeight();
-    }
+void SvgVisual::ParseFromUrl( const std::string& imageUrl, ImageDimensions size )
+{
+  mImageUrl = imageUrl;
 
-    if( mImpl->mSize != Vector2::ZERO && GetIsOnStage() )
-    {
-      AddRasterizationTask( mImpl->mSize );
-    }
+  Vector2 dpi = Stage::GetCurrent().GetDpi();
+  float meanDpi = (dpi.height + dpi.width) * 0.5f;
+  mParsedImage = nsvgParseFromFile( imageUrl.c_str(), UNITS, meanDpi );
 
-    mFactoryCache.GetSVGRasterizationThread()->DeleteImage( parsedImageOld );
+  if( size.GetWidth() != 0u && size.GetHeight() != 0u)
+  {
+    mImpl->mSize.x = size.GetWidth();
+    mImpl->mSize.y = size.GetHeight();
   }
 }
 
@@ -192,7 +205,7 @@ void SvgVisual::AddRasterizationTask( const Vector2& size )
 
 void SvgVisual::ApplyRasterizedImage( PixelData rasterizedPixelData )
 {
-  if( GetIsOnStage()  )
+  if( IsOnStage()  )
   {
     TextureSet currentTextureSet = mImpl->mRenderer.GetTextures();
     if( mAtlasRect != FULL_TEXTURE_RECT )
@@ -214,8 +227,9 @@ void SvgVisual::ApplyRasterizedImage( PixelData rasterizedPixelData )
     }
     else // no atlasing
     {
-      Atlas texture = Atlas::New( rasterizedPixelData.GetWidth(), rasterizedPixelData.GetHeight() );
-      texture.Upload( rasterizedPixelData, 0, 0 );
+      Texture texture = Texture::New( Dali::TextureType::TEXTURE_2D, Pixel::RGBA8888,
+                                      rasterizedPixelData.GetWidth(), rasterizedPixelData.GetHeight() );
+      texture.Upload( rasterizedPixelData );
       mImpl->mFlags &= ~Impl::IS_ATLASING_APPLIED;
 
       if( mAtlasRect == FULL_TEXTURE_RECT )
@@ -233,7 +247,7 @@ void SvgVisual::ApplyRasterizedImage( PixelData rasterizedPixelData )
 
       if( textureSet )
       {
-        TextureSetImage( textureSet, 0u, texture );
+        textureSet.SetTexture( 0, texture );
       }
     }
 
index 81672e5..0456bb5 100644 (file)
@@ -18,7 +18,8 @@
  *
  */
 
-//EXTERNAL INCLUDES
+// EXTERNAL INCLUDES
+#include <dali/public-api/common/intrusive-ptr.h>
 #include <dali/devel-api/object/weak-handle.h>
 
 // INTERNAL INCLUDES
@@ -35,6 +36,9 @@ namespace Toolkit
 namespace Internal
 {
 
+class SvgVisual;
+typedef IntrusivePtr< SvgVisual > SvgVisualPtr;
+
 /**
  * The visual which renders a svg image
  *
@@ -50,16 +54,24 @@ class SvgVisual: public Visual::Base
 public:
 
   /**
-   * @brief Constructor.
+   * @brief Create a new SVG visual.
    *
    * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object
+   * @return A smart-pointer to the newly allocated visual.
    */
-  SvgVisual( VisualFactoryCache& factoryCache );
+  static SvgVisualPtr New( VisualFactoryCache& factoryCache );
 
   /**
-   * @brief A reference counted object may only be deleted by calling Unreference().
+   * @brief Create the SVG Visual using the image URL.
+   *
+   * The visual will parse the SVG image once it is set.
+   * And rasterize it into BufferImage synchronously when the associated actor is put on stage, and destroy the BufferImage when it is off stage
+   *
+   * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object
+   * @param[in] imageUrl The URL to svg resource to use
+   * @param[in] size The required size for the SVG
    */
-  ~SvgVisual();
+  static SvgVisualPtr New( VisualFactoryCache& factoryCache, const std::string& imageUrl, ImageDimensions size = ImageDimensions() );
 
 public:  // from Visual
 
@@ -78,12 +90,34 @@ public:  // from Visual
    */
   virtual void DoCreatePropertyMap( Property::Map& map ) const;
 
+  /**
+   * @copydoc Visual::Base::DoSetProperty
+   */
+  virtual void DoSetProperty( Dali::Property::Index index, const Dali::Property::Value& propertyValue );
+
+  /**
+   * @copydoc Visual::Base::DoGetProperty
+   */
+  virtual Dali::Property::Value DoGetProperty( Dali::Property::Index index );
+
 protected:
 
   /**
-   * @copydoc Visual::Base::DoInitialize
+   * @brief Constructor.
+   *
+   * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object
    */
-  virtual void DoInitialize( Actor& actor, const Property::Map& propertyMap );
+  SvgVisual( VisualFactoryCache& factoryCache );
+
+  /**
+   * @brief A reference counted object may only be deleted by calling Unreference().
+   */
+  virtual ~SvgVisual();
+
+  /**
+   * @copydoc Visual::Base::DoSetProperties
+   */
+  virtual void DoSetProperties( const Property::Map& propertyMap );
 
   /**
    * @copydoc Visual::Base::DoSetOnStage
@@ -98,15 +132,6 @@ protected:
 public:
 
   /**
-   * @brief Sets the svg image of this visual to the resource at imageUrl
-   * The visual will parse the svg image once it is set.
-   * And rasterize it into BufferImage synchronously when the associated actor is put on stage, and destroy the BufferImage when it is off stage
-   *
-   * @param[in] imageUrl The URL to svg resource to use
-   */
-  void SetImage( const std::string& imageUrl, ImageDimensions size = ImageDimensions() );
-
-  /**
    * @bried Apply the rasterized image to the visual.
    *
    * @param[in] rasterizedPixelData The pixel buffer with the rasterized pixels
@@ -114,6 +139,15 @@ public:
   void ApplyRasterizedImage( PixelData rasterizedPixelData );
 
 private:
+
+  /**
+   * @brief Parses the SVG Image from the set URL.
+   *
+   * @param[in] imageUrl The URL of the image to parse the SVG from.
+   * @param[in] size The required size of the SVG
+   */
+  void ParseFromUrl( const std::string& imageUrl, ImageDimensions size = ImageDimensions() );
+
   /**
    * @bried Rasterize the svg with the given size, and add it to the visual.
    *
diff --git a/dali-toolkit/internal/visuals/text/text-visual.cpp b/dali-toolkit/internal/visuals/text/text-visual.cpp
new file mode 100644 (file)
index 0000000..31dc8bb
--- /dev/null
@@ -0,0 +1,886 @@
+/*
+ * 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.
+ *
+ */
+
+// CLASS HEADER
+#include <dali-toolkit/internal/visuals/text/text-visual.h>
+
+// EXTERNAL HEADER
+#include <dali/devel-api/scripting/enum-helper.h>
+// #include <dali/devel-api/scripting/scripting.h>
+
+// INTERNAL HEADER
+#include <dali-toolkit/public-api/text/rendering-backend.h>
+#include <dali-toolkit/public-api/visuals/text-visual-properties.h>
+#include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
+#include <dali-toolkit/internal/text/rendering/text-backend.h>
+#include <dali-toolkit/internal/text/text-view.h>
+#include <dali-toolkit/internal/visuals/visual-base-impl.h>
+#include <dali-toolkit/internal/visuals/visual-base-data-impl.h>
+#include <dali-toolkit/internal/text/text-font-style.h>
+#include <dali-toolkit/internal/text/text-effects-style.h>
+
+using Dali::Toolkit::Text::LayoutEngine;
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+namespace
+{
+
+// Property names.
+const char * const RENDERING_BACKEND_PROPERTY( "renderingBackend" );
+const char * const TEXT_PROPERTY( "text" );
+const char * const FONT_FAMILY_PROPERTY( "fontFamily" );
+const char * const FONT_STYLE_PROPERTY( "fontStyle" );
+const char * const POINT_SIZE_PROPERTY( "pointSize" );
+const char * const MULTI_LINE_PROPERTY( "multiLine" );
+const char * const HORIZONTAL_ALIGNMENT_PROPERTY( "horizontalAlignment" );
+const char * const VERTICAL_ALIGNMENT_PROPERTY( "verticalAlignment" );
+const char * const TEXT_COLOR_PROPERTY( "textColor" );
+const char * const ENABLE_MARKUP_PROPERTY( "enableMarkup" );
+const char * const ENABLE_AUTO_SCROLL_PROPERTY( "enableAutoScroll" );
+const char * const AUTO_SCROLL_SPEED_PROPERTY( "autoScrollSpeed" );
+const char * const AUTO_SCROLL_LOOP_COUNT_PROPERTY( "autoScrollLoopCount" );
+const char * const AUTO_SCROLL_GAP_PROPERTY( "autoScrollGap" );
+const char * const LINE_SPACING_PROPERTY( "lineSpacing" );
+const char * const UNDERLINE_PROPERTY( "underline" );
+const char * const SHADOW_PROPERTY( "shadow" );
+const char * const OUTLINE_PROPERTY( "outline" );
+const char * const BATCHING_ENABLED_PROPERTY( "batchingEnabled" );
+
+const Scripting::StringEnum HORIZONTAL_ALIGNMENT_STRING_TABLE[] =
+{
+  { "BEGIN",  Toolkit::Text::LayoutEngine::HORIZONTAL_ALIGN_BEGIN  },
+  { "CENTER", Toolkit::Text::LayoutEngine::HORIZONTAL_ALIGN_CENTER },
+  { "END",    Toolkit::Text::LayoutEngine::HORIZONTAL_ALIGN_END    },
+};
+const unsigned int HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT = sizeof( HORIZONTAL_ALIGNMENT_STRING_TABLE ) / sizeof( HORIZONTAL_ALIGNMENT_STRING_TABLE[0] );
+
+const Scripting::StringEnum VERTICAL_ALIGNMENT_STRING_TABLE[] =
+{
+  { "TOP",    Toolkit::Text::LayoutEngine::VERTICAL_ALIGN_TOP    },
+  { "CENTER", Toolkit::Text::LayoutEngine::VERTICAL_ALIGN_CENTER },
+  { "BOTTOM", Toolkit::Text::LayoutEngine::VERTICAL_ALIGN_BOTTOM },
+};
+const unsigned int VERTICAL_ALIGNMENT_STRING_TABLE_COUNT = sizeof( VERTICAL_ALIGNMENT_STRING_TABLE ) / sizeof( VERTICAL_ALIGNMENT_STRING_TABLE[0] );
+
+std::string GetHorizontalAlignment( LayoutEngine::HorizontalAlignment alignment )
+{
+  const char* name = Scripting::GetEnumerationName<Toolkit::Text::LayoutEngine::HorizontalAlignment>( alignment,
+                                                                                                      HORIZONTAL_ALIGNMENT_STRING_TABLE,
+                                                                                                      HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT );
+
+  return std::string( name );
+}
+
+std::string GetVerticalAlignment( LayoutEngine::VerticalAlignment alignment )
+{
+  const char* name = Scripting::GetEnumerationName< Toolkit::Text::LayoutEngine::VerticalAlignment >( alignment,
+                                                                                                      VERTICAL_ALIGNMENT_STRING_TABLE,
+                                                                                                      VERTICAL_ALIGNMENT_STRING_TABLE_COUNT );
+
+  return std::string( name );
+}
+
+const char* VERTEX_SHADER = DALI_COMPOSE_SHADER(
+  attribute mediump vec2 aPosition;\n
+  uniform mediump mat4 uMvpMatrix;\n
+  uniform mediump vec3 uSize;\n
+  uniform mediump vec4 pixelArea;
+  varying mediump vec2 vTexCoord;\n
+  \n
+  void main()\n
+  {\n
+    mediump vec4 vertexPosition = vec4(aPosition, 0.0, 1.0);\n
+    vertexPosition.xyz *= uSize;\n
+    vertexPosition = uMvpMatrix * vertexPosition;\n
+    \n
+    vTexCoord = pixelArea.xy+pixelArea.zw*(aPosition + vec2(0.5) );\n
+    gl_Position = vertexPosition;\n
+  }\n
+);
+
+const char* FRAGMENT_SHADER_ATLAS_CLAMP = DALI_COMPOSE_SHADER(
+    varying mediump vec2 vTexCoord;\n
+    uniform sampler2D sTexture;\n
+    uniform mediump vec4 uAtlasRect;\n
+    uniform lowp vec4 uColor;\n
+    \n
+    void main()\n
+    {\n
+      mediump vec2 texCoord = clamp( mix( uAtlasRect.xy, uAtlasRect.zw, vTexCoord ), uAtlasRect.xy, uAtlasRect.zw );\n
+      gl_FragColor = texture2D( sTexture, texCoord ) * uColor;\n
+    }\n
+);
+
+Geometry CreateGeometry( VisualFactoryCache& factoryCache, ImageDimensions gridSize )
+{
+  Geometry geometry;
+
+  if( gridSize == ImageDimensions( 1, 1 ) )
+  {
+    geometry = factoryCache.GetGeometry( VisualFactoryCache::QUAD_GEOMETRY );
+    if( !geometry )
+    {
+      geometry =  VisualFactoryCache::CreateQuadGeometry();
+      factoryCache.SaveGeometry( VisualFactoryCache::QUAD_GEOMETRY, geometry );
+    }
+  }
+  else
+  {
+    geometry = VisualFactoryCache::CreateGridGeometry( gridSize );
+  }
+
+  return geometry;
+}
+
+} // unnamed namespace
+
+TextVisualPtr TextVisual::New( VisualFactoryCache& factoryCache )
+{
+  return new TextVisual( factoryCache );
+}
+
+void TextVisual::SetTextControlInterface( Text::ControlInterface* controlInterface )
+{
+  if( mController )
+  {
+    mController->SetTextControlInterface( controlInterface );
+  }
+}
+
+void TextVisual::SetSize( const Vector2& size )
+{
+  const Text::Controller::UpdateTextType updateTextType = mController->Relayout( size );
+
+  if( ( Text::Controller::NONE_UPDATED != ( Text::Controller::MODEL_UPDATED & updateTextType ) ) ||
+      !mRenderer )
+  {
+    if( !mRenderer )
+    {
+      mRenderer = Text::Backend::Get().NewRenderer( mRenderingBackend );
+    }
+
+    RenderText();
+  }
+}
+
+float TextVisual::GetHeightForWidth( float width ) const
+{
+  return mController->GetHeightForWidth( width );
+}
+
+void TextVisual::GetNaturalSize( Vector2& naturalSize ) const
+{
+  naturalSize = mController->GetNaturalSize().GetVectorXY();
+}
+
+void TextVisual::DoCreatePropertyMap( Property::Map& map ) const
+{
+  Property::Value value;
+
+  map.Clear();
+  map.Insert( Toolkit::Visual::Property::TYPE, Toolkit::Visual::TEXT );
+
+  map.Insert( Toolkit::TextVisual::Property::RENDERING_BACKEND, mRenderingBackend );
+
+  std::string text;
+  mController->GetText( text );
+  map.Insert( Toolkit::TextVisual::Property::TEXT, text );
+
+  map.Insert( Toolkit::TextVisual::Property::FONT_FAMILY, mController->GetDefaultFontFamily() );
+
+  GetFontStyleProperty( mController, value, Text::FontStyle::DEFAULT );
+  map.Insert( Toolkit::TextVisual::Property::FONT_STYLE, value );
+
+  map.Insert( Toolkit::TextVisual::Property::POINT_SIZE, mController->GetDefaultPointSize() );
+
+  map.Insert( Toolkit::TextVisual::Property::MULTI_LINE, mController->IsMultiLineEnabled() );
+
+  map.Insert( Toolkit::TextVisual::Property::HORIZONTAL_ALIGNMENT, GetHorizontalAlignment( mController->GetHorizontalAlignment() ) );
+
+  map.Insert( Toolkit::TextVisual::Property::VERTICAL_ALIGNMENT, GetVerticalAlignment( mController->GetVerticalAlignment() ) );
+
+  map.Insert( Toolkit::TextVisual::Property::TEXT_COLOR, mController->GetTextColor() );
+
+  map.Insert( Toolkit::TextVisual::Property::ENABLE_MARKUP, mController->IsMarkupProcessorEnabled() );
+
+  map.Insert( Toolkit::TextVisual::Property::ENABLE_AUTO_SCROLL, mController->IsAutoScrollEnabled() );
+
+  map.Insert( Toolkit::TextVisual::Property::AUTO_SCROLL_SPEED, mController->GetAutoScrollSpeed() );
+
+  map.Insert( Toolkit::TextVisual::Property::AUTO_SCROLL_LOOP_COUNT, mController->GetAutoScrollLoopCount() );
+
+  map.Insert( Toolkit::TextVisual::Property::AUTO_SCROLL_GAP, mController->GetAutoScrollWrapGap() );
+
+  map.Insert( Toolkit::TextVisual::Property::LINE_SPACING, mController->GetDefaultLineSpacing() );
+
+  GetUnderlineProperties( mController, value, Text::EffectStyle::DEFAULT );
+  map.Insert( Toolkit::TextVisual::Property::UNDERLINE, value );
+
+  GetShadowProperties( mController, value, Text::EffectStyle::DEFAULT );
+  map.Insert( Toolkit::TextVisual::Property::SHADOW, value );
+
+  GetOutlineProperties( mController, value, Text::EffectStyle::DEFAULT );
+  map.Insert( Toolkit::TextVisual::Property::OUTLINE, value );
+
+  map.Insert( Toolkit::TextVisual::Property::BATCHING_ENABLED, false ); // TODO
+}
+
+TextVisual::TextVisual( VisualFactoryCache& factoryCache )
+: Visual::Base( factoryCache ),
+  mController( Text::Controller::New() ),
+  mRenderingBackend( Toolkit::Text::DEFAULT_RENDERING_BACKEND ),
+  mHasBeenStaged( false )
+{
+}
+
+TextVisual::~TextVisual()
+{
+}
+
+void TextVisual::DoSetProperties( const Property::Map& propertyMap )
+{
+  for( Property::Map::SizeType index = 0u, count = propertyMap.Count(); index < count; ++index )
+  {
+    const KeyValuePair& keyValue = propertyMap.GetKeyValue( index );
+
+    switch( keyValue.first.type )
+    {
+      case Property::Key::INDEX:
+      {
+        if( Toolkit::Visual::Property::TYPE != keyValue.first.indexKey ) // Toolkit::Visual::Property::TYPE is not a TextVisual's property.
+        {
+          DoSetProperty( keyValue.first.indexKey, keyValue.second );
+        }
+        break;
+      }
+      case Property::Key::STRING:
+      {
+        if( keyValue.first.stringKey == RENDERING_BACKEND_PROPERTY )
+        {
+          DoSetProperty( Toolkit::TextVisual::Property::RENDERING_BACKEND, keyValue.second );
+        }
+        else if( keyValue.first.stringKey == TEXT_PROPERTY )
+        {
+          DoSetProperty( Toolkit::TextVisual::Property::TEXT, keyValue.second );
+        }
+        else if( keyValue.first.stringKey == FONT_FAMILY_PROPERTY )
+        {
+          DoSetProperty( Toolkit::TextVisual::Property::FONT_FAMILY, keyValue.second );
+        }
+        else if( keyValue.first.stringKey == FONT_STYLE_PROPERTY )
+        {
+          DoSetProperty( Toolkit::TextVisual::Property::FONT_STYLE, keyValue.second );
+        }
+        else if( keyValue.first.stringKey == POINT_SIZE_PROPERTY )
+        {
+          DoSetProperty( Toolkit::TextVisual::Property::POINT_SIZE, keyValue.second );
+        }
+        else if( keyValue.first.stringKey == MULTI_LINE_PROPERTY )
+        {
+          DoSetProperty( Toolkit::TextVisual::Property::MULTI_LINE, keyValue.second );
+        }
+        else if( keyValue.first.stringKey == HORIZONTAL_ALIGNMENT_PROPERTY )
+        {
+          DoSetProperty( Toolkit::TextVisual::Property::HORIZONTAL_ALIGNMENT, keyValue.second );
+        }
+        else if( keyValue.first.stringKey == VERTICAL_ALIGNMENT_PROPERTY )
+        {
+          DoSetProperty( Toolkit::TextVisual::Property::VERTICAL_ALIGNMENT, keyValue.second );
+        }
+        else if( keyValue.first.stringKey == TEXT_COLOR_PROPERTY )
+        {
+          DoSetProperty( Toolkit::TextVisual::Property::TEXT_COLOR, keyValue.second );
+        }
+        else if( keyValue.first.stringKey == ENABLE_MARKUP_PROPERTY )
+        {
+          DoSetProperty( Toolkit::TextVisual::Property::ENABLE_MARKUP, keyValue.second );
+        }
+        else if( keyValue.first.stringKey == ENABLE_AUTO_SCROLL_PROPERTY )
+        {
+          DoSetProperty( Toolkit::TextVisual::Property::ENABLE_AUTO_SCROLL, keyValue.second );
+        }
+        else if( keyValue.first.stringKey == AUTO_SCROLL_SPEED_PROPERTY )
+        {
+          DoSetProperty( Toolkit::TextVisual::Property::AUTO_SCROLL_SPEED, keyValue.second );
+        }
+        else if( keyValue.first.stringKey == AUTO_SCROLL_LOOP_COUNT_PROPERTY )
+        {
+          DoSetProperty( Toolkit::TextVisual::Property::AUTO_SCROLL_LOOP_COUNT, keyValue.second );
+        }
+        else if( keyValue.first.stringKey == AUTO_SCROLL_GAP_PROPERTY )
+        {
+          DoSetProperty( Toolkit::TextVisual::Property::AUTO_SCROLL_GAP, keyValue.second );
+        }
+        else if( keyValue.first.stringKey == LINE_SPACING_PROPERTY )
+        {
+          DoSetProperty( Toolkit::TextVisual::Property::LINE_SPACING, keyValue.second );
+        }
+        else if( keyValue.first.stringKey == UNDERLINE_PROPERTY )
+        {
+          DoSetProperty( Toolkit::TextVisual::Property::UNDERLINE, keyValue.second );
+        }
+        else if( keyValue.first.stringKey == SHADOW_PROPERTY )
+        {
+          DoSetProperty( Toolkit::TextVisual::Property::SHADOW, keyValue.second );
+        }
+        else if( keyValue.first.stringKey == OUTLINE_PROPERTY )
+        {
+          DoSetProperty( Toolkit::TextVisual::Property::OUTLINE, keyValue.second );
+        }
+        else if( keyValue.first.stringKey == BATCHING_ENABLED_PROPERTY )
+        {
+          DoSetProperty( Toolkit::TextVisual::Property::BATCHING_ENABLED, keyValue.second );
+        }
+        break;
+      }
+    }
+  }
+
+  // Retrieve the layout engine to set whether to elide the text and set the cursor's width.
+  Text::LayoutEngine& engine = mController->GetLayoutEngine();
+
+  // Elide the text if it exceeds the boundaries.
+  engine.SetTextEllipsisEnabled( true );
+
+  // Sets 0 as cursor's width.
+  engine.SetCursorWidth( 0u ); // Do not layout space for the cursor.
+}
+
+void TextVisual::DoSetOnStage( Actor& actor )
+{
+  // TODO Create the actual renderer(s) for the text!!!!
+  //      Will crash if no mImpl->mRenderer is set.
+  Geometry geometry;
+  Shader shader;
+
+  geometry = CreateGeometry( mFactoryCache, ImageDimensions( 1, 1 ) );
+
+  shader = mFactoryCache.GetShader( VisualFactoryCache::IMAGE_SHADER_ATLAS_DEFAULT_WRAP );
+  if( !shader )
+  {
+    shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER_ATLAS_CLAMP );
+    mFactoryCache.SaveShader( VisualFactoryCache::IMAGE_SHADER_ATLAS_DEFAULT_WRAP, shader );
+  }
+
+  mImpl->mRenderer = Renderer::New( geometry, shader );
+
+  mSelf = actor;
+
+  if( mHasBeenStaged )
+  {
+    RenderText();
+  }
+  else
+  {
+    mHasBeenStaged = true;
+  }
+}
+
+void TextVisual::DoSetOffStage( Actor& actor )
+{
+  mSelf.Reset();
+}
+
+void TextVisual::DoSetProperty( Dali::Property::Index index, const Dali::Property::Value& propertyValue )
+{
+  switch( index )
+  {
+    case Toolkit::TextVisual::Property::RENDERING_BACKEND:
+    {
+      int backend = propertyValue.Get<int>();
+
+#ifndef ENABLE_VECTOR_BASED_TEXT_RENDERING
+      if( Text::RENDERING_VECTOR_BASED == backend )
+      {
+        backend = TextAbstraction::BITMAP_GLYPH; // Fallback to bitmap-based rendering
+      }
+#endif
+      if( mRenderingBackend != backend )
+      {
+        mRenderingBackend = backend;
+        mRenderer.Reset();
+
+        // When using the vector-based rendering, the size of the GLyphs are different
+        TextAbstraction::GlyphType glyphType = ( Text::RENDERING_VECTOR_BASED == mRenderingBackend ) ? TextAbstraction::VECTOR_GLYPH : TextAbstraction::BITMAP_GLYPH;
+        mController->SetGlyphType( glyphType );
+      }
+      break;
+    }
+    case Toolkit::TextVisual::Property::TEXT:
+    {
+      mController->SetText( propertyValue.Get<std::string>() );
+      break;
+    }
+    case Toolkit::TextVisual::Property::FONT_FAMILY:
+    {
+      SetFontFamilyProperty( mController, propertyValue );
+      break;
+    }
+    case Toolkit::TextVisual::Property::FONT_STYLE:
+    {
+      SetFontStyleProperty( mController, propertyValue, Text::FontStyle::DEFAULT );
+      break;
+    }
+    case Toolkit::TextVisual::Property::POINT_SIZE:
+    {
+      const float pointSize = propertyValue.Get<float>();
+
+      if( !Equals( mController->GetDefaultPointSize(), pointSize ) )
+      {
+        mController->SetDefaultPointSize( pointSize );
+      }
+      break;
+    }
+    case Toolkit::TextVisual::Property::MULTI_LINE:
+    {
+      mController->SetMultiLineEnabled( propertyValue.Get<bool>() );
+      break;
+    }
+    case Toolkit::TextVisual::Property::HORIZONTAL_ALIGNMENT:
+    {
+      LayoutEngine::HorizontalAlignment alignment( LayoutEngine::HORIZONTAL_ALIGN_BEGIN );
+      if( Scripting::GetEnumeration< Toolkit::Text::LayoutEngine::HorizontalAlignment >( propertyValue.Get< std::string >().c_str(),
+                                                                                         HORIZONTAL_ALIGNMENT_STRING_TABLE,
+                                                                                         HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT,
+                                                                                         alignment ) )
+      {
+        mController->SetHorizontalAlignment( alignment );
+      }
+      break;
+    }
+    case Toolkit::TextVisual::Property::VERTICAL_ALIGNMENT:
+    {
+      LayoutEngine::VerticalAlignment alignment( LayoutEngine::VERTICAL_ALIGN_BOTTOM );
+      if( Scripting::GetEnumeration< Toolkit::Text::LayoutEngine::VerticalAlignment >( propertyValue.Get< std::string >().c_str(),
+                                                                                       VERTICAL_ALIGNMENT_STRING_TABLE,
+                                                                                       VERTICAL_ALIGNMENT_STRING_TABLE_COUNT,
+                                                                                       alignment ) )
+      {
+        mController->SetVerticalAlignment( alignment );
+      }
+      break;
+    }
+    case Toolkit::TextVisual::Property::TEXT_COLOR:
+    {
+      const Vector4 textColor = propertyValue.Get< Vector4 >();
+      if( mController->GetTextColor() != textColor )
+      {
+        mController->SetTextColor( textColor );
+        mRenderer.Reset();
+      }
+      break;
+    }
+    case Toolkit::TextVisual::Property::ENABLE_MARKUP:
+    {
+      const bool enableMarkup = propertyValue.Get<bool>();
+      mController->SetMarkupProcessorEnabled( enableMarkup );
+      break;
+    }
+    case Toolkit::TextVisual::Property::ENABLE_AUTO_SCROLL:
+    {
+      const bool enableAutoScroll = propertyValue.Get<bool>();
+
+      // If request to auto scroll is the same as current state then do nothing.
+      if( enableAutoScroll != mController->IsAutoScrollEnabled() )
+      {
+        // If request is disable (false) and auto scrolling is enabled then need to stop it
+        if( !enableAutoScroll )
+        {
+          StopTextAutoScrolling(); // Causes the current animation to finish playing.
+        }
+        // If request is enable (true) then start autoscroll as not already running
+        else
+        {
+          mController->GetLayoutEngine().SetTextEllipsisEnabled( false );
+          mController->SetAutoScrollEnabled( enableAutoScroll );
+          mController->RequestRelayout();
+        }
+      }
+      break;
+    }
+    case Toolkit::TextVisual::Property::AUTO_SCROLL_SPEED:
+    {
+      mController->SetAutoscrollSpeed( propertyValue.Get<int>() );
+      break;
+    }
+    case Toolkit::TextVisual::Property::AUTO_SCROLL_LOOP_COUNT:
+    {
+      const int loopCount = propertyValue.Get<int>();
+      if( loopCount > 0 )
+      {
+        mController->SetAutoScrollLoopCount( loopCount );
+      }
+      else
+      {
+        StopTextAutoScrolling(); // Causes the current animation to finish playing.
+      }
+      break;
+    }
+    case Toolkit::TextVisual::Property::AUTO_SCROLL_GAP:
+    {
+      mController->SetAutoScrollWrapGap( propertyValue.Get<float>() );
+      break;
+    }
+    case Toolkit::TextVisual::Property::LINE_SPACING:
+    {
+      const float lineSpacing = propertyValue.Get<float>();
+      mController->SetDefaultLineSpacing( lineSpacing );
+      mRenderer.Reset();
+      break;
+    }
+    case Toolkit::TextVisual::Property::UNDERLINE:
+    {
+      // TODO : This switch can be removed when the deprecated SHADOW_OFFSET and SHADOW_COLOR properties are finally removed.
+      //        Only the code for the STRING case should be kept.
+      switch( propertyValue.GetType() )
+      {
+        case Property::VECTOR4:
+        {
+          const Vector4 color = propertyValue.Get<Vector4>();
+          if( mController->GetUnderlineColor() != color )
+          {
+            mController->SetUnderlineColor( color );
+            mRenderer.Reset();
+          }
+          break;
+        }
+        case Property::FLOAT:
+        {
+          float height = propertyValue.Get<float>();
+          if( fabsf( mController->GetUnderlineHeight() - height ) > Math::MACHINE_EPSILON_1000 )
+          {
+            mController->SetUnderlineHeight( height );
+            mRenderer.Reset();
+          }
+          break;
+        }
+        case Property::BOOLEAN:
+        {
+          const bool enabled = propertyValue.Get<bool>();
+          if( mController->IsUnderlineEnabled() != enabled )
+          {
+            mController->SetUnderlineEnabled( enabled );
+            mRenderer.Reset();
+          }
+          break;
+        }
+        case Property::STRING:
+        {
+          const bool update = SetUnderlineProperties( mController, propertyValue, Text::EffectStyle::DEFAULT );
+          if( update )
+          {
+            mRenderer.Reset();
+          }
+          break;
+        }
+        default:
+        {
+          // Nothing to do.
+          break;
+        }
+      }
+
+      break;
+    }
+    case Toolkit::TextVisual::Property::SHADOW:
+    {
+      // TODO : This switch can be removed when the deprecated SHADOW_OFFSET and SHADOW_COLOR properties are finally removed.
+      //        Only the code for the STRING case should be kept.
+      switch( propertyValue.GetType() )
+      {
+        case Property::VECTOR2:
+        {
+          const Vector2 shadowOffset = propertyValue.Get<Vector2>();
+          if( mController->GetShadowOffset() != shadowOffset )
+          {
+            mController->SetShadowOffset( shadowOffset );
+            mRenderer.Reset();
+          }
+          break;
+        }
+        case Property::VECTOR4:
+        {
+          const Vector4 shadowColor = propertyValue.Get<Vector4>();
+          if( mController->GetShadowColor() != shadowColor )
+          {
+            mController->SetShadowColor( shadowColor );
+            mRenderer.Reset();
+          }
+          break;
+        }
+        case Property::STRING:
+        {
+          const bool update = SetShadowProperties( mController, propertyValue, Text::EffectStyle::DEFAULT );
+          if( update )
+          {
+            mRenderer.Reset();
+          }
+          break;
+        }
+        default:
+        {
+          // Nothing to do.
+          break;
+        }
+      }
+      break;
+    }
+    case Toolkit::TextVisual::Property::EMBOSS:
+    {
+      const bool update = SetEmbossProperties( mController, propertyValue, Text::EffectStyle::DEFAULT );
+      if( update )
+      {
+        mRenderer.Reset();
+     }
+      break;
+    }
+    case Toolkit::TextVisual::Property::OUTLINE:
+    {
+      const bool update = SetOutlineProperties( mController, propertyValue, Text::EffectStyle::DEFAULT );
+      if( update )
+      {
+        mRenderer.Reset();
+      }
+      break;
+    }
+    case Toolkit::TextVisual::Property::BATCHING_ENABLED:
+    {
+      // TODO
+      break;
+    }
+    default:
+    {
+      // Should not arrive here.
+      DALI_ASSERT_DEBUG( false );
+    }
+  }
+}
+
+Dali::Property::Value TextVisual::DoGetProperty( Dali::Property::Index index )
+{
+  Dali::Property::Value value;
+
+  switch( index )
+  {
+    case Toolkit::TextVisual::Property::RENDERING_BACKEND:
+    {
+      value = mRenderingBackend;
+      break;
+    }
+    case Toolkit::TextVisual::Property::TEXT:
+    {
+      std::string text;
+      mController->GetText( text );
+      value = text;
+      break;
+    }
+    case Toolkit::TextVisual::Property::FONT_FAMILY:
+    {
+      value = mController->GetDefaultFontFamily();
+      break;
+    }
+    case Toolkit::TextVisual::Property::FONT_STYLE:
+    {
+      GetFontStyleProperty( mController, value, Text::FontStyle::DEFAULT );
+      break;
+    }
+    case Toolkit::TextVisual::Property::POINT_SIZE:
+    {
+      value = mController->GetDefaultPointSize();
+      break;
+    }
+    case Toolkit::TextVisual::Property::MULTI_LINE:
+    {
+      value = mController->IsMultiLineEnabled();
+      break;
+    }
+    case Toolkit::TextVisual::Property::HORIZONTAL_ALIGNMENT:
+    {
+      const char* name = Scripting::GetEnumerationName< Toolkit::Text::LayoutEngine::HorizontalAlignment >( mController->GetHorizontalAlignment(),
+                                                                                                            HORIZONTAL_ALIGNMENT_STRING_TABLE,
+                                                                                                            HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT );
+      if( name )
+      {
+        value = std::string( name );
+      }
+      break;
+    }
+    case Toolkit::TextVisual::Property::VERTICAL_ALIGNMENT:
+    {
+      const char* name = Scripting::GetEnumerationName< Toolkit::Text::LayoutEngine::VerticalAlignment >( mController->GetVerticalAlignment(),
+                                                                                                          VERTICAL_ALIGNMENT_STRING_TABLE,
+                                                                                                          VERTICAL_ALIGNMENT_STRING_TABLE_COUNT );
+      if( name )
+      {
+        value = std::string( name );
+      }
+      break;
+    }
+    case Toolkit::TextVisual::Property::TEXT_COLOR:
+    {
+      value = mController->GetTextColor();
+      break;
+    }
+    case Toolkit::TextVisual::Property::ENABLE_MARKUP:
+    {
+      value = mController->IsMarkupProcessorEnabled();
+      break;
+    }
+    case Toolkit::TextVisual::Property::ENABLE_AUTO_SCROLL:
+    {
+      value = mController->IsAutoScrollEnabled();
+      break;
+    }
+    case Toolkit::TextVisual::Property::AUTO_SCROLL_SPEED:
+    {
+      value = mController->GetAutoScrollSpeed();
+      break;
+    }
+    case Toolkit::TextVisual::Property::AUTO_SCROLL_LOOP_COUNT:
+    {
+      value = mController->GetAutoScrollLoopCount();
+      break;
+    }
+    case Toolkit::TextVisual::Property::AUTO_SCROLL_GAP:
+    {
+      value = mController->GetAutoScrollWrapGap();
+      break;
+    }
+    case Toolkit::TextVisual::Property::LINE_SPACING:
+    {
+      value = mController->GetDefaultLineSpacing();
+      break;
+    }
+    case Toolkit::TextVisual::Property::UNDERLINE:
+    {
+      GetUnderlineProperties( mController, value, Text::EffectStyle::DEFAULT );
+      break;
+    }
+    case Toolkit::TextVisual::Property::SHADOW:
+    {
+      GetShadowProperties( mController, value, Text::EffectStyle::DEFAULT );
+      break;
+    }
+    case Toolkit::TextVisual::Property::EMBOSS:
+    {
+      GetEmbossProperties( mController, value, Text::EffectStyle::DEFAULT );
+      break;
+    }
+    case Toolkit::TextVisual::Property::OUTLINE:
+    {
+      GetOutlineProperties( mController, value, Text::EffectStyle::DEFAULT );
+      break;
+    }
+    case Toolkit::TextVisual::Property::BATCHING_ENABLED:
+    {
+      // TODO
+      break;
+    }
+    default:
+    {
+      // Should not arrive here.
+      DALI_ASSERT_DEBUG( false );
+    }
+  }
+
+  return value;
+}
+
+void TextVisual::RenderText()
+{
+  Actor self = mSelf.GetHandle();
+  if( !self )
+  {
+    // Nothing to do if the handle is not initialized.
+    return;
+  }
+
+  Actor renderableActor;
+
+  if( mRenderer )
+  {
+    renderableActor = mRenderer->Render( mController->GetView(), Toolkit::DepthIndex::TEXT );
+  }
+
+  if( renderableActor != mRenderableActor )
+  {
+    UnparentAndReset( mRenderableActor );
+
+    if( renderableActor )
+    {
+      const Vector2& scrollOffset = mController->GetScrollPosition();
+      renderableActor.SetPosition( scrollOffset.x, scrollOffset.y );
+
+      self.Add( renderableActor );
+    }
+    mRenderableActor = renderableActor;
+
+    if( mController->IsAutoScrollEnabled() )
+    {
+      SetUpAutoScrolling();
+    }
+  }
+}
+
+void TextVisual::StopTextAutoScrolling()
+{
+  if( mTextScroller )
+  {
+    mTextScroller->StopScrolling();
+  }
+}
+
+void TextVisual::SetUpAutoScrolling()
+{
+  Actor self = mSelf.GetHandle();
+  if( !self )
+  {
+    // Nothing to do if the handle is not initialized.
+    return;
+  }
+
+  const Text::ScrollerData* const data = mController->GetAutoScrollData();
+
+  if( NULL != data )
+  {
+    if( !mTextScroller )
+    {
+      // If speed, loopCount or gap not set via property system then will need to create a TextScroller with defaults
+      mTextScroller = Text::TextScroller::New( *mController );
+    }
+
+    mTextScroller->StartScrolling( mRenderableActor,
+                                   *data );
+
+    self.Add( mTextScroller->GetScrollingText() );
+    self.Add( mTextScroller->GetSourceCamera() );
+  }
+}
+
+} // namespace Internal
+
+} // namespace Toolkit
+
+} // namespace Dali
diff --git a/dali-toolkit/internal/visuals/text/text-visual.h b/dali-toolkit/internal/visuals/text/text-visual.h
new file mode 100644 (file)
index 0000000..47289d1
--- /dev/null
@@ -0,0 +1,188 @@
+#ifndef DALI_TOOLKIT_INTERNAL_TEXT_VISUAL_H
+#define DALI_TOOLKIT_INTERNAL_TEXT_VISUAL_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.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/devel-api/object/weak-handle.h>
+#include <dali/public-api/common/intrusive-ptr.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/visuals/visual-base-impl.h>
+#include <dali-toolkit/internal/text/rendering/text-renderer.h>
+#include <dali-toolkit/internal/text/text-controller.h>
+#include <dali-toolkit/internal/text/text-scroller.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+class TextVisual;
+typedef IntrusivePtr< TextVisual > TextVisualPtr;
+
+/**
+ * The visual which renders text
+ *
+ * The following properties are optional:
+ *
+ * | %Property Name      | Type    |
+ * |---------------------|---------|
+ * | renderingBackend    | INTEGER |
+ * | text                | STRING  |
+ * | fontFamily          | STRING  |
+ * | fontStyle           | STRING  |
+ * | pointSize           | FLOAT   |
+ * | multiLine           | BOOLEAN |
+ * | horizontalAlignment | STRING  |
+ * | verticalAlignment   | STRING  |
+ * | textColor           | VECTOR4 |
+ * | enableMarkup        | BOOLEAN |
+ * | enableAutoScroll    | BOOLEAN |
+ * | autoScrollSpeed     | INTEGER |
+ * | autoScrollLoopCount | INTEGER |
+ * | autoScrollGap       | INTEGER |
+ * | lineSpacing         | FLOAT   |
+ * | underline           | STRING  |
+ * | shadow              | STRING  |
+ * | outline             | STRING  |
+ * | batchingEnabled     | BOOLEAN |
+ *
+ */
+class TextVisual : public Visual::Base
+{
+public:
+
+  /**
+   * @brief Create a new text visual.
+   *
+   * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object
+   * @return A smart-pointer to the newly allocated visual.
+   */
+  static TextVisualPtr New( VisualFactoryCache& factoryCache );
+
+  /**
+   * @brief Sets the text control interface which is needed to communicate with a control.
+   * @param[in] controlInterface Pointer to the control-interface.
+   */
+  void SetTextControlInterface( Text::ControlInterface* controlInterface );
+
+public: // from Visual::Base
+
+  /**
+   * @copydoc Visual::Base::GetHeightForWidth()
+   */
+  float GetHeightForWidth( float width ) const;
+
+  /**
+   * @copydoc Visual::Base::GetNaturalSize()
+   */
+  virtual void SetSize( const Vector2& size );
+
+  /**
+   * @copydoc Visual::Base::GetNaturalSize()
+   */
+  virtual void GetNaturalSize( Vector2& naturalSize ) const;
+
+  /**
+   * @copydoc Visual::Base::CreatePropertyMap()
+   */
+  virtual void DoCreatePropertyMap( Property::Map& map ) const;
+
+protected:
+
+  /**
+   * @brief Constructor.
+   *
+   * @param[in] factoryCache The VisualFactoryCache object
+   */
+  TextVisual( VisualFactoryCache& factoryCache );
+
+  /**
+   * @brief A reference counted object may only be deleted by calling Unreference().
+   */
+  virtual ~TextVisual();
+
+  // from Visual::Base
+
+  /**
+   * @copydoc Visual::Base::DoSetProperties()
+   */
+  virtual void DoSetProperties( const Property::Map& propertyMap );
+
+  /**
+   * @copydoc Visual::Base::DoSetOnStage()
+   */
+  virtual void DoSetOnStage( Actor& actor );
+
+  /**
+   * @copydoc Visual::Base::DoSetOffStage()
+   */
+  virtual void DoSetOffStage( Actor& actor );
+
+  /**
+   *@copydoc Visual::Base::DoSetProperty
+   */
+  virtual void DoSetProperty( Dali::Property::Index index, const Dali::Property::Value& propertyValue );
+
+  /**
+   * @copydoc Visual::Base::DoGetProperty
+   */
+  virtual Dali::Property::Value DoGetProperty( Dali::Property::Index index );
+
+private:
+
+  /**
+   * @brief Render view, create and attach actor(s) to this TextView.
+   * @todo In a next patch a new text render back-end won't add extra actors.
+   */
+  void RenderText();
+
+  /**
+   * @brief Stops the text auto scroll.
+   */
+  void StopTextAutoScrolling();
+
+  /**
+   * @brief Set up Autoscrolling.
+   */
+  void SetUpAutoScrolling();
+
+private:
+  Text::ControllerPtr          mController;               ///< The text's controller.
+  WeakHandle<Actor>            mSelf;
+
+  Text::RendererPtr            mRenderer;
+  Text::TextScrollerPtr        mTextScroller;
+  Actor                        mRenderableActor;
+
+  int mRenderingBackend;
+  bool mHasBeenStaged           : 1;
+};
+
+} // namespace Internal
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif /* DALI_TOOLKIT_INTERNAL_TEXT_VISUAL_H */
diff --git a/dali-toolkit/internal/visuals/transition-data-impl.cpp b/dali-toolkit/internal/visuals/transition-data-impl.cpp
new file mode 100644 (file)
index 0000000..8ccb354
--- /dev/null
@@ -0,0 +1,385 @@
+/*
+ * 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.
+ *
+ */
+
+// CLASS HEADER
+#include <dali-toolkit/internal/visuals/transition-data-impl.h>
+
+// EXTERNAL HEADERS
+#include <dali/dali.h>
+#include <dali/devel-api/scripting/enum-helper.h>
+#include <dali/integration-api/debug.h>
+#include <dali-toolkit/public-api/controls/control.h>
+#include <dali-toolkit/public-api/controls/control-impl.h>
+#include <sstream>
+
+using namespace Dali;
+
+namespace
+{
+const char* TOKEN_TARGET("target");
+const char* TOKEN_PROPERTY("property");
+const char* TOKEN_INITIAL_VALUE("initialValue");
+const char* TOKEN_TARGET_VALUE("targetValue");
+const char* TOKEN_ANIMATOR("animator");
+const char* TOKEN_TIME_PERIOD("timePeriod");
+const char* TOKEN_DURATION("duration");
+const char* TOKEN_DELAY("delay");
+const char* TOKEN_ALPHA_FUNCTION("alphaFunction");
+
+
+DALI_ENUM_TO_STRING_TABLE_BEGIN( ALPHA_FUNCTION_BUILTIN )
+DALI_ENUM_TO_STRING_WITH_SCOPE(AlphaFunction, LINEAR)
+DALI_ENUM_TO_STRING_WITH_SCOPE(AlphaFunction, REVERSE)
+DALI_ENUM_TO_STRING_WITH_SCOPE(AlphaFunction, EASE_IN)
+DALI_ENUM_TO_STRING_WITH_SCOPE(AlphaFunction, EASE_OUT)
+DALI_ENUM_TO_STRING_WITH_SCOPE(AlphaFunction, EASE_IN_OUT)
+DALI_ENUM_TO_STRING_WITH_SCOPE(AlphaFunction, EASE_IN_SQUARE)
+DALI_ENUM_TO_STRING_WITH_SCOPE(AlphaFunction, EASE_OUT_SQUARE)
+DALI_ENUM_TO_STRING_WITH_SCOPE(AlphaFunction, EASE_IN_SINE)
+DALI_ENUM_TO_STRING_WITH_SCOPE(AlphaFunction, EASE_OUT_SINE)
+DALI_ENUM_TO_STRING_WITH_SCOPE(AlphaFunction, EASE_IN_OUT_SINE)
+DALI_ENUM_TO_STRING_WITH_SCOPE(AlphaFunction, EASE_OUT_BACK)
+DALI_ENUM_TO_STRING_WITH_SCOPE(AlphaFunction, BOUNCE)
+DALI_ENUM_TO_STRING_WITH_SCOPE(AlphaFunction, SIN)
+DALI_ENUM_TO_STRING_TABLE_END( ALPHA_FUNCTION_BUILTIN )
+}
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Internal
+{
+
+TransitionData::TransitionData()
+{
+}
+
+TransitionData::~TransitionData()
+{
+}
+
+TransitionDataPtr TransitionData::New( const Property::Array& value )
+{
+  TransitionDataPtr transitionData( new TransitionData() );
+  transitionData->Initialize(value);
+  return transitionData;
+}
+
+TransitionDataPtr TransitionData::New( const Property::Map& value )
+{
+  TransitionDataPtr transitionData( new TransitionData() );
+  transitionData->Initialize(value);
+  return transitionData;
+}
+
+
+void TransitionData::Initialize( const Property::Map& map )
+{
+  TransitionData::Animator* animator = ConvertMap( map );
+  Add( animator );
+}
+
+void TransitionData::Initialize( const Property::Array& array )
+{
+  for( unsigned int arrayIdx = 0, transitionArrayCount = array.Count(); arrayIdx < transitionArrayCount; ++arrayIdx )
+  {
+    const Property::Value& element = array.GetElementAt( arrayIdx );
+    // Expect each child to be an object representing an animator:
+
+    Property::Map* map = element.GetMap();
+    if( map != NULL )
+    {
+      TransitionData::Animator* animator = ConvertMap( *map );
+      Add( animator );
+    }
+  }
+}
+
+TransitionData::Animator* TransitionData::ConvertMap( const Property::Map& map)
+{
+  TransitionData::Animator* animator = new TransitionData::Animator();
+  animator->alphaFunction = AlphaFunction::LINEAR;
+  animator->timePeriodDelay = 0.0f;
+  animator->timePeriodDuration = 1.0f;
+
+  for( unsigned int mapIdx = 0; mapIdx < map.Count(); ++mapIdx )
+  {
+    const KeyValuePair pair( map.GetKeyValue( mapIdx ) );
+    if( pair.first.type == Property::Key::INDEX )
+    {
+      continue; // We don't consider index keys.
+    }
+
+    const std::string& key( pair.first.stringKey );
+    const Property::Value& value( pair.second );
+
+    if( key == TOKEN_TARGET )
+    {
+      animator->objectName = value.Get< std::string >();
+    }
+    else if( key == TOKEN_PROPERTY )
+    {
+      if( value.GetType() == Property::STRING )
+      {
+        animator->propertyKey = Property::Key( value.Get<std::string>() );
+      }
+      else
+      {
+        animator->propertyKey = Property::Key( value.Get<int>() );
+      }
+    }
+    else if( key == TOKEN_INITIAL_VALUE )
+    {
+      animator->initialValue = value;
+    }
+    else if( key == TOKEN_TARGET_VALUE )
+    {
+      animator->targetValue = value;
+    }
+    else if( key == TOKEN_ANIMATOR )
+    {
+      animator->animate = true;
+      Property::Map animatorMap = value.Get< Property::Map >();
+      for( size_t animatorMapIdx = 0; animatorMapIdx < animatorMap.Count(); ++animatorMapIdx )
+      {
+        const KeyValuePair pair( animatorMap.GetKeyValue( animatorMapIdx ) );
+
+        if( pair.first.type == Property::Key::INDEX )
+        {
+          continue; // We don't consider index keys.
+        }
+
+        const std::string& key( pair.first.stringKey );
+        const Property::Value& value( pair.second );
+
+        if( key == TOKEN_ALPHA_FUNCTION )
+        {
+          if( value.GetType() == Property::ARRAY )
+          {
+            bool valid = true;
+            Vector4 controlPoints;
+            Property::Array *array = value.GetArray();
+            if( array->Count() >= 4 )
+            {
+              for( size_t vecIdx = 0; vecIdx < 4; ++vecIdx )
+              {
+                Property::Value& v = array->GetElementAt(vecIdx);
+                if( v.GetType() == Property::FLOAT )
+                {
+                  controlPoints[vecIdx] = v.Get<float>();
+                }
+                else
+                {
+                  valid = false;
+                  break;
+                }
+              }
+            }
+            else
+            {
+              valid = false;
+            }
+
+            if( valid )
+            {
+              Vector2 controlPoint1( controlPoints.x, controlPoints.y );
+              Vector2 controlPoint2( controlPoints.z, controlPoints.w );
+              animator->alphaFunction = AlphaFunction( controlPoint1, controlPoint2 );
+            }
+            else
+            {
+              animator->animate = false;
+            }
+          }
+          else if( value.GetType() == Property::VECTOR4 )
+          {
+            Vector4 controlPoints = value.Get<Vector4>();
+            Vector2 controlPoint1( controlPoints.x, controlPoints.y );
+            Vector2 controlPoint2( controlPoints.z, controlPoints.w );
+            animator->alphaFunction = AlphaFunction( controlPoint1, controlPoint2 );
+          }
+          else if( value.GetType() == Property::STRING )
+          {
+            std::string alphaFunctionValue = value.Get< std::string >();
+
+            if( alphaFunctionValue == "LINEAR" )
+            {
+              animator->alphaFunction = AlphaFunction(AlphaFunction::LINEAR);
+            }
+            else if( ! alphaFunctionValue.compare(0, 5, "EASE_" ) )
+            {
+              if( alphaFunctionValue == "EASE_IN" )
+              {
+                animator->alphaFunction = AlphaFunction(AlphaFunction::EASE_IN);
+              }
+              else if( alphaFunctionValue == "EASE_OUT" )
+              {
+                animator->alphaFunction = AlphaFunction(AlphaFunction::EASE_OUT);
+              }
+              else if( ! alphaFunctionValue.compare( 5, 3, "IN_" ) )
+              {
+                if( ! alphaFunctionValue.compare(8, -1, "SQUARE" ))
+                {
+                  animator->alphaFunction = AlphaFunction(AlphaFunction::EASE_IN_SQUARE);
+                }
+                else if( ! alphaFunctionValue.compare(8, -1, "OUT" ))
+                {
+                  animator->alphaFunction = AlphaFunction(AlphaFunction::EASE_IN_OUT);
+                }
+                else if( ! alphaFunctionValue.compare(8, -1, "OUT_SINE" ))
+                {
+                  animator->alphaFunction = AlphaFunction(AlphaFunction::EASE_IN_OUT_SINE);
+                }
+                else if( ! alphaFunctionValue.compare(8, -1, "SINE" ))
+                {
+                  animator->alphaFunction = AlphaFunction(AlphaFunction::EASE_IN_SINE);
+                }
+              }
+              else if( ! alphaFunctionValue.compare( 5, 4, "OUT_" ) )
+              {
+                if( ! alphaFunctionValue.compare(9, -1, "SQUARE" ) )
+                {
+                  animator->alphaFunction = AlphaFunction(AlphaFunction::EASE_OUT_SQUARE);
+                }
+                else if( ! alphaFunctionValue.compare(9, -1, "SINE" ) )
+                {
+                  animator->alphaFunction = AlphaFunction(AlphaFunction::EASE_OUT_SINE);
+                }
+                else if( ! alphaFunctionValue.compare(9, -1, "BACK" ) )
+                {
+                  animator->alphaFunction = AlphaFunction(AlphaFunction::EASE_OUT_BACK);
+                }
+              }
+            }
+            else if( alphaFunctionValue == "REVERSE" )
+            {
+              animator->alphaFunction = AlphaFunction(AlphaFunction::REVERSE);
+            }
+            else if( alphaFunctionValue == "BOUNCE" )
+            {
+              animator->alphaFunction = AlphaFunction(AlphaFunction::BOUNCE);
+            }
+            else if( alphaFunctionValue == "SIN" )
+            {
+              animator->alphaFunction = AlphaFunction(AlphaFunction::SIN);
+            }
+          }
+          else
+          {
+            animator->animate = false;
+          }
+        }
+        else if( key == TOKEN_TIME_PERIOD )
+        {
+          Property::Map timeMap = value.Get< Property::Map >();
+          for( size_t timeMapIdx = 0; timeMapIdx < timeMap.Count(); ++timeMapIdx )
+          {
+            const KeyValuePair pair( timeMap.GetKeyValue( timeMapIdx ) );
+            if( pair.first.type == Property::Key::INDEX )
+            {
+              continue;
+            }
+            const std::string& key( pair.first.stringKey );
+
+            if( key == TOKEN_DELAY )
+            {
+              animator->timePeriodDelay = pair.second.Get< float >();
+            }
+            else if( key == TOKEN_DURATION )
+            {
+              animator->timePeriodDuration = pair.second.Get< float >();
+            }
+          }
+        }
+      }
+    }
+  }
+  return animator;
+}
+
+void TransitionData::Add( Animator* animator )
+{
+  mAnimators.PushBack( animator );
+}
+
+TransitionData::Iterator TransitionData::Begin() const
+{
+  return mAnimators.Begin();
+}
+
+TransitionData::Iterator TransitionData::End() const
+{
+  return mAnimators.End();
+}
+
+size_t TransitionData::Count() const
+{
+  return mAnimators.Count();
+}
+
+Property::Map TransitionData::GetAnimatorAt( size_t index )
+{
+  DALI_ASSERT_ALWAYS( index < Count() && "index exceeds bounds" );
+
+  Animator* animator = mAnimators[index];
+  Property::Map map;
+  map[TOKEN_TARGET] = animator->objectName;
+  if( animator->propertyKey.type == Property::Key::INDEX )
+  {
+    map[TOKEN_PROPERTY] = animator->propertyKey.indexKey;
+  }
+  else
+  {
+    map[TOKEN_PROPERTY] = animator->propertyKey.stringKey;
+  }
+  if( animator->initialValue.GetType() != Property::NONE )
+  {
+    map[TOKEN_INITIAL_VALUE] = animator->initialValue;
+  }
+  if( animator->targetValue.GetType() != Property::NONE )
+  {
+    map[TOKEN_TARGET_VALUE] = animator->targetValue;
+  }
+  if( animator->animate )
+  {
+    Property::Map animateMap;
+
+    if( animator->alphaFunction.GetMode() == AlphaFunction::BUILTIN_FUNCTION )
+    {
+      animateMap.Add(TOKEN_ALPHA_FUNCTION, GetEnumerationName( animator->alphaFunction.GetBuiltinFunction(),
+                                                               ALPHA_FUNCTION_BUILTIN_TABLE,
+                                                               ALPHA_FUNCTION_BUILTIN_TABLE_COUNT ));
+    }
+    else if( animator->alphaFunction.GetMode() == AlphaFunction::BEZIER )
+    {
+      Vector4 controlPoints = animator->alphaFunction.GetBezierControlPoints();
+      animateMap.Add( TOKEN_ALPHA_FUNCTION, controlPoints );
+    }
+    animateMap.Add(TOKEN_TIME_PERIOD, Property::Map()
+                   .Add( TOKEN_DELAY, animator->timePeriodDelay )
+                   .Add( TOKEN_DURATION, animator->timePeriodDuration ));
+
+    map[TOKEN_ANIMATOR] = animateMap;
+  }
+
+  return map;
+}
+
+} // namespace Internal
+} // namespace Toolkit
+} // namespace Dali
diff --git a/dali-toolkit/internal/visuals/transition-data-impl.h b/dali-toolkit/internal/visuals/transition-data-impl.h
new file mode 100644 (file)
index 0000000..9ca8193
--- /dev/null
@@ -0,0 +1,170 @@
+#ifndef DALI_TOOLKIT_INTERNAL_TRANSITION_DATA_H
+#define DALI_TOOLKIT_INTERNAL_TRANSITION_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.
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/object/base-object.h>
+#include <dali/public-api/animation/alpha-function.h>
+#include <dali/public-api/object/property-key.h>
+#include <dali/devel-api/common/owner-container.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/devel-api/visual-factory/transition-data.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Internal
+{
+
+class TransitionData;
+typedef IntrusivePtr<TransitionData> TransitionDataPtr;
+
+/**
+ * TransitionData is an object that holds animator data.
+ */
+class TransitionData : public BaseObject
+{
+public:
+
+  /**
+   * @brief TransitionDataElement Describes one animator of an transition.
+   */
+  struct Animator
+  {
+    Animator()
+    : propertyKey( Property::INVALID_INDEX ),
+      alphaFunction( AlphaFunction::DEFAULT ),
+      timePeriodDelay( 0.0f ),
+      timePeriodDuration( 1.0f ),
+      animate(false)
+    {
+    }
+
+    std::string objectName;   ///< An identifier of the actor or visual
+    Property::Key propertyKey; ///< A property key of the property owner
+    Property::Value initialValue; ///< The value to set at the start of the transition
+    Property::Value targetValue;   ///< The value to set or animate to
+    Dali::AlphaFunction alphaFunction;
+    float timePeriodDelay;
+    float timePeriodDuration;
+    bool animate;
+  };
+
+  /**
+   * @brief TransitionData holds the required data required to define an
+   * transition to be performed on a property owner
+   */
+  typedef Dali::OwnerContainer< Animator* > AnimatorList;
+  typedef AnimatorList::Iterator Iterator;
+
+public:
+  /**
+   * @copydoc Dali::Transition::New()
+   */
+  static TransitionDataPtr New( const Property::Array& value );
+
+  /**
+   * @copydoc Dali::Transition::New()
+   */
+  static TransitionDataPtr New( const Property::Map& value );
+
+  /**
+   * @brief Iterator to the beginning of the data
+   */
+  Iterator Begin() const;
+
+  /**
+   * @brief Iterator to the end of the data (one past last element)
+   */
+  Iterator End() const;
+
+  /**
+   * @copydoc Dali::Transition::Count()
+   */
+  size_t Count() const;
+
+  /**
+   * @copydoc Dali::Transition::GetAnimatorAt()
+   */
+  Property::Map GetAnimatorAt( size_t index );
+
+private: // Implementation
+  /**
+   * Ref counted object - Only allow construction via New().
+   */
+  TransitionData();
+
+  /**
+   * Second stage initialiazation
+   */
+  void Initialize( const Property::Map& value );
+
+  /**
+   * Second stage initialiazation
+   */
+  void Initialize( const Property::Array& value );
+
+  /**
+   * @brief Adds one Animator to the list to describe a transition.
+   * @param[in] animator An animator data structure
+   */
+  void Add( Animator* animator );
+
+  /**
+   * Convert a Property map into Animator data
+   */
+  Animator* ConvertMap( const Property::Map& map );
+
+protected:
+  /**
+   *  A ref counted object may only be deleted by calling Unreference
+   */
+  virtual ~TransitionData();
+
+private: // Unimplemented methods
+  TransitionData( const TransitionData& );
+  TransitionData& operator=( const TransitionData& );
+
+private: // Data members
+  AnimatorList mAnimators; ///< A vector of individual property transitions from which to generate a Dali::Animation.
+};
+
+} // namespace Internal
+
+// Helpers for public-api forwarding methods
+inline Internal::TransitionData& GetImplementation( Dali::Toolkit::TransitionData& handle )
+{
+  DALI_ASSERT_ALWAYS(handle && "TransitionData handle is empty");
+  BaseObject& object = handle.GetBaseObject();
+  return static_cast<Internal::TransitionData&>(object);
+}
+
+inline const Internal::TransitionData& GetImplementation( const Dali::Toolkit::TransitionData& handle )
+{
+  DALI_ASSERT_ALWAYS(handle && "TransitionData handle is empty");
+  const BaseObject& object = handle.GetBaseObject();
+  return static_cast<const Internal::TransitionData&>(object);
+}
+
+} // namespace Toolkit
+} // namespace Dali
+
+
+#endif // DALI_TOOLKIT_INTERNAL_TRANSITION_DATA_H
index 524057e..c4877b4 100644 (file)
@@ -60,13 +60,12 @@ struct Base::Impl
     void CreatePropertyMap( Property::Map& map ) const;
   };
 
-  Renderer mRenderer;
-
+  Renderer      mRenderer;
   CustomShader* mCustomShader;
-
-  Vector2   mSize;
-  float     mDepthIndex;
-  int       mFlags;
+  std::string   mName;
+  Vector2       mSize;
+  float         mDepthIndex;
+  int           mFlags;
 
   Impl();
   ~Impl();
index 8356de5..d152a7f 100644 (file)
@@ -55,11 +55,11 @@ void Visual::Base::SetCustomShader( const Property::Map& shaderMap )
   }
   else
   {
-   mImpl->mCustomShader = new Impl::CustomShader( shaderMap );
+    mImpl->mCustomShader = new Impl::CustomShader( shaderMap );
   }
 }
 
-void Visual::Base::Initialize( Actor& actor, const Property::Map& propertyMap )
+void Visual::Base::SetProperties( const Property::Map& propertyMap )
 {
   Property::Value* customShaderValue = propertyMap.Find( Toolkit::Visual::Property::SHADER, CUSTOM_SHADER );
   if( customShaderValue )
@@ -71,7 +71,17 @@ void Visual::Base::Initialize( Actor& actor, const Property::Map& propertyMap )
     }
   }
 
-  DoInitialize( actor, propertyMap );
+  DoSetProperties( propertyMap );
+}
+
+void Visual::Base::SetName( const std::string& name )
+{
+  mImpl->mName = name;
+}
+
+const std::string& Visual::Base::GetName()
+{
+  return mImpl->mName;
 }
 
 void Visual::Base::SetSize( const Vector2& size )
@@ -84,6 +94,11 @@ const Vector2& Visual::Base::GetSize() const
   return mImpl->mSize;
 }
 
+float Visual::Base::GetHeightForWidth( float width ) const
+{
+  return 0.f;
+}
+
 void Visual::Base::GetNaturalSize( Vector2& naturalSize ) const
 {
   naturalSize = Vector2::ZERO;
@@ -116,7 +131,7 @@ void Visual::Base::SetOnStage( Actor& actor )
 
 void Visual::Base::SetOffStage( Actor& actor )
 {
-  if( GetIsOnStage() )
+  if( IsOnStage() )
   {
     DoSetOffStage( actor );
 
@@ -124,6 +139,16 @@ void Visual::Base::SetOffStage( Actor& actor )
   }
 }
 
+void Visual::Base::CreatePropertyMap( Property::Map& map ) const
+{
+  DoCreatePropertyMap( map );
+
+  if( mImpl->mCustomShader )
+  {
+    mImpl->mCustomShader->CreatePropertyMap( map );
+  }
+}
+
 void Visual::Base::EnablePreMultipliedAlpha( bool preMultipled )
 {
   if(preMultipled)
@@ -152,24 +177,50 @@ void Visual::Base::DoSetOffStage( Actor& actor )
   mImpl->mRenderer.Reset();
 }
 
-void Visual::Base::CreatePropertyMap( Property::Map& map ) const
+bool Visual::Base::IsOnStage() const
 {
-  DoCreatePropertyMap( map );
+  return mImpl->mFlags & Impl::IS_ON_STAGE;
+}
 
-  if( mImpl->mCustomShader )
-  {
-    mImpl->mCustomShader->CreatePropertyMap( map );
-  }
+bool Visual::Base::IsFromCache() const
+{
+  return mImpl->mFlags & Impl::IS_FROM_CACHE;
 }
 
-bool Visual::Base::GetIsOnStage() const
+void Visual::Base::SetProperty( Dali::Property::Index index, const Dali::Property::Value& propertyValue )
 {
-  return mImpl->mFlags & Impl::IS_ON_STAGE;
+  DALI_ASSERT_ALWAYS( ( index > Property::INVALID_INDEX ) &&
+                      ( index > VISUAL_PROPERTY_BASE_START_INDEX ) && // Change the type of visual is not allowed.
+                      "Property index is out of bounds" );
+
+  if( index < VISUAL_PROPERTY_START_INDEX )
+  {
+    // TODO set the properties of the visual base.
+  }
+  else
+  {
+    DoSetProperty( index, propertyValue );
+  }
 }
 
-bool Visual::Base::GetIsFromCache() const
+Dali::Property::Value Visual::Base::GetProperty( Dali::Property::Index index )
 {
-  return mImpl->mFlags & Impl::IS_FROM_CACHE;
+  DALI_ASSERT_ALWAYS( ( index > Property::INVALID_INDEX ) &&
+                      ( index >= VISUAL_PROPERTY_BASE_START_INDEX ) &&
+                      "Property index is out of bounds" );
+
+  Dali::Property::Value value;
+
+  if( index < VISUAL_PROPERTY_START_INDEX )
+  {
+    // TODO retrieve the properties of the visual base.
+  }
+  else
+  {
+    value = DoGetProperty( index );
+  }
+
+  return value;
 }
 
 } // namespace Internal
index 3820bd0..432a3f2 100644 (file)
@@ -19,6 +19,7 @@
  */
 
 // EXTERNAL INCLUDES
+#include <dali/public-api/common/intrusive-ptr.h>
 #include <dali/public-api/images/image-operations.h>
 #include <dali/public-api/object/base-object.h>
 #include <dali/public-api/rendering/shader.h>
@@ -65,14 +66,20 @@ class Base : public BaseObject
 public:
 
   /**
-   *  Initialisation of the visual, this API should only called by the VisualFactory:
-   *  request the geometry and shader from the cache, if not available, create and save to the cache for sharing;
-   *  record the property values.
-   *
-   * @param[in] actor The Actor the visual is applied to if, empty if the visual has not been applied to any Actor
+   * Setting the properties of the visual, this API should only called by the VisualFactory
    * @param[in] propertyMap The properties for the requested Visual object.
    */
-  void Initialize( Actor& actor, const Property::Map& propertyMap );
+  void SetProperties( const Property::Map& propertyMap );
+
+  /**
+   * @copydoc Toolkit::Visual::Base::SetName
+   */
+  void SetName( const std::string& name );
+
+  /**
+   * @copydoc Toolkit::Visual::Base::GetName
+   */
+  const std::string& GetName();
 
   /**
    * @copydoc Toolkit::Visual::Base::SetSize
@@ -85,6 +92,11 @@ public:
   const Vector2& GetSize() const;
 
   /**
+   * @copydoc Toolkit::Visual::Base::GetHeightForWidth
+   */
+  virtual float GetHeightForWidth( float width ) const;
+
+  /**
    * @copydoc Toolkit::Visual::Base::GetNaturalSize
    */
   virtual void GetNaturalSize( Vector2& naturalSize ) const;
@@ -120,7 +132,7 @@ public:
    *
    * @param[in] preMultipled whether alpha is pre-multiplied.
    */
-  void EnablePreMultipliedAlpha(  bool preMultipled );
+  void EnablePreMultipliedAlpha( bool preMultipled );
 
   /**
    * @brief Query whether alpha is pre-multiplied.
@@ -135,6 +147,16 @@ public:
    */
   void SetCustomShader( const Property::Map& propertyMap );
 
+  /**
+   * @copydoc Toolkit::Visual::Base::SetProperty
+   */
+  void SetProperty( Dali::Property::Index index, const Dali::Property::Value& propertyValue );
+
+  /**
+   * @copydoc Toolkit::Visual::Base::GetProperty
+   */
+  Dali::Property::Value GetProperty( Dali::Property::Index index );
+
 protected:
 
   /**
@@ -158,12 +180,11 @@ protected:
   virtual void DoCreatePropertyMap( Property::Map& map ) const = 0;
 
   /**
-   * @brief Called by Initialize() allowing sub classes to respond to the Initialize event
+   * @brief Called by SetProperties() allowing sub classes to set their properties
    *
-   * @param[in] actor The Actor the visual is applied to if, empty if the visual has not been applied to any Actor
    * @param[in] propertyMap The properties for the requested Visual object.
    */
-  virtual void DoInitialize( Actor& actor, const Property::Map& propertyMap ) {}
+  virtual void DoSetProperties( const Property::Map& propertyMap ) = 0;
 
 protected:
 
@@ -184,19 +205,38 @@ protected:
   virtual void DoSetOffStage( Actor& actor );
 
 protected:
+
   /**
    * @brief Gets the on stage state for this Visual
    *
    * @return Returns true if this Visual is on stage, false if it is off the stage
    */
-  bool GetIsOnStage() const;
+  bool IsOnStage() const;
 
   /**
    * @brief Gets whether the Dali::Renderer is from a shared cache (and therefore any modifications will affect other users of that renderer)
    *
    * @return Returns true if the renderer is from shared cache, false otherwise
    */
-  bool GetIsFromCache() const;
+  bool IsFromCache() const;
+
+protected:
+  /**
+   * @brief Called by SetProperty(). To be overriden by derived clases in order to set properties.
+   *
+   * @param [in] index The index of the property.
+   * @param [in] propertyValue The new value of the property.
+   */
+  virtual void DoSetProperty( Dali::Property::Index index, const Dali::Property::Value& propertyValue ) = 0;
+
+  /**
+   * @brief Called by GetProperty(). To be overriden by derived classes in order to retrieve properties.
+   *
+   * @param [in] index The index of the property.
+   *
+   * @return The property value.
+   */
+  virtual Dali::Property::Value DoGetProperty( Dali::Property::Index index ) = 0;
 
 private:
 
@@ -212,6 +252,8 @@ protected:
   VisualFactoryCache& mFactoryCache;
 };
 
+typedef IntrusivePtr<Base> BasePtr;
+
 } // namspace Visual
 
 } // namespace Internal
index 6baaec2..67311b0 100644 (file)
@@ -38,6 +38,7 @@
 #include <dali-toolkit/internal/visuals/npatch/npatch-visual.h>
 #include <dali-toolkit/internal/visuals/primitive/primitive-visual.h>
 #include <dali-toolkit/internal/visuals/svg/svg-visual.h>
+#include <dali-toolkit/internal/visuals/text/text-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-factory-resolve-url.h>
@@ -99,10 +100,10 @@ Toolkit::Visual::Base VisualFactory::CreateVisual( const Property::Map& property
   // Return a new WireframeVisual if we have debug enabled
   if( mDebugEnabled )
   {
-    return Toolkit::Visual::Base( new WireframeVisual( *( mFactoryCache.Get() ) ) );
+    return Toolkit::Visual::Base( WireframeVisual::New( *( mFactoryCache.Get() ) ).Get() );
   }
 
-  Visual::Base* visualPtr = NULL;
+  Visual::BasePtr visualPtr;
 
   Property::Value* typeValue = propertyMap.Find( Toolkit::Visual::Property::TYPE, VISUAL_TYPE );
   Toolkit::Visual::Type visualType = Toolkit::Visual::IMAGE; // Default to IMAGE type.
@@ -115,19 +116,19 @@ Toolkit::Visual::Base VisualFactory::CreateVisual( const Property::Map& property
   {
     case Toolkit::Visual::BORDER:
     {
-      visualPtr = new BorderVisual( *( mFactoryCache.Get() ) );
+      visualPtr = BorderVisual::New( *( mFactoryCache.Get() ) );
       break;
     }
 
     case Toolkit::Visual::COLOR:
     {
-      visualPtr = new ColorVisual( *( mFactoryCache.Get() ) );
+      visualPtr = ColorVisual::New( *( mFactoryCache.Get() ) );
       break;
     }
 
     case Toolkit::Visual::GRADIENT:
     {
-      visualPtr = new GradientVisual( *( mFactoryCache.Get() ) );
+      visualPtr = GradientVisual::New( *( mFactoryCache.Get() ) );
       break;
     }
 
@@ -141,11 +142,11 @@ Toolkit::Visual::Base VisualFactory::CreateVisual( const Property::Map& property
         UrlType::Type type = ResolveUrlType( imageUrl );
         if( UrlType::N_PATCH == type )
         {
-          visualPtr = new NPatchVisual( *( mFactoryCache.Get() ) );
+          visualPtr = NPatchVisual::New( *( mFactoryCache.Get() ) );
         }
         else if( UrlType::SVG == type )
         {
-          visualPtr = new SvgVisual( *( mFactoryCache.Get() ) );
+          visualPtr = SvgVisual::New( *( mFactoryCache.Get() ) );
         }
         else // Regular image
         {
@@ -158,12 +159,12 @@ Toolkit::Visual::Base VisualFactory::CreateVisual( const Property::Map& property
 
           if( batchingEnabled )
           {
-            visualPtr = new BatchImageVisual( *( mFactoryCache.Get() ) );
+            visualPtr = BatchImageVisual::New( *( mFactoryCache.Get() ) );
             break;
           }
           else
           {
-            visualPtr = new ImageVisual( *( mFactoryCache.Get() ) );
+            visualPtr = ImageVisual::New( *( mFactoryCache.Get() ) );
           }
         }
       }
@@ -173,35 +174,39 @@ Toolkit::Visual::Base VisualFactory::CreateVisual( const Property::Map& property
 
     case Toolkit::Visual::MESH:
     {
-      visualPtr = new MeshVisual( *( mFactoryCache.Get() ) );
+      visualPtr = MeshVisual::New( *( mFactoryCache.Get() ) );
       break;
     }
 
     case Toolkit::Visual::PRIMITIVE:
     {
-      visualPtr = new PrimitiveVisual( *( mFactoryCache.Get() ) );
+      visualPtr = PrimitiveVisual::New( *( mFactoryCache.Get() ) );
       break;
     }
 
     case Toolkit::Visual::WIREFRAME:
     {
-      visualPtr = new WireframeVisual( *( mFactoryCache.Get() ) );
+      visualPtr = WireframeVisual::New( *( mFactoryCache.Get() ) );
       break;
     }
 
+    case Toolkit::Visual::TEXT:
+    {
+      visualPtr = TextVisual::New( *( mFactoryCache.Get() ) );
+      break;
+    }
   }
 
   if( visualPtr )
   {
-    Actor actor;
-    visualPtr->Initialize( actor, propertyMap );
+    visualPtr->SetProperties( propertyMap );
   }
   else
   {
     DALI_LOG_ERROR( "Renderer type unknown\n" );
   }
 
-  return Toolkit::Visual::Base( visualPtr );
+  return Toolkit::Visual::Base( visualPtr.Get() );
 }
 
 Toolkit::Visual::Base VisualFactory::CreateVisual( const Image& image )
@@ -213,25 +218,22 @@ Toolkit::Visual::Base VisualFactory::CreateVisual( const Image& image )
 
   if( mDebugEnabled )
   {
-    return Toolkit::Visual::Base( new WireframeVisual( *( mFactoryCache.Get() ) ) );
+    return Toolkit::Visual::Base( WireframeVisual::New( *( mFactoryCache.Get() ) ).Get() );
   }
 
+  Visual::BasePtr visualPtr;
+
   NinePatchImage npatchImage = NinePatchImage::DownCast( image );
   if( npatchImage )
   {
-    NPatchVisual* visualPtr = new NPatchVisual( *( mFactoryCache.Get() ) );
-    visualPtr->SetImage( npatchImage );
-
-    return Toolkit::Visual::Base( visualPtr );
+    visualPtr = NPatchVisual::New( *( mFactoryCache.Get() ), npatchImage );
   }
   else
   {
-    ImageVisual* visualPtr = new ImageVisual( *( mFactoryCache.Get() ) );
-    Actor actor;
-    visualPtr->SetImage( actor, image );
-
-    return Toolkit::Visual::Base( visualPtr );
+    visualPtr = ImageVisual::New( *( mFactoryCache.Get() ), image );
   }
+
+  return Toolkit::Visual::Base( visualPtr.Get() );
 }
 
 Toolkit::Visual::Base VisualFactory::CreateVisual( const std::string& url, ImageDimensions size )
@@ -243,32 +245,27 @@ Toolkit::Visual::Base VisualFactory::CreateVisual( const std::string& url, Image
 
   if( mDebugEnabled )
   {
-    return Toolkit::Visual::Base( new WireframeVisual( *( mFactoryCache.Get() ) ) );
+    return Toolkit::Visual::Base( WireframeVisual::New( *( mFactoryCache.Get() ) ).Get() );
   }
 
+  Visual::BasePtr visualPtr;
+
   // first resolve url type to know which visual to create
   UrlType::Type type = ResolveUrlType( url );
   if( UrlType::N_PATCH == type )
   {
-    NPatchVisual* visualPtr = new NPatchVisual( *( mFactoryCache.Get() ) );
-    visualPtr->SetImage( url );
-
-    return Toolkit::Visual::Base( visualPtr );
+    visualPtr = NPatchVisual::New( *( mFactoryCache.Get() ), url );
   }
   else if( UrlType::SVG == type )
   {
-    SvgVisual* visualPtr = new SvgVisual( *( mFactoryCache.Get() ) );
-    visualPtr->SetImage( url, size );
-    return Toolkit::Visual::Base( visualPtr );
+    visualPtr = SvgVisual::New( *( mFactoryCache.Get() ), url, size );
   }
   else // Regular image
   {
-    ImageVisual* visualPtr = new ImageVisual( *( mFactoryCache.Get() ));
-    Actor actor;
-    visualPtr->SetImage( actor, url, size );
-
-    return Toolkit::Visual::Base( visualPtr );
+    visualPtr = ImageVisual::New( *( mFactoryCache.Get() ), url, size );
   }
+
+  return Toolkit::Visual::Base( visualPtr.Get() );
 }
 
 } // namespace Internal
index 484a688..501a854 100644 (file)
@@ -65,7 +65,6 @@ public:
    */
   Toolkit::Visual::Base CreateVisual( const std::string& image, ImageDimensions size );
 
-
 protected:
 
   /**
index 4299eb6..b65f67c 100644 (file)
@@ -64,6 +64,10 @@ void main()\n
 
 }
 
+WireframeVisualPtr WireframeVisual::New( VisualFactoryCache& factoryCache )
+{
+  return new WireframeVisual( factoryCache );
+}
 
 WireframeVisual::WireframeVisual( VisualFactoryCache& factoryCache )
 : Visual::Base( factoryCache )
@@ -71,7 +75,13 @@ WireframeVisual::WireframeVisual( VisualFactoryCache& factoryCache )
 }
 
 WireframeVisual::~WireframeVisual()
-{}
+{
+}
+
+void WireframeVisual::DoSetProperties( const Property::Map& propertyMap )
+{
+  // no properties supported at the moment
+}
 
 void WireframeVisual::DoSetOnStage( Actor& actor )
 {
@@ -86,6 +96,17 @@ void WireframeVisual::DoCreatePropertyMap( Property::Map& map ) const
   map.Insert( Toolkit::Visual::Property::TYPE, Toolkit::Visual::WIREFRAME );
 }
 
+void WireframeVisual::DoSetProperty( Dali::Property::Index index, const Dali::Property::Value& propertyValue )
+{
+  // TODO
+}
+
+Dali::Property::Value WireframeVisual::DoGetProperty( Dali::Property::Index index )
+{
+  // TODO
+  return Dali::Property::Value();
+}
+
 void WireframeVisual::InitializeRenderer()
 {
   mImpl->mRenderer = mFactoryCache.GetWireframeRenderer();
index c0d8682..3756e00 100644 (file)
@@ -18,6 +18,9 @@
  *
  */
 
+// EXTERNAL INCLUDES
+#include <dali/public-api/common/intrusive-ptr.h>
+
 // INTERNAL INCLUDES
 #include <dali-toolkit/internal/visuals/visual-base-impl.h>
 
@@ -30,15 +33,27 @@ namespace Toolkit
 namespace Internal
 {
 
+class WireframeVisual;
+typedef IntrusivePtr< WireframeVisual > WireframeVisualPtr;
+
 /**
- * The visual which renders a wireframe outline to the control's quad.
- *
+ * @brief Renders a wireframe outline to the control's quad.
  */
 class WireframeVisual: public Visual::Base
 {
 public:
 
   /**
+   * @brief Create a new wireframe visual.
+   *
+   * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object
+   * @return A smart-pointer to the newly allocated visual.
+   */
+  static WireframeVisualPtr New( VisualFactoryCache& factoryCache );
+
+protected:
+
+  /**
    * @brief Constructor.
    *
    * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object
@@ -50,7 +65,10 @@ public:
    */
   virtual ~WireframeVisual();
 
-protected:
+  /**
+   * @copydoc Visual::Base::DoSetProperties()
+   */
+  virtual void DoSetProperties( const Property::Map& propertyMap );
 
   /**
    * @copydoc Visual::Base::DoSetOnStage
@@ -62,6 +80,15 @@ protected:
    */
   virtual void DoCreatePropertyMap( Property::Map& map ) const;
 
+  /**
+   * @copydoc Visual::Base::DoSetProperty
+   */
+  virtual void DoSetProperty( Dali::Property::Index index, const Dali::Property::Value& propertyValue );
+
+  /**
+   * @copydoc Visual::Base::DoGetProperty
+   */
+  virtual Dali::Property::Value DoGetProperty( Dali::Property::Index index );
 
 private:
   /**
index 53c9293..6c4b211 100644 (file)
@@ -42,6 +42,7 @@
 #include <dali-toolkit/devel-api/focus-manager/keyinput-focus-manager.h>
 #include <dali-toolkit/internal/styling/style-manager-impl.h>
 #include <dali-toolkit/internal/visuals/color/color-visual.h>
+#include <dali-toolkit/internal/visuals/transition-data-impl.h>
 
 namespace Dali
 {
@@ -52,6 +53,10 @@ namespace Toolkit
 namespace
 {
 
+#if defined(DEBUG_ENABLED)
+Debug::Filter* gLogFilter = Debug::Filter::New( Debug::General, false, "LOG_CONTROL_VISUALS");
+#endif
+
 /**
  * Struct used to store Visual within the control, index is a unique key for each visual.
  */
@@ -60,16 +65,37 @@ struct RegisteredVisual
   Property::Index index;
   Toolkit::Visual::Base visual;
   Actor placementActor;
+  bool enabled;
+
+  RegisteredVisual( Property::Index aIndex, Toolkit::Visual::Base &aVisual, Actor &aPlacementActor, bool aEnabled) :
+                   index(aIndex), visual(aVisual), placementActor(aPlacementActor), enabled(aEnabled) {}
+};
+
+struct VisualProperty
+{
+  Handle handle; ///< a handle to the target object
+  Property::Index index; ///< The index of a property provided by the referenced object
+
+  VisualProperty( )
+  : handle(),
+    index( Property::INVALID_INDEX )
+  {
+  }
 
-  RegisteredVisual( Property::Index aIndex, Toolkit::Visual::Base &aVisual, Actor &aPlacementActor) : index(aIndex), visual(aVisual), placementActor(aPlacementActor) {}
+  VisualProperty( Handle& handle, Property::Index index )
+  : handle( handle ),
+    index( index )
+  {
+  }
 };
 
-typedef Dali::OwnerContainer< RegisteredVisual* > RegisteredVisuals;
+
+typedef Dali::OwnerContainer< RegisteredVisual* > RegisteredVisualContainer;
 
 /**
  *  Finds visual in given array, returning true if found along with the iterator for that visual as a out parameter
  */
-bool FindVisual( Property::Index targetIndex, RegisteredVisuals& visuals, RegisteredVisuals::Iterator& iter )
+bool FindVisual( Property::Index targetIndex, RegisteredVisualContainer& visuals, RegisteredVisualContainer::Iterator& iter )
 {
   for ( iter = visuals.Begin(); iter != visuals.End(); iter++ )
   {
@@ -81,6 +107,71 @@ bool FindVisual( Property::Index targetIndex, RegisteredVisuals& visuals, Regist
   return false;
 }
 
+VisualProperty GetVisualProperty(
+  Internal::Control& controlImpl,
+  RegisteredVisualContainer& visuals,
+  const std::string& visualName,
+  Property::Key propertyKey )
+{
+#if defined(DEBUG_ENABLED)
+  std::ostringstream oss;
+  oss << "Control::GetVisualProperty(" << visualName << ", " << propertyKey << ")" << std::endl;
+  DALI_LOG_INFO( gLogFilter, Debug::General, oss.str().c_str() );
+#endif
+
+  // Find visualName in the control
+  RegisteredVisualContainer::Iterator iter;
+  for ( iter = visuals.Begin(); iter != visuals.End(); iter++ )
+  {
+    if ( (*iter)->visual.GetName() == visualName )
+    {
+      break;
+    }
+  }
+
+  // Does either it's renderer or placement actor have an associated property?
+  if( iter != visuals.End() )
+  {
+    Actor placementActor = (*iter)->placementActor;
+    if( !placementActor )
+    {
+      placementActor = controlImpl.Self();
+    }
+
+    Property::Index index = placementActor.GetPropertyIndex( propertyKey );
+    if( index != Property::INVALID_INDEX )
+    {
+      // It's a placement actor property:
+      return VisualProperty( placementActor, index );
+    }
+    else
+    {
+      // Check if it is a renderer property:
+      if( placementActor.GetRendererCount() > 0 )
+      {
+        // @todo Need to use correct renderer index when placement actors
+        // are removed
+        Renderer renderer = placementActor.GetRendererAt(0);
+        Property::Index index = renderer.GetPropertyIndex( propertyKey );
+        if( index != Property::INVALID_INDEX )
+        {
+          // It's a renderer property:
+          return VisualProperty( renderer, index );
+        }
+      }
+      else
+      {
+        std::ostringstream oss;
+        oss << propertyKey;
+        DALI_LOG_WARNING( "Control::GetVisualProperty(%s, %s) No renderers\n", visualName.c_str(), oss.str().c_str() );
+      }
+    }
+  }
+  Handle handle;
+  return VisualProperty( handle, Property::INVALID_INDEX );
+}
+
+
 /**
  * Creates control through type registry
  */
@@ -205,21 +296,21 @@ public:
 
   // Construction & Destruction
   Impl(Control& controlImpl)
-: mControlImpl( controlImpl ),
-  mStyleName(""),
-  mBackgroundVisual(),
-  mBackgroundColor(Color::TRANSPARENT),
-  mStartingPinchScale( NULL ),
-  mKeyEventSignal(),
-  mPinchGestureDetector(),
-  mPanGestureDetector(),
-  mTapGestureDetector(),
-  mLongPressGestureDetector(),
-  mFlags( Control::ControlBehaviour( CONTROL_BEHAVIOUR_DEFAULT ) ),
-  mIsKeyboardNavigationSupported( false ),
-  mIsKeyboardFocusGroup( false )
-{
-}
+  : mControlImpl( controlImpl ),
+    mStyleName(""),
+    mBackgroundVisual(),
+    mBackgroundColor(Color::TRANSPARENT),
+    mStartingPinchScale( NULL ),
+    mKeyEventSignal(),
+    mPinchGestureDetector(),
+    mPanGestureDetector(),
+    mTapGestureDetector(),
+    mLongPressGestureDetector(),
+    mFlags( Control::ControlBehaviour( CONTROL_BEHAVIOUR_DEFAULT ) ),
+    mIsKeyboardNavigationSupported( false ),
+    mIsKeyboardFocusGroup( false )
+  {
+  }
 
   ~Impl()
   {
@@ -397,7 +488,7 @@ public:
   // Data
 
   Control& mControlImpl;
-  RegisteredVisuals mVisuals; // Stores visuals needed by the control, non trivial type so std::vector used.
+  RegisteredVisualContainer mVisuals; // Stores visuals needed by the control, non trivial type so std::vector used.
   std::string mStyleName;
   Toolkit::Visual::Base mBackgroundVisual;   ///< The visual to render the background
   Vector4 mBackgroundColor;                       ///< The color of the background visual
@@ -661,6 +752,11 @@ void Control::KeyboardEnter()
 
 void Control::RegisterVisual( Property::Index index, Actor& placementActor, Toolkit::Visual::Base& visual )
 {
+  RegisterVisual( index, placementActor, visual, true );
+}
+
+void Control::RegisterVisual( Property::Index index, Actor& placementActor, Toolkit::Visual::Base& visual, bool enabled )
+{
   bool visualReplaced ( false );
   Actor actorToRegister; // Null actor, replaced if placement actor not Self
   Actor self = Self();
@@ -672,7 +768,7 @@ void Control::RegisterVisual( Property::Index index, Actor& placementActor, Tool
 
   if ( !mImpl->mVisuals.Empty() )
   {
-      RegisteredVisuals::Iterator iter;
+      RegisteredVisualContainer::Iterator iter;
       // Check if visual (index) is already registered.  Replace if so.
       if ( FindVisual( index, mImpl->mVisuals, iter ) )
       {
@@ -695,10 +791,10 @@ void Control::RegisterVisual( Property::Index index, Actor& placementActor, Tool
 
   if ( !visualReplaced ) // New registration entry
   {
-    mImpl->mVisuals.PushBack( new RegisteredVisual( index, visual, actorToRegister ) );
+    mImpl->mVisuals.PushBack( new RegisteredVisual( index, visual, actorToRegister, enabled ) );
   }
 
-  if( visual && self.OnStage() )
+  if( visual && self.OnStage() && enabled )
   {
     visual.SetOnStage( placementActor );
   }
@@ -706,7 +802,7 @@ void Control::RegisterVisual( Property::Index index, Actor& placementActor, Tool
 
 void Control::UnregisterVisual( Property::Index index )
 {
-   RegisteredVisuals::Iterator iter;
+   RegisteredVisualContainer::Iterator iter;
    if ( FindVisual( index, mImpl->mVisuals, iter ) )
    {
      mImpl->mVisuals.Erase( iter );
@@ -715,7 +811,7 @@ void Control::UnregisterVisual( Property::Index index )
 
 Toolkit::Visual::Base Control::GetVisual( Property::Index index ) const
 {
-  RegisteredVisuals::Iterator iter;
+  RegisteredVisualContainer::Iterator iter;
   if ( FindVisual( index, mImpl->mVisuals, iter ) )
   {
     return (*iter)->visual;
@@ -724,9 +820,51 @@ Toolkit::Visual::Base Control::GetVisual( Property::Index index ) const
   return Toolkit::Visual::Base();
 }
 
+void Control::EnableVisual( Property::Index index, bool enable )
+{
+  RegisteredVisualContainer::Iterator iter;
+  if ( FindVisual( index, mImpl->mVisuals, iter ) )
+  {
+    if (  (*iter)->enabled == enable )
+    {
+      return;
+    }
+
+    (*iter)->enabled = enable;
+    Actor parentActor = Self();
+    if ( (*iter)->placementActor )
+    {
+      parentActor = (*iter)->placementActor;
+    }
+
+    if ( Self().OnStage() ) // If control not on Stage then Visual will be added when StageConnection is called.
+    {
+      if ( enable )
+      {
+
+        (*iter)->visual.SetOnStage( parentActor );
+      }
+      else
+      {
+        (*iter)->visual.SetOffStage( parentActor );  // No need to call if control not staged.
+      }
+    }
+  }
+}
+
+bool Control::IsVisualEnabled( Property::Index index ) const
+{
+  RegisteredVisualContainer::Iterator iter;
+  if ( FindVisual( index, mImpl->mVisuals, iter ) )
+  {
+    return (*iter)->enabled;
+  }
+  return false;
+}
+
 Actor Control::GetPlacementActor( Property::Index index ) const
 {
-  RegisteredVisuals::Iterator iter;
+  RegisteredVisualContainer::Iterator iter;
   if ( FindVisual( index, mImpl->mVisuals, iter ) )
   {
     if( (*iter)->placementActor )
@@ -742,6 +880,73 @@ Actor Control::GetPlacementActor( Property::Index index ) const
   return Actor();
 }
 
+Dali::Animation Control::CreateTransition( const Toolkit::TransitionData& handle )
+{
+  Dali::Animation transition;
+  const Internal::TransitionData& transitionData = Toolkit::GetImplementation( handle );
+
+  if( transitionData.Count() > 0 )
+  {
+    // Setup a Transition from TransitionData.
+    TransitionData::Iterator end = transitionData.End();
+    for( TransitionData::Iterator iter = transitionData.Begin() ;
+         iter != end; ++iter )
+    {
+      TransitionData::Animator* animator = (*iter);
+      VisualProperty visualProperty;
+
+      // Attempt to find the object name as a child actor
+      Actor child = Self().FindChildByName( animator->objectName );
+      if( child )
+      {
+        Property::Index propertyIndex = child.GetPropertyIndex( animator->propertyKey );
+        visualProperty = VisualProperty( child, propertyIndex );
+      }
+      else
+      {
+        // Is it a placement actor/visual pair?;
+        visualProperty = GetVisualProperty( *this, mImpl->mVisuals,
+                                            animator->objectName,
+                                            animator->propertyKey );
+      }
+
+      if( visualProperty.handle && visualProperty.index != Property::INVALID_INDEX )
+      {
+        if( animator->animate == false )
+        {
+          if( animator->targetValue.GetType() != Property::NONE )
+          {
+            visualProperty.handle.SetProperty( visualProperty.index, animator->targetValue );
+          }
+        }
+        else
+        {
+          if( animator->initialValue.GetType() != Property::NONE )
+          {
+            visualProperty.handle.SetProperty( visualProperty.index, animator->initialValue );
+          }
+
+          if( ! transition )
+          {
+            // Create an animation with a default .1 second duration - the animators
+            // will automatically force it to the 'right' duration.
+            transition = Dali::Animation::New( 0.1f );
+          }
+
+          transition.AnimateTo( Property( visualProperty.handle, visualProperty.index ),
+                                animator->targetValue,
+                                animator->alphaFunction,
+                                TimePeriod( animator->timePeriodDelay,
+                                            animator->timePeriodDuration ) );
+        }
+      }
+    }
+  }
+
+  return transition;
+}
+
+
 bool Control::OnAccessibilityActivated()
 {
   return false; // Accessibility activation is not handled by default
@@ -928,10 +1133,10 @@ void Control::EmitKeyInputFocusSignal( bool focusGained )
 
 void Control::OnStageConnection( int depth )
 {
-  for(RegisteredVisuals::Iterator iter = mImpl->mVisuals.Begin(); iter!= mImpl->mVisuals.End(); iter++)
+  for(RegisteredVisualContainer::Iterator iter = mImpl->mVisuals.Begin(); iter!= mImpl->mVisuals.End(); iter++)
   {
     // Check whether the visual is empty, as it is allowed to register a placement actor without visual.
-    if( (*iter)->visual )
+    if( (*iter)->visual && (*iter)->enabled )
     {
       if( (*iter)->placementActor )
       {
@@ -948,7 +1153,7 @@ void Control::OnStageConnection( int depth )
 
 void Control::OnStageDisconnection()
 {
-  for(RegisteredVisuals::Iterator iter = mImpl->mVisuals.Begin(); iter!= mImpl->mVisuals.End(); iter++)
+  for(RegisteredVisualContainer::Iterator iter = mImpl->mVisuals.Begin(); iter!= mImpl->mVisuals.End(); iter++)
   {
     // Check whether the visual is empty, as it is allowed to register a placement actor without visual.
     if( (*iter)->visual )
index 9cee83e..92786d4 100644 (file)
 
 namespace Dali
 {
-
 namespace Toolkit
 {
+
 /**
  * @addtogroup dali_toolkit_controls
  * @{
  */
 
 class StyleManager;
+class TransitionData;
 
 namespace Visual
 {
 class Base;
 }
+
 namespace Internal
 {
+
 /**
  * @brief This is the internal base class for all controls.
  *
@@ -296,8 +299,8 @@ public:
 protected: // For derived classes to call
 
   /**
-   * @brief Register a visual by Property Index, linking an Actor to controlRenderer when required.
-   * In the case of the visual being an actor or control deeming controlRenderer not required then controlRenderer should be an empty handle.
+   * @brief Register a visual by Property Index, linking an Actor to visual when required.
+   * In the case of the visual being an actor or control deeming visual not required then visual should be an empty handle.
    * No parenting is done during registration, this should be done by derived class.
    *
    * @SINCE_1_2.0
@@ -305,39 +308,87 @@ protected: // For derived classes to call
    * @param[in] index The Property index of the visual, used to reference visual
    * @param[in] placementActor The actor used to by the visual.
    * @param[in] visual The visual to register
-   * @note Derived class must NOT call visual.SetOnStage(placementActor). It is the responsibility of the base class to connect/disconnect registered visual to stage.
-   */
-   void RegisterVisual( Property::Index index, Actor& placementActor, Toolkit::Visual::Base& visual );
-
-   /**
-    * @brief Erase the entry matching the given index from the list of registered visuals
-    * @param[in] index The Property index of the visual, used to reference visual
-    *
-    * @SINCE_1_2.0
-    */
-   void UnregisterVisual( Property::Index index );
-
-   /**
-    * @brief Retrieve the visual associated with the given property index.
-    *
-    * @SINCE_1_2.2
-    *
-    * @param[in] index The Property index of the visual.
-    * @return The registered visual if exist, otherwise empty handle.
-    * @note For managing object life-cycle, do not store the returned visual as a member which increments its reference count.
-    */
-   Toolkit::Visual::Base GetVisual( Property::Index index ) const;
-
-   /**
-    * @brief Retrieve the placement actor associated with the given index.
-    *
-    * @SINCE_1_2.2
-    *
-    * @@param[in] index The Property index of the visual.
-    * @return Then placement actor if exist, otherwise empty handle.
-    * @note For managing object life-cycle, do not store the returned placement actor as a member which increments its reference count.
-    */
-   Actor GetPlacementActor( Property::Index index ) const;
+   * @note Derived class should not call visual.SetOnStage(placementActor). It is the responsibility of the base class to connect/disconnect registered visual to stage.
+   *       Use below API with enabled set to false if derived class wishes to control when visual is staged.
+   */
+  void RegisterVisual( Property::Index index, Actor& placementActor, Toolkit::Visual::Base& visual );
+
+  /**
+   * @brief Register a visual by Property Index, linking an Actor to visual when required.
+   * In the case of the visual being an actor or control deeming visual not required then visual should be an empty handle.
+   * If enabled is false then the visual is not set on stage until enabled by the derived class.
+   * @see EnableVisual
+   *
+   * @SINCE_1_2.11
+   *
+   * @param[in] index The Property index of the visual, used to reference visual
+   * @param[in] placementActor The actor used to by the visual.
+   * @param[in] visual The visual to register
+   * @param[in] enabled false if derived class wants to control when visual is set on stage.
+   *
+   */
+  void RegisterVisual( Property::Index index, Actor& placementActor, Toolkit::Visual::Base& visual, bool enabled );
+
+  /**
+   * @brief Erase the entry matching the given index from the list of registered visuals
+   * @param[in] index The Property index of the visual, used to reference visual
+   *
+   * @SINCE_1_2.0
+   */
+  void UnregisterVisual( Property::Index index );
+
+  /**
+   * @brief Retrieve the visual associated with the given property index.
+   *
+   * @SINCE_1_2.2
+   *
+   * @param[in] index The Property index of the visual.
+   * @return The registered visual if exist, otherwise empty handle.
+   * @note For managing object life-cycle, do not store the returned visual as a member which increments its reference count.
+   */
+  Toolkit::Visual::Base GetVisual( Property::Index index ) const;
+
+  /**
+   * @brief Sets the given visual to be displayed or not when parent staged.
+   *
+   * @SINCE_1_2.11
+   *
+   * @param[in] index The Property index of the visual
+   * @param[in] enable flag to set enabled or disabled.
+   */
+  void EnableVisual( Property::Index index, bool enable );
+
+  /**
+   * @brief Queries if the given visual is to be displayed when parent staged.
+   *
+   * @SINCE_1_2.11
+   *
+   * @param[in] index The Property index of the visual
+   * @return bool whether visual is enabled or not
+   */
+  bool IsVisualEnabled( Property::Index index ) const;
+
+  /**
+   * @brief Retrieve the placement actor associated with the given index.
+   *
+   * @SINCE_1_2.2
+   *
+   * @@param[in] index The Property index of the visual.
+   * @return Then placement actor if exist, otherwise empty handle.
+   * @note For managing object life-cycle, do not store the returned placement actor as a member which increments its reference count.
+   */
+  Actor GetPlacementActor( Property::Index index ) const;
+
+  /**
+   * @brief Create a transition effect on the control.
+   *
+   * @SINCE_1_2.12
+   *
+   * @param[in] transitionData The transition data describing the effect to create
+   * @return A handle to an animation defined with the given effect, or an empty
+   * handle if no properties match.
+   */
+  Dali::Animation CreateTransition( const Toolkit::TransitionData& transitionData );
 
   /**
    * @brief Emits KeyInputFocusGained signal if true else emits KeyInputFocusLost signal
index c9322aa..9c216c2 100644 (file)
@@ -122,7 +122,7 @@ public:
 
       /**
        * @brief The single-line or multi-line layout option
-       * @details name "multiLine", type FLOAT, default SINGLE_LINE_BOX
+       * @details name "multiLine", type BOOLEAN, default false
        * @SINCE_1_0.0
        */
       MULTI_LINE,
@@ -150,7 +150,7 @@ public:
 
       /**
        * @brief The drop shadow offset 0 indicates no shadow
-       * @details name "shadowOffset", type VECTOR4
+       * @details name "shadowOffset", type VECTOR2
        * @DEPRECATED_1_1.37 Use SHADOW instead
        */
       SHADOW_OFFSET,
@@ -192,13 +192,13 @@ public:
 
       /**
        * @brief  Start or stop auto scrolling,
-       * @details name "enableMarkup", type BOOLEAN, default is false
+       * @details name "enableAutoScroll", type BOOLEAN, default is false
        * @SINCE_1_1.35
        */
       ENABLE_AUTO_SCROLL,
 
       /**
-       * @brief  Start or stop auto scrolling,
+       * @brief Sets the speed of scrolling in pixels per second,
        * @details name "autoScrollSpeed", type INT, default in style sheet
        * @SINCE_1_1.35
        */
index 418d99c..8c9ed00 100644 (file)
@@ -31,7 +31,7 @@ namespace Toolkit
 
 const unsigned int TOOLKIT_MAJOR_VERSION = 1;
 const unsigned int TOOLKIT_MINOR_VERSION = 2;
-const unsigned int TOOLKIT_MICRO_VERSION = 9;
+const unsigned int TOOLKIT_MICRO_VERSION = 11;
 const char * const TOOLKIT_BUILD_DATE    = __DATE__ " " __TIME__;
 
 #ifdef DEBUG_ENABLED
index de5e006..3734525 100755 (executable)
@@ -25,10 +25,10 @@ public_api_src_files = \
   $(public_api_src_dir)/controls/text-controls/text-editor.cpp \
   $(public_api_src_dir)/controls/text-controls/text-label.cpp \
   $(public_api_src_dir)/controls/text-controls/text-field.cpp \
+  $(public_api_src_dir)/controls/video-view/video-view.cpp \
   $(public_api_src_dir)/styling/style-manager.cpp \
   $(public_api_src_dir)/accessibility-manager/accessibility-manager.cpp \
   $(public_api_src_dir)/focus-manager/keyboard-focus-manager.cpp \
-  $(public_api_src_dir)/controls/video-view/video-view.cpp \
   $(public_api_src_dir)/dali-toolkit-version.cpp \
   $(public_api_src_dir)/enums.cpp
 
@@ -113,4 +113,5 @@ public_api_visuals_header_files = \
   $(public_api_src_dir)/visuals/image-visual-properties.h \
   $(public_api_src_dir)/visuals/mesh-visual-properties.h \
   $(public_api_src_dir)/visuals/primitive-visual-properties.h \
+  $(public_api_src_dir)/visuals/text-visual-properties.h \
   $(public_api_src_dir)/visuals/visual-properties.h
diff --git a/dali-toolkit/public-api/visuals/text-visual-properties.h b/dali-toolkit/public-api/visuals/text-visual-properties.h
new file mode 100644 (file)
index 0000000..39a5eb3
--- /dev/null
@@ -0,0 +1,188 @@
+#ifndef DALI_TOOLKIT_TEXT_VISUAL_PROPERTIES_H
+#define DALI_TOOLKIT_TEXT_VISUAL_PROPERTIES_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.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/public-api/visuals/visual-properties.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace TextVisual
+{
+
+namespace Property
+{
+
+enum
+{
+  /**
+   * @brief The type of rendering e.g. bitmap-based
+   * @details name "renderingBackend", type INTEGER, default RENDERING_SHARED_ATLAS
+   * @SINCE_1_2.11
+   */
+  RENDERING_BACKEND = VISUAL_PROPERTY_START_INDEX,
+
+  /**
+   * @brief The text to display in UTF-8 format,
+   * @details name "text", type STRING
+   * @SINCE_1_2.11
+   */
+  TEXT,
+
+  /**
+   * @brief The requested font family to use,
+   * @details name "fontFamily", type STRING
+   * @SINCE_1_2.11
+   */
+  FONT_FAMILY,
+
+  /**
+   * @brief The requested font style to use,
+   * @details name "fontStyle", type STRING
+   * @SINCE_1_2.11
+   */
+  FONT_STYLE,
+
+  /**
+   * @brief The size of font in points
+   * @details name "pointSize", type FLOAT
+   * @SINCE_1_2.11
+   */
+  POINT_SIZE,
+
+  /**
+   * @brief The single-line or multi-line layout option
+   * @details name "multiLine", type BOOLEAN, default false
+   * @SINCE_1_2.11
+   */
+  MULTI_LINE,
+
+  /**
+   * @brief The line horizontal alignment
+   * @details name "horizontalAlignment", type STRING,  values "BEGIN", "CENTER", "END", default BEGIN
+   * @SINCE_1_2.11
+   */
+  HORIZONTAL_ALIGNMENT,
+
+  /**
+   * @brief The line vertical alignment
+   * @details name "verticalAlignment", type STRING,  values "TOP",   "CENTER", "BOTTOM", default TOP
+   * @SINCE_1_2.11
+   */
+  VERTICAL_ALIGNMENT,
+
+  /**
+   * @brief The color of the text
+   * @details name "textColor", type VECTOR4
+   * @SINCE_1_2.11
+   */
+  TEXT_COLOR,
+
+  /**
+   * @brief  Whether the mark-up processing is enabled
+   * @details name "enableMarkup", type BOOLEAN
+   * @SINCE_1_2.11
+   */
+  ENABLE_MARKUP,
+
+  /**
+   * @brief  Start or stop auto scrolling,
+   * @details name "enableAutoScroll", type BOOLEAN, default is false
+   * @SINCE_1_2.11
+   */
+  ENABLE_AUTO_SCROLL,
+
+  /**
+   * @brief Sets the speed of scrolling in pixels per second,
+   * @details name "autoScrollSpeed", type INTEGER, default in style sheet
+   * @SINCE_1_2.11
+   */
+  AUTO_SCROLL_SPEED,
+
+  /**
+   * @brief  Number of complete loops when scrolling enabled
+   * @details name "autoScrollLoopCount", type INTEGER, default in style sheet
+   * @SINCE_1_2.11
+   */
+  AUTO_SCROLL_LOOP_COUNT,
+
+  /**
+   * @brief  Gap before before scrolling wraps
+   * @details name "autoScrollGap", type INTEGER, default in style sheet but can be overridden to prevent same text being show at start and end.
+   * @SINCE_1_2.11
+   */
+  AUTO_SCROLL_GAP,
+
+  /**
+   * @brief The default extra space between lines in points.
+   * @details name "lineSpacing", type FLOAT.
+   * @SINCE_1_2.11
+   */
+  LINE_SPACING,
+
+  /**
+   * @brief The default underline parameters.
+   * @details name "underline", type STRING.
+   * @SINCE_1_2.11
+   */
+  UNDERLINE,
+
+  /**
+   * @brief The default shadow parameters.
+   * @details name "shadow", type STRING.
+   * @SINCE_1_2.11
+   */
+  SHADOW,
+
+  /**
+   * @brief The default emboss parameters.
+   * @details name "emboss", type STRING.
+   * @SINCE_1_2.11
+   */
+  EMBOSS,
+
+  /**
+   * @brief The default outline parameters.
+   * @details name "outline", type STRING.
+   * @SINCE_1_2.11
+   */
+  OUTLINE,
+
+  /**
+   * @brief This enables Text visuals to automatically be converted to Batch-Text visuals.
+   * @details Name "batchingEnabled", type Property::BOOLEAN.
+   * @SINCE_1_2.11
+   * @note Optional. If not specified, the default is false.
+   */
+  BATCHING_ENABLED,
+};
+
+} // namespace Property
+
+} // namespace TextVisual
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_TEXT_VISUAL_PROPERTIES_H
index 989d938..c64a73c 100644 (file)
@@ -43,6 +43,7 @@ enum Type
   MESH, ///< Renders a mesh using an "obj" file, optionally with textures provided by an "mtl" file. @SINCE_1_1.45
   PRIMITIVE, ///< Renders a simple 3D shape, such as a cube or sphere. @SINCE_1_1.45
   WIREFRAME, ///< Renders a simple wire-frame outlining a quad. @SINCE_1_2_2
+  TEXT, ///< Renders text. @SINCE_1_2.11
 };
 
 namespace Property
index eb05a02..b5a63b2 100644 (file)
@@ -1,6 +1,6 @@
 Name:       dali-addon
 Summary:    DALi module for Node.JS
-Version:    1.2.9
+Version:    1.2.11
 Release:    1
 Group:      Development/Libraries
 License:    Apache License, Version 2.0
index dca178a..788769d 100755 (executable)
@@ -1,6 +1,6 @@
 Name:       NDalic
 Summary:    dali wrapper
-Version:    1.0.0
+Version:    1.2.11
 Release:    1
 Group:      uifw/graphic
 License:    TO_BE_FILLED_IN
index a14456d..bae76d7 100644 (file)
@@ -1,6 +1,6 @@
 Name:       dali-toolkit
 Summary:    The OpenGLES Canvas Core Library Toolkit
-Version:    1.2.9
+Version:    1.2.11
 Release:    1
 Group:      System/Libraries
 License:    Apache-2.0 and BSD-2-Clause and MIT
index f6bbe4d..894b34f 100644 (file)
  * This is because from C# we can't wrap the operator BooleanType() function
  */
 %extend Dali::BaseHandle {
-   bool IsHandleEmpty() const {
+   bool HasBody() const {
+
+     // C++ code. DALi uses Handle <-> Body design pattern.
+     // This function checks the Handle to see if it has a body attached ( possible to have empty handles).
+     // Handles in DALi can be converted into a boolean type
+     // to check if the handle has a valid body attached to it.
+     // Internally checking *$self will  checks IntrusivePtr<Dali::RefObject> mObjectHandle in BaseHandle;
      if( *$self )
      {
        return true;
        return false;
      }
     }
+
+     // Check if two handles point to the same body / ref-object.
+     bool IsEqual( const BaseHandle& rhs ) const {
+
+     // C++ code. Check if two handles reference the same implemtion
+     if( *$self == rhs)
+     {
+       return true;
+     }
+     else
+     {
+       return false;
+     }
+    }
+
 };
 
 /**
  */
 %typemap(cscode) Dali::BaseHandle %{
 
- public static bool operator true(BaseHandle  handle)
- {
-   if( handle!= null  )
-   {
-     return  handle.IsHandleEmpty();
-   }
-   else
-   {
-     return false;
-   }
- }
- public static bool operator false(BaseHandle  handle)
- {
-   return  handle.IsHandleEmpty();
- }
-%}
+  // Returns the bool value true to indicate that an operand is true and returns false otherwise.
+  public static bool operator true(BaseHandle handle)
+  {
+    // if the C# object is null, return false
+    if( BaseHandle.ReferenceEquals( handle, null ) )
+    {
+      return false;
+    }
+    // returns true if the handle has a body, false otherwise
+    return handle.HasBody();
+  }
+
+  // Returns the bool false  to indicate that an operand is false and returns true otherwise.
+  public static bool operator false(BaseHandle  handle)
+  {
+    // if the C# object is null, return true
+    if( BaseHandle.ReferenceEquals( handle, null ) )
+    {
+      return true;
+    }
+    return !handle.HasBody();
+  }
+
+  // Explicit conversion from Handle to bool.
+  public static explicit operator bool(BaseHandle handle)
+  {
+     // if the C# object is null, return false
+    if( BaseHandle.ReferenceEquals( handle, null ) )
+    {
+      return false;
+    }
+    // returns true if the handle has a body, false otherwise
+    return handle.HasBody();
+  }
 
+  // Equality operator
+  public static bool operator == (BaseHandle x, BaseHandle y)
+  {
+    // if the C# objects are the same return true
+    if(  BaseHandle.ReferenceEquals( x, y ) )
+    {
+      return true;
+    }
+    if ( !BaseHandle.ReferenceEquals( x, null ) && !BaseHandle.ReferenceEquals( y, null ) )
+    {
+      // drop into native code to see if both handles point to the same body
+      return x.IsEqual( y) ;
+    }
+    return false;
+
+  }
+
+  // Inequality operator. Returns Null if either operand is Null
+  public static bool operator !=(BaseHandle x, BaseHandle y)
+  {
+    return !(x==y);
+  }
+
+  // Logical AND operator for &&
+  // It's possible when doing a && this function (opBitwiseAnd) is never called due
+  // to short circuiting. E.g.
+  // If you perform x && y What actually is called is
+  // BaseHandle.op_False( x ) ? BaseHandle.op_True( x ) : BaseHandle.opTrue( BaseHandle.opBitwiseAnd(x,y) )
+  //
+  public static BaseHandle operator &(BaseHandle x, BaseHandle y)
+  {
+    if( x == y )
+    {
+      return x;
+    }
+    return null;
+  }
+
+  // Logical OR operator for ||
+  // It's possible when doing a || this function (opBitwiseOr) is never called due
+  // to short circuiting. E.g.
+  // If you perform x || y What actually is called is
+  // BaseHandle.op_True( x ) ? BaseHandle.op_True( x ) : BaseHandle.opTrue( BaseHandle.opBitwiseOr(x,y) )
+  public static BaseHandle operator |(BaseHandle x, BaseHandle y)
+  {
+    if ( !BaseHandle.ReferenceEquals( x, null ) || !BaseHandle.ReferenceEquals( y, null ) )
+    {
+       if( x.HasBody() )
+       {
+         return x;
+       }
+       if( y.HasBody() )
+       {
+         return y;
+       }
+       return null;
+    }
+    return null;
+  }
+
+  // Logical ! operator
+  public static bool operator !(BaseHandle x)
+  {
+    // if the C# object is null, return true
+    if( BaseHandle.ReferenceEquals( x, null ) )
+    {
+      return true;
+    }
+    if( x.HasBody() )
+    {
+      return false;
+    }
+    return true;
+  }
 
+%}
\ No newline at end of file
index e921f76..323a6fc 100644 (file)
@@ -26,6 +26,63 @@ using System.Runtime.InteropServices;
 %define Animation_EVENTHANDLER_TYPEMAP_HELPER(NameSpace, ClassName)
   %typemap(cscode) NameSpace::ClassName %{
 
+    public static readonly int PARENT_ORIGIN = NDalicPINVOKE.Actor_Property_PARENT_ORIGIN_get();
+    public static readonly int PARENT_ORIGIN_X = NDalicPINVOKE.Actor_Property_PARENT_ORIGIN_X_get();
+    public static readonly int PARENT_ORIGIN_Y = NDalicPINVOKE.Actor_Property_PARENT_ORIGIN_Y_get();
+    public static readonly int PARENT_ORIGIN_Z = NDalicPINVOKE.Actor_Property_PARENT_ORIGIN_Z_get();
+    public static readonly int ANCHOR_POINT = NDalicPINVOKE.Actor_Property_ANCHOR_POINT_get();
+    public static readonly int ANCHOR_POINT_X = NDalicPINVOKE.Actor_Property_ANCHOR_POINT_X_get();
+    public static readonly int ANCHOR_POINT_Y = NDalicPINVOKE.Actor_Property_ANCHOR_POINT_Y_get();
+    public static readonly int ANCHOR_POINT_Z = NDalicPINVOKE.Actor_Property_ANCHOR_POINT_Z_get();
+    public static readonly int SIZE = NDalicPINVOKE.Actor_Property_SIZE_get();
+    public static readonly int SIZE_WIDTH = NDalicPINVOKE.Actor_Property_SIZE_WIDTH_get();
+    public static readonly int SIZE_HEIGHT = NDalicPINVOKE.Actor_Property_SIZE_HEIGHT_get();
+    public static readonly int SIZE_DEPTH = NDalicPINVOKE.Actor_Property_SIZE_DEPTH_get();
+    public static readonly int POSITION = NDalicPINVOKE.Actor_Property_POSITION_get();
+    public static readonly int POSITION_X = NDalicPINVOKE.Actor_Property_POSITION_X_get();
+    public static readonly int POSITION_Y = NDalicPINVOKE.Actor_Property_POSITION_Y_get();
+    public static readonly int POSITION_Z = NDalicPINVOKE.Actor_Property_POSITION_Z_get();
+    public static readonly int WORLD_POSITION = NDalicPINVOKE.Actor_Property_WORLD_POSITION_get();
+    public static readonly int WORLD_POSITION_X = NDalicPINVOKE.Actor_Property_WORLD_POSITION_X_get();
+    public static readonly int WORLD_POSITION_Y = NDalicPINVOKE.Actor_Property_WORLD_POSITION_Y_get();
+    public static readonly int WORLD_POSITION_Z = NDalicPINVOKE.Actor_Property_WORLD_POSITION_Z_get();
+    public static readonly int ORIENTATION = NDalicPINVOKE.Actor_Property_ORIENTATION_get();
+    public static readonly int WORLD_ORIENTATION = NDalicPINVOKE.Actor_Property_WORLD_ORIENTATION_get();
+    public static readonly int SCALE = NDalicPINVOKE.Actor_Property_SCALE_get();
+    public static readonly int SCALE_X = NDalicPINVOKE.Actor_Property_SCALE_X_get();
+    public static readonly int SCALE_Y = NDalicPINVOKE.Actor_Property_SCALE_Y_get();
+    public static readonly int SCALE_Z = NDalicPINVOKE.Actor_Property_SCALE_Z_get();
+    public static readonly int WORLD_SCALE = NDalicPINVOKE.Actor_Property_WORLD_SCALE_get();
+    public static readonly int VISIBLE = NDalicPINVOKE.Actor_Property_VISIBLE_get();
+    public static readonly int COLOR = NDalicPINVOKE.Actor_Property_COLOR_get();
+    public static readonly int COLOR_RED = NDalicPINVOKE.Actor_Property_COLOR_RED_get();
+    public static readonly int COLOR_GREEN = NDalicPINVOKE.Actor_Property_COLOR_GREEN_get();
+    public static readonly int COLOR_BLUE = NDalicPINVOKE.Actor_Property_COLOR_BLUE_get();
+    public static readonly int COLOR_ALPHA = NDalicPINVOKE.Actor_Property_COLOR_ALPHA_get();
+    public static readonly int WORLD_COLOR = NDalicPINVOKE.Actor_Property_WORLD_COLOR_get();
+    public static readonly int WORLD_MATRIX = NDalicPINVOKE.Actor_Property_WORLD_MATRIX_get();
+    public static readonly int NAME = NDalicPINVOKE.Actor_Property_NAME_get();
+    public static readonly int SENSITIVE = NDalicPINVOKE.Actor_Property_SENSITIVE_get();
+    public static readonly int LEAVE_REQUIRED = NDalicPINVOKE.Actor_Property_LEAVE_REQUIRED_get();
+    public static readonly int INHERIT_ORIENTATION = NDalicPINVOKE.Actor_Property_INHERIT_ORIENTATION_get();
+    public static readonly int INHERIT_SCALE = NDalicPINVOKE.Actor_Property_INHERIT_SCALE_get();
+    public static readonly int COLOR_MODE = NDalicPINVOKE.Actor_Property_COLOR_MODE_get();
+    public static readonly int POSITION_INHERITANCE = NDalicPINVOKE.Actor_Property_POSITION_INHERITANCE_get();
+    public static readonly int DRAW_MODE = NDalicPINVOKE.Actor_Property_DRAW_MODE_get();
+    public static readonly int SIZE_MODE_FACTOR = NDalicPINVOKE.Actor_Property_SIZE_MODE_FACTOR_get();
+    public static readonly int WIDTH_RESIZE_POLICY = NDalicPINVOKE.Actor_Property_WIDTH_RESIZE_POLICY_get();
+    public static readonly int HEIGHT_RESIZE_POLICY = NDalicPINVOKE.Actor_Property_HEIGHT_RESIZE_POLICY_get();
+    public static readonly int SIZE_SCALE_POLICY = NDalicPINVOKE.Actor_Property_SIZE_SCALE_POLICY_get();
+    public static readonly int WIDTH_FOR_HEIGHT = NDalicPINVOKE.Actor_Property_WIDTH_FOR_HEIGHT_get();
+    public static readonly int HEIGHT_FOR_WIDTH = NDalicPINVOKE.Actor_Property_HEIGHT_FOR_WIDTH_get();
+    public static readonly int PADDING = NDalicPINVOKE.Actor_Property_PADDING_get();
+    public static readonly int MINIMUM_SIZE = NDalicPINVOKE.Actor_Property_MINIMUM_SIZE_get();
+    public static readonly int MAXIMUM_SIZE = NDalicPINVOKE.Actor_Property_MAXIMUM_SIZE_get();
+    public static readonly int INHERIT_POSITION = NDalicPINVOKE.Actor_Property_INHERIT_POSITION_get();
+    public static readonly int CLIPPING_MODE = NDalicPINVOKE.Actor_Property_CLIPPING_MODE_get();
+    public static readonly int BATCH_PARENT = NDalicPINVOKE.Actor_Property_BATCH_PARENT_get();
+
+
     /**
       * @brief Event arguments that passed via Finished signal
       *
@@ -150,6 +207,110 @@ using System.Runtime.InteropServices;
     }
   }
 
+  public void AnimateBy<T,U>(Actor target, U propertyIndex, T relativeValue)
+  {
+       dynamic var = (object)(propertyIndex);
+       dynamic obj = (object)(relativeValue);
+       AnimateBy(new Property(target, var), new Property.Value(obj));
+  }
+
+  public void AnimateBy<T,U>(Actor target, U propertyIndex, T relativeValue, AlphaFunction alpha)
+  {
+       dynamic var = (object)(propertyIndex);
+       dynamic obj = (object)(relativeValue);
+       AnimateBy(new Property(target, var), new Property.Value(obj),  alpha);
+  }
+
+  public void AnimateBy<T,U>(Actor target, U propertyIndex, T relativeValue, TimePeriod period)
+  {
+       dynamic var = (object)(propertyIndex);
+       dynamic obj = (object)(relativeValue);
+       AnimateBy(new Property(target, var), new Property.Value(obj), period);
+  }
+
+  public void AnimateBy<T,U>(Actor target, U propertyIndex, T relativeValue, AlphaFunction alpha, TimePeriod period)
+  {
+       dynamic var = (object)(propertyIndex);
+       dynamic obj = (object)(relativeValue);
+       AnimateBy(new Property(target, var), new Property.Value(obj), alpha, period);
+  }
+
+  public void AnimateTo<T,U>(Actor target, U propertyIndex, T destinationValue)
+  {
+       dynamic var = (object)(propertyIndex);
+       dynamic obj = (object)(destinationValue);
+       AnimateTo(new Property(target, var), new Property.Value(obj));
+  }
+
+  public void AnimateTo<T,U>(Actor target, U propertyIndex, T destinationValue, AlphaFunction alpha)
+  {
+       dynamic var = (object)(propertyIndex);
+       dynamic obj = (object)(destinationValue);
+       AnimateTo(new Property(target, var), new Property.Value(obj), alpha);
+  }
+
+  public void AnimateTo<T,U>(Actor target, U propertyIndex, T destinationValue, TimePeriod period)
+  {
+       dynamic var = (object)(propertyIndex);
+       dynamic obj = (object)(destinationValue);
+       AnimateTo(new Property(target, var), new Property.Value(obj), period);
+  }
+
+  public void AnimateTo<T,U>(Actor target, U propertyIndex, T destinationValue, AlphaFunction alpha, TimePeriod period)
+  {
+       dynamic var = (object)(propertyIndex);
+       dynamic obj = (object)(destinationValue);
+       AnimateTo(new Property(target, var), new Property.Value(obj), alpha, period);
+  }
+
+  public void AnimateBetween<U>(Actor target, U propertyIndex, KeyFrames keyFrames)
+  {
+       dynamic var = (object)(propertyIndex);
+       AnimateBetween(new Property(target, var), keyFrames);
+  }
+
+  public void AnimateBetween<U>(Actor target, U propertyIndex, KeyFrames keyFrames, Animation.Interpolation interpolation)
+  {
+       dynamic var = (object)(propertyIndex);
+       AnimateBetween(new Property(target, var), keyFrames, interpolation);
+  }
+
+  public void AnimateBetween<U>(Actor target, U propertyIndex, KeyFrames keyFrames, AlphaFunction alpha)
+  {
+       dynamic var = (object)(propertyIndex);
+       AnimateBetween(new Property(target, var), keyFrames, alpha);
+  }
+
+  public void AnimateBetween<U>(Actor target, U propertyIndex, KeyFrames keyFrames, AlphaFunction alpha, Animation.Interpolation interpolation)
+  {
+       dynamic var = (object)(propertyIndex);
+       AnimateBetween(new Property(target, var), keyFrames, alpha, interpolation);
+  }
+
+  public void AnimateBetween<U>(Actor target, U propertyIndex, KeyFrames keyFrames, TimePeriod period)
+  {
+       dynamic var = (object)(propertyIndex);
+       AnimateBetween(new Property(target, var), keyFrames, period);
+  }
+
+  public void AnimateBetween<U>(Actor target, U propertyIndex, KeyFrames keyFrames, TimePeriod period, Animation.Interpolation interpolation)
+  {
+       dynamic var = (object)(propertyIndex);
+       AnimateBetween(new Property(target, var), keyFrames,  period, interpolation);
+  }
+
+  public void AnimateBetween<U>(Actor target, U propertyIndex, KeyFrames keyFrames, AlphaFunction alpha, TimePeriod period)
+  {
+       dynamic var = (object)(propertyIndex);
+       AnimateBetween(new Property(target, var), keyFrames, alpha, period);
+  }
+
+  public void AnimateBetween<U>(Actor target, U propertyIndex, KeyFrames keyFrames, AlphaFunction alpha, TimePeriod period, Animation.Interpolation interpolation)
+  {
+       dynamic var = (object)(propertyIndex);
+       AnimateBetween(new Property(target, var), keyFrames, alpha, period, interpolation);
+  }
+
 %}
 
 %enddef
index ac4bc85..491bd95 100644 (file)
@@ -39,6 +39,9 @@ namespace MyCSharpExample
 
     public void Initialize(object source, AUIApplicationInitEventArgs e)
     {
+
+      OperatorTests();
+
       Handle handle = new Handle();
       int myPropertyIndex = handle.RegisterProperty("myProperty", new Property.Value(10.0f), Property.AccessMode.READ_WRITE);
       float myProperty = 0.0f;
@@ -162,6 +165,181 @@ namespace MyCSharpExample
       Console.WriteLine( "    Vector4 r =  " + vector4.r + ", g = " + vector4.g + ", b = " + vector4.b + ", a = " + vector4.a );
     }
 
+
+  public void OperatorTests()
+  {
+    Actor actor = new Actor();
+    Actor differentActor = new Actor();
+    Actor actorSame = actor;
+    Actor nullActor = null;
+
+      // test the true operator
+    if ( actor )
+    {
+      Console.WriteLine ("BaseHandle Operator true (actor) : test passed ");
+    }
+    else
+    {
+      Console.WriteLine ("BaseHandle Operator true (actor): test failed ");
+    }
+
+    Actor parent = actor.GetParent ();
+
+    if ( parent )
+    {
+      Console.WriteLine ("Handle with Empty body  :failed ");
+    }
+    else
+    {
+      Console.WriteLine ("Valid with Empty body  :passed ");
+    }
+
+    actor.Add( differentActor );
+    // here we test two different C# objects, which on the native side have the same body/ ref-object
+    if ( actor == differentActor.GetParent() )
+    {
+       Console.WriteLine ("actor == differentActor.GetParent() :passed ");
+    }
+    else
+    {
+      Console.WriteLine ("actor == differentActor.GetParent() :failed ");
+    }
+
+    if ( differentActor == differentActor.GetParent() )
+    {
+       Console.WriteLine ("differentActor == differentActor.GetParent() :failed ");
+    }
+    else
+    {
+      Console.WriteLine ("differentActor == differentActor.GetParent() :passed ");
+    }
+
+
+    if ( nullActor )
+    {
+      Console.WriteLine ("BaseHandle Operator true (nullActor) : test failed ");
+    }
+    else
+    {
+      Console.WriteLine ("BaseHandle Operator true (nullActor): test passed ");
+    }
+
+    // ! operator
+    if ( !actor )
+    {
+      Console.WriteLine ("BaseHandle Operator !(actor) : test failed ");
+    }
+    else
+    {
+      Console.WriteLine ("BaseHandle Operator !(actor): test passed ");
+    }
+
+    if ( !nullActor )
+    {
+      Console.WriteLine ("BaseHandle Operator !(nullActor) : test passed ");
+    }
+    else
+    {
+      Console.WriteLine ("BaseHandle Operator !(nullActor): test failed ");
+    }
+
+    // Note: operator false only used inside & operator
+    // test equality operator ==
+    if ( actor == actorSame )
+    {
+      Console.WriteLine ("BaseHandle Operator  (actor == actorSame) : test passed");
+    }
+    else
+    {
+      Console.WriteLine ("BaseHandle Operator  (actor == actorSame) : test failed");
+    }
+
+    if ( actor == differentActor )
+    {
+      Console.WriteLine ("BaseHandle Operator (actor == differentActor) : test failed");
+    }
+    else
+    {
+      Console.WriteLine ("BaseHandle Operator (actor == differentActor) : test passed");
+    }
+
+    if ( actor == nullActor )
+    {
+      Console.WriteLine ("BaseHandle Operator (actor == nullActor) : test failed");
+    }
+    else
+    {
+      Console.WriteLine ("BaseHandle Operator (actor == nullActor) : test passed");
+    }
+
+    if ( nullActor == nullActor )
+    {
+      Console.WriteLine ("BaseHandle Operator (nullActor == nullActor) : test passed");
+    }
+    else
+    {
+      Console.WriteLine ("BaseHandle Operator (nullActor == nullActor) : test failed");
+    }
+
+    // test || operator
+    if ( actor || actorSame )
+    {
+      Console.WriteLine ("BaseHandle Operator (actor || actorSame) : test passed");
+    }
+    else
+    {
+      Console.WriteLine ("BaseHandle Operator (actor || actorSame) : test failed");
+    }
+
+    if ( actor || nullActor )
+    {
+      Console.WriteLine ("BaseHandle Operator (actor || nullActor) : test passed");
+    }
+    else
+    {
+      Console.WriteLine ("BaseHandle Operator (actor || nullActor) : test failed");
+    }
+
+    if ( nullActor || nullActor )
+    {
+      Console.WriteLine ("BaseHandle Operator (nullActor || nullActor) : test failed");
+    }
+    else
+    {
+      Console.WriteLine ("BaseHandle Operator (nullActor || nullActor) : test passed");
+    }
+
+
+    // test && operator
+    if ( actor && actorSame )
+    {
+      Console.WriteLine ("BaseHandle Operator (actor && actorSame) : test passed");
+    }
+    else
+    {
+      Console.WriteLine ("BaseHandle Operator (actor && actorSame) : test failed");
+    }
+
+    if ( actor && nullActor )
+    {
+      Console.WriteLine ("BaseHandle Operator (actor && nullActor) : test failed");
+    }
+    else
+    {
+      Console.WriteLine ("BaseHandle Operator (actor && nullActor) : test passed");
+    }
+
+    if ( nullActor && nullActor )
+    {
+      Console.WriteLine ("BaseHandle Operator (nullActor && nullActor) : test failed");
+    }
+    else
+    {
+      Console.WriteLine ("BaseHandle Operator (nullActor && nullActor) : test passed");
+    }
+
+  }
+
     public void MainLoop()
     {
       _application.MainLoop ();
diff --git a/plugins/dali-swig/examples/firstscreen/App.cs b/plugins/dali-swig/examples/firstscreen/App.cs
new file mode 100644 (file)
index 0000000..5f5819f
--- /dev/null
@@ -0,0 +1,392 @@
+using Dali;
+using System;
+using System.Runtime.InteropServices;
+using System.Collections.Generic;
+
+namespace FirstScreen
+{
+    public class FirstScreenApp
+    {
+        private int _currentPostersContainerID;
+        private int _totalPostersContainers;
+
+        private Application _application;
+        private Stage _stage;
+        private Vector2 _stageSize;
+
+        private List<ScrollContainer> _postersContainer;
+
+        private ScrollContainer _menuContainer;
+        private Vector3 _menuItemSize;
+
+        private Layer _bottomClipLayer;
+        private Layer _topClipLayer;
+        private View _topContainer;
+        private View _bottomContainer;
+
+        private FocusEffect _focusEffect;
+        private string _imagePath;
+
+        private ImageView _keyboardFocusIndicator;
+        private ImageView _launcherSeparator;
+        private ImageView[] launcherIcon;
+        private Animation _showBottomContainerAnimation;
+        private Animation _hideBottomContainerAnimation;
+
+        public FirstScreenApp(Application application)
+        {
+            _application = application;
+            _application.Initialized += OnInitialize;
+        }
+
+        public static void Run()
+        {
+            FirstScreenApp tVApp = new FirstScreenApp(Application.NewApplication());
+            tVApp.MainLoop();
+        }
+
+        public void MainLoop()
+        {
+            _application.MainLoop();
+        }
+
+        // Create Items for Poster ScrollContainer
+        private void CreatePosters()
+        {
+            for (int j = 0; j < _totalPostersContainers; j++)
+            {
+                View posterContainer = _postersContainer[j].Container;
+                for (int i = 0; i < Constants.PostersItemsCount; i++)
+                {
+                    if (j % _totalPostersContainers == 0)
+                    {
+                        View item = new ImageView(_imagePath + "/poster"+j+"/"+ (i % 6)+ ".jpg");
+                        item.SetName ("poster-item-" + _postersContainer[j].ItemCount);
+                        _postersContainer[j].AddItem(item);
+                    }
+                    else
+                    {
+                        View item = new ImageView(_imagePath + "/poster"+j+"/"+ (i % 6)+ ".jpg");
+                        item.SetName ("poster-item-" + _postersContainer[j].ItemCount);
+                        _postersContainer[j].AddItem(item);
+                    }
+                }
+
+                if (j == 0)
+                {
+                    _postersContainer[j].Show();
+                }
+                else
+                {
+                    _postersContainer[j].Hide();
+                }
+
+                _postersContainer[j].SetFocused(false);
+            }
+
+            _currentPostersContainerID = 0;
+        }
+
+        // Create Items for Menu ScrollContainer
+        private void CreateMenu()
+        {
+            View menuContainer = _menuContainer.Container;
+            menuContainer.Position = new Vector3(Constants.LauncherWidth, 0.0f, 0.0f);
+
+            for(int i = 0; i < Constants.MenuItemsCount; i++)
+            {
+                View menuItem = new ImageView(_imagePath + "/menu/" + i % 7 + ".png");
+                menuItem.SetName("menu-item-" + _menuContainer.ItemCount);
+                _menuContainer.AddItem(menuItem);
+            }
+        }
+
+        private Actor OnKeyboardPreFocusChangeSignal(object source, KeyboardFocusManager.PreFocusChangeEventArgs e)
+        {
+            Actor actor = _menuContainer.ItemRoot;
+
+            if (e.Direction == View.KeyboardFocus.Direction.UP)
+            {
+                // Move the Focus to Poster ScrollContainer and hide Bottom Container (Menu ScrollContainer)
+                if (_menuContainer.IsFocused)
+                {
+                    actor = _postersContainer[_currentPostersContainerID].GetCurrentFocusedActor();
+                    _menuContainer.SetFocused(false);
+                    _postersContainer[_currentPostersContainerID].SetFocused(true);
+                    HideBottomContainer();
+
+                    // Also apply Focus animation on Focused item on Poster ScrollContainer
+                    _postersContainer[_currentPostersContainerID].FocusAnimation(_focusEffect, FocusEffectDirection.BottomToTop);
+                }
+            }
+            else if (e.Direction == View.KeyboardFocus.Direction.DOWN)
+            {
+                // Show Bottom Container (Menu ScrollContainer) and move the Focus to it
+                if (!_menuContainer.IsFocused)
+                {
+                    ShowBottomContainer();
+                    actor = _menuContainer.GetCurrentFocusedActor();
+                    _postersContainer[_currentPostersContainerID].SetFocused(false);
+                    _menuContainer.SetFocused(true);
+
+                    // Also apply Focus animation on Focused item on Menu ScrollContainer
+                    _menuContainer.FocusAnimation(_focusEffect, FocusEffectDirection.TopToBottom);
+                }
+            }
+            else if (e.Direction == View.KeyboardFocus.Direction.LEFT)
+            {
+                if (_menuContainer.IsFocused)
+                {
+                    // Move the Focus to the left item/image of currently focused item on Menu ScrollContainer
+                    actor = _menuContainer.FocusPrevious();
+
+                    int id = _menuContainer.FocusedItemID % _totalPostersContainers;
+                    if (id != _currentPostersContainerID)
+                    {
+                        _postersContainer[_currentPostersContainerID].Hide();
+                        _currentPostersContainerID = id;
+
+                        _postersContainer[_currentPostersContainerID].Show();
+                    }
+                }
+                else
+                {
+                    // Move the Focus to the left item/image of currently focused item on Poster ScrollContainer
+                    actor = _postersContainer[_currentPostersContainerID].FocusPrevious();
+                }
+            }
+            else if (e.Direction == View.KeyboardFocus.Direction.RIGHT)
+            {
+                if (_menuContainer.IsFocused)
+                {
+                    // Move the Focus to the right item/image of currently focused item on Menu ScrollContainer
+                    actor = _menuContainer.FocusNext();
+
+                    int id = _menuContainer.FocusedItemID % _totalPostersContainers;
+                    if (id != _currentPostersContainerID)
+                    {
+                        _postersContainer[_currentPostersContainerID].Hide();
+                        _currentPostersContainerID = id;
+                        _postersContainer[_currentPostersContainerID].Show();
+                    }
+                }
+                else
+                {
+                    // Move the Focus to the right item/image of currently focused item on Poster ScrollContainer
+                    actor = _postersContainer[_currentPostersContainerID].FocusNext();
+                }
+            }
+
+            return actor;
+        }
+
+        // Hide Bottom Container (Menu ScrollContainer) when it is not focused
+        private void HideBottomContainer()
+        {
+            _topClipLayer.ClippingBox = new RectInteger(0,
+                                                        Convert.ToInt32(_stageSize.height * Constants.TopContainerPositionFactor),
+                                                        Convert.ToInt32((_stageSize.width)),
+                                                        Convert.ToInt32((_stageSize.height * Constants.TopClipLayerExpandHeightFactor)));  // X, Y, Width, Height
+
+            _hideBottomContainerAnimation.AnimateTo(new Property(_bottomContainer, Actor.Property.POSITION),
+                                                    new Property.Value(new Vector3(0.0f, _stageSize.height * Constants.BottomContainerHidePositionFactor, 0.0f)),
+                                                    new AlphaFunction(AlphaFunction.BuiltinFunction.EASE_OUT_SINE));
+            _hideBottomContainerAnimation.Play();
+        }
+
+        // Show (unhide) Bottom Container (Menu ScrollContainer) when it is focused
+        private void ShowBottomContainer()
+        {
+            _topClipLayer.ClippingBox = new RectInteger(0,
+                                                        Convert.ToInt32(_stageSize.height * Constants.TopContainerPositionFactor),
+                                                        Convert.ToInt32((_stageSize.width)),
+                                                        Convert.ToInt32((_stageSize.height * Constants.TopClipLayerHeightFactor)));  // X, Y, Width, Height
+
+            _showBottomContainerAnimation.AnimateTo(new Property(_bottomContainer, Actor.Property.POSITION),
+                                                    new Property.Value(new Vector3(0.0f, _stageSize.height * Constants.BottomContainerShowPositionFactor, 0.0f)),
+                                                    new AlphaFunction(AlphaFunction.BuiltinFunction.EASE_OUT_SINE));
+            _showBottomContainerAnimation.Play();
+        }
+
+        // First screen demo Application initialisation
+        private void OnInitialize(object source, AUIApplicationInitEventArgs e)
+        {
+            _stage = Stage.GetCurrent();
+            _stageSize = _stage.GetSize();
+//            _stage.SetBackgroundColor(NDalic.TRANSPARENT);
+
+            _totalPostersContainers = Constants.TotalPostersContainers;
+            _imagePath = "./images/"; // Desktop
+//            _imagePath = "/home/owner/apps_rw/org.tizen.firstscreen/res/images/"; // Target
+
+            _postersContainer = new List<ScrollContainer> ();
+            _menuContainer = new ScrollContainer ();
+
+            _hideBottomContainerAnimation = new Animation(0.25f);
+            _showBottomContainerAnimation = new Animation(0.25f);
+
+            // Create a Top Container for poster items
+            _topContainer = new View();
+            _topContainer.Size = new Vector3(_stageSize.width, _stageSize.height * Constants.TopContainerHeightFactor, 0.0f);
+            _topContainer.Position = new Vector3(0.0f, _stageSize.y * Constants.TopContainerPositionFactor, 0.0f);
+            _topContainer.ParentOrigin = NDalic.ParentOriginTopLeft;
+            _topContainer.AnchorPoint = NDalic.AnchorPointTopLeft;
+
+            // Add a background to Top container
+            Property.Map visual = new Property.Map();
+            visual.Insert(NDalic.VISUAL_PROPERTY_TYPE, new Property.Value((int)VisualType.IMAGE));
+            visual.Insert(NDalic.IMAGE_VISUAL_URL, new Property.Value(_imagePath + "/background.png"));
+            _topContainer.Background = visual;
+            _topContainer.Name = "TopControl";
+
+            // Create a Bottom Container
+            _bottomContainer = new View();
+            _bottomContainer.Size = new Vector3(_stageSize.width, _stageSize.height * Constants.BottomContainerHeightFactor, 0.0f);
+            _bottomContainer.Position = new Vector3(0.0f, _stageSize.height * Constants.BottomContainerHidePositionFactor, 0.0f);
+            _bottomContainer.ParentOrigin = NDalic.ParentOriginTopLeft;
+            _bottomContainer.AnchorPoint = NDalic.AnchorPointTopLeft;
+
+            // Add a background to Bottom Container
+            visual = new Property.Map();
+            visual.Insert(NDalic.VISUAL_PROPERTY_TYPE, new Property.Value((int)VisualType.IMAGE));
+            visual.Insert(NDalic.IMAGE_VISUAL_URL, new Property.Value(_imagePath + "/background.png"));
+            _bottomContainer.Background = visual;
+            _bottomContainer.Name = "BottomControl";
+
+            // Add both Top and Bottom Containers to Stage
+            _stage.Add(_topContainer);
+            _stage.Add(_bottomContainer);
+
+            // Add a clip layer to Top Container
+            _topClipLayer = new Layer();
+            _topClipLayer.AnchorPoint = NDalic.AnchorPointBottomCenter;
+            _topClipLayer.ParentOrigin = NDalic.ParentOriginBottomCenter;
+            _topClipLayer.ClippingEnable = true;
+            _topClipLayer.ClippingBox = new RectInteger(0,
+                                                        Convert.ToInt32(_stageSize.height * Constants.TopContainerPositionFactor),
+                                                        Convert.ToInt32((_stageSize.width)),
+                                                        Convert.ToInt32((_stageSize.height * Constants.TopClipLayerHeightFactor)));  // X, Y, Width, Height
+            _topContainer.Add(_topClipLayer);
+
+            // Create a SpotLight for items / images of both Poster and Menu ScrollContainers
+            ImageView spotLight = new ImageView(_imagePath + "/highlight_spot.png");
+            spotLight.WidthResizePolicy = "USE_NATURAL_SIZE";
+            spotLight.HeightResizePolicy = "USE_NATURAL_SIZE";
+            spotLight.ParentOrigin = NDalic.ParentOriginCenter;
+            spotLight.AnchorPoint = NDalic.AnchorPointCenter;
+            spotLight.Name = "spotLight";
+
+            // Create a shadowBorder for items / images of Poster ScrollContainers
+            ImageView shadowBorder = new ImageView(_imagePath + "/thumbnail_shadow.9.png");
+            shadowBorder.ParentOrigin = NDalic.ParentOriginCenter;
+            shadowBorder.AnchorPoint = NDalic.AnchorPointCenter;
+            shadowBorder.WidthResizePolicy = "SIZE_FIXED_OFFSET_FROM_PARENT";
+            shadowBorder.HeightResizePolicy = "SIZE_FIXED_OFFSET_FROM_PARENT";
+            shadowBorder.SetSizeModeFactor(new Vector3(32.0f, 41.0f, 0.0f));
+            shadowBorder.Name = "poster shadowBorder";
+
+            // Create Poster Containers and add them to Top Clip layer
+            for (int i = 0; i < _totalPostersContainers; i++)
+            {
+                _postersContainer.Add(new ScrollContainer());
+                _postersContainer[i].Container.Name = "poster" + i;
+                if (i == 0)
+                {
+                    _postersContainer[i].ItemSize = new Vector3((_stageSize.width * Constants.Poster0ItemWidthFactor) - Constants.PostersContainerPadding,
+                                                                _stageSize.height * Constants.PostersItemHeightFactor, 0.0f);
+                }
+                else
+                {
+                    _postersContainer[i].ItemSize = new Vector3(_stageSize.width * Constants.Poster1ItemWidthFactor,
+                                                                _stageSize.height * Constants.PostersItemHeightFactor, 0.0f);
+                }
+                _postersContainer[i].Padding = Constants.PostersContainerPadding;
+                _postersContainer[i].MarginX = Constants.PostersContainerMargin;
+                _postersContainer[i].OffsetY = Constants.PostersContainerOffsetYFactor;
+                _postersContainer[i].Width = _stageSize.width;
+                _postersContainer[i].Height = _stageSize.height * Constants.PostersContainerHeightFactor;
+                _postersContainer[i].ShadowBorder = shadowBorder;
+                _postersContainer[i].ShadowBorder.Position = new Vector3(0.0f, 4.0f, 0.0f);
+                _postersContainer[i].SpotLight = spotLight;
+                _topClipLayer.Add(_postersContainer[i].Container);
+            }
+
+            // Add a clip layer to Bottom Container
+            _bottomClipLayer = new Layer();
+            _bottomClipLayer.AnchorPoint = NDalic.AnchorPointBottomCenter;
+            _bottomClipLayer.ParentOrigin = NDalic.ParentOriginBottomCenter;
+            _bottomClipLayer.ClippingEnable = true;
+            _bottomClipLayer.ClippingBox = new RectInteger(Convert.ToInt32(Constants.LauncherWidth),
+                                                           Convert.ToInt32(_stageSize.height * Constants.BottomContainerShowPositionFactor),
+                                                           Convert.ToInt32((_stageSize.width)),
+                                                           Convert.ToInt32((_stageSize.height - (_stageSize.height * Constants.BottomClipLayerHeightFactor))));  // X, Y, Width, Height
+            _bottomContainer.Add(_bottomClipLayer);
+
+            // Add Launcher items to Bottom Container. Launcher is used to display three images on left of Menu ScrollContainer
+            launcherIcon = new ImageView[Convert.ToInt32(Constants.LauncherItemsCount)];
+            for (int launcherIndex = 0; launcherIndex < Constants.LauncherItemsCount; launcherIndex++)
+            {
+                launcherIcon[launcherIndex] = new ImageView(_imagePath + "/" + launcherIndex + "-normal.png");
+                launcherIcon[launcherIndex].Name = "launcherIcon" + launcherIndex;
+                launcherIcon[launcherIndex].WidthResizePolicy = "USE_NATURAL_SIZE";
+                launcherIcon[launcherIndex].HeightResizePolicy = "USE_NATURAL_SIZE";
+                launcherIcon[launcherIndex].ParentOrigin = NDalic.ParentOriginCenterLeft;
+                launcherIcon[launcherIndex].AnchorPoint = NDalic.AnchorPointCenterLeft;
+                launcherIcon[launcherIndex].Position = new Vector3(Constants.LauncherIconWidth * launcherIndex + Constants.LauncherLeftMargin, 0.0f, 0.0f);
+                _bottomContainer.Add(launcherIcon[launcherIndex]);
+            }
+
+            // Add a shadow seperator image between last Launcher icon and Menu ScrollContainer
+            _launcherSeparator = new ImageView(_imagePath + "/focus_launcher_shadow_n.png");
+            _launcherSeparator.Name = "launcherSeparator";
+            _launcherSeparator.WidthResizePolicy = "USE_NATURAL_SIZE";
+            _launcherSeparator.HeightResizePolicy = "FILL_TO_PARENT";
+            _launcherSeparator.ParentOrigin = NDalic.ParentOriginCenterLeft;
+            _launcherSeparator.AnchorPoint = NDalic.AnchorPointCenterLeft;
+            _launcherSeparator.Position = new Vector3(Constants.LauncherIconWidth * Constants.LauncherItemsCount + Constants.LauncherLeftMargin, 0.0f, 0.0f);
+            _bottomContainer.Add(_launcherSeparator);
+
+            // Create Menu Container and add it to Bottom Clip Layer
+            _menuItemSize = new Vector3((_stageSize.width * Constants.MenuItemWidthFactor) - Constants.MenuContainerPadding,
+                                        _stageSize.height * Constants.MenuItemHeightFactor, 0.0f);
+            _menuContainer.Container.Name = "menu";
+            _menuContainer.ItemSize = _menuItemSize;
+            _menuContainer.Padding = Constants.MenuContainerPadding;
+            _menuContainer.MarginX = Constants.MenuContainerMargin;
+            _menuContainer.OffsetY = Constants.MenuContainerOffsetYFactor;
+            _menuContainer.OffsetX = Constants.LauncherWidth;
+            _menuContainer.Width = _stageSize.width - Constants.LauncherWidth;
+            _menuContainer.Height = _stageSize.height * Constants.MenuContainerHeightFactor;
+            _menuContainer.ShadowBorder = new ImageView(_imagePath + "/focus_launcher_shadow.9.png");
+            _menuContainer.ShadowBorder.Name = "_menuContainer.ShadowBorder";
+            _menuContainer.ShadowBorder.Size = new Vector3(_menuContainer.ItemSize.width + 40.0f, _menuContainer.ItemSize.height + 50.0f, 0.0f);
+            _menuContainer.ShadowBorder.Position = new Vector3(0.0f, 5.0f, 0.0f);
+            _menuContainer.ShadowBorder.ParentOrigin = NDalic.ParentOriginCenter;
+            _menuContainer.ShadowBorder.AnchorPoint = NDalic.AnchorPointCenter;
+            _menuContainer.SpotLight = spotLight;
+            _bottomClipLayer.Add(_menuContainer.Container);
+
+            CreatePosters(); // Create Items for Poster ScrollContainer
+            CreateMenu();    // Create Items for Menu ScrollContainer
+
+            // Initialize PreFocusChange event of KeyboardFocusManager
+            KeyboardFocusManager keyboardFocusManager = KeyboardFocusManager.Get();
+            keyboardFocusManager.PreFocusChange += OnKeyboardPreFocusChangeSignal;
+
+            _keyboardFocusIndicator = new ImageView(_imagePath + "/highlight_stroke.9.png");
+            _keyboardFocusIndicator.ParentOrigin = NDalic.ParentOriginCenter;
+            _keyboardFocusIndicator.AnchorPoint = NDalic.AnchorPointCenter;
+            _keyboardFocusIndicator.WidthResizePolicy = "FILL_TO_PARENT";
+            _keyboardFocusIndicator.HeightResizePolicy = "FILL_TO_PARENT";
+
+            keyboardFocusManager.SetFocusIndicatorActor(_keyboardFocusIndicator);
+
+            _focusEffect = new FocusEffect();
+
+            // Move Fcous to Bottom Container (Menu ScrollContainer)
+            ShowBottomContainer();
+            _menuContainer.SetFocused(true);
+        }
+    }
+}
+
diff --git a/plugins/dali-swig/examples/firstscreen/Constants.cs b/plugins/dali-swig/examples/firstscreen/Constants.cs
new file mode 100644 (file)
index 0000000..7ada417
--- /dev/null
@@ -0,0 +1,43 @@
+using System;
+
+namespace FirstScreen
+{
+    public class Constants
+    {
+        public const int TotalPostersContainers = 2;                  // Number of Poster ScrollContainers to be added on Top Container
+
+        public const float TopContainerHeightFactor = 0.38f;          // Height Factor of stage height used for Top Container total height
+        public const float TopContainerPositionFactor = 0.50f;        // Position Factor of stage height used for Top Container position
+        public const float TopClipLayerHeightFactor = 0.34f;          // Height Factor of stage height used for Top Clip layer height
+        public const float TopClipLayerExpandHeightFactor = 0.36f;    // Expanded Height Factor of stage height used for Top Clip layer height (used when Bottom container is hidden)
+        public const float PostersContainerHeightFactor = 0.32f;      // Height Factor of stage height used for Poster ScrollContainers
+        public const float PostersContainerPadding = 2.0f;            // Padding size used between items / images in Poster ScrollContainer
+        public const float PostersContainerMargin = 60.0f;            // Extra margin Padding size used between items / images in Poster ScrollContainer when item / image is focused
+        public const float PostersContainerOffsetYFactor = 0.17f;     // Position Factor of Poster item height used for Poster items / images position
+
+        public const float BottomContainerHeightFactor = 0.16f;       // Height Factor of stage height used for Bottom Container total height
+        public const float BottomContainerHidePositionFactor = 0.88f; // Position Factor of stage height used for Bottom Container position when bottom container is hidden (not focused)
+        public const float BottomContainerShowPositionFactor = 0.84f; // Position Factor of stage height used for Bottom Container position when bottom container is not hidden (focused)
+        public const float MenuContainerHeightFactor = 0.16f;         // Height Factor of stage height used for Bottom ScrollContainers
+        public const float BottomClipLayerHeightFactor = 0.84f;       // Height Factor of stage height used for Bottom Clip layer height
+        public const float MenuContainerPadding = 10.0f;              // Padding size used between items / images in Menu ScrollContainer
+        public const float MenuContainerMargin = 25.0f;               // Extra margin Padding size used between items / images in Menu ScrollContainer when item / image is focused
+        public const float MenuContainerOffsetYFactor = 0.35f;        // Position Factor of Poster item height used for Menu items / images position
+
+        public const float MenuItemWidthFactor = 0.125f;              // Width Factor (1/8) of stage Width used for Menu items / images Width
+        public const float MenuItemHeightFactor = 0.10f;              // Height Factor of stage height used for Menu items / images Height
+        public const float MenuItemsCount = 14;                       // Number of Menu items / images used in a Menu ScrollContainer
+
+        public const float Poster0ItemWidthFactor = 0.25f;            // Width Factor (1/4) of stage Width used for Poster items / images Width in a Poster ScrollContainer 0
+        public const float Poster1ItemWidthFactor = 0.24f;            // Width Factor of stage Width used for Poster items / images Width in a Poster ScrollContainer 1
+        public const float PostersItemHeightFactor = 0.24f;           // Height Factor of stage height used for Poster items / images Height
+        public const float PostersItemsCount = 24;                    // Number of Menu items / images used in a Poster ScrollContainer
+
+        public const float LauncherWidth = 280.0f;                    // Width of Launcher. Launcher is used to display three images on left of Menu ScrollContainer
+        public const float LauncherLeftMargin = 40.0f;                // Extra Spaces to the left of first Launcher item / image
+        public const float LauncherSeparatorWidth = 20.0f;            // Extra area / space to the left of Menu ScrollContainer used for a speration shadow image
+        public const float LauncherItemsCount = 3.0f;                 // Total number of Launcher items / images
+        public const float LauncherIconWidth = (LauncherWidth - LauncherLeftMargin - LauncherSeparatorWidth) / LauncherItemsCount; // Width of each Launcher item / image
+    }
+}
+
diff --git a/plugins/dali-swig/examples/firstscreen/FocusData.cs b/plugins/dali-swig/examples/firstscreen/FocusData.cs
new file mode 100644 (file)
index 0000000..b1ee188
--- /dev/null
@@ -0,0 +1,106 @@
+using Dali;
+using System;
+
+namespace FirstScreen
+{
+    public class FocusData
+    {
+        private string _name;                 // Name used for FocusData object (mainly to differentiate key frame animation )
+        private string _imageName;            // Image File Name (to be loaded from disk) used for ImageView used in key frame animation
+        private Vector3 _parentOrigin;        // ParentOrigin applied to ImageView
+        private Vector3 _initSize;            // InitSize used for key frame animation
+        private Vector3 _targetSize;          // TargetSize used for key frame animation
+        private float _keyFrameStart;         // KeyFrameStart used for key frame animation
+        private float _keyFrameEnd;           // KeyFrameEnd used for key frame animation
+        private Direction _direction;         // Direction used for key frame animation
+        private ImageView _imageFocus;        // ImageView used in key frame animation
+
+        // Initialize FocusData used for key frame animation
+        public FocusData(string name, string imageName, Direction direction, Vector3 parentOrigin, Vector3 initSize,
+                        Vector3 targetSize, float keyFrameStart, float keyFrameEnd)
+        {
+            _name = name;
+            _imageName = imageName;
+            _parentOrigin = parentOrigin;
+            _initSize = initSize;
+            _targetSize = targetSize;
+            _keyFrameStart = keyFrameStart;
+            _keyFrameEnd = keyFrameEnd;
+            _direction = direction;
+
+            _imageFocus = new ImageView("./images/focuseffect/" + _imageName); // Desktop
+//            _imageFocus = new ImageView("/home/owner/apps_rw/org.tizen.firstscreen/res/images/focuseffect/" + _imageName); // Target
+
+            _imageFocus.ParentOrigin = _parentOrigin;
+            _imageFocus.AnchorPoint = NDalic.AnchorPointCenter;
+            _imageFocus.Name = _name;
+        }
+
+        public enum Direction
+        {
+            Horizontal,
+            Vertical
+        };
+
+        public Direction FocusDirection
+        {
+            get {return _direction;}
+            set {_direction = value;}
+        }
+
+        public string Name
+        {
+            get {return _name;}
+            set {_name = value;}
+        }
+
+        public string ImageName
+        {
+            get {return _imageName;}
+            set {_imageName = value;}
+        }
+
+        public Vector3 ParentOrigin
+        {
+            get
+            {
+                return _parentOrigin;
+            }
+            set
+            {
+                _parentOrigin = value;
+                _imageFocus.ParentOrigin = _parentOrigin;
+            }
+        }
+
+        public Vector3 InitSize
+        {
+            get {return _initSize;}
+            set {_initSize = value;}
+        }
+
+        public Vector3 TargetSize
+        {
+            get {return _targetSize;}
+            set {_targetSize = value;}
+        }
+
+        public float KeyFrameStart
+        {
+            get {return _keyFrameStart;}
+            set {_keyFrameStart = value;}
+        }
+
+        public float KeyFrameEnd
+        {
+            get {return _keyFrameEnd;}
+            set {_keyFrameEnd = value;}
+        }
+
+        public ImageView ImageItem
+        {
+            get {return _imageFocus;}
+        }
+    }
+}
+
diff --git a/plugins/dali-swig/examples/firstscreen/FocusEffect.cs b/plugins/dali-swig/examples/firstscreen/FocusEffect.cs
new file mode 100644 (file)
index 0000000..d02e483
--- /dev/null
@@ -0,0 +1,203 @@
+using Dali;
+using System;
+using System.Collections.Generic;
+using System.Collections.Specialized;
+
+namespace FirstScreen
+{
+    public class FocusEffect : IFocusEffect
+    {
+        private float _frameThickness;
+        private FocusData[] _focusData; // Each FocusData is used for one key frame animation (total 6 key frame animations needed for EddenEffect)
+        private Animation _animation;      // Animation used to apply all six key frame animations
+
+        public FocusEffect()
+        {
+            _frameThickness = 10.0f;
+            float _bottomFrameTime = 0.6f; // complete the halo/bottom animation 60% of the way through
+            float _sideFrameTime = 0.8f; // Start the side frame  animation after the bottom animation and complete at 80% of the way through
+            float _topFrameTime = 1.0f; // start the top frame animation after the side frame animation and complete at 100% way through
+
+            // Six key frame animations (FocusData objects) needed for EddenEffect
+            // Two key frame animations for top horizontal effect
+            // Two key frame animations for bottom horizontal effect
+            // Two key frame animations for vertical horizontal effect
+            _focusData = new FocusData[6];
+
+            FocusData focusData = new FocusData("halo", "halo.png", FocusData.Direction.Horizontal, NDalic.ParentOriginTopCenter,
+                                             new Vector3(50,20,0),  new Vector3(0.0f, 100.0f , 0.0f), 0.0f, _bottomFrameTime);
+            _focusData[0] = focusData;
+
+            focusData = new FocusData("bottom", "horizontalFrame.png", FocusData.Direction.Horizontal, NDalic.ParentOriginTopCenter,
+                                    new Vector3(0.0f, 0.0f, 0.0f),  new Vector3(0.0f, _frameThickness, 0.0f), 0.0f, _bottomFrameTime);
+            _focusData[1] = focusData;
+
+            focusData = new FocusData("left", "verticalFrame.png", FocusData.Direction.Vertical, NDalic.ParentOriginBottomLeft,
+                                    new Vector3(0.0f, 0.0f, 0.0f),  new Vector3(_frameThickness, 0.0f, 0.0f), _bottomFrameTime, _sideFrameTime);
+            _focusData[2] = focusData;
+
+            focusData = new FocusData("right", "verticalFrame.png", FocusData.Direction.Vertical, NDalic.ParentOriginBottomRight,
+                                    new Vector3(0.0f, 0.0f, 0.0f),  new Vector3(_frameThickness, 0.0f, 0.0f), _bottomFrameTime, _sideFrameTime);
+            _focusData[3] = focusData;
+
+            focusData = new FocusData("top-left", "horizontalFrame.png", FocusData.Direction.Horizontal, NDalic.ParentOriginBottomLeft,
+                                    new Vector3(0.0f, 0.0f, 0.0f),  new Vector3(0.0f ,_frameThickness, 0.0f), _sideFrameTime, _topFrameTime);
+            _focusData[4] = focusData;
+
+            focusData = new FocusData("top-right", "horizontalFrame.png", FocusData.Direction.Horizontal, NDalic.ParentOriginBottomRight,
+                                    new Vector3(0.0f, 0.0f, 0.0f),  new Vector3(0.0f, _frameThickness, 0.0f), _sideFrameTime, _topFrameTime);
+            _focusData[5] = focusData;
+        }
+
+        public void FocusAnimation(View parentItem, Vector3 itemSize, float duration, FocusEffectDirection direction)
+        {
+            var itemWidth = itemSize.x + _frameThickness / 2;
+            var itemHeight = itemSize.y + _frameThickness / 3;
+
+            if (_animation)
+            {
+                _animation.Clear();
+                _animation.Reset();
+            }
+            _animation = new Animation(duration);
+
+            if (direction == FocusEffectDirection.BottomToTop)
+            {
+                _focusData[0].ParentOrigin = NDalic.ParentOriginBottomCenter;
+                _focusData[1].ParentOrigin = NDalic.ParentOriginBottomCenter;
+                _focusData[2].ParentOrigin = NDalic.ParentOriginBottomLeft;
+                _focusData[3].ParentOrigin = NDalic.ParentOriginBottomRight;
+                _focusData[4].ParentOrigin = NDalic.ParentOriginTopLeft;
+                _focusData[5].ParentOrigin = NDalic.ParentOriginTopRight;
+            }
+            else
+            {
+                _focusData[0].ParentOrigin = NDalic.ParentOriginTopCenter;
+                _focusData[1].ParentOrigin = NDalic.ParentOriginTopCenter;
+                _focusData[2].ParentOrigin = NDalic.ParentOriginBottomLeft;
+                _focusData[3].ParentOrigin = NDalic.ParentOriginBottomRight;
+                _focusData[4].ParentOrigin = NDalic.ParentOriginBottomLeft;
+                _focusData[5].ParentOrigin = NDalic.ParentOriginBottomRight;
+            }
+
+            foreach (FocusData focusData in _focusData)
+            {
+                var currentParent =  focusData.ImageItem.GetParent();
+
+                // first parent the controls
+                if (parentItem != currentParent)
+                {
+                    parentItem.Add(focusData.ImageItem);
+                }
+
+                focusData.ImageItem.Size = new Vector3(100.0f,100.0f, 0.0f);
+                parentItem.Add(focusData.ImageItem);
+
+                Vector3 targetSize = focusData.TargetSize;
+                Vector3 initSize = focusData.InitSize;
+
+                if (focusData.FocusDirection == FocusData.Direction.Horizontal)
+                {
+                    // adjust the width to match the parent
+                    targetSize.x = itemWidth;
+                }
+                else // vertical frame
+                {
+                    // adjust the height to match the parent
+                    targetSize.y = itemHeight;
+                }
+
+                // half the size for the top frame as we come out from both left / right sides
+                if (focusData.Name == "top-right" ||  focusData.Name == "top-left")
+                {
+                    targetSize.x = itemWidth - _frameThickness;
+                }
+
+                KeyFrames keyFrames = new KeyFrames();
+
+                keyFrames.Add(0.0f, new Property.Value(initSize));
+                keyFrames.Add(focusData.KeyFrameStart, new Property.Value(initSize));
+                keyFrames.Add(focusData.KeyFrameEnd, new Property.Value(targetSize));
+
+                // for halo add an extra keyframe to shrink it ( in 20% of time after it has finished)
+                if (focusData.Name =="halo")
+                {
+                    keyFrames.Add(focusData.KeyFrameEnd + 0.2f, new Property.Value(initSize));
+                }
+
+                _animation.AnimateBetween(new Property(focusData.ImageItem, Actor.Property.SIZE), keyFrames,
+                                          new AlphaFunction(AlphaFunction.BuiltinFunction.EASE_OUT_SINE));
+
+                // Simulate the vertical frame growing from the top.
+                // Vertical items are anchored to the bottom of the parent... so when they grow
+                // we need to move them to the middle of the parent ( otherwise they stick out the bottom)
+                if (focusData.FocusDirection == FocusData.Direction.Vertical)
+                {
+                    //animate position as well so it looks like animation is coming from bottom
+                    KeyFrames keyFramesV = new KeyFrames();
+
+                    if (direction == FocusEffectDirection.BottomToTop)
+                    {
+                        keyFramesV.Add(0.0f, new Property.Value(0.0f));
+                        keyFramesV.Add(focusData.KeyFrameStart, new Property.Value(0.0f));
+                    }
+                    else
+                    {
+                        keyFramesV.Add(0.0f, new Property.Value(-itemHeight));
+                        keyFramesV.Add(focusData.KeyFrameStart, new Property.Value(-itemHeight));
+                    }
+
+                    keyFramesV.Add(focusData.KeyFrameEnd, new Property.Value(-itemHeight / 2)); // animate to halfway up the control
+
+                    _animation.AnimateBetween(new Property(focusData.ImageItem, Actor.Property.POSITION_Y), keyFramesV,
+                                              new AlphaFunction(AlphaFunction.BuiltinFunction.EASE_OUT_SINE));
+                }
+
+                // Simulate the top frame growing from the sides.
+                if (focusData.Name == "top-left")
+                {
+                    KeyFrames keyFramesTL = new KeyFrames();
+
+                    keyFramesTL.Add(0.0f, new Property.Value(0.0f));
+                    keyFramesTL.Add(focusData.KeyFrameStart, new Property.Value(0.0f));
+                    keyFramesTL.Add(focusData.KeyFrameEnd, new Property.Value(itemWidth / 2)); // animate to halfway up the control
+
+                    // grow these from the left or right
+                    _animation.AnimateBetween(new Property(focusData.ImageItem, Actor.Property.POSITION_X), keyFramesTL,
+                                              new AlphaFunction(AlphaFunction.BuiltinFunction.EASE_OUT_SINE));
+                }
+
+                if (focusData.Name == "top-right")
+                {
+                    KeyFrames keyFramesTR = new KeyFrames();
+
+                    keyFramesTR.Add(0.0f, new Property.Value(0.0f));
+                    keyFramesTR.Add(focusData.KeyFrameStart, new Property.Value(0.0f));
+                    keyFramesTR.Add(focusData.KeyFrameEnd, new Property.Value(-itemWidth / 2)); // animate to halfway up the control
+
+                    // grow these from the left or right
+                    _animation.AnimateBetween(new Property(focusData.ImageItem, Actor.Property.POSITION_X), keyFramesTR,
+                                              new AlphaFunction(AlphaFunction.BuiltinFunction.EASE_OUT_SINE));
+                }
+
+                _animation.Finished += OnAnimationFinished;
+
+                _animation.Play();
+            }
+        }
+
+        private void OnAnimationFinished(object source, Animation.FinishedEventArgs e)
+        {
+            foreach (FocusData focusData in _focusData)
+            {
+                var currentParent =  focusData.ImageItem.GetParent();
+
+                if (currentParent)
+                {
+                    currentParent.Remove(focusData.ImageItem);
+                }
+            }
+        }
+    }
+}
+
diff --git a/plugins/dali-swig/examples/firstscreen/IFocusEffect.cs b/plugins/dali-swig/examples/firstscreen/IFocusEffect.cs
new file mode 100644 (file)
index 0000000..222c2ed
--- /dev/null
@@ -0,0 +1,17 @@
+using Dali;
+using System;
+
+namespace FirstScreen
+{
+    public enum FocusEffectDirection
+    {
+        TopToBottom,
+        BottomToTop
+    };
+
+    public interface IFocusEffect
+    {
+        void FocusAnimation(View parentItem, Vector3 itemSize, float duration, FocusEffectDirection direction);
+    }
+}
+
diff --git a/plugins/dali-swig/examples/firstscreen/Program.cs b/plugins/dali-swig/examples/firstscreen/Program.cs
new file mode 100644 (file)
index 0000000..d33c1f6
--- /dev/null
@@ -0,0 +1,14 @@
+using System;
+
+namespace FirstScreen
+{
+    public class MainClass
+    {
+        [STAThread]
+        static void Main(string[] args)
+        {
+            FirstScreenApp.Run();
+        }
+    }
+}
+
diff --git a/plugins/dali-swig/examples/firstscreen/ScrollContainer.cs b/plugins/dali-swig/examples/firstscreen/ScrollContainer.cs
new file mode 100644 (file)
index 0000000..633af05
--- /dev/null
@@ -0,0 +1,744 @@
+using Dali;
+using System;
+using System.Runtime.InteropServices;
+using System.Collections.Generic;
+
+
+namespace FirstScreen
+{
+    public class ScrollContainer
+    {
+        private View _container;
+        private Actor _itemRoot;
+        private Vector3 _itemSize;
+        private List<View> _itemList;
+        private int _itemCount;
+        private int _focusedItem;
+        private PanGestureDetector _panGestureDetector;
+        private float _scrollDisplacement;
+        private float _currentScrollPosition;
+        private float _padding;
+        private float _width;
+        private float _height;
+        private bool _isFocused;
+        private float _marginX;
+        private float _marginY;
+        private float _offsetY;
+        private float _offsetX;
+        private Stage _stage;
+        private Vector2 _stageSize;
+        private ImageView _shadowBorder;
+        private ImageView _spotLight;
+        private Animation _spotLightAnimation;
+        private Animation _showAnimation;
+        private Animation _hideAnimation;
+        private Animation _focusAnimation;
+        private Animation _scrollAnimation;
+        private Animation _focusTransitionAnimation;
+        private Path _circularPath;
+        private bool _shouldHide;
+
+        public ScrollContainer()
+        {
+            _itemSize = new Vector3(0.0f, 0.0f, 0.0f);
+            _padding = 0.0f;
+            _width = 0.0f;
+            _height = 0.0f;
+            _currentScrollPosition = 0.0f;
+            _itemCount = 0;
+            _focusedItem = -1;
+            _isFocused = false;
+            _marginX = 50.0f;
+            _marginY = 0.0f;
+            _offsetY = 0.0f;
+            _offsetX = 0.0f;
+
+            _shouldHide = true;
+
+            _container = new View();
+            _itemRoot = new Actor();
+            _container.Add(_itemRoot);
+
+            _itemList = new List<View>();
+
+            if (_panGestureDetector == null)
+            {
+                _panGestureDetector = new PanGestureDetector();
+                _panGestureDetector.Attach(_container);
+
+                _panGestureDetector.Detected += OnPan;
+            }
+
+            _container.ParentOrigin = NDalic.ParentOriginTopLeft;
+            _container.AnchorPoint = NDalic.AnchorPointTopLeft;
+            _itemRoot.ParentOrigin = NDalic.ParentOriginTopLeft;
+            _itemRoot.AnchorPoint = NDalic.AnchorPointTopLeft;
+
+            _container.WidthResizePolicy = "FILL_TO_PARENT";
+            _container.HeightResizePolicy = "FILL_TO_PARENT";
+            _itemRoot.WidthResizePolicy = "FILL_TO_PARENT";
+            _itemRoot.HeightResizePolicy = "FILL_TO_PARENT";
+
+            _stage = Stage.GetCurrent();
+            _stageSize = _stage.GetSize();
+
+            _spotLightAnimation = new Animation(5.0f);
+            _focusTransitionAnimation = new Animation (0.35f);
+            _focusAnimation = new Animation (0.35f);
+            _focusAnimation.SetEndAction(Animation.EndAction.BakeFinal);
+            _scrollAnimation = new Animation (0.35f);
+            _scrollAnimation.SetEndAction(Animation.EndAction.BakeFinal);
+        }
+
+        public bool IsFocused
+        {
+            get
+            {
+                return _isFocused;
+            }
+        }
+
+        public Dali.View Container
+        {
+            get
+            {
+                return _container;
+            }
+        }
+
+        public int ItemCount
+        {
+            get
+            {
+                return _itemCount;
+            }
+        }
+
+        public Actor ItemRoot
+        {
+            get
+            {
+                return _itemRoot;
+            }
+        }
+
+        public Vector3 ItemSize
+        {
+            get
+            {
+                return _itemSize;
+            }
+
+            set
+            {
+                _itemSize = value;
+
+                Vector3 topLeft = new Vector3(-0.25f * _itemSize.width, -0.25f * _itemSize.height, 0.0f);
+                Vector3 topRight = new Vector3(0.25f * _itemSize.width, -0.25f * _itemSize.height, 0.0f);
+                Vector3 bottomRight = new Vector3(0.25f * _itemSize.width, 0.25f * _itemSize.height, 0.0f);
+                Vector3 bottomLeft = new Vector3(-0.25f * _itemSize.width, 0.25f * _itemSize.height, 0.0f);
+
+                _circularPath = new Path();
+                _circularPath.AddPoint(topLeft);
+                _circularPath.AddPoint(topRight);
+                _circularPath.AddPoint(bottomRight);
+                _circularPath.AddPoint(bottomLeft);
+                _circularPath.AddPoint(topLeft);
+                _circularPath.GenerateControlPoints(0.5f);
+            }
+        }
+
+        public float Padding
+        {
+            get
+            {
+                return _padding;
+            }
+
+            set
+            {
+                _padding = value;
+            }
+        }
+
+        public float MarginX
+        {
+            get
+            {
+                return _marginX;
+            }
+
+            set
+            {
+                _marginX = value;
+            }
+        }
+
+        public float OffsetY
+        {
+            get
+            {
+                return _offsetY;
+            }
+
+            set
+            {
+                _offsetY = value;
+            }
+        }
+
+        public float OffsetX
+        {
+            get
+            {
+                return _offsetX;
+            }
+
+            set
+            {
+                _offsetX = value;
+            }
+        }
+
+        public float MarginY
+        {
+            get
+            {
+                return _marginY;
+            }
+
+            set
+            {
+                _marginY = value;
+            }
+        }
+
+        public float Width
+        {
+            get
+            {
+                return _width;
+            }
+
+            set
+            {
+                _width = value;
+            }
+        }
+
+        public float Height
+        {
+            get
+            {
+                return _height;
+            }
+
+            set
+            {
+                _height = value;
+            }
+        }
+
+        public ImageView ShadowBorder
+        {
+            get
+            {
+                return _shadowBorder;
+            }
+
+            set
+            {
+                _shadowBorder = value;
+            }
+        }
+
+        public ImageView SpotLight
+        {
+            get
+            {
+                return _spotLight;
+            }
+
+            set
+            {
+                _spotLight = value;
+            }
+        }
+
+        public int FocusedItemID
+        {
+            get
+            {
+                if (_focusedItem < 0)
+                {
+                    _focusedItem = 0;
+                }
+
+                return _focusedItem;
+            }
+        }
+
+        public Actor GetCurrentFocusedActor()
+        {
+            if (_focusedItem < 0)
+            {
+                _focusedItem = 0;
+            }
+
+            return _itemList[_focusedItem];
+        }
+
+        public void AddItem(View item)
+        {
+            item.AnchorPoint = NDalic.AnchorPointBottomCenter;
+            item.ParentOrigin = NDalic.ParentOriginBottomCenter;
+
+            item.Size = _itemSize;
+            item.SetKeyboardFocusable(true);
+            item.Position = GetItemPosition(_itemCount, _currentScrollPosition);
+
+            item.Name = _itemCount.ToString();
+
+//          item.ClippingMode = "CLIP_CHILDREN";
+
+            _itemRoot.Add(item);
+            _itemList.Add(item);
+            _panGestureDetector.Attach(item);
+            _itemCount++;
+        }
+
+        // Perform Show animation on ScrollContainer (used only for Poster Container)
+        public void Show()
+        {
+            Container.Add(ItemRoot);
+
+            _shouldHide = false;
+            _showAnimation = new Animation (0.35f);
+
+            _showAnimation.AnimateTo(new Property(_container, Actor.Property.COLOR_ALPHA), new Property.Value(1.0f));
+
+            _container.PositionY = _container.Position.y + 200.0f;
+            float targetPositionY = _container.Position.y - 200.0f;
+            _showAnimation.AnimateTo(new Property(_container, Actor.Property.POSITION_Y), new Property.Value(targetPositionY),
+                                     new AlphaFunction(AlphaFunction.BuiltinFunction.LINEAR));
+
+            _showAnimation.Play();
+        }
+
+        // Perform Hide animation on ScrollContainer (used only for Poster Container)
+        public void Hide()
+        {
+            if (_hideAnimation)
+            {
+                _hideAnimation.Clear();
+                _hideAnimation.Reset();
+            }
+
+            float duration = 0.35f;
+            _hideAnimation = new Animation(duration);
+
+            _hideAnimation.AnimateTo(new Property(_container, Actor.Property.COLOR_ALPHA), new Property.Value(0.0f),
+                                     new AlphaFunction(AlphaFunction.BuiltinFunction.LINEAR), new TimePeriod(0.0f, duration * 0.75f));
+
+            _hideAnimation.Finished += OnHideAnimationFinished;
+
+            _shouldHide = true;
+            _hideAnimation.Play();
+        }
+
+        public View Focus(int itemId)
+        {
+            if (itemId < 0)
+            {
+                itemId = 0;
+            }
+            else if (itemId >= _itemList.Count)
+            {
+                itemId = _itemList.Count - 1;
+            }
+
+            _itemList[itemId].Add(_shadowBorder);
+            _itemList[itemId].Add(_spotLight);
+
+            // Perform Spot Light animation
+            if(_focusedItem != itemId && _spotLight != null)
+            {
+                _spotLightAnimation.Clear();
+                _spotLightAnimation.Animate( _spotLight, _circularPath, new Vector3(0.0f, 0.0f, 0.0f) );
+                _spotLightAnimation.SetLooping(true);
+                _spotLightAnimation.Play();
+            }
+
+            _focusedItem = itemId;
+
+            Vector3 itemPosition = GetItemPosition(_focusedItem, _currentScrollPosition);
+
+            _focusAnimation.Clear();
+
+            float relativeItemPositionX = itemPosition.x - _itemSize.width * 0.5f + (_stageSize.width * 0.5f) + _offsetX;
+            if (relativeItemPositionX < _marginX + _offsetX + _padding)
+            {
+                float amount = _marginX + _offsetX + _padding - relativeItemPositionX;
+                Scroll(amount, itemId + 1); // Perform Scroll animation
+            }
+            else if (relativeItemPositionX + _itemSize.width + _padding + _marginX > _stageSize.width)
+            {
+                float amount = relativeItemPositionX + _marginX + _padding + _itemSize.width - _stageSize.width;
+                Scroll(-amount, itemId - 1); // Perform Scroll animation
+            }
+            else
+            {
+                for (int i = 0; i < _itemList.Count; ++i)
+                {
+                    Vector3 targetPosition = GetItemPosition(i, _currentScrollPosition);
+                    _focusAnimation.AnimateTo(new Property(_itemList[i], Actor.Property.POSITION),
+                                              new Property.Value(targetPosition),
+                                              new AlphaFunction(AlphaFunction.BuiltinFunction.EASE_OUT_SINE));
+                }
+            }
+
+            for (int i = 0; i < _itemList.Count; ++i)
+            {
+                SetupItemRenderer(_itemList[i], false);
+
+                // Perform Focus animation
+                if (i == _focusedItem)
+                {
+                    _focusAnimation.AnimateTo(new Property(_itemList[i], Actor.Property.SCALE),
+                                              new Property.Value(new Vector3(1.2f, 1.2f, 1.2f)),
+                                              new AlphaFunction(AlphaFunction.BuiltinFunction.EASE_OUT_SINE));
+                }
+                else
+                {
+                    _focusAnimation.AnimateTo(new Property(_itemList[i], Actor.Property.SCALE),
+                                              new Property.Value(new Vector3(1.0f, 1.0f, 1.0f)),
+                                              new AlphaFunction(AlphaFunction.BuiltinFunction.EASE_OUT_SINE));
+                }
+            }
+
+            _focusAnimation.Play();
+
+            if (_isFocused && _focusedItem >= 0)
+            {
+                SetupItemRenderer(_itemList[_focusedItem], true);
+                SetupSpotLightRenderer();
+            }
+
+            return _itemList[_focusedItem];
+        }
+
+        // Perform EddenEffect animation on Focused Item specified
+        public void FocusAnimation(FocusEffect focusEffect, FocusEffectDirection direction)
+        {
+            focusEffect.FocusAnimation(_itemList[_focusedItem], _itemSize, 1.0f, direction);
+        }
+
+        public void SetFocused(bool focused)
+        {
+            _isFocused = focused;
+
+            // Perform Focus animation if the ScrollContainer is not focused already
+            if (!_isFocused)
+            {
+                Actor parent = _shadowBorder.GetParent();
+                if (parent)
+                {
+                    parent.Remove(_shadowBorder);
+                }
+
+                parent = _spotLight.GetParent();
+                if (parent)
+                {
+                    parent.Remove(_spotLight);
+                }
+
+                _focusTransitionAnimation.Clear();
+
+                for (int i = 0; i < _itemList.Count; ++i)
+                {
+                    SetupItemRenderer(_itemList[i], false);
+
+                    Vector3 targetPosition = GetItemPosition(i, _currentScrollPosition);
+                    _focusTransitionAnimation.AnimateTo(new Property(_itemList[i], Actor.Property.POSITION),
+                                                        new Property.Value(targetPosition),
+                                                        new AlphaFunction(AlphaFunction.BuiltinFunction.EASE_OUT_SINE));
+
+                    _focusTransitionAnimation.AnimateTo(new Property(_itemList[i], Actor.Property.SCALE),
+                                                        new Property.Value(new Vector3(1.0f, 1.0f, 1.0f)),
+                                                        new AlphaFunction(AlphaFunction.BuiltinFunction.EASE_OUT_SINE));
+                }
+
+                _focusTransitionAnimation.Play();
+            }
+            else
+            {
+                Focus(_focusedItem);
+            }
+        }
+
+        // Obtain ID of first visible item/image on the screen of the ScrollContainer
+        public int GetFirstVisibleItemId()
+        {
+            int firstItemId = -1;
+
+            if (_isFocused)
+            {
+                firstItemId = (int)Math.Floor((-1.0 * _currentScrollPosition + _marginX * 2.0f) / (_itemSize.x + _padding));
+            }
+            else
+            {
+                firstItemId = (int)Math.Floor(-1.0 * _currentScrollPosition / (_itemSize.x + _padding));
+            }
+
+            if (firstItemId < 0)
+            {
+                firstItemId = 0;
+            }
+
+            return firstItemId;
+        }
+
+        // Obtain ID of last visible item/image on the screen of the ScrollContainer
+        public int GetLastVisibleItemId()
+        {
+            int lastItemId = -1;
+
+            if (_isFocused)
+            {
+                lastItemId = (int)Math.Ceiling(((_width - _currentScrollPosition - _marginX * 2.0f) / _itemSize.x) - 1);
+            }
+            else
+            {
+                lastItemId = (int)Math.Ceiling(((_width - _currentScrollPosition) / _itemSize.x) - 1);
+            }
+
+            if (lastItemId >= _itemList.Count)
+            {
+
+                lastItemId = _itemList.Count - 1;
+            }
+
+            return lastItemId;
+        }
+
+        // Obtain Next item/image (Right of the currently focused item) of the ScrollContainer
+        public Actor FocusNext()
+        {
+            int nextItem = -1;
+
+            if (_focusedItem < GetFirstVisibleItemId() || _focusedItem > GetLastVisibleItemId())
+            {
+                nextItem = GetFirstVisibleItemId();
+            }
+            else
+            {
+                nextItem = _focusedItem + 1;
+            }
+
+            return Focus(nextItem);
+        }
+
+        // Obtain Previous item/image (left of the currently focused item) of the ScrollContainer
+        public Actor FocusPrevious()
+        {
+            int previousItem = -1;
+
+            if (_focusedItem < GetFirstVisibleItemId() || _focusedItem > GetLastVisibleItemId())
+            {
+                previousItem = GetFirstVisibleItemId();
+            }
+            else
+            {
+                previousItem = _focusedItem - 1;
+            }
+
+            return Focus(previousItem);
+        }
+
+        private void OnHideAnimationFinished(object source, Animation.FinishedEventArgs e)
+        {
+            var currentParent =  ItemRoot.GetParent();
+            if (_shouldHide && currentParent != null)
+            {
+                Container.Remove(ItemRoot);
+            }
+        }
+
+        private void OnPan(object source, PanGestureDetector.DetectedEventArgs e)
+        {
+            switch (e.PanGesture.state)
+            {
+            case Gesture.State.Started:
+                _scrollDisplacement = 0.0f;
+                break;
+
+            case Gesture.State.Continuing:
+                _scrollDisplacement = e.PanGesture.displacement.x;
+                break;
+
+            case Gesture.State.Finished:
+            case Gesture.State.Cancelled:
+                float absScrollDistance = _scrollDisplacement;
+                if (absScrollDistance < 0.0f)
+                    absScrollDistance = 0.0f - absScrollDistance;
+
+                float scrollSpeed = e.PanGesture.velocity.x * e.PanGesture.velocity.x + e.PanGesture.velocity.y * e.PanGesture.velocity.y;
+                float maxScrollSpeed = 40.0f;  // TBD
+                if (scrollSpeed > maxScrollSpeed)
+                    scrollSpeed = maxScrollSpeed;
+
+                if (absScrollDistance > 1.0f && scrollSpeed > 0.05f) // Threshold TBD
+                {
+                    if (_scrollDisplacement > 0.0f) // scroll constant distance in constant speed.
+                    {
+                        Scroll((_itemSize.x + _padding) * 2, GetFirstVisibleItemId());
+                    }
+                    else
+                    {
+                        Scroll(-(_itemSize.x + _padding) * 2, GetFirstVisibleItemId());
+                    }
+                }
+                break;
+            }
+        }
+
+        // Perform ScrollAnimation on each item
+        private void Scroll(float amount, int baseItem)
+        {
+            float tagetScrollPosition = _currentScrollPosition + amount;
+            float totalItemSize = _itemList.Count * (_itemSize.width + _padding) + _padding + (_marginX * 2.0f);
+
+            float maxScrollPosition = _width - totalItemSize;
+
+            if (tagetScrollPosition < maxScrollPosition)
+            {
+                tagetScrollPosition = maxScrollPosition;
+            }
+            if (tagetScrollPosition > 0.0f)
+            {
+                tagetScrollPosition = 0.0f;
+            }
+
+            _scrollAnimation.Clear();
+
+            for (int i = 0; i < _itemList.Count; ++i)
+            {
+                Vector3 targetPosition = GetItemPosition(i, tagetScrollPosition);
+                _scrollAnimation.AnimateTo(new Property(_itemList[i], Actor.Property.POSITION),
+                                           new Property.Value(targetPosition),
+                                           new AlphaFunction(AlphaFunction.BuiltinFunction.EASE_OUT_SINE));
+            }
+
+            _currentScrollPosition = tagetScrollPosition;
+            _scrollAnimation.Play();
+        }
+
+        // Calculate Position of any item/image of ScrollContainer
+        private Vector3 GetItemPosition(int itemId, float scrollPosition)
+        {
+            if (_isFocused)
+            {
+                // used (_itemSize.width * 0.5f) because of AnchorPointCenter
+                // used (_stageSize.width * 0.5f) because of ParentOriginCenter
+                if (_focusedItem > itemId)
+                {
+                    float positionX = (_itemSize.width * itemId) + (_padding * (itemId + 1)) + scrollPosition + (_itemSize.width * 0.5f) - (_stageSize.width * 0.5f);
+                    return new Vector3(positionX, -_itemSize.height * _offsetY, 0.0f);
+                }
+                else if (_focusedItem == itemId)
+                {
+                    float positionX = (_itemSize.width * itemId) + (_padding * (itemId + 1)) + scrollPosition + _marginX + (_itemSize.width * 0.5f) - (_stageSize.width * 0.5f);
+                    return new Vector3(positionX, -_itemSize.height * _offsetY, 0.0f);
+                }
+                else
+                {
+                    float positionX = (_itemSize.width * itemId) + (_padding * (itemId + 1)) + scrollPosition + _marginX * 2.0f + (_itemSize.width * 0.5f) - (_stageSize.width * 0.5f);
+                    return new Vector3(positionX, -_itemSize.height * _offsetY, 0.0f);
+                }
+            }
+            else
+            {
+                float positionX = (_itemSize.width * itemId) + (_padding * (itemId + 1)) + scrollPosition + (_itemSize.width * 0.5f) - (_stageSize.width * 0.5f);
+                return new Vector3(positionX, -_itemSize.height * _offsetY, 0.0f);
+            }
+        }
+
+        // Used for SpotLight animation with clipping
+        private void SetupItemRenderer(Actor actor, bool stencilOn)
+        {
+            if (actor)
+            {
+                Renderer renderer = actor.GetRendererAt(0);
+
+                if (renderer)
+                {
+                    // Setup the renderer properties:
+                    // The stencil plane is only for stencilling, so disable writing to color buffer.
+
+                    // Enable stencil. Draw to the stencil buffer (only).
+                    if (stencilOn)
+                    {
+                        renderer.RenderMode = (int)RenderModeType.COLOR_STENCIL;
+                    }
+                    else
+                    {
+                        renderer.RenderMode = (int)RenderModeType.COLOR;
+                    }
+                    renderer.StencilFunction = (int)StencilFunctionType.ALWAYS;
+                    renderer.StencilFunctionReference = 1;
+                    renderer.StencilFunctionMask = 0xFF;
+                    renderer.StencilOperationOnFail = (int)StencilOperationType.KEEP;
+                    renderer.StencilOperationOnZFail = (int)StencilOperationType.KEEP;
+                    renderer.StencilOperationOnZPass = (int)StencilOperationType.REPLACE;
+                    renderer.StencilMask = 0xFF;
+
+                    // We don't want to write to the depth buffer.
+                    renderer.DepthWriteMode = (int)DepthWriteModeType.OFF;
+                    // We don't beed to test the depth buffer.
+                    renderer.DepthTestMode = (int)DepthTestModeType.OFF;
+
+                    // This object must be rendered 1st.
+                    renderer.DepthIndex = 10;
+                }
+            }
+        }
+
+        // Used for SpotLight animation with clipping
+        private void SetupSpotLightRenderer()
+        {
+            if (_spotLight)
+            {
+                Renderer renderer = _spotLight.GetRendererAt(0);
+
+                if (renderer)
+                {
+                    // Setup the renderer properties:
+                    // Write to color buffer so soptlight is visible
+
+                    // We use blending to blend the spotlight with the poster image.
+                    renderer.BlendMode = (int)BlendModeType.ON;
+                    renderer.BlendEquationRgb = (int)BlendEquationType.ADD;
+                    renderer.BlendEquationAlpha = (int)BlendEquationType.ADD;
+                    renderer.BlendFactorDestRgb = (int)BlendFactorType.ONE;
+
+                    // Enable stencil. Here we only draw to areas within the stencil.
+                    renderer.RenderMode = (int)RenderModeType.COLOR_STENCIL;
+                    renderer.StencilFunction = (int)StencilFunctionType.EQUAL;
+                    renderer.StencilFunctionReference = 1;
+                    renderer.StencilFunctionMask = 0xFF;
+                    // Don't write to the stencil.
+                    renderer.StencilMask = 0x00;
+
+                    // We don't need to write to the depth buffer.
+                    renderer.DepthWriteMode = (int)DepthWriteModeType.OFF;
+                    // We don't need to test the depth buffer.
+                    renderer.DepthTestMode = (int)DepthTestModeType.OFF;
+
+                    // This object must be rendered last.
+                    renderer.DepthIndex = 20;
+                }
+            }
+        }
+    }
+}
+
diff --git a/plugins/dali-swig/examples/firstscreen/images/0-normal.png b/plugins/dali-swig/examples/firstscreen/images/0-normal.png
new file mode 100644 (file)
index 0000000..ee755c3
Binary files /dev/null and b/plugins/dali-swig/examples/firstscreen/images/0-normal.png differ
diff --git a/plugins/dali-swig/examples/firstscreen/images/1-normal.png b/plugins/dali-swig/examples/firstscreen/images/1-normal.png
new file mode 100644 (file)
index 0000000..432bf7f
Binary files /dev/null and b/plugins/dali-swig/examples/firstscreen/images/1-normal.png differ
diff --git a/plugins/dali-swig/examples/firstscreen/images/2-normal.png b/plugins/dali-swig/examples/firstscreen/images/2-normal.png
new file mode 100644 (file)
index 0000000..c921918
Binary files /dev/null and b/plugins/dali-swig/examples/firstscreen/images/2-normal.png differ
diff --git a/plugins/dali-swig/examples/firstscreen/images/background.png b/plugins/dali-swig/examples/firstscreen/images/background.png
new file mode 100644 (file)
index 0000000..7e4caad
Binary files /dev/null and b/plugins/dali-swig/examples/firstscreen/images/background.png differ
diff --git a/plugins/dali-swig/examples/firstscreen/images/focus_grid.9.png b/plugins/dali-swig/examples/firstscreen/images/focus_grid.9.png
new file mode 100644 (file)
index 0000000..04ccb1f
Binary files /dev/null and b/plugins/dali-swig/examples/firstscreen/images/focus_grid.9.png differ
diff --git a/plugins/dali-swig/examples/firstscreen/images/focus_launcher_shadow.9.png b/plugins/dali-swig/examples/firstscreen/images/focus_launcher_shadow.9.png
new file mode 100644 (file)
index 0000000..f989071
Binary files /dev/null and b/plugins/dali-swig/examples/firstscreen/images/focus_launcher_shadow.9.png differ
diff --git a/plugins/dali-swig/examples/firstscreen/images/focus_launcher_shadow_n.png b/plugins/dali-swig/examples/firstscreen/images/focus_launcher_shadow_n.png
new file mode 100644 (file)
index 0000000..0805e9e
Binary files /dev/null and b/plugins/dali-swig/examples/firstscreen/images/focus_launcher_shadow_n.png differ
diff --git a/plugins/dali-swig/examples/firstscreen/images/focuseffect/halo.png b/plugins/dali-swig/examples/firstscreen/images/focuseffect/halo.png
new file mode 100644 (file)
index 0000000..307f67e
Binary files /dev/null and b/plugins/dali-swig/examples/firstscreen/images/focuseffect/halo.png differ
diff --git a/plugins/dali-swig/examples/firstscreen/images/focuseffect/horizontalFrame.png b/plugins/dali-swig/examples/firstscreen/images/focuseffect/horizontalFrame.png
new file mode 100644 (file)
index 0000000..abff4ec
Binary files /dev/null and b/plugins/dali-swig/examples/firstscreen/images/focuseffect/horizontalFrame.png differ
diff --git a/plugins/dali-swig/examples/firstscreen/images/focuseffect/verticalFrame.png b/plugins/dali-swig/examples/firstscreen/images/focuseffect/verticalFrame.png
new file mode 100644 (file)
index 0000000..bdd372d
Binary files /dev/null and b/plugins/dali-swig/examples/firstscreen/images/focuseffect/verticalFrame.png differ
diff --git a/plugins/dali-swig/examples/firstscreen/images/highlight_spot.png b/plugins/dali-swig/examples/firstscreen/images/highlight_spot.png
new file mode 100644 (file)
index 0000000..8caa716
Binary files /dev/null and b/plugins/dali-swig/examples/firstscreen/images/highlight_spot.png differ
diff --git a/plugins/dali-swig/examples/firstscreen/images/highlight_stroke.9.png b/plugins/dali-swig/examples/firstscreen/images/highlight_stroke.9.png
new file mode 100644 (file)
index 0000000..493b206
Binary files /dev/null and b/plugins/dali-swig/examples/firstscreen/images/highlight_stroke.9.png differ
diff --git a/plugins/dali-swig/examples/firstscreen/images/menu/0.png b/plugins/dali-swig/examples/firstscreen/images/menu/0.png
new file mode 100644 (file)
index 0000000..cf1135c
Binary files /dev/null and b/plugins/dali-swig/examples/firstscreen/images/menu/0.png differ
diff --git a/plugins/dali-swig/examples/firstscreen/images/menu/1.png b/plugins/dali-swig/examples/firstscreen/images/menu/1.png
new file mode 100644 (file)
index 0000000..16d48e7
Binary files /dev/null and b/plugins/dali-swig/examples/firstscreen/images/menu/1.png differ
diff --git a/plugins/dali-swig/examples/firstscreen/images/menu/2.png b/plugins/dali-swig/examples/firstscreen/images/menu/2.png
new file mode 100644 (file)
index 0000000..bf7f1e8
Binary files /dev/null and b/plugins/dali-swig/examples/firstscreen/images/menu/2.png differ
diff --git a/plugins/dali-swig/examples/firstscreen/images/menu/3.png b/plugins/dali-swig/examples/firstscreen/images/menu/3.png
new file mode 100644 (file)
index 0000000..ba40892
Binary files /dev/null and b/plugins/dali-swig/examples/firstscreen/images/menu/3.png differ
diff --git a/plugins/dali-swig/examples/firstscreen/images/menu/4.png b/plugins/dali-swig/examples/firstscreen/images/menu/4.png
new file mode 100644 (file)
index 0000000..ad580d8
Binary files /dev/null and b/plugins/dali-swig/examples/firstscreen/images/menu/4.png differ
diff --git a/plugins/dali-swig/examples/firstscreen/images/menu/5.png b/plugins/dali-swig/examples/firstscreen/images/menu/5.png
new file mode 100644 (file)
index 0000000..599147c
Binary files /dev/null and b/plugins/dali-swig/examples/firstscreen/images/menu/5.png differ
diff --git a/plugins/dali-swig/examples/firstscreen/images/menu/6.png b/plugins/dali-swig/examples/firstscreen/images/menu/6.png
new file mode 100644 (file)
index 0000000..5f215f6
Binary files /dev/null and b/plugins/dali-swig/examples/firstscreen/images/menu/6.png differ
diff --git a/plugins/dali-swig/examples/firstscreen/images/poster0/0.jpg b/plugins/dali-swig/examples/firstscreen/images/poster0/0.jpg
new file mode 100644 (file)
index 0000000..5b234db
Binary files /dev/null and b/plugins/dali-swig/examples/firstscreen/images/poster0/0.jpg differ
diff --git a/plugins/dali-swig/examples/firstscreen/images/poster0/1.jpg b/plugins/dali-swig/examples/firstscreen/images/poster0/1.jpg
new file mode 100644 (file)
index 0000000..f999f55
Binary files /dev/null and b/plugins/dali-swig/examples/firstscreen/images/poster0/1.jpg differ
diff --git a/plugins/dali-swig/examples/firstscreen/images/poster0/10.jpg b/plugins/dali-swig/examples/firstscreen/images/poster0/10.jpg
new file mode 100644 (file)
index 0000000..e8be482
Binary files /dev/null and b/plugins/dali-swig/examples/firstscreen/images/poster0/10.jpg differ
diff --git a/plugins/dali-swig/examples/firstscreen/images/poster0/11.jpg b/plugins/dali-swig/examples/firstscreen/images/poster0/11.jpg
new file mode 100644 (file)
index 0000000..2b97815
Binary files /dev/null and b/plugins/dali-swig/examples/firstscreen/images/poster0/11.jpg differ
diff --git a/plugins/dali-swig/examples/firstscreen/images/poster0/12.jpg b/plugins/dali-swig/examples/firstscreen/images/poster0/12.jpg
new file mode 100644 (file)
index 0000000..8b7bda9
Binary files /dev/null and b/plugins/dali-swig/examples/firstscreen/images/poster0/12.jpg differ
diff --git a/plugins/dali-swig/examples/firstscreen/images/poster0/13.jpg b/plugins/dali-swig/examples/firstscreen/images/poster0/13.jpg
new file mode 100644 (file)
index 0000000..ba8d61a
Binary files /dev/null and b/plugins/dali-swig/examples/firstscreen/images/poster0/13.jpg differ
diff --git a/plugins/dali-swig/examples/firstscreen/images/poster0/2.jpg b/plugins/dali-swig/examples/firstscreen/images/poster0/2.jpg
new file mode 100644 (file)
index 0000000..dba62e1
Binary files /dev/null and b/plugins/dali-swig/examples/firstscreen/images/poster0/2.jpg differ
diff --git a/plugins/dali-swig/examples/firstscreen/images/poster0/3.jpg b/plugins/dali-swig/examples/firstscreen/images/poster0/3.jpg
new file mode 100644 (file)
index 0000000..bd74752
Binary files /dev/null and b/plugins/dali-swig/examples/firstscreen/images/poster0/3.jpg differ
diff --git a/plugins/dali-swig/examples/firstscreen/images/poster0/4.jpg b/plugins/dali-swig/examples/firstscreen/images/poster0/4.jpg
new file mode 100644 (file)
index 0000000..13581f8
Binary files /dev/null and b/plugins/dali-swig/examples/firstscreen/images/poster0/4.jpg differ
diff --git a/plugins/dali-swig/examples/firstscreen/images/poster0/5.jpg b/plugins/dali-swig/examples/firstscreen/images/poster0/5.jpg
new file mode 100644 (file)
index 0000000..7526f22
Binary files /dev/null and b/plugins/dali-swig/examples/firstscreen/images/poster0/5.jpg differ
diff --git a/plugins/dali-swig/examples/firstscreen/images/poster0/6.jpg b/plugins/dali-swig/examples/firstscreen/images/poster0/6.jpg
new file mode 100644 (file)
index 0000000..3882771
Binary files /dev/null and b/plugins/dali-swig/examples/firstscreen/images/poster0/6.jpg differ
diff --git a/plugins/dali-swig/examples/firstscreen/images/poster0/7.jpg b/plugins/dali-swig/examples/firstscreen/images/poster0/7.jpg
new file mode 100644 (file)
index 0000000..7a0844b
Binary files /dev/null and b/plugins/dali-swig/examples/firstscreen/images/poster0/7.jpg differ
diff --git a/plugins/dali-swig/examples/firstscreen/images/poster0/8.jpg b/plugins/dali-swig/examples/firstscreen/images/poster0/8.jpg
new file mode 100644 (file)
index 0000000..4798052
Binary files /dev/null and b/plugins/dali-swig/examples/firstscreen/images/poster0/8.jpg differ
diff --git a/plugins/dali-swig/examples/firstscreen/images/poster0/9.jpg b/plugins/dali-swig/examples/firstscreen/images/poster0/9.jpg
new file mode 100644 (file)
index 0000000..5f160b3
Binary files /dev/null and b/plugins/dali-swig/examples/firstscreen/images/poster0/9.jpg differ
diff --git a/plugins/dali-swig/examples/firstscreen/images/poster1/0.jpg b/plugins/dali-swig/examples/firstscreen/images/poster1/0.jpg
new file mode 100644 (file)
index 0000000..1d4b86b
Binary files /dev/null and b/plugins/dali-swig/examples/firstscreen/images/poster1/0.jpg differ
diff --git a/plugins/dali-swig/examples/firstscreen/images/poster1/1.jpg b/plugins/dali-swig/examples/firstscreen/images/poster1/1.jpg
new file mode 100644 (file)
index 0000000..f95670d
Binary files /dev/null and b/plugins/dali-swig/examples/firstscreen/images/poster1/1.jpg differ
diff --git a/plugins/dali-swig/examples/firstscreen/images/poster1/2.jpg b/plugins/dali-swig/examples/firstscreen/images/poster1/2.jpg
new file mode 100644 (file)
index 0000000..f4c0246
Binary files /dev/null and b/plugins/dali-swig/examples/firstscreen/images/poster1/2.jpg differ
diff --git a/plugins/dali-swig/examples/firstscreen/images/poster1/3.jpg b/plugins/dali-swig/examples/firstscreen/images/poster1/3.jpg
new file mode 100644 (file)
index 0000000..49acd6a
Binary files /dev/null and b/plugins/dali-swig/examples/firstscreen/images/poster1/3.jpg differ
diff --git a/plugins/dali-swig/examples/firstscreen/images/poster1/4.jpg b/plugins/dali-swig/examples/firstscreen/images/poster1/4.jpg
new file mode 100644 (file)
index 0000000..cb11761
Binary files /dev/null and b/plugins/dali-swig/examples/firstscreen/images/poster1/4.jpg differ
diff --git a/plugins/dali-swig/examples/firstscreen/images/poster1/5.jpg b/plugins/dali-swig/examples/firstscreen/images/poster1/5.jpg
new file mode 100644 (file)
index 0000000..eba0c14
Binary files /dev/null and b/plugins/dali-swig/examples/firstscreen/images/poster1/5.jpg differ
diff --git a/plugins/dali-swig/examples/firstscreen/images/star-dim.png b/plugins/dali-swig/examples/firstscreen/images/star-dim.png
new file mode 100644 (file)
index 0000000..38cc674
Binary files /dev/null and b/plugins/dali-swig/examples/firstscreen/images/star-dim.png differ
diff --git a/plugins/dali-swig/examples/firstscreen/images/star-highlight.png b/plugins/dali-swig/examples/firstscreen/images/star-highlight.png
new file mode 100644 (file)
index 0000000..f99ee25
Binary files /dev/null and b/plugins/dali-swig/examples/firstscreen/images/star-highlight.png differ
diff --git a/plugins/dali-swig/examples/firstscreen/images/thumbnail_shadow.9.png b/plugins/dali-swig/examples/firstscreen/images/thumbnail_shadow.9.png
new file mode 100644 (file)
index 0000000..61f5a99
Binary files /dev/null and b/plugins/dali-swig/examples/firstscreen/images/thumbnail_shadow.9.png differ
diff --git a/plugins/dali-swig/examples/firstscreen/images/white-pixel.png b/plugins/dali-swig/examples/firstscreen/images/white-pixel.png
new file mode 100644 (file)
index 0000000..c63f333
Binary files /dev/null and b/plugins/dali-swig/examples/firstscreen/images/white-pixel.png differ
index 28fd1dd..1d35bc1 100755 (executable)
@@ -85,8 +85,9 @@ namespace MyCSharpExample
 
                 _animation = new Animation(1.0f); // 1 second of duration
 
-                _animation.AnimateTo(new Property(_text, Actor.Property.ORIENTATION), new Property.Value(new Quaternion( new Radian( new Degree( 180.0f ) ), Vector3.XAXIS )), new AlphaFunction(AlphaFunction.BuiltinFunction.LINEAR), new TimePeriod(0.0f, 0.5f));
-                _animation.AnimateTo(new Property(_text, Actor.Property.ORIENTATION), new Property.Value(new Quaternion( new Radian( new Degree( 0.0f ) ), Vector3.XAXIS )), new AlphaFunction(AlphaFunction.BuiltinFunction.LINEAR), new TimePeriod(0.5f, 0.5f));
+               _animation.AnimateTo(_text, Animation.ORIENTATION, new Quaternion( new Radian( new Degree( 180.0f ) ), Vector3.XAXIS ), new AlphaFunction(AlphaFunction.BuiltinFunction.LINEAR), new TimePeriod(0.0f, 0.5f));
+
+               _animation.AnimateTo(_text, Animation.ORIENTATION, new Quaternion( new Radian( new Degree( 0.0f ) ), Vector3.XAXIS ), new AlphaFunction(AlphaFunction.BuiltinFunction.LINEAR), new TimePeriod(0.5f, 0.5f));
 
                 // Connect the signal callback for animaiton finished signal
                 _animation.Finished += AnimationFinished;
index 1f3fc62..e548f61 100755 (executable)
@@ -26,13 +26,28 @@ $typeTable =  [
         ["ARRAY",       "Dali.Property.Array",   "",     "Dali.Property.Array temp = new Dali.Property.Array();"],
         ["MAP",         "Dali.Property.Map",     "",     "Dali.Property.Map temp = new Dali.Property.Map();"],
     ]
+
+# Some csharp classes are renamed ( e.g. C++ Control is called View in C#)
+$renameMap = [
+              ["Control", "View"]
+             ]
+
 $daliSwigPath = String.new;
 
+def getCSharpName( cppClassName )
+
+    entry = $renameMap.select{ |a| a.first == cppClassName }
+    if( entry.empty?)
+      return cppClassName
+    end
+    return entry[0][1]
+end
+
 # use the table above to get information for a specific type
 def getCSharpType( type )
 
     entry = $typeTable.select{ |a| a.first == type }
-    if( entry == nil )
+    if( entry.empty? )
       return nil
     end
     return entry[0]
@@ -182,7 +197,11 @@ def writePropertiesToCSharpFile( daliClass )
    # open the CSharp file autogenerated by SWIG
   swigFiles =  $daliSwigPath + "/automatic/csharp/"
 
-  fileName =(swigFiles+daliClass.name) + ".cs"
+  # some C++ classes are renamed for C#
+  className = getCSharpName( daliClass.name )
+
+  fileName =(swigFiles + className ) + ".cs"
+
 
   # it's possible some classes in dali-core aren't being wrapped by swig, so if the swig generated file
   # doesn't exist just return
@@ -212,7 +231,7 @@ def writePropertiesToCSharpFile( daliClass )
   file.write("\n}\n\n}");  # re-insert the closing brackets we over-wrote
   end
 
-  puts("Injected #{daliClass.properties.length} C# Properties into #{daliClass.name}.cs".blueBackground)
+  puts("Injected #{daliClass.properties.length} C# Properties from #{daliClass.name} into #{className}.cs".blueBackground)
 
 end
 
@@ -222,7 +241,7 @@ def writeChildPropertiesToCSharpFile( daliClass )
   swigFiles =  $daliSwigPath + "/automatic/csharp/"
 
   # Add all the child properties to Control
-  fileName = (swigFiles+"Control") + ".cs"
+  fileName = (swigFiles+"View") + ".cs"
 
   if( ! File.exist?(fileName) )
     return
@@ -252,7 +271,7 @@ def writeChildPropertiesToCSharpFile( daliClass )
   file.write("\n}\n\n}");  # re-insert the closing brackets we over-wrote
   end
 
-  puts("Injected #{$childPropertyCount} C# Child Properties into #{"Control"}.cs".blueBackground)
+  puts("Injected #{$childPropertyCount} C# Child Properties into #{"View"}.cs".blueBackground)
 
 end
 
@@ -263,6 +282,7 @@ def writeCSharpData
 
         #puts ( daliClass.name )
 
+
         hasChildProperties = false
 
         for property in daliClass.properties
@@ -279,10 +299,13 @@ def writeCSharpData
             propertyArg =  propertyInfo[2]  # e.g. ref or out
             tempDeclaration = propertyInfo[3] # e.g. bool temp;
 
-            propertyName = "#{daliClass.name}.Property.#{property.enum}"
+            csharpClassName = getCSharpName(daliClass.name);
+
+
+            propertyName = "#{csharpClassName}.Property.#{property.enum}"
 
             if property.childProperty
-              propertyName = "#{daliClass.name}.ChildProperty.#{property.enum}"
+              propertyName = "#{csharpClassName}.ChildProperty.#{property.enum}"
               hasChildProperties = true
             end
 
@@ -308,7 +331,7 @@ def writeCSharpData
         end
         # write normal properties to the class's own csharp file
         writePropertiesToCSharpFile( daliClass )
-        # write child properties to Control.cs
+        # write child properties to View.cs ( on Control has child properties)
         if (hasChildProperties)
           writeChildPropertiesToCSharpFile( daliClass )
         end