]> cloud.milkyroute.net Git - dolphin.git/blobdiff - src/kitemviews/kitemlistgroupheader.cpp
Fix selection issue when expanding a tree
[dolphin.git] / src / kitemviews / kitemlistgroupheader.cpp
index 5aac02c829d8c39673d755cde35691f0713d008c..a63ad8d0913c79025a19dc206485020e5265fc3c 100644 (file)
 
 #include "kitemlistview.h"
 
+#include <QGraphicsSceneResizeEvent>
 #include <QPainter>
-
+#include <QStyleOptionGraphicsItem>
 #include <KDebug>
 
 KItemListGroupHeader::KItemListGroupHeader(QGraphicsWidget* parent) :
     QGraphicsWidget(parent, 0),
+    m_dirtyCache(true),
     m_role(),
-    m_data()
+    m_data(),
+    m_styleOption(),
+    m_scrollOrientation(Qt::Vertical),
+    m_leftBorderCache(0),
+    m_rightBorderCache(0),
+    m_outlineColor()
 {
 }
 
 KItemListGroupHeader::~KItemListGroupHeader()
 {
+    deleteCache();
 }
 
 void KItemListGroupHeader::setRole(const QByteArray& role)
@@ -69,22 +77,61 @@ QVariant KItemListGroupHeader::data() const
     return m_data;
 }
 
-QSizeF KItemListGroupHeader::sizeHint(Qt::SizeHint which, const QSizeF& constraint) const
+void KItemListGroupHeader::setStyleOption(const KItemListStyleOption& option)
+{
+    const KItemListStyleOption previous = m_styleOption;
+    m_styleOption = option;
+    m_dirtyCache = true;
+    styleOptionChanged(option, previous);
+}
+
+const KItemListStyleOption& KItemListGroupHeader::styleOption() const
+{
+    return m_styleOption;
+}
+
+void KItemListGroupHeader::setScrollOrientation(Qt::Orientation orientation)
+{
+    if (m_scrollOrientation != orientation) {
+        const Qt::Orientation previous = m_scrollOrientation;
+        m_scrollOrientation = orientation;
+        if (orientation == Qt::Vertical) {
+            m_dirtyCache = true;
+        } else {
+            deleteCache();
+        }
+        scrollOrientationChanged(orientation, previous);
+    }
+}
+
+Qt::Orientation KItemListGroupHeader::scrollOrientation() const
 {
-    Q_UNUSED(which);
-    Q_UNUSED(constraint);
-    return QSizeF();
+    return m_scrollOrientation;
 }
 
 void KItemListGroupHeader::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
 {
     Q_UNUSED(option);
     Q_UNUSED(widget);
-    painter->setPen(Qt::darkGreen);
-    painter->setBrush(QColor(0, 255, 0, 50));
-    painter->drawRect(rect());
 
-    //painter->drawText(rect(), QString::number(m_index));
+    if (m_scrollOrientation == Qt::Horizontal) {
+        Q_ASSERT(!m_leftBorderCache);
+        Q_ASSERT(!m_rightBorderCache);
+        return;
+    }
+
+    if (m_dirtyCache) {
+        updateCache();
+    }
+
+    const int leftBorderX = m_leftBorderCache->width() + 1;
+    const int rightBorderX = size().width() - m_rightBorderCache->width() - 2;
+
+    painter->setPen(m_outlineColor);
+    painter->drawLine(leftBorderX, 1, rightBorderX, 1);
+
+    painter->drawPixmap(1, 1, *m_leftBorderCache);
+    painter->drawPixmap(rightBorderX, 1, *m_rightBorderCache);
 }
 
 void KItemListGroupHeader::roleChanged(const QByteArray& current, const QByteArray& previous)
@@ -99,4 +146,106 @@ void KItemListGroupHeader::dataChanged(const QVariant& current, const QVariant&
     Q_UNUSED(previous);
 }
 
+void KItemListGroupHeader::styleOptionChanged(const KItemListStyleOption& current, const KItemListStyleOption& previous)
+{
+    Q_UNUSED(current);
+    Q_UNUSED(previous);
+}
+
+void KItemListGroupHeader::scrollOrientationChanged(Qt::Orientation current, Qt::Orientation previous)
+{
+    Q_UNUSED(current);
+    Q_UNUSED(previous);
+}
+
+void KItemListGroupHeader::resizeEvent(QGraphicsSceneResizeEvent* event)
+{
+    QGraphicsWidget::resizeEvent(event);
+    if (event->oldSize().height() != event->newSize().height()) {
+        m_dirtyCache = true;
+    }
+}
+
+void KItemListGroupHeader::updateCache()
+{
+    Q_ASSERT(m_dirtyCache);
+
+    deleteCache();
+
+    const int length = qMax(int(size().height() - 1), 1);
+    m_leftBorderCache = new QPixmap(length, length);
+    m_leftBorderCache->fill(Qt::transparent);
+
+    m_rightBorderCache = new QPixmap(length, length);
+    m_rightBorderCache->fill(Qt::transparent);
+
+    // Calculate the outline color. No alphablending is used for
+    // performance reasons.
+    const QColor c1 = m_styleOption.palette.text().color();
+    const QColor c2 = m_styleOption.palette.background().color();
+    const int p1 = 35;
+    const int p2 = 100 - p1;
+    m_outlineColor = QColor((c1.red()   * p1 + c2.red()   * p2) / 100,
+                            (c1.green() * p1 + c2.green() * p2) / 100,
+                            (c1.blue()  * p1 + c2.blue()  * p2) / 100);
+
+    // The drawing code is based on the code of DolphinCategoryDrawer from Dolphin 1.7
+    // Copyright (C) 2007 Rafael Fernández López <ereslibre@kde.org>
+    {
+        // Cache the left border as pixmap
+        QPainter painter(m_leftBorderCache);
+        painter.setPen(m_outlineColor);
+
+        // 1. Draw top horizontal line
+        painter.drawLine(3, 0, length, 0);
+
+        // 2. Draw vertical line with gradient
+        const QPoint start(0, 3);
+        QLinearGradient gradient(start, QPoint(0, length));
+        gradient.setColorAt(0, m_outlineColor);
+        gradient.setColorAt(1, Qt::transparent);
+        painter.fillRect(QRect(start, QSize(1, length - start.y())), gradient);
+
+        // 3. Draw arc
+        painter.setRenderHint(QPainter::Antialiasing);
+        QRectF arc(QPointF(0, 0), QSizeF(4, 4));
+        arc.translate(0.5, 0.5);
+        painter.drawArc(arc, 1440, 1440);
+    }
+
+    {
+        // Cache the right border as pixmap
+        QPainter painter(m_rightBorderCache);
+        painter.setPen(m_outlineColor);
+
+        // 1. Draw top horizontal line
+        painter.drawLine(0, 0, length - 3, 0);
+
+        // 2. Draw vertical line with gradient
+        const int right = length - 1;
+        const QPoint start(right, 3);
+        QLinearGradient gradient(start, QPoint(right, length));
+        gradient.setColorAt(0, m_outlineColor);
+        gradient.setColorAt(1, Qt::transparent);
+        painter.fillRect(QRect(start, QSize(1, length - start.y())), gradient);
+
+        // 3. Draw arc
+        painter.setRenderHint(QPainter::Antialiasing);
+        QRectF arc(QPointF(length - 5, 0), QSizeF(4, 4));
+        arc.translate(0.5, 0.5);
+        painter.drawArc(arc, 0, 1440);
+    }
+
+    m_dirtyCache = false;
+}
+
+void KItemListGroupHeader::deleteCache()
+{
+    delete m_leftBorderCache;
+    m_leftBorderCache = 0;
+
+    delete m_rightBorderCache;
+    m_rightBorderCache = 0;
+}
+
 #include "kitemlistgroupheader.moc"