diff --git a/src/songinfo/songinfobase.cpp b/src/songinfo/songinfobase.cpp index f70e1e0ae..ab2ba37fe 100644 --- a/src/songinfo/songinfobase.cpp +++ b/src/songinfo/songinfobase.cpp @@ -61,7 +61,7 @@ SongInfoBase::SongInfoBase(NetworkAccessManager* network, QWidget* parent) } void SongInfoBase::Clear() { - fader_->Start(); + fader_->StartFade(); qDeleteAll(widgets_); widgets_.clear(); @@ -128,6 +128,7 @@ void SongInfoBase::MaybeUpdate(const Song& metadata) { } void SongInfoBase::Update(const Song& metadata) { + fader_->StartBlur(); current_request_id_ = fetcher_->FetchInfo(metadata); } diff --git a/src/widgets/widgetfadehelper.cpp b/src/widgets/widgetfadehelper.cpp index 74263d59b..d5ddc9c4b 100644 --- a/src/widgets/widgetfadehelper.cpp +++ b/src/widgets/widgetfadehelper.cpp @@ -20,22 +20,38 @@ #include #include +// Exported by QtGui +void qt_blurImage(QPainter *p, QImage &blurImage, qreal radius, bool quality, bool alphaOnly, int transposed = 0); + WidgetFadeHelper::WidgetFadeHelper(QWidget* parent, int msec) : QWidget(parent), parent_(parent), - timeline_(new QTimeLine(msec, this)) + blur_timeline_(new QTimeLine(msec, this)), + fade_timeline_(new QTimeLine(msec, this)) { setAttribute(Qt::WA_TransparentForMouseEvents); - connect(timeline_, SIGNAL(valueChanged(qreal)), SLOT(update())); - connect(timeline_, SIGNAL(finished()), SLOT(hide())); + connect(blur_timeline_, SIGNAL(valueChanged(qreal)), SLOT(update())); + connect(fade_timeline_, SIGNAL(valueChanged(qreal)), SLOT(update())); + connect(fade_timeline_, SIGNAL(finished()), SLOT(FadeFinished())); hide(); } -void WidgetFadeHelper::Start() { +void WidgetFadeHelper::StartBlur() { // Take a "screenshot" of the window - pixmap_ = QPixmap::grabWidget(parent_); + original_pixmap_ = QPixmap::grabWidget(parent_); + QImage original_image = original_pixmap_.toImage(); + + // Blur it + QImage blurred(original_image.size(), QImage::Format_ARGB32_Premultiplied); + blurred.fill(Qt::transparent); + + QPainter blur_painter(&blurred); + qt_blurImage(&blur_painter, original_image, 10.0, true, false); + blur_painter.end(); + + blurred_pixmap_ = QPixmap::fromImage(blurred); // Cover the parent resize(parent_->size()); @@ -43,12 +59,45 @@ void WidgetFadeHelper::Start() { show(); // Start the timeline - timeline_->start(); + blur_timeline_->stop(); + blur_timeline_->start(); +} + +void WidgetFadeHelper::StartFade() { + if (blur_timeline_->state() == QTimeLine::Running) { + // Blur timeline is still running, so we need render the current state + // into a new pixmap. + QPixmap pixmap(original_pixmap_); + QPainter painter(&pixmap); + painter.setOpacity(blur_timeline_->currentValue()); + painter.drawPixmap(0, 0, blurred_pixmap_); + painter.end(); + blurred_pixmap_ = pixmap; + } + blur_timeline_->stop(); + original_pixmap_ = QPixmap(); + + // Start the timeline + fade_timeline_->stop(); + fade_timeline_->start(); } void WidgetFadeHelper::paintEvent(QPaintEvent* ) { QPainter p(this); - p.setOpacity(1.0 - timeline_->currentValue()); - p.drawPixmap(0, 0, pixmap_); + if (fade_timeline_->state() != QTimeLine::Running) { + // We're fading in the blur + p.setOpacity(blur_timeline_->currentValue()); + } else { + // Fading out the blur into the new image + p.setOpacity(1.0 - fade_timeline_->currentValue()); + } + + p.drawPixmap(0, 0, blurred_pixmap_); +} + +void WidgetFadeHelper::FadeFinished() { + hide(); + original_pixmap_ = QPixmap(); + blurred_pixmap_ = QPixmap(); } diff --git a/src/widgets/widgetfadehelper.h b/src/widgets/widgetfadehelper.h index 3def52bb8..a0d09bc60 100644 --- a/src/widgets/widgetfadehelper.h +++ b/src/widgets/widgetfadehelper.h @@ -28,16 +28,22 @@ public: WidgetFadeHelper(QWidget* parent, int msec = 500); public slots: - void Start(); + void StartBlur(); + void StartFade(); protected: void paintEvent(QPaintEvent*); +private slots: + void FadeFinished(); + private: QWidget* parent_; - QTimeLine* timeline_; + QTimeLine* blur_timeline_; + QTimeLine* fade_timeline_; - QPixmap pixmap_; + QPixmap original_pixmap_; + QPixmap blurred_pixmap_; }; #endif // WIDGETFADEHELPER_H