diff options
Diffstat (limited to 'src/quicktemplates2/qquickdialogbuttonbox.cpp')
-rw-r--r-- | src/quicktemplates2/qquickdialogbuttonbox.cpp | 124 |
1 files changed, 103 insertions, 21 deletions
diff --git a/src/quicktemplates2/qquickdialogbuttonbox.cpp b/src/quicktemplates2/qquickdialogbuttonbox.cpp index e53313b1..03f5f8e8 100644 --- a/src/quicktemplates2/qquickdialogbuttonbox.cpp +++ b/src/quicktemplates2/qquickdialogbuttonbox.cpp @@ -192,16 +192,27 @@ QT_BEGIN_NAMESPACE \sa accepted(), rejected(), helpRequested() */ +static QPlatformDialogHelper::ButtonLayout platformButtonLayout() +{ + return QGuiApplicationPrivate::platformTheme()->themeHint(QPlatformTheme::DialogButtonBoxLayout).value<QPlatformDialogHelper::ButtonLayout>(); +} + 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() @@ -212,7 +223,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; @@ -230,11 +241,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()); @@ -251,8 +259,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); @@ -260,11 +268,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; @@ -274,6 +282,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); @@ -296,20 +309,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); @@ -405,6 +445,9 @@ void QQuickDialogButtonBoxPrivate::removeStandardButtons() QQuickDialogButtonBox::QQuickDialogButtonBox(QQuickItem *parent) : QQuickContainer(*(new QQuickDialogButtonBoxPrivate), parent) { + Q_D(QQuickDialogButtonBox); + d->changeTypes |= QQuickItemPrivate::ImplicitWidth | QQuickItemPrivate::ImplicitHeight; + d->buttonLayout = platformButtonLayout(); } QQuickDialogButtonBox::~QQuickDialogButtonBox() @@ -596,6 +639,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. +*/ +QPlatformDialogHelper::ButtonLayout QQuickDialogButtonBox::buttonLayout() const +{ + Q_D(const QQuickDialogButtonBox); + return d->buttonLayout; +} + +void QQuickDialogButtonBox::setButtonLayout(QPlatformDialogHelper::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); @@ -640,6 +720,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(); } @@ -652,6 +733,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(); } |