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