File indexing completed on 2024-04-21 03:55:59

0001 /*
0002  *  SPDX-FileCopyrightText: 2023 Marco Martin <mart@kde.org>
0003  *  SPDX-FileCopyrightText: 2023 ivan tkachenko <me@ratijas.tk>
0004  *
0005  *  SPDX-License-Identifier: LGPL-2.0-or-later
0006  */
0007 #ifndef HEADERFOOTERLAYOUT_H
0008 #define HEADERFOOTERLAYOUT_H
0009 
0010 #include <QQuickItem>
0011 #include <qtmetamacros.h>
0012 
0013 /**
0014  * replicates a little part of what Page does,
0015  * It's a container with 3 properties, header, contentItem and footer
0016  * which will be laid out oone on top of each other. It works better than a
0017  * ColumnLayout when the elements are to be defined by properties by the
0018  * user, which would require ugly reparenting dances and container items to
0019  * maintain the layout well behaving.
0020  */
0021 class HeaderFooterLayout : public QQuickItem
0022 {
0023     Q_OBJECT
0024     QML_ELEMENT
0025     /**
0026      * @brief This property holds the page header item.
0027      *
0028      * The header item is positioned to the top,
0029      * and resized to the width of the page. The default value is null.
0030      */
0031     Q_PROPERTY(QQuickItem *header READ header WRITE setHeader NOTIFY headerChanged FINAL)
0032 
0033     /**
0034      * @brief This property holds the visual content Item.
0035      *
0036      * It will be resized both in width and height with the layout resizing.
0037      * Its height will be resized to still have room for the heder and footer
0038      */
0039     Q_PROPERTY(QQuickItem *contentItem READ contentItem WRITE setContentItem NOTIFY contentItemChanged FINAL)
0040 
0041     /**
0042      * @brief This property holds the page footer item.
0043      *
0044      * The footer item is positioned to the bottom,
0045      * and resized to the width of the page. The default value is null.
0046      */
0047     Q_PROPERTY(QQuickItem *footer READ footer WRITE setFooter NOTIFY footerChanged FINAL)
0048 
0049 public:
0050     HeaderFooterLayout(QQuickItem *parent = nullptr);
0051     ~HeaderFooterLayout() override;
0052 
0053     void setHeader(QQuickItem *item);
0054     QQuickItem *header();
0055 
0056     void setContentItem(QQuickItem *item);
0057     QQuickItem *contentItem();
0058 
0059     void setFooter(QQuickItem *item);
0060     QQuickItem *footer();
0061 
0062     /**
0063      * @brief HeaderFooterLayout normally positions its header, footer and
0064      * contentItem once per frame (at polish event). This method forces the it
0065      * to recalculate the layout immediately.
0066      */
0067     Q_INVOKABLE void forceLayout();
0068 
0069 Q_SIGNALS:
0070     void headerChanged();
0071     void contentItemChanged();
0072     void footerChanged();
0073 
0074 protected:
0075     void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override;
0076     void componentComplete() override;
0077     void updatePolish() override;
0078 
0079 private:
0080     void markAsDirty();
0081     void performLayout();
0082     void updateImplicitSize();
0083     void disconnectItem(QQuickItem *item);
0084 
0085     QPointer<QQuickItem> m_header;
0086     QPointer<QQuickItem> m_contentItem;
0087     QPointer<QQuickItem> m_footer;
0088 
0089     bool m_isDirty : 1;
0090     bool m_performingLayout : 1;
0091 };
0092 
0093 #endif