|
1 /* |
|
2 * Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 |
|
18 #include <QGraphicsLinearLayout> |
|
19 #include <QApplication> |
|
20 #include <hbscrollbar_p.h> |
|
21 #include <hgwidgets/hgwidgets.h> |
|
22 |
|
23 #include "hgwidgets_p.h" |
|
24 #include "hgcontainer.h" |
|
25 #include "hgcoverflowcontainer.h" |
|
26 #include "hgscrollbuffermanager.h" |
|
27 #include "hgwidgetitem.h" |
|
28 #include "trace.h" |
|
29 #include "hgindexfeedback.h" |
|
30 |
|
31 static const int INITIAL_SCROLLBAR_HIDE_TIMEOUT(4000); |
|
32 static const int DEFAULT_BUFFER_SIZE(40); |
|
33 |
|
34 HgWidgetPrivate::HgWidgetPrivate() : |
|
35 mLayout(0), |
|
36 mContainer(0), |
|
37 mBufferManager(0), |
|
38 mModel(0), |
|
39 mSelectionModel(0), |
|
40 mDefaultSelectionModel(0), |
|
41 mScrollBar(0), |
|
42 mAbleToScroll(false), |
|
43 mHandleLongPress(false), |
|
44 mBufferSize(DEFAULT_BUFFER_SIZE) |
|
45 { |
|
46 FUNC_LOG; |
|
47 } |
|
48 |
|
49 HgWidgetPrivate::~HgWidgetPrivate() |
|
50 { |
|
51 FUNC_LOG; |
|
52 |
|
53 delete mDefaultSelectionModel; |
|
54 delete mBufferManager; |
|
55 } |
|
56 |
|
57 void HgWidgetPrivate::init(HgContainer *container) |
|
58 { |
|
59 FUNC_LOG; |
|
60 Q_Q(HgWidget); |
|
61 |
|
62 mScrollBarHideTimer.setParent(q); |
|
63 mScrollBarHideTimer.setSingleShot(true); |
|
64 |
|
65 q->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); |
|
66 q->setFlag( QGraphicsItem::ItemClipsChildrenToShape, true ); |
|
67 q->setFocusPolicy(Qt::StrongFocus); |
|
68 |
|
69 createScrollBar(container->orientation()); |
|
70 |
|
71 QObject::connect(&(mScrollBarHideTimer), SIGNAL(timeout()), q, SLOT(_q_hideScrollBars())); |
|
72 |
|
73 mContainer = container; |
|
74 |
|
75 mScrollBarPolicy = HgWidget::ScrollBarAutoHide; |
|
76 |
|
77 q->connect(mContainer, SIGNAL(scrollPositionChanged(qreal,bool)), |
|
78 q, SLOT(_q_scrollPositionChanged(qreal,bool))); |
|
79 q->connect(mContainer, SIGNAL(activated(const QModelIndex&)), |
|
80 q, SIGNAL(activated(const QModelIndex&))); |
|
81 q->connect(mContainer, SIGNAL(longPressed(const QModelIndex&, const QPointF &)), |
|
82 q, SIGNAL(longPressed(const QModelIndex&, const QPointF &))); |
|
83 q->connect(mContainer, SIGNAL(scrollingStarted()), q, SIGNAL(scrollingStarted())); |
|
84 q->connect(mContainer, SIGNAL(scrollingEnded()), q, SIGNAL(scrollingEnded())); |
|
85 |
|
86 mIndexFeedback = new HgIndexFeedback(q); |
|
87 mIndexFeedback->setWidget(q); |
|
88 |
|
89 } |
|
90 |
|
91 void HgWidgetPrivate::setModel( QAbstractItemModel *model ) |
|
92 { |
|
93 FUNC_LOG; |
|
94 |
|
95 if (model != mModel) { |
|
96 clearCurrentModel(); |
|
97 mModel = model; |
|
98 initializeNewModel(); |
|
99 } |
|
100 } |
|
101 |
|
102 void HgWidgetPrivate::setSelectionModel(QItemSelectionModel *selectionModel) |
|
103 { |
|
104 FUNC_LOG; |
|
105 |
|
106 Q_Q(HgWidget); |
|
107 |
|
108 if (mContainer) { |
|
109 if (selectionModel == 0) { |
|
110 QItemSelectionModel *oldSelectionModel = mDefaultSelectionModel; |
|
111 mDefaultSelectionModel = 0; |
|
112 mDefaultSelectionModel = new QItemSelectionModel(mModel); |
|
113 mContainer->setSelectionModel(mDefaultSelectionModel); |
|
114 delete oldSelectionModel; |
|
115 } |
|
116 else if (selectionModel != mContainer->selectionModel()) { |
|
117 QItemSelectionModel *oldSelectionModel = mDefaultSelectionModel; |
|
118 mDefaultSelectionModel = 0; |
|
119 mContainer->setSelectionModel(selectionModel); |
|
120 delete oldSelectionModel; |
|
121 } |
|
122 if (mContainer->selectionModel()) { |
|
123 if (mIndexFeedback) { |
|
124 delete mIndexFeedback; |
|
125 mIndexFeedback = 0; |
|
126 } |
|
127 mIndexFeedback = new HgIndexFeedback(q); |
|
128 mIndexFeedback->setWidget(q); |
|
129 } |
|
130 } |
|
131 } |
|
132 |
|
133 QItemSelectionModel *HgWidgetPrivate::selectionModel() const |
|
134 { |
|
135 FUNC_LOG; |
|
136 |
|
137 if (mContainer) { |
|
138 return mContainer->selectionModel(); |
|
139 } |
|
140 return 0; |
|
141 } |
|
142 |
|
143 HgWidget::SelectionMode HgWidgetPrivate::selectionMode() const |
|
144 { |
|
145 FUNC_LOG; |
|
146 |
|
147 if (mContainer) { |
|
148 return mContainer->selectionMode(); |
|
149 } |
|
150 return HgWidget::NoSelection; |
|
151 } |
|
152 |
|
153 void HgWidgetPrivate::setSelectionMode(HgWidget::SelectionMode mode, bool resetSelection) |
|
154 { |
|
155 FUNC_LOG; |
|
156 |
|
157 if (mContainer) { |
|
158 mContainer->setSelectionMode(mode, resetSelection); |
|
159 } |
|
160 } |
|
161 |
|
162 void HgWidgetPrivate::selectAll() |
|
163 { |
|
164 FUNC_LOG; |
|
165 Q_Q(HgWidget); |
|
166 |
|
167 if (mContainer && |
|
168 (mContainer->selectionMode() == HgWidget::MultiSelection || |
|
169 mContainer->selectionMode() == HgWidget::ContiguousSelection) && |
|
170 mModel && mModel->columnCount() > 0 && mModel->rowCount() > 0) { |
|
171 QItemSelection selection( |
|
172 mModel->index(0, 0), |
|
173 mModel->index(mModel->rowCount()-1, mModel->columnCount()-1)); |
|
174 mContainer->selectionModel()->select(selection, QItemSelectionModel::Select); |
|
175 q->update(); |
|
176 } |
|
177 } |
|
178 |
|
179 void HgWidgetPrivate::clearSelection() |
|
180 { |
|
181 FUNC_LOG; |
|
182 Q_Q(HgWidget); |
|
183 |
|
184 if (mContainer) { |
|
185 mContainer->selectionModel()->clearSelection(); |
|
186 q->update(); |
|
187 } |
|
188 } |
|
189 |
|
190 QModelIndex HgWidgetPrivate::currentIndex() const |
|
191 { |
|
192 FUNC_LOG; |
|
193 |
|
194 if (mContainer && mContainer->selectionModel()) { |
|
195 return mContainer->selectionModel()->currentIndex(); |
|
196 } |
|
197 return QModelIndex(); |
|
198 } |
|
199 |
|
200 void HgWidgetPrivate::setCurrentIndex( |
|
201 const QModelIndex &index, QItemSelectionModel::SelectionFlags selectionFlag) |
|
202 { |
|
203 FUNC_LOG; |
|
204 |
|
205 if (mContainer && mContainer->selectionModel()) { |
|
206 mContainer->selectionModel()->setCurrentIndex(index, selectionFlag); |
|
207 } |
|
208 } |
|
209 |
|
210 void HgWidgetPrivate::scrollTo(const QModelIndex &index) |
|
211 { |
|
212 FUNC_LOG; |
|
213 |
|
214 if (index.isValid()) { |
|
215 if (mContainer) { |
|
216 mContainer->scrollTo(index); |
|
217 } |
|
218 if (mBufferManager) { |
|
219 mBufferManager->scrollPositionChanged(index.row()); |
|
220 } |
|
221 } |
|
222 } |
|
223 |
|
224 void HgWidgetPrivate::initializeNewModel() |
|
225 { |
|
226 FUNC_LOG; |
|
227 Q_Q(HgWidget); |
|
228 |
|
229 if (mModel) { |
|
230 // These asserts do basic sanity checking of the model |
|
231 Q_ASSERT_X(mModel->index(0,0) == mModel->index(0,0), |
|
232 "HbAbstractItemView::setModel", |
|
233 "A model should return the exact same index " |
|
234 "(including its internal id/pointer) when asked for it twice in a row."); |
|
235 Q_ASSERT_X(mModel->index(0,0).parent() == QModelIndex(), |
|
236 "HbAbstractItemView::setModel", |
|
237 "The parent of a top level index should be invalid"); |
|
238 |
|
239 q->connect(mModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)), |
|
240 SLOT( dataChanged(QModelIndex,QModelIndex))); |
|
241 q->connect(mModel, SIGNAL(rowsInserted(QModelIndex, int, int)), |
|
242 SLOT(_q_insertRows(QModelIndex, int, int))); |
|
243 q->connect(mModel, SIGNAL(rowsRemoved(QModelIndex, int, int)), |
|
244 SLOT(_q_removeRows(QModelIndex, int, int))); |
|
245 q->connect(mModel, SIGNAL(rowsMoved(QModelIndex, int, int, QModelIndex, int)), |
|
246 SLOT(_q_moveRows(QModelIndex, int, int, QModelIndex, int))); |
|
247 |
|
248 mContainer->setItemCount(mModel->rowCount(QModelIndex())); |
|
249 QList<HgWidgetItem*> items = mContainer->items(); |
|
250 |
|
251 // set model indexes for the items firsts |
|
252 int itemCount = items.count(); |
|
253 for( int i=0; i<itemCount; i++) |
|
254 { |
|
255 items.at(i)->setModelIndex(mModel->index(i, 0, QModelIndex())); |
|
256 } |
|
257 |
|
258 if( mBufferManager ) |
|
259 { |
|
260 delete mBufferManager; |
|
261 mBufferManager = 0; |
|
262 } |
|
263 |
|
264 mBufferManager = new HgScrollBufferManager(mBufferSize,mBufferSize/4,0,itemCount); |
|
265 q->connect( mBufferManager, SIGNAL(releaseItems(int,int)), q, SLOT(_q_releaseItems(int,int))); |
|
266 q->connect( mBufferManager, SIGNAL(requestItems(int,int)), q, SLOT(_q_requestItems(int,int))); |
|
267 mBufferManager->resetBuffer(0, itemCount); |
|
268 |
|
269 setSelectionModel(0); // Default |
|
270 |
|
271 if (mModel->rowCount() > 0) |
|
272 { |
|
273 setCurrentIndex(mModel->index(0, 0)); |
|
274 scrollTo(mModel->index(0, 0)); |
|
275 } |
|
276 } |
|
277 } |
|
278 |
|
279 void HgWidgetPrivate::clearCurrentModel() |
|
280 { |
|
281 FUNC_LOG; |
|
282 Q_Q(HgWidget); |
|
283 |
|
284 if (mModel) { |
|
285 mModel->disconnect(q, SLOT(dataChanged(QModelIndex, QModelIndex))); |
|
286 mModel->disconnect(q, SLOT(_q_insertRows(QModelIndex, int, int))); |
|
287 mModel->disconnect(q, SLOT(_q_removeRows(QModelIndex, int, int))); |
|
288 mModel->disconnect(q, SLOT(_q_moveRows(QModelIndex, int, int, QModelIndex, int))); |
|
289 mModel = 0; |
|
290 } |
|
291 |
|
292 // TODO: setSelectionModel(0); |
|
293 |
|
294 } |
|
295 void HgWidgetPrivate::_q_releaseItems( int releaseStart, int releaseEnd ) |
|
296 { |
|
297 FUNC_LOG; |
|
298 |
|
299 QList<HgWidgetItem*> items = mContainer->items(); |
|
300 const int itemCount = items.count(); |
|
301 |
|
302 int start = qBound(0, releaseStart, itemCount-1); |
|
303 int end = qBound(0, releaseEnd, itemCount-1); |
|
304 |
|
305 INFO("Release items:" << start << "-" << end); |
|
306 // request data for items |
|
307 for (int i = start; i <= end; i++) { |
|
308 HgWidgetItem* item = items.at(i); |
|
309 if (item) { |
|
310 item->releaseItemData(); |
|
311 } |
|
312 } |
|
313 } |
|
314 |
|
315 void HgWidgetPrivate::_q_requestItems(int requestStart, int requestEnd) |
|
316 { |
|
317 FUNC_LOG; |
|
318 |
|
319 QList<HgWidgetItem*> items = mContainer->items(); |
|
320 const int itemCount = items.count(); |
|
321 |
|
322 int start = qBound(0, requestStart, itemCount-1); |
|
323 int end = qBound(0, requestEnd, itemCount-1); |
|
324 |
|
325 // variables to track which items are really updated. |
|
326 int firstUpdated = -1; |
|
327 int lastUpdated = -1; |
|
328 |
|
329 INFO("Request items:" << start << "-" << end); |
|
330 // request data for items |
|
331 for (int i = start; i <= end; i++) { |
|
332 HgWidgetItem* item = items.at(i); |
|
333 if (item && item->updateItemData()) { |
|
334 if (firstUpdated == -1) firstUpdated = i; |
|
335 lastUpdated = i; |
|
336 } |
|
337 } |
|
338 |
|
339 // notify container which items have updated data available. |
|
340 // container is responsible to redraw view if some of the items |
|
341 // is visible. |
|
342 if (firstUpdated != -1 && lastUpdated != -1) { |
|
343 mContainer->itemDataChanged(firstUpdated, lastUpdated); |
|
344 } |
|
345 } |
|
346 |
|
347 void HgWidgetPrivate::_q_scrollPositionChanged(qreal index,bool scrollBarAnimation) |
|
348 { |
|
349 int newPos = index; |
|
350 newPos *= mContainer->rowCount(); |
|
351 if (mBufferManager) { |
|
352 mBufferManager->scrollPositionChanged(newPos); |
|
353 } |
|
354 |
|
355 if (!scrollBarAnimation) |
|
356 updateScrollMetrics(index); |
|
357 } |
|
358 |
|
359 void HgWidgetPrivate::replaceScrollBar(HbScrollBar *scrollBar) |
|
360 { |
|
361 Q_Q(HgWidget); |
|
362 delete mScrollBar; |
|
363 mScrollBar = scrollBar; |
|
364 |
|
365 scrollBar->setParentItem(q); |
|
366 |
|
367 // make sure the scrollbar is on top |
|
368 scrollBar->setZValue(q->zValue() + 1); |
|
369 |
|
370 prepareScrollBars(); |
|
371 |
|
372 QObject::connect(scrollBar, SIGNAL(valueChanged(qreal, Qt::Orientation)), q, SLOT(_q_thumbPositionChanged(qreal, Qt::Orientation))); |
|
373 } |
|
374 |
|
375 void HgWidgetPrivate::prepareScrollBars( qreal pos ) |
|
376 { |
|
377 Q_Q( HgWidget ); |
|
378 |
|
379 QRectF boundingRect = q->boundingRect(); |
|
380 |
|
381 bool scrollBarsVisible(false); |
|
382 |
|
383 if ((mAbleToScroll && mScrollBarPolicy != HgWidget::ScrollBarAlwaysOff) || |
|
384 mScrollBarPolicy == HgWidget::ScrollBarAlwaysOn) { |
|
385 |
|
386 displayScrollBar(pos ); |
|
387 scrollBarsVisible = true; |
|
388 } |
|
389 else if((!mAbleToScroll || mScrollBarPolicy == HgWidget::ScrollBarAlwaysOff) |
|
390 && mScrollBar->isVisible()){ |
|
391 mScrollBar->setVisible(false); |
|
392 } |
|
393 |
|
394 if (scrollBarsVisible && !mScrollBarHideTimer.isActive()) { |
|
395 mScrollBarHideTimer.start(INITIAL_SCROLLBAR_HIDE_TIMEOUT); |
|
396 } |
|
397 } |
|
398 |
|
399 void HgWidgetPrivate::displayScrollBar(qreal pos) |
|
400 { |
|
401 Q_Q(HgWidget); |
|
402 // Layout the scrollbar |
|
403 setScrollBarMetrics(pos); |
|
404 |
|
405 // Activate the scrollbar |
|
406 if ( !mScrollBar->isVisible() && q->isVisible()) { |
|
407 mScrollBar->setVisible(true); |
|
408 } |
|
409 } |
|
410 |
|
411 void HgWidgetPrivate::setScrollBarPolicy(HgWidget::ScrollBarPolicy policy) |
|
412 { |
|
413 mScrollBarPolicy = policy; |
|
414 |
|
415 if (mScrollBarPolicy == HgWidget::ScrollBarAlwaysOff && |
|
416 mScrollBar->isVisible()){ |
|
417 mScrollBar->setVisible(false); |
|
418 } |
|
419 |
|
420 if(policy != HgWidget::ScrollBarAlwaysOff){ |
|
421 updateScrollMetrics(); |
|
422 } |
|
423 } |
|
424 |
|
425 void HgWidgetPrivate::_q_hideScrollBars() |
|
426 { |
|
427 if (mScrollBar && mScrollBarPolicy == HgWidget::ScrollBarAutoHide) { |
|
428 |
|
429 // TODO, do we need to know if scrollbar was pressed? we cannot access the private methods, since |
|
430 // only scrollareaprivate is a friend class. |
|
431 if (false/*scrollBarPressed(mHorizontalScrollBar) || |
|
432 scrollBarPressed(mVerticalScrollBar)*/) { |
|
433 mScrollBarHideTimer.start(); |
|
434 } else if(mScrollBarPolicy != HgWidget::ScrollBarAlwaysOn |
|
435 && mScrollBar->isVisible()){ |
|
436 mScrollBar->setVisible(false); |
|
437 |
|
438 } |
|
439 } |
|
440 } |
|
441 |
|
442 /** |
|
443 * |
|
444 */ |
|
445 void HgWidgetPrivate::_q_thumbPositionChanged(qreal value, Qt::Orientation orientation) |
|
446 { |
|
447 Q_UNUSED(orientation) |
|
448 |
|
449 mContainer->scrollToPosition( value, true ); |
|
450 |
|
451 // TODO, stop all scrolling and animations |
|
452 |
|
453 if (mScrollBarHideTimer.isActive()) { |
|
454 mScrollBarHideTimer.stop(); |
|
455 mScrollBarHideTimer.start(); |
|
456 } |
|
457 } |
|
458 |
|
459 void HgWidgetPrivate::_q_insertRows(const QModelIndex &parent, int start, int end) |
|
460 { |
|
461 FUNC_LOG; |
|
462 INFO("Insert rows" << start << "-" << end); |
|
463 Q_UNUSED(parent) |
|
464 Q_Q(HgWidget); |
|
465 |
|
466 if (mContainer) { |
|
467 mContainer->addItems(start, end); |
|
468 // re-set model indexes for the items including and after the added indexes |
|
469 QList<HgWidgetItem *> items = mContainer->items(); |
|
470 int newItemCount = items.count(); |
|
471 for (int i = start; i < newItemCount; i++) { |
|
472 items.at(i)->setModelIndex(mModel->index(i, 0, QModelIndex())); |
|
473 } |
|
474 mBufferManager->addItems(start, end, newItemCount); |
|
475 q->update(); |
|
476 } |
|
477 } |
|
478 |
|
479 void HgWidgetPrivate::_q_removeRows(const QModelIndex &parent, int start, int end) |
|
480 { |
|
481 FUNC_LOG; |
|
482 INFO("Remove rows" << start << "-" << end); |
|
483 Q_UNUSED(parent) |
|
484 Q_Q(HgWidget); |
|
485 |
|
486 if (mContainer && mBufferManager) { |
|
487 mContainer->removeItems(start, end); |
|
488 // re-set model indexes for the items after the removed indexes |
|
489 QList<HgWidgetItem *> items = mContainer->items(); |
|
490 int newItemCount = items.count(); |
|
491 for (int i = start; i < newItemCount; i++) { |
|
492 items.at(i)->setModelIndex(mModel->index(i, 0, QModelIndex())); |
|
493 } |
|
494 mBufferManager->removeItems(start, end, newItemCount); |
|
495 q->update(); |
|
496 } |
|
497 } |
|
498 |
|
499 void HgWidgetPrivate::_q_moveRows(const QModelIndex &sourceParent, |
|
500 int sourceStart, int sourceEnd, |
|
501 const QModelIndex &destinationParent, int destinationRow) |
|
502 { |
|
503 FUNC_LOG; |
|
504 INFO("Move rows" << sourceStart << "-" << sourceEnd << "to" << destinationRow); |
|
505 Q_UNUSED(sourceParent) |
|
506 Q_UNUSED(destinationParent) |
|
507 Q_Q(HgWidget); |
|
508 |
|
509 if (mContainer) { |
|
510 mContainer->moveItems(sourceStart, sourceEnd, destinationRow); |
|
511 // re-set model indexes for the items after the removed indexes |
|
512 QList<HgWidgetItem *> items = mContainer->items(); |
|
513 int itemCount = items.count(); |
|
514 for (int i = qMin(sourceStart, destinationRow); i < itemCount; i++) { |
|
515 items.at(i)->setModelIndex(mModel->index(i, 0, QModelIndex())); |
|
516 } |
|
517 mBufferManager->moveItems(sourceStart, sourceEnd, destinationRow, itemCount); |
|
518 q->update(); |
|
519 } |
|
520 } |
|
521 |
|
522 void HgWidgetPrivate::setScrollBarMetrics(qreal pos) |
|
523 { |
|
524 Q_Q( HgWidget ); |
|
525 |
|
526 if (!mContainer) |
|
527 return; |
|
528 |
|
529 qreal screenSize, worldSize; |
|
530 mContainer->dimensions(screenSize,worldSize); |
|
531 |
|
532 const qreal start(0.0); |
|
533 const qreal end(1.0); |
|
534 const qreal page(screenSize/worldSize); |
|
535 |
|
536 // Set handle size |
|
537 mScrollBar->setPageSize( qBound(start,page,end ) ); |
|
538 |
|
539 updateScrollBar(pos); |
|
540 } |
|
541 |
|
542 void HgWidgetPrivate::updateScrollBar(qreal pos) |
|
543 { |
|
544 Q_Q( HgWidget ); |
|
545 |
|
546 if (pos < 0.0) |
|
547 pos = 0.0; |
|
548 else if (pos > 1.0) |
|
549 pos = 1.0; |
|
550 // The scrollbar "thumb" position is the current position of the contents widget divided |
|
551 // by the difference between the height of the contents widget and the height of the scroll area. |
|
552 // This formula assumes that the "thumb" of the the scroll bar is sized proportionately to |
|
553 // the height of the contents widget. |
|
554 mScrollBar->setValue(pos); |
|
555 } |
|
556 |
|
557 /* |
|
558 * updateScrollMetrics() is a private function called when |
|
559 * scrolling starts to set the metrics needed in scrolling. |
|
560 */ |
|
561 void HgWidgetPrivate::updateScrollMetrics( qreal pos) |
|
562 { |
|
563 Q_Q(HgWidget); |
|
564 |
|
565 QRectF scrollAreaBoundingRect = q->boundingRect(); |
|
566 |
|
567 if (!mContainer || scrollAreaBoundingRect.isNull() || |
|
568 !scrollAreaBoundingRect.isValid()) |
|
569 return; |
|
570 |
|
571 qreal screenSize, worldSize; |
|
572 mContainer->dimensions(screenSize,worldSize); |
|
573 |
|
574 mAbleToScroll = false; |
|
575 if (worldSize > screenSize) { |
|
576 mAbleToScroll = true; |
|
577 } |
|
578 |
|
579 prepareScrollBars( pos/worldSize ); |
|
580 } |
|
581 |
|
582 void HgWidgetPrivate::adjustGeometry() |
|
583 { |
|
584 Q_Q(HgWidget); |
|
585 |
|
586 QRectF scrollAreaBoundingRect = q->boundingRect(); |
|
587 if( scrollAreaBoundingRect.isNull() || |
|
588 !scrollAreaBoundingRect.isValid() || |
|
589 !mContainer || |
|
590 scrollAreaBoundingRect == mContainer->boundingRect() ) |
|
591 return; |
|
592 |
|
593 mContainer->resize(scrollAreaBoundingRect.size()); |
|
594 |
|
595 updateScrollMetrics(0); |
|
596 } |
|
597 |
|
598 |
|
599 void HgWidgetPrivate::lostForeground() |
|
600 { |
|
601 if( !mForeground ) return; |
|
602 |
|
603 mForeground = false; |
|
604 QList<HgWidgetItem*> list = mContainer->items(); |
|
605 foreach(HgWidgetItem* item, list){ |
|
606 item->releaseItemData(); |
|
607 } |
|
608 } |
|
609 |
|
610 void HgWidgetPrivate::gainedForeground() |
|
611 { |
|
612 if( mForeground ) return; |
|
613 |
|
614 mForeground = true; |
|
615 QList<HgWidgetItem*> list = mContainer->items(); |
|
616 int bufferStart = 0; |
|
617 int bufferEnd = 0; |
|
618 mBufferManager->currentBuffer(bufferStart,bufferEnd); |
|
619 for(;bufferStart<=bufferEnd;bufferStart++){ |
|
620 list.at(bufferStart)->updateItemData(); |
|
621 } |
|
622 } |
|
623 |
|
624 bool HgWidgetPrivate::getItemOutline(const QModelIndex& index, QPolygonF& points) |
|
625 { |
|
626 return mContainer->getItemPoints(index.row(), points); |
|
627 } |
|
628 |
|
629 void HgWidgetPrivate::aboutToChangeOrientation() |
|
630 { |
|
631 |
|
632 } |
|
633 |
|
634 void HgWidgetPrivate::orientationChanged(Qt::Orientation orientation) |
|
635 { |
|
636 Q_Q(HgWidget); |
|
637 if (mContainer->orientation() != orientation) { |
|
638 createScrollBar(orientation); |
|
639 q->repolish(); |
|
640 mContainer->setOrientation(orientation); |
|
641 adjustGeometry(); |
|
642 } |
|
643 } |
|
644 |
|
645 void HgWidgetPrivate::_q_groovePressed(qreal value, Qt::Orientation orientation) |
|
646 { |
|
647 Q_UNUSED(value); |
|
648 Q_UNUSED(orientation); |
|
649 } |
|
650 |
|
651 Qt::Orientation HgWidgetPrivate::scrollDirection() const |
|
652 { |
|
653 return mContainer->orientation(); |
|
654 } |
|
655 |
|
656 void HgWidgetPrivate::createScrollBar(Qt::Orientation orientation) |
|
657 { |
|
658 Q_Q(HgWidget); |
|
659 |
|
660 delete mScrollBar; |
|
661 mScrollBar = 0; |
|
662 mScrollBar = new HbScrollBar(orientation,q); |
|
663 if (orientation == Qt::Vertical) { |
|
664 HbStyle::setItemName(mScrollBar, "scrollbar-vertical"); |
|
665 } |
|
666 else { |
|
667 HbStyle::setItemName(mScrollBar, "scrollbar-horizontal"); |
|
668 } |
|
669 |
|
670 mScrollBar->setZValue(q->zValue() + 1); |
|
671 QObject::connect(mScrollBar, SIGNAL(valueChanged(qreal, Qt::Orientation)), |
|
672 q, SLOT(_q_thumbPositionChanged(qreal, Qt::Orientation))); |
|
673 QObject::connect(mScrollBar, SIGNAL(valueChangeRequested(qreal, Qt::Orientation)), |
|
674 q, SLOT(_q_groovePressed(qreal, Qt::Orientation))); |
|
675 mScrollBar->setVisible(false); |
|
676 } |
|
677 |
|
678 QList<QModelIndex> HgWidgetPrivate::getVisibleItemIndices() const |
|
679 { |
|
680 return mContainer->getVisibleItemIndices(); |
|
681 } |
|
682 |
|
683 void HgWidgetPrivate::setIndexFeedbackPolicy( HgWidget::IndexFeedbackPolicy policy) |
|
684 { |
|
685 mIndexFeedback->setIndexFeedbackPolicy(policy); |
|
686 } |
|
687 |
|
688 HgWidget::IndexFeedbackPolicy HgWidgetPrivate::indexFeedbackPolicy() const |
|
689 { |
|
690 return mIndexFeedback->indexFeedbackPolicy(); |
|
691 } |
|
692 |
|
693 #include "moc_hgwidgets.cpp" |