From 8b1f3f9ca0409d954a6fa7c35fbc43523b2ddc0e Mon Sep 17 00:00:00 2001 From: Agnelo Vaz Date: Mon, 23 Jun 2014 21:52:40 +0100 Subject: [PATCH] TextInput Popup is parented to TextInput so moves with it. Tail flips if Popup in lower position [problem] Popup Tail points down even if highlighted text is above it. Popup does not move with TextInput. [cause] Missing code. [solution] Use different image in this case and reposition. Change-Id: I15236fb02b7bc09a1e8c012bae4c93735cf24dd7 Signed-off-by: Adeel Kazmi --- base/dali-toolkit/images/popup_bubble_tail_top.png | Bin 0 -> 1298 bytes .../images/popup_bubble_tail_top_ef.png | Bin 0 -> 3065 bytes .../images/popup_bubble_tail_top_line.png | Bin 0 -> 1377 bytes .../controls/text-input/text-input-impl.cpp | 68 ++++-- .../internal/controls/text-input/text-input-impl.h | 3 +- .../controls/text-input/text-input-popup-impl.cpp | 263 ++++++--------------- .../controls/text-input/text-input-popup-impl.h | 38 +-- 7 files changed, 141 insertions(+), 231 deletions(-) create mode 100755 base/dali-toolkit/images/popup_bubble_tail_top.png create mode 100755 base/dali-toolkit/images/popup_bubble_tail_top_ef.png create mode 100755 base/dali-toolkit/images/popup_bubble_tail_top_line.png diff --git a/base/dali-toolkit/images/popup_bubble_tail_top.png b/base/dali-toolkit/images/popup_bubble_tail_top.png new file mode 100755 index 0000000000000000000000000000000000000000..6e635fc9faded05e1a3929a74d55185b60622665 GIT binary patch literal 1298 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 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 ) @@ -3731,9 +3768,10 @@ void TextInput::HidePopup(bool animate, bool signalFinished ) } } -void TextInput::ShowPopup(bool animate) +void TextInput::ShowPopup( bool animate ) { Vector3 position; + Vector2 alternativePopupPosition; if(mHighlightMeshActor && mState == StateEdit) { @@ -3757,12 +3795,13 @@ void TextInput::ShowPopup(bool animate) 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 { @@ -3771,25 +3810,18 @@ void TextInput::ShowPopup(bool animate) const Size rowSize = GetRowRectFromCharacterPosition( mCursorPosition ); position.y -= ( mPopupOffsetFromText.y + rowSize.height ); // if can't be positioned above, then position below row. - Vector2 alternativePopupPosition( mBoundingRectangleWorldCoordinates.x, position.y ); // default if no grab handle + alternativePopupPosition = Vector2( position.x, position.y ); // default if no grab handle if ( mGrabHandle ) { // If grab handle enabled then position pop-up below the grab handle. alternativePopupPosition.y = rowSize.height + mGrabHandle.GetCurrentSize().height + mPopupOffsetFromText.w +50.0f; } - mPopupPanel.SetAlternativeOffset( alternativePopupPosition ); } - // reposition popup above the desired cursor posiiton. - Vector3 textViewSize = mDisplayedTextView.GetCurrentSize(); - textViewSize.z = 0.0f; - // World position = world position of local position i.e. top-left corner of TextView - Vector3 worldPosition = mDisplayedTextView.GetCurrentWorldPosition() - ( textViewSize * 0.5f ) + position; - - SetPopupPosition( worldPosition ); + SetPopupPosition( position, alternativePopupPosition ); // Show popup - mPopupPanel.Show(animate); + mPopupPanel.Show( Self(), animate ); StartMonitoringStageForTouch(); mPopupPanel.PressedSignal().Connect( this, &TextInput::OnPopupButtonPressed ); 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 35d9313..d38b7cb 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 @@ -1062,8 +1062,9 @@ public: // Public to allow internal testing. /** * Sets popup position * @param[in] position The actual position for this popup. + * @param[in] alternativePosition Alternative popup position if no space in upper area. */ - void SetPopupPosition(const Vector3& position); + void SetPopupPosition(const Vector3& position, const Vector2& alternativePosition ); /** * Hides the popup 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 515a53c..9951f88 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 @@ -32,12 +32,8 @@ namespace { const Vector2 DEFAULT_POPUP_INDICATOR_OFFSET(0.0f, 60.0f); - -// TODO: This should be based on the content for example: // 1. For selection: should be above top of highlighted selection, or below bottom of highlighted selection + end handle. // 2. For cursor: should be above top of cursor, or below bottom of cursor + grab handle. -const std::string POPUP_ALTERNATIVE_OFFSET("popup-alternative-offset"); ///< Alternative offset property for confinenment constraint. -const std::string POPUP_REQUESTED_POSITION("popup-requested-position"); ///< Position the Popup was requested to be, for confinenment constraint. /** * Image resource paths @@ -45,9 +41,14 @@ const std::string POPUP_REQUESTED_POSITION("popup-requested-position"); // const std::string POPUP_BACKGROUND( DALI_IMAGE_DIR "popup_bubble_bg.#.png" ); const std::string POPUP_BACKGROUND_EFFECT( DALI_IMAGE_DIR "popup_bubble_bg_ef.#.png" ); const std::string POPUP_BACKGROUND_LINE( DALI_IMAGE_DIR "popup_bubble_bg_line.#.png" ); + const std::string POPUP_TAIL_BOTTOM( DALI_IMAGE_DIR "popup_bubble_tail_bottom.png" ); const std::string POPUP_TAIL_BOTTOM_EFFECT( DALI_IMAGE_DIR "popup_bubble_tail_bottom_ef.png" ); const std::string POPUP_TAIL_BOTTOM_LINE( DALI_IMAGE_DIR "popup_bubble_tail_bottom_line.png" ); +const std::string POPUP_TAIL_TOP( DALI_IMAGE_DIR "popup_bubble_tail_top.png" ); +const std::string POPUP_TAIL_TOP_EFFECT( DALI_IMAGE_DIR "popup_bubble_tail_top_ef.png" ); +const std::string POPUP_TAIL_TOP_LINE( DALI_IMAGE_DIR "popup_bubble_tail_top_line.png" ); + const std::string OPTION_ICON_CLIPBOARD( DALI_IMAGE_DIR "copy_paste_icon_clipboard.png" ); const std::string OPTION_ICON_COPY( DALI_IMAGE_DIR "copy_paste_icon_copy.png" ); const std::string OPTION_ICON_CUT( DALI_IMAGE_DIR "copy_paste_icon_cut.png" ); @@ -86,130 +87,6 @@ const Vector4 DEFAULT_OPTION_ICON_PRESSED( Vector4( 1.0f, 1.0f, 1.0f, 1.0f ) ); const Vector4 DEFAULT_OPTION_TEXT( Vector4( 1.0f, 1.0f, 1.0f, 1.0f ) ); const Vector4 DEFAULT_OPTION_TEXT_PRESSED( Vector4( 1.0f, 1.0f, 1.0f, 1.0f ) ); - -/** - * Confine Actor to boundaries of reference actor (e.g. Parent) - * Actor bounds (top-left position + size) are confined to reference Actor's - * bounds. - */ -struct ConfinementConstraint -{ - /** - * Confinement constraint constructor. - * @param[in] topLeftMargin (optional) Top-Left margins (defaults to 0.0f, 0.0f) - * @param[in] bottomRightMargin (optional) Bottom-Right margins (defaults to 0.0f, 0.0f) - * @paran[in[ flipHorizontal (optional) whether to flip Actor to other side if near edge - * @param[in] flipVertical (optional) whether to flip Actor to the other side if near edge - * @param[in] boundingRect Rectangle to bound Popup to. - * - */ - ConfinementConstraint(Vector2 topLeftMargin = Vector2::ZERO, Vector2 bottomRightMargin = Vector2::ZERO, bool flipHorizontal = false, bool flipVertical = false, Rect boundingRect = Rect(0.0f, 0.0f, 0.0f, 0.0f) ) - : mMinIndent(topLeftMargin), - mMaxIndent(bottomRightMargin), - mFlipHorizontal(flipHorizontal), - mFlipVertical(flipVertical), - mBoundingRect( boundingRect ) - { - } - - Vector3 operator()(const Vector3& constPosition, - const PropertyInput& sizeProperty, - const PropertyInput& parentOriginProperty, - const PropertyInput& anchorPointProperty, - const PropertyInput& referenceSizeProperty, - const PropertyInput& alternativeOffsetProperty, - const PropertyInput& requestedPositionProperty ) - { - const Vector3& size = sizeProperty.GetVector3(); - const Vector3& origin = parentOriginProperty.GetVector3(); - const Vector3& anchor = anchorPointProperty.GetVector3(); - const Vector3& referenceSize = referenceSizeProperty.GetVector3(); - const Vector2& alternativeOffset = alternativeOffsetProperty.GetVector2(); - const Vector3& requestedPosition = requestedPositionProperty.GetVector3(); - - Vector3 newPosition( requestedPosition ); - - // Get actual position of Actor relative to parent's Top-Left. - Vector3 position(constPosition + origin * referenceSize); - - // if top-left corner is outside of Top-Left bounds, then push back in screen. - - Vector3 corner(position - size * anchor - mMinIndent); - - if ( mFlipHorizontal ) - { - if( corner.x < mBoundingRect.x ) - { - // Snap Popup to left hand boundary so stays visible - corner.x = mBoundingRect.x - ( origin.x * referenceSize.x ) + ( size.x * anchor.x ); - newPosition.x = corner.x; - } - else if ( ( corner.x + size.x ) > ( mBoundingRect.x + mBoundingRect.width )) - { - // Calculate offset from left boundary Popup must be placed at so it does not exceed right side boundary. - float requiredOffSetFromLeftBoundaryToFit = mBoundingRect.width - size.x; - corner.x = mBoundingRect.x + requiredOffSetFromLeftBoundaryToFit - ( origin.x * referenceSize.x ) + ( size.x * anchor.x ); - newPosition.x = corner.x; - } - } - - if(mFlipVertical && corner.y < 0.0f) - { - corner.y = 0.0f; - newPosition.y += size.height + alternativeOffset.height; - } - - newPosition.y -= std::min(corner.y, 0.0f); - - // if bottom-right corner is outside of Bottom-Right bounds, then push back in screen. - corner += size - referenceSize + mMinIndent + mMaxIndent; - - if(mFlipVertical && corner.y > 0.0f) - { - corner.y = 0.0f; - newPosition.y -= size.height + alternativeOffset.height; - } - - return newPosition; - } - - Vector3 mMinIndent; ///< Top-Left Margin - Vector3 mMaxIndent; ///< Bottom-Right Margin. - bool mFlipHorizontal; ///< Whether to flip actor's position if exceeds horizontal screen bounds - bool mFlipVertical; ///< Whether to flip actor's position if exceeds vertical screen bounds - 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& localSizeWidthProperty, - const PropertyInput& parentWidthProperty, - const PropertyInput& anchorPointXProperty ) - { - const float localSizeProperty = localSizeWidthProperty.GetFloat(); - const float size = parentWidthProperty.GetFloat(); - - float newPosition = std::max( mHandlesMidPoint, -size/2 + localSizeProperty ); - newPosition = std::min( newPosition, size/2 - localSizeProperty ); - return newPosition; - } - - float mHandlesMidPoint; -}; - - } // unnamed namespace namespace Dali @@ -235,6 +112,7 @@ const char* const TextInputPopup::OPTION_CLIPBOARD("option-clipboard"); TextInputPopup::TextInputPopup() : mState(StateHidden), mRoot(Layer::New()), + mVisiblePopUpSize(), mPopupTailXPosition( 0.0f ), mContentSize( POPUP_MIN_SIZE ), mBackgroundColor( DEFAULT_POPUP_BACKGROUND ), @@ -254,51 +132,31 @@ TextInputPopup::TextInputPopup() mHideFinishedSignal(), mShowFinishedSignal() { - mAlternativeOffsetProperty = mRoot.RegisterProperty( POPUP_ALTERNATIVE_OFFSET, Vector2::ZERO ); - mRequestionPositionProperty = mRoot.RegisterProperty( POPUP_REQUESTED_POSITION, Vector3::ZERO ); - mRoot.SetParentOrigin( ParentOrigin::CENTER ); + mRoot.SetParentOrigin( ParentOrigin::TOP_LEFT ); mRoot.SetAnchorPoint( AnchorPoint::BOTTOM_CENTER ); - // constrain popup to size of parent. } -void TextInputPopup::AddToStage() +void TextInputPopup::AddToParent( Actor parent ) { - // TODO: Confinement constraint borders should be defined by the application. - // It should also not use the stage directly, instead it should add to parent container. - Stage::GetCurrent().Add(mRoot); + Actor existingParent = mRoot.GetParent(); - ApplyConfinementConstraint(); + if ( !existingParent ) + { + parent.Add( mRoot ); + } } -void TextInputPopup::ApplyConfinementConstraint() +void TextInputPopup::RemoveFromParent() { - mRoot.RemoveConstraints(); - Constraint constraint = Constraint::New( Actor::POSITION, - LocalSource( Actor::SIZE ), - LocalSource( Actor::PARENT_ORIGIN ), - LocalSource( Actor::ANCHOR_POINT ), - ParentSource( Actor::SIZE ), - LocalSource( mAlternativeOffsetProperty ), - LocalSource( mRequestionPositionProperty), - ConfinementConstraint( DEFAULT_POPUP_INDICATOR_OFFSET, - Vector2::ZERO, - true, - true, mBoundingRect ) ); - mRoot.ApplyConstraint(constraint); -} + Actor parent = mRoot.GetParent(); -void TextInputPopup::ApplyTailConstraint() -{ - mTail.RemoveConstraints(); - Constraint constraint = Constraint::New( Actor::POSITION_X, - LocalSource( Actor::SIZE_WIDTH ), - ParentSource( Actor::SIZE_WIDTH ), - LocalSource( Actor::PARENT_ORIGIN_X ), - ParentXAxisConstraint( mPopupTailXPosition )); - mTail.ApplyConstraint( constraint ); + if ( parent ) + { + parent.Remove( mRoot ); + } } -void TextInputPopup::CreateStencil( const Vector2& size) +void TextInputPopup::CreateStencil( const Vector2& size ) { mStencil = CreateSolidColorActor( Color::BLUE ); mStencil.SetParentOrigin( ParentOrigin::CENTER ); @@ -332,7 +190,7 @@ void TextInputPopup::CreateScrollView() mScrollView.ScrollCompletedSignal().Connect( this, &TextInputPopup::OnScrollCompleted ); } -void TextInputPopup::UpdateScrollViewProperty( const Vector2& visibleSize ) +void TextInputPopup::UpdateScrollViewRulerAndSize( const Vector2& visibleSize ) { mScrollView.SetSize( visibleSize.x, visibleSize.y ); @@ -344,10 +202,6 @@ void TextInputPopup::UpdateScrollViewProperty( const Vector2& visibleSize ) mScrollView.SetRulerY(rulerY); } -void TextInputPopup::RemoveFromStage() -{ - Stage::GetCurrent().Remove( mRoot ); -} void TextInputPopup::Clear() { @@ -359,10 +213,8 @@ void TextInputPopup::Clear() UnparentAndReset( mScrollView ); mButtonContainer.clear(); mDividerContainer.clear(); - - RemoveFromStage(); mRoot.RemoveConstraints(); - + RemoveFromParent(); mState = StateHidden; } } @@ -436,7 +288,7 @@ void TextInputPopup::CreateBackground() mBackgroundEffect.Add( mBackgroundLine ); Hide(false); - AddToStage(); + GetRootActor().Add( mBackground ); } } @@ -475,17 +327,17 @@ void TextInputPopup::CreateTail() ImageActor TextInputPopup::CreateDivider() { - ImageActor divider = Toolkit::CreateSolidColorActor( mLineColor ); - divider.SetParentOrigin( ParentOrigin::TOP_LEFT ); - divider.SetAnchorPoint( AnchorPoint::TOP_LEFT ); - divider.SetSize( POPUP_DIVIDER_SIZE ); - divider.SetPosition( mContentSize.width - POPUP_DIVIDER_SIZE.width, 0.0f ); + ImageActor divider = Toolkit::CreateSolidColorActor( mLineColor ); + divider.SetParentOrigin( ParentOrigin::TOP_LEFT ); + divider.SetAnchorPoint( AnchorPoint::TOP_LEFT ); + divider.SetSize( POPUP_DIVIDER_SIZE ); + divider.SetPosition( mContentSize.width - POPUP_DIVIDER_SIZE.width, 0.0f ); - // Keep track of all the dividers. As their height's need to be updated to the max. of all - // buttons currently added. - mDividerContainer.push_back( divider ); + // Keep track of all the dividers. As their height's need to be updated to the max of all + // buttons currently added. + mDividerContainer.push_back( divider ); - return divider; + return divider; } ImageActor TextInputPopup::CreatePressedBackground( const Vector2& requiredSize ) @@ -685,7 +537,7 @@ void TextInputPopup::Hide(bool animate) } } -void TextInputPopup::Show(bool animate) +void TextInputPopup::Show( Actor target, bool animate ) { if( mRoot ) { @@ -697,6 +549,11 @@ void TextInputPopup::Show(bool animate) mAnimation.Reset(); } + if ( target ) + { + AddToParent( target ); + } + if(animate) { mAnimation = Animation::New( SHOW_POPUP_ANIMATION_DURATION ); @@ -716,12 +573,6 @@ void TextInputPopup::Show(bool animate) } } -void TextInputPopup::SetAlternativeOffset(Vector2 offset) -{ - mRoot.SetProperty( mAlternativeOffsetProperty, offset ); - ApplyConfinementConstraint(); -} - TextInputPopup::State TextInputPopup::GetState(void) const { return mState; @@ -933,22 +784,22 @@ void TextInputPopup::AddPopupOptions() } } - // 5. Calcurate a lot of size to make the layout. + // 5. Calculate size of content and of popup including borders const Vector2 visibleContentSize = Vector2( std::min( mContentSize.x, POPUP_MAX_SIZE.x - POPUP_BORDER.x - POPUP_BORDER.y ), mContentSize.y ); const Vector2 popupSize = Vector2( POPUP_BORDER.x + visibleContentSize.x + POPUP_BORDER.y, POPUP_BORDER.z + visibleContentSize.y + POPUP_BORDER.w ); + mVisiblePopUpSize = Vector3( popupSize.x, popupSize.y, 1.0f); - // 6. Set the scroll view ruller. - UpdateScrollViewProperty( visibleContentSize ); + // 6. Set the scroll view ruler. + UpdateScrollViewRulerAndSize( visibleContentSize ); - // 8. Create stencil + // 7. Create stencil const Vector2 stencilSize = Vector2( popupSize.x, popupSize.y + POPUP_TAIL_SIZE.x + POPUP_TAIL_Y_OFFSET ); CreateStencil( stencilSize ); mRoot.Add( mStencil ); - // 7. Set the root size. + // 8. Set the root size. mRoot.SetSize( popupSize ); // Make Root Actor reflect the size of its content - } void TextInputPopup::SetPopupBoundary( const Rect& boundingRectangle ) @@ -956,12 +807,30 @@ void TextInputPopup::SetPopupBoundary( const Rect& boundingRectangle ) mBoundingRect = boundingRectangle; } -void TextInputPopup::SetTailPosition( const Vector3& position ) +const Vector3& TextInputPopup::GetVisibileSize() const +{ + return mVisiblePopUpSize; +} + + +void TextInputPopup::SetTailPosition( const Vector3& position, bool yAxisFlip ) { - mRoot.SetProperty( mRequestionPositionProperty, position ); mPopupTailXPosition = position.x; - ApplyConfinementConstraint(); - ApplyTailConstraint(); + mTail.SetX( position.x ); + + if ( yAxisFlip ) + { + Image tail = Image::New( POPUP_TAIL_TOP ); + mTail.SetImage( tail ); + mTail.SetParentOrigin( ParentOrigin::TOP_CENTER ); + mTail.SetAnchorPoint( AnchorPoint::BOTTOM_CENTER ); + mTail.SetY( POPUP_BORDER.y - POPUP_TAIL_Y_OFFSET ); + Image tailEffect = Image::New( POPUP_TAIL_TOP_EFFECT ); + mTailEffect.SetImage( tailEffect ); + + Image tailLine = Image::New( POPUP_TAIL_TOP_LINE ); + mTailLine.SetImage( tailLine ); + } } bool TextInputPopup::OnButtonPressed( Toolkit::Button button ) 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 41b9bb6..759c104 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 @@ -181,8 +181,9 @@ public: /** * Shows the popup * @param[in] animate (optional) whether to animate popup to show state over time (i.e. tween). + * @param[in] target Actor to parent popup. */ - void Show(bool animate = true); + void Show( Actor target, bool animate = true ); /** * Sets Alternative offset property. @@ -321,10 +322,17 @@ public: void SetPopupBoundary( const Rect& boundingRectangle ); /** - * Sets the positon of the Popup tail relative to TextInput - * @param position Position to set + * Get Visible size of the Popup, excludes content that needs scrolling + * @return Vector3 size of Popup */ - void SetTailPosition( const Vector3& position ); + const Vector3& GetVisibileSize() const; + + /** + * Sets the positon of the PopUp tail relative to TextInput + * @param[in] position Position to set + * @param[in] yAxisFlip If tail should be flipped in y axis + */ + void SetTailPosition( const Vector3& position, const bool yAxisFlip ); private: @@ -341,9 +349,15 @@ private: const std::string& name, const std::string& caption, Image iconImage, bool enabled ); /** - * Adds Popup to the stage (ideally on a separate top-most layer and as an overlay) + * @brief Adds popup to the given parent + * @paran[in] parent target to add Popup to */ - void AddToStage(); + void AddToParent( Actor parent ); + + /** + * @brief Removes Popup from Parent + */ + void RemoveFromParent(); /** * Applies constraint to keep Popup in view within the desired area. @@ -382,12 +396,7 @@ private: * Set the scroll view size and ruler. * @param[in] visibleSize size of the visible scroll view */ - void UpdateScrollViewProperty( const Vector2& visibleSize ); - - /** - * Removes Popup from the stage. - */ - void RemoveFromStage(); + void UpdateScrollViewRulerAndSize( const Vector2& visibleSize ); /** * Called when a button is pressed in the Popup @@ -413,8 +422,6 @@ private: State mState; ///< Popup State. Layer mRoot; ///< The actor which all popup content is added to (i.e. panel and buttons) - Property::Index mAlternativeOffsetProperty; ///< Property [Vector3] how much to offset the popup if it goes out of the screen - Property::Index mRequestionPositionProperty; ///< Prperty [Vector3] Requested position to place popup ImageActor mBackground; ///< The background popup panel ImageActor mBackgroundEffect; ///< The background effect ImageActor mBackgroundLine; ///< The background line @@ -422,7 +429,8 @@ private: ImageActor mTailEffect; ///< the tail effect ImageActor mTailLine; ///< The border/outline around the tail - float mPopupTailXPosition; ///< X position of Popup tail. + Vector3 mVisiblePopUpSize; ///< Visible Size of Popup excluding content that needs scrolling. + float mPopupTailXPosition; ///< X position of PopUp tail. Vector2 mContentSize; ///< Size of Content (i.e. Buttons) ActorContainer mButtonContainer; ///< List of buttons added to popup. -- 2.7.4