Merge "Modified key event in TC" into devel/master
authortaeyoon0.lee <taeyoon0.lee@samsung.com>
Wed, 12 Jul 2017 16:24:50 +0000 (16:24 +0000)
committerGerrit Code Review <gerrit@review.ap-northeast-2.compute.internal>
Wed, 12 Jul 2017 16:24:50 +0000 (16:24 +0000)
18 files changed:
automated-tests/src/dali-toolkit-internal/CMakeLists.txt
automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Cursor.cpp
automated-tests/src/dali-toolkit-styling/CMakeLists.txt
automated-tests/src/dali-toolkit-third-party/CMakeLists.txt
automated-tests/src/dali-toolkit/CMakeLists.txt
automated-tests/src/dali-toolkit/utc-Dali-Control.cpp
automated-tests/src/dali-toolkit/utc-Dali-PushButton.cpp
automated-tests/src/dali-toolkit/utc-Dali-Visual.cpp
dali-toolkit/internal/controls/control/control-data-impl.cpp
dali-toolkit/internal/controls/control/control-data-impl.h
dali-toolkit/internal/controls/image-view/image-view-impl.cpp
dali-toolkit/internal/text/cursor-helper-functions.cpp
dali-toolkit/internal/text/cursor-helper-functions.h
dali-toolkit/internal/text/text-controller-impl.cpp
dali-toolkit/internal/text/text-controller.cpp
dali-toolkit/public-api/controls/control-impl.cpp
dali-toolkit/public-api/dali-toolkit-version.cpp
packaging/dali-toolkit.spec

index b9554e9..366c44c 100755 (executable)
@@ -68,7 +68,8 @@ PKG_CHECK_MODULES(${CAPI_LIB} REQUIRED
     dali-toolkit
 )
 
-SET(CMAKE_CXX_FLAGS  "${CMAKE_CXX_FLAGS} -O0 -ggdb --coverage -Wall -Werror")
+ADD_COMPILE_OPTIONS( -O0 -ggdb --coverage -Wall -Werror )
+ADD_COMPILE_OPTIONS( ${${CAPI_LIB}_CFLAGS_OTHER} )
 
 ADD_DEFINITIONS(-DTEST_RESOURCE_DIR=\"${CMAKE_CURRENT_SOURCE_DIR}/../../resources\" )
 
@@ -86,7 +87,7 @@ INCLUDE_DIRECTORIES(
 ADD_EXECUTABLE(${EXEC_NAME} ${EXEC_NAME}.cpp ${TC_SOURCES})
 TARGET_LINK_LIBRARIES(${EXEC_NAME}
     ${${CAPI_LIB}_LIBRARIES}
-    -lpthread
+    -lpthread --coverage
 )
 
 INSTALL(PROGRAMS ${EXEC_NAME}
index 1e2b72d..2a5ae46 100644 (file)
@@ -206,13 +206,18 @@ bool GetCursorPositionTest( const GetCursorPositionData& data )
                    visualModel,
                    metrics );
 
+  GetCursorPositionParameters parameters;
+  parameters.visualModel = visualModel;
+  parameters.logicalModel = logicalModel;
+  parameters.metrics = metrics;
+  parameters.isMultiline = true;
+
   for( unsigned int index = 0; index < data.numberOfTests; ++index )
   {
     CursorInfo cursorInfo;
-    GetCursorPosition( visualModel,
-                       logicalModel,
-                       metrics,
-                       data.logicalIndex[index],
+    parameters.logical = data.logicalIndex[index];
+
+    GetCursorPosition( parameters,
                        cursorInfo );
 
     if( cursorInfo.primaryPosition.x != data.visualX[index] )
index 0ef2777..51f2551 100644 (file)
@@ -60,7 +60,8 @@ PKG_CHECK_MODULES(DALI_ADAPTOR REQUIRED
   dali-adaptor
 )
 
-SET(CMAKE_CXX_FLAGS  "${CMAKE_CXX_FLAGS} -O0 -ggdb --coverage -Wall -Werror")
+ADD_COMPILE_OPTIONS( -O0 -ggdb --coverage -Wall -Werror )
+ADD_COMPILE_OPTIONS( ${${CAPI_LIB}_CFLAGS_OTHER} )
 
 ADD_DEFINITIONS(-DTEST_RESOURCE_DIR=\"${CMAKE_CURRENT_SOURCE_DIR}/../../resources\" )
 
@@ -78,7 +79,7 @@ INCLUDE_DIRECTORIES(
 ADD_EXECUTABLE(${EXEC_NAME} ${EXEC_NAME}.cpp ${TC_SOURCES})
 TARGET_LINK_LIBRARIES(${EXEC_NAME}
   ${${CAPI_LIB}_LIBRARIES}
-  -lpthread -ldl
+  -lpthread -ldl --coverage
 )
 
 INSTALL(PROGRAMS ${EXEC_NAME}
index ea5ce5c..9417822 100644 (file)
@@ -50,7 +50,14 @@ PKG_CHECK_MODULES(${CAPI_LIB} REQUIRED
     dali-toolkit
 )
 
-SET(CMAKE_CXX_FLAGS  "${CMAKE_CXX_FLAGS} -O0 -ggdb --coverage -Wall -Werror")
+#ADD_COMPILE_OPTIONS( -O0 -ggdb --coverage -Wall -Werror )
+# ADD_COMPILE_OPTIONS( ${${CAPI_LIB}_CFLAGS_OTHER} )
+# This works for a homogenous C++ project, but not for mixed C++/C project
+# On CMake >= 3.3, could use
+# ADD_COMPILE_OPTIONS( "$<$<COMPILE_LANGUAGE:CXX>:${${CAPI_LIB}_CFLAGS_OTHER}>" )
+# However, we need to support CMake 2.8, so instead, fall back to setting the CXX_FLAGS directly:
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0 -ggdb --coverage -Wall -Werror" )
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${${CAPI_LIB}_CFLAGS_OTHER}" )
 
 FOREACH(directory ${${CAPI_LIB}_LIBRARY_DIRS})
     SET(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} -L${directory}")
@@ -65,7 +72,7 @@ INCLUDE_DIRECTORIES(
 ADD_EXECUTABLE(${EXEC_NAME} ${EXEC_NAME}.cpp ${TC_SOURCES})
 TARGET_LINK_LIBRARIES(${EXEC_NAME}
     ${${CAPI_LIB}_LIBRARIES}
-    -lpthread
+    -lpthread --coverage
 )
 
 INSTALL(PROGRAMS ${EXEC_NAME}
index 19f812e..39b37de 100755 (executable)
@@ -108,7 +108,8 @@ PKG_CHECK_MODULES(${CAPI_LIB} REQUIRED
     dali-toolkit
 )
 
-SET(CMAKE_CXX_FLAGS  "${CMAKE_CXX_FLAGS} -O0 -ggdb --coverage -Wall -Werror")
+ADD_COMPILE_OPTIONS( -O0 -ggdb --coverage -Wall -Werror )
+ADD_COMPILE_OPTIONS( ${${CAPI_LIB}_CFLAGS_OTHER} )
 
 ADD_DEFINITIONS(-DTEST_RESOURCE_DIR=\"${CMAKE_CURRENT_SOURCE_DIR}/../../resources\" )
 
@@ -125,7 +126,7 @@ INCLUDE_DIRECTORIES(
 ADD_EXECUTABLE(${EXEC_NAME} ${EXEC_NAME}.cpp ${TC_SOURCES})
 TARGET_LINK_LIBRARIES(${EXEC_NAME}
     ${${CAPI_LIB}_LIBRARIES}
-    -lpthread
+    -lpthread --coverage
 )
 
 INSTALL(PROGRAMS ${EXEC_NAME}
index 32d16e4..4d4a35e 100644 (file)
@@ -27,6 +27,8 @@
 #include <dali-toolkit/devel-api/visuals/visual-properties-devel.h>
 #include <dali-toolkit/devel-api/align-enums.h>
 #include <dali-toolkit/devel-api/controls/control-devel.h>
+#include <dali-toolkit/devel-api/visual-factory/visual-factory.h>
+#include <toolkit-event-thread-callback.h>
 
 #include "dummy-control.h"
 
@@ -68,6 +70,9 @@ static void TestKeyInputFocusCallback( Control control )
   gKeyInputFocusCallBackCalled = true;
 }
 
+const char* TEST_LARGE_IMAGE_FILE_NAME =  TEST_RESOURCE_DIR "/tbcol.png";
+const char* TEST_IMAGE_FILE_NAME =  TEST_RESOURCE_DIR "/gallery-small-1.jpg";
+
 } // namespace
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -803,3 +808,61 @@ int UtcDaliControlSetTransformSize(void)
 
   END_TEST;
 }
+
+
+int UtcDaliControlResourcesReady(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline( "Register 2 visuals and check ResourceReady when a visual is disabled" );
+
+  VisualFactory factory = VisualFactory::Get();
+  DALI_TEST_CHECK( factory );
+
+  Property::Map propertyMapLarge;
+  propertyMapLarge.Insert( Visual::Property::TYPE,  Visual::IMAGE );
+  propertyMapLarge.Insert( ImageVisual::Property::URL,  TEST_LARGE_IMAGE_FILE_NAME );
+
+  Property::Map propertyMapSmall;
+  propertyMapSmall.Insert( Visual::Property::TYPE,  Visual::IMAGE );
+  propertyMapSmall.Insert( ImageVisual::Property::URL,  TEST_IMAGE_FILE_NAME );
+
+  Visual::Base smallVisual = factory.CreateVisual( propertyMapSmall );
+  smallVisual.SetName("smallVisual");
+  DALI_TEST_CHECK( smallVisual );
+
+  DummyControl actor = DummyControl::New();
+  DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(actor.GetImplementation());
+  dummyImpl.RegisterVisual( DummyControl::Property::TEST_VISUAL, smallVisual );
+
+  actor.SetSize( 200.f, 200.f );
+  DALI_TEST_EQUALS( actor.GetRendererCount(), 0u, TEST_LOCATION );
+  DALI_TEST_EQUALS( DevelControl::IsResourceReady( actor ), false, TEST_LOCATION );
+
+  Stage::GetCurrent().Add( actor );
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
+
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( actor.GetRendererCount(), 1u, TEST_LOCATION );
+  DALI_TEST_EQUALS( DevelControl::IsResourceReady( actor ), true, TEST_LOCATION );
+
+  Visual::Base largeVisual = factory.CreateVisual( propertyMapLarge );
+  largeVisual.SetName("largeVisual");
+  DALI_TEST_CHECK( largeVisual );
+
+  tet_infoline( "Register Visual but set disabled, IsResourceReady should be true" );
+
+  dummyImpl.RegisterVisual( DummyControl::Property::TEST_VISUAL2, largeVisual, false );
+
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( actor.GetRendererCount(), 1u, TEST_LOCATION );
+  DALI_TEST_EQUALS( DevelControl::IsResourceReady( actor ), true, TEST_LOCATION );
+
+  END_TEST;
+}
index 57b39a5..7ea83bc 100644 (file)
@@ -48,6 +48,7 @@ void utc_dali_toolkit_pushbutton_cleanup(void)
 namespace
 {
 static const char* TEST_IMAGE_ONE = TEST_RESOURCE_DIR "/gallery-small-1.jpg";
+static const char* TEST_IMAGE_TWO = TEST_RESOURCE_DIR "/icon-delete.jpg";
 
 static const Vector2 INSIDE_TOUCH_POINT_POSITON  = Vector2( 240, 400 );
 static const Vector3 BUTTON_POSITON_TO_GET_INSIDE_TOUCH_EVENTS  = Vector3( 200, 360, 0 );
@@ -1816,3 +1817,37 @@ int UtcDaliPushButtonSetDisabledSelectedImageWithActorDeprecatedP(void)
 
   END_TEST;
 }
+
+int UtcDaliPushButtonReplaceButtonImageP2(void)
+{
+  tet_infoline("Set button image then replace with new image and query url");
+
+  ToolkitTestApplication application;
+
+  ResourceImage setImage = ResourceImage::New( TEST_IMAGE_ONE );
+  DALI_TEST_CHECK(setImage);
+
+  Actor imgActorSet = ImageView::New(setImage);
+  DALI_TEST_CHECK(imgActorSet);
+
+  PushButton pushButton = PushButton::New();
+  pushButton.SetProperty( Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL, TEST_IMAGE_TWO );
+
+
+  Stage::GetCurrent().Add( pushButton );
+
+  pushButton.SetButtonImage( imgActorSet );
+  application.SendNotification();
+  application.Render();
+
+  tet_infoline("Get button image before it has been able to load");
+
+  ImageView imageView = ImageView::DownCast(pushButton.GetButtonImage());
+
+  ResourceImage getImage = ResourceImage::DownCast( imageView.GetImage() );
+
+  tet_infoline("Check if url matches last assignment even if not loaded yet");
+  DALI_TEST_EQUALS( getImage.GetUrl(), setImage.GetUrl() , TEST_LOCATION );
+
+  END_TEST;
+}
index f441dd8..f8e61b8 100644 (file)
@@ -24,6 +24,7 @@
 #include <dali/public-api/rendering/shader.h>
 #include <dali/devel-api/object/handle-devel.h>
 #include <dali-toolkit/devel-api/controls/control-devel.h>
+#include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
 #include <dali-toolkit/devel-api/visual-factory/visual-factory.h>
 #include <dali-toolkit/devel-api/visual-factory/transition-data.h>
 #include <dali-toolkit/devel-api/visuals/text-visual-properties.h>
@@ -2142,6 +2143,42 @@ int UtcDaliRegisterVisualOrder(void)
   END_TEST;
 }
 
+int UtcDaliRegisterVisualOrder02(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline( "Register Visual Order with Background Set" );
+
+  DummyControl dummyControl = DummyControl::New(true);
+  Impl::DummyControl& dummyImpl = static_cast<Impl::DummyControl&>(dummyControl.GetImplementation());
+
+  const int backgroundDepthIndex = Toolkit::DepthIndex::BACKGROUND;
+
+  VisualFactory factory = VisualFactory::Get();
+  Property::Map propertyMap;
+  propertyMap.Insert(Visual::Property::TYPE,  Visual::COLOR);
+  propertyMap.Insert(ColorVisual::Property::MIX_COLOR,  Color::BLUE);
+
+  tet_printf( "Register a control background visual, should have depth index of %d\n", backgroundDepthIndex );
+
+  dummyControl.SetProperty( Control::Property::BACKGROUND, propertyMap );
+
+  const int TEST_VISUAL_1_DEPTH_INDEX = 0;
+  tet_printf( "Register visual, should have depth index of %d\n", TEST_VISUAL_1_DEPTH_INDEX );
+  Visual::Base testVisual1 = factory.CreateVisual( propertyMap );
+  dummyImpl.RegisterVisual( DummyControl::Property::TEST_VISUAL, testVisual1 );
+  DALI_TEST_EQUALS( testVisual1.GetDepthIndex(), TEST_VISUAL_1_DEPTH_INDEX , TEST_LOCATION );
+
+  tet_printf( "Register another visual, should have a depth index greater than previous(%d)\n", TEST_VISUAL_1_DEPTH_INDEX );
+  Visual::Base testVisual2 = factory.CreateVisual( propertyMap );
+  dummyImpl.RegisterVisual( DummyControl::Property::TEST_VISUAL2, testVisual2 );
+  DALI_TEST_CHECK( testVisual2.GetDepthIndex() >  testVisual1.GetDepthIndex() );
+
+  dummyControl.SetSize(200.f, 200.f);
+  Stage::GetCurrent().Add( dummyControl );
+
+  END_TEST;
+}
+
 int UtcDaliRegisterVisualWithDepthIndex(void)
 {
   ToolkitTestApplication application;
index e1d82e3..2469beb 100644 (file)
@@ -275,6 +275,24 @@ TypeAction registerAction( typeRegistration, ACTION_ACCESSIBILITY_ACTIVATED, &Do
 
 DALI_TYPE_REGISTRATION_END()
 
+/**
+ * @brief Iterate through given container and setOffStage any visual found
+ *
+ * @param[in] container Container of visuals
+ * @param[in] parent Parent actor to remove visuals from
+ */
+void SetVisualsOffStage( const RegisteredVisualContainer& container, Actor parent )
+{
+  for( auto iter = container.Begin(), end = container.End() ; iter!= end; iter++)
+  {
+    if( (*iter)->visual )
+    {
+      DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Control::SetOffStage Setting visual(%d) off stage\n", (*iter)->index );
+      Toolkit::GetImplementation((*iter)->visual).SetOffStage( parent );
+    }
+  }
+}
+
 } // unnamed namespace
 
 
@@ -354,89 +372,6 @@ void Control::Impl::LongPressDetected(Actor actor, const LongPressGesture& longP
   mControlImpl.OnLongPress(longPress);
 }
 
-// Called by a Visual when it's resource is ready
-void Control::Impl::ResourceReady( Visual::Base& object)
-{
-  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "ResourceReady \n");
-
-  // A resource is ready, check if is in the replacement visual container
-  // Iterate through all visuals in replacement container and store indexes of ready visuals
-  Dali::Vector <Property::Index> readyVisuals;
-  Actor self = mControlImpl.Self();
-
-  for( auto replacementVisualIter = mReplacementVisuals.Begin();
-        replacementVisualIter < mReplacementVisuals.End(); ++replacementVisualIter )
-  {
-    const Toolkit::Visual::Base replacementVisual = (*replacementVisualIter)->visual;
-    const Internal::Visual::Base& replacementVisualImpl = Toolkit::GetImplementation( replacementVisual );
-
-    if( replacementVisualImpl.IsResourceReady() )
-    {
-      // Check if new replacement visual (index) is already queued for replacement and swap old for new.
-      RegisteredVisualContainer::Iterator registeredVisualsIter;
-      if( FindVisual( (*replacementVisualIter)->index, mVisuals, registeredVisualsIter ) )
-      {
-        Property::Index readyVisualIndex = (*replacementVisualIter)->index;
-        DALI_LOG_INFO( gLogFilter, Debug::Verbose, "ResourceReady: %d Ready to replace\n", readyVisualIndex );
-        readyVisuals.PushBack( readyVisualIndex );
-        // Remove current shown visual from stage and from registered visuals container
-        Toolkit::GetImplementation((*registeredVisualsIter)->visual).SetOffStage( self );
-        mVisuals.Erase( registeredVisualsIter );
-      }
-    }
-  }
-
-  for( auto readyVisualsIter = readyVisuals.Begin(); readyVisualsIter != readyVisuals.End(); readyVisualsIter++ )
-  {
-    DALI_LOG_INFO( gLogFilter, Debug::Verbose, "ResourceReady: %d Matched\n", (*readyVisualsIter) );
-    // Move new visual to be shown from replacement container into the control's registered visuals container
-    // Replacement visual has already been set on stage when it was added to replacement container
-    RegisteredVisualContainer::Iterator readyReplacementVisual;
-    if( FindVisual( (*readyVisualsIter) , mReplacementVisuals, readyReplacementVisual ) )
-    {
-      MoveVisual( readyReplacementVisual, mReplacementVisuals, mVisuals ); // Erases visual from replacement queue
-    }
-    // A visual has been replaced so control will most likely need relayouting
-    mControlImpl.RelayoutRequest();
-  }
-
-  // go through and check if all the visuals are ready, if they are emit a signal
-  for( auto visualIter = mVisuals.Begin();
-        visualIter != mVisuals.End(); ++visualIter )
-  {
-    const Toolkit::Visual::Base visual = (*visualIter)->visual;
-    const Internal::Visual::Base& visualImpl = Toolkit::GetImplementation( visual );
-
-    // one of the visuals is not ready
-    if( !visualImpl.IsResourceReady() )
-    {
-      return;
-    }
-  }
-
-  // all the visuals are ready
-  Dali::Toolkit::Control handle( mControlImpl.GetOwner() );
-  mResourceReadySignal.Emit( handle );
-}
-
-bool Control::Impl::IsResourceReady() const
-{
-  // go through and check all the visuals are ready
-  for ( RegisteredVisualContainer::ConstIterator visualIter = mVisuals.Begin();
-         visualIter != mVisuals.End(); ++visualIter )
-   {
-     const Toolkit::Visual::Base visual = (*visualIter)->visual;
-     const Internal::Visual::Base& visualImpl = Toolkit::GetImplementation( visual );
-
-     // one of the visuals is not ready
-     if( !visualImpl.IsResourceReady()  )
-     {
-       return false;
-     }
-   }
-  return true;
-}
-
 void Control::Impl::RegisterVisual( Property::Index index, Toolkit::Visual::Base& visual )
 {
   RegisterVisual( index, visual, VisualState::ENABLED, DepthIndexValue::NOT_SET );
@@ -464,48 +399,61 @@ void Control::Impl::RegisterVisual( Property::Index index, Toolkit::Visual::Base
   bool visualReplaced ( false );
   Actor self = mControlImpl.Self();
 
+  // Set the depth index, if not set by caller this will be either the current visual depth, max depth of all visuals
+  // or zero.
+  int requiredDepthIndex = visual.GetDepthIndex();
+
+  if( depthIndexValueSet == DepthIndexValue::SET )
+  {
+    requiredDepthIndex = depthIndex;
+  }
+
+  // Visual replacement, existing visual should only be removed from stage when replacement ready.
   if( !mVisuals.Empty() )
   {
     RegisteredVisualContainer::Iterator registeredVisualsiter;
-    // Check if visual (index) is already registered.  Replace if so.
+    // Check if visual (index) is already registered, this is the current visual.
     if( FindVisual( index, mVisuals, registeredVisualsiter ) )
     {
-      if( (*registeredVisualsiter)->visual )
+      Toolkit::Visual::Base& currentRegisteredVisual = (*registeredVisualsiter)->visual;
+      if( currentRegisteredVisual )
       {
         // Store current visual depth index as may need to set the replacement visual to same depth
         const int currentDepthIndex = (*registeredVisualsiter)->visual.GetDepthIndex();
 
-        // Monitor when the visuals resources are ready
-        StopObservingVisual( (*registeredVisualsiter)->visual );
-        StartObservingVisual( visual );
+        // No longer required to know if the replaced visual's resources are ready
+        StopObservingVisual( currentRegisteredVisual );
 
-        if(  self.OnStage() )
+        // If control staged and visual enabled then visuals will be swapped once ready
+        if(  self.OnStage() && enabled )
         {
-          DALI_LOG_INFO( gLogFilter, Debug::Verbose, "RegisterVisual Adding visual to replacement Queue: %d \n", index );
-          // Check if visual is currently in the process of being replaced
-          RegisteredVisualContainer::Iterator queuedReplacementVisual;
-          if ( FindVisual( index, mReplacementVisuals, queuedReplacementVisual ) )
+          // Check if visual is currently in the process of being replaced ( is in removal container )
+          RegisteredVisualContainer::Iterator visualQueuedForRemoval;
+          if ( FindVisual( index, mRemoveVisuals, visualQueuedForRemoval ) )
+          {
+            // Visual with same index is already in removal container so current visual pending
+            // Only the the last requested visual will be displayed so remove current visual which is staged but not ready.
+            Toolkit::GetImplementation( currentRegisteredVisual ).SetOffStage( self );
+            mVisuals.Erase( registeredVisualsiter );
+          }
+          else
           {
-            // If visual on replacement queue is going to be replaced before it's ready then will be removed from queue (and stage)
-            // Only the the last requested visual will be queued and then displayed.
-            Toolkit::GetImplementation( (*queuedReplacementVisual)->visual ).SetOffStage( self );
-            mReplacementVisuals.Erase(queuedReplacementVisual);
+            // current visual not already in removal container so add now.
+            DALI_LOG_INFO( gLogFilter, Debug::Verbose, "RegisterVisual Move current registered visual to removal Queue: %d \n", index );
+            MoveVisual( registeredVisualsiter, mVisuals, mRemoveVisuals );
           }
-          // Add to replacement list
-          mReplacementVisuals.PushBack( new RegisteredVisual( index, visual, ( enabled == VisualState::ENABLED ? true : false ) ) );
         }
         else
         {
-          // Not staged so can just replace registered visual
-          (*registeredVisualsiter)->visual = visual;
-          (*registeredVisualsiter)->enabled = ( enabled == VisualState::ENABLED ) ? true : false;
+          // Control not staged or visual disabled so can just erase from registered visuals and new visual will be added later.
+          mVisuals.Erase( registeredVisualsiter );
         }
 
         // If we've not set the depth-index value and the new visual does not have a depth index applied to it, then use the previously set depth-index for this index
         if( ( depthIndexValueSet == DepthIndexValue::NOT_SET ) &&
             ( visual.GetDepthIndex() == 0 ) )
         {
-          visual.SetDepthIndex( currentDepthIndex );
+          requiredDepthIndex = currentDepthIndex;
         }
       }
 
@@ -535,15 +483,12 @@ void Control::Impl::RegisterVisual( Property::Index index, Toolkit::Visual::Base
 
   if( !visualReplaced ) // New registration entry
   {
-    DALI_LOG_INFO( gLogFilter, Debug::Concise, "New Visual registration %d\n", index);
-    mVisuals.PushBack( new RegisteredVisual( index, visual, ( enabled == VisualState::ENABLED ? true : false ) ) );
-
-    // monitor when the visuals resources are ready
+    // monitor when the visual resources are ready
     StartObservingVisual( visual );
 
     // If we've not set the depth-index value, we have more than one visual and the visual does not have a depth index, then set it to be the highest
     if( ( depthIndexValueSet == DepthIndexValue::NOT_SET ) &&
-        ( mVisuals.Size() > 1 ) &&
+        ( mVisuals.Size() > 0 ) &&
         ( visual.GetDepthIndex() == 0 ) )
     {
       int maxDepthIndex = std::numeric_limits< int >::min();
@@ -558,29 +503,34 @@ void Control::Impl::RegisterVisual( Property::Index index, Toolkit::Visual::Base
           maxDepthIndex = visualDepthIndex;
         }
       }
-
       ++maxDepthIndex; // Add one to the current maximum depth index so that our added visual appears on top
-      visual.SetDepthIndex( maxDepthIndex );
+      requiredDepthIndex = std::max( 0, maxDepthIndex ); // Start at zero if maxDepth index belongs to a background
     }
   }
 
   if( visual )
   {
-    // If the caller has set the depth-index, then set it here
-    if( depthIndexValueSet == DepthIndexValue::SET )
-    {
-      visual.SetDepthIndex( depthIndex );
-    }
+    // Set determined depth index
+    visual.SetDepthIndex( requiredDepthIndex );
+
+    // Monitor when the visual resources are ready
+    StartObservingVisual( visual );
+
+    DALI_LOG_INFO( gLogFilter, Debug::Concise, "New Visual registration index[%d] depth[%d]\n", index, requiredDepthIndex );
+    RegisteredVisual* newRegisteredVisual  = new RegisteredVisual( index, visual,
+                                             ( enabled == VisualState::ENABLED ? true : false ),
+                                             ( visualReplaced && enabled ) ) ;
+    mVisuals.PushBack( newRegisteredVisual );
 
     // Put on stage if enabled and the control is already on the stage
+    // Visual must be set on stage for the renderer to be created and the ResourceReady triggered.
     if( ( enabled == VisualState::ENABLED ) && self.OnStage() )
     {
-      // Visual must be set on stage for the renderer to be created and the ResourceReady triggered.
       Toolkit::GetImplementation(visual).SetOnStage( self );
     }
   }
 
-  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Control::RegisterVisual() Registered %s(%d), enabled:%s\n",  visual.GetName().c_str(), index, enabled?"T":"F" );
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Control::RegisterVisual() Registered %s(%d), enabled:%s\n",  visual.GetName().c_str(), index, enabled?"true":"false" );
 }
 
 void Control::Impl::UnregisterVisual( Property::Index index )
@@ -666,6 +616,65 @@ void Control::Impl::StartObservingVisual( Toolkit::Visual::Base& visual)
   visualImpl.AddResourceObserver( *this );
 }
 
+// Called by a Visual when it's resource is ready
+void Control::Impl::ResourceReady( Visual::Base& object)
+{
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "ResourceReady replacements pending[%d]\n", mRemoveVisuals.Count() );
+
+  Actor self = mControlImpl.Self();
+
+  // A resource is ready, find resource in the registered visuals container and get its index
+  for( auto registeredIter = mVisuals.Begin(),  end = mVisuals.End(); registeredIter != end; ++registeredIter )
+  {
+    Internal::Visual::Base& registeredVisualImpl = Toolkit::GetImplementation( (*registeredIter)->visual );
+
+    if( &object == &registeredVisualImpl )
+    {
+      RegisteredVisualContainer::Iterator visualToRemoveIter;
+      // Find visual with the same index in the removal container
+      // Set if off stage as it's replacement is now ready.
+      // Remove if from removal list as now removed from stage.
+      // Set Pending flag on the ready visual to false as now ready.
+      if( FindVisual( (*registeredIter)->index, mRemoveVisuals, visualToRemoveIter ) )
+      {
+        (*registeredIter)->pending = false;
+        Toolkit::GetImplementation( (*visualToRemoveIter)->visual ).SetOffStage( self );
+        mRemoveVisuals.Erase( visualToRemoveIter );
+      }
+      break;
+    }
+  }
+
+  // A visual is ready so control may need relayouting
+  mControlImpl.RelayoutRequest();
+
+  // Emit signal if all enabled visuals registered by the control are ready.
+  if( IsResourceReady() )
+  {
+    Dali::Toolkit::Control handle( mControlImpl.GetOwner() );
+    mResourceReadySignal.Emit( handle );
+  }
+}
+
+bool Control::Impl::IsResourceReady() const
+{
+  // Iterate through and check all the enabled visuals are ready
+  for( auto visualIter = mVisuals.Begin();
+         visualIter != mVisuals.End(); ++visualIter )
+  {
+    const Toolkit::Visual::Base visual = (*visualIter)->visual;
+    const Internal::Visual::Base& visualImpl = Toolkit::GetImplementation( visual );
+
+    // one of the enabled visuals is not ready
+    if( !visualImpl.IsResourceReady() && (*visualIter)->enabled )
+    {
+      return false;
+    }
+  }
+  return true;
+}
+
+
 Dali::Animation Control::Impl::CreateTransition( const Toolkit::TransitionData& handle )
 {
   Dali::Animation transition;
@@ -1263,6 +1272,32 @@ void Control::Impl::SetSubState( const std::string& subStateName, bool withTrans
   }
 }
 
+void Control::Impl::OnStageDisconnection()
+{
+  Actor self = mControlImpl.Self();
+
+  // Any visuals set for replacement but not yet ready should still be registered.
+  // Reason: If a request was made to register a new visual but the control removed from stage before visual was ready
+  // then when this control appears back on stage it should use that new visual.
+
+  // Iterate through all registered visuals and set off stage
+  SetVisualsOffStage( mVisuals, self );
+
+  // Visuals pending replacement can now be taken out of the removal list and set off stage
+  // Iterate through all replacement visuals and add to a move queue then set off stage
+  for( auto removalIter = mRemoveVisuals.Begin(), end = mRemoveVisuals.End(); removalIter != end; removalIter++ )
+  {
+    Toolkit::GetImplementation((*removalIter)->visual).SetOffStage( self );
+  }
+
+  for( auto replacedIter = mVisuals.Begin(), end = mVisuals.End(); replacedIter != end; replacedIter++ )
+  {
+    (*replacedIter)->pending = false;
+  }
+
+  mRemoveVisuals.Clear();
+}
+
 } // namespace Internal
 
 } // namespace Toolkit
index 91b8314..73c4626 100644 (file)
@@ -41,20 +41,21 @@ namespace Toolkit
 namespace Internal
 {
 
-/**
+ /**
   * Struct used to store Visual within the control, index is a unique key for each visual.
   */
- struct RegisteredVisual
- {
-   Property::Index index;
-   Toolkit::Visual::Base visual;
-   bool enabled;
-
-   RegisteredVisual( Property::Index aIndex, Toolkit::Visual::Base &aVisual, bool aEnabled)
-   : index(aIndex), visual(aVisual), enabled(aEnabled)
-   {
-   }
- };
+struct RegisteredVisual
+{
+  Property::Index index;
+  Toolkit::Visual::Base visual;
+  bool enabled : 1;
+  bool pending : 1;
+
+  RegisteredVisual( Property::Index aIndex, Toolkit::Visual::Base &aVisual, bool aEnabled, bool aPendingReplacement )
+  : index(aIndex), visual(aVisual), enabled(aEnabled), pending( aPendingReplacement )
+  {
+  }
+};
 
 typedef Dali::OwnerContainer< RegisteredVisual* > RegisteredVisualContainer;
 
@@ -259,6 +260,11 @@ public:
    */
   bool IsResourceReady() const;
 
+  /**
+   * @copydoc CustomActorImpl::OnStageDisconnection()
+   */
+  void OnStageDisconnection();
+
 private:
 
   /**
@@ -332,7 +338,7 @@ public:
   bool mIsKeyboardNavigationSupported :1;  ///< Stores whether keyboard navigation is supported by the control.
   bool mIsKeyboardFocusGroup :1;           ///< Stores whether the control is a focus group.
 
-  RegisteredVisualContainer mReplacementVisuals;         ///< List of visuals that will be used for replacing current visuals.
+  RegisteredVisualContainer mRemoveVisuals;         ///< List of visuals that are being replaced by another visual once ready
 
   // Properties - these need to be members of Internal::Control::Impl as they access private methods/data of Internal::Control and Internal::Control::Impl.
   static const PropertyRegistration PROPERTY_1;
index 8ced30e..4183b89 100644 (file)
@@ -214,6 +214,9 @@ void ImageView::OnRelayout( const Vector2& size, RelayoutContainer& container )
 {
   Control::OnRelayout( size, container );
 
+  // If visual is being replaced then mVisual will be the replacement visual even if not ready.
+  mVisual = DevelControl::GetVisual( *this, Toolkit::ImageView::Property::IMAGE );
+
   if( mVisual )
   {
     // Pass in an empty map which uses default transform values meaning our visual fills the control
@@ -224,7 +227,6 @@ void ImageView::OnRelayout( const Vector2& size, RelayoutContainer& container )
 
 void ImageView::OnResourceReady( Toolkit::Control control )
 {
-  mVisual = DevelControl::GetVisual( *this, Toolkit::ImageView::Property::IMAGE );
 }
 
 ///////////////////////////////////////////////////////////
index 04a1af3..91b6a40 100644 (file)
@@ -464,24 +464,21 @@ CharacterIndex GetClosestCursorIndex( VisualModelPtr visualModel,
 }
 
 
-void GetCursorPosition( VisualModelPtr visualModel,
-                        LogicalModelPtr logicalModel,
-                        MetricsPtr metrics,
-                        CharacterIndex logical,
+void GetCursorPosition( GetCursorPositionParameters& parameters,
                         CursorInfo& cursorInfo )
 {
   // Whether the logical cursor position is at the end of the whole text.
-  const bool isLastPosition = logicalModel->mText.Count() == logical;
+  const bool isLastPosition = parameters.logicalModel->mText.Count() == parameters.logical;
 
   // Get the line where the character is laid-out.
-  const CharacterIndex characterOfLine = isLastPosition ? ( logical - 1u ) : logical;
+  const CharacterIndex characterOfLine = isLastPosition ? ( parameters.logical - 1u ) : parameters.logical;
 
   // Whether the cursor is in the last position and the last position is a new paragraph character.
-  const bool isLastNewParagraph = isLastPosition && TextAbstraction::IsNewParagraph( *( logicalModel->mText.Begin() + characterOfLine ) );
+  const bool isLastNewParagraph = parameters.isMultiline && isLastPosition && TextAbstraction::IsNewParagraph( *( parameters.logicalModel->mText.Begin() + characterOfLine ) );
 
-  const LineRun* const modelLines = visualModel->mLines.Begin();
+  const LineRun* const modelLines = parameters.visualModel->mLines.Begin();
 
-  const LineIndex lineIndex = visualModel->GetLineOfCharacter( characterOfLine );
+  const LineIndex lineIndex = parameters.visualModel->GetLineOfCharacter( characterOfLine );
   const LineRun& line = *( modelLines + lineIndex );
 
   if( isLastNewParagraph )
@@ -493,7 +490,7 @@ void GetCursorPosition( VisualModelPtr visualModel,
     cursorInfo.isSecondaryCursor = false;
 
     // Set the line offset and height.
-    cursorInfo.lineOffset = CalculateLineOffset( visualModel->mLines,
+    cursorInfo.lineOffset = CalculateLineOffset( parameters.visualModel->mLines,
                                                  newLineIndex );
 
     // The line height is the addition of the line ascender and the line descender.
@@ -508,24 +505,24 @@ void GetCursorPosition( VisualModelPtr visualModel,
     cursorInfo.primaryPosition.y = cursorInfo.lineOffset;
 
     // Transform the cursor info from line's coords to text's coords.
-    cursorInfo.primaryPosition.x += ( LTR == line.direction ) ? 0.f : visualModel->mControlSize.width;
+    cursorInfo.primaryPosition.x += ( LTR == line.direction ) ? 0.f : parameters.visualModel->mControlSize.width;
   }
   else
   {
     // Whether this line is a bidirectional line.
-    const bool bidiLineFetched = logicalModel->FetchBidirectionalLineInfo( characterOfLine );
+    const bool bidiLineFetched = parameters.logicalModel->FetchBidirectionalLineInfo( characterOfLine );
 
     // Check if the logical position is the first or the last one of the line.
-    const bool isFirstPositionOfLine = line.characterRun.characterIndex == logical;
-    const bool isLastPositionOfLine = line.characterRun.characterIndex + line.characterRun.numberOfCharacters == logical;
+    const bool isFirstPositionOfLine = line.characterRun.characterIndex == parameters.logical;
+    const bool isLastPositionOfLine = line.characterRun.characterIndex + line.characterRun.numberOfCharacters == parameters.logical;
 
     // 'logical' is the logical 'cursor' index.
     // Get the next and current logical 'character' index.
-    const CharacterIndex characterIndex = isFirstPositionOfLine ? logical : logical - 1u;
-    const CharacterIndex nextCharacterIndex = isLastPositionOfLine ? characterIndex : logical;
+    const CharacterIndex characterIndex = isFirstPositionOfLine ? parameters.logical : parameters.logical - 1u;
+    const CharacterIndex nextCharacterIndex = isLastPositionOfLine ? characterIndex : parameters.logical;
 
     // The character's direction buffer.
-    const CharacterDirection* const directionsBuffer = bidiLineFetched ? logicalModel->mCharacterDirections.Begin() : NULL;
+    const CharacterDirection* const directionsBuffer = bidiLineFetched ? parameters.logicalModel->mCharacterDirections.Begin() : NULL;
 
     CharacterDirection isCurrentRightToLeft = false;
     CharacterDirection isNextRightToLeft = false;
@@ -544,7 +541,7 @@ void GetCursorPosition( VisualModelPtr visualModel,
                                      ( isFirstPositionOfLine && ( isRightToLeftParagraph != isCurrentRightToLeft ) ) );
 
     // Set the line offset and height.
-    cursorInfo.lineOffset = CalculateLineOffset( visualModel->mLines,
+    cursorInfo.lineOffset = CalculateLineOffset( parameters.visualModel->mLines,
                                                  lineIndex );
 
     // The line height is the addition of the line ascender and the line descender.
@@ -569,7 +566,7 @@ void GetCursorPosition( VisualModelPtr visualModel,
         index = isRightToLeftParagraph ? line.characterRun.characterIndex : line.characterRun.characterIndex + line.characterRun.numberOfCharacters - 1u;
         if( bidiLineFetched )
         {
-          index = logicalModel->GetLogicalCharacterIndex( index );
+          index = parameters.logicalModel->GetLogicalCharacterIndex( index );
         }
       }
       else if( isFirstPositionOfLine )
@@ -577,7 +574,7 @@ void GetCursorPosition( VisualModelPtr visualModel,
         index = isRightToLeftParagraph ? line.characterRun.characterIndex + line.characterRun.numberOfCharacters - 1u : line.characterRun.characterIndex;
         if( bidiLineFetched )
         {
-          index = logicalModel->GetLogicalCharacterIndex( index );
+          index = parameters.logicalModel->GetLogicalCharacterIndex( index );
         }
       }
       else
@@ -586,12 +583,12 @@ void GetCursorPosition( VisualModelPtr visualModel,
       }
     }
 
-    const GlyphIndex* const charactersToGlyphBuffer = visualModel->mCharactersToGlyph.Begin();
-    const Length* const glyphsPerCharacterBuffer = visualModel->mGlyphsPerCharacter.Begin();
-    const Length* const charactersPerGlyphBuffer = visualModel->mCharactersPerGlyph.Begin();
-    const CharacterIndex* const glyphsToCharactersBuffer = visualModel->mGlyphsToCharacters.Begin();
-    const Vector2* const glyphPositionsBuffer = visualModel->mGlyphPositions.Begin();
-    const GlyphInfo* const glyphInfoBuffer = visualModel->mGlyphs.Begin();
+    const GlyphIndex* const charactersToGlyphBuffer = parameters.visualModel->mCharactersToGlyph.Begin();
+    const Length* const glyphsPerCharacterBuffer = parameters.visualModel->mGlyphsPerCharacter.Begin();
+    const Length* const charactersPerGlyphBuffer = parameters.visualModel->mCharactersPerGlyph.Begin();
+    const CharacterIndex* const glyphsToCharactersBuffer = parameters.visualModel->mGlyphsToCharacters.Begin();
+    const Vector2* const glyphPositionsBuffer = parameters.visualModel->mGlyphPositions.Begin();
+    const GlyphInfo* const glyphInfoBuffer = parameters.visualModel->mGlyphs.Begin();
 
     // Convert the cursor position into the glyph position.
     const GlyphIndex primaryGlyphIndex = *( charactersToGlyphBuffer + index );
@@ -604,7 +601,7 @@ void GetCursorPosition( VisualModelPtr visualModel,
                       primaryNumberOfGlyphs,
                       glyphMetrics,
                       glyphInfoBuffer,
-                      metrics );
+                      parameters.metrics );
 
     // Whether to add the glyph's advance to the cursor position.
     // i.e if the paragraph is left to right and the logical cursor is zero, the position is the position of the first glyph and the advance is not added,
@@ -698,7 +695,7 @@ void GetCursorPosition( VisualModelPtr visualModel,
                         secondaryNumberOfGlyphs,
                         glyphMetrics,
                         glyphInfoBuffer,
-                        metrics );
+                        parameters.metrics );
 
       // Set the secondary cursor's position.
 
index 34a5f7b..ad17b31 100644 (file)
@@ -71,6 +71,18 @@ struct CursorInfo
 };
 
 /**
+ * @brief Parameters passed to the GetCursorPosition() function.
+ */
+struct GetCursorPositionParameters
+{
+  VisualModelPtr visualModel;    ///< The visual model.
+  LogicalModelPtr logicalModel;  ///< The logical model.
+  MetricsPtr metrics;            ///< A wrapper around FontClient used to get metrics.
+  CharacterIndex logical;        ///< The logical cursor position (in characters). 0 is just before the first character, a value equal to the number of characters is just after the last character.
+  bool isMultiline;              ///< Whether the text control is multi-line.
+};
+
+/**
  * @brief Retrieves the closest line for a given touch point.
  *
  * It returns the first line if the touch point is above the text and the last line if the touch point is below.
@@ -130,16 +142,10 @@ CharacterIndex GetClosestCursorIndex( VisualModelPtr visualModel,
  * It retrieves as well the line's height and the cursor's height and
  * if there is a valid alternative cursor, its position and height.
  *
- * @param[in] visualModel The visual model.
- * @param[in] logicalModel The logical model.
- * @param[in] metrics A wrapper around FontClient used to get metrics.
- * @param[in] logical The logical cursor position (in characters). 0 is just before the first character, a value equal to the number of characters is just after the last character.
+ * @param[in] parameters Parameters used to calculate the cursor's position.
  * @param[out] cursorInfo The line's height, the cursor's height, the cursor's position and whether there is an alternative cursor.
  */
-void GetCursorPosition( VisualModelPtr visualModel,
-                        LogicalModelPtr logicalModel,
-                        MetricsPtr metrics,
-                        CharacterIndex logical,
+void GetCursorPosition( GetCursorPositionParameters& parameters,
                         CursorInfo& cursorInfo );
 
 /**
index 6a90595..532afed 100644 (file)
@@ -1789,8 +1789,18 @@ void Controller::Impl::RetrieveSelection( std::string& selectedText, bool delete
       mModel->mLogicalModel->UpdateTextStyleRuns( startOfSelectedText, -static_cast<int>( lengthOfSelectedText ) );
 
       // Mark the paragraphs to be updated.
-      mTextUpdateInfo.mCharacterIndex = startOfSelectedText;
-      mTextUpdateInfo.mNumberOfCharactersToRemove = lengthOfSelectedText;
+      if( Layout::Engine::SINGLE_LINE_BOX == mLayoutEngine.GetLayout() )
+      {
+        mTextUpdateInfo.mCharacterIndex = 0;
+        mTextUpdateInfo.mNumberOfCharactersToRemove = mTextUpdateInfo.mPreviousNumberOfCharacters;
+        mTextUpdateInfo.mNumberOfCharactersToAdd = mTextUpdateInfo.mPreviousNumberOfCharacters - lengthOfSelectedText;
+        mTextUpdateInfo.mClearAll = true;
+      }
+      else
+      {
+        mTextUpdateInfo.mCharacterIndex = startOfSelectedText;
+        mTextUpdateInfo.mNumberOfCharactersToRemove = lengthOfSelectedText;
+      }
 
       // Delete text between handles
       Vector<Character>::Iterator first = utf32Characters.Begin() + startOfSelectedText;
@@ -2621,13 +2631,18 @@ void Controller::Impl::GetCursorPosition( CharacterIndex logical,
     return;
   }
 
-  Text::GetCursorPosition( mModel->mVisualModel,
-                           mModel->mLogicalModel,
-                           mMetrics,
-                           logical,
+  const bool isMultiLine = ( Layout::Engine::MULTI_LINE_BOX == mLayoutEngine.GetLayout() );
+  GetCursorPositionParameters parameters;
+  parameters.visualModel = mModel->mVisualModel;
+  parameters.logicalModel = mModel->mLogicalModel;
+  parameters.metrics = mMetrics;
+  parameters.logical = logical;
+  parameters.isMultiline = isMultiLine;
+
+  Text::GetCursorPosition( parameters,
                            cursorInfo );
 
-  if( Layout::Engine::MULTI_LINE_BOX == mLayoutEngine.GetLayout() )
+  if( isMultiLine )
   {
     // If the text is editable and multi-line, the cursor position after a white space shouldn't exceed the boundaries of the text control.
 
@@ -2845,13 +2860,16 @@ void Controller::Impl::ScrollToMakePositionVisible( const Vector2& position, flo
     mModel->mScrollPosition.x = mModel->mVisualModel->mControlSize.width - positionEndX;
   }
 
-  if( decoratorPositionBeginY < 0.f )
-  {
-    mModel->mScrollPosition.y = -position.y;
-  }
-  else if( decoratorPositionEndY > mModel->mVisualModel->mControlSize.height )
+  if( Layout::Engine::MULTI_LINE_BOX == mLayoutEngine.GetLayout() )
   {
-    mModel->mScrollPosition.y = mModel->mVisualModel->mControlSize.height - positionEndY;
+    if( decoratorPositionBeginY < 0.f )
+    {
+      mModel->mScrollPosition.y = -position.y;
+    }
+    else if( decoratorPositionEndY > mModel->mVisualModel->mControlSize.height )
+    {
+      mModel->mScrollPosition.y = mModel->mVisualModel->mControlSize.height - positionEndY;
+    }
   }
 }
 
index b94ff3a..b2fec63 100644 (file)
@@ -2947,8 +2947,18 @@ void Controller::InsertText( const std::string& text, Controller::InsertType typ
     }
 
     // Mark the first paragraph to be updated.
-    mImpl->mTextUpdateInfo.mCharacterIndex = std::min( cursorIndex, mImpl->mTextUpdateInfo.mCharacterIndex );
-    mImpl->mTextUpdateInfo.mNumberOfCharactersToAdd += maxSizeOfNewText;
+    if( Layout::Engine::SINGLE_LINE_BOX == mImpl->mLayoutEngine.GetLayout() )
+    {
+      mImpl->mTextUpdateInfo.mCharacterIndex = 0;
+      mImpl->mTextUpdateInfo.mNumberOfCharactersToRemove = mImpl->mTextUpdateInfo.mPreviousNumberOfCharacters;
+      mImpl->mTextUpdateInfo.mNumberOfCharactersToAdd = numberOfCharactersInModel + maxSizeOfNewText;
+      mImpl->mTextUpdateInfo.mClearAll = true;
+    }
+    else
+    {
+      mImpl->mTextUpdateInfo.mCharacterIndex = std::min( cursorIndex, mImpl->mTextUpdateInfo.mCharacterIndex );
+      mImpl->mTextUpdateInfo.mNumberOfCharactersToAdd += maxSizeOfNewText;
+    }
 
     // Update the cursor index.
     cursorIndex += maxSizeOfNewText;
@@ -3046,8 +3056,18 @@ bool Controller::RemoveText( int cursorOffset,
         ( ( cursorIndex + numberOfCharacters ) <= mImpl->mTextUpdateInfo.mPreviousNumberOfCharacters ) )
     {
       // Mark the paragraphs to be updated.
-      mImpl->mTextUpdateInfo.mCharacterIndex = std::min( cursorIndex, mImpl->mTextUpdateInfo.mCharacterIndex );
-      mImpl->mTextUpdateInfo.mNumberOfCharactersToRemove += numberOfCharacters;
+      if( Layout::Engine::SINGLE_LINE_BOX == mImpl->mLayoutEngine.GetLayout() )
+      {
+        mImpl->mTextUpdateInfo.mCharacterIndex = 0;
+        mImpl->mTextUpdateInfo.mNumberOfCharactersToRemove = mImpl->mTextUpdateInfo.mPreviousNumberOfCharacters;
+        mImpl->mTextUpdateInfo.mNumberOfCharactersToAdd = mImpl->mTextUpdateInfo.mPreviousNumberOfCharacters - numberOfCharacters;
+        mImpl->mTextUpdateInfo.mClearAll = true;
+      }
+      else
+      {
+        mImpl->mTextUpdateInfo.mCharacterIndex = std::min( cursorIndex, mImpl->mTextUpdateInfo.mCharacterIndex );
+        mImpl->mTextUpdateInfo.mNumberOfCharactersToRemove += numberOfCharacters;
+      }
 
       // Update the input style and remove the text's style before removing the text.
 
index 59e0a18..05f7ab3 100644 (file)
@@ -517,16 +517,7 @@ void Control::OnStageConnection( int depth )
 
 void Control::OnStageDisconnection()
 {
-  for(RegisteredVisualContainer::Iterator iter = mImpl->mVisuals.Begin(); iter!= mImpl->mVisuals.End(); iter++)
-  {
-    // Check whether the visual is empty
-    if( (*iter)->visual )
-    {
-      DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Control::OnStageDisconnection Setting visual(%d) off stage\n", (*iter)->index );
-      Actor self( Self() );
-      Toolkit::GetImplementation((*iter)->visual).SetOffStage( self );
-    }
-  }
+  mImpl->OnStageDisconnection();
 }
 
 void Control::OnKeyInputFocusGained()
index 7064c51..3bb9f35 100644 (file)
@@ -31,7 +31,7 @@ namespace Toolkit
 
 const unsigned int TOOLKIT_MAJOR_VERSION = 1;
 const unsigned int TOOLKIT_MINOR_VERSION = 2;
-const unsigned int TOOLKIT_MICRO_VERSION = 46;
+const unsigned int TOOLKIT_MICRO_VERSION = 47;
 const char * const TOOLKIT_BUILD_DATE    = __DATE__ " " __TIME__;
 
 #ifdef DEBUG_ENABLED
index 8ef63e7..e512fe7 100644 (file)
@@ -1,6 +1,6 @@
 Name:       dali-toolkit
 Summary:    The OpenGLES Canvas Core Library Toolkit
-Version:    1.2.46
+Version:    1.2.47
 Release:    1
 Group:      System/Libraries
 License:    Apache-2.0 and BSD-3-Clause and MIT