src/hbcore/gui/hbscrollarea.cpp
changeset 2 06ff229162e9
parent 1 f7ac710697a9
child 3 11d3954df52a
equal deleted inserted replaced
1:f7ac710697a9 2:06ff229162e9
    35 #include <QGesture>
    35 #include <QGesture>
    36 
    36 
    37 #include <QDebug>
    37 #include <QDebug>
    38 
    38 
    39 /*!
    39 /*!
    40  *  @beta
    40  @beta
    41  *  @hbcore
    41  @hbcore
    42  *  \class HbScrollArea
    42  \class HbScrollArea
    43  *  \brief HbScrollArea provides a finger-touch enabled scrollable container class.  
    43  \brief HbScrollArea provides a finger-touch enabled scrollable container class.  
    44  *
    44  
    45  *  HbScrollArea handles the events need to scroll the contents placed inside it.  It also
    45  HbScrollArea handles the events need to scroll the contents placed inside it.  It also
    46  *  handles the display of scrollbar while scrolling is occurring.
    46  handles the display of scrollbar while scrolling is occurring.
    47  *
    47  
    48  *  HbScrollArea is used by constructing a QGraphicsWidget that contains the content to be
    48  HbScrollArea is used by constructing a QGraphicsWidget that contains the content to be
    49  *  displayed, then calling the setContentWidget() method.  The content widget must have its size
    49  displayed, then calling the setContentWidget() method.  The content widget must have its size
    50  *  set appropriately either by associating a layout with the widget or by explicitly setting
    50  set appropriately either by associating a layout with the widget or by explicitly setting
    51  *  the size (e.g. by calling QGraphicsWidget::setGeometry()).
    51  the size (e.g. by calling QGraphicsWidget::setGeometry()).
    52  * 
    52  
    53  *  The class can be used by itself to provide default scrolling behavior or can be
    53  The class can be used by itself to provide default scrolling behavior or can be
    54  *  subclassed to add touch feedback, selection feedback, etc.
    54  subclassed to add touch feedback, selection feedback, etc.
    55  *
    55  
    56  *  By default, the class provides dragging, flicking with animated follow-on, a
    56  By default, the class provides dragging, flicking with animated follow-on, a
    57  *  simple inertia algorithm for slowing the animated follow-on scrolling and
    57  simple inertia algorithm for slowing the animated follow-on scrolling and
    58  *  a bounce-back algorithm for animating the content back to its bounding
    58  a bounce-back algorithm for animating the content back to its bounding
    59  *  limits at the end of a drag or flick action.
    59  limits at the end of a drag or flick action.
    60  */
    60  */
    61 
    61 
    62 /*!
    62 /*!
    63  Here are the main properties of the class:
    63  Here are the main properties of the class:
    64 
    64 
   220 
   220 
   221     This is the default behavior.
   221     This is the default behavior.
   222 */
   222 */
   223 
   223 
   224 /*!
   224 /*!
   225  * Constructor
   225   Constructor
   226  *
   226  
   227  * \sa HbScrollArea::HbScrollArea
   227   \sa HbScrollArea::HbScrollArea
   228  */
   228  */
   229 HbScrollArea::HbScrollArea(QGraphicsItem* parent) : 
   229 HbScrollArea::HbScrollArea(QGraphicsItem* parent) : 
   230         HbWidget( *new HbScrollAreaPrivate, parent )
   230         HbWidget( *new HbScrollAreaPrivate, parent )
   231 {
   231 {
   232     Q_D( HbScrollArea );
   232     Q_D( HbScrollArea );
   241     d->q_ptr = this;
   241     d->q_ptr = this;
   242     d->init();
   242     d->init();
   243 }
   243 }
   244    
   244    
   245 /*!
   245 /*!
   246  * Destructor
   246  Destructor
   247  *
   247  
   248  * \sa HbScrollArea::~HbScrollArea
   248  \sa HbScrollArea::~HbScrollArea
   249  */
   249  */
   250 HbScrollArea::~HbScrollArea()
   250 HbScrollArea::~HbScrollArea()
   251 {
   251 {
   252     Q_D( HbScrollArea );
   252     Q_D( HbScrollArea );
   253     if (d && d->mContents) {
   253     if (d && d->mContents) {
   254         d->mContents->setParentLayoutItem(0);
   254         d->mContents->setParentLayoutItem(0);
   255     }
   255     }
   256 }
   256 }
   257 
   257 
   258 /*!
   258 /*!
   259  * Returns a pointer to the QGraphicsWidget,which is the content of scrollable area.
   259  Returns a pointer to the QGraphicsWidget,which is the content of scrollable area.
   260  *
   260  
   261  * \sa HbScrollArea::setContentWidget()
   261  \sa HbScrollArea::setContentWidget()
   262  */
   262  */
   263 QGraphicsWidget* HbScrollArea::contentWidget() const
   263 QGraphicsWidget* HbScrollArea::contentWidget() const
   264 {
   264 {
   265     Q_D( const HbScrollArea );
   265     Q_D( const HbScrollArea );
   266 
   266 
   267     return d->mContents;
   267     return d->mContents;
   268 }
   268 }
   269 
   269 
   270 /*!
   270 /*!
   271  * Assigns the QGraphicsWidget that is to be scrolled.  The HbScrollArea widget takes ownership of
   271  Assigns the QGraphicsWidget that is to be scrolled.  The HbScrollArea widget takes ownership of
   272  * the QGraphicsWidget.
   272  the QGraphicsWidget.
   273  *
   273  
   274  * \sa HbScrollArea::contentWidget()
   274  \sa HbScrollArea::contentWidget()
   275  */
   275  */
   276 void HbScrollArea::setContentWidget(QGraphicsWidget* contents)
   276 void HbScrollArea::setContentWidget(QGraphicsWidget* contents)
   277 {
   277 {
   278     Q_D( HbScrollArea );
   278     Q_D( HbScrollArea );
   279 
   279 
   327     d->hideChildComponents();
   327     d->hideChildComponents();
   328     return content;
   328     return content;
   329 }
   329 }
   330 
   330 
   331 /*!
   331 /*!
   332  * Returns the value of the clampingStyle property
   332  Returns the value of the clampingStyle property
   333  *
   333  
   334  * \sa HbScrollArea::setClampingStyle()
   334  \sa HbScrollArea::setClampingStyle()
   335  */
   335  */
   336 HbScrollArea::ClampingStyle HbScrollArea::clampingStyle() const
   336 HbScrollArea::ClampingStyle HbScrollArea::clampingStyle() const
   337 {
   337 {
   338     Q_D( const HbScrollArea );
   338     Q_D( const HbScrollArea );
   339 
   339 
   340     return d->mClampingStyle;
   340     return d->mClampingStyle;
   341 }
   341 }
   342 
   342 
   343 /*!
   343 /*!
   344  * Sets the clampingStyle property that controls how the scrolling is constrained
   344  Sets the clampingStyle property that controls how the scrolling is constrained
   345  * relative to the contents of the scrolling area.
   345  relative to the contents of the scrolling area.
   346  *
   346  
   347  * Possible values for the clamping style include:
   347  Possible values for the clamping style include:
   348  *
   348  
   349  *		StrictClamping - scrolling is limited to the bounding rectangle of the content item
   349  	StrictClamping - scrolling is limited to the bounding rectangle of the content item
   350  *		BounceBackClamping - scrolling can go beyond the bounding rectangle of the content item, but bounces back to the
   350  	BounceBackClamping - scrolling can go beyond the bounding rectangle of the content item, but bounces back to the
   351  *						limits of the bounding rectangle when released or when inertia scrolling stops
   351  					limits of the bounding rectangle when released or when inertia scrolling stops
   352  *		NoClamping - scrolling is completely unclamped (this is usually used when the subclass implements its own
   352  	NoClamping - scrolling is completely unclamped (this is usually used when the subclass implements its own
   353  *						custom clamping behavior)
   353  					custom clamping behavior)
   354  *
   354  
   355  * The default value is BounceBackClamping.
   355  The default value is BounceBackClamping.
   356  *
   356  
   357  * \sa HbScrollArea::clampingStyle()
   357  \sa HbScrollArea::clampingStyle()
   358  */
   358  */
   359 void HbScrollArea::setClampingStyle(ClampingStyle value)
   359 void HbScrollArea::setClampingStyle(ClampingStyle value)
   360 {
   360 {
   361     Q_D( HbScrollArea );
   361     Q_D( HbScrollArea );
   362 
   362 
   363     d->mClampingStyle = value;
   363     d->mClampingStyle = value;
   364 }
   364 }
   365 
   365 
   366 /*!
   366 /*!
   367  * Returns the value of the scrollingStyle property
   367   Returns the value of the scrollingStyle property
   368  *
   368  
   369  * \sa HbScrollArea::setScrollingStyle()
   369   \sa HbScrollArea::setScrollingStyle()
   370  */
   370  */
   371 HbScrollArea::ScrollingStyle HbScrollArea::scrollingStyle() const
   371 HbScrollArea::ScrollingStyle HbScrollArea::scrollingStyle() const
   372 {
   372 {
   373     Q_D( const HbScrollArea );
   373     Q_D( const HbScrollArea );
   374 
   374 
   380   provided by the widget
   380   provided by the widget
   381  
   381  
   382   Possible values for the clamping style include:
   382   Possible values for the clamping style include:
   383  
   383  
   384  		Pan - dragging motion pans the view with no follow-on scrolling animation
   384  		Pan - dragging motion pans the view with no follow-on scrolling animation
   385  \deprecated PanOrFlick
   385                \deprecated PanOrFlick
   386                     is deprecated.
   386                     is deprecated.
   387  		PanWithFollowOn - dragging motion pans the view, velocity at end of drag motion triggers follow-on animated scrolling
   387  		PanWithFollowOn - dragging motion pans the view, velocity at end of drag motion triggers follow-on animated scrolling
   388  
   388  
   389   The default value is PanWithFollowOn.
   389   The default value is PanWithFollowOn.
   390  
   390  
   401         d->mScrollingStyle = value;
   401         d->mScrollingStyle = value;
   402     }
   402     }
   403 }
   403 }
   404 
   404 
   405 /*!
   405 /*!
   406  * Returns the value of the scrollDirections property.
   406   Returns the value of the scrollDirections property.
   407  *
   407  
   408  * \sa HbScrollArea::setScrollDirections()
   408   \sa HbScrollArea::setScrollDirections()
   409  */
   409  */
   410 Qt::Orientations HbScrollArea::scrollDirections() const
   410 Qt::Orientations HbScrollArea::scrollDirections() const
   411 {
   411 {
   412     Q_D( const HbScrollArea );
   412     Q_D( const HbScrollArea );
   413 
   413 
   414     return d->mScrollDirections;
   414     return d->mScrollDirections;
   415 }
   415 }
   416 
   416 
   417 /*!
   417 /*!
   418  * Sets the value of the scrollDirections property.  This value is of
   418   Sets the value of the scrollDirections property.  This value is of
   419  * type Qt::Orientations and can set to either Qt::Horizontal to enable horizontal scrolling,
   419   type Qt::Orientations and can set to either Qt::Horizontal to enable horizontal scrolling,
   420  * Qt::Vertical to enable vertical scrolling or (Qt::Horizontal | Qt::Vertical) to enable
   420   Qt::Vertical to enable vertical scrolling or (Qt::Horizontal | Qt::Vertical) to enable
   421  * scrolling in both directions.
   421   scrolling in both directions.
   422  *
   422  
   423  * The default value is Qt::Vertical.
   423   The default value is Qt::Vertical.
   424  *
   424  
   425  * \sa HbScrollArea::scrollDirections()
   425   \sa HbScrollArea::scrollDirections()
   426  */
   426  */
   427 void HbScrollArea::setScrollDirections(Qt::Orientations value)
   427 void HbScrollArea::setScrollDirections(Qt::Orientations value)
   428 {
   428 {
   429     Q_D( HbScrollArea );
   429     Q_D( HbScrollArea );
   430 
   430 
   436         emit scrollDirectionsChanged( value );
   436         emit scrollDirectionsChanged( value );
   437     }
   437     }
   438 }
   438 }
   439 
   439 
   440 /*!
   440 /*!
   441  * Returns true if the inertia scrolling effect is enabled, false otherwise.
   441   Returns true if the inertia scrolling effect is enabled, false otherwise.
   442  *
   442  
   443  * \sa HbScrollArea::setFrictionEnabled()
   443   \sa HbScrollArea::setFrictionEnabled()
   444  */
   444  */
   445 bool HbScrollArea::frictionEnabled() const
   445 bool HbScrollArea::frictionEnabled() const
   446 {
   446 {
   447     Q_D( const HbScrollArea );
   447     Q_D( const HbScrollArea );
   448 
   448 
   449     return d->mFrictionEnabled;
   449     return d->mFrictionEnabled;
   450 }
   450 }
   451 
   451 
   452 /*!
   452 /*!
   453  * Enables/disables the inertia scrolling effect.
   453   Enables/disables the inertia scrolling effect.
   454  * By default, the inertia effect is enabled.
   454   By default, the inertia effect is enabled.
   455  *
   455  
   456  * \sa HbScrollArea::frictionEnabled()
   456   \sa HbScrollArea::frictionEnabled()
   457  */
   457  */
   458 void HbScrollArea::setFrictionEnabled(bool value)
   458 void HbScrollArea::setFrictionEnabled(bool value)
   459 {
   459 {
   460     Q_D( HbScrollArea );
   460     Q_D( HbScrollArea );
   461 
   461 
   493     HB_DEPRECATED("HbScrollArea::setLongPressEnabled(bool) is deprecated");
   493     HB_DEPRECATED("HbScrollArea::setLongPressEnabled(bool) is deprecated");
   494     Q_UNUSED(value);
   494     Q_UNUSED(value);
   495 }
   495 }
   496 
   496 
   497 /*
   497 /*
   498  * \reimp
   498   \reimp
   499  */
   499  */
   500 QVariant HbScrollArea::itemChange(GraphicsItemChange change, const QVariant &value)
   500 QVariant HbScrollArea::itemChange(GraphicsItemChange change, const QVariant &value)
   501 {
   501 {
   502     Q_D( HbScrollArea );
   502     Q_D( HbScrollArea );
   503 
   503 
   626 {
   626 {
   627     Q_UNUSED (event);
   627     Q_UNUSED (event);
   628 }
   628 }
   629 
   629 
   630 /*!
   630 /*!
   631  * Returns true if a scrolling action is in progress, false otherwise.
   631   Returns true if a scrolling action is in progress, false otherwise.
   632  */
   632  */
   633 bool HbScrollArea::isScrolling() const
   633 bool HbScrollArea::isScrolling() const
   634 {
   634 {
   635     Q_D( const HbScrollArea );
   635     Q_D( const HbScrollArea );
   636 
   636 
   637     return d->mIsScrolling;
   637     return d->mIsScrolling;
   638 }
   638 }
   639 
   639 
   640 /*!
   640 /*!
   641  * Returns true if the scrolling is due to dragging as opposed to follow-on scrolling
   641   Returns true if the scrolling is due to dragging as opposed to follow-on scrolling
   642  */
   642  */
   643 bool HbScrollArea::isDragging() const
   643 bool HbScrollArea::isDragging() const
   644 {
   644 {
   645     Q_D( const HbScrollArea );
   645     Q_D( const HbScrollArea );
   646 
   646 
   647     return (d->mIsScrolling && !d->mIsAnimating);
   647     return (d->mIsScrolling && !d->mIsAnimating);
   648 }
   648 }
   649 
   649 
   650 /*!
   650 /*!
   651  * Scrolls the view by the amount indicated by "delta".
   651   Scrolls the view by the amount indicated by "delta".
   652  *
   652  
   653  * The function returns TRUE if the view was able to scroll, FALSE otherwise.
   653   The function returns TRUE if the view was able to scroll, FALSE otherwise.
   654  *
   654  
   655  * The function is virtual so subclasses can override it to customize the behavior by, for example, 
   655   The function is virtual so subclasses can override it to customize the behavior by, for example, 
   656  * clamping the position so that at least one item in the view remains visible.
   656   clamping the position so that at least one item in the view remains visible.
   657  */
   657  */
   658 bool HbScrollArea::scrollByAmount(const QPointF& delta)
   658 bool HbScrollArea::scrollByAmount(const QPointF& delta)
   659 {
   659 {
   660     Q_D( HbScrollArea );
   660     Q_D( HbScrollArea );
   661 
   661 
   672     if(event) {
   672     if(event) {
   673         value = HbWidget::event(event);
   673         value = HbWidget::event(event);
   674         if(event->type() == QEvent::ApplicationLayoutDirectionChange
   674         if(event->type() == QEvent::ApplicationLayoutDirectionChange
   675                    || event->type() == QEvent::LayoutDirectionChange) {
   675                    || event->type() == QEvent::LayoutDirectionChange) {
   676              d->changeLayoutDirection(layoutDirection());
   676              d->changeLayoutDirection(layoutDirection());
   677         } else if (event->type() == QEvent::GraphicsSceneResize) {
   677         } else if (event->type() == HbEvent::ChildFocusOut) {
   678             if (isVisible() && d->mContents) {
       
   679                 if ( d->mIsAnimating ) {
       
   680                     d->stopAnimating();
       
   681                 }
       
   682                 d->adjustContent();
       
   683             }
       
   684         }  else if (event->type() == HbEvent::ChildFocusOut) {
       
   685             //qDebug() << "focusout";
   678             //qDebug() << "focusout";
   686             if ( !d->positionOutOfBounds() ) {
   679             if ( !d->positionOutOfBounds() ) {
   687                 d->stopAnimating();
   680                 d->stopAnimating();
   688             }
   681             }
   689         } else if( event->type() == QEvent::GestureOverride ) {
   682         } else if( event->type() == QEvent::GestureOverride ) {
   700 
   693 
   701                 QSizeF newSize = d->mContents->size();
   694                 QSizeF newSize = d->mContents->size();
   702                 QSizePolicy contentPolicy = d->mContents->sizePolicy();
   695                 QSizePolicy contentPolicy = d->mContents->sizePolicy();
   703 
   696 
   704                 if (d->mScrollDirections & Qt::Vertical) {
   697                 if (d->mScrollDirections & Qt::Vertical) {
   705                     if (contentPolicy.verticalPolicy() != QSizePolicy::Ignored) {
   698                     if ((contentPolicy.verticalPolicy() & QSizePolicy::ExpandFlag) &&
       
   699                         (d->mContents->preferredHeight() < size().height())) {
       
   700                         newSize.setHeight(size().height());
       
   701                     } else if (contentPolicy.verticalPolicy() != QSizePolicy::Ignored) {
   706                         newSize.setHeight(d->mContents->preferredHeight());
   702                         newSize.setHeight(d->mContents->preferredHeight());
   707                     }
   703                     }
   708                 } else {
   704                 } else {
   709                     newSize.setHeight(size().height());
   705                     newSize.setHeight(size().height());
   710                 }
   706                 }
   711 
   707 
   712                 if (d->mScrollDirections & Qt::Horizontal) {
   708                 if (d->mScrollDirections & Qt::Horizontal) {
   713                     if (contentPolicy.horizontalPolicy() != QSizePolicy::Ignored) {
   709                     if ((contentPolicy.horizontalPolicy() & QSizePolicy::ExpandFlag) &&
       
   710                         (d->mContents->preferredWidth() < size().width())) {
       
   711                         newSize.setWidth(size().width());
       
   712                     } else if (contentPolicy.horizontalPolicy() != QSizePolicy::Ignored) {
   714                         newSize.setWidth(d->mContents->preferredWidth());
   713                         newSize.setWidth(d->mContents->preferredWidth());
   715                     }
   714                     }
   716                 } else {
   715                 } else {
   717                     newSize.setWidth(size().width());
   716                     newSize.setWidth(size().width());
   718                 }
   717                 }
   719 
   718 
   720                 d->mContents->resize(newSize);
   719                 d->mContents->resize(newSize);
   721             }
   720             }
   722         } else if (event->type() == QEvent::GraphicsSceneResize) {
   721         } else if (event->type() == QEvent::GraphicsSceneResize) {
   723             if (d->mContents) {
   722             if (d->mContents) {
       
   723                 if ( d->mIsAnimating ) {
       
   724                     d->stopAnimating();
       
   725                 }
   724                 QSizeF newSize = d->mContents->size();
   726                 QSizeF newSize = d->mContents->size();
       
   727                 bool sizeChanged = false;
   725 
   728 
   726                 if (!(d->mScrollDirections & Qt::Vertical)) {
   729                 if (!(d->mScrollDirections & Qt::Vertical)) {
   727                     newSize.setHeight(size().height());
   730                     newSize.setHeight(size().height());
       
   731                     sizeChanged = true;
   728                 }
   732                 }
   729 
   733 
   730                 if (!(d->mScrollDirections & Qt::Horizontal)) {
   734                 if (!(d->mScrollDirections & Qt::Horizontal)) {
   731                     newSize.setWidth(size().width());
   735                     newSize.setWidth(size().width());
       
   736                     sizeChanged = true;
   732                 }
   737                 }
   733 
   738                 if (sizeChanged) {
   734                 d->mContents->resize(newSize);
   739                     d->mContents->resize(newSize);
       
   740                 } else {
       
   741                     d->adjustContent();
       
   742                 }
   735             }
   743             }
   736         }
   744         }
   737     }
   745     }
   738   return value;
   746   return value;
   739 }
   747 }
  1040 
  1048 
  1041     }
  1049     }
  1042 }
  1050 }
  1043 
  1051 
  1044 /*
  1052 /*
  1045  * \reimp
  1053   \reimp
  1046  */
  1054  */
  1047 void HbScrollArea::polish(HbStyleParameters& params)
  1055 void HbScrollArea::polish(HbStyleParameters& params)
  1048 {
  1056 {
  1049     Q_D(HbScrollArea);
  1057     Q_D(HbScrollArea);
  1050 
  1058