X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=blobdiff_plain;f=dali-toolkit%2Finternal%2Ftext%2Fdecorator%2Ftext-decorator.cpp;h=ed67d72480a5c04f4ac961d91926eabf8b928319;hp=8209d14eecee804ee06878cfd6178e7e9fd6f3e4;hb=5b3cf0e6742934674bdf62bbe15af00e39eae566;hpb=bec8228daa1be042b45b6f52eb19215a56fe8589 diff --git a/dali-toolkit/internal/text/decorator/text-decorator.cpp b/dali-toolkit/internal/text/decorator/text-decorator.cpp index 8209d14..ed67d72 100644 --- a/dali-toolkit/internal/text/decorator/text-decorator.cpp +++ b/dali-toolkit/internal/text/decorator/text-decorator.cpp @@ -20,39 +20,21 @@ // EXTERNAL INCLUDES #include -#include + #include -#include #include -#include -#include #include -#include -#include #include #include -#include #include -#include -#include -#include #include -#include -#include #include -#include #include -#include // INTERNAL INCLUDES -#include #include -#include -#include #include -#include -#include #ifdef DEBUG_ENABLED #define DECORATOR_DEBUG @@ -104,26 +86,23 @@ Integration::Log::Filter* gLogFilter( Integration::Log::Filter::New(Debug::NoLog namespace { -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_RELEASED( DALI_IMAGE_DIR "text-input-selection-handle-left.png" ); -const char* DEFAULT_SELECTION_HANDLE_ONE_PRESSED( DALI_IMAGE_DIR "text-input-selection-handle-left-press.png" ); -const char* DEFAULT_SELECTION_HANDLE_TWO_RELEASED( DALI_IMAGE_DIR "text-input-selection-handle-right.png" ); -const char* DEFAULT_SELECTION_HANDLE_TWO_PRESSED( DALI_IMAGE_DIR "text-input-selection-handle-right-press.png" ); +const char* DEFAULT_GRAB_HANDLE_IMAGE_RELEASED( DALI_IMAGE_DIR "cursor_handler_center.png" ); +const char* DEFAULT_SELECTION_HANDLE_ONE_RELEASED( DALI_IMAGE_DIR "selection_handle_left.png" ); +const char* DEFAULT_SELECTION_HANDLE_TWO_RELEASED( DALI_IMAGE_DIR "selection_handle_right.png" ); const int DEFAULT_POPUP_OFFSET( -100.0f ); // Vertical offset of Popup from cursor or handles position. const Dali::Vector3 DEFAULT_GRAB_HANDLE_RELATIVE_SIZE( 1.25f, 1.5f, 1.0f ); const Dali::Vector3 DEFAULT_SELECTION_HANDLE_RELATIVE_SIZE( 1.25f, 1.5f, 1.0f ); -const Dali::Vector4 LIGHT_BLUE( (0xb2 / 255.0f), (0xeb / 255.0f), (0xf2 / 255.0f), 0.5f ); // The text highlight color. +const Dali::Vector4 LIGHT_BLUE( 0.75f, 0.96f, 1.f, 1.f ); // The text highlight color. TODO: due some problems, maybe with the blending function in the text clipping, the color is fully opaque. + +const Dali::Vector4 HANDLE_COLOR( 0.0f, (183.0f / 255.0f), (229.0f / 255.0f), 1.0f ); 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; @@ -264,6 +243,7 @@ struct Decorator::Impl : public ConnectionTracker : mController( controller ), mEnabledPopupButtons( TextSelectionPopup::NONE ), mTextSelectionPopupCallbackInterface( callbackInterface ), + mHandleColor( HANDLE_COLOR ), mBoundingBox( Rect() ), mHighlightColor( LIGHT_BLUE ), mHighlightPosition( Vector2::ZERO ), @@ -275,6 +255,7 @@ struct Decorator::Impl : public ConnectionTracker mScrollThreshold( SCROLL_THRESHOLD ), mScrollSpeed( SCROLL_SPEED ), mScrollDistance( SCROLL_DISTANCE ), + mTextDepth( 0u ), mActiveCopyPastePopup( false ), mCursorBlinkStatus( true ), mPrimaryCursorVisible( false ), @@ -283,7 +264,7 @@ struct Decorator::Impl : public ConnectionTracker mNotifyEndOfScroll( false ) { mQuadVertexFormat[ "aPosition" ] = Property::VECTOR2; - mQuadIndexFormat[ "indices" ] = Property::UNSIGNED_INTEGER; + mQuadIndexFormat[ "indices" ] = Property::INTEGER; mHighlightMaterial = Material::New( Shader::New( VERTEX_SHADER, FRAGMENT_SHADER ) ); } @@ -296,9 +277,9 @@ struct Decorator::Impl : public ConnectionTracker // TODO - Remove this if nothing is active CreateActiveLayer(); - /* // Show or hide the cursors CreateCursors(); + if( mPrimaryCursor ) { const CursorImpl& cursor = mCursor[PRIMARY_CURSOR]; @@ -325,7 +306,7 @@ struct Decorator::Impl : public ConnectionTracker } mSecondaryCursor.SetVisible( mSecondaryCursorVisible ); } - */ + // Show or hide the grab handle HandleImpl& grabHandle = mHandle[GRAB_HANDLE]; if( grabHandle.active ) @@ -341,13 +322,13 @@ struct Decorator::Impl : public ConnectionTracker CreateGrabHandle(); grabHandle.actor.SetPosition( position.x, - position.y + grabHandle.lineHeight ); + grabHandle.lineHeight ); // TODO : Fix for multiline. } grabHandle.actor.SetVisible( isVisible ); } else if( grabHandle.actor ) { - UnparentAndReset( grabHandle.actor ); + grabHandle.actor.Unparent(); } // Show or hide the selection handles/highlight @@ -370,52 +351,52 @@ struct Decorator::Impl : public ConnectionTracker if( isPrimaryVisible ) { primary.actor.SetPosition( primaryPosition.x, - primaryPosition.y + primary.lineHeight ); + primary.lineHeight ); // TODO : Fix for multiline. } if( isSecondaryVisible ) { secondary.actor.SetPosition( secondaryPosition.x, - secondaryPosition.y + secondary.lineHeight ); + secondary.lineHeight ); // TODO : Fix for multiline. } } primary.actor.SetVisible( isPrimaryVisible ); secondary.actor.SetVisible( isSecondaryVisible ); - // Shouldn't be needed...... - UnparentAndReset( mHighlightActor ); - CreateHighlight(); UpdateHighlight(); } else { - UnparentAndReset( primary.actor ); - UnparentAndReset( secondary.actor ); - UnparentAndReset( mHighlightActor ); + if( primary.actor ) + { + primary.actor.Unparent(); + } + if( secondary.actor ) + { + secondary.actor.Unparent(); + } + if( mHighlightActor ) + { + mHighlightActor.Unparent(); + } } - if ( mActiveCopyPastePopup ) + if( mActiveCopyPastePopup ) { - // todo Swap UnparentAndReset for DeterminePositionPopup() if mCopyPastePopup.actor valid Once the issue with the labels disappearing is fixed. - UnparentAndReset( mCopyPastePopup.actor ); - if ( !mCopyPastePopup.actor ) + if( !mCopyPastePopup.actor.GetParent() ) { - mCopyPastePopup.actor = TextSelectionPopup::New( mEnabledPopupButtons, &mTextSelectionPopupCallbackInterface ); -#ifdef DECORATOR_DEBUG - mCopyPastePopup.actor.SetName("mCopyPastePopup"); -#endif - mCopyPastePopup.actor.SetAnchorPoint( AnchorPoint::CENTER ); - mCopyPastePopup.actor.OnRelayoutSignal().Connect( this, &Decorator::Impl::PopupRelayoutComplete ); // Position popup after size negotiation - mActiveLayer.Add ( mCopyPastePopup.actor ); + mActiveLayer.Add( mCopyPastePopup.actor ); } + + mCopyPastePopup.actor.RaiseAbove( mActiveLayer ); } else { - if ( mCopyPastePopup.actor ) - { - UnparentAndReset( mCopyPastePopup.actor ); - } + if( mCopyPastePopup.actor ) + { + mCopyPastePopup.actor.Unparent(); + } } } @@ -427,6 +408,7 @@ struct Decorator::Impl : public ConnectionTracker mHandle[ LEFT_SELECTION_HANDLE ].position += scrollOffset; mHandle[ RIGHT_SELECTION_HANDLE ].position += scrollOffset; mHighlightPosition += scrollOffset; + DeterminePositionPopup(); } void DeterminePositionPopup() @@ -479,11 +461,16 @@ struct Decorator::Impl : public ConnectionTracker // Add or Remove cursor(s) from parent void CreateCursors() { - /* if( mActiveCursor == ACTIVE_CURSOR_NONE ) { - UnparentAndReset( mPrimaryCursor ); - UnparentAndReset( mSecondaryCursor ); + if( mPrimaryCursor ) + { + mPrimaryCursor.Unparent(); + } + if( mSecondaryCursor ) + { + mSecondaryCursor.Unparent(); + } } else { @@ -497,6 +484,10 @@ struct Decorator::Impl : public ConnectionTracker #ifdef DECORATOR_DEBUG mPrimaryCursor.SetName( "PrimaryCursorActor" ); #endif + } + + if( !mPrimaryCursor.GetParent() ) + { mActiveLayer.Add( mPrimaryCursor ); } } @@ -509,20 +500,25 @@ struct Decorator::Impl : public ConnectionTracker #ifdef DECORATOR_DEBUG mSecondaryCursor.SetName( "SecondaryCursorActor" ); #endif + } + + if( !mSecondaryCursor.GetParent() ) + { mActiveLayer.Add( mSecondaryCursor ); } } else { - UnparentAndReset( mSecondaryCursor ); + if( mSecondaryCursor ) + { + mSecondaryCursor.Unparent(); + } } } - */ } bool OnCursorBlinkTimerTick() { - /* // Cursor blinking if ( mPrimaryCursor ) { @@ -534,7 +530,7 @@ struct Decorator::Impl : public ConnectionTracker } mCursorBlinkStatus = !mCursorBlinkStatus; - */ + return true; } @@ -582,10 +578,6 @@ struct Decorator::Impl : public ConnectionTracker { mHandleImages[GRAB_HANDLE][HANDLE_IMAGE_RELEASED] = ResourceImage::New( DEFAULT_GRAB_HANDLE_IMAGE_RELEASED ); } - if( !mHandleImages[GRAB_HANDLE][HANDLE_IMAGE_PRESSED] ) - { - mHandleImages[GRAB_HANDLE][HANDLE_IMAGE_PRESSED] = ResourceImage::New( DEFAULT_GRAB_HANDLE_IMAGE_PRESSED ); - } grabHandle.actor = ImageActor::New( mHandleImages[GRAB_HANDLE][HANDLE_IMAGE_RELEASED] ); grabHandle.actor.SetSortModifier( DECORATION_DEPTH_INDEX ); @@ -612,6 +604,7 @@ struct Decorator::Impl : public ConnectionTracker grabHandle.grabArea.SetResizePolicy( ResizePolicy::SIZE_RELATIVE_TO_PARENT, Dimension::ALL_DIMENSIONS ); grabHandle.grabArea.SetSizeModeFactor( DEFAULT_GRAB_HANDLE_RELATIVE_SIZE ); grabHandle.actor.Add( grabHandle.grabArea ); + grabHandle.actor.SetColor( mHandleColor ); grabHandle.grabArea.TouchedSignal().Connect( this, &Decorator::Impl::OnGrabHandleTouched ); mTapDetector.Attach( grabHandle.grabArea ); @@ -619,6 +612,11 @@ struct Decorator::Impl : public ConnectionTracker mActiveLayer.Add( grabHandle.actor ); } + + if( !grabHandle.actor.GetParent() ) + { + mActiveLayer.Add( grabHandle.actor ); + } } void CreateSelectionHandles() @@ -630,10 +628,6 @@ struct Decorator::Impl : public ConnectionTracker { mHandleImages[LEFT_SELECTION_HANDLE][HANDLE_IMAGE_RELEASED] = ResourceImage::New( DEFAULT_SELECTION_HANDLE_ONE_RELEASED ); } - if( !mHandleImages[LEFT_SELECTION_HANDLE][HANDLE_IMAGE_PRESSED] ) - { - mHandleImages[LEFT_SELECTION_HANDLE][HANDLE_IMAGE_PRESSED] = ResourceImage::New( DEFAULT_SELECTION_HANDLE_ONE_PRESSED ); - } primary.actor = ImageActor::New( mHandleImages[LEFT_SELECTION_HANDLE][HANDLE_IMAGE_RELEASED] ); #ifdef DECORATOR_DEBUG @@ -642,6 +636,7 @@ struct Decorator::Impl : public ConnectionTracker primary.actor.SetAnchorPoint( AnchorPoint::TOP_RIGHT ); // Change to BOTTOM_RIGHT if Look'n'Feel requires handle above text. primary.actor.SetSortModifier( DECORATION_DEPTH_INDEX ); primary.flipped = false; + primary.actor.SetColor( mHandleColor ); primary.grabArea = Actor::New(); // Area that Grab handle responds to, larger than actual handle so easier to move #ifdef DECORATOR_DEBUG @@ -657,6 +652,10 @@ struct Decorator::Impl : public ConnectionTracker primary.grabArea.TouchedSignal().Connect( this, &Decorator::Impl::OnHandleOneTouched ); primary.actor.Add( primary.grabArea ); + } + + if( !primary.actor.GetParent() ) + { mActiveLayer.Add( primary.actor ); } @@ -667,10 +666,6 @@ struct Decorator::Impl : public ConnectionTracker { mHandleImages[RIGHT_SELECTION_HANDLE][HANDLE_IMAGE_RELEASED] = ResourceImage::New( DEFAULT_SELECTION_HANDLE_TWO_RELEASED ); } - if( !mHandleImages[RIGHT_SELECTION_HANDLE][HANDLE_IMAGE_PRESSED] ) - { - mHandleImages[RIGHT_SELECTION_HANDLE][HANDLE_IMAGE_PRESSED] = ResourceImage::New( DEFAULT_SELECTION_HANDLE_TWO_PRESSED ); - } secondary.actor = ImageActor::New( mHandleImages[RIGHT_SELECTION_HANDLE][HANDLE_IMAGE_RELEASED] ); #ifdef DECORATOR_DEBUG @@ -679,6 +674,7 @@ struct Decorator::Impl : public ConnectionTracker secondary.actor.SetAnchorPoint( AnchorPoint::TOP_LEFT ); // Change to BOTTOM_LEFT if Look'n'Feel requires handle above text. secondary.actor.SetSortModifier( DECORATION_DEPTH_INDEX ); secondary.flipped = false; + secondary.actor.SetColor( mHandleColor ); secondary.grabArea = Actor::New(); // Area that Grab handle responds to, larger than actual handle so easier to move #ifdef DECORATOR_DEBUG @@ -694,13 +690,17 @@ struct Decorator::Impl : public ConnectionTracker secondary.grabArea.TouchedSignal().Connect( this, &Decorator::Impl::OnHandleTwoTouched ); secondary.actor.Add( secondary.grabArea ); + } + + if( !secondary.actor.GetParent() ) + { mActiveLayer.Add( secondary.actor ); } } void CreateHighlight() { - if ( !mHighlightActor ) + if( !mHighlightActor ) { mHighlightActor = Actor::New(); @@ -708,84 +708,105 @@ struct Decorator::Impl : public ConnectionTracker mHighlightActor.SetName( "HighlightActor" ); #endif mHighlightActor.SetAnchorPoint( AnchorPoint::TOP_LEFT ); - mHighlightActor.SetPosition( 0.0f, 0.0f, DISPLAYED_HIGHLIGHT_Z_OFFSET ); mHighlightActor.SetSize( 1.0f, 1.0f ); mHighlightActor.SetColor( mHighlightColor ); mHighlightActor.SetColorMode( USE_OWN_COLOR ); - - // Add the highlight box telling the controller it needs clipping. - mController.AddDecoration( mHighlightActor, true ); } + + // Add the highlight box telling the controller it needs clipping. + mController.AddDecoration( mHighlightActor, true ); } void UpdateHighlight() { - - if ( mHighlightActor && !mHighlightQuadList.empty() ) + if ( mHighlightActor ) { - Vector< Vector2 > vertices; - Vector< unsigned int> indices; - Vector2 vertex; + if( !mHighlightQuadList.empty() ) + { + Vector< Vector2 > vertices; + Vector< unsigned int> indices; + Vector2 vertex; - std::vector::iterator iter = mHighlightQuadList.begin(); - std::vector::iterator endIter = mHighlightQuadList.end(); + std::vector::iterator iter = mHighlightQuadList.begin(); + std::vector::iterator endIter = mHighlightQuadList.end(); - for(std::size_t v = 0; iter != endIter; ++iter,v+=4 ) - { + for( std::size_t v = 0; iter != endIter; ++iter,v+=4 ) + { - QuadCoordinates& quad = *iter; - - // top-left (v+0) - vertex.x = quad.min.x; - vertex.y = quad.min.y; - vertices.PushBack( vertex ); - - // top-right (v+1) - vertex.x = quad.max.x; - vertex.y = quad.min.y; - vertices.PushBack( vertex ); - - // bottom-left (v+2) - vertex.x = quad.min.x; - vertex.y = quad.max.y; - vertices.PushBack( vertex ); - - // bottom-right (v+3) - vertex.x = quad.max.x; - vertex.y = quad.max.y; - vertices.PushBack( vertex ); - - // triangle A (3, 1, 0) - indices.PushBack( v + 3 ); - indices.PushBack( v + 1 ); - indices.PushBack( v ); - - // triangle B (0, 2, 3) - indices.PushBack( v ); - indices.PushBack( v + 2 ); - indices.PushBack( v + 3 ); + QuadCoordinates& quad = *iter; + + // top-left (v+0) + vertex.x = quad.min.x; + vertex.y = quad.min.y; + vertices.PushBack( vertex ); + + // top-right (v+1) + vertex.x = quad.max.x; + vertex.y = quad.min.y; + vertices.PushBack( vertex ); + + // bottom-left (v+2) + vertex.x = quad.min.x; + vertex.y = quad.max.y; + vertices.PushBack( vertex ); + + // bottom-right (v+3) + vertex.x = quad.max.x; + vertex.y = quad.max.y; + vertices.PushBack( vertex ); + + // triangle A (3, 1, 0) + indices.PushBack( v + 3 ); + indices.PushBack( v + 1 ); + indices.PushBack( v ); + + // triangle B (0, 2, 3) + indices.PushBack( v ); + indices.PushBack( v + 2 ); + indices.PushBack( v + 3 ); + } + + if( mQuadVertices ) + { + mQuadVertices.SetSize( vertices.Size() ); + } + else + { + mQuadVertices = PropertyBuffer::New( mQuadVertexFormat, vertices.Size() ); + } + + if( mQuadIndices ) + { + mQuadIndices.SetSize( indices.Size() ); + } + else + { + mQuadIndices = PropertyBuffer::New( mQuadIndexFormat, indices.Size() ); + } + + mQuadVertices.SetData( &vertices[ 0 ] ); + mQuadIndices.SetData( &indices[ 0 ] ); + + if( !mQuadGeometry ) + { + mQuadGeometry = Geometry::New(); + mQuadGeometry.AddVertexBuffer( mQuadVertices ); + } + mQuadGeometry.SetIndexBuffer( mQuadIndices ); + + if( !mHighlightRenderer ) + { + mHighlightRenderer = Dali::Renderer::New( mQuadGeometry, mHighlightMaterial ); + mHighlightActor.AddRenderer( mHighlightRenderer ); + } } - PropertyBuffer quadVertices = PropertyBuffer::New( mQuadVertexFormat, vertices.Size() ); - PropertyBuffer quadIndices = PropertyBuffer::New( mQuadIndexFormat, indices.Size() ); - - quadVertices.SetData( &vertices[ 0 ] ); - quadIndices.SetData( &indices[ 0 ] ); - - Geometry quadGeometry = Geometry::New(); - quadGeometry.AddVertexBuffer( quadVertices ); - quadGeometry.SetIndexBuffer( quadIndices ); - - // if ( mHighlightRenderer ) - // { - // mHighlightRenderer.SetGeometry( quadGeometry ); - // } - // else - // { - mHighlightRenderer = Dali::Renderer::New( quadGeometry, mHighlightMaterial ); - mHighlightRenderer.SetDepthIndex( DECORATION_DEPTH_INDEX - 1 ); - // } - mHighlightActor.AddRenderer( mHighlightRenderer ); + mHighlightActor.SetPosition( mHighlightPosition.x, + mHighlightPosition.y ); + + mHighlightQuadList.clear(); + + mHighlightRenderer.SetDepthIndex( mTextDepth - 2u ); // text is rendered at mTextDepth and text's shadow at mTextDepth -1u. } } @@ -907,7 +928,8 @@ struct Decorator::Impl : public ConnectionTracker mHandle[GRAB_HANDLE].actor.SetImage( imagePressed ); } } - else if( TouchPoint::Up == point.state ) + else if( ( TouchPoint::Up == point.state ) || + ( TouchPoint::Interrupted == point.state ) ) { mHandle[GRAB_HANDLE].pressed = false; Image imageReleased = mHandleImages[GRAB_HANDLE][HANDLE_IMAGE_RELEASED]; @@ -940,7 +962,8 @@ struct Decorator::Impl : public ConnectionTracker mHandle[LEFT_SELECTION_HANDLE].actor.SetImage( imagePressed ); } } - else if( TouchPoint::Up == point.state ) + else if( ( TouchPoint::Up == point.state ) || + ( TouchPoint::Interrupted == point.state ) ) { mHandle[LEFT_SELECTION_HANDLE].pressed = false; Image imageReleased = mHandleImages[flip ? RIGHT_SELECTION_HANDLE : LEFT_SELECTION_HANDLE][HANDLE_IMAGE_RELEASED]; @@ -973,7 +996,8 @@ struct Decorator::Impl : public ConnectionTracker mHandle[RIGHT_SELECTION_HANDLE].actor.SetImage( imagePressed ); } } - else if( TouchPoint::Up == point.state ) + else if( ( TouchPoint::Up == point.state ) || + ( TouchPoint::Interrupted == point.state ) ) { Image imageReleased = mHandleImages[flip ? LEFT_SELECTION_HANDLE : RIGHT_SELECTION_HANDLE][HANDLE_IMAGE_RELEASED]; mHandle[RIGHT_SELECTION_HANDLE].pressed = false; @@ -994,13 +1018,12 @@ struct Decorator::Impl : public ConnectionTracker { float alternativePosition=0.0f;; - /* if ( mPrimaryCursor ) // Secondary cursor not used for paste { Cursor cursor = PRIMARY_CURSOR; alternativePosition = mCursor[cursor].position.y; } - */ + const float popupHeight = 120.0f; // todo Set as a MaxSize Property in Control or retrieve from CopyPastePopup class. if( mHandle[GRAB_HANDLE].active ) @@ -1095,8 +1118,10 @@ struct Decorator::Impl : public ConnectionTracker HandleImpl& leftHandle = mHandle[LEFT_SELECTION_HANDLE]; HandleImpl& rightHandle = mHandle[RIGHT_SELECTION_HANDLE]; - const HandleImageType leftImageType = leftHandle.pressed ? HANDLE_IMAGE_PRESSED : HANDLE_IMAGE_RELEASED; - const HandleImageType rightImageType = rightHandle.pressed ? HANDLE_IMAGE_PRESSED : HANDLE_IMAGE_RELEASED; + // If handle pressed and pressed image exists then use pressed image else stick with released image + const HandleImageType leftImageType = ( leftHandle.pressed && mHandleImages[LEFT_SELECTION_HANDLE][HANDLE_IMAGE_PRESSED] ) ? HANDLE_IMAGE_PRESSED : HANDLE_IMAGE_RELEASED; + const HandleImageType rightImageType = ( rightHandle.pressed && mHandleImages[RIGHT_SELECTION_HANDLE][HANDLE_IMAGE_PRESSED] ) ? HANDLE_IMAGE_PRESSED : HANDLE_IMAGE_RELEASED; + const bool leftFlipped = mSwapSelectionHandles != leftHandle.flipped; const bool rightFlipped = mSwapSelectionHandles != rightHandle.flipped; @@ -1196,6 +1221,8 @@ struct Decorator::Impl : public ConnectionTracker 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; Actor mHighlightActor; ///< Actor to display highlight Renderer mHighlightRenderer; @@ -1207,10 +1234,14 @@ struct Decorator::Impl : public ConnectionTracker TextSelectionPopupCallbackInterface& mTextSelectionPopupCallbackInterface; Image mHandleImages[HANDLE_TYPE_COUNT][HANDLE_IMAGE_TYPE_COUNT]; - Image mCursorImage; + Vector4 mHandleColor; CursorImpl mCursor[CURSOR_COUNT]; HandleImpl mHandle[HANDLE_TYPE_COUNT]; + + PropertyBuffer mQuadVertices; + PropertyBuffer mQuadIndices; + Geometry mQuadGeometry; QuadContainer mHighlightQuadList; ///< Sub-selections that combine to create the complete selection highlight Rect mBoundingBox; @@ -1225,6 +1256,7 @@ struct Decorator::Impl : public ConnectionTracker 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. + int mTextDepth; ///< The depth used to render the text. bool mActiveCopyPastePopup : 1; bool mCursorBlinkStatus : 1; ///< Flag to switch between blink on and blink off. @@ -1294,7 +1326,7 @@ const Vector2& Decorator::GetPosition( Cursor cursor ) const return mImpl->mCursor[cursor].position; } -void Decorator::SetColor( Cursor cursor, const Dali::Vector4& color ) +void Decorator::SetCursorColor( Cursor cursor, const Dali::Vector4& color ) { mImpl->mCursor[cursor].color = color; } @@ -1351,6 +1383,20 @@ float Decorator::GetCursorBlinkDuration() const void Decorator::SetHandleActive( HandleType handleType, bool active ) { mImpl->mHandle[handleType].active = active; + + if( !active ) + { + // TODO: this is a work-around. + // The problem is the handle actor does not receive the touch event with the Interrupt + // state when the power button is pressed and the application goes to background. + mImpl->mHandle[handleType].pressed = false; + Image imageReleased = mImpl->mHandleImages[handleType][HANDLE_IMAGE_RELEASED]; + ImageActor imageActor = mImpl->mHandle[handleType].actor; + if( imageReleased && imageActor ) + { + imageActor.SetImage( imageReleased ); + } + } } bool Decorator::IsHandleActive( HandleType handleType ) const @@ -1368,6 +1414,16 @@ Dali::Image Decorator::GetHandleImage( HandleType handleType, HandleImageType ha return mImpl->mHandleImages[handleType][handleImageType]; } +void Decorator::SetHandleColor( const Vector4& color ) +{ + mImpl->mHandleColor = color; +} + +const Vector4& Decorator::GetHandleColor() const +{ + return mImpl->mHandleColor; +} + void Decorator::SetPosition( HandleType handleType, float x, float y, float height ) { // Adjust grab handle displacement @@ -1423,6 +1479,11 @@ const Vector4& Decorator::GetHighlightColor() const return mImpl->mHighlightColor; } +void Decorator::SetTextDepth( int textDepth ) +{ + mImpl->mTextDepth = textDepth; +} + void Decorator::SetPopupActive( bool active ) { mImpl->mActiveCopyPastePopup = active; @@ -1436,6 +1497,21 @@ bool Decorator::IsPopupActive() const void Decorator::SetEnabledPopupButtons( TextSelectionPopup::Buttons& enabledButtonsBitMask ) { mImpl->mEnabledPopupButtons = enabledButtonsBitMask; + + UnparentAndReset( mImpl->mCopyPastePopup.actor ); + mImpl->mCopyPastePopup.actor = TextSelectionPopup::New( mImpl->mEnabledPopupButtons, + &mImpl->mTextSelectionPopupCallbackInterface ); +#ifdef DECORATOR_DEBUG + mImpl->mCopyPastePopup.actor.SetName("mCopyPastePopup"); +#endif + mImpl->mCopyPastePopup.actor.SetAnchorPoint( AnchorPoint::CENTER ); + mImpl->mCopyPastePopup.actor.OnRelayoutSignal().Connect( mImpl, &Decorator::Impl::PopupRelayoutComplete ); // Position popup after size negotiation + + if( mImpl->mActiveLayer ) + { + mImpl->mActiveLayer.Add( mImpl->mCopyPastePopup.actor ); + mImpl->mCopyPastePopup.actor.ShowPopup(); + } } TextSelectionPopup::Buttons& Decorator::GetEnabledPopupButtons()