Shortcut check for markup in a string, before attempting to parse and split the strin...
[platform/core/uifw/dali-toolkit.git] / capi / dali-toolkit / public-api / controls / text-view / text-view.h
1 #ifndef __DALI_TOOLKIT_TEXT_VIEW_H__
2 #define __DALI_TOOLKIT_TEXT_VIEW_H__
3
4 //
5 // Copyright (c) 2014 Samsung Electronics Co., Ltd.
6 //
7 // Licensed under the Flora License, Version 1.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://floralicense.org/license/
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  * @addtogroup CAPI_DALI_TOOLKIT_TEXT_VIEW_MODULE
22  * @{
23  */
24
25 // EXTERNAL INCLUDES
26 #include <string>
27
28 // INTERNAL INCLUDES
29 #include <dali-toolkit/public-api/controls/alignment/alignment.h>
30 #include <dali-toolkit/public-api/markup-processor/markup-processor.h>
31
32 namespace Dali DALI_IMPORT_API
33 {
34
35 namespace Toolkit
36 {
37
38 namespace Internal DALI_INTERNAL
39 {
40 class TextView;
41 }
42
43 /**
44  * @brief TextView is a layout container for text with alignment, multi-line wrapping and formatting support.
45  *
46  * Different multi-line and exceed policies could be chosen to represent the given text.
47  * \see Toolkit::TextView::SetMultilinePolicy \see Toolkit::TextView::SetExceedPolicy
48  *
49  * Multi-line policies:
50  * <ul>
51  *   <li>\e Split by new line character.
52  *          Text will split when a '\\n' character is found.
53  *
54  *   <li>\e Split by word.
55  *          Text will split when a '\\n' character is found or if the text doesn't fit in the text view width.
56  *          In that case, some words will be moved to a new line.
57  *
58  *   <li>\e Split by character.
59  *          Text will split when a '\\n' character is found or if the text doesn't fit in the text view width.
60  *          In that case, words which doesn't fit will be split in two and the remaining text moved to a new line.
61  * </ul>
62  *
63  * Exceed policies work in combination with multi-line policies:
64  * <ul>
65  *   <li>\e Original size.
66  *          Text will be displayed with its original size.
67  *
68  *   <li>\e Truncate.
69  *          Text will be truncated.
70  *
71  *   <li>\e Fade.
72  *          Text will be faded out.
73  *
74  *   <li>\e Split.
75  *          Text will be split and moved to a new line.
76  *
77  *   <li>\e Shrink to fit.
78  *          Text will be shrink to fit in the text view's boundary.
79  *
80  *   <li>\e EllipsizeEnd.
81  *          Text will be ellipsized at the end.
82  *
83  * </ul>
84  *
85  * Text alignment could be set to align the whole text block inside the text view's boundary. \see Toolkit::TextView::SetTextAlignment.
86  *
87  * Line justification could be set to align lines inside a text block. \see Toolkit::TextView::SetLineJustification.
88  *
89  * A default font could be set through the \see Toolkit::TextView::SetFont method. If any font is set, text view automatically detects a suitable font for every character.
90  *
91  * Font priority:
92  * 1) Use the font specified in text decoration.
93  * 2) Use automatic font detection.
94  *
95  * Integration with other classes (GetSizeAndPositionTable )
96  *
97  * Text decoration ( Color, Font, Size, italic and all features supported in TextActor )
98  */
99 class TextView : public Control
100 {
101 public:
102
103   // Signal Names
104   static const char* const SIGNAL_TEXT_SCROLLED; ///< Signal emitted when the scroll position changes. @see SignalScrolled()
105
106   /**
107    * @brief Structure used to retrieve Layout info per character.
108    */
109   struct CharacterLayoutInfo
110   {
111     /**
112      * @brief Default constructor.
113      *
114      * Initializes all members to their default values.
115      */
116     CharacterLayoutInfo();
117
118     /**
119      * @brief Empty destructor.
120      *
121      * @note Added to increase coverage.
122      */
123     ~CharacterLayoutInfo();
124
125     /**
126      * @brief Copy constructor.
127      */
128     CharacterLayoutInfo( const CharacterLayoutInfo& characterLayoutInfo );
129
130     /**
131      * @brief Assignment operator.
132      */
133     CharacterLayoutInfo& operator=( const CharacterLayoutInfo& character );
134
135     /**
136      * @brief Constructor.
137      *
138      * @param[in] size of the character.
139      * @param[in] position of the character.
140      * @param[in] isNewLineChar Whether the character is a new line character.
141      * @param[in] isRightToLeftCharacter Whether is a right to left character.
142      * @param[in] visible Whether is visible.
143      * @param[in] descender of the character (distance from the base line to the bottom of the character.)
144      */
145     CharacterLayoutInfo( const Size& size,
146                          const Vector3& position,
147                          bool isNewLineChar,
148                          bool isRightToLeftCharacter,
149                          bool visible,
150                          float descender );
151
152     Size    mSize;                     ///< Size of the group of characters.
153     Vector3 mPosition;                 ///< Position of the group of characters within the text view.
154     bool    mIsNewLineChar:1;          ///< Whether this group of characters represent a new line.
155     bool    mIsRightToLeftCharacter:1; ///< Whether it's a right-to-left character.
156     bool    mIsVisible:1;              ///< Whether this group of characters is visible or not.
157     float   mDescender;                ///< The character's descender which is the distance from the baseline to the bottom of the character
158   };
159
160   typedef std::vector<CharacterLayoutInfo> CharacterLayoutInfoContainer; ///< Container of Character layouts
161
162   /**
163    * @brief Stores some info about a laid-out line.
164    */
165   struct LineLayoutInfo
166   {
167     std::size_t mCharacterGlobalIndex; ///< Global index within the whole text of the first character of current laid-out line.
168     Size        mSize;                 ///< Size of the current laid-out line.
169     float       mAscender;             ///< The max ascender of the current laid-out line.
170   };
171
172   typedef std::vector<LineLayoutInfo> LineLayoutInfoContainer; ///< Container of line layouts
173
174   /**
175    * @brief How text is laid out.
176    */
177   struct TextLayoutInfo
178   {
179     /**
180      * @brief Default constructor.
181      */
182     TextLayoutInfo();
183
184     /**
185      * @brief Empty destructor.
186      *
187      * @note Added to increase coverage.
188      */
189     ~TextLayoutInfo();
190
191     /**
192      * @brief Copy constructor.
193      */
194     TextLayoutInfo( const TextLayoutInfo& textLayoutInfo );
195
196     /**
197      * @brief Assignment operator.
198      */
199     TextLayoutInfo& operator=( const TextLayoutInfo& textLayoutInfo );
200
201     CharacterLayoutInfoContainer mCharacterLayoutInfoTable;    ///< The table of character positions and sizes sorted by the characters' visual index.
202     LineLayoutInfoContainer      mLines;                       ///< For each laid-out line, it stores an index to the first character of the line.
203     std::vector<int>             mCharacterLogicalToVisualMap; ///< The map to store the character's logical (input) index according to its visual (reordered) index.
204     std::vector<int>             mCharacterVisualToLogicalMap; ///< The map to store the character's visual (reordered) index according to its logical (input) index.
205     Size                         mTextSize;                    ///< Text size after relayout.
206     Vector2                      mScrollOffset;                ///< Scroll's position.
207   };
208
209   /**
210    * @brief This structure represents a fade boundary.
211    *
212    * If Exceed policy is set to Fade all text which does not fit within the text-view fade boundary is faded out. Text which exceeds the text-view boundary becomes invisible.
213    * The \e left, \e right, \e top and \e bottom values are positive, in pixels and set the distances between the text-view and fade boundaries.
214    */
215   struct FadeBoundary
216   {
217     /**
218      * @brief Default constructor.
219      *
220      * Initializes all values to 0. It means no fade boundary.
221      */
222     FadeBoundary();
223
224     /**
225      * @brief Constructor.
226      *
227      * Initializes the fade boundary with the given values.
228      *
229      * @param[in] left value in pixels.
230      * @param[in] right value in pixels.
231      * @param[in] top value in pixels.
232      * @param[in] bottom value in pixels.
233      */
234     FadeBoundary( PixelSize left, PixelSize right, PixelSize top, PixelSize bottom );
235
236     PixelSize mLeft;   ///< The left fade boundary
237     PixelSize mRight;  ///< The right fade boundary
238     PixelSize mTop;    ///< The top fade boundary
239     PixelSize mBottom; ///< The bottom fade bounday
240   };
241
242   /**
243    * @brief Define how to split the text in lines.
244    *
245    * SplitByNewLineChar will split the text in lines when a '\\n' character is found.
246    * SplitByWord has effect only when TextView size is assigned.
247    * It will split the text in lines when a '\\n' character is found or if a line exceeds the TextView's boundary. This option won't split a word in two.
248    * SplitByChar has effect only when TextView size is assigned.
249    * It will split the text in lines when a '\\n' character is found or if a line exceeds the TextView's boundary. This option might split a word in two.
250    * The default value is SplitByNewLineChar.
251    */
252   enum MultilinePolicy
253   {
254     SplitByNewLineChar, ///< Text lines will split when '\\n' character is found.
255     SplitByWord,        ///< Text lines will split by word or if '\\n' character is found. It has effect only when TextView size is assigned.
256     SplitByChar         ///< Text lines will split by char or if '\\n' character is found. It has effect only when TextView size is assigned.
257   };
258
259   /**
260    * @brief Define how to display the text when it doesn't fit inside the TextView.
261    *
262    * The default value is ShrinkToFit.
263    */
264   enum ExceedPolicy
265   {
266     Original,         ///< Will display the text in its original size. If a line, a word or a character is bigger than the TextView size it may exceed its boundary.
267     Truncate,         ///< Will display the text in its original size. It won't display the text which exceeds the TextView boundary.
268     Fade,             ///< Will display the text in its original size. It won't display the text which exceeds the TextView boundary. It fades the text out.
269     Split,            ///< Will split the text in a new line.
270     ShrinkToFit,      ///< Will shrink the text to fit the TextView boundary.
271     EllipsizeEnd      ///< Will ellipsize the text by the end.
272   };
273
274   /**
275    * @brief Define how to justify lines inside the text area.
276    *
277    * The default value is Left.
278    */
279   enum LineJustification
280   {
281     Left,     ///< Justify to the left.
282     Center,   ///< Centered.
283     Right,    ///< Justify to the right.
284     Justified ///< Line justified.
285   };
286
287 public:
288   /**
289    * @brief Create an TextView handle; this can be initialised with TextView::New().
290    *
291    * Calling member functions with an uninitialised Dali::Object handle is not allowed.
292    */
293   TextView();
294
295   /**
296    * @brief Copy constructor.
297    *
298    * Creates another handle that points to the same real object
299    * @param[in] handle The handle to copy from
300    */
301   TextView( const TextView& handle );
302
303   /**
304    * @brief Assignment operator.
305    *
306    * Changes this handle to point to another real object
307    * @param[in] handle The handle to copy from
308    * @return a reference to this
309    */
310   TextView& operator=( const TextView& handle );
311
312   /**
313    * @brief Create a TextView control with no text.
314    *
315    * @return A handle the TextView control.
316    */
317   static TextView New();
318
319   /**
320    * @brief Create a TextView control.
321    *
322    * @param[in] text to display.
323    * @return A handle the TextView control.
324    */
325   static TextView New( const std::string& text );
326
327   /**
328    * @copydoc TextView New( const std::string& text )
329    */
330   static TextView New( const MarkupProcessor::StyledTextArray& text );
331
332   /**
333    * @brief Downcast an Object handle to TextView.
334    *
335    * If handle points to a TextView the
336    * downcast produces valid handle. If not the returned handle is left uninitialized.
337    * @param[in] handle Handle to an object
338    * @return handle to a TextView or an uninitialized handle
339    */
340   static TextView DownCast( BaseHandle handle );
341
342   /**
343    * @brief Virtual destructor.
344    *
345    * Dali::Object derived classes typically do not contain member data.
346    */
347   virtual ~TextView();
348
349   /**
350    * @brief Replace the current text with a new text string.
351    *
352    * @param[in] text to display. The string may contain style tags.
353    */
354   void SetText( const std::string& text );
355
356   /**
357    * @brief Replace the current text with a new text string with style.
358    *
359    * @param[in] text with style to display.
360    */
361   void SetText( const MarkupProcessor::StyledTextArray& text );
362
363   /**
364    * @brief Inserts the given text in the specified position.
365    *
366    * @param[in] position Where the given text is going to be added.
367    * @param[in] text The text to be added.
368    */
369   void InsertTextAt( std::size_t position, const std::string& text );
370
371   /**
372    * @copydoc InsertTextAt( std::size_t position, const std::string& text )
373    */
374   void InsertTextAt( std::size_t position, const MarkupProcessor::StyledTextArray& text );
375
376   /**
377    * @brief Replaces part of the text.
378    *
379    * It removes the specified number of characters from the given position and inserts the given text in the same specified position.
380    *
381    * @param[in] position of the first character to be removed and Where the given text is going to be added.
382    * @param[in] numberOfCharacters number of characters to be removed.
383    * @param[in] text The text to be added.
384    */
385   void ReplaceTextFromTo( std::size_t position, std::size_t numberOfCharacters, const std::string& text );
386
387   /**
388    * @copydoc ReplaceTextFromTo( std::size_t position, std::size_t numberOfCharacters, const std::string& text )
389    */
390   void ReplaceTextFromTo( std::size_t position, std::size_t numberOfCharacters, const MarkupProcessor::StyledTextArray& text );
391
392   /**
393    * @brief Removes the specified number of characters from the given position.
394    *
395    * @param[in] position of the first character to be removed.
396    * @param[in] numberOfCharacters number of characters to be removed.
397    */
398   void RemoveTextFrom( std::size_t position, std::size_t numberOfCharacters );
399
400   /**
401    * @brief Get the currently displayed text.
402    *
403    * @return The currently displayed text.
404    */
405   std::string GetText() const;
406
407   /**
408    * @brief Sets a line height offset.
409    *
410    * The line height offset will be added to the font line height.
411    * @param [in] offset The height offset in PointSize units.
412    */
413   void SetLineHeightOffset( PointSize offset );
414
415   /**
416    * @brief Retrieves the line height offset.
417    *
418    * @return The line height offset in PointSize units.
419    */
420   PointSize GetLineHeightOffset() const;
421
422   /**
423    * @brief Sets the given style to the current text.
424    *
425    * By default all style settings are applied but a bit mask could be used to modify only certain style settings.
426    * @note TextView doesn't store a copy of the given style, it applies the given style to the current text only.
427    * Subsequent calls to SetText() will override any style set by this method.
428    * @param[in] style The given style
429    * @param[in] mask The bit mask.
430    */
431   void SetStyleToCurrentText( const TextStyle& style, TextStyle::Mask mask = TextStyle::ALL );
432
433   /**
434    * @brief Set the current text alignment.
435    *
436    * Default alignment is (HorizontalCenter | VerticalCenter)
437    * @param[in] align The new alignment option.
438    */
439   void SetTextAlignment( Alignment::Type align );
440
441   /**
442    * @brief Get the current text alignment combined into a single value.
443    *
444    * The values can be tested by using the & operator
445    * and the desired flag. e.g. if (GetTextAlignment() & HorizontalCentre) ...
446    * @return the combined alignment
447    */
448   Alignment::Type GetTextAlignment() const;
449
450   /**
451    * @brief Sets how to split the text in lines policy.
452    *
453    * @param policy The multi-line policy. SplitByNewLineChar is set by default.
454    */
455   void SetMultilinePolicy( MultilinePolicy policy );
456
457   /**
458    * @brief Gets the split in lines policy.
459    *
460    * @return The multi-line policy.
461    */
462   MultilinePolicy GetMultilinePolicy() const;
463
464   /**
465    * @brief Sets how to display the text inside the TextView when it exceeds the text-view's width.
466    *
467    * @param policy The exceed policy. Original is set by default.
468    */
469   void SetWidthExceedPolicy( ExceedPolicy policy );
470
471   /**
472    * @brief Gets the width exceed policy.
473    *
474    * @return The exceed policy.
475    */
476   ExceedPolicy GetWidthExceedPolicy() const;
477
478   /**
479    * @brief Sets how to display the text inside the TextView when it exceeds the text-view's height.
480    *
481    * @param policy The exceed policy. Original is set by default.
482    */
483   void SetHeightExceedPolicy( ExceedPolicy policy );
484
485   /**
486    * @brief Gets the height exceed policy.
487    *
488    * @return The exceed policy.
489    */
490   ExceedPolicy GetHeightExceedPolicy() const;
491
492   /**
493    * @brief Sets how to justify lines inside the text area.
494    *
495    * @param justification The line justification. Left is set by default.
496    */
497   void SetLineJustification( LineJustification justification );
498
499   /**
500    * @brief Gets the line justification.
501    *
502    * @return The line justification.
503    */
504   LineJustification GetLineJustification() const;
505
506   /**
507    * @brief Sets a fade boundary.
508    *
509    * @see FadeBoundary.
510    *
511    * @param[in] fadeBoundary The given fade boundary.
512    */
513   void SetFadeBoundary( const FadeBoundary& fadeBoundary );
514
515   /**
516    * @brief Retrieves the fade boundary.
517    *
518    * @see FadeBoundary.
519    *
520    * @return The fade boundary.
521    */
522   const FadeBoundary& GetFadeBoundary() const;
523
524   /**
525    * @brief Sets the ellipsize text.
526    *
527    * @param[in] ellipsizeText The new text. The string may contain style tags. By default the ellipsize text is '...'
528    */
529   void SetEllipsizeText( const std::string& ellipsizeText );
530
531   /**
532    * @brief Sets the ellipsize text.
533    *
534    * @param[in] ellipsizeText The new text with its style.
535    */
536   void SetEllipsizeText( const MarkupProcessor::StyledTextArray& ellipsizeText );
537
538   /**
539    * @brief Retrieves the ellipsize text.
540    *
541    * @return The ellipsize text.
542    */
543   std::string GetEllipsizeText() const;
544
545   /**
546    * @brief A mechanism to retrieve layout information from the TextView.
547    *
548    * It produces a vector of CharcterLayoutInfo structures which describe the size and position of each character,
549    * two vectors which maps the logical and visual positions of the characters in a bidirectional text, the size
550    * of the whole laid-out text and the scroll offset value.
551    *
552    * @see TextLayoutInfo.
553    *
554    * @param[out] textLayoutInfo A structure with text layout information.
555    */
556   void GetTextLayoutInfo( TextLayoutInfo& textLayoutInfo );
557
558   /**
559    * @brief Allows modification of text-actor's position in the depth sort algorithm.
560    *
561    * @see Dali::RenderableActor::SetSortModifier()
562    * @param [in] depthOffset the offset to be given to the internal text-actors. Positive values pushing it further back.
563    */
564   void SetSortModifier( float depthOffset );
565
566   /**
567    * @brief Sets whether text-view renders text using a previously generated snapshot.
568    *
569    * Rendering long text using a snapshot may increase performance. The default value is \e true (render using a snapshot).
570    *
571    * @param[in] enable Whether text-view is using a snapshot to render text.
572    */
573   void SetSnapshotModeEnabled( bool enable );
574
575   /**
576    * @brief Retrieves whether text-view is using a snapshot to render text.
577    *
578    * @return \e true if text-view is using a snapshot to render text, otherwhise it returns \e false.
579    */
580   bool IsSnapshotModeEnabled() const;
581
582   /**
583    * @brief Sets whether markup processing should be carried out.
584    *
585    * @param[in] enable whether markup processing is carried out or not.
586    */
587   void SetMarkupProcessingEnabled( bool enable );
588
589   /**
590    * @brief Retrieves whether text-view is processing markup text
591    *
592    * @return \e true if text-view markup processing is enabled, otherwhise it returns \e false.
593    */
594   bool IsMarkupProcessingEnabled() const;
595
596   /**
597    * @brief Enables or disables the text scroll.
598    *
599    * When scroll is enabled, snapshot mode will be enabled automatically. Equally, if scroll is disabled
600    * the snapshot mode is restored to the previous value.
601    *
602    * @param[in] enable Whether to enable the text scroll.
603    */
604   void SetScrollEnabled( bool enable );
605
606   /**
607    * @brief Retrieves whether the text scroll is enabled.
608    *
609    * @return \e true if the scroll is enabled.
610    */
611   bool IsScrollEnabled() const;
612
613   /**
614    * @brief Sets a new scroll position.
615    *
616    * The new scroll position set could be trimmed if the text doesn't cover the whole text-view.
617    * i.e. If a text-view is 100x100 and a text is 200x100 a scroll position beyond 50x0 will be trimmed to 50x0.
618    *
619    * Call IsScrollPositionTrimmed() to know if the last scroll position set has been trimmed.
620    *
621    * A signal is emitted. @see ScrolledSignal().
622    *
623    * @param[in] position The new scroll position.
624    */
625   void SetScrollPosition( const Vector2& position );
626
627   /**
628    * @brief Recrieves current scroll position.
629    *
630    * @return The scroll position.
631    */
632   const Vector2& GetScrollPosition() const;
633
634   /**
635    * @brief Whether the last scroll position set was trimmed.
636    *
637    * @return \e true if the last scroll position set was trimmed, otherwise \e false.
638    */
639   bool IsScrollPositionTrimmed() const;
640
641 public:
642   /// @brief Signal types
643   typedef SignalV2< void ( TextView textView, Vector2 scrollDelta ) > ScrolledSignalV2;
644
645   /**
646    * @brief Signal emitted when the scroll position changes.
647    *
648    * A callback with the following prototype can be connected to this signal.
649    *
650    * Callback(TextView textView, Vector2 scrollDelta)
651    *
652    * \e textView is the handle of the text-view emitting the signal.
653    * \e scrollDelta is the differente of the current scroll position with the previous one.
654    * @return The signal to connect to
655    */
656   ScrolledSignalV2& ScrolledSignal();
657
658 public: // Not intended for application developers
659
660   /**
661    * @brief Creates a handle using the Toolkit::Internal implementation.
662    *
663    * @param[in]  implementation  The Control implementation.
664    */
665   TextView( Internal::TextView& implementation );
666
667   /**
668    * @brief Allows the creation of this Control from an Internal::CustomActor pointer.
669    *
670    * @param[in]  internal  A pointer to the internal CustomActor.
671    */
672   TextView( Dali::Internal::CustomActor* internal );
673 };
674
675 } // namespace Toolkit
676
677 } // namespace Dali
678
679 /**
680  * @}
681  */
682 #endif // __DALI_TOOLKIT_ITEM_VIEW_H__