#include <dali-toolkit/internal/controls/text-view/text-processor.h>
#include <dali-toolkit/public-api/controls/buttons/push-button.h>
#include <dali-toolkit/public-api/controls/alignment/alignment.h>
+#include <dali-toolkit/public-api/controls/default-controls/solid-color-actor.h>
#include <dali/integration-api/debug.h>
const char* DEFAULT_SELECTION_HANDLE_TWO( DALI_IMAGE_DIR "text-input-selection-handle-right.png" );
const char* DEFAULT_SELECTION_HANDLE_ONE_PRESSED( DALI_IMAGE_DIR "text-input-selection-handle-left-press.png" );
const char* DEFAULT_SELECTION_HANDLE_TWO_PRESSED( DALI_IMAGE_DIR "text-input-selection-handle-right-press.png" );
-const char* DEFAULT_CURSOR( DALI_IMAGE_DIR "cursor.png" );
-
-const Vector4 DEFAULT_CURSOR_IMAGE_9_BORDER( 2.0f, 2.0f, 2.0f, 2.0f );
const std::size_t CURSOR_BLINK_INTERVAL = 500; ///< Cursor blink interval
const float CHARACTER_THRESHOLD( 2.5f ); ///< the threshold of a line.
const Vector3 DEFAULT_HANDLE_TWO_OFFSET(0.0f, -5.0f, 0.0f); ///< Handle Two's Offset
const float TOP_HANDLE_TOP_OFFSET( 34.0f); ///< Offset between top handle and cutCopyPaste pop-up
const float BOTTOM_HANDLE_BOTTOM_OFFSET(34.0f); ///< Offset between bottom handle and cutCopyPaste pop-up
-const float CURSOR_THICKNESS(6.0f);
+const float CURSOR_THICKNESS(4.0f);
const Degree CURSOR_ANGLE_OFFSET(2.0f); ///< Offset from the angle of italic angle.
+const Vector4 DEFAULT_CURSOR_COLOR(1.0f, 1.0f, 1.0f, 1.0f);
const std::string NEWLINE( "\n" );
SelectionFinished ///< Finished selected section
};
-/**
- * Whether the given style is the default style or not.
- * @param[in] style The given style.
- * @return \e true if the given style is the default. Otherwise it returns \e false.
- */
-bool IsDefaultStyle( const TextStyle& style )
-{
- return DEFAULT_TEXT_STYLE == style;
-}
-
-/**
- * Whether the given styled text is using the default style or not.
- * @param[in] textArray The given text.
- * @return \e true if the given styled text is using the default style. Otherwise it returns \e false.
- */
-bool IsTextDefaultStyle( const Toolkit::MarkupProcessor::StyledTextArray& textArray )
-{
- for( Toolkit::MarkupProcessor::StyledTextArray::const_iterator it = textArray.begin(), endIt = textArray.end(); it != endIt; ++it )
- {
- const TextStyle& style( (*it).mStyle );
-
- if( !IsDefaultStyle( style ) )
- {
- return false;
- }
- }
-
- return true;
-}
-
std::size_t FindVisibleCharacterLeft( std::size_t cursorPosition, const Toolkit::TextView::CharacterLayoutInfoContainer& characterLayoutInfoTable )
{
for( Toolkit::TextView::CharacterLayoutInfoContainer::const_reverse_iterator it = characterLayoutInfoTable.rbegin() + characterLayoutInfoTable.size() - cursorPosition, endIt = characterLayoutInfoTable.rend();
const Property::Index TextInput::SELECT_BUTTON_POSITION_PRIORITY_PROPERTY = Internal::TextInput::TEXTINPUT_PROPERTY_START_INDEX+11;
const Property::Index TextInput::SELECT_ALL_BUTTON_POSITION_PRIORITY_PROPERTY = Internal::TextInput::TEXTINPUT_PROPERTY_START_INDEX+12;
const Property::Index TextInput::CLIPBOARD_BUTTON_POSITION_PRIORITY_PROPERTY = Internal::TextInput::TEXTINPUT_PROPERTY_START_INDEX+13;
-
const Property::Index TextInput::POP_UP_OFFSET_FROM_TEXT_PROPERTY = Internal::TextInput::TEXTINPUT_PROPERTY_START_INDEX+14;
+const Property::Index TextInput::CURSOR_COLOR_PROPERTY = Internal::TextInput::TEXTINPUT_PROPERTY_START_INDEX+15;
+
namespace Internal
{
PropertyRegistration property13( typeRegistration, "select-all-button-position-priority", Toolkit::TextInput::SELECT_ALL_BUTTON_POSITION_PRIORITY_PROPERTY, Property::UNSIGNED_INTEGER, &TextInput::SetProperty, &TextInput::GetProperty );
PropertyRegistration property14( typeRegistration, "clipboard-button-position-priority", Toolkit::TextInput::CLIPBOARD_BUTTON_POSITION_PRIORITY_PROPERTY, Property::UNSIGNED_INTEGER, &TextInput::SetProperty, &TextInput::GetProperty );
PropertyRegistration property15( typeRegistration, "popup-offset-from-text", Toolkit::TextInput::POP_UP_OFFSET_FROM_TEXT_PROPERTY, Property::VECTOR4, &TextInput::SetProperty, &TextInput::GetProperty );
+PropertyRegistration property16( typeRegistration, "cursor-color", Toolkit::TextInput::CURSOR_COLOR_PROPERTY, Property::VECTOR4, &TextInput::SetProperty, &TextInput::GetProperty );
+
// [TextInput::HighlightInfo] /////////////////////////////////////////////////
TextInputPtr textInput(new TextInput());
// Pass ownership to CustomActor via derived handle
Dali::Toolkit::TextInput handle(*textInput);
+ handle.SetName( "TextInput");
textInput->Initialize();
-
return handle;
}
originY + boundingRectangle.height );
mBoundingRectangleWorldCoordinates = boundary;
-
- // Set Boundary for Popup so it keeps the Pop-up within the area also.
- mPopupPanel.SetPopupBoundary( boundingRectangle );
}
const Rect<float> TextInput::GetBoundingRectangle() const
{
Actor self = Self();
mActiveLayer = Layer::New();
+ mActiveLayer.SetName ( "ActiveLayerActor" );
mActiveLayer.SetAnchorPoint( AnchorPoint::CENTER);
mActiveLayer.SetParentOrigin( ParentOrigin::CENTER);
// Create 2 cursors (standard LTR and RTL cursor for when text can be added at
// different positions depending on language)
- Image mCursorImage = Image::New( DEFAULT_CURSOR );
- mCursor = CreateCursor( mCursorImage, DEFAULT_CURSOR_IMAGE_9_BORDER );
- mCursorRTL = CreateCursor( mCursorImage, DEFAULT_CURSOR_IMAGE_9_BORDER );
+ mCursor = CreateCursor(DEFAULT_CURSOR_COLOR);
+ mCursorRTL = CreateCursor(DEFAULT_CURSOR_COLOR);
Actor self = Self();
self.Add( mCursor );
void TextInput::OnRelaidOut( Vector2 size, ActorSizeContainer& container )
{
Relayout( mDisplayedTextView, size, container );
+ Relayout( mPopupPanel.GetRootActor(), size, container );
+
GetTextLayoutInfo();
DrawCursor();
mTextLayoutInfo.mScrollOffset = mDisplayedTextView.GetScrollPosition();
ReturnClosestIndex( tap.localPoint, mCursorPosition );
+ std::size_t start = 0;
+ std::size_t end = 0;
+ Dali::Toolkit::Internal::TextProcessor::FindNearestWord( mStyledText, mCursorPosition, start, end );
+
+ mCursorPosition = end; // Ensure cursor is positioned at end of selected word
+
ImfManager imfManager = ImfManager::Get();
if ( imfManager )
{
imfManager.NotifyCursorPosition();
}
- std::size_t start = 0;
- std::size_t end = 0;
- Dali::Toolkit::Internal::TextProcessor::FindNearestWord( mStyledText, mCursorPosition, start, end );
-
- SelectText( start, end );
+ if ( !mStyledText.at(end-1).mText[0].IsWhiteSpace() )
+ {
+ SelectText( start, end );
+ ShowPopupCutCopyPaste();
+ }
+ else
+ {
+ RemoveHighlight( false ); // Remove highlight but do not auto hide popup
+ HidePopup( false ); // Hide popup with setting to do auto show.
+ SetUpPopupSelection( false ); // Set to false so if nearest word is whitespace it will not show cut button.
+ ShowPopup();
+ }
}
- // if no text but clipboard has content then show paste option
- if ( ( mClipboard && mClipboard.NumberOfItems() ) || !mStyledText.empty() )
+ else if ( mClipboard && mClipboard.NumberOfItems() )
{
ShowPopupCutCopyPaste();
}
{
// Set the initial cursor position in the tap point.
ReturnClosestIndex(tap.localPoint, mCursorPosition );
-
- // Create the grab handle.
- // TODO Make this a re-usable function.
- if ( IsGrabHandleEnabled() )
- {
- const Vector3 cursorPosition = GetActualPositionFromCharacterPosition(mCursorPosition);
-
- CreateGrabHandle();
-
- mActualGrabHandlePosition.x = cursorPosition.x; // Set grab handle to be at the cursor position
- mActualGrabHandlePosition.y = cursorPosition.y; // Set grab handle to be at the cursor position
- mGrabHandle.SetPosition( mActualGrabHandlePosition + UI_OFFSET );
- ShowGrabHandleAndSetVisibility( mIsGrabHandleInScrollArea );
-
- }
-
- // Edit mode started after grab handle created to ensure the signal InputStarted is sent last.
- // This is used to ensure if selecting text hides the grab handle then this code is run after grab handle is created,
- // otherwise the Grab handle will be shown when selecting.
-
StartEditMode();
}
}
}
}
+ // Edit mode started after grab handle created to ensure the signal InputStarted is sent last.
+ // This is used to ensure if selecting text hides the grab handle then this code is run after grab handle is created,
+ // otherwise the Grab handle will be shown when selecting.
if ( createGrabHandle && IsGrabHandleEnabled() )
{
const Vector3 cursorPosition = GetActualPositionFromCharacterPosition(mCursorPosition);
{
DALI_LOG_INFO( gLogFilter, Debug::General, "OnLongPress\n" );
+ // Ignore longpress if in selection mode already
+ if( mHighlightMeshActor )
+ {
+ return;
+ }
+
if(longPress.state == Dali::Gesture::Started)
{
// Start edit mode on long press
mTextLayoutInfo.mScrollOffset = mDisplayedTextView.GetScrollPosition();
ReturnClosestIndex( longPress.localPoint, mCursorPosition );
+ std::size_t start = 0;
+ std::size_t end = 0;
+ Dali::Toolkit::Internal::TextProcessor::FindNearestWord( mStyledText, mCursorPosition, start, end );
+
+ mCursorPosition = end; // Ensure cursor is positioned at end of selected word
+
ImfManager imfManager = ImfManager::Get();
if ( imfManager )
{
imfManager.SetCursorPosition ( mCursorPosition );
imfManager.NotifyCursorPosition();
}
- std::size_t start = 0;
- std::size_t end = 0;
- Dali::Toolkit::Internal::TextProcessor::FindNearestWord( mStyledText, mCursorPosition, start, end );
SelectText( start, end );
}
{
bool preEditFlagPreviouslySet( mPreEditFlag );
- if (mHighlightMeshActor)
- {
- // replaces highlighted text with new line
- DeleteHighlightedText( false );
- }
+ // replaces highlighted text with new line
+ DeleteHighlightedText( false );
+
mCursorPosition = mCursorPosition + InsertAt( Text( NEWLINE ), mCursorPosition, 0 );
// If we are in pre-edit mode then pressing enter will cause a commit. But the commit string does not include the
// Some text may be selected, hiding keyboard causes an empty keystring to be sent, we don't want to delete highlight in this case
if ( !keyString.empty() )
{
- if ( mHighlightMeshActor )
- {
- // replaces highlighted text with new character
- DeleteHighlightedText( false );
- }
-
+ // replaces highlighted text with new character
+ DeleteHighlightedText( false );
// Received key String
- mCursorPosition = mCursorPosition + InsertAt( Text( keyString ), mCursorPosition, 0 );
+ mCursorPosition += InsertAt( Text( keyString ), mCursorPosition, 0 );
update = true;
EmitTextModified();
}
scrollOffset.x += cursorPosition.x;
}
- if( cursorPosition.y - cursorSize.height < 0.f )
- {
- scrollOffset.y += ( cursorPosition.y - cursorSize.height );
- }
- else if( cursorPosition.y > controlSize.height )
+ if( cursorPosition.y - cursorSize.height < 0.f || cursorPosition.y > controlSize.height )
{
scrollOffset.y += cursorPosition.y;
}
void TextInput::CreateTextViewActor()
{
mDisplayedTextView = Toolkit::TextView::New();
+ mDisplayedTextView.SetName( "DisplayedTextView ");
mDisplayedTextView.SetMarkupProcessingEnabled( mMarkUpEnabled );
mDisplayedTextView.SetParentOrigin(ParentOrigin::TOP_LEFT);
mDisplayedTextView.SetAnchorPoint(AnchorPoint::TOP_LEFT);
}
else
{
- if( std::abs( imfEvent.cursorOffset ) < mCursorPosition )
+ if( static_cast<std::size_t>(std::abs( imfEvent.cursorOffset )) < mCursorPosition )
{
toDelete = mCursorPosition + imfEvent.cursorOffset;
}
{
DALI_LOG_INFO( gLogFilter, Debug::General, "DeleteHighlightedText handlePosOne[%u] handlePosTwo[%u]\n", mSelectionHandleOnePosition, mSelectionHandleTwoPosition);
- if(mHighlightMeshActor)
+ if( mHighlightMeshActor )
{
mCursorPosition = std::min( mSelectionHandleOnePosition, mSelectionHandleTwoPosition );
RemoveHighlight();
+ EmitTextModified();
+
if( inheritStyle )
{
const TextStyle oldInputStyle( mInputStyle );
return insertedStringLength;
}
-ImageActor TextInput::CreateCursor( Image cursorImage, const Vector4& border )
+ImageActor TextInput::CreateCursor( const Vector4& color)
{
ImageActor cursor;
-
- if ( cursorImage )
- {
- cursor = ImageActor::New( cursorImage );
- }
- else
- {
- cursor = ImageActor::New( Image::New( DEFAULT_CURSOR ) );
- }
-
- cursor.SetStyle(ImageActor::STYLE_NINE_PATCH);
- cursor.SetNinePatchBorder( border );
+ cursor = CreateSolidColorActor(color);
+ cursor.SetName( "Cursor" );
cursor.SetParentOrigin(ParentOrigin::TOP_LEFT);
- cursor.SetAnchorPoint(AnchorPoint::BOTTOM_CENTER);
+ cursor.SetAnchorPoint(AnchorPoint::BOTTOM_LEFT);
cursor.SetVisible(false);
return cursor;
{
// Get height of cursor and set its size
Size size( CURSOR_THICKNESS, 0.0f );
- if (!mTextLayoutInfo.mCharacterLayoutInfoTable.empty())
+ if( !mTextLayoutInfo.mCharacterLayoutInfoTable.empty() )
{
size.height = GetRowRectFromCharacterPosition( GetVisualPosition( mCursorPosition ) ).height;
}
void TextInput::CreateGrabArea( Actor& parent )
{
mGrabArea = Actor::New(); // Area that Grab handle responds to, larger than actual handle so easier to move
+ mGrabArea.SetName( "GrabArea" );
mGrabArea.SetPositionInheritanceMode( Dali::USE_PARENT_POSITION );
mGrabArea.ApplyConstraint( Constraint::New<Vector3>( Actor::SIZE, ParentSource( Actor::SIZE ), RelativeToConstraint( DEFAULT_GRAB_HANDLE_RELATIVE_SIZE ) ) ); // grab area to be larger than text actor
mGrabArea.TouchedSignal().Connect(this,&TextInput::OnPressDown);
mTapDetector.Attach( mGrabArea );
mPanGestureDetector.Attach( mGrabArea );
+ mLongPressDetector.Attach( mGrabArea );
parent.Add(mGrabArea);
}
// TODO: TextView should have a table of visual rows, and each character a reference to the row
// that it resides on. That way this enumeration is not necessary.
Vector2 min, max;
- if(lastIt->mIsNewLineChar)
+ if(lastIt->mIsNewParagraphChar)
{
// If the last character is a new line, then to get the row rect, we need to scan from the character before the new line.
lastIt = std::max( mTextLayoutInfo.mCharacterLayoutInfoTable.begin(), lastIt - 1 );
{
// finished selection.
Vector2 min, max;
- if(lastIt->mIsNewLineChar)
+ if(lastIt->mIsNewParagraphChar)
{
lastIt = std::max( mTextLayoutInfo.mCharacterLayoutInfoTable.begin(), lastIt - 1 );
}
mPopupPanel.AddPopupOptions();
}
-void TextInput::SetPopupPosition( const Vector3& position )
+void TextInput::SetPopupPosition( const Vector3& position, const Vector2& alternativePosition )
{
- mPopupPanel.SetTailPosition( position );
- mPopupPanel.GetRootActor().SetPosition( position );
+ const Vector3& visiblePopUpSize = mPopupPanel.GetVisibileSize();
+
+ Vector3 clampedPosition ( position );
+ Vector3 tailOffsetPosition ( position );
+
+ float xOffSet( 0.0f );
+
+ Actor self = Self();
+ const Vector3 textViewTopLeftWorldPosition = self.GetCurrentWorldPosition() - self.GetCurrentSize()*0.5f;
+
+ const float popUpLeft = textViewTopLeftWorldPosition.x + position.x - visiblePopUpSize.width*0.5f;
+ const float popUpTop = textViewTopLeftWorldPosition.y + position.y - visiblePopUpSize.height;
+
+ // Clamp to left or right or of boundary
+ if( popUpLeft < mBoundingRectangleWorldCoordinates.x )
+ {
+ xOffSet = mBoundingRectangleWorldCoordinates.x - popUpLeft ;
+ }
+ else if ( popUpLeft + visiblePopUpSize.width > mBoundingRectangleWorldCoordinates.z )
+ {
+ xOffSet = mBoundingRectangleWorldCoordinates.z - ( popUpLeft + visiblePopUpSize.width );
+ }
+
+ clampedPosition.x = position.x + xOffSet;
+ tailOffsetPosition.x = -xOffSet;
+
+ // Check if top left of PopUp outside of top bounding rectangle, if so then flip to lower position.
+ bool flipTail( false );
+
+ if ( popUpTop < mBoundingRectangleWorldCoordinates.y )
+ {
+ clampedPosition.y = alternativePosition.y + visiblePopUpSize.height;
+ flipTail = true;
+ }
+
+ mPopupPanel.GetRootActor().SetPosition( clampedPosition );
+ mPopupPanel.SetTailPosition( tailOffsetPosition, flipTail );
}
void TextInput::HidePopup(bool animate, bool signalFinished )
}
}
-void TextInput::ShowPopup(bool animate)
+void TextInput::ShowPopup( bool animate )
{
Vector3 position;
+ Vector2 alternativePopupPosition;
if(mHighlightMeshActor && mState == StateEdit)
{
topHandle.y += -mPopupOffsetFromText.y - rowSize.height;
position = Vector3(topHandle.x, topHandle.y, 0.0f);
- bottomHandle.y += GetSelectionHandleSize().y + mPopupOffsetFromText.w;
- mPopupPanel.SetAlternativeOffset(Vector2( mBoundingRectangleWorldCoordinates.x, bottomHandle.y - topHandle.y));
-
- float xPosition = ( fabsf( topHandle.x - bottomHandle.x ) )*0.5f + std::min( topHandle.x , bottomHandle.x );
+ float xPosition = ( fabsf( topHandle.x - bottomHandle.x ) )*0.5f + std::min( mSelectionHandleOneActualPosition.x , mSelectionHandleTwoActualPosition.x );
position.x = xPosition;
+
+ // Alternative position if no upper space
+ bottomHandle.y += GetSelectionHandleSize().y + mPopupOffsetFromText.w;
+ alternativePopupPosition = Vector2 ( position.x, bottomHandle.y );
}
else
{
const Size rowSize = GetRowRectFromCharacterPosition( mCursorPosition );
position.y -= ( mPopupOffsetFromText.y + rowSize.height );
// if can't be positioned above, then position below row.
- Vector2 alternativePopupPosition( mBoundingRectangleWorldCoordinates.x, position.y ); // default if no grab handle
+ alternativePopupPosition = Vector2( position.x, position.y ); // default if no grab handle
if ( mGrabHandle )
{
// If grab handle enabled then position pop-up below the grab handle.
alternativePopupPosition.y = rowSize.height + mGrabHandle.GetCurrentSize().height + mPopupOffsetFromText.w +50.0f;
}
- mPopupPanel.SetAlternativeOffset( alternativePopupPosition );
}
- // reposition popup above the desired cursor posiiton.
- Vector3 textViewSize = mDisplayedTextView.GetCurrentSize();
- textViewSize.z = 0.0f;
- // World position = world position of local position i.e. top-left corner of TextView
- Vector3 worldPosition = mDisplayedTextView.GetCurrentWorldPosition() - ( textViewSize * 0.5f ) + position;
-
- SetPopupPosition( worldPosition );
+ SetPopupPosition( position, alternativePopupPosition );
// Show popup
- mPopupPanel.Show(animate);
+ mPopupPanel.Show( Self(), animate );
StartMonitoringStageForTouch();
mPopupPanel.PressedSignal().Connect( this, &TextInput::OnPopupButtonPressed );
ShowPopup();
}
-void TextInput::SetUpPopupSelection()
+void TextInput::SetUpPopupSelection( bool showCutButton )
{
ClearPopup();
mPopupPanel.CreateOrderedListOfOptions(); // todo Move this so only run when order has changed
{
mPopupPanel.TogglePopupButtonOnOff( TextInputPopup::ButtonsSelectAll, true );
mPopupPanel.TogglePopupButtonOnOff( TextInputPopup::ButtonsSelect, true );
- mPopupPanel.TogglePopupButtonOnOff( TextInputPopup::ButtonsCut, true );
+ mPopupPanel.TogglePopupButtonOnOff( TextInputPopup::ButtonsCut, showCutButton );
}
// if clipboard has valid contents then offer paste option
if( mClipboard && mClipboard.NumberOfItems() )
if( fabsf( closestYdifference - currentYdifference ) < CHARACTER_THRESHOLD )
{
// ignore new line character.
- if( !info.mIsNewLineChar )
+ if( !info.mIsNewParagraphChar )
{
matchedCharacters.push_back( info );
numberOfMatchedCharacters++;
// and check if user is touching below previous line.
const Toolkit::TextView::CharacterLayoutInfo& lastInfo( mTextLayoutInfo.mCharacterLayoutInfoTable[mTextLayoutInfo.mCharacterLayoutInfoTable.size() - 1] );
- if( ( lastInfo.mIsVisible ) && ( lastInfo.mIsNewLineChar ) && ( sourceScrollOffset.y > lastInfo.mPosition.y ) )
+ if( ( lastInfo.mIsVisible ) && ( lastInfo.mIsNewParagraphChar ) && ( sourceScrollOffset.y > lastInfo.mPosition.y ) )
{
closestIndex = mTextLayoutInfo.mCharacterLayoutInfoTable.size();
}
}
Toolkit::TextView::CharacterLayoutInfo info = mTextLayoutInfo.mCharacterLayoutInfoTable[ visualCharacterPosition ];
- if( ( visualCharacterPosition > 0 ) && info.mIsNewLineChar && !IsScrollEnabled() )
+ if( ( visualCharacterPosition > 0 ) && info.mIsNewParagraphChar && !IsScrollEnabled() )
{
// Prevents the cursor to exceed the boundary if the last visible character is a 'new line character' and the scroll is not enabled.
const Vector3& size = GetControlSize();
info = mTextLayoutInfo.mCharacterLayoutInfoTable[ visualCharacterPosition ];
}
- if(!info.mIsNewLineChar)
+ if(!info.mIsNewParagraphChar)
{
cursorPosition = PositionCursorAfterWordWrap( characterPosition ); // Get position of cursor/handles taking in account auto word wrap.
}
// between RTL and LTR text...
if(characterPosition != mTextLayoutInfo.mCharacterLogicalToVisualMap.size())
{
- std::size_t visualCharacterAltPosition = mTextLayoutInfo.mCharacterLogicalToVisualMap[characterPosition] - 1;
+ std::size_t visualCharacterAltPosition = mTextLayoutInfo.mCharacterLogicalToVisualMap[characterPosition]; // VCC TODO: find why in the previous patch it was a -1 here.
DALI_ASSERT_ALWAYS(visualCharacterAltPosition < mTextLayoutInfo.mCharacterLayoutInfoTable.size());
const Toolkit::TextView::CharacterLayoutInfo& infoAlt = mTextLayoutInfo.mCharacterLayoutInfoTable[ visualCharacterAltPosition ];
{
logicalPosition--;
std::size_t visualPosition = GetVisualPosition(logicalPosition);
- if(mTextLayoutInfo.mCharacterLayoutInfoTable[visualPosition].mIsNewLineChar)
+ if(mTextLayoutInfo.mCharacterLayoutInfoTable[visualPosition].mIsNewParagraphChar)
{
logicalPosition++;
break;
--it;
if( (it->mPosition.y < referenceLine) ||
- (it->mIsNewLineChar) ||
+ (it->mIsNewParagraphChar) ||
(!it->mIsVisible) )
{
break;
while(it != end)
{
if( (it->mPosition.y > referenceLine) ||
- (it->mIsNewLineChar) ||
+ (it->mIsNewParagraphChar) ||
(!it->mIsVisible) )
{
break;
// When replacing highlighted text keyboard should ignore current word at cursor hence notify keyboard that the cursor is at the start of the highlight.
mSelectingText = true;
- mCursorPosition = std::min( start, end ); // Set cursor position to start of highlighted text.
-
- ImfManager imfManager = ImfManager::Get();
- if ( imfManager )
- {
- imfManager.SetCursorPosition ( mCursorPosition );
- imfManager.SetSurroundingText( GetText() );
- imfManager.NotifyCursorPosition();
- }
- // As the imfManager has been notified of the new cursor position we do not need to reset the pre-edit as it will be updated instead.
+ std::size_t selectionStartPosition = std::min( start, end );
// Hide grab handle when selecting.
ShowGrabHandleAndSetVisibility( false );
UpdateHighlight();
const TextStyle oldInputStyle( mInputStyle );
- mInputStyle = GetStyleAt( mCursorPosition ); // Inherit style from selected position.
+ mInputStyle = GetStyleAt( selectionStartPosition ); // Inherit style from selected position.
if( oldInputStyle != mInputStyle )
{
}
// Removes highlight and resumes edit mode state
-void TextInput::RemoveHighlight()
+void TextInput::RemoveHighlight( bool hidePopup )
{
DALI_LOG_INFO(gLogFilter, Debug::General, "RemoveHighlight\n");
// NOTE: We cannot dereference mHighlightMesh, due
// to a bug in how the scene-graph MeshRenderer uses the Mesh data incorrectly.
- HidePopup();
+ if ( hidePopup )
+ {
+ HidePopup();
+ }
}
mSelectionHandleOnePosition = 0;
mHighlightMeshActor = MeshActor::New( mHighlightMesh );
mHighlightMeshActor.SetName( "HighlightMeshActor" );
- mHighlightMeshActor.SetInheritShaderEffect( false );
mHighlightMeshActor.SetParentOrigin( ParentOrigin::TOP_LEFT );
mHighlightMeshActor.SetAnchorPoint( AnchorPoint::TOP_LEFT );
mHighlightMeshActor.SetPosition( 0.0f, 0.0f, DISPLAYED_HIGHLIGHT_Z_OFFSET );
if( update )
{
CursorUpdate();
+ EmitTextModified();
}
if( insertedStringLength < text.GetLength() )
textInputImpl.SetOffsetFromText( value.Get< Vector4 >() );
break;
}
+ case Toolkit::TextInput::CURSOR_COLOR_PROPERTY:
+ {
+ textInputImpl.mCursor.SetColor( value.Get< Vector4 >() );
+ }
}
}
}
value = textInputImpl.GetOffsetFromText();
break;
}
+ case Toolkit::TextInput::CURSOR_COLOR_PROPERTY:
+ {
+ value = textInputImpl.mCursor.GetCurrentColor();
+ }
}
}
return value;