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=874503d200968cd7aeacfa502b705f236bda097d;hp=05f353614c0e7addff2be6c608f532a44368aed8;hb=718e975ec30138ecd521ed2e4afdcf84172f0b08;hpb=632c0f0659030bea7e4854c815c88a1eeabcf843 diff --git a/dali-toolkit/internal/text/text-controller-impl.cpp b/dali-toolkit/internal/text/text-controller-impl.cpp index 05f35361..874503d 100644 --- a/dali-toolkit/internal/text/text-controller-impl.cpp +++ b/dali-toolkit/internal/text/text-controller-impl.cpp @@ -55,7 +55,6 @@ struct SelectionBoxInfo const float MAX_FLOAT = std::numeric_limits::max(); const float MIN_FLOAT = std::numeric_limits::min(); const Dali::Toolkit::Text::CharacterDirection LTR = false; ///< Left To Right direction -const uint32_t STAR = 0x2A; } // namespace @@ -71,9 +70,10 @@ namespace Text EventData::EventData( DecoratorPtr decorator ) : mDecorator( decorator ), mImfManager(), + mPlaceholderFont( NULL ), mPlaceholderTextActive(), mPlaceholderTextInactive(), - mPlaceholderTextColor( 0.8f, 0.8f, 0.8f, 0.8f ), + mPlaceholderTextColor( 0.8f, 0.8f, 0.8f, 0.8f ), // This color has been published in the Public API (placeholder-properties.h). mEventQueue(), mInputStyleChangedQueue(), mPreviousState( INACTIVE ), @@ -105,7 +105,10 @@ EventData::EventData( DecoratorPtr decorator ) mScrollAfterDelete( false ), mAllTextSelected( false ), mUpdateInputStyle( false ), - mPasswordInput( false ) + mPasswordInput( false ), + mIsPlaceholderPixelSize( false ), + mIsPlaceholderElideEnabled( false ), + mPlaceholderEllipsisFlag( false ) { mImfManager = ImfManager::Get(); } @@ -789,24 +792,16 @@ bool Controller::Impl::UpdateModel( OperationsMask operationsRequired ) return false; } - Vector utf32CharactersStar; - const Length characterCount = mModel->mLogicalModel->mText.Count(); - const bool isPasswordInput = ( mEventData != NULL && mEventData->mPasswordInput && - !mEventData->mIsShowingPlaceholderText && characterCount > 0 ); - - if (isPasswordInput) + Vector& srcCharacters = mModel->mLogicalModel->mText; + Vector displayCharacters; + bool useHiddenText = false; + if ( mHiddenInput && mEventData != NULL && !mEventData->mIsShowingPlaceholderText) { - utf32CharactersStar.Resize( characterCount ); - - uint32_t* begin = utf32CharactersStar.Begin(); - uint32_t* end = begin + characterCount; - while ( begin < end ) - { - *begin++ = STAR; - } + mHiddenInput->Substitute( srcCharacters,displayCharacters ); + useHiddenText = true; } - Vector& utf32Characters = isPasswordInput ? utf32CharactersStar : mModel->mLogicalModel->mText; + Vector& utf32Characters = useHiddenText ? displayCharacters : srcCharacters; const Length numberOfCharacters = utf32Characters.Count(); // Index to the first character of the first paragraph to be updated. @@ -892,8 +887,19 @@ bool Controller::Impl::UpdateModel( OperationsMask operationsRequired ) // Get the default font's description. TextAbstraction::FontDescription defaultFontDescription; TextAbstraction::PointSize26Dot6 defaultPointSize = TextAbstraction::FontClient::DEFAULT_POINT_SIZE; - if( NULL != mFontDefaults ) + + if( IsShowingPlaceholderText() && ( NULL != mEventData->mPlaceholderFont ) ) + { + // If the placeholder font is set specifically, only placeholder font is changed. + defaultFontDescription = mEventData->mPlaceholderFont->mFontDescription; + if( mEventData->mPlaceholderFont->sizeDefined ) + { + defaultPointSize = mEventData->mPlaceholderFont->mDefaultPointSize * 64u; + } + } + else if( NULL != mFontDefaults ) { + // Set the normal font and the placeholder font. defaultFontDescription = mFontDefaults->mFontDescription; defaultPointSize = mFontDefaults->mDefaultPointSize * 64u; } @@ -1145,6 +1151,9 @@ void Controller::Impl::OnCursorKeyEvent( const Event& event ) } int keyCode = event.p1.mInt; + bool isShiftModifier = event.p2.mBool; + + CharacterIndex previousPrimaryCursorPosition = mEventData->mPrimaryCursorPosition; if( Dali::DALI_KEY_CURSOR_LEFT == keyCode ) { @@ -1160,8 +1169,10 @@ void Controller::Impl::OnCursorKeyEvent( const Event& event ) mEventData->mPrimaryCursorPosition = CalculateNewCursorIndex( mEventData->mPrimaryCursorPosition ); } } - else if( Dali::DALI_KEY_CURSOR_UP == keyCode ) + else if( Dali::DALI_KEY_CURSOR_UP == keyCode && !isShiftModifier ) { + // Ignore Shift-Up for text selection for now. + // Get first the line index of the current cursor position index. CharacterIndex characterIndex = 0u; @@ -1194,8 +1205,10 @@ void Controller::Impl::OnCursorKeyEvent( const Event& event ) CharacterHitTest::TAP, matchedCharacter ); } - else if( Dali::DALI_KEY_CURSOR_DOWN == keyCode ) + else if( Dali::DALI_KEY_CURSOR_DOWN == keyCode && !isShiftModifier ) { + // Ignore Shift-Down for text selection for now. + // Get first the line index of the current cursor position index. CharacterIndex characterIndex = 0u; @@ -1231,7 +1244,64 @@ void Controller::Impl::OnCursorKeyEvent( const Event& event ) } } - mEventData->mUpdateCursorPosition = true; + if ( !isShiftModifier && mEventData->mState != EventData::SELECTING ) + { + // Update selection position after moving the cursor + mEventData->mLeftSelectionPosition = mEventData->mPrimaryCursorPosition; + mEventData->mRightSelectionPosition = mEventData->mPrimaryCursorPosition; + } + + if ( isShiftModifier && IsShowingRealText() ) + { + // Handle text selection + bool selecting = false; + + if ( Dali::DALI_KEY_CURSOR_LEFT == keyCode || Dali::DALI_KEY_CURSOR_RIGHT == keyCode ) + { + // Shift-Left/Right to select the text + int cursorPositionDelta = mEventData->mPrimaryCursorPosition - previousPrimaryCursorPosition; + if ( cursorPositionDelta > 0 || mEventData->mRightSelectionPosition > 0u ) // Check the boundary + { + mEventData->mRightSelectionPosition += cursorPositionDelta; + } + selecting = true; + } + else if ( mEventData->mLeftSelectionPosition != mEventData->mRightSelectionPosition ) + { + // Show no grab handles and text highlight if Shift-Up/Down pressed but no selected text + selecting = true; + } + + if ( selecting ) + { + // Notify the cursor position to the imf manager. + if( mEventData->mImfManager ) + { + mEventData->mImfManager.SetCursorPosition( mEventData->mPrimaryCursorPosition ); + mEventData->mImfManager.NotifyCursorPosition(); + } + + ChangeState( EventData::SELECTING ); + + mEventData->mUpdateLeftSelectionPosition = true; + mEventData->mUpdateRightSelectionPosition = true; + mEventData->mUpdateGrabHandlePosition = true; + mEventData->mUpdateHighlightBox = true; + + // Hide the text selection popup if select the text using keyboard instead of moving grab handles + if( mEventData->mGrabHandlePopupEnabled ) + { + mEventData->mDecorator->SetPopupActive( false ); + } + } + } + else + { + // Handle normal cursor move + ChangeState( EventData::EDITING ); + mEventData->mUpdateCursorPosition = true; + } + mEventData->mUpdateInputStyle = true; mEventData->mScrollAfterUpdatePosition = true; } @@ -1271,6 +1341,10 @@ void Controller::Impl::OnTapEvent( const Event& event ) mEventData->mPrimaryCursorPosition = 0u; } + // Update selection position after tapping + mEventData->mLeftSelectionPosition = mEventData->mPrimaryCursorPosition; + mEventData->mRightSelectionPosition = mEventData->mPrimaryCursorPosition; + mEventData->mUpdateCursorPosition = true; mEventData->mUpdateGrabHandlePosition = true; mEventData->mScrollAfterUpdatePosition = true; @@ -1784,8 +1858,18 @@ void Controller::Impl::RetrieveSelection( std::string& selectedText, bool delete mModel->mLogicalModel->UpdateTextStyleRuns( startOfSelectedText, -static_cast( lengthOfSelectedText ) ); // Mark the paragraphs to be updated. - mTextUpdateInfo.mCharacterIndex = startOfSelectedText; - mTextUpdateInfo.mNumberOfCharactersToRemove = lengthOfSelectedText; + if( Layout::Engine::SINGLE_LINE_BOX == mLayoutEngine.GetLayout() ) + { + mTextUpdateInfo.mCharacterIndex = 0; + mTextUpdateInfo.mNumberOfCharactersToRemove = mTextUpdateInfo.mPreviousNumberOfCharacters; + mTextUpdateInfo.mNumberOfCharactersToAdd = mTextUpdateInfo.mPreviousNumberOfCharacters - lengthOfSelectedText; + mTextUpdateInfo.mClearAll = true; + } + else + { + mTextUpdateInfo.mCharacterIndex = startOfSelectedText; + mTextUpdateInfo.mNumberOfCharactersToRemove = lengthOfSelectedText; + } // Delete text between handles Vector::Iterator first = utf32Characters.Begin() + startOfSelectedText; @@ -2595,17 +2679,17 @@ void Controller::Impl::GetCursorPosition( CharacterIndex logical, switch( mModel->mHorizontalAlignment ) { - case Layout::HORIZONTAL_ALIGN_BEGIN: + case Text::HorizontalAlignment::BEGIN : { cursorInfo.primaryPosition.x = 0.f; break; } - case Layout::HORIZONTAL_ALIGN_CENTER: + case Text::HorizontalAlignment::CENTER: { cursorInfo.primaryPosition.x = floorf( 0.5f * mModel->mVisualModel->mControlSize.width ); break; } - case Layout::HORIZONTAL_ALIGN_END: + case Text::HorizontalAlignment::END: { cursorInfo.primaryPosition.x = mModel->mVisualModel->mControlSize.width - mEventData->mDecorator->GetCursorWidth(); break; @@ -2616,13 +2700,18 @@ void Controller::Impl::GetCursorPosition( CharacterIndex logical, return; } - Text::GetCursorPosition( mModel->mVisualModel, - mModel->mLogicalModel, - mMetrics, - logical, + const bool isMultiLine = ( Layout::Engine::MULTI_LINE_BOX == mLayoutEngine.GetLayout() ); + GetCursorPositionParameters parameters; + parameters.visualModel = mModel->mVisualModel; + parameters.logicalModel = mModel->mLogicalModel; + parameters.metrics = mMetrics; + parameters.logical = logical; + parameters.isMultiline = isMultiLine; + + Text::GetCursorPosition( parameters, cursorInfo ); - if( Layout::Engine::MULTI_LINE_BOX == mLayoutEngine.GetLayout() ) + if( isMultiLine ) { // If the text is editable and multi-line, the cursor position after a white space shouldn't exceed the boundaries of the text control. @@ -2703,6 +2792,8 @@ void Controller::Impl::UpdateCursorPosition( const CursorInfo& cursorInfo ) const Vector2 cursorPosition = cursorInfo.primaryPosition + mModel->mScrollPosition; + mEventData->mDecorator->SetGlyphOffset( PRIMARY_CURSOR, cursorInfo.glyphOffset ); + // Sets the cursor position. mEventData->mDecorator->SetPosition( PRIMARY_CURSOR, cursorPosition.x, @@ -2838,13 +2929,16 @@ void Controller::Impl::ScrollToMakePositionVisible( const Vector2& position, flo mModel->mScrollPosition.x = mModel->mVisualModel->mControlSize.width - positionEndX; } - if( decoratorPositionBeginY < 0.f ) - { - mModel->mScrollPosition.y = -position.y; - } - else if( decoratorPositionEndY > mModel->mVisualModel->mControlSize.height ) + if( Layout::Engine::MULTI_LINE_BOX == mLayoutEngine.GetLayout() ) { - mModel->mScrollPosition.y = mModel->mVisualModel->mControlSize.height - positionEndY; + if( decoratorPositionBeginY < 0.f ) + { + mModel->mScrollPosition.y = -position.y; + } + else if( decoratorPositionEndY > mModel->mVisualModel->mControlSize.height ) + { + mModel->mScrollPosition.y = mModel->mVisualModel->mControlSize.height - positionEndY; + } } } @@ -2853,9 +2947,20 @@ void Controller::Impl::ScrollTextToMatchCursor( const CursorInfo& cursorInfo ) // Get the current cursor position in decorator coords. const Vector2& currentCursorPosition = mEventData->mDecorator->GetPosition( PRIMARY_CURSOR ); + const LineIndex lineIndex = mModel->mVisualModel->GetLineOfCharacter( mEventData->mPrimaryCursorPosition ); + + + // Calculate the offset to match the cursor position before the character was deleted. mModel->mScrollPosition.x = currentCursorPosition.x - cursorInfo.primaryPosition.x; - mModel->mScrollPosition.y = currentCursorPosition.y - cursorInfo.lineOffset; + + //If text control has more than two lines and current line index is not last, calculate scrollpositionY + if( mModel->mVisualModel->mLines.Count() > 1u && lineIndex != mModel->mVisualModel->mLines.Count() -1u ) + { + const float currentCursorGlyphOffset = mEventData->mDecorator->GetGlyphOffset( PRIMARY_CURSOR ); + mModel->mScrollPosition.y = currentCursorPosition.y - cursorInfo.lineOffset - currentCursorGlyphOffset; + } + ClampHorizontalScroll( mModel->mVisualModel->GetLayoutSize() ); ClampVerticalScroll( mModel->mVisualModel->GetLayoutSize() );