Merge "Added pixel format to fix bug with ktx loader" into devel/graphics
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / text / text-controller-impl.h
1 #ifndef DALI_TOOLKIT_TEXT_CONTROLLER_IMPL_H
2 #define DALI_TOOLKIT_TEXT_CONTROLLER_IMPL_H
3
4 /*
5  * Copyright (c) 2021 Samsung Electronics Co., Ltd.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */
20
21 // EXTERNAL INCLUDES
22 #include <dali/devel-api/adaptor-framework/clipboard.h>
23 #include <dali/devel-api/text-abstraction/font-client.h>
24 #include <dali/public-api/rendering/shader.h>
25
26 // INTERNAL INCLUDES
27 #include <dali-toolkit/devel-api/styling/style-manager-devel.h>
28 #include <dali-toolkit/internal/text/input-style.h>
29 #include <dali-toolkit/internal/text/text-controller.h>
30 #include <dali-toolkit/internal/text/text-model.h>
31 #include <dali-toolkit/internal/text/text-view.h>
32 #include <dali-toolkit/public-api/styling/style-manager.h>
33
34 namespace Dali
35 {
36 namespace Toolkit
37 {
38 namespace Text
39 {
40 const float DEFAULT_TEXTFIT_MIN     = 10.f;
41 const float DEFAULT_TEXTFIT_MAX     = 100.f;
42 const float DEFAULT_TEXTFIT_STEP    = 1.f;
43 const float DEFAULT_FONT_SIZE_SCALE = 1.f;
44
45 //Forward declarations
46 struct CursorInfo;
47 struct FontDefaults;
48 struct ControllerImplEventHandler;
49 struct SelectionHandleController;
50
51 class SelectableControlInterface;
52 class AnchorControlInterface;
53
54 struct Event
55 {
56   // Used to queue input events until DoRelayout()
57   enum Type
58   {
59     CURSOR_KEY_EVENT,
60     TAP_EVENT,
61     PAN_EVENT,
62     LONG_PRESS_EVENT,
63     GRAB_HANDLE_EVENT,
64     LEFT_SELECTION_HANDLE_EVENT,
65     RIGHT_SELECTION_HANDLE_EVENT,
66     SELECT,
67     SELECT_ALL,
68     SELECT_NONE,
69   };
70
71   union Param
72   {
73     int          mInt;
74     unsigned int mUint;
75     float        mFloat;
76     bool         mBool;
77   };
78
79   Event(Type eventType)
80   : type(eventType)
81   {
82     p1.mInt = 0;
83     p2.mInt = 0;
84     p3.mInt = 0;
85   }
86
87   Type  type;
88   Param p1;
89   Param p2;
90   Param p3;
91 };
92
93 struct EventData
94 {
95   enum State
96   {
97     INACTIVE,
98     INTERRUPTED,
99     SELECTING,
100     EDITING,
101     EDITING_WITH_POPUP,
102     EDITING_WITH_GRAB_HANDLE,
103     EDITING_WITH_PASTE_POPUP,
104     GRAB_HANDLE_PANNING,
105     SELECTION_HANDLE_PANNING,
106     TEXT_PANNING
107   };
108
109   EventData(DecoratorPtr decorator, InputMethodContext& inputMethodContext);
110
111   ~EventData() = default;
112
113   static bool IsEditingState(State stateToCheck)
114   {
115     return (stateToCheck == EDITING || stateToCheck == EDITING_WITH_POPUP || stateToCheck == EDITING_WITH_GRAB_HANDLE || stateToCheck == EDITING_WITH_PASTE_POPUP);
116   }
117
118   DecoratorPtr       mDecorator;               ///< Pointer to the decorator.
119   InputMethodContext mInputMethodContext;      ///< The Input Method Framework Manager.
120   FontDefaults*      mPlaceholderFont;         ///< The placeholder default font.
121   std::string        mPlaceholderTextActive;   ///< The text to display when the TextField is empty with key-input focus.
122   std::string        mPlaceholderTextInactive; ///< The text to display when the TextField is empty and inactive.
123   Vector4            mPlaceholderTextColor;    ///< The in/active placeholder text color.
124
125   /**
126    * This is used to delay handling events until after the model has been updated.
127    * The number of updates to the model is minimized to improve performance.
128    */
129   std::vector<Event> mEventQueue; ///< The queue of touch events etc.
130
131   Vector<InputStyle::Mask> mInputStyleChangedQueue; ///< Queue of changes in the input style. Used to emit the signal in the iddle callback.
132
133   InputStyle mInputStyle; ///< The style to be set to the new inputed text.
134
135   State mPreviousState; ///< Stores the current state before it's updated with the new one.
136   State mState;         ///< Selection mode, edit mode etc.
137
138   CharacterIndex mPrimaryCursorPosition;  ///< Index into logical model for primary cursor.
139   CharacterIndex mLeftSelectionPosition;  ///< Index into logical model for left selection handle.
140   CharacterIndex mRightSelectionPosition; ///< Index into logical model for right selection handle.
141
142   CharacterIndex mPreEditStartPosition; ///< Used to remove the pre-edit text if necessary.
143   Length         mPreEditLength;        ///< Used to remove the pre-edit text if necessary.
144
145   float mCursorHookPositionX; ///< Used to move the cursor with the keys or when scrolling the text vertically with the handles.
146
147   Controller::NoTextTap::Action mDoubleTapAction; ///< Action to be done when there is a double tap on top of 'no text'
148   Controller::NoTextTap::Action mLongPressAction; ///< Action to be done when there is a long press on top of 'no text'
149
150   bool mIsShowingPlaceholderText : 1;     ///< True if the place-holder text is being displayed.
151   bool mPreEditFlag : 1;                  ///< True if the model contains text in pre-edit state.
152   bool mDecoratorUpdated : 1;             ///< True if the decorator was updated during event processing.
153   bool mCursorBlinkEnabled : 1;           ///< True if cursor should blink when active.
154   bool mGrabHandleEnabled : 1;            ///< True if grab handle is enabled.
155   bool mGrabHandlePopupEnabled : 1;       ///< True if the grab handle popu-up should be shown.
156   bool mSelectionEnabled : 1;             ///< True if selection handles, highlight etc. are enabled.
157   bool mUpdateCursorHookPosition : 1;     ///< True if the cursor hook position must be updated. Used to move the cursor with the keys 'up' and 'down'.
158   bool mUpdateCursorPosition : 1;         ///< True if the visual position of the cursor must be recalculated.
159   bool mUpdateGrabHandlePosition : 1;     ///< True if the visual position of the grab handle must be recalculated.
160   bool mUpdateLeftSelectionPosition : 1;  ///< True if the visual position of the left selection handle must be recalculated.
161   bool mUpdateRightSelectionPosition : 1; ///< True if the visual position of the right selection handle must be recalculated.
162   bool mIsLeftHandleSelected : 1;         ///< Whether is the left handle the one which is selected.
163   bool mIsRightHandleSelected : 1;        ///< Whether is the right handle the one which is selected.
164   bool mUpdateHighlightBox : 1;           ///< True if the text selection high light box must be updated.
165   bool mScrollAfterUpdatePosition : 1;    ///< Whether to scroll after the cursor position is updated.
166   bool mScrollAfterDelete : 1;            ///< Whether to scroll after delete characters.
167   bool mAllTextSelected : 1;              ///< True if the selection handles are selecting all the text.
168   bool mUpdateInputStyle : 1;             ///< Whether to update the input style after moving the cursor.
169   bool mPasswordInput : 1;                ///< True if password input is enabled.
170   bool mCheckScrollAmount : 1;            ///< Whether to check scrolled amount after updating the position
171   bool mIsPlaceholderPixelSize : 1;       ///< True if the placeholder font size is set as pixel size.
172   bool mIsPlaceholderElideEnabled : 1;    ///< True if the placeholder text's elide is enabled.
173   bool mPlaceholderEllipsisFlag : 1;      ///< True if the text controller sets the placeholder ellipsis.
174   bool mShiftSelectionFlag : 1;           ///< True if the text selection using Shift key is enabled.
175   bool mUpdateAlignment : 1;              ///< True if the whole text needs to be full aligned..
176   bool mEditingEnabled : 1;               ///< True if the editing is enabled, false otherwise.
177 };
178
179 struct ModifyEvent
180 {
181   enum Type
182   {
183     TEXT_REPLACED, ///< The entire text was replaced
184     TEXT_INSERTED, ///< Insert characters at the current cursor position
185     TEXT_DELETED   ///< Characters were deleted
186   };
187
188   Type type;
189 };
190
191 struct FontDefaults
192 {
193   FontDefaults()
194   : mFontDescription(),
195     mDefaultPointSize(0.f),
196     mFitPointSize(0.f),
197     mFontId(0u),
198     familyDefined(false),
199     weightDefined(false),
200     widthDefined(false),
201     slantDefined(false),
202     sizeDefined(false)
203   {
204     // Initially use the default platform font
205     TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
206     fontClient.GetDefaultPlatformFontDescription(mFontDescription);
207   }
208
209   FontId GetFontId(TextAbstraction::FontClient& fontClient, float fontPointSize)
210   {
211     if(!mFontId)
212     {
213       const PointSize26Dot6 pointSize = static_cast<PointSize26Dot6>(fontPointSize * 64.f);
214       mFontId                         = fontClient.GetFontId(mFontDescription, pointSize);
215     }
216
217     return mFontId;
218   }
219
220   TextAbstraction::FontDescription mFontDescription;  ///< The default font's description.
221   float                            mDefaultPointSize; ///< The default font's point size.
222   float                            mFitPointSize;     ///< The fit font's point size.
223   FontId                           mFontId;           ///< The font's id of the default font.
224   bool                             familyDefined : 1; ///< Whether the default font's family name is defined.
225   bool                             weightDefined : 1; ///< Whether the default font's weight is defined.
226   bool                             widthDefined : 1;  ///< Whether the default font's width is defined.
227   bool                             slantDefined : 1;  ///< Whether the default font's slant is defined.
228   bool                             sizeDefined : 1;   ///< Whether the default font's point size is defined.
229 };
230
231 /**
232  * @brief Stores indices used to update the text.
233  * Stores the character index where the text is updated and the number of characters removed and added.
234  * Stores as well indices to the first and the last paragraphs to be updated.
235  */
236 struct TextUpdateInfo
237 {
238   TextUpdateInfo()
239   : mCharacterIndex(0u),
240     mNumberOfCharactersToRemove(0u),
241     mNumberOfCharactersToAdd(0u),
242     mPreviousNumberOfCharacters(0u),
243     mParagraphCharacterIndex(0u),
244     mRequestedNumberOfCharacters(0u),
245     mStartGlyphIndex(0u),
246     mStartLineIndex(0u),
247     mEstimatedNumberOfLines(0u),
248     mClearAll(true),
249     mFullRelayoutNeeded(true),
250     mIsLastCharacterNewParagraph(false)
251   {
252   }
253
254   ~TextUpdateInfo()
255   {
256   }
257
258   CharacterIndex mCharacterIndex;             ///< Index to the first character to be updated.
259   Length         mNumberOfCharactersToRemove; ///< The number of characters to be removed.
260   Length         mNumberOfCharactersToAdd;    ///< The number of characters to be added.
261   Length         mPreviousNumberOfCharacters; ///< The number of characters before the text update.
262
263   CharacterIndex mParagraphCharacterIndex;     ///< Index of the first character of the first paragraph to be updated.
264   Length         mRequestedNumberOfCharacters; ///< The requested number of characters.
265   GlyphIndex     mStartGlyphIndex;
266   LineIndex      mStartLineIndex;
267   Length         mEstimatedNumberOfLines; ///< The estimated number of lines. Used to avoid reallocations when layouting.
268
269   bool mClearAll : 1;                    ///< Whether the whole text is cleared. i.e. when the text is reset.
270   bool mFullRelayoutNeeded : 1;          ///< Whether a full re-layout is needed. i.e. when a new size is set to the text control.
271   bool mIsLastCharacterNewParagraph : 1; ///< Whether the last character is a new paragraph character.
272
273   void Clear()
274   {
275     // Clear all info except the mPreviousNumberOfCharacters member.
276     mCharacterIndex              = static_cast<CharacterIndex>(-1);
277     mNumberOfCharactersToRemove  = 0u;
278     mNumberOfCharactersToAdd     = 0u;
279     mParagraphCharacterIndex     = 0u;
280     mRequestedNumberOfCharacters = 0u;
281     mStartGlyphIndex             = 0u;
282     mStartLineIndex              = 0u;
283     mEstimatedNumberOfLines      = 0u;
284     mClearAll                    = false;
285     mFullRelayoutNeeded          = false;
286     mIsLastCharacterNewParagraph = false;
287   }
288 };
289
290 struct UnderlineDefaults
291 {
292   std::string properties;
293   // TODO: complete with underline parameters.
294 };
295
296 struct ShadowDefaults
297 {
298   std::string properties;
299   // TODO: complete with shadow parameters.
300 };
301
302 struct EmbossDefaults
303 {
304   std::string properties;
305   // TODO: complete with emboss parameters.
306 };
307
308 struct OutlineDefaults
309 {
310   std::string properties;
311   // TODO: complete with outline parameters.
312 };
313
314 struct Controller::Impl
315 {
316   Impl(ControlInterface*           controlInterface,
317        EditableControlInterface*   editableControlInterface,
318        SelectableControlInterface* selectableControlInterface,
319        AnchorControlInterface*     anchorControlInterface)
320   : mControlInterface(controlInterface),
321     mEditableControlInterface(editableControlInterface),
322     mSelectableControlInterface(selectableControlInterface),
323     mAnchorControlInterface(anchorControlInterface),
324     mModel(),
325     mFontDefaults(NULL),
326     mUnderlineDefaults(NULL),
327     mShadowDefaults(NULL),
328     mEmbossDefaults(NULL),
329     mOutlineDefaults(NULL),
330     mEventData(NULL),
331     mFontClient(),
332     mClipboard(),
333     mView(),
334     mMetrics(),
335     mModifyEvents(),
336     mTextColor(Color::BLACK),
337     mTextUpdateInfo(),
338     mOperationsPending(NO_OPERATION),
339     mMaximumNumberOfCharacters(50u),
340     mHiddenInput(NULL),
341     mRecalculateNaturalSize(true),
342     mMarkupProcessorEnabled(false),
343     mClipboardHideEnabled(true),
344     mIsAutoScrollEnabled(false),
345     mUpdateTextDirection(true),
346     mIsTextDirectionRTL(false),
347     mUnderlineSetByString(false),
348     mShadowSetByString(false),
349     mOutlineSetByString(false),
350     mFontStyleSetByString(false),
351     mShouldClearFocusOnEscape(true),
352     mLayoutDirection(LayoutDirection::LEFT_TO_RIGHT),
353     mTextFitMinSize(DEFAULT_TEXTFIT_MIN),
354     mTextFitMaxSize(DEFAULT_TEXTFIT_MAX),
355     mTextFitStepSize(DEFAULT_TEXTFIT_STEP),
356     mTextFitEnabled(false),
357     mFontSizeScale(DEFAULT_FONT_SIZE_SCALE)
358   {
359     mModel = Model::New();
360
361     mFontClient = TextAbstraction::FontClient::Get();
362     mClipboard  = Clipboard::Get();
363
364     mView.SetVisualModel(mModel->mVisualModel);
365
366     // Use this to access FontClient i.e. to get down-scaled Emoji metrics.
367     mMetrics = Metrics::New(mFontClient);
368     mLayoutEngine.SetMetrics(mMetrics);
369
370     // Set the text properties to default
371     mModel->mVisualModel->SetUnderlineEnabled(false);
372     mModel->mVisualModel->SetUnderlineHeight(0.0f);
373
374     Toolkit::StyleManager styleManager = Toolkit::StyleManager::Get();
375     if(styleManager)
376     {
377       bool          temp;
378       Property::Map config = Toolkit::DevelStyleManager::GetConfigurations(styleManager);
379       if(config["clearFocusOnEscape"].Get(temp))
380       {
381         mShouldClearFocusOnEscape = temp;
382       }
383     }
384   }
385
386   ~Impl()
387   {
388     delete mHiddenInput;
389
390     delete mFontDefaults;
391     delete mUnderlineDefaults;
392     delete mShadowDefaults;
393     delete mEmbossDefaults;
394     delete mOutlineDefaults;
395     delete mEventData;
396   }
397
398   // Text Controller Implementation.
399
400   /**
401    * @copydoc Text::Controller::RequestRelayout()
402    */
403   void RequestRelayout();
404
405   /**
406    * @brief Request a relayout using the ControlInterface.
407    */
408   void QueueModifyEvent(ModifyEvent::Type type)
409   {
410     if(ModifyEvent::TEXT_REPLACED == type)
411     {
412       // Cancel previously queued inserts etc.
413       mModifyEvents.Clear();
414     }
415
416     ModifyEvent event;
417     event.type = type;
418     mModifyEvents.PushBack(event);
419
420     // The event will be processed during relayout
421     RequestRelayout();
422   }
423
424   /**
425    * @brief Helper to move the cursor, grab handle etc.
426    */
427   bool ProcessInputEvents();
428
429   /**
430    * @brief Helper to check whether any place-holder text is available.
431    */
432   bool IsPlaceholderAvailable() const
433   {
434     return (mEventData &&
435             (!mEventData->mPlaceholderTextInactive.empty() ||
436              !mEventData->mPlaceholderTextActive.empty()));
437   }
438
439   bool IsShowingPlaceholderText() const
440   {
441     return (mEventData && mEventData->mIsShowingPlaceholderText);
442   }
443
444   /**
445    * @brief Helper to check whether active place-holder text is available.
446    */
447   bool IsFocusedPlaceholderAvailable() const
448   {
449     return (mEventData && !mEventData->mPlaceholderTextActive.empty());
450   }
451
452   bool IsShowingRealText() const
453   {
454     return (!IsShowingPlaceholderText() &&
455             0u != mModel->mLogicalModel->mText.Count());
456   }
457
458   /**
459    * @brief Called when placeholder-text is hidden
460    */
461   void PlaceholderCleared()
462   {
463     if(mEventData)
464     {
465       mEventData->mIsShowingPlaceholderText = false;
466
467       // Remove mPlaceholderTextColor
468       mModel->mVisualModel->SetTextColor(mTextColor);
469     }
470   }
471
472   void ClearPreEditFlag()
473   {
474     if(mEventData)
475     {
476       mEventData->mPreEditFlag          = false;
477       mEventData->mPreEditStartPosition = 0;
478       mEventData->mPreEditLength        = 0;
479     }
480   }
481
482   void ResetInputMethodContext()
483   {
484     if(mEventData)
485     {
486       // Reset incase we are in a pre-edit state.
487       if(mEventData->mInputMethodContext)
488       {
489         mEventData->mInputMethodContext.Reset(); // Will trigger a message ( commit, get surrounding )
490       }
491
492       ClearPreEditFlag();
493     }
494   }
495
496   /**
497    * @brief Helper to notify InputMethodContext with surrounding text & cursor changes.
498    */
499   void NotifyInputMethodContext();
500
501   /**
502    * @brief Helper to notify InputMethodContext with multi line status.
503    */
504   void NotifyInputMethodContextMultiLineStatus();
505
506   /**
507    * @brief Retrieve the current cursor position.
508    *
509    * @return The cursor position.
510    */
511   CharacterIndex GetLogicalCursorPosition() const;
512
513   /**
514    * @brief Retrieves the number of consecutive white spaces starting from the given @p index.
515    *
516    * @param[in] index The character index from where to count the number of consecutive white spaces.
517    *
518    * @return The number of consecutive white spaces.
519    */
520   Length GetNumberOfWhiteSpaces(CharacterIndex index) const;
521
522   /**
523    * @brief Retrieve any text previously set starting from the given @p index.
524    *
525    * @param[in] index The character index from where to retrieve the text.
526    * @param[out] text A string of UTF-8 characters.
527    *
528    * @see Dali::Toolkit::Text::Controller::GetText()
529    */
530   void GetText(CharacterIndex index, std::string& text) const;
531
532   bool IsClipboardEmpty()
533   {
534     bool result(mClipboard && mClipboard.NumberOfItems());
535     return !result; // If NumberOfItems greater than 0, return false
536   }
537
538   bool IsClipboardVisible()
539   {
540     bool result(mClipboard && mClipboard.IsVisible());
541     return result;
542   }
543
544   /**
545    * @brief Calculates the start character index of the first paragraph to be updated and
546    * the end character index of the last paragraph to be updated.
547    *
548    * @param[out] numberOfCharacters The number of characters to be updated.
549    */
550   void CalculateTextUpdateIndices(Length& numberOfCharacters);
551
552   /**
553    * @brief Helper to clear completely the parts of the model specified by the given @p operations.
554    *
555    * @note It never clears the text stored in utf32.
556    */
557   void ClearFullModelData(OperationsMask operations);
558
559   /**
560    * @brief Helper to clear completely the parts of the model related with the characters specified by the given @p operations.
561    *
562    * @note It never clears the text stored in utf32.
563    *
564    * @param[in] startIndex Index to the first character to be cleared.
565    * @param[in] endIndex Index to the last character to be cleared.
566    * @param[in] operations The operations required.
567    */
568   void ClearCharacterModelData(CharacterIndex startIndex, CharacterIndex endIndex, OperationsMask operations);
569
570   /**
571    * @brief Helper to clear completely the parts of the model related with the glyphs specified by the given @p operations.
572    *
573    * @note It never clears the text stored in utf32.
574    * @note Character indices are transformed to glyph indices.
575    *
576    * @param[in] startIndex Index to the first character to be cleared.
577    * @param[in] endIndex Index to the last character to be cleared.
578    * @param[in] operations The operations required.
579    */
580   void ClearGlyphModelData(CharacterIndex startIndex, CharacterIndex endIndex, OperationsMask operations);
581
582   /**
583    * @brief Helper to clear the parts of the model specified by the given @p operations and from @p startIndex to @p endIndex.
584    *
585    * @note It never clears the text stored in utf32.
586    *
587    * @param[in] startIndex Index to the first character to be cleared.
588    * @param[in] endIndex Index to the last character to be cleared.
589    * @param[in] operations The operations required.
590    */
591   void ClearModelData(CharacterIndex startIndex, CharacterIndex endIndex, OperationsMask operations);
592
593   /**
594    * @brief Updates the logical and visual models. Updates the style runs in the visual model when the text's styles changes.
595    *
596    * When text or style changes the model is set with some operations pending.
597    * When i.e. the text's size or a relayout is required this method is called
598    * with a given @p operationsRequired parameter. The operations required are
599    * matched with the operations pending to perform the minimum number of operations.
600    *
601    * @param[in] operationsRequired The operations required.
602    *
603    * @return @e true if the model has been modified.
604    */
605   bool UpdateModel(OperationsMask operationsRequired);
606
607   /**
608    * @brief Retreieves the default style.
609    *
610    * @param[out] inputStyle The default style.
611    */
612   void RetrieveDefaultInputStyle(InputStyle& inputStyle);
613
614   /**
615    * @brief Retrieve the line height of the default font.
616    */
617   float GetDefaultFontLineHeight();
618
619   /**
620    * @copydoc Text::Controller::GetPrimaryCursorPosition()
621    */
622   CharacterIndex GetPrimaryCursorPosition() const;
623
624   /**
625    * @copydoc Text::Controller::SetPrimaryCursorPosition()
626    */
627   bool SetPrimaryCursorPosition(CharacterIndex index);
628
629   /**
630    * @copydoc Text::SelectableControlInterface::SetTextSelectionRange()
631    */
632   void SetTextSelectionRange(const uint32_t* pStart, const uint32_t* pEndf);
633
634   /**
635    * @copydoc Text::SelectableControlInterface::GetTextSelectionRange()
636    */
637   Uint32Pair GetTextSelectionRange() const;
638
639   /**
640    * @copydoc Text::EditableControlInterface::IsEditable()
641    */
642   bool IsEditable() const;
643
644   /**
645    * @copydoc Text::EditableControlInterface::SetEditable()
646    */
647   void SetEditable(bool editable);
648
649   /**
650    * @brief Retrieves the selected text. It removes the text if the @p deleteAfterRetrieval parameter is @e true.
651    *
652    * @param[out] selectedText The selected text encoded in utf8.
653    * @param[in] deleteAfterRetrieval Whether the text should be deleted after retrieval.
654    */
655   void RetrieveSelection(std::string& selectedText, bool deleteAfterRetrieval);
656
657   void SetSelection(int start, int end);
658
659   std::pair<int, int> GetSelectionIndexes() const;
660
661   void ShowClipboard();
662
663   void HideClipboard();
664
665   void SetClipboardHideEnable(bool enable);
666
667   bool CopyStringToClipboard(const std::string& source);
668
669   void SendSelectionToClipboard(bool deleteAfterSending);
670
671   void RequestGetTextFromClipboard();
672
673   void RepositionSelectionHandles();
674   void RepositionSelectionHandles(float visualX, float visualY, Controller::NoTextTap::Action action);
675
676   void SetPopupButtons();
677
678   void ChangeState(EventData::State newState);
679
680   /**
681    * @brief Calculates the cursor's position for a given character index in the logical order.
682    *
683    * It retrieves as well the line's height and the cursor's height and
684    * if there is a valid alternative cursor, its position and height.
685    *
686    * @param[in] logical The logical cursor position (in characters). 0 is just before the first character, a value equal to the number of characters is just after the last character.
687    * @param[out] cursorInfo The line's height, the cursor's height, the cursor's position and whether there is an alternative cursor.
688    */
689   void GetCursorPosition(CharacterIndex logical,
690                          CursorInfo&    cursorInfo);
691
692   /**
693    * @brief Calculates the new cursor index.
694    *
695    * It takes into account that in some scripts multiple characters can form a glyph and all of them
696    * need to be jumped with one key event.
697    *
698    * @param[in] index The initial new index.
699    *
700    * @return The new cursor index.
701    */
702   CharacterIndex CalculateNewCursorIndex(CharacterIndex index) const;
703
704   /**
705    * @brief Updates the cursor position.
706    *
707    * Sets the cursor's position into the decorator. It transforms the cursor's position into decorator's coords.
708    * It sets the position of the secondary cursor if it's a valid one.
709    * Sets which cursors are active.
710    *
711    * @param[in] cursorInfo Contains the selection handle position in Actor's coords.
712    *
713    */
714   void UpdateCursorPosition(const CursorInfo& cursorInfo);
715
716   /**
717    * @brief Updates the position of the given selection handle. It transforms the handle's position into decorator's coords.
718    *
719    * @param[in] handleType One of the selection handles.
720    * @param[in] cursorInfo Contains the selection handle position in Actor's coords.
721    */
722   void UpdateSelectionHandle(HandleType        handleType,
723                              const CursorInfo& cursorInfo);
724
725   /**
726    * @biref Clamps the horizontal scrolling to get the control always filled with text.
727    *
728    * @param[in] layoutSize The size of the laid out text.
729    */
730   void ClampHorizontalScroll(const Vector2& layoutSize);
731
732   /**
733    * @biref Clamps the vertical scrolling to get the control always filled with text.
734    *
735    * @param[in] layoutSize The size of the laid out text.
736    */
737   void ClampVerticalScroll(const Vector2& layoutSize);
738
739   /**
740    * @brief Scrolls the text to make a position visible.
741    *
742    * @pre mEventData must not be NULL. (there is a text-input or selection capabilities).
743    *
744    * @param[in] position A position in text coords.
745    * @param[in] lineHeight The line height for the given position.
746    *
747    * This method is called after inserting text, moving the cursor with the grab handle or the keypad,
748    * or moving the selection handles.
749    */
750   void ScrollToMakePositionVisible(const Vector2& position, float lineHeight);
751
752   /**
753    * @brief Scrolls the text to make the cursor visible.
754    *
755    * This method is called after deleting text.
756    */
757   void ScrollTextToMatchCursor(const CursorInfo& cursorInfo);
758
759   /**
760    * @brief Scrolls the text to make primary cursor visible.
761    */
762   void ScrollTextToMatchCursor();
763
764   /**
765    * @brief Create an actor that renders the text background color
766    *
767    * @return the created actor or an empty handle if no background color needs to be rendered.
768    */
769   Actor CreateBackgroundActor();
770
771 public:
772   /**
773    * @brief Gets implementation from the controller handle.
774    * @param controller The text controller
775    * @return The implementation of the Controller
776    */
777   static Impl& GetImplementation(Text::Controller& controller)
778   {
779     return *controller.mImpl;
780   }
781
782 private:
783   // Declared private and left undefined to avoid copies.
784   Impl(const Impl&);
785   // Declared private and left undefined to avoid copies.
786   Impl& operator=(const Impl&);
787
788   /**
789    * @brief Copy Underlined-Character-Runs from Logical-Model to Underlined-Glyph-Runs in Visual-Model
790    *
791    * @param shouldClearPreUnderlineRuns Whether should clear the existing Underlined-Glyph-Runs in Visual-Model
792    */
793   void CopyUnderlinedFromLogicalToVisualModels(bool shouldClearPreUnderlineRuns);
794
795 public:
796   ControlInterface*           mControlInterface;           ///< Reference to the text controller.
797   EditableControlInterface*   mEditableControlInterface;   ///< Reference to the editable text controller.
798   SelectableControlInterface* mSelectableControlInterface; ///< Reference to the selectable text controller.
799   AnchorControlInterface*     mAnchorControlInterface;     ///< Reference to the anchor controller.
800   ModelPtr                    mModel;                      ///< Pointer to the text's model.
801   FontDefaults*               mFontDefaults;               ///< Avoid allocating this when the user does not specify a font.
802   UnderlineDefaults*          mUnderlineDefaults;          ///< Avoid allocating this when the user does not specify underline parameters.
803   ShadowDefaults*             mShadowDefaults;             ///< Avoid allocating this when the user does not specify shadow parameters.
804   EmbossDefaults*             mEmbossDefaults;             ///< Avoid allocating this when the user does not specify emboss parameters.
805   OutlineDefaults*            mOutlineDefaults;            ///< Avoid allocating this when the user does not specify outline parameters.
806   EventData*                  mEventData;                  ///< Avoid allocating everything for text input until EnableTextInput().
807   TextAbstraction::FontClient mFontClient;                 ///< Handle to the font client.
808   Clipboard                   mClipboard;                  ///< Handle to the system clipboard
809   View                        mView;                       ///< The view interface to the rendering back-end.
810   MetricsPtr                  mMetrics;                    ///< A wrapper around FontClient used to get metrics & potentially down-scaled Emoji metrics.
811   Layout::Engine              mLayoutEngine;               ///< The layout engine.
812   Vector<ModifyEvent>         mModifyEvents;               ///< Temporary stores the text set until the next relayout.
813   Vector4                     mTextColor;                  ///< The regular text color
814   TextUpdateInfo              mTextUpdateInfo;             ///< Info of the characters updated.
815   OperationsMask              mOperationsPending;          ///< Operations pending to be done to layout the text.
816   Length                      mMaximumNumberOfCharacters;  ///< Maximum number of characters that can be inserted.
817   HiddenText*                 mHiddenInput;                ///< Avoid allocating this when the user does not specify hidden input mode.
818   Vector2                     mTextFitContentSize;         ///< Size of Text fit content
819
820   bool               mRecalculateNaturalSize : 1; ///< Whether the natural size needs to be recalculated.
821   bool               mMarkupProcessorEnabled : 1; ///< Whether the mark-up procesor is enabled.
822   bool               mClipboardHideEnabled : 1;   ///< Whether the ClipboardHide function work or not
823   bool               mIsAutoScrollEnabled : 1;    ///< Whether auto text scrolling is enabled.
824   bool               mUpdateTextDirection : 1;    ///< Whether the text direction needs to be updated.
825   CharacterDirection mIsTextDirectionRTL : 1;     ///< Whether the text direction is right to left or not
826
827   bool                  mUnderlineSetByString : 1;     ///< Set when underline is set by string (legacy) instead of map
828   bool                  mShadowSetByString : 1;        ///< Set when shadow is set by string (legacy) instead of map
829   bool                  mOutlineSetByString : 1;       ///< Set when outline is set by string (legacy) instead of map
830   bool                  mFontStyleSetByString : 1;     ///< Set when font style is set by string (legacy) instead of map
831   bool                  mShouldClearFocusOnEscape : 1; ///< Whether text control should clear key input focus
832   LayoutDirection::Type mLayoutDirection;              ///< Current system language direction
833
834   Shader mShaderBackground; ///< The shader for text background.
835
836   float mTextFitMinSize;     ///< Minimum Font Size for text fit. Default 10
837   float mTextFitMaxSize;     ///< Maximum Font Size for text fit. Default 100
838   float mTextFitStepSize;    ///< Step Size for font intervalse. Default 1
839   bool  mTextFitEnabled : 1; ///< Whether the text's fit is enabled.
840   float mFontSizeScale;      ///< Scale value for Font Size. Default 1.0
841
842 private:
843   friend ControllerImplEventHandler;
844   friend SelectionHandleController;
845 };
846
847 } // namespace Text
848
849 } // namespace Toolkit
850
851 } // namespace Dali
852
853 #endif // DALI_TOOLKIT_TEXT_CONTROLLER_H