diff options
author | Stanislav Ionascu <stanislav.ionascu@nokia.com> | 2010-12-07 14:57:57 +0200 |
---|---|---|
committer | Stanislav Ionascu <stanislav.ionascu@nokia.com> | 2010-12-13 15:52:05 +0200 |
commit | 399ba8045503397531a1ca250f0b154bac7f3e48 (patch) | |
tree | e6361cf19377917a93ca1efe679da67651c40c77 | |
parent | 677e2575d31ff9c723de0cf8669e9c64bb677645 (diff) |
Fixes: NB#210072 - Widgetsgallery grid page should stop loading images when page is left
RevBy: Armin Berres
Details: Pauses the image loading during list paning and when leaving page, resumes as soon
as the page appears, or the list panning is stopped.
Tries to load first the visible items of the list, then starts from the end of the queue. In case
if we're in the begining of the list, starts from the top.
-rw-r--r-- | demos/widgetsgallery/gridmodel.cpp | 90 | ||||
-rw-r--r-- | demos/widgetsgallery/gridmodel.h | 20 | ||||
-rw-r--r-- | demos/widgetsgallery/mgridpage.cpp | 21 | ||||
-rw-r--r-- | demos/widgetsgallery/mgridpage.h | 4 |
4 files changed, 118 insertions, 17 deletions
diff --git a/demos/widgetsgallery/gridmodel.cpp b/demos/widgetsgallery/gridmodel.cpp index a96f33a6..88a5d2cd 100644 --- a/demos/widgetsgallery/gridmodel.cpp +++ b/demos/widgetsgallery/gridmodel.cpp @@ -33,7 +33,6 @@ GridModel::GridModel(const QSize &size, const QStringList &dirs) for (int i = 0; i < THREAD_COUNT; i++) { Loader *loader = new Loader(size); - loader->start(QThread::LowestPriority); connect(loader, SIGNAL(imageReady(QImage, int)), this, SLOT(insertImage(QImage, int))); m_loaders.append(loader); } @@ -87,6 +86,29 @@ QVariant GridModel::data(const QModelIndex &index, int role) const return QVariant(); } +void GridModel::pauseLoaders() +{ + for (int i = 0; i < THREAD_COUNT; i++) { + Loader *loader = m_loaders[i]; + if (loader->isRunning()) + loader->stop(); + } +} + +void GridModel::resumeLoaders(int offset) +{ + if (offset < 0) + offset = 0; + else + offset = offset / THREAD_COUNT; + + for (int i = 0; i < THREAD_COUNT; i++) { + Loader *loader = m_loaders[i]; + if (!loader->isRunning() && loader->hasWork()) + loader->resume(offset); + } +} + void GridModel::createItems() { int index = 0; @@ -112,6 +134,7 @@ void GridModel::createItems() index++; } } + resumeLoaders(); } void GridModel::insertImage(QImage image, int index) @@ -133,22 +156,46 @@ void Loader::run() mutex.unlock(); return; } - if (backlog.isEmpty()) { - haveWork.wait(&mutex); - mutex.unlock(); - continue; + + int offset = loadOffset; + + BacklogItem *backlogItem = NULL; + if (offset >= backlog.count()) + offset = backlog.count() - 1; + + if (backlog.count() > offset) { + backlogItem = backlog.at(offset); + + // Try to find next item in backlog to load + int nextOffset = offset; + while (backlogItem->loaded && nextOffset < backlog.count()) + backlogItem = backlog.at(nextOffset++); + + // If we did not find, try to load previous in backlog + int prevOffset = offset; + while (backlogItem->loaded && prevOffset > 0) + backlogItem = backlog.at(prevOffset--); + + // Everything is loaded, stop. + if (backlogItem->loaded) { + mutex.unlock(); + stop(); + return; + } } - BacklogItem backlogItem = backlog.takeFirst(); + backlogItem->loaded = true; + const QFileInfo file(backlogItem->path); + int index = backlogItem->index; mutex.unlock(); - const QFileInfo file(backlogItem.first); - int index = backlogItem.second; QImage image(file.absoluteFilePath()); if (!image.isNull()) { scaleImage(image); emit imageReady(image, index); + // Sleep for 8ms to let other threads do their job. + msleep(8); } } } @@ -162,20 +209,39 @@ void Loader::scaleImage(QImage& image) const } } -void Loader::pushImage(const QString &path, int index) +bool Loader::hasWork() { - BacklogItem backlogItem(path, index); mutex.lock(); + bool result = false; + int i = 0; + while (!result && i < backlog.count()) + result = (!backlog.at(i++)->loaded); + mutex.unlock(); + return result; +} +void Loader::pushImage(const QString &path, int index) +{ + BacklogItem *backlogItem = new BacklogItem; + backlogItem->path = path; + backlogItem->index = index; + backlogItem->loaded = false; + + mutex.lock(); backlog.append(backlogItem); mutex.unlock(); - haveWork.wakeAll(); +} + +void Loader::resume(int offset) +{ + loadOffset = offset; + stopWork = false; + start(QThread::LowestPriority); } void Loader::stop() { mutex.lock(); stopWork = true; - haveWork.wakeAll(); mutex.unlock(); } diff --git a/demos/widgetsgallery/gridmodel.h b/demos/widgetsgallery/gridmodel.h index 88fbe3bc..4a8afd65 100644 --- a/demos/widgetsgallery/gridmodel.h +++ b/demos/widgetsgallery/gridmodel.h @@ -62,6 +62,9 @@ public: virtual int columnCount(const QModelIndex &parent = QModelIndex()) const; virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + void pauseLoaders(); + void resumeLoaders(int offset = 0); + private slots: void insertImage(QImage pixmap, int index); @@ -73,18 +76,27 @@ private: QStringList m_dirs; }; -typedef QPair<QString, int> BacklogItem; +struct BacklogItem { + QString path; + int index; + bool loaded; +}; class Loader : public QThread { Q_OBJECT public: explicit Loader (const QSize &s) - : QThread(), mutex(), haveWork(), backlog(), size(s), stopWork(false) { } + : QThread(), mutex(), backlog(), size(s), stopWork(false), loadOffset(0) { } void pushImage(const QString &path, int index); + + void resume(int offset); void stop(); + void scaleImage(QImage& image) const; + bool hasWork(); + signals: void imageReady(QImage pixmap, int index); @@ -93,10 +105,10 @@ protected: private: QMutex mutex; - QWaitCondition haveWork; - QList<BacklogItem> backlog; + QList<BacklogItem*> backlog; QSize size; bool stopWork; + int loadOffset; }; #endif diff --git a/demos/widgetsgallery/mgridpage.cpp b/demos/widgetsgallery/mgridpage.cpp index 27c82bc3..5cd9c007 100644 --- a/demos/widgetsgallery/mgridpage.cpp +++ b/demos/widgetsgallery/mgridpage.cpp @@ -103,6 +103,7 @@ QSizeF ContentItemCreator::cellSize() const MGridPage::MGridPage() : TemplatePage(TemplatePage::ListsGridsAndPopups), list(0), + model(0), actionConfiguration(0), m_itemSize(10,10), m_columnsPortrait(4), @@ -158,7 +159,8 @@ void MGridPage::createContent() QStringList mediaDirs; mediaDirs << Utils::picturesDir(); mediaDirs << Utils::mediaArtDir(); - GridModel *model = new GridModel(m_itemSize.toSize(), mediaDirs); + + model = new GridModel(m_itemSize.toSize(), mediaDirs); list->setItemModel(model); connect(list, SIGNAL(itemClicked(QModelIndex)), this, SLOT(itemClicked(QModelIndex))); @@ -169,6 +171,12 @@ void MGridPage::createContent() connect(actionConfiguration, SIGNAL(triggered()), this, SLOT(showGridConfigurationDialog())); addAction(actionConfiguration); + connect(this, SIGNAL(disappearing()), this, SLOT(pauseLoaders())); + connect(this, SIGNAL(appeared()), this, SLOT(resumeLoaders())); + + connect(list, SIGNAL(panningStarted()), this, SLOT(pauseLoaders())); + connect(list, SIGNAL(panningStopped()), this, SLOT(resumeLoaders())); + retranslateUi(); } @@ -304,3 +312,14 @@ void MGridPage::modifyRowsSliderHandle(int newValue) m_columnsPortraitSlider->setHandleLabel(QString::number(newValue)); m_columnsPortraitLabel->setText(QString::number(newValue)); } + +void MGridPage::pauseLoaders() +{ + model->pauseLoaders(); +} + +void MGridPage::resumeLoaders() +{ + if (MApplication::instance()->activeApplicationWindow()->currentPage() == this) + model->resumeLoaders(list->firstVisibleItem().row()); +} diff --git a/demos/widgetsgallery/mgridpage.h b/demos/widgetsgallery/mgridpage.h index 55396e93..73b327a0 100644 --- a/demos/widgetsgallery/mgridpage.h +++ b/demos/widgetsgallery/mgridpage.h @@ -61,8 +61,12 @@ private slots: void configureGrid(); void configureGrid(M::Orientation orientation); + void pauseLoaders(); + void resumeLoaders(); + private: MList *list; + GridModel *model; MAction *actionConfiguration; QSizeF m_itemSize; |