From: Agnelo Vaz Date: Mon, 16 Jun 2014 16:02:11 +0000 (+0100) Subject: TextInput Popup has a tail which points to the TextInput X-Git-Tag: dali_1.0.0~43 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=commitdiff_plain;h=05c97b7ff1d90ab7f90cb9d6ec5f060c61b46aab TextInput Popup has a tail which points to the TextInput [problem] User may not know the cut and paste popup applies to the current TextInput [solution] Display a tail which points to the TextInput. Change-Id: I712eb34ce00fbf3a02e7fe4bd975fc556b5c97e6 Signed-off-by: Adeel Kazmi --- diff --git a/base/dali-toolkit/images/copypanelLine.png b/base/dali-toolkit/images/copypanelLine.png deleted file mode 100755 index 4a9a101..0000000 Binary files a/base/dali-toolkit/images/copypanelLine.png and /dev/null differ diff --git a/base/dali-toolkit/images/cutCopyPastePopup_bg.png b/base/dali-toolkit/images/cutCopyPastePopup_bg.png deleted file mode 100644 index b9c6365..0000000 Binary files a/base/dali-toolkit/images/cutCopyPastePopup_bg.png and /dev/null differ diff --git a/base/dali-toolkit/images/popup_bubble_tail_bottom.png b/base/dali-toolkit/images/popup_bubble_tail_bottom.png new file mode 100755 index 0000000..2ca1593 Binary files /dev/null and b/base/dali-toolkit/images/popup_bubble_tail_bottom.png differ diff --git a/base/dali-toolkit/images/popup_bubble_tail_bottom_line.png b/base/dali-toolkit/images/popup_bubble_tail_bottom_line.png new file mode 100755 index 0000000..99a9c23 Binary files /dev/null and b/base/dali-toolkit/images/popup_bubble_tail_bottom_line.png differ 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 d615942..fe54de2 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 @@ -57,15 +57,15 @@ 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 float DISPLAYED_HIGHLIGHT_Z_OFFSET( 0.0f ); ///< 1. Highlight rendered (z-offset). -const float DISPLAYED_TEXT_VIEW_Z_OFFSET( 0.1f ); ///< 2. Text rendered (z-offset). +const float DISPLAYED_HIGHLIGHT_Z_OFFSET( 0.1f ); ///< 1. Highlight rendered (z-offset). +const float DISPLAYED_TEXT_VIEW_Z_OFFSET( 0.2f ); ///< 2. Text rendered (z-offset). const float UI_Z_OFFSET( 0.2f ); ///< 3. Text Selection Handles/Cursor z-offset. const Vector3 UI_OFFSET(0.0f, 0.0f, UI_Z_OFFSET); ///< Text Selection Handles/Cursor offset. const Vector3 DEFAULT_HANDLE_ONE_OFFSET(0.0f, -5.0f, 0.0f); ///< Handle One's Offset const Vector3 DEFAULT_HANDLE_TWO_OFFSET(0.0f, -5.0f, 0.0f); ///< Handle Two's Offset -const float TOP_HANDLE_TOP_OFFSET(-1.5f); ///< Offset between top handle and cutCopyPaste pop-up -const float BOTTOM_HANDLE_BOTTOM_OFFSET(1.5f); ///< Offset between bottom handle and cutCopyPaste pop-up +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 Degree CURSOR_ANGLE_OFFSET(2.0f); ///< Offset from the angle of italic angle. @@ -208,6 +208,8 @@ const Property::Index TextInput::SELECT_BUTTON_POSITION_PRIORITY_PROPERTY = const Property::Index TextInput::SELECT_ALL_BUTTON_POSITION_PRIORITY_PROPERTY = Internal::TextInput::TEXTINPUT_PROPERTY_START_INDEX+7; const Property::Index TextInput::CLIPBOARD_BUTTON_POSITION_PRIORITY_PROPERTY = Internal::TextInput::TEXTINPUT_PROPERTY_START_INDEX+8; +const Property::Index TextInput::POP_UP_OFFSET_FROM_TEXT_PROPERTY = Internal::TextInput::TEXTINPUT_PROPERTY_START_INDEX+9; + namespace Internal { @@ -312,6 +314,7 @@ TextInput::TextInput() 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 ), @@ -3703,6 +3706,7 @@ void TextInput::AddPopupOptions() void TextInput::SetPopupPosition(const Vector3& position) { mPopUpPanel.Self().SetPosition( position ); + mPopUpPanel.SetTailPosition( position ); } void TextInput::HidePopup(bool animate, bool signalFinished ) @@ -3738,27 +3742,31 @@ void TextInput::ShowPopup(bool animate) topHandle = mSelectionHandleTwoActualPosition; 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; + 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 ); + + position.x = xPosition; } 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( mBoundingRectangleWorldCoordinates.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 + BOTTOM_HANDLE_BOTTOM_OFFSET ; + alternativePopUpPosition.y = rowSize.height + mGrabHandle.GetCurrentSize().height + mPopupOffsetFromText.w +50.0f; } mPopUpPanel.SetAlternativeOffset( alternativePopUpPosition ); } @@ -3767,7 +3775,7 @@ void TextInput::ShowPopup(bool animate) 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; + Vector3 worldPosition = mDisplayedTextView.GetCurrentWorldPosition() - ( textViewSize * 0.5f ) + position; SetPopupPosition( worldPosition ); @@ -5135,6 +5143,16 @@ 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 ) ); @@ -5190,6 +5208,11 @@ void TextInput::SetProperty( BaseObject* object, Property::Index propertyIndex, textInputImpl.mPopUpPanel.SetButtonPriorityPosition( TextInputPopup::ButtonsClipboard, value.Get() ); break; } + case Toolkit::TextInput::POP_UP_OFFSET_FROM_TEXT_PROPERTY: + { + textInputImpl.SetOffsetFromText( value.Get< Vector4 >() ); + break; + } } } } @@ -5251,6 +5274,11 @@ Property::Value TextInput::GetProperty( BaseObject* object, Property::Index prop value = textInputImpl.mPopUpPanel.GetButtonPriorityPosition( TextInputPopup::ButtonsClipboard ); break; } + case Toolkit::TextInput::POP_UP_OFFSET_FROM_TEXT_PROPERTY: + { + value = textInputImpl.GetOffsetFromText(); + break; + } } } return value; diff --git a/base/dali-toolkit/internal/controls/text-input/text-input-impl.h b/base/dali-toolkit/internal/controls/text-input/text-input-impl.h index 9eb5ee6..e7a4f42 100644 --- a/base/dali-toolkit/internal/controls/text-input/text-input-impl.h +++ b/base/dali-toolkit/internal/controls/text-input/text-input-impl.h @@ -1333,6 +1333,18 @@ public: // Public to allow internal testing. */ void GetTextLayoutInfo(); + /** + * Set the offset for positioning Popup from the TextInput + * @param[in] offset in the order, left, top, right, bottom + */ + void SetOffsetFromText( const Vector4& offset ); + + /** + * Get the offset of the Popup from the TextInput + * @return Vector4 with the offset in the order, left, top, right, bottom + */ + const Vector4& GetOffsetFromText() const; + // Properties /** @@ -1452,10 +1464,11 @@ private: Vector4 mSelectionHandleFlipMargin; Vector4 mBoundingRectangleWorldCoordinates; - Clipboard mClipboard; ///< Handle to clipboard + Clipboard mClipboard; ///< Handle to clipboard // Styling - Vector4 mMaterialColor; // Color of the highlight + Vector4 mMaterialColor; // Color of the highlight + Vector4 mPopupOffsetFromText; // Offset of Popup from the TextInput. bool mOverrideAutomaticAlignment:1; ///< Whether to override the alignment automatically set by the text content (e.g. european LTR or arabic RTL) bool mCursorRTLEnabled:1; ///< Enable state of Alternate RTL Cursor (need to keep track of this as it's not always enabled) diff --git a/base/dali-toolkit/internal/controls/text-input/text-input-popup-impl.cpp b/base/dali-toolkit/internal/controls/text-input/text-input-popup-impl.cpp index 9df837f..bd7132e 100644 --- a/base/dali-toolkit/internal/controls/text-input/text-input-popup-impl.cpp +++ b/base/dali-toolkit/internal/controls/text-input/text-input-popup-impl.cpp @@ -42,7 +42,8 @@ const Vector3 POPUP_BORDER( Vector3(1.0f, 1.0f, 0.0f) ); */ // Popup: Tails -const char* DEFAULT_POPUP_TAIL_BOTTOM( DALI_IMAGE_DIR "00_popup_bubble_tail_bottom.png" ); +const char* DEFAULT_POPUP_TAIL_BOTTOM( DALI_IMAGE_DIR "popup_bubble_tail_bottom.png" ); +const char* DEFAULT_POPUP_TAIL_BOTTOM_OUTLINE( DALI_IMAGE_DIR "popup_bubble_tail_bottom_line.png" ); // Popup: Vertical Constraint // TODO: Remove - this should come from application - it is not possible to get the @@ -69,7 +70,7 @@ const float HIDE_POPUP_ANIMATION_DURATION(0.2f); ///< const float SHOW_POPUP_ANIMATION_DURATION(0.2f); ///< Duration of popup show animation in seconds. const Vector2 DEFAULT_ICON_SIZE( 45.0f, 45.0f ); ///< Default icon size for image in options -const float TEXT_POSITION_OFFSET( -19.0f ); ///< Default offset for text label +const float TEXT_POSITION_OFFSET( -19.0f ); ///< Default offset for text label const float ICON_POSITION_OFFSET( 19.0f ); ///< Default offset for icon const char* DEFAULT_ICON_CLIPBOARD( DALI_IMAGE_DIR "copy_paste_icon_clipboard.png" ); @@ -177,6 +178,35 @@ struct ConfinementConstraint Rect mBoundingRect; ///< Bounding Rect Popup must stay within }; +/** + * Confine actor to the x axis boundaries of reference actor (e.g. Parent) + */ +struct ParentXAxisConstraint +{ + /** + * Confinement constraint constructor. + */ + ParentXAxisConstraint( float handlesMidPoint = 0.0f ) + : mHandlesMidPoint( handlesMidPoint ) + { + } + + float operator()( const float constXPosition, + const PropertyInput& localWidthProperty, + const PropertyInput& anchorPointXProperty ) + { + const float size = localWidthProperty.GetFloat(); + const float anchor = anchorPointXProperty.GetFloat(); + + float newPosition = Clamp( mHandlesMidPoint, constXPosition - size * anchor , constXPosition + size * anchor); + + return newPosition; + } + + float mHandlesMidPoint; +}; + + } // unnamed namespace namespace Dali @@ -202,6 +232,7 @@ const char* const TextInputPopup::OPTION_CLIPBOARD("option-clipboard"); TextInputPopup::TextInputPopup() : mState(StateHidden), mRootActor(Layer::New()), + mPopupTailXPosition( 0.0f ), mContentSize( Vector3::ZERO ), mCutPasteButtonsColor( DEFAULT_POPUP_BACKGROUND ), mCutPasteButtonsPressedColor( DEFAULT_POPUP_BUTTON_PRESSED ), @@ -252,6 +283,15 @@ void TextInputPopup::ApplyConfinementConstraint() mRootActor.ApplyConstraint(constraint); } +void TextInputPopup::ApplyTailConstraint() +{ + mTail.RemoveConstraints(); + Constraint constraint = Constraint::New( Actor::POSITION_X, + LocalSource( Actor::SIZE_WIDTH ), + LocalSource( Actor::ANCHOR_POINT_X ), + ParentXAxisConstraint()); +} + void TextInputPopup::CreateLayer( const Vector2& size ) { mLayer = Layer::New(); @@ -312,6 +352,7 @@ void TextInputPopup::Clear() { if ( mBackground ) { + UnparentAndReset( mTail ); UnparentAndReset( mStencil ); UnparentAndReset( mBackground ); UnparentAndReset( mScrollView ); @@ -365,13 +406,21 @@ void TextInputPopup::CreatePopUpBackground() // Add Tail too. Image tailImage = Image::New( DEFAULT_POPUP_TAIL_BOTTOM ); + Image tailImageOutline = Image::New( DEFAULT_POPUP_TAIL_BOTTOM_OUTLINE ); + + mTailOutline = ImageActor::New ( tailImageOutline ); + mTailOutline.SetParentOrigin( ParentOrigin::CENTER ); + mTailOutline.SetAnchorPoint( AnchorPoint::CENTER ); + mTailOutline.ApplyConstraint( Constraint::New( Actor::SIZE, ParentSource( Actor::SIZE ), EqualToConstraint() ) ); mTail = ImageActor::New( tailImage ); mTail.SetParentOrigin( ParentOrigin::BOTTOM_CENTER ); mTail.SetAnchorPoint( AnchorPoint::TOP_CENTER ); - mBackground.Add( mTail ); // TODO: Make tail visible, and positioned in relation to original intended position of popup (i.e. before constrained effects) - mTail.SetVisible(false); + mTail.SetVisible(true); + mTail.SetColor( mCutPasteButtonsColor ); + mTailOutline.SetColor( mBorderColor ); + mTail.Add( mTailOutline); } } @@ -577,15 +626,12 @@ void TextInputPopup::AddOption(const std::string& name, const std::string& capti { i->SetSize( DIVIDER_WIDTH, dividerHeight ); } - - mTail.SetPosition(Vector3(0.0f, -20.0f, 0.0f)); - button.ClickedSignal().Connect( this, &TextInputPopup::OnButtonPressed ); } void TextInputPopup::Hide(bool animate) { - if(mBackground) + if( mRootActor ) { if(mAnimation) { @@ -596,8 +642,8 @@ void TextInputPopup::Hide(bool animate) if(animate) { mAnimation = Animation::New( HIDE_POPUP_ANIMATION_DURATION ); - mAnimation.AnimateTo( Property(mBackground, Actor::SCALE), Vector3::ZERO, AlphaFunctions::EaseOut ); - mAnimation.AnimateTo( Property(mBackground, Actor::COLOR_ALPHA), 0.0f, AlphaFunctions::EaseOut ); + mAnimation.AnimateTo( Property(mRootActor, Actor::SCALE), Vector3::ZERO, AlphaFunctions::EaseOut ); + mAnimation.AnimateTo( Property(mRootActor, Actor::COLOR_ALPHA), 0.0f, AlphaFunctions::EaseOut ); mAnimation.Play(); mAnimation.FinishedSignal().Connect( this, &TextInputPopup::OnHideFinished ); @@ -605,8 +651,8 @@ void TextInputPopup::Hide(bool animate) } else { - mBackground.SetProperty(Actor::SCALE, Vector3::ZERO); - mBackground.SetProperty(Actor::COLOR_ALPHA, 0.0f); + mRootActor.SetProperty(Actor::SCALE, Vector3::ZERO); + mRootActor.SetProperty(Actor::COLOR_ALPHA, 0.0f); mState = StateHidden; } } @@ -614,9 +660,11 @@ void TextInputPopup::Hide(bool animate) void TextInputPopup::Show(bool animate) { - if(mBackground) + if( mRootActor ) { - mBackground.SetSensitive( true ); + mRootActor.SetSensitive( true ); + + mTail.SetPosition(Vector3( mPopupTailXPosition, 0.0f, 0.0f)); if(mAnimation) { @@ -627,8 +675,8 @@ void TextInputPopup::Show(bool animate) if(animate) { mAnimation = Animation::New( SHOW_POPUP_ANIMATION_DURATION ); - mAnimation.AnimateTo( Property(mBackground, Actor::SCALE), Vector3::ONE, AlphaFunctions::EaseOut ); - mAnimation.AnimateTo( Property(mBackground, Actor::COLOR_ALPHA), 1.0f, AlphaFunctions::EaseOut ); + mAnimation.AnimateTo( Property(mRootActor, Actor::SCALE), Vector3::ONE, AlphaFunctions::EaseOut ); + mAnimation.AnimateTo( Property(mRootActor, Actor::COLOR_ALPHA), 1.0f, AlphaFunctions::EaseOut ); mAnimation.Play(); mAnimation.FinishedSignal().Connect( this, &TextInputPopup::OnShowFinished ); @@ -636,8 +684,8 @@ void TextInputPopup::Show(bool animate) } else { - mBackground.SetProperty(Actor::SCALE, Vector3::ONE); - mBackground.SetProperty(Actor::COLOR_ALPHA, 1.0f); + mRootActor.SetProperty(Actor::SCALE, Vector3::ONE); + mRootActor.SetProperty(Actor::COLOR_ALPHA, 1.0f); mState = StateShown; } } @@ -811,6 +859,7 @@ void TextInputPopup::AddPopupOptions() mLayer.Add( mStencil ); mLayer.Add( mScrollView ); mScrollView.Add( mBackground ); + mRootActor.Add( mTail ); Self().Add(mLayer); } @@ -820,6 +869,12 @@ void TextInputPopup::SetPopupBoundary( const Rect& boundingRectangle ) mBoundingRect = boundingRectangle; } +void TextInputPopup::SetTailPosition( const Vector3& position ) +{ + mPopupTailXPosition = position.x; + ApplyTailConstraint(); +} + bool TextInputPopup::OnButtonPressed( Toolkit::Button button ) { mPressedSignal.Emit( button ); @@ -861,3 +916,4 @@ TextInputPopup::ShowFinishedSignalV2& TextInputPopup::ShowFinishedSignal() } // namespace Toolkit } // namespace Dali + diff --git a/base/dali-toolkit/internal/controls/text-input/text-input-popup-impl.h b/base/dali-toolkit/internal/controls/text-input/text-input-popup-impl.h index cd5b2be..3a5a415 100644 --- a/base/dali-toolkit/internal/controls/text-input/text-input-popup-impl.h +++ b/base/dali-toolkit/internal/controls/text-input/text-input-popup-impl.h @@ -260,6 +260,12 @@ public: */ void SetPopupBoundary( const Rect& boundingRectangle ); + /** + * Sets the positon of the PopUp tail relative to TextInput + * @param position Position to set + */ + void SetTailPosition( const Vector3& position ); + private: /** @@ -285,6 +291,11 @@ private: void ApplyConfinementConstraint(); /** + * Applies constraint to keep the Tail attached to Popup + */ + void ApplyTailConstraint(); + + /** * Create a layer to hold the stencil * @param[in] size Size to of layer */ @@ -347,6 +358,10 @@ private: Property::Index mAlternativeOffsetProperty; ///< Property [Vector3] how much to offset the popup if it goes out of the screen ImageActor mBackground; ///< The background popup panel ImageActor mTail; ///< The tail for the popup + ImageActor mTailOutline; ///< The border/outline around the tail + + float mPopupTailXPosition; ///< X position of PopUp tail. + Vector3 mContentSize; ///< Size of Content (i.e. Buttons) ActorContainer mButtonContainer; ///< List of buttons added to popup. ActorContainer mDividerContainer; ///< List of dividers added to popup. diff --git a/capi/dali-toolkit/public-api/controls/text-input/text-input.h b/capi/dali-toolkit/public-api/controls/text-input/text-input.h index df140b3..3768c55 100644 --- a/capi/dali-toolkit/public-api/controls/text-input/text-input.h +++ b/capi/dali-toolkit/public-api/controls/text-input/text-input.h @@ -59,6 +59,9 @@ public: static const Property::Index SELECT_BUTTON_POSITION_PRIORITY_PROPERTY; // Property, name "select-button-position-priority", type unsigned int static const Property::Index SELECT_ALL_BUTTON_POSITION_PRIORITY_PROPERTY; // Property, name "select-all-button-position-priority", type unsigned int static const Property::Index CLIPBOARD_BUTTON_POSITION_PRIORITY_PROPERTY; // Property, name "clipboard-button-position-priority", type unsigned int + + static const Property::Index POP_UP_OFFSET_FROM_TEXT_PROPERTY; // Property, name "popup-offset-from-text", type VECTOR4 + /** @} */ /// @name Signals