]> cloud.milkyroute.net Git - dolphin.git/commitdiff
Fix selection style issues
authorPeter Penz <peter.penz19@gmail.com>
Sun, 13 Nov 2011 19:55:51 +0000 (20:55 +0100)
committerPeter Penz <peter.penz19@gmail.com>
Sun, 13 Nov 2011 19:58:43 +0000 (20:58 +0100)
Don't use a custom drawing code for showing the hover-indication
or selection of the text.
- The default style for items is used.
- Merge icon-rectangle and text-rectangle if possible.
- Fix background and minor focus-issues

src/kitemviews/kfileitemlistwidget.cpp
src/kitemviews/kfileitemlistwidget.h
src/kitemviews/kitemlistcontroller.cpp
src/kitemviews/kitemlistselectiontoggle.cpp
src/kitemviews/kitemlistwidget.cpp
src/kitemviews/kitemlistwidget.h
src/views/dolphinview.cpp

index 8fd00fa020179ba53d4d48e218a213223302a385..710253ae8d636529d95701f95bb12b5114f32406 100644 (file)
@@ -58,7 +58,8 @@ KFileItemListWidget::KFileItemListWidget(QGraphicsItem* parent) :
     m_expansionArea(),
     m_customTextColor(),
     m_additionalInfoTextColor(),
-    m_overlay()
+    m_overlay(),
+    m_selectionTogglePos()
 {
     for (int i = 0; i < TextIdCount; ++i) {
         m_text[i].setTextFormat(Qt::PlainText);
@@ -185,7 +186,26 @@ QRectF KFileItemListWidget::selectionToggleRect() const
         toggleSize = KIconLoader::SizeSmallMedium;
     }
 
-    return QRectF(m_pixmapPos, QSizeF(toggleSize, toggleSize));
+    QPointF pos = m_selectionTogglePos;
+
+    // If the selection toggle has a very small distance to the
+    // widget borders, the size of the selection toggle will get
+    // increased to prevent an accidental clicking of the item
+    // when trying to hit the toggle.
+    const int widgetHeight = size().height();
+    const int widgetWidth = size().width();
+    const int minMargin = 2;
+
+    if (toggleSize + minMargin * 2 >= widgetHeight) {
+        toggleSize = widgetHeight;
+        pos.setY(0);
+    }
+    if (toggleSize + minMargin * 2 >= widgetWidth) {
+        toggleSize = widgetWidth;
+        pos.setX(0);
+    }
+
+    return QRectF(pos, QSizeF(toggleSize, toggleSize));
 }
 
 QString KFileItemListWidget::roleText(const QByteArray& role, const QHash<QByteArray, QVariant>& values)
@@ -397,6 +417,10 @@ void KFileItemListWidget::updatePixmapCache()
     }
 
     if (updatePixmap) {
+        // The selection toggle should always be applied to the top/left
+        // of the pixmap
+        m_selectionTogglePos = QPointF(-option.margin, -option.margin);
+
         m_pixmap = values["iconPixmap"].value<QPixmap>();
         if (m_pixmap.isNull()) {
             // Use the icon that fits to the MIME-type
@@ -424,15 +448,17 @@ void KFileItemListWidget::updatePixmapCache()
             squarePixmap.fill(Qt::transparent);
 
             QPainter painter(&squarePixmap);
+            int x, y;
             if (iconOnTop) {
-                const int x = (iconHeight - m_pixmap.width()) / 2;  // Center horizontally
-                const int y = iconHeight - m_pixmap.height();       // Align on bottom
+                x = (iconHeight - m_pixmap.width()) / 2;  // Center horizontally
+                y = iconHeight - m_pixmap.height();       // Align on bottom
                 painter.drawPixmap(x, y, m_pixmap);
             } else {
-                const int x = iconHeight - m_pixmap.width();        // Align right
-                const int y = (iconHeight - m_pixmap.height()) / 2; // Center vertically
+                x = iconHeight - m_pixmap.width();        // Align right
+                y = (iconHeight - m_pixmap.height()) / 2; // Center vertically
                 painter.drawPixmap(x, y, m_pixmap);
             }
+            m_selectionTogglePos += QPointF(x, y);
 
             m_pixmap = squarePixmap;
         } else {
@@ -455,6 +481,10 @@ void KFileItemListWidget::updatePixmapCache()
     }
     m_pixmapPos.setY(option.margin);
 
+    if (updatePixmap) {
+      m_selectionTogglePos += m_pixmapPos;
+    }
+
     // Center the hover rectangle horizontally and align it on bottom
     const qreal x = m_pixmapPos.x() + (m_scaledPixmapSize.width() - m_hoverPixmapRect.width()) / 2.0;
     const qreal y = m_pixmapPos.y() + m_scaledPixmapSize.height() - m_hoverPixmapRect.height();
index 3c9a1d73a512923f3b98c34c3c5d87cd9e662713..1f0c89449fb9fb079f7bdbf4da47cd81d6227c1c 100644 (file)
@@ -143,6 +143,8 @@ private:
     QColor m_additionalInfoTextColor;
 
     QPixmap m_overlay;
+
+    QPointF m_selectionTogglePos;
 };
 
 #endif
index 8b135fbb5f9a87640f1110a3e7e6734720de5249..5d4963bfd21c30eb471d0c7de0b22a300a87b4bd 100644 (file)
@@ -275,7 +275,6 @@ bool KItemListController::mousePressEvent(QGraphicsSceneMouseEvent* event, const
     m_pressedIndex = m_view->itemAt(m_pressedMousePos);
 
     if (m_view->isAboveExpansionToggle(m_pressedIndex, m_pressedMousePos)) {
-        m_selectionTogglePressed = true;
         m_selectionManager->setCurrentItem(m_pressedIndex);
         return true;
     }
index 43725e0de58445b6bce77c1f7c5b7381a07165f7..014f65b40d6636d2f022eee9387586fe4f9278cc 100644 (file)
@@ -23,6 +23,8 @@
 #include <KIconLoader>
 #include <QPainter>
 
+#include <KDebug>
+
 KItemListSelectionToggle::KItemListSelectionToggle(QGraphicsItem* parent) :
     QGraphicsWidget(parent, 0),
     m_checked(false),
@@ -80,7 +82,20 @@ void KItemListSelectionToggle::hoverLeaveEvent(QGraphicsSceneHoverEvent* event)
 void KItemListSelectionToggle::updatePixmap()
 {
     const char* icon = m_checked ? "list-remove" : "list-add";
-    const int iconSize = qMin(size().width(), size().height());
+
+    int iconSize = qMin(size().width(), size().height());
+    if (iconSize < KIconLoader::SizeSmallMedium) {
+        iconSize = KIconLoader::SizeSmall;
+    } else if (iconSize < KIconLoader::SizeMedium) {
+        iconSize = KIconLoader::SizeSmallMedium;
+    } else if (iconSize < KIconLoader::SizeLarge) {
+        iconSize = KIconLoader::SizeMedium;
+    } else if (iconSize < KIconLoader::SizeHuge) {
+        iconSize = KIconLoader::SizeLarge;
+    } else if (iconSize < KIconLoader::SizeEnormous) {
+        iconSize = KIconLoader::SizeHuge;
+    }
+
     m_pixmap = KIconLoader::global()->loadIcon(QLatin1String(icon), KIconLoader::NoGroup, iconSize);
 
     if (m_hovered) {
index 04438262f9050d1e2ec06a7bab9adafd2a1a41a0..cf8b54c0cfec7bce7771d5886c9327d1f0a92b30 100644 (file)
@@ -31,7 +31,6 @@
 #include <QApplication>
 #include <QPainter>
 #include <QPropertyAnimation>
-#include <QStyle>
 #include <QStyleOption>
 
 KItemListWidget::KItemListWidget(QGraphicsItem* parent) :
@@ -111,16 +110,10 @@ void KItemListWidget::paint(QPainter* painter, const QStyleOptionGraphicsItem* o
         painter->fillRect(backgroundRect, backgroundColor);
     }
 
-    const QRect iconBounds = iconRect().toRect();
     if (m_selected) {
-        QStyleOptionViewItemV4 viewItemOption;
-        viewItemOption.initFrom(widget);
-        viewItemOption.rect = iconBounds;
-        viewItemOption.state = QStyle::State_Enabled | QStyle::State_Selected | QStyle::State_Item;
-        viewItemOption.viewItemPosition = QStyleOptionViewItemV4::OnlyOne;
-        widget->style()->drawPrimitive(QStyle::PE_PanelItemViewItem, &viewItemOption, painter, widget);
-
-        drawTextBackground(painter);
+        drawItemStyleOption(painter, widget, QStyle::State_Enabled |
+                                             QStyle::State_Selected |
+                                             QStyle::State_Item);
     }
 
     if (isCurrent()) {
@@ -132,32 +125,24 @@ void KItemListWidget::paint(QPainter* painter, const QStyleOptionGraphicsItem* o
         style()->drawPrimitive(QStyle::PE_FrameFocusRect, &viewItemOption, painter, widget);
     }
 
-    if (m_hoverOpacity <= 0.0) {
-        return;
-    }
-
-    if (!m_hoverCache) {
-        // Initialize the m_hoverCache pixmap to improve the drawing performance
-        // when fading the hover background
-        m_hoverCache = new QPixmap(iconBounds.size());
-        m_hoverCache->fill(Qt::transparent);
-
-        QPainter pixmapPainter(m_hoverCache);
-
-        QStyleOptionViewItemV4 viewItemOption;
-        viewItemOption.initFrom(widget);
-        viewItemOption.rect = QRect(0, 0, iconBounds.width(), iconBounds.height());
-        viewItemOption.state = QStyle::State_Enabled | QStyle::State_MouseOver | QStyle::State_Item;
-        viewItemOption.viewItemPosition = QStyleOptionViewItemV4::OnlyOne;
+    if (m_hoverOpacity > 0.0) {
+        if (!m_hoverCache) {
+            // Initialize the m_hoverCache pixmap to improve the drawing performance
+            // when fading the hover background
+            m_hoverCache = new QPixmap(size().toSize());
+            m_hoverCache->fill(Qt::transparent);
+
+            QPainter pixmapPainter(m_hoverCache);
+            drawItemStyleOption(&pixmapPainter, widget, QStyle::State_Enabled |
+                                                        QStyle::State_MouseOver |
+                                                        QStyle::State_Item);
+        }
 
-        widget->style()->drawPrimitive(QStyle::PE_PanelItemViewItem, &viewItemOption, &pixmapPainter, widget);
+        const qreal opacity = painter->opacity();
+        painter->setOpacity(m_hoverOpacity * opacity);
+        painter->drawPixmap(0, 0, *m_hoverCache);
+        painter->setOpacity(opacity);
     }
-
-    const qreal opacity = painter->opacity();
-    painter->setOpacity(m_hoverOpacity * opacity);
-    painter->drawPixmap(iconBounds.topLeft(), *m_hoverCache);
-    drawTextBackground(painter);
-    painter->setOpacity(opacity);
 }
 
 void KItemListWidget::setVisibleRoles(const QList<QByteArray>& roles)
@@ -247,11 +232,14 @@ void KItemListWidget::setHovered(bool hovered)
     m_hoverAnimation->stop();
 
     if (hovered) {
+        const qreal startValue = qMax(hoverOpacity(), qreal(0.1));
+        m_hoverAnimation->setStartValue(startValue);
         m_hoverAnimation->setEndValue(1.0);
         if (m_enabledSelectionToggle && !(QApplication::mouseButtons() & Qt::LeftButton)) {
             initializeSelectionToggle();
         }
     } else {
+        m_hoverAnimation->setStartValue(hoverOpacity());
         m_hoverAnimation->setEndValue(0.0);
     }
 
@@ -408,6 +396,12 @@ void KItemListWidget::setHoverOpacity(qreal opacity)
     if (m_selectionToggle) {
         m_selectionToggle->setOpacity(opacity);
     }
+
+    if (m_hoverOpacity <= 0.0) {
+        delete m_hoverCache;
+        m_hoverCache = 0;
+    }
+
     update();
 }
 
@@ -417,19 +411,29 @@ void KItemListWidget::clearHoverCache()
     m_hoverCache = 0;
 }
 
-void KItemListWidget::drawTextBackground(QPainter* painter)
+void KItemListWidget::drawItemStyleOption(QPainter* painter, QWidget* widget, QStyle::State styleState)
 {
-    const qreal opacity = painter->opacity();
+    const QRect iconBounds = iconRect().toRect();
+    const QRect textBounds = textRect().toRect();
+
+    QStyleOptionViewItemV4 viewItemOption;
+    viewItemOption.initFrom(widget);
+    viewItemOption.state = styleState;
+    viewItemOption.viewItemPosition = QStyleOptionViewItemV4::OnlyOne;
 
-    QRectF textBounds = textRect();
-    const qreal marginDiff = m_styleOption.margin / 2;
-    textBounds.adjust(marginDiff, marginDiff, -marginDiff, -marginDiff);
-    painter->setOpacity(opacity * 0.1);
-    painter->setPen(Qt::NoPen);
-    painter->setBrush(m_styleOption.palette.text());
-    painter->drawRoundedRect(textBounds, 4, 4);
+    const bool drawMerged = (iconBounds.top()    == textBounds.top() &&
+                             iconBounds.bottom() == textBounds.bottom());
 
-    painter->setOpacity(opacity);
+    if (drawMerged) {
+        viewItemOption.rect = iconBounds | textBounds;
+        widget->style()->drawPrimitive(QStyle::PE_PanelItemViewItem, &viewItemOption, painter, widget);
+    } else {
+        viewItemOption.rect = iconBounds;
+        widget->style()->drawPrimitive(QStyle::PE_PanelItemViewItem, &viewItemOption, painter, widget);
+
+        viewItemOption.rect = textBounds.adjusted(2, 2, -2, -2);
+        widget->style()->drawPrimitive(QStyle::PE_PanelItemViewItem, &viewItemOption, painter, widget);
+    }
 }
 
 #include "kitemlistwidget.moc"
index a624950b8a669ab85350706dbc5ea359752bf84f..02e5998f99596a319372f44084d5279cc4767ea7 100644 (file)
@@ -28,6 +28,7 @@
 #include <kitemviews/kitemliststyleoption.h>
 
 #include <QGraphicsWidget>
+#include <QStyle>
 
 class KItemListSelectionToggle;
 class QPropertyAnimation;
@@ -142,7 +143,7 @@ private:
     void initializeSelectionToggle();
     void setHoverOpacity(qreal opacity);
     void clearHoverCache();
-    void drawTextBackground(QPainter* painter);
+    void drawItemStyleOption(QPainter* painter, QWidget* widget, QStyle::State styleState);
 
 private:
     Q_PROPERTY(qreal hoverOpacity READ hoverOpacity WRITE setHoverOpacity)
index 9bb1d03db107db51dd4d254682102192759dffbe..509546d820e2ab3db2a2b2568ded60b7a18408c5 100644 (file)
@@ -99,39 +99,6 @@ DolphinView::DolphinView(const KUrl& url, QWidget* parent) :
     m_topLayout->setSpacing(0);
     m_topLayout->setMargin(0);
 
-    //m_dolphinViewController = new DolphinViewController(this);
-
-    //m_viewModeController = new ViewModeController(this);
-    //m_viewModeController->setUrl(url);
-
-    /*connect(m_viewModeController, SIGNAL(urlChanged(KUrl)),
-            this, SIGNAL(urlChanged(KUrl)));
-
-    connect(m_dolphinViewController, SIGNAL(requestContextMenu(QPoint,QList<QAction*>)),
-            this, SLOT(openContextMenu(QPoint,QList<QAction*>)));
-    connect(m_dolphinViewController, SIGNAL(urlsDropped(KFileItem,KUrl,QDropEvent*)),
-            this, SLOT(dropUrls(KFileItem,KUrl,QDropEvent*)));
-    connect(m_dolphinViewController, SIGNAL(sortingChanged(DolphinView::Sorting)),
-            this, SLOT(updateSorting(DolphinView::Sorting)));
-    connect(m_dolphinViewController, SIGNAL(sortOrderChanged(Qt::SortOrder)),
-            this, SLOT(updateSortOrder(Qt::SortOrder)));
-    connect(m_dolphinViewController, SIGNAL(sortFoldersFirstChanged(bool)),
-            this, SLOT(updateSortFoldersFirst(bool)));
-    connect(m_dolphinViewController, SIGNAL(additionalInfoChanged(QList<DolphinView::AdditionalInfo>)),
-            this, SLOT(updateAdditionalInfo(QList<DolphinView::AdditionalInfo>)));*/
-    //connect(m_dolphinViewController, SIGNAL(itemActivated(KFileItem)),
-    //        this, SLOT(triggerItem(KFileItem)));
-    //connect(m_dolphinViewController, SIGNAL(tabRequested(KUrl)),
-    //        this, SIGNAL(tabRequested(KUrl)));
-    /*connect(m_dolphinViewController, SIGNAL(activated()),
-            this, SLOT(activate()));
-    connect(m_dolphinViewController, SIGNAL(itemEntered(KFileItem)),
-            this, SLOT(showHoverInformation(KFileItem)));
-    connect(m_dolphinViewController, SIGNAL(viewportEntered()),
-            this, SLOT(clearHoverInformation()));
-    connect(m_dolphinViewController, SIGNAL(urlChangeRequested(KUrl)),
-            this, SLOT(slotUrlChangeRequested(KUrl)));*/
-
     // When a new item has been created by the "Create New..." menu, the item should
     // get selected and it must be assured that the item will get visible. As the
     // creation is done asynchronously, several signals must be checked:
@@ -164,6 +131,7 @@ DolphinView::DolphinView(const KUrl& url, QWidget* parent) :
     m_container = new DolphinItemListContainer(m_dirLister, this);
     m_container->setVisibleRoles(QList<QByteArray>() << "name");
     m_container->installEventFilter(this);
+    setFocusProxy(m_container);
 
     KItemListController* controller = m_container->controller();
     controller->setSelectionBehavior(KItemListController::MultiSelection);
@@ -224,25 +192,20 @@ void DolphinView::setActive(bool active)
         color.setAlpha(150);
     }
 
-    /*QAbstractItemView* view = m_viewAccessor.itemView();
-    QWidget* viewport = view ? view->viewport() : 0;
+    QWidget* viewport = m_container->viewport();
     if (viewport) {
         QPalette palette;
         palette.setColor(viewport->backgroundRole(), color);
         viewport->setPalette(palette);
-    }*/
+    }
 
     update();
 
     if (active) {
-        //if (view) {
-        //    view->setFocus();
-        //}
+        m_container->setFocus();
         emit activated();
         emit writeStateChanged(m_isFolderWritable);
     }
-
-    //m_viewModeController->indicateActivationChange(active);
 }
 
 bool DolphinView::isActive() const