File indexing completed on 2024-05-19 04:27:45
0001 /* 0002 * SPDX-FileCopyrightText: 2023 Srirupa Datta <srirupa.sps@gmail.com> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "KisResourceItemListWidget.h" 0008 0009 #include <QDebug> 0010 #include <QEvent> 0011 #include <QHeaderView> 0012 #include <QHelpEvent> 0013 #include <QScroller> 0014 #include <QScrollBar> 0015 #include <QScrollArea> 0016 0017 #include "KisIconToolTip.h" 0018 0019 0020 struct Q_DECL_HIDDEN KisResourceItemListWidget::Private 0021 { 0022 ListViewMode viewMode = ListViewMode::IconGrid; 0023 bool strictSelectionMode {false}; 0024 KisIconToolTip tip; 0025 0026 QScroller* scroller {0}; 0027 QString prev_scrollbar_style; 0028 }; 0029 0030 KisResourceItemListWidget::KisResourceItemListWidget(QWidget *parent) 0031 : QListWidget(parent) 0032 , m_d(new Private) 0033 { 0034 setSelectionMode(QAbstractItemView::ExtendedSelection); 0035 setContextMenuPolicy(Qt::DefaultContextMenu); 0036 setViewMode(QListView::IconMode); 0037 setGridSize(QSize(56, 56)); 0038 setIconSize(QSize(56, 56)); 0039 setResizeMode(QListWidget::Adjust); 0040 setUniformItemSizes(true); 0041 0042 m_d->scroller = KisKineticScroller::createPreconfiguredScroller(this); 0043 if (m_d->scroller) { 0044 connect(m_d->scroller, SIGNAL(stateChanged(QScroller::State)), this, SLOT(slotScrollerStateChange(QScroller::State))); 0045 } 0046 0047 connect(this, SIGNAL(clicked(QModelIndex)), SIGNAL(currentResourceClicked(const QModelIndex &))); 0048 0049 m_d->prev_scrollbar_style = horizontalScrollBar()->styleSheet(); 0050 } 0051 0052 KisResourceItemListWidget::~KisResourceItemListWidget() 0053 { 0054 } 0055 0056 void KisResourceItemListWidget::setListViewMode(ListViewMode viewMode) 0057 { 0058 m_d->viewMode = viewMode; 0059 0060 switch (viewMode) { 0061 case ListViewMode::IconGrid: { 0062 setViewMode(ViewMode::IconMode); 0063 setFlow(Flow::LeftToRight); 0064 setWrapping(true); 0065 horizontalScrollBar()->setStyleSheet(m_d->prev_scrollbar_style); 0066 setVerticalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAsNeeded); 0067 break; 0068 } 0069 case ListViewMode::IconStripHorizontal: { 0070 setViewMode(ViewMode::IconMode); 0071 setFlow(Flow::LeftToRight); 0072 setWrapping(false); 0073 0074 // this is the only way to hide it and not have it ocupy space 0075 horizontalScrollBar()->setStyleSheet("QScrollBar::horizontal {height: 0px;}"); 0076 setVerticalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAlwaysOff); 0077 break; 0078 } 0079 case ListViewMode::Detail: { 0080 setViewMode(ViewMode::ListMode); 0081 setFlow(Flow::TopToBottom); 0082 setWrapping(false); 0083 // horizontalScrollBar()->setStyleSheet(m_d->prev_scrollbar_style); 0084 setVerticalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAsNeeded); 0085 setHorizontalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAsNeeded); 0086 break; 0087 } 0088 } 0089 0090 setItemSize(iconSize()); 0091 } 0092 0093 void KisResourceItemListWidget::setItemSize(QSize size) 0094 { 0095 switch (m_d->viewMode) { 0096 case ListViewMode::IconGrid: { 0097 setGridSize(size); 0098 setIconSize(size); 0099 break; 0100 } 0101 case ListViewMode::IconStripHorizontal: { 0102 // you can not set the item size in strip mode 0103 // it is configured automatically based on size 0104 break; 0105 } 0106 case ListViewMode::Detail: { 0107 const int w = width(); 0108 setGridSize(QSize(w, size.height())); 0109 setIconSize(QSize(size)); 0110 break; 0111 } 0112 } 0113 } 0114 0115 void KisResourceItemListWidget::setStrictSelectionMode(bool enable) 0116 { 0117 m_d->strictSelectionMode = enable; 0118 } 0119 0120 void KisResourceItemListWidget::setFixedToolTipThumbnailSize(const QSize &size) 0121 { 0122 m_d->tip.setFixedToolTipThumbnailSize(size); 0123 } 0124 0125 void KisResourceItemListWidget::setToolTipShouldRenderCheckers(bool value) 0126 { 0127 m_d->tip.setToolTipShouldRenderCheckers(value); 0128 } 0129 0130 void KisResourceItemListWidget::rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end) 0131 { 0132 // QAbstractItemView moves the current index if the row it points to is removed, 0133 // which we don't want for strict selections 0134 QModelIndex current = currentIndex(); 0135 if (selectionMode() == SingleSelection 0136 && m_d->strictSelectionMode 0137 && current.isValid() 0138 && current.row() >= start 0139 && current.row() <= end) { 0140 0141 selectionModel()->clear(); 0142 } 0143 QListWidget::rowsAboutToBeRemoved(parent, start, end); 0144 } 0145 0146 void KisResourceItemListWidget::selectionChanged(const QItemSelection &selected, const QItemSelection &deselected) 0147 { 0148 // base class takes care of viewport updates 0149 QListWidget::selectionChanged(selected, deselected); 0150 0151 if (selected.isEmpty()) { 0152 emit currentResourceChanged(QModelIndex()); 0153 } 0154 else { 0155 emit currentResourceChanged(selected.indexes().first()); 0156 } 0157 } 0158 0159 QItemSelectionModel::SelectionFlags KisResourceItemListWidget::selectionCommand(const QModelIndex &index, const QEvent *event) const 0160 { 0161 QItemSelectionModel::SelectionFlags cmd = QListWidget::selectionCommand(index, event); 0162 0163 // avoid deselecting the current item by Ctrl-clicking in single selection mode 0164 if (selectionMode() == SingleSelection 0165 && m_d->strictSelectionMode 0166 && cmd.testFlag(QItemSelectionModel::Deselect)) { 0167 0168 cmd = QItemSelectionModel::NoUpdate; 0169 } 0170 return cmd; 0171 } 0172 0173 void KisResourceItemListWidget::contextMenuEvent(QContextMenuEvent *event) 0174 { 0175 QListWidget::contextMenuEvent(event); 0176 emit contextMenuRequested(event->globalPos()); 0177 } 0178 0179 bool KisResourceItemListWidget::viewportEvent(QEvent *event) 0180 { 0181 return QListWidget::viewportEvent(event); 0182 } 0183 0184 void KisResourceItemListWidget::resizeEvent(QResizeEvent *event) 0185 { 0186 if (m_d->viewMode == ListViewMode::IconStripHorizontal) { 0187 const int height = event->size().height(); 0188 setGridSize(QSize(height, height)); 0189 setIconSize(QSize(height, height)); 0190 } 0191 // trigger relaying the items, internally here not externally 0192 // by calling setItemSize 0193 else { 0194 setGridSize(gridSize()); 0195 } 0196 }