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