Fixing the issue where characters were being drawn at the same location whenever... 86/253286/11
authorSara Samara <sara.samara@samsung.com>
Mon, 8 Feb 2021 09:48:08 +0000 (11:48 +0200)
committerSara Samara <sara.samara@samsung.com>
Thu, 1 Apr 2021 16:05:59 +0000 (19:05 +0300)
*********************************************************************************
Description:
GetNaturalSize method was updating a copy by reference of the pending operations mask.
The value of the mask was being updated to Layout and Render.
After calling GetNaturalSize and giving focus to the editor by tapping it, the UpdateModel was attempting to perform an update based on the mask but had no update details stored in the the object and this caused all the characters to be pushed to the same paragraph.
The change stored a back-up of the mask as soon as it entered the GetNaturalSize so that its value can be restored before exiting GetNaturalSize. This ensured that no modifications made on the mask copy while getting the natural size were reflected on the original mask.
The utc checks on the line count before calling GetNaturalSize and tapping the text-editor and after doing so. The line count is expected to not change.
*********************************************************************************

using namespace Dali;
using namespace Dali::Toolkit;

class SimpleApp : public ConnectionTracker
{
public:
  SimpleApp(Application& application)
  : mApplication(application)
  {
    mApplication.InitSignal().Connect(this, &SimpleApp::Create);
  }
  void Create(Application& application)
  {
    Window window = application.GetWindow();
    mEditor = TextEditor::New();
    mEditor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_CENTER);
    mEditor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_CENTER);
    mEditor.SetProperty(Actor::Property::POSITION, Vector3(0.f, 0.0f, 0.f));
    mEditor.SetProperty(Actor::Property::SIZE, Vector2(200.f, 100.0f));
    mEditor.SetBackgroundColor(Vector4(0.04f, 0.345f, 0.392f, 1.0f));
    mEditor.SetProperty(TextEditor::Property::TEXT, "A\na\n");

    mButton = PushButton::New();
    mButton.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
    mButton.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
    mButton.SetProperty(Actor::Property::SIZE, Vector2(100.f, 50.0f));
    mButton.SetProperty(Actor::Property::POSITION, Vector3(0.f, 0.0f, 0.f));
    mButton.SetProperty(Button::Property::LABEL, "click");
    mButton.SetBackgroundColor(Vector4(0.5f, 0.5f, 0.5f, 1.0f));
    mButton.ClickedSignal().Connect(this, &SimpleApp::OnButtonClicked);

    window.Add(mButton);
    window.Add(mEditor);
  }
  std::string str1,str2;

  bool OnButtonClicked(Button button)
  {
    if(button == mButton)
    {
      Vector3 originalSize = mEditor.GetNaturalSize();
    }
    return true;
  }
private:
  Application& mApplication;
  TextEditor mEditor;
  PushButton mButton;
};

int DALI_EXPORT_API main(int argc, char** argv)
{
  Application application = Application::New(&argc, &argv);
  SimpleApp test(application);
  application.MainLoop();

  return 0;
}

Change-Id: I287f2f195d861a2cebbb256195d25cb653702dc7

automated-tests/src/dali-toolkit/utc-Dali-TextEditor.cpp
dali-toolkit/internal/text/text-controller-relayouter.cpp

index d5a243c..e74ccf4 100644 (file)
@@ -3216,3 +3216,36 @@ int UtcDaliTextEditorPrimaryCursorPosition(void)
 
   END_TEST;
 }
+
+int UtcDaliTextEditorLineCountAfterGetNaturalSize(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliTextEditorLineCountAfterGetNaturalSize ");
+
+  TextEditor textEditor = TextEditor::New();
+  textEditor.SetProperty(TextEditor::Property::TEXT, "A\nB\nC\nD\nE\nF\n");
+  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 );
+  application.GetScene().Add( textEditor );
+
+  application.SendNotification();
+  application.Render();
+
+  int lineCount = 0;
+  lineCount =  textEditor.GetProperty<int>( TextEditor::Property::LINE_COUNT );
+  DALI_TEST_EQUALS( lineCount, 7, TEST_LOCATION );
+
+  textEditor.GetNaturalSize();
+
+  // Create a tap event to touch the text editor.
+  TestGenerateTap( application, 18.0f, 25.0f );
+
+  application.SendNotification();
+  application.Render();
+
+  lineCount =  textEditor.GetProperty<int>( TextEditor::Property::LINE_COUNT );
+  DALI_TEST_EQUALS( lineCount, 7, TEST_LOCATION );
+
+  END_TEST;
+}
index a900601..227d889 100644 (file)
@@ -61,6 +61,9 @@ Vector3 Controller::Relayouter::GetNaturalSize(Controller& controller)
   VisualModelPtr&   visualModel = model->mVisualModel;
   if(impl.mRecalculateNaturalSize)
   {
+    // Store the pending operations mask so that it can be restored later on with no modifications made on it
+    // while getting the natural size were reflected on the original mask.
+    OperationsMask operationsPendingBackUp = static_cast<OperationsMask>(impl.mOperationsPending);
     // Operations that can be done only once until the text changes.
     const OperationsMask onlyOnceOperations = static_cast<OperationsMask>(CONVERT_TO_UTF32 |
                                                                           GET_SCRIPTS |
@@ -93,15 +96,6 @@ Vector3 Controller::Relayouter::GetNaturalSize(Controller& controller)
                                            LAYOUT | REORDER),
                naturalSize.GetVectorXY());
 
-    // Do not do again the only once operations.
-    operationsPending = static_cast<OperationsMask>(operationsPending & ~onlyOnceOperations);
-
-    // Do the size related operations again.
-    const OperationsMask sizeOperations = static_cast<OperationsMask>(LAYOUT |
-                                                                      ALIGN |
-                                                                      REORDER);
-    operationsPending                   = static_cast<OperationsMask>(operationsPending | sizeOperations);
-
     // Stores the natural size to avoid recalculate it again
     // unless the text/style changes.
     visualModel->SetNaturalSize(naturalSize.GetVectorXY());
@@ -114,7 +108,8 @@ Vector3 Controller::Relayouter::GetNaturalSize(Controller& controller)
 
     // Restore the actual control's size.
     visualModel->mControlSize = actualControlSize;
-
+    // Restore the previously backed-up pending operations' mask without the only once operations.
+    impl.mOperationsPending = static_cast<OperationsMask>(operationsPendingBackUp & ~onlyOnceOperations);
     DALI_LOG_INFO(gLogFilter, Debug::Verbose, "<--Controller::GetNaturalSize calculated %f,%f,%f\n", naturalSize.x, naturalSize.y, naturalSize.z);
   }
   else
@@ -244,6 +239,9 @@ float Controller::Relayouter::GetHeightForWidth(Controller& controller, float wi
      textUpdateInfo.mFullRelayoutNeeded ||
      textUpdateInfo.mClearAll)
   {
+    // Store the pending operations mask so that it can be restored later on with no modifications made on it
+    // while getting the natural size were reflected on the original mask.
+    OperationsMask operationsPendingBackUp = static_cast<OperationsMask>(impl.mOperationsPending);
     // Operations that can be done only once until the text changes.
     const OperationsMask onlyOnceOperations = static_cast<OperationsMask>(CONVERT_TO_UTF32 |
                                                                           GET_SCRIPTS |
@@ -275,23 +273,14 @@ float Controller::Relayouter::GetHeightForWidth(Controller& controller, float wi
                                            LAYOUT),
                layoutSize);
 
-    // Do not do again the only once operations.
-    operationsPending = static_cast<OperationsMask>(operationsPending & ~onlyOnceOperations);
-
-    // Do the size related operations again.
-    const OperationsMask sizeOperations = static_cast<OperationsMask>(LAYOUT |
-                                                                      ALIGN |
-                                                                      REORDER);
-
-    operationsPending = static_cast<OperationsMask>(operationsPending | sizeOperations);
-
     // Clear the update info. This info will be set the next time the text is updated.
     textUpdateInfo.Clear();
     textUpdateInfo.mClearAll = true;
 
     // Restore the actual control's width.
     visualModel->mControlSize.width = actualControlWidth;
-
+    // Restore the previously backed-up pending operations' mask without the only once operations.
+    impl.mOperationsPending = static_cast<OperationsMask>(operationsPendingBackUp & ~onlyOnceOperations);
     DALI_LOG_INFO(gLogFilter, Debug::Verbose, "<--Controller::GetHeightForWidth calculated %f\n", layoutSize.height);
   }
   else