TextInput Popup scrolling fixed after GUI changes. GUI settings changed. 99/24199/1
authorAgnelo Vaz <agnelo.vaz@samsung.com>
Tue, 24 Jun 2014 14:54:59 +0000 (15:54 +0100)
committerAdeel Kazmi <adeel.kazmi@samsung.com>
Tue, 8 Jul 2014 17:48:00 +0000 (18:48 +0100)
[problem]      Scrolling would cause the buttons to leave the popup area. Change language to French to see issue
[cause]        Regression
[solution]     Popup sizes amended so buttons scroll again if do not fit. Popup max width reduced to look more like Tizen apps.

Change-Id: Ibac5b243fd30a5c2f5bd58d0a4884676ae3aae5c
Signed-off-by: Adeel Kazmi <adeel.kazmi@samsung.com>
base/dali-toolkit/internal/controls/text-input/text-input-impl.cpp
base/dali-toolkit/internal/controls/text-input/text-input-popup-impl.cpp
base/dali-toolkit/internal/controls/text-input/text-input-popup-impl.h

index 2ec8170..b577b06 100644 (file)
@@ -794,9 +794,6 @@ void TextInput::SetBoundingRectangle( const Rect<float>& boundingRectangle )
                           originY + boundingRectangle.height );
 
   mBoundingRectangleWorldCoordinates = boundary;
-
-  // Set Boundary for Popup so it keeps the Pop-up within the area also.
-  mPopupPanel.SetPopupBoundary( boundingRectangle );
 }
 
 const Rect<float> TextInput::GetBoundingRectangle() const
index 9951f88..14f998f 100644 (file)
@@ -59,15 +59,16 @@ const std::string OPTION_ICON_SELECT_ALL( DALI_IMAGE_DIR "copy_paste_icon_select
 /**
  * Constant values for building the GUI
  */
-const Vector4 POPUP_BORDER( 14.0f, 14.0f, 14.0f, 14.0f );  ///< The margin of the popup.
+const Vector4 POPUP_MARGIN( 14.0f, 14.0f, 14.0f, 14.0f );  ///< Margin around the popup visible background Image.
+const Vector4 POPUP_BORDER( 2.0f, 2.0f, 2.0f, 2.0f );  ///< The Border of the popup.
 const Vector2 POPUP_MIN_SIZE( 0.0f, 126.0f );  ///< The minimum size of the popup.
 const Vector2 POPUP_MAX_SIZE( 720.0f, 126.0f );  ///< The maximum size of the popup.
 const float POPUP_TAIL_Y_OFFSET( -2.25f );  ///< The y offset of the tail.
 const Vector2 POPUP_TAIL_SIZE( 36.0f, 36.0f );  ///< The size of the tail.
 const Vector2 POPUP_DIVIDER_SIZE( 1.0f, 126.0f );  ///< The size of the divider.
 
-const Vector4 OPTION_MARGIN( 0.0f, 0.0f, 24.0f, 19.0f );  ///< The margin of the icon. the order is left, right, top and bottom
-const Vector2 OPTION_MAX_SIZE( 360.0f, 126.0f );  ///< The maximum size of the option.
+const Vector4 OPTION_PADDING( 16.0f, 16.0f, 24.0f, 19.0f );  ///< The padding within the option to position icon and text away from the border. The order is left, right, top and bottom
+const Vector2 OPTION_MAX_SIZE( 220.0f, 126.0f );  ///< The maximum size of the option.
 const Vector2 OPTION_MIN_SIZE( 128.0f, 126.0f );  ///< The minimum size of the option.
 const Vector2 OPTION_ICON_SIZE( 45.0f, 45.0f );  ///< The size of the icon.
 const Vector2 OPTION_TEXT_MIN_SIZE( 128.0f, 30.0f );  ///< The minimum size of the text.
@@ -111,10 +112,11 @@ const char* const TextInputPopup::OPTION_CLIPBOARD("option-clipboard");
 
 TextInputPopup::TextInputPopup()
 : mState(StateHidden),
-  mRoot(Layer::New()),
+  mRoot( Layer::New() ),
+  mButtons(),
   mVisiblePopUpSize(),
   mPopupTailXPosition( 0.0f ),
-  mContentSize( POPUP_MIN_SIZE ),
+  mContentSize(),
   mBackgroundColor( DEFAULT_POPUP_BACKGROUND ),
   mBackgroundPressedColor( DEFAULT_POPUP_BACKGROUND_PRESSED ),
   mLineColor( DEFAULT_POPUP_LINE_COLOR ),
@@ -156,6 +158,15 @@ void TextInputPopup::RemoveFromParent()
   }
 }
 
+void TextInputPopup::CreateLayer( const Vector2& size )
+{
+  mLayer = Layer::New();
+  mLayer.SetParentOrigin(ParentOrigin::CENTER);
+  mLayer.SetAnchorPoint(AnchorPoint::CENTER);
+  mLayer.SetSize( size ); // matches stencil size
+  mLayer.SetName("popup-mLayer");
+}
+
 void TextInputPopup::CreateStencil( const Vector2& size )
 {
   mStencil = CreateSolidColorActor( Color::BLUE );
@@ -169,21 +180,20 @@ void TextInputPopup::CreateStencil( const Vector2& size )
 
 void TextInputPopup::OnScrollStarted( const Vector3& position )
 {
-  mBackground.SetSensitive( false );
+  mButtons.SetSensitive( false );
 }
 
 void TextInputPopup::OnScrollCompleted( const Vector3& position )
 {
-  mBackground.SetSensitive( true );
+  mButtons.SetSensitive( true );
 }
 
 void TextInputPopup::CreateScrollView()
 {
   mScrollView = Toolkit::ScrollView::New();
   mScrollView.SetName("popup-scroll-view");
-  mScrollView.SetAnchorPoint( AnchorPoint::TOP_LEFT );
-  mScrollView.SetParentOrigin( ParentOrigin::TOP_LEFT );
-  mScrollView.SetPosition( POPUP_BORDER.x, POPUP_BORDER.y );
+  mScrollView.SetAnchorPoint( AnchorPoint::CENTER );
+  mScrollView.SetParentOrigin( ParentOrigin::CENTER );
   mScrollView.SetScrollingDirection( PanGestureDetector::DIRECTION_HORIZONTAL, Degree( 40.0f ) );
   mScrollView.SetAxisAutoLock( true );
   mScrollView.ScrollStartedSignal().Connect( this, &TextInputPopup::OnScrollStarted );
@@ -210,10 +220,9 @@ void TextInputPopup::Clear()
     UnparentAndReset( mTail );
     UnparentAndReset( mStencil );
     UnparentAndReset( mBackground );
+    UnparentAndReset( mButtons );
     UnparentAndReset( mScrollView );
-    mButtonContainer.clear();
     mDividerContainer.clear();
-    mRoot.RemoveConstraints();
     RemoveFromParent();
     mState = StateHidden;
   }
@@ -226,7 +235,7 @@ ImageActor TextInputPopup::CreateOptionIcon( Image iconImage, const Vector4& col
   icon.SetParentOrigin( ParentOrigin::TOP_CENTER );
   icon.SetAnchorPoint( AnchorPoint::TOP_CENTER );
   icon.SetColor( color );
-  icon.SetY( OPTION_MARGIN.z );
+  icon.SetY( OPTION_PADDING.z - POPUP_BORDER.y );
   return icon;
 }
 
@@ -243,11 +252,15 @@ Toolkit::TextView TextInputPopup::CreateOptionCaption( const std::string& captio
 
   Toolkit::TextView textView = Toolkit::TextView::New( styledCaption );
   textView.SetSizePolicy( Toolkit::Control::Fixed, Toolkit::Control::Fixed );
-  textView.SetWidthExceedPolicy( Toolkit::TextView::ShrinkToFit );
-  textView.SetHeightExceedPolicy( Toolkit::TextView::ShrinkToFit );
+  textView.SetWidthExceedPolicy( Toolkit::TextView::EllipsizeEnd );
+  textView.SetHeightExceedPolicy( Toolkit::TextView::EllipsizeEnd );
   textView.SetParentOrigin( ParentOrigin::BOTTOM_CENTER );
   textView.SetAnchorPoint( AnchorPoint::BOTTOM_CENTER );
-  textView.SetY( -OPTION_MARGIN.w );
+  textView.SetY( -OPTION_PADDING.w + POPUP_BORDER.w );
+
+  MarkupProcessor::StyledTextArray styledCaptionEllipsize;
+  MarkupProcessor::SetTextStyle( Text("..."), styledCaptionEllipsize, style );
+  textView.SetEllipsizeText( styledCaptionEllipsize );
 
   const float textWidth = textView.GetWidthForHeight( OPTION_TEXT_MIN_SIZE.y );
   textView.SetSize( textWidth, OPTION_TEXT_MIN_SIZE.y );
@@ -265,7 +278,6 @@ void TextInputPopup::CreateBackground()
     mBackground.SetAnchorPoint( AnchorPoint::CENTER );
     mBackground.SetParentOrigin( ParentOrigin::CENTER );
     mBackground.SetName( "text-input-popup-background" );
-    mBackground.ApplyConstraint( Constraint::New<Vector3>( Actor::SIZE, ParentSource( Actor::SIZE ), EqualToConstraint() ) );
     mBackground.SetColor( mBackgroundColor );
 
     Image bgEffectImg = Image::New( POPUP_BACKGROUND_EFFECT );
@@ -288,7 +300,6 @@ void TextInputPopup::CreateBackground()
     mBackgroundEffect.Add( mBackgroundLine );
 
     Hide(false);
-    GetRootActor().Add( mBackground );
   }
 }
 
@@ -330,7 +341,7 @@ ImageActor TextInputPopup::CreateDivider()
   ImageActor divider = Toolkit::CreateSolidColorActor( mLineColor );
   divider.SetParentOrigin( ParentOrigin::TOP_LEFT );
   divider.SetAnchorPoint( AnchorPoint::TOP_LEFT );
-  divider.SetSize( POPUP_DIVIDER_SIZE );
+  divider.SetSize( POPUP_DIVIDER_SIZE.width , mContentSize.height );
   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
@@ -435,13 +446,18 @@ void TextInputPopup::CreateOrderedListOfOptions()
       }
     }
 
-    if ( !match)
+    if ( !match )
     {
       mOrderListOfButtons.push_back( currentButton );
     }
   }
 }
 
+Vector2 TextInputPopup::GetConstrainedTextSize( const Vector2& textSize )
+{
+  return  Vector2( std::min( textSize.width, OPTION_MAX_SIZE.width - OPTION_PADDING.x - OPTION_PADDING.y ), textSize.height );
+}
+
 void TextInputPopup::AddOption(const std::string& name, const std::string& caption, const Image iconImage, bool finalOption)
 {
   // 1. Create container for text and icon when not pressed.
@@ -459,9 +475,16 @@ void TextInputPopup::AddOption(const std::string& name, const std::string& capti
 
   // 4. Calculate the size of option.
   const Vector2 textSize = Vector2( captionTextView.GetNaturalSize() );
-  const Vector2 optionSize( std::max( textSize.x, OPTION_ICON_SIZE.x ),
-                            OPTION_MARGIN.z + OPTION_ICON_SIZE.y + OPTION_GAP_ICON_TEXT + textSize.y + OPTION_MARGIN.w );
-  const Vector2 constrainedOptionSize = Min( Max( optionSize, OPTION_MIN_SIZE ), OPTION_MAX_SIZE );
+  captionTextView.SetSize( GetConstrainedTextSize( textSize ) );
+
+
+  const Vector2 optionSize( std::max( textSize.x, OPTION_ICON_SIZE.x ) +  OPTION_PADDING.x + OPTION_PADDING.z,
+                            OPTION_PADDING.z + OPTION_ICON_SIZE.y + OPTION_GAP_ICON_TEXT + textSize.y + OPTION_MAX_SIZE.y );
+
+
+  Vector2 constrainedOptionSize = Min( Max( optionSize, OPTION_MIN_SIZE ), OPTION_MAX_SIZE );
+
+  constrainedOptionSize.height = constrainedOptionSize.height - POPUP_BORDER.y - POPUP_BORDER.z;
 
   // 5. Create a option.
   Toolkit::PushButton option = Toolkit::PushButton::New();
@@ -473,24 +496,26 @@ void TextInputPopup::AddOption(const std::string& name, const std::string& capti
   option.SetName( name );
   option.SetAnimationTime( 0.0f );
   option.ClickedSignal().Connect( this, &TextInputPopup::OnButtonPressed );
-  mScrollView.Add( option );
+  mButtons.Add( option );
 
   // 6. Set the normal option image.
   option.SetButtonImage( optionContainer );
 
   // 7. Update the content size.
   mContentSize.x += constrainedOptionSize.x;
+  mContentSize.y = std::max ( constrainedOptionSize.y, mContentSize.y );
 
   // 8. Create the pressed container.
   Actor optionPressedContainer = Actor::New();
 
   // 9. Add option pressed background.
-  Vector2 optionPressedBackgroundSize( constrainedOptionSize.x - 1.0f, constrainedOptionSize.y - 2.0f );
+  Vector2 optionPressedBackgroundSize( constrainedOptionSize.x - POPUP_BORDER.x, mContentSize.y - POPUP_BORDER.y - POPUP_BORDER.w );
   ImageActor optionPressedBackground = CreatePressedBackground( optionPressedBackgroundSize );
   optionPressedContainer.Add( optionPressedBackground );
 
   // 10. Add pressed text
   Toolkit::TextView pressedCaptionTextView = CreateOptionCaption( caption, mTextPressedColor );
+  pressedCaptionTextView.SetSize( GetConstrainedTextSize( Vector2( pressedCaptionTextView.GetNaturalSize() ) ) );
   optionPressedBackground.Add( pressedCaptionTextView );
 
   // 11. Add pressed icon
@@ -504,7 +529,7 @@ void TextInputPopup::AddOption(const std::string& name, const std::string& capti
   if ( !finalOption )
   {
     ImageActor divider = CreateDivider();
-    mScrollView.Add( divider );
+    mButtons.Add( divider );
   }
 }
 
@@ -760,19 +785,26 @@ unsigned int TextInputPopup::GetButtonPriorityPosition( TextInputPopup::Buttons
 
 void TextInputPopup::AddPopupOptions()
 {
-  mContentSize = POPUP_MIN_SIZE;
+  mContentSize = Vector2( POPUP_MIN_SIZE.width, ( POPUP_BORDER.y + POPUP_BORDER.z ) );
 
   // 1. Create the background.
   CreateBackground();
-  mRoot.Add(mBackground);
 
   // 2. Create the tail.
   CreateTail();
-  mBackground.Add( mTail );
 
-  // 3. Create the scroll view.
+  // 3. Create the scroll view and Actor to hold buttons.
   CreateScrollView();
-  mBackground.Add( mScrollView );
+
+  // Clear previous buttons
+  if ( mButtons )
+  {
+    UnparentAndReset( mButtons );
+  }
+
+  mButtons = Actor::New();
+  mButtons.SetParentOrigin( ParentOrigin::CENTER );
+  mButtons.SetAnchorPoint( AnchorPoint::CENTER );
 
   // 4. Create the options and add into the scroll view.
   for( std::vector<ButtonRequirement>::const_iterator it = mOrderListOfButtons.begin(), endIt = mOrderListOfButtons.end(); ( it != endIt ); ++it )
@@ -785,51 +817,59 @@ void TextInputPopup::AddPopupOptions()
   }
 
   // 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);
+  const Vector2 popupSize = Vector2( std::min ( ( POPUP_BORDER.x + mContentSize.width + POPUP_BORDER.z ), POPUP_MAX_SIZE.width ) ,  POPUP_BORDER.y + mContentSize.height + POPUP_BORDER.w );
+
+  mVisiblePopUpSize = Vector3( popupSize.width - POPUP_BORDER.x - POPUP_BORDER.z , mContentSize.height, 1.0f);
+
+  mBackground.SetSize( popupSize.x + 28 - POPUP_BORDER.x - POPUP_BORDER.z, popupSize.y + 28 - POPUP_BORDER.y - POPUP_BORDER.w );
+  mButtons.SetSize( mVisiblePopUpSize.GetVectorXY() );
 
   // 6. Set the scroll view ruler.
-  UpdateScrollViewRulerAndSize( visibleContentSize );
+  UpdateScrollViewRulerAndSize( mVisiblePopUpSize.GetVectorXY() );
 
   // 7. Create stencil
-  const Vector2 stencilSize = Vector2( popupSize.x, popupSize.y + POPUP_TAIL_SIZE.x + POPUP_TAIL_Y_OFFSET );
+  const Vector2 stencilSize = Vector2( mVisiblePopUpSize.GetVectorXY() );
+
+  CreateLayer( stencilSize );
   CreateStencil( stencilSize );
-  mRoot.Add( mStencil );
+
+  mScrollView.Add ( mButtons );
+  mLayer.Add( mScrollView);
+  mLayer.Add( mStencil);
+  mRoot.Add( mTail );
+  mRoot.Add( mBackground );
+  mRoot.Add( mLayer );
 
   // 8. Set the root size.
   mRoot.SetSize( popupSize );   // Make Root Actor reflect the size of its content
 }
 
-void TextInputPopup::SetPopupBoundary( const Rect<float>& boundingRectangle )
-{
-  mBoundingRect =  boundingRectangle;
-}
-
 const Vector3& TextInputPopup::GetVisibileSize() const
 {
   return mVisiblePopUpSize;
 }
 
-
 void TextInputPopup::SetTailPosition( const Vector3& position, bool yAxisFlip )
 {
-  mPopupTailXPosition = position.x;
-  mTail.SetX( position.x );
+  mPopupTailXPosition = std::max(  position.x, POPUP_TAIL_SIZE.width*0.5f - mVisiblePopUpSize.width*0.5f + POPUP_BORDER.x );
+
+  std::min( mPopupTailXPosition, mVisiblePopUpSize.width*0.5f - POPUP_BORDER.x - POPUP_TAIL_SIZE.width*0.5f );
+
+  mTail.SetX( mPopupTailXPosition );
 
   if ( yAxisFlip )
   {
     Image tail = Image::New( POPUP_TAIL_TOP );
+    Image tailEffect = Image::New( POPUP_TAIL_TOP_EFFECT );
+    Image tailLine = Image::New( POPUP_TAIL_TOP_LINE );
+
     mTail.SetImage( tail );
+    mTailEffect.SetImage( tailEffect );
+    mTailLine.SetImage( tailLine );
+
     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 );
   }
 }
 
index 759c104..4348ca8 100644 (file)
@@ -162,6 +162,14 @@ public:
   void CreateOrderedListOfOptions();
 
   /**
+   * Get the TextSize after constrained by the Popup margins.
+   * @param[in] textSize Natural size of text
+   * @return Vector2 constrained text size.
+   *
+   */
+  Vector2 GetConstrainedTextSize( const Vector2& textSize );
+
+  /**
    * Adds a popup option.
    * @note Creates popup frame if not already created.
    * @param[in] name The unique name for this option.
@@ -186,14 +194,6 @@ public:
   void Show( Actor target, bool animate = true );
 
   /**
-   * Sets Alternative offset property.
-   * The alternative offset property is how much to move in the horizontal and vertical
-   * axes when the popup goes out of the screen on the left/right sides or top/bottom sides.
-   * @param[in] offset Vector holding the left/right offset (x) and top/bottom offset (y)
-   */
-  void SetAlternativeOffset(Vector2 offset);
-
-  /**
    * Returns the current state of the popup.
    * @return The state of the popup see enum State
    */
@@ -316,12 +316,6 @@ public:
   void AddPopupOptions();
 
   /**
-   * Set Boundary that Popup should stay within
-   * @param[in] boundingRectangle coordinates of bounding box from Top Left
-   */
-  void SetPopupBoundary( const Rect<float>& boundingRectangle );
-
-  /**
    * Get Visible size of the Popup, excludes content that needs scrolling
    * @return Vector3 size of Popup
    */
@@ -370,6 +364,12 @@ private:
   void ApplyTailConstraint();
 
   /**
+   * Create Layer to be used with stencil to allow scrolling of buttons which do not fit in visible popup
+   * @param[in] size of the layer.
+   */
+  void CreateLayer( const Vector2& size );
+
+  /**
    * Create a stencil to clip the scroll view content
    * @param[in] size of the stencil.
    */
@@ -421,7 +421,8 @@ private:
 private:
 
   State mState;                                       ///< Popup State.
-  Layer mRoot;                                       ///< The actor which all popup content is added to (i.e. panel and buttons)
+  Layer mRoot;                                        ///< The actor which all popup content is added to (i.e. panel and buttons)
+  Actor mButtons;                                     ///< Actor which holds all the buttons, sensitivity can be set on all buttons via this actor
   ImageActor mBackground;                             ///< The background popup panel
   ImageActor mBackgroundEffect;                       ///< The background effect
   ImageActor mBackgroundLine;                         ///< The background line
@@ -433,10 +434,10 @@ private:
   float mPopupTailXPosition;                          ///< X position of PopUp tail.
 
   Vector2 mContentSize;                               ///< Size of Content (i.e. Buttons)
-  ActorContainer mButtonContainer;                    ///< List of buttons added to popup.
   ActorContainer mDividerContainer;                   ///< List of dividers added to popup.
   Animation mAnimation;                               ///< Popup Hide/Show animation.
 
+  Layer mLayer;                                       ///< Layer to be used with Stencil
   Actor mStencil;                                     ///< Stencil to clip scrollview
   Toolkit::ScrollView mScrollView;                    ///< Scrollview to house the popup
 
@@ -450,8 +451,6 @@ private:
   Vector4 mTextColor;                    // Color of the popup text.
   Vector4 mTextPressedColor;             // Color of the popup text when pressed.
 
-  Rect<float> mBoundingRect; // Boundary that Popup must stay within.
-
   // Priority of Options/Buttons in the Cut and Paste pop-up, higher priority buttons are displayed first, left to right.
   std::size_t mSelectOptionPriority;  // Position of Select Button
   std::size_t mSelectAllOptionPriority; // Position of Select All button