aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStanislav Ionascu <stanislav.ionascu@nokia.com>2010-12-07 14:57:57 +0200
committerStanislav Ionascu <stanislav.ionascu@nokia.com>2010-12-13 15:52:05 +0200
commit399ba8045503397531a1ca250f0b154bac7f3e48 (patch)
treee6361cf19377917a93ca1efe679da67651c40c77
parent677e2575d31ff9c723de0cf8669e9c64bb677645 (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.cpp90
-rw-r--r--demos/widgetsgallery/gridmodel.h20
-rw-r--r--demos/widgetsgallery/mgridpage.cpp21
-rw-r--r--demos/widgetsgallery/mgridpage.h4
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;