Merge "[AT-SPI] Support for hidden text added" into devel/master
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / text / text-controller.cpp
1 /*
2  * Copyright (c) 2021 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include <dali-toolkit/internal/text/text-controller.h>
20
21 // EXTERNAL INCLUDES
22 #include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
23 #include <dali/devel-api/adaptor-framework/window-devel.h>
24 #include <dali/integration-api/debug.h>
25 #include <memory.h>
26 #include <cmath>
27 #include <limits>
28
29 // INTERNAL INCLUDES
30 #include <dali-toolkit/devel-api/text/text-enumerations-devel.h>
31 #include <dali-toolkit/internal/text/text-controller-event-handler.h>
32 #include <dali-toolkit/internal/text/text-controller-impl.h>
33 #include <dali-toolkit/internal/text/text-controller-input-font-handler.h>
34 #include <dali-toolkit/internal/text/text-controller-input-properties.h>
35 #include <dali-toolkit/internal/text/text-controller-placeholder-handler.h>
36 #include <dali-toolkit/internal/text/text-controller-relayouter.h>
37 #include <dali-toolkit/internal/text/text-controller-text-updater.h>
38 #include <dali-toolkit/internal/text/text-editable-control-interface.h>
39
40 namespace
41 {
42 #if defined(DEBUG_ENABLED)
43 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, true, "LOG_TEXT_CONTROLS");
44 #endif
45
46 constexpr float MAX_FLOAT = std::numeric_limits<float>::max();
47
48 const std::string EMPTY_STRING("");
49
50 template<typename Type>
51 void EnsureCreated(Type*& object)
52 {
53   if(!object)
54   {
55     object = new Type();
56   }
57 }
58
59 template<typename Type>
60 void EnsureCreated(std::unique_ptr<Type>& object)
61 {
62   if(!object)
63   {
64     object = std::unique_ptr<Type>(new Type());
65   }
66 }
67
68 template<typename Type, typename Arg1>
69 void EnsureCreated(Type*& object, Arg1 arg1)
70 {
71   if(!object)
72   {
73     object = new Type(arg1);
74   }
75 }
76
77 template<typename Type, typename Arg1, typename Arg2>
78 void EnsureCreated(Type*& object, Arg1 arg1, Arg2 arg2)
79 {
80   if(!object)
81   {
82     object = new Type(arg1, arg2);
83   }
84 }
85
86 float GetDpi()
87 {
88   unsigned int                      horizontalDpi = 0u;
89   unsigned int                      verticalDpi   = 0u;
90   Dali::TextAbstraction::FontClient fontClient    = Dali::TextAbstraction::FontClient::Get();
91   fontClient.GetDpi(horizontalDpi, verticalDpi);
92   return static_cast<float>(horizontalDpi);
93 }
94
95 float ConvertPixelToPoint(float pixel)
96 {
97   return pixel * 72.0f / GetDpi();
98 }
99
100 float ConvertPointToPixel(float point)
101 {
102   // Pixel size = Point size * DPI / 72.f
103   return point * GetDpi() / 72.0f;
104 }
105
106 void UpdateCursorPosition(Dali::Toolkit::Text::EventData* eventData)
107 {
108   if(eventData && Dali::Toolkit::Text::EventData::IsEditingState(eventData->mState))
109   {
110     // Update the cursor position if it's in editing mode
111     eventData->mDecoratorUpdated     = true;
112     eventData->mUpdateCursorPosition = true; // Cursor position should be updated when the font size is updated.
113   }
114 }
115
116 } // namespace
117
118 namespace Dali::Toolkit::Text
119 {
120
121 void Controller::EnableTextInput(DecoratorPtr decorator, InputMethodContext& inputMethodContext)
122 {
123   if(!decorator)
124   {
125     delete mImpl->mEventData;
126     mImpl->mEventData = NULL;
127
128     // Nothing else to do.
129     return;
130   }
131
132   EnsureCreated(mImpl->mEventData, decorator, inputMethodContext);
133 }
134
135 void Controller::SetGlyphType(TextAbstraction::GlyphType glyphType)
136 {
137   // Metrics for bitmap & vector based glyphs are different
138   mImpl->mMetrics->SetGlyphType(glyphType);
139
140   // Clear the font-specific data
141   mImpl->ClearFontData();
142
143   mImpl->RequestRelayout();
144 }
145
146 void Controller::SetMarkupProcessorEnabled(bool enable)
147 {
148   if(enable != mImpl->mMarkupProcessorEnabled)
149   {
150     //If Text was already set, call the SetText again for enabling or disabling markup
151     mImpl->mMarkupProcessorEnabled = enable;
152     std::string text;
153     GetText(text);
154     SetText(text);
155   }
156
157   mImpl->mModel->mVisualModel->SetMarkupProcessorEnabled(enable);
158 }
159
160 bool Controller::IsMarkupProcessorEnabled() const
161 {
162   return mImpl->mMarkupProcessorEnabled;
163 }
164
165 bool Controller::HasAnchors() const
166 {
167   return (mImpl->mMarkupProcessorEnabled && mImpl->mModel->mLogicalModel->mAnchors.Count() && mImpl->IsShowingRealText());
168 }
169
170 void Controller::SetAutoScrollEnabled(bool enable)
171 {
172   DALI_LOG_INFO(gLogFilter, Debug::General, "Controller::SetAutoScrollEnabled[%s] SingleBox[%s]-> [%p]\n", (enable) ? "true" : "false", (mImpl->mLayoutEngine.GetLayout() == Layout::Engine::SINGLE_LINE_BOX) ? "true" : "false", this);
173   mImpl->SetAutoScrollEnabled(enable);
174 }
175
176 bool Controller::IsAutoScrollEnabled() const
177 {
178   DALI_LOG_INFO(gLogFilter, Debug::Verbose, "Controller::IsAutoScrollEnabled[%s]\n", mImpl->mIsAutoScrollEnabled ? "true" : "false");
179   return mImpl->mIsAutoScrollEnabled;
180 }
181
182 CharacterDirection Controller::GetAutoScrollDirection() const
183 {
184   return mImpl->mIsTextDirectionRTL;
185 }
186
187 float Controller::GetAutoScrollLineAlignment() const
188 {
189   float offset = 0.f;
190   if(mImpl->mModel->mVisualModel && (0u != mImpl->mModel->mVisualModel->mLines.Count()))
191   {
192     offset = (*mImpl->mModel->mVisualModel->mLines.Begin()).alignmentOffset;
193   }
194   return offset;
195 }
196
197 void Controller::SetHorizontalScrollEnabled(bool enable)
198 {
199   if(mImpl->mEventData && mImpl->mEventData->mDecorator)
200   {
201     mImpl->mEventData->mDecorator->SetHorizontalScrollEnabled(enable);
202   }
203 }
204
205 bool Controller::IsHorizontalScrollEnabled() const
206 {
207   return mImpl->mEventData && mImpl->mEventData->mDecorator && mImpl->mEventData->mDecorator->IsHorizontalScrollEnabled();
208 }
209
210 void Controller::SetVerticalScrollEnabled(bool enable)
211 {
212   if(mImpl->mEventData && mImpl->mEventData->mDecorator)
213   {
214     mImpl->mEventData->mDecorator->SetVerticalScrollEnabled(enable);
215   }
216 }
217
218 bool Controller::IsVerticalScrollEnabled() const
219 {
220   return mImpl->mEventData && mImpl->mEventData->mDecorator && mImpl->mEventData->mDecorator->IsVerticalScrollEnabled();
221 }
222
223 void Controller::SetSmoothHandlePanEnabled(bool enable)
224 {
225   if(mImpl->mEventData && mImpl->mEventData->mDecorator)
226   {
227     mImpl->mEventData->mDecorator->SetSmoothHandlePanEnabled(enable);
228   }
229 }
230
231 bool Controller::IsSmoothHandlePanEnabled() const
232 {
233   return mImpl->mEventData && mImpl->mEventData->mDecorator && mImpl->mEventData->mDecorator->IsSmoothHandlePanEnabled();
234 }
235
236 void Controller::SetMaximumNumberOfCharacters(Length maxCharacters)
237 {
238   mImpl->mMaximumNumberOfCharacters = maxCharacters;
239 }
240
241 int Controller::GetMaximumNumberOfCharacters()
242 {
243   return mImpl->mMaximumNumberOfCharacters;
244 }
245
246 void Controller::SetEnableCursorBlink(bool enable)
247 {
248   mImpl->SetEnableCursorBlink(enable);
249 }
250
251 bool Controller::GetEnableCursorBlink() const
252 {
253   return mImpl->mEventData && mImpl->mEventData->mCursorBlinkEnabled;
254 }
255
256 void Controller::SetMultiLineEnabled(bool enable)
257 {
258   mImpl->SetMultiLineEnabled(enable);
259 }
260
261 bool Controller::IsMultiLineEnabled() const
262 {
263   return Layout::Engine::MULTI_LINE_BOX == mImpl->mLayoutEngine.GetLayout();
264 }
265
266 void Controller::SetHorizontalAlignment(Text::HorizontalAlignment::Type alignment)
267 {
268   mImpl->SetHorizontalAlignment(alignment);
269 }
270
271 Text::HorizontalAlignment::Type Controller::GetHorizontalAlignment() const
272 {
273   return mImpl->mModel->mHorizontalAlignment;
274 }
275
276 void Controller::SetVerticalAlignment(VerticalAlignment::Type alignment)
277 {
278   mImpl->SetVerticalAlignment(alignment);
279 }
280
281 VerticalAlignment::Type Controller::GetVerticalAlignment() const
282 {
283   return mImpl->mModel->mVerticalAlignment;
284 }
285
286 bool Controller::IsIgnoreSpacesAfterText() const
287 {
288   return mImpl->mModel->mIgnoreSpacesAfterText;
289 }
290
291 void Controller::SetIgnoreSpacesAfterText(bool ignore)
292 {
293   mImpl->mModel->mIgnoreSpacesAfterText = ignore;
294 }
295
296 void Controller::ChangedLayoutDirection()
297 {
298   mImpl->mIsLayoutDirectionChanged = true;
299 }
300
301 void Controller::SetMatchLayoutDirection(DevelText::MatchLayoutDirection type)
302 {
303   mImpl->mModel->mMatchLayoutDirection = type;
304 }
305
306 DevelText::MatchLayoutDirection Controller::GetMatchLayoutDirection() const
307 {
308   return mImpl->mModel->mMatchLayoutDirection;
309 }
310
311 void Controller::SetLayoutDirection(Dali::LayoutDirection::Type layoutDirection)
312 {
313   mImpl->mLayoutDirection = layoutDirection;
314 }
315
316 Dali::LayoutDirection::Type Controller::GetLayoutDirection(Dali::Actor& actor) const
317 {
318   if(mImpl->mModel->mMatchLayoutDirection == DevelText::MatchLayoutDirection::LOCALE ||
319      (mImpl->mModel->mMatchLayoutDirection == DevelText::MatchLayoutDirection::INHERIT && !mImpl->mIsLayoutDirectionChanged))
320   {
321     return static_cast<Dali::LayoutDirection::Type>(DevelWindow::Get(actor).GetRootLayer().GetProperty(Dali::Actor::Property::LAYOUT_DIRECTION).Get<int>());
322   }
323   else
324   {
325     return static_cast<Dali::LayoutDirection::Type>(actor.GetProperty(Dali::Actor::Property::LAYOUT_DIRECTION).Get<int>());
326   }
327 }
328
329 bool Controller::IsShowingRealText() const
330 {
331   return mImpl->IsShowingRealText();
332 }
333
334 void Controller::SetLineWrapMode(Text::LineWrap::Mode lineWrapMode)
335 {
336   mImpl->SetLineWrapMode(lineWrapMode);
337 }
338
339 Text::LineWrap::Mode Controller::GetLineWrapMode() const
340 {
341   return mImpl->mModel->mLineWrapMode;
342 }
343
344 void Controller::SetTextElideEnabled(bool enabled)
345 {
346   mImpl->mModel->mElideEnabled = enabled;
347   mImpl->mModel->mVisualModel->SetTextElideEnabled(enabled);
348 }
349
350 bool Controller::IsTextElideEnabled() const
351 {
352   return mImpl->mModel->mElideEnabled;
353 }
354
355 void Controller::SetTextFitEnabled(bool enabled)
356 {
357   mImpl->mTextFitEnabled = enabled;
358 }
359
360 bool Controller::IsTextFitEnabled() const
361 {
362   return mImpl->mTextFitEnabled;
363 }
364
365 void Controller::SetTextFitMinSize(float minSize, FontSizeType type)
366 {
367   mImpl->mTextFitMinSize = (type == POINT_SIZE) ? minSize : ConvertPixelToPoint(minSize);
368 }
369
370 float Controller::GetTextFitMinSize() const
371 {
372   return mImpl->mTextFitMinSize;
373 }
374
375 void Controller::SetTextFitMaxSize(float maxSize, FontSizeType type)
376 {
377   mImpl->mTextFitMaxSize = (type == POINT_SIZE) ? maxSize : ConvertPixelToPoint(maxSize);
378 }
379
380 float Controller::GetTextFitMaxSize() const
381 {
382   return mImpl->mTextFitMaxSize;
383 }
384
385 void Controller::SetTextFitStepSize(float step, FontSizeType type)
386 {
387   mImpl->mTextFitStepSize = (type == POINT_SIZE) ? step : ConvertPixelToPoint(step);
388 }
389
390 float Controller::GetTextFitStepSize() const
391 {
392   return mImpl->mTextFitStepSize;
393 }
394
395 void Controller::SetTextFitContentSize(Vector2 size)
396 {
397   mImpl->mTextFitContentSize = size;
398 }
399
400 Vector2 Controller::GetTextFitContentSize() const
401 {
402   return mImpl->mTextFitContentSize;
403 }
404
405 void Controller::SetPlaceholderTextElideEnabled(bool enabled)
406 {
407   PlaceholderHandler::SetPlaceholderTextElideEnabled(*this, enabled);
408 }
409
410 bool Controller::IsPlaceholderTextElideEnabled() const
411 {
412   return PlaceholderHandler::IsPlaceholderTextElideEnabled(*this);
413 }
414
415 void Controller::SetSelectionEnabled(bool enabled)
416 {
417   mImpl->mEventData->mSelectionEnabled = enabled;
418 }
419
420 bool Controller::IsSelectionEnabled() const
421 {
422   return mImpl->mEventData->mSelectionEnabled;
423 }
424
425 void Controller::SetShiftSelectionEnabled(bool enabled)
426 {
427   mImpl->mEventData->mShiftSelectionFlag = enabled;
428 }
429
430 bool Controller::IsShiftSelectionEnabled() const
431 {
432   return mImpl->mEventData->mShiftSelectionFlag;
433 }
434
435 void Controller::SetGrabHandleEnabled(bool enabled)
436 {
437   mImpl->mEventData->mGrabHandleEnabled = enabled;
438 }
439
440 bool Controller::IsGrabHandleEnabled() const
441 {
442   return mImpl->mEventData->mGrabHandleEnabled;
443 }
444
445 void Controller::SetGrabHandlePopupEnabled(bool enabled)
446 {
447   mImpl->mEventData->mGrabHandlePopupEnabled = enabled;
448 }
449
450 bool Controller::IsGrabHandlePopupEnabled() const
451 {
452   return mImpl->mEventData->mGrabHandlePopupEnabled;
453 }
454
455 void Controller::SetText(const std::string& text)
456 {
457   TextUpdater::SetText(*this, text);
458 }
459
460 void Controller::GetText(std::string& text) const
461 {
462   if(!mImpl->IsShowingPlaceholderText())
463   {
464     // Retrieves the text string.
465     mImpl->GetText(0u, text);
466   }
467   else
468   {
469     DALI_LOG_INFO(gLogFilter, Debug::Verbose, "Controller::GetText %p empty (but showing placeholder)\n", this);
470   }
471 }
472
473 void Controller::SetPlaceholderText(PlaceholderType type, const std::string& text)
474 {
475   PlaceholderHandler::SetPlaceholderText(*this, type, text);
476 }
477
478 void Controller::GetPlaceholderText(PlaceholderType type, std::string& text) const
479 {
480   PlaceholderHandler::GetPlaceholderText(*this, type, text);
481 }
482
483 void Controller::UpdateAfterFontChange(const std::string& newDefaultFont)
484 {
485   mImpl->UpdateAfterFontChange(newDefaultFont);
486 }
487
488 void Controller::RetrieveSelection(std::string& selectedText) const
489 {
490   mImpl->RetrieveSelection(selectedText, false);
491 }
492
493 void Controller::SetSelection(int start, int end)
494 {
495   mImpl->SetSelection(start, end);
496 }
497
498 std::pair<int, int> Controller::GetSelectionIndexes() const
499 {
500   return mImpl->GetSelectionIndexes();
501 }
502
503 void Controller::CopyStringToClipboard(const std::string& source)
504 {
505   mImpl->CopyStringToClipboard(source);
506 }
507
508 void Controller::SendSelectionToClipboard(bool deleteAfterSending)
509 {
510   mImpl->SendSelectionToClipboard(deleteAfterSending);
511 }
512
513 void Controller::SetDefaultFontFamily(const std::string& defaultFontFamily)
514 {
515   EnsureCreated(mImpl->mFontDefaults);
516
517   mImpl->mFontDefaults->mFontDescription.family = defaultFontFamily;
518   DALI_LOG_INFO(gLogFilter, Debug::General, "Controller::SetDefaultFontFamily %s\n", defaultFontFamily.c_str());
519   mImpl->mFontDefaults->familyDefined = !defaultFontFamily.empty();
520
521   // Update the cursor position if it's in editing mode
522   UpdateCursorPosition(mImpl->mEventData);
523
524   // Clear the font-specific data
525   mImpl->ClearFontData();
526
527   mImpl->RequestRelayout();
528 }
529
530 const std::string& Controller::GetDefaultFontFamily() const
531 {
532   return mImpl->mFontDefaults ? mImpl->mFontDefaults->mFontDescription.family : EMPTY_STRING;
533 }
534
535 void Controller::SetPlaceholderFontFamily(const std::string& placeholderTextFontFamily)
536 {
537   PlaceholderHandler::SetPlaceholderFontFamily(*this, placeholderTextFontFamily);
538 }
539
540 const std::string& Controller::GetPlaceholderFontFamily() const
541 {
542   return PlaceholderHandler::GetPlaceholderFontFamily(*this);
543 }
544
545 void Controller::SetDefaultFontWeight(FontWeight weight)
546 {
547   EnsureCreated(mImpl->mFontDefaults);
548
549   mImpl->mFontDefaults->mFontDescription.weight = weight;
550   mImpl->mFontDefaults->weightDefined           = true;
551
552   // Update the cursor position if it's in editing mode
553   UpdateCursorPosition(mImpl->mEventData);
554
555   // Clear the font-specific data
556   mImpl->ClearFontData();
557
558   mImpl->RequestRelayout();
559 }
560
561 bool Controller::IsDefaultFontWeightDefined() const
562 {
563   return mImpl->mFontDefaults && mImpl->mFontDefaults->weightDefined;
564 }
565
566 FontWeight Controller::GetDefaultFontWeight() const
567 {
568   return mImpl->mFontDefaults ? mImpl->mFontDefaults->mFontDescription.weight : TextAbstraction::FontWeight::NORMAL;
569 }
570
571 void Controller::SetPlaceholderTextFontWeight(FontWeight weight)
572 {
573   PlaceholderHandler::SetPlaceholderTextFontWeight(*this, weight);
574 }
575
576 bool Controller::IsPlaceholderTextFontWeightDefined() const
577 {
578   return PlaceholderHandler::IsPlaceholderTextFontWeightDefined(*this);
579 }
580
581 FontWeight Controller::GetPlaceholderTextFontWeight() const
582 {
583   return PlaceholderHandler::GetPlaceholderTextFontWeight(*this);
584 }
585
586 void Controller::SetDefaultFontWidth(FontWidth width)
587 {
588   EnsureCreated(mImpl->mFontDefaults);
589
590   mImpl->mFontDefaults->mFontDescription.width = width;
591   mImpl->mFontDefaults->widthDefined           = true;
592
593   // Update the cursor position if it's in editing mode
594   UpdateCursorPosition(mImpl->mEventData);
595
596   // Clear the font-specific data
597   mImpl->ClearFontData();
598
599   mImpl->RequestRelayout();
600 }
601
602 bool Controller::IsDefaultFontWidthDefined() const
603 {
604   return mImpl->mFontDefaults && mImpl->mFontDefaults->widthDefined;
605 }
606
607 FontWidth Controller::GetDefaultFontWidth() const
608 {
609   return mImpl->mFontDefaults ? mImpl->mFontDefaults->mFontDescription.width : TextAbstraction::FontWidth::NORMAL;
610 }
611
612 void Controller::SetPlaceholderTextFontWidth(FontWidth width)
613 {
614   PlaceholderHandler::SetPlaceholderTextFontWidth(*this, width);
615 }
616
617 bool Controller::IsPlaceholderTextFontWidthDefined() const
618 {
619   return PlaceholderHandler::IsPlaceholderTextFontWidthDefined(*this);
620 }
621
622 FontWidth Controller::GetPlaceholderTextFontWidth() const
623 {
624   return PlaceholderHandler::GetPlaceholderTextFontWidth(*this);
625 }
626
627 void Controller::SetDefaultFontSlant(FontSlant slant)
628 {
629   EnsureCreated(mImpl->mFontDefaults);
630
631   mImpl->mFontDefaults->mFontDescription.slant = slant;
632   mImpl->mFontDefaults->slantDefined           = true;
633
634   // Update the cursor position if it's in editing mode
635   UpdateCursorPosition(mImpl->mEventData);
636
637   // Clear the font-specific data
638   mImpl->ClearFontData();
639
640   mImpl->RequestRelayout();
641 }
642
643 bool Controller::IsDefaultFontSlantDefined() const
644 {
645   return mImpl->mFontDefaults && mImpl->mFontDefaults->slantDefined;
646 }
647
648 FontSlant Controller::GetDefaultFontSlant() const
649 {
650   return mImpl->mFontDefaults ? mImpl->mFontDefaults->mFontDescription.slant : TextAbstraction::FontSlant::NORMAL;
651 }
652
653 void Controller::SetPlaceholderTextFontSlant(FontSlant slant)
654 {
655   PlaceholderHandler::SetPlaceholderTextFontSlant(*this, slant);
656 }
657
658 bool Controller::IsPlaceholderTextFontSlantDefined() const
659 {
660   return PlaceholderHandler::IsPlaceholderTextFontSlantDefined(*this);
661 }
662
663 FontSlant Controller::GetPlaceholderTextFontSlant() const
664 {
665   return PlaceholderHandler::GetPlaceholderTextFontSlant(*this);
666 }
667
668 void Controller::SetFontSizeScale(float scale)
669 {
670   mImpl->mFontSizeScale = scale;
671
672   // Update the cursor position if it's in editing mode
673   UpdateCursorPosition(mImpl->mEventData);
674
675   // Clear the font-specific data
676   mImpl->ClearFontData();
677
678   mImpl->RequestRelayout();
679 }
680
681 float Controller::GetFontSizeScale() const
682 {
683   return mImpl->mFontDefaults ? mImpl->mFontSizeScale : 1.0f;
684 }
685
686 void Controller::SetDefaultFontSize(float fontSize, FontSizeType type)
687 {
688   EnsureCreated(mImpl->mFontDefaults);
689
690   mImpl->mFontDefaults->mDefaultPointSize = (type == POINT_SIZE) ? fontSize : ConvertPixelToPoint(fontSize);
691   mImpl->mFontDefaults->sizeDefined       = true;
692
693   // Update the cursor position if it's in editing mode
694   UpdateCursorPosition(mImpl->mEventData);
695
696   // Clear the font-specific data
697   mImpl->ClearFontData();
698
699   mImpl->RequestRelayout();
700 }
701
702 float Controller::GetDefaultFontSize(FontSizeType type) const
703 {
704   if(mImpl->mFontDefaults)
705   {
706     return (type == POINT_SIZE) ? mImpl->mFontDefaults->mDefaultPointSize : ConvertPointToPixel(mImpl->mFontDefaults->mDefaultPointSize);
707   }
708   return 0.0f;
709 }
710
711 void Controller::SetPlaceholderTextFontSize(float fontSize, FontSizeType type)
712 {
713   PlaceholderHandler::SetPlaceholderTextFontSize(*this, fontSize, type);
714 }
715
716 float Controller::GetPlaceholderTextFontSize(FontSizeType type) const
717 {
718   return PlaceholderHandler::GetPlaceholderTextFontSize(*this, type);
719 }
720
721 void Controller::SetDefaultColor(const Vector4& color)
722 {
723   mImpl->SetDefaultColor(color);
724 }
725
726 const Vector4& Controller::GetDefaultColor() const
727 {
728   return mImpl->mTextColor;
729 }
730
731 void Controller::SetPlaceholderTextColor(const Vector4& textColor)
732 {
733   PlaceholderHandler::SetPlaceholderTextColor(*this, textColor);
734 }
735
736 const Vector4& Controller::GetPlaceholderTextColor() const
737 {
738   return PlaceholderHandler::GetPlaceholderTextColor(*this);
739 }
740
741 void Controller::SetShadowOffset(const Vector2& shadowOffset)
742 {
743   mImpl->mModel->mVisualModel->SetShadowOffset(shadowOffset);
744   mImpl->RequestRelayout();
745 }
746
747 const Vector2& Controller::GetShadowOffset() const
748 {
749   return mImpl->mModel->mVisualModel->GetShadowOffset();
750 }
751
752 void Controller::SetShadowColor(const Vector4& shadowColor)
753 {
754   mImpl->mModel->mVisualModel->SetShadowColor(shadowColor);
755   mImpl->RequestRelayout();
756 }
757
758 const Vector4& Controller::GetShadowColor() const
759 {
760   return mImpl->mModel->mVisualModel->GetShadowColor();
761 }
762
763 void Controller::SetShadowBlurRadius(const float& shadowBlurRadius)
764 {
765   if(fabsf(GetShadowBlurRadius() - shadowBlurRadius) > Math::MACHINE_EPSILON_1)
766   {
767     mImpl->mModel->mVisualModel->SetShadowBlurRadius(shadowBlurRadius);
768     mImpl->RequestRelayout();
769   }
770 }
771
772 const float& Controller::GetShadowBlurRadius() const
773 {
774   return mImpl->mModel->mVisualModel->GetShadowBlurRadius();
775 }
776
777 void Controller::SetUnderlineColor(const Vector4& color)
778 {
779   mImpl->mModel->mVisualModel->SetUnderlineColor(color);
780   mImpl->RequestRelayout();
781 }
782
783 const Vector4& Controller::GetUnderlineColor() const
784 {
785   return mImpl->mModel->mVisualModel->GetUnderlineColor();
786 }
787
788 void Controller::SetUnderlineEnabled(bool enabled)
789 {
790   mImpl->mModel->mVisualModel->SetUnderlineEnabled(enabled);
791   mImpl->RequestRelayout();
792 }
793
794 bool Controller::IsUnderlineEnabled() const
795 {
796   return mImpl->mModel->mVisualModel->IsUnderlineEnabled();
797 }
798
799 void Controller::SetUnderlineHeight(float height)
800 {
801   mImpl->mModel->mVisualModel->SetUnderlineHeight(height);
802   mImpl->RequestRelayout();
803 }
804
805 float Controller::GetUnderlineHeight() const
806 {
807   return mImpl->mModel->mVisualModel->GetUnderlineHeight();
808 }
809
810 void Controller::SetOutlineColor(const Vector4& color)
811 {
812   mImpl->mModel->mVisualModel->SetOutlineColor(color);
813   mImpl->RequestRelayout();
814 }
815
816 const Vector4& Controller::GetOutlineColor() const
817 {
818   return mImpl->mModel->mVisualModel->GetOutlineColor();
819 }
820
821 void Controller::SetOutlineWidth(uint16_t width)
822 {
823   mImpl->mModel->mVisualModel->SetOutlineWidth(width);
824   mImpl->RequestRelayout();
825 }
826
827 uint16_t Controller::GetOutlineWidth() const
828 {
829   return mImpl->mModel->mVisualModel->GetOutlineWidth();
830 }
831
832 void Controller::SetBackgroundColor(const Vector4& color)
833 {
834   mImpl->mModel->mVisualModel->SetBackgroundColor(color);
835   mImpl->RequestRelayout();
836 }
837
838 const Vector4& Controller::GetBackgroundColor() const
839 {
840   return mImpl->mModel->mVisualModel->GetBackgroundColor();
841 }
842
843 void Controller::SetBackgroundEnabled(bool enabled)
844 {
845   mImpl->mModel->mVisualModel->SetBackgroundEnabled(enabled);
846   mImpl->RequestRelayout();
847 }
848
849 bool Controller::IsBackgroundEnabled() const
850 {
851   return mImpl->mModel->mVisualModel->IsBackgroundEnabled();
852 }
853
854 void Controller::SetDefaultEmbossProperties(const std::string& embossProperties)
855 {
856   EnsureCreated(mImpl->mEmbossDefaults);
857   mImpl->mEmbossDefaults->properties = embossProperties;
858 }
859
860 const std::string& Controller::GetDefaultEmbossProperties() const
861 {
862   return mImpl->mEmbossDefaults ? mImpl->mEmbossDefaults->properties : EMPTY_STRING;
863 }
864
865 void Controller::SetDefaultOutlineProperties(const std::string& outlineProperties)
866 {
867   EnsureCreated(mImpl->mOutlineDefaults);
868   mImpl->mOutlineDefaults->properties = outlineProperties;
869 }
870
871 const std::string& Controller::GetDefaultOutlineProperties() const
872 {
873   return mImpl->mOutlineDefaults ? mImpl->mOutlineDefaults->properties : EMPTY_STRING;
874 }
875
876 bool Controller::SetDefaultLineSpacing(float lineSpacing)
877 {
878   return mImpl->SetDefaultLineSpacing(lineSpacing);
879 }
880
881 float Controller::GetDefaultLineSpacing() const
882 {
883   return mImpl->mLayoutEngine.GetDefaultLineSpacing();
884 }
885
886 bool Controller::SetDefaultLineSize(float lineSize)
887 {
888   return mImpl->SetDefaultLineSize(lineSize);
889 }
890
891 float Controller::GetDefaultLineSize() const
892 {
893   return mImpl->mLayoutEngine.GetDefaultLineSize();
894 }
895
896 void Controller::SetInputColor(const Vector4& color)
897 {
898   InputProperties::SetInputColor(*this, color);
899 }
900
901 const Vector4& Controller::GetInputColor() const
902 {
903   return InputProperties::GetInputColor(*this);
904 }
905
906 void Controller::SetInputFontFamily(const std::string& fontFamily)
907 {
908   InputFontHandler::SetInputFontFamily(*this, fontFamily);
909 }
910
911 const std::string& Controller::GetInputFontFamily() const
912 {
913   return InputFontHandler::GetInputFontFamily(*this);
914 }
915
916 void Controller::SetInputFontWeight(FontWeight weight)
917 {
918   InputFontHandler::SetInputFontWeight(*this, weight);
919 }
920
921 bool Controller::IsInputFontWeightDefined() const
922 {
923   return InputFontHandler::IsInputFontWeightDefined(*this);
924 }
925
926 FontWeight Controller::GetInputFontWeight() const
927 {
928   return InputFontHandler::GetInputFontWeight(*this);
929 }
930
931 void Controller::SetInputFontWidth(FontWidth width)
932 {
933   InputFontHandler::SetInputFontWidth(*this, width);
934 }
935
936 bool Controller::IsInputFontWidthDefined() const
937 {
938   return InputFontHandler::IsInputFontWidthDefined(*this);
939 }
940
941 FontWidth Controller::GetInputFontWidth() const
942 {
943   return InputFontHandler::GetInputFontWidth(*this);
944 }
945
946 void Controller::SetInputFontSlant(FontSlant slant)
947 {
948   InputFontHandler::SetInputFontSlant(*this, slant);
949 }
950
951 bool Controller::IsInputFontSlantDefined() const
952 {
953   return InputFontHandler::IsInputFontSlantDefined(*this);
954 }
955
956 FontSlant Controller::GetInputFontSlant() const
957 {
958   return InputFontHandler::GetInputFontSlant(*this);
959 }
960
961 void Controller::SetInputFontPointSize(float size)
962 {
963   InputFontHandler::SetInputFontPointSize(*this, size);
964 }
965
966 float Controller::GetInputFontPointSize() const
967 {
968   return InputFontHandler::GetInputFontPointSize(*this);
969 }
970
971 void Controller::SetInputLineSpacing(float lineSpacing)
972 {
973   InputProperties::SetInputLineSpacing(*this, lineSpacing);
974 }
975
976 float Controller::GetInputLineSpacing() const
977 {
978   return InputProperties::GetInputLineSpacing(*this);
979 }
980
981 void Controller::SetInputShadowProperties(const std::string& shadowProperties)
982 {
983   InputProperties::SetInputShadowProperties(*this, shadowProperties);
984 }
985
986 const std::string& Controller::GetInputShadowProperties() const
987 {
988   return InputProperties::GetInputShadowProperties(*this);
989 }
990
991 void Controller::SetInputUnderlineProperties(const std::string& underlineProperties)
992 {
993   InputProperties::SetInputUnderlineProperties(*this, underlineProperties);
994 }
995
996 const std::string& Controller::GetInputUnderlineProperties() const
997 {
998   return InputProperties::GetInputUnderlineProperties(*this);
999 }
1000
1001 void Controller::SetInputEmbossProperties(const std::string& embossProperties)
1002 {
1003   InputProperties::SetInputEmbossProperties(*this, embossProperties);
1004 }
1005
1006 const std::string& Controller::GetInputEmbossProperties() const
1007 {
1008   return InputProperties::GetInputEmbossProperties(*this);
1009 }
1010
1011 void Controller::SetInputOutlineProperties(const std::string& outlineProperties)
1012 {
1013   InputProperties::SetInputOutlineProperties(*this, outlineProperties);
1014 }
1015
1016 const std::string& Controller::GetInputOutlineProperties() const
1017 {
1018   return InputProperties::GetInputOutlineProperties(*this);
1019 }
1020
1021 void Controller::SetInputModePassword(bool passwordInput)
1022 {
1023   InputProperties::SetInputModePassword(*this, passwordInput);
1024 }
1025
1026 bool Controller::IsInputModePassword()
1027 {
1028   return InputProperties::IsInputModePassword(*this);
1029 }
1030
1031 void Controller::SetNoTextDoubleTapAction(NoTextTap::Action action)
1032 {
1033   if(mImpl->mEventData)
1034   {
1035     mImpl->mEventData->mDoubleTapAction = action;
1036   }
1037 }
1038
1039 Controller::NoTextTap::Action Controller::GetNoTextDoubleTapAction() const
1040 {
1041   return mImpl->mEventData ? mImpl->mEventData->mDoubleTapAction : NoTextTap::NO_ACTION;
1042 }
1043
1044 void Controller::SetNoTextLongPressAction(NoTextTap::Action action)
1045 {
1046   if(mImpl->mEventData)
1047   {
1048     mImpl->mEventData->mLongPressAction = action;
1049   }
1050 }
1051
1052 Controller::NoTextTap::Action Controller::GetNoTextLongPressAction() const
1053 {
1054   return mImpl->mEventData ? mImpl->mEventData->mLongPressAction : NoTextTap::NO_ACTION;
1055 }
1056
1057 bool Controller::IsUnderlineSetByString()
1058 {
1059   return mImpl->mUnderlineSetByString;
1060 }
1061
1062 void Controller::UnderlineSetByString(bool setByString)
1063 {
1064   mImpl->mUnderlineSetByString = setByString;
1065 }
1066
1067 bool Controller::IsShadowSetByString()
1068 {
1069   return mImpl->mShadowSetByString;
1070 }
1071
1072 void Controller::ShadowSetByString(bool setByString)
1073 {
1074   mImpl->mShadowSetByString = setByString;
1075 }
1076
1077 bool Controller::IsOutlineSetByString()
1078 {
1079   return mImpl->mOutlineSetByString;
1080 }
1081
1082 void Controller::OutlineSetByString(bool setByString)
1083 {
1084   mImpl->mOutlineSetByString = setByString;
1085 }
1086
1087 bool Controller::IsFontStyleSetByString()
1088 {
1089   return mImpl->mFontStyleSetByString;
1090 }
1091
1092 void Controller::FontStyleSetByString(bool setByString)
1093 {
1094   mImpl->mFontStyleSetByString = setByString;
1095 }
1096
1097 Layout::Engine& Controller::GetLayoutEngine()
1098 {
1099   return mImpl->mLayoutEngine;
1100 }
1101
1102 View& Controller::GetView()
1103 {
1104   return mImpl->mView;
1105 }
1106
1107 Vector3 Controller::GetNaturalSize()
1108 {
1109   return Relayouter::GetNaturalSize(*this);
1110 }
1111
1112 bool Controller::CheckForTextFit(float pointSize, Size& layoutSize)
1113 {
1114   return Relayouter::CheckForTextFit(*this, pointSize, layoutSize);
1115 }
1116
1117 void Controller::FitPointSizeforLayout(Size layoutSize)
1118 {
1119   Relayouter::FitPointSizeforLayout(*this, layoutSize);
1120 }
1121
1122 float Controller::GetHeightForWidth(float width)
1123 {
1124   return Relayouter::GetHeightForWidth(*this, width);
1125 }
1126
1127 int Controller::GetLineCount(float width)
1128 {
1129   GetHeightForWidth(width);
1130   return mImpl->mModel->GetNumberOfLines();
1131 }
1132
1133 const ModelInterface* const Controller::GetTextModel() const
1134 {
1135   return mImpl->mModel.Get();
1136 }
1137
1138 float Controller::GetScrollAmountByUserInput()
1139 {
1140   float scrollAmount = 0.0f;
1141
1142   if(NULL != mImpl->mEventData && mImpl->mEventData->mCheckScrollAmount)
1143   {
1144     scrollAmount                          = mImpl->mModel->mScrollPosition.y - mImpl->mModel->mScrollPositionLast.y;
1145     mImpl->mEventData->mCheckScrollAmount = false;
1146   }
1147   return scrollAmount;
1148 }
1149
1150 bool Controller::GetTextScrollInfo(float& scrollPosition, float& controlHeight, float& layoutHeight)
1151 {
1152   const Vector2& layout = mImpl->mModel->mVisualModel->GetLayoutSize();
1153   bool           isScrolled;
1154
1155   controlHeight  = mImpl->mModel->mVisualModel->mControlSize.height;
1156   layoutHeight   = layout.height;
1157   scrollPosition = mImpl->mModel->mScrollPosition.y;
1158   isScrolled     = !Equals(mImpl->mModel->mScrollPosition.y, mImpl->mModel->mScrollPositionLast.y, Math::MACHINE_EPSILON_1);
1159   return isScrolled;
1160 }
1161
1162 void Controller::SetHiddenInputOption(const Property::Map& options)
1163 {
1164   EnsureCreated<HiddenText, Controller*>(mImpl->mHiddenInput, this);
1165   mImpl->mHiddenInput->SetProperties(options);
1166 }
1167
1168 void Controller::GetHiddenInputOption(Property::Map& options)
1169 {
1170   if(mImpl->mHiddenInput)
1171   {
1172     mImpl->mHiddenInput->GetProperties(options);
1173   }
1174 }
1175
1176 void Controller::SetInputFilterOption(const Property::Map& options)
1177 {
1178   EnsureCreated(mImpl->mInputFilter);
1179   mImpl->mInputFilter->SetProperties(options);
1180 }
1181
1182 void Controller::GetInputFilterOption(Property::Map& options)
1183 {
1184   if(mImpl->mInputFilter)
1185   {
1186     mImpl->mInputFilter->GetProperties(options);
1187   }
1188 }
1189
1190 void Controller::SetPlaceholderProperty(const Property::Map& map)
1191 {
1192   PlaceholderHandler::SetPlaceholderProperty(*this, map);
1193 }
1194
1195 void Controller::GetPlaceholderProperty(Property::Map& map)
1196 {
1197   PlaceholderHandler::GetPlaceholderProperty(*this, map);
1198 }
1199
1200 Toolkit::DevelText::TextDirection::Type Controller::GetTextDirection()
1201 {
1202   // Make sure the model is up-to-date before layouting
1203   ProcessModifyEvents();
1204
1205   if(mImpl->mUpdateTextDirection)
1206   {
1207     // Operations that can be done only once until the text changes.
1208     const OperationsMask onlyOnceOperations = static_cast<OperationsMask>(CONVERT_TO_UTF32 |
1209                                                                           GET_SCRIPTS |
1210                                                                           VALIDATE_FONTS |
1211                                                                           GET_LINE_BREAKS |
1212                                                                           BIDI_INFO |
1213                                                                           SHAPE_TEXT |
1214                                                                           GET_GLYPH_METRICS);
1215
1216     // Set the update info to relayout the whole text.
1217     mImpl->mTextUpdateInfo.mParagraphCharacterIndex     = 0u;
1218     mImpl->mTextUpdateInfo.mRequestedNumberOfCharacters = mImpl->mModel->mLogicalModel->mText.Count();
1219
1220     // Make sure the model is up-to-date before layouting
1221     mImpl->UpdateModel(onlyOnceOperations);
1222
1223     Vector3 naturalSize;
1224     DoRelayout(Size(MAX_FLOAT, MAX_FLOAT),
1225                static_cast<OperationsMask>(onlyOnceOperations |
1226                                            LAYOUT | REORDER | UPDATE_DIRECTION),
1227                naturalSize.GetVectorXY());
1228
1229     // Do not do again the only once operations.
1230     mImpl->mOperationsPending = static_cast<OperationsMask>(mImpl->mOperationsPending & ~onlyOnceOperations);
1231
1232     // Clear the update info. This info will be set the next time the text is updated.
1233     mImpl->mTextUpdateInfo.Clear();
1234
1235     // FullRelayoutNeeded should be true because DoRelayout is MAX_FLOAT, MAX_FLOAT.
1236     mImpl->mTextUpdateInfo.mFullRelayoutNeeded = true;
1237
1238     mImpl->mUpdateTextDirection = false;
1239   }
1240
1241   return mImpl->mIsTextDirectionRTL ? Toolkit::DevelText::TextDirection::RIGHT_TO_LEFT : Toolkit::DevelText::TextDirection::LEFT_TO_RIGHT;
1242 }
1243
1244 Toolkit::DevelText::VerticalLineAlignment::Type Controller::GetVerticalLineAlignment() const
1245 {
1246   return mImpl->mModel->GetVerticalLineAlignment();
1247 }
1248
1249 void Controller::SetVerticalLineAlignment(Toolkit::DevelText::VerticalLineAlignment::Type alignment)
1250 {
1251   mImpl->mModel->mVerticalLineAlignment = alignment;
1252 }
1253
1254 Toolkit::DevelText::EllipsisPosition::Type Controller::GetEllipsisPosition() const
1255 {
1256   return mImpl->mModel->GetEllipsisPosition();
1257 }
1258
1259 void Controller::SetEllipsisPosition(Toolkit::DevelText::EllipsisPosition::Type ellipsisPosition)
1260 {
1261   mImpl->mModel->mEllipsisPosition = ellipsisPosition;
1262   mImpl->mModel->mVisualModel->SetEllipsisPosition(ellipsisPosition);
1263 }
1264
1265 Controller::UpdateTextType Controller::Relayout(const Size& size, Dali::LayoutDirection::Type layoutDirection)
1266 {
1267   return Relayouter::Relayout(*this, size, layoutDirection);
1268 }
1269
1270 void Controller::RequestRelayout()
1271 {
1272   mImpl->RequestRelayout();
1273 }
1274
1275 bool Controller::IsInputStyleChangedSignalsQueueEmpty()
1276 {
1277   return mImpl->IsInputStyleChangedSignalsQueueEmpty();
1278 }
1279
1280 void Controller::ProcessInputStyleChangedSignals()
1281 {
1282   mImpl->ProcessInputStyleChangedSignals();
1283 }
1284
1285 void Controller::KeyboardFocusGainEvent()
1286 {
1287   EventHandler::KeyboardFocusGainEvent(*this);
1288 }
1289
1290 void Controller::KeyboardFocusLostEvent()
1291 {
1292   EventHandler::KeyboardFocusLostEvent(*this);
1293 }
1294
1295 bool Controller::KeyEvent(const Dali::KeyEvent& keyEvent)
1296 {
1297   return EventHandler::KeyEvent(*this, keyEvent);
1298 }
1299
1300 void Controller::AnchorEvent(float x, float y)
1301 {
1302   EventHandler::AnchorEvent(*this, x, y);
1303 }
1304
1305 void Controller::TapEvent(unsigned int tapCount, float x, float y)
1306 {
1307   EventHandler::TapEvent(*this, tapCount, x, y);
1308 }
1309
1310 void Controller::PanEvent(GestureState state, const Vector2& displacement)
1311 {
1312   EventHandler::PanEvent(*this, state, displacement);
1313 }
1314
1315 void Controller::LongPressEvent(GestureState state, float x, float y)
1316 {
1317   EventHandler::LongPressEvent(*this, state, x, y);
1318 }
1319
1320 void Controller::SelectEvent(float x, float y, SelectionType selectType)
1321 {
1322   EventHandler::SelectEvent(*this, x, y, selectType);
1323 }
1324
1325 void Controller::SelectEvent(const uint32_t start, const uint32_t end, SelectionType selectType)
1326 {
1327   EventHandler::SelectEvent(*this, start, end, selectType);
1328 }
1329
1330 void Controller::SetTextSelectionRange(const uint32_t* start, const uint32_t* end)
1331 {
1332   if(mImpl->mEventData)
1333   {
1334     mImpl->mEventData->mCheckScrollAmount     = true;
1335     mImpl->mEventData->mIsLeftHandleSelected  = true;
1336     mImpl->mEventData->mIsRightHandleSelected = true;
1337     mImpl->SetTextSelectionRange(start, end);
1338     mImpl->RequestRelayout();
1339     KeyboardFocusGainEvent();
1340   }
1341 }
1342
1343 Uint32Pair Controller::GetTextSelectionRange() const
1344 {
1345   return mImpl->GetTextSelectionRange();
1346 }
1347
1348 CharacterIndex Controller::GetPrimaryCursorPosition() const
1349 {
1350   return mImpl->GetPrimaryCursorPosition();
1351 }
1352
1353 bool Controller::SetPrimaryCursorPosition(CharacterIndex index, bool focused)
1354 {
1355   if(mImpl->mEventData)
1356   {
1357     mImpl->mEventData->mCheckScrollAmount     = true;
1358     mImpl->mEventData->mIsLeftHandleSelected  = true;
1359     mImpl->mEventData->mIsRightHandleSelected = true;
1360     mImpl->mEventData->mCheckScrollAmount     = true;
1361     if(mImpl->SetPrimaryCursorPosition(index, focused) && focused)
1362     {
1363       KeyboardFocusGainEvent();
1364       return true;
1365     }
1366   }
1367   return false;
1368 }
1369
1370 void Controller::SelectWholeText()
1371 {
1372   SelectEvent(0.f, 0.f, SelectionType::ALL);
1373 }
1374
1375 void Controller::SelectNone()
1376 {
1377   SelectEvent(0.f, 0.f, SelectionType::NONE);
1378 }
1379
1380 void Controller::SelectText(const uint32_t start, const uint32_t end)
1381 {
1382   SelectEvent(start, end, SelectionType::RANGE);
1383 }
1384
1385 string Controller::GetSelectedText() const
1386 {
1387   string text;
1388   if(EventData::SELECTING == mImpl->mEventData->mState)
1389   {
1390     mImpl->RetrieveSelection(text, false);
1391   }
1392   return text;
1393 }
1394
1395 string Controller::CopyText()
1396 {
1397   string text;
1398   mImpl->RetrieveSelection(text, false);
1399   mImpl->SendSelectionToClipboard(false); // Text not modified
1400
1401   mImpl->mEventData->mUpdateCursorPosition = true;
1402
1403   mImpl->RequestRelayout(); // Cursor, Handles, Selection Highlight, Popup
1404
1405   return text;
1406 }
1407
1408 string Controller::CutText()
1409 {
1410   string text;
1411   mImpl->RetrieveSelection(text, false);
1412
1413   if(!IsEditable())
1414   {
1415     return EMPTY_STRING;
1416   }
1417
1418   mImpl->SendSelectionToClipboard(true); // Synchronous call to modify text
1419   mImpl->mOperationsPending = ALL_OPERATIONS;
1420
1421   if((0u != mImpl->mModel->mLogicalModel->mText.Count()) ||
1422      !mImpl->IsPlaceholderAvailable())
1423   {
1424     mImpl->QueueModifyEvent(ModifyEvent::TEXT_DELETED);
1425   }
1426   else
1427   {
1428     ShowPlaceholderText();
1429   }
1430
1431   mImpl->mEventData->mUpdateCursorPosition = true;
1432   mImpl->mEventData->mScrollAfterDelete    = true;
1433
1434   mImpl->RequestRelayout();
1435
1436   if(nullptr != mImpl->mEditableControlInterface)
1437   {
1438     mImpl->mEditableControlInterface->TextChanged(true);
1439   }
1440   return text;
1441 }
1442
1443 void Controller::PasteText()
1444 {
1445   mImpl->RequestGetTextFromClipboard(); // Request clipboard service to retrieve an item
1446 }
1447
1448 InputMethodContext::CallbackData Controller::OnInputMethodContextEvent(InputMethodContext& inputMethodContext, const InputMethodContext::EventData& inputMethodContextEvent)
1449 {
1450   return EventHandler::OnInputMethodContextEvent(*this, inputMethodContext, inputMethodContextEvent);
1451 }
1452
1453 void Controller::PasteClipboardItemEvent()
1454 {
1455   EventHandler::PasteClipboardItemEvent(*this);
1456 }
1457
1458 void Controller::GetTargetSize(Vector2& targetSize)
1459 {
1460   targetSize = mImpl->mModel->mVisualModel->mControlSize;
1461 }
1462
1463 void Controller::AddDecoration(Actor& actor, bool needsClipping)
1464 {
1465   if(mImpl->mEditableControlInterface)
1466   {
1467     mImpl->mEditableControlInterface->AddDecoration(actor, needsClipping);
1468   }
1469 }
1470
1471 bool Controller::IsEditable() const
1472 {
1473   return mImpl->IsEditable();
1474 }
1475
1476 void Controller::SetEditable(bool editable)
1477 {
1478   mImpl->SetEditable(editable);
1479 }
1480
1481 void Controller::ScrollBy(Vector2 scroll)
1482 {
1483   mImpl->ScrollBy(scroll);
1484 }
1485
1486 float Controller::GetHorizontalScrollPosition()
1487 {
1488   return mImpl->GetHorizontalScrollPosition();
1489 }
1490
1491 float Controller::GetVerticalScrollPosition()
1492 {
1493   return mImpl->GetVerticalScrollPosition();
1494 }
1495
1496 void Controller::DecorationEvent(HandleType handleType, HandleState state, float x, float y)
1497 {
1498   EventHandler::DecorationEvent(*this, handleType, state, x, y);
1499 }
1500
1501 void Controller::TextPopupButtonTouched(Dali::Toolkit::TextSelectionPopup::Buttons button)
1502 {
1503   EventHandler::TextPopupButtonTouched(*this, button);
1504 }
1505
1506 void Controller::DisplayTimeExpired()
1507 {
1508   mImpl->mEventData->mUpdateCursorPosition = true;
1509   // Apply modifications to the model
1510   mImpl->mOperationsPending = ALL_OPERATIONS;
1511
1512   mImpl->RequestRelayout();
1513 }
1514
1515 void Controller::InsertText(const std::string& text, Controller::InsertType type)
1516 {
1517   TextUpdater::InsertText(*this, text, type);
1518 }
1519
1520 void Controller::PasteText(const std::string& stringToPaste)
1521 {
1522   TextUpdater::PasteText(*this, stringToPaste);
1523 }
1524
1525 bool Controller::RemoveText(int cursorOffset, int numberOfCharacters, UpdateInputStyleType type)
1526 {
1527   return TextUpdater::RemoveText(*this, cursorOffset, numberOfCharacters, type);
1528 }
1529
1530 bool Controller::RemoveSelectedText()
1531 {
1532   return TextUpdater::RemoveSelectedText(*this);
1533 }
1534
1535 void Controller::InsertTextAnchor(int numberOfCharacters, CharacterIndex previousCursorIndex)
1536 {
1537   TextUpdater::InsertTextAnchor(*this, numberOfCharacters, previousCursorIndex);
1538 }
1539
1540 void Controller::RemoveTextAnchor(int cursorOffset, int numberOfCharacters, CharacterIndex previousCursorIndex)
1541 {
1542   TextUpdater::RemoveTextAnchor(*this, cursorOffset, numberOfCharacters, previousCursorIndex);
1543 }
1544
1545 bool Controller::DoRelayout(const Size& size, OperationsMask operationsRequired, Size& layoutSize)
1546 {
1547   return Relayouter::DoRelayout(*this, size, operationsRequired, layoutSize);
1548 }
1549
1550 void Controller::CalculateVerticalOffset(const Size& controlSize)
1551 {
1552   Relayouter::CalculateVerticalOffset(*this, controlSize);
1553 }
1554
1555 void Controller::ProcessModifyEvents()
1556 {
1557   EventHandler::ProcessModifyEvents(*this);
1558 }
1559
1560 void Controller::TextReplacedEvent()
1561 {
1562   EventHandler::TextReplacedEvent(*this);
1563 }
1564
1565 void Controller::TextInsertedEvent()
1566 {
1567   EventHandler::TextInsertedEvent(*this);
1568 }
1569
1570 void Controller::TextDeletedEvent()
1571 {
1572   EventHandler::TextDeletedEvent(*this);
1573 }
1574
1575 bool Controller::DeleteEvent(int keyCode)
1576 {
1577   return EventHandler::DeleteEvent(*this, keyCode);
1578 }
1579
1580 // private : Helpers.
1581
1582 void Controller::ResetText()
1583 {
1584   TextUpdater::ResetText(*this);
1585 }
1586
1587 void Controller::ShowPlaceholderText()
1588 {
1589   PlaceholderHandler::ShowPlaceholderText(*this);
1590 }
1591
1592 void Controller::ResetCursorPosition(CharacterIndex cursorIndex)
1593 {
1594   // Reset the cursor position
1595   if(NULL != mImpl->mEventData)
1596   {
1597     mImpl->mEventData->mPrimaryCursorPosition = cursorIndex;
1598
1599     // Update the cursor if it's in editing mode.
1600     if(EventData::IsEditingState(mImpl->mEventData->mState))
1601     {
1602       mImpl->mEventData->mUpdateCursorPosition = true;
1603     }
1604   }
1605 }
1606
1607 CharacterIndex Controller::GetCursorPosition()
1608 {
1609   return mImpl->mEventData ? mImpl->mEventData->mPrimaryCursorPosition : 0;
1610 }
1611
1612 void Controller::SetControlInterface(ControlInterface* controlInterface)
1613 {
1614   mImpl->mControlInterface = controlInterface;
1615 }
1616
1617 void Controller::SetAnchorControlInterface(AnchorControlInterface* anchorControlInterface)
1618 {
1619   mImpl->mAnchorControlInterface = anchorControlInterface;
1620 }
1621
1622 bool Controller::ShouldClearFocusOnEscape() const
1623 {
1624   return mImpl->mShouldClearFocusOnEscape;
1625 }
1626
1627 Actor Controller::CreateBackgroundActor()
1628 {
1629   return mImpl->CreateBackgroundActor();
1630 }
1631
1632 Controller::Controller(ControlInterface*           controlInterface,
1633                        EditableControlInterface*   editableControlInterface,
1634                        SelectableControlInterface* selectableControlInterface,
1635                        AnchorControlInterface*     anchorControlInterface)
1636 : mImpl(new Controller::Impl(controlInterface, editableControlInterface, selectableControlInterface, anchorControlInterface))
1637 {
1638 }
1639
1640 Controller::~Controller()
1641 {
1642   delete mImpl;
1643 }
1644
1645 } // namespace Dali::Toolkit::Text