Merge "Support Ellipsis Position Property" 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-placeholder-handler.h>
35 #include <dali-toolkit/internal/text/text-controller-relayouter.h>
36 #include <dali-toolkit/internal/text/text-controller-text-updater.h>
37 #include <dali-toolkit/internal/text/text-editable-control-interface.h>
38
39 namespace
40 {
41 #if defined(DEBUG_ENABLED)
42 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, true, "LOG_TEXT_CONTROLS");
43 #endif
44
45 constexpr float MAX_FLOAT = std::numeric_limits<float>::max();
46
47 const std::string EMPTY_STRING("");
48
49 int ConvertPixelToPint(float pixel)
50 {
51   unsigned int                      horizontalDpi = 0u;
52   unsigned int                      verticalDpi   = 0u;
53   Dali::TextAbstraction::FontClient fontClient    = Dali::TextAbstraction::FontClient::Get();
54   fontClient.GetDpi(horizontalDpi, verticalDpi);
55
56   return (pixel * 72.f) / static_cast<float>(horizontalDpi);
57 }
58
59 } // namespace
60
61 namespace Dali
62 {
63 namespace Toolkit
64 {
65 namespace Text
66 {
67 // public : Constructor.
68
69 ControllerPtr Controller::New()
70 {
71   return ControllerPtr(new Controller());
72 }
73
74 ControllerPtr Controller::New(ControlInterface* controlInterface)
75 {
76   return ControllerPtr(new Controller(controlInterface));
77 }
78
79 ControllerPtr Controller::New(ControlInterface*           controlInterface,
80                               EditableControlInterface*   editableControlInterface,
81                               SelectableControlInterface* selectableControlInterface,
82                               AnchorControlInterface*     anchorControlInterface)
83 {
84   return ControllerPtr(new Controller(controlInterface,
85                                       editableControlInterface,
86                                       selectableControlInterface,
87                                       anchorControlInterface));
88 }
89
90 // public : Configure the text controller.
91
92 void Controller::EnableTextInput(DecoratorPtr decorator, InputMethodContext& inputMethodContext)
93 {
94   if(!decorator)
95   {
96     delete mImpl->mEventData;
97     mImpl->mEventData = NULL;
98
99     // Nothing else to do.
100     return;
101   }
102
103   if(NULL == mImpl->mEventData)
104   {
105     mImpl->mEventData = new EventData(decorator, inputMethodContext);
106   }
107 }
108
109 void Controller::SetGlyphType(TextAbstraction::GlyphType glyphType)
110 {
111   // Metrics for bitmap & vector based glyphs are different
112   mImpl->mMetrics->SetGlyphType(glyphType);
113
114   // Clear the font-specific data
115   ClearFontData();
116
117   mImpl->RequestRelayout();
118 }
119
120 void Controller::SetMarkupProcessorEnabled(bool enable)
121 {
122   if(enable != mImpl->mMarkupProcessorEnabled)
123   {
124     //If Text was already set, call the SetText again for enabling or disabling markup
125     mImpl->mMarkupProcessorEnabled = enable;
126     std::string text;
127     GetText(text);
128     SetText(text);
129   }
130
131   mImpl->mModel->mVisualModel->SetMarkupProcessorEnabled(enable);
132 }
133
134 bool Controller::IsMarkupProcessorEnabled() const
135 {
136   return mImpl->mMarkupProcessorEnabled;
137 }
138
139 void Controller::SetAutoScrollEnabled(bool enable)
140 {
141   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);
142
143   if(mImpl->mLayoutEngine.GetLayout() == Layout::Engine::SINGLE_LINE_BOX)
144   {
145     if(enable)
146     {
147       DALI_LOG_INFO(gLogFilter, Debug::General, "Controller::SetAutoScrollEnabled for SINGLE_LINE_BOX\n");
148       mImpl->mOperationsPending = static_cast<OperationsMask>(mImpl->mOperationsPending |
149                                                               LAYOUT |
150                                                               ALIGN |
151                                                               UPDATE_LAYOUT_SIZE |
152                                                               UPDATE_DIRECTION |
153                                                               REORDER);
154     }
155     else
156     {
157       DALI_LOG_INFO(gLogFilter, Debug::General, "Controller::SetAutoScrollEnabled Disabling autoscroll\n");
158       mImpl->mOperationsPending = static_cast<OperationsMask>(mImpl->mOperationsPending |
159                                                               LAYOUT |
160                                                               ALIGN |
161                                                               UPDATE_LAYOUT_SIZE |
162                                                               REORDER);
163     }
164
165     mImpl->mIsAutoScrollEnabled = enable;
166     mImpl->RequestRelayout();
167   }
168   else
169   {
170     DALI_LOG_WARNING("Attempted AutoScrolling on a non SINGLE_LINE_BOX, request ignored\n");
171     mImpl->mIsAutoScrollEnabled = false;
172   }
173 }
174
175 bool Controller::IsAutoScrollEnabled() const
176 {
177   DALI_LOG_INFO(gLogFilter, Debug::Verbose, "Controller::IsAutoScrollEnabled[%s]\n", mImpl->mIsAutoScrollEnabled ? "true" : "false");
178
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
191   if(mImpl->mModel->mVisualModel &&
192      (0u != mImpl->mModel->mVisualModel->mLines.Count()))
193   {
194     offset = (*mImpl->mModel->mVisualModel->mLines.Begin()).alignmentOffset;
195   }
196
197   return offset;
198 }
199
200 void Controller::SetHorizontalScrollEnabled(bool enable)
201 {
202   if((NULL != mImpl->mEventData) &&
203      mImpl->mEventData->mDecorator)
204   {
205     mImpl->mEventData->mDecorator->SetHorizontalScrollEnabled(enable);
206   }
207 }
208 bool Controller::IsHorizontalScrollEnabled() const
209 {
210   if((NULL != mImpl->mEventData) &&
211      mImpl->mEventData->mDecorator)
212   {
213     return mImpl->mEventData->mDecorator->IsHorizontalScrollEnabled();
214   }
215
216   return false;
217 }
218
219 void Controller::SetVerticalScrollEnabled(bool enable)
220 {
221   if((NULL != mImpl->mEventData) &&
222      mImpl->mEventData->mDecorator)
223   {
224     if(mImpl->mEventData->mDecorator)
225     {
226       mImpl->mEventData->mDecorator->SetVerticalScrollEnabled(enable);
227     }
228   }
229 }
230
231 bool Controller::IsVerticalScrollEnabled() const
232 {
233   if((NULL != mImpl->mEventData) &&
234      mImpl->mEventData->mDecorator)
235   {
236     return mImpl->mEventData->mDecorator->IsVerticalScrollEnabled();
237   }
238
239   return false;
240 }
241
242 void Controller::SetSmoothHandlePanEnabled(bool enable)
243 {
244   if((NULL != mImpl->mEventData) &&
245      mImpl->mEventData->mDecorator)
246   {
247     mImpl->mEventData->mDecorator->SetSmoothHandlePanEnabled(enable);
248   }
249 }
250
251 bool Controller::IsSmoothHandlePanEnabled() const
252 {
253   if((NULL != mImpl->mEventData) &&
254      mImpl->mEventData->mDecorator)
255   {
256     return mImpl->mEventData->mDecorator->IsSmoothHandlePanEnabled();
257   }
258
259   return false;
260 }
261
262 void Controller::SetMaximumNumberOfCharacters(Length maxCharacters)
263 {
264   mImpl->mMaximumNumberOfCharacters = maxCharacters;
265 }
266
267 int Controller::GetMaximumNumberOfCharacters()
268 {
269   return mImpl->mMaximumNumberOfCharacters;
270 }
271
272 void Controller::SetEnableCursorBlink(bool enable)
273 {
274   DALI_ASSERT_DEBUG(NULL != mImpl->mEventData && "TextInput disabled");
275
276   if(NULL != mImpl->mEventData)
277   {
278     mImpl->mEventData->mCursorBlinkEnabled = enable;
279
280     if(!enable &&
281        mImpl->mEventData->mDecorator)
282     {
283       mImpl->mEventData->mDecorator->StopCursorBlink();
284     }
285   }
286 }
287
288 bool Controller::GetEnableCursorBlink() const
289 {
290   if(NULL != mImpl->mEventData)
291   {
292     return mImpl->mEventData->mCursorBlinkEnabled;
293   }
294
295   return false;
296 }
297
298 void Controller::SetMultiLineEnabled(bool enable)
299 {
300   const Layout::Engine::Type layout = enable ? Layout::Engine::MULTI_LINE_BOX : Layout::Engine::SINGLE_LINE_BOX;
301
302   if(layout != mImpl->mLayoutEngine.GetLayout())
303   {
304     // Set the layout type.
305     mImpl->mLayoutEngine.SetLayout(layout);
306
307     // Set the flags to redo the layout operations
308     const OperationsMask layoutOperations = static_cast<OperationsMask>(LAYOUT |
309                                                                         UPDATE_LAYOUT_SIZE |
310                                                                         ALIGN |
311                                                                         REORDER);
312
313     mImpl->mTextUpdateInfo.mFullRelayoutNeeded = true;
314     mImpl->mOperationsPending                  = static_cast<OperationsMask>(mImpl->mOperationsPending | layoutOperations);
315
316     // Need to recalculate natural size
317     mImpl->mRecalculateNaturalSize = true;
318
319     mImpl->RequestRelayout();
320   }
321 }
322
323 bool Controller::IsMultiLineEnabled() const
324 {
325   return Layout::Engine::MULTI_LINE_BOX == mImpl->mLayoutEngine.GetLayout();
326 }
327
328 void Controller::SetHorizontalAlignment(Text::HorizontalAlignment::Type alignment)
329 {
330   if(alignment != mImpl->mModel->mHorizontalAlignment)
331   {
332     // Set the alignment.
333     mImpl->mModel->mHorizontalAlignment = alignment;
334
335     // Set the flag to redo the alignment operation.
336     mImpl->mOperationsPending = static_cast<OperationsMask>(mImpl->mOperationsPending | ALIGN);
337
338     if(mImpl->mEventData)
339     {
340       mImpl->mEventData->mUpdateAlignment = true;
341
342       // Update the cursor if it's in editing mode
343       if(EventData::IsEditingState(mImpl->mEventData->mState))
344       {
345         mImpl->ChangeState(EventData::EDITING);
346         mImpl->mEventData->mUpdateCursorPosition = true;
347       }
348     }
349
350     mImpl->RequestRelayout();
351   }
352 }
353
354 Text::HorizontalAlignment::Type Controller::GetHorizontalAlignment() const
355 {
356   return mImpl->mModel->mHorizontalAlignment;
357 }
358
359 void Controller::SetVerticalAlignment(VerticalAlignment::Type alignment)
360 {
361   if(alignment != mImpl->mModel->mVerticalAlignment)
362   {
363     // Set the alignment.
364     mImpl->mModel->mVerticalAlignment = alignment;
365
366     mImpl->mOperationsPending = static_cast<OperationsMask>(mImpl->mOperationsPending | ALIGN);
367
368     mImpl->RequestRelayout();
369   }
370 }
371
372 VerticalAlignment::Type Controller::GetVerticalAlignment() const
373 {
374   return mImpl->mModel->mVerticalAlignment;
375 }
376
377 bool Controller::IsIgnoreSpacesAfterText() const
378 {
379   return mImpl->mModel->mIgnoreSpacesAfterText;
380 }
381
382 void Controller::SetIgnoreSpacesAfterText(bool ignore)
383 {
384   mImpl->mModel->mIgnoreSpacesAfterText = ignore;
385 }
386
387 void Controller::ChangedLayoutDirection()
388 {
389   mImpl->mIsLayoutDirectionChanged = true;
390 }
391
392 void Controller::SetMatchLayoutDirection(DevelText::MatchLayoutDirection type)
393 {
394   mImpl->mModel->mMatchLayoutDirection = type;
395 }
396
397 DevelText::MatchLayoutDirection Controller::GetMatchLayoutDirection() const
398 {
399   return mImpl->mModel->mMatchLayoutDirection;
400 }
401
402 void Controller::SetLayoutDirection(Dali::LayoutDirection::Type layoutDirection)
403 {
404   mImpl->mLayoutDirection = layoutDirection;
405 }
406
407 Dali::LayoutDirection::Type Controller::GetLayoutDirection(Dali::Actor& actor) const
408 {
409   if(mImpl->mModel->mMatchLayoutDirection == DevelText::MatchLayoutDirection::LOCALE ||
410      (mImpl->mModel->mMatchLayoutDirection == DevelText::MatchLayoutDirection::INHERIT && !mImpl->mIsLayoutDirectionChanged))
411   {
412     return static_cast<Dali::LayoutDirection::Type>(DevelWindow::Get(actor).GetRootLayer().GetProperty(Dali::Actor::Property::LAYOUT_DIRECTION).Get<int>());
413   }
414   else
415   {
416     return static_cast<Dali::LayoutDirection::Type>(actor.GetProperty(Dali::Actor::Property::LAYOUT_DIRECTION).Get<int>());
417   }
418 }
419
420 bool Controller::IsShowingRealText() const
421 {
422   return mImpl->IsShowingRealText();
423 }
424
425 void Controller::SetLineWrapMode(Text::LineWrap::Mode lineWrapMode)
426 {
427   if(lineWrapMode != mImpl->mModel->mLineWrapMode)
428   {
429     // Update Text layout for applying wrap mode
430     mImpl->mOperationsPending = static_cast<OperationsMask>(mImpl->mOperationsPending |
431                                                             ALIGN |
432                                                             LAYOUT |
433                                                             UPDATE_LAYOUT_SIZE |
434                                                             REORDER);
435
436     if((mImpl->mModel->mLineWrapMode == (Text::LineWrap::Mode)DevelText::LineWrap::HYPHENATION) || (lineWrapMode == (Text::LineWrap::Mode)DevelText::LineWrap::HYPHENATION) ||
437        (mImpl->mModel->mLineWrapMode == (Text::LineWrap::Mode)DevelText::LineWrap::MIXED) || (lineWrapMode == (Text::LineWrap::Mode)DevelText::LineWrap::MIXED)) // hyphen is treated as line break
438     {
439       mImpl->mOperationsPending = static_cast<OperationsMask>(mImpl->mOperationsPending | GET_LINE_BREAKS);
440     }
441
442     // Set the text wrap mode.
443     mImpl->mModel->mLineWrapMode = lineWrapMode;
444
445     mImpl->mTextUpdateInfo.mCharacterIndex             = 0u;
446     mImpl->mTextUpdateInfo.mNumberOfCharactersToRemove = mImpl->mTextUpdateInfo.mPreviousNumberOfCharacters;
447     mImpl->mTextUpdateInfo.mNumberOfCharactersToAdd    = mImpl->mModel->mLogicalModel->mText.Count();
448
449     // Request relayout
450     mImpl->RequestRelayout();
451   }
452 }
453
454 Text::LineWrap::Mode Controller::GetLineWrapMode() const
455 {
456   return mImpl->mModel->mLineWrapMode;
457 }
458
459 void Controller::SetTextElideEnabled(bool enabled)
460 {
461   mImpl->mModel->mElideEnabled = enabled;
462   mImpl->mModel->mVisualModel->SetTextElideEnabled(enabled);
463 }
464
465 bool Controller::IsTextElideEnabled() const
466 {
467   return mImpl->mModel->mElideEnabled;
468 }
469
470 void Controller::SetTextFitEnabled(bool enabled)
471 {
472   mImpl->mTextFitEnabled = enabled;
473 }
474
475 bool Controller::IsTextFitEnabled() const
476 {
477   return mImpl->mTextFitEnabled;
478 }
479
480 void Controller::SetTextFitMinSize(float minSize, FontSizeType type)
481 {
482   switch(type)
483   {
484     case POINT_SIZE:
485     {
486       mImpl->mTextFitMinSize = minSize;
487       break;
488     }
489     case PIXEL_SIZE:
490     {
491       mImpl->mTextFitMinSize = ConvertPixelToPint(minSize);
492       break;
493     }
494   }
495 }
496
497 float Controller::GetTextFitMinSize() const
498 {
499   return mImpl->mTextFitMinSize;
500 }
501
502 void Controller::SetTextFitMaxSize(float maxSize, FontSizeType type)
503 {
504   switch(type)
505   {
506     case POINT_SIZE:
507     {
508       mImpl->mTextFitMaxSize = maxSize;
509       break;
510     }
511     case PIXEL_SIZE:
512     {
513       mImpl->mTextFitMaxSize = ConvertPixelToPint(maxSize);
514       break;
515     }
516   }
517 }
518
519 float Controller::GetTextFitMaxSize() const
520 {
521   return mImpl->mTextFitMaxSize;
522 }
523
524 void Controller::SetTextFitStepSize(float step, FontSizeType type)
525 {
526   switch(type)
527   {
528     case POINT_SIZE:
529     {
530       mImpl->mTextFitStepSize = step;
531       break;
532     }
533     case PIXEL_SIZE:
534     {
535       mImpl->mTextFitStepSize = ConvertPixelToPint(step);
536       break;
537     }
538   }
539 }
540
541 float Controller::GetTextFitStepSize() const
542 {
543   return mImpl->mTextFitStepSize;
544 }
545
546 void Controller::SetTextFitContentSize(Vector2 size)
547 {
548   mImpl->mTextFitContentSize = size;
549 }
550
551 Vector2 Controller::GetTextFitContentSize() const
552 {
553   return mImpl->mTextFitContentSize;
554 }
555
556 void Controller::SetPlaceholderTextElideEnabled(bool enabled)
557 {
558   PlaceholderHandler::SetPlaceholderTextElideEnabled(*this, enabled);
559 }
560
561 bool Controller::IsPlaceholderTextElideEnabled() const
562 {
563   return PlaceholderHandler::IsPlaceholderTextElideEnabled(*this);
564 }
565
566 void Controller::SetSelectionEnabled(bool enabled)
567 {
568   mImpl->mEventData->mSelectionEnabled = enabled;
569 }
570
571 bool Controller::IsSelectionEnabled() const
572 {
573   return mImpl->mEventData->mSelectionEnabled;
574 }
575
576 void Controller::SetShiftSelectionEnabled(bool enabled)
577 {
578   mImpl->mEventData->mShiftSelectionFlag = enabled;
579 }
580
581 bool Controller::IsShiftSelectionEnabled() const
582 {
583   return mImpl->mEventData->mShiftSelectionFlag;
584 }
585
586 void Controller::SetGrabHandleEnabled(bool enabled)
587 {
588   mImpl->mEventData->mGrabHandleEnabled = enabled;
589 }
590
591 bool Controller::IsGrabHandleEnabled() const
592 {
593   return mImpl->mEventData->mGrabHandleEnabled;
594 }
595
596 void Controller::SetGrabHandlePopupEnabled(bool enabled)
597 {
598   mImpl->mEventData->mGrabHandlePopupEnabled = enabled;
599 }
600
601 bool Controller::IsGrabHandlePopupEnabled() const
602 {
603   return mImpl->mEventData->mGrabHandlePopupEnabled;
604 }
605
606 // public : Update
607
608 void Controller::SetText(const std::string& text)
609 {
610   TextUpdater::SetText(*this, text);
611 }
612
613 void Controller::GetText(std::string& text) const
614 {
615   if(!mImpl->IsShowingPlaceholderText())
616   {
617     // Retrieves the text string.
618     mImpl->GetText(0u, text);
619   }
620   else
621   {
622     DALI_LOG_INFO(gLogFilter, Debug::Verbose, "Controller::GetText %p empty (but showing placeholder)\n", this);
623   }
624 }
625
626 void Controller::SetPlaceholderText(PlaceholderType type, const std::string& text)
627 {
628   PlaceholderHandler::SetPlaceholderText(*this, type, text);
629 }
630
631 void Controller::GetPlaceholderText(PlaceholderType type, std::string& text) const
632 {
633   PlaceholderHandler::GetPlaceholderText(*this, type, text);
634 }
635
636 void Controller::UpdateAfterFontChange(const std::string& newDefaultFont)
637 {
638   DALI_LOG_INFO(gLogFilter, Debug::Verbose, "Controller::UpdateAfterFontChange\n");
639
640   if(!mImpl->mFontDefaults->familyDefined) // If user defined font then should not update when system font changes
641   {
642     DALI_LOG_INFO(gLogFilter, Debug::Concise, "Controller::UpdateAfterFontChange newDefaultFont(%s)\n", newDefaultFont.c_str());
643     mImpl->mFontDefaults->mFontDescription.family = newDefaultFont;
644
645     ClearFontData();
646
647     mImpl->RequestRelayout();
648   }
649 }
650
651 void Controller::RetrieveSelection(std::string& selectedText) const
652 {
653   mImpl->RetrieveSelection(selectedText, false);
654 }
655
656 void Controller::SetSelection(int start, int end)
657 {
658   mImpl->SetSelection(start, end);
659 }
660
661 std::pair<int, int> Controller::GetSelectionIndexes() const
662 {
663   return mImpl->GetSelectionIndexes();
664 }
665
666 void Controller::CopyStringToClipboard(const std::string& source)
667 {
668   mImpl->CopyStringToClipboard(source);
669 }
670
671 void Controller::SendSelectionToClipboard(bool deleteAfterSending)
672 {
673   mImpl->SendSelectionToClipboard(deleteAfterSending);
674 }
675
676 // public : Default style & Input style
677
678 void Controller::SetDefaultFontFamily(const std::string& defaultFontFamily)
679 {
680   if(NULL == mImpl->mFontDefaults)
681   {
682     mImpl->mFontDefaults = new FontDefaults();
683   }
684
685   mImpl->mFontDefaults->mFontDescription.family = defaultFontFamily;
686   DALI_LOG_INFO(gLogFilter, Debug::General, "Controller::SetDefaultFontFamily %s\n", defaultFontFamily.c_str());
687   mImpl->mFontDefaults->familyDefined = !defaultFontFamily.empty();
688
689   if(mImpl->mEventData)
690   {
691     // Update the cursor position if it's in editing mode
692     if(EventData::IsEditingState(mImpl->mEventData->mState))
693     {
694       mImpl->mEventData->mDecoratorUpdated     = true;
695       mImpl->mEventData->mUpdateCursorPosition = true; // Cursor position should be updated when the font family is updated.
696     }
697   }
698
699   // Clear the font-specific data
700   ClearFontData();
701
702   mImpl->RequestRelayout();
703 }
704
705 const std::string& Controller::GetDefaultFontFamily() const
706 {
707   if(NULL != mImpl->mFontDefaults)
708   {
709     return mImpl->mFontDefaults->mFontDescription.family;
710   }
711
712   return EMPTY_STRING;
713 }
714
715 void Controller::SetPlaceholderFontFamily(const std::string& placeholderTextFontFamily)
716 {
717   PlaceholderHandler::SetPlaceholderFontFamily(*this, placeholderTextFontFamily);
718 }
719
720 const std::string& Controller::GetPlaceholderFontFamily() const
721 {
722   return PlaceholderHandler::GetPlaceholderFontFamily(*this);
723 }
724
725 void Controller::SetDefaultFontWeight(FontWeight weight)
726 {
727   if(NULL == mImpl->mFontDefaults)
728   {
729     mImpl->mFontDefaults = new FontDefaults();
730   }
731
732   mImpl->mFontDefaults->mFontDescription.weight = weight;
733   mImpl->mFontDefaults->weightDefined           = true;
734
735   if(mImpl->mEventData)
736   {
737     // Update the cursor position if it's in editing mode
738     if(EventData::IsEditingState(mImpl->mEventData->mState))
739     {
740       mImpl->mEventData->mDecoratorUpdated     = true;
741       mImpl->mEventData->mUpdateCursorPosition = true; // Cursor position should be updated when the font weight is updated.
742     }
743   }
744
745   // Clear the font-specific data
746   ClearFontData();
747
748   mImpl->RequestRelayout();
749 }
750
751 bool Controller::IsDefaultFontWeightDefined() const
752 {
753   if(NULL != mImpl->mFontDefaults)
754   {
755     return mImpl->mFontDefaults->weightDefined;
756   }
757
758   return false;
759 }
760
761 FontWeight Controller::GetDefaultFontWeight() const
762 {
763   if(NULL != mImpl->mFontDefaults)
764   {
765     return mImpl->mFontDefaults->mFontDescription.weight;
766   }
767
768   return TextAbstraction::FontWeight::NORMAL;
769 }
770
771 void Controller::SetPlaceholderTextFontWeight(FontWeight weight)
772 {
773   PlaceholderHandler::SetPlaceholderTextFontWeight(*this, weight);
774 }
775
776 bool Controller::IsPlaceholderTextFontWeightDefined() const
777 {
778   return PlaceholderHandler::IsPlaceholderTextFontWeightDefined(*this);
779   ;
780 }
781
782 FontWeight Controller::GetPlaceholderTextFontWeight() const
783 {
784   return PlaceholderHandler::GetPlaceholderTextFontWeight(*this);
785 }
786
787 void Controller::SetDefaultFontWidth(FontWidth width)
788 {
789   if(NULL == mImpl->mFontDefaults)
790   {
791     mImpl->mFontDefaults = new FontDefaults();
792   }
793
794   mImpl->mFontDefaults->mFontDescription.width = width;
795   mImpl->mFontDefaults->widthDefined           = true;
796
797   if(mImpl->mEventData)
798   {
799     // Update the cursor position if it's in editing mode
800     if(EventData::IsEditingState(mImpl->mEventData->mState))
801     {
802       mImpl->mEventData->mDecoratorUpdated     = true;
803       mImpl->mEventData->mUpdateCursorPosition = true; // Cursor position should be updated when the font width is updated.
804     }
805   }
806
807   // Clear the font-specific data
808   ClearFontData();
809
810   mImpl->RequestRelayout();
811 }
812
813 bool Controller::IsDefaultFontWidthDefined() const
814 {
815   if(NULL != mImpl->mFontDefaults)
816   {
817     return mImpl->mFontDefaults->widthDefined;
818   }
819
820   return false;
821 }
822
823 FontWidth Controller::GetDefaultFontWidth() const
824 {
825   if(NULL != mImpl->mFontDefaults)
826   {
827     return mImpl->mFontDefaults->mFontDescription.width;
828   }
829
830   return TextAbstraction::FontWidth::NORMAL;
831 }
832
833 void Controller::SetPlaceholderTextFontWidth(FontWidth width)
834 {
835   PlaceholderHandler::SetPlaceholderTextFontWidth(*this, width);
836 }
837
838 bool Controller::IsPlaceholderTextFontWidthDefined() const
839 {
840   return PlaceholderHandler::IsPlaceholderTextFontWidthDefined(*this);
841 }
842
843 FontWidth Controller::GetPlaceholderTextFontWidth() const
844 {
845   return PlaceholderHandler::GetPlaceholderTextFontWidth(*this);
846 }
847
848 void Controller::SetDefaultFontSlant(FontSlant slant)
849 {
850   if(NULL == mImpl->mFontDefaults)
851   {
852     mImpl->mFontDefaults = new FontDefaults();
853   }
854
855   mImpl->mFontDefaults->mFontDescription.slant = slant;
856   mImpl->mFontDefaults->slantDefined           = true;
857
858   if(mImpl->mEventData)
859   {
860     // Update the cursor position if it's in editing mode
861     if(EventData::IsEditingState(mImpl->mEventData->mState))
862     {
863       mImpl->mEventData->mDecoratorUpdated     = true;
864       mImpl->mEventData->mUpdateCursorPosition = true; // Cursor position should be updated when the font slant is updated.
865     }
866   }
867
868   // Clear the font-specific data
869   ClearFontData();
870
871   mImpl->RequestRelayout();
872 }
873
874 bool Controller::IsDefaultFontSlantDefined() const
875 {
876   if(NULL != mImpl->mFontDefaults)
877   {
878     return mImpl->mFontDefaults->slantDefined;
879   }
880   return false;
881 }
882
883 FontSlant Controller::GetDefaultFontSlant() const
884 {
885   if(NULL != mImpl->mFontDefaults)
886   {
887     return mImpl->mFontDefaults->mFontDescription.slant;
888   }
889
890   return TextAbstraction::FontSlant::NORMAL;
891 }
892
893 void Controller::SetPlaceholderTextFontSlant(FontSlant slant)
894 {
895   PlaceholderHandler::SetPlaceholderTextFontSlant(*this, slant);
896 }
897
898 bool Controller::IsPlaceholderTextFontSlantDefined() const
899 {
900   return PlaceholderHandler::IsPlaceholderTextFontSlantDefined(*this);
901 }
902
903 FontSlant Controller::GetPlaceholderTextFontSlant() const
904 {
905   return PlaceholderHandler::GetPlaceholderTextFontSlant(*this);
906 }
907
908 void Controller::SetFontSizeScale(float scale)
909 {
910   mImpl->mFontSizeScale = scale;
911
912   if(mImpl->mEventData)
913   {
914     // Update the cursor position if it's in editing mode
915     if(EventData::IsEditingState(mImpl->mEventData->mState))
916     {
917       mImpl->mEventData->mDecoratorUpdated     = true;
918       mImpl->mEventData->mUpdateCursorPosition = true; // Cursor position should be updated when the font size is updated.
919     }
920   }
921
922   // Clear the font-specific data
923   ClearFontData();
924
925   mImpl->RequestRelayout();
926 }
927
928 float Controller::GetFontSizeScale() const
929 {
930   if(nullptr != mImpl->mFontDefaults)
931   {
932     return mImpl->mFontSizeScale;
933   }
934
935   return 1.f;
936 }
937
938 void Controller::SetDefaultFontSize(float fontSize, FontSizeType type)
939 {
940   if(NULL == mImpl->mFontDefaults)
941   {
942     mImpl->mFontDefaults = new FontDefaults();
943   }
944
945   switch(type)
946   {
947     case POINT_SIZE:
948     {
949       mImpl->mFontDefaults->mDefaultPointSize = fontSize;
950       mImpl->mFontDefaults->sizeDefined       = true;
951       break;
952     }
953     case PIXEL_SIZE:
954     {
955       // Point size = Pixel size * 72.f / DPI
956       unsigned int                horizontalDpi = 0u;
957       unsigned int                verticalDpi   = 0u;
958       TextAbstraction::FontClient fontClient    = TextAbstraction::FontClient::Get();
959       fontClient.GetDpi(horizontalDpi, verticalDpi);
960
961       mImpl->mFontDefaults->mDefaultPointSize = (fontSize * 72.f) / static_cast<float>(horizontalDpi);
962       mImpl->mFontDefaults->sizeDefined       = true;
963       break;
964     }
965   }
966
967   if(mImpl->mEventData)
968   {
969     // Update the cursor position if it's in editing mode
970     if(EventData::IsEditingState(mImpl->mEventData->mState))
971     {
972       mImpl->mEventData->mDecoratorUpdated     = true;
973       mImpl->mEventData->mUpdateCursorPosition = true; // Cursor position should be updated when the font size is updated.
974     }
975   }
976
977   // Clear the font-specific data
978   ClearFontData();
979
980   mImpl->RequestRelayout();
981 }
982
983 float Controller::GetDefaultFontSize(FontSizeType type) const
984 {
985   float value = 0.0f;
986   if(NULL != mImpl->mFontDefaults)
987   {
988     switch(type)
989     {
990       case POINT_SIZE:
991       {
992         value = mImpl->mFontDefaults->mDefaultPointSize;
993         break;
994       }
995       case PIXEL_SIZE:
996       {
997         // Pixel size = Point size * DPI / 72.f
998         unsigned int                horizontalDpi = 0u;
999         unsigned int                verticalDpi   = 0u;
1000         TextAbstraction::FontClient fontClient    = TextAbstraction::FontClient::Get();
1001         fontClient.GetDpi(horizontalDpi, verticalDpi);
1002
1003         value = mImpl->mFontDefaults->mDefaultPointSize * static_cast<float>(horizontalDpi) / 72.f;
1004         break;
1005       }
1006     }
1007     return value;
1008   }
1009
1010   return value;
1011 }
1012
1013 void Controller::SetPlaceholderTextFontSize(float fontSize, FontSizeType type)
1014 {
1015   PlaceholderHandler::SetPlaceholderTextFontSize(*this, fontSize, type);
1016 }
1017
1018 float Controller::GetPlaceholderTextFontSize(FontSizeType type) const
1019 {
1020   return PlaceholderHandler::GetPlaceholderTextFontSize(*this, type);
1021 }
1022
1023 void Controller::SetDefaultColor(const Vector4& color)
1024 {
1025   mImpl->mTextColor = color;
1026
1027   if(!mImpl->IsShowingPlaceholderText())
1028   {
1029     mImpl->mModel->mVisualModel->SetTextColor(color);
1030
1031     mImpl->mModel->mLogicalModel->mColorRuns.Clear();
1032
1033     mImpl->mOperationsPending = static_cast<OperationsMask>(mImpl->mOperationsPending | COLOR);
1034
1035     mImpl->RequestRelayout();
1036   }
1037 }
1038
1039 const Vector4& Controller::GetDefaultColor() const
1040 {
1041   return mImpl->mTextColor;
1042 }
1043
1044 void Controller::SetPlaceholderTextColor(const Vector4& textColor)
1045 {
1046   PlaceholderHandler::SetPlaceholderTextColor(*this, textColor);
1047 }
1048
1049 const Vector4& Controller::GetPlaceholderTextColor() const
1050 {
1051   return PlaceholderHandler::GetPlaceholderTextColor(*this);
1052 }
1053
1054 void Controller::SetShadowOffset(const Vector2& shadowOffset)
1055 {
1056   mImpl->mModel->mVisualModel->SetShadowOffset(shadowOffset);
1057
1058   mImpl->RequestRelayout();
1059 }
1060
1061 const Vector2& Controller::GetShadowOffset() const
1062 {
1063   return mImpl->mModel->mVisualModel->GetShadowOffset();
1064 }
1065
1066 void Controller::SetShadowColor(const Vector4& shadowColor)
1067 {
1068   mImpl->mModel->mVisualModel->SetShadowColor(shadowColor);
1069
1070   mImpl->RequestRelayout();
1071 }
1072
1073 const Vector4& Controller::GetShadowColor() const
1074 {
1075   return mImpl->mModel->mVisualModel->GetShadowColor();
1076 }
1077
1078 void Controller::SetShadowBlurRadius(const float& shadowBlurRadius)
1079 {
1080   if(fabsf(GetShadowBlurRadius() - shadowBlurRadius) > Math::MACHINE_EPSILON_1)
1081   {
1082     mImpl->mModel->mVisualModel->SetShadowBlurRadius(shadowBlurRadius);
1083
1084     mImpl->RequestRelayout();
1085   }
1086 }
1087
1088 const float& Controller::GetShadowBlurRadius() const
1089 {
1090   return mImpl->mModel->mVisualModel->GetShadowBlurRadius();
1091 }
1092
1093 void Controller::SetUnderlineColor(const Vector4& color)
1094 {
1095   mImpl->mModel->mVisualModel->SetUnderlineColor(color);
1096
1097   mImpl->RequestRelayout();
1098 }
1099
1100 const Vector4& Controller::GetUnderlineColor() const
1101 {
1102   return mImpl->mModel->mVisualModel->GetUnderlineColor();
1103 }
1104
1105 void Controller::SetUnderlineEnabled(bool enabled)
1106 {
1107   mImpl->mModel->mVisualModel->SetUnderlineEnabled(enabled);
1108
1109   mImpl->RequestRelayout();
1110 }
1111
1112 bool Controller::IsUnderlineEnabled() const
1113 {
1114   return mImpl->mModel->mVisualModel->IsUnderlineEnabled();
1115 }
1116
1117 void Controller::SetUnderlineHeight(float height)
1118 {
1119   mImpl->mModel->mVisualModel->SetUnderlineHeight(height);
1120
1121   mImpl->RequestRelayout();
1122 }
1123
1124 float Controller::GetUnderlineHeight() const
1125 {
1126   return mImpl->mModel->mVisualModel->GetUnderlineHeight();
1127 }
1128
1129 void Controller::SetOutlineColor(const Vector4& color)
1130 {
1131   mImpl->mModel->mVisualModel->SetOutlineColor(color);
1132
1133   mImpl->RequestRelayout();
1134 }
1135
1136 const Vector4& Controller::GetOutlineColor() const
1137 {
1138   return mImpl->mModel->mVisualModel->GetOutlineColor();
1139 }
1140
1141 void Controller::SetOutlineWidth(uint16_t width)
1142 {
1143   mImpl->mModel->mVisualModel->SetOutlineWidth(width);
1144
1145   mImpl->RequestRelayout();
1146 }
1147
1148 uint16_t Controller::GetOutlineWidth() const
1149 {
1150   return mImpl->mModel->mVisualModel->GetOutlineWidth();
1151 }
1152
1153 void Controller::SetBackgroundColor(const Vector4& color)
1154 {
1155   mImpl->mModel->mVisualModel->SetBackgroundColor(color);
1156
1157   mImpl->RequestRelayout();
1158 }
1159
1160 const Vector4& Controller::GetBackgroundColor() const
1161 {
1162   return mImpl->mModel->mVisualModel->GetBackgroundColor();
1163 }
1164
1165 void Controller::SetBackgroundEnabled(bool enabled)
1166 {
1167   mImpl->mModel->mVisualModel->SetBackgroundEnabled(enabled);
1168
1169   mImpl->RequestRelayout();
1170 }
1171
1172 bool Controller::IsBackgroundEnabled() const
1173 {
1174   return mImpl->mModel->mVisualModel->IsBackgroundEnabled();
1175 }
1176
1177 void Controller::SetDefaultEmbossProperties(const std::string& embossProperties)
1178 {
1179   if(NULL == mImpl->mEmbossDefaults)
1180   {
1181     mImpl->mEmbossDefaults = new EmbossDefaults();
1182   }
1183
1184   mImpl->mEmbossDefaults->properties = embossProperties;
1185 }
1186
1187 const std::string& Controller::GetDefaultEmbossProperties() const
1188 {
1189   if(NULL != mImpl->mEmbossDefaults)
1190   {
1191     return mImpl->mEmbossDefaults->properties;
1192   }
1193
1194   return EMPTY_STRING;
1195 }
1196
1197 void Controller::SetDefaultOutlineProperties(const std::string& outlineProperties)
1198 {
1199   if(NULL == mImpl->mOutlineDefaults)
1200   {
1201     mImpl->mOutlineDefaults = new OutlineDefaults();
1202   }
1203
1204   mImpl->mOutlineDefaults->properties = outlineProperties;
1205 }
1206
1207 const std::string& Controller::GetDefaultOutlineProperties() const
1208 {
1209   if(NULL != mImpl->mOutlineDefaults)
1210   {
1211     return mImpl->mOutlineDefaults->properties;
1212   }
1213
1214   return EMPTY_STRING;
1215 }
1216
1217 bool Controller::SetDefaultLineSpacing(float lineSpacing)
1218 {
1219   if(std::fabs(lineSpacing - mImpl->mLayoutEngine.GetDefaultLineSpacing()) > Math::MACHINE_EPSILON_1000)
1220   {
1221     mImpl->mLayoutEngine.SetDefaultLineSpacing(lineSpacing);
1222     mImpl->mRecalculateNaturalSize = true;
1223     return true;
1224   }
1225   return false;
1226 }
1227
1228 float Controller::GetDefaultLineSpacing() const
1229 {
1230   return mImpl->mLayoutEngine.GetDefaultLineSpacing();
1231 }
1232
1233 bool Controller::SetDefaultLineSize(float lineSize)
1234 {
1235   if(std::fabs(lineSize - mImpl->mLayoutEngine.GetDefaultLineSize()) > Math::MACHINE_EPSILON_1000)
1236   {
1237     mImpl->mLayoutEngine.SetDefaultLineSize(lineSize);
1238     mImpl->mRecalculateNaturalSize = true;
1239     return true;
1240   }
1241   return false;
1242 }
1243
1244 float Controller::GetDefaultLineSize() const
1245 {
1246   return mImpl->mLayoutEngine.GetDefaultLineSize();
1247 }
1248
1249 void Controller::SetInputColor(const Vector4& color)
1250 {
1251   if(NULL != mImpl->mEventData)
1252   {
1253     mImpl->mEventData->mInputStyle.textColor      = color;
1254     mImpl->mEventData->mInputStyle.isDefaultColor = false;
1255
1256     if(EventData::SELECTING == mImpl->mEventData->mState || EventData::EDITING == mImpl->mEventData->mState || EventData::INACTIVE == mImpl->mEventData->mState)
1257     {
1258       if(EventData::SELECTING == mImpl->mEventData->mState)
1259       {
1260         const bool handlesCrossed = mImpl->mEventData->mLeftSelectionPosition > mImpl->mEventData->mRightSelectionPosition;
1261
1262         // Get start and end position of selection
1263         const CharacterIndex startOfSelectedText  = handlesCrossed ? mImpl->mEventData->mRightSelectionPosition : mImpl->mEventData->mLeftSelectionPosition;
1264         const Length         lengthOfSelectedText = (handlesCrossed ? mImpl->mEventData->mLeftSelectionPosition : mImpl->mEventData->mRightSelectionPosition) - startOfSelectedText;
1265
1266         // Add the color run.
1267         const VectorBase::SizeType numberOfRuns = mImpl->mModel->mLogicalModel->mColorRuns.Count();
1268         mImpl->mModel->mLogicalModel->mColorRuns.Resize(numberOfRuns + 1u);
1269
1270         ColorRun& colorRun                       = *(mImpl->mModel->mLogicalModel->mColorRuns.Begin() + numberOfRuns);
1271         colorRun.color                           = color;
1272         colorRun.characterRun.characterIndex     = startOfSelectedText;
1273         colorRun.characterRun.numberOfCharacters = lengthOfSelectedText;
1274
1275         mImpl->mTextUpdateInfo.mCharacterIndex             = startOfSelectedText;
1276         mImpl->mTextUpdateInfo.mNumberOfCharactersToRemove = lengthOfSelectedText;
1277         mImpl->mTextUpdateInfo.mNumberOfCharactersToAdd    = lengthOfSelectedText;
1278       }
1279       else
1280       {
1281         mImpl->mTextUpdateInfo.mCharacterIndex             = 0;
1282         mImpl->mTextUpdateInfo.mNumberOfCharactersToRemove = mImpl->mTextUpdateInfo.mPreviousNumberOfCharacters;
1283         mImpl->mTextUpdateInfo.mNumberOfCharactersToAdd    = mImpl->mModel->mLogicalModel->mText.Count();
1284       }
1285
1286       // Request to relayout.
1287       mImpl->mOperationsPending = static_cast<OperationsMask>(mImpl->mOperationsPending | COLOR);
1288       mImpl->RequestRelayout();
1289     }
1290   }
1291 }
1292
1293 const Vector4& Controller::GetInputColor() const
1294 {
1295   if(NULL != mImpl->mEventData)
1296   {
1297     return mImpl->mEventData->mInputStyle.textColor;
1298   }
1299
1300   // Return the default text's color if there is no EventData.
1301   return mImpl->mTextColor;
1302 }
1303
1304 void Controller::SetInputFontFamily(const std::string& fontFamily)
1305 {
1306   InputFontHandler::SetInputFontFamily(*this, fontFamily);
1307 }
1308
1309 const std::string& Controller::GetInputFontFamily() const
1310 {
1311   return InputFontHandler::GetInputFontFamily(*this);
1312 }
1313
1314 void Controller::SetInputFontWeight(FontWeight weight)
1315 {
1316   InputFontHandler::SetInputFontWeight(*this, weight);
1317 }
1318
1319 bool Controller::IsInputFontWeightDefined() const
1320 {
1321   return InputFontHandler::IsInputFontWeightDefined(*this);
1322 }
1323
1324 FontWeight Controller::GetInputFontWeight() const
1325 {
1326   return InputFontHandler::GetInputFontWeight(*this);
1327 }
1328
1329 void Controller::SetInputFontWidth(FontWidth width)
1330 {
1331   InputFontHandler::SetInputFontWidth(*this, width);
1332 }
1333
1334 bool Controller::IsInputFontWidthDefined() const
1335 {
1336   return InputFontHandler::IsInputFontWidthDefined(*this);
1337 }
1338
1339 FontWidth Controller::GetInputFontWidth() const
1340 {
1341   return InputFontHandler::GetInputFontWidth(*this);
1342 }
1343
1344 void Controller::SetInputFontSlant(FontSlant slant)
1345 {
1346   InputFontHandler::SetInputFontSlant(*this, slant);
1347 }
1348
1349 bool Controller::IsInputFontSlantDefined() const
1350 {
1351   return InputFontHandler::IsInputFontSlantDefined(*this);
1352 }
1353
1354 FontSlant Controller::GetInputFontSlant() const
1355 {
1356   return InputFontHandler::GetInputFontSlant(*this);
1357 }
1358
1359 void Controller::SetInputFontPointSize(float size)
1360 {
1361   InputFontHandler::SetInputFontPointSize(*this, size);
1362 }
1363
1364 float Controller::GetInputFontPointSize() const
1365 {
1366   return InputFontHandler::GetInputFontPointSize(*this);
1367 }
1368
1369 void Controller::SetInputLineSpacing(float lineSpacing)
1370 {
1371   if(NULL != mImpl->mEventData)
1372   {
1373     mImpl->mEventData->mInputStyle.lineSpacing          = lineSpacing;
1374     mImpl->mEventData->mInputStyle.isLineSpacingDefined = true;
1375   }
1376 }
1377
1378 float Controller::GetInputLineSpacing() const
1379 {
1380   if(NULL != mImpl->mEventData)
1381   {
1382     return mImpl->mEventData->mInputStyle.lineSpacing;
1383   }
1384
1385   return 0.f;
1386 }
1387
1388 void Controller::SetInputShadowProperties(const std::string& shadowProperties)
1389 {
1390   if(NULL != mImpl->mEventData)
1391   {
1392     mImpl->mEventData->mInputStyle.shadowProperties = shadowProperties;
1393   }
1394 }
1395
1396 const std::string& Controller::GetInputShadowProperties() const
1397 {
1398   if(NULL != mImpl->mEventData)
1399   {
1400     return mImpl->mEventData->mInputStyle.shadowProperties;
1401   }
1402
1403   return EMPTY_STRING;
1404 }
1405
1406 void Controller::SetInputUnderlineProperties(const std::string& underlineProperties)
1407 {
1408   if(NULL != mImpl->mEventData)
1409   {
1410     mImpl->mEventData->mInputStyle.underlineProperties = underlineProperties;
1411   }
1412 }
1413
1414 const std::string& Controller::GetInputUnderlineProperties() const
1415 {
1416   if(NULL != mImpl->mEventData)
1417   {
1418     return mImpl->mEventData->mInputStyle.underlineProperties;
1419   }
1420
1421   return EMPTY_STRING;
1422 }
1423
1424 void Controller::SetInputEmbossProperties(const std::string& embossProperties)
1425 {
1426   if(NULL != mImpl->mEventData)
1427   {
1428     mImpl->mEventData->mInputStyle.embossProperties = embossProperties;
1429   }
1430 }
1431
1432 const std::string& Controller::GetInputEmbossProperties() const
1433 {
1434   if(NULL != mImpl->mEventData)
1435   {
1436     return mImpl->mEventData->mInputStyle.embossProperties;
1437   }
1438
1439   return GetDefaultEmbossProperties();
1440 }
1441
1442 void Controller::SetInputOutlineProperties(const std::string& outlineProperties)
1443 {
1444   if(NULL != mImpl->mEventData)
1445   {
1446     mImpl->mEventData->mInputStyle.outlineProperties = outlineProperties;
1447   }
1448 }
1449
1450 const std::string& Controller::GetInputOutlineProperties() const
1451 {
1452   if(NULL != mImpl->mEventData)
1453   {
1454     return mImpl->mEventData->mInputStyle.outlineProperties;
1455   }
1456
1457   return GetDefaultOutlineProperties();
1458 }
1459
1460 void Controller::SetInputModePassword(bool passwordInput)
1461 {
1462   if(NULL != mImpl->mEventData)
1463   {
1464     mImpl->mEventData->mPasswordInput = passwordInput;
1465   }
1466 }
1467
1468 bool Controller::IsInputModePassword()
1469 {
1470   if(NULL != mImpl->mEventData)
1471   {
1472     return mImpl->mEventData->mPasswordInput;
1473   }
1474   return false;
1475 }
1476
1477 void Controller::SetNoTextDoubleTapAction(NoTextTap::Action action)
1478 {
1479   if(NULL != mImpl->mEventData)
1480   {
1481     mImpl->mEventData->mDoubleTapAction = action;
1482   }
1483 }
1484
1485 Controller::NoTextTap::Action Controller::GetNoTextDoubleTapAction() const
1486 {
1487   NoTextTap::Action action = NoTextTap::NO_ACTION;
1488
1489   if(NULL != mImpl->mEventData)
1490   {
1491     action = mImpl->mEventData->mDoubleTapAction;
1492   }
1493
1494   return action;
1495 }
1496
1497 void Controller::SetNoTextLongPressAction(NoTextTap::Action action)
1498 {
1499   if(NULL != mImpl->mEventData)
1500   {
1501     mImpl->mEventData->mLongPressAction = action;
1502   }
1503 }
1504
1505 Controller::NoTextTap::Action Controller::GetNoTextLongPressAction() const
1506 {
1507   NoTextTap::Action action = NoTextTap::NO_ACTION;
1508
1509   if(NULL != mImpl->mEventData)
1510   {
1511     action = mImpl->mEventData->mLongPressAction;
1512   }
1513
1514   return action;
1515 }
1516
1517 bool Controller::IsUnderlineSetByString()
1518 {
1519   return mImpl->mUnderlineSetByString;
1520 }
1521
1522 void Controller::UnderlineSetByString(bool setByString)
1523 {
1524   mImpl->mUnderlineSetByString = setByString;
1525 }
1526
1527 bool Controller::IsShadowSetByString()
1528 {
1529   return mImpl->mShadowSetByString;
1530 }
1531
1532 void Controller::ShadowSetByString(bool setByString)
1533 {
1534   mImpl->mShadowSetByString = setByString;
1535 }
1536
1537 bool Controller::IsOutlineSetByString()
1538 {
1539   return mImpl->mOutlineSetByString;
1540 }
1541
1542 void Controller::OutlineSetByString(bool setByString)
1543 {
1544   mImpl->mOutlineSetByString = setByString;
1545 }
1546
1547 bool Controller::IsFontStyleSetByString()
1548 {
1549   return mImpl->mFontStyleSetByString;
1550 }
1551
1552 void Controller::FontStyleSetByString(bool setByString)
1553 {
1554   mImpl->mFontStyleSetByString = setByString;
1555 }
1556
1557 // public : Queries & retrieves.
1558
1559 Layout::Engine& Controller::GetLayoutEngine()
1560 {
1561   return mImpl->mLayoutEngine;
1562 }
1563
1564 View& Controller::GetView()
1565 {
1566   return mImpl->mView;
1567 }
1568
1569 Vector3 Controller::GetNaturalSize()
1570 {
1571   return Relayouter::GetNaturalSize(*this);
1572 }
1573
1574 bool Controller::CheckForTextFit(float pointSize, Size& layoutSize)
1575 {
1576   return Relayouter::CheckForTextFit(*this, pointSize, layoutSize);
1577 }
1578
1579 void Controller::FitPointSizeforLayout(Size layoutSize)
1580 {
1581   Relayouter::FitPointSizeforLayout(*this, layoutSize);
1582 }
1583
1584 float Controller::GetHeightForWidth(float width)
1585 {
1586   return Relayouter::GetHeightForWidth(*this, width);
1587 }
1588
1589 int Controller::GetLineCount(float width)
1590 {
1591   GetHeightForWidth(width);
1592   int numberofLines = mImpl->mModel->GetNumberOfLines();
1593   return numberofLines;
1594 }
1595
1596 const ModelInterface* const Controller::GetTextModel() const
1597 {
1598   return mImpl->mModel.Get();
1599 }
1600
1601 float Controller::GetScrollAmountByUserInput()
1602 {
1603   float scrollAmount = 0.0f;
1604
1605   if(NULL != mImpl->mEventData && mImpl->mEventData->mCheckScrollAmount)
1606   {
1607     scrollAmount                          = mImpl->mModel->mScrollPosition.y - mImpl->mModel->mScrollPositionLast.y;
1608     mImpl->mEventData->mCheckScrollAmount = false;
1609   }
1610   return scrollAmount;
1611 }
1612
1613 bool Controller::GetTextScrollInfo(float& scrollPosition, float& controlHeight, float& layoutHeight)
1614 {
1615   const Vector2& layout = mImpl->mModel->mVisualModel->GetLayoutSize();
1616   bool           isScrolled;
1617
1618   controlHeight  = mImpl->mModel->mVisualModel->mControlSize.height;
1619   layoutHeight   = layout.height;
1620   scrollPosition = mImpl->mModel->mScrollPosition.y;
1621   isScrolled     = !Equals(mImpl->mModel->mScrollPosition.y, mImpl->mModel->mScrollPositionLast.y, Math::MACHINE_EPSILON_1);
1622   return isScrolled;
1623 }
1624
1625 void Controller::SetHiddenInputOption(const Property::Map& options)
1626 {
1627   if(NULL == mImpl->mHiddenInput)
1628   {
1629     mImpl->mHiddenInput = new HiddenText(this);
1630   }
1631   mImpl->mHiddenInput->SetProperties(options);
1632 }
1633
1634 void Controller::GetHiddenInputOption(Property::Map& options)
1635 {
1636   if(NULL != mImpl->mHiddenInput)
1637   {
1638     mImpl->mHiddenInput->GetProperties(options);
1639   }
1640 }
1641
1642 void Controller::SetInputFilterOption(const Property::Map& options)
1643 {
1644   if(!mImpl->mInputFilter)
1645   {
1646     mImpl->mInputFilter = std::unique_ptr<InputFilter>(new InputFilter());
1647   }
1648   mImpl->mInputFilter->SetProperties(options);
1649 }
1650
1651 void Controller::GetInputFilterOption(Property::Map& options)
1652 {
1653   if(NULL != mImpl->mInputFilter)
1654   {
1655     mImpl->mInputFilter->GetProperties(options);
1656   }
1657 }
1658
1659 void Controller::SetPlaceholderProperty(const Property::Map& map)
1660 {
1661   PlaceholderHandler::SetPlaceholderProperty(*this, map);
1662 }
1663
1664 void Controller::GetPlaceholderProperty(Property::Map& map)
1665 {
1666   PlaceholderHandler::GetPlaceholderProperty(*this, map);
1667 }
1668
1669 Toolkit::DevelText::TextDirection::Type Controller::GetTextDirection()
1670 {
1671   // Make sure the model is up-to-date before layouting
1672   ProcessModifyEvents();
1673
1674   if(mImpl->mUpdateTextDirection)
1675   {
1676     // Operations that can be done only once until the text changes.
1677     const OperationsMask onlyOnceOperations = static_cast<OperationsMask>(CONVERT_TO_UTF32 |
1678                                                                           GET_SCRIPTS |
1679                                                                           VALIDATE_FONTS |
1680                                                                           GET_LINE_BREAKS |
1681                                                                           BIDI_INFO |
1682                                                                           SHAPE_TEXT |
1683                                                                           GET_GLYPH_METRICS);
1684
1685     // Set the update info to relayout the whole text.
1686     mImpl->mTextUpdateInfo.mParagraphCharacterIndex     = 0u;
1687     mImpl->mTextUpdateInfo.mRequestedNumberOfCharacters = mImpl->mModel->mLogicalModel->mText.Count();
1688
1689     // Make sure the model is up-to-date before layouting
1690     mImpl->UpdateModel(onlyOnceOperations);
1691
1692     Vector3 naturalSize;
1693     DoRelayout(Size(MAX_FLOAT, MAX_FLOAT),
1694                static_cast<OperationsMask>(onlyOnceOperations |
1695                                            LAYOUT | REORDER | UPDATE_DIRECTION),
1696                naturalSize.GetVectorXY());
1697
1698     // Do not do again the only once operations.
1699     mImpl->mOperationsPending = static_cast<OperationsMask>(mImpl->mOperationsPending & ~onlyOnceOperations);
1700
1701     // Clear the update info. This info will be set the next time the text is updated.
1702     mImpl->mTextUpdateInfo.Clear();
1703
1704     // FullRelayoutNeeded should be true because DoRelayout is MAX_FLOAT, MAX_FLOAT.
1705     mImpl->mTextUpdateInfo.mFullRelayoutNeeded = true;
1706
1707     mImpl->mUpdateTextDirection = false;
1708   }
1709
1710   return mImpl->mIsTextDirectionRTL ? Toolkit::DevelText::TextDirection::RIGHT_TO_LEFT : Toolkit::DevelText::TextDirection::LEFT_TO_RIGHT;
1711 }
1712
1713 Toolkit::DevelText::VerticalLineAlignment::Type Controller::GetVerticalLineAlignment() const
1714 {
1715   return mImpl->mModel->GetVerticalLineAlignment();
1716 }
1717
1718 void Controller::SetVerticalLineAlignment(Toolkit::DevelText::VerticalLineAlignment::Type alignment)
1719 {
1720   mImpl->mModel->mVerticalLineAlignment = alignment;
1721 }
1722
1723 Toolkit::DevelText::EllipsisPosition::Type Controller::GetEllipsisPosition() const
1724 {
1725   return mImpl->mModel->GetEllipsisPosition();
1726 }
1727
1728 void Controller::SetEllipsisPosition(Toolkit::DevelText::EllipsisPosition::Type ellipsisPosition)
1729 {
1730   mImpl->mModel->mEllipsisPosition = ellipsisPosition;
1731   mImpl->mModel->mVisualModel->SetEllipsisPosition(ellipsisPosition);
1732 }
1733
1734 // public : Relayout.
1735
1736 Controller::UpdateTextType Controller::Relayout(const Size& size, Dali::LayoutDirection::Type layoutDirection)
1737 {
1738   return Relayouter::Relayout(*this, size, layoutDirection);
1739 }
1740
1741 void Controller::RequestRelayout()
1742 {
1743   mImpl->RequestRelayout();
1744 }
1745
1746 // public : Input style change signals.
1747
1748 bool Controller::IsInputStyleChangedSignalsQueueEmpty()
1749 {
1750   return (NULL == mImpl->mEventData) || (0u == mImpl->mEventData->mInputStyleChangedQueue.Count());
1751 }
1752
1753 void Controller::ProcessInputStyleChangedSignals()
1754 {
1755   if(NULL == mImpl->mEventData)
1756   {
1757     // Nothing to do.
1758     return;
1759   }
1760
1761   for(Vector<InputStyle::Mask>::ConstIterator it    = mImpl->mEventData->mInputStyleChangedQueue.Begin(),
1762                                               endIt = mImpl->mEventData->mInputStyleChangedQueue.End();
1763       it != endIt;
1764       ++it)
1765   {
1766     const InputStyle::Mask mask = *it;
1767
1768     if(NULL != mImpl->mEditableControlInterface)
1769     {
1770       // Emit the input style changed signal.
1771       mImpl->mEditableControlInterface->InputStyleChanged(mask);
1772     }
1773   }
1774
1775   mImpl->mEventData->mInputStyleChangedQueue.Clear();
1776 }
1777
1778 // public : Text-input Event Queuing.
1779
1780 void Controller::KeyboardFocusGainEvent()
1781 {
1782   EventHandler::KeyboardFocusGainEvent(*this);
1783 }
1784
1785 void Controller::KeyboardFocusLostEvent()
1786 {
1787   EventHandler::KeyboardFocusLostEvent(*this);
1788 }
1789
1790 bool Controller::KeyEvent(const Dali::KeyEvent& keyEvent)
1791 {
1792   return EventHandler::KeyEvent(*this, keyEvent);
1793 }
1794
1795 void Controller::AnchorEvent(float x, float y)
1796 {
1797   EventHandler::AnchorEvent(*this, x, y);
1798 }
1799
1800 void Controller::TapEvent(unsigned int tapCount, float x, float y)
1801 {
1802   EventHandler::TapEvent(*this, tapCount, x, y);
1803 }
1804
1805 void Controller::PanEvent(GestureState state, const Vector2& displacement)
1806 {
1807   EventHandler::PanEvent(*this, state, displacement);
1808 }
1809
1810 void Controller::LongPressEvent(GestureState state, float x, float y)
1811 {
1812   EventHandler::LongPressEvent(*this, state, x, y);
1813 }
1814
1815 void Controller::SelectEvent(float x, float y, SelectionType selectType)
1816 {
1817   EventHandler::SelectEvent(*this, x, y, selectType);
1818 }
1819
1820 void Controller::SetTextSelectionRange(const uint32_t* start, const uint32_t* end)
1821 {
1822   if(mImpl->mEventData)
1823   {
1824     mImpl->mEventData->mCheckScrollAmount     = true;
1825     mImpl->mEventData->mIsLeftHandleSelected  = true;
1826     mImpl->mEventData->mIsRightHandleSelected = true;
1827     mImpl->SetTextSelectionRange(start, end);
1828     mImpl->RequestRelayout();
1829     KeyboardFocusGainEvent();
1830   }
1831 }
1832
1833 Uint32Pair Controller::GetTextSelectionRange() const
1834 {
1835   return mImpl->GetTextSelectionRange();
1836 }
1837
1838 CharacterIndex Controller::GetPrimaryCursorPosition() const
1839 {
1840   return mImpl->GetPrimaryCursorPosition();
1841 }
1842
1843 bool Controller::SetPrimaryCursorPosition(CharacterIndex index)
1844 {
1845   if(mImpl->mEventData)
1846   {
1847     mImpl->mEventData->mCheckScrollAmount     = true;
1848     mImpl->mEventData->mIsLeftHandleSelected  = true;
1849     mImpl->mEventData->mIsRightHandleSelected = true;
1850     mImpl->mEventData->mCheckScrollAmount     = true;
1851     if(mImpl->SetPrimaryCursorPosition(index))
1852     {
1853       KeyboardFocusGainEvent();
1854       return true;
1855     }
1856   }
1857   return false;
1858 }
1859
1860 void Controller::SelectWholeText()
1861 {
1862   SelectEvent(0.f, 0.f, SelectionType::ALL);
1863 }
1864
1865 void Controller::SelectNone()
1866 {
1867   SelectEvent(0.f, 0.f, SelectionType::NONE);
1868 }
1869
1870 string Controller::GetSelectedText() const
1871 {
1872   string text;
1873   if(EventData::SELECTING == mImpl->mEventData->mState)
1874   {
1875     mImpl->RetrieveSelection(text, false);
1876   }
1877   return text;
1878 }
1879
1880 InputMethodContext::CallbackData Controller::OnInputMethodContextEvent(InputMethodContext& inputMethodContext, const InputMethodContext::EventData& inputMethodContextEvent)
1881 {
1882   return EventHandler::OnInputMethodContextEvent(*this, inputMethodContext, inputMethodContextEvent);
1883 }
1884
1885 void Controller::PasteClipboardItemEvent()
1886 {
1887   EventHandler::PasteClipboardItemEvent(*this);
1888 }
1889
1890 // protected : Inherit from Text::Decorator::ControllerInterface.
1891
1892 void Controller::GetTargetSize(Vector2& targetSize)
1893 {
1894   targetSize = mImpl->mModel->mVisualModel->mControlSize;
1895 }
1896
1897 void Controller::AddDecoration(Actor& actor, bool needsClipping)
1898 {
1899   if(NULL != mImpl->mEditableControlInterface)
1900   {
1901     mImpl->mEditableControlInterface->AddDecoration(actor, needsClipping);
1902   }
1903 }
1904
1905 bool Controller::IsEditable() const
1906 {
1907   return mImpl->IsEditable();
1908 }
1909
1910 void Controller::SetEditable(bool editable)
1911 {
1912   mImpl->SetEditable(editable);
1913   if(mImpl->mEventData && mImpl->mEventData->mDecorator)
1914   {
1915     mImpl->mEventData->mDecorator->SetEditable(editable);
1916   }
1917 }
1918
1919 void Controller::ScrollBy(Vector2 scroll)
1920 {
1921   if(mImpl->mEventData && (fabs(scroll.x) > Math::MACHINE_EPSILON_0 || fabs(scroll.y) > Math::MACHINE_EPSILON_0))
1922   {
1923     const Vector2& layoutSize    = mImpl->mModel->mVisualModel->GetLayoutSize();
1924     const Vector2  currentScroll = mImpl->mModel->mScrollPosition;
1925
1926     scroll.x = -scroll.x;
1927     scroll.y = -scroll.y;
1928
1929     if(fabs(scroll.x) > Math::MACHINE_EPSILON_0)
1930     {
1931       mImpl->mModel->mScrollPosition.x += scroll.x;
1932       mImpl->ClampHorizontalScroll(layoutSize);
1933     }
1934
1935     if(fabs(scroll.y) > Math::MACHINE_EPSILON_0)
1936     {
1937       mImpl->mModel->mScrollPosition.y += scroll.y;
1938       mImpl->ClampVerticalScroll(layoutSize);
1939     }
1940
1941     if(mImpl->mModel->mScrollPosition != currentScroll)
1942     {
1943       mImpl->mEventData->mDecorator->UpdatePositions(mImpl->mModel->mScrollPosition - currentScroll);
1944       mImpl->RequestRelayout();
1945     }
1946   }
1947 }
1948
1949 float Controller::GetHorizontalScrollPosition()
1950 {
1951   if(mImpl->mEventData)
1952   {
1953     //scroll values are negative internally so we convert them to positive numbers
1954     return -mImpl->mModel->mScrollPosition.x;
1955   }
1956   return 0;
1957 }
1958
1959 float Controller::GetVerticalScrollPosition()
1960 {
1961   if(mImpl->mEventData)
1962   {
1963     //scroll values are negative internally so we convert them to positive numbers
1964     return -mImpl->mModel->mScrollPosition.y;
1965   }
1966   return 0;
1967 }
1968
1969 void Controller::DecorationEvent(HandleType handleType, HandleState state, float x, float y)
1970 {
1971   EventHandler::DecorationEvent(*this, handleType, state, x, y);
1972 }
1973
1974 // protected : Inherit from TextSelectionPopup::TextPopupButtonCallbackInterface.
1975
1976 void Controller::TextPopupButtonTouched(Dali::Toolkit::TextSelectionPopup::Buttons button)
1977 {
1978   EventHandler::TextPopupButtonTouched(*this, button);
1979 }
1980
1981 void Controller::DisplayTimeExpired()
1982 {
1983   mImpl->mEventData->mUpdateCursorPosition = true;
1984   // Apply modifications to the model
1985   mImpl->mOperationsPending = ALL_OPERATIONS;
1986
1987   mImpl->RequestRelayout();
1988 }
1989
1990 // private : Update.
1991
1992 void Controller::InsertText(const std::string& text, Controller::InsertType type)
1993 {
1994   TextUpdater::InsertText(*this, text, type);
1995 }
1996
1997 void Controller::PasteText(const std::string& stringToPaste)
1998 {
1999   TextUpdater::PasteText(*this, stringToPaste);
2000 }
2001
2002 bool Controller::RemoveText(int                  cursorOffset,
2003                             int                  numberOfCharacters,
2004                             UpdateInputStyleType type)
2005 {
2006   return TextUpdater::RemoveText(*this, cursorOffset, numberOfCharacters, type);
2007 }
2008
2009 bool Controller::RemoveSelectedText()
2010 {
2011   return TextUpdater::RemoveSelectedText(*this);
2012 }
2013
2014 void Controller::InsertTextAnchor(int            numberOfCharacters,
2015                                   CharacterIndex previousCursorIndex)
2016 {
2017   TextUpdater::InsertTextAnchor(*this, numberOfCharacters, previousCursorIndex);
2018 }
2019
2020 void Controller::RemoveTextAnchor(int            cursorOffset,
2021                                   int            numberOfCharacters,
2022                                   CharacterIndex previousCursorIndex)
2023 {
2024   TextUpdater::RemoveTextAnchor(*this, cursorOffset, numberOfCharacters, previousCursorIndex);
2025 }
2026
2027 // private : Relayout.
2028
2029 bool Controller::DoRelayout(const Size&    size,
2030                             OperationsMask operationsRequired,
2031                             Size&          layoutSize)
2032 {
2033   return Relayouter::DoRelayout(*this, size, operationsRequired, layoutSize);
2034 }
2035
2036 void Controller::CalculateVerticalOffset(const Size& controlSize)
2037 {
2038   Relayouter::CalculateVerticalOffset(*this, controlSize);
2039 }
2040
2041 // private : Events.
2042
2043 void Controller::ProcessModifyEvents()
2044 {
2045   EventHandler::ProcessModifyEvents(*this);
2046 }
2047
2048 void Controller::TextReplacedEvent()
2049 {
2050   EventHandler::TextReplacedEvent(*this);
2051 }
2052
2053 void Controller::TextInsertedEvent()
2054 {
2055   EventHandler::TextInsertedEvent(*this);
2056 }
2057
2058 void Controller::TextDeletedEvent()
2059 {
2060   EventHandler::TextDeletedEvent(*this);
2061 }
2062
2063 bool Controller::DeleteEvent(int keyCode)
2064 {
2065   return EventHandler::DeleteEvent(*this, keyCode);
2066 }
2067
2068 // private : Helpers.
2069
2070 void Controller::ResetText()
2071 {
2072   TextUpdater::ResetText(*this);
2073 }
2074
2075 void Controller::ShowPlaceholderText()
2076 {
2077   PlaceholderHandler::ShowPlaceholderText(*this);
2078 }
2079
2080 void Controller::ClearFontData()
2081 {
2082   if(mImpl->mFontDefaults)
2083   {
2084     mImpl->mFontDefaults->mFontId = 0u; // Remove old font ID
2085   }
2086
2087   // Set flags to update the model.
2088   mImpl->mTextUpdateInfo.mCharacterIndex             = 0u;
2089   mImpl->mTextUpdateInfo.mNumberOfCharactersToRemove = mImpl->mTextUpdateInfo.mPreviousNumberOfCharacters;
2090   mImpl->mTextUpdateInfo.mNumberOfCharactersToAdd    = mImpl->mModel->mLogicalModel->mText.Count();
2091
2092   mImpl->mTextUpdateInfo.mClearAll           = true;
2093   mImpl->mTextUpdateInfo.mFullRelayoutNeeded = true;
2094   mImpl->mRecalculateNaturalSize             = true;
2095
2096   mImpl->mOperationsPending = static_cast<OperationsMask>(mImpl->mOperationsPending |
2097                                                           VALIDATE_FONTS |
2098                                                           SHAPE_TEXT |
2099                                                           BIDI_INFO |
2100                                                           GET_GLYPH_METRICS |
2101                                                           LAYOUT |
2102                                                           UPDATE_LAYOUT_SIZE |
2103                                                           REORDER |
2104                                                           ALIGN);
2105 }
2106
2107 void Controller::ClearStyleData()
2108 {
2109   mImpl->mModel->mLogicalModel->mColorRuns.Clear();
2110   mImpl->mModel->mLogicalModel->ClearFontDescriptionRuns();
2111 }
2112
2113 void Controller::ResetCursorPosition(CharacterIndex cursorIndex)
2114 {
2115   // Reset the cursor position
2116   if(NULL != mImpl->mEventData)
2117   {
2118     mImpl->mEventData->mPrimaryCursorPosition = cursorIndex;
2119
2120     // Update the cursor if it's in editing mode.
2121     if(EventData::IsEditingState(mImpl->mEventData->mState))
2122     {
2123       mImpl->mEventData->mUpdateCursorPosition = true;
2124     }
2125   }
2126 }
2127
2128 CharacterIndex Controller::GetCursorPosition()
2129 {
2130   if(!mImpl->mEventData)
2131     return 0;
2132
2133   return mImpl->mEventData->mPrimaryCursorPosition;
2134 }
2135
2136 void Controller::ResetScrollPosition()
2137 {
2138   if(NULL != mImpl->mEventData)
2139   {
2140     // Reset the scroll position.
2141     mImpl->mModel->mScrollPosition                = Vector2::ZERO;
2142     mImpl->mEventData->mScrollAfterUpdatePosition = true;
2143   }
2144 }
2145
2146 void Controller::SetControlInterface(ControlInterface* controlInterface)
2147 {
2148   mImpl->mControlInterface = controlInterface;
2149 }
2150
2151 void Controller::SetAnchorControlInterface(AnchorControlInterface* anchorControlInterface)
2152 {
2153   mImpl->mAnchorControlInterface = anchorControlInterface;
2154 }
2155
2156 bool Controller::ShouldClearFocusOnEscape() const
2157 {
2158   return mImpl->mShouldClearFocusOnEscape;
2159 }
2160
2161 Actor Controller::CreateBackgroundActor()
2162 {
2163   return mImpl->CreateBackgroundActor();
2164 }
2165
2166 // private : Private contructors & copy operator.
2167
2168 Controller::Controller()
2169 : Controller(nullptr, nullptr, nullptr, nullptr)
2170 {
2171 }
2172
2173 Controller::Controller(ControlInterface* controlInterface)
2174 : Controller(controlInterface, nullptr, nullptr, nullptr)
2175 {
2176 }
2177
2178 Controller::Controller(ControlInterface*           controlInterface,
2179                        EditableControlInterface*   editableControlInterface,
2180                        SelectableControlInterface* selectableControlInterface,
2181                        AnchorControlInterface*     anchorControlInterface)
2182 : mImpl(new Controller::Impl(controlInterface, editableControlInterface, selectableControlInterface, anchorControlInterface))
2183 {
2184 }
2185
2186 // The copy constructor and operator are left unimplemented.
2187
2188 // protected : Destructor.
2189
2190 Controller::~Controller()
2191 {
2192   delete mImpl;
2193 }
2194
2195 } // namespace Text
2196
2197 } // namespace Toolkit
2198
2199 } // namespace Dali