aboutsummaryrefslogtreecommitdiffstats
path: root/src/quicktemplates2
diff options
context:
space:
mode:
Diffstat (limited to 'src/quicktemplates2')
-rw-r--r--src/quicktemplates2/qquickabstractbutton.cpp6
-rw-r--r--src/quicktemplates2/qquickabstractbutton_p_p.h1
-rw-r--r--src/quicktemplates2/qquickapplicationwindow.cpp90
-rw-r--r--src/quicktemplates2/qquickbutton.cpp17
-rw-r--r--src/quicktemplates2/qquickcheckbox.cpp6
-rw-r--r--src/quicktemplates2/qquickcheckdelegate.cpp13
-rw-r--r--src/quicktemplates2/qquickcontainer.cpp6
-rw-r--r--src/quicktemplates2/qquickcontrol.cpp130
-rw-r--r--src/quicktemplates2/qquickdial.cpp17
-rw-r--r--src/quicktemplates2/qquickdrawer.cpp101
-rw-r--r--src/quicktemplates2/qquickdrawer_p.h2
-rw-r--r--src/quicktemplates2/qquickdrawer_p_p.h3
-rw-r--r--src/quicktemplates2/qquickframe.cpp4
-rw-r--r--src/quicktemplates2/qquickgroupbox.cpp11
-rw-r--r--src/quicktemplates2/qquickmenu.cpp42
-rw-r--r--src/quicktemplates2/qquickmenuitem.cpp35
-rw-r--r--src/quicktemplates2/qquickoverlay.cpp20
-rw-r--r--src/quicktemplates2/qquickoverlay_p_p.h1
-rw-r--r--src/quicktemplates2/qquickpage.cpp47
-rw-r--r--src/quicktemplates2/qquickpopup.cpp116
-rw-r--r--src/quicktemplates2/qquickpopup_p_p.h7
-rw-r--r--src/quicktemplates2/qquickswitch.cpp147
-rw-r--r--src/quicktemplates2/qquickswitch_p.h8
-rw-r--r--src/quicktemplates2/qquickswitchdelegate.cpp65
-rw-r--r--src/quicktemplates2/qquickswitchdelegate_p.h7
25 files changed, 648 insertions, 254 deletions
diff --git a/src/quicktemplates2/qquickabstractbutton.cpp b/src/quicktemplates2/qquickabstractbutton.cpp
index 9c840493..f2442cb7 100644
--- a/src/quicktemplates2/qquickabstractbutton.cpp
+++ b/src/quicktemplates2/qquickabstractbutton.cpp
@@ -105,7 +105,7 @@ static const int AUTO_REPEAT_INTERVAL = 100;
*/
QQuickAbstractButtonPrivate::QQuickAbstractButtonPrivate() :
- down(false), explicitDown(false), pressed(false), checked(false), checkable(false),
+ down(false), explicitDown(false), pressed(false), keepPressed(false), checked(false), checkable(false),
autoExclusive(false), autoRepeat(false), wasHeld(false),
holdTimer(0), delayTimer(0), repeatTimer(0), repeatButton(Qt::NoButton), indicator(nullptr), group(nullptr)
{
@@ -525,7 +525,7 @@ void QQuickAbstractButton::mouseMoveEvent(QMouseEvent *event)
{
Q_D(QQuickAbstractButton);
QQuickControl::mouseMoveEvent(event);
- setPressed(contains(event->pos()));
+ setPressed(d->keepPressed || contains(event->pos()));
if (d->autoRepeat)
d->stopPressRepeat();
@@ -540,7 +540,7 @@ void QQuickAbstractButton::mouseReleaseEvent(QMouseEvent *event)
bool wasPressed = d->pressed;
setPressed(false);
- if (contains(event->pos()))
+ if (d->keepPressed || contains(event->pos()))
nextCheckState();
if (wasPressed) {
diff --git a/src/quicktemplates2/qquickabstractbutton_p_p.h b/src/quicktemplates2/qquickabstractbutton_p_p.h
index a7d4d6c2..688ad804 100644
--- a/src/quicktemplates2/qquickabstractbutton_p_p.h
+++ b/src/quicktemplates2/qquickabstractbutton_p_p.h
@@ -82,6 +82,7 @@ public:
bool down;
bool explicitDown;
bool pressed;
+ bool keepPressed;
bool checked;
bool checkable;
bool autoExclusive;
diff --git a/src/quicktemplates2/qquickapplicationwindow.cpp b/src/quicktemplates2/qquickapplicationwindow.cpp
index 7f466fd7..7fb406c1 100644
--- a/src/quicktemplates2/qquickapplicationwindow.cpp
+++ b/src/quicktemplates2/qquickapplicationwindow.cpp
@@ -443,7 +443,7 @@ QQuickItem *QQuickApplicationWindow::contentItem() const
The difference between \l Window::activeFocusItem and ApplicationWindow::activeFocusControl
is that the former may point to a building block of a control, whereas the latter points
to the enclosing control. For example, when SpinBox has focus, activeFocusItem points to
- the editor and acticeFocusControl to the SpinBox itself.
+ the editor and activeFocusControl to the SpinBox itself.
\sa Window::activeFocusItem
*/
@@ -622,47 +622,49 @@ public:
void windowChange(QQuickWindow *wnd);
- QQuickApplicationWindow *window;
+ QQuickWindow *window;
};
void QQuickApplicationWindowAttachedPrivate::windowChange(QQuickWindow *wnd)
{
Q_Q(QQuickApplicationWindowAttached);
- if (window && !QQuickApplicationWindowPrivate::get(window))
- window = nullptr; // being deleted (QTBUG-52731)
+ if (window == wnd)
+ return;
- QQuickApplicationWindow *newWindow = qobject_cast<QQuickApplicationWindow *>(wnd);
- if (window != newWindow) {
- QQuickApplicationWindow *oldWindow = window;
- if (oldWindow) {
- QObject::disconnect(oldWindow, &QQuickApplicationWindow::activeFocusControlChanged,
- q, &QQuickApplicationWindowAttached::activeFocusControlChanged);
- QObject::disconnect(oldWindow, &QQuickApplicationWindow::headerChanged,
- q, &QQuickApplicationWindowAttached::headerChanged);
- QObject::disconnect(oldWindow, &QQuickApplicationWindow::footerChanged,
- q, &QQuickApplicationWindowAttached::footerChanged);
- }
- if (newWindow) {
- QObject::connect(newWindow, &QQuickApplicationWindow::activeFocusControlChanged,
- q, &QQuickApplicationWindowAttached::activeFocusControlChanged);
- QObject::connect(newWindow, &QQuickApplicationWindow::headerChanged,
- q, &QQuickApplicationWindowAttached::headerChanged);
- QObject::connect(newWindow, &QQuickApplicationWindow::footerChanged,
- q, &QQuickApplicationWindowAttached::footerChanged);
- }
+ QQuickApplicationWindow *oldWindow = qobject_cast<QQuickApplicationWindow *>(window);
+ if (oldWindow && !QQuickApplicationWindowPrivate::get(oldWindow))
+ oldWindow = nullptr; // being deleted (QTBUG-52731)
+
+ if (oldWindow) {
+ QObject::disconnect(oldWindow, &QQuickApplicationWindow::activeFocusControlChanged,
+ q, &QQuickApplicationWindowAttached::activeFocusControlChanged);
+ QObject::disconnect(oldWindow, &QQuickApplicationWindow::headerChanged,
+ q, &QQuickApplicationWindowAttached::headerChanged);
+ QObject::disconnect(oldWindow, &QQuickApplicationWindow::footerChanged,
+ q, &QQuickApplicationWindowAttached::footerChanged);
+ }
- window = newWindow;
- emit q->windowChanged();
- emit q->contentItemChanged();
- emit q->overlayChanged();
-
- if ((oldWindow && oldWindow->activeFocusControl()) || (newWindow && newWindow->activeFocusControl()))
- emit q->activeFocusControlChanged();
- if ((oldWindow && oldWindow->header()) || (newWindow && newWindow->header()))
- emit q->headerChanged();
- if ((oldWindow && oldWindow->footer()) || (newWindow && newWindow->footer()))
- emit q->footerChanged();
+ QQuickApplicationWindow *newWindow = qobject_cast<QQuickApplicationWindow *>(wnd);
+ if (newWindow) {
+ QObject::connect(newWindow, &QQuickApplicationWindow::activeFocusControlChanged,
+ q, &QQuickApplicationWindowAttached::activeFocusControlChanged);
+ QObject::connect(newWindow, &QQuickApplicationWindow::headerChanged,
+ q, &QQuickApplicationWindowAttached::headerChanged);
+ QObject::connect(newWindow, &QQuickApplicationWindow::footerChanged,
+ q, &QQuickApplicationWindowAttached::footerChanged);
}
+
+ window = wnd;
+ emit q->windowChanged();
+ emit q->contentItemChanged();
+ emit q->overlayChanged();
+
+ if ((oldWindow && oldWindow->activeFocusControl()) || (newWindow && newWindow->activeFocusControl()))
+ emit q->activeFocusControlChanged();
+ if ((oldWindow && oldWindow->header()) || (newWindow && newWindow->header()))
+ emit q->headerChanged();
+ if ((oldWindow && oldWindow->footer()) || (newWindow && newWindow->footer()))
+ emit q->footerChanged();
}
QQuickApplicationWindowAttached::QQuickApplicationWindowAttached(QObject *parent)
@@ -698,7 +700,7 @@ QQuickApplicationWindowAttached::QQuickApplicationWindowAttached(QObject *parent
QQuickApplicationWindow *QQuickApplicationWindowAttached::window() const
{
Q_D(const QQuickApplicationWindowAttached);
- return d->window;
+ return qobject_cast<QQuickApplicationWindow *>(d->window);
}
/*!
@@ -711,7 +713,9 @@ QQuickApplicationWindow *QQuickApplicationWindowAttached::window() const
QQuickItem *QQuickApplicationWindowAttached::contentItem() const
{
Q_D(const QQuickApplicationWindowAttached);
- return d->window ? d->window->contentItem() : nullptr;
+ if (QQuickApplicationWindow *window = qobject_cast<QQuickApplicationWindow *>(d->window))
+ return window->contentItem();
+ return nullptr;
}
/*!
@@ -728,7 +732,9 @@ QQuickItem *QQuickApplicationWindowAttached::contentItem() const
QQuickItem *QQuickApplicationWindowAttached::activeFocusControl() const
{
Q_D(const QQuickApplicationWindowAttached);
- return d->window ? d->window->activeFocusControl() : nullptr;
+ if (QQuickApplicationWindow *window = qobject_cast<QQuickApplicationWindow *>(d->window))
+ return window->activeFocusControl();
+ return nullptr;
}
/*!
@@ -742,7 +748,9 @@ QQuickItem *QQuickApplicationWindowAttached::activeFocusControl() const
QQuickItem *QQuickApplicationWindowAttached::header() const
{
Q_D(const QQuickApplicationWindowAttached);
- return d->window ? d->window->header() : nullptr;
+ if (QQuickApplicationWindow *window = qobject_cast<QQuickApplicationWindow *>(d->window))
+ return window->header();
+ return nullptr;
}
/*!
@@ -756,7 +764,9 @@ QQuickItem *QQuickApplicationWindowAttached::header() const
QQuickItem *QQuickApplicationWindowAttached::footer() const
{
Q_D(const QQuickApplicationWindowAttached);
- return d->window ? d->window->footer() : nullptr;
+ if (QQuickApplicationWindow *window = qobject_cast<QQuickApplicationWindow *>(d->window))
+ return window->footer();
+ return nullptr;
}
/*!
@@ -769,7 +779,7 @@ QQuickItem *QQuickApplicationWindowAttached::footer() const
QQuickOverlay *QQuickApplicationWindowAttached::overlay() const
{
Q_D(const QQuickApplicationWindowAttached);
- return d->window ? d->window->overlay() : nullptr;
+ return QQuickOverlay::overlay(d->window);
}
QT_END_NAMESPACE
diff --git a/src/quicktemplates2/qquickbutton.cpp b/src/quicktemplates2/qquickbutton.cpp
index 19310713..591c4316 100644
--- a/src/quicktemplates2/qquickbutton.cpp
+++ b/src/quicktemplates2/qquickbutton.cpp
@@ -110,6 +110,17 @@ QQuickButton::QQuickButton(QQuickButtonPrivate &dd, QQuickItem *parent) :
\qmlproperty bool QtQuick.Controls::Button::checkable
This property holds whether the button is checkable.
+
+ A checkable button toggles between checked (on) and unchecked (off) when
+ the user clicks on it or presses the space bar while the button has active
+ focus.
+
+ Setting \l {AbstractButton::}{checked} to \c true forces this property to
+ \c true.
+
+ The default value is \c false.
+
+ \sa CheckBox, Switch
*/
void QQuickButton::checkableChange()
@@ -120,8 +131,10 @@ void QQuickButton::checkableChange()
/*!
\qmlproperty bool QtQuick.Controls::Button::autoRepeat
- This property holds whether the button repeats pressed(), released()
- and clicked() signals while the button is pressed and held down.
+ This property holds whether the button repeats
+ \l {AbstractButton::}{pressed()}, \l {AbstractButton::}{released()}
+ and \l {AbstractButton::}{clicked()} signals while the button is pressed
+ and held down.
The default value is \c false.
*/
diff --git a/src/quicktemplates2/qquickcheckbox.cpp b/src/quicktemplates2/qquickcheckbox.cpp
index 1daf69dc..a777c2b4 100644
--- a/src/quicktemplates2/qquickcheckbox.cpp
+++ b/src/quicktemplates2/qquickcheckbox.cpp
@@ -52,9 +52,11 @@ QT_BEGIN_NAMESPACE
CheckBox presents an option button that can be toggled on (checked) or
off (unchecked). Check boxes are typically used to select one or more
- options from a set of options.
+ options from a set of options. For larger sets of options, such as those
+ in a list, consider using \l CheckDelegate instead.
- The state of the checkbox can be set with the \l {AbstractButton::}{checked} property.
+ CheckBox inherits its API from \l AbstractButton. For instance, the
+ state of the checkbox can be set with the \l {AbstractButton::}{checked} property.
In addition to the checked and unchecked states, there is a third state:
partially checked. The partially checked state can be enabled using the
diff --git a/src/quicktemplates2/qquickcheckdelegate.cpp b/src/quicktemplates2/qquickcheckdelegate.cpp
index 09be5d60..249aaa95 100644
--- a/src/quicktemplates2/qquickcheckdelegate.cpp
+++ b/src/quicktemplates2/qquickcheckdelegate.cpp
@@ -54,9 +54,14 @@ QT_BEGIN_NAMESPACE
CheckDelegate presents an item delegate that can be toggled on (checked) or
off (unchecked). Check delegates are typically used to select one or more
- options from a set of options.
-
- The state of the check delegate can be set with the
+ options from a set of options in a list. For smaller sets of options, or
+ for options that need to be uniquely identifiable, consider using
+ \l CheckBox instead.
+
+ CheckDelegate inherits its API from \l ItemDelegate, which is inherited
+ from AbstractButton. For instance, you can set \l {AbstractButton::text}{text},
+ and react to \l {AbstractButton::clicked}{clicks} using the AbstractButton
+ API. The state of the check delegate can be set with the
\l {AbstractButton::}{checked} property.
In addition to the checked and unchecked states, there is a third state:
@@ -75,7 +80,7 @@ QT_BEGIN_NAMESPACE
}
\endcode
- \sa {Customizing CheckDelegate}, {Delegate Controls}
+ \sa {Customizing CheckDelegate}, {Delegate Controls}, CheckBox
*/
class QQuickCheckDelegatePrivate : public QQuickItemDelegatePrivate
diff --git a/src/quicktemplates2/qquickcontainer.cpp b/src/quicktemplates2/qquickcontainer.cpp
index 31a92b5d..d9859b7d 100644
--- a/src/quicktemplates2/qquickcontainer.cpp
+++ b/src/quicktemplates2/qquickcontainer.cpp
@@ -55,9 +55,11 @@ QT_BEGIN_NAMESPACE
\section2 Using Containers
- Container provides an API to \l {addItem}{add}, \l {insertItem}{insert},
+ Typically, items are statically declared as children of Container, but it
+ is also possible to \l {addItem}{add}, \l {insertItem}{insert},
\l {moveItem}{move} and \l {removeItem}{remove} items dynamically. The
- items in a container can be accessed using \l itemAt() or \l contentChildren.
+ items in a container can be accessed using \l itemAt() or
+ \l contentChildren.
Most containers have the concept of a "current" item. The current item is
specified via the \l currentIndex property, and can be accessed using the
diff --git a/src/quicktemplates2/qquickcontrol.cpp b/src/quicktemplates2/qquickcontrol.cpp
index 642e2e72..518255dd 100644
--- a/src/quicktemplates2/qquickcontrol.cpp
+++ b/src/quicktemplates2/qquickcontrol.cpp
@@ -70,8 +70,26 @@ QT_BEGIN_NAMESPACE
events from the window system, and paints a representation of itself on
the screen.
+ \section1 Control Layout
+
+ The following diagram illustrates the layout of a typical control:
+
\image qtquickcontrols2-control.png
+ 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
+ the control will be when no explicit \l {Item::}{width} or
+ \l {Item::}{height} is specified.
+
+ The \l {Control::}{background} item fills the entire width and height of the
+ control, unless an explicit size has been given for it.
+
+ The geometry of the \l {Control::}{contentItem} is determined by the
+ padding.
+
+ \section1 Event Handling
+
All controls, except non-interactive indicators, do not let clicks and
touches through to items below them. For example, if \l Pane is used as the
\l {ApplicationWindow::}{header} or \l {ApplicationWindow::}{footer} of
@@ -397,6 +415,10 @@ void QQuickControl::itemChange(QQuickItem::ItemChange change, const QQuickItem::
Q_D(QQuickControl);
QQuickItem::itemChange(change, value);
switch (change) {
+ case ItemVisibleHasChanged:
+ if (!value.boolValue)
+ setHovered(false);
+ break;
case ItemParentHasChanged:
if (value.item) {
d->resolveFont();
@@ -432,6 +454,22 @@ void QQuickControl::itemChange(QQuickItem::ItemChange change, const QQuickItem::
Control propagates explicit font properties from parent to children. If you change a specific
property on a control's font, that property propagates to all of the control's children,
overriding any system defaults for that property.
+
+ \code
+ Page {
+ font.family: "Courier"
+
+ Column {
+ Label {
+ text: qsTr("This will use Courier...")
+ }
+
+ Switch {
+ text: qsTr("... and so will this")
+ }
+ }
+ }
+ \endcode
*/
QFont QQuickControl::font() const
{
@@ -458,9 +496,10 @@ void QQuickControl::resetFont()
\qmlproperty real QtQuick.Controls::Control::availableWidth
\readonly
- This property holds the width available after deducting horizontal padding.
+ This property holds the width available to the \l contentItem after
+ deducting horizontal padding from the \l {Item::}{width} of the control.
- \sa padding, leftPadding, rightPadding
+ \sa {Control Layout}, padding, leftPadding, rightPadding
*/
qreal QQuickControl::availableWidth() const
{
@@ -471,9 +510,10 @@ qreal QQuickControl::availableWidth() const
\qmlproperty real QtQuick.Controls::Control::availableHeight
\readonly
- This property holds the height available after deducting vertical padding.
+ This property holds the height available to the \l contentItem after
+ deducting vertical padding from the \l {Item::}{height} of the control.
- \sa padding, topPadding, bottomPadding
+ \sa {Control Layout}, padding, topPadding, bottomPadding
*/
qreal QQuickControl::availableHeight() const
{
@@ -485,7 +525,19 @@ qreal QQuickControl::availableHeight() const
This property holds the default padding.
- \sa availableWidth, availableHeight, topPadding, leftPadding, rightPadding, bottomPadding
+ Padding adds a space between each edge of the content item and the
+ background item, effectively controlling the size of the content item. To
+ specify a padding value for a specific edge of the control, set its
+ relevant property:
+
+ \list
+ \li \l {Control::}{leftPadding}
+ \li \l {Control::}{rightPadding}
+ \li \l {Control::}{topPadding}
+ \li \l {Control::}{bottomPadding}
+ \endlist
+
+ \sa {Control Layout}, availableWidth, availableHeight, topPadding, leftPadding, rightPadding, bottomPadding
*/
qreal QQuickControl::padding() const
{
@@ -527,7 +579,7 @@ void QQuickControl::resetPadding()
This property holds the top padding.
- \sa padding, bottomPadding, availableHeight
+ \sa {Control Layout}, padding, bottomPadding, availableHeight
*/
qreal QQuickControl::topPadding() const
{
@@ -554,7 +606,7 @@ void QQuickControl::resetTopPadding()
This property holds the left padding.
- \sa padding, rightPadding, availableWidth
+ \sa {Control Layout}, padding, rightPadding, availableWidth
*/
qreal QQuickControl::leftPadding() const
{
@@ -581,7 +633,7 @@ void QQuickControl::resetLeftPadding()
This property holds the right padding.
- \sa padding, leftPadding, availableWidth
+ \sa {Control Layout}, padding, leftPadding, availableWidth
*/
qreal QQuickControl::rightPadding() const
{
@@ -608,7 +660,7 @@ void QQuickControl::resetRightPadding()
This property holds the bottom padding.
- \sa padding, topPadding, availableHeight
+ \sa {Control Layout}, padding, topPadding, availableHeight
*/
qreal QQuickControl::bottomPadding() const
{
@@ -634,6 +686,12 @@ void QQuickControl::resetBottomPadding()
\qmlproperty real QtQuick.Controls::Control::spacing
This property holds the spacing.
+
+ Spacing is useful for controls that have multiple or repetitive building
+ blocks. For example, some styles use spacing to determine the distance
+ between the text and indicator of \l CheckBox. Spacing is not enforced by
+ Control, so each style may interpret it differently, and some may ignore it
+ altogether.
*/
qreal QQuickControl::spacing() const
{
@@ -766,9 +824,11 @@ void QQuickControlPrivate::updateLocaleRecur(QQuickItem *item, const QLocale &l)
This property holds whether the control is mirrored.
This property is provided for convenience. A control is considered mirrored
- when its visual layout direction is right-to-left.
+ when its visual layout direction is right-to-left; that is, when using a
+ right-to-left locale or when \l {LayoutMirroring::enabled}{LayoutMirroring.enabled}
+ is \c true.
- \sa locale, {LayoutMirroring}{LayoutMirroring}
+ \sa locale, {LayoutMirroring}{LayoutMirroring}, {Right-to-left User Interfaces}
*/
bool QQuickControl::isMirrored() const
{
@@ -917,6 +977,10 @@ void QQuickControl::setHoverEnabled(bool enabled)
\qmlproperty bool QtQuick.Controls::Control::wheelEnabled
This property determines whether the control handles wheel events. The default value is \c false.
+
+ \note Care must be taken when enabling wheel events for controls within scrollable items such
+ as \l Flickable, as the control will consume the events and hence interrupt scrolling of the
+ Flickable.
*/
bool QQuickControl::isWheelEnabled() const
{
@@ -939,9 +1003,30 @@ void QQuickControl::setWheelEnabled(bool enabled)
This property holds the background item.
+ \code
+ Button {
+ id: control
+ text: qsTr("Button")
+ background: Rectangle {
+ implicitWidth: 100
+ implicitHeight: 40
+ opacity: enabled ? 1 : 0.3
+ color: control.down ? "#d0d0d0" : "#e0e0e0"
+ }
+ }
+ \endcode
+
\note If the background item has no explicit size specified, it automatically
follows the control's size. In most cases, there is no need to specify
width or height for a background item.
+
+ \note Most controls use the implicit size of the background item to calculate
+ the implicit size of the control itself. If you replace the background item
+ with a custom one, you should also consider providing a sensible implicit
+ size for it (unless it is an item like \l Image which has its own implicit
+ size).
+
+ \sa {Control Layout}
*/
QQuickItem *QQuickControl::background() const
{
@@ -972,7 +1057,28 @@ void QQuickControl::setBackground(QQuickItem *background)
This property holds the visual content item.
- \note The content item is automatically resized inside the \l padding of the control.
+ \note The content item is automatically resized to fit within the
+ \l padding of the control.
+
+ \note Most controls use the implicit size of the content item to calculate
+ the implicit size of the control itself. If you replace the content item
+ with a custom one, you should also consider providing a sensible implicit
+ size for it (unless it is an item like \l Text which has its own implicit
+ size).
+
+ \code
+ Button {
+ id: control
+ text: qsTr("Button")
+ contentItem: Label {
+ text: control.text
+ font: control.font
+ verticalAlignment: Text.AlignVCenter
+ }
+ }
+ \endcode
+
+ \sa {Control Layout}, padding
*/
QQuickItem *QQuickControl::contentItem() const
{
diff --git a/src/quicktemplates2/qquickdial.cpp b/src/quicktemplates2/qquickdial.cpp
index 3b096255..48d02faa 100644
--- a/src/quicktemplates2/qquickdial.cpp
+++ b/src/quicktemplates2/qquickdial.cpp
@@ -300,6 +300,8 @@ qreal QQuickDial::position() const
Like the \l position property, angle is continuously updated while the
handle is dragged.
+ The range is from \c -140 degrees to \c 140 degrees.
+
\sa position
*/
qreal QQuickDial::angle() const
@@ -311,7 +313,18 @@ qreal QQuickDial::angle() const
/*!
\qmlproperty real QtQuick.Controls::Dial::stepSize
- This property holds the step size. The default value is \c 0.0.
+ This property holds the step size.
+
+ The step size determines the amount by which the dial's value
+ is increased and decreased when interacted with via the keyboard.
+ For example, a step size of \c 0.2, will result in the dial's
+ value increasing and decreasing in increments of \c 0.2.
+
+ The step size is only respected for touch and mouse interaction
+ when \l snapMode is set to a value other than \c Dial.NoSnap.
+
+ The default value is \c 0.0, which results in an effective step
+ size of \c 0.1 for keyboard interaction.
\sa snapMode, increase(), decrease()
*/
@@ -460,7 +473,7 @@ void QQuickDial::decrease()
}
/*!
- \qmlproperty component QtQuick.Controls::Dial::handle
+ \qmlproperty Item QtQuick.Controls::Dial::handle
This property holds the handle of the dial.
diff --git a/src/quicktemplates2/qquickdrawer.cpp b/src/quicktemplates2/qquickdrawer.cpp
index 4c9fbb62..bc1636de 100644
--- a/src/quicktemplates2/qquickdrawer.cpp
+++ b/src/quicktemplates2/qquickdrawer.cpp
@@ -69,6 +69,54 @@ QT_BEGIN_NAMESPACE
of the window.
\endtable
+ \code
+ import QtQuick 2.7
+ import QtQuick.Controls 2.0
+
+ ApplicationWindow {
+ id: window
+ visible: true
+
+ Drawer {
+ id: drawer
+ width: 0.66 * window.width
+ height: window.height
+ }
+ }
+ \endcode
+
+ Drawer is a special type of popup that resides at one of the window \l {edge}{edges}.
+ By default, Drawer re-parents itself to the window \l {ApplicationWindow::}{overlay},
+ and therefore operates on window coordinates. It is also possible to manually set the
+ \l {Popup::}{parent} to something else to make the drawer operate in a specific
+ coordinate space.
+
+ Drawer can be configured to cover only part of its window edge. The following example
+ illustrates how Drawer can be positioned to appear below a window header:
+
+ \code
+ import QtQuick 2.7
+ import QtQuick.Controls 2.0
+
+ ApplicationWindow {
+ id: window
+ visible: true
+
+ header: ToolBar { }
+
+ Drawer {
+ y: header.height
+ width: window.width * 0.6
+ height: window.height - header.height
+ }
+ }
+ \endcode
+
+ The \l position property determines how much of the drawer is visible, as
+ a value between \c 0.0 and \c 1.0. It is not possible to set the x-coordinate
+ (or horizontal margins) of a drawer at the left or right window edge, or the
+ y-coordinate (or vertical margins) of a drawer at the top or bottom window edge.
+
In the image above, the application's contents are \e "pushed" across the
screen. This is achieved by applying a translation to the contents:
@@ -117,6 +165,7 @@ QQuickDrawerPrivate::QQuickDrawerPrivate()
: edge(Qt::LeftEdge), offset(0), position(0),
dragMargin(QGuiApplication::styleHints()->startDragDistance())
{
+ setEdge(Qt::LeftEdge);
}
qreal QQuickDrawerPrivate::positionAt(const QPointF &point) const
@@ -161,6 +210,27 @@ void QQuickDrawerPrivate::reposition()
popupItem->setY(window->height() - position * popupItem->height());
break;
}
+
+ QQuickPopupPrivate::reposition();
+}
+
+void QQuickDrawerPrivate::resizeOverlay()
+{
+ if (!dimmer || !window)
+ return;
+
+ QRectF geometry(0, 0, window->width(), window->height());
+
+ if (edge == Qt::LeftEdge || edge == Qt::RightEdge) {
+ geometry.setY(popupItem->y());
+ geometry.setHeight(popupItem->height());
+ } else {
+ geometry.setX(popupItem->x());
+ geometry.setWidth(popupItem->width());
+ }
+
+ dimmer->setPosition(geometry.topLeft());
+ dimmer->setSize(geometry.size());
}
static bool dragOverThreshold(qreal d, Qt::Axis axis, QMouseEvent *event, int threshold = -1)
@@ -309,6 +379,12 @@ bool QQuickDrawerPrivate::handleMouseMoveEvent(QQuickItem *item, QMouseEvent *ev
Q_Q(QQuickDrawer);
Q_UNUSED(item);
+ // Don't react to synthesized mouse move events at INF,INF coordinates.
+ // QQuickWindowPrivate::translateTouchToMouse() uses them to clear hover
+ // on touch release (QTBUG-55995).
+ if (qIsInf(event->screenPos().x()) || qIsInf(event->screenPos().y()))
+ return true;
+
const QPointF movePoint = event->windowPos();
if (grabMouse(event)) {
@@ -374,6 +450,22 @@ bool QQuickDrawerPrivate::prepareExitTransition()
return QQuickPopupPrivate::prepareExitTransition();
}
+void QQuickDrawerPrivate::setEdge(Qt::Edge e)
+{
+ edge = e;
+ if (edge == Qt::LeftEdge || edge == Qt::RightEdge) {
+ allowVerticalMove = true;
+ allowVerticalResize = true;
+ allowHorizontalMove = false;
+ allowHorizontalResize = false;
+ } else {
+ allowVerticalMove = false;
+ allowVerticalResize = false;
+ allowHorizontalMove = true;
+ allowHorizontalResize = true;
+ }
+}
+
QQuickDrawer::QQuickDrawer(QObject *parent) :
QQuickPopup(*(new QQuickDrawerPrivate), parent)
{
@@ -406,7 +498,7 @@ void QQuickDrawer::setEdge(Qt::Edge edge)
if (d->edge == edge)
return;
- d->edge = edge;
+ d->setEdge(edge);
if (isComponentComplete())
d->reposition();
emit edgeChanged();
@@ -531,4 +623,11 @@ bool QQuickDrawer::overlayEvent(QQuickItem *item, QEvent *event)
}
}
+void QQuickDrawer::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
+{
+ Q_D(QQuickDrawer);
+ QQuickPopup::geometryChanged(newGeometry, oldGeometry);
+ d->resizeOverlay();
+}
+
QT_END_NAMESPACE
diff --git a/src/quicktemplates2/qquickdrawer_p.h b/src/quicktemplates2/qquickdrawer_p.h
index e694e27b..bada1344 100644
--- a/src/quicktemplates2/qquickdrawer_p.h
+++ b/src/quicktemplates2/qquickdrawer_p.h
@@ -87,6 +87,8 @@ protected:
void mouseUngrabEvent() override;
bool overlayEvent(QQuickItem *item, QEvent *event) override;
+ void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) override;
+
private:
Q_DISABLE_COPY(QQuickDrawer)
Q_DECLARE_PRIVATE(QQuickDrawer)
diff --git a/src/quicktemplates2/qquickdrawer_p_p.h b/src/quicktemplates2/qquickdrawer_p_p.h
index f14c36dd..b7555c3e 100644
--- a/src/quicktemplates2/qquickdrawer_p_p.h
+++ b/src/quicktemplates2/qquickdrawer_p_p.h
@@ -68,6 +68,7 @@ public:
qreal positionAt(const QPointF &point) const;
void reposition() override;
+ void resizeOverlay() override;
bool startDrag(QQuickWindow *window, QMouseEvent *event);
bool grabMouse(QMouseEvent *event);
@@ -80,6 +81,8 @@ public:
bool prepareEnterTransition() override;
bool prepareExitTransition() override;
+ void setEdge(Qt::Edge edge);
+
Qt::Edge edge;
qreal offset;
qreal position;
diff --git a/src/quicktemplates2/qquickframe.cpp b/src/quicktemplates2/qquickframe.cpp
index 2f2a5497..bcc387c1 100644
--- a/src/quicktemplates2/qquickframe.cpp
+++ b/src/quicktemplates2/qquickframe.cpp
@@ -54,8 +54,8 @@ QT_BEGIN_NAMESPACE
or a \l ColumnLayout.
Items declared as children of a Frame are automatically parented to the
- Frame's contentItem. Items created dynamically need to be explicitly
- parented to the contentItem.
+ Frame's \l {Control::}{contentItem}. Items created dynamically need to be
+ explicitly parented to the contentItem.
If only a single item is used within a Frame, it will resize to fit the
implicit size of its contained item. This makes it particularly suitable
diff --git a/src/quicktemplates2/qquickgroupbox.cpp b/src/quicktemplates2/qquickgroupbox.cpp
index 45fe406f..27c325ef 100644
--- a/src/quicktemplates2/qquickgroupbox.cpp
+++ b/src/quicktemplates2/qquickgroupbox.cpp
@@ -48,10 +48,10 @@ QT_BEGIN_NAMESPACE
\inqmlmodule QtQuick.Controls
\since 5.7
\ingroup qtquickcontrols2-containers
- \brief A frame with a logical group of controls.
+ \brief A logical group of controls within a titled visual frame.
GroupBox is used to layout a logical group of controls together, within
- a titled visual frame. GroupBox does not provide a layout of its own, but
+ a \l {title}{titled} visual frame. GroupBox does not provide a layout of its own, but
requires you to position its contents, for instance by creating a \l RowLayout
or a \l ColumnLayout.
@@ -75,8 +75,8 @@ QT_BEGIN_NAMESPACE
\image qtquickcontrols2-groupbox-checkable.png
It is a common pattern to enable or disable the groupbox's children when
- its checkbox is toggled on or off, but it is the application that decides
- on the behavior of the groupbox.
+ its checkbox is toggled on or off, but it is up to the application to decide
+ on the behavior of the checkbox.
\snippet qtquickcontrols2-groupbox-checkable.qml 1
@@ -101,6 +101,9 @@ QQuickGroupBox::QQuickGroupBox(QQuickItem *parent) :
\qmlproperty string QtQuick.Controls::GroupBox::title
This property holds the title.
+
+ The title is typically displayed above the groupbox to
+ summarize its contents.
*/
QString QQuickGroupBox::title() const
{
diff --git a/src/quicktemplates2/qquickmenu.cpp b/src/quicktemplates2/qquickmenu.cpp
index b8522668..bf37f801 100644
--- a/src/quicktemplates2/qquickmenu.cpp
+++ b/src/quicktemplates2/qquickmenu.cpp
@@ -89,6 +89,15 @@ QT_BEGIN_NAMESPACE
}
\endcode
+ Typically, menu items are statically declared as children of the menu, but
+ Menu also provides API to \l {addItem}{add}, \l {insertItem}{insert},
+ \l {moveItem}{move} and \l {removeItem}{remove} items dynamically. The
+ items in a menu can be accessed using \l itemAt() or
+ \l {Popup::}{contentChildren}.
+
+ Although \l {MenuItem}{MenuItems} are most commonly used with Menu, it can
+ contain any type of item.
+
\sa {Customizing Menu}, {Menu Controls}, {Popup Controls}
*/
@@ -350,7 +359,7 @@ void QQuickMenu::moveItem(int from, int to)
/*!
\qmlmethod void QtQuick.Controls::Menu::removeItem(int index)
- Removes an item at \a index.
+ Removes the item at \a index.
\note The ownership of the item is transferred to the caller.
*/
@@ -372,8 +381,20 @@ void QQuickMenu::removeItem(int index)
This property holds the model used to display menu items.
- By default, the model is an \l ObjectModel, in order to allow declaring
- menu items as children of the menu.
+ The content model is provided for visualization purposes. It can be assigned
+ as a model to a content item that presents the contents of the menu.
+
+ \code
+ Menu {
+ id: menu
+ contentItem: ListView {
+ model: menu.contentModel
+ }
+ }
+ \endcode
+
+ The model allows menu items to be statically declared as children of the
+ menu.
*/
QVariant QQuickMenu::contentModel() const
{
@@ -387,7 +408,14 @@ QVariant QQuickMenu::contentModel() const
This property holds the list of content data.
- \sa Item::data
+ The list contains all objects that have been declared in QML as children
+ of the menu, and also items that have been dynamically added or
+ inserted using the \l addItem() and \l insertItem() methods, respectively.
+
+ \note Unlike \c contentChildren, \c contentData does include non-visual QML
+ objects. It is not re-ordered when items are inserted or moved.
+
+ \sa Item::data, contentChildren
*/
QQmlListProperty<QObject> QQuickMenu::contentData()
{
@@ -402,9 +430,11 @@ QQmlListProperty<QObject> QQuickMenu::contentData()
/*!
\qmlproperty string QtQuick.Controls::Menu::title
- Title for the menu as a submenu or in a menubar.
+ This property holds the title for the menu.
- Its value defaults to an empty string.
+ The title of a menu is often displayed in the text of a menu item when the
+ menu is a submenu, and in the text of a tool button when it is in a
+ menubar.
*/
QString QQuickMenu::title() const
{
diff --git a/src/quicktemplates2/qquickmenuitem.cpp b/src/quicktemplates2/qquickmenuitem.cpp
index 35942f92..902889b0 100644
--- a/src/quicktemplates2/qquickmenuitem.cpp
+++ b/src/quicktemplates2/qquickmenuitem.cpp
@@ -52,26 +52,30 @@ QT_BEGIN_NAMESPACE
\brief A menu item within a Menu.
MenuItem is a convenience type that implements the AbstractButton API,
- providing an easy way to respond to menu items being clicked, for example.
+ providing a familiar way to respond to menu items being \l triggered, for
+ example.
\code
Button {
id: fileButton
text: "File"
onClicked: menu.open()
- }
- Menu {
- id: menu
- anchor.target: fileButton
- MenuItem {
- text: "New..."
- }
- MenuItem {
- text: "Open..."
- }
- MenuItem {
- text: "Save"
+ Menu {
+ id: menu
+
+ MenuItem {
+ text: "New..."
+ onTriggered: document.reset()
+ }
+ MenuItem {
+ text: "Open..."
+ onTriggered: openDialog.open()
+ }
+ MenuItem {
+ text: "Save"
+ onTriggered: saveDialog.open()
+ }
}
}
\endcode
@@ -110,6 +114,11 @@ QQuickMenuItem::QQuickMenuItem(QQuickItem *parent) :
\qmlproperty bool QtQuick.Controls::MenuItem::checkable
This property holds whether the menu item is checkable.
+
+ A checkable menu item toggles between checked (on) and unchecked (off) when
+ the user clicks on it or interacts with it via the keyboard.
+
+ \sa {AbstractButton::}{checked}
*/
void QQuickMenuItem::checkableChange()
diff --git a/src/quicktemplates2/qquickoverlay.cpp b/src/quicktemplates2/qquickoverlay.cpp
index ccae4da6..9bdc9135 100644
--- a/src/quicktemplates2/qquickoverlay.cpp
+++ b/src/quicktemplates2/qquickoverlay.cpp
@@ -113,7 +113,7 @@ void QQuickOverlayPrivate::createOverlay(QQuickPopup *popup)
QQuickPopupPrivate *p = QQuickPopupPrivate::get(popup);
if (!p->dimmer)
p->dimmer = createDimmer(popup->isModal() ? modal : modeless, popup, q);
- resizeOverlay(popup);
+ p->resizeOverlay();
}
void QQuickOverlayPrivate::destroyOverlay(QQuickPopup *popup)
@@ -126,16 +126,6 @@ void QQuickOverlayPrivate::destroyOverlay(QQuickPopup *popup)
}
}
-void QQuickOverlayPrivate::resizeOverlay(QQuickPopup *popup)
-{
- Q_Q(QQuickOverlay);
- QQuickPopupPrivate *p = QQuickPopupPrivate::get(popup);
- if (p->dimmer) {
- p->dimmer->setWidth(q->width());
- p->dimmer->setHeight(q->height());
- }
-}
-
void QQuickOverlayPrivate::toggleOverlay()
{
Q_Q(QQuickOverlay);
@@ -320,7 +310,7 @@ void QQuickOverlay::geometryChanged(const QRectF &newGeometry, const QRectF &old
Q_D(QQuickOverlay);
QQuickItem::geometryChanged(newGeometry, oldGeometry);
for (QQuickPopup *popup : qAsConst(d->allPopups))
- d->resizeOverlay(popup);
+ QQuickPopupPrivate::get(popup)->resizeOverlay();
}
void QQuickOverlay::mousePressEvent(QMouseEvent *event)
@@ -404,7 +394,11 @@ bool QQuickOverlay::childMouseEventFilter(QQuickItem *item, QEvent *event)
switch (event->type()) {
case QEvent::MouseButtonPress:
emit pressed();
- return popup->overlayEvent(item, event);
+ if (popup->overlayEvent(item, event)) {
+ d->mouseGrabberPopup = popup;
+ return true;
+ }
+ break;
case QEvent::MouseMove:
return popup->overlayEvent(item, event);
case QEvent::MouseButtonRelease:
diff --git a/src/quicktemplates2/qquickoverlay_p_p.h b/src/quicktemplates2/qquickoverlay_p_p.h
index db005555..ef142f1b 100644
--- a/src/quicktemplates2/qquickoverlay_p_p.h
+++ b/src/quicktemplates2/qquickoverlay_p_p.h
@@ -78,7 +78,6 @@ public:
void createOverlay(QQuickPopup *popup);
void destroyOverlay(QQuickPopup *popup);
- void resizeOverlay(QQuickPopup *popup);
void toggleOverlay();
QVector<QQuickPopup *> stackingOrderPopups() const;
diff --git a/src/quicktemplates2/qquickpage.cpp b/src/quicktemplates2/qquickpage.cpp
index 4304c4fb..54e79fbe 100644
--- a/src/quicktemplates2/qquickpage.cpp
+++ b/src/quicktemplates2/qquickpage.cpp
@@ -104,6 +104,37 @@ QQuickPage::QQuickPage(QQuickItem *parent) :
\qmlproperty string QtQuick.Controls::Page::title
This property holds the page title.
+
+ The title is often displayed at the top of a page to give
+ the user context about the page they are viewing.
+
+ \code
+ ApplicationWindow {
+ visible: true
+ width: 400
+ height: 400
+
+ header: Label {
+ text: view.currentItem.title
+ horizontalAlignment: Text.AlignHCenter
+ }
+
+ SwipeView {
+ id: view
+ anchors.fill: parent
+
+ Page {
+ title: qsTr("Home")
+ }
+ Page {
+ title: qsTr("Discover")
+ }
+ Page {
+ title: qsTr("Activity")
+ }
+ }
+ }
+ \endcode
*/
QString QQuickPage::title() const
@@ -183,7 +214,13 @@ void QQuickPage::setFooter(QQuickItem *footer)
This property holds the list of content data.
- \sa Item::data
+ The list contains all objects that have been declared in QML as children
+ of the container.
+
+ \note Unlike \c contentChildren, \c contentData does include non-visual QML
+ objects.
+
+ \sa Item::data, contentChildren
*/
QQmlListProperty<QObject> QQuickPage::contentData()
{
@@ -200,7 +237,13 @@ QQmlListProperty<QObject> QQuickPage::contentData()
This property holds the list of content children.
- \sa Item::children
+ The list contains all items that have been declared in QML as children
+ of the page.
+
+ \note Unlike \c contentData, \c contentChildren does not include non-visual
+ QML objects.
+
+ \sa Item::children, contentData
*/
QQmlListProperty<QQuickItem> QQuickPage::contentChildren()
{
diff --git a/src/quicktemplates2/qquickpopup.cpp b/src/quicktemplates2/qquickpopup.cpp
index 4143ee3f..1a5310bf 100644
--- a/src/quicktemplates2/qquickpopup.cpp
+++ b/src/quicktemplates2/qquickpopup.cpp
@@ -125,12 +125,18 @@ QQuickPopupPrivate::QQuickPopupPrivate()
, hasDim(false)
, visible(false)
, complete(false)
+ , hasWidth(false)
+ , hasHeight(false)
, hasTopMargin(false)
, hasLeftMargin(false)
, hasRightMargin(false)
, hasBottomMargin(false)
, allowVerticalFlip(false)
, allowHorizontalFlip(false)
+ , allowVerticalMove(true)
+ , allowHorizontalMove(true)
+ , allowVerticalResize(true)
+ , allowHorizontalResize(true)
, hadActiveFocusBeforeExitTransition(false)
, x(0)
, y(0)
@@ -587,13 +593,19 @@ void QQuickPopupPrivate::reposition()
bool widthAdjusted = false;
bool heightAdjusted = false;
- QRectF rect(x, y, iw > 0 ? iw : w, ih > 0 ? ih : h);
+ QRectF rect(allowHorizontalMove ? x : popupItem->x(),
+ allowVerticalMove ? y : popupItem->y(),
+ !hasWidth && iw > 0 ? iw : w,
+ !hasHeight && ih > 0 ? ih : h);
if (parentItem) {
rect = parentItem->mapRectToScene(rect);
if (window) {
const QMarginsF margins = getMargins();
- const QRectF bounds = QRectF(0, 0, window->width(), window->height()).marginsRemoved(margins);
+ const QRectF bounds(qMax<qreal>(0.0, margins.left()),
+ qMax<qreal>(0.0, margins.top()),
+ window->width() - qMax<qreal>(0.0, margins.left()) - qMax<qreal>(0.0, margins.right()),
+ window->height() - qMax<qreal>(0.0, margins.top()) - qMax<qreal>(0.0, margins.bottom()));
// if the popup doesn't fit horizontally inside the window, try flipping it around (left <-> right)
if (allowHorizontalFlip && (rect.left() < bounds.left() || rect.right() > bounds.right())) {
@@ -610,31 +622,39 @@ void QQuickPopupPrivate::reposition()
}
// push inside the margins if specified
- if (margins.top() >= 0 && rect.top() < bounds.top())
- rect.moveTop(margins.top());
- if (margins.bottom() >= 0 && rect.bottom() > bounds.bottom())
- rect.moveBottom(bounds.bottom());
- if (margins.left() >= 0 && rect.left() < bounds.left())
- rect.moveLeft(margins.left());
- if (margins.right() >= 0 && rect.right() > bounds.right())
- rect.moveRight(bounds.right());
+ if (allowVerticalMove) {
+ if (margins.top() >= 0 && rect.top() < bounds.top())
+ rect.moveTop(margins.top());
+ if (margins.bottom() >= 0 && rect.bottom() > bounds.bottom())
+ rect.moveBottom(bounds.bottom());
+ }
+ if (allowHorizontalMove) {
+ if (margins.left() >= 0 && rect.left() < bounds.left())
+ rect.moveLeft(margins.left());
+ if (margins.right() >= 0 && rect.right() > bounds.right())
+ rect.moveRight(bounds.right());
+ }
if (iw > 0 && (rect.left() < bounds.left() || rect.right() > bounds.right())) {
// neither the flipped or pushed geometry fits inside the window, choose
// whichever side (left vs. right) fits larger part of the popup
- if (rect.left() < bounds.left() && bounds.left() + rect.width() <= bounds.right())
- rect.moveLeft(bounds.left());
- else if (rect.right() > bounds.right() && bounds.right() - rect.width() >= bounds.left())
- rect.moveRight(bounds.right());
+ if (allowHorizontalMove && allowHorizontalFlip) {
+ if (rect.left() < bounds.left() && bounds.left() + rect.width() <= bounds.right())
+ rect.moveLeft(bounds.left());
+ else if (rect.right() > bounds.right() && bounds.right() - rect.width() >= bounds.left())
+ rect.moveRight(bounds.right());
+ }
// as a last resort, adjust the width to fit the window
- if (rect.left() < bounds.left()) {
- rect.setLeft(bounds.left());
- widthAdjusted = true;
- }
- if (rect.right() > bounds.right()) {
- rect.setRight(bounds.right());
- widthAdjusted = true;
+ if (allowHorizontalResize) {
+ if (rect.left() < bounds.left()) {
+ rect.setLeft(bounds.left());
+ widthAdjusted = true;
+ }
+ if (rect.right() > bounds.right()) {
+ rect.setRight(bounds.right());
+ widthAdjusted = true;
+ }
}
} else if (iw > 0 && rect.left() >= bounds.left() && rect.right() <= bounds.right()
&& iw != w) {
@@ -646,19 +666,23 @@ void QQuickPopupPrivate::reposition()
if (ih > 0 && (rect.top() < bounds.top() || rect.bottom() > bounds.bottom())) {
// neither the flipped or pushed geometry fits inside the window, choose
// whichever side (above vs. below) fits larger part of the popup
- if (rect.top() < bounds.top() && bounds.top() + rect.height() <= bounds.bottom())
- rect.moveTop(bounds.top());
- else if (rect.bottom() > bounds.bottom() && bounds.bottom() - rect.height() >= bounds.top())
- rect.moveBottom(bounds.bottom());
+ if (allowVerticalMove && allowVerticalFlip) {
+ if (rect.top() < bounds.top() && bounds.top() + rect.height() <= bounds.bottom())
+ rect.moveTop(bounds.top());
+ else if (rect.bottom() > bounds.bottom() && bounds.bottom() - rect.height() >= bounds.top())
+ rect.moveBottom(bounds.bottom());
+ }
// as a last resort, adjust the height to fit the window
- if (rect.top() < bounds.top()) {
- rect.setTop(bounds.top());
- heightAdjusted = true;
- }
- if (rect.bottom() > bounds.bottom()) {
- rect.setBottom(bounds.bottom());
- heightAdjusted = true;
+ if (allowVerticalResize) {
+ if (rect.top() < bounds.top()) {
+ rect.setTop(bounds.top());
+ heightAdjusted = true;
+ }
+ if (rect.bottom() > bounds.bottom()) {
+ rect.setBottom(bounds.bottom());
+ heightAdjusted = true;
+ }
}
} else if (ih > 0 && rect.top() >= bounds.top() && rect.bottom() <= bounds.bottom()
&& ih != h) {
@@ -681,12 +705,22 @@ void QQuickPopupPrivate::reposition()
emit q->yChanged();
}
- if (widthAdjusted && rect.width() > 0)
+ if (!hasWidth && widthAdjusted && rect.width() > 0)
popupItem->setWidth(rect.width());
- if (heightAdjusted && rect.height() > 0)
+ if (!hasHeight && heightAdjusted && rect.height() > 0)
popupItem->setHeight(rect.height());
}
+void QQuickPopupPrivate::resizeOverlay()
+{
+ if (!dimmer)
+ return;
+
+ qreal w = window ? window->width() : 0;
+ qreal h = window ? window->height() : 0;
+ dimmer->setSize(QSizeF(w, h));
+}
+
void QQuickPopupPositioner::removeAncestorListeners(QQuickItem *item)
{
if (item == m_parentItem)
@@ -907,13 +941,20 @@ qreal QQuickPopup::width() const
void QQuickPopup::setWidth(qreal width)
{
Q_D(QQuickPopup);
+ d->hasWidth = true;
d->popupItem->setWidth(width);
}
void QQuickPopup::resetWidth()
{
Q_D(QQuickPopup);
+ if (!d->hasWidth)
+ return;
+
+ d->hasWidth = false;
d->popupItem->resetWidth();
+ if (d->popupItem->isVisible())
+ d->reposition();
}
/*!
@@ -930,13 +971,20 @@ qreal QQuickPopup::height() const
void QQuickPopup::setHeight(qreal height)
{
Q_D(QQuickPopup);
+ d->hasHeight = true;
d->popupItem->setHeight(height);
}
void QQuickPopup::resetHeight()
{
Q_D(QQuickPopup);
+ if (!d->hasHeight)
+ return;
+
+ d->hasHeight = false;
d->popupItem->resetHeight();
+ if (d->popupItem->isVisible())
+ d->reposition();
}
/*!
diff --git a/src/quicktemplates2/qquickpopup_p_p.h b/src/quicktemplates2/qquickpopup_p_p.h
index 93039287..4ad8d171 100644
--- a/src/quicktemplates2/qquickpopup_p_p.h
+++ b/src/quicktemplates2/qquickpopup_p_p.h
@@ -157,6 +157,7 @@ public:
void init();
bool tryClose(QQuickItem *item, QMouseEvent *event);
virtual void reposition();
+ virtual void resizeOverlay();
virtual bool prepareEnterTransition();
virtual bool prepareExitTransition();
@@ -183,12 +184,18 @@ public:
bool hasDim;
bool visible;
bool complete;
+ bool hasWidth;
+ bool hasHeight;
bool hasTopMargin;
bool hasLeftMargin;
bool hasRightMargin;
bool hasBottomMargin;
bool allowVerticalFlip;
bool allowHorizontalFlip;
+ bool allowVerticalMove;
+ bool allowHorizontalMove;
+ bool allowVerticalResize;
+ bool allowHorizontalResize;
bool hadActiveFocusBeforeExitTransition;
qreal x;
qreal y;
diff --git a/src/quicktemplates2/qquickswitch.cpp b/src/quicktemplates2/qquickswitch.cpp
index 37ae53f0..a7d17e86 100644
--- a/src/quicktemplates2/qquickswitch.cpp
+++ b/src/quicktemplates2/qquickswitch.cpp
@@ -90,103 +90,28 @@ class QQuickSwitchPrivate : public QQuickAbstractButtonPrivate
public:
QQuickSwitchPrivate() : position(0) { }
- void updatePosition();
- qreal positionAt(const QPoint &point) const;
-
- bool handleMousePressEvent(QQuickItem *child, QMouseEvent *event);
- bool handleMouseMoveEvent(QQuickItem *child, QMouseEvent *event);
- bool handleMouseReleaseEvent(QQuickItem *child, QMouseEvent *event);
- bool handleMouseUngrabEvent(QQuickItem *child);
+ qreal positionAt(const QPointF &point) const;
qreal position;
- QPoint pressPoint;
};
-void QQuickSwitchPrivate::updatePosition()
-{
- Q_Q(QQuickSwitch);
- q->setPosition(checked ? 1.0 : 0.0);
-}
-
-qreal QQuickSwitchPrivate::positionAt(const QPoint &point) const
+qreal QQuickSwitchPrivate::positionAt(const QPointF &point) const
{
Q_Q(const QQuickSwitch);
- qreal pos = point.x() / indicator->width();
+ qreal pos = 0.0;
+ if (indicator)
+ pos = indicator->mapFromItem(q, point).x() / indicator->width();
if (q->isMirrored())
return 1.0 - pos;
return pos;
}
-bool QQuickSwitchPrivate::handleMousePressEvent(QQuickItem *child, QMouseEvent *event)
-{
- Q_Q(QQuickSwitch);
- Q_UNUSED(child);
- if ((focusPolicy & Qt::ClickFocus) == Qt::ClickFocus && !QGuiApplication::styleHints()->setFocusOnTouchRelease())
- q->forceActiveFocus(Qt::MouseFocusReason);
-
- pressPoint = event->pos();
- q->setPressed(true);
- emit q->pressed();
- event->accept();
- return true;
-}
-
-bool QQuickSwitchPrivate::handleMouseMoveEvent(QQuickItem *child, QMouseEvent *event)
-{
- Q_Q(QQuickSwitch);
- if (!child->keepMouseGrab())
- child->setKeepMouseGrab(QQuickWindowPrivate::dragOverThreshold(event->pos().x() - pressPoint.x(), Qt::XAxis, event));
- if (child->keepMouseGrab()) {
- q->setPosition(positionAt(event->pos()));
- event->accept();
- }
- return true;
-}
-
-bool QQuickSwitchPrivate::handleMouseReleaseEvent(QQuickItem *child, QMouseEvent *event)
-{
- Q_Q(QQuickSwitch);
- if ((focusPolicy & Qt::ClickFocus) == Qt::ClickFocus && QGuiApplication::styleHints()->setFocusOnTouchRelease())
- q->forceActiveFocus(Qt::MouseFocusReason);
-
- pressPoint = QPoint();
- q->setPressed(false);
- if (child->keepMouseGrab()) {
- bool wasChecked = checked;
- q->setChecked(position > 0.5);
- q->setPosition(checked ? 1.0 : 0.0);
- child->setKeepMouseGrab(false);
- if (wasChecked != checked) {
- emit q->released();
- emit q->clicked();
- }
- event->accept();
- } else {
- q->toggle();
- emit q->released();
- emit q->clicked();
- event->accept();
- }
- return true;
-}
-
-bool QQuickSwitchPrivate::handleMouseUngrabEvent(QQuickItem *child)
-{
- Q_Q(QQuickSwitch);
- Q_UNUSED(child);
- pressPoint = QPoint();
- q->setChecked(position > 0.5);
- q->setPosition(checked ? 1.0 : 0.0);
- q->setPressed(false);
- return true;
-}
-
QQuickSwitch::QQuickSwitch(QQuickItem *parent) :
QQuickAbstractButton(*(new QQuickSwitchPrivate), parent)
{
+ Q_D(QQuickSwitch);
+ d->keepPressed = true;
setCheckable(true);
- setFiltersChildMouseEvents(true);
- QObjectPrivate::connect(this, &QQuickAbstractButton::checkedChanged, d_func(), &QQuickSwitchPrivate::updatePosition);
}
/*!
@@ -227,30 +152,56 @@ qreal QQuickSwitch::visualPosition() const
return d->position;
}
+void QQuickSwitch::mousePressEvent(QMouseEvent *event)
+{
+ QQuickAbstractButton::mousePressEvent(event);
+}
+
+void QQuickSwitch::mouseMoveEvent(QMouseEvent *event)
+{
+ Q_D(QQuickSwitch);
+ QQuickAbstractButton::mouseMoveEvent(event);
+
+ const QPointF movePoint = event->localPos();
+ if (!keepMouseGrab()) {
+ // don't start dragging the handle unless the initial press was at the indicator,
+ // or the drag has reached the indicator area. this prevents unnatural jumps when
+ // dragging far outside the indicator.
+ const qreal pressPos = d->positionAt(d->pressPoint);
+ const qreal movePos = d->positionAt(movePoint);
+ if ((pressPos >= 0.0 && pressPos <= 1.0) || (movePos >= 0.0 && movePos <= 1.0))
+ setKeepMouseGrab(QQuickWindowPrivate::dragOverThreshold(movePoint.x() - d->pressPoint.x(), Qt::XAxis, event));
+ }
+
+ if (keepMouseGrab())
+ setPosition(d->positionAt(movePoint));
+}
+
+void QQuickSwitch::mouseReleaseEvent(QMouseEvent *event)
+{
+ QQuickAbstractButton::mouseReleaseEvent(event);
+ setKeepMouseGrab(false);
+}
+
void QQuickSwitch::mirrorChange()
{
QQuickAbstractButton::mirrorChange();
emit visualPositionChanged();
}
-bool QQuickSwitch::childMouseEventFilter(QQuickItem *child, QEvent *event)
+void QQuickSwitch::nextCheckState()
{
Q_D(QQuickSwitch);
- if (child == indicator()) {
- switch (event->type()) {
- case QEvent::MouseButtonPress:
- return d->handleMousePressEvent(child, static_cast<QMouseEvent *>(event));
- case QEvent::MouseMove:
- return d->handleMouseMoveEvent(child, static_cast<QMouseEvent *>(event));
- case QEvent::MouseButtonRelease:
- return d->handleMouseReleaseEvent(child, static_cast<QMouseEvent *>(event));
- case QEvent::UngrabMouse:
- return d->handleMouseUngrabEvent(child);
- default:
- return false;
- }
- }
- return false;
+ if (keepMouseGrab())
+ setChecked(d->position > 0.5);
+ else
+ QQuickAbstractButton::nextCheckState();
+}
+
+void QQuickSwitch::checkStateSet()
+{
+ Q_D(QQuickSwitch);
+ setPosition(d->checked ? 1.0 : 0.0);
}
QT_END_NAMESPACE
diff --git a/src/quicktemplates2/qquickswitch_p.h b/src/quicktemplates2/qquickswitch_p.h
index fa92e9f3..27a065b4 100644
--- a/src/quicktemplates2/qquickswitch_p.h
+++ b/src/quicktemplates2/qquickswitch_p.h
@@ -73,8 +73,14 @@ Q_SIGNALS:
void visualPositionChanged();
protected:
+ void mousePressEvent(QMouseEvent *event) override;
+ void mouseMoveEvent(QMouseEvent *event) override;
+ void mouseReleaseEvent(QMouseEvent *event) override;
+
void mirrorChange() override;
- bool childMouseEventFilter(QQuickItem *child, QEvent *event) override;
+
+ void nextCheckState() override;
+ void checkStateSet() override;
private:
Q_DISABLE_COPY(QQuickSwitch)
diff --git a/src/quicktemplates2/qquickswitchdelegate.cpp b/src/quicktemplates2/qquickswitchdelegate.cpp
index fbdae418..62b677e5 100644
--- a/src/quicktemplates2/qquickswitchdelegate.cpp
+++ b/src/quicktemplates2/qquickswitchdelegate.cpp
@@ -80,22 +80,17 @@ public:
{
}
- void updatePosition();
- qreal positionAt(const QPoint &point) const;
+ qreal positionAt(const QPointF &point) const;
qreal position;
};
-void QQuickSwitchDelegatePrivate::updatePosition()
-{
- Q_Q(QQuickSwitchDelegate);
- q->setPosition(checked ? 1.0 : 0.0);
-}
-
-qreal QQuickSwitchDelegatePrivate::positionAt(const QPoint &point) const
+qreal QQuickSwitchDelegatePrivate::positionAt(const QPointF &point) const
{
Q_Q(const QQuickSwitchDelegate);
- qreal pos = point.x() / indicator->width();
+ qreal pos = 0.0;
+ if (indicator)
+ pos = indicator->mapFromItem(q, point).x() / indicator->width();
if (q->isMirrored())
return 1.0 - pos;
return pos;
@@ -104,9 +99,9 @@ qreal QQuickSwitchDelegatePrivate::positionAt(const QPoint &point) const
QQuickSwitchDelegate::QQuickSwitchDelegate(QQuickItem *parent) :
QQuickItemDelegate(*(new QQuickSwitchDelegatePrivate), parent)
{
+ Q_D(QQuickSwitchDelegate);
+ d->keepPressed = true;
setCheckable(true);
-
- QObjectPrivate::connect(this, &QQuickAbstractButton::checkedChanged, d_func(), &QQuickSwitchDelegatePrivate::updatePosition);
}
/*!
@@ -147,6 +142,37 @@ qreal QQuickSwitchDelegate::visualPosition() const
return d->position;
}
+void QQuickSwitchDelegate::mousePressEvent(QMouseEvent *event)
+{
+ QQuickItemDelegate::mousePressEvent(event);
+}
+
+void QQuickSwitchDelegate::mouseMoveEvent(QMouseEvent *event)
+{
+ Q_D(QQuickSwitchDelegate);
+ QQuickItemDelegate::mouseMoveEvent(event);
+
+ const QPointF movePoint = event->localPos();
+ if (!keepMouseGrab()) {
+ // don't start dragging the handle unless the initial press was at the indicator,
+ // or the drag has reached the indicator area. this prevents unnatural jumps when
+ // dragging far outside the indicator.
+ const qreal pressPos = d->positionAt(d->pressPoint);
+ const qreal movePos = d->positionAt(movePoint);
+ if ((pressPos >= 0.0 && pressPos <= 1.0) || (movePos >= 0.0 && movePos <= 1.0))
+ setKeepMouseGrab(QQuickWindowPrivate::dragOverThreshold(movePoint.x() - d->pressPoint.x(), Qt::XAxis, event));
+ }
+
+ if (keepMouseGrab())
+ setPosition(d->positionAt(movePoint));
+}
+
+void QQuickSwitchDelegate::mouseReleaseEvent(QMouseEvent *event)
+{
+ QQuickItemDelegate::mouseReleaseEvent(event);
+ setKeepMouseGrab(false);
+}
+
QFont QQuickSwitchDelegate::defaultFont() const
{
return QQuickControlPrivate::themeFont(QPlatformTheme::ListViewFont);
@@ -158,4 +184,19 @@ void QQuickSwitchDelegate::mirrorChange()
emit visualPositionChanged();
}
+void QQuickSwitchDelegate::nextCheckState()
+{
+ Q_D(QQuickSwitchDelegate);
+ if (keepMouseGrab())
+ setChecked(d->position > 0.5);
+ else
+ QQuickItemDelegate::nextCheckState();
+}
+
+void QQuickSwitchDelegate::checkStateSet()
+{
+ Q_D(QQuickSwitchDelegate);
+ setPosition(d->checked ? 1.0 : 0.0);
+}
+
QT_END_NAMESPACE
diff --git a/src/quicktemplates2/qquickswitchdelegate_p.h b/src/quicktemplates2/qquickswitchdelegate_p.h
index 5126f643..c0cc21ac 100644
--- a/src/quicktemplates2/qquickswitchdelegate_p.h
+++ b/src/quicktemplates2/qquickswitchdelegate_p.h
@@ -73,9 +73,16 @@ Q_SIGNALS:
void visualPositionChanged();
protected:
+ void mousePressEvent(QMouseEvent *event) override;
+ void mouseMoveEvent(QMouseEvent *event) override;
+ void mouseReleaseEvent(QMouseEvent *event) override;
+
QFont defaultFont() const override;
void mirrorChange() override;
+ void nextCheckState() override;
+ void checkStateSet() override;
+
private:
Q_DISABLE_COPY(QQuickSwitchDelegate)
Q_DECLARE_PRIVATE(QQuickSwitchDelegate)