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