Merge "Show CopyPaste Poup on long press" into devel/master
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / text / text-controller.h
1 #ifndef __DALI_TOOLKIT_TEXT_CONTROLLER_H__
2 #define __DALI_TOOLKIT_TEXT_CONTROLLER_H__
3
4 /*
5  * Copyright (c) 2015 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 <string>
23 #include <dali/devel-api/adaptor-framework/imf-manager.h>
24 #include <dali/public-api/common/dali-vector.h>
25 #include <dali/public-api/common/intrusive-ptr.h>
26 #include <dali/public-api/events/gesture.h>
27 #include <dali/public-api/events/key-event.h>
28 #include <dali/public-api/math/vector3.h>
29 #include <dali/public-api/math/vector2.h>
30 #include <dali/public-api/object/ref-object.h>
31
32 // INTERNAL INCLUDES
33 #include <dali-toolkit/devel-api/controls/text-controls/text-selection-popup-callback-interface.h>
34 #include <dali-toolkit/internal/text/decorator/text-decorator.h>
35 #include <dali-toolkit/internal/text/font-run.h>
36 #include <dali-toolkit/internal/text/layouts/layout-engine.h>
37 #include <dali-toolkit/internal/text/text-control-interface.h>
38 #include <dali-toolkit/internal/text/text-view.h>
39
40 namespace Dali
41 {
42
43 namespace Toolkit
44 {
45
46 namespace Text
47 {
48
49 class Controller;
50 class LayoutEngine;
51
52 typedef IntrusivePtr<Controller> ControllerPtr;
53 typedef Dali::Toolkit::Text::ControlInterface ControlInterface;
54
55 /**
56  * @brief Different placeholder-text can be shown when the control is active/inactive.
57  */
58 enum PlaceholderType
59 {
60   PLACEHOLDER_TYPE_ACTIVE,
61   PLACEHOLDER_TYPE_INACTIVE,
62 };
63
64 /**
65  * @brief A Text Controller is used by UI Controls which display text.
66  *
67  * It manipulates the Logical & Visual text models on behalf of the UI Controls.
68  * It provides a view of the text that can be used by rendering back-ends.
69  *
70  * For selectable/editable UI controls, the controller handles input events from the UI control
71  * and decorations (grab handles etc) via the Decorator::ControllerInterface interface.
72  *
73  * The text selection popup button callbacks are as well handled via the TextSelectionPopupCallbackInterface interface.
74  */
75 class Controller : public RefObject, public Decorator::ControllerInterface, public TextSelectionPopupCallbackInterface
76 {
77 public:
78
79   /**
80    * @brief Text related operations to be done in the relayout process.
81    */
82   enum OperationsMask
83   {
84     NO_OPERATION       = 0x0000,
85     CONVERT_TO_UTF32   = 0x0001,
86     GET_SCRIPTS        = 0x0002,
87     VALIDATE_FONTS     = 0x0004,
88     GET_LINE_BREAKS    = 0x0008,
89     GET_WORD_BREAKS    = 0x0010,
90     BIDI_INFO          = 0x0020,
91     SHAPE_TEXT         = 0x0040,
92     GET_GLYPH_METRICS  = 0x0080,
93     LAYOUT             = 0x0100,
94     UPDATE_ACTUAL_SIZE = 0x0200,
95     REORDER            = 0x0400,
96     ALIGN              = 0x0800,
97     ALL_OPERATIONS     = 0xFFFF
98   };
99
100   /**
101    * @brief Used to distinguish between regular key events and IMF events
102    */
103   enum InsertType
104   {
105     COMMIT,
106     PRE_EDIT
107   };
108
109   /**
110    * @brief Create a new instance of a Controller.
111    *
112    * @param[in] controlInterface An interface used to request a text relayout.
113    * @return A pointer to a new Controller.
114    */
115   static ControllerPtr New( ControlInterface& controlInterface );
116
117   /**
118    * @brief Called to enable text input.
119    *
120    * @note Selectable or editable controls should call this once after Controller::New().
121    * @param[in] decorator Used to create cursor, selection handle decorations etc.
122    */
123   void EnableTextInput( DecoratorPtr decorator );
124
125   /**
126    * @brief Replaces any text previously set.
127    *
128    * @note This will be converted into UTF-32 when stored in the text model.
129    * @param[in] text A string of UTF-8 characters.
130    */
131   void SetText( const std::string& text );
132
133   /**
134    * @brief Retrieve any text previously set.
135    *
136    * @return A string of UTF-8 characters.
137    */
138   void GetText( std::string& text ) const;
139
140   /**
141    * @brief Remove a given number of characters
142    *
143    * @param[in] cursorOffset Start position from the current cursor position to start deleting characters.
144    * @param[in] numberOfChars The number of characters to delete from the cursorOffset.
145    * @return True if the remove was successful.
146    */
147   bool RemoveText( int cursorOffset, int numberOfChars );
148
149   /**
150    * @brief Retrieve the current cursor position.
151    *
152    * @return The cursor position.
153    */
154   unsigned int GetLogicalCursorPosition() const;
155
156   /**
157    * @brief Replaces any placeholder text previously set.
158    *
159    * @param[in] type Different placeholder-text can be shown when the control is active/inactive.
160    * @param[in] text A string of UTF-8 characters.
161    */
162   void SetPlaceholderText( PlaceholderType type, const std::string& text );
163
164   /**
165    * @brief Retrieve any placeholder text previously set.
166    *
167    * @param[in] type Different placeholder-text can be shown when the control is active/inactive.
168    * @param[out] A string of UTF-8 characters.
169    */
170   void GetPlaceholderText( PlaceholderType type, std::string& text ) const;
171
172   /**
173    * @brief Sets the maximum number of characters that can be inserted into the TextModel
174    *
175    * @param[in] maxCharacters maximum number of characters to be accepted
176    */
177   void SetMaximumNumberOfCharacters( int maxCharacters );
178
179   /**
180    * @brief Sets the maximum number of characters that can be inserted into the TextModel
181    *
182    * @param[in] maxCharacters maximum number of characters to be accepted
183    */
184   int GetMaximumNumberOfCharacters();
185
186   /**
187    * @brief Set the default font family.
188    *
189    * @param[in] defaultFontFamily The default font family.
190    */
191   void SetDefaultFontFamily( const std::string& defaultFontFamily );
192
193   /**
194    * @brief Retrieve the default font family.
195    *
196    * @return The default font family.
197    */
198   const std::string& GetDefaultFontFamily() const;
199
200   /**
201    * @brief Set the default font style.
202    *
203    * @param[in] defaultFontStyle The default font style.
204    */
205   void SetDefaultFontStyle( const std::string& defaultFontStyle );
206
207   /**
208    * @brief Retrieve the default font style.
209    *
210    * @return The default font style.
211    */
212   const std::string& GetDefaultFontStyle() const;
213
214   /**
215    * @brief Set the default point size.
216    *
217    * @param[in] defaultFontStyle The default point size.
218    */
219   void SetDefaultPointSize( float pointSize );
220
221   /**
222    * @brief Retrieve the default point size.
223    *
224    * @return The default point size.
225    */
226   float GetDefaultPointSize() const;
227
228   /**
229    * @brief Set the text color
230    *
231    * @param textColor The text color
232    */
233   void SetTextColor( const Vector4& textColor );
234
235   /**
236    * @brief Retrieve the text color
237    *
238    * @return The text color
239    */
240   const Vector4& GetTextColor() const;
241
242   /**
243    * @brief Set the text color
244    *
245    * @param textColor The text color
246    */
247   void SetPlaceholderTextColor( const Vector4& textColor );
248
249   /**
250    * @brief Retrieve the text color
251    *
252    * @return The text color
253    */
254   const Vector4& GetPlaceholderTextColor() const;
255
256   /**
257    * @brief Set the shadow offset.
258    *
259    * @param[in] shadowOffset The shadow offset, 0,0 indicates no shadow.
260    */
261   void SetShadowOffset( const Vector2& shadowOffset );
262
263   /**
264    * @brief Retrieve the shadow offset.
265    *
266    * @return The shadow offset.
267    */
268   const Vector2& GetShadowOffset() const;
269
270   /**
271    * @brief Set the shadow color.
272    *
273    * @param[in] shadowColor The shadow color.
274    */
275   void SetShadowColor( const Vector4& shadowColor );
276
277   /**
278    * @brief Retrieve the shadow color.
279    *
280    * @return The shadow color.
281    */
282   const Vector4& GetShadowColor() const;
283
284   /**
285    * @brief Set the underline color.
286    *
287    * @param[in] color color of underline.
288    */
289   void SetUnderlineColor( const Vector4& color );
290
291   /**
292    * @brief Retrieve the underline color.
293    *
294    * @return The underline color.
295    */
296   const Vector4& GetUnderlineColor() const;
297
298   /**
299    * @brief Set the underline enabled flag.
300    *
301    * @param[in] enabled The underline enabled flag.
302    */
303   void SetUnderlineEnabled( bool enabled );
304
305   /**
306    * @brief Returns whether the text is underlined or not.
307    *
308    * @return The underline state.
309    */
310   bool IsUnderlineEnabled() const;
311
312   /**
313    * @brief Set the override used for underline height, 0 indicates height will be supplied by font metrics
314    *
315    * @param[in] height The height in pixels of the underline
316    */
317   void SetUnderlineHeight( float height );
318
319   /**
320    * @brief Retrieves the override height of an underline, 0 indicates height is supplied by font metrics
321    *
322    * @return The height of the underline, or 0 if height is not overrided.
323    */
324   float GetUnderlineHeight() const;
325
326   /**
327    * @brief Called to enable/disable cursor blink.
328    *
329    * @note Only editable controls should calls this.
330    * @param[in] enabled Whether the cursor should blink or not.
331    */
332   void SetEnableCursorBlink( bool enable );
333
334   /**
335    * @brief Query whether cursor blink is enabled.
336    *
337    * @return Whether the cursor should blink or not.
338    */
339   bool GetEnableCursorBlink() const;
340
341   /**
342    * @brief Query the current scroll position; the UI control is responsible for moving actors to this position.
343    *
344    * @return The scroll position.
345    */
346   const Vector2& GetScrollPosition() const;
347
348   /**
349    * @brief Query the alignment offset.
350    *
351    * @return The alignmnet offset.
352    */
353   const Vector2& GetAlignmentOffset() const;
354
355   /**
356    * @copydoc Control::GetNaturalSize()
357    */
358   Vector3 GetNaturalSize();
359
360   /**
361    * @copydoc Control::GetHeightForWidth()
362    */
363   float GetHeightForWidth( float width );
364
365   /**
366    * @brief Triggers a relayout which updates View (if necessary).
367    *
368    * @note UI Controls are expected to minimize calls to this method e.g. call once after size negotiation.
369    * @param[in] size A the size of a bounding box to layout text within.
370    * @return True if the text model or decorations were updated.
371    */
372   bool Relayout( const Size& size );
373
374   /**
375    * @brief Process queued events which modify the model.
376    */
377   void ProcessModifyEvents();
378
379   /**
380    * @brief Used to remove placeholder text.
381    */
382   void ResetText();
383
384   /**
385    * @brief Used to reset the cursor position after setting a new text.
386    *
387    * @param[in] cursorIndex Where to place the cursor.
388    */
389   void ResetCursorPosition( CharacterIndex cursorIndex );
390
391   /**
392    * @brief Used to reset the scroll position after setting a new text.
393    */
394   void ResetScrollPosition();
395
396   /**
397    * @brief Used to process an event queued from SetText()
398    */
399   void TextReplacedEvent();
400
401   /**
402    * @brief Used to process an event queued from key events etc.
403    */
404   void TextInsertedEvent();
405
406   /**
407    * @brief Used to process an event queued from backspace key etc.
408    */
409   void TextDeletedEvent();
410
411   /**
412    * @brief Lays-out the text.
413    *
414    * GetNaturalSize(), GetHeightForWidth() and Relayout() calls this method.
415    *
416    * @param[in] size A the size of a bounding box to layout text within.
417    * @param[in] operations The layout operations which need to be done.
418    * @param[out] layoutSize The size of the laid-out text.
419    */
420   bool DoRelayout( const Size& size,
421                    OperationsMask operations,
422                    Size& layoutSize );
423
424   /**
425    * @brief Whether to enable the multi-line layout.
426    *
427    * @param[in] enable \e true enables the multi-line (by default)
428    */
429   void SetMultiLineEnabled( bool enable );
430
431   /**
432    * @return Whether the multi-line layout is enabled.
433    */
434   bool IsMultiLineEnabled() const;
435
436   /**
437    * @copydoc Dali::Toolkit::Text::LayoutEngine::SetHorizontalAlignment()
438    */
439   void SetHorizontalAlignment( LayoutEngine::HorizontalAlignment alignment );
440
441   /**
442    * @copydoc Dali::Toolkit::Text::LayoutEngine::GetHorizontalAlignment()
443    */
444   LayoutEngine::HorizontalAlignment GetHorizontalAlignment() const;
445
446   /**
447    * @copydoc Dali::Toolkit::Text::LayoutEngine::SetVerticalAlignment()
448    */
449   void SetVerticalAlignment( LayoutEngine::VerticalAlignment alignment );
450
451   /**
452    * @copydoc Dali::Toolkit::Text::LayoutEngine::GetVerticalAlignment()
453    */
454   LayoutEngine::VerticalAlignment GetVerticalAlignment() const;
455
456   /**
457    * @brief Calulates the alignment of the whole text inside the bounding box.
458    *
459    * @param[in] size The size of the bounding box.
460    */
461   void CalculateTextAlignment( const Size& size );
462
463   /**
464    * @brief Return the layout engine.
465    *
466    * @return A reference to the layout engine.
467    */
468   LayoutEngine& GetLayoutEngine();
469
470   /**
471    * @brief Return a view of the text.
472    *
473    * @return A reference to the view.
474    */
475   View& GetView();
476
477   // Text-input Event Queuing
478
479   /**
480    * @brief Called by editable UI controls when keyboard focus is gained.
481    */
482   void KeyboardFocusGainEvent();
483
484   /**
485    * @brief Called by editable UI controls when focus is lost.
486    */
487   void KeyboardFocusLostEvent();
488
489   /**
490    * @brief Called by editable UI controls when key events are received.
491    *
492    * @param[in] event The key event.
493    * @param[in] type Used to distinguish between regular key events and IMF events.
494    */
495   bool KeyEvent( const Dali::KeyEvent& event );
496
497   /**
498    * @brief Called by editable UI controls when key events are received.
499    *
500    * @param[in] text The text to insert.
501    * @param[in] type Used to distinguish between regular key events and IMF events.
502    */
503   void InsertText( const std::string& text, InsertType type );
504
505   /**
506    * @brief Checks if text is selected and if so removes it.
507    * @return true if text was removed
508    */
509   bool RemoveSelectedText();
510
511   /**
512    * @brief Called by editable UI controls when a tap gesture occurs.
513    * @param[in] tapCount The number of taps.
514    * @param[in] x The x position relative to the top-left of the parent control.
515    * @param[in] y The y position relative to the top-left of the parent control.
516    */
517   void TapEvent( unsigned int tapCount, float x, float y );
518
519   /**
520    * @brief Called by editable UI controls when a pan gesture occurs.
521    *
522    * @param[in] state The state of the gesture.
523    * @param[in] displacement This distance panned since the last pan gesture.
524    */
525   void PanEvent( Gesture::State state, const Vector2& displacement );
526
527   /**
528    * @brief Called by editable UI controls when a long press gesture occurs.
529    *
530    * @param[in] state The state of the gesture.
531    * @param[in] x The x position relative to the top-left of the parent control.
532    * @param[in] y The y position relative to the top-left of the parent control.
533    */
534   void LongPressEvent( Gesture::State state, float x, float y );
535
536   /**
537    * @brief Creates a selection event.
538    *
539    * It could be called from the TapEvent (double tap) or when the text selection popup's sellect all button is pressed.
540    *
541    * @param[in] x The x position relative to the top-left of the parent control.
542    * @param[in] y The y position relative to the top-left of the parent control.
543    * @param[in] selectAll Whether the whole text is selected.
544    */
545   void SelectEvent( float x, float y, bool selectAll );
546
547   /**
548    * @brief Event received from IMF manager
549    *
550    * @param[in] imfManager The IMF manager.
551    * @param[in] imfEvent The event received.
552    * @return A data struture indicating if update is needed, cursor position and current text.
553    */
554   ImfManager::ImfCallbackData OnImfEvent( ImfManager& imfManager, const ImfManager::ImfEventData& imfEvent );
555
556   /**
557    * @brief Paste given string into Text model
558    * @param[in] stringToPaste this string will be inserted into the text model
559    */
560   void PasteText( const std::string& stringToPaste );
561
562   /**
563    * @brief Event from Clipboard notifying an Item has been selected for pasting
564    */
565   void PasteClipboardItemEvent();
566
567   /**
568    * @copydoc Dali::Toolkit::Text::Decorator::ControllerInterface::GetTargetSize()
569    */
570   virtual void GetTargetSize( Vector2& targetSize );
571
572   /**
573    * @copydoc Dali::Toolkit::Text::Decorator::ControllerInterface::AddDecoration()
574    */
575   virtual void AddDecoration( Actor& actor, bool needsClipping );
576
577   /**
578    * @copydoc Dali::Toolkit::Text::Decorator::ControllerInterface::DecorationEvent()
579    */
580   virtual void DecorationEvent( HandleType handle, HandleState state, float x, float y );
581
582   /**
583    * @copydoc Dali::Toolkit::TextSelectionPopup::TextPopupButtonCallbackInterface::TextPopupButtonTouched()
584    */
585   virtual void TextPopupButtonTouched( Dali::Toolkit::TextSelectionPopup::Buttons button );
586
587 protected:
588
589   /**
590    * @brief A reference counted object may only be deleted by calling Unreference().
591    */
592   virtual ~Controller();
593
594 private:
595
596   /**
597    * @brief Helper to KeyEvent() to handle the backspace case.
598    *
599    * @return True if a character was deleted.
600    */
601   bool BackspaceKeyEvent();
602
603   /**
604    * @brief Helper to clear font-specific data.
605    */
606   void ShowPlaceholderText();
607
608   /**
609    * @brief Helper to clear all the model data except for LogicalModel::mText.
610    */
611   void ClearModelData();
612
613   /**
614    * @brief Helper to clear font-specific data (only).
615    */
616   void ClearFontData();
617
618   /**
619    * @brief Private constructor.
620    */
621   Controller( ControlInterface& controlInterface );
622
623   // Undefined
624   Controller( const Controller& handle );
625
626   // Undefined
627   Controller& operator=( const Controller& handle );
628
629 private:
630
631   struct Impl;
632   Impl* mImpl;
633 };
634
635 } // namespace Text
636
637 } // namespace Toolkit
638
639 } // namespace Dali
640
641 #endif // __DALI_TOOLKIT_TEXT_CONTROLLER_H__