[dali_2.1.7] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / text-controls / text-editor-impl.h
1 #ifndef DALI_TOOLKIT_INTERNAL_TEXT_EDITOR_H
2 #define DALI_TOOLKIT_INTERNAL_TEXT_EDITOR_H
3
4 /*
5  * Copyright (c) 2022 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/devel-api/adaptor-framework/accessibility.h>
23 #include <dali/devel-api/adaptor-framework/clipboard-event-notifier.h>
24 #include <dali/devel-api/adaptor-framework/input-method-context.h>
25 #include <dali/devel-api/atspi-interfaces/editable-text.h>
26 #include <dali/devel-api/atspi-interfaces/hypertext.h>
27 #include <dali/devel-api/atspi-interfaces/text.h>
28 #include <dali/public-api/animation/animation.h>
29
30 // INTERNAL INCLUDES
31 #include <dali-toolkit/devel-api/controls/control-devel.h>
32 #include <dali-toolkit/devel-api/controls/scroll-bar/scroll-bar.h>
33 #include <dali-toolkit/devel-api/controls/text-controls/text-editor-devel.h>
34 #include <dali-toolkit/internal/controls/control/control-data-impl.h>
35 #include <dali-toolkit/internal/text/decorator/text-decorator.h>
36 #include <dali-toolkit/internal/text/rendering/text-renderer.h>
37 #include <dali-toolkit/internal/text/text-anchor-control-interface.h>
38 #include <dali-toolkit/internal/text/text-control-interface.h>
39 #include <dali-toolkit/internal/text/text-controller.h>
40 #include <dali-toolkit/internal/text/text-editable-control-interface.h>
41 #include <dali-toolkit/internal/text/text-selectable-control-interface.h>
42 #include <dali-toolkit/internal/text/text-vertical-scroller.h>
43 #include <dali-toolkit/public-api/controls/control-impl.h>
44 #include <dali-toolkit/public-api/controls/text-controls/text-editor.h>
45
46 namespace Dali
47 {
48 namespace Toolkit
49 {
50 namespace Internal
51 {
52 /**
53  * @brief A control which renders a long text string with styles.
54  */
55 class TextEditor : public Control, public Text::ControlInterface, public Text::EditableControlInterface, public Text::SelectableControlInterface, public Text::AnchorControlInterface
56 {
57 public:
58   /**
59    * @copydoc Dali::Toollkit::TextEditor::New()
60    */
61   static Toolkit::TextEditor New();
62
63   // Properties
64
65   /**
66    * @brief Called when a property of an object of this type is set.
67    *
68    * @param[in] object The object whose property is set.
69    * @param[in] index The property index.
70    * @param[in] value The new property value.
71    */
72   static void SetProperty(BaseObject* object, Property::Index index, const Property::Value& value);
73
74   /**
75    * @brief Called to retrieve a property of an object of this type.
76    *
77    * @param[in] object The object whose property is to be retrieved.
78    * @param[in] index The property index.
79    * @return The current value of the property.
80    */
81   static Property::Value GetProperty(BaseObject* object, Property::Index index);
82
83   /**
84    * @copydoc Dali::Toollkit::TextEditor::GetInputMethodContext()
85    */
86   InputMethodContext GetInputMethodContext();
87
88   /**
89    * @copydoc Dali::Toollkit::TextEditor::MaxLengthReachedSignal()
90    */
91   DevelTextEditor::MaxLengthReachedSignalType& MaxLengthReachedSignal();
92
93   /**
94    * @copydoc Dali::Toollkit::TextEditor::AnchorClickedSignal()
95    */
96   DevelTextEditor::AnchorClickedSignalType& AnchorClickedSignal();
97
98   /**
99    * @copydoc Dali::Toollkit::TextEditor::CursorPositionChangedSignal()
100    */
101   DevelTextEditor::CursorPositionChangedSignalType& CursorPositionChangedSignal();
102
103   /**
104    * @copydoc Dali::Toollkit::TextEditor::InputFilteredSignal()
105    */
106   DevelTextEditor::InputFilteredSignalType& InputFilteredSignal();
107
108   /**
109    * @copydoc Dali::Toollkit::TextEditor::SelectionChangedSignal()
110    */
111   DevelTextEditor::SelectionChangedSignalType& SelectionChangedSignal();
112
113   /**
114    * @copydoc Dali::Toollkit::TextEditor::SelectionClearedSignal()
115    */
116   DevelTextEditor::SelectionClearedSignalType& SelectionClearedSignal();
117
118   /**
119    * @copydoc Dali::Toollkit::TextEditor::SelectionStartedSignal()
120    */
121   DevelTextEditor::SelectionStartedSignalType& SelectionStartedSignal();
122
123   /**
124    * Connects a callback function with the object's signals.
125    * @param[in] object The object providing the signal.
126    * @param[in] tracker Used to disconnect the signal.
127    * @param[in] signalName The signal to connect to.
128    * @param[in] functor A newly allocated FunctorDelegate.
129    * @return True if the signal was connected.
130    * @post If a signal was connected, ownership of functor was passed to CallbackBase. Otherwise the caller is responsible for deleting the unused functor.
131    */
132   static bool DoConnectSignal(BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor);
133
134   /**
135    * @brief Gets text controller
136    *
137    * @return The text controller
138    */
139   Text::ControllerPtr GetTextController();
140
141   /**
142    * @copydoc TextEditor::TextChangedSignal()
143    */
144   Toolkit::TextEditor::TextChangedSignalType& TextChangedSignal();
145
146   /**
147    * @copydoc TextEditor::TextChangedSignal()
148    */
149   Toolkit::TextEditor::InputStyleChangedSignalType& InputStyleChangedSignal();
150
151   /**
152    * @copydoc TextEditor::ScrollStateChangedSignal()
153    */
154   Toolkit::TextEditor::ScrollStateChangedSignalType& ScrollStateChangedSignal();
155
156 private: // From Control
157   /**
158    * @copydoc Control::OnInitialize()
159    */
160   void OnInitialize() override;
161
162   /**
163    * @copydoc Control::OnStyleChange()
164    */
165   void OnStyleChange(Toolkit::StyleManager styleManager, StyleChange::Type change) override;
166
167   /**
168    * @copydoc Control::GetNaturalSize()
169    */
170   Vector3 GetNaturalSize() override;
171
172   /**
173    * @copydoc Control::GetHeightForWidth()
174    */
175   float GetHeightForWidth(float width) override;
176
177   /**
178    * @copydoc Control::OnInitialize()
179    */
180   void OnRelayout(const Vector2& size, RelayoutContainer& container) override;
181
182   /**
183    * @copydoc Control::OnKeyInputFocusGained()
184    */
185   void OnKeyInputFocusGained() override;
186
187   /**
188    * @copydoc Control::OnKeyInputFocusLost()
189    */
190   void OnKeyInputFocusLost() override;
191
192   /**
193    * @copydoc Control::OnAccessibilityActivated()
194    */
195   bool OnAccessibilityActivated() override;
196
197   /**
198    * @copydoc Control::OnTap()
199    */
200   void OnTap(const TapGesture& tap) override;
201
202   /**
203    * @copydoc Control::OnPan()
204    */
205   void OnPan(const PanGesture& gesture) override;
206
207   /**
208    * @copydoc Control::OnLongPress()
209    */
210   void OnLongPress(const LongPressGesture& gesture) override;
211
212   /**
213    * @copydoc Control::OnSceneConnection()
214    */
215   void OnSceneConnection(int depth) override;
216
217   /**
218    * @copydoc Dali::CustomActorImpl::OnKeyEvent(const KeyEvent&)
219    */
220   bool OnKeyEvent(const KeyEvent& event) override;
221
222   // From ControlInterface
223
224   /**
225    * @copydoc Text::ControlInterface::RequestTextRelayout()
226    */
227   void RequestTextRelayout() override;
228
229   // From EditableControlInterface
230
231   /**
232    * @copydoc Text::EditableControlInterface::TextChanged()
233    */
234   void TextInserted(unsigned int position, unsigned int length, const std::string& content) override;
235
236   /**
237    * @copydoc Text::EditableControlInterface::TextDeleted()
238    */
239   void TextDeleted(unsigned int position, unsigned int length, const std::string& content) override;
240
241   /**
242    * @copydoc Text::EditableControlInterface::CursorPositionChanged()
243    */
244   void CursorPositionChanged(unsigned int oldPosition, unsigned int newPosition) override;
245
246   /**
247    * @copydoc Text::EditableControlInterface::TextChanged()
248    */
249   void TextChanged(bool immediate) override;
250
251   /**
252    * @copydoc Text::EditableControlInterface::MaxLengthReached()
253    */
254   void MaxLengthReached() override;
255
256   /**
257    * @copydoc Text::EditableControlInterface::InputStyleChanged()
258    */
259   void InputStyleChanged(Text::InputStyle::Mask inputStyleMask) override;
260
261   /**
262    * @copydoc Text::SelectableControlInterface::SelectionChanged()
263    */
264   void SelectionChanged(uint32_t oldStart, uint32_t oldEnd, uint32_t newStart, uint32_t newEnd) override;
265
266   /**
267    * @copydoc Text::EditableControlInterface::AddDecoration()
268    */
269   void AddDecoration(Actor& actor, bool needsClipping) override;
270
271   /**
272    * @copydoc Text::EditableControlInterface::InputFiltered()
273    */
274   void InputFiltered(Toolkit::InputFilter::Property::Type type) override;
275
276   /**
277    * @copydoc Text::EditableControlInterface::GetControlBackgroundColor()
278    */
279   void GetControlBackgroundColor(Vector4& color) const override;
280
281   // From SelectableControlInterface
282 public:
283   /**
284    * @copydoc Text::SelectableControlInterface::SetTextSelectionRange()
285    */
286   void SetTextSelectionRange(const uint32_t* start, const uint32_t* end) override;
287
288   /**
289    * @copydoc Text::SelectableControlInterface::GetTextSelectionRange()
290    */
291   Uint32Pair GetTextSelectionRange() const override;
292
293   /**
294    * @copydoc Text::SelectableControlInterface::SelectWholeText()
295    */
296   void SelectWholeText() override;
297
298   /**
299    * @copydoc Text::SelectableControlInterface::SelectNone()
300    */
301   void SelectNone() override;
302
303   /**
304    * @copydoc Text::SelectableControlInterface::SelectText()
305    */
306   void SelectText(const uint32_t start, const uint32_t end) override;
307
308   /**
309    * @copydoc Dali::Toolkit::DevelTextEditor::ScrollBy()
310    */
311   void ScrollBy(Vector2 Scroll);
312
313   /**
314    * @brief Get Horizontal scroll position of TextEditor.
315    *
316    * @return Horizontal scroll position (in pixels) of TextEditor.
317    */
318   float GetHorizontalScrollPosition();
319
320   /**
321    * @brief Get Vertical scroll position of TextEditor.
322    *
323    * @return Vertical scroll position (in pixels) of TextEditor.
324    */
325   float GetVerticalScrollPosition();
326
327   /**
328    * @brief Get the rendered size of a specific text range.
329    * if the requested text is at multilines, multiple sizes will be returned for each text located in a separate line.
330    * if a line contains characters with different directions, multiple sizes will be returned for each block of contiguous characters with the same direction.
331    *
332    * @param[in] startIndex start index of the text requested to calculate size for.
333    * @param[in] endIndex end index(included) of the text requested to calculate size for.
334    * @return list of sizes of the reuested text.
335    */
336   Vector<Vector2> GetTextSize(const uint32_t startIndex, const uint32_t endIndex) const;
337
338   /**
339    * @brief Get the top/left rendered position of a specific text range.
340    * if the requested text is at multilines, multiple positions will be returned for each text located in a separate line.
341    * if a line contains characters with different directions, multiple positions will be returned for each block of contiguous characters with the same direction.
342    *
343    * @param[in] startIndex start index of the text requested to get position to.
344    * @param[in] endIndex end index(included) of the text requested to get position to.
345    * @return list of positions of the requested text.
346    */
347   Vector<Vector2> GetTextPosition(const uint32_t startIndex, const uint32_t endIndex) const;
348
349   /**
350    * @copydoc Text::SelectableControlInterface::GetSelectedText()
351    */
352   string GetSelectedText() const override;
353
354   /**
355    * @copydoc Text::EditableControlInterface::IsEditable()
356    */
357   bool IsEditable() const override;
358
359   /**
360    * @copydoc Text::EditableControlInterface::SetEditable()
361    */
362   void SetEditable(bool editable) override;
363
364   /**
365    * @copydoc Text::EditableControlInterface::CopyText()
366    */
367   string CopyText() override;
368
369   /**
370    * @copydoc Text::EditableControlInterface::CutText()
371    */
372   string CutText() override;
373
374   /**
375    * @copydoc Text::EditableControlInterface::PasteText()
376    */
377   void PasteText() override;
378
379   // From AnchorControlInterface
380
381   /**
382    * @copydoc Text::AnchorControlInterface::AnchorClicked()
383    */
384   void AnchorClicked(const std::string& href) override;
385
386 private: // Implementation
387   /**
388    * @copydoc Dali::Toolkit::Text::Controller::(InputMethodContext& inputMethodContext, const InputMethodContext::EventData& inputMethodContextEvent)
389    */
390   InputMethodContext::CallbackData OnInputMethodContextEvent(InputMethodContext& inputMethodContext, const InputMethodContext::EventData& inputMethodContextEvent);
391
392   /**
393    * @brief Callback when Clipboard signals an item should be pasted
394    * @param[in] clipboard handle to Clipboard Event Notifier
395    */
396   void OnClipboardTextSelected(ClipboardEventNotifier& clipboard);
397
398   /**
399    * @brief Get a Property Map for the image used for the required Handle Image
400    * @param[out] value the returned image property
401    * @param[in] handleType the type of handle
402    * @param[in] handleImageType the type of image for the given handleType
403    */
404   void GetHandleImagePropertyValue(Property::Value& value, Text::HandleType handleType, Text::HandleImageType handleImageType);
405
406   /**
407    * @brief Callback when keyboard is shown/hidden.
408    *
409    * @param[in] keyboardShown True if keyboard is shown.
410    */
411   void KeyboardStatusChanged(bool keyboardShown);
412
413   /**
414    * @brief update scroll bar position
415    *
416    * If text scroll is occurred, create or update scroll bar position
417    */
418   void UpdateScrollBar();
419
420   /**
421    * @brief Callback when TextEditor is touched
422    *
423    * @param[in] actor TextEditor touched
424    * @param[in] touch Touch information
425    */
426   bool OnTouched(Actor actor, const TouchEvent& touch);
427
428   /**
429    * @brief Callbacks called on idle.
430    *
431    * If there are notifications of change of input style on the queue, Toolkit::TextEditor::InputStyleChangedSignal() are emitted.
432    */
433   void OnIdleSignal();
434
435   /**
436    * @brief Emits CursorPositionChanged signal.
437    */
438   void EmitCursorPositionChangedSignal();
439
440   /**
441    * @brief Emits TextChanged signal.
442    */
443   void EmitTextChangedSignal();
444
445   /**
446    * @brief Emits SelectionChanged signal.
447    */
448   void EmitSelectionChangedSignal();
449
450   /**
451    * @brief Emits SelectionCleared signal.
452    */
453   void EmitSelectionClearedSignal();
454
455   /**
456    * @brief Emits SelectionStarted signal.
457    */
458   void EmitSelectionStartedSignal();
459
460   /**
461    * @brief set RenderActor's position with new scrollPosition
462    *
463    * Apply updated scroll position or start scroll animation if VerticalScrollAnimation is enabled
464    */
465   void ApplyScrollPosition();
466
467   /**
468    * @brief Callback function for ScrollBar indicator animation finished signal
469    *
470    * Emit ScrollBarStateChanged Signal and toggle mScrollStarted flag to false
471    */
472   void OnScrollIndicatorAnimationFinished(Animation& animation);
473
474   /**
475   * @brief Callback function for when the layout is changed.
476   * @param[in] actor The actor whose layoutDirection is changed.
477   * @param[in] type  The layoutDirection.
478   */
479   void OnLayoutDirectionChanged(Actor actor, LayoutDirection::Type type);
480
481   /**
482    * Construct a new TextEditor.
483    */
484   TextEditor();
485
486   /**
487    * A reference counted object may only be deleted by calling Unreference()
488    */
489   virtual ~TextEditor();
490
491   // Undefined copy constructor and assignment operators
492   TextEditor(const TextEditor&);
493   TextEditor& operator=(const TextEditor& rhs);
494
495   /**
496    * @brief Resize actor to the given size.
497    *
498    * @param[in] actor The actor to be resized.
499    * @param[in] size Size to change.
500    */
501   void ResizeActor(Actor& actor, const Vector2& size);
502
503   /**
504    * @brief Render view, create and attach actor(s) to this text editor.
505    */
506   void RenderText(Text::Controller::UpdateTextType updateTextType);
507
508   // Connection needed to re-render text, when a text editor returns to the scene.
509   void OnSceneConnect(Dali::Actor actor);
510
511   // Needed to synchronize TextAnchor actors with Anchor objects in text's logical model
512   void OnAccessibilityStatusChanged();
513
514 private: // Data
515   // Signals
516   Toolkit::TextEditor::TextChangedSignalType                mTextChangedSignal;
517   Toolkit::TextEditor::InputStyleChangedSignalType          mInputStyleChangedSignal;
518   Toolkit::TextEditor::ScrollStateChangedSignalType         mScrollStateChangedSignal;
519   Toolkit::DevelTextEditor::MaxLengthReachedSignalType      mMaxLengthReachedSignal;
520   Toolkit::DevelTextEditor::AnchorClickedSignalType         mAnchorClickedSignal;
521   Toolkit::DevelTextEditor::InputFilteredSignalType         mInputFilteredSignal;
522   Toolkit::DevelTextEditor::CursorPositionChangedSignalType mCursorPositionChangedSignal;
523   Toolkit::DevelTextEditor::SelectionChangedSignalType      mSelectionChangedSignal;
524   Toolkit::DevelTextEditor::SelectionClearedSignalType      mSelectionClearedSignal;
525   Toolkit::DevelTextEditor::SelectionStartedSignalType      mSelectionStartedSignal;
526
527   InputMethodContext               mInputMethodContext;
528   Text::ControllerPtr              mController;
529   Text::RendererPtr                mRenderer;
530   Text::DecoratorPtr               mDecorator;
531   Text::TextVerticalScrollerPtr    mTextVerticalScroller;
532   Toolkit::Control                 mStencil;
533   Toolkit::ScrollBar               mScrollBar;
534   Dali::Animation                  mAnimation; ///< Scroll indicator Show/Hide Animation.
535   Dali::TimePeriod                 mAnimationPeriod;
536   std::vector<Actor>               mClippingDecorationActors; ///< Decoration actors which need clipping.
537   std::vector<Toolkit::TextAnchor> mAnchorActors;
538   Dali::InputMethodOptions         mInputMethodOptions;
539
540   Actor         mRenderableActor;
541   Actor         mActiveLayer;
542   Actor         mBackgroundActor;
543   CallbackBase* mIdleCallback;
544
545   float mAlignmentOffset;
546   float mScrollAnimationDuration;
547   float mLineSpacing;
548   int   mRenderingBackend;
549   bool  mHasBeenStaged : 1;
550   bool  mScrollAnimationEnabled : 1;
551   bool  mScrollBarEnabled : 1;
552   bool  mScrollStarted : 1;
553   bool  mTextChanged : 1;           ///< If true, emits TextChangedSignal in next OnRelayout().
554   bool  mCursorPositionChanged : 1; ///< If true, emits CursorPositionChangedSignal at the end of OnRelayout().
555   bool  mSelectionChanged : 1;      ///< If true, emits SelectionChangedSignal at the end of OnRelayout().
556   bool  mSelectionCleared : 1;      ///< If true, emits SelectionClearedSignal at the end of OnRelayout().
557
558   //args for cursor PositionChanged event
559   unsigned int mOldPosition;
560
561   //args for selection changed event
562   uint32_t mOldSelectionStart;
563   uint32_t mOldSelectionEnd;
564
565   bool mSelectionStarted : 1; ///< If true, emits SelectionStartedSignal at the end of OnRelayout().
566
567   struct PropertyHandler;
568
569   /**
570    * @brief This structure is to connect TextEditor with Accessible functions.
571    */
572   struct AccessibleImpl : public DevelControl::ControlAccessible,
573                           public virtual Dali::Accessibility::EditableText,
574                           public virtual Dali::Accessibility::Hypertext
575   {
576     using DevelControl::ControlAccessible::ControlAccessible;
577
578     /**
579      * @copydoc Dali::Accessibility::Accessible::GetName()
580      */
581     std::string GetName() const override;
582
583     /**
584      * @copydoc Dali::Accessibility::Text::GetText()
585      */
586     std::string GetText(size_t startOffset, size_t endOffset) const override;
587
588     /**
589      * @copydoc Dali::Accessibility::Text::GetCharacterCount()
590      */
591     size_t GetCharacterCount() const override;
592
593     /**
594      * @copydoc Dali::Accessibility::Text::GetCursorOffset()
595      */
596     size_t GetCursorOffset() const override;
597
598     /**
599      * @copydoc Dali::Accessibility::Text::SetCursorOffset()
600      */
601     bool SetCursorOffset(size_t offset) override;
602
603     /**
604      * @copydoc Dali::Accessibility::Text::GetTextAtOffset()
605      */
606     Accessibility::Range GetTextAtOffset(size_t offset, Accessibility::TextBoundary boundary) const override;
607
608     /**
609      * @copydoc Dali::Accessibility::Text::GetRangeOfSelection()
610      */
611     Accessibility::Range GetRangeOfSelection(size_t selectionIndex) const override;
612
613     /**
614      * @copydoc Dali::Accessibility::Text::RemoveSelection()
615      */
616     bool RemoveSelection(size_t selectionIndex) override;
617
618     /**
619      * @copydoc Dali::Accessibility::Text::SetRangeOfSelection()
620      */
621     bool SetRangeOfSelection(size_t selectionIndex, size_t startOffset, size_t endOffset) override;
622
623     /**
624      * @copydoc Dali::Accessibility::EditableText::CopyText()
625      */
626     bool CopyText(size_t startPosition, size_t endPosition) override;
627
628     /**
629      * @copydoc Dali::Accessibility::EditableText::CutText()
630      */
631     bool CutText(size_t startPosition, size_t endPosition) override;
632
633     /**
634      * @copydoc Dali::Accessibility::Accessible::GetStates()
635      */
636     Accessibility::States CalculateStates() override;
637
638     /**
639      * @copydoc Dali::Accessibility::EditableText::InsertText()
640      */
641     bool InsertText(size_t startPosition, std::string text) override;
642
643     /**
644      * @copydoc Dali::Accessibility::EditableText::SetTextContents()
645      */
646     bool SetTextContents(std::string newContents) override;
647
648     /**
649      * @copydoc Dali::Accessibility::EditableText::DeleteText()
650      */
651     bool DeleteText(size_t startPosition, size_t endPosition) override;
652
653     /**
654      * @copydoc Dali::Accessibility::Hypertext::GetLink()
655      */
656     Accessibility::Hyperlink* GetLink(int32_t linkIndex) const override;
657
658     /**
659      * @copydoc Dali::Accessibility::Hypertext::GetLinkIndex()
660      */
661     int32_t GetLinkIndex(int32_t characterOffset) const override;
662
663     /**
664      * @copydoc Dali::Accessibility::Hypertext::GetLinkCount()
665      */
666     int32_t GetLinkCount() const override;
667   };
668 };
669
670 } // namespace Internal
671
672 // Helpers for public-api forwarding methods
673
674 inline Toolkit::Internal::TextEditor& GetImpl(Toolkit::TextEditor& textEditor)
675 {
676   DALI_ASSERT_ALWAYS(textEditor);
677
678   Dali::RefObject& handle = textEditor.GetImplementation();
679
680   return static_cast<Toolkit::Internal::TextEditor&>(handle);
681 }
682
683 inline const Toolkit::Internal::TextEditor& GetImpl(const Toolkit::TextEditor& textEditor)
684 {
685   DALI_ASSERT_ALWAYS(textEditor);
686
687   const Dali::RefObject& handle = textEditor.GetImplementation();
688
689   return static_cast<const Toolkit::Internal::TextEditor&>(handle);
690 }
691
692 } // namespace Toolkit
693
694 } // namespace Dali
695
696 #endif // DALI_TOOLKIT_INTERNAL_TEXT_EDITOR_H