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