*
*/
-#include <dali/dali.h>
-
+// CLASS HEADER
#include <dali-toolkit/internal/controls/text-input/text-input-impl.h>
-#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/integration-api/debug.h>
+// EXTERNAL INCLUDES
#include <math.h>
#include <sstream>
#include <algorithm>
+#include <dali/public-api/adaptor-framework/virtual-keyboard.h>
+#include <dali/public-api/animation/constraints.h>
+#include <dali/public-api/common/stage.h>
+#include <dali/public-api/events/key-event.h>
+#include <dali/public-api/events/touch-event.h>
+#include <dali/public-api/object/type-registry.h>
+#include <dali/public-api/object/property-notification.h>
+#include <dali/integration-api/debug.h>
+
+// INTERNAL INCLUDES
+#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>
-using namespace std;
using namespace Dali;
// Local Data
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();
--cursorPosition;
}
- return 0;
+ return 0u;
}
std::size_t FindVisibleCharacterRight( std::size_t cursorPosition, const Toolkit::TextView::CharacterLayoutInfoContainer& characterLayoutInfoTable )
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;
}
mTouchStartTime( 0 ),
mTextLayoutInfo(),
mCurrentCopySelecton(),
- mPopUpPanel(),
+ mPopupPanel(),
mScrollTimer(),
mScrollDisplacement(),
mCurrentHandlePosition(),
return markupString;
}
+void TextInput::ShowPlaceholderText( const MarkupProcessor::StyledTextArray& stylePlaceHolderText )
+{
+ mDisplayedTextView.SetText( stylePlaceHolderText );
+ mPlaceHolderSet = true;
+ mDisplayedTextView.SetScrollPosition( Vector2( 0.0f,0.0f ) );
+}
+
void TextInput::SetPlaceholderText( const std::string& placeHolderText )
{
// Get the placeholder styled text array from the markup string.
MarkupProcessor::GetStyledTextArray( placeHolderText, mStyledPlaceHolderText, IsMarkupProcessingEnabled() );
-
if( mStyledText.empty() )
{
- // Set the placeholder text only if the styled text is empty.
- mDisplayedTextView.SetText( mStyledPlaceHolderText );
- mPlaceHolderSet = true;
+ ShowPlaceholderText( mStyledPlaceHolderText );
}
}
if( mStyledText.empty() )
{
- // If the initial text is empty, set the placeholder text.
- mDisplayedTextView.SetText( mStyledPlaceHolderText );
- mPlaceHolderSet = true;
+ ShowPlaceholderText( mStyledPlaceHolderText );
}
else
{
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
mClipboard = Clipboard::Get(); // Store handle to clipboard
// Now in edit mode we can accept string to paste from clipboard
- if( Adaptor::IsAvailable() )
+ ClipboardEventNotifier notifier( ClipboardEventNotifier::Get() );
+ if ( notifier )
{
- ClipboardEventNotifier notifier( ClipboardEventNotifier::Get() );
- if ( notifier )
- {
- notifier.ContentSelectedSignal().Connect( this, &TextInput::OnClipboardTextSelected );
- }
+ notifier.ContentSelectedSignal().Connect( this, &TextInput::OnClipboardTextSelected );
}
}
mClipboard.Reset();
// No longer in edit mode so do not want to receive string from clipboard
- if( Adaptor::IsAvailable() )
+ ClipboardEventNotifier notifier( ClipboardEventNotifier::Get() );
+ if ( notifier )
{
- ClipboardEventNotifier notifier( ClipboardEventNotifier::Get() );
- if ( notifier )
- {
- notifier.ContentSelectedSignal().Disconnect( this, &TextInput::OnClipboardTextSelected );
- }
- Clipboard clipboard = Clipboard::Get();
+ notifier.ContentSelectedSignal().Disconnect( this, &TextInput::OnClipboardTextSelected );
+ }
- if ( clipboard )
- {
- clipboard.HideClipboard();
- }
+ Clipboard clipboard = Clipboard::Get();
+ if ( clipboard )
+ {
+ clipboard.HideClipboard();
}
}
{
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();
// Private Internal methods
-void TextInput::OnHandlePan(Actor actor, PanGesture gesture)
+void TextInput::OnHandlePan(Actor actor, const PanGesture& gesture)
{
switch (gesture.state)
{
{
mActualGrabHandlePosition = MoveGrabHandle( gesture.displacement );
SetCursorVisibility( true );
- SetUpPopUpSelection();
+ SetUpPopupSelection();
ShowPopup();
}
if (actor == mHandleOneGrabArea)
return false;
}
-void TextInput::OnDoubleTap(Dali::Actor actor, Dali::TapGesture tap)
+void TextInput::OnDoubleTap(Dali::Actor actor, const Dali::TapGesture& tap)
{
// If text exists then select nearest word.
if ( !mStyledText.empty())
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();
}
}
// TODO: Change the function name to be more general.
-void TextInput::OnTextTap(Dali::Actor actor, Dali::TapGesture tap)
+void TextInput::OnTextTap(Dali::Actor actor, const Dali::TapGesture& tap)
{
DALI_LOG_INFO( gLogFilter, Debug::General, "OnTap mPreEditFlag[%s] mEditOnTouch[%s] mEditModeActive[%s] ", (mPreEditFlag)?"true":"false"
, (mEditOnTouch)?"true":"false"
if( mGrabArea == actor )
{
- if( mPopUpPanel.GetState() == TextInputPopup::StateHidden || mPopUpPanel.GetState() == TextInputPopup::StateHiding )
+ if( mPopupPanel.GetState() == TextInputPopup::StateHidden || mPopupPanel.GetState() == TextInputPopup::StateHiding )
{
- SetUpPopUpSelection();
+ SetUpPopupSelection();
ShowPopup();
}
{
// 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);
+ Vector3 altPosition; // Alternate (i.e. opposite direction) cursor position.
+ bool altPositionValid; // Alternate cursor validity flag.
+ bool directionRTL; // Need to know direction of primary cursor (in case we have 2 cursors and need to show them differently)
+ Vector3 cursorPosition = GetActualPositionFromCharacterPosition( mCursorPosition, directionRTL, altPosition, altPositionValid );
+
+ if( altPositionValid )
+ {
+ // Check which of the positions is the closest.
+ if( fabsf( altPosition.x - tap.localPoint.x ) < fabsf( cursorPosition.x - tap.localPoint.x ) )
+ {
+ cursorPosition = altPosition;
+ }
+ }
CreateGrabHandle();
}
}
-void TextInput::OnLongPress(Dali::Actor actor, Dali::LongPressGesture longPress)
+void TextInput::OnLongPress(Dali::Actor actor, const Dali::LongPressGesture& longPress)
{
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 TextInput::OnPopupButtonPressed( Toolkit::Button button )
{
- mPopUpPanel.PressedSignal().Disconnect( this, &TextInput::OnPopupButtonPressed );
+ mPopupPanel.PressedSignal().Disconnect( this, &TextInput::OnPopupButtonPressed );
const std::string& name = button.GetName();
{
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 is selected so erase it before adding space.
DeleteHighlightedText( true );
- update = true;
}
mCursorPosition = mCursorPosition + InsertAt(Text(keyString), mCursorPosition, 0);
// 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();
}
return false;
}
+void TextInput::ChooseRtlSelectionHandlePosition( const Vector3& cursorPositionOne,
+ const Vector3& cursorPositionTwo,
+ bool altPositionValidOne,
+ bool altPositionValidTwo,
+ const Vector3& altPositionOne,
+ const Vector3& altPositionTwo )
+{
+ // TODO VCC Valid for one line.
+ // Try to place the selection handles. TODO think in something better. Probably need to know the direction of the paragraph.
+ if( cursorPositionOne != cursorPositionTwo )
+ {
+ if( cursorPositionOne.x < cursorPositionTwo.x )
+ {
+ mSelectionHandleOneActualPosition = cursorPositionOne;
+ mSelectionHandleTwoActualPosition = cursorPositionTwo;
+ }
+ else
+ {
+ mSelectionHandleOneActualPosition = cursorPositionTwo;
+ mSelectionHandleTwoActualPosition = cursorPositionOne;
+ }
+ }
+ else
+ {
+ mSelectionHandleOneActualPosition = cursorPositionOne;
+ if( altPositionValidOne )
+ {
+ if( altPositionOne.x < mSelectionHandleOneActualPosition.x )
+ {
+ mSelectionHandleOneActualPosition = altPositionOne;
+ }
+ }
+ if( altPositionValidTwo )
+ {
+ if( altPositionTwo.x < mSelectionHandleOneActualPosition.x )
+ {
+ mSelectionHandleOneActualPosition = altPositionTwo;
+ }
+ }
+
+ mSelectionHandleTwoActualPosition = cursorPositionTwo;
+ if( altPositionValidTwo )
+ {
+ if( altPositionTwo.x > mSelectionHandleTwoActualPosition.x )
+ {
+ mSelectionHandleTwoActualPosition = altPositionTwo;
+ }
+ }
+ if( altPositionValidOne )
+ {
+ if( altPositionOne.x > mSelectionHandleTwoActualPosition.x )
+ {
+ mSelectionHandleTwoActualPosition = altPositionOne;
+ }
+ }
+ }
+}
+
void TextInput::OnTextViewScrolled( Toolkit::TextView textView, Vector2 scrollPosition )
{
// Updates the stored scroll position.
// Updates the cursor and grab handle position and visibility.
if( mGrabHandle || mCursor )
{
- cursorSize.height = GetRowRectFromCharacterPosition( GetVisualPosition( mCursorPosition ) ).height;
- const Vector3 cursorPosition = GetActualPositionFromCharacterPosition(mCursorPosition);
+ cursorSize.height = GetRowRectFromCharacterPosition( mCursorPosition ).height;
+
+ Vector3 altPosition; // Alternate (i.e. opposite direction) cursor position.
+ bool altPositionValid; // Alternate cursor validity flag.
+ bool directionRTL; // Need to know direction of primary cursor (in case we have 2 cursors and need to show them differently)
+ Vector3 cursorPosition = GetActualPositionFromCharacterPosition( mCursorPosition, directionRTL, altPosition, altPositionValid );
+
+ if( altPositionValid )
+ {
+ // Check which of the positions is the closest.
+ if( fabsf( altPosition.x - mActualGrabHandlePosition.x ) < fabsf( cursorPosition.x - mActualGrabHandlePosition.x ) )
+ {
+ cursorPosition = altPosition;
+ }
+ }
mIsCursorInScrollArea = mIsGrabHandleInScrollArea = IsPositionInsideBoundaries( cursorPosition, cursorSize, controlSize );
// Updates the selection handles and highlighted text position and visibility.
if( mSelectionHandleOne && mSelectionHandleTwo )
{
- const Vector3 cursorPositionOne = GetActualPositionFromCharacterPosition(mSelectionHandleOnePosition);
- const Vector3 cursorPositionTwo = GetActualPositionFromCharacterPosition(mSelectionHandleTwoPosition);
+ Vector3 altPositionOne; // Alternate (i.e. opposite direction) cursor position.
+ bool altPositionValidOne; // Alternate cursor validity flag.
+ bool directionRTLOne; // Need to know direction of primary cursor (in case we have 2 cursors and need to show them differently)
+ Vector3 cursorPositionOne = GetActualPositionFromCharacterPosition( mSelectionHandleOnePosition, directionRTLOne, altPositionOne, altPositionValidOne );
+
+ Vector3 altPositionTwo; // Alternate (i.e. opposite direction) cursor position.
+ bool altPositionValidTwo; // Alternate cursor validity flag.
+ bool directionRTLTwo; // Need to know direction of primary cursor (in case we have 2 cursors and need to show them differently)
+ Vector3 cursorPositionTwo = GetActualPositionFromCharacterPosition( mSelectionHandleTwoPosition, directionRTLTwo, altPositionTwo, altPositionValidTwo );
+
+ // VCC TODO: This method is a hack for one line.
+ ChooseRtlSelectionHandlePosition( cursorPositionOne,
+ cursorPositionTwo,
+ altPositionValidOne,
+ altPositionValidTwo,
+ altPositionOne,
+ altPositionTwo );
+
cursorSize.height = ( *( mTextLayoutInfo.mCharacterLayoutInfoTable.begin() + mSelectionHandleOnePosition ) ).mSize.height;
const bool isSelectionHandleOneVisible = IsPositionInsideBoundaries( cursorPositionOne, cursorSize, controlSize );
cursorSize.height = ( *( mTextLayoutInfo.mCharacterLayoutInfoTable.begin() + mSelectionHandleTwoPosition ) ).mSize.height;
const bool isSelectionHandleTwoVisible = IsPositionInsideBoundaries( cursorPositionTwo, cursorSize, controlSize );
- mSelectionHandleOneActualPosition = cursorPositionOne.GetVectorXY();
- mSelectionHandleTwoActualPosition = cursorPositionTwo.GetVectorXY();
-
mSelectionHandleOne.SetVisible( isSelectionHandleOneVisible );
mSelectionHandleTwo.SetVisible( isSelectionHandleTwoVisible );
mSelectionHandleOne.SetPosition( mSelectionHandleOneActualPosition + UI_OFFSET + mSelectionHandleOneOffset );
{
// Scroll the text to make the cursor visible.
const Size cursorSize( CURSOR_THICKNESS,
- GetRowRectFromCharacterPosition( GetVisualPosition( mCursorPosition ) ).height );
+ GetRowRectFromCharacterPosition( mCursorPosition ).height );
// Need to scroll the text to make the cursor visible and to cover the whole text-input area.
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;
}
if( mStyledText.empty() )
{
- // Styled text is empty, so set the placeholder text.
- mDisplayedTextView.SetText( mStyledPlaceHolderText );
- mPlaceHolderSet = true;
+ ShowPlaceholderText( mStyledPlaceHolderText );
}
}
break;
if( mStyledText.empty() )
{
- // Styled text is empty, so set the placeholder text.
- mDisplayedTextView.SetText( mStyledPlaceHolderText );
- mPlaceHolderSet = true;
+ ShowPlaceholderText( mStyledPlaceHolderText );
}
else
{
mDisplayedTextView.RemoveTextFrom( mPreEditStartPosition, numberOfCharactersToReplace );
}
+
GetTextLayoutInfo();
EmitTextModified();
}
{
DALI_LOG_INFO( gLogFilter, Debug::General, "DeleteHighlightedText handlePosOne[%u] handlePosTwo[%u]\n", mSelectionHandleOnePosition, mSelectionHandleTwoPosition);
- if(mHighlightMeshActor)
+ if( mHighlightMeshActor )
{
mCursorPosition = std::min( mSelectionHandleOnePosition, mSelectionHandleTwoPosition );
mStyledText.erase( start, end ); // erase range of characters
- // Remove text from TextView.
+ // Remove text from TextView and update place holder text if required
+ // Set the placeholder text only if the styled text is empty.
if( mStyledText.empty() )
{
- // Styled text is empty, so set the placeholder text.
- mDisplayedTextView.SetText( mStyledPlaceHolderText );
- mPlaceHolderSet = true;
+ ShowPlaceholderText( mStyledPlaceHolderText );
}
else
{
RemoveHighlight();
+ EmitTextModified();
+
if( inheritStyle )
{
const TextStyle oldInputStyle( mInputStyle );
if( mStyledText.empty() )
{
- // Styled text is empty, so set the placeholder text.
- mDisplayedTextView.SetText( mStyledPlaceHolderText );
- mPlaceHolderSet = true;
+ ShowPlaceholderText( mStyledPlaceHolderText );
}
else
{
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;
}
}
-void TextInput::DrawCursor(const std::size_t nthChar)
+void TextInput::DrawCursor()
{
+ const Size rowRect = GetRowRectFromCharacterPosition( mCursorPosition );
+
// 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;
+ size.height = rowRect.height;
}
else
{
DALI_ASSERT_DEBUG( mCursorPosition <= mTextLayoutInfo.mCharacterLayoutInfoTable.size() );
- if ( ( mCursorPosition <= mTextLayoutInfo.mCharacterLayoutInfoTable.size() ) )
+ if( ( mCursorPosition <= mTextLayoutInfo.mCharacterLayoutInfoTable.size() ) )
{
Vector3 altPosition; // Alternate (i.e. opposite direction) cursor position.
bool altPositionValid; // Alternate cursor validity flag.
SetAltCursorEnabled( altPositionValid );
- if(!altPositionValid)
+ if( !altPositionValid )
{
mCursor.SetPosition( position + UI_OFFSET );
}
{
size.height *= 0.5f;
mCursor.SetSize(size);
- mCursor.SetPosition( position + UI_OFFSET - Vector3(0.0f, directionRTL ? 0.0f : size.height, 0.0f) );
+ mCursor.SetPosition( position + UI_OFFSET - Vector3( 0.0f, directionRTL ? 0.0f : size.height, 0.0f ) );
// TODO: change this cursor pos, to be the one where the cursor is sourced from.
- Size rowSize = GetRowRectFromCharacterPosition( GetVisualPosition( mCursorPosition ) );
- size.height = rowSize.height * 0.5f;
+ size.height = rowRect.height * 0.5f;
mCursorRTL.SetSize(size);
- mCursorRTL.SetPosition( altPosition + UI_OFFSET - Vector3(0.0f, directionRTL ? size.height : 0.0f, 0.0f) );
+ mCursorRTL.SetPosition( altPosition + UI_OFFSET - Vector3( 0.0f, directionRTL ? size.height : 0.0f, 0.0f ) );
}
if( IsScrollEnabled() )
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);
}
std::size_t newCursorPosition = 0;
ReturnClosestIndex( mActualGrabHandlePosition.GetVectorXY(), newCursorPosition );
- actualHandlePosition = GetActualPositionFromCharacterPosition( newCursorPosition );
+ Vector3 altPosition; // Alternate (i.e. opposite direction) cursor position.
+ bool altPositionValid; // Alternate cursor validity flag.
+ bool directionRTL; // Need to know direction of primary cursor (in case we have 2 cursors and need to show them differently)
+ actualHandlePosition = GetActualPositionFromCharacterPosition( newCursorPosition, directionRTL, altPosition, altPositionValid );
+
+ if( altPositionValid )
+ {
+ // Check which of the positions is the closest.
+ if( fabsf( altPosition.x - mActualGrabHandlePosition.x ) < fabsf( actualHandlePosition.x - mActualGrabHandlePosition.x ) )
+ {
+ actualHandlePosition = altPosition;
+ }
+ }
bool handleVisible = true;
if( IsScrollEnabled() )
{
const Vector3 controlSize = GetControlSize();
- const Size cursorSize = GetRowRectFromCharacterPosition( GetVisualPosition( newCursorPosition ) );
+ const Size cursorSize = GetRowRectFromCharacterPosition( newCursorPosition );
// Scrolls the text if the handle is not in a visible position
handleVisible = IsPositionInsideBoundaries( actualHandlePosition,
cursorSize,
// update table as text may have changed.
GetTextLayoutInfo();
- mSelectionHandleOneActualPosition = GetActualPositionFromCharacterPosition( mSelectionHandleOnePosition );
- mSelectionHandleTwoActualPosition = GetActualPositionFromCharacterPosition( mSelectionHandleTwoPosition );
+ Vector3 altPositionOne; // Alternate (i.e. opposite direction) cursor position.
+ bool altPositionValidOne; // Alternate cursor validity flag.
+ bool directionRTLOne; // Need to know direction of primary cursor (in case we have 2 cursors and need to show them differently)
+ Vector3 cursorPositionOne = GetActualPositionFromCharacterPosition( mSelectionHandleOnePosition, directionRTLOne, altPositionOne, altPositionValidOne );
+
+ Vector3 altPositionTwo; // Alternate (i.e. opposite direction) cursor position.
+ bool altPositionValidTwo; // Alternate cursor validity flag.
+ bool directionRTLTwo; // Need to know direction of primary cursor (in case we have 2 cursors and need to show them differently)
+ Vector3 cursorPositionTwo = GetActualPositionFromCharacterPosition( mSelectionHandleTwoPosition, directionRTLTwo, altPositionTwo, altPositionValidTwo );
+
+ // VCC TODO: This method is a hack for one line.
+ ChooseRtlSelectionHandlePosition( cursorPositionOne,
+ cursorPositionTwo,
+ altPositionValidOne,
+ altPositionValidTwo,
+ altPositionOne,
+ altPositionTwo );
mSelectionHandleOne.SetPosition( mSelectionHandleOneActualPosition + UI_OFFSET + mSelectionHandleOneOffset );
mSelectionHandleTwo.SetPosition( mSelectionHandleTwoActualPosition + UI_OFFSET + mSelectionHandleTwoOffset );
std::size_t newHandlePosition = 0;
ReturnClosestIndex( actualSelectionHandlePosition.GetVectorXY(), newHandlePosition );
- actualHandlePosition = GetActualPositionFromCharacterPosition( newHandlePosition );
+ Vector3 altPosition; // Alternate (i.e. opposite direction) cursor position.
+ bool altPositionValid; // Alternate cursor validity flag.
+ bool directionRTL; // Need to know direction of primary cursor (in case we have 2 cursors and need to show them differently)
+ actualHandlePosition = GetActualPositionFromCharacterPosition( newHandlePosition, directionRTL, altPosition, altPositionValid );
+ if( altPositionValid )
+ {
+ // Check which of the positions is the closest.
+ if( fabsf( altPosition.x - actualSelectionHandlePosition.x ) < fabsf( actualHandlePosition.x - actualSelectionHandlePosition.x ) )
+ {
+ actualHandlePosition = altPosition;
+ }
+ }
bool handleVisible = true;
{
mCurrentSelectionId = handleId;
- cursorSize.height = GetRowRectFromCharacterPosition( GetVisualPosition( newHandlePosition ) ).height;
+ cursorSize.height = GetRowRectFromCharacterPosition( newHandlePosition ).height;
// Restricts the movement of the grab handle inside the boundaries of the text-input.
handleVisible = IsPositionInsideBoundaries( actualHandlePosition,
cursorSize,
void TextInput::SetSelectionHandlePosition(SelectionHandleId handleId)
{
-
const std::size_t selectionHandlePosition = ( handleId == HandleOne ) ? mSelectionHandleOnePosition : mSelectionHandleTwoPosition;
ImageActor selectionHandleActor = ( handleId == HandleOne ) ? mSelectionHandleOne : mSelectionHandleTwo;
if( IsScrollEnabled() )
{
const Size cursorSize( CURSOR_THICKNESS,
- GetRowRectFromCharacterPosition( GetVisualPosition( selectionHandlePosition ) ).height );
+ GetRowRectFromCharacterPosition( selectionHandlePosition ).height );
selectionHandleActor.SetVisible( IsPositionInsideBoundaries( actualHandlePosition,
cursorSize,
GetControlSize() ) );
}
}
-std::size_t TextInput::GetVisualPosition(std::size_t logicalPosition) const
-{
- // Note: we're allowing caller to request a logical position of size (i.e. end of string)
- // For now the visual position of end of logical string will be end of visual string.
- DALI_ASSERT_DEBUG( logicalPosition <= mTextLayoutInfo.mCharacterLogicalToVisualMap.size() );
-
- return logicalPosition != mTextLayoutInfo.mCharacterLogicalToVisualMap.size() ? mTextLayoutInfo.mCharacterLogicalToVisualMap[logicalPosition] : mTextLayoutInfo.mCharacterLogicalToVisualMap.size();
-}
-
-void TextInput::GetVisualTextSelection(std::vector<bool>& selectedVisualText, std::size_t startSelection, std::size_t endSelection)
+void TextInput::GetVisualTextSelection( std::vector<bool>& selectedVisualText, std::size_t startSelection, std::size_t endSelection )
{
- std::vector<int>::iterator it = mTextLayoutInfo.mCharacterLogicalToVisualMap.begin();
- std::vector<int>::iterator startSelectionIt = mTextLayoutInfo.mCharacterLogicalToVisualMap.begin() + std::min(startSelection, endSelection);
- std::vector<int>::iterator endSelectionIt = mTextLayoutInfo.mCharacterLogicalToVisualMap.begin() + std::max(startSelection, endSelection);
- std::vector<int>::iterator end = mTextLayoutInfo.mCharacterLogicalToVisualMap.end();
-
- selectedVisualText.resize( mTextLayoutInfo.mCharacterLogicalToVisualMap.size() );
+ selectedVisualText.resize( mTextLayoutInfo.mCharacterLogicalToVisualMap.size(), false );
- // Deselect text prior to startSelectionIt
- for(;it!=startSelectionIt;++it)
- {
- selectedVisualText[*it] = false;
- }
+ // VCC Set true/false in logical order. TODO : It needs to be checked.
- // Select text from startSelectionIt -> endSelectionIt
- for(;it!=endSelectionIt;++it)
+ if( startSelection > endSelection )
{
- selectedVisualText[*it] = true;
+ std::swap( startSelection, endSelection );
}
-
- // Deselect text after endSelection
- for(;it!=end;++it)
+ std::size_t index = 0u;
+ for( std::vector<bool>::iterator it = selectedVisualText.begin(), endIt = selectedVisualText.end(); it != endIt; ++it, ++index )
{
- selectedVisualText[*it] = false;
+ if( ( index < startSelection ) || ( endSelection <= index ) )
+ {
+ *it = false;
+ }
+ else
+ {
+ *it = true;
+ }
}
-
- selectedVisualText.resize( mTextLayoutInfo.mCharacterLogicalToVisualMap.size(), false );
}
// Calculate the dimensions of the quads they will make the highlight mesh
TextInput::HighlightInfo TextInput::CalculateHighlightInfo()
{
// At the moment there is no public API to modify the block alignment option.
- const bool blockAlignEnabled = true;
mNewHighlightInfo.mQuadList.clear(); // clear last quad information.
// Get vector of flags representing characters that are selected (true) vs unselected (false).
std::vector<bool> selectedVisualText;
- GetVisualTextSelection(selectedVisualText, mSelectionHandleOnePosition, mSelectionHandleTwoPosition);
- std::vector<bool>::iterator selectedIt(selectedVisualText.begin());
- std::vector<bool>::iterator selectedEndIt(selectedVisualText.end());
+ GetVisualTextSelection( selectedVisualText, mSelectionHandleOnePosition, mSelectionHandleTwoPosition );
+ std::vector<bool>::iterator selectedIt = selectedVisualText.begin();
+ std::vector<bool>::iterator selectedEndIt = selectedVisualText.end();
SelectionState selectionState = SelectionNone; ///< Current selection status of cursor over entire text.
float rowLeft = 0.0f;
// selectionState: None when not in selection, Started when in selection, and Ended when reached end of selection.
Toolkit::TextView::CharacterLayoutInfo& charInfo(*it);
- bool charSelected( false );
+ bool charSelected = false;
if( selectedIt != selectedEndIt )
{
charSelected = *selectedIt++;
}
- if(selectionState == SelectionNone)
+ if( selectionState == SelectionNone )
{
- if(charSelected)
+ if( charSelected )
{
selectionState = SelectionStarted;
rowLeft = charInfo.mPosition.x - mTextLayoutInfo.mScrollOffset.x;
rowRight = rowLeft + charInfo.mSize.width;
}
}
- else if(selectionState == SelectionStarted)
+ else if( selectionState == SelectionStarted )
{
// break selection on:
// 1. new line causing selection break. (\n or wordwrap)
// 2. character not selected.
- if(charInfo.mPosition.y - lastIt->mPosition.y > CHARACTER_THRESHOLD ||
- !charSelected)
+ if( !charSelected ||
+ ( charInfo.mPosition.y - lastIt->mPosition.y > CHARACTER_THRESHOLD ) )
{
// finished selection.
// 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 );
float rowTop = rowBottom - rowSize.height;
// Still selected, and block-align mode then set rowRight to max, so it can be clamped afterwards
- if(charSelected && blockAlignEnabled)
+ if(charSelected)
{
rowRight = std::numeric_limits<float>::max();
}
if( charSelected )
{
// if block-align mode then set rowLeft to min, so it can be clamped afterwards
- rowLeft = blockAlignEnabled ? 0.0f : charInfo.mPosition.x - mTextLayoutInfo.mScrollOffset.x;
+ rowLeft = 0.0f;
rowRight = ( charInfo.mPosition.x - mTextLayoutInfo.mScrollOffset.x ) + charInfo.mSize.width;
selectionState = SelectionStarted;
}
{
// finished selection.
Vector2 min, max;
- if(lastIt->mIsNewLineChar)
+ if(lastIt->mIsNewParagraphChar)
{
lastIt = std::max( mTextLayoutInfo.mCharacterLayoutInfoTable.begin(), lastIt - 1 );
}
mNewHighlightInfo.Clamp2D( topLeft, bottomRight );
// For block-align align Further Clamp quads to max left and right extents
- if(blockAlignEnabled)
- {
// BlockAlign: Will adjust highlight to block:
// i.e.
// H[ello] (top row right = max of all rows right)
// [is some]
// [text]
// (common in regular text editors/web browser selection)
-
mNewHighlightInfo.Clamp2D( Vector2(maxRowLeft, topLeft.y), Vector2(maxRowRight, bottomRight.y ) );
+
+ // Finally clamp quads again so they don't exceed the boundry of the control.
+ const Vector3& controlSize = GetControlSize();
+ mNewHighlightInfo.Clamp2D( Vector2::ZERO, Vector2(controlSize.x, controlSize.y) );
+ } // end if
+
+ return mNewHighlightInfo;
+}
+
+// VCC TODO: two methods are not needed. this one is a quick hack to fix PLMs. Should implement one which support both directions.
+// This method creates one quad per character so different selection boxes for a mix of LTR and RTL languages are created.
+TextInput::HighlightInfo TextInput::CalculateHighlightInfoRtl()
+{
+ // At the moment there is no public API to modify the block alignment option.
+
+ mNewHighlightInfo.mQuadList.clear(); // clear last quad information.
+
+ if ( !mTextLayoutInfo.mCharacterLayoutInfoTable.empty() && !mTextLayoutInfo.mCharacterLogicalToVisualMap.empty() )
+ {
+ Toolkit::TextView::CharacterLayoutInfoContainer::iterator it = mTextLayoutInfo.mCharacterLayoutInfoTable.begin();
+ Toolkit::TextView::CharacterLayoutInfoContainer::iterator end = mTextLayoutInfo.mCharacterLayoutInfoTable.end();
+
+ // Get vector of flags representing characters that are selected (true) vs unselected (false).
+ std::vector<bool> selectedVisualText;
+ GetVisualTextSelection( selectedVisualText, mSelectionHandleOnePosition, mSelectionHandleTwoPosition );
+ std::vector<bool>::iterator selectedIt = selectedVisualText.begin();
+ std::vector<bool>::iterator selectedEndIt = selectedVisualText.end();
+
+ // SelectionState selectionState = SelectionNone; ///< Current selection status of cursor over entire text.
+ float rowLeft = 0.0f;
+ float rowRight = 0.0f;
+
+ // VCC TODO this is valid for one line.
+ Vector2 min, max;
+ const Size rowSize = GetRowRectFromCharacterPosition( 0, min, max );
+
+ // Scan through entire text.
+ while(it != end)
+ {
+ // selectionState: None when not in selection, Started when in selection, and Ended when reached end of selection.
+
+ Toolkit::TextView::CharacterLayoutInfo& charInfo(*it);
+ bool charSelected = false;
+ if( selectedIt != selectedEndIt )
+ {
+ charSelected = *selectedIt++;
+ }
+
+ if( charSelected )
+ {
+ rowLeft = charInfo.mPosition.x - mTextLayoutInfo.mScrollOffset.x;
+ rowRight = rowLeft + charInfo.mSize.width;
+
+ float rowBottom = charInfo.mPosition.y - mTextLayoutInfo.mScrollOffset.y;
+ float rowTop = rowBottom - rowSize.height;
+ mNewHighlightInfo.AddQuad( rowLeft, rowTop, rowRight, rowBottom );
+ }
+
+ ++it;
}
// Finally clamp quads again so they don't exceed the boundry of the control.
if ( mHighlightMeshActor )
{
// vertex and triangle buffers should always be present if MeshActor is alive.
- HighlightInfo newHighlightInfo = CalculateHighlightInfo();
+ HighlightInfo newHighlightInfo = CalculateHighlightInfoRtl();
MeshData::VertexContainer vertices;
Dali::MeshData::FaceIndices faceIndices;
void TextInput::ClearPopup()
{
- mPopUpPanel.Clear();
+ mPopupPanel.Clear();
}
void TextInput::AddPopupOptions()
{
- mPopUpPanel.AddPopupOptions();
+ mPopupPanel.AddPopupOptions();
}
-void TextInput::SetPopupPosition( const Vector3& position )
+void TextInput::SetPopupPosition( const Vector3& position, const Vector2& alternativePosition )
{
- mPopUpPanel.SetTailPosition( position );
- mPopUpPanel.Self().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 )
{
- if ( ( mPopUpPanel.GetState() == TextInputPopup::StateShowing ) || ( mPopUpPanel.GetState() == TextInputPopup::StateShown ) )
+ if ( ( mPopupPanel.GetState() == TextInputPopup::StateShowing ) || ( mPopupPanel.GetState() == TextInputPopup::StateShown ) )
{
- mPopUpPanel.Hide( animate );
+ mPopupPanel.Hide( animate );
if( animate && signalFinished )
{
- mPopUpPanel.HideFinishedSignal().Connect( this, &TextInput::OnPopupHideFinished );
+ mPopupPanel.HideFinishedSignal().Connect( this, &TextInput::OnPopupHideFinished );
}
}
}
-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;
+ 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 );
+ mPopupPanel.PressedSignal().Connect( this, &TextInput::OnPopupButtonPressed );
}
void TextInput::ShowPopupCutCopyPaste()
{
ClearPopup();
- mPopUpPanel.CreateOrderedListOfOptions(); // todo Move this so only run when order has changed
+ mPopupPanel.CreateOrderedListOfOptions(); // todo Move this so only run when order has changed
// Check the selected text is whole text or not.
if( IsTextSelected() && ( mStyledText.size() != GetSelectedText().size() ) )
{
- mPopUpPanel.TogglePopUpButtonOnOff( TextInputPopup::ButtonsSelectAll, true );
+ mPopupPanel.TogglePopupButtonOnOff( TextInputPopup::ButtonsSelectAll, true );
}
- if ( !mStyledText.empty() )
+ if ( !mStyledText.empty() && IsTextSelected() )
{
-
- mPopUpPanel.TogglePopUpButtonOnOff( TextInputPopup::ButtonsCopy, true );
- mPopUpPanel.TogglePopUpButtonOnOff( TextInputPopup::ButtonsCut, true );
+ mPopupPanel.TogglePopupButtonOnOff( TextInputPopup::ButtonsCopy, true );
+ mPopupPanel.TogglePopupButtonOnOff( TextInputPopup::ButtonsCut, true );
}
if( mClipboard && mClipboard.NumberOfItems() )
{
- mPopUpPanel.TogglePopUpButtonOnOff( TextInputPopup::ButtonsPaste, true );
- mPopUpPanel.TogglePopUpButtonOnOff( TextInputPopup::ButtonsClipboard, true );
+ mPopupPanel.TogglePopupButtonOnOff( TextInputPopup::ButtonsPaste, true );
+ mPopupPanel.TogglePopupButtonOnOff( TextInputPopup::ButtonsClipboard, true );
}
AddPopupOptions();
- mPopUpPanel.Hide(false);
+ mPopupPanel.Hide(false);
ShowPopup();
}
-void TextInput::SetUpPopUpSelection()
+void TextInput::SetUpPopupSelection( bool showCutButton )
{
ClearPopup();
- mPopUpPanel.CreateOrderedListOfOptions(); // todo Move this so only run when order has changed
+ mPopupPanel.CreateOrderedListOfOptions(); // todo Move this so only run when order has changed
// If no text exists then don't offer to select
if ( !mStyledText.empty() )
{
- mPopUpPanel.TogglePopUpButtonOnOff( TextInputPopup::ButtonsSelectAll, true );
- mPopUpPanel.TogglePopUpButtonOnOff( TextInputPopup::ButtonsSelect, true );
- mPopUpPanel.TogglePopUpButtonOnOff( TextInputPopup::ButtonsCut, true );
+ mPopupPanel.TogglePopupButtonOnOff( TextInputPopup::ButtonsSelectAll, true );
+ mPopupPanel.TogglePopupButtonOnOff( TextInputPopup::ButtonsSelect, true );
+ mPopupPanel.TogglePopupButtonOnOff( TextInputPopup::ButtonsCut, ( showCutButton && IsTextSelected() ) );
}
// if clipboard has valid contents then offer paste option
if( mClipboard && mClipboard.NumberOfItems() )
{
- mPopUpPanel.TogglePopUpButtonOnOff( TextInputPopup::ButtonsPaste, true );
- mPopUpPanel.TogglePopUpButtonOnOff( TextInputPopup::ButtonsClipboard, true );
+ mPopupPanel.TogglePopupButtonOnOff( TextInputPopup::ButtonsPaste, true );
+ mPopupPanel.TogglePopupButtonOnOff( TextInputPopup::ButtonsClipboard, true );
}
AddPopupOptions();
- mPopUpPanel.Hide(false);
+ mPopupPanel.Hide(false);
}
bool TextInput::ReturnClosestIndex(const Vector2& source, std::size_t& closestIndex )
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();
}
else
{
- std::vector<Toolkit::TextView::CharacterLayoutInfo>::const_iterator it = matchedCharacters.begin();
- std::vector<Toolkit::TextView::CharacterLayoutInfo>::const_iterator endIt = matchedCharacters.end();
+ // 2 Iterate through matching list of y positions and find closest matching X position.
bool matched( false );
- // 2 Iterate through matching list of y positions and find closest matching X position.
- for( ; it != endIt; ++it )
+ // Traverse the characters in the visual order. VCC TODO: check for more than one line.
+ std::size_t visualIndex = 0u;
+ const std::size_t matchedCharactersSize = matchedCharacters.size();
+ for( ; visualIndex < matchedCharactersSize; ++visualIndex )
{
- const Toolkit::TextView::CharacterLayoutInfo& info( *it );
+ const Toolkit::TextView::CharacterLayoutInfo& info( *( matchedCharacters.begin() + mTextLayoutInfo.mCharacterVisualToLogicalMap[visualIndex] ) );
if( info.mIsVisible )
{
}
}
- if( it == endIt )
+ if( visualIndex == matchedCharactersSize )
{
rightToLeftChar = lastRightToLeftChar;
}
- std::size_t matchCharacterIndex = it - matchedCharacters.begin();
- closestIndex = lineOffset + matchCharacterIndex;
+ closestIndex = lineOffset + visualIndex;
mClosestCursorPositionEOL = false; // reset
- if ( it == endIt && !matched )
+ if( ( visualIndex == matchedCharactersSize ) && !matched )
{
mClosestCursorPositionEOL = true; // Reached end of matched characters in closest line but no match so cursor should be after last character.
}
++closestIndex;
}
}
- else if( closestIndex == numeric_limits<std::size_t>::max() ) // -1 RTL (after last arabic character on line)
+ else if( closestIndex == std::numeric_limits<std::size_t>::max() ) // -1 RTL (after last arabic character on line)
{
closestIndex = mTextLayoutInfo.mCharacterVisualToLogicalMap.size();
}
/* Word wrap occurs automatically in TextView when the exceed policy moves a word to the next line when not enough space on current.
A newline character is not inserted in this case */
- DALI_ASSERT_DEBUG( !(characterPosition <= 0 ));
-
Vector3 cursorPosition;
- Toolkit::TextView::CharacterLayoutInfo currentCharInfo;
-
- if ( characterPosition == mTextLayoutInfo.mCharacterLayoutInfoTable.size() )
- {
- // end character so use
- currentCharInfo = mTextLayoutInfo.mCharacterLayoutInfoTable[ characterPosition - 1 ];
- cursorPosition = Vector3(currentCharInfo.mPosition.x + currentCharInfo.mSize.width, currentCharInfo.mPosition.y, currentCharInfo.mPosition.z) ;
- }
- else
- {
- currentCharInfo = mTextLayoutInfo.mCharacterLayoutInfoTable[ characterPosition ];
- }
+ Toolkit::TextView::CharacterLayoutInfo currentCharInfo = mTextLayoutInfo.mCharacterLayoutInfoTable[ characterPosition ];
- Toolkit::TextView::CharacterLayoutInfo previousCharInfo = mTextLayoutInfo.mCharacterLayoutInfoTable[ characterPosition - 1];
+ bool noWrap = true;
- // If previous character on a different line then use current characters position
- if ( fabsf( (currentCharInfo.mPosition.y - currentCharInfo.mDescender ) - ( previousCharInfo.mPosition.y - previousCharInfo.mDescender) ) > Math::MACHINE_EPSILON_1000 )
+ if( characterPosition > 0u )
{
- if ( mClosestCursorPositionEOL )
- {
- cursorPosition = Vector3(previousCharInfo.mPosition.x + previousCharInfo.mSize.width, previousCharInfo.mPosition.y, previousCharInfo.mPosition.z) ;
- }
- else
+ Toolkit::TextView::CharacterLayoutInfo previousCharInfo = mTextLayoutInfo.mCharacterLayoutInfoTable[ characterPosition - 1u ];
+
+ // If previous character on a different line then use current characters position
+ if( fabsf( (currentCharInfo.mPosition.y - currentCharInfo.mDescender ) - ( previousCharInfo.mPosition.y - previousCharInfo.mDescender) ) > Math::MACHINE_EPSILON_1000 )
{
- cursorPosition = Vector3(currentCharInfo.mPosition);
+ // VCC TODO: PositionCursorAfterWordWrap currently doesn't work for multiline. Need to check this branch.
+ if ( mClosestCursorPositionEOL )
+ {
+ cursorPosition = Vector3( previousCharInfo.mPosition.x + previousCharInfo.mSize.width, previousCharInfo.mPosition.y, previousCharInfo.mPosition.z ) ;
+ }
+ else
+ {
+ cursorPosition = Vector3( currentCharInfo.mPosition );
+ }
+
+ noWrap = false;
}
}
- else
+
+ if( noWrap )
{
- // Previous character is on same line so use position of previous character plus it's width.
- cursorPosition = Vector3(previousCharInfo.mPosition.x + previousCharInfo.mSize.width, previousCharInfo.mPosition.y, previousCharInfo.mPosition.z) ;
+ // If the character is left to right, the position is the character's position plus its width.
+ const float ltrOffset = !currentCharInfo.mIsRightToLeftCharacter ? currentCharInfo.mSize.width : 0.f;
+
+ cursorPosition.x = currentCharInfo.mPosition.x + ltrOffset;
+ cursorPosition.y = currentCharInfo.mPosition.y;
}
return cursorPosition;
}
-Vector3 TextInput::GetActualPositionFromCharacterPosition(std::size_t characterPosition) const
+Vector3 TextInput::GetActualPositionFromCharacterPosition( std::size_t characterPosition ) const
{
- bool direction(false);
+ bool direction = false;
Vector3 alternatePosition;
- bool alternatePositionValid(false);
+ bool alternatePositionValid = false;
return GetActualPositionFromCharacterPosition( characterPosition, direction, alternatePosition, alternatePositionValid );
}
-Vector3 TextInput::GetActualPositionFromCharacterPosition(std::size_t characterPosition, bool& directionRTL, Vector3& alternatePosition, bool& alternatePositionValid ) const
+Vector3 TextInput::GetActualPositionFromCharacterPosition( std::size_t characterPosition, bool& directionRTL, Vector3& alternatePosition, bool& alternatePositionValid ) const
{
+ DALI_ASSERT_DEBUG( ( mTextLayoutInfo.mCharacterLayoutInfoTable.size() == mTextLayoutInfo.mCharacterLogicalToVisualMap.size() ) &&
+ ( mTextLayoutInfo.mCharacterLayoutInfoTable.size() == mTextLayoutInfo.mCharacterVisualToLogicalMap.size() ) &&
+ "TextInput::GetActualPositionFromCharacterPosition. All layout tables must have the same size." );
+
Vector3 cursorPosition( 0.f, 0.f, 0.f );
alternatePositionValid = false;
directionRTL = false;
- if( !mTextLayoutInfo.mCharacterLayoutInfoTable.empty() && !mTextLayoutInfo.mCharacterLogicalToVisualMap.empty() )
+ if( !mTextLayoutInfo.mCharacterLayoutInfoTable.empty() )
{
- std::size_t visualCharacterPosition;
+ if( characterPosition == 0u )
+ {
+ // When the cursor position is at the beginning, it should be at the start of the current character.
+ // If the current character is LTR, then the start is on the right side of the glyph.
+ // If the current character is RTL, then the start is on the left side of the glyph.
+
+ if( !( *( mTextLayoutInfo.mCharacterLayoutInfoTable.begin() ) ).mIsVisible )
+ {
+ characterPosition = FindVisibleCharacter( Right, 0u );
+ }
- // When cursor is not at beginning, consider possibility of
- // showing 2 cursors. (whereas at beginning we only ever show one cursor)
- if(characterPosition > 0)
+ const Toolkit::TextView::CharacterLayoutInfo& info = mTextLayoutInfo.mCharacterLayoutInfoTable[ characterPosition ];
+ const float rtlOffset = info.mIsRightToLeftCharacter ? info.mSize.width : 0.0f;
+
+ cursorPosition.x = info.mPosition.x + rtlOffset;
+ cursorPosition.y = info.mPosition.y;
+ directionRTL = info.mIsRightToLeftCharacter;
+ }
+ else if( characterPosition > 0u )
{
+ // Get the direction of the paragraph.
+ const std::size_t startCharacterPosition = GetRowStartFromCharacterPosition( characterPosition );
+ const bool isParagraphRightToLeft = ( *( mTextLayoutInfo.mCharacterLayoutInfoTable.begin() + startCharacterPosition ) ).mIsRightToLeftCharacter;
+
+ // When cursor is not at beginning, consider possibility of
+ // showing 2 cursors. (whereas at beginning we only ever show one cursor)
+
// Cursor position should be the end of the last character.
// If the last character is LTR, then the end is on the right side of the glyph.
// If the last character is RTL, then the end is on the left side of the glyph.
- visualCharacterPosition = mTextLayoutInfo.mCharacterLogicalToVisualMap[ characterPosition - 1 ];
- if( !( *( mTextLayoutInfo.mCharacterLayoutInfoTable.begin() + visualCharacterPosition ) ).mIsVisible )
+ --characterPosition;
+
+ if( !( *( mTextLayoutInfo.mCharacterLayoutInfoTable.begin() + characterPosition ) ).mIsVisible )
{
- visualCharacterPosition = FindVisibleCharacter( Left, visualCharacterPosition );
+ characterPosition = FindVisibleCharacter( Left, characterPosition );
}
- Toolkit::TextView::CharacterLayoutInfo info = mTextLayoutInfo.mCharacterLayoutInfoTable[ visualCharacterPosition ];
- if( ( visualCharacterPosition > 0 ) && info.mIsNewLineChar && !IsScrollEnabled() )
+ Toolkit::TextView::CharacterLayoutInfo info = mTextLayoutInfo.mCharacterLayoutInfoTable[ characterPosition ];
+ if( ( characterPosition > 0u ) && info.mIsNewParagraphChar && !IsScrollEnabled() )
{
+ // VCC TODO : check for a new paragraph character.
+
// 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();
if( info.mPosition.y + info.mSize.height - mDisplayedTextView.GetLineHeightOffset() > size.height )
{
- --visualCharacterPosition;
+ --characterPosition;
}
- info = mTextLayoutInfo.mCharacterLayoutInfoTable[ visualCharacterPosition ];
+ info = mTextLayoutInfo.mCharacterLayoutInfoTable[ characterPosition ];
}
- if(!info.mIsNewLineChar)
+ if( !info.mIsNewParagraphChar )
{
cursorPosition = PositionCursorAfterWordWrap( characterPosition ); // Get position of cursor/handles taking in account auto word wrap.
}
else
{
+ // VCC TODO : check for a new paragraph character.
+
// When cursor points to first character on new line, position cursor at the start of this glyph.
- if(characterPosition < mTextLayoutInfo.mCharacterLogicalToVisualMap.size())
+ if( characterPosition < mTextLayoutInfo.mCharacterLayoutInfoTable.size() )
{
- std::size_t visualCharacterNextPosition = mTextLayoutInfo.mCharacterLogicalToVisualMap[ characterPosition ];
- const Toolkit::TextView::CharacterLayoutInfo& infoNext = mTextLayoutInfo.mCharacterLayoutInfoTable[ visualCharacterNextPosition ];
+ const Toolkit::TextView::CharacterLayoutInfo& infoNext = mTextLayoutInfo.mCharacterLayoutInfoTable[ characterPosition ];
const float start( infoNext.mIsRightToLeftCharacter ? infoNext.mSize.width : 0.0f );
cursorPosition.x = infoNext.mPosition.x + start;
// cursor where the new line starts based on the line-justification position.
cursorPosition.x = GetLineJustificationPosition();
- if(characterPosition == mTextLayoutInfo.mCharacterLogicalToVisualMap.size())
+ if( characterPosition == mTextLayoutInfo.mCharacterLogicalToVisualMap.size() )
{
// If this is after the last character, then we can assume that the new cursor
// should be exactly one row below the current row.
- const Size rowRect(GetRowRectFromCharacterPosition(characterPosition - 1));
+ const Size rowRect = GetRowRectFromCharacterPosition( characterPosition - 1u );
cursorPosition.y = info.mPosition.y + rowRect.height;
}
else
// If this is not after last character, then we can use this row's height.
// should be exactly one row below the current row.
- const Size rowRect(GetRowRectFromCharacterPosition(characterPosition));
+ const Size rowRect = GetRowRectFromCharacterPosition( characterPosition );
cursorPosition.y = info.mPosition.y + rowRect.height;
}
}
directionRTL = info.mIsRightToLeftCharacter;
- // 1. When the cursor is neither at the beginning or the end,
- // we can show multiple cursors under situations when the cursor is
- // between RTL and LTR text...
- if(characterPosition != mTextLayoutInfo.mCharacterLogicalToVisualMap.size())
+ if( 1u < mTextLayoutInfo.mCharacterLayoutInfoTable.size() )
{
- std::size_t visualCharacterAltPosition = mTextLayoutInfo.mCharacterLogicalToVisualMap[characterPosition] - 1;
+ // 1. When the cursor is neither at the beginning or the end,
+ // we can show multiple cursors under situations when the cursor is
+ // between RTL and LTR text...
+ if( characterPosition + 1u < mTextLayoutInfo.mCharacterLayoutInfoTable.size() )
+ {
+ std::size_t characterAltPosition = characterPosition + 1u;
- DALI_ASSERT_ALWAYS(visualCharacterAltPosition < mTextLayoutInfo.mCharacterLayoutInfoTable.size());
- const Toolkit::TextView::CharacterLayoutInfo& infoAlt = mTextLayoutInfo.mCharacterLayoutInfoTable[ visualCharacterAltPosition ];
+ const Toolkit::TextView::CharacterLayoutInfo& infoAlt = mTextLayoutInfo.mCharacterLayoutInfoTable[ characterAltPosition ];
- if(!info.mIsRightToLeftCharacter && infoAlt.mIsRightToLeftCharacter)
- {
- // Stuation occurs when cursor is at the end of English text (LTR) and beginning of Arabic (RTL)
- // Text: [...LTR...]|[...RTL...]
- // Cursor pos: ^
- // Alternate cursor pos: ^
- // In which case we need to display an alternate cursor for the RTL text.
-
- alternatePosition.x = infoAlt.mPosition.x + infoAlt.mSize.width;
- alternatePosition.y = infoAlt.mPosition.y;
- alternatePositionValid = true;
+ if(!info.mIsRightToLeftCharacter && infoAlt.mIsRightToLeftCharacter)
+ {
+ // Stuation occurs when cursor is at the end of English text (LTR) and beginning of Arabic (RTL)
+ // Text: [...LTR...]|[...RTL...]
+ // Cursor pos: ^
+ // Alternate cursor pos: ^
+ // In which case we need to display an alternate cursor for the RTL text.
+
+ alternatePosition.x = infoAlt.mPosition.x + infoAlt.mSize.width;
+ alternatePosition.y = infoAlt.mPosition.y;
+ alternatePositionValid = true;
+ }
+ else if(info.mIsRightToLeftCharacter && !infoAlt.mIsRightToLeftCharacter)
+ {
+ // Situation occurs when cursor is at end of the Arabic text (LTR) and beginning of English (RTL)
+ // Text: |[...RTL...] [...LTR....]
+ // Cursor pos: ^
+ // Alternate cursor pos: ^
+ // In which case we need to display an alternate cursor for the RTL text.
+
+ alternatePosition.x = infoAlt.mPosition.x;
+ alternatePosition.y = infoAlt.mPosition.y;
+ alternatePositionValid = true;
+ }
}
- else if(info.mIsRightToLeftCharacter && !infoAlt.mIsRightToLeftCharacter)
+ else
{
- // Situation occurs when cursor is at end of the Arabic text (LTR) and beginning of English (RTL)
- // Text: |[...RTL...] [...LTR....]
- // Cursor pos: ^
- // Alternate cursor pos: ^
- // In which case we need to display an alternate cursor for the RTL text.
-
- alternatePosition.x = infoAlt.mPosition.x;
- alternatePosition.y = infoAlt.mPosition.y;
- alternatePositionValid = true;
- }
- }
- else
- {
- // 2. When the cursor is at the end of the text,
- // and we have multi-directional text,
- // we can also consider showing mulitple cursors.
- // The rule here is:
- // If first and last characters on row are different
- // Directions, then two cursors need to be displayed.
-
- // Get first logical glyph on row
- std::size_t startCharacterPosition = GetRowStartFromCharacterPosition( characterPosition - 1 );
+ // 2. When the cursor is at the end of the text,
+ // and we have multi-directional text,
+ // we can also consider showing mulitple cursors.
+ // The rule here is:
+ // If first and last characters on row are different
+ // Directions, then two cursors need to be displayed.
+
+ if( info.mIsRightToLeftCharacter != isParagraphRightToLeft )
+ {
+ // The last character's direction is differernt than the first one of current paragraph.
- std::size_t visualCharacterStartPosition = mTextLayoutInfo.mCharacterLogicalToVisualMap[ startCharacterPosition ];
- const Toolkit::TextView::CharacterLayoutInfo& infoStart= mTextLayoutInfo.mCharacterLayoutInfoTable[ visualCharacterStartPosition ];
+ // Get first
+ const Toolkit::TextView::CharacterLayoutInfo& infoStart= mTextLayoutInfo.mCharacterLayoutInfoTable[ GetFirstCharacterWithSameDirection( characterPosition ) ];
- if(info.mIsRightToLeftCharacter && !infoStart.mIsRightToLeftCharacter)
- {
- // For text Starting as LTR and ending as RTL. End cursor position is as follows:
- // Text: [...LTR...]|[...RTL...]
- // Cursor pos: ^
- // Alternate cursor pos: ^
- // In which case we need to display an alternate cursor for the RTL text, this cursor
- // should be at the end of the given line.
-
- const Toolkit::TextView::CharacterLayoutInfo& infoAlt = mTextLayoutInfo.mCharacterLayoutInfoTable[ mTextLayoutInfo.mCharacterLayoutInfoTable.size() - 1 ];
- alternatePosition.x = infoAlt.mPosition.x + infoAlt.mSize.width;
- alternatePosition.y = infoAlt.mPosition.y;
- alternatePositionValid = true;
- }
- else if(!info.mIsRightToLeftCharacter && infoStart.mIsRightToLeftCharacter) // starting RTL
- {
- // For text Starting as RTL and ending as LTR. End cursor position is as follows:
- // Text: |[...RTL...] [...LTR....]
- // Cursor pos: ^
- // Alternate cursor pos: ^
- // In which case we need to display an alternate cursor for the RTL text.
-
- const Toolkit::TextView::CharacterLayoutInfo& infoAlt = mTextLayoutInfo.mCharacterLayoutInfoTable[ startCharacterPosition ];
- alternatePosition.x = infoAlt.mPosition.x;
- alternatePosition.y = infoAlt.mPosition.y;
- alternatePositionValid = true;
+ if(info.mIsRightToLeftCharacter)
+ {
+ // For text Starting as LTR and ending as RTL. End cursor position is as follows:
+ // Text: [...LTR...]|[...RTL...]
+ // Cursor pos: ^
+ // Alternate cursor pos: ^
+ // In which case we need to display an alternate cursor for the RTL text, this cursor
+ // should be at the end of the given line.
+
+ alternatePosition.x = infoStart.mPosition.x + infoStart.mSize.width;
+ alternatePosition.y = infoStart.mPosition.y;
+ alternatePositionValid = true;
+ }
+ else if(!info.mIsRightToLeftCharacter) // starting RTL
+ {
+ // For text Starting as RTL and ending as LTR. End cursor position is as follows:
+ // Text: |[...RTL...] [...LTR....]
+ // Cursor pos: ^
+ // Alternate cursor pos: ^
+ // In which case we need to display an alternate cursor for the RTL text.
+
+ alternatePosition.x = infoStart.mPosition.x;
+ alternatePosition.y = infoStart.mPosition.y;
+ alternatePositionValid = true;
+ }
+ }
}
}
} // characterPosition > 0
- else if(characterPosition == 0)
- {
- // When the cursor position is at the beginning, it should be at the start of the current character.
- // If the current character is LTR, then the start is on the right side of the glyph.
- // If the current character is RTL, then the start is on the left side of the glyph.
- visualCharacterPosition = mTextLayoutInfo.mCharacterLogicalToVisualMap[ characterPosition ];
-
- if( !( *( mTextLayoutInfo.mCharacterLayoutInfoTable.begin() + visualCharacterPosition ) ).mIsVisible )
- {
- visualCharacterPosition = FindVisibleCharacter( Right, visualCharacterPosition );
- }
-
- const Toolkit::TextView::CharacterLayoutInfo& info = mTextLayoutInfo.mCharacterLayoutInfoTable[ visualCharacterPosition ];
- const float start(info.mIsRightToLeftCharacter ? info.mSize.width : 0.0f);
-
- cursorPosition.x = info.mPosition.x + start;
- cursorPosition.y = info.mPosition.y;
- directionRTL = info.mIsRightToLeftCharacter;
- }
}
else
{
cursorPosition.x -= mTextLayoutInfo.mScrollOffset.x;
cursorPosition.y -= mTextLayoutInfo.mScrollOffset.y;
+
if( alternatePositionValid )
{
alternatePosition.x -= mTextLayoutInfo.mScrollOffset.x;
return cursorPosition;
}
-std::size_t TextInput::GetRowStartFromCharacterPosition(std::size_t logicalPosition) const
+std::size_t TextInput::GetRowStartFromCharacterPosition( std::size_t logicalPosition ) const
{
// scan string from current position to beginning of current line to note direction of line
- while(logicalPosition)
+ while( logicalPosition )
{
logicalPosition--;
- std::size_t visualPosition = GetVisualPosition(logicalPosition);
- if(mTextLayoutInfo.mCharacterLayoutInfoTable[visualPosition].mIsNewLineChar)
+ if( mTextLayoutInfo.mCharacterLayoutInfoTable[logicalPosition].mIsNewParagraphChar )
+ {
+ logicalPosition++;
+ break;
+ }
+ }
+
+ return logicalPosition;
+}
+
+std::size_t TextInput::GetFirstCharacterWithSameDirection( std::size_t logicalPosition ) const
+{
+ const bool isRightToLeft = mTextLayoutInfo.mCharacterLayoutInfoTable[logicalPosition].mIsRightToLeftCharacter;
+
+ while( logicalPosition )
+ {
+ logicalPosition--;
+ if( isRightToLeft != mTextLayoutInfo.mCharacterLayoutInfoTable[logicalPosition].mIsRightToLeftCharacter )
{
logicalPosition++;
break;
return GetRowRectFromCharacterPosition( characterPosition, min, max );
}
-Size TextInput::GetRowRectFromCharacterPosition(std::size_t characterPosition, Vector2& min, Vector2& max) const
+Size TextInput::GetRowRectFromCharacterPosition( std::size_t characterPosition, Vector2& min, Vector2& max ) const
{
// if we have no text content, then return position 0,0 with width 0, and height the same as cursor height.
if( mTextLayoutInfo.mCharacterLayoutInfoTable.empty() )
return max;
}
- // TODO: This info should be readily available from text-view, we should not have to search hard for it.
- Toolkit::TextView::CharacterLayoutInfoContainer::const_iterator begin = mTextLayoutInfo.mCharacterLayoutInfoTable.begin();
- Toolkit::TextView::CharacterLayoutInfoContainer::const_iterator end = mTextLayoutInfo.mCharacterLayoutInfoTable.end();
-
- // If cursor is pointing to end of line, then start from last character.
- characterPosition = std::min( characterPosition, static_cast<std::size_t>(mTextLayoutInfo.mCharacterLayoutInfoTable.size() - 1) );
+ DALI_ASSERT_DEBUG( characterPosition <= mTextLayoutInfo.mCharacterLayoutInfoTable.size() );
- Toolkit::TextView::CharacterLayoutInfoContainer::const_iterator it = mTextLayoutInfo.mCharacterLayoutInfoTable.begin() + characterPosition;
+ // Initializes the min and max position.
+ const std::size_t initialPosition = ( characterPosition == mTextLayoutInfo.mCharacterLayoutInfoTable.size() ) ? characterPosition - 1u : characterPosition;
+ min = ( *( mTextLayoutInfo.mCharacterLayoutInfoTable.begin() + initialPosition ) ).mPosition.GetVectorXY();
+ max = min;
- // 0. Find first a visible character. Draw a cursor beyound text-input bounds is not wanted.
- if( !it->mIsVisible )
+ bool found = false;
+ // 1) Find the line where the character is laid-out.
+ for( Toolkit::TextView::LineLayoutInfoContainer::const_iterator lineIt = mTextLayoutInfo.mLines.begin(), lineEndIt = mTextLayoutInfo.mLines.end();
+ !found && ( lineIt != mTextLayoutInfo.mLines.end() );
+ ++lineIt )
{
- characterPosition = FindVisibleCharacter( Left, characterPosition );
- it = mTextLayoutInfo.mCharacterLayoutInfoTable.begin() + characterPosition;
- }
-
- // Scan characters left and right of cursor, stopping when end of line/string reached or
- // y position greater than threshold of reference line.
+ const Toolkit::TextView::LineLayoutInfo& lineInfo( *lineIt );
- // 1. scan left until we reach the beginning or a different line.
- Toolkit::TextView::CharacterLayoutInfoContainer::const_iterator validCharIt = it;
- float referenceLine = it->mPosition.y - CHARACTER_THRESHOLD;
- // min-x position is the left-most char's left (x)
- // max-x position is the right-most char's right (x)
- // min-y position is the minimum of all character's top (y)
- // max-y position is the maximum of all character's bottom (y+height)
- min.y = validCharIt->mPosition.y;
- max.y = validCharIt->mPosition.y + validCharIt->mSize.y;
+ // Index within the whole text to the last character of the current line.
+ std::size_t lastCharacterOfLine = 0u;
- while(true)
- {
- validCharIt = it;
- min.y = std::min(min.y, validCharIt->mPosition.y);
- max.y = std::max(max.y, validCharIt->mPosition.y + validCharIt->mSize.y);
-
- if(it == begin)
+ Toolkit::TextView::LineLayoutInfoContainer::const_iterator lineNextIt = lineIt + 1u;
+ if( lineNextIt != lineEndIt )
{
- break;
+ lastCharacterOfLine = (*lineNextIt).mCharacterGlobalIndex - 1u;
}
-
- --it;
-
- if( (it->mPosition.y < referenceLine) ||
- (it->mIsNewLineChar) ||
- (!it->mIsVisible) )
+ else
{
- break;
+ lastCharacterOfLine = mTextLayoutInfo.mCharacterLayoutInfoTable.size() - 1u;
}
- }
-
- // info refers to the first character on this line.
- min.x = validCharIt->mPosition.x;
- // 2. scan right until we reach end or a different line
- it = mTextLayoutInfo.mCharacterLayoutInfoTable.begin() + characterPosition;
- referenceLine = it->mPosition.y + CHARACTER_THRESHOLD;
-
- while(it != end)
- {
- if( (it->mPosition.y > referenceLine) ||
- (it->mIsNewLineChar) ||
- (!it->mIsVisible) )
+ // Check if the given chracter position is within the line.
+ if( ( lineInfo.mCharacterGlobalIndex <= initialPosition ) && ( initialPosition <= lastCharacterOfLine ) )
{
- break;
- }
-
- validCharIt = it;
- min.y = std::min(min.y, validCharIt->mPosition.y);
- max.y = std::max(max.y, validCharIt->mPosition.y + validCharIt->mSize.y);
+ // 2) Get the row rect of all laid-out characters on the line.
- ++it;
- }
+ // Need to scan all characters of the line because they are in the logical position.
+ for( Toolkit::TextView::CharacterLayoutInfoContainer::const_iterator it = mTextLayoutInfo.mCharacterLayoutInfoTable.begin() + lineInfo.mCharacterGlobalIndex,
+ endIt = mTextLayoutInfo.mCharacterLayoutInfoTable.begin() + lastCharacterOfLine + 1u;
+ it != endIt;
+ ++it )
+ {
+ const Toolkit::TextView::CharacterLayoutInfo& characterInfo( *it );
- DALI_ASSERT_DEBUG ( validCharIt != end && "validCharIt invalid")
+ min.x = std::min( min.x, characterInfo.mPosition.x );
+ min.y = std::min( min.y, characterInfo.mPosition.y );
+ max.x = std::max( max.x, characterInfo.mPosition.x + characterInfo.mSize.width );
+ max.y = std::max( max.y, characterInfo.mPosition.y + characterInfo.mSize.height );
+ }
- if ( validCharIt != end )
- {
- // info refers to the last character on this line.
- max.x = validCharIt->mPosition.x + validCharIt->mSize.x;
+ found = true;
+ }
}
return Size( max.x - min.x, max.y - min.y );
bool TextInput::WasTouchedCheck( const Actor& touchedActor ) const
{
- Actor popUpPanel = mPopUpPanel.GetRootActor();
+ Actor popUpPanel = mPopupPanel.GetRootActor();
if ( ( touchedActor == Self() ) || ( touchedActor == popUpPanel ) )
{
bool popUpShown( false );
- if ( ( mPopUpPanel.GetState() == TextInputPopup::StateShowing ) || ( mPopUpPanel.GetState() == TextInputPopup::StateShown ) )
+ if ( ( mPopupPanel.GetState() == TextInputPopup::StateShowing ) || ( mPopupPanel.GetState() == TextInputPopup::StateShown ) )
{
popUpShown = true;
}
// 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 )
{
ShowGrabHandleAndSetVisibility( false );
// If the keyboard is not now being shown, then hide the popup panel
- mPopUpPanel.Hide( true );
+ mPopupPanel.Hide( true );
}
}
// 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 );
*/
MarkupProcessor::StyledTextArray selectedText(mCurrentCopySelecton.begin(),mCurrentCopySelecton.end());
MarkupProcessor::GetPlainString( selectedText, stringToStore );
+
bool success = mClipboard.SetItem( stringToStore );
return success;
}
if( update )
{
CursorUpdate();
+ EmitTextModified();
}
if( insertedStringLength < text.GetLength() )
}
}
-std::size_t TextInput::FindVisibleCharacter( const FindVisibleCharacterDirection direction , const std::size_t cursorPosition ) const
+std::size_t TextInput::FindVisibleCharacter( FindVisibleCharacterDirection direction , std::size_t cursorPosition ) const
{
- std::size_t position = 0;
+ // VCC check if we need do this in the visual order ...
+ std::size_t position = 0u;
const std::size_t tableSize = mTextLayoutInfo.mCharacterLayoutInfoTable.size();
{
position = FindVisibleCharacterLeft( cursorPosition, mTextLayoutInfo.mCharacterLayoutInfoTable );
- if( !( *( mTextLayoutInfo.mCharacterLayoutInfoTable.begin() + ( tableSize == position ? position - 1 : position ) ) ).mIsVisible )
+ if( !( *( mTextLayoutInfo.mCharacterLayoutInfoTable.begin() + ( tableSize == position ? position - 1u : position ) ) ).mIsVisible )
{
position = FindVisibleCharacterRight( cursorPosition, mTextLayoutInfo.mCharacterLayoutInfoTable );
}
case Right:
{
position = FindVisibleCharacterRight( cursorPosition, mTextLayoutInfo.mCharacterLayoutInfoTable );
- if( !( *( mTextLayoutInfo.mCharacterLayoutInfoTable.begin() + ( tableSize == position ? position - 1 : position ) ) ).mIsVisible )
+ if( !( *( mTextLayoutInfo.mCharacterLayoutInfoTable.begin() + ( tableSize == position ? position - 1u : position ) ) ).mIsVisible )
{
position = FindVisibleCharacterLeft( cursorPosition, mTextLayoutInfo.mCharacterLayoutInfoTable );
}
}
case ByEnd:
{
- position = FindVisibleCharacterLeft( 0, mTextLayoutInfo.mCharacterLayoutInfoTable );
+ position = FindVisibleCharacterLeft( 0u, mTextLayoutInfo.mCharacterLayoutInfoTable );
break;
}
default:
if( textToInsert.empty() && emptyTextView )
{
// No character has been added and the text-view was empty.
- // Set the placeholder text.
- mDisplayedTextView.SetText( mStyledPlaceHolderText );
- mPlaceHolderSet = true;
+ // Show the placeholder text.
+ ShowPlaceholderText( mStyledPlaceHolderText );
}
else
{
}
case Toolkit::TextInput::CUT_AND_PASTE_COLOR_PROPERTY:
{
- textInputImpl.mPopUpPanel.SetCutPastePopUpColor( value.Get< Vector4 >() );
+ textInputImpl.mPopupPanel.SetCutPastePopupColor( value.Get< Vector4 >() );
break;
}
case Toolkit::TextInput::CUT_AND_PASTE_PRESSED_COLOR_PROPERTY:
{
- textInputImpl.mPopUpPanel.SetCutPastePopUpPressedColor( value.Get< Vector4 >() );
+ textInputImpl.mPopupPanel.SetCutPastePopupPressedColor( value.Get< Vector4 >() );
break;
}
case Toolkit::TextInput::CUT_AND_PASTE_BORDER_COLOR_PROPERTY:
{
- textInputImpl.mPopUpPanel.SetCutPastePopUpBorderColor( value.Get< Vector4 >() );
+ textInputImpl.mPopupPanel.SetCutPastePopupBorderColor( value.Get< Vector4 >() );
break;
}
case Toolkit::TextInput::CUT_AND_PASTE_ICON_COLOR_PROPERTY:
{
- textInputImpl.mPopUpPanel.SetCutPastePopUpIconColor( value.Get< Vector4 >() );
+ textInputImpl.mPopupPanel.SetCutPastePopupIconColor( value.Get< Vector4 >() );
break;
}
case Toolkit::TextInput::CUT_AND_PASTE_ICON_PRESSED_COLOR_PROPERTY:
{
- textInputImpl.mPopUpPanel.SetCutPastePopUpIconPressedColor( value.Get< Vector4 >() );
+ textInputImpl.mPopupPanel.SetCutPastePopupIconPressedColor( value.Get< Vector4 >() );
break;
}
case Toolkit::TextInput::CUT_AND_PASTE_TEXT_COLOR_PROPERTY:
{
- textInputImpl.mPopUpPanel.SetCutPastePopUpTextColor( value.Get< Vector4 >() );
+ textInputImpl.mPopupPanel.SetCutPastePopupTextColor( value.Get< Vector4 >() );
break;
}
case Toolkit::TextInput::CUT_AND_PASTE_TEXT_PRESSED_COLOR_PROPERTY:
{
- textInputImpl.mPopUpPanel.SetCutPastePopUpTextPressedColor( value.Get< Vector4 >() );
+ textInputImpl.mPopupPanel.SetCutPastePopupTextPressedColor( value.Get< Vector4 >() );
break;
}
case Toolkit::TextInput::CUT_BUTTON_POSITION_PRIORITY_PROPERTY:
{
- textInputImpl.mPopUpPanel.SetButtonPriorityPosition( TextInputPopup::ButtonsCut, value.Get<unsigned int>() );
+ textInputImpl.mPopupPanel.SetButtonPriorityPosition( TextInputPopup::ButtonsCut, value.Get<unsigned int>() );
break;
}
case Toolkit::TextInput::COPY_BUTTON_POSITION_PRIORITY_PROPERTY:
{
- textInputImpl.mPopUpPanel.SetButtonPriorityPosition( TextInputPopup::ButtonsCopy, value.Get<unsigned int>() );
+ textInputImpl.mPopupPanel.SetButtonPriorityPosition( TextInputPopup::ButtonsCopy, value.Get<unsigned int>() );
break;
}
case Toolkit::TextInput::PASTE_BUTTON_POSITION_PRIORITY_PROPERTY:
{
- textInputImpl.mPopUpPanel.SetButtonPriorityPosition( TextInputPopup::ButtonsPaste, value.Get<unsigned int>() );
+ textInputImpl.mPopupPanel.SetButtonPriorityPosition( TextInputPopup::ButtonsPaste, value.Get<unsigned int>() );
break;
}
case Toolkit::TextInput::SELECT_BUTTON_POSITION_PRIORITY_PROPERTY:
{
- textInputImpl.mPopUpPanel.SetButtonPriorityPosition( TextInputPopup::ButtonsSelect, value.Get<unsigned int>() );
+ textInputImpl.mPopupPanel.SetButtonPriorityPosition( TextInputPopup::ButtonsSelect, value.Get<unsigned int>() );
break;
}
case Toolkit::TextInput::SELECT_ALL_BUTTON_POSITION_PRIORITY_PROPERTY:
{
- textInputImpl.mPopUpPanel.SetButtonPriorityPosition( TextInputPopup::ButtonsSelectAll, value.Get<unsigned int>() );
+ textInputImpl.mPopupPanel.SetButtonPriorityPosition( TextInputPopup::ButtonsSelectAll, value.Get<unsigned int>() );
break;
}
case Toolkit::TextInput::CLIPBOARD_BUTTON_POSITION_PRIORITY_PROPERTY:
{
- textInputImpl.mPopUpPanel.SetButtonPriorityPosition( TextInputPopup::ButtonsClipboard, value.Get<unsigned int>() );
+ textInputImpl.mPopupPanel.SetButtonPriorityPosition( TextInputPopup::ButtonsClipboard, value.Get<unsigned int>() );
break;
}
case Toolkit::TextInput::POP_UP_OFFSET_FROM_TEXT_PROPERTY:
textInputImpl.SetOffsetFromText( value.Get< Vector4 >() );
break;
}
+ case Toolkit::TextInput::CURSOR_COLOR_PROPERTY:
+ {
+ textInputImpl.mCursor.SetColor( value.Get< Vector4 >() );
+ }
}
}
}
}
case Toolkit::TextInput::CUT_AND_PASTE_COLOR_PROPERTY:
{
- value = textInputImpl.mPopUpPanel.GetCutPastePopUpColor();
+ value = textInputImpl.mPopupPanel.GetCutPastePopupColor();
break;
}
case Toolkit::TextInput::CUT_AND_PASTE_PRESSED_COLOR_PROPERTY:
{
- value = textInputImpl.mPopUpPanel.GetCutPastePopUpPressedColor();
+ value = textInputImpl.mPopupPanel.GetCutPastePopupPressedColor();
break;
}
case Toolkit::TextInput::CUT_AND_PASTE_BORDER_COLOR_PROPERTY :
{
- value = textInputImpl.mPopUpPanel.GetCutPastePopUpBorderColor();
+ value = textInputImpl.mPopupPanel.GetCutPastePopupBorderColor();
break;
}
case Toolkit::TextInput::CUT_AND_PASTE_ICON_COLOR_PROPERTY:
{
- value = textInputImpl.mPopUpPanel.GetCutPastePopUpIconColor();
+ value = textInputImpl.mPopupPanel.GetCutPastePopupIconColor();
break;
}
case Toolkit::TextInput::CUT_AND_PASTE_ICON_PRESSED_COLOR_PROPERTY:
{
- value = textInputImpl.mPopUpPanel.GetCutPastePopUpIconPressedColor();
+ value = textInputImpl.mPopupPanel.GetCutPastePopupIconPressedColor();
break;
}
case Toolkit::TextInput::CUT_AND_PASTE_TEXT_COLOR_PROPERTY:
{
- value = textInputImpl.mPopUpPanel.GetCutPastePopUpTextColor();
+ value = textInputImpl.mPopupPanel.GetCutPastePopupTextColor();
break;
}
case Toolkit::TextInput::CUT_AND_PASTE_TEXT_PRESSED_COLOR_PROPERTY:
{
- value = textInputImpl.mPopUpPanel.GetCutPastePopUpTextPressedColor();
+ value = textInputImpl.mPopupPanel.GetCutPastePopupTextPressedColor();
break;
}
case Toolkit::TextInput::CUT_BUTTON_POSITION_PRIORITY_PROPERTY:
{
- value = textInputImpl.mPopUpPanel.GetButtonPriorityPosition( TextInputPopup::ButtonsCut );
+ value = textInputImpl.mPopupPanel.GetButtonPriorityPosition( TextInputPopup::ButtonsCut );
break;
}
case Toolkit::TextInput::COPY_BUTTON_POSITION_PRIORITY_PROPERTY:
{
- value = textInputImpl.mPopUpPanel.GetButtonPriorityPosition( TextInputPopup::ButtonsCopy );
+ value = textInputImpl.mPopupPanel.GetButtonPriorityPosition( TextInputPopup::ButtonsCopy );
break;
}
case Toolkit::TextInput::PASTE_BUTTON_POSITION_PRIORITY_PROPERTY:
{
- value = textInputImpl.mPopUpPanel.GetButtonPriorityPosition( TextInputPopup::ButtonsPaste );
+ value = textInputImpl.mPopupPanel.GetButtonPriorityPosition( TextInputPopup::ButtonsPaste );
break;
}
case Toolkit::TextInput::SELECT_BUTTON_POSITION_PRIORITY_PROPERTY:
{
- value = textInputImpl.mPopUpPanel.GetButtonPriorityPosition( TextInputPopup::ButtonsSelect );
+ value = textInputImpl.mPopupPanel.GetButtonPriorityPosition( TextInputPopup::ButtonsSelect );
break;
}
case Toolkit::TextInput::SELECT_ALL_BUTTON_POSITION_PRIORITY_PROPERTY:
{
- value = textInputImpl.mPopUpPanel.GetButtonPriorityPosition( TextInputPopup::ButtonsSelectAll );
+ value = textInputImpl.mPopupPanel.GetButtonPriorityPosition( TextInputPopup::ButtonsSelectAll );
break;
}
case Toolkit::TextInput::CLIPBOARD_BUTTON_POSITION_PRIORITY_PROPERTY:
{
- value = textInputImpl.mPopUpPanel.GetButtonPriorityPosition( TextInputPopup::ButtonsClipboard );
+ value = textInputImpl.mPopupPanel.GetButtonPriorityPosition( TextInputPopup::ButtonsClipboard );
break;
}
case Toolkit::TextInput::POP_UP_OFFSET_FROM_TEXT_PROPERTY:
value = textInputImpl.GetOffsetFromText();
break;
}
+ case Toolkit::TextInput::CURSOR_COLOR_PROPERTY:
+ {
+ value = textInputImpl.mCursor.GetCurrentColor();
+ }
}
}
return value;