X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=blobdiff_plain;f=base%2Fdali-toolkit%2Finternal%2Fcontrols%2Ftext-input%2Ftext-input-impl.cpp;h=7600969536fff9b61d7b7fb02eb8e098be27f86a;hp=24710e72a808227402a731d8dd213bbdbaca3379;hb=714066000e082a6a1e5053d79c2e0c9cb5e163dd;hpb=e04ededcf6627685b262355b66459f0f1d1ac815 diff --git a/base/dali-toolkit/internal/controls/text-input/text-input-impl.cpp b/base/dali-toolkit/internal/controls/text-input/text-input-impl.cpp index 24710e7..7600969 100644 --- a/base/dali-toolkit/internal/controls/text-input/text-input-impl.cpp +++ b/base/dali-toolkit/internal/controls/text-input/text-input-impl.cpp @@ -1,18 +1,19 @@ -// -// Copyright (c) 2014 Samsung Electronics Co., Ltd. -// -// Licensed under the Flora License, Version 1.0 (the License); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://floralicense.org/license/ -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an AS IS BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ #include @@ -20,15 +21,13 @@ #include #include #include +#include #include #include #include #include -#include - -#define GET_LOCALE_TEXT(string) dgettext("sys_string", string) using namespace std; using namespace Dali; @@ -46,44 +45,28 @@ const std::size_t DEFAULT_NUMBER_OF_LINES_LIMIT( std::numeric_limitsInitialize(); - return handle; } TextInput::TextInput() -:Control( true ), +:Control( ControlBehaviour( REQUIRES_TOUCH_EVENTS | REQUIRES_STYLE_CHANGE_SIGNALS ) ), mState( StateEdit ), mStyledText(), mInputStyle(), @@ -295,6 +314,7 @@ TextInput::TextInput() mTouchStartTime( 0 ), mTextLayoutInfo(), mCurrentCopySelecton(), + mPopupPanel(), mScrollTimer(), mScrollDisplacement(), mCurrentHandlePosition(), @@ -304,6 +324,8 @@ TextInput::TextInput() mSelectionHandleFlipMargin( 0.0f, 0.0f, 0.0f, 0.0f ), mBoundingRectangleWorldCoordinates( 0.0f, 0.0f, 0.0f, 0.0f ), mClipboard(), + mMaterialColor( LIGHTBLUE ), + mPopupOffsetFromText ( Vector4( 0.0f, TOP_HANDLE_TOP_OFFSET, 0.0f, BOTTOM_HANDLE_BOTTOM_OFFSET ) ), mOverrideAutomaticAlignment( false ), mCursorRTLEnabled( false ), mClosestCursorPositionEOL ( false ), @@ -519,6 +541,24 @@ std::size_t TextInput::GetNumberOfCharacters() const return mStyledText.size(); } +// Styling +void TextInput::SetMaterialDiffuseColor( const Vector4& color ) +{ + mMaterialColor = color; + if ( mCustomMaterial ) + { + mCustomMaterial.SetDiffuseColor( mMaterialColor ); + mMeshData.SetMaterial( mCustomMaterial ); + } +} + +const Vector4& TextInput::GetMaterialDiffuseColor() const +{ + return mMaterialColor; +} + +// Signals + Toolkit::TextInput::InputSignalV2& TextInput::InputStartedSignal() { return mInputStartedSignalV2; @@ -1112,6 +1152,7 @@ void TextInput::CreateActiveLayer() { Actor self = Self(); mActiveLayer = Layer::New(); + mActiveLayer.SetName ( "ActiveLayerActor" ); mActiveLayer.SetAnchorPoint( AnchorPoint::CENTER); mActiveLayer.SetParentOrigin( ParentOrigin::CENTER); @@ -1129,9 +1170,8 @@ void TextInput::OnInitialize() // 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 ); @@ -1156,6 +1196,8 @@ void TextInput::OnControlSizeSet(const Vector3& targetSize) void TextInput::OnRelaidOut( Vector2 size, ActorSizeContainer& container ) { Relayout( mDisplayedTextView, size, container ); + Relayout( mPopupPanel.GetRootActor(), size, container ); + GetTextLayoutInfo(); DrawCursor(); @@ -1238,7 +1280,7 @@ void TextInput::OnHandlePan(Actor actor, PanGesture gesture) { mActualGrabHandlePosition = MoveGrabHandle( gesture.displacement ); SetCursorVisibility( true ); - SetUpPopUpSelection(); + SetUpPopupSelection(); ShowPopup(); } if (actor == mHandleOneGrabArea) @@ -1360,7 +1402,7 @@ void TextInput::OnDoubleTap(Dali::Actor actor, Dali::TapGesture tap) SelectText( start, end ); } // if no text but clipboard has content then show paste option - if ( mClipboard.NumberOfItems() || !mStyledText.empty() ) + if ( ( mClipboard && mClipboard.NumberOfItems() ) || !mStyledText.empty() ) { ShowPopupCutCopyPaste(); } @@ -1382,9 +1424,9 @@ void TextInput::OnTextTap(Dali::Actor actor, Dali::TapGesture tap) if( mGrabArea == actor ) { - if( mPopUpPanel.GetState() == TextInputPopup::StateHidden || mPopUpPanel.GetState() == TextInputPopup::StateHiding ) + if( mPopupPanel.GetState() == TextInputPopup::StateHidden || mPopupPanel.GetState() == TextInputPopup::StateHiding ) { - SetUpPopUpSelection(); + SetUpPopupSelection(); ShowPopup(); } @@ -1500,6 +1542,12 @@ void TextInput::OnLongPress(Dali::Actor actor, 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 @@ -1550,7 +1598,7 @@ void TextInput::OnLongPress(Dali::Actor actor, Dali::LongPressGesture longPress) } // if no text but clipboard has content then show paste option, if no text and clipboard empty then do nothing - if ( mClipboard.NumberOfItems() || !mStyledText.empty() ) + if ( ( mClipboard && mClipboard.NumberOfItems() ) || !mStyledText.empty() ) { ShowPopupCutCopyPaste(); } @@ -1573,11 +1621,11 @@ void TextInput::OnClipboardTextSelected( ClipboardEventNotifier& notifier ) bool TextInput::OnPopupButtonPressed( Toolkit::Button button ) { - mPopUpPanel.PressedSignal().Disconnect( this, &TextInput::OnPopupButtonPressed ); + mPopupPanel.PressedSignal().Disconnect( this, &TextInput::OnPopupButtonPressed ); const std::string& name = button.GetName(); - if(name == OPTION_SELECT_WORD) + if(name == TextInputPopup::OPTION_SELECT_WORD) { std::size_t start = 0; std::size_t end = 0; @@ -1585,7 +1633,7 @@ bool TextInput::OnPopupButtonPressed( Toolkit::Button button ) SelectText( start, end ); } - else if(name == OPTION_SELECT_ALL) + else if(name == TextInputPopup::OPTION_SELECT_ALL) { SetCursorVisibility(false); StopCursorBlinkTimer(); @@ -1595,7 +1643,7 @@ bool TextInput::OnPopupButtonPressed( Toolkit::Button button ) SelectText( start, end ); } - else if(name == OPTION_CUT) + else if(name == TextInputPopup::OPTION_CUT) { bool ret = CopySelectedTextToClipboard(); @@ -1610,7 +1658,7 @@ bool TextInput::OnPopupButtonPressed( Toolkit::Button button ) HidePopup(); } - else if(name == OPTION_COPY) + else if(name == TextInputPopup::OPTION_COPY) { CopySelectedTextToClipboard(); @@ -1621,7 +1669,7 @@ bool TextInput::OnPopupButtonPressed( Toolkit::Button button ) HidePopup(); } - else if(name == OPTION_PASTE) + else if(name == TextInputPopup::OPTION_PASTE) { const Text retrievedString( mClipboard.GetItem( 0 ) ); // currently can only get first item in clip board, index 0; @@ -1634,7 +1682,7 @@ bool TextInput::OnPopupButtonPressed( Toolkit::Button button ) HidePopup(); } - else if(name == OPTION_CLIPBOARD) + else if(name == TextInputPopup::OPTION_CLIPBOARD) { // In the case of clipboard being shown we do not want to show updated pop-up after hide animation completes // Hence pass the false parameter for signalFinished. @@ -1723,7 +1771,7 @@ bool TextInput::OnKeyDownEvent(const KeyEvent& event) mPreEditFlag = true; mIgnoreCommitFlag = false; } - + EmitTextModified(); update = true; } else @@ -1748,7 +1796,7 @@ bool TextInput::OnKeyDownEvent(const KeyEvent& event) { mCommitByKeyInput = true; } - + EmitTextModified(); update = true; } // space else if (keyName == "BackSpace") @@ -1767,6 +1815,7 @@ bool TextInput::OnKeyDownEvent(const KeyEvent& event) update = true; } } + EmitTextModified(); } // BackSpace else if (keyName == "Right") { @@ -1909,11 +1958,7 @@ void TextInput::ScrollTextViewToMakeCursorVisible( const Vector3& cursorPosition 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; } @@ -2038,6 +2083,7 @@ void TextInput::SetUpTouchEvents() void TextInput::CreateTextViewActor() { mDisplayedTextView = Toolkit::TextView::New(); + mDisplayedTextView.SetName( "TextView "); mDisplayedTextView.SetMarkupProcessingEnabled( mMarkUpEnabled ); mDisplayedTextView.SetParentOrigin(ParentOrigin::TOP_LEFT); mDisplayedTextView.SetAnchorPoint(AnchorPoint::TOP_LEFT); @@ -2109,7 +2155,7 @@ void TextInput::ApplyPreEditStyle( std::size_t preEditStartPosition, std::size_t { if ( mPreEditFlag && ( preEditStringLength > 0 ) ) { - mUnderlinedPriorToPreEdit = mInputStyle.GetUnderline(); + mUnderlinedPriorToPreEdit = mInputStyle.IsUnderlineEnabled(); TextStyle style; style.SetUnderline( true ); ApplyStyleToRange( style, TextStyle::UNDERLINE , preEditStartPosition, preEditStartPosition + preEditStringLength -1 ); @@ -2225,7 +2271,7 @@ ImfManager::ImfCallbackData TextInput::ImfEventReceived( Dali::ImfManager& imfMa } else { - if( std::abs( imfEvent.cursorOffset ) < mCursorPosition ) + if( static_cast(std::abs( imfEvent.cursorOffset )) < mCursorPosition ) { toDelete = mCursorPosition + imfEvent.cursorOffset; } @@ -2597,6 +2643,8 @@ void TextInput::DeleteHighlightedText( bool inheritStyle ) RemoveHighlight(); + EmitTextModified(); + if( inheritStyle ) { const TextStyle oldInputStyle( mInputStyle ); @@ -2782,21 +2830,10 @@ std::size_t TextInput::InsertAt( const Text& newText, const std::size_t insertio 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.SetParentOrigin(ParentOrigin::TOP_LEFT); cursor.SetAnchorPoint(AnchorPoint::BOTTOM_CENTER); @@ -2871,7 +2908,7 @@ void TextInput::DrawCursor(const std::size_t nthChar) mCursor.SetSize(size); // If the character is italic then the cursor also tilts. - mCursor.SetRotation( mInputStyle.GetItalics() ? Degree( mInputStyle.GetItalicsAngle() - CURSOR_ANGLE_OFFSET ) : Degree( 0.f ), Vector3::ZAXIS ); + mCursor.SetRotation( mInputStyle.IsItalicsEnabled() ? Degree( mInputStyle.GetItalicsAngle() - CURSOR_ANGLE_OFFSET ) : Degree( 0.f ), Vector3::ZAXIS ); DALI_ASSERT_DEBUG( mCursorPosition <= mTextLayoutInfo.mCharacterLayoutInfoTable.size() ); @@ -3466,7 +3503,7 @@ TextInput::HighlightInfo TextInput::CalculateHighlightInfo() // 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 ); @@ -3513,7 +3550,7 @@ TextInput::HighlightInfo TextInput::CalculateHighlightInfo() { // finished selection. Vector2 min, max; - if(lastIt->mIsNewLineChar) + if(lastIt->mIsNewParagraphChar) { lastIt = std::max( mTextLayoutInfo.mCharacterLayoutInfoTable.begin(), lastIt - 1 ); } @@ -3662,144 +3699,177 @@ void TextInput::UpdateHighlight() void TextInput::ClearPopup() { - mPopUpPanel.Clear(); + mPopupPanel.Clear(); } -void TextInput::AddPopupOption(const std::string& name, const std::string& caption, const Image icon, bool finalOption) +void TextInput::AddPopupOptions() { - mPopUpPanel.AddOption(name, caption, icon, finalOption); + mPopupPanel.AddPopupOptions(); } -void TextInput::SetPopupPosition(const Vector3& position) +void TextInput::SetPopupPosition( const Vector3& position, const Vector2& alternativePosition ) { - 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) { Vector3 topHandle; + Vector3 bottomHandle; // referring to the bottom most point of the handle or the bottom line of selection. Size rowSize; // When text is selected, show popup above top handle (and text), or below bottom handle. // topHandle: referring to the top most point of the handle or the top line of selection. if ( mSelectionHandleTwoActualPosition.y > mSelectionHandleOneActualPosition.y ) { topHandle = mSelectionHandleOneActualPosition; + bottomHandle = mSelectionHandleTwoActualPosition; rowSize= GetRowRectFromCharacterPosition( mSelectionHandleOnePosition ); } else { topHandle = mSelectionHandleTwoActualPosition; + bottomHandle = mSelectionHandleOneActualPosition; rowSize = GetRowRectFromCharacterPosition( mSelectionHandleTwoPosition ); } - topHandle.y += TOP_HANDLE_TOP_OFFSET - rowSize.height; + topHandle.y += -mPopupOffsetFromText.y - rowSize.height; position = Vector3(topHandle.x, topHandle.y, 0.0f); - // bottomHandle: referring to the bottom most point of the handle or the bottom line of selection. - Vector3 bottomHandle; - bottomHandle.y = std::max ( mSelectionHandleTwoActualPosition.y , mSelectionHandleOneActualPosition.y ); - bottomHandle.y += GetSelectionHandleSize().y + BOTTOM_HANDLE_BOTTOM_OFFSET; - mPopUpPanel.SetAlternativeOffset(Vector2(0.0f, bottomHandle.y - topHandle.y)); + 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 { // When no text is selected, show popup at world position of grab handle or cursor position = GetActualPositionFromCharacterPosition( mCursorPosition ); const Size rowSize = GetRowRectFromCharacterPosition( mCursorPosition ); - position.y -= rowSize.height; + position.y -= ( mPopupOffsetFromText.y + rowSize.height ); // if can't be positioned above, then position below row. - Vector2 alternativePopUpPosition( 0.0f, position.y ); // default if no grab handle + alternativePopupPosition = Vector2( position.x, position.y ); // default if no grab handle if ( mGrabHandle ) { - alternativePopUpPosition.y = rowSize.height + ( mGrabHandle.GetCurrentSize().height * DEFAULT_GRAB_HANDLE_RELATIVE_SIZE.y ) ; // 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 ParentOrigin of cursor (i.e. top-left corner of TextView) + cursor position; - 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 // Check the selected text is whole text or not. if( IsTextSelected() && ( mStyledText.size() != GetSelectedText().size() ) ) { - Image selectAllIcon = Image::New( DEFAULT_ICON_SELECT_ALL ); - AddPopupOption( OPTION_SELECT_ALL, GET_LOCALE_TEXT("IDS_COM_BODY_SELECT_ALL"), selectAllIcon ); + mPopupPanel.TogglePopupButtonOnOff( TextInputPopup::ButtonsSelectAll, true ); } if ( !mStyledText.empty() ) { - Image cutIcon = Image::New( DEFAULT_ICON_CUT ); - Image copyIcon = Image::New( DEFAULT_ICON_COPY ); - AddPopupOption( OPTION_CUT, GET_LOCALE_TEXT("IDS_COM_BODY_CUT"), cutIcon ); - AddPopupOption( OPTION_COPY, GET_LOCALE_TEXT("IDS_COM_BODY_COPY"), copyIcon, true ); + mPopupPanel.TogglePopupButtonOnOff( TextInputPopup::ButtonsCopy, true ); + mPopupPanel.TogglePopupButtonOnOff( TextInputPopup::ButtonsCut, true ); } - if(mClipboard.NumberOfItems()) + if( mClipboard && mClipboard.NumberOfItems() ) { - Image pasteIcon = Image::New( DEFAULT_ICON_PASTE ); - Image clipboardIcon = Image::New( DEFAULT_ICON_CLIPBOARD ); - AddPopupOption( OPTION_PASTE, GET_LOCALE_TEXT("IDS_COM_BODY_PASTE"), pasteIcon ); - AddPopupOption( OPTION_CLIPBOARD, GET_LOCALE_TEXT("IDS_COM_BODY_CLIPBOARD"), clipboardIcon, true ); + mPopupPanel.TogglePopupButtonOnOff( TextInputPopup::ButtonsPaste, true ); + mPopupPanel.TogglePopupButtonOnOff( TextInputPopup::ButtonsClipboard, true ); } - mPopUpPanel.Hide(false); + AddPopupOptions(); + + mPopupPanel.Hide(false); ShowPopup(); } -void TextInput::SetUpPopUpSelection() +void TextInput::SetUpPopupSelection() { ClearPopup(); - + 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() ) { - Image selectIcon = Image::New( DEFAULT_ICON_SELECT ); - Image selectAllIcon = Image::New( DEFAULT_ICON_SELECT_ALL ); - AddPopupOption( OPTION_SELECT_WORD, GET_LOCALE_TEXT("IDS_COM_SK_SELECT"), selectIcon ); - AddPopupOption( OPTION_SELECT_ALL, GET_LOCALE_TEXT("IDS_COM_BODY_SELECT_ALL"), selectAllIcon ); + mPopupPanel.TogglePopupButtonOnOff( TextInputPopup::ButtonsSelectAll, true ); + mPopupPanel.TogglePopupButtonOnOff( TextInputPopup::ButtonsSelect, true ); + mPopupPanel.TogglePopupButtonOnOff( TextInputPopup::ButtonsCut, true ); } // if clipboard has valid contents then offer paste option - if( mClipboard.NumberOfItems() ) + if( mClipboard && mClipboard.NumberOfItems() ) { - Image pasteIcon = Image::New( DEFAULT_ICON_PASTE ); - Image clipboardIcon = Image::New( DEFAULT_ICON_CLIPBOARD ); - AddPopupOption( OPTION_PASTE, GET_LOCALE_TEXT("IDS_COM_BODY_PASTE"), pasteIcon, true ); - AddPopupOption( OPTION_CLIPBOARD, GET_LOCALE_TEXT("IDS_COM_BODY_CLIPBOARD"), clipboardIcon, true ); + mPopupPanel.TogglePopupButtonOnOff( TextInputPopup::ButtonsPaste, true ); + mPopupPanel.TogglePopupButtonOnOff( TextInputPopup::ButtonsClipboard, true ); } - mPopUpPanel.Hide(false); + AddPopupOptions(); + + mPopupPanel.Hide(false); } bool TextInput::ReturnClosestIndex(const Vector2& source, std::size_t& closestIndex ) @@ -3846,7 +3916,7 @@ bool TextInput::ReturnClosestIndex(const Vector2& source, std::size_t& closestIn if( fabsf( closestYdifference - currentYdifference ) < CHARACTER_THRESHOLD ) { // ignore new line character. - if( !info.mIsNewLineChar ) + if( !info.mIsNewParagraphChar ) { matchedCharacters.push_back( info ); numberOfMatchedCharacters++; @@ -3860,7 +3930,7 @@ bool TextInput::ReturnClosestIndex(const Vector2& source, std::size_t& closestIn // 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(); } @@ -4118,7 +4188,7 @@ Vector3 TextInput::GetActualPositionFromCharacterPosition(std::size_t characterP } 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(); @@ -4130,7 +4200,7 @@ Vector3 TextInput::GetActualPositionFromCharacterPosition(std::size_t characterP info = mTextLayoutInfo.mCharacterLayoutInfoTable[ visualCharacterPosition ]; } - if(!info.mIsNewLineChar) + if(!info.mIsNewParagraphChar) { cursorPosition = PositionCursorAfterWordWrap( characterPosition ); // Get position of cursor/handles taking in account auto word wrap. } @@ -4330,7 +4400,7 @@ std::size_t TextInput::GetRowStartFromCharacterPosition(std::size_t logicalPosit { logicalPosition--; std::size_t visualPosition = GetVisualPosition(logicalPosition); - if(mTextLayoutInfo.mCharacterLayoutInfoTable[visualPosition].mIsNewLineChar) + if(mTextLayoutInfo.mCharacterLayoutInfoTable[visualPosition].mIsNewParagraphChar) { logicalPosition++; break; @@ -4400,7 +4470,7 @@ Size TextInput::GetRowRectFromCharacterPosition(std::size_t characterPosition, V --it; if( (it->mPosition.y < referenceLine) || - (it->mIsNewLineChar) || + (it->mIsNewParagraphChar) || (!it->mIsVisible) ) { break; @@ -4417,7 +4487,7 @@ Size TextInput::GetRowRectFromCharacterPosition(std::size_t characterPosition, V while(it != end) { if( (it->mPosition.y > referenceLine) || - (it->mIsNewLineChar) || + (it->mIsNewParagraphChar) || (!it->mIsVisible) ) { break; @@ -4443,7 +4513,7 @@ Size TextInput::GetRowRectFromCharacterPosition(std::size_t characterPosition, V bool TextInput::WasTouchedCheck( const Actor& touchedActor ) const { - Actor popUpPanel = mPopUpPanel.GetRootActor(); + Actor popUpPanel = mPopupPanel.GetRootActor(); if ( ( touchedActor == Self() ) || ( touchedActor == popUpPanel ) ) { @@ -4484,7 +4554,7 @@ void TextInput::OnStageTouched(const TouchEvent& event) bool popUpShown( false ); - if ( ( mPopUpPanel.GetState() == TextInputPopup::StateShowing ) || ( mPopUpPanel.GetState() == TextInputPopup::StateShown ) ) + if ( ( mPopupPanel.GetState() == TextInputPopup::StateShowing ) || ( mPopupPanel.GetState() == TextInputPopup::StateShown ) ) { popUpShown = true; } @@ -4619,7 +4689,7 @@ void TextInput::KeyboardStatusChanged(bool keyboardShown) ShowGrabHandleAndSetVisibility( false ); // If the keyboard is not now being shown, then hide the popup panel - mPopUpPanel.Hide( true ); + mPopupPanel.Hide( true ); } } @@ -4669,7 +4739,7 @@ void TextInput::CreateHighlight() mMeshData.SetHasNormals( true ); mCustomMaterial = Material::New("CustomMaterial"); - mCustomMaterial.SetDiffuseColor( LIGHTBLUE ); + mCustomMaterial.SetDiffuseColor( mMaterialColor ); mMeshData.SetMaterial( mCustomMaterial ); @@ -4677,7 +4747,6 @@ void TextInput::CreateHighlight() 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 ); @@ -4743,6 +4812,7 @@ void TextInput::PasteText( const Text& text ) if( update ) { CursorUpdate(); + EmitTextModified(); } if( insertedStringLength < text.GetLength() ) @@ -5106,6 +5176,205 @@ void TextInput::GetTextLayoutInfo() } } +void TextInput::SetOffsetFromText( const Vector4& offset ) +{ + mPopupOffsetFromText = offset; +} + +const Vector4& TextInput::GetOffsetFromText() const +{ + return mPopupOffsetFromText; +} + +void TextInput::SetProperty( BaseObject* object, Property::Index propertyIndex, const Property::Value& value ) +{ + Toolkit::TextInput textInput = Toolkit::TextInput::DownCast( Dali::BaseHandle( object ) ); + + if ( textInput ) + { + TextInput& textInputImpl( GetImpl( textInput ) ); + + switch ( propertyIndex ) + { + case Toolkit::TextInput::HIGHLIGHT_COLOR_PROPERTY: + { + textInputImpl.SetMaterialDiffuseColor( value.Get< Vector4 >() ); + break; + } + case Toolkit::TextInput::CUT_AND_PASTE_COLOR_PROPERTY: + { + textInputImpl.mPopupPanel.SetCutPastePopupColor( value.Get< Vector4 >() ); + break; + } + case Toolkit::TextInput::CUT_AND_PASTE_PRESSED_COLOR_PROPERTY: + { + textInputImpl.mPopupPanel.SetCutPastePopupPressedColor( value.Get< Vector4 >() ); + break; + } + case Toolkit::TextInput::CUT_AND_PASTE_BORDER_COLOR_PROPERTY: + { + textInputImpl.mPopupPanel.SetCutPastePopupBorderColor( value.Get< Vector4 >() ); + break; + } + case Toolkit::TextInput::CUT_AND_PASTE_ICON_COLOR_PROPERTY: + { + textInputImpl.mPopupPanel.SetCutPastePopupIconColor( value.Get< Vector4 >() ); + break; + } + case Toolkit::TextInput::CUT_AND_PASTE_ICON_PRESSED_COLOR_PROPERTY: + { + textInputImpl.mPopupPanel.SetCutPastePopupIconPressedColor( value.Get< Vector4 >() ); + break; + } + case Toolkit::TextInput::CUT_AND_PASTE_TEXT_COLOR_PROPERTY: + { + textInputImpl.mPopupPanel.SetCutPastePopupTextColor( value.Get< Vector4 >() ); + break; + } + case Toolkit::TextInput::CUT_AND_PASTE_TEXT_PRESSED_COLOR_PROPERTY: + { + textInputImpl.mPopupPanel.SetCutPastePopupTextPressedColor( value.Get< Vector4 >() ); + break; + } + case Toolkit::TextInput::CUT_BUTTON_POSITION_PRIORITY_PROPERTY: + { + textInputImpl.mPopupPanel.SetButtonPriorityPosition( TextInputPopup::ButtonsCut, value.Get() ); + break; + } + case Toolkit::TextInput::COPY_BUTTON_POSITION_PRIORITY_PROPERTY: + { + textInputImpl.mPopupPanel.SetButtonPriorityPosition( TextInputPopup::ButtonsCopy, value.Get() ); + break; + } + case Toolkit::TextInput::PASTE_BUTTON_POSITION_PRIORITY_PROPERTY: + { + textInputImpl.mPopupPanel.SetButtonPriorityPosition( TextInputPopup::ButtonsPaste, value.Get() ); + break; + } + case Toolkit::TextInput::SELECT_BUTTON_POSITION_PRIORITY_PROPERTY: + { + textInputImpl.mPopupPanel.SetButtonPriorityPosition( TextInputPopup::ButtonsSelect, value.Get() ); + break; + } + case Toolkit::TextInput::SELECT_ALL_BUTTON_POSITION_PRIORITY_PROPERTY: + { + textInputImpl.mPopupPanel.SetButtonPriorityPosition( TextInputPopup::ButtonsSelectAll, value.Get() ); + break; + } + case Toolkit::TextInput::CLIPBOARD_BUTTON_POSITION_PRIORITY_PROPERTY: + { + textInputImpl.mPopupPanel.SetButtonPriorityPosition( TextInputPopup::ButtonsClipboard, value.Get() ); + 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 >() ); + } + } + } +} + +Property::Value TextInput::GetProperty( BaseObject* object, Property::Index propertyIndex ) +{ + Property::Value value; + + Toolkit::TextInput textInput = Toolkit::TextInput::DownCast( Dali::BaseHandle( object ) ); + + if ( textInput ) + { + TextInput& textInputImpl( GetImpl( textInput ) ); + + switch ( propertyIndex ) + { + case Toolkit::TextInput::HIGHLIGHT_COLOR_PROPERTY: + { + value = textInputImpl.GetMaterialDiffuseColor(); + break; + } + case Toolkit::TextInput::CUT_AND_PASTE_COLOR_PROPERTY: + { + value = textInputImpl.mPopupPanel.GetCutPastePopupColor(); + break; + } + case Toolkit::TextInput::CUT_AND_PASTE_PRESSED_COLOR_PROPERTY: + { + value = textInputImpl.mPopupPanel.GetCutPastePopupPressedColor(); + break; + } + case Toolkit::TextInput::CUT_AND_PASTE_BORDER_COLOR_PROPERTY : + { + value = textInputImpl.mPopupPanel.GetCutPastePopupBorderColor(); + break; + } + case Toolkit::TextInput::CUT_AND_PASTE_ICON_COLOR_PROPERTY: + { + value = textInputImpl.mPopupPanel.GetCutPastePopupIconColor(); + break; + } + case Toolkit::TextInput::CUT_AND_PASTE_ICON_PRESSED_COLOR_PROPERTY: + { + value = textInputImpl.mPopupPanel.GetCutPastePopupIconPressedColor(); + break; + } + case Toolkit::TextInput::CUT_AND_PASTE_TEXT_COLOR_PROPERTY: + { + value = textInputImpl.mPopupPanel.GetCutPastePopupTextColor(); + break; + } + case Toolkit::TextInput::CUT_AND_PASTE_TEXT_PRESSED_COLOR_PROPERTY: + { + value = textInputImpl.mPopupPanel.GetCutPastePopupTextPressedColor(); + break; + } + case Toolkit::TextInput::CUT_BUTTON_POSITION_PRIORITY_PROPERTY: + { + value = textInputImpl.mPopupPanel.GetButtonPriorityPosition( TextInputPopup::ButtonsCut ); + break; + } + case Toolkit::TextInput::COPY_BUTTON_POSITION_PRIORITY_PROPERTY: + { + value = textInputImpl.mPopupPanel.GetButtonPriorityPosition( TextInputPopup::ButtonsCopy ); + break; + } + case Toolkit::TextInput::PASTE_BUTTON_POSITION_PRIORITY_PROPERTY: + { + value = textInputImpl.mPopupPanel.GetButtonPriorityPosition( TextInputPopup::ButtonsPaste ); + break; + } + case Toolkit::TextInput::SELECT_BUTTON_POSITION_PRIORITY_PROPERTY: + { + value = textInputImpl.mPopupPanel.GetButtonPriorityPosition( TextInputPopup::ButtonsSelect ); + break; + } + case Toolkit::TextInput::SELECT_ALL_BUTTON_POSITION_PRIORITY_PROPERTY: + { + value = textInputImpl.mPopupPanel.GetButtonPriorityPosition( TextInputPopup::ButtonsSelectAll ); + break; + } + case Toolkit::TextInput::CLIPBOARD_BUTTON_POSITION_PRIORITY_PROPERTY: + { + 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; +} + void TextInput::EmitStyleChangedSignal() { // emit signal if input style changes.