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