X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali-toolkit%2Finternal%2Ftext%2Fdecorator%2Ftext-decorator.cpp;h=6d348cb3e758df4dc9eca4f49eeab00e39e7a489;hb=6af7f672f096ad4de44568a48810b509379408e8;hp=3a6d7dad5d36929478e6be9325b6153028611785;hpb=b88f2695b93192680a5779764757ada1534c57fe;p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git diff --git a/dali-toolkit/internal/text/decorator/text-decorator.cpp b/dali-toolkit/internal/text/decorator/text-decorator.cpp index 3a6d7da..6d348cb 100644 --- a/dali-toolkit/internal/text/decorator/text-decorator.cpp +++ b/dali-toolkit/internal/text/decorator/text-decorator.cpp @@ -54,7 +54,6 @@ #endif - namespace Dali { namespace Internal @@ -73,7 +72,8 @@ Integration::Log::Filter* gLogFilter( Integration::Log::Filter::New(Debug::NoLog namespace { -const char* DEFAULT_GRAB_HANDLE_IMAGE( DALI_IMAGE_DIR "insertpoint-icon.png" ); +const char* DEFAULT_GRAB_HANDLE_IMAGE_RELEASED( DALI_IMAGE_DIR "insertpoint-icon.png" ); +const char* DEFAULT_GRAB_HANDLE_IMAGE_PRESSED( DALI_IMAGE_DIR "insertpoint-icon-pressed.png" ); const char* DEFAULT_SELECTION_HANDLE_ONE( DALI_IMAGE_DIR "text-input-selection-handle-left.png" ); const char* DEFAULT_SELECTION_HANDLE_TWO( DALI_IMAGE_DIR "text-input-selection-handle-right.png" ); //const char* DEFAULT_SELECTION_HANDLE_ONE_PRESSED( DALI_IMAGE_DIR "text-input-selection-handle-left-press.png" ); @@ -82,11 +82,18 @@ const char* DEFAULT_SELECTION_HANDLE_TWO( DALI_IMAGE_DIR "text-input-selection-h const Dali::Vector3 DEFAULT_GRAB_HANDLE_RELATIVE_SIZE( 1.5f, 2.0f, 1.0f ); const Dali::Vector3 DEFAULT_SELECTION_HANDLE_RELATIVE_SIZE( 1.5f, 1.5f, 1.0f ); -const std::size_t CURSOR_BLINK_INTERVAL = 500; // Cursor blink interval -const std::size_t MILLISECONDS = 1000; +const unsigned int CURSOR_BLINK_INTERVAL = 500u; // Cursor blink interval +const float TO_MILLISECONDS = 1000.f; +const float TO_SECONDS = 1.f / TO_MILLISECONDS; const float DISPLAYED_HIGHLIGHT_Z_OFFSET( -0.05f ); +const unsigned int SCROLL_TICK_INTERVAL = 50u; + +const float SCROLL_THRESHOLD = 10.f; +const float SCROLL_SPEED = 300.f; +const float SCROLL_DISTANCE = SCROLL_SPEED * SCROLL_TICK_INTERVAL * TO_SECONDS; + /** * structure to hold coordinates of each quad, which will make up the mesh. */ @@ -151,69 +158,76 @@ namespace Text struct Decorator::Impl : public ConnectionTracker { + enum ScrollDirection + { + SCROLL_NONE, + SCROLL_RIGHT, + SCROLL_LEFT, + SCROLL_TOP, + SCROLL_BOTTOM + }; + struct CursorImpl { CursorImpl() - : x(0.0f), - y(0.0f), - cursorHeight(0.0f), - lineHeight(0.0f), - color(Dali::Color::WHITE) + : color( Dali::Color::WHITE ), + position(), + cursorHeight( 0.0f ), + lineHeight( 0.0f ) { } - float x; - float y; + Vector4 color; + Vector2 position; float cursorHeight; float lineHeight; - - Vector4 color; }; struct SelectionHandleImpl { SelectionHandleImpl() - : x(0.0f), - y(0.0f), - lineHeight(0.0f), - flipped(false) + : position(), + lineHeight( 0.0f ), + flipped( false ) { } - float x; - float y; - float lineHeight; ///< Not the handle height - bool flipped; - ImageActor actor; Actor grabArea; - Image pressedImage; - Image releasedImage; + Vector2 position; + float lineHeight; ///< Not the handle height + bool flipped; }; Impl( Dali::Toolkit::Internal::Control& parent, Observer& observer ) - : mTextControlParent(parent), - mObserver(observer), - mActiveCursor(ACTIVE_CURSOR_NONE), - mActiveGrabHandle(false), - mActiveSelection( false ), - mActiveCopyPastePopup( false ), + : mTextControlParent( parent ), + mObserver( observer ), + mBoundingBox( Rect() ), + mHighlightColor( 0.07f, 0.41f, 0.59f, 1.0f ), // light blue + mActiveCursor( ACTIVE_CURSOR_NONE ), mCursorBlinkInterval( CURSOR_BLINK_INTERVAL ), mCursorBlinkDuration( 0.0f ), - mCursorBlinkStatus( true ), mGrabDisplacementX( 0.0f ), mGrabDisplacementY( 0.0f ), - mHighlightColor( 0.07f, 0.41f, 0.59f, 1.0f ), // light blue - mBoundingBox( Rect() ) + mScrollDirection( SCROLL_NONE ), + mScrollThreshold( SCROLL_THRESHOLD ), + mScrollSpeed( SCROLL_SPEED ), + mScrollDistance( SCROLL_DISTANCE ), + mActiveGrabHandle( false ), + mActiveSelection( false ), + mActiveCopyPastePopup( false ), + mCursorBlinkStatus( true ), + mPrimaryCursorVisible( false ), + mSecondaryCursorVisible( false ) { } /** * Relayout of the decorations owned by the decorator. - * @param[in] size The Size of the UI control the decorater is adding it's decorations to. + * @param[in] size The Size of the UI control the decorator is adding it's decorations to. */ - void Relayout( const Vector2& size, const Vector2& scrollPosition ) + void Relayout( const Vector2& size ) { // TODO - Remove this if nothing is active CreateActiveLayer(); @@ -222,26 +236,42 @@ struct Decorator::Impl : public ConnectionTracker CreateCursors(); if( mPrimaryCursor ) { - mPrimaryCursor.SetPosition( mCursor[PRIMARY_CURSOR].x + scrollPosition.x, - mCursor[PRIMARY_CURSOR].y + scrollPosition.y ); - mPrimaryCursor.SetSize( Size( 1.0f, mCursor[PRIMARY_CURSOR].cursorHeight ) ); + mPrimaryCursorVisible = ( mCursor[PRIMARY_CURSOR].position.x <= size.width ) && ( mCursor[PRIMARY_CURSOR].position.x >= 0.f ); + if( mPrimaryCursorVisible ) + { + mPrimaryCursor.SetPosition( mCursor[PRIMARY_CURSOR].position.x, + mCursor[PRIMARY_CURSOR].position.y ); + mPrimaryCursor.SetSize( Size( 1.0f, mCursor[PRIMARY_CURSOR].cursorHeight ) ); + } + mPrimaryCursor.SetVisible( mPrimaryCursorVisible ); } if( mSecondaryCursor ) { - mSecondaryCursor.SetPosition( mCursor[SECONDARY_CURSOR].x + scrollPosition.x, - mCursor[SECONDARY_CURSOR].y + scrollPosition.y ); - mSecondaryCursor.SetSize( Size( 1.0f, mCursor[SECONDARY_CURSOR].cursorHeight ) ); + mSecondaryCursorVisible = ( mCursor[SECONDARY_CURSOR].position.x <= size.width ) && ( mCursor[SECONDARY_CURSOR].position.x >= 0.f ); + if( mSecondaryCursorVisible ) + { + mSecondaryCursor.SetPosition( mCursor[SECONDARY_CURSOR].position.x, + mCursor[SECONDARY_CURSOR].position.y ); + mSecondaryCursor.SetSize( Size( 1.0f, mCursor[SECONDARY_CURSOR].cursorHeight ) ); + } + mSecondaryCursor.SetVisible( mSecondaryCursorVisible ); } // Show or hide the grab handle if( mActiveGrabHandle ) { - SetupTouchEvents(); + const bool isVisible = ( mCursor[PRIMARY_CURSOR].position.x <= size.width ) && ( mCursor[PRIMARY_CURSOR].position.x >= 0.f ); + + if( isVisible ) + { + SetupTouchEvents(); - CreateGrabHandle(); + CreateGrabHandle(); - mGrabHandle.SetPosition( mCursor[PRIMARY_CURSOR].x + scrollPosition.x, - mCursor[PRIMARY_CURSOR].lineHeight + scrollPosition.y ); + mGrabHandle.SetPosition( mCursor[PRIMARY_CURSOR].position.x, + mCursor[PRIMARY_CURSOR].position.y + mCursor[PRIMARY_CURSOR].lineHeight ); + } + mGrabHandle.SetVisible( isVisible ); } else if( mGrabHandle ) { @@ -256,12 +286,12 @@ struct Decorator::Impl : public ConnectionTracker CreateSelectionHandles(); SelectionHandleImpl& primary = mSelectionHandle[ PRIMARY_SELECTION_HANDLE ]; - primary.actor.SetPosition( primary.x + scrollPosition.x, - primary.lineHeight + scrollPosition.y ); + primary.actor.SetPosition( primary.position.x, + primary.position.y + primary.lineHeight ); SelectionHandleImpl& secondary = mSelectionHandle[ SECONDARY_SELECTION_HANDLE ]; - secondary.actor.SetPosition( secondary.x + scrollPosition.x, - secondary.lineHeight + scrollPosition.y ); + secondary.actor.SetPosition( secondary.position.x, + secondary.position.y + secondary.lineHeight ); CreateHighlight(); UpdateHighlight(); @@ -295,13 +325,23 @@ struct Decorator::Impl : public ConnectionTracker } } + void UpdatePositions( const Vector2& scrollOffset ) + { + mCursor[PRIMARY_CURSOR].position += scrollOffset; + mCursor[SECONDARY_CURSOR].position += scrollOffset; + mSelectionHandle[ PRIMARY_SELECTION_HANDLE ].position += scrollOffset; + mSelectionHandle[ SECONDARY_SELECTION_HANDLE ].position += scrollOffset; + + // TODO Highlight box?? + } + void PopUpRelayoutComplete( Actor actor ) { // Size negotiation for CopyPastePopup complete so can get the size and constrain position within bounding box. mCopyPastePopup.OnRelayoutSignal().Disconnect( this, &Decorator::Impl::PopUpRelayoutComplete ); - Vector3 popupPosition( mCursor[PRIMARY_CURSOR].x, mCursor[PRIMARY_CURSOR].y -100.0f , 0.0f); //todo 100 to be an offset Property + Vector3 popupPosition( mCursor[PRIMARY_CURSOR].position.x, mCursor[PRIMARY_CURSOR].position.y -100.0f , 0.0f); //todo 100 to be an offset Property Vector3 popupSize = Vector3( mCopyPastePopup.GetRelayoutSize( Dimension::WIDTH ), mCopyPastePopup.GetRelayoutSize( Dimension::HEIGHT ), 0.0f ); @@ -312,12 +352,11 @@ struct Decorator::Impl : public ConnectionTracker mCopyPastePopup.SetPosition( popupPosition ); //todo grabhandle(cursor) or selection handle positions to be used } - void CreateCursor( ImageActor& cursor ) + void CreateCursor( ImageActor& cursor, const Vector4& color ) { - cursor = CreateSolidColorActor( Color::WHITE ); + cursor = CreateSolidColorActor( color ); cursor.SetParentOrigin( ParentOrigin::TOP_LEFT ); // Need to set the default parent origin as CreateSolidColorActor() sets a different one. cursor.SetAnchorPoint( AnchorPoint::TOP_CENTER ); - cursor.SetRelayoutEnabled( false ); } // Add or Remove cursor(s) from parent @@ -336,11 +375,11 @@ struct Decorator::Impl : public ConnectionTracker { if ( !mPrimaryCursor ) { - CreateCursor( mPrimaryCursor ); + CreateCursor( mPrimaryCursor, mCursor[PRIMARY_CURSOR].color ); #ifdef DECORATOR_DEBUG mPrimaryCursor.SetName( "PrimaryCursorActor" ); #endif - mActiveLayer.Add( mPrimaryCursor); + mActiveLayer.Add( mPrimaryCursor ); } } @@ -348,11 +387,11 @@ struct Decorator::Impl : public ConnectionTracker { if ( !mSecondaryCursor ) { - CreateCursor( mSecondaryCursor ); + CreateCursor( mSecondaryCursor, mCursor[SECONDARY_CURSOR].color ); #ifdef DECORATOR_DEBUG mSecondaryCursor.SetName( "SecondaryCursorActor" ); #endif - mActiveLayer.Add( mSecondaryCursor); + mActiveLayer.Add( mSecondaryCursor ); } } else @@ -367,11 +406,11 @@ struct Decorator::Impl : public ConnectionTracker // Cursor blinking if ( mPrimaryCursor ) { - mPrimaryCursor.SetVisible( mCursorBlinkStatus ); + mPrimaryCursor.SetVisible( mPrimaryCursorVisible && mCursorBlinkStatus ); } if ( mSecondaryCursor ) { - mSecondaryCursor.SetVisible( mCursorBlinkStatus ); + mSecondaryCursor.SetVisible( mSecondaryCursorVisible && mCursorBlinkStatus ); } mCursorBlinkStatus = !mCursorBlinkStatus; @@ -419,12 +458,16 @@ struct Decorator::Impl : public ConnectionTracker { if( !mGrabHandle ) { - if ( !mGrabHandleImage ) + if ( !mGrabHandleImageReleased ) + { + mGrabHandleImageReleased = ResourceImage::New( DEFAULT_GRAB_HANDLE_IMAGE_RELEASED ); + } + if ( !mGrabHandleImagePressed ) { - mGrabHandleImage = ResourceImage::New( DEFAULT_GRAB_HANDLE_IMAGE ); + mGrabHandleImagePressed = ResourceImage::New( DEFAULT_GRAB_HANDLE_IMAGE_PRESSED ); } - mGrabHandle = ImageActor::New( mGrabHandleImage ); + mGrabHandle = ImageActor::New( mGrabHandleImageReleased ); mGrabHandle.SetAnchorPoint( AnchorPoint::TOP_CENTER ); mGrabHandle.SetDrawMode( DrawMode::OVERLAY ); // Area that Grab handle responds to, larger than actual handle so easier to move @@ -438,12 +481,10 @@ struct Decorator::Impl : public ConnectionTracker else { mGrabArea = Actor::New(); - mGrabArea.SetRelayoutEnabled( true ); mGrabArea.SetName( "GrabArea" ); } #else mGrabArea = Actor::New(); - mGrabArea.SetRelayoutEnabled( true ); #endif mGrabArea.SetParentOrigin( ParentOrigin::TOP_CENTER ); @@ -464,12 +505,12 @@ struct Decorator::Impl : public ConnectionTracker SelectionHandleImpl& primary = mSelectionHandle[ PRIMARY_SELECTION_HANDLE ]; if ( !primary.actor ) { - if ( !primary.releasedImage ) + if ( !mSelectionReleasedLeft ) { - primary.releasedImage = ResourceImage::New( DEFAULT_SELECTION_HANDLE_ONE ); + mSelectionReleasedLeft = ResourceImage::New( DEFAULT_SELECTION_HANDLE_ONE ); } - primary.actor = ImageActor::New( primary.releasedImage ); + primary.actor = ImageActor::New( mSelectionReleasedLeft ); #ifdef DECORATOR_DEBUG primary.actor.SetName("SelectionHandleOne"); #endif @@ -478,7 +519,6 @@ struct Decorator::Impl : public ConnectionTracker primary.flipped = false; primary.grabArea = Actor::New(); // Area that Grab handle responds to, larger than actual handle so easier to move - primary.grabArea.SetRelayoutEnabled( true ); #ifdef DECORATOR_DEBUG primary.grabArea.SetName("SelectionHandleOneGrabArea"); #endif @@ -497,12 +537,12 @@ struct Decorator::Impl : public ConnectionTracker SelectionHandleImpl& secondary = mSelectionHandle[ SECONDARY_SELECTION_HANDLE ]; if ( !secondary.actor ) { - if ( !secondary.releasedImage ) + if ( !mSelectionReleasedRight ) { - secondary.releasedImage = ResourceImage::New( DEFAULT_SELECTION_HANDLE_TWO ); + mSelectionReleasedRight = ResourceImage::New( DEFAULT_SELECTION_HANDLE_TWO ); } - secondary.actor = ImageActor::New( secondary.releasedImage ); + secondary.actor = ImageActor::New( mSelectionReleasedRight ); #ifdef DECORATOR_DEBUG secondary.actor.SetName("SelectionHandleTwo"); #endif @@ -511,7 +551,6 @@ struct Decorator::Impl : public ConnectionTracker secondary.flipped = false; secondary.grabArea = Actor::New(); // Area that Grab handle responds to, larger than actual handle so easier to move - secondary.grabArea.SetRelayoutEnabled( true ); #ifdef DECORATOR_DEBUG secondary.grabArea.SetName("SelectionHandleTwoGrabArea"); #endif @@ -661,23 +700,52 @@ struct Decorator::Impl : public ConnectionTracker if( Gesture::Started == gesture.state ) { mGrabDisplacementX = mGrabDisplacementY = 0; + mGrabHandle.SetImage( mGrabHandleImagePressed ); } mGrabDisplacementX += gesture.displacement.x; mGrabDisplacementY += gesture.displacement.y; - float x = mCursor[PRIMARY_CURSOR].x + mGrabDisplacementX; - float y = mCursor[PRIMARY_CURSOR].y + mCursor[PRIMARY_CURSOR].lineHeight*0.5f + mGrabDisplacementY; + const float x = mCursor[PRIMARY_CURSOR].position.x + mGrabDisplacementX; + const float y = mCursor[PRIMARY_CURSOR].position.y + mCursor[PRIMARY_CURSOR].lineHeight*0.5f + mGrabDisplacementY; if( Gesture::Started == gesture.state || Gesture::Continuing == gesture.state ) { - mObserver.GrabHandleEvent( GRAB_HANDLE_PRESSED, x, y ); + if( x < mScrollThreshold ) + { + mScrollDirection = SCROLL_RIGHT; + mGrabDisplacementX -= x; + mCursor[PRIMARY_CURSOR].position.x = 0.f; + StartScrollTimer(); + } + else if( x > mTextControlParent.GetControlSize().width - mScrollThreshold ) + { + mScrollDirection = SCROLL_LEFT; + mGrabDisplacementX += ( mTextControlParent.GetControlSize().width - x ); + mCursor[PRIMARY_CURSOR].position.x = mTextControlParent.GetControlSize().width; + StartScrollTimer(); + } + else + { + StopScrollTimer(); + mObserver.GrabHandleEvent( GRAB_HANDLE_PRESSED, x, y ); + } } else if( Gesture::Finished == gesture.state || Gesture::Cancelled == gesture.state ) { - mObserver.GrabHandleEvent( GRAB_HANDLE_RELEASED, x, y ); + if( mScrollTimer && mScrollTimer.IsRunning() ) + { + StopScrollTimer(); + mObserver.GrabHandleEvent( GRAB_HANDLE_STOP_SCROLLING, x, y ); + } + else + { + mObserver.GrabHandleEvent( GRAB_HANDLE_RELEASED, x, y ); + } + + mGrabHandle.SetImage( mGrabHandleImageReleased ); } } } @@ -703,12 +771,12 @@ struct Decorator::Impl : public ConnectionTracker if ( mPrimaryCursor ) // Secondary cursor not used for paste { Cursor cursor = PRIMARY_CURSOR; - alternativePosition = mCursor[cursor].y; + alternativePosition = mCursor[cursor].position.y; } const float popupHeight = 120.0f; // todo Set as a MaxSize Property in Control or retrieve from CopyPastePopup class. - if ( mActiveGrabHandle ) + if( mActiveGrabHandle ) { // If grab handle enabled then position pop-up below the grab handle. const Vector2 grabHandleSize( 59.0f, 56.0f ); // todo @@ -792,49 +860,123 @@ struct Decorator::Impl : public ConnectionTracker requiredPopupPosition.x = requiredPopupPosition.x + xOffSetToKeepWithinBounds; } - Internal::Control& mTextControlParent; - Observer& mObserver; - - Layer mActiveLayer; // Layer for active handles and alike that ensures they are above all else. - - unsigned int mActiveCursor; - bool mActiveGrabHandle; - bool mActiveSelection; - bool mActiveCopyPastePopup; - - CursorImpl mCursor[CURSOR_COUNT]; + void SetScrollThreshold( float threshold ) + { + mScrollThreshold = threshold; + } - Timer mCursorBlinkTimer; // Timer to signal cursor to blink - unsigned int mCursorBlinkInterval; - float mCursorBlinkDuration; - bool mCursorBlinkStatus; // Flag to switch between blink on and blink off + float GetScrollThreshold() const + { + return mScrollThreshold; + } - ImageActor mPrimaryCursor; - ImageActor mSecondaryCursor; + void SetScrollSpeed( float speed ) + { + mScrollSpeed = speed; + mScrollDistance = speed * SCROLL_TICK_INTERVAL * TO_SECONDS; + } - ImageActor mGrabHandle; - Actor mGrabArea; - float mGrabDisplacementX; - float mGrabDisplacementY; + float GetScrollSpeed() const + { + return mScrollSpeed; + } - SelectionHandleImpl mSelectionHandle[SELECTION_HANDLE_COUNT]; + /** + * Creates and starts a timer to scroll the text when handles are close to the edges of the text. + * + * It only starts the timer if it's already created. + */ + void StartScrollTimer() + { + if( !mScrollTimer ) + { + mScrollTimer = Timer::New( SCROLL_TICK_INTERVAL ); + mScrollTimer.TickSignal().Connect( this, &Decorator::Impl::OnScrollTimerTick ); + } - MeshActor mHighlightMeshActor; ///< Mesh Actor to display highlight - Mesh mHighlightMesh; ///< Mesh for highlight - MeshData mHighlightMeshData; ///< Mesh Data for highlight - Material mHighlightMaterial; ///< Material used for highlight - Vector4 mHighlightColor; ///< Color of the highlight - QuadContainer mHighlightQuadList; ///< Sub-selections that combine to create the complete selection highlight + if( !mScrollTimer.IsRunning() ) + { + mScrollTimer.Start(); + } + } - TextSelectionPopup mCopyPastePopup; + /** + * Stops the timer used to scroll the text. + */ + void StopScrollTimer() + { + if( mScrollTimer ) + { + mScrollTimer.Stop(); + } + } - Image mCursorImage; - Image mGrabHandleImage; + /** + * Callback called by the timer used to scroll the text. + * + * It calculates and sets a new scroll position. + */ + bool OnScrollTimerTick() + { + mObserver.GrabHandleEvent( GRAB_HANDLE_SCROLLING, + mScrollDirection == SCROLL_RIGHT ? mScrollDistance : -mScrollDistance, + 0.f ); + return true; + } - TapGestureDetector mTapDetector; - PanGestureDetector mPanGestureDetector; + Internal::Control& mTextControlParent; + Observer& mObserver; + + TapGestureDetector mTapDetector; + PanGestureDetector mPanGestureDetector; + Timer mCursorBlinkTimer; ///< Timer to signal cursor to blink + Timer mScrollTimer; ///< Timer used to scroll the text when the grab handle is moved close to the edges. + + Layer mActiveLayer; ///< Layer for active handles and alike that ensures they are above all else. + ImageActor mPrimaryCursor; + ImageActor mSecondaryCursor; + ImageActor mGrabHandle; + Actor mGrabArea; + MeshActor mHighlightMeshActor; ///< Mesh Actor to display highlight + TextSelectionPopup mCopyPastePopup; + + Image mCursorImage; + Image mGrabHandleImageReleased; + Image mGrabHandleImagePressed; + Mesh mHighlightMesh; ///< Mesh for highlight + MeshData mHighlightMeshData; ///< Mesh Data for highlight + Material mHighlightMaterial; ///< Material used for highlight + + CursorImpl mCursor[CURSOR_COUNT]; + SelectionHandleImpl mSelectionHandle[SELECTION_HANDLE_COUNT]; - Rect mBoundingBox; + QuadContainer mHighlightQuadList; ///< Sub-selections that combine to create the complete selection highlight + + Image mSelectionReleasedLeft; ///< Selection handle images + Image mSelectionReleasedRight; + Image mSelectionPressedLeft; + Image mSelectionPressedRight; + + Rect mBoundingBox; + Vector4 mHighlightColor; ///< Color of the highlight + + unsigned int mActiveCursor; + unsigned int mCursorBlinkInterval; + float mCursorBlinkDuration; + float mGrabDisplacementX; + float mGrabDisplacementY; + ScrollDirection mScrollDirection; ///< The direction of the scroll. + float mScrollThreshold; ///< Defines a square area inside the control, close to the edge. A cursor entering this area will trigger scroll events. + float mScrollSpeed; ///< The scroll speed in pixels per second. + float mScrollDistance; ///< Distance the text scrolls during a scroll interval. + unsigned int mScrollInterval; ///< Time in milliseconds of a scroll interval. + + bool mActiveGrabHandle : 1; + bool mActiveSelection : 1; + bool mActiveCopyPastePopup : 1; + bool mCursorBlinkStatus : 1; ///< Flag to switch between blink on and blink off. + bool mPrimaryCursorVisible : 1; ///< Whether the primary cursor is visible. + bool mSecondaryCursorVisible : 1; ///< Whether the secondary cursor is visible. }; DecoratorPtr Decorator::New( Internal::Control& parent, Observer& observer ) @@ -852,9 +994,14 @@ const Rect& Decorator::GetBoundingBox() const return mImpl->mBoundingBox; } -void Decorator::Relayout( const Vector2& size, const Vector2& scrollPosition ) +void Decorator::Relayout( const Vector2& size ) +{ + mImpl->Relayout( size ); +} + +void Decorator::UpdatePositions( const Vector2& scrollOffset ) { - mImpl->Relayout( size, scrollPosition ); + mImpl->UpdatePositions( scrollOffset ); } /** Cursor **/ @@ -872,23 +1019,31 @@ unsigned int Decorator::GetActiveCursor() const void Decorator::SetPosition( Cursor cursor, float x, float y, float cursorHeight, float lineHeight ) { // Adjust grab handle displacement - mImpl->mGrabDisplacementX -= x - mImpl->mCursor[cursor].x; - mImpl->mGrabDisplacementY -= y - mImpl->mCursor[cursor].y; + if( PRIMARY_CURSOR == cursor ) + { + mImpl->mGrabDisplacementX -= x - mImpl->mCursor[cursor].position.x; + mImpl->mGrabDisplacementY -= y - mImpl->mCursor[cursor].position.y; + } - mImpl->mCursor[cursor].x = x; - mImpl->mCursor[cursor].y = y; + mImpl->mCursor[cursor].position.x = x; + mImpl->mCursor[cursor].position.y = y; mImpl->mCursor[cursor].cursorHeight = cursorHeight; mImpl->mCursor[cursor].lineHeight = lineHeight; } void Decorator::GetPosition( Cursor cursor, float& x, float& y, float& cursorHeight, float& lineHeight ) const { - x = mImpl->mCursor[cursor].x; - y = mImpl->mCursor[cursor].y; + x = mImpl->mCursor[cursor].position.x; + y = mImpl->mCursor[cursor].position.y; cursorHeight = mImpl->mCursor[cursor].cursorHeight; lineHeight = mImpl->mCursor[cursor].lineHeight; } +const Vector2& Decorator::GetPosition( Cursor cursor ) const +{ + return mImpl->mCursor[cursor].position; +} + void Decorator::SetColor( Cursor cursor, const Dali::Vector4& color ) { mImpl->mCursor[cursor].color = color; @@ -923,12 +1078,12 @@ void Decorator::StopCursorBlink() void Decorator::SetCursorBlinkInterval( float seconds ) { - mImpl->mCursorBlinkInterval = seconds*MILLISECONDS; // Convert to milliseconds + mImpl->mCursorBlinkInterval = static_cast( seconds * TO_MILLISECONDS ); // Convert to milliseconds } float Decorator::GetCursorBlinkInterval() const { - return mImpl->mCursorBlinkInterval; + return static_cast( mImpl->mCursorBlinkInterval ) * TO_SECONDS; } void Decorator::SetCursorBlinkDuration( float seconds ) @@ -953,14 +1108,26 @@ bool Decorator::IsGrabHandleActive() const return mImpl->mActiveGrabHandle; } -void Decorator::SetGrabHandleImage( Dali::Image image ) +void Decorator::SetGrabHandleImage( GrabHandleImageType type, Dali::Image image ) { - mImpl->mGrabHandleImage = image; + if( GRAB_HANDLE_IMAGE_PRESSED == type ) + { + mImpl->mGrabHandleImagePressed = image; + } + else + { + mImpl->mGrabHandleImageReleased = image; + } } -Dali::Image Decorator::GetGrabHandleImage() const +Dali::Image Decorator::GetGrabHandleImage( GrabHandleImageType type ) const { - return mImpl->mGrabHandleImage; + if( GRAB_HANDLE_IMAGE_PRESSED == type ) + { + return mImpl->mGrabHandleImagePressed; + } + + return mImpl->mGrabHandleImageReleased; } /** Selection **/ @@ -977,38 +1144,60 @@ bool Decorator::IsSelectionActive() const void Decorator::SetPosition( SelectionHandle handle, float x, float y, float height ) { - mImpl->mSelectionHandle[handle].x = x; - mImpl->mSelectionHandle[handle].y = y; + mImpl->mSelectionHandle[handle].position.x = x; + mImpl->mSelectionHandle[handle].position.y = y; mImpl->mSelectionHandle[handle].lineHeight = height; } void Decorator::GetPosition( SelectionHandle handle, float& x, float& y, float& height ) const { - x = mImpl->mSelectionHandle[handle].x; - y = mImpl->mSelectionHandle[handle].y; + x = mImpl->mSelectionHandle[handle].position.x; + y = mImpl->mSelectionHandle[handle].position.y; height = mImpl->mSelectionHandle[handle].lineHeight; } -void Decorator::SetImage( SelectionHandle handle, SelectionHandleState state, Dali::Image image ) +void Decorator::SetLeftSelectionImage( SelectionHandleState state, Dali::Image image ) { if( SELECTION_HANDLE_PRESSED == state ) { - mImpl->mSelectionHandle[handle].pressedImage = image; + mImpl->mSelectionPressedLeft = image; } else { - mImpl->mSelectionHandle[handle].releasedImage = image; + mImpl->mSelectionReleasedLeft = image; } } -Dali::Image Decorator::GetImage( SelectionHandle handle, SelectionHandleState state ) const +Dali::Image Decorator::GetLeftSelectionImage( SelectionHandleState state ) const { if( SELECTION_HANDLE_PRESSED == state ) { - return mImpl->mSelectionHandle[handle].pressedImage; + return mImpl->mSelectionPressedLeft; } - return mImpl->mSelectionHandle[handle].releasedImage; + return mImpl->mSelectionReleasedLeft; +} + +void Decorator::SetRightSelectionImage( SelectionHandleState state, Dali::Image image ) +{ + if( SELECTION_HANDLE_PRESSED == state ) + { + mImpl->mSelectionPressedRight = image; + } + else + { + mImpl->mSelectionReleasedRight = image; + } +} + +Dali::Image Decorator::GetRightSelectionImage( SelectionHandleState state ) const +{ + if( SELECTION_HANDLE_PRESSED == state ) + { + return mImpl->mSelectionPressedRight; + } + + return mImpl->mSelectionReleasedRight; } void Decorator::AddHighlight( float x1, float y1, float x2, float y2 ) @@ -1021,6 +1210,16 @@ void Decorator::ClearHighlights() mImpl->mHighlightQuadList.clear(); } +void Decorator::SetHighlightColor( const Vector4& color ) +{ + mImpl->mHighlightColor = color; +} + +const Vector4& Decorator::GetHighlightColor() const +{ + return mImpl->mHighlightColor; +} + void Decorator::SetPopupActive( bool active ) { mImpl->mActiveCopyPastePopup = active; @@ -1031,6 +1230,28 @@ bool Decorator::IsPopupActive() const return mImpl->mActiveCopyPastePopup ; } +/** Scroll **/ + +void Decorator::SetScrollThreshold( float threshold ) +{ + mImpl->SetScrollThreshold( threshold ); +} + +float Decorator::GetScrollThreshold() const +{ + return mImpl->GetScrollThreshold(); +} + +void Decorator::SetScrollSpeed( float speed ) +{ + mImpl->SetScrollSpeed( speed ); +} + +float Decorator::GetScrollSpeed() const +{ + return mImpl->GetScrollSpeed(); +} + Decorator::~Decorator() { delete mImpl;