X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/blobdiff_plain/d0f1df0cc6eb305fa0b76b41af65a422f42ba6dc..c8d8556950005dfd96ebdb41d2f43ad90356367c:/src/kitemviews/kitemlistwidget.cpp diff --git a/src/kitemviews/kitemlistwidget.cpp b/src/kitemviews/kitemlistwidget.cpp index 5aa6e1baa..61e06078b 100644 --- a/src/kitemviews/kitemlistwidget.cpp +++ b/src/kitemviews/kitemlistwidget.cpp @@ -22,14 +22,15 @@ #include "kitemlistwidget.h" +#include "kitemlistselectiontoggle_p.h" #include "kitemlistview.h" #include "kitemmodelbase.h" #include +#include #include #include -#include #include KItemListWidget::KItemListWidget(QGraphicsItem* parent) : @@ -39,13 +40,15 @@ KItemListWidget::KItemListWidget(QGraphicsItem* parent) : m_current(false), m_hovered(false), m_alternatingBackgroundColors(false), + m_enabledSelectionToggle(false), m_data(), m_visibleRoles(), m_visibleRolesSizes(), m_styleOption(), m_hoverOpacity(0), m_hoverCache(0), - m_hoverAnimation(0) + m_hoverAnimation(0), + m_selectionToggle(0) { } @@ -57,6 +60,9 @@ KItemListWidget::~KItemListWidget() void KItemListWidget::setIndex(int index) { if (m_index != index) { + delete m_selectionToggle; + m_selectionToggle = 0; + if (m_hoverAnimation) { m_hoverAnimation->stop(); m_hoverOpacity = 0; @@ -104,48 +110,56 @@ void KItemListWidget::paint(QPainter* painter, const QStyleOptionGraphicsItem* o painter->fillRect(backgroundRect, backgroundColor); } - const QRect iconBounds = iconBoundingRect().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); + const QStyle::State activeState(isActiveWindow() ? QStyle::State_Active : 0); + drawItemStyleOption(painter, widget, activeState | + QStyle::State_Enabled | + QStyle::State_Selected | + QStyle::State_Item); } if (isCurrent()) { - drawFocusIndicator(painter); - } - - if (m_hoverOpacity <= 0.0) { - return; - } + QStyleOptionFocusRect focusRectOption; + focusRectOption.initFrom(widget); + + const QRect iconBounds = iconRect().toRect(); + const QRect textBounds = textRect().toRect(); + if (iconBounds.bottom() > textBounds.top()) { + focusRectOption.rect = textBounds; + } else { + // See KItemListWidget::drawItemStyleOption(): The selection rectangle + // gets decreased. + focusRectOption.rect = textBounds.adjusted(1, 1, -1, -1); + } - 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); + focusRectOption.state = QStyle::State_Enabled | QStyle::State_Item; + if (m_selected) { + focusRectOption.state |= QStyle::State_Selected; + } - QPainter pixmapPainter(m_hoverCache); + style()->drawPrimitive(QStyle::PE_FrameFocusRect, &focusRectOption, painter, widget); + } - 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); + const QStyle::State activeState(isActiveWindow() ? QStyle::State_Active : 0); + drawItemStyleOption(&pixmapPainter, widget, activeState | + 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) @@ -190,6 +204,10 @@ void KItemListWidget::setSelected(bool selected) { if (m_selected != selected) { m_selected = selected; + if (m_selectionToggle) { + m_selectionToggle->setChecked(selected); + } + selectedChanged(selected); update(); } @@ -204,6 +222,7 @@ void KItemListWidget::setCurrent(bool current) { if (m_current != current) { m_current = current; + currentChanged(current); update(); } @@ -225,12 +244,19 @@ void KItemListWidget::setHovered(bool hovered) if (!m_hoverAnimation) { m_hoverAnimation = new QPropertyAnimation(this, "hoverOpacity", this); m_hoverAnimation->setDuration(200); + connect(m_hoverAnimation, SIGNAL(finished()), this, SLOT(slotHoverAnimationFinished())); } 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); } @@ -260,14 +286,27 @@ bool KItemListWidget::alternatingBackgroundColors() const return m_alternatingBackgroundColors; } +void KItemListWidget::setEnabledSelectionToggle(bool enable) +{ + if (m_enabledSelectionToggle != enable) { + m_enabledSelectionToggle = enable; + update(); + } +} + +bool KItemListWidget::enabledSelectionToggle() const +{ + return m_enabledSelectionToggle; +} + bool KItemListWidget::contains(const QPointF& point) const { if (!QGraphicsWidget::contains(point)) { return false; } - return iconBoundingRect().contains(point) || - textBoundingRect().contains(point) || + return iconRect().contains(point) || + textRect().contains(point) || expansionToggleRect().contains(point) || selectionToggleRect().contains(point); } @@ -345,9 +384,41 @@ qreal KItemListWidget::hoverOpacity() const return m_hoverOpacity; } +void KItemListWidget::slotHoverAnimationFinished() +{ + if (!m_hovered) { + delete m_selectionToggle; + m_selectionToggle = 0; + } +} + +void KItemListWidget::initializeSelectionToggle() +{ + Q_ASSERT(m_enabledSelectionToggle); + + if (!m_selectionToggle) { + m_selectionToggle = new KItemListSelectionToggle(this); + } + + const QRectF toggleRect = selectionToggleRect(); + m_selectionToggle->setPos(toggleRect.topLeft()); + m_selectionToggle->resize(toggleRect.size()); + + m_selectionToggle->setChecked(isSelected()); +} + void KItemListWidget::setHoverOpacity(qreal opacity) { m_hoverOpacity = opacity; + if (m_selectionToggle) { + m_selectionToggle->setOpacity(opacity); + } + + if (m_hoverOpacity <= 0.0) { + delete m_hoverCache; + m_hoverCache = 0; + } + update(); } @@ -357,44 +428,27 @@ void KItemListWidget::clearHoverCache() m_hoverCache = 0; } -void KItemListWidget::drawFocusIndicator(QPainter* painter) +void KItemListWidget::drawItemStyleOption(QPainter* painter, QWidget* widget, QStyle::State styleState) { - // Ideally style()->drawPrimitive(QStyle::PE_FrameFocusRect...) - // should be used, but Oxygen only draws indicators within classes - // derived from QAbstractItemView or Q3ListView. As a workaround - // the indicator is drawn manually. Code copied from oxygenstyle.cpp - // Copyright ( C ) 2009-2010 Hugo Pereira Da Costa - // TODO: Clarify with Oxygen maintainers how to proceed with this. - - const KItemListStyleOption& option = styleOption(); - const QPalette palette = option.palette; - const QRect rect = textBoundingRect().toRect().adjusted(0, 0, 0, -1); - - QLinearGradient gradient(rect.bottomLeft(), rect.bottomRight()); - gradient.setColorAt(0.0, Qt::transparent); - gradient.setColorAt(1.0, Qt::transparent); - gradient.setColorAt(0.2, palette.color(QPalette::Text)); - gradient.setColorAt(0.8, palette.color(QPalette::Text)); + const QRect iconBounds = iconRect().toRect(); + const QRect textBounds = textRect().toRect(); - painter->setRenderHint(QPainter::Antialiasing, false); - painter->setPen(QPen(gradient, 1)); - painter->drawLine(rect.bottomLeft(), rect.bottomRight()); - painter->setRenderHint(QPainter::Antialiasing, true); -} - -void KItemListWidget::drawTextBackground(QPainter* painter) -{ - const qreal opacity = painter->opacity(); + QStyleOptionViewItemV4 viewItemOption; + viewItemOption.initFrom(widget); + viewItemOption.state = styleState; + viewItemOption.viewItemPosition = QStyleOptionViewItemV4::OnlyOne; + viewItemOption.showDecorationSelected = true; - QRectF textBounds = textBoundingRect(); - 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); + 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); - painter->setOpacity(opacity); + viewItemOption.rect = textBounds.adjusted(1, 1, -1, -1); + widget->style()->drawPrimitive(QStyle::PE_PanelItemViewItem, &viewItemOption, painter, widget); + } } #include "kitemlistwidget.moc"