// EXTERNAL INCLUDES
#include <dali/integration-api/debug.h>
-#include <dali/public-api/actors/actor.h>
+
#include <dali/public-api/adaptor-framework/timer.h>
-#include <dali/public-api/actors/image-actor.h>
#include <dali/public-api/actors/layer.h>
-#include <dali/public-api/animation/constraint.h>
-#include <dali/public-api/common/constants.h>
#include <dali/public-api/common/stage.h>
-#include <dali/public-api/events/tap-gesture.h>
-#include <dali/public-api/events/tap-gesture-detector.h>
#include <dali/public-api/events/touch-event.h>
#include <dali/public-api/events/pan-gesture.h>
-#include <dali/public-api/events/pan-gesture-detector.h>
#include <dali/public-api/images/resource-image.h>
-#include <dali/public-api/math/rect.h>
-#include <dali/public-api/math/vector2.h>
-#include <dali/public-api/math/vector4.h>
#include <dali/public-api/object/property-notification.h>
-#include <dali/public-api/signals/connection-tracker.h>
-#include <dali/devel-api/object/property-buffer.h>
#include <dali/devel-api/rendering/geometry.h>
-#include <dali/devel-api/rendering/material.h>
#include <dali/devel-api/rendering/renderer.h>
-#include <dali/devel-api/rendering/shader.h>
// INTERNAL INCLUDES
-#include <dali-toolkit/public-api/controls/control.h>
#include <dali-toolkit/public-api/controls/control-depth-index-ranges.h>
-#include <dali-toolkit/public-api/controls/control-impl.h>
-#include <dali-toolkit/public-api/controls/buttons/push-button.h>
#include <dali-toolkit/public-api/controls/default-controls/solid-color-actor.h>
-#include <dali-toolkit/public-api/controls/text-controls/text-label.h>
-#include <dali-toolkit/devel-api/controls/text-controls/text-selection-popup.h>
#ifdef DEBUG_ENABLED
#define DECORATOR_DEBUG
{
const char* DEFAULT_GRAB_HANDLE_IMAGE_RELEASED( DALI_IMAGE_DIR "cursor_handler_center.png" );
-const char* DEFAULT_SELECTION_HANDLE_ONE_RELEASED( DALI_IMAGE_DIR "selection_handle_left.png" );
-const char* DEFAULT_SELECTION_HANDLE_TWO_RELEASED( DALI_IMAGE_DIR "selection_handle_right.png" );
const int DEFAULT_POPUP_OFFSET( -100.0f ); // Vertical offset of Popup from cursor or handles position.
const float SCROLL_SPEED = 300.f;
const float SCROLL_DISTANCE = SCROLL_SPEED * SCROLL_TICK_INTERVAL * TO_SECONDS;
+const float CURSOR_WIDTH = 1.f;
+
/**
* structure to hold coordinates of each quad, which will make up the mesh.
*/
ImageActor actor;
Actor grabArea;
+ ImageActor markerActor;
Vector2 position;
float lineHeight; ///< Not the handle height
mActiveCursor( ACTIVE_CURSOR_NONE ),
mCursorBlinkInterval( CURSOR_BLINK_INTERVAL ),
mCursorBlinkDuration( 0.0f ),
+ mCursorWidth( CURSOR_WIDTH ),
mHandleScrolling( HANDLE_TYPE_COUNT ),
mScrollDirection( SCROLL_NONE ),
mScrollThreshold( SCROLL_THRESHOLD ),
mScrollSpeed( SCROLL_SPEED ),
mScrollDistance( SCROLL_DISTANCE ),
+ mTextDepth( 0u ),
mActiveCopyPastePopup( false ),
mCursorBlinkStatus( true ),
mPrimaryCursorVisible( false ),
// Show or hide the cursors
CreateCursors();
+
if( mPrimaryCursor )
{
const CursorImpl& cursor = mCursor[PRIMARY_CURSOR];
mPrimaryCursor.SetPosition( position.x,
position.y );
- mPrimaryCursor.SetSize( Size( 1.0f, cursor.cursorHeight ) );
+ mPrimaryCursor.SetSize( Size( mCursorWidth, cursor.cursorHeight ) );
}
mPrimaryCursor.SetVisible( mPrimaryCursorVisible );
}
{
mSecondaryCursor.SetPosition( cursor.position.x,
cursor.position.y );
- mSecondaryCursor.SetSize( Size( 1.0f, cursor.cursorHeight ) );
+ mSecondaryCursor.SetSize( Size( mCursorWidth, cursor.cursorHeight ) );
}
mSecondaryCursor.SetVisible( mSecondaryCursorVisible );
}
CreateGrabHandle();
grabHandle.actor.SetPosition( position.x,
- position.y + grabHandle.lineHeight );
+ position.y + grabHandle.lineHeight ); // TODO : Fix for multiline.
}
grabHandle.actor.SetVisible( isVisible );
}
if( isPrimaryVisible )
{
primary.actor.SetPosition( primaryPosition.x,
- primaryPosition.y + primary.lineHeight );
+ primaryPosition.y + primary.lineHeight ); // TODO : Fix for multiline.
+
+ SetSelectionHandleMarkerSize( primary );
}
if( isSecondaryVisible )
{
secondary.actor.SetPosition( secondaryPosition.x,
- secondaryPosition.y + secondary.lineHeight );
+ secondaryPosition.y + secondary.lineHeight ); // TODO : Fix for multiline.
+
+ SetSelectionHandleMarkerSize( secondary );
}
}
primary.actor.SetVisible( isPrimaryVisible );
if( mActiveCopyPastePopup )
{
- if( !mCopyPastePopup.actor.GetParent() )
- {
- mActiveLayer.Add( mCopyPastePopup.actor );
- }
-
- mCopyPastePopup.actor.RaiseAbove( mActiveLayer );
+ ShowPopup();
}
else
{
if( mCopyPastePopup.actor )
{
- mCopyPastePopup.actor.Unparent();
+ mCopyPastePopup.actor.HidePopup();
}
}
}
DeterminePositionPopup();
}
+ void ShowPopup()
+ {
+ if ( !mCopyPastePopup.actor )
+ {
+ return;
+ }
+
+ if( !mCopyPastePopup.actor.GetParent() )
+ {
+ mActiveLayer.Add( mCopyPastePopup.actor );
+ }
+
+ mCopyPastePopup.actor.RaiseAbove( mActiveLayer );
+ mCopyPastePopup.actor.ShowPopup();
+ }
+
void DeterminePositionPopup()
{
if ( !mActiveCopyPastePopup )
void PopupRelayoutComplete( Actor actor )
{
// Size negotiation for CopyPastePopup complete so can get the size and constrain position within bounding box.
- mCopyPastePopup.actor.OnRelayoutSignal().Disconnect( this, &Decorator::Impl::PopupRelayoutComplete );
DeterminePositionPopup();
}
mActiveLayer.RaiseToTop();
}
+ void SetSelectionHandleMarkerSize( HandleImpl& handle )
+ {
+ if ( handle.markerActor )
+ {
+ handle.markerActor.SetResizePolicy ( ResizePolicy::FIXED, Dimension::HEIGHT );
+ handle.markerActor.SetSize( 0, handle.lineHeight );
+ }
+ }
+
void CreateGrabHandle()
{
HandleImpl& grabHandle = mHandle[GRAB_HANDLE];
}
}
- void CreateSelectionHandles()
+ void CreateHandleMarker( HandleImpl& handle, Image& image, HandleType handleType )
{
- HandleImpl& primary = mHandle[ LEFT_SELECTION_HANDLE ];
- if( !primary.actor )
+ if ( image)
{
- if( !mHandleImages[LEFT_SELECTION_HANDLE][HANDLE_IMAGE_RELEASED] )
+ handle.markerActor = ImageActor::New( image );
+ handle.markerActor.SetColor( mHandleColor );
+ handle.actor.Add( handle.markerActor );
+
+ if ( LEFT_SELECTION_HANDLE == handleType )
+ {
+ handle.markerActor.SetAnchorPoint( AnchorPoint::BOTTOM_RIGHT );
+ handle.markerActor.SetParentOrigin( ParentOrigin::TOP_RIGHT );
+ }
+ else if ( RIGHT_SELECTION_HANDLE == handleType )
{
- mHandleImages[LEFT_SELECTION_HANDLE][HANDLE_IMAGE_RELEASED] = ResourceImage::New( DEFAULT_SELECTION_HANDLE_ONE_RELEASED );
+ handle.markerActor.SetAnchorPoint( AnchorPoint::BOTTOM_LEFT );
+ handle.markerActor.SetParentOrigin( ParentOrigin::TOP_LEFT );
}
+ }
+ }
+ void CreateSelectionHandles()
+ {
+ HandleImpl& primary = mHandle[ LEFT_SELECTION_HANDLE ];
+ if( !primary.actor )
+ {
primary.actor = ImageActor::New( mHandleImages[LEFT_SELECTION_HANDLE][HANDLE_IMAGE_RELEASED] );
#ifdef DECORATOR_DEBUG
primary.actor.SetName("SelectionHandleOne");
primary.grabArea.TouchedSignal().Connect( this, &Decorator::Impl::OnHandleOneTouched );
primary.actor.Add( primary.grabArea );
+
+ CreateHandleMarker( primary, mHandleImages[LEFT_SELECTION_HANDLE_MARKER][HANDLE_IMAGE_RELEASED], LEFT_SELECTION_HANDLE );
}
if( !primary.actor.GetParent() )
HandleImpl& secondary = mHandle[ RIGHT_SELECTION_HANDLE ];
if( !secondary.actor )
{
- if( !mHandleImages[RIGHT_SELECTION_HANDLE][HANDLE_IMAGE_RELEASED] )
- {
- mHandleImages[RIGHT_SELECTION_HANDLE][HANDLE_IMAGE_RELEASED] = ResourceImage::New( DEFAULT_SELECTION_HANDLE_TWO_RELEASED );
- }
-
secondary.actor = ImageActor::New( mHandleImages[RIGHT_SELECTION_HANDLE][HANDLE_IMAGE_RELEASED] );
#ifdef DECORATOR_DEBUG
secondary.actor.SetName("SelectionHandleTwo");
secondary.grabArea.TouchedSignal().Connect( this, &Decorator::Impl::OnHandleTwoTouched );
secondary.actor.Add( secondary.grabArea );
+
+ CreateHandleMarker( secondary, mHandleImages[RIGHT_SELECTION_HANDLE_MARKER][HANDLE_IMAGE_RELEASED], RIGHT_SELECTION_HANDLE );
}
if( !secondary.actor.GetParent() )
mQuadVertices.SetData( &vertices[ 0 ] );
mQuadIndices.SetData( &indices[ 0 ] );
- mQuadGeometry = Geometry::New();
- mQuadGeometry.AddVertexBuffer( mQuadVertices );
- mQuadGeometry.SetIndexBuffer( mQuadIndices );
-
- if( mHighlightRenderer )
+ if( !mQuadGeometry )
{
- mHighlightRenderer.SetGeometry( mQuadGeometry );
+ mQuadGeometry = Geometry::New();
+ mQuadGeometry.AddVertexBuffer( mQuadVertices );
}
- else
+ mQuadGeometry.SetIndexBuffer( mQuadIndices );
+
+ if( !mHighlightRenderer )
{
mHighlightRenderer = Dali::Renderer::New( mQuadGeometry, mHighlightMaterial );
mHighlightActor.AddRenderer( mHighlightRenderer );
}
-
- mHighlightActor.SetPosition( mHighlightPosition.x,
- mHighlightPosition.y );
}
+ mHighlightActor.SetPosition( mHighlightPosition.x,
+ mHighlightPosition.y );
+
+ mHighlightQuadList.clear();
+
mHighlightRenderer.SetDepthIndex( mTextDepth - 2u ); // text is rendered at mTextDepth and text's shadow at mTextDepth -1u.
}
}
rightHandle.actor.SetImage( rightFlipped ? mHandleImages[LEFT_SELECTION_HANDLE][rightImageType] : mHandleImages[RIGHT_SELECTION_HANDLE][rightImageType] );
rightHandle.actor.SetAnchorPoint( rightFlipped ? AnchorPoint::TOP_RIGHT : AnchorPoint::TOP_LEFT );
+
+ if ( leftHandle.markerActor )
+ {
+ leftHandle.markerActor.SetImage( leftFlipped ? mHandleImages[RIGHT_SELECTION_HANDLE_MARKER][leftImageType] : mHandleImages[LEFT_SELECTION_HANDLE_MARKER][leftImageType] );
+ }
+ if ( rightHandle.markerActor )
+ {
+ rightHandle.markerActor.SetImage( rightFlipped ? mHandleImages[LEFT_SELECTION_HANDLE_MARKER][rightImageType] : mHandleImages[RIGHT_SELECTION_HANDLE_MARKER][rightImageType] );
+ }
}
void SetScrollThreshold( float threshold )
unsigned int mActiveCursor;
unsigned int mCursorBlinkInterval;
float mCursorBlinkDuration;
+ float mCursorWidth; ///< The width of the cursors in pixels.
HandleType mHandleScrolling; ///< The handle which is scrolling.
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.
return mImpl->mCursorBlinkDuration;
}
+void Decorator::SetCursorWidth( int width )
+{
+ mImpl->mCursorWidth = static_cast<float>( width );
+}
+
+int Decorator::GetCursorWidth() const
+{
+ return static_cast<int>( mImpl->mCursorWidth );
+}
+
/** Handles **/
void Decorator::SetHandleActive( HandleType handleType, bool active )
{
mImpl->mEnabledPopupButtons = enabledButtonsBitMask;
- UnparentAndReset( mImpl->mCopyPastePopup.actor );
- mImpl->mCopyPastePopup.actor = TextSelectionPopup::New( mImpl->mEnabledPopupButtons,
- &mImpl->mTextSelectionPopupCallbackInterface );
+ if ( !mImpl->mCopyPastePopup.actor )
+ {
+ mImpl->mCopyPastePopup.actor = TextSelectionPopup::New( &mImpl->mTextSelectionPopupCallbackInterface );
#ifdef DECORATOR_DEBUG
- mImpl->mCopyPastePopup.actor.SetName("mCopyPastePopup");
+ mImpl->mCopyPastePopup.actor.SetName("mCopyPastePopup");
#endif
- mImpl->mCopyPastePopup.actor.SetAnchorPoint( AnchorPoint::CENTER );
- mImpl->mCopyPastePopup.actor.OnRelayoutSignal().Connect( mImpl, &Decorator::Impl::PopupRelayoutComplete ); // Position popup after size negotiation
-
- if( mImpl->mActiveLayer )
- {
- mImpl->mActiveLayer.Add( mImpl->mCopyPastePopup.actor );
+ mImpl->mCopyPastePopup.actor.SetAnchorPoint( AnchorPoint::CENTER );
+ mImpl->mCopyPastePopup.actor.OnRelayoutSignal().Connect( mImpl, &Decorator::Impl::PopupRelayoutComplete ); // Position popup after size negotiation
}
+
+ mImpl->mCopyPastePopup.actor.EnableButtons( mImpl->mEnabledPopupButtons );
}
TextSelectionPopup::Buttons& Decorator::GetEnabledPopupButtons()