087cde32e9c5bd650476f6a21462557d06b6a1ac
[platform/core/uifw/dali-toolkit.git] / base / dali-toolkit / internal / controls / text-input / text-input-decorator-impl.h
1 #ifndef __DALI_TOOLKIT_INTERNAL_TEXT_INPUT_DECORATOR_H__
2 #define __DALI_TOOLKIT_INTERNAL_TEXT_INPUT_DECORATOR_H__
3
4 //
5 // Copyright (c) 2014 Samsung Electronics Co., Ltd.
6 //
7 // Licensed under the Flora License, Version 1.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://floralicense.org/license/
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 #include <dali/dali.h>
21
22 // INTERNAL INCLUDES
23
24 #include <dali-toolkit/internal/controls/text-input/textview-character-positions-impl.h>
25 #include <dali-toolkit/internal/controls/text-input/text-input-handles-impl.h>
26 #include <dali-toolkit/internal/controls/text-input/text-input-text-highlight-impl.h>
27 #include <dali-toolkit/internal/controls/text-input/text-input-popup-new-impl.h>
28
29 namespace Dali
30 {
31
32 namespace Toolkit
33 {
34
35 namespace Internal
36 {
37
38 class Decorator;
39
40 typedef IntrusivePtr<Decorator> DecoratorPtr;
41
42 /**
43  *  @brief Decorator Class
44  *
45  *  Decorations are Selection Handles, cursor, grab handle, magnifier the "cut copy paste" PopUp and Selection highlight.
46  *  The Decorator triggers creation of these decorations and positions them.
47  *  Decoration positions can be dependent on other decorations like the PopUp on the Selection handles.
48  *  The decorator maintains a Bounding Box which the decorations have to be positioned within, decorations can be flipped or hidden to obey this Bounding Box.
49  *  Scrolling of Text can effect positioning of decorations, the decorator repositions decorations in this case.
50  */
51
52 class Decorator : public ConnectionTracker
53 {
54
55 public:
56
57   /**
58    * @brief Constructor
59    *
60    * @param[in] textviewManager TextViewManager to be used
61    */
62   Decorator( TextViewCharacterPositioning& textviewManager, TextInputTextStyle& textStyle);
63
64   /**
65    * @brief Default destructor
66    */
67   ~Decorator();
68
69   /**
70    * @brief Set the dimensions of the bounding rectangle for decorations to obey.
71    *
72    * @param[in] boundingRectangle
73    */
74   void SetBoundingBox( const Rect<float>& boundingRectangle );
75
76   /**
77    * @brief Get the bounding dimensions of the bounding box
78    *
79    * @return dimensions of the bounding box from world origin. (x, y, w, z )
80    *
81    *  -----------------
82    * |        ^        |
83    * |        |        |
84    * |        y        |
85    * |        |        |
86    * |        v        |
87    * |<--x--> o <--z-->|
88    * |        ^        |
89    * |        |        |
90    * |        w        |
91    * |        |        |
92    * |        v        |
93    *  -----------------
94    */
95   Vector4 GetBoundingBox() const;
96
97   /**
98    * @brief Callback when a handle is panned/moved, either selection handles or grab handle
99    *
100    * @param actor Handle of the selection or grab handle.
101    * @param gesture Data structure with the parameters of the gesture.
102    */
103   void OnHandlePan(Actor actor, PanGesture gesture);
104
105   // Selection Handles
106
107   /**
108    * @brief Create a left and right selection handle and parent both to the provided actor
109    * @param[in] parent actor in which the handles should be added to.
110    */
111   void CreateSelectionHandles( Actor parent );
112
113   /**
114    * @brief Remove selection handles from their parent
115    */
116   void RemoveSelectionHandles();
117
118   /**
119    * @brief Get size of Selection handles
120    *
121    * @return size of a selection handle
122    */
123   Vector3 GetSelectionHandleSize();
124
125   /**
126    * @brief Get position of Selection handle within text
127    *
128    * @return character position of a selection handle one
129    */
130   std::size_t GetHandleOnePosition() const;
131
132   /**
133    * @brief Get position of Selection handle within text
134    *
135    * @return character position of a selection handle two
136    */
137   std::size_t GetHandleTwoPosition() const;
138
139   /**
140    * @brief Position Selection a single handle at given positions within the text string.
141    *
142    * @param[in] selectionHandle handle to be positioned
143    * @param[in] position where to place handle
144    * @return Vector3 Position of handle as a coordinate.
145    */
146   Vector3 PositionSelectionHandle( Actor selectionHandle, std::size_t position );
147
148   /**
149    * @brief Position Selection a single handle at given coordinates
150    *
151    * @param[in] selectionHandle handle to be positioned
152    * @param[in] actualPosition coordinates to position handle
153    * @param[in] position where to place handle
154    * @return Vector3 Position of handle as a coordinate.
155    */
156   Vector3 PositionSelectionHandle( Actor selectionHandle, Vector3& actualPosition, std::size_t position );
157
158   /**
159    * @brief Make both selection handle visible or invisible
160    * @param[in] visible true to make visible, false to fine
161    */
162   void SetSelectionHandlesVisibility( bool visible );
163
164   /**
165    * @brief Callback for when a handle is released
166    * @return bool
167    */
168   bool OnHandleReleased();
169
170   /**
171    * @brief Position Selection handles at given positions within the text string.
172    *
173    * @param[in] start where to place first handle
174    * @param[in] end  where to place second handle
175    */
176   void PositionSelectionHandles( std::size_t start, std::size_t end );
177
178   /**
179    * @brief Move selection handle by the given displacement.
180    *
181    * @param[in] selectionHandle Actor to move
182    * @param[in] actualSelectionHandlePosition actual current position of the handle in x y z
183    * @param[in] currentSelectionHandlePosition current position along the string
184    * @param[in] displacement the x y displacement
185    */
186   Vector3 MoveSelectionHandle( Actor selectionHandle,
187                                Vector3& actualSelectionHandlePosition,
188                                std::size_t& currentSelectionHandlePosition,
189                                const Vector2& displacement );
190
191   /* Grab Handle */
192
193   /**
194    * @brief Position GrabHandlewith depending on the the character in the text it should be placed at
195    * @param[in] positonInText the character position within the text the handle should be at
196    */
197   void PositionGrabHandle( std::size_t positionInText );
198
199   /**
200    * @brief Move grab handle to the required position within the text
201    *
202    * @param[in] displacement Displacement of the grab handle in actor coordinates.
203    */
204   void MoveGrabHandle( const Vector2& displacement );
205
206   /**
207    * @brief Show or hide the GrabHandle is visibility is true
208    *
209    * @param[in] visible flag to show or not show the grab handle
210    */
211   void ShowGrabHandle( bool visible );
212
213   /**
214    * @brief Create the GrabHandle used to position cursor
215    * @param[in] targetParent the Actor to parent the GrabHandle
216    */
217   void CreateGrabHandle( Actor targetParent );
218
219   /**
220    * @brief Set the image to be used as the cursor grab hander
221    * @pre The text input actor has been initialised.
222    * @param[in] image The image to be used.
223    */
224   void SetGrabHandleImage( Image image );
225
226   /**
227    * @brief Toggle to enable the grab handle, used to position cursor when magnifier not being used.
228    * Default behaviour is to use the magnifier to position the cursor, enabling this prevents the magnifier from being shown.
229    * @param[in] toggle true to enable, false to disable grab handle
230    */
231   void EnableGrabHandle(bool toggle);
232
233   /**
234    * @brief Method to check if grab handle is enabled, if false then the magnifier will be used to position cursor.
235    * @return bool returns true is grab handle enabled.
236    */
237   bool IsGrabHandleEnabled();
238
239   /* Cursor */
240
241   /**
242    * @brief Get the current Cursor position
243    * @return current cursor position
244    */
245   std::size_t GetCurrentCursorPosition() const;
246
247   /**
248    * @brief Set the Cursor position
249    * @param[in] the position the cursor should be set to
250    */
251   void SetCurrentCursorPosition( std::size_t newCursorPosition );
252
253   /**
254    * @brief Set if the cursors are visible or not.
255    * @param[in] visible flag true for visible
256    */
257   void SetCursorVisibility( bool visible );
258
259   /**
260    * @brief Display cursor
261    * @param[in] nthChar position in text string to display cursor
262    */
263   void DrawCursor( const std::size_t nthChar = 0 );
264
265   /**
266    * Sets alternate cursor enable state
267    * @see SetCursorVisibility
268    * alternate cursor will only be visible if both SetCursorVisiblity
269    * and cursor enabled have been set to true.
270    */
271   void SetAltCursorEnabled( bool enabled );
272
273   /**
274    * @brief Set the image to be used for the regular left to right cursor
275    * @pre The text input actor has been initialised.
276    * @param[in] image The image to be used.
277    * @param[in] border The nine patch border for the image.
278    */
279   void SetCursorImage( Image image, const Vector4& border );
280
281   /**
282    * @brief Set the image to be used for the Right to Left cursor
283    * @pre The text input actor has been initialised.
284    * @param[in] image The image to be used.
285    * @param[in] border The nine patch border for the image.
286    */
287   void SetRTLCursorImage( Image image, const Vector4& border );
288
289   /**
290    * @brief Creates a cursor from the supplied image and nine patch border.
291    * @param[in] cursorImage the image to be used for the cursor.
292    * @param[in] border the nine patch border corresponding to the supplied image.
293    * @paran[in] cursorName actor name for cursor
294    * @return the image actor to be used as the cursor.
295    */
296   ImageActor CreateCursor( Image cursorImage, const Vector4& border,  const std::string& cursorName );
297
298   /**
299    * @brief Creates a regular and Right-To-Left cursor and parents them to give target Actor
300    * @param[in] targetParent target Actor
301    */
302   void CreateCursors( Actor targetParent );
303
304   /**
305    * @Brief Returns the cursor size at a given position in the text.
306    * @return Size the size of the cursor
307    */
308   Size GetCursorSizeAt( std::size_t positionWithinTextToGetCursorSize );
309
310   /**
311    * @brief  Start a timer to signal cursor to blink.
312    */
313   void StartCursorBlinkTimer();
314
315   /**
316    * @brief  Stop the timer signalling the cursor to blink.
317    */
318   void StopCursorBlinkTimer();
319
320   /**
321    * @brief Callback when handle timer ticks.
322    *
323    * Cursor should become visible/invisible to simulate blinking.
324    *
325    * @return True if the timer should be keep running.
326    */
327   bool OnCursorBlinkTimerTick();
328
329   /* Selection Highlight */
330
331   /**
332    * @brief Updates mesh data for selection highlight depending on handle positions and displays it.
333    */
334   void ShowUpdatedHighlight();
335
336   /**
337    * @brief Creates the Highlight used for selection
338    *
339    * @param[in] parent target actor in which the handles should be added to.
340    */
341   void CreateHighlight( Actor parent );
342
343   /**
344    * @brief Remove Highlight actor from it's parent
345    */
346   void RemoveHighlight();
347
348   /**
349    * @brief Set the visibility of the Highlight
350    *
351    * @param[in] visibility True to show and False to hide.
352    */
353   void HighlightVisibility( bool visiblility );
354
355   /* Boundary Property Notifications when handle exceed bounding box*/
356
357   /**
358    * @brief PropertyNotification Callback when left boundary exceeded so handle can be flipped.
359    *
360    * @param[in] source PropertyNotification
361    */
362   void OnLeftBoundaryExceeded( PropertyNotification& source );
363   /**
364    * @brief PropertyNotification Callback when within left boundary so handle can be flipped back.
365    *
366    * @param[in] source PropertyNotification
367    */
368   void OnReturnToLeftBoundary( PropertyNotification& source );
369   /**
370    * @brief PropertyNotification Callback when right boundary exceeded so handle can be flipped.
371    *
372    * @param[in] source PropertyNotification
373    */
374   void OnRightBoundaryExceeded( PropertyNotification& source );
375   /**
376    * @brief PropertyNotification Callback when within right boundary so handle can be flipped back.
377    *
378    * @param[in] source PropertyNotification
379    */
380   void OnReturnToRightBoundary( PropertyNotification& source );
381
382   /**
383    * @brief PropertyNotification Callbacks for hiding handle one when it exceeds boundary.
384    *
385    * @param[in] source PropertyNotification
386    */
387   void OnHandleOneLeavesBoundary( PropertyNotification& source );
388   /**
389    * @brief PropertyNotification Callbacks for showing hidden handle one when returns within boundary
390    *
391    * @param[in] source PropertyNotification
392    */
393   void OnHandleOneWithinBoundary( PropertyNotification& source );
394   /**
395    * @brief PropertyNotification Callbacks for hiding handle two it  when exceeds boundary.
396    *
397    * @param[in] source PropertyNotification
398    */
399   void OnHandleTwoLeavesBoundary( PropertyNotification& source );
400   /**
401    * @brief PropertyNotification Callbacks for showing hidden handle two when returns within boundary
402    *
403    * @param[in] source PropertyNotification
404    */
405   void OnHandleTwoWithinBoundary( PropertyNotification& source );
406
407   /**
408    * @brief Set up property notifications on the position of the handles to facilitate flipping and hiding when at screen boundary.
409    */
410   void SetUpHandlePropertyNotifications();
411
412   // Cut & Paste Pop-up
413
414   /**
415    * @brief Calculate positioning of PopUp relative to handles
416    * @return Actual position of PopUp
417    */
418   Vector3 PositionOfPopUpRelativeToSelectionHandles( );
419
420   /**
421    * @brief Calculate alternative position of PopUp relative to handles  when can it not be displayed in the default upper position.
422    * @return Actual position of PopUp
423    */
424   Vector3 AlternatePopUpPositionRelativeToSelectionHandles();
425
426   /**
427    * @brief Calculate positioning of PopUp relative to cursor
428    * @return Actual position of PopUp
429    */
430   Vector3 PositionOfPopUpRelativeToCursor();
431
432   /**
433    * @brief Calculate alternative position of PopUp relative to cursor when can not be displayed in normal upper position.
434    * @return Actual position of PopUp
435    */
436   Vector3 AlternatePopUpPositionRelativeToCursor();
437
438   /**
439    * @brief Calculate positioning of PopUp relative to GrabHandle
440    * @return Actual position of PopUp
441    */
442   Vector3 PositionOfPopUpRelativeToGrabHandle();
443
444  /**
445   * @brief Show the PopUp in the provided target
446   * @param[in] target target actor in which the PopUp should be added to.
447   */
448   void ShowPopUp( Actor target );
449
450   /**
451    * @brief Show PopUp in previously set Target.
452    * @pre Must have previously called ShopPopUp( Actor target ) otherwise PopUp will not be shown.
453    */
454   void ShowPopUp();
455
456   /**
457    * @brief Create and Show Cut Copy Paste PopUp
458    */
459   void ShowPopupCutCopyPaste();
460
461   /**
462    * @brief Hide PopUp
463    * @param[in] animate Animate or just hide instantly, default is true
464    * @param[in] signalFinished Signal when finished, default is true
465    */
466   void HidePopUp( bool animate=true, bool signalFinished=true );
467
468   /**
469    * @brief Adds a popup option.
470    * @brief Creates popup frame if not already created.
471    * @param[in] name The unique name for this option.
472    * @param[in] caption The caption (label) for this option
473    * @param[in] icon the image icon to be displayed for this option
474    * @param[in] finalOption Flag to indicate that this is the final option.
475    * (set to true on the last option you add)
476    */
477   void AddPopupOption(const std::string& name, const std::string& caption, const Image icon, bool finalOption = false);
478
479   /**
480    * @brief Removes popup, and its options.
481    */
482   void ClearPopup();
483
484   /**
485    * @brief PropertyNotification Callbacks for flipping PopUp when exceeds boundary.
486    * @param[in] source PropertyNotification
487    */
488   void PopUpLeavesVerticalBoundary( PropertyNotification& source );
489
490   /**
491    * @brief Setup position notifications when PopUp exceeds boundary
492    */
493   void SetUpPopUpPositionNotifications( );
494
495   /**
496    * @brief Callback for when a button is pressed in popup panel
497    * @param[in] button handle to the button pressed.
498    * @return bool consummation
499    */
500   bool OnPopupButtonPressed( Toolkit::Button button );
501
502   // Decoration positioning during scrolling
503
504   /**
505    * @brief Updates the position of the decorations when Text is scrolled.
506    *
507    * @param[in] textView Handle of the text-view.
508    * @param[in] scrollPosition The difference with the previous scroll position.
509    */
510   void TextViewScrolled( Toolkit::TextView textView, Vector2 scrollPosition );
511
512   /**
513    * @brief  Creates and starts a timer to scroll the text when handles are close to the edges of the text-input.
514    *
515    * It only starts the timer if it's already created.
516    */
517   void StartScrollTimer();
518
519   /**
520    * @brief  Stops the timer used to scroll the text.
521    */
522   void StopScrollTimer();
523
524   /**
525    * @brief Scroll Text according to handle position
526    * @param[in out] handlePosition handle position within character string
527    * @param[in] actual vector position of handle
528    * @return updated actual vector position of handle
529    */
530   Vector3 ScrollRelativeToHandle( std::size_t& handlePosition, Vector3& actualHandlePosition );
531
532   /**
533    * @brief Callback called by the timer used to scroll the text.
534    *
535    * It calculates and sets a new scroll position.
536    */
537   bool OnScrollTimerTick();
538
539   // Text Selection
540
541   /**
542    * @brief Function to get Text selected between the 2 selection handles.
543    * @return StyledTextArray an array of
544    */
545   MarkupProcessor::StyledTextArray GetSelectedText();
546
547 private:
548
549   /**
550    * @brief Copy Constructor
551    * @param[in] decorator
552    * Undefined/Hidden.
553    */
554   Decorator(const Decorator& decorator);
555
556   /**
557    * @Assignment Constructor
558    * @param[in] rhs
559    * Undefined/Hidden.
560    */
561   Decorator& operator=(const Decorator& rhs);
562
563 public:
564
565   typedef SignalV2< bool( Toolkit::Button ) > PressedSignal;
566   typedef SignalV2< void () > CursorPositionedSignal;
567   /**
568    * @brief Signal emitted when the button is touched.
569    * This is relayed from the PopUp class.  It enables the owner of the Decorator to act on the PopUp button press.
570    */
571   PressedSignal& PopUpButtonPressedSignal();
572
573   /**
574    * @brief Signal emitted when the cursor is repositioned
575    * @param[in] cursor the new cursor position
576    */
577   CursorPositionedSignal& CursorRePositionedSignal();
578
579 private:
580
581   Vector4 mBoundingRectangleWorldCoordinates;
582
583   TextViewCharacterPositioning& mTextViewCharacterPositioning;
584
585   TextInputHandles mTextInputHandles;
586
587   TextInputTextStyle& mTextStyle;
588
589   Vector3 mSelectionHandleOneActualPosition;    // Actual x y position of handle
590   Vector3 mSelectionHandleTwoActualPosition;    // Actual x y position of handle
591   std::size_t mSelectionHandleOnePosition;      // Position of handle along the string of text
592   std::size_t mSelectionHandleTwoPosition;      // Position of handle along the string of text
593
594   TextInputPopupNew mPopUpPanel;                // PopUp used for Cut Cpoy and Paste
595   Actor mPopUpTarget;                           // Target Actor to parent PopUp
596
597   Vector3 mActualGrabHandlePosition;            // Actual position of grab handle, this might not be snapped to a character
598   std::size_t mGrabHandlePosition;              // Position of grab handle along the string of text
599   Vector3 mCurrentHandlePosition;
600
601   std::size_t mCursorPosition;                  // Current cursor position within the text string
602   ImageActor mCursor;                           // Cursor overlayed on Text to show where new text will be inserted
603   ImageActor mCursorRTL;                        // Right To Left Cursor overlayed on Text (where new RTL text would be inserted)
604   Animation mCursorAnimation;                   // Animation for cursor blinking.
605   Timer mCursorBlinkTimer;                      // Timer to signal cursor to blink
606
607   Vector2 mScrollDisplacement;                  // How much to scroll by
608   Timer mScrollTimer;                           // Timer to scroll text over a period of time not all in one update.
609
610   TextHighlight mTextHighlight;                 // Holds data required to construct the highlight
611   MeshActor mHighlightMeshActor;                // Mesh Actor to display highlight
612
613   PanGestureDetector mPanGestureDetector;
614
615   PressedSignal mPopUpButtonPressedSignal;           // Signal emitted when a button within the popup is pressed.
616   CursorPositionedSignal mCursorRePositionedSignal;  // Signal emitted when a button when cursor position is changed.
617
618   bool mCursorBlinkStatus:1;                    // \e true shows the cursor, \e false hides it.
619   bool mCursorVisibility:1;                     // Should cursor be visible
620   bool mCursorRTLEnabled:1;                     // Enable state of Alternate RTL Cursor (need to keep track of this as it's not always enabled)
621   bool mIsGrabHandleInScrollArea:1;             // Whether the grab handle is inside the boundaries of the text-input.
622   bool mIsCursorInScrollArea:1;                 // Whether the cursor is inside the boundaries of the text-input.
623   bool mGrabHandleVisibility:1;                 // Should grab handle be visible
624   bool mGrabHandleEnabled:1;                    // Flag to enable the grab handle instead of the default magnifier.
625 };
626
627 } // namespace Internal
628
629 } // namespace Toolkit
630
631 } // namespace Dali
632
633 #endif // __DALI_TOOLKIT_INTERNAL_TEXT_INPUT_DECORATOR_H__
634
635