TextInput Popup is parented to TextInput so moves with it. Tail flips if Popup in... 85/24185/1
authorAgnelo Vaz <agnelo.vaz@samsung.com>
Mon, 23 Jun 2014 20:52:40 +0000 (21:52 +0100)
committerAdeel Kazmi <adeel.kazmi@samsung.com>
Tue, 8 Jul 2014 17:47:37 +0000 (18:47 +0100)
[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 <adeel.kazmi@samsung.com>
base/dali-toolkit/images/popup_bubble_tail_top.png [new file with mode: 0755]
base/dali-toolkit/images/popup_bubble_tail_top_ef.png [new file with mode: 0755]
base/dali-toolkit/images/popup_bubble_tail_top_line.png [new file with mode: 0755]
base/dali-toolkit/internal/controls/text-input/text-input-impl.cpp
base/dali-toolkit/internal/controls/text-input/text-input-impl.h
base/dali-toolkit/internal/controls/text-input/text-input-popup-impl.cpp
base/dali-toolkit/internal/controls/text-input/text-input-popup-impl.h

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 (executable)
index 0000000..6e635fc
Binary files /dev/null and b/base/dali-toolkit/images/popup_bubble_tail_top.png differ
diff --git a/base/dali-toolkit/images/popup_bubble_tail_top_ef.png b/base/dali-toolkit/images/popup_bubble_tail_top_ef.png
new file mode 100755 (executable)
index 0000000..1ace985
Binary files /dev/null and b/base/dali-toolkit/images/popup_bubble_tail_top_ef.png differ
diff --git a/base/dali-toolkit/images/popup_bubble_tail_top_line.png b/base/dali-toolkit/images/popup_bubble_tail_top_line.png
new file mode 100755 (executable)
index 0000000..3b1ad65
Binary files /dev/null and b/base/dali-toolkit/images/popup_bubble_tail_top_line.png differ
index 952503a..2ec8170 100644 (file)
@@ -1197,6 +1197,8 @@ void TextInput::OnControlSizeSet(const Vector3& targetSize)
 void TextInput::OnRelaidOut( Vector2 size, ActorSizeContainer& container )
 {
   Relayout( mDisplayedTextView, size, container );
 void TextInput::OnRelaidOut( Vector2 size, ActorSizeContainer& container )
 {
   Relayout( mDisplayedTextView, size, container );
+  Relayout( mPopupPanel.GetRootActor(), size, container );
+
   GetTextLayoutInfo();
 
   DrawCursor();
   GetTextLayoutInfo();
 
   DrawCursor();
@@ -3712,10 +3714,45 @@ 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.GetRootActor().SetPosition( position );
+  const Vector3& visiblePopUpSize = mPopupPanel.GetVisibileSize();
+
+  Vector3 clampedPosition ( position );
+  Vector3 tailOffsetPosition ( position );
+
+  float xOffSet( 0.0f );
+
+  Actor self = Self();
+  const Vector3 textViewTopLeftWorldPosition = self.GetCurrentWorldPosition() - self.GetCurrentSize()*0.5f;
+
+  const float popUpLeft = textViewTopLeftWorldPosition.x + position.x - visiblePopUpSize.width*0.5f;
+  const float popUpTop = textViewTopLeftWorldPosition.y + position.y - visiblePopUpSize.height;
+
+  // Clamp to left or right or of boundary
+  if( popUpLeft < mBoundingRectangleWorldCoordinates.x )
+  {
+    xOffSet = mBoundingRectangleWorldCoordinates.x - popUpLeft ;
+  }
+  else if ( popUpLeft + visiblePopUpSize.width > mBoundingRectangleWorldCoordinates.z )
+  {
+    xOffSet = mBoundingRectangleWorldCoordinates.z - ( popUpLeft + visiblePopUpSize.width );
+  }
+
+  clampedPosition.x = position.x + xOffSet;
+  tailOffsetPosition.x = -xOffSet;
+
+  // Check if top left of PopUp outside of top bounding rectangle, if so then flip to lower position.
+  bool flipTail( false );
+
+  if ( popUpTop < mBoundingRectangleWorldCoordinates.y )
+  {
+    clampedPosition.y = alternativePosition.y + visiblePopUpSize.height;
+    flipTail = true;
+  }
+
+  mPopupPanel.GetRootActor().SetPosition( clampedPosition );
+  mPopupPanel.SetTailPosition( tailOffsetPosition, flipTail );
 }
 
 void TextInput::HidePopup(bool animate, bool signalFinished )
 }
 
 void TextInput::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;
 {
   Vector3 position;
+  Vector2 alternativePopupPosition;
 
   if(mHighlightMeshActor && mState == StateEdit)
   {
 
   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);
 
     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;
 
     position.x = xPosition;
+
+    // Alternative position if no upper space
+    bottomHandle.y += GetSelectionHandleSize().y + mPopupOffsetFromText.w;
+    alternativePopupPosition = Vector2 ( position.x, bottomHandle.y );
   }
   else
   {
   }
   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.
     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;
     }
     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
 
   // Show popup
-  mPopupPanel.Show(animate);
+  mPopupPanel.Show( Self(), animate );
   StartMonitoringStageForTouch();
 
   mPopupPanel.PressedSignal().Connect( this, &TextInput::OnPopupButtonPressed );
   StartMonitoringStageForTouch();
 
   mPopupPanel.PressedSignal().Connect( this, &TextInput::OnPopupButtonPressed );
index 35d9313..d38b7cb 100644 (file)
@@ -1062,8 +1062,9 @@ public:  // Public to allow internal testing.
   /**
    * Sets popup position
    * @param[in] position The actual position for this popup.
   /**
    * 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
 
   /**
    * Hides the popup
index 515a53c..9951f88 100644 (file)
@@ -32,12 +32,8 @@ namespace
 {
 const Vector2 DEFAULT_POPUP_INDICATOR_OFFSET(0.0f, 60.0f);
 
 {
 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.
 // 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
 
 /**
  * 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_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_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" );
 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 ) );
 
 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<float> boundingRect = Rect<float>(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<float> 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
 } // unnamed namespace
 
 namespace Dali
@@ -235,6 +112,7 @@ const char* const TextInputPopup::OPTION_CLIPBOARD("option-clipboard");
 TextInputPopup::TextInputPopup()
 : mState(StateHidden),
   mRoot(Layer::New()),
 TextInputPopup::TextInputPopup()
 : mState(StateHidden),
   mRoot(Layer::New()),
+  mVisiblePopUpSize(),
   mPopupTailXPosition( 0.0f ),
   mContentSize( POPUP_MIN_SIZE ),
   mBackgroundColor( DEFAULT_POPUP_BACKGROUND ),
   mPopupTailXPosition( 0.0f ),
   mContentSize( POPUP_MIN_SIZE ),
   mBackgroundColor( DEFAULT_POPUP_BACKGROUND ),
@@ -254,51 +132,31 @@ TextInputPopup::TextInputPopup()
   mHideFinishedSignal(),
   mShowFinishedSignal()
 {
   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 );
   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<Vector3>( 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<float>( 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 );
 {
   mStencil = CreateSolidColorActor( Color::BLUE );
   mStencil.SetParentOrigin( ParentOrigin::CENTER );
@@ -332,7 +190,7 @@ void TextInputPopup::CreateScrollView()
   mScrollView.ScrollCompletedSignal().Connect( this, &TextInputPopup::OnScrollCompleted );
 }
 
   mScrollView.ScrollCompletedSignal().Connect( this, &TextInputPopup::OnScrollCompleted );
 }
 
-void TextInputPopup::UpdateScrollViewProperty( const Vector2& visibleSize )
+void TextInputPopup::UpdateScrollViewRulerAndSize( const Vector2& visibleSize )
 {
   mScrollView.SetSize( visibleSize.x, visibleSize.y );
 
 {
   mScrollView.SetSize( visibleSize.x, visibleSize.y );
 
@@ -344,10 +202,6 @@ void TextInputPopup::UpdateScrollViewProperty( const Vector2& visibleSize )
   mScrollView.SetRulerY(rulerY);
 }
 
   mScrollView.SetRulerY(rulerY);
 }
 
-void TextInputPopup::RemoveFromStage()
-{
-  Stage::GetCurrent().Remove( mRoot );
-}
 
 void TextInputPopup::Clear()
 {
 
 void TextInputPopup::Clear()
 {
@@ -359,10 +213,8 @@ void TextInputPopup::Clear()
     UnparentAndReset( mScrollView );
     mButtonContainer.clear();
     mDividerContainer.clear();
     UnparentAndReset( mScrollView );
     mButtonContainer.clear();
     mDividerContainer.clear();
-
-    RemoveFromStage();
     mRoot.RemoveConstraints();
     mRoot.RemoveConstraints();
-
+    RemoveFromParent();
     mState = StateHidden;
   }
 }
     mState = StateHidden;
   }
 }
@@ -436,7 +288,7 @@ void TextInputPopup::CreateBackground()
     mBackgroundEffect.Add( mBackgroundLine );
 
     Hide(false);
     mBackgroundEffect.Add( mBackgroundLine );
 
     Hide(false);
-    AddToStage();
+    GetRootActor().Add( mBackground );
   }
 }
 
   }
 }
 
@@ -475,17 +327,17 @@ void TextInputPopup::CreateTail()
 
 ImageActor TextInputPopup::CreateDivider()
 {
 
 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 )
 }
 
 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 )
   {
 {
   if( mRoot )
   {
@@ -697,6 +549,11 @@ void TextInputPopup::Show(bool animate)
       mAnimation.Reset();
     }
 
       mAnimation.Reset();
     }
 
+    if ( target )
+    {
+      AddToParent( target );
+    }
+
     if(animate)
     {
       mAnimation = Animation::New( SHOW_POPUP_ANIMATION_DURATION );
     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;
 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 );
   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 );
 
   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
   mRoot.SetSize( popupSize );   // Make Root Actor reflect the size of its content
-
 }
 
 void TextInputPopup::SetPopupBoundary( const Rect<float>& boundingRectangle )
 }
 
 void TextInputPopup::SetPopupBoundary( const Rect<float>& boundingRectangle )
@@ -956,12 +807,30 @@ void TextInputPopup::SetPopupBoundary( const Rect<float>& boundingRectangle )
   mBoundingRect =  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;
   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 )
 }
 
 bool TextInputPopup::OnButtonPressed( Toolkit::Button button )
index 41b9bb6..759c104 100644 (file)
@@ -181,8 +181,9 @@ public:
   /**
    * Shows the popup
    * @param[in] animate (optional) whether to animate popup to show state over time (i.e. tween).
   /**
    * 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.
 
   /**
    * Sets Alternative offset property.
@@ -321,10 +322,17 @@ public:
   void SetPopupBoundary( const Rect<float>& boundingRectangle );
 
   /**
   void SetPopupBoundary( const Rect<float>& 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:
 
 
 private:
 
@@ -341,9 +349,15 @@ private:
                                                                           const std::string& name, const std::string& caption, Image iconImage, bool enabled );
 
   /**
                                                                           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.
 
   /**
    * 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
    */
    * 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
 
   /**
    * 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)
 
   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
   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
 
   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.
 
   Vector2 mContentSize;                               ///< Size of Content (i.e. Buttons)
   ActorContainer mButtonContainer;                    ///< List of buttons added to popup.