1 #ifndef __DALI_TOOLKIT_INTERNAL_TEXT_INPUT_DECORATOR_H__
2 #define __DALI_TOOLKIT_INTERNAL_TEXT_INPUT_DECORATOR_H__
5 * Copyright (c) 2014 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/actors/image-actor.h>
23 #include <dali/public-api/actors/mesh-actor.h>
24 #include <dali/public-api/adaptor-framework/timer.h>
25 #include <dali/public-api/animation/animation.h>
26 #include <dali/public-api/common/intrusive-ptr.h>
27 #include <dali/public-api/geometry/mesh.h>
28 #include <dali/public-api/signals/connection-tracker.h>
31 #include <dali-toolkit/internal/controls/text-input/textview-character-positions-impl.h>
32 #include <dali-toolkit/internal/controls/text-input/text-input-handles-impl.h>
33 #include <dali-toolkit/internal/controls/text-input/text-input-text-highlight-impl.h>
34 #include <dali-toolkit/internal/controls/text-input/text-input-popup-new-impl.h>
47 typedef IntrusivePtr<Decorator> DecoratorPtr;
50 * @brief Decorator Class
52 * Decorations are Selection Handles, cursor, grab handle, magnifier the "cut copy paste" PopUp and Selection highlight.
53 * The Decorator triggers creation of these decorations and positions them.
54 * Decoration positions can be dependent on other decorations like the PopUp on the Selection handles.
55 * The decorator maintains a Bounding Box which the decorations have to be positioned within, decorations can be flipped or hidden to obey this Bounding Box.
56 * Scrolling of Text can effect positioning of decorations, the decorator repositions decorations in this case.
59 class Decorator : public ConnectionTracker
67 * @param[in] textviewManager TextViewManager to be used
69 Decorator( TextViewCharacterPositioning& textviewManager, TextInputTextStyle& textStyle);
72 * @brief Default destructor
77 * @brief Set the dimensions of the bounding rectangle for decorations to obey.
79 * @param[in] boundingRectangle
81 void SetBoundingBox( const Rect<float>& boundingRectangle );
84 * @brief Get the bounding dimensions of the bounding box
86 * @return dimensions of the bounding box from world origin. (x, y, w, z )
102 Vector4 GetBoundingBox() const;
105 * @brief Callback when a handle is panned/moved, either selection handles or grab handle
107 * @param actor Handle of the selection or grab handle.
108 * @param gesture Data structure with the parameters of the gesture.
110 void OnHandlePan(Actor actor, const PanGesture& gesture);
115 * @brief Create a left and right selection handle and parent both to the provided actor
116 * @param[in] parent actor in which the handles should be added to.
118 void CreateSelectionHandles( Actor parent );
121 * @brief Remove selection handles from their parent
123 void RemoveSelectionHandles();
126 * @brief Get size of Selection handles
128 * @return size of a selection handle
130 Vector3 GetSelectionHandleSize();
133 * @brief Get position of Selection handle within text
135 * @return character position of a selection handle one
137 std::size_t GetHandleOnePosition() const;
140 * @brief Get position of Selection handle within text
142 * @return character position of a selection handle two
144 std::size_t GetHandleTwoPosition() const;
147 * @brief Position Selection a single handle at given positions within the text string.
149 * @param[in] selectionHandle handle to be positioned
150 * @param[in] position where to place handle
151 * @return Vector3 Position of handle as a coordinate.
153 Vector3 PositionSelectionHandle( Actor selectionHandle, std::size_t position );
156 * @brief Position Selection a single handle at given coordinates
158 * @param[in] selectionHandle handle to be positioned
159 * @param[in] actualPosition coordinates to position handle
160 * @param[in] position where to place handle
161 * @return Vector3 Position of handle as a coordinate.
163 Vector3 PositionSelectionHandle( Actor selectionHandle, Vector3& actualPosition, std::size_t position );
166 * @brief Make both selection handle visible or invisible
167 * @param[in] visible true to make visible, false to fine
169 void SetSelectionHandlesVisibility( bool visible );
172 * @brief Position Selection handles at given positions within the text string.
174 * @param[in] start where to place first handle
175 * @param[in] end where to place second handle
177 void PositionSelectionHandles( std::size_t start, std::size_t end );
180 * @brief Move selection handle by the given displacement.
182 * @param[in] selectionHandle Actor to move
183 * @param[in] actualSelectionHandlePosition actual current position of the handle in x y z
184 * @param[in] currentSelectionHandlePosition current position along the string
185 * @param[in] displacement the x y displacement
187 Vector3 MoveSelectionHandle( Actor selectionHandle,
188 Vector3& actualSelectionHandlePosition,
189 std::size_t& currentSelectionHandlePosition,
190 const Vector2& displacement );
195 * @brief Position GrabHandlewith depending on the the character in the text it should be placed at
196 * @param[in] positonInText the character position within the text the handle should be at
198 void PositionGrabHandle( std::size_t positionInText );
201 * @brief Move grab handle to the required position within the text
203 * @param[in] displacement Displacement of the grab handle in actor coordinates.
205 void MoveGrabHandle( const Vector2& displacement );
208 * @brief Show or hide the GrabHandle is visibility is true
210 * @param[in] visible flag to show or not show the grab handle
212 void ShowGrabHandle( bool visible );
215 * @brief Create the GrabHandle used to position cursor
216 * @param[in] targetParent the Actor to parent the GrabHandle
218 void CreateGrabHandle( Actor targetParent );
221 * @brief Set the image to be used as the cursor grab hander
222 * @pre The text input actor has been initialised.
223 * @param[in] image The image to be used.
225 void SetGrabHandleImage( Image image );
228 * @brief Toggle to enable the grab handle, used to position cursor when magnifier not being used.
229 * Default behaviour is to use the magnifier to position the cursor, enabling this prevents the magnifier from being shown.
230 * @param[in] toggle true to enable, false to disable grab handle
232 void EnableGrabHandle(bool toggle);
235 * @brief Method to check if grab handle is enabled, if false then the magnifier will be used to position cursor.
236 * @return bool returns true is grab handle enabled.
238 bool IsGrabHandleEnabled();
243 * @brief Get the current Cursor position
244 * @return current cursor position
246 std::size_t GetCurrentCursorPosition() const;
249 * @brief Set the Cursor position
250 * @param[in] the position the cursor should be set to
252 void SetCurrentCursorPosition( std::size_t newCursorPosition );
255 * @brief Set if the cursors are visible or not.
256 * @param[in] visible flag true for visible
258 void SetCursorVisibility( bool visible );
261 * @brief Display cursor
262 * @param[in] nthChar position in text string to display cursor
264 void DrawCursor( const std::size_t nthChar = 0 );
267 * Sets alternate cursor enable state
268 * @see SetCursorVisibility
269 * alternate cursor will only be visible if both SetCursorVisiblity
270 * and cursor enabled have been set to true.
272 void SetAltCursorEnabled( bool enabled );
275 * @brief Set the image to be used for the regular left to right cursor
276 * @pre The text input actor has been initialised.
277 * @param[in] image The image to be used.
278 * @param[in] border The nine patch border for the image.
280 void SetCursorImage( Image image, const Vector4& border );
283 * @brief Set the image to be used for the Right to Left cursor
284 * @pre The text input actor has been initialised.
285 * @param[in] image The image to be used.
286 * @param[in] border The nine patch border for the image.
288 void SetRTLCursorImage( Image image, const Vector4& border );
291 * @brief Creates a cursor from the supplied image and nine patch border.
292 * @param[in] cursorImage the image to be used for the cursor.
293 * @param[in] border the nine patch border corresponding to the supplied image.
294 * @paran[in] cursorName actor name for cursor
295 * @return the image actor to be used as the cursor.
297 ImageActor CreateCursor( Image cursorImage, const Vector4& border, const std::string& cursorName );
300 * @brief Creates a regular and Right-To-Left cursor and parents them to give target Actor
301 * @param[in] targetParent target Actor
303 void CreateCursors( Actor targetParent );
306 * @Brief Returns the cursor size at a given position in the text.
307 * @return Size the size of the cursor
309 Size GetCursorSizeAt( std::size_t positionWithinTextToGetCursorSize );
312 * @brief Start a timer to signal cursor to blink.
314 void StartCursorBlinkTimer();
317 * @brief Stop the timer signalling the cursor to blink.
319 void StopCursorBlinkTimer();
322 * @brief Callback when handle timer ticks.
324 * Cursor should become visible/invisible to simulate blinking.
326 * @return True if the timer should be keep running.
328 bool OnCursorBlinkTimerTick();
330 /* Selection Highlight */
333 * @brief Updates mesh data for selection highlight depending on handle positions and displays it.
335 void ShowUpdatedHighlight();
338 * @brief Creates the Highlight used for selection
340 * @param[in] parent target actor in which the handles should be added to.
342 void CreateHighlight( Actor parent );
345 * @brief Remove Highlight actor from it's parent
347 void RemoveHighlight();
350 * @brief Set the visibility of the Highlight
352 * @param[in] visibility True to show and False to hide.
354 void HighlightVisibility( bool visiblility );
356 /* Boundary Property Notifications when handle exceed bounding box*/
359 * @brief PropertyNotification Callback when left boundary exceeded so handle can be flipped.
361 * @param[in] source PropertyNotification
363 void OnLeftBoundaryExceeded( PropertyNotification& source );
365 * @brief PropertyNotification Callback when within left boundary so handle can be flipped back.
367 * @param[in] source PropertyNotification
369 void OnReturnToLeftBoundary( PropertyNotification& source );
371 * @brief PropertyNotification Callback when right boundary exceeded so handle can be flipped.
373 * @param[in] source PropertyNotification
375 void OnRightBoundaryExceeded( PropertyNotification& source );
377 * @brief PropertyNotification Callback when within right boundary so handle can be flipped back.
379 * @param[in] source PropertyNotification
381 void OnReturnToRightBoundary( PropertyNotification& source );
384 * @brief PropertyNotification Callbacks for hiding handle one when it exceeds boundary.
386 * @param[in] source PropertyNotification
388 void OnHandleOneLeavesBoundary( PropertyNotification& source );
390 * @brief PropertyNotification Callbacks for showing hidden handle one when returns within boundary
392 * @param[in] source PropertyNotification
394 void OnHandleOneWithinBoundary( PropertyNotification& source );
396 * @brief PropertyNotification Callbacks for hiding handle two it when exceeds boundary.
398 * @param[in] source PropertyNotification
400 void OnHandleTwoLeavesBoundary( PropertyNotification& source );
402 * @brief PropertyNotification Callbacks for showing hidden handle two when returns within boundary
404 * @param[in] source PropertyNotification
406 void OnHandleTwoWithinBoundary( PropertyNotification& source );
409 * @brief Set up property notifications on the position of the handles to facilitate flipping and hiding when at screen boundary.
411 void SetUpHandlePropertyNotifications();
413 // Cut & Paste Pop-up
416 * @brief Calculate positioning of PopUp relative to handles
417 * @return Actual position of PopUp
419 Vector3 PositionOfPopUpRelativeToSelectionHandles( );
422 * @brief Calculate alternative position of PopUp relative to handles when can it not be displayed in the default upper position.
423 * @return Actual position of PopUp
425 Vector3 AlternatePopUpPositionRelativeToSelectionHandles();
428 * @brief Calculate positioning of PopUp relative to cursor
429 * @return Actual position of PopUp
431 Vector3 PositionOfPopUpRelativeToCursor();
434 * @brief Calculate alternative position of PopUp relative to cursor when can not be displayed in normal upper position.
435 * @return Actual position of PopUp
437 Vector3 AlternatePopUpPositionRelativeToCursor();
440 * @brief Calculate positioning of PopUp relative to GrabHandle
441 * @return Actual position of PopUp
443 Vector3 PositionOfPopUpRelativeToGrabHandle();
446 * @brief Show the PopUp in the provided target
447 * @param[in] target target actor in which the PopUp should be added to.
449 void ShowPopUp( Actor target );
452 * @brief Show PopUp in previously set Target.
453 * @pre Must have previously called ShopPopUp( Actor target ) otherwise PopUp will not be shown.
458 * @brief Create and Show Cut Copy Paste PopUp
460 void ShowPopupCutCopyPaste();
464 * @param[in] animate Animate or just hide instantly, default is true
465 * @param[in] signalFinished Signal when finished, default is true
467 void HidePopUp( bool animate=true, bool signalFinished=true );
470 * @brief Adds a popup option.
471 * @brief Creates popup frame if not already created.
472 * @param[in] name The unique name for this option.
473 * @param[in] caption The caption (label) for this option
474 * @param[in] icon the image icon to be displayed for this option
475 * @param[in] finalOption Flag to indicate that this is the final option.
476 * (set to true on the last option you add)
478 void AddPopupOption(const std::string& name, const std::string& caption, const Image icon, bool finalOption = false);
481 * @brief Removes popup, and its options.
486 * @brief PropertyNotification Callbacks for flipping PopUp when exceeds boundary.
487 * @param[in] source PropertyNotification
489 void PopUpLeavesVerticalBoundary( PropertyNotification& source );
492 * @brief Setup position notifications when PopUp exceeds boundary
494 void SetUpPopUpPositionNotifications( );
497 * @brief Callback for when a button is pressed in popup panel
498 * @param[in] button handle to the button pressed.
499 * @return bool consummation
501 bool OnPopupButtonPressed( Toolkit::Button button );
503 // Decoration positioning during scrolling
506 * @brief Updates the position of the decorations when Text is scrolled.
508 * @param[in] textView Handle of the text-view.
509 * @param[in] scrollPosition The difference with the previous scroll position.
511 void TextViewScrolled( Toolkit::TextView textView, Vector2 scrollPosition );
514 * @brief Creates and starts a timer to scroll the text when handles are close to the edges of the text-input.
516 * It only starts the timer if it's already created.
518 void StartScrollTimer();
521 * @brief Stops the timer used to scroll the text.
523 void StopScrollTimer();
526 * @brief Scroll Text according to handle position
527 * @param[in out] handlePosition handle position within character string
528 * @param[in] actual vector position of handle
529 * @return updated actual vector position of handle
531 Vector3 ScrollRelativeToHandle( std::size_t& handlePosition, Vector3& actualHandlePosition );
534 * @brief Callback called by the timer used to scroll the text.
536 * It calculates and sets a new scroll position.
538 bool OnScrollTimerTick();
543 * @brief Function to get Text selected between the 2 selection handles.
544 * @return StyledTextArray an array of
546 MarkupProcessor::StyledTextArray GetSelectedText();
551 * @brief Copy Constructor
552 * @param[in] decorator
555 Decorator(const Decorator& decorator);
558 * @Assignment Constructor
562 Decorator& operator=(const Decorator& rhs);
566 typedef Signal< bool( Toolkit::Button ) > PressedSignal;
567 typedef Signal< void () > CursorPositionedSignal;
569 * @brief Signal emitted when the button is touched.
570 * This is relayed from the PopUp class. It enables the owner of the Decorator to act on the PopUp button press.
572 PressedSignal& PopUpButtonPressedSignal();
575 * @brief Signal emitted when the cursor is repositioned
576 * @param[in] cursor the new cursor position
578 CursorPositionedSignal& CursorRePositionedSignal();
582 Vector4 mBoundingRectangleWorldCoordinates;
584 TextViewCharacterPositioning& mTextViewCharacterPositioning;
586 TextInputHandles mTextInputHandles;
588 TextInputTextStyle& mTextStyle;
590 Vector3 mSelectionHandleOneActualPosition; // Actual x y position of handle
591 Vector3 mSelectionHandleTwoActualPosition; // Actual x y position of handle
592 std::size_t mSelectionHandleOnePosition; // Position of handle along the string of text
593 std::size_t mSelectionHandleTwoPosition; // Position of handle along the string of text
595 TextInputPopupNew mPopUpPanel; // PopUp used for Cut Cpoy and Paste
596 Actor mPopUpTarget; // Target Actor to parent PopUp
598 Vector3 mActualGrabHandlePosition; // Actual position of grab handle, this might not be snapped to a character
599 std::size_t mGrabHandlePosition; // Position of grab handle along the string of text
600 Vector3 mCurrentHandlePosition;
602 std::size_t mCursorPosition; // Current cursor position within the text string
603 ImageActor mCursor; // Cursor overlayed on Text to show where new text will be inserted
604 ImageActor mCursorRTL; // Right To Left Cursor overlayed on Text (where new RTL text would be inserted)
605 Animation mCursorAnimation; // Animation for cursor blinking.
606 Timer mCursorBlinkTimer; // Timer to signal cursor to blink
608 Vector2 mScrollDisplacement; // How much to scroll by
609 Timer mScrollTimer; // Timer to scroll text over a period of time not all in one update.
611 TextHighlight mTextHighlight; // Holds data required to construct the highlight
612 MeshActor mHighlightMeshActor; // Mesh Actor to display highlight
614 PanGestureDetector mPanGestureDetector;
616 PressedSignal mPopUpButtonPressedSignal; // Signal emitted when a button within the popup is pressed.
617 CursorPositionedSignal mCursorRePositionedSignal; // Signal emitted when a button when cursor position is changed.
619 bool mCursorBlinkStatus:1; // \e true shows the cursor, \e false hides it.
620 bool mCursorVisibility:1; // Should cursor be visible
621 bool mCursorRTLEnabled:1; // Enable state of Alternate RTL Cursor (need to keep track of this as it's not always enabled)
622 bool mIsGrabHandleInScrollArea:1; // Whether the grab handle is inside the boundaries of the text-input.
623 bool mIsCursorInScrollArea:1; // Whether the cursor is inside the boundaries of the text-input.
624 bool mGrabHandleVisibility:1; // Should grab handle be visible
625 bool mGrabHandleEnabled:1; // Flag to enable the grab handle instead of the default magnifier.
628 } // namespace Internal
630 } // namespace Toolkit
634 #endif // __DALI_TOOLKIT_INTERNAL_TEXT_INPUT_DECORATOR_H__