From: Paul Wisbey Date: Sun, 1 Mar 2015 13:39:27 +0000 (+0000) Subject: Copied some TextInput grab/selection handle code X-Git-Tag: new_text_0.1~32 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=commitdiff_plain;h=0ae54c139d553cd05ba466a102ec18cf2cf11e81 Copied some TextInput grab/selection handle code Change-Id: Id65562d557cd2017e3d54f44e9e764a34ad73697 --- diff --git a/dali-toolkit/internal/controls/text-controls/text-field-impl.cpp b/dali-toolkit/internal/controls/text-controls/text-field-impl.cpp index 4ebda6f..53c5705 100644 --- a/dali-toolkit/internal/controls/text-controls/text-field-impl.cpp +++ b/dali-toolkit/internal/controls/text-controls/text-field-impl.cpp @@ -32,8 +32,11 @@ using namespace Dali::Toolkit::Text; namespace { +const unsigned int DEFAULT_RENDERING_BACKEND = 0; + } // namespace + namespace Dali { @@ -300,12 +303,23 @@ void TextField::OnInitialize() // Forward input events to controller EnableGestureDetection( Gesture::Tap ); + + // TODO - Fix TapGestureDetector to support single and double tap + mDoubleTapDetector = TapGestureDetector::New(); + mDoubleTapDetector.SetTapsRequired( 2 ); + mDoubleTapDetector.DetectedSignal().Connect( this, &TextField::OnDoubleTap ); + mDoubleTapDetector.Attach(Self()); } void TextField::OnRelayout( const Vector2& size, ActorSizeContainer& container ) { if( mController->Relayout( size ) ) { + if( mDecorator ) + { + mDecorator->Relayout( size ); + } + if( !mRenderer ) { mRenderer = Backend::Get().NewRenderer( mRenderingBackend ); @@ -325,7 +339,12 @@ void TextField::OnRelayout( const Vector2& size, ActorSizeContainer& container ) void TextField::OnTap( const TapGesture& tap ) { - mController->TapEvent( tap.localPoint.x, tap.localPoint.y ); + mController->TapEvent( tap.numberOfTaps, tap.localPoint.x, tap.localPoint.y ); +} + +void TextField::OnDoubleTap( Actor actor, const TapGesture& tap ) +{ + mController->TapEvent( tap.numberOfTaps, tap.localPoint.x, tap.localPoint.y ); } void TextField::RequestTextRelayout() @@ -334,7 +353,8 @@ void TextField::RequestTextRelayout() } TextField::TextField() -: Control( ControlBehaviour( CONTROL_BEHAVIOUR_NONE ) ) +: Control( ControlBehaviour( CONTROL_BEHAVIOUR_NONE ) ), + mRenderingBackend( DEFAULT_RENDERING_BACKEND ) { } diff --git a/dali-toolkit/internal/controls/text-controls/text-field-impl.h b/dali-toolkit/internal/controls/text-controls/text-field-impl.h index 443e3e1..7b013f5 100644 --- a/dali-toolkit/internal/controls/text-controls/text-field-impl.h +++ b/dali-toolkit/internal/controls/text-controls/text-field-impl.h @@ -89,6 +89,11 @@ private: // From Control virtual void OnTap( const TapGesture& tap ); /** + * TODO - Fix TapGestureDetector to support single and double tap + */ + void OnDoubleTap( Actor actor, const TapGesture& tap ); + + /** * @copydoc Text::ControlInterface::RequestTextRelayout() */ virtual void RequestTextRelayout(); @@ -117,6 +122,8 @@ private: // Data Text::RendererPtr mRenderer; Text::DecoratorPtr mDecorator; + TapGestureDetector mDoubleTapDetector; + unsigned int mRenderingBackend; }; diff --git a/dali-toolkit/public-api/text/decorator/text-decorator.cpp b/dali-toolkit/public-api/text/decorator/text-decorator.cpp index 4a7f666..0503635 100644 --- a/dali-toolkit/public-api/text/decorator/text-decorator.cpp +++ b/dali-toolkit/public-api/text/decorator/text-decorator.cpp @@ -19,10 +19,41 @@ #include // EXTERNAL INCLUDES +#include +#include +#include #include -#include +#include +#include +#include +#include +#include #include #include +#include + +// INTERNAL INCLUDES +#include +#include + +#ifdef DEBUG_ENABLED +#define DECORATOR_DEBUG +#endif + +// Local Data +namespace +{ + +const char* DEFAULT_GRAB_HANDLE_IMAGE( DALI_IMAGE_DIR "insertpoint-icon.png" ); +const char* DEFAULT_SELECTION_HANDLE_ONE( DALI_IMAGE_DIR "text-input-selection-handle-left.png" ); +const char* DEFAULT_SELECTION_HANDLE_TWO( DALI_IMAGE_DIR "text-input-selection-handle-right.png" ); +//const char* DEFAULT_SELECTION_HANDLE_ONE_PRESSED( DALI_IMAGE_DIR "text-input-selection-handle-left-press.png" ); +//const char* DEFAULT_SELECTION_HANDLE_TWO_PRESSED( DALI_IMAGE_DIR "text-input-selection-handle-right-press.png" ); + +const Dali::Vector3 DEFAULT_GRAB_HANDLE_RELATIVE_SIZE( 1.5f, 2.0f, 1.0f ); +const Dali::Vector3 DEFAULT_SELECTION_HANDLE_RELATIVE_SIZE( 1.5f, 1.5f, 1.0f ); + +} // end of namespace namespace Dali { @@ -33,7 +64,7 @@ namespace Toolkit namespace Text { -struct Decorator::Impl +struct Decorator::Impl : public ConnectionTracker { struct CursorImpl { @@ -52,10 +83,33 @@ struct Decorator::Impl Vector4 color; }; - Impl(Dali::Toolkit::Internal::Control& parent, Observer& observer) + struct SelectionHandleImpl + { + SelectionHandleImpl() + : x(0.0f), + y(0.0f), + cursorHeight(0.0f), + flipped(false) + { + } + + float x; + float y; + float cursorHeight; ///< Not the handle height + bool flipped; + + ImageActor actor; + Actor grabArea; + + Image pressedImage; + Image releasedImage; + }; + + Impl( Dali::Toolkit::Internal::Control& parent, Observer& observer ) : mParent(parent), mObserver(observer), mActiveCursor(ACTIVE_CURSOR_NONE), + mActiveGrabHandle(false), mCursorBlinkInterval(0.5f), mCursorBlinkDuration(0.0f) { @@ -63,19 +117,237 @@ struct Decorator::Impl void Relayout( const Vector2& size ) { + // Show or hide the grab handle + if( mActiveGrabHandle ) + { + SetupTouchEvents(); + + CreateActiveLayer(); + CreateGrabHandle(); + + mGrabHandle.SetPosition( mCursor[PRIMARY_CURSOR].x, mCursor[PRIMARY_CURSOR].y + mCursor[PRIMARY_CURSOR].height ); + } + else if( mGrabHandle ) + { + UnparentAndReset( mGrabHandle ); + } + + // Show or hide the selection handles/highlight + if( mActiveSelection ) + { + SetupTouchEvents(); + + CreateActiveLayer(); + CreateSelectionHandles(); + + SelectionHandleImpl& primary = mSelectionHandle[ PRIMARY_SELECTION_HANDLE ]; + primary.actor.SetPosition( primary.x, primary.y + primary.cursorHeight ); + + SelectionHandleImpl& secondary = mSelectionHandle[ SECONDARY_SELECTION_HANDLE ]; + secondary.actor.SetPosition( secondary.x, secondary.y + secondary.cursorHeight ); + + //CreateHighlight(); TODO + } + else + { + UnparentAndReset( mSelectionHandle[ PRIMARY_SELECTION_HANDLE ].actor ); + UnparentAndReset( mSelectionHandle[ SECONDARY_SELECTION_HANDLE ].actor ); + } + // TODO } + void SetupTouchEvents() + { + if ( !mTapDetector ) + { + mTapDetector = TapGestureDetector::New(); + mTapDetector.DetectedSignal().Connect( this, &Decorator::Impl::OnTap ); + } + + if ( !mPanGestureDetector ) + { + mPanGestureDetector = PanGestureDetector::New(); + mPanGestureDetector.DetectedSignal().Connect( this, &Decorator::Impl::OnPan ); + } + } + + void CreateActiveLayer() + { + if( !mActiveLayer ) + { + Actor parent = mParent.Self(); + + mActiveLayer = Layer::New(); +#ifdef DECORATOR_DEBUG + mActiveLayer.SetName ( "ActiveLayerActor" ); +#endif + + mActiveLayer.SetAnchorPoint( AnchorPoint::CENTER); + mActiveLayer.SetParentOrigin( ParentOrigin::CENTER); + mActiveLayer.SetSizeMode( SIZE_EQUAL_TO_PARENT ); + mActiveLayer.SetPositionInheritanceMode( USE_PARENT_POSITION ); + + parent.Add( mActiveLayer ); + } + + mActiveLayer.RaiseToTop(); + } + + void CreateGrabHandle() + { + if( !mGrabHandle ) + { + if ( !mGrabHandleImage ) + { + mGrabHandleImage = ResourceImage::New( DEFAULT_GRAB_HANDLE_IMAGE ); + } + + mGrabHandle = ImageActor::New( mGrabHandleImage ); +#ifdef DECORATOR_DEBUG + mGrabHandle.SetName( "GrabHandleActor" ); +#endif + mGrabHandle.SetParentOrigin( ParentOrigin::TOP_LEFT ); + mGrabHandle.SetAnchorPoint( AnchorPoint::TOP_CENTER ); + mGrabHandle.SetDrawMode( DrawMode::OVERLAY ); + + mGrabArea = Actor::New(); // Area that Grab handle responds to, larger than actual handle so easier to move +#ifdef DECORATOR_DEBUG + mGrabArea.SetName( "GrabArea" ); +#endif + mGrabArea.SetPositionInheritanceMode( Dali::USE_PARENT_POSITION ); + mGrabArea.SetSizeMode( SIZE_RELATIVE_TO_PARENT ); + mGrabArea.SetSizeModeFactor( DEFAULT_GRAB_HANDLE_RELATIVE_SIZE ); + mGrabHandle.Add(mGrabArea); + + mTapDetector.Attach( mGrabArea ); + mPanGestureDetector.Attach( mGrabArea ); + + mActiveLayer.Add(mGrabHandle); + } + } + + void CreateSelectionHandles() + { + SelectionHandleImpl& primary = mSelectionHandle[ PRIMARY_SELECTION_HANDLE ]; + if ( !primary.actor ) + { + if ( !primary.releasedImage ) + { + primary.releasedImage = ResourceImage::New( DEFAULT_SELECTION_HANDLE_ONE ); + } + + primary.actor = ImageActor::New( primary.releasedImage ); +#ifdef DECORATOR_DEBUG + primary.actor.SetName("SelectionHandleOne"); +#endif + primary.actor.SetParentOrigin( ParentOrigin::TOP_LEFT ); + primary.actor.SetAnchorPoint( AnchorPoint::TOP_RIGHT ); // Change to BOTTOM_RIGHT if Look'n'Feel requires handle above text. + primary.actor.SetDrawMode( DrawMode::OVERLAY ); // ensure grab handle above text + primary.flipped = false; + + 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"); +#endif + primary.grabArea.SetSizeMode( SIZE_RELATIVE_TO_PARENT ); + primary.grabArea.SetSizeModeFactor( DEFAULT_SELECTION_HANDLE_RELATIVE_SIZE ); + primary.grabArea.SetPositionInheritanceMode( Dali::USE_PARENT_POSITION ); + + mTapDetector.Attach( primary.grabArea ); + mPanGestureDetector.Attach( primary.grabArea ); + primary.grabArea.TouchedSignal().Connect( this, &Decorator::Impl::OnHandleOneTouched ); + + primary.actor.Add( primary.grabArea ); + mActiveLayer.Add( primary.actor ); + } + + SelectionHandleImpl& secondary = mSelectionHandle[ SECONDARY_SELECTION_HANDLE ]; + if ( !secondary.actor ) + { + if ( !secondary.releasedImage ) + { + secondary.releasedImage = ResourceImage::New( DEFAULT_SELECTION_HANDLE_TWO ); + } + + secondary.actor = ImageActor::New( secondary.releasedImage ); +#ifdef DECORATOR_DEBUG + secondary.actor.SetName("SelectionHandleTwo"); +#endif + secondary.actor.SetParentOrigin( ParentOrigin::TOP_LEFT ); + secondary.actor.SetAnchorPoint( AnchorPoint::TOP_RIGHT ); // Change to BOTTOM_RIGHT if Look'n'Feel requires handle above text. + secondary.actor.SetDrawMode( DrawMode::OVERLAY ); // ensure grab handle above text + secondary.flipped = false; + + 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"); +#endif + secondary.grabArea.SetSizeMode( SIZE_RELATIVE_TO_PARENT ); + secondary.grabArea.SetSizeModeFactor( DEFAULT_SELECTION_HANDLE_RELATIVE_SIZE ); + secondary.grabArea.SetPositionInheritanceMode( Dali::USE_PARENT_POSITION ); + + mTapDetector.Attach( secondary.grabArea ); + mPanGestureDetector.Attach( secondary.grabArea ); + secondary.grabArea.TouchedSignal().Connect( this, &Decorator::Impl::OnHandleTwoTouched ); + + secondary.actor.Add( secondary.grabArea ); + mActiveLayer.Add( secondary.actor ); + } + + //SetUpHandlePropertyNotifications(); TODO + } + + void OnTap( Actor actor, const TapGesture& tap ) + { + if( actor == mGrabHandle ) + { + // TODO + } + } + + void OnPan( Actor actor, const PanGesture& gesture ) + { + if( actor == mGrabHandle ) + { + // TODO + } + } + + bool OnHandleOneTouched( Actor actor, const TouchEvent& touch ) + { + // TODO + return false; + } + + bool OnHandleTwoTouched( Actor actor, const TouchEvent& touch ) + { + // TODO + return false; + } + Internal::Control& mParent; Observer& mObserver; + Layer mActiveLayer; ///< Layer for active handles and alike that ensures they are above all else. + unsigned int mActiveCursor; + bool mActiveGrabHandle; + bool mActiveSelection; CursorImpl mCursor[CURSOR_COUNT]; + ImageActor mGrabHandle; + Actor mGrabArea; + + SelectionHandleImpl mSelectionHandle[SELECTION_HANDLE_COUNT]; + Image mCursorImage; Image mGrabHandleImage; + TapGestureDetector mTapDetector; + PanGestureDetector mPanGestureDetector; + float mCursorBlinkInterval; float mCursorBlinkDuration; }; @@ -164,6 +436,16 @@ float Decorator::GetCursorBlinkDuration() const return mImpl->mCursorBlinkDuration; } +void Decorator::SetGrabHandleActive( bool active ) +{ + mImpl->mActiveGrabHandle = active; +} + +bool Decorator::IsGrabHandleActive() const +{ + return mImpl->mActiveGrabHandle; +} + void Decorator::SetGrabHandleImage( Dali::Image image ) { mImpl->mGrabHandleImage = image; @@ -174,15 +456,61 @@ Dali::Image Decorator::GetGrabHandleImage() const return mImpl->mGrabHandleImage; } +void Decorator::SetSelectionActive( bool active ) +{ + mImpl->mActiveSelection = active; +} + +bool Decorator::IsSelectionActive() const +{ + return mImpl->mActiveSelection; +} + +void Decorator::SetPosition( SelectionHandle handle, float x, float y, float height ) +{ + mImpl->mSelectionHandle[handle].x = x; + mImpl->mSelectionHandle[handle].y = y; + mImpl->mSelectionHandle[handle].cursorHeight = height; +} + +void Decorator::GetPosition( SelectionHandle handle, float& x, float& y, float& height ) const +{ + x = mImpl->mSelectionHandle[handle].x; + y = mImpl->mSelectionHandle[handle].y; + height = mImpl->mSelectionHandle[handle].cursorHeight; +} + +void Decorator::SetImage( SelectionHandle handle, SelectionHandleState state, Dali::Image image ) +{ + if( SELECTION_HANDLE_PRESSED == state ) + { + mImpl->mSelectionHandle[handle].pressedImage = image; + } + else + { + mImpl->mSelectionHandle[handle].releasedImage = image; + } +} + +Dali::Image Decorator::GetImage( SelectionHandle handle, SelectionHandleState state ) const +{ + if( SELECTION_HANDLE_PRESSED == state ) + { + return mImpl->mSelectionHandle[handle].pressedImage; + } + + return mImpl->mSelectionHandle[handle].releasedImage; +} + Decorator::~Decorator() { delete mImpl; } -Decorator::Decorator(Dali::Toolkit::Internal::Control& parent, Observer& observer) +Decorator::Decorator( Dali::Toolkit::Internal::Control& parent, Observer& observer ) : mImpl( NULL ) { - mImpl = new Decorator::Impl(parent, observer); + mImpl = new Decorator::Impl( parent, observer ); } } // namespace Text diff --git a/dali-toolkit/public-api/text/decorator/text-decorator.h b/dali-toolkit/public-api/text/decorator/text-decorator.h index 3ebc588..809be0d 100644 --- a/dali-toolkit/public-api/text/decorator/text-decorator.h +++ b/dali-toolkit/public-api/text/decorator/text-decorator.h @@ -62,10 +62,25 @@ enum ActiveCursor // The state information for grab handle events enum GrabHandleState { - GRAB_HANDLE_MOVING, + GRAB_HANDLE_TAPPED, + GRAB_HANDLE_PRESSED, GRAB_HANDLE_RELEASED }; +// The set the selection-handle positions etc. +enum SelectionHandle +{ + PRIMARY_SELECTION_HANDLE, + SECONDARY_SELECTION_HANDLE, + SELECTION_HANDLE_COUNT +}; + +enum SelectionHandleState +{ + SELECTION_HANDLE_PRESSED, + SELECTION_HANDLE_RELEASED +}; + /** * @brief A Text Decorator is used to display cursors, handles, selection highlights and pop-ups. * @@ -250,6 +265,58 @@ public: */ Dali::Image GetGrabHandleImage() const; + /** + * @brief Sets whether the selection handles and highlight are active. + * + * @param[in] active True if the selection handles and highlight are active. + */ + void SetSelectionActive( bool active ); + + /** + * @brief Query whether the selection handles and highlight are active. + * + * @return True if the selection handles and highlight are active. + */ + bool IsSelectionActive() const; + + /** + * @brief Sets the position of a selection handle. + * + * @param[in] handle The handle to set. + * @param[in] x The x position relative to the top-left of the parent control. + * @param[in] y The y position relative to the top-left of the parent control. + * @param[in] cursorHeight The logical cursor height at this position. + */ + void SetPosition( SelectionHandle handle, float x, float y, float cursorHeight ); + + /** + * @brief Retrieves the position of a selection handle. + * + * @param[in] handle The handle to get. + * @param[out] x The x position relative to the top-left of the parent control. + * @param[out] y The y position relative to the top-left of the parent control. + * @param[out] cursorHeight The logical cursor height at this position. + */ + void GetPosition( SelectionHandle handle, float& x, float& y, float& cursorHeight ) const; + + /** + * @brief Sets the image for one of the selection handles. + * + * @param[in] handle The selection handle. + * @param[in] state A different image can be set for the pressed/released states. + * @param[in] image The image to use. + */ + void SetImage( SelectionHandle handle, SelectionHandleState state, Dali::Image image ); + + /** + * @brief Retrieves the image for a selection handle. + * + * @param[in] handle The selection handle. + * @param[in] state A different image can be set for the pressed/released states. + * @return The image. + */ + Dali::Image GetImage( SelectionHandle handle, SelectionHandleState state ) const; + protected: /** diff --git a/dali-toolkit/public-api/text/rendering/basic/text-basic-renderer.cpp b/dali-toolkit/public-api/text/rendering/basic/text-basic-renderer.cpp index 6fbaa3a..5cd608f 100644 --- a/dali-toolkit/public-api/text/rendering/basic/text-basic-renderer.cpp +++ b/dali-toolkit/public-api/text/rendering/basic/text-basic-renderer.cpp @@ -279,6 +279,8 @@ Text::RendererPtr BasicRenderer::New() RenderableActor BasicRenderer::Render( Text::ViewInterface& view ) { + UnparentAndReset( mImpl->mActor ); + Text::Length numberOfGlyphs = view.GetNumberOfGlyphs(); if( numberOfGlyphs > 0 ) diff --git a/dali-toolkit/public-api/text/text-controller.cpp b/dali-toolkit/public-api/text/text-controller.cpp index 4582944..7d0b956 100644 --- a/dali-toolkit/public-api/text/text-controller.cpp +++ b/dali-toolkit/public-api/text/text-controller.cpp @@ -30,8 +30,11 @@ #include // EXTERNAL INCLUDES -#include #include +#include +#include + +using std::vector; namespace Dali { @@ -56,6 +59,7 @@ struct Controller::TextInput union Param { int mInt; + unsigned int mUint; float mFloat; }; @@ -71,16 +75,102 @@ struct Controller::TextInput EventType type; Param p1; Param p2; + Param p3; + }; + + enum State + { + INACTIVE, + SELECTING, + EDITING }; TextInput( DecoratorPtr decorator ) - : mDecorator( decorator ) + : mDecorator( decorator ), + mState( INACTIVE ) { } + /** + * @brief Helper to move the cursor, grab handle etc. + */ + bool ProcessTouchEvents() + { + mDecoratorUpdated = false; + + if( mDecorator ) + { + for( vector::iterator iter = mEventQueue.begin(); iter != mEventQueue.end(); ++iter ) + { + switch( iter->type ) + { + case KEYBOARD_FOCUS_GAIN_EVENT: + { + OnKeyboardFocus( true ); + break; + } + case KEYBOARD_FOCUS_LOST_EVENT: + { + OnKeyboardFocus( false ); + break; + } + case TAP_EVENT: + { + OnTapEvent( *iter ); + break; + } + case GRAB_HANDLE_EVENT: + { + OnGrabHandleEvent( *iter ); + break; + } + } + } + } + + mEventQueue.clear(); + + return mDecoratorUpdated; + } + + void OnKeyboardFocus( bool hasFocus ) + { + // TODO + } + + void OnTapEvent( const Event& event ) + { + if( 1u == event.p1.mUint ) + { + mState = TextInput::EDITING; + mDecorator->SetGrabHandleActive( true ); + mDecorator->SetPosition( PRIMARY_CURSOR, 0, 0, 10 ); + mDecoratorUpdated = true; + } + else if( 2u == event.p1.mUint ) + { + mState = TextInput::SELECTING; + mDecorator->SetGrabHandleActive( false ); + mDecorator->SetSelectionActive( true ); + mDecoratorUpdated = true; + } + } + + void OnGrabHandleEvent( const Event& event ) + { + // TODO + } + DecoratorPtr mDecorator; + bool mDecoratorUpdated; + + State mState; - std::vector mEventQueue; + /** + * This is used to delay handling events until after the model has been updated. + * The number of updates to the model is minimized to improve performance. + */ + vector mEventQueue; ///< The queue of touch events etc. }; struct Controller::Impl @@ -162,11 +252,11 @@ bool Controller::Relayout( const Vector2& size ) return false; } - bool viewUpdated = false; + bool updated = false; if( size != mImpl->mControlSize ) { - viewUpdated = DoRelayout( size, mImpl->mOperations ); + updated = DoRelayout( size, mImpl->mOperations ); // Do not re-do any operation until something changes. mImpl->mOperations = NO_OPERATION; @@ -174,7 +264,13 @@ bool Controller::Relayout( const Vector2& size ) mImpl->mControlSize = size; } - return viewUpdated; + if( mImpl->mTextInput ) + { + // Move the cursor, grab handle etc. + updated = mImpl->mTextInput->ProcessTouchEvents() || updated; + } + + return updated; } bool Controller::DoRelayout( const Vector2& size, OperationsMask operations ) @@ -308,8 +404,6 @@ bool Controller::DoRelayout( const Vector2& size, OperationsMask operations ) viewUpdated = true; } - // TODO - process input events to move grab handle - return viewUpdated; } @@ -411,15 +505,17 @@ void Controller::KeyboardFocusLostEvent() } } -void Controller::TapEvent( float x, float y) +void Controller::TapEvent( unsigned int tapCount, float x, float y ) { DALI_ASSERT_DEBUG( mImpl->mTextInput && "Unexpected TapEvent" ); if( mImpl->mTextInput ) { TextInput::Event event( TextInput::TAP_EVENT ); - event.p1.mFloat = x; - event.p2.mFloat = y; + event.p1.mUint = tapCount; + event.p2.mFloat = x; + event.p3.mFloat = y; + mImpl->mTextInput->mEventQueue.push_back( event ); RequestRelayout(); } @@ -434,6 +530,7 @@ void Controller::GrabHandleEvent( GrabHandleState state, float x ) TextInput::Event event( TextInput::GRAB_HANDLE_EVENT ); event.p1.mInt = state; event.p2.mFloat = x; + mImpl->mTextInput->mEventQueue.push_back( event ); RequestRelayout(); } diff --git a/dali-toolkit/public-api/text/text-controller.h b/dali-toolkit/public-api/text/text-controller.h index d2c9117..8f67531 100644 --- a/dali-toolkit/public-api/text/text-controller.h +++ b/dali-toolkit/public-api/text/text-controller.h @@ -109,7 +109,7 @@ public: * * @note UI Controls are expected to minimize calls to this method e.g. call once after size negotiation. * @param[in] size A the size of a bounding box to layout text within. - * @return True if the View was updated. + * @return True if the text model or decorations were updated. */ bool Relayout( const Vector2& size ); @@ -153,9 +153,12 @@ public: void KeyboardFocusLostEvent(); /** - * @brief Caller by editable UI controls when focus is lost. + * @brief Caller by editable UI controls when a tap gesture occurs. + * @param[in] tapCount The number of taps. + * @param[in] x The x position relative to the top-left of the parent control. + * @param[in] y The y position relative to the top-left of the parent control. */ - void TapEvent( float x, float y ); + void TapEvent( unsigned int tapCount, float x, float y ); /** * @copydoc Dali::Toolkit::Text::Decorator::Observer::GrabHandleEvent()