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