]> cloud.milkyroute.net Git - dolphin.git/commitdiff
Fix transition between m_pixmap and m_hoverPixmap
authorAurélien Gâteau <agateau@kde.org>
Thu, 21 Mar 2013 13:06:07 +0000 (14:06 +0100)
committerAurélien Gâteau <agateau@kde.org>
Thu, 21 Mar 2013 13:06:07 +0000 (14:06 +0100)
The default SourceOver composition mode of QPainter cannot be used
to interpolate between two images, we must use intermediate buffers
to perform the interpolation and blend the result on the widget.

More details are available in the review request.

REVIEW: 109614
FIXED-IN: 4.10.2

src/kitemviews/kstandarditemlistwidget.cpp

index fcd0520457dc2cbe3ca1435129e20a0b9dfb28fc..6adb546332e234c77bcdb68313b2b87860859262 100644 (file)
@@ -249,17 +249,46 @@ void KStandardItemListWidget::paint(QPainter* painter, const QStyleOptionGraphic
 
     const KItemListStyleOption& itemListStyleOption = styleOption();
     if (isHovered()) {
-        const qreal opacity = painter->opacity();
-        // Blend the unhovered and hovered pixmap if the hovering
-        // animation is ongoing
         if (hoverOpacity() < 1.0) {
-            painter->setOpacity((1.0 - hoverOpacity()) * opacity);
-            drawPixmap(painter, m_pixmap);
-        }
+            /*
+             * Linear interpolation between m_pixmap and m_hoverPixmap.
+             *
+             * Note that this cannot be achieved by painting m_hoverPixmap over
+             * m_pixmap, even if the opacities are adjusted. For details see
+             * https://git.reviewboard.kde.org/r/109614/
+             */
+            // Paint pixmap1 so that pixmap1 = m_pixmap * (1.0 - hoverOpacity())
+            QPixmap pixmap1(option->rect.size());
+            pixmap1.fill(Qt::transparent);
+            {
+                QPainter p(&pixmap1);
+                p.setOpacity(1.0 - hoverOpacity());
+                drawPixmap(&p, m_pixmap);
+            }
+
+            // Paint pixmap2 so that pixmap2 = m_hoverPixmap * hoverOpacity()
+            QPixmap pixmap2(option->rect.size());
+            pixmap2.fill(Qt::transparent);
+            {
+                QPainter p(&pixmap2);
+                p.setOpacity(hoverOpacity());
+                drawPixmap(&p, m_hoverPixmap);
+            }
 
-        painter->setOpacity(hoverOpacity() * opacity);
-        drawPixmap(painter, m_hoverPixmap);
-        painter->setOpacity(opacity);
+            // Paint pixmap2 on pixmap1 using CompositionMode_Plus
+            // Now pixmap1 = pixmap2 + m_pixmap * (1.0 - hoverOpacity())
+            //             = m_hoverPixmap * hoverOpacity() + m_pixmap * (1.0 - hoverOpacity())
+            {
+                QPainter p(&pixmap1);
+                p.setCompositionMode(QPainter::CompositionMode_Plus);
+                p.drawPixmap(0, 0, pixmap2);
+            }
+
+            // Finally paint pixmap1 on the widget
+            painter->drawPixmap(0, 0, pixmap1);
+        } else {
+            drawPixmap(painter, m_hoverPixmap);
+        }
     } else {
         drawPixmap(painter, m_pixmap);
     }