#include <dali/public-api/adaptor-framework/timer.h>
#include <dali/public-api/actors/layer.h>
#include <dali/public-api/common/stage.h>
-#include <dali/public-api/events/touch-event.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>
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;
- mQuadIndexFormat[ "indices" ] = Property::INTEGER;
mHighlightShader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER );
- SetupTouchEvents();
+ SetupGestures();
}
/**
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 )
{
{
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];
if( primaryHandle.active || secondaryHandle.active )
else
{
// Calculates the popup's position if the grab handle is active.
- mCopyPastePopup.position = Vector3( cursor.position.x, -0.5f * popupSize.height - grabHandle.size.height + cursor.position.y, 0.0f );
+ const HandleImpl& grabHandle = mHandle[GRAB_HANDLE];
+ if( grabHandle.verticallyFlipped )
+ {
+ mCopyPastePopup.position = Vector3( cursor.position.x, -0.5f * popupSize.height - grabHandle.size.height + cursor.position.y, 0.0f );
+ }
+ else
+ {
+ mCopyPastePopup.position = Vector3( cursor.position.x, -0.5f * popupSize.height + cursor.position.y, 0.0f );
+ }
}
}
return true;
}
- void SetupTouchEvents()
+ 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.Add( grabHandle.grabArea );
grabHandle.actor.SetColor( mHandleColor );
- grabHandle.grabArea.TouchedSignal().Connect( this, &Decorator::Impl::OnGrabHandleTouched );
- mTapDetector.Attach( grabHandle.grabArea );
- mPanGestureDetector.Attach( grabHandle.grabArea );
+ grabHandle.grabArea.TouchSignal().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 );
+
+ // 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.TouchedSignal().Connect( this, &Decorator::Impl::OnHandleOneTouched );
+ 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 );
secondary.grabArea.SetAnchorPoint( AnchorPoint::TOP_CENTER );
secondary.grabArea.SetSizeModeFactor( DEFAULT_SELECTION_HANDLE_RELATIVE_SIZE );
- mTapDetector.Attach( secondary.grabArea );
- mPanGestureDetector.Attach( secondary.grabArea );
- secondary.grabArea.TouchedSignal().Connect( this, &Decorator::Impl::OnHandleTwoTouched );
+ 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 );
// 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 ) );
}
}
if( !mHighlightQuadList.empty() )
{
Vector< Vector2 > vertices;
- Vector< unsigned int> indices;
+ Vector< unsigned short> indices;
Vector2 vertex;
std::vector<QuadCoordinates>::iterator iter = mHighlightQuadList.begin();
mQuadVertices = PropertyBuffer::New( mQuadVertexFormat );
}
- if( ! mQuadIndices )
- {
- mQuadIndices = PropertyBuffer::New( mQuadIndexFormat );
- }
-
mQuadVertices.SetData( &vertices[ 0 ], vertices.Size() );
- mQuadIndices.SetData( &indices[ 0 ], indices.Size() );
if( !mQuadGeometry )
{
mQuadGeometry = Geometry::New();
mQuadGeometry.AddVertexBuffer( mQuadVertices );
}
- mQuadGeometry.SetIndexBuffer( mQuadIndices );
+ mQuadGeometry.SetIndexBuffer( &indices[ 0 ], indices.Size() );
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;
+ 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 += gesture.displacement.y;
+ 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 TouchEvent& event )
+ bool OnGrabHandleTouched( Actor actor, const TouchData& touch )
{
+ HandleImpl& grabHandle = mHandle[GRAB_HANDLE];
+
// Switch between pressed/release grab-handle images
- if( event.GetPointCount() > 0 &&
- mHandle[GRAB_HANDLE].actor )
+ if( touch.GetPointCount() > 0 &&
+ grabHandle.actor )
{
- const TouchPoint& point = event.GetPoint(0);
+ const PointState::Type state = touch.GetState( 0 );
- if( TouchPoint::Down == point.state )
+ if( PointState::DOWN == state )
{
- mHandle[GRAB_HANDLE].pressed = true;
+ grabHandle.pressed = true;
}
- else if( ( TouchPoint::Up == point.state ) ||
- ( TouchPoint::Interrupted == point.state ) )
+ else if( ( PointState::UP == state ) ||
+ ( PointState::INTERRUPTED == state ) )
{
- mHandle[GRAB_HANDLE].pressed = false;
+ grabHandle.pressed = false;
}
SetHandleImage( GRAB_HANDLE );
return true;
}
- bool OnHandleOneTouched( Actor actor, const TouchEvent& event )
+ bool OnHandleOneTouched( Actor actor, const TouchData& touch )
{
+ HandleImpl& primarySelectionHandle = mHandle[LEFT_SELECTION_HANDLE];
+
// Switch between pressed/release selection handle images
- if( event.GetPointCount() > 0 &&
- mHandle[LEFT_SELECTION_HANDLE].actor )
+ if( touch.GetPointCount() > 0 &&
+ primarySelectionHandle.actor )
{
- const TouchPoint& point = event.GetPoint(0);
+ const PointState::Type state = touch.GetState( 0 );
- if( TouchPoint::Down == point.state )
+ if( PointState::DOWN == state )
{
- mHandle[LEFT_SELECTION_HANDLE].pressed = true;
+ primarySelectionHandle.pressed = true;
}
- else if( ( TouchPoint::Up == point.state ) ||
- ( TouchPoint::Interrupted == point.state ) )
+ 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 );
return true;
}
- bool OnHandleTwoTouched( Actor actor, const TouchEvent& event )
+ bool OnHandleTwoTouched( Actor actor, const TouchData& touch )
{
+ HandleImpl& secondarySelectionHandle = mHandle[RIGHT_SELECTION_HANDLE];
+
// Switch between pressed/release selection handle images
- if( event.GetPointCount() > 0 &&
- mHandle[RIGHT_SELECTION_HANDLE].actor )
+ if( touch.GetPointCount() > 0 &&
+ secondarySelectionHandle.actor )
{
- const TouchPoint& point = event.GetPoint(0);
+ const PointState::Type state = touch.GetState( 0 );
- if( TouchPoint::Down == point.state )
+ if( PointState::DOWN == state )
{
- mHandle[RIGHT_SELECTION_HANDLE].pressed = true;
+ secondarySelectionHandle.pressed = true;
}
- else if( ( TouchPoint::Up == point.state ) ||
- ( TouchPoint::Interrupted == point.state ) )
+ 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.
Renderer mHighlightRenderer;
Shader mHighlightShader; ///< Shader used for highlight
Property::Map mQuadVertexFormat;
- Property::Map mQuadIndexFormat;
PopupImpl mCopyPastePopup;
TextSelectionPopup::Buttons mEnabledPopupButtons; /// Bit mask of currently enabled Popup buttons
TextSelectionPopupCallbackInterface& mTextSelectionPopupCallbackInterface;
HandleImpl mHandle[HANDLE_TYPE_COUNT];
PropertyBuffer mQuadVertices;
- PropertyBuffer mQuadIndices;
Geometry mQuadGeometry;
QuadContainer mHighlightQuadList; ///< Sub-selections that combine to create the complete selection highlight
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->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;