Qt 4.8
qdeclarativegridview.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtDeclarative module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include "private/qdeclarativegridview_p.h"
43 
44 #include "private/qdeclarativevisualitemmodel_p.h"
45 #include "private/qdeclarativeflickable_p_p.h"
46 
47 #include "private/qdeclarativesmoothedanimation_p_p.h"
48 #include <qdeclarativeguard_p.h>
49 
50 #include <qlistmodelinterface_p.h>
51 #include <QKeyEvent>
52 
53 #include <qmath.h>
54 #include <math.h>
55 #include "qplatformdefs.h"
56 
58 
59 #ifndef QML_FLICK_SNAPONETHRESHOLD
60 #define QML_FLICK_SNAPONETHRESHOLD 30
61 #endif
62 
63 //----------------------------------------------------------------------------
64 
66 {
67 public:
69  attached = static_cast<QDeclarativeGridViewAttached*>(qmlAttachedPropertiesObject<QDeclarativeGridView>(item));
70  if (attached)
72  }
74 
75  qreal rowPos() const {
76  qreal rowPos = 0;
78  rowPos = item->y();
79  } else {
81  rowPos = -view->cellWidth()-item->x();
82  else
83  rowPos = item->x();
84  }
85  return rowPos;
86  }
87  qreal colPos() const {
88  qreal colPos = 0;
91  int colSize = view->cellWidth();
92  int columns = view->width()/colSize;
93  colPos = colSize * (columns-1) - item->x();
94  } else {
95  colPos = item->x();
96  }
97  } else {
98  colPos = item->y();
99  }
100 
101  return colPos;
102  }
103 
104  qreal endRowPos() const {
106  return item->y() + view->cellHeight() - 1;
107  } else {
109  return -item->x() - 1;
110  else
111  return item->x() + view->cellWidth() - 1;
112  }
113  }
114  void setPosition(qreal col, qreal row) {
117  int columns = view->width()/view->cellWidth();
118  item->setPos(QPointF((view->cellWidth() * (columns-1) - col), row));
119  } else {
120  item->setPos(QPointF(-view->cellWidth()-row, col));
121  }
122  } else {
124  item->setPos(QPointF(col, row));
125  else
126  item->setPos(QPointF(row, col));
127  }
128 
129  }
130  bool contains(qreal x, qreal y) const {
131  return (x >= item->x() && x < item->x() + view->cellWidth() &&
132  y >= item->y() && y < item->y() + view->cellHeight());
133  }
134 
138  int index;
139 };
140 
141 //----------------------------------------------------------------------------
142 
144 {
146 
147 public:
149  : currentItem(0), layoutDirection(Qt::LeftToRight), flow(QDeclarativeGridView::LeftToRight)
150  , visibleIndex(0) , currentIndex(-1)
151  , cellWidth(100), cellHeight(100), columns(1), requestedIndex(-1), itemCount(0)
152  , highlightRangeStart(0), highlightRangeEnd(0)
153  , highlightRangeStartValid(false), highlightRangeEndValid(false)
154  , highlightRange(QDeclarativeGridView::NoHighlightRange)
155  , highlightComponent(0), highlight(0), trackedItem(0)
156  , moveReason(Other), buffer(0), highlightXAnimator(0), highlightYAnimator(0)
157  , highlightMoveDuration(150)
158  , footerComponent(0), footer(0), headerComponent(0), header(0)
159  , bufferMode(BufferBefore | BufferAfter), snapMode(QDeclarativeGridView::NoSnap)
160  , ownModel(false), wrap(false), autoHighlight(true)
161  , fixCurrentVisibility(false), lazyRelease(false), layoutScheduled(false)
162  , deferredRelease(false), haveHighlightRange(false), currentIndexCleared(false) {}
163 
164  void init();
165  void clear();
166  FxGridItem *createItem(int modelIndex);
167  void releaseItem(FxGridItem *item);
168  QDeclarativeItem *createComponentItem(QDeclarativeComponent *component);
169  void refill(qreal from, qreal to, bool doBuffer=false);
170 
171  void updateGrid();
172  void scheduleLayout();
173  void layout();
174  void updateUnrequestedIndexes();
175  void updateUnrequestedPositions();
176  void updateTrackedItem();
177  void createHighlight();
178  void updateHighlight();
179  void updateCurrent(int modelIndex);
180  void updateHeader();
181  void updateFooter();
182  void fixupPosition();
183 
184  FxGridItem *visibleItem(int modelIndex) const {
185  if (modelIndex >= visibleIndex && modelIndex < visibleIndex + visibleItems.count()) {
186  for (int i = modelIndex - visibleIndex; i < visibleItems.count(); ++i) {
187  FxGridItem *item = visibleItems.at(i);
188  if (item->index == modelIndex)
189  return item;
190  }
191  }
192  return 0;
193  }
194 
196  Q_Q(const QDeclarativeGridView);
197  return flow == QDeclarativeGridView::TopToBottom && q->effectiveLayoutDirection() == Qt::RightToLeft;
198  }
199 
200  void regenerate() {
202  if (q->isComponentComplete()) {
203  clear();
204  updateGrid();
205  setPosition(0);
206  q->refill();
207  updateCurrent(currentIndex);
208  }
209  }
210 
211  void mirrorChange() {
212  regenerate();
213  }
214 
215  qreal position() const {
216  Q_Q(const QDeclarativeGridView);
217  return flow == QDeclarativeGridView::LeftToRight ? q->contentY() : q->contentX();
218  }
219  void setPosition(qreal pos) {
221  if (flow == QDeclarativeGridView::LeftToRight) {
222  q->QDeclarativeFlickable::setContentY(pos);
223  q->QDeclarativeFlickable::setContentX(0);
224  } else {
225  if (q->effectiveLayoutDirection() == Qt::LeftToRight)
226  q->QDeclarativeFlickable::setContentX(pos);
227  else
228  q->QDeclarativeFlickable::setContentX(-pos-size());
229  q->QDeclarativeFlickable::setContentY(0);
230  }
231  }
232  int size() const {
233  Q_Q(const QDeclarativeGridView);
234  return flow == QDeclarativeGridView::LeftToRight ? q->height() : q->width();
235  }
237  qreal pos = 0;
238  if (!visibleItems.isEmpty())
239  pos = visibleItems.first()->rowPos() - visibleIndex / columns * rowSize();
240  return pos;
241  }
242 
243  qreal lastPosition() const {
244  qreal pos = 0;
245  if (model && model->count())
246  pos = rowPosAt(model->count() - 1) + rowSize();
247  return pos;
248  }
249 
251  return isRightToLeftTopToBottom() ? -lastPosition()+1 : originPosition();
252  }
253 
254  qreal endPosition() const {
255  return isRightToLeftTopToBottom() ? -originPosition()+1 : lastPosition();
256 
257  }
258 
259  bool isValid() const {
260  return model && model->count() && model->isValid();
261  }
262 
263  int rowSize() const {
264  return flow == QDeclarativeGridView::LeftToRight ? cellHeight : cellWidth;
265  }
266  int colSize() const {
267  return flow == QDeclarativeGridView::LeftToRight ? cellWidth : cellHeight;
268  }
269 
270  qreal colPosAt(int modelIndex) const {
271  if (FxGridItem *item = visibleItem(modelIndex))
272  return item->colPos();
273  if (!visibleItems.isEmpty()) {
274  if (modelIndex < visibleIndex) {
275  int count = (visibleIndex - modelIndex) % columns;
276  int col = visibleItems.first()->colPos() / colSize();
277  col = (columns - count + col) % columns;
278  return col * colSize();
279  } else {
280  int count = columns - 1 - (modelIndex - visibleItems.last()->index - 1) % columns;
281  return visibleItems.last()->colPos() - count * colSize();
282  }
283  } else {
284  return (modelIndex % columns) * colSize();
285  }
286  return 0;
287  }
288  qreal rowPosAt(int modelIndex) const {
289  if (FxGridItem *item = visibleItem(modelIndex))
290  return item->rowPos();
291  if (!visibleItems.isEmpty()) {
292  if (modelIndex < visibleIndex) {
293  int firstCol = visibleItems.first()->colPos() / colSize();
294  int col = visibleIndex - modelIndex + (columns - firstCol - 1);
295  int rows = col / columns;
296  return visibleItems.first()->rowPos() - rows * rowSize();
297  } else {
298  int count = modelIndex - visibleItems.last()->index;
299  int col = visibleItems.last()->colPos() + count * colSize();
300  int rows = col / (columns * colSize());
301  return visibleItems.last()->rowPos() + rows * rowSize();
302  }
303  } else {
304  qreal pos = (modelIndex / columns) * rowSize();
305  if (header)
306  pos += headerSize();
307  return pos;
308  }
309  return 0;
310  }
311 
313  const qreal pos = isRightToLeftTopToBottom() ? -position()-size() : position();
314  for (int i = 0; i < visibleItems.count(); ++i) {
315  FxGridItem *item = visibleItems.at(i);
316  if (item->index != -1 && item->endRowPos() > pos)
317  return item;
318  }
319  return visibleItems.count() ? visibleItems.first() : 0;
320  }
321 
322  int lastVisibleIndex() const {
323  for (int i = 0; i < visibleItems.count(); ++i) {
324  FxGridItem *item = visibleItems.at(i);
325  if (item->index != -1)
326  return item->index;
327  }
328  return -1;
329  }
330 
331  // Map a model index to visibleItems list index.
332  // These may differ if removed items are still present in the visible list,
333  // e.g. doing a removal animation
334  int mapFromModel(int modelIndex) const {
335  if (modelIndex < visibleIndex || modelIndex >= visibleIndex + visibleItems.count())
336  return -1;
337  for (int i = 0; i < visibleItems.count(); ++i) {
338  FxGridItem *listItem = visibleItems.at(i);
339  if (listItem->index == modelIndex)
340  return i + visibleIndex;
341  if (listItem->index > modelIndex)
342  return -1;
343  }
344  return -1; // Not in visibleList
345  }
346 
347  qreal snapPosAt(qreal pos) const {
348  Q_Q(const QDeclarativeGridView);
349  qreal snapPos = 0;
350  if (!visibleItems.isEmpty()) {
351  qreal highlightStart = isRightToLeftTopToBottom() && highlightRangeStartValid ? size()-highlightRangeEnd : highlightRangeStart;
352  pos += highlightStart;
353  pos += rowSize()/2;
354  snapPos = visibleItems.first()->rowPos() - visibleIndex / columns * rowSize();
355  snapPos = pos - fmodf(pos - snapPos, qreal(rowSize()));
356  snapPos -= highlightStart;
357  qreal maxExtent;
358  qreal minExtent;
359  if (isRightToLeftTopToBottom()) {
360  maxExtent = q->minXExtent();
361  minExtent = q->maxXExtent();
362  } else {
363  maxExtent = flow == QDeclarativeGridView::LeftToRight ? -q->maxYExtent() : -q->maxXExtent();
364  minExtent = flow == QDeclarativeGridView::LeftToRight ? -q->minYExtent() : -q->minXExtent();
365  }
366  if (snapPos > maxExtent)
367  snapPos = maxExtent;
368  if (snapPos < minExtent)
369  snapPos = minExtent;
370  }
371  return snapPos;
372  }
373 
375  for (int i = 0; i < visibleItems.count(); ++i) {
376  FxGridItem *item = visibleItems[i];
377  if (item->index == -1)
378  continue;
379  qreal itemTop = item->rowPos();
380  if (itemTop+rowSize()/2 >= pos && itemTop - rowSize()/2 <= pos)
381  return item;
382  }
383  return 0;
384  }
385 
386  int snapIndex() {
387  int index = currentIndex;
388  for (int i = 0; i < visibleItems.count(); ++i) {
389  FxGridItem *item = visibleItems[i];
390  if (item->index == -1)
391  continue;
392  qreal itemTop = item->rowPos();
393  if (itemTop >= highlight->rowPos()-rowSize()/2 && itemTop < highlight->rowPos()+rowSize()/2) {
394  index = item->index;
395  if (item->colPos() >= highlight->colPos()-colSize()/2 && item->colPos() < highlight->colPos()+colSize()/2)
396  return item->index;
397  }
398  }
399  return index;
400  }
401 
402  qreal headerSize() const {
403  if (!header)
404  return 0.0;
405 
406  return flow == QDeclarativeGridView::LeftToRight
407  ? header->item->height()
408  : header->item->width();
409  }
410 
411 
412  virtual void itemGeometryChanged(QDeclarativeItem *item, const QRectF &newGeometry, const QRectF &oldGeometry) {
413  Q_Q(const QDeclarativeGridView);
414  QDeclarativeFlickablePrivate::itemGeometryChanged(item, newGeometry, oldGeometry);
415  if (item == q) {
416  if (newGeometry.height() != oldGeometry.height()
417  || newGeometry.width() != oldGeometry.width()) {
418  if (q->isComponentComplete()) {
419  updateGrid();
420  scheduleLayout();
421  }
422  }
423  } else if ((header && header->item == item) || (footer && footer->item == item)) {
424  if (header)
425  updateHeader();
426  if (footer)
427  updateFooter();
428  }
429  }
430 
431  void positionViewAtIndex(int index, int mode);
432  virtual void fixup(AxisData &data, qreal minExtent, qreal maxExtent);
433  virtual void flick(AxisData &data, qreal minExtent, qreal maxExtent, qreal vSize,
434  QDeclarativeTimeLineCallback::Callback fixupCallback, qreal velocity);
435 
436  // for debugging only
437  void checkVisible() const {
438  int skip = 0;
439  for (int i = 0; i < visibleItems.count(); ++i) {
440  FxGridItem *listItem = visibleItems.at(i);
441  if (listItem->index == -1) {
442  ++skip;
443  } else if (listItem->index != visibleIndex + i - skip) {
444  for (int j = 0; j < visibleItems.count(); j++)
445  qDebug() << " index" << j << "item index" << visibleItems.at(j)->index;
446  qFatal("index %d %d %d", visibleIndex, i, listItem->index);
447  }
448  }
449  }
450 
462  int columns;
473  enum MovementReason { Other, SetIndex, Mouse };
475  int buffer;
483  enum BufferMode { NoBuffer = 0x00, BufferBefore = 0x01, BufferAfter = 0x02 };
486 
487  bool ownModel : 1;
488  bool wrap : 1;
489  bool autoHighlight : 1;
491  bool lazyRelease : 1;
492  bool layoutScheduled : 1;
493  bool deferredRelease : 1;
496 };
497 
499 {
501  QObject::connect(q, SIGNAL(movementEnded()), q, SLOT(animStopped()));
503  q->setFlickableDirection(QDeclarativeFlickable::VerticalFlick);
504  addItemChangeListener(this, Geometry);
505 }
506 
508 {
509  for (int i = 0; i < visibleItems.count(); ++i)
510  releaseItem(visibleItems.at(i));
511  visibleItems.clear();
512  visibleIndex = 0;
513  releaseItem(currentItem);
514  currentItem = 0;
515  createHighlight();
516  trackedItem = 0;
517  itemCount = 0;
518 }
519 
521 {
523  // create object
524  requestedIndex = modelIndex;
525  FxGridItem *listItem = 0;
526  if (QDeclarativeItem *item = model->item(modelIndex, false)) {
527  listItem = new FxGridItem(item, q);
528  listItem->index = modelIndex;
529  if (model->completePending()) {
530  // complete
531  listItem->item->setZValue(1);
532  listItem->item->setParentItem(q->contentItem());
533  model->completeItem();
534  } else {
535  listItem->item->setParentItem(q->contentItem());
536  }
537  unrequestedItems.remove(listItem->item);
538  }
539  requestedIndex = -1;
540  return listItem;
541 }
542 
543 
545 {
547  if (!item || !model)
548  return;
549  if (trackedItem == item) {
550  QObject::disconnect(trackedItem->item, SIGNAL(yChanged()), q, SLOT(trackedPositionChanged()));
551  QObject::disconnect(trackedItem->item, SIGNAL(xChanged()), q, SLOT(trackedPositionChanged()));
552  trackedItem = 0;
553  }
554  if (model->release(item->item) == 0) {
555  // item was not destroyed, and we no longer reference it.
556  unrequestedItems.insert(item->item, model->indexOf(item->item, q));
557  }
558  delete item;
559 }
560 
562 {
564  QDeclarativeItem *item = 0;
565  QDeclarativeContext *creationContext = component->creationContext();
567  creationContext ? creationContext : qmlContext(q));
568  QObject *nobj = component->create(context);
569  if (nobj) {
570  QDeclarative_setParent_noEvent(context, nobj);
571  item = qobject_cast<QDeclarativeItem *>(nobj);
572  if (!item)
573  delete nobj;
574  } else {
575  delete context;
576  }
577 
578  return item;
579 }
580 
581 void QDeclarativeGridViewPrivate::refill(qreal from, qreal to, bool doBuffer)
582 {
584  if (!isValid() || !q->isComponentComplete())
585  return;
586  itemCount = model->count();
587  qreal bufferFrom = from - buffer;
588  qreal bufferTo = to + buffer;
589  qreal fillFrom = from;
590  qreal fillTo = to;
591  if (doBuffer && (bufferMode & BufferAfter))
592  fillTo = bufferTo;
593  if (doBuffer && (bufferMode & BufferBefore))
594  fillFrom = bufferFrom;
595 
596  bool changed = false;
597 
598  int colPos = colPosAt(visibleIndex);
599  int rowPos = rowPosAt(visibleIndex);
600  int modelIndex = visibleIndex;
601  if (visibleItems.count()) {
602  rowPos = visibleItems.last()->rowPos();
603  colPos = visibleItems.last()->colPos() + colSize();
604  if (colPos > colSize() * (columns-1)) {
605  colPos = 0;
606  rowPos += rowSize();
607  }
608  int i = visibleItems.count() - 1;
609  while (i > 0 && visibleItems.at(i)->index == -1)
610  --i;
611  modelIndex = visibleItems.at(i)->index + 1;
612  }
613 
614  if (visibleItems.count() && (fillFrom > rowPos + rowSize()*2
615  || fillTo < rowPosAt(visibleIndex) - rowSize())) {
616  // We've jumped more than a page. Estimate which items are now
617  // visible and fill from there.
618  int count = (fillFrom - (rowPos + rowSize())) / (rowSize()) * columns;
619  for (int i = 0; i < visibleItems.count(); ++i)
620  releaseItem(visibleItems.at(i));
621  visibleItems.clear();
622  modelIndex += count;
623  if (modelIndex >= model->count())
624  modelIndex = model->count() - 1;
625  else if (modelIndex < 0)
626  modelIndex = 0;
627  modelIndex = modelIndex / columns * columns;
628  visibleIndex = modelIndex;
629  colPos = colPosAt(visibleIndex);
630  rowPos = rowPosAt(visibleIndex);
631  }
632 
633  int colNum = colPos / colSize();
634 
635  FxGridItem *item = 0;
636 
637  // Item creation and release is staggered in order to avoid
638  // creating/releasing multiple items in one frame
639  // while flicking (as much as possible).
640  while (modelIndex < model->count() && rowPos <= fillTo + rowSize()*(columns - colNum)/(columns+1)) {
641 // qDebug() << "refill: append item" << modelIndex;
642  if (!(item = createItem(modelIndex)))
643  break;
644  item->setPosition(colPos, rowPos);
645  visibleItems.append(item);
646  colPos += colSize();
647  colNum++;
648  if (colPos > colSize() * (columns-1)) {
649  colPos = 0;
650  colNum = 0;
651  rowPos += rowSize();
652  }
653  ++modelIndex;
654  changed = true;
655  if (doBuffer) // never buffer more than one item per frame
656  break;
657  }
658 
659  if (visibleItems.count()) {
660  rowPos = visibleItems.first()->rowPos();
661  colPos = visibleItems.first()->colPos() - colSize();
662  if (colPos < 0) {
663  colPos = colSize() * (columns - 1);
664  rowPos -= rowSize();
665  }
666  }
667  colNum = colPos / colSize();
668  while (visibleIndex > 0 && rowPos + rowSize() - 1 >= fillFrom - rowSize()*(colNum+1)/(columns+1)){
669 // qDebug() << "refill: prepend item" << visibleIndex-1 << "top pos" << rowPos << colPos;
670  if (!(item = createItem(visibleIndex-1)))
671  break;
672  --visibleIndex;
673  item->setPosition(colPos, rowPos);
674  visibleItems.prepend(item);
675  colPos -= colSize();
676  colNum--;
677  if (colPos < 0) {
678  colPos = colSize() * (columns - 1);
679  colNum = columns-1;
680  rowPos -= rowSize();
681  }
682  changed = true;
683  if (doBuffer) // never buffer more than one item per frame
684  break;
685  }
686 
687  if (!lazyRelease || !changed || deferredRelease) { // avoid destroying items in the same frame that we create
688  while (visibleItems.count() > 1
689  && (item = visibleItems.first())
690  && item->rowPos()+rowSize()-1 < bufferFrom - rowSize()*(item->colPos()/colSize()+1)/(columns+1)) {
691  if (item->attached->delayRemove())
692  break;
693 // qDebug() << "refill: remove first" << visibleIndex << "top end pos" << item->endRowPos();
694  if (item->index != -1)
695  visibleIndex++;
696  visibleItems.removeFirst();
697  releaseItem(item);
698  changed = true;
699  }
700  while (visibleItems.count() > 1
701  && (item = visibleItems.last())
702  && item->rowPos() > bufferTo + rowSize()*(columns - item->colPos()/colSize())/(columns+1)) {
703  if (item->attached->delayRemove())
704  break;
705 // qDebug() << "refill: remove last" << visibleIndex+visibleItems.count()-1;
706  visibleItems.removeLast();
707  releaseItem(item);
708  changed = true;
709  }
710  deferredRelease = false;
711  } else {
712  deferredRelease = true;
713  }
714  if (changed) {
715  if (header)
716  updateHeader();
717  if (footer)
718  updateFooter();
720  q->setContentHeight(endPosition() - startPosition());
721  else
722  q->setContentWidth(endPosition() - startPosition());
723  } else if (!doBuffer && buffer && bufferMode != NoBuffer) {
724  refill(from, to, true);
725  }
726  lazyRelease = false;
727 }
728 
730 {
732 
733  columns = (int)qMax((flow == QDeclarativeGridView::LeftToRight ? q->width() : q->height()) / colSize(), qreal(1.));
734  if (isValid()) {
736  q->setContentHeight(endPosition() - startPosition());
737  else
738  q->setContentWidth(lastPosition() - originPosition());
739  }
740 }
741 
743 {
745  if (!layoutScheduled) {
746  layoutScheduled = true;
748  }
749 }
750 
752 {
754  layoutScheduled = false;
755  if (!isValid() && !visibleItems.count()) {
756  clear();
757  return;
758  }
759  if (visibleItems.count()) {
760  qreal rowPos = visibleItems.first()->rowPos();
761  qreal colPos = visibleItems.first()->colPos();
762  int col = visibleIndex % columns;
763  if (colPos != col * colSize()) {
764  colPos = col * colSize();
765  visibleItems.first()->setPosition(colPos, rowPos);
766  }
767  for (int i = 1; i < visibleItems.count(); ++i) {
768  FxGridItem *item = visibleItems.at(i);
769  colPos += colSize();
770  if (colPos > colSize() * (columns-1)) {
771  colPos = 0;
772  rowPos += rowSize();
773  }
774  item->setPosition(colPos, rowPos);
775  }
776  }
777  if (header)
778  updateHeader();
779  if (footer)
780  updateFooter();
781  q->refill();
782  updateHighlight();
783  moveReason = Other;
784  if (flow == QDeclarativeGridView::LeftToRight) {
785  q->setContentHeight(endPosition() - startPosition());
786  fixupY();
787  } else {
788  q->setContentWidth(endPosition() - startPosition());
789  fixupX();
790  }
791  updateUnrequestedPositions();
792 }
793 
795 {
798  for (it = unrequestedItems.begin(); it != unrequestedItems.end(); ++it)
799  *it = model->indexOf(it.key(), q);
800 }
801 
803 {
805  for (it = unrequestedItems.begin(); it != unrequestedItems.end(); ++it) {
806  QDeclarativeItem *item = it.key();
807  if (flow == QDeclarativeGridView::LeftToRight) {
808  item->setPos(QPointF(colPosAt(*it), rowPosAt(*it)));
809  } else {
810  if (isRightToLeftTopToBottom())
811  item->setPos(QPointF(-rowPosAt(*it)-item->width(), colPosAt(*it)));
812  else
813  item->setPos(QPointF(rowPosAt(*it), colPosAt(*it)));
814  }
815  }
816 }
817 
819 {
821  FxGridItem *item = currentItem;
822  if (highlight)
823  item = highlight;
824 
825  if (trackedItem && item != trackedItem) {
826  QObject::disconnect(trackedItem->item, SIGNAL(yChanged()), q, SLOT(trackedPositionChanged()));
827  QObject::disconnect(trackedItem->item, SIGNAL(xChanged()), q, SLOT(trackedPositionChanged()));
828  trackedItem = 0;
829  }
830 
831  if (!trackedItem && item) {
832  trackedItem = item;
833  QObject::connect(trackedItem->item, SIGNAL(yChanged()), q, SLOT(trackedPositionChanged()));
834  QObject::connect(trackedItem->item, SIGNAL(xChanged()), q, SLOT(trackedPositionChanged()));
835  }
836  if (trackedItem)
837  q->trackedPositionChanged();
838 }
839 
841 {
843  bool changed = false;
844  if (highlight) {
845  if (trackedItem == highlight)
846  trackedItem = 0;
847  if (highlight->item->scene())
848  highlight->item->scene()->removeItem(highlight->item);
849  highlight->item->deleteLater();
850  delete highlight;
851  highlight = 0;
852  delete highlightXAnimator;
853  delete highlightYAnimator;
854  highlightXAnimator = 0;
855  highlightYAnimator = 0;
856  changed = true;
857  }
858 
859  if (currentItem) {
860  QDeclarativeItem *item = 0;
861  if (highlightComponent) {
862  item = createComponentItem(highlightComponent);
863  } else {
864  item = new QDeclarativeItem;
865  QDeclarative_setParent_noEvent(item, q->contentItem());
866  item->setParentItem(q->contentItem());
867  }
868  if (item) {
869  QDeclarative_setParent_noEvent(item, q->contentItem());
870  item->setParentItem(q->contentItem());
871  highlight = new FxGridItem(item, q);
872  if (currentItem && autoHighlight)
873  highlight->setPosition(currentItem->colPos(), currentItem->rowPos());
874  highlightXAnimator = new QSmoothedAnimation(q);
875  highlightXAnimator->target = QDeclarativeProperty(highlight->item, QLatin1String("x"));
876  highlightXAnimator->userDuration = highlightMoveDuration;
877  highlightYAnimator = new QSmoothedAnimation(q);
878  highlightYAnimator->target = QDeclarativeProperty(highlight->item, QLatin1String("y"));
879  highlightYAnimator->userDuration = highlightMoveDuration;
880  if (autoHighlight) {
881  highlightXAnimator->restart();
882  highlightYAnimator->restart();
883  }
884  changed = true;
885  }
886  }
887  if (changed)
888  emit q->highlightItemChanged();
889 }
890 
892 {
893  if ((!currentItem && highlight) || (currentItem && !highlight))
894  createHighlight();
895  if (currentItem && autoHighlight && highlight && !hData.moving && !vData.moving) {
896  // auto-update highlight
897  highlightXAnimator->to = currentItem->item->x();
898  highlightYAnimator->to = currentItem->item->y();
899  highlight->item->setWidth(currentItem->item->width());
900  highlight->item->setHeight(currentItem->item->height());
901  highlightXAnimator->restart();
902  highlightYAnimator->restart();
903  }
904  updateTrackedItem();
905 }
906 
908 {
910  if (!q->isComponentComplete() || !isValid() || modelIndex < 0 || modelIndex >= model->count()) {
911  if (currentItem) {
912  currentItem->attached->setIsCurrentItem(false);
913  releaseItem(currentItem);
914  currentItem = 0;
915  currentIndex = modelIndex;
916  emit q->currentIndexChanged();
917  updateHighlight();
918  } else if (currentIndex != modelIndex) {
919  currentIndex = modelIndex;
920  emit q->currentIndexChanged();
921  }
922  return;
923  }
924 
925  if (currentItem && currentIndex == modelIndex) {
926  updateHighlight();
927  return;
928  }
929 
930  FxGridItem *oldCurrentItem = currentItem;
931  currentIndex = modelIndex;
932  currentItem = createItem(modelIndex);
933  fixCurrentVisibility = true;
934  if (oldCurrentItem && (!currentItem || oldCurrentItem->item != currentItem->item))
935  oldCurrentItem->attached->setIsCurrentItem(false);
936  if (currentItem) {
937  currentItem->setPosition(colPosAt(modelIndex), rowPosAt(modelIndex));
938  currentItem->item->setFocus(true);
939  currentItem->attached->setIsCurrentItem(true);
940  }
941  updateHighlight();
942  emit q->currentIndexChanged();
943  releaseItem(oldCurrentItem);
944 }
945 
947 {
949  if (!footer && footerComponent) {
950  QDeclarativeItem *item = createComponentItem(footerComponent);
951  if (item) {
952  QDeclarative_setParent_noEvent(item, q->contentItem());
953  item->setParentItem(q->contentItem());
954  item->setZValue(1);
957  footer = new FxGridItem(item, q);
958  }
959  }
960  if (footer) {
961  qreal colOffset = 0;
962  qreal rowOffset;
963  if (isRightToLeftTopToBottom()) {
964  rowOffset = footer->item->width()-cellWidth;
965  } else {
966  rowOffset = 0;
967  if (q->effectiveLayoutDirection() == Qt::RightToLeft)
968  colOffset = footer->item->width()-cellWidth;
969  }
970  if (visibleItems.count()) {
971  qreal endPos = lastPosition();
972  if (lastVisibleIndex() == model->count()-1) {
973  footer->setPosition(colOffset, endPos + rowOffset);
974  } else {
975  qreal visiblePos = isRightToLeftTopToBottom() ? -position() : position() + size();
976  if (endPos <= visiblePos || footer->endRowPos() < endPos + rowOffset)
977  footer->setPosition(colOffset, endPos + rowOffset);
978  }
979  } else {
980  qreal endPos = 0;
981  if (header) {
982  endPos += flow == QDeclarativeGridView::LeftToRight ? header->item->height() : header->item->width();
983  }
984  footer->setPosition(colOffset, endPos);
985  }
986  }
987 }
988 
990 {
992  if (!header && headerComponent) {
993  QDeclarativeItem *item = createComponentItem(headerComponent);
994  if (item) {
995  QDeclarative_setParent_noEvent(item, q->contentItem());
996  item->setParentItem(q->contentItem());
997  item->setZValue(1);
1000  header = new FxGridItem(item, q);
1001  }
1002  }
1003  if (header) {
1004  qreal colOffset = 0;
1005  qreal rowOffset;
1006  if (isRightToLeftTopToBottom()) {
1007  rowOffset = -cellWidth;
1008  } else {
1009  rowOffset = -headerSize();
1010  if (q->effectiveLayoutDirection() == Qt::RightToLeft)
1011  colOffset = header->item->width()-cellWidth;
1012  }
1013  if (visibleItems.count()) {
1014  qreal startPos = originPosition();
1015  if (visibleIndex == 0) {
1016  header->setPosition(colOffset, startPos + rowOffset);
1017  } else {
1018  qreal tempPos = isRightToLeftTopToBottom() ? -position()-size() : position();
1019  qreal headerPos = isRightToLeftTopToBottom() ? header->rowPos() + cellWidth - headerSize() : header->rowPos();
1020  if (tempPos <= startPos || headerPos > startPos + rowOffset)
1021  header->setPosition(colOffset, startPos + rowOffset);
1022  }
1023  } else {
1024  header->setPosition(colOffset, 0);
1025  }
1026  }
1027 }
1028 
1030 {
1031  moveReason = Other;
1033  fixupY();
1034  else
1035  fixupX();
1036 }
1037 
1039 {
1040  if ((flow == QDeclarativeGridView::TopToBottom && &data == &vData)
1041  || (flow == QDeclarativeGridView::LeftToRight && &data == &hData))
1042  return;
1043 
1044  fixupMode = moveReason == Mouse ? fixupMode : Immediate;
1045 
1046  qreal highlightStart;
1047  qreal highlightEnd;
1048  qreal viewPos;
1049  if (isRightToLeftTopToBottom()) {
1050  // Handle Right-To-Left exceptions
1051  viewPos = -position()-size();
1052  highlightStart = highlightRangeStartValid ? size()-highlightRangeEnd : highlightRangeStart;
1053  highlightEnd = highlightRangeEndValid ? size()-highlightRangeStart : highlightRangeEnd;
1054  } else {
1055  viewPos = position();
1056  highlightStart = highlightRangeStart;
1057  highlightEnd = highlightRangeEnd;
1058  }
1059 
1060  bool strictHighlightRange = haveHighlightRange && highlightRange == QDeclarativeGridView::StrictlyEnforceRange;
1061 
1062  if (snapMode != QDeclarativeGridView::NoSnap) {
1063  qreal tempPosition = isRightToLeftTopToBottom() ? -position()-size() : position();
1064  if (snapMode == QDeclarativeGridView::SnapOneRow && moveReason == Mouse) {
1065  // if we've been dragged < rowSize()/2 then bias towards the next row
1066  qreal dist = data.move.value() - (data.pressPos - data.dragStartOffset);
1067  qreal bias = 0;
1068  if (data.velocity > 0 && dist > QML_FLICK_SNAPONETHRESHOLD && dist < rowSize()/2)
1069  bias = rowSize()/2;
1070  else if (data.velocity < 0 && dist < -QML_FLICK_SNAPONETHRESHOLD && dist > -rowSize()/2)
1071  bias = -rowSize()/2;
1072  if (isRightToLeftTopToBottom())
1073  bias = -bias;
1074  tempPosition -= bias;
1075  }
1076  FxGridItem *topItem = snapItemAt(tempPosition+highlightStart);
1077  if (!topItem && strictHighlightRange && currentItem) {
1078  // StrictlyEnforceRange always keeps an item in range
1079  updateHighlight();
1080  topItem = currentItem;
1081  }
1082  FxGridItem *bottomItem = snapItemAt(tempPosition+highlightEnd);
1083  if (!bottomItem && strictHighlightRange && currentItem) {
1084  // StrictlyEnforceRange always keeps an item in range
1085  updateHighlight();
1086  bottomItem = currentItem;
1087  }
1088  qreal pos;
1089  bool isInBounds = -position() > maxExtent && -position() <= minExtent;
1090  if (topItem && (isInBounds || strictHighlightRange)) {
1091  if (topItem->index == 0 && header && tempPosition+highlightStart < header->rowPos()+headerSize()/2 && !strictHighlightRange) {
1092  pos = isRightToLeftTopToBottom() ? - header->rowPos() + highlightStart - size() : header->rowPos() - highlightStart;
1093  } else {
1094  if (isRightToLeftTopToBottom())
1095  pos = qMax(qMin(-topItem->rowPos() + highlightStart - size(), -maxExtent), -minExtent);
1096  else
1097  pos = qMax(qMin(topItem->rowPos() - highlightStart, -maxExtent), -minExtent);
1098  }
1099  } else if (bottomItem && isInBounds) {
1100  if (isRightToLeftTopToBottom())
1101  pos = qMax(qMin(-bottomItem->rowPos() + highlightEnd - size(), -maxExtent), -minExtent);
1102  else
1103  pos = qMax(qMin(bottomItem->rowPos() - highlightEnd, -maxExtent), -minExtent);
1104  } else {
1105  QDeclarativeFlickablePrivate::fixup(data, minExtent, maxExtent);
1106  return;
1107  }
1108  qreal dist = qAbs(data.move + pos);
1109  if (dist > 0) {
1110  timeline.reset(data.move);
1111  if (fixupMode != Immediate) {
1112  timeline.move(data.move, -pos, QEasingCurve(QEasingCurve::InOutQuad), fixupDuration/2);
1113  data.fixingUp = true;
1114  } else {
1115  timeline.set(data.move, -pos);
1116  }
1117  vTime = timeline.time();
1118  }
1119  } else if (haveHighlightRange && highlightRange == QDeclarativeGridView::StrictlyEnforceRange) {
1120  if (currentItem) {
1121  updateHighlight();
1122  qreal pos = currentItem->rowPos();
1123  if (viewPos < pos + rowSize() - highlightEnd)
1124  viewPos = pos + rowSize() - highlightEnd;
1125  if (viewPos > pos - highlightStart)
1126  viewPos = pos - highlightStart;
1127  if (isRightToLeftTopToBottom())
1128  viewPos = -viewPos-size();
1129  timeline.reset(data.move);
1130  if (viewPos != position()) {
1131  if (fixupMode != Immediate) {
1132  timeline.move(data.move, -viewPos, QEasingCurve(QEasingCurve::InOutQuad), fixupDuration/2);
1133  data.fixingUp = true;
1134  } else {
1135  timeline.set(data.move, -viewPos);
1136  }
1137  }
1138  vTime = timeline.time();
1139  }
1140  } else {
1141  QDeclarativeFlickablePrivate::fixup(data, minExtent, maxExtent);
1142  }
1143  data.inOvershoot = false;
1144  fixupMode = Normal;
1145 }
1146 
1148  QDeclarativeTimeLineCallback::Callback fixupCallback, qreal velocity)
1149 {
1151  data.fixingUp = false;
1152  moveReason = Mouse;
1153  if ((!haveHighlightRange || highlightRange != QDeclarativeGridView::StrictlyEnforceRange)
1154  && snapMode == QDeclarativeGridView::NoSnap) {
1155  QDeclarativeFlickablePrivate::flick(data, minExtent, maxExtent, vSize, fixupCallback, velocity);
1156  return;
1157  }
1158  qreal maxDistance = 0;
1159  qreal dataValue = isRightToLeftTopToBottom() ? -data.move.value()+size() : data.move.value();
1160  // -ve velocity means list is moving up/left
1161  if (velocity > 0) {
1162  if (data.move.value() < minExtent) {
1163  if (snapMode == QDeclarativeGridView::SnapOneRow) {
1164  // if we've been dragged < averageSize/2 then bias towards the next item
1165  qreal dist = data.move.value() - (data.pressPos - data.dragStartOffset);
1166  qreal bias = dist < rowSize()/2 ? rowSize()/2 : 0;
1167  if (isRightToLeftTopToBottom())
1168  bias = -bias;
1169  data.flickTarget = -snapPosAt(-dataValue - bias);
1170  maxDistance = qAbs(data.flickTarget - data.move.value());
1171  velocity = maxVelocity;
1172  } else {
1173  maxDistance = qAbs(minExtent - data.move.value());
1174  }
1175  }
1176  if (snapMode == QDeclarativeGridView::NoSnap && highlightRange != QDeclarativeGridView::StrictlyEnforceRange)
1177  data.flickTarget = minExtent;
1178  } else {
1179  if (data.move.value() > maxExtent) {
1180  if (snapMode == QDeclarativeGridView::SnapOneRow) {
1181  // if we've been dragged < averageSize/2 then bias towards the next item
1182  qreal dist = data.move.value() - (data.pressPos - data.dragStartOffset);
1183  qreal bias = -dist < rowSize()/2 ? rowSize()/2 : 0;
1184  if (isRightToLeftTopToBottom())
1185  bias = -bias;
1186  data.flickTarget = -snapPosAt(-dataValue + bias);
1187  maxDistance = qAbs(data.flickTarget - data.move.value());
1188  velocity = -maxVelocity;
1189  } else {
1190  maxDistance = qAbs(maxExtent - data.move.value());
1191  }
1192  }
1193  if (snapMode == QDeclarativeGridView::NoSnap && highlightRange != QDeclarativeGridView::StrictlyEnforceRange)
1194  data.flickTarget = maxExtent;
1195  }
1196 
1197  bool overShoot = boundsBehavior == QDeclarativeFlickable::DragAndOvershootBounds;
1198 
1199  if (maxDistance > 0 || overShoot) {
1200  // This mode requires the grid to stop exactly on a row boundary.
1201  qreal v = velocity;
1202  if (maxVelocity != -1 && maxVelocity < qAbs(v)) {
1203  if (v < 0)
1204  v = -maxVelocity;
1205  else
1206  v = maxVelocity;
1207  }
1208  qreal accel = deceleration;
1209  qreal v2 = v * v;
1210  qreal overshootDist = qreal(0.0);
1211  if ((maxDistance > qreal(0.0) && v2 / (2.0f * maxDistance) < accel) || snapMode == QDeclarativeGridView::SnapOneRow) {
1212  // + rowSize()/4 to encourage moving at least one item in the flick direction
1213  qreal dist = v2 / (accel * qreal(2.0)) + rowSize()/4;
1214  dist = qMin(dist, maxDistance);
1215  if (v > 0)
1216  dist = -dist;
1217  if (snapMode != QDeclarativeGridView::SnapOneRow) {
1218  qreal distTemp = isRightToLeftTopToBottom() ? -dist : dist;
1219  data.flickTarget = -snapPosAt(-dataValue + distTemp);
1220  }
1221  data.flickTarget = isRightToLeftTopToBottom() ? -data.flickTarget+size() : data.flickTarget;
1222  if (overShoot) {
1223  if (data.flickTarget >= minExtent) {
1224  overshootDist = overShootDistance(vSize);
1225  data.flickTarget += overshootDist;
1226  } else if (data.flickTarget <= maxExtent) {
1227  overshootDist = overShootDistance(vSize);
1228  data.flickTarget -= overshootDist;
1229  }
1230  }
1231  qreal adjDist = -data.flickTarget + data.move.value();
1232  if (qAbs(adjDist) > qAbs(dist)) {
1233  // Prevent painfully slow flicking - adjust velocity to suit flickDeceleration
1234  qreal adjv2 = accel * 2.0f * qAbs(adjDist);
1235  if (adjv2 > v2) {
1236  v2 = adjv2;
1237  v = qSqrt(v2);
1238  if (dist > 0)
1239  v = -v;
1240  }
1241  }
1242  dist = adjDist;
1243  accel = v2 / (2.0f * qAbs(dist));
1244  } else {
1245  data.flickTarget = velocity > 0 ? minExtent : maxExtent;
1246  overshootDist = overShoot ? overShootDistance(vSize) : 0;
1247  }
1248  timeline.reset(data.move);
1249  timeline.accel(data.move, v, accel, maxDistance + overshootDist);
1250  timeline.callback(QDeclarativeTimeLineCallback(&data.move, fixupCallback, this));
1251  if (!hData.flicking && q->xflick()) {
1252  hData.flicking = true;
1253  emit q->flickingChanged();
1254  emit q->flickingHorizontallyChanged();
1255  emit q->flickStarted();
1256  }
1257  if (!vData.flicking && q->yflick()) {
1258  vData.flicking = true;
1259  emit q->flickingChanged();
1260  emit q->flickingVerticallyChanged();
1261  emit q->flickStarted();
1262  }
1263  } else {
1264  timeline.reset(data.move);
1265  fixup(data, minExtent, maxExtent);
1266  }
1267 }
1268 
1269 
1270 //----------------------------------------------------------------------------
1271 
1351 {
1353  d->init();
1354 }
1355 
1357 {
1359  d->clear();
1360  if (d->ownModel)
1361  delete d->model;
1362  delete d->header;
1363  delete d->footer;
1364 }
1365 
1438 {
1439  Q_D(const QDeclarativeGridView);
1440  return d->modelVariant;
1441 }
1442 
1443 // For internal use
1445 {
1446  Q_D(const QDeclarativeGridView);
1447  return d->model->count();
1448 }
1449 
1451 {
1453  if (d->modelVariant == model)
1454  return;
1455  if (d->model) {
1456  disconnect(d->model, SIGNAL(itemsInserted(int,int)), this, SLOT(itemsInserted(int,int)));
1457  disconnect(d->model, SIGNAL(itemsRemoved(int,int)), this, SLOT(itemsRemoved(int,int)));
1458  disconnect(d->model, SIGNAL(itemsMoved(int,int,int)), this, SLOT(itemsMoved(int,int,int)));
1459  disconnect(d->model, SIGNAL(modelReset()), this, SLOT(modelReset()));
1462  }
1463  d->clear();
1464  d->modelVariant = model;
1465  QObject *object = qvariant_cast<QObject*>(model);
1466  QDeclarativeVisualModel *vim = 0;
1467  if (object && (vim = qobject_cast<QDeclarativeVisualModel *>(object))) {
1468  if (d->ownModel) {
1469  delete d->model;
1470  d->ownModel = false;
1471  }
1472  d->model = vim;
1473  } else {
1474  if (!d->ownModel) {
1475  d->model = new QDeclarativeVisualDataModel(qmlContext(this), this);
1476  d->ownModel = true;
1477  }
1478  if (QDeclarativeVisualDataModel *dataModel = qobject_cast<QDeclarativeVisualDataModel*>(d->model))
1479  dataModel->setModel(model);
1480  }
1481  if (d->model) {
1483  if (isComponentComplete()) {
1484  refill();
1485  if ((d->currentIndex >= d->model->count() || d->currentIndex < 0) && !d->currentIndexCleared) {
1486  setCurrentIndex(0);
1487  } else {
1489  d->updateCurrent(d->currentIndex);
1490  if (d->highlight && d->currentItem) {
1491  if (d->autoHighlight)
1492  d->highlight->setPosition(d->currentItem->colPos(), d->currentItem->rowPos());
1493  d->updateTrackedItem();
1494  }
1495  d->moveReason = QDeclarativeGridViewPrivate::Other;
1496  }
1497  }
1498  connect(d->model, SIGNAL(itemsInserted(int,int)), this, SLOT(itemsInserted(int,int)));
1499  connect(d->model, SIGNAL(itemsRemoved(int,int)), this, SLOT(itemsRemoved(int,int)));
1500  connect(d->model, SIGNAL(itemsMoved(int,int,int)), this, SLOT(itemsMoved(int,int,int)));
1501  connect(d->model, SIGNAL(modelReset()), this, SLOT(modelReset()));
1504  emit countChanged();
1505  }
1506  emit modelChanged();
1507 }
1508 
1531 {
1532  Q_D(const QDeclarativeGridView);
1533  if (d->model) {
1534  if (QDeclarativeVisualDataModel *dataModel = qobject_cast<QDeclarativeVisualDataModel*>(d->model))
1535  return dataModel->delegate();
1536  }
1537 
1538  return 0;
1539 }
1540 
1542 {
1544  if (delegate == this->delegate())
1545  return;
1546 
1547  if (!d->ownModel) {
1548  d->model = new QDeclarativeVisualDataModel(qmlContext(this));
1549  d->ownModel = true;
1550  }
1551  if (QDeclarativeVisualDataModel *dataModel = qobject_cast<QDeclarativeVisualDataModel*>(d->model)) {
1552  int oldCount = dataModel->count();
1553  dataModel->setDelegate(delegate);
1554  if (isComponentComplete()) {
1555  for (int i = 0; i < d->visibleItems.count(); ++i)
1556  d->releaseItem(d->visibleItems.at(i));
1557  d->visibleItems.clear();
1558  d->releaseItem(d->currentItem);
1559  d->currentItem = 0;
1560  refill();
1562  d->updateCurrent(d->currentIndex);
1563  if (d->highlight && d->currentItem) {
1564  if (d->autoHighlight)
1565  d->highlight->setPosition(d->currentItem->colPos(), d->currentItem->rowPos());
1566  d->updateTrackedItem();
1567  }
1568  d->moveReason = QDeclarativeGridViewPrivate::Other;
1569  }
1570  if (oldCount != dataModel->count())
1571  emit countChanged();
1573  }
1574 }
1575 
1595 {
1596  Q_D(const QDeclarativeGridView);
1597  return d->currentIndex;
1598 }
1599 
1601 {
1603  if (d->requestedIndex >= 0) // currently creating item
1604  return;
1605  d->currentIndexCleared = (index == -1);
1606  if (index == d->currentIndex)
1607  return;
1608  if (isComponentComplete() && d->isValid()) {
1609  if (d->layoutScheduled)
1610  d->layout();
1612  d->updateCurrent(index);
1613  } else {
1614  d->currentIndex = index;
1616  }
1617 }
1618 
1620 {
1622  if (!d->currentItem)
1623  return 0;
1624  return d->currentItem->item;
1625 }
1626 
1641 {
1643  if (!d->highlight)
1644  return 0;
1645  return d->highlight->item;
1646 }
1647 
1655 int QDeclarativeGridView::count() const
1656 {
1657  Q_D(const QDeclarativeGridView);
1658  if (d->model)
1659  return d->model->count();
1660  return 0;
1661 }
1662 
1677 {
1678  Q_D(const QDeclarativeGridView);
1679  return d->highlightComponent;
1680 }
1681 
1683 {
1685  if (highlight != d->highlightComponent) {
1686  d->highlightComponent = highlight;
1687  d->updateCurrent(d->currentIndex);
1689  }
1690 }
1691 
1709 {
1710  Q_D(const QDeclarativeGridView);
1711  return d->autoHighlight;
1712 }
1713 
1715 {
1717  if (d->autoHighlight != autoHighlight) {
1718  d->autoHighlight = autoHighlight;
1719  if (autoHighlight) {
1720  d->updateHighlight();
1721  } else if (d->highlightXAnimator) {
1722  d->highlightXAnimator->stop();
1723  d->highlightYAnimator->stop();
1724  }
1725  }
1726 }
1727 
1743 {
1744  Q_D(const QDeclarativeGridView);
1745  return d->highlightMoveDuration;
1746 }
1747 
1749 {
1751  if (d->highlightMoveDuration != duration) {
1752  d->highlightMoveDuration = duration;
1753  if (d->highlightYAnimator) {
1754  d->highlightXAnimator->userDuration = d->highlightMoveDuration;
1755  d->highlightYAnimator->userDuration = d->highlightMoveDuration;
1756  }
1758  }
1759 }
1760 
1761 
1796 {
1797  Q_D(const QDeclarativeGridView);
1798  return d->highlightRangeStart;
1799 }
1800 
1802 {
1804  d->highlightRangeStartValid = true;
1805  if (d->highlightRangeStart == start)
1806  return;
1807  d->highlightRangeStart = start;
1808  d->haveHighlightRange = d->highlightRange != NoHighlightRange && d->highlightRangeStart <= d->highlightRangeEnd;
1810 }
1811 
1813 {
1815  d->highlightRangeStartValid = false;
1816  if (d->highlightRangeStart == 0)
1817  return;
1818  d->highlightRangeStart = 0;
1820 }
1821 
1823 {
1824  Q_D(const QDeclarativeGridView);
1825  return d->highlightRangeEnd;
1826 }
1827 
1829 {
1831  d->highlightRangeEndValid = true;
1832  if (d->highlightRangeEnd == end)
1833  return;
1834  d->highlightRangeEnd = end;
1835  d->haveHighlightRange = d->highlightRange != NoHighlightRange && d->highlightRangeStart <= d->highlightRangeEnd;
1837 }
1838 
1840 {
1842  d->highlightRangeEndValid = false;
1843  if (d->highlightRangeEnd == 0)
1844  return;
1845  d->highlightRangeEnd = 0;
1847 }
1848 
1850 {
1851  Q_D(const QDeclarativeGridView);
1852  return d->highlightRange;
1853 }
1854 
1856 {
1858  if (d->highlightRange == mode)
1859  return;
1860  d->highlightRange = mode;
1861  d->haveHighlightRange = d->highlightRange != NoHighlightRange && d->highlightRangeStart <= d->highlightRangeEnd;
1863 }
1864 
1890 {
1891  Q_D(const QDeclarativeGridView);
1892  return d->layoutDirection;
1893 }
1894 
1896 {
1898  if (d->layoutDirection != layoutDirection) {
1899  d->layoutDirection = layoutDirection;
1900  d->regenerate();
1902  }
1903 }
1904 
1906 {
1907  Q_D(const QDeclarativeGridView);
1908  if (d->effectiveLayoutMirror)
1909  return d->layoutDirection == Qt::RightToLeft ? Qt::LeftToRight : Qt::RightToLeft;
1910  else
1911  return d->layoutDirection;
1912 }
1913 
1929 {
1930  Q_D(const QDeclarativeGridView);
1931  return d->flow;
1932 }
1933 
1935 {
1937  if (d->flow != flow) {
1938  d->flow = flow;
1939  if (d->flow == LeftToRight) {
1940  setContentWidth(-1);
1942  } else {
1943  setContentHeight(-1);
1945  }
1946  setContentX(0);
1947  setContentY(0);
1948  d->regenerate();
1949  emit flowChanged();
1950  }
1951 }
1952 
1967 {
1968  Q_D(const QDeclarativeGridView);
1969  return d->wrap;
1970 }
1971 
1973 {
1975  if (d->wrap == wrap)
1976  return;
1977  d->wrap = wrap;
1979 }
1980 
2004 {
2005  Q_D(const QDeclarativeGridView);
2006  return d->buffer;
2007 }
2008 
2010 {
2012  if (d->buffer != buffer) {
2013  d->buffer = buffer;
2014  if (isComponentComplete())
2015  refill();
2017  }
2018 }
2019 
2032 {
2033  Q_D(const QDeclarativeGridView);
2034  return d->cellWidth;
2035 }
2036 
2038 {
2040  if (cellWidth != d->cellWidth && cellWidth > 0) {
2041  d->cellWidth = qMax(1, cellWidth);
2042  d->updateGrid();
2044  d->layout();
2045  }
2046 }
2047 
2049 {
2050  Q_D(const QDeclarativeGridView);
2051  return d->cellHeight;
2052 }
2053 
2055 {
2057  if (cellHeight != d->cellHeight && cellHeight > 0) {
2058  d->cellHeight = qMax(1, cellHeight);
2059  d->updateGrid();
2061  d->layout();
2062  }
2063 }
2084 {
2085  Q_D(const QDeclarativeGridView);
2086  return d->snapMode;
2087 }
2088 
2090 {
2092  if (d->snapMode != mode) {
2093  d->snapMode = mode;
2095  }
2096 }
2097 
2111 {
2112  Q_D(const QDeclarativeGridView);
2113  return d->footerComponent;
2114 }
2115 
2117 {
2119  if (d->footerComponent != footer) {
2120  if (d->footer) {
2121  if (scene())
2122  scene()->removeItem(d->footer->item);
2123  d->footer->item->deleteLater();
2124  delete d->footer;
2125  d->footer = 0;
2126  }
2127  d->footerComponent = footer;
2128  if (isComponentComplete()) {
2129  d->updateFooter();
2130  d->updateGrid();
2131  d->fixupPosition();
2132  }
2133  emit footerChanged();
2134  }
2135 }
2136 
2150 {
2151  Q_D(const QDeclarativeGridView);
2152  return d->headerComponent;
2153 }
2154 
2156 {
2158  if (d->headerComponent != header) {
2159  if (d->header) {
2160  if (scene())
2161  scene()->removeItem(d->header->item);
2162  d->header->item->deleteLater();
2163  delete d->header;
2164  d->header = 0;
2165  }
2166  d->headerComponent = header;
2167  if (isComponentComplete()) {
2168  d->updateHeader();
2169  d->updateFooter();
2170  d->updateGrid();
2171  d->fixupPosition();
2172  }
2173  emit headerChanged();
2174  }
2175 }
2176 
2178 {
2180  // Positioning the view manually should override any current movement state
2181  d->moveReason = QDeclarativeGridViewPrivate::Other;
2183 }
2184 
2186 {
2188  // Positioning the view manually should override any current movement state
2189  d->moveReason = QDeclarativeGridViewPrivate::Other;
2191 }
2192 
2194 {
2196  if (event->type() == QEvent::User) {
2197  if (d->layoutScheduled)
2198  d->layout();
2199  return true;
2200  }
2201 
2202  return QDeclarativeFlickable::event(event);
2203 }
2204 
2206 {
2209  if (!d->itemCount)
2210  return;
2211  d->lazyRelease = true;
2212  if (d->hData.flicking || d->vData.flicking) {
2213  if (yflick()) {
2214  if (d->vData.velocity > 0)
2216  else if (d->vData.velocity < 0)
2218  }
2219 
2220  if (xflick()) {
2221  if (d->hData.velocity > 0)
2223  else if (d->hData.velocity < 0)
2225  }
2226  }
2227  refill();
2228  if (d->hData.flicking || d->vData.flicking || d->hData.moving || d->vData.moving)
2229  d->moveReason = QDeclarativeGridViewPrivate::Mouse;
2230  if (d->moveReason != QDeclarativeGridViewPrivate::SetIndex) {
2231  if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange && d->highlight) {
2232  // reposition highlight
2233  qreal pos = d->highlight->rowPos();
2234  qreal viewPos;
2235  qreal highlightStart;
2236  qreal highlightEnd;
2237  if (d->isRightToLeftTopToBottom()) {
2238  highlightStart = d->highlightRangeStartValid ? d->size()-d->highlightRangeEnd : d->highlightRangeStart;
2239  highlightEnd = d->highlightRangeEndValid ? d->size()-d->highlightRangeStart : d->highlightRangeEnd;
2240  viewPos = -d->position()-d->size();
2241  } else {
2242  highlightStart = d->highlightRangeStart;
2243  highlightEnd = d->highlightRangeEnd;
2244  viewPos = d->position();
2245  }
2246  if (pos > viewPos + highlightEnd - d->rowSize())
2247  pos = viewPos + highlightEnd - d->rowSize();
2248  if (pos < viewPos + highlightStart)
2249  pos = viewPos + highlightStart;
2250 
2251  d->highlight->setPosition(d->highlight->colPos(), qRound(pos));
2252 
2253  // update current index
2254  int idx = d->snapIndex();
2255  if (idx >= 0 && idx != d->currentIndex) {
2256  d->updateCurrent(idx);
2257  if (d->currentItem && d->currentItem->colPos() != d->highlight->colPos() && d->autoHighlight) {
2258  if (d->flow == LeftToRight)
2259  d->highlightXAnimator->to = d->currentItem->item->x();
2260  else
2261  d->highlightYAnimator->to = d->currentItem->item->y();
2262  }
2263  }
2264  }
2265  }
2266 }
2267 
2269 {
2270  Q_D(const QDeclarativeGridView);
2271  if (d->flow == QDeclarativeGridView::TopToBottom)
2273  qreal extent = -d->startPosition();
2274  if (d->header && d->visibleItems.count())
2275  extent += d->header->item->height();
2276  if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) {
2277  extent += d->highlightRangeStart;
2278  extent = qMax(extent, -(d->rowPosAt(0) + d->rowSize() - d->highlightRangeEnd));
2279  }
2280  return extent;
2281 }
2282 
2284 {
2285  Q_D(const QDeclarativeGridView);
2286  if (d->flow == QDeclarativeGridView::TopToBottom)
2288  qreal extent;
2289  if (!d->model || !d->model->count()) {
2290  extent = 0;
2291  } else if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) {
2292  extent = -(d->rowPosAt(d->model->count()-1) - d->highlightRangeStart);
2293  if (d->highlightRangeEnd != d->highlightRangeStart)
2294  extent = qMin(extent, -(d->endPosition() - d->highlightRangeEnd + 1));
2295  } else {
2296  extent = -(d->endPosition() - height());
2297  }
2298  if (d->footer)
2299  extent -= d->footer->item->height();
2300  const qreal minY = minYExtent();
2301  if (extent > minY)
2302  extent = minY;
2303  return extent;
2304 }
2305 
2307 {
2308  Q_D(const QDeclarativeGridView);
2309  if (d->flow == QDeclarativeGridView::LeftToRight)
2311  qreal extent = -d->startPosition();
2312  qreal highlightStart;
2313  qreal highlightEnd;
2314  qreal endPositionFirstItem = 0;
2315  if (d->isRightToLeftTopToBottom()) {
2316  if (d->model && d->model->count())
2317  endPositionFirstItem = d->rowPosAt(d->model->count()-1);
2318  highlightStart = d->highlightRangeStartValid
2319  ? d->highlightRangeStart - (d->lastPosition()-endPositionFirstItem)
2320  : d->size() - (d->lastPosition()-endPositionFirstItem);
2321  highlightEnd = d->highlightRangeEndValid ? d->highlightRangeEnd : d->size();
2322  if (d->footer && d->visibleItems.count())
2323  extent += d->footer->item->width();
2324  } else {
2325  endPositionFirstItem = d->rowPosAt(0)+d->rowSize();
2326  highlightStart = d->highlightRangeStart;
2327  highlightEnd = d->highlightRangeEnd;
2328  if (d->header && d->visibleItems.count())
2329  extent += d->header->item->width();
2330  }
2331  if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) {
2332  extent += d->isRightToLeftTopToBottom() ? -highlightStart : highlightStart;
2333  extent = qMax(extent, -(endPositionFirstItem - highlightEnd));
2334  }
2335  return extent;
2336 }
2337 
2339 {
2340  Q_D(const QDeclarativeGridView);
2341  if (d->flow == QDeclarativeGridView::LeftToRight)
2343  qreal extent;
2344  qreal highlightStart;
2345  qreal highlightEnd;
2346  qreal lastItemPosition = 0;
2347  if (d->isRightToLeftTopToBottom()){
2348  highlightStart = d->highlightRangeStartValid ? d->highlightRangeEnd : d->size();
2349  highlightEnd = d->highlightRangeEndValid ? d->highlightRangeStart : d->size();
2350  lastItemPosition = d->endPosition();
2351  } else {
2352  highlightStart = d->highlightRangeStart;
2353  highlightEnd = d->highlightRangeEnd;
2354  lastItemPosition = 0;
2355  if (d->model && d->model->count())
2356  lastItemPosition = d->rowPosAt(d->model->count()-1);
2357  }
2358  if (!d->model || !d->model->count()) {
2359  extent = 0;
2360  } else if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) {
2361  extent = -(lastItemPosition - highlightStart);
2362  if (highlightEnd != highlightStart)
2363  extent = d->isRightToLeftTopToBottom()
2364  ? qMax(extent, -(d->endPosition() - highlightEnd + 1))
2365  : qMin(extent, -(d->endPosition() - highlightEnd + 1));
2366  } else {
2367  extent = -(d->endPosition() - width());
2368  }
2369  if (d->isRightToLeftTopToBottom()) {
2370  if (d->header)
2371  extent -= d->header->item->width();
2372  } else {
2373  if (d->footer)
2374  extent -= d->footer->item->width();
2375  }
2376 
2377  const qreal minX = minXExtent();
2378  if (extent > minX)
2379  extent = minX;
2380  return extent;
2381 }
2382 
2384 {
2386  keyPressPreHandler(event);
2387  if (event->isAccepted())
2388  return;
2389  if (d->model && d->model->count() && d->interactive) {
2391  int oldCurrent = currentIndex();
2392  switch (event->key()) {
2393  case Qt::Key_Up:
2395  break;
2396  case Qt::Key_Down:
2398  break;
2399  case Qt::Key_Left:
2401  break;
2402  case Qt::Key_Right:
2404  break;
2405  default:
2406  break;
2407  }
2408  if (oldCurrent != currentIndex()) {
2409  event->accept();
2410  return;
2411  }
2412  }
2413  d->moveReason = QDeclarativeGridViewPrivate::Other;
2414  event->ignore();
2416 }
2417 
2431 {
2433  const int count = d->model ? d->model->count() : 0;
2434  if (!count)
2435  return;
2436  if (d->flow == QDeclarativeGridView::LeftToRight) {
2437  if (currentIndex() >= d->columns || d->wrap) {
2438  int index = currentIndex() - d->columns;
2439  setCurrentIndex((index >= 0 && index < count) ? index : count-1);
2440  }
2441  } else {
2442  if (currentIndex() > 0 || d->wrap) {
2443  int index = currentIndex() - 1;
2444  setCurrentIndex((index >= 0 && index < count) ? index : count-1);
2445  }
2446  }
2447 }
2448 
2462 {
2464  const int count = d->model ? d->model->count() : 0;
2465  if (!count)
2466  return;
2467  if (d->flow == QDeclarativeGridView::LeftToRight) {
2468  if (currentIndex() < count - d->columns || d->wrap) {
2469  int index = currentIndex()+d->columns;
2470  setCurrentIndex((index >= 0 && index < count) ? index : 0);
2471  }
2472  } else {
2473  if (currentIndex() < count - 1 || d->wrap) {
2474  int index = currentIndex() + 1;
2475  setCurrentIndex((index >= 0 && index < count) ? index : 0);
2476  }
2477  }
2478 }
2479 
2493 {
2495  const int count = d->model ? d->model->count() : 0;
2496  if (!count)
2497  return;
2498 
2500  if (d->flow == QDeclarativeGridView::LeftToRight) {
2501  if (currentIndex() > 0 || d->wrap) {
2502  int index = currentIndex() - 1;
2503  setCurrentIndex((index >= 0 && index < count) ? index : count-1);
2504  }
2505  } else {
2506  if (currentIndex() >= d->columns || d->wrap) {
2507  int index = currentIndex() - d->columns;
2508  setCurrentIndex((index >= 0 && index < count) ? index : count-1);
2509  }
2510  }
2511  } else {
2512  if (d->flow == QDeclarativeGridView::LeftToRight) {
2513  if (currentIndex() < count - 1 || d->wrap) {
2514  int index = currentIndex() + 1;
2515  setCurrentIndex((index >= 0 && index < count) ? index : 0);
2516  }
2517  } else {
2518  if (currentIndex() < count - d->columns || d->wrap) {
2519  int index = currentIndex() + d->columns;
2520  setCurrentIndex((index >= 0 && index < count) ? index : 0);
2521  }
2522  }
2523  }
2524 }
2525 
2539 {
2541  const int count = d->model ? d->model->count() : 0;
2542  if (!count)
2543  return;
2544 
2546  if (d->flow == QDeclarativeGridView::LeftToRight) {
2547  if (currentIndex() < count - 1 || d->wrap) {
2548  int index = currentIndex() + 1;
2549  setCurrentIndex((index >= 0 && index < count) ? index : 0);
2550  }
2551  } else {
2552  if (currentIndex() < count - d->columns || d->wrap) {
2553  int index = currentIndex()+d->columns;
2554  setCurrentIndex((index >= 0 && index < count) ? index : 0);
2555  }
2556  }
2557  } else {
2558  if (d->flow == QDeclarativeGridView::LeftToRight) {
2559  if (currentIndex() > 0 || d->wrap) {
2560  int index = currentIndex() - 1;
2561  setCurrentIndex((index >= 0 && index < count) ? index : count-1);
2562  }
2563  } else {
2564  if (currentIndex() >= d->columns || d->wrap) {
2565  int index = currentIndex() - d->columns;
2566  setCurrentIndex((index >= 0 && index < count) ? index : count-1);
2567  }
2568  }
2569  }
2570 }
2571 
2573 {
2575  if (!isValid())
2576  return;
2577  if (mode < QDeclarativeGridView::Beginning || mode > QDeclarativeGridView::Contain)
2578  return;
2579 
2580  int idx = qMax(qMin(index, model->count()-1), 0);
2581 
2582  if (layoutScheduled)
2583  layout();
2584  qreal pos = isRightToLeftTopToBottom() ? -position() - size() : position();
2585  FxGridItem *item = visibleItem(idx);
2586  qreal maxExtent;
2588  maxExtent = -q->maxYExtent();
2589  else
2590  maxExtent = isRightToLeftTopToBottom() ? q->minXExtent()-size() : -q->maxXExtent();
2591 
2592  if (!item) {
2593  int itemPos = rowPosAt(idx);
2594  // save the currently visible items in case any of them end up visible again
2595  QList<FxGridItem*> oldVisible = visibleItems;
2596  visibleItems.clear();
2597  visibleIndex = idx - idx % columns;
2599  maxExtent = -q->maxYExtent();
2600  else
2601  maxExtent = isRightToLeftTopToBottom() ? q->minXExtent()-size() : -q->maxXExtent();
2602  setPosition(qMin(qreal(itemPos), maxExtent));
2603  // now release the reference to all the old visible items.
2604  for (int i = 0; i < oldVisible.count(); ++i)
2605  releaseItem(oldVisible.at(i));
2606  item = visibleItem(idx);
2607  }
2608  if (item) {
2609  qreal itemPos = item->rowPos();
2610  switch (mode) {
2612  pos = itemPos;
2613  if (index < 0 && header) {
2615  ? header->item->height()
2616  : header->item->width();
2617  }
2618  break;
2620  pos = itemPos - (size() - rowSize())/2;
2621  break;
2623  pos = itemPos - size() + rowSize();
2624  if (index >= model->count() && footer) {
2626  ? footer->item->height()
2627  : footer->item->width();
2628  }
2629  break;
2631  if (itemPos > pos + size())
2632  pos = itemPos - size() + rowSize();
2633  else if (item->endRowPos() < pos)
2634  pos = itemPos;
2635  break;
2637  if (item->endRowPos() > pos + size())
2638  pos = itemPos - size() + rowSize();
2639  if (itemPos < pos)
2640  pos = itemPos;
2641  }
2642 
2643  pos = qMin(pos, maxExtent);
2644  qreal minExtent;
2646  minExtent = -q->minYExtent();
2647  else
2648  minExtent = isRightToLeftTopToBottom() ? q->maxXExtent()-size() : -q->minXExtent();
2649  pos = qMax(pos, minExtent);
2651  q->cancelFlick();
2652  setPosition(pos);
2653  }
2654  fixupPosition();
2655 }
2656 
2693 {
2695  if (!d->isValid() || index < 0 || index >= d->model->count())
2696  return;
2697  d->positionViewAtIndex(index, mode);
2698 }
2699 
2724 {
2726  if (!d->isValid())
2727  return;
2728  d->positionViewAtIndex(-1, Beginning);
2729 }
2730 
2732 {
2734  if (!d->isValid())
2735  return;
2736  d->positionViewAtIndex(d->model->count(), End);
2737 }
2738 
2755 {
2756  Q_D(const QDeclarativeGridView);
2757  for (int i = 0; i < d->visibleItems.count(); ++i) {
2758  const FxGridItem *listItem = d->visibleItems.at(i);
2759  if(listItem->contains(x, y))
2760  return listItem->index;
2761  }
2762 
2763  return -1;
2764 }
2765 
2767 {
2770  d->updateHeader();
2771  d->updateFooter();
2772  d->updateGrid();
2773  if (d->isValid()) {
2774  refill();
2776  if (d->currentIndex < 0 && !d->currentIndexCleared)
2777  d->updateCurrent(0);
2778  else
2779  d->updateCurrent(d->currentIndex);
2780  if (d->highlight && d->currentItem) {
2781  if (d->autoHighlight)
2782  d->highlight->setPosition(d->currentItem->colPos(), d->currentItem->rowPos());
2783  d->updateTrackedItem();
2784  }
2785  d->moveReason = QDeclarativeGridViewPrivate::Other;
2786  d->fixupPosition();
2787  }
2788 }
2789 
2791 {
2793  if (!d->trackedItem || !d->currentItem)
2794  return;
2795  if (d->moveReason == QDeclarativeGridViewPrivate::SetIndex) {
2796  const qreal trackedPos = d->trackedItem->rowPos();
2797  qreal viewPos;
2798  qreal highlightStart;
2799  qreal highlightEnd;
2800  if (d->isRightToLeftTopToBottom()) {
2801  viewPos = -d->position()-d->size();
2802  highlightStart = d->highlightRangeStartValid ? d->size()-d->highlightRangeEnd : d->highlightRangeStart;
2803  highlightEnd = d->highlightRangeEndValid ? d->size()-d->highlightRangeStart : d->highlightRangeEnd;
2804  } else {
2805  viewPos = d->position();
2806  highlightStart = d->highlightRangeStart;
2807  highlightEnd = d->highlightRangeEnd;
2808  }
2809  qreal pos = viewPos;
2810  if (d->haveHighlightRange) {
2811  if (d->highlightRange == StrictlyEnforceRange) {
2812  if (trackedPos > pos + highlightEnd - d->rowSize())
2813  pos = trackedPos - highlightEnd + d->rowSize();
2814  if (trackedPos < pos + highlightStart)
2815  pos = trackedPos - highlightStart;
2816  } else {
2817  if (trackedPos < d->startPosition() + highlightStart) {
2818  pos = d->startPosition();
2819  } else if (d->trackedItem->endRowPos() > d->endPosition() - d->size() + highlightEnd) {
2820  pos = d->endPosition() - d->size() + 1;
2821  if (pos < d->startPosition())
2822  pos = d->startPosition();
2823  } else {
2824  if (trackedPos < viewPos + highlightStart) {
2825  pos = trackedPos - highlightStart;
2826  } else if (trackedPos > viewPos + highlightEnd - d->rowSize()) {
2827  pos = trackedPos - highlightEnd + d->rowSize();
2828  }
2829  }
2830  }
2831  } else {
2832  if (trackedPos < viewPos && d->currentItem->rowPos() < viewPos) {
2833  pos = qMax(trackedPos, d->currentItem->rowPos());
2834  } else if (d->trackedItem->endRowPos() >= viewPos + d->size()
2835  && d->currentItem->endRowPos() >= viewPos + d->size()) {
2836  if (d->trackedItem->endRowPos() <= d->currentItem->endRowPos()) {
2837  pos = d->trackedItem->endRowPos() - d->size() + 1;
2838  if (d->rowSize() > d->size())
2839  pos = trackedPos;
2840  } else {
2841  pos = d->currentItem->endRowPos() - d->size() + 1;
2842  if (d->rowSize() > d->size())
2843  pos = d->currentItem->rowPos();
2844  }
2845  }
2846  }
2847  if (viewPos != pos) {
2848  cancelFlick();
2849  d->calcVelocity = true;
2850  d->setPosition(pos);
2851  d->calcVelocity = false;
2852  }
2853  }
2854 }
2855 
2857 {
2859  if (!isComponentComplete())
2860  return;
2861 
2862  int index = d->visibleItems.count() ? d->mapFromModel(modelIndex) : 0;
2863  if (index < 0) {
2864  int i = d->visibleItems.count() - 1;
2865  while (i > 0 && d->visibleItems.at(i)->index == -1)
2866  --i;
2867  if (d->visibleItems.at(i)->index + 1 == modelIndex) {
2868  // Special case of appending an item to the model.
2869  index = d->visibleIndex + d->visibleItems.count();
2870  } else {
2871  if (modelIndex <= d->visibleIndex) {
2872  // Insert before visible items
2873  d->visibleIndex += count;
2874  for (int i = 0; i < d->visibleItems.count(); ++i) {
2875  FxGridItem *listItem = d->visibleItems.at(i);
2876  if (listItem->index != -1 && listItem->index >= modelIndex)
2877  listItem->index += count;
2878  }
2879  }
2880  if (d->currentIndex >= modelIndex) {
2881  // adjust current item index
2882  d->currentIndex += count;
2883  if (d->currentItem)
2884  d->currentItem->index = d->currentIndex;
2886  }
2887  d->scheduleLayout();
2888  d->itemCount += count;
2889  emit countChanged();
2890  return;
2891  }
2892  }
2893 
2894  int insertCount = count;
2895  if (index < d->visibleIndex && d->visibleItems.count()) {
2896  insertCount -= d->visibleIndex - index;
2897  index = d->visibleIndex;
2898  modelIndex = d->visibleIndex;
2899  }
2900 
2901  qreal tempPos = d->isRightToLeftTopToBottom() ? -d->position()-d->size()+d->width()+1 : d->position();
2902  int to = d->buffer+tempPos+d->size()-1;
2903  int colPos = 0;
2904  int rowPos = 0;
2905  if (d->visibleItems.count()) {
2906  index -= d->visibleIndex;
2907  if (index < d->visibleItems.count()) {
2908  colPos = d->visibleItems.at(index)->colPos();
2909  rowPos = d->visibleItems.at(index)->rowPos();
2910  } else {
2911  // appending items to visible list
2912  colPos = d->visibleItems.at(index-1)->colPos() + d->colSize();
2913  rowPos = d->visibleItems.at(index-1)->rowPos();
2914  if (colPos > d->colSize() * (d->columns-1)) {
2915  colPos = 0;
2916  rowPos += d->rowSize();
2917  }
2918  }
2919  } else if (d->itemCount == 0 && d->header) {
2920  rowPos = d->headerSize();
2921  }
2922 
2923  // Update the indexes of the following visible items.
2924  for (int i = 0; i < d->visibleItems.count(); ++i) {
2925  FxGridItem *listItem = d->visibleItems.at(i);
2926  if (listItem->index != -1 && listItem->index >= modelIndex)
2927  listItem->index += count;
2928  }
2929 
2930  bool addedVisible = false;
2931  QList<FxGridItem*> added;
2932  int i = 0;
2933  while (i < insertCount && rowPos <= to + d->rowSize()*(d->columns - (colPos/d->colSize()))/qreal(d->columns+1)) {
2934  if (!addedVisible) {
2935  d->scheduleLayout();
2936  addedVisible = true;
2937  }
2938  FxGridItem *item = d->createItem(modelIndex + i);
2939  if (!item) {
2940  // broken or no delegate
2941  d->clear();
2942  return;
2943  }
2944  d->visibleItems.insert(index, item);
2945  item->setPosition(colPos, rowPos);
2946  added.append(item);
2947  colPos += d->colSize();
2948  if (colPos > d->colSize() * (d->columns-1)) {
2949  colPos = 0;
2950  rowPos += d->rowSize();
2951  }
2952  ++index;
2953  ++i;
2954  }
2955  if (i < insertCount) {
2956  // We didn't insert all our new items, which means anything
2957  // beyond the current index is not visible - remove it.
2958  while (d->visibleItems.count() > index) {
2959  d->releaseItem(d->visibleItems.takeLast());
2960  }
2961  }
2962 
2963  // update visibleIndex
2964  d->visibleIndex = 0;
2965  for (QList<FxGridItem*>::Iterator it = d->visibleItems.begin(); it != d->visibleItems.end(); ++it) {
2966  if ((*it)->index != -1) {
2967  d->visibleIndex = (*it)->index;
2968  break;
2969  }
2970  }
2971 
2972  if (d->itemCount && d->currentIndex >= modelIndex) {
2973  // adjust current item index
2974  d->currentIndex += count;
2975  if (d->currentItem) {
2976  d->currentItem->index = d->currentIndex;
2977  d->currentItem->setPosition(d->colPosAt(d->currentIndex), d->rowPosAt(d->currentIndex));
2978  }
2980  } else if (d->itemCount == 0 && (!d->currentIndex || (d->currentIndex < 0 && !d->currentIndexCleared))) {
2981  setCurrentIndex(0);
2982  }
2983 
2984  // everything is in order now - emit add() signal
2985  for (int j = 0; j < added.count(); ++j)
2986  added.at(j)->attached->emitAdd();
2987 
2988  d->itemCount += count;
2989  emit countChanged();
2990 }
2991 
2993 {
2995  if (!isComponentComplete())
2996  return;
2997 
2998  d->itemCount -= count;
2999  bool currentRemoved = d->currentIndex >= modelIndex && d->currentIndex < modelIndex + count;
3000  bool removedVisible = false;
3001  // Remove the items from the visible list, skipping anything already marked for removal
3002  QList<FxGridItem*>::Iterator it = d->visibleItems.begin();
3003  while (it != d->visibleItems.end()) {
3004  FxGridItem *item = *it;
3005  if (item->index == -1 || item->index < modelIndex) {
3006  // already removed, or before removed items
3007  if (item->index < modelIndex && !removedVisible) {
3008  d->scheduleLayout();
3009  removedVisible = true;
3010  }
3011  ++it;
3012  } else if (item->index >= modelIndex + count) {
3013  // after removed items
3014  item->index -= count;
3015  ++it;
3016  } else {
3017  // removed item
3018  if (!removedVisible) {
3019  d->scheduleLayout();
3020  removedVisible = true;
3021  }
3022  item->attached->emitRemove();
3023  if (item->attached->delayRemove()) {
3024  item->index = -1;
3025  connect(item->attached, SIGNAL(delayRemoveChanged()), this, SLOT(destroyRemoved()), Qt::QueuedConnection);
3026  ++it;
3027  } else {
3028  it = d->visibleItems.erase(it);
3029  d->releaseItem(item);
3030  }
3031  }
3032  }
3033 
3034  // If we removed items before visible items a layout may be
3035  // required to ensure item 0 is in the first column.
3036  if (!removedVisible && modelIndex < d->visibleIndex)
3037  d->scheduleLayout();
3038 
3039  // fix current
3040  if (d->currentIndex >= modelIndex + count) {
3041  d->currentIndex -= count;
3042  if (d->currentItem)
3043  d->currentItem->index -= count;
3045  } else if (currentRemoved) {
3046  // current item has been removed.
3047  d->releaseItem(d->currentItem);
3048  d->currentItem = 0;
3049  d->currentIndex = -1;
3050  if (d->itemCount)
3051  d->updateCurrent(qMin(modelIndex, d->itemCount-1));
3052  else
3054  }
3055 
3056  // update visibleIndex
3057  d->visibleIndex = 0;
3058  for (it = d->visibleItems.begin(); it != d->visibleItems.end(); ++it) {
3059  if ((*it)->index != -1) {
3060  d->visibleIndex = (*it)->index;
3061  break;
3062  }
3063  }
3064 
3065  if (removedVisible && d->visibleItems.isEmpty()) {
3066  d->timeline.clear();
3067  if (d->itemCount == 0) {
3068  d->setPosition(0);
3069  d->updateHeader();
3070  d->updateFooter();
3071  update();
3072  }
3073  }
3074 
3075  emit countChanged();
3076 }
3077 
3079 {
3081  for (QList<FxGridItem*>::Iterator it = d->visibleItems.begin();
3082  it != d->visibleItems.end();) {
3083  FxGridItem *listItem = *it;
3084  if (listItem->index == -1 && listItem->attached->delayRemove() == false) {
3085  d->releaseItem(listItem);
3086  it = d->visibleItems.erase(it);
3087  } else {
3088  ++it;
3089  }
3090  }
3091 
3092  // Correct the positioning of the items
3093  d->layout();
3094 }
3095 
3096 void QDeclarativeGridView::itemsMoved(int from, int to, int count)
3097 {
3099  if (!isComponentComplete())
3100  return;
3101  QHash<int,FxGridItem*> moved;
3102 
3103  FxGridItem *firstItem = d->firstVisibleItem();
3104 
3105  QList<FxGridItem*>::Iterator it = d->visibleItems.begin();
3106  while (it != d->visibleItems.end()) {
3107  FxGridItem *item = *it;
3108  if (item->index >= from && item->index < from + count) {
3109  // take the items that are moving
3110  item->index += (to-from);
3111  moved.insert(item->index, item);
3112  it = d->visibleItems.erase(it);
3113  } else {
3114  if (item->index > from && item->index != -1) {
3115  // move everything after the moved items.
3116  item->index -= count;
3117  if (item->index < d->visibleIndex)
3118  d->visibleIndex = item->index;
3119  }
3120  ++it;
3121  }
3122  }
3123 
3124  int remaining = count;
3125  int endIndex = d->visibleIndex;
3126  it = d->visibleItems.begin();
3127  while (it != d->visibleItems.end()) {
3128  FxGridItem *item = *it;
3129  if (remaining && item->index >= to && item->index < to + count) {
3130  // place items in the target position, reusing any existing items
3131  FxGridItem *movedItem = moved.take(item->index);
3132  if (!movedItem)
3133  movedItem = d->createItem(item->index);
3134  if (!movedItem) {
3135  // broken or no delegate
3136  d->clear();
3137  return;
3138  }
3139  it = d->visibleItems.insert(it, movedItem);
3140  if (it == d->visibleItems.begin() && firstItem)
3141  movedItem->setPosition(firstItem->colPos(), firstItem->rowPos());
3142  ++it;
3143  --remaining;
3144  } else {
3145  if (item->index != -1) {
3146  if (item->index >= to) {
3147  // update everything after the moved items.
3148  item->index += count;
3149  }
3150  endIndex = item->index;
3151  }
3152  ++it;
3153  }
3154  }
3155 
3156  // If we have moved items to the end of the visible items
3157  // then add any existing moved items that we have
3158  while (FxGridItem *item = moved.take(endIndex+1)) {
3159  d->visibleItems.append(item);
3160  ++endIndex;
3161  }
3162 
3163  // update visibleIndex
3164  for (it = d->visibleItems.begin(); it != d->visibleItems.end(); ++it) {
3165  if ((*it)->index != -1) {
3166  d->visibleIndex = (*it)->index;
3167  break;
3168  }
3169  }
3170 
3171  // Fix current index
3172  if (d->currentIndex >= 0 && d->currentItem) {
3173  int oldCurrent = d->currentIndex;
3174  d->currentIndex = d->model->indexOf(d->currentItem->item, this);
3175  if (oldCurrent != d->currentIndex) {
3176  d->currentItem->index = d->currentIndex;
3178  }
3179  }
3180 
3181  // Whatever moved items remain are no longer visible items.
3182  while (moved.count()) {
3183  int idx = moved.begin().key();
3184  FxGridItem *item = moved.take(idx);
3185  if (d->currentItem && item->item == d->currentItem->item)
3186  item->setPosition(d->colPosAt(idx), d->rowPosAt(idx));
3187  d->releaseItem(item);
3188  }
3189 
3190  d->layout();
3191 }
3192 
3194 {
3196  d->clear();
3197  refill();
3199  d->updateCurrent(d->currentIndex);
3200  if (d->highlight && d->currentItem) {
3201  if (d->autoHighlight)
3202  d->highlight->setPosition(d->currentItem->colPos(), d->currentItem->rowPos());
3203  d->updateTrackedItem();
3204  }
3205  d->moveReason = QDeclarativeGridViewPrivate::Other;
3206 
3207  emit countChanged();
3208 }
3209 
3211 {
3213  if (d->requestedIndex != index) {
3214  item->setParentItem(this);
3215  d->unrequestedItems.insert(item, index);
3216  if (d->flow == QDeclarativeGridView::LeftToRight) {
3217  item->setPos(QPointF(d->colPosAt(index), d->rowPosAt(index)));
3218  } else {
3219  item->setPos(QPointF(d->rowPosAt(index), d->colPosAt(index)));
3220  }
3221  }
3222 }
3223 
3225 {
3227  d->unrequestedItems.remove(item);
3228 }
3229 
3231 {
3234  if (d->haveHighlightRange && d->highlightRange == QDeclarativeGridView::StrictlyEnforceRange)
3235  d->updateHighlight();
3236 }
3237 
3239 {
3241  if (d->isRightToLeftTopToBottom())
3242  d->refill(-d->position()-d->size()+1, -d->position());
3243  else
3244  d->refill(d->position(), d->position()+d->size()-1);
3245 }
3246 
3247 
3249 {
3250  return new QDeclarativeGridViewAttached(obj);
3251 }
3252 
The QVariant class acts like a union for the most common Qt data types.
Definition: qvariant.h:92
Qt::LayoutDirection layoutDirection() const
T qobject_cast(QObject *object)
Definition: qobject.h:375
void setFlickableDirection(FlickableDirection)
FxGridItem * firstVisibleItem() const
FxGridItem * createItem(int modelIndex)
The QKeyEvent class describes a key event.
Definition: qevent.h:224
QDeclarativeComponent * header() const
QDeclarativeGridView::HighlightRangeMode highlightRange
double qreal
Definition: qglobal.h:1193
void itemsMoved(int from, int to, int count)
Qt::LayoutDirection effectiveLayoutDirection() const
Q_DECL_CONSTEXPR const T & qMin(const T &a, const T &b)
Definition: qglobal.h:1215
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
void highlightMoveDurationChanged()
QDeclarativeParserStatus ** d
virtual qreal maxYExtent() const
The QEasingCurve class provides easing curves for controlling animation.
Definition: qeasingcurve.h:55
void setLayoutDirection(Qt::LayoutDirection)
void setDelegate(QDeclarativeComponent *)
#define it(className, varName)
QDeclarativeComponent * footer() const
QDeclarativeComponent * headerComponent
bool isComponentComplete() const
Returns true if construction of the QML component is complete; otherwise returns false.
static void postEvent(QObject *receiver, QEvent *event)
Adds the event event, with the object receiver as the receiver of the event, to an event queue and re...
void releaseItem(FxGridItem *item)
QDeclarativeGridViewAttached * attached
virtual bool event(QEvent *)
void setSnapMode(SnapMode mode)
HighlightRangeMode highlightRangeMode() const
#define SLOT(a)
Definition: qobjectdefs.h:226
The QPointF class defines a point in the plane using floating point precision.
Definition: qpoint.h:214
static qreal position(QGraphicsObject *item, QDeclarativeAnchorLine::AnchorLine anchorLine)
static void clear(QVariant::Private *d)
Definition: qvariant.cpp:197
virtual void keyPressEvent(QKeyEvent *event)
void createdItem(int index, QDeclarativeItem *item)
void setHighlight(QDeclarativeComponent *highlight)
#define QML_FLICK_SNAPONETHRESHOLD
QDeclarativeItem * currentItem()
QPointF pos() const
Returns the position of the item in parent coordinates.
int count(const T &t) const
Returns the number of occurrences of value in the list.
Definition: qlist.h:891
T take(const Key &key)
Removes the item with the key from the hash and returns the value associated with it...
Definition: qhash.h:807
void refill(qreal from, qreal to, bool doBuffer=false)
void update(const QRectF &rect=QRectF())
Schedules a redraw of the area covered by rect in this item.
virtual qreal minYExtent() const
Q_DECL_CONSTEXPR T qAbs(const T &t)
Definition: qglobal.h:1201
The QObject class is the base class of all Qt objects.
Definition: qobject.h:111
QDeclarativeComponent * highlightComponent
void setPos(const QPointF &pos)
Sets the position of the item to pos, which is in parent coordinates.
Q_DECLARATIVE_EXPORT QDeclarativeContext * qmlContext(const QObject *)
#define Q_D(Class)
Definition: qglobal.h:2482
virtual QObject * create(QDeclarativeContext *context=0)
Create an object instance from this component.
void itemGeometryChanged(QDeclarativeItem *, const QRectF &, const QRectF &)
virtual qreal minYExtent() const
QDeclarativeGridView * view
FxGridItem(QDeclarativeItem *i, QDeclarativeGridView *v)
void positionViewAtIndex(int index, int mode)
Q_DECL_CONSTEXPR const T & qMax(const T &a, const T &b)
Definition: qglobal.h:1217
void itemsRemoved(int index, int count)
iterator insert(const Key &key, const T &value)
Inserts a new item with the key and a value of value.
Definition: qhash.h:753
#define Q_Q(Class)
Definition: qglobal.h:2483
virtual void itemGeometryChanged(QDeclarativeItem *item, const QRectF &newGeometry, const QRectF &oldGeometry)
int cacheBuffer() const
FxGridItem * snapItemAt(qreal pos)
Q_CORE_EXPORT void qDebug(const char *,...)
void setPosition(qreal col, qreal row)
void setParentItem(QDeclarativeItem *parent)
int key() const
Returns the code of the key that was pressed or released.
Definition: qevent.h:231
virtual bool event(QEvent *event)
#define SIGNAL(a)
Definition: qobjectdefs.h:227
void append(const T &t)
Inserts value at the end of the list.
Definition: qlist.h:507
QDeclarativeItem * highlightItem()
void setHighlightRangeMode(HighlightRangeMode mode)
Q_INVOKABLE void positionViewAtIndex(int index, int mode)
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
void setZValue(qreal z)
Sets the Z-value of the item to z.
The QRectF class defines a rectangle in the plane using floating point precision. ...
Definition: qrect.h:511
bool isAccepted() const
Definition: qcoreevent.h:307
int mapFromModel(int modelIndex) const
The QDeclarativeComponent class encapsulates a QML component definition.
int currentIndex() const
The QDeclarativeItem class provides the most basic of all visual items in QML.
QDeclarativeComponent * highlight() const
static bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
Creates a connection of the given type from the signal in the sender object to the method in the rece...
Definition: qobject.cpp:2580
void addItemChangeListener(QDeclarativeItemChangeListener *listener, ChangeTypes types)
void removeItem(QGraphicsItem *item)
Removes the item item and all its children from the scene.
static bool init
qreal height() const
Returns the height of the rectangle.
Definition: qrect.h:710
virtual qreal value() const
Return the current value.
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
#define emit
Definition: qobjectdefs.h:76
const char * layout
LayoutDirection
Definition: qnamespace.h:1580
virtual void fixup(AxisData &data, qreal minExtent, qreal maxExtent)
virtual void setContentY(qreal pos)
static const char * data(const QByteArray &arr)
The QLatin1String class provides a thin wrapper around an US-ASCII/Latin-1 encoded string literal...
Definition: qstring.h:654
QDeclarativeGuard< QDeclarativeVisualModel > model
static QDeclarativeGridViewAttached * qmlAttachedProperties(QObject *)
qreal width() const
Returns the width of the rectangle.
Definition: qrect.h:707
FxGridItem * visibleItem(int modelIndex) const
void highlightRangeModeChanged()
void clear()
Removes all items from the list.
Definition: qlist.h:764
static qreal component(const QPointF &point, unsigned int i)
void setHeader(QDeclarativeComponent *)
void destroyingItem(QDeclarativeItem *item)
qreal rowPosAt(int modelIndex) const
QDeclarativeGridView(QDeclarativeItem *parent=0)
virtual qreal minXExtent() const
qreal colPosAt(int modelIndex) const
QDeclarativeGridView::SnapMode snapMode
Q_INVOKABLE int indexAt(qreal x, qreal y) const
The QList::iterator class provides an STL-style non-const iterator for QList and QQueue.
Definition: qlist.h:181
virtual void flick(AxisData &data, qreal minExtent, qreal maxExtent, qreal vSize, QDeclarativeTimeLineCallback::Callback fixupCallback, qreal velocity)
bool highlightFollowsCurrentItem() const
static bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *member)
Disconnects signal in object sender from method in object receiver.
Definition: qobject.cpp:2895
void setFooter(QDeclarativeComponent *)
Q_CORE_EXPORT void qFatal(const char *,...)
#define Q_DECLARE_PUBLIC(Class)
Definition: qglobal.h:2477
QDeclarativeTimeLineValueProxy< QDeclarativeFlickablePrivate > move
qreal y() const
This convenience function is equivalent to calling pos().
void preferredHighlightBeginChanged()
iterator end()
Returns an STL-style iterator pointing to the imaginary item after the last item in the hash...
Definition: qhash.h:467
The Flow item arranges its children side by side, wrapping as necessary.
qreal endRowPos() const
void QDeclarative_setParent_noEvent(QObject *object, QObject *parent)
Makes the object a child of parent.
const Key key(const T &value) const
Returns the first key mapped to value.
Definition: qhash.h:674
qreal x() const
This convenience function is equivalent to calling pos().
void setView(QDeclarativeGridView *view)
virtual void componentComplete()
QDeclarativeComponent * delegate() const
void preferredHighlightEndChanged()
qreal colPos() const
Definition: qnamespace.h:54
iterator begin()
Returns an STL-style iterator pointing to the first item in the hash.
Definition: qhash.h:464
QDeclarativeComponent * footerComponent
T qvariant_cast(const QVariant &)
Definition: qvariant.h:571
virtual void flick(AxisData &data, qreal minExtent, qreal maxExtent, qreal vSize, QDeclarativeTimeLineCallback::Callback fixupCallback, qreal velocity)
The QDeclarativeContext class defines a context within a QML engine.
void setModel(const QVariant &)
static const QGraphicsItemPrivate * get(const QGraphicsItem *item)
quint16 index
The QDeclarativeProperty class abstracts accessing properties on objects created from QML...
virtual qreal maxXExtent() const
Q_INVOKABLE void positionViewAtBeginning()
int cellHeight() const
int count(const Key &key) const
Returns the number of items associated with the key.
Definition: qhash.h:719
virtual void setContentX(qreal pos)
int highlightMoveDuration() const
qreal preferredHighlightBegin() const
QGraphicsScene * scene() const
Returns the current scene for the item, or 0 if the item is not stored in a scene.
QVariant model() const
void itemsInserted(int index, int count)
qreal rowPos() const
QSmoothedAnimation * highlightYAnimator
virtual qreal maxYExtent() const
virtual void setContentX(qreal pos)
bool contains(qreal x, qreal y) const
SnapMode snapMode() const
qreal preferredHighlightEnd() const
virtual void fixup(AxisData &data, qreal minExtent, qreal maxExtent)
static const KeyPair *const end
virtual qreal maxXExtent() const
The QEvent class is the base class of all event classes.
Definition: qcoreevent.h:56
Type type() const
Returns the event type.
Definition: qcoreevent.h:303
QList< FxGridItem * > visibleItems
virtual void keyPressEvent(QKeyEvent *)
QDeclarativeGridView::Flow flow
qreal qSqrt(qreal v)
Definition: qmath.h:205
Q_INVOKABLE void positionViewAtEnd()
virtual void setContentY(qreal pos)
qreal snapPosAt(qreal pos) const
virtual qreal minXExtent() const
Q_DECL_CONSTEXPR int qRound(qreal d)
Definition: qglobal.h:1203
QSmoothedAnimation * highlightXAnimator
void keyNavigationWrapsChanged()
QDeclarativeItem * item
QDeclarativeItem * createComponentItem(QDeclarativeComponent *component)
QDeclarativeContext * creationContext() const
Returns the QDeclarativeContext the component was created in.
The QList class is a template class that provides lists.
Definition: qdatastream.h:62
void keyPressPreHandler(QKeyEvent *)
int cellWidth() const
QHash< QDeclarativeItem *, int > unrequestedItems