File indexing completed on 2024-05-12 17:18:47
0001 /* 0002 * SPDX-FileCopyrightText: 2011 Peter Penz <peter.penz19@gmail.com> 0003 * 0004 * Based on the Itemviews NG project from Trolltech Labs 0005 * 0006 * SPDX-License-Identifier: GPL-2.0-or-later 0007 */ 0008 0009 #ifndef KITEMLISTWIDGET_H 0010 #define KITEMLISTWIDGET_H 0011 0012 #include "dolphin_export.h" 0013 #include "kitemviews/kitemliststyleoption.h" 0014 0015 #include <QBitArray> 0016 #include <QGraphicsWidget> 0017 #include <QStyle> 0018 #include <QTimer> 0019 0020 class KItemListSelectionToggle; 0021 class KItemListView; 0022 class QPropertyAnimation; 0023 0024 /** 0025 * @brief Provides information for creating an instance of KItemListWidget. 0026 * 0027 * KItemListView only creates KItemListWidget instances for the visible 0028 * area. For calculating the required size of all items the expected 0029 * size for the invisible items must be accessible. KItemListWidgetInformant 0030 * provides this information. 0031 */ 0032 class DOLPHIN_EXPORT KItemListWidgetInformant 0033 { 0034 public: 0035 KItemListWidgetInformant(); 0036 virtual ~KItemListWidgetInformant(); 0037 0038 virtual void calculateItemSizeHints(QVector<std::pair<qreal, bool>> &logicalHeightHints, qreal &logicalWidthHint, const KItemListView *view) const = 0; 0039 0040 virtual qreal preferredRoleColumnWidth(const QByteArray &role, int index, const KItemListView *view) const = 0; 0041 }; 0042 0043 /** 0044 * @brief Widget that shows a visible item from the model. 0045 * 0046 * For showing an item from a custom model it is required to at least overwrite KItemListWidget::paint(). 0047 * All properties are set by KItemListView, for each property there is a corresponding 0048 * virtual protected method that allows to react on property changes. 0049 */ 0050 class DOLPHIN_EXPORT KItemListWidget : public QGraphicsWidget 0051 { 0052 Q_OBJECT 0053 0054 Q_PROPERTY(int iconSize READ iconSize WRITE setIconSize) 0055 0056 public: 0057 KItemListWidget(KItemListWidgetInformant *informant, QGraphicsItem *parent); 0058 ~KItemListWidget() override; 0059 0060 void setIndex(int index); 0061 int index() const; 0062 0063 void setData(const QHash<QByteArray, QVariant> &data, const QSet<QByteArray> &roles = QSet<QByteArray>()); 0064 QHash<QByteArray, QVariant> data() const; 0065 0066 /** 0067 * Draws the hover-rectangle if the item is hovered. Overwrite this method 0068 * to show the data of the custom model provided by KItemListWidget::data(). 0069 * @reimp 0070 */ 0071 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = nullptr) override; 0072 0073 void setVisibleRoles(const QList<QByteArray> &roles); 0074 QList<QByteArray> visibleRoles() const; 0075 0076 /** 0077 * Sets the width of a role that should be used if the alignment of the content 0078 * should be done in columns. 0079 */ 0080 void setColumnWidth(const QByteArray &role, qreal width); 0081 qreal columnWidth(const QByteArray &role) const; 0082 0083 void setSidePadding(qreal width); 0084 qreal sidePadding() const; 0085 0086 void setStyleOption(const KItemListStyleOption &option); 0087 const KItemListStyleOption &styleOption() const; 0088 0089 // TODO: Hides QGraphicsItem::setSelected()/isSelected(). Replace 0090 // this by using the default mechanism. 0091 void setSelected(bool selected); 0092 bool isSelected() const; 0093 0094 void setCurrent(bool current); 0095 bool isCurrent() const; 0096 0097 void setHovered(bool hovered); 0098 bool isHovered() const; 0099 0100 void setExpansionAreaHovered(bool hover); 0101 bool expansionAreaHovered() const; 0102 0103 void setHoverPosition(const QPointF &pos); 0104 0105 void setAlternateBackground(bool enable); 0106 bool alternateBackground() const; 0107 0108 void setEnabledSelectionToggle(bool enabled); 0109 bool enabledSelectionToggle() const; 0110 0111 /** 0112 * Sets the sibling information for the item and all of its parents. 0113 * The sibling information of the upper most parent is represented by 0114 * the first bit, the sibling information of the item by the last bit. 0115 * The sibling information is useful for drawing the branches in 0116 * tree views. 0117 */ 0118 void setSiblingsInformation(const QBitArray &siblings); 0119 QBitArray siblingsInformation() const; 0120 0121 /** 0122 * Allows the user to edit the role \a role. The signals 0123 * roleEditingCanceled() or roleEditingFinished() will be 0124 * emitted after editing. An ongoing editing gets canceled if 0125 * the role is empty. Derived classes must implement 0126 * editedRoleChanged(). 0127 */ 0128 void setEditedRole(const QByteArray &role); 0129 QByteArray editedRole() const; 0130 0131 /** 0132 * Contains the actual icon size used to draw the icon. 0133 * Also used during icon resizing animation. 0134 */ 0135 void setIconSize(int iconSize); 0136 int iconSize() const; 0137 0138 /** 0139 * @return True if \a point is inside KItemListWidget::hoverRect(), 0140 * KItemListWidget::textRect(), KItemListWidget::selectionToggleRect() 0141 * or KItemListWidget::expansionToggleRect(). 0142 * @reimp 0143 */ 0144 bool contains(const QPointF &point) const override; 0145 0146 /** 0147 * @return Rectangle for the area that shows the icon. 0148 */ 0149 virtual QRectF iconRect() const = 0; 0150 0151 /** 0152 * @return Rectangle for the area that contains the text-properties. 0153 */ 0154 virtual QRectF textRect() const = 0; 0155 0156 /** 0157 * @return Focus rectangle for indicating the current item. Per default 0158 * textRect() will be returned. Overwrite this method if textRect() 0159 * provides a larger rectangle than the actual text (e.g. to 0160 * be aligned with the iconRect()). The textFocusRect() may not be 0161 * outside the boundaries of textRect(). 0162 */ 0163 virtual QRectF textFocusRect() const; 0164 0165 /** 0166 * @return Rectangle around which a selection box should be drawn if the item is selected. 0167 */ 0168 virtual QRectF selectionRect() const = 0; 0169 0170 /** 0171 * @return Rectangle for the selection-toggle that is used to select or deselect an item. 0172 * Per default an empty rectangle is returned which means that no selection-toggle 0173 * is available. 0174 */ 0175 virtual QRectF selectionToggleRect() const; 0176 0177 /** 0178 * @return Rectangle for the expansion-toggle that is used to open a sub-tree of the model. 0179 * Per default an empty rectangle is returned which means that no opening of sub-trees 0180 * is supported. 0181 */ 0182 virtual QRectF expansionToggleRect() const; 0183 0184 /** 0185 * @return Pixmap that is used when dragging an item. Per default the current state of the 0186 * widget is returned as pixmap. 0187 */ 0188 virtual QPixmap createDragPixmap(const QStyleOptionGraphicsItem *option, QWidget *widget = nullptr); 0189 0190 Q_SIGNALS: 0191 void roleEditingCanceled(int index, const QByteArray &role, const QVariant &value); 0192 void roleEditingFinished(int index, const QByteArray &role, const QVariant &value); 0193 0194 protected: 0195 virtual void dataChanged(const QHash<QByteArray, QVariant> ¤t, const QSet<QByteArray> &roles = QSet<QByteArray>()); 0196 virtual void visibleRolesChanged(const QList<QByteArray> ¤t, const QList<QByteArray> &previous); 0197 virtual void columnWidthChanged(const QByteArray &role, qreal current, qreal previous); 0198 virtual void sidePaddingChanged(qreal width); 0199 virtual void styleOptionChanged(const KItemListStyleOption ¤t, const KItemListStyleOption &previous); 0200 virtual void currentChanged(bool current); 0201 virtual void selectedChanged(bool selected); 0202 virtual void hoveredChanged(bool hovered); 0203 virtual void alternateBackgroundChanged(bool enabled); 0204 virtual void siblingsInformationChanged(const QBitArray ¤t, const QBitArray &previous); 0205 virtual void editedRoleChanged(const QByteArray ¤t, const QByteArray &previous); 0206 virtual void iconSizeChanged(int current, int previous); 0207 void resizeEvent(QGraphicsSceneResizeEvent *event) override; 0208 void clearHoverCache(); 0209 0210 /** 0211 * Called when the user starts hovering this item. 0212 */ 0213 virtual void hoverSequenceStarted(); 0214 0215 /** 0216 * Called in regular intervals while the user is hovering this item. 0217 * 0218 * @param sequenceIndex An index that increases over time while the user hovers. 0219 */ 0220 virtual void hoverSequenceIndexChanged(int sequenceIndex); 0221 0222 /** 0223 * Called when the user stops hovering this item. 0224 */ 0225 virtual void hoverSequenceEnded(); 0226 0227 /** 0228 * @return The current opacity of the hover-animation. When implementing a custom painting-code for a hover-state 0229 * this opacity value should be respected. 0230 */ 0231 qreal hoverOpacity() const; 0232 0233 int hoverSequenceIndex() const; 0234 0235 const KItemListWidgetInformant *informant() const; 0236 0237 private Q_SLOTS: 0238 void slotHoverSequenceTimerTimeout(); 0239 0240 private: 0241 void initializeSelectionToggle(); 0242 void setHoverOpacity(qreal opacity); 0243 void drawItemStyleOption(QPainter *painter, QWidget *widget, QStyle::State styleState); 0244 0245 private: 0246 Q_PROPERTY(qreal hoverOpacity READ hoverOpacity WRITE setHoverOpacity) 0247 0248 KItemListWidgetInformant *m_informant; 0249 int m_index; 0250 bool m_selected; 0251 bool m_current; 0252 bool m_hovered; 0253 bool m_expansionAreaHovered; 0254 bool m_alternateBackground; 0255 bool m_enabledSelectionToggle; 0256 QHash<QByteArray, QVariant> m_data; 0257 QList<QByteArray> m_visibleRoles; 0258 QHash<QByteArray, qreal> m_columnWidths; 0259 qreal m_sidePadding; 0260 KItemListStyleOption m_styleOption; 0261 QBitArray m_siblingsInfo; 0262 0263 qreal m_hoverOpacity; 0264 mutable QPixmap *m_hoverCache; 0265 0266 int m_hoverSequenceIndex; 0267 QTimer m_hoverSequenceTimer; 0268 0269 KItemListSelectionToggle *m_selectionToggle; 0270 0271 QByteArray m_editedRole; 0272 int m_iconSize; 0273 }; 0274 0275 inline const KItemListWidgetInformant *KItemListWidget::informant() const 0276 { 0277 return m_informant; 0278 } 0279 0280 #endif