File indexing completed on 2024-04-21 04:00:36
0001 /* 0002 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0003 SPDX-FileCopyrightText: 2023 David Redondo <kde@david-redondo.de> 0004 */ 0005 0006 #include "itembranchindicators.h" 0007 0008 #include "kquickstyleitem_p.h" 0009 0010 #include <Kirigami/Platform/PlatformTheme> 0011 0012 #include <QAbstractItemModel> 0013 #include <QGuiApplication> 0014 #include <QStyle> 0015 #include <QStyleOption> 0016 0017 ItemBranchIndicators::ItemBranchIndicators(QQuickItem *parent) 0018 : QQuickPaintedItem(parent) 0019 { 0020 if (auto theme = static_cast<Kirigami::Platform::PlatformTheme *>(qmlAttachedPropertiesObject<Kirigami::Platform::PlatformTheme>(this, true))) { 0021 m_palette = theme->palette(); 0022 connect(theme, &Kirigami::Platform::PlatformTheme::paletteChanged, this, [this](const QPalette &palette) { 0023 m_palette = palette; 0024 update(); 0025 }); 0026 } 0027 } 0028 0029 void ItemBranchIndicators::updateParentChain() 0030 { 0031 const bool wasPainting = parentChain.size() != 0; 0032 parentChain.clear(); 0033 0034 // If we have children the indicator is drawn in the QML 0035 if (m_index.column() == 0) { 0036 auto index = m_index.model()->hasChildren(m_index) ? m_index.parent() : m_index; 0037 // if the TreeView's root index is set, don't go past it 0038 while (index.isValid() && (!m_rootIndex.isValid() || index != m_rootIndex)) { 0039 parentChain.push_back(index); 0040 index = index.parent(); 0041 } 0042 } 0043 0044 const auto elementWidth = KQuickStyleItem::style()->pixelMetric(QStyle::PM_TreeViewIndentation); 0045 setImplicitWidth(elementWidth * parentChain.size()); 0046 0047 if (wasPainting || !parentChain.empty()) { 0048 update(); 0049 } 0050 } 0051 0052 void ItemBranchIndicators::setRootIndex(const QModelIndex &new_root_index) 0053 { 0054 m_rootIndex = new_root_index; 0055 updateParentChain(); 0056 Q_EMIT rootIndexChanged(); 0057 } 0058 0059 void ItemBranchIndicators::setModelIndex(const QModelIndex &new_index) 0060 { 0061 m_index = new_index; 0062 updateParentChain(); 0063 Q_EMIT modelIndexChanged(); 0064 } 0065 0066 void ItemBranchIndicators::setSelected(bool selected) 0067 { 0068 if (m_selected == selected) { 0069 return; 0070 } 0071 m_selected = selected; 0072 update(); 0073 Q_EMIT selectedChanged(); 0074 } 0075 0076 void ItemBranchIndicators::paint(QPainter *painter) 0077 { 0078 const auto elementWidth = KQuickStyleItem::style()->pixelMetric(QStyle::PM_TreeViewIndentation); 0079 QStyleOption styleOption; 0080 styleOption.state.setFlag(QStyle::State_Selected, m_selected); 0081 styleOption.state.setFlag(QStyle::State_Children, false); 0082 styleOption.rect.setSize(QSize(elementWidth, height())); 0083 styleOption.palette = m_palette; 0084 for (auto it = parentChain.rbegin(); it != parentChain.rend(); ++it) { 0085 styleOption.state.setFlag(QStyle::State_Item, *it == m_index); 0086 styleOption.state.setFlag(QStyle::State_Sibling, it->siblingAtRow(it->row() + 1).isValid()); 0087 if (QGuiApplication::layoutDirection() == Qt::LeftToRight) { 0088 styleOption.rect.moveLeft(std::distance(parentChain.rbegin(), it) * elementWidth); 0089 } else { 0090 styleOption.rect.moveLeft((std::distance(it, parentChain.rend()) - 1) * elementWidth); 0091 } 0092 KQuickStyleItem::style()->drawPrimitive(QStyle::PE_IndicatorBranch, &styleOption, painter); 0093 } 0094 }