| /**************************************************************************** |
| ** |
| ** Copyright (C) 2016 The Qt Company Ltd. |
| ** Contact: https://www.qt.io/licensing/ |
| ** |
| ** This file is part of the Qt Quick Layouts module of the Qt Toolkit. |
| ** |
| ** $QT_BEGIN_LICENSE:LGPL$ |
| ** Commercial License Usage |
| ** Licensees holding valid commercial Qt licenses may use this file in |
| ** accordance with the commercial license agreement provided with the |
| ** Software or, alternatively, in accordance with the terms contained in |
| ** a written agreement between you and The Qt Company. For licensing terms |
| ** and conditions see https://www.qt.io/terms-conditions. For further |
| ** information use the contact form at https://www.qt.io/contact-us. |
| ** |
| ** GNU Lesser General Public License Usage |
| ** Alternatively, this file may be used under the terms of the GNU Lesser |
| ** General Public License version 3 as published by the Free Software |
| ** Foundation and appearing in the file LICENSE.LGPL3 included in the |
| ** packaging of this file. Please review the following information to |
| ** ensure the GNU Lesser General Public License version 3 requirements |
| ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. |
| ** |
| ** GNU General Public License Usage |
| ** Alternatively, this file may be used under the terms of the GNU |
| ** General Public License version 2.0 or (at your option) the GNU General |
| ** Public license version 3 or any later version approved by the KDE Free |
| ** Qt Foundation. The licenses are as published by the Free Software |
| ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 |
| ** included in the packaging of this file. Please review the following |
| ** information to ensure the GNU General Public License requirements will |
| ** be met: https://www.gnu.org/licenses/gpl-2.0.html and |
| ** https://www.gnu.org/licenses/gpl-3.0.html. |
| ** |
| ** $QT_END_LICENSE$ |
| ** |
| ****************************************************************************/ |
| |
| #ifndef QQUICKLAYOUT_P_H |
| #define QQUICKLAYOUT_P_H |
| |
| #include <QPointer> |
| #include <QQuickItem> |
| #include <private/qquickitem_p.h> |
| #include <QtQuick/private/qquickitemchangelistener_p.h> |
| #include <QtGui/private/qlayoutpolicy_p.h> |
| |
| QT_BEGIN_NAMESPACE |
| |
| class QQuickLayoutAttached; |
| |
| #if 0 && !defined(QT_NO_DEBUG) && !defined(QT_NO_DEBUG_OUTPUT) |
| # define quickLayoutDebug QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO).debug |
| #else |
| # define quickLayoutDebug QT_NO_QDEBUG_MACRO |
| #endif |
| |
| class QQuickLayoutPrivate; |
| class QQuickLayout : public QQuickItem, public QQuickItemChangeListener |
| |
| { |
| Q_OBJECT |
| public: |
| enum SizeHint { |
| MinimumSize = 0, |
| PreferredSize, |
| MaximumSize, |
| NSizes |
| }; |
| |
| explicit QQuickLayout(QQuickLayoutPrivate &dd, QQuickItem *parent = 0); |
| ~QQuickLayout(); |
| |
| static QQuickLayoutAttached *qmlAttachedProperties(QObject *object); |
| |
| |
| void componentComplete() override; |
| virtual QSizeF sizeHint(Qt::SizeHint whichSizeHint) const = 0; |
| virtual void setAlignment(QQuickItem *item, Qt::Alignment align) = 0; |
| virtual void invalidate(QQuickItem * childItem = 0); |
| virtual void updateLayoutItems() = 0; |
| |
| // iterator |
| virtual QQuickItem *itemAt(int index) const = 0; |
| virtual int itemCount() const = 0; |
| |
| virtual void rearrange(const QSizeF &); |
| bool arrangementIsDirty() const { return m_dirty; } |
| |
| static void effectiveSizeHints_helper(QQuickItem *item, QSizeF *cachedSizeHints, QQuickLayoutAttached **info, bool useFallbackToWidthOrHeight); |
| static QLayoutPolicy::Policy effectiveSizePolicy_helper(QQuickItem *item, Qt::Orientation orientation, QQuickLayoutAttached *info); |
| bool shouldIgnoreItem(QQuickItem *child, QQuickLayoutAttached *&info, QSizeF *sizeHints) const; |
| void checkAnchors(QQuickItem *item) const; |
| |
| void itemChange(ItemChange change, const ItemChangeData &value) override; |
| void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) override; |
| bool isReady() const; |
| void deactivateRecur(); |
| |
| |
| /* QQuickItemChangeListener */ |
| void itemSiblingOrderChanged(QQuickItem *item) override; |
| void itemImplicitWidthChanged(QQuickItem *item) override; |
| void itemImplicitHeightChanged(QQuickItem *item) override; |
| void itemDestroyed(QQuickItem *item) override; |
| void itemVisibilityChanged(QQuickItem *item) override; |
| |
| protected: |
| void updatePolish() override; |
| |
| enum Orientation { |
| Vertical = 0, |
| Horizontal, |
| NOrientations |
| }; |
| |
| protected slots: |
| void invalidateSenderItem(); |
| |
| private: |
| bool m_dirty; |
| |
| Q_DECLARE_PRIVATE(QQuickLayout) |
| |
| friend class QQuickLayoutAttached; |
| }; |
| |
| |
| class QQuickLayoutPrivate : public QQuickItemPrivate |
| { |
| Q_DECLARE_PUBLIC(QQuickLayout) |
| public: |
| QQuickLayoutPrivate() : m_isReady(false), m_disableRearrange(true) {} |
| |
| protected: |
| unsigned m_isReady : 1; |
| unsigned m_disableRearrange : 1; |
| unsigned m_hasItemChangeListeners : 1; // if false, we don't need to remove its item change listeners... |
| mutable QSet<QQuickItem *> m_ignoredItems; |
| }; |
| |
| |
| class QQuickLayoutAttached : public QObject |
| { |
| Q_OBJECT |
| Q_PROPERTY(qreal minimumWidth READ minimumWidth WRITE setMinimumWidth NOTIFY minimumWidthChanged) |
| Q_PROPERTY(qreal minimumHeight READ minimumHeight WRITE setMinimumHeight NOTIFY minimumHeightChanged) |
| Q_PROPERTY(qreal preferredWidth READ preferredWidth WRITE setPreferredWidth NOTIFY preferredWidthChanged) |
| Q_PROPERTY(qreal preferredHeight READ preferredHeight WRITE setPreferredHeight NOTIFY preferredHeightChanged) |
| Q_PROPERTY(qreal maximumWidth READ maximumWidth WRITE setMaximumWidth NOTIFY maximumWidthChanged) |
| Q_PROPERTY(qreal maximumHeight READ maximumHeight WRITE setMaximumHeight NOTIFY maximumHeightChanged) |
| Q_PROPERTY(bool fillHeight READ fillHeight WRITE setFillHeight NOTIFY fillHeightChanged) |
| Q_PROPERTY(bool fillWidth READ fillWidth WRITE setFillWidth NOTIFY fillWidthChanged) |
| Q_PROPERTY(int row READ row WRITE setRow NOTIFY rowChanged) |
| Q_PROPERTY(int column READ column WRITE setColumn NOTIFY columnChanged) |
| Q_PROPERTY(int rowSpan READ rowSpan WRITE setRowSpan NOTIFY rowSpanChanged) |
| Q_PROPERTY(int columnSpan READ columnSpan WRITE setColumnSpan NOTIFY columnSpanChanged) |
| Q_PROPERTY(Qt::Alignment alignment READ alignment WRITE setAlignment NOTIFY alignmentChanged) |
| |
| Q_PROPERTY(qreal margins READ margins WRITE setMargins NOTIFY marginsChanged) |
| Q_PROPERTY(qreal leftMargin READ leftMargin WRITE setLeftMargin RESET resetLeftMargin NOTIFY leftMarginChanged) |
| Q_PROPERTY(qreal topMargin READ topMargin WRITE setTopMargin RESET resetTopMargin NOTIFY topMarginChanged) |
| Q_PROPERTY(qreal rightMargin READ rightMargin WRITE setRightMargin RESET resetRightMargin NOTIFY rightMarginChanged) |
| Q_PROPERTY(qreal bottomMargin READ bottomMargin WRITE setBottomMargin RESET resetBottomMargin NOTIFY bottomMarginChanged) |
| |
| public: |
| QQuickLayoutAttached(QObject *object); |
| |
| qreal minimumWidth() const { return !m_isMinimumWidthSet ? sizeHint(Qt::MinimumSize, Qt::Horizontal) : m_minimumWidth; } |
| void setMinimumWidth(qreal width); |
| |
| qreal minimumHeight() const { return !m_isMinimumHeightSet ? sizeHint(Qt::MinimumSize, Qt::Vertical) : m_minimumHeight; } |
| void setMinimumHeight(qreal height); |
| |
| qreal preferredWidth() const { return m_preferredWidth; } |
| void setPreferredWidth(qreal width); |
| |
| qreal preferredHeight() const { return m_preferredHeight; } |
| void setPreferredHeight(qreal width); |
| |
| qreal maximumWidth() const { return !m_isMaximumWidthSet ? sizeHint(Qt::MaximumSize, Qt::Horizontal) : m_maximumWidth; } |
| void setMaximumWidth(qreal width); |
| |
| qreal maximumHeight() const { return !m_isMaximumHeightSet ? sizeHint(Qt::MaximumSize, Qt::Vertical) : m_maximumHeight; } |
| void setMaximumHeight(qreal height); |
| |
| void setMinimumImplicitSize(const QSizeF &sz); |
| void setMaximumImplicitSize(const QSizeF &sz); |
| |
| bool fillWidth() const { return m_fillWidth; } |
| void setFillWidth(bool fill); |
| bool isFillWidthSet() const { return m_isFillWidthSet; } |
| |
| bool fillHeight() const { return m_fillHeight; } |
| void setFillHeight(bool fill); |
| bool isFillHeightSet() const { return m_isFillHeightSet; } |
| |
| int row() const { return qMax(m_row, 0); } |
| void setRow(int row); |
| bool isRowSet() const { return m_row >= 0; } |
| int column() const { return qMax(m_column, 0); } |
| void setColumn(int column); |
| bool isColumnSet() const { return m_column >= 0; } |
| |
| int rowSpan() const { return m_rowSpan; } |
| void setRowSpan(int span); |
| int columnSpan() const { return m_columnSpan; } |
| void setColumnSpan(int span); |
| |
| Qt::Alignment alignment() const { return m_alignment; } |
| void setAlignment(Qt::Alignment align); |
| |
| qreal margins() const { return m_defaultMargins; } |
| void setMargins(qreal m); |
| |
| qreal leftMargin() const { return m_isLeftMarginSet ? m_margins.left() : m_defaultMargins; } |
| void setLeftMargin(qreal m); |
| void resetLeftMargin(); |
| |
| qreal topMargin() const { return m_isTopMarginSet ? m_margins.top() : m_defaultMargins; } |
| void setTopMargin(qreal m); |
| void resetTopMargin(); |
| |
| qreal rightMargin() const { return m_isRightMarginSet ? m_margins.right() : m_defaultMargins; } |
| void setRightMargin(qreal m); |
| void resetRightMargin(); |
| |
| qreal bottomMargin() const { return m_isBottomMarginSet ? m_margins.bottom() : m_defaultMargins; } |
| void setBottomMargin(qreal m); |
| void resetBottomMargin(); |
| |
| QMarginsF qMargins() const { |
| return QMarginsF(leftMargin(), topMargin(), rightMargin(), bottomMargin()); |
| } |
| |
| bool setChangesNotificationEnabled(bool enabled) |
| { |
| const bool old = m_changesNotificationEnabled; |
| m_changesNotificationEnabled = enabled; |
| return old; |
| } |
| |
| qreal sizeHint(Qt::SizeHint which, Qt::Orientation orientation) const; |
| |
| bool isExtentExplicitlySet(Qt::Orientation o, Qt::SizeHint whichSize) const |
| { |
| switch (whichSize) { |
| case Qt::MinimumSize: |
| return o == Qt::Horizontal ? m_isMinimumWidthSet : m_isMinimumHeightSet; |
| case Qt::MaximumSize: |
| return o == Qt::Horizontal ? m_isMaximumWidthSet : m_isMaximumHeightSet; |
| case Qt::PreferredSize: |
| return true; // Layout.preferredWidth is always explicitly set |
| case Qt::MinimumDescent: // Not supported |
| case Qt::NSizeHints: |
| return false; |
| } |
| return false; |
| } |
| |
| signals: |
| void minimumWidthChanged(); |
| void minimumHeightChanged(); |
| void preferredWidthChanged(); |
| void preferredHeightChanged(); |
| void maximumWidthChanged(); |
| void maximumHeightChanged(); |
| void fillWidthChanged(); |
| void fillHeightChanged(); |
| void leftMarginChanged(); |
| void topMarginChanged(); |
| void rightMarginChanged(); |
| void bottomMarginChanged(); |
| void marginsChanged(); |
| void rowChanged(); |
| void columnChanged(); |
| void rowSpanChanged(); |
| void columnSpanChanged(); |
| void alignmentChanged(); |
| |
| private: |
| void invalidateItem(); |
| void repopulateLayout(); |
| QQuickLayout *parentLayout() const; |
| QQuickItem *item() const; |
| private: |
| qreal m_minimumWidth; |
| qreal m_minimumHeight; |
| qreal m_preferredWidth; |
| qreal m_preferredHeight; |
| qreal m_maximumWidth; |
| qreal m_maximumHeight; |
| |
| qreal m_defaultMargins; |
| QMarginsF m_margins; |
| |
| qreal m_fallbackWidth; |
| qreal m_fallbackHeight; |
| |
| // GridLayout specific properties |
| int m_row; |
| int m_column; |
| int m_rowSpan; |
| int m_columnSpan; |
| |
| unsigned m_fillWidth : 1; |
| unsigned m_fillHeight : 1; |
| unsigned m_isFillWidthSet : 1; |
| unsigned m_isFillHeightSet : 1; |
| unsigned m_isMinimumWidthSet : 1; |
| unsigned m_isMinimumHeightSet : 1; |
| // preferredWidth and preferredHeight are always explicit, since |
| // their implicit equivalent is implicitWidth and implicitHeight |
| unsigned m_isMaximumWidthSet : 1; |
| unsigned m_isMaximumHeightSet : 1; |
| unsigned m_changesNotificationEnabled : 1; |
| unsigned m_isLeftMarginSet : 1; |
| unsigned m_isTopMarginSet : 1; |
| unsigned m_isRightMarginSet : 1; |
| unsigned m_isBottomMarginSet : 1; |
| Qt::Alignment m_alignment; |
| friend class QQuickLayout; |
| }; |
| |
| inline QQuickLayoutAttached *attachedLayoutObject(QQuickItem *item, bool create = true) |
| { |
| return static_cast<QQuickLayoutAttached *>(qmlAttachedPropertiesObject<QQuickLayout>(item, create)); |
| } |
| |
| QT_END_NAMESPACE |
| |
| QML_DECLARE_TYPE(QQuickLayout) |
| QML_DECLARE_TYPEINFO(QQuickLayout, QML_HAS_ATTACHED_PROPERTIES) |
| |
| #endif // QQUICKLAYOUT_P_H |