X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=blobdiff_plain;f=dali-toolkit%2Finternal%2Ftext%2Ftext-controller-impl.cpp;h=55b5893f376b39ad1aef39eaa124ffdfc0853c4d;hp=3da71385abec07e1306ab5c865f1962faf72323c;hb=2047844bb3b4a84231905c8c540d34d4c468e5ad;hpb=fddb0059f61f9e5dfd10521a14e15e6bad110d06 diff --git a/dali-toolkit/internal/text/text-controller-impl.cpp b/dali-toolkit/internal/text/text-controller-impl.cpp index 3da7138..55b5893 100644 --- a/dali-toolkit/internal/text/text-controller-impl.cpp +++ b/dali-toolkit/internal/text/text-controller-impl.cpp @@ -78,20 +78,20 @@ namespace Text * @param[in] numberOfGlyphs The number of glyphs. * @param[out] glyphMetrics Some glyph metrics (font height, advance, ascender and x bearing). * @param[in] visualModel The visual model. - * @param[in] fontClient The font client. + * @param[in] metrics Used to access metrics from FontClient. */ void GetGlyphsMetrics( GlyphIndex glyphIndex, Length numberOfGlyphs, GlyphMetrics& glyphMetrics, - VisualModelPtr visualModel, - TextAbstraction::FontClient& fontClient ) + VisualModelPtr& visualModel, + MetricsPtr& metrics ) { const GlyphInfo* glyphsBuffer = visualModel->mGlyphs.Begin(); const GlyphInfo& firstGlyph = *( glyphsBuffer + glyphIndex ); Text::FontMetrics fontMetrics; - fontClient.GetFontMetrics( firstGlyph.fontId, fontMetrics ); + metrics->GetFontMetrics( firstGlyph.fontId, fontMetrics ); glyphMetrics.fontHeight = fontMetrics.height; glyphMetrics.advance = firstGlyph.advance; @@ -423,7 +423,7 @@ void Controller::Impl::UpdateModel( OperationsMask operationsRequired ) if( GET_GLYPH_METRICS & operations ) { GlyphInfo* glyphsBuffer = glyphs.Begin(); - mFontClient.GetGlyphMetrics( glyphsBuffer, numberOfGlyphs ); + mMetrics->GetGlyphMetrics( glyphsBuffer, numberOfGlyphs ); // Update the width and advance of all new paragraph characters. for( Vector::ConstIterator it = newParagraphGlyphs.Begin(), endIt = newParagraphGlyphs.End(); it != endIt; ++it ) @@ -436,6 +436,27 @@ void Controller::Impl::UpdateModel( OperationsMask operationsRequired ) glyph.advance = 0.f; } } + + if( mEventData && + mEventData->mPreEditFlag && + ( 0u != mVisualModel->mCharactersToGlyph.Count() ) ) + { + // Add the underline for the pre-edit text. + const GlyphIndex* const charactersToGlyphBuffer = mVisualModel->mCharactersToGlyph.Begin(); + const Length* const glyphsPerCharacterBuffer = mVisualModel->mGlyphsPerCharacter.Begin(); + + const GlyphIndex glyphStart = *( charactersToGlyphBuffer + mEventData->mPreEditStartPosition ); + const CharacterIndex lastPreEditCharacter = mEventData->mPreEditStartPosition + ( ( mEventData->mPreEditLength > 0u ) ? mEventData->mPreEditLength - 1u : 0u ); + const Length numberOfGlyphsLastCharacter = *( glyphsPerCharacterBuffer + lastPreEditCharacter ); + const GlyphIndex glyphEnd = *( charactersToGlyphBuffer + lastPreEditCharacter ) + ( numberOfGlyphsLastCharacter > 1u ? numberOfGlyphsLastCharacter - 1u : 0u ); + + GlyphRun underlineRun; + underlineRun.glyphIndex = glyphStart; + underlineRun.numberOfGlyphs = 1u + glyphEnd - glyphStart; + + // TODO: At the moment the underline runs are only for pre-edit. + mVisualModel->mUnderlineRuns.PushBack( underlineRun ); + } } void Controller::Impl::GetDefaultFonts( Vector& fonts, Length numberOfCharacters ) @@ -466,7 +487,7 @@ float Controller::Impl::GetDefaultFontLineHeight() } Text::FontMetrics fontMetrics; - mFontClient.GetFontMetrics( defaultFontId, fontMetrics ); + mMetrics->GetFontMetrics( defaultFontId, fontMetrics ); return( fontMetrics.ascender - fontMetrics.descender ); } @@ -516,13 +537,16 @@ void Controller::Impl::OnTapEvent( const Event& event ) if( 1u == tapCount ) { - if( ! IsShowingPlaceholderText() ) + if( IsShowingRealText() ) { const float xPosition = event.p2.mFloat - mEventData->mScrollPosition.x - mAlignmentOffset.x; const float yPosition = event.p3.mFloat - mEventData->mScrollPosition.y - mAlignmentOffset.y; mEventData->mPrimaryCursorPosition = GetClosestCursorIndex( xPosition, yPosition ); + + // When the cursor position is changing, delay cursor blinking + mEventData->mDecorator->DelayCursorBlink(); } else { @@ -857,7 +881,7 @@ void Controller::Impl::RetrieveSelection( std::string& selectedText, bool delete uint32_t lengthOfSelectedText = mEventData->mRightSelectionPosition - startOfSelectedText; // Validate the start and end selection points - if( ( startOfSelectedText >= 0 ) && ( ( startOfSelectedText + lengthOfSelectedText ) <= mLogicalModel->mText.Count() ) ) + if( ( startOfSelectedText + lengthOfSelectedText ) <= mLogicalModel->mText.Count() ) { //Get text as a UTF8 string Vector& utf32Characters = mLogicalModel->mText; @@ -1053,6 +1077,9 @@ void Controller::Impl::RepositionSelectionHandles( CharacterIndex selectionStart mEventData->mDecorator->SetPosition( RIGHT_SELECTION_HANDLE, secondaryPosition.x, secondaryPosition.y, secondaryCursorInfo.lineHeight ); + // Cursor to be positioned at end of selection so if selection interrupted and edit mode restarted the cursor will be at end of selection + mEventData->mPrimaryCursorPosition = (indicesSwapped)?mEventData->mLeftSelectionPosition:mEventData->mRightSelectionPosition; + // Set the flag to update the decorator. mEventData->mDecoratorUpdated = true; } @@ -1317,10 +1344,25 @@ LineIndex Controller::Impl::GetClosestLine( float y ) const void Controller::Impl::FindSelectionIndices( float visualX, float visualY, CharacterIndex& startIndex, CharacterIndex& endIndex ) { CharacterIndex hitCharacter = GetClosestCursorIndex( visualX, visualY ); + DALI_ASSERT_DEBUG( hitCharacter <= mLogicalModel->mText.Count() && "GetClosestCursorIndex returned out of bounds index" ); + + if ( mLogicalModel->mText.Count() == 0 ) + { + return; // if model empty + } + if( hitCharacter >= mLogicalModel->mText.Count() ) { - // Selection out of bounds. - return; + // Closest hit character is the last character. + if ( hitCharacter == mLogicalModel->mText.Count() ) + { + hitCharacter--; //Hit character index set to last character in logical model + } + else + { + // hitCharacter is out of bounds + return; + } } startIndex = hitCharacter; @@ -1352,6 +1394,8 @@ void Controller::Impl::FindSelectionIndices( float visualX, float visualY, Chara CharacterIndex Controller::Impl::GetClosestCursorIndex( float visualX, float visualY ) { + DALI_LOG_INFO( gLogFilter, Debug::Verbose, "GetClosestCursorIndex %p closest visualX %f visualY %f\n", this, visualX, visualY ); + if( NULL == mEventData ) { // Nothing to do if there is no text input. @@ -1418,7 +1462,7 @@ CharacterIndex Controller::Impl::GetClosestCursorIndex( float visualX, numberOfGlyphs, glyphMetrics, mVisualModel, - mFontClient ); + mMetrics ); const Vector2& position = *( positionsBuffer + glyphLogicalOrderIndex ); @@ -1455,6 +1499,8 @@ CharacterIndex Controller::Impl::GetClosestCursorIndex( float visualX, logicalIndex = hasRightToLeftCharacters ? *( visualToLogicalCursorBuffer + visualIndex ) : visualIndex; DALI_LOG_INFO( gLogFilter, Debug::Verbose, "%p closest visualIndex %d logicalIndex %d\n", this, visualIndex, logicalIndex ); + DALI_ASSERT_DEBUG( ( logicalIndex <= mLogicalModel->mText.Count() && logicalIndex >= 0 ) && "GetClosestCursorIndex - Out of bounds index" ); + return logicalIndex; } @@ -1555,7 +1601,7 @@ void Controller::Impl::GetCursorPosition( CharacterIndex logical, primaryNumberOfGlyphs, glyphMetrics, mVisualModel, - mFontClient ); + mMetrics ); // Whether to add the glyph's advance to the cursor position. // i.e if the paragraph is left to right and the logical cursor is zero, the position is the position of the first glyph and the advance is not added, @@ -1645,7 +1691,7 @@ void Controller::Impl::GetCursorPosition( CharacterIndex logical, secondaryNumberOfGlyphs, glyphMetrics, mVisualModel, - mFontClient ); + mMetrics ); // Set the secondary cursor's position. cursorInfo.secondaryPosition.x = -glyphMetrics.xBearing + secondaryPosition.x + ( isCurrentRightToLeft ? 0.f : glyphMetrics.advance ); @@ -1709,7 +1755,7 @@ void Controller::Impl::UpdateCursorPosition() return; } - if( IsShowingPlaceholderText() ) + if( IsShowingPlaceholderText() || ( 0u == mLogicalModel->mText.Count() ) ) { // Do not want to use the place-holder text to set the cursor position. @@ -1731,7 +1777,7 @@ void Controller::Impl::UpdateCursorPosition() } Text::FontMetrics fontMetrics; - mFontClient.GetFontMetrics( defaultFontId, fontMetrics ); + mMetrics->GetFontMetrics( defaultFontId, fontMetrics ); lineHeight = fontMetrics.ascender - fontMetrics.descender; @@ -1954,8 +2000,9 @@ void Controller::Impl::ScrollTextToMatchCursor() } // Set which cursors are active according the state. - if( ( EventData::EDITING == mEventData->mState ) || - ( EventData::EDITING_WITH_POPUP == mEventData->mState ) || + if( ( EventData::EDITING == mEventData->mState ) || + ( EventData::EDITING_WITH_POPUP == mEventData->mState ) || + ( EventData::EDITING_WITH_GRAB_HANDLE == mEventData->mState ) || ( EventData::GRAB_HANDLE_PANNING == mEventData->mState ) ) { if( cursorInfo.isSecondaryCursor )