X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/blobdiff_plain/188d1a9c7d11db2a98f5110fce6ff03afffcb2db..3fc96ef97bbea25418bb22a18e82f6b874eedb38:/src/kitemviews/kitemlistwidget.cpp diff --git a/src/kitemviews/kitemlistwidget.cpp b/src/kitemviews/kitemlistwidget.cpp index 86febed97..951fb396c 100644 --- a/src/kitemviews/kitemlistwidget.cpp +++ b/src/kitemviews/kitemlistwidget.cpp @@ -22,14 +22,16 @@ #include "kitemlistwidget.h" +#include "kitemlistselectiontoggle_p.h" #include "kitemlistview.h" #include "kitemmodelbase.h" #include +#include +#include #include #include -#include #include KItemListWidget::KItemListWidget(QGraphicsItem* parent) : @@ -38,29 +40,36 @@ KItemListWidget::KItemListWidget(QGraphicsItem* parent) : m_selected(false), m_current(false), m_hovered(false), + m_alternateBackground(false), + m_enabledSelectionToggle(false), m_data(), m_visibleRoles(), m_visibleRolesSizes(), m_styleOption(), + m_siblingsInfo(), m_hoverOpacity(0), m_hoverCache(0), - m_hoverAnimation(0) + m_hoverAnimation(0), + m_selectionToggle(0) { } KItemListWidget::~KItemListWidget() { - clearCache(); + clearHoverCache(); } void KItemListWidget::setIndex(int index) { if (m_index != index) { + delete m_selectionToggle; + m_selectionToggle = 0; + if (m_hoverAnimation) { m_hoverAnimation->stop(); m_hoverOpacity = 0; } - clearCache(); + clearHoverCache(); m_index = index; } @@ -74,7 +83,7 @@ int KItemListWidget::index() const void KItemListWidget::setData(const QHash& data, const QSet& roles) { - clearCache(); + clearHoverCache(); if (roles.isEmpty()) { m_data = data; dataChanged(m_data); @@ -84,6 +93,7 @@ void KItemListWidget::setData(const QHash& data, } dataChanged(m_data, roles); } + update(); } QHash KItemListWidget::data() const @@ -95,60 +105,74 @@ void KItemListWidget::paint(QPainter* painter, const QStyleOptionGraphicsItem* o { Q_UNUSED(option); - painter->setRenderHint(QPainter::Antialiasing); + if (m_alternateBackground) { + const QColor backgroundColor = m_styleOption.palette.color(QPalette::AlternateBase); + const QRectF backgroundRect(0, 0, size().width(), size().height()); + 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 | QStyle::State_KeyboardFocusChange; + 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 QHash& roles) +void KItemListWidget::setVisibleRoles(const QList& roles) { - const QHash previousRoles = m_visibleRoles; + const QList previousRoles = m_visibleRoles; m_visibleRoles = roles; + visibleRolesChanged(roles, previousRoles); + update(); } -QHash KItemListWidget::visibleRoles() const +QList KItemListWidget::visibleRoles() const { return m_visibleRoles; } @@ -157,7 +181,9 @@ void KItemListWidget::setVisibleRolesSizes(const QHash roles { const QHash previousRolesSizes = m_visibleRolesSizes; m_visibleRolesSizes = rolesSizes; + visibleRolesSizesChanged(rolesSizes, previousRolesSizes); + update(); } QHash KItemListWidget::visibleRolesSizes() const @@ -168,10 +194,11 @@ QHash KItemListWidget::visibleRolesSizes() const void KItemListWidget::setStyleOption(const KItemListStyleOption& option) { const KItemListStyleOption previous = m_styleOption; - clearCache(); + clearHoverCache(); m_styleOption = option; styleOptionChanged(option, previous); + update(); } const KItemListStyleOption& KItemListWidget::styleOption() const @@ -183,6 +210,9 @@ void KItemListWidget::setSelected(bool selected) { if (m_selected != selected) { m_selected = selected; + if (m_selectionToggle) { + m_selectionToggle->setChecked(selected); + } selectedChanged(selected); update(); } @@ -217,20 +247,27 @@ void KItemListWidget::setHovered(bool hovered) if (!m_hoverAnimation) { m_hoverAnimation = new QPropertyAnimation(this, "hoverOpacity", this); - m_hoverAnimation->setDuration(200); + const int duration = (KGlobalSettings::graphicEffectsLevel() == KGlobalSettings::NoEffects) ? 1 : 200; + m_hoverAnimation->setDuration(duration); + 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); } m_hoverAnimation->start(); hoveredChanged(hovered); - update(); } @@ -239,14 +276,54 @@ bool KItemListWidget::isHovered() const return m_hovered; } +void KItemListWidget::setAlternateBackground(bool enable) +{ + if (m_alternateBackground != enable) { + m_alternateBackground = enable; + alternateBackgroundChanged(enable); + update(); + } +} + +bool KItemListWidget::alternateBackground() const +{ + return m_alternateBackground; +} + +void KItemListWidget::setEnabledSelectionToggle(bool enable) +{ + if (m_enabledSelectionToggle != enable) { + m_enabledSelectionToggle = enable; + update(); + } +} + +bool KItemListWidget::enabledSelectionToggle() const +{ + return m_enabledSelectionToggle; +} + +void KItemListWidget::setSiblingsInformation(const QBitArray& siblings) +{ + const QBitArray previous = m_siblingsInfo; + m_siblingsInfo = siblings; + siblingsInformationChanged(m_siblingsInfo, previous); + update(); +} + +QBitArray KItemListWidget::siblingsInformation() const +{ + return m_siblingsInfo; +} + 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); } @@ -266,15 +343,13 @@ void KItemListWidget::dataChanged(const QHash& current, { Q_UNUSED(current); Q_UNUSED(roles); - update(); } -void KItemListWidget::visibleRolesChanged(const QHash& current, - const QHash& previous) +void KItemListWidget::visibleRolesChanged(const QList& current, + const QList& previous) { Q_UNUSED(current); Q_UNUSED(previous); - update(); } void KItemListWidget::visibleRolesSizesChanged(const QHash& current, @@ -282,7 +357,6 @@ void KItemListWidget::visibleRolesSizesChanged(const QHash& { Q_UNUSED(current); Q_UNUSED(previous); - update(); } void KItemListWidget::styleOptionChanged(const KItemListStyleOption& current, @@ -290,7 +364,6 @@ void KItemListWidget::styleOptionChanged(const KItemListStyleOption& current, { Q_UNUSED(current); Q_UNUSED(previous); - update(); } void KItemListWidget::currentChanged(bool current) @@ -308,10 +381,21 @@ void KItemListWidget::hoveredChanged(bool hovered) Q_UNUSED(hovered); } +void KItemListWidget::alternateBackgroundChanged(bool enabled) +{ + Q_UNUSED(enabled); +} + +void KItemListWidget::siblingsInformationChanged(const QBitArray& current, const QBitArray& previous) +{ + Q_UNUSED(current); + Q_UNUSED(previous); +} + void KItemListWidget::resizeEvent(QGraphicsSceneResizeEvent* event) { QGraphicsWidget::resizeEvent(event); - clearCache(); + clearHoverCache(); } qreal KItemListWidget::hoverOpacity() const @@ -319,56 +403,61 @@ qreal KItemListWidget::hoverOpacity() const return m_hoverOpacity; } -void KItemListWidget::setHoverOpacity(qreal opacity) +void KItemListWidget::slotHoverAnimationFinished() { - m_hoverOpacity = opacity; - update(); + if (!m_hovered) { + delete m_selectionToggle; + m_selectionToggle = 0; + } } -void KItemListWidget::clearCache() +void KItemListWidget::initializeSelectionToggle() { - delete m_hoverCache; - m_hoverCache = 0; + 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::drawFocusIndicator(QPainter* painter) +void KItemListWidget::setHoverOpacity(qreal opacity) { - // 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); + m_hoverOpacity = opacity; + if (m_selectionToggle) { + m_selectionToggle->setOpacity(opacity); + } - 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)); + if (m_hoverOpacity <= 0.0) { + delete m_hoverCache; + m_hoverCache = 0; + } - painter->setRenderHint(QPainter::Antialiasing, false); - painter->setPen(QPen(gradient, 1)); - painter->drawLine(rect.bottomLeft(), rect.bottomRight()); - painter->setRenderHint(QPainter::Antialiasing, true); + update(); } -void KItemListWidget::drawTextBackground(QPainter* painter) +void KItemListWidget::clearHoverCache() { - const qreal opacity = painter->opacity(); + delete m_hoverCache; + m_hoverCache = 0; +} - 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); +void KItemListWidget::drawItemStyleOption(QPainter* painter, QWidget* widget, QStyle::State styleState) +{ + const QRect textBounds = textRect().toRect(); - painter->setOpacity(opacity); + QStyleOptionViewItemV4 viewItemOption; + viewItemOption.initFrom(widget); + viewItemOption.state = styleState; + viewItemOption.viewItemPosition = QStyleOptionViewItemV4::OnlyOne; + viewItemOption.showDecorationSelected = true; + viewItemOption.rect = textBounds.adjusted(1, 0, -1, 0); + widget->style()->drawPrimitive(QStyle::PE_PanelItemViewItem, &viewItemOption, painter, widget); } #include "kitemlistwidget.moc"