diff --git a/src/kitemviews/kitemlistwidget.cpp b/src/kitemviews/kitemlistwidget.cpp index 49a13f68f..42bf9ebdc 100644 --- a/src/kitemviews/kitemlistwidget.cpp +++ b/src/kitemviews/kitemlistwidget.cpp @@ -1,526 +1,525 @@ /*************************************************************************** * Copyright (C) 2011 by Peter Penz * * * * Based on the Itemviews NG project from Trolltech Labs * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * ***************************************************************************/ #include "kitemlistwidget.h" #include "kitemlistview.h" #include "private/kitemlistselectiontoggle.h" #include #include #include #include KItemListWidgetInformant::KItemListWidgetInformant() { } KItemListWidgetInformant::~KItemListWidgetInformant() { } KItemListWidget::KItemListWidget(KItemListWidgetInformant* informant, QGraphicsItem* parent) : QGraphicsWidget(parent), m_informant(informant), m_index(-1), m_selected(false), m_current(false), m_hovered(false), m_alternateBackground(false), m_enabledSelectionToggle(false), m_data(), m_visibleRoles(), m_columnWidths(), m_styleOption(), m_siblingsInfo(), m_hoverOpacity(0), m_hoverCache(nullptr), m_hoverAnimation(nullptr), m_selectionToggle(nullptr), m_editedRole() { } KItemListWidget::~KItemListWidget() { clearHoverCache(); } void KItemListWidget::setIndex(int index) { if (m_index != index) { delete m_selectionToggle; m_selectionToggle = nullptr; if (m_hoverAnimation) { m_hoverAnimation->stop(); m_hoverOpacity = 0; } clearHoverCache(); m_index = index; } } int KItemListWidget::index() const { return m_index; } void KItemListWidget::setData(const QHash& data, const QSet& roles) { clearHoverCache(); if (roles.isEmpty()) { m_data = data; dataChanged(m_data); } else { foreach (const QByteArray& role, roles) { m_data[role] = data[role]; } dataChanged(m_data, roles); } update(); } QHash KItemListWidget::data() const { return m_data; } void KItemListWidget::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) { Q_UNUSED(option) 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); } if (m_selected && m_editedRole.isEmpty()) { const QStyle::State activeState(isActiveWindow() ? QStyle::State_Active : 0); drawItemStyleOption(painter, widget, activeState | QStyle::State_Enabled | QStyle::State_Selected | QStyle::State_Item); } if (m_current && m_editedRole.isEmpty()) { QStyleOptionFocusRect focusRectOption; initStyleOption(&focusRectOption); focusRectOption.rect = textFocusRect().toRect(); focusRectOption.state = QStyle::State_Enabled | QStyle::State_Item | QStyle::State_KeyboardFocusChange; if (m_selected) { focusRectOption.state |= QStyle::State_Selected; } style()->drawPrimitive(QStyle::PE_FrameFocusRect, &focusRectOption, painter, widget); } 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); } const qreal opacity = painter->opacity(); painter->setOpacity(m_hoverOpacity * opacity); painter->drawPixmap(0, 0, *m_hoverCache); painter->setOpacity(opacity); } } void KItemListWidget::setVisibleRoles(const QList& roles) { const QList previousRoles = m_visibleRoles; m_visibleRoles = roles; visibleRolesChanged(roles, previousRoles); update(); } QList KItemListWidget::visibleRoles() const { return m_visibleRoles; } void KItemListWidget::setColumnWidth(const QByteArray& role, qreal width) { const qreal previousWidth = m_columnWidths.value(role); if (previousWidth != width) { m_columnWidths.insert(role, width); columnWidthChanged(role, width, previousWidth); update(); } } qreal KItemListWidget::columnWidth(const QByteArray& role) const { return m_columnWidths.value(role); } void KItemListWidget::setStyleOption(const KItemListStyleOption& option) { if (m_styleOption == option) { return; } const KItemListStyleOption previous = m_styleOption; clearHoverCache(); m_styleOption = option; styleOptionChanged(option, previous); update(); } const KItemListStyleOption& KItemListWidget::styleOption() const { return m_styleOption; } void KItemListWidget::setSelected(bool selected) { if (m_selected != selected) { m_selected = selected; if (m_selectionToggle) { m_selectionToggle->setChecked(selected); } selectedChanged(selected); update(); } } bool KItemListWidget::isSelected() const { return m_selected; } void KItemListWidget::setCurrent(bool current) { if (m_current != current) { m_current = current; currentChanged(current); update(); } } bool KItemListWidget::isCurrent() const { return m_current; } void KItemListWidget::setHovered(bool hovered) { if (hovered == m_hovered) { return; } m_hovered = hovered; if (!m_hoverAnimation) { m_hoverAnimation = new QPropertyAnimation(this, "hoverOpacity", this); const int duration = style()->styleHint(QStyle::SH_Widget_Animate) ? 200 : 1; m_hoverAnimation->setDuration(duration); connect(m_hoverAnimation, &QPropertyAnimation::finished, this, &KItemListWidget::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(); } bool KItemListWidget::isHovered() const { return m_hovered; } void KItemListWidget::setHoverPosition(const QPointF& pos) { if (m_selectionToggle) { m_selectionToggle->setHovered(selectionToggleRect().contains(pos)); } } 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; } void KItemListWidget::setEditedRole(const QByteArray& role) { if (m_editedRole != role) { const QByteArray previous = m_editedRole; m_editedRole = role; editedRoleChanged(role, previous); } } QByteArray KItemListWidget::editedRole() const { return m_editedRole; } bool KItemListWidget::contains(const QPointF& point) const { if (!QGraphicsWidget::contains(point)) { return false; } return iconRect().contains(point) || textRect().contains(point) || expansionToggleRect().contains(point) || selectionToggleRect().contains(point); } QRectF KItemListWidget::textFocusRect() const { return textRect(); } QRectF KItemListWidget::selectionToggleRect() const { return QRectF(); } QRectF KItemListWidget::expansionToggleRect() const { return QRectF(); } QPixmap KItemListWidget::createDragPixmap(const QStyleOptionGraphicsItem* option, QWidget* widget) { QPixmap pixmap(size().toSize() * widget->devicePixelRatio()); pixmap.setDevicePixelRatio(widget->devicePixelRatio()); pixmap.fill(Qt::transparent); QPainter painter(&pixmap); const bool oldAlternateBackground = m_alternateBackground; const bool wasSelected = m_selected; const bool wasHovered = m_hovered; setAlternateBackground(false); - setSelected(false); setHovered(false); paint(&painter, option, widget); setAlternateBackground(oldAlternateBackground); setSelected(wasSelected); setHovered(wasHovered); return pixmap; } void KItemListWidget::dataChanged(const QHash& current, const QSet& roles) { Q_UNUSED(current) Q_UNUSED(roles) } void KItemListWidget::visibleRolesChanged(const QList& current, const QList& previous) { Q_UNUSED(current) Q_UNUSED(previous) } void KItemListWidget::columnWidthChanged(const QByteArray& role, qreal current, qreal previous) { Q_UNUSED(role) Q_UNUSED(current) Q_UNUSED(previous) } void KItemListWidget::styleOptionChanged(const KItemListStyleOption& current, const KItemListStyleOption& previous) { Q_UNUSED(current) Q_UNUSED(previous) } void KItemListWidget::currentChanged(bool current) { Q_UNUSED(current) } void KItemListWidget::selectedChanged(bool selected) { Q_UNUSED(selected) } 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::editedRoleChanged(const QByteArray& current, const QByteArray& previous) { Q_UNUSED(current) Q_UNUSED(previous) } void KItemListWidget::resizeEvent(QGraphicsSceneResizeEvent* event) { QGraphicsWidget::resizeEvent(event); clearHoverCache(); if (m_selectionToggle) { const QRectF& toggleRect = selectionToggleRect(); m_selectionToggle->setPos(toggleRect.topLeft()); m_selectionToggle->resize(toggleRect.size()); } } qreal KItemListWidget::hoverOpacity() const { return m_hoverOpacity; } void KItemListWidget::slotHoverAnimationFinished() { if (!m_hovered && m_selectionToggle) { m_selectionToggle->deleteLater(); m_selectionToggle = nullptr; } } 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 = nullptr; } update(); } void KItemListWidget::clearHoverCache() { delete m_hoverCache; m_hoverCache = nullptr; } void KItemListWidget::drawItemStyleOption(QPainter* painter, QWidget* widget, QStyle::State styleState) { QStyleOptionViewItem viewItemOption; initStyleOption(&viewItemOption); viewItemOption.state = styleState; viewItemOption.viewItemPosition = QStyleOptionViewItem::OnlyOne; viewItemOption.showDecorationSelected = true; viewItemOption.rect = selectionRect().toRect(); style()->drawPrimitive(QStyle::PE_PanelItemViewItem, &viewItemOption, painter, widget); }