123 gridItem->updateChildItems(); |
115 gridItem->updateChildItems(); |
124 } |
116 } |
125 } |
117 } |
126 } |
118 } |
127 |
119 |
|
120 qreal HbGridViewPrivate::calculateScrollBarPos() const |
|
121 { |
|
122 // calculate thumb size and position |
|
123 Q_Q(const HbGridView); |
|
124 |
|
125 qreal thumbPos = 0.0; |
|
126 int columnCount = getScrollDirectionColumnCount(); |
|
127 int rowCount = getScrollDirectionRowCount(); |
|
128 qreal containerPos = getScrollDirectionContainerPos(); |
|
129 qreal itemSize = getScrollDirectionItemSize(); |
|
130 |
|
131 // add coulmnCount-1 to indexCount to get remainder included in result (rounding up) |
|
132 int modelRowCount = (mModelIterator->indexCount() + columnCount - 1) / columnCount; |
|
133 modelRowCount -= rowCount; |
|
134 QModelIndex firstItem = mContainer->items().first()->modelIndex(); |
|
135 qreal firstVisibleRow = (qreal)(q->modelIterator()->indexPosition(firstItem)) / columnCount; |
|
136 firstVisibleRow += -containerPos / itemSize; // applying container pos to get trully visible row |
|
137 thumbPos = firstVisibleRow / (qreal)modelRowCount; |
|
138 thumbPos = qBound((qreal)0.0, thumbPos, (qreal)1.0); |
|
139 |
|
140 return thumbPos; |
|
141 } |
|
142 |
|
143 qreal HbGridViewPrivate::calculateScrollBarThumbSize() const |
|
144 { |
|
145 // calculate thumb size and position |
|
146 qreal thumbSize = 0.0; |
|
147 int columnCount = getScrollDirectionColumnCount(); |
|
148 int rowCount = getScrollDirectionRowCount(); |
|
149 |
|
150 // add coulmnCount-1 to indexCount to get remainder included in result (rounding up) |
|
151 int modelRowCount = (mModelIterator->indexCount() + columnCount - 1) / columnCount; |
|
152 thumbSize = (qreal)rowCount / (qreal)modelRowCount; |
|
153 thumbSize = qBound((qreal)0.0, thumbSize, (qreal)1.0); |
|
154 |
|
155 return thumbSize; |
|
156 } |
|
157 |
128 /*! |
158 /*! |
129 Overwrites the default scroll area scrollbar updating algorithm when |
159 Overwrites the default scroll area scrollbar updating algorithm when |
130 recycling is used. On recycling the scrollbar position & size is calculated |
160 recycling is used. On recycling the scrollbar position & size is calculated |
131 using rows and their pixel size is not used. |
161 using rows and their pixel size is not used. |
132 */ |
162 */ |
133 void HbGridViewPrivate::updateScrollBar(Qt::Orientation orientation) |
163 void HbGridViewPrivate::updateScrollBar(Qt::Orientation orientation) |
134 { |
164 { |
135 if (!mContainer->itemRecycling() |
165 if (!handleScrollBar(orientation)) { |
136 || mContainer->itemPrototypes().count() != 1 |
|
137 || mContainer->items().count() == 0) { |
|
138 HbScrollAreaPrivate::updateScrollBar(orientation); |
166 HbScrollAreaPrivate::updateScrollBar(orientation); |
139 } else { |
167 } else { |
140 if (mContainer->layout() && !mContainer->layout()->isActivated()) { |
168 if (mContainer->layout() && !mContainer->layout()->isActivated()) { |
141 mContainer->layout()->activate(); |
169 mContainer->layout()->activate(); |
142 } |
170 } |
143 if (orientation == Qt::Vertical) { |
171 |
144 updateVerticalScrollBar(); |
172 qreal thumbPos = calculateScrollBarPos(); |
145 } else { |
173 HbScrollBar *scrollBar = getScrollDirectionScrollBar(); |
146 updateHorizontalScrollBar(); |
174 scrollBar->setValue(thumbPos); |
147 } |
175 } |
148 } |
176 } |
149 } |
177 |
150 |
178 /*! |
151 void HbGridViewPrivate::updateHorizontalScrollBar() |
179 \reimp |
152 { |
180 */ |
153 Q_Q(const HbGridView); |
|
154 |
|
155 HbAbstractViewItem *firstItem = mContainer->items().first(); |
|
156 qreal uniformItemWidth = firstItem->size().width(); |
|
157 |
|
158 int rowCount = q->rowCount(); |
|
159 int indexCount = mModelIterator->indexCount(); |
|
160 |
|
161 int virtualColumnCount = indexCount / rowCount; |
|
162 int remainder = indexCount % rowCount; |
|
163 if (remainder != 0) { |
|
164 virtualColumnCount++; |
|
165 } |
|
166 |
|
167 int firstItemModelRowNumber = mModelIterator->indexPosition(firstItem->modelIndex()); |
|
168 int firstBufferItemRowNumber = firstItemModelRowNumber / rowCount; |
|
169 |
|
170 QRectF itemRect = itemBoundingRect(firstItem); |
|
171 qreal realLeftBoundary = itemRect.left(); |
|
172 qreal virtualLeftBoundary = realLeftBoundary - (firstBufferItemRowNumber*uniformItemWidth); |
|
173 |
|
174 qreal containerVirtualWidth = uniformItemWidth * virtualColumnCount; |
|
175 qreal thumbPosition(0); |
|
176 |
|
177 // The scrollbar "thumb" position is the current position of the contents widget divided |
|
178 // by the difference between the width of the contents widget and the width of the scroll area. |
|
179 // This formula assumes that the "thumb" of the the scroll bar is sized proportionately to |
|
180 // the width of the contents widget. |
|
181 qreal hiddenVirtualWidth = containerVirtualWidth - q->boundingRect().width(); |
|
182 if (hiddenVirtualWidth != 0) { |
|
183 thumbPosition = (-virtualLeftBoundary) / hiddenVirtualWidth; |
|
184 } |
|
185 |
|
186 if (thumbPosition < 0.0) |
|
187 thumbPosition = 0.0; |
|
188 else if (thumbPosition > 1.0) |
|
189 thumbPosition = 1.0; |
|
190 |
|
191 if (mHorizontalScrollBar) { |
|
192 if (containerVirtualWidth!=0) { |
|
193 mHorizontalScrollBar->setPageSize(qBound ( (qreal)0.0, |
|
194 q->boundingRect().width() / containerVirtualWidth, |
|
195 (qreal)1.0)); |
|
196 } |
|
197 mHorizontalScrollBar->setValue(thumbPosition); |
|
198 } |
|
199 } |
|
200 |
|
201 void HbGridViewPrivate::updateVerticalScrollBar() |
|
202 { |
|
203 Q_Q(const HbGridView); |
|
204 |
|
205 HbAbstractViewItem *firstItem = mContainer->items().first(); |
|
206 qreal uniformItemHeight = firstItem->size().height(); |
|
207 |
|
208 int columnCount = q->columnCount(); |
|
209 int indexCount = mModelIterator->indexCount(); |
|
210 |
|
211 int virtualRowCount = indexCount / columnCount; |
|
212 int remainder = indexCount % columnCount; |
|
213 if (remainder != 0) { //even one item requires the whole row |
|
214 virtualRowCount++; |
|
215 } |
|
216 |
|
217 int firstItemModelRowNumber = mModelIterator->indexPosition(firstItem->modelIndex()); |
|
218 int firstBufferItemRowNumber = firstItemModelRowNumber / columnCount; |
|
219 |
|
220 QRectF itemRect = itemBoundingRect(firstItem); |
|
221 qreal realTopBoundary = itemRect.top(); |
|
222 qreal virtualTopBoundary = realTopBoundary - (firstBufferItemRowNumber*uniformItemHeight); |
|
223 |
|
224 qreal containerVirtualHeight = uniformItemHeight * virtualRowCount; |
|
225 qreal thumbPosition = 0; |
|
226 |
|
227 // The scrollbar "thumb" position is the current position of the contents widget divided |
|
228 // by the difference between the height of the contents widget and the height of the scroll area. |
|
229 // This formula assumes that the "thumb" of the the scroll bar is sized proportionately to |
|
230 // the height of the contents widget. |
|
231 qreal hiddenVirtualHeight = containerVirtualHeight - q->boundingRect().height(); |
|
232 if (hiddenVirtualHeight != 0) { |
|
233 thumbPosition = (-virtualTopBoundary) / hiddenVirtualHeight; |
|
234 } |
|
235 |
|
236 if (thumbPosition < 0.0) |
|
237 thumbPosition = 0.0; |
|
238 else if (thumbPosition > 1.0) |
|
239 thumbPosition = 1.0; |
|
240 |
|
241 if (mVerticalScrollBar) { |
|
242 if (containerVirtualHeight!=0) { |
|
243 mVerticalScrollBar->setPageSize(qBound ( (qreal)0.0, |
|
244 q->boundingRect().height() / containerVirtualHeight, |
|
245 (qreal)1.0)); |
|
246 } |
|
247 mVerticalScrollBar->setValue(thumbPosition); |
|
248 } |
|
249 } |
|
250 |
|
251 void HbGridViewPrivate::setScrollBarMetrics(Qt::Orientation orientation) |
181 void HbGridViewPrivate::setScrollBarMetrics(Qt::Orientation orientation) |
252 { |
182 { |
253 if (!mContainer->itemRecycling() |
183 if (!handleScrollBar(orientation)) { |
254 || mContainer->itemPrototypes().count() != 1 |
|
255 || mContainer->items().count() == 0) { |
|
256 HbScrollAreaPrivate::setScrollBarMetrics(orientation); |
184 HbScrollAreaPrivate::setScrollBarMetrics(orientation); |
257 } else { |
185 } else { |
258 //We just make sure that the base clas is not called |
186 if (mContainer->layout() && !mContainer->layout()->isActivated()) { |
259 //It set the page size wrongly |
187 mContainer->layout()->activate(); |
260 updateScrollBar(orientation); |
188 } |
261 } |
189 |
262 } |
190 qreal thumbSize = calculateScrollBarThumbSize(); |
263 |
191 HbScrollBar *scrollBar = getScrollDirectionScrollBar(); |
264 void HbGridViewPrivate::setContentPosition( qreal value, Qt::Orientation orientation, bool animate ) |
192 scrollBar->setPageSize(thumbSize); |
|
193 } |
|
194 } |
|
195 |
|
196 /*! |
|
197 \reimp |
|
198 */ |
|
199 void HbGridViewPrivate::setContentPosition(qreal value, Qt::Orientation orientation, bool animate) |
265 { |
200 { |
266 Q_Q( HbGridView ); |
201 Q_Q( HbGridView ); |
267 |
202 |
268 if (mContainer->itemRecycling() && mModelIterator->model()) { |
203 if (mContainer->itemRecycling() && mModelIterator->model()) { |
269 if (mContainer->layout() && !mContainer->layout()->isActivated()) { |
204 if (mContainer->layout() && !mContainer->layout()->isActivated()) { |
270 mContainer->layout()->activate(); |
205 mContainer->layout()->activate(); |
271 } |
206 } |
272 |
207 |
273 qreal filteredValue = (int)(value * 1000) / 1000.0; |
208 int columnCount = getScrollDirectionColumnCount(); |
274 |
209 int rowCount = getScrollDirectionRowCount(); |
275 HbAbstractViewItem *firstItem = mContainer->items().first(); |
210 int modelRowCount = (mModelIterator->indexCount() + columnCount - 1) / columnCount; |
276 |
211 modelRowCount -= rowCount; |
277 qreal uniformItemDimension = 0; // width or height of item |
212 qreal thumbPos = calculateScrollBarPos(); |
278 qreal dimension = 0; // width or height of view |
213 qreal itemSize = getScrollDirectionItemSize(); |
279 int dimensionCount = 0; // rowcount or columncount |
214 qreal diff = (value - thumbPos) * itemSize * modelRowCount; |
280 qreal posInBeginning = 0; // top or left position of first item in buffer |
|
281 |
215 |
282 if (orientation == Qt::Vertical) { |
216 if (orientation == Qt::Vertical) { |
283 posInBeginning = itemBoundingRect(firstItem).top(); |
217 q->scrollByAmount(QPointF(0, diff)); |
284 uniformItemDimension = firstItem->size().height(); |
|
285 dimension = q->boundingRect().height(); |
|
286 dimensionCount = q->columnCount(); |
|
287 } else { |
218 } else { |
288 posInBeginning = itemBoundingRect(firstItem).left(); |
219 q->scrollByAmount(QPointF(diff, 0)); |
289 uniformItemDimension = firstItem->size().width(); |
|
290 dimension = q->boundingRect().width(); |
|
291 dimensionCount = q->rowCount(); |
|
292 } |
|
293 |
|
294 int indexCount = mModelIterator->indexCount(); |
|
295 int virtualCount = indexCount / dimensionCount; // amount of rows/columns in "complete" grid |
|
296 int remainder = indexCount % dimensionCount; |
|
297 if (remainder != 0) { //even one item requires the whole row |
|
298 virtualCount++; |
|
299 } |
|
300 |
|
301 qreal target = virtualCount * filteredValue; // target position in "complete" grid (in rows/columns) |
|
302 int virtualItemCount = virtualCount * dimensionCount; // item count when all the "empty" items are also counted in |
|
303 qreal posToBeInView = dimension * filteredValue; |
|
304 |
|
305 QModelIndex newIndex = mModelIterator->index(qMin((int)(virtualItemCount * filteredValue), indexCount - 1)); |
|
306 |
|
307 if (!mContainer->itemByIndex(newIndex)) { |
|
308 //jump |
|
309 int itemsInBuffer = mContainer->items().count(); |
|
310 |
|
311 int newBufferStartItem = (int)(virtualItemCount * filteredValue) - qMin(itemsInBuffer - 1, (int)(itemsInBuffer * filteredValue)); |
|
312 mContainer->setModelIndexes(mModelIterator->index(newBufferStartItem)); |
|
313 int newBufferStartRow = newBufferStartItem / dimensionCount; |
|
314 |
|
315 qreal posToBeInBuffer = ((target - newBufferStartRow) * uniformItemDimension); |
|
316 |
|
317 qreal posToBe = posToBeInView - posToBeInBuffer; |
|
318 |
|
319 if (orientation == Qt::Vertical) { |
|
320 HbScrollAreaPrivate::setContentPosition(QPointF(0, posToBe)); |
|
321 } else { |
|
322 HbScrollAreaPrivate::setContentPosition(QPointF(posToBe, 0)); |
|
323 } |
|
324 } else { |
|
325 // scroll |
|
326 int firstItemRow = mContainer->items().first()->modelIndex().row() / dimensionCount; |
|
327 |
|
328 qreal posToBeInBuffer = (target - firstItemRow) * uniformItemDimension; |
|
329 |
|
330 qreal posToBe = posToBeInView - posToBeInBuffer; |
|
331 |
|
332 if (orientation == Qt::Vertical) { |
|
333 q->scrollByAmount(QPointF(0, posInBeginning - posToBe)); |
|
334 } else { |
|
335 q->scrollByAmount(QPointF(posInBeginning - posToBe, 0)); |
|
336 } |
|
337 } |
220 } |
338 } else { |
221 } else { |
339 HbScrollAreaPrivate::setContentPosition(value, orientation, animate); |
222 HbScrollAreaPrivate::setContentPosition(value, orientation, animate); |
340 } |
|
341 |
|
342 if (animate) { |
|
343 updateScrollBar(orientation); |
|
344 } |
223 } |
345 } |
224 } |
346 |
225 |
347 QModelIndex HbGridViewPrivate::indexInTheCenter(Qt::Orientations scrollDirection) const |
226 QModelIndex HbGridViewPrivate::indexInTheCenter(Qt::Orientations scrollDirection) const |
348 { |
227 { |