Problem:TextInput is a huge class with many responsibilities, it's hard to maintain and decorations can not be re-used.
Solution: Spilt into multiple classes. In this patch the Decorator initiates creation of decorations and positions them.
Stubbed Decoration classes provided for build purposes.
Change-Id: Ib880849dbc80cb1b6510a06401f5a6bfccfa55e8
Signed-off-by: Agnelo Vaz <agnelo.vaz@samsung.com>
--- /dev/null
+//
+// Copyright (c) 2014 Samsung Electronics Co., Ltd.
+//
+// Licensed under the Flora License, Version 1.0 (the License);
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://floralicense.org/license/
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an AS IS BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include <dali/integration-api/debug.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/controls/text-input/text-input-decorator-impl.h>
+
+#include <dali-toolkit/internal/controls/text-input/text-input-handles-impl.h>
+
+using namespace Dali;
+
+namespace
+{
+#if defined(DEBUG_ENABLED)
+ Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_TEXT_INPUT_DECORATOR");
+#endif
+
+ const Vector3 DEFAULT_SELECTION_HANDLE_SIZE( 51.0f, 79.0f, 0.0f );
+ const float TOP_HANDLE_TOP_OFFSET(-1.5f); // Offset between top handle and cutCopyPaste pop-up
+ const float BOTTOM_HANDLE_BOTTOM_OFFSET(1.5f); // Offset between bottom handle and cutCopyPaste pop-up
+ const float UI_Z_OFFSET( 0.2f ); // Text Selection Handles/Cursor z-offset.
+ const Vector3 UI_OFFSET(0.0f, 0.0f, UI_Z_OFFSET); // Text Selection Handles/Cursor offset.
+ const char* DEFAULT_CURSOR( DALI_IMAGE_DIR "cursor.png" );
+ const Vector4 DEFAULT_CURSOR_IMAGE_9_BORDER( 2.0f, 2.0f, 2.0f, 2.0f );
+ const std::size_t CURSOR_BLINK_INTERVAL = 500; // Cursor blink interval
+ const float CURSOR_THICKNESS(6.0f);
+ const Degree CURSOR_ANGLE_OFFSET(2.0f); // Offset from the angle
+
+ const unsigned int SCROLL_TICK_INTERVAL = 50u;
+ const float SCROLL_THRESHOLD = 10.f;
+ const float SCROLL_SPEED = 15.f;
+
+ /**
+ * Whether the given position plus the cursor size offset is inside the given boundary.
+ *
+ * @param[in] position The given position.
+ * @param[in] cursorSize The cursor size.
+ * @param[in] controlSize The given boundary.
+ * @param[in] threshold imaginary indent around boundary that will trigger the position to be outside of control.
+ *
+ * @return whether the given position is inside the given boundary.
+ */
+ bool IsPositionWithinControl( const Vector3& position, const Size& cursorSize, const Vector3& controlSize, const Vector2 threshold = Vector2::ZERO )
+ {
+ return ( position.x >= -Math::MACHINE_EPSILON_1000 + threshold.x ) &&
+ ( position.x <= controlSize.width - threshold.x + Math::MACHINE_EPSILON_1000 ) &&
+ ( position.y - cursorSize.height >= -Math::MACHINE_EPSILON_1000 + threshold.y ) &&
+ ( position.y <= controlSize.height + Math::MACHINE_EPSILON_1000 - threshold.y);
+ }
+}
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+Decorator::Decorator( TextViewCharacterPositioning& textViewManager, TextInputTextStyle& textStyle ):
+ mTextViewCharacterPositioning( textViewManager ),
+ mTextStyle( textStyle ),
+ mCursorPosition( 0 ),
+ mTextHighlight( textViewManager ),
+ mCursorBlinkStatus( true ),
+ mCursorVisibility( true ),
+ mGrabHandleEnabled( true )
+{
+}
+
+Decorator::~Decorator()
+{
+}
+
+/**
+ * Bounding Box
+ */
+void Decorator::SetBoundingBox( const Rect<float>& boundingRectangle )
+{
+ // Convert to world coordinates and store as a Vector4 to be compatible with Property Notifications.
+ Vector2 stageSize = Dali::Stage::GetCurrent().GetSize();
+
+ const float originX = boundingRectangle.x - 0.5f * stageSize.width;
+ const float originY = boundingRectangle.y - 0.5f * stageSize.height;
+
+ const Vector4 boundary( originX,
+ originY,
+ originX + boundingRectangle.width,
+ originY + boundingRectangle.height );
+
+ mBoundingRectangleWorldCoordinates = boundary;
+}
+
+Vector4 Decorator::GetBoundingBox() const
+{
+ return mBoundingRectangleWorldCoordinates;
+}
+
+/**
+ * Selection Handles
+ */
+void Decorator::OnHandlePan(Actor actor, PanGesture gesture)
+{
+ Actor selectionHandleOne = mTextInputHandles.GetSelectionHandleOne();
+ Actor selectionHandleTwo = mTextInputHandles.GetSelectionHandleTwo();
+
+ switch (gesture.state)
+ {
+ case Gesture::Started:
+ // fall through so code not duplicated
+ case Gesture::Continuing:
+ {
+ if ( actor.GetParent() == mTextInputHandles.GetSelectionHandleOne() )
+ {
+ MoveSelectionHandle( selectionHandleOne, mSelectionHandleOneActualPosition, mSelectionHandleOnePosition, gesture.displacement );
+ HidePopUp();
+ }
+ else if ( actor.GetParent() == mTextInputHandles.GetSelectionHandleTwo() )
+ {
+ MoveSelectionHandle( selectionHandleTwo, mSelectionHandleTwoActualPosition, mSelectionHandleTwoPosition, gesture.displacement );
+ HidePopUp();
+ }
+ else if ( actor.GetParent() == mTextInputHandles.GetGrabHandle() )
+ {
+ SetCursorVisibility( true );
+ ShowGrabHandle( mGrabHandleVisibility && mIsGrabHandleInScrollArea );
+ MoveGrabHandle( gesture.displacement );
+ HidePopUp(); // Do not show popup while handle is moving
+ }
+ }
+ break;
+
+ case Gesture::Finished:
+ {
+ // Revert back to non-pressed selection handle images
+ if ( actor.GetParent() == mTextInputHandles.GetSelectionHandleOne() )
+ {
+ mSelectionHandleOneActualPosition = MoveSelectionHandle( selectionHandleOne, mSelectionHandleOneActualPosition, mSelectionHandleOnePosition, gesture.displacement );
+ ShowPopupCutCopyPaste();
+ ShowPopUp();
+ }
+ else if ( actor.GetParent() == mTextInputHandles.GetSelectionHandleTwo() )
+ {
+ mSelectionHandleTwoActualPosition = MoveSelectionHandle( selectionHandleTwo, mSelectionHandleTwoActualPosition, mSelectionHandleTwoPosition, gesture.displacement );
+ ShowPopupCutCopyPaste();
+ ShowPopUp();
+ }
+ else if ( actor.GetParent() == mTextInputHandles.GetGrabHandle() )
+ {
+ MoveGrabHandle( gesture.displacement );
+ SetCursorVisibility( true );
+ ShowPopupCutCopyPaste();
+ ShowPopUp();
+ }
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+void Decorator::CreateSelectionHandles( Actor targetParent )
+{
+ if ( !mPanGestureDetector )
+ {
+ mPanGestureDetector = PanGestureDetector::New();
+ mPanGestureDetector.DetectedSignal().Connect(this, &Decorator::OnHandlePan);
+ }
+
+ if ( !mTextInputHandles.GetSelectionHandleOne() )
+ {
+ mTextInputHandles.CreateSelectionHandles();
+
+ mTextInputHandles.AttachSelectionHandlesToGivenPanGesture( mPanGestureDetector );
+
+ targetParent.Add( mTextInputHandles.GetSelectionHandleOne() );
+ targetParent.Add( mTextInputHandles.GetSelectionHandleTwo() );
+
+ SetUpHandlePropertyNotifications();
+ }
+}
+
+void Decorator::RemoveSelectionHandles()
+{
+ mTextInputHandles.DestorySelectionHandles();
+}
+
+Vector3 Decorator::GetSelectionHandleSize()
+{
+ return DEFAULT_SELECTION_HANDLE_SIZE;
+}
+
+std::size_t Decorator::GetHandleOnePosition() const
+{
+ return mSelectionHandleOnePosition;
+}
+
+std::size_t Decorator::GetHandleTwoPosition() const
+{
+ return mSelectionHandleTwoPosition;
+}
+
+Vector3 Decorator::PositionSelectionHandle( Actor selectionHandle, std::size_t position )
+{
+ bool direction(false);
+ Vector3 alternatePosition;
+ bool alternatePositionValid(false);
+
+ Vector3 actualPositionOfSelectionHandle = mTextViewCharacterPositioning.GetActualPositionFromCharacterPosition( position, direction, alternatePosition,alternatePositionValid );
+
+ return PositionSelectionHandle( selectionHandle, actualPositionOfSelectionHandle, position );
+
+}
+
+Vector3 Decorator::PositionSelectionHandle( Actor selectionHandle, Vector3& actualPosition, std::size_t position )
+{
+ const Vector3 DEFAULT_HANDLE_OFFSET(0.0f, -5.0f, 0.0f);
+
+ selectionHandle.SetPosition( actualPosition += DEFAULT_HANDLE_OFFSET );
+
+ if( mTextViewCharacterPositioning.IsScrollEnabled() )
+ {
+ const Vector3 controlSize = mTextViewCharacterPositioning.GetTextView().GetCurrentSize();
+ const Size cursorSize( GetCursorSizeAt( position ) );
+ bool handleVisible = IsPositionWithinControl( actualPosition, Vector2(DEFAULT_HANDLE_OFFSET.width, DEFAULT_HANDLE_OFFSET.height), controlSize );
+
+ DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextInputDecorationLayouter::PositionSelectionHandle controlSize[%f,%f] cursorSize[%f,%f] actualPos[%f,%f] visible[%s] \n",
+ controlSize.x, controlSize.y, cursorSize.x, cursorSize.y, actualPosition.x, actualPosition.y, ( handleVisible )?"true":"false" );
+
+ selectionHandle.SetVisible( handleVisible );
+ }
+ return actualPosition;
+}
+
+void Decorator::SetSelectionHandlesVisibility(bool visible )
+{
+ mTextInputHandles.SetSelectionHandleOneVisibility( visible );
+ mTextInputHandles.SetSelectionHandleTwoVisibility( visible );
+}
+
+bool Decorator::OnHandleReleased()
+{
+ ShowPopUp();
+ return false;
+}
+
+void Decorator::PositionSelectionHandles( std::size_t start, std::size_t end )
+{
+ mSelectionHandleOnePosition = start;
+ mSelectionHandleTwoPosition = end;
+
+ mTextViewCharacterPositioning.UpdateTextLayoutInfo();
+
+ mSelectionHandleOneActualPosition = PositionSelectionHandle( mTextInputHandles.GetSelectionHandleOne(), mSelectionHandleOnePosition );
+ mSelectionHandleTwoActualPosition = PositionSelectionHandle( mTextInputHandles.GetSelectionHandleTwo(), mSelectionHandleTwoPosition );
+
+ mTextInputHandles.ReleasedSignal().Connect( this, &Decorator::OnHandleReleased );
+}
+
+Vector3 Decorator::MoveSelectionHandle( Actor selectionHandle,
+ Vector3& actualSelectionHandlePosition,
+ std::size_t& currentSelectionHandlePosition,
+ const Vector2& displacement )
+{
+ Vector3 actualHandlePosition;
+ actualSelectionHandlePosition.x += displacement.x * selectionHandle.GetCurrentScale().x;
+ actualSelectionHandlePosition.y += displacement.y * selectionHandle.GetCurrentScale().y;;
+
+ // Selection handles should jump to the nearest character
+ std::size_t newHandlePosition = 0;
+ newHandlePosition = mTextViewCharacterPositioning.ReturnClosestIndex( actualSelectionHandlePosition.GetVectorXY() );
+
+ bool direction(false);
+ Vector3 alternatePosition;
+ bool alternatePositionValid(false);
+ actualHandlePosition = mTextViewCharacterPositioning.GetActualPositionFromCharacterPosition( newHandlePosition,direction, alternatePosition, alternatePositionValid );
+
+ bool handleVisible = true;
+
+ Vector2 min, max;
+ if( mTextViewCharacterPositioning.IsScrollEnabled() )
+ {
+ const Vector3 controlSize = mTextViewCharacterPositioning.GetTextView().GetCurrentSize();
+ const Size cursorSize( GetCursorSizeAt( newHandlePosition ) );
+
+ handleVisible = IsPositionWithinControl( actualHandlePosition,
+ cursorSize,
+ controlSize );
+
+ if( handleVisible )
+ {
+ StopScrollTimer();
+ mCurrentHandlePosition = actualHandlePosition;
+ mScrollDisplacement = Vector2::ZERO;
+ }
+ else
+ {
+
+ if( ( actualHandlePosition.x < SCROLL_THRESHOLD ) && ( displacement.x <= 0.f ) )
+ {
+ mScrollDisplacement.x = -SCROLL_SPEED;
+ }
+ else if( ( actualHandlePosition.x > controlSize.width - SCROLL_THRESHOLD ) && ( displacement.x >= 0.f ) )
+ {
+ mScrollDisplacement.x = SCROLL_SPEED;
+ }
+ if( ( actualHandlePosition.y < SCROLL_THRESHOLD ) && ( displacement.y <= 0.f ) )
+ {
+ mScrollDisplacement.y = -SCROLL_SPEED;
+ }
+ else if( ( actualHandlePosition.y > controlSize.height - SCROLL_THRESHOLD ) && ( displacement.y >= 0.f ) )
+ {
+ mScrollDisplacement.y = SCROLL_SPEED;
+ }
+ DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextInputDecorationLayouter::MoveSelectionHandle Handle not visible scroll displacement [%f]\n", mScrollDisplacement.x);
+
+ StartScrollTimer();
+ }
+ }
+
+ if ( handleVisible && // Ensure the handle is visible.
+ ( newHandlePosition != currentSelectionHandlePosition ) && // Ensure the handle has moved.
+ ( newHandlePosition != mSelectionHandleTwoPosition ) && // Ensure new handle position not the same position as an existing handle.
+ ( newHandlePosition != mSelectionHandleOnePosition ) )
+ {
+ DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextInputDecorationLayouter::MoveSelectionHandle Handle visible and moved]\n");
+
+ currentSelectionHandlePosition = newHandlePosition;
+
+ PositionSelectionHandle( selectionHandle, actualHandlePosition, newHandlePosition );
+
+ ShowUpdatedHighlight();
+
+ // Set Active Style to that of first character in selection
+ std::size_t firstHandleInSelection = std::min( mSelectionHandleOnePosition, mSelectionHandleTwoPosition );
+
+ const TextStyle inputStyle = mTextViewCharacterPositioning.GetStyleAt( firstHandleInSelection );
+ mTextStyle.SetInputStyle( inputStyle );
+ }
+ return actualHandlePosition; // Returns Handle position passed in if new value not assigned.
+}
+
+/**
+ * GrabHandle
+ */
+void Decorator::PositionGrabHandle( std::size_t positionInText )
+{
+ bool direction(false);
+ Vector3 alternatePosition;
+ bool alternatePositionValid(false);
+
+ mGrabHandlePosition = positionInText;
+
+ mTextViewCharacterPositioning.UpdateTextLayoutInfo();
+ mActualGrabHandlePosition = mTextViewCharacterPositioning.GetActualPositionFromCharacterPosition( positionInText, direction, alternatePosition,alternatePositionValid );
+
+ mTextInputHandles.GetGrabHandle().SetPosition( mActualGrabHandlePosition );
+}
+
+void Decorator::MoveGrabHandle( const Vector2& displacement /*, std::size_t currentHandlePosition */)
+{
+ mActualGrabHandlePosition.x += displacement.x;
+ mActualGrabHandlePosition.y += displacement.y;
+
+ // Grab handle should jump to the nearest character and take cursor with it
+ std::size_t newHandlePosition = mTextViewCharacterPositioning.ReturnClosestIndex( mActualGrabHandlePosition.GetVectorXY() );
+
+ Vector3 actualHandlePosition = mTextViewCharacterPositioning.GetActualPositionFromCharacterPosition( newHandlePosition );
+
+ bool handleVisible = true;
+
+ if( mTextViewCharacterPositioning.IsScrollEnabled() )
+ {
+ const Vector3 controlSize = mTextViewCharacterPositioning.GetTextView().GetCurrentSize();
+ const Size cursorSize( GetCursorSizeAt( newHandlePosition ) );
+ // Scrolls the text if the handle is not in a visible position
+ handleVisible = IsPositionWithinControl( actualHandlePosition,
+ cursorSize,
+ controlSize );
+
+ DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextInputDecorationLayouter::MoveGrabHandle handleVisible[%s]\n", ( handleVisible )?"true":"false");
+
+ if( handleVisible )
+ {
+ StopScrollTimer();
+ mCurrentHandlePosition = actualHandlePosition;
+ mScrollDisplacement = Vector2::ZERO;
+ }
+ else
+ {
+ if( ( actualHandlePosition.x < SCROLL_THRESHOLD ) && ( displacement.x <= 0.f ) )
+ {
+ mScrollDisplacement.x = -SCROLL_SPEED;
+ }
+ else if( ( actualHandlePosition.x > controlSize.width - SCROLL_THRESHOLD ) && ( displacement.x >= 0.f ) )
+ {
+ mScrollDisplacement.x = SCROLL_SPEED;
+ }
+ if( ( actualHandlePosition.y < SCROLL_THRESHOLD ) && ( displacement.y <= 0.f ) )
+ {
+ mScrollDisplacement.y = -SCROLL_SPEED;
+ }
+ else if( ( actualHandlePosition.y > controlSize.height - SCROLL_THRESHOLD ) && ( displacement.y >= 0.f ) )
+ {
+ mScrollDisplacement.y = SCROLL_SPEED;
+ }
+ StartScrollTimer();
+ }
+ }
+
+ if( ( newHandlePosition != mGrabHandlePosition ) && // Only redraw cursor and do updates if position changed
+ ( handleVisible ) )// and the new position is visible (if scroll is not enabled, it's always true).
+ {
+ mActualGrabHandlePosition = actualHandlePosition;
+ mTextInputHandles.GetGrabHandle().SetPosition( mActualGrabHandlePosition );
+
+ //PositionGrabHandle( newHandlePosition );
+ mGrabHandlePosition = newHandlePosition;
+ SetCurrentCursorPosition( mGrabHandlePosition );
+ DrawCursor( mGrabHandlePosition );
+
+ const std::size_t cursorPosition = GetCurrentCursorPosition();
+
+ // Let keyboard know the new cursor position so can 're-capture' for prediction.
+ mCursorRePositionedSignal.Emit();
+
+ // Set Input Style to that of cursor position
+ if ( !mTextViewCharacterPositioning.IsStyledTextEmpty() && ( cursorPosition > 0 ) )
+ {
+ DALI_ASSERT_DEBUG( ( 0 <= cursorPosition-1 ) && ( cursorPosition-1 < mTextViewCharacterPositioning.StyledTextSize() ) );
+ const TextStyle inputStyle = mTextViewCharacterPositioning.GetStyleAt( cursorPosition-1 );
+ mTextStyle.SetInputStyle( inputStyle );
+ }
+ }
+}
+
+void Decorator::ShowGrabHandle( bool visible )
+{
+ mGrabHandleVisibility = visible;
+ mTextInputHandles.SetGrabHandleVisibility( visible );
+}
+
+void Decorator::CreateGrabHandle( Actor targetParent )
+{
+ if ( !mPanGestureDetector )
+ {
+ mPanGestureDetector = PanGestureDetector::New();
+ mPanGestureDetector.DetectedSignal().Connect(this, &Decorator::OnHandlePan);
+ }
+
+ if ( !mTextInputHandles.GetGrabHandle() )
+ {
+ mTextInputHandles.CreateGrabHandle();
+ mTextInputHandles.AttachGrabHandleToGivenPanGesture( mPanGestureDetector );
+ targetParent.Add( mTextInputHandles.GetGrabHandle() );
+ }
+}
+
+void Decorator::SetGrabHandleImage( Image image )
+{
+ mTextInputHandles.SetGrabHandleImage( image );
+}
+
+void Decorator::EnableGrabHandle( bool toggle)
+{
+ // enables grab handle with will in turn de-activate magnifier
+ mGrabHandleEnabled = toggle;
+}
+
+bool Decorator::IsGrabHandleEnabled()
+{
+ // if false then magnifier will be shown instead.
+ return mGrabHandleEnabled;
+}
+
+/**
+ * Cursor
+ */
+std::size_t Decorator::GetCurrentCursorPosition() const
+{
+ return mCursorPosition;
+}
+
+void Decorator::SetCurrentCursorPosition( std::size_t newCursorPosition )
+{
+ mCursorPosition = newCursorPosition;
+}
+
+void Decorator::SetCursorVisibility( bool visible )
+{
+ DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextInputDecorationLayouter::SetCursorVisibility[%s]\n", ( visible )?"true":"false");
+
+ mCursorVisibility = visible;
+ mCursor.SetVisible( mCursorVisibility && mIsCursorInScrollArea );
+ mCursorRTL.SetVisible( mCursorVisibility && mCursorRTLEnabled );
+}
+
+void Decorator::DrawCursor(const std::size_t nthChar)
+{
+ std::size_t cursorPosition = GetCurrentCursorPosition();
+
+ // Get height of cursor and set its size
+ Size size( CURSOR_THICKNESS, 0.0f );
+ if ( !mTextViewCharacterPositioning.IsTextEmpty() )
+ {
+ Vector2 min, max; // out parameters for GetRowRectFromCharacterPosition
+ size.height = mTextViewCharacterPositioning.GetRowRectFromCharacterPosition( mTextViewCharacterPositioning.GetVisualPosition( cursorPosition ), min, max ).height;
+ }
+ else
+ {
+ // Measure Font so know how big text will be if no initial text to measure.
+ size.height = mTextViewCharacterPositioning.GetLineHeight( nthChar );
+ }
+
+ mCursor.SetSize(size);
+
+ // If the character is italic then the cursor also tilts.
+ if ( !mTextViewCharacterPositioning.IsStyledTextEmpty() && ( cursorPosition > 0 ) )
+ {
+ DALI_ASSERT_DEBUG( ( 0 <= cursorPosition-1 ) && ( cursorPosition-1 < mTextViewCharacterPositioning.StyledTextSize() ) );
+ const TextStyle styleAtCursor = mTextViewCharacterPositioning.GetStyleAt( cursorPosition-1 );
+ mCursor.SetRotation( styleAtCursor.GetItalics() ? Degree( styleAtCursor.GetItalicsAngle() - CURSOR_ANGLE_OFFSET ) : Degree( 0.f ), Vector3::ZAXIS );
+ }
+
+ DALI_ASSERT_DEBUG( cursorPosition <= mTextViewCharacterPositioning.GetNumberOfCharactersInText() );
+ if ( ( cursorPosition <= mTextViewCharacterPositioning.GetNumberOfCharactersInText() ) )
+ {
+ Vector3 altPosition; // Alternate (i.e. opposite direction) cursor position.
+ bool altPositionValid( false ); // Alternate cursor validity flag.
+ bool directionRTL( false ); // Need to know direction of primary cursor (in case we have 2 cursors and need to show them differently)
+ Vector3 position = mTextViewCharacterPositioning.GetActualPositionFromCharacterPosition( cursorPosition, directionRTL, altPosition, altPositionValid );
+
+ SetAltCursorEnabled( altPositionValid );
+
+ if(!altPositionValid)
+ {
+ mCursor.SetPosition( position + UI_OFFSET );
+ }
+ else
+ {
+ size.height *= 0.5f;
+ mCursor.SetSize(size);
+ mCursor.SetPosition( position + UI_OFFSET - Vector3(0.0f, directionRTL ? 0.0f : size.height, 0.0f) );
+ Vector2 min, max; // out parameters for GetRowRectFromCharacterPosition
+ Size rowSize = mTextViewCharacterPositioning.GetRowRectFromCharacterPosition( mTextViewCharacterPositioning.GetVisualPosition( cursorPosition ), min, max );
+ size.height = rowSize.height * 0.5f;
+ mCursorRTL.SetSize(size);
+ mCursorRTL.SetPosition( altPosition + UI_OFFSET - Vector3(0.0f, directionRTL ? size.height : 0.0f, 0.0f) );
+ }
+
+ if( mTextViewCharacterPositioning.IsScrollEnabled() )
+ {
+ // Whether cursor and grab handle are inside the boundaries of the text-input when text scroll is enabled.
+ const Vector3& controlSize = mTextViewCharacterPositioning.GetTextView().GetCurrentSize();
+ mIsCursorInScrollArea = mIsGrabHandleInScrollArea = IsPositionWithinControl( position, size, controlSize );
+ }
+ }
+}
+
+void Decorator::SetAltCursorEnabled( bool enabled )
+{
+ mCursorRTLEnabled = enabled;
+ mCursorRTL.SetVisible( mCursorVisibility && mCursorRTLEnabled );
+}
+
+void Decorator::SetCursorImage(Dali::Image image, const Vector4& border )
+{
+ DALI_ASSERT_DEBUG ( image && "Create cursor image invalid")
+
+ if ( image )
+ {
+ mCursor.SetImage( image );
+ mCursor.SetNinePatchBorder( border );
+ }
+}
+
+void Decorator::SetRTLCursorImage( Image image, const Vector4& border )
+{
+ DALI_ASSERT_DEBUG ( image && "Create cursor image invalid")
+
+ if ( image )
+ {
+ mCursorRTL.SetImage( image );
+ mCursorRTL.SetNinePatchBorder( border );
+ }
+}
+
+ImageActor Decorator::CreateCursor( Image cursorImage, const Vector4& border, const std::string& cursorName )
+{
+ ImageActor cursor;
+
+ if ( cursorImage )
+ {
+ cursor = ImageActor::New( cursorImage );
+ }
+ else
+ {
+ cursor = ImageActor::New( Image::New( DEFAULT_CURSOR ) );
+ }
+
+ cursor.SetStyle(ImageActor::STYLE_NINE_PATCH);
+ cursor.SetNinePatchBorder( border );
+ cursor.SetAnchorPoint(AnchorPoint::BOTTOM_CENTER);
+ cursor.SetVisible(false);
+ cursor.SetName( cursorName );
+ return cursor;
+}
+
+void Decorator::CreateCursors( Actor targetParent )
+{
+ Image mCursorImage = Image::New( DEFAULT_CURSOR );
+ mCursor = CreateCursor (mCursorImage, DEFAULT_CURSOR_IMAGE_9_BORDER , "mainCursor");
+ mCursorRTL = CreateCursor ( mCursorImage, DEFAULT_CURSOR_IMAGE_9_BORDER, "rtlCursor");
+ targetParent.Add( mCursor );
+ targetParent.Add( mCursorRTL );
+}
+
+Size Decorator::GetCursorSizeAt( std::size_t positionWithinTextToGetCursorSize )
+{
+ std::size_t visualPosition = mTextViewCharacterPositioning.GetVisualPosition( positionWithinTextToGetCursorSize );
+
+ Vector2 min, max;
+
+ const Size cursorSize( CURSOR_THICKNESS,
+ mTextViewCharacterPositioning.GetRowRectFromCharacterPosition( visualPosition, min, max ).height );
+
+ return cursorSize;
+}
+
+void Decorator::StartCursorBlinkTimer()
+{
+ if ( !mCursorBlinkTimer )
+ {
+ mCursorBlinkTimer = Timer::New( CURSOR_BLINK_INTERVAL );
+ mCursorBlinkTimer.TickSignal().Connect( this, &Decorator::OnCursorBlinkTimerTick );
+ }
+
+ if ( !mCursorBlinkTimer.IsRunning() )
+ {
+ mCursorBlinkTimer.Start();
+ }
+}
+
+void Decorator::StopCursorBlinkTimer()
+{
+ if ( mCursorBlinkTimer )
+ {
+ mCursorBlinkTimer.Stop();
+ }
+}
+
+bool Decorator::OnCursorBlinkTimerTick()
+{
+ // Cursor blinking
+ mCursor.SetVisible( mCursorVisibility && mIsCursorInScrollArea && mCursorBlinkStatus );
+ if ( mCursorRTLEnabled )
+ {
+ mCursorRTL.SetVisible( mCursorVisibility && mIsCursorInScrollArea && mCursorBlinkStatus );
+ }
+ mCursorBlinkStatus = !mCursorBlinkStatus;
+
+ return true;
+}
+
+/**
+ * Highlight
+ */
+void Decorator::ShowUpdatedHighlight()
+{
+ Toolkit::TextView::TextLayoutInfo textLayoutInfo = mTextViewCharacterPositioning.GetLayoutInfo();
+ TextHighlight::HighlightInfo highlightInfo = mTextHighlight.CalculateHighlightInfo( mSelectionHandleOnePosition, mSelectionHandleTwoPosition, textLayoutInfo );
+
+ // Clamp highlightInfo so they don't exceed the boundary of the control.
+ const Vector3& controlSize = mTextViewCharacterPositioning.GetTextView().GetCurrentSize();
+ highlightInfo.Clamp2D( Vector2::ZERO, Vector2(controlSize.x, controlSize.y) );
+
+ mTextHighlight.UpdateHighlight( highlightInfo );
+}
+
+void Decorator::CreateHighlight( Actor parent )
+{
+ DALI_ASSERT_DEBUG( parent && "Highlight target parent does not exist" );
+
+ if ( !mHighlightMeshActor )
+ {
+ mHighlightMeshActor = MeshActor::New( mTextHighlight.CreateHighLightMesh() );
+ mHighlightMeshActor.SetName( "HighlightMeshActor" );
+ mHighlightMeshActor.SetInheritShaderEffect( false );
+ mHighlightMeshActor.SetAffectedByLighting(false);
+ parent.Add( mHighlightMeshActor );
+ }
+}
+
+void Decorator::RemoveHighlight()
+{
+ if ( mHighlightMeshActor )
+ {
+ mHighlightMeshActor.Unparent();
+ mHighlightMeshActor.Reset();
+ // NOTE: We cannot dereference mHighlightMesh, due to a how the scene-graph MeshRenderer uses the Mesh data.
+ }
+}
+
+void Decorator::HighlightVisibility( bool visiblility )
+{
+ if ( mHighlightMeshActor )
+ {
+ mHighlightMeshActor.SetVisible( visiblility );
+ }
+}
+
+/**
+ * Callbacks connected to be Property notifications for Boundary checking.
+ */
+// Note If PropertyNotification signal definition included Actor we would not need to duplicate functions.
+void Decorator::OnHandleOneLeavesBoundary( PropertyNotification& source)
+{
+ mTextInputHandles.GetSelectionHandleOne().SetOpacity(0.0f);
+}
+
+void Decorator::OnHandleOneWithinBoundary(PropertyNotification& source)
+{
+ mTextInputHandles.GetSelectionHandleOne().SetOpacity(1.0f);
+}
+
+void Decorator::OnHandleTwoLeavesBoundary( PropertyNotification& source)
+{
+ mTextInputHandles.GetSelectionHandleTwo().SetOpacity(0.0f);
+}
+
+void Decorator::OnHandleTwoWithinBoundary(PropertyNotification& source)
+{
+ mTextInputHandles.GetSelectionHandleTwo().SetOpacity(1.0f);
+}
+
+void Decorator::OnLeftBoundaryExceeded(PropertyNotification& source)
+{
+ DALI_LOG_INFO(gLogFilter, Debug::General, "TextInputDecorationLayouter::OnLeftBoundaryExceeded\n");
+ Actor selectionHandleOne = mTextInputHandles.GetSelectionHandleOne();
+ selectionHandleOne.SetScale( -1.0f, 1.0f, 1.0f );
+ selectionHandleOne.SetAnchorPoint( AnchorPoint::TOP_LEFT);
+}
+
+void Decorator::OnReturnToLeftBoundary(PropertyNotification& source)
+{
+ DALI_LOG_INFO(gLogFilter, Debug::General, "TextInputDecorationLayouter::OnReturnToLeftBoundary\n");
+ Actor selectionHandleOne = mTextInputHandles.GetSelectionHandleOne();
+ selectionHandleOne.SetScale( 1.0f, 1.0f, 1.0f );
+ selectionHandleOne.SetAnchorPoint( AnchorPoint::TOP_RIGHT);
+}
+
+void Decorator::OnRightBoundaryExceeded(PropertyNotification& source)
+{
+ Actor selectionHandleTwo = mTextInputHandles.GetSelectionHandleTwo();
+ selectionHandleTwo.SetScale( -1.0f, 1.0f, 1.0f );
+ selectionHandleTwo.SetAnchorPoint( AnchorPoint::TOP_RIGHT);
+}
+
+void Decorator::OnReturnToRightBoundary(PropertyNotification& source)
+{
+ Actor selectionHandleTwo = mTextInputHandles.GetSelectionHandleTwo();
+ selectionHandleTwo.SetScale( 1.0f, 1.0f, 1.0f );
+ selectionHandleTwo.SetAnchorPoint( AnchorPoint::TOP_LEFT);
+}
+
+void Decorator::SetUpHandlePropertyNotifications()
+{
+ /* Property notifications for handles exceeding the boundary and returning back within boundary */
+
+ Vector3 handlesize = GetSelectionHandleSize();
+
+ Actor selectionHandleOne = mTextInputHandles.GetSelectionHandleOne();
+ Actor selectionHandleTwo = mTextInputHandles.GetSelectionHandleTwo();
+
+ // Exceeding horizontal boundary
+ PropertyNotification leftNotification = selectionHandleOne.AddPropertyNotification( Actor::WORLD_POSITION_X, LessThanCondition( mBoundingRectangleWorldCoordinates.x + handlesize.x) );
+ leftNotification.NotifySignal().Connect( this, &Decorator::OnLeftBoundaryExceeded );
+
+ PropertyNotification rightNotification = selectionHandleTwo.AddPropertyNotification( Actor::WORLD_POSITION_X, GreaterThanCondition( mBoundingRectangleWorldCoordinates.z - handlesize.x ) );
+ rightNotification.NotifySignal().Connect( this, &Decorator::OnRightBoundaryExceeded );
+
+ // Within horizontal boundary
+ PropertyNotification leftLeaveNotification = selectionHandleOne.AddPropertyNotification( Actor::WORLD_POSITION_X, GreaterThanCondition( mBoundingRectangleWorldCoordinates.x + 2*handlesize.x ) );
+ leftLeaveNotification.NotifySignal().Connect( this, &Decorator::OnReturnToLeftBoundary );
+
+ PropertyNotification rightLeaveNotification = selectionHandleTwo.AddPropertyNotification( Actor::WORLD_POSITION_X, LessThanCondition( mBoundingRectangleWorldCoordinates.z - 2*handlesize.x ) );
+ rightLeaveNotification.NotifySignal().Connect( this, &Decorator::OnReturnToRightBoundary );
+
+ // Exceeding vertical boundary
+ PropertyNotification verticalExceedNotificationOne = selectionHandleOne.AddPropertyNotification( Actor::WORLD_POSITION_Y,
+ OutsideCondition( mBoundingRectangleWorldCoordinates.y + handlesize.y,
+ mBoundingRectangleWorldCoordinates.w - handlesize.y ) );
+ verticalExceedNotificationOne.NotifySignal().Connect( this, &Decorator::OnHandleOneLeavesBoundary );
+
+ PropertyNotification verticalExceedNotificationTwo = selectionHandleTwo.AddPropertyNotification( Actor::WORLD_POSITION_Y,
+ OutsideCondition( mBoundingRectangleWorldCoordinates.y + handlesize.y,
+ mBoundingRectangleWorldCoordinates.w - handlesize.y ) );
+ verticalExceedNotificationTwo.NotifySignal().Connect( this, &Decorator::OnHandleTwoLeavesBoundary );
+
+ // Within vertical boundary
+ PropertyNotification verticalWithinNotificationOne = selectionHandleOne.AddPropertyNotification( Actor::WORLD_POSITION_Y,
+ InsideCondition( mBoundingRectangleWorldCoordinates.y + handlesize.y,
+ mBoundingRectangleWorldCoordinates.w - handlesize.y ) );
+ verticalWithinNotificationOne.NotifySignal().Connect( this, &Decorator::OnHandleOneWithinBoundary );
+
+ PropertyNotification verticalWithinNotificationTwo = selectionHandleTwo.AddPropertyNotification( Actor::WORLD_POSITION_Y,
+ InsideCondition( mBoundingRectangleWorldCoordinates.y + handlesize.y,
+ mBoundingRectangleWorldCoordinates.w - handlesize.y ) );
+ verticalWithinNotificationTwo.NotifySignal().Connect( this, &Decorator::OnHandleTwoWithinBoundary );
+}
+
+/**
+ * PopUp
+ */
+Vector3 Decorator::PositionOfPopUpRelativeToSelectionHandles()
+{
+ Vector3 position;
+ Vector2 min, max;
+ Vector3 topHandle;
+ Size rowSize;
+
+ // When text is selected, show popup above top handle (and text), or below bottom handle.
+
+ // topHandle: referring to the top most point of the handle or the top line of selection.
+ if ( mSelectionHandleTwoActualPosition.y > mSelectionHandleOneActualPosition.y )
+ {
+ topHandle = mSelectionHandleOneActualPosition;
+ rowSize= mTextViewCharacterPositioning.GetRowRectFromCharacterPosition( mSelectionHandleOnePosition, min, max );
+ }
+ else
+ {
+ topHandle = mSelectionHandleTwoActualPosition;
+ rowSize = mTextViewCharacterPositioning.GetRowRectFromCharacterPosition( mSelectionHandleTwoPosition, min, max );
+ }
+ topHandle.y += TOP_HANDLE_TOP_OFFSET - rowSize.height;
+ position = Vector3(topHandle.x, topHandle.y, 0.0f);
+
+ return position;
+}
+
+Vector3 Decorator::AlternatePopUpPositionRelativeToSelectionHandles()
+{
+ // alternativePosition: referring to the bottom most point of the handle or the bottom line of selection.
+ Vector3 alternativePosition;
+ alternativePosition.y = std::max ( mSelectionHandleTwoActualPosition.y , mSelectionHandleOneActualPosition.y );
+ alternativePosition.y += GetSelectionHandleSize().y + mPopUpPanel.GetSize().y + BOTTOM_HANDLE_BOTTOM_OFFSET;
+
+ return alternativePosition;
+}
+
+Vector3 Decorator::PositionOfPopUpRelativeToCursor()
+{
+ // When no text is selected, show PopUp at position of cursor
+ Vector3 position;
+ Vector2 min, max;
+ std::size_t cursorPosition = GetCurrentCursorPosition();
+ position = mTextViewCharacterPositioning.GetActualPositionFromCharacterPosition( cursorPosition );
+ const Size rowSize = mTextViewCharacterPositioning.GetRowRectFromCharacterPosition( cursorPosition, min, max );
+ position.y -= rowSize.height;
+
+ return position;
+}
+
+Vector3 Decorator::AlternatePopUpPositionRelativeToCursor()
+{
+ std::size_t cursorPosition = GetCurrentCursorPosition();
+ Vector3 alternativePosition = mTextViewCharacterPositioning.GetActualPositionFromCharacterPosition( cursorPosition );
+
+ if ( mTextInputHandles.GetGrabHandle() )
+ {
+ // If grab handle enabled then position pop-up below the grab handle.
+ alternativePosition.y += mTextInputHandles.GetGrabHandle().GetCurrentSize().height + mPopUpPanel.GetSize().y + BOTTOM_HANDLE_BOTTOM_OFFSET ;
+ }
+ else
+ {
+ alternativePosition.y += mPopUpPanel.GetSize().y;
+ }
+
+ return alternativePosition;
+
+}
+
+Vector3 Decorator::PositionOfPopUpRelativeToGrabHandle()
+{
+ return Vector3::ZERO;
+}
+
+void Decorator::ShowPopUp()
+{
+ Vector3 position;
+ Vector3 alternativePosition;
+ Size rowSize;
+
+ DALI_ASSERT_DEBUG( mPopUpTarget && "PopUp Target Actor does not exist" );
+
+ if( mHighlightMeshActor ) // Text Selection mode
+ {
+ position = PositionOfPopUpRelativeToSelectionHandles();
+ }
+ else // Not in Text Selection mode so position relative to cursor.
+ {
+ position = PositionOfPopUpRelativeToCursor();
+ }
+
+ // reposition popup above the desired cursor position.
+ mPopUpPanel.Show( mPopUpTarget, true );
+ mPopUpPanel.Self().SetPosition( position );
+ mPopUpPanel.PressedSignal().Connect( this, &Decorator::OnPopupButtonPressed );
+
+ SetUpPopUpPositionNotifications();
+ mPopUpPanel.ApplyConfinementConstraint( mBoundingRectangleWorldCoordinates );
+}
+
+void Decorator::ShowPopUp( Actor target )
+{
+ mPopUpTarget = target;
+ ShowPopupCutCopyPaste();
+}
+
+void Decorator::ShowPopupCutCopyPaste()
+{
+ bool isAllTextSelectedAlready = ( mTextViewCharacterPositioning.StyledTextSize() == GetSelectedText().size() );
+ bool isTextEmpty = mTextViewCharacterPositioning.IsStyledTextEmpty() ;
+ bool isSubsetOfTextAlreadySelected = ( !isAllTextSelectedAlready ) && mHighlightMeshActor;
+
+ Clipboard clipboard = Clipboard::Get();
+ bool hasClipboardGotContent = clipboard.NumberOfItems();
+
+ mPopUpPanel.CreateCutCopyPastePopUp( isAllTextSelectedAlready, isTextEmpty, hasClipboardGotContent, isSubsetOfTextAlreadySelected );
+ ShowPopUp();
+}
+
+void Decorator::HidePopUp( bool animate, bool signalFinished )
+{
+ if ( ( mPopUpPanel.GetState() == TextInputPopupNew::StateShowing ) || ( mPopUpPanel.GetState() == TextInputPopupNew::StateShown ) )
+ {
+ mPopUpPanel.Hide( animate );
+ }
+}
+
+void Decorator::AddPopupOption(const std::string& name, const std::string& caption, const Image icon, bool finalOption)
+{
+ mPopUpPanel.AddButton(name, caption, icon, finalOption);
+}
+
+void Decorator::ClearPopup()
+{
+ mPopUpPanel.Clear();
+}
+
+void Decorator::PopUpLeavesVerticalBoundary( PropertyNotification& source)
+{
+ Vector3 position, alternativePosition;
+
+ if( mHighlightMeshActor ) // Text Selection mode
+ {
+ alternativePosition = AlternatePopUpPositionRelativeToSelectionHandles();
+ }
+ else // Not in Text Selection mode
+ {
+ alternativePosition = AlternatePopUpPositionRelativeToCursor();
+ // if can't be positioned above, then position below row.
+ }
+ // reposition popup above the desired cursor position.
+ mPopUpPanel.Self().SetPosition( alternativePosition );
+}
+
+void Decorator::SetUpPopUpPositionNotifications( )
+{
+ // Note Property notifications ignore any set anchor point so conditions must allow for this. Default is Top Left.
+
+ // Exceeding vertical boundary
+ PropertyNotification verticalExceedNotificationOne = mPopUpPanel.Self().AddPropertyNotification( Actor::WORLD_POSITION_Y,
+ OutsideCondition( mBoundingRectangleWorldCoordinates.y + mPopUpPanel.GetSize().y/2,
+ mBoundingRectangleWorldCoordinates.w - mPopUpPanel.GetSize().y/2 ) );
+ verticalExceedNotificationOne.NotifySignal().Connect( this, &Decorator::PopUpLeavesVerticalBoundary );
+}
+
+bool Decorator::OnPopupButtonPressed( Toolkit::Button button )
+{
+ mPopUpButtonPressedSignal.Emit( button );
+ return false;
+}
+
+Decorator::PressedSignal& Decorator::PopUpButtonPressedSignal()
+{
+ return mPopUpButtonPressedSignal;
+}
+
+Decorator::CursorPositionedSignal& Decorator::CursorRePositionedSignal()
+{
+ return mCursorRePositionedSignal;
+}
+
+/**
+ * Decoration Positioning during Scrolling
+ */
+void Decorator::TextViewScrolled( Toolkit::TextView textView, Vector2 scrollPosition )
+{
+ DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextInputDecorationLayouter::TextViewScrolled\n");
+
+ const Vector3& controlSize = mTextViewCharacterPositioning.GetTextView().GetCurrentSize(); // todo Could store size and only update in Control Size change.
+ Size cursorSize( CURSOR_THICKNESS, 0.f );
+
+ // Updates the cursor and grab handle position and visibility.
+ if( mTextInputHandles.GetGrabHandle() || mCursor )
+ {
+ Vector2 min, max;
+ size_t cursorTextPosition = GetCurrentCursorPosition();
+ cursorSize.height = mTextViewCharacterPositioning.GetRowRectFromCharacterPosition( cursorTextPosition, min, max ).height;
+
+ const Vector3 cursorPosition = mTextViewCharacterPositioning.GetActualPositionFromCharacterPosition( cursorTextPosition );
+
+ bool mIsCursorInScrollArea = IsPositionWithinControl( cursorPosition, cursorSize, controlSize );
+ bool mIsGrabHandleInScrollArea = mIsCursorInScrollArea;
+
+ Vector2 actualGrabHandlePosition = cursorPosition.GetVectorXY();
+
+ if( mTextInputHandles.GetGrabHandle() )
+ {
+ ShowGrabHandle( mGrabHandleVisibility && mIsGrabHandleInScrollArea );
+ PositionGrabHandle( cursorTextPosition );
+ }
+
+ if( mCursor )
+ {
+ mCursor.SetVisible( mCursorVisibility && mIsCursorInScrollArea );
+ DrawCursor( cursorTextPosition );
+ mCursor.SetPosition( Vector3(actualGrabHandlePosition) + UI_OFFSET );
+ }
+ }
+
+ Actor selectionHandleOne = mTextInputHandles.GetSelectionHandleOne();
+ Actor selectionHandleTwo = mTextInputHandles.GetSelectionHandleTwo();
+
+ // Updates the selection handles and highlighted text position and visibility.
+ if( mTextInputHandles.GetSelectionHandleOne() && mTextInputHandles.GetSelectionHandleTwo() )
+ {
+ const Vector3 cursorPositionOne = mTextViewCharacterPositioning.GetActualPositionFromCharacterPosition( mSelectionHandleOnePosition );
+ const Vector3 cursorPositionTwo = mTextViewCharacterPositioning.GetActualPositionFromCharacterPosition( mSelectionHandleTwoPosition );
+
+ Size cursorSize( GetCursorSizeAt( mSelectionHandleOnePosition ) );
+ const bool isSelectionHandleOneVisible = IsPositionWithinControl( cursorPositionOne, cursorSize, controlSize );
+
+ cursorSize = GetCursorSizeAt( mSelectionHandleTwoPosition );
+ const bool isSelectionHandleTwoVisible = IsPositionWithinControl( cursorPositionTwo, cursorSize, controlSize );
+
+ mSelectionHandleOneActualPosition = cursorPositionOne.GetVectorXY();
+ mSelectionHandleTwoActualPosition = cursorPositionTwo.GetVectorXY();
+
+ selectionHandleOne.SetVisible( isSelectionHandleOneVisible );
+ selectionHandleTwo.SetVisible( isSelectionHandleTwoVisible );
+
+ PositionSelectionHandle( selectionHandleOne, mSelectionHandleOneActualPosition, mSelectionHandleOnePosition );
+ PositionSelectionHandle( selectionHandleTwo, mSelectionHandleTwoActualPosition, mSelectionHandleTwoPosition );
+
+ if( mHighlightMeshActor )
+ {
+ mHighlightMeshActor.SetVisible( true );
+ ShowUpdatedHighlight();
+ }
+ }
+}
+
+void Decorator::StartScrollTimer()
+{
+ if( !mScrollTimer )
+ {
+ mScrollTimer = Timer::New( SCROLL_TICK_INTERVAL );
+ mScrollTimer.TickSignal().Connect( this, &Decorator::OnScrollTimerTick );
+ }
+
+ if( !mScrollTimer.IsRunning() )
+ {
+ DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextInputDecorationLayouter::StartScrollTimer\n");
+ mScrollTimer.Start();
+ }
+}
+
+void Decorator::StopScrollTimer()
+{
+ if( mScrollTimer )
+ {
+ DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextInputDecorationLayouter::StopScrollTimer\n");
+
+ mScrollTimer.Stop();
+ mScrollTimer.Reset();
+ }
+}
+
+bool Decorator::OnScrollTimerTick()
+{
+ DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextInputDecorationLayouter::OnScrollTimerTick\n");
+
+ if ( mGrabHandleVisibility && mTextInputHandles.GetGrabHandle() )
+ {
+ std::size_t newGrabHandlePosition = mTextViewCharacterPositioning.ReturnClosestIndex( mActualGrabHandlePosition.GetVectorXY() );
+ if ( mGrabHandlePosition != newGrabHandlePosition )
+ {
+ Vector2 scrollPosition = mTextViewCharacterPositioning.GetScrollPosition();
+ Vector2 scrollDelta = ( mActualGrabHandlePosition - mCurrentHandlePosition ).GetVectorXY();
+ DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextInputDecorationLayouter::OnScrollTimerTick scrollPosition(%f) scrollDelta(%f)\n", scrollPosition.x, scrollDelta.x);
+ scrollPosition += scrollDelta;
+ mTextViewCharacterPositioning.SetScrollPosition( scrollPosition );
+
+ // If scroll position goes too far TextView will trim it to fit.
+ if ( mTextViewCharacterPositioning.IsScrollPositionTrimmed() )
+ {
+ StopScrollTimer();
+ }
+
+ mActualGrabHandlePosition = mTextViewCharacterPositioning.GetActualPositionFromCharacterPosition( newGrabHandlePosition ).GetVectorXY();
+ }
+ }
+
+ Actor selectionHandleOne = mTextInputHandles.GetSelectionHandleOne();
+ Actor selectionHandleTwo = mTextInputHandles.GetSelectionHandleTwo();
+
+ if ( selectionHandleOne && selectionHandleTwo )
+ {
+ std::size_t newHandleOnePosition = mTextViewCharacterPositioning.ReturnClosestIndex( mSelectionHandleOneActualPosition.GetVectorXY() );
+
+ // todo duplicated code should be a function
+
+ if ( mSelectionHandleOnePosition != newHandleOnePosition )
+ {
+ const Vector3 actualPosition = mTextViewCharacterPositioning.GetActualPositionFromCharacterPosition( newHandleOnePosition );
+
+ Vector2 scrollDelta = ( actualPosition - mSelectionHandleOneActualPosition ).GetVectorXY();
+
+ Vector2 scrollPosition = mTextViewCharacterPositioning.GetScrollPosition();
+ scrollPosition += scrollDelta;
+ mTextViewCharacterPositioning.SetScrollPosition( scrollPosition );
+
+ if( mTextViewCharacterPositioning.IsScrollPositionTrimmed() )
+ {
+ StopScrollTimer();
+ }
+
+ mSelectionHandleOnePosition = newHandleOnePosition;
+ mSelectionHandleOneActualPosition = mTextViewCharacterPositioning.GetActualPositionFromCharacterPosition( mSelectionHandleOnePosition ).GetVectorXY();
+ }
+ else
+ {
+ mSelectionHandleOneActualPosition.x += mScrollDisplacement.x;
+ mSelectionHandleOneActualPosition.y += mScrollDisplacement.y;
+ }
+
+ std::size_t newHandleTwoPosition = mTextViewCharacterPositioning.ReturnClosestIndex( mSelectionHandleTwoActualPosition.GetVectorXY() );
+
+ if ( mSelectionHandleTwoPosition != newHandleTwoPosition )
+ {
+ const Vector3 actualPosition = mTextViewCharacterPositioning.GetActualPositionFromCharacterPosition( newHandleTwoPosition );
+
+ Vector2 scrollDelta = ( actualPosition - mSelectionHandleTwoActualPosition ).GetVectorXY();
+
+ Vector2 scrollPosition = mTextViewCharacterPositioning.GetScrollPosition();
+ scrollPosition += scrollDelta;
+ mTextViewCharacterPositioning.SetScrollPosition( scrollPosition );
+
+ if( mTextViewCharacterPositioning.IsScrollPositionTrimmed() )
+ {
+ StopScrollTimer();
+ }
+
+ mSelectionHandleTwoPosition = newHandleTwoPosition;
+ mCurrentHandlePosition = mTextViewCharacterPositioning.GetActualPositionFromCharacterPosition( mSelectionHandleTwoPosition ).GetVectorXY();
+
+ }
+ else
+ {
+ mSelectionHandleTwoActualPosition.x += mScrollDisplacement.x;
+ mSelectionHandleTwoActualPosition.y += mScrollDisplacement.y;
+ }
+ }
+
+ return true;
+}
+
+/**
+ * Text Selection
+ */
+MarkupProcessor::StyledTextArray Decorator::GetSelectedText()
+{
+ MarkupProcessor::StyledTextArray currentSelectedText;
+
+ if ( mHighlightMeshActor ) // Text Selected
+ {
+ MarkupProcessor::StyledTextArray::iterator it = mTextViewCharacterPositioning.GetStyledTextArray().begin() + std::min(mSelectionHandleOnePosition, mSelectionHandleTwoPosition);
+ MarkupProcessor::StyledTextArray::iterator end = mTextViewCharacterPositioning.GetStyledTextArray().begin() + std::max(mSelectionHandleOnePosition, mSelectionHandleTwoPosition);
+
+ for(; it != end; ++it)
+ {
+ MarkupProcessor::StyledText& styledText( *it );
+ currentSelectedText.push_back( styledText );
+ }
+ }
+ return currentSelectedText;
+}
+
+} // Internal
+
+} // namespace Toolkit
+
+} // namespace Dali
+
--- /dev/null
+#ifndef __DALI_TOOLKIT_INTERNAL_TEXT_INPUT_DECORATOR_H__
+#define __DALI_TOOLKIT_INTERNAL_TEXT_INPUT_DECORATOR_H__
+
+//
+// Copyright (c) 2014 Samsung Electronics Co., Ltd.
+//
+// Licensed under the Flora License, Version 1.0 (the License);
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://floralicense.org/license/
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an AS IS BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include <dali/dali.h>
+
+// INTERNAL INCLUDES
+
+#include <dali-toolkit/internal/controls/text-input/textview-character-positions-impl.h>
+#include <dali-toolkit/internal/controls/text-input/text-input-handles-impl.h>
+#include <dali-toolkit/internal/controls/text-input/text-input-text-highlight-impl.h>
+#include <dali-toolkit/internal/controls/text-input/text-input-popup-new-impl.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+class Decorator;
+
+typedef IntrusivePtr<Decorator> DecoratorPtr;
+
+/**
+ * @brief Decorator Class
+ *
+ * Decorations are Selection Handles, cursor, grab handle, magnifier the "cut copy paste" PopUp and Selection highlight.
+ * The Decorator triggers creation of these decorations and positions them.
+ * Decoration positions can be dependent on other decorations like the PopUp on the Selection handles.
+ * 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.
+ * Scrolling of Text can effect positioning of decorations, the decorator repositions decorations in this case.
+ */
+
+class Decorator : public ConnectionTracker
+{
+
+public:
+
+ /**
+ * @brief Constructor
+ *
+ * @param[in] textviewManager TextViewManager to be used
+ */
+ Decorator( TextViewCharacterPositioning& textviewManager, TextInputTextStyle& textStyle);
+
+ /**
+ * @brief Default destructor
+ */
+ ~Decorator();
+
+ /**
+ * @brief Set the dimensions of the bounding rectangle for decorations to obey.
+ *
+ * @param[in] boundingRectangle
+ */
+ void SetBoundingBox( const Rect<float>& boundingRectangle );
+
+ /**
+ * @brief Get the bounding dimensions of the bounding box
+ *
+ * @return dimensions of the bounding box from world origin. (x, y, w, z )
+ *
+ * -----------------
+ * | ^ |
+ * | | |
+ * | y |
+ * | | |
+ * | v |
+ * |<--x--> o <--z-->|
+ * | ^ |
+ * | | |
+ * | w |
+ * | | |
+ * | v |
+ * -----------------
+ */
+ Vector4 GetBoundingBox() const;
+
+ /**
+ * @brief Callback when a handle is panned/moved, either selection handles or grab handle
+ *
+ * @param actor Handle of the selection or grab handle.
+ * @param gesture Data structure with the parameters of the gesture.
+ */
+ void OnHandlePan(Actor actor, PanGesture gesture);
+
+ // Selection Handles
+
+ /**
+ * @brief Create a left and right selection handle and parent both to the provided actor
+ * @param[in] parent actor in which the handles should be added to.
+ */
+ void CreateSelectionHandles( Actor parent );
+
+ /**
+ * @brief Remove selection handles from their parent
+ */
+ void RemoveSelectionHandles();
+
+ /**
+ * @brief Get size of Selection handles
+ *
+ * @return size of a selection handle
+ */
+ Vector3 GetSelectionHandleSize();
+
+ /**
+ * @brief Get position of Selection handle within text
+ *
+ * @return character position of a selection handle one
+ */
+ std::size_t GetHandleOnePosition() const;
+
+ /**
+ * @brief Get position of Selection handle within text
+ *
+ * @return character position of a selection handle two
+ */
+ std::size_t GetHandleTwoPosition() const;
+
+ /**
+ * @brief Position Selection a single handle at given positions within the text string.
+ *
+ * @param[in] selectionHandle handle to be positioned
+ * @param[in] position where to place handle
+ * @return Vector3 Position of handle as a coordinate.
+ */
+ Vector3 PositionSelectionHandle( Actor selectionHandle, std::size_t position );
+
+ /**
+ * @brief Position Selection a single handle at given coordinates
+ *
+ * @param[in] selectionHandle handle to be positioned
+ * @param[in] actualPosition coordinates to position handle
+ * @param[in] position where to place handle
+ * @return Vector3 Position of handle as a coordinate.
+ */
+ Vector3 PositionSelectionHandle( Actor selectionHandle, Vector3& actualPosition, std::size_t position );
+
+ /**
+ * @brief Make both selection handle visible or invisible
+ * @param[in] visible true to make visible, false to fine
+ */
+ void SetSelectionHandlesVisibility( bool visible );
+
+ /**
+ * @brief Callback for when a handle is released
+ * @return bool
+ */
+ bool OnHandleReleased();
+
+ /**
+ * @brief Position Selection handles at given positions within the text string.
+ *
+ * @param[in] start where to place first handle
+ * @param[in] end where to place second handle
+ */
+ void PositionSelectionHandles( std::size_t start, std::size_t end );
+
+ /**
+ * @brief Move selection handle by the given displacement.
+ *
+ * @param[in] selectionHandle Actor to move
+ * @param[in] actualSelectionHandlePosition actual current position of the handle in x y z
+ * @param[in] currentSelectionHandlePosition current position along the string
+ * @param[in] displacement the x y displacement
+ */
+ Vector3 MoveSelectionHandle( Actor selectionHandle,
+ Vector3& actualSelectionHandlePosition,
+ std::size_t& currentSelectionHandlePosition,
+ const Vector2& displacement );
+
+ /* Grab Handle */
+
+ /**
+ * @brief Position GrabHandlewith depending on the the character in the text it should be placed at
+ * @param[in] positonInText the character position within the text the handle should be at
+ */
+ void PositionGrabHandle( std::size_t positionInText );
+
+ /**
+ * @brief Move grab handle to the required position within the text
+ *
+ * @param[in] displacement Displacement of the grab handle in actor coordinates.
+ */
+ void MoveGrabHandle( const Vector2& displacement );
+
+ /**
+ * @brief Show or hide the GrabHandle is visibility is true
+ *
+ * @param[in] visible flag to show or not show the grab handle
+ */
+ void ShowGrabHandle( bool visible );
+
+ /**
+ * @brief Create the GrabHandle used to position cursor
+ * @param[in] targetParent the Actor to parent the GrabHandle
+ */
+ void CreateGrabHandle( Actor targetParent );
+
+ /**
+ * @brief Set the image to be used as the cursor grab hander
+ * @pre The text input actor has been initialised.
+ * @param[in] image The image to be used.
+ */
+ void SetGrabHandleImage( Image image );
+
+ /**
+ * @brief Toggle to enable the grab handle, used to position cursor when magnifier not being used.
+ * Default behaviour is to use the magnifier to position the cursor, enabling this prevents the magnifier from being shown.
+ * @param[in] toggle true to enable, false to disable grab handle
+ */
+ void EnableGrabHandle(bool toggle);
+
+ /**
+ * @brief Method to check if grab handle is enabled, if false then the magnifier will be used to position cursor.
+ * @return bool returns true is grab handle enabled.
+ */
+ bool IsGrabHandleEnabled();
+
+ /* Cursor */
+
+ /**
+ * @brief Get the current Cursor position
+ * @return current cursor position
+ */
+ std::size_t GetCurrentCursorPosition() const;
+
+ /**
+ * @brief Set the Cursor position
+ * @param[in] the position the cursor should be set to
+ */
+ void SetCurrentCursorPosition( std::size_t newCursorPosition );
+
+ /**
+ * @brief Set if the cursors are visible or not.
+ * @param[in] visible flag true for visible
+ */
+ void SetCursorVisibility( bool visible );
+
+ /**
+ * @brief Display cursor
+ * @param[in] nthChar position in text string to display cursor
+ */
+ void DrawCursor( const std::size_t nthChar = 0 );
+
+ /**
+ * Sets alternate cursor enable state
+ * @see SetCursorVisibility
+ * alternate cursor will only be visible if both SetCursorVisiblity
+ * and cursor enabled have been set to true.
+ */
+ void SetAltCursorEnabled( bool enabled );
+
+ /**
+ * @brief Set the image to be used for the regular left to right cursor
+ * @pre The text input actor has been initialised.
+ * @param[in] image The image to be used.
+ * @param[in] border The nine patch border for the image.
+ */
+ void SetCursorImage( Image image, const Vector4& border );
+
+ /**
+ * @brief Set the image to be used for the Right to Left cursor
+ * @pre The text input actor has been initialised.
+ * @param[in] image The image to be used.
+ * @param[in] border The nine patch border for the image.
+ */
+ void SetRTLCursorImage( Image image, const Vector4& border );
+
+ /**
+ * @brief Creates a cursor from the supplied image and nine patch border.
+ * @param[in] cursorImage the image to be used for the cursor.
+ * @param[in] border the nine patch border corresponding to the supplied image.
+ * @paran[in] cursorName actor name for cursor
+ * @return the image actor to be used as the cursor.
+ */
+ ImageActor CreateCursor( Image cursorImage, const Vector4& border, const std::string& cursorName );
+
+ /**
+ * @brief Creates a regular and Right-To-Left cursor and parents them to give target Actor
+ * @param[in] targetParent target Actor
+ */
+ void CreateCursors( Actor targetParent );
+
+ /**
+ * @Brief Returns the cursor size at a given position in the text.
+ * @return Size the size of the cursor
+ */
+ Size GetCursorSizeAt( std::size_t positionWithinTextToGetCursorSize );
+
+ /**
+ * @brief Start a timer to signal cursor to blink.
+ */
+ void StartCursorBlinkTimer();
+
+ /**
+ * @brief Stop the timer signalling the cursor to blink.
+ */
+ void StopCursorBlinkTimer();
+
+ /**
+ * @brief Callback when handle timer ticks.
+ *
+ * Cursor should become visible/invisible to simulate blinking.
+ *
+ * @return True if the timer should be keep running.
+ */
+ bool OnCursorBlinkTimerTick();
+
+ /* Selection Highlight */
+
+ /**
+ * @brief Updates mesh data for selection highlight depending on handle positions and displays it.
+ */
+ void ShowUpdatedHighlight();
+
+ /**
+ * @brief Creates the Highlight used for selection
+ *
+ * @param[in] parent target actor in which the handles should be added to.
+ */
+ void CreateHighlight( Actor parent );
+
+ /**
+ * @brief Remove Highlight actor from it's parent
+ */
+ void RemoveHighlight();
+
+ /**
+ * @brief Set the visibility of the Highlight
+ *
+ * @param[in] visibility True to show and False to hide.
+ */
+ void HighlightVisibility( bool visiblility );
+
+ /* Boundary Property Notifications when handle exceed bounding box*/
+
+ /**
+ * @brief PropertyNotification Callback when left boundary exceeded so handle can be flipped.
+ *
+ * @param[in] source PropertyNotification
+ */
+ void OnLeftBoundaryExceeded( PropertyNotification& source );
+ /**
+ * @brief PropertyNotification Callback when within left boundary so handle can be flipped back.
+ *
+ * @param[in] source PropertyNotification
+ */
+ void OnReturnToLeftBoundary( PropertyNotification& source );
+ /**
+ * @brief PropertyNotification Callback when right boundary exceeded so handle can be flipped.
+ *
+ * @param[in] source PropertyNotification
+ */
+ void OnRightBoundaryExceeded( PropertyNotification& source );
+ /**
+ * @brief PropertyNotification Callback when within right boundary so handle can be flipped back.
+ *
+ * @param[in] source PropertyNotification
+ */
+ void OnReturnToRightBoundary( PropertyNotification& source );
+
+ /**
+ * @brief PropertyNotification Callbacks for hiding handle one when it exceeds boundary.
+ *
+ * @param[in] source PropertyNotification
+ */
+ void OnHandleOneLeavesBoundary( PropertyNotification& source );
+ /**
+ * @brief PropertyNotification Callbacks for showing hidden handle one when returns within boundary
+ *
+ * @param[in] source PropertyNotification
+ */
+ void OnHandleOneWithinBoundary( PropertyNotification& source );
+ /**
+ * @brief PropertyNotification Callbacks for hiding handle two it when exceeds boundary.
+ *
+ * @param[in] source PropertyNotification
+ */
+ void OnHandleTwoLeavesBoundary( PropertyNotification& source );
+ /**
+ * @brief PropertyNotification Callbacks for showing hidden handle two when returns within boundary
+ *
+ * @param[in] source PropertyNotification
+ */
+ void OnHandleTwoWithinBoundary( PropertyNotification& source );
+
+ /**
+ * @brief Set up property notifications on the position of the handles to facilitate flipping and hiding when at screen boundary.
+ */
+ void SetUpHandlePropertyNotifications();
+
+ // Cut & Paste Pop-up
+
+ /**
+ * @brief Calculate positioning of PopUp relative to handles
+ * @return Actual position of PopUp
+ */
+ Vector3 PositionOfPopUpRelativeToSelectionHandles( );
+
+ /**
+ * @brief Calculate alternative position of PopUp relative to handles when can it not be displayed in the default upper position.
+ * @return Actual position of PopUp
+ */
+ Vector3 AlternatePopUpPositionRelativeToSelectionHandles();
+
+ /**
+ * @brief Calculate positioning of PopUp relative to cursor
+ * @return Actual position of PopUp
+ */
+ Vector3 PositionOfPopUpRelativeToCursor();
+
+ /**
+ * @brief Calculate alternative position of PopUp relative to cursor when can not be displayed in normal upper position.
+ * @return Actual position of PopUp
+ */
+ Vector3 AlternatePopUpPositionRelativeToCursor();
+
+ /**
+ * @brief Calculate positioning of PopUp relative to GrabHandle
+ * @return Actual position of PopUp
+ */
+ Vector3 PositionOfPopUpRelativeToGrabHandle();
+
+ /**
+ * @brief Show the PopUp in the provided target
+ * @param[in] target target actor in which the PopUp should be added to.
+ */
+ void ShowPopUp( Actor target );
+
+ /**
+ * @brief Show PopUp in previously set Target.
+ * @pre Must have previously called ShopPopUp( Actor target ) otherwise PopUp will not be shown.
+ */
+ void ShowPopUp();
+
+ /**
+ * @brief Create and Show Cut Copy Paste PopUp
+ */
+ void ShowPopupCutCopyPaste();
+
+ /**
+ * @brief Hide PopUp
+ * @param[in] animate Animate or just hide instantly, default is true
+ * @param[in] signalFinished Signal when finished, default is true
+ */
+ void HidePopUp( bool animate=true, bool signalFinished=true );
+
+ /**
+ * @brief Adds a popup option.
+ * @brief Creates popup frame if not already created.
+ * @param[in] name The unique name for this option.
+ * @param[in] caption The caption (label) for this option
+ * @param[in] icon the image icon to be displayed for this option
+ * @param[in] finalOption Flag to indicate that this is the final option.
+ * (set to true on the last option you add)
+ */
+ void AddPopupOption(const std::string& name, const std::string& caption, const Image icon, bool finalOption = false);
+
+ /**
+ * @brief Removes popup, and its options.
+ */
+ void ClearPopup();
+
+ /**
+ * @brief PropertyNotification Callbacks for flipping PopUp when exceeds boundary.
+ * @param[in] source PropertyNotification
+ */
+ void PopUpLeavesVerticalBoundary( PropertyNotification& source );
+
+ /**
+ * @brief Setup position notifications when PopUp exceeds boundary
+ */
+ void SetUpPopUpPositionNotifications( );
+
+ /**
+ * @brief Callback for when a button is pressed in popup panel
+ * @param[in] button handle to the button pressed.
+ * @return bool consummation
+ */
+ bool OnPopupButtonPressed( Toolkit::Button button );
+
+ // Decoration positioning during scrolling
+
+ /**
+ * @brief Updates the position of the decorations when Text is scrolled.
+ *
+ * @param[in] textView Handle of the text-view.
+ * @param[in] scrollPosition The difference with the previous scroll position.
+ */
+ void TextViewScrolled( Toolkit::TextView textView, Vector2 scrollPosition );
+
+ /**
+ * @brief Creates and starts a timer to scroll the text when handles are close to the edges of the text-input.
+ *
+ * It only starts the timer if it's already created.
+ */
+ void StartScrollTimer();
+
+ /**
+ * @brief Stops the timer used to scroll the text.
+ */
+ void StopScrollTimer();
+
+ /**
+ * @brief Scroll Text according to handle position
+ * @param[in out] handlePosition handle position within character string
+ * @param[in] actual vector position of handle
+ * @return updated actual vector position of handle
+ */
+ Vector3 ScrollRelativeToHandle( std::size_t& handlePosition, Vector3& actualHandlePosition );
+
+ /**
+ * @brief Callback called by the timer used to scroll the text.
+ *
+ * It calculates and sets a new scroll position.
+ */
+ bool OnScrollTimerTick();
+
+ // Text Selection
+
+ /**
+ * @brief Function to get Text selected between the 2 selection handles.
+ * @return StyledTextArray an array of
+ */
+ MarkupProcessor::StyledTextArray GetSelectedText();
+
+private:
+
+ /**
+ * @brief Copy Constructor
+ * @param[in] decorator
+ * Undefined/Hidden.
+ */
+ Decorator(const Decorator& decorator);
+
+ /**
+ * @Assignment Constructor
+ * @param[in] rhs
+ * Undefined/Hidden.
+ */
+ Decorator& operator=(const Decorator& rhs);
+
+public:
+
+ typedef SignalV2< bool( Toolkit::Button ) > PressedSignal;
+ typedef SignalV2< void () > CursorPositionedSignal;
+ /**
+ * @brief Signal emitted when the button is touched.
+ * This is relayed from the PopUp class. It enables the owner of the Decorator to act on the PopUp button press.
+ */
+ PressedSignal& PopUpButtonPressedSignal();
+
+ /**
+ * @brief Signal emitted when the cursor is repositioned
+ * @param[in] cursor the new cursor position
+ */
+ CursorPositionedSignal& CursorRePositionedSignal();
+
+private:
+
+ Vector4 mBoundingRectangleWorldCoordinates;
+
+ TextViewCharacterPositioning& mTextViewCharacterPositioning;
+
+ TextInputHandles mTextInputHandles;
+
+ TextInputTextStyle& mTextStyle;
+
+ Vector3 mSelectionHandleOneActualPosition; // Actual x y position of handle
+ Vector3 mSelectionHandleTwoActualPosition; // Actual x y position of handle
+ std::size_t mSelectionHandleOnePosition; // Position of handle along the string of text
+ std::size_t mSelectionHandleTwoPosition; // Position of handle along the string of text
+
+ TextInputPopupNew mPopUpPanel; // PopUp used for Cut Cpoy and Paste
+ Actor mPopUpTarget; // Target Actor to parent PopUp
+
+ Vector3 mActualGrabHandlePosition; // Actual position of grab handle, this might not be snapped to a character
+ std::size_t mGrabHandlePosition; // Position of grab handle along the string of text
+ Vector3 mCurrentHandlePosition;
+
+ std::size_t mCursorPosition; // Current cursor position within the text string
+ ImageActor mCursor; // Cursor overlayed on Text to show where new text will be inserted
+ ImageActor mCursorRTL; // Right To Left Cursor overlayed on Text (where new RTL text would be inserted)
+ Animation mCursorAnimation; // Animation for cursor blinking.
+ Timer mCursorBlinkTimer; // Timer to signal cursor to blink
+
+ Vector2 mScrollDisplacement; // How much to scroll by
+ Timer mScrollTimer; // Timer to scroll text over a period of time not all in one update.
+
+ TextHighlight mTextHighlight; // Holds data required to construct the highlight
+ MeshActor mHighlightMeshActor; // Mesh Actor to display highlight
+
+ PanGestureDetector mPanGestureDetector;
+
+ PressedSignal mPopUpButtonPressedSignal; // Signal emitted when a button within the popup is pressed.
+ CursorPositionedSignal mCursorRePositionedSignal; // Signal emitted when a button when cursor position is changed.
+
+ bool mCursorBlinkStatus:1; // \e true shows the cursor, \e false hides it.
+ bool mCursorVisibility:1; // Should cursor be visible
+ bool mCursorRTLEnabled:1; // Enable state of Alternate RTL Cursor (need to keep track of this as it's not always enabled)
+ bool mIsGrabHandleInScrollArea:1; // Whether the grab handle is inside the boundaries of the text-input.
+ bool mIsCursorInScrollArea:1; // Whether the cursor is inside the boundaries of the text-input.
+ bool mGrabHandleVisibility:1; // Should grab handle be visible
+ bool mGrabHandleEnabled:1; // Flag to enable the grab handle instead of the default magnifier.
+};
+
+} // namespace Internal
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_INTERNAL_TEXT_INPUT_DECORATOR_H__
+
+
--- /dev/null
+#ifndef __DALI_TOOLKIT_INTERNAL_TEXT_INPUT_HANDLES_H__
+#define __DALI_TOOLKIT_INTERNAL_TEXT_INPUT_HANDLES_H__
+
+//
+// Copyright (c) 2014 Samsung Electronics Co., Ltd.
+//
+// Licensed under the Flora License, Version 1.0 (the License);
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://floralicense.org/license/
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an AS IS BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+// INTERNAL INCLUDES
+#include <dali/dali.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+/**
+ * Class to create handles and alter their visualisation.
+ * Not responsible for positioning.
+ */
+
+class TextInputHandles : public ConnectionTracker
+{
+
+public:
+
+ typedef SignalV2< bool () > HandlesReleasedSignal;
+
+ /**
+ * Signal emitted when a handle is released
+ */
+ HandlesReleasedSignal& ReleasedSignal(){ return mReleasedSignal; };
+
+ /**
+ * Default constructor
+ */
+ TextInputHandles() {}
+
+ /**
+ * Destructor
+ */
+ ~TextInputHandles() {};
+
+ /**
+ * Create the selection handles
+ */
+ void CreateSelectionHandles(){};
+
+ /**
+ * Un-parents the Selection Handles and resets their Image Actors
+ */
+ void DestorySelectionHandles(){};
+
+ /**
+ * Set the Actor visibility on Selection Handle One
+ * @param[in] visibility visibility flag
+ */
+ void SetSelectionHandleOneVisibility( bool visibility ){};
+
+ /**
+ * Set the Actor visibility on Selection Handle Two
+ * @param[in] visibility visibility flag
+ */
+ void SetSelectionHandleTwoVisibility( bool visibility ){};
+
+ /**
+ * Attach the two selection handles to the pan gesture detector
+ * @param[in] panGestureDetector the PanGestureDetector to attach to
+ */
+ void AttachSelectionHandlesToGivenPanGesture(PanGestureDetector& panGestureDetector ){};
+
+ /**
+ * Attach the two selection handles to the tap gesture detector
+ * @param[in] tapGestureDetector the TapGestureDetector to attach to
+ */
+ void AttachSelectionHandlesToGivenTapDetector(TapGestureDetector& tapGestureDetector ){};
+
+ /**
+ * Attach the grab handle to the pan gesture detector
+ * @param[in] panGestureDetector the PanGestureDetector to attach to
+ */
+ void AttachGrabHandleToGivenPanGesture( PanGestureDetector& panGestureDetector ){};
+
+ /**
+ * Get Selection handle one
+ * @return selection handle actor
+ */
+ Actor GetSelectionHandleOne() { return Actor(); };
+
+ /**
+ * Get Selection handle two
+ * @return selection handle actor
+ */
+ Actor GetSelectionHandleTwo() { return Actor(); };
+
+ /**
+ * Get the grab handle
+ * @return grab handle Actor
+ */
+ Actor GetGrabHandle() { return Actor(); };
+
+ /**
+ * Create the grab handle that positions the cursor
+ * @param[in] image the image to be used.
+ */
+ void CreateGrabHandle(){};
+
+ /**
+ * Removes and Resets GrabHandle
+ */
+ void DestoryGrabHandle(){};
+
+ /**
+ * Set the image to be used as the cursor grab hander
+ * @pre The text input actor has been initialised.
+ * @param[in] image The image to be used.
+ */
+ void SetGrabHandleImage( Dali::Image image ){};
+
+ /**
+ * Set the Actor visibility on the GrabHandle
+ * @param[in] visibility visibility flag
+ */
+ void SetGrabHandleVisibility( bool visibility ){};
+
+ /* Touch Event Callbacks */
+
+ /**
+ * Callback on selection handle touched.
+ * Sets the image depending if handle in pressed or normal state
+ * @param[in] actor touched
+ * @param[in] touch touch event, used to determine if down or up event
+ */
+ bool OnSelectionHandleTouched(Dali::Actor actor, const TouchEvent& touch){ return true; };
+
+private:
+
+ /**
+ * @brief Copy Constructor
+ * @param[in] handles
+ * Undefined/Hidden.
+ */
+ TextInputHandles(const TextInputHandles& handles);
+
+ /**
+ * @Assignment Constructor
+ * @param[in] rhs
+ * Undefined/Hidden.
+ */
+ TextInputHandles& operator=(const TextInputHandles& rhs);
+
+private:
+
+ ImageActor mSelectionHandleOne; // First selection handle used for selecting text to cut&paste
+ ImageActor mSelectionHandleTwo; // Second selection handle used for selecting text to cut&paste
+ Actor mHandleOneGrabArea; // Invisible actor that receives pans events for the selection handle.
+ Actor mHandleTwoGrabArea; // Invisible actor that receives pans events for the selection handle.
+
+ Image mSelectionHandleOneImage; // image used for selection handle one
+ Image mSelectionHandleOneImagePressed; // image used for selection handle one pressed state
+ Image mSelectionHandleTwoImage; // image used for selection handle two
+ Image mSelectionHandleTwoImagePressed; // image used for selection handle two pressed state
+
+ Vector3 mSelectionHandleOneOffset; // Handle One's Offset
+ Vector3 mSelectionHandleTwoOffset; // Handle Two's Offset
+ Vector3 mSelectionHandleOneCoordinatePosition; // Actual x y z position of handle
+ Vector3 mSelectionHandleTwoCoordinatePosition; // Actual x y z position of handle
+ std::size_t mSelectionHandleOneStringPosition; // Position of handle along the string of text
+ std::size_t mSelectionHandleTwoStringPosition; // Position of handle along the string of text
+
+ Image mGrabHandleImage; // Image to be used for grab handle
+ ImageActor mGrabHandle; // Handle used to move cursor for editing
+ Actor mGrabHandleGrabArea; // invisible actor that receives pans events for the grab handle.
+
+ HandlesReleasedSignal mReleasedSignal; // Signal emitted when a handle is released
+
+ bool mIsSelectionHandleOneFlipped:1; // Flag to know whether the handle one is flipped or not.
+ bool mIsSelectionHandleTwoFlipped:1; // Flag to know whether the handle two is flipped or not.
+};
+
+
+} // namespace Internal
+
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_INTERNAL_TEXT_INPUT_HANDLES_H__
--- /dev/null
+#ifndef __DALI_TOOLKIT_INTERNAL_TEXT_INPUT_POPUP_NEW_H__
+#define __DALI_TOOLKIT_INTERNAL_TEXT_INPUT_POPUP_NEW_H__
+
+//
+// Copyright (c) 2014 Samsung Electronics Co., Ltd.
+//
+// Licensed under the Flora License, Version 1.0 (the License);
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://floralicense.org/license/
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an AS IS BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+// INTERNAL INCLUDES
+#include <dali/dali.h>
+
+#include <dali-toolkit/public-api/controls/text-view/text-view.h>
+#include <dali-toolkit/public-api/controls/buttons/button.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+/**
+ * @brief Class to create and Popup bar made up of buttons.
+ * It provides signals when a button is pressed.
+ * The Popup must be positioned by it's owner.
+ * The future plan is to reuse the Toolkit Popup control to house the buttons.
+ */
+
+class TextInputPopupNew : public ConnectionTracker
+{
+
+public:
+
+ enum State
+ {
+ StateHidden,
+ StateHiding,
+ StateShowing,
+ StateShown
+ };
+
+ // Signal names
+ static const char* const SIGNAL_PRESSED;
+ static const char* const SIGNAL_HIDE_FINISHED;
+ static const char* const SIGNAL_SHOW_FINISHED;
+
+ // Popup Button Pressed
+ typedef SignalV2< bool( Toolkit::Button ) > PopUpPressedSignal;
+
+ // Popup Hide Finished
+ typedef SignalV2< void( TextInputPopupNew& ) > PopUpHideFinishedSignal;
+
+ // Popup Show Finished
+ typedef SignalV2< void( TextInputPopupNew& ) > PopUpShowFinishedSignal;
+
+ /**
+ * Signal emitted when the button is touched.
+ */
+ PopUpPressedSignal& PressedSignal() { return mPressedSignal; }
+
+ /**
+ * Signal emitted when popup is completely hidden
+ * @note Only occurs after a Show() call with animation enabled.
+ */
+ PopUpHideFinishedSignal& HideFinishedSignal() {return mHideFinishedSignal;}
+
+ /**
+ * Signal emitted when popup is completely shown
+ * @note Only occurs after a Hide() call with animation enabled.
+ */
+ PopUpShowFinishedSignal& ShowFinishedSignal() {return mShowFinishedSignal;}
+
+public:
+
+ /**
+ * Default constructor
+ * Creates an empty popup base actor (no content i.e. invisible)
+ */
+ TextInputPopupNew(){};
+
+ /**
+ * Destructor
+ */
+ ~TextInputPopupNew(){};
+
+ /**
+ * @return The root actor of for this popup is returned.
+ */
+ Actor Self() { return mRootActor; };
+
+ /**
+ * Clears popup options (popup no longer exists)
+ */
+ void Clear(){};
+
+ /**
+ * Create the label
+ * @param[in] styledCaption The text to be displayed
+ * @return the newly created label
+ */
+ Toolkit::TextView CreateLabel( const MarkupProcessor::StyledTextArray& styledCaption ){return Toolkit::TextView();};
+
+ /**
+ * Create the label
+ * @param[in] iconImage the image to be used
+ * @return the newly created Image actor to be used as the icon
+ */
+ ImageActor CreateIcon( Image iconImage ) {return ImageActor();};
+
+ /**
+ * Creates and sets up the popup background
+ */
+ void CreatePopUpBackground(){};
+
+ /**
+ * Create divider if multiple options
+ */
+ void CreateDivider(){};
+
+ /**
+ * Create a background to be used when button pressed
+ * @param[in] requiredSize size Image actor should be
+ * @param[in] finalFlag flag to be set if option is the final one.
+ * @return Returns an Image Actor to be used a pressed background
+ */
+ ImageActor CreatePressedBackground( const Vector3 requiredSize, const bool finalFlag ){ return ImageActor(); };
+
+ /**
+ * Adds a popup option button.
+ * @note Creates popup frame if not already created.
+ * @param[in] name The unique name for this option.
+ * @param[in] caption The caption (label) for this option
+ * @param[in] iconImage Image to displayed with text.
+ * @param[in] finalOption Flag to indicate that this is the final option.
+ * (set to true on the last option you add)
+ */
+ void AddButton(const std::string& name, const std::string& caption, const Image iconImage, bool finalOption ){};
+
+ /**
+ * Hides the popup
+ * @param[in] animate (optional) whether to animate popup to hide state over time (i.e. tween).
+ */
+ void Hide(bool animate = true){};
+
+ /**
+ * Shows the popup
+ * @param[in] animate (optional) whether to animate popup to show state over time (i.e. tween).
+ * @param[in] target Actor to parent popup.
+ */
+ void Show( Actor target, bool animate = true ){};
+
+ /**
+ * @brief Get the calculated size of the PopUp
+ * This can not be set directly as is calculated depending on the content added.
+ *
+ * @return Vector3 size of PopUp.
+ */
+ Vector3 GetSize() const { return Vector3::ZERO;};
+
+ /**
+ * Returns the current state of the popup.
+ * @return The state of the popup see enum State
+ */
+ State GetState(void) const{ return StateHidden;};
+
+ /**
+ * Get the root actor which the buttons are added to.
+ * @return the root actor
+ */
+ Actor GetRootActor() const { return Actor(); };
+
+ /**
+ * @brief Creates the PopUp with the required buttons for the provided states.
+ * @param[in] isAllTextSelectedAlready Is all the text already selected
+ * @param[in] isTextEmpty Contains some text
+ * @param[in] hasClipboardGotContent Something to paste from clipboard
+ * @param[in] isSubsetOfTextAlreadySelected Some but not all text is selected
+ */
+ void CreateCutCopyPastePopUp( bool isAllTextSelectedAlready, bool isTextEmpty, bool hasClipboardGotContent, bool isSubsetOfTextAlreadySelected ){};
+
+ /**
+ * @brief Applies constraint to keep Popup in view within the desired area.
+ * @param[in] bounding box in which the PopUp must remain.
+ *
+ */
+ void ApplyConfinementConstraint( Vector4 boundingBox ){};
+
+private:
+
+ /**
+ * @brief Adds popup to the given parent
+ * @paran[in] parent target to add Popup to
+ */
+ void AddToParent( Actor parent ){};
+
+ /**
+ * Removes popup from Parent.
+ */
+ void RemoveFromStage(){};
+
+ /**
+ * Called when a button is pressed in the popup
+ * @param[in] button The button pressed.
+ */
+ bool OnButtonPressed( Toolkit::Button button ){return false;};
+
+ /**
+ * Invoked upon popup Hide animation completing.
+ * @note Only called for animating hide, not called for instantaneous (animate = false)
+ * @param[in] source The animation which completed.
+ */
+ void OnHideFinished(Animation& source){};
+
+ /**
+ * Invoked upon popup Show animation completing.
+ * @note Only called for animating show, not called for instantaneous (animate = false)
+ * @param[in] source The animation which completed.
+ */
+ void OnShowFinished(Animation& source);
+
+private:
+
+ /**
+ * @brief Copy Constructor
+ * @param[in] popup
+ * Undefined/Hidden.
+ */
+ TextInputPopupNew(const TextInputPopupNew& popup );
+
+ /**
+ * @Assignment Constructor
+ * @param[in] rhs
+ * Undefined/Hidden.
+ */
+ TextInputPopupNew& operator=(const TextInputPopupNew& rhs);
+
+private:
+
+ State mState; // Popup State.
+ Actor mRootActor; // The actor which all popup content is added to (i.e. panel and buttons)
+ Vector3 mPopupSize; // Size of the PopUp determined by it's content and max/min size constraints.
+ ImageActor mBackground; // The background popup panel
+ ImageActor mTail; // The tail for the popup
+ Vector3 mContentSize; // Size of Content (i.e. Buttons)
+ ActorContainer mButtonContainer; // List of buttons added to popup.
+ ActorContainer mDividerContainer; // List of dividers added to popup.
+ Animation mAnimation; // Popup Hide/Show animation.
+
+ PopUpPressedSignal mPressedSignal; // Signal emitted when a button within the popup is pressed.
+ PopUpHideFinishedSignal mHideFinishedSignal; // Signal emitted when popup is completely hidden
+ PopUpShowFinishedSignal mShowFinishedSignal; // Signal emitted when popup is completely shown
+
+};
+
+} // namespace Internal
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_INTERNAL_TEXT_INPUT_POPUP_NEW_H__
--- /dev/null
+#ifndef __DALI_TOOLKIT_INTERNAL_TEXT_HIGHLIGHT_H__
+#define __DALI_TOOLKIT_INTERNAL_TEXT_HIGHLIGHT_H__
+
+//
+// Copyright (c) 2014 Samsung Electronics Co., Ltd.
+//
+// Licensed under the Flora License, Version 1.0 (the License);
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://floralicense.org/license/
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an AS IS BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+// INTERNAL INCLUDES
+#include <dali/dali.h>
+#include <dali-toolkit/internal/controls/text-input/textview-character-positions-impl.h>
+
+#include <dali-toolkit/public-api/controls/text-view/text-view.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+/**
+ * @brief TextHighlight is a decoration which highlights selected text.
+ *
+ * The class creates a highlight mesh used to show selected text between handles.
+ * Not responsible for positioning.
+ */
+class TextHighlight
+{
+ /**
+ * structure to hold coordinates of each quad, which will make up the mesh.
+ */
+ struct QuadCoordinates
+ {
+ /**
+ * Default constructor
+ */
+ QuadCoordinates()
+ {
+ }
+
+ /**
+ * Constructor
+ * @param[in] x1 left co-ordinate
+ * @param[in] y1 top co-ordinate
+ * @param[in] x2 right co-ordinate
+ * @param[in] y2 bottom co-ordinate
+ */
+ QuadCoordinates(float x1, float y1, float x2, float y2)
+ : min(x1, y1),
+ max(x2, y2)
+ {
+ }
+
+ Vector2 min; ///< top-left (minimum) position of quad
+ Vector2 max; ///< bottom-right (maximum) position of quad
+ };
+
+ typedef std::vector<QuadCoordinates> QuadContainer;
+
+public:
+
+ /**
+ * structure for information required to build the highlight mesh
+ */
+ struct HighlightInfo
+ {
+ /**
+ * Adds a Quad (2D rectangular sub-selection)
+ * @param[in] x1 left co-ordinate
+ * @param[in] y1 top co-ordinate
+ * @param[in] x2 right co-ordinate
+ * @param[in] y2 bottom co-ordinate
+ */
+ void AddQuad( float x1, float y1, float x2, float y2 ){};
+
+ /**
+ * Clamps all quads to fit within a min -> max 2D boundary.
+ */
+ void Clamp2D(const Vector2& min, const Vector2& max){};
+
+ QuadContainer mQuadList; ///< List of quads (sub-selections that form to create complete selection)
+ };
+
+ /**
+ * Constructor
+ * @param[in] textViewCharacterPositioning TextViewCharacterPositioning to be used for positioning information.
+ */
+ TextHighlight( TextViewCharacterPositioning& textViewCharacterPositioning ):mTextViewCharacterPositioning( textViewCharacterPositioning ){};
+
+ /**
+ * Destructor
+ */
+ ~TextHighlight(){};
+
+ /**
+ * Gets the table of the visual text positions which has a flag
+ * for each Character. The flag is either true (character selected)
+ * or false (character de-selected)
+ * @note startSelection can be greater or less than endSelection
+ *
+ * @param[in,out] selectedVisualText The vector to be resized and populated with the selected flags
+ * @param[in] startSelection The start selection point for the text
+ * @param[in] endSelection The end selection point for the text
+ * @param[in] endSelection The end selection point for the text
+ * @param[in] textLayoutInfo TextView character layout information
+ */
+ void GetVisualTextSelection(std::vector<bool>& selectedVisualText, std::size_t startSelection, std::size_t endSelection,
+ Toolkit::TextView::TextLayoutInfo& textLayoutInfo){};
+
+ /**
+ * Iterates between selection handles and computes the info required to build the highlight mesh
+ * @param[in] handlePositionStart starting handle position
+ * @param[in] handlePositionEnd ending handle position
+ * @return textHighlight target TextHighlight
+ */
+ TextHighlight::HighlightInfo CalculateHighlightInfo( std::size_t handlePositionStart, std::size_t handlePositionEnd, Toolkit::TextView::TextLayoutInfo& textLayoutInfo )
+ { return HighlightInfo();};
+
+ /**
+ * Calculates new Mesh data so highlight moves with selection handles.
+ * @param[in] newHighlightInfo HighlightInfo calculated by CalculateHighlightInfo
+ */
+ void UpdateHighlight( TextHighlight::HighlightInfo& newHighlightInfo ){};
+
+ /**
+ * Creates the Mesh data needed by the Mesh Actor
+ */
+ Mesh CreateHighLightMesh(){return Mesh();};
+
+private:
+
+ /**
+ * @brief Copy Constructor
+ * @param[in] textHight
+ * Undefined/Hidden.
+ */
+ TextHighlight(const TextHighlight& textHight );
+
+ /**
+ * @Assignment Constructor
+ * @param[in] rhs
+ * Undefined/Hidden.
+ */
+ TextHighlight& operator=(const TextHighlight& rhs);
+
+private:
+
+ TextViewCharacterPositioning& mTextViewCharacterPositioning;
+
+ Mesh mHighlightMesh; ///< Mesh Data for highlight
+ MeshData mMeshData; ///< Container to hold meshData for highlight
+ Material mCustomMaterial; ///< Custom material used for highlight
+ HighlightInfo mNewHighlightInfo; ///< Geometry info to create highlight.
+
+};
+
+
+} // namespace Internal
+
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_INTERNAL_TEXT_HIGHLIGHT_H__
--- /dev/null
+#ifndef __DALI_TOOLKIT_INTERNAL_TEXT_INPUT_TEXT_STYLE_H__
+#define __DALI_TOOLKIT_INTERNAL_TEXT_INPUT_TEXT_STYLE_H__
+
+//
+// Copyright (c) 2014 Samsung Electronics Co., Ltd.
+//
+// Licensed under the Flora License, Version 1.0 (the License);
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://floralicense.org/license/
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an AS IS BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include <dali/dali.h>
+
+// INTERNAL INCLUDES
+
+#include <dali-toolkit/internal/controls/text-input/textview-character-positions-impl.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+class TextInputTextStyle;
+
+typedef IntrusivePtr<TextInputTextStyle> TextInputTextStylePtr;
+
+/**
+ * Stores the Input Text Style and provides functions to retrieve and manipulate it.
+ */
+
+class TextInputTextStyle : ConnectionTracker
+{
+
+public:
+
+ /**
+ * @brief Constructor
+ */
+ TextInputTextStyle(){};
+
+ /**
+ * @brief Destructor
+ */
+ ~TextInputTextStyle(){};
+
+ /**
+ * @brief Returns the current Input Style, this is the style that newly inputed text will inherit.
+ * @return TextStyle object representing new style.
+ */
+ TextStyle GetInputStyle() const{return mInputStyle;};
+
+ /**
+ * @brief Sets the Input style so newly inputed text will inherit this.
+ * @param[in] newStyle the style to now use for Input
+ * @return returns true if style changed. False if new style is the same as current setting.
+ */
+ bool SetInputStyle( const TextStyle newStyle, const TextStyle::Mask mask = TextStyle::ALL ){return false;};
+
+ /**
+ * @brief Gets the Current Font used for newly inputed text
+ * @return the Font currently set for new text
+ */
+ Dali::Font GetInputFont() const{return Dali::Font();};
+
+ /**
+ * Signals
+ */
+
+ /* Input style changed signal.*/
+ typedef SignalV2< void( const TextStyle& style ) > StyleChangedSignalType;
+
+ /**
+ * @brief Signal emitted when style changes.
+ * @return The signal to connect to
+ */
+ StyleChangedSignalType& StyleChangedSignal();
+
+private:
+
+ /**
+ * @brief Copy Constructor
+ * @param[in] textStyle
+ * Undefined/Hidden.
+ */
+ TextInputTextStyle(const TextInputTextStyle& textStyle );
+
+ /**
+ * @Assignment Constructor
+ * @param[in] rhs
+ * Undefined/Hidden.
+ */
+ TextInputTextStyle& operator=(const TextInputTextStyle& rhs);
+
+private:
+
+ TextStyle mInputStyle; // Stores the current input style.
+ StyleChangedSignalType mStyleChangedSignal; // Signal emitted when style changes.
+};
+
+} // namespace Internal
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_INTERNAL_TEXT_INPUT_TEXT_STYLE_H__
+
+
--- /dev/null
+#ifndef __DALI_TOOLKIT_INTERNAL_TEXT_INPUT_TEXTVIEW_CHARACTER_POSITIONS_H__
+#define __DALI_TOOLKIT_INTERNAL_TEXT_INPUT_TEXTVIEW_CHARACTER_POSITIONS_H__
+
+//
+// Copyright (c) 2014 Samsung Electronics Co., Ltd.
+//
+// Licensed under the Flora License, Version 1.0 (the License);
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://floralicense.org/license/
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an AS IS BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+///
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/controls/text-input/text-input-text-style-impl.h>
+
+// EXTERNAL INCLUDES
+#include <dali/dali.h>
+#include <dali-toolkit/public-api/controls/text-view/text-view.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+class TextInputTextStyle;
+
+/**
+ * Class which contains functions related to the TextView.
+ * Functions which are needed by various parts of the TextInput to determine the position of characters.
+ * Functions to Set the TextView so text justification, alignment and wrapping behaviour in the desired manner for text input.
+ * The functionality of this class may be divided in future.
+ */
+class TextViewCharacterPositioning
+{
+
+public:
+
+ /**
+ * @brief Constructor
+ *
+ * @param[in] displayedTextView TextView to be used with this class.
+ * @param[in] textStyle TextInputTextStyle to be used
+ */
+ TextViewCharacterPositioning( Toolkit::TextView displayedTextView, TextInputTextStyle& textStyle ):mTextStyle( textStyle ){};
+
+ /**
+ * Destructor
+ */
+ ~TextViewCharacterPositioning(){};
+
+ /**
+ * @brief Creates the TextView to be used within this class.
+ */
+ void CreateTextView(){};
+
+ /*
+ * @brief Get a handle to the current text view object
+ * If one does not exist then it's create.
+ * @return TextView
+ */
+ Toolkit::TextView GetTextView() const{return Toolkit::TextView();};
+
+ /**
+ * @brief Get the TextLayoutInfo from the TextView so know the updated positions of characters.
+ */
+ void UpdateTextLayoutInfo(){};
+
+
+ /**
+ * @brief Get the TextLayoutInfo structure for the TextView
+ * @return the TextLayoutInfo structure
+ */
+ const Toolkit::TextView::TextLayoutInfo& GetLayoutInfo() const{return mTextLayoutInfo;};
+
+
+ /**
+ * @brief Get the number of characters visually represented in the text
+ * @return the number of characters
+ */
+ std::size_t GetNumberOfCharactersInText() const{return 0;};
+
+ /**
+ * @brief Check if any text exists in TextView's character layout table
+ * @return bool true if empty
+ */
+ bool IsTextEmpty() const{return false;};
+
+ /**
+ * @brief Get the height of the line at the given cursor position
+ * @param[in] position
+ * @return float the height of the line
+ */
+ float GetLineHeight( std::size_t position ) const{return 0.0f;};
+
+ /**
+ * @brief Sets if the inputed text can exceed the text-input boundary.
+ * By default is enabled.
+ * @param[in] enable Whether the inputed text can exceed its boundary.
+ */
+ void SetTextExceedEnabled( bool enable ) {};
+
+ /**
+ * @brief Retrieves whether inputed text can exceed the text-input boundary.
+ * @return \e true if text inputed can exceed the boundary, otherwise \e false.
+ */
+ bool IsTextExceedEnabled() const{ return false;};
+
+ /**
+ * @brief From the given x and y vector the closest character position is returned
+ * @param[in] source the x and y position
+ * @return the position in the string of the character closest to the source.
+ */
+ std::size_t ReturnClosestIndex( const Vector2& source ){return 0;};
+
+ /**
+ * @brief If no text exists then this function uses the text alignment to position cursor.
+ * @param[in] cursorPosition
+ */
+ void GetActualPositionFromCharacterPositionWhenNoText( Vector3& cursorPosition ) const{};
+
+ /**
+ * @brief Function to position cursor when a word is wrapped to another line
+ * @param[in] characterPosition that actual position is required for
+ * @return the actual position of the cursor.
+ */
+ Vector3 PositionCursorAfterWordWrap( std::size_t characterPosition ) const{return Vector3::ZERO;};
+
+ /**
+ * @brief Returns the x-position of the current line justification
+ * (relative to left of text-view container)
+ * @return x position for line justification
+ */
+ float GetLineJustificationPosition() const{return 0.0f;};
+
+ /**
+ * @brief Retrieve the dimensions (and min-max) of this row of text that the character resides on.
+ * @param[in] characterPosition the position in the 'string' of characters.
+ * @param[out] min the top-left position of the rectangle representing this row
+ * @param[out] max the bottom-right position of the rectangle representing this row
+ * @return The size of the rectangle representing this row (max - min)
+ */
+ Size GetRowRectFromCharacterPosition(std::size_t characterPosition, Vector2& min, Vector2& max) const{return Vector2::ZERO;};
+
+ /**
+ * @brief Retrieve the character position of the first character on the row of text
+ * that this character resides on.
+ * @param[in] logicalPosition the position in the 'string' of characters.
+ * @return logical character position of start of row.
+ */
+ std::size_t GetRowStartFromCharacterPosition(std::size_t logicalPosition) const{return 0;};
+
+ /**
+ * @brief Gets the visual position of a logical position.
+ * @note This is preferred over directly accessing the Map, as it resolves visual
+ * positions outside of the character map range.
+ * @param[in] logicalPosition The logical position
+ * @return Visual position is returned.
+ */
+ std::size_t GetVisualPosition(std::size_t logicalPosition) const{return 0;};
+
+ /**
+ * @brief Return a vector which is the actual position for the given character position
+ * The character position is where a cursor would be position for that character.
+ * @param[in] characterPosition the logical (input) position in the 'string' of characters.
+ *
+ * @return Vector3 the actual x,y,z position
+ */
+ Vector3 GetActualPositionFromCharacterPosition(std::size_t characterPosition ) const{return Vector3::ZERO;};
+
+ /**
+ * @brief Return a vector which is the actual position for the given character position
+ * The character position is where a cursor would be positioned for that character to be inserted.
+ * An additional alternatePosition is also set in circumstances where the possible writing
+ * of characters would be in the opposite direction.
+ * e.g. "HelloشقشلاهؤEnglish"
+ * | |
+ * * +
+ * [*] - Primary actual position for cursor i.e. continuing writing LTR (English)
+ * [+] - Alternate actual position for cursor i.e. writing RTL (Arabic)
+ *
+ * @param[in] characterPosition the logical (input) position in the 'string' of characters.
+ * @param[out] directionRTL Whether the actual x,y,z position is after LTR (false) or RTL (true) text.
+ * @param[out] alternatePosition the actual x,y,z position of the cursor if user types
+ * in alternate direction to current flow of text.
+ * @param[out] alternatePositionValid whether this alternate position is valid.
+ * @return Vector3 the actual x,y,z position
+ */
+ Vector3 GetActualPositionFromCharacterPosition(std::size_t characterPosition, bool& directionRTL, Vector3& alternatePosition, bool& alternatePositionValid ) const{return Vector3::ZERO;};
+
+ /**
+ * @brief Get the currently displayed text.
+ * @return The currently displayed text.
+ */
+ std::string GetText() const{return std::string();};
+
+ /**
+ * @brief Get the text currently being displayed together with mark-up tags.
+ * @return string, the currently displayed string with mark-up.
+ */
+ std::string GetMarkupText() const{return std::string();};
+
+ /**
+ * @brief Sets whether markup processing should be carried out.
+ *
+ * @param[in] enable whether markup processing is carried out or not.
+ */
+ void SetMarkupProcessingEnabled( bool enable ){};
+
+ /**
+ * @brief Returns whether markup processing is enabled or not
+ *
+ * @return true is markup processing is enabled
+ */
+ bool IsMarkupProcessingEnabled() const{ return false;};
+
+ // Styled Text
+
+ /**
+ * @brief Check if styled text is empty
+ * @return bool returns true if styled text is empty
+ */
+ bool IsStyledTextEmpty() const{ return false;};
+
+ /**
+ * @brief The size of the style text
+ * @return std::size_t returns number of characters in styled text
+ */
+ std::size_t StyledTextSize() const{return 0;};
+
+ /**
+ * @brief Get the styled text array
+ * @return reference to MarkupProcessor::StyledTextArray
+ */
+ MarkupProcessor::StyledTextArray& GetStyledTextArray(){return mStyledText;};
+
+ /**
+ * @brief Get the style for the character at the given position
+ * @param[in] position of character style is required for
+ * @return a copy of the style structure for the character at the given position
+ */
+ TextStyle GetStyleAt( std::size_t position ) const{return TextStyle();};
+
+/**
+ * @briefApplies the given style to all text, selected or not selected.
+ * By default all style settings are applied but a bit mask could be used to modify only certain style settings.
+ * @param[in] style style to apply
+ * @param[in] mask mask style should be applied to
+ * @param[in] begin start position of range to apply style
+ * @param[in] end end position of range to apply style
+ */
+ void ApplyStyleToRange( const TextStyle& style, const TextStyle::Mask mask, const std::size_t begin, const std::size_t end ){};
+
+ // Snapshot
+ /**
+ * @copydoc TextView::SetSnapshotModeEnabled()
+ */
+ void SetSnapshotModeEnabled( bool enable ){};
+
+ /**
+ * @copydoc TextView::IsSnapshotModeEnabled()
+ */
+ bool IsSnapshotModeEnabled() const{ return false;};
+
+ // Scrolling
+ /**
+ * @copydoc TextView::SetScrollEnabled()
+ */
+ void SetScrollEnabled( bool enable ){};
+
+ /**
+ * @copydoc TextView::SetScrollPosition()
+ */
+ void SetScrollPosition( const Vector2& position ){};
+
+ /**
+ * @copydoc TextView::IsScrollEnabled()
+ */
+ bool IsScrollEnabled() const{ return false;};
+
+ /**
+ * @copydoc TextView::GetScrollPosition()
+ */
+ Vector2 GetScrollPosition() const{return Vector2::ZERO;};
+
+ /**
+ * @copydoc TextView::GetScrollPosition()
+ */
+ bool IsScrollPositionTrimmed() const{ return false;};
+
+private:
+
+ /**
+ * @brief Copy Constructor
+ * @param[in] characterPositioning
+ * Undefined.
+ */
+ TextViewCharacterPositioning(const TextViewCharacterPositioning& characterPositioning );
+
+ /**
+ * @Assignment Constructor
+ * @param[in] rhs
+ * Undefined.
+ */
+ TextViewCharacterPositioning& operator=(const TextViewCharacterPositioning& rhs);
+
+private:
+
+ Toolkit::TextView mDisplayedTextView; // A text view object used to display the text.
+ TextInputTextStyle& mTextStyle; // Holds the style object related to input style
+
+ MarkupProcessor::StyledTextArray mStyledText; // String currently displayed by TextView with style info.
+
+ Toolkit::TextView::TextLayoutInfo mTextLayoutInfo; // It contains a table layout info per character sorted by the character's visual index (retrieved from TextView),
+ // a reorder map that stores each character's visual (output) index according to its logical (input) index,
+ // a reorder map that stores each character's logical (input) index according to its visual (output) index
+
+ bool mExceedEnabled:1; // flag set by user to determine if text can exceed the control's size
+ bool mMarkUpEnabled:1; // If Markup is being passed with the text
+};
+
+
+} // namespace Internal
+
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_INTERNAL_TEXT_INPUT_TEXTVIEW_CHARACTER_POSITIONS_H__
$(toolkit_base_src_dir)/controls/scrollable/scroll-view/scroll-view-twist-effect-impl.cpp \
$(toolkit_base_src_dir)/controls/scrollable/scroll-view/scroll-view-wobble-effect-impl.cpp \
$(toolkit_base_src_dir)/controls/table-view/table-view-impl.cpp \
+ $(toolkit_base_src_dir)/controls/text-input/text-input-decorator-impl.cpp \
$(toolkit_base_src_dir)/controls/text-input/text-input-impl.cpp \
$(toolkit_base_src_dir)/controls/text-input/text-input-popup-impl.cpp \
$(toolkit_base_src_dir)/controls/text-view/relayout-utilities.cpp \