src/declarative/graphicsitems/qdeclarativepositioners.cpp
changeset 33 3e2da88830cd
parent 30 5dc02b23752f
child 37 758a864f9613
equal deleted inserted replaced
30:5dc02b23752f 33:3e2da88830cd
   217     positionedItems.copyAndClear(oldItems);
   217     positionedItems.copyAndClear(oldItems);
   218     for (int ii = 0; ii < children.count(); ++ii) {
   218     for (int ii = 0; ii < children.count(); ++ii) {
   219         QDeclarativeItem *child = qobject_cast<QDeclarativeItem *>(children.at(ii));
   219         QDeclarativeItem *child = qobject_cast<QDeclarativeItem *>(children.at(ii));
   220         if (!child)
   220         if (!child)
   221             continue;
   221             continue;
       
   222         QDeclarativeItemPrivate *childPrivate = static_cast<QDeclarativeItemPrivate*>(QGraphicsItemPrivate::get(child));
   222         PositionedItem *item = 0;
   223         PositionedItem *item = 0;
   223         PositionedItem posItem(child);
   224         PositionedItem posItem(child);
   224         int wIdx = oldItems.find(posItem);
   225         int wIdx = oldItems.find(posItem);
   225         if (wIdx < 0) {
   226         if (wIdx < 0) {
   226             d->watchChanges(child);
   227             d->watchChanges(child);
   227             positionedItems.append(posItem);
   228             positionedItems.append(posItem);
   228             item = &positionedItems[positionedItems.count()-1];
   229             item = &positionedItems[positionedItems.count()-1];
   229             item->isNew = true;
   230             item->isNew = true;
   230             if (child->opacity() <= 0.0 || !child->isVisible())
   231             if (child->opacity() <= 0.0 || childPrivate->explicitlyHidden)
   231                 item->isVisible = false;
   232                 item->isVisible = false;
   232         } else {
   233         } else {
   233             item = &oldItems[wIdx];
   234             item = &oldItems[wIdx];
   234             if (child->opacity() <= 0.0 || !child->isVisible()) {
   235             // Items are only omitted from positioning if they are explicitly hidden
       
   236             // i.e. their positioning is not affected if an ancestor is hidden.
       
   237             if (child->opacity() <= 0.0 || childPrivate->explicitlyHidden) {
   235                 item->isVisible = false;
   238                 item->isVisible = false;
   236             } else if (!item->isVisible) {
   239             } else if (!item->isVisible) {
   237                 item->isVisible = true;
   240                 item->isVisible = true;
   238                 item->isNew = true;
   241                 item->isNew = true;
   239             } else {
   242             } else {
   297     d->moveTransitionManager.transition(d->moveActions, d->moveTransition);
   300     d->moveTransitionManager.transition(d->moveActions, d->moveTransition);
   298     d->addActions.clear();
   301     d->addActions.clear();
   299     d->moveActions.clear();
   302     d->moveActions.clear();
   300 }
   303 }
   301 
   304 
       
   305 static inline bool isInvisible(QDeclarativeItem *child)
       
   306 {
       
   307     QDeclarativeItemPrivate *childPrivate = static_cast<QDeclarativeItemPrivate*>(QGraphicsItemPrivate::get(child));
       
   308     return child->opacity() == 0.0 || childPrivate->explicitlyHidden || !child->width() || !child->height();
       
   309 }
       
   310 
   302 /*!
   311 /*!
   303   \qmlclass Column QDeclarativeColumn
   312   \qmlclass Column QDeclarativeColumn
   304     \since 4.7
   313     \since 4.7
   305   \brief The Column item lines up its children vertically.
   314   \brief The Column item arranges its children vertically.
   306   \inherits Item
   315   \inherits Item
   307 
   316 
   308   The Column item positions its child items so that they are vertically
   317   The Column item positions its child items so that they are vertically
   309     aligned and not overlapping. Spacing between items can be added.
   318     aligned and not overlapping. Spacing between items can be added.
   310 
   319 
   344 
   353 
   345   Note that the positioner assumes that the x and y positions of its children
   354   Note that the positioner assumes that the x and y positions of its children
   346   will not change. If you manually change the x or y properties in script, bind
   355   will not change. If you manually change the x or y properties in script, bind
   347   the x or y properties, use anchors on a child of a positioner, or have the
   356   the x or y properties, use anchors on a child of a positioner, or have the
   348   height of a child depend on the position of a child, then the
   357   height of a child depend on the position of a child, then the
   349   positioner may exhibit strange behaviour.
   358   positioner may exhibit strange behaviour. If you need to perform any of these
   350 
   359   actions, consider positioning the items without the use of a Column.
       
   360 
       
   361   Items with a width or height of 0 will not be positioned.
       
   362 
       
   363   \sa Row, {declarative/positioners}{Positioners example}
   351 */
   364 */
   352 /*!
   365 /*!
   353     \qmlproperty Transition Column::add
   366     \qmlproperty Transition Column::add
   354 
   367 
   355     This property holds the transition to be applied when adding an
   368     This property holds the transition to be applied when adding an
   394   \qmlproperty int Column::spacing
   407   \qmlproperty int Column::spacing
   395 
   408 
   396   spacing is the amount in pixels left empty between each adjacent
   409   spacing is the amount in pixels left empty between each adjacent
   397   item, and defaults to 0.
   410   item, and defaults to 0.
   398 
   411 
   399   The below example places a Grid containing a red, a blue and a
   412   The below example places a \l Grid containing a red, a blue and a
   400   green rectangle on a gray background. The area the grid positioner
   413   green rectangle on a gray background. The area the grid positioner
   401   occupies is colored white. The top positioner has the default of no spacing,
   414   occupies is colored white. The top positioner has the default of no spacing,
   402   and the bottom positioner has its spacing set to 2.
   415   and the bottom positioner has its spacing set to 2.
   403 
   416 
   404   \image spacing_a.png
   417   \image spacing_a.png
   411     \brief The QDeclarativeColumn class lines up items vertically.
   424     \brief The QDeclarativeColumn class lines up items vertically.
   412 */
   425 */
   413 QDeclarativeColumn::QDeclarativeColumn(QDeclarativeItem *parent)
   426 QDeclarativeColumn::QDeclarativeColumn(QDeclarativeItem *parent)
   414 : QDeclarativeBasePositioner(Vertical, parent)
   427 : QDeclarativeBasePositioner(Vertical, parent)
   415 {
   428 {
   416 }
       
   417 
       
   418 static inline bool isInvisible(QDeclarativeItem *child)
       
   419 {
       
   420     return child->opacity() == 0.0 || !child->isVisible() || !child->width() || !child->height();
       
   421 }
   429 }
   422 
   430 
   423 void QDeclarativeColumn::doPositioning(QSizeF *contentSize)
   431 void QDeclarativeColumn::doPositioning(QSizeF *contentSize)
   424 {
   432 {
   425     int voffset = 0;
   433     int voffset = 0;
   466 }
   474 }
   467 
   475 
   468 /*!
   476 /*!
   469   \qmlclass Row QDeclarativeRow
   477   \qmlclass Row QDeclarativeRow
   470   \since 4.7
   478   \since 4.7
   471   \brief The Row item lines up its children horizontally.
   479   \brief The Row item arranges its children horizontally.
   472   \inherits Item
   480   \inherits Item
   473 
   481 
   474   The Row item positions its child items so that they are
   482   The Row item positions its child items so that they are
   475   horizontally aligned and not overlapping. Spacing can be added between the
   483   horizontally aligned and not overlapping. 
   476   items, and a margin around all items can also be added. It also provides for
   484 
   477   transitions to be set when items are added, moved, or removed in the
   485   Use \l spacing to set the spacing between items in a Row, and use the
   478   positioner. Adding and removing apply both to items which are deleted or have
   486   \l add and \l move properties to set the transitions that should be applied
   479   their position in the document changed so as to no longer be children of the
   487   when items are added to, removed from, or re-positioned within the Row.
   480   positioner, as well as to items which have their opacity set to or from zero
       
   481   so as to appear or disappear.
       
   482 
   488 
   483   The below example lays out differently shaped rectangles using a Row.
   489   The below example lays out differently shaped rectangles using a Row.
   484   \qml
   490   \qml
   485 Row {
   491 Row {
   486     spacing: 2
   492     spacing: 2
   493 
   499 
   494   Note that the positioner assumes that the x and y positions of its children
   500   Note that the positioner assumes that the x and y positions of its children
   495   will not change. If you manually change the x or y properties in script, bind
   501   will not change. If you manually change the x or y properties in script, bind
   496   the x or y properties, use anchors on a child of a positioner, or have the
   502   the x or y properties, use anchors on a child of a positioner, or have the
   497   width of a child depend on the position of a child, then the
   503   width of a child depend on the position of a child, then the
   498   positioner may exhibit strange behaviour.
   504   positioner may exhibit strange behaviour. If you need to perform any of these
   499 
   505   actions, consider positioning the items without the use of a Row.
       
   506 
       
   507   Items with a width or height of 0 will not be positioned.
       
   508 
       
   509   \sa Column, {declarative/positioners}{Positioners example}
   500 */
   510 */
   501 /*!
   511 /*!
   502     \qmlproperty Transition Row::add
   512     \qmlproperty Transition Row::add
   503     This property holds the transition to apply when adding an item to the positioner.
   513     This property holds the transition to apply when adding an item to the positioner.
   504     The transition will only be applied to the added item(s).
   514     The transition will only be applied to the added item(s).
   505     Positioner transitions will only affect the position (x,y) of items.
   515     Positioner transitions will only affect the position (x,y) of items.
   506 
   516 
   507     Added can mean that either the object has been created or
   517     An object is considered to be added to the positioner if it has been
   508     reparented, and thus is now a child or the positioner, or that the
   518     created or reparented and thus is now a child or the positioner, or if the
   509     object has had its opacity increased from zero, and thus is now
   519     object has had its opacity increased from zero, and thus is now
   510     visible.
   520     visible.
   511 
       
   512 
       
   513 */
   521 */
   514 /*!
   522 /*!
   515     \qmlproperty Transition Row::move
   523     \qmlproperty Transition Row::move
   516 
   524 
   517     This property holds the transition to apply when moving an item
   525     This property holds the transition to apply when moving an item
   538   \qmlproperty int Row::spacing
   546   \qmlproperty int Row::spacing
   539 
   547 
   540   spacing is the amount in pixels left empty between each adjacent
   548   spacing is the amount in pixels left empty between each adjacent
   541   item, and defaults to 0.
   549   item, and defaults to 0.
   542 
   550 
   543   The below example places a Grid containing a red, a blue and a
   551   The below example places a \l Grid containing a red, a blue and a
   544   green rectangle on a gray background. The area the grid positioner
   552   green rectangle on a gray background. The area the grid positioner
   545   occupies is colored white. The top positioner has the default of no spacing,
   553   occupies is colored white. The top positioner has the default of no spacing,
   546   and the bottom positioner has its spacing set to 2.
   554   and the bottom positioner has its spacing set to 2.
   547 
   555 
   548   \image spacing_a.png
   556   \image spacing_a.png
   608   \since 4.7
   616   \since 4.7
   609   \brief The Grid item positions its children in a grid.
   617   \brief The Grid item positions its children in a grid.
   610   \inherits Item
   618   \inherits Item
   611 
   619 
   612   The Grid item positions its child items so that they are
   620   The Grid item positions its child items so that they are
   613   aligned in a grid and are not overlapping. Spacing can be added
   621   aligned in a grid and are not overlapping. 
   614   between the items. It also provides for transitions to be set when items are
   622   
       
   623   Spacing can be added
       
   624   between child items. It also provides for transitions to be set when items are
   615   added, moved, or removed in the positioner. Adding and removing apply
   625   added, moved, or removed in the positioner. Adding and removing apply
   616   both to items which are deleted or have their position in the
   626   both to items which are deleted or have their position in the
   617   document changed so as to no longer be children of the positioner, as
   627   document changed so as to no longer be children of the positioner, as
   618   well as to items which have their opacity set to or from zero so
   628   well as to items which have their opacity set to or from zero so
   619   as to appear or disappear.
   629   as to appear or disappear.
   620 
   630 
   621   The Grid defaults to using four columns, and as many rows as
   631   A Grid defaults to four columns, and as many rows as
   622   are necessary to fit all the child items. The number of rows
   632   are necessary to fit all child items. The number of rows
   623   and/or the number of columns can be constrained by setting the rows
   633   and/or the number of columns can be constrained by setting the \l rows
   624   or columns properties. The grid positioner calculates a grid with
   634   or \l columns properties. The grid positioner calculates a grid with
   625   rectangular cells of sufficient size to hold all items, and then
   635   rectangular cells of sufficient size to hold all items, and then
   626   places the items in the cells, going across then down, and
   636   places the items in the cells, going across then down, and
   627   positioning each item at the (0,0) corner of the cell. The below
   637   positioning each item at the (0,0) corner of the cell. The below
   628   example demonstrates this.
   638   example demonstrates this.
   629 
   639 
   646 
   656 
   647   Note that the positioner assumes that the x and y positions of its children
   657   Note that the positioner assumes that the x and y positions of its children
   648   will not change. If you manually change the x or y properties in script, bind
   658   will not change. If you manually change the x or y properties in script, bind
   649   the x or y properties, use anchors on a child of a positioner, or have the
   659   the x or y properties, use anchors on a child of a positioner, or have the
   650   width or height of a child depend on the position of a child, then the
   660   width or height of a child depend on the position of a child, then the
   651   positioner may exhibit strange behaviour.
   661   positioner may exhibit strange behaviour. If you need to perform any of these
       
   662   actions, consider positioning the items without the use of a Grid.
       
   663 
       
   664   Items with a width or height of 0 will not be positioned.
       
   665 
       
   666   \sa Flow, {declarative/positioners}{Positioners example}
   652 */
   667 */
   653 /*!
   668 /*!
   654     \qmlproperty Transition Grid::add
   669     \qmlproperty Transition Grid::add
   655     This property holds the transition to apply when adding an item to the positioner.
   670     This property holds the transition to apply when adding an item to the positioner.
   656     The transition is only applied to the added item(s).
   671     The transition is only applied to the added item(s).
   657     Positioner transitions will only affect the position (x,y) of items,
   672     Positioner transitions will only affect the position (x,y) of items,
   658     as that is all the positioners affect. To animate other property change
   673     as that is all the positioners affect. To animate other property change
   659     you will have to do so based on how you have changed those properties.
   674     you will have to do so based on how you have changed those properties.
   660 
   675 
   661     Added can mean that either the object has been created or
   676     An object is considered to be added to the positioner if it has been
   662     reparented, and thus is now a child or the positioner, or that the
   677     created or reparented and thus is now a child or the positioner, or if the
   663     object has had its opacity increased from zero, and thus is now
   678     object has had its opacity increased from zero, and thus is now
   664     visible.
   679     visible.
   665 
       
   666 
       
   667 */
   680 */
   668 /*!
   681 /*!
   669     \qmlproperty Transition Grid::move
   682     \qmlproperty Transition Grid::move
   670     This property holds the transition to apply when moving an item within the positioner.
   683     This property holds the transition to apply when moving an item within the positioner.
   671     Positioner transitions will only affect the position (x,y) of items.
   684     Positioner transitions will only affect the position (x,y) of items.
   712 
   725 
   713 /*!
   726 /*!
   714     \qmlproperty int Grid::columns
   727     \qmlproperty int Grid::columns
   715     This property holds the number of columns in the grid.
   728     This property holds the number of columns in the grid.
   716 
   729 
   717     When the columns property is set the Grid will always have
   730     If the grid does not have enough items to fill the specified
   718     that many columns. Note that if you do not have enough items to
   731     number of columns, some columns will be of zero width.
   719     fill this many columns some columns will be of zero width.
       
   720 */
   732 */
   721 
   733 
   722 /*!
   734 /*!
   723     \qmlproperty int Grid::rows
   735     \qmlproperty int Grid::rows
   724     This property holds the number of rows in the grid.
   736     This property holds the number of rows in the grid.
   725 
   737 
   726     When the rows property is set the Grid will always have that
   738     If the grid does not have enough items to fill the specified
   727     many rows. Note that if you do not have enough items to fill this
   739     number of rows, some rows will be of zero width.
   728     many rows some rows will be of zero width.
       
   729 */
   740 */
   730 
   741 
   731 void QDeclarativeGrid::setColumns(const int columns)
   742 void QDeclarativeGrid::setColumns(const int columns)
   732 {
   743 {
   733     if (columns == m_columns)
   744     if (columns == m_columns)
   748 
   759 
   749 /*!
   760 /*!
   750     \qmlproperty enumeration Grid::flow
   761     \qmlproperty enumeration Grid::flow
   751     This property holds the flow of the layout.
   762     This property holds the flow of the layout.
   752 
   763 
   753     Possible values are \c Grid.LeftToRight (default) and \c Grid.TopToBottom.
   764     Possible values are:
   754 
   765 
   755     If \a flow is \c Grid.LeftToRight, the items are positioned next to
   766     \list
   756     to each other from left to right, then wrapped to the next line.
   767     \o Grid.LeftToRight (default) - Items are positioned next to
   757     If \a flow is \c Grid.TopToBottom, the items are positioned next to each
   768        to each other from left to right, then wrapped to the next line.
   758     other from top to bottom, then wrapped to the next column.
   769     \o Grid.TopToBottom - Items are positioned next to each
       
   770        other from top to bottom, then wrapped to the next column.
       
   771     \endlist
   759 */
   772 */
   760 QDeclarativeGrid::Flow QDeclarativeGrid::flow() const
   773 QDeclarativeGrid::Flow QDeclarativeGrid::flow() const
   761 {
   774 {
   762     return m_flow;
   775     return m_flow;
   763 }
   776 }
   891 }
   904 }
   892 
   905 
   893 /*!
   906 /*!
   894   \qmlclass Flow QDeclarativeFlow
   907   \qmlclass Flow QDeclarativeFlow
   895   \since 4.7
   908   \since 4.7
   896   \brief The Flow item lines up its children side by side, wrapping as necessary.
   909   \brief The Flow item arranges its children side by side, wrapping as necessary.
   897   \inherits Item
   910   \inherits Item
       
   911 
       
   912   The Flow item positions its child items so that they are side by side and are
       
   913   not overlapping.
   898 
   914 
   899   Note that the positioner assumes that the x and y positions of its children
   915   Note that the positioner assumes that the x and y positions of its children
   900   will not change. If you manually change the x or y properties in script, bind
   916   will not change. If you manually change the x or y properties in script, bind
   901   the x or y properties, use anchors on a child of a positioner, or have the
   917   the x or y properties, use anchors on a child of a positioner, or have the
   902   width or height of a child depend on the position of a child, then the
   918   width or height of a child depend on the position of a child, then the
   903   positioner may exhibit strange behaviour.
   919   positioner may exhibit strange behaviour.  If you need to perform any of these
   904 
   920   actions, consider positioning the items without the use of a Flow.
       
   921 
       
   922   Items with a width or height of 0 will not be positioned.
       
   923 
       
   924     \sa Grid, {declarative/positioners}{Positioners example}
   905 */
   925 */
   906 /*!
   926 /*!
   907     \qmlproperty Transition Flow::add
   927     \qmlproperty Transition Flow::add
   908     This property holds the transition to apply when adding an item to the positioner.
   928     This property holds the transition to apply when adding an item to the positioner.
   909     The transition will only be applied to the added item(s).
   929     The transition will only be applied to the added item(s).
   910     Positioner transitions will only affect the position (x,y) of items.
   930     Positioner transitions will only affect the position (x,y) of items.
   911 
   931 
   912     Added can mean that either the object has been created or reparented, and thus is now a child or the positioner, or that the object has had its opacity increased from zero, and thus is now visible.
   932     An object is considered to be added to the positioner if it has been
   913 
   933     created or reparented and thus is now a child or the positioner, or if the
   914 
   934     object has had its opacity increased from zero, and thus is now
       
   935     visible.
   915 */
   936 */
   916 /*!
   937 /*!
   917     \qmlproperty Transition Flow::move
   938     \qmlproperty Transition Flow::move
   918     This property holds the transition to apply when moving an item within the positioner.
   939     This property holds the transition to apply when moving an item within the positioner.
   919     Positioner transitions will only affect the position (x,y) of items.
   940     Positioner transitions will only affect the position (x,y) of items.
   963 
   984 
   964 /*!
   985 /*!
   965     \qmlproperty enumeration Flow::flow
   986     \qmlproperty enumeration Flow::flow
   966     This property holds the flow of the layout.
   987     This property holds the flow of the layout.
   967 
   988 
   968     Possible values are \c Flow.LeftToRight (default) and \c Flow.TopToBottom.
   989     Possible values are:
   969 
   990 
   970     If \a flow is \c Flow.LeftToRight, the items are positioned next to
   991     \list
       
   992     \o Flow.LeftToRight (default) - Items are positioned next to
   971     to each other from left to right until the width of the Flow
   993     to each other from left to right until the width of the Flow
   972     is exceeded, then wrapped to the next line.
   994     is exceeded, then wrapped to the next line.
   973     If \a flow is \c Flow.TopToBottom, the items are positioned next to each
   995     \o Flow.TopToBottom - Items are positioned next to each
   974     other from top to bottom until the height of the Flow is exceeded,
   996     other from top to bottom until the height of the Flow is exceeded,
   975     then wrapped to the next column.
   997     then wrapped to the next column.
       
   998     \endlist
   976 */
   999 */
   977 QDeclarativeFlow::Flow QDeclarativeFlow::flow() const
  1000 QDeclarativeFlow::Flow QDeclarativeFlow::flow() const
   978 {
  1001 {
   979     Q_D(const QDeclarativeFlow);
  1002     Q_D(const QDeclarativeFlow);
   980     return d->flow;
  1003     return d->flow;
  1002         const PositionedItem &child = positionedItems.at(i);
  1025         const PositionedItem &child = positionedItems.at(i);
  1003         if (!child.item || isInvisible(child.item))
  1026         if (!child.item || isInvisible(child.item))
  1004             continue;
  1027             continue;
  1005 
  1028 
  1006         if (d->flow == LeftToRight)  {
  1029         if (d->flow == LeftToRight)  {
  1007             if (hoffset && hoffset + child.item->width() > width()) {
  1030             if (widthValid() && hoffset && hoffset + child.item->width() > width()) {
  1008                 hoffset = 0;
  1031                 hoffset = 0;
  1009                 voffset += linemax + spacing();
  1032                 voffset += linemax + spacing();
  1010                 linemax = 0;
  1033                 linemax = 0;
  1011             }
  1034             }
  1012         } else {
  1035         } else {
  1013             if (voffset && voffset + child.item->height() > height()) {
  1036             if (heightValid() && voffset && voffset + child.item->height() > height()) {
  1014                 voffset = 0;
  1037                 voffset = 0;
  1015                 hoffset += linemax + spacing();
  1038                 hoffset += linemax + spacing();
  1016                 linemax = 0;
  1039                 linemax = 0;
  1017             }
  1040             }
  1018         }
  1041         }