/*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2016 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.
// EXTERNAL INCLUDES
#include <dali/integration-api/debug.h>
-
-#include <dali/public-api/adaptor-framework/timer.h>
#include <dali/public-api/actors/layer.h>
+#include <dali/public-api/adaptor-framework/timer.h>
#include <dali/public-api/common/stage.h>
#include <dali/public-api/events/touch-data.h>
#include <dali/public-api/events/pan-gesture.h>
#include <dali/public-api/images/resource-image.h>
#include <dali/public-api/object/property-notification.h>
-
-#include <dali/devel-api/rendering/geometry.h>
-#include <dali/devel-api/rendering/renderer.h>
+#include <dali/public-api/rendering/geometry.h>
+#include <dali/public-api/rendering/renderer.h>
// INTERNAL INCLUDES
#include <dali-toolkit/public-api/controls/image-view/image-view.h>
const char* VERTEX_SHADER = MAKE_SHADER(
attribute mediump vec2 aPosition;
uniform mediump mat4 uMvpMatrix;
-uniform mediump vec3 uSize;
void main()
{
mediump vec4 position = vec4( aPosition, 0.0, 1.0 );
- position.xyz *= uSize;
gl_Position = uMvpMatrix * position;
}
);
const Dali::Vector4 HANDLE_COLOR( 0.0f, (183.0f / 255.0f), (229.0f / 255.0f), 1.0f );
-const unsigned int CURSOR_BLINK_INTERVAL = 500u; // Cursor blink interval
-const float TO_MILLISECONDS = 1000.f;
-const float TO_SECONDS = 1.f / TO_MILLISECONDS;
+const 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;
+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_THRESHOLD = 10.f;
-const float SCROLL_SPEED = 300.f;
-const float SCROLL_DISTANCE = SCROLL_SPEED * SCROLL_TICK_INTERVAL * TO_SECONDS;
+const float SCROLL_DISTANCE = SCROLL_SPEED * SCROLL_TICK_INTERVAL * TO_SECONDS; ///< Distance in pixels scrolled in one second.
-const float CURSOR_WIDTH = 1.f;
+const float CURSOR_WIDTH = 1.f; ///< The cursor's width in pixels.
/**
* structure to hold coordinates of each quad, which will make up the mesh.
{
HandleImpl()
: position(),
+ globalPosition(),
size(),
lineHeight( 0.0f ),
grabDisplacementX( 0.f ),
ImageView markerActor;
Vector2 position;
+ Vector2 globalPosition;
Size size;
float lineHeight; ///< Not the handle height
float grabDisplacementX;
mFlipSelectionHandlesOnCross( false ),
mFlipLeftSelectionHandleDirection( false ),
mFlipRightSelectionHandleDirection( false ),
- mHandlePanning( false ),
- mHandleCurrentCrossed( false ),
- mHandlePreviousCrossed( false ),
- mNotifyEndOfScroll( false )
+ mIsHandlePanning( false ),
+ mIsHandleCurrentlyCrossed( false ),
+ mIsHandlePreviouslyCrossed( false ),
+ mNotifyEndOfScroll( false ),
+ mHorizontalScrollingEnabled( false ),
+ mVerticalScrollingEnabled( false )
{
mQuadVertexFormat[ "aPosition" ] = Property::VECTOR2;
mHighlightShader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER );
if( mPrimaryCursor )
{
const CursorImpl& cursor = mCursor[PRIMARY_CURSOR];
- mPrimaryCursorVisible = ( cursor.position.x + mCursorWidth <= mControlSize.width ) && ( cursor.position.x >= 0.f );
+ mPrimaryCursorVisible = ( ( cursor.position.x + mCursorWidth <= mControlSize.width ) &&
+ ( cursor.position.x >= 0.f ) &&
+ ( cursor.position.y + cursor.cursorHeight <= mControlSize.height ) &&
+ ( cursor.position.y >= 0.f ) );
if( mPrimaryCursorVisible )
{
mPrimaryCursor.SetPosition( cursor.position.x,
if( mSecondaryCursor )
{
const CursorImpl& cursor = mCursor[SECONDARY_CURSOR];
- mSecondaryCursorVisible = ( cursor.position.x + mCursorWidth <= mControlSize.width ) && ( cursor.position.x >= 0.f );
+ mSecondaryCursorVisible = ( ( cursor.position.x + mCursorWidth <= mControlSize.width ) &&
+ ( cursor.position.x >= 0.f ) &&
+ ( cursor.position.y + cursor.cursorHeight <= mControlSize.height ) &&
+ ( cursor.position.y >= 0.f ) );
if( mSecondaryCursorVisible )
{
mSecondaryCursor.SetPosition( cursor.position.x,
bool newGrabHandlePosition = false;
if( grabHandle.active )
{
- const bool isVisible = ( grabHandle.position.x + floor( 0.5f * mCursorWidth ) <= mControlSize.width ) && ( grabHandle.position.x >= 0.f );
+ const bool isVisible = ( ( grabHandle.position.x + floor( 0.5f * mCursorWidth ) <= mControlSize.width ) &&
+ ( grabHandle.position.x >= 0.f ) &&
+ ( grabHandle.position.y <= mControlSize.height - grabHandle.lineHeight ) &&
+ ( grabHandle.position.y >= 0.f ) );
if( isVisible )
{
bool newSecondaryHandlePosition = false;
if( primary.active || secondary.active )
{
- const bool isPrimaryVisible = ( primary.position.x <= mControlSize.width ) && ( primary.position.x >= 0.f );
- const bool isSecondaryVisible = ( secondary.position.x <= mControlSize.width ) && ( secondary.position.x >= 0.f );
+ const bool isPrimaryVisible = ( ( primary.position.x <= mControlSize.width ) &&
+ ( primary.position.x >= 0.f ) &&
+ ( primary.position.y <= mControlSize.height - primary.lineHeight ) &&
+ ( primary.position.y >= 0.f ) );
+ const bool isSecondaryVisible = ( ( secondary.position.x <= mControlSize.width ) &&
+ ( secondary.position.x >= 0.f ) &&
+ ( secondary.position.y <= mControlSize.height - secondary.lineHeight ) &&
+ ( secondary.position.y >= 0.f ) );
if( isPrimaryVisible || isSecondaryVisible )
{
void SetupGestures()
{
+ // Will consume tap gestures on handles.
mTapDetector = TapGestureDetector::New();
- mTapDetector.DetectedSignal().Connect( this, &Decorator::Impl::OnTap );
- mPanGestureDetector = PanGestureDetector::New();
- mPanGestureDetector.DetectedSignal().Connect( this, &Decorator::Impl::OnPan );
+ // Will consume double tap gestures on handles.
+ 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 );
}
void CreateActiveLayer()
grabHandle.actor.SetColor( mHandleColor );
grabHandle.grabArea.TouchSignal().Connect( this, &Decorator::Impl::OnGrabHandleTouched );
- mTapDetector.Attach( grabHandle.grabArea );
- mPanGestureDetector.Attach( grabHandle.grabArea );
+
+ // 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 );
+
+ // 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 );
mActiveLayer.Add( grabHandle.actor );
}
primary.grabArea.SetAnchorPoint( AnchorPoint::TOP_CENTER );
primary.grabArea.SetSizeModeFactor( DEFAULT_SELECTION_HANDLE_RELATIVE_SIZE );
- mTapDetector.Attach( primary.grabArea );
- mPanGestureDetector.Attach( primary.grabArea );
primary.grabArea.TouchSignal().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 );
+
+ // 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 );
+
primary.actor.Add( primary.grabArea );
CreateHandleMarker( primary, mHandleImages[LEFT_SELECTION_HANDLE_MARKER][HANDLE_IMAGE_RELEASED], LEFT_SELECTION_HANDLE );
secondary.grabArea.SetAnchorPoint( AnchorPoint::TOP_CENTER );
secondary.grabArea.SetSizeModeFactor( DEFAULT_SELECTION_HANDLE_RELATIVE_SIZE );
- mTapDetector.Attach( secondary.grabArea );
- mPanGestureDetector.Attach( secondary.grabArea );
secondary.grabArea.TouchSignal().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 );
+
+ // 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 );
+
secondary.actor.Add( secondary.grabArea );
CreateHandleMarker( secondary, mHandleImages[RIGHT_SELECTION_HANDLE_MARKER][HANDLE_IMAGE_RELEASED], RIGHT_SELECTION_HANDLE );
// 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;
- position.y = parentWorldPosition.y - 0.5f * mControlSize.height + handle.position.y;
+ 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()
if( grabHandle.actor )
{
- grabHandle.actor.SetPosition( grabHandle.position.x + floor( 0.5f * mCursorWidth ),
- yLocalPosition ); // TODO : Fix for multiline.
+ grabHandle.actor.SetPosition( grabHandle.position.x + floor( 0.5f * mCursorWidth ) + ( mSmoothHandlePanEnabled ? grabHandle.grabDisplacementX : 0.f ),
+ yLocalPosition + ( mSmoothHandlePanEnabled ? grabHandle.grabDisplacementY : 0.f ) );
}
}
// Whether to flip the handles if they are crossed.
bool crossFlip = false;
- if( mFlipSelectionHandlesOnCross || !mHandlePanning )
+ if( mFlipSelectionHandlesOnCross || !mIsHandlePanning )
{
- crossFlip = mHandleCurrentCrossed;
+ crossFlip = mIsHandleCurrentlyCrossed;
}
+ // Whether the handle was crossed before start the panning.
+ const bool isHandlePreviouslyCrossed = mFlipSelectionHandlesOnCross ? false : mIsHandlePreviouslyCrossed;
+
// Does not flip if both conditions are true (double flip)
- flipHandle = flipHandle != ( crossFlip || mHandlePreviousCrossed );
+ flipHandle = flipHandle != ( crossFlip || isHandlePreviouslyCrossed );
// Will flip the handles vertically if the user prefers it.
bool verticallyFlippedPreferred = handle.verticallyFlippedPreferred;
- if( crossFlip || mHandlePreviousCrossed )
+ if( crossFlip || isHandlePreviouslyCrossed )
{
if( isPrimaryHandle )
{
if( handle.actor )
{
- handle.actor.SetPosition( handle.position.x,
- yLocalPosition ); // TODO : Fix for multiline.
+ handle.actor.SetPosition( handle.position.x + ( mSmoothHandlePanEnabled ? handle.grabDisplacementX : 0.f ),
+ yLocalPosition + ( mSmoothHandlePanEnabled ? handle.grabDisplacementY : 0.f ) );
}
}
#ifdef DECORATOR_DEBUG
mHighlightActor.SetName( "HighlightActor" );
#endif
+ mHighlightActor.SetParentOrigin( ParentOrigin::TOP_LEFT );
mHighlightActor.SetAnchorPoint( AnchorPoint::TOP_LEFT );
- mHighlightActor.SetSize( 1.0f, 1.0f );
mHighlightActor.SetColor( mHighlightColor );
mHighlightActor.SetColorMode( USE_OWN_COLOR );
}
{
if ( mHighlightActor )
{
- if( !mHighlightQuadList.empty() )
+ // Sets the position of the highlight actor inside the decorator.
+ mHighlightActor.SetPosition( mHighlightPosition.x,
+ mHighlightPosition.y );
+
+ const unsigned int numberOfQuads = mHighlightQuadList.size();
+ if( 0u != numberOfQuads )
{
- Vector< Vector2 > vertices;
- Vector< unsigned short> indices;
- Vector2 vertex;
+ // Set the size of the highlighted text to the actor.
+ mHighlightActor.SetSize( mHighlightSize );
- std::vector<QuadCoordinates>::iterator iter = mHighlightQuadList.begin();
- std::vector<QuadCoordinates>::iterator endIter = mHighlightQuadList.end();
+ // 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;
- for( std::size_t v = 0; iter != endIter; ++iter,v+=4 )
+ Vector<Vector2> vertices;
+ Vector<unsigned short> indices;
+
+ vertices.Reserve( 4u * numberOfQuads );
+ indices.Reserve( 6u * numberOfQuads );
+
+ // Index to the vertex.
+ unsigned int v = 0u;
+
+ // Traverse all quads.
+ for( std::vector<QuadCoordinates>::iterator it = mHighlightQuadList.begin(),
+ endIt = mHighlightQuadList.end();
+ it != endIt;
+ ++it, v += 4u )
{
- QuadCoordinates& quad = *iter;
+ QuadCoordinates& quad = *it;
+
+ Vector2 vertex;
// top-left (v+0)
- vertex.x = quad.min.x;
- vertex.y = quad.min.y;
+ vertex.x = quad.min.x - offsetX;
+ vertex.y = quad.min.y - offsetY;
vertices.PushBack( vertex );
// top-right (v+1)
- vertex.x = quad.max.x;
- vertex.y = quad.min.y;
+ vertex.x = quad.max.x - offsetX;
+ vertex.y = quad.min.y - offsetY;
vertices.PushBack( vertex );
// bottom-left (v+2)
- vertex.x = quad.min.x;
- vertex.y = quad.max.y;
+ vertex.x = quad.min.x - offsetX;
+ vertex.y = quad.max.y - offsetY;
vertices.PushBack( vertex );
// bottom-right (v+3)
- vertex.x = quad.max.x;
- vertex.y = quad.max.y;
+ vertex.x = quad.max.x - offsetX;
+ vertex.y = quad.max.y - offsetY;
vertices.PushBack( vertex );
// triangle A (3, 1, 0)
}
}
- mHighlightActor.SetPosition( mHighlightPosition.x,
- mHighlightPosition.y );
-
mHighlightQuadList.clear();
if( mHighlightRenderer )
}
}
- void OnTap( Actor actor, const TapGesture& tap )
- {
- if( actor == mHandle[GRAB_HANDLE].actor )
- {
- // TODO
- }
- }
-
void DoPan( HandleImpl& handle, HandleType type, const PanGesture& gesture )
{
if( Gesture::Started == gesture.state )
{
handle.grabDisplacementX = handle.grabDisplacementY = 0.f;
+
+ handle.globalPosition.x = handle.position.x;
+ handle.globalPosition.y = handle.position.y;
}
handle.grabDisplacementX += gesture.displacement.x;
handle.grabDisplacementY += ( handle.verticallyFlipped ? -gesture.displacement.y : gesture.displacement.y );
- const float x = handle.position.x + handle.grabDisplacementX;
- const float y = handle.position.y + handle.lineHeight*0.5f + handle.grabDisplacementY;
+ 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.verticallyFlipped ? handle.lineHeight : 0.f );
- if( Gesture::Started == gesture.state ||
- Gesture::Continuing == gesture.state )
+ if( ( Gesture::Started == gesture.state ) ||
+ ( Gesture::Continuing == gesture.state ) )
{
Vector2 targetSize;
mController.GetTargetSize( targetSize );
- if( x < mScrollThreshold )
+ if( mHorizontalScrollingEnabled &&
+ ( x < mScrollThreshold ) )
{
mScrollDirection = SCROLL_RIGHT;
mHandleScrolling = type;
StartScrollTimer();
}
- else if( x > targetSize.width - mScrollThreshold )
+ else if( mHorizontalScrollingEnabled &&
+ ( x > targetSize.width - mScrollThreshold ) )
{
mScrollDirection = SCROLL_LEFT;
mHandleScrolling = type;
StartScrollTimer();
}
+ else if( mVerticalScrollingEnabled &&
+ ( yVerticallyFlippedCorrected < mScrollThreshold ) )
+ {
+ mScrollDirection = SCROLL_TOP;
+ mHandleScrolling = type;
+ StartScrollTimer();
+ }
+ else if( mVerticalScrollingEnabled &&
+ ( yVerticallyFlippedCorrected + handle.lineHeight > targetSize.height - mScrollThreshold ) )
+ {
+ mScrollDirection = SCROLL_BOTTOM;
+ mHandleScrolling = type;
+ StartScrollTimer();
+ }
else
{
mHandleScrolling = HANDLE_TYPE_COUNT;
mController.DecorationEvent( type, HANDLE_PRESSED, x, y );
}
- mHandlePanning = true;
+ mIsHandlePanning = true;
}
- else if( Gesture::Finished == gesture.state ||
- Gesture::Cancelled == gesture.state )
+ else if( ( Gesture::Finished == gesture.state ) ||
+ ( Gesture::Cancelled == gesture.state ) )
{
if( mScrollTimer &&
( mScrollTimer.IsRunning() || mNotifyEndOfScroll ) )
}
handle.pressed = false;
- mHandlePanning = false;
+ mIsHandlePanning = false;
}
}
bool OnGrabHandleTouched( Actor actor, const TouchData& touch )
{
+ HandleImpl& grabHandle = mHandle[GRAB_HANDLE];
+
// Switch between pressed/release grab-handle images
if( touch.GetPointCount() > 0 &&
- mHandle[GRAB_HANDLE].actor )
+ grabHandle.actor )
{
const PointState::Type state = touch.GetState( 0 );
if( PointState::DOWN == state )
{
- mHandle[GRAB_HANDLE].pressed = true;
+ grabHandle.pressed = true;
}
else if( ( PointState::UP == state ) ||
( PointState::INTERRUPTED == state ) )
{
- mHandle[GRAB_HANDLE].pressed = false;
+ grabHandle.pressed = false;
}
SetHandleImage( GRAB_HANDLE );
bool OnHandleOneTouched( Actor actor, const TouchData& touch )
{
+ HandleImpl& primarySelectionHandle = mHandle[LEFT_SELECTION_HANDLE];
+
// Switch between pressed/release selection handle images
if( touch.GetPointCount() > 0 &&
- mHandle[LEFT_SELECTION_HANDLE].actor )
+ primarySelectionHandle.actor )
{
const PointState::Type state = touch.GetState( 0 );
if( PointState::DOWN == state )
{
- mHandle[LEFT_SELECTION_HANDLE].pressed = true;
+ primarySelectionHandle.pressed = true;
}
else if( ( PointState::UP == state ) ||
( PointState::INTERRUPTED == state ) )
{
- mHandle[LEFT_SELECTION_HANDLE].pressed = false;
- mHandlePreviousCrossed = mHandleCurrentCrossed;
- mHandlePanning = false;
+ primarySelectionHandle.pressed = false;
+ mIsHandlePreviouslyCrossed = mIsHandleCurrentlyCrossed;
+ mIsHandlePanning = false;
}
SetHandleImage( LEFT_SELECTION_HANDLE );
bool OnHandleTwoTouched( Actor actor, const TouchData& touch )
{
+ HandleImpl& secondarySelectionHandle = mHandle[RIGHT_SELECTION_HANDLE];
+
// Switch between pressed/release selection handle images
if( touch.GetPointCount() > 0 &&
- mHandle[RIGHT_SELECTION_HANDLE].actor )
+ secondarySelectionHandle.actor )
{
const PointState::Type state = touch.GetState( 0 );
if( PointState::DOWN == state )
{
- mHandle[RIGHT_SELECTION_HANDLE].pressed = true;
+ secondarySelectionHandle.pressed = true;
}
else if( ( PointState::UP == state ) ||
( PointState::INTERRUPTED == state ) )
{
- mHandle[RIGHT_SELECTION_HANDLE].pressed = false;
- mHandlePreviousCrossed = mHandleCurrentCrossed;
- mHandlePanning = false;
+ secondarySelectionHandle.pressed = false;
+ mIsHandlePreviouslyCrossed = mIsHandleCurrentlyCrossed;
+ mIsHandlePanning = false;
}
SetHandleImage( RIGHT_SELECTION_HANDLE );
{
if( HANDLE_TYPE_COUNT != mHandleScrolling )
{
+ float x = 0.f;
+ float y = 0.f;
+
+ switch( mScrollDirection )
+ {
+ case SCROLL_RIGHT:
+ {
+ x = mScrollDistance;
+ break;
+ }
+ case SCROLL_LEFT:
+ {
+ x = -mScrollDistance;
+ break;
+ }
+ case SCROLL_TOP:
+ {
+ y = mScrollDistance;
+ break;
+ }
+ case SCROLL_BOTTOM:
+ {
+ y = -mScrollDistance;
+ break;
+ }
+ default:
+ break;
+ }
+
mController.DecorationEvent( mHandleScrolling,
HANDLE_SCROLLING,
- mScrollDirection == SCROLL_RIGHT ? mScrollDistance : -mScrollDistance,
- 0.f );
+ x,
+ y );
}
return true;
ControllerInterface& mController;
- TapGestureDetector mTapDetector;
- PanGestureDetector mPanGestureDetector;
+ TapGestureDetector mTapDetector;
+ 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.
Vector4 mBoundingBox; ///< The bounding box in world coords.
Vector4 mHighlightColor; ///< Color of the highlight
Vector2 mHighlightPosition; ///< The position of the highlight actor.
- Vector2 mControlSize; ///< The control's size. Set by the Relayout.
+ Size mHighlightSize; ///< The size of the highlighted text.
+ Size mControlSize; ///< The control's size. Set by the Relayout.
unsigned int mActiveCursor;
unsigned int mCursorBlinkInterval;
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 mHandlePanning : 1; ///< Whether any of the handles is moving.
- bool mHandleCurrentCrossed : 1; ///< Whether the handles are crossed.
- bool mHandlePreviousCrossed : 1; ///< Whether the handles where crossed at the last handle touch up.
+ 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.
};
DecoratorPtr Decorator::New( ControllerInterface& controller,
void Decorator::SetPosition( Cursor cursor, float x, float y, float cursorHeight, float lineHeight )
{
- mImpl->mCursor[cursor].position.x = x;
- mImpl->mCursor[cursor].position.y = y;
- mImpl->mCursor[cursor].cursorHeight = cursorHeight;
- mImpl->mCursor[cursor].lineHeight = lineHeight;
+ Impl::CursorImpl& cursorImpl = mImpl->mCursor[cursor];
+
+ cursorImpl.position.x = x;
+ cursorImpl.position.y = y;
+ cursorImpl.cursorHeight = cursorHeight;
+ cursorImpl.lineHeight = lineHeight;
}
void Decorator::GetPosition( Cursor cursor, float& x, float& y, float& cursorHeight, float& lineHeight ) const
{
- x = mImpl->mCursor[cursor].position.x;
- y = mImpl->mCursor[cursor].position.y;
- cursorHeight = mImpl->mCursor[cursor].cursorHeight;
- lineHeight = mImpl->mCursor[cursor].lineHeight;
+ const Impl::CursorImpl& cursorImpl = mImpl->mCursor[cursor];
+
+ x = cursorImpl.position.x;
+ y = cursorImpl.position.y;
+ cursorHeight = cursorImpl.cursorHeight;
+ lineHeight = cursorImpl.lineHeight;
}
const Vector2& Decorator::GetPosition( Cursor cursor ) const
{
if( ( LEFT_SELECTION_HANDLE == handleType ) || ( RIGHT_SELECTION_HANDLE == handleType ) )
{
- mImpl->mHandlePreviousCrossed = false;
+ mImpl->mIsHandlePreviouslyCrossed = false;
}
// TODO: this is a work-around.
// Adjust handle's displacement
Impl::HandleImpl& handle = mImpl->mHandle[handleType];
- handle.grabDisplacementX -= x - handle.position.x;
- handle.grabDisplacementY -= y - handle.position.y;
-
handle.position.x = x;
handle.position.y = y;
handle.lineHeight = height;
+
+ 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::SetSelectionHandleFlipState( bool indicesSwapped, bool left, bool right )
{
- mImpl->mHandleCurrentCrossed = indicesSwapped;
+ mImpl->mIsHandleCurrentlyCrossed = indicesSwapped;
mImpl->mFlipLeftSelectionHandleDirection = left;
mImpl->mFlipRightSelectionHandleDirection = right;
}
mImpl->mHighlightQuadList.push_back( QuadCoordinates(x1, y1, x2, y2) );
}
+void Decorator::SetHighLightBox( const Vector2& position, const Size& size )
+{
+ mImpl->mHighlightPosition = position;
+ mImpl->mHighlightSize = size;
+}
+
void Decorator::ClearHighlights()
{
mImpl->mHighlightQuadList.clear();
mImpl->NotifyEndOfScroll();
}
+void Decorator::SetHorizontalScrollEnabled( bool enable )
+{
+ mImpl->mHorizontalScrollingEnabled = enable;
+}
+
+bool Decorator::IsHorizontalScrollEnabled() const
+{
+ return mImpl->mHorizontalScrollingEnabled;
+}
+
+void Decorator::SetVerticalScrollEnabled( bool enable )
+{
+ mImpl->mVerticalScrollingEnabled = enable;
+}
+
+bool Decorator::IsVerticalScrollEnabled() const
+{
+ return mImpl->mVerticalScrollingEnabled;
+}
+
+void Decorator::SetSmoothHandlePanEnabled( bool enable )
+{
+ mImpl->mSmoothHandlePanEnabled = enable;
+}
+
+bool Decorator::IsSmoothHandlePanEnabled() const
+{
+ return mImpl->mSmoothHandlePanEnabled;
+}
+
Decorator::~Decorator()
{
delete mImpl;