]> cloud.milkyroute.net Git - dolphin.git/commitdiff
Icons view: Layout optimizations
authorPeter Penz <peter.penz19@gmail.com>
Sat, 4 Feb 2012 21:14:53 +0000 (22:14 +0100)
committerPeter Penz <peter.penz19@gmail.com>
Sat, 4 Feb 2012 21:22:19 +0000 (22:22 +0100)
- Assure that landscape-previews use the whole available width of the icon-area
  instead of only using the square width. This waste of space occured if the
  text-width was larger than the icon-width.

- Only use one margin instead of two between the icons and the text to improve the
  visual appearance (thanks to Martin Zilz for the hint)

BUG: 293268
FIXED-IN: 4.8.1
CCMAIL: martin@kreativkonzentrat.de

src/kitemviews/kfileitemlistview.cpp
src/kitemviews/kfileitemlistview.h
src/kitemviews/kfileitemlistwidget.cpp
src/kitemviews/kfileitemlistwidget.h
src/kitemviews/kitemlistview.cpp
src/kitemviews/kitemlistwidget.cpp
src/views/dolphinitemlistcontainer.cpp

index 4762e8089f81e00e764365a09e9c986f55773b65..650ed454f551e4cb4e387e9ab4a20666a9bdf260 100644 (file)
@@ -152,7 +152,7 @@ QSizeF KFileItemListView::itemSizeHint(int index) const
 
         const qreal height = textLinesCount * option.fontMetrics.height() +
                              option.iconSize +
-                             option.margin * 4;
+                             option.margin * 3;
         return QSizeF(itemSize().width(), height);
     }
 
@@ -347,8 +347,7 @@ void KFileItemListView::onModelChanged(KItemModelBase* current, KItemModelBase*
 
     delete m_modelRolesUpdater;
     m_modelRolesUpdater = new KFileItemModelRolesUpdater(static_cast<KFileItemModel*>(current), this);
-    const int size = styleOption().iconSize;
-    m_modelRolesUpdater->setIconSize(QSize(size, size));
+    m_modelRolesUpdater->setIconSize(availableIconSize());
 
     applyRolesToModel();
 }
@@ -462,8 +461,7 @@ void KFileItemListView::updateVisibleIndexRange()
         // of the icon-size before unpausing m_modelRolesUpdater. This prevents
         // an unnecessary expensive recreation of all previews afterwards.
         m_updateIconSizeTimer->stop();
-        const KItemListStyleOption& option = styleOption();
-        m_modelRolesUpdater->setIconSize(QSize(option.iconSize, option.iconSize));
+        m_modelRolesUpdater->setIconSize(availableIconSize());
     }
 
     m_modelRolesUpdater->setPaused(isTransactionActive());
@@ -485,8 +483,7 @@ void KFileItemListView::updateIconSize()
         return;
     }
 
-    const KItemListStyleOption& option = styleOption();
-    m_modelRolesUpdater->setIconSize(QSize(option.iconSize, option.iconSize));
+    m_modelRolesUpdater->setIconSize(availableIconSize());
 
     if (m_updateVisibleIndexRangeTimer->isActive()) {
         // If the visibility-index-range update is pending do an immediate update
@@ -595,4 +592,16 @@ void KFileItemListView::applyRolesToModel()
     m_modelRolesUpdater->setRoles(roles);
 }
 
+QSize KFileItemListView::availableIconSize() const
+{
+    const KItemListStyleOption& option = styleOption();
+    const int iconSize = option.iconSize;
+    if (m_itemLayout == IconsLayout) {
+        const int maxIconWidth = itemSize().width() - 2 * option.margin;
+        return QSize(maxIconWidth, iconSize);
+    }
+
+    return QSize(iconSize, iconSize);
+}
+
 #include "kfileitemlistview.moc"
index 203fb78c4d9bfcced079f7d3bad97acdc60486e8..ea8477858e7b349ea5996843493cd45750c7ff5d 100644 (file)
@@ -124,6 +124,13 @@ private:
      */
     void applyRolesToModel();
 
+    /**
+     * @return Size that is available for the icons. The size might be larger than specified by
+     *         KItemListStyleOption::iconSize: With the IconsLayout also the empty left area left
+     *         and right of an icon will be included.
+     */
+    QSize availableIconSize() const;
+
 private:
     Layout m_itemLayout;
 
index d93e434da16a1bb84af4ca7588787f69a13ce2d6..7a95846d89eb3b99f96bfff0702417e81bd432f2 100644 (file)
@@ -52,7 +52,6 @@ KFileItemListWidget::KFileItemListWidget(QGraphicsItem* parent) :
     m_pixmapPos(),
     m_pixmap(),
     m_scaledPixmapSize(),
-    m_originalPixmapSize(),
     m_iconRect(),
     m_hoverPixmap(),
     m_textPos(),
@@ -448,23 +447,17 @@ void KFileItemListWidget::updatePixmapCache()
     // Precondition: Requires already updated m_textPos values to calculate
     // the remaining height when the alignment is vertical.
 
+    const QSizeF widgetSize = size();
     const bool iconOnTop = (m_layout == IconsLayout);
     const KItemListStyleOption& option = styleOption();
-    const int iconHeight = option.iconSize;
+    const qreal margin = option.margin;
 
-    const QHash<QByteArray, QVariant> values = data();
-    const QSizeF widgetSize = size();
+    const int maxIconWidth = iconOnTop ? widgetSize.width() - 2 * margin : option.iconSize;
+    const int maxIconHeight = option.iconSize;
 
-    int scaledIconHeight = 0;
-    if (iconOnTop) {
-        scaledIconHeight = static_cast<int>(m_textPos[Name].y() - 3 * option.margin);
-    } else {
-        const int textRowsCount = (m_layout == CompactLayout) ? visibleRoles().count() : 1;
-        const qreal requiredTextHeight = textRowsCount * option.fontMetrics.height();
-        scaledIconHeight = (requiredTextHeight < iconHeight) ? widgetSize.height() - 2 * option.margin : iconHeight;
-    }
+    const QHash<QByteArray, QVariant> values = data();
 
-    bool updatePixmap = (iconHeight != m_pixmap.height());
+    bool updatePixmap = (m_pixmap.width() != maxIconWidth || m_pixmap.height() != maxIconHeight);
     if (!updatePixmap && m_dirtyContent) {
         updatePixmap = m_dirtyContentRoles.isEmpty()
                        || m_dirtyContentRoles.contains("iconPixmap")
@@ -482,34 +475,11 @@ void KFileItemListWidget::updatePixmapCache()
                 // use a generic icon as fallback
                 iconName = QLatin1String("unknown");
             }
-            m_pixmap = pixmapForIcon(iconName, iconHeight);
-            m_originalPixmapSize = m_pixmap.size();
-        } else if (m_pixmap.size() != QSize(iconHeight, iconHeight)) {
+            m_pixmap = pixmapForIcon(iconName, maxIconHeight);
+        } else if (m_pixmap.width() != maxIconWidth || m_pixmap.height() != maxIconHeight) {
             // A custom pixmap has been applied. Assure that the pixmap
-            // is scaled to the available size.
-            const bool scale = m_pixmap.width() > iconHeight || m_pixmap.height() > iconHeight ||
-                               (m_pixmap.width() < iconHeight && m_pixmap.height() < iconHeight);
-            if (scale) {
-                KPixmapModifier::scale(m_pixmap, QSize(iconHeight, iconHeight));
-            }
-            m_originalPixmapSize = m_pixmap.size();
-
-            // To simplify the handling of scaling the original pixmap
-            // will be embedded into a square pixmap.
-            QPixmap squarePixmap(iconHeight, iconHeight);
-            squarePixmap.fill(Qt::transparent);
-
-            QPainter painter(&squarePixmap);
-            const int x = (iconHeight - m_pixmap.width()) / 2;  // Center horizontally
-            int y = iconHeight - m_pixmap.height();             // Move to bottom
-            if (!iconOnTop) {
-                y /= 2.0;                                       // Center vertically
-            }
-            painter.drawPixmap(x, y, m_pixmap);
-
-            m_pixmap = squarePixmap;
-        } else {
-            m_originalPixmapSize = m_pixmap.size();
+            // is scaled to the maximum available size.
+            KPixmapModifier::scale(m_pixmap, QSize(maxIconWidth, maxIconHeight));
         }
 
         const QStringList overlays = values["iconOverlays"].toStringList();
@@ -535,40 +505,42 @@ void KFileItemListWidget::updatePixmapCache()
         if (m_isHidden) {
             applyHiddenEffect(m_pixmap);
         }
-
-        Q_ASSERT(m_pixmap.height() == iconHeight);
     }
+
     if (!m_overlay.isNull()) {
         QPainter painter(&m_pixmap);
         painter.drawPixmap(0, m_pixmap.height() - m_overlay.height(), m_overlay);
     }
 
-    m_scaledPixmapSize = QSize(scaledIconHeight, scaledIconHeight);
-
+    int scaledIconSize = 0;
     if (iconOnTop) {
-        m_pixmapPos.setX((widgetSize.width() - m_scaledPixmapSize.width()) / 2);
+        scaledIconSize = static_cast<int>(m_textPos[Name].y() - 2 * margin);
     } else {
-        m_pixmapPos.setX(m_textPos[Name].x() - 2 * option.margin - scaledIconHeight);
+        const int textRowsCount = (m_layout == CompactLayout) ? visibleRoles().count() : 1;
+        const qreal requiredTextHeight = textRowsCount * option.fontMetrics.height();
+        scaledIconSize = (requiredTextHeight < maxIconHeight) ?
+                           widgetSize.height() - 2 * margin : maxIconHeight;
     }
-    m_pixmapPos.setY(option.margin);
 
-    // Center the hover rectangle horizontally and align it on bottom
-    qreal hoverWidth = m_originalPixmapSize.width();
-    qreal hoverHeight = m_originalPixmapSize.height();
-    if (scaledIconHeight != m_pixmap.height()) {
-        const qreal scaleFactor = qreal(scaledIconHeight) / qreal(m_pixmap.height());
-        hoverWidth  *= scaleFactor;
-        hoverHeight *= scaleFactor;
-    }
-    const qreal hoverX = m_pixmapPos.x() + (m_scaledPixmapSize.width() - hoverWidth) / 2.0;
-    qreal hoverY = m_scaledPixmapSize.height() - hoverHeight;
-    if (!iconOnTop) {
-        hoverY /= 2.0;
+    const int maxScaledIconWidth = iconOnTop ? widgetSize.width() - 2 * margin : scaledIconSize;
+    const int maxScaledIconHeight = scaledIconSize;
+
+    m_scaledPixmapSize = m_pixmap.size();
+    m_scaledPixmapSize.scale(maxScaledIconWidth, maxScaledIconHeight, Qt::KeepAspectRatio);
+
+    if (iconOnTop) {
+        // Center horizontally and align on bottom within the icon-area
+        m_pixmapPos.setX((widgetSize.width() - m_scaledPixmapSize.width()) / 2);
+        m_pixmapPos.setY(margin + scaledIconSize - m_scaledPixmapSize.height());
+    } else {
+        // Center horizontally and vertically within the icon-area
+        m_pixmapPos.setX(m_textPos[Name].x() - 2 * margin
+                         - (scaledIconSize + m_scaledPixmapSize.width()) / 2);
+        m_pixmapPos.setY(margin
+                         + (scaledIconSize - m_scaledPixmapSize.height()) / 2);
     }
-    hoverY += m_pixmapPos.y();
 
-    m_iconRect = QRectF(hoverX, hoverY, hoverWidth, hoverHeight);
-    const qreal margin = option.margin;
+    m_iconRect = QRectF(m_pixmapPos, QSizeF(m_scaledPixmapSize));
     m_iconRect.adjust(-margin, -margin, margin, margin);
     
     // Prepare the pixmap that is used when the item gets hovered
@@ -633,7 +605,8 @@ void KFileItemListWidget::updateIconsLayoutTextCache()
     const QHash<QByteArray, QVariant> values = data();
 
     const KItemListStyleOption& option = styleOption();
-    const qreal maxWidth = size().width() - 2 * option.margin;
+    const qreal margin = option.margin;
+    const qreal maxWidth = size().width() - 2 * margin;
     const qreal widgetHeight = size().height();
     const qreal fontHeight = option.fontMetrics.height();
 
@@ -662,8 +635,8 @@ void KFileItemListWidget::updateIconsLayoutTextCache()
     textLinesCount += additionalRolesCount;
 
     m_text[Name].setTextWidth(maxWidth);
-    m_textPos[Name] = QPointF(option.margin, widgetHeight - textLinesCount * fontHeight - option.margin);
-    m_textRect = QRectF(option.margin + (maxWidth - requiredWidthForName) / 2,
+    m_textPos[Name] = QPointF(margin, widgetHeight - textLinesCount * fontHeight - margin);
+    m_textRect = QRectF(margin + (maxWidth - requiredWidthForName) / 2,
                         m_textPos[Name].y(),
                         requiredWidthForName,
                         textLinesCountForName * fontHeight);
@@ -693,23 +666,22 @@ void KFileItemListWidget::updateIconsLayoutTextCache()
                 // in comparison to QTextLine::setLineWidth(). It might happen that the text does
                 // not get elided although it does not fit into the given width. As workaround
                 // the margin is substracted.
-                const QString elidedText = option.fontMetrics.elidedText(text, Qt::ElideRight, maxWidth - option.margin);
+                const QString elidedText = option.fontMetrics.elidedText(text, Qt::ElideRight, maxWidth - margin);
                 m_text[textId].setText(elidedText);
             }
         }
         layout.endLayout();
 
-        m_textPos[textId] = QPointF(option.margin, y);
+        m_textPos[textId] = QPointF(margin, y);
         m_text[textId].setTextWidth(maxWidth);
 
-        const QRectF textRect(option.margin + (maxWidth - requiredWidth) / 2, y, requiredWidth, fontHeight);
+        const QRectF textRect(margin + (maxWidth - requiredWidth) / 2, y, requiredWidth, fontHeight);
         m_textRect |= textRect;
 
         y += fontHeight;
     }
 
     // Add a margin to the text rectangle
-    const qreal margin = option.margin;
     m_textRect.adjust(-margin, -margin, margin, margin);
 }
 
@@ -851,7 +823,7 @@ void KFileItemListWidget::drawPixmap(QPainter* painter, const QPixmap& pixmap)
 
 #ifdef KFILEITEMLISTWIDGET_DEBUG
         painter->setPen(Qt::blue);
-        painter->drawRect(QRectF(m_pixmapPos, QSizeF(scaledPixmap.size())));
+        painter->drawRect(QRectF(m_pixmapPos, QSizeF(m_scaledPixmapSize)));
 #endif
     } else {
         painter->drawPixmap(m_pixmapPos, pixmap);
index 91f00fe73f52672e5c23a11ed8e824a99f33b049..4a44a846889de014a8a128cfb6df889509948a6c 100644 (file)
@@ -139,7 +139,6 @@ private:
     QPixmap m_pixmap;
     QSize m_scaledPixmapSize;
 
-    QSize m_originalPixmapSize; // Size of pixmap before it gets converted to a square pixmap
     QRectF m_iconRect;          // Cache for KItemListWidget::iconRect()
     QPixmap m_hoverPixmap;      // Cache for modified m_pixmap when hovering the item
 
index 67ba01a2f18fc465c52128e91e119d156b3d935a..c671a2e6e939500b787fd0d7c137f8bbc078f79e 100644 (file)
@@ -1847,16 +1847,20 @@ bool KItemListView::changesItemGridLayout(const QSizeF& newGridSize, const QSize
     if (m_layouter->scrollOrientation() == Qt::Vertical) {
         const qreal itemWidth = m_layouter->itemSize().width();
         if (itemWidth > 0) {
-            const int oldColumnCount = m_layouter->size().width() / itemWidth;
             const int newColumnCount = newGridSize.width() / newItemSize.width();
-            return oldColumnCount != newColumnCount;
+            if (m_model->count() > newColumnCount) {
+                const int oldColumnCount = m_layouter->size().width() / itemWidth;
+                return oldColumnCount != newColumnCount;
+            }
         }       
     } else {
         const qreal itemHeight = m_layouter->itemSize().height();
         if (itemHeight > 0) {
-            const int oldRowCount = m_layouter->size().height() / itemHeight;
             const int newRowCount = newGridSize.height() / newItemSize.height();
-            return oldRowCount != newRowCount;
+            if (m_model->count() > newRowCount) {
+                const int oldRowCount = m_layouter->size().height() / itemHeight;
+                return oldRowCount != newRowCount;
+            }
         }               
     }
     
index 8e6c728f7dfa9ba8a695659da2bb83a495f16311..67df036c837764bac862d3f7a62996223a37698f 100644 (file)
@@ -432,7 +432,6 @@ void KItemListWidget::clearHoverCache()
 
 void KItemListWidget::drawItemStyleOption(QPainter* painter, QWidget* widget, QStyle::State styleState)
 {
-    const QRect iconBounds = iconRect().toRect();
     const QRect textBounds = textRect().toRect();
 
     QStyleOptionViewItemV4 viewItemOption;
@@ -440,17 +439,8 @@ void KItemListWidget::drawItemStyleOption(QPainter* painter, QWidget* widget, QS
     viewItemOption.state = styleState;
     viewItemOption.viewItemPosition = QStyleOptionViewItemV4::OnlyOne;
     viewItemOption.showDecorationSelected = true;
-
-    if (iconBounds.bottom() > textBounds.top()) {
-        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(1, 1, -1, -1);
-        widget->style()->drawPrimitive(QStyle::PE_PanelItemViewItem, &viewItemOption, painter, widget);
-    }
+    viewItemOption.rect = textBounds;
+    widget->style()->drawPrimitive(QStyle::PE_PanelItemViewItem, &viewItemOption, painter, widget);
 }
 
 #include "kitemlistwidget.moc"
index c687ede4d4a4702393ee542bcc483800806c2547..4f7a0e06b16ac89d378643b69e203cc188c656b1 100644 (file)
@@ -218,7 +218,7 @@ void DolphinItemListContainer::updateGridSize()
         if (itemWidth < iconSize + innerMargin * 2) {
             itemWidth = iconSize + innerMargin * 2;
         }
-        itemHeight = innerMargin * 2 + iconSize + styleOption.fontMetrics.height();
+        itemHeight = innerMargin * 3 + iconSize + styleOption.fontMetrics.height();
         break;
     }
     case KFileItemListView::CompactLayout: {