[dali_2.1.23] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / text / decorator / text-decorator.h
1 #ifndef DALI_TOOLKIT_TEXT_DECORATOR_H
2 #define DALI_TOOLKIT_TEXT_DECORATOR_H
3
4 /*
5  * Copyright (c) 2021 Samsung Electronics Co., Ltd.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */
20
21 // EXTERNAL INCLUDES
22 #include <dali/public-api/common/intrusive-ptr.h>
23 #include <dali/public-api/math/rect.h>
24 #include <dali/public-api/object/ref-object.h>
25
26 // INTERNAL INCLUDES
27 #include <dali-toolkit/devel-api/controls/text-controls/text-selection-popup.h>
28
29 namespace Dali
30 {
31 struct Vector2;
32 struct Vector4;
33
34 namespace Toolkit
35 {
36 namespace Text
37 {
38 class Decorator;
39 typedef IntrusivePtr<Decorator> DecoratorPtr;
40
41 // Used to set the cursor positions etc.
42 enum Cursor
43 {
44   PRIMARY_CURSOR,   ///< The primary cursor for bidirectional text (or the regular cursor for single-direction text)
45   SECONDARY_CURSOR, ///< The secondary cursor for bidirectional text
46   CURSOR_COUNT
47 };
48
49 // Determines which of the cursors are active (if any).
50 enum ActiveCursor
51 {
52   ACTIVE_CURSOR_NONE,    ///< Neither primary nor secondary cursor are active
53   ACTIVE_CURSOR_PRIMARY, ///< Primary cursor is active (only)
54   ACTIVE_CURSOR_BOTH     ///< Both primary and secondary cursor are active
55 };
56
57 // The state information for handle events.
58 enum HandleState
59 {
60   HANDLE_TAPPED,
61   HANDLE_PRESSED,
62   HANDLE_RELEASED,
63   HANDLE_SCROLLING,
64   HANDLE_STOP_SCROLLING
65 };
66
67 // Used to set different handle images
68 enum HandleImageType
69 {
70   HANDLE_IMAGE_PRESSED,
71   HANDLE_IMAGE_RELEASED,
72   HANDLE_IMAGE_TYPE_COUNT
73 };
74
75 // Types of handles.
76 enum HandleType
77 {
78   GRAB_HANDLE,
79   LEFT_SELECTION_HANDLE,
80   RIGHT_SELECTION_HANDLE,
81   LEFT_SELECTION_HANDLE_MARKER,
82   RIGHT_SELECTION_HANDLE_MARKER,
83   HANDLE_TYPE_COUNT
84 };
85
86 // Types of decoration.
87 enum DecorationType
88 {
89   NONE_LAYER,
90   ACTIVE_LAYER,
91   CURSOR_LAYER
92 };
93
94 /**
95  * @brief A Text Decorator is used to display cursors, handles, selection highlights and pop-ups.
96  *
97  * The decorator is responsible for clipping decorations which are positioned outside of the parent area.
98  *
99  * The Popup decoration will be positioned either above the Grab handle or above the selection handles but if doing so
100  * would cause the Popup to exceed the Decoration Bounding Box ( see SetBoundingBox API ) the the Popup will be repositioned below the handle(s).
101  *
102  * Selection handles will be flipped around to ensure they do not exceed the Decoration Bounding Box. ( Stay visible ).
103  *
104  * Decorator components forward input events to a controller class through an interface.
105  * The controller is responsible for selecting which components are active.
106  */
107 class Decorator : public RefObject
108 {
109 public:
110   class ControllerInterface
111   {
112   public:
113     /**
114      * @brief Constructor.
115      */
116     ControllerInterface(){};
117
118     /**
119      * @brief Virtual destructor.
120      */
121     virtual ~ControllerInterface(){};
122
123     /**
124      * @brief Query the target size of the UI control.
125      *
126      * @param[out] targetSize The size of the UI control the decorator is adding it's decorations to.
127      */
128     virtual void GetTargetSize(Vector2& targetSize) = 0;
129
130     /**
131      * @brief Add a decoration to the parent UI control.
132      *
133      * @param[in] actor The actor displaying a decoration.
134      * @param[in] type Whether this decoration is a layer or not, which layer it is.
135      * @param[in] needsClipping Whether the actor needs clipping.
136      */
137     virtual void AddDecoration(Actor& actor, DecorationType type, bool needsClipping) = 0;
138
139     /**
140      * @brief An input event from one of the handles.
141      *
142      * @param[in] handleType The handle's type.
143      * @param[in] state The handle's state.
144      * @param[in] x The x position relative to the top-left of the parent control.
145      * @param[in] y The y position relative to the top-left of the parent control.
146      */
147     virtual void DecorationEvent(HandleType handleType, HandleState state, float x, float y) = 0;
148   };
149
150   /**
151    * @brief Create a new instance of a Decorator.
152    *
153    * @param[in] controller The controller which receives input events from Decorator components.
154    * @param[in] callbackInterface The text popup callback interface which receives the button click callbacks.
155    *
156    * @return A pointer to a new Decorator.
157    */
158   static DecoratorPtr New(ControllerInterface&                 controller,
159                           TextSelectionPopupCallbackInterface& callbackInterface);
160
161   /**
162    * @brief Set the bounding box which handles, popup and similar decorations will not exceed.
163    *
164    * The default value is the width and height of the stage from the top left origin.
165    * If a title bar for example is on the top of the screen then the y should be the title's height and
166    * the boundary height the stage height minus the title's height.
167    * Restrictions - The boundary box should be set up with a fixed z position for the text-input and the default camera.
168    *
169    * ------------------------------------------
170    * |(x,y)                                   |
171    * |o---------------------------------------|
172    * ||                                      ||
173    * ||            Bounding Box              || boundary height
174    * ||                                      ||
175    * |----------------------------------------|
176    * ------------------------------------------
177    *               boundary width
178    *
179    * @param[in] boundingBox Vector( x coordinate, y coordinate, width, height )
180    */
181   void SetBoundingBox(const Rect<int>& boundingBox);
182
183   /**
184    * @brief Retrieve the bounding box origin and dimensions.
185    *
186    * default is set once control is added to stage, before this the return vector will be Vector4:ZERO
187    * @param[out] boundingBox The bounding box origin, width and height.
188    */
189   void GetBoundingBox(Rect<int>& boundingBox) const;
190
191   /**
192    * @brief The decorator waits until a relayout before creating actors etc.
193    *
194    * @param[in] size The size of the parent control after size-negotiation.
195    */
196   void Relayout(const Dali::Vector2& size);
197
198   /**
199    * @brief Updates the decorator's actor positions after scrolling.
200    *
201    * @param[in] scrollOffset The scroll offset.
202    */
203   void UpdatePositions(const Vector2& scrollOffset);
204
205   /**
206    * @brief Sets which of the cursors are active.
207    *
208    * @note Cursor will only be visible if within the parent area.
209    * @param[in] activeCursor Which of the cursors should be active (if any).
210    */
211   void SetActiveCursor(ActiveCursor activeCursor);
212
213   /**
214    * @brief Query which of the cursors are active.
215    *
216    * @return  Which of the cursors are active (if any).
217    */
218   unsigned int GetActiveCursor() const;
219
220   /**
221    * @brief Sets the position of a cursor.
222    *
223    * @param[in] cursor The cursor to set.
224    * @param[in] x The x position relative to the top-left of the parent control.
225    * @param[in] y The y position relative to the top-left of the parent control.
226    * @param[in] cursorHeight The logical height of the cursor.
227    * @param[in] lineHeight The logical height of the line.
228    */
229   void SetPosition(Cursor cursor, float x, float y, float cursorHeight, float lineHeight);
230
231   /**
232    * @brief Retrieves the position, height and lineHeight of a cursor.
233    *
234    * @param[in] cursor The cursor to get.
235    * @param[out] x The x position relative to the top-left of the parent control.
236    * @param[out] y The y position relative to the top-left of the parent control.
237    * @param[out] cursorHeight The logical height of the cursor.
238    * @param[out] lineHeight The logical height of the line.
239    */
240   void GetPosition(Cursor cursor, float& x, float& y, float& cursorHeight, float& lineHeight) const;
241
242   /**
243    * @brief Retrieves the position of a cursor.
244    *
245    * @param[in] cursor The cursor to get.
246    *
247    * @return The position.
248    */
249   const Vector2& GetPosition(Cursor cursor) const;
250
251   /**
252    * @brief Sets the glyph offset of a cursor.
253    *
254    * @param[in] cursor The cursor to set.
255    * @param[in] glyphoffset The difference of line ascender and glyph ascender.
256    */
257   void SetGlyphOffset(Cursor cursor, float glyphOffset);
258
259   /**
260    * @brief Retrieves the glyph offset of a cursor.
261    *
262    * @param[in] cursor The cursor to get.
263    *
264    * @return The glyph offset. glyph offset means difference of line ascender and glyph ascender.
265    */
266   const float GetGlyphOffset(Cursor cursor) const;
267
268   /**
269    * @brief Sets the color for a cursor.
270    *
271    * @param[in] cursor Whether this color is for the primary or secondary cursor.
272    * @param[in] color The color to use.
273    */
274   void SetCursorColor(Cursor cursor, const Dali::Vector4& color);
275
276   /**
277    * @brief Retrieves the color for a cursor.
278    *
279    * @param[in] cursor Whether this color is for the primary or secondary cursor.
280    * @return The cursor color.
281    */
282   const Dali::Vector4& GetColor(Cursor cursor) const;
283
284   /**
285    * @brief Start blinking the cursor; see also SetCursorBlinkDuration().
286    */
287   void StartCursorBlink();
288
289   /**
290    * @brief Stop blinking the cursor.
291    */
292   void StopCursorBlink();
293
294   /**
295    * @brief Temporarily stops the cursor from blinking.
296    */
297   void DelayCursorBlink();
298
299   /**
300    * @brief Set the interval between cursor blinks.
301    *
302    * @param[in] seconds The interval in seconds.
303    */
304   void SetCursorBlinkInterval(float seconds);
305
306   /**
307    * @brief Retrieves the blink-interval for a cursor.
308    *
309    * @return The cursor blink-interval in seconds.
310    */
311   float GetCursorBlinkInterval() const;
312
313   /**
314    * @brief The cursor will stop blinking after this duration.
315    *
316    * @param[in] seconds The duration in seconds.
317    */
318   void SetCursorBlinkDuration(float seconds);
319
320   /**
321    * @brief Retrieves the blink-duration for a cursor.
322    *
323    * @return The cursor blink-duration in seconds.
324    */
325   float GetCursorBlinkDuration() const;
326
327   /**
328    * @brief Sets the width of the cursors.
329    *
330    * @param[in] width The width of the cursor in pixels.
331    */
332   void SetCursorWidth(int width);
333
334   /**
335    * @brief Retrieves the width of the cursors.
336    *
337    * @return The width of the cursors in pixels.
338    */
339   int GetCursorWidth() const;
340
341   /**
342    * @brief Sets whether a handle is active.
343    *
344    * @param[in] handleType One of the handles.
345    * @param[in] active True if the handle should be active.
346    */
347   void SetHandleActive(HandleType handleType,
348                        bool       active);
349
350   /**
351    * @brief Query whether a handle is active.
352    *
353    * @param[in] handleType One of the handles.
354    *
355    * @return True if the handle is active.
356    */
357   bool IsHandleActive(HandleType handleType) const;
358
359   /**
360    * @brief Sets the image file name for one of the handles.
361    *
362    * @param[in] handleType One of the handles.
363    * @param[in] handleImageType A different image can be set for the pressed/released states.
364    * @param[in] imageFileName The image filename to use.
365    */
366   void SetHandleImage(HandleType handleType, HandleImageType handleImageType, const std::string& imageFileName);
367
368   /**
369    * @brief Retrieves the file name of the image for one of the handles.
370    *
371    * @param[in] handleType One of the handles.
372    * @param[in] handleImageType A different image can be set for the pressed/released states.
373    *
374    * @return The grab handle image string.
375    */
376   const std::string& GetHandleImage(HandleType handleType, HandleImageType handleImageType) const;
377
378   /**
379    * @brief Sets the color of the handles
380    *
381    * @param[in] color The color to use.
382    */
383   void SetHandleColor(const Vector4& color);
384
385   /**
386    * @brief Retrieves the handles color.
387    *
388    * @return The color of the handles.
389    */
390   const Vector4& GetHandleColor() const;
391
392   /**
393    * @brief Sets the position of a selection handle.
394    *
395    * @param[in] handleType The handle to set.
396    * @param[in] x The x position relative to the top-left of the parent control.
397    * @param[in] y The y position relative to the top-left of the parent control.
398    * @param[in] lineHeight The logical line height at this position.
399    */
400   void SetPosition(HandleType handleType, float x, float y, float lineHeight);
401
402   /**
403    * @brief Retrieves the position of a selection handle.
404    *
405    * @param[in] handleType The handle to get.
406    * @param[out] x The x position relative to the top-left of the parent control.
407    * @param[out] y The y position relative to the top-left of the parent control.
408    * @param[out] lineHeight The logical line height at this position.
409    */
410   void GetPosition(HandleType handleType, float& x, float& y, float& lineHeight) const;
411
412   /**
413    * @brief Retrieves the position of a selection handle.
414    *
415    * @param[in] handleType The handle to get.
416    *
417    * @return The position of the selection handle relative to the top-left of the parent control.
418    */
419   const Vector2& GetPosition(HandleType handleType) const;
420
421   /**
422    * @brief Whether to flip vertically a handle.
423    *
424    * @param[in] handleType The handle to flip vertically.
425    * @param[in] flip Whether to flip vertically.
426    */
427   void FlipHandleVertically(HandleType handleType, bool flip);
428
429   /**
430    * @brief Retrieves whether the handle is vertically flipped.
431    *
432    * @param[in] handleType The handle to query.
433    *
434    * @return @e ture if the handle is vertically flipped.
435    */
436   bool IsHandleVerticallyFlipped(HandleType handleType) const;
437
438   /**
439    * @brief Whether to flip the selection handles as soon as they are crossed.
440    *
441    * By default they flip when the handle is released.
442    *
443    * @param[in] enable If @e true the selection handles will flip as soon as they are crossed.
444    */
445   void FlipSelectionHandlesOnCrossEnabled(bool enable);
446
447   /**
448    * @brief Sets info to calculate the handle flip state.
449    *
450    * Sets the character's direction where the handles are pointing.
451    * It resets the decorator internal flip state when there is a new selection.
452    *
453    * @param[in] indicesSwapped Whether the selection handle indices are swapped (start > end).
454    * @param[in] left The direction of the character pointed by the primary selection handle.
455    * @param[in] right The direction of the character pointed by the secondary selection handle.
456    */
457   void SetSelectionHandleFlipState(bool indicesSwapped, bool left, bool right);
458
459   /**
460    * @brief Adds a quad to the existing selection highlights. Vertices are in decorator's coordinates.
461    *
462    * @param[in] index Position in the vector where to add the quad.
463    * @param[in] quad The quad. The 'x' and 'y' coordinates store the min 'x' and min 'y'. The 'z' and 'w' coordinates store the max 'x' and max 'y'.
464    */
465   void AddHighlight(unsigned int index, const Vector4& quad);
466
467   /**
468    * @brief Sets the min 'x,y' coordinates and the size of the highlighted box.
469    *
470    * It's used to set the size and position of the highlight's actor and to translate each highlight quad from
471    * decorator's coordinates to the local coords of the highlight's actor.
472    *
473    * @param[in] position The position of the highlighted text in decorator's coords.
474    * @param[in] size The size of the highlighted text.
475    * @param[in] outlineOffset The outline's offset.
476    */
477   void SetHighLightBox(const Vector2& position,
478                        const Size&    size,
479                        float          outlineOffset);
480
481   /**
482    * @brief Removes all of the previously added highlights.
483    */
484   void ClearHighlights();
485
486   /**
487    * @brief Reserves space for the highlight quads.
488    *
489    * @param[in] numberOfQuads The expected number of quads.
490    */
491   void ResizeHighlightQuads(unsigned int numberOfQuads);
492
493   /**
494    * @brief Sets the selection highlight color.
495    *
496    * @param[in] color The color to use.
497    */
498   void SetHighlightColor(const Vector4& color);
499
500   /**
501    * @brief Retrieves the selection highlight color.
502    *
503    * @return The color of the highlight
504    */
505   const Vector4& GetHighlightColor() const;
506
507   /**
508    * @brief Sets whether the highlight is active.
509    *
510    * @param[in] active Whether the highlight is active.
511    */
512   void SetHighlightActive(bool active);
513
514   /**
515    * @brief Retrieves whether the highlight is active.
516    *
517    * @return @e true if the highlight is active, @e false otherwise.
518    */
519   bool IsHighlightActive() const;
520
521   /**
522    * @brief Retreives whether the highlight is shown or not.
523    *
524    * @return true if the highlight is visible, false otherwise.
525    */
526   bool IsHighlightVisible() const;
527
528   /**
529    * @brief Sets into the decorator the depth used to render the text.
530    *
531    * @param[in] depth The text's depth.
532    */
533   void SetTextDepth(int textDepth);
534
535   /**
536    * @brief Set the Selection Popup to show or hide via the active flaf
537    * @param[in] active true to show, false to hide
538    */
539   void SetPopupActive(bool active);
540
541   /**
542    * @brief Query whether the Selection Popup is active.
543    *
544    * @return True if the Selection Popup should be active.
545    */
546   bool IsPopupActive() const;
547
548   /**
549    * @brief Set a bit mask of the buttons to be shown by Popup
550    * @param[in] enabledButtonsBitMask from TextSelectionPopup::Buttons enum
551    */
552   void SetEnabledPopupButtons(TextSelectionPopup::Buttons& enabledButtonsBitMask);
553
554   /**
555    * @brief Get the current bit mask of buttons to be shown by Popup
556    * @return bitmask of TextSelectionPopup::Buttons
557    */
558   TextSelectionPopup::Buttons& GetEnabledPopupButtons();
559
560   /**
561    * @brief Sets the scroll threshold.
562    *
563    * It defines a square area inside the control, close to the edge.
564    * When the cursor enters this area, the decorator starts to send scroll events.
565    *
566    * @param[in] threshold The scroll threshold in pixels.
567    */
568   void SetScrollThreshold(float threshold);
569
570   /**
571    * @brief Retrieves the scroll threshold.
572    *
573    * @retunr The scroll threshold in pixels.
574    */
575   float GetScrollThreshold() const;
576
577   /**
578    * @brief Sets the scroll speed.
579    *
580    * Is the distance the text is going to be scrolled during a scroll interval.
581    *
582    * @param[in] speed The scroll speed in pixels/second.
583    */
584   void SetScrollSpeed(float speed);
585
586   /**
587    * @brief Sets Editable mode decoration.
588    *
589    * If this set to false, Primary cursor and grab will always be hidden.
590    *
591    * @param[in] isEditable enable or disable Editing.
592    */
593   void SetEditable(bool isEditable);
594
595   /**
596    * @brief Retrieves the scroll speed.
597    *
598    * @return The scroll speed in pixels/second.
599    */
600   float GetScrollSpeed() const;
601
602   /**
603    * @brief Notifies the decorator the whole text has been scrolled.
604    */
605   void NotifyEndOfScroll();
606
607   /**
608    * @copydoc Text::Controller::SetHorizontalScrollEnabled()
609    */
610   void SetHorizontalScrollEnabled(bool enable);
611
612   /**
613    * @copydoc Text::Controller::IsHorizontalScrollEnabled()
614    */
615   bool IsHorizontalScrollEnabled() const;
616
617   /**
618    * @copydoc Text::Controller::SetVerticalScrollEnabled()
619    */
620   void SetVerticalScrollEnabled(bool enable);
621
622   /**
623    * @copydoc Text::Controller::IsVerticalScrollEnabled()
624    */
625   bool IsVerticalScrollEnabled() const;
626
627   /**
628    * @copydoc Text::Controller::SetSmoothHandlePanEnabled()
629    */
630   void SetSmoothHandlePanEnabled(bool enable);
631
632   /**
633    * @copydoc Text::Controller::IsSmoothHandlePanEnabled()
634    */
635   bool IsSmoothHandlePanEnabled() const;
636
637 protected:
638   /**
639    * @brief A reference counted object may only be deleted by calling Unreference().
640    */
641   virtual ~Decorator();
642
643 private:
644   /**
645    * @brief Private constructor.
646    * @param[in] controller The controller which receives input events from Decorator components.
647    * @param[in] callbackInterface The text popup callback interface which receives the button click callbacks.
648    */
649   Decorator(ControllerInterface&                 controller,
650             TextSelectionPopupCallbackInterface& callbackInterface);
651
652   // Undefined
653   Decorator(const Decorator& handle);
654
655   // Undefined
656   Decorator& operator=(const Decorator& handle);
657
658 private:
659   struct Impl;
660   Impl* mImpl;
661 };
662 } // namespace Text
663
664 } // namespace Toolkit
665
666 } // namespace Dali
667
668 #endif // DALI_TOOLKIT_TEXT_DECORATOR_H