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=543c232a3e2f25fe70053389c112753ccdc92d99;hp=be8cdd01218107be1fba1480e1e792ce0ee95601;hb=6ae6cb59fdc507c422db80110606c4125c19466b;hpb=c295a64b88c2cbbdd30543afe2464060de7816fd diff --git a/dali-toolkit/internal/text/decorator/text-decorator.cpp b/dali-toolkit/internal/text/decorator/text-decorator.cpp index be8cdd0..543c232 100644 --- a/dali-toolkit/internal/text/decorator/text-decorator.cpp +++ b/dali-toolkit/internal/text/decorator/text-decorator.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * Copyright (c) 2021 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,52 +19,29 @@ #include // EXTERNAL INCLUDES +#include +#include #include #include #include -#include -#include #include -#include +#include #include #include #include // INTERNAL INCLUDES -#include #include +#include #include +#include +#include #ifdef DEBUG_ENABLED #define DECORATOR_DEBUG #endif -#define MAKE_SHADER(A)#A - -namespace -{ -const char* VERTEX_SHADER = MAKE_SHADER( -attribute mediump vec2 aPosition; -uniform mediump mat4 uMvpMatrix; - -void main() -{ - mediump vec4 position = vec4( aPosition, 0.0, 1.0 ); - gl_Position = uMvpMatrix * position; -} -); - -const char* FRAGMENT_SHADER = MAKE_SHADER( -uniform lowp vec4 uColor; - -void main() -{ - gl_FragColor = uColor; -} -); -} - namespace Dali { namespace Internal @@ -72,31 +49,30 @@ namespace Internal namespace { #ifdef DECORATOR_DEBUG -Integration::Log::Filter* gLogFilter( Integration::Log::Filter::New(Debug::NoLogging, false, "LOG_TEXT_DECORATOR") ); +Integration::Log::Filter* gLogFilter(Integration::Log::Filter::New(Debug::NoLogging, false, "LOG_TEXT_DECORATOR")); #endif -} -} -} - +} // namespace +} // namespace Internal +} // namespace Dali // Local Data namespace { -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::Vector3 ACTIVE_LAYER_ANCHOR_POINT( 0.5f, 0.5f, 0.5f ); +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::Vector3 ACTIVE_LAYER_ANCHOR_POINT(0.5f, 0.5f, 0.5f); -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 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 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 in milliseconds. -const float TO_MILLISECONDS = 1000.f; ///< Converts from seconds to milliseconds. -const float TO_SECONDS = 1.f / TO_MILLISECONDS; ///< Converts from milliseconds to seconds. +const unsigned int CURSOR_BLINK_INTERVAL = 500u; ///< Cursor blink interval in milliseconds. +const float TO_MILLISECONDS = 1000.f; ///< Converts from seconds to milliseconds. +const float TO_SECONDS = 1.f / TO_MILLISECONDS; ///< Converts from milliseconds to seconds. -const unsigned int SCROLL_TICK_INTERVAL = 50u; ///< Scroll interval in milliseconds. -const float SCROLL_THRESHOLD = 10.f; ///< Threshold in pixels close to the edges of the decorator boundaries from where the scroll timer starts to emit signals. -const float SCROLL_SPEED = 300.f; ///< The scroll speed in pixels/second. +const unsigned int SCROLL_TICK_INTERVAL = 50u; ///< Scroll interval in milliseconds. +const float SCROLL_THRESHOLD = 10.f; ///< Threshold in pixels close to the edges of the decorator boundaries from where the scroll timer starts to emit signals. +const float SCROLL_SPEED = 300.f; ///< The scroll speed in pixels/second. const float SCROLL_DISTANCE = SCROLL_SPEED * SCROLL_TICK_INTERVAL * TO_SECONDS; ///< Distance in pixels scrolled in one second. @@ -111,7 +87,7 @@ typedef Dali::Vector QuadContainer; * @param[in] boundingRectangle local bounding * @param[out] Vector4 World coordinate bounding Box. */ -void LocalToWorldCoordinatesBoundingBox( const Dali::Rect& boundingRectangle, Dali::Vector4& boundingBox ) +void LocalToWorldCoordinatesBoundingBox(const Dali::Rect& boundingRectangle, Dali::Vector4& boundingBox) { // Convert to world coordinates and store as a Vector4 to be compatible with Property Notifications. Dali::Vector2 stageSize = Dali::Stage::GetCurrent().GetSize(); @@ -119,20 +95,20 @@ void LocalToWorldCoordinatesBoundingBox( const Dali::Rect& boundingRectangl const float originX = boundingRectangle.x - 0.5f * stageSize.width; const float originY = boundingRectangle.y - 0.5f * stageSize.height; - boundingBox = Dali::Vector4( originX, - originY, - originX + boundingRectangle.width, - originY + boundingRectangle.height ); + boundingBox = Dali::Vector4(originX, + originY, + originX + boundingRectangle.width, + originY + boundingRectangle.height); } -void WorldToLocalCoordinatesBoundingBox( const Dali::Vector4& boundingBox, Dali::Rect& boundingRectangle ) +void WorldToLocalCoordinatesBoundingBox(const Dali::Vector4& boundingBox, Dali::Rect& boundingRectangle) { // Convert to local coordinates and store as a Dali::Rect. Dali::Vector2 stageSize = Dali::Stage::GetCurrent().GetSize(); - boundingRectangle.x = boundingBox.x + 0.5f * stageSize.width; - boundingRectangle.y = boundingBox.y + 0.5f * stageSize.height; - boundingRectangle.width = boundingBox.z - boundingBox.x; + boundingRectangle.x = boundingBox.x + 0.5f * stageSize.width; + boundingRectangle.y = boundingBox.y + 0.5f * stageSize.height; + boundingRectangle.width = boundingBox.z - boundingBox.x; boundingRectangle.height = boundingBox.w - boundingBox.y; } @@ -140,13 +116,10 @@ void WorldToLocalCoordinatesBoundingBox( const Dali::Vector4& boundingBox, Dali: namespace Dali { - namespace Toolkit { - namespace Text { - struct Decorator::Impl : public ConnectionTracker { enum ScrollDirection @@ -161,19 +134,19 @@ struct Decorator::Impl : public ConnectionTracker struct CursorImpl { CursorImpl() - : color( Dali::Color::BLACK ), + : color(Dali::Color::BLACK), position(), - cursorHeight( 0.0f ), - lineHeight( 0.0f ), - glyphOffset( 0.0f ) + cursorHeight(0.0f), + lineHeight(0.0f), + glyphOffset(0.0f) { } Vector4 color; Vector2 position; - float cursorHeight; - float lineHeight; - float glyphOffset; + float cursorHeight; + float lineHeight; + float glyphOffset; }; struct HandleImpl @@ -182,38 +155,38 @@ struct Decorator::Impl : public ConnectionTracker : position(), globalPosition(), size(), - lineHeight( 0.0f ), - grabDisplacementX( 0.f ), - grabDisplacementY( 0.f ), - active( false ), - horizontallyVisible( false ), - verticallyVisible( false ), - pressed( false ), - verticallyFlippedPreferred( false ), - horizontallyFlipped( false ), - verticallyFlipped( false ), - verticallyFlippedOnTouch( false ) + lineHeight(0.0f), + grabDisplacementX(0.f), + grabDisplacementY(0.f), + active(false), + horizontallyVisible(false), + verticallyVisible(false), + pressed(false), + verticallyFlippedPreferred(false), + horizontallyFlipped(false), + verticallyFlipped(false), + verticallyFlippedOnTouch(false) { } ImageView actor; - Actor grabArea; + Actor grabArea; ImageView markerActor; Vector2 position; Vector2 globalPosition; Size size; - float lineHeight; ///< Not the handle height + float lineHeight; ///< Not the handle height float grabDisplacementX; float grabDisplacementY; - bool active : 1; - bool horizontallyVisible : 1; - bool verticallyVisible : 1; - bool pressed : 1; + bool active : 1; + bool horizontallyVisible : 1; + bool verticallyVisible : 1; + bool pressed : 1; bool verticallyFlippedPreferred : 1; ///< Whether the handle is preferred to be vertically flipped. - bool horizontallyFlipped : 1; ///< Whether the handle has been horizontally flipped. - bool verticallyFlipped : 1; ///< Whether the handle has been vertically flipped. - bool verticallyFlippedOnTouch : 1; ///< Whether the handle is vertically flipped on touch. + bool horizontallyFlipped : 1; ///< Whether the handle has been horizontally flipped. + bool verticallyFlipped : 1; ///< Whether the handle has been vertically flipped. + bool verticallyFlippedOnTouch : 1; ///< Whether the handle is vertically flipped on touch. }; struct PopupImpl @@ -224,52 +197,53 @@ struct Decorator::Impl : public ConnectionTracker } TextSelectionPopup actor; - Vector3 position; + Vector3 position; }; - Impl( ControllerInterface& controller, - TextSelectionPopupCallbackInterface& callbackInterface ) - : mController( controller ), - mEnabledPopupButtons( TextSelectionPopup::NONE ), - mTextSelectionPopupCallbackInterface( callbackInterface ), - mHandleColor( HANDLE_COLOR ), + Impl(ControllerInterface& controller, + TextSelectionPopupCallbackInterface& callbackInterface) + : mController(controller), + mEnabledPopupButtons(TextSelectionPopup::NONE), + mTextSelectionPopupCallbackInterface(callbackInterface), + mHandleColor(HANDLE_COLOR), mBoundingBox(), - mHighlightColor( LIGHT_BLUE ), - mHighlightPosition( Vector2::ZERO ), - mHighlightSize( Vector2::ZERO ), - mControlSize( Vector2::ZERO ), - mHighlightOutlineOffset( 0.f ), - mActiveCursor( ACTIVE_CURSOR_NONE ), - mCursorBlinkInterval( CURSOR_BLINK_INTERVAL ), - mCursorBlinkDuration( 0.0f ), - mCursorWidth( CURSOR_WIDTH ), - mHandleScrolling( HANDLE_TYPE_COUNT ), - mHandleReleased( HANDLE_TYPE_COUNT ), - mScrollDirection( SCROLL_NONE ), - mScrollThreshold( SCROLL_THRESHOLD ), - mScrollSpeed( SCROLL_SPEED ), - mScrollDistance( SCROLL_DISTANCE ), - mTextDepth( 0u ), - mActiveCopyPastePopup( false ), - mPopupSetNewPosition( true ), - mCursorBlinkStatus( true ), - mDelayCursorBlink( false ), - mPrimaryCursorVisible( false ), - mSecondaryCursorVisible( false ), - mFlipSelectionHandlesOnCross( false ), - mFlipLeftSelectionHandleDirection( false ), - mFlipRightSelectionHandleDirection( false ), - mIsHandlePanning( false ), - mIsHandleCurrentlyCrossed( false ), - mIsHandlePreviouslyCrossed( false ), - mNotifyEndOfScroll( false ), - mHorizontalScrollingEnabled( false ), - mVerticalScrollingEnabled( false ), - mSmoothHandlePanEnabled( false ), - mIsHighlightBoxActive( false ) + mHighlightColor(LIGHT_BLUE), + mHighlightPosition(Vector2::ZERO), + mHighlightSize(Vector2::ZERO), + mControlSize(Vector2::ZERO), + mHighlightOutlineOffset(0.f), + mActiveCursor(ACTIVE_CURSOR_NONE), + mCursorBlinkInterval(CURSOR_BLINK_INTERVAL), + mCursorBlinkDuration(0.0f), + mCursorWidth(CURSOR_WIDTH), + mHandleScrolling(HANDLE_TYPE_COUNT), + mHandleReleased(HANDLE_TYPE_COUNT), + mScrollDirection(SCROLL_NONE), + mScrollThreshold(SCROLL_THRESHOLD), + mScrollSpeed(SCROLL_SPEED), + mScrollDistance(SCROLL_DISTANCE), + mTextDepth(0u), + mActiveCopyPastePopup(false), + mPopupSetNewPosition(true), + mCursorBlinkStatus(true), + mDelayCursorBlink(false), + mPrimaryCursorVisible(false), + mSecondaryCursorVisible(false), + mFlipSelectionHandlesOnCross(false), + mFlipLeftSelectionHandleDirection(false), + mFlipRightSelectionHandleDirection(false), + mIsHandlePanning(false), + mIsHandleCurrentlyCrossed(false), + mIsHandlePreviouslyCrossed(false), + mNotifyEndOfScroll(false), + mHorizontalScrollingEnabled(false), + mVerticalScrollingEnabled(false), + mSmoothHandlePanEnabled(false), + mIsHighlightBoxActive(false), + mHidePrimaryCursorAndGrabHandle(false) { - mQuadVertexFormat[ "aPosition" ] = Property::VECTOR2; - mHighlightShader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER ); + mQuadVertexFormat["aPosition"] = Property::VECTOR2; + mHighlightShader = Shader::New(SHADER_TEXT_DECORATOR_SHADER_VERT, SHADER_TEXT_DECORATOR_SHADER_FRAG); SetupGestures(); } @@ -277,61 +251,60 @@ struct Decorator::Impl : public ConnectionTracker * Relayout of the decorations owned by the decorator. * @param[in] size The Size of the UI control the decorator is adding it's decorations to. */ - void Relayout( const Vector2& size ) + void Relayout(const Vector2& size) { mControlSize = size; // TODO - Remove this if nothing is active - CreateActiveLayer(); + CreateLayer(mActiveLayer, DecorationType::ACTIVE_LAYER); + CreateLayer(mCursorLayer, DecorationType::CURSOR_LAYER); // Show or hide the cursors CreateCursors(); - if( mPrimaryCursor ) + if(mPrimaryCursor) { const CursorImpl& cursor = mCursor[PRIMARY_CURSOR]; - mPrimaryCursorVisible = ( ( mControlSize.width - ( cursor.position.x + mCursorWidth ) > -Math::MACHINE_EPSILON_1000 ) && - ( cursor.position.x > -Math::MACHINE_EPSILON_1000 ) && - ( mControlSize.height - ( cursor.position.y + cursor.cursorHeight ) > -Math::MACHINE_EPSILON_1000 ) && - ( cursor.position.y > -Math::MACHINE_EPSILON_1000 ) ); - if( mPrimaryCursorVisible ) + mPrimaryCursorVisible = (!mHidePrimaryCursorAndGrabHandle) && ((mControlSize.width - (cursor.position.x + mCursorWidth) > -Math::MACHINE_EPSILON_1000) && + (cursor.position.x > -Math::MACHINE_EPSILON_1000) && + (mControlSize.height - cursor.position.y > -Math::MACHINE_EPSILON_1000) && + (cursor.position.y + cursor.cursorHeight > -Math::MACHINE_EPSILON_1000)); + if(mPrimaryCursorVisible) { - mPrimaryCursor.SetPosition( cursor.position.x, - cursor.position.y ); - mPrimaryCursor.SetSize( Size( mCursorWidth, cursor.cursorHeight ) ); + mPrimaryCursor.SetProperty(Actor::Property::POSITION, Vector2(cursor.position.x, cursor.position.y)); + mPrimaryCursor.SetProperty(Actor::Property::SIZE, Size(mCursorWidth, cursor.cursorHeight)); } - mPrimaryCursor.SetVisible( mPrimaryCursorVisible && mCursorBlinkStatus ); + mPrimaryCursor.SetProperty(Actor::Property::VISIBLE, mPrimaryCursorVisible && mCursorBlinkStatus); } - if( mSecondaryCursor ) + if(mSecondaryCursor) { const CursorImpl& cursor = mCursor[SECONDARY_CURSOR]; - mSecondaryCursorVisible = ( ( mControlSize.width - ( cursor.position.x + mCursorWidth ) > -Math::MACHINE_EPSILON_1000 ) && - ( cursor.position.x > -Math::MACHINE_EPSILON_1000 ) && - ( mControlSize.height - ( cursor.position.y + cursor.cursorHeight ) > -Math::MACHINE_EPSILON_1000 ) && - ( cursor.position.y > -Math::MACHINE_EPSILON_1000 ) ); - if( mSecondaryCursorVisible ) + mSecondaryCursorVisible = ((mControlSize.width - (cursor.position.x + mCursorWidth) > -Math::MACHINE_EPSILON_1000) && + (cursor.position.x > -Math::MACHINE_EPSILON_1000) && + (mControlSize.height - cursor.position.y > -Math::MACHINE_EPSILON_1000) && + (cursor.position.y + cursor.cursorHeight > -Math::MACHINE_EPSILON_1000)); + if(mSecondaryCursorVisible) { - mSecondaryCursor.SetPosition( cursor.position.x, - cursor.position.y ); - mSecondaryCursor.SetSize( Size( mCursorWidth, cursor.cursorHeight ) ); + mSecondaryCursor.SetProperty(Actor::Property::POSITION, Vector2(cursor.position.x, cursor.position.y)); + mSecondaryCursor.SetProperty(Actor::Property::SIZE, Size(mCursorWidth, cursor.cursorHeight)); } - mSecondaryCursor.SetVisible( mSecondaryCursorVisible && mCursorBlinkStatus ); + mSecondaryCursor.SetProperty(Actor::Property::VISIBLE, mSecondaryCursorVisible && mCursorBlinkStatus); } // Show or hide the grab handle - HandleImpl& grabHandle = mHandle[GRAB_HANDLE]; - bool newGrabHandlePosition = false; - grabHandle.horizontallyVisible = false; - grabHandle.verticallyVisible = false; - if( grabHandle.active ) - { - grabHandle.horizontallyVisible = ( ( mControlSize.width - ( grabHandle.position.x + floor( 0.5f * mCursorWidth ) ) > -Math::MACHINE_EPSILON_1000 ) && - ( grabHandle.position.x > -Math::MACHINE_EPSILON_1000 ) ); - grabHandle.verticallyVisible = ( ( ( mControlSize.height - grabHandle.lineHeight ) - grabHandle.position.y > -Math::MACHINE_EPSILON_1000 ) && - ( grabHandle.position.y > -Math::MACHINE_EPSILON_1000 ) ); - - const bool isVisible = grabHandle.horizontallyVisible && grabHandle.verticallyVisible; - if( isVisible ) + HandleImpl& grabHandle = mHandle[GRAB_HANDLE]; + bool newGrabHandlePosition = false; + grabHandle.horizontallyVisible = false; + grabHandle.verticallyVisible = false; + if(grabHandle.active) + { + grabHandle.horizontallyVisible = ((mControlSize.width - (grabHandle.position.x + floor(0.5f * mCursorWidth)) > -Math::MACHINE_EPSILON_1000) && + (grabHandle.position.x > -Math::MACHINE_EPSILON_1000)); + grabHandle.verticallyVisible = ((fabsf(mControlSize.height - grabHandle.lineHeight) - grabHandle.position.y > -Math::MACHINE_EPSILON_1000) && + (grabHandle.position.y + grabHandle.lineHeight > -Math::MACHINE_EPSILON_1000)); + + const bool isVisible = grabHandle.horizontallyVisible && grabHandle.verticallyVisible && (!mHidePrimaryCursorAndGrabHandle); + if(isVisible) { CreateGrabHandle(); @@ -339,122 +312,121 @@ struct Decorator::Impl : public ConnectionTracker SetGrabHandlePosition(); // Sets the grab handle image according if it's pressed, flipped, etc. - SetHandleImage( GRAB_HANDLE ); + SetHandleImage(GRAB_HANDLE); newGrabHandlePosition = true; } - if( grabHandle.actor ) + if(grabHandle.actor) { - grabHandle.actor.SetVisible( isVisible ); + grabHandle.actor.SetProperty(Actor::Property::VISIBLE, isVisible); } } - else if( grabHandle.actor ) + else if(grabHandle.actor) { grabHandle.actor.Unparent(); } // Show or hide the selection handles/highlight - HandleImpl& primary = mHandle[ LEFT_SELECTION_HANDLE ]; - HandleImpl& secondary = mHandle[ RIGHT_SELECTION_HANDLE ]; - bool newPrimaryHandlePosition = false; - bool newSecondaryHandlePosition = false; - - primary.horizontallyVisible = ( ( mControlSize.width - primary.position.x > -Math::MACHINE_EPSILON_1000 ) && - ( primary.position.x > -Math::MACHINE_EPSILON_1000 ) ); - primary.verticallyVisible = ( ( ( mControlSize.height - primary.lineHeight ) - primary.position.y > -Math::MACHINE_EPSILON_1000 ) && - ( primary.position.y + ( primary.verticallyFlipped ? 0.f : primary.lineHeight ) > -Math::MACHINE_EPSILON_1000 ) ); - secondary.horizontallyVisible = ( ( mControlSize.width - secondary.position.x > -Math::MACHINE_EPSILON_1000 ) && - ( secondary.position.x > -Math::MACHINE_EPSILON_1000 ) ); - secondary.verticallyVisible = ( ( ( mControlSize.height - secondary.lineHeight ) - secondary.position.y > -Math::MACHINE_EPSILON_1000 ) && - ( secondary.position.y + ( secondary.verticallyFlipped ? 0.f : secondary.lineHeight ) > -Math::MACHINE_EPSILON_1000 ) ); - - const bool primaryVisible = primary.horizontallyVisible && primary.verticallyVisible; + HandleImpl& primary = mHandle[LEFT_SELECTION_HANDLE]; + HandleImpl& secondary = mHandle[RIGHT_SELECTION_HANDLE]; + bool newPrimaryHandlePosition = false; + bool newSecondaryHandlePosition = false; + + primary.horizontallyVisible = ((mControlSize.width - primary.position.x > -Math::MACHINE_EPSILON_1000) && + (primary.position.x > -Math::MACHINE_EPSILON_1000)); + primary.verticallyVisible = ((fabsf(mControlSize.height - primary.lineHeight) - primary.position.y > -Math::MACHINE_EPSILON_1000) && + (primary.position.y + (primary.verticallyFlipped ? 0.f : primary.lineHeight) > -Math::MACHINE_EPSILON_1000)); + secondary.horizontallyVisible = ((mControlSize.width - secondary.position.x > -Math::MACHINE_EPSILON_1000) && + (secondary.position.x > -Math::MACHINE_EPSILON_1000)); + secondary.verticallyVisible = ((fabsf(mControlSize.height - secondary.lineHeight) - secondary.position.y > -Math::MACHINE_EPSILON_1000) && + (secondary.position.y + (secondary.verticallyFlipped ? 0.f : secondary.lineHeight) > -Math::MACHINE_EPSILON_1000)); + + const bool primaryVisible = primary.horizontallyVisible && primary.verticallyVisible; const bool secondaryVisible = secondary.horizontallyVisible && secondary.verticallyVisible; - if( primary.active || secondary.active ) + if(primary.active || secondary.active) { - if( primaryVisible || secondaryVisible ) + if(primaryVisible || secondaryVisible) { CreateSelectionHandles(); - if( primaryVisible ) + if(primaryVisible) { - SetSelectionHandlePosition( LEFT_SELECTION_HANDLE ); + SetSelectionHandlePosition(LEFT_SELECTION_HANDLE); // Sets the primary handle image according if it's pressed, flipped, etc. - SetHandleImage( LEFT_SELECTION_HANDLE ); + SetHandleImage(LEFT_SELECTION_HANDLE); - SetSelectionHandleMarkerSize( primary ); + SetSelectionHandleMarkerSize(primary); newPrimaryHandlePosition = true; } - if( secondaryVisible ) + if(secondaryVisible) { - SetSelectionHandlePosition( RIGHT_SELECTION_HANDLE ); + SetSelectionHandlePosition(RIGHT_SELECTION_HANDLE); // Sets the secondary handle image according if it's pressed, flipped, etc. - SetHandleImage( RIGHT_SELECTION_HANDLE ); + SetHandleImage(RIGHT_SELECTION_HANDLE); - SetSelectionHandleMarkerSize( secondary ); + SetSelectionHandleMarkerSize(secondary); newSecondaryHandlePosition = true; } } - if( primary.actor ) + if(primary.actor) { - primary.actor.SetVisible( primaryVisible ); + primary.actor.SetProperty(Actor::Property::VISIBLE, primaryVisible); } - if( secondary.actor ) + if(secondary.actor) { - secondary.actor.SetVisible( secondaryVisible ); + secondary.actor.SetProperty(Actor::Property::VISIBLE, secondaryVisible); } - } else { - if( primary.actor ) + if(primary.actor) { primary.actor.Unparent(); } - if( secondary.actor ) + if(secondary.actor) { secondary.actor.Unparent(); } } - if( mIsHighlightBoxActive ) + if(mIsHighlightBoxActive) { CreateHighlight(); UpdateHighlight(); } else { - if( mHighlightActor ) + if(mHighlightActor) { mHighlightActor.Unparent(); } } - if( newGrabHandlePosition || - newPrimaryHandlePosition || - newSecondaryHandlePosition ) + if(newGrabHandlePosition || + newPrimaryHandlePosition || + newSecondaryHandlePosition) { // Setup property notifications to find whether the handles leave the boundaries of the current display. SetupActiveLayerPropertyNotifications(); } - if( mActiveCopyPastePopup && - ( primaryVisible || secondaryVisible ) ) + if(mActiveCopyPastePopup && + (primaryVisible || secondaryVisible)) { ShowPopup(); mPopupSetNewPosition = true; } else { - if( mCopyPastePopup.actor ) + if(mCopyPastePopup.actor) { mCopyPastePopup.actor.HidePopup(); mPopupSetNewPosition = true; @@ -462,63 +434,63 @@ struct Decorator::Impl : public ConnectionTracker } } - void UpdatePositions( const Vector2& scrollOffset ) + void UpdatePositions(const Vector2& scrollOffset) { mCursor[PRIMARY_CURSOR].position += scrollOffset; mCursor[SECONDARY_CURSOR].position += scrollOffset; - mHandle[ GRAB_HANDLE ].position += scrollOffset; - mHandle[ LEFT_SELECTION_HANDLE ].position += scrollOffset; - mHandle[ RIGHT_SELECTION_HANDLE ].position += scrollOffset; + mHandle[GRAB_HANDLE].position += scrollOffset; + mHandle[LEFT_SELECTION_HANDLE].position += scrollOffset; + mHandle[RIGHT_SELECTION_HANDLE].position += scrollOffset; mHighlightPosition += scrollOffset; } void ShowPopup() { - if( !mCopyPastePopup.actor ) + if(!mCopyPastePopup.actor) { return; } - if( !mCopyPastePopup.actor.GetParent() ) + if(!mCopyPastePopup.actor.GetParent()) { - mActiveLayer.Add( mCopyPastePopup.actor ); + mActiveLayer.Add(mCopyPastePopup.actor); } - mCopyPastePopup.actor.RaiseAbove( mActiveLayer ); + mCopyPastePopup.actor.RaiseAbove(mActiveLayer); mCopyPastePopup.actor.ShowPopup(); } - float CalculateVerticalPopUpPosition( float halfHeight, bool preferBelow ) + float CalculateVerticalPopUpPosition(float halfHeight, bool preferBelow) { float yPosition = 0.f; - const HandleImpl& primaryHandle = mHandle[LEFT_SELECTION_HANDLE]; + const HandleImpl& primaryHandle = mHandle[LEFT_SELECTION_HANDLE]; const HandleImpl& secondaryHandle = mHandle[RIGHT_SELECTION_HANDLE]; - const HandleImpl& grabHandle = mHandle[GRAB_HANDLE]; + const HandleImpl& grabHandle = mHandle[GRAB_HANDLE]; - if( primaryHandle.active || secondaryHandle.active ) + if(primaryHandle.active || secondaryHandle.active) { // The origin of the decorator's coordinate system in world coords. - const Vector3 originWorldCoords = mActiveLayer.GetCurrentWorldPosition() - mActiveLayer.GetCurrentSize() * ACTIVE_LAYER_ANCHOR_POINT; + const Vector3 originWorldCoords = mActiveLayer.GetCurrentProperty(Actor::Property::WORLD_POSITION) - mActiveLayer.GetCurrentProperty(Actor::Property::SIZE) * ACTIVE_LAYER_ANCHOR_POINT; - if( preferBelow ) + if(preferBelow) { // Find out if there is enough space for the popup at the bottom. - const float primaryBelowY = primaryHandle.position.y + primaryHandle.lineHeight + primaryHandle.size.height; + const float primaryBelowY = primaryHandle.position.y + primaryHandle.lineHeight + primaryHandle.size.height; const float secondaryBelowY = secondaryHandle.position.y + secondaryHandle.lineHeight + secondaryHandle.size.height; - float maxY = std::max( primaryBelowY, secondaryBelowY ); + float maxY = std::max(primaryBelowY, secondaryBelowY); yPosition = halfHeight + maxY; - if( originWorldCoords.y + yPosition + halfHeight > mBoundingBox.w ) + if(originWorldCoords.y + yPosition + halfHeight > mBoundingBox.w) { // Does not fit below. // Try to fit first below the non active handle. Otherwise above the active handle. - if( RIGHT_SELECTION_HANDLE == mHandleReleased ) + if(RIGHT_SELECTION_HANDLE == mHandleReleased) { - if( primaryBelowY < secondaryBelowY ) + if(primaryBelowY < secondaryBelowY) { yPosition = halfHeight + primaryBelowY; } @@ -527,9 +499,9 @@ struct Decorator::Impl : public ConnectionTracker yPosition = primaryHandle.position.y - primaryHandle.size.height - halfHeight; } } - else if( LEFT_SELECTION_HANDLE == mHandleReleased ) + else if(LEFT_SELECTION_HANDLE == mHandleReleased) { - if( secondaryBelowY < primaryBelowY ) + if(secondaryBelowY < primaryBelowY) { yPosition = halfHeight + secondaryBelowY; } @@ -540,12 +512,12 @@ struct Decorator::Impl : public ConnectionTracker } // Check the handle is whithin the decoration box. - if( originWorldCoords.y + yPosition < mBoundingBox.y ) + if(originWorldCoords.y + yPosition < mBoundingBox.y) { yPosition = mBoundingBox.y - originWorldCoords.y + halfHeight; } - if( originWorldCoords.y + yPosition > mBoundingBox.w ) + if(originWorldCoords.y + yPosition > mBoundingBox.w) { yPosition = mBoundingBox.w - originWorldCoords.y - halfHeight; } @@ -554,17 +526,17 @@ struct Decorator::Impl : public ConnectionTracker else { // Find out if there is enough space for the popup at the top. - const float primaryTopY = primaryHandle.position.y - primaryHandle.size.height; + const float primaryTopY = primaryHandle.position.y - primaryHandle.size.height; const float secondaryTopY = secondaryHandle.position.y - secondaryHandle.size.height; - float minY = std::min( primaryTopY, secondaryTopY ); + float minY = std::min(primaryTopY, secondaryTopY); yPosition = -halfHeight + minY; } // !preferBelow - } // ( primaryHandle.active || secondaryHandle.active ) - else if( grabHandle.active ) + } // ( primaryHandle.active || secondaryHandle.active ) + else if(grabHandle.active) { - if( preferBelow ) + if(preferBelow) { yPosition = halfHeight + grabHandle.lineHeight + grabHandle.size.height + grabHandle.position.y; } @@ -577,102 +549,103 @@ struct Decorator::Impl : public ConnectionTracker return yPosition; } - void ConstrainPopupPosition( const Vector3& popupHalfSize ) + void ConstrainPopupPosition(const Vector3& popupHalfSize) { // Check if the popup is within the boundaries of the decoration box. // Check first the horizontal dimension. If is not within the boundaries, it calculates the offset. // The origin of the decorator's coordinate system in world coords. - const Vector3 originWorldCoords = mActiveLayer.GetCurrentWorldPosition() - mActiveLayer.GetCurrentSize() * ACTIVE_LAYER_ANCHOR_POINT; + const Vector3 originWorldCoords = mActiveLayer.GetCurrentProperty(Actor::Property::WORLD_POSITION) - mActiveLayer.GetCurrentProperty(Actor::Property::SIZE) * ACTIVE_LAYER_ANCHOR_POINT; // The popup's position in world coords. Vector3 popupPositionWorldCoords = originWorldCoords + mCopyPastePopup.position; - if( popupPositionWorldCoords.x - popupHalfSize.width < mBoundingBox.x ) + if(popupPositionWorldCoords.x - popupHalfSize.width < mBoundingBox.x) { - mCopyPastePopup.position.x += mBoundingBox.x - ( popupPositionWorldCoords.x - popupHalfSize.width ); + mCopyPastePopup.position.x += mBoundingBox.x - (popupPositionWorldCoords.x - popupHalfSize.width); } - else if( popupPositionWorldCoords.x + popupHalfSize.width > mBoundingBox.z ) + else if(popupPositionWorldCoords.x + popupHalfSize.width > mBoundingBox.z) { - mCopyPastePopup.position.x += mBoundingBox.z - ( popupPositionWorldCoords.x + popupHalfSize.width ); + mCopyPastePopup.position.x += mBoundingBox.z - (popupPositionWorldCoords.x + popupHalfSize.width); } // Check the vertical dimension. If the popup doesn't fit above the handles, it looks for a valid position below. - if( popupPositionWorldCoords.y - popupHalfSize.height < mBoundingBox.y ) + if(popupPositionWorldCoords.y - popupHalfSize.height < mBoundingBox.y) { - mCopyPastePopup.position.y = CalculateVerticalPopUpPosition( popupHalfSize.height, true ); // true -> prefer to set the popup's position below. + mCopyPastePopup.position.y = CalculateVerticalPopUpPosition(popupHalfSize.height, true); // true -> prefer to set the popup's position below. } } - void SetPopupPosition( Actor actor ) + void SetPopupPosition(Actor actor) { - if( !mActiveCopyPastePopup ) + if(!mActiveCopyPastePopup) { return; } // Retrieves the popup's size after relayout. - const Vector3 popupSize( mCopyPastePopup.actor.GetRelayoutSize( Dimension::WIDTH ), mCopyPastePopup.actor.GetRelayoutSize( Dimension::HEIGHT ), 0.0f ); + const Vector3 popupSize(mCopyPastePopup.actor.GetRelayoutSize(Dimension::WIDTH), mCopyPastePopup.actor.GetRelayoutSize(Dimension::HEIGHT), 0.0f); const Vector3 popupHalfSize = popupSize * 0.5f; - if( mPopupSetNewPosition ) + if(mPopupSetNewPosition) { - const HandleImpl& primaryHandle = mHandle[LEFT_SELECTION_HANDLE]; + const HandleImpl& primaryHandle = mHandle[LEFT_SELECTION_HANDLE]; const HandleImpl& secondaryHandle = mHandle[RIGHT_SELECTION_HANDLE]; - const HandleImpl& grabHandle = mHandle[GRAB_HANDLE]; + const HandleImpl& grabHandle = mHandle[GRAB_HANDLE]; - if( primaryHandle.active || secondaryHandle.active ) + if(primaryHandle.active || secondaryHandle.active) { - const float minHandleXPosition = std::min( primaryHandle.position.x, secondaryHandle.position.x ); - const float maxHandleXPosition = std::max( primaryHandle.position.x, secondaryHandle.position.x ); + const float minHandleXPosition = std::min(primaryHandle.position.x, secondaryHandle.position.x); + const float maxHandleXPosition = std::max(primaryHandle.position.x, secondaryHandle.position.x); - mCopyPastePopup.position.x = minHandleXPosition + ( ( maxHandleXPosition - minHandleXPosition ) * 0.5f ); + mCopyPastePopup.position.x = minHandleXPosition + ((maxHandleXPosition - minHandleXPosition) * 0.5f); - const float primaryY = -popupHalfSize.height + primaryHandle.position.y - ( primaryHandle.verticallyFlipped ? primaryHandle.size.height : POPUP_PADDING ); - const float secondaryY = -popupHalfSize.height + secondaryHandle.position.y - ( secondaryHandle.verticallyFlipped ? secondaryHandle.size.height : POPUP_PADDING ); + const float primaryY = -popupHalfSize.height + primaryHandle.position.y - (primaryHandle.verticallyFlipped ? primaryHandle.size.height : POPUP_PADDING); + const float secondaryY = -popupHalfSize.height + secondaryHandle.position.y - (secondaryHandle.verticallyFlipped ? secondaryHandle.size.height : POPUP_PADDING); - mCopyPastePopup.position.y = std::min( primaryY, secondaryY ); + mCopyPastePopup.position.y = std::min(primaryY, secondaryY); } - else if( grabHandle.active ) + else if(grabHandle.active) { mCopyPastePopup.position.x = grabHandle.position.x; - mCopyPastePopup.position.y = -popupHalfSize.height + grabHandle.position.y - ( grabHandle.verticallyFlipped ? grabHandle.size.height : POPUP_PADDING ); + mCopyPastePopup.position.y = -popupHalfSize.height + grabHandle.position.y - (grabHandle.verticallyFlipped ? grabHandle.size.height : POPUP_PADDING); } } // mPopupSetNewPosition // It may change the popup's position to fit within the decoration box. - ConstrainPopupPosition( popupHalfSize ); + ConstrainPopupPosition(popupHalfSize); - SetUpPopupPositionNotifications( popupHalfSize ); + SetUpPopupPositionNotifications(popupHalfSize); // Prevent pixel mis-alignment by rounding down. - mCopyPastePopup.position.x = floorf( mCopyPastePopup.position.x ); - mCopyPastePopup.position.y = floorf( mCopyPastePopup.position.y ); + mCopyPastePopup.position.x = floorf(mCopyPastePopup.position.x); + mCopyPastePopup.position.y = floorf(mCopyPastePopup.position.y); - mCopyPastePopup.actor.SetPosition( mCopyPastePopup.position ); + mCopyPastePopup.actor.SetProperty(Actor::Property::POSITION, mCopyPastePopup.position); mPopupSetNewPosition = false; } - void CreateCursor( Control& cursor, const Vector4& color ) + void CreateCursor(Control& cursor, const Vector4& color) { cursor = Control::New(); - cursor.SetBackgroundColor( color ); - cursor.SetParentOrigin( ParentOrigin::TOP_LEFT ); - cursor.SetAnchorPoint( AnchorPoint::TOP_LEFT ); + cursor.SetBackgroundColor(color); + cursor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT); + cursor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT); + cursor.SetProperty(Toolkit::DevelControl::Property::ACCESSIBILITY_HIDDEN, true); } // Add or Remove cursor(s) from parent void CreateCursors() { - if( mActiveCursor == ACTIVE_CURSOR_NONE ) + if(mActiveCursor == ACTIVE_CURSOR_NONE) { - if( mPrimaryCursor ) + if(mPrimaryCursor) { mPrimaryCursor.Unparent(); } - if( mSecondaryCursor ) + if(mSecondaryCursor) { mSecondaryCursor.Unparent(); } @@ -680,41 +653,41 @@ struct Decorator::Impl : public ConnectionTracker else { // Create Primary and or Secondary Cursor(s) if active and add to parent - if ( mActiveCursor == ACTIVE_CURSOR_PRIMARY || - mActiveCursor == ACTIVE_CURSOR_BOTH ) + if(mActiveCursor == ACTIVE_CURSOR_PRIMARY || + mActiveCursor == ACTIVE_CURSOR_BOTH) { - if ( !mPrimaryCursor ) + if(!mPrimaryCursor) { - CreateCursor( mPrimaryCursor, mCursor[PRIMARY_CURSOR].color ); + CreateCursor(mPrimaryCursor, mCursor[PRIMARY_CURSOR].color); #ifdef DECORATOR_DEBUG - mPrimaryCursor.SetName( "PrimaryCursorActor" ); + mPrimaryCursor.SetProperty(Dali::Actor::Property::NAME, "PrimaryCursorActor"); #endif } - if( !mPrimaryCursor.GetParent() ) + if(!mPrimaryCursor.GetParent()) { - mActiveLayer.Add( mPrimaryCursor ); + mCursorLayer.Add(mPrimaryCursor); } } - if ( mActiveCursor == ACTIVE_CURSOR_BOTH ) + if(mActiveCursor == ACTIVE_CURSOR_BOTH) { - if ( !mSecondaryCursor ) + if(!mSecondaryCursor) { - CreateCursor( mSecondaryCursor, mCursor[SECONDARY_CURSOR].color ); + CreateCursor(mSecondaryCursor, mCursor[SECONDARY_CURSOR].color); #ifdef DECORATOR_DEBUG - mSecondaryCursor.SetName( "SecondaryCursorActor" ); + mSecondaryCursor.SetProperty(Dali::Actor::Property::NAME, "SecondaryCursorActor"); #endif } - if( !mSecondaryCursor.GetParent() ) + if(!mSecondaryCursor.GetParent()) { - mActiveLayer.Add( mSecondaryCursor ); + mCursorLayer.Add(mSecondaryCursor); } } else { - if( mSecondaryCursor ) + if(mSecondaryCursor) { mSecondaryCursor.Unparent(); } @@ -724,16 +697,16 @@ struct Decorator::Impl : public ConnectionTracker bool OnCursorBlinkTimerTick() { - if( !mDelayCursorBlink ) + if(!mDelayCursorBlink) { // Cursor blinking - if ( mPrimaryCursor ) + if(mPrimaryCursor) { - mPrimaryCursor.SetVisible( mPrimaryCursorVisible && mCursorBlinkStatus ); + mPrimaryCursor.SetProperty(Actor::Property::VISIBLE, mPrimaryCursorVisible && mCursorBlinkStatus); } - if ( mSecondaryCursor ) + if(mSecondaryCursor) { - mSecondaryCursor.SetVisible( mSecondaryCursorVisible && mCursorBlinkStatus ); + mSecondaryCursor.SetProperty(Actor::Property::VISIBLE, mSecondaryCursorVisible && mCursorBlinkStatus); } mCursorBlinkStatus = !mCursorBlinkStatus; @@ -753,225 +726,249 @@ struct Decorator::Impl : public ConnectionTracker mTapDetector = TapGestureDetector::New(); // Will consume double tap gestures on handles. - mTapDetector.SetMaximumTapsRequired( 2u ); + mTapDetector.SetMaximumTapsRequired(2u); // Will consume long press gestures on handles. mLongPressDetector = LongPressGestureDetector::New(); // Detects pan gestures on handles. mPanDetector = PanGestureDetector::New(); - mPanDetector.DetectedSignal().Connect( this, &Decorator::Impl::OnPan ); + mPanDetector.DetectedSignal().Connect(this, &Decorator::Impl::OnPan); } - void CreateActiveLayer() + void CreateLayer(Actor& layer, DecorationType type) { - if( !mActiveLayer ) + if(!layer) { - mActiveLayer = Layer::New(); + layer = Actor::New(); #ifdef DECORATOR_DEBUG - mActiveLayer.SetName ( "ActiveLayerActor" ); + if(type == DecorationType::ACTIVE_LAYER) + { + layer.SetProperty(Actor::Property::NAME, "ActiveLayerActor"); + } + else if(type == DecorationType::CURSOR_LAYER) + { + layer.SetProperty(Actor::Property::NAME, "CursorLayerActor"); + } #endif + bool needsClipping = false; + if(type == DecorationType::CURSOR_LAYER) + { + needsClipping = true; + } - mActiveLayer.SetParentOrigin( ParentOrigin::CENTER ); - mActiveLayer.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS ); + layer.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER); + layer.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS); - // Add the active layer telling the controller it doesn't need clipping. - mController.AddDecoration( mActiveLayer, false ); + mController.AddDecoration(layer, type, needsClipping); } - mActiveLayer.RaiseToTop(); + layer.RaiseToTop(); } - void SetSelectionHandleMarkerSize( HandleImpl& handle ) + void SetSelectionHandleMarkerSize(HandleImpl& handle) { - if( handle.markerActor ) + if(handle.markerActor) { - handle.markerActor.SetSize( 0, handle.lineHeight ); + handle.markerActor.SetProperty(Actor::Property::SIZE, Vector2(0, handle.lineHeight)); } } void CreateGrabHandle() { HandleImpl& grabHandle = mHandle[GRAB_HANDLE]; - if( !grabHandle.actor ) + if(!grabHandle.actor) { - if( mHandleImages[GRAB_HANDLE][HANDLE_IMAGE_RELEASED] ) + if(mHandleImages[GRAB_HANDLE][HANDLE_IMAGE_RELEASED].size()) { - grabHandle.actor = ImageView::New( mHandleImages[GRAB_HANDLE][HANDLE_IMAGE_RELEASED] ); - GetImpl( grabHandle.actor).SetDepthIndex( DepthIndex::DECORATION ); - grabHandle.actor.SetAnchorPoint( AnchorPoint::TOP_CENTER ); + grabHandle.actor = ImageView::New(mHandleImages[GRAB_HANDLE][HANDLE_IMAGE_RELEASED]); + GetImpl(grabHandle.actor).SetDepthIndex(DepthIndex::DECORATION); + grabHandle.actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_CENTER); // Area that Grab handle responds to, larger than actual handle so easier to move #ifdef DECORATOR_DEBUG - grabHandle.actor.SetName( "GrabHandleActor" ); - if ( Dali::Internal::gLogFilter->IsEnabledFor( Debug::Verbose ) ) + grabHandle.actor.SetProperty(Dali::Actor::Property::NAME, "GrabHandleActor"); + if(Dali::Internal::gLogFilter->IsEnabledFor(Debug::Verbose)) { - grabHandle.grabArea = Control::New(); - Toolkit::Control control = Toolkit::Control::DownCast( grabHandle.grabArea ); - control.SetBackgroundColor( Vector4( 1.0f, 1.0f, 1.0f, 0.5f ) ); - grabHandle.grabArea.SetName( "GrabArea" ); + grabHandle.grabArea = Control::New(); + Toolkit::Control control = Toolkit::Control::DownCast(grabHandle.grabArea); + control.SetBackgroundColor(Vector4(1.0f, 1.0f, 1.0f, 0.5f)); + grabHandle.grabArea.SetProperty(Dali::Actor::Property::NAME, "GrabArea"); } else { grabHandle.grabArea = Actor::New(); - grabHandle.grabArea.SetName( "GrabArea" ); + grabHandle.grabArea.SetProperty(Dali::Actor::Property::NAME, "GrabArea"); } #else grabHandle.grabArea = Actor::New(); #endif - grabHandle.grabArea.SetParentOrigin( ParentOrigin::TOP_CENTER ); - grabHandle.grabArea.SetAnchorPoint( AnchorPoint::TOP_CENTER ); - 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.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_CENTER); + grabHandle.grabArea.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_CENTER); + grabHandle.grabArea.SetResizePolicy(ResizePolicy::SIZE_RELATIVE_TO_PARENT, Dimension::ALL_DIMENSIONS); + grabHandle.grabArea.SetProperty(Actor::Property::SIZE_MODE_FACTOR, DEFAULT_GRAB_HANDLE_RELATIVE_SIZE); + grabHandle.actor.Add(grabHandle.grabArea); + grabHandle.actor.SetProperty(Actor::Property::COLOR, mHandleColor); - grabHandle.grabArea.TouchSignal().Connect( this, &Decorator::Impl::OnGrabHandleTouched ); + grabHandle.grabArea.TouchedSignal().Connect(this, &Decorator::Impl::OnGrabHandleTouched); // The grab handle's actor is attached to the tap and long press detectors in order to consume these events. // Note that no callbacks are connected to any signal emitted by the tap and long press detectors. - mTapDetector.Attach( grabHandle.actor ); - mLongPressDetector.Attach( grabHandle.actor ); + mTapDetector.Attach(grabHandle.actor); + mLongPressDetector.Attach(grabHandle.actor); // The grab handle's area is attached to the pan detector. // The OnPan() method is connected to the signals emitted by the pan detector. - mPanDetector.Attach( grabHandle.grabArea ); + mPanDetector.Attach(grabHandle.grabArea); - mActiveLayer.Add( grabHandle.actor ); + mActiveLayer.Add(grabHandle.actor); } } - if( grabHandle.actor && !grabHandle.actor.GetParent() ) + if(grabHandle.actor && !grabHandle.actor.GetParent()) { - mActiveLayer.Add( grabHandle.actor ); + mActiveLayer.Add(grabHandle.actor); } } - void CreateHandleMarker( HandleImpl& handle, Image& image, HandleType handleType ) + void CreateHandleMarker(HandleImpl& handle, const std::string& image, HandleType handleType) { - if( image ) + if(image.size()) { - handle.markerActor = ImageView::New( image ); - handle.markerActor.SetColor( mHandleColor ); - handle.actor.Add( handle.markerActor ); + handle.markerActor = ImageView::New(image); + handle.markerActor.SetProperty(Actor::Property::COLOR, mHandleColor); + handle.actor.Add(handle.markerActor); - handle.markerActor.SetResizePolicy ( ResizePolicy::FIXED, Dimension::HEIGHT ); + handle.markerActor.SetResizePolicy(ResizePolicy::FIXED, Dimension::HEIGHT); - if( LEFT_SELECTION_HANDLE == handleType ) + if(LEFT_SELECTION_HANDLE == handleType) { - handle.markerActor.SetAnchorPoint( AnchorPoint::BOTTOM_RIGHT ); - handle.markerActor.SetParentOrigin( ParentOrigin::TOP_RIGHT ); + handle.markerActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::BOTTOM_RIGHT); + handle.markerActor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_RIGHT); } - else if( RIGHT_SELECTION_HANDLE == handleType ) + else if(RIGHT_SELECTION_HANDLE == handleType) { - handle.markerActor.SetAnchorPoint( AnchorPoint::BOTTOM_LEFT ); - handle.markerActor.SetParentOrigin( ParentOrigin::TOP_LEFT ); + handle.markerActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::BOTTOM_LEFT); + handle.markerActor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT); } } } void CreateSelectionHandles() { - HandleImpl& primary = mHandle[ LEFT_SELECTION_HANDLE ]; - if( !primary.actor ) + HandleImpl& primary = mHandle[LEFT_SELECTION_HANDLE]; + if(!primary.actor) { - if( mHandleImages[LEFT_SELECTION_HANDLE][HANDLE_IMAGE_RELEASED] ) + if(mHandleImages[LEFT_SELECTION_HANDLE][HANDLE_IMAGE_RELEASED].size()) { - primary.actor = ImageView::New( mHandleImages[LEFT_SELECTION_HANDLE][HANDLE_IMAGE_RELEASED] ); + primary.actor = ImageView::New(mHandleImages[LEFT_SELECTION_HANDLE][HANDLE_IMAGE_RELEASED]); #ifdef DECORATOR_DEBUG - primary.actor.SetName("SelectionHandleOne"); + primary.actor.SetProperty(Dali::Actor::Property::NAME, "SelectionHandleOne"); #endif - primary.actor.SetAnchorPoint( AnchorPoint::TOP_RIGHT ); // Change to BOTTOM_RIGHT if Look'n'Feel requires handle above text. - GetImpl( primary.actor ).SetDepthIndex( DepthIndex::DECORATION ); - primary.actor.SetColor( mHandleColor ); + primary.actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_RIGHT); // Change to BOTTOM_RIGHT if Look'n'Feel requires handle above text. + GetImpl(primary.actor).SetDepthIndex(DepthIndex::DECORATION); + primary.actor.SetProperty(Actor::Property::COLOR, mHandleColor); primary.grabArea = Actor::New(); // Area that Grab handle responds to, larger than actual handle so easier to move #ifdef DECORATOR_DEBUG - primary.grabArea.SetName("SelectionHandleOneGrabArea"); + primary.grabArea.SetProperty(Dali::Actor::Property::NAME, "SelectionHandleOneGrabArea"); #endif - primary.grabArea.SetResizePolicy( ResizePolicy::SIZE_RELATIVE_TO_PARENT, Dimension::ALL_DIMENSIONS ); - primary.grabArea.SetParentOrigin( ParentOrigin::TOP_CENTER ); - primary.grabArea.SetAnchorPoint( AnchorPoint::TOP_CENTER ); - primary.grabArea.SetSizeModeFactor( DEFAULT_SELECTION_HANDLE_RELATIVE_SIZE ); + primary.grabArea.SetResizePolicy(ResizePolicy::SIZE_RELATIVE_TO_PARENT, Dimension::ALL_DIMENSIONS); + primary.grabArea.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_CENTER); + primary.grabArea.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_CENTER); + primary.grabArea.SetProperty(Actor::Property::SIZE_MODE_FACTOR, DEFAULT_SELECTION_HANDLE_RELATIVE_SIZE); - primary.grabArea.TouchSignal().Connect( this, &Decorator::Impl::OnHandleOneTouched ); + primary.grabArea.TouchedSignal().Connect(this, &Decorator::Impl::OnHandleOneTouched); // The handle's actor is attached to the tap and long press detectors in order to consume these events. // Note that no callbacks are connected to any signal emitted by the tap and long press detectors. - mTapDetector.Attach( primary.actor ); - mLongPressDetector.Attach( primary.actor ); + mTapDetector.Attach(primary.actor); + mLongPressDetector.Attach(primary.actor); // The handle's area is attached to the pan detector. // The OnPan() method is connected to the signals emitted by the pan detector. - mPanDetector.Attach( primary.grabArea ); + mPanDetector.Attach(primary.grabArea); - primary.actor.Add( primary.grabArea ); + primary.actor.Add(primary.grabArea); - CreateHandleMarker( primary, mHandleImages[LEFT_SELECTION_HANDLE_MARKER][HANDLE_IMAGE_RELEASED], LEFT_SELECTION_HANDLE ); + CreateHandleMarker(primary, mHandleImages[LEFT_SELECTION_HANDLE_MARKER][HANDLE_IMAGE_RELEASED], LEFT_SELECTION_HANDLE); } } - if( primary.actor && !primary.actor.GetParent() ) + if(primary.actor && !primary.actor.GetParent()) { - mActiveLayer.Add( primary.actor ); + mActiveLayer.Add(primary.actor); } - HandleImpl& secondary = mHandle[ RIGHT_SELECTION_HANDLE ]; - if( !secondary.actor ) + HandleImpl& secondary = mHandle[RIGHT_SELECTION_HANDLE]; + if(!secondary.actor) { - if( mHandleImages[RIGHT_SELECTION_HANDLE][HANDLE_IMAGE_RELEASED] ) + if(mHandleImages[RIGHT_SELECTION_HANDLE][HANDLE_IMAGE_RELEASED].size()) { - secondary.actor = ImageView::New( mHandleImages[RIGHT_SELECTION_HANDLE][HANDLE_IMAGE_RELEASED] ); + secondary.actor = ImageView::New(mHandleImages[RIGHT_SELECTION_HANDLE][HANDLE_IMAGE_RELEASED]); #ifdef DECORATOR_DEBUG - secondary.actor.SetName("SelectionHandleTwo"); + secondary.actor.SetProperty(Dali::Actor::Property::NAME, "SelectionHandleTwo"); #endif - secondary.actor.SetAnchorPoint( AnchorPoint::TOP_LEFT ); // Change to BOTTOM_LEFT if Look'n'Feel requires handle above text. - GetImpl( secondary.actor ).SetDepthIndex( DepthIndex::DECORATION ); - secondary.actor.SetColor( mHandleColor ); + secondary.actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT); // Change to BOTTOM_LEFT if Look'n'Feel requires handle above text. + GetImpl(secondary.actor).SetDepthIndex(DepthIndex::DECORATION); + secondary.actor.SetProperty(Actor::Property::COLOR, mHandleColor); secondary.grabArea = Actor::New(); // Area that Grab handle responds to, larger than actual handle so easier to move #ifdef DECORATOR_DEBUG - secondary.grabArea.SetName("SelectionHandleTwoGrabArea"); + secondary.grabArea.SetProperty(Dali::Actor::Property::NAME, "SelectionHandleTwoGrabArea"); #endif - secondary.grabArea.SetResizePolicy( ResizePolicy::SIZE_RELATIVE_TO_PARENT, Dimension::ALL_DIMENSIONS ); - secondary.grabArea.SetParentOrigin( ParentOrigin::TOP_CENTER ); - secondary.grabArea.SetAnchorPoint( AnchorPoint::TOP_CENTER ); - secondary.grabArea.SetSizeModeFactor( DEFAULT_SELECTION_HANDLE_RELATIVE_SIZE ); + secondary.grabArea.SetResizePolicy(ResizePolicy::SIZE_RELATIVE_TO_PARENT, Dimension::ALL_DIMENSIONS); + secondary.grabArea.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_CENTER); + secondary.grabArea.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_CENTER); + secondary.grabArea.SetProperty(Actor::Property::SIZE_MODE_FACTOR, DEFAULT_SELECTION_HANDLE_RELATIVE_SIZE); - secondary.grabArea.TouchSignal().Connect( this, &Decorator::Impl::OnHandleTwoTouched ); + secondary.grabArea.TouchedSignal().Connect(this, &Decorator::Impl::OnHandleTwoTouched); // The handle's actor is attached to the tap and long press detectors in order to consume these events. // Note that no callbacks are connected to any signal emitted by the tap and long press detectors. - mTapDetector.Attach( secondary.actor ); - mLongPressDetector.Attach( secondary.actor ); + mTapDetector.Attach(secondary.actor); + mLongPressDetector.Attach(secondary.actor); // The handle's area is attached to the pan detector. // The OnPan() method is connected to the signals emitted by the pan detector. - mPanDetector.Attach( secondary.grabArea ); + mPanDetector.Attach(secondary.grabArea); - secondary.actor.Add( secondary.grabArea ); + secondary.actor.Add(secondary.grabArea); - CreateHandleMarker( secondary, mHandleImages[RIGHT_SELECTION_HANDLE_MARKER][HANDLE_IMAGE_RELEASED], RIGHT_SELECTION_HANDLE ); + CreateHandleMarker(secondary, mHandleImages[RIGHT_SELECTION_HANDLE_MARKER][HANDLE_IMAGE_RELEASED], RIGHT_SELECTION_HANDLE); } } - if( secondary.actor && !secondary.actor.GetParent() ) + if(secondary.actor && !secondary.actor.GetParent()) + { + mActiveLayer.Add(secondary.actor); + } + } + + void CreateSelectionPopup() + { + if(!mCopyPastePopup.actor) { - mActiveLayer.Add( secondary.actor ); + mCopyPastePopup.actor = TextSelectionPopup::New(&mTextSelectionPopupCallbackInterface); + #ifdef DECORATOR_DEBUG + mCopyPastePopup.actor.SetProperty(Dali::Actor::Property::NAME, "mCopyPastePopup"); + #endif + mCopyPastePopup.actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER); + mCopyPastePopup.actor.OnRelayoutSignal().Connect(this, &Decorator::Impl::SetPopupPosition); // Position popup after size negotiation } } - void CalculateHandleWorldCoordinates( HandleImpl& handle, Vector2& position ) + void CalculateHandleWorldCoordinates(HandleImpl& handle, Vector2& position) { // Gets the world position of the active layer. The active layer is where the handles are added. - const Vector3 parentWorldPosition = mActiveLayer.GetCurrentWorldPosition(); + const Vector3 parentWorldPosition = mActiveLayer.GetCurrentProperty(Actor::Property::WORLD_POSITION); // The grab handle position in world coords. // The active layer's world position is the center of the active layer. The origin of the // coord system of the handles is the top left of the active layer. - position.x = parentWorldPosition.x - 0.5f * mControlSize.width + handle.position.x + ( mSmoothHandlePanEnabled ? handle.grabDisplacementX : 0.f ); - position.y = parentWorldPosition.y - 0.5f * mControlSize.height + handle.position.y + ( mSmoothHandlePanEnabled ? handle.grabDisplacementY : 0.f ); + position.x = parentWorldPosition.x - 0.5f * mControlSize.width + handle.position.x + (mSmoothHandlePanEnabled ? handle.grabDisplacementX : 0.f); + position.y = parentWorldPosition.y - 0.5f * mControlSize.height + handle.position.y + (mSmoothHandlePanEnabled ? handle.grabDisplacementY : 0.f); } void SetGrabHandlePosition() @@ -980,20 +977,20 @@ struct Decorator::Impl : public ConnectionTracker HandleImpl& grabHandle = mHandle[GRAB_HANDLE]; // Transforms the handle position into world coordinates. - // @note This is not the same value as grabHandle.actor.GetCurrentWorldPosition() + // @note This is not the same value as grabHandle.actor.GetCurrentProperty< Vector3 >( Actor::Property::WORLD_POSITION ) // as it's transforming the handle's position set by the text-controller and not - // the final position set to the actor. Another difference is the GetCurrentWorldPosition() + // the final position set to the actor. Another difference is the.GetCurrentProperty< Vector3 >( Actor::Property::WORLD_POSITION ) // retrieves the position of the center of the actor but the handle's position set // by the text controller is not the center of the actor. Vector2 grabHandleWorldPosition; - CalculateHandleWorldCoordinates( grabHandle, grabHandleWorldPosition ); + CalculateHandleWorldCoordinates(grabHandle, grabHandleWorldPosition); // Check if the grab handle exceeds the boundaries of the decoration box. // At the moment only the height is checked for the grab handle. - grabHandle.verticallyFlipped = ( grabHandle.verticallyFlippedPreferred && - ( ( grabHandleWorldPosition.y - grabHandle.size.height ) > mBoundingBox.y ) ) || - ( grabHandleWorldPosition.y + grabHandle.lineHeight + grabHandle.size.height > mBoundingBox.w ); + grabHandle.verticallyFlipped = (grabHandle.verticallyFlippedPreferred && + ((grabHandleWorldPosition.y - grabHandle.size.height) > mBoundingBox.y)) || + (grabHandleWorldPosition.y + grabHandle.lineHeight + grabHandle.size.height > mBoundingBox.w); // The grab handle 'y' position in local coords. // If the grab handle exceeds the bottom of the decoration box, @@ -1001,14 +998,10 @@ struct Decorator::Impl : public ConnectionTracker // The SetGrabHandleImage() method will change the orientation. const float yLocalPosition = grabHandle.verticallyFlipped ? grabHandle.position.y : grabHandle.position.y + grabHandle.lineHeight; - if( grabHandle.actor ) - { - grabHandle.actor.SetPosition( grabHandle.position.x + floor( 0.5f * mCursorWidth ) + ( mSmoothHandlePanEnabled ? grabHandle.grabDisplacementX : 0.f ), - yLocalPosition + ( mSmoothHandlePanEnabled ? grabHandle.grabDisplacementY : 0.f ) ); - } + ApplyDisplacement(grabHandle, yLocalPosition); } - void SetSelectionHandlePosition( HandleType type ) + void SetSelectionHandlePosition(HandleType type) { const bool isPrimaryHandle = LEFT_SELECTION_HANDLE == type; @@ -1016,20 +1009,20 @@ struct Decorator::Impl : public ConnectionTracker HandleImpl& handle = mHandle[type]; // Transforms the handle position into world coordinates. - // @note This is not the same value as handle.actor.GetCurrentWorldPosition() + // @note This is not the same value as handle.actor.GetCurrentProperty< Vector3 >( Actor::Property::WORLD_POSITION ) // as it's transforming the handle's position set by the text-controller and not - // the final position set to the actor. Another difference is the GetCurrentWorldPosition() + // the final position set to the actor. Another difference is the.GetCurrentProperty< Vector3 >( Actor::Property::WORLD_POSITION ) // retrieves the position of the center of the actor but the handle's position set // by the text controller is not the center of the actor. Vector2 handleWorldPosition; - CalculateHandleWorldCoordinates( handle, handleWorldPosition ); + CalculateHandleWorldCoordinates(handle, handleWorldPosition); // Whether to flip the handle (horizontally). bool flipHandle = isPrimaryHandle ? mFlipLeftSelectionHandleDirection : mFlipRightSelectionHandleDirection; // Whether to flip the handles if they are crossed. bool crossFlip = false; - if( mFlipSelectionHandlesOnCross || !mIsHandlePanning ) + if(mFlipSelectionHandlesOnCross || !mIsHandlePanning) { crossFlip = mIsHandleCurrentlyCrossed; } @@ -1038,14 +1031,14 @@ struct Decorator::Impl : public ConnectionTracker const bool isHandlePreviouslyCrossed = mFlipSelectionHandlesOnCross ? false : mIsHandlePreviouslyCrossed; // Does not flip if both conditions are true (double flip) - flipHandle = flipHandle != ( crossFlip || isHandlePreviouslyCrossed ); + flipHandle = flipHandle != (crossFlip || isHandlePreviouslyCrossed); // Will flip the handles vertically if the user prefers it. bool verticallyFlippedPreferred = handle.verticallyFlippedPreferred; - if( crossFlip || isHandlePreviouslyCrossed ) + if(crossFlip || isHandlePreviouslyCrossed) { - if( isPrimaryHandle ) + if(isPrimaryHandle) { verticallyFlippedPreferred = mHandle[RIGHT_SELECTION_HANDLE].verticallyFlippedPreferred; } @@ -1056,37 +1049,37 @@ struct Decorator::Impl : public ConnectionTracker } // Check if the selection handle exceeds the boundaries of the decoration box. - const bool exceedsLeftEdge = ( isPrimaryHandle ? !flipHandle : flipHandle ) && ( handleWorldPosition.x - handle.size.width < mBoundingBox.x ); - const bool exceedsRightEdge = ( isPrimaryHandle ? flipHandle : !flipHandle ) && ( handleWorldPosition.x + handle.size.width > mBoundingBox.z ); + const bool exceedsLeftEdge = (isPrimaryHandle ? !flipHandle : flipHandle) && (handleWorldPosition.x - handle.size.width < mBoundingBox.x); + const bool exceedsRightEdge = (isPrimaryHandle ? flipHandle : !flipHandle) && (handleWorldPosition.x + handle.size.width > mBoundingBox.z); // Does not flip if both conditions are true (double flip) - flipHandle = flipHandle != ( exceedsLeftEdge || exceedsRightEdge ); + flipHandle = flipHandle != (exceedsLeftEdge || exceedsRightEdge); - if( flipHandle ) + if(flipHandle) { - if( handle.actor && !handle.horizontallyFlipped ) + if(handle.actor && !handle.horizontallyFlipped) { // Change the anchor point to flip the image. - handle.actor.SetAnchorPoint( isPrimaryHandle ? AnchorPoint::TOP_LEFT : AnchorPoint::TOP_RIGHT ); + handle.actor.SetProperty(Actor::Property::ANCHOR_POINT, isPrimaryHandle ? AnchorPoint::TOP_LEFT : AnchorPoint::TOP_RIGHT); handle.horizontallyFlipped = true; } } else { - if( handle.actor && handle.horizontallyFlipped ) + if(handle.actor && handle.horizontallyFlipped) { // Reset the anchor point. - handle.actor.SetAnchorPoint( isPrimaryHandle ? AnchorPoint::TOP_RIGHT : AnchorPoint::TOP_LEFT ); + handle.actor.SetProperty(Actor::Property::ANCHOR_POINT, isPrimaryHandle ? AnchorPoint::TOP_RIGHT : AnchorPoint::TOP_LEFT); handle.horizontallyFlipped = false; } } // Whether to flip the handle vertically. - handle.verticallyFlipped = ( verticallyFlippedPreferred && - ( ( handleWorldPosition.y - handle.size.height ) > mBoundingBox.y ) ) || - ( handleWorldPosition.y + handle.lineHeight + handle.size.height > mBoundingBox.w ); + handle.verticallyFlipped = (verticallyFlippedPreferred && + ((handleWorldPosition.y - handle.size.height) > mBoundingBox.y)) || + (handleWorldPosition.y + handle.lineHeight + handle.size.height > mBoundingBox.w); // The primary selection handle 'y' position in local coords. // If the handle exceeds the bottom of the decoration box, @@ -1094,105 +1087,138 @@ struct Decorator::Impl : public ConnectionTracker // The SetHandleImage() method will change the orientation. const float yLocalPosition = handle.verticallyFlipped ? handle.position.y : handle.position.y + handle.lineHeight; + ApplyDisplacement(handle, yLocalPosition); + } + + void ApplyDisplacement(HandleImpl& handle, float yLocalPosition) + { if( handle.actor ) { - handle.actor.SetPosition( handle.position.x + ( mSmoothHandlePanEnabled ? handle.grabDisplacementX : 0.f ), - yLocalPosition + ( mSmoothHandlePanEnabled ? handle.grabDisplacementY : 0.f ) ); + float adjustedDisplacementX = 0.0f; + float adjustedDisplacementY = 0.0f; + if (mSmoothHandlePanEnabled) + { + adjustedDisplacementX = CalculateAdjustedDisplacement(handle.position.x, handle.grabDisplacementX, mControlSize.x); + adjustedDisplacementY = CalculateAdjustedDisplacement(handle.position.y, handle.grabDisplacementY, (mControlSize.y - handle.lineHeight)); + } + handle.actor.SetProperty(Actor::Property::POSITION, + Vector2(handle.position.x + floor(0.5f * mCursorWidth) + adjustedDisplacementX, + yLocalPosition + adjustedDisplacementY)); + } + } + + float CalculateAdjustedDisplacement(float position, float displacement, float edge) + { + //Apply the displacement (on the X-axis & the Y-axis) + //as long as it does not exceed the control's edge. + float adjustedDisplacement = 0.0f; + if(position + displacement < 0.0f) + { + // -position to cancel it out and relocate to 0. + adjustedDisplacement = -position; + } + else if(position + displacement > edge) + { + // move in a displacement which is sufficient to reach the edge. + adjustedDisplacement = edge - position; + } + else + { + // move normally in the displacement. + adjustedDisplacement = displacement; } + return adjustedDisplacement; } - void SetHandleImage( HandleType type ) + void SetHandleImage(HandleType type) { HandleImpl& handle = mHandle[type]; HandleType markerType = HANDLE_TYPE_COUNT; // If the selection handle is flipped it chooses the image of the other selection handle. Does nothing for the grab handle. - if( LEFT_SELECTION_HANDLE == type ) + if(LEFT_SELECTION_HANDLE == type) { - type = handle.horizontallyFlipped ? RIGHT_SELECTION_HANDLE : LEFT_SELECTION_HANDLE; + type = handle.horizontallyFlipped ? RIGHT_SELECTION_HANDLE : LEFT_SELECTION_HANDLE; markerType = handle.horizontallyFlipped ? RIGHT_SELECTION_HANDLE_MARKER : LEFT_SELECTION_HANDLE_MARKER; } - else if( RIGHT_SELECTION_HANDLE == type ) + else if(RIGHT_SELECTION_HANDLE == type) { - type = handle.horizontallyFlipped ? LEFT_SELECTION_HANDLE : RIGHT_SELECTION_HANDLE; + type = handle.horizontallyFlipped ? LEFT_SELECTION_HANDLE : RIGHT_SELECTION_HANDLE; markerType = handle.horizontallyFlipped ? LEFT_SELECTION_HANDLE_MARKER : RIGHT_SELECTION_HANDLE_MARKER; } // Chooses between the released or pressed image. It checks whether the pressed image exists. - if( handle.actor ) + if(handle.actor) { - const HandleImageType imageType = ( handle.pressed ? ( mHandleImages[type][HANDLE_IMAGE_PRESSED] ? HANDLE_IMAGE_PRESSED : HANDLE_IMAGE_RELEASED ) : HANDLE_IMAGE_RELEASED ); + const HandleImageType imageType = (handle.pressed ? (mHandleImages[type][HANDLE_IMAGE_PRESSED].size() ? HANDLE_IMAGE_PRESSED : HANDLE_IMAGE_RELEASED) : HANDLE_IMAGE_RELEASED); - handle.actor.SetImage( mHandleImages[type][imageType] ); + handle.actor.SetImage(mHandleImages[type][imageType]); } - if( HANDLE_TYPE_COUNT != markerType ) + if(HANDLE_TYPE_COUNT != markerType) { - if( handle.markerActor ) + if(handle.markerActor) { - const HandleImageType markerImageType = ( handle.pressed ? ( mHandleImages[markerType][HANDLE_IMAGE_PRESSED] ? HANDLE_IMAGE_PRESSED : HANDLE_IMAGE_RELEASED ) : HANDLE_IMAGE_RELEASED ); - handle.markerActor.SetImage( mHandleImages[markerType][markerImageType] ); + const HandleImageType markerImageType = (handle.pressed ? (mHandleImages[markerType][HANDLE_IMAGE_PRESSED].size() ? HANDLE_IMAGE_PRESSED : HANDLE_IMAGE_RELEASED) : HANDLE_IMAGE_RELEASED); + handle.markerActor.SetImage(mHandleImages[markerType][markerImageType]); } } // Whether to flip the handle vertically. - if( handle.actor ) + if(handle.actor) { - handle.actor.SetOrientation( handle.verticallyFlipped ? ANGLE_180 : ANGLE_0, Vector3::XAXIS ); + handle.actor.SetProperty(Actor::Property::ORIENTATION, Quaternion(handle.verticallyFlipped ? ANGLE_180 : ANGLE_0, Vector3::XAXIS)); } } void CreateHighlight() { - if( !mHighlightActor ) + if(!mHighlightActor) { mHighlightActor = Actor::New(); -#ifdef DECORATOR_DEBUG - mHighlightActor.SetName( "HighlightActor" ); -#endif - mHighlightActor.SetParentOrigin( ParentOrigin::TOP_LEFT ); - mHighlightActor.SetAnchorPoint( AnchorPoint::TOP_LEFT ); - mHighlightActor.SetColor( mHighlightColor ); - mHighlightActor.SetColorMode( USE_OWN_COLOR ); + mHighlightActor.SetProperty(Dali::Actor::Property::NAME, "HighlightActor"); + mHighlightActor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT); + mHighlightActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT); + mHighlightActor.SetProperty(Actor::Property::COLOR, mHighlightColor); + mHighlightActor.SetProperty(Actor::Property::COLOR_MODE, USE_OWN_COLOR); } // Add the highlight box telling the controller it needs clipping. - mController.AddDecoration( mHighlightActor, true ); + mController.AddDecoration(mHighlightActor, DecorationType::NONE_LAYER, true); } void UpdateHighlight() { - if ( mHighlightActor ) + if(mHighlightActor) { // Sets the position of the highlight actor inside the decorator. - mHighlightActor.SetPosition( mHighlightPosition.x + mHighlightOutlineOffset, - mHighlightPosition.y + mHighlightOutlineOffset ); + mHighlightActor.SetProperty(Actor::Property::POSITION, Vector2(mHighlightPosition.x + mHighlightOutlineOffset, mHighlightPosition.y + mHighlightOutlineOffset)); const unsigned int numberOfQuads = mHighlightQuadList.Count(); - if( 0u != numberOfQuads ) + if(0u != numberOfQuads) { // Set the size of the highlighted text to the actor. - mHighlightActor.SetSize( mHighlightSize ); + mHighlightActor.SetProperty(Actor::Property::SIZE, mHighlightSize); // Used to translate the vertices given in decorator's coords to the mHighlightActor's local coords. const float offsetX = mHighlightPosition.x + 0.5f * mHighlightSize.width; const float offsetY = mHighlightPosition.y + 0.5f * mHighlightSize.height; - Vector vertices; + Vector vertices; Vector indices; - vertices.Reserve( 4u * numberOfQuads ); - indices.Reserve( 6u * numberOfQuads ); + vertices.Reserve(4u * numberOfQuads); + indices.Reserve(6u * numberOfQuads); // Index to the vertex. unsigned int v = 0u; // Traverse all quads. - for( Vector::ConstIterator it = mHighlightQuadList.Begin(), - endIt = mHighlightQuadList.End(); - it != endIt; - ++it, v += 4u ) + for(Vector::ConstIterator it = mHighlightQuadList.Begin(), + endIt = mHighlightQuadList.End(); + it != endIt; + ++it, v += 4u) { const Vector4& quad = *it; @@ -1201,67 +1227,68 @@ struct Decorator::Impl : public ConnectionTracker // top-left (v+0) vertex.x = quad.x - offsetX; vertex.y = quad.y - offsetY; - vertices.PushBack( vertex ); + vertices.PushBack(vertex); // top-right (v+1) vertex.x = quad.z - offsetX; vertex.y = quad.y - offsetY; - vertices.PushBack( vertex ); + vertices.PushBack(vertex); // bottom-left (v+2) vertex.x = quad.x - offsetX; vertex.y = quad.w - offsetY; - vertices.PushBack( vertex ); + vertices.PushBack(vertex); // bottom-right (v+3) vertex.x = quad.z - offsetX; vertex.y = quad.w - offsetY; - vertices.PushBack( vertex ); + vertices.PushBack(vertex); // triangle A (3, 1, 0) - indices.PushBack( v + 3 ); - indices.PushBack( v + 1 ); - indices.PushBack( v ); + 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 ); + indices.PushBack(v); + indices.PushBack(v + 2); + indices.PushBack(v + 3); } - if( ! mQuadVertices ) + if(!mQuadVertices) { - mQuadVertices = PropertyBuffer::New( mQuadVertexFormat ); + mQuadVertices = VertexBuffer::New(mQuadVertexFormat); } - mQuadVertices.SetData( &vertices[ 0 ], vertices.Size() ); + mQuadVertices.SetData(&vertices[0], vertices.Size()); - if( !mQuadGeometry ) + if(!mQuadGeometry) { mQuadGeometry = Geometry::New(); - mQuadGeometry.AddVertexBuffer( mQuadVertices ); + mQuadGeometry.AddVertexBuffer(mQuadVertices); } - mQuadGeometry.SetIndexBuffer( &indices[ 0 ], indices.Size() ); + mQuadGeometry.SetIndexBuffer(&indices[0], indices.Size()); - if( !mHighlightRenderer ) + if(!mHighlightRenderer) { - mHighlightRenderer = Dali::Renderer::New( mQuadGeometry, mHighlightShader ); - mHighlightActor.AddRenderer( mHighlightRenderer ); + mHighlightRenderer = Dali::Renderer::New(mQuadGeometry, mHighlightShader); + mHighlightActor.AddRenderer(mHighlightRenderer); } } mHighlightQuadList.Clear(); - if( mHighlightRenderer ) + if(mHighlightRenderer) { - mHighlightRenderer.SetProperty( Renderer::Property::DEPTH_INDEX, mTextDepth - 2 ); // text is rendered at mTextDepth and text's shadow at mTextDepth -1u. + mHighlightRenderer.SetProperty(Renderer::Property::DEPTH_INDEX, mTextDepth - 2); // text is rendered at mTextDepth and text's shadow at mTextDepth -1u. } } } - void DoPan( HandleImpl& handle, HandleType type, const PanGesture& gesture ) + void DoPan(HandleImpl& handle, HandleType type, const PanGesture& gesture) { - if( Gesture::Started == gesture.state ) + GestureState state = gesture.GetState(); + if(GestureState::STARTED == state) { handle.grabDisplacementX = handle.grabDisplacementY = 0.f; @@ -1269,42 +1296,43 @@ struct Decorator::Impl : public ConnectionTracker handle.globalPosition.y = handle.position.y; } - handle.grabDisplacementX += gesture.displacement.x; - handle.grabDisplacementY += ( handle.verticallyFlipped ? -gesture.displacement.y : gesture.displacement.y ); + const Vector2& displacement = gesture.GetDisplacement(); + handle.grabDisplacementX += displacement.x; + handle.grabDisplacementY += (handle.verticallyFlipped ? -displacement.y : displacement.y); - const float x = handle.globalPosition.x + handle.grabDisplacementX; - const float y = handle.globalPosition.y + handle.grabDisplacementY + 0.5f * handle.lineHeight; - const float yVerticallyFlippedCorrected = y - ( handle.verticallyFlippedOnTouch ? handle.lineHeight : 0.f ); + const float x = handle.globalPosition.x + handle.grabDisplacementX; + const float y = handle.globalPosition.y + handle.grabDisplacementY + 0.5f * handle.lineHeight; + const float yVerticallyFlippedCorrected = y - (handle.verticallyFlippedOnTouch ? handle.lineHeight : 0.f); - if( ( Gesture::Started == gesture.state ) || - ( Gesture::Continuing == gesture.state ) ) + if((GestureState::STARTED == state) || + (GestureState::CONTINUING == state)) { Vector2 targetSize; - mController.GetTargetSize( targetSize ); + mController.GetTargetSize(targetSize); - if( mHorizontalScrollingEnabled && - ( x < mScrollThreshold ) ) + if(mHorizontalScrollingEnabled && + (x < mScrollThreshold)) { mScrollDirection = SCROLL_RIGHT; mHandleScrolling = type; StartScrollTimer(); } - else if( mHorizontalScrollingEnabled && - ( x > targetSize.width - mScrollThreshold ) ) + else if(mHorizontalScrollingEnabled && + (x > targetSize.width - mScrollThreshold)) { mScrollDirection = SCROLL_LEFT; mHandleScrolling = type; StartScrollTimer(); } - else if( mVerticalScrollingEnabled && - ( yVerticallyFlippedCorrected < mScrollThreshold ) ) + else if(mVerticalScrollingEnabled && + (yVerticallyFlippedCorrected < mScrollThreshold)) { mScrollDirection = SCROLL_TOP; mHandleScrolling = type; StartScrollTimer(); } - else if( mVerticalScrollingEnabled && - ( yVerticallyFlippedCorrected + handle.lineHeight > targetSize.height - mScrollThreshold ) ) + else if(mVerticalScrollingEnabled && + (yVerticallyFlippedCorrected + handle.lineHeight > targetSize.height - mScrollThreshold)) { mScrollDirection = SCROLL_BOTTOM; mHandleScrolling = type; @@ -1314,30 +1342,30 @@ struct Decorator::Impl : public ConnectionTracker { mHandleScrolling = HANDLE_TYPE_COUNT; StopScrollTimer(); - mController.DecorationEvent( type, HANDLE_PRESSED, x, y ); + mController.DecorationEvent(type, HANDLE_PRESSED, x, y); } mIsHandlePanning = true; } - else if( ( Gesture::Finished == gesture.state ) || - ( Gesture::Cancelled == gesture.state ) ) + else if((GestureState::FINISHED == state) || + (GestureState::CANCELLED == state)) { - if( mScrollTimer && - ( mScrollTimer.IsRunning() || mNotifyEndOfScroll ) ) + if(mScrollTimer && + (mScrollTimer.IsRunning() || mNotifyEndOfScroll)) { mNotifyEndOfScroll = false; - mHandleScrolling = HANDLE_TYPE_COUNT; + mHandleScrolling = HANDLE_TYPE_COUNT; StopScrollTimer(); - mController.DecorationEvent( type, HANDLE_STOP_SCROLLING, x, y ); + mController.DecorationEvent(type, HANDLE_STOP_SCROLLING, x, y); } else { - mController.DecorationEvent( type, HANDLE_RELEASED, x, y ); + mController.DecorationEvent(type, HANDLE_RELEASED, x, y); } - if( handle.actor ) + if(handle.actor) { - handle.actor.SetImage( mHandleImages[type][HANDLE_IMAGE_RELEASED] ); + handle.actor.SetImage(mHandleImages[type][HANDLE_IMAGE_RELEASED]); } handle.pressed = false; @@ -1345,146 +1373,143 @@ struct Decorator::Impl : public ConnectionTracker } } - void OnPan( Actor actor, const PanGesture& gesture ) + void OnPan(Actor actor, const PanGesture& gesture) { - HandleImpl& grabHandle = mHandle[GRAB_HANDLE]; - HandleImpl& primarySelectionHandle = mHandle[LEFT_SELECTION_HANDLE]; + HandleImpl& grabHandle = mHandle[GRAB_HANDLE]; + HandleImpl& primarySelectionHandle = mHandle[LEFT_SELECTION_HANDLE]; HandleImpl& secondarySelectionHandle = mHandle[RIGHT_SELECTION_HANDLE]; - if( actor == grabHandle.grabArea ) + if(actor == grabHandle.grabArea) { - DoPan( grabHandle, GRAB_HANDLE, gesture ); + DoPan(grabHandle, GRAB_HANDLE, gesture); } - else if( actor == primarySelectionHandle.grabArea ) + else if(actor == primarySelectionHandle.grabArea) { - DoPan( primarySelectionHandle, LEFT_SELECTION_HANDLE, gesture ); + DoPan(primarySelectionHandle, LEFT_SELECTION_HANDLE, gesture); } - else if( actor == secondarySelectionHandle.grabArea ) + else if(actor == secondarySelectionHandle.grabArea) { - DoPan( secondarySelectionHandle, RIGHT_SELECTION_HANDLE, gesture ); + DoPan(secondarySelectionHandle, RIGHT_SELECTION_HANDLE, gesture); } } - bool OnGrabHandleTouched( Actor actor, const TouchData& touch ) + bool OnGrabHandleTouched(Actor actor, const TouchEvent& touch) { HandleImpl& grabHandle = mHandle[GRAB_HANDLE]; // Switch between pressed/release grab-handle images - if( touch.GetPointCount() > 0 && - grabHandle.actor ) + if(touch.GetPointCount() > 0 && + grabHandle.actor) { - const PointState::Type state = touch.GetState( 0 ); + const PointState::Type state = touch.GetState(0); - if( PointState::DOWN == state ) + if(PointState::DOWN == state) { grabHandle.pressed = true; } - else if( ( PointState::UP == state ) || - ( PointState::INTERRUPTED == state ) ) + else if((PointState::UP == state) || + (PointState::INTERRUPTED == state)) { grabHandle.pressed = false; } - SetHandleImage( GRAB_HANDLE ); + SetHandleImage(GRAB_HANDLE); } - // Consume to avoid pop-ups accidentally closing, when handle is outside of pop-up area - return true; + return false; } - bool OnHandleOneTouched( Actor actor, const TouchData& touch ) + bool OnHandleOneTouched(Actor actor, const TouchEvent& touch) { HandleImpl& primarySelectionHandle = mHandle[LEFT_SELECTION_HANDLE]; // Switch between pressed/release selection handle images - if( touch.GetPointCount() > 0 && - primarySelectionHandle.actor ) + if(touch.GetPointCount() > 0 && + primarySelectionHandle.actor) { - const PointState::Type state = touch.GetState( 0 ); + const PointState::Type state = touch.GetState(0); - if( PointState::DOWN == state ) + if(PointState::DOWN == state) { - primarySelectionHandle.pressed = true; + primarySelectionHandle.pressed = true; primarySelectionHandle.verticallyFlippedOnTouch = primarySelectionHandle.verticallyFlipped; } - else if( ( PointState::UP == state ) || - ( PointState::INTERRUPTED == state ) ) + else if((PointState::UP == state) || + (PointState::INTERRUPTED == state)) { primarySelectionHandle.pressed = false; - mIsHandlePreviouslyCrossed = mIsHandleCurrentlyCrossed; - mIsHandlePanning = false; - mHandleReleased = LEFT_SELECTION_HANDLE; + mIsHandlePreviouslyCrossed = mIsHandleCurrentlyCrossed; + mIsHandlePanning = false; + mHandleReleased = LEFT_SELECTION_HANDLE; } - SetHandleImage( LEFT_SELECTION_HANDLE ); + SetHandleImage(LEFT_SELECTION_HANDLE); } - // Consume to avoid pop-ups accidentally closing, when handle is outside of pop-up area - return true; + return false; } - bool OnHandleTwoTouched( Actor actor, const TouchData& touch ) + bool OnHandleTwoTouched(Actor actor, const TouchEvent& touch) { HandleImpl& secondarySelectionHandle = mHandle[RIGHT_SELECTION_HANDLE]; // Switch between pressed/release selection handle images - if( touch.GetPointCount() > 0 && - secondarySelectionHandle.actor ) + if(touch.GetPointCount() > 0 && + secondarySelectionHandle.actor) { - const PointState::Type state = touch.GetState( 0 ); + const PointState::Type state = touch.GetState(0); - if( PointState::DOWN == state ) + if(PointState::DOWN == state) { - secondarySelectionHandle.pressed = true; + secondarySelectionHandle.pressed = true; secondarySelectionHandle.verticallyFlippedOnTouch = secondarySelectionHandle.verticallyFlipped; } - else if( ( PointState::UP == state ) || - ( PointState::INTERRUPTED == state ) ) + else if((PointState::UP == state) || + (PointState::INTERRUPTED == state)) { secondarySelectionHandle.pressed = false; - mIsHandlePreviouslyCrossed = mIsHandleCurrentlyCrossed; - mIsHandlePanning = false; - mHandleReleased = RIGHT_SELECTION_HANDLE; + mIsHandlePreviouslyCrossed = mIsHandleCurrentlyCrossed; + mIsHandlePanning = false; + mHandleReleased = RIGHT_SELECTION_HANDLE; } - SetHandleImage( RIGHT_SELECTION_HANDLE ); + SetHandleImage(RIGHT_SELECTION_HANDLE); } - // Consume to avoid pop-ups accidentally closing, when handle is outside of pop-up area - return true; + return false; } - void HandleResetPosition( PropertyNotification& source ) + void HandleResetPosition(PropertyNotification& source) { const HandleImpl& grabHandle = mHandle[GRAB_HANDLE]; - if( grabHandle.active ) + if(grabHandle.active) { // Sets the grab handle position and calculates if it needs to be vertically flipped if it exceeds the boundary box. SetGrabHandlePosition(); // Sets the grab handle image according if it's pressed, flipped, etc. - SetHandleImage( GRAB_HANDLE ); + SetHandleImage(GRAB_HANDLE); } else { // Sets the primary selection handle position and calculates if it needs to be vertically flipped if it exceeds the boundary box. - SetSelectionHandlePosition( LEFT_SELECTION_HANDLE ); + SetSelectionHandlePosition(LEFT_SELECTION_HANDLE); // Sets the primary handle image according if it's pressed, flipped, etc. - SetHandleImage( LEFT_SELECTION_HANDLE ); + SetHandleImage(LEFT_SELECTION_HANDLE); // Sets the secondary selection handle position and calculates if it needs to be vertically flipped if it exceeds the boundary box. - SetSelectionHandlePosition( RIGHT_SELECTION_HANDLE ); + SetSelectionHandlePosition(RIGHT_SELECTION_HANDLE); // Sets the secondary handle image according if it's pressed, flipped, etc. - SetHandleImage( RIGHT_SELECTION_HANDLE ); + SetHandleImage(RIGHT_SELECTION_HANDLE); } } void SetupActiveLayerPropertyNotifications() { - if( !mActiveLayer ) + if(!mActiveLayer) { return; } @@ -1492,25 +1517,25 @@ struct Decorator::Impl : public ConnectionTracker // Vertical notifications. // Disconnect any previous connected callback. - if( mHandleVerticalLessThanNotification ) + if(mHandleVerticalLessThanNotification) { - mHandleVerticalLessThanNotification.NotifySignal().Disconnect( this, &Decorator::Impl::HandleResetPosition ); - mActiveLayer.RemovePropertyNotification( mHandleVerticalLessThanNotification ); + mHandleVerticalLessThanNotification.NotifySignal().Disconnect(this, &Decorator::Impl::HandleResetPosition); + mActiveLayer.RemovePropertyNotification(mHandleVerticalLessThanNotification); } - if( mHandleVerticalGreaterThanNotification ) + if(mHandleVerticalGreaterThanNotification) { - mHandleVerticalGreaterThanNotification.NotifySignal().Disconnect( this, &Decorator::Impl::HandleResetPosition ); - mActiveLayer.RemovePropertyNotification( mHandleVerticalGreaterThanNotification ); + mHandleVerticalGreaterThanNotification.NotifySignal().Disconnect(this, &Decorator::Impl::HandleResetPosition); + mActiveLayer.RemovePropertyNotification(mHandleVerticalGreaterThanNotification); } - const HandleImpl& grabHandle = mHandle[GRAB_HANDLE]; - const HandleImpl& primaryHandle = mHandle[LEFT_SELECTION_HANDLE]; + const HandleImpl& grabHandle = mHandle[GRAB_HANDLE]; + const HandleImpl& primaryHandle = mHandle[LEFT_SELECTION_HANDLE]; const HandleImpl& secondaryHandle = mHandle[RIGHT_SELECTION_HANDLE]; - if( grabHandle.active ) + if(grabHandle.active) { - if( grabHandle.verticallyFlipped ) + if(grabHandle.verticallyFlipped) { // The grab handle is vertically flipped. Never is going to exceed the bottom edje of the display. mHandleVerticalGreaterThanNotification.Reset(); @@ -1518,14 +1543,14 @@ struct Decorator::Impl : public ConnectionTracker // The vertical distance from the center of the active layer to the top edje of the display. const float topHeight = 0.5f * mControlSize.height - grabHandle.position.y + grabHandle.size.height; - mHandleVerticalLessThanNotification = mActiveLayer.AddPropertyNotification( Actor::Property::WORLD_POSITION_Y, - LessThanCondition( mBoundingBox.y + topHeight ) ); + mHandleVerticalLessThanNotification = mActiveLayer.AddPropertyNotification(Actor::Property::WORLD_POSITION_Y, + LessThanCondition(mBoundingBox.y + topHeight)); // Notifies the change from false to true and from true to false. - mHandleVerticalLessThanNotification.SetNotifyMode( PropertyNotification::NotifyOnChanged ); + mHandleVerticalLessThanNotification.SetNotifyMode(PropertyNotification::NOTIFY_ON_CHANGED); // Connects the signals with the callbacks. - mHandleVerticalLessThanNotification.NotifySignal().Connect( this, &Decorator::Impl::HandleResetPosition ); + mHandleVerticalLessThanNotification.NotifySignal().Connect(this, &Decorator::Impl::HandleResetPosition); } else { @@ -1535,237 +1560,235 @@ struct Decorator::Impl : public ConnectionTracker // The vertical distance from the center of the active layer to the bottom edje of the display. const float bottomHeight = -0.5f * mControlSize.height + grabHandle.position.y + grabHandle.lineHeight + grabHandle.size.height; - mHandleVerticalGreaterThanNotification = mActiveLayer.AddPropertyNotification( Actor::Property::WORLD_POSITION_Y, - GreaterThanCondition( mBoundingBox.w - bottomHeight ) ); + mHandleVerticalGreaterThanNotification = mActiveLayer.AddPropertyNotification(Actor::Property::WORLD_POSITION_Y, + GreaterThanCondition(mBoundingBox.w - bottomHeight)); // Notifies the change from false to true and from true to false. - mHandleVerticalGreaterThanNotification.SetNotifyMode( PropertyNotification::NotifyOnChanged ); + mHandleVerticalGreaterThanNotification.SetNotifyMode(PropertyNotification::NOTIFY_ON_CHANGED); // Connects the signals with the callbacks. - mHandleVerticalGreaterThanNotification.NotifySignal().Connect( this, &Decorator::Impl::HandleResetPosition ); + mHandleVerticalGreaterThanNotification.NotifySignal().Connect(this, &Decorator::Impl::HandleResetPosition); } } else // The selection handles are active { - if( primaryHandle.verticallyFlipped && secondaryHandle.verticallyFlipped ) + if(primaryHandle.verticallyFlipped && secondaryHandle.verticallyFlipped) { // Both selection handles are vertically flipped. Never are going to exceed the bottom edje of the display. mHandleVerticalGreaterThanNotification.Reset(); // The vertical distance from the center of the active layer to the top edje of the display. - const float topHeight = 0.5f * mControlSize.height + std::max( -primaryHandle.position.y + primaryHandle.size.height, -secondaryHandle.position.y + secondaryHandle.size.height ); + const float topHeight = 0.5f * mControlSize.height + std::max(-primaryHandle.position.y + primaryHandle.size.height, -secondaryHandle.position.y + secondaryHandle.size.height); - mHandleVerticalLessThanNotification = mActiveLayer.AddPropertyNotification( Actor::Property::WORLD_POSITION_Y, - LessThanCondition( mBoundingBox.y + topHeight ) ); + mHandleVerticalLessThanNotification = mActiveLayer.AddPropertyNotification(Actor::Property::WORLD_POSITION_Y, + LessThanCondition(mBoundingBox.y + topHeight)); // Notifies the change from false to true and from true to false. - mHandleVerticalLessThanNotification.SetNotifyMode( PropertyNotification::NotifyOnChanged ); + mHandleVerticalLessThanNotification.SetNotifyMode(PropertyNotification::NOTIFY_ON_CHANGED); // Connects the signals with the callbacks. - mHandleVerticalLessThanNotification.NotifySignal().Connect( this, &Decorator::Impl::HandleResetPosition ); + mHandleVerticalLessThanNotification.NotifySignal().Connect(this, &Decorator::Impl::HandleResetPosition); } - else if( !primaryHandle.verticallyFlipped && !secondaryHandle.verticallyFlipped ) + else if(!primaryHandle.verticallyFlipped && !secondaryHandle.verticallyFlipped) { // Both selection handles aren't vertically flipped. Never are going to exceed the top edje of the display. mHandleVerticalLessThanNotification.Reset(); // The vertical distance from the center of the active layer to the bottom edje of the display. - const float bottomHeight = -0.5f * mControlSize.height + std::max( primaryHandle.position.y + primaryHandle.lineHeight + primaryHandle.size.height, - secondaryHandle.position.y + secondaryHandle.lineHeight + secondaryHandle.size.height ); + const float bottomHeight = -0.5f * mControlSize.height + std::max(primaryHandle.position.y + primaryHandle.lineHeight + primaryHandle.size.height, + secondaryHandle.position.y + secondaryHandle.lineHeight + secondaryHandle.size.height); - mHandleVerticalGreaterThanNotification = mActiveLayer.AddPropertyNotification( Actor::Property::WORLD_POSITION_Y, - GreaterThanCondition( mBoundingBox.w - bottomHeight ) ); + mHandleVerticalGreaterThanNotification = mActiveLayer.AddPropertyNotification(Actor::Property::WORLD_POSITION_Y, + GreaterThanCondition(mBoundingBox.w - bottomHeight)); // Notifies the change from false to true and from true to false. - mHandleVerticalGreaterThanNotification.SetNotifyMode( PropertyNotification::NotifyOnChanged ); + mHandleVerticalGreaterThanNotification.SetNotifyMode(PropertyNotification::NOTIFY_ON_CHANGED); // Connects the signals with the callbacks. - mHandleVerticalGreaterThanNotification.NotifySignal().Connect( this, &Decorator::Impl::HandleResetPosition ); + mHandleVerticalGreaterThanNotification.NotifySignal().Connect(this, &Decorator::Impl::HandleResetPosition); } else { // Only one of the selection handles is vertically flipped. Both vertical notifications are needed. // The vertical distance from the center of the active layer to the top edje of the display. - const float topHeight = 0.5f * mControlSize.height + ( primaryHandle.verticallyFlipped ? - -primaryHandle.position.y + primaryHandle.size.height : - -secondaryHandle.position.y + secondaryHandle.size.height ); + const float topHeight = 0.5f * mControlSize.height + (primaryHandle.verticallyFlipped ? -primaryHandle.position.y + primaryHandle.size.height : -secondaryHandle.position.y + secondaryHandle.size.height); - mHandleVerticalLessThanNotification = mActiveLayer.AddPropertyNotification( Actor::Property::WORLD_POSITION_Y, - LessThanCondition( mBoundingBox.y + topHeight ) ); + mHandleVerticalLessThanNotification = mActiveLayer.AddPropertyNotification(Actor::Property::WORLD_POSITION_Y, + LessThanCondition(mBoundingBox.y + topHeight)); // Notifies the change from false to true and from true to false. - mHandleVerticalLessThanNotification.SetNotifyMode( PropertyNotification::NotifyOnChanged ); + mHandleVerticalLessThanNotification.SetNotifyMode(PropertyNotification::NOTIFY_ON_CHANGED); // Connects the signals with the callbacks. - mHandleVerticalLessThanNotification.NotifySignal().Connect( this, &Decorator::Impl::HandleResetPosition ); + mHandleVerticalLessThanNotification.NotifySignal().Connect(this, &Decorator::Impl::HandleResetPosition); // The vertical distance from the center of the active layer to the bottom edje of the display. - const float bottomHeight = -0.5f * mControlSize.height + ( primaryHandle.verticallyFlipped ? - secondaryHandle.position.y + secondaryHandle.lineHeight + secondaryHandle.size.height : - primaryHandle.position.y + primaryHandle.lineHeight + primaryHandle.size.height ); + const float bottomHeight = -0.5f * mControlSize.height + (primaryHandle.verticallyFlipped ? secondaryHandle.position.y + secondaryHandle.lineHeight + secondaryHandle.size.height : primaryHandle.position.y + primaryHandle.lineHeight + primaryHandle.size.height); - mHandleVerticalGreaterThanNotification = mActiveLayer.AddPropertyNotification( Actor::Property::WORLD_POSITION_Y, - GreaterThanCondition( mBoundingBox.w - bottomHeight ) ); + mHandleVerticalGreaterThanNotification = mActiveLayer.AddPropertyNotification(Actor::Property::WORLD_POSITION_Y, + GreaterThanCondition(mBoundingBox.w - bottomHeight)); // Notifies the change from false to true and from true to false. - mHandleVerticalGreaterThanNotification.SetNotifyMode( PropertyNotification::NotifyOnChanged ); + mHandleVerticalGreaterThanNotification.SetNotifyMode(PropertyNotification::NOTIFY_ON_CHANGED); // Connects the signals with the callbacks. - mHandleVerticalGreaterThanNotification.NotifySignal().Connect( this, &Decorator::Impl::HandleResetPosition ); + mHandleVerticalGreaterThanNotification.NotifySignal().Connect(this, &Decorator::Impl::HandleResetPosition); } } // Horizontal notifications. // Disconnect any previous connected callback. - if( mHandleHorizontalLessThanNotification ) + if(mHandleHorizontalLessThanNotification) { - mHandleHorizontalLessThanNotification.NotifySignal().Disconnect( this, &Decorator::Impl::HandleResetPosition ); - mActiveLayer.RemovePropertyNotification( mHandleHorizontalLessThanNotification ); + mHandleHorizontalLessThanNotification.NotifySignal().Disconnect(this, &Decorator::Impl::HandleResetPosition); + mActiveLayer.RemovePropertyNotification(mHandleHorizontalLessThanNotification); } - if( mHandleHorizontalGreaterThanNotification ) + if(mHandleHorizontalGreaterThanNotification) { - mHandleHorizontalGreaterThanNotification.NotifySignal().Disconnect( this, &Decorator::Impl::HandleResetPosition ); - mActiveLayer.RemovePropertyNotification( mHandleHorizontalGreaterThanNotification ); + mHandleHorizontalGreaterThanNotification.NotifySignal().Disconnect(this, &Decorator::Impl::HandleResetPosition); + mActiveLayer.RemovePropertyNotification(mHandleHorizontalGreaterThanNotification); } - if( primaryHandle.active || secondaryHandle.active ) + if(primaryHandle.active || secondaryHandle.active) { // The horizontal distance from the center of the active layer to the left edje of the display. - const float leftWidth = 0.5f * mControlSize.width + std::max( -primaryHandle.position.x + primaryHandle.size.width, - -secondaryHandle.position.x + secondaryHandle.size.width ); + const float leftWidth = 0.5f * mControlSize.width + std::max(-primaryHandle.position.x + primaryHandle.size.width, + -secondaryHandle.position.x + secondaryHandle.size.width); - mHandleHorizontalLessThanNotification = mActiveLayer.AddPropertyNotification( Actor::Property::WORLD_POSITION_X, - LessThanCondition( mBoundingBox.x + leftWidth ) ); + mHandleHorizontalLessThanNotification = mActiveLayer.AddPropertyNotification(Actor::Property::WORLD_POSITION_X, + LessThanCondition(mBoundingBox.x + leftWidth)); // Notifies the change from false to true and from true to false. - mHandleHorizontalLessThanNotification.SetNotifyMode( PropertyNotification::NotifyOnChanged ); + mHandleHorizontalLessThanNotification.SetNotifyMode(PropertyNotification::NOTIFY_ON_CHANGED); // Connects the signals with the callbacks. - mHandleHorizontalLessThanNotification.NotifySignal().Connect( this, &Decorator::Impl::HandleResetPosition ); + mHandleHorizontalLessThanNotification.NotifySignal().Connect(this, &Decorator::Impl::HandleResetPosition); // The horizontal distance from the center of the active layer to the right edje of the display. - const float rightWidth = -0.5f * mControlSize.width + std::max( primaryHandle.position.x + primaryHandle.size.width, - secondaryHandle.position.x + secondaryHandle.size.width ); + const float rightWidth = -0.5f * mControlSize.width + std::max(primaryHandle.position.x + primaryHandle.size.width, + secondaryHandle.position.x + secondaryHandle.size.width); - mHandleHorizontalGreaterThanNotification = mActiveLayer.AddPropertyNotification( Actor::Property::WORLD_POSITION_X, - GreaterThanCondition( mBoundingBox.z - rightWidth ) ); + mHandleHorizontalGreaterThanNotification = mActiveLayer.AddPropertyNotification(Actor::Property::WORLD_POSITION_X, + GreaterThanCondition(mBoundingBox.z - rightWidth)); // Notifies the change from false to true and from true to false. - mHandleHorizontalGreaterThanNotification.SetNotifyMode( PropertyNotification::NotifyOnChanged ); + mHandleHorizontalGreaterThanNotification.SetNotifyMode(PropertyNotification::NOTIFY_ON_CHANGED); // Connects the signals with the callbacks. - mHandleHorizontalGreaterThanNotification.NotifySignal().Connect( this, &Decorator::Impl::HandleResetPosition ); + mHandleHorizontalGreaterThanNotification.NotifySignal().Connect(this, &Decorator::Impl::HandleResetPosition); } } // Popup - float AlternatePopUpPositionRelativeToCursor( bool topBottom ) + float AlternatePopUpPositionRelativeToCursor(bool topBottom) { float alternativePosition = 0.0f; - const float halfPopupHeight = 0.5f * mCopyPastePopup.actor.GetRelayoutSize( Dimension::HEIGHT ); + const float halfPopupHeight = 0.5f * mCopyPastePopup.actor.GetRelayoutSize(Dimension::HEIGHT); - const HandleImpl& primaryHandle = mHandle[LEFT_SELECTION_HANDLE]; + const HandleImpl& primaryHandle = mHandle[LEFT_SELECTION_HANDLE]; const HandleImpl& secondaryHandle = mHandle[RIGHT_SELECTION_HANDLE]; - const HandleImpl& grabHandle = mHandle[GRAB_HANDLE]; - const CursorImpl& cursor = mCursor[PRIMARY_CURSOR]; + const HandleImpl& grabHandle = mHandle[GRAB_HANDLE]; + const CursorImpl& cursor = mCursor[PRIMARY_CURSOR]; - if( primaryHandle.active || secondaryHandle.active ) + if(primaryHandle.active || secondaryHandle.active) { - float handleY = 0.f; + float handleY = 0.f; float maxHandleHeight = 0.f; - const bool primaryVisible = primaryHandle.horizontallyVisible && primaryHandle.verticallyVisible; + const bool primaryVisible = primaryHandle.horizontallyVisible && primaryHandle.verticallyVisible; const bool secondaryVisible = secondaryHandle.horizontallyVisible && secondaryHandle.verticallyVisible; - if( primaryVisible && secondaryVisible ) + if(primaryVisible && secondaryVisible) { - handleY = std::max( primaryHandle.position.y, secondaryHandle.position.y ); - maxHandleHeight = std::max( primaryHandle.size.height, secondaryHandle.size.height ); + handleY = std::max(primaryHandle.position.y, secondaryHandle.position.y); + maxHandleHeight = std::max(primaryHandle.size.height, secondaryHandle.size.height); } - else if( primaryVisible && !secondaryVisible ) + else if(primaryVisible && !secondaryVisible) { - handleY = primaryHandle.position.y; + handleY = primaryHandle.position.y; maxHandleHeight = primaryHandle.size.height; } - else if( !primaryVisible && secondaryVisible ) + else if(!primaryVisible && secondaryVisible) { - handleY = secondaryHandle.position.y; + handleY = secondaryHandle.position.y; maxHandleHeight = secondaryHandle.size.height; } - alternativePosition = handleY + ( topBottom ? halfPopupHeight + maxHandleHeight + cursor.lineHeight : -halfPopupHeight - maxHandleHeight ); + alternativePosition = handleY + (topBottom ? halfPopupHeight + maxHandleHeight + cursor.lineHeight : -halfPopupHeight - maxHandleHeight); } else { - alternativePosition = cursor.position.y + ( topBottom ? halfPopupHeight + grabHandle.size.height + cursor.lineHeight : -halfPopupHeight - grabHandle.size.height ); + alternativePosition = cursor.position.y + (topBottom ? halfPopupHeight + grabHandle.size.height + cursor.lineHeight : -halfPopupHeight - grabHandle.size.height); } return alternativePosition; } - void PopUpLeavesTopBoundary( PropertyNotification& source ) + void PopUpLeavesTopBoundary(PropertyNotification& source) { - const float popupHeight = mCopyPastePopup.actor.GetRelayoutSize( Dimension::HEIGHT ); + const float popupHeight = mCopyPastePopup.actor.GetRelayoutSize(Dimension::HEIGHT); // Sets the position of the popup below. - mCopyPastePopup.actor.SetY( floorf( CalculateVerticalPopUpPosition( 0.5f * popupHeight, true ) ) ); + mCopyPastePopup.actor.SetProperty(Actor::Property::POSITION_Y, floorf(CalculateVerticalPopUpPosition(0.5f * popupHeight, true))); } - void PopUpLeavesBottomBoundary( PropertyNotification& source ) + void PopUpLeavesBottomBoundary(PropertyNotification& source) { - const float popupHeight = mCopyPastePopup.actor.GetRelayoutSize( Dimension::HEIGHT ); + const float popupHeight = mCopyPastePopup.actor.GetRelayoutSize(Dimension::HEIGHT); // Sets the position of the popup above. - mCopyPastePopup.actor.SetY( floorf( CalculateVerticalPopUpPosition( 0.5f * popupHeight, false ) ) ); + mCopyPastePopup.actor.SetProperty(Actor::Property::POSITION_Y, floorf(CalculateVerticalPopUpPosition(0.5f * popupHeight, false))); } - void SetUpPopupPositionNotifications( const Vector3& popupHalfSize ) + void SetUpPopupPositionNotifications(const Vector3& popupHalfSize) { // Disconnect any previous connected callback. - if( mPopupTopExceedNotification ) + if(mPopupTopExceedNotification) { - mPopupTopExceedNotification.NotifySignal().Disconnect( this, &Decorator::Impl::PopUpLeavesTopBoundary ); - mCopyPastePopup.actor.RemovePropertyNotification( mPopupTopExceedNotification ); + mPopupTopExceedNotification.NotifySignal().Disconnect(this, &Decorator::Impl::PopUpLeavesTopBoundary); + mCopyPastePopup.actor.RemovePropertyNotification(mPopupTopExceedNotification); } - if( mPopupBottomExceedNotification ) + if(mPopupBottomExceedNotification) { - mPopupBottomExceedNotification.NotifySignal().Disconnect( this, &Decorator::Impl::PopUpLeavesBottomBoundary ); - mCopyPastePopup.actor.RemovePropertyNotification( mPopupBottomExceedNotification ); + mPopupBottomExceedNotification.NotifySignal().Disconnect(this, &Decorator::Impl::PopUpLeavesBottomBoundary); + mCopyPastePopup.actor.RemovePropertyNotification(mPopupBottomExceedNotification); } // Note Property notifications ignore any set anchor point so conditions must allow for this. Default is Top Left. // Exceeding vertical boundary - mPopupTopExceedNotification = mCopyPastePopup.actor.AddPropertyNotification( Actor::Property::WORLD_POSITION_Y, - LessThanCondition( mBoundingBox.y + popupHalfSize.height ) ); + mPopupTopExceedNotification = mCopyPastePopup.actor.AddPropertyNotification(Actor::Property::WORLD_POSITION_Y, + LessThanCondition(mBoundingBox.y + popupHalfSize.height)); - mPopupBottomExceedNotification = mCopyPastePopup.actor.AddPropertyNotification( Actor::Property::WORLD_POSITION_Y, - GreaterThanCondition( mBoundingBox.w - popupHalfSize.height ) ); + mPopupBottomExceedNotification = mCopyPastePopup.actor.AddPropertyNotification(Actor::Property::WORLD_POSITION_Y, + GreaterThanCondition(mBoundingBox.w - popupHalfSize.height)); // Notifies the change from false to true and from true to false. - mPopupTopExceedNotification.SetNotifyMode( PropertyNotification::NotifyOnChanged ); - mPopupBottomExceedNotification.SetNotifyMode( PropertyNotification::NotifyOnChanged ); + mPopupTopExceedNotification.SetNotifyMode(PropertyNotification::NOTIFY_ON_CHANGED); + mPopupBottomExceedNotification.SetNotifyMode(PropertyNotification::NOTIFY_ON_CHANGED); - mPopupTopExceedNotification.NotifySignal().Connect( this, &Decorator::Impl::PopUpLeavesTopBoundary ); - mPopupBottomExceedNotification.NotifySignal().Connect( this, &Decorator::Impl::PopUpLeavesBottomBoundary ); + mPopupTopExceedNotification.NotifySignal().Connect(this, &Decorator::Impl::PopUpLeavesTopBoundary); + mPopupBottomExceedNotification.NotifySignal().Connect(this, &Decorator::Impl::PopUpLeavesBottomBoundary); } - void SetHandleImage( HandleType handleType, HandleImageType handleImageType, Dali::Image image ) + void SetHandleImage(HandleType handleType, HandleImageType handleImageType, const std::string& imageFileName) { + ImageDimensions dimensions = Dali::GetOriginalImageSize(imageFileName); + HandleImpl& handle = mHandle[handleType]; - handle.size = Size( image.GetWidth(), image.GetHeight() ); + handle.size = Size(dimensions.GetWidth(), dimensions.GetHeight()); - mHandleImages[handleType][handleImageType] = image; + mHandleImages[handleType][handleImageType] = imageFileName; } - void SetScrollThreshold( float threshold ) + void SetScrollThreshold(float threshold) { mScrollThreshold = threshold; } @@ -1775,9 +1798,9 @@ struct Decorator::Impl : public ConnectionTracker return mScrollThreshold; } - void SetScrollSpeed( float speed ) + void SetScrollSpeed(float speed) { - mScrollSpeed = speed; + mScrollSpeed = speed; mScrollDistance = speed * SCROLL_TICK_INTERVAL * TO_SECONDS; } @@ -1790,7 +1813,7 @@ struct Decorator::Impl : public ConnectionTracker { StopScrollTimer(); - if( mScrollTimer ) + if(mScrollTimer) { mNotifyEndOfScroll = true; } @@ -1803,13 +1826,13 @@ struct Decorator::Impl : public ConnectionTracker */ void StartScrollTimer() { - if( !mScrollTimer ) + if(!mScrollTimer) { - mScrollTimer = Timer::New( SCROLL_TICK_INTERVAL ); - mScrollTimer.TickSignal().Connect( this, &Decorator::Impl::OnScrollTimerTick ); + mScrollTimer = Timer::New(SCROLL_TICK_INTERVAL); + mScrollTimer.TickSignal().Connect(this, &Decorator::Impl::OnScrollTimerTick); } - if( !mScrollTimer.IsRunning() ) + if(!mScrollTimer.IsRunning()) { mScrollTimer.Start(); } @@ -1820,7 +1843,7 @@ struct Decorator::Impl : public ConnectionTracker */ void StopScrollTimer() { - if( mScrollTimer ) + if(mScrollTimer) { mScrollTimer.Stop(); } @@ -1833,12 +1856,12 @@ struct Decorator::Impl : public ConnectionTracker */ bool OnScrollTimerTick() { - if( HANDLE_TYPE_COUNT != mHandleScrolling ) + if(HANDLE_TYPE_COUNT != mHandleScrolling) { float x = 0.f; float y = 0.f; - switch( mScrollDirection ) + switch(mScrollDirection) { case SCROLL_RIGHT: { @@ -1864,10 +1887,10 @@ struct Decorator::Impl : public ConnectionTracker break; } - mController.DecorationEvent( mHandleScrolling, - HANDLE_SCROLLING, - x, - y ); + mController.DecorationEvent(mHandleScrolling, + HANDLE_SCROLLING, + x, + y); } return true; @@ -1879,10 +1902,11 @@ struct Decorator::Impl : public ConnectionTracker PanGestureDetector mPanDetector; LongPressGestureDetector mLongPressDetector; - 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. + 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. + Actor mActiveLayer; ///< Actor for active handles and alike that ensures they are above all else. + Actor mCursorLayer; ///< Actor for cursor layer. this is for cursor clipping. PropertyNotification mHandleVerticalLessThanNotification; ///< Notifies when the 'y' coord of the active layer is less than a given value. PropertyNotification mHandleVerticalGreaterThanNotification; ///< Notifies when the 'y' coord of the active layer is grater than a given value. PropertyNotification mHandleHorizontalLessThanNotification; ///< Notifies when the 'x' coord of the active layer is less than a given value. @@ -1892,92 +1916,93 @@ struct Decorator::Impl : public ConnectionTracker Control mPrimaryCursor; Control mSecondaryCursor; - Actor mHighlightActor; ///< Actor to display highlight - Renderer mHighlightRenderer; - Shader mHighlightShader; ///< Shader used for highlight - Property::Map mQuadVertexFormat; - PopupImpl mCopyPastePopup; - TextSelectionPopup::Buttons mEnabledPopupButtons; /// Bit mask of currently enabled Popup buttons + Actor mHighlightActor; ///< Actor to display highlight + Renderer mHighlightRenderer; + Shader mHighlightShader; ///< Shader used for highlight + Property::Map mQuadVertexFormat; + PopupImpl mCopyPastePopup; + TextSelectionPopup::Buttons mEnabledPopupButtons; /// Bit mask of currently enabled Popup buttons TextSelectionPopupCallbackInterface& mTextSelectionPopupCallbackInterface; - Image mHandleImages[HANDLE_TYPE_COUNT][HANDLE_IMAGE_TYPE_COUNT]; - Vector4 mHandleColor; - - CursorImpl mCursor[CURSOR_COUNT]; - HandleImpl mHandle[HANDLE_TYPE_COUNT]; - - PropertyBuffer mQuadVertices; - Geometry mQuadGeometry; - QuadContainer mHighlightQuadList; ///< Sub-selections that combine to create the complete selection highlight. - - Vector4 mBoundingBox; ///< The bounding box in world coords. - Vector4 mHighlightColor; ///< Color of the highlight - Vector2 mHighlightPosition; ///< The position of the highlight actor. - Size mHighlightSize; ///< The size of the highlighted text. - Size mControlSize; ///< The control's size. Set by the Relayout. - float mHighlightOutlineOffset; ///< The outline's offset. - - unsigned int mActiveCursor; - unsigned int mCursorBlinkInterval; - float mCursorBlinkDuration; - float mCursorWidth; ///< The width of the cursors in pixels. - HandleType mHandleScrolling; ///< The handle which is scrolling. - HandleType mHandleReleased; ///< The last handle released. - 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. - int mTextDepth; ///< The depth used to render the text. - - bool mActiveCopyPastePopup : 1; - bool mPopupSetNewPosition : 1; - bool mCursorBlinkStatus : 1; ///< Flag to switch between blink on and blink off. - bool mDelayCursorBlink : 1; ///< Used to avoid cursor blinking when entering text. - bool mPrimaryCursorVisible : 1; ///< Whether the primary cursor is visible. - bool mSecondaryCursorVisible : 1; ///< Whether the secondary cursor is visible. - bool mFlipSelectionHandlesOnCross : 1; ///< Whether to flip the selection handles as soon as they cross. - bool mFlipLeftSelectionHandleDirection : 1; ///< Whether to flip the left selection handle image because of the character's direction. - bool mFlipRightSelectionHandleDirection : 1; ///< Whether to flip the right selection handle image because of the character's direction. - bool mIsHandlePanning : 1; ///< Whether any of the handles is moving. - bool mIsHandleCurrentlyCrossed : 1; ///< Whether the handles are crossed. - bool mIsHandlePreviouslyCrossed : 1; ///< Whether the handles where crossed at the last handle touch up. - bool mNotifyEndOfScroll : 1; ///< Whether to notify the end of the scroll. - bool mHorizontalScrollingEnabled : 1; ///< Whether the horizontal scrolling is enabled. - bool mVerticalScrollingEnabled : 1; ///< Whether the vertical scrolling is enabled. - bool mSmoothHandlePanEnabled : 1; ///< Whether to pan smoothly the handles. - bool mIsHighlightBoxActive : 1; ///< Whether the highlight box is active. + std::string mHandleImages[HANDLE_TYPE_COUNT][HANDLE_IMAGE_TYPE_COUNT]; + Vector4 mHandleColor; + + CursorImpl mCursor[CURSOR_COUNT]; + HandleImpl mHandle[HANDLE_TYPE_COUNT]; + + VertexBuffer mQuadVertices; + Geometry mQuadGeometry; + QuadContainer mHighlightQuadList; ///< Sub-selections that combine to create the complete selection highlight. + + Vector4 mBoundingBox; ///< The bounding box in world coords. + Vector4 mHighlightColor; ///< Color of the highlight + Vector2 mHighlightPosition; ///< The position of the highlight actor. + Size mHighlightSize; ///< The size of the highlighted text. + Size mControlSize; ///< The control's size. Set by the Relayout. + float mHighlightOutlineOffset; ///< The outline's offset. + + unsigned int mActiveCursor; + unsigned int mCursorBlinkInterval; + float mCursorBlinkDuration; + float mCursorWidth; ///< The width of the cursors in pixels. + HandleType mHandleScrolling; ///< The handle which is scrolling. + HandleType mHandleReleased; ///< The last handle released. + 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. + int mTextDepth; ///< The depth used to render the text. + + bool mActiveCopyPastePopup : 1; + bool mPopupSetNewPosition : 1; + bool mCursorBlinkStatus : 1; ///< Flag to switch between blink on and blink off. + bool mDelayCursorBlink : 1; ///< Used to avoid cursor blinking when entering text. + bool mPrimaryCursorVisible : 1; ///< Whether the primary cursor is visible. + bool mSecondaryCursorVisible : 1; ///< Whether the secondary cursor is visible. + bool mFlipSelectionHandlesOnCross : 1; ///< Whether to flip the selection handles as soon as they cross. + bool mFlipLeftSelectionHandleDirection : 1; ///< Whether to flip the left selection handle image because of the character's direction. + bool mFlipRightSelectionHandleDirection : 1; ///< Whether to flip the right selection handle image because of the character's direction. + bool mIsHandlePanning : 1; ///< Whether any of the handles is moving. + bool mIsHandleCurrentlyCrossed : 1; ///< Whether the handles are crossed. + bool mIsHandlePreviouslyCrossed : 1; ///< Whether the handles where crossed at the last handle touch up. + bool mNotifyEndOfScroll : 1; ///< Whether to notify the end of the scroll. + bool mHorizontalScrollingEnabled : 1; ///< Whether the horizontal scrolling is enabled. + bool mVerticalScrollingEnabled : 1; ///< Whether the vertical scrolling is enabled. + bool mSmoothHandlePanEnabled : 1; ///< Whether to pan smoothly the handles. + bool mIsHighlightBoxActive : 1; ///< Whether the highlight box is active. + bool mHidePrimaryCursorAndGrabHandle : 1; ///< Whether the primary cursor and grab are hidden always. }; -DecoratorPtr Decorator::New( ControllerInterface& controller, - TextSelectionPopupCallbackInterface& callbackInterface ) +DecoratorPtr Decorator::New(ControllerInterface& controller, + TextSelectionPopupCallbackInterface& callbackInterface) { - return DecoratorPtr( new Decorator( controller, - callbackInterface ) ); + return DecoratorPtr(new Decorator(controller, + callbackInterface)); } -void Decorator::SetBoundingBox( const Rect& boundingBox ) +void Decorator::SetBoundingBox(const Rect& boundingBox) { - LocalToWorldCoordinatesBoundingBox( boundingBox, mImpl->mBoundingBox ); + LocalToWorldCoordinatesBoundingBox(boundingBox, mImpl->mBoundingBox); } -void Decorator::GetBoundingBox( Rect& boundingBox ) const +void Decorator::GetBoundingBox(Rect& boundingBox) const { - WorldToLocalCoordinatesBoundingBox( mImpl->mBoundingBox, boundingBox ); + WorldToLocalCoordinatesBoundingBox(mImpl->mBoundingBox, boundingBox); } -void Decorator::Relayout( const Vector2& size ) +void Decorator::Relayout(const Vector2& size) { - mImpl->Relayout( size ); + mImpl->Relayout(size); } -void Decorator::UpdatePositions( const Vector2& scrollOffset ) +void Decorator::UpdatePositions(const Vector2& scrollOffset) { - mImpl->UpdatePositions( scrollOffset ); + mImpl->UpdatePositions(scrollOffset); } /** Cursor **/ -void Decorator::SetActiveCursor( ActiveCursor activeCursor ) +void Decorator::SetActiveCursor(ActiveCursor activeCursor) { mImpl->mActiveCursor = activeCursor; } @@ -1987,62 +2012,62 @@ unsigned int Decorator::GetActiveCursor() const return mImpl->mActiveCursor; } -void Decorator::SetPosition( Cursor cursor, float x, float y, float cursorHeight, float lineHeight ) +void Decorator::SetPosition(Cursor cursor, float x, float y, float cursorHeight, float lineHeight) { Impl::CursorImpl& cursorImpl = mImpl->mCursor[cursor]; - cursorImpl.position.x = x; - cursorImpl.position.y = y; + cursorImpl.position.x = x; + cursorImpl.position.y = y; cursorImpl.cursorHeight = cursorHeight; - cursorImpl.lineHeight = lineHeight; + cursorImpl.lineHeight = lineHeight; } -void Decorator::GetPosition( Cursor cursor, float& x, float& y, float& cursorHeight, float& lineHeight ) const +void Decorator::GetPosition(Cursor cursor, float& x, float& y, float& cursorHeight, float& lineHeight) const { const Impl::CursorImpl& cursorImpl = mImpl->mCursor[cursor]; - x = cursorImpl.position.x; - y = cursorImpl.position.y; + x = cursorImpl.position.x; + y = cursorImpl.position.y; cursorHeight = cursorImpl.cursorHeight; - lineHeight = cursorImpl.lineHeight; + lineHeight = cursorImpl.lineHeight; } -const Vector2& Decorator::GetPosition( Cursor cursor ) const +const Vector2& Decorator::GetPosition(Cursor cursor) const { return mImpl->mCursor[cursor].position; } -void Decorator::SetGlyphOffset( Cursor cursor, float glyphOffset ) +void Decorator::SetGlyphOffset(Cursor cursor, float glyphOffset) { Impl::CursorImpl& cursorImpl = mImpl->mCursor[cursor]; cursorImpl.glyphOffset = glyphOffset; } -const float Decorator::GetGlyphOffset( Cursor cursor) const +const float Decorator::GetGlyphOffset(Cursor cursor) const { return mImpl->mCursor[cursor].glyphOffset; } -void Decorator::SetCursorColor( Cursor cursor, const Dali::Vector4& color ) +void Decorator::SetCursorColor(Cursor cursor, const Dali::Vector4& color) { mImpl->mCursor[cursor].color = color; } -const Dali::Vector4& Decorator::GetColor( Cursor cursor ) const +const Dali::Vector4& Decorator::GetColor(Cursor cursor) const { return mImpl->mCursor[cursor].color; } void Decorator::StartCursorBlink() { - if ( !mImpl->mCursorBlinkTimer ) + if(!mImpl->mCursorBlinkTimer) { - mImpl->mCursorBlinkTimer = Timer::New( mImpl->mCursorBlinkInterval ); - mImpl->mCursorBlinkTimer.TickSignal().Connect( mImpl, &Decorator::Impl::OnCursorBlinkTimerTick ); + mImpl->mCursorBlinkTimer = Timer::New(mImpl->mCursorBlinkInterval); + mImpl->mCursorBlinkTimer.TickSignal().Connect(mImpl, &Decorator::Impl::OnCursorBlinkTimerTick); } - if ( !mImpl->mCursorBlinkTimer.IsRunning() ) + if(!mImpl->mCursorBlinkTimer.IsRunning()) { mImpl->mCursorBlinkTimer.Start(); } @@ -2050,7 +2075,7 @@ void Decorator::StartCursorBlink() void Decorator::StopCursorBlink() { - if ( mImpl->mCursorBlinkTimer ) + if(mImpl->mCursorBlinkTimer) { mImpl->mCursorBlinkTimer.Stop(); } @@ -2061,20 +2086,20 @@ void Decorator::StopCursorBlink() void Decorator::DelayCursorBlink() { mImpl->mCursorBlinkStatus = true; // Show cursor for a bit longer - mImpl->mDelayCursorBlink = true; + mImpl->mDelayCursorBlink = true; } -void Decorator::SetCursorBlinkInterval( float seconds ) +void Decorator::SetCursorBlinkInterval(float seconds) { - mImpl->mCursorBlinkInterval = static_cast( seconds * TO_MILLISECONDS ); // Convert to milliseconds + mImpl->mCursorBlinkInterval = static_cast(seconds * TO_MILLISECONDS); // Convert to milliseconds } float Decorator::GetCursorBlinkInterval() const { - return static_cast( mImpl->mCursorBlinkInterval ) * TO_SECONDS; + return static_cast(mImpl->mCursorBlinkInterval) * TO_SECONDS; } -void Decorator::SetCursorBlinkDuration( float seconds ) +void Decorator::SetCursorBlinkDuration(float seconds) { mImpl->mCursorBlinkDuration = seconds; } @@ -2084,25 +2109,51 @@ float Decorator::GetCursorBlinkDuration() const return mImpl->mCursorBlinkDuration; } -void Decorator::SetCursorWidth( int width ) +void Decorator::SetCursorWidth(int width) { - mImpl->mCursorWidth = static_cast( width ); + mImpl->mCursorWidth = static_cast(width); } int Decorator::GetCursorWidth() const { - return static_cast( mImpl->mCursorWidth ); + return static_cast(mImpl->mCursorWidth); } +void Decorator::SetEditable(bool editable) +{ + mImpl->mHidePrimaryCursorAndGrabHandle = !editable; + // If editable is false, all decorators should be disabled. + if(!editable) + { + if(IsHighlightActive()) + { + SetHighlightActive(false); + } + if(IsHandleActive(LEFT_SELECTION_HANDLE)) + { + SetHandleActive(LEFT_SELECTION_HANDLE, false); + } + if(IsHandleActive(RIGHT_SELECTION_HANDLE)) + { + SetHandleActive(RIGHT_SELECTION_HANDLE, false); + } + if(IsPopupActive()) + { + SetPopupActive(false); + } + } + + mImpl->Relayout(mImpl->mControlSize); +} /** Handles **/ -void Decorator::SetHandleActive( HandleType handleType, bool active ) +void Decorator::SetHandleActive(HandleType handleType, bool active) { mImpl->mHandle[handleType].active = active; - if( !active ) + if(!active) { - if( ( LEFT_SELECTION_HANDLE == handleType ) || ( RIGHT_SELECTION_HANDLE == handleType ) ) + if((LEFT_SELECTION_HANDLE == handleType) || (RIGHT_SELECTION_HANDLE == handleType)) { mImpl->mIsHandlePreviouslyCrossed = false; } @@ -2111,32 +2162,31 @@ void Decorator::SetHandleActive( HandleType handleType, bool active ) // 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]; - ImageView imageView = mImpl->mHandle[handleType].actor; - if( imageReleased && imageView ) + const bool imageReleased = mImpl->mHandleImages[handleType][HANDLE_IMAGE_RELEASED].size(); + ImageView imageView = mImpl->mHandle[handleType].actor; + if(imageReleased && imageView) { - imageView.SetImage( imageReleased ); + imageView.SetImage(mImpl->mHandleImages[handleType][HANDLE_IMAGE_RELEASED]); } } - } -bool Decorator::IsHandleActive( HandleType handleType ) const +bool Decorator::IsHandleActive(HandleType handleType) const { - return mImpl->mHandle[handleType].active ; + return mImpl->mHandle[handleType].active; } -void Decorator::SetHandleImage( HandleType handleType, HandleImageType handleImageType, Dali::Image image ) +void Decorator::SetHandleImage(HandleType handleType, HandleImageType handleImageType, const std::string& imageFileName) { - mImpl->SetHandleImage( handleType, handleImageType, image ); + mImpl->SetHandleImage(handleType, handleImageType, imageFileName); } -Dali::Image Decorator::GetHandleImage( HandleType handleType, HandleImageType handleImageType ) const +const std::string& Decorator::GetHandleImage(HandleType handleType, HandleImageType handleImageType) const { return mImpl->mHandleImages[handleType][handleImageType]; } -void Decorator::SetHandleColor( const Vector4& color ) +void Decorator::SetHandleColor(const Vector4& color) { mImpl->mHandleColor = color; } @@ -2146,7 +2196,7 @@ const Vector4& Decorator::GetHandleColor() const return mImpl->mHandleColor; } -void Decorator::SetPosition( HandleType handleType, float x, float y, float height ) +void Decorator::SetPosition(HandleType handleType, float x, float y, float height) { // Adjust handle's displacement Impl::HandleImpl& handle = mImpl->mHandle[handleType]; @@ -2155,74 +2205,74 @@ void Decorator::SetPosition( HandleType handleType, float x, float y, float heig handle.position.y = y; handle.lineHeight = height; - if( mImpl->mSmoothHandlePanEnabled ) + if(mImpl->mSmoothHandlePanEnabled) { handle.grabDisplacementX = 0.f; handle.grabDisplacementY = 0.f; } } -void Decorator::GetPosition( HandleType handleType, float& x, float& y, float& height ) const +void Decorator::GetPosition(HandleType handleType, float& x, float& y, float& height) const { Impl::HandleImpl& handle = mImpl->mHandle[handleType]; - x = handle.position.x; - y = handle.position.y; + x = handle.position.x; + y = handle.position.y; height = handle.lineHeight; } -const Vector2& Decorator::GetPosition( HandleType handleType ) const +const Vector2& Decorator::GetPosition(HandleType handleType) const { return mImpl->mHandle[handleType].position; } -void Decorator::FlipHandleVertically( HandleType handleType, bool flip ) +void Decorator::FlipHandleVertically(HandleType handleType, bool flip) { mImpl->mHandle[handleType].verticallyFlippedPreferred = flip; } -bool Decorator::IsHandleVerticallyFlipped( HandleType handleType ) const +bool Decorator::IsHandleVerticallyFlipped(HandleType handleType) const { return mImpl->mHandle[handleType].verticallyFlippedPreferred; } -void Decorator::FlipSelectionHandlesOnCrossEnabled( bool enable ) +void Decorator::FlipSelectionHandlesOnCrossEnabled(bool enable) { mImpl->mFlipSelectionHandlesOnCross = enable; } -void Decorator::SetSelectionHandleFlipState( bool indicesSwapped, bool left, bool right ) +void Decorator::SetSelectionHandleFlipState(bool indicesSwapped, bool left, bool right) { - mImpl->mIsHandleCurrentlyCrossed = indicesSwapped; - mImpl->mFlipLeftSelectionHandleDirection = left; + mImpl->mIsHandleCurrentlyCrossed = indicesSwapped; + mImpl->mFlipLeftSelectionHandleDirection = left; mImpl->mFlipRightSelectionHandleDirection = right; } -void Decorator::AddHighlight( unsigned int index, const Vector4& quad ) +void Decorator::AddHighlight(unsigned int index, const Vector4& quad) { - *( mImpl->mHighlightQuadList.Begin() + index ) = quad; + *(mImpl->mHighlightQuadList.Begin() + index) = quad; } -void Decorator::SetHighLightBox( const Vector2& position, const Size& size, float outlineOffset ) +void Decorator::SetHighLightBox(const Vector2& position, const Size& size, float outlineOffset) { - mImpl->mHighlightPosition = position; - mImpl->mHighlightSize = size; + mImpl->mHighlightPosition = position; + mImpl->mHighlightSize = size; mImpl->mHighlightOutlineOffset = outlineOffset; } void Decorator::ClearHighlights() { mImpl->mHighlightQuadList.Clear(); - mImpl->mHighlightPosition = Vector2::ZERO; + mImpl->mHighlightPosition = Vector2::ZERO; mImpl->mHighlightOutlineOffset = 0.f; } -void Decorator::ResizeHighlightQuads( unsigned int numberOfQuads ) +void Decorator::ResizeHighlightQuads(unsigned int numberOfQuads) { - mImpl->mHighlightQuadList.Resize( numberOfQuads ); + mImpl->mHighlightQuadList.Resize(numberOfQuads); } -void Decorator::SetHighlightColor( const Vector4& color ) +void Decorator::SetHighlightColor(const Vector4& color) { mImpl->mHighlightColor = color; } @@ -2232,7 +2282,7 @@ const Vector4& Decorator::GetHighlightColor() const return mImpl->mHighlightColor; } -void Decorator::SetHighlightActive( bool active ) +void Decorator::SetHighlightActive(bool active) { mImpl->mIsHighlightBoxActive = active; } @@ -2244,15 +2294,15 @@ bool Decorator::IsHighlightActive() const bool Decorator::IsHighlightVisible() const { - return ( mImpl->mHighlightActor && mImpl->mHighlightActor.GetParent() ); + return (mImpl->mHighlightActor && mImpl->mHighlightActor.GetParent()); } -void Decorator::SetTextDepth( int textDepth ) +void Decorator::SetTextDepth(int textDepth) { mImpl->mTextDepth = textDepth; } -void Decorator::SetPopupActive( bool active ) +void Decorator::SetPopupActive(bool active) { mImpl->mActiveCopyPastePopup = active; } @@ -2262,21 +2312,11 @@ bool Decorator::IsPopupActive() const return mImpl->mActiveCopyPastePopup; } -void Decorator::SetEnabledPopupButtons( TextSelectionPopup::Buttons& enabledButtonsBitMask ) +void Decorator::SetEnabledPopupButtons(TextSelectionPopup::Buttons& enabledButtonsBitMask) { mImpl->mEnabledPopupButtons = enabledButtonsBitMask; - - if ( !mImpl->mCopyPastePopup.actor ) - { - mImpl->mCopyPastePopup.actor = TextSelectionPopup::New( &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::SetPopupPosition ); // Position popup after size negotiation - } - - mImpl->mCopyPastePopup.actor.EnableButtons( mImpl->mEnabledPopupButtons ); + mImpl->CreateSelectionPopup(); + mImpl->mCopyPastePopup.actor.EnableButtons(mImpl->mEnabledPopupButtons); } TextSelectionPopup::Buttons& Decorator::GetEnabledPopupButtons() @@ -2284,11 +2324,25 @@ TextSelectionPopup::Buttons& Decorator::GetEnabledPopupButtons() return mImpl->mEnabledPopupButtons; } +void Decorator::SetSelectionPopupStyle(const Property::Map& options) +{ + mImpl->CreateSelectionPopup(); + mImpl->mCopyPastePopup.actor.SetProperties(options); +} + +void Decorator::GetSelectionPopupStyle(Property::Map& options) +{ + if(mImpl->mCopyPastePopup.actor) + { + mImpl->mCopyPastePopup.actor.GetProperties(options); + } +} + /** Scroll **/ -void Decorator::SetScrollThreshold( float threshold ) +void Decorator::SetScrollThreshold(float threshold) { - mImpl->SetScrollThreshold( threshold ); + mImpl->SetScrollThreshold(threshold); } float Decorator::GetScrollThreshold() const @@ -2296,9 +2350,9 @@ float Decorator::GetScrollThreshold() const return mImpl->GetScrollThreshold(); } -void Decorator::SetScrollSpeed( float speed ) +void Decorator::SetScrollSpeed(float speed) { - mImpl->SetScrollSpeed( speed ); + mImpl->SetScrollSpeed(speed); } float Decorator::GetScrollSpeed() const @@ -2311,7 +2365,7 @@ void Decorator::NotifyEndOfScroll() mImpl->NotifyEndOfScroll(); } -void Decorator::SetHorizontalScrollEnabled( bool enable ) +void Decorator::SetHorizontalScrollEnabled(bool enable) { mImpl->mHorizontalScrollingEnabled = enable; } @@ -2321,7 +2375,7 @@ bool Decorator::IsHorizontalScrollEnabled() const return mImpl->mHorizontalScrollingEnabled; } -void Decorator::SetVerticalScrollEnabled( bool enable ) +void Decorator::SetVerticalScrollEnabled(bool enable) { mImpl->mVerticalScrollingEnabled = enable; } @@ -2331,7 +2385,7 @@ bool Decorator::IsVerticalScrollEnabled() const return mImpl->mVerticalScrollingEnabled; } -void Decorator::SetSmoothHandlePanEnabled( bool enable ) +void Decorator::SetSmoothHandlePanEnabled(bool enable) { mImpl->mSmoothHandlePanEnabled = enable; } @@ -2346,11 +2400,11 @@ Decorator::~Decorator() delete mImpl; } -Decorator::Decorator( ControllerInterface& controller, - TextSelectionPopupCallbackInterface& callbackInterface ) -: mImpl( NULL ) +Decorator::Decorator(ControllerInterface& controller, + TextSelectionPopupCallbackInterface& callbackInterface) +: mImpl(NULL) { - mImpl = new Decorator::Impl( controller, callbackInterface ); + mImpl = new Decorator::Impl(controller, callbackInterface); } } // namespace Text