From: Peter Penz Date: Sun, 13 Nov 2011 19:55:51 +0000 (+0100) Subject: Fix selection style issues X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/commitdiff_plain/e560a2f6462044c4cf3c66366b6995cf74dd8e2d?ds=sidebyside Fix selection style issues 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 --- diff --git a/src/kitemviews/kfileitemlistwidget.cpp b/src/kitemviews/kfileitemlistwidget.cpp index 8fd00fa02..710253ae8 100644 --- a/src/kitemviews/kfileitemlistwidget.cpp +++ b/src/kitemviews/kfileitemlistwidget.cpp @@ -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& 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(); 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(); diff --git a/src/kitemviews/kfileitemlistwidget.h b/src/kitemviews/kfileitemlistwidget.h index 3c9a1d73a..1f0c89449 100644 --- a/src/kitemviews/kfileitemlistwidget.h +++ b/src/kitemviews/kfileitemlistwidget.h @@ -143,6 +143,8 @@ private: QColor m_additionalInfoTextColor; QPixmap m_overlay; + + QPointF m_selectionTogglePos; }; #endif diff --git a/src/kitemviews/kitemlistcontroller.cpp b/src/kitemviews/kitemlistcontroller.cpp index 8b135fbb5..5d4963bfd 100644 --- a/src/kitemviews/kitemlistcontroller.cpp +++ b/src/kitemviews/kitemlistcontroller.cpp @@ -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; } diff --git a/src/kitemviews/kitemlistselectiontoggle.cpp b/src/kitemviews/kitemlistselectiontoggle.cpp index 43725e0de..014f65b40 100644 --- a/src/kitemviews/kitemlistselectiontoggle.cpp +++ b/src/kitemviews/kitemlistselectiontoggle.cpp @@ -23,6 +23,8 @@ #include #include +#include + 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) { diff --git a/src/kitemviews/kitemlistwidget.cpp b/src/kitemviews/kitemlistwidget.cpp index 04438262f..cf8b54c0c 100644 --- a/src/kitemviews/kitemlistwidget.cpp +++ b/src/kitemviews/kitemlistwidget.cpp @@ -31,7 +31,6 @@ #include #include #include -#include #include 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& 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" diff --git a/src/kitemviews/kitemlistwidget.h b/src/kitemviews/kitemlistwidget.h index a624950b8..02e5998f9 100644 --- a/src/kitemviews/kitemlistwidget.h +++ b/src/kitemviews/kitemlistwidget.h @@ -28,6 +28,7 @@ #include #include +#include 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) diff --git a/src/views/dolphinview.cpp b/src/views/dolphinview.cpp index 9bb1d03db..509546d82 100644 --- a/src/views/dolphinview.cpp +++ b/src/views/dolphinview.cpp @@ -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)), - this, SLOT(openContextMenu(QPoint,QList))); - 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)), - this, SLOT(updateAdditionalInfo(QList)));*/ - //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() << "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