2 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <dali-toolkit/internal/controls/text-input/text-input-decorator-impl.h>
22 #include <dali/public-api/adaptor-framework/clipboard.h>
23 #include <dali/public-api/common/stage.h>
24 #include <dali/public-api/events/pan-gesture.h>
25 #include <dali/public-api/object/property-notification.h>
26 #include <dali/integration-api/debug.h>
29 #include <dali-toolkit/internal/controls/text-input/text-input-handles-impl.h>
35 #if defined(DEBUG_ENABLED)
36 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_TEXT_INPUT_DECORATOR");
39 const Vector3 DEFAULT_SELECTION_HANDLE_SIZE( 51.0f, 79.0f, 0.0f );
40 const float TOP_HANDLE_TOP_OFFSET(-1.5f); // Offset between top handle and cutCopyPaste pop-up
41 const float BOTTOM_HANDLE_BOTTOM_OFFSET(1.5f); // Offset between bottom handle and cutCopyPaste pop-up
42 const float UI_Z_OFFSET( 0.2f ); // Text Selection Handles/Cursor z-offset.
43 const Vector3 UI_OFFSET(0.0f, 0.0f, UI_Z_OFFSET); // Text Selection Handles/Cursor offset.
44 const char* DEFAULT_CURSOR( DALI_IMAGE_DIR "cursor.png" );
45 const Vector4 DEFAULT_CURSOR_IMAGE_9_BORDER( 2.0f, 2.0f, 2.0f, 2.0f );
46 const std::size_t CURSOR_BLINK_INTERVAL = 500; // Cursor blink interval
47 const float CURSOR_THICKNESS(6.0f);
48 const Degree CURSOR_ANGLE_OFFSET(2.0f); // Offset from the angle
50 const unsigned int SCROLL_TICK_INTERVAL = 50u;
51 const float SCROLL_THRESHOLD = 10.f;
52 const float SCROLL_SPEED = 15.f;
55 * Whether the given position plus the cursor size offset is inside the given boundary.
57 * @param[in] position The given position.
58 * @param[in] cursorSize The cursor size.
59 * @param[in] controlSize The given boundary.
60 * @param[in] threshold imaginary indent around boundary that will trigger the position to be outside of control.
62 * @return whether the given position is inside the given boundary.
64 bool IsPositionWithinControl( const Vector3& position, const Size& cursorSize, const Vector3& controlSize, const Vector2 threshold = Vector2::ZERO )
66 return ( position.x >= -Math::MACHINE_EPSILON_1000 + threshold.x ) &&
67 ( position.x <= controlSize.width - threshold.x + Math::MACHINE_EPSILON_1000 ) &&
68 ( position.y - cursorSize.height >= -Math::MACHINE_EPSILON_1000 + threshold.y ) &&
69 ( position.y <= controlSize.height + Math::MACHINE_EPSILON_1000 - threshold.y);
83 Decorator::Decorator( TextViewCharacterPositioning& textViewManager, TextInputTextStyle& textStyle ):
84 mTextViewCharacterPositioning( textViewManager ),
85 mTextStyle( textStyle ),
87 mTextHighlight( textViewManager ),
88 mCursorBlinkStatus( true ),
89 mCursorVisibility( true ),
90 mGrabHandleEnabled( true )
94 Decorator::~Decorator()
101 void Decorator::SetBoundingBox( const Rect<float>& boundingRectangle )
103 // Convert to world coordinates and store as a Vector4 to be compatible with Property Notifications.
104 Vector2 stageSize = Dali::Stage::GetCurrent().GetSize();
106 const float originX = boundingRectangle.x - 0.5f * stageSize.width;
107 const float originY = boundingRectangle.y - 0.5f * stageSize.height;
109 const Vector4 boundary( originX,
111 originX + boundingRectangle.width,
112 originY + boundingRectangle.height );
114 mBoundingRectangleWorldCoordinates = boundary;
117 Vector4 Decorator::GetBoundingBox() const
119 return mBoundingRectangleWorldCoordinates;
125 void Decorator::OnHandlePan(Actor actor, PanGesture gesture)
127 Actor selectionHandleOne = mTextInputHandles.GetSelectionHandleOne();
128 Actor selectionHandleTwo = mTextInputHandles.GetSelectionHandleTwo();
130 switch (gesture.state)
132 case Gesture::Started:
133 // fall through so code not duplicated
134 case Gesture::Continuing:
136 if ( actor.GetParent() == mTextInputHandles.GetSelectionHandleOne() )
138 MoveSelectionHandle( selectionHandleOne, mSelectionHandleOneActualPosition, mSelectionHandleOnePosition, gesture.displacement );
141 else if ( actor.GetParent() == mTextInputHandles.GetSelectionHandleTwo() )
143 MoveSelectionHandle( selectionHandleTwo, mSelectionHandleTwoActualPosition, mSelectionHandleTwoPosition, gesture.displacement );
146 else if ( actor.GetParent() == mTextInputHandles.GetGrabHandle() )
148 SetCursorVisibility( true );
149 ShowGrabHandle( mGrabHandleVisibility && mIsGrabHandleInScrollArea );
150 MoveGrabHandle( gesture.displacement );
151 HidePopUp(); // Do not show popup while handle is moving
156 case Gesture::Finished:
158 // Revert back to non-pressed selection handle images
159 if ( actor.GetParent() == mTextInputHandles.GetSelectionHandleOne() )
161 mSelectionHandleOneActualPosition = MoveSelectionHandle( selectionHandleOne, mSelectionHandleOneActualPosition, mSelectionHandleOnePosition, gesture.displacement );
162 ShowPopupCutCopyPaste();
164 else if ( actor.GetParent() == mTextInputHandles.GetSelectionHandleTwo() )
166 mSelectionHandleTwoActualPosition = MoveSelectionHandle( selectionHandleTwo, mSelectionHandleTwoActualPosition, mSelectionHandleTwoPosition, gesture.displacement );
167 ShowPopupCutCopyPaste();
169 else if ( actor.GetParent() == mTextInputHandles.GetGrabHandle() )
171 MoveGrabHandle( gesture.displacement );
172 SetCursorVisibility( true );
173 ShowPopupCutCopyPaste();
182 void Decorator::CreateSelectionHandles( Actor targetParent )
184 if ( !mPanGestureDetector )
186 mPanGestureDetector = PanGestureDetector::New();
187 mPanGestureDetector.DetectedSignal().Connect(this, &Decorator::OnHandlePan);
190 if ( !mTextInputHandles.GetSelectionHandleOne() )
192 mTextInputHandles.CreateSelectionHandles();
194 mTextInputHandles.AttachSelectionHandlesToGivenPanGesture( mPanGestureDetector );
196 targetParent.Add( mTextInputHandles.GetSelectionHandleOne() );
197 targetParent.Add( mTextInputHandles.GetSelectionHandleTwo() );
199 SetUpHandlePropertyNotifications();
203 void Decorator::RemoveSelectionHandles()
205 mTextInputHandles.DestorySelectionHandles();
208 Vector3 Decorator::GetSelectionHandleSize()
210 return DEFAULT_SELECTION_HANDLE_SIZE;
213 std::size_t Decorator::GetHandleOnePosition() const
215 return mSelectionHandleOnePosition;
218 std::size_t Decorator::GetHandleTwoPosition() const
220 return mSelectionHandleTwoPosition;
223 Vector3 Decorator::PositionSelectionHandle( Actor selectionHandle, std::size_t position )
225 bool direction(false);
226 Vector3 alternatePosition;
227 bool alternatePositionValid(false);
229 Vector3 actualPositionOfSelectionHandle = mTextViewCharacterPositioning.GetActualPositionFromCharacterPosition( position, direction, alternatePosition,alternatePositionValid );
231 return PositionSelectionHandle( selectionHandle, actualPositionOfSelectionHandle, position );
235 Vector3 Decorator::PositionSelectionHandle( Actor selectionHandle, Vector3& actualPosition, std::size_t position )
237 const Vector3 DEFAULT_HANDLE_OFFSET(0.0f, -5.0f, 0.0f);
239 selectionHandle.SetPosition( actualPosition += DEFAULT_HANDLE_OFFSET );
241 if( mTextViewCharacterPositioning.IsScrollEnabled() )
243 const Vector3 controlSize = mTextViewCharacterPositioning.GetTextView().GetCurrentSize();
244 const Size cursorSize( GetCursorSizeAt( position ) );
245 bool handleVisible = IsPositionWithinControl( actualPosition, Vector2(DEFAULT_HANDLE_OFFSET.width, DEFAULT_HANDLE_OFFSET.height), controlSize );
247 DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextInputDecorationLayouter::PositionSelectionHandle controlSize[%f,%f] cursorSize[%f,%f] actualPos[%f,%f] visible[%s] \n",
248 controlSize.x, controlSize.y, cursorSize.x, cursorSize.y, actualPosition.x, actualPosition.y, ( handleVisible )?"true":"false" );
250 selectionHandle.SetVisible( handleVisible );
252 return actualPosition;
255 void Decorator::SetSelectionHandlesVisibility(bool visible )
257 mTextInputHandles.SetSelectionHandleOneVisibility( visible );
258 mTextInputHandles.SetSelectionHandleTwoVisibility( visible );
261 void Decorator::PositionSelectionHandles( std::size_t start, std::size_t end )
263 mSelectionHandleOnePosition = start;
264 mSelectionHandleTwoPosition = end;
266 mTextViewCharacterPositioning.UpdateTextLayoutInfo();
268 mSelectionHandleOneActualPosition = PositionSelectionHandle( mTextInputHandles.GetSelectionHandleOne(), mSelectionHandleOnePosition );
269 mSelectionHandleTwoActualPosition = PositionSelectionHandle( mTextInputHandles.GetSelectionHandleTwo(), mSelectionHandleTwoPosition );
272 Vector3 Decorator::MoveSelectionHandle( Actor selectionHandle,
273 Vector3& actualSelectionHandlePosition,
274 std::size_t& currentSelectionHandlePosition,
275 const Vector2& displacement )
277 Vector3 actualHandlePosition;
278 actualSelectionHandlePosition.x += displacement.x * selectionHandle.GetCurrentScale().x;
279 actualSelectionHandlePosition.y += displacement.y * selectionHandle.GetCurrentScale().y;;
281 // Selection handles should jump to the nearest character
282 std::size_t newHandlePosition = 0;
283 newHandlePosition = mTextViewCharacterPositioning.ReturnClosestIndex( actualSelectionHandlePosition.GetVectorXY() );
285 bool direction(false);
286 Vector3 alternatePosition;
287 bool alternatePositionValid(false);
288 actualHandlePosition = mTextViewCharacterPositioning.GetActualPositionFromCharacterPosition( newHandlePosition,direction, alternatePosition, alternatePositionValid );
290 bool handleVisible = true;
293 if( mTextViewCharacterPositioning.IsScrollEnabled() )
295 const Vector3 controlSize = mTextViewCharacterPositioning.GetTextView().GetCurrentSize();
296 const Size cursorSize( GetCursorSizeAt( newHandlePosition ) );
298 handleVisible = IsPositionWithinControl( actualHandlePosition,
305 mCurrentHandlePosition = actualHandlePosition;
306 mScrollDisplacement = Vector2::ZERO;
311 if( ( actualHandlePosition.x < SCROLL_THRESHOLD ) && ( displacement.x <= 0.f ) )
313 mScrollDisplacement.x = -SCROLL_SPEED;
315 else if( ( actualHandlePosition.x > controlSize.width - SCROLL_THRESHOLD ) && ( displacement.x >= 0.f ) )
317 mScrollDisplacement.x = SCROLL_SPEED;
319 if( ( actualHandlePosition.y < SCROLL_THRESHOLD ) && ( displacement.y <= 0.f ) )
321 mScrollDisplacement.y = -SCROLL_SPEED;
323 else if( ( actualHandlePosition.y > controlSize.height - SCROLL_THRESHOLD ) && ( displacement.y >= 0.f ) )
325 mScrollDisplacement.y = SCROLL_SPEED;
327 DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextInputDecorationLayouter::MoveSelectionHandle Handle not visible scroll displacement [%f]\n", mScrollDisplacement.x);
333 if ( handleVisible && // Ensure the handle is visible.
334 ( newHandlePosition != currentSelectionHandlePosition ) && // Ensure the handle has moved.
335 ( newHandlePosition != mSelectionHandleTwoPosition ) && // Ensure new handle position not the same position as an existing handle.
336 ( newHandlePosition != mSelectionHandleOnePosition ) )
338 DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextInputDecorationLayouter::MoveSelectionHandle Handle visible and moved]\n");
340 currentSelectionHandlePosition = newHandlePosition;
342 PositionSelectionHandle( selectionHandle, actualHandlePosition, newHandlePosition );
344 ShowUpdatedHighlight();
346 // Set Active Style to that of first character in selection
347 std::size_t firstHandleInSelection = std::min( mSelectionHandleOnePosition, mSelectionHandleTwoPosition );
349 const TextStyle inputStyle = mTextViewCharacterPositioning.GetStyleAt( firstHandleInSelection );
350 mTextStyle.SetInputStyle( inputStyle );
352 return actualHandlePosition; // Returns Handle position passed in if new value not assigned.
358 void Decorator::PositionGrabHandle( std::size_t positionInText )
360 bool direction(false);
361 Vector3 alternatePosition;
362 bool alternatePositionValid(false);
364 mGrabHandlePosition = positionInText;
366 mTextViewCharacterPositioning.UpdateTextLayoutInfo();
367 mActualGrabHandlePosition = mTextViewCharacterPositioning.GetActualPositionFromCharacterPosition( positionInText, direction, alternatePosition,alternatePositionValid );
369 mTextInputHandles.GetGrabHandle().SetPosition( mActualGrabHandlePosition );
372 void Decorator::MoveGrabHandle( const Vector2& displacement /*, std::size_t currentHandlePosition */)
374 mActualGrabHandlePosition.x += displacement.x;
375 mActualGrabHandlePosition.y += displacement.y;
377 // Grab handle should jump to the nearest character and take cursor with it
378 std::size_t newHandlePosition = mTextViewCharacterPositioning.ReturnClosestIndex( mActualGrabHandlePosition.GetVectorXY() );
380 Vector3 actualHandlePosition = mTextViewCharacterPositioning.GetActualPositionFromCharacterPosition( newHandlePosition );
382 bool handleVisible = true;
384 if( mTextViewCharacterPositioning.IsScrollEnabled() )
386 const Vector3 controlSize = mTextViewCharacterPositioning.GetTextView().GetCurrentSize();
387 const Size cursorSize( GetCursorSizeAt( newHandlePosition ) );
388 // Scrolls the text if the handle is not in a visible position
389 handleVisible = IsPositionWithinControl( actualHandlePosition,
393 DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextInputDecorationLayouter::MoveGrabHandle handleVisible[%s]\n", ( handleVisible )?"true":"false");
398 mCurrentHandlePosition = actualHandlePosition;
399 mScrollDisplacement = Vector2::ZERO;
403 if( ( actualHandlePosition.x < SCROLL_THRESHOLD ) && ( displacement.x <= 0.f ) )
405 mScrollDisplacement.x = -SCROLL_SPEED;
407 else if( ( actualHandlePosition.x > controlSize.width - SCROLL_THRESHOLD ) && ( displacement.x >= 0.f ) )
409 mScrollDisplacement.x = SCROLL_SPEED;
411 if( ( actualHandlePosition.y < SCROLL_THRESHOLD ) && ( displacement.y <= 0.f ) )
413 mScrollDisplacement.y = -SCROLL_SPEED;
415 else if( ( actualHandlePosition.y > controlSize.height - SCROLL_THRESHOLD ) && ( displacement.y >= 0.f ) )
417 mScrollDisplacement.y = SCROLL_SPEED;
423 if( ( newHandlePosition != mGrabHandlePosition ) && // Only redraw cursor and do updates if position changed
424 ( handleVisible ) )// and the new position is visible (if scroll is not enabled, it's always true).
426 mActualGrabHandlePosition = actualHandlePosition;
427 mTextInputHandles.GetGrabHandle().SetPosition( mActualGrabHandlePosition );
429 //PositionGrabHandle( newHandlePosition );
430 mGrabHandlePosition = newHandlePosition;
431 SetCurrentCursorPosition( mGrabHandlePosition );
432 DrawCursor( mGrabHandlePosition );
434 const std::size_t cursorPosition = GetCurrentCursorPosition();
436 // Let keyboard know the new cursor position so can 're-capture' for prediction.
437 mCursorRePositionedSignal.Emit();
439 // Set Input Style to that of cursor position
440 if ( !mTextViewCharacterPositioning.IsStyledTextEmpty() && ( cursorPosition > 0 ) )
442 DALI_ASSERT_DEBUG( ( 0 <= cursorPosition-1 ) && ( cursorPosition-1 < mTextViewCharacterPositioning.StyledTextSize() ) );
443 const TextStyle inputStyle = mTextViewCharacterPositioning.GetStyleAt( cursorPosition-1 );
444 mTextStyle.SetInputStyle( inputStyle );
449 void Decorator::ShowGrabHandle( bool visible )
451 mGrabHandleVisibility = visible;
452 mTextInputHandles.SetGrabHandleVisibility( visible );
455 void Decorator::CreateGrabHandle( Actor targetParent )
457 if ( !mPanGestureDetector )
459 mPanGestureDetector = PanGestureDetector::New();
460 mPanGestureDetector.DetectedSignal().Connect(this, &Decorator::OnHandlePan);
463 if ( !mTextInputHandles.GetGrabHandle() )
465 mTextInputHandles.CreateGrabHandle();
466 mTextInputHandles.AttachGrabHandleToGivenPanGesture( mPanGestureDetector );
467 targetParent.Add( mTextInputHandles.GetGrabHandle() );
471 void Decorator::SetGrabHandleImage( Image image )
473 mTextInputHandles.SetGrabHandleImage( image );
476 void Decorator::EnableGrabHandle( bool toggle)
478 // enables grab handle with will in turn de-activate magnifier
479 mGrabHandleEnabled = toggle;
482 bool Decorator::IsGrabHandleEnabled()
484 // if false then magnifier will be shown instead.
485 return mGrabHandleEnabled;
491 std::size_t Decorator::GetCurrentCursorPosition() const
493 return mCursorPosition;
496 void Decorator::SetCurrentCursorPosition( std::size_t newCursorPosition )
498 mCursorPosition = newCursorPosition;
501 void Decorator::SetCursorVisibility( bool visible )
503 DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextInputDecorationLayouter::SetCursorVisibility[%s]\n", ( visible )?"true":"false");
505 mCursorVisibility = visible;
506 mCursor.SetVisible( mCursorVisibility && mIsCursorInScrollArea );
507 mCursorRTL.SetVisible( mCursorVisibility && mCursorRTLEnabled );
510 void Decorator::DrawCursor(const std::size_t nthChar)
512 std::size_t cursorPosition = GetCurrentCursorPosition();
514 // Get height of cursor and set its size
515 Size size( CURSOR_THICKNESS, 0.0f );
516 if ( !mTextViewCharacterPositioning.IsTextEmpty() )
518 Vector2 min, max; // out parameters for GetRowRectFromCharacterPosition
519 size.height = mTextViewCharacterPositioning.GetRowRectFromCharacterPosition( mTextViewCharacterPositioning.GetVisualPosition( cursorPosition ), min, max ).height;
523 // Measure Font so know how big text will be if no initial text to measure.
524 size.height = mTextViewCharacterPositioning.GetLineHeight( nthChar );
527 mCursor.SetSize(size);
529 // If the character is italic then the cursor also tilts.
530 if ( !mTextViewCharacterPositioning.IsStyledTextEmpty() && ( cursorPosition > 0 ) )
532 DALI_ASSERT_DEBUG( ( 0 <= cursorPosition-1 ) && ( cursorPosition-1 < mTextViewCharacterPositioning.StyledTextSize() ) );
533 const TextStyle styleAtCursor = mTextViewCharacterPositioning.GetStyleAt( cursorPosition-1 );
534 mCursor.SetRotation( styleAtCursor.IsItalicsEnabled() ? Degree( styleAtCursor.GetItalicsAngle() - CURSOR_ANGLE_OFFSET ) : Degree( 0.f ), Vector3::ZAXIS );
537 DALI_ASSERT_DEBUG( cursorPosition <= mTextViewCharacterPositioning.GetNumberOfCharactersInText() );
538 if ( ( cursorPosition <= mTextViewCharacterPositioning.GetNumberOfCharactersInText() ) )
540 Vector3 altPosition; // Alternate (i.e. opposite direction) cursor position.
541 bool altPositionValid( false ); // Alternate cursor validity flag.
542 bool directionRTL( false ); // Need to know direction of primary cursor (in case we have 2 cursors and need to show them differently)
543 Vector3 position = mTextViewCharacterPositioning.GetActualPositionFromCharacterPosition( cursorPosition, directionRTL, altPosition, altPositionValid );
545 SetAltCursorEnabled( altPositionValid );
547 if(!altPositionValid)
549 mCursor.SetPosition( position + UI_OFFSET );
554 mCursor.SetSize(size);
555 mCursor.SetPosition( position + UI_OFFSET - Vector3(0.0f, directionRTL ? 0.0f : size.height, 0.0f) );
556 Vector2 min, max; // out parameters for GetRowRectFromCharacterPosition
557 Size rowSize = mTextViewCharacterPositioning.GetRowRectFromCharacterPosition( mTextViewCharacterPositioning.GetVisualPosition( cursorPosition ), min, max );
558 size.height = rowSize.height * 0.5f;
559 mCursorRTL.SetSize(size);
560 mCursorRTL.SetPosition( altPosition + UI_OFFSET - Vector3(0.0f, directionRTL ? size.height : 0.0f, 0.0f) );
563 if( mTextViewCharacterPositioning.IsScrollEnabled() )
565 // Whether cursor and grab handle are inside the boundaries of the text-input when text scroll is enabled.
566 const Vector3& controlSize = mTextViewCharacterPositioning.GetTextView().GetCurrentSize();
567 mIsCursorInScrollArea = mIsGrabHandleInScrollArea = IsPositionWithinControl( position, size, controlSize );
572 void Decorator::SetAltCursorEnabled( bool enabled )
574 mCursorRTLEnabled = enabled;
575 mCursorRTL.SetVisible( mCursorVisibility && mCursorRTLEnabled );
578 void Decorator::SetCursorImage(Dali::Image image, const Vector4& border )
580 DALI_ASSERT_DEBUG ( image && "Create cursor image invalid")
584 mCursor.SetImage( image );
585 mCursor.SetNinePatchBorder( border );
589 void Decorator::SetRTLCursorImage( Image image, const Vector4& border )
591 DALI_ASSERT_DEBUG ( image && "Create cursor image invalid")
595 mCursorRTL.SetImage( image );
596 mCursorRTL.SetNinePatchBorder( border );
600 ImageActor Decorator::CreateCursor( Image cursorImage, const Vector4& border, const std::string& cursorName )
606 cursor = ImageActor::New( cursorImage );
610 cursor = ImageActor::New( Image::New( DEFAULT_CURSOR ) );
613 cursor.SetStyle(ImageActor::STYLE_NINE_PATCH);
614 cursor.SetNinePatchBorder( border );
615 cursor.SetAnchorPoint(AnchorPoint::BOTTOM_CENTER);
616 cursor.SetVisible(false);
617 cursor.SetName( cursorName );
621 void Decorator::CreateCursors( Actor targetParent )
623 Image mCursorImage = Image::New( DEFAULT_CURSOR );
624 mCursor = CreateCursor (mCursorImage, DEFAULT_CURSOR_IMAGE_9_BORDER , "mainCursor");
625 mCursorRTL = CreateCursor ( mCursorImage, DEFAULT_CURSOR_IMAGE_9_BORDER, "rtlCursor");
626 targetParent.Add( mCursor );
627 targetParent.Add( mCursorRTL );
630 Size Decorator::GetCursorSizeAt( std::size_t positionWithinTextToGetCursorSize )
632 std::size_t visualPosition = mTextViewCharacterPositioning.GetVisualPosition( positionWithinTextToGetCursorSize );
636 const Size cursorSize( CURSOR_THICKNESS,
637 mTextViewCharacterPositioning.GetRowRectFromCharacterPosition( visualPosition, min, max ).height );
642 void Decorator::StartCursorBlinkTimer()
644 if ( !mCursorBlinkTimer )
646 mCursorBlinkTimer = Timer::New( CURSOR_BLINK_INTERVAL );
647 mCursorBlinkTimer.TickSignal().Connect( this, &Decorator::OnCursorBlinkTimerTick );
650 if ( !mCursorBlinkTimer.IsRunning() )
652 mCursorBlinkTimer.Start();
656 void Decorator::StopCursorBlinkTimer()
658 if ( mCursorBlinkTimer )
660 mCursorBlinkTimer.Stop();
664 bool Decorator::OnCursorBlinkTimerTick()
667 mCursor.SetVisible( mCursorVisibility && mIsCursorInScrollArea && mCursorBlinkStatus );
668 if ( mCursorRTLEnabled )
670 mCursorRTL.SetVisible( mCursorVisibility && mIsCursorInScrollArea && mCursorBlinkStatus );
672 mCursorBlinkStatus = !mCursorBlinkStatus;
680 void Decorator::ShowUpdatedHighlight()
682 Toolkit::TextView::TextLayoutInfo textLayoutInfo = mTextViewCharacterPositioning.GetLayoutInfo();
683 TextHighlight::HighlightInfo highlightInfo = mTextHighlight.CalculateHighlightInfo( mSelectionHandleOnePosition, mSelectionHandleTwoPosition, textLayoutInfo );
685 // Clamp highlightInfo so they don't exceed the boundary of the control.
686 const Vector3& controlSize = mTextViewCharacterPositioning.GetTextView().GetCurrentSize();
687 highlightInfo.Clamp2D( Vector2::ZERO, Vector2(controlSize.x, controlSize.y) );
689 mTextHighlight.UpdateHighlight( highlightInfo );
692 void Decorator::CreateHighlight( Actor parent )
694 DALI_ASSERT_DEBUG( parent && "Highlight target parent does not exist" );
696 if ( !mHighlightMeshActor )
698 mHighlightMeshActor = MeshActor::New( mTextHighlight.CreateHighLightMesh() );
699 mHighlightMeshActor.SetName( "HighlightMeshActor" );
700 mHighlightMeshActor.SetAffectedByLighting(false);
701 parent.Add( mHighlightMeshActor );
705 void Decorator::RemoveHighlight()
707 if ( mHighlightMeshActor )
709 mHighlightMeshActor.Unparent();
710 mHighlightMeshActor.Reset();
711 // NOTE: We cannot dereference mHighlightMesh, due to a how the scene-graph MeshRenderer uses the Mesh data.
715 void Decorator::HighlightVisibility( bool visiblility )
717 if ( mHighlightMeshActor )
719 mHighlightMeshActor.SetVisible( visiblility );
724 * Callbacks connected to be Property notifications for Boundary checking.
726 // Note If PropertyNotification signal definition included Actor we would not need to duplicate functions.
727 void Decorator::OnHandleOneLeavesBoundary( PropertyNotification& source)
729 mTextInputHandles.GetSelectionHandleOne().SetOpacity(0.0f);
732 void Decorator::OnHandleOneWithinBoundary(PropertyNotification& source)
734 mTextInputHandles.GetSelectionHandleOne().SetOpacity(1.0f);
737 void Decorator::OnHandleTwoLeavesBoundary( PropertyNotification& source)
739 mTextInputHandles.GetSelectionHandleTwo().SetOpacity(0.0f);
742 void Decorator::OnHandleTwoWithinBoundary(PropertyNotification& source)
744 mTextInputHandles.GetSelectionHandleTwo().SetOpacity(1.0f);
747 void Decorator::OnLeftBoundaryExceeded(PropertyNotification& source)
749 DALI_LOG_INFO(gLogFilter, Debug::General, "TextInputDecorationLayouter::OnLeftBoundaryExceeded\n");
750 Actor selectionHandleOne = mTextInputHandles.GetSelectionHandleOne();
751 selectionHandleOne.SetScale( -1.0f, 1.0f, 1.0f );
752 selectionHandleOne.SetAnchorPoint( AnchorPoint::TOP_LEFT);
755 void Decorator::OnReturnToLeftBoundary(PropertyNotification& source)
757 DALI_LOG_INFO(gLogFilter, Debug::General, "TextInputDecorationLayouter::OnReturnToLeftBoundary\n");
758 Actor selectionHandleOne = mTextInputHandles.GetSelectionHandleOne();
759 selectionHandleOne.SetScale( 1.0f, 1.0f, 1.0f );
760 selectionHandleOne.SetAnchorPoint( AnchorPoint::TOP_RIGHT);
763 void Decorator::OnRightBoundaryExceeded(PropertyNotification& source)
765 Actor selectionHandleTwo = mTextInputHandles.GetSelectionHandleTwo();
766 selectionHandleTwo.SetScale( -1.0f, 1.0f, 1.0f );
767 selectionHandleTwo.SetAnchorPoint( AnchorPoint::TOP_RIGHT);
770 void Decorator::OnReturnToRightBoundary(PropertyNotification& source)
772 Actor selectionHandleTwo = mTextInputHandles.GetSelectionHandleTwo();
773 selectionHandleTwo.SetScale( 1.0f, 1.0f, 1.0f );
774 selectionHandleTwo.SetAnchorPoint( AnchorPoint::TOP_LEFT);
777 void Decorator::SetUpHandlePropertyNotifications()
779 /* Property notifications for handles exceeding the boundary and returning back within boundary */
781 Vector3 handlesize = GetSelectionHandleSize();
783 Actor selectionHandleOne = mTextInputHandles.GetSelectionHandleOne();
784 Actor selectionHandleTwo = mTextInputHandles.GetSelectionHandleTwo();
786 // Exceeding horizontal boundary
787 PropertyNotification leftNotification = selectionHandleOne.AddPropertyNotification( Actor::WORLD_POSITION_X, LessThanCondition( mBoundingRectangleWorldCoordinates.x + handlesize.x) );
788 leftNotification.NotifySignal().Connect( this, &Decorator::OnLeftBoundaryExceeded );
790 PropertyNotification rightNotification = selectionHandleTwo.AddPropertyNotification( Actor::WORLD_POSITION_X, GreaterThanCondition( mBoundingRectangleWorldCoordinates.z - handlesize.x ) );
791 rightNotification.NotifySignal().Connect( this, &Decorator::OnRightBoundaryExceeded );
793 // Within horizontal boundary
794 PropertyNotification leftLeaveNotification = selectionHandleOne.AddPropertyNotification( Actor::WORLD_POSITION_X, GreaterThanCondition( mBoundingRectangleWorldCoordinates.x + 2*handlesize.x ) );
795 leftLeaveNotification.NotifySignal().Connect( this, &Decorator::OnReturnToLeftBoundary );
797 PropertyNotification rightLeaveNotification = selectionHandleTwo.AddPropertyNotification( Actor::WORLD_POSITION_X, LessThanCondition( mBoundingRectangleWorldCoordinates.z - 2*handlesize.x ) );
798 rightLeaveNotification.NotifySignal().Connect( this, &Decorator::OnReturnToRightBoundary );
800 // Exceeding vertical boundary
801 PropertyNotification verticalExceedNotificationOne = selectionHandleOne.AddPropertyNotification( Actor::WORLD_POSITION_Y,
802 OutsideCondition( mBoundingRectangleWorldCoordinates.y + handlesize.y,
803 mBoundingRectangleWorldCoordinates.w - handlesize.y ) );
804 verticalExceedNotificationOne.NotifySignal().Connect( this, &Decorator::OnHandleOneLeavesBoundary );
806 PropertyNotification verticalExceedNotificationTwo = selectionHandleTwo.AddPropertyNotification( Actor::WORLD_POSITION_Y,
807 OutsideCondition( mBoundingRectangleWorldCoordinates.y + handlesize.y,
808 mBoundingRectangleWorldCoordinates.w - handlesize.y ) );
809 verticalExceedNotificationTwo.NotifySignal().Connect( this, &Decorator::OnHandleTwoLeavesBoundary );
811 // Within vertical boundary
812 PropertyNotification verticalWithinNotificationOne = selectionHandleOne.AddPropertyNotification( Actor::WORLD_POSITION_Y,
813 InsideCondition( mBoundingRectangleWorldCoordinates.y + handlesize.y,
814 mBoundingRectangleWorldCoordinates.w - handlesize.y ) );
815 verticalWithinNotificationOne.NotifySignal().Connect( this, &Decorator::OnHandleOneWithinBoundary );
817 PropertyNotification verticalWithinNotificationTwo = selectionHandleTwo.AddPropertyNotification( Actor::WORLD_POSITION_Y,
818 InsideCondition( mBoundingRectangleWorldCoordinates.y + handlesize.y,
819 mBoundingRectangleWorldCoordinates.w - handlesize.y ) );
820 verticalWithinNotificationTwo.NotifySignal().Connect( this, &Decorator::OnHandleTwoWithinBoundary );
826 Vector3 Decorator::PositionOfPopUpRelativeToSelectionHandles()
833 // When text is selected, show popup above top handle (and text), or below bottom handle.
835 // topHandle: referring to the top most point of the handle or the top line of selection.
836 if ( mSelectionHandleTwoActualPosition.y > mSelectionHandleOneActualPosition.y ) // Handle may switch positions so calculate which is top.
838 topHandle = mSelectionHandleOneActualPosition;
839 rowSize= mTextViewCharacterPositioning.GetRowRectFromCharacterPosition( mSelectionHandleOnePosition, min, max );
843 topHandle = mSelectionHandleTwoActualPosition;
844 rowSize = mTextViewCharacterPositioning.GetRowRectFromCharacterPosition( mSelectionHandleTwoPosition, min, max );
846 topHandle.y += TOP_HANDLE_TOP_OFFSET - rowSize.height;
847 position = Vector3(topHandle.x, topHandle.y, 0.0f);
852 Vector3 Decorator::AlternatePopUpPositionRelativeToSelectionHandles()
854 // alternativePosition: referring to the bottom most point of the handle or the bottom line of selection.
855 Vector3 alternativePosition;
856 alternativePosition.y = std::max ( mSelectionHandleTwoActualPosition.y , mSelectionHandleOneActualPosition.y );
857 alternativePosition.y += GetSelectionHandleSize().y + mPopUpPanel.GetSize().y + BOTTOM_HANDLE_BOTTOM_OFFSET;
859 return alternativePosition;
862 Vector3 Decorator::PositionOfPopUpRelativeToCursor()
864 // When no text is selected, show PopUp at position of cursor
867 std::size_t cursorPosition = GetCurrentCursorPosition();
868 position = mTextViewCharacterPositioning.GetActualPositionFromCharacterPosition( cursorPosition );
869 const Size rowSize = mTextViewCharacterPositioning.GetRowRectFromCharacterPosition( cursorPosition, min, max );
870 position.y -= rowSize.height;
875 Vector3 Decorator::AlternatePopUpPositionRelativeToCursor()
877 std::size_t cursorPosition = GetCurrentCursorPosition();
878 Vector3 alternativePosition = mTextViewCharacterPositioning.GetActualPositionFromCharacterPosition( cursorPosition );
880 if ( mTextInputHandles.GetGrabHandle() )
882 // If grab handle enabled then position pop-up below the grab handle.
883 alternativePosition.y += mTextInputHandles.GetGrabHandle().GetCurrentSize().height + mPopUpPanel.GetSize().y + BOTTOM_HANDLE_BOTTOM_OFFSET ;
887 alternativePosition.y += mPopUpPanel.GetSize().y;
890 return alternativePosition;
894 Vector3 Decorator::PositionOfPopUpRelativeToGrabHandle()
896 return Vector3::ZERO;
899 void Decorator::ShowPopUp()
902 Vector3 alternativePosition;
905 DALI_ASSERT_DEBUG( mPopUpTarget && "PopUp Target Actor does not exist" );
907 if( mHighlightMeshActor ) // Text Selection mode
909 position = PositionOfPopUpRelativeToSelectionHandles();
911 else // Not in Text Selection mode so position relative to cursor.
913 position = PositionOfPopUpRelativeToCursor();
916 // reposition popup above the desired cursor position.
917 mPopUpPanel.Show( mPopUpTarget, true );
918 mPopUpPanel.Self().SetPosition( position );
919 mPopUpPanel.PressedSignal().Connect( this, &Decorator::OnPopupButtonPressed );
921 SetUpPopUpPositionNotifications();
922 mPopUpPanel.ApplyConfinementConstraint( mBoundingRectangleWorldCoordinates );
925 void Decorator::ShowPopUp( Actor target )
927 mPopUpTarget = target;
928 ShowPopupCutCopyPaste();
931 void Decorator::ShowPopupCutCopyPaste()
933 bool isAllTextSelectedAlready = ( mTextViewCharacterPositioning.StyledTextSize() == GetSelectedText().size() );
934 bool isTextEmpty = mTextViewCharacterPositioning.IsStyledTextEmpty() ;
935 bool isSubsetOfTextAlreadySelected = ( !isAllTextSelectedAlready ) && mHighlightMeshActor;
937 Clipboard clipboard = Clipboard::Get();
938 bool hasClipboardGotContent = clipboard.NumberOfItems();
940 mPopUpPanel.CreateCutCopyPastePopUp( isAllTextSelectedAlready, isTextEmpty, hasClipboardGotContent, isSubsetOfTextAlreadySelected );
944 void Decorator::HidePopUp( bool animate, bool signalFinished )
946 if ( ( mPopUpPanel.GetState() == TextInputPopupNew::StateShowing ) || ( mPopUpPanel.GetState() == TextInputPopupNew::StateShown ) )
948 mPopUpPanel.Hide( animate );
952 void Decorator::AddPopupOption(const std::string& name, const std::string& caption, const Image icon, bool finalOption)
954 mPopUpPanel.AddButton(name, caption, icon, finalOption);
957 void Decorator::ClearPopup()
962 void Decorator::PopUpLeavesVerticalBoundary( PropertyNotification& source)
964 Vector3 position, alternativePosition;
966 if( mHighlightMeshActor ) // Text Selection mode
968 alternativePosition = AlternatePopUpPositionRelativeToSelectionHandles();
970 else // Not in Text Selection mode
972 alternativePosition = AlternatePopUpPositionRelativeToCursor();
973 // if can't be positioned above, then position below row.
975 // reposition popup above the desired cursor position.
976 mPopUpPanel.Self().SetPosition( alternativePosition );
979 void Decorator::SetUpPopUpPositionNotifications( )
981 // Note Property notifications ignore any set anchor point so conditions must allow for this. Default is Top Left.
983 // Exceeding vertical boundary
984 PropertyNotification verticalExceedNotificationOne = mPopUpPanel.Self().AddPropertyNotification( Actor::WORLD_POSITION_Y,
985 OutsideCondition( mBoundingRectangleWorldCoordinates.y + mPopUpPanel.GetSize().y/2,
986 mBoundingRectangleWorldCoordinates.w - mPopUpPanel.GetSize().y/2 ) );
987 verticalExceedNotificationOne.NotifySignal().Connect( this, &Decorator::PopUpLeavesVerticalBoundary );
990 bool Decorator::OnPopupButtonPressed( Toolkit::Button button )
992 mPopUpButtonPressedSignal.Emit( button );
996 Decorator::PressedSignal& Decorator::PopUpButtonPressedSignal()
998 return mPopUpButtonPressedSignal;
1001 Decorator::CursorPositionedSignal& Decorator::CursorRePositionedSignal()
1003 return mCursorRePositionedSignal;
1007 * Decoration Positioning during Scrolling
1009 void Decorator::TextViewScrolled( Toolkit::TextView textView, Vector2 scrollPosition )
1011 DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextInputDecorationLayouter::TextViewScrolled\n");
1013 const Vector3& controlSize = mTextViewCharacterPositioning.GetTextView().GetCurrentSize(); // todo Could store size and only update in Control Size change.
1014 Size cursorSize( CURSOR_THICKNESS, 0.f );
1016 // Updates the cursor and grab handle position and visibility.
1017 if( mTextInputHandles.GetGrabHandle() || mCursor )
1020 size_t cursorTextPosition = GetCurrentCursorPosition();
1021 cursorSize.height = mTextViewCharacterPositioning.GetRowRectFromCharacterPosition( cursorTextPosition, min, max ).height;
1023 const Vector3 cursorPosition = mTextViewCharacterPositioning.GetActualPositionFromCharacterPosition( cursorTextPosition );
1025 bool mIsCursorInScrollArea = IsPositionWithinControl( cursorPosition, cursorSize, controlSize );
1026 bool mIsGrabHandleInScrollArea = mIsCursorInScrollArea;
1028 Vector2 actualGrabHandlePosition = cursorPosition.GetVectorXY();
1030 if( mTextInputHandles.GetGrabHandle() )
1032 ShowGrabHandle( mGrabHandleVisibility && mIsGrabHandleInScrollArea );
1033 PositionGrabHandle( cursorTextPosition );
1038 mCursor.SetVisible( mCursorVisibility && mIsCursorInScrollArea );
1039 DrawCursor( cursorTextPosition );
1040 mCursor.SetPosition( Vector3(actualGrabHandlePosition) + UI_OFFSET );
1044 Actor selectionHandleOne = mTextInputHandles.GetSelectionHandleOne();
1045 Actor selectionHandleTwo = mTextInputHandles.GetSelectionHandleTwo();
1047 // Updates the selection handles and highlighted text position and visibility.
1048 if( mTextInputHandles.GetSelectionHandleOne() && mTextInputHandles.GetSelectionHandleTwo() )
1050 const Vector3 cursorPositionOne = mTextViewCharacterPositioning.GetActualPositionFromCharacterPosition( mSelectionHandleOnePosition );
1051 const Vector3 cursorPositionTwo = mTextViewCharacterPositioning.GetActualPositionFromCharacterPosition( mSelectionHandleTwoPosition );
1053 Size cursorSize( GetCursorSizeAt( mSelectionHandleOnePosition ) );
1054 const bool isSelectionHandleOneVisible = IsPositionWithinControl( cursorPositionOne, cursorSize, controlSize );
1056 cursorSize = GetCursorSizeAt( mSelectionHandleTwoPosition );
1057 const bool isSelectionHandleTwoVisible = IsPositionWithinControl( cursorPositionTwo, cursorSize, controlSize );
1059 mSelectionHandleOneActualPosition = cursorPositionOne.GetVectorXY();
1060 mSelectionHandleTwoActualPosition = cursorPositionTwo.GetVectorXY();
1062 selectionHandleOne.SetVisible( isSelectionHandleOneVisible );
1063 selectionHandleTwo.SetVisible( isSelectionHandleTwoVisible );
1065 PositionSelectionHandle( selectionHandleOne, mSelectionHandleOneActualPosition, mSelectionHandleOnePosition );
1066 PositionSelectionHandle( selectionHandleTwo, mSelectionHandleTwoActualPosition, mSelectionHandleTwoPosition );
1068 if( mHighlightMeshActor )
1070 mHighlightMeshActor.SetVisible( true );
1071 ShowUpdatedHighlight();
1076 void Decorator::StartScrollTimer()
1080 mScrollTimer = Timer::New( SCROLL_TICK_INTERVAL );
1081 mScrollTimer.TickSignal().Connect( this, &Decorator::OnScrollTimerTick );
1084 if( !mScrollTimer.IsRunning() )
1086 DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextInputDecorationLayouter::StartScrollTimer\n");
1087 mScrollTimer.Start();
1091 void Decorator::StopScrollTimer()
1095 DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextInputDecorationLayouter::StopScrollTimer\n");
1097 mScrollTimer.Stop();
1098 mScrollTimer.Reset();
1102 bool Decorator::OnScrollTimerTick()
1104 DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextInputDecorationLayouter::OnScrollTimerTick\n");
1106 if ( mGrabHandleVisibility && mTextInputHandles.GetGrabHandle() )
1108 std::size_t newGrabHandlePosition = mTextViewCharacterPositioning.ReturnClosestIndex( mActualGrabHandlePosition.GetVectorXY() );
1109 if ( mGrabHandlePosition != newGrabHandlePosition )
1111 Vector2 scrollPosition = mTextViewCharacterPositioning.GetScrollPosition();
1112 Vector2 scrollDelta = ( mActualGrabHandlePosition - mCurrentHandlePosition ).GetVectorXY();
1113 DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextInputDecorationLayouter::OnScrollTimerTick scrollPosition(%f) scrollDelta(%f)\n", scrollPosition.x, scrollDelta.x);
1114 scrollPosition += scrollDelta;
1115 mTextViewCharacterPositioning.SetScrollPosition( scrollPosition );
1117 // If scroll position goes too far TextView will trim it to fit.
1118 if ( mTextViewCharacterPositioning.IsScrollPositionTrimmed() )
1123 mActualGrabHandlePosition = mTextViewCharacterPositioning.GetActualPositionFromCharacterPosition( newGrabHandlePosition ).GetVectorXY();
1127 Actor selectionHandleOne = mTextInputHandles.GetSelectionHandleOne();
1128 Actor selectionHandleTwo = mTextInputHandles.GetSelectionHandleTwo();
1130 if ( selectionHandleOne && selectionHandleTwo )
1132 std::size_t newHandleOnePosition = mTextViewCharacterPositioning.ReturnClosestIndex( mSelectionHandleOneActualPosition.GetVectorXY() );
1134 // todo duplicated code should be a function
1136 if ( mSelectionHandleOnePosition != newHandleOnePosition )
1138 const Vector3 actualPosition = mTextViewCharacterPositioning.GetActualPositionFromCharacterPosition( newHandleOnePosition );
1140 Vector2 scrollDelta = ( actualPosition - mSelectionHandleOneActualPosition ).GetVectorXY();
1142 Vector2 scrollPosition = mTextViewCharacterPositioning.GetScrollPosition();
1143 scrollPosition += scrollDelta;
1144 mTextViewCharacterPositioning.SetScrollPosition( scrollPosition );
1146 if( mTextViewCharacterPositioning.IsScrollPositionTrimmed() )
1151 mSelectionHandleOnePosition = newHandleOnePosition;
1152 mSelectionHandleOneActualPosition = mTextViewCharacterPositioning.GetActualPositionFromCharacterPosition( mSelectionHandleOnePosition ).GetVectorXY();
1156 mSelectionHandleOneActualPosition.x += mScrollDisplacement.x;
1157 mSelectionHandleOneActualPosition.y += mScrollDisplacement.y;
1160 std::size_t newHandleTwoPosition = mTextViewCharacterPositioning.ReturnClosestIndex( mSelectionHandleTwoActualPosition.GetVectorXY() );
1162 if ( mSelectionHandleTwoPosition != newHandleTwoPosition )
1164 const Vector3 actualPosition = mTextViewCharacterPositioning.GetActualPositionFromCharacterPosition( newHandleTwoPosition );
1166 Vector2 scrollDelta = ( actualPosition - mSelectionHandleTwoActualPosition ).GetVectorXY();
1168 Vector2 scrollPosition = mTextViewCharacterPositioning.GetScrollPosition();
1169 scrollPosition += scrollDelta;
1170 mTextViewCharacterPositioning.SetScrollPosition( scrollPosition );
1172 if( mTextViewCharacterPositioning.IsScrollPositionTrimmed() )
1177 mSelectionHandleTwoPosition = newHandleTwoPosition;
1178 mCurrentHandlePosition = mTextViewCharacterPositioning.GetActualPositionFromCharacterPosition( mSelectionHandleTwoPosition ).GetVectorXY();
1183 mSelectionHandleTwoActualPosition.x += mScrollDisplacement.x;
1184 mSelectionHandleTwoActualPosition.y += mScrollDisplacement.y;
1194 MarkupProcessor::StyledTextArray Decorator::GetSelectedText()
1196 MarkupProcessor::StyledTextArray currentSelectedText;
1198 if ( mHighlightMeshActor ) // Text Selected
1200 MarkupProcessor::StyledTextArray::iterator it = mTextViewCharacterPositioning.GetStyledTextArray().begin() + std::min(mSelectionHandleOnePosition, mSelectionHandleTwoPosition);
1201 MarkupProcessor::StyledTextArray::iterator end = mTextViewCharacterPositioning.GetStyledTextArray().begin() + std::max(mSelectionHandleOnePosition, mSelectionHandleTwoPosition);
1203 for(; it != end; ++it)
1205 MarkupProcessor::StyledText& styledText( *it );
1206 currentSelectedText.push_back( styledText );
1209 return currentSelectedText;
1214 } // namespace Toolkit