diff options
Diffstat (limited to 'src/quicktemplates2')
96 files changed, 4069 insertions, 1113 deletions
diff --git a/src/quicktemplates2/qquickabstractbutton.cpp b/src/quicktemplates2/qquickabstractbutton.cpp index 0a8b8ddf..9f92155e 100644 --- a/src/quicktemplates2/qquickabstractbutton.cpp +++ b/src/quicktemplates2/qquickabstractbutton.cpp @@ -388,6 +388,22 @@ void QQuickAbstractButtonPrivate::executeIndicator(bool complete) quickCompleteDeferred(q, indicatorName(), indicator); } +void QQuickAbstractButtonPrivate::itemImplicitWidthChanged(QQuickItem *item) +{ + Q_Q(QQuickAbstractButton); + QQuickControlPrivate::itemImplicitWidthChanged(item); + if (item == indicator) + emit q->implicitIndicatorWidthChanged(); +} + +void QQuickAbstractButtonPrivate::itemImplicitHeightChanged(QQuickItem *item) +{ + Q_Q(QQuickAbstractButton); + QQuickControlPrivate::itemImplicitHeightChanged(item); + if (item == indicator) + emit q->implicitIndicatorHeightChanged(); +} + QQuickAbstractButton *QQuickAbstractButtonPrivate::findCheckedButton() const { Q_Q(const QQuickAbstractButton); @@ -458,6 +474,7 @@ QQuickAbstractButton::QQuickAbstractButton(QQuickAbstractButtonPrivate &dd, QQui QQuickAbstractButton::~QQuickAbstractButton() { Q_D(QQuickAbstractButton); + d->removeImplicitSizeListener(d->indicator); if (d->group) d->group->removeButton(this); d->ungrabShortcut(); @@ -706,13 +723,24 @@ void QQuickAbstractButton::setIndicator(QQuickItem *indicator) if (!d->indicator.isExecuting()) d->cancelIndicator(); + const qreal oldImplicitIndicatorWidth = implicitIndicatorWidth(); + const qreal oldImplicitIndicatorHeight = implicitIndicatorHeight(); + + d->removeImplicitSizeListener(d->indicator); delete d->indicator; d->indicator = indicator; + if (indicator) { if (!indicator->parentItem()) indicator->setParentItem(this); indicator->setAcceptedMouseButtons(Qt::LeftButton); + d->addImplicitSizeListener(indicator); } + + if (!qFuzzyCompare(oldImplicitIndicatorWidth, implicitIndicatorWidth())) + emit implicitIndicatorWidthChanged(); + if (!qFuzzyCompare(oldImplicitIndicatorHeight, implicitIndicatorHeight())) + emit implicitIndicatorHeightChanged(); if (!d->indicator.isExecuting()) emit indicatorChanged(); } @@ -940,6 +968,50 @@ qreal QQuickAbstractButton::pressY() const } /*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::AbstractButton::implicitIndicatorWidth + \readonly + + This property holds the implicit indicator width. + + The value is equal to \c {indicator ? indicator.implicitWidth : 0}. + + This is typically used, together with \l {Control::}{implicitContentWidth} and + \l {Control::}{implicitBackgroundWidth}, to calculate the \l {Item::}{implicitWidth}. + + \sa implicitIndicatorHeight +*/ +qreal QQuickAbstractButton::implicitIndicatorWidth() const +{ + Q_D(const QQuickAbstractButton); + if (!d->indicator) + return 0; + return d->indicator->implicitWidth(); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::AbstractButton::implicitIndicatorHeight + \readonly + + This property holds the implicit indicator height. + + The value is equal to \c {indicator ? indicator.implicitHeight : 0}. + + This is typically used, together with \l {Control::}{implicitContentHeight} and + \l {Control::}{implicitBackgroundHeight}, to calculate the \l {Item::}{implicitHeight}. + + \sa implicitIndicatorWidth +*/ +qreal QQuickAbstractButton::implicitIndicatorHeight() const +{ + Q_D(const QQuickAbstractButton); + if (!d->indicator) + return 0; + return d->indicator->implicitHeight(); +} + +/*! \qmlmethod void QtQuick.Controls::AbstractButton::toggle() Toggles the checked state of the button. diff --git a/src/quicktemplates2/qquickabstractbutton_p.h b/src/quicktemplates2/qquickabstractbutton_p.h index de0c26ab..0fa48980 100644 --- a/src/quicktemplates2/qquickabstractbutton_p.h +++ b/src/quicktemplates2/qquickabstractbutton_p.h @@ -76,6 +76,9 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickAbstractButton : public QQuickContr Q_PROPERTY(int autoRepeatInterval READ autoRepeatInterval WRITE setAutoRepeatInterval NOTIFY autoRepeatIntervalChanged FINAL REVISION 4) Q_PROPERTY(qreal pressX READ pressX NOTIFY pressXChanged FINAL REVISION 4) Q_PROPERTY(qreal pressY READ pressY NOTIFY pressYChanged FINAL REVISION 4) + // 2.5 (Qt 5.12) + Q_PROPERTY(qreal implicitIndicatorWidth READ implicitIndicatorWidth NOTIFY implicitIndicatorWidthChanged FINAL REVISION 5) + Q_PROPERTY(qreal implicitIndicatorHeight READ implicitIndicatorHeight NOTIFY implicitIndicatorHeightChanged FINAL REVISION 5) Q_CLASSINFO("DeferredPropertyNames", "background,contentItem,indicator") public: @@ -141,6 +144,10 @@ public: qreal pressX() const; qreal pressY() const; + // 2.5 (Qt 5.12) + qreal implicitIndicatorWidth() const; + qreal implicitIndicatorHeight() const; + public Q_SLOTS: void toggle(); @@ -170,6 +177,9 @@ Q_SIGNALS: Q_REVISION(4) void autoRepeatIntervalChanged(); Q_REVISION(4) void pressXChanged(); Q_REVISION(4) void pressYChanged(); + // 2.5 (Qt 5.12) + Q_REVISION(5) void implicitIndicatorWidthChanged(); + Q_REVISION(5) void implicitIndicatorHeightChanged(); protected: QQuickAbstractButton(QQuickAbstractButtonPrivate &dd, QQuickItem *parent); diff --git a/src/quicktemplates2/qquickabstractbutton_p_p.h b/src/quicktemplates2/qquickabstractbutton_p_p.h index bb74e143..d88e5d31 100644 --- a/src/quicktemplates2/qquickabstractbutton_p_p.h +++ b/src/quicktemplates2/qquickabstractbutton_p_p.h @@ -105,6 +105,9 @@ public: void cancelIndicator(); void executeIndicator(bool complete = false); + void itemImplicitWidthChanged(QQuickItem *item) override; + void itemImplicitHeightChanged(QQuickItem *item) override; + QString text; bool explicitText; bool down; diff --git a/src/quicktemplates2/qquickapplicationwindow.cpp b/src/quicktemplates2/qquickapplicationwindow.cpp index 77cf5465..b2ca40f4 100644 --- a/src/quicktemplates2/qquickapplicationwindow.cpp +++ b/src/quicktemplates2/qquickapplicationwindow.cpp @@ -35,6 +35,7 @@ ****************************************************************************/ #include "qquickapplicationwindow_p.h" +#include "qquickcontentitem_p.h" #include "qquickoverlay_p.h" #include "qquickpopup_p_p.h" #include "qquickcontrol_p_p.h" @@ -140,6 +141,8 @@ public: return window->d_func(); } + QQmlListProperty<QObject> contentData(); + void relayout(); void itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &diff) override; @@ -274,7 +277,7 @@ void QQuickApplicationWindowPrivate::updateFont(const QFont &f) void QQuickApplicationWindowPrivate::resolveFont() { - QFont resolvedFont = font.resolve(QQuickControlPrivate::themeFont(QPlatformTheme::SystemFont)); + QFont resolvedFont = font.resolve(QQuickTheme::themeFont(QQuickTheme::System)); setFont_helper(resolvedFont); } @@ -296,7 +299,7 @@ void QQuickApplicationWindowPrivate::updatePalette(const QPalette &p) void QQuickApplicationWindowPrivate::resolvePalette() { - QPalette resolvedPalette = palette.resolve(QQuickControlPrivate::themePalette(QPlatformTheme::SystemPalette)); + QPalette resolvedPalette = palette.resolve(QQuickTheme::themePalette(QQuickTheme::System)); setPalette_helper(resolvedPalette); } @@ -560,9 +563,10 @@ void QQuickApplicationWindow::setFooter(QQuickItem *footer) \sa contentItem */ -QQmlListProperty<QObject> QQuickApplicationWindow::contentData() +QQmlListProperty<QObject> QQuickApplicationWindowPrivate::contentData() { - return QQmlListProperty<QObject>(contentItem(), this, + Q_Q(QQuickApplicationWindow); + return QQmlListProperty<QObject>(q->contentItem(), q, QQuickApplicationWindowPrivate::contentData_append, QQuickItemPrivate::data_count, QQuickItemPrivate::data_at, @@ -584,7 +588,7 @@ QQuickItem *QQuickApplicationWindow::contentItem() const { QQuickApplicationWindowPrivate *d = const_cast<QQuickApplicationWindowPrivate *>(d_func()); if (!d->contentItem) { - d->contentItem = new QQuickItem(QQuickWindow::contentItem()); + d->contentItem = new QQuickContentItem(this, QQuickWindow::contentItem()); d->contentItem->setFlag(QQuickItem::ItemIsFocusScope); d->contentItem->setFocus(true); d->relayout(); @@ -691,7 +695,7 @@ void QQuickApplicationWindow::setFont(const QFont &font) if (d->font.resolve() == font.resolve() && d->font == font) return; - QFont resolvedFont = font.resolve(QQuickControlPrivate::themeFont(QPlatformTheme::SystemFont)); + QFont resolvedFont = font.resolve(QQuickTheme::themeFont(QQuickTheme::System)); d->setFont_helper(resolvedFont); } @@ -770,7 +774,7 @@ void QQuickApplicationWindow::setPalette(const QPalette &palette) if (d->palette.resolve() == palette.resolve() && d->palette == palette) return; - QPalette resolvedPalette = palette.resolve(QQuickControlPrivate::themePalette(QPlatformTheme::SystemPalette)); + QPalette resolvedPalette = palette.resolve(QQuickTheme::themePalette(QQuickTheme::System)); d->setPalette_helper(resolvedPalette); } diff --git a/src/quicktemplates2/qquickapplicationwindow_p.h b/src/quicktemplates2/qquickapplicationwindow_p.h index d74d3c9d..c004ee3a 100644 --- a/src/quicktemplates2/qquickapplicationwindow_p.h +++ b/src/quicktemplates2/qquickapplicationwindow_p.h @@ -66,7 +66,7 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickApplicationWindow : public QQuickWi Q_OBJECT Q_PROPERTY(QQuickItem *background READ background WRITE setBackground NOTIFY backgroundChanged FINAL) Q_PROPERTY(QQuickItem *contentItem READ contentItem CONSTANT FINAL) - Q_PROPERTY(QQmlListProperty<QObject> contentData READ contentData FINAL) + Q_PRIVATE_PROPERTY(QQuickApplicationWindow::d_func(), QQmlListProperty<QObject> contentData READ contentData FINAL) Q_PROPERTY(QQuickItem *activeFocusControl READ activeFocusControl NOTIFY activeFocusControlChanged FINAL) Q_PROPERTY(QQuickItem *header READ header WRITE setHeader NOTIFY headerChanged FINAL) Q_PROPERTY(QQuickItem *footer READ footer WRITE setFooter NOTIFY footerChanged FINAL) @@ -89,7 +89,6 @@ public: void setBackground(QQuickItem *background); QQuickItem *contentItem() const; - QQmlListProperty<QObject> contentData(); QQuickItem *activeFocusControl() const; diff --git a/src/quicktemplates2/qquickbutton.cpp b/src/quicktemplates2/qquickbutton.cpp index a1bea792..ce8cede7 100644 --- a/src/quicktemplates2/qquickbutton.cpp +++ b/src/quicktemplates2/qquickbutton.cpp @@ -102,12 +102,12 @@ QQuickButton::QQuickButton(QQuickButtonPrivate &dd, QQuickItem *parent) QFont QQuickButton::defaultFont() const { - return QQuickControlPrivate::themeFont(QPlatformTheme::PushButtonFont); + return QQuickTheme::themeFont(QQuickTheme::Button); } QPalette QQuickButton::defaultPalette() const { - return QQuickControlPrivate::themePalette(QPlatformTheme::ButtonPalette); + return QQuickTheme::themePalette(QQuickTheme::Button); } /*! diff --git a/src/quicktemplates2/qquickcheckbox.cpp b/src/quicktemplates2/qquickcheckbox.cpp index c6519338..cb2e62e7 100644 --- a/src/quicktemplates2/qquickcheckbox.cpp +++ b/src/quicktemplates2/qquickcheckbox.cpp @@ -189,12 +189,12 @@ void QQuickCheckBox::setCheckState(Qt::CheckState state) QFont QQuickCheckBox::defaultFont() const { - return QQuickControlPrivate::themeFont(QPlatformTheme::CheckBoxFont); + return QQuickTheme::themeFont(QQuickTheme::CheckBox); } QPalette QQuickCheckBox::defaultPalette() const { - return QQuickControlPrivate::themePalette(QPlatformTheme::CheckBoxPalette); + return QQuickTheme::themePalette(QQuickTheme::CheckBox); } void QQuickCheckBox::buttonChange(ButtonChange change) diff --git a/src/quicktemplates2/qquickcheckdelegate.cpp b/src/quicktemplates2/qquickcheckdelegate.cpp index b53877df..35de80ec 100644 --- a/src/quicktemplates2/qquickcheckdelegate.cpp +++ b/src/quicktemplates2/qquickcheckdelegate.cpp @@ -176,7 +176,12 @@ void QQuickCheckDelegate::setCheckState(Qt::CheckState state) QFont QQuickCheckDelegate::defaultFont() const { - return QQuickControlPrivate::themeFont(QPlatformTheme::ListViewFont); + return QQuickTheme::themeFont(QQuickTheme::ListView); +} + +QPalette QQuickCheckDelegate::defaultPalette() const +{ + return QQuickTheme::themePalette(QQuickTheme::ListView); } void QQuickCheckDelegate::buttonChange(ButtonChange change) diff --git a/src/quicktemplates2/qquickcheckdelegate_p.h b/src/quicktemplates2/qquickcheckdelegate_p.h index 67dcf706..2d5a5cb2 100644 --- a/src/quicktemplates2/qquickcheckdelegate_p.h +++ b/src/quicktemplates2/qquickcheckdelegate_p.h @@ -79,6 +79,7 @@ Q_SIGNALS: protected: QFont defaultFont() const override; + QPalette defaultPalette() const override; void buttonChange(ButtonChange change) override; void nextCheckState() override; diff --git a/src/quicktemplates2/qquickcombobox.cpp b/src/quicktemplates2/qquickcombobox.cpp index 4d5efece..d4280b30 100644 --- a/src/quicktemplates2/qquickcombobox.cpp +++ b/src/quicktemplates2/qquickcombobox.cpp @@ -263,6 +263,9 @@ public: void cancelPopup(); void executePopup(bool complete = false); + void itemImplicitWidthChanged(QQuickItem *item) override; + void itemImplicitHeightChanged(QQuickItem *item) override; + bool flat; bool down; bool hasDown; @@ -751,6 +754,22 @@ void QQuickComboBoxPrivate::executePopup(bool complete) quickCompleteDeferred(q, popupName(), popup); } +void QQuickComboBoxPrivate::itemImplicitWidthChanged(QQuickItem *item) +{ + Q_Q(QQuickComboBox); + QQuickControlPrivate::itemImplicitWidthChanged(item); + if (item == indicator) + emit q->implicitIndicatorWidthChanged(); +} + +void QQuickComboBoxPrivate::itemImplicitHeightChanged(QQuickItem *item) +{ + Q_Q(QQuickComboBox); + QQuickControlPrivate::itemImplicitHeightChanged(item); + if (item == indicator) + emit q->implicitIndicatorHeightChanged(); +} + QQuickComboBox::QQuickComboBox(QQuickItem *parent) : QQuickControl(*(new QQuickComboBoxPrivate), parent) { @@ -766,6 +785,7 @@ QQuickComboBox::QQuickComboBox(QQuickItem *parent) QQuickComboBox::~QQuickComboBox() { Q_D(QQuickComboBox); + d->removeImplicitSizeListener(d->indicator); if (d->popup) { // Disconnect visibleChanged() to avoid a spurious highlightedIndexChanged() signal // emission during the destruction of the (visible) popup. (QTBUG-57650) @@ -1072,12 +1092,22 @@ void QQuickComboBox::setIndicator(QQuickItem *indicator) if (!d->indicator.isExecuting()) d->cancelIndicator(); + const qreal oldImplicitIndicatorWidth = implicitIndicatorWidth(); + const qreal oldImplicitIndicatorHeight = implicitIndicatorHeight(); + + d->removeImplicitSizeListener(d->indicator); delete d->indicator; d->indicator = indicator; if (indicator) { if (!indicator->parentItem()) indicator->setParentItem(this); + d->addImplicitSizeListener(indicator); } + + if (!qFuzzyCompare(oldImplicitIndicatorWidth, implicitIndicatorWidth())) + emit implicitIndicatorWidthChanged(); + if (!qFuzzyCompare(oldImplicitIndicatorHeight, implicitIndicatorHeight())) + emit implicitIndicatorHeightChanged(); if (!d->indicator.isExecuting()) emit indicatorChanged(); } @@ -1389,6 +1419,50 @@ bool QQuickComboBox::hasAcceptableInput() const } /*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::ComboBox::implicitIndicatorWidth + \readonly + + This property holds the implicit indicator width. + + The value is equal to \c {indicator ? indicator.implicitWidth : 0}. + + This is typically used, together with \l {Control::}{implicitContentWidth} and + \l {Control::}{implicitBackgroundWidth}, to calculate the \l {Item::}{implicitWidth}. + + \sa implicitIndicatorHeight +*/ +qreal QQuickComboBox::implicitIndicatorWidth() const +{ + Q_D(const QQuickComboBox); + if (!d->indicator) + return 0; + return d->indicator->implicitWidth(); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::ComboBox::implicitIndicatorHeight + \readonly + + This property holds the implicit indicator height. + + The value is equal to \c {indicator ? indicator.implicitHeight : 0}. + + This is typically used, together with \l {Control::}{implicitContentHeight} and + \l {Control::}{implicitBackgroundHeight}, to calculate the \l {Item::}{implicitHeight}. + + \sa implicitIndicatorWidth +*/ +qreal QQuickComboBox::implicitIndicatorHeight() const +{ + Q_D(const QQuickComboBox); + if (!d->indicator) + return 0; + return d->indicator->implicitHeight(); +} + +/*! \qmlmethod string QtQuick.Controls::ComboBox::textAt(int index) Returns the text for the specified \a index, or an empty string @@ -1715,12 +1789,12 @@ void QQuickComboBox::localeChange(const QLocale &newLocale, const QLocale &oldLo QFont QQuickComboBox::defaultFont() const { - return QQuickControlPrivate::themeFont(QPlatformTheme::ComboMenuItemFont); + return QQuickTheme::themeFont(QQuickTheme::ComboBox); } QPalette QQuickComboBox::defaultPalette() const { - return QQuickControlPrivate::themePalette(QPlatformTheme::ComboBoxPalette); + return QQuickTheme::themePalette(QQuickTheme::ComboBox); } #if QT_CONFIG(accessibility) diff --git a/src/quicktemplates2/qquickcombobox_p.h b/src/quicktemplates2/qquickcombobox_p.h index 2faff745..75e535a9 100644 --- a/src/quicktemplates2/qquickcombobox_p.h +++ b/src/quicktemplates2/qquickcombobox_p.h @@ -82,6 +82,9 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickComboBox : public QQuickControl Q_PROPERTY(Qt::InputMethodHints inputMethodHints READ inputMethodHints WRITE setInputMethodHints NOTIFY inputMethodHintsChanged FINAL REVISION 2) Q_PROPERTY(bool inputMethodComposing READ isInputMethodComposing NOTIFY inputMethodComposingChanged FINAL REVISION 2) Q_PROPERTY(bool acceptableInput READ hasAcceptableInput NOTIFY acceptableInputChanged FINAL REVISION 2) + // 2.5 (Qt 5.12) + Q_PROPERTY(qreal implicitIndicatorWidth READ implicitIndicatorWidth NOTIFY implicitIndicatorWidthChanged FINAL REVISION 5) + Q_PROPERTY(qreal implicitIndicatorHeight READ implicitIndicatorHeight NOTIFY implicitIndicatorHeightChanged FINAL REVISION 5) Q_CLASSINFO("DeferredPropertyNames", "background,contentItem,indicator,popup") public: @@ -148,6 +151,10 @@ public: bool isInputMethodComposing() const; bool hasAcceptableInput() const; + // 2.5 (Qt 5.12) + qreal implicitIndicatorWidth() const; + qreal implicitIndicatorHeight() const; + public Q_SLOTS: void incrementCurrentIndex(); void decrementCurrentIndex(); @@ -179,6 +186,9 @@ Q_SIGNALS: Q_REVISION(2) void inputMethodHintsChanged(); Q_REVISION(2) void inputMethodComposingChanged(); Q_REVISION(2) void acceptableInputChanged(); + // 2.5 (Qt 5.12) + Q_REVISION(5) void implicitIndicatorWidthChanged(); + Q_REVISION(5) void implicitIndicatorHeightChanged(); protected: bool eventFilter(QObject *object, QEvent *event) override; diff --git a/src/quicktemplates2/qquickcontainer.cpp b/src/quicktemplates2/qquickcontainer.cpp index 048cfdfa..44f943d9 100644 --- a/src/quicktemplates2/qquickcontainer.cpp +++ b/src/quicktemplates2/qquickcontainer.cpp @@ -193,7 +193,11 @@ static QQuickItem *effectiveContentItem(QQuickItem *item) } QQuickContainerPrivate::QQuickContainerPrivate() - : contentModel(nullptr), + : hasContentWidth(false), + hasContentHeight(false), + contentWidth(0), + contentHeight(0), + contentModel(nullptr), currentIndex(-1), updatingCurrent(false), changeTypes(Destroyed | Parent | SiblingOrder) @@ -206,6 +210,8 @@ void QQuickContainerPrivate::init() contentModel = new QQmlObjectModel(q); QObject::connect(contentModel, &QQmlObjectModel::countChanged, q, &QQuickContainer::countChanged); QObject::connect(contentModel, &QQmlObjectModel::childrenChanged, q, &QQuickContainer::contentChildrenChanged); + connect(q, &QQuickControl::implicitContentWidthChanged, this, &QQuickContainerPrivate::updateContentWidth); + connect(q, &QQuickControl::implicitContentHeightChanged, this, &QQuickContainerPrivate::updateContentHeight); } void QQuickContainerPrivate::cleanup() @@ -377,6 +383,8 @@ void QQuickContainerPrivate::itemDestroyed(QQuickItem *item) int index = contentModel->indexOf(item, nullptr); if (index != -1) removeItem(index, item); + else + QQuickControlPrivate::itemDestroyed(item); } void QQuickContainerPrivate::contentData_append(QQmlListProperty<QObject> *prop, QObject *obj) @@ -436,6 +444,26 @@ void QQuickContainerPrivate::contentChildren_clear(QQmlListProperty<QQuickItem> return QQuickContainerPrivate::get(q)->contentModel->clear(); } +void QQuickContainerPrivate::updateContentWidth() +{ + Q_Q(QQuickContainer); + if (hasContentWidth || qFuzzyCompare(contentWidth, implicitContentWidth)) + return; + + contentWidth = implicitContentWidth; + emit q->contentWidthChanged(); +} + +void QQuickContainerPrivate::updateContentHeight() +{ + Q_Q(QQuickContainer); + if (hasContentHeight || qFuzzyCompare(contentHeight, implicitContentHeight)) + return; + + contentHeight = implicitContentHeight; + emit q->contentHeightChanged(); +} + QQuickContainer::QQuickContainer(QQuickItem *parent) : QQuickControl(*(new QQuickContainerPrivate), parent) { @@ -751,6 +779,84 @@ QQuickItem *QQuickContainer::currentItem() const return itemAt(d->currentIndex); } +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::Container::contentWidth + + This property holds the content width. It is used for calculating the total + implicit width of the container. + + Unless explicitly overridden, the content width is automatically calculated + based on the implicit width of the items in the container. + + \sa contentHeight +*/ +qreal QQuickContainer::contentWidth() const +{ + Q_D(const QQuickContainer); + return d->contentWidth; +} + +void QQuickContainer::setContentWidth(qreal width) +{ + Q_D(QQuickContainer); + d->hasContentWidth = true; + if (qFuzzyCompare(d->contentWidth, width)) + return; + + d->contentWidth = width; + emit contentWidthChanged(); +} + +void QQuickContainer::resetContentWidth() +{ + Q_D(QQuickContainer); + if (!d->hasContentWidth) + return; + + d->hasContentWidth = false; + d->updateContentWidth(); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::Container::contentHeight + + This property holds the content height. It is used for calculating the total + implicit height of the container. + + Unless explicitly overridden, the content height is automatically calculated + based on the implicit height of the items in the container. + + \sa contentWidth +*/ +qreal QQuickContainer::contentHeight() const +{ + Q_D(const QQuickContainer); + return d->contentHeight; +} + +void QQuickContainer::setContentHeight(qreal height) +{ + Q_D(QQuickContainer); + d->hasContentHeight = true; + if (qFuzzyCompare(d->contentHeight, height)) + return; + + d->contentHeight = height; + emit contentHeightChanged(); +} + +void QQuickContainer::resetContentHeight() +{ + Q_D(QQuickContainer); + if (!d->hasContentHeight) + return; + + d->hasContentHeight = false; + d->updateContentHeight(); +} + void QQuickContainer::componentComplete() { Q_D(QQuickContainer); @@ -776,7 +882,7 @@ void QQuickContainer::contentItemChange(QQuickItem *newItem, QQuickItem *oldItem static const int slotIndex = metaObject()->indexOfSlot("_q_currentIndexChanged()"); if (oldItem) { - QQuickItemPrivate::get(oldItem)->removeItemChangeListener(d, QQuickItemPrivate::Children); + QQuickItemPrivate::get(oldItem)->removeItemChangeListener(d, QQuickItemPrivate::Children | QQuickItemPrivate::ImplicitWidth | QQuickItemPrivate::ImplicitHeight); QQuickItem *oldContentItem = effectiveContentItem(oldItem); if (oldContentItem != oldItem) QQuickItemPrivate::get(oldContentItem)->removeItemChangeListener(d, QQuickItemPrivate::Children); @@ -787,7 +893,7 @@ void QQuickContainer::contentItemChange(QQuickItem *newItem, QQuickItem *oldItem } if (newItem) { - QQuickItemPrivate::get(newItem)->addItemChangeListener(d, QQuickItemPrivate::Children); + QQuickItemPrivate::get(newItem)->addItemChangeListener(d, QQuickItemPrivate::Children | QQuickItemPrivate::ImplicitWidth | QQuickItemPrivate::ImplicitHeight); QQuickItem *newContentItem = effectiveContentItem(newItem); if (newContentItem != newItem) QQuickItemPrivate::get(newContentItem)->addItemChangeListener(d, QQuickItemPrivate::Children); diff --git a/src/quicktemplates2/qquickcontainer_p.h b/src/quicktemplates2/qquickcontainer_p.h index 030497cf..310aacd1 100644 --- a/src/quicktemplates2/qquickcontainer_p.h +++ b/src/quicktemplates2/qquickcontainer_p.h @@ -64,6 +64,9 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickContainer : public QQuickControl Q_PROPERTY(QQmlListProperty<QQuickItem> contentChildren READ contentChildren NOTIFY contentChildrenChanged FINAL) Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentIndexChanged FINAL) Q_PROPERTY(QQuickItem *currentItem READ currentItem NOTIFY currentItemChanged FINAL) + // 2.5 (Qt 5.12) + Q_PROPERTY(qreal contentWidth READ contentWidth WRITE setContentWidth RESET resetContentWidth NOTIFY contentWidthChanged FINAL REVISION 5) + Q_PROPERTY(qreal contentHeight READ contentHeight WRITE setContentHeight RESET resetContentHeight NOTIFY contentHeightChanged FINAL REVISION 5) Q_CLASSINFO("DefaultProperty", "contentData") public: @@ -87,6 +90,15 @@ public: int currentIndex() const; QQuickItem *currentItem() const; + // 2.5 (Qt 5.12) + qreal contentWidth() const; + void setContentWidth(qreal width); + void resetContentWidth(); + + qreal contentHeight() const; + void setContentHeight(qreal height); + void resetContentHeight(); + public Q_SLOTS: void setCurrentIndex(int index); // 2.1 (Qt 5.8) @@ -98,6 +110,9 @@ Q_SIGNALS: void contentChildrenChanged(); void currentIndexChanged(); void currentItemChanged(); + // 2.5 (Qt 5.12) + Q_REVISION(5) void contentWidthChanged(); + Q_REVISION(5) void contentHeightChanged(); protected: QQuickContainer(QQuickContainerPrivate &dd, QQuickItem *parent); diff --git a/src/quicktemplates2/qquickcontainer_p_p.h b/src/quicktemplates2/qquickcontainer_p_p.h index 7791b69c..28190f07 100644 --- a/src/quicktemplates2/qquickcontainer_p_p.h +++ b/src/quicktemplates2/qquickcontainer_p_p.h @@ -50,12 +50,11 @@ #include <QtQuickTemplates2/private/qquickcontainer_p.h> #include <QtQuickTemplates2/private/qquickcontrol_p_p.h> -#include <QtQuick/private/qquickitemchangelistener_p.h> #include <QtQml/private/qqmlobjectmodel_p.h> QT_BEGIN_NAMESPACE -class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickContainerPrivate : public QQuickControlPrivate, public QQuickItemChangeListener +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickContainerPrivate : public QQuickControlPrivate { Q_DECLARE_PUBLIC(QQuickContainer) @@ -93,6 +92,13 @@ public: static QQuickItem *contentChildren_at(QQmlListProperty<QQuickItem> *prop, int index); static void contentChildren_clear(QQmlListProperty<QQuickItem> *prop); + void updateContentWidth(); + void updateContentHeight(); + + bool hasContentWidth; + bool hasContentHeight; + qreal contentWidth; + qreal contentHeight; QObjectList contentData; QQmlObjectModel *contentModel; int currentIndex; diff --git a/src/quicktemplates2/qquickcontentitem.cpp b/src/quicktemplates2/qquickcontentitem.cpp new file mode 100644 index 00000000..95665f70 --- /dev/null +++ b/src/quicktemplates2/qquickcontentitem.cpp @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickcontentitem_p.h" + +#include <QtQml/private/qqmlmetatype_p.h> + +QT_BEGIN_NAMESPACE + +/*! + \internal + + Helper class that aids debugging by producing more useful debugging output. +*/ + +QQuickContentItem::QQuickContentItem(QQuickItem *parent) + : QQuickItem(parent) +{ + setObjectName(QQmlMetaType::prettyTypeName(parent)); +} + +QQuickContentItem::QQuickContentItem(const QObject *scope, QQuickItem *parent) + : QQuickItem(parent) +{ + setObjectName(QQmlMetaType::prettyTypeName(scope)); +} + +QT_END_NAMESPACE diff --git a/src/quicktemplates2/qquickcontentitem_p.h b/src/quicktemplates2/qquickcontentitem_p.h new file mode 100644 index 00000000..df0f0b24 --- /dev/null +++ b/src/quicktemplates2/qquickcontentitem_p.h @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKCONTENTITEM_P_H +#define QQUICKCONTENTITEM_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuick/qquickitem.h> +#include <QtQuickTemplates2/private/qtquicktemplates2global_p.h> + +QT_BEGIN_NAMESPACE + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickContentItem : public QQuickItem +{ + Q_OBJECT + +public: + explicit QQuickContentItem(QQuickItem *parent = nullptr); + explicit QQuickContentItem(const QObject *scope, QQuickItem *parent); + +private: + Q_DISABLE_COPY(QQuickContentItem) +}; + +QT_END_NAMESPACE + +#endif // QQUICKCONTENTITEM_P_H diff --git a/src/quicktemplates2/qquickcontrol.cpp b/src/quicktemplates2/qquickcontrol.cpp index 9f796a70..afb7c08a 100644 --- a/src/quicktemplates2/qquickcontrol.cpp +++ b/src/quicktemplates2/qquickcontrol.cpp @@ -50,9 +50,6 @@ #include "qquickapplicationwindow_p.h" #include "qquickdeferredexecute_p_p.h" -#include <QtGui/private/qguiapplication_p.h> -#include <QtGui/qpa/qplatformtheme.h> - #if QT_CONFIG(accessibility) #include <QtQuick/private/qquickaccessibleattached_p.h> #endif @@ -79,15 +76,48 @@ QT_BEGIN_NAMESPACE The \l {Item::}{implicitWidth} and \l {Item::}{implicitHeight} of a control are typically based on the implicit sizes of the background and the content - item plus any \l {Control::}{padding}. These properties determine how large + item plus any insets and paddings. These properties determine how large the control will be when no explicit \l {Item::}{width} or \l {Item::}{height} is specified. + The geometry of the \l {Control::}{contentItem} is determined by the padding. + The following example reserves 10px padding between the boundaries of the + control and its content: + + \code + Control { + padding: 10 + + contentItem: Text { + text: "Content" + } + } + \endcode + The \l {Control::}{background} item fills the entire width and height of the - control, unless an explicit size has been given for it. + control, unless insets or an explicit size have been given for it. Background + insets are useful for extending the touchable/interactive area of a control + without affecting its visual size. This is often used on touch devices to + ensure that a control is not too small to be interacted with by the user. + Insets affect the size of the control, and hence will affect how much space + they take up in a layout, for example. + + Negative insets can be used to make the background larger than the control. + The following example uses negative insets to place a shadow outside the + control's boundaries: - The geometry of the \l {Control::}{contentItem} is determined by the - padding. + \code + Control { + topInset: -2 + leftInset: -2 + rightInset: -6 + bottomInset: -6 + + background: BorderImage { + source: ":/images/shadowed-background.png" + } + } + \endcode \section1 Event Handling @@ -100,32 +130,52 @@ QT_BEGIN_NAMESPACE \sa ApplicationWindow, Container */ +const QQuickItemPrivate::ChangeTypes QQuickControlPrivate::ImplicitSizeChanges = QQuickItemPrivate::ImplicitWidth | QQuickItemPrivate::ImplicitHeight | QQuickItemPrivate::Destroyed; + static bool isKeyFocusReason(Qt::FocusReason reason) { return reason == Qt::TabFocusReason || reason == Qt::BacktabFocusReason || reason == Qt::ShortcutFocusReason; } QQuickControlPrivate::ExtraData::ExtraData() -{ -} - -QQuickControlPrivate::QQuickControlPrivate() : hasTopPadding(false), hasLeftPadding(false), hasRightPadding(false), hasBottomPadding(false), + hasBaselineOffset(false), + hasTopInset(false), + hasLeftInset(false), + hasRightInset(false), + hasBottomInset(false), + hasBackgroundWidth(false), + hasBackgroundHeight(false), + topPadding(0), + leftPadding(0), + rightPadding(0), + bottomPadding(0), + topInset(0), + leftInset(0), + rightInset(0), + bottomInset(0) +{ +} + +QQuickControlPrivate::QQuickControlPrivate() + : hasHorizontalPadding(false), + hasVerticalPadding(false), hasLocale(false), wheelEnabled(false), #if QT_CONFIG(quicktemplates2_hover) hovered(false), explicitHoverEnabled(false), #endif + resizingBackground(false), touchId(-1), padding(0), - topPadding(0), - leftPadding(0), - rightPadding(0), - bottomPadding(0), + horizontalPadding(0), + verticalPadding(0), + implicitContentWidth(0), + implicitContentHeight(0), spacing(0), focusPolicy(Qt::NoFocus), focusReason(Qt::OtherFocusReason), @@ -144,6 +194,12 @@ QQuickControlPrivate::~QQuickControlPrivate() #endif } +void QQuickControlPrivate::init() +{ + Q_Q(QQuickControl); + QObject::connect(q, &QQuickItem::baselineOffsetChanged, q, &QQuickControl::baselineOffsetChanged); +} + #if QT_CONFIG(quicktemplates2_multitouch) bool QQuickControlPrivate::acceptTouch(const QTouchEvent::TouchPoint &point) { @@ -207,75 +263,163 @@ void QQuickControlPrivate::mirrorChange() void QQuickControlPrivate::setTopPadding(qreal value, bool reset) { Q_Q(QQuickControl); - qreal oldPadding = q->topPadding(); - topPadding = value; - hasTopPadding = !reset; - if ((!reset && !qFuzzyCompare(oldPadding, value)) || (reset && !qFuzzyCompare(oldPadding, padding))) { + const QMarginsF oldPadding = getPadding(); + extra.value().topPadding = value; + extra.value().hasTopPadding = !reset; + if ((!reset && !qFuzzyCompare(oldPadding.top(), value)) || (reset && !qFuzzyCompare(oldPadding.top(), getVerticalPadding()))) { emit q->topPaddingChanged(); emit q->availableHeightChanged(); - q->paddingChange(QMarginsF(leftPadding, topPadding, rightPadding, bottomPadding), - QMarginsF(leftPadding, oldPadding, rightPadding, bottomPadding)); + q->paddingChange(getPadding(), oldPadding); } } void QQuickControlPrivate::setLeftPadding(qreal value, bool reset) { Q_Q(QQuickControl); - qreal oldPadding = q->leftPadding(); - leftPadding = value; - hasLeftPadding = !reset; - if ((!reset && !qFuzzyCompare(oldPadding, value)) || (reset && !qFuzzyCompare(oldPadding, padding))) { + const QMarginsF oldPadding = getPadding(); + extra.value().leftPadding = value; + extra.value().hasLeftPadding = !reset; + if ((!reset && !qFuzzyCompare(oldPadding.left(), value)) || (reset && !qFuzzyCompare(oldPadding.left(), getHorizontalPadding()))) { emit q->leftPaddingChanged(); emit q->availableWidthChanged(); - q->paddingChange(QMarginsF(leftPadding, topPadding, rightPadding, bottomPadding), - QMarginsF(oldPadding, topPadding, rightPadding, bottomPadding)); + q->paddingChange(getPadding(), oldPadding); } } void QQuickControlPrivate::setRightPadding(qreal value, bool reset) { Q_Q(QQuickControl); - qreal oldPadding = q->rightPadding(); - rightPadding = value; - hasRightPadding = !reset; - if ((!reset && !qFuzzyCompare(oldPadding, value)) || (reset && !qFuzzyCompare(oldPadding, padding))) { + const QMarginsF oldPadding = getPadding(); + extra.value().rightPadding = value; + extra.value().hasRightPadding = !reset; + if ((!reset && !qFuzzyCompare(oldPadding.right(), value)) || (reset && !qFuzzyCompare(oldPadding.right(), getHorizontalPadding()))) { emit q->rightPaddingChanged(); emit q->availableWidthChanged(); - q->paddingChange(QMarginsF(leftPadding, topPadding, rightPadding, bottomPadding), - QMarginsF(leftPadding, topPadding, oldPadding, bottomPadding)); + q->paddingChange(getPadding(), oldPadding); } } void QQuickControlPrivate::setBottomPadding(qreal value, bool reset) { Q_Q(QQuickControl); - qreal oldPadding = q->bottomPadding(); - bottomPadding = value; - hasBottomPadding = !reset; - if ((!reset && !qFuzzyCompare(oldPadding, value)) || (reset && !qFuzzyCompare(oldPadding, padding))) { + const QMarginsF oldPadding = getPadding(); + extra.value().bottomPadding = value; + extra.value().hasBottomPadding = !reset; + if ((!reset && !qFuzzyCompare(oldPadding.bottom(), value)) || (reset && !qFuzzyCompare(oldPadding.bottom(), getVerticalPadding()))) { emit q->bottomPaddingChanged(); emit q->availableHeightChanged(); - q->paddingChange(QMarginsF(leftPadding, topPadding, rightPadding, bottomPadding), - QMarginsF(leftPadding, topPadding, rightPadding, oldPadding)); + q->paddingChange(getPadding(), oldPadding); } } -void QQuickControlPrivate::resizeBackground() +void QQuickControlPrivate::setHorizontalPadding(qreal value, bool reset) { Q_Q(QQuickControl); - if (background) { - QQuickItemPrivate *p = QQuickItemPrivate::get(background); - if (!p->widthValid && qFuzzyIsNull(background->x())) { - background->setWidth(q->width()); - p->widthValid = false; - } - if (!p->heightValid && qFuzzyIsNull(background->y())) { - background->setHeight(q->height()); - p->heightValid = false; - } + const QMarginsF oldPadding = getPadding(); + const qreal oldHorizontalPadding = getHorizontalPadding(); + horizontalPadding = value; + hasHorizontalPadding = !reset; + if ((!reset && !qFuzzyCompare(oldHorizontalPadding, value)) || (reset && !qFuzzyCompare(oldHorizontalPadding, padding))) { + const QMarginsF newPadding = getPadding(); + if (!qFuzzyCompare(newPadding.left(), oldPadding.left())) + emit q->leftPaddingChanged(); + if (!qFuzzyCompare(newPadding.right(), oldPadding.right())) + emit q->rightPaddingChanged(); + emit q->horizontalPaddingChanged(); + emit q->availableWidthChanged(); + q->paddingChange(newPadding, oldPadding); + } +} + +void QQuickControlPrivate::setVerticalPadding(qreal value, bool reset) +{ + Q_Q(QQuickControl); + const QMarginsF oldPadding = getPadding(); + const qreal oldVerticalPadding = getVerticalPadding(); + verticalPadding = value; + hasVerticalPadding = !reset; + if ((!reset && !qFuzzyCompare(oldVerticalPadding, value)) || (reset && !qFuzzyCompare(oldVerticalPadding, padding))) { + const QMarginsF newPadding = getPadding(); + if (!qFuzzyCompare(newPadding.top(), oldPadding.top())) + emit q->topPaddingChanged(); + if (!qFuzzyCompare(newPadding.bottom(), oldPadding.bottom())) + emit q->bottomPaddingChanged(); + emit q->verticalPaddingChanged(); + emit q->availableHeightChanged(); + q->paddingChange(newPadding, oldPadding); + } +} + +void QQuickControlPrivate::setTopInset(qreal value, bool reset) +{ + Q_Q(QQuickControl); + const QMarginsF oldInset = getInset(); + extra.value().topInset = value; + extra.value().hasTopInset = !reset; + if (!qFuzzyCompare(oldInset.top(), value)) { + emit q->topInsetChanged(); + q->insetChange(getInset(), oldInset); + } +} + +void QQuickControlPrivate::setLeftInset(qreal value, bool reset) +{ + Q_Q(QQuickControl); + const QMarginsF oldInset = getInset(); + extra.value().leftInset = value; + extra.value().hasLeftInset = !reset; + if (!qFuzzyCompare(oldInset.left(), value)) { + emit q->leftInsetChanged(); + q->insetChange(getInset(), oldInset); } } +void QQuickControlPrivate::setRightInset(qreal value, bool reset) +{ + Q_Q(QQuickControl); + const QMarginsF oldInset = getInset(); + extra.value().rightInset = value; + extra.value().hasRightInset = !reset; + if (!qFuzzyCompare(oldInset.right(), value)) { + emit q->rightInsetChanged(); + q->insetChange(getInset(), oldInset); + } +} + +void QQuickControlPrivate::setBottomInset(qreal value, bool reset) +{ + Q_Q(QQuickControl); + const QMarginsF oldInset = getInset(); + extra.value().bottomInset = value; + extra.value().hasBottomInset = !reset; + if (!qFuzzyCompare(oldInset.bottom(), value)) { + emit q->bottomInsetChanged(); + q->insetChange(getInset(), oldInset); + } +} + +void QQuickControlPrivate::resizeBackground() +{ + if (!background) + return; + + resizingBackground = true; + + QQuickItemPrivate *p = QQuickItemPrivate::get(background); + if (((!p->widthValid || !extra.isAllocated() || !extra->hasBackgroundWidth) && qFuzzyIsNull(background->x())) + || (extra.isAllocated() && (extra->hasLeftInset || extra->hasRightInset))) { + background->setX(getLeftInset()); + background->setWidth(width - getLeftInset() - getRightInset()); + } + if (((!p->heightValid || !extra.isAllocated() || !extra->hasBackgroundHeight) && qFuzzyIsNull(background->y())) + || (extra.isAllocated() && (extra->hasTopInset || extra->hasBottomInset))) { + background->setY(getTopInset()); + background->setHeight(height - getTopInset() - getBottomInset()); + } + + resizingBackground = false; +} + void QQuickControlPrivate::resizeContent() { Q_Q(QQuickControl); @@ -301,21 +445,73 @@ void QQuickControlPrivate::setContentItem_helper(QQuickItem *item, bool notify) if (!contentItem.isExecuting()) cancelContentItem(); - q->contentItemChange(item, contentItem); - delete contentItem; + QQuickItem *oldContentItem = contentItem; + if (oldContentItem) { + disconnect(oldContentItem, &QQuickItem::baselineOffsetChanged, this, &QQuickControlPrivate::updateBaselineOffset); + removeImplicitSizeListener(oldContentItem); + } + contentItem = item; + q->contentItemChange(item, oldContentItem); + delete oldContentItem; if (item) { + connect(contentItem, &QQuickItem::baselineOffsetChanged, this, &QQuickControlPrivate::updateBaselineOffset); if (!item->parentItem()) item->setParentItem(q); if (componentComplete) resizeContent(); + addImplicitSizeListener(contentItem); } + updateImplicitContentSize(); + updateBaselineOffset(); + if (notify && !contentItem.isExecuting()) emit q->contentItemChanged(); } +qreal QQuickControlPrivate::getContentWidth() const +{ + return contentItem ? contentItem->implicitWidth() : 0; +} + +qreal QQuickControlPrivate::getContentHeight() const +{ + return contentItem ? contentItem->implicitHeight() : 0; +} + +void QQuickControlPrivate::updateImplicitContentWidth() +{ + Q_Q(QQuickControl); + const qreal oldWidth = implicitContentWidth; + implicitContentWidth = getContentWidth(); + if (!qFuzzyCompare(implicitContentWidth, oldWidth)) + emit q->implicitContentWidthChanged(); +} + +void QQuickControlPrivate::updateImplicitContentHeight() +{ + Q_Q(QQuickControl); + const qreal oldHeight = implicitContentHeight; + implicitContentHeight = getContentHeight(); + if (!qFuzzyCompare(implicitContentHeight, oldHeight)) + emit q->implicitContentHeightChanged(); +} + +void QQuickControlPrivate::updateImplicitContentSize() +{ + Q_Q(QQuickControl); + const qreal oldWidth = implicitContentWidth; + const qreal oldHeight = implicitContentHeight; + implicitContentWidth = getContentWidth(); + implicitContentHeight = getContentHeight(); + if (!qFuzzyCompare(implicitContentWidth, oldWidth)) + emit q->implicitContentWidthChanged(); + if (!qFuzzyCompare(implicitContentHeight, oldHeight)) + emit q->implicitContentHeightChanged(); +} + #if QT_CONFIG(accessibility) void QQuickControlPrivate::accessibilityActiveChanged(bool active) { @@ -362,21 +558,7 @@ QFont QQuickControlPrivate::parentFont(const QQuickItem *item) if (QQuickApplicationWindow *window = qobject_cast<QQuickApplicationWindow *>(item->window())) return window->font(); - return themeFont(QPlatformTheme::SystemFont); -} - -QFont QQuickControlPrivate::themeFont(QPlatformTheme::Font type) -{ - if (QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) { - if (const QFont *font = theme->font(type)) { - QFont f = *font; - if (type == QPlatformTheme::SystemFont) - f.resolve(0); - return f; - } - } - - return QFont(); + return QQuickTheme::themeFont(QQuickTheme::System); } /*! @@ -467,21 +649,7 @@ QPalette QQuickControlPrivate::parentPalette(const QQuickItem *item) if (QQuickApplicationWindow *window = qobject_cast<QQuickApplicationWindow *>(item->window())) return window->palette(); - return themePalette(QPlatformTheme::SystemPalette); -} - -QPalette QQuickControlPrivate::themePalette(QPlatformTheme::Palette type) -{ - if (QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) { - if (const QPalette *palette = theme->palette(type)) { - QPalette p = *palette; - if (type == QPlatformTheme::SystemPalette) - p.resolve(0); - return p; - } - } - - return QPalette(); + return QQuickTheme::themePalette(QQuickTheme::System); } /*! @@ -697,14 +865,94 @@ void QQuickControlPrivate::executeBackground(bool complete) quickCompleteDeferred(q, backgroundName(), background); } +void QQuickControlPrivate::updateBaselineOffset() +{ + Q_Q(QQuickControl); + if (extra.isAllocated() && extra.value().hasBaselineOffset) + return; + + if (!contentItem) + q->QQuickItem::setBaselineOffset(0); + else + q->QQuickItem::setBaselineOffset(getTopPadding() + contentItem->baselineOffset()); +} + +void QQuickControlPrivate::addImplicitSizeListener(QQuickItem *item, ChangeTypes changes) +{ + if (!item) + return; + QQuickItemPrivate::get(item)->addItemChangeListener(this, changes); +} + +void QQuickControlPrivate::removeImplicitSizeListener(QQuickItem *item, ChangeTypes changes) +{ + if (!item) + return; + QQuickItemPrivate::get(item)->removeItemChangeListener(this, changes); +} + +void QQuickControlPrivate::itemImplicitWidthChanged(QQuickItem *item) +{ + Q_Q(QQuickControl); + if (item == background) + emit q->implicitBackgroundWidthChanged(); + else if (item == contentItem) + updateImplicitContentWidth(); +} + +void QQuickControlPrivate::itemImplicitHeightChanged(QQuickItem *item) +{ + Q_Q(QQuickControl); + if (item == background) + emit q->implicitBackgroundHeightChanged(); + else if (item == contentItem) + updateImplicitContentHeight(); +} + +void QQuickControlPrivate::itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &diff) +{ + Q_UNUSED(diff); + if (resizingBackground || item != background || !change.sizeChange()) + return; + + QQuickItemPrivate *p = QQuickItemPrivate::get(item); + extra.value().hasBackgroundWidth = p->widthValid; + extra.value().hasBackgroundHeight = p->heightValid; + resizeBackground(); +} + +void QQuickControlPrivate::itemDestroyed(QQuickItem *item) +{ + Q_Q(QQuickControl); + if (item == background) { + background = nullptr; + emit q->implicitBackgroundWidthChanged(); + emit q->implicitBackgroundHeightChanged(); + } else if (item == contentItem) { + contentItem = nullptr; + updateImplicitContentSize(); + } +} + QQuickControl::QQuickControl(QQuickItem *parent) : QQuickItem(*(new QQuickControlPrivate), parent) { + Q_D(QQuickControl); + d->init(); } QQuickControl::QQuickControl(QQuickControlPrivate &dd, QQuickItem *parent) : QQuickItem(dd, parent) { + Q_D(QQuickControl); + d->init(); +} + +QQuickControl::~QQuickControl() +{ + Q_D(QQuickControl); + d->removeImplicitSizeListener(d->background, QQuickControlPrivate::ImplicitSizeChanges | QQuickItemPrivate::Geometry); + d->removeImplicitSizeListener(d->contentItem); } void QQuickControl::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &value) @@ -866,10 +1114,18 @@ void QQuickControl::setPadding(qreal padding) Q_D(QQuickControl); if (qFuzzyCompare(d->padding, padding)) return; - QMarginsF oldPadding(leftPadding(), topPadding(), rightPadding(), bottomPadding()); + + const QMarginsF oldPadding = d->getPadding(); + const qreal oldVerticalPadding = d->getVerticalPadding(); + const qreal oldHorizontalPadding = d->getHorizontalPadding(); + d->padding = padding; emit paddingChanged(); - QMarginsF newPadding(leftPadding(), topPadding(), rightPadding(), bottomPadding()); + + const QMarginsF newPadding = d->getPadding(); + const qreal newVerticalPadding = d->getVerticalPadding(); + const qreal newHorizontalPadding = d->getHorizontalPadding(); + if (!qFuzzyCompare(newPadding.top(), oldPadding.top())) emit topPaddingChanged(); if (!qFuzzyCompare(newPadding.left(), oldPadding.left())) @@ -878,10 +1134,15 @@ void QQuickControl::setPadding(qreal padding) emit rightPaddingChanged(); if (!qFuzzyCompare(newPadding.bottom(), oldPadding.bottom())) emit bottomPaddingChanged(); + if (!qFuzzyCompare(newVerticalPadding, oldVerticalPadding)) + emit verticalPaddingChanged(); + if (!qFuzzyCompare(newHorizontalPadding, oldHorizontalPadding)) + emit horizontalPaddingChanged(); if (!qFuzzyCompare(newPadding.top(), oldPadding.top()) || !qFuzzyCompare(newPadding.bottom(), oldPadding.bottom())) emit availableHeightChanged(); if (!qFuzzyCompare(newPadding.left(), oldPadding.left()) || !qFuzzyCompare(newPadding.right(), oldPadding.right())) emit availableWidthChanged(); + paddingChange(newPadding, oldPadding); } @@ -893,16 +1154,15 @@ void QQuickControl::resetPadding() /*! \qmlproperty real QtQuick.Controls::Control::topPadding - This property holds the top padding. + This property holds the top padding. Unless explicitly set, the value + is equal to \c verticalPadding. - \sa {Control Layout}, padding, bottomPadding, availableHeight + \sa {Control Layout}, padding, bottomPadding, verticalPadding, availableHeight */ qreal QQuickControl::topPadding() const { Q_D(const QQuickControl); - if (d->hasTopPadding) - return d->topPadding; - return d->padding; + return d->getTopPadding(); } void QQuickControl::setTopPadding(qreal padding) @@ -920,16 +1180,15 @@ void QQuickControl::resetTopPadding() /*! \qmlproperty real QtQuick.Controls::Control::leftPadding - This property holds the left padding. + This property holds the left padding. Unless explicitly set, the value + is equal to \c horizontalPadding. - \sa {Control Layout}, padding, rightPadding, availableWidth + \sa {Control Layout}, padding, rightPadding, horizontalPadding, availableWidth */ qreal QQuickControl::leftPadding() const { Q_D(const QQuickControl); - if (d->hasLeftPadding) - return d->leftPadding; - return d->padding; + return d->getLeftPadding(); } void QQuickControl::setLeftPadding(qreal padding) @@ -947,16 +1206,15 @@ void QQuickControl::resetLeftPadding() /*! \qmlproperty real QtQuick.Controls::Control::rightPadding - This property holds the right padding. + This property holds the right padding. Unless explicitly set, the value + is equal to \c horizontalPadding. - \sa {Control Layout}, padding, leftPadding, availableWidth + \sa {Control Layout}, padding, leftPadding, horizontalPadding, availableWidth */ qreal QQuickControl::rightPadding() const { Q_D(const QQuickControl); - if (d->hasRightPadding) - return d->rightPadding; - return d->padding; + return d->getRightPadding(); } void QQuickControl::setRightPadding(qreal padding) @@ -974,16 +1232,15 @@ void QQuickControl::resetRightPadding() /*! \qmlproperty real QtQuick.Controls::Control::bottomPadding - This property holds the bottom padding. + This property holds the bottom padding. Unless explicitly set, the value + is equal to \c verticalPadding. - \sa {Control Layout}, padding, topPadding, availableHeight + \sa {Control Layout}, padding, topPadding, verticalPadding, availableHeight */ qreal QQuickControl::bottomPadding() const { Q_D(const QQuickControl); - if (d->hasBottomPadding) - return d->bottomPadding; - return d->padding; + return d->getBottomPadding(); } void QQuickControl::setBottomPadding(qreal padding) @@ -1316,15 +1573,36 @@ void QQuickControl::setBackground(QQuickItem *background) if (!d->background.isExecuting()) d->cancelBackground(); + const qreal oldImplicitBackgroundWidth = implicitBackgroundWidth(); + const qreal oldImplicitBackgroundHeight = implicitBackgroundHeight(); + + if (d->extra.isAllocated()) { + d->extra.value().hasBackgroundWidth = false; + d->extra.value().hasBackgroundHeight = false; + } + + d->removeImplicitSizeListener(d->background, QQuickControlPrivate::ImplicitSizeChanges | QQuickItemPrivate::Geometry); delete d->background; d->background = background; + if (background) { background->setParentItem(this); if (qFuzzyIsNull(background->z())) background->setZ(-1); + QQuickItemPrivate *p = QQuickItemPrivate::get(background); + if (p->widthValid || p->heightValid) { + d->extra.value().hasBackgroundWidth = p->widthValid; + d->extra.value().hasBackgroundHeight = p->heightValid; + } if (isComponentComplete()) d->resizeBackground(); + d->addImplicitSizeListener(background, QQuickControlPrivate::ImplicitSizeChanges | QQuickItemPrivate::Geometry); } + + if (!qFuzzyCompare(oldImplicitBackgroundWidth, implicitBackgroundWidth())) + emit implicitBackgroundWidthChanged(); + if (!qFuzzyCompare(oldImplicitBackgroundHeight, implicitBackgroundHeight())) + emit implicitBackgroundHeightChanged(); if (!d->background.isExecuting()) emit backgroundChanged(); } @@ -1371,6 +1649,30 @@ void QQuickControl::setContentItem(QQuickItem *item) d->setContentItem_helper(item, true); } +qreal QQuickControl::baselineOffset() const +{ + Q_D(const QQuickControl); + return d->baselineOffset; +} + +void QQuickControl::setBaselineOffset(qreal offset) +{ + Q_D(QQuickControl); + d->extra.value().hasBaselineOffset = true; + QQuickItem::setBaselineOffset(offset); +} + +void QQuickControl::resetBaselineOffset() +{ + Q_D(QQuickControl); + if (!d->extra.isAllocated() || !d->extra.value().hasBaselineOffset) + return; + + if (d->extra.isAllocated()) + d->extra.value().hasBaselineOffset = false; + d->updateBaselineOffset(); +} + /*! \since QtQuick.Controls 2.3 (Qt 5.10) \qmlproperty palette QtQuick.Controls::Control::palette @@ -1440,6 +1742,278 @@ void QQuickControl::resetPalette() setPalette(QPalette()); } +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::Control::horizontalPadding + + This property holds the horizontal padding. Unless explicitly set, the value + is equal to \c padding. + + \sa {Control Layout}, padding, leftPadding, rightPadding, verticalPadding +*/ +qreal QQuickControl::horizontalPadding() const +{ + Q_D(const QQuickControl); + return d->getHorizontalPadding(); +} + +void QQuickControl::setHorizontalPadding(qreal padding) +{ + Q_D(QQuickControl); + d->setHorizontalPadding(padding); +} + +void QQuickControl::resetHorizontalPadding() +{ + Q_D(QQuickControl); + d->setHorizontalPadding(0, true); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::Control::verticalPadding + + This property holds the vertical padding. Unless explicitly set, the value + is equal to \c padding. + + \sa {Control Layout}, padding, topPadding, bottomPadding, horizontalPadding +*/ +qreal QQuickControl::verticalPadding() const +{ + Q_D(const QQuickControl); + return d->getVerticalPadding(); +} + +void QQuickControl::setVerticalPadding(qreal padding) +{ + Q_D(QQuickControl); + d->setVerticalPadding(padding); +} + +void QQuickControl::resetVerticalPadding() +{ + Q_D(QQuickControl); + d->setVerticalPadding(0, true); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::Control::implicitContentWidth + \readonly + + This property holds the implicit content width. + + For basic controls, the value is equal to \c {contentItem ? contentItem.implicitWidth : 0}. + For types that inherit Container or Pane, the value is calculated based on the content children. + + This is typically used, together with \l implicitBackgroundWidth, to calculate + the \l {Item::}{implicitWidth}: + + \code + Control { + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + } + \endcode + + \sa implicitContentHeight, implicitBackgroundWidth +*/ +qreal QQuickControl::implicitContentWidth() const +{ + Q_D(const QQuickControl); + return d->implicitContentWidth; +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::Control::implicitContentHeight + \readonly + + This property holds the implicit content height. + + For basic controls, the value is equal to \c {contentItem ? contentItem.implicitHeight : 0}. + For types that inherit Container or Pane, the value is calculated based on the content children. + + This is typically used, together with \l implicitBackgroundHeight, to calculate + the \l {Item::}{implicitHeight}: + + \code + Control { + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + } + \endcode + + \sa implicitContentWidth, implicitBackgroundHeight +*/ +qreal QQuickControl::implicitContentHeight() const +{ + Q_D(const QQuickControl); + return d->implicitContentHeight; +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::Control::implicitBackgroundWidth + \readonly + + This property holds the implicit background width. + + The value is equal to \c {background ? background.implicitWidth : 0}. + + This is typically used, together with \l implicitContentWidth, to calculate + the \l {Item::}{implicitWidth}: + + \code + Control { + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + } + \endcode + + \sa implicitBackgroundHeight, implicitContentWidth +*/ +qreal QQuickControl::implicitBackgroundWidth() const +{ + Q_D(const QQuickControl); + if (!d->background) + return 0; + return d->background->implicitWidth(); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::Control::implicitBackgroundHeight + \readonly + + This property holds the implicit background height. + + The value is equal to \c {background ? background.implicitHeight : 0}. + + This is typically used, together with \l implicitContentHeight, to calculate + the \l {Item::}{implicitHeight}: + + \code + Control { + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + } + \endcode + + \sa implicitBackgroundWidth, implicitContentHeight +*/ +qreal QQuickControl::implicitBackgroundHeight() const +{ + Q_D(const QQuickControl); + if (!d->background) + return 0; + return d->background->implicitHeight(); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::Control::topInset + + This property holds the top inset for the background. + + \sa {Control Layout}, bottomInset +*/ +qreal QQuickControl::topInset() const +{ + Q_D(const QQuickControl); + return d->getTopInset(); +} + +void QQuickControl::setTopInset(qreal inset) +{ + Q_D(QQuickControl); + d->setTopInset(inset); +} + +void QQuickControl::resetTopInset() +{ + Q_D(QQuickControl); + d->setTopInset(0, true); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::Control::leftInset + + This property holds the left inset for the background. + + \sa {Control Layout}, rightInset +*/ +qreal QQuickControl::leftInset() const +{ + Q_D(const QQuickControl); + return d->getLeftInset(); +} + +void QQuickControl::setLeftInset(qreal inset) +{ + Q_D(QQuickControl); + d->setLeftInset(inset); +} + +void QQuickControl::resetLeftInset() +{ + Q_D(QQuickControl); + d->setLeftInset(0, true); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::Control::rightInset + + This property holds the right inset for the background. + + \sa {Control Layout}, leftInset +*/ +qreal QQuickControl::rightInset() const +{ + Q_D(const QQuickControl); + return d->getRightInset(); +} + +void QQuickControl::setRightInset(qreal inset) +{ + Q_D(QQuickControl); + d->setRightInset(inset); +} + +void QQuickControl::resetRightInset() +{ + Q_D(QQuickControl); + d->setRightInset(0, true); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::Control::bottomInset + + This property holds the bottom inset for the background. + + \sa {Control Layout}, topInset +*/ +qreal QQuickControl::bottomInset() const +{ + Q_D(const QQuickControl); + return d->getBottomInset(); +} + +void QQuickControl::setBottomInset(qreal inset) +{ + Q_D(QQuickControl); + d->setBottomInset(inset); +} + +void QQuickControl::resetBottomInset() +{ + Q_D(QQuickControl); + d->setBottomInset(0, true); +} + void QQuickControl::classBegin() { Q_D(QQuickControl); @@ -1456,6 +2030,7 @@ void QQuickControl::componentComplete() QQuickItem::componentComplete(); d->resizeBackground(); d->resizeContent(); + d->updateBaselineOffset(); if (!d->hasLocale) d->locale = QQuickControlPrivate::calcLocale(d->parentItem); #if QT_CONFIG(quicktemplates2_hover) @@ -1470,12 +2045,12 @@ void QQuickControl::componentComplete() QFont QQuickControl::defaultFont() const { - return QQuickControlPrivate::themeFont(QPlatformTheme::SystemFont); + return QQuickTheme::themeFont(QQuickTheme::System); } QPalette QQuickControl::defaultPalette() const { - return QQuickControlPrivate::themePalette(QPlatformTheme::SystemPalette); + return QQuickTheme::themePalette(QQuickTheme::System); } void QQuickControl::focusInEvent(QFocusEvent *event) @@ -1637,6 +2212,7 @@ void QQuickControl::paddingChange(const QMarginsF &newPadding, const QMarginsF & Q_UNUSED(newPadding); Q_UNUSED(oldPadding); d->resizeContent(); + d->updateBaselineOffset(); } void QQuickControl::contentItemChange(QQuickItem *newItem, QQuickItem *oldItem) @@ -1657,6 +2233,14 @@ void QQuickControl::paletteChange(const QPalette &newPalette, const QPalette &ol Q_UNUSED(oldPalette); } +void QQuickControl::insetChange(const QMarginsF &newInset, const QMarginsF &oldInset) +{ + Q_D(QQuickControl); + Q_UNUSED(newInset); + Q_UNUSED(oldInset); + d->resizeBackground(); +} + #if QT_CONFIG(accessibility) QAccessible::Role QQuickControl::accessibleRole() const { diff --git a/src/quicktemplates2/qquickcontrol_p.h b/src/quicktemplates2/qquickcontrol_p.h index 6b2d48d6..a38e34f9 100644 --- a/src/quicktemplates2/qquickcontrol_p.h +++ b/src/quicktemplates2/qquickcontrol_p.h @@ -79,12 +79,25 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickControl : public QQuickItem Q_PROPERTY(bool wheelEnabled READ isWheelEnabled WRITE setWheelEnabled NOTIFY wheelEnabledChanged FINAL) Q_PROPERTY(QQuickItem *background READ background WRITE setBackground NOTIFY backgroundChanged FINAL) Q_PROPERTY(QQuickItem *contentItem READ contentItem WRITE setContentItem NOTIFY contentItemChanged FINAL) + Q_PROPERTY(qreal baselineOffset READ baselineOffset WRITE setBaselineOffset RESET resetBaselineOffset NOTIFY baselineOffsetChanged FINAL) // 2.3 (Qt 5.10) Q_PROPERTY(QPalette palette READ palette WRITE setPalette RESET resetPalette NOTIFY paletteChanged FINAL REVISION 3) + // 2.5 (Qt 5.12) + Q_PROPERTY(qreal horizontalPadding READ horizontalPadding WRITE setHorizontalPadding RESET resetHorizontalPadding NOTIFY horizontalPaddingChanged FINAL REVISION 5) + Q_PROPERTY(qreal verticalPadding READ verticalPadding WRITE setVerticalPadding RESET resetVerticalPadding NOTIFY verticalPaddingChanged FINAL REVISION 5) + Q_PROPERTY(qreal implicitContentWidth READ implicitContentWidth NOTIFY implicitContentWidthChanged FINAL REVISION 5) + Q_PROPERTY(qreal implicitContentHeight READ implicitContentHeight NOTIFY implicitContentHeightChanged FINAL REVISION 5) + Q_PROPERTY(qreal implicitBackgroundWidth READ implicitBackgroundWidth NOTIFY implicitBackgroundWidthChanged FINAL REVISION 5) + Q_PROPERTY(qreal implicitBackgroundHeight READ implicitBackgroundHeight NOTIFY implicitBackgroundHeightChanged FINAL REVISION 5) + Q_PROPERTY(qreal topInset READ topInset WRITE setTopInset RESET resetTopInset NOTIFY topInsetChanged FINAL REVISION 5) + Q_PROPERTY(qreal leftInset READ leftInset WRITE setLeftInset RESET resetLeftInset NOTIFY leftInsetChanged FINAL REVISION 5) + Q_PROPERTY(qreal rightInset READ rightInset WRITE setRightInset RESET resetRightInset NOTIFY rightInsetChanged FINAL REVISION 5) + Q_PROPERTY(qreal bottomInset READ bottomInset WRITE setBottomInset RESET resetBottomInset NOTIFY bottomInsetChanged FINAL REVISION 5) Q_CLASSINFO("DeferredPropertyNames", "background,contentItem") public: explicit QQuickControl(QQuickItem *parent = nullptr); + ~QQuickControl(); QFont font() const; void setFont(const QFont &font); @@ -147,11 +160,46 @@ public: QQuickItem *contentItem() const; void setContentItem(QQuickItem *item); + qreal baselineOffset() const; + void setBaselineOffset(qreal offset); + void resetBaselineOffset(); + // 2.3 (Qt 5.10) QPalette palette() const; void setPalette(const QPalette &palette); void resetPalette(); + // 2.5 (Qt 5.12) + qreal horizontalPadding() const; + void setHorizontalPadding(qreal padding); + void resetHorizontalPadding(); + + qreal verticalPadding() const; + void setVerticalPadding(qreal padding); + void resetVerticalPadding(); + + qreal implicitContentWidth() const; + qreal implicitContentHeight() const; + + qreal implicitBackgroundWidth() const; + qreal implicitBackgroundHeight() const; + + qreal topInset() const; + void setTopInset(qreal inset); + void resetTopInset(); + + qreal leftInset() const; + void setLeftInset(qreal inset); + void resetLeftInset(); + + qreal rightInset() const; + void setRightInset(qreal inset); + void resetRightInset(); + + qreal bottomInset() const; + void setBottomInset(qreal inset); + void resetBottomInset(); + Q_SIGNALS: void fontChanged(); void availableWidthChanged(); @@ -172,8 +220,20 @@ Q_SIGNALS: void wheelEnabledChanged(); void backgroundChanged(); void contentItemChanged(); + void baselineOffsetChanged(); // 2.3 (Qt 5.10) Q_REVISION(3) void paletteChanged(); + // 2.5 (Qt 5.12) + Q_REVISION(5) void horizontalPaddingChanged(); + Q_REVISION(5) void verticalPaddingChanged(); + Q_REVISION(5) void implicitContentWidthChanged(); + Q_REVISION(5) void implicitContentHeightChanged(); + Q_REVISION(5) void implicitBackgroundWidthChanged(); + Q_REVISION(5) void implicitBackgroundHeightChanged(); + Q_REVISION(5) void topInsetChanged(); + Q_REVISION(5) void leftInsetChanged(); + Q_REVISION(5) void rightInsetChanged(); + Q_REVISION(5) void bottomInsetChanged(); protected: virtual QFont defaultFont() const; @@ -217,6 +277,7 @@ protected: virtual void contentItemChange(QQuickItem *newItem, QQuickItem *oldItem); virtual void localeChange(const QLocale &newLocale, const QLocale &oldLocale); virtual void paletteChange(const QPalette &newPalette, const QPalette &oldPalette); + virtual void insetChange(const QMarginsF &newInset, const QMarginsF &oldInset); #if QT_CONFIG(accessibility) virtual QAccessible::Role accessibleRole() const; diff --git a/src/quicktemplates2/qquickcontrol_p_p.h b/src/quicktemplates2/qquickcontrol_p_p.h index 7d040ded..410c7811 100644 --- a/src/quicktemplates2/qquickcontrol_p_p.h +++ b/src/quicktemplates2/qquickcontrol_p_p.h @@ -50,10 +50,11 @@ #include <QtQuickTemplates2/private/qquickcontrol_p.h> #include <QtQuickTemplates2/private/qquickdeferredpointer_p_p.h> +#include <QtQuickTemplates2/private/qquicktheme_p.h> #include <QtQuick/private/qquickitem_p.h> +#include <QtQuick/private/qquickitemchangelistener_p.h> #include <QtQml/private/qlazilyallocated_p.h> -#include <qpa/qplatformtheme.h> #if QT_CONFIG(accessibility) #include <QtGui/qaccessible.h> @@ -63,7 +64,7 @@ QT_BEGIN_NAMESPACE class QQuickAccessibleAttached; -class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickControlPrivate : public QQuickItemPrivate +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickControlPrivate : public QQuickItemPrivate, public QQuickItemChangeListener #if QT_CONFIG(accessibility) , public QAccessible::ActivationObserver #endif @@ -79,6 +80,8 @@ public: return control->d_func(); } + void init(); + #if QT_CONFIG(quicktemplates2_multitouch) virtual bool acceptTouch(const QTouchEvent::TouchPoint &point); #endif @@ -89,10 +92,31 @@ public: void mirrorChange() override; + inline QMarginsF getPadding() const { return QMarginsF(getLeftPadding(), getTopPadding(), getRightPadding(), getBottomPadding()); } + inline qreal getTopPadding() const { return extra.isAllocated() && extra->hasTopPadding ? extra->topPadding : getVerticalPadding(); } + inline qreal getLeftPadding() const { return extra.isAllocated() && extra->hasLeftPadding ? extra->leftPadding : getHorizontalPadding(); } + inline qreal getRightPadding() const { return extra.isAllocated() && extra->hasRightPadding ? extra->rightPadding : getHorizontalPadding(); } + inline qreal getBottomPadding() const { return extra.isAllocated() && extra->hasBottomPadding ? extra->bottomPadding : getVerticalPadding(); } + inline qreal getHorizontalPadding() const { return hasHorizontalPadding ? horizontalPadding : padding; } + inline qreal getVerticalPadding() const { return hasVerticalPadding ? verticalPadding : padding; } + void setTopPadding(qreal value, bool reset = false); void setLeftPadding(qreal value, bool reset = false); void setRightPadding(qreal value, bool reset = false); void setBottomPadding(qreal value, bool reset = false); + void setHorizontalPadding(qreal value, bool reset = false); + void setVerticalPadding(qreal value, bool reset = false); + + inline QMarginsF getInset() const { return QMarginsF(getLeftInset(), getTopInset(), getRightInset(), getBottomInset()); } + inline qreal getTopInset() const { return extra.isAllocated() ? extra->topInset : 0; } + inline qreal getLeftInset() const { return extra.isAllocated() ? extra->leftInset : 0; } + inline qreal getRightInset() const { return extra.isAllocated() ? extra->rightInset : 0; } + inline qreal getBottomInset() const { return extra.isAllocated() ? extra->bottomInset : 0; } + + void setTopInset(qreal value, bool reset = false); + void setLeftInset(qreal value, bool reset = false); + void setRightInset(qreal value, bool reset = false); + void setBottomInset(qreal value, bool reset = false); void resizeBackground(); virtual void resizeContent(); @@ -116,7 +140,6 @@ public: updateFont(font); } static QFont parentFont(const QQuickItem *item); - static QFont themeFont(QPlatformTheme::Font type); virtual void resolvePalette(); void inheritPalette(const QPalette &palette); @@ -128,7 +151,6 @@ public: updatePalette(palette); } static QPalette parentPalette(const QQuickItem *item); - static QPalette themePalette(QPlatformTheme::Palette type); void updateLocale(const QLocale &l, bool e); static void updateLocaleRecur(QQuickItem *item, const QLocale &l); @@ -146,29 +168,66 @@ public: virtual void cancelBackground(); virtual void executeBackground(bool complete = false); + void updateBaselineOffset(); + + static const ChangeTypes ImplicitSizeChanges; + + void addImplicitSizeListener(QQuickItem *item, ChangeTypes changes = ImplicitSizeChanges); + void removeImplicitSizeListener(QQuickItem *item, ChangeTypes changes = ImplicitSizeChanges); + + void itemImplicitWidthChanged(QQuickItem *item) override; + void itemImplicitHeightChanged(QQuickItem *item) override; + void itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &diff) override; + void itemDestroyed(QQuickItem *item) override; + + virtual qreal getContentWidth() const; + virtual qreal getContentHeight() const; + + void updateImplicitContentWidth(); + void updateImplicitContentHeight(); + void updateImplicitContentSize(); + struct ExtraData { ExtraData(); + bool hasTopPadding; + bool hasLeftPadding; + bool hasRightPadding; + bool hasBottomPadding; + bool hasBaselineOffset; + bool hasTopInset; + bool hasLeftInset; + bool hasRightInset; + bool hasBottomInset; + bool hasBackgroundWidth; + bool hasBackgroundHeight; + qreal topPadding; + qreal leftPadding; + qreal rightPadding; + qreal bottomPadding; + qreal topInset; + qreal leftInset; + qreal rightInset; + qreal bottomInset; QFont requestedFont; QPalette requestedPalette; }; QLazilyAllocated<ExtraData> extra; - bool hasTopPadding; - bool hasLeftPadding; - bool hasRightPadding; - bool hasBottomPadding; + bool hasHorizontalPadding; + bool hasVerticalPadding; bool hasLocale; bool wheelEnabled; #if QT_CONFIG(quicktemplates2_hover) bool hovered; bool explicitHoverEnabled; #endif + bool resizingBackground; int touchId; qreal padding; - qreal topPadding; - qreal leftPadding; - qreal rightPadding; - qreal bottomPadding; + qreal horizontalPadding; + qreal verticalPadding; + qreal implicitContentWidth; + qreal implicitContentHeight; qreal spacing; QLocale locale; QFont resolvedFont; diff --git a/src/quicktemplates2/qquickdelaybutton.cpp b/src/quicktemplates2/qquickdelaybutton.cpp index 128f0c78..02efc3a2 100644 --- a/src/quicktemplates2/qquickdelaybutton.cpp +++ b/src/quicktemplates2/qquickdelaybutton.cpp @@ -265,12 +265,12 @@ void QQuickDelayButton::nextCheckState() QFont QQuickDelayButton::defaultFont() const { - return QQuickControlPrivate::themeFont(QPlatformTheme::PushButtonFont); + return QQuickTheme::themeFont(QQuickTheme::Button); } QPalette QQuickDelayButton::defaultPalette() const { - return QQuickControlPrivate::themePalette(QPlatformTheme::ButtonPalette); + return QQuickTheme::themePalette(QQuickTheme::Button); } QT_END_NAMESPACE diff --git a/src/quicktemplates2/qquickdialog.cpp b/src/quicktemplates2/qquickdialog.cpp index cce1ae47..7d3152e2 100644 --- a/src/quicktemplates2/qquickdialog.cpp +++ b/src/quicktemplates2/qquickdialog.cpp @@ -183,7 +183,13 @@ QQuickDialog::QQuickDialog(QObject *parent) : QQuickPopup(*(new QQuickDialogPrivate), parent) { Q_D(QQuickDialog); - d->layout.reset(new QQuickPageLayout(d->popupItem)); + connect(d->popupItem, &QQuickPopupItem::titleChanged, this, &QQuickDialog::titleChanged); + connect(d->popupItem, &QQuickPopupItem::headerChanged, this, &QQuickDialog::headerChanged); + connect(d->popupItem, &QQuickPopupItem::footerChanged, this, &QQuickDialog::footerChanged); + connect(d->popupItem, &QQuickPopupItem::implicitHeaderWidthChanged, this, &QQuickDialog::implicitHeaderWidthChanged); + connect(d->popupItem, &QQuickPopupItem::implicitHeaderHeightChanged, this, &QQuickDialog::implicitHeaderHeightChanged); + connect(d->popupItem, &QQuickPopupItem::implicitFooterWidthChanged, this, &QQuickDialog::implicitFooterWidthChanged); + connect(d->popupItem, &QQuickPopupItem::implicitFooterHeightChanged, this, &QQuickDialog::implicitFooterHeightChanged); } /*! @@ -206,18 +212,14 @@ QQuickDialog::QQuickDialog(QObject *parent) QString QQuickDialog::title() const { Q_D(const QQuickDialog); - return d->title; + return d->popupItem->title(); } void QQuickDialog::setTitle(const QString &title) { Q_D(QQuickDialog); - if (d->title == title) - return; - - d->title = title; + d->popupItem->setTitle(title); setAccessibleName(title); - emit titleChanged(); } /*! @@ -239,14 +241,14 @@ void QQuickDialog::setTitle(const QString &title) QQuickItem *QQuickDialog::header() const { Q_D(const QQuickDialog); - return d->layout->header(); + return d->popupItem->header(); } void QQuickDialog::setHeader(QQuickItem *header) { Q_D(QQuickDialog); - QQuickItem *oldHeader = d->layout->header(); - if (!d->layout->setHeader(header)) + QQuickItem *oldHeader = d->popupItem->header(); + if (oldHeader == header) return; if (QQuickDialogButtonBox *buttonBox = qobject_cast<QQuickDialogButtonBox *>(oldHeader)) { @@ -256,6 +258,7 @@ void QQuickDialog::setHeader(QQuickItem *header) if (d->buttonBox == buttonBox) d->buttonBox = nullptr; } + if (QQuickDialogButtonBox *buttonBox = qobject_cast<QQuickDialogButtonBox *>(header)) { connect(buttonBox, &QQuickDialogButtonBox::accepted, this, &QQuickDialog::accept); connect(buttonBox, &QQuickDialogButtonBox::rejected, this, &QQuickDialog::reject); @@ -264,9 +267,7 @@ void QQuickDialog::setHeader(QQuickItem *header) buttonBox->setStandardButtons(d->standardButtons); } - if (isComponentComplete()) - d->layout->update(); - emit headerChanged(); + d->popupItem->setHeader(header); } /*! @@ -288,14 +289,14 @@ void QQuickDialog::setHeader(QQuickItem *header) QQuickItem *QQuickDialog::footer() const { Q_D(const QQuickDialog); - return d->layout->footer(); + return d->popupItem->footer(); } void QQuickDialog::setFooter(QQuickItem *footer) { Q_D(QQuickDialog); - QQuickItem *oldFooter = d->layout->footer(); - if (!d->layout->setFooter(footer)) + QQuickItem *oldFooter = d->popupItem->footer(); + if (oldFooter == footer) return; if (QQuickDialogButtonBox *buttonBox = qobject_cast<QQuickDialogButtonBox *>(oldFooter)) { @@ -313,9 +314,7 @@ void QQuickDialog::setFooter(QQuickItem *footer) buttonBox->setStandardButtons(d->standardButtons); } - if (isComponentComplete()) - d->layout->update(); - emit footerChanged(); + d->popupItem->setFooter(footer); } /*! @@ -413,6 +412,74 @@ void QQuickDialog::setResult(int result) } /*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::Dialog::implicitHeaderWidth + \readonly + + This property holds the implicit header width. + + The value is equal to \c {header && header.visible ? header.implicitWidth : 0}. + + \sa implicitHeaderHeight, implicitFooterWidth +*/ +qreal QQuickDialog::implicitHeaderWidth() const +{ + Q_D(const QQuickDialog); + return d->popupItem->implicitHeaderWidth(); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::Dialog::implicitHeaderHeight + \readonly + + This property holds the implicit header height. + + The value is equal to \c {header && header.visible ? header.implicitHeight : 0}. + + \sa implicitHeaderWidth, implicitFooterHeight +*/ +qreal QQuickDialog::implicitHeaderHeight() const +{ + Q_D(const QQuickDialog); + return d->popupItem->implicitHeaderHeight(); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::Dialog::implicitFooterWidth + \readonly + + This property holds the implicit footer width. + + The value is equal to \c {footer && footer.visible ? footer.implicitWidth : 0}. + + \sa implicitFooterHeight, implicitHeaderWidth +*/ +qreal QQuickDialog::implicitFooterWidth() const +{ + Q_D(const QQuickDialog); + return d->popupItem->implicitFooterWidth(); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::Dialog::implicitFooterHeight + \readonly + + This property holds the implicit footer height. + + The value is equal to \c {footer && footer.visible ? footer.implicitHeight : 0}. + + \sa implicitFooterWidth, implicitHeaderHeight +*/ +qreal QQuickDialog::implicitFooterHeight() const +{ + Q_D(const QQuickDialog); + return d->popupItem->implicitFooterHeight(); +} + +/*! \qmlmethod void QtQuick.Controls::Dialog::accept() Closes the dialog and emits the \l accepted() signal. @@ -457,27 +524,6 @@ void QQuickDialog::done(int result) emit rejected(); } -void QQuickDialog::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) -{ - Q_D(QQuickDialog); - QQuickPopup::geometryChanged(newGeometry, oldGeometry); - d->layout->update(); -} - -void QQuickDialog::paddingChange(const QMarginsF &newPadding, const QMarginsF &oldPadding) -{ - Q_D(QQuickDialog); - QQuickPopup::paddingChange(newPadding, oldPadding); - d->layout->update(); -} - -void QQuickDialog::spacingChange(qreal newSpacing, qreal oldSpacing) -{ - Q_D(QQuickDialog); - QQuickPopup::spacingChange(newSpacing, oldSpacing); - d->layout->update(); -} - #if QT_CONFIG(accessibility) QAccessible::Role QQuickDialog::accessibleRole() const { @@ -490,7 +536,7 @@ void QQuickDialog::accessibilityActiveChanged(bool active) QQuickPopup::accessibilityActiveChanged(active); if (active) - setAccessibleName(d->title); + setAccessibleName(d->popupItem->title()); } #endif diff --git a/src/quicktemplates2/qquickdialog_p.h b/src/quicktemplates2/qquickdialog_p.h index d22685b6..38a1b396 100644 --- a/src/quicktemplates2/qquickdialog_p.h +++ b/src/quicktemplates2/qquickdialog_p.h @@ -66,6 +66,11 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickDialog : public QQuickPopup // 2.3 (Qt 5.10) Q_PROPERTY(int result READ result WRITE setResult NOTIFY resultChanged FINAL REVISION 3) Q_FLAGS(QPlatformDialogHelper::StandardButtons) + // 2.5 (Qt 5.12) + Q_PROPERTY(qreal implicitHeaderWidth READ implicitHeaderWidth NOTIFY implicitHeaderWidthChanged FINAL REVISION 5) + Q_PROPERTY(qreal implicitHeaderHeight READ implicitHeaderHeight NOTIFY implicitHeaderHeightChanged FINAL REVISION 5) + Q_PROPERTY(qreal implicitFooterWidth READ implicitFooterWidth NOTIFY implicitFooterWidthChanged FINAL REVISION 5) + Q_PROPERTY(qreal implicitFooterHeight READ implicitFooterHeight NOTIFY implicitFooterHeightChanged FINAL REVISION 5) public: explicit QQuickDialog(QObject *parent = nullptr); @@ -90,6 +95,13 @@ public: int result() const; void setResult(int result); + // 2.5 (Qt 5.12) + qreal implicitHeaderWidth() const; + qreal implicitHeaderHeight() const; + + qreal implicitFooterWidth() const; + qreal implicitFooterHeight() const; + public Q_SLOTS: virtual void accept(); virtual void reject(); @@ -108,12 +120,13 @@ Q_SIGNALS: Q_REVISION(3) void discarded(); Q_REVISION(3) void helpRequested(); Q_REVISION(3) void resultChanged(); + // 2.5 (Qt 5.12) + void implicitHeaderWidthChanged(); + void implicitHeaderHeightChanged(); + void implicitFooterWidthChanged(); + void implicitFooterHeightChanged(); protected: - void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) override; - void paddingChange(const QMarginsF &newPadding, const QMarginsF &oldPadding) override; - void spacingChange(qreal newSpacing, qreal oldSpacing) override; - #if QT_CONFIG(accessibility) QAccessible::Role accessibleRole() const override; void accessibilityActiveChanged(bool active) override; diff --git a/src/quicktemplates2/qquickdialog_p_p.h b/src/quicktemplates2/qquickdialog_p_p.h index e26182ac..70128f34 100644 --- a/src/quicktemplates2/qquickdialog_p_p.h +++ b/src/quicktemplates2/qquickdialog_p_p.h @@ -50,7 +50,6 @@ #include <QtQuickTemplates2/private/qquickdialog_p.h> #include <QtQuickTemplates2/private/qquickpopup_p_p.h> -#include <QtQuickTemplates2/private/qquickpagelayout_p_p.h> #include <QtGui/qpa/qplatformdialoghelper.h> QT_BEGIN_NAMESPACE @@ -75,9 +74,7 @@ public: void handleClick(QQuickAbstractButton *button); int result; - QString title; QQuickDialogButtonBox *buttonBox; - QScopedPointer<QQuickPageLayout> layout; QPlatformDialogHelper::StandardButtons standardButtons; }; diff --git a/src/quicktemplates2/qquickdialogbuttonbox.cpp b/src/quicktemplates2/qquickdialogbuttonbox.cpp index 52171f5b..98437500 100644 --- a/src/quicktemplates2/qquickdialogbuttonbox.cpp +++ b/src/quicktemplates2/qquickdialogbuttonbox.cpp @@ -192,24 +192,37 @@ QT_BEGIN_NAMESPACE \sa accepted(), rejected(), helpRequested() */ +static QQuickDialogButtonBox::ButtonLayout platformButtonLayout() +{ + return QGuiApplicationPrivate::platformTheme()->themeHint(QPlatformTheme::DialogButtonBoxLayout).value<QQuickDialogButtonBox::ButtonLayout>(); +} + QQuickDialogButtonBoxPrivate::QQuickDialogButtonBoxPrivate() : alignment(0), position(QQuickDialogButtonBox::Footer), standardButtons(QPlatformDialogHelper::NoButton), + buttonLayout(platformButtonLayout()), delegate(nullptr) { + changeTypes |= ImplicitWidth | ImplicitHeight; } void QQuickDialogButtonBoxPrivate::itemImplicitWidthChanged(QQuickItem *item) { - Q_UNUSED(item); - resizeContent(); + QQuickContainerPrivate::itemImplicitWidthChanged(item); + if (item == contentItem) + resizeContent(); + else + updateImplicitContentWidth(); } void QQuickDialogButtonBoxPrivate::itemImplicitHeightChanged(QQuickItem *item) { - Q_UNUSED(item); - resizeContent(); + QQuickContainerPrivate::itemImplicitHeightChanged(item); + if (item == contentItem) + resizeContent(); + else + updateImplicitContentHeight(); } // adapted from QStyle::alignedRect() @@ -220,7 +233,7 @@ static QRectF alignedRect(Qt::LayoutDirection direction, Qt::Alignment alignment qreal y = rectangle.y(); qreal w = size.width(); qreal h = size.height(); - if ((alignment & Qt::AlignVCenter) == Qt::AlignVCenter) + if ((alignment & Qt::AlignVCenter) == Qt::AlignVCenter || (alignment & Qt::AlignVertical_Mask) == 0) y += (rectangle.size().height() - h) / 2; else if ((alignment & Qt::AlignBottom) == Qt::AlignBottom) y += rectangle.size().height() - h; @@ -238,11 +251,8 @@ void QQuickDialogButtonBoxPrivate::resizeContent() return; QRectF geometry = q->boundingRect().adjusted(q->leftPadding(), q->topPadding(), -q->rightPadding(), -q->bottomPadding()); - if (alignment != 0) { - qreal cw = (alignment & Qt::AlignHorizontal_Mask) == 0 ? q->availableWidth() : contentItem->property("contentWidth").toReal(); - qreal ch = (alignment & Qt::AlignVertical_Mask) == 0 ? q->availableHeight() : contentItem->property("contentHeight").toReal(); - geometry = alignedRect(q->isMirrored() ? Qt::RightToLeft : Qt::LeftToRight, alignment, QSizeF(cw, ch), geometry); - } + if (alignment != 0) + geometry = alignedRect(q->isMirrored() ? Qt::RightToLeft : Qt::LeftToRight, alignment, QSizeF(contentWidth, contentHeight), geometry); contentItem->setPosition(geometry.topLeft()); contentItem->setSize(geometry.size()); @@ -259,8 +269,8 @@ void QQuickDialogButtonBoxPrivate::updateLayout() const int valign = alignment & Qt::AlignVertical_Mask; QVector<QQuickAbstractButton *> buttons; - const qreal maxItemWidth = ((contentItem ? contentItem->width() : q->availableWidth()) - qMax(0, count - 1) * spacing) / count; - const qreal maxItemHeight = contentItem ? contentItem->height() : q->availableHeight(); + const qreal cw = (alignment & Qt::AlignHorizontal_Mask) == 0 ? q->availableWidth() : contentWidth; + const qreal itemWidth = (cw - qMax(0, count - 1) * spacing) / count; for (int i = 0; i < count; ++i) { QQuickItem *item = q->itemAt(i); @@ -268,11 +278,11 @@ void QQuickDialogButtonBoxPrivate::updateLayout() QQuickItemPrivate *p = QQuickItemPrivate::get(item); if (!p->widthValid) { if (!halign) - item->setWidth(maxItemWidth); + item->setWidth(itemWidth); else item->resetWidth(); if (!valign) - item->setHeight(maxItemHeight); + item->setHeight(contentHeight); else item->resetHeight(); p->widthValid = false; @@ -282,6 +292,11 @@ void QQuickDialogButtonBoxPrivate::updateLayout() } struct ButtonLayout { + ButtonLayout(QPlatformDialogHelper::ButtonLayout layout) + : m_layout(QPlatformDialogHelper::buttonLayout(Qt::Horizontal, layout)) + { + } + bool operator()(QQuickAbstractButton *first, QQuickAbstractButton *second) { const QPlatformDialogHelper::ButtonRole firstRole = QQuickDialogPrivate::buttonRole(first); @@ -304,20 +319,47 @@ void QQuickDialogButtonBoxPrivate::updateLayout() return firstRole != QPlatformDialogHelper::InvalidRole; } - static const int *themeButtonLayout() - { - const int hint = QGuiApplicationPrivate::platformTheme()->themeHint(QPlatformTheme::DialogButtonBoxLayout).toInt(); - return QPlatformDialogHelper::buttonLayout(Qt::Horizontal, static_cast<QPlatformDialogHelper::ButtonLayout>(hint)); - } - const int *m_layout = themeButtonLayout(); + const int *m_layout; }; - std::sort(buttons.begin(), buttons.end(), ButtonLayout()); + std::sort(buttons.begin(), buttons.end(), ButtonLayout(static_cast<QPlatformDialogHelper::ButtonLayout>(buttonLayout))); for (int i = 0; i < buttons.count() - 1; ++i) q->insertItem(i, buttons.at(i)); } +qreal QQuickDialogButtonBoxPrivate::getContentWidth() const +{ + Q_Q(const QQuickDialogButtonBox); + const int count = contentModel->count(); + const qreal totalSpacing = qMax(0, count - 1) * spacing; + qreal totalWidth = totalSpacing; + qreal maxWidth = 0; + for (int i = 0; i < count; ++i) { + QQuickItem *item = q->itemAt(i); + if (item) { + totalWidth += item->implicitWidth(); + maxWidth = qMax(maxWidth, item->implicitWidth()); + } + } + if ((alignment & Qt::AlignHorizontal_Mask) == 0) + totalWidth = qMax(totalWidth, count * maxWidth + totalSpacing); + return totalWidth; +} + +qreal QQuickDialogButtonBoxPrivate::getContentHeight() const +{ + Q_Q(const QQuickDialogButtonBox); + const int count = contentModel->count(); + qreal maxHeight = 0; + for (int i = 0; i < count; ++i) { + QQuickItem *item = q->itemAt(i); + if (item) + maxHeight = qMax(maxHeight, item->implicitHeight()); + } + return maxHeight; +} + void QQuickDialogButtonBoxPrivate::handleClick() { Q_Q(QQuickDialogButtonBox); @@ -604,6 +646,43 @@ QQuickDialogButtonBoxAttached *QQuickDialogButtonBox::qmlAttachedProperties(QObj return new QQuickDialogButtonBoxAttached(object); } +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty enumeration QtQuick.Controls::DialogButtonBox::buttonLayout + + This property holds the button layout policy to be used when arranging the buttons contained in the button box. + The default value is platform-specific. + + Available values: + \value DialogButtonBox.WinLayout Use a policy appropriate for applications on Windows. + \value DialogButtonBox.MacLayout Use a policy appropriate for applications on macOS. + \value DialogButtonBox.KdeLayout Use a policy appropriate for applications on KDE. + \value DialogButtonBox.GnomeLayout Use a policy appropriate for applications on GNOME. + \value DialogButtonBox.AndroidLayout Use a policy appropriate for applications on Android. +*/ +QQuickDialogButtonBox::ButtonLayout QQuickDialogButtonBox::buttonLayout() const +{ + Q_D(const QQuickDialogButtonBox); + return d->buttonLayout; +} + +void QQuickDialogButtonBox::setButtonLayout(ButtonLayout layout) +{ + Q_D(QQuickDialogButtonBox); + if (d->buttonLayout == layout) + return; + + d->buttonLayout = layout; + if (isComponentComplete()) + d->updateLayout(); + emit buttonLayoutChanged(); +} + +void QQuickDialogButtonBox::resetButtonLayout() +{ + setButtonLayout(platformButtonLayout()); +} + void QQuickDialogButtonBox::updatePolish() { Q_D(QQuickDialogButtonBox); @@ -648,6 +727,7 @@ void QQuickDialogButtonBox::itemAdded(int index, QQuickItem *item) QObjectPrivate::connect(button, &QQuickAbstractButton::clicked, d, &QQuickDialogButtonBoxPrivate::handleClick); if (QQuickDialogButtonBoxAttached *attached = qobject_cast<QQuickDialogButtonBoxAttached *>(qmlAttachedPropertiesObject<QQuickDialogButtonBox>(item, false))) QQuickDialogButtonBoxAttachedPrivate::get(attached)->setButtonBox(this); + d->updateImplicitContentSize(); if (isComponentComplete()) polish(); } @@ -660,6 +740,7 @@ void QQuickDialogButtonBox::itemRemoved(int index, QQuickItem *item) QObjectPrivate::disconnect(button, &QQuickAbstractButton::clicked, d, &QQuickDialogButtonBoxPrivate::handleClick); if (QQuickDialogButtonBoxAttached *attached = qobject_cast<QQuickDialogButtonBoxAttached *>(qmlAttachedPropertiesObject<QQuickDialogButtonBox>(item, false))) QQuickDialogButtonBoxAttachedPrivate::get(attached)->setButtonBox(nullptr); + d->updateImplicitContentSize(); if (isComponentComplete()) polish(); } diff --git a/src/quicktemplates2/qquickdialogbuttonbox_p.h b/src/quicktemplates2/qquickdialogbuttonbox_p.h index 1e3cdeef..df302e54 100644 --- a/src/quicktemplates2/qquickdialogbuttonbox_p.h +++ b/src/quicktemplates2/qquickdialogbuttonbox_p.h @@ -66,6 +66,8 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickDialogButtonBox : public QQuickCont Q_PROPERTY(Qt::Alignment alignment READ alignment WRITE setAlignment RESET resetAlignment NOTIFY alignmentChanged FINAL) Q_PROPERTY(QPlatformDialogHelper::StandardButtons standardButtons READ standardButtons WRITE setStandardButtons NOTIFY standardButtonsChanged FINAL) Q_PROPERTY(QQmlComponent *delegate READ delegate WRITE setDelegate NOTIFY delegateChanged FINAL) + // 2.5 (Qt 5.12) + Q_PROPERTY(ButtonLayout buttonLayout READ buttonLayout WRITE setButtonLayout RESET resetButtonLayout NOTIFY buttonLayoutChanged FINAL REVISION 5) Q_FLAGS(QPlatformDialogHelper::StandardButtons) public: @@ -94,6 +96,24 @@ public: static QQuickDialogButtonBoxAttached *qmlAttachedProperties(QObject *object); + // 2.5 (Qt 5.12) + + // ### TODO: use Q_ENUMS(QPlatformDialogHelper::ButtonLayout) + enum ButtonLayout { + UnknownLayout = -1, + WinLayout, + MacLayout, + KdeLayout, + GnomeLayout, + MacModelessLayout, + AndroidLayout + }; + Q_ENUM(ButtonLayout) + + ButtonLayout buttonLayout() const; + void setButtonLayout(ButtonLayout layout); + void resetButtonLayout(); + Q_SIGNALS: void accepted(); void rejected(); @@ -107,6 +127,8 @@ Q_SIGNALS: Q_REVISION(3) void applied(); Q_REVISION(3) void reset(); Q_REVISION(3) void discarded(); + // 2.5 (Qt 5.12) + Q_REVISION(5) void buttonLayoutChanged(); protected: void updatePolish() override; diff --git a/src/quicktemplates2/qquickdialogbuttonbox_p_p.h b/src/quicktemplates2/qquickdialogbuttonbox_p_p.h index 7247d591..5633d880 100644 --- a/src/quicktemplates2/qquickdialogbuttonbox_p_p.h +++ b/src/quicktemplates2/qquickdialogbuttonbox_p_p.h @@ -69,7 +69,12 @@ public: void itemImplicitHeightChanged(QQuickItem *item) override; void resizeContent() override; + void updateLayout(); + + qreal getContentWidth() const override; + qreal getContentHeight() const override; + void handleClick(); QQuickAbstractButton *createStandardButton(QPlatformDialogHelper::StandardButton button); @@ -78,6 +83,7 @@ public: Qt::Alignment alignment; QQuickDialogButtonBox::Position position; QPlatformDialogHelper::StandardButtons standardButtons; + QQuickDialogButtonBox::ButtonLayout buttonLayout; QQmlComponent *delegate; }; diff --git a/src/quicktemplates2/qquickgroupbox.cpp b/src/quicktemplates2/qquickgroupbox.cpp index 4f4c5eed..490d8bdd 100644 --- a/src/quicktemplates2/qquickgroupbox.cpp +++ b/src/quicktemplates2/qquickgroupbox.cpp @@ -94,6 +94,9 @@ public: void cancelLabel(); void executeLabel(bool complete = false); + void itemImplicitWidthChanged(QQuickItem *item) override; + void itemImplicitHeightChanged(QQuickItem *item) override; + QString title; QQuickDeferredPointer<QQuickItem> label; }; @@ -118,11 +121,33 @@ void QQuickGroupBoxPrivate::executeLabel(bool complete) quickCompleteDeferred(q, labelName(), label); } +void QQuickGroupBoxPrivate::itemImplicitWidthChanged(QQuickItem *item) +{ + Q_Q(QQuickGroupBox); + QQuickFramePrivate::itemImplicitWidthChanged(item); + if (item == label) + emit q->implicitLabelWidthChanged(); +} + +void QQuickGroupBoxPrivate::itemImplicitHeightChanged(QQuickItem *item) +{ + Q_Q(QQuickGroupBox); + QQuickFramePrivate::itemImplicitHeightChanged(item); + if (item == label) + emit q->implicitLabelHeightChanged(); +} + QQuickGroupBox::QQuickGroupBox(QQuickItem *parent) : QQuickFrame(*(new QQuickGroupBoxPrivate), parent) { } +QQuickGroupBox::~QQuickGroupBox() +{ + Q_D(QQuickGroupBox); + d->removeImplicitSizeListener(d->label); +} + /*! \qmlproperty string QtQuick.Controls::GroupBox::title @@ -172,14 +197,65 @@ void QQuickGroupBox::setLabel(QQuickItem *label) if (!d->label.isExecuting()) d->cancelLabel(); + const qreal oldImplicitLabelWidth = implicitLabelWidth(); + const qreal oldImplicitLabelHeight = implicitLabelHeight(); + + d->removeImplicitSizeListener(d->label); delete d->label; d->label = label; - if (label && !label->parentItem()) - label->setParentItem(this); + + if (label) { + if (!label->parentItem()) + label->setParentItem(this); + d->addImplicitSizeListener(label); + } + + if (!qFuzzyCompare(oldImplicitLabelWidth, implicitLabelWidth())) + emit implicitLabelWidthChanged(); + if (!qFuzzyCompare(oldImplicitLabelHeight, implicitLabelHeight())) + emit implicitLabelHeightChanged(); if (!d->label.isExecuting()) emit labelChanged(); } +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::GroupBox::implicitLabelWidth + \readonly + + This property holds the implicit label width. + + The value is equal to \c {label ? label.implicitWidth : 0}. + + \sa implicitLabelHeight +*/ +qreal QQuickGroupBox::implicitLabelWidth() const +{ + Q_D(const QQuickGroupBox); + if (!d->label) + return 0; + return d->label->implicitWidth(); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::GroupBox::implicitLabelHeight + \readonly + + This property holds the implicit label height. + + The value is equal to \c {label ? label.implicitHeight : 0}. + + \sa implicitLabelWidth +*/ +qreal QQuickGroupBox::implicitLabelHeight() const +{ + Q_D(const QQuickGroupBox); + if (!d->label) + return 0; + return d->label->implicitHeight(); +} + void QQuickGroupBox::componentComplete() { Q_D(QQuickGroupBox); @@ -189,12 +265,12 @@ void QQuickGroupBox::componentComplete() QFont QQuickGroupBox::defaultFont() const { - return QQuickControlPrivate::themeFont(QPlatformTheme::GroupBoxTitleFont); + return QQuickTheme::themeFont(QQuickTheme::GroupBox); } QPalette QQuickGroupBox::defaultPalette() const { - return QQuickControlPrivate::themePalette(QPlatformTheme::GroupBoxPalette); + return QQuickTheme::themePalette(QQuickTheme::GroupBox); } #if QT_CONFIG(accessibility) diff --git a/src/quicktemplates2/qquickgroupbox_p.h b/src/quicktemplates2/qquickgroupbox_p.h index b46d91fd..de36d7d7 100644 --- a/src/quicktemplates2/qquickgroupbox_p.h +++ b/src/quicktemplates2/qquickgroupbox_p.h @@ -59,10 +59,14 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickGroupBox : public QQuickFrame Q_OBJECT Q_PROPERTY(QString title READ title WRITE setTitle NOTIFY titleChanged FINAL) Q_PROPERTY(QQuickItem *label READ label WRITE setLabel NOTIFY labelChanged FINAL) + // 2.5 (Qt 5.12) + Q_PROPERTY(qreal implicitLabelWidth READ implicitLabelWidth NOTIFY implicitLabelWidthChanged FINAL REVISION 5) + Q_PROPERTY(qreal implicitLabelHeight READ implicitLabelHeight NOTIFY implicitLabelHeightChanged FINAL REVISION 5) Q_CLASSINFO("DeferredPropertyNames", "background,contentItem,label") public: explicit QQuickGroupBox(QQuickItem *parent = nullptr); + ~QQuickGroupBox(); QString title() const; void setTitle(const QString &title); @@ -70,9 +74,16 @@ public: QQuickItem *label() const; void setLabel(QQuickItem *label); + // 2.5 (Qt 5.12) + qreal implicitLabelWidth() const; + qreal implicitLabelHeight() const; + Q_SIGNALS: void titleChanged(); void labelChanged(); + // 2.5 (Qt 5.12) + Q_REVISION(5) void implicitLabelWidthChanged(); + Q_REVISION(5) void implicitLabelHeightChanged(); protected: void componentComplete() override; diff --git a/src/quicktemplates2/qquickitemdelegate.cpp b/src/quicktemplates2/qquickitemdelegate.cpp index 044141f2..145eaaf4 100644 --- a/src/quicktemplates2/qquickitemdelegate.cpp +++ b/src/quicktemplates2/qquickitemdelegate.cpp @@ -122,12 +122,12 @@ void QQuickItemDelegate::setHighlighted(bool highlighted) QFont QQuickItemDelegate::defaultFont() const { - return QQuickControlPrivate::themeFont(QPlatformTheme::ItemViewFont); + return QQuickTheme::themeFont(QQuickTheme::ItemView); } QPalette QQuickItemDelegate::defaultPalette() const { - return QQuickControlPrivate::themePalette(QPlatformTheme::ItemViewPalette); + return QQuickTheme::themePalette(QQuickTheme::ItemView); } #if QT_CONFIG(accessibility) diff --git a/src/quicktemplates2/qquicklabel.cpp b/src/quicktemplates2/qquicklabel.cpp index d39006cd..e54aa556 100644 --- a/src/quicktemplates2/qquicklabel.cpp +++ b/src/quicktemplates2/qquicklabel.cpp @@ -129,7 +129,7 @@ void QQuickLabelPrivate::inheritFont(const QFont &font) QFont parentFont = extra.isAllocated() ? extra->requestedFont.resolve(font) : font; parentFont.resolve(extra.isAllocated() ? extra->requestedFont.resolve() | font.resolve() : font.resolve()); - const QFont defaultFont = QQuickControlPrivate::themeFont(QPlatformTheme::LabelFont); + const QFont defaultFont = QQuickTheme::themeFont(QQuickTheme::Label); const QFont resolvedFont = parentFont.resolve(defaultFont); setFont_helper(resolvedFont); @@ -171,7 +171,7 @@ void QQuickLabelPrivate::inheritPalette(const QPalette &palette) QPalette parentPalette = extra.isAllocated() ? extra->requestedPalette.resolve(palette) : palette; parentPalette.resolve(extra.isAllocated() ? extra->requestedPalette.resolve() | palette.resolve() : palette.resolve()); - const QPalette defaultPalette = QQuickControlPrivate::themePalette(QPlatformTheme::LabelPalette); + const QPalette defaultPalette = QQuickTheme::themePalette(QQuickTheme::Label); const QPalette resolvedPalette = parentPalette.resolve(defaultPalette); setPalette_helper(resolvedPalette); diff --git a/src/quicktemplates2/qquickmenu.cpp b/src/quicktemplates2/qquickmenu.cpp index 5dbfe3d9..4e334bba 100644 --- a/src/quicktemplates2/qquickmenu.cpp +++ b/src/quicktemplates2/qquickmenu.cpp @@ -1432,12 +1432,12 @@ void QQuickMenu::timerEvent(QTimerEvent *event) QFont QQuickMenu::defaultFont() const { - return QQuickControlPrivate::themeFont(QPlatformTheme::MenuFont); + return QQuickTheme::themeFont(QQuickTheme::Menu); } QPalette QQuickMenu::defaultPalette() const { - return QQuickControlPrivate::themePalette(QPlatformTheme::MenuPalette); + return QQuickTheme::themePalette(QQuickTheme::Menu); } #if QT_CONFIG(accessibility) diff --git a/src/quicktemplates2/qquickmenubar.cpp b/src/quicktemplates2/qquickmenubar.cpp index 8398633c..2d4c7a4f 100644 --- a/src/quicktemplates2/qquickmenubar.cpp +++ b/src/quicktemplates2/qquickmenubar.cpp @@ -79,13 +79,9 @@ QT_BEGIN_NAMESPACE QQuickMenuBarPrivate::QQuickMenuBarPrivate() : popupMode(false), triggering(false), - hasContentWidth(false), - hasContentHeight(false), - contentWidth(0), - contentHeight(0), delegate(nullptr) { - changeTypes |= Geometry; + changeTypes |= ImplicitWidth | ImplicitHeight; } QQuickItem *QQuickMenuBarPrivate::beginCreateItem() @@ -223,49 +219,44 @@ void QQuickMenuBarPrivate::onMenuAboutToHide() activateItem(nullptr); } -void QQuickMenuBarPrivate::updateContentSize() +qreal QQuickMenuBarPrivate::getContentWidth() const { - Q_Q(QQuickMenuBar); - if (hasContentWidth && hasContentHeight) - return; - + Q_Q(const QQuickMenuBar); const int count = contentModel->count(); - if (count <= 0 || !contentItem) - return; - - qreal maxHeight = 0; qreal totalWidth = qMax(0, count - 1) * spacing; - for (int i = 0; i < count; ++i) { QQuickItem *item = q->itemAt(i); - if (item) { - totalWidth += item->width(); - maxHeight = qMax(maxHeight, item->implicitHeight()); - } - } - - bool contentWidthChange = false; - if (!hasContentWidth && !qFuzzyCompare(contentWidth, totalWidth)) { - contentWidth = totalWidth; - contentWidthChange = true; + if (item) + totalWidth += item->implicitWidth(); } + return totalWidth; +} - bool contentHeightChange = false; - if (!hasContentHeight && !qFuzzyCompare(contentHeight, maxHeight)) { - contentHeight = maxHeight; - contentHeightChange = true; +qreal QQuickMenuBarPrivate::getContentHeight() const +{ + Q_Q(const QQuickMenuBar); + const int count = contentModel->count(); + qreal maxHeight = 0; + for (int i = 0; i < count; ++i) { + QQuickItem *item = q->itemAt(i); + if (item) + maxHeight = qMax(maxHeight, item->implicitHeight()); } + return maxHeight; +} - if (contentWidthChange) - emit q->contentWidthChanged(); - if (contentHeightChange) - emit q->contentHeightChanged(); +void QQuickMenuBarPrivate::itemImplicitWidthChanged(QQuickItem *item) +{ + QQuickContainerPrivate::itemImplicitWidthChanged(item); + if (item != contentItem) + updateImplicitContentWidth(); } -void QQuickMenuBarPrivate::itemGeometryChanged(QQuickItem *, QQuickGeometryChange change, const QRectF &) +void QQuickMenuBarPrivate::itemImplicitHeightChanged(QQuickItem *item) { - if ((change.widthChange() && !hasContentWidth) || (change.heightChange() && !hasContentHeight)) - updateContentSize(); + QQuickContainerPrivate::itemImplicitHeightChanged(item); + if (item != contentItem) + updateImplicitContentHeight(); } void QQuickMenuBarPrivate::contentData_append(QQmlListProperty<QObject> *prop, QObject *obj) @@ -415,83 +406,30 @@ QQuickMenu *QQuickMenuBar::takeMenu(int index) } /*! + \since QtQuick.Controls 2.3 (Qt 5.10) \qmlproperty real QtQuick.Controls::MenuBar::contentWidth This property holds the content width. It is used for calculating the total implicit width of the menu bar. - Unless explicitly overridden, the content width is automatically calculated - based on the total implicit width of the items and the \l {Control::}{spacing} - of the menu bar. + \note This property is available in MenuBar since QtQuick.Controls 2.3 (Qt 5.10), + but it was promoted to the Container base type in QtQuick.Controls 2.5 (Qt 5.12). - \sa contentHeight + \sa Container::contentWidth */ -qreal QQuickMenuBar::contentWidth() const -{ - Q_D(const QQuickMenuBar); - return d->contentWidth; -} - -void QQuickMenuBar::setContentWidth(qreal width) -{ - Q_D(QQuickMenuBar); - d->hasContentWidth = true; - if (qFuzzyCompare(d->contentWidth, width)) - return; - - d->contentWidth = width; - emit contentWidthChanged(); -} - -void QQuickMenuBar::resetContentWidth() -{ - Q_D(QQuickMenuBar); - if (!d->hasContentWidth) - return; - - d->hasContentWidth = false; - if (isComponentComplete()) - d->updateContentSize(); -} /*! + \since QtQuick.Controls 2.3 (Qt 5.10) \qmlproperty real QtQuick.Controls::MenuBar::contentHeight This property holds the content height. It is used for calculating the total implicit height of the menu bar. - Unless explicitly overridden, the content height is automatically calculated - based on the maximum implicit height of the items. + \note This property is available in MenuBar since QtQuick.Controls 2.3 (Qt 5.10), + but it was promoted to the Container base type in QtQuick.Controls 2.5 (Qt 5.12). - \sa contentWidth + \sa Container::contentHeight */ -qreal QQuickMenuBar::contentHeight() const -{ - Q_D(const QQuickMenuBar); - return d->contentHeight; -} - -void QQuickMenuBar::setContentHeight(qreal height) -{ - Q_D(QQuickMenuBar); - d->hasContentHeight = true; - if (qFuzzyCompare(d->contentHeight, height)) - return; - - d->contentHeight = height; - emit contentHeightChanged(); -} - -void QQuickMenuBar::resetContentHeight() -{ - Q_D(QQuickMenuBar); - if (!d->hasContentHeight) - return; - - d->hasContentHeight = false; - if (isComponentComplete()) - d->updateContentSize(); -} /*! \qmlproperty list<Menu> QtQuick.Controls::MenuBar::menus @@ -502,38 +440,26 @@ void QQuickMenuBar::resetContentHeight() of the menu bar, and also menus that have been dynamically added or inserted using the \l addMenu() and \l insertMenu() methods, respectively. */ -QQmlListProperty<QQuickMenu> QQuickMenuBar::menus() +QQmlListProperty<QQuickMenu> QQuickMenuBarPrivate::menus() { - return QQmlListProperty<QQuickMenu>(this, nullptr, + Q_Q(QQuickMenuBar); + return QQmlListProperty<QQuickMenu>(q, nullptr, QQuickMenuBarPrivate::menus_append, QQuickMenuBarPrivate::menus_count, QQuickMenuBarPrivate::menus_at, QQuickMenuBarPrivate::menus_clear); } -QQmlListProperty<QObject> QQuickMenuBar::contentData() +QQmlListProperty<QObject> QQuickMenuBarPrivate::contentData() { - return QQmlListProperty<QObject>(this, nullptr, + Q_Q(QQuickMenuBar); + return QQmlListProperty<QObject>(q, nullptr, QQuickMenuBarPrivate::contentData_append, QQuickContainerPrivate::contentData_count, QQuickContainerPrivate::contentData_at, QQuickContainerPrivate::contentData_clear); } -void QQuickMenuBar::updatePolish() -{ - Q_D(QQuickMenuBar); - QQuickContainer::updatePolish(); - d->updateContentSize(); -} - -void QQuickMenuBar::componentComplete() -{ - Q_D(QQuickMenuBar); - QQuickContainer::componentComplete(); - d->updateContentSize(); -} - bool QQuickMenuBar::eventFilter(QObject *object, QEvent *event) { return QObject::eventFilter(object, event); @@ -614,10 +540,7 @@ void QQuickMenuBar::itemAdded(int index, QQuickItem *item) if (QQuickMenu *menu = menuBarItem->menu()) QObjectPrivate::connect(menu, &QQuickPopup::aboutToHide, d, &QQuickMenuBarPrivate::onMenuAboutToHide); } - if (isComponentComplete()) - polish(); - if (isComponentComplete()) - polish(); + d->updateImplicitContentSize(); emit menusChanged(); } @@ -638,17 +561,18 @@ void QQuickMenuBar::itemRemoved(int index, QQuickItem *item) if (QQuickMenu *menu = menuBarItem->menu()) QObjectPrivate::disconnect(menu, &QQuickPopup::aboutToHide, d, &QQuickMenuBarPrivate::onMenuAboutToHide); } + d->updateImplicitContentSize(); emit menusChanged(); } QFont QQuickMenuBar::defaultFont() const { - return QQuickControlPrivate::themeFont(QPlatformTheme::MenuBarFont); + return QQuickTheme::themeFont(QQuickTheme::MenuBar); } QPalette QQuickMenuBar::defaultPalette() const { - return QQuickControlPrivate::themePalette(QPlatformTheme::MenuBarPalette); + return QQuickTheme::themePalette(QQuickTheme::MenuBar); } #if QT_CONFIG(accessibility) @@ -659,3 +583,5 @@ QAccessible::Role QQuickMenuBar::accessibleRole() const #endif QT_END_NAMESPACE + +#include "moc_qquickmenubar_p.cpp" diff --git a/src/quicktemplates2/qquickmenubar_p.h b/src/quicktemplates2/qquickmenubar_p.h index 8c703f25..af37d0f2 100644 --- a/src/quicktemplates2/qquickmenubar_p.h +++ b/src/quicktemplates2/qquickmenubar_p.h @@ -59,10 +59,10 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickMenuBar : public QQuickContainer { Q_OBJECT Q_PROPERTY(QQmlComponent *delegate READ delegate WRITE setDelegate NOTIFY delegateChanged FINAL) - Q_PROPERTY(qreal contentWidth READ contentWidth WRITE setContentWidth RESET resetContentWidth NOTIFY contentWidthChanged FINAL) - Q_PROPERTY(qreal contentHeight READ contentHeight WRITE setContentHeight RESET resetContentHeight NOTIFY contentHeightChanged FINAL) - Q_PROPERTY(QQmlListProperty<QQuickMenu> menus READ menus NOTIFY menusChanged FINAL) - Q_PROPERTY(QQmlListProperty<QObject> contentData READ contentData FINAL) + Q_PROPERTY(qreal contentWidth READ contentWidth WRITE setContentWidth RESET resetContentWidth NOTIFY contentWidthChanged FINAL) // re-declare QQuickContainer::contentWidth (REV 5) + Q_PROPERTY(qreal contentHeight READ contentHeight WRITE setContentHeight RESET resetContentHeight NOTIFY contentHeightChanged FINAL) // re-declare QQuickContainer::contentHeight (REV 5) + Q_PRIVATE_PROPERTY(QQuickMenuBar::d_func(), QQmlListProperty<QQuickMenu> menus READ menus NOTIFY menusChanged FINAL) + Q_PRIVATE_PROPERTY(QQuickMenuBar::d_func(), QQmlListProperty<QObject> contentData READ contentData FINAL) public: explicit QQuickMenuBar(QQuickItem *parent = nullptr); @@ -76,27 +76,11 @@ public: Q_INVOKABLE void removeMenu(QQuickMenu *menu); Q_INVOKABLE QQuickMenu *takeMenu(int index); - qreal contentWidth() const; - void setContentWidth(qreal width); - void resetContentWidth(); - - qreal contentHeight() const; - void setContentHeight(qreal height); - void resetContentHeight(); - - QQmlListProperty<QQuickMenu> menus(); - QQmlListProperty<QObject> contentData(); - Q_SIGNALS: void delegateChanged(); - void contentWidthChanged(); - void contentHeightChanged(); void menusChanged(); protected: - void updatePolish() override; - void componentComplete() override; - bool eventFilter(QObject *object, QEvent *event) override; void keyPressEvent(QKeyEvent *event) override; void keyReleaseEvent(QKeyEvent *event) override; diff --git a/src/quicktemplates2/qquickmenubar_p_p.h b/src/quicktemplates2/qquickmenubar_p_p.h index 161806fb..e11580e2 100644 --- a/src/quicktemplates2/qquickmenubar_p_p.h +++ b/src/quicktemplates2/qquickmenubar_p_p.h @@ -68,6 +68,9 @@ public: return menuBar->d_func(); } + QQmlListProperty<QQuickMenu> menus(); + QQmlListProperty<QObject> contentData(); + QQuickItem *beginCreateItem(); void completeCreateItem(); @@ -82,8 +85,11 @@ public: void onItemTriggered(); void onMenuAboutToHide(); - void updateContentSize(); - void itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &diff) override; + qreal getContentWidth() const override; + qreal getContentHeight() const override; + + void itemImplicitWidthChanged(QQuickItem *item) override; + void itemImplicitHeightChanged(QQuickItem *item) override; static void contentData_append(QQmlListProperty<QObject> *prop, QObject *obj); @@ -94,10 +100,6 @@ public: bool popupMode; bool triggering; - bool hasContentWidth; - bool hasContentHeight; - qreal contentWidth; - qreal contentHeight; QQmlComponent *delegate; QPointer<QQuickMenuBarItem> currentItem; }; diff --git a/src/quicktemplates2/qquickmenubaritem.cpp b/src/quicktemplates2/qquickmenubaritem.cpp index cbf490b8..863e88e3 100644 --- a/src/quicktemplates2/qquickmenubaritem.cpp +++ b/src/quicktemplates2/qquickmenubaritem.cpp @@ -167,12 +167,12 @@ void QQuickMenuBarItem::geometryChanged(const QRectF &newGeometry, const QRectF QFont QQuickMenuBarItem::defaultFont() const { - return QQuickControlPrivate::themeFont(QPlatformTheme::MenuBarFont); + return QQuickTheme::themeFont(QQuickTheme::MenuBar); } QPalette QQuickMenuBarItem::defaultPalette() const { - return QQuickControlPrivate::themePalette(QPlatformTheme::MenuBarPalette); + return QQuickTheme::themePalette(QQuickTheme::MenuBar); } #if QT_CONFIG(accessibility) diff --git a/src/quicktemplates2/qquickmenuitem.cpp b/src/quicktemplates2/qquickmenuitem.cpp index 6693d4f8..ca74dd60 100644 --- a/src/quicktemplates2/qquickmenuitem.cpp +++ b/src/quicktemplates2/qquickmenuitem.cpp @@ -264,12 +264,12 @@ void QQuickMenuItem::componentComplete() QFont QQuickMenuItem::defaultFont() const { - return QQuickControlPrivate::themeFont(QPlatformTheme::MenuItemFont); + return QQuickTheme::themeFont(QQuickTheme::Menu); } QPalette QQuickMenuItem::defaultPalette() const { - return QQuickControlPrivate::themePalette(QPlatformTheme::MenuPalette); + return QQuickTheme::themePalette(QQuickTheme::Menu); } #if QT_CONFIG(accessibility) diff --git a/src/quicktemplates2/qquickmenuseparator.cpp b/src/quicktemplates2/qquickmenuseparator.cpp index dee5287a..1e7c58c6 100644 --- a/src/quicktemplates2/qquickmenuseparator.cpp +++ b/src/quicktemplates2/qquickmenuseparator.cpp @@ -71,9 +71,14 @@ QQuickMenuSeparator::QQuickMenuSeparator(QQuickItem *parent) { } +QFont QQuickMenuSeparator::defaultFont() const +{ + return QQuickTheme::themeFont(QQuickTheme::Menu); +} + QPalette QQuickMenuSeparator::defaultPalette() const { - return QQuickControlPrivate::themePalette(QPlatformTheme::MenuPalette); + return QQuickTheme::themePalette(QQuickTheme::Menu); } #if QT_CONFIG(accessibility) diff --git a/src/quicktemplates2/qquickmenuseparator_p.h b/src/quicktemplates2/qquickmenuseparator_p.h index 002b68ba..1e687fd0 100644 --- a/src/quicktemplates2/qquickmenuseparator_p.h +++ b/src/quicktemplates2/qquickmenuseparator_p.h @@ -60,6 +60,7 @@ public: explicit QQuickMenuSeparator(QQuickItem *parent = nullptr); protected: + QFont defaultFont() const override; QPalette defaultPalette() const override; #if QT_CONFIG(accessibility) diff --git a/src/quicktemplates2/qquickpage.cpp b/src/quicktemplates2/qquickpage.cpp index 8f34dca9..93196c4c 100644 --- a/src/quicktemplates2/qquickpage.cpp +++ b/src/quicktemplates2/qquickpage.cpp @@ -35,14 +35,16 @@ ****************************************************************************/ #include "qquickpage_p.h" -#include "qquickcontrol_p_p.h" -#include "qquickpagelayout_p_p.h" +#include "qquickpage_p_p.h" +#include "qquicktabbar_p.h" +#include "qquicktoolbar_p.h" +#include "qquickdialogbuttonbox_p.h" QT_BEGIN_NAMESPACE /*! \qmltype Page - \inherits Control + \inherits Pane \instantiates QQuickPage \inqmlmodule QtQuick.Controls \since 5.7 @@ -84,45 +86,142 @@ QT_BEGIN_NAMESPACE {Focus Management in Qt Quick Controls 2} */ -class QQuickPagePrivate : public QQuickControlPrivate +static const QQuickItemPrivate::ChangeTypes LayoutChanges = QQuickItemPrivate::Geometry | QQuickItemPrivate::Visibility | QQuickItemPrivate::Destroyed + | QQuickItemPrivate::ImplicitWidth | QQuickItemPrivate::ImplicitHeight; + +namespace { + enum Position { + Header, + Footer + }; + + Q_STATIC_ASSERT(int(Header) == int(QQuickTabBar::Header)); + Q_STATIC_ASSERT(int(Footer) == int(QQuickTabBar::Footer)); + + Q_STATIC_ASSERT(int(Header) == int(QQuickToolBar::Header)); + Q_STATIC_ASSERT(int(Footer) == int(QQuickToolBar::Footer)); + + Q_STATIC_ASSERT(int(Header) == int(QQuickDialogButtonBox::Header)); + Q_STATIC_ASSERT(int(Footer) == int(QQuickDialogButtonBox::Footer)); + + static void setPos(QQuickItem *item, Position position) + { + if (QQuickToolBar *toolBar = qobject_cast<QQuickToolBar *>(item)) + toolBar->setPosition(static_cast<QQuickToolBar::Position>(position)); + else if (QQuickTabBar *tabBar = qobject_cast<QQuickTabBar *>(item)) + tabBar->setPosition(static_cast<QQuickTabBar::Position>(position)); + else if (QQuickDialogButtonBox *buttonBox = qobject_cast<QQuickDialogButtonBox *>(item)) + buttonBox->setPosition(static_cast<QQuickDialogButtonBox::Position>(position)); + } +} + +void QQuickPagePrivate::relayout() { - Q_DECLARE_PUBLIC(QQuickPage) + Q_Q(QQuickPage); + const qreal hh = header && header->isVisible() ? header->height() : 0; + const qreal fh = footer && footer->isVisible() ? footer->height() : 0; + const qreal hsp = hh > 0 ? spacing : 0; + const qreal fsp = fh > 0 ? spacing : 0; + + if (contentItem) { + contentItem->setY(q->topPadding() + hh + hsp); + contentItem->setX(q->leftPadding()); + contentItem->setWidth(q->availableWidth()); + contentItem->setHeight(q->availableHeight() - hh - fh - hsp - fsp); + } -public: - QQuickPagePrivate(); + if (header) + header->setWidth(q->width()); - QQuickItem *getContentItem() override; + if (footer) { + footer->setY(q->height() - footer->height()); + footer->setWidth(q->width()); + } +} - qreal contentWidth; - qreal contentHeight; - QString title; - QScopedPointer<QQuickPageLayout> layout; -}; +void QQuickPagePrivate::resizeContent() +{ + relayout(); +} -QQuickPagePrivate::QQuickPagePrivate() - : contentWidth(0), - contentHeight(0) +void QQuickPagePrivate::itemVisibilityChanged(QQuickItem *item) { + Q_Q(QQuickPage); + QQuickPanePrivate::itemVisibilityChanged(item); + if (item == header) { + emit q->implicitHeaderWidthChanged(); + emit q->implicitHeaderHeightChanged(); + relayout(); + } else if (item == footer) { + emit q->implicitFooterWidthChanged(); + emit q->implicitFooterHeightChanged(); + relayout(); + } } -QQuickItem *QQuickPagePrivate::getContentItem() +void QQuickPagePrivate::itemImplicitWidthChanged(QQuickItem *item) { Q_Q(QQuickPage); - if (QQuickItem *item = QQuickControlPrivate::getContentItem()) - return item; - return new QQuickItem(q); + QQuickPanePrivate::itemImplicitWidthChanged(item); + if (item == header) + emit q->implicitHeaderWidthChanged(); + else if (item == footer) + emit q->implicitFooterWidthChanged(); +} + +void QQuickPagePrivate::itemImplicitHeightChanged(QQuickItem *item) +{ + Q_Q(QQuickPage); + QQuickPanePrivate::itemImplicitHeightChanged(item); + if (item == header) + emit q->implicitHeaderHeightChanged(); + else if (item == footer) + emit q->implicitFooterHeightChanged(); +} + +void QQuickPagePrivate::itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF & diff) +{ + QQuickPanePrivate::itemGeometryChanged(item, change, diff); + if (item == header || item == footer) + relayout(); +} + +void QQuickPagePrivate::itemDestroyed(QQuickItem *item) +{ + Q_Q(QQuickPage); + QQuickPanePrivate::itemDestroyed(item); + if (item == header) { + header = nullptr; + relayout(); + emit q->implicitHeaderWidthChanged(); + emit q->implicitHeaderHeightChanged(); + emit q->headerChanged(); + } else if (item == footer) { + footer = nullptr; + relayout(); + emit q->implicitFooterWidthChanged(); + emit q->implicitFooterHeightChanged(); + emit q->footerChanged(); + } } QQuickPage::QQuickPage(QQuickItem *parent) - : QQuickControl(*(new QQuickPagePrivate), parent) + : QQuickPane(*(new QQuickPagePrivate), parent) +{ +} + +QQuickPage::QQuickPage(QQuickPagePrivate &dd, QQuickItem *parent) + : QQuickPane(dd, parent) +{ +} + +QQuickPage::~QQuickPage() { Q_D(QQuickPage); - setFlag(ItemIsFocusScope); - setAcceptedMouseButtons(Qt::AllButtons); -#if QT_CONFIG(cursor) - setCursor(Qt::ArrowCursor); -#endif - d->layout.reset(new QQuickPageLayout(this)); + if (d->header) + QQuickItemPrivate::get(d->header)->removeItemChangeListener(d, LayoutChanges); + if (d->footer) + QQuickItemPrivate::get(d->footer)->removeItemChangeListener(d, LayoutChanges); } /*! @@ -193,16 +292,29 @@ void QQuickPage::setTitle(const QString &title) QQuickItem *QQuickPage::header() const { Q_D(const QQuickPage); - return d->layout->header(); + return d->header; } void QQuickPage::setHeader(QQuickItem *header) { Q_D(QQuickPage); - if (!d->layout->setHeader(header)) + if (d->header == header) return; + + if (d->header) { + QQuickItemPrivate::get(d->header)->removeItemChangeListener(d, LayoutChanges); + d->header->setParentItem(nullptr); + } + d->header = header; + if (header) { + header->setParentItem(this); + QQuickItemPrivate::get(header)->addItemChangeListener(d, LayoutChanges); + if (qFuzzyIsNull(header->z())) + header->setZ(1); + setPos(header, Header); + } if (isComponentComplete()) - d->layout->update(); + d->relayout(); emit headerChanged(); } @@ -221,150 +333,120 @@ void QQuickPage::setHeader(QQuickItem *header) QQuickItem *QQuickPage::footer() const { Q_D(const QQuickPage); - return d->layout->footer(); + return d->footer; } void QQuickPage::setFooter(QQuickItem *footer) { Q_D(QQuickPage); - if (!d->layout->setFooter(footer)) + if (d->footer == footer) return; + + if (d->footer) { + QQuickItemPrivate::get(d->footer)->removeItemChangeListener(d, LayoutChanges); + footer->setParentItem(nullptr); + } + d->footer = footer; + if (footer) { + footer->setParentItem(this); + QQuickItemPrivate::get(footer)->addItemChangeListener(d, LayoutChanges); + if (qFuzzyIsNull(footer->z())) + footer->setZ(1); + setPos(footer, Footer); + } if (isComponentComplete()) - d->layout->update(); + d->relayout(); emit footerChanged(); } /*! - \qmlproperty list<Object> QtQuick.Controls::Page::contentData - \default - - This property holds the list of content data. + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::Page::implicitHeaderWidth + \readonly - The list contains all objects that have been declared in QML as children - of the container. + This property holds the implicit header width. - \note Unlike \c contentChildren, \c contentData does include non-visual QML - objects. + The value is equal to \c {header && header.visible ? header.implicitWidth : 0}. - \sa Item::data, contentChildren + \sa implicitHeaderHeight, implicitFooterWidth */ -QQmlListProperty<QObject> QQuickPage::contentData() +qreal QQuickPage::implicitHeaderWidth() const { - return QQmlListProperty<QObject>(contentItem(), nullptr, - QQuickItemPrivate::data_append, - QQuickItemPrivate::data_count, - QQuickItemPrivate::data_at, - QQuickItemPrivate::data_clear); + Q_D(const QQuickPage); + if (!d->header || !d->header->isVisible()) + return 0; + return d->header->implicitWidth(); } /*! - \qmlproperty list<Item> QtQuick.Controls::Page::contentChildren - - This property holds the list of content children. + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::Page::implicitHeaderHeight + \readonly - The list contains all items that have been declared in QML as children - of the page. + This property holds the implicit header height. - \note Unlike \c contentData, \c contentChildren does not include non-visual - QML objects. + The value is equal to \c {header && header.visible ? header.implicitHeight : 0}. - \sa Item::children, contentData + \sa implicitHeaderWidth, implicitFooterHeight */ -QQmlListProperty<QQuickItem> QQuickPage::contentChildren() +qreal QQuickPage::implicitHeaderHeight() const { - return QQmlListProperty<QQuickItem>(contentItem(), nullptr, - QQuickItemPrivate::children_append, - QQuickItemPrivate::children_count, - QQuickItemPrivate::children_at, - QQuickItemPrivate::children_clear); + Q_D(const QQuickPage); + if (!d->header || !d->header->isVisible()) + return 0; + return d->header->implicitHeight(); } /*! - \qmlproperty real QtQuick.Controls::Page::contentWidth - \since QtQuick.Controls 2.1 (Qt 5.8) + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::Page::implicitFooterWidth + \readonly + + This property holds the implicit footer width. - This property holds the content width. It is used for calculating the total - implicit width of the page. + The value is equal to \c {footer && footer.visible ? footer.implicitWidth : 0}. - \sa contentHeight + \sa implicitFooterHeight, implicitHeaderWidth */ -qreal QQuickPage::contentWidth() const +qreal QQuickPage::implicitFooterWidth() const { Q_D(const QQuickPage); - return d->contentWidth; -} - -void QQuickPage::setContentWidth(qreal width) -{ - Q_D(QQuickPage); - if (qFuzzyCompare(d->contentWidth, width)) - return; - - d->contentWidth = width; - emit contentWidthChanged(); + if (!d->footer || !d->footer->isVisible()) + return 0; + return d->footer->implicitWidth(); } /*! - \qmlproperty real QtQuick.Controls::Page::contentHeight - \since QtQuick.Controls 2.1 (Qt 5.8) + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::Page::implicitFooterHeight + \readonly + + This property holds the implicit footer height. - This property holds the content height. It is used for calculating the total - implicit height of the page. + The value is equal to \c {footer && footer.visible ? footer.implicitHeight : 0}. - \sa contentWidth + \sa implicitFooterWidth, implicitHeaderHeight */ -qreal QQuickPage::contentHeight() const +qreal QQuickPage::implicitFooterHeight() const { Q_D(const QQuickPage); - return d->contentHeight; -} - -void QQuickPage::setContentHeight(qreal height) -{ - Q_D(QQuickPage); - if (qFuzzyCompare(d->contentHeight, height)) - return; - - d->contentHeight = height; - emit contentHeightChanged(); + if (!d->footer || !d->footer->isVisible()) + return 0; + return d->footer->implicitHeight(); } void QQuickPage::componentComplete() { Q_D(QQuickPage); - QQuickControl::componentComplete(); - d->layout->update(); -} - -void QQuickPage::contentItemChange(QQuickItem *newItem, QQuickItem *oldItem) -{ - QQuickControl::contentItemChange(newItem, oldItem); - if (oldItem) - disconnect(oldItem, &QQuickItem::childrenChanged, this, &QQuickPage::contentChildrenChanged); - if (newItem) - connect(newItem, &QQuickItem::childrenChanged, this, &QQuickPage::contentChildrenChanged); - emit contentChildrenChanged(); -} - -void QQuickPage::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) -{ - Q_D(QQuickPage); - QQuickControl::geometryChanged(newGeometry, oldGeometry); - d->layout->update(); -} - -void QQuickPage::paddingChange(const QMarginsF &newPadding, const QMarginsF &oldPadding) -{ - Q_D(QQuickPage); - QQuickControl::paddingChange(newPadding, oldPadding); - d->layout->update(); + QQuickPane::componentComplete(); + d->relayout(); } void QQuickPage::spacingChange(qreal newSpacing, qreal oldSpacing) { Q_D(QQuickPage); - QQuickControl::spacingChange(newSpacing, oldSpacing); - d->layout->update(); + QQuickPane::spacingChange(newSpacing, oldSpacing); + d->relayout(); } #if QT_CONFIG(accessibility) @@ -376,7 +458,7 @@ QAccessible::Role QQuickPage::accessibleRole() const void QQuickPage::accessibilityActiveChanged(bool active) { Q_D(QQuickPage); - QQuickControl::accessibilityActiveChanged(active); + QQuickPane::accessibilityActiveChanged(active); if (active) setAccessibleName(d->title); diff --git a/src/quicktemplates2/qquickpage_p.h b/src/quicktemplates2/qquickpage_p.h index 0789e996..b7888ad6 100644 --- a/src/quicktemplates2/qquickpage_p.h +++ b/src/quicktemplates2/qquickpage_p.h @@ -48,28 +48,31 @@ // We mean it. // -#include <QtQuickTemplates2/private/qquickcontrol_p.h> +#include <QtQuickTemplates2/private/qquickpane_p.h> #include <QtQml/qqmllist.h> QT_BEGIN_NAMESPACE class QQuickPagePrivate; -class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickPage : public QQuickControl +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickPage : public QQuickPane { Q_OBJECT Q_PROPERTY(QString title READ title WRITE setTitle NOTIFY titleChanged FINAL) Q_PROPERTY(QQuickItem *header READ header WRITE setHeader NOTIFY headerChanged FINAL) Q_PROPERTY(QQuickItem *footer READ footer WRITE setFooter NOTIFY footerChanged FINAL) - Q_PROPERTY(QQmlListProperty<QObject> contentData READ contentData FINAL) - Q_PROPERTY(QQmlListProperty<QQuickItem> contentChildren READ contentChildren NOTIFY contentChildrenChanged FINAL) // 2.1 (Qt 5.8) Q_PROPERTY(qreal contentWidth READ contentWidth WRITE setContentWidth NOTIFY contentWidthChanged FINAL REVISION 1) Q_PROPERTY(qreal contentHeight READ contentHeight WRITE setContentHeight NOTIFY contentHeightChanged FINAL REVISION 1) - Q_CLASSINFO("DefaultProperty", "contentData") + // 2.5 (Qt 5.12) + Q_PROPERTY(qreal implicitHeaderWidth READ implicitHeaderWidth NOTIFY implicitHeaderWidthChanged FINAL REVISION 5) + Q_PROPERTY(qreal implicitHeaderHeight READ implicitHeaderHeight NOTIFY implicitHeaderHeightChanged FINAL REVISION 5) + Q_PROPERTY(qreal implicitFooterWidth READ implicitFooterWidth NOTIFY implicitFooterWidthChanged FINAL REVISION 5) + Q_PROPERTY(qreal implicitFooterHeight READ implicitFooterHeight NOTIFY implicitFooterHeightChanged FINAL REVISION 5) public: explicit QQuickPage(QQuickItem *parent = nullptr); + ~QQuickPage(); QString title() const; void setTitle(const QString &title); @@ -80,31 +83,28 @@ public: QQuickItem *footer() const; void setFooter(QQuickItem *footer); - QQmlListProperty<QObject> contentData(); - QQmlListProperty<QQuickItem> contentChildren(); + // 2.5 (Qt 5.12) + qreal implicitHeaderWidth() const; + qreal implicitHeaderHeight() const; - // 2.1 (Qt 5.8) - qreal contentWidth() const; - void setContentWidth(qreal width); - - qreal contentHeight() const; - void setContentHeight(qreal height); + qreal implicitFooterWidth() const; + qreal implicitFooterHeight() const; Q_SIGNALS: void titleChanged(); void headerChanged(); void footerChanged(); - void contentChildrenChanged(); - // 2.1 (Qt 5.8) - Q_REVISION(1) void contentWidthChanged(); - Q_REVISION(1) void contentHeightChanged(); + // 2.5 (Qt 5.12) + void implicitHeaderWidthChanged(); + void implicitHeaderHeightChanged(); + void implicitFooterWidthChanged(); + void implicitFooterHeightChanged(); protected: + QQuickPage(QQuickPagePrivate &dd, QQuickItem *parent); + void componentComplete() override; - void contentItemChange(QQuickItem *newItem, QQuickItem *oldItem) override; - void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) override; - void paddingChange(const QMarginsF &newPadding, const QMarginsF &oldPadding) override; void spacingChange(qreal newSpacing, qreal oldSpacing) override; #if QT_CONFIG(accessibility) diff --git a/src/quicktemplates2/qquickpagelayout_p_p.h b/src/quicktemplates2/qquickpage_p_p.h index aac52ca3..b7d89ac4 100644 --- a/src/quicktemplates2/qquickpagelayout_p_p.h +++ b/src/quicktemplates2/qquickpage_p_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2018 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** ** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. @@ -34,8 +34,8 @@ ** ****************************************************************************/ -#ifndef QQUICKPAGELAYOUT_P_P_H -#define QQUICKPAGELAYOUT_P_P_H +#ifndef QQUICKPAGE_P_P_H +#define QQUICKPAGE_P_P_H // // W A R N I N G @@ -48,39 +48,31 @@ // We mean it. // -#include <QtQuick/private/qquickitemchangelistener_p.h> +#include <QtQuickTemplates2/private/qquickpane_p_p.h> QT_BEGIN_NAMESPACE -class QQuickControl; +class QQuickPane; -class QQuickPageLayout : public QQuickItemChangeListener +class QQuickPagePrivate : public QQuickPanePrivate { -public: - explicit QQuickPageLayout(QQuickControl *control); - ~QQuickPageLayout(); - - QQuickItem *header() const; - bool setHeader(QQuickItem *header); + Q_DECLARE_PUBLIC(QQuickPage) - QQuickItem *footer() const; - bool setFooter(QQuickItem *footer); - - void update(); +public: + void relayout(); + void resizeContent() override; -protected: void itemVisibilityChanged(QQuickItem *item) override; void itemImplicitWidthChanged(QQuickItem *item) override; void itemImplicitHeightChanged(QQuickItem *item) override; - void itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &diff) override; + void itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF & diff) override; void itemDestroyed(QQuickItem *item) override; -private: - QQuickItem *m_header; - QQuickItem *m_footer; - QQuickControl *m_control; + QString title; + QQuickItem *header = nullptr; + QQuickItem *footer = nullptr; }; QT_END_NAMESPACE -#endif // QQUICKPAGELAYOUT_P_P_H +#endif // QQUICKPAGE_P_P_H diff --git a/src/quicktemplates2/qquickpageindicator.cpp b/src/quicktemplates2/qquickpageindicator.cpp index df720c91..c5c42dfb 100644 --- a/src/quicktemplates2/qquickpageindicator.cpp +++ b/src/quicktemplates2/qquickpageindicator.cpp @@ -39,7 +39,6 @@ #include <QtCore/qmath.h> #include <QtQuick/private/qquickitem_p.h> -#include <QtQuick/private/qquickitemchangelistener_p.h> QT_BEGIN_NAMESPACE @@ -84,7 +83,7 @@ QT_BEGIN_NAMESPACE \sa SwipeView, {Customizing PageIndicator}, {Indicator Controls} */ -class QQuickPageIndicatorPrivate : public QQuickControlPrivate, public QQuickItemChangeListener +class QQuickPageIndicatorPrivate : public QQuickControlPrivate { Q_DECLARE_PUBLIC(QQuickPageIndicator) diff --git a/src/quicktemplates2/qquickpagelayout.cpp b/src/quicktemplates2/qquickpagelayout.cpp deleted file mode 100644 index 595db560..00000000 --- a/src/quicktemplates2/qquickpagelayout.cpp +++ /dev/null @@ -1,195 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL3$ -** 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 http://www.qt.io/terms-conditions. For further -** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free -** Software Foundation and appearing in the file LICENSE.GPL included in -** the packaging of this file. Please review the following information to -** ensure the GNU General Public License version 2.0 requirements will be -** met: http://www.gnu.org/licenses/gpl-2.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qquickpagelayout_p_p.h" -#include "qquickcontrol_p.h" -#include "qquickcontrol_p_p.h" -#include "qquicktoolbar_p.h" -#include "qquicktabbar_p.h" -#include "qquickdialogbuttonbox_p.h" - -#include <QtQuick/private/qquickitem_p.h> - -QT_BEGIN_NAMESPACE - -static const QQuickItemPrivate::ChangeTypes ItemChanges = QQuickItemPrivate::Geometry | QQuickItemPrivate::Visibility | QQuickItemPrivate::Destroyed - | QQuickItemPrivate::ImplicitWidth | QQuickItemPrivate::ImplicitHeight; - -namespace { - enum Position { - Header, - Footer - }; - - Q_STATIC_ASSERT(int(Header) == int(QQuickTabBar::Header)); - Q_STATIC_ASSERT(int(Footer) == int(QQuickTabBar::Footer)); - - Q_STATIC_ASSERT(int(Header) == int(QQuickToolBar::Header)); - Q_STATIC_ASSERT(int(Footer) == int(QQuickToolBar::Footer)); - - Q_STATIC_ASSERT(int(Header) == int(QQuickDialogButtonBox::Header)); - Q_STATIC_ASSERT(int(Footer) == int(QQuickDialogButtonBox::Footer)); -} - -static void setPosition(QQuickItem *item, Position position) -{ - if (QQuickToolBar *toolBar = qobject_cast<QQuickToolBar *>(item)) - toolBar->setPosition(static_cast<QQuickToolBar::Position>(position)); - else if (QQuickTabBar *tabBar = qobject_cast<QQuickTabBar *>(item)) - tabBar->setPosition(static_cast<QQuickTabBar::Position>(position)); - else if (QQuickDialogButtonBox *buttonBox = qobject_cast<QQuickDialogButtonBox *>(item)) - buttonBox->setPosition(static_cast<QQuickDialogButtonBox::Position>(position)); -} - -QQuickPageLayout::QQuickPageLayout(QQuickControl *control) - : m_header(nullptr), - m_footer(nullptr), - m_control(control) -{ -} - -QQuickPageLayout::~QQuickPageLayout() -{ - if (m_header) - QQuickItemPrivate::get(m_header)->removeItemChangeListener(this, ItemChanges); - if (m_footer) - QQuickItemPrivate::get(m_footer)->removeItemChangeListener(this, ItemChanges); -} - -QQuickItem *QQuickPageLayout::header() const -{ - return m_header; -} - -bool QQuickPageLayout::setHeader(QQuickItem *header) -{ - if (m_header == header) - return false; - - if (m_header) { - QQuickItemPrivate::get(m_header)->removeItemChangeListener(this, ItemChanges); - m_header->setParentItem(nullptr); - } - m_header = header; - if (header) { - header->setParentItem(m_control); - QQuickItemPrivate::get(header)->addItemChangeListener(this, ItemChanges); - if (qFuzzyIsNull(header->z())) - header->setZ(1); - setPosition(header, Header); - } - return true; -} - -QQuickItem *QQuickPageLayout::footer() const -{ - return m_footer; -} - -bool QQuickPageLayout::setFooter(QQuickItem *footer) -{ - if (m_footer == footer) - return false; - - if (m_footer) { - QQuickItemPrivate::get(m_footer)->removeItemChangeListener(this, ItemChanges); - m_footer->setParentItem(nullptr); - } - m_footer = footer; - if (footer) { - footer->setParentItem(m_control); - QQuickItemPrivate::get(footer)->addItemChangeListener(this, ItemChanges); - if (qFuzzyIsNull(footer->z())) - footer->setZ(1); - setPosition(footer, Footer); - } - return true; -} - -void QQuickPageLayout::update() -{ - QQuickItem *content = QQuickControlPrivate::get(m_control)->contentItem; - - const qreal hh = m_header && m_header->isVisible() ? m_header->height() : 0; - const qreal fh = m_footer && m_footer->isVisible() ? m_footer->height() : 0; - const qreal hsp = hh > 0 ? m_control->spacing() : 0; - const qreal fsp = fh > 0 ? m_control->spacing() : 0; - - if (content) { - content->setY(m_control->topPadding() + hh + hsp); - content->setX(m_control->leftPadding()); - content->setWidth(m_control->availableWidth()); - content->setHeight(m_control->availableHeight() - hh - fh - hsp - fsp); - } - - if (m_header) - m_header->setWidth(m_control->width()); - - if (m_footer) { - m_footer->setY(m_control->height() - m_footer->height()); - m_footer->setWidth(m_control->width()); - } -} - -void QQuickPageLayout::itemVisibilityChanged(QQuickItem *) -{ - update(); -} - -void QQuickPageLayout::itemImplicitWidthChanged(QQuickItem *) -{ - update(); -} - -void QQuickPageLayout::itemImplicitHeightChanged(QQuickItem *) -{ - update(); -} - -void QQuickPageLayout::itemGeometryChanged(QQuickItem *, QQuickGeometryChange, const QRectF &) -{ - update(); -} - -void QQuickPageLayout::itemDestroyed(QQuickItem *item) -{ - if (item == m_header) - m_header = nullptr; - else if (item == m_footer) - m_footer = nullptr; -} - -QT_END_NAMESPACE diff --git a/src/quicktemplates2/qquickpane.cpp b/src/quicktemplates2/qquickpane.cpp index 8038f1b1..72a5ee17 100644 --- a/src/quicktemplates2/qquickpane.cpp +++ b/src/quicktemplates2/qquickpane.cpp @@ -36,6 +36,7 @@ #include "qquickpane_p.h" #include "qquickpane_p_p.h" +#include "qquickcontentitem_p.h" QT_BEGIN_NAMESPACE @@ -107,37 +108,150 @@ QT_BEGIN_NAMESPACE */ QQuickPanePrivate::QQuickPanePrivate() - : contentWidth(0), - contentHeight(0) + : hasContentWidth(false), + hasContentHeight(false), + contentWidth(0), + contentHeight(0), + firstChild(nullptr) { } +void QQuickPanePrivate::init() +{ + Q_Q(QQuickPane); + q->setFlag(QQuickItem::ItemIsFocusScope); + q->setAcceptedMouseButtons(Qt::AllButtons); +#if QT_CONFIG(cursor) + q->setCursor(Qt::ArrowCursor); +#endif + connect(q, &QQuickControl::implicitContentWidthChanged, this, &QQuickPanePrivate::updateContentWidth); + connect(q, &QQuickControl::implicitContentHeightChanged, this, &QQuickPanePrivate::updateContentHeight); +} + +QList<QQuickItem *> QQuickPanePrivate::contentChildItems() const +{ + if (!contentItem) + return QList<QQuickItem *>(); + + return contentItem->childItems(); +} + QQuickItem *QQuickPanePrivate::getContentItem() { Q_Q(QQuickPane); if (QQuickItem *item = QQuickControlPrivate::getContentItem()) return item; - return new QQuickItem(q); + + return new QQuickContentItem(q); +} + +void QQuickPanePrivate::itemImplicitWidthChanged(QQuickItem *item) +{ + QQuickControlPrivate::itemImplicitWidthChanged(item); + + if (item == firstChild) + updateImplicitContentWidth(); +} + +void QQuickPanePrivate::itemImplicitHeightChanged(QQuickItem *item) +{ + QQuickControlPrivate::itemImplicitHeightChanged(item); + + if (item == firstChild) + updateImplicitContentHeight(); +} + +void QQuickPanePrivate::contentChildrenChange() +{ + Q_Q(QQuickPane); + QQuickItem *newFirstChild = contentChildItems().value(0); + if (newFirstChild != firstChild) { + if (firstChild) + removeImplicitSizeListener(firstChild); + if (newFirstChild) + addImplicitSizeListener(newFirstChild); + firstChild = newFirstChild; + } + + updateImplicitContentSize(); + emit q->contentChildrenChanged(); +} + +qreal QQuickPanePrivate::getContentWidth() const +{ + if (!contentItem) + return 0; + + const qreal cw = contentItem->implicitWidth(); + if (!qFuzzyIsNull(cw)) + return cw; + + const auto contentChildren = contentChildItems(); + if (contentChildren.count() == 1) + return contentChildren.first()->implicitWidth(); + + return 0; +} + +qreal QQuickPanePrivate::getContentHeight() const +{ + if (!contentItem) + return 0; + + const qreal ch = contentItem->implicitHeight(); + if (!qFuzzyIsNull(ch)) + return ch; + + const auto contentChildren = contentChildItems(); + if (contentChildren.count() == 1) + return contentChildren.first()->implicitHeight(); + + return 0; +} + +void QQuickPanePrivate::updateContentWidth() +{ + Q_Q(QQuickPane); + if (hasContentWidth || qFuzzyCompare(contentWidth, implicitContentWidth)) + return; + + const qreal oldContentWidth = contentWidth; + contentWidth = implicitContentWidth; + q->contentSizeChange(QSizeF(contentWidth, contentHeight), QSizeF(oldContentWidth, contentHeight)); + emit q->contentWidthChanged(); +} + +void QQuickPanePrivate::updateContentHeight() +{ + Q_Q(QQuickPane); + if (hasContentHeight || qFuzzyCompare(contentHeight, implicitContentHeight)) + return; + + const qreal oldContentHeight = contentHeight; + contentHeight = implicitContentHeight; + q->contentSizeChange(QSizeF(contentWidth, contentHeight), QSizeF(contentWidth, oldContentHeight)); + emit q->contentHeightChanged(); } QQuickPane::QQuickPane(QQuickItem *parent) : QQuickControl(*(new QQuickPanePrivate), parent) { - setFlag(QQuickItem::ItemIsFocusScope); - setAcceptedMouseButtons(Qt::AllButtons); -#if QT_CONFIG(cursor) - setCursor(Qt::ArrowCursor); -#endif + Q_D(QQuickPane); + d->init(); +} + +QQuickPane::~QQuickPane() +{ + Q_D(QQuickPane); + d->removeImplicitSizeListener(d->contentItem); + d->removeImplicitSizeListener(d->firstChild); } QQuickPane::QQuickPane(QQuickPanePrivate &dd, QQuickItem *parent) : QQuickControl(dd, parent) { - setFlag(QQuickItem::ItemIsFocusScope); - setAcceptedMouseButtons(Qt::AllButtons); -#if QT_CONFIG(cursor) - setCursor(Qt::ArrowCursor); -#endif + Q_D(QQuickPane); + d->init(); } /*! @@ -159,13 +273,26 @@ qreal QQuickPane::contentWidth() const void QQuickPane::setContentWidth(qreal width) { Q_D(QQuickPane); + d->hasContentWidth = true; if (qFuzzyCompare(d->contentWidth, width)) return; + const qreal oldWidth = d->contentWidth; d->contentWidth = width; + contentSizeChange(QSizeF(width, d->contentHeight), QSizeF(oldWidth, d->contentHeight)); emit contentWidthChanged(); } +void QQuickPane::resetContentWidth() +{ + Q_D(QQuickPane); + if (!d->hasContentWidth) + return; + + d->hasContentHeight = false; + d->updateContentWidth(); +} + /*! \qmlproperty real QtQuick.Controls::Pane::contentHeight @@ -185,13 +312,26 @@ qreal QQuickPane::contentHeight() const void QQuickPane::setContentHeight(qreal height) { Q_D(QQuickPane); + d->hasContentHeight = true; if (qFuzzyCompare(d->contentHeight, height)) return; + const qreal oldHeight = d->contentHeight; d->contentHeight = height; + contentSizeChange(QSizeF(d->contentWidth, height), QSizeF(d->contentWidth, oldHeight)); emit contentHeightChanged(); } +void QQuickPane::resetContentHeight() +{ + Q_D(QQuickPane); + if (!d->hasContentHeight) + return; + + d->hasContentHeight = false; + d->updateContentHeight(); +} + /*! \qmlproperty list<Object> QtQuick.Controls::Pane::contentData \default @@ -206,9 +346,10 @@ void QQuickPane::setContentHeight(qreal height) \sa Item::data, contentChildren */ -QQmlListProperty<QObject> QQuickPane::contentData() +QQmlListProperty<QObject> QQuickPanePrivate::contentData() { - return QQmlListProperty<QObject>(contentItem(), nullptr, + Q_Q(QQuickPane); + return QQmlListProperty<QObject>(q->contentItem(), nullptr, QQuickItemPrivate::data_append, QQuickItemPrivate::data_count, QQuickItemPrivate::data_at, @@ -228,23 +369,42 @@ QQmlListProperty<QObject> QQuickPane::contentData() \sa Item::children, contentData */ -QQmlListProperty<QQuickItem> QQuickPane::contentChildren() +QQmlListProperty<QQuickItem> QQuickPanePrivate::contentChildren() { - return QQmlListProperty<QQuickItem>(contentItem(), nullptr, + Q_Q(QQuickPane); + return QQmlListProperty<QQuickItem>(q->contentItem(), nullptr, QQuickItemPrivate::children_append, QQuickItemPrivate::children_count, QQuickItemPrivate::children_at, QQuickItemPrivate::children_clear); } +void QQuickPane::componentComplete() +{ + Q_D(QQuickPane); + QQuickControl::componentComplete(); + d->updateImplicitContentSize(); +} + void QQuickPane::contentItemChange(QQuickItem *newItem, QQuickItem *oldItem) { + Q_D(QQuickPane); QQuickControl::contentItemChange(newItem, oldItem); - if (oldItem) - disconnect(oldItem, &QQuickItem::childrenChanged, this, &QQuickPane::contentChildrenChanged); - if (newItem) - connect(newItem, &QQuickItem::childrenChanged, this, &QQuickPane::contentChildrenChanged); - emit contentChildrenChanged(); + if (oldItem) { + d->removeImplicitSizeListener(oldItem); + QObjectPrivate::disconnect(oldItem, &QQuickItem::childrenChanged, d, &QQuickPanePrivate::contentChildrenChange); + } + if (newItem) { + d->addImplicitSizeListener(newItem); + QObjectPrivate::connect(newItem, &QQuickItem::childrenChanged, d, &QQuickPanePrivate::contentChildrenChange); + } + d->contentChildrenChange(); +} + +void QQuickPane::contentSizeChange(const QSizeF &newSize, const QSizeF &oldSize) +{ + Q_UNUSED(newSize) + Q_UNUSED(oldSize) } #if QT_CONFIG(accessibility) @@ -255,3 +415,5 @@ QAccessible::Role QQuickPane::accessibleRole() const #endif QT_END_NAMESPACE + +#include "moc_qquickpane_p.cpp" diff --git a/src/quicktemplates2/qquickpane_p.h b/src/quicktemplates2/qquickpane_p.h index 759c59d8..86b2c9f2 100644 --- a/src/quicktemplates2/qquickpane_p.h +++ b/src/quicktemplates2/qquickpane_p.h @@ -58,23 +58,23 @@ class QQuickPanePrivate; class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickPane : public QQuickControl { Q_OBJECT - Q_PROPERTY(qreal contentWidth READ contentWidth WRITE setContentWidth NOTIFY contentWidthChanged FINAL) - Q_PROPERTY(qreal contentHeight READ contentHeight WRITE setContentHeight NOTIFY contentHeightChanged FINAL) - Q_PROPERTY(QQmlListProperty<QObject> contentData READ contentData FINAL) - Q_PROPERTY(QQmlListProperty<QQuickItem> contentChildren READ contentChildren NOTIFY contentChildrenChanged FINAL) + Q_PROPERTY(qreal contentWidth READ contentWidth WRITE setContentWidth RESET resetContentWidth NOTIFY contentWidthChanged FINAL) + Q_PROPERTY(qreal contentHeight READ contentHeight WRITE setContentHeight RESET resetContentHeight NOTIFY contentHeightChanged FINAL) + Q_PRIVATE_PROPERTY(QQuickPane::d_func(), QQmlListProperty<QObject> contentData READ contentData FINAL) + Q_PRIVATE_PROPERTY(QQuickPane::d_func(), QQmlListProperty<QQuickItem> contentChildren READ contentChildren NOTIFY contentChildrenChanged FINAL) Q_CLASSINFO("DefaultProperty", "contentData") public: explicit QQuickPane(QQuickItem *parent = nullptr); + ~QQuickPane(); qreal contentWidth() const; void setContentWidth(qreal width); + void resetContentWidth(); qreal contentHeight() const; void setContentHeight(qreal height); - - QQmlListProperty<QObject> contentData(); - QQmlListProperty<QQuickItem> contentChildren(); + void resetContentHeight(); Q_SIGNALS: void contentWidthChanged(); @@ -84,7 +84,10 @@ Q_SIGNALS: protected: QQuickPane(QQuickPanePrivate &dd, QQuickItem *parent); + void componentComplete() override; + void contentItemChange(QQuickItem *newItem, QQuickItem *oldItem) override; + virtual void contentSizeChange(const QSizeF &newSize, const QSizeF &oldSize); #if QT_CONFIG(accessibility) QAccessible::Role accessibleRole() const override; diff --git a/src/quicktemplates2/qquickpane_p_p.h b/src/quicktemplates2/qquickpane_p_p.h index 16a07f08..808b33c6 100644 --- a/src/quicktemplates2/qquickpane_p_p.h +++ b/src/quicktemplates2/qquickpane_p_p.h @@ -61,10 +61,30 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickPanePrivate : public QQuickControlP public: QQuickPanePrivate(); + void init(); + + virtual QQmlListProperty<QObject> contentData(); + virtual QQmlListProperty<QQuickItem> contentChildren(); + virtual QList<QQuickItem *> contentChildItems() const; + QQuickItem *getContentItem() override; + qreal getContentWidth() const override; + qreal getContentHeight() const override; + + void itemImplicitWidthChanged(QQuickItem *item) override; + void itemImplicitHeightChanged(QQuickItem *item) override; + + void contentChildrenChange(); + + void updateContentWidth(); + void updateContentHeight(); + + bool hasContentWidth; + bool hasContentHeight; qreal contentWidth; qreal contentHeight; + QQuickItem *firstChild; }; QT_END_NAMESPACE diff --git a/src/quicktemplates2/qquickpopup.cpp b/src/quicktemplates2/qquickpopup.cpp index e3ab952d..08b3ee63 100644 --- a/src/quicktemplates2/qquickpopup.cpp +++ b/src/quicktemplates2/qquickpopup.cpp @@ -36,6 +36,7 @@ #include "qquickpopup_p.h" #include "qquickpopup_p_p.h" +#include "qquickpopupanchors_p.h" #include "qquickpopupitem_p_p.h" #include "qquickpopuppositioner_p_p.h" #include "qquickapplicationwindow_p.h" @@ -109,14 +110,42 @@ QT_BEGIN_NAMESPACE \image qtquickcontrols2-popup.png The \l implicitWidth and \l implicitHeight of a popup are typically based - on the implicit sizes of the background and the content item plus any - \l padding. These properties determine how large the popup will be when no + on the implicit sizes of the background and the content item plus any insets + and paddings. These properties determine how large the popup will be when no explicit \l width or \l height is specified. + The geometry of the \l contentItem is determined by the padding. The following + example reserves 10px padding between the boundaries of the popup and its content: + + \code + Popup { + padding: 10 + + contentItem: Text { + text: "Content" + } + } + \endcode + The \l background item fills the entire width and height of the popup, - unless an explicit size has been given for it. + unless insets or an explicit size have been given for it. + + Negative insets can be used to make the background larger than the popup. + The following example uses negative insets to place a shadow outside the + popup's boundaries: + + \code + Popup { + topInset: -2 + leftInset: -2 + rightInset: -6 + bottomInset: -6 - The geometry of the \l contentItem is determined by the \l padding. + background: BorderImage { + source: ":/images/shadowed-background.png" + } + } + \endcode \section1 Popup Sizing @@ -178,6 +207,11 @@ QT_BEGIN_NAMESPACE \include qquickoverlay-popup-parent.qdocinc + Another way to center a popup in the window regardless of its parent item + is to use \l {anchors.centerIn}: + + \snippet qtquickcontrols2-popup.qml centerIn + \sa {Popup Controls}, {Customizing Popup}, ApplicationWindow */ @@ -248,8 +282,6 @@ QQuickPopupPrivate::QQuickPopupPrivate() leftMargin(0), rightMargin(0), bottomMargin(0), - contentWidth(0), - contentHeight(0), transitionState(QQuickPopupPrivate::NoTransition), closePolicy(DefaultClosePolicy), parentItem(nullptr), @@ -259,7 +291,8 @@ QQuickPopupPrivate::QQuickPopupPrivate() exit(nullptr), popupItem(nullptr), positioner(nullptr), - transitionManager(this) + transitionManager(this), + anchors(nullptr) { } @@ -277,6 +310,10 @@ void QQuickPopupPrivate::init() QObject::connect(popupItem, &QQuickControl::paddingChanged, q, &QQuickPopup::paddingChanged); QObject::connect(popupItem, &QQuickControl::backgroundChanged, q, &QQuickPopup::backgroundChanged); QObject::connect(popupItem, &QQuickControl::contentItemChanged, q, &QQuickPopup::contentItemChanged); + QObject::connect(popupItem, &QQuickControl::implicitContentWidthChanged, q, &QQuickPopup::implicitContentWidthChanged); + QObject::connect(popupItem, &QQuickControl::implicitContentHeightChanged, q, &QQuickPopup::implicitContentHeightChanged); + QObject::connect(popupItem, &QQuickControl::implicitBackgroundWidthChanged, q, &QQuickPopup::implicitBackgroundWidthChanged); + QObject::connect(popupItem, &QQuickControl::implicitBackgroundHeightChanged, q, &QQuickPopup::implicitBackgroundHeightChanged); positioner = new QQuickPopupPositioner(q); } @@ -572,6 +609,48 @@ void QQuickPopupPrivate::setBottomMargin(qreal value, bool reset) } } +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlpropertygroup QtQuick.Controls::Popup::anchors + \qmlproperty Object QtQuick.Controls::Popup::anchors.centerIn + + Anchors provide a way to position an item by specifying its + relationship with other items. + + A common use case is to center a popup within its parent. One way to do + this is with the \l {Item::}{x} and \l {Item::}{y} properties. Anchors offer + a more convenient approach: + + \qml + Pane { + // ... + + Popup { + anchors.centerIn: parent + } + } + \endqml + + It is also possible to center the popup in the window by using \l Overlay: + + \snippet qtquickcontrols2-popup.qml centerIn + + This makes it easy to center a popup in the window from any component. + + \note Popups can only be centered within their immediate parent or + the window overlay; trying to center in other items will produce a warning. + + \sa {Popup Positioning}, {Item::anchors} +*/ +QQuickPopupAnchors *QQuickPopupPrivate::getAnchors() +{ + if (!anchors) { + Q_Q(QQuickPopup); + anchors = new QQuickPopupAnchors(positioner, q); + } + return anchors; +} + void QQuickPopupPrivate::setWindow(QQuickWindow *newWindow) { Q_Q(QQuickPopup); @@ -1000,17 +1079,13 @@ void QQuickPopup::setImplicitHeight(qreal height) qreal QQuickPopup::contentWidth() const { Q_D(const QQuickPopup); - return d->contentWidth; + return d->popupItem->contentWidth(); } void QQuickPopup::setContentWidth(qreal width) { Q_D(QQuickPopup); - if (qFuzzyCompare(d->contentWidth, width)) - return; - - d->contentWidth = width; - emit contentWidthChanged(); + d->popupItem->setContentWidth(width); } /*! @@ -1026,17 +1101,13 @@ void QQuickPopup::setContentWidth(qreal width) qreal QQuickPopup::contentHeight() const { Q_D(const QQuickPopup); - return d->contentHeight; + return d->popupItem->contentHeight(); } void QQuickPopup::setContentHeight(qreal height) { Q_D(QQuickPopup); - if (qFuzzyCompare(d->contentHeight, height)) - return; - - d->contentHeight = height; - emit contentHeightChanged(); + d->popupItem->setContentHeight(height); } /*! @@ -1294,11 +1365,12 @@ void QQuickPopup::resetPadding() /*! \qmlproperty real QtQuick.Controls::Popup::topPadding - This property holds the top padding. + This property holds the top padding. Unless explicitly set, the value + is equal to \c verticalPadding. \include qquickpopup-padding.qdocinc - \sa padding, bottomPadding, availableHeight + \sa padding, bottomPadding, verticalPadding, availableHeight */ qreal QQuickPopup::topPadding() const { @@ -1321,11 +1393,12 @@ void QQuickPopup::resetTopPadding() /*! \qmlproperty real QtQuick.Controls::Popup::leftPadding - This property holds the left padding. + This property holds the left padding. Unless explicitly set, the value + is equal to \c horizontalPadding. \include qquickpopup-padding.qdocinc - \sa padding, rightPadding, availableWidth + \sa padding, rightPadding, horizontalPadding, availableWidth */ qreal QQuickPopup::leftPadding() const { @@ -1348,11 +1421,12 @@ void QQuickPopup::resetLeftPadding() /*! \qmlproperty real QtQuick.Controls::Popup::rightPadding - This property holds the right padding. + This property holds the right padding. Unless explicitly set, the value + is equal to \c horizontalPadding. \include qquickpopup-padding.qdocinc - \sa padding, leftPadding, availableWidth + \sa padding, leftPadding, horizontalPadding, availableWidth */ qreal QQuickPopup::rightPadding() const { @@ -1375,11 +1449,12 @@ void QQuickPopup::resetRightPadding() /*! \qmlproperty real QtQuick.Controls::Popup::bottomPadding - This property holds the bottom padding. + This property holds the bottom padding. Unless explicitly set, the value + is equal to \c verticalPadding. \include qquickpopup-padding.qdocinc - \sa padding, topPadding, availableHeight + \sa padding, topPadding, verticalPadding, availableHeight */ qreal QQuickPopup::bottomPadding() const { @@ -1665,13 +1740,12 @@ void QQuickPopup::setContentItem(QQuickItem *item) \sa Item::data, contentChildren */ -QQmlListProperty<QObject> QQuickPopup::contentData() +QQmlListProperty<QObject> QQuickPopupPrivate::contentData() { - Q_D(QQuickPopup); - QQuickControlPrivate *p = QQuickControlPrivate::get(d->popupItem); + QQuickControlPrivate *p = QQuickControlPrivate::get(popupItem); if (!p->contentItem) p->executeContentItem(); - return QQmlListProperty<QObject>(d->popupItem->contentItem(), nullptr, + return QQmlListProperty<QObject>(popupItem->contentItem(), nullptr, QQuickItemPrivate::data_append, QQuickItemPrivate::data_count, QQuickItemPrivate::data_at, @@ -1691,10 +1765,9 @@ QQmlListProperty<QObject> QQuickPopup::contentData() \sa Item::children, contentData */ -QQmlListProperty<QQuickItem> QQuickPopup::contentChildren() +QQmlListProperty<QQuickItem> QQuickPopupPrivate::contentChildren() { - Q_D(QQuickPopup); - return QQmlListProperty<QQuickItem>(d->popupItem->contentItem(), nullptr, + return QQmlListProperty<QQuickItem>(popupItem->contentItem(), nullptr, QQuickItemPrivate::children_append, QQuickItemPrivate::children_count, QQuickItemPrivate::children_at, @@ -2087,6 +2160,236 @@ void QQuickPopup::setExit(QQuickTransition *transition) emit exitChanged(); } +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::Popup::horizontalPadding + + This property holds the horizontal padding. Unless explicitly set, the value + is equal to \c padding. + + \include qquickpopup-padding.qdocinc + + \sa padding, leftPadding, rightPadding, verticalPadding +*/ +qreal QQuickPopup::horizontalPadding() const +{ + Q_D(const QQuickPopup); + return d->popupItem->horizontalPadding(); +} + +void QQuickPopup::setHorizontalPadding(qreal padding) +{ + Q_D(QQuickPopup); + d->popupItem->setHorizontalPadding(padding); +} + +void QQuickPopup::resetHorizontalPadding() +{ + Q_D(QQuickPopup); + d->popupItem->resetHorizontalPadding(); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::Popup::verticalPadding + + This property holds the vertical padding. Unless explicitly set, the value + is equal to \c padding. + + \include qquickpopup-padding.qdocinc + + \sa padding, topPadding, bottomPadding, horizontalPadding +*/ +qreal QQuickPopup::verticalPadding() const +{ + Q_D(const QQuickPopup); + return d->popupItem->verticalPadding(); +} + +void QQuickPopup::setVerticalPadding(qreal padding) +{ + Q_D(QQuickPopup); + d->popupItem->setVerticalPadding(padding); +} + +void QQuickPopup::resetVerticalPadding() +{ + Q_D(QQuickPopup); + d->popupItem->resetVerticalPadding(); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::Popup::implicitContentWidth + \readonly + + This property holds the implicit content width. + + The value is calculated based on the content children. + + \sa implicitContentHeight, implicitBackgroundWidth +*/ +qreal QQuickPopup::implicitContentWidth() const +{ + Q_D(const QQuickPopup); + return d->popupItem->implicitContentWidth(); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::Popup::implicitContentHeight + \readonly + + This property holds the implicit content height. + + The value is calculated based on the content children. + + \sa implicitContentWidth, implicitBackgroundHeight +*/ +qreal QQuickPopup::implicitContentHeight() const +{ + Q_D(const QQuickPopup); + return d->popupItem->implicitContentHeight(); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::Popup::implicitBackgroundWidth + \readonly + + This property holds the implicit background width. + + The value is equal to \c {background ? background.implicitWidth : 0}. + + \sa implicitBackgroundHeight, implicitContentWidth +*/ +qreal QQuickPopup::implicitBackgroundWidth() const +{ + Q_D(const QQuickPopup); + return d->popupItem->implicitBackgroundWidth(); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::Popup::implicitBackgroundHeight + \readonly + + This property holds the implicit background height. + + The value is equal to \c {background ? background.implicitHeight : 0}. + + \sa implicitBackgroundWidth, implicitContentHeight +*/ +qreal QQuickPopup::implicitBackgroundHeight() const +{ + Q_D(const QQuickPopup); + return d->popupItem->implicitBackgroundHeight(); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::Popup::topInset + + This property holds the top inset for the background. + + \sa {Popup Layout}, bottomInset +*/ +qreal QQuickPopup::topInset() const +{ + Q_D(const QQuickPopup); + return d->popupItem->topInset(); +} + +void QQuickPopup::setTopInset(qreal inset) +{ + Q_D(QQuickPopup); + d->popupItem->setTopInset(inset); +} + +void QQuickPopup::resetTopInset() +{ + Q_D(QQuickPopup); + d->popupItem->resetTopInset(); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::Popup::leftInset + + This property holds the left inset for the background. + + \sa {Popup Layout}, rightInset +*/ +qreal QQuickPopup::leftInset() const +{ + Q_D(const QQuickPopup); + return d->popupItem->leftInset(); +} + +void QQuickPopup::setLeftInset(qreal inset) +{ + Q_D(QQuickPopup); + d->popupItem->setLeftInset(inset); +} + +void QQuickPopup::resetLeftInset() +{ + Q_D(QQuickPopup); + d->popupItem->resetLeftInset(); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::Popup::rightInset + + This property holds the right inset for the background. + + \sa {Popup Layout}, leftInset +*/ +qreal QQuickPopup::rightInset() const +{ + Q_D(const QQuickPopup); + return d->popupItem->rightInset(); +} + +void QQuickPopup::setRightInset(qreal inset) +{ + Q_D(QQuickPopup); + d->popupItem->setRightInset(inset); +} + +void QQuickPopup::resetRightInset() +{ + Q_D(QQuickPopup); + d->popupItem->resetRightInset(); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::Popup::bottomInset + + This property holds the bottom inset for the background. + + \sa {Popup Layout}, topInset +*/ +qreal QQuickPopup::bottomInset() const +{ + Q_D(const QQuickPopup); + return d->popupItem->bottomInset(); +} + +void QQuickPopup::setBottomInset(qreal inset) +{ + Q_D(QQuickPopup); + d->popupItem->setBottomInset(inset); +} + +void QQuickPopup::resetBottomInset() +{ + Q_D(QQuickPopup); + d->popupItem->resetBottomInset(); +} + bool QQuickPopup::filtersChildMouseEvents() const { Q_D(const QQuickPopup); @@ -2262,6 +2565,14 @@ void QQuickPopup::contentItemChange(QQuickItem *newItem, QQuickItem *oldItem) Q_UNUSED(oldItem); } +void QQuickPopup::contentSizeChange(const QSizeF &newSize, const QSizeF &oldSize) +{ + if (!qFuzzyCompare(newSize.width(), oldSize.width())) + emit contentWidthChanged(); + if (!qFuzzyCompare(newSize.height(), oldSize.height())) + emit contentHeightChanged(); +} + void QQuickPopup::fontChange(const QFont &newFont, const QFont &oldFont) { Q_UNUSED(newFont); @@ -2337,10 +2648,14 @@ void QQuickPopup::paddingChange(const QMarginsF &newPadding, const QMarginsF &ol if (bp) emit bottomPaddingChanged(); - if (lp || rp) + if (lp || rp) { + emit horizontalPaddingChanged(); emit availableWidthChanged(); - if (tp || bp) + } + if (tp || bp) { + emit verticalPaddingChanged(); emit availableHeightChanged(); + } } void QQuickPopup::paletteChange(const QPalette &newPalette, const QPalette &oldPalette) @@ -2357,14 +2672,26 @@ void QQuickPopup::spacingChange(qreal newSpacing, qreal oldSpacing) emit spacingChanged(); } +void QQuickPopup::insetChange(const QMarginsF &newInset, const QMarginsF &oldInset) +{ + if (!qFuzzyCompare(newInset.top(), oldInset.top())) + emit topInsetChanged(); + if (!qFuzzyCompare(newInset.left(), oldInset.left())) + emit leftInsetChanged(); + if (!qFuzzyCompare(newInset.right(), oldInset.right())) + emit rightInsetChanged(); + if (!qFuzzyCompare(newInset.bottom(), oldInset.bottom())) + emit bottomInsetChanged(); +} + QFont QQuickPopup::defaultFont() const { - return QQuickControlPrivate::themeFont(QPlatformTheme::SystemFont); + return QQuickTheme::themeFont(QQuickTheme::System); } QPalette QQuickPopup::defaultPalette() const { - return QQuickControlPrivate::themePalette(QPlatformTheme::SystemPalette); + return QQuickTheme::themePalette(QQuickTheme::System); } #if QT_CONFIG(accessibility) @@ -2404,3 +2731,5 @@ bool QQuickPopup::setAccessibleProperty(const char *propertyName, const QVariant } QT_END_NAMESPACE + +#include "moc_qquickpopup_p.cpp" diff --git a/src/quicktemplates2/qquickpopup_p.h b/src/quicktemplates2/qquickpopup_p.h index 2a42ff27..12dbd247 100644 --- a/src/quicktemplates2/qquickpopup_p.h +++ b/src/quicktemplates2/qquickpopup_p.h @@ -67,6 +67,7 @@ QT_BEGIN_NAMESPACE class QQuickWindow; +class QQuickPopupAnchors; class QQuickPopupPrivate; class QQuickTransition; @@ -100,8 +101,8 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickPopup : public QObject, public QQml Q_PROPERTY(QQuickItem *parent READ parentItem WRITE setParentItem RESET resetParentItem NOTIFY parentChanged FINAL) Q_PROPERTY(QQuickItem *background READ background WRITE setBackground NOTIFY backgroundChanged FINAL) Q_PROPERTY(QQuickItem *contentItem READ contentItem WRITE setContentItem NOTIFY contentItemChanged FINAL) - Q_PROPERTY(QQmlListProperty<QObject> contentData READ contentData FINAL) - Q_PROPERTY(QQmlListProperty<QQuickItem> contentChildren READ contentChildren NOTIFY contentChildrenChanged FINAL) + Q_PRIVATE_PROPERTY(QQuickPopup::d_func(), QQmlListProperty<QObject> contentData READ contentData FINAL) + Q_PRIVATE_PROPERTY(QQuickPopup::d_func(), QQmlListProperty<QQuickItem> contentChildren READ contentChildren NOTIFY contentChildrenChanged FINAL) Q_PROPERTY(bool clip READ clip WRITE setClip NOTIFY clipChanged FINAL) Q_PROPERTY(bool focus READ hasFocus WRITE setFocus NOTIFY focusChanged FINAL) Q_PROPERTY(bool activeFocus READ hasActiveFocus NOTIFY activeFocusChanged FINAL) @@ -121,6 +122,18 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickPopup : public QObject, public QQml Q_PROPERTY(bool mirrored READ isMirrored NOTIFY mirroredChanged FINAL REVISION 3) Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged FINAL REVISION 3) Q_PROPERTY(QPalette palette READ palette WRITE setPalette RESET resetPalette NOTIFY paletteChanged FINAL REVISION 3) + // 2.5 (Qt 5.12) + Q_PROPERTY(qreal horizontalPadding READ horizontalPadding WRITE setHorizontalPadding RESET resetHorizontalPadding NOTIFY horizontalPaddingChanged FINAL) + Q_PROPERTY(qreal verticalPadding READ verticalPadding WRITE setVerticalPadding RESET resetVerticalPadding NOTIFY verticalPaddingChanged FINAL) + Q_PRIVATE_PROPERTY(QQuickPopup::d_func(), QQuickPopupAnchors *anchors READ getAnchors DESIGNABLE false CONSTANT FINAL REVISION 5) + Q_PROPERTY(qreal implicitContentWidth READ implicitContentWidth NOTIFY implicitContentWidthChanged FINAL REVISION 5) + Q_PROPERTY(qreal implicitContentHeight READ implicitContentHeight NOTIFY implicitContentHeightChanged FINAL REVISION 5) + Q_PROPERTY(qreal implicitBackgroundWidth READ implicitBackgroundWidth NOTIFY implicitBackgroundWidthChanged FINAL REVISION 5) + Q_PROPERTY(qreal implicitBackgroundHeight READ implicitBackgroundHeight NOTIFY implicitBackgroundHeightChanged FINAL REVISION 5) + Q_PROPERTY(qreal topInset READ topInset WRITE setTopInset RESET resetTopInset NOTIFY topInsetChanged FINAL REVISION 5) + Q_PROPERTY(qreal leftInset READ leftInset WRITE setLeftInset RESET resetLeftInset NOTIFY leftInsetChanged FINAL REVISION 5) + Q_PROPERTY(qreal rightInset READ rightInset WRITE setRightInset RESET resetRightInset NOTIFY rightInsetChanged FINAL REVISION 5) + Q_PROPERTY(qreal bottomInset READ bottomInset WRITE setBottomInset RESET resetBottomInset NOTIFY bottomInsetChanged FINAL REVISION 5) Q_CLASSINFO("DeferredPropertyNames", "background,contentItem") Q_CLASSINFO("DefaultProperty", "contentData") @@ -224,9 +237,6 @@ public: QQuickItem *contentItem() const; void setContentItem(QQuickItem *item); - QQmlListProperty<QObject> contentData(); - QQmlListProperty<QQuickItem> contentChildren(); - bool clip() const; void setClip(bool clip); @@ -304,6 +314,37 @@ public: void setPalette(const QPalette &palette); void resetPalette(); + // 2.5 (Qt 5.12) + qreal horizontalPadding() const; + void setHorizontalPadding(qreal padding); + void resetHorizontalPadding(); + + qreal verticalPadding() const; + void setVerticalPadding(qreal padding); + void resetVerticalPadding(); + + qreal implicitContentWidth() const; + qreal implicitContentHeight() const; + + qreal implicitBackgroundWidth() const; + qreal implicitBackgroundHeight() const; + + qreal topInset() const; + void setTopInset(qreal inset); + void resetTopInset(); + + qreal leftInset() const; + void setLeftInset(qreal inset); + void resetLeftInset(); + + qreal rightInset() const; + void setRightInset(qreal inset); + void resetRightInset(); + + qreal bottomInset() const; + void setBottomInset(qreal inset); + void resetBottomInset(); + public Q_SLOTS: void open(); void close(); @@ -359,6 +400,17 @@ Q_SIGNALS: Q_REVISION(3) void mirroredChanged(); Q_REVISION(3) void enabledChanged(); Q_REVISION(3) void paletteChanged(); + // 2.5 (Qt 5.12) + Q_REVISION(5) void horizontalPaddingChanged(); + Q_REVISION(5) void verticalPaddingChanged(); + Q_REVISION(5) void implicitContentWidthChanged(); + Q_REVISION(5) void implicitContentHeightChanged(); + Q_REVISION(5) void implicitBackgroundWidthChanged(); + Q_REVISION(5) void implicitBackgroundHeightChanged(); + Q_REVISION(5) void topInsetChanged(); + Q_REVISION(5) void leftInsetChanged(); + Q_REVISION(5) void rightInsetChanged(); + Q_REVISION(5) void bottomInsetChanged(); protected: QQuickPopup(QQuickPopupPrivate &dd, QObject *parent); @@ -387,6 +439,7 @@ protected: #endif virtual void contentItemChange(QQuickItem *newItem, QQuickItem *oldItem); + virtual void contentSizeChange(const QSizeF &newSize, const QSizeF &oldSize); virtual void fontChange(const QFont &newFont, const QFont &oldFont); virtual void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry); virtual void localeChange(const QLocale &newLocale, const QLocale &oldLocale); @@ -395,6 +448,7 @@ protected: virtual void paddingChange(const QMarginsF &newPadding, const QMarginsF &oldPadding); virtual void paletteChange(const QPalette &newPalette, const QPalette &oldPalette); virtual void spacingChange(qreal newSpacing, qreal oldSpacing); + virtual void insetChange(const QMarginsF &newInset, const QMarginsF &oldInset); virtual QFont defaultFont() const; virtual QPalette defaultPalette() const; diff --git a/src/quicktemplates2/qquickpopup_p_p.h b/src/quicktemplates2/qquickpopup_p_p.h index 6890fdac..37c9ffe5 100644 --- a/src/quicktemplates2/qquickpopup_p_p.h +++ b/src/quicktemplates2/qquickpopup_p_p.h @@ -61,6 +61,7 @@ QT_BEGIN_NAMESPACE class QQuickTransition; class QQuickTransitionManager; class QQuickPopup; +class QQuickPopupAnchors; class QQuickPopupItem; class QQuickPopupPrivate; class QQuickPopupPositioner; @@ -93,6 +94,9 @@ public: return popup->d_func(); } + QQmlListProperty<QObject> contentData(); + QQmlListProperty<QQuickItem> contentChildren(); + void init(); void closeOrReject(); bool tryClose(const QPointF &pos, QQuickPopup::ClosePolicy flags); @@ -135,6 +139,8 @@ public: void setRightMargin(qreal value, bool reset = false); void setBottomMargin(qreal value, bool reset = false); + QQuickPopupAnchors *getAnchors(); + void setWindow(QQuickWindow *window); void itemDestroyed(QQuickItem *item) override; @@ -174,8 +180,6 @@ public: qreal leftMargin; qreal rightMargin; qreal bottomMargin; - qreal contentWidth; - qreal contentHeight; QPointF pressPoint; TransitionState transitionState; QQuickPopup::ClosePolicy closePolicy; @@ -189,6 +193,7 @@ public: QList<QQuickStateAction> enterActions; QList<QQuickStateAction> exitActions; QQuickPopupTransitionManager transitionManager; + QQuickPopupAnchors *anchors; friend class QQuickPopupTransitionManager; }; diff --git a/src/quicktemplates2/qquickpopupanchors.cpp b/src/quicktemplates2/qquickpopupanchors.cpp new file mode 100644 index 00000000..1311a322 --- /dev/null +++ b/src/quicktemplates2/qquickpopupanchors.cpp @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickpopupanchors_p.h" +#include "qquickpopupanchors_p_p.h" +#include "qquickpopuppositioner_p_p.h" + +#include <QtQuick/qquickwindow.h> + +QT_BEGIN_NAMESPACE + +QQuickPopupAnchorsPrivate::QQuickPopupAnchorsPrivate(QQuickPopupPositioner *positioner) + : positioner(positioner) +{ +} + +QQuickPopupAnchorsPrivate::~QQuickPopupAnchorsPrivate() +{ +} + +QQuickPopupAnchors::QQuickPopupAnchors(QQuickPopupPositioner *positioner, QObject *parent) + : QObject(*(new QQuickPopupAnchorsPrivate(positioner)), parent) +{ +} + +QQuickPopupAnchors::QQuickPopupAnchors(QQuickPopupAnchorsPrivate &dd, QObject *parent) + : QObject(dd, parent) +{ +} + +QQuickPopupAnchors::~QQuickPopupAnchors() +{ +} + +QQuickItem *QQuickPopupAnchors::centerIn() const +{ + Q_D(const QQuickPopupAnchors); + return d->centerIn; +} + +void QQuickPopupAnchors::setCenterIn(QQuickItem *item) +{ + Q_D(QQuickPopupAnchors); + if (item == d->centerIn) + return; + + d->centerIn = item; + d->positioner->reposition(); + emit centerInChanged(); +} + +void QQuickPopupAnchors::resetCenterIn() +{ + setCenterIn(nullptr); +} + +QT_END_NAMESPACE diff --git a/src/quicktemplates2/qquickpopupanchors_p.h b/src/quicktemplates2/qquickpopupanchors_p.h new file mode 100644 index 00000000..490a4867 --- /dev/null +++ b/src/quicktemplates2/qquickpopupanchors_p.h @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKPOPUPANCHORS_P_H +#define QQUICKPOPUPANCHORS_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qobject.h> +#include <QtQml/qqml.h> +#include <QtQuickTemplates2/private/qtquicktemplates2global_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickItem; +class QQuickPopupAnchorsPrivate; +class QQuickPopupPositioner; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickPopupAnchors : public QObject +{ + Q_OBJECT + Q_PROPERTY(QQuickItem *centerIn READ centerIn WRITE setCenterIn RESET resetCenterIn NOTIFY centerInChanged) + +public: + explicit QQuickPopupAnchors(QQuickPopupPositioner *positioner, QObject *parent); + ~QQuickPopupAnchors(); + + QQuickItem *centerIn() const; + void setCenterIn(QQuickItem *item); + void resetCenterIn(); + +Q_SIGNALS: + void centerInChanged(); + +protected: + QQuickPopupAnchors(QQuickPopupAnchorsPrivate &dd, QObject *parent); + +private: + Q_DISABLE_COPY(QQuickPopupAnchors) + Q_DECLARE_PRIVATE(QQuickPopupAnchors) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickPopupAnchors) + +#endif // QQUICKPOPUPANCHORS_P_H diff --git a/src/quicktemplates2/qquickpopupanchors_p_p.h b/src/quicktemplates2/qquickpopupanchors_p_p.h new file mode 100644 index 00000000..c2f577bf --- /dev/null +++ b/src/quicktemplates2/qquickpopupanchors_p_p.h @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKPOPUPANCHORS_P_P_H +#define QQUICKPOPUPANCHORS_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/private/qobject_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickPopupAnchors; +class QQuickPopupPositioner; + +class QQuickPopupAnchorsPrivate : public QObjectPrivate +{ + Q_DECLARE_PUBLIC(QQuickPopupAnchors) + +public: + QQuickPopupAnchorsPrivate(QQuickPopupPositioner *positioner); + ~QQuickPopupAnchorsPrivate(); + + static QQuickPopupAnchorsPrivate *get(QQuickPopupAnchors *popupAnchors) + { + return popupAnchors->d_func(); + } + + QQuickPopupPositioner *positioner = nullptr; + QQuickItem *centerIn = nullptr; +}; + +QT_END_NAMESPACE + +#endif // QQUICKPOPUPANCHORS_P_P_H diff --git a/src/quicktemplates2/qquickpopupitem.cpp b/src/quicktemplates2/qquickpopupitem.cpp index 566a5245..ad9ffe51 100644 --- a/src/quicktemplates2/qquickpopupitem.cpp +++ b/src/quicktemplates2/qquickpopupitem.cpp @@ -37,7 +37,8 @@ #include "qquickpopupitem_p_p.h" #include "qquickapplicationwindow_p.h" #include "qquickshortcutcontext_p_p.h" -#include "qquickcontrol_p_p.h" +#include "qquickpage_p_p.h" +#include "qquickcontentitem_p.h" #include "qquickpopup_p_p.h" #include "qquickdeferredexecute_p_p.h" @@ -46,7 +47,7 @@ QT_BEGIN_NAMESPACE -class QQuickPopupItemPrivate : public QQuickControlPrivate +class QQuickPopupItemPrivate : public QQuickPagePrivate { Q_DECLARE_PUBLIC(QQuickPopupItem) @@ -82,13 +83,13 @@ QQuickPopupItemPrivate::QQuickPopupItemPrivate(QQuickPopup *popup) void QQuickPopupItemPrivate::implicitWidthChanged() { - QQuickControlPrivate::implicitWidthChanged(); + QQuickPagePrivate::implicitWidthChanged(); emit popup->implicitWidthChanged(); } void QQuickPopupItemPrivate::implicitHeightChanged() { - QQuickControlPrivate::implicitHeightChanged(); + QQuickPagePrivate::implicitHeightChanged(); emit popup->implicitHeightChanged(); } @@ -97,7 +98,7 @@ void QQuickPopupItemPrivate::resolveFont() if (QQuickApplicationWindow *window = qobject_cast<QQuickApplicationWindow *>(popup->window())) inheritFont(window->font()); else - inheritFont(themeFont(QPlatformTheme::SystemFont)); + inheritFont(QQuickTheme::themeFont(QQuickTheme::System)); } void QQuickPopupItemPrivate::resolvePalette() @@ -105,15 +106,16 @@ void QQuickPopupItemPrivate::resolvePalette() if (QQuickApplicationWindow *window = qobject_cast<QQuickApplicationWindow *>(popup->window())) inheritPalette(window->palette()); else - inheritPalette(themePalette(QPlatformTheme::SystemPalette)); + inheritPalette(QQuickTheme::themePalette(QQuickTheme::System)); } QQuickItem *QQuickPopupItemPrivate::getContentItem() { Q_Q(QQuickPopupItem); - if (QQuickItem *item = QQuickControlPrivate::getContentItem()) + if (QQuickItem *item = QQuickPagePrivate::getContentItem()) return item; - return new QQuickItem(q); + + return new QQuickContentItem(popup, q); } static inline QString contentItemName() { return QStringLiteral("contentItem"); } @@ -153,7 +155,7 @@ void QQuickPopupItemPrivate::executeBackground(bool complete) } QQuickPopupItem::QQuickPopupItem(QQuickPopup *popup) - : QQuickControl(*(new QQuickPopupItemPrivate(popup)), nullptr) + : QQuickPage(*(new QQuickPopupItemPrivate(popup)), nullptr) { setParent(popup); setFlag(ItemIsFocusScope); @@ -307,28 +309,35 @@ void QQuickPopupItem::wheelEvent(QWheelEvent *event) void QQuickPopupItem::contentItemChange(QQuickItem *newItem, QQuickItem *oldItem) { Q_D(QQuickPopupItem); - QQuickControl::contentItemChange(newItem, oldItem); + QQuickPage::contentItemChange(newItem, oldItem); d->popup->contentItemChange(newItem, oldItem); } +void QQuickPopupItem::contentSizeChange(const QSizeF &newSize, const QSizeF &oldSize) +{ + Q_D(QQuickPopupItem); + QQuickPage::contentSizeChange(newSize, oldSize); + d->popup->contentSizeChange(newSize, oldSize); +} + void QQuickPopupItem::fontChange(const QFont &newFont, const QFont &oldFont) { Q_D(QQuickPopupItem); - QQuickControl::fontChange(newFont, oldFont); + QQuickPage::fontChange(newFont, oldFont); d->popup->fontChange(newFont, oldFont); } void QQuickPopupItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) { Q_D(QQuickPopupItem); - QQuickControl::geometryChanged(newGeometry, oldGeometry); + QQuickPage::geometryChanged(newGeometry, oldGeometry); d->popup->geometryChanged(newGeometry, oldGeometry); } void QQuickPopupItem::localeChange(const QLocale &newLocale, const QLocale &oldLocale) { Q_D(QQuickPopupItem); - QQuickControl::localeChange(newLocale, oldLocale); + QQuickPage::localeChange(newLocale, oldLocale); d->popup->localeChange(newLocale, oldLocale); } @@ -341,21 +350,21 @@ void QQuickPopupItem::mirrorChange() void QQuickPopupItem::itemChange(ItemChange change, const ItemChangeData &data) { Q_D(QQuickPopupItem); - QQuickControl::itemChange(change, data); + QQuickPage::itemChange(change, data); d->popup->itemChange(change, data); } void QQuickPopupItem::paddingChange(const QMarginsF &newPadding, const QMarginsF &oldPadding) { Q_D(QQuickPopupItem); - QQuickControl::paddingChange(newPadding, oldPadding); + QQuickPage::paddingChange(newPadding, oldPadding); d->popup->paddingChange(newPadding, oldPadding); } void QQuickPopupItem::paletteChange(const QPalette &newPalette, const QPalette &oldPalette) { Q_D(QQuickPopupItem); - QQuickControl::paletteChange(newPalette, oldPalette); + QQuickPage::paletteChange(newPalette, oldPalette); d->popup->paletteChange(newPalette, oldPalette); } @@ -381,7 +390,7 @@ QAccessible::Role QQuickPopupItem::accessibleRole() const void QQuickPopupItem::accessibilityActiveChanged(bool active) { Q_D(const QQuickPopupItem); - QQuickControl::accessibilityActiveChanged(active); + QQuickPage::accessibilityActiveChanged(active); d->popup->accessibilityActiveChanged(active); } #endif diff --git a/src/quicktemplates2/qquickpopupitem_p_p.h b/src/quicktemplates2/qquickpopupitem_p_p.h index 0187b77a..a15aeb17 100644 --- a/src/quicktemplates2/qquickpopupitem_p_p.h +++ b/src/quicktemplates2/qquickpopupitem_p_p.h @@ -48,14 +48,13 @@ // We mean it. // -#include <QtQuickTemplates2/private/qquickcontrol_p.h> +#include <QtQuickTemplates2/private/qquickpage_p.h> QT_BEGIN_NAMESPACE class QQuickPopup; class QQuickPopupItemPrivate; - -class QQuickPopupItem : public QQuickControl +class QQuickPopupItem : public QQuickPage { Q_OBJECT @@ -88,6 +87,7 @@ protected: #endif void contentItemChange(QQuickItem *newItem, QQuickItem *oldItem) override; + void contentSizeChange(const QSizeF &newSize, const QSizeF &oldSize) override; void fontChange(const QFont &newFont, const QFont &oldFont) override; void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) override; void localeChange(const QLocale &newLocale, const QLocale &oldLocale) override; diff --git a/src/quicktemplates2/qquickpopuppositioner.cpp b/src/quicktemplates2/qquickpopuppositioner.cpp index 2b67c85e..60a989da 100644 --- a/src/quicktemplates2/qquickpopuppositioner.cpp +++ b/src/quicktemplates2/qquickpopuppositioner.cpp @@ -34,10 +34,13 @@ ** ****************************************************************************/ +#include "qquickoverlay_p.h" #include "qquickpopuppositioner_p_p.h" +#include "qquickpopupanchors_p.h" #include "qquickpopupitem_p_p.h" #include "qquickpopup_p_p.h" +#include <QtQml/qqmlinfo.h> #include <QtQuick/private/qquickitem_p.h> QT_BEGIN_NAMESPACE @@ -111,12 +114,31 @@ void QQuickPopupPositioner::reposition() bool heightAdjusted = false; QQuickPopupPrivate *p = QQuickPopupPrivate::get(m_popup); - QRectF rect(p->allowHorizontalMove ? p->x : popupItem->x(), - p->allowVerticalMove ? p->y : popupItem->y(), + const QQuickItem *centerInParent = p->anchors ? p->getAnchors()->centerIn() : nullptr; + const QQuickOverlay *centerInOverlay = qobject_cast<const QQuickOverlay*>(centerInParent); + QRectF rect(!centerInParent ? p->allowHorizontalMove ? p->x : popupItem->x() : 0, + !centerInParent ? p->allowVerticalMove ? p->y : popupItem->y() : 0, !p->hasWidth && iw > 0 ? iw : w, !p->hasHeight && ih > 0 ? ih : h); if (m_parentItem) { - rect.moveTopLeft(m_parentItem->mapToItem(popupItem->parentItem(), rect.topLeft())); + // m_parentItem is the parent that the popup should open in, + // and popupItem()->parentItem() is the overlay, so the mapToItem() calls below + // effectively map the rect to scene coordinates. + if (centerInParent) { + if (centerInParent != parentItem() && !centerInOverlay) { + qmlWarning(m_popup) << "Popup can only be centered within its immediate parent or Overlay.overlay"; + return; + } + + if (centerInOverlay) { + rect.moveCenter(QPointF(qRound(centerInOverlay->width() / 2.0), qRound(centerInOverlay->height() / 2.0))); + } else { + const QPointF parentItemCenter = QPointF(qRound(m_parentItem->width() / 2), qRound(m_parentItem->height() / 2)); + rect.moveCenter(m_parentItem->mapToItem(popupItem->parentItem(), parentItemCenter)); + } + } else { + rect.moveTopLeft(m_parentItem->mapToItem(popupItem->parentItem(), rect.topLeft())); + } if (p->window) { const QMarginsF margins = p->getMargins(); @@ -217,7 +239,11 @@ void QQuickPopupPositioner::reposition() popupItem->setPosition(rect.topLeft()); - const QPointF effectivePos = m_parentItem ? m_parentItem->mapFromScene(rect.topLeft()) : rect.topLeft(); + // If the popup was assigned a parent, rect will be in scene coordinates, + // so we need to map its top left back to item coordinates. + // However, if centering within the overlay, the coordinates will be relative + // to the window, so we don't need to do anything. + const QPointF effectivePos = m_parentItem && !centerInOverlay ? m_parentItem->mapFromScene(rect.topLeft()) : rect.topLeft(); if (!qFuzzyCompare(p->effectiveX, effectivePos.x())) { p->effectiveX = effectivePos.x(); emit m_popup->xChanged(); diff --git a/src/quicktemplates2/qquickradiobutton.cpp b/src/quicktemplates2/qquickradiobutton.cpp index 86be3ed6..31aa4be9 100644 --- a/src/quicktemplates2/qquickradiobutton.cpp +++ b/src/quicktemplates2/qquickradiobutton.cpp @@ -99,12 +99,12 @@ QQuickRadioButton::QQuickRadioButton(QQuickItem *parent) QFont QQuickRadioButton::defaultFont() const { - return QQuickControlPrivate::themeFont(QPlatformTheme::RadioButtonFont); + return QQuickTheme::themeFont(QQuickTheme::RadioButton); } QPalette QQuickRadioButton::defaultPalette() const { - return QQuickControlPrivate::themePalette(QPlatformTheme::RadioButtonPalette); + return QQuickTheme::themePalette(QQuickTheme::RadioButton); } #if QT_CONFIG(accessibility) diff --git a/src/quicktemplates2/qquickradiodelegate.cpp b/src/quicktemplates2/qquickradiodelegate.cpp index fe603d36..12cb0d08 100644 --- a/src/quicktemplates2/qquickradiodelegate.cpp +++ b/src/quicktemplates2/qquickradiodelegate.cpp @@ -100,7 +100,12 @@ QQuickRadioDelegate::QQuickRadioDelegate(QQuickItem *parent) QFont QQuickRadioDelegate::defaultFont() const { - return QQuickControlPrivate::themeFont(QPlatformTheme::ListViewFont); + return QQuickTheme::themeFont(QQuickTheme::ListView); +} + +QPalette QQuickRadioDelegate::defaultPalette() const +{ + return QQuickTheme::themePalette(QQuickTheme::ListView); } #if QT_CONFIG(accessibility) diff --git a/src/quicktemplates2/qquickradiodelegate_p.h b/src/quicktemplates2/qquickradiodelegate_p.h index 4db9959d..453856e4 100644 --- a/src/quicktemplates2/qquickradiodelegate_p.h +++ b/src/quicktemplates2/qquickradiodelegate_p.h @@ -63,6 +63,7 @@ public: protected: QFont defaultFont() const override; + QPalette defaultPalette() const override; #if QT_CONFIG(accessibility) QAccessible::Role accessibleRole() const override; diff --git a/src/quicktemplates2/qquickrangeslider.cpp b/src/quicktemplates2/qquickrangeslider.cpp index 35797203..b06cb23c 100644 --- a/src/quicktemplates2/qquickrangeslider.cpp +++ b/src/quicktemplates2/qquickrangeslider.cpp @@ -74,7 +74,7 @@ QT_BEGIN_NAMESPACE use the following syntax: \code - first.onValueChanged: console.log("first.value changed to " + first.value) + first.onMoved: console.log("first.value changed to " + first.value) \endcode The \l {first.position} and \l {second.position} properties are expressed as @@ -270,8 +270,13 @@ void QQuickRangeSliderNode::setHandle(QQuickItem *handle) if (!d->handle.isExecuting()) d->cancelHandle(); + const qreal oldImplicitHandleWidth = implicitHandleWidth(); + const qreal oldImplicitHandleHeight = implicitHandleHeight(); + + QQuickControlPrivate::get(d->slider)->removeImplicitSizeListener(d->handle); delete d->handle; d->handle = handle; + if (handle) { if (!handle->parentItem()) handle->setParentItem(d->slider); @@ -295,7 +300,13 @@ void QQuickRangeSliderNode::setHandle(QQuickItem *handle) } handle->setActiveFocusOnTab(true); + QQuickControlPrivate::get(d->slider)->addImplicitSizeListener(handle); } + + if (!qFuzzyCompare(oldImplicitHandleWidth, implicitHandleWidth())) + emit implicitHandleWidthChanged(); + if (!qFuzzyCompare(oldImplicitHandleHeight, implicitHandleHeight())) + emit implicitHandleHeightChanged(); if (!d->handle.isExecuting()) emit handleChanged(); } @@ -333,6 +344,22 @@ void QQuickRangeSliderNode::setHovered(bool hovered) emit hoveredChanged(); } +qreal QQuickRangeSliderNode::implicitHandleWidth() const +{ + Q_D(const QQuickRangeSliderNode); + if (!d->handle) + return 0; + return d->handle->implicitWidth(); +} + +qreal QQuickRangeSliderNode::implicitHandleHeight() const +{ + Q_D(const QQuickRangeSliderNode); + if (!d->handle) + return 0; + return d->handle->implicitHeight(); +} + void QQuickRangeSliderNode::increase() { Q_D(QQuickRangeSliderNode); @@ -360,6 +387,7 @@ public: from(defaultFrom), to(defaultTo), stepSize(0), + touchDragThreshold(-1), first(nullptr), second(nullptr), orientation(Qt::Horizontal), @@ -379,10 +407,14 @@ public: void updateHover(const QPointF &pos); + void itemImplicitWidthChanged(QQuickItem *item) override; + void itemImplicitHeightChanged(QQuickItem *item) override; + bool live; qreal from; qreal to; qreal stepSize; + qreal touchDragThreshold; QQuickRangeSliderNode *first; QQuickRangeSliderNode *second; QPointF pressPoint; @@ -522,6 +554,7 @@ void QQuickRangeSliderPrivate::handleMove(const QPointF &point) QQuickControlPrivate::handleMove(point); QQuickRangeSliderNode *pressedNode = QQuickRangeSliderPrivate::pressedNode(touchId); if (pressedNode) { + const qreal oldPos = pressedNode->position(); qreal pos = positionAt(q, pressedNode->handle(), point); if (snapMode == QQuickRangeSlider::SnapAlways) pos = snapPosition(q, pos); @@ -529,6 +562,9 @@ void QQuickRangeSliderPrivate::handleMove(const QPointF &point) pressedNode->setValue(valueAt(q, pos)); else QQuickRangeSliderNodePrivate::get(pressedNode)->setPosition(pos); + + if (!qFuzzyCompare(pressedNode->position(), oldPos)) + emit pressedNode->moved(); } } @@ -544,6 +580,7 @@ void QQuickRangeSliderPrivate::handleRelease(const QPointF &point) QQuickRangeSliderNodePrivate *pressedNodePrivate = QQuickRangeSliderNodePrivate::get(pressedNode); if (q->keepMouseGrab() || q->keepTouchGrab()) { + const qreal oldPos = pressedNode->position(); qreal pos = positionAt(q, pressedNode->handle(), point); if (snapMode != QQuickRangeSlider::NoSnap) pos = snapPosition(q, pos); @@ -554,6 +591,9 @@ void QQuickRangeSliderPrivate::handleRelease(const QPointF &point) pressedNodePrivate->setPosition(pos); q->setKeepMouseGrab(false); q->setKeepTouchGrab(false); + + if (!qFuzzyCompare(pressedNode->position(), oldPos)) + emit pressedNode->moved(); } pressedNode->setPressed(false); pressedNodePrivate->touchId = -1; @@ -578,6 +618,24 @@ void QQuickRangeSliderPrivate::updateHover(const QPointF &pos) second->setHovered(secondHandle && secondHandle->isEnabled() && secondHandle->contains(q->mapToItem(secondHandle, pos))); } +void QQuickRangeSliderPrivate::itemImplicitWidthChanged(QQuickItem *item) +{ + QQuickControlPrivate::itemImplicitWidthChanged(item); + if (item == first->handle()) + emit first->implicitHandleWidthChanged(); + else if (item == second->handle()) + emit second->implicitHandleWidthChanged(); +} + +void QQuickRangeSliderPrivate::itemImplicitHeightChanged(QQuickItem *item) +{ + QQuickControlPrivate::itemImplicitHeightChanged(item); + if (item == first->handle()) + emit first->implicitHandleHeightChanged(); + else if (item == second->handle()) + emit second->implicitHandleHeightChanged(); +} + QQuickRangeSlider::QQuickRangeSlider(QQuickItem *parent) : QQuickControl(*(new QQuickRangeSliderPrivate), parent) { @@ -592,6 +650,13 @@ QQuickRangeSlider::QQuickRangeSlider(QQuickItem *parent) #endif } +QQuickRangeSlider::~QQuickRangeSlider() +{ + Q_D(QQuickRangeSlider); + d->removeImplicitSizeListener(d->first->handle()); + d->removeImplicitSizeListener(d->second->handle()); +} + /*! \qmlproperty real QtQuick.Controls::RangeSlider::from @@ -649,6 +714,55 @@ void QQuickRangeSlider::setTo(qreal to) } /*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty qreal QtQuick.Controls::RangeSlider::touchDragThreshold + + This property holds the threshold (in logical pixels) at which a touch drag event will be initiated. + The mouse drag threshold won't be affected. + The default value is \c Qt.styleHints.startDragDistance. + + \sa QStyleHints + +*/ +qreal QQuickRangeSlider::touchDragThreshold() const +{ + Q_D(const QQuickRangeSlider); + return d->touchDragThreshold; +} + +void QQuickRangeSlider::setTouchDragThreshold(qreal touchDragThreshold) +{ + Q_D(QQuickRangeSlider); + if (d->touchDragThreshold == touchDragThreshold) + return; + + d->touchDragThreshold = touchDragThreshold; + emit touchDragThresholdChanged(); +} + +void QQuickRangeSlider::resetTouchDragThreshold() +{ + setTouchDragThreshold(-1); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlmethod real QtQuick.Controls::RangeSlider::valueAt(real position) + + Returns the value for the given \a position. + + \sa first.value, second.value, first.position, second.position, live +*/ +qreal QQuickRangeSlider::valueAt(qreal position) const +{ + Q_D(const QQuickRangeSlider); + const qreal value = (d->to - d->from) * position; + if (qFuzzyIsNull(d->stepSize)) + return d->from + value; + return d->from + qRound(value / d->stepSize) * d->stepSize; +} + +/*! \qmlpropertygroup QtQuick.Controls::RangeSlider::first \qmlproperty real QtQuick.Controls::RangeSlider::first.value \qmlproperty real QtQuick.Controls::RangeSlider::first.position @@ -656,6 +770,9 @@ void QQuickRangeSlider::setTo(qreal to) \qmlproperty Item QtQuick.Controls::RangeSlider::first.handle \qmlproperty bool QtQuick.Controls::RangeSlider::first.pressed \qmlproperty bool QtQuick.Controls::RangeSlider::first.hovered + \qmlproperty real QtQuick.Controls::RangeSlider::first.implicitHandleWidth + \qmlproperty real QtQuick.Controls::RangeSlider::first.implicitHandleHeight + \qmlsignal void QtQuick.Controls::RangeSlider::moved() \table \header @@ -696,6 +813,20 @@ void QQuickRangeSlider::setTo(qreal to) \li hovered \li This property holds whether the first handle is hovered. This property was introduced in QtQuick.Controls 2.1. + \row + \li implicitHandleWidth + \li This property holds the implicit width of the first handle. + This property was introduced in QtQuick.Controls 2.5. + \row + \li implicitHandleHeight + \li This property holds the implicit height of the first handle. + This property was introduced in QtQuick.Controls 2.5. + \row + \li moved() + \li This signal is emitted when the first handle has been interactively moved + by the user by either touch, mouse, or keys. + + This signal was introduced in QtQuick.Controls 2.5. \endtable \sa first.increase(), first.decrease() @@ -714,6 +845,9 @@ QQuickRangeSliderNode *QQuickRangeSlider::first() const \qmlproperty Item QtQuick.Controls::RangeSlider::second.handle \qmlproperty bool QtQuick.Controls::RangeSlider::second.pressed \qmlproperty bool QtQuick.Controls::RangeSlider::second.hovered + \qmlproperty real QtQuick.Controls::RangeSlider::second.implicitHandleWidth + \qmlproperty real QtQuick.Controls::RangeSlider::second.implicitHandleHeight + \qmlsignal void QtQuick.Controls::RangeSlider::moved() \table \header @@ -754,6 +888,20 @@ QQuickRangeSliderNode *QQuickRangeSlider::first() const \li hovered \li This property holds whether the second handle is hovered. This property was introduced in QtQuick.Controls 2.1. + \row + \li implicitHandleWidth + \li This property holds the implicit width of the second handle. + This property was introduced in QtQuick.Controls 2.5. + \row + \li implicitHandleHeight + \li This property holds the implicit height of the second handle. + This property was introduced in QtQuick.Controls 2.5. + \row + \li moved() + \li This signal is emitted when the second handle has been interactively moved + by the user by either touch, mouse, or keys. + + This signal was introduced in QtQuick.Controls 2.5. \endtable \sa second.increase(), second.decrease() @@ -990,6 +1138,7 @@ void QQuickRangeSlider::keyPressEvent(QKeyEvent *event) if (!focusNode) return; + const qreal oldValue = focusNode->value(); if (d->orientation == Qt::Horizontal) { if (event->key() == Qt::Key_Left) { focusNode->setPressed(true); @@ -1017,6 +1166,8 @@ void QQuickRangeSlider::keyPressEvent(QKeyEvent *event) event->accept(); } } + if (!qFuzzyCompare(focusNode->value(), oldValue)) + emit focusNode->moved(); } void QQuickRangeSlider::hoverEnterEvent(QHoverEvent *event) @@ -1074,9 +1225,9 @@ void QQuickRangeSlider::touchEvent(QTouchEvent *event) case Qt::TouchPointMoved: if (!keepTouchGrab()) { if (d->orientation == Qt::Horizontal) - setKeepTouchGrab(QQuickWindowPrivate::dragOverThreshold(point.pos().x() - point.startPos().x(), Qt::XAxis, &point)); + setKeepTouchGrab(QQuickWindowPrivate::dragOverThreshold(point.pos().x() - point.startPos().x(), Qt::XAxis, &point, qRound(d->touchDragThreshold))); else - setKeepTouchGrab(QQuickWindowPrivate::dragOverThreshold(point.pos().y() - point.startPos().y(), Qt::YAxis, &point)); + setKeepTouchGrab(QQuickWindowPrivate::dragOverThreshold(point.pos().y() - point.startPos().y(), Qt::YAxis, &point, qRound(d->touchDragThreshold))); } if (keepTouchGrab()) d->handleMove(point.pos()); diff --git a/src/quicktemplates2/qquickrangeslider_p.h b/src/quicktemplates2/qquickrangeslider_p.h index 45de6bbb..a42245a1 100644 --- a/src/quicktemplates2/qquickrangeslider_p.h +++ b/src/quicktemplates2/qquickrangeslider_p.h @@ -70,9 +70,12 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickRangeSlider : public QQuickControl Q_PROPERTY(bool horizontal READ isHorizontal NOTIFY orientationChanged FINAL REVISION 3) // 2.3 (Qt 5.10) Q_PROPERTY(bool vertical READ isVertical NOTIFY orientationChanged FINAL REVISION 3) + // 2.5 (Qt 5.12) + Q_PROPERTY(qreal touchDragThreshold READ touchDragThreshold WRITE setTouchDragThreshold RESET resetTouchDragThreshold NOTIFY touchDragThresholdChanged FINAL REVISION 5) public: explicit QQuickRangeSlider(QQuickItem *parent = nullptr); + ~QQuickRangeSlider(); qreal from() const; void setFrom(qreal from); @@ -109,6 +112,12 @@ public: bool isHorizontal() const; bool isVertical() const; + // 2.5 (Qt 5.12) + qreal touchDragThreshold() const; + void setTouchDragThreshold(qreal touchDragThreshold); + void resetTouchDragThreshold(); + Q_REVISION(5) Q_INVOKABLE qreal valueAt(qreal position) const; + Q_SIGNALS: void fromChanged(); void toChanged(); @@ -117,6 +126,8 @@ Q_SIGNALS: void orientationChanged(); // 2.2 (Qt 5.9) Q_REVISION(2) void liveChanged(); + // 2.5 (Qt 5.12) + Q_REVISION(5) void touchDragThresholdChanged(); protected: void focusInEvent(QFocusEvent *event) override; @@ -156,6 +167,9 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickRangeSliderNode : public QObject Q_PROPERTY(bool pressed READ isPressed WRITE setPressed NOTIFY pressedChanged FINAL) // 2.1 (Qt 5.8) Q_PROPERTY(bool hovered READ isHovered WRITE setHovered NOTIFY hoveredChanged FINAL REVISION 1) + // 2.5 (Qt 5.12) + Q_PROPERTY(qreal implicitHandleWidth READ implicitHandleWidth NOTIFY implicitHandleWidthChanged FINAL REVISION 5) + Q_PROPERTY(qreal implicitHandleHeight READ implicitHandleHeight NOTIFY implicitHandleHeightChanged FINAL REVISION 5) Q_CLASSINFO("DeferredPropertyNames", "handle") public: @@ -178,6 +192,10 @@ public: bool isHovered() const; void setHovered(bool hovered); + // 2.5 (Qt 5.12) + qreal implicitHandleWidth() const; + qreal implicitHandleHeight() const; + public Q_SLOTS: void increase(); void decrease(); @@ -190,6 +208,10 @@ Q_SIGNALS: void pressedChanged(); // 2.1 (Qt 5.8) Q_REVISION(1) void hoveredChanged(); + // 2.5 (Qt 5.12) + /*Q_REVISION(5)*/ void moved(); + /*Q_REVISION(5)*/ void implicitHandleWidthChanged(); + /*Q_REVISION(5)*/ void implicitHandleHeightChanged(); private: Q_DISABLE_COPY(QQuickRangeSliderNode) diff --git a/src/quicktemplates2/qquickscrollview.cpp b/src/quicktemplates2/qquickscrollview.cpp index 30750aa8..c4ca2caa 100644 --- a/src/quicktemplates2/qquickscrollview.cpp +++ b/src/quicktemplates2/qquickscrollview.cpp @@ -35,7 +35,7 @@ ****************************************************************************/ #include "qquickscrollview_p.h" -#include "qquickcontrol_p_p.h" +#include "qquickpane_p_p.h" #include "qquickscrollbar_p_p.h" #include <QtQuick/private/qquickflickable_p.h> @@ -44,7 +44,7 @@ QT_BEGIN_NAMESPACE /*! \qmltype ScrollView - \inherits Control + \inherits Pane \instantiates QQuickScrollView \inqmlmodule QtQuick.Controls \since 5.9 @@ -101,13 +101,17 @@ QT_BEGIN_NAMESPACE {Focus Management in Qt Quick Controls 2} */ -class QQuickScrollViewPrivate : public QQuickControlPrivate +class QQuickScrollViewPrivate : public QQuickPanePrivate { Q_DECLARE_PUBLIC(QQuickScrollView) public: QQuickScrollViewPrivate(); + QQmlListProperty<QObject> contentData() override; + QQmlListProperty<QQuickItem> contentChildren() override; + QList<QQuickItem *> contentChildItems() const override; + QQuickItem *getContentItem() override; QQuickFlickable *ensureFlickable(bool content); @@ -131,21 +135,29 @@ public: static QQuickItem *contentChildren_at(QQmlListProperty<QQuickItem> *prop, int index); static void contentChildren_clear(QQmlListProperty<QQuickItem> *prop); + void itemImplicitWidthChanged(QQuickItem *item) override; + bool wasTouched; - qreal contentWidth; - qreal contentHeight; QQuickFlickable *flickable; }; QQuickScrollViewPrivate::QQuickScrollViewPrivate() : wasTouched(false), - contentWidth(-1), - contentHeight(-1), flickable(nullptr) { + contentWidth = -1; + contentHeight = -1; wheelEnabled = true; } +QList<QQuickItem *> QQuickScrollViewPrivate::contentChildItems() const +{ + if (!flickable) + return QList<QQuickItem *>(); + + return flickable->contentItem()->childItems(); +} + QQuickItem *QQuickScrollViewPrivate::getContentItem() { if (!contentItem) @@ -175,7 +187,7 @@ bool QQuickScrollViewPrivate::setFlickable(QQuickFlickable *item, bool content) if (attached) QQuickScrollBarAttachedPrivate::get(attached)->setFlickable(nullptr); - QObject::disconnect(flickable->contentItem(), &QQuickItem::childrenChanged, q, &QQuickScrollView::contentChildrenChanged); + QObjectPrivate::disconnect(flickable->contentItem(), &QQuickItem::childrenChanged, this, &QQuickPanePrivate::contentChildrenChange); QObjectPrivate::disconnect(flickable, &QQuickFlickable::contentWidthChanged, this, &QQuickScrollViewPrivate::updateContentWidth); QObjectPrivate::disconnect(flickable, &QQuickFlickable::contentHeightChanged, this, &QQuickScrollViewPrivate::updateContentHeight); } @@ -186,19 +198,19 @@ bool QQuickScrollViewPrivate::setFlickable(QQuickFlickable *item, bool content) if (flickable) { flickable->installEventFilter(q); - if (contentWidth > 0) - item->setContentWidth(contentWidth); + if (hasContentWidth) + flickable->setContentWidth(contentWidth); else updateContentWidth(); - if (contentHeight > 0) - item->setContentHeight(contentHeight); + if (hasContentHeight) + flickable->setContentHeight(contentHeight); else updateContentHeight(); if (attached) QQuickScrollBarAttachedPrivate::get(attached)->setFlickable(flickable); - QObject::connect(flickable->contentItem(), &QQuickItem::childrenChanged, q, &QQuickScrollView::contentChildrenChanged); + QObjectPrivate::connect(flickable->contentItem(), &QQuickItem::childrenChanged, this, &QQuickPanePrivate::contentChildrenChange); QObjectPrivate::connect(flickable, &QQuickFlickable::contentWidthChanged, this, &QQuickScrollViewPrivate::updateContentWidth); QObjectPrivate::connect(flickable, &QQuickFlickable::contentHeightChanged, this, &QQuickScrollViewPrivate::updateContentHeight); } @@ -213,11 +225,11 @@ void QQuickScrollViewPrivate::updateContentWidth() return; const qreal cw = flickable->contentWidth(); - if (qFuzzyCompare(cw, contentWidth)) + if (qFuzzyCompare(cw, implicitContentWidth)) return; - contentWidth = cw; - emit q->contentWidthChanged(); + implicitContentWidth = cw; + emit q->implicitContentWidthChanged(); } void QQuickScrollViewPrivate::updateContentHeight() @@ -227,11 +239,11 @@ void QQuickScrollViewPrivate::updateContentHeight() return; const qreal ch = flickable->contentHeight(); - if (qFuzzyCompare(ch, contentHeight)) + if (qFuzzyCompare(ch, implicitContentHeight)) return; - contentHeight = ch; - emit q->contentHeightChanged(); + implicitContentHeight = ch; + emit q->implicitContentHeightChanged(); } QQuickScrollBar *QQuickScrollViewPrivate::verticalScrollBar() const @@ -353,72 +365,20 @@ void QQuickScrollViewPrivate::contentChildren_clear(QQmlListProperty<QQuickItem> children.clear(&children); } -QQuickScrollView::QQuickScrollView(QQuickItem *parent) - : QQuickControl(*(new QQuickScrollViewPrivate), parent) -{ - setFlag(ItemIsFocusScope); - setActiveFocusOnTab(true); - setFiltersChildMouseEvents(true); -} - -/*! - \qmlproperty real QtQuick.Controls::ScrollView::contentWidth - - This property holds the width of the scrollable content. - - If only a single item is used within a ScrollView, the content size is - automatically calculated based on the implicit size of its contained item. - - \sa contentHeight -*/ -qreal QQuickScrollView::contentWidth() const +void QQuickScrollViewPrivate::itemImplicitWidthChanged(QQuickItem *item) { - Q_D(const QQuickScrollView); - return d->contentWidth; -} - -void QQuickScrollView::setContentWidth(qreal width) -{ - Q_D(QQuickScrollView); - if (qFuzzyCompare(d->contentWidth, width)) + // a special case for width<->height dependent content (wrapping text) in ScrollView + if (contentWidth < 0 && !componentComplete) return; - if (d->flickable) { - d->flickable->setContentWidth(width); - } else { - d->contentWidth = width; - emit contentWidthChanged(); - } -} - -/*! - \qmlproperty real QtQuick.Controls::ScrollView::contentHeight - - This property holds the height of the scrollable content. - - If only a single item is used within a ScrollView, the content size is - automatically calculated based on the implicit size of its contained item. - - \sa contentWidth -*/ -qreal QQuickScrollView::contentHeight() const -{ - Q_D(const QQuickScrollView); - return d->contentHeight; + QQuickPanePrivate::itemImplicitWidthChanged(item); } -void QQuickScrollView::setContentHeight(qreal height) +QQuickScrollView::QQuickScrollView(QQuickItem *parent) + : QQuickPane(*(new QQuickScrollViewPrivate), parent) { - Q_D(QQuickScrollView); - if (qFuzzyCompare(d->contentHeight, height)) - return; - - if (d->flickable) { - d->flickable->setContentHeight(height); - } else { - d->contentHeight = height; - emit contentHeightChanged(); - } + setActiveFocusOnTab(true); + setFiltersChildMouseEvents(true); } /*! @@ -433,10 +393,10 @@ void QQuickScrollView::setContentHeight(qreal height) \sa Item::data, contentChildren */ -QQmlListProperty<QObject> QQuickScrollView::contentData() +QQmlListProperty<QObject> QQuickScrollViewPrivate::contentData() { - Q_D(QQuickScrollView); - return QQmlListProperty<QObject>(this, d, + Q_Q(QQuickScrollView); + return QQmlListProperty<QObject>(q, this, QQuickScrollViewPrivate::contentData_append, QQuickScrollViewPrivate::contentData_count, QQuickScrollViewPrivate::contentData_at, @@ -454,10 +414,10 @@ QQmlListProperty<QObject> QQuickScrollView::contentData() \sa Item::children, contentData */ -QQmlListProperty<QQuickItem> QQuickScrollView::contentChildren() +QQmlListProperty<QQuickItem> QQuickScrollViewPrivate::contentChildren() { - Q_D(QQuickScrollView); - return QQmlListProperty<QQuickItem>(this, d, + Q_Q(QQuickScrollView); + return QQmlListProperty<QQuickItem>(q, this, QQuickScrollViewPrivate::contentChildren_append, QQuickScrollViewPrivate::contentChildren_count, QQuickScrollViewPrivate::contentChildren_at, @@ -513,13 +473,13 @@ bool QQuickScrollView::eventFilter(QObject *object, QEvent *event) if (!d->wheelEnabled) return true; } - return QQuickControl::eventFilter(object, event); + return QQuickPane::eventFilter(object, event); } void QQuickScrollView::keyPressEvent(QKeyEvent *event) { Q_D(QQuickScrollView); - QQuickControl::keyPressEvent(event); + QQuickPane::keyPressEvent(event); switch (event->key()) { case Qt::Key_Up: if (QQuickScrollBar *vbar = d->verticalScrollBar()) { @@ -554,22 +514,26 @@ void QQuickScrollView::keyPressEvent(QKeyEvent *event) void QQuickScrollView::componentComplete() { Q_D(QQuickScrollView); - QQuickControl::componentComplete(); - if (!d->contentItem) { + QQuickPane::componentComplete(); + if (!d->contentItem) d->ensureFlickable(true); - } else { - if (d->contentWidth <= 0) - d->updateContentWidth(); - if (d->contentHeight <= 0) - d->updateContentHeight(); - } } void QQuickScrollView::contentItemChange(QQuickItem *newItem, QQuickItem *oldItem) { Q_D(QQuickScrollView); - QQuickControl::contentItemChange(newItem, oldItem); d->setFlickable(qobject_cast<QQuickFlickable *>(newItem), false); + QQuickPane::contentItemChange(newItem, oldItem); +} + +void QQuickScrollView::contentSizeChange(const QSizeF &newSize, const QSizeF &oldSize) +{ + Q_D(QQuickScrollView); + QQuickPane::contentSizeChange(newSize, oldSize); + if (d->flickable) { + d->flickable->setContentWidth(newSize.width()); + d->flickable->setContentHeight(newSize.height()); + } } #if QT_CONFIG(accessibility) @@ -580,3 +544,5 @@ QAccessible::Role QQuickScrollView::accessibleRole() const #endif QT_END_NAMESPACE + +#include "moc_qquickscrollview_p.cpp" diff --git a/src/quicktemplates2/qquickscrollview_p.h b/src/quicktemplates2/qquickscrollview_p.h index 136260c2..2b8d260e 100644 --- a/src/quicktemplates2/qquickscrollview_p.h +++ b/src/quicktemplates2/qquickscrollview_p.h @@ -48,39 +48,20 @@ // We mean it. // -#include <QtQuickTemplates2/private/qquickcontrol_p.h> +#include <QtQuickTemplates2/private/qquickpane_p.h> #include <QtQml/qqmllist.h> QT_BEGIN_NAMESPACE class QQuickScrollViewPrivate; -class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickScrollView : public QQuickControl +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickScrollView : public QQuickPane { Q_OBJECT - Q_PROPERTY(qreal contentWidth READ contentWidth WRITE setContentWidth NOTIFY contentWidthChanged FINAL) - Q_PROPERTY(qreal contentHeight READ contentHeight WRITE setContentHeight NOTIFY contentHeightChanged FINAL) - Q_PROPERTY(QQmlListProperty<QObject> contentData READ contentData FINAL) - Q_PROPERTY(QQmlListProperty<QQuickItem> contentChildren READ contentChildren NOTIFY contentChildrenChanged FINAL) - Q_CLASSINFO("DefaultProperty", "contentData") public: explicit QQuickScrollView(QQuickItem *parent = nullptr); - qreal contentWidth() const; - void setContentWidth(qreal width); - - qreal contentHeight() const; - void setContentHeight(qreal height); - - QQmlListProperty<QObject> contentData(); - QQmlListProperty<QQuickItem> contentChildren(); - -Q_SIGNALS: - void contentWidthChanged(); - void contentHeightChanged(); - void contentChildrenChanged(); - protected: bool childMouseEventFilter(QQuickItem *item, QEvent *event) override; bool eventFilter(QObject *object, QEvent *event) override; @@ -88,6 +69,7 @@ protected: void componentComplete() override; void contentItemChange(QQuickItem *newItem, QQuickItem *oldItem) override; + void contentSizeChange(const QSizeF &newSize, const QSizeF &oldSize) override; #if QT_CONFIG(accessibility) QAccessible::Role accessibleRole() const override; diff --git a/src/quicktemplates2/qquickslider.cpp b/src/quicktemplates2/qquickslider.cpp index e9717368..1e6e0c25 100644 --- a/src/quicktemplates2/qquickslider.cpp +++ b/src/quicktemplates2/qquickslider.cpp @@ -98,6 +98,7 @@ public: value(0), position(0), stepSize(0), + touchDragThreshold(-1), // in QQuickWindowPrivate::dragOverThreshold, '-1' implies using styleHints::startDragDistance() live(true), pressed(false), orientation(Qt::Horizontal), @@ -119,11 +120,15 @@ public: void cancelHandle(); void executeHandle(bool complete = false); + void itemImplicitWidthChanged(QQuickItem *item) override; + void itemImplicitHeightChanged(QQuickItem *item) override; + qreal from; qreal to; qreal value; qreal position; qreal stepSize; + qreal touchDragThreshold; bool live; bool pressed; QPointF pressPoint; @@ -262,6 +267,22 @@ void QQuickSliderPrivate::executeHandle(bool complete) quickCompleteDeferred(q, handleName(), handle); } +void QQuickSliderPrivate::itemImplicitWidthChanged(QQuickItem *item) +{ + Q_Q(QQuickSlider); + QQuickControlPrivate::itemImplicitWidthChanged(item); + if (item == handle) + emit q->implicitHandleWidthChanged(); +} + +void QQuickSliderPrivate::itemImplicitHeightChanged(QQuickItem *item) +{ + Q_Q(QQuickSlider); + QQuickControlPrivate::itemImplicitHeightChanged(item); + if (item == handle) + emit q->implicitHandleHeightChanged(); +} + QQuickSlider::QQuickSlider(QQuickItem *parent) : QQuickControl(*(new QQuickSliderPrivate), parent) { @@ -273,6 +294,12 @@ QQuickSlider::QQuickSlider(QQuickItem *parent) #endif } +QQuickSlider::~QQuickSlider() +{ + Q_D(QQuickSlider); + d->removeImplicitSizeListener(d->handle); +} + /*! \qmlproperty real QtQuick.Controls::Slider::from @@ -563,10 +590,23 @@ void QQuickSlider::setHandle(QQuickItem *handle) if (!d->handle.isExecuting()) d->cancelHandle(); + const qreal oldImplicitHandleWidth = implicitHandleWidth(); + const qreal oldImplicitHandleHeight = implicitHandleHeight(); + + d->removeImplicitSizeListener(d->handle); delete d->handle; d->handle = handle; - if (handle && !handle->parentItem()) - handle->setParentItem(this); + + if (handle) { + if (!handle->parentItem()) + handle->setParentItem(this); + d->addImplicitSizeListener(handle); + } + + if (!qFuzzyCompare(oldImplicitHandleWidth, implicitHandleWidth())) + emit implicitHandleWidthChanged(); + if (!qFuzzyCompare(oldImplicitHandleHeight, implicitHandleHeight())) + emit implicitHandleHeightChanged(); if (!d->handle.isExecuting()) emit handleChanged(); } @@ -643,6 +683,81 @@ void QQuickSlider::decrease() setValue(d->value - step); } +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty qreal QtQuick.Controls::Slider::touchDragThreshold + + This property holds the threshold (in logical pixels) at which a touch drag event will be initiated. + The mouse drag threshold won't be affected. + The default value is \c Qt.styleHints.startDragDistance. + + \sa QStyleHints +*/ +qreal QQuickSlider::touchDragThreshold() const +{ + Q_D(const QQuickSlider); + return d->touchDragThreshold; +} + +void QQuickSlider::setTouchDragThreshold(qreal touchDragThreshold) +{ + Q_D(QQuickSlider); + if (d->touchDragThreshold == touchDragThreshold) + return; + + d->touchDragThreshold = touchDragThreshold; + emit touchDragThresholdChanged(); +} + +void QQuickSlider::resetTouchDragThreshold() +{ + setTouchDragThreshold(-1); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::Slider::implicitHandleWidth + \readonly + + This property holds the implicit handle width. + + The value is equal to \c {handle ? handle.implicitWidth : 0}. + + This is typically used, together with \l {Control::}{implicitContentWidth} and + \l {Control::}{implicitBackgroundWidth}, to calculate the \l {Item::}{implicitWidth}. + + \sa implicitHandleHeight +*/ +qreal QQuickSlider::implicitHandleWidth() const +{ + Q_D(const QQuickSlider); + if (!d->handle) + return 0; + return d->handle->implicitWidth(); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlproperty real QtQuick.Controls::Slider::implicitHandleHeight + \readonly + + This property holds the implicit handle height. + + The value is equal to \c {handle ? handle.implicitHeight : 0}. + + This is typically used, together with \l {Control::}{implicitContentHeight} and + \l {Control::}{implicitBackgroundHeight}, to calculate the \l {Item::}{implicitHeight}. + + \sa implicitHandleWidth +*/ +qreal QQuickSlider::implicitHandleHeight() const +{ + Q_D(const QQuickSlider); + if (!d->handle) + return 0; + return d->handle->implicitHeight(); +} + void QQuickSlider::keyPressEvent(QKeyEvent *event) { Q_D(QQuickSlider); @@ -711,9 +826,9 @@ void QQuickSlider::touchEvent(QTouchEvent *event) case Qt::TouchPointMoved: if (!keepTouchGrab()) { if (d->orientation == Qt::Horizontal) - setKeepTouchGrab(QQuickWindowPrivate::dragOverThreshold(point.pos().x() - d->pressPoint.x(), Qt::XAxis, &point)); + setKeepTouchGrab(QQuickWindowPrivate::dragOverThreshold(point.pos().x() - d->pressPoint.x(), Qt::XAxis, &point, qRound(d->touchDragThreshold))); else - setKeepTouchGrab(QQuickWindowPrivate::dragOverThreshold(point.pos().y() - d->pressPoint.y(), Qt::YAxis, &point)); + setKeepTouchGrab(QQuickWindowPrivate::dragOverThreshold(point.pos().y() - d->pressPoint.y(), Qt::YAxis, &point, qRound(d->touchDragThreshold))); } if (keepTouchGrab()) d->handleMove(point.pos()); diff --git a/src/quicktemplates2/qquickslider_p.h b/src/quicktemplates2/qquickslider_p.h index ee6bcffa..c65733dc 100644 --- a/src/quicktemplates2/qquickslider_p.h +++ b/src/quicktemplates2/qquickslider_p.h @@ -71,10 +71,15 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickSlider : public QQuickControl // 2.3 (Qt 5.10) Q_PROPERTY(bool horizontal READ isHorizontal NOTIFY orientationChanged FINAL REVISION 3) Q_PROPERTY(bool vertical READ isVertical NOTIFY orientationChanged FINAL REVISION 3) + // 2.5 (Qt 5.12) + Q_PROPERTY(qreal touchDragThreshold READ touchDragThreshold WRITE setTouchDragThreshold RESET resetTouchDragThreshold NOTIFY touchDragThresholdChanged FINAL REVISION 5) + Q_PROPERTY(qreal implicitHandleWidth READ implicitHandleWidth NOTIFY implicitHandleWidthChanged FINAL REVISION 5) + Q_PROPERTY(qreal implicitHandleHeight READ implicitHandleHeight NOTIFY implicitHandleHeightChanged FINAL REVISION 5) Q_CLASSINFO("DeferredPropertyNames", "background,handle") public: explicit QQuickSlider(QQuickItem *parent = nullptr); + ~QQuickSlider(); qreal from() const; void setFrom(qreal from); @@ -121,6 +126,14 @@ public: bool isHorizontal() const; bool isVertical() const; + // 2.5 (Qt 5.12) + qreal touchDragThreshold() const; + void setTouchDragThreshold(qreal touchDragThreshold); + void resetTouchDragThreshold(); + + qreal implicitHandleWidth() const; + qreal implicitHandleHeight() const; + public Q_SLOTS: void increase(); void decrease(); @@ -139,6 +152,10 @@ Q_SIGNALS: // 2.2 (Qt 5.9) Q_REVISION(2) void moved(); Q_REVISION(2) void liveChanged(); + // 2.5 (Qt 5.12) + Q_REVISION(5) void touchDragThresholdChanged(); + Q_REVISION(5) void implicitHandleWidthChanged(); + Q_REVISION(5) void implicitHandleHeightChanged(); protected: void keyPressEvent(QKeyEvent *event) override; diff --git a/src/quicktemplates2/qquickspinbox.cpp b/src/quicktemplates2/qquickspinbox.cpp index 7412936c..c5bde74e 100644 --- a/src/quicktemplates2/qquickspinbox.cpp +++ b/src/quicktemplates2/qquickspinbox.cpp @@ -151,6 +151,9 @@ public: void handleRelease(const QPointF &point) override; void handleUngrab() override; + void itemImplicitWidthChanged(QQuickItem *item) override; + void itemImplicitHeightChanged(QQuickItem *item) override; + bool editable; bool wrap; int from; @@ -426,6 +429,24 @@ void QQuickSpinBoxPrivate::handleUngrab() stopPressRepeat(); } +void QQuickSpinBoxPrivate::itemImplicitWidthChanged(QQuickItem *item) +{ + QQuickControlPrivate::itemImplicitWidthChanged(item); + if (item == up->indicator()) + emit up->implicitIndicatorWidthChanged(); + else if (item == down->indicator()) + emit down->implicitIndicatorWidthChanged(); +} + +void QQuickSpinBoxPrivate::itemImplicitHeightChanged(QQuickItem *item) +{ + QQuickControlPrivate::itemImplicitHeightChanged(item); + if (item == up->indicator()) + emit up->implicitIndicatorHeightChanged(); + else if (item == down->indicator()) + emit down->implicitIndicatorHeightChanged(); +} + QQuickSpinBox::QQuickSpinBox(QQuickItem *parent) : QQuickControl(*(new QQuickSpinBoxPrivate), parent) { @@ -441,6 +462,13 @@ QQuickSpinBox::QQuickSpinBox(QQuickItem *parent) #endif } +QQuickSpinBox::~QQuickSpinBox() +{ + Q_D(QQuickSpinBox); + d->removeImplicitSizeListener(d->up->indicator()); + d->removeImplicitSizeListener(d->down->indicator()); +} + /*! \qmlproperty int QtQuick.Controls::SpinBox::from @@ -711,9 +739,13 @@ void QQuickSpinBox::setValueFromText(const QJSValue &callback) \qmlproperty bool QtQuick.Controls::SpinBox::up.pressed \qmlproperty Item QtQuick.Controls::SpinBox::up.indicator \qmlproperty bool QtQuick.Controls::SpinBox::up.hovered + \qmlproperty real QtQuick.Controls::SpinBox::up.implicitIndicatorWidth + \qmlproperty real QtQuick.Controls::SpinBox::up.implicitIndicatorHeight These properties hold the up indicator item and whether it is pressed or - hovered. The \c up.hovered property was introduced in QtQuick.Controls 2.1. + hovered. The \c up.hovered property was introduced in QtQuick.Controls 2.1, + and the \c up.implicitIndicatorWidth and \c up.implicitIndicatorHeight + properties were introduced in QtQuick.Controls 2.5. \sa increase() */ @@ -728,9 +760,13 @@ QQuickSpinButton *QQuickSpinBox::up() const \qmlproperty bool QtQuick.Controls::SpinBox::down.pressed \qmlproperty Item QtQuick.Controls::SpinBox::down.indicator \qmlproperty bool QtQuick.Controls::SpinBox::down.hovered + \qmlproperty real QtQuick.Controls::SpinBox::down.implicitIndicatorWidth + \qmlproperty real QtQuick.Controls::SpinBox::down.implicitIndicatorHeight These properties hold the down indicator item and whether it is pressed or - hovered. The \c down.hovered property was introduced in QtQuick.Controls 2.1. + hovered. The \c down.hovered property was introduced in QtQuick.Controls 2.1, + and the \c down.implicitIndicatorWidth and \c down.implicitIndicatorHeight + properties were introduced in QtQuick.Controls 2.5. \sa decrease() */ @@ -1023,12 +1059,12 @@ void QQuickSpinBox::localeChange(const QLocale &newLocale, const QLocale &oldLoc QFont QQuickSpinBox::defaultFont() const { - return QQuickControlPrivate::themeFont(QPlatformTheme::EditorFont); + return QQuickTheme::themeFont(QQuickTheme::SpinBox); } QPalette QQuickSpinBox::defaultPalette() const { - return QQuickControlPrivate::themePalette(QPlatformTheme::TextLineEditPalette); + return QQuickTheme::themePalette(QQuickTheme::SpinBox); } #if QT_CONFIG(accessibility) @@ -1105,13 +1141,24 @@ void QQuickSpinButton::setIndicator(QQuickItem *indicator) if (!d->indicator.isExecuting()) d->cancelIndicator(); + const qreal oldImplicitIndicatorWidth = implicitIndicatorWidth(); + const qreal oldImplicitIndicatorHeight = implicitIndicatorHeight(); + + QQuickSpinBox *spinBox = static_cast<QQuickSpinBox *>(parent()); + QQuickSpinBoxPrivate::get(spinBox)->removeImplicitSizeListener(d->indicator); delete d->indicator; d->indicator = indicator; if (indicator) { if (!indicator->parentItem()) - indicator->setParentItem(static_cast<QQuickItem *>(parent())); + indicator->setParentItem(spinBox); + QQuickSpinBoxPrivate::get(spinBox)->addImplicitSizeListener(indicator); } + + if (!qFuzzyCompare(oldImplicitIndicatorWidth, implicitIndicatorWidth())) + emit implicitIndicatorWidthChanged(); + if (!qFuzzyCompare(oldImplicitIndicatorHeight, implicitIndicatorHeight())) + emit implicitIndicatorHeightChanged(); if (!d->indicator.isExecuting()) emit indicatorChanged(); } @@ -1132,4 +1179,20 @@ void QQuickSpinButton::setHovered(bool hovered) emit hoveredChanged(); } +qreal QQuickSpinButton::implicitIndicatorWidth() const +{ + Q_D(const QQuickSpinButton); + if (!d->indicator) + return 0; + return d->indicator->implicitWidth(); +} + +qreal QQuickSpinButton::implicitIndicatorHeight() const +{ + Q_D(const QQuickSpinButton); + if (!d->indicator) + return 0; + return d->indicator->implicitHeight(); +} + QT_END_NAMESPACE diff --git a/src/quicktemplates2/qquickspinbox_p.h b/src/quicktemplates2/qquickspinbox_p.h index f5370331..4a339b76 100644 --- a/src/quicktemplates2/qquickspinbox_p.h +++ b/src/quicktemplates2/qquickspinbox_p.h @@ -81,6 +81,7 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickSpinBox : public QQuickControl public: explicit QQuickSpinBox(QQuickItem *parent = nullptr); + ~QQuickSpinBox(); int from() const; void setFrom(int from); @@ -182,6 +183,9 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickSpinButton : public QObject Q_PROPERTY(QQuickItem *indicator READ indicator WRITE setIndicator NOTIFY indicatorChanged FINAL) // 2.1 (Qt 5.8) Q_PROPERTY(bool hovered READ isHovered WRITE setHovered NOTIFY hoveredChanged FINAL REVISION 1) + // 2.5 (Qt 5.12) + Q_PROPERTY(qreal implicitIndicatorWidth READ implicitIndicatorWidth NOTIFY implicitIndicatorWidthChanged FINAL REVISION 5) + Q_PROPERTY(qreal implicitIndicatorHeight READ implicitIndicatorHeight NOTIFY implicitIndicatorHeightChanged FINAL REVISION 5) Q_CLASSINFO("DeferredPropertyNames", "indicator") public: @@ -197,11 +201,18 @@ public: bool isHovered() const; void setHovered(bool hovered); + // 2.5 (Qt 5.12) + qreal implicitIndicatorWidth() const; + qreal implicitIndicatorHeight() const; + Q_SIGNALS: void pressedChanged(); void indicatorChanged(); // 2.1 (Qt 5.8) Q_REVISION(1) void hoveredChanged(); + // 2.5 (Qt 5.12) + Q_REVISION(5) void implicitIndicatorWidthChanged(); + Q_REVISION(5) void implicitIndicatorHeightChanged(); private: Q_DISABLE_COPY(QQuickSpinButton) diff --git a/src/quicktemplates2/qquickswipedelegate.cpp b/src/quicktemplates2/qquickswipedelegate.cpp index dcf93437..ed6da9dc 100644 --- a/src/quicktemplates2/qquickswipedelegate.cpp +++ b/src/quicktemplates2/qquickswipedelegate.cpp @@ -1217,12 +1217,19 @@ void QQuickSwipeDelegate::touchEvent(QTouchEvent *event) event->ignore(); } +void QQuickSwipeDelegate::componentComplete() +{ + Q_D(QQuickSwipeDelegate); + QQuickItemDelegate::componentComplete(); + QQuickSwipePrivate::get(&d->swipe)->reposition(DontAnimatePosition); +} + void QQuickSwipeDelegate::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) { Q_D(QQuickSwipeDelegate); QQuickControl::geometryChanged(newGeometry, oldGeometry); - if (!qFuzzyCompare(newGeometry.width(), oldGeometry.width())) { + if (isComponentComplete() && !qFuzzyCompare(newGeometry.width(), oldGeometry.width())) { QQuickSwipePrivate *swipePrivate = QQuickSwipePrivate::get(&d->swipe); swipePrivate->reposition(DontAnimatePosition); } @@ -1230,7 +1237,12 @@ void QQuickSwipeDelegate::geometryChanged(const QRectF &newGeometry, const QRect QFont QQuickSwipeDelegate::defaultFont() const { - return QQuickControlPrivate::themeFont(QPlatformTheme::ListViewFont); + return QQuickTheme::themeFont(QQuickTheme::ListView); +} + +QPalette QQuickSwipeDelegate::defaultPalette() const +{ + return QQuickTheme::themePalette(QQuickTheme::ListView); } #if QT_CONFIG(accessibility) diff --git a/src/quicktemplates2/qquickswipedelegate_p.h b/src/quicktemplates2/qquickswipedelegate_p.h index a9900eb8..53211ccb 100644 --- a/src/quicktemplates2/qquickswipedelegate_p.h +++ b/src/quicktemplates2/qquickswipedelegate_p.h @@ -79,9 +79,11 @@ protected: void mouseReleaseEvent(QMouseEvent *event) override; void touchEvent(QTouchEvent *event) override; + void componentComplete() override; void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) override; QFont defaultFont() const override; + QPalette defaultPalette() const override; #if QT_CONFIG(accessibility) QAccessible::Role accessibleRole() const override; diff --git a/src/quicktemplates2/qquickswipeview.cpp b/src/quicktemplates2/qquickswipeview.cpp index 60bc9477..0f3b6851 100644 --- a/src/quicktemplates2/qquickswipeview.cpp +++ b/src/quicktemplates2/qquickswipeview.cpp @@ -112,6 +112,7 @@ public: : interactive(true), orientation(Qt::Horizontal) { + changeTypes |= ImplicitWidth | ImplicitHeight; } void resizeItem(QQuickItem *item); @@ -119,6 +120,12 @@ public: static QQuickSwipeViewPrivate *get(QQuickSwipeView *view); + void itemImplicitWidthChanged(QQuickItem *item) override; + void itemImplicitHeightChanged(QQuickItem *item) override; + + qreal getContentWidth() const override; + qreal getContentHeight() const override; + bool interactive; Qt::Orientation orientation; }; @@ -177,11 +184,43 @@ QQuickSwipeViewPrivate *QQuickSwipeViewPrivate::get(QQuickSwipeView *view) return view->d_func(); } +void QQuickSwipeViewPrivate::itemImplicitWidthChanged(QQuickItem *item) +{ + Q_Q(QQuickSwipeView); + QQuickContainerPrivate::itemImplicitWidthChanged(item); + if (item == q->currentItem()) + updateImplicitContentWidth(); +} + +void QQuickSwipeViewPrivate::itemImplicitHeightChanged(QQuickItem *item) +{ + Q_Q(QQuickSwipeView); + QQuickContainerPrivate::itemImplicitHeightChanged(item); + if (item == q->currentItem()) + updateImplicitContentHeight(); +} + +qreal QQuickSwipeViewPrivate::getContentWidth() const +{ + Q_Q(const QQuickSwipeView); + QQuickItem *currentItem = q->currentItem(); + return currentItem ? currentItem->implicitWidth() : 0; +} + +qreal QQuickSwipeViewPrivate::getContentHeight() const +{ + Q_Q(const QQuickSwipeView); + QQuickItem *currentItem = q->currentItem(); + return currentItem ? currentItem->implicitHeight() : 0; +} + QQuickSwipeView::QQuickSwipeView(QQuickItem *parent) : QQuickContainer(*(new QQuickSwipeViewPrivate), parent) { + Q_D(QQuickSwipeView); setFlag(ItemIsFocusScope); setActiveFocusOnTab(true); + QObjectPrivate::connect(this, &QQuickContainer::currentItemChanged, d, &QQuickControlPrivate::updateImplicitContentSize); } /*! diff --git a/src/quicktemplates2/qquickswitch.cpp b/src/quicktemplates2/qquickswitch.cpp index da1f0408..3093b334 100644 --- a/src/quicktemplates2/qquickswitch.cpp +++ b/src/quicktemplates2/qquickswitch.cpp @@ -231,10 +231,14 @@ void QQuickSwitch::buttonChange(ButtonChange change) QQuickAbstractButton::buttonChange(change); } +QFont QQuickSwitch::defaultFont() const +{ + return QQuickTheme::themeFont(QQuickTheme::Switch); +} + QPalette QQuickSwitch::defaultPalette() const { - // ### TODO: add QPlatformTheme::SwitchPalette - return QQuickControlPrivate::themePalette(QPlatformTheme::CheckBoxPalette); + return QQuickTheme::themePalette(QQuickTheme::Switch); } QT_END_NAMESPACE diff --git a/src/quicktemplates2/qquickswitch_p.h b/src/quicktemplates2/qquickswitch_p.h index 0faaf114..ddc32395 100644 --- a/src/quicktemplates2/qquickswitch_p.h +++ b/src/quicktemplates2/qquickswitch_p.h @@ -83,6 +83,7 @@ protected: void nextCheckState() override; void buttonChange(ButtonChange change) override; + QFont defaultFont() const override; QPalette defaultPalette() const override; private: diff --git a/src/quicktemplates2/qquickswitchdelegate.cpp b/src/quicktemplates2/qquickswitchdelegate.cpp index d8ce8096..3ba859f5 100644 --- a/src/quicktemplates2/qquickswitchdelegate.cpp +++ b/src/quicktemplates2/qquickswitchdelegate.cpp @@ -202,7 +202,12 @@ void QQuickSwitchDelegate::touchEvent(QTouchEvent *event) QFont QQuickSwitchDelegate::defaultFont() const { - return QQuickControlPrivate::themeFont(QPlatformTheme::ListViewFont); + return QQuickTheme::themeFont(QQuickTheme::ListView); +} + +QPalette QQuickSwitchDelegate::defaultPalette() const +{ + return QQuickTheme::themePalette(QQuickTheme::ListView); } void QQuickSwitchDelegate::mirrorChange() diff --git a/src/quicktemplates2/qquickswitchdelegate_p.h b/src/quicktemplates2/qquickswitchdelegate_p.h index 973ec21d..1fb35aea 100644 --- a/src/quicktemplates2/qquickswitchdelegate_p.h +++ b/src/quicktemplates2/qquickswitchdelegate_p.h @@ -79,6 +79,8 @@ protected: #endif QFont defaultFont() const override; + QPalette defaultPalette() const override; + void mirrorChange() override; void nextCheckState() override; diff --git a/src/quicktemplates2/qquicktabbar.cpp b/src/quicktemplates2/qquicktabbar.cpp index cd0c5c45..3873ecfa 100644 --- a/src/quicktemplates2/qquicktabbar.cpp +++ b/src/quicktemplates2/qquicktabbar.cpp @@ -106,15 +106,14 @@ public: void updateCurrentIndex(); void updateLayout(); + qreal getContentWidth() const override; + qreal getContentHeight() const override; + void itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &diff) override; void itemImplicitWidthChanged(QQuickItem *item) override; void itemImplicitHeightChanged(QQuickItem *item) override; bool updatingLayout; - bool hasContentWidth; - bool hasContentHeight; - qreal contentWidth; - qreal contentHeight; QQuickTabBar::Position position; }; @@ -142,10 +141,6 @@ public: QQuickTabBarPrivate::QQuickTabBarPrivate() : updatingLayout(false), - hasContentWidth(false), - hasContentHeight(false), - contentWidth(0), - contentHeight(0), position(QQuickTabBar::Header) { changeTypes |= Geometry | ImplicitWidth | ImplicitHeight; @@ -173,8 +168,6 @@ void QQuickTabBarPrivate::updateLayout() if (count <= 0 || !contentItem) return; - qreal maxHeight = 0; - qreal totalWidth = 0; qreal reservedWidth = 0; int resizableCount = 0; @@ -185,21 +178,15 @@ void QQuickTabBarPrivate::updateLayout() QQuickItem *item = q->itemAt(i); if (item) { QQuickItemPrivate *p = QQuickItemPrivate::get(item); - if (!p->widthValid) { + if (!p->widthValid) ++resizableCount; - totalWidth += item->implicitWidth(); - } else { + else reservedWidth += item->width(); - totalWidth += item->width(); - } - maxHeight = qMax(maxHeight, item->implicitHeight()); allItems += item; } } const qreal totalSpacing = qMax(0, count - 1) * spacing; - totalWidth += totalSpacing; - const qreal itemWidth = (contentItem->width() - reservedWidth - totalSpacing) / qMax(1, resizableCount); updatingLayout = true; @@ -210,48 +197,68 @@ void QQuickTabBarPrivate::updateLayout() p->widthValid = false; } if (!p->heightValid) { - item->setHeight(hasContentHeight ? contentHeight : maxHeight); + item->setHeight(contentHeight); p->heightValid = false; } else { - item->setY((maxHeight - item->height()) / 2); + item->setY((contentHeight - item->height()) / 2); } } updatingLayout = false; +} - bool contentWidthChange = false; - if (!hasContentWidth && !qFuzzyCompare(contentWidth, totalWidth)) { - contentWidth = totalWidth; - contentWidthChange = true; +qreal QQuickTabBarPrivate::getContentWidth() const +{ + Q_Q(const QQuickTabBar); + const int count = contentModel->count(); + qreal totalWidth = qMax(0, count - 1) * spacing; + for (int i = 0; i < count; ++i) { + QQuickItem *item = q->itemAt(i); + if (item) { + QQuickItemPrivate *p = QQuickItemPrivate::get(item); + if (!p->widthValid) + totalWidth += item->implicitWidth(); + else + totalWidth += item->width(); + } } + return totalWidth; +} - bool contentHeightChange = false; - if (!hasContentHeight && !qFuzzyCompare(contentHeight, maxHeight)) { - contentHeight = maxHeight; - contentHeightChange = true; +qreal QQuickTabBarPrivate::getContentHeight() const +{ + Q_Q(const QQuickTabBar); + const int count = contentModel->count(); + qreal maxHeight = 0; + for (int i = 0; i < count; ++i) { + QQuickItem *item = q->itemAt(i); + if (item) + maxHeight = qMax(maxHeight, item->implicitHeight()); } - - if (contentWidthChange) - emit q->contentWidthChanged(); - if (contentHeightChange) - emit q->contentHeightChanged(); + return maxHeight; } -void QQuickTabBarPrivate::itemGeometryChanged(QQuickItem *, QQuickGeometryChange, const QRectF &) +void QQuickTabBarPrivate::itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &diff) { - if (!updatingLayout) + QQuickContainerPrivate::itemGeometryChanged(item, change, diff); + if (!updatingLayout) { + if (change.sizeChange()) + updateImplicitContentSize(); updateLayout(); + } } -void QQuickTabBarPrivate::itemImplicitWidthChanged(QQuickItem *) +void QQuickTabBarPrivate::itemImplicitWidthChanged(QQuickItem *item) { - if (!updatingLayout && !hasContentWidth) - updateLayout(); + QQuickContainerPrivate::itemImplicitWidthChanged(item); + if (item != contentItem) + updateImplicitContentWidth(); } -void QQuickTabBarPrivate::itemImplicitHeightChanged(QQuickItem *) +void QQuickTabBarPrivate::itemImplicitHeightChanged(QQuickItem *item) { - if (!updatingLayout && !hasContentHeight) - updateLayout(); + QQuickContainerPrivate::itemImplicitHeightChanged(item); + if (item != contentItem) + updateImplicitContentHeight(); } QQuickTabBar::QQuickTabBar(QQuickItem *parent) @@ -301,39 +308,11 @@ void QQuickTabBar::setPosition(Position position) This property holds the content width. It is used for calculating the total implicit width of the tab bar. - Unless explicitly overridden, the content width is automatically calculated - based on the total implicit width of the tabs and the \l {Control::}{spacing} - of the tab bar. + \note This property is available in TabBar since QtQuick.Controls 2.2 (Qt 5.9), + but it was promoted to the Container base type in QtQuick.Controls 2.5 (Qt 5.12). - \sa contentHeight + \sa Container::contentWidth */ -qreal QQuickTabBar::contentWidth() const -{ - Q_D(const QQuickTabBar); - return d->contentWidth; -} - -void QQuickTabBar::setContentWidth(qreal width) -{ - Q_D(QQuickTabBar); - d->hasContentWidth = true; - if (qFuzzyCompare(d->contentWidth, width)) - return; - - d->contentWidth = width; - emit contentWidthChanged(); -} - -void QQuickTabBar::resetContentWidth() -{ - Q_D(QQuickTabBar); - if (!d->hasContentWidth) - return; - - d->hasContentWidth = false; - if (isComponentComplete()) - d->updateLayout(); -} /*! \since QtQuick.Controls 2.2 (Qt 5.9) @@ -342,38 +321,11 @@ void QQuickTabBar::resetContentWidth() This property holds the content height. It is used for calculating the total implicit height of the tab bar. - Unless explicitly overridden, the content height is automatically calculated - based on the maximum implicit height of the tabs. + \note This property is available in TabBar since QtQuick.Controls 2.2 (Qt 5.9), + but it was promoted to the Container base type in QtQuick.Controls 2.5 (Qt 5.12). - \sa contentWidth + \sa Container::contentHeight */ -qreal QQuickTabBar::contentHeight() const -{ - Q_D(const QQuickTabBar); - return d->contentHeight; -} - -void QQuickTabBar::setContentHeight(qreal height) -{ - Q_D(QQuickTabBar); - d->hasContentHeight = true; - if (qFuzzyCompare(d->contentHeight, height)) - return; - - d->contentHeight = height; - emit contentHeightChanged(); -} - -void QQuickTabBar::resetContentHeight() -{ - Q_D(QQuickTabBar); - if (!d->hasContentHeight) - return; - - d->hasContentHeight = false; - if (isComponentComplete()) - d->updateLayout(); -} QQuickTabBarAttached *QQuickTabBar::qmlAttachedProperties(QObject *object) { @@ -417,6 +369,7 @@ void QQuickTabBar::itemAdded(int index, QQuickItem *item) QQuickTabBarAttached *attached = qobject_cast<QQuickTabBarAttached *>(qmlAttachedPropertiesObject<QQuickTabBar>(item)); if (attached) QQuickTabBarAttachedPrivate::get(attached)->update(this, index); + d->updateImplicitContentSize(); if (isComponentComplete()) polish(); } @@ -437,13 +390,19 @@ void QQuickTabBar::itemRemoved(int index, QQuickItem *item) QQuickTabBarAttached *attached = qobject_cast<QQuickTabBarAttached *>(qmlAttachedPropertiesObject<QQuickTabBar>(item)); if (attached) QQuickTabBarAttachedPrivate::get(attached)->update(nullptr, -1); + d->updateImplicitContentSize(); if (isComponentComplete()) polish(); } +QFont QQuickTabBar::defaultFont() const +{ + return QQuickTheme::themeFont(QQuickTheme::TabBar); +} + QPalette QQuickTabBar::defaultPalette() const { - return QQuickControlPrivate::themePalette(QPlatformTheme::TabBarPalette); + return QQuickTheme::themePalette(QQuickTheme::TabBar); } #if QT_CONFIG(accessibility) diff --git a/src/quicktemplates2/qquicktabbar_p.h b/src/quicktemplates2/qquicktabbar_p.h index f0299bd5..5367118c 100644 --- a/src/quicktemplates2/qquicktabbar_p.h +++ b/src/quicktemplates2/qquicktabbar_p.h @@ -61,8 +61,8 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickTabBar : public QQuickContainer Q_OBJECT Q_PROPERTY(Position position READ position WRITE setPosition NOTIFY positionChanged FINAL) // 2.2 (Qt 5.9) - Q_PROPERTY(qreal contentWidth READ contentWidth WRITE setContentWidth RESET resetContentWidth NOTIFY contentWidthChanged FINAL REVISION 2) - Q_PROPERTY(qreal contentHeight READ contentHeight WRITE setContentHeight RESET resetContentHeight NOTIFY contentHeightChanged FINAL REVISION 2) + Q_PROPERTY(qreal contentWidth READ contentWidth WRITE setContentWidth RESET resetContentWidth NOTIFY contentWidthChanged FINAL REVISION 2) // re-declare QQuickContainer::contentWidth (REV 5) + Q_PROPERTY(qreal contentHeight READ contentHeight WRITE setContentHeight RESET resetContentHeight NOTIFY contentHeightChanged FINAL REVISION 2) // re-declare QQuickContainer::contentHeight (REV 5) public: explicit QQuickTabBar(QQuickItem *parent = nullptr); @@ -76,22 +76,10 @@ public: Position position() const; void setPosition(Position position); - // 2.2 (Qt 5.9) - qreal contentWidth() const; - void setContentWidth(qreal width); - void resetContentWidth(); - - qreal contentHeight() const; - void setContentHeight(qreal height); - void resetContentHeight(); - static QQuickTabBarAttached *qmlAttachedProperties(QObject *object); Q_SIGNALS: void positionChanged(); - // 2.2 (Qt 5.9) - Q_REVISION(2) void contentWidthChanged(); - Q_REVISION(2) void contentHeightChanged(); protected: void updatePolish() override; @@ -102,6 +90,7 @@ protected: void itemMoved(int index, QQuickItem *item) override; void itemRemoved(int index, QQuickItem *item) override; + QFont defaultFont() const override; QPalette defaultPalette() const override; #if QT_CONFIG(accessibility) diff --git a/src/quicktemplates2/qquicktabbutton.cpp b/src/quicktemplates2/qquicktabbutton.cpp index 617d4aea..597f4a5e 100644 --- a/src/quicktemplates2/qquicktabbutton.cpp +++ b/src/quicktemplates2/qquicktabbutton.cpp @@ -72,12 +72,12 @@ QQuickTabButton::QQuickTabButton(QQuickItem *parent) QFont QQuickTabButton::defaultFont() const { - return QQuickControlPrivate::themeFont(QPlatformTheme::TabButtonFont); + return QQuickTheme::themeFont(QQuickTheme::TabBar); } QPalette QQuickTabButton::defaultPalette() const { - return QQuickControlPrivate::themePalette(QPlatformTheme::TabBarPalette); + return QQuickTheme::themePalette(QQuickTheme::TabBar); } #if QT_CONFIG(accessibility) diff --git a/src/quicktemplates2/qquicktextarea.cpp b/src/quicktemplates2/qquicktextarea.cpp index aca13d5e..4193483c 100644 --- a/src/quicktemplates2/qquicktextarea.cpp +++ b/src/quicktemplates2/qquicktextarea.cpp @@ -194,7 +194,7 @@ void QQuickTextAreaPrivate::inheritFont(const QFont &font) QFont parentFont = extra.isAllocated() ? extra->requestedFont.resolve(font) : font; parentFont.resolve(extra.isAllocated() ? extra->requestedFont.resolve() | font.resolve() : font.resolve()); - const QFont defaultFont = QQuickControlPrivate::themeFont(QPlatformTheme::EditorFont); + const QFont defaultFont = QQuickTheme::themeFont(QQuickTheme::TextArea); const QFont resolvedFont = parentFont.resolve(defaultFont); setFont_helper(resolvedFont); @@ -236,7 +236,7 @@ void QQuickTextAreaPrivate::inheritPalette(const QPalette &palette) QPalette parentPalette = extra.isAllocated() ? extra->requestedPalette.resolve(palette) : palette; parentPalette.resolve(extra.isAllocated() ? extra->requestedPalette.resolve() | palette.resolve() : palette.resolve()); - const QPalette defaultPalette = QQuickControlPrivate::themePalette(QPlatformTheme::TextEditPalette); + const QPalette defaultPalette = QQuickTheme::themePalette(QQuickTheme::TextArea); const QPalette resolvedPalette = parentPalette.resolve(defaultPalette); setPalette_helper(resolvedPalette); @@ -569,6 +569,30 @@ void QQuickTextArea::setPlaceholderText(const QString &text) } /*! + \qmlproperty color QtQuick.Controls::TextArea::placeholderTextColor + \since QtQuick.Controls 2.5 (Qt 5.12) + + This property holds the color of placeholderText. + + \sa placeholderText +*/ +QColor QQuickTextArea::placeholderTextColor() const +{ + Q_D(const QQuickTextArea); + return d->placeholderColor; +} + +void QQuickTextArea::setPlaceholderTextColor(const QColor &color) +{ + Q_D(QQuickTextArea); + if (d->placeholderColor == color) + return; + + d->placeholderColor = color; + emit placeholderTextColorChanged(); +} + +/*! \qmlproperty enumeration QtQuick.Controls::TextArea::focusReason \include qquickcontrol-focusreason.qdocinc diff --git a/src/quicktemplates2/qquicktextarea_p.h b/src/quicktemplates2/qquicktextarea_p.h index 5482ceae..346438ea 100644 --- a/src/quicktemplates2/qquicktextarea_p.h +++ b/src/quicktemplates2/qquicktextarea_p.h @@ -74,6 +74,8 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickTextArea : public QQuickTextEdit // 2.3 (Qt 5.10) Q_PROPERTY(QPalette palette READ palette WRITE setPalette RESET resetPalette NOTIFY paletteChanged FINAL REVISION 3) Q_CLASSINFO("DeferredPropertyNames", "background") + // 2.5 (Qt 5.12) + Q_PROPERTY(QColor placeholderTextColor READ placeholderTextColor WRITE setPlaceholderTextColor NOTIFY placeholderTextColorChanged FINAL REVISION 5) public: explicit QQuickTextArea(QQuickItem *parent = nullptr); @@ -108,6 +110,10 @@ public: void setPalette(const QPalette &palette); void resetPalette(); + // 2.5 (Qt 5.12) + QColor placeholderTextColor() const; + void setPlaceholderTextColor(const QColor &color); + Q_SIGNALS: void fontChanged(); void implicitWidthChanged3(); @@ -123,6 +129,8 @@ Q_SIGNALS: Q_REVISION(1) void hoverEnabledChanged(); // 2.3 (Qt 5.10) Q_REVISION(3) void paletteChanged(); + // 2.5 (Qt 5.12) + Q_REVISION(5) void placeholderTextColorChanged(); protected: void classBegin() override; diff --git a/src/quicktemplates2/qquicktextarea_p_p.h b/src/quicktemplates2/qquicktextarea_p_p.h index 8621c61c..c271660a 100644 --- a/src/quicktemplates2/qquicktextarea_p_p.h +++ b/src/quicktemplates2/qquicktextarea_p_p.h @@ -142,6 +142,7 @@ public: QPalette resolvedPalette; QQuickDeferredPointer<QQuickItem> background; QString placeholder; + QColor placeholderColor; Qt::FocusReason focusReason; QQuickPressHandler pressHandler; QQuickFlickable *flickable; diff --git a/src/quicktemplates2/qquicktextfield.cpp b/src/quicktemplates2/qquicktextfield.cpp index 876ceca6..3125028f 100644 --- a/src/quicktemplates2/qquicktextfield.cpp +++ b/src/quicktemplates2/qquicktextfield.cpp @@ -168,7 +168,7 @@ void QQuickTextFieldPrivate::inheritFont(const QFont &font) QFont parentFont = extra.isAllocated() ? extra->requestedFont.resolve(font) : font; parentFont.resolve(extra.isAllocated() ? extra->requestedFont.resolve() | font.resolve() : font.resolve()); - const QFont defaultFont = QQuickControlPrivate::themeFont(QPlatformTheme::EditorFont); + const QFont defaultFont = QQuickTheme::themeFont(QQuickTheme::TextField); const QFont resolvedFont = parentFont.resolve(defaultFont); setFont_helper(resolvedFont); @@ -210,7 +210,7 @@ void QQuickTextFieldPrivate::inheritPalette(const QPalette &palette) QPalette parentPalette = extra.isAllocated() ? extra->requestedPalette.resolve(palette) : palette; parentPalette.resolve(extra.isAllocated() ? extra->requestedPalette.resolve() | palette.resolve() : palette.resolve()); - const QPalette defaultPalette = QQuickControlPrivate::themePalette(QPlatformTheme::TextLineEditPalette); + const QPalette defaultPalette = QQuickTheme::themePalette(QQuickTheme::TextField); const QPalette resolvedPalette = parentPalette.resolve(defaultPalette); setPalette_helper(resolvedPalette); @@ -428,6 +428,30 @@ void QQuickTextField::setPlaceholderText(const QString &text) } /*! + \qmlproperty color QtQuick.Controls::TextField::placeholderTextColor + \since QtQuick.Controls 2.5 (Qt 5.12) + + This property holds the color of placeholderText. + + \sa placeholderText +*/ +QColor QQuickTextField::placeholderTextColor() const +{ + Q_D(const QQuickTextField); + return d->placeholderColor; +} + +void QQuickTextField::setPlaceholderTextColor(const QColor &color) +{ + Q_D(QQuickTextField); + if (d->placeholderColor == color) + return; + + d->placeholderColor = color; + emit placeholderTextColorChanged(); +} + +/*! \qmlproperty enumeration QtQuick.Controls::TextField::focusReason \include qquickcontrol-focusreason.qdocinc diff --git a/src/quicktemplates2/qquicktextfield_p.h b/src/quicktemplates2/qquicktextfield_p.h index 4757bd2d..b2e77342 100644 --- a/src/quicktemplates2/qquicktextfield_p.h +++ b/src/quicktemplates2/qquicktextfield_p.h @@ -73,6 +73,8 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickTextField : public QQuickTextInput // 2.3 (Qt 5.10) Q_PROPERTY(QPalette palette READ palette WRITE setPalette RESET resetPalette NOTIFY paletteChanged FINAL REVISION 3) Q_CLASSINFO("DeferredPropertyNames", "background") + // 2.5 (Qt 5.12) + Q_PROPERTY(QColor placeholderTextColor READ placeholderTextColor WRITE setPlaceholderTextColor NOTIFY placeholderTextColorChanged FINAL REVISION 5) public: explicit QQuickTextField(QQuickItem *parent = nullptr); @@ -101,6 +103,9 @@ public: QPalette palette() const; void setPalette(const QPalette &palette); void resetPalette(); + // 2.5 (Qt 5.12) + QColor placeholderTextColor() const; + void setPlaceholderTextColor(const QColor &color); Q_SIGNALS: void fontChanged(); @@ -117,6 +122,8 @@ Q_SIGNALS: Q_REVISION(1) void hoverEnabledChanged(); // 2.3 (Qt 5.10) Q_REVISION(3) void paletteChanged(); + // 2.5 (Qt 5.12) + Q_REVISION(5) void placeholderTextColorChanged(); protected: void classBegin() override; diff --git a/src/quicktemplates2/qquicktextfield_p_p.h b/src/quicktemplates2/qquicktextfield_p_p.h index 41843370..13a20e32 100644 --- a/src/quicktemplates2/qquicktextfield_p_p.h +++ b/src/quicktemplates2/qquicktextfield_p_p.h @@ -130,6 +130,7 @@ public: QPalette resolvedPalette; QQuickDeferredPointer<QQuickItem> background; QString placeholder; + QColor placeholderColor; Qt::FocusReason focusReason; QQuickPressHandler pressHandler; }; diff --git a/src/quicktemplates2/qquicktheme.cpp b/src/quicktemplates2/qquicktheme.cpp new file mode 100644 index 00000000..30185fe2 --- /dev/null +++ b/src/quicktemplates2/qquicktheme.cpp @@ -0,0 +1,199 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquicktheme_p.h" +#include "qquicktheme_p_p.h" + +#include <QtGui/qpa/qplatformtheme.h> +#include <QtGui/private/qguiapplication_p.h> + +QT_BEGIN_NAMESPACE + +QScopedPointer<QQuickTheme> QQuickThemePrivate::current; + +static QPlatformTheme::Font platformFont(QQuickTheme::Scope scope) +{ + switch (scope) { + case QQuickTheme::Button: return QPlatformTheme::PushButtonFont; + case QQuickTheme::CheckBox: return QPlatformTheme::CheckBoxFont; + case QQuickTheme::ComboBox: return QPlatformTheme::ComboMenuItemFont; + case QQuickTheme::GroupBox: return QPlatformTheme::GroupBoxTitleFont; + case QQuickTheme::ItemView: return QPlatformTheme::ItemViewFont; + case QQuickTheme::Label: return QPlatformTheme::LabelFont; + case QQuickTheme::ListView: return QPlatformTheme::ListViewFont; + case QQuickTheme::Menu: return QPlatformTheme::MenuFont; + case QQuickTheme::MenuBar: return QPlatformTheme::MenuBarFont; + case QQuickTheme::RadioButton: return QPlatformTheme::RadioButtonFont; + case QQuickTheme::SpinBox: return QPlatformTheme::EditorFont; + case QQuickTheme::Switch: return QPlatformTheme::CheckBoxFont; + case QQuickTheme::TabBar: return QPlatformTheme::TabButtonFont; + case QQuickTheme::TextArea: return QPlatformTheme::EditorFont; + case QQuickTheme::TextField: return QPlatformTheme::EditorFont; + case QQuickTheme::ToolBar: return QPlatformTheme::ToolButtonFont; + case QQuickTheme::ToolTip: return QPlatformTheme::TipLabelFont; + case QQuickTheme::Tumbler: return QPlatformTheme::ItemViewFont; + default: return QPlatformTheme::SystemFont; + } +} + +static QPlatformTheme::Palette platformPalette(QQuickTheme::Scope scope) +{ + switch (scope) { + case QQuickTheme::Button: return QPlatformTheme::ButtonPalette; + case QQuickTheme::CheckBox: return QPlatformTheme::CheckBoxPalette; + case QQuickTheme::ComboBox: return QPlatformTheme::ComboBoxPalette; + case QQuickTheme::GroupBox: return QPlatformTheme::GroupBoxPalette; + case QQuickTheme::ItemView: return QPlatformTheme::ItemViewPalette; + case QQuickTheme::Label: return QPlatformTheme::LabelPalette; + case QQuickTheme::ListView: return QPlatformTheme::ItemViewPalette; + case QQuickTheme::Menu: return QPlatformTheme::MenuPalette; + case QQuickTheme::MenuBar: return QPlatformTheme::MenuBarPalette; + case QQuickTheme::RadioButton: return QPlatformTheme::RadioButtonPalette; + case QQuickTheme::SpinBox: return QPlatformTheme::TextLineEditPalette; + case QQuickTheme::Switch: return QPlatformTheme::CheckBoxPalette; + case QQuickTheme::TabBar: return QPlatformTheme::TabBarPalette; + case QQuickTheme::TextArea: return QPlatformTheme::TextEditPalette; + case QQuickTheme::TextField: return QPlatformTheme::TextLineEditPalette; + case QQuickTheme::ToolBar: return QPlatformTheme::ToolButtonPalette; + case QQuickTheme::ToolTip: return QPlatformTheme::ToolTipPalette; + case QQuickTheme::Tumbler: return QPlatformTheme::ItemViewPalette; + default: return QPlatformTheme::SystemPalette; + } +} + +const QFont *QQuickThemePrivate::resolveThemeFont(QQuickTheme::Scope scope) +{ + Q_Q(QQuickTheme); + if (!hasResolvedFonts) { + q->resolveFonts(defaultFont ? *defaultFont : QFont()); + hasResolvedFonts = true; + defaultFont.reset(); + } + return q->font(scope); +} + +const QPalette *QQuickThemePrivate::resolveThemePalette(QQuickTheme::Scope scope) +{ + Q_Q(QQuickTheme); + if (!hasResolvedPalettes) { + q->resolvePalettes(defaultPalette ? *defaultPalette : QPalette()); + hasResolvedPalettes = true; + defaultPalette.reset(); + } + return q->palette(scope); +} + +QQuickTheme::QQuickTheme() + : d_ptr(new QQuickThemePrivate) +{ + d_ptr->q_ptr = this; +} + +QQuickTheme::~QQuickTheme() +{ +} + +QQuickTheme *QQuickTheme::current() +{ + return QQuickThemePrivate::current.data(); +} + +void QQuickTheme::setCurrent(QQuickTheme *theme) +{ + QQuickThemePrivate::current.reset(theme); +} + +QFont QQuickTheme::themeFont(Scope scope) +{ + const QFont *font = nullptr; + if (QQuickTheme *theme = current()) + font = QQuickThemePrivate::get(theme)->resolveThemeFont(scope); + else if (QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) + font = theme->font(platformFont(scope)); + + if (font) { + QFont f = *font; + if (scope == System) + f.resolve(0); + return f; + } + + return QFont(); +} + +QPalette QQuickTheme::themePalette(Scope scope) +{ + const QPalette *palette = nullptr; + if (QQuickTheme *theme = current()) + palette = QQuickThemePrivate::get(theme)->resolveThemePalette(scope); + else if (QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) + palette = theme->palette(platformPalette(scope)); + + if (palette) { + QPalette f = *palette; + if (scope == System) + f.resolve(0); + return f; + } + + return QPalette(); +} + +const QFont *QQuickTheme::font(Scope scope) const +{ + Q_D(const QQuickTheme); + Q_UNUSED(scope) + return d->defaultFont.data(); +} + +const QPalette *QQuickTheme::palette(Scope scope) const +{ + Q_D(const QQuickTheme); + Q_UNUSED(scope) + return d->defaultPalette.data(); +} + +void QQuickTheme::resolveFonts(const QFont &defaultFont) +{ + Q_UNUSED(defaultFont) +} + +void QQuickTheme::resolvePalettes(const QPalette &defaultPalette) +{ + Q_UNUSED(defaultPalette) +} + +QT_END_NAMESPACE diff --git a/src/quicktemplates2/qquicktheme_p.h b/src/quicktemplates2/qquicktheme_p.h new file mode 100644 index 00000000..32044b67 --- /dev/null +++ b/src/quicktemplates2/qquicktheme_p.h @@ -0,0 +1,109 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKTHEME_P_H +#define QQUICKTHEME_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qtquicktemplates2global_p.h> +#include <QtCore/qscopedpointer.h> +#include <QtGui/qfont.h> +#include <QtGui/qpalette.h> + +QT_BEGIN_NAMESPACE + +class QQuickThemePrivate; + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickTheme +{ +public: + QQuickTheme(); + virtual ~QQuickTheme(); + + static QQuickTheme *current(); + static void setCurrent(QQuickTheme *theme); + + enum Scope { + System, + Button, + CheckBox, + ComboBox, + GroupBox, + ItemView, + Label, + ListView, + Menu, + MenuBar, + RadioButton, + SpinBox, + Switch, + TabBar, + TextArea, + TextField, + ToolBar, + ToolTip, + Tumbler + }; + + static QFont themeFont(Scope scope); + static QPalette themePalette(Scope scope); + +protected: + virtual const QFont *font(Scope scope) const; + virtual const QPalette *palette(Scope scope) const; + + virtual void resolveFonts(const QFont &defaultFont); + virtual void resolvePalettes(const QPalette &defaultPalette); + +private: + Q_DISABLE_COPY(QQuickTheme) + Q_DECLARE_PRIVATE(QQuickTheme) + QScopedPointer<QQuickThemePrivate> d_ptr; +}; + +QT_END_NAMESPACE + +#endif // QQUICKTHEME_P_H diff --git a/src/quicktemplates2/qquicktheme_p_p.h b/src/quicktemplates2/qquicktheme_p_p.h new file mode 100644 index 00000000..e9593865 --- /dev/null +++ b/src/quicktemplates2/qquicktheme_p_p.h @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKTHEME_P_P_H +#define QQUICKTHEME_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquicktheme_p.h> + +QT_BEGIN_NAMESPACE + +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickThemePrivate +{ + Q_DECLARE_PUBLIC(QQuickTheme) + +public: + static QQuickThemePrivate *get(QQuickTheme *theme) + { + return theme->d_func(); + } + + const QFont *resolveThemeFont(QQuickTheme::Scope scope); + const QPalette *resolveThemePalette(QQuickTheme::Scope scope); + + static QScopedPointer<QQuickTheme> current; + + bool hasResolvedFonts = false; + bool hasResolvedPalettes = false; + QScopedPointer<const QFont> defaultFont; + QScopedPointer<const QPalette> defaultPalette; + QQuickTheme *q_ptr = nullptr; +}; + +QT_END_NAMESPACE + +#endif // QQUICKTHEME_P_P_H diff --git a/src/quicktemplates2/qquicktoolbar.cpp b/src/quicktemplates2/qquicktoolbar.cpp index 99775c6a..c597de74 100644 --- a/src/quicktemplates2/qquicktoolbar.cpp +++ b/src/quicktemplates2/qquicktoolbar.cpp @@ -141,9 +141,14 @@ void QQuickToolBar::setPosition(Position position) emit positionChanged(); } +QFont QQuickToolBar::defaultFont() const +{ + return QQuickTheme::themeFont(QQuickTheme::ToolBar); +} + QPalette QQuickToolBar::defaultPalette() const { - return QQuickControlPrivate::themePalette(QPlatformTheme::ToolButtonPalette); + return QQuickTheme::themePalette(QQuickTheme::ToolBar); } #if QT_CONFIG(accessibility) diff --git a/src/quicktemplates2/qquicktoolbar_p.h b/src/quicktemplates2/qquicktoolbar_p.h index b919c615..ef2ceb7e 100644 --- a/src/quicktemplates2/qquicktoolbar_p.h +++ b/src/quicktemplates2/qquicktoolbar_p.h @@ -75,6 +75,7 @@ Q_SIGNALS: void positionChanged(); protected: + QFont defaultFont() const override; QPalette defaultPalette() const override; #if QT_CONFIG(accessibility) diff --git a/src/quicktemplates2/qquicktoolbutton.cpp b/src/quicktemplates2/qquicktoolbutton.cpp index f87a58b2..3a8aa7b3 100644 --- a/src/quicktemplates2/qquicktoolbutton.cpp +++ b/src/quicktemplates2/qquicktoolbutton.cpp @@ -71,12 +71,12 @@ QQuickToolButton::QQuickToolButton(QQuickItem *parent) QFont QQuickToolButton::defaultFont() const { - return QQuickControlPrivate::themeFont(QPlatformTheme::ToolButtonFont); + return QQuickTheme::themeFont(QQuickTheme::ToolBar); } QPalette QQuickToolButton::defaultPalette() const { - return QQuickControlPrivate::themePalette(QPlatformTheme::ToolButtonPalette); + return QQuickTheme::themePalette(QQuickTheme::ToolBar); } QT_END_NAMESPACE diff --git a/src/quicktemplates2/qquicktoolseparator.cpp b/src/quicktemplates2/qquicktoolseparator.cpp index 2ec7799f..2343c7ce 100644 --- a/src/quicktemplates2/qquicktoolseparator.cpp +++ b/src/quicktemplates2/qquicktoolseparator.cpp @@ -133,9 +133,14 @@ bool QQuickToolSeparator::isVertical() const return d->orientation == Qt::Vertical; } +QFont QQuickToolSeparator::defaultFont() const +{ + return QQuickTheme::themeFont(QQuickTheme::ToolBar); +} + QPalette QQuickToolSeparator::defaultPalette() const { - return QQuickControlPrivate::themePalette(QPlatformTheme::ToolButtonPalette); + return QQuickTheme::themePalette(QQuickTheme::ToolBar); } #if QT_CONFIG(accessibility) diff --git a/src/quicktemplates2/qquicktoolseparator_p.h b/src/quicktemplates2/qquicktoolseparator_p.h index 2108cc5b..c3c14b82 100644 --- a/src/quicktemplates2/qquicktoolseparator_p.h +++ b/src/quicktemplates2/qquicktoolseparator_p.h @@ -74,6 +74,7 @@ Q_SIGNALS: void orientationChanged(); protected: + QFont defaultFont() const override; QPalette defaultPalette() const override; #if QT_CONFIG(accessibility) diff --git a/src/quicktemplates2/qquicktooltip.cpp b/src/quicktemplates2/qquicktooltip.cpp index 1bf6ca55..66fe9afe 100644 --- a/src/quicktemplates2/qquicktooltip.cpp +++ b/src/quicktemplates2/qquicktooltip.cpp @@ -276,14 +276,39 @@ QQuickToolTipAttached *QQuickToolTip::qmlAttachedProperties(QObject *object) return new QQuickToolTipAttached(object); } +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlmethod void QtQuick.Controls::ToolTip::show(string text, int timeout = -1) + + This method shows the tooltip with \a text and \a timeout (milliseconds). +*/ +void QQuickToolTip::show(const QString &text, int ms) +{ + if (ms >= 0) + setTimeout(ms); + setText(text); + open(); +} + +/*! + \since QtQuick.Controls 2.5 (Qt 5.12) + \qmlmethod void QtQuick.Controls::ToolTip::hide() + + This method hides the tooltip. +*/ +void QQuickToolTip::hide() +{ + close(); +} + QFont QQuickToolTip::defaultFont() const { - return QQuickControlPrivate::themeFont(QPlatformTheme::TipLabelFont); + return QQuickTheme::themeFont(QQuickTheme::ToolTip); } QPalette QQuickToolTip::defaultPalette() const { - return QQuickControlPrivate::themePalette(QPlatformTheme::ToolTipPalette); + return QQuickTheme::themePalette(QQuickTheme::ToolTip); } void QQuickToolTip::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &data) @@ -520,10 +545,8 @@ void QQuickToolTipAttached::show(const QString &text, int ms) tip->resetWidth(); tip->resetHeight(); tip->setParentItem(qobject_cast<QQuickItem *>(parent())); - tip->setTimeout(ms >= 0 ? ms : d->timeout); tip->setDelay(d->delay); - tip->setText(text); - tip->open(); + tip->show(text, ms >= 0 ? ms : d->timeout); } /*! diff --git a/src/quicktemplates2/qquicktooltip_p.h b/src/quicktemplates2/qquicktooltip_p.h index 60b02502..432bdd8e 100644 --- a/src/quicktemplates2/qquicktooltip_p.h +++ b/src/quicktemplates2/qquicktooltip_p.h @@ -84,6 +84,10 @@ Q_SIGNALS: void delayChanged(); void timeoutChanged(); +public Q_SLOTS: + Q_REVISION(5) void show(const QString &text, int ms = -1); + Q_REVISION(5) void hide(); + protected: QFont defaultFont() const override; QPalette defaultPalette() const override; diff --git a/src/quicktemplates2/qquicktumbler.cpp b/src/quicktemplates2/qquicktumbler.cpp index efa61dad..a40330a3 100644 --- a/src/quicktemplates2/qquicktumbler.cpp +++ b/src/quicktemplates2/qquicktumbler.cpp @@ -70,7 +70,8 @@ QT_BEGIN_NAMESPACE The API is similar to that of views like \l ListView and \l PathView; a \l model and \l delegate can be set, and the \l count and \l currentItem - properties provide read-only access to information about the view. + properties provide read-only access to information about the view. To + position the view at a certain index, use \l positionViewAtIndex(). Unlike views like \l PathView and \l ListView, however, there is always a current item (when the model isn't empty). This means that when \l count is @@ -277,8 +278,9 @@ void QQuickTumblerPrivate::itemChildRemoved(QQuickItem *, QQuickItem *) _q_updateItemHeights(); } -void QQuickTumblerPrivate::itemGeometryChanged(QQuickItem *, QQuickGeometryChange change, const QRectF &) +void QQuickTumblerPrivate::itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &diff) { + QQuickControlPrivate::itemGeometryChanged(item, change, diff); if (change.sizeChange()) calculateDisplacements(); } @@ -350,6 +352,8 @@ int QQuickTumbler::count() const The value of this property is \c -1 when \l count is equal to \c 0. In all other cases, it will be greater than or equal to \c 0. + + \sa currentItem, positionViewAtIndex() */ int QQuickTumbler::currentIndex() const { @@ -410,6 +414,8 @@ void QQuickTumbler::setCurrentIndex(int currentIndex) \readonly This property holds the item at the current index. + + \sa currentIndex, positionViewAtIndex() */ QQuickItem *QQuickTumbler::currentItem() const { @@ -511,6 +517,41 @@ bool QQuickTumbler::isMoving() const return d->view && d->view->property("moving").toBool(); } +/*! + \qmlmethod void QtQuick.Controls::Tumbler::positionViewAtIndex(int index, PositionMode mode) + \since QtQuick.Controls 2.5 (Qt 5.12) + + Positions the view so that the \a index is at the position specified by \a mode. + + For example: + + \code + positionViewAtIndex(10, Tumbler.Center) + \endcode + + If \l wrap is true (the default), the modes available to \l {PathView}'s + \l {PathView::}{positionViewAtIndex()} function + are available, otherwise the modes available to \l {ListView}'s + \l {ListView::}{positionViewAtIndex()} function + are available. + + \note There is a known limitation that using \c Tumbler.Beginning when \l + wrap is \c true will result in the wrong item being positioned at the top + of view. As a workaround, pass \c {index - 1}. + + \sa currentIndex +*/ +void QQuickTumbler::positionViewAtIndex(int index, QQuickTumbler::PositionMode mode) +{ + Q_D(QQuickTumbler); + if (!d->view) { + d->warnAboutIncorrectContentItem(); + return; + } + + QMetaObject::invokeMethod(d->view, "positionViewAtIndex", Q_ARG(int, index), Q_ARG(int, mode)); +} + void QQuickTumbler::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) { Q_D(QQuickTumbler); @@ -609,7 +650,7 @@ void QQuickTumblerPrivate::setupViewData(QQuickItem *newControlContentItem) return; if (viewContentItemType == QQuickTumblerPrivate::UnsupportedContentItemType) { - qWarning() << "Tumbler: contentItem must contain either a PathView or a ListView"; + warnAboutIncorrectContentItem(); return; } @@ -636,6 +677,12 @@ void QQuickTumblerPrivate::setupViewData(QQuickItem *newControlContentItem) calculateDisplacements(); } +void QQuickTumblerPrivate::warnAboutIncorrectContentItem() +{ + Q_Q(QQuickTumbler); + qmlWarning(q) << "Tumbler: contentItem must contain either a PathView or a ListView"; +} + void QQuickTumblerPrivate::syncCurrentIndex() { const int actualViewIndex = view->property("currentIndex").toInt(); @@ -784,12 +831,12 @@ void QQuickTumbler::updatePolish() QFont QQuickTumbler::defaultFont() const { - return QQuickControlPrivate::themeFont(QPlatformTheme::ItemViewFont); + return QQuickTheme::themeFont(QQuickTheme::Tumbler); } QPalette QQuickTumbler::defaultPalette() const { - return QQuickControlPrivate::themePalette(QPlatformTheme::ItemViewPalette); + return QQuickTheme::themePalette(QQuickTheme::Tumbler); } QQuickTumblerAttachedPrivate::QQuickTumblerAttachedPrivate() diff --git a/src/quicktemplates2/qquicktumbler_p.h b/src/quicktemplates2/qquicktumbler_p.h index 5d4df4a7..3f7c06db 100644 --- a/src/quicktemplates2/qquicktumbler_p.h +++ b/src/quicktemplates2/qquicktumbler_p.h @@ -100,6 +100,19 @@ public: // 2.2 (Qt 5.9) bool isMoving() const; + enum PositionMode { + Beginning, + Center, + End, + Visible, // ListView-only + Contain, + SnapPosition + }; + Q_ENUM(PositionMode) + + // 2.5 (Qt 5.12) + Q_REVISION(5) Q_INVOKABLE void positionViewAtIndex(int index, PositionMode mode); + Q_SIGNALS: void modelChanged(); void countChanged(); diff --git a/src/quicktemplates2/qquicktumbler_p_p.h b/src/quicktemplates2/qquicktumbler_p_p.h index 75b1a396..24589486 100644 --- a/src/quicktemplates2/qquicktumbler_p_p.h +++ b/src/quicktemplates2/qquicktumbler_p_p.h @@ -48,13 +48,12 @@ // We mean it. // -#include <QtQuick/private/qquickitemchangelistener_p.h> #include <QtQuickTemplates2/private/qquickcontrol_p_p.h> #include <QtQuickTemplates2/private/qquicktumbler_p.h> QT_BEGIN_NAMESPACE -class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickTumblerPrivate : public QQuickControlPrivate, public QQuickItemChangeListener +class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickTumblerPrivate : public QQuickControlPrivate { Q_DECLARE_PUBLIC(QQuickTumbler) @@ -105,6 +104,7 @@ public: void disconnectFromView(); void setupViewData(QQuickItem *newControlContentItem); + void warnAboutIncorrectContentItem(); void syncCurrentIndex(); void setCount(int newCount); diff --git a/src/quicktemplates2/quicktemplates2.pri b/src/quicktemplates2/quicktemplates2.pri index b2193ec0..33bc47ca 100644 --- a/src/quicktemplates2/quicktemplates2.pri +++ b/src/quicktemplates2/quicktemplates2.pri @@ -15,6 +15,7 @@ HEADERS += \ $$PWD/qquickcombobox_p.h \ $$PWD/qquickcontainer_p.h \ $$PWD/qquickcontainer_p_p.h \ + $$PWD/qquickcontentitem_p.h \ $$PWD/qquickcontrol_p.h \ $$PWD/qquickcontrol_p_p.h \ $$PWD/qquickdeferredexecute_p_p.h \ @@ -47,14 +48,16 @@ HEADERS += \ $$PWD/qquickoverlay_p.h \ $$PWD/qquickoverlay_p_p.h \ $$PWD/qquickpage_p.h \ + $$PWD/qquickpage_p_p.h \ $$PWD/qquickpageindicator_p.h \ - $$PWD/qquickpagelayout_p_p.h \ $$PWD/qquickpalette_p.h \ $$PWD/qquickpaletteprovider_p.h \ $$PWD/qquickpane_p.h \ $$PWD/qquickpane_p_p.h \ $$PWD/qquickpopup_p.h \ $$PWD/qquickpopup_p_p.h \ + $$PWD/qquickpopupanchors_p.h \ + $$PWD/qquickpopupanchors_p_p.h \ $$PWD/qquickpopupitem_p_p.h \ $$PWD/qquickpopuppositioner_p_p.h \ $$PWD/qquickpresshandler_p_p.h \ @@ -86,6 +89,8 @@ HEADERS += \ $$PWD/qquicktextarea_p_p.h \ $$PWD/qquicktextfield_p.h \ $$PWD/qquicktextfield_p_p.h \ + $$PWD/qquicktheme_p.h \ + $$PWD/qquicktheme_p_p.h \ $$PWD/qquicktoolbar_p.h \ $$PWD/qquicktoolbutton_p.h \ $$PWD/qquicktoolseparator_p.h \ @@ -104,6 +109,7 @@ SOURCES += \ $$PWD/qquickcheckdelegate.cpp \ $$PWD/qquickcombobox.cpp \ $$PWD/qquickcontainer.cpp \ + $$PWD/qquickcontentitem.cpp \ $$PWD/qquickcontrol.cpp \ $$PWD/qquickdeferredexecute.cpp \ $$PWD/qquickdelaybutton.cpp \ @@ -124,11 +130,11 @@ SOURCES += \ $$PWD/qquickoverlay.cpp \ $$PWD/qquickpage.cpp \ $$PWD/qquickpageindicator.cpp \ - $$PWD/qquickpagelayout.cpp \ $$PWD/qquickpalette.cpp \ $$PWD/qquickpaletteprovider.cpp \ $$PWD/qquickpane.cpp \ $$PWD/qquickpopup.cpp \ + $$PWD/qquickpopupanchors.cpp \ $$PWD/qquickpopupitem.cpp \ $$PWD/qquickpopuppositioner.cpp \ $$PWD/qquickpresshandler.cpp \ @@ -155,6 +161,7 @@ SOURCES += \ $$PWD/qquicktabbutton.cpp \ $$PWD/qquicktextarea.cpp \ $$PWD/qquicktextfield.cpp \ + $$PWD/qquicktheme.cpp \ $$PWD/qquicktoolbar.cpp \ $$PWD/qquicktoolbutton.cpp \ $$PWD/qquicktoolseparator.cpp \ |