From 5adce042aa8c75970eef4cc8a5492b8d644ffcf7 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Tue, 13 Feb 2018 17:05:16 +0100 Subject: Control: add support for background insets [ChangeLog][Controls][Control] Added topInset, bottomInset, leftInset, and rightInset properties to control the geometry of the background similarly to how paddings control the geometry of the contentItem. Task-number: QTBUG-60156 Change-Id: Id8228d32f6a5fffeb771964a153ee062a5a083b5 Reviewed-by: Mitch Curtis --- src/quicktemplates2/qquickcontrol.cpp | 249 +++++++++++++++++++++++++++++--- src/quicktemplates2/qquickcontrol_p.h | 25 ++++ src/quicktemplates2/qquickcontrol_p_p.h | 19 +++ 3 files changed, 273 insertions(+), 20 deletions(-) (limited to 'src/quicktemplates2') diff --git a/src/quicktemplates2/qquickcontrol.cpp b/src/quicktemplates2/qquickcontrol.cpp index de68b4ef..8b571612 100644 --- a/src/quicktemplates2/qquickcontrol.cpp +++ b/src/quicktemplates2/qquickcontrol.cpp @@ -76,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. - The geometry of the \l {Control::}{contentItem} is determined by the - padding. + 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: + + \code + Control { + topInset: -2 + leftInset: -2 + rightInset: -6 + bottomInset: -6 + + background: BorderImage { + source: ":/images/shadowed-background.png" + } + } + \endcode \section1 Event Handling @@ -110,10 +143,18 @@ QQuickControlPrivate::ExtraData::ExtraData() hasRightPadding(false), hasBottomPadding(false), hasBaselineOffset(false), + hasTopInset(false), + hasLeftInset(false), + hasRightInset(false), + hasBottomInset(false), topPadding(0), leftPadding(0), rightPadding(0), - bottomPadding(0) + bottomPadding(0), + topInset(0), + leftInset(0), + rightInset(0), + bottomInset(0) { } @@ -306,19 +347,71 @@ void QQuickControlPrivate::setVerticalPadding(qreal value, bool reset) } } -void QQuickControlPrivate::resizeBackground() +void QQuickControlPrivate::setTopInset(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 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; + + QQuickItemPrivate *p = QQuickItemPrivate::get(background); + if ((!p->widthValid && qFuzzyIsNull(background->x())) + || (extra.isAllocated() && (extra->hasLeftInset || extra->hasRightInset))) { + background->setX(getLeftInset()); + background->setWidth(width - getLeftInset() - getRightInset()); + p->widthValid = false; + } + if ((!p->heightValid && qFuzzyIsNull(background->y())) + || (extra.isAllocated() && (extra->hasTopInset || extra->hasBottomInset))) { + background->setY(getTopInset()); + background->setHeight(height - getTopInset() - getBottomInset()); + p->heightValid = false; } } @@ -1691,7 +1784,8 @@ void QQuickControl::resetVerticalPadding() \code Control { - implicitWidth: Math.max(implicitBackgroundWidth, implicitContentWidth + leftPadding + rightPadding) + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) } \endcode @@ -1718,7 +1812,8 @@ qreal QQuickControl::implicitContentWidth() const \code Control { - implicitHeight: Math.max(implicitBackgroundHeight, implicitContentHeight + topPadding + bottomPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) } \endcode @@ -1744,7 +1839,8 @@ qreal QQuickControl::implicitContentHeight() const \code Control { - implicitWidth: Math.max(implicitBackgroundWidth, implicitContentWidth + leftPadding + rightPadding) + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) } \endcode @@ -1772,7 +1868,8 @@ qreal QQuickControl::implicitBackgroundWidth() const \code Control { - implicitHeight: Math.max(implicitBackgroundHeight, implicitContentHeight + topPadding + bottomPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) } \endcode @@ -1786,6 +1883,110 @@ qreal QQuickControl::implicitBackgroundHeight() const 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); @@ -2005,6 +2206,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 5716a725..a38e34f9 100644 --- a/src/quicktemplates2/qquickcontrol_p.h +++ b/src/quicktemplates2/qquickcontrol_p.h @@ -89,6 +89,10 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickControl : public QQuickItem 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: @@ -180,6 +184,22 @@ public: 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(); @@ -210,6 +230,10 @@ Q_SIGNALS: 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; @@ -253,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 f1873da9..757452a6 100644 --- a/src/quicktemplates2/qquickcontrol_p_p.h +++ b/src/quicktemplates2/qquickcontrol_p_p.h @@ -107,6 +107,17 @@ public: 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(); @@ -180,10 +191,18 @@ public: bool hasRightPadding; bool hasBottomPadding; bool hasBaselineOffset; + bool hasTopInset; + bool hasLeftInset; + bool hasRightInset; + bool hasBottomInset; qreal topPadding; qreal leftPadding; qreal rightPadding; qreal bottomPadding; + qreal topInset; + qreal leftInset; + qreal rightInset; + qreal bottomInset; QFont requestedFont; QPalette requestedPalette; }; -- cgit v1.2.3