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.cpp;h=9a46e8b1fbdb1dfe69bf8194d5cdc0549a906cc7;hp=6e6bfaa4dacc89b4cc99ef349965369942697dc2;hb=1a3ce129d812ac386adfaf2f10b9d40591f274a2;hpb=f60b3d8e308a5145efe754cbff2a47b4ae278021 diff --git a/dali-toolkit/internal/text/text-controller.cpp b/dali-toolkit/internal/text/text-controller.cpp index 6e6bfaa..9a46e8b 100755 --- a/dali-toolkit/internal/text/text-controller.cpp +++ b/dali-toolkit/internal/text/text-controller.cpp @@ -20,6 +20,7 @@ // EXTERNAL INCLUDES #include +#include #include #include #include @@ -68,6 +69,16 @@ float ConvertToEven( float value ) return static_cast( intValue + ( intValue & 1 ) ); } +int ConvertPixelToPint( float pixel ) +{ + unsigned int horizontalDpi = 0u; + unsigned int verticalDpi = 0u; + Dali::TextAbstraction::FontClient fontClient = Dali::TextAbstraction::FontClient::Get(); + fontClient.GetDpi( horizontalDpi, verticalDpi ); + + return ( pixel * 72.f ) / static_cast< float >( horizontalDpi ); +} + } // namespace namespace Dali @@ -383,6 +394,18 @@ void Controller::SetHorizontalAlignment( Text::HorizontalAlignment::Type alignme // Set the flag to redo the alignment operation. mImpl->mOperationsPending = static_cast( mImpl->mOperationsPending | ALIGN ); + if( mImpl->mEventData ) + { + mImpl->mEventData->mUpdateAlignment = true; + + // Update the cursor if it's in editing mode + if( EventData::IsEditingState( mImpl->mEventData->mState ) ) + { + mImpl->ChangeState( EventData::EDITING ); + mImpl->mEventData->mUpdateCursorPosition = true; + } + } + mImpl->RequestRelayout(); } } @@ -435,6 +458,11 @@ void Controller::SetLayoutDirection( Dali::LayoutDirection::Type layoutDirection mImpl->mLayoutDirection = layoutDirection; } +bool Controller::IsShowingRealText() const +{ + return mImpl->IsShowingRealText(); +} + void Controller::SetLineWrapMode( Text::LineWrap::Mode lineWrapMode ) { @@ -474,6 +502,92 @@ bool Controller::IsTextElideEnabled() const return mImpl->mModel->mElideEnabled; } +void Controller::SetTextFitEnabled(bool enabled) +{ + mImpl->mTextFitEnabled = enabled; +} + +bool Controller::IsTextFitEnabled() const +{ + return mImpl->mTextFitEnabled; +} + +void Controller::SetTextFitMinSize( float minSize, FontSizeType type ) +{ + switch( type ) + { + case POINT_SIZE: + { + mImpl->mTextFitMinSize = minSize; + break; + } + case PIXEL_SIZE: + { + mImpl->mTextFitMinSize = ConvertPixelToPint( minSize ); + break; + } + } +} + +float Controller::GetTextFitMinSize() const +{ + return mImpl->mTextFitMinSize; +} + +void Controller::SetTextFitMaxSize( float maxSize, FontSizeType type ) +{ + switch( type ) + { + case POINT_SIZE: + { + mImpl->mTextFitMaxSize = maxSize; + break; + } + case PIXEL_SIZE: + { + mImpl->mTextFitMaxSize = ConvertPixelToPint( maxSize ); + break; + } + } +} + +float Controller::GetTextFitMaxSize() const +{ + return mImpl->mTextFitMaxSize; +} + +void Controller::SetTextFitStepSize( float step, FontSizeType type ) +{ + switch( type ) + { + case POINT_SIZE: + { + mImpl->mTextFitStepSize = step; + break; + } + case PIXEL_SIZE: + { + mImpl->mTextFitStepSize = ConvertPixelToPint( step ); + break; + } + } +} + +float Controller::GetTextFitStepSize() const +{ + return mImpl->mTextFitStepSize; +} + +void Controller::SetTextFitContentSize(Vector2 size) +{ + mImpl->mTextFitContentSize = size; +} + +Vector2 Controller::GetTextFitContentSize() const +{ + return mImpl->mTextFitContentSize; +} + void Controller::SetPlaceholderTextElideEnabled( bool enabled ) { mImpl->mEventData->mIsPlaceholderElideEnabled = enabled; @@ -522,6 +636,16 @@ bool Controller::IsGrabHandleEnabled() const return mImpl->mEventData->mGrabHandleEnabled; } +void Controller::SetGrabHandlePopupEnabled(bool enabled) +{ + mImpl->mEventData->mGrabHandlePopupEnabled = enabled; +} + +bool Controller::IsGrabHandlePopupEnabled() const +{ + return mImpl->mEventData->mGrabHandlePopupEnabled; +} + // public : Update void Controller::SetText( const std::string& text ) @@ -1122,6 +1246,10 @@ void Controller::SetDefaultColor( const Vector4& color ) { mImpl->mModel->mVisualModel->SetTextColor( color ); + mImpl->mModel->mLogicalModel->mColorRuns.Clear(); + + mImpl->mOperationsPending = static_cast( mImpl->mOperationsPending | COLOR ); + mImpl->RequestRelayout(); } } @@ -1320,7 +1448,7 @@ const std::string& Controller::GetDefaultOutlineProperties() const bool Controller::SetDefaultLineSpacing( float lineSpacing ) { - if( std::abs(lineSpacing - mImpl->mLayoutEngine.GetDefaultLineSpacing()) > Math::MACHINE_EPSILON_1000 ) + if( std::fabs( lineSpacing - mImpl->mLayoutEngine.GetDefaultLineSpacing() ) > Math::MACHINE_EPSILON_1000 ) { mImpl->mLayoutEngine.SetDefaultLineSpacing(lineSpacing); mImpl->mRecalculateNaturalSize = true; @@ -1341,7 +1469,7 @@ void Controller::SetInputColor( const Vector4& color ) mImpl->mEventData->mInputStyle.textColor = color; mImpl->mEventData->mInputStyle.isDefaultColor = false; - if( EventData::SELECTING == mImpl->mEventData->mState ) + if( EventData::SELECTING == mImpl->mEventData->mState || EventData::EDITING == mImpl->mEventData->mState || EventData::INACTIVE == mImpl->mEventData->mState ) { const bool handlesCrossed = mImpl->mEventData->mLeftSelectionPosition > mImpl->mEventData->mRightSelectionPosition; @@ -1388,21 +1516,36 @@ void Controller::SetInputFontFamily( const std::string& fontFamily ) mImpl->mEventData->mInputStyle.familyName = fontFamily; mImpl->mEventData->mInputStyle.isFamilyDefined = true; - if( EventData::SELECTING == mImpl->mEventData->mState ) + if( EventData::SELECTING == mImpl->mEventData->mState || EventData::EDITING == mImpl->mEventData->mState || EventData::INACTIVE == mImpl->mEventData->mState ) { CharacterIndex startOfSelectedText = 0u; Length lengthOfSelectedText = 0u; - FontDescriptionRun& fontDescriptionRun = UpdateSelectionFontStyleRun( mImpl->mEventData, - mImpl->mModel->mLogicalModel, - startOfSelectedText, - lengthOfSelectedText ); - fontDescriptionRun.familyLength = fontFamily.size(); - fontDescriptionRun.familyName = new char[fontDescriptionRun.familyLength]; - memcpy( fontDescriptionRun.familyName, fontFamily.c_str(), fontDescriptionRun.familyLength ); - fontDescriptionRun.familyDefined = true; + if( EventData::SELECTING == mImpl->mEventData->mState ) + { + // Update a font description run for the selecting state. + FontDescriptionRun& fontDescriptionRun = UpdateSelectionFontStyleRun( mImpl->mEventData, + mImpl->mModel->mLogicalModel, + startOfSelectedText, + lengthOfSelectedText ); + + fontDescriptionRun.familyLength = fontFamily.size(); + fontDescriptionRun.familyName = new char[fontDescriptionRun.familyLength]; + memcpy( fontDescriptionRun.familyName, fontFamily.c_str(), fontDescriptionRun.familyLength ); + fontDescriptionRun.familyDefined = true; + + // The memory allocated for the font family name is freed when the font description is removed from the logical model. - // The memory allocated for the font family name is freed when the font description is removed from the logical model. + mImpl->mTextUpdateInfo.mCharacterIndex = startOfSelectedText; + mImpl->mTextUpdateInfo.mNumberOfCharactersToRemove = lengthOfSelectedText; + mImpl->mTextUpdateInfo.mNumberOfCharactersToAdd = lengthOfSelectedText; + } + else + { + mImpl->mTextUpdateInfo.mCharacterIndex = 0; + mImpl->mTextUpdateInfo.mNumberOfCharactersToRemove = mImpl->mTextUpdateInfo.mPreviousNumberOfCharacters; + mImpl->mTextUpdateInfo.mNumberOfCharactersToAdd = mImpl->mModel->mLogicalModel->mText.Count(); + } // Request to relayout. mImpl->mOperationsPending = static_cast( mImpl->mOperationsPending | @@ -1416,10 +1559,6 @@ void Controller::SetInputFontFamily( const std::string& fontFamily ) mImpl->mRecalculateNaturalSize = true; mImpl->RequestRelayout(); - mImpl->mTextUpdateInfo.mCharacterIndex = startOfSelectedText; - mImpl->mTextUpdateInfo.mNumberOfCharactersToRemove = lengthOfSelectedText; - mImpl->mTextUpdateInfo.mNumberOfCharactersToAdd = lengthOfSelectedText; - // As the font changes, recalculate the handle positions is needed. mImpl->mEventData->mUpdateLeftSelectionPosition = true; mImpl->mEventData->mUpdateRightSelectionPosition = true; @@ -1447,17 +1586,32 @@ void Controller::SetInputFontWeight( FontWeight weight ) mImpl->mEventData->mInputStyle.weight = weight; mImpl->mEventData->mInputStyle.isWeightDefined = true; - if( EventData::SELECTING == mImpl->mEventData->mState ) + if( EventData::SELECTING == mImpl->mEventData->mState || EventData::EDITING == mImpl->mEventData->mState || EventData::INACTIVE == mImpl->mEventData->mState ) { CharacterIndex startOfSelectedText = 0u; Length lengthOfSelectedText = 0u; - FontDescriptionRun& fontDescriptionRun = UpdateSelectionFontStyleRun( mImpl->mEventData, - mImpl->mModel->mLogicalModel, - startOfSelectedText, - lengthOfSelectedText ); - fontDescriptionRun.weight = weight; - fontDescriptionRun.weightDefined = true; + if( EventData::SELECTING == mImpl->mEventData->mState ) + { + // Update a font description run for the selecting state. + FontDescriptionRun& fontDescriptionRun = UpdateSelectionFontStyleRun( mImpl->mEventData, + mImpl->mModel->mLogicalModel, + startOfSelectedText, + lengthOfSelectedText ); + + fontDescriptionRun.weight = weight; + fontDescriptionRun.weightDefined = true; + + mImpl->mTextUpdateInfo.mCharacterIndex = startOfSelectedText; + mImpl->mTextUpdateInfo.mNumberOfCharactersToRemove = lengthOfSelectedText; + mImpl->mTextUpdateInfo.mNumberOfCharactersToAdd = lengthOfSelectedText; + } + else + { + mImpl->mTextUpdateInfo.mCharacterIndex = 0; + mImpl->mTextUpdateInfo.mNumberOfCharactersToRemove = mImpl->mTextUpdateInfo.mPreviousNumberOfCharacters; + mImpl->mTextUpdateInfo.mNumberOfCharactersToAdd = mImpl->mModel->mLogicalModel->mText.Count(); + } // Request to relayout. mImpl->mOperationsPending = static_cast( mImpl->mOperationsPending | @@ -1471,10 +1625,6 @@ void Controller::SetInputFontWeight( FontWeight weight ) mImpl->mRecalculateNaturalSize = true; mImpl->RequestRelayout(); - mImpl->mTextUpdateInfo.mCharacterIndex = startOfSelectedText; - mImpl->mTextUpdateInfo.mNumberOfCharactersToRemove = lengthOfSelectedText; - mImpl->mTextUpdateInfo.mNumberOfCharactersToAdd = lengthOfSelectedText; - // As the font might change, recalculate the handle positions is needed. mImpl->mEventData->mUpdateLeftSelectionPosition = true; mImpl->mEventData->mUpdateRightSelectionPosition = true; @@ -1513,17 +1663,32 @@ void Controller::SetInputFontWidth( FontWidth width ) mImpl->mEventData->mInputStyle.width = width; mImpl->mEventData->mInputStyle.isWidthDefined = true; - if( EventData::SELECTING == mImpl->mEventData->mState ) + if( EventData::SELECTING == mImpl->mEventData->mState || EventData::EDITING == mImpl->mEventData->mState || EventData::INACTIVE == mImpl->mEventData->mState ) { CharacterIndex startOfSelectedText = 0u; Length lengthOfSelectedText = 0u; - FontDescriptionRun& fontDescriptionRun = UpdateSelectionFontStyleRun( mImpl->mEventData, - mImpl->mModel->mLogicalModel, - startOfSelectedText, - lengthOfSelectedText ); - fontDescriptionRun.width = width; - fontDescriptionRun.widthDefined = true; + if( EventData::SELECTING == mImpl->mEventData->mState ) + { + // Update a font description run for the selecting state. + FontDescriptionRun& fontDescriptionRun = UpdateSelectionFontStyleRun( mImpl->mEventData, + mImpl->mModel->mLogicalModel, + startOfSelectedText, + lengthOfSelectedText ); + + fontDescriptionRun.width = width; + fontDescriptionRun.widthDefined = true; + + mImpl->mTextUpdateInfo.mCharacterIndex = startOfSelectedText; + mImpl->mTextUpdateInfo.mNumberOfCharactersToRemove = lengthOfSelectedText; + mImpl->mTextUpdateInfo.mNumberOfCharactersToAdd = lengthOfSelectedText; + } + else + { + mImpl->mTextUpdateInfo.mCharacterIndex = 0; + mImpl->mTextUpdateInfo.mNumberOfCharactersToRemove = mImpl->mTextUpdateInfo.mPreviousNumberOfCharacters; + mImpl->mTextUpdateInfo.mNumberOfCharactersToAdd = mImpl->mModel->mLogicalModel->mText.Count(); + } // Request to relayout. mImpl->mOperationsPending = static_cast( mImpl->mOperationsPending | @@ -1537,10 +1702,6 @@ void Controller::SetInputFontWidth( FontWidth width ) mImpl->mRecalculateNaturalSize = true; mImpl->RequestRelayout(); - mImpl->mTextUpdateInfo.mCharacterIndex = startOfSelectedText; - mImpl->mTextUpdateInfo.mNumberOfCharactersToRemove = lengthOfSelectedText; - mImpl->mTextUpdateInfo.mNumberOfCharactersToAdd = lengthOfSelectedText; - // As the font might change, recalculate the handle positions is needed. mImpl->mEventData->mUpdateLeftSelectionPosition = true; mImpl->mEventData->mUpdateRightSelectionPosition = true; @@ -1579,17 +1740,32 @@ void Controller::SetInputFontSlant( FontSlant slant ) mImpl->mEventData->mInputStyle.slant = slant; mImpl->mEventData->mInputStyle.isSlantDefined = true; - if( EventData::SELECTING == mImpl->mEventData->mState ) + if( EventData::SELECTING == mImpl->mEventData->mState || EventData::EDITING == mImpl->mEventData->mState || EventData::INACTIVE == mImpl->mEventData->mState ) { CharacterIndex startOfSelectedText = 0u; Length lengthOfSelectedText = 0u; - FontDescriptionRun& fontDescriptionRun = UpdateSelectionFontStyleRun( mImpl->mEventData, - mImpl->mModel->mLogicalModel, - startOfSelectedText, - lengthOfSelectedText ); - fontDescriptionRun.slant = slant; - fontDescriptionRun.slantDefined = true; + if( EventData::SELECTING == mImpl->mEventData->mState ) + { + // Update a font description run for the selecting state. + FontDescriptionRun& fontDescriptionRun = UpdateSelectionFontStyleRun( mImpl->mEventData, + mImpl->mModel->mLogicalModel, + startOfSelectedText, + lengthOfSelectedText ); + + fontDescriptionRun.slant = slant; + fontDescriptionRun.slantDefined = true; + + mImpl->mTextUpdateInfo.mCharacterIndex = startOfSelectedText; + mImpl->mTextUpdateInfo.mNumberOfCharactersToRemove = lengthOfSelectedText; + mImpl->mTextUpdateInfo.mNumberOfCharactersToAdd = lengthOfSelectedText; + } + else + { + mImpl->mTextUpdateInfo.mCharacterIndex = 0; + mImpl->mTextUpdateInfo.mNumberOfCharactersToRemove = mImpl->mTextUpdateInfo.mPreviousNumberOfCharacters; + mImpl->mTextUpdateInfo.mNumberOfCharactersToAdd = mImpl->mModel->mLogicalModel->mText.Count(); + } // Request to relayout. mImpl->mOperationsPending = static_cast( mImpl->mOperationsPending | @@ -1603,10 +1779,6 @@ void Controller::SetInputFontSlant( FontSlant slant ) mImpl->mRecalculateNaturalSize = true; mImpl->RequestRelayout(); - mImpl->mTextUpdateInfo.mCharacterIndex = startOfSelectedText; - mImpl->mTextUpdateInfo.mNumberOfCharactersToRemove = lengthOfSelectedText; - mImpl->mTextUpdateInfo.mNumberOfCharactersToAdd = lengthOfSelectedText; - // As the font might change, recalculate the handle positions is needed. mImpl->mEventData->mUpdateLeftSelectionPosition = true; mImpl->mEventData->mUpdateRightSelectionPosition = true; @@ -1645,17 +1817,32 @@ void Controller::SetInputFontPointSize( float size ) mImpl->mEventData->mInputStyle.size = size; mImpl->mEventData->mInputStyle.isSizeDefined = true; - if( EventData::SELECTING == mImpl->mEventData->mState ) + if( EventData::SELECTING == mImpl->mEventData->mState || EventData::EDITING == mImpl->mEventData->mState || EventData::INACTIVE == mImpl->mEventData->mState ) { CharacterIndex startOfSelectedText = 0u; Length lengthOfSelectedText = 0u; - FontDescriptionRun& fontDescriptionRun = UpdateSelectionFontStyleRun( mImpl->mEventData, - mImpl->mModel->mLogicalModel, - startOfSelectedText, - lengthOfSelectedText ); - fontDescriptionRun.size = static_cast( size * 64.f ); - fontDescriptionRun.sizeDefined = true; + if( EventData::SELECTING == mImpl->mEventData->mState ) + { + // Update a font description run for the selecting state. + FontDescriptionRun& fontDescriptionRun = UpdateSelectionFontStyleRun( mImpl->mEventData, + mImpl->mModel->mLogicalModel, + startOfSelectedText, + lengthOfSelectedText ); + + fontDescriptionRun.size = static_cast( size * 64.f ); + fontDescriptionRun.sizeDefined = true; + + mImpl->mTextUpdateInfo.mCharacterIndex = startOfSelectedText; + mImpl->mTextUpdateInfo.mNumberOfCharactersToRemove = lengthOfSelectedText; + mImpl->mTextUpdateInfo.mNumberOfCharactersToAdd = lengthOfSelectedText; + } + else + { + mImpl->mTextUpdateInfo.mCharacterIndex = 0; + mImpl->mTextUpdateInfo.mNumberOfCharactersToRemove = mImpl->mTextUpdateInfo.mPreviousNumberOfCharacters; + mImpl->mTextUpdateInfo.mNumberOfCharactersToAdd = mImpl->mModel->mLogicalModel->mText.Count(); + } // Request to relayout. mImpl->mOperationsPending = static_cast( mImpl->mOperationsPending | @@ -1669,10 +1856,6 @@ void Controller::SetInputFontPointSize( float size ) mImpl->mRecalculateNaturalSize = true; mImpl->RequestRelayout(); - mImpl->mTextUpdateInfo.mCharacterIndex = startOfSelectedText; - mImpl->mTextUpdateInfo.mNumberOfCharactersToRemove = lengthOfSelectedText; - mImpl->mTextUpdateInfo.mNumberOfCharactersToAdd = lengthOfSelectedText; - // As the font might change, recalculate the handle positions is needed. mImpl->mEventData->mUpdateLeftSelectionPosition = true; mImpl->mEventData->mUpdateRightSelectionPosition = true; @@ -1908,7 +2091,6 @@ Vector3 Controller::GetNaturalSize() GET_SCRIPTS | VALIDATE_FONTS | GET_LINE_BREAKS | - GET_WORD_BREAKS | BIDI_INFO | SHAPE_TEXT | GET_GLYPH_METRICS ); @@ -1968,6 +2150,97 @@ Vector3 Controller::GetNaturalSize() return naturalSize; } +bool Controller::CheckForTextFit( float pointSize, Size& layoutSize ) +{ + Size textSize; + mImpl->mFontDefaults->mFitPointSize = pointSize; + mImpl->mFontDefaults->sizeDefined = true; + ClearFontData(); + + // Operations that can be done only once until the text changes. + const OperationsMask onlyOnceOperations = static_cast( CONVERT_TO_UTF32 | + GET_SCRIPTS | + VALIDATE_FONTS | + GET_LINE_BREAKS | + BIDI_INFO | + SHAPE_TEXT| + GET_GLYPH_METRICS ); + + mImpl->mTextUpdateInfo.mParagraphCharacterIndex = 0u; + mImpl->mTextUpdateInfo.mRequestedNumberOfCharacters = mImpl->mModel->mLogicalModel->mText.Count(); + + // Make sure the model is up-to-date before layouting + mImpl->UpdateModel( onlyOnceOperations ); + + DoRelayout( Size( layoutSize.width, MAX_FLOAT ), + static_cast( onlyOnceOperations | LAYOUT), + textSize); + + // Clear the update info. This info will be set the next time the text is updated. + mImpl->mTextUpdateInfo.Clear(); + mImpl->mTextUpdateInfo.mClearAll = true; + + if( textSize.width > layoutSize.width || textSize.height > layoutSize.height ) + { + return false; + } + return true; +} + +void Controller::FitPointSizeforLayout( Size layoutSize ) +{ + const OperationsMask operations = mImpl->mOperationsPending; + if( NO_OPERATION != ( UPDATE_LAYOUT_SIZE & operations ) || mImpl->mTextFitContentSize != layoutSize ) + { + bool actualellipsis = mImpl->mModel->mElideEnabled; + float minPointSize = mImpl->mTextFitMinSize; + float maxPointSize = mImpl->mTextFitMaxSize; + float pointInterval = mImpl->mTextFitStepSize; + + mImpl->mModel->mElideEnabled = false; + Vector pointSizeArray; + + // check zero value + if( pointInterval < 1.f ) + { + mImpl->mTextFitStepSize = pointInterval = 1.0f; + } + + pointSizeArray.Reserve( static_cast< unsigned int >( ceil( ( maxPointSize - minPointSize ) / pointInterval ) ) ); + + for( float i = minPointSize; i < maxPointSize; i += pointInterval ) + { + pointSizeArray.PushBack( i ); + } + + pointSizeArray.PushBack( maxPointSize ); + + int bestSizeIndex = 0; + int min = bestSizeIndex + 1; + int max = pointSizeArray.Size() - 1; + while( min <= max ) + { + int destI = ( min + max ) / 2; + + if( CheckForTextFit( pointSizeArray[destI], layoutSize ) ) + { + bestSizeIndex = min; + min = destI + 1; + } + else + { + max = destI - 1; + bestSizeIndex = max; + } + } + + mImpl->mModel->mElideEnabled = actualellipsis; + mImpl->mFontDefaults->mFitPointSize = pointSizeArray[bestSizeIndex]; + mImpl->mFontDefaults->sizeDefined = true; + ClearFontData(); + } +} + float Controller::GetHeightForWidth( float width ) { DALI_LOG_INFO( gLogFilter, Debug::Verbose, "-->Controller::GetHeightForWidth %p width %f\n", this, width ); @@ -1984,7 +2257,6 @@ float Controller::GetHeightForWidth( float width ) GET_SCRIPTS | VALIDATE_FONTS | GET_LINE_BREAKS | - GET_WORD_BREAKS | BIDI_INFO | SHAPE_TEXT | GET_GLYPH_METRICS ); @@ -2206,7 +2478,6 @@ Toolkit::DevelText::TextDirection::Type Controller::GetTextDirection() GET_SCRIPTS | VALIDATE_FONTS | GET_LINE_BREAKS | - GET_WORD_BREAKS | BIDI_INFO | SHAPE_TEXT | GET_GLYPH_METRICS ); @@ -2230,6 +2501,9 @@ Toolkit::DevelText::TextDirection::Type Controller::GetTextDirection() // Clear the update info. This info will be set the next time the text is updated. mImpl->mTextUpdateInfo.Clear(); + // FullRelayoutNeeded should be true because DoRelayout is MAX_FLOAT, MAX_FLOAT. + mImpl->mTextUpdateInfo.mFullRelayoutNeeded = true; + mImpl->mUpdateTextDirection = false; } @@ -2608,9 +2882,9 @@ bool Controller::KeyEvent( const Dali::KeyEvent& keyEvent ) // This branch avoids calling the InsertText() method of the 'else' branch which can delete selected text. } - else if( Dali::DALI_KEY_SHIFT_LEFT == keyCode ) + else if( ( Dali::DALI_KEY_SHIFT_LEFT == keyCode ) || ( Dali::DALI_KEY_SHIFT_RIGHT == keyCode ) ) { - // DALI_KEY_SHIFT_LEFT is the key code for the Left Shift. It's sent (by the InputMethodContext?) when the predictive text is enabled + // DALI_KEY_SHIFT_LEFT or DALI_KEY_SHIFT_RIGHT is the key code for Shift. It's sent (by the InputMethodContext?) when the predictive text is enabled // and a character is typed after the type of a upper case latin character. // Do nothing. @@ -2626,20 +2900,26 @@ bool Controller::KeyEvent( const Dali::KeyEvent& keyEvent ) { DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Controller::KeyEvent %p keyString %s\n", this, keyString.c_str() ); - // InputMethodContext is no longer handling key-events - mImpl->ClearPreEditFlag(); + if( !keyString.empty() ) + { + // InputMethodContext is no longer handling key-events + mImpl->ClearPreEditFlag(); - InsertText( keyString, COMMIT ); - textChanged = true; + InsertText( keyString, COMMIT ); + + textChanged = true; + + // Will request for relayout. + relayoutNeeded = true; + } - // Will request for relayout. - relayoutNeeded = true; } if ( ( mImpl->mEventData->mState != EventData::INTERRUPTED ) && ( mImpl->mEventData->mState != EventData::INACTIVE ) && ( !isNullKey ) && ( Dali::DALI_KEY_SHIFT_LEFT != keyCode ) && + ( Dali::DALI_KEY_SHIFT_RIGHT != keyCode ) && ( Dali::DALI_KEY_VOLUME_UP != keyCode ) && ( Dali::DALI_KEY_VOLUME_DOWN != keyCode ) ) { @@ -2808,6 +3088,37 @@ void Controller::LongPressEvent( Gesture::State state, float x, float y ) } } +void Controller::SelectEvent( float x, float y, SelectionType selectType ) +{ + DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Controller::SelectEvent\n" ); + + if( NULL != mImpl->mEventData ) + { + if( selectType == SelectionType::ALL ) + { + Event event( Event::SELECT_ALL ); + mImpl->mEventData->mEventQueue.push_back( event ); + } + else if( selectType == SelectionType::NONE ) + { + Event event( Event::SELECT_NONE ); + mImpl->mEventData->mEventQueue.push_back( event ); + } + else + { + Event event( Event::SELECT ); + event.p2.mFloat = x; + event.p3.mFloat = y; + mImpl->mEventData->mEventQueue.push_back( event ); + } + + mImpl->mEventData->mCheckScrollAmount = true; + mImpl->mEventData->mIsLeftHandleSelected = true; + mImpl->mEventData->mIsRightHandleSelected = true; + mImpl->RequestRelayout(); + } +} + InputMethodContext::CallbackData Controller::OnInputMethodContextEvent( InputMethodContext& inputMethodContext, const InputMethodContext::EventData& inputMethodContextEvent ) { // Whether the text needs to be relaid-out. @@ -3075,14 +3386,14 @@ void Controller::TextPopupButtonTouched( Dali::Toolkit::TextSelectionPopup::Butt if( mImpl->mEventData->mSelectionEnabled ) { // Creates a SELECT event. - SelectEvent( currentCursorPosition.x, currentCursorPosition.y, false ); + SelectEvent( currentCursorPosition.x, currentCursorPosition.y, SelectionType::INTERACTIVE ); } break; } case Toolkit::TextSelectionPopup::SELECT_ALL: { // Creates a SELECT_ALL event - SelectEvent( 0.f, 0.f, true ); + SelectEvent( 0.f, 0.f, SelectionType::ALL ); break; } case Toolkit::TextSelectionPopup::CLIPBOARD: @@ -3221,14 +3532,14 @@ void Controller::InsertText( const std::string& text, Controller::InsertType typ mImpl->mModel->mLogicalModel->RetrieveStyle( styleIndex, style ); // Whether to add a new text color run. - const bool addColorRun = ( style.textColor != mImpl->mEventData->mInputStyle.textColor ); + const bool addColorRun = ( style.textColor != mImpl->mEventData->mInputStyle.textColor ) && !mImpl->mEventData->mInputStyle.isDefaultColor; // Whether to add a new font run. - const bool addFontNameRun = style.familyName != mImpl->mEventData->mInputStyle.familyName; - const bool addFontWeightRun = style.weight != mImpl->mEventData->mInputStyle.weight; - const bool addFontWidthRun = style.width != mImpl->mEventData->mInputStyle.width; - const bool addFontSlantRun = style.slant != mImpl->mEventData->mInputStyle.slant; - const bool addFontSizeRun = style.size != mImpl->mEventData->mInputStyle.size; + const bool addFontNameRun = ( style.familyName != mImpl->mEventData->mInputStyle.familyName ) && mImpl->mEventData->mInputStyle.isFamilyDefined; + const bool addFontWeightRun = ( style.weight != mImpl->mEventData->mInputStyle.weight ) && mImpl->mEventData->mInputStyle.isWeightDefined; + const bool addFontWidthRun = ( style.width != mImpl->mEventData->mInputStyle.width ) && mImpl->mEventData->mInputStyle.isWidthDefined; + const bool addFontSlantRun = ( style.slant != mImpl->mEventData->mInputStyle.slant ) && mImpl->mEventData->mInputStyle.isSlantDefined; + const bool addFontSizeRun = ( style.size != mImpl->mEventData->mInputStyle.size ) && mImpl->mEventData->mInputStyle.isSizeDefined ; // Add style runs. if( addColorRun ) @@ -3451,6 +3762,13 @@ bool Controller::RemoveText( int cursorOffset, } } + // If the number of current text and the number of characters to be deleted are same, + // it means all texts should be removed and all Preedit variables should be initialized. + if( ( currentText.Count() - numberOfCharacters == 0 ) && ( cursorIndex == 0 ) ) + { + mImpl->ClearPreEditFlag(); + } + // Updates the text style runs by removing characters. Runs with no characters are removed. mImpl->mModel->mLogicalModel->UpdateTextStyleRuns( cursorIndex, -numberOfCharacters ); @@ -3465,6 +3783,11 @@ bool Controller::RemoveText( int cursorOffset, mImpl->mEventData->mScrollAfterDelete = true; + if( EventData::INACTIVE == mImpl->mEventData->mState ) + { + mImpl->ChangeState( EventData::EDITING ); + } + DALI_LOG_INFO( gLogFilter, Debug::General, "Controller::RemoveText %p removed %d\n", this, numberOfCharacters ); removed = true; } @@ -3492,6 +3815,16 @@ bool Controller::RemoveSelectedText() return textRemoved; } +std::string Controller::GetSelectedText() +{ + std::string text; + if( EventData::SELECTING == mImpl->mEventData->mState ) + { + mImpl->RetrieveSelection( text, false ); + } + return text; +} + // private : Relayout. bool Controller::DoRelayout( const Size& size, @@ -3530,7 +3863,7 @@ bool Controller::DoRelayout( const Size& size, // Make sure the index is not out of bound if ( charactersToGlyph.Count() != glyphsPerCharacter.Count() || requestedNumberOfCharacters > charactersToGlyph.Count() || - ( lastIndex >= charactersToGlyph.Count() && charactersToGlyph.Count() > 0u ) ) + ( lastIndex > charactersToGlyph.Count() && charactersToGlyph.Count() > 0u ) ) { std::string currentText; GetText( currentText ); @@ -3557,38 +3890,16 @@ bool Controller::DoRelayout( const Size& size, return true; } - const Vector& lineBreakInfo = mImpl->mModel->mLogicalModel->mLineBreakInfo; - const Vector& wordBreakInfo = mImpl->mModel->mLogicalModel->mWordBreakInfo; - const Vector& characterDirection = mImpl->mModel->mLogicalModel->mCharacterDirections; - const Vector& glyphs = mImpl->mModel->mVisualModel->mGlyphs; - const Vector& glyphsToCharactersMap = mImpl->mModel->mVisualModel->mGlyphsToCharacters; - const Vector& charactersPerGlyph = mImpl->mModel->mVisualModel->mCharactersPerGlyph; - const Character* const textBuffer = mImpl->mModel->mLogicalModel->mText.Begin(); - const float outlineWidth = static_cast( mImpl->mModel->GetOutlineWidth() ); - // Set the layout parameters. Layout::Parameters layoutParameters( size, - textBuffer, - lineBreakInfo.Begin(), - wordBreakInfo.Begin(), - ( 0u != characterDirection.Count() ) ? characterDirection.Begin() : NULL, - glyphs.Begin(), - glyphsToCharactersMap.Begin(), - charactersPerGlyph.Begin(), - charactersToGlyphBuffer, - glyphsPerCharacterBuffer, - totalNumberOfGlyphs, - mImpl->mModel->mHorizontalAlignment, - mImpl->mModel->mLineWrapMode, - outlineWidth, - mImpl->mModel->mIgnoreSpacesAfterText, - mImpl->mModel->mMatchSystemLanguageDirection ); + mImpl->mModel); // Resize the vector of positions to have the same size than the vector of glyphs. Vector& glyphPositions = mImpl->mModel->mVisualModel->mGlyphPositions; glyphPositions.Resize( totalNumberOfGlyphs ); // Whether the last character is a new paragraph character. + const Character* const textBuffer = mImpl->mModel->mLogicalModel->mText.Begin(); mImpl->mTextUpdateInfo.mIsLastCharacterNewParagraph = TextAbstraction::IsNewParagraph( *( textBuffer + ( mImpl->mModel->mLogicalModel->mText.Count() - 1u ) ) ); layoutParameters.isLastNewParagraph = mImpl->mTextUpdateInfo.mIsLastCharacterNewParagraph; @@ -3624,8 +3935,6 @@ bool Controller::DoRelayout( const Size& size, bool isAutoScrollEnabled = mImpl->mIsAutoScrollEnabled; Size newLayoutSize; viewUpdated = mImpl->mLayoutEngine.LayoutText( layoutParameters, - glyphPositions, - mImpl->mModel->mVisualModel->mLines, newLayoutSize, elideTextEnabled, isAutoScrollEnabled ); @@ -3642,46 +3951,10 @@ bool Controller::DoRelayout( const Size& size, mImpl->mIsTextDirectionRTL = false; } - // Reorder the lines - if( NO_OPERATION != ( REORDER & operations ) ) + if ( ( NO_OPERATION != ( UPDATE_DIRECTION & operations ) ) && !mImpl->mModel->mVisualModel->mLines.Empty() ) { - Vector& bidirectionalInfo = mImpl->mModel->mLogicalModel->mBidirectionalParagraphInfo; - Vector& bidirectionalLineInfo = mImpl->mModel->mLogicalModel->mBidirectionalLineInfo; - - // Check first if there are paragraphs with bidirectional info. - if( 0u != bidirectionalInfo.Count() ) - { - // Get the lines - const Length numberOfLines = mImpl->mModel->mVisualModel->mLines.Count(); - - // Reorder the lines. - bidirectionalLineInfo.Reserve( numberOfLines ); // Reserve because is not known yet how many lines have right to left characters. - ReorderLines( bidirectionalInfo, - startIndex, - requestedNumberOfCharacters, - mImpl->mModel->mVisualModel->mLines, - bidirectionalLineInfo ); - - // Set the bidirectional info per line into the layout parameters. - layoutParameters.lineBidirectionalInfoRunsBuffer = bidirectionalLineInfo.Begin(); - layoutParameters.numberOfBidirectionalInfoRuns = bidirectionalLineInfo.Count(); - - // Re-layout the text. Reorder those lines with right to left characters. - mImpl->mLayoutEngine.ReLayoutRightToLeftLines( layoutParameters, - startIndex, - requestedNumberOfCharacters, - glyphPositions ); - - if ( ( NO_OPERATION != ( UPDATE_DIRECTION & operations ) ) && ( numberOfLines > 0 ) ) - { - const LineRun* const firstline = mImpl->mModel->mVisualModel->mLines.Begin(); - if ( firstline ) - { - mImpl->mIsTextDirectionRTL = firstline->direction; - } - } - } - } // REORDER + mImpl->mIsTextDirectionRTL = mImpl->mModel->mVisualModel->mLines[0u].direction; + } // Sets the layout size. if( NO_OPERATION != ( UPDATE_LAYOUT_SIZE & operations ) ) @@ -3696,11 +3969,23 @@ bool Controller::DoRelayout( const Size& size, // The laid-out lines. Vector& lines = mImpl->mModel->mVisualModel->mLines; + CharacterIndex alignStartIndex = startIndex; + Length alignRequestedNumberOfCharacters = requestedNumberOfCharacters; + + // the whole text needs to be full aligned. + // If you do not do a full aligned, only the last line of the multiline input is aligned. + if( mImpl->mEventData && mImpl->mEventData->mUpdateAlignment ) + { + alignStartIndex = 0u; + alignRequestedNumberOfCharacters = mImpl->mModel->mLogicalModel->mText.Count(); + mImpl->mEventData->mUpdateAlignment = false; + } + // Need to align with the control's size as the text may contain lines // starting either with left to right text or right to left. mImpl->mLayoutEngine.Align( size, - startIndex, - requestedNumberOfCharacters, + alignStartIndex, + alignRequestedNumberOfCharacters, mImpl->mModel->mHorizontalAlignment, lines, mImpl->mModel->mAlignmentOffset, @@ -3856,32 +4141,6 @@ void Controller::TextDeletedEvent() mImpl->mOperationsPending = ALL_OPERATIONS; } -void Controller::SelectEvent( float x, float y, bool selectAll ) -{ - DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Controller::SelectEvent\n" ); - - if( NULL != mImpl->mEventData ) - { - if( selectAll ) - { - Event event( Event::SELECT_ALL ); - mImpl->mEventData->mEventQueue.push_back( event ); - } - else - { - Event event( Event::SELECT ); - event.p2.mFloat = x; - event.p3.mFloat = y; - mImpl->mEventData->mEventQueue.push_back( event ); - } - - mImpl->mEventData->mCheckScrollAmount = true; - mImpl->mEventData->mIsLeftHandleSelected = true; - mImpl->mEventData->mIsRightHandleSelected = true; - mImpl->RequestRelayout(); - } -} - bool Controller::DeleteEvent( int keyCode ) { DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Controller::KeyEvent %p KeyCode : %d \n", this, keyCode ); @@ -4104,6 +4363,11 @@ bool Controller::ShouldClearFocusOnEscape() const return mImpl->mShouldClearFocusOnEscape; } +Actor Controller::CreateBackgroundActor() +{ + return mImpl->CreateBackgroundActor(); +} + // private : Private contructors & copy operator. Controller::Controller()