Merge "[AT-SPI] Use WeakHandle<Actor> in Accessible objects" into devel/master
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / text-controls / text-field-impl.cpp
index 4cca3fd..7fc3eca 100644 (file)
@@ -137,10 +137,12 @@ DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextField, "selectedTextEnd"
 DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextField, "enableEditing",                    BOOLEAN,   ENABLE_EDITING                      )
 DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextField, "fontSizeScale",                    FLOAT,     FONT_SIZE_SCALE                     )
 DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextField, "primaryCursorPosition",            INTEGER,   PRIMARY_CURSOR_POSITION             )
+DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextField, "grabHandleColor",                  VECTOR4,   GRAB_HANDLE_COLOR                   )
 
 DALI_SIGNAL_REGISTRATION(Toolkit, TextField, "textChanged",       SIGNAL_TEXT_CHANGED       )
 DALI_SIGNAL_REGISTRATION(Toolkit, TextField, "maxLengthReached",  SIGNAL_MAX_LENGTH_REACHED )
 DALI_SIGNAL_REGISTRATION(Toolkit, TextField, "inputStyleChanged", SIGNAL_INPUT_STYLE_CHANGED)
+DALI_SIGNAL_REGISTRATION(Toolkit, TextField, "anchorClicked",     SIGNAL_ANCHOR_CLICKED     )
 
 DALI_TYPE_REGISTRATION_END()
 // clang-format on
@@ -754,6 +756,15 @@ void TextField::SetProperty(BaseObject* object, Property::Index index, const Pro
         }
         break;
       }
+      case Toolkit::DevelTextField::Property::GRAB_HANDLE_COLOR:
+      {
+        const Vector4 color = value.Get<Vector4>();
+        DALI_LOG_INFO(gLogFilter, Debug::General, "TextField %p GRAB_HANDLE_COLOR %f,%f,%f,%f\n", impl.mController.Get(), color.r, color.g, color.b, color.a);
+
+        impl.mDecorator->SetHandleColor(color);
+        impl.RequestTextRelayout();
+        break;
+      }
     } // switch
   }   // textfield
 }
@@ -1104,6 +1115,11 @@ Property::Value TextField::GetProperty(BaseObject* object, Property::Index index
         value = static_cast<int>(impl.mController->GetPrimaryCursorPosition());
         break;
       }
+      case Toolkit::DevelTextField::Property::GRAB_HANDLE_COLOR:
+      {
+        value = impl.mDecorator->GetHandleColor();
+        break;
+      }
     } //switch
   }
 
@@ -1180,6 +1196,14 @@ bool TextField::DoConnectSignal(BaseObject* object, ConnectionTrackerInterface*
   {
     field.InputStyleChangedSignal().Connect(tracker, functor);
   }
+  else if(0 == strcmp(signalName.c_str(), SIGNAL_ANCHOR_CLICKED))
+  {
+    if(field)
+    {
+      Internal::TextField& fieldImpl(GetImpl(field));
+      fieldImpl.AnchorClickedSignal().Connect(tracker, functor);
+    }
+  }
   else
   {
     // signalName does not match any signal
@@ -1204,11 +1228,16 @@ Toolkit::TextField::InputStyleChangedSignalType& TextField::InputStyleChangedSig
   return mInputStyleChangedSignal;
 }
 
+DevelTextField::AnchorClickedSignalType& TextField::AnchorClickedSignal()
+{
+  return mAnchorClickedSignal;
+}
+
 void TextField::OnInitialize()
 {
   Actor self = Self();
 
-  mController = Text::Controller::New(this, this, this);
+  mController = Text::Controller::New(this, 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;
@@ -1333,6 +1362,14 @@ float TextField::GetHeightForWidth(float width)
   return mController->GetHeightForWidth(width) + padding.top + padding.bottom;
 }
 
+void TextField::ResizeActor(Actor& actor, const Vector2& size)
+{
+  if(actor.GetProperty<Vector3>(Dali::Actor::Property::SIZE).GetVectorXY() != size)
+  {
+    actor.SetProperty(Actor::Property::SIZE, size);
+  }
+}
+
 void TextField::OnRelayout(const Vector2& size, RelayoutContainer& container)
 {
   DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextField OnRelayout\n");
@@ -1362,10 +1399,12 @@ void TextField::OnRelayout(const Vector2& size, RelayoutContainer& container)
   if(mStencil)
   {
     mStencil.SetProperty(Actor::Property::POSITION, Vector2(padding.start, padding.top));
+    ResizeActor(mStencil, contentSize);
   }
   if(mActiveLayer)
   {
     mActiveLayer.SetProperty(Actor::Property::POSITION, Vector2(padding.start, padding.top));
+    ResizeActor(mActiveLayer, contentSize);
   }
 
   const Text::Controller::UpdateTextType updateTextType = mController->Relayout(contentSize, layoutDirection);
@@ -1378,7 +1417,7 @@ void TextField::OnRelayout(const Vector2& size, RelayoutContainer& container)
     if(mDecorator &&
        (Text::Controller::NONE_UPDATED != (Text::Controller::DECORATOR_UPDATED & updateTextType)))
     {
-      mDecorator->Relayout(size);
+      mDecorator->Relayout(contentSize);
     }
 
     if(!mRenderer)
@@ -1387,6 +1426,12 @@ void TextField::OnRelayout(const Vector2& size, RelayoutContainer& container)
     }
 
     RenderText(updateTextType);
+
+    // If there is text changed, callback is called.
+    if(mTextChanged)
+    {
+      EmitTextChangedSignal();
+    }
   }
 
   // The text-field emits signals when the input style changes. These changes of style are
@@ -1588,6 +1633,7 @@ void TextField::OnTap(const TapGesture& gesture)
   padding                   = Self().GetProperty<Extents>(Toolkit::Control::Property::PADDING);
   const Vector2& localPoint = gesture.GetLocalPoint();
   mController->TapEvent(gesture.GetNumberOfTaps(), localPoint.x - padding.start, localPoint.y - padding.top);
+  mController->AnchorEvent(localPoint.x - padding.start, localPoint.y - padding.top);
 
   SetKeyInputFocus();
 }
@@ -1677,10 +1723,23 @@ void TextField::CaretMoved(unsigned int position)
   }
 }
 
-void TextField::TextChanged()
+void TextField::TextChanged(bool immediate)
+{
+  if(immediate) // Emits TextChangedSignal immediately
+  {
+    EmitTextChangedSignal();
+  }
+  else
+  {
+    mTextChanged = true;
+  }
+}
+
+void TextField::EmitTextChangedSignal()
 {
   Dali::Toolkit::TextField handle(GetOwner());
   mTextChangedSignal.Emit(handle);
+  mTextChanged = false;
 }
 
 void TextField::MaxLengthReached()
@@ -1739,6 +1798,12 @@ void TextField::InputStyleChanged(Text::InputStyle::Mask inputStyleMask)
   mInputStyleChangedSignal.Emit(handle, fieldInputStyleMask);
 }
 
+void TextField::AnchorClicked(const std::string& href)
+{
+  Dali::Toolkit::TextField handle(GetOwner());
+  mAnchorClickedSignal.Emit(handle, href.c_str(), href.length());
+}
+
 void TextField::AddDecoration(Actor& actor, bool needsClipping)
 {
   if(actor)
@@ -1857,7 +1922,8 @@ TextField::TextField()
   mAlignmentOffset(0.f),
   mRenderingBackend(DEFAULT_RENDERING_BACKEND),
   mExceedPolicy(Dali::Toolkit::TextField::EXCEED_POLICY_CLIP),
-  mHasBeenStaged(false)
+  mHasBeenStaged(false),
+  mTextChanged(false)
 {
 }
 
@@ -1873,7 +1939,7 @@ TextField::~TextField()
 
 std::string TextField::AccessibleImpl::GetName()
 {
-  auto slf = Toolkit::TextField::DownCast(self);
+  auto slf = Toolkit::TextField::DownCast(Self());
   return slf.GetProperty(Toolkit::TextField::Property::TEXT).Get<std::string>();
 }
 
@@ -1883,7 +1949,7 @@ std::string TextField::AccessibleImpl::GetText(size_t startOffset,
   if(endOffset <= startOffset)
     return {};
 
-  auto slf = Toolkit::TextField::DownCast(self);
+  auto slf = Toolkit::TextField::DownCast(Self());
   auto txt =
     slf.GetProperty(Toolkit::TextField::Property::TEXT).Get<std::string>();
 
@@ -1895,7 +1961,7 @@ std::string TextField::AccessibleImpl::GetText(size_t startOffset,
 
 size_t TextField::AccessibleImpl::GetCharacterCount()
 {
-  auto slf = Toolkit::TextField::DownCast(self);
+  auto slf = Toolkit::TextField::DownCast(Self());
   auto txt =
     slf.GetProperty(Toolkit::TextField::Property::TEXT).Get<std::string>();
 
@@ -1904,13 +1970,13 @@ size_t TextField::AccessibleImpl::GetCharacterCount()
 
 size_t TextField::AccessibleImpl::GetCaretOffset()
 {
-  auto slf = Toolkit::TextField::DownCast(self);
+  auto slf = Toolkit::TextField::DownCast(Self());
   return Dali::Toolkit::GetImpl(slf).getController()->GetCursorPosition();
 }
 
 bool TextField::AccessibleImpl::SetCaretOffset(size_t offset)
 {
-  auto slf = Toolkit::TextField::DownCast(self);
+  auto slf = Toolkit::TextField::DownCast(Self());
   auto txt = slf.GetProperty(Toolkit::TextField::Property::TEXT).Get<std::string>();
   if(offset > txt.size())
     return false;
@@ -1924,7 +1990,7 @@ bool TextField::AccessibleImpl::SetCaretOffset(size_t offset)
 Dali::Accessibility::Range TextField::AccessibleImpl::GetTextAtOffset(
   size_t offset, Dali::Accessibility::TextBoundary boundary)
 {
-  auto slf      = Toolkit::TextField::DownCast(self);
+  auto slf      = Toolkit::TextField::DownCast(Self());
   auto txt      = slf.GetProperty(Toolkit::TextField::Property::TEXT).Get<std::string>();
   auto txt_size = txt.size();
 
@@ -2004,7 +2070,7 @@ TextField::AccessibleImpl::GetSelection(size_t selectionNum)
   if(selectionNum > 0)
     return {};
 
-  auto        slf  = Toolkit::TextField::DownCast(self);
+  auto        slf  = Toolkit::TextField::DownCast(Self());
   auto        ctrl = Dali::Toolkit::GetImpl(slf).getController();
   std::string ret;
   ctrl->RetrieveSelection(ret);
@@ -2019,7 +2085,7 @@ bool TextField::AccessibleImpl::RemoveSelection(size_t selectionNum)
   if(selectionNum > 0)
     return false;
 
-  auto slf = Toolkit::TextField::DownCast(self);
+  auto slf = Toolkit::TextField::DownCast(Self());
   Dali::Toolkit::GetImpl(slf).getController()->SetSelection(0, 0);
   return true;
 }
@@ -2032,7 +2098,7 @@ bool TextField::AccessibleImpl::SetSelection(size_t selectionNum,
   if(selectionNum > 0)
     return false;
 
-  auto slf = Toolkit::TextField::DownCast(self);
+  auto slf = Toolkit::TextField::DownCast(Self());
   Dali::Toolkit::GetImpl(slf).getController()->SetSelection(startOffset,
                                                             endOffset);
   return true;
@@ -2044,7 +2110,7 @@ bool TextField::AccessibleImpl::CopyText(size_t startPosition,
   if(endPosition <= startPosition)
     return false;
 
-  auto slf = Toolkit::TextField::DownCast(self);
+  auto slf = Toolkit::TextField::DownCast(Self());
   auto txt = slf.GetProperty(Toolkit::TextField::Property::TEXT).Get<std::string>();
   Dali::Toolkit::GetImpl(slf).getController()->CopyStringToClipboard(txt.substr(startPosition, endPosition - startPosition));
 
@@ -2057,7 +2123,7 @@ bool TextField::AccessibleImpl::CutText(size_t startPosition,
   if(endPosition <= startPosition)
     return false;
 
-  auto slf = Toolkit::TextField::DownCast(self);
+  auto slf = Toolkit::TextField::DownCast(Self());
   auto txt = slf.GetProperty(Toolkit::TextField::Property::TEXT).Get<std::string>();
   Dali::Toolkit::GetImpl(slf).getController()->CopyStringToClipboard(txt.substr(startPosition, endPosition - startPosition));
 
@@ -2071,7 +2137,7 @@ Dali::Accessibility::States TextField::AccessibleImpl::CalculateStates()
 {
   using namespace Dali::Accessibility;
 
-  auto states = Control::Impl::AccessibleImpl::CalculateStates();
+  auto states = DevelControl::AccessibleImpl::CalculateStates();
 
   states[State::EDITABLE]  = true;
   states[State::FOCUSABLE] = true;