| 98 | } |
| 99 | |
| 100 | void TileLayout::doLayout(const QRect& rect) const |
| 101 | { |
| 102 | if (m_items.isEmpty()) |
| 103 | return; |
| 104 | |
| 105 | int left, top, right, bottom; |
| 106 | getContentsMargins(&left, &top, &right, &bottom); |
| 107 | QRect effectiveRect = rect.adjusted(left, top, -right, -bottom); |
| 108 | int x = effectiveRect.x(); |
| 109 | int y = effectiveRect.y(); |
| 110 | |
| 111 | QWidget* widget = m_items.first()->widget(); |
| 112 | int spaceX = horizontalSpacing(); |
| 113 | if (spaceX == -1) |
| 114 | spaceX = widget->style()->layoutSpacing(QSizePolicy::DefaultType, |
| 115 | QSizePolicy::DefaultType, |
| 116 | Qt::Horizontal); |
| 117 | int spaceY = verticalSpacing(); |
| 118 | if (spaceY == -1) |
| 119 | spaceY = widget->style()->layoutSpacing(QSizePolicy::DefaultType, |
| 120 | QSizePolicy::DefaultType, |
| 121 | Qt::Vertical); |
| 122 | |
| 123 | qreal layoutAr = qreal(effectiveRect.width()) / effectiveRect.height(); |
| 124 | int count = m_items.size(); |
| 125 | QSize sh = widget->sizeHint(); |
| 126 | qreal pixels = sh.width() * sh.height() * count; |
| 127 | |
| 128 | // Approximation based on the layout's aspect ratio |
| 129 | qreal totalWidth = qSqrt(pixels * layoutAr); |
| 130 | int cols = totalWidth / sh.width() + 0.5; |
| 131 | int rows = (count - 1) / cols + 1; |
| 132 | |
| 133 | // The approximation is far from perfect, so we perform some |
| 134 | // additional checks to make sure we have as few rows and |
| 135 | // columns as possible. |
| 136 | int smallest = qMin(cols, rows); |
| 137 | if (count <= smallest * smallest) |
| 138 | { |
| 139 | cols = smallest; |
| 140 | rows = smallest; |
| 141 | } |
| 142 | if (count <= cols * (rows - 1)) |
| 143 | rows--; |
| 144 | if (count <= (cols - 1) * rows) |
| 145 | cols--; |
| 146 | |
| 147 | // Often the column and row counts are backwards, meaning that |
| 148 | // the available space isn't being used efficiently. In that |
| 149 | // case we swap the values of 'cols' and 'rows'. |
| 150 | if (qAbs(cols - rows) >= 1) |
| 151 | { |
| 152 | qreal ar1 = qreal(cols * sh.width()) / (rows * sh.height()); |
| 153 | qreal ar2 = qreal(rows * sh.width()) / (cols * sh.height()); |
| 154 | if (qAbs(ar1 - layoutAr) > qAbs(ar2 - layoutAr)) |
| 155 | std::swap(cols, rows); |
| 156 | } |
| 157 | |