X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali-toolkit%2Finternal%2Ftext%2Ftext-controller.cpp;h=a504bf6778f9a01660f03db410d05b512ee0f7df;hb=9817d4be0f95105f1cc8c5a211296da86af6d471;hp=2c42abdbd20082c127f0ef5aeae8d4780026ed6e;hpb=232082aeaf842a8dc87c2465123102a8bf30314e;p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git diff --git a/dali-toolkit/internal/text/text-controller.cpp b/dali-toolkit/internal/text/text-controller.cpp index 2c42abd..a504bf6 100755 --- a/dali-toolkit/internal/text/text-controller.cpp +++ b/dali-toolkit/internal/text/text-controller.cpp @@ -45,10 +45,16 @@ namespace Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, true, "LOG_TEXT_CONTROLS"); #endif +const int MAX_NUMBER_OF_CHARACTERS = 200000; + const float MAX_FLOAT = std::numeric_limits::max(); const std::string EMPTY_STRING(""); +const std::string KEY_C_NAME = "c"; +const std::string KEY_V_NAME = "v"; +const std::string KEY_X_NAME = "x"; + const char * const PLACEHOLDER_TEXT = "text"; const char * const PLACEHOLDER_TEXT_FOCUSED = "textFocused"; const char * const PLACEHOLDER_COLOR = "color"; @@ -469,6 +475,16 @@ bool Controller::IsSelectionEnabled() const return mImpl->mEventData->mSelectionEnabled; } +void Controller::SetShiftSelectionEnabled( bool enabled ) +{ + mImpl->mEventData->mShiftSelectionFlag = enabled; +} + +bool Controller::IsShiftSelectionEnabled() const +{ + return mImpl->mEventData->mShiftSelectionFlag; +} + // public : Update void Controller::SetText( const std::string& text ) @@ -1185,14 +1201,14 @@ const Vector4& Controller::GetOutlineColor() const return mImpl->mModel->mVisualModel->GetOutlineColor(); } -void Controller::SetOutlineWidth( float width ) +void Controller::SetOutlineWidth( unsigned int width ) { mImpl->mModel->mVisualModel->SetOutlineWidth( width ); mImpl->RequestRelayout(); } -float Controller::GetOutlineWidth() const +unsigned int Controller::GetOutlineWidth() const { return mImpl->mModel->mVisualModel->GetOutlineWidth(); } @@ -1237,10 +1253,15 @@ const std::string& Controller::GetDefaultOutlineProperties() const return EMPTY_STRING; } -void Controller::SetDefaultLineSpacing( float lineSpacing ) +bool Controller::SetDefaultLineSpacing( float lineSpacing ) { - //TODO finish implementation - mImpl->mLayoutEngine.SetDefaultLineSpacing( lineSpacing ); + if( std::abs(lineSpacing - mImpl->mLayoutEngine.GetDefaultLineSpacing()) > Math::MACHINE_EPSILON_1000 ) + { + mImpl->mLayoutEngine.SetDefaultLineSpacing(lineSpacing); + mImpl->mRecalculateNaturalSize = true; + return true; + } + return false; } float Controller::GetDefaultLineSpacing() const @@ -1933,6 +1954,7 @@ float Controller::GetHeightForWidth( float width ) // Clear the update info. This info will be set the next time the text is updated. mImpl->mTextUpdateInfo.Clear(); + mImpl->mTextUpdateInfo.mClearAll = true; // Restore the actual control's width. mImpl->mModel->mVisualModel->mControlSize.width = actualControlWidth; @@ -2106,6 +2128,34 @@ void Controller::GetPlaceholderProperty( Property::Map& map ) } } +Toolkit::DevelText::TextDirection::Type Controller::GetTextDirection() +{ + if( ( 0u == mImpl->mModel->mLogicalModel->mText.Count() ) ) + { + return Toolkit::DevelText::TextDirection::LEFT_TO_RIGHT; + } + + const Character character = mImpl->mModel->mLogicalModel->mText[0]; + Script script = TextAbstraction::GetCharacterScript( character ); + + if( TextAbstraction::IsRightToLeftScript( script ) ) + { + return Toolkit::DevelText::TextDirection::RIGHT_TO_LEFT; + } + + return Toolkit::DevelText::TextDirection::LEFT_TO_RIGHT; +} + +Toolkit::DevelText::VerticalLineAlignment::Type Controller::GetVerticalLineAlignment() const +{ + return mImpl->mModel->GetVerticalLineAlignment(); +} + +void Controller::SetVerticalLineAlignment( Toolkit::DevelText::VerticalLineAlignment::Type alignment ) +{ + mImpl->mModel->mVerticalLineAlignment = alignment; +} + // public : Relayout. Controller::UpdateTextType Controller::Relayout( const Size& size ) @@ -2138,6 +2188,13 @@ Controller::UpdateTextType Controller::Relayout( const Size& size ) { DALI_LOG_INFO( gLogFilter, Debug::Verbose, "new size (previous size %f,%f)\n", mImpl->mModel->mVisualModel->mControlSize.width, mImpl->mModel->mVisualModel->mControlSize.height ); + if( ( 0 == mImpl->mTextUpdateInfo.mNumberOfCharactersToAdd ) && + ( 0 == mImpl->mTextUpdateInfo.mPreviousNumberOfCharacters ) && + ( ( mImpl->mModel->mVisualModel->mControlSize.width < Math::MACHINE_EPSILON_1000 ) || ( mImpl->mModel->mVisualModel->mControlSize.height < Math::MACHINE_EPSILON_1000 ) ) ) + { + mImpl->mTextUpdateInfo.mNumberOfCharactersToAdd = mImpl->mModel->mLogicalModel->mText.Count(); + } + // Layout operations that need to be done if the size changes. mImpl->mOperationsPending = static_cast( mImpl->mOperationsPending | LAYOUT | @@ -2329,6 +2386,7 @@ bool Controller::KeyEvent( const Dali::KeyEvent& keyEvent ) { int keyCode = keyEvent.keyCode; const std::string& keyString = keyEvent.keyPressed; + const std::string keyName = keyEvent.keyPressedName; const bool isNullKey = ( 0 == keyCode ) && ( keyString.empty() ); @@ -2361,24 +2419,67 @@ bool Controller::KeyEvent( const Dali::KeyEvent& keyEvent ) uint32_t numberOfLines = mImpl->mModel->GetNumberOfLines(); // Logic to determine whether this text control will lose focus or not. - if( ( Dali::DALI_KEY_CURSOR_LEFT == keyCode && 0 == cursorPosition ) || - ( Dali::DALI_KEY_CURSOR_RIGHT == keyCode && numberOfCharacters == cursorPosition) || + if( ( Dali::DALI_KEY_CURSOR_LEFT == keyCode && 0 == cursorPosition && !keyEvent.IsShiftModifier() ) || + ( Dali::DALI_KEY_CURSOR_RIGHT == keyCode && numberOfCharacters == cursorPosition && !keyEvent.IsShiftModifier() ) || ( Dali::DALI_KEY_CURSOR_DOWN == keyCode && cursorLine == numberOfLines -1 ) || ( Dali::DALI_KEY_CURSOR_DOWN == keyCode && numberOfCharacters == cursorPosition && cursorLine -1 == numberOfLines -1 ) || ( Dali::DALI_KEY_CURSOR_UP == keyCode && cursorLine == 0 ) || ( Dali::DALI_KEY_CURSOR_UP == keyCode && numberOfCharacters == cursorPosition && cursorLine == 1 ) ) { + // Release the active highlight. + if( mImpl->mEventData->mState == EventData::SELECTING ) + { + mImpl->ChangeState( EventData::EDITING ); + + // Update selection position. + mImpl->mEventData->mLeftSelectionPosition = mImpl->mEventData->mPrimaryCursorPosition; + mImpl->mEventData->mRightSelectionPosition = mImpl->mEventData->mPrimaryCursorPosition; + mImpl->mEventData->mUpdateCursorPosition = true; + mImpl->RequestRelayout(); + } return false; } mImpl->mEventData->mCheckScrollAmount = true; Event event( Event::CURSOR_KEY_EVENT ); event.p1.mInt = keyCode; + event.p2.mBool = keyEvent.IsShiftModifier(); mImpl->mEventData->mEventQueue.push_back( event ); // Will request for relayout. relayoutNeeded = true; } + else if ( Dali::DevelKey::DALI_KEY_CONTROL_LEFT == keyCode || Dali::DevelKey::DALI_KEY_CONTROL_RIGHT == keyCode ) + { + // Left or Right Control key event is received before Ctrl-C/V/X key event is received + // If not handle it here, any selected text will be deleted + + // Do nothing + return false; + } + else if ( keyEvent.IsCtrlModifier() ) + { + bool consumed = false; + if (keyName == KEY_C_NAME) + { + // Ctrl-C to copy the selected text + TextPopupButtonTouched( Toolkit::TextSelectionPopup::COPY ); + consumed = true; + } + else if (keyName == KEY_V_NAME) + { + // Ctrl-V to paste the copied text + TextPopupButtonTouched( Toolkit::TextSelectionPopup::PASTE ); + consumed = true; + } + else if (keyName == KEY_X_NAME) + { + // Ctrl-X to cut the selected text + TextPopupButtonTouched( Toolkit::TextSelectionPopup::CUT ); + consumed = true; + } + return consumed; + } else if( ( Dali::DALI_KEY_BACKSPACE == keyCode ) || ( Dali::DevelKey::DALI_KEY_DELETE == keyCode ) ) { @@ -2388,7 +2489,8 @@ bool Controller::KeyEvent( const Dali::KeyEvent& keyEvent ) relayoutNeeded = true; } else if( IsKey( keyEvent, Dali::DALI_KEY_POWER ) || - IsKey( keyEvent, Dali::DALI_KEY_MENU ) || + IsKey( keyEvent, Dali::DALI_KEY_MENU ) || + IsKey( keyEvent, static_cast(Dali::DevelKey::DALI_KEY_SOURCE) ) || IsKey( keyEvent, Dali::DALI_KEY_HOME ) ) { // Power key/Menu/Home key behaviour does not allow edit mode to resume. @@ -2696,7 +2798,17 @@ ImfManager::ImfCallbackData Controller::OnImfEvent( ImfManager& imfManager, cons if( retrieveText ) { - mImpl->GetText( numberOfWhiteSpaces, text ); + if( !mImpl->IsShowingPlaceholderText() ) + { + // Retrieves the normal text string. + mImpl->GetText( numberOfWhiteSpaces, text ); + } + else + { + // When the current text is Placeholder Text, the surrounding text should be empty string. + // It means DALi should send empty string ("") to IME. + text = ""; + } } ImfManager::ImfCallbackData callbackData( ( retrieveText || retrieveCursor ), cursorPosition, text, false ); @@ -3163,6 +3275,9 @@ bool Controller::RemoveText( int cursorOffset, { bool removed = false; + // When the users press "Delete All" button, the IME sends numberOfCharacters as '200000' value which means the max number of characters. + const bool deleteAll = ( numberOfCharacters >= MAX_NUMBER_OF_CHARACTERS ); + if( NULL == mImpl->mEventData ) { return removed; @@ -3191,7 +3306,7 @@ bool Controller::RemoveText( int cursorOffset, } if( mImpl->mEventData->mPreEditFlag || // If the preedit flag is enabled, it means two (or more) of them came together i.e. when two keys have been pressed at the same time. - ( ( cursorIndex + numberOfCharacters ) <= mImpl->mTextUpdateInfo.mPreviousNumberOfCharacters ) ) + ( ( cursorIndex + numberOfCharacters ) <= mImpl->mTextUpdateInfo.mPreviousNumberOfCharacters ) || deleteAll /*'Delete All' button clicked*/ ) { // Mark the paragraphs to be updated. if( Layout::Engine::SINGLE_LINE_BOX == mImpl->mLayoutEngine.GetLayout() ) @@ -3329,7 +3444,7 @@ bool Controller::DoRelayout( const Size& size, const Vector& glyphsToCharactersMap = mImpl->mModel->mVisualModel->mGlyphsToCharacters; const Vector& charactersPerGlyph = mImpl->mModel->mVisualModel->mCharactersPerGlyph; const Character* const textBuffer = mImpl->mModel->mLogicalModel->mText.Begin(); - float outlineWidth = mImpl->mModel->GetOutlineWidth(); + const float outlineWidth = static_cast( mImpl->mModel->GetOutlineWidth() ); // Set the layout parameters. Layout::Parameters layoutParameters( size, @@ -3550,6 +3665,10 @@ void Controller::ProcessModifyEvents() { // When the text is being modified, delay cursor blinking mImpl->mEventData->mDecorator->DelayCursorBlink(); + + // Update selection position after modifying the text + mImpl->mEventData->mLeftSelectionPosition = mImpl->mEventData->mPrimaryCursorPosition; + mImpl->mEventData->mRightSelectionPosition = mImpl->mEventData->mPrimaryCursorPosition; } // Discard temporary text @@ -3652,7 +3771,7 @@ bool Controller::DeleteEvent( int keyCode ) 1, UPDATE_INPUT_STYLE ); } - else if( ( mImpl->mEventData->mPrimaryCursorPosition >= 0 ) && ( keyCode == Dali::DevelKey::DALI_KEY_DELETE ) ) + else if( keyCode == Dali::DevelKey::DALI_KEY_DELETE ) { // Remove the character after the current cursor position removed = RemoveText( 0, @@ -3791,6 +3910,7 @@ void Controller::ClearFontData() mImpl->mOperationsPending = static_cast( mImpl->mOperationsPending | VALIDATE_FONTS | SHAPE_TEXT | + BIDI_INFO | GET_GLYPH_METRICS | LAYOUT | UPDATE_LAYOUT_SIZE |