mController->EnableTextInput( mDecorator );
// Forward input events to controller
- EnableGestureDetection(Gesture::Tap);
+ EnableGestureDetection( static_cast<Gesture::Type>( Gesture::Tap | Gesture::Pan |Gesture::LongPress ) );
GetTapGestureDetector().SetMaximumTapsRequired( 2 );
- EnableGestureDetection(Gesture::Pan);
self.TouchedSignal().Connect( this, &TextField::OnTouched );
mController->PanEvent( gesture.state, gesture.displacement );
}
+void TextField::OnLongPress( const LongPressGesture& gesture )
+{
+ mController->LongPressEvent( gesture.state, gesture.localPoint.x, gesture.localPoint.y );
+}
+
bool TextField::OnKeyEvent( const KeyEvent& event )
{
DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField::OnKeyEvent %p keyCode %d\n", mController.Get(), event.keyCode );
OnTapEvent( *iter );
break;
}
+ case Event::LONG_PRESS_EVENT:
+ {
+ OnLongPressEvent( *iter );
+ break;
+ }
case Event::PAN_EVENT:
{
OnPanEvent( *iter );
}
}
+void Controller::Impl::OnLongPressEvent( const Event& event )
+{
+ if ( EventData::EDITING == mEventData->mState )
+ {
+ ChangeState ( EventData::EDITING_WITH_POPUP );
+ mEventData->mDecoratorUpdated = true;
+ }
+}
+
void Controller::Impl::OnHandleEvent( const Event& event )
{
if( NULL == mEventData )
}
else if ( EventData::EDITING_WITH_POPUP == mEventData->mState )
{
- buttonsToShow = TextSelectionPopup::Buttons( TextSelectionPopup::SELECT | TextSelectionPopup::SELECT_ALL );
+ if ( mLogicalModel->mText.Count() && !IsShowingPlaceholderText())
+ {
+ buttonsToShow = TextSelectionPopup::Buttons( TextSelectionPopup::SELECT | TextSelectionPopup::SELECT_ALL );
+ }
if ( !IsClipboardEmpty() )
{
// Get the glyphs per character table.
const Length* const glyphsPerCharacterBuffer = mVisualModel->mGlyphsPerCharacter.Begin();
+ const Length* const charactersPerGlyphBuffer = mVisualModel->mCharactersPerGlyph.Begin();
// If the vector is void, there is no right to left characters.
const bool hasRightToLeftCharacters = NULL != visualToLogicalBuffer;
// The character in logical order.
const CharacterIndex characterLogicalOrderIndex = hasRightToLeftCharacters ? *( visualToLogicalBuffer + visualIndex ) : visualIndex;
+ // Get the script of the character.
+ const Script script = mLogicalModel->GetScript( characterLogicalOrderIndex );
+
// The first glyph for that character in logical order.
const GlyphIndex glyphLogicalOrderIndex = *( charactersToGlyphBuffer + characterLogicalOrderIndex );
-
// The number of glyphs for that character
const Length numberOfGlyphs = *( glyphsPerCharacterBuffer + characterLogicalOrderIndex );
const Vector2& position = *( positionsBuffer + glyphLogicalOrderIndex );
- // Find the mid-point of the area containing the glyph
- const float glyphCenter = -glyphMetrics.xBearing + position.x + 0.5f * glyphMetrics.advance;
+ // Prevents to jump the whole Latin ligatures like fi, ff, ...
+ const Length numberOfCharactersInLigature = ( TextAbstraction::LATIN == script ) ? *( charactersPerGlyphBuffer + glyphLogicalOrderIndex ) : 1u;
+ const float glyphAdvance = glyphMetrics.advance / static_cast<float>( numberOfCharactersInLigature );
- if( visualX < glyphCenter )
+ for( GlyphIndex index = 0u; !matched && ( index < numberOfCharactersInLigature ); ++index )
+ {
+ // Find the mid-point of the area containing the glyph
+ const float glyphCenter = -glyphMetrics.xBearing + position.x + ( static_cast<float>( index ) + 0.5f ) * glyphAdvance;
+
+ if( visualX < glyphCenter )
+ {
+ visualIndex += index;
+ matched = true;
+ break;
+ }
+ }
+
+ if( matched )
{
- matched = true;
break;
}
}
logicalIndex = hasRightToLeftCharacters ? *( visualToLogicalCursorBuffer + visualIndex ) : visualIndex;
DALI_LOG_INFO( gLogFilter, Debug::Verbose, "%p closest visualIndex %d logicalIndex %d\n", this, visualIndex, logicalIndex );
+
return logicalIndex;
}
}
}
+void Controller::LongPressEvent( Gesture::State state, float x, float y )
+{
+ DALI_ASSERT_DEBUG( mImpl->mEventData && "Unexpected PanEvent" );
+
+ if ( mImpl->IsShowingPlaceholderText() || mImpl->mLogicalModel->mText.Count() == 0u )
+ {
+ if ( mImpl->mEventData )
+ {
+ Event event( Event::LONG_PRESS_EVENT );
+ event.p1.mInt = state;
+ mImpl->mEventData->mEventQueue.push_back( event );
+ mImpl->RequestRelayout();
+ }
+ }
+ else if( mImpl->mEventData )
+ {
+ SelectEvent( x, y, false );
+ }
+}
+
void Controller::SelectEvent( float x, float y, bool selectAll )
{
if( mImpl->mEventData )
void PanEvent( Gesture::State state, const Vector2& displacement );
/**
+ * @brief Called by editable UI controls when a long press gesture occurs.
+ *
+ * @param[in] state The state of the gesture.
+ * @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 LongPressEvent( Gesture::State state, float x, float y );
+
+ /**
* @brief Creates a selection event.
*
* It could be called from the TapEvent (double tap) or when the text selection popup's sellect all button is pressed.