X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/blobdiff_plain/517ebd721e12e3a4a3430ac3cba8ce99b33c5b0e..3bf471e0:/src/kitemviews/kitemlistwidget.cpp diff --git a/src/kitemviews/kitemlistwidget.cpp b/src/kitemviews/kitemlistwidget.cpp index 21bfe707f..f729f0239 100644 --- a/src/kitemviews/kitemlistwidget.cpp +++ b/src/kitemviews/kitemlistwidget.cpp @@ -1,52 +1,56 @@ -/*************************************************************************** - * Copyright (C) 2011 by Peter Penz * - * * - * Based on the Itemviews NG project from Trolltech Labs: * - * http://qt.gitorious.org/qt-labs/itemviews-ng * - * * - * 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 * - ***************************************************************************/ +/* + * SPDX-FileCopyrightText: 2011 Peter Penz + * + * Based on the Itemviews NG project from Trolltech Labs + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ #include "kitemlistwidget.h" #include "kitemlistview.h" -#include "kitemmodelbase.h" +#include "private/kitemlistselectiontoggle.h" -#include +#include +#include +#include #include #include -#include #include -KItemListWidget::KItemListWidget(QGraphicsItem* parent) : - QGraphicsWidget(parent, 0), +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_alternatingBackgroundColors(false), + m_expansionAreaHovered(false), + m_alternateBackground(false), + m_enabledSelectionToggle(false), m_data(), m_visibleRoles(), - m_visibleRolesSizes(), + m_columnWidths(), m_styleOption(), + m_siblingsInfo(), m_hoverOpacity(0), - m_hoverCache(0), - m_hoverAnimation(0) + m_hoverCache(nullptr), + m_hoverAnimation(nullptr), + m_hoverSequenceIndex(0), + m_selectionToggle(nullptr), + m_editedRole(), + m_iconSize(-1) { + connect(&m_hoverSequenceTimer, &QTimer::timeout, this, &KItemListWidget::slotHoverSequenceTimerTimeout); } KItemListWidget::~KItemListWidget() @@ -57,6 +61,9 @@ KItemListWidget::~KItemListWidget() void KItemListWidget::setIndex(int index) { if (m_index != index) { + delete m_selectionToggle; + m_selectionToggle = nullptr; + if (m_hoverAnimation) { m_hoverAnimation->stop(); m_hoverOpacity = 0; @@ -80,11 +87,12 @@ void KItemListWidget::setData(const QHash& data, m_data = data; dataChanged(m_data); } else { - foreach (const QByteArray& role, roles) { + for (const QByteArray& role : roles) { m_data[role] = data[role]; } dataChanged(m_data, roles); } + update(); } QHash KItemListWidget::data() const @@ -94,70 +102,63 @@ QHash KItemListWidget::data() const void KItemListWidget::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) { - Q_UNUSED(option); + Q_UNUSED(option) - painter->setRenderHint(QPainter::Antialiasing); - - if (m_alternatingBackgroundColors && (m_index & 0x1)) { + 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 = 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); + 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 (isCurrent()) { - QStyleOptionViewItemV4 viewItemOption; - viewItemOption.initFrom(widget); - viewItemOption.rect = textRect().toRect(); - viewItemOption.state = QStyle::State_Enabled | QStyle::State_Item; - viewItemOption.viewItemPosition = QStyleOptionViewItemV4::OnlyOne; - style()->drawPrimitive(QStyle::PE_FrameFocusRect, &viewItemOption, painter, widget); - } + 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; + } - if (m_hoverOpacity <= 0.0) { - return; + style()->drawPrimitive(QStyle::PE_FrameFocusRect, &focusRectOption, painter, widget); } - 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); + 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) { const QList previousRoles = m_visibleRoles; m_visibleRoles = roles; + visibleRolesChanged(roles, previousRoles); + update(); } QList KItemListWidget::visibleRoles() const @@ -165,25 +166,45 @@ QList KItemListWidget::visibleRoles() const return m_visibleRoles; } -void KItemListWidget::setVisibleRolesSizes(const QHash rolesSizes) + +void KItemListWidget::setColumnWidth(const QByteArray& role, qreal width) { - const QHash previousRolesSizes = m_visibleRolesSizes; - m_visibleRolesSizes = rolesSizes; - visibleRolesSizesChanged(rolesSizes, previousRolesSizes); + const qreal previousWidth = m_columnWidths.value(role); + if (previousWidth != width) { + m_columnWidths.insert(role, width); + columnWidthChanged(role, width, previousWidth); + update(); + } } -QHash KItemListWidget::visibleRolesSizes() const +qreal KItemListWidget::columnWidth(const QByteArray& role) const { - return m_visibleRolesSizes; + return m_columnWidths.value(role); +} + +qreal KItemListWidget::leadingPadding() const { + return m_leadingPadding; +} + +void KItemListWidget::setLeadingPadding(qreal width) { + if (m_leadingPadding != width){ + m_leadingPadding = width; + leadingPaddingChanged(width); + update(); + } } 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 @@ -195,6 +216,9 @@ void KItemListWidget::setSelected(bool selected) { if (m_selected != selected) { m_selected = selected; + if (m_selectionToggle) { + m_selectionToggle->setChecked(selected); + } selectedChanged(selected); update(); } @@ -229,20 +253,39 @@ void KItemListWidget::setHovered(bool hovered) if (!m_hoverAnimation) { m_hoverAnimation = new QPropertyAnimation(this, "hoverOpacity", this); - m_hoverAnimation->setDuration(200); + 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(); + m_hoverSequenceIndex = 0; + 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(); + } + + hoverSequenceStarted(); + + const KConfigGroup globalConfig(KSharedConfig::openConfig(), "PreviewSettings"); + const int interval = globalConfig.readEntry("HoverSequenceInterval", 700); + + m_hoverSequenceTimer.start(interval); } else { + m_hoverAnimation->setStartValue(hoverOpacity()); m_hoverAnimation->setEndValue(0.0); + + hoverSequenceEnded(); + m_hoverSequenceTimer.stop(); } m_hoverAnimation->start(); hoveredChanged(hovered); - update(); } @@ -251,18 +294,93 @@ bool KItemListWidget::isHovered() const return m_hovered; } -void KItemListWidget::setAlternatingBackgroundColors(bool enable) +void KItemListWidget::setExpansionAreaHovered(bool hovered) +{ + if (hovered == m_expansionAreaHovered) { + return; + } + m_expansionAreaHovered = hovered; + update(); +} + +bool KItemListWidget::expansionAreaHovered() const { - if (m_alternatingBackgroundColors != enable) { - m_alternatingBackgroundColors = enable; - alternatingBackgroundColorsChanged(enable); + return m_expansionAreaHovered; +} + +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::alternatingBackgroundColors() const +bool KItemListWidget::alternateBackground() const { - return m_alternatingBackgroundColors; + 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; +} + +void KItemListWidget::setIconSize(int iconSize) +{ + if (m_iconSize != iconSize) { + const int previousIconSize = m_iconSize; + m_iconSize = iconSize; + iconSizeChanged(iconSize, previousIconSize); + } +} + +int KItemListWidget::iconSize() const +{ + return m_iconSize; } bool KItemListWidget::contains(const QPointF& point) const @@ -277,6 +395,11 @@ bool KItemListWidget::contains(const QPointF& point) const selectionToggleRect().contains(point); } +QRectF KItemListWidget::textFocusRect() const +{ + return textRect(); +} + QRectF KItemListWidget::selectionToggleRect() const { return QRectF(); @@ -287,62 +410,131 @@ 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); + 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); - update(); + Q_UNUSED(current) + Q_UNUSED(roles) } void KItemListWidget::visibleRolesChanged(const QList& current, const QList& previous) { - Q_UNUSED(current); - Q_UNUSED(previous); - update(); + Q_UNUSED(current) + Q_UNUSED(previous) } -void KItemListWidget::visibleRolesSizesChanged(const QHash& current, - const QHash& previous) +void KItemListWidget::columnWidthChanged(const QByteArray& role, + qreal current, + qreal previous) { - Q_UNUSED(current); - Q_UNUSED(previous); - update(); + Q_UNUSED(role) + Q_UNUSED(current) + Q_UNUSED(previous) +} + +void KItemListWidget::leadingPaddingChanged(qreal width) +{ + Q_UNUSED(width) } void KItemListWidget::styleOptionChanged(const KItemListStyleOption& current, const KItemListStyleOption& previous) { - Q_UNUSED(current); - Q_UNUSED(previous); - update(); + Q_UNUSED(previous) + + // set the initial value of m_iconSize if not set + if (m_iconSize == -1) { + m_iconSize = current.iconSize; + } } void KItemListWidget::currentChanged(bool current) { - Q_UNUSED(current); + Q_UNUSED(current) } void KItemListWidget::selectedChanged(bool selected) { - Q_UNUSED(selected); + Q_UNUSED(selected) } void KItemListWidget::hoveredChanged(bool hovered) { - Q_UNUSED(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::alternatingBackgroundColorsChanged(bool enabled) +void KItemListWidget::iconSizeChanged(int current, int previous) { - Q_UNUSED(enabled); + 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()); + } +} + +void KItemListWidget::hoverSequenceStarted() +{ +} + +void KItemListWidget::hoverSequenceIndexChanged(int sequenceIndex) +{ + Q_UNUSED(sequenceIndex); +} + +void KItemListWidget::hoverSequenceEnded() +{ } qreal KItemListWidget::hoverOpacity() const @@ -350,31 +542,69 @@ qreal KItemListWidget::hoverOpacity() const return m_hoverOpacity; } +int KItemListWidget::hoverSequenceIndex() const +{ + return m_hoverSequenceIndex; +} + +void KItemListWidget::slotHoverAnimationFinished() +{ + if (!m_hovered && m_selectionToggle) { + m_selectionToggle->deleteLater(); + m_selectionToggle = nullptr; + } +} + +void KItemListWidget::slotHoverSequenceTimerTimeout() +{ + m_hoverSequenceIndex++; + hoverSequenceIndexChanged(m_hoverSequenceIndex); +} + +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 = 0; + m_hoverCache = nullptr; } -void KItemListWidget::drawTextBackground(QPainter* painter) +void KItemListWidget::drawItemStyleOption(QPainter* painter, QWidget* widget, QStyle::State styleState) { - const qreal opacity = painter->opacity(); - - 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); - - painter->setOpacity(opacity); + 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); } -#include "kitemlistwidget.moc"