1 #ifndef DALI_TOOLKIT_TEXT_DECORATOR_H
2 #define DALI_TOOLKIT_TEXT_DECORATOR_H
5 * Copyright (c) 2021 Samsung Electronics Co., Ltd.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
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>
27 #include <dali-toolkit/devel-api/controls/text-controls/text-selection-popup.h>
39 typedef IntrusivePtr<Decorator> DecoratorPtr;
41 // Used to set the cursor positions etc.
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
49 // Determines which of the cursors are active (if any).
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
57 // The state information for handle events.
67 // Used to set different handle images
71 HANDLE_IMAGE_RELEASED,
72 HANDLE_IMAGE_TYPE_COUNT
79 LEFT_SELECTION_HANDLE,
80 RIGHT_SELECTION_HANDLE,
81 LEFT_SELECTION_HANDLE_MARKER,
82 RIGHT_SELECTION_HANDLE_MARKER,
87 * @brief A Text Decorator is used to display cursors, handles, selection highlights and pop-ups.
89 * The decorator is responsible for clipping decorations which are positioned outside of the parent area.
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).
94 * Selection handles will be flipped around to ensure they do not exceed the Decoration Bounding Box. ( Stay visible ).
96 * Decorator components forward input events to a controller class through an interface.
97 * The controller is responsible for selecting which components are active.
99 class Decorator : public RefObject
102 class ControllerInterface
106 * @brief Constructor.
108 ControllerInterface(){};
111 * @brief Virtual destructor.
113 virtual ~ControllerInterface(){};
116 * @brief Query the target size of the UI control.
118 * @param[out] targetSize The size of the UI control the decorator is adding it's decorations to.
120 virtual void GetTargetSize(Vector2& targetSize) = 0;
123 * @brief Add a decoration to the parent UI control.
125 * @param[in] decoration The actor displaying a decoration.
127 virtual void AddDecoration(Actor& actor, bool needsClipping) = 0;
130 * @brief An input event from one of the handles.
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.
137 virtual void DecorationEvent(HandleType handleType, HandleState state, float x, float y) = 0;
141 * @brief Create a new instance of a Decorator.
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.
146 * @return A pointer to a new Decorator.
148 static DecoratorPtr New(ControllerInterface& controller,
149 TextSelectionPopupCallbackInterface& callbackInterface);
152 * @brief Set the bounding box which handles, popup and similar decorations will not exceed.
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.
159 * ------------------------------------------
161 * |o---------------------------------------|
163 * || Bounding Box || boundary height
165 * |----------------------------------------|
166 * ------------------------------------------
169 * @param[in] boundingBox Vector( x coordinate, y coordinate, width, height )
171 void SetBoundingBox(const Rect<int>& boundingBox);
174 * @brief Retrieve the bounding box origin and dimensions.
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.
179 void GetBoundingBox(Rect<int>& boundingBox) const;
182 * @brief The decorator waits until a relayout before creating actors etc.
184 * @param[in] size The size of the parent control after size-negotiation.
186 void Relayout(const Dali::Vector2& size);
189 * @brief Updates the decorator's actor positions after scrolling.
191 * @param[in] scrollOffset The scroll offset.
193 void UpdatePositions(const Vector2& scrollOffset);
196 * @brief Sets which of the cursors are active.
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).
201 void SetActiveCursor(ActiveCursor activeCursor);
204 * @brief Query which of the cursors are active.
206 * @return Which of the cursors are active (if any).
208 unsigned int GetActiveCursor() const;
211 * @brief Sets the position of a cursor.
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.
219 void SetPosition(Cursor cursor, float x, float y, float cursorHeight, float lineHeight);
222 * @brief Retrieves the position, height and lineHeight of a cursor.
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.
230 void GetPosition(Cursor cursor, float& x, float& y, float& cursorHeight, float& lineHeight) const;
233 * @brief Retrieves the position of a cursor.
235 * @param[in] cursor The cursor to get.
237 * @return The position.
239 const Vector2& GetPosition(Cursor cursor) const;
242 * @brief Sets the glyph offset of a cursor.
244 * @param[in] cursor The cursor to set.
245 * @param[in] glyphoffset The difference of line ascender and glyph ascender.
247 void SetGlyphOffset(Cursor cursor, float glyphOffset);
250 * @brief Retrieves the glyph offset of a cursor.
252 * @param[in] cursor The cursor to get.
254 * @return The glyph offset. glyph offset means difference of line ascender and glyph ascender.
256 const float GetGlyphOffset(Cursor cursor) const;
259 * @brief Sets the color for a cursor.
261 * @param[in] cursor Whether this color is for the primary or secondary cursor.
262 * @param[in] color The color to use.
264 void SetCursorColor(Cursor cursor, const Dali::Vector4& color);
267 * @brief Retrieves the color for a cursor.
269 * @param[in] cursor Whether this color is for the primary or secondary cursor.
270 * @return The cursor color.
272 const Dali::Vector4& GetColor(Cursor cursor) const;
275 * @brief Start blinking the cursor; see also SetCursorBlinkDuration().
277 void StartCursorBlink();
280 * @brief Stop blinking the cursor.
282 void StopCursorBlink();
285 * @brief Temporarily stops the cursor from blinking.
287 void DelayCursorBlink();
290 * @brief Set the interval between cursor blinks.
292 * @param[in] seconds The interval in seconds.
294 void SetCursorBlinkInterval(float seconds);
297 * @brief Retrieves the blink-interval for a cursor.
299 * @return The cursor blink-interval in seconds.
301 float GetCursorBlinkInterval() const;
304 * @brief The cursor will stop blinking after this duration.
306 * @param[in] seconds The duration in seconds.
308 void SetCursorBlinkDuration(float seconds);
311 * @brief Retrieves the blink-duration for a cursor.
313 * @return The cursor blink-duration in seconds.
315 float GetCursorBlinkDuration() const;
318 * @brief Sets the width of the cursors.
320 * @param[in] width The width of the cursor in pixels.
322 void SetCursorWidth(int width);
325 * @brief Retrieves the width of the cursors.
327 * @return The width of the cursors in pixels.
329 int GetCursorWidth() const;
332 * @brief Sets whether a handle is active.
334 * @param[in] handleType One of the handles.
335 * @param[in] active True if the handle should be active.
337 void SetHandleActive(HandleType handleType,
341 * @brief Query whether a handle is active.
343 * @param[in] handleType One of the handles.
345 * @return True if the handle is active.
347 bool IsHandleActive(HandleType handleType) const;
350 * @brief Sets the image file name for one of the handles.
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.
356 void SetHandleImage(HandleType handleType, HandleImageType handleImageType, const std::string& imageFileName);
359 * @brief Retrieves the file name of the image for one of the handles.
361 * @param[in] handleType One of the handles.
362 * @param[in] handleImageType A different image can be set for the pressed/released states.
364 * @return The grab handle image string.
366 const std::string& GetHandleImage(HandleType handleType, HandleImageType handleImageType) const;
369 * @brief Sets the color of the handles
371 * @param[in] color The color to use.
373 void SetHandleColor(const Vector4& color);
376 * @brief Retrieves the handles color.
378 * @return The color of the handles.
380 const Vector4& GetHandleColor() const;
383 * @brief Sets the position of a selection handle.
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.
390 void SetPosition(HandleType handleType, float x, float y, float lineHeight);
393 * @brief Retrieves the position of a selection handle.
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.
400 void GetPosition(HandleType handleType, float& x, float& y, float& lineHeight) const;
403 * @brief Retrieves the position of a selection handle.
405 * @param[in] handleType The handle to get.
407 * @return The position of the selection handle relative to the top-left of the parent control.
409 const Vector2& GetPosition(HandleType handleType) const;
412 * @brief Whether to flip vertically a handle.
414 * @param[in] handleType The handle to flip vertically.
415 * @param[in] flip Whether to flip vertically.
417 void FlipHandleVertically(HandleType handleType, bool flip);
420 * @brief Retrieves whether the handle is vertically flipped.
422 * @param[in] handleType The handle to query.
424 * @return @e ture if the handle is vertically flipped.
426 bool IsHandleVerticallyFlipped(HandleType handleType) const;
429 * @brief Whether to flip the selection handles as soon as they are crossed.
431 * By default they flip when the handle is released.
433 * @param[in] enable If @e true the selection handles will flip as soon as they are crossed.
435 void FlipSelectionHandlesOnCrossEnabled(bool enable);
438 * @brief Sets info to calculate the handle flip state.
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.
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.
447 void SetSelectionHandleFlipState(bool indicesSwapped, bool left, bool right);
450 * @brief Adds a quad to the existing selection highlights. Vertices are in decorator's coordinates.
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'.
455 void AddHighlight(unsigned int index, const Vector4& quad);
458 * @brief Sets the min 'x,y' coordinates and the size of the highlighted box.
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.
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.
467 void SetHighLightBox(const Vector2& position,
469 float outlineOffset);
472 * @brief Removes all of the previously added highlights.
474 void ClearHighlights();
477 * @brief Reserves space for the highlight quads.
479 * @param[in] numberOfQuads The expected number of quads.
481 void ResizeHighlightQuads(unsigned int numberOfQuads);
484 * @brief Sets the selection highlight color.
486 * @param[in] color The color to use.
488 void SetHighlightColor(const Vector4& color);
491 * @brief Retrieves the selection highlight color.
493 * @return The color of the highlight
495 const Vector4& GetHighlightColor() const;
498 * @brief Sets whether the highlight is active.
500 * @param[in] active Whether the highlight is active.
502 void SetHighlightActive(bool active);
505 * @brief Retrieves whether the highlight is active.
507 * @return @e true if the highlight is active, @e false otherwise.
509 bool IsHighlightActive() const;
512 * @brief Retreives whether the highlight is shown or not.
514 * @return true if the highlight is visible, false otherwise.
516 bool IsHighlightVisible() const;
519 * @brief Sets into the decorator the depth used to render the text.
521 * @param[in] depth The text's depth.
523 void SetTextDepth(int textDepth);
526 * @brief Set the Selection Popup to show or hide via the active flaf
527 * @param[in] active true to show, false to hide
529 void SetPopupActive(bool active);
532 * @brief Query whether the Selection Popup is active.
534 * @return True if the Selection Popup should be active.
536 bool IsPopupActive() const;
539 * @brief Set a bit mask of the buttons to be shown by Popup
540 * @param[in] enabledButtonsBitMask from TextSelectionPopup::Buttons enum
542 void SetEnabledPopupButtons(TextSelectionPopup::Buttons& enabledButtonsBitMask);
545 * @brief Get the current bit mask of buttons to be shown by Popup
546 * @return bitmask of TextSelectionPopup::Buttons
548 TextSelectionPopup::Buttons& GetEnabledPopupButtons();
551 * @brief Sets the scroll threshold.
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.
556 * @param[in] threshold The scroll threshold in pixels.
558 void SetScrollThreshold(float threshold);
561 * @brief Retrieves the scroll threshold.
563 * @retunr The scroll threshold in pixels.
565 float GetScrollThreshold() const;
568 * @brief Sets the scroll speed.
570 * Is the distance the text is going to be scrolled during a scroll interval.
572 * @param[in] speed The scroll speed in pixels/second.
574 void SetScrollSpeed(float speed);
577 * @brief Sets Editable mode decoration.
579 * If this set to false, Primary cursor and grab will always be hidden.
581 * @param[in] isEditable enable or disable Editing.
583 void SetEditable(bool isEditable);
586 * @brief Retrieves the scroll speed.
588 * @return The scroll speed in pixels/second.
590 float GetScrollSpeed() const;
593 * @brief Notifies the decorator the whole text has been scrolled.
595 void NotifyEndOfScroll();
598 * @copydoc Text::Controller::SetHorizontalScrollEnabled()
600 void SetHorizontalScrollEnabled(bool enable);
603 * @copydoc Text::Controller::IsHorizontalScrollEnabled()
605 bool IsHorizontalScrollEnabled() const;
608 * @copydoc Text::Controller::SetVerticalScrollEnabled()
610 void SetVerticalScrollEnabled(bool enable);
613 * @copydoc Text::Controller::IsVerticalScrollEnabled()
615 bool IsVerticalScrollEnabled() const;
618 * @copydoc Text::Controller::SetSmoothHandlePanEnabled()
620 void SetSmoothHandlePanEnabled(bool enable);
623 * @copydoc Text::Controller::IsSmoothHandlePanEnabled()
625 bool IsSmoothHandlePanEnabled() const;
629 * @brief A reference counted object may only be deleted by calling Unreference().
631 virtual ~Decorator();
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.
639 Decorator(ControllerInterface& controller,
640 TextSelectionPopupCallbackInterface& callbackInterface);
643 Decorator(const Decorator& handle);
646 Decorator& operator=(const Decorator& handle);
654 } // namespace Toolkit
658 #endif // DALI_TOOLKIT_TEXT_DECORATOR_H