978ad97bc5aedb51d2d74ed5235b0ca08dbd934a
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / text-controls / text-label-impl.h
1 #ifndef DALI_TOOLKIT_INTERNAL_TEXT_LABEL_H
2 #define DALI_TOOLKIT_INTERNAL_TEXT_LABEL_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/atspi-interfaces/hypertext.h>
23 #include <dali/devel-api/atspi-interfaces/text.h>
24 #include <dali/public-api/object/property-map.h>
25
26 // INTERNAL INCLUDES
27 #include <dali-toolkit/internal/controls/control/control-data-impl.h>
28 #include <dali-toolkit/internal/text/rendering/text-renderer.h>
29 #include <dali-toolkit/internal/text/text-anchor-control-interface.h>
30 #include <dali-toolkit/internal/text/text-control-interface.h>
31 #include <dali-toolkit/internal/text/text-controller.h>
32 #include <dali-toolkit/internal/text/text-scroller-interface.h>
33 #include <dali-toolkit/internal/text/text-scroller.h>
34 #include <dali-toolkit/internal/visuals/text/text-visual.h>
35 #include <dali-toolkit/public-api/controls/control-impl.h>
36 #include <dali-toolkit/public-api/controls/text-controls/text-label.h>
37
38 namespace Dali
39 {
40 namespace Toolkit
41 {
42 namespace Internal
43 {
44 /**
45  * @brief A control which renders a short text string.
46  */
47 class TextLabel : public Control, public Text::ControlInterface, public Text::ScrollerInterface, public Text::AnchorControlInterface
48 {
49 public:
50   /**
51    * @copydoc Dali::Toollkit::TextLabel::New()
52    * @param[in] additionalBehaviour custom behavior flags for this TextLabel. Default is CONTROL_BEHAVIOUR_DEFAULT
53    */
54   static Toolkit::TextLabel New(ControlBehaviour additionalBehaviour = ControlBehaviour::CONTROL_BEHAVIOUR_DEFAULT);
55
56   // Properties
57
58   /**
59    * @brief Called when a property of an object of this type is set.
60    *
61    * @param[in] object The object whose property is set.
62    * @param[in] index The property index.
63    * @param[in] value The new property value.
64    */
65   static void SetProperty(BaseObject* object, Property::Index index, const Property::Value& value);
66
67   /**
68    * @brief Called to retrieve a property of an object of this type.
69    *
70    * @param[in] object The object whose property is to be retrieved.
71    * @param[in] index The property index.
72    * @return The current value of the property.
73    */
74   static Property::Value GetProperty(BaseObject* object, Property::Index index);
75
76   /**
77    * @copydoc Dali::Toollkit::TextLabel::AnchorClickedSignal()
78    */
79   DevelTextLabel::AnchorClickedSignalType& AnchorClickedSignal();
80
81   /**
82    * @copydoc Dali::Toollkit::TextLabel::TextFitChangedSignal()
83    */
84   DevelTextLabel::TextFitChangedSignalType& TextFitChangedSignal();
85
86   /**
87    * Connects a callback function with the object's signals.
88    * @param[in] object The object providing the signal.
89    * @param[in] tracker Used to disconnect the signal.
90    * @param[in] signalName The signal to connect to.
91    * @param[in] functor A newly allocated FunctorDelegate.
92    * @return True if the signal was connected.
93    * @post If a signal was connected, ownership of functor was passed to CallbackBase. Otherwise the caller is responsible for deleting the unused functor.
94    */
95   static bool DoConnectSignal(BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor);
96
97   /**
98    * @brief Gets text controller
99    *
100    * @return The text controller
101    */
102   Text::ControllerPtr GetTextController();
103
104   /**
105    * @brief Get the rendered size of a specific text range.
106    * if the requested text is at multilines, multiple sizes will be returned for each text located in a separate line.
107    * if a line contains characters with different directions, multiple sizes will be returned for each block of contiguous characters with the same direction.
108    *
109    * @param[in] startIndex start index of the text requested to calculate size for.
110    * @param[in] endIndex end index(included) of the text requested to calculate size for.
111    * @return list of sizes of the reuested text.
112    */
113   Vector<Vector2> GetTextSize(const uint32_t startIndex, const uint32_t endIndex) const;
114
115   /**
116    * @brief Get the top/left rendered position of a specific text range.
117    * if the requested text is at multilines, multiple positions will be returned for each text located in a separate line.
118    * if a line contains characters with different directions, multiple positions will be returned for each block of contiguous characters with the same direction.
119    *
120    * @param[in] startIndex start index of the text requested to get position to.
121    * @param[in] endIndex end index(included) of the text requested to get position to.
122    * @return list of positions of the requested text.
123    */
124   Vector<Vector2> GetTextPosition(const uint32_t startIndex, const uint32_t endIndex) const;
125
126 private: // From Control
127   /**
128    * @copydoc Control::OnInitialize()
129    */
130   void OnInitialize() override;
131
132   /**
133    * @copydoc Control::OnStyleChange()
134    */
135   void OnStyleChange(Toolkit::StyleManager styleManager, StyleChange::Type change) override;
136
137   /**
138    * @copydoc Control::OnRelayout()
139    */
140   void OnRelayout(const Vector2& size, RelayoutContainer& container) override;
141
142   /**
143    * @copydoc Control::OnTap()
144    */
145   void OnTap(const TapGesture& tap) override;
146
147   /**
148    * @copydoc Control::GetNaturalSize()
149    */
150   Vector3 GetNaturalSize() override;
151
152   /**
153    * @copydoc Control::GetHeightForWidth()
154    */
155   float GetHeightForWidth(float width) override;
156
157   /**
158    * @copydoc Control::OnPropertySet()
159    */
160   void OnPropertySet(Property::Index index, const Property::Value& propertyValue) override;
161
162   // From ControlInterface
163
164   /**
165    * @copydoc Text::ControlInterface::RequestTextRelayout()
166    */
167   void RequestTextRelayout() override;
168
169 private: // from TextScroller
170   /**
171    * @copydoc Text::ScrollerInterface::ScrollingFinished()
172    */
173   void ScrollingFinished() override;
174
175 public: // From AnchorControlInterface
176   /**
177    * @copydoc Text::AnchorControlInterface::AnchorClicked()
178    */
179   void AnchorClicked(const std::string& href) override;
180
181 private: // Implementation
182   /**
183    * Construct a new TextLabel.
184    *
185    * @param[in] additionalBehaviour additional behaviour flags for this TextLabel
186    */
187   TextLabel(ControlBehaviour additionalBehaviour);
188
189   /**
190    * A reference counted object may only be deleted by calling Unreference()
191    */
192   virtual ~TextLabel();
193
194 private:
195   // Undefined copy constructor and assignment operators
196   TextLabel(const TextLabel&);
197   TextLabel& operator=(const TextLabel& rhs);
198
199   /**
200    * @brief Set up Autoscrolling
201    */
202   void SetUpAutoScrolling();
203
204   /**
205    * Creates a text-scroller if one has not been created.
206    * @return The text scroller.
207    */
208   Text::TextScrollerPtr GetTextScroller()
209   {
210     if(!mTextScroller)
211     {
212       mTextScroller = Text::TextScroller::New(*this);
213     }
214     return mTextScroller;
215   }
216
217   /**
218    * @brief Callback function for when the layout is changed.
219    * @param[in] actor The actor whose layoutDirection is changed.
220    * @param[in] type  The layoutDirection.
221    */
222   void OnLayoutDirectionChanged(Actor actor, LayoutDirection::Type type);
223
224   /**
225    * @brief Emits TextFitChanged signal.
226    */
227   void EmitTextFitChangedSignal();
228   void OnAccessibilityStatusChanged();
229
230 private: // Data
231   Text::ControllerPtr   mController;
232   Text::TextScrollerPtr mTextScroller;
233
234   Toolkit::Visual::Base mVisual;
235
236   std::vector<Toolkit::TextAnchor> mAnchorActors;
237
238   // Signals
239   Toolkit::DevelTextLabel::AnchorClickedSignalType  mAnchorClickedSignal;
240   Toolkit::DevelTextLabel::TextFitChangedSignalType mTextFitChangedSignal;
241
242   int  mRenderingBackend;
243   bool mTextUpdateNeeded : 1;
244
245 protected:
246   /**
247    * @brief This structure is to connect TextLabel with Accessible functions.
248    */
249   struct AccessibleImpl : public DevelControl::ControlAccessible,
250                           public virtual Dali::Accessibility::Text,
251                           public virtual Dali::Accessibility::Hypertext
252   {
253     using DevelControl::ControlAccessible::ControlAccessible;
254
255     /**
256      * @copydoc Dali::Accessibility::Text::GetText()
257      */
258     std::string GetText(size_t startOffset, size_t endOffset) const override;
259
260     /**
261      * @copydoc Dali::Accessibility::Text::GetCharacterCount()
262      */
263     size_t GetCharacterCount() const override;
264
265     /**
266      * @copydoc Dali::Accessibility::Text::GetCursorOffset()
267      */
268     size_t GetCursorOffset() const override;
269
270     /**
271      * @copydoc Dali::Accessibility::Text::SetCursorOffset()
272      */
273     bool SetCursorOffset(size_t offset) override;
274
275     /**
276      * @copydoc Dali::Accessibility::Text::GetTextAtOffset()
277      */
278     Accessibility::Range GetTextAtOffset(size_t offset, Accessibility::TextBoundary boundary) const override;
279
280     /**
281      * @copydoc Dali::Accessibility::Text::GetRangeOfSelection()
282      */
283     Accessibility::Range GetRangeOfSelection(size_t selectionIndex) const override;
284
285     /**
286      * @copydoc Dali::Accessibility::Text::RemoveSelection()
287      */
288     bool RemoveSelection(size_t selectionIndex) override;
289
290     /**
291      * @copydoc Dali::Accessibility::Text::SetRangeOfSelection()
292      */
293     bool SetRangeOfSelection(size_t selectionIndex, size_t startOffset, size_t endOffset) override;
294
295     /**
296      * @copydoc Dali::Accessibility::Text::GetNameRaw()
297      */
298     std::string GetNameRaw() const override;
299
300     /**
301      * @copydoc Dali::Accessibility::Text::GetNamePropertyIndex()
302      */
303     Property::Index GetNamePropertyIndex() override;
304
305     /**
306      * @copydoc Dali::Accessibility::Hypertext::GetLink()
307      */
308     Accessibility::Hyperlink* GetLink(int32_t linkIndex) const override;
309
310     /**
311      * @copydoc Dali::Accessibility::Hypertext::GetLinkIndex()
312      */
313     int32_t GetLinkIndex(int32_t characterOffset) const override;
314
315     /**
316      * @copydoc Dali::Accessibility::Hypertext::GetLinkCount()
317      */
318     int32_t GetLinkCount() const override;
319   };
320 };
321
322 } // namespace Internal
323
324 // Helpers for public-api forwarding methods
325
326 inline Toolkit::Internal::TextLabel& GetImpl(Toolkit::TextLabel& textLabel)
327 {
328   DALI_ASSERT_ALWAYS(textLabel);
329
330   Dali::RefObject& handle = textLabel.GetImplementation();
331
332   return static_cast<Toolkit::Internal::TextLabel&>(handle);
333 }
334
335 inline const Toolkit::Internal::TextLabel& GetImpl(const Toolkit::TextLabel& textLabel)
336 {
337   DALI_ASSERT_ALWAYS(textLabel);
338
339   const Dali::RefObject& handle = textLabel.GetImplementation();
340
341   return static_cast<const Toolkit::Internal::TextLabel&>(handle);
342 }
343
344 } // namespace Toolkit
345
346 } // namespace Dali
347
348 #endif // DALI_TOOLKIT_INTERNAL_TEXT_LABEL_H