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=4ce4b5a1c497f312e853d9d3b544161180bc3a3b;hp=17456863180c97681ac4340b492958c516b17c7b;hb=c7e73b4c3dc56c3e5ed45a6ce5853280c7679a47;hpb=89f8a8b49600d9bd38db894616bb319ff4c6a9fa diff --git a/dali-toolkit/internal/text/text-controller.cpp b/dali-toolkit/internal/text/text-controller.cpp index 1745686..4ce4b5a 100755 --- a/dali-toolkit/internal/text/text-controller.cpp +++ b/dali-toolkit/internal/text/text-controller.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -49,6 +49,10 @@ 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"; @@ -134,7 +138,7 @@ ControllerPtr Controller::New( ControlInterface* controlInterface, // public : Configure the text controller. -void Controller::EnableTextInput( DecoratorPtr decorator ) +void Controller::EnableTextInput( DecoratorPtr decorator, InputMethodContext& inputMethodContext ) { if( !decorator ) { @@ -147,7 +151,7 @@ void Controller::EnableTextInput( DecoratorPtr decorator ) if( NULL == mImpl->mEventData ) { - mImpl->mEventData = new EventData( decorator ); + mImpl->mEventData = new EventData( decorator, inputMethodContext ); } } @@ -164,7 +168,14 @@ void Controller::SetGlyphType( TextAbstraction::GlyphType glyphType ) void Controller::SetMarkupProcessorEnabled( bool enable ) { - mImpl->mMarkupProcessorEnabled = enable; + if( enable != mImpl->mMarkupProcessorEnabled ) + { + //If Text was already set, call the SetText again for enabling or disabling markup + mImpl->mMarkupProcessorEnabled = enable; + std::string text; + GetText( text ); + SetText( text ); + } } bool Controller::IsMarkupProcessorEnabled() const @@ -218,7 +229,7 @@ bool Controller::IsAutoScrollEnabled() const CharacterDirection Controller::GetAutoScrollDirection() const { - return mImpl->mAutoScrollDirectionRTL; + return mImpl->mIsTextDirectionRTL; } float Controller::GetAutoScrollLineAlignment() const @@ -462,6 +473,26 @@ 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; +} + +void Controller::SetGrabHandleEnabled( bool enabled ) +{ + mImpl->mEventData->mGrabHandleEnabled = enabled; +} + +bool Controller::IsGrabHandleEnabled() const +{ + return mImpl->mEventData->mGrabHandleEnabled; +} + // public : Update void Controller::SetText( const std::string& text ) @@ -469,7 +500,7 @@ void Controller::SetText( const std::string& text ) DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Controller::SetText\n" ); // Reset keyboard as text changed - mImpl->ResetImfManager(); + mImpl->ResetInputMethodContext(); // Remove the previously set text and style. ResetText(); @@ -540,6 +571,9 @@ void Controller::SetText( const std::string& text ) // The natural size needs to be re-calculated. mImpl->mRecalculateNaturalSize = true; + // The text direction needs to be updated. + mImpl->mUpdateTextDirection = true; + // Apply modifications to the model mImpl->mOperationsPending = ALL_OPERATIONS; } @@ -1178,18 +1212,42 @@ 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(); } +void Controller::SetBackgroundColor( const Vector4& color ) +{ + mImpl->mModel->mVisualModel->SetBackgroundColor( color ); + + mImpl->RequestRelayout(); +} + +const Vector4& Controller::GetBackgroundColor() const +{ + return mImpl->mModel->mVisualModel->GetBackgroundColor(); +} + +void Controller::SetBackgroundEnabled( bool enabled ) +{ + mImpl->mModel->mVisualModel->SetBackgroundEnabled( enabled ); + + mImpl->RequestRelayout(); +} + +bool Controller::IsBackgroundEnabled() const +{ + return mImpl->mModel->mVisualModel->IsBackgroundEnabled(); +} + void Controller::SetDefaultEmbossProperties( const std::string& embossProperties ) { if( NULL == mImpl->mEmbossDefaults ) @@ -1230,10 +1288,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 @@ -1855,6 +1918,7 @@ Vector3 Controller::GetNaturalSize() // 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 size. mImpl->mModel->mVisualModel->mControlSize = actualControlSize; @@ -1926,6 +1990,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; @@ -2099,6 +2164,58 @@ void Controller::GetPlaceholderProperty( Property::Map& map ) } } +Toolkit::DevelText::TextDirection::Type Controller::GetTextDirection() +{ + // Make sure the model is up-to-date before layouting + ProcessModifyEvents(); + + if ( mImpl->mUpdateTextDirection ) + { + // 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 | + GET_WORD_BREAKS | + BIDI_INFO | + SHAPE_TEXT | + GET_GLYPH_METRICS ); + + // Set the update info to relayout the whole text. + 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 ); + + Vector3 naturalSize; + DoRelayout( Size( MAX_FLOAT, MAX_FLOAT ), + static_cast( onlyOnceOperations | + LAYOUT | REORDER | UPDATE_DIRECTION ), + naturalSize.GetVectorXY() ); + + // Do not do again the only once operations. + mImpl->mOperationsPending = static_cast( mImpl->mOperationsPending & ~onlyOnceOperations ); + + // Clear the update info. This info will be set the next time the text is updated. + mImpl->mTextUpdateInfo.Clear(); + + mImpl->mUpdateTextDirection = false; + } + + return mImpl->mIsTextDirectionRTL ? Toolkit::DevelText::TextDirection::RIGHT_TO_LEFT : 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 ) @@ -2131,6 +2248,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 | @@ -2279,7 +2403,7 @@ void Controller::KeyboardFocusGainEvent() mImpl->mEventData->mUpdateCursorPosition = true; //If editing started without tap event, cursor update must be triggered. mImpl->mEventData->mUpdateInputStyle = true; } - mImpl->NotifyImfMultiLineStatus(); + mImpl->NotifyInputMethodContextMultiLineStatus(); if( mImpl->IsShowingPlaceholderText() ) { // Show alternative placeholder-text when editing @@ -2322,6 +2446,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() ); @@ -2354,24 +2479,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 ) ) { @@ -2394,7 +2562,7 @@ bool Controller::KeyEvent( const Dali::KeyEvent& keyEvent ) } else if( Dali::DALI_KEY_SHIFT_LEFT == keyCode ) { - // DALI_KEY_SHIFT_LEFT is the key code for the Left Shift. It's sent (by the imf?) when the predictive text is enabled + // DALI_KEY_SHIFT_LEFT is the key code for the Left 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. @@ -2410,7 +2578,7 @@ bool Controller::KeyEvent( const Dali::KeyEvent& keyEvent ) { DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Controller::KeyEvent %p keyString %s\n", this, keyString.c_str() ); - // IMF manager is no longer handling key-events + // InputMethodContext is no longer handling key-events mImpl->ClearPreEditFlag(); InsertText( keyString, COMMIT ); @@ -2427,9 +2595,9 @@ bool Controller::KeyEvent( const Dali::KeyEvent& keyEvent ) ( Dali::DALI_KEY_VOLUME_UP != keyCode ) && ( Dali::DALI_KEY_VOLUME_DOWN != keyCode ) ) { - // Should not change the state if the key is the shift send by the imf manager. + // Should not change the state if the key is the shift send by the InputMethodContext. // Otherwise, when the state is SELECTING the text controller can't send the right - // surrounding info to the imf. + // surrounding info to the InputMethodContext. mImpl->ChangeState( EventData::EDITING ); // Will request for relayout. @@ -2526,7 +2694,7 @@ void Controller::TapEvent( unsigned int tapCount, float x, float y ) } // Reset keyboard as tap event has occurred. - mImpl->ResetImfManager(); + mImpl->ResetInputMethodContext(); } void Controller::PanEvent( Gesture::State state, const Vector2& displacement ) @@ -2576,8 +2744,8 @@ void Controller::LongPressEvent( Gesture::State state, float x, float y ) } else if( !mImpl->IsClipboardVisible() ) { - // Reset the imf manager to commit the pre-edit before selecting the text. - mImpl->ResetImfManager(); + // Reset the InputMethodContext to commit the pre-edit before selecting the text. + mImpl->ResetInputMethodContext(); Event event( Event::LONG_PRESS_EVENT ); event.p1.mInt = state; @@ -2592,35 +2760,35 @@ void Controller::LongPressEvent( Gesture::State state, float x, float y ) } } -ImfManager::ImfCallbackData Controller::OnImfEvent( ImfManager& imfManager, const ImfManager::ImfEventData& imfEvent ) +InputMethodContext::CallbackData Controller::OnInputMethodContextEvent( InputMethodContext& inputMethodContext, const InputMethodContext::EventData& inputMethodContextEvent ) { // Whether the text needs to be relaid-out. bool requestRelayout = false; - // Whether to retrieve the text and cursor position to be sent to the IMF manager. + // Whether to retrieve the text and cursor position to be sent to the InputMethodContext. bool retrieveText = false; bool retrieveCursor = false; - switch( imfEvent.eventName ) + switch( inputMethodContextEvent.eventName ) { - case ImfManager::COMMIT: + case InputMethodContext::COMMIT: { - InsertText( imfEvent.predictiveString, Text::Controller::COMMIT ); + InsertText( inputMethodContextEvent.predictiveString, Text::Controller::COMMIT ); requestRelayout = true; retrieveCursor = true; break; } - case ImfManager::PREEDIT: + case InputMethodContext::PRE_EDIT: { - InsertText( imfEvent.predictiveString, Text::Controller::PRE_EDIT ); + InsertText( inputMethodContextEvent.predictiveString, Text::Controller::PRE_EDIT ); requestRelayout = true; retrieveCursor = true; break; } - case ImfManager::DELETESURROUNDING: + case InputMethodContext::DELETE_SURROUNDING: { - const bool textDeleted = RemoveText( imfEvent.cursorOffset, - imfEvent.numberOfChars, + const bool textDeleted = RemoveText( inputMethodContextEvent.cursorOffset, + inputMethodContextEvent.numberOfChars, DONT_UPDATE_INPUT_STYLE ); if( textDeleted ) @@ -2641,20 +2809,20 @@ ImfManager::ImfCallbackData Controller::OnImfEvent( ImfManager& imfManager, cons } break; } - case ImfManager::GETSURROUNDING: + case InputMethodContext::GET_SURROUNDING: { retrieveText = true; retrieveCursor = true; break; } - case ImfManager::PRIVATECOMMAND: + case InputMethodContext::PRIVATE_COMMAND: { // PRIVATECOMMAND event is just for getting the private command message retrieveText = true; retrieveCursor = true; break; } - case ImfManager::VOID: + case InputMethodContext::VOID: { // do nothing break; @@ -2689,10 +2857,20 @@ 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 ); + InputMethodContext::CallbackData callbackData( ( retrieveText || retrieveCursor ), cursorPosition, text, false ); if( requestRelayout && ( NULL != mImpl->mEditableControlInterface ) ) @@ -2711,7 +2889,7 @@ void Controller::PasteClipboardItemEvent() std::string stringToPaste( notifier.GetContent() ); // Commit the current pre-edit text; the contents of the clipboard should be appended - mImpl->ResetImfManager(); + mImpl->ResetInputMethodContext(); // Temporary disable hiding clipboard mImpl->SetClipboardHideEnable( false ); @@ -2903,7 +3081,7 @@ void Controller::InsertText( const std::string& text, Controller::InsertType typ // TODO: At the moment the underline runs are only for pre-edit. mImpl->mModel->mVisualModel->mUnderlineRuns.Clear(); - // Remove the previous IMF pre-edit. + // Remove the previous InputMethodContext pre-edit. if( mImpl->mEventData->mPreEditFlag && ( 0u != mImpl->mEventData->mPreEditLength ) ) { removedPrevious = RemoveText( -static_cast( mImpl->mEventData->mPrimaryCursorPosition - mImpl->mEventData->mPreEditStartPosition ), @@ -2950,10 +3128,10 @@ void Controller::InsertText( const std::string& text, Controller::InsertType typ mImpl->ChangeState( EventData::EDITING ); - // Handle the IMF (predicitive text) state changes + // Handle the InputMethodContext (predicitive text) state changes if( COMMIT == type ) { - // IMF manager is no longer handling key-events + // InputMethodContext is no longer handling key-events mImpl->ClearPreEditFlag(); } else // PRE_EDIT @@ -3127,7 +3305,7 @@ void Controller::InsertText( const std::string& text, Controller::InsertType typ { DALI_LOG_INFO( gLogFilter, Debug::Verbose, "MaxLengthReached (%d)\n", mImpl->mModel->mLogicalModel->mText.Count() ); - mImpl->ResetImfManager(); + mImpl->ResetInputMethodContext(); if( NULL != mImpl->mEditableControlInterface ) { @@ -3300,6 +3478,22 @@ bool Controller::DoRelayout( const Size& size, const CharacterIndex lastIndex = startIndex + ( ( requestedNumberOfCharacters > 0u ) ? requestedNumberOfCharacters - 1u : 0u ); const GlyphIndex startGlyphIndex = mImpl->mTextUpdateInfo.mStartGlyphIndex; + + // Make sure the index is not out of bound + if ( charactersToGlyph.Count() != glyphsPerCharacter.Count() || + requestedNumberOfCharacters > charactersToGlyph.Count() || + ( lastIndex >= charactersToGlyph.Count() && charactersToGlyph.Count() > 0u ) ) + { + std::string currentText; + GetText( currentText ); + + DALI_LOG_ERROR( "Controller::DoRelayout: Attempting to access invalid buffer\n" ); + DALI_LOG_ERROR( "Current text is: %s\n", currentText.c_str() ); + DALI_LOG_ERROR( "startIndex: %u, lastIndex: %u, requestedNumberOfCharacters: %u, charactersToGlyph.Count = %lu, glyphsPerCharacter.Count = %lu\n", startIndex, lastIndex, requestedNumberOfCharacters, charactersToGlyph.Count(), glyphsPerCharacter.Count()); + + return false; + } + const Length numberOfGlyphs = ( requestedNumberOfCharacters > 0u ) ? *( charactersToGlyphBuffer + lastIndex ) + *( glyphsPerCharacterBuffer + lastIndex ) - startGlyphIndex : 0u; const Length totalNumberOfGlyphs = mImpl->mModel->mVisualModel->mGlyphs.Count(); @@ -3322,10 +3516,11 @@ 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, + const Vector2 sizeOffset = Vector2(outlineWidth * 2.0f, outlineWidth * 2.0f); // The outline should be fit into the bounding box + Layout::Parameters layoutParameters( size - sizeOffset, textBuffer, lineBreakInfo.Begin(), wordBreakInfo.Begin(), @@ -3392,7 +3587,7 @@ bool Controller::DoRelayout( const Size& size, if( NO_OPERATION != ( UPDATE_DIRECTION & operations ) ) { - mImpl->mAutoScrollDirectionRTL = false; + mImpl->mIsTextDirectionRTL = false; } // Reorder the lines @@ -3430,7 +3625,7 @@ bool Controller::DoRelayout( const Size& size, const LineRun* const firstline = mImpl->mModel->mVisualModel->mLines.Begin(); if ( firstline ) { - mImpl->mAutoScrollDirectionRTL = firstline->direction; + mImpl->mIsTextDirectionRTL = firstline->direction; } } } @@ -3463,7 +3658,7 @@ bool Controller::DoRelayout( const Size& size, #if defined(DEBUG_ENABLED) std::string currentText; GetText( currentText ); - DALI_LOG_INFO( gLogFilter, Debug::Concise, "Controller::DoRelayout [%p] mImpl->mAutoScrollDirectionRTL[%s] [%s]\n", this, (mImpl->mAutoScrollDirectionRTL)?"true":"false", currentText.c_str() ); + DALI_LOG_INFO( gLogFilter, Debug::Concise, "Controller::DoRelayout [%p] mImpl->mIsTextDirectionRTL[%s] [%s]\n", this, (mImpl->mIsTextDirectionRTL)?"true":"false", currentText.c_str() ); #endif DALI_LOG_INFO( gLogFilter, Debug::Verbose, "<--Controller::DoRelayout, view updated %s\n", ( viewUpdated ? "true" : "false" ) ); return viewUpdated; @@ -3543,6 +3738,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 @@ -3554,6 +3753,9 @@ void Controller::TextReplacedEvent() // The natural size needs to be re-calculated. mImpl->mRecalculateNaturalSize = true; + // The text direction needs to be updated. + mImpl->mUpdateTextDirection = true; + // Apply modifications to the model mImpl->mOperationsPending = ALL_OPERATIONS; } @@ -3572,6 +3774,9 @@ void Controller::TextInsertedEvent() // The natural size needs to be re-calculated. mImpl->mRecalculateNaturalSize = true; + // The text direction needs to be updated. + mImpl->mUpdateTextDirection = true; + // Apply modifications to the model; TODO - Optimize this mImpl->mOperationsPending = ALL_OPERATIONS; } @@ -3590,6 +3795,9 @@ void Controller::TextDeletedEvent() // The natural size needs to be re-calculated. mImpl->mRecalculateNaturalSize = true; + // The text direction needs to be updated. + mImpl->mUpdateTextDirection = true; + // Apply modifications to the model; TODO - Optimize this mImpl->mOperationsPending = ALL_OPERATIONS; } @@ -3631,7 +3839,7 @@ bool Controller::DeleteEvent( int keyCode ) return removed; } - // IMF manager is no longer handling key-events + // InputMethodContext is no longer handling key-events mImpl->ClearPreEditFlag(); if( EventData::SELECTING == mImpl->mEventData->mState ) @@ -3645,7 +3853,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, @@ -3691,6 +3899,9 @@ void Controller::ResetText() // The natural size needs to be re-calculated. mImpl->mRecalculateNaturalSize = true; + // The text direction needs to be updated. + mImpl->mUpdateTextDirection = true; + // Apply modifications to the model mImpl->mOperationsPending = ALL_OPERATIONS; } @@ -3757,6 +3968,9 @@ void Controller::ShowPlaceholderText() // The natural size needs to be re-calculated. mImpl->mRecalculateNaturalSize = true; + // The text direction needs to be updated. + mImpl->mUpdateTextDirection = true; + // Apply modifications to the model mImpl->mOperationsPending = ALL_OPERATIONS; @@ -3784,6 +3998,7 @@ void Controller::ClearFontData() mImpl->mOperationsPending = static_cast( mImpl->mOperationsPending | VALIDATE_FONTS | SHAPE_TEXT | + BIDI_INFO | GET_GLYPH_METRICS | LAYOUT | UPDATE_LAYOUT_SIZE |