From 0ae54c139d553cd05ba466a102ec18cf2cf11e81 Mon Sep 17 00:00:00 2001
From: Paul Wisbey
Date: Sun, 1 Mar 2015 13:39:27 +0000
Subject: [PATCH] Copied some TextInput grab/selection handle code
Change-Id: Id65562d557cd2017e3d54f44e9e764a34ad73697
---
.../controls/text-controls/text-field-impl.cpp | 24 +-
.../controls/text-controls/text-field-impl.h | 7 +
.../public-api/text/decorator/text-decorator.cpp | 338 ++++++++++++++++++++-
.../public-api/text/decorator/text-decorator.h | 69 ++++-
.../text/rendering/basic/text-basic-renderer.cpp | 2 +
dali-toolkit/public-api/text/text-controller.cpp | 119 +++++++-
dali-toolkit/public-api/text/text-controller.h | 9 +-
7 files changed, 546 insertions(+), 22 deletions(-)
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()
--
2.7.4