File indexing completed on 2024-04-28 04:41:51

0001 /***************************************************************************
0002  *   Copyright (C) 2018 by Emmanuel Lepage Vallee                          *
0003  *   Author : Emmanuel Lepage Vallee <emmanuel.lepage@kde.org>             *
0004  *                                                                         *
0005  *   This program is free software; you can redistribute it and/or modify  *
0006  *   it under the terms of the GNU General Public License as published by  *
0007  *   the Free Software Foundation; either version 3 of the License, or     *
0008  *   (at your option) any later version.                                   *
0009  *                                                                         *
0010  *   This program is distributed in the hope that it will be useful,       *
0011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
0012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
0013  *   GNU General Public License for more details.                          *
0014  *                                                                         *
0015  *   You should have received a copy of the GNU General Public License     *
0016  *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
0017  **************************************************************************/
0018 #ifndef KQUICKITEMVIEWS_SIZEHINTPROXYMODEL_H
0019 #define KQUICKITEMVIEWS_SIZEHINTPROXYMODEL_H
0020 
0021 // Qt
0022 #include <QtCore/QIdentityProxyModel>
0023 #include <QtCore/QVariant>
0024 #include <QJSValue>
0025 #include <QQmlScriptString>
0026 
0027 class SizeHintProxyModelPrivate;
0028 
0029 /**
0030  * This proxy model allows to predict the final size of a view delegate.
0031  *
0032  * This model needs to be implemented when both of the following things are
0033  * used:
0034  *
0035  * * A scrollbar or anything that depends on `contentHeight` being correct
0036  * * A non uniform delegate size
0037  *
0038  * Back in the QtWidgets days, the QItemDelegate/QStyledItemDelegate had the
0039  * `sizeHint` method. It was easy to use because it was the same class that
0040  * performed the painting so it had all the necessary knowledge to return
0041  * the correct value. In QML, however, it's not the case. Predicting the size
0042  * may or may not require knowledge of the style that are not officially in
0043  * public APIs. That being said, it should usually be possible to gather the
0044  * data in one way or another.
0045  *
0046  * This class is part of the public C++ API so the `sizeHint` method can be
0047  * re-implemented. Otherwise it is specified in JavaScript.
0048  */
0049 class Q_DECL_EXPORT SizeHintProxyModel : public QIdentityProxyModel
0050 {
0051     Q_OBJECT
0052 public:
0053     /**
0054      * Return the width for a QModelIndex.
0055      *
0056      * All roles and all constants constants are exposed as variables in the
0057      * expression.
0058      */
0059     Q_PROPERTY(QQmlScriptString widthHint READ widthHint WRITE setWidthHint)
0060 
0061     /**
0062      * Return the width for a QModelIndex.
0063      *
0064      * All roles and all constants constants are exposed as variables in the
0065      * expression.
0066      */
0067     Q_PROPERTY(QQmlScriptString heightHint READ heightHint WRITE setHeightHint)
0068 
0069     /**
0070      * Add variables to the sizeHint callback context that likely wont change
0071      * over time. This is useful to store font metrics and static sizes.
0072      *
0073      * The function is called when the model changes or invalidateContext is
0074      * called.
0075      */
0076     Q_PROPERTY(QJSValue constants READ constants WRITE setConstants)
0077 
0078     /**
0079      * When `dataChanged` on the model is called with a list of invalidated roles
0080      * matching the entries in this list, assume the size hint needs to be
0081      * recomputed.
0082      *
0083      * When used with the other KQuickItemViews views, they will be notified.
0084      *
0085      * Note that the constants wont be invalidated.
0086      */
0087     Q_PROPERTY(QStringList invalidationRoles READ invalidationRoles WRITE setInvalidationRoles)
0088 
0089     explicit SizeHintProxyModel(QObject* parent = nullptr);
0090     virtual ~SizeHintProxyModel();
0091 
0092     virtual void setSourceModel(QAbstractItemModel *newSourceModel) override;
0093 
0094     QQmlScriptString widthHint() const;
0095     void setWidthHint(const QQmlScriptString& value);
0096 
0097     QQmlScriptString heightHint() const;
0098     void setHeightHint(const QQmlScriptString& value);
0099 
0100     QJSValue constants() const;
0101     void setConstants(const QJSValue& value);
0102 
0103     QStringList invalidationRoles() const;
0104     void setInvalidationRoles(const QStringList& l);
0105 
0106     Q_INVOKABLE QSizeF sizeHintForIndex(const QModelIndex& idx);
0107 
0108     Q_INVOKABLE QVariant getRoleValue(const QModelIndex& idx, const QString& roleName) const;
0109 
0110 public Q_SLOTS:
0111     /**
0112      * Call this when the values in the constants may have changed.
0113      */
0114     void invalidateConstants();
0115 
0116 private:
0117     SizeHintProxyModelPrivate* d_ptr;
0118     Q_DECLARE_PRIVATE(SizeHintProxyModel)
0119 };
0120 
0121 Q_DECLARE_METATYPE(SizeHintProxyModel*)
0122 
0123 #endif