From 03f28cfc174dbad3d9531b29b6dfed9983ea5d73 Mon Sep 17 00:00:00 2001 From: Benjamin Poulain Date: Fri, 18 Dec 2009 13:42:35 +0100 Subject: Improve the performance of the Anomaly browser demo Some minor changes to improve the demo: -use QUrl::fromUserInput() -scroll a surface instead of moving the widgets to minimize the repaint -use the animation framework instead of QTimeLine --- demos/embedded/anomaly/src/BrowserWindow.cpp | 146 ++++++++++++--------------- demos/embedded/anomaly/src/BrowserWindow.h | 12 ++- 2 files changed, 70 insertions(+), 88 deletions(-) diff --git a/demos/embedded/anomaly/src/BrowserWindow.cpp b/demos/embedded/anomaly/src/BrowserWindow.cpp index 1036735..1163b6a 100644 --- a/demos/embedded/anomaly/src/BrowserWindow.cpp +++ b/demos/embedded/anomaly/src/BrowserWindow.cpp @@ -43,92 +43,44 @@ #include #include +#include +#include #include "BrowserView.h" #include "HomeView.h" BrowserWindow::BrowserWindow() - : QWidget() - , m_homeView(0) - , m_browserView(0) + : m_slidingSurface(new QWidget(this)) + , m_homeView(new HomeView(m_slidingSurface)) + , m_browserView(new BrowserView(m_slidingSurface)) + , m_animation(new QPropertyAnimation(this, "slideValue")) { - m_timeLine = new QTimeLine(300, this); - m_timeLine->setCurveShape(QTimeLine::EaseInOutCurve); - QTimer::singleShot(0, this, SLOT(initialize())); -} - -void BrowserWindow::initialize() -{ - m_homeView = new HomeView(this); - m_browserView = new BrowserView(this); + m_slidingSurface->setAutoFillBackground(true); - m_homeView->hide(); m_homeView->resize(size()); - m_homeView->move(0, 0); - m_browserView->hide(); m_browserView->resize(size()); - m_browserView->move(0, 0); connect(m_homeView, SIGNAL(addressEntered(QString)), SLOT(gotoAddress(QString))); connect(m_homeView, SIGNAL(urlActivated(QUrl)), SLOT(navigate(QUrl))); connect(m_browserView, SIGNAL(menuButtonClicked()), SLOT(showHomeView())); - m_homeView->setVisible(false); - m_browserView->setVisible(false); - slide(0); + m_animation->setDuration(200); + connect(m_animation, SIGNAL(finished()), SLOT(animationFinished())); - connect(m_timeLine, SIGNAL(frameChanged(int)), SLOT(slide(int))); + setSlideValue(0.0f); } - -// from Demo Browser -QUrl guessUrlFromString(const QString &string) +void BrowserWindow::gotoAddress(const QString &address) { - QString urlStr = string.trimmed(); - QRegExp test(QLatin1String("^[a-zA-Z]+\\:.*")); - - // Check if it looks like a qualified URL. Try parsing it and see. - bool hasSchema = test.exactMatch(urlStr); - if (hasSchema) { - QUrl url = QUrl::fromEncoded(urlStr.toUtf8(), QUrl::TolerantMode); - if (url.isValid()) - return url; - } - - // Might be a file. - if (QFile::exists(urlStr)) { - QFileInfo info(urlStr); - return QUrl::fromLocalFile(info.absoluteFilePath()); - } - - // Might be a shorturl - try to detect the schema. - if (!hasSchema) { - int dotIndex = urlStr.indexOf(QLatin1Char('.')); - if (dotIndex != -1) { - QString prefix = urlStr.left(dotIndex).toLower(); - QString schema = (prefix == QString("ftp")) ? prefix.toLatin1() : QString("http"); - QString location = schema + "://" + urlStr; - QUrl url = QUrl::fromEncoded(location.toUtf8(), QUrl::TolerantMode); - if (url.isValid()) - return url; - } - } - - // Fall back to QUrl's own tolerant parser. - QUrl url = QUrl::fromEncoded(string.toUtf8(), QUrl::TolerantMode); - - // finally for cases where the user just types in a hostname add http - if (url.scheme().isEmpty()) - url = QUrl::fromEncoded("http://" + string.toUtf8(), QUrl::TolerantMode); - return url; + m_browserView->navigate(QUrl::fromUserInput(address)); + showBrowserView(); } -void BrowserWindow::gotoAddress(const QString &address) +void BrowserWindow::animationFinished() { - m_browserView->navigate(guessUrlFromString(address)); - showBrowserView(); + m_animation->setDirection(QAbstractAnimation::Forward); } void BrowserWindow::navigate(const QUrl &url) @@ -137,31 +89,44 @@ void BrowserWindow::navigate(const QUrl &url) showBrowserView(); } -void BrowserWindow::slide(int pos) +void BrowserWindow::setSlideValue(qreal slideRatio) { - m_browserView->move(pos, 0); - m_homeView->move(pos - width(), 0); - m_browserView->show(); - m_homeView->show(); + // we use a ratio to handle resize corectly + const int pos = -qRound(slideRatio * width()); + m_slidingSurface->scroll(pos - m_homeView->x(), 0); + + if (qFuzzyCompare(slideRatio, static_cast(1.0f))) { + m_browserView->show(); + m_homeView->hide(); + } else if (qFuzzyCompare(slideRatio, static_cast(0.0f))) { + m_homeView->show(); + m_browserView->hide(); + } else { + m_browserView->show(); + m_homeView->show(); + } } -void BrowserWindow::showHomeView() +qreal BrowserWindow::slideValue() const { - if (m_timeLine->state() != QTimeLine::NotRunning) - return; + Q_ASSERT(m_slidingSurface->x() < width()); + return static_cast(qAbs(m_homeView->x())) / width(); +} - m_timeLine->setFrameRange(0, width()); - m_timeLine->start(); +void BrowserWindow::showHomeView() +{ + m_animation->setStartValue(slideValue()); + m_animation->setEndValue(0.0f); + m_animation->start(); m_homeView->setFocus(); } void BrowserWindow::showBrowserView() { - if (m_timeLine->state() != QTimeLine::NotRunning) - return; + m_animation->setStartValue(slideValue()); + m_animation->setEndValue(1.0f); + m_animation->start(); - m_timeLine->setFrameRange(width(), 0); - m_timeLine->start(); m_browserView->setFocus(); } @@ -170,18 +135,31 @@ void BrowserWindow::keyReleaseEvent(QKeyEvent *event) QWidget::keyReleaseEvent(event); if (event->key() == Qt::Key_F3) { - if (m_homeView->isVisible()) - showBrowserView(); - else + if (m_animation->state() == QAbstractAnimation::Running) { + const QAbstractAnimation::Direction direction = m_animation->direction() == QAbstractAnimation::Forward + ? QAbstractAnimation::Forward + : QAbstractAnimation::Backward; + m_animation->setDirection(direction); + } else if (qFuzzyCompare(slideValue(), static_cast(1.0f))) showHomeView(); + else + showBrowserView(); + event->accept(); } } void BrowserWindow::resizeEvent(QResizeEvent *event) { - if (m_homeView) - m_homeView->resize(size()); + const QSize newSize = event->size(); + m_slidingSurface->resize(newSize.width() * 2, newSize.height()); + + m_homeView->resize(newSize); + m_homeView->move(0, 0); + + m_browserView->resize(newSize); + m_browserView->move(newSize.width(), 0); - if (m_browserView) - m_browserView->resize(size()); + const QSize oldSize = event->oldSize(); + const qreal oldSlidingRatio = static_cast(qAbs(m_slidingSurface->x())) / oldSize.width(); + setSlideValue(oldSlidingRatio); } diff --git a/demos/embedded/anomaly/src/BrowserWindow.h b/demos/embedded/anomaly/src/BrowserWindow.h index 9647efb..2b77939 100644 --- a/demos/embedded/anomaly/src/BrowserWindow.h +++ b/demos/embedded/anomaly/src/BrowserWindow.h @@ -43,7 +43,7 @@ #define BROWSERWINDOW_H #include -class QTimeLine; +class QPropertyAnimation; class QUrl; class BrowserView; @@ -52,28 +52,32 @@ class HomeView; class BrowserWindow : public QWidget { Q_OBJECT + Q_PROPERTY(qreal slideValue READ slideValue WRITE setSlideValue) public: BrowserWindow(); private slots: - void initialize(); void navigate(const QUrl &url); void gotoAddress(const QString &address); + void animationFinished(); public slots: void showBrowserView(); void showHomeView(); - void slide(int); protected: void keyReleaseEvent(QKeyEvent *event); void resizeEvent(QResizeEvent *event); private: + void setSlideValue(qreal); + qreal slideValue() const; + + QWidget *m_slidingSurface; HomeView *m_homeView; BrowserView *m_browserView; - QTimeLine *m_timeLine; + QPropertyAnimation *m_animation; }; #endif // BROWSERWINDOW_H -- cgit v0.12