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