[app] Delay repaint after color scheme change
That allows settings page animation to complete smoothly. Also switched BooksPageWidget from QTimer to QBasicTimer for better efficiency.
This commit is contained in:
parent
a4a868c1c8
commit
ba04787927
2 changed files with 90 additions and 40 deletions
|
@ -48,6 +48,7 @@
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
|
|
||||||
static const QString IMAGE_URL("image://%1/%2");
|
static const QString IMAGE_URL("image://%1/%2");
|
||||||
|
static const int REPAINT_DELAY_MSEC = 250;
|
||||||
|
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
// BooksPageWidget::Data
|
// BooksPageWidget::Data
|
||||||
|
@ -533,7 +534,6 @@ BooksPageWidget::BooksPageWidget(QQuickItem* aParent) :
|
||||||
iSettings(BooksSettings::sharedInstance()),
|
iSettings(BooksSettings::sharedInstance()),
|
||||||
iTaskQueue(BooksTaskQueue::defaultQueue()),
|
iTaskQueue(BooksTaskQueue::defaultQueue()),
|
||||||
iTextStyle(BooksTextStyle::defaults()),
|
iTextStyle(BooksTextStyle::defaults()),
|
||||||
iResizeTimer(new QTimer(this)),
|
|
||||||
iModel(NULL),
|
iModel(NULL),
|
||||||
iResetTask(NULL),
|
iResetTask(NULL),
|
||||||
iRenderTask(NULL),
|
iRenderTask(NULL),
|
||||||
|
@ -551,9 +551,6 @@ BooksPageWidget::BooksPageWidget(QQuickItem* aParent) :
|
||||||
{
|
{
|
||||||
connect(iSettings.data(), SIGNAL(colorSchemeChanged()), SLOT(onColorsChanged()));
|
connect(iSettings.data(), SIGNAL(colorSchemeChanged()), SLOT(onColorsChanged()));
|
||||||
setFlag(ItemHasContents, true);
|
setFlag(ItemHasContents, true);
|
||||||
iResizeTimer->setSingleShot(true);
|
|
||||||
iResizeTimer->setInterval(0);
|
|
||||||
connect(iResizeTimer, SIGNAL(timeout()), SLOT(onResizeTimeout()));
|
|
||||||
connect(this, SIGNAL(widthChanged()), SLOT(onWidthChanged()));
|
connect(this, SIGNAL(widthChanged()), SLOT(onWidthChanged()));
|
||||||
connect(this, SIGNAL(heightChanged()), SLOT(onHeightChanged()));
|
connect(this, SIGNAL(heightChanged()), SLOT(onHeightChanged()));
|
||||||
}
|
}
|
||||||
|
@ -650,7 +647,7 @@ BooksPageWidget::onColorsChanged()
|
||||||
{
|
{
|
||||||
HDEBUG(iPage);
|
HDEBUG(iPage);
|
||||||
HASSERT(sender() == iSettings);
|
HASSERT(sender() == iSettings);
|
||||||
scheduleRepaint();
|
scheduleRepaintDelayUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -797,7 +794,7 @@ BooksPageWidget::resetView()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!iEmpty) {
|
if (!iEmpty) {
|
||||||
update();
|
updateNow();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -816,16 +813,38 @@ BooksPageWidget::scheduleRepaint()
|
||||||
{
|
{
|
||||||
BooksLoadingSignalBlocker block(this);
|
BooksLoadingSignalBlocker block(this);
|
||||||
cancelRepaint();
|
cancelRepaint();
|
||||||
const int w = width();
|
if (width() > 0 && height() > 0) {
|
||||||
const int h = height();
|
if (!iData.isNull() && !iData->iView.isNull()) {
|
||||||
if (w > 0 && h > 0 && !iData.isNull() && !iData->iView.isNull()) {
|
|
||||||
const shared_ptr<BooksTextView> view(iData->iView);
|
|
||||||
(iRenderTask = new RenderTask(iTaskQueue->pool(), thread(),
|
(iRenderTask = new RenderTask(iTaskQueue->pool(), thread(),
|
||||||
iData, iSettings->colorScheme()))->
|
iData, iSettings->colorScheme()))->submit(this,
|
||||||
submit(this, SLOT(onRenderTaskDone()));
|
SLOT(onRenderTaskDone()));
|
||||||
} else {
|
} else {
|
||||||
update();
|
updateNow();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BooksPageWidget::scheduleRepaintDelayUpdate()
|
||||||
|
{
|
||||||
|
BooksLoadingSignalBlocker block(this);
|
||||||
|
cancelRepaint();
|
||||||
|
if (width() > 0 && height() > 0) {
|
||||||
|
if (!iData.isNull() && !iData->iView.isNull()) {
|
||||||
|
(iRenderTask = new RenderTask(iTaskQueue->pool(), thread(),
|
||||||
|
iData, iSettings->colorScheme()))->submit(this,
|
||||||
|
SLOT(onRenderTaskDoneDelayUpdate()));
|
||||||
|
} else if (!iDelayUpdateTimer.isActive()) {
|
||||||
|
iDelayUpdateTimer.start(REPAINT_DELAY_MSEC, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BooksPageWidget::updateNow()
|
||||||
|
{
|
||||||
|
iDelayUpdateTimer.stop();
|
||||||
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -841,14 +860,47 @@ BooksPageWidget::onResetTaskDone()
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
BooksPageWidget::onRenderTaskDone()
|
BooksPageWidget::renderTaskDone()
|
||||||
{
|
{
|
||||||
BooksLoadingSignalBlocker block(this);
|
|
||||||
HASSERT(sender() == iRenderTask);
|
HASSERT(sender() == iRenderTask);
|
||||||
iImage = iRenderTask->iImage;
|
iImage = iRenderTask->iImage;
|
||||||
iRenderTask->release(this);
|
iRenderTask->release(this);
|
||||||
iRenderTask = NULL;
|
iRenderTask = NULL;
|
||||||
update();
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BooksPageWidget::onRenderTaskDone()
|
||||||
|
{
|
||||||
|
BooksLoadingSignalBlocker block(this);
|
||||||
|
renderTaskDone();
|
||||||
|
updateNow();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BooksPageWidget::onRenderTaskDoneDelayUpdate()
|
||||||
|
{
|
||||||
|
BooksLoadingSignalBlocker block(this);
|
||||||
|
renderTaskDone();
|
||||||
|
if (!iDelayUpdateTimer.isActive()) {
|
||||||
|
iDelayUpdateTimer.start(REPAINT_DELAY_MSEC, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BooksPageWidget::timerEvent(
|
||||||
|
QTimerEvent* aEvent)
|
||||||
|
{
|
||||||
|
const int timerId = aEvent->timerId();
|
||||||
|
if (timerId == iResizeTimer.timerId()) {
|
||||||
|
// This can only happen if only width or height has changed.
|
||||||
|
// Normally, width change is followed by height change and
|
||||||
|
// the size is updated from the setHeight() method
|
||||||
|
updateSize();
|
||||||
|
} else if (timerId == iDelayUpdateTimer.timerId()) {
|
||||||
|
updateNow();
|
||||||
|
} else {
|
||||||
|
return QQuickPaintedItem::timerEvent(aEvent);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -882,7 +934,7 @@ BooksPageWidget::onClearSelectionTaskDone()
|
||||||
|
|
||||||
if (task->iImageUpdated) {
|
if (task->iImageUpdated) {
|
||||||
iImage = task->iImage;
|
iImage = task->iImage;
|
||||||
update();
|
updateNow();
|
||||||
}
|
}
|
||||||
|
|
||||||
task->release(this);
|
task->release(this);
|
||||||
|
@ -913,7 +965,7 @@ BooksPageWidget::onStartSelectionTaskDone()
|
||||||
if (emitSelectionEmpty) {
|
if (emitSelectionEmpty) {
|
||||||
Q_EMIT selectionEmptyChanged();
|
Q_EMIT selectionEmptyChanged();
|
||||||
}
|
}
|
||||||
update();
|
updateNow();
|
||||||
}
|
}
|
||||||
|
|
||||||
task->release(this);
|
task->release(this);
|
||||||
|
@ -933,7 +985,7 @@ BooksPageWidget::onExtendSelectionTaskDone()
|
||||||
HDEBUG("selection" << iSelectionEmpty);
|
HDEBUG("selection" << iSelectionEmpty);
|
||||||
Q_EMIT selectionEmptyChanged();
|
Q_EMIT selectionEmptyChanged();
|
||||||
}
|
}
|
||||||
update();
|
updateNow();
|
||||||
}
|
}
|
||||||
|
|
||||||
task->release(this);
|
task->release(this);
|
||||||
|
@ -1042,6 +1094,7 @@ void
|
||||||
BooksPageWidget::updateSize()
|
BooksPageWidget::updateSize()
|
||||||
{
|
{
|
||||||
HDEBUG("page" << iPage << QSize(width(), height()));
|
HDEBUG("page" << iPage << QSize(width(), height()));
|
||||||
|
iResizeTimer.stop();
|
||||||
iImage = QImage();
|
iImage = QImage();
|
||||||
resetView();
|
resetView();
|
||||||
}
|
}
|
||||||
|
@ -1051,35 +1104,25 @@ BooksPageWidget::onWidthChanged()
|
||||||
{
|
{
|
||||||
HVERBOSE((int)width());
|
HVERBOSE((int)width());
|
||||||
// Width change will probably be followed by height change
|
// Width change will probably be followed by height change
|
||||||
iResizeTimer->start();
|
iResizeTimer.start(0, this);
|
||||||
iImage = QImage();
|
iImage = QImage();
|
||||||
update();
|
updateNow();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
BooksPageWidget::onHeightChanged()
|
BooksPageWidget::onHeightChanged()
|
||||||
{
|
{
|
||||||
HVERBOSE((int)height());
|
HVERBOSE((int)height());
|
||||||
if (iResizeTimer->isActive()) {
|
if (iResizeTimer.isActive()) { // Started by onWidthChanged()
|
||||||
// Height is usually changed after width, repaint right away
|
// Height is usually changed after width, repaint right away
|
||||||
iResizeTimer->stop();
|
|
||||||
updateSize();
|
updateSize();
|
||||||
} else {
|
} else {
|
||||||
iResizeTimer->start();
|
iResizeTimer.start(0, this);
|
||||||
iImage = QImage();
|
iImage = QImage();
|
||||||
update();
|
updateNow();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
BooksPageWidget::onResizeTimeout()
|
|
||||||
{
|
|
||||||
// This can only happen if only width or height has changed. Normally,
|
|
||||||
// width change is followed by height change and view is reset from the
|
|
||||||
// setHeight() method
|
|
||||||
updateSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BooksPageWidget::handleLongPress(
|
BooksPageWidget::handleLongPress(
|
||||||
int aX,
|
int aX,
|
||||||
|
|
|
@ -45,7 +45,7 @@
|
||||||
#include "ZLTextStyle.h"
|
#include "ZLTextStyle.h"
|
||||||
|
|
||||||
#include <QQuickPaintedItem>
|
#include <QQuickPaintedItem>
|
||||||
#include <QTimer>
|
#include <QBasicTimer>
|
||||||
#include <QList>
|
#include <QList>
|
||||||
|
|
||||||
class BooksPageWidget: public QQuickPaintedItem, private BooksLoadingProperty
|
class BooksPageWidget: public QQuickPaintedItem, private BooksLoadingProperty
|
||||||
|
@ -129,12 +129,12 @@ Q_SIGNALS:
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
void onWidthChanged();
|
void onWidthChanged();
|
||||||
void onHeightChanged();
|
void onHeightChanged();
|
||||||
void onResizeTimeout();
|
|
||||||
void onBookModelDestroyed();
|
void onBookModelDestroyed();
|
||||||
void onTextStyleChanged();
|
void onTextStyleChanged();
|
||||||
void onColorsChanged();
|
void onColorsChanged();
|
||||||
void onResetTaskDone();
|
void onResetTaskDone();
|
||||||
void onRenderTaskDone();
|
void onRenderTaskDone();
|
||||||
|
void onRenderTaskDoneDelayUpdate();
|
||||||
void onClearSelectionTaskDone();
|
void onClearSelectionTaskDone();
|
||||||
void onStartSelectionTaskDone();
|
void onStartSelectionTaskDone();
|
||||||
void onExtendSelectionTaskDone();
|
void onExtendSelectionTaskDone();
|
||||||
|
@ -142,13 +142,19 @@ private Q_SLOTS:
|
||||||
void onLongPressTaskDone();
|
void onLongPressTaskDone();
|
||||||
void onFootnoteTaskDone();
|
void onFootnoteTaskDone();
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
|
void timerEvent(QTimerEvent*) Q_DECL_OVERRIDE;
|
||||||
void paint(QPainter*) Q_DECL_OVERRIDE;
|
void paint(QPainter*) Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
|
private:
|
||||||
void updateSize();
|
void updateSize();
|
||||||
void resetView();
|
void resetView();
|
||||||
void releaseExtendSelectionTasks();
|
void releaseExtendSelectionTasks();
|
||||||
void scheduleRepaint();
|
void scheduleRepaint();
|
||||||
|
void scheduleRepaintDelayUpdate();
|
||||||
void cancelRepaint();
|
void cancelRepaint();
|
||||||
|
void renderTaskDone();
|
||||||
|
void updateNow();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class ResetTask;
|
class ResetTask;
|
||||||
|
@ -163,7 +169,8 @@ private:
|
||||||
shared_ptr<BooksTaskQueue> iTaskQueue;
|
shared_ptr<BooksTaskQueue> iTaskQueue;
|
||||||
shared_ptr<ZLTextStyle> iTextStyle;
|
shared_ptr<ZLTextStyle> iTextStyle;
|
||||||
BooksPos iBookPos;
|
BooksPos iBookPos;
|
||||||
QTimer* iResizeTimer;
|
QBasicTimer iResizeTimer;
|
||||||
|
QBasicTimer iDelayUpdateTimer;
|
||||||
BooksBookModel* iModel;
|
BooksBookModel* iModel;
|
||||||
BooksMargins iMargins;
|
BooksMargins iMargins;
|
||||||
shared_ptr<Data> iData;
|
shared_ptr<Data> iData;
|
||||||
|
|
Loading…
Reference in a new issue