Merge "use string_view to avoid temporary string allocation." into devel/master
authorAdeel Kazmi <adeel.kazmi@samsung.com>
Tue, 6 Oct 2020 09:04:45 +0000 (09:04 +0000)
committerGerrit Code Review <gerrit@review>
Tue, 6 Oct 2020 09:04:45 +0000 (09:04 +0000)
75 files changed:
automated-tests/src/dali-toolkit-internal/CMakeLists.txt
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/test-animation-data.cpp
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-button.cpp
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-vector-image-renderer.cpp [new file with mode: 0644]
automated-tests/src/dali-toolkit/utc-Dali-FlexNode.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-Tooltip.cpp
automated-tests/src/dali-toolkit/utc-Dali-VideoView.cpp
build/tizen/CMakeLists.txt
dali-toolkit/devel-api/builder/base64-encoding.cpp
dali-toolkit/devel-api/controls/text-controls/text-editor-devel.h
dali-toolkit/devel-api/controls/text-controls/text-field-devel.h
dali-toolkit/devel-api/controls/text-controls/text-selection-popup.cpp
dali-toolkit/devel-api/controls/text-controls/text-selection-popup.h
dali-toolkit/devel-api/controls/text-controls/text-selection-toolbar.cpp
dali-toolkit/devel-api/controls/text-controls/text-selection-toolbar.h
dali-toolkit/devel-api/layouting/flex-node.cpp
dali-toolkit/devel-api/layouting/flex-node.h
dali-toolkit/internal/builder/json-parser-state.cpp
dali-toolkit/internal/builder/json-parser-state.h
dali-toolkit/internal/controls/buttons/button-impl.cpp
dali-toolkit/internal/controls/buttons/toggle-button-impl.cpp
dali-toolkit/internal/controls/control/control-data-impl.cpp
dali-toolkit/internal/controls/image-view/image-view-impl.cpp
dali-toolkit/internal/controls/progress-bar/progress-bar-impl.cpp
dali-toolkit/internal/controls/scroll-bar/scroll-bar-impl.cpp
dali-toolkit/internal/controls/scrollable/item-view/item-view-impl.cpp
dali-toolkit/internal/controls/scrollable/scroll-view/scroll-view-impl.cpp
dali-toolkit/internal/controls/table-view/table-view-impl.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-selection-popup-impl.cpp
dali-toolkit/internal/controls/text-controls/text-selection-popup-impl.h
dali-toolkit/internal/controls/text-controls/text-selection-toolbar-impl.cpp
dali-toolkit/internal/controls/text-controls/text-selection-toolbar-impl.h
dali-toolkit/internal/controls/tooltip/tooltip.cpp
dali-toolkit/internal/controls/video-view/video-view-impl.cpp [changed mode: 0644->0755]
dali-toolkit/internal/helpers/property-helper.cpp
dali-toolkit/internal/text/decorator/text-decorator.cpp
dali-toolkit/internal/text/decorator/text-decorator.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
dali-toolkit/internal/text/text-scroller.cpp [changed mode: 0644->0755]
dali-toolkit/internal/text/text-selectable-control-interface.h [new file with mode: 0644]
dali-toolkit/internal/visuals/animated-gradient/animated-gradient-visual.cpp
dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.cpp
dali-toolkit/internal/visuals/arc/arc-visual.cpp
dali-toolkit/internal/visuals/border/border-visual.cpp
dali-toolkit/internal/visuals/color/color-visual.cpp
dali-toolkit/internal/visuals/gradient/gradient-visual.cpp
dali-toolkit/internal/visuals/image-visual-shader-factory.cpp
dali-toolkit/internal/visuals/image/image-visual.cpp
dali-toolkit/internal/visuals/npatch/npatch-visual.cpp
dali-toolkit/internal/visuals/svg/svg-rasterize-thread.cpp
dali-toolkit/internal/visuals/svg/svg-rasterize-thread.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
dali-toolkit/internal/visuals/text/text-visual.h
dali-toolkit/internal/visuals/transition-data-impl.cpp
dali-toolkit/internal/visuals/visual-base-data-impl.cpp
dali-toolkit/internal/visuals/visual-factory-cache.cpp
dali-toolkit/internal/visuals/wireframe/wireframe-visual.cpp
dali-toolkit/public-api/controls/control-impl.h
dali-toolkit/public-api/dali-toolkit-version.cpp
packaging/dali-toolkit.spec

index bbb53b3..851ca00 100755 (executable)
@@ -55,6 +55,7 @@ LIST(APPEND TC_SOURCES
    ../dali-toolkit/dali-toolkit-test-utils/toolkit-timer.cpp
    ../dali-toolkit/dali-toolkit-test-utils/toolkit-tts-player.cpp
    ../dali-toolkit/dali-toolkit-test-utils/toolkit-vector-animation-renderer.cpp
+   ../dali-toolkit/dali-toolkit-test-utils/toolkit-vector-image-renderer.cpp
    ../dali-toolkit/dali-toolkit-test-utils/toolkit-window.cpp
    ../dali-toolkit/dali-toolkit-test-utils/toolkit-scene-holder.cpp
    ../dali-toolkit/dali-toolkit-test-utils/dali-test-suite-utils.cpp
index d7b4a5b..d889c6f 100755 (executable)
@@ -95,6 +95,7 @@ LIST(APPEND TC_SOURCES
   dali-toolkit-test-utils/toolkit-tts-player.cpp
   dali-toolkit-test-utils/toolkit-native-image-source.cpp
   dali-toolkit-test-utils/toolkit-vector-animation-renderer.cpp
+  dali-toolkit-test-utils/toolkit-vector-image-renderer.cpp
   dali-toolkit-test-utils/toolkit-video-player.cpp
   dali-toolkit-test-utils/toolkit-web-engine.cpp
   dali-toolkit-test-utils/toolkit-window.cpp
index a7ccfba..7d0c661 100644 (file)
@@ -174,7 +174,7 @@ void DummyControlImpl::SetProperty( BaseObject* object, Dali::Property::Index in
     case Toolkit::DummyControl::Property::FOCUS_VISUAL:
     case Toolkit::DummyControl::Property::LABEL_VISUAL:
     {
-      Property::Map* map = value.GetMap();
+      const Property::Map* map = value.GetMap();
       if( map != NULL )
       {
         VisualFactory visualFactory = VisualFactory::Get();
index 57c1e41..6702798 100644 (file)
@@ -156,7 +156,7 @@ void NewAnimator( const Property::Map& map, TestAnimationData::AnimationDataElem
     {
       if( value.GetType() == Property::MAP )
       {
-        Property::Map* map = value.GetMap();
+        const Property::Map* map = value.GetMap();
         const Property::Map& mapref = *map;
         NewAnimator( mapref, element ); // Merge the map into element
       }
@@ -180,7 +180,7 @@ void NewAnimation( const Property::Array& array, TestAnimationData& outputAnimat
     const Property::Value& value = array.GetElementAt(i);
     if( value.GetType() == Property::MAP )
     {
-      Property::Map* map = value.GetMap();
+      const Property::Map* map = value.GetMap();
       NewAnimator( *map, *element );
       outputAnimationData.Add( element );
     }
index 3b5f451..ff5e1dc 100644 (file)
@@ -78,13 +78,13 @@ void TestButton::SetProperty( BaseObject* object, Property::Index index, const P
       {
         if( value.GetType() == Property::MAP )
         {
-          Property::Map* valueMap = value.GetMap();
+          const Property::Map* valueMap = value.GetMap();
           buttonImpl.mPressTransitionData.Clear();
           NewAnimation( *valueMap, buttonImpl.mPressTransitionData );
         }
         else if( value.GetType() == Property::ARRAY )
         {
-          Property::Array* valueArray = value.GetArray();
+          const Property::Array* valueArray = value.GetArray();
           buttonImpl.mPressTransitionData.Clear();
           NewAnimation( *valueArray, buttonImpl.mPressTransitionData );
         }
diff --git a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-vector-image-renderer.cpp b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-vector-image-renderer.cpp
new file mode 100644 (file)
index 0000000..3513410
--- /dev/null
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2020 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/devel-api/adaptor-framework/vector-image-renderer.h>
+#include <dali/public-api/object/base-object.h>
+#include <dali/public-api/rendering/renderer.h>
+#include <toolkit-application.h>
+#include <toolkit-event-thread-callback.h>
+#include <memory>
+#include <sys/stat.h>
+
+namespace Dali
+{
+
+namespace Internal
+{
+
+namespace Adaptor
+{
+
+class VectorImageRenderer: public Dali::BaseObject
+{
+public:
+
+  VectorImageRenderer()
+  : mUrl(),
+    mRenderer(),
+    mWidth( 0 ),
+    mHeight( 0 )
+  {
+  }
+
+  ~VectorImageRenderer()
+  {
+  }
+
+  bool Render( float scale )
+  {
+     return true;
+  }
+
+  void SetBuffer( Dali::Devel::PixelBuffer &buffer )
+  {
+  }
+
+  bool Load( const std::string& url )
+  {
+    struct stat sb;
+    if ( stat(url.c_str(), &sb) == 0 )
+    {
+      return true;
+    }
+
+    return false;
+  }
+
+  bool Load( const char *data, uint32_t size )
+  {
+    return true;
+  }
+
+  void GetDefaultSize( uint32_t& width, uint32_t& height ) const
+  {
+    width = 100;
+    height = 100;
+  }
+
+public:
+
+  std::string mUrl;
+  Dali::Renderer mRenderer;
+  uint32_t mWidth;
+  uint32_t mHeight;
+};
+
+inline VectorImageRenderer& GetImplementation( Dali::VectorImageRenderer& renderer )
+{
+  DALI_ASSERT_ALWAYS( renderer && "VectorImageRenderer handle is empty." );
+  BaseObject& handle = renderer.GetBaseObject();
+  return static_cast< Internal::Adaptor::VectorImageRenderer& >( handle );
+}
+
+inline const VectorImageRenderer& GetImplementation( const Dali::VectorImageRenderer& renderer )
+{
+  DALI_ASSERT_ALWAYS( renderer && "VectorImageRenderer handle is empty." );
+  const BaseObject& handle = renderer.GetBaseObject();
+  return static_cast< const Internal::Adaptor::VectorImageRenderer& >( handle );
+}
+
+} // namespace Adaptor
+
+} // namespace Internal
+
+
+/********************************************************************************/
+/*********************************  PUBLIC CLASS  *******************************/
+/********************************************************************************/
+
+VectorImageRenderer VectorImageRenderer::New()
+{
+  Internal::Adaptor::VectorImageRenderer* imageRenderer = new Internal::Adaptor::VectorImageRenderer();
+
+  return VectorImageRenderer( imageRenderer );
+}
+
+VectorImageRenderer::VectorImageRenderer()
+{
+}
+
+VectorImageRenderer::~VectorImageRenderer()
+{
+}
+
+VectorImageRenderer::VectorImageRenderer( Internal::Adaptor::VectorImageRenderer* internal )
+: BaseHandle( internal )
+{
+}
+
+void VectorImageRenderer::SetBuffer( Dali::Devel::PixelBuffer &buffer )
+{
+  Internal::Adaptor::GetImplementation( *this ).SetBuffer( buffer );
+}
+
+bool VectorImageRenderer::Render( float scale )
+{
+  return Internal::Adaptor::GetImplementation( *this ).Render( scale );
+}
+
+bool VectorImageRenderer::Load( const std::string& url )
+{
+  return Internal::Adaptor::GetImplementation( *this ).Load( url );
+}
+
+bool VectorImageRenderer::Load( const char *data, uint32_t size )
+{
+  return Internal::Adaptor::GetImplementation( *this ).Load( data, size );
+}
+
+void VectorImageRenderer::GetDefaultSize( uint32_t& width, uint32_t& height ) const
+{
+  Internal::Adaptor::GetImplementation( *this ).GetDefaultSize( width, height );
+}
+
+} // namespace Dali
index 93a3ac5..307c149 100644 (file)
@@ -41,15 +41,14 @@ namespace
 const Flex::SizeTuple ITEM_SIZE = Flex::SizeTuple{ 10.0f, 10.0f };
 const Flex::SizeTuple ITEM_SIZE_CALLBACK_TEST = Flex::SizeTuple{ 15.0f, 15.0f };
 
-Flex::SizeTuple MeasureChild( Actor child, float width, int measureModeWidth, float height, int measureModeHeight)
+void MeasureChild( Actor child, float width, int measureModeWidth, float height, int measureModeHeight, Flex::SizeTuple *childSize)
 {
-  Flex::SizeTuple childSize = ITEM_SIZE;
+  *childSize = ITEM_SIZE;
   if (child.GetProperty< std::string >( Dali::Actor::Property::NAME ) == "callbackTest")
   {
-    childSize = ITEM_SIZE_CALLBACK_TEST;
+    *childSize = ITEM_SIZE_CALLBACK_TEST;
   }
-  tet_printf(" MeasureChild test callback executed (%f,%f)\n", childSize.width, childSize.height );
-  return childSize;
+  tet_printf(" MeasureChild test callback executed (%f,%f)\n", childSize->width, childSize->height );
 }
 
 }
index cb8d8bb..574cbf9 100644 (file)
@@ -1557,8 +1557,6 @@ int utcDaliTextEditorEvent02(void)
   application.Render();
 
   Actor layer = editor.GetChildAt( 1u );
-  DALI_TEST_CHECK( layer.GetProperty< bool >( Actor::Property::IS_LAYER ) );
-
   DALI_TEST_EQUALS( layer.GetChildCount(), 1u, TEST_LOCATION ); // The cursor.
   DALI_TEST_EQUALS( stencil.GetChildCount(), 0u, TEST_LOCATION );
 
@@ -2157,6 +2155,23 @@ int utcDaliTextEditorEvent07(void)
   // The text is not selected and not changed because of 'SetProperty( DevelTextEditor::Property::ENABLE_SHIFT_SELECTION, false )'
   DALI_TEST_EQUALS( "Hello\nld\nHello lo\nworld", editor.GetProperty<std::string>( TextEditor::Property::TEXT ), TEST_LOCATION );
 
+  // Select all Text
+  application.ProcessEvent( GenerateKey( "a", "", "a", KEY_A_CODE, KEY_CONTROL_MODIFIER, 0, Integration::KeyEvent::DOWN, "a", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE ) );
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  // replace text with "c"
+  application.ProcessEvent( GenerateKey( "c", "", "c", KEY_C_CODE, 0, 0, Integration::KeyEvent::DOWN, "c", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE ) );
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  //text is "c"
+  DALI_TEST_EQUALS( "c", editor.GetProperty<std::string>( TextEditor::Property::TEXT ), TEST_LOCATION );
+
   END_TEST;
 }
 
@@ -2845,3 +2860,74 @@ int utcDaliTextEditorMaxCharactersReached(void)
 
   END_TEST;
 }
+
+int UtcDaliTextEditorSelectRange(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline("utcDaliTextEditorSelectRange");
+
+  TextEditor textEditor = TextEditor::New();
+  DALI_TEST_CHECK( textEditor );
+
+  application.GetScene().Add( textEditor );
+
+  // Avoid a crash when core load gl resources.
+  application.GetGlAbstraction().SetCheckFramebufferStatusResult( GL_FRAMEBUFFER_COMPLETE );
+
+  application.SendNotification();
+  application.Render();
+
+  textEditor.SetProperty( TextEditor::Property::TEXT, "Hello world" );
+
+  textEditor.SetProperty( DevelTextEditor::Property::SELECTED_TEXT_START, 0 );
+  textEditor.SetProperty( DevelTextEditor::Property::SELECTED_TEXT_END, 5 );
+
+  DALI_TEST_EQUALS( textEditor.GetProperty( DevelTextEditor::Property::SELECTED_TEXT_START ).Get<int>(), 0, TEST_LOCATION );
+  DALI_TEST_EQUALS( textEditor.GetProperty( DevelTextEditor::Property::SELECTED_TEXT_END ).Get<int>(), 5, TEST_LOCATION );
+
+  END_TEST;
+}
+
+int UtcDaliTextEditorEnableEditing(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliTextEditorEnableEditing ");
+
+  TextEditor textEditor = TextEditor::New();
+
+  application.GetScene().Add( textEditor );
+
+  textEditor.SetProperty( Actor::Property::SIZE, Vector2( 300.f, 50.f ) );
+  textEditor.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT );
+  textEditor.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT );
+
+  // Avoid a crash when core load gl resources.
+  application.GetGlAbstraction().SetCheckFramebufferStatusResult( GL_FRAMEBUFFER_COMPLETE );
+
+  application.SendNotification();
+  application.Render();
+
+  textEditor.SetKeyInputFocus();
+  textEditor.SetProperty( DevelTextEditor::Property::ENABLE_EDITING, false );
+  application.ProcessEvent( GenerateKey( "D", "", "D", KEY_D_CODE, 0, 0, Integration::KeyEvent::DOWN, "D", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE ) );
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( textEditor.GetProperty( TextEditor::Property::TEXT ).Get<std::string>(), "", TEST_LOCATION );
+  DALI_TEST_EQUALS( textEditor.GetProperty( DevelTextEditor::Property::ENABLE_EDITING ).Get<bool>(), false, TEST_LOCATION );
+
+  textEditor.SetKeyInputFocus();
+  textEditor.SetProperty( DevelTextEditor::Property::ENABLE_EDITING, true );
+  application.ProcessEvent( GenerateKey( "D", "", "D", KEY_D_CODE, 0, 0, Integration::KeyEvent::DOWN, "D", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE ) );
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( textEditor.GetProperty( TextEditor::Property::TEXT ).Get<std::string>(), "D", TEST_LOCATION );
+  DALI_TEST_EQUALS( textEditor.GetProperty( DevelTextEditor::Property::ENABLE_EDITING ).Get<bool>(), true, TEST_LOCATION );
+
+  END_TEST;
+}
index 8bfb93b..2dd61c2 100644 (file)
@@ -1686,8 +1686,6 @@ int utcDaliTextFieldEvent02(void)
   application.Render();
 
   Actor layer = field.GetChildAt( 1u );
-  DALI_TEST_CHECK( layer.GetProperty< bool >( Actor::Property::IS_LAYER ) );
-
   DALI_TEST_EQUALS( layer.GetChildCount(), 1u, TEST_LOCATION ); // The cursor.
   DALI_TEST_EQUALS( stencil.GetChildCount(), 0u, TEST_LOCATION );
 
@@ -2960,3 +2958,95 @@ int UtcDaliTextFieldSelectNone(void)
 
   END_TEST;
 }
+
+int UtcDaliTextFieldSelectRange(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliTextFieldSelectRange ");
+
+  TextField textField = TextField::New();
+
+  application.GetScene().Add( textField );
+
+  textField.SetProperty( Actor::Property::SIZE, Vector2( 300.f, 50.f ) );
+  textField.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT );
+  textField.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT );
+
+  // Avoid a crash when core load gl resources.
+  application.GetGlAbstraction().SetCheckFramebufferStatusResult( GL_FRAMEBUFFER_COMPLETE );
+
+  application.SendNotification();
+  application.Render();
+
+  textField.SetProperty( TextField::Property::TEXT, "Hello world" );
+
+  application.SendNotification();
+  application.Render();
+
+  textField.SetProperty( DevelTextField::Property::SELECTED_TEXT_START , 0);
+  textField.SetProperty( DevelTextField::Property::SELECTED_TEXT_END , 5);
+
+  // Hello is selected
+  std::string selectedText = textField.GetProperty( DevelTextField::Property::SELECTED_TEXT ).Get<std::string>();
+  DALI_TEST_EQUALS( "Hello", selectedText, TEST_LOCATION );
+
+  DALI_TEST_EQUALS( textField.GetProperty( DevelTextField::Property::SELECTED_TEXT_START ).Get<int>(), 0, TEST_LOCATION );
+  DALI_TEST_EQUALS( textField.GetProperty( DevelTextField::Property::SELECTED_TEXT_END ).Get<int>(), 5, TEST_LOCATION );
+
+  textField.SetProperty( DevelTextField::Property::SELECTED_TEXT_START , 6);
+  textField.SetProperty( DevelTextField::Property::SELECTED_TEXT_END , 11);
+
+  // world is selected
+  selectedText = textField.GetProperty( DevelTextField::Property::SELECTED_TEXT ).Get<std::string>();
+  DALI_TEST_EQUALS( "world", selectedText, TEST_LOCATION );
+
+  DALI_TEST_EQUALS( textField.GetProperty( DevelTextField::Property::SELECTED_TEXT_START ).Get<int>(), 6, TEST_LOCATION );
+  DALI_TEST_EQUALS( textField.GetProperty( DevelTextField::Property::SELECTED_TEXT_END ).Get<int>(), 11, TEST_LOCATION );
+
+  END_TEST;
+}
+
+int UtcDaliTextFieldEnableEditing(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliTextFieldEnableEditing ");
+
+  TextField textField = TextField::New();
+
+  application.GetScene().Add( textField );
+
+  textField.SetProperty( Actor::Property::SIZE, Vector2( 300.f, 50.f ) );
+  textField.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT );
+  textField.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT );
+
+  // Avoid a crash when core load gl resources.
+  application.GetGlAbstraction().SetCheckFramebufferStatusResult( GL_FRAMEBUFFER_COMPLETE );
+
+  application.SendNotification();
+  application.Render();
+
+  textField.SetKeyInputFocus();
+  textField.SetProperty( DevelTextField::Property::ENABLE_EDITING, false );
+  application.ProcessEvent( GenerateKey( "D", "", "D", KEY_D_CODE, 0, 0, Integration::KeyEvent::DOWN, "D", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE ) );
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( textField.GetProperty( TextField::Property::TEXT ).Get<std::string>(), "", TEST_LOCATION );
+  DALI_TEST_EQUALS( textField.GetProperty( DevelTextField::Property::ENABLE_EDITING ).Get<bool>(), false, TEST_LOCATION );
+
+
+  textField.SetKeyInputFocus();
+  textField.SetProperty( DevelTextField::Property::ENABLE_EDITING, true );
+  application.ProcessEvent( GenerateKey( "D", "", "D", KEY_D_CODE, 0, 0, Integration::KeyEvent::DOWN, "D", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE ) );
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( textField.GetProperty( TextField::Property::TEXT ).Get<std::string>(), "D", TEST_LOCATION );
+  DALI_TEST_EQUALS( textField.GetProperty( DevelTextField::Property::ENABLE_EDITING ).Get<bool>(), true, TEST_LOCATION );
+
+  END_TEST;
+}
index b1cf510..3d68d5a 100644 (file)
@@ -272,7 +272,7 @@ int UtcDaliTooltipCreateWithArray(void)
 
   tet_infoline( "Ensure first value is a map and contains the right item" );
   const Property::Value mapValue1 = contentArray->GetElementAt( 0 );
-  Property::Map* map1 = mapValue1.GetMap();
+  const Property::Map* map1 = mapValue1.GetMap();
   DALI_TEST_CHECK( map1 );
   Property::Value* urlValue = map1->Find( ImageVisual::Property::URL );
   DALI_TEST_CHECK( urlValue );
@@ -280,7 +280,7 @@ int UtcDaliTooltipCreateWithArray(void)
 
   tet_infoline( "Ensure second value is a map and contains the right item" );
   const Property::Value mapValue2 = contentArray->GetElementAt( 1 );
-  Property::Map* map2 = mapValue2.GetMap();
+  const Property::Map* map2 = mapValue2.GetMap();
   DALI_TEST_CHECK( map2 );
   Property::Value* textValue = map2->Find( TextVisual::Property::TEXT );
   DALI_TEST_CHECK( textValue );
index 54cb6f7..b0aa75e 100644 (file)
@@ -692,6 +692,8 @@ int UtcDaliVideoViewSyncAniamtionForCoverage(void)
   VideoView videoView = DevelVideoView::New( Dali::VideoSyncMode::ENABLED );
   DALI_TEST_CHECK( videoView );
 
+  application.GetScene().Add( videoView );
+
   // Build the animation
   float durationSeconds(1.0f);
   Animation animation = Animation::New(durationSeconds);
@@ -732,6 +734,8 @@ int UtcDaliVideoViewASyncAniamtionForCoverage(void)
   VideoView videoView = DevelVideoView::New( Dali::VideoSyncMode::DISABLED );
   DALI_TEST_CHECK( videoView );
 
+  application.GetScene().Add( videoView );
+
   // Build the animation
   float durationSeconds(1.0f);
   Animation animation = Animation::New(durationSeconds);
index d122fd5..21b7c0f 100644 (file)
@@ -154,6 +154,9 @@ IF( ENABLE_TRACE )
   ADD_DEFINITIONS("-DTRACE_ENABLED")
 ENDIF()
 
+# Remove below when thorvg is ready
+ADD_DEFINITIONS( "-DNO_THORVG" )
+
 # Set paths
 SET( toolkit_images_dir  ${ROOT_SRC_DIR}/dali-toolkit/styles/images-common )
 SET( toolkit_sounds_dir  ${ROOT_SRC_DIR}/dali-toolkit/sounds )
index f95dde8..024c1b5 100644 (file)
@@ -41,7 +41,7 @@ bool GetStringFromProperty(const Property::Value& value, std::string& output)
   }
   else
   {
-    Property::Array* array = value.GetArray();
+    const Property::Array* array = value.GetArray();
     if(array)
     {
       const unsigned int arraySize = array->Size();
index bd01101..619f91a 100644 (file)
@@ -122,10 +122,28 @@ enum Type
   RENDERING_BACKEND,
 
   /**
-       * @brief The maximum number of characters that can be inserted.
-       * @details Name "maxLength", type Property::INTEGER.
-       */
+   * @brief The maximum number of characters that can be inserted.
+   * @details Name "maxLength", type Property::INTEGER.
+   */
   MAX_LENGTH,
+
+  /**
+   * @brief The selected text start position.
+   * @details Name "selectedTextStart", type Property::INTEGER.
+   */
+  SELECTED_TEXT_START,
+
+  /**
+   * @brief The selected text range end position.
+   * @details Name "selectedTextEnd", type Property::INTEGER.
+   */
+  SELECTED_TEXT_END,
+
+  /**
+   * @brief The Editable state of control.
+   * @details Name "editable", type Property::BOOL.
+   */
+  ENABLE_EDITING,
 };
 
 } // namespace Property
index 8e2e006..824d83c 100644 (file)
@@ -131,6 +131,24 @@ enum
        */
   RENDERING_BACKEND = ELLIPSIS + 7,
 
+  /**
+   * @brief The selected text start position.
+   * @details Name "selectedTextStart", type Property::INTEGER.
+   */
+  SELECTED_TEXT_START,
+
+  /**
+   * @brief The selected text range end position.
+   * @details Name "selectedTextEnd", type Property::INTEGER.
+   */
+  SELECTED_TEXT_END,
+
+  /**
+   * @brief The Editable state of control.
+   * @details Name "editable", type Property::BOOL.
+   */
+  ENABLE_EDITING,
+
 };
 } // namespace Property
 
index cfc5e43..9f92518 100644 (file)
@@ -64,7 +64,7 @@ void TextSelectionPopup::EnableButtons(Toolkit::TextSelectionPopup::Buttons butt
   GetImpl(*this).EnableButtons(buttonsToEnable);
 }
 
-void TextSelectionPopup::RaiseAbove(Layer target)
+void TextSelectionPopup::RaiseAbove(Actor target)
 {
   GetImpl(*this).RaiseAbove(target);
 }
index c46d138..551066f 100644 (file)
@@ -235,11 +235,11 @@ public:
   void EnableButtons(Toolkit::TextSelectionPopup::Buttons buttonsToEnable);
 
   /**
-   * @brief Raises the toolbar's layer above the given @e target layer.
+   * @brief Raises the toolbar's actor above the given @e target actor.
    *
-   * @param[in] target The layer to get above of.
+   * @param[in] target The actor to get above of.
    */
-  void RaiseAbove(Layer target);
+  void RaiseAbove(Actor target);
 
   /**
    * @brief Show the Popup if not being shown
index 276dfe4..64515fc 100644 (file)
@@ -69,7 +69,7 @@ void TextSelectionToolbar::ResizeDividers(Size& size)
   GetImpl(*this).ResizeDividers(size);
 }
 
-void TextSelectionToolbar::RaiseAbove(Layer target)
+void TextSelectionToolbar::RaiseAbove(Actor target)
 {
   GetImpl(*this).RaiseAbove(target);
 }
index 71e7419..98b4e7d 100644 (file)
@@ -119,11 +119,11 @@ public:
   void ResizeDividers(Size& size);
 
   /**
-   * @brief Raises the layer above the given @e target layer.
+   * @brief Raises the actor above the given @e target actor.
    *
-   * @param[in] target The layer to get above of.
+   * @param[in] target The actor to get above of.
    */
-  void RaiseAbove(Layer target);
+  void RaiseAbove(Actor target);
 
   /**
    * @copydoc Toolkit::ScrollView::ScrollTo(const Vector2&)
index bdc520a..aa46e6f 100644 (file)
@@ -162,8 +162,8 @@ SizeTuple Node::MeasureNode(float width, int widthMode, float height, int height
   Toolkit::Flex::SizeTuple nodeSize{8, 8}; // Default size set to 8,8 to aid bug detection.
   if(mImpl->mMeasureCallback && mImpl->mActor.GetHandle())
   {
-    DALI_LOG_INFO(gLogFilter, Debug::Verbose, "MeasureNode MeasureCallback executing on %s\n", mImpl->mActor.GetHandle().GetProperty<std::string>(Dali::Actor::Property::NAME).c_str());
-    nodeSize = mImpl->mMeasureCallback(mImpl->mActor.GetHandle(), width, widthMode, height, heightMode);
+    DALI_LOG_INFO(gLogFilter, Debug::Verbose, "MeasureNode MeasureCallback executing on %s\n", mImpl->mActor.GetHandle().GetProperty< std::string >( Dali::Actor::Property::NAME ).c_str());
+    mImpl->mMeasureCallback(mImpl->mActor.GetHandle(), width, widthMode, height, heightMode, &nodeSize);
   }
   DALI_LOG_INFO(gLogFilter, Debug::Verbose, "MeasureNode nodeSize width:%f height:%f\n", nodeSize.width, nodeSize.height);
   return nodeSize;
index 677fab0..5a73458 100644 (file)
@@ -113,8 +113,9 @@ struct SizeTuple
  * @note int, width measure specifcation mode
  * @note float, available height for child
  * @note int, height measure specification mode
+ * @note SizeTuple, return value
  */
-using MeasureCallback = SizeTuple (*)(Dali::Actor, float, int, float, int);
+using MeasureCallback = void (*)(Dali::Actor, float , int , float , int, SizeTuple *);
 
 /**
  * This class provides the API for calling into the Flex layout implementation.
index 636bac1..40ec632 100644 (file)
@@ -249,11 +249,11 @@ bool IsNumber(char c)
 
 JsonParserState::JsonParserState(TreeNode* _root)
   : mRoot(_root), mCurrent(_root),
-    mErrorDescription(NULL), mErrorNewLine(0), mErrorColumn(0), mErrorPosition(0),
+    mErrorDescription(nullptr), mErrorNewLine(0), mErrorColumn(0), mErrorPosition(0),
     mNumberOfParsedChars(0), mNumberOfCreatedNodes(0), mFirstParse(false),
     mState(STATE_START)
 {
-  if(_root == NULL)
+  if(_root == nullptr)
   {
     mFirstParse = true;
   }
@@ -261,13 +261,13 @@ JsonParserState::JsonParserState(TreeNode* _root)
 
 TreeNode* JsonParserState::CreateNewNode(const char* name, TreeNode::NodeType type)
 {
-  TreeNode* node = NULL;
+  TreeNode* node = nullptr;
 
   node = TreeNodeManipulator::NewTreeNode();
   TreeNodeManipulator modifyNew(node);
   modifyNew.SetType(type);
   modifyNew.SetName(name);
-  if(mRoot == NULL)
+  if(mRoot == nullptr)
   {
     mRoot    = node;
     mCurrent = TreeNodeManipulator(mRoot);
@@ -286,7 +286,7 @@ TreeNode* JsonParserState::CreateNewNode(const char* name, TreeNode::NodeType ty
 
 TreeNode* JsonParserState::NewNode(const char* name, TreeNode::NodeType type)
 {
-  TreeNode* node = NULL;
+  TreeNode* node = nullptr;
 
   if(mFirstParse)
   {
@@ -299,7 +299,7 @@ TreeNode* JsonParserState::NewNode(const char* name, TreeNode::NodeType type)
     if(name)
     {
       const TreeNode* found = mCurrent.GetChild(name);
-      if( NULL != found )
+      if( nullptr != found )
       {
         node = const_cast<TreeNode*>(found);
       }
@@ -307,7 +307,7 @@ TreeNode* JsonParserState::NewNode(const char* name, TreeNode::NodeType type)
     else
     {
       // if root node
-      if( mCurrent.GetParent() == NULL )
+      if( mCurrent.GetParent() == nullptr )
       {
         node = mRoot;
       }
@@ -550,7 +550,7 @@ char* JsonParserState::EncodeString()
     if (static_cast<unsigned char>(*mIter) < '\x20')
     {
       static_cast<void>( Error("Control characters not allowed in strings") );
-      return NULL;
+      return nullptr;
     }
     else if (*mIter == '\\' && AtLeast(2))
     {
@@ -602,12 +602,12 @@ char* JsonParserState::EncodeString()
           if( !AtLeast(6) )
           {
             static_cast<void>( Error("Bad unicode codepoint; not enough characters") );
-            return NULL;
+            return nullptr;
           }
           if ( !HexStringToUnsignedInteger(&(*(mIter + 2)), &(*(mIter + 6)), codepoint) )
           {
             static_cast<void>( Error("Bad unicode codepoint") );
-            return NULL;
+            return nullptr;
           }
 
           if (codepoint <= 0x7F)
@@ -633,7 +633,7 @@ char* JsonParserState::EncodeString()
         default:
         {
           static_cast<void>( Error("Unrecognized escape sequence") );
-          return NULL;
+          return nullptr;
         }
       }
 
@@ -682,6 +682,172 @@ char* JsonParserState::EncodeString()
 
 } // ParseString()
 
+bool JsonParserState::HandleStartState(const char* name, const char currentChar)
+{
+  if( '{' == currentChar )
+  {
+    NewNode(name, TreeNode::OBJECT);
+    mState = STATE_OBJECT;
+  }
+  else if( '[' == currentChar )
+  {
+    NewNode(name, TreeNode::ARRAY);
+    mState = STATE_VALUE;
+  }
+  else
+  {
+    return Error("Json must start with object {} or array []");
+  }
+
+  AdvanceSkipWhiteSpace(1);
+  return true;
+}
+
+bool JsonParserState::HandleObjectState(const char currentChar, const char lastCharacter)
+{
+  if( '}' == currentChar )
+  {
+    if(',' == lastCharacter)
+    {
+      return Error("Unexpected comma");
+    }
+
+    if( !UpToParent() )
+    {
+      return false;
+    }
+    mState = STATE_VALUE;
+  }
+  else if ( '"' == currentChar )
+  {
+    mState = STATE_KEY;
+  }
+  else
+  {
+    return Error("Unexpected character");
+  }
+
+  AdvanceSkipWhiteSpace(1);
+  return true;
+}
+
+bool JsonParserState::HandleKeyState(char*& name)
+{
+  name = EncodeString();
+  if( nullptr == name )
+  {
+    return false;
+  }
+  if( !ParseWhiteSpace() )
+  {
+    return false;
+  }
+  if( ':' != Char())
+  {
+    return Error("Expected ':'");
+  }
+  if( !ParseWhiteSpace() )
+  {
+    return false;
+  }
+  mState = STATE_VALUE;
+
+  AdvanceSkipWhiteSpace(1);
+  return true;
+}
+
+bool JsonParserState::HandleCharacterQuote(char*& name)
+{
+  Advance(1);
+  NewNode(name, TreeNode::STRING);
+  if( char* value = EncodeString() )
+  {
+    mCurrent.SetString(value);
+  }
+  else
+  {
+    return false;
+  }
+  if( !UpToParent() )
+  {
+    return false;
+  }
+  AdvanceSkipWhiteSpace(0);
+  return true;
+}
+
+bool JsonParserState::HandleCharacterNumberOrHyphen(const char* name)
+{
+  NewNode(name, TreeNode::IS_NULL);
+  if( !ParseNumber() )
+  {
+    return false;
+  }
+  if( !UpToParent() )
+  {
+    return false;
+  }
+  AdvanceSkipWhiteSpace(0);
+  return true;
+}
+
+bool JsonParserState::HandleValueState(char*& name, const char currentChar, const char lastCharacter)
+{
+  bool handled = true;
+
+  if( '"' == currentChar )
+  {
+    handled = HandleCharacterQuote(name);
+  }
+  else if( IsNumber(currentChar) || currentChar == '-' )
+  {
+    handled = HandleCharacterNumberOrHyphen(name);
+  }
+  else if( '{' == currentChar )
+  {
+    handled = HandleCharacterBracesStart(name, lastCharacter);
+  }
+  else if( '}' == currentChar )
+  {
+    handled = HandleCharacterBracesEnd(lastCharacter);
+  }
+  else if( '[' == currentChar )
+  {
+    handled = HandleCharacterSquareBracketStart(name);
+  }
+  else if( ']' == currentChar )
+  {
+    handled = HandleCharacterSquareBracketEnd(lastCharacter);
+  }
+  else if( 't' == currentChar )
+  {
+    handled = HandleCharacterLowercaseT(name);
+  }
+  else if( 'n' == currentChar )
+  {
+    handled = HandleCharacterLowercaseN(name);
+  }
+  else if( 'f' == currentChar)
+  {
+    handled = HandleCharacterLowercaseF(name);
+  }
+  else if( ',' == currentChar )
+  {
+    handled = HandleCharacterComma(name);
+  }
+  else
+  {
+    handled = Error("Unexpected character");
+  }
+
+  if(handled)
+  {
+    name = nullptr;
+  }
+
+  return handled;
+}
+
 bool JsonParserState::ParseJson(VectorChar& source)
 {
   Reset();
@@ -694,7 +860,7 @@ bool JsonParserState::ParseJson(VectorChar& source)
   mIter = source.begin();
   mEnd  = source.end();
 
-  char* name = NULL;
+  char* name = nullptr;
   char currentChar   = 0;
   char lastCharacter = 0;
 
@@ -712,244 +878,34 @@ bool JsonParserState::ParseJson(VectorChar& source)
     {
       case STATE_START:
       {
-        if( '{' == currentChar )
-        {
-          NewNode(name, TreeNode::OBJECT);
-          mState = STATE_OBJECT;
-        }
-        else if( '[' == currentChar )
+        if(!HandleStartState(name, currentChar))
         {
-          NewNode(name, TreeNode::ARRAY);
-          mState = STATE_VALUE;
-        }
-        else
-        {
-          return Error("Json must start with object {} or array []");
+          return false;
         }
-
-        AdvanceSkipWhiteSpace(1);
         break;
       }
       case STATE_OBJECT:
       {
-        if( '}' == currentChar )
+        if(!HandleObjectState(currentChar, lastCharacter))
         {
-          if(',' == lastCharacter)
-          {
-            return Error("Unexpected comma");
-          }
-
-          if( !UpToParent() )
-          {
-            return false;
-          }
-          mState = STATE_VALUE;
-        }
-        else if ( '"' == currentChar )
-        {
-          mState = STATE_KEY;
-        }
-        else
-        {
-          return Error("Unexpected character");
+          return false;
         }
-
-        AdvanceSkipWhiteSpace(1);
         break;
       }
       case STATE_KEY:
       {
-        name = EncodeString();
-        if( NULL == name )
+        if(!HandleKeyState(name))
         {
           return false;
         }
-        if( !ParseWhiteSpace() )
-        {
-          return false;
-        }
-        if( ':' != Char())
-        {
-          return Error("Expected ':'");
-        }
-        if( !ParseWhiteSpace() )
-        {
-          return false;
-        }
-        mState = STATE_VALUE;
-
-        AdvanceSkipWhiteSpace(1);
         break;
       }
       case STATE_VALUE:
       {
-        if( '"' == currentChar )
+        if(!HandleValueState(name, currentChar, lastCharacter))
         {
-          Advance(1);
-          NewNode(name, TreeNode::STRING);
-          if( char* value = EncodeString() )
-          {
-            mCurrent.SetString(value);
-          }
-          else
-          {
-            return false;
-          }
-          if( !UpToParent() )
-          {
-            return false;
-          }
-          AdvanceSkipWhiteSpace(0);
-        }
-        else if( IsNumber(currentChar) || currentChar == '-' )
-        {
-          NewNode(name, TreeNode::IS_NULL);
-          if( !ParseNumber() )
-          {
-            return false;
-          }
-          if( !UpToParent() )
-          {
-            return false;
-          }
-          AdvanceSkipWhiteSpace(0);
-        }
-        else if( '{' == currentChar )
-        {
-          if( '}' == lastCharacter )
-          {
-            return Error("Expected a comma");
-          }
-          else
-          {
-            NewNode(name, TreeNode::OBJECT);
-            mState = STATE_OBJECT;
-            AdvanceSkipWhiteSpace(1);
-          }
-        }
-        else if( '}' == currentChar )
-        {
-          if(',' == lastCharacter)
-          {
-            return Error("Expected another value");
-          }
-
-          if(mCurrent.GetType() != TreeNode::OBJECT)
-          {
-            return Error("Mismatched array definition");
-          }
-
-          if(mCurrent.GetParent() == NULL)
-          {
-            mState = STATE_END;
-          }
-          else
-          {
-            if( !UpToParent() )
-            {
-              return false;
-            }
-          }
-          AdvanceSkipWhiteSpace(1);
-        }
-        else if( '[' == currentChar )
-        {
-          NewNode(name, TreeNode::ARRAY);
-          mState = STATE_VALUE;
-          AdvanceSkipWhiteSpace(1);
-        }
-        else if( ']' == currentChar )
-        {
-          if(',' == lastCharacter)
-          {
-            return Error("Expected a value");
-          }
-
-          if(mCurrent.GetType() != TreeNode::ARRAY)
-          {
-            return Error("Mismatched braces in object definition");
-          }
-
-          if(mCurrent.GetParent() == NULL)
-          {
-            mState = STATE_END;
-          }
-          else
-          {
-            if( !UpToParent() )
-            {
-              return false;
-            }
-          }
-          AdvanceSkipWhiteSpace(1);
-        }
-        else if( 't' == currentChar )
-        {
-          NewNode(name, TreeNode::BOOLEAN);
-          if( !ParseTrue() )
-          {
-            return false;
-          }
-          if( !UpToParent() )
-          {
-            return false;
-          }
-          AdvanceSkipWhiteSpace(0);
-        }
-        else if( 'n' == currentChar )
-        {
-          NewNode(name, TreeNode::IS_NULL);
-          if( !ParseNULL() )
-          {
-            return false;
-          }
-          if( !UpToParent() )
-          {
-            return false;
-          }
-          AdvanceSkipWhiteSpace(0);
-        }
-        else if( 'f' == currentChar)
-        {
-          NewNode(name, TreeNode::BOOLEAN);
-          if( !ParseFalse() )
-          {
-            return false;
-          }
-          if( !UpToParent() )
-          {
-            return false;
-          }
-          AdvanceSkipWhiteSpace(0);
-        }
-        else if( ',' == currentChar )
-        {
-          if( 0 == mCurrent.Size() )
-          {
-            return Error("Missing Value");
-          }
-
-          if(mCurrent.GetType() == TreeNode::OBJECT)
-          {
-            mState = STATE_OBJECT; // to get '"' in '"key":val'
-          }
-          else if(mCurrent.GetType() == TreeNode::ARRAY)
-          {
-            mState = STATE_VALUE; // array so just get next value
-          }
-          else
-          {
-            return Error("Unexpected character");
-          }
-          AdvanceSkipWhiteSpace(1);
-        }
-        else
-        {
-          return Error("Unexpected character");
+          return false;
         }
-
-        name = NULL;
-
         break;
       } // case STATE_VALUE
       case STATE_END:
@@ -973,17 +929,160 @@ bool JsonParserState::ParseJson(VectorChar& source)
 
 } // ParseJson
 
-
 void JsonParserState::Reset()
 {
   mCurrent = TreeNodeManipulator(mRoot);
 
-  mErrorDescription   = NULL;
+  mErrorDescription   = nullptr;
   mErrorNewLine       = 0;
   mErrorColumn        = 0;
   mErrorPosition      = 0;
 }
 
+bool JsonParserState::HandleCharacterBracesStart(const char* name, const char lastCharacter)
+{
+  if( '}' == lastCharacter )
+  {
+    return Error("Expected a comma");
+  }
+  else
+  {
+    NewNode(name, TreeNode::OBJECT);
+    mState = STATE_OBJECT;
+    AdvanceSkipWhiteSpace(1);
+  }
+  return true;
+}
+
+bool JsonParserState::HandleCharacterBracesEnd(const char lastCharacter)
+{
+  if(',' == lastCharacter)
+  {
+    return Error("Expected another value");
+  }
+
+  if(mCurrent.GetType() != TreeNode::OBJECT)
+  {
+    return Error("Mismatched array definition");
+  }
+
+  if(mCurrent.GetParent() == nullptr)
+  {
+    mState = STATE_END;
+  }
+  else
+  {
+    if( !UpToParent() )
+    {
+      return false;
+    }
+  }
+  AdvanceSkipWhiteSpace(1);
+  return true;
+}
+
+bool JsonParserState::HandleCharacterSquareBracketStart(const char* name)
+{
+  NewNode(name, TreeNode::ARRAY);
+  mState = STATE_VALUE;
+  AdvanceSkipWhiteSpace(1);
+  return true;
+}
+
+bool JsonParserState::HandleCharacterSquareBracketEnd(const char lastCharacter)
+{
+  if(',' == lastCharacter)
+  {
+    return Error("Expected a value");
+  }
+
+  if(mCurrent.GetType() != TreeNode::ARRAY)
+  {
+    return Error("Mismatched braces in object definition");
+  }
+
+  if(mCurrent.GetParent() == nullptr)
+  {
+    mState = STATE_END;
+  }
+  else
+  {
+    if( !UpToParent() )
+    {
+      return false;
+    }
+  }
+  AdvanceSkipWhiteSpace(1);
+  return true;
+}
+
+bool JsonParserState::HandleCharacterLowercaseT(const char* name)
+{
+  NewNode(name, TreeNode::BOOLEAN);
+  if( !ParseTrue() )
+  {
+    return false;
+  }
+  if( !UpToParent() )
+  {
+    return false;
+  }
+  AdvanceSkipWhiteSpace(0);
+  return true;
+}
+
+bool JsonParserState::HandleCharacterLowercaseN(const char* name)
+{
+  NewNode(name, TreeNode::IS_NULL);
+  if( !ParseNULL() )
+  {
+    return false;
+  }
+  if( !UpToParent() )
+  {
+    return false;
+  }
+  AdvanceSkipWhiteSpace(0);
+  return true;
+}
+
+bool JsonParserState::HandleCharacterLowercaseF(const char* name)
+{
+  NewNode(name, TreeNode::BOOLEAN);
+  if( !ParseFalse() )
+  {
+    return false;
+  }
+  if( !UpToParent() )
+  {
+    return false;
+  }
+  AdvanceSkipWhiteSpace(0);
+  return true;
+}
+
+bool JsonParserState::HandleCharacterComma(const char* name)
+{
+  if( 0 == mCurrent.Size() )
+  {
+    return Error("Missing Value");
+  }
+
+  if(mCurrent.GetType() == TreeNode::OBJECT)
+  {
+    mState = STATE_OBJECT; // to get '"' in '"key":val'
+  }
+  else if(mCurrent.GetType() == TreeNode::ARRAY)
+  {
+    mState = STATE_VALUE; // array so just get next value
+  }
+  else
+  {
+    return Error("Unexpected character");
+  }
+  AdvanceSkipWhiteSpace(1);
+  return true;
+}
 
 } // namespace Internal
 
index 210c11f..4d7e7a4 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_JSON_PARSE_STATE_H
 
 /*
- * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2020 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.
@@ -35,7 +35,7 @@ namespace Toolkit
 namespace Internal
 {
 
-/*
+/**
  * A safer std::advance()
  */
 template <typename IteratorType,typename EndIteratorType>
@@ -52,7 +52,7 @@ inline int AdvanceIter(IteratorType& iter, EndIteratorType& end, int n)
   return n;
 }
 
-/*
+/**
  * Maintains parser state machine
  *
  * If a NULL root node is passed in the constructor then a faster non merging parse is performed (the first pass).
@@ -61,13 +61,13 @@ inline int AdvanceIter(IteratorType& iter, EndIteratorType& end, int n)
 class JsonParserState
 {
 public:
-  /*
+  /**
    * Constructor
    * @param tree Tree to start with, pass NULL if no existing tree
    */
   explicit JsonParserState(TreeNode* tree);
 
-  /*
+  /**
    * Parse json source
    * The source is modified in place
    * @param source The vector buffer to parse
@@ -75,43 +75,43 @@ public:
    */
   bool ParseJson(VectorChar& source);
 
-  /*
+  /**
    * Get the root node
    * @return The root TreeNode
    */
   TreeNode* GetRoot();
 
-  /*
+  /**
    * Get the error description of the last parse
    * @return The error description or NULL if no error
    */
   const char* GetErrorDescription() { return mErrorDescription; }
 
-  /*
+  /**
    * Get the error line number
    * @return The line number of the error
    */
   int GetErrorLineNumber() { return mErrorNewLine; }
 
-  /*
+  /**
    * Get the error column
    * @return The error column
    */
   int GetErrorColumn() { return mErrorColumn; }
 
-  /*
+  /**
    * Get the error position
    * @return The error position
    */
   int GetErrorPosition() { return mErrorPosition; }
 
-  /*
+  /**
    * Get the size of the string data that has been parsed
    * @return The size of string data
    */
   int GetParsedStringSize() { return mNumberOfParsedChars; };
 
-  /*
+  /**
    * Get the number of nodes created
    * @return The number of nodes
    */
@@ -131,7 +131,7 @@ private:
   int mNumberOfCreatedNodes;           ///< The number of nodes created
   bool mFirstParse;                    ///< Flag if first parse
 
-  /*
+  /**
    * The current parse state
    */
   enum State
@@ -149,49 +149,49 @@ private:
   JsonParserState(const JsonParserState&);
   const JsonParserState& operator=(const JsonParserState&);
 
-  /*
+  /**
    * Parse over white space
    * Increments the current position
    * @return true if no parse errors
    */
   bool ParseWhiteSpace();
 
-  /*
+  /**
    * Parse over a number, setting the current node if found
    * Increments the current position. Sets error data if parse error.
    * @return true if found, false if parse error
    */
   bool ParseNumber();
 
-  /*
+  /**
    * Parse over a symbol
    * Increments the current position. Sets error data if parse error.
    * @return true if found, false if parse error
    */
   bool ParseSymbol(const std::string& symbol);
 
-  /*
+  /**
    * Parse over 'true' symbol, setting the current node if found
    * Increments the current position. Sets error data if parse error.
    * @return true if found, false if parse error
    */
   bool ParseTrue();
 
-  /*
+  /**
    * Parse over 'false' symbol, setting the current node if found
    * Increments the current position. Sets error data if parse error.
    * @return true if found, false if parse error
    */
   bool ParseFalse();
 
-  /*
+  /**
    * Parse over 'null' symbol, setting the current node if found
    * Increments the current position. Sets error data if parse error.
    * @return true if found, false if parse error
    */
   bool ParseNULL();
 
-  /*
+  /**
    * Parse over a string from the current position and insert escaped
    * control characters in place in the string and a null terminator.
    * This function works from and modifes the current buffer position.
@@ -199,29 +199,29 @@ private:
    */
   char* EncodeString();
 
-  /*
+  /**
    * Create a new node with name and type
    */
   TreeNode* CreateNewNode(const char* name, TreeNode::NodeType type);
 
-  /*
+  /**
    * Create a new node if first parse, else check if the node already
    * exists and set it to a new type
    */
   TreeNode* NewNode(const char* name, TreeNode::NodeType type);
 
-  /*
+  /**
    * Set error meta data
    * @returns always false.
    */
   bool Error(const char* description);
 
-  /*
+  /**
    * Reset state for another parse
    */
   void Reset();
 
-  /*
+  /**
    * Set current to its parent
    * @return true if we had a parent, false and error otherwise
    */
@@ -235,7 +235,7 @@ private:
     return true;
   }
 
-  /*
+  /**
    * Get the current character
    */
   inline char Char()
@@ -243,7 +243,7 @@ private:
     return *mIter;
   }
 
-  /*
+  /**
    * @return True if there are at least n character left
    */
   inline bool AtLeast(int n)
@@ -254,7 +254,7 @@ private:
     return (mEnd - mIter) > n;
   }
 
-  /*
+  /**
    * @return True if at the end of the data to parse
    */
   inline bool AtEnd()
@@ -262,7 +262,7 @@ private:
     return mEnd == mIter;
   }
 
-  /*
+  /**
    * Advance current position by n characters or stop at mEnd
    */
   inline void Advance(int n)
@@ -272,7 +272,7 @@ private:
     mErrorColumn   += c;
   }
 
-  /*
+  /**
    * Advance by n charaters and return true if we reached the end
    */
   inline bool AdvanceEnded(int n)
@@ -283,7 +283,7 @@ private:
     return mEnd == mIter;
   }
 
-  /*
+  /**
    * Advance by at least n characters (stopping at mEnd) and skip any whitespace after n.
    */
   inline void AdvanceSkipWhiteSpace(int n)
@@ -294,7 +294,7 @@ private:
     static_cast<void>( ParseWhiteSpace() );
   }
 
-  /*
+  /**
    * Increment new line counters
    */
   inline void NewLine()
@@ -303,6 +303,122 @@ private:
     mErrorColumn = 0;
   }
 
+  /**
+   * @brief Called by ParseJson if we are in STATE_START.
+   *
+   * @param[in] name The current name
+   * @param[in] currentChar The current character being parsed
+   * @return true if successfully parsed
+   */
+  bool HandleStartState(const char* name, const char currentChar);
+
+  /**
+   * @brief Called by ParseJson if we are in STATE_OBJECT.
+   *
+   * @param[in] currentChar The current character being parsed
+   * @param[in] lastCharacter The last character we parsed
+   * @return true if successfully parsed
+   */
+  bool HandleObjectState(const char currentChar, const char lastCharacter);
+
+  /**
+   * @brief Called by ParseJson if we are in STATE_KEY.
+   *
+   * @param[in/out] name A reference to the name variable
+   * @return true if successfully parsed
+   */
+  bool HandleKeyState(char*& name);
+
+  /**
+   * @brief Called by ParseJson if we are in STATE_VALUE.
+   *
+   * @param[in/out] name A reference to the name variable
+   * @param[in] currentChar The current character being parsed
+   * @param[in] lastCharacter The last character we parsed
+   * @return true if successfully parsed
+   */
+  bool HandleValueState(char*& name, const char currentChar, const char lastCharacter);
+
+  /**
+   * @brief Called by HandleValueState to parse a '"' character.
+   *
+   * @param[in] name The current name
+   * @return true if successfully parsed
+   */
+  bool HandleCharacterQuote(char*& name);
+
+  /**
+   * @brief Called by HandleValueState to parse a number or hyphen character.
+   *
+   * @param[in] name The current name
+   * @return true if successfully parsed
+   */
+  bool HandleCharacterNumberOrHyphen(const char* name);
+
+  /**
+   * @brief Called by HandleValueState to parse a '{' character.
+   *
+   * @param[in] name The current name
+   * @param[in] lastCharacter The last character we parsed
+   * @return true if successfully parsed
+   */
+  bool HandleCharacterBracesStart(const char* name, const char lastCharacter);
+
+  /**
+   * @brief Called by HandleValueState to parse a '}' character.
+   *
+   * @param[in] lastCharacter The last character we parsed
+   * @return true if successfully parsed
+   */
+  bool HandleCharacterBracesEnd(const char lastCharacter);
+
+  /**
+   * @brief Called by HandleValueState to parse a '[' character.
+   *
+   * @param[in] name The current name
+   * @return true if successfully parsed
+   */
+  bool HandleCharacterSquareBracketStart(const char* name);
+
+  /**
+   * @brief Called by HandleValueState to parse a ']' character.
+   *
+   * @param[in] lastCharacter The last character we parsed
+   * @return true if successfully parsed
+   */
+  bool HandleCharacterSquareBracketEnd(const char lastCharacter);
+
+  /**
+   * @brief Called by HandleValueState to parse a 't' character.
+   *
+   * @param[in] name The current name
+   * @return true if successfully parsed
+   */
+  bool HandleCharacterLowercaseT(const char* name);
+
+  /**
+   * @brief Called by HandleValueState to parse a 'n' character.
+   *
+   * @param[in] name The current name
+   * @return true if successfully parsed
+   */
+  bool HandleCharacterLowercaseN(const char* name);
+
+  /**
+   * @brief Called by HandleValueState to parse a 'f' character.
+   *
+   * @param[in] name The current name
+   * @return true if successfully parsed
+   */
+  bool HandleCharacterLowercaseF(const char* name);
+
+  /**
+   * @brief Called by HandleValueState to parse a ',' character.
+   *
+   * @param[in] name The current name
+   * @return true if successfully parsed
+   */
+  bool HandleCharacterComma(const char* name);
 };
 
 
index 6d45eed..d840e96 100644 (file)
@@ -379,7 +379,7 @@ void Button::CreateVisualsForComponent( Property::Index index, const Property::V
   else
   {
     // if its not a string then get a Property::Map from the property if possible.
-    Property::Map *map = value.GetMap();
+    const Property::Map *map = value.GetMap();
     if( map && !map->Empty()  ) // Empty map results in current visual removal.
     {
       DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "CreateVisualsForComponent Using Map(%d)\n", index );
@@ -1151,11 +1151,11 @@ void Button::SetProperty( BaseObject* object, Property::Index index, const Prope
         else
         {
           // Get a Property::Map from the property if possible.
-          Property::Map* setPropertyMap = value.GetMap();
+          const Property::Map* setPropertyMap = value.GetMap();
           if( setPropertyMap )
           {
-            TextVisual::ConvertStringKeysToIndexKeys( *setPropertyMap );
-            GetImplementation( button ).MergeWithExistingLabelProperties( *setPropertyMap, outTextVisualProperties );
+            Property::Map indexKeys = TextVisual::ConvertStringKeysToIndexKeys( *setPropertyMap );
+            GetImplementation( button ).MergeWithExistingLabelProperties( indexKeys, outTextVisualProperties );
           }
         }
 
index e6c0ab7..b1808f5 100755 (executable)
@@ -136,7 +136,7 @@ void ToggleButton::SetProperty( BaseObject* object, Property::Index propertyInde
       }
       case Toolkit::ToggleButton::Property::TOOLTIPS:
       {
-        Property::Array* tipArray = value.GetArray();
+        const Property::Array* tipArray = value.GetArray();
         if( tipArray )
         {
           std::vector<std::string> tips;
index 46a1972..8a2dfd7 100755 (executable)
@@ -835,7 +835,7 @@ void Control::Impl::SetProperty( BaseObject* object, Property::Index index, cons
       {
         bool withTransitions=true;
         const Property::Value* valuePtr=&value;
-        Property::Map* map = value.GetMap();
+        const Property::Map* map = value.GetMap();
         if(map)
         {
           Property::Value* value2 = map->Find("withTransitions");
index 7f92138..36702a8 100755 (executable)
@@ -432,7 +432,7 @@ void ImageView::SetProperty( BaseObject* object, Property::Index index, const Pr
       case Toolkit::ImageView::Property::IMAGE:
       {
         std::string imageUrl;
-        Property::Map* map;
+        const Property::Map* map;
         if( value.Get( imageUrl ) )
         {
           impl.SetImage( imageUrl, ImageDimensions() );
index 3d18ddb..0a4a7e5 100755 (executable)
@@ -404,7 +404,7 @@ void ProgressBar::CreateVisualsForComponent( Property::Index index, const Proper
   else // Does this code make text-visual can be accepted as visual?
   {
     // if its not a string then get a Property::Map from the property if possible.
-    Property::Map *map = value.GetMap();
+    const Property::Map *map = value.GetMap();
     if( map && !map->Empty()  ) // Empty map results in current visual removal.
     {
       progressVisual = visualFactory.CreateVisual( *map );
index f002764..54dc431 100644 (file)
@@ -689,7 +689,7 @@ void ScrollBar::SetProperty( BaseObject* object, Property::Index index, const Pr
       }
       case Toolkit::ScrollBar::Property::SCROLL_POSITION_INTERVALS:
       {
-        Property::Array* array = value.GetArray();
+        const Property::Array* array = value.GetArray();
         if( array )
         {
           Dali::Vector<float> positions;
index c442fb8..12bd0c3 100644 (file)
@@ -1819,7 +1819,7 @@ void ItemView::SetLayoutArray( const Property::Array& layouts )
   {
     const Property::Value& element = layouts.GetElementAt( arrayIdx );
 
-    Property::Map* layout = element.GetMap();
+    const Property::Map* layout = element.GetMap();
     if( layout != NULL )
     {
       for( unsigned int mapIdx = 0, mapCount = (*layout).Count(); mapIdx < mapCount; ++mapIdx )
index 1273cd1..01c5731 100644 (file)
@@ -2915,7 +2915,7 @@ void ScrollView::SetProperty( BaseObject* object, Property::Index index, const P
       }
       case Toolkit::ScrollView::Property::SCROLL_MODE:
       {
-        Property::Map* map = value.GetMap();
+        const Property::Map* map = value.GetMap();
         if( map )
         {
           scrollViewImpl.SetScrollMode( *map );
index a0c1849..92cdd01 100755 (executable)
@@ -1212,7 +1212,7 @@ void TableView::SetHeightOrWidthProperty(TableView& tableViewImpl,
                                          void(TableView::*funcFit)(unsigned int),
                                          const Property::Value& value )
 {
-  Property::Map* map = value.GetMap();
+  const Property::Map* map = value.GetMap();
   if( map )
   {
     unsigned int index(0);
index 7576bc1..4224df2 100644 (file)
@@ -22,6 +22,7 @@
 #include <cstring>
 #include <limits>
 #include <dali/public-api/adaptor-framework/key.h>
+#include <dali/public-api/common/dali-common.h>
 #include <dali/devel-api/adaptor-framework/window-devel.h>
 #include <dali/devel-api/common/stage.h>
 #include <dali/devel-api/actors/actor-devel.h>
@@ -139,6 +140,9 @@ DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextEditor, "enableGrabHandle",
 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextEditor, "matchSystemLanguageDirection",   BOOLEAN,   MATCH_SYSTEM_LANGUAGE_DIRECTION      )
 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextEditor, "renderingBackend",               INTEGER,   RENDERING_BACKEND                    )
 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextEditor, "maxLength",                      INTEGER,   MAX_LENGTH                           )
+DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextEditor, "selectedTextStart",              INTEGER,   SELECTED_TEXT_START                  )
+DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextEditor, "selectedTextEnd",                INTEGER,   SELECTED_TEXT_END                    )
+DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextEditor, "enableEditing",                  BOOLEAN,   ENABLE_EDITING                       )
 
 DALI_SIGNAL_REGISTRATION( Toolkit, TextEditor, "textChanged",        SIGNAL_TEXT_CHANGED )
 DALI_SIGNAL_REGISTRATION( Toolkit, TextEditor, "inputStyleChanged",  SIGNAL_INPUT_STYLE_CHANGED )
@@ -191,6 +195,8 @@ void TextEditor::SetProperty( BaseObject* object, Property::Index index, const P
   if( textEditor )
   {
     TextEditor& impl( GetImpl( textEditor ) );
+    DALI_ASSERT_DEBUG( impl.mController && "No text contoller" );
+    DALI_ASSERT_DEBUG( impl.mDecorator && "No text decorator" );
 
     switch( index )
     {
@@ -209,39 +215,30 @@ void TextEditor::SetProperty( BaseObject* object, Property::Index index, const P
       }
       case Toolkit::TextEditor::Property::TEXT:
       {
-        if( impl.mController )
-        {
-          const std::string& text = value.Get< std::string >();
-          DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p TEXT %s\n", impl.mController.Get(), text.c_str() );
+        const std::string& text = value.Get< std::string >();
+        DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p TEXT %s\n", impl.mController.Get(), text.c_str() );
 
-          impl.mController->SetText( text );
-        }
+        impl.mController->SetText( text );
         break;
       }
       case Toolkit::TextEditor::Property::TEXT_COLOR:
       {
-        if( impl.mController )
+        const Vector4& textColor = value.Get< Vector4 >();
+        DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p TEXT_COLOR %f,%f,%f,%f\n", impl.mController.Get(), textColor.r, textColor.g, textColor.b, textColor.a );
+
+        if( impl.mController->GetDefaultColor() != textColor )
         {
-          const Vector4& textColor = value.Get< Vector4 >();
-          DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p TEXT_COLOR %f,%f,%f,%f\n", impl.mController.Get(), textColor.r, textColor.g, textColor.b, textColor.a );
-
-          if( impl.mController->GetDefaultColor() != textColor )
-          {
-            impl.mController->SetDefaultColor( textColor );
-            impl.mController->SetInputColor( textColor );
-            impl.mRenderer.Reset();
-          }
+          impl.mController->SetDefaultColor( textColor );
+          impl.mController->SetInputColor( textColor );
+          impl.mRenderer.Reset();
         }
         break;
       }
       case Toolkit::TextEditor::Property::FONT_FAMILY:
       {
-        if( impl.mController )
-        {
-          const std::string& fontFamily = value.Get< std::string >();
-          DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p FONT_FAMILY %s\n", impl.mController.Get(), fontFamily.c_str() );
-          impl.mController->SetDefaultFontFamily( fontFamily );
-        }
+        const std::string& fontFamily = value.Get< std::string >();
+        DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p FONT_FAMILY %s\n", impl.mController.Get(), fontFamily.c_str() );
+        impl.mController->SetDefaultFontFamily( fontFamily );
         break;
       }
       case Toolkit::TextEditor::Property::FONT_STYLE:
@@ -251,28 +248,22 @@ void TextEditor::SetProperty( BaseObject* object, Property::Index index, const P
       }
       case Toolkit::TextEditor::Property::POINT_SIZE:
       {
-        if( impl.mController )
-        {
-          const float pointSize = value.Get< float >();
-          DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p POINT_SIZE %f\n", impl.mController.Get(), pointSize );
+        const float pointSize = value.Get< float >();
+        DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p POINT_SIZE %f\n", impl.mController.Get(), pointSize );
 
-          if( !Equals( impl.mController->GetDefaultFontSize( Text::Controller::POINT_SIZE ), pointSize ) )
-          {
-            impl.mController->SetDefaultFontSize( pointSize, Text::Controller::POINT_SIZE );
-          }
+        if( !Equals( impl.mController->GetDefaultFontSize( Text::Controller::POINT_SIZE ), pointSize ) )
+        {
+          impl.mController->SetDefaultFontSize( pointSize, Text::Controller::POINT_SIZE );
         }
         break;
       }
       case Toolkit::TextEditor::Property::HORIZONTAL_ALIGNMENT:
       {
-        if( impl.mController )
+        Text::HorizontalAlignment::Type alignment( static_cast< Text::HorizontalAlignment::Type >( -1 ) ); // Set to invalid value to ensure a valid mode does get set
+        if( Text::GetHorizontalAlignmentEnumeration( value, alignment ) )
         {
-          Text::HorizontalAlignment::Type alignment( static_cast< Text::HorizontalAlignment::Type >( -1 ) ); // Set to invalid value to ensure a valid mode does get set
-          if( Text::GetHorizontalAlignmentEnumeration( value, alignment ) )
-          {
-            DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p HORIZONTAL_ALIGNMENT %d\n", impl.mController.Get(), alignment );
-            impl.mController->SetHorizontalAlignment( alignment );
-          }
+          DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p HORIZONTAL_ALIGNMENT %d\n", impl.mController.Get(), alignment );
+          impl.mController->SetHorizontalAlignment( alignment );
         }
         break;
       }
@@ -281,10 +272,7 @@ void TextEditor::SetProperty( BaseObject* object, Property::Index index, const P
         const float threshold = value.Get< float >();
         DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor %p SCROLL_THRESHOLD %f\n", impl.mController.Get(), threshold );
 
-        if( impl.mDecorator )
-        {
-          impl.mDecorator->SetScrollThreshold( threshold );
-        }
+        impl.mDecorator->SetScrollThreshold( threshold );
         break;
       }
       case Toolkit::TextEditor::Property::SCROLL_SPEED:
@@ -292,80 +280,59 @@ void TextEditor::SetProperty( BaseObject* object, Property::Index index, const P
         const float speed = value.Get< float >();
         DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor %p SCROLL_SPEED %f\n", impl.mController.Get(), speed );
 
-        if( impl.mDecorator )
-        {
-          impl.mDecorator->SetScrollSpeed( speed );
-        }
+        impl.mDecorator->SetScrollSpeed( speed );
         break;
       }
       case Toolkit::TextEditor::Property::PRIMARY_CURSOR_COLOR:
       {
-        if( impl.mDecorator )
-        {
-          const Vector4& color = value.Get< Vector4 >();
-          DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p PRIMARY_CURSOR_COLOR %f,%f,%f,%f\n", impl.mController.Get(), color.r, color.g, color.b, color.a );
+        const Vector4& color = value.Get< Vector4 >();
+        DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p PRIMARY_CURSOR_COLOR %f,%f,%f,%f\n", impl.mController.Get(), color.r, color.g, color.b, color.a );
 
-          impl.mDecorator->SetCursorColor( PRIMARY_CURSOR, color );
-          impl.RequestTextRelayout();
-        }
+        impl.mDecorator->SetCursorColor( PRIMARY_CURSOR, color );
+        impl.RequestTextRelayout();
         break;
       }
       case Toolkit::TextEditor::Property::SECONDARY_CURSOR_COLOR:
       {
-        if( impl.mDecorator )
-        {
-          const Vector4& color = value.Get< Vector4 >();
-          DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p SECONDARY_CURSOR_COLOR %f,%f,%f,%f\n", impl.mController.Get(), color.r, color.g, color.b, color.a );
+        const Vector4& color = value.Get< Vector4 >();
+        DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p SECONDARY_CURSOR_COLOR %f,%f,%f,%f\n", impl.mController.Get(), color.r, color.g, color.b, color.a );
 
-          impl.mDecorator->SetCursorColor( SECONDARY_CURSOR, color );
-          impl.RequestTextRelayout();
-        }
+        impl.mDecorator->SetCursorColor( SECONDARY_CURSOR, color );
+        impl.RequestTextRelayout();
         break;
       }
       case Toolkit::TextEditor::Property::ENABLE_CURSOR_BLINK:
       {
-        if( impl.mController )
-        {
-          const bool enable = value.Get< bool >();
-          DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor %p ENABLE_CURSOR_BLINK %d\n", impl.mController.Get(), enable );
+        const bool enable = value.Get< bool >();
+        DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor %p ENABLE_CURSOR_BLINK %d\n", impl.mController.Get(), enable );
 
-          impl.mController->SetEnableCursorBlink( enable );
-          impl.RequestTextRelayout();
-        }
+        impl.mController->SetEnableCursorBlink( enable );
+        impl.RequestTextRelayout();
         break;
       }
       case Toolkit::TextEditor::Property::CURSOR_BLINK_INTERVAL:
       {
-        if( impl.mDecorator )
-        {
-          const float interval = value.Get< float >();
-          DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor %p CURSOR_BLINK_INTERVAL %f\n", impl.mController.Get(), interval );
+        const float interval = value.Get< float >();
+        DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor %p CURSOR_BLINK_INTERVAL %f\n", impl.mController.Get(), interval );
 
-          impl.mDecorator->SetCursorBlinkInterval( interval );
-        }
+        impl.mDecorator->SetCursorBlinkInterval( interval );
         break;
       }
       case Toolkit::TextEditor::Property::CURSOR_BLINK_DURATION:
       {
-        if( impl.mDecorator )
-        {
-          const float duration = value.Get< float >();
-          DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor %p CURSOR_BLINK_DURATION %f\n", impl.mController.Get(), duration );
+        const float duration = value.Get< float >();
+        DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor %p CURSOR_BLINK_DURATION %f\n", impl.mController.Get(), duration );
 
-          impl.mDecorator->SetCursorBlinkDuration( duration );
-        }
+        impl.mDecorator->SetCursorBlinkDuration( duration );
         break;
       }
       case Toolkit::TextEditor::Property::CURSOR_WIDTH:
       {
-        if( impl.mDecorator )
-        {
-          const int width = value.Get< int >();
-          DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor %p CURSOR_WIDTH %d\n", impl.mController.Get(), width );
+        const int width = value.Get< int >();
+        DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor %p CURSOR_WIDTH %d\n", impl.mController.Get(), width );
 
-          impl.mDecorator->SetCursorWidth( width );
-          impl.mController->GetLayoutEngine().SetCursorWidth( width );
-        }
+        impl.mDecorator->SetCursorWidth( width );
+        impl.mController->GetLayoutEngine().SetCursorWidth( width );
         break;
       }
       case Toolkit::TextEditor::Property::GRAB_HANDLE_IMAGE:
@@ -373,7 +340,7 @@ void TextEditor::SetProperty( BaseObject* object, Property::Index index, const P
         const std::string imageFileName = value.Get< std::string >();
         DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor %p GRAB_HANDLE_IMAGE %s\n", impl.mController.Get(), imageFileName.c_str() );
 
-        if( impl.mDecorator && imageFileName.size() )
+        if( imageFileName.size() )
         {
           impl.mDecorator->SetHandleImage( GRAB_HANDLE, HANDLE_IMAGE_RELEASED, imageFileName );
           impl.RequestTextRelayout();
@@ -385,7 +352,7 @@ void TextEditor::SetProperty( BaseObject* object, Property::Index index, const P
         const std::string imageFileName = value.Get< std::string >();
         DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor %p GRAB_HANDLE_PRESSED_IMAGE %s\n", impl.mController.Get(), imageFileName.c_str() );
 
-        if( impl.mDecorator && imageFileName.size() )
+        if( imageFileName.size() )
         {
           impl.mDecorator->SetHandleImage( GRAB_HANDLE, HANDLE_IMAGE_PRESSED, imageFileName );
           impl.RequestTextRelayout();
@@ -396,7 +363,7 @@ void TextEditor::SetProperty( BaseObject* object, Property::Index index, const P
       {
         const std::string filename = GetImageFileNameFromPropertyValue( value );
 
-        if( impl.mDecorator && filename.size() )
+        if( filename.size() )
         {
           impl.mDecorator->SetHandleImage( LEFT_SELECTION_HANDLE, HANDLE_IMAGE_RELEASED, filename );
           impl.RequestTextRelayout();
@@ -407,7 +374,7 @@ void TextEditor::SetProperty( BaseObject* object, Property::Index index, const P
       {
         const std::string filename = GetImageFileNameFromPropertyValue( value );
 
-        if( impl.mDecorator && filename.size() )
+        if( filename.size() )
         {
           impl.mDecorator->SetHandleImage( RIGHT_SELECTION_HANDLE, HANDLE_IMAGE_RELEASED, filename );
           impl.RequestTextRelayout();
@@ -418,7 +385,7 @@ void TextEditor::SetProperty( BaseObject* object, Property::Index index, const P
       {
         const std::string filename = GetImageFileNameFromPropertyValue( value );
 
-        if( impl.mDecorator && filename.size() )
+        if( filename.size() )
         {
           impl.mDecorator->SetHandleImage( LEFT_SELECTION_HANDLE, HANDLE_IMAGE_PRESSED, filename );
           impl.RequestTextRelayout();
@@ -429,7 +396,7 @@ void TextEditor::SetProperty( BaseObject* object, Property::Index index, const P
       {
         const std::string filename = GetImageFileNameFromPropertyValue( value );
 
-        if( impl.mDecorator && filename.size() )
+        if( filename.size() )
         {
           impl.mDecorator->SetHandleImage( RIGHT_SELECTION_HANDLE, HANDLE_IMAGE_PRESSED, filename );
           impl.RequestTextRelayout();
@@ -440,7 +407,7 @@ void TextEditor::SetProperty( BaseObject* object, Property::Index index, const P
       {
         const std::string filename = GetImageFileNameFromPropertyValue( value );
 
-        if( impl.mDecorator && filename.size() )
+        if( filename.size() )
         {
           impl.mDecorator->SetHandleImage( LEFT_SELECTION_HANDLE_MARKER, HANDLE_IMAGE_RELEASED, filename );
           impl.RequestTextRelayout();
@@ -451,7 +418,7 @@ void TextEditor::SetProperty( BaseObject* object, Property::Index index, const P
       {
         const std::string filename = GetImageFileNameFromPropertyValue( value );
 
-        if( impl.mDecorator && filename.size() )
+        if( filename.size() )
         {
           impl.mDecorator->SetHandleImage( RIGHT_SELECTION_HANDLE_MARKER, HANDLE_IMAGE_RELEASED, filename );
           impl.RequestTextRelayout();
@@ -463,55 +430,40 @@ void TextEditor::SetProperty( BaseObject* object, Property::Index index, const P
         const Vector4 color = value.Get< Vector4 >();
         DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p SELECTION_HIGHLIGHT_COLOR %f,%f,%f,%f\n", impl.mController.Get(), color.r, color.g, color.b, color.a );
 
-        if( impl.mDecorator )
-        {
-          impl.mDecorator->SetHighlightColor( color );
-          impl.RequestTextRelayout();
-        }
+        impl.mDecorator->SetHighlightColor( color );
+        impl.RequestTextRelayout();
         break;
       }
       case Toolkit::TextEditor::Property::DECORATION_BOUNDING_BOX:
       {
-        if( impl.mDecorator )
-        {
-          const Rect<int>& box = value.Get< Rect<int> >();
-          DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p DECORATION_BOUNDING_BOX %d,%d %dx%d\n", impl.mController.Get(), box.x, box.y, box.width, box.height );
+        const Rect<int>& box = value.Get< Rect<int> >();
+        DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p DECORATION_BOUNDING_BOX %d,%d %dx%d\n", impl.mController.Get(), box.x, box.y, box.width, box.height );
 
-          impl.mDecorator->SetBoundingBox( box );
-          impl.RequestTextRelayout();
-        }
+        impl.mDecorator->SetBoundingBox( box );
+        impl.RequestTextRelayout();
         break;
       }
       case Toolkit::TextEditor::Property::ENABLE_MARKUP:
       {
-        if( impl.mController )
-        {
-          const bool enableMarkup = value.Get<bool>();
-          DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p ENABLE_MARKUP %d\n", impl.mController.Get(), enableMarkup );
+        const bool enableMarkup = value.Get<bool>();
+        DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p ENABLE_MARKUP %d\n", impl.mController.Get(), enableMarkup );
 
-          impl.mController->SetMarkupProcessorEnabled( enableMarkup );
-        }
+        impl.mController->SetMarkupProcessorEnabled( enableMarkup );
         break;
       }
       case Toolkit::TextEditor::Property::INPUT_COLOR:
       {
-        if( impl.mController )
-        {
-          const Vector4& inputColor = value.Get< Vector4 >();
-          DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p INPUT_COLOR %f,%f,%f,%f\n", impl.mController.Get(), inputColor.r, inputColor.g, inputColor.b, inputColor.a );
+        const Vector4& inputColor = value.Get< Vector4 >();
+        DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p INPUT_COLOR %f,%f,%f,%f\n", impl.mController.Get(), inputColor.r, inputColor.g, inputColor.b, inputColor.a );
 
-          impl.mController->SetInputColor( inputColor );
-        }
+        impl.mController->SetInputColor( inputColor );
         break;
       }
       case Toolkit::TextEditor::Property::INPUT_FONT_FAMILY:
       {
-        if( impl.mController )
-        {
-          const std::string& fontFamily = value.Get< std::string >();
-          DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p INPUT_FONT_FAMILY %s\n", impl.mController.Get(), fontFamily.c_str() );
-          impl.mController->SetInputFontFamily( fontFamily );
-        }
+        const std::string& fontFamily = value.Get< std::string >();
+        DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p INPUT_FONT_FAMILY %s\n", impl.mController.Get(), fontFamily.c_str() );
+        impl.mController->SetInputFontFamily( fontFamily );
         break;
       }
       case Toolkit::TextEditor::Property::INPUT_FONT_STYLE:
@@ -521,38 +473,28 @@ void TextEditor::SetProperty( BaseObject* object, Property::Index index, const P
       }
       case Toolkit::TextEditor::Property::INPUT_POINT_SIZE:
       {
-        if( impl.mController )
-        {
-          const float pointSize = value.Get< float >();
-          DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p INPUT_POINT_SIZE %f\n", impl.mController.Get(), pointSize );
-          impl.mController->SetInputFontPointSize( pointSize );
-        }
+        const float pointSize = value.Get< float >();
+        DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p INPUT_POINT_SIZE %f\n", impl.mController.Get(), pointSize );
+        impl.mController->SetInputFontPointSize( pointSize );
         break;
       }
       case Toolkit::TextEditor::Property::LINE_SPACING:
       {
-        if( impl.mController )
-        {
-
-          // The line spacing isn't supported by the TextEditor. Since it's supported
-          // by the TextLabel for now it must be ignored. The property is being shadowed
-          // locally so its value isn't affected.
-          const float lineSpacing = value.Get<float>();
-          impl.mLineSpacing = lineSpacing;
-          // set it to 0.0 due to missing implementation
-          impl.mController->SetDefaultLineSpacing( 0.0f );
-          impl.mRenderer.Reset();
-        }
+        // The line spacing isn't supported by the TextEditor. Since it's supported
+        // by the TextLabel for now it must be ignored. The property is being shadowed
+        // locally so its value isn't affected.
+        const float lineSpacing = value.Get<float>();
+        impl.mLineSpacing = lineSpacing;
+        // set it to 0.0 due to missing implementation
+        impl.mController->SetDefaultLineSpacing( 0.0f );
+        impl.mRenderer.Reset();
         break;
       }
       case Toolkit::TextEditor::Property::INPUT_LINE_SPACING:
       {
-        if( impl.mController )
-        {
-          const float lineSpacing = value.Get<float>();
-          impl.mController->SetInputLineSpacing( lineSpacing );
-          impl.mRenderer.Reset();
-        }
+        const float lineSpacing = value.Get<float>();
+        impl.mController->SetInputLineSpacing( lineSpacing );
+        impl.mRenderer.Reset();
         break;
       }
       case Toolkit::TextEditor::Property::UNDERLINE:
@@ -673,52 +615,40 @@ void TextEditor::SetProperty( BaseObject* object, Property::Index index, const P
       }
       case Toolkit::TextEditor::Property::PIXEL_SIZE:
       {
-        if( impl.mController )
-        {
-          const float pixelSize = value.Get< float >();
-          DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p PIXEL_SIZE %f\n", impl.mController.Get(), pixelSize );
+        const float pixelSize = value.Get< float >();
+        DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p PIXEL_SIZE %f\n", impl.mController.Get(), pixelSize );
 
-          if( !Equals( impl.mController->GetDefaultFontSize( Text::Controller::PIXEL_SIZE ), pixelSize ) )
-          {
-            impl.mController->SetDefaultFontSize( pixelSize, Text::Controller::PIXEL_SIZE );
-          }
+        if( !Equals( impl.mController->GetDefaultFontSize( Text::Controller::PIXEL_SIZE ), pixelSize ) )
+        {
+          impl.mController->SetDefaultFontSize( pixelSize, Text::Controller::PIXEL_SIZE );
         }
         break;
       }
       case Toolkit::DevelTextEditor::Property::PLACEHOLDER_TEXT:
       {
-        if( impl.mController )
-        {
-          const std::string& text = value.Get< std::string >();
-          DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor::OnPropertySet %p PLACEHOLDER_TEXT %s\n", impl.mController.Get(), text.c_str() );
+        const std::string& text = value.Get< std::string >();
+        DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor::OnPropertySet %p PLACEHOLDER_TEXT %s\n", impl.mController.Get(), text.c_str() );
 
-          impl.mController->SetPlaceholderText( Controller::PLACEHOLDER_TYPE_INACTIVE, text );
-        }
+        impl.mController->SetPlaceholderText( Controller::PLACEHOLDER_TYPE_INACTIVE, text );
         break;
       }
       case Toolkit::DevelTextEditor::Property::PLACEHOLDER_TEXT_COLOR:
       {
-        if( impl.mController )
+        const Vector4& textColor = value.Get< Vector4 >();
+        DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p PLACEHOLDER_TEXT_COLOR %f,%f,%f,%f\n", impl.mController.Get(), textColor.r, textColor.g, textColor.b, textColor.a );
+
+        if( impl.mController->GetPlaceholderTextColor() != textColor )
         {
-          const Vector4& textColor = value.Get< Vector4 >();
-          DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p PLACEHOLDER_TEXT_COLOR %f,%f,%f,%f\n", impl.mController.Get(), textColor.r, textColor.g, textColor.b, textColor.a );
-
-          if( impl.mController->GetPlaceholderTextColor() != textColor )
-          {
-            impl.mController->SetPlaceholderTextColor( textColor );
-            impl.mRenderer.Reset();
-          }
+          impl.mController->SetPlaceholderTextColor( textColor );
+          impl.mRenderer.Reset();
         }
         break;
       }
       case Toolkit::TextEditor::Property::ENABLE_SELECTION:
       {
-        if( impl.mController )
-        {
-          const bool enableSelection = value.Get< bool >();
-          DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p ENABLE_SELECTION %d\n", impl.mController.Get(), enableSelection );
-          impl.mController->SetSelectionEnabled( enableSelection );
-        }
+        const bool enableSelection = value.Get< bool >();
+        DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p ENABLE_SELECTION %d\n", impl.mController.Get(), enableSelection );
+        impl.mController->SetSelectionEnabled( enableSelection );
         break;
       }
       case Toolkit::TextEditor::Property::PLACEHOLDER:
@@ -732,58 +662,70 @@ void TextEditor::SetProperty( BaseObject* object, Property::Index index, const P
       }
       case Toolkit::TextEditor::Property::LINE_WRAP_MODE:
       {
-        if( impl.mController )
+        Text::LineWrap::Mode lineWrapMode( static_cast< Text::LineWrap::Mode >( -1 ) ); // Set to invalid value to ensure a valid mode does get set
+        if( GetLineWrapModeEnumeration( value, lineWrapMode ) )
         {
-          Text::LineWrap::Mode lineWrapMode( static_cast< Text::LineWrap::Mode >( -1 ) ); // Set to invalid value to ensure a valid mode does get set
-          if( GetLineWrapModeEnumeration( value, lineWrapMode ) )
-          {
-            DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p LineWrap::MODE %d\n", impl.mController.Get(), lineWrapMode );
-            impl.mController->SetLineWrapMode( lineWrapMode );
-          }
+          DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p LineWrap::MODE %d\n", impl.mController.Get(), lineWrapMode );
+          impl.mController->SetLineWrapMode( lineWrapMode );
         }
         break;
       }
       case Toolkit::DevelTextEditor::Property::ENABLE_SHIFT_SELECTION:
       {
-        if( impl.mController )
-        {
-          const bool shiftSelection = value.Get<bool>();
-          DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p ENABLE_SHIFT_SELECTION %d\n", impl.mController.Get(), shiftSelection );
+        const bool shiftSelection = value.Get<bool>();
+        DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p ENABLE_SHIFT_SELECTION %d\n", impl.mController.Get(), shiftSelection );
 
-          impl.mController->SetShiftSelectionEnabled( shiftSelection );
-        }
+        impl.mController->SetShiftSelectionEnabled( shiftSelection );
         break;
       }
       case Toolkit::DevelTextEditor::Property::ENABLE_GRAB_HANDLE:
       {
-        if( impl.mController )
-        {
-          const bool grabHandleEnabled = value.Get<bool>();
-          DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p ENABLE_GRAB_HANDLE %d\n", impl.mController.Get(), grabHandleEnabled );
+        const bool grabHandleEnabled = value.Get<bool>();
+        DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p ENABLE_GRAB_HANDLE %d\n", impl.mController.Get(), grabHandleEnabled );
 
-          impl.mController->SetGrabHandleEnabled( grabHandleEnabled );
-        }
+        impl.mController->SetGrabHandleEnabled( grabHandleEnabled );
         break;
       }
       case Toolkit::DevelTextEditor::Property::MATCH_SYSTEM_LANGUAGE_DIRECTION:
       {
+        impl.mController->SetMatchSystemLanguageDirection(value.Get< bool >());
+        break;
+      }
+      case Toolkit::DevelTextEditor::Property::MAX_LENGTH:
+      {
+        const int max = value.Get< int >();
+        DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p MAX_LENGTH %d\n", impl.mController.Get(), max );
+
+        impl.mController->SetMaximumNumberOfCharacters( max );
+        break;
+      }
+      case Toolkit::DevelTextEditor::Property::SELECTED_TEXT_START:
+      {
         if( impl.mController )
         {
-          impl.mController->SetMatchSystemLanguageDirection(value.Get< bool >());
+          uint32_t start = static_cast<uint32_t>(value.Get< int >());
+          DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p SELECTED_TEXT_START %d\n", impl.mController.Get(), start );
+          impl.SetTextSelectionRange( &start, nullptr );
         }
         break;
       }
-      case Toolkit::DevelTextEditor::Property::MAX_LENGTH:
+      case Toolkit::DevelTextEditor::Property::SELECTED_TEXT_END:
       {
         if( impl.mController )
         {
-          const int max = value.Get< int >();
-          DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p MAX_LENGTH %d\n", impl.mController.Get(), max );
-
-          impl.mController->SetMaximumNumberOfCharacters( max );
+          uint32_t end = static_cast<uint32_t>(value.Get< int >());
+          DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p SELECTED_TEXT_END %d\n", impl.mController.Get(), end );
+          impl.SetTextSelectionRange( nullptr, &end );
         }
         break;
       }
+      case Toolkit::DevelTextEditor::Property::ENABLE_EDITING:
+      {
+        const bool editable = value.Get< bool >();
+        DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p ENABLE_EDITING %d\n", impl.mController.Get(), editable );
+        impl.SetEditable( editable );
+        break;
+      }
     } // switch
   } // texteditor
 }
@@ -797,6 +739,8 @@ Property::Value TextEditor::GetProperty( BaseObject* object, Property::Index ind
   if( textEditor )
   {
     TextEditor& impl( GetImpl( textEditor ) );
+    DALI_ASSERT_DEBUG( impl.mController && "No text contoller" );
+    DALI_ASSERT_DEBUG( impl.mDecorator && "No text decorator" );
 
     switch( index )
     {
@@ -807,29 +751,20 @@ Property::Value TextEditor::GetProperty( BaseObject* object, Property::Index ind
       }
       case Toolkit::TextEditor::Property::TEXT:
       {
-        if( impl.mController )
-        {
-          std::string text;
-          impl.mController->GetText( text );
-          DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p returning text: %s\n", impl.mController.Get(), text.c_str() );
-          value = text;
-        }
+        std::string text;
+        impl.mController->GetText( text );
+        DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p returning text: %s\n", impl.mController.Get(), text.c_str() );
+        value = text;
         break;
       }
       case Toolkit::TextEditor::Property::TEXT_COLOR:
       {
-        if ( impl.mController )
-        {
-          value = impl.mController->GetDefaultColor();
-        }
+        value = impl.mController->GetDefaultColor();
         break;
       }
       case Toolkit::TextEditor::Property::FONT_FAMILY:
       {
-        if( impl.mController )
-        {
-          value = impl.mController->GetDefaultFontFamily();
-        }
+        value = impl.mController->GetDefaultFontFamily();
         break;
       }
       case Toolkit::TextEditor::Property::FONT_STYLE:
@@ -839,54 +774,36 @@ Property::Value TextEditor::GetProperty( BaseObject* object, Property::Index ind
       }
       case Toolkit::TextEditor::Property::POINT_SIZE:
       {
-        if( impl.mController )
-        {
-          value = impl.mController->GetDefaultFontSize( Text::Controller::POINT_SIZE );
-        }
+        value = impl.mController->GetDefaultFontSize( Text::Controller::POINT_SIZE );
         break;
       }
       case Toolkit::TextEditor::Property::HORIZONTAL_ALIGNMENT:
       {
-        if( impl.mController )
+        const char* name = GetHorizontalAlignmentString( impl.mController->GetHorizontalAlignment() );
+        if( name )
         {
-          const char* name = GetHorizontalAlignmentString( impl.mController->GetHorizontalAlignment() );
-          if( name )
-          {
-            value = std::string( name );
-          }
+          value = std::string( name );
         }
         break;
       }
       case Toolkit::TextEditor::Property::SCROLL_THRESHOLD:
       {
-        if( impl.mDecorator )
-        {
-          value = impl.mDecorator->GetScrollThreshold();
-        }
+        value = impl.mDecorator->GetScrollThreshold();
         break;
       }
       case Toolkit::TextEditor::Property::SCROLL_SPEED:
       {
-        if( impl.mDecorator )
-        {
-          value = impl.mDecorator->GetScrollSpeed();
-        }
+        value = impl.mDecorator->GetScrollSpeed();
         break;
       }
       case Toolkit::TextEditor::Property::PRIMARY_CURSOR_COLOR:
       {
-        if( impl.mDecorator )
-        {
-          value = impl.mDecorator->GetColor( PRIMARY_CURSOR );
-        }
+        value = impl.mDecorator->GetColor( PRIMARY_CURSOR );
         break;
       }
       case Toolkit::TextEditor::Property::SECONDARY_CURSOR_COLOR:
       {
-        if( impl.mDecorator )
-        {
-          value = impl.mDecorator->GetColor( SECONDARY_CURSOR );
-        }
+        value = impl.mDecorator->GetColor( SECONDARY_CURSOR );
         break;
       }
       case Toolkit::TextEditor::Property::ENABLE_CURSOR_BLINK:
@@ -896,42 +813,27 @@ Property::Value TextEditor::GetProperty( BaseObject* object, Property::Index ind
       }
       case Toolkit::TextEditor::Property::CURSOR_BLINK_INTERVAL:
       {
-        if( impl.mDecorator )
-        {
-          value = impl.mDecorator->GetCursorBlinkInterval();
-        }
+        value = impl.mDecorator->GetCursorBlinkInterval();
         break;
       }
       case Toolkit::TextEditor::Property::CURSOR_BLINK_DURATION:
       {
-        if( impl.mDecorator )
-        {
-          value = impl.mDecorator->GetCursorBlinkDuration();
-        }
+        value = impl.mDecorator->GetCursorBlinkDuration();
         break;
       }
       case Toolkit::TextEditor::Property::CURSOR_WIDTH:
       {
-        if( impl.mDecorator )
-        {
-          value = impl.mDecorator->GetCursorWidth();
-        }
+        value = impl.mDecorator->GetCursorWidth();
         break;
       }
       case Toolkit::TextEditor::Property::GRAB_HANDLE_IMAGE:
       {
-        if( impl.mDecorator )
-        {
-          value = impl.mDecorator->GetHandleImage( GRAB_HANDLE, HANDLE_IMAGE_RELEASED );
-        }
+        value = impl.mDecorator->GetHandleImage( GRAB_HANDLE, HANDLE_IMAGE_RELEASED );
         break;
       }
       case Toolkit::TextEditor::Property::GRAB_HANDLE_PRESSED_IMAGE:
       {
-        if( impl.mDecorator )
-        {
-          value = impl.mDecorator->GetHandleImage( GRAB_HANDLE, HANDLE_IMAGE_PRESSED );
-        }
+        value = impl.mDecorator->GetHandleImage( GRAB_HANDLE, HANDLE_IMAGE_PRESSED );
         break;
       }
       case Toolkit::TextEditor::Property::SELECTION_HANDLE_IMAGE_LEFT:
@@ -966,44 +868,29 @@ Property::Value TextEditor::GetProperty( BaseObject* object, Property::Index ind
       }
       case Toolkit::TextEditor::Property::SELECTION_HIGHLIGHT_COLOR:
       {
-        if( impl.mDecorator )
-        {
-          value = impl.mDecorator->GetHighlightColor();
-        }
+        value = impl.mDecorator->GetHighlightColor();
         break;
       }
       case Toolkit::TextEditor::Property::DECORATION_BOUNDING_BOX:
       {
-        if( impl.mDecorator )
-        {
-          Rect<int> boundingBox;
-          impl.mDecorator->GetBoundingBox( boundingBox );
-          value = boundingBox;
-        }
+        Rect<int> boundingBox;
+        impl.mDecorator->GetBoundingBox( boundingBox );
+        value = boundingBox;
         break;
       }
       case Toolkit::TextEditor::Property::ENABLE_MARKUP:
       {
-        if( impl.mController )
-        {
-          value = impl.mController->IsMarkupProcessorEnabled();
-        }
+        value = impl.mController->IsMarkupProcessorEnabled();
         break;
       }
       case Toolkit::TextEditor::Property::INPUT_COLOR:
       {
-        if( impl.mController )
-        {
-          value = impl.mController->GetInputColor();
-        }
+        value = impl.mController->GetInputColor();
         break;
       }
       case Toolkit::TextEditor::Property::INPUT_FONT_FAMILY:
       {
-        if( impl.mController )
-        {
-          value = impl.mController->GetInputFontFamily();
-        }
+        value = impl.mController->GetInputFontFamily();
         break;
       }
       case Toolkit::TextEditor::Property::INPUT_FONT_STYLE:
@@ -1013,28 +900,19 @@ Property::Value TextEditor::GetProperty( BaseObject* object, Property::Index ind
       }
       case Toolkit::TextEditor::Property::INPUT_POINT_SIZE:
       {
-        if( impl.mController )
-        {
-          value = impl.mController->GetInputFontPointSize();
-        }
+        value = impl.mController->GetInputFontPointSize();
         break;
       }
       case Toolkit::TextEditor::Property::LINE_SPACING:
       {
-        if( impl.mController )
-        {
-          // LINE_SPACING isn't implemented for the TextEditor. Returning
-          // only shadowed value, not the real one.
-          value = impl.mLineSpacing;
-        }
+        // LINE_SPACING isn't implemented for the TextEditor. Returning
+        // only shadowed value, not the real one.
+        value = impl.mLineSpacing;
         break;
       }
       case Toolkit::TextEditor::Property::INPUT_LINE_SPACING:
       {
-        if( impl.mController )
-        {
-          value = impl.mController->GetInputLineSpacing();
-        }
+        value = impl.mController->GetInputLineSpacing();
         break;
       }
       case Toolkit::TextEditor::Property::UNDERLINE:
@@ -1104,45 +982,30 @@ Property::Value TextEditor::GetProperty( BaseObject* object, Property::Index ind
       }
       case Toolkit::TextEditor::Property::PIXEL_SIZE:
       {
-        if( impl.mController )
-        {
-          value = impl.mController->GetDefaultFontSize( Text::Controller::PIXEL_SIZE );
-        }
+        value = impl.mController->GetDefaultFontSize( Text::Controller::PIXEL_SIZE );
         break;
       }
       case Toolkit::TextEditor::Property::LINE_COUNT:
       {
-        if( impl.mController )
-        {
-          float width = textEditor.GetProperty( Actor::Property::SIZE_WIDTH ).Get<float>();
-          value = impl.mController->GetLineCount( width );
-        }
+        float width = textEditor.GetProperty( Actor::Property::SIZE_WIDTH ).Get<float>();
+        value = impl.mController->GetLineCount( width );
         break;
       }
       case Toolkit::DevelTextEditor::Property::PLACEHOLDER_TEXT:
       {
-        if( impl.mController )
-        {
-          std::string text;
-          impl.mController->GetPlaceholderText( Controller::PLACEHOLDER_TYPE_INACTIVE, text );
-          value = text;
-        }
+        std::string text;
+        impl.mController->GetPlaceholderText( Controller::PLACEHOLDER_TYPE_INACTIVE, text );
+        value = text;
         break;
       }
       case Toolkit::DevelTextEditor::Property::PLACEHOLDER_TEXT_COLOR:
       {
-        if( impl.mController )
-        {
-          value = impl.mController->GetPlaceholderTextColor();
-        }
+        value = impl.mController->GetPlaceholderTextColor();
         break;
       }
       case Toolkit::TextEditor::Property::ENABLE_SELECTION:
       {
-        if( impl.mController )
-        {
-          value = impl.mController->IsSelectionEnabled();
-        }
+        value = impl.mController->IsSelectionEnabled();
         break;
       }
       case Toolkit::TextEditor::Property::PLACEHOLDER:
@@ -1154,42 +1017,44 @@ Property::Value TextEditor::GetProperty( BaseObject* object, Property::Index ind
       }
       case Toolkit::TextEditor::Property::LINE_WRAP_MODE:
       {
-        if( impl.mController )
-        {
-          value = impl.mController->GetLineWrapMode();
-        }
+        value = impl.mController->GetLineWrapMode();
         break;
       }
       case Toolkit::DevelTextEditor::Property::ENABLE_SHIFT_SELECTION:
       {
-        if( impl.mController )
-        {
-          value = impl.mController->IsShiftSelectionEnabled();
-        }
+        value = impl.mController->IsShiftSelectionEnabled();
         break;
       }
       case Toolkit::DevelTextEditor::Property::ENABLE_GRAB_HANDLE:
       {
-        if( impl.mController )
-        {
-          value = impl.mController->IsGrabHandleEnabled();
-        }
+        value = impl.mController->IsGrabHandleEnabled();
         break;
       }
       case Toolkit::DevelTextEditor::Property::MATCH_SYSTEM_LANGUAGE_DIRECTION:
       {
-        if( impl.mController )
-        {
-          value = impl.mController->IsMatchSystemLanguageDirection();
-        }
+        value = impl.mController->IsMatchSystemLanguageDirection();
         break;
       }
       case Toolkit::DevelTextEditor::Property::MAX_LENGTH:
       {
-        if( impl.mController )
-        {
-          value = impl.mController->GetMaximumNumberOfCharacters();
-        }
+        value = impl.mController->GetMaximumNumberOfCharacters();
+        break;
+      }
+      case Toolkit::DevelTextEditor::Property::SELECTED_TEXT_START:
+      {
+        Uint32Pair range = impl.GetTextSelectionRange();
+        value = static_cast<int>(range.first);
+        break;
+      }
+      case Toolkit::DevelTextEditor::Property::SELECTED_TEXT_END:
+      {
+        Uint32Pair range = impl.GetTextSelectionRange();
+        value = static_cast<int>(range.second);
+        break;
+      }
+      case Toolkit::DevelTextEditor::Property::ENABLE_EDITING:
+      {
+        value = impl.IsEditable();
         break;
       }
     } //switch
@@ -1259,7 +1124,7 @@ void TextEditor::OnInitialize()
 {
   Actor self = Self();
 
-  mController = Text::Controller::New( this, this );
+  mController = Text::Controller::New( this, this, this);
 
   mDecorator = Text::Decorator::New( *mController,
                                      *mController );
@@ -1515,7 +1380,7 @@ void TextEditor::RenderText( Text::Controller::UpdateTextType updateTextType )
 void TextEditor::OnKeyInputFocusGained()
 {
   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor::OnKeyInputFocusGained %p\n", mController.Get() );
-  if ( mInputMethodContext )
+  if ( mInputMethodContext  && IsEditable() )
   {
     mInputMethodContext.StatusChangedSignal().Connect( this, &TextEditor::KeyboardStatusChanged );
 
@@ -1569,7 +1434,7 @@ void TextEditor::OnKeyInputFocusLost()
 void TextEditor::OnTap( const TapGesture& gesture )
 {
   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor::OnTap %p\n", mController.Get() );
-  if ( mInputMethodContext )
+  if ( mInputMethodContext && IsEditable() )
   {
     mInputMethodContext.Activate();
   }
@@ -1589,7 +1454,7 @@ void TextEditor::OnPan( const PanGesture& gesture )
 
 void TextEditor::OnLongPress( const LongPressGesture& gesture )
 {
-  if ( mInputMethodContext )
+  if ( mInputMethodContext && IsEditable() )
   {
     mInputMethodContext.Activate();
   }
@@ -1708,6 +1573,25 @@ void TextEditor::AddDecoration( Actor& actor, bool needsClipping )
   }
 }
 
+void TextEditor::SetTextSelectionRange(const uint32_t *start, const uint32_t *end)
+{
+  if( mController && mController->IsShowingRealText() )
+  {
+    mController->SetTextSelectionRange( start, end );
+    SetKeyInputFocus();
+  }
+}
+
+Uint32Pair TextEditor::GetTextSelectionRange() const
+{
+  Uint32Pair range(0, 0);
+  if( mController && mController->IsShowingRealText() )
+  {
+    range = mController->GetTextSelectionRange();
+  }
+  return range;
+}
+
 void TextEditor::UpdateScrollBar()
 {
   using namespace Dali;
@@ -1905,6 +1789,20 @@ void TextEditor::ApplyScrollPosition()
   }
 }
 
+bool TextEditor::IsEditable() const
+{
+  return mController->IsEditable();
+}
+
+void TextEditor::SetEditable( bool editable )
+{
+  mController->SetEditable(editable);
+  if ( mInputMethodContext && !editable )
+  {
+    mInputMethodContext.Deactivate();
+  }
+}
+
 TextEditor::TextEditor()
 : Control( ControlBehaviour( CONTROL_BEHAVIOUR_DEFAULT ) ),
   mAnimationPeriod( 0.0f, 0.0f ),
index d51ba2a..a149a79 100755 (executable)
@@ -31,6 +31,7 @@
 #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-selectable-control-interface.h>
 #include <dali-toolkit/internal/text/text-controller.h>
 #include <dali-toolkit/internal/text/text-vertical-scroller.h>
 #include <dali-toolkit/internal/text/rendering/text-renderer.h>
@@ -46,7 +47,7 @@ namespace Internal
 /**
  * @brief A control which renders a long text string with styles.
  */
-class TextEditor : public Control, public Text::ControlInterface, public Text::EditableControlInterface
+class TextEditor : public Control, public Text::ControlInterface, public Text::EditableControlInterface, public Text::SelectableControlInterface
 {
 public:
 
@@ -202,6 +203,28 @@ private: // From Control
    */
   void AddDecoration( Actor& actor, bool needsClipping ) override;
 
+// From SelectableControlInterface
+public:
+  /**
+   * @copydoc Text::SelectableControlInterface::SetTextSelectionRange()
+   */
+  void SetTextSelectionRange(const uint32_t *start, const uint32_t *end) override;
+
+  /**
+   * @copydoc Text::SelectableControlInterface::GetTextSelectionRange()
+   */
+  Uint32Pair GetTextSelectionRange() const override;
+
+  /**
+   * @copydoc Text::EditableControlInterface::IsEditable()
+   */
+  bool IsEditable() const override;
+
+  /**
+   * @copydoc Text::EditableControlInterface::SetEditable()
+   */
+  void SetEditable( bool editable ) override;
+
 private: // Implementation
 
   /**
index dfe68d1..c038d08 100644 (file)
@@ -21,6 +21,7 @@
 // EXTERNAL INCLUDES
 #include <cstring>
 #include <dali/public-api/adaptor-framework/key.h>
+#include <dali/public-api/common/dali-common.h>
 #include <dali/devel-api/adaptor-framework/key-devel.h>
 #include <dali/devel-api/adaptor-framework/window-devel.h>
 #include <dali/devel-api/common/stage.h>
@@ -134,6 +135,9 @@ DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextField, "enableGrabHandlePopup",
 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextField, "textBackground",                 VECTOR4,   BACKGROUND                           )
 DALI_DEVEL_PROPERTY_REGISTRATION_READ_ONLY( Toolkit, TextField, "selectedText",         STRING,    SELECTED_TEXT                        )
 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextField, "renderingBackend",               INTEGER,   RENDERING_BACKEND                    )
+DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextField, "selectedTextStart",              INTEGER,   SELECTED_TEXT_START                  )
+DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextField, "selectedTextEnd",                INTEGER,   SELECTED_TEXT_END                    )
+DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextField, "enableEditing",                  BOOLEAN,   ENABLE_EDITING                       )
 
 DALI_SIGNAL_REGISTRATION( Toolkit, TextField, "textChanged",        SIGNAL_TEXT_CHANGED )
 DALI_SIGNAL_REGISTRATION( Toolkit, TextField, "maxLengthReached",   SIGNAL_MAX_LENGTH_REACHED )
@@ -182,10 +186,11 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
 
   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField SetProperty\n");
 
-
   if( textField )
   {
     TextField& impl( GetImpl( textField ) );
+    DALI_ASSERT_DEBUG( impl.mController && "No text contoller" );
+    DALI_ASSERT_DEBUG( impl.mDecorator && "No text decorator" );
 
     switch( index )
     {
@@ -205,56 +210,41 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
           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 = (DevelText::RENDERING_VECTOR_BASED == impl.mRenderingBackend) ? TextAbstraction::VECTOR_GLYPH : TextAbstraction::BITMAP_GLYPH;
-            impl.mController->SetGlyphType( glyphType );
-          }
+          // When using the vector-based rendering, the size of the GLyphs are different
+          TextAbstraction::GlyphType glyphType = (DevelText::RENDERING_VECTOR_BASED == impl.mRenderingBackend) ? TextAbstraction::VECTOR_GLYPH : TextAbstraction::BITMAP_GLYPH;
+          impl.mController->SetGlyphType( glyphType );
         }
         break;
       }
       case Toolkit::TextField::Property::TEXT:
       {
-        if( impl.mController )
-        {
-          const std::string& text = value.Get< std::string >();
-          DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p TEXT %s\n", impl.mController.Get(), text.c_str() );
+        const std::string& text = value.Get< std::string >();
+        DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p TEXT %s\n", impl.mController.Get(), text.c_str() );
 
-          impl.mController->SetText( text );
-        }
+        impl.mController->SetText( text );
         break;
       }
       case Toolkit::TextField::Property::PLACEHOLDER_TEXT:
       {
-        if( impl.mController )
-        {
-          const std::string& text = value.Get< std::string >();
-          DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p PLACEHOLDER_TEXT %s\n", impl.mController.Get(), text.c_str() );
+        const std::string& text = value.Get< std::string >();
+        DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p PLACEHOLDER_TEXT %s\n", impl.mController.Get(), text.c_str() );
 
-          impl.mController->SetPlaceholderText( Controller::PLACEHOLDER_TYPE_INACTIVE, text );
-        }
+        impl.mController->SetPlaceholderText( Controller::PLACEHOLDER_TYPE_INACTIVE, text );
         break;
       }
       case Toolkit::TextField::Property::PLACEHOLDER_TEXT_FOCUSED:
       {
-        if( impl.mController )
-        {
-          const std::string& text = value.Get< std::string >();
-          DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p PLACEHOLDER_TEXT_FOCUSED %s\n", impl.mController.Get(), text.c_str() );
+        const std::string& text = value.Get< std::string >();
+        DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p PLACEHOLDER_TEXT_FOCUSED %s\n", impl.mController.Get(), text.c_str() );
 
-          impl.mController->SetPlaceholderText( Controller::PLACEHOLDER_TYPE_ACTIVE, text );
-        }
+        impl.mController->SetPlaceholderText( Controller::PLACEHOLDER_TYPE_ACTIVE, text );
         break;
       }
       case Toolkit::TextField::Property::FONT_FAMILY:
       {
-        if( impl.mController )
-        {
-          const std::string& fontFamily = value.Get< std::string >();
-          DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p FONT_FAMILY %s\n", impl.mController.Get(), fontFamily.c_str() );
-          impl.mController->SetDefaultFontFamily( fontFamily );
-        }
+        const std::string& fontFamily = value.Get< std::string >();
+        DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p FONT_FAMILY %s\n", impl.mController.Get(), fontFamily.c_str() );
+        impl.mController->SetDefaultFontFamily( fontFamily );
         break;
       }
       case Toolkit::TextField::Property::FONT_STYLE:
@@ -264,27 +254,21 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
       }
       case Toolkit::TextField::Property::POINT_SIZE:
       {
-        if( impl.mController )
-        {
-          const float pointSize = value.Get< float >();
-          DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p POINT_SIZE %f\n", impl.mController.Get(), pointSize );
+        const float pointSize = value.Get< float >();
+        DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p POINT_SIZE %f\n", impl.mController.Get(), pointSize );
 
-          if( !Equals( impl.mController->GetDefaultFontSize( Text::Controller::POINT_SIZE ), pointSize ) )
-          {
-            impl.mController->SetDefaultFontSize( pointSize, Text::Controller::POINT_SIZE );
-          }
+        if( !Equals( impl.mController->GetDefaultFontSize( Text::Controller::POINT_SIZE ), pointSize ) )
+        {
+          impl.mController->SetDefaultFontSize( pointSize, Text::Controller::POINT_SIZE );
         }
         break;
       }
       case Toolkit::TextField::Property::MAX_LENGTH:
       {
-        if( impl.mController )
-        {
-          const int max = value.Get< int >();
-          DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p MAX_LENGTH %d\n", impl.mController.Get(), max );
+        const int max = value.Get< int >();
+        DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p MAX_LENGTH %d\n", impl.mController.Get(), max );
 
-          impl.mController->SetMaximumNumberOfCharacters( max );
-        }
+        impl.mController->SetMaximumNumberOfCharacters( max );
         break;
       }
       case Toolkit::TextField::Property::EXCEED_POLICY:
@@ -304,129 +288,99 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
       }
       case Toolkit::TextField::Property::HORIZONTAL_ALIGNMENT:
       {
-        if( impl.mController )
+        Text::HorizontalAlignment::Type alignment( static_cast< Text::HorizontalAlignment::Type >( -1 ) ); // Set to invalid value to ensure a valid mode does get set
+        if( GetHorizontalAlignmentEnumeration( value, alignment ) )
         {
-          Text::HorizontalAlignment::Type alignment( static_cast< Text::HorizontalAlignment::Type >( -1 ) ); // Set to invalid value to ensure a valid mode does get set
-          if( GetHorizontalAlignmentEnumeration( value, alignment ) )
-          {
-            DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p HORIZONTAL_ALIGNMENT %d\n", impl.mController.Get(), alignment );
-            impl.mController->SetHorizontalAlignment( alignment );
-          }
+          DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p HORIZONTAL_ALIGNMENT %d\n", impl.mController.Get(), alignment );
+          impl.mController->SetHorizontalAlignment( alignment );
         }
         break;
       }
       case Toolkit::TextField::Property::VERTICAL_ALIGNMENT:
       {
-        if( impl.mController )
+        Toolkit::Text::VerticalAlignment::Type alignment( static_cast< Text::VerticalAlignment::Type >( -1 ) ); // Set to invalid value to ensure a valid mode does get set
+        if( GetVerticalAlignmentEnumeration( value, alignment ) )
         {
-          Toolkit::Text::VerticalAlignment::Type alignment( static_cast< Text::VerticalAlignment::Type >( -1 ) ); // Set to invalid value to ensure a valid mode does get set
-          if( GetVerticalAlignmentEnumeration( value, alignment ) )
-          {
-            impl.mController->SetVerticalAlignment( alignment );
-            DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p VERTICAL_ALIGNMENT %d\n", impl.mController.Get(), alignment );
-          }
+          impl.mController->SetVerticalAlignment( alignment );
+          DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p VERTICAL_ALIGNMENT %d\n", impl.mController.Get(), alignment );
         }
         break;
       }
       case Toolkit::TextField::Property::TEXT_COLOR:
       {
-        if( impl.mController )
+        const Vector4& textColor = value.Get< Vector4 >();
+        DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p TEXT_COLOR %f,%f,%f,%f\n", impl.mController.Get(), textColor.r, textColor.g, textColor.b, textColor.a );
+
+        if( impl.mController->GetDefaultColor() != textColor )
         {
-          const Vector4& textColor = value.Get< Vector4 >();
-          DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p TEXT_COLOR %f,%f,%f,%f\n", impl.mController.Get(), textColor.r, textColor.g, textColor.b, textColor.a );
-
-          if( impl.mController->GetDefaultColor() != textColor )
-          {
-            impl.mController->SetDefaultColor( textColor );
-            impl.mController->SetInputColor( textColor );
-            impl.mRenderer.Reset();
-          }
+          impl.mController->SetDefaultColor( textColor );
+          impl.mController->SetInputColor( textColor );
+          impl.mRenderer.Reset();
         }
         break;
       }
       case Toolkit::TextField::Property::PLACEHOLDER_TEXT_COLOR:
       {
-        if( impl.mController )
+        const Vector4& textColor = value.Get< Vector4 >();
+        DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p PLACEHOLDER_TEXT_COLOR %f,%f,%f,%f\n", impl.mController.Get(), textColor.r, textColor.g, textColor.b, textColor.a );
+
+        if( impl.mController->GetPlaceholderTextColor() != textColor )
         {
-          const Vector4& textColor = value.Get< Vector4 >();
-          DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p PLACEHOLDER_TEXT_COLOR %f,%f,%f,%f\n", impl.mController.Get(), textColor.r, textColor.g, textColor.b, textColor.a );
-
-          if( impl.mController->GetPlaceholderTextColor() != textColor )
-          {
-            impl.mController->SetPlaceholderTextColor( textColor );
-            impl.mRenderer.Reset();
-          }
+          impl.mController->SetPlaceholderTextColor( textColor );
+          impl.mRenderer.Reset();
         }
         break;
       }
       case Toolkit::TextField::Property::PRIMARY_CURSOR_COLOR:
       {
-        if( impl.mDecorator )
-        {
-          const Vector4& color = value.Get< Vector4 >();
-          DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p PRIMARY_CURSOR_COLOR %f,%f,%f,%f\n", impl.mController.Get(), color.r, color.g, color.b, color.a );
+        const Vector4& color = value.Get< Vector4 >();
+        DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p PRIMARY_CURSOR_COLOR %f,%f,%f,%f\n", impl.mController.Get(), color.r, color.g, color.b, color.a );
 
-          impl.mDecorator->SetCursorColor( PRIMARY_CURSOR, color );
-          impl.RequestTextRelayout();
-        }
+        impl.mDecorator->SetCursorColor( PRIMARY_CURSOR, color );
+        impl.RequestTextRelayout();
         break;
       }
       case Toolkit::TextField::Property::SECONDARY_CURSOR_COLOR:
       {
-        if( impl.mDecorator )
-        {
-          const Vector4& color = value.Get< Vector4 >();
-          DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p SECONDARY_CURSOR_COLOR %f,%f,%f,%f\n", impl.mController.Get(), color.r, color.g, color.b, color.a );
+        const Vector4& color = value.Get< Vector4 >();
+        DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p SECONDARY_CURSOR_COLOR %f,%f,%f,%f\n", impl.mController.Get(), color.r, color.g, color.b, color.a );
 
-          impl.mDecorator->SetCursorColor( SECONDARY_CURSOR, color );
-          impl.RequestTextRelayout();
-        }
+        impl.mDecorator->SetCursorColor( SECONDARY_CURSOR, color );
+        impl.RequestTextRelayout();
         break;
       }
       case Toolkit::TextField::Property::ENABLE_CURSOR_BLINK:
       {
-        if( impl.mController )
-        {
-          const bool enable = value.Get< bool >();
-          DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField %p ENABLE_CURSOR_BLINK %d\n", impl.mController.Get(), enable );
+        const bool enable = value.Get< bool >();
+        DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField %p ENABLE_CURSOR_BLINK %d\n", impl.mController.Get(), enable );
 
-          impl.mController->SetEnableCursorBlink( enable );
-          impl.RequestTextRelayout();
-        }
+        impl.mController->SetEnableCursorBlink( enable );
+        impl.RequestTextRelayout();
         break;
       }
       case Toolkit::TextField::Property::CURSOR_BLINK_INTERVAL:
       {
-        if( impl.mDecorator )
-        {
-          const float interval = value.Get< float >();
-          DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField %p CURSOR_BLINK_INTERVAL %f\n", impl.mController.Get(), interval );
+        const float interval = value.Get< float >();
+        DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField %p CURSOR_BLINK_INTERVAL %f\n", impl.mController.Get(), interval );
 
-          impl.mDecorator->SetCursorBlinkInterval( interval );
-        }
+        impl.mDecorator->SetCursorBlinkInterval( interval );
         break;
       }
       case Toolkit::TextField::Property::CURSOR_BLINK_DURATION:
       {
-        if( impl.mDecorator )
-        {
-          const float duration = value.Get< float >();
-          DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField %p CURSOR_BLINK_DURATION %f\n", impl.mController.Get(), duration );
+        const float duration = value.Get< float >();
+        DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField %p CURSOR_BLINK_DURATION %f\n", impl.mController.Get(), duration );
 
-          impl.mDecorator->SetCursorBlinkDuration( duration );
-        }
+        impl.mDecorator->SetCursorBlinkDuration( duration );
         break;
       }
       case Toolkit::TextField::Property::CURSOR_WIDTH:
       {
-        if( impl.mDecorator )
-        {
-          const int width = value.Get< int >();
-          DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField %p CURSOR_WIDTH %d\n", impl.mController.Get(), width );
+        const int width = value.Get< int >();
+        DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField %p CURSOR_WIDTH %d\n", impl.mController.Get(), width );
 
-          impl.mDecorator->SetCursorWidth( width );
-          impl.mController->GetLayoutEngine().SetCursorWidth( width );
-        }
+        impl.mDecorator->SetCursorWidth( width );
+        impl.mController->GetLayoutEngine().SetCursorWidth( width );
         break;
       }
       case Toolkit::TextField::Property::GRAB_HANDLE_IMAGE:
@@ -434,7 +388,7 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
         const std::string imageFileName = value.Get< std::string >();
         DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField %p GRAB_HANDLE_IMAGE %s\n", impl.mController.Get(), imageFileName.c_str() );
 
-        if( impl.mDecorator && imageFileName.size() )
+        if( imageFileName.size() )
         {
           impl.mDecorator->SetHandleImage( GRAB_HANDLE, HANDLE_IMAGE_RELEASED, imageFileName );
           impl.RequestTextRelayout();
@@ -446,7 +400,7 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
         const std::string imageFileName = value.Get< std::string >();
         DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField %p GRAB_HANDLE_PRESSED_IMAGE %s\n", impl.mController.Get(), imageFileName.c_str() );
 
-        if( impl.mDecorator && imageFileName.size() )
+        if( imageFileName.size() )
         {
           impl.mDecorator->SetHandleImage( GRAB_HANDLE, HANDLE_IMAGE_PRESSED, imageFileName );
           impl.RequestTextRelayout();
@@ -458,10 +412,7 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
         const float threshold = value.Get< float >();
         DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField %p SCROLL_THRESHOLD %f\n", impl.mController.Get(), threshold );
 
-        if( impl.mDecorator )
-        {
-          impl.mDecorator->SetScrollThreshold( threshold );
-        }
+        impl.mDecorator->SetScrollThreshold( threshold );
         break;
       }
       case Toolkit::TextField::Property::SCROLL_SPEED:
@@ -469,17 +420,14 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
         const float speed = value.Get< float >();
         DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField %p SCROLL_SPEED %f\n", impl.mController.Get(), speed );
 
-        if( impl.mDecorator )
-        {
-          impl.mDecorator->SetScrollSpeed( speed );
-        }
+        impl.mDecorator->SetScrollSpeed( speed );
         break;
       }
       case Toolkit::TextField::Property::SELECTION_HANDLE_IMAGE_LEFT:
       {
         const std::string filename = GetImageFileNameFromPropertyValue( value );
 
-        if( impl.mDecorator && filename.size() )
+        if( filename.size() )
         {
           impl.mDecorator->SetHandleImage( LEFT_SELECTION_HANDLE, HANDLE_IMAGE_RELEASED, filename );
           impl.RequestTextRelayout();
@@ -490,7 +438,7 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
       {
         const std::string filename = GetImageFileNameFromPropertyValue( value );
 
-        if( impl.mDecorator && filename.size() )
+        if( filename.size() )
         {
           impl.mDecorator->SetHandleImage( RIGHT_SELECTION_HANDLE, HANDLE_IMAGE_RELEASED, filename );
           impl.RequestTextRelayout();
@@ -501,7 +449,7 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
       {
         const std::string filename = GetImageFileNameFromPropertyValue( value );
 
-        if( impl.mDecorator && filename.size() )
+        if( filename.size() )
         {
           impl.mDecorator->SetHandleImage( LEFT_SELECTION_HANDLE, HANDLE_IMAGE_PRESSED, filename );
           impl.RequestTextRelayout();
@@ -512,7 +460,7 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
       {
         const std::string filename = GetImageFileNameFromPropertyValue( value );
 
-        if( impl.mDecorator && filename.size() )
+        if( filename.size() )
         {
           impl.mDecorator->SetHandleImage( RIGHT_SELECTION_HANDLE, HANDLE_IMAGE_PRESSED, filename );
           impl.RequestTextRelayout();
@@ -523,7 +471,7 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
       {
         const std::string filename = GetImageFileNameFromPropertyValue( value );
 
-        if( impl.mDecorator && filename.size() )
+        if( filename.size() )
         {
           impl.mDecorator->SetHandleImage( LEFT_SELECTION_HANDLE_MARKER, HANDLE_IMAGE_RELEASED, filename );
           impl.RequestTextRelayout();
@@ -534,7 +482,7 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
       {
         const std::string filename = GetImageFileNameFromPropertyValue( value );
 
-        if( impl.mDecorator && filename.size() )
+        if( filename.size() )
         {
           impl.mDecorator->SetHandleImage( RIGHT_SELECTION_HANDLE_MARKER, HANDLE_IMAGE_RELEASED, filename );
           impl.RequestTextRelayout();
@@ -546,23 +494,17 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
         const Vector4 color = value.Get< Vector4 >();
         DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p SELECTION_HIGHLIGHT_COLOR %f,%f,%f,%f\n", impl.mController.Get(), color.r, color.g, color.b, color.a );
 
-        if( impl.mDecorator )
-        {
-          impl.mDecorator->SetHighlightColor( color );
-          impl.RequestTextRelayout();
-        }
+        impl.mDecorator->SetHighlightColor( color );
+        impl.RequestTextRelayout();
         break;
       }
       case Toolkit::TextField::Property::DECORATION_BOUNDING_BOX:
       {
-        if( impl.mDecorator )
-        {
-          const Rect<int> box = value.Get< Rect<int> >();
-          DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p DECORATION_BOUNDING_BOX %d,%d %dx%d\n", impl.mController.Get(), box.x, box.y, box.width, box.height );
+        const Rect<int> box = value.Get< Rect<int> >();
+        DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p DECORATION_BOUNDING_BOX %d,%d %dx%d\n", impl.mController.Get(), box.x, box.y, box.width, box.height );
 
-          impl.mDecorator->SetBoundingBox( box );
-          impl.RequestTextRelayout();
-        }
+        impl.mDecorator->SetBoundingBox( box );
+        impl.RequestTextRelayout();
         break;
       }
       case Toolkit::TextField::Property::INPUT_METHOD_SETTINGS:
@@ -583,34 +525,25 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
       }
       case Toolkit::TextField::Property::INPUT_COLOR:
       {
-        if( impl.mController )
-        {
-          const Vector4 inputColor = value.Get< Vector4 >();
-          DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p INPUT_COLOR %f,%f,%f,%f\n", impl.mController.Get(), inputColor.r, inputColor.g, inputColor.b, inputColor.a );
+        const Vector4 inputColor = value.Get< Vector4 >();
+        DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p INPUT_COLOR %f,%f,%f,%f\n", impl.mController.Get(), inputColor.r, inputColor.g, inputColor.b, inputColor.a );
 
-          impl.mController->SetInputColor( inputColor );
-        }
+        impl.mController->SetInputColor( inputColor );
         break;
       }
       case Toolkit::TextField::Property::ENABLE_MARKUP:
       {
-        if( impl.mController )
-        {
-          const bool enableMarkup = value.Get<bool>();
-          DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p ENABLE_MARKUP %d\n", impl.mController.Get(), enableMarkup );
+        const bool enableMarkup = value.Get<bool>();
+        DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p ENABLE_MARKUP %d\n", impl.mController.Get(), enableMarkup );
 
-          impl.mController->SetMarkupProcessorEnabled( enableMarkup );
-        }
+        impl.mController->SetMarkupProcessorEnabled( enableMarkup );
         break;
       }
       case Toolkit::TextField::Property::INPUT_FONT_FAMILY:
       {
-        if( impl.mController )
-        {
-          const std::string& fontFamily = value.Get< std::string >();
-          DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p INPUT_FONT_FAMILY %s\n", impl.mController.Get(), fontFamily.c_str() );
-          impl.mController->SetInputFontFamily( fontFamily );
-        }
+        const std::string& fontFamily = value.Get< std::string >();
+        DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p INPUT_FONT_FAMILY %s\n", impl.mController.Get(), fontFamily.c_str() );
+        impl.mController->SetInputFontFamily( fontFamily );
         break;
       }
       case Toolkit::TextField::Property::INPUT_FONT_STYLE:
@@ -620,12 +553,9 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
       }
       case Toolkit::TextField::Property::INPUT_POINT_SIZE:
       {
-        if( impl.mController )
-        {
-          const float pointSize = value.Get< float >();
-          DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p INPUT_POINT_SIZE %f\n", impl.mController.Get(), pointSize );
-          impl.mController->SetInputFontPointSize( pointSize );
-        }
+        const float pointSize = value.Get< float >();
+        DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p INPUT_POINT_SIZE %f\n", impl.mController.Get(), pointSize );
+        impl.mController->SetInputFontPointSize( pointSize );
         break;
       }
       case Toolkit::TextField::Property::UNDERLINE:
@@ -711,26 +641,20 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
       }
       case Toolkit::TextField::Property::PIXEL_SIZE:
       {
-        if( impl.mController )
-        {
-          const float pixelSize = value.Get< float >();
-          DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p PIXEL_SIZE %f\n", impl.mController.Get(), pixelSize );
+        const float pixelSize = value.Get< float >();
+        DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p PIXEL_SIZE %f\n", impl.mController.Get(), pixelSize );
 
-          if( !Equals( impl.mController->GetDefaultFontSize( Text::Controller::PIXEL_SIZE ), pixelSize ) )
-          {
-            impl.mController->SetDefaultFontSize( pixelSize, Text::Controller::PIXEL_SIZE );
-          }
+        if( !Equals( impl.mController->GetDefaultFontSize( Text::Controller::PIXEL_SIZE ), pixelSize ) )
+        {
+          impl.mController->SetDefaultFontSize( pixelSize, Text::Controller::PIXEL_SIZE );
         }
         break;
       }
       case Toolkit::TextField::Property::ENABLE_SELECTION:
       {
-        if( impl.mController )
-        {
-          const bool enableSelection = value.Get< bool >();
-           DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p ENABLE_SELECTION %d\n", impl.mController.Get(), enableSelection );
-          impl.mController->SetSelectionEnabled( enableSelection );
-        }
+        const bool enableSelection = value.Get< bool >();
+        DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p ENABLE_SELECTION %d\n", impl.mController.Get(), enableSelection );
+        impl.mController->SetSelectionEnabled( enableSelection );
         break;
       }
       case Toolkit::TextField::Property::PLACEHOLDER:
@@ -744,68 +668,77 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
       }
       case Toolkit::TextField::Property::ELLIPSIS:
       {
-        if( impl.mController )
-        {
-          const bool ellipsis = value.Get<bool>();
-          DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p ELLIPSIS %d\n", impl.mController.Get(), ellipsis );
+        const bool ellipsis = value.Get<bool>();
+        DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p ELLIPSIS %d\n", impl.mController.Get(), ellipsis );
 
-          impl.mController->SetTextElideEnabled( ellipsis );
-        }
+        impl.mController->SetTextElideEnabled( ellipsis );
         break;
       }
       case Toolkit::DevelTextField::Property::ENABLE_SHIFT_SELECTION:
       {
-        if( impl.mController )
-        {
-          const bool shiftSelection = value.Get<bool>();
-          DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p ENABLE_SHIFT_SELECTION %d\n", impl.mController.Get(), shiftSelection );
+        const bool shiftSelection = value.Get<bool>();
+        DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p ENABLE_SHIFT_SELECTION %d\n", impl.mController.Get(), shiftSelection );
 
-          impl.mController->SetShiftSelectionEnabled( shiftSelection );
-        }
+        impl.mController->SetShiftSelectionEnabled( shiftSelection );
         break;
       }
       case Toolkit::DevelTextField::Property::ENABLE_GRAB_HANDLE:
       {
-        if( impl.mController )
-        {
-          const bool grabHandleEnabled = value.Get<bool>();
-          DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p ENABLE_GRAB_HANDLE %d\n", impl.mController.Get(), grabHandleEnabled );
+        const bool grabHandleEnabled = value.Get<bool>();
+        DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p ENABLE_GRAB_HANDLE %d\n", impl.mController.Get(), grabHandleEnabled );
 
-          impl.mController->SetGrabHandleEnabled( grabHandleEnabled );
-        }
+        impl.mController->SetGrabHandleEnabled( grabHandleEnabled );
         break;
       }
       case Toolkit::DevelTextField::Property::MATCH_SYSTEM_LANGUAGE_DIRECTION:
       {
-        if( impl.mController )
-        {
-          impl.mController->SetMatchSystemLanguageDirection(value.Get< bool >());
-        }
+        impl.mController->SetMatchSystemLanguageDirection(value.Get< bool >());
         break;
       }
       case Toolkit::DevelTextField::Property::ENABLE_GRAB_HANDLE_POPUP:
       {
+        const bool grabHandlePopupEnabled = value.Get<bool>();
+        DALI_LOG_INFO(gLogFilter, Debug::General, "TextField %p ENABLE_GRAB_HANDLE_POPUP %d\n", impl.mController.Get(), grabHandlePopupEnabled);
+
+        impl.mController->SetGrabHandlePopupEnabled(grabHandlePopupEnabled);
+        break;
+      }
+      case Toolkit::DevelTextField::Property::BACKGROUND:
+      {
+        const Vector4 backgroundColor = value.Get< Vector4 >();
+        DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p BACKGROUND %f,%f,%f,%f\n", impl.mController.Get(), backgroundColor.r, backgroundColor.g, backgroundColor.b, backgroundColor.a );
+
+        impl.mController->SetBackgroundEnabled( true );
+        impl.mController->SetBackgroundColor( backgroundColor );
+        break;
+      }
+      case Toolkit::DevelTextField::Property::SELECTED_TEXT_START:
+      {
         if( impl.mController )
         {
-          const bool grabHandlePopupEnabled = value.Get<bool>();
-          DALI_LOG_INFO(gLogFilter, Debug::General, "TextField %p ENABLE_GRAB_HANDLE_POPUP %d\n", impl.mController.Get(), grabHandlePopupEnabled);
-
-          impl.mController->SetGrabHandlePopupEnabled(grabHandlePopupEnabled);
-          break;
+          uint32_t start = static_cast<uint32_t>(value.Get< int >());
+          DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p SELECTED_TEXT_START %d\n", impl.mController.Get(), start );
+          impl.SetTextSelectionRange( &start, nullptr );
         }
+        break;
       }
-      case Toolkit::DevelTextField::Property::BACKGROUND:
+      case Toolkit::DevelTextField::Property::SELECTED_TEXT_END:
       {
         if( impl.mController )
         {
-          const Vector4 backgroundColor = value.Get< Vector4 >();
-          DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p BACKGROUND %f,%f,%f,%f\n", impl.mController.Get(), backgroundColor.r, backgroundColor.g, backgroundColor.b, backgroundColor.a );
-
-          impl.mController->SetBackgroundEnabled( true );
-          impl.mController->SetBackgroundColor( backgroundColor );
+          uint32_t end = static_cast<uint32_t>(value.Get< int >());
+          DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p SELECTED_TEXT_END %d\n", impl.mController.Get(), end );
+          impl.SetTextSelectionRange( nullptr, &end );
         }
         break;
       }
+      case Toolkit::DevelTextField::Property::ENABLE_EDITING:
+      {
+        const bool editable = value.Get< bool >();
+        DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p ENABLE_EDITING %d\n", impl.mController.Get(), editable );
+        impl.SetEditable( editable );
+        break;
+      }
     } // switch
   } // textfield
 }
@@ -819,6 +752,8 @@ Property::Value TextField::GetProperty( BaseObject* object, Property::Index inde
   if( textField )
   {
     TextField& impl( GetImpl( textField ) );
+    DALI_ASSERT_DEBUG( impl.mController && "No text contoller" );
+    DALI_ASSERT_DEBUG( impl.mDecorator && "No text decorator" );
 
     switch( index )
     {
@@ -829,41 +764,29 @@ Property::Value TextField::GetProperty( BaseObject* object, Property::Index inde
       }
       case Toolkit::TextField::Property::TEXT:
       {
-        if( impl.mController )
-        {
-          std::string text;
-          impl.mController->GetText( text );
-          DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p returning text: %s\n", impl.mController.Get(), text.c_str() );
-          value = text;
-        }
+        std::string text;
+        impl.mController->GetText( text );
+        DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p returning text: %s\n", impl.mController.Get(), text.c_str() );
+        value = text;
         break;
       }
       case Toolkit::TextField::Property::PLACEHOLDER_TEXT:
       {
-        if( impl.mController )
-        {
-          std::string text;
-          impl.mController->GetPlaceholderText( Controller::PLACEHOLDER_TYPE_INACTIVE, text );
-          value = text;
-        }
+        std::string text;
+        impl.mController->GetPlaceholderText( Controller::PLACEHOLDER_TYPE_INACTIVE, text );
+        value = text;
         break;
       }
       case Toolkit::TextField::Property::PLACEHOLDER_TEXT_FOCUSED:
       {
-        if( impl.mController )
-        {
-          std::string text;
-          impl.mController->GetPlaceholderText( Controller::PLACEHOLDER_TYPE_ACTIVE, text );
-          value = text;
-        }
+        std::string text;
+        impl.mController->GetPlaceholderText( Controller::PLACEHOLDER_TYPE_ACTIVE, text );
+        value = text;
         break;
       }
       case Toolkit::TextField::Property::FONT_FAMILY:
       {
-        if( impl.mController )
-        {
-          value = impl.mController->GetDefaultFontFamily();
-        }
+        value = impl.mController->GetDefaultFontFamily();
         break;
       }
       case Toolkit::TextField::Property::FONT_STYLE:
@@ -873,18 +796,12 @@ Property::Value TextField::GetProperty( BaseObject* object, Property::Index inde
       }
       case Toolkit::TextField::Property::POINT_SIZE:
       {
-        if( impl.mController )
-        {
-          value = impl.mController->GetDefaultFontSize( Text::Controller::POINT_SIZE );
-        }
+        value = impl.mController->GetDefaultFontSize( Text::Controller::POINT_SIZE );
         break;
       }
       case Toolkit::TextField::Property::MAX_LENGTH:
       {
-        if( impl.mController )
-        {
-          value = impl.mController->GetMaximumNumberOfCharacters();
-        }
+        value = impl.mController->GetMaximumNumberOfCharacters();
         break;
       }
       case Toolkit::TextField::Property::EXCEED_POLICY:
@@ -894,60 +811,42 @@ Property::Value TextField::GetProperty( BaseObject* object, Property::Index inde
       }
       case Toolkit::TextField::Property::HORIZONTAL_ALIGNMENT:
       {
-        if( impl.mController )
-        {
-          const char* name = Text::GetHorizontalAlignmentString( impl.mController->GetHorizontalAlignment() );
+        const char* name = Text::GetHorizontalAlignmentString( impl.mController->GetHorizontalAlignment() );
 
-          if ( name )
-          {
-            value = std::string( name );
-          }
+        if ( name )
+        {
+          value = std::string( name );
         }
         break;
       }
       case Toolkit::TextField::Property::VERTICAL_ALIGNMENT:
       {
-        if( impl.mController )
-        {
-          const char* name = Text::GetVerticalAlignmentString( impl.mController->GetVerticalAlignment() );
+        const char* name = Text::GetVerticalAlignmentString( impl.mController->GetVerticalAlignment() );
 
-          if( name )
-          {
-            value = std::string( name );
-          }
+        if( name )
+        {
+          value = std::string( name );
         }
         break;
       }
       case Toolkit::TextField::Property::TEXT_COLOR:
       {
-        if ( impl.mController )
-        {
-          value = impl.mController->GetDefaultColor();
-        }
+        value = impl.mController->GetDefaultColor();
         break;
       }
       case Toolkit::TextField::Property::PLACEHOLDER_TEXT_COLOR:
       {
-        if ( impl.mController )
-        {
-          value = impl.mController->GetPlaceholderTextColor();
-        }
+        value = impl.mController->GetPlaceholderTextColor();
         break;
       }
       case Toolkit::TextField::Property::PRIMARY_CURSOR_COLOR:
       {
-        if( impl.mDecorator )
-        {
-          value = impl.mDecorator->GetColor( PRIMARY_CURSOR );
-        }
+        value = impl.mDecorator->GetColor( PRIMARY_CURSOR );
         break;
       }
       case Toolkit::TextField::Property::SECONDARY_CURSOR_COLOR:
       {
-        if( impl.mDecorator )
-        {
-          value = impl.mDecorator->GetColor( SECONDARY_CURSOR );
-        }
+        value = impl.mDecorator->GetColor( SECONDARY_CURSOR );
         break;
       }
       case Toolkit::TextField::Property::ENABLE_CURSOR_BLINK:
@@ -957,58 +856,37 @@ Property::Value TextField::GetProperty( BaseObject* object, Property::Index inde
       }
       case Toolkit::TextField::Property::CURSOR_BLINK_INTERVAL:
       {
-        if( impl.mDecorator )
-        {
-          value = impl.mDecorator->GetCursorBlinkInterval();
-        }
+        value = impl.mDecorator->GetCursorBlinkInterval();
         break;
       }
       case Toolkit::TextField::Property::CURSOR_BLINK_DURATION:
       {
-        if( impl.mDecorator )
-        {
-          value = impl.mDecorator->GetCursorBlinkDuration();
-        }
+        value = impl.mDecorator->GetCursorBlinkDuration();
         break;
       }
       case Toolkit::TextField::Property::CURSOR_WIDTH:
       {
-        if( impl.mDecorator )
-        {
-          value = impl.mDecorator->GetCursorWidth();
-        }
+        value = impl.mDecorator->GetCursorWidth();
         break;
       }
       case Toolkit::TextField::Property::GRAB_HANDLE_IMAGE:
       {
-        if( impl.mDecorator )
-        {
-          value = impl.mDecorator->GetHandleImage( GRAB_HANDLE, HANDLE_IMAGE_RELEASED );
-        }
+        value = impl.mDecorator->GetHandleImage( GRAB_HANDLE, HANDLE_IMAGE_RELEASED );
         break;
       }
       case Toolkit::TextField::Property::GRAB_HANDLE_PRESSED_IMAGE:
       {
-        if( impl.mDecorator )
-        {
-          value = impl.mDecorator->GetHandleImage( GRAB_HANDLE, HANDLE_IMAGE_PRESSED );
-        }
+        value = impl.mDecorator->GetHandleImage( GRAB_HANDLE, HANDLE_IMAGE_PRESSED );
         break;
       }
       case Toolkit::TextField::Property::SCROLL_THRESHOLD:
       {
-        if( impl.mDecorator )
-        {
-          value = impl.mDecorator->GetScrollThreshold();
-        }
+        value = impl.mDecorator->GetScrollThreshold();
         break;
       }
       case Toolkit::TextField::Property::SCROLL_SPEED:
       {
-        if( impl.mDecorator )
-        {
-          value = impl.mDecorator->GetScrollSpeed();
-        }
+        value = impl.mDecorator->GetScrollSpeed();
         break;
       }
       case Toolkit::TextField::Property::SELECTION_HANDLE_IMAGE_LEFT:
@@ -1043,20 +921,14 @@ Property::Value TextField::GetProperty( BaseObject* object, Property::Index inde
       }
       case Toolkit::TextField::Property::SELECTION_HIGHLIGHT_COLOR:
       {
-        if( impl.mDecorator )
-        {
-          value = impl.mDecorator->GetHighlightColor();
-        }
+        value = impl.mDecorator->GetHighlightColor();
         break;
       }
       case Toolkit::TextField::Property::DECORATION_BOUNDING_BOX:
       {
-        if( impl.mDecorator )
-        {
-          Rect<int> boundingBox;
-          impl.mDecorator->GetBoundingBox( boundingBox );
-          value = boundingBox;
-        }
+        Rect<int> boundingBox;
+        impl.mDecorator->GetBoundingBox( boundingBox );
+        value = boundingBox;
         break;
       }
       case Toolkit::TextField::Property::INPUT_METHOD_SETTINGS:
@@ -1068,26 +940,17 @@ Property::Value TextField::GetProperty( BaseObject* object, Property::Index inde
       }
       case Toolkit::TextField::Property::INPUT_COLOR:
       {
-        if( impl.mController )
-        {
-          value = impl.mController->GetInputColor();
-        }
+        value = impl.mController->GetInputColor();
         break;
       }
       case Toolkit::TextField::Property::ENABLE_MARKUP:
       {
-        if( impl.mController )
-        {
-          value = impl.mController->IsMarkupProcessorEnabled();
-        }
+        value = impl.mController->IsMarkupProcessorEnabled();
         break;
       }
       case Toolkit::TextField::Property::INPUT_FONT_FAMILY:
       {
-        if( impl.mController )
-        {
-          value = impl.mController->GetInputFontFamily();
-        }
+        value = impl.mController->GetInputFontFamily();
         break;
       }
       case Toolkit::TextField::Property::INPUT_FONT_STYLE:
@@ -1097,10 +960,7 @@ Property::Value TextField::GetProperty( BaseObject* object, Property::Index inde
       }
       case Toolkit::TextField::Property::INPUT_POINT_SIZE:
       {
-        if( impl.mController )
-        {
-          value = impl.mController->GetInputFontPointSize();
-        }
+        value = impl.mController->GetInputFontPointSize();
         break;
       }
       case Toolkit::TextField::Property::UNDERLINE:
@@ -1152,18 +1012,12 @@ Property::Value TextField::GetProperty( BaseObject* object, Property::Index inde
       }
       case Toolkit::TextField::Property::PIXEL_SIZE:
       {
-        if( impl.mController )
-        {
-          value = impl.mController->GetDefaultFontSize( Text::Controller::PIXEL_SIZE );
-        }
+        value = impl.mController->GetDefaultFontSize( Text::Controller::PIXEL_SIZE );
         break;
       }
       case Toolkit::TextField::Property::ENABLE_SELECTION:
       {
-        if( impl.mController )
-        {
-          value = impl.mController->IsSelectionEnabled();
-        }
+        value = impl.mController->IsSelectionEnabled();
         break;
       }
       case Toolkit::TextField::Property::PLACEHOLDER:
@@ -1175,58 +1029,54 @@ Property::Value TextField::GetProperty( BaseObject* object, Property::Index inde
       }
       case Toolkit::TextField::Property::ELLIPSIS:
       {
-        if( impl.mController )
-        {
-          value = impl.mController->IsTextElideEnabled();
-        }
+        value = impl.mController->IsTextElideEnabled();
         break;
       }
       case Toolkit::DevelTextField::Property::ENABLE_SHIFT_SELECTION:
       {
-        if( impl.mController )
-        {
-          value = impl.mController->IsShiftSelectionEnabled();
-        }
+        value = impl.mController->IsShiftSelectionEnabled();
         break;
       }
       case Toolkit::DevelTextField::Property::ENABLE_GRAB_HANDLE:
       {
-        if( impl.mController )
-        {
-          value = impl.mController->IsGrabHandleEnabled();
-        }
+        value = impl.mController->IsGrabHandleEnabled();
         break;
       }
       case Toolkit::DevelTextField::Property::MATCH_SYSTEM_LANGUAGE_DIRECTION:
       {
-        if( impl.mController )
-        {
-          value = impl.mController->IsMatchSystemLanguageDirection();
-        }
+        value = impl.mController->IsMatchSystemLanguageDirection();
         break;
       }
       case Toolkit::DevelTextField::Property::ENABLE_GRAB_HANDLE_POPUP:
       {
-        if( impl.mController )
-        {
-          value = impl.mController->IsGrabHandlePopupEnabled();
-        }
+        value = impl.mController->IsGrabHandlePopupEnabled();
         break;
       }
       case Toolkit::DevelTextField::Property::BACKGROUND:
       {
-        if( impl.mController )
-        {
-          value = impl.mController->GetBackgroundColor();
-        }
+        value = impl.mController->GetBackgroundColor();
         break;
       }
       case Toolkit::DevelTextField::Property::SELECTED_TEXT:
       {
-        if( impl.mController )
-        {
-          value = impl.mController->GetSelectedText( );
-        }
+        value = impl.mController->GetSelectedText( );
+        break;
+      }
+      case Toolkit::DevelTextField::Property::SELECTED_TEXT_START:
+      {
+        Uint32Pair range = impl.GetTextSelectionRange( );
+        value = static_cast<int>(range.first);
+        break;
+      }
+      case Toolkit::DevelTextField::Property::SELECTED_TEXT_END:
+      {
+        Uint32Pair range = impl.GetTextSelectionRange( );
+        value = static_cast<int>(range.second);
+        break;
+      }
+      case Toolkit::DevelTextField::Property::ENABLE_EDITING:
+      {
+        value = impl.IsEditable();
         break;
       }
     } //switch
@@ -1253,6 +1103,26 @@ void TextField::SelectNone()
   }
 }
 
+void TextField::SetTextSelectionRange(const uint32_t *start, const uint32_t *end)
+{
+  if( mController && mController->IsShowingRealText() )
+  {
+    mController->SetTextSelectionRange( start, end );
+    SetKeyInputFocus();
+  }
+}
+
+Uint32Pair TextField::GetTextSelectionRange() const
+{
+  Uint32Pair range;
+  if( mController && mController->IsShowingRealText() )
+  {
+    range = mController->GetTextSelectionRange();
+  }
+  return range;
+}
+
+
 InputMethodContext TextField::GetInputMethodContext()
 {
   return mInputMethodContext;
@@ -1305,7 +1175,7 @@ void TextField::OnInitialize()
 {
   Actor self = Self();
 
-  mController = Text::Controller::New( this, this );
+  mController = Text::Controller::New( this, this ,this);
 
   // When using the vector-based rendering, the size of the GLyphs are different
   TextAbstraction::GlyphType glyphType = (DevelText::RENDERING_VECTOR_BASED == mRenderingBackend) ? TextAbstraction::VECTOR_GLYPH : TextAbstraction::BITMAP_GLYPH;
@@ -1601,7 +1471,7 @@ void TextField::RenderText( Text::Controller::UpdateTextType updateTextType )
 void TextField::OnKeyInputFocusGained()
 {
   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField::OnKeyInputFocusGained %p\n", mController.Get() );
-  if ( mInputMethodContext )
+  if ( mInputMethodContext && IsEditable() )
   {
     mInputMethodContext.ApplyOptions( mInputMethodOptions );
 
@@ -1656,7 +1526,7 @@ void TextField::OnKeyInputFocusLost()
 void TextField::OnTap( const TapGesture& gesture )
 {
   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField::OnTap %p\n", mController.Get() );
-  if ( mInputMethodContext )
+  if ( mInputMethodContext && IsEditable() )
   {
     mInputMethodContext.Activate();
   }
@@ -1676,7 +1546,7 @@ void TextField::OnPan( const PanGesture& gesture )
 
 void TextField::OnLongPress( const LongPressGesture& gesture )
 {
-  if ( mInputMethodContext )
+  if ( mInputMethodContext && IsEditable() )
   {
     mInputMethodContext.Activate();
   }
@@ -1716,6 +1586,20 @@ void TextField::RequestTextRelayout()
   RelayoutRequest();
 }
 
+bool TextField::IsEditable() const
+{
+  return mController->IsEditable();
+}
+
+void TextField::SetEditable( bool editable )
+{
+  mController->SetEditable(editable);
+  if ( mInputMethodContext && !editable )
+  {
+    mInputMethodContext.Deactivate();
+  }
+}
+
 void TextField::TextChanged()
 {
   Dali::Toolkit::TextField handle( GetOwner() );
index f7b6e56..aa5350d 100755 (executable)
@@ -28,6 +28,7 @@
 #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-selectable-control-interface.h>
 #include <dali-toolkit/internal/text/text-controller.h>
 #include <dali-toolkit/internal/text/rendering/text-renderer.h>
 
@@ -42,7 +43,7 @@ namespace Internal
 /**
  * @brief A control which renders a short text string.
  */
-class TextField : public Control, public Text::ControlInterface, public Text::EditableControlInterface
+class TextField : public Control, public Text::ControlInterface, public Text::EditableControlInterface, public Text::SelectableControlInterface
 {
 public:
 
@@ -107,7 +108,7 @@ public:
    */
   void SelectWholeText();
 
-    /**
+  /**
    * @brief Called to unselect the whole texts.
    */
   void SelectNone();
@@ -203,6 +204,28 @@ private: // From Control
    */
   void AddDecoration( Actor& actor, bool needsClipping ) override;
 
+// From SelectableControlInterface
+public:
+  /**
+   * @copydoc Text::SelectableControlInterface::SetTextSelectionRange()
+   */
+  void SetTextSelectionRange(const uint32_t *start, const uint32_t *end) override;
+
+  /**
+   * @copydoc Text::SelectableControlInterface::GetTextSelectionRange()
+   */
+  Uint32Pair GetTextSelectionRange() const override;
+
+  /**
+   * @copydoc Text::EditableControlInterface::IsEditable()
+   */
+  bool IsEditable() const override;
+
+  /**
+   * @copydoc Text::EditableControlInterface::SetEditable()
+   */
+  void SetEditable( bool editable ) override;
+
 private: // Implementation
 
   /**
index d40cd76..1cdb0f8 100755 (executable)
@@ -19,6 +19,7 @@
 #include <dali-toolkit/internal/controls/text-controls/text-label-impl.h>
 
 // EXTERNAL INCLUDES
+#include <dali/public-api/common/dali-common.h>
 #include <dali/public-api/object/type-registry-helper.h>
 #include <dali/devel-api/common/stage.h>
 #include <dali/devel-api/object/property-helper-devel.h>
@@ -168,6 +169,8 @@ void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Pr
   if( label )
   {
     TextLabel& impl( GetImpl( label ) );
+    DALI_ASSERT_ALWAYS( impl.mController && "No text contoller" );
+
     switch( index )
     {
       case Toolkit::DevelTextLabel::Property::RENDERING_BACKEND:
@@ -185,32 +188,23 @@ void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Pr
           impl.mRenderingBackend = backend;
           impl.mTextUpdateNeeded = true;
 
-          if( impl.mController )
-          {
-            // When using the vector-based rendering, the size of the GLyphs are different
-            TextAbstraction::GlyphType glyphType = (DevelText::RENDERING_VECTOR_BASED == impl.mRenderingBackend) ? TextAbstraction::VECTOR_GLYPH : TextAbstraction::BITMAP_GLYPH;
-            impl.mController->SetGlyphType( glyphType );
-          }
+          // When using the vector-based rendering, the size of the GLyphs are different
+          TextAbstraction::GlyphType glyphType = (DevelText::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 >() );
-        }
+        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 >();
+        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 );
-        }
+        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:
@@ -220,80 +214,62 @@ void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Pr
       }
       case Toolkit::TextLabel::Property::POINT_SIZE:
       {
-        if( impl.mController )
-        {
-          const float pointSize = value.Get< float >();
+        const float pointSize = value.Get< float >();
 
-          if( !Equals( impl.mController->GetDefaultFontSize( Text::Controller::POINT_SIZE ), pointSize ) )
-          {
-            impl.mController->SetDefaultFontSize( pointSize, Text::Controller::POINT_SIZE );
-          }
+        if( !Equals( impl.mController->GetDefaultFontSize( Text::Controller::POINT_SIZE ), pointSize ) )
+        {
+          impl.mController->SetDefaultFontSize( pointSize, Text::Controller::POINT_SIZE );
         }
         break;
       }
       case Toolkit::TextLabel::Property::MULTI_LINE:
       {
-        if( impl.mController )
-        {
-          impl.mController->SetMultiLineEnabled( value.Get< bool >() );
-        }
+        impl.mController->SetMultiLineEnabled( value.Get< bool >() );
         break;
       }
       case Toolkit::TextLabel::Property::HORIZONTAL_ALIGNMENT:
       {
-        if( impl.mController )
+        Text::HorizontalAlignment::Type alignment( static_cast< Text::HorizontalAlignment::Type >( -1 ) ); // Set to invalid value to ensure a valid mode does get set
+        if( Text::GetHorizontalAlignmentEnumeration( value, alignment ) )
         {
-          Text::HorizontalAlignment::Type alignment( static_cast< Text::HorizontalAlignment::Type >( -1 ) ); // Set to invalid value to ensure a valid mode does get set
-          if( Text::GetHorizontalAlignmentEnumeration( value, alignment ) )
-          {
-            impl.mController->SetHorizontalAlignment( alignment );
-          }
+          impl.mController->SetHorizontalAlignment( alignment );
         }
         break;
       }
       case Toolkit::TextLabel::Property::VERTICAL_ALIGNMENT:
       {
-        if( impl.mController )
+        Toolkit::Text::VerticalAlignment::Type alignment( static_cast< Text::VerticalAlignment::Type >( -1 ) ); // Set to invalid value to ensure a valid mode does get set
+        if( Text::GetVerticalAlignmentEnumeration( value, alignment ) )
         {
-          Toolkit::Text::VerticalAlignment::Type alignment( static_cast< Text::VerticalAlignment::Type >( -1 ) ); // Set to invalid value to ensure a valid mode does get set
-          if( Text::GetVerticalAlignmentEnumeration( value, alignment ) )
-          {
-            impl.mController->SetVerticalAlignment( alignment );
-          }
+          impl.mController->SetVerticalAlignment( alignment );
         }
         break;
       }
       case Toolkit::TextLabel::Property::ENABLE_MARKUP:
       {
-        if( impl.mController )
-        {
-          const bool enableMarkup = value.Get<bool>();
-          impl.mController->SetMarkupProcessorEnabled( enableMarkup );
-        }
+        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() )
         {
-          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->StopScrolling();
-               }
-             }
-             // If request is enable (true) then start autoscroll as not already running
-             else
+           // If request is disable (false) and auto scrolling is enabled then need to stop it
+           if ( enableAutoScroll == false )
+           {
+             if( impl.mTextScroller )
              {
-               impl.mController->SetAutoScrollEnabled( enableAutoScroll );
+               impl.mTextScroller->StopScrolling();
              }
-          }
+           }
+           // If request is enable (true) then start autoscroll as not already running
+           else
+           {
+             impl.mController->SetAutoScrollEnabled( enableAutoScroll );
+           }
         }
         break;
       }
@@ -351,15 +327,12 @@ void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Pr
       }
       case Toolkit::TextLabel::Property::LINE_SPACING:
       {
-        if( impl.mController )
-        {
-          const float lineSpacing = value.Get<float>();
+        const float lineSpacing = value.Get<float>();
 
-          // Don't trigger anything if the line spacing didn't change
-          if( impl.mController->SetDefaultLineSpacing( lineSpacing ) )
-          {
-            impl.mTextUpdateNeeded = true;
-          }
+        // Don't trigger anything if the line spacing didn't change
+        if( impl.mController->SetDefaultLineSpacing( lineSpacing ) )
+        {
+          impl.mTextUpdateNeeded = true;
         }
         break;
       }
@@ -401,45 +374,36 @@ void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Pr
       }
       case Toolkit::TextLabel::Property::PIXEL_SIZE:
       {
-        if( impl.mController )
-        {
-          const float pixelSize = value.Get< float >();
-          DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel %p PIXEL_SIZE %f\n", impl.mController.Get(), pixelSize );
+        const float pixelSize = value.Get< float >();
+        DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel %p PIXEL_SIZE %f\n", impl.mController.Get(), pixelSize );
 
-          if( !Equals( impl.mController->GetDefaultFontSize( Text::Controller::PIXEL_SIZE ), pixelSize ) )
-          {
-            impl.mController->SetDefaultFontSize( pixelSize, Text::Controller::PIXEL_SIZE );
-          }
+        if( !Equals( impl.mController->GetDefaultFontSize( Text::Controller::PIXEL_SIZE ), pixelSize ) )
+        {
+          impl.mController->SetDefaultFontSize( pixelSize, Text::Controller::PIXEL_SIZE );
         }
         break;
       }
       case Toolkit::TextLabel::Property::ELLIPSIS:
       {
-        if( impl.mController )
-        {
-          const bool ellipsis = value.Get<bool>();
-          DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel %p ELLIPSIS %d\n", impl.mController.Get(), ellipsis );
+        const bool ellipsis = value.Get<bool>();
+        DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel %p ELLIPSIS %d\n", impl.mController.Get(), ellipsis );
 
-          impl.mController->SetTextElideEnabled( ellipsis );
-        }
+        impl.mController->SetTextElideEnabled( ellipsis );
         break;
       }
       case Toolkit::TextLabel::Property::LINE_WRAP_MODE:
       {
-        if( impl.mController )
+        Text::LineWrap::Mode lineWrapMode( static_cast< Text::LineWrap::Mode >( -1 ) ); // Set to invalid value to ensure a valid mode does get set
+        if( GetLineWrapModeEnumeration( value, lineWrapMode ) )
         {
-          Text::LineWrap::Mode lineWrapMode( static_cast< Text::LineWrap::Mode >( -1 ) ); // Set to invalid value to ensure a valid mode does get set
-          if( GetLineWrapModeEnumeration( value, lineWrapMode ) )
-          {
-            DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel %p LineWrap::MODE %d\n", impl.mController.Get(), lineWrapMode );
-            impl.mController->SetLineWrapMode( lineWrapMode );
-          }
+          DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel %p LineWrap::MODE %d\n", impl.mController.Get(), lineWrapMode );
+          impl.mController->SetLineWrapMode( lineWrapMode );
         }
         break;
       }
       case Toolkit::DevelTextLabel::Property::VERTICAL_LINE_ALIGNMENT:
       {
-        if( impl.mController && impl.mController->GetTextModel() )
+        if( impl.mController->GetTextModel() )
         {
           DevelText::VerticalLineAlignment::Type alignment = static_cast<DevelText::VerticalLineAlignment::Type>( value.Get<int>() );
 
@@ -542,14 +506,11 @@ void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Pr
       }
       case Toolkit::DevelTextLabel::Property::MIN_LINE_SIZE:
       {
-        if( impl.mController )
-        {
-          const float lineSize = value.Get<float>();
+        const float lineSize = value.Get<float>();
 
-          if( impl.mController->SetDefaultLineSize( lineSize ) )
-          {
-            impl.mTextUpdateNeeded = true;
-          }
+        if( impl.mController->SetDefaultLineSize( lineSize ) )
+        {
+          impl.mTextUpdateNeeded = true;
         }
         break;
       }
@@ -575,6 +536,8 @@ Property::Value TextLabel::GetProperty( BaseObject* object, Property::Index inde
   if( label )
   {
     TextLabel& impl( GetImpl( label ) );
+    DALI_ASSERT_DEBUG( impl.mController && "No text contoller" );
+
     switch( index )
     {
       case Toolkit::DevelTextLabel::Property::RENDERING_BACKEND:
@@ -584,20 +547,14 @@ Property::Value TextLabel::GetProperty( BaseObject* object, Property::Index inde
       }
       case Toolkit::TextLabel::Property::TEXT:
       {
-        if( impl.mController )
-        {
-          std::string text;
-          impl.mController->GetText( text );
-          value = text;
-        }
+        std::string text;
+        impl.mController->GetText( text );
+        value = text;
         break;
       }
       case Toolkit::TextLabel::Property::FONT_FAMILY:
       {
-        if( impl.mController )
-        {
-          value = impl.mController->GetDefaultFontFamily();
-        }
+        value = impl.mController->GetDefaultFontFamily();
         break;
       }
       case Toolkit::TextLabel::Property::FONT_STYLE:
@@ -607,59 +564,41 @@ Property::Value TextLabel::GetProperty( BaseObject* object, Property::Index inde
       }
       case Toolkit::TextLabel::Property::POINT_SIZE:
       {
-        if( impl.mController )
-        {
-          value = impl.mController->GetDefaultFontSize( Text::Controller::POINT_SIZE );
-        }
+        value = impl.mController->GetDefaultFontSize( Text::Controller::POINT_SIZE );
         break;
       }
       case Toolkit::TextLabel::Property::MULTI_LINE:
       {
-        if( impl.mController )
-        {
-          value = impl.mController->IsMultiLineEnabled();
-        }
+        value = impl.mController->IsMultiLineEnabled();
         break;
       }
       case Toolkit::TextLabel::Property::HORIZONTAL_ALIGNMENT:
       {
-        if( impl.mController )
-        {
-          const char* name = Text::GetHorizontalAlignmentString( impl.mController->GetHorizontalAlignment() );
+        const char* name = Text::GetHorizontalAlignmentString( impl.mController->GetHorizontalAlignment() );
 
-           if ( name )
-           {
-             value = std::string( name );
-           }
+        if ( name )
+        {
+          value = std::string( name );
         }
         break;
       }
       case Toolkit::TextLabel::Property::VERTICAL_ALIGNMENT:
       {
-        if( impl.mController )
+        const char* name = Text::GetVerticalAlignmentString( impl.mController->GetVerticalAlignment() );
+        if( name )
         {
-          const char* name = Text::GetVerticalAlignmentString( impl.mController->GetVerticalAlignment() );
-          if( name )
-          {
-            value = std::string( name );
-          }
+          value = std::string( name );
         }
         break;
       }
       case Toolkit::TextLabel::Property::ENABLE_MARKUP:
       {
-        if( impl.mController )
-        {
-          value = impl.mController->IsMarkupProcessorEnabled();
-        }
+        value = impl.mController->IsMarkupProcessorEnabled();
         break;
       }
       case Toolkit::TextLabel::Property::ENABLE_AUTO_SCROLL:
       {
-        if( impl.mController )
-        {
-          value = impl.mController->IsAutoScrollEnabled();
-        }
+        value = impl.mController->IsAutoScrollEnabled();
         break;
       }
       case Toolkit::TextLabel::Property::AUTO_SCROLL_STOP_MODE:
@@ -678,7 +617,6 @@ Property::Value TextLabel::GetProperty( BaseObject* object, Property::Index inde
       }
       case Toolkit::TextLabel::Property::AUTO_SCROLL_SPEED:
       {
-        TextLabel& impl( GetImpl( label ) );
         if ( impl.mTextScroller )
         {
           value = impl.mTextScroller->GetSpeed();
@@ -687,31 +625,22 @@ Property::Value TextLabel::GetProperty( BaseObject* object, Property::Index inde
       }
       case Toolkit::TextLabel::Property::AUTO_SCROLL_LOOP_COUNT:
       {
-        if( impl.mController )
+        if ( impl.mTextScroller )
         {
-          TextLabel& impl( GetImpl( label ) );
-          if ( impl.mTextScroller )
-          {
-            value = impl.mTextScroller->GetLoopCount();
-          }
+          value = impl.mTextScroller->GetLoopCount();
         }
         break;
       }
       case Toolkit::TextLabel::Property::AUTO_SCROLL_LOOP_DELAY:
       {
-        if( impl.mController )
+        if ( impl.mTextScroller )
         {
-          TextLabel& impl( GetImpl( label ) );
-          if ( impl.mTextScroller )
-          {
-            value = impl.mTextScroller->GetLoopDelay();
-          }
+          value = impl.mTextScroller->GetLoopDelay();
         }
         break;
       }
       case Toolkit::TextLabel::Property::AUTO_SCROLL_GAP:
       {
-        TextLabel& impl( GetImpl( label ) );
         if ( impl.mTextScroller )
         {
           value = impl.mTextScroller->GetGap();
@@ -720,10 +649,7 @@ Property::Value TextLabel::GetProperty( BaseObject* object, Property::Index inde
       }
       case Toolkit::TextLabel::Property::LINE_SPACING:
       {
-        if( impl.mController )
-        {
-          value = impl.mController->GetDefaultLineSpacing();
-        }
+        value = impl.mController->GetDefaultLineSpacing();
         break;
       }
       case Toolkit::TextLabel::Property::UNDERLINE:
@@ -748,51 +674,33 @@ Property::Value TextLabel::GetProperty( BaseObject* object, Property::Index inde
       }
       case Toolkit::TextLabel::Property::PIXEL_SIZE:
       {
-        if( impl.mController )
-        {
-          value = impl.mController->GetDefaultFontSize( Text::Controller::PIXEL_SIZE );
-        }
+        value = impl.mController->GetDefaultFontSize( Text::Controller::PIXEL_SIZE );
         break;
       }
       case Toolkit::TextLabel::Property::ELLIPSIS:
       {
-        if( impl.mController )
-        {
-          value = impl.mController->IsTextElideEnabled();
-        }
+        value = impl.mController->IsTextElideEnabled();
         break;
       }
       case Toolkit::TextLabel::Property::LINE_WRAP_MODE:
       {
-        if( impl.mController )
-        {
-          value = impl.mController->GetLineWrapMode();
-        }
+        value = impl.mController->GetLineWrapMode();
         break;
       }
       case Toolkit::TextLabel::Property::LINE_COUNT:
       {
-        if( impl.mController )
-        {
-          float width = label.GetProperty( Actor::Property::SIZE_WIDTH ).Get<float>();
-          value = impl.mController->GetLineCount( width );
-        }
+        float width = label.GetProperty( Actor::Property::SIZE_WIDTH ).Get<float>();
+        value = impl.mController->GetLineCount( width );
         break;
       }
       case Toolkit::DevelTextLabel::Property::TEXT_DIRECTION:
       {
-        if( impl.mController )
-        {
-          value = impl.mController->GetTextDirection();
-        }
+        value = impl.mController->GetTextDirection();
         break;
       }
       case Toolkit::DevelTextLabel::Property::VERTICAL_LINE_ALIGNMENT:
       {
-        if( impl.mController )
-        {
-          value = impl.mController->GetVerticalLineAlignment();
-        }
+        value = impl.mController->GetVerticalLineAlignment();
         break;
       }
       case Toolkit::DevelTextLabel::Property::BACKGROUND:
@@ -829,10 +737,7 @@ Property::Value TextLabel::GetProperty( BaseObject* object, Property::Index inde
       }
       case Toolkit::DevelTextLabel::Property::MIN_LINE_SIZE:
       {
-        if( impl.mController )
-        {
-          value = impl.mController->GetDefaultLineSize();
-        }
+        value = impl.mController->GetDefaultLineSize();
         break;
       }
     }
@@ -854,10 +759,9 @@ void TextLabel::OnInitialize()
   TextVisual::SetAnimatableTextColorProperty( mVisual, Toolkit::TextLabel::Property::TEXT_COLOR );
 
   mController = TextVisual::GetController(mVisual);
-  if( mController )
-  {
-    mController->SetControlInterface(this);
-  }
+  DALI_ASSERT_DEBUG( mController && "Invalid Text Controller")
+
+  mController->SetControlInterface(this);
 
   // Use height-for-width negotiation by default
   self.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH );
index e88adbe..6631898 100644 (file)
@@ -344,7 +344,7 @@ void TextSelectionPopup::EnableButtons( Toolkit::TextSelectionPopup::Buttons but
   mButtonsChanged = true;
 }
 
-void TextSelectionPopup::RaiseAbove( Layer target )
+void TextSelectionPopup::RaiseAbove( Actor target )
 {
   if( mToolbar )
   {
index 09066c0..a94fee9 100644 (file)
@@ -122,7 +122,7 @@ public:
   /**
    * @copydoc Toolkit::TextSelectionPopup::RaiseAbove()
    */
-  void RaiseAbove( Layer target );
+  void RaiseAbove( Actor target );
 
   /**
    * @copydoc Toolkit::TextSelectionPopup::ShowPopup()
index 4a06886..8cdd32a 100644 (file)
@@ -184,10 +184,10 @@ void TextSelectionToolbar::OnRelayout( const Vector2& size, RelayoutContainer& c
 void TextSelectionToolbar::SetPopupMaxSize( const Size& maxSize )
 {
   mMaxSize = maxSize;
-  if (mScrollView && mToolbarLayer )
+  if( mScrollView && mToolbarActor )
   {
     mScrollView.SetProperty( Actor::Property::MAXIMUM_SIZE, mMaxSize );
-    mToolbarLayer.SetProperty( Actor::Property::MAXIMUM_SIZE, mMaxSize );
+    mToolbarActor.SetProperty( Actor::Property::MAXIMUM_SIZE, mMaxSize );
   }
 }
 
@@ -224,11 +224,11 @@ void TextSelectionToolbar::SetUp()
 
   self.SetResizePolicy( ResizePolicy::FIT_TO_CHILDREN, Dimension::ALL_DIMENSIONS );
 
-  // Create Layer to house the toolbar.
-  mToolbarLayer = Layer::New();
-  mToolbarLayer.SetResizePolicy( ResizePolicy::FIT_TO_CHILDREN, Dimension::ALL_DIMENSIONS );
-  mToolbarLayer.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER );
-  mToolbarLayer.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER );
+  // Create Actor to house the toolbar.
+  mToolbarActor = Actor::New();
+  mToolbarActor.SetResizePolicy( ResizePolicy::FIT_TO_CHILDREN, Dimension::ALL_DIMENSIONS );
+  mToolbarActor.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER );
+  mToolbarActor.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER );
 
   if( !mScrollView )
   {
@@ -243,9 +243,9 @@ void TextSelectionToolbar::SetUp()
   mTableOfButtons.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER_LEFT );
 
   mScrollView.Add( mTableOfButtons );
-  mToolbarLayer.Add( mScrollView );
+  mToolbarActor.Add( mScrollView );
 
-  self.Add( mToolbarLayer );
+  self.Add( mToolbarActor );
 }
 
 void TextSelectionToolbar::SetUpScrollBar( bool enable )
@@ -316,9 +316,9 @@ void TextSelectionToolbar::ResizeDividers( Size& size )
   RelayoutRequest();
 }
 
-void TextSelectionToolbar::RaiseAbove( Layer target )
+void TextSelectionToolbar::RaiseAbove( Actor target )
 {
-  mToolbarLayer.RaiseAbove( target );
+  mToolbarActor.RaiseAbove( target );
 }
 
 void TextSelectionToolbar::SetScrollBarPadding( const Vector2& padding )
index 5052ded..5cc4fda 100644 (file)
@@ -83,7 +83,7 @@ public:
   /**
    * @copydoc Toolkit::TextSelectionToolbar::RaiseAbove()
    */
-  void RaiseAbove( Layer target );
+  void RaiseAbove( Actor target );
 
   /**
    * Sets the scroll bar padding.
@@ -180,7 +180,7 @@ private:
 
 private: // Data
 
-  Layer mToolbarLayer;                                ///< The layer used to house the toolbar.
+  Actor mToolbarActor;                                ///< The actor used to house the toolbar.
   Toolkit::TableView mTableOfButtons;                 ///< Actor which holds all the buttons, sensitivity can be set on buttons via this actor
   Toolkit::ScrollView mScrollView;                    ///< Provides scrolling of Toolbar when content does not fit.
   Toolkit::ScrollBar mScrollBar;                      ///< An horizontal scroll bar for the text's popup options.
index 80a558e..e7f8b9f 100644 (file)
@@ -85,7 +85,7 @@ void Tooltip::SetProperties( const Property::Value& value )
   Toolkit::Control control = mControl.GetHandle();
   if( control )
   {
-    Property::Map* properties = value.GetMap();
+    const Property::Map* properties = value.GetMap();
     if( properties )
     {
       const Property::Map::SizeType count = properties->Count();
@@ -229,7 +229,7 @@ void Tooltip::SetContent( Toolkit::Control& control, const Property::Value& valu
   Property::Type type = value.GetType();
   if( type == Property::MAP )
   {
-    Property::Map* map = value.GetMap();
+    const Property::Map* map = value.GetMap();
     if( map )
     {
       mContentTextVisual.Merge( *map );
@@ -302,7 +302,7 @@ void Tooltip::SetBackground( const Property::Value& value )
   }
   else if( type == Property::MAP )
   {
-    Property::Map* map = value.GetMap();
+    const Property::Map* map = value.GetMap();
     if( map )
     {
       const Property::Map::SizeType count = map->Count();
old mode 100644 (file)
new mode 100755 (executable)
index 463a214..d7d812c
@@ -88,7 +88,7 @@ const char* const CUSTOM_SAMPLER_TYPE_NAME( "samplerExternalOES" );
 const char* VERTEX_SHADER = DALI_COMPOSE_SHADER(
   attribute mediump vec2 aPosition;\n
   uniform highp   mat4 uMvpMatrix;\n
-  uniform mediump vec3 uSize;\n
+  uniform highp   vec3 uSize;\n
   \n
   void main()\n
   {\n
@@ -110,7 +110,7 @@ const char* VERTEX_SHADER_TEXTURE = DALI_COMPOSE_SHADER(
   attribute mediump vec2 aPosition;\n
   varying mediump vec2 vTexCoord;\n
   uniform highp   mat4 uMvpMatrix;\n
-  uniform mediump vec3 uSize;\n
+  uniform highp   vec3 uSize;\n
   varying mediump vec2 sTexCoordRect;\n
   void main()\n
   {\n
@@ -228,11 +228,6 @@ bool VideoView::IsLooping()
 
 void VideoView::Play()
 {
-  if( mOverlayRenderer )
-  {
-    Self().AddRenderer( mOverlayRenderer );
-  }
-
   mVideoPlayer.Play();
   mIsPlay = true;
 }
@@ -295,11 +290,6 @@ Dali::Toolkit::VideoView::VideoViewSignalType& VideoView::FinishedSignal()
 
 void VideoView::EmitSignalFinish()
 {
-  if( mOverlayRenderer )
-  {
-    Self().RemoveRenderer( mOverlayRenderer );
-  }
-
   if ( !mFinishedSignal.Empty() )
   {
     Dali::Toolkit::VideoView handle( GetOwner() );
@@ -660,6 +650,7 @@ void VideoView::SetWindowSurfaceTarget()
     mOverlayRenderer = Renderer::New( geometry, shader );
     mOverlayRenderer.SetProperty( Renderer::Property::BLEND_MODE, BlendMode::OFF );
   }
+  Self().AddRenderer( mOverlayRenderer );
 
   if( mIsPlay )
   {
index 94be023..db8597b 100644 (file)
@@ -39,7 +39,7 @@ bool GetStringFromProperty( const Property::Value& value, std::string& output )
   }
   else
   {
-    Property::Array* array = value.GetArray();
+    const Property::Array* array = value.GetArray();
     if( array )
     {
       const unsigned int arraySize = array->Size();
index ad02368..7016759 100644 (file)
@@ -266,7 +266,8 @@ struct Decorator::Impl : public ConnectionTracker
     mHorizontalScrollingEnabled( false ),
     mVerticalScrollingEnabled( false ),
     mSmoothHandlePanEnabled( false ),
-    mIsHighlightBoxActive( false )
+    mIsHighlightBoxActive( false ),
+    mHidePrimaryCursorAndGrabHandle( false )
   {
     mQuadVertexFormat[ "aPosition" ] = Property::VECTOR2;
     mHighlightShader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER );
@@ -290,7 +291,7 @@ struct Decorator::Impl : public ConnectionTracker
     if( mPrimaryCursor )
     {
       const CursorImpl& cursor = mCursor[PRIMARY_CURSOR];
-      mPrimaryCursorVisible = ( ( mControlSize.width - ( cursor.position.x + mCursorWidth ) > -Math::MACHINE_EPSILON_1000 ) &&
+      mPrimaryCursorVisible = (!mHidePrimaryCursorAndGrabHandle) && ( ( mControlSize.width - ( cursor.position.x + mCursorWidth ) > -Math::MACHINE_EPSILON_1000 ) &&
                                 ( cursor.position.x > -Math::MACHINE_EPSILON_1000 ) &&
                                 ( mControlSize.height - ( cursor.position.y + cursor.cursorHeight ) > -Math::MACHINE_EPSILON_1000 ) &&
                                 ( cursor.position.y > -Math::MACHINE_EPSILON_1000 ) );
@@ -330,7 +331,7 @@ struct Decorator::Impl : public ConnectionTracker
       grabHandle.verticallyVisible = ( ( ( mControlSize.height - grabHandle.lineHeight ) - grabHandle.position.y > -Math::MACHINE_EPSILON_1000 ) &&
                                        ( grabHandle.position.y > -Math::MACHINE_EPSILON_1000 ) );
 
-      const bool isVisible = grabHandle.horizontallyVisible && grabHandle.verticallyVisible;
+      const bool isVisible = grabHandle.horizontallyVisible && grabHandle.verticallyVisible && (!mHidePrimaryCursorAndGrabHandle);
       if( isVisible )
       {
         CreateGrabHandle();
@@ -767,7 +768,7 @@ struct Decorator::Impl : public ConnectionTracker
   {
     if( !mActiveLayer )
     {
-      mActiveLayer = Layer::New();
+      mActiveLayer = Actor::New();
 #ifdef DECORATOR_DEBUG
       mActiveLayer.SetProperty( Actor::Property::NAME, "ActiveLayerActor" );
 #endif
@@ -1881,7 +1882,7 @@ struct Decorator::Impl : public ConnectionTracker
   Timer               mCursorBlinkTimer;          ///< Timer to signal cursor to blink
   Timer               mScrollTimer;               ///< Timer used to scroll the text when the grab handle is moved close to the edges.
 
-  Layer                mActiveLayer;                             ///< Layer for active handles and alike that ensures they are above all else.
+  Actor                mActiveLayer;                             ///< Actor for active handles and alike that ensures they are above all else.
   PropertyNotification mHandleVerticalLessThanNotification;      ///< Notifies when the 'y' coord of the active layer is less than a given value.
   PropertyNotification mHandleVerticalGreaterThanNotification;   ///< Notifies when the 'y' coord of the active layer is grater than a given value.
   PropertyNotification mHandleHorizontalLessThanNotification;    ///< Notifies when the 'x' coord of the active layer is less than a given value.
@@ -1945,6 +1946,7 @@ struct Decorator::Impl : public ConnectionTracker
   bool                mVerticalScrollingEnabled          : 1; ///< Whether the vertical scrolling is enabled.
   bool                mSmoothHandlePanEnabled            : 1; ///< Whether to pan smoothly the handles.
   bool                mIsHighlightBoxActive              : 1; ///< Whether the highlight box is active.
+  bool                mHidePrimaryCursorAndGrabHandle    : 1; ///< Whether the primary cursor and grab are hidden always.
 };
 
 DecoratorPtr Decorator::New( ControllerInterface& controller,
@@ -2093,6 +2095,11 @@ int Decorator::GetCursorWidth() const
   return static_cast<int>( mImpl->mCursorWidth );
 }
 
+void Decorator::SetEditable( bool editable )
+{
+  mImpl->mHidePrimaryCursorAndGrabHandle = !editable;
+  mImpl->Relayout( mImpl->mControlSize );
+}
 /** Handles **/
 
 void Decorator::SetHandleActive( HandleType handleType, bool active )
index 8d0894f..0d0b25b 100644 (file)
@@ -579,6 +579,15 @@ public:
    */
   void SetScrollSpeed( float speed );
 
+ /**
+   * @brief Sets Editable mode decoration.
+   *
+   * If this set to false, Primary cursor and grab will always be hidden.
+   *
+   * @param[in] isEditable enable or disable Editing.
+   */
+  void SetEditable( bool isEditable );
+
   /**
    * @brief Retrieves the scroll speed.
    *
index 0a8fe4b..bfce755 100644 (file)
@@ -159,7 +159,8 @@ EventData::EventData( DecoratorPtr decorator, InputMethodContext& inputMethodCon
   mIsPlaceholderElideEnabled( false ),
   mPlaceholderEllipsisFlag( false ),
   mShiftSelectionFlag( true ),
-  mUpdateAlignment( false )
+  mUpdateAlignment( false ),
+  mEditingEnabled( true )
 {
 }
 
@@ -2040,6 +2041,67 @@ void Controller::Impl::OnSelectNoneEvent()
   }
 }
 
+void Controller::Impl::SetTextSelectionRange(const uint32_t *pStart, const uint32_t *pEnd)
+{
+  if( nullptr == mEventData )
+  {
+    // Nothing to do if there is no text.
+    return;
+  }
+
+  if( mEventData->mSelectionEnabled && (pStart || pEnd))
+  {
+    uint32_t length = static_cast<uint32_t>(mModel->mLogicalModel->mText.Count());
+
+    if (pStart)
+    {
+      mEventData->mLeftSelectionPosition = std::min(*pStart, length);
+    }
+    if (pEnd)
+    {
+      mEventData->mRightSelectionPosition = std::min(*pEnd, length);
+    }
+
+    if (mEventData->mLeftSelectionPosition == mEventData->mRightSelectionPosition)
+    {
+      ChangeState( EventData::EDITING );
+      mEventData->mPrimaryCursorPosition = mEventData->mLeftSelectionPosition = mEventData->mRightSelectionPosition;
+      mEventData->mUpdateCursorPosition = true;
+    }
+    else
+    {
+      ChangeState( EventData::SELECTING );
+      mEventData->mUpdateHighlightBox = true;
+    }
+  }
+}
+
+Uint32Pair Controller::Impl::GetTextSelectionRange() const
+{
+  Uint32Pair range;
+
+  if( mEventData )
+  {
+    range.first = mEventData->mLeftSelectionPosition;
+    range.second = mEventData->mRightSelectionPosition;
+  }
+
+  return range;
+}
+
+bool Controller::Impl::IsEditable() const
+{
+  return mEventData && mEventData->mEditingEnabled;
+}
+
+void Controller::Impl::SetEditable( bool editable )
+{
+  if( mEventData)
+  {
+    mEventData->mEditingEnabled = editable;
+  }
+}
+
 void Controller::Impl::RetrieveSelection( std::string& selectedText, bool deleteAfterRetrieval )
 {
   if( mEventData->mLeftSelectionPosition == mEventData->mRightSelectionPosition )
@@ -2645,15 +2707,23 @@ void Controller::Impl::SetPopupButtons()
    *  If EDITING_WITH_POPUP : SELECT & SELECT_ALL
    */
 
+  bool isEditable = IsEditable();
   TextSelectionPopup::Buttons buttonsToShow = TextSelectionPopup::NONE;
 
   if( EventData::SELECTING == mEventData->mState )
   {
-    buttonsToShow = TextSelectionPopup::Buttons(  TextSelectionPopup::CUT | TextSelectionPopup::COPY );
+    buttonsToShow = TextSelectionPopup::Buttons( TextSelectionPopup::COPY );
+    if(isEditable)
+    {
+      buttonsToShow = TextSelectionPopup::Buttons( buttonsToShow | TextSelectionPopup::CUT );
+    }
 
     if( !IsClipboardEmpty() )
     {
-      buttonsToShow = TextSelectionPopup::Buttons ( ( buttonsToShow | TextSelectionPopup::PASTE ) );
+      if(isEditable)
+      {
+        buttonsToShow = TextSelectionPopup::Buttons ( ( buttonsToShow | TextSelectionPopup::PASTE ) );
+      }
       buttonsToShow = TextSelectionPopup::Buttons ( ( buttonsToShow | TextSelectionPopup::CLIPBOARD ) );
     }
 
@@ -2671,7 +2741,10 @@ void Controller::Impl::SetPopupButtons()
 
     if( !IsClipboardEmpty() )
     {
-      buttonsToShow = TextSelectionPopup::Buttons ( ( buttonsToShow | TextSelectionPopup::PASTE ) );
+      if(isEditable)
+      {
+        buttonsToShow = TextSelectionPopup::Buttons ( ( buttonsToShow | TextSelectionPopup::PASTE ) );
+      }
       buttonsToShow = TextSelectionPopup::Buttons ( ( buttonsToShow | TextSelectionPopup::CLIPBOARD ) );
     }
   }
@@ -2679,7 +2752,10 @@ void Controller::Impl::SetPopupButtons()
   {
     if ( !IsClipboardEmpty() )
     {
-      buttonsToShow = TextSelectionPopup::Buttons ( ( buttonsToShow | TextSelectionPopup::PASTE ) );
+      if(isEditable)
+      {
+        buttonsToShow = TextSelectionPopup::Buttons ( ( buttonsToShow | TextSelectionPopup::PASTE ) );
+      }
       buttonsToShow = TextSelectionPopup::Buttons ( ( buttonsToShow | TextSelectionPopup::CLIPBOARD ) );
     }
   }
index 981e498..3fc33b3 100755 (executable)
@@ -48,6 +48,8 @@ const float DEFAULT_TEXTFIT_STEP = 1.f;
 struct CursorInfo;
 struct FontDefaults;
 
+class SelectableControlInterface;
+
 struct Event
 {
   // Used to queue input events until DoRelayout()
@@ -170,6 +172,7 @@ struct EventData
   bool mPlaceholderEllipsisFlag         : 1;   ///< True if the text controller sets the placeholder ellipsis.
   bool mShiftSelectionFlag              : 1;   ///< True if the text selection using Shift key is enabled.
   bool mUpdateAlignment                 : 1;   ///< True if the whole text needs to be full aligned..
+  bool mEditingEnabled                   : 1;   ///< True if the editing is enabled, false otherwise.
 };
 
 struct ModifyEvent
@@ -308,9 +311,11 @@ struct OutlineDefaults
 struct Controller::Impl
 {
   Impl( ControlInterface* controlInterface,
-        EditableControlInterface* editableControlInterface )
+        EditableControlInterface* editableControlInterface,
+        SelectableControlInterface* selectableControlInterface )
   : mControlInterface( controlInterface ),
     mEditableControlInterface( editableControlInterface ),
+    mSelectableControlInterface( selectableControlInterface ),
     mModel(),
     mFontDefaults( NULL ),
     mUnderlineDefaults( NULL ),
@@ -623,6 +628,26 @@ struct Controller::Impl
   void OnSelectNoneEvent();
 
   /**
+   * @copydoc Text::SelectableControlInterface::SetTextSelectionRange()
+   */
+  void SetTextSelectionRange(const uint32_t *pStart, const uint32_t *pEndf);
+
+  /**
+   * @copydoc Text::SelectableControlInterface::GetTextSelectionRange()
+   */
+  Uint32Pair GetTextSelectionRange() const;
+
+  /**
+   * @copydoc Text::EditableControlInterface::IsEditable()
+   */
+  bool IsEditable() const;
+
+  /**
+   * @copydoc Text::EditableControlInterface::SetEditable()
+   */
+  void SetEditable( bool editable );
+
+  /**
    * @brief Retrieves the selected text. It removes the text if the @p deleteAfterRetrieval parameter is @e true.
    *
    * @param[out] selectedText The selected text encoded in utf8.
@@ -757,6 +782,7 @@ public:
 
   ControlInterface* mControlInterface;     ///< Reference to the text controller.
   EditableControlInterface* mEditableControlInterface; ///< Reference to the editable text controller.
+  SelectableControlInterface* mSelectableControlInterface; ///< Reference to the selectable text controller.
   ModelPtr mModel;                         ///< Pointer to the text's model.
   FontDefaults* mFontDefaults;             ///< Avoid allocating this when the user does not specify a font.
   UnderlineDefaults* mUnderlineDefaults;   ///< Avoid allocating this when the user does not specify underline parameters.
index 4edac33..ca02bac 100755 (executable)
@@ -53,6 +53,8 @@ const std::string EMPTY_STRING("");
 const std::string KEY_C_NAME = "c";
 const std::string KEY_V_NAME = "v";
 const std::string KEY_X_NAME = "x";
+const std::string KEY_A_NAME = "a";
+const std::string KEY_INSERT_NAME = "Insert";
 
 const char * const PLACEHOLDER_TEXT = "text";
 const char * const PLACEHOLDER_TEXT_FOCUSED = "textFocused";
@@ -141,10 +143,12 @@ ControllerPtr Controller::New( ControlInterface* controlInterface )
 }
 
 ControllerPtr Controller::New( ControlInterface* controlInterface,
-                               EditableControlInterface* editableControlInterface )
+                               EditableControlInterface* editableControlInterface,
+                               SelectableControlInterface* selectableControlInterface )
 {
   return ControllerPtr( new Controller( controlInterface,
-                                        editableControlInterface ) );
+                                        editableControlInterface,
+                                        selectableControlInterface ) );
 }
 
 // public : Configure the text controller.
@@ -2905,12 +2909,12 @@ bool Controller::KeyEvent( const Dali::KeyEvent& keyEvent )
       // Do nothing
       return false;
     }
-    else if ( keyEvent.IsCtrlModifier() )
+    else if ( keyEvent.IsCtrlModifier() && !keyEvent.IsShiftModifier())
     {
       bool consumed = false;
-      if (keyName == KEY_C_NAME)
+      if (keyName == KEY_C_NAME || keyName == KEY_INSERT_NAME)
       {
-        // Ctrl-C to copy the selected text
+        // Ctrl-C or Ctrl+Insert to copy the selected text
         TextPopupButtonTouched( Toolkit::TextSelectionPopup::COPY );
         consumed = true;
       }
@@ -2926,6 +2930,12 @@ bool Controller::KeyEvent( const Dali::KeyEvent& keyEvent )
         TextPopupButtonTouched( Toolkit::TextSelectionPopup::CUT );
         consumed = true;
       }
+      else if (keyName == KEY_A_NAME)
+      {
+        // Ctrl-A to select All the text
+        TextPopupButtonTouched( Toolkit::TextSelectionPopup::SELECT_ALL );
+        consumed = true;
+      }
       return consumed;
     }
     else if( ( Dali::DALI_KEY_BACKSPACE == keyCode ) ||
@@ -2965,6 +2975,7 @@ bool Controller::KeyEvent( const Dali::KeyEvent& keyEvent )
     else
     {
       DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Controller::KeyEvent %p keyString %s\n", this, keyString.c_str() );
+      if (!IsEditable()) return false;
 
       if( !keyString.empty() )
       {
@@ -3185,6 +3196,24 @@ void Controller::SelectEvent( float x, float y, SelectionType selectType )
   }
 }
 
+void Controller::SetTextSelectionRange(const uint32_t *start, const uint32_t *end)
+{
+  if( mImpl->mEventData )
+  {
+    mImpl->mEventData->mCheckScrollAmount = true;
+    mImpl->mEventData->mIsLeftHandleSelected = true;
+    mImpl->mEventData->mIsRightHandleSelected = true;
+    mImpl->SetTextSelectionRange(start, end);
+    mImpl->RequestRelayout();
+    KeyboardFocusGainEvent();
+  }
+}
+
+Uint32Pair Controller::GetTextSelectionRange() const
+{
+  return mImpl->GetTextSelectionRange();
+}
+
 InputMethodContext::CallbackData Controller::OnInputMethodContextEvent( InputMethodContext& inputMethodContext, const InputMethodContext::EventData& inputMethodContextEvent )
 {
   // Whether the text needs to be relaid-out.
@@ -3340,6 +3369,20 @@ void Controller::AddDecoration( Actor& actor, bool needsClipping )
   }
 }
 
+bool Controller::IsEditable() const
+{
+  return mImpl->IsEditable();
+}
+
+void Controller::SetEditable( bool editable )
+{
+  mImpl->SetEditable( editable );
+  if(mImpl->mEventData && mImpl->mEventData->mDecorator)
+  {
+    mImpl->mEventData->mDecorator->SetEditable( editable );
+  }
+}
+
 void Controller::DecorationEvent( HandleType handleType, HandleState state, float x, float y )
 {
   DALI_ASSERT_DEBUG( mImpl->mEventData && "Unexpected DecorationEvent" );
@@ -3407,6 +3450,7 @@ void Controller::TextPopupButtonTouched( Dali::Toolkit::TextSelectionPopup::Butt
   {
     case Toolkit::TextSelectionPopup::CUT:
     {
+      if (!IsEditable()) return;
       mImpl->SendSelectionToClipboard( true ); // Synchronous call to modify text
       mImpl->mOperationsPending = ALL_OPERATIONS;
 
@@ -4196,6 +4240,8 @@ void Controller::TextDeletedEvent()
     return;
   }
 
+  if (!IsEditable()) return;
+
   mImpl->mEventData->mCheckScrollAmount = true;
 
   // The natural size needs to be re-calculated.
@@ -4219,6 +4265,8 @@ bool Controller::DeleteEvent( int keyCode )
     return removed;
   }
 
+  if (!IsEditable()) return false;
+
   // InputMethodContext is no longer handling key-events
   mImpl->ClearPreEditFlag();
 
@@ -4440,19 +4488,21 @@ Actor Controller::CreateBackgroundActor()
 Controller::Controller()
 : mImpl( NULL )
 {
-  mImpl = new Controller::Impl( NULL, NULL );
+  mImpl = new Controller::Impl( nullptr, nullptr, nullptr );
 }
 
 Controller::Controller( ControlInterface* controlInterface )
 {
-  mImpl = new Controller::Impl( controlInterface, NULL );
+  mImpl = new Controller::Impl( controlInterface, NULL, NULL );
 }
 
 Controller::Controller( ControlInterface* controlInterface,
-                        EditableControlInterface* editableControlInterface )
+                        EditableControlInterface* editableControlInterface,
+                        SelectableControlInterface* selectableControlInterface )
 {
   mImpl = new Controller::Impl( controlInterface,
-                                editableControlInterface );
+                                editableControlInterface,
+                                selectableControlInterface );
 }
 
 // The copy constructor and operator are left unimplemented.
index 4d40f41..e523dd2 100755 (executable)
@@ -31,6 +31,7 @@
 #include <dali-toolkit/internal/text/layouts/layout-engine.h>
 #include <dali-toolkit/internal/text/hidden-text.h>
 #include <dali-toolkit/internal/text/text-model-interface.h>
+#include <dali-toolkit/internal/text/text-selectable-control-interface.h>
 
 namespace Dali
 {
@@ -187,11 +188,13 @@ public: // Constructor.
    *
    * @param[in] controlInterface The control's interface.
    * @param[in] editableControlInterface The editable control's interface.
+   * @param[in] selectableControlInterface The selectable control's interface.
    *
    * @return A pointer to a new Controller.
    */
   static ControllerPtr New( ControlInterface* controlInterface,
-                            EditableControlInterface* editableControlInterface );
+                            EditableControlInterface* editableControlInterface,
+                            SelectableControlInterface* selectableControlInterface );
 
 public: // Configure the text controller.
 
@@ -1493,6 +1496,26 @@ public: // Text-input Event Queuing.
   void SelectEvent( float x, float y, SelectionType selection );
 
   /**
+   * @copydoc Text::SelectableControlInterface::SetTextSelectionRange()
+   */
+  void SetTextSelectionRange(const uint32_t *start, const uint32_t *end);
+
+  /**
+   * @copydoc Text::SelectableControlInterface::GetTextSelectionRange()
+   */
+  Uint32Pair GetTextSelectionRange() const;
+
+  /**
+   * @copydoc Text::EditableControlInterface::IsEditable()
+   */
+  virtual bool IsEditable() const;
+
+  /**
+   * @copydoc Text::EditableControlInterface::SetEditable()
+   */
+  virtual void SetEditable( bool editable );
+
+  /**
    * @brief Event received from input method context
    *
    * @param[in] inputMethodContext The input method context.
@@ -1698,7 +1721,8 @@ private: // Private contructors & copy operator.
    * @brief Private constructor.
    */
   Controller( ControlInterface* controlInterface,
-              EditableControlInterface* editableControlInterface );
+              EditableControlInterface* editableControlInterface,
+              SelectableControlInterface* selectableControlInterface );
 
   // Undefined
   Controller( const Controller& handle );
index e54704c..abfbb59 100644 (file)
@@ -69,6 +69,20 @@ public:
    * @param[in] needsClipping Whether the actor needs clipping.
    */
   virtual void AddDecoration( Actor& actor, bool needsClipping ) = 0;
+
+  /**
+   * @brief Editable status (on/off).
+   *
+   * @return true if it can be edit, else false.
+   */
+  virtual bool IsEditable() const = 0;
+
+  /**
+   * @brief Change the editable status (on/off) .
+   *
+   * @param[in] editable The editable status.
+   */
+  virtual void SetEditable( bool editable ) = 0;
 };
 
 } // namespace Text
old mode 100644 (file)
new mode 100755 (executable)
index 22f1156..b2c1b19
@@ -42,7 +42,7 @@ 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
-  uniform mediump vec3 uSize;\n
+  uniform highp vec3 uSize;\n
   uniform mediump float uDelta;\n
   uniform mediump vec2 uTextureSize;\n
   uniform mediump float uGap;\n
@@ -53,7 +53,7 @@ const char* VERTEX_SHADER_SCROLL = DALI_COMPOSE_SHADER(
   \n
   //Visual size and offset
   uniform mediump vec2 offset;\n
-  uniform mediump vec2 size;\n
+  uniform highp vec2 size;\n
   uniform mediump vec4 offsetSizeMode;\n
   uniform mediump vec2 origin;\n
   uniform mediump vec2 anchorPoint;\n
@@ -271,7 +271,10 @@ void TextScroller::SetParameters( Actor scrollingTextActor, Renderer renderer, T
 
     // Reset to the original shader and texture before scrolling
     mRenderer.SetShader(mShader);
-    mRenderer.SetTextures( mTextureSet );
+    if( mTextureSet )
+    {
+      mRenderer.SetTextures( mTextureSet );
+    }
   }
 
   mShader = mRenderer.GetShader();
diff --git a/dali-toolkit/internal/text/text-selectable-control-interface.h b/dali-toolkit/internal/text/text-selectable-control-interface.h
new file mode 100644 (file)
index 0000000..fe70abb
--- /dev/null
@@ -0,0 +1,63 @@
+#ifndef DALI_TOOLKIT_TEXT_SELECTABLE_CONTROL_INTERFACE_H
+#define DALI_TOOLKIT_TEXT_SELECTABLE_CONTROL_INTERFACE_H
+
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+using  Uint32Pair = std::pair<uint32_t,uint32_t>;
+namespace Text
+{
+
+/**
+ * @brief An interface that the Text::Controller used for text selection functionality.
+ */
+class SelectableControlInterface
+{
+public:
+
+  /**
+   * @brief Virtual destructor.
+   */
+  virtual ~SelectableControlInterface() = default;
+
+  /**
+   * @brief Called to set the selection postions in the texts.
+   * @param start start selection position (pass NULL to ignore).
+   * @param end end selection position (pass NULL to ignore).
+   */
+  virtual void SetTextSelectionRange(const uint32_t *start, const uint32_t *end) = 0;
+
+  /**
+   * @brief Called to return the selection postions in the texts.
+   * @return pair contains start and end positions.
+   */
+  virtual Uint32Pair GetTextSelectionRange() const = 0;
+};
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_TEXT_SELECTABLE_CONTROL_INTERFACE_H
index 0a045f0..05d1724 100755 (executable)
@@ -96,7 +96,7 @@ const Toolkit::DevelAnimatedGradientVisual::AnimationParameter::EasingType::Type
 const char* const BASIC_VERTEX_SHADER = DALI_COMPOSE_SHADER(
   attribute mediump vec2 aPosition;
   uniform highp   mat4 uMvpMatrix;
-  uniform mediump vec3 uSize;
+  uniform highp   vec3 uSize;
 
   uniform mediump vec2 start_point;
   uniform mediump vec2 end_point;
@@ -118,7 +118,7 @@ const char* const BASIC_VERTEX_SHADER = DALI_COMPOSE_SHADER(
 
   //Visual size and offset
   uniform mediump vec2 offset;
-  uniform mediump vec2 size;
+  uniform highp vec2 size;
   uniform mediump vec4 offsetSizeMode;
   uniform mediump vec2 origin;
   uniform mediump vec2 anchorPoint;
index 453f14e..ea097e1 100644 (file)
@@ -217,7 +217,7 @@ void AnimatedVectorImageVisual::DoSetProperty( Property::Index index, const Prop
     }
     case Toolkit::DevelImageVisual::Property::PLAY_RANGE:
     {
-      Property::Array* array = value.GetArray();
+      const Property::Array* array = value.GetArray();
       if( array )
       {
         mAnimationData.playRange = *array;
@@ -406,7 +406,7 @@ void AnimatedVectorImageVisual::OnDoAction( const Property::Index actionId, cons
     }
     case DevelAnimatedVectorImageVisual::Action::UPDATE_PROPERTY:
     {
-      Property::Map* map = attributes.GetMap();
+      const Property::Map* map = attributes.GetMap();
       if( map )
       {
         DoSetProperties( *map );
index a16d72c..babfc94 100644 (file)
@@ -276,7 +276,7 @@ void ArcVisual::OnDoAction( const Property::Index actionId, const Property::Valu
   {
     case DevelArcVisual::Action::UPDATE_PROPERTY:
     {
-      Property::Map* map = attributes.GetMap();
+      const Property::Map* map = attributes.GetMap();
       if( map )
       {
         DoSetProperties( *map );
index 47667fc..03412bf 100644 (file)
@@ -49,13 +49,13 @@ const char* VERTEX_SHADER = DALI_COMPOSE_SHADER(
   attribute mediump vec2 aPosition;\n
   attribute mediump vec2 aDrift;\n
   uniform highp   mat4 uMvpMatrix;\n
-  uniform mediump vec3 uSize;\n
+  uniform highp   vec3 uSize;\n
   uniform mediump float borderSize;\n
   \n
 
   //Visual size and offset
   uniform mediump vec2 offset;\n
-  uniform mediump vec2 size;\n
+  uniform highp   vec2 size;\n
   uniform mediump vec4 offsetSizeMode;\n
   uniform mediump vec2 origin;\n
   uniform mediump vec2 anchorPoint;\n
@@ -89,7 +89,7 @@ const char* VERTEX_SHADER_ANTI_ALIASING = DALI_COMPOSE_SHADER(
   attribute mediump vec2 aPosition;\n
   attribute mediump vec2 aDrift;\n
   uniform highp   mat4 uMvpMatrix;\n
-  uniform mediump vec3 uSize;\n
+  uniform highp   vec3 uSize;\n
   uniform mediump float borderSize;\n
   varying mediump float vAlpha;\n
   \n
index dce5255..4fae268 100644 (file)
@@ -46,12 +46,12 @@ namespace
 const char* VERTEX_SHADER = DALI_COMPOSE_SHADER(
   attribute mediump vec2 aPosition;\n
   uniform highp   mat4 uMvpMatrix;\n
-  uniform mediump vec3 uSize;\n
+  uniform highp   vec3 uSize;\n
   \n
 
   //Visual size and offset
   uniform mediump vec2 offset;\n
-  uniform mediump vec2 size;\n
+  uniform highp   vec2 size;\n
   uniform mediump vec4 offsetSizeMode;\n
   uniform mediump vec2 origin;\n
   uniform mediump vec2 anchorPoint;\n
@@ -83,14 +83,14 @@ const char* FRAGMENT_SHADER = DALI_COMPOSE_SHADER(
 const char* VERTEX_SHADER_ROUNDED_CORNER = DALI_COMPOSE_SHADER(
   attribute mediump vec2 aPosition;\n
   uniform highp   mat4 uMvpMatrix;\n
-  uniform mediump vec3 uSize;\n
+  uniform highp   vec3 uSize;\n
   varying mediump vec2 vPosition;\n
   varying mediump vec2 vRectSize;\n
   varying mediump float vCornerRadius;\n
   \n
   //Visual size and offset
   uniform mediump vec2 offset;\n
-  uniform mediump vec2 size;\n
+  uniform highp   vec2 size;\n
   uniform mediump vec2 extraSize;\n
   uniform mediump vec4 offsetSizeMode;\n
   uniform mediump vec2 origin;\n
@@ -135,13 +135,13 @@ const char* FRAGMENT_SHADER_ROUNDED_CORNER = DALI_COMPOSE_SHADER(
 const char* VERTEX_SHADER_BLUR_EDGE = DALI_COMPOSE_SHADER(
   attribute mediump vec2 aPosition;\n
   uniform highp   mat4 uMvpMatrix;\n
-  uniform mediump vec3 uSize;\n
+  uniform highp vec3 uSize;\n
   varying mediump vec2 vPosition;\n
   varying mediump vec2 vRectSize;\n
   \n
   //Visual size and offset
   uniform mediump vec2 offset;\n
-  uniform mediump vec2 size;\n
+  uniform highp vec2 size;\n
   uniform mediump vec2 extraSize;\n
   uniform mediump vec4 offsetSizeMode;\n
   uniform mediump vec2 origin;\n
@@ -289,7 +289,7 @@ void ColorVisual::OnDoAction( const Property::Index actionId, const Property::Va
   {
     case DevelColorVisual::Action::UPDATE_PROPERTY:
     {
-      Property::Map* map = attributes.GetMap();
+      const Property::Map* map = attributes.GetMap();
       if( map )
       {
         DoSetProperties( *map );
index d5af5a4..462a6c0 100644 (file)
@@ -88,14 +88,14 @@ const char* VERTEX_SHADER[] =
 DALI_COMPOSE_SHADER(
   attribute mediump vec2 aPosition;\n
   uniform highp   mat4 uMvpMatrix;\n
-  uniform mediump vec3 uSize;\n
+  uniform highp   vec3 uSize;\n
   uniform mediump mat3 uAlignmentMatrix;\n
   varying mediump vec2 vTexCoord;\n
   \n
 
   //Visual size and offset
   uniform mediump vec2 offset;\n
-  uniform mediump vec2 size;\n
+  uniform highp   vec2 size;\n
   uniform mediump vec4 offsetSizeMode;\n
   uniform mediump vec2 origin;\n
   uniform mediump vec2 anchorPoint;\n
@@ -120,14 +120,14 @@ DALI_COMPOSE_SHADER(
 DALI_COMPOSE_SHADER(
   attribute mediump vec2 aPosition;\n
   uniform highp   mat4 uMvpMatrix;\n
-  uniform mediump vec3 uSize;\n
+  uniform highp   vec3 uSize;\n
   uniform mediump mat3 uAlignmentMatrix;\n
   varying mediump vec2 vTexCoord;\n
   \n
 
   //Visual size and offset
   uniform mediump vec2 offset;\n
-  uniform mediump vec2 size;\n
+  uniform highp   vec2 size;\n
   uniform mediump vec4 offsetSizeMode;\n
   uniform mediump vec2 origin;\n
   uniform mediump vec2 anchorPoint;\n
@@ -153,7 +153,7 @@ DALI_COMPOSE_SHADER(
 DALI_COMPOSE_SHADER(
   attribute mediump vec2 aPosition;\n
   uniform highp   mat4 uMvpMatrix;\n
-  uniform mediump vec3 uSize;\n
+  uniform highp   vec3 uSize;\n
   uniform mediump mat3 uAlignmentMatrix;\n
   varying mediump vec2 vTexCoord;\n
   varying mediump vec2 vPosition;\n
@@ -162,7 +162,7 @@ DALI_COMPOSE_SHADER(
   \n
   //Visual size and offset
   uniform mediump vec2 offset;\n
-  uniform mediump vec2 size;\n
+  uniform highp   vec2 size;\n
   uniform mediump vec4 offsetSizeMode;\n
   uniform mediump vec2 origin;\n
   uniform mediump vec2 anchorPoint;\n
@@ -194,7 +194,7 @@ DALI_COMPOSE_SHADER(
 DALI_COMPOSE_SHADER(
   attribute mediump vec2 aPosition;\n
   uniform highp   mat4 uMvpMatrix;\n
-  uniform mediump vec3 uSize;\n
+  uniform highp   vec3 uSize;\n
   uniform mediump mat3 uAlignmentMatrix;\n
   varying mediump vec2 vTexCoord;\n
   varying mediump vec2 vPosition;\n
@@ -203,7 +203,7 @@ DALI_COMPOSE_SHADER(
   \n
   //Visual size and offset
   uniform mediump vec2 offset;\n
-  uniform mediump vec2 size;\n
+  uniform highp   vec2 size;\n
   uniform mediump vec4 offsetSizeMode;\n
   uniform mediump vec2 origin;\n
   uniform mediump vec2 anchorPoint;\n
@@ -589,7 +589,7 @@ void GradientVisual::GetStopOffsets(const Property::Value* value, Vector<float>&
       }
       case Property::ARRAY:
       {
-        Property::Array* offsetArray = value->GetArray();
+        const Property::Array* offsetArray = value->GetArray();
         if( offsetArray )
         {
           unsigned int numStop = offsetArray->Count();
index beb4f09..45d0e3f 100644 (file)
@@ -39,13 +39,13 @@ const Vector4 FULL_TEXTURE_RECT(0.f, 0.f, 1.f, 1.f);
 const char* VERTEX_SHADER = DALI_COMPOSE_SHADER(
   attribute mediump vec2 aPosition;\n
   uniform highp   mat4 uMvpMatrix;\n
-  uniform mediump vec3 uSize;\n
+  uniform highp   vec3 uSize;\n
   uniform mediump vec4 pixelArea;
   varying mediump vec2 vTexCoord;\n
   \n
   //Visual size and offset
   uniform mediump vec2 offset;\n
-  uniform mediump vec2 size;\n
+  uniform highp   vec2 size;\n
   uniform mediump vec4 offsetSizeMode;\n
   uniform mediump vec2 origin;\n
   uniform mediump vec2 anchorPoint;\n
index b8abd9b..b0324ed 100644 (file)
@@ -23,6 +23,8 @@
 #include <dali/public-api/actors/layer.h>
 #include <dali/devel-api/common/stage.h>
 #include <dali/devel-api/adaptor-framework/image-loading.h>
+#include <dali/devel-api/rendering/renderer-devel.h>
+#include <dali/devel-api/rendering/texture-devel.h>
 #include <dali/devel-api/scripting/enum-helper.h>
 #include <dali/devel-api/scripting/scripting.h>
 #include <dali/integration-api/debug.h>
@@ -40,7 +42,6 @@
 #include <dali-toolkit/internal/visuals/visual-base-data-impl.h>
 #include <dali-toolkit/internal/visuals/visual-url.h>
 #include <dali-toolkit/internal/visuals/image-visual-shader-factory.h>
-#include <dali/devel-api/rendering/renderer-devel.h>
 
 namespace Dali
 {
@@ -514,42 +515,78 @@ void ImageVisual::CreateRenderer( TextureSet& textureSet )
   Geometry geometry;
   Shader shader;
 
-  if( !mImpl->mCustomShader )
+  // Get the geometry
+  if( mImpl->mCustomShader )
+  {
+    geometry = CreateGeometry( mFactoryCache, mImpl->mCustomShader->mGridSize );
+  }
+  else // Get any geometry associated with the texture
   {
     TextureManager& textureManager = mFactoryCache.GetTextureManager();
 
     uint32_t firstElementCount {0u};
     uint32_t secondElementCount {0u};
     geometry = textureManager.GetRenderGeometry(mTextureId, firstElementCount, secondElementCount);
-    if(!firstElementCount && !secondElementCount)
+
+    if(!firstElementCount && !secondElementCount) // Otherwise use quad
     {
       geometry = CreateGeometry( mFactoryCache, ImageDimensions( 1, 1 ) );
     }
+  }
 
-    shader = mImageVisualShaderFactory.GetShader( mFactoryCache,
-                             mImpl->mFlags & Impl::IS_ATLASING_APPLIED,
-                             mWrapModeU <= WrapMode::CLAMP_TO_EDGE && mWrapModeV <= WrapMode::CLAMP_TO_EDGE,
-                             IsRoundedCornerRequired() );
+  std::string vertexShader;
+  bool usesWholeTexture = true;
+  if(mImpl->mCustomShader && !mImpl->mCustomShader->mVertexShader.empty())
+  {
+    vertexShader = mImpl->mCustomShader->mVertexShader;
+    usesWholeTexture = false; // Impossible to tell.
   }
   else
   {
-    geometry = CreateGeometry( mFactoryCache, mImpl->mCustomShader->mGridSize );
-    if( mImpl->mCustomShader->mVertexShader.empty() && mImpl->mCustomShader->mFragmentShader.empty() )
-    {
-      // Use custom hints
-      shader = Shader::New( mImageVisualShaderFactory.GetVertexShaderSource(), mImageVisualShaderFactory.GetFragmentShaderSource(), mImpl->mCustomShader->mHints );
-      shader.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT );
-    }
-    else
-    {
-      shader = Shader::New( mImpl->mCustomShader->mVertexShader.empty() ? mImageVisualShaderFactory.GetVertexShaderSource() : mImpl->mCustomShader->mVertexShader,
-                            mImpl->mCustomShader->mFragmentShader.empty() ? mImageVisualShaderFactory.GetFragmentShaderSource() : mImpl->mCustomShader->mFragmentShader,
-                            mImpl->mCustomShader->mHints );
-      if( mImpl->mCustomShader->mVertexShader.empty() )
-      {
-        shader.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT );
-      }
-    }
+    vertexShader = mImageVisualShaderFactory.GetVertexShaderSource();
+  }
+
+  std::string fragmentShader;
+  if(mImpl->mCustomShader && !mImpl->mCustomShader->mFragmentShader.empty())
+  {
+    fragmentShader = mImpl->mCustomShader->mFragmentShader;
+  }
+  else
+  {
+    fragmentShader = mImageVisualShaderFactory.GetFragmentShaderSource();
+  }
+
+  // If the texture is native, we may need to change prefix and sampler in
+  // the fragment shader
+  bool modifiedFragmentShader = false;
+  if(mTextures && DevelTexture::IsNative(mTextures.GetTexture(0)))
+  {
+    Texture nativeTexture = mTextures.GetTexture(0);
+    modifiedFragmentShader = DevelTexture::ApplyNativeFragmentShader(nativeTexture, fragmentShader);
+  }
+
+  const bool useStandardShader = !mImpl->mCustomShader && !modifiedFragmentShader;
+  if(useStandardShader)
+  {
+    // Create and cache the standard shader
+    shader = mImageVisualShaderFactory.GetShader(
+      mFactoryCache,
+      mImpl->mFlags & Impl::IS_ATLASING_APPLIED,
+      mWrapModeU <= WrapMode::CLAMP_TO_EDGE && mWrapModeV <= WrapMode::CLAMP_TO_EDGE,
+      IsRoundedCornerRequired() );
+  }
+  else if(mImpl->mCustomShader)
+  {
+    shader = Shader::New(vertexShader, fragmentShader, mImpl->mCustomShader->mHints);
+  }
+  else
+  {
+    shader = Shader::New(vertexShader, fragmentShader);
+  }
+
+  if(usesWholeTexture)
+  {
+    shader.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT );
   }
 
   // Set pixel align off as default.
@@ -557,7 +594,9 @@ void ImageVisual::CreateRenderer( TextureSet& textureSet )
   // We should trun it off until issues are resolved
   shader.RegisterProperty( PIXEL_ALIGNED_UNIFORM_NAME, PIXEL_ALIGN_OFF );
 
+  // Create the renderer
   mImpl->mRenderer = Renderer::New( geometry, shader );
+
   if( textureSet )
   {
     mImpl->mRenderer.SetTextures( textureSet );
@@ -570,6 +609,7 @@ void ImageVisual::CreateRenderer( TextureSet& textureSet )
   EnablePreMultipliedAlpha( IsPreMultipliedAlphaEnabled() );
 }
 
+
 void ImageVisual::LoadTexture( bool& atlasing, Vector4& atlasRect, TextureSet& textures, bool orientationCorrection,
                                TextureManager::ReloadPolicy forceReload )
 {
index b954c8c..bd374aa 100644 (file)
@@ -51,14 +51,14 @@ const char* VERTEX_SHADER = DALI_COMPOSE_SHADER(
   varying mediump vec2 vTexCoord;\n
   varying mediump vec2 vMaskTexCoord;\n
   uniform highp   mat4 uMvpMatrix;\n
-  uniform mediump vec3 uSize;\n
+  uniform highp   vec3 uSize;\n
   uniform mediump vec2 uNinePatchFactorsX[ FACTOR_SIZE_X ];\n
   uniform mediump vec2 uNinePatchFactorsY[ FACTOR_SIZE_Y ];\n
   \n
 
   // Visual size and offset
   uniform mediump vec2 offset;\n
-  uniform mediump vec2 size;\n
+  uniform highp   vec2 size;\n
   uniform mediump vec4 offsetSizeMode;\n
   uniform mediump vec2 origin;\n
   uniform mediump vec2 anchorPoint;\n
@@ -93,13 +93,13 @@ const char* VERTEX_SHADER_3X3 = DALI_COMPOSE_SHADER(
     varying mediump vec2 vTexCoord;\n
     varying mediump vec2 vMaskTexCoord;\n
     uniform highp   mat4 uMvpMatrix;\n
-    uniform mediump vec3 uSize;\n
+    uniform highp   vec3 uSize;\n
     uniform mediump vec2 uFixed[ 3 ];\n
     uniform mediump vec2 uStretchTotal;\n
     \n
     //Visual size and offset
     uniform mediump vec2 offset;\n
-    uniform mediump vec2 size;\n
+    uniform highp   vec2 size;\n
     uniform mediump vec4 offsetSizeMode;\n
     uniform mediump vec2 origin;\n
     uniform mediump vec2 anchorPoint;\n
index f0dc4a4..151eda8 100644 (file)
@@ -24,7 +24,9 @@
 #include <dali/integration-api/debug.h>
 
 // INTERNAL INCLUDES
+#ifdef NO_THORVG
 #include <dali-toolkit/third-party/nanosvg/nanosvgrast.h>
+#endif /* NO_THORVG */
 #include <dali-toolkit/internal/visuals/svg/svg-visual.h>
 
 namespace Dali
@@ -41,6 +43,7 @@ namespace
 const char * const UNITS("px");
 }
 
+#ifdef NO_THORVG
 RasterizingTask::RasterizingTask( SvgVisual* svgRenderer, NSVGimage* parsedSvg, const VisualUrl& url, float dpi, unsigned int width, unsigned int height)
 : mSvgVisual( svgRenderer ),
   mParsedSvg( parsedSvg ),
@@ -51,14 +54,30 @@ RasterizingTask::RasterizingTask( SvgVisual* svgRenderer, NSVGimage* parsedSvg,
 {
   mRasterizer = nsvgCreateRasterizer();
 }
+#else /* NO_THORVG */
+RasterizingTask::RasterizingTask( SvgVisual* svgRenderer, VectorImageRenderer vectorRenderer, const VisualUrl& url, float dpi, unsigned int width, unsigned int height, bool loaded)
+: mSvgVisual( svgRenderer ),
+  mVectorRenderer( vectorRenderer ),
+  mUrl( url ),
+  mDpi( dpi ),
+  mWidth( width ),
+  mHeight( height ),
+  mLoaded( loaded )
+{
+
+}
+#endif /* NO_THORVG */
 
 RasterizingTask::~RasterizingTask()
 {
+#ifdef NO_THORVG
   nsvgDeleteRasterizer( mRasterizer );
+#endif /* NO_THORVG */
 }
 
 void RasterizingTask::Load()
 {
+#ifdef NO_THORVG
   if( mParsedSvg != NULL)
   {
     return;
@@ -77,10 +96,33 @@ void RasterizingTask::Load()
     remoteBuffer.PushBack( '\0' );
     mParsedSvg = nsvgParse( reinterpret_cast<char*>(remoteBuffer.begin()), UNITS, mDpi );
   }
+#else /* NO_THORVG */
+  if( !mLoaded &&  !mUrl.IsLocalResource() )
+  {
+    Dali::Vector<uint8_t> remoteBuffer;
+
+    if( !Dali::FileLoader::DownloadFileSynchronously( mUrl.GetUrl(), remoteBuffer ))
+    {
+      DALI_LOG_ERROR("Failed to download file!\n");
+      return;
+    }
+
+    remoteBuffer.PushBack( '\0' );
+    char *data = reinterpret_cast<char*>(remoteBuffer.begin());
+    if ( !mVectorRenderer.Load( data, remoteBuffer.Size()))
+    {
+      DALI_LOG_ERROR( "Failed to load data!\n" );
+      return;
+    }
+
+    mLoaded = true;
+  }
+#endif /* NO_THORVG */
 }
 
 void RasterizingTask::Rasterize( )
 {
+#ifdef NO_THORVG
   if( mParsedSvg != NULL && mWidth > 0u && mHeight > 0u )
   {
     float scaleX = static_cast<float>( mWidth ) /  mParsedSvg->width;
@@ -96,12 +138,54 @@ void RasterizingTask::Rasterize( )
 
     mPixelData = Dali::PixelData::New( buffer, bufferSize, mWidth, mHeight, Pixel::RGBA8888, Dali::PixelData::DELETE_ARRAY );
   }
+#else /* NO_THORVG */
+  if ( mWidth <= 0u || mHeight <= 0u )
+  {
+    DALI_LOG_ERROR( "Size is zero!\n" );
+    return;
+  }
+
+  Devel::PixelBuffer pixelBuffer = Devel::PixelBuffer::New( mWidth, mHeight, Dali::Pixel::RGBA8888 );
+  mVectorRenderer.SetBuffer( pixelBuffer );
+  {
+    uint32_t defaultWidth, defaultHeight;
+    mVectorRenderer.GetDefaultSize( defaultWidth, defaultHeight );
+
+    float scaleX = static_cast<float>( mWidth ) / static_cast<float>( defaultWidth );
+    float scaleY = static_cast<float>( mHeight ) / static_cast<float>( defaultHeight );
+    float scale = scaleX < scaleY ? scaleX : scaleY;
+
+    if ( !mVectorRenderer.Render( scale ) )
+    {
+      DALI_LOG_ERROR( "SVG Render Fail!\n" );
+      return;
+    }
+
+    mPixelData = Devel::PixelBuffer::Convert( pixelBuffer );
+    if ( !mPixelData )
+    {
+      DALI_LOG_ERROR( "Pixel Data is null\n" );
+    }
+  }
+#endif /* NO_THORVG */
 }
 
+#ifdef NO_THORVG
 NSVGimage* RasterizingTask::GetParsedImage() const
 {
   return mParsedSvg;
 }
+#else /* NO_THORVG */
+VectorImageRenderer RasterizingTask::GetVectorRenderer() const
+{
+  return mVectorRenderer;
+}
+
+bool RasterizingTask::IsLoaded() const
+{
+  return mLoaded;
+}
+#endif /* NO_THORVG */
 
 SvgVisual* RasterizingTask::GetSvgVisual() const
 {
@@ -203,6 +287,7 @@ void SvgRasterizeThread::RemoveTask( SvgVisual* visual )
   }
 }
 
+#ifdef NO_THORVG
 void SvgRasterizeThread::DeleteImage( NSVGimage* parsedSvg )
 {
   // Lock while adding image to the delete queue
@@ -217,6 +302,22 @@ void SvgRasterizeThread::DeleteImage( NSVGimage* parsedSvg )
     mDeleteSvg.PushBack( parsedSvg );
   }
 }
+#else /* NO_THORVG */
+void SvgRasterizeThread::DeleteImage( VectorImageRenderer vectorRenderer )
+{
+  // Lock while adding image to the delete queue
+  ConditionalWait::ScopedLock lock( mConditionalWait );
+
+  if( mIsThreadWaiting ) // no rasterization is ongoing, save to delete
+  {
+    // TODO: what?
+  }
+  else // wait to delete until current rasterization completed.
+  {
+    mDeleteSvg.PushBack( &vectorRenderer );
+  }
+}
+#endif /* NO_THORVG */
 
 RasterizingTaskPtr SvgRasterizeThread::NextTaskToProcess()
 {
@@ -226,12 +327,14 @@ RasterizingTaskPtr SvgRasterizeThread::NextTaskToProcess()
   // Delete the image here to make sure that it is not used in the nsvgRasterize()
   if( !mDeleteSvg.Empty() )
   {
+#ifdef NO_THORVG
     for( Vector< NSVGimage* >::Iterator it = mDeleteSvg.Begin(), endIt = mDeleteSvg.End();
         it != endIt;
         ++it )
     {
       nsvgDelete( *it );
     }
+#endif /* NO_THORVG */
     mDeleteSvg.Clear();
   }
 
index 11fa03f..5c8b323 100644 (file)
 #include <dali/public-api/rendering/texture-set.h>
 #include <dali-toolkit/internal/visuals/visual-url.h>
 
+#ifdef NO_THORVG
 struct NSVGimage;
 struct NSVGrasterizer;
+#else /* NO_THORVG */
+#include <string.h>
+#include <dali/devel-api/adaptor-framework/vector-image-renderer.h>
+#endif /* NO_THORVG */
 
 namespace Dali
 {
@@ -58,6 +63,7 @@ typedef IntrusivePtr< RasterizingTask > RasterizingTaskPtr;
 class RasterizingTask : public RefObject
 {
 public:
+#ifdef NO_THORVG
   /**
    * Constructor
    *
@@ -70,6 +76,17 @@ public:
    * @param[in] height The rasterization height.
    */
   RasterizingTask( SvgVisual* svgRenderer, NSVGimage* parsedSvg, const VisualUrl& url, float dpi, unsigned int width, unsigned int height );
+#else /* NO_THORVG */
+  /**
+   * Constructor
+   * @param[in] svgRenderer The renderer which the rasterized image to be applied.
+   * @param[in] url The URL to svg resource to use.
+   * @param[in] width The rasterization width.
+   * @param[in] height The rasterization height.
+   * @param[in] loaded The svg resource is loaded or not.
+   */
+  RasterizingTask( SvgVisual* svgRenderer, VectorImageRenderer vectorRenderer, const VisualUrl& url, float dpi, unsigned int width, unsigned int height, bool loaded );
+#endif /* NO_THORVG */
 
   /**
    * Destructor.
@@ -92,11 +109,31 @@ public:
    */
   PixelData GetPixelData() const;
 
+#ifdef NO_THORVG
   /**
    * Get the parsed data.
    * @return parsed image data.
    */
   NSVGimage* GetParsedImage() const;
+  /**
+   * Get default size of svg
+   *
+   * @param[out] width The default width of svg
+   * @param[out] height The default height of svg
+   */
+  void GetDefaultSize( uint32_t& width, uint32_t& height ) const;
+#else /* NO_THORVG */
+  /**
+   * Get the VectorRenderer.
+   * @return VectorRenderer.
+   */
+  VectorImageRenderer GetVectorRenderer() const;
+  /**
+   * Whether the resource is loaded.
+   * @return True if the resource is loaded.
+   */
+  bool IsLoaded() const;
+#endif /* NO_THORVG */
 
   /**
    * Load svg file
@@ -112,13 +149,21 @@ private:
 
 private:
   SvgVisualPtr    mSvgVisual;
+#ifdef NO_THORVG
   NSVGimage*      mParsedSvg;
+#else /* NO_THORVG */
+  VectorImageRenderer mVectorRenderer;
+#endif /* NO_THORVG */
   VisualUrl       mUrl;
   PixelData       mPixelData;
   float           mDpi;
   unsigned int    mWidth;
   unsigned int    mHeight;
+#ifdef NO_THORVG
   NSVGrasterizer* mRasterizer;
+#else /* NO_THORVG */
+  bool            mLoaded;
+#endif /* NO_THORVG */
 };
 
 /**
@@ -163,14 +208,25 @@ public:
    */
   void RemoveTask( SvgVisual* visual );
 
+#ifdef NO_THORVG
   /**
    * Delete the parsed SVG image, called by main thread.
    *
-   * The parsed svg should be delelted in worker thread, as the main thread does not know whether a rasterization of this svg is ongoing.
+   * The parsed svg should be deleted in worker thread, as the main thread does not know whether a rasterization of this svg is ongoing.
    *
    * @param[in] parsedImage The image to be deleted
    */
   void DeleteImage( NSVGimage* parsedSvg );
+#else /* NO_THORVG */
+  /**
+   * Delete the parsed SVG image, called by main thread.
+   *
+   * The parsed svg should be deleted in worker thread, as the main thread does not know whether a rasterization of this svg is ongoing.
+   *
+   * @param[in] VectorImage The image to be deleted
+   */
+  void DeleteImage( VectorImageRenderer vectorImage );
+#endif /* NO_THORVG */
 
 private:
 
@@ -214,7 +270,11 @@ private:
 
   std::vector<RasterizingTaskPtr>  mRasterizeTasks;     //The queue of the tasks waiting to rasterize the SVG image
   std::vector <RasterizingTaskPtr> mCompletedTasks;     //The queue of the tasks with the SVG rasterization completed
+#ifdef NO_THORVG
   Vector<NSVGimage*>               mDeleteSvg;          //The images that the event thread requested to delete
+#else /* NO_THORVG */
+  Vector <VectorImageRenderer*>      mDeleteSvg;          //The images that the event thread requested to delete
+#endif /* NO_THORVG */
 
   ConditionalWait            mConditionalWait;
   Dali::Mutex                mMutex;
index a9989c0..0e005b3 100644 (file)
 #include "svg-visual.h"
 
 // INTERNAL INCLUDES
+#ifdef NO_THORVG
 #include <dali-toolkit/third-party/nanosvg/nanosvg.h>
 #include <dali-toolkit/third-party/nanosvg/nanosvgrast.h>
+#endif /* NO_THORVG */
 #include <dali-toolkit/internal/visuals/svg/svg-rasterize-thread.h>
 #include <dali-toolkit/internal/visuals/image-atlas-manager.h>
 #include <dali-toolkit/internal/visuals/visual-string-constants.h>
@@ -54,8 +56,13 @@ const Dali::Vector4 FULL_TEXTURE_RECT(0.f, 0.f, 1.f, 1.f);
 SvgVisualPtr SvgVisual::New( VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl, const Property::Map& properties )
 {
   SvgVisualPtr svgVisual( new SvgVisual( factoryCache, shaderFactory, imageUrl ) );
+#ifdef NO_THORVG
   svgVisual->ParseFromUrl( imageUrl );
   svgVisual->SetProperties( properties );
+#else /* NO_THORVG */
+  svgVisual->Load();
+  svgVisual->SetProperties( properties );
+#endif /* NO_THORVG */
 
   return svgVisual;
 }
@@ -63,7 +70,11 @@ SvgVisualPtr SvgVisual::New( VisualFactoryCache& factoryCache, ImageVisualShader
 SvgVisualPtr SvgVisual::New( VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl )
 {
   SvgVisualPtr svgVisual( new SvgVisual( factoryCache, shaderFactory, imageUrl ) );
+#ifdef NO_THORVG
   svgVisual->ParseFromUrl( imageUrl );
+#else /* NO_THORVG */
+  svgVisual->Load();
+#endif /* NO_THORVG */
 
   return svgVisual;
 }
@@ -73,7 +84,15 @@ SvgVisual::SvgVisual( VisualFactoryCache& factoryCache, ImageVisualShaderFactory
   mImageVisualShaderFactory( shaderFactory ),
   mAtlasRect( FULL_TEXTURE_RECT ),
   mImageUrl( imageUrl ),
+#ifdef NO_THORVG
   mParsedImage( NULL ),
+#else
+  mVectorRenderer( VectorImageRenderer::New() ),
+  mDefaultWidth( 0 ),
+  mDefaultHeight( 0 ),
+  mLoaded( false ),
+  mLocalResource( true ),
+#endif /* NO_THORVG */
   mPlacementActor(),
   mVisualSize(Vector2::ZERO),
   mAttemptAtlasing( false )
@@ -84,10 +103,12 @@ SvgVisual::SvgVisual( VisualFactoryCache& factoryCache, ImageVisualShaderFactory
 
 SvgVisual::~SvgVisual()
 {
+#ifdef NO_THORVG
   if( mParsedImage )
   {
     nsvgDelete( mParsedImage );
   }
+#endif /* NO_THORVG */
 }
 
 void SvgVisual::DoSetProperties( const Property::Map& propertyMap )
@@ -190,11 +211,19 @@ void SvgVisual::DoSetOffScene( Actor& actor )
 
 void SvgVisual::GetNaturalSize( Vector2& naturalSize )
 {
+#ifdef NO_THORVG
   if( mParsedImage )
   {
     naturalSize.x = mParsedImage->width;
     naturalSize.y = mParsedImage->height;
   }
+#else /* NO_THORVG */
+  if ( mLoaded )
+  {
+    naturalSize.x = mDefaultWidth;
+    naturalSize.y = mDefaultHeight;
+  }
+#endif /* NO_THORVG */
   else
   {
     naturalSize = Vector2::ZERO;
@@ -218,6 +247,7 @@ void SvgVisual::DoCreateInstancePropertyMap( Property::Map& map ) const
   // Do nothing
 }
 
+#ifdef NO_THORVG
 void SvgVisual::ParseFromUrl( const VisualUrl& imageUrl )
 {
   mImageUrl = imageUrl;
@@ -233,6 +263,33 @@ void SvgVisual::ParseFromUrl( const VisualUrl& imageUrl )
     }
   }
 }
+#else /* NO_THORVG */
+void SvgVisual::Load()
+{
+  if( mLoaded || !mLocalResource )
+  {
+    return;
+  }
+
+  mLocalResource = mImageUrl.IsLocalResource();
+
+  if( !mLocalResource )
+  {
+    // load remote resource on svg rasterize thread.
+    return;
+  }
+
+  if( !mVectorRenderer.Load( mImageUrl.GetUrl() ) )
+  {
+    DALI_LOG_ERROR( "Failed to load file!\n" );
+    return;
+  }
+
+  mVectorRenderer.GetDefaultSize(mDefaultWidth, mDefaultHeight);
+  mLoaded = true;
+}
+#endif /* NO_THORVG */
+
 
 void SvgVisual::AddRasterizationTask( const Vector2& size )
 {
@@ -244,11 +301,21 @@ void SvgVisual::AddRasterizationTask( const Vector2& size )
     Vector2 dpi = Stage::GetCurrent().GetDpi();
     float meanDpi = ( dpi.height + dpi.width ) * 0.5f;
 
+#ifdef NO_THORVG
     RasterizingTaskPtr newTask = new RasterizingTask( this, mParsedImage, mImageUrl, meanDpi, width, height );
+#else /* NO_THORVG */
+    RasterizingTaskPtr newTask = new RasterizingTask( this, mVectorRenderer, mImageUrl, meanDpi, width, height, mLoaded );
+#endif /* NO_THORVG */
     if ( IsSynchronousLoadingRequired() )
     {
+#ifdef NO_THORVG
       newTask->Rasterize();
       ApplyRasterizedImage( newTask->GetParsedImage(), newTask->GetPixelData() );
+#else /* NO_THORVG */
+      newTask->Load();
+      newTask->Rasterize();
+      ApplyRasterizedImage( newTask->GetVectorRenderer(), newTask->GetPixelData(), newTask->IsLoaded() );
+#endif /* NO_THORVG */
     }
     else
     {
@@ -257,6 +324,7 @@ void SvgVisual::AddRasterizationTask( const Vector2& size )
   }
 }
 
+#ifdef NO_THORVG
 void SvgVisual::ApplyRasterizedImage( NSVGimage* parsedSvg, PixelData rasterizedPixelData )
 {
   if( mParsedImage == NULL)
@@ -265,6 +333,13 @@ void SvgVisual::ApplyRasterizedImage( NSVGimage* parsedSvg, PixelData rasterized
   }
 
   if( mParsedImage && IsOnScene() )
+#else /* NO_THORVG */
+void SvgVisual::ApplyRasterizedImage( VectorImageRenderer vectorRenderer, PixelData rasterizedPixelData, bool isLoaded )
+{
+  mLoaded = isLoaded;
+
+  if( isLoaded && rasterizedPixelData && IsOnScene() )
+#endif /* NO_THORVG */
   {
     TextureSet currentTextureSet = mImpl->mRenderer.GetTextures();
     if( mImpl->mFlags & Impl::IS_ATLASING_APPLIED )
@@ -328,7 +403,11 @@ void SvgVisual::ApplyRasterizedImage( NSVGimage* parsedSvg, PixelData rasterized
    // Svg loaded and ready to display
    ResourceReady( Toolkit::Visual::ResourceStatus::READY );
   }
+#ifdef NO_THORVG
   else if( !mParsedImage )
+#else /* NO_THORVG */
+  else if( !isLoaded || !rasterizedPixelData )
+#endif /* NO_THORVG */
   {
     ResourceReady( Toolkit::Visual::ResourceStatus::FAILED );
   }
index e18d5cf..0f1dc95 100644 (file)
@@ -26,7 +26,9 @@
 #include <dali-toolkit/internal/visuals/visual-base-impl.h>
 #include <dali-toolkit/internal/visuals/visual-url.h>
 
+#ifdef NO_THORVG
 struct NSVGimage;
+#endif /* NO_THORVG */
 
 namespace Dali
 {
@@ -142,6 +144,7 @@ protected:
 
 public:
 
+#ifdef NO_THORVG
   /**
    * @bried Apply the rasterized image to the visual.
    *
@@ -149,14 +152,31 @@ public:
    * @param[in] rasterizedPixelData The pixel buffer with the rasterized pixels
    */
   void ApplyRasterizedImage( NSVGimage* parsedSvg, PixelData rasterizedPixelData );
+#else /* NO_THORVG */
+  /**
+   * @bried Apply the rasterized image to the visual.
+   *
+   * @param[in] vectorImage The data of vector image.
+   * @param[in] rasterizedPixelData The pixel buffer with the rasterized pixels
+   * @param[in] bool Whether the resource is loaded
+   */
+  void ApplyRasterizedImage( VectorImageRenderer vectorImage, PixelData rasterizedPixelData, bool isLoaded );
+#endif /* NO_THORVG */
 
 private:
+#ifdef NO_THORVG
   /**
     * @brief Parses the SVG Image from the set URL.
     *
     * @param[in] imageUrl The URL of the image to parse the SVG from.
     */
    void ParseFromUrl( const VisualUrl& imageUrl );
+#else /* NO_THORVG */
+  /**
+    * @brief Load the SVG Image from the set URL.
+    */
+   void Load();
+#endif /* NO_THORVG */
 
   /**
    * @bried Rasterize the svg with the given size, and add it to the visual.
@@ -182,7 +202,15 @@ private:
   ImageVisualShaderFactory& mImageVisualShaderFactory;
   Vector4                   mAtlasRect;
   VisualUrl                 mImageUrl;
+#ifdef NO_THORVG
   NSVGimage*                mParsedImage;
+#else /* NO_THORVG */
+  VectorImageRenderer       mVectorRenderer;
+  uint32_t                  mDefaultWidth;
+  uint32_t                  mDefaultHeight;
+  bool                      mLoaded;
+  bool                      mLocalResource;
+#endif /* NO_THORVG */
   WeakHandle<Actor>         mPlacementActor;
   Vector2                   mVisualSize;
   bool                      mAttemptAtlasing;  ///< If true will attempt atlasing, otherwise create unique texture
index 1d75634..f8d5f53 100755 (executable)
@@ -58,14 +58,14 @@ const Vector4 FULL_TEXTURE_RECT( 0.f, 0.f, 1.f, 1.f );
 const char* VERTEX_SHADER = DALI_COMPOSE_SHADER(
   attribute mediump vec2 aPosition;\n
   uniform highp   mat4 uMvpMatrix;\n
-  uniform mediump vec3 uSize;\n
+  uniform highp   vec3 uSize;\n
   uniform mediump vec4 pixelArea;\n
 
   varying mediump vec2 vTexCoord;\n
 
   //Visual size and offset
   uniform mediump vec2 offset;\n
-  uniform mediump vec2 size;\n
+  uniform highp   vec2 size;\n
   uniform mediump vec4 offsetSizeMode;\n
   uniform mediump vec2 origin;\n
   uniform mediump vec2 anchorPoint;\n
@@ -301,7 +301,7 @@ TextVisualPtr TextVisual::New( VisualFactoryCache& factoryCache, const Property:
   return TextVisualPtr;
 }
 
-void TextVisual::ConvertStringKeysToIndexKeys( Property::Map& propertyMap )
+Property::Map TextVisual::ConvertStringKeysToIndexKeys( const Property::Map& propertyMap )
 {
   Property::Map outMap;
 
@@ -319,7 +319,7 @@ void TextVisual::ConvertStringKeysToIndexKeys( Property::Map& propertyMap )
     outMap.Insert( indexKey, keyValue.second );
   }
 
-  propertyMap = outMap;
+  return outMap;
 }
 
 float TextVisual::GetHeightForWidth( float width )
index e6c0ab8..136a23f 100755 (executable)
@@ -81,9 +81,10 @@ public:
 
   /**
    * @brief Converts all strings keys in property map to index keys.  Property Map can then be merged correctly.
-   * @param[in,out] propertyMap containing string keys or a mix of strings and indexes. Will be changed to index keys.
+   * @param[in] propertyMap containing string keys or a mix of strings and indexes.
+   * @return Property::Map containing index keys.
    */
-  static void ConvertStringKeysToIndexKeys( Property::Map& propertyMap );
+  static Property::Map ConvertStringKeysToIndexKeys( const Property::Map& propertyMap );
 
   /**
    * @brief Retrieve the text's controller.
index a91b8ab..78dab18 100644 (file)
@@ -101,7 +101,7 @@ void TransitionData::Initialize( const Property::Array& array )
     const Property::Value& element = array.GetElementAt( arrayIdx );
     // Expect each child to be an object representing an animator:
 
-    Property::Map* map = element.GetMap();
+    const Property::Map* map = element.GetMap();
     if( map != NULL )
     {
       TransitionData::Animator* animator = ConvertMap( *map );
@@ -173,12 +173,12 @@ TransitionData::Animator* TransitionData::ConvertMap( const Property::Map& map)
           {
             bool valid = true;
             Vector4 controlPoints;
-            Property::Array *array = value.GetArray();
+            const Property::Array* array = value.GetArray();
             if( array && array->Count() >= 4 )
             {
               for( size_t vecIdx = 0; vecIdx < 4; ++vecIdx )
               {
-                Property::Value& v = array->GetElementAt(vecIdx);
+                const Property::Value& v = array->GetElementAt(vecIdx);
                 if( v.GetType() == Property::FLOAT )
                 {
                   controlPoints[vecIdx] = v.Get<float>();
index ba9f925..631f61b 100644 (file)
@@ -95,7 +95,7 @@ bool GetPolicyFromValue( const Property::Value& value, Vector2& policy )
   }
   else
   {
-    Property::Array* array = value.GetArray();
+    const Property::Array* array = value.GetArray();
     if( array && array->Size() == 2 )
     {
       Toolkit::Visual::Transform::Policy::Type xPolicy = static_cast< Toolkit::Visual::Transform::Policy::Type >( -1 ); // Assign an invalid value so definitely changes
index 218ba4f..ad5bcb3 100644 (file)
@@ -144,7 +144,11 @@ void VisualFactoryCache::ApplyRasterizedSVGToSampler()
 {
   while( RasterizingTaskPtr task = mSvgRasterizeThread->NextCompletedTask() )
   {
+#ifdef NO_THORVG
     task->GetSvgVisual()->ApplyRasterizedImage( task->GetParsedImage(), task->GetPixelData() );
+#else /* NO_THORVG */
+    task->GetSvgVisual()->ApplyRasterizedImage( task->GetVectorRenderer(), task->GetPixelData(), task->IsLoaded() );
+#endif /* NO_THORVG */
   }
 }
 
index ba3b651..3707465 100644 (file)
@@ -43,12 +43,12 @@ const char * const INDEX_NAME("indices");
 const char* VERTEX_SHADER = DALI_COMPOSE_SHADER(
 attribute mediump vec2  aPosition;\n
 uniform   highp   mat4  uMvpMatrix;\n
-uniform   mediump vec3  uSize;\n
+uniform   highp   vec3  uSize;\n
 \n
 
 //Visual size and offset
 uniform mediump vec2 offset;\n
-uniform mediump vec2 size;\n
+uniform highp   vec2 size;\n
 uniform mediump vec4 offsetSizeMode;\n
 uniform mediump vec2 origin;\n
 uniform mediump vec2 anchorPoint;\n
index 55bc3d0..6717f5b 100644 (file)
@@ -387,11 +387,10 @@ protected: // Helpers for deriving classes
    */
   enum ControlBehaviour
   {
-    CONTROL_BEHAVIOUR_DEFAULT = 0, ///< Default behaviour: Size negotiation is enabled & listens to Style Change signal, but doesn't receive event callbacks. @SINCE_1_2_10
-
-    REQUIRES_KEYBOARD_NAVIGATION_SUPPORT = 1 << (CustomActorImpl::ACTOR_FLAG_COUNT + 0), ///< True if needs to support keyboard navigation @SINCE_1_0.0
-
-    DISABLE_STYLE_CHANGE_SIGNALS = 1 << (CustomActorImpl::ACTOR_FLAG_COUNT + 1), ///< True if control should not monitor style change signals @SINCE_1_2_10
+    CONTROL_BEHAVIOUR_DEFAULT            = 0, ///< Default behaviour: Size negotiation is enabled & listens to Style Change signal, but doesn't receive event callbacks. @SINCE_1_2_10
+    NOT_IN_USE_1                         = 1 << (CustomActorImpl::ACTOR_FLAG_COUNT + 0),
+    REQUIRES_KEYBOARD_NAVIGATION_SUPPORT = 1 << (CustomActorImpl::ACTOR_FLAG_COUNT + 1), ///< True if needs to support keyboard navigation @SINCE_1_0.0
+    DISABLE_STYLE_CHANGE_SIGNALS         = 1 << (CustomActorImpl::ACTOR_FLAG_COUNT + 2), ///< True if control should not monitor style change signals @SINCE_1_2_10
 
     LAST_CONTROL_BEHAVIOUR_FLAG
   };
index d355b35..e452c16 100644 (file)
@@ -29,7 +29,7 @@ namespace Toolkit
 {
 const unsigned int TOOLKIT_MAJOR_VERSION = 1;
 const unsigned int TOOLKIT_MINOR_VERSION = 9;
-const unsigned int TOOLKIT_MICRO_VERSION = 28;
+const unsigned int TOOLKIT_MICRO_VERSION = 32;
 const char* const  TOOLKIT_BUILD_DATE    = __DATE__ " " __TIME__;
 
 #ifdef DEBUG_ENABLED
index df51c53..46686cd 100644 (file)
@@ -1,6 +1,6 @@
 Name:       dali2-toolkit
 Summary:    Dali 3D engine Toolkit
-Version:    1.9.28
+Version:    1.9.32
 Release:    1
 Group:      System/Libraries
 License:    Apache-2.0 and BSD-3-Clause and MIT