673 consideration. (i.e. if sizepolicy does not have QSizePolicy::Grow, then |
699 consideration. (i.e. if sizepolicy does not have QSizePolicy::Grow, then |
674 maxSizeHint will be the preferredSize) |
700 maxSizeHint will be the preferredSize) |
675 Note that effectiveSizeHint does not take sizePolicy into consideration, |
701 Note that effectiveSizeHint does not take sizePolicy into consideration, |
676 (since it only evaluates the hints, as the name implies) |
702 (since it only evaluates the hints, as the name implies) |
677 */ |
703 */ |
678 QSizeF QGridLayoutItem::effectiveMaxSize() const |
704 QSizeF QGridLayoutItem::effectiveMaxSize(const QSizeF &constraint) const |
679 { |
705 { |
680 QSizeF size; |
706 QSizeF size = constraint; |
681 bool vGrow = (sizePolicy(Qt::Vertical) & QSizePolicy::GrowFlag) == QSizePolicy::GrowFlag; |
707 bool vGrow = (sizePolicy(Qt::Vertical) & QSizePolicy::GrowFlag) == QSizePolicy::GrowFlag; |
682 bool hGrow = (sizePolicy(Qt::Horizontal) & QSizePolicy::GrowFlag) == QSizePolicy::GrowFlag; |
708 bool hGrow = (sizePolicy(Qt::Horizontal) & QSizePolicy::GrowFlag) == QSizePolicy::GrowFlag; |
683 if (!vGrow || !hGrow) { |
709 if (!vGrow || !hGrow) { |
684 QSizeF pref = layoutItem()->effectiveSizeHint(Qt::PreferredSize); |
710 QSizeF pref = layoutItem()->effectiveSizeHint(Qt::PreferredSize, constraint); |
685 if (!vGrow) |
711 if (!vGrow) |
686 size.setHeight(pref.height()); |
712 size.setHeight(pref.height()); |
687 if (!hGrow) |
713 if (!hGrow) |
688 size.setWidth(pref.width()); |
714 size.setWidth(pref.width()); |
689 } |
715 } |
690 |
716 |
691 if (!size.isValid()) { |
717 if (!size.isValid()) { |
692 QSizeF maxSize = layoutItem()->effectiveSizeHint(Qt::MaximumSize); |
718 QSizeF maxSize = layoutItem()->effectiveSizeHint(Qt::MaximumSize, constraint); |
693 if (size.width() == -1) |
719 if (size.width() == -1) |
694 size.setWidth(maxSize.width()); |
720 size.setWidth(maxSize.width()); |
695 if (size.height() == -1) |
721 if (size.height() == -1) |
696 size.setHeight(maxSize.height()); |
722 size.setHeight(maxSize.height()); |
697 } |
723 } |
1530 q_totalBoxes[Ver] = q_rowData.totalBox(0, rowCount()); |
1564 q_totalBoxes[Ver] = q_rowData.totalBox(0, rowCount()); |
1531 |
1565 |
1532 q_cachedDataForStyleInfo = styleInfo; |
1566 q_cachedDataForStyleInfo = styleInfo; |
1533 } |
1567 } |
1534 |
1568 |
1535 void QGridLayoutEngine::ensureGeometries(const QLayoutStyleInfo &styleInfo, |
1569 QSizeF QGridLayoutEngine::dynamicallyConstrainedSizeHint(Qt::SizeHint which, |
1536 const QSizeF &size) const |
1570 const QSizeF &constraint) const |
1537 { |
1571 { |
1538 ensureColumnAndRowData(styleInfo); |
1572 Q_ASSERT(hasDynamicConstraint()); |
1539 if (q_cachedSize == size) |
1573 if (constraint.width() < 0 && constraint.height() < 0) { |
1540 return; |
1574 // Process the hfw / wfh items that we did not process in fillRowData() |
1541 |
1575 const Qt::Orientation constraintOrient = constraintOrientation(); |
|
1576 |
|
1577 QGridLayoutRowData rowData = constraintOrient == Qt::Vertical ? q_rowData : q_columnData; |
|
1578 for (int i = q_items.count() - 1; i >= 0; --i) { |
|
1579 QGridLayoutItem *item = q_items.at(i); |
|
1580 if (item->hasDynamicConstraint()) { |
|
1581 QGridLayoutBox box = item->box(constraintOrient); |
|
1582 QGridLayoutBox &rowBox = rowData.boxes[item->firstRow(constraintOrient)]; |
|
1583 rowBox.combine(box); |
|
1584 } |
|
1585 } |
|
1586 |
|
1587 QGridLayoutBox totalBoxes[2]; |
|
1588 if (constraintOrient == Qt::Vertical) { |
|
1589 totalBoxes[Hor] = q_columnData.totalBox(0, columnCount()); |
|
1590 totalBoxes[Ver] = rowData.totalBox(0, rowCount()); |
|
1591 } else { |
|
1592 totalBoxes[Hor] = rowData.totalBox(0, columnCount()); |
|
1593 totalBoxes[Ver] = q_rowData.totalBox(0, rowCount()); |
|
1594 } |
|
1595 return QSizeF(totalBoxes[Hor].q_sizes(which), totalBoxes[Ver].q_sizes(which)); |
|
1596 } |
|
1597 |
|
1598 |
|
1599 Q_ASSERT(constraint.width() >= 0 || constraint.height() >= 0); |
1542 q_xx.resize(columnCount()); |
1600 q_xx.resize(columnCount()); |
1543 q_yy.resize(rowCount()); |
1601 q_yy.resize(rowCount()); |
1544 q_widths.resize(columnCount()); |
1602 q_widths.resize(columnCount()); |
1545 q_heights.resize(rowCount()); |
1603 q_heights.resize(rowCount()); |
1546 q_descents.resize(rowCount()); |
1604 q_descents.resize(rowCount()); |
1547 q_columnData.calculateGeometries(0, columnCount(), size.width(), q_xx.data(), q_widths.data(), |
1605 |
1548 0, q_totalBoxes[Hor]); |
1606 |
1549 q_rowData.calculateGeometries(0, rowCount(), size.height(), q_yy.data(), q_heights.data(), |
1607 const Qt::Orientation orientation = constraintOrientation(); |
1550 q_descents.data(), q_totalBoxes[Ver]); |
1608 QGridLayoutRowData *colData; |
|
1609 QGridLayoutRowData constrainedRowData; |
|
1610 QGridLayoutBox *totalBox; |
|
1611 qreal *sizes; |
|
1612 qreal *pos; |
|
1613 qreal *descents; |
|
1614 qreal targetSize; |
|
1615 qreal cCount; |
|
1616 qreal rCount; |
|
1617 |
|
1618 if (orientation == Qt::Vertical) { |
|
1619 // height for width |
|
1620 colData = &q_columnData; |
|
1621 totalBox = &q_totalBoxes[Hor]; |
|
1622 sizes = q_widths.data(); |
|
1623 pos = q_xx.data(); |
|
1624 descents = 0; |
|
1625 targetSize = constraint.width(); |
|
1626 cCount = columnCount(); |
|
1627 rCount = rowCount(); |
|
1628 constrainedRowData = q_rowData; |
|
1629 } else { |
|
1630 // width for height |
|
1631 colData = &q_rowData; |
|
1632 totalBox = &q_totalBoxes[Ver]; |
|
1633 sizes = q_heights.data(); |
|
1634 pos = q_yy.data(); |
|
1635 descents = q_descents.data(); |
|
1636 targetSize = constraint.height(); |
|
1637 cCount = rowCount(); |
|
1638 rCount = columnCount(); |
|
1639 constrainedRowData = q_columnData; |
|
1640 } |
|
1641 colData->calculateGeometries(0, cCount, targetSize, pos, sizes, descents, *totalBox); |
|
1642 for (int i = q_items.count() - 1; i >= 0; --i) { |
|
1643 QGridLayoutItem *item = q_items.at(i); |
|
1644 |
|
1645 if (item->hasDynamicConstraint()) { |
|
1646 const qreal size = sizes[item->firstColumn(orientation)]; |
|
1647 QGridLayoutBox box = item->box(orientation, size); |
|
1648 QGridLayoutBox &rowBox = constrainedRowData.boxes[item->firstRow(orientation)]; |
|
1649 rowBox.combine(box); |
|
1650 } |
|
1651 } |
|
1652 const qreal newSize = constrainedRowData.totalBox(0, rCount).q_sizes(which); |
|
1653 |
|
1654 return (orientation == Qt::Vertical) ? QSizeF(targetSize, newSize) : QSizeF(newSize, targetSize); |
|
1655 } |
|
1656 |
|
1657 |
|
1658 /** |
|
1659 returns false if the layout has contradicting constraints (i.e. some items with a horizontal |
|
1660 constraint and other items with a vertical constraint) |
|
1661 */ |
|
1662 bool QGridLayoutEngine::ensureDynamicConstraint() const |
|
1663 { |
|
1664 if (q_cachedConstraintOrientation == UnknownConstraint) { |
|
1665 for (int i = q_items.count() - 1; i >= 0; --i) { |
|
1666 QGridLayoutItem *item = q_items.at(i); |
|
1667 if (item->hasDynamicConstraint()) { |
|
1668 Qt::Orientation itemConstraintOrientation = item->dynamicConstraintOrientation(); |
|
1669 if (q_cachedConstraintOrientation == UnknownConstraint) { |
|
1670 q_cachedConstraintOrientation = itemConstraintOrientation; |
|
1671 } else if (q_cachedConstraintOrientation != itemConstraintOrientation) { |
|
1672 q_cachedConstraintOrientation = UnfeasibleConstraint; |
|
1673 qWarning("QGridLayoutEngine: Unfeasible, cannot mix horizontal and" |
|
1674 " vertical constraint in the same layout"); |
|
1675 return false; |
|
1676 } |
|
1677 } |
|
1678 } |
|
1679 if (q_cachedConstraintOrientation == UnknownConstraint) |
|
1680 q_cachedConstraintOrientation = NoConstraint; |
|
1681 } |
|
1682 return true; |
|
1683 } |
|
1684 |
|
1685 bool QGridLayoutEngine::hasDynamicConstraint() const |
|
1686 { |
|
1687 if (!ensureDynamicConstraint()) |
|
1688 return false; |
|
1689 return q_cachedConstraintOrientation != NoConstraint; |
|
1690 } |
|
1691 |
|
1692 /* |
|
1693 * return value is only valid if hasConstraint() returns true |
|
1694 */ |
|
1695 Qt::Orientation QGridLayoutEngine::constraintOrientation() const |
|
1696 { |
|
1697 (void)ensureDynamicConstraint(); |
|
1698 return (Qt::Orientation)q_cachedConstraintOrientation; |
|
1699 } |
|
1700 |
|
1701 void QGridLayoutEngine::ensureGeometries(const QLayoutStyleInfo &styleInfo, |
|
1702 const QSizeF &size) const |
|
1703 { |
|
1704 ensureColumnAndRowData(styleInfo); |
|
1705 if (q_cachedSize == size) |
|
1706 return; |
|
1707 |
|
1708 q_xx.resize(columnCount()); |
|
1709 q_yy.resize(rowCount()); |
|
1710 q_widths.resize(columnCount()); |
|
1711 q_heights.resize(rowCount()); |
|
1712 q_descents.resize(rowCount()); |
|
1713 |
|
1714 |
|
1715 Qt::Orientation orientation = Qt::Vertical; |
|
1716 if (hasDynamicConstraint()) |
|
1717 orientation = constraintOrientation(); |
|
1718 |
|
1719 /* |
|
1720 In order to do hfw we need to first distribute the columns, then the rows. |
|
1721 In order to do wfh we need to first distribute the rows, then the columns. |
|
1722 |
|
1723 If there is no constraint, the order of distributing the rows or columns first is irrelevant. |
|
1724 We choose horizontal just to keep the same behaviour as before (however, there shouldn't |
|
1725 be any behaviour difference). |
|
1726 */ |
|
1727 |
|
1728 QGridLayoutRowData *colData; |
|
1729 QGridLayoutRowData rowData; |
|
1730 qreal *widths; |
|
1731 qreal *heights; |
|
1732 qreal *xx; |
|
1733 qreal *yy; |
|
1734 qreal *xdescents = 0; |
|
1735 qreal *ydescents = 0; |
|
1736 qreal cCount; |
|
1737 qreal rCount; |
|
1738 QSizeF oSize = size; |
|
1739 if (orientation == Qt::Vertical) { |
|
1740 // height for width |
|
1741 colData = &q_columnData; |
|
1742 rowData = q_rowData; |
|
1743 widths = q_widths.data(); |
|
1744 heights = q_heights.data(); |
|
1745 xx = q_xx.data(); |
|
1746 yy = q_yy.data(); |
|
1747 cCount = columnCount(); |
|
1748 rCount = rowCount(); |
|
1749 ydescents = q_descents.data(); |
|
1750 } else { |
|
1751 // width for height |
|
1752 colData = &q_rowData; |
|
1753 rowData = q_columnData; |
|
1754 widths = q_heights.data(); |
|
1755 heights = q_widths.data(); |
|
1756 xx = q_yy.data(); |
|
1757 yy = q_xx.data(); |
|
1758 cCount = rowCount(); |
|
1759 rCount = columnCount(); |
|
1760 xdescents = q_descents.data(); |
|
1761 oSize.transpose(); |
|
1762 } |
|
1763 |
|
1764 colData->calculateGeometries(0, cCount, oSize.width(), xx, widths, |
|
1765 xdescents, q_totalBoxes[orientation == Qt::Horizontal]); |
|
1766 for (int i = q_items.count() - 1; i >= 0; --i) { |
|
1767 QGridLayoutItem *item = q_items.at(i); |
|
1768 const int col = item->firstColumn(orientation); |
|
1769 const int row = item->firstRow(orientation); |
|
1770 if (item->hasDynamicConstraint()) { |
|
1771 const qreal sz = widths[col]; |
|
1772 QGridLayoutBox box = item->box(orientation, sz); |
|
1773 rowData.boxes[row].combine(box); |
|
1774 } |
|
1775 } |
|
1776 |
|
1777 QGridLayoutBox &totalBox = q_totalBoxes[orientation == Qt::Vertical]; |
|
1778 totalBox = rowData.totalBox(0, rCount); |
|
1779 rowData.calculateGeometries(0, rCount, oSize.height(), yy, heights, |
|
1780 ydescents, totalBox); |
1551 |
1781 |
1552 q_cachedSize = size; |
1782 q_cachedSize = size; |
1553 } |
1783 } |
1554 |
1784 |
1555 QT_END_NAMESPACE |
1785 QT_END_NAMESPACE |