File indexing completed on 2024-05-12 16:02:29

0001 /*
0002  *  SPDX-FileCopyrightText: 2022 Deif Lou <ginoba@gmail.com>
0003  *
0004  *  SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 
0007 #ifndef KISOPTIONCOLLECTIONWIDGET_H
0008 #define KISOPTIONCOLLECTIONWIDGET_H
0009 
0010 #include <QWidget>
0011 #include <QScopedPointer>
0012 
0013 #include <kritawidgetutils_export.h>
0014 
0015 /**
0016  * @brief Class providing a list of widgets with some addons such as separators,
0017  *        orientation or individual widget visibility
0018  */
0019 class KRITAWIDGETUTILS_EXPORT KisOptionCollectionWidget : public QWidget
0020 {
0021     Q_OBJECT
0022 
0023 public:
0024     KisOptionCollectionWidget(QWidget *parent = nullptr);
0025     ~KisOptionCollectionWidget() override;
0026 
0027     /**
0028      * @brief Get the index of the widget that has the given id
0029      */
0030     int widgetIndexFromId(const QString &id) const;
0031     /**
0032      * @brief Get if the list contains a widget with the given id
0033      */
0034     bool containsWidget(const QString &id) const;
0035 
0036     /**
0037      * @brief Get the widget that is at the given position
0038      */
0039     QWidget* widget(int index) const;
0040     /**
0041      * @brief Get the widget that is at the given position casted to some other class
0042      */
0043     template <typename T>
0044     T widgetAs(int index) const
0045     {
0046         return qobject_cast<T>(widget(index));
0047     }
0048 
0049     /**
0050      * @brief Get the widget with the given id
0051      */
0052     QWidget* widget(const QString &id) const;
0053     /**
0054      * @brief Get the widget with the given id casted to some other class
0055      */
0056     template <typename T>
0057     T widgetAs(const QString &id) const
0058     {
0059         return qobject_cast<T>(widget(id));
0060     }
0061 
0062     /**
0063      * @brief Get the widget that is at the given path. The path must be a
0064      *        forward slash separated list of ids. If the list contains some
0065      *        other @ref KisOptionCollectionWidget or
0066      *        @ref KisOptionCollectionWidgetWithHeader, and they do as well,
0067      *        then they form a hierarchy tree, so the path is searched
0068      *        recursively through all those child widgets
0069      */
0070     QWidget* findWidget(const QString &path) const;
0071     /**
0072      * @brief Get the widget that is at the given path casted to some other class
0073      * @see findWidget
0074      */
0075     template <typename T>
0076     T findWidgetAs(const QString &path) const
0077     {
0078         return qobject_cast<T>(findWidget(path));
0079     }
0080 
0081     /**
0082      * @brief Insert the given widget with the given id at the given position.
0083      *        The list widget takes ownership of the inserted widget
0084      */
0085     void insertWidget(int index, const QString &id, QWidget *widget);
0086     /**
0087      * @brief Insert the given widget with the given id at the end of the list.
0088      *        The list widget takes ownership of the inserted widget
0089      */
0090     void appendWidget(const QString &id, QWidget *widget);
0091 
0092     /**
0093      * @brief Remove the widget that is at the given position from the list.
0094      *        This also destroys the widget
0095      */
0096     void removeWidget(int index);
0097     /**
0098      * @brief Remove the widget that has the given id from the list.
0099      *        This also destroys the widget
0100      */
0101     void removeWidget(const QString &id);
0102 
0103     /**
0104      * @brief Remove the widget that is at the given position from the list.
0105      *        The widget is returned instead of being destroyed
0106      */
0107     QWidget* takeWidget(int index);
0108     /**
0109      * @brief Remove the widget that has the given id from the list.
0110      *        The widget is returned instead of being destroyed
0111      */
0112     QWidget* takeWidget(const QString &id);
0113 
0114     /**
0115      * @brief Set the visibility of the widget that is at the given position.
0116      *        Use this function instead of the widget's one directly to get better
0117      *        visual results
0118      */
0119     void setWidgetVisible(int index, bool visible);
0120     /**
0121      * @brief Set the visibility of the widget that has the given id.
0122      *        Use this function instead of the widget's one directly to get better
0123      *        visual results
0124      */
0125     void setWidgetVisible(const QString &id, bool visible);
0126 
0127     /**
0128      * @brief Set the margins of the widgets. This allows to indent the widgets
0129      *        with respect to the separators. The separators themselves are not
0130      *        changed
0131      */
0132     void setWidgetsMargin(int margin);
0133     /**
0134      * @brief Set the visibility of the separators
0135      */
0136     void setSeparatorsVisible(bool visible);
0137     /**
0138      * @brief Set the orientation of the list of widgets
0139      * @param recursive If set to true and the list contains some
0140      *        @ref KisOptionCollectionWidget or @ref KisOptionCollectionWidgetWithHeader,
0141      *        then the orientation of those child widgets is also set, with the
0142      *        same recursive value
0143      */
0144     void setOrientation(Qt::Orientation orientation, bool recursive = false);
0145 
0146     /**
0147      * @brief Get the number of widgets in the list
0148      */
0149     int size() const;
0150     /**
0151      * @brief Get the number of visible widgets in the list
0152      */
0153     int numberOfVisibleWidgets() const;
0154 
0155 private:
0156     struct Private;
0157     QScopedPointer<Private> m_d;
0158 };
0159 
0160 /**
0161  * @brief Wrapper class around a @ref KisOptionCollectionWidget that also
0162  *        provide a header with a title label and an optional primary widget
0163  */
0164 class KRITAWIDGETUTILS_EXPORT KisOptionCollectionWidgetWithHeader : public QWidget
0165 {
0166     Q_OBJECT
0167 
0168 public:
0169     KisOptionCollectionWidgetWithHeader(const QString &title, QWidget *parent = nullptr);
0170     ~KisOptionCollectionWidgetWithHeader() override;
0171 
0172     QSize minimumSizeHint() const override;
0173     /**
0174      * @brief Get the primary widget
0175      */
0176     QWidget* primaryWidget() const;
0177     /**
0178      * @brief Get the primary widget casted to some other class
0179      */
0180     template <typename T>
0181     T primaryWidgetAs() const
0182     {
0183         return qobject_cast<T>(primaryWidget());
0184     }
0185     /**
0186      * @brief Set the primary widget. The list widget takes ownership of it
0187      */
0188     void setPrimaryWidget(QWidget *widget);
0189     /**
0190      * @brief Remove the primary widget. This also destroys it
0191      */
0192     void removePrimaryWidget();
0193     /**
0194      * @brief Remove the primary widget. The widget is returned instead of
0195      *        being destroyed
0196      */
0197     QWidget* takePrimaryWidget();
0198     /**
0199      * @brief Set the visibility of the primary widget. Use this function
0200      *        instead of the widget one directly to get better visual results
0201      */
0202     void setPrimaryWidgetVisible(bool visible);
0203 
0204     /**
0205      * @brief Get the index of the widget that has the given id
0206      */
0207     int widgetIndexFromId(const QString &id) const;
0208     /**
0209      * @brief Get if the list contains a widget with the given id
0210      */
0211     bool containsWidget(const QString &id) const;
0212 
0213     /**
0214      * @brief Get the widget that is at the given position
0215      */
0216     QWidget* widget(int index) const;
0217     /**
0218      * @brief Get the widget that is at the given position casted to some other class
0219      */
0220     template <typename T>
0221     T widgetAs(int index) const
0222     {
0223         return qobject_cast<T>(widget(index));
0224     }
0225 
0226     /**
0227      * @brief Get the widget with the given id
0228      */
0229     QWidget* widget(const QString &id) const;
0230     /**
0231      * @brief Get the widget with the given id casted to some other class
0232      */
0233     template <typename T>
0234     T widgetAs(const QString &id) const
0235     {
0236         return qobject_cast<T>(widget(id));
0237     }
0238 
0239     /**
0240      * @brief Get the widget that is at the given path. The path must be a
0241      *        forward slash separated list of ids. If the list contains some
0242      *        other @ref KisOptionCollectionWidget or
0243      *        @ref KisOptionCollectionWidgetWithHeader, and they do as well,
0244      *        then they form a hierarchy tree, so the path is searched
0245      *        recursively through all those child widgets
0246      */
0247     QWidget* findWidget(const QString &path) const;
0248     /**
0249      * @brief Get the widget that is at the given path casted to some other class
0250      * @see findWidget
0251      */
0252     template <typename T>
0253     T findWidgetAs(const QString &path) const
0254     {
0255         return qobject_cast<T>(findWidget(path));
0256     }
0257 
0258     /**
0259      * @brief Insert the given widget with the given id at the given position.
0260      *        The list widget takes ownership of the inserted widget
0261      */
0262     void insertWidget(int index, const QString &id, QWidget *widget);
0263     /**
0264      * @brief Insert the given widget with the given id at the end of the list.
0265      *        The list widget takes ownership of the inserted widget
0266      */
0267     void appendWidget(const QString &id, QWidget *widget);
0268 
0269     /**
0270      * @brief Remove the widget that is at the given position from the list.
0271      *        This also destroys the widget
0272      */
0273     void removeWidget(int index);
0274     /**
0275      * @brief Remove the widget that has the given id from the list.
0276      *        This also destroys the widget
0277      */
0278     void removeWidget(const QString &id);
0279 
0280     /**
0281      * @brief Remove the widget that is at the given position from the list.
0282      *        The widget is returned instead of being destroyed
0283      */
0284     QWidget* takeWidget(int index);
0285     /**
0286      * @brief Remove the widget that has the given id from the list.
0287      *        The widget is returned instead of being destroyed
0288      */
0289     QWidget* takeWidget(const QString &id);
0290 
0291     /**
0292      * @brief Set the visibility of the widget that is at the given position
0293      */
0294     void setWidgetVisible(int index, bool visible);
0295     /**
0296      * @brief Set the visibility of the widget that has the given id
0297      */
0298     void setWidgetVisible(const QString &id, bool visible);
0299 
0300     /**
0301      * @brief Set the margins of the widgets. This allows to indent the widgets
0302      *        with respect to the separators. The separators themselves are not
0303      *        changed
0304      */
0305     void setWidgetsMargin(int margin);
0306     /**
0307      * @brief Set the visibility of the separators
0308      */
0309     void setSeparatorsVisible(bool visible);
0310     /**
0311      * @brief Set the orientation of the list of widgets
0312      * @param recursive If set to true and the list contains some
0313      *        @ref KisOptionCollectionWidget or @ref KisOptionCollectionWidgetWithHeader,
0314      *        then the orientation of those child widgets is also set, with the
0315      *        same recursive value
0316      */
0317     void setOrientation(Qt::Orientation orientation, bool recursive = false);
0318 
0319     /**
0320      * @brief Get the number of widgets in the list
0321      */
0322     int size() const;
0323     /**
0324      * @brief Get the number of visible widgets in the list
0325      */
0326     int numberOfVisibleWidgets() const;
0327 
0328 protected:
0329     void resizeEvent(QResizeEvent*) override;
0330 
0331 private:
0332     struct Private;
0333     QScopedPointer<Private> m_d;
0334     friend class KisOptionCollectionWidget;
0335 };
0336 
0337 #endif