diff options
author | Liang Qi <liang.qi@theqtcompany.com> | 2016-01-05 12:13:56 +0100 |
---|---|---|
committer | Liang Qi <liang.qi@theqtcompany.com> | 2016-01-05 12:13:56 +0100 |
commit | 719dd0dd2721739f51f0cc711f42f176e74e8529 (patch) | |
tree | cbc58e3e8e2786631d741b0d5a94f685b12b2fe3 /src/templates | |
parent | 1c7daa22ebfb4682e18c8afb911e8c784127ade3 (diff) | |
parent | 408eb756d0a429c7b9c8189b7475b0ddfaa7a21e (diff) |
Merge remote-tracking branch 'origin/5.6' into dev
Change-Id: Ifca1c4f4f6d243d2a8c693b71fbea3bf49634c2e
Diffstat (limited to 'src/templates')
76 files changed, 2448 insertions, 680 deletions
diff --git a/src/templates/qquickabstractbutton.cpp b/src/templates/qquickabstractbutton.cpp index 74058daf..d2f1c7ec 100644 --- a/src/templates/qquickabstractbutton.cpp +++ b/src/templates/qquickabstractbutton.cpp @@ -109,7 +109,7 @@ static const int AUTO_REPEAT_INTERVAL = 100; */ QQuickAbstractButtonPrivate::QQuickAbstractButtonPrivate() : - pressed(false), checked(false), checkable(false), autoExclusive(false), autoRepeat(false), + pressed(false), checked(false), checkable(false), highlighted(false), autoExclusive(false), autoRepeat(false), delayTimer(0), repeatTimer(0), repeatButton(Qt::NoButton), label(Q_NULLPTR), indicator(Q_NULLPTR), group(Q_NULLPTR) { } @@ -297,6 +297,31 @@ void QQuickAbstractButton::setCheckable(bool checkable) } /*! + \qmlproperty bool Qt.labs.controls::AbstractButton::highlighted + + This property holds whether the button is highlighted. + + A button can be highlighted in order to draw the user's attention towards + it. It has no effect on keyboard interaction. + + The default value is \c false. +*/ +bool QQuickAbstractButton::isHighlighted() const +{ + Q_D(const QQuickAbstractButton); + return d->highlighted; +} + +void QQuickAbstractButton::setHighlighted(bool highlighted) +{ + Q_D(QQuickAbstractButton); + if (highlighted != d->highlighted) { + d->highlighted = highlighted; + emit highlightedChanged(); + } +} + +/*! \qmlproperty bool Qt.labs.controls::AbstractButton::autoExclusive This property holds whether auto-exclusivity is enabled. diff --git a/src/templates/qquickabstractbutton_p.h b/src/templates/qquickabstractbutton_p.h index 24998520..e0296dc0 100644 --- a/src/templates/qquickabstractbutton_p.h +++ b/src/templates/qquickabstractbutton_p.h @@ -62,6 +62,7 @@ class Q_LABSTEMPLATES_EXPORT QQuickAbstractButton : public QQuickControl Q_PROPERTY(bool pressed READ isPressed WRITE setPressed NOTIFY pressedChanged FINAL) Q_PROPERTY(bool checked READ isChecked WRITE setChecked NOTIFY checkedChanged FINAL) Q_PROPERTY(bool checkable READ isCheckable WRITE setCheckable NOTIFY checkableChanged FINAL) + Q_PROPERTY(bool highlighted READ isHighlighted WRITE setHighlighted NOTIFY highlightedChanged FINAL) Q_PROPERTY(bool autoExclusive READ autoExclusive WRITE setAutoExclusive NOTIFY autoExclusiveChanged FINAL) Q_PROPERTY(bool autoRepeat READ autoRepeat WRITE setAutoRepeat NOTIFY autoRepeatChanged FINAL) Q_PROPERTY(QQuickItem *indicator READ indicator WRITE setIndicator NOTIFY indicatorChanged FINAL) @@ -83,6 +84,9 @@ public: bool isCheckable() const; void setCheckable(bool checkable); + bool isHighlighted() const; + void setHighlighted(bool highlighted); + bool autoExclusive() const; void setAutoExclusive(bool exclusive); @@ -108,6 +112,7 @@ Q_SIGNALS: void pressedChanged(); void checkedChanged(); void checkableChanged(); + void highlightedChanged(); void autoExclusiveChanged(); void autoRepeatChanged(); void indicatorChanged(); @@ -139,8 +144,8 @@ private: Q_DECLARE_PRIVATE(QQuickAbstractButton) }; -Q_DECLARE_TYPEINFO(QQuickAbstractButton, Q_COMPLEX_TYPE); - QT_END_NAMESPACE +QML_DECLARE_TYPE(QQuickAbstractButton) + #endif // QQUICKABSTRACTBUTTON_P_H diff --git a/src/templates/qquickabstractbutton_p_p.h b/src/templates/qquickabstractbutton_p_p.h index ed0a8d9d..601c6dc7 100644 --- a/src/templates/qquickabstractbutton_p_p.h +++ b/src/templates/qquickabstractbutton_p_p.h @@ -78,6 +78,7 @@ public: bool pressed; bool checked; bool checkable; + bool highlighted; bool autoExclusive; bool autoRepeat; int delayTimer; @@ -89,8 +90,6 @@ public: QQuickButtonGroup *group; }; -Q_DECLARE_TYPEINFO(QQuickAbstractButtonPrivate, Q_COMPLEX_TYPE); - QT_END_NAMESPACE #endif // QQUICKABSTRACTBUTTON_P_P_H diff --git a/src/templates/qquickapplicationwindow.cpp b/src/templates/qquickapplicationwindow.cpp index 2c4cd7c9..46f07d3e 100644 --- a/src/templates/qquickapplicationwindow.cpp +++ b/src/templates/qquickapplicationwindow.cpp @@ -36,6 +36,9 @@ #include "qquickapplicationwindow_p.h" #include "qquickoverlay_p.h" +#include "qquickcontrol_p_p.h" +#include "qquicktextarea_p.h" +#include "qquicktextfield_p.h" #include <QtCore/private/qobject_p.h> #include <QtQuick/private/qquickitem_p.h> @@ -56,6 +59,26 @@ QT_BEGIN_NAMESPACE \image qtlabscontrols-applicationwindow-wireframe.png + \qml + import Qt.labs.controls 1.0 + + ApplicationWindow { + visible: true + + header: ToolBar { + // ... + } + + footer: TabBar { + // ... + } + + StackView { + anchors.fill: parent + } + } + \endqml + \note By default, an ApplicationWindow is not visible. \sa {Container Controls} @@ -72,6 +95,7 @@ public: , header(Q_NULLPTR) , footer(Q_NULLPTR) , overlay(Q_NULLPTR) + , activeFocusControl(Q_NULLPTR) { } void relayout(); @@ -79,11 +103,25 @@ public: void itemImplicitWidthChanged(QQuickItem *item) Q_DECL_OVERRIDE; void itemImplicitHeightChanged(QQuickItem *item) Q_DECL_OVERRIDE; + void updateFont(const QFont &); + inline void setFont_helper(const QFont &f) { + if (font.resolve() == f.resolve() && font == f) + return; + updateFont(f); + } + void resolveFont(); + + void _q_updateActiveFocus(); + void setActiveFocusControl(QQuickItem *item); + bool complete; QQuickItem *contentItem; QQuickItem *header; QQuickItem *footer; QQuickOverlay *overlay; + QFont font; + QLocale locale; + QQuickItem *activeFocusControl; QQuickApplicationWindow *q_ptr; }; @@ -135,10 +173,44 @@ void QQuickApplicationWindowPrivate::itemImplicitHeightChanged(QQuickItem *item) relayout(); } +void QQuickApplicationWindowPrivate::_q_updateActiveFocus() +{ + Q_Q(QQuickApplicationWindow); + QQuickItem *item = q->activeFocusItem(); + while (item) { + QQuickControl *control = qobject_cast<QQuickControl *>(item); + if (control) { + setActiveFocusControl(control); + break; + } + QQuickTextField *textField = qobject_cast<QQuickTextField *>(item); + if (textField) { + setActiveFocusControl(textField); + break; + } + QQuickTextArea *textArea = qobject_cast<QQuickTextArea *>(item); + if (textArea) { + setActiveFocusControl(textArea); + break; + } + item = item->parentItem(); + } +} + +void QQuickApplicationWindowPrivate::setActiveFocusControl(QQuickItem *control) +{ + Q_Q(QQuickApplicationWindow); + if (activeFocusControl != control) { + activeFocusControl = control; + emit q->activeFocusControlChanged(); + } +} + QQuickApplicationWindow::QQuickApplicationWindow(QWindow *parent) : QQuickWindowQmlImpl(parent), d_ptr(new QQuickApplicationWindowPrivate) { d_ptr->q_ptr = this; + connect(this, SIGNAL(activeFocusItemChanged()), this, SLOT(_q_updateActiveFocus())); } QQuickApplicationWindow::~QQuickApplicationWindow() @@ -153,8 +225,8 @@ QQuickApplicationWindow::~QQuickApplicationWindow() /*! \qmlproperty Item Qt.labs.controls::ApplicationWindow::header - A header item for the window, for example a title bar, menu or tool-bar. - By default this property is empty, no header will be shown. + This property holds the window header item. The header item is positioned to + the top, and resized to the width of the window. The default value is \c null. \sa footer */ @@ -186,8 +258,8 @@ void QQuickApplicationWindow::setHeader(QQuickItem *header) /*! \qmlproperty Item Qt.labs.controls::ApplicationWindow::footer - A footer item for the window, for example a status bar or menu. - By default this property is empty, no footer will be shown. + This property holds the window footer item. The footer item is positioned to + the bottom, and resized to the width of the window. The default value is \c null. \sa header */ @@ -216,11 +288,26 @@ void QQuickApplicationWindow::setFooter(QQuickItem *footer) } } +/*! + \qmlproperty list<Object> Qt.labs.controls::ApplicationWindow::contentData + \default + + This default property holds the list of all objects declared as children of + the window. + + \sa contentItem +*/ QQmlListProperty<QObject> QQuickApplicationWindow::contentData() { return QQuickItemPrivate::get(contentItem())->data(); } +/*! + \qmlproperty Item Qt.labs.controls::ApplicationWindow::contentItem + \readonly + + This property holds the window content item. +*/ QQuickItem *QQuickApplicationWindow::contentItem() const { QQuickApplicationWindowPrivate *d = const_cast<QQuickApplicationWindowPrivate *>(d_func()); @@ -231,7 +318,37 @@ QQuickItem *QQuickApplicationWindow::contentItem() const return d->contentItem; } -QQuickItem *QQuickApplicationWindow::overlay() const +/*! + \qmlproperty Control Qt.labs.controls::ApplicationWindow::activeFocusControl + + This property holds the control that currently has active focus, or \c null if there is + no control with active focus. + + 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. + + \sa Window::activeFocusItem +*/ +QQuickItem *QQuickApplicationWindow::activeFocusControl() const +{ + Q_D(const QQuickApplicationWindow); + return d->activeFocusControl; +} + +/*! + \qmlpropertygroup Qt.labs.controls::ApplicationWindow::overlay + \qmlproperty Item Qt.labs.controls::ApplicationWindow::overlay + \qmlproperty Item Qt.labs.controls::ApplicationWindow::overlay.background + + This property holds the window overlay item and its background that implements the + background dimming when any modal popups are open. Popups are automatically + reparented to the overlay. + + \sa Popup +*/ +QQuickOverlay *QQuickApplicationWindow::overlay() const { QQuickApplicationWindowPrivate *d = const_cast<QQuickApplicationWindowPrivate *>(d_func()); if (!d->overlay) { @@ -241,6 +358,81 @@ QQuickItem *QQuickApplicationWindow::overlay() const return d->overlay; } +/*! + \qmlproperty font Qt.labs.controls::ApplicationWindow::font + + This property holds the font currently set for the window. + + The default font depends on the system environment. QGuiApplication maintains a system/theme + font which serves as a default for all application windows. You can also set the default font + for windows by passing a custom font to QGuiApplication::setFont(), before loading any QML. + Finally, the font is matched against Qt's font database to find the best match. + + ApplicationWindow propagates explicit font properties to child controls. If you change a specific + property on the window's font, that property propagates to all child controls in the window, + overriding any system defaults for that property. + + \sa Control::font +*/ +QFont QQuickApplicationWindow::font() const +{ + Q_D(const QQuickApplicationWindow); + return d->font; +} + +void QQuickApplicationWindow::setFont(const QFont &f) +{ + Q_D(QQuickApplicationWindow); + if (d->font == f) + return; + + QFont resolvedFont = f.resolve(QQuickControlPrivate::themeFont(QPlatformTheme::SystemFont)); + d->setFont_helper(resolvedFont); +} + +void QQuickApplicationWindow::resetFont() +{ + setFont(QFont()); +} + +void QQuickApplicationWindowPrivate::resolveFont() +{ + QFont resolvedFont = font.resolve(QQuickControlPrivate::themeFont(QPlatformTheme::SystemFont)); + setFont_helper(resolvedFont); +} + +void QQuickApplicationWindowPrivate::updateFont(const QFont &f) +{ + Q_Q(QQuickApplicationWindow); + font = f; + + QQuickControlPrivate::updateFontRecur(q->contentItem(), f); + + emit q->fontChanged(); +} + +QLocale QQuickApplicationWindow::locale() const +{ + Q_D(const QQuickApplicationWindow); + return d->locale; +} + +void QQuickApplicationWindow::setLocale(const QLocale &locale) +{ + Q_D(QQuickApplicationWindow); + if (d->locale == locale) + return; + + d->locale = locale; + QQuickControlPrivate::updateLocaleRecur(contentItem(), locale); + emit localeChanged(); +} + +void QQuickApplicationWindow::resetLocale() +{ + setLocale(QLocale()); +} + QQuickApplicationWindowAttached *QQuickApplicationWindow::qmlAttachedProperties(QObject *object) { return new QQuickApplicationWindowAttached(object); @@ -285,16 +477,16 @@ void QQuickApplicationWindowAttachedPrivate::windowChange(QQuickWindow *wnd) if (window != newWindow) { QQuickApplicationWindow *oldWindow = window; if (oldWindow) { - QObject::disconnect(oldWindow, &QQuickApplicationWindow::activeFocusItemChanged, - q, &QQuickApplicationWindowAttached::activeFocusItemChanged); + 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::activeFocusItemChanged, - q, &QQuickApplicationWindowAttached::activeFocusItemChanged); + QObject::connect(newWindow, &QQuickApplicationWindow::activeFocusControlChanged, + q, &QQuickApplicationWindowAttached::activeFocusControlChanged); QObject::connect(newWindow, &QQuickApplicationWindow::headerChanged, q, &QQuickApplicationWindowAttached::headerChanged); QObject::connect(newWindow, &QQuickApplicationWindow::footerChanged, @@ -306,8 +498,8 @@ void QQuickApplicationWindowAttachedPrivate::windowChange(QQuickWindow *wnd) emit q->contentItemChanged(); emit q->overlayChanged(); - if ((oldWindow && oldWindow->activeFocusItem()) || (newWindow && newWindow->activeFocusItem())) - emit q->activeFocusItemChanged(); + 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())) @@ -351,18 +543,19 @@ QQuickItem *QQuickApplicationWindowAttached::contentItem() const } /*! - \qmlattachedproperty Item Qt.labs.controls::ApplicationWindow::activeFocusItem + \qmlattachedproperty Control Qt.labs.controls::ApplicationWindow::activeFocusControl - This attached property holds the active focus item. The property can be attached - to any item. The value is \c null if the item is not in an ApplicationWindow, or - the window has no active focus. + This attached property holds the control that currently has active focus, or \c null + if there is no control with active focus. The property can be attached to any item. + The value is \c null if the item is not in an ApplicationWindow, or the window has + no active focus. \sa Window::activeFocusItem */ -QQuickItem *QQuickApplicationWindowAttached::activeFocusItem() const +QQuickItem *QQuickApplicationWindowAttached::activeFocusControl() const { Q_D(const QQuickApplicationWindowAttached); - return d->window ? d->window->activeFocusItem() : Q_NULLPTR; + return d->window ? d->window->activeFocusControl() : Q_NULLPTR; } /*! @@ -397,10 +590,12 @@ QQuickItem *QQuickApplicationWindowAttached::footer() const This attached property holds the window overlay item. The property can be attached to any item. The value is \c null if the item is not in an ApplicationWindow. */ -QQuickItem *QQuickApplicationWindowAttached::overlay() const +QQuickOverlay *QQuickApplicationWindowAttached::overlay() const { Q_D(const QQuickApplicationWindowAttached); return d->window ? d->window->overlay() : Q_NULLPTR; } QT_END_NAMESPACE + +#include "moc_qquickapplicationwindow_p.cpp" diff --git a/src/templates/qquickapplicationwindow_p.h b/src/templates/qquickapplicationwindow_p.h index c5b0dc42..c9e619be 100644 --- a/src/templates/qquickapplicationwindow_p.h +++ b/src/templates/qquickapplicationwindow_p.h @@ -50,9 +50,12 @@ #include <QtQuick/private/qquickwindowmodule_p.h> #include <QtLabsTemplates/private/qtlabstemplatesglobal_p.h> +#include <QtGui/qfont.h> +#include <QtCore/qlocale.h> QT_BEGIN_NAMESPACE +class QQuickOverlay; class QQuickApplicationWindowPrivate; class QQuickApplicationWindowAttached; class QQuickApplicationWindowAttachedPrivate; @@ -62,9 +65,12 @@ class Q_LABSTEMPLATES_EXPORT QQuickApplicationWindow : public QQuickWindowQmlImp Q_OBJECT Q_PROPERTY(QQuickItem *contentItem READ contentItem CONSTANT FINAL) Q_PROPERTY(QQmlListProperty<QObject> data 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) - Q_PROPERTY(QQuickItem *overlay READ overlay CONSTANT FINAL) + Q_PROPERTY(QQuickOverlay *overlay READ overlay CONSTANT FINAL) + Q_PROPERTY(QFont font READ font WRITE setFont RESET resetFont NOTIFY fontChanged) + Q_PROPERTY(QLocale locale READ locale WRITE setLocale RESET resetLocale NOTIFY localeChanged FINAL) Q_CLASSINFO("DefaultProperty", "data") public: @@ -74,19 +80,32 @@ public: QQuickItem *contentItem() const; QQmlListProperty<QObject> contentData(); + QQuickItem *activeFocusControl() const; + QQuickItem *header() const; void setHeader(QQuickItem *header); QQuickItem *footer() const; void setFooter(QQuickItem *footer); - QQuickItem *overlay() const; + QQuickOverlay *overlay() const; + + QFont font() const; + void setFont(const QFont &); + void resetFont(); + + QLocale locale() const; + void setLocale(const QLocale &locale); + void resetLocale(); static QQuickApplicationWindowAttached *qmlAttachedProperties(QObject *object); Q_SIGNALS: + void activeFocusControlChanged(); void headerChanged(); void footerChanged(); + void fontChanged(); + void localeChanged(); protected: bool isComponentComplete() const; @@ -96,6 +115,7 @@ protected: private: Q_DISABLE_COPY(QQuickApplicationWindow) Q_DECLARE_PRIVATE(QQuickApplicationWindow) + Q_PRIVATE_SLOT(d_func(), void _q_updateActiveFocus()) QScopedPointer<QQuickApplicationWindowPrivate> d_ptr; }; @@ -104,25 +124,25 @@ class Q_LABSTEMPLATES_EXPORT QQuickApplicationWindowAttached : public QObject Q_OBJECT Q_PROPERTY(QQuickApplicationWindow *window READ window NOTIFY windowChanged FINAL) Q_PROPERTY(QQuickItem *contentItem READ contentItem NOTIFY contentItemChanged FINAL) - Q_PROPERTY(QQuickItem *activeFocusItem READ activeFocusItem NOTIFY activeFocusItemChanged FINAL) + Q_PROPERTY(QQuickItem *activeFocusControl READ activeFocusControl NOTIFY activeFocusControlChanged FINAL) Q_PROPERTY(QQuickItem *header READ header NOTIFY headerChanged FINAL) Q_PROPERTY(QQuickItem *footer READ footer NOTIFY footerChanged FINAL) - Q_PROPERTY(QQuickItem *overlay READ overlay NOTIFY overlayChanged FINAL) + Q_PROPERTY(QQuickOverlay *overlay READ overlay NOTIFY overlayChanged FINAL) public: explicit QQuickApplicationWindowAttached(QObject *parent = Q_NULLPTR); QQuickApplicationWindow *window() const; QQuickItem *contentItem() const; - QQuickItem *activeFocusItem() const; + QQuickItem *activeFocusControl() const; QQuickItem *header() const; QQuickItem *footer() const; - QQuickItem *overlay() const; + QQuickOverlay *overlay() const; Q_SIGNALS: void windowChanged(); void contentItemChanged(); - void activeFocusItemChanged(); + void activeFocusControlChanged(); void headerChanged(); void footerChanged(); void overlayChanged(); @@ -132,11 +152,9 @@ private: Q_DECLARE_PRIVATE(QQuickApplicationWindowAttached) }; -Q_DECLARE_TYPEINFO(QQuickApplicationWindow, Q_COMPLEX_TYPE); -Q_DECLARE_TYPEINFO(QQuickApplicationWindowAttached, Q_COMPLEX_TYPE); - QT_END_NAMESPACE +QML_DECLARE_TYPE(QQuickApplicationWindow) QML_DECLARE_TYPEINFO(QQuickApplicationWindow, QML_HAS_ATTACHED_PROPERTIES) #endif // QQUICKAPPLICATIONWINDOW_P_H diff --git a/src/templates/qquickbusyindicator_p.h b/src/templates/qquickbusyindicator_p.h index 0a5defbc..8be19d5c 100644 --- a/src/templates/qquickbusyindicator_p.h +++ b/src/templates/qquickbusyindicator_p.h @@ -78,8 +78,8 @@ private: Q_DECLARE_PRIVATE(QQuickBusyIndicator) }; -Q_DECLARE_TYPEINFO(QQuickBusyIndicator, Q_COMPLEX_TYPE); - QT_END_NAMESPACE +QML_DECLARE_TYPE(QQuickBusyIndicator) + #endif // QQUICKBUSYINDICATOR_P_H diff --git a/src/templates/qquickbutton.cpp b/src/templates/qquickbutton.cpp index 4f5df5fa..b323cb0b 100644 --- a/src/templates/qquickbutton.cpp +++ b/src/templates/qquickbutton.cpp @@ -83,47 +83,8 @@ QT_BEGIN_NAMESPACE \sa {Customizing Button}, {Button Controls} */ -class QQuickButtonPrivate : public QQuickAbstractButtonPrivate +QQuickButton::QQuickButton(QQuickItem *parent) : QQuickAbstractButton(parent) { -public: - QQuickButtonPrivate(); - - bool highlighted; -}; - -QQuickButtonPrivate::QQuickButtonPrivate() : - highlighted(false) -{ -} - -QQuickButton::QQuickButton(QQuickItem *parent) : - QQuickAbstractButton(*(new QQuickButtonPrivate), parent) -{ -} - -/*! - \qmlproperty bool Qt.labs.controls::Button::highlighted - - This property holds whether the button is highlighted. - - A button can be highlighted in order to draw the user's attention towards - it. It has no effect on keyboard interaction. - - The default value is \c false. -*/ -bool QQuickButton::isHighlighted() const -{ - Q_D(const QQuickButton); - return d->highlighted; -} - -void QQuickButton::setHighlighted(bool highlighted) -{ - Q_D(QQuickButton); - if (highlighted != d->highlighted) { - d->highlighted = highlighted; - emit highlightedChanged(); - } } QFont QQuickButton::defaultFont() const diff --git a/src/templates/qquickbutton_p.h b/src/templates/qquickbutton_p.h index 5b9c7df5..83d22fb8 100644 --- a/src/templates/qquickbutton_p.h +++ b/src/templates/qquickbutton_p.h @@ -52,32 +52,19 @@ QT_BEGIN_NAMESPACE -class QQuickButtonPrivate; - class Q_LABSTEMPLATES_EXPORT QQuickButton : public QQuickAbstractButton { Q_OBJECT - Q_PROPERTY(bool highlighted READ isHighlighted WRITE setHighlighted NOTIFY highlightedChanged FINAL) public: explicit QQuickButton(QQuickItem *parent = Q_NULLPTR); - bool isHighlighted() const; - void setHighlighted(bool highlighted); - -Q_SIGNALS: - void highlightedChanged(); - protected: QFont defaultFont() const Q_DECL_OVERRIDE; - -private: - Q_DISABLE_COPY(QQuickButton) - Q_DECLARE_PRIVATE(QQuickButton) }; -Q_DECLARE_TYPEINFO(QQuickButton, Q_COMPLEX_TYPE); - QT_END_NAMESPACE +QML_DECLARE_TYPE(QQuickButton) + #endif // QQUICKBUTTON_P_H diff --git a/src/templates/qquickbuttongroup_p.h b/src/templates/qquickbuttongroup_p.h index 366d2b2a..6210079d 100644 --- a/src/templates/qquickbuttongroup_p.h +++ b/src/templates/qquickbuttongroup_p.h @@ -108,10 +108,9 @@ private: Q_DECLARE_PRIVATE(QQuickButtonGroupAttached) }; -Q_DECLARE_TYPEINFO(QQuickButtonGroup, Q_COMPLEX_TYPE); - QT_END_NAMESPACE +QML_DECLARE_TYPE(QQuickButtonGroup) QML_DECLARE_TYPEINFO(QQuickButtonGroup, QML_HAS_ATTACHED_PROPERTIES) #endif // QQuickButtonGroup_H diff --git a/src/templates/qquickcheckbox_p.h b/src/templates/qquickcheckbox_p.h index 5cf97476..4c0d505f 100644 --- a/src/templates/qquickcheckbox_p.h +++ b/src/templates/qquickcheckbox_p.h @@ -88,8 +88,8 @@ private: Q_DECLARE_PRIVATE(QQuickCheckBox) }; -Q_DECLARE_TYPEINFO(QQuickCheckBox, Q_COMPLEX_TYPE); - QT_END_NAMESPACE +QML_DECLARE_TYPE(QQuickCheckBox) + #endif // QQUICKCHECKBOX_P_H diff --git a/src/templates/qquickcombobox.cpp b/src/templates/qquickcombobox.cpp new file mode 100644 index 00000000..a2c0bf89 --- /dev/null +++ b/src/templates/qquickcombobox.cpp @@ -0,0 +1,795 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Templates 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 "qquickcombobox_p.h" +#include "qquickcontrol_p_p.h" +#include "qquickabstractbutton_p.h" +#include "qquickpopup_p.h" + +#include <QtCore/qregexp.h> +#include <QtQml/qjsvalue.h> +#include <QtQml/qqmlcontext.h> +#include <QtQml/private/qqmldelegatemodel_p.h> +#include <QtQuick/private/qquickevents_p_p.h> + +QT_BEGIN_NAMESPACE + +/*! + \qmltype ComboBox + \inherits Control + \instantiates QQuickComboBox + \inqmlmodule Qt.labs.controls + \ingroup qtlabscontrols-input + \brief A combo box control. + + \image qtlabscontrols-combobox.png + + ComboBox is a combined button and popup list. It provides a means of + presenting a list of options to the user in a way that takes up the + minimum amount of screen space. + + ComboBox is populated with a data model. The data model is commonly + a JavaScript array, a \l ListModel or an integer, but also other types + of \l {qml-data-models}{data models} are supported. + + \code + ComboBox { + model: ["First", "Second", "Third"] + } + \endcode + + ComboBox is able to visualize standard \l {qml-data-models}{data models} + that provide the \c modelData role: + \list + \li models that have only one role + \li models that do not have named roles (JavaScript array, integer) + \endlist + + When using models that have multiple named roles, ComboBox must be configured + to use a specific \l {textRole}{text role} for its \l {displayText}{display text} + and \l delegate instances. + + \code + ComboBox { + textRole: "key" + model: ListModel { + ListElement { key: "First"; value: 123 } + ListElement { key: "Second"; value: 456 } + ListElement { key: "Third"; value: 789 } + } + } + \endcode + + \note If ComboBox is assigned a data model that has multiple named roles, but + \l textRole is not defined, ComboBox is unable to visualize it and throws a + \c {ReferenceError: modelData is not defined}. + + \sa {Customizing ComboBox}, {Input Controls} +*/ + +/*! + \qmlsignal void Qt.labs.controls::ComboBox::activated(int index) + + This signal is emitted when the item at \a index is activated by the user. + + \sa currentIndex +*/ + +/*! + \qmlsignal void Qt.labs.controls::ComboBox::highlighted(int index) + + This signal is emitted when the item at \a index in the popup list is highlighted by the user. + + \sa highlightedIndex +*/ + +class QQuickComboBoxPrivate : public QQuickControlPrivate +{ + Q_DECLARE_PUBLIC(QQuickComboBox) + +public: + QQuickComboBoxPrivate() : pressed(false), ownModel(false), hasDisplayText(false), + hideTimer(0), highlightedIndex(-1), currentIndex(-1), delegateModel(Q_NULLPTR), + delegate(Q_NULLPTR), popup(Q_NULLPTR) { } + + bool isPopupVisible() const; + void showPopup(); + void hidePopup(bool accept); + void togglePopup(bool accept); + + void pressedOutside(); + void itemClicked(); + + void initItem(int index, QObject *object); + void countChanged(); + void updateCurrentText(); + void increase(); + void decrease(); + void setHighlightedIndex(int index); + + void createDelegateModel(); + + bool pressed; + bool ownModel; + bool hasDisplayText; + int hideTimer; + int highlightedIndex; + int currentIndex; + QVariant model; + QString textRole; + QString currentText; + QString displayText; + QQuickItem *pressedItem; + QQmlInstanceModel *delegateModel; + QQmlComponent *delegate; + QQuickPopup *popup; +}; + +bool QQuickComboBoxPrivate::isPopupVisible() const +{ + return popup && popup->isVisible(); +} + +void QQuickComboBoxPrivate::showPopup() +{ + if (popup && !popup->isVisible()) + popup->open(); + setHighlightedIndex(currentIndex); +} + +void QQuickComboBoxPrivate::hidePopup(bool accept) +{ + Q_Q(QQuickComboBox); + if (popup && popup->isVisible()) + popup->close(); + if (accept) { + q->setCurrentIndex(highlightedIndex); + emit q->activated(currentIndex); + } + setHighlightedIndex(-1); +} + +void QQuickComboBoxPrivate::togglePopup(bool accept) +{ + if (!popup) + return; + + if (popup->isVisible()) + hidePopup(accept); + else + showPopup(); +} + +void QQuickComboBoxPrivate::pressedOutside() +{ + Q_Q(QQuickComboBox); + if (hideTimer <= 0) + hideTimer = q->startTimer(0); +} + +void QQuickComboBoxPrivate::itemClicked() +{ + Q_Q(QQuickComboBox); + int index = delegateModel->indexOf(q->sender(), Q_NULLPTR); + if (index != -1) { + setHighlightedIndex(index); + emit q->highlighted(index); + hidePopup(true); + } +} + +void QQuickComboBoxPrivate::initItem(int index, QObject *object) +{ + QQuickAbstractButton *button = qobject_cast<QQuickAbstractButton *>(object); + if (button) + connect(button, &QQuickAbstractButton::clicked, this, &QQuickComboBoxPrivate::itemClicked); + + if (index == currentIndex) + updateCurrentText(); +} + +void QQuickComboBoxPrivate::countChanged() +{ + Q_Q(QQuickComboBox); + if (q->count() == 0) + q->setCurrentIndex(-1); + emit q->countChanged(); +} + +void QQuickComboBoxPrivate::updateCurrentText() +{ + Q_Q(QQuickComboBox); + QString text = q->textAt(currentIndex); + if (currentText != text) { + currentText = text; + emit q->currentTextChanged(); + } + if (!hasDisplayText && displayText != text) { + displayText = text; + emit q->displayTextChanged(); + } +} + +void QQuickComboBoxPrivate::increase() +{ + Q_Q(QQuickComboBox); + if (isPopupVisible()) { + if (highlightedIndex < q->count() - 1) { + setHighlightedIndex(highlightedIndex + 1); + emit q->highlighted(highlightedIndex); + } + } else { + if (currentIndex < q->count() - 1) { + q->setCurrentIndex(currentIndex + 1); + emit q->activated(currentIndex); + } + } +} + +void QQuickComboBoxPrivate::decrease() +{ + Q_Q(QQuickComboBox); + if (isPopupVisible()) { + if (highlightedIndex > 0) { + setHighlightedIndex(highlightedIndex - 1); + emit q->highlighted(highlightedIndex); + } + } else { + if (currentIndex > 0) { + q->setCurrentIndex(currentIndex - 1); + emit q->activated(currentIndex); + } + } +} + +void QQuickComboBoxPrivate::setHighlightedIndex(int index) +{ + Q_Q(QQuickComboBox); + if (highlightedIndex != index) { + highlightedIndex = index; + emit q->highlightedIndexChanged(); + } +} + +void QQuickComboBoxPrivate::createDelegateModel() +{ + Q_Q(QQuickComboBox); + if (delegateModel) { + if (ownModel) { + delete delegateModel; + } else { + disconnect(delegateModel, &QQmlInstanceModel::countChanged, this, &QQuickComboBoxPrivate::countChanged); + disconnect(delegateModel, &QQmlInstanceModel::modelUpdated, this, &QQuickComboBoxPrivate::updateCurrentText); + disconnect(delegateModel, &QQmlInstanceModel::initItem, this, &QQuickComboBoxPrivate::initItem); + } + } + + ownModel = false; + delegateModel = model.value<QQmlInstanceModel *>(); + + if (!delegateModel && model.isValid()) { + QQmlDelegateModel *dataModel = new QQmlDelegateModel(qmlContext(q), q); + dataModel->setModel(model); + dataModel->setDelegate(delegate); + if (q->isComponentComplete()) + dataModel->componentComplete(); + + ownModel = true; + delegateModel = dataModel; + } + + if (delegateModel) { + connect(delegateModel, &QQmlInstanceModel::countChanged, this, &QQuickComboBoxPrivate::countChanged); + connect(delegateModel, &QQmlInstanceModel::modelUpdated, this, &QQuickComboBoxPrivate::updateCurrentText); + connect(delegateModel, &QQmlInstanceModel::initItem, this, &QQuickComboBoxPrivate::initItem); + } + + emit q->delegateModelChanged(); +} + +QQuickComboBox::QQuickComboBox(QQuickItem *parent) : + QQuickControl(*(new QQuickComboBoxPrivate), parent) +{ + setActiveFocusOnTab(true); + setFlag(QQuickItem::ItemIsFocusScope); + setAcceptedMouseButtons(Qt::LeftButton); +} + +/*! + \readonly + \qmlproperty int Qt.labs.controls::ComboBox::count + + This property holds the number of items in the combo box. +*/ +int QQuickComboBox::count() const +{ + Q_D(const QQuickComboBox); + return d->delegateModel ? d->delegateModel->count() : 0; +} + +/*! + \qmlproperty model Qt.labs.controls::ComboBox::model + + This property holds the model providing data for the combo box. + + \code + ComboBox { + textRole: "key" + model: ListModel { + ListElement { key: "First"; value: 123 } + ListElement { key: "Second"; value: 456 } + ListElement { key: "Third"; value: 789 } + } + } + \endcode + + \sa textRole, {qml-data-models}{Data Models} +*/ +QVariant QQuickComboBox::model() const +{ + Q_D(const QQuickComboBox); + return d->model; +} + +void QQuickComboBox::setModel(const QVariant& m) +{ + Q_D(QQuickComboBox); + QVariant model = m; + if (model.userType() == qMetaTypeId<QJSValue>()) + model = model.value<QJSValue>().toVariant(); + + if (d->model != model) { + d->model = model; + d->createDelegateModel(); + if (isComponentComplete()) { + setCurrentIndex(count() > 0 ? 0 : -1); + d->updateCurrentText(); + } + emit modelChanged(); + } +} + +/*! + \internal + \qmlproperty model Qt.labs.controls::ComboBox::delegateModel + + This property holds the model providing delegate instances for the combo box. +*/ +QQmlInstanceModel *QQuickComboBox::delegateModel() const +{ + Q_D(const QQuickComboBox); + return d->delegateModel; +} + +/*! + \qmlproperty bool Qt.labs.controls::ComboBox::pressed + + This property holds whether the combo box button is pressed. +*/ +bool QQuickComboBox::isPressed() const +{ + Q_D(const QQuickComboBox); + return d->pressed; +} + +void QQuickComboBox::setPressed(bool pressed) +{ + Q_D(QQuickComboBox); + if (d->pressed != pressed) { + d->pressed = pressed; + emit pressedChanged(); + } +} + +/*! + \qmlproperty int Qt.labs.controls::ComboBox::highlightedIndex + + This property holds the index of the highlighted item in the combo box popup list. + + \sa highlighted(), currentIndex +*/ +int QQuickComboBox::highlightedIndex() const +{ + Q_D(const QQuickComboBox); + return d->highlightedIndex; +} + +/*! + \qmlproperty int Qt.labs.controls::ComboBox::currentIndex + + This property holds the index of the current item in the combo box. + + \sa activated(), currentText +*/ +int QQuickComboBox::currentIndex() const +{ + Q_D(const QQuickComboBox); + return d->currentIndex; +} + +void QQuickComboBox::setCurrentIndex(int index) +{ + Q_D(QQuickComboBox); + if (d->currentIndex != index) { + d->currentIndex = index; + emit currentIndexChanged(); + if (isComponentComplete()) + d->updateCurrentText(); + } +} + +/*! + \readonly + \qmlproperty string Qt.labs.controls::ComboBox::currentText + + This property holds the text of the current item in the combo box. + + \sa currentIndex, displayText, textRole +*/ +QString QQuickComboBox::currentText() const +{ + Q_D(const QQuickComboBox); + return d->currentText; +} + +/*! + \qmlproperty string Qt.labs.controls::ComboBox::displayText + + This property holds the text that is displayed on the combo box button. + + By default, the display text presents the current selection. That is, + it follows the text of the current item. However, the default display + text can be overridden with a custom value. + + \code + ComboBox { + currentIndex: 1 + displayText: "Size: " + currentText + model: ["S", "M", "L"] + } + \endcode + + \sa currentText, textRole +*/ +QString QQuickComboBox::displayText() const +{ + Q_D(const QQuickComboBox); + return d->displayText; +} + +void QQuickComboBox::setDisplayText(const QString &text) +{ + Q_D(QQuickComboBox); + d->hasDisplayText = true; + if (d->displayText != text) { + d->displayText = text; + emit displayTextChanged(); + } +} + +void QQuickComboBox::resetDisplayText() +{ + Q_D(QQuickComboBox); + if (d->hasDisplayText) { + d->hasDisplayText = false; + d->updateCurrentText(); + } +} + +/*! + \qmlproperty string Qt.labs.controls::ComboBox::textRole + + This property holds the model role used for populating the combo box. + + \sa model, currentText, displayText +*/ +QString QQuickComboBox::textRole() const +{ + Q_D(const QQuickComboBox); + return d->textRole; +} + +void QQuickComboBox::setTextRole(const QString &role) +{ + Q_D(QQuickComboBox); + if (d->textRole != role) { + d->textRole = role; + if (isComponentComplete()) + d->updateCurrentText(); + emit textRoleChanged(); + } +} + +/*! + \qmlproperty Component Qt.labs.controls::ComboBox::delegate + + This property holds a delegate that presents an item in the combo box popup. + + \sa ItemDelegate, {Customizing ComboBox} +*/ +QQmlComponent *QQuickComboBox::delegate() const +{ + Q_D(const QQuickComboBox); + return d->delegate; +} + +void QQuickComboBox::setDelegate(QQmlComponent* delegate) +{ + Q_D(QQuickComboBox); + if (d->delegate != delegate) { + delete d->delegate; + d->delegate = delegate; + QQmlDelegateModel *delegateModel = qobject_cast<QQmlDelegateModel*>(d->delegateModel); + if (delegateModel) + delegateModel->setDelegate(d->delegate); + emit delegateChanged(); + } +} + +/*! + \qmlproperty Popup Qt.labs.controls::ComboBox::popup + + This property holds the popup. + + \sa {Customizing ComboBox} +*/ +QQuickPopup *QQuickComboBox::popup() const +{ + Q_D(const QQuickComboBox); + return d->popup; +} + +void QQuickComboBox::setPopup(QQuickPopup *popup) +{ + Q_D(QQuickComboBox); + if (d->popup != popup) { + delete d->popup; + if (popup) + QObjectPrivate::connect(popup, &QQuickPopup::pressedOutside, d, &QQuickComboBoxPrivate::pressedOutside); + d->popup = popup; + emit popupChanged(); + } +} + +/*! + \qmlmethod string Qt.labs.controls::ComboBox::textAt(int index) + + Returns the text for the specified \a index, or an empty string + if the index is out of bounds. + + \sa textRole +*/ +QString QQuickComboBox::textAt(int index) const +{ + Q_D(const QQuickComboBox); + if (!d->delegateModel || index < 0 || index >= d->delegateModel->count() || !d->delegateModel->object(index)) + return QString(); + return d->delegateModel->stringValue(index, d->textRole.isEmpty() ? QStringLiteral("modelData") : d->textRole); +} + +/*! + \qmlmethod int Qt.labs.controls::ComboBox::find(string text, flags = Qt.MatchExactly) + + Returns the index of the specified \a text, or \c -1 if no match is found. + + The way the search is performed is defined by the specified match \a flags. By default, + combo box performs case sensitive exact matching (\c Qt.MatchExactly). All other match + types are case-insensitive unless the \c Qt.MatchCaseSensitive flag is also specified. + + \value Qt.MatchExactly The search term matches exactly (default). + \value Qt.MatchRegExp The search term matches as a regular expression. + \value Qt.MatchWildcard The search term matches using wildcards. + \value Qt.MatchFixedString The search term matches as a fixed string. + \value Qt.MatchStartsWith The search term matches the start of the item. + \value Qt.MatchEndsWidth The search term matches the end of the item. + \value Qt.MatchContains The search term is contained in the item. + \value Qt.MatchCaseSensitive The search is case sensitive. + + \sa textRole +*/ +int QQuickComboBox::find(const QString &text, Qt::MatchFlags flags) const +{ + int itemCount = count(); + uint matchType = flags & 0x0F; + Qt::CaseSensitivity cs = flags & Qt::MatchCaseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive; + + for (int idx = 0; idx < itemCount; ++idx) { + QString t = textAt(idx); + switch (matchType) { + case Qt::MatchExactly: + if (t == text) + return idx; + break; + case Qt::MatchRegExp: + if (QRegExp(text, cs).exactMatch(t)) + return idx; + break; + case Qt::MatchWildcard: + if (QRegExp(text, cs, QRegExp::Wildcard).exactMatch(t)) + return idx; + break; + case Qt::MatchStartsWith: + if (t.startsWith(text, cs)) + return idx; + break; + case Qt::MatchEndsWith: + if (t.endsWith(text, cs)) + return idx; + break; + case Qt::MatchFixedString: + if (t.compare(text, cs) == 0) + return idx; + break; + case Qt::MatchContains: + default: + if (t.contains(text, cs)) + return idx; + break; + } + } + return -1; +} + +void QQuickComboBox::focusOutEvent(QFocusEvent *event) +{ + Q_D(QQuickComboBox); + QQuickControl::focusOutEvent(event); + d->hidePopup(false); + setPressed(false); +} + +void QQuickComboBox::keyPressEvent(QKeyEvent *event) +{ + Q_D(QQuickComboBox); + QQuickControl::keyPressEvent(event); + if (!d->popup) + return; + + switch (event->key()) { + case Qt::Key_Space: + if (!event->isAutoRepeat()) + setPressed(true); + event->accept(); + break; + case Qt::Key_Enter: + case Qt::Key_Return: + if (d->isPopupVisible()) + setPressed(true); + event->accept(); + break; + case Qt::Key_Up: + d->decrease(); + event->accept(); + break; + case Qt::Key_Down: + d->increase(); + event->accept(); + break; + case Qt::Key_Escape: + event->accept(); + default: + break; + } +} + +void QQuickComboBox::keyReleaseEvent(QKeyEvent *event) +{ + Q_D(QQuickComboBox); + QQuickControl::keyReleaseEvent(event); + if (!d->popup || event->isAutoRepeat()) + return; + + switch (event->key()) { + case Qt::Key_Space: + d->togglePopup(true); + setPressed(false); + event->accept(); + break; + case Qt::Key_Enter: + case Qt::Key_Return: + d->hidePopup(true); + setPressed(false); + event->accept(); + break; + case Qt::Key_Escape: + d->hidePopup(false); + setPressed(false); + event->accept(); + break; + default: + break; + } +} + +void QQuickComboBox::mousePressEvent(QMouseEvent *event) +{ + QQuickControl::mousePressEvent(event); + setPressed(true); +} + +void QQuickComboBox::mouseMoveEvent(QMouseEvent* event) +{ + QQuickControl::mouseMoveEvent(event); + setPressed(contains(event->pos())); +} + +void QQuickComboBox::mouseReleaseEvent(QMouseEvent *event) +{ + Q_D(QQuickComboBox); + QQuickControl::mouseReleaseEvent(event); + if (d->pressed) { + setPressed(false); + if (!d->isPopupVisible()) + forceActiveFocus(Qt::MouseFocusReason); + d->togglePopup(false); + } +} + +void QQuickComboBox::mouseUngrabEvent() +{ + QQuickControl::mouseUngrabEvent(); + setPressed(false); +} + +void QQuickComboBox::timerEvent(QTimerEvent *event) +{ + Q_D(QQuickComboBox); + QQuickControl::timerEvent(event); + if (event->timerId() == d->hideTimer) { + killTimer(d->hideTimer); + d->hideTimer = 0; + if (!d->pressed) + d->hidePopup(false); + } +} + +void QQuickComboBox::componentComplete() +{ + Q_D(QQuickComboBox); + QQuickControl::componentComplete(); + + if (d->delegateModel && d->ownModel) + static_cast<QQmlDelegateModel *>(d->delegateModel)->componentComplete(); + + if (count() > 0) { + if (d->currentIndex == -1) + setCurrentIndex(0); + else + d->updateCurrentText(); + } +} + +QT_END_NAMESPACE diff --git a/src/templates/qquickcombobox_p.h b/src/templates/qquickcombobox_p.h new file mode 100644 index 00000000..da237c8e --- /dev/null +++ b/src/templates/qquickcombobox_p.h @@ -0,0 +1,146 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Templates 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 QQUICKCOMBOBOX_P_H +#define QQUICKCOMBOBOX_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 <QtLabsTemplates/private/qquickcontrol_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickPopup; +class QQmlInstanceModel; +class QQuickComboBoxPrivate; + +class Q_LABSTEMPLATES_EXPORT QQuickComboBox : public QQuickControl +{ + Q_OBJECT + Q_PROPERTY(int count READ count NOTIFY countChanged FINAL) + Q_PROPERTY(QVariant model READ model WRITE setModel NOTIFY modelChanged FINAL) + Q_PROPERTY(QQmlInstanceModel *delegateModel READ delegateModel NOTIFY delegateModelChanged FINAL) + Q_PROPERTY(bool pressed READ isPressed WRITE setPressed NOTIFY pressedChanged FINAL) + Q_PROPERTY(int highlightedIndex READ highlightedIndex NOTIFY highlightedIndexChanged FINAL) + Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentIndexChanged FINAL) + Q_PROPERTY(QString currentText READ currentText NOTIFY currentTextChanged FINAL) + Q_PROPERTY(QString displayText READ displayText WRITE setDisplayText RESET resetDisplayText NOTIFY displayTextChanged FINAL) + Q_PROPERTY(QString textRole READ textRole WRITE setTextRole NOTIFY textRoleChanged FINAL) + Q_PROPERTY(QQmlComponent *delegate READ delegate WRITE setDelegate NOTIFY delegateChanged FINAL) + Q_PROPERTY(QQuickPopup *popup READ popup WRITE setPopup NOTIFY popupChanged FINAL) + +public: + explicit QQuickComboBox(QQuickItem *parent = Q_NULLPTR); + + int count() const; + + QVariant model() const; + void setModel(const QVariant &model); + QQmlInstanceModel *delegateModel() const; + + bool isPressed() const; + void setPressed(bool pressed); + + int highlightedIndex() const; + + int currentIndex() const; + void setCurrentIndex(int index); + + QString currentText() const; + + QString displayText() const; + void setDisplayText(const QString &text); + void resetDisplayText(); + + QString textRole() const; + void setTextRole(const QString &role); + + QQmlComponent *delegate() const; + void setDelegate(QQmlComponent *delegate); + + QQuickPopup *popup() const; + void setPopup(QQuickPopup *popup); + + Q_INVOKABLE QString textAt(int index) const; + Q_INVOKABLE int find(const QString &text, Qt::MatchFlags flags = Qt::MatchExactly) const; + +Q_SIGNALS: + void countChanged(); + void modelChanged(); + void delegateModelChanged(); + void pressedChanged(); + void highlightedIndexChanged(); + void currentIndexChanged(); + void currentTextChanged(); + void displayTextChanged(); + void textRoleChanged(); + void delegateChanged(); + void popupChanged(); + + void activated(int index); + void highlighted(int index); + +protected: + void focusOutEvent(QFocusEvent *event) Q_DECL_OVERRIDE; + void keyPressEvent(QKeyEvent *event) Q_DECL_OVERRIDE; + void keyReleaseEvent(QKeyEvent *event) Q_DECL_OVERRIDE; + void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE; + void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE; + void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE; + void mouseUngrabEvent() Q_DECL_OVERRIDE; + void timerEvent(QTimerEvent *event) Q_DECL_OVERRIDE; + + void componentComplete() Q_DECL_OVERRIDE; + +private: + Q_DISABLE_COPY(QQuickComboBox) + Q_DECLARE_PRIVATE(QQuickComboBox) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickComboBox) + +#endif // QQUICKCOMBOBOX_P_H diff --git a/src/templates/qquickcontainer_p.h b/src/templates/qquickcontainer_p.h index a77b285c..83476f66 100644 --- a/src/templates/qquickcontainer_p.h +++ b/src/templates/qquickcontainer_p.h @@ -109,8 +109,8 @@ private: Q_PRIVATE_SLOT(d_func(), void _q_currentIndexChanged()) }; -Q_DECLARE_TYPEINFO(QQuickContainer, Q_COMPLEX_TYPE); - QT_END_NAMESPACE +QML_DECLARE_TYPE(QQuickContainer) + #endif // QQUICKCONTAINER_P_H diff --git a/src/templates/qquickcontainer_p_p.h b/src/templates/qquickcontainer_p_p.h index 2e5a36a1..6eb79c88 100644 --- a/src/templates/qquickcontainer_p_p.h +++ b/src/templates/qquickcontainer_p_p.h @@ -92,8 +92,6 @@ public: bool updatingCurrent; }; -Q_DECLARE_TYPEINFO(QQuickContainerPrivate, Q_COMPLEX_TYPE); - QT_END_NAMESPACE #endif // QQUICKCONTAINER_P_P_H diff --git a/src/templates/qquickcontrol.cpp b/src/templates/qquickcontrol.cpp index 908abeda..d1abafe2 100644 --- a/src/templates/qquickcontrol.cpp +++ b/src/templates/qquickcontrol.cpp @@ -44,6 +44,7 @@ #include "qquicktextarea_p_p.h" #include "qquicktextfield_p.h" #include "qquicktextfield_p_p.h" +#include "qquickapplicationwindow_p.h" #include <QtGui/private/qguiapplication_p.h> #include <QtGui/qpa/qplatformtheme.h> @@ -65,10 +66,9 @@ QT_BEGIN_NAMESPACE */ QQuickControlPrivate::QQuickControlPrivate() : - hasTopPadding(false), hasLeftPadding(false), hasRightPadding(false), hasBottomPadding(false), - padding(0), topPadding(0), leftPadding(0), rightPadding(0), bottomPadding(0), spacing(0), - layoutDirection(Qt::LeftToRight), background(Q_NULLPTR), contentItem(Q_NULLPTR), - accessibleAttached(Q_NULLPTR) + hasTopPadding(false), hasLeftPadding(false), hasRightPadding(false), hasBottomPadding(false), hasLocale(false), + padding(0), topPadding(0), leftPadding(0), rightPadding(0), bottomPadding(0), spacing(0), focusReason(Qt::OtherFocusReason), + background(Q_NULLPTR), contentItem(Q_NULLPTR), accessibleAttached(Q_NULLPTR) { #ifndef QT_NO_ACCESSIBILITY QAccessible::installActivationObserver(this); @@ -85,7 +85,8 @@ QQuickControlPrivate::~QQuickControlPrivate() void QQuickControlPrivate::mirrorChange() { Q_Q(QQuickControl); - q->mirrorChange(); + if (locale.textDirection() == Qt::LeftToRight) + q->mirrorChange(); } void QQuickControlPrivate::setTopPadding(qreal value, bool reset) @@ -218,15 +219,22 @@ QFont QQuickControlPrivate::naturalControlFont(const QQuickItem *q) } QQuickItem *p = q->parentItem(); + bool found = false; while (p) { if (QQuickControl *qc = qobject_cast<QQuickControl *>(p)) { naturalFont = qc->font(); + found = true; break; } p = p->parentItem(); } + if (!found) { + if (QQuickApplicationWindow *w = qobject_cast<QQuickApplicationWindow *>(q->window())) + naturalFont = w->font(); + } + naturalFont.resolve(0); return naturalFont; } @@ -353,8 +361,11 @@ void QQuickControl::itemChange(QQuickItem::ItemChange change, const QQuickItem:: { Q_D(QQuickControl); QQuickItem::itemChange(change, value); - if (change == ItemParentHasChanged && isComponentComplete()) + if (change == ItemParentHasChanged && isComponentComplete()) { d->resolveFont(); + if (!d->hasLocale) + d->locale = d->calcLocale(); + } } /*! @@ -367,7 +378,7 @@ void QQuickControl::itemChange(QQuickItem::ItemChange change, const QQuickItem:: controls can maintain consistency with the native platform's native look and feel. It's common that different platforms, or different styles, define different fonts for an application. - The default font depends on the system environment. QGuiApplication maintains a system/theme + The default font depends on the system environment. ApplicationWindow maintains a system/theme font which serves as a default for all controls. There may also be special font defaults for certain types of controls. You can also set the default font for controls by passing a custom font to QGuiApplication::setFont(), before loading the QML. Finally, the font is matched @@ -412,7 +423,7 @@ void QQuickControl::resetFont() */ qreal QQuickControl::availableWidth() const { - return qMax(0.0, width() - leftPadding() - rightPadding()); + return qMax<qreal>(0.0, width() - leftPadding() - rightPadding()); } /*! @@ -424,7 +435,7 @@ qreal QQuickControl::availableWidth() const */ qreal QQuickControl::availableHeight() const { - return qMax(0.0, height() - topPadding() - bottomPadding()); + return qMax<qreal>(0.0, height() - topPadding() - bottomPadding()); } /*! @@ -603,51 +614,83 @@ void QQuickControl::resetSpacing() } /*! - \qmlproperty enumeration Qt.labs.controls::Control::layoutDirection - - This property holds the layout direction of the control. + \qmlproperty Locale Qt.labs.calendar::Control::locale - Possible values: - \value Qt.LeftToRight Items are laid out from left to right. If the width of the row is explicitly set, - the left anchor remains to the left of the row (default). - \value Qt.RightToLeft Items are laid out from right to left. If the width of the row is explicitly set, - the right anchor remains to the right of the row. + This property holds the locale of the control. - \sa effectiveLayoutDirection + \sa mirrored, {LayoutMirroring}{LayoutMirroring} */ -Qt::LayoutDirection QQuickControl::layoutDirection() const +QLocale QQuickControl::locale() const { Q_D(const QQuickControl); - return d->layoutDirection; + return d->locale; } -/*! - \qmlproperty enumeration Qt.labs.controls::Control::effectiveLayoutDirection - \readonly +void QQuickControl::setLocale(const QLocale &locale) +{ + Q_D(QQuickControl); + if (d->hasLocale && d->locale == locale) + return; + + d->updateLocale(locale, true); // explicit=true +} - This property holds the effective layout direction of the control. +void QQuickControl::resetLocale() +{ + Q_D(QQuickControl); + if (!d->hasLocale) + return; - When using the attached property \l {LayoutMirroring::enabled}{LayoutMirroring::enabled} - for locale layouts, the visual layout direction of the control will be mirrored. However, - the \l layoutDirection property will remain unchanged. + d->updateLocale(d->calcLocale(), false); // explicit=false +} - \sa layoutDirection, {LayoutMirroring}{LayoutMirroring} -*/ -Qt::LayoutDirection QQuickControl::effectiveLayoutDirection() const +QLocale QQuickControlPrivate::calcLocale() const { - Q_D(const QQuickControl); - if (d->isMirrored()) - return d->layoutDirection == Qt::RightToLeft ? Qt::LeftToRight : Qt::RightToLeft; - return d->layoutDirection; + Q_Q(const QQuickControl); + QQuickItem *p = q->parentItem(); + while (p) { + if (QQuickControl *qc = qobject_cast<QQuickControl *>(p)) + return qc->locale(); + + QVariant v = p->property("locale"); + if (v.isValid() && v.userType() == QMetaType::QLocale) + return v.toLocale(); + + p = p->parentItem(); + } + + if (QQuickApplicationWindow *w = qobject_cast<QQuickApplicationWindow *>(q->window())) + return w->locale(); + + return QLocale(); } -void QQuickControl::setLayoutDirection(Qt::LayoutDirection direction) +void QQuickControlPrivate::updateLocale(const QLocale &l, bool e) { - Q_D(QQuickControl); - if (d->layoutDirection != direction) { - d->layoutDirection = direction; - emit layoutDirectionChanged(); - mirrorChange(); + Q_Q(QQuickControl); + if (!e && hasLocale) + return; + + QLocale old = q->locale(); + hasLocale = e; + if (old != l) { + bool wasMirrored = q->isMirrored(); + q->localeChange(l, old); + locale = l; + QQuickControlPrivate::updateLocaleRecur(q, l); + emit q->localeChanged(); + if (wasMirrored != q->isMirrored()) + q->mirrorChange(); + } +} + +void QQuickControlPrivate::updateLocaleRecur(QQuickItem *item, const QLocale &l) +{ + foreach (QQuickItem *child, item->childItems()) { + if (QQuickControl *control = qobject_cast<QQuickControl *>(child)) + QQuickControlPrivate::get(control)->updateLocale(l, false); + else + updateLocaleRecur(child, l); } } @@ -660,11 +703,46 @@ void QQuickControl::setLayoutDirection(Qt::LayoutDirection direction) This property is provided for convenience. A control is considered mirrored when its visual layout direction is right-to-left. - \sa effectiveLayoutDirection, {LayoutMirroring}{LayoutMirroring} + \sa locale, {LayoutMirroring}{LayoutMirroring} */ bool QQuickControl::isMirrored() const { - return effectiveLayoutDirection() == Qt::RightToLeft; + Q_D(const QQuickControl); + return d->isMirrored() || d->locale.textDirection() == Qt::RightToLeft; +} + +/*! + \qmlproperty enumeration Qt.labs.controls::Control::focusReason + + This property holds the reason of the last focus change. + + \note This property does not indicate whether the control has \l {Item::activeFocus} + {active focus}, but the reason why the control either gained or lost focus. + + \value Qt.MouseFocusReason A mouse action occurred. + \value Qt.TabFocusReason The Tab key was pressed. + \value Qt.BacktabFocusReason A Backtab occurred. The input for this may include the Shift or Control keys; e.g. Shift+Tab. + \value Qt.ActiveWindowFocusReason The window system made this window either active or inactive. + \value Qt.PopupFocusReason The application opened/closed a pop-up that grabbed/released the keyboard focus. + \value Qt.ShortcutFocusReason The user typed a label's buddy shortcut + \value Qt.MenuBarFocusReason The menu bar took focus. + \value Qt.OtherFocusReason Another reason, usually application-specific. + + \sa Item::activeFocus +*/ +Qt::FocusReason QQuickControl::focusReason() const +{ + Q_D(const QQuickControl); + return d->focusReason; +} + +void QQuickControl::setFocusReason(Qt::FocusReason reason) +{ + Q_D(QQuickControl); + if (d->focusReason != reason) { + d->focusReason = reason; + emit focusReasonChanged(); + } } /*! @@ -742,6 +820,18 @@ QFont QQuickControl::defaultFont() const return QQuickControlPrivate::themeFont(QPlatformTheme::SystemFont); } +void QQuickControl::focusInEvent(QFocusEvent *event) +{ + QQuickItem::focusInEvent(event); + setFocusReason(event->reason()); +} + +void QQuickControl::focusOutEvent(QFocusEvent *event) +{ + QQuickItem::focusOutEvent(event); + setFocusReason(event->reason()); +} + void QQuickControl::mousePressEvent(QMouseEvent *event) { event->accept(); @@ -771,7 +861,6 @@ void QQuickControl::geometryChanged(const QRectF &newGeometry, const QRectF &old void QQuickControl::mirrorChange() { - emit effectiveLayoutDirectionChanged(); emit mirroredChanged(); } @@ -789,4 +878,10 @@ void QQuickControl::contentItemChange(QQuickItem *newItem, QQuickItem *oldItem) Q_UNUSED(oldItem); } +void QQuickControl::localeChange(const QLocale &newLocale, const QLocale &oldLocale) +{ + Q_UNUSED(newLocale); + Q_UNUSED(oldLocale); +} + QT_END_NAMESPACE diff --git a/src/templates/qquickcontrol_p.h b/src/templates/qquickcontrol_p.h index 346b45b3..8d4055e5 100644 --- a/src/templates/qquickcontrol_p.h +++ b/src/templates/qquickcontrol_p.h @@ -48,6 +48,7 @@ // We mean it. // +#include <QtCore/qlocale.h> #include <QtQuick/qquickitem.h> #include <QtLabsTemplates/private/qtlabstemplatesglobal_p.h> @@ -67,9 +68,9 @@ class Q_LABSTEMPLATES_EXPORT QQuickControl : public QQuickItem Q_PROPERTY(qreal rightPadding READ rightPadding WRITE setRightPadding RESET resetRightPadding NOTIFY rightPaddingChanged FINAL) Q_PROPERTY(qreal bottomPadding READ bottomPadding WRITE setBottomPadding RESET resetBottomPadding NOTIFY bottomPaddingChanged FINAL) Q_PROPERTY(qreal spacing READ spacing WRITE setSpacing RESET resetSpacing NOTIFY spacingChanged FINAL) - Q_PROPERTY(Qt::LayoutDirection layoutDirection READ layoutDirection WRITE setLayoutDirection NOTIFY layoutDirectionChanged FINAL) - Q_PROPERTY(Qt::LayoutDirection effectiveLayoutDirection READ effectiveLayoutDirection NOTIFY effectiveLayoutDirectionChanged FINAL) + Q_PROPERTY(QLocale locale READ locale WRITE setLocale RESET resetLocale NOTIFY localeChanged FINAL) Q_PROPERTY(bool mirrored READ isMirrored NOTIFY mirroredChanged FINAL) + Q_PROPERTY(Qt::FocusReason focusReason READ focusReason WRITE setFocusReason NOTIFY focusReasonChanged FINAL) Q_PROPERTY(QQuickItem *background READ background WRITE setBackground NOTIFY backgroundChanged FINAL) Q_PROPERTY(QQuickItem *contentItem READ contentItem WRITE setContentItem NOTIFY contentItemChanged FINAL) @@ -107,12 +108,15 @@ public: void setSpacing(qreal spacing); void resetSpacing(); - Qt::LayoutDirection layoutDirection() const; - Qt::LayoutDirection effectiveLayoutDirection() const; - void setLayoutDirection(Qt::LayoutDirection direction); + QLocale locale() const; + void setLocale(const QLocale &locale); + void resetLocale(); bool isMirrored() const; + Qt::FocusReason focusReason() const; + void setFocusReason(Qt::FocusReason reason); + QQuickItem *background() const; void setBackground(QQuickItem *background); @@ -129,9 +133,9 @@ Q_SIGNALS: void rightPaddingChanged(); void bottomPaddingChanged(); void spacingChanged(); - void layoutDirectionChanged(); - void effectiveLayoutDirectionChanged(); + void localeChanged(); void mirroredChanged(); + void focusReasonChanged(); void backgroundChanged(); void contentItemChanged(); @@ -145,6 +149,9 @@ protected: void itemChange(ItemChange change, const ItemChangeData &value) Q_DECL_OVERRIDE; + void focusInEvent(QFocusEvent *event) Q_DECL_OVERRIDE; + void focusOutEvent(QFocusEvent *event) Q_DECL_OVERRIDE; + void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE; void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE; void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE; @@ -153,6 +160,7 @@ protected: virtual void mirrorChange(); virtual void paddingChange(const QMarginsF &newPadding, const QMarginsF &oldPadding); virtual void contentItemChange(QQuickItem *newItem, QQuickItem *oldItem); + virtual void localeChange(const QLocale &newLocale, const QLocale &oldLocale); #ifndef QT_NO_ACCESSIBILITY virtual void accessibilityActiveChanged(bool active); @@ -171,8 +179,8 @@ private: Q_DECLARE_PRIVATE(QQuickControl) }; -Q_DECLARE_TYPEINFO(QQuickControl, Q_COMPLEX_TYPE); - QT_END_NAMESPACE +QML_DECLARE_TYPE(QQuickControl) + #endif // QQUICKCONTROL_P_H diff --git a/src/templates/qquickcontrol_p_p.h b/src/templates/qquickcontrol_p_p.h index ab185952..21f6c1b1 100644 --- a/src/templates/qquickcontrol_p_p.h +++ b/src/templates/qquickcontrol_p_p.h @@ -102,26 +102,30 @@ public: void resolveFont(); static QFont naturalControlFont(const QQuickItem *); static QFont themeFont(QPlatformTheme::Font type); + void updateLocale(const QLocale &l, bool e); + static void updateLocaleRecur(QQuickItem *item, const QLocale &l); + + QLocale calcLocale() const; QFont font; bool hasTopPadding; bool hasLeftPadding; bool hasRightPadding; bool hasBottomPadding; + bool hasLocale; qreal padding; qreal topPadding; qreal leftPadding; qreal rightPadding; qreal bottomPadding; qreal spacing; - Qt::LayoutDirection layoutDirection; + QLocale locale; + Qt::FocusReason focusReason; QQuickItem *background; QQuickItem *contentItem; QQuickAccessibleAttached *accessibleAttached; }; -Q_DECLARE_TYPEINFO(QQuickControlPrivate, Q_COMPLEX_TYPE); - QT_END_NAMESPACE #endif // QQUICKCONTROL_P_P_H diff --git a/src/templates/qquickdial.cpp b/src/templates/qquickdial.cpp index bb3b5250..dcc2b293 100644 --- a/src/templates/qquickdial.cpp +++ b/src/templates/qquickdial.cpp @@ -140,7 +140,7 @@ qreal QQuickDialPrivate::positionAt(const QPoint &point) const void QQuickDialPrivate::setPosition(qreal pos) { Q_Q(QQuickDial); - pos = qBound(0.0, pos, 1.0); + pos = qBound<qreal>(0.0, pos, 1.0); if (!qFuzzyCompare(position, pos)) { position = pos; diff --git a/src/templates/qquickdial_p.h b/src/templates/qquickdial_p.h index c4e7c276..19d37547 100644 --- a/src/templates/qquickdial_p.h +++ b/src/templates/qquickdial_p.h @@ -140,8 +140,8 @@ private: Q_DECLARE_PRIVATE(QQuickDial) }; -Q_DECLARE_TYPEINFO(QQuickDial, Q_COMPLEX_TYPE); - QT_END_NAMESPACE +QML_DECLARE_TYPE(QQuickDial) + #endif // QQUICKDIAL_H diff --git a/src/templates/qquickdrawer.cpp b/src/templates/qquickdrawer.cpp index a1fdf8f8..ca6c8c13 100644 --- a/src/templates/qquickdrawer.cpp +++ b/src/templates/qquickdrawer.cpp @@ -40,6 +40,7 @@ #include <QtGui/private/qguiapplication_p.h> #include <QtQuick/private/qquickwindow_p.h> #include <QtQuick/private/qquickanimation_p.h> +#include <QtQuick/private/qquickitemchangelistener_p.h> #include <QtLabsTemplates/private/qquickcontrol_p_p.h> QT_BEGIN_NAMESPACE @@ -88,7 +89,7 @@ QT_BEGIN_NAMESPACE This signal is emitted when the drawer is clicked. */ -class QQuickDrawerPrivate : public QQuickControlPrivate +class QQuickDrawerPrivate : public QQuickControlPrivate, public QQuickItemChangeListener { Q_DECLARE_PUBLIC(QQuickDrawer) @@ -101,6 +102,8 @@ public: bool handleMouseMoveEvent(QQuickItem *item, QMouseEvent *event); bool handleMouseReleaseEvent(QQuickItem *item, QMouseEvent *event); + void itemGeometryChanged(QQuickItem *, const QRectF &, const QRectF &) Q_DECL_OVERRIDE; + Qt::Edge edge; qreal offset; qreal position; @@ -131,31 +134,35 @@ void QQuickDrawerPrivate::updateContent() } } +static bool dragOverThreshold(qreal d, Qt::Axis axis, QMouseEvent *event, int threshold = -1) +{ + return QQuickWindowPrivate::dragOverThreshold(d, axis, event, threshold); +} + bool QQuickDrawerPrivate::handleMousePressEvent(QQuickItem *item, QMouseEvent *event) { Q_Q(QQuickDrawer); - pressPoint = q->mapFromItem(item, event->pos()); + pressPoint = event->windowPos(); + offset = 0; if (qFuzzyIsNull(position)) { // only accept pressing at drag margins when fully closed switch (edge) { case Qt::LeftEdge: - event->setAccepted(!QQuickWindowPrivate::dragOverThreshold(event->x(), Qt::XAxis, event)); + event->setAccepted(!dragOverThreshold(event->windowPos().x(), Qt::XAxis, event)); break; case Qt::RightEdge: - event->setAccepted(!QQuickWindowPrivate::dragOverThreshold(q->width() - event->x(), Qt::XAxis, event)); + event->setAccepted(!dragOverThreshold(q->width() - event->windowPos().x(), Qt::XAxis, event)); break; case Qt::TopEdge: - event->setAccepted(!QQuickWindowPrivate::dragOverThreshold(event->y(), Qt::YAxis, event)); + event->setAccepted(!dragOverThreshold(event->windowPos().y(), Qt::YAxis, event)); break; case Qt::BottomEdge: - event->setAccepted(!QQuickWindowPrivate::dragOverThreshold(q->height() - event->y(), Qt::YAxis, event)); + event->setAccepted(!dragOverThreshold(q->height() - event->windowPos().y(), Qt::YAxis, event)); break; } - offset = 0; } else { event->accept(); - offset = q->positionAt(pressPoint) - position; } return item == q; @@ -164,26 +171,32 @@ bool QQuickDrawerPrivate::handleMousePressEvent(QQuickItem *item, QMouseEvent *e bool QQuickDrawerPrivate::handleMouseMoveEvent(QQuickItem *item, QMouseEvent *event) { Q_Q(QQuickDrawer); - QPointF movePoint = q->mapFromItem(item, event->pos()); + Q_UNUSED(item); + QPointF movePoint = event->windowPos(); if (!q->keepMouseGrab()) { + // Flickable uses a hard-coded threshold of 15 for flicking, and + // QStyleHints::startDragDistance for dragging. Drawer uses a bit + // larger threshold to avoid being too eager to steal touch (QTBUG-50045) + int threshold = qMax(20, QGuiApplication::styleHints()->startDragDistance() + 5); bool overThreshold = false; if (edge == Qt::LeftEdge || edge == Qt::RightEdge) - overThreshold = QQuickWindowPrivate::dragOverThreshold(movePoint.x() - pressPoint.x(), Qt::XAxis, event); + overThreshold = dragOverThreshold(movePoint.x() - pressPoint.x(), Qt::XAxis, event, threshold); else - overThreshold = QQuickWindowPrivate::dragOverThreshold(movePoint.y() - pressPoint.y(), Qt::YAxis, event); + overThreshold = dragOverThreshold(movePoint.y() - pressPoint.y(), Qt::YAxis, event, threshold); if (window && overThreshold) { QQuickItem *grabber = q->window()->mouseGrabberItem(); if (!grabber || !grabber->keepMouseGrab()) { q->grabMouse(); q->setKeepMouseGrab(overThreshold); + offset = qMin<qreal>(0.0, q->positionAt(movePoint) - position); } } } if (q->keepMouseGrab()) - q->setPosition(q->positionAt(event->pos()) - offset); + q->setPosition(q->positionAt(movePoint) - offset); event->accept(); return q->keepMouseGrab(); @@ -242,6 +255,11 @@ bool QQuickDrawerPrivate::handleMouseReleaseEvent(QQuickItem *item, QMouseEvent return wasGrabbed; } +void QQuickDrawerPrivate::itemGeometryChanged(QQuickItem *, const QRectF &, const QRectF &) +{ + updateContent(); +} + QQuickDrawer::QQuickDrawer(QQuickItem *parent) : QQuickControl(*(new QQuickDrawerPrivate), parent) { @@ -294,7 +312,7 @@ qreal QQuickDrawer::position() const void QQuickDrawer::setPosition(qreal position) { Q_D(QQuickDrawer); - position = qBound(0.0, position, 1.0); + position = qBound<qreal>(0.0, position, 1.0); if (!qFuzzyCompare(d->position, position)) { d->position = position; if (isComponentComplete()) @@ -319,12 +337,17 @@ void QQuickDrawer::setContentItem(QQuickItem *item) { Q_D(QQuickDrawer); if (d->content != item) { - delete d->content; + if (d->content) { + QQuickItemPrivate::get(d->content)->removeItemChangeListener(d, QQuickItemPrivate::Geometry); + delete d->content; + } d->content = item; - if (item) + if (item) { item->setParentItem(this); - if (isComponentComplete()) - d->updateContent(); + QQuickItemPrivate::get(item)->updateOrAddGeometryChangeListener(d, QQuickItemPrivate::SizeChange); + if (isComponentComplete()) + d->updateContent(); + } emit contentItemChanged(); } } diff --git a/src/templates/qquickdrawer_p.h b/src/templates/qquickdrawer_p.h index c05ad036..f953b0fd 100644 --- a/src/templates/qquickdrawer_p.h +++ b/src/templates/qquickdrawer_p.h @@ -107,8 +107,8 @@ private: Q_DECLARE_PRIVATE(QQuickDrawer) }; -Q_DECLARE_TYPEINFO(QQuickDrawer, Q_COMPLEX_TYPE); - QT_END_NAMESPACE +QML_DECLARE_TYPE(QQuickDrawer) + #endif // QQUICKDRAWER_P_H diff --git a/src/templates/qquickframe.cpp b/src/templates/qquickframe.cpp index 69a7abb0..386aa5fb 100644 --- a/src/templates/qquickframe.cpp +++ b/src/templates/qquickframe.cpp @@ -41,7 +41,7 @@ QT_BEGIN_NAMESPACE /*! \qmltype Frame - \inherits Control + \inherits Pane \instantiates QQuickFrame \inqmlmodule Qt.labs.controls \ingroup qtlabscontrols-containers @@ -63,76 +63,18 @@ QT_BEGIN_NAMESPACE \sa {Customizing Frame}, {Container Controls} */ -QQuickFramePrivate::QQuickFramePrivate() : contentWidth(0), contentHeight(0), frame(Q_NULLPTR) +QQuickFramePrivate::QQuickFramePrivate() : frame(Q_NULLPTR) { } -void QQuickFramePrivate::init() -{ - Q_Q(QQuickFrame); - q->setFlag(QQuickItem::ItemIsFocusScope); - q->setAcceptedMouseButtons(Qt::AllButtons); - -} - QQuickFrame::QQuickFrame(QQuickItem *parent) : - QQuickControl(*(new QQuickFramePrivate), parent) + QQuickPane(*(new QQuickFramePrivate), parent) { - d_func()->init(); } QQuickFrame::QQuickFrame(QQuickFramePrivate &dd, QQuickItem *parent) : - QQuickControl(dd, parent) + QQuickPane(dd, parent) { - d_func()->init(); -} - -/*! - \qmlproperty real Qt.labs.controls::Frame::contentWidth - - This property holds the content width. It is used for calculating the - total implicit width of the frame. - - \note If only a single item is used within the frame, the implicit width - of its contained item is used as the content width. -*/ -qreal QQuickFrame::contentWidth() const -{ - Q_D(const QQuickFrame); - return d->contentWidth; -} - -void QQuickFrame::setContentWidth(qreal width) -{ - Q_D(QQuickFrame); - if (d->contentWidth != width) { - d->contentWidth = width; - emit contentWidthChanged(); - } -} - -/*! - \qmlproperty real Qt.labs.controls::Frame::contentHeight - - This property holds the content height. It is used for calculating the - total implicit height of the frame. - - \note If only a single item is used within the frame, the implicit height - of its contained item is used as the content height. -*/ -qreal QQuickFrame::contentHeight() const -{ - Q_D(const QQuickFrame); - return d->contentHeight; -} - -void QQuickFrame::setContentHeight(qreal height) -{ - Q_D(QQuickFrame); - if (d->contentHeight != height) { - d->contentHeight = height; - emit contentHeightChanged(); - } } /*! @@ -160,49 +102,4 @@ void QQuickFrame::setFrame(QQuickItem *frame) } } -/*! - \qmlproperty list<Object> Qt.labs.controls::Frame::contentData - \default - - This property holds the list of content data. - - \sa Item::data -*/ -QQmlListProperty<QObject> QQuickFrame::contentData() -{ - Q_D(QQuickFrame); - return QQmlListProperty<QObject>(d->contentItem, Q_NULLPTR, - QQuickItemPrivate::data_append, - QQuickItemPrivate::data_count, - QQuickItemPrivate::data_at, - QQuickItemPrivate::data_clear); -} - -/*! - \qmlproperty list<Item> Qt.labs.controls::Frame::contentChildren - - This property holds the list of content children. - - \sa Item::children -*/ -QQmlListProperty<QQuickItem> QQuickFrame::contentChildren() -{ - Q_D(QQuickFrame); - return QQmlListProperty<QQuickItem>(d->contentItem, Q_NULLPTR, - QQuickItemPrivate::children_append, - QQuickItemPrivate::children_count, - QQuickItemPrivate::children_at, - QQuickItemPrivate::children_clear); -} - -void QQuickFrame::contentItemChange(QQuickItem *newItem, QQuickItem *oldItem) -{ - QQuickControl::contentItemChange(newItem, oldItem); - if (oldItem) - disconnect(oldItem, &QQuickItem::childrenChanged, this, &QQuickFrame::contentChildrenChanged); - if (newItem) - connect(newItem, &QQuickItem::childrenChanged, this, &QQuickFrame::contentChildrenChanged); - emit contentChildrenChanged(); -} - QT_END_NAMESPACE diff --git a/src/templates/qquickframe_p.h b/src/templates/qquickframe_p.h index 7d4db523..0bfd63e8 100644 --- a/src/templates/qquickframe_p.h +++ b/src/templates/qquickframe_p.h @@ -48,56 +48,36 @@ // We mean it. // -#include <QtLabsTemplates/private/qquickcontrol_p.h> -#include <QtQml/qqmllist.h> +#include <QtLabsTemplates/private/qquickpane_p.h> QT_BEGIN_NAMESPACE class QQuickFramePrivate; -class Q_LABSTEMPLATES_EXPORT QQuickFrame : public QQuickControl +class Q_LABSTEMPLATES_EXPORT QQuickFrame : 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(QQuickItem *frame READ frame WRITE setFrame NOTIFY frameChanged 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 QQuickFrame(QQuickItem *parent = Q_NULLPTR); - qreal contentWidth() const; - void setContentWidth(qreal width); - - qreal contentHeight() const; - void setContentHeight(qreal height); - QQuickItem *frame() const; void setFrame(QQuickItem *frame); - QQmlListProperty<QObject> contentData(); - QQmlListProperty<QQuickItem> contentChildren(); - Q_SIGNALS: - void contentWidthChanged(); - void contentHeightChanged(); - void contentChildrenChanged(); void frameChanged(); protected: QQuickFrame(QQuickFramePrivate &dd, QQuickItem *parent); - void contentItemChange(QQuickItem *newItem, QQuickItem *oldItem) Q_DECL_OVERRIDE; - private: Q_DISABLE_COPY(QQuickFrame) Q_DECLARE_PRIVATE(QQuickFrame) }; -Q_DECLARE_TYPEINFO(QQuickFrame, Q_COMPLEX_TYPE); - QT_END_NAMESPACE +QML_DECLARE_TYPE(QQuickFrame) + #endif // QQUICKFRAME_P_H diff --git a/src/templates/qquickframe_p_p.h b/src/templates/qquickframe_p_p.h index 73a8cd85..3d570572 100644 --- a/src/templates/qquickframe_p_p.h +++ b/src/templates/qquickframe_p_p.h @@ -48,28 +48,22 @@ // We mean it. // -#include <QtLabsTemplates/private/qquickcontrol_p_p.h> +#include <QtLabsTemplates/private/qquickpane_p_p.h> QT_BEGIN_NAMESPACE class QQuickFrame; -class Q_LABSTEMPLATES_EXPORT QQuickFramePrivate : public QQuickControlPrivate +class Q_LABSTEMPLATES_EXPORT QQuickFramePrivate : public QQuickPanePrivate { Q_DECLARE_PUBLIC(QQuickFrame) public: QQuickFramePrivate(); - void init(); - - qreal contentWidth; - qreal contentHeight; QQuickItem *frame; }; -Q_DECLARE_TYPEINFO(QQuickFramePrivate, Q_COMPLEX_TYPE); - QT_END_NAMESPACE #endif // QQUICKFRAME_P_P_H diff --git a/src/templates/qquickgroupbox.cpp b/src/templates/qquickgroupbox.cpp index 2f120879..ef8789a5 100644 --- a/src/templates/qquickgroupbox.cpp +++ b/src/templates/qquickgroupbox.cpp @@ -62,7 +62,20 @@ QT_BEGIN_NAMESPACE \snippet qtlabscontrols-groupbox.qml 1 - \sa {Customizing GroupBox}, {Container Controls} + \section2 Checkable GroupBox + + Even though GroupBox has no built-in check box, it is straightforward + to create a checkable GroupBox by pairing it with a CheckBox. + + \image qtlabscontrols-groupbox-checkable.png + + It is a common pattern to enable or disable the groupbox's children when + its check box is toggled on/off, respectively, but the semantics of the + check box is left to the application to decide. + + \snippet qtlabscontrols-groupbox-checkable.qml 1 + + \sa CheckBox, {Customizing GroupBox}, {Container Controls} */ class QQuickGroupBoxPrivate : public QQuickFramePrivate @@ -126,7 +139,7 @@ void QQuickGroupBox::setLabel(QQuickItem *label) QFont QQuickGroupBox::defaultFont() const { - return QQuickControlPrivate::themeFont(QPlatformTheme::MdiSubWindowTitleFont); // tmp + return QQuickControlPrivate::themeFont(QPlatformTheme::GroupBoxTitleFont); } QT_END_NAMESPACE diff --git a/src/templates/qquickgroupbox_p.h b/src/templates/qquickgroupbox_p.h index 5dcfe971..b81d6534 100644 --- a/src/templates/qquickgroupbox_p.h +++ b/src/templates/qquickgroupbox_p.h @@ -81,8 +81,8 @@ private: Q_DECLARE_PRIVATE(QQuickGroupBox) }; -Q_DECLARE_TYPEINFO(QQuickGroupBox, Q_COMPLEX_TYPE); - QT_END_NAMESPACE +QML_DECLARE_TYPE(QQuickGroupBox) + #endif // QQUICKGROUPBOX_P_H diff --git a/src/templates/qquickitemdelegate_p.h b/src/templates/qquickitemdelegate_p.h index e3f415a6..01e7b39c 100644 --- a/src/templates/qquickitemdelegate_p.h +++ b/src/templates/qquickitemdelegate_p.h @@ -71,8 +71,8 @@ private: Q_DECLARE_PRIVATE(QQuickItemDelegate) }; -Q_DECLARE_TYPEINFO(QQuickItemDelegate, Q_COMPLEX_TYPE); - QT_END_NAMESPACE +QML_DECLARE_TYPE(QQuickItemDelegate) + #endif // QQUICKITEMDELEGATE_P_H diff --git a/src/templates/qquicklabel_p.h b/src/templates/qquicklabel_p.h index d753320d..26f72840 100644 --- a/src/templates/qquicklabel_p.h +++ b/src/templates/qquicklabel_p.h @@ -86,8 +86,8 @@ private: Q_DECLARE_PRIVATE(QQuickLabel) }; -Q_DECLARE_TYPEINFO(QQuickLabel, Q_COMPLEX_TYPE); - QT_END_NAMESPACE +QML_DECLARE_TYPE(QQuickLabel) + #endif // QQUICKLABEL_P_H diff --git a/src/templates/qquicklabel_p_p.h b/src/templates/qquicklabel_p_p.h index 1cd831b1..a4e9f4e5 100644 --- a/src/templates/qquicklabel_p_p.h +++ b/src/templates/qquicklabel_p_p.h @@ -86,8 +86,6 @@ public: QQuickAccessibleAttached *accessibleAttached; }; -Q_DECLARE_TYPEINFO(QQuickLabelPrivate, Q_COMPLEX_TYPE); - QT_END_NAMESPACE #endif // QQUICKLABEL_P_P_H diff --git a/src/templates/qquickmenu.cpp b/src/templates/qquickmenu.cpp index b21a7a3e..d6c6e1cb 100644 --- a/src/templates/qquickmenu.cpp +++ b/src/templates/qquickmenu.cpp @@ -36,7 +36,6 @@ #include "qquickmenu_p.h" #include "qquickmenu_p_p.h" -#include "qquickpanel_p_p.h" #include "qquickmenuitem_p.h" #include <QtGui/qevent.h> @@ -50,7 +49,7 @@ QT_BEGIN_NAMESPACE /*! \qmltype Menu - \inherits Panel + \inherits Popup \instantiates QQuickMenu \inqmlmodule Qt.labs.controls \ingroup qtlabscontrols-menus @@ -68,7 +67,7 @@ QT_BEGIN_NAMESPACE Button { id: fileButton text: "File" - onClicked: menu.show() + onClicked: menu.open() } Menu { id: menu @@ -268,7 +267,7 @@ void QQuickMenuPrivate::contentData_append(QQmlListProperty<QObject> *prop, QObj QQuickMenuItem *menuItem = qobject_cast<QQuickMenuItem *>(item); if (menuItem) { QObjectPrivate::connect(menuItem, &QQuickMenuItem::pressed, p, &QQuickMenuPrivate::onItemPressed); - QObject::connect(menuItem, &QQuickMenuItem::triggered, q, &QQuickPanel::hide); + QObject::connect(menuItem, &QQuickMenuItem::triggered, q, &QQuickPopup::close); QObjectPrivate::connect(menuItem, &QQuickItem::activeFocusChanged, p, &QQuickMenuPrivate::onItemActiveFocusChanged); } } @@ -296,11 +295,11 @@ void QQuickMenuPrivate::contentData_clear(QQmlListProperty<QObject> *prop) } QQuickMenu::QQuickMenu(QObject *parent) : - QQuickPanel(*(new QQuickMenuPrivate), parent) + QQuickPopup(*(new QQuickMenuPrivate), parent) { Q_D(QQuickMenu); - connect(this, &QQuickMenu::pressedOutside, this, &QQuickMenu::hide); - connect(this, &QQuickMenu::releasedOutside, this, &QQuickMenu::hide); + connect(this, &QQuickMenu::pressedOutside, this, &QQuickMenu::close); + connect(this, &QQuickMenu::releasedOutside, this, &QQuickMenu::close); QObjectPrivate::connect(this, &QQuickMenu::contentItemChanged, d, &QQuickMenuPrivate::onContentItemChanged); } @@ -445,6 +444,9 @@ bool QQuickMenu::eventFilter(QObject *object, QEvent *event) if (d->contentItem->metaObject()->indexOfMethod("incrementCurrentIndex()") != -1) QMetaObject::invokeMethod(d->contentItem, "incrementCurrentIndex"); return true; + } else if (keyEvent->key() == Qt::Key_Escape) { + close(); + return true; } return false; diff --git a/src/templates/qquickmenu_p.h b/src/templates/qquickmenu_p.h index cd079d4e..d4bb27b9 100644 --- a/src/templates/qquickmenu_p.h +++ b/src/templates/qquickmenu_p.h @@ -49,15 +49,16 @@ // #include <QtQml/qqmllist.h> +#include <QtQml/qqml.h> -#include "qquickpanel_p.h" +#include "qquickpopup_p.h" QT_BEGIN_NAMESPACE class QQuickMenuItem; class QQuickMenuPrivate; -class Q_LABSTEMPLATES_EXPORT QQuickMenu : public QQuickPanel +class Q_LABSTEMPLATES_EXPORT QQuickMenu : public QQuickPopup { Q_OBJECT Q_PROPERTY(QVariant contentModel READ contentModel CONSTANT FINAL) @@ -84,8 +85,8 @@ private: Q_DECLARE_PRIVATE(QQuickMenu) }; -Q_DECLARE_TYPEINFO(QQuickMenu, Q_COMPLEX_TYPE); - QT_END_NAMESPACE +QML_DECLARE_TYPE(QQuickMenu) + #endif // QQUICKMENU_P_H diff --git a/src/templates/qquickmenu_p_p.h b/src/templates/qquickmenu_p_p.h index 166d184b..154ba968 100644 --- a/src/templates/qquickmenu_p_p.h +++ b/src/templates/qquickmenu_p_p.h @@ -51,13 +51,13 @@ #include <QtCore/qvector.h> #include <QtQuick/private/qquickitemchangelistener_p.h> -#include <QtLabsTemplates/private/qquickpanel_p_p.h> +#include <QtLabsTemplates/private/qquickpopup_p_p.h> QT_BEGIN_NAMESPACE class QQmlObjectModel; -class Q_LABSTEMPLATES_EXPORT QQuickMenuPrivate : public QQuickPanelPrivate, public QQuickItemChangeListener +class Q_LABSTEMPLATES_EXPORT QQuickMenuPrivate : public QQuickPopupPrivate, public QQuickItemChangeListener { Q_DECLARE_PUBLIC(QQuickMenu) @@ -91,8 +91,6 @@ public: bool ignoreActiveFocusChanges; }; -Q_DECLARE_TYPEINFO(QQuickMenuPrivate, Q_COMPLEX_TYPE); - QT_END_NAMESPACE #endif // QQUICKMENU_P_P_H diff --git a/src/templates/qquickmenuitem.cpp b/src/templates/qquickmenuitem.cpp index 83696535..f6cfda4c 100644 --- a/src/templates/qquickmenuitem.cpp +++ b/src/templates/qquickmenuitem.cpp @@ -37,6 +37,7 @@ #include "qquickmenuitem_p.h" #include "qquickabstractbutton_p_p.h" +#include <QtGui/qpa/qplatformtheme.h> #include <QtQuick/private/qquickevents_p_p.h> QT_BEGIN_NAMESPACE @@ -56,7 +57,7 @@ QT_BEGIN_NAMESPACE Button { id: fileButton text: "File" - onClicked: menu.show() + onClicked: menu.open() } Menu { id: menu @@ -89,6 +90,11 @@ QQuickMenuItem::QQuickMenuItem(QQuickItem *parent) : connect(this, &QQuickAbstractButton::clicked, this, &QQuickMenuItem::triggered); } +QFont QQuickMenuItem::defaultFont() const +{ + return QQuickControlPrivate::themeFont(QPlatformTheme::MenuItemFont); +} + #ifndef QT_NO_ACCESSIBILITY QAccessible::Role QQuickMenuItem::accessibleRole() const { diff --git a/src/templates/qquickmenuitem_p.h b/src/templates/qquickmenuitem_p.h index 3f86fe2e..91d1e91e 100644 --- a/src/templates/qquickmenuitem_p.h +++ b/src/templates/qquickmenuitem_p.h @@ -65,6 +65,8 @@ Q_SIGNALS: void triggered(); protected: + QFont defaultFont() const Q_DECL_OVERRIDE; + #ifndef QT_NO_ACCESSIBILITY QAccessible::Role accessibleRole() const Q_DECL_OVERRIDE; #endif @@ -74,8 +76,8 @@ private: Q_DECLARE_PRIVATE(QQuickMenuItem) }; -Q_DECLARE_TYPEINFO(QQuickMenuItem, Q_COMPLEX_TYPE); - QT_END_NAMESPACE +QML_DECLARE_TYPE(QQuickMenuItem) + #endif // QQUICKMENUITEM_P_H diff --git a/src/templates/qquickoverlay.cpp b/src/templates/qquickoverlay.cpp index 4a00387a..e06d28ea 100644 --- a/src/templates/qquickoverlay.cpp +++ b/src/templates/qquickoverlay.cpp @@ -35,88 +35,215 @@ ****************************************************************************/ #include "qquickoverlay_p.h" -#include "qquickpanel_p.h" +#include "qquickpopup_p.h" +#include "qquickdrawer_p.h" #include <QtQml/qqmlinfo.h> +#include <QtQml/qqmlproperty.h> #include <QtQuick/private/qquickitem_p.h> QT_BEGIN_NAMESPACE +class QQuickOverlayPrivate : public QQuickItemPrivate +{ + Q_DECLARE_PUBLIC(QQuickOverlay) + +public: + QQuickOverlayPrivate(); + + void popupAboutToShow(); + void popupAboutToHide(); + void drawerPositionChange(); + void resizeBackground(); + + QQuickItem *background; + QVector<QQuickDrawer *> drawers; + QHash<QQuickItem *, QQuickPopup *> popups; + int modalPopups; +}; + +void QQuickOverlayPrivate::popupAboutToShow() +{ + Q_Q(QQuickOverlay); + if (!background || modalPopups > 1) + return; + + QQuickPopup *popup = qobject_cast<QQuickPopup *>(q->sender()); + if (!popup || !popup->isModal()) + return; + + // use QQmlProperty instead of QQuickItem::setOpacity() to trigger QML Behaviors + QQmlProperty::write(background, QStringLiteral("opacity"), 1.0); +} + +void QQuickOverlayPrivate::popupAboutToHide() +{ + Q_Q(QQuickOverlay); + if (!background || modalPopups > 1) + return; + + QQuickPopup *popup = qobject_cast<QQuickPopup *>(q->sender()); + if (!popup || !popup->isModal()) + return; + + // use QQmlProperty instead of QQuickItem::setOpacity() to trigger QML Behaviors + QQmlProperty::write(background, QStringLiteral("opacity"), 0.0); +} + +void QQuickOverlayPrivate::drawerPositionChange() +{ + Q_Q(QQuickOverlay); + QQuickDrawer *drawer = qobject_cast<QQuickDrawer *>(q->sender()); + if (!background || !drawer || modalPopups > 0) + return; + + // call QQuickItem::setOpacity() directly to avoid triggering QML Behaviors + // which would make the fading feel laggy compared to the drawer movement + background->setOpacity(drawer->position()); +} + +void QQuickOverlayPrivate::resizeBackground() +{ + Q_Q(QQuickOverlay); + background->setWidth(q->width()); + background->setHeight(q->height()); +} + +QQuickOverlayPrivate::QQuickOverlayPrivate() : + background(Q_NULLPTR), + modalPopups(0) +{ +} + QQuickOverlay::QQuickOverlay(QQuickItem *parent) - : QQuickItem(parent), m_modalPanels(0) + : QQuickItem(*(new QQuickOverlayPrivate), parent) { setAcceptedMouseButtons(Qt::AllButtons); setFiltersChildMouseEvents(true); setVisible(false); } + +QQuickItem *QQuickOverlay::background() const +{ + Q_D(const QQuickOverlay); + return d->background; +} + +void QQuickOverlay::setBackground(QQuickItem *background) +{ + Q_D(QQuickOverlay); + if (d->background != background) { + delete d->background; + d->background = background; + if (background) { + background->setOpacity(0.0); + background->setParentItem(this); + if (qFuzzyIsNull(background->z())) + background->setZ(-1); + if (isComponentComplete()) + d->resizeBackground(); + } + emit backgroundChanged(); + } +} + void QQuickOverlay::itemChange(ItemChange change, const ItemChangeData &data) { + Q_D(QQuickOverlay); QQuickItem::itemChange(change, data); - QQuickItem *panelItem = const_cast<QQuickItem *>(data.item); - QQuickPanel *panel = Q_NULLPTR; + QQuickPopup *popup = Q_NULLPTR; if (change == ItemChildAddedChange || change == ItemChildRemovedChange) { - panel = qobject_cast<QQuickPanel *>(panelItem->parent()); + QQuickDrawer *drawer = qobject_cast<QQuickDrawer *>(data.item); + if (drawer) { + if (change == ItemChildAddedChange) { + QObjectPrivate::connect(drawer, &QQuickDrawer::positionChanged, d, &QQuickOverlayPrivate::drawerPositionChange); + d->drawers.append(drawer); + } else { + QObjectPrivate::disconnect(drawer, &QQuickDrawer::positionChanged, d, &QQuickOverlayPrivate::drawerPositionChange); + d->drawers.removeOne(drawer); + } + } else { + popup = qobject_cast<QQuickPopup *>(data.item->parent()); + } setVisible(!childItems().isEmpty()); } - if (!panel) + if (!popup) return; if (change == ItemChildAddedChange) { - if (QQuickPanel *prevPanel = m_panels.value(panelItem)) { - qmlInfo(panel).nospace() << "Panel is sharing item " << panelItem << " with " << prevPanel + if (QQuickPopup *prevPopup = d->popups.value(data.item)) { + qmlInfo(popup).nospace() << "Popup is sharing item " << data.item << " with " << prevPopup << ". This is not supported and strange things are about to happen."; return; } - m_panels.insert(panelItem, panel); - if (panel->isModal()) - ++m_modalPanels; + d->popups.insert(data.item, popup); + if (popup->isModal()) + ++d->modalPopups; - connect(this, &QQuickOverlay::pressed, panel, &QQuickPanel::pressedOutside); - connect(this, &QQuickOverlay::released, panel, &QQuickPanel::releasedOutside); + connect(this, &QQuickOverlay::pressed, popup, &QQuickPopup::pressedOutside); + connect(this, &QQuickOverlay::released, popup, &QQuickPopup::releasedOutside); + QObjectPrivate::connect(popup, &QQuickPopup::aboutToShow, d, &QQuickOverlayPrivate::popupAboutToShow); + QObjectPrivate::connect(popup, &QQuickPopup::aboutToHide, d, &QQuickOverlayPrivate::popupAboutToHide); } else if (change == ItemChildRemovedChange) { - Q_ASSERT(panel == m_panels.value(panelItem)); + Q_ASSERT(popup == d->popups.value(data.item)); - disconnect(this, &QQuickOverlay::pressed, panel, &QQuickPanel::pressedOutside); - disconnect(this, &QQuickOverlay::released, panel, &QQuickPanel::releasedOutside); + disconnect(this, &QQuickOverlay::pressed, popup, &QQuickPopup::pressedOutside); + disconnect(this, &QQuickOverlay::released, popup, &QQuickPopup::releasedOutside); + QObjectPrivate::disconnect(popup, &QQuickPopup::aboutToShow, d, &QQuickOverlayPrivate::popupAboutToShow); + QObjectPrivate::disconnect(popup, &QQuickPopup::aboutToHide, d, &QQuickOverlayPrivate::popupAboutToHide); - if (panel->isModal()) - --m_modalPanels; - m_panels.remove(panelItem); + if (popup->isModal()) + --d->modalPopups; + d->popups.remove(data.item); } } +void QQuickOverlay::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) +{ + Q_D(QQuickOverlay); + QQuickItem::geometryChanged(newGeometry, oldGeometry); + if (d->background) + d->resizeBackground(); +} + void QQuickOverlay::keyPressEvent(QKeyEvent *event) { - event->setAccepted(m_modalPanels > 0); + Q_D(QQuickOverlay); + event->setAccepted(d->modalPopups > 0); } void QQuickOverlay::keyReleaseEvent(QKeyEvent *event) { - event->setAccepted(m_modalPanels > 0); + Q_D(QQuickOverlay); + event->setAccepted(d->modalPopups > 0); } void QQuickOverlay::mousePressEvent(QMouseEvent *event) { - event->setAccepted(m_modalPanels > 0); + Q_D(QQuickOverlay); + event->setAccepted(d->modalPopups > 0); emit pressed(); } void QQuickOverlay::mouseMoveEvent(QMouseEvent *event) { - event->setAccepted(m_modalPanels > 0); + Q_D(QQuickOverlay); + event->setAccepted(d->modalPopups > 0); } void QQuickOverlay::mouseReleaseEvent(QMouseEvent *event) { - event->setAccepted(m_modalPanels > 0); + Q_D(QQuickOverlay); + event->setAccepted(d->modalPopups > 0); emit released(); } bool QQuickOverlay::childMouseEventFilter(QQuickItem *item, QEvent *event) { - if (m_modalPanels == 0) + Q_D(QQuickOverlay); + if (d->modalPopups == 0) return false; // TODO Filter touch events if (event->type() != QEvent::MouseButtonPress) @@ -128,15 +255,15 @@ bool QQuickOverlay::childMouseEventFilter(QQuickItem *item, QEvent *event) const QQuickItemPrivate *priv = QQuickItemPrivate::get(this); const QList<QQuickItem *> &sortedChildren = priv->paintOrderChildItems(); for (int i = sortedChildren.count() - 1; i >= 0; --i) { - QQuickItem *panelItem = sortedChildren[i]; - if (panelItem == item) + QQuickItem *contentItem = sortedChildren[i]; + if (contentItem == item) break; - QQuickPanel *panel = m_panels.value(panelItem); - if (panel) { - emit panel->pressedOutside(); + QQuickPopup *popup = d->popups.value(contentItem); + if (popup) { + emit popup->pressedOutside(); - if (!modalBlocked && panel->isModal()) + if (!modalBlocked && popup->isModal()) modalBlocked = true; } } diff --git a/src/templates/qquickoverlay_p.h b/src/templates/qquickoverlay_p.h index c5f9b719..a48b54ed 100644 --- a/src/templates/qquickoverlay_p.h +++ b/src/templates/qquickoverlay_p.h @@ -49,24 +49,31 @@ // #include <QtQuick/qquickitem.h> +#include <QtLabsTemplates/private/qquickabstractbutton_p.h> QT_BEGIN_NAMESPACE -class QQuickPanel; +class QQuickOverlayPrivate; -class QQuickOverlay : public QQuickItem +class Q_LABSTEMPLATES_EXPORT QQuickOverlay : public QQuickItem { Q_OBJECT + Q_PROPERTY(QQuickItem *background READ background WRITE setBackground NOTIFY backgroundChanged FINAL) public: explicit QQuickOverlay(QQuickItem *parent = Q_NULLPTR); + QQuickItem *background() const; + void setBackground(QQuickItem *background); + Q_SIGNALS: + void backgroundChanged(); void pressed(); void released(); protected: void itemChange(ItemChange change, const ItemChangeData &data) Q_DECL_OVERRIDE; + void geometryChanged(const QRectF &oldGeometry, const QRectF &newGeometry) Q_DECL_OVERRIDE; void keyPressEvent(QKeyEvent *event) Q_DECL_OVERRIDE; void keyReleaseEvent(QKeyEvent *event) Q_DECL_OVERRIDE; @@ -77,10 +84,11 @@ protected: private: Q_DISABLE_COPY(QQuickOverlay) - QHash<QQuickItem *, QQuickPanel *> m_panels; - int m_modalPanels; + Q_DECLARE_PRIVATE(QQuickOverlay) }; QT_END_NAMESPACE +QML_DECLARE_TYPE(QQuickOverlay) + #endif // QQUICKOVERLAY_P_H diff --git a/src/templates/qquickpageindicator_p.h b/src/templates/qquickpageindicator_p.h index 46eb2cb2..487b4d6e 100644 --- a/src/templates/qquickpageindicator_p.h +++ b/src/templates/qquickpageindicator_p.h @@ -101,8 +101,8 @@ private: Q_DECLARE_PRIVATE(QQuickPageIndicator) }; -Q_DECLARE_TYPEINFO(QQuickPageIndicator, Q_COMPLEX_TYPE); - QT_END_NAMESPACE +QML_DECLARE_TYPE(QQuickPageIndicator) + #endif // QQUICKPAGEINDICATOR_P_H diff --git a/src/templates/qquickpane.cpp b/src/templates/qquickpane.cpp new file mode 100644 index 00000000..27e76ea3 --- /dev/null +++ b/src/templates/qquickpane.cpp @@ -0,0 +1,184 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Templates 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 "qquickpane_p.h" +#include "qquickpane_p_p.h" + +QT_BEGIN_NAMESPACE + +/*! + \qmltype Pane + \inherits Control + \instantiates QQuickPane + \inqmlmodule Qt.labs.controls + \ingroup qtlabscontrols-containers + \brief A pane control. + + Pane provides a background color that matches with the application style + and theme. Pane 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. + + If only a single item is used within a Pane, it will resize to fit the + implicit size of its contained item. This makes it particularly suitable + for use together with layouts. + + \image qtlabscontrols-pane.png + + \snippet qtlabscontrols-pane.qml 1 + + \sa {Customizing Pane}, {Container Controls} +*/ + +QQuickPanePrivate::QQuickPanePrivate() : contentWidth(0), contentHeight(0) +{ +} + +QQuickPane::QQuickPane(QQuickItem *parent) : + QQuickControl(*(new QQuickPanePrivate), parent) +{ + setFlag(QQuickItem::ItemIsFocusScope); + setAcceptedMouseButtons(Qt::AllButtons); +} + +QQuickPane::QQuickPane(QQuickPanePrivate &dd, QQuickItem *parent) : + QQuickControl(dd, parent) +{ + setFlag(QQuickItem::ItemIsFocusScope); + setAcceptedMouseButtons(Qt::AllButtons); +} + +/*! + \qmlproperty real Qt.labs.controls::Pane::contentWidth + + This property holds the content width. It is used for calculating the + total implicit width of the pane. + + \note If only a single item is used within the pane, the implicit width + of its contained item is used as the content width. +*/ +qreal QQuickPane::contentWidth() const +{ + Q_D(const QQuickPane); + return d->contentWidth; +} + +void QQuickPane::setContentWidth(qreal width) +{ + Q_D(QQuickPane); + if (d->contentWidth != width) { + d->contentWidth = width; + emit contentWidthChanged(); + } +} + +/*! + \qmlproperty real Qt.labs.controls::Pane::contentHeight + + This property holds the content height. It is used for calculating the + total implicit height of the pane. + + \note If only a single item is used within the pane, the implicit height + of its contained item is used as the content height. +*/ +qreal QQuickPane::contentHeight() const +{ + Q_D(const QQuickPane); + return d->contentHeight; +} + +void QQuickPane::setContentHeight(qreal height) +{ + Q_D(QQuickPane); + if (d->contentHeight != height) { + d->contentHeight = height; + emit contentHeightChanged(); + } +} + +/*! + \qmlproperty list<Object> Qt.labs.controls::Pane::contentData + \default + + This property holds the list of content data. + + \sa Item::data +*/ +QQmlListProperty<QObject> QQuickPane::contentData() +{ + Q_D(QQuickPane); + return QQmlListProperty<QObject>(d->contentItem, Q_NULLPTR, + QQuickItemPrivate::data_append, + QQuickItemPrivate::data_count, + QQuickItemPrivate::data_at, + QQuickItemPrivate::data_clear); +} + +/*! + \qmlproperty list<Item> Qt.labs.controls::Pane::contentChildren + + This property holds the list of content children. + + \sa Item::children +*/ +QQmlListProperty<QQuickItem> QQuickPane::contentChildren() +{ + Q_D(QQuickPane); + return QQmlListProperty<QQuickItem>(d->contentItem, Q_NULLPTR, + QQuickItemPrivate::children_append, + QQuickItemPrivate::children_count, + QQuickItemPrivate::children_at, + QQuickItemPrivate::children_clear); +} + +void QQuickPane::contentItemChange(QQuickItem *newItem, QQuickItem *oldItem) +{ + QQuickControl::contentItemChange(newItem, oldItem); + if (oldItem) + disconnect(oldItem, &QQuickItem::childrenChanged, this, &QQuickPane::contentChildrenChanged); + if (newItem) + connect(newItem, &QQuickItem::childrenChanged, this, &QQuickPane::contentChildrenChanged); + emit contentChildrenChanged(); +} + +#ifndef QT_NO_ACCESSIBILITY +QAccessible::Role QQuickPane::accessibleRole() const +{ + return QAccessible::Pane; +} +#endif + +QT_END_NAMESPACE diff --git a/src/templates/qquickpane_p.h b/src/templates/qquickpane_p.h new file mode 100644 index 00000000..e599f55f --- /dev/null +++ b/src/templates/qquickpane_p.h @@ -0,0 +1,102 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Templates 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 QQUICKPANE_P_H +#define QQUICKPANE_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 <QtLabsTemplates/private/qquickcontrol_p.h> +#include <QtQml/qqmllist.h> + +QT_BEGIN_NAMESPACE + +class QQuickPanePrivate; + +class Q_LABSTEMPLATES_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_CLASSINFO("DefaultProperty", "contentData") + +public: + explicit QQuickPane(QQuickItem *parent = Q_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: + QQuickPane(QQuickPanePrivate &dd, QQuickItem *parent); + + void contentItemChange(QQuickItem *newItem, QQuickItem *oldItem) Q_DECL_OVERRIDE; + +#ifndef QT_NO_ACCESSIBILITY + QAccessible::Role accessibleRole() const Q_DECL_OVERRIDE; +#endif + +private: + Q_DISABLE_COPY(QQuickPane) + Q_DECLARE_PRIVATE(QQuickPane) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickPane) + +#endif // QQUICKPANE_P_H diff --git a/src/templates/qquickpane_p_p.h b/src/templates/qquickpane_p_p.h new file mode 100644 index 00000000..477dc0bc --- /dev/null +++ b/src/templates/qquickpane_p_p.h @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Templates 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 QQUICKPANE_P_P_H +#define QQUICKPANE_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 <QtLabsTemplates/private/qquickcontrol_p_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickPane; + +class Q_LABSTEMPLATES_EXPORT QQuickPanePrivate : public QQuickControlPrivate +{ + Q_DECLARE_PUBLIC(QQuickPane) + +public: + QQuickPanePrivate(); + + qreal contentWidth; + qreal contentHeight; +}; + +QT_END_NAMESPACE + +#endif // QQUICKPANE_P_P_H diff --git a/src/templates/qquickpanel.cpp b/src/templates/qquickpopup.cpp index 38f1a73c..2e826591 100644 --- a/src/templates/qquickpanel.cpp +++ b/src/templates/qquickpopup.cpp @@ -34,10 +34,11 @@ ** ****************************************************************************/ -#include "qquickpanel_p.h" -#include "qquickpanel_p_p.h" +#include "qquickpopup_p.h" +#include "qquickpopup_p_p.h" #include "qquickapplicationwindow_p.h" #include "qquickoverlay_p.h" + #include <QtQml/qqmlinfo.h> #include <QtQuick/qquickitem.h> #include <QtQuick/private/qquicktransition_p.h> @@ -46,183 +47,178 @@ QT_BEGIN_NAMESPACE /*! - \qmltype Panel + \qmltype Popup \inherits QtObject - \instantiates QQuickPanel + \instantiates QQuickPopup \inqmlmodule Qt.labs.controls \ingroup qtlabscontrols-popups - \brief A popup panel. + \brief A popup control. - Panel is the base type of popup-like user interface controls. + Popup is the base type of popup-like user interface controls. */ -QQuickPanelPrivate::QQuickPanelPrivate() +QQuickPopupPrivate::QQuickPopupPrivate() : QObjectPrivate() - , contentItem(Q_NULLPTR) - , overlay(Q_NULLPTR) , focus(false) , modal(false) - , showTransition(Q_NULLPTR) - , hideTransition(Q_NULLPTR) + , contentItem(Q_NULLPTR) + , overlay(Q_NULLPTR) + , enter(Q_NULLPTR) + , exit(Q_NULLPTR) , transitionManager(this) -{ } - -QQuickPanelPrivate::~QQuickPanelPrivate() -{ } +{ +} -void QQuickPanelPrivate::finalizeShowTransition() +void QQuickPopupPrivate::finalizeEnterTransition() { if (focus) contentItem->setFocus(true); } -void QQuickPanelPrivate::finalizeHideTransition() +void QQuickPopupPrivate::finalizeExitTransition() { + Q_Q(QQuickPopup); overlay = Q_NULLPTR; contentItem->setParentItem(Q_NULLPTR); - emit q_func()->visibleChanged(); + emit q->visibleChanged(); } -QQuickPanelTransitionManager::QQuickPanelTransitionManager(QQuickPanelPrivate *priv) +QQuickPopupTransitionManager::QQuickPopupTransitionManager(QQuickPopupPrivate *popup) : QQuickTransitionManager() , state(Off) - , pp(priv) -{ } + , popup(popup) +{ +} -void QQuickPanelTransitionManager::transitionShow() +void QQuickPopupTransitionManager::transitionEnter() { - if (isRunning()) + if (state == Enter && isRunning()) return; QList<QQuickStateAction> actions; - state = Show; - transition(actions, pp->showTransition, pp->contentItem); + state = Enter; + transition(actions, popup->enter, popup->contentItem); } -void QQuickPanelTransitionManager::transitionHide() +void QQuickPopupTransitionManager::transitionExit() { - if (isRunning()) + if (state == Exit && isRunning()) return; QList<QQuickStateAction> actions; - state = Hide; - transition(actions, pp->hideTransition, pp->contentItem); + state = Exit; + transition(actions, popup->exit, popup->contentItem); } -void QQuickPanelTransitionManager::finished() +void QQuickPopupTransitionManager::finished() { - if (state == Show) - pp->finalizeShowTransition(); - else if (state == Hide) - pp->finalizeHideTransition(); + if (state == Enter) + popup->finalizeEnterTransition(); + else if (state == Exit) + popup->finalizeExitTransition(); state = Off; } -QQuickPanel::QQuickPanel(QObject *parent) - : QObject(*(new QQuickPanelPrivate), parent) +QQuickPopup::QQuickPopup(QObject *parent) + : QObject(*(new QQuickPopupPrivate), parent) { } -QQuickPanel::QQuickPanel(QQuickPanelPrivate &dd, QObject *parent) +QQuickPopup::QQuickPopup(QQuickPopupPrivate &dd, QObject *parent) : QObject(dd, parent) { } -QQuickPanel::~QQuickPanel() -{ -} - /*! - \qmlmethod void Qt.labs.controls::Panel::show() + \qmlmethod void Qt.labs.controls::Popup::open() - Shows the panel. + Opens the popup. */ -void QQuickPanel::show() +void QQuickPopup::open() { - Q_D(QQuickPanel); + Q_D(QQuickPopup); if (!d->contentItem) { - qmlInfo(this) << "no panel content to show."; + qmlInfo(this) << "no popup content to show."; return; } if (d->overlay) { // FIXME qmlInfo needs to know about QQuickWindow and/or QObject - static_cast<QDebug>(qmlInfo(this) << "panel already showing in window") << d->overlay->window(); + static_cast<QDebug>(qmlInfo(this) << "popup already open in window") << d->overlay->window(); return; } - QQuickWindow *win = Q_NULLPTR; + QQuickWindow *window = Q_NULLPTR; QObject *p = parent(); - while (p && !win) { + while (p && !window) { if (QQuickItem *item = qobject_cast<QQuickItem *>(p)) { - win = item->window(); - if (!win) + window = item->window(); + if (!window) p = item->parentItem(); } else { - win = qobject_cast<QQuickWindow *>(p); - if (!win) + window = qobject_cast<QQuickWindow *>(p); + if (!window) p = p->parent(); } } - if (!win) { - qmlInfo(this) << "cannot find any window to show panel."; + if (!window) { + qmlInfo(this) << "cannot find any window to open popup in."; return; } - if (QQuickApplicationWindow *appWin = qobject_cast<QQuickApplicationWindow*>(win)) { - d->overlay = static_cast<QQuickOverlay *>(appWin->overlay()); - d->contentItem->setParentItem(d->overlay); - } else { - // FIXME Maybe try to show it somehow on that window + QQuickApplicationWindow *applicationWindow = qobject_cast<QQuickApplicationWindow*>(window); + if (!applicationWindow) { + // FIXME Maybe try to open it in that window somehow qmlInfo(this) << "is not in an ApplicationWindow."; return; } + d->overlay = static_cast<QQuickOverlay *>(applicationWindow->overlay()); + d->contentItem->setParentItem(d->overlay); emit aboutToShow(); - d->transitionManager.transitionShow(); + d->transitionManager.transitionEnter(); emit visibleChanged(); } /*! - \qmlmethod void Qt.labs.controls::Panel::hide() + \qmlmethod void Qt.labs.controls::Popup::close() - Hides the panel. + Closes the popup. */ -void QQuickPanel::hide() +void QQuickPopup::close() { - Q_D(QQuickPanel); - + Q_D(QQuickPopup); if (!d->overlay) { - // TODO This could mean we showed the panel item on a plain QQuickWindow - qmlInfo(this) << "trying to hide non-visible Panel."; + // TODO This could mean we opened the popup item in a plain QQuickWindow + qmlInfo(this) << "trying to close non-visible Popup."; return; } d->contentItem->setFocus(false); emit aboutToHide(); - d->transitionManager.transitionHide(); + d->transitionManager.transitionExit(); } /*! - \qmlproperty Item Qt.labs.controls::Panel::contentItem + \qmlproperty Item Qt.labs.controls::Popup::contentItem - This property holds the content item of the panel. + This property holds the content item of the popup. - The content item is the visual implementation of the panel. When the - panel is made visible, the content item is automatically reparented to + The content item is the visual implementation of the popup. When the + popup is made visible, the content item is automatically reparented to the \l {ApplicationWindow::overlay}{overlay item} of its application window. */ -QQuickItem *QQuickPanel::contentItem() const +QQuickItem *QQuickPopup::contentItem() const { - Q_D(const QQuickPanel); + Q_D(const QQuickPopup); return d->contentItem; } -void QQuickPanel::setContentItem(QQuickItem *item) +void QQuickPopup::setContentItem(QQuickItem *item) { - Q_D(QQuickPanel); + Q_D(QQuickPopup); if (d->overlay) { // FIXME qmlInfo needs to know about QQuickItem and/or QObject - static_cast<QDebug>(qmlInfo(this) << "cannot set content item") << item << "while Panel is visible."; + static_cast<QDebug>(qmlInfo(this) << "cannot set content item") << item << "while Popup is visible."; return; } if (d->contentItem != item) { @@ -235,19 +231,19 @@ void QQuickPanel::setContentItem(QQuickItem *item) } /*! - \qmlproperty bool Qt.labs.controls::Panel::focus + \qmlproperty bool Qt.labs.controls::Popup::focus - This property holds whether the panel has focus. + This property holds whether the popup has focus. */ -bool QQuickPanel::hasFocus() const +bool QQuickPopup::hasFocus() const { - Q_D(const QQuickPanel); + Q_D(const QQuickPopup); return d->focus; } -void QQuickPanel::setFocus(bool focus) +void QQuickPopup::setFocus(bool focus) { - Q_D(QQuickPanel); + Q_D(QQuickPopup); if (d->focus == focus) return; d->focus = focus; @@ -255,19 +251,19 @@ void QQuickPanel::setFocus(bool focus) } /*! - \qmlproperty bool Qt.labs.controls::Panel::modal + \qmlproperty bool Qt.labs.controls::Popup::modal - This property holds whether the panel is modal. + This property holds whether the popup is modal. */ -bool QQuickPanel::isModal() const +bool QQuickPopup::isModal() const { - Q_D(const QQuickPanel); + Q_D(const QQuickPopup); return d->modal; } -void QQuickPanel::setModal(bool modal) +void QQuickPopup::setModal(bool modal) { - Q_D(QQuickPanel); + Q_D(QQuickPopup); if (d->modal == modal) return; d->modal = modal; @@ -275,56 +271,58 @@ void QQuickPanel::setModal(bool modal) } /*! - \qmlproperty bool Qt.labs.controls::Panel::visible + \qmlproperty bool Qt.labs.controls::Popup::visible - This property holds whether the panel is visible. + This property holds whether the popup is visible. */ -bool QQuickPanel::isVisible() const +bool QQuickPopup::isVisible() const { - Q_D(const QQuickPanel); + Q_D(const QQuickPopup); return d->overlay != Q_NULLPTR /*&& !d->transitionManager.isRunning()*/; } /*! - \qmlproperty Transition Qt.labs.controls::Panel::showTransition + \qmlproperty Transition Qt.labs.controls::Popup::enter This property holds the transition that is applied to the content item - when the panel is shown. + when the popup is opened and enters the screen. */ -QQuickTransition *QQuickPanel::showTransition() const +QQuickTransition *QQuickPopup::enter() const { - return d_func()->showTransition; + Q_D(const QQuickPopup); + return d->enter; } -void QQuickPanel::setShowTransition(QQuickTransition *t) +void QQuickPopup::setEnter(QQuickTransition *transition) { - Q_D(QQuickPanel); - if (d->showTransition == t) + Q_D(QQuickPopup); + if (d->enter == transition) return; - d->showTransition = t; - emit showTransitionChanged(); + d->enter = transition; + emit enterChanged(); } /*! - \qmlproperty Transition Qt.labs.controls::Panel::hideTransition + \qmlproperty Transition Qt.labs.controls::Popup::exit This property holds the transition that is applied to the content item - when the panel is hidden. + when the popup is closed and exits the screen. */ -QQuickTransition *QQuickPanel::hideTransition() const +QQuickTransition *QQuickPopup::exit() const { - return d_func()->hideTransition; + Q_D(const QQuickPopup); + return d->exit; } -void QQuickPanel::setHideTransition(QQuickTransition *t) +void QQuickPopup::setExit(QQuickTransition *transition) { - Q_D(QQuickPanel); - if (d->hideTransition == t) + Q_D(QQuickPopup); + if (d->exit == transition) return; - d->hideTransition = t; - emit hideTransitionChanged(); + d->exit = transition; + emit exitChanged(); } QT_END_NAMESPACE -#include "moc_qquickpanel_p.cpp" +#include "moc_qquickpopup_p.cpp" diff --git a/src/templates/qquickpanel_p.h b/src/templates/qquickpopup_p.h index 6d6f4df9..630b7a4a 100644 --- a/src/templates/qquickpanel_p.h +++ b/src/templates/qquickpopup_p.h @@ -34,8 +34,8 @@ ** ****************************************************************************/ -#ifndef QQUICKPANEL_P_H -#define QQUICKPANEL_P_H +#ifndef QQUICKPOPUP_P_H +#define QQUICKPOPUP_P_H // // W A R N I N G @@ -50,26 +50,26 @@ #include <QtCore/qobject.h> #include <QtLabsTemplates/private/qtlabstemplatesglobal_p.h> +#include <QtQml/qqml.h> QT_BEGIN_NAMESPACE class QQuickItem; -class QQuickPanelPrivate; +class QQuickPopupPrivate; class QQuickTransition; -class Q_LABSTEMPLATES_EXPORT QQuickPanel : public QObject +class Q_LABSTEMPLATES_EXPORT QQuickPopup : public QObject { Q_OBJECT Q_PROPERTY(QQuickItem *contentItem READ contentItem WRITE setContentItem NOTIFY contentItemChanged FINAL) Q_PROPERTY(bool focus READ hasFocus WRITE setFocus NOTIFY focusChanged) Q_PROPERTY(bool modal READ isModal WRITE setModal NOTIFY modalChanged) Q_PROPERTY(bool visible READ isVisible NOTIFY visibleChanged) - Q_PROPERTY(QQuickTransition *showTransition READ showTransition WRITE setShowTransition NOTIFY showTransitionChanged FINAL) - Q_PROPERTY(QQuickTransition *hideTransition READ showTransition WRITE setHideTransition NOTIFY hideTransitionChanged FINAL) + Q_PROPERTY(QQuickTransition *enter READ enter WRITE setEnter NOTIFY enterChanged FINAL) + Q_PROPERTY(QQuickTransition *exit READ exit WRITE setExit NOTIFY exitChanged FINAL) public: - explicit QQuickPanel(QObject *parent = Q_NULLPTR); - ~QQuickPanel(); + explicit QQuickPopup(QObject *parent = Q_NULLPTR); QQuickItem *contentItem() const; void setContentItem(QQuickItem *item); @@ -82,19 +82,23 @@ public: bool isVisible() const; - QQuickTransition *showTransition() const; - void setShowTransition(QQuickTransition *); + QQuickTransition *enter() const; + void setEnter(QQuickTransition *transition); - QQuickTransition *hideTransition() const; - void setHideTransition(QQuickTransition *); + QQuickTransition *exit() const; + void setExit(QQuickTransition *transition); + +public Q_SLOTS: + void open(); + void close(); Q_SIGNALS: void contentItemChanged(); void focusChanged(); void modalChanged(); void visibleChanged(); - void showTransitionChanged(); - void hideTransitionChanged(); + void enterChanged(); + void exitChanged(); void pressedOutside(); void releasedOutside(); @@ -103,19 +107,16 @@ Q_SIGNALS: void aboutToShow(); void aboutToHide(); - -public Q_SLOTS: - void show(); - void hide(); - protected: - QQuickPanel(QQuickPanelPrivate &dd, QObject *parent); + QQuickPopup(QQuickPopupPrivate &dd, QObject *parent); private: - Q_DISABLE_COPY(QQuickPanel) - Q_DECLARE_PRIVATE(QQuickPanel) + Q_DISABLE_COPY(QQuickPopup) + Q_DECLARE_PRIVATE(QQuickPopup) }; QT_END_NAMESPACE -#endif // QQUICKPANEL_P_H +QML_DECLARE_TYPE(QQuickPopup) + +#endif // QQUICKPOPUP_P_H diff --git a/src/templates/qquickpanel_p_p.h b/src/templates/qquickpopup_p_p.h index 42c06cd9..b0c6d709 100644 --- a/src/templates/qquickpanel_p_p.h +++ b/src/templates/qquickpopup_p_p.h @@ -34,8 +34,8 @@ ** ****************************************************************************/ -#ifndef QQUICKPANEL_P_P_H -#define QQUICKPANEL_P_P_H +#ifndef QQUICKPOPUP_P_P_H +#define QQUICKPOPUP_P_P_H // // W A R N I N G @@ -56,50 +56,50 @@ QT_BEGIN_NAMESPACE class QQuickItem; class QQuickTransition; class QQuickTransitionManager; -class QQuickPanel; -class QQuickPanelPrivate; +class QQuickPopup; +class QQuickPopupPrivate; class QQuickOverlay; -class QQuickPanelTransitionManager : public QQuickTransitionManager +class QQuickPopupTransitionManager : public QQuickTransitionManager { public: - QQuickPanelTransitionManager(QQuickPanelPrivate *); - void transitionShow(); - void transitionHide(); + QQuickPopupTransitionManager(QQuickPopupPrivate *popup); + + void transitionEnter(); + void transitionExit(); protected: void finished() Q_DECL_OVERRIDE; private: enum TransitionState { - Off, Show, Hide + Off, Enter, Exit }; TransitionState state; - QQuickPanelPrivate *pp; + QQuickPopupPrivate *popup; }; -class QQuickPanelPrivate : public QObjectPrivate +class QQuickPopupPrivate : public QObjectPrivate { - Q_DECLARE_PUBLIC(QQuickPanel) + Q_DECLARE_PUBLIC(QQuickPopup) public: - QQuickPanelPrivate(); - ~QQuickPanelPrivate(); + QQuickPopupPrivate(); - void finalizeShowTransition(); - void finalizeHideTransition(); + void finalizeEnterTransition(); + void finalizeExitTransition(); - QQuickItem *contentItem; - QQuickOverlay *overlay; bool focus; bool modal; - QQuickTransition *showTransition; - QQuickTransition *hideTransition; - QQuickPanelTransitionManager transitionManager; + QQuickItem *contentItem; + QQuickOverlay *overlay; + QQuickTransition *enter; + QQuickTransition *exit; + QQuickPopupTransitionManager transitionManager; }; QT_END_NAMESPACE -#endif // QQUICKPANEL_P_P_H +#endif // QQUICKPOPUP_P_P_H diff --git a/src/templates/qquickprogressbar.cpp b/src/templates/qquickprogressbar.cpp index f1a4c00f..aa0789bc 100644 --- a/src/templates/qquickprogressbar.cpp +++ b/src/templates/qquickprogressbar.cpp @@ -251,7 +251,7 @@ void QQuickProgressBar::setIndicator(QQuickItem *indicator) void QQuickProgressBar::mirrorChange() { QQuickControl::mirrorChange(); - if (!qFuzzyCompare(position(), 0.5)) + if (!qFuzzyCompare(position(), qreal(0.5))) emit visualPositionChanged(); } diff --git a/src/templates/qquickprogressbar_p.h b/src/templates/qquickprogressbar_p.h index f311e1c6..f94c718e 100644 --- a/src/templates/qquickprogressbar_p.h +++ b/src/templates/qquickprogressbar_p.h @@ -108,8 +108,8 @@ private: Q_DECLARE_PRIVATE(QQuickProgressBar) }; -Q_DECLARE_TYPEINFO(QQuickProgressBar, Q_COMPLEX_TYPE); - QT_END_NAMESPACE +QML_DECLARE_TYPE(QQuickProgressBar) + #endif // QQUICKPROGRESSBAR_P_H diff --git a/src/templates/qquickradiobutton_p.h b/src/templates/qquickradiobutton_p.h index 1667de22..7d664864 100644 --- a/src/templates/qquickradiobutton_p.h +++ b/src/templates/qquickradiobutton_p.h @@ -67,8 +67,8 @@ protected: #endif }; -Q_DECLARE_TYPEINFO(QQuickRadioButton, Q_COMPLEX_TYPE); - QT_END_NAMESPACE +QML_DECLARE_TYPE(QQuickRadioButton) + #endif // QQUICKRADIOBUTTON_P_H diff --git a/src/templates/qquickrangeslider.cpp b/src/templates/qquickrangeslider.cpp index 2d0806e2..70d5a03d 100644 --- a/src/templates/qquickrangeslider.cpp +++ b/src/templates/qquickrangeslider.cpp @@ -119,8 +119,8 @@ void QQuickRangeSliderNodePrivate::setPosition(qreal position, bool ignoreOtherP { Q_Q(QQuickRangeSliderNode); - const qreal min = isFirst() || ignoreOtherPosition ? 0.0 : qMax(0.0, slider->first()->position()); - const qreal max = !isFirst() || ignoreOtherPosition ? 1.0 : qMin(1.0, slider->second()->position()); + const qreal min = isFirst() || ignoreOtherPosition ? 0.0 : qMax<qreal>(0.0, slider->first()->position()); + const qreal max = !isFirst() || ignoreOtherPosition ? 1.0 : qMin<qreal>(1.0, slider->second()->position()); position = qBound(min, position, max); if (!qFuzzyCompare(this->position, position)) { this->position = position; diff --git a/src/templates/qquickrangeslider_p.h b/src/templates/qquickrangeslider_p.h index 3bd46624..604666c8 100644 --- a/src/templates/qquickrangeslider_p.h +++ b/src/templates/qquickrangeslider_p.h @@ -129,8 +129,6 @@ private: Q_DECLARE_PRIVATE(QQuickRangeSlider) }; -Q_DECLARE_TYPEINFO(QQuickRangeSlider, Q_COMPLEX_TYPE); - class QQuickRangeSliderNodePrivate; class Q_LABSTEMPLATES_EXPORT QQuickRangeSliderNode : public QObject @@ -174,8 +172,8 @@ private: Q_DECLARE_PRIVATE(QQuickRangeSliderNode) }; -Q_DECLARE_TYPEINFO(QQuickRangeSliderNode, Q_COMPLEX_TYPE); - QT_END_NAMESPACE +QML_DECLARE_TYPE(QQuickRangeSlider) + #endif // QQUICKRANGESLIDER_H diff --git a/src/templates/qquickscrollbar.cpp b/src/templates/qquickscrollbar.cpp index f6499004..23db7fcf 100644 --- a/src/templates/qquickscrollbar.cpp +++ b/src/templates/qquickscrollbar.cpp @@ -267,14 +267,14 @@ void QQuickScrollBar::mouseMoveEvent(QMouseEvent *event) { Q_D(QQuickScrollBar); QQuickControl::mouseMoveEvent(event); - setPosition(qBound(0.0, positionAt(event->pos()) - d->offset, 1.0 - d->size)); + setPosition(qBound<qreal>(0.0, positionAt(event->pos()) - d->offset, 1.0 - d->size)); } void QQuickScrollBar::mouseReleaseEvent(QMouseEvent *event) { Q_D(QQuickScrollBar); QQuickControl::mouseReleaseEvent(event); - setPosition(qBound(0.0, positionAt(event->pos()) - d->offset, 1.0 - d->size)); + setPosition(qBound<qreal>(0.0, positionAt(event->pos()) - d->offset, 1.0 - d->size)); d->offset = 0.0; setPressed(false); } @@ -386,12 +386,11 @@ void QQuickScrollBarAttachedPrivate::itemGeometryChanged(QQuickItem *item, const { Q_UNUSED(item); Q_UNUSED(newGeometry); - Q_ASSERT(item == flickable); - if (horizontal) { + if (horizontal && horizontal->height() > 0) { bool move = qFuzzyIsNull(horizontal->y()) || qFuzzyCompare(horizontal->y(), oldGeometry.height() - horizontal->height()); layoutHorizontal(move); } - if (vertical) { + if (vertical && vertical->width() > 0) { bool move = qFuzzyIsNull(vertical->x()) || qFuzzyCompare(vertical->x(), oldGeometry.width() - vertical->width()); layoutVertical(move); } @@ -402,7 +401,16 @@ QQuickScrollBarAttached::QQuickScrollBarAttached(QQuickFlickable *flickable) : { Q_D(QQuickScrollBarAttached); QQuickItemPrivate *p = QQuickItemPrivate::get(flickable); - p->addItemChangeListener(d, QQuickItemPrivate::Geometry); + p->updateOrAddGeometryChangeListener(d, QQuickItemPrivate::SizeChange); +} + +QQuickScrollBarAttached::~QQuickScrollBarAttached() +{ + Q_D(QQuickScrollBarAttached); + if (d->horizontal) + QQuickItemPrivate::get(d->horizontal)->removeItemChangeListener(d, QQuickItemPrivate::Geometry); + if (d->vertical) + QQuickItemPrivate::get(d->vertical)->removeItemChangeListener(d, QQuickItemPrivate::Geometry); } /*! @@ -428,6 +436,7 @@ void QQuickScrollBarAttached::setHorizontal(QQuickScrollBar *horizontal) Q_D(QQuickScrollBarAttached); if (d->horizontal != horizontal) { if (d->horizontal) { + QQuickItemPrivate::get(d->horizontal)->removeItemChangeListener(d, QQuickItemPrivate::Geometry); QObjectPrivate::disconnect(d->horizontal, &QQuickScrollBar::positionChanged, d, &QQuickScrollBarAttachedPrivate::scrollHorizontal); QObjectPrivate::disconnect(d->flickable, &QQuickFlickable::movingHorizontallyChanged, d, &QQuickScrollBarAttachedPrivate::activateHorizontal); @@ -444,6 +453,7 @@ void QQuickScrollBarAttached::setHorizontal(QQuickScrollBar *horizontal) horizontal->setParentItem(d->flickable); horizontal->setOrientation(Qt::Horizontal); + QQuickItemPrivate::get(horizontal)->updateOrAddGeometryChangeListener(d, QQuickItemPrivate::SizeChange); QObjectPrivate::connect(horizontal, &QQuickScrollBar::positionChanged, d, &QQuickScrollBarAttachedPrivate::scrollHorizontal); QObjectPrivate::connect(d->flickable, &QQuickFlickable::movingHorizontallyChanged, d, &QQuickScrollBarAttachedPrivate::activateHorizontal); @@ -483,6 +493,7 @@ void QQuickScrollBarAttached::setVertical(QQuickScrollBar *vertical) Q_D(QQuickScrollBarAttached); if (d->vertical != vertical) { if (d->vertical) { + QQuickItemPrivate::get(d->vertical)->removeItemChangeListener(d, QQuickItemPrivate::Geometry); QObjectPrivate::disconnect(d->vertical, &QQuickScrollBar::positionChanged, d, &QQuickScrollBarAttachedPrivate::scrollVertical); QObjectPrivate::disconnect(d->flickable, &QQuickFlickable::movingVerticallyChanged, d, &QQuickScrollBarAttachedPrivate::activateVertical); @@ -499,6 +510,7 @@ void QQuickScrollBarAttached::setVertical(QQuickScrollBar *vertical) vertical->setParentItem(d->flickable); vertical->setOrientation(Qt::Vertical); + QQuickItemPrivate::get(vertical)->updateOrAddGeometryChangeListener(d, QQuickItemPrivate::SizeChange); QObjectPrivate::connect(vertical, &QQuickScrollBar::positionChanged, d, &QQuickScrollBarAttachedPrivate::scrollVertical); QObjectPrivate::connect(d->flickable, &QQuickFlickable::movingVerticallyChanged, d, &QQuickScrollBarAttachedPrivate::activateVertical); diff --git a/src/templates/qquickscrollbar_p.h b/src/templates/qquickscrollbar_p.h index 6171d26e..b944f92a 100644 --- a/src/templates/qquickscrollbar_p.h +++ b/src/templates/qquickscrollbar_p.h @@ -115,8 +115,6 @@ private: Q_DECLARE_PRIVATE(QQuickScrollBar) }; -Q_DECLARE_TYPEINFO(QQuickScrollBar, Q_COMPLEX_TYPE); - class QQuickScrollBarAttachedPrivate; class Q_LABSTEMPLATES_EXPORT QQuickScrollBarAttached : public QObject @@ -127,6 +125,7 @@ class Q_LABSTEMPLATES_EXPORT QQuickScrollBarAttached : public QObject public: explicit QQuickScrollBarAttached(QQuickFlickable *flickable); + ~QQuickScrollBarAttached(); QQuickScrollBar *horizontal() const; void setHorizontal(QQuickScrollBar *horizontal); @@ -143,10 +142,9 @@ private: Q_DECLARE_PRIVATE(QQuickScrollBarAttached) }; -Q_DECLARE_TYPEINFO(QQuickScrollBarAttached, Q_COMPLEX_TYPE); - QT_END_NAMESPACE +QML_DECLARE_TYPE(QQuickScrollBar) QML_DECLARE_TYPEINFO(QQuickScrollBar, QML_HAS_ATTACHED_PROPERTIES) #endif // QQUICKSCROLLBAR_P_H diff --git a/src/templates/qquickscrollindicator.cpp b/src/templates/qquickscrollindicator.cpp index 94b47e4d..b041e2ab 100644 --- a/src/templates/qquickscrollindicator.cpp +++ b/src/templates/qquickscrollindicator.cpp @@ -268,12 +268,11 @@ void QQuickScrollIndicatorAttachedPrivate::itemGeometryChanged(QQuickItem *item, { Q_UNUSED(item); Q_UNUSED(newGeometry); - Q_ASSERT(item == flickable); - if (horizontal) { + if (horizontal && horizontal->height() > 0) { bool move = qFuzzyIsNull(horizontal->y()) || qFuzzyCompare(horizontal->y(), oldGeometry.height() - horizontal->height()); layoutHorizontal(move); } - if (vertical) { + if (vertical && vertical->width() > 0) { bool move = qFuzzyIsNull(vertical->x()) || qFuzzyCompare(vertical->x(), oldGeometry.width() - vertical->width()); layoutVertical(move); } @@ -284,7 +283,16 @@ QQuickScrollIndicatorAttached::QQuickScrollIndicatorAttached(QQuickFlickable *fl { Q_D(QQuickScrollIndicatorAttached); QQuickItemPrivate *p = QQuickItemPrivate::get(flickable); - p->addItemChangeListener(d, QQuickItemPrivate::Geometry); + p->updateOrAddGeometryChangeListener(d, QQuickItemPrivate::SizeChange); +} + +QQuickScrollIndicatorAttached::~QQuickScrollIndicatorAttached() +{ + Q_D(QQuickScrollIndicatorAttached); + if (d->horizontal) + QQuickItemPrivate::get(d->horizontal)->removeItemChangeListener(d, QQuickItemPrivate::Geometry); + if (d->vertical) + QQuickItemPrivate::get(d->vertical)->removeItemChangeListener(d, QQuickItemPrivate::Geometry); } /*! @@ -310,6 +318,7 @@ void QQuickScrollIndicatorAttached::setHorizontal(QQuickScrollIndicator *horizon Q_D(QQuickScrollIndicatorAttached); if (d->horizontal != horizontal) { if (d->horizontal) { + QQuickItemPrivate::get(d->horizontal)->removeItemChangeListener(d, QQuickItemPrivate::Geometry); QObjectPrivate::disconnect(d->flickable, &QQuickFlickable::movingHorizontallyChanged, d, &QQuickScrollIndicatorAttachedPrivate::activateHorizontal); // TODO: export QQuickFlickableVisibleArea @@ -325,6 +334,7 @@ void QQuickScrollIndicatorAttached::setHorizontal(QQuickScrollIndicator *horizon horizontal->setParentItem(d->flickable); horizontal->setOrientation(Qt::Horizontal); + QQuickItemPrivate::get(horizontal)->updateOrAddGeometryChangeListener(d, QQuickItemPrivate::SizeChange); QObjectPrivate::connect(d->flickable, &QQuickFlickable::movingHorizontallyChanged, d, &QQuickScrollIndicatorAttachedPrivate::activateHorizontal); // TODO: export QQuickFlickableVisibleArea @@ -363,6 +373,7 @@ void QQuickScrollIndicatorAttached::setVertical(QQuickScrollIndicator *vertical) Q_D(QQuickScrollIndicatorAttached); if (d->vertical != vertical) { if (d->vertical) { + QQuickItemPrivate::get(d->vertical)->removeItemChangeListener(d, QQuickItemPrivate::Geometry); QObjectPrivate::disconnect(d->flickable, &QQuickFlickable::movingVerticallyChanged, d, &QQuickScrollIndicatorAttachedPrivate::activateVertical); // TODO: export QQuickFlickableVisibleArea @@ -378,6 +389,7 @@ void QQuickScrollIndicatorAttached::setVertical(QQuickScrollIndicator *vertical) vertical->setParentItem(d->flickable); vertical->setOrientation(Qt::Vertical); + QQuickItemPrivate::get(vertical)->updateOrAddGeometryChangeListener(d, QQuickItemPrivate::SizeChange); QObjectPrivate::connect(d->flickable, &QQuickFlickable::movingVerticallyChanged, d, &QQuickScrollIndicatorAttachedPrivate::activateVertical); // TODO: export QQuickFlickableVisibleArea diff --git a/src/templates/qquickscrollindicator_p.h b/src/templates/qquickscrollindicator_p.h index e67118b4..1f5f07b7 100644 --- a/src/templates/qquickscrollindicator_p.h +++ b/src/templates/qquickscrollindicator_p.h @@ -103,8 +103,6 @@ private: Q_DECLARE_PRIVATE(QQuickScrollIndicator) }; -Q_DECLARE_TYPEINFO(QQuickScrollIndicator, Q_COMPLEX_TYPE); - class QQuickScrollIndicatorAttachedPrivate; class Q_LABSTEMPLATES_EXPORT QQuickScrollIndicatorAttached : public QObject @@ -115,6 +113,7 @@ class Q_LABSTEMPLATES_EXPORT QQuickScrollIndicatorAttached : public QObject public: explicit QQuickScrollIndicatorAttached(QQuickFlickable *flickable); + ~QQuickScrollIndicatorAttached(); QQuickScrollIndicator *horizontal() const; void setHorizontal(QQuickScrollIndicator *horizontal); @@ -131,10 +130,9 @@ private: Q_DECLARE_PRIVATE(QQuickScrollIndicatorAttached) }; -Q_DECLARE_TYPEINFO(QQuickScrollIndicatorAttached, Q_COMPLEX_TYPE); - QT_END_NAMESPACE +QML_DECLARE_TYPE(QQuickScrollIndicator) QML_DECLARE_TYPEINFO(QQuickScrollIndicator, QML_HAS_ATTACHED_PROPERTIES) #endif // QQUICKSCROLLINDICATOR_P_H diff --git a/src/templates/qquickslider.cpp b/src/templates/qquickslider.cpp index b77de9d3..bdb18ad9 100644 --- a/src/templates/qquickslider.cpp +++ b/src/templates/qquickslider.cpp @@ -138,7 +138,7 @@ qreal QQuickSliderPrivate::positionAt(const QPoint &point) const void QQuickSliderPrivate::setPosition(qreal pos) { Q_Q(QQuickSlider); - pos = qBound(0.0, pos, 1.0); + pos = qBound<qreal>(0.0, pos, 1.0); if (!qFuzzyCompare(position, pos)) { position = pos; emit q->positionChanged(); diff --git a/src/templates/qquickslider_p.h b/src/templates/qquickslider_p.h index 02d26538..663ad684 100644 --- a/src/templates/qquickslider_p.h +++ b/src/templates/qquickslider_p.h @@ -146,8 +146,8 @@ private: Q_DECLARE_PRIVATE(QQuickSlider) }; -Q_DECLARE_TYPEINFO(QQuickSlider, Q_COMPLEX_TYPE); - QT_END_NAMESPACE +QML_DECLARE_TYPE(QQuickSlider) + #endif // QQUICKSLIDER_P_H diff --git a/src/templates/qquickspinbox.cpp b/src/templates/qquickspinbox.cpp index 9e0bd723..13770e46 100644 --- a/src/templates/qquickspinbox.cpp +++ b/src/templates/qquickspinbox.cpp @@ -113,7 +113,6 @@ public: int repeatTimer; QQuickSpinButton *up; QQuickSpinButton *down; - QLocale locale; QValidator *validator; QJSValue textFromValue; QJSValue valueFromText; @@ -170,19 +169,19 @@ void QQuickSpinBoxPrivate::stopPressRepeat() } } -bool QQuickSpinBoxPrivate::handleMousePressEvent(QQuickItem *child, QMouseEvent *) +bool QQuickSpinBoxPrivate::handleMousePressEvent(QQuickItem *child, QMouseEvent *event) { Q_Q(QQuickSpinBox); QQuickItem *ui = up->indicator(); QQuickItem *di = down->indicator(); - up->setPressed(child == ui); - down->setPressed(child == di); + up->setPressed(ui && ui->contains(ui->mapFromItem(child, event->pos()))); + down->setPressed(di && di->contains(di->mapFromItem(child, event->pos()))); bool pressed = up->isPressed() || down->isPressed(); q->setAccessibleProperty("pressed", pressed); if (pressed) startRepeatDelay(); - return child == ui || child == di; + return up->isPressed() || down->isPressed(); } bool QQuickSpinBoxPrivate::handleMouseMoveEvent(QQuickItem *child, QMouseEvent *event) @@ -190,13 +189,13 @@ bool QQuickSpinBoxPrivate::handleMouseMoveEvent(QQuickItem *child, QMouseEvent * Q_Q(QQuickSpinBox); QQuickItem *ui = up->indicator(); QQuickItem *di = down->indicator(); - up->setPressed(child == ui && ui->contains(event->pos())); - down->setPressed(child == di && di->contains(event->pos())); + up->setPressed(ui && ui->contains(ui->mapFromItem(child, event->pos()))); + down->setPressed(di && di->contains(di->mapFromItem(child, event->pos()))); bool pressed = up->isPressed() || down->isPressed(); q->setAccessibleProperty("pressed", pressed); stopPressRepeat(); - return child == ui || child == di; + return up->isPressed() || down->isPressed(); } bool QQuickSpinBoxPrivate::handleMouseReleaseEvent(QQuickItem *child, QMouseEvent *event) @@ -204,32 +203,31 @@ bool QQuickSpinBoxPrivate::handleMouseReleaseEvent(QQuickItem *child, QMouseEven Q_Q(QQuickSpinBox); QQuickItem *ui = up->indicator(); QQuickItem *di = down->indicator(); - if (child == ui) { + bool wasPressed = up->isPressed() || down->isPressed(); + if (up->isPressed()) { up->setPressed(false); - if (repeatTimer <= 0 && ui->contains(event->pos())) + if (repeatTimer <= 0 && ui && ui->contains(ui->mapFromItem(child, event->pos()))) q->increase(); - } else if (child == di) { + } else if (down->isPressed()) { down->setPressed(false); - if (repeatTimer <= 0 && di->contains(event->pos())) + if (repeatTimer <= 0 && di && di->contains(di->mapFromItem(child, event->pos()))) q->decrease(); } q->setAccessibleProperty("pressed", false); stopPressRepeat(); - return child == ui || child == di; + return wasPressed; } -bool QQuickSpinBoxPrivate::handleMouseUngrabEvent(QQuickItem *child) +bool QQuickSpinBoxPrivate::handleMouseUngrabEvent(QQuickItem *) { Q_Q(QQuickSpinBox); - QQuickItem *ui = up->indicator(); - QQuickItem *di = down->indicator(); up->setPressed(false); down->setPressed(false); q->setAccessibleProperty("pressed", false); stopPressRepeat(); - return child == ui || child == di; + return false; } QQuickSpinBox::QQuickSpinBox(QQuickItem *parent) : @@ -241,6 +239,7 @@ QQuickSpinBox::QQuickSpinBox(QQuickItem *parent) : setFlag(ItemIsFocusScope); setFiltersChildMouseEvents(true); + setAcceptedMouseButtons(Qt::LeftButton); } /*! @@ -337,26 +336,6 @@ void QQuickSpinBox::setStepSize(int step) } /*! - \qmlproperty Locale Qt.labs.controls::SpinBox::locale - - This property holds the locale that is used to format the value. -*/ -QLocale QQuickSpinBox::locale() const -{ - Q_D(const QQuickSpinBox); - return d->locale; -} - -void QQuickSpinBox::setLocale(const QLocale &locale) -{ - Q_D(QQuickSpinBox); - if (d->locale != locale) { - d->locale = locale; - emit localeChanged(); - } -} - -/*! \qmlproperty Validator Qt.labs.controls::SpinBox::validator This property holds the input text validator. By default, SpinBox uses @@ -364,7 +343,7 @@ void QQuickSpinBox::setLocale(const QLocale &locale) \snippet SpinBox.qml validator - \sa textFromValue, valueFromText, locale + \sa textFromValue, valueFromText, {Control::locale}{locale} */ QValidator *QQuickSpinBox::validator() const { @@ -398,7 +377,7 @@ void QQuickSpinBox::setValidator(QValidator *validator) textFromValue: function(value, locale) { return Number(value).toLocaleString(locale, 'f', 0); } \endcode - \sa valueFromText, validator, locale + \sa valueFromText, validator, {Control::locale}{locale} */ QJSValue QQuickSpinBox::textFromValue() const { @@ -434,7 +413,7 @@ void QQuickSpinBox::setTextFromValue(const QJSValue &callback) valueFromText: function(text, locale) { return Number.fromLocaleString(locale, text); } \endcode - \sa textFromValue, validator, locale + \sa textFromValue, validator, {Control::locale}{locale} */ QJSValue QQuickSpinBox::valueFromText() const { @@ -564,6 +543,34 @@ bool QQuickSpinBox::childMouseEventFilter(QQuickItem *child, QEvent *event) } } +void QQuickSpinBox::mousePressEvent(QMouseEvent *event) +{ + Q_D(QQuickSpinBox); + QQuickControl::mousePressEvent(event); + d->handleMousePressEvent(this, event); +} + +void QQuickSpinBox::mouseMoveEvent(QMouseEvent *event) +{ + Q_D(QQuickSpinBox); + QQuickControl::mouseMoveEvent(event); + d->handleMouseMoveEvent(this, event); +} + +void QQuickSpinBox::mouseReleaseEvent(QMouseEvent *event) +{ + Q_D(QQuickSpinBox); + QQuickControl::mouseReleaseEvent(event); + d->handleMouseReleaseEvent(this, event); +} + +void QQuickSpinBox::mouseUngrabEvent() +{ + Q_D(QQuickSpinBox); + QQuickControl::mouseUngrabEvent(); + d->handleMouseUngrabEvent(this); +} + void QQuickSpinBox::timerEvent(QTimerEvent *event) { Q_D(QQuickSpinBox); diff --git a/src/templates/qquickspinbox_p.h b/src/templates/qquickspinbox_p.h index 1ea7130d..0ad5e70d 100644 --- a/src/templates/qquickspinbox_p.h +++ b/src/templates/qquickspinbox_p.h @@ -65,7 +65,6 @@ class Q_LABSTEMPLATES_EXPORT QQuickSpinBox : public QQuickControl Q_PROPERTY(int to READ to WRITE setTo NOTIFY toChanged FINAL) Q_PROPERTY(int value READ value WRITE setValue NOTIFY valueChanged FINAL) Q_PROPERTY(int stepSize READ stepSize WRITE setStepSize NOTIFY stepSizeChanged FINAL) - Q_PROPERTY(QLocale locale READ locale WRITE setLocale NOTIFY localeChanged FINAL) Q_PROPERTY(QValidator *validator READ validator WRITE setValidator NOTIFY validatorChanged FINAL) Q_PROPERTY(QJSValue textFromValue READ textFromValue WRITE setTextFromValue NOTIFY textFromValueChanged FINAL) Q_PROPERTY(QJSValue valueFromText READ valueFromText WRITE setValueFromText NOTIFY valueFromTextChanged FINAL) @@ -87,9 +86,6 @@ public: int stepSize() const; void setStepSize(int step); - QLocale locale() const; - void setLocale(const QLocale &locale); - QValidator *validator() const; void setValidator(QValidator *validator); @@ -111,7 +107,6 @@ Q_SIGNALS: void toChanged(); void valueChanged(); void stepSizeChanged(); - void localeChanged(); void validatorChanged(); void textFromValueChanged(); void valueFromTextChanged(); @@ -120,6 +115,10 @@ protected: bool childMouseEventFilter(QQuickItem *child, QEvent *event) Q_DECL_OVERRIDE; void keyPressEvent(QKeyEvent *event) Q_DECL_OVERRIDE; void keyReleaseEvent(QKeyEvent *event) Q_DECL_OVERRIDE; + void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE; + void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE; + void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE; + void mouseUngrabEvent() Q_DECL_OVERRIDE; void timerEvent(QTimerEvent *event) Q_DECL_OVERRIDE; void componentComplete() Q_DECL_OVERRIDE; @@ -159,9 +158,8 @@ private: Q_DECLARE_PRIVATE(QQuickSpinButton) }; -Q_DECLARE_TYPEINFO(QQuickSpinBox, Q_COMPLEX_TYPE); -Q_DECLARE_TYPEINFO(QQuickSpinButton, Q_COMPLEX_TYPE); - QT_END_NAMESPACE +QML_DECLARE_TYPE(QQuickSpinBox) + #endif // QQUICKSPINBOX_P_H diff --git a/src/templates/qquickstackview.cpp b/src/templates/qquickstackview.cpp index 2dcae1a1..e127d79f 100644 --- a/src/templates/qquickstackview.cpp +++ b/src/templates/qquickstackview.cpp @@ -198,7 +198,7 @@ QT_BEGIN_NAMESPACE You can also get to an item in the stack using \l {get()}{get(index)}. \badcode - previousItem = stackView.get(myItem.Stack.index - 1)); + previousItem = stackView.get(myItem.StackView.index - 1)); \endcode \section1 Transitions @@ -636,7 +636,7 @@ void QQuickStackView::replace(QQmlV4Function *args) if (!d->elements.isEmpty()) exit = d->elements.pop(); - if (d->replaceElements(target, elements)) { + if (exit != target ? d->replaceElements(target, elements) : d->pushElements(elements)) { if (depth != d->elements.count()) emit depthChanged(); QQuickStackElement *enter = d->elements.top(); @@ -870,15 +870,10 @@ void QQuickStackView::geometryChanged(const QRectF &newGeometry, const QRectF &o Q_D(QQuickStackView); foreach (QQuickStackElement *element, d->elements) { if (element->item) { - QQuickItemPrivate *p = QQuickItemPrivate::get(element->item); - if (!p->widthValid) { + if (!element->widthValid) element->item->setWidth(newGeometry.width()); - p->widthValid = false; - } - if (!p->heightValid) { + if (!element->heightValid) element->item->setHeight(newGeometry.height()); - p->heightValid = false; - } } } } diff --git a/src/templates/qquickstackview_p.cpp b/src/templates/qquickstackview_p.cpp index 1a08d349..06c605d2 100644 --- a/src/templates/qquickstackview_p.cpp +++ b/src/templates/qquickstackview_p.cpp @@ -69,7 +69,7 @@ private: }; QQuickStackElement::QQuickStackElement() : QQuickItemViewTransitionableItem(Q_NULLPTR), - index(-1), init(false), removal(false), ownItem(false), ownComponent(false), + index(-1), init(false), removal(false), ownItem(false), ownComponent(false), widthValid(false), heightValid(false), context(Q_NULLPTR), component(Q_NULLPTR), incubator(Q_NULLPTR), view(Q_NULLPTR), status(QQuickStackView::Inactive) { @@ -139,16 +139,21 @@ bool QQuickStackElement::load(QQuickStackView *parent) delete incubator; incubator = new QQuickStackIncubator(this); component->create(*incubator, context); + if (component->isError()) + qWarning() << qPrintable(component->errorString().trimmed()); + } else { + initialize(); } - initialize(); return item; } void QQuickStackElement::incubate(QObject *object) { item = qmlobject_cast<QQuickItem *>(object); - if (item) + if (item) { QQmlEngine::setObjectOwnership(item, QQmlEngine::CppOwnership); + initialize(); + } } void QQuickStackElement::initialize() @@ -157,14 +162,10 @@ void QQuickStackElement::initialize() return; QQuickItemPrivate *p = QQuickItemPrivate::get(item); - if (!p->widthValid) { + if (!(widthValid = p->widthValid)) item->setWidth(view->width()); - p->widthValid = false; - } - if (!p->heightValid) { + if (!(heightValid = p->heightValid)) item->setHeight(view->height()); - p->heightValid = false; - } item->setParentItem(view); p->addItemChangeListener(this, QQuickItemPrivate::Destroyed); @@ -405,13 +406,13 @@ void QQuickStackViewPrivate::popTransition(QQuickStackElement *enter, QQuickStac } if (exit) { - if (immediate || !exit->prepareTransition(transitioner, viewBounds)) + if (immediate || !exit->item || !exit->prepareTransition(transitioner, viewBounds)) completeTransition(exit, transitioner->removeTransition); else exit->startTransition(transitioner); } if (enter) { - if (immediate || !enter->prepareTransition(transitioner, QRectF())) + if (immediate || !enter->item || !enter->prepareTransition(transitioner, QRectF())) completeTransition(enter, transitioner->removeDisplacedTransition); else enter->startTransition(transitioner); @@ -437,13 +438,13 @@ void QQuickStackViewPrivate::pushTransition(QQuickStackElement *enter, QQuickSta } if (enter) { - if (immediate || !enter->prepareTransition(transitioner, viewBounds)) + if (immediate || !enter->item || !enter->prepareTransition(transitioner, viewBounds)) completeTransition(enter, transitioner->addTransition); else enter->startTransition(transitioner); } if (exit) { - if (immediate || !exit->prepareTransition(transitioner, QRectF())) + if (immediate || !exit->item || !exit->prepareTransition(transitioner, QRectF())) completeTransition(exit, transitioner->addDisplacedTransition); else exit->startTransition(transitioner); @@ -470,13 +471,13 @@ void QQuickStackViewPrivate::replaceTransition(QQuickStackElement *enter, QQuick } if (exit) { - if (immediate || !exit->prepareTransition(transitioner, QRectF())) + if (immediate || !exit->item || !exit->prepareTransition(transitioner, QRectF())) completeTransition(exit, transitioner->moveDisplacedTransition); else exit->startTransition(transitioner); } if (enter) { - if (immediate || !enter->prepareTransition(transitioner, viewBounds)) + if (immediate || !enter->item || !enter->prepareTransition(transitioner, viewBounds)) completeTransition(enter, transitioner->moveTransition); else enter->startTransition(transitioner); diff --git a/src/templates/qquickstackview_p.h b/src/templates/qquickstackview_p.h index be73ea85..6b78b50a 100644 --- a/src/templates/qquickstackview_p.h +++ b/src/templates/qquickstackview_p.h @@ -154,8 +154,6 @@ private: Q_DECLARE_PRIVATE(QQuickStackView) }; -Q_DECLARE_TYPEINFO(QQuickStackView, Q_COMPLEX_TYPE); - class QQuickStackAttachedPrivate; class Q_LABSTEMPLATES_EXPORT QQuickStackAttached : public QObject @@ -183,11 +181,9 @@ private: Q_DECLARE_PRIVATE(QQuickStackAttached) }; -Q_DECLARE_TYPEINFO(QQuickStackAttached, Q_COMPLEX_TYPE); - QT_END_NAMESPACE -QML_DECLARE_TYPEINFO(QQuickStackView, QML_HAS_ATTACHED_PROPERTIES) QML_DECLARE_TYPE(QQuickStackView) +QML_DECLARE_TYPEINFO(QQuickStackView, QML_HAS_ATTACHED_PROPERTIES) #endif // QQUICKSTACKVIEW_P_H diff --git a/src/templates/qquickstackview_p_p.h b/src/templates/qquickstackview_p_p.h index 94919939..d14c6326 100644 --- a/src/templates/qquickstackview_p_p.h +++ b/src/templates/qquickstackview_p_p.h @@ -89,6 +89,8 @@ public: bool removal; bool ownItem; bool ownComponent; + bool widthValid; + bool heightValid; QQmlContext *context; QQmlComponent *component; QQmlIncubator *incubator; @@ -98,8 +100,6 @@ public: QV4::PersistentValue properties; }; -Q_DECLARE_TYPEINFO(QQuickStackElement, Q_COMPLEX_TYPE); - class QQuickStackViewPrivate : public QQuickControlPrivate, public QQuickItemViewTransitionChangeListener { Q_DECLARE_PUBLIC(QQuickStackView) @@ -157,8 +157,6 @@ public: QQuickStackElement *element; }; -Q_DECLARE_TYPEINFO(QQuickStackViewPrivate, Q_COMPLEX_TYPE); - QT_END_NAMESPACE #endif // QQUICKSTACKVIEW_P_P_H diff --git a/src/templates/qquickswipeview_p.h b/src/templates/qquickswipeview_p.h index a40c831e..bf733c7b 100644 --- a/src/templates/qquickswipeview_p.h +++ b/src/templates/qquickswipeview_p.h @@ -100,10 +100,9 @@ private: Q_DECLARE_PRIVATE(QQuickSwipeViewAttached) }; -Q_DECLARE_TYPEINFO(QQuickSwipeView, Q_COMPLEX_TYPE); - QT_END_NAMESPACE +QML_DECLARE_TYPE(QQuickSwipeView) QML_DECLARE_TYPEINFO(QQuickSwipeView, QML_HAS_ATTACHED_PROPERTIES) #endif // QQUICKSWIPEVIEW_P_H diff --git a/src/templates/qquickswitch.cpp b/src/templates/qquickswitch.cpp index 241deed9..a867ec70 100644 --- a/src/templates/qquickswitch.cpp +++ b/src/templates/qquickswitch.cpp @@ -185,7 +185,7 @@ qreal QQuickSwitch::position() const void QQuickSwitch::setPosition(qreal position) { Q_D(QQuickSwitch); - position = qBound(0.0, position, 1.0); + position = qBound<qreal>(0.0, position, 1.0); if (d->position != position) { d->position = position; emit positionChanged(); diff --git a/src/templates/qquickswitch_p.h b/src/templates/qquickswitch_p.h index 2670c863..94d0d601 100644 --- a/src/templates/qquickswitch_p.h +++ b/src/templates/qquickswitch_p.h @@ -83,8 +83,8 @@ private: Q_DECLARE_PRIVATE(QQuickSwitch) }; -Q_DECLARE_TYPEINFO(QQuickSwitch, Q_COMPLEX_TYPE); - QT_END_NAMESPACE +QML_DECLARE_TYPE(QQuickSwitch) + #endif // QQUICKSWITCH_P_H diff --git a/src/templates/qquicktabbar_p.h b/src/templates/qquicktabbar_p.h index a1f4ff54..7d6f674c 100644 --- a/src/templates/qquicktabbar_p.h +++ b/src/templates/qquicktabbar_p.h @@ -78,8 +78,8 @@ private: Q_DECLARE_PRIVATE(QQuickTabBar) }; -Q_DECLARE_TYPEINFO(QQuickTabBar, Q_COMPLEX_TYPE); - QT_END_NAMESPACE +QML_DECLARE_TYPE(QQuickTabBar) + #endif // QQUICKTABBAR_P_H diff --git a/src/templates/qquicktabbutton.cpp b/src/templates/qquicktabbutton.cpp index 07dc533c..00d4d8b4 100644 --- a/src/templates/qquicktabbutton.cpp +++ b/src/templates/qquicktabbutton.cpp @@ -67,7 +67,7 @@ QQuickTabButton::QQuickTabButton(QQuickItem *parent) : QFont QQuickTabButton::defaultFont() const { - return QQuickControlPrivate::themeFont(QPlatformTheme::DockWidgetTitleFont); // tmp + return QQuickControlPrivate::themeFont(QPlatformTheme::TabButtonFont); } #ifndef QT_NO_ACCESSIBILITY diff --git a/src/templates/qquicktabbutton_p.h b/src/templates/qquicktabbutton_p.h index 0170a2b0..c02a206f 100644 --- a/src/templates/qquicktabbutton_p.h +++ b/src/templates/qquicktabbutton_p.h @@ -67,8 +67,8 @@ protected: #endif }; -Q_DECLARE_TYPEINFO(QQuickTabButton, Q_COMPLEX_TYPE); - QT_END_NAMESPACE +QML_DECLARE_TYPE(QQuickTabButton) + #endif // QQUICKTABBUTTON_P_H diff --git a/src/templates/qquicktextarea.cpp b/src/templates/qquicktextarea.cpp index c78da815..fbc14573 100644 --- a/src/templates/qquicktextarea.cpp +++ b/src/templates/qquicktextarea.cpp @@ -70,8 +70,16 @@ QT_BEGIN_NAMESPACE \sa TextField, {Customizing TextArea}, {Input Controls} */ +/*! + \qmlsignal Qt.labs.controls::TextArea::pressAndHold(MouseEvent mouse) + + This signal is emitted when there is a long press (the delay depends on the platform plugin). + The \l {MouseEvent}{mouse} parameter provides information about the press, including the x and y + position of the press, and which button is pressed. +*/ + QQuickTextAreaPrivate::QQuickTextAreaPrivate() - : background(Q_NULLPTR), accessibleAttached(Q_NULLPTR) + : background(Q_NULLPTR), focusReason(Qt::OtherFocusReason), accessibleAttached(Q_NULLPTR) { #ifndef QT_NO_ACCESSIBILITY QAccessible::installActivationObserver(this); @@ -277,6 +285,40 @@ void QQuickTextArea::setPlaceholderText(const QString &text) } } +/*! + \qmlproperty enumeration Qt.labs.controls::TextArea::focusReason + + This property holds the reason of the last focus change. + + \note This property does not indicate whether the control has \l {Item::activeFocus} + {active focus}, but the reason why the control either gained or lost focus. + + \value Qt.MouseFocusReason A mouse action occurred. + \value Qt.TabFocusReason The Tab key was pressed. + \value Qt.BacktabFocusReason A Backtab occurred. The input for this may include the Shift or Control keys; e.g. Shift+Tab. + \value Qt.ActiveWindowFocusReason The window system made this window either active or inactive. + \value Qt.PopupFocusReason The application opened/closed a pop-up that grabbed/released the keyboard focus. + \value Qt.ShortcutFocusReason The user typed a label's buddy shortcut + \value Qt.MenuBarFocusReason The menu bar took focus. + \value Qt.OtherFocusReason Another reason, usually application-specific. + + \sa Item::activeFocus +*/ +Qt::FocusReason QQuickTextArea::focusReason() const +{ + Q_D(const QQuickTextArea); + return d->focusReason; +} + +void QQuickTextArea::setFocusReason(Qt::FocusReason reason) +{ + Q_D(QQuickTextArea); + if (d->focusReason != reason) { + d->focusReason = reason; + emit focusReasonChanged(); + } +} + void QQuickTextArea::classBegin() { Q_D(QQuickTextArea); @@ -315,6 +357,18 @@ QSGNode *QQuickTextArea::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData * return clipNode; } +void QQuickTextArea::focusInEvent(QFocusEvent *event) +{ + QQuickTextEdit::focusInEvent(event); + setFocusReason(event->reason()); +} + +void QQuickTextArea::focusOutEvent(QFocusEvent *event) +{ + QQuickTextEdit::focusOutEvent(event); + setFocusReason(event->reason()); +} + void QQuickTextArea::mousePressEvent(QMouseEvent *event) { Q_D(QQuickTextArea); diff --git a/src/templates/qquicktextarea_p.h b/src/templates/qquicktextarea_p.h index d8326f66..acf67359 100644 --- a/src/templates/qquicktextarea_p.h +++ b/src/templates/qquicktextarea_p.h @@ -65,6 +65,7 @@ class Q_LABSTEMPLATES_EXPORT QQuickTextArea : public QQuickTextEdit Q_PROPERTY(qreal implicitHeight READ implicitHeight WRITE setImplicitHeight NOTIFY implicitHeightChanged FINAL) Q_PROPERTY(QQuickItem *background READ background WRITE setBackground NOTIFY backgroundChanged FINAL) Q_PROPERTY(QString placeholderText READ placeholderText WRITE setPlaceholderText NOTIFY placeholderTextChanged FINAL) + Q_PROPERTY(Qt::FocusReason focusReason READ focusReason WRITE setFocusReason NOTIFY focusReasonChanged FINAL) public: explicit QQuickTextArea(QQuickItem *parent = Q_NULLPTR); @@ -79,12 +80,16 @@ public: QString placeholderText() const; void setPlaceholderText(const QString &text); + Qt::FocusReason focusReason() const; + void setFocusReason(Qt::FocusReason reason); + Q_SIGNALS: void fontChanged(); void implicitWidthChanged(); void implicitHeightChanged(); void backgroundChanged(); void placeholderTextChanged(); + void focusReasonChanged(); void pressAndHold(QQuickMouseEvent *event); protected: @@ -93,6 +98,9 @@ protected: void itemChange(ItemChange change, const ItemChangeData &value) Q_DECL_OVERRIDE; void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) Q_DECL_OVERRIDE; QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data) Q_DECL_OVERRIDE; + + void focusInEvent(QFocusEvent *event) Q_DECL_OVERRIDE; + void focusOutEvent(QFocusEvent *event) Q_DECL_OVERRIDE; void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE; void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE; void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE; @@ -103,8 +111,8 @@ private: Q_DECLARE_PRIVATE(QQuickTextArea) }; -Q_DECLARE_TYPEINFO(QQuickTextArea, Q_COMPLEX_TYPE); - QT_END_NAMESPACE +QML_DECLARE_TYPE(QQuickTextArea) + #endif // QQUICKTEXTAREA_P_H diff --git a/src/templates/qquicktextarea_p_p.h b/src/templates/qquicktextarea_p_p.h index 2960f7bf..2a16e5cc 100644 --- a/src/templates/qquicktextarea_p_p.h +++ b/src/templates/qquicktextarea_p_p.h @@ -93,12 +93,11 @@ public: QQuickItem *background; QString placeholder; + Qt::FocusReason focusReason; QQuickPressAndHoldHelper pressAndHoldHelper; QQuickAccessibleAttached *accessibleAttached; }; -Q_DECLARE_TYPEINFO(QQuickTextAreaPrivate, Q_COMPLEX_TYPE); - QT_END_NAMESPACE #endif // QQUICKTEXTAREA_P_P_H diff --git a/src/templates/qquicktextfield.cpp b/src/templates/qquicktextfield.cpp index 50d49c11..ec8c24ab 100644 --- a/src/templates/qquicktextfield.cpp +++ b/src/templates/qquicktextfield.cpp @@ -90,6 +90,7 @@ QT_BEGIN_NAMESPACE QQuickTextFieldPrivate::QQuickTextFieldPrivate() : background(Q_NULLPTR) + , focusReason(Qt::OtherFocusReason) , accessibleAttached(Q_NULLPTR) { #ifndef QT_NO_ACCESSIBILITY @@ -309,6 +310,40 @@ void QQuickTextField::setPlaceholderText(const QString &text) } } +/*! + \qmlproperty enumeration Qt.labs.controls::TextField::focusReason + + This property holds the reason of the last focus change. + + \note This property does not indicate whether the control has \l {Item::activeFocus} + {active focus}, but the reason why the control either gained or lost focus. + + \value Qt.MouseFocusReason A mouse action occurred. + \value Qt.TabFocusReason The Tab key was pressed. + \value Qt.BacktabFocusReason A Backtab occurred. The input for this may include the Shift or Control keys; e.g. Shift+Tab. + \value Qt.ActiveWindowFocusReason The window system made this window either active or inactive. + \value Qt.PopupFocusReason The application opened/closed a pop-up that grabbed/released the keyboard focus. + \value Qt.ShortcutFocusReason The user typed a label's buddy shortcut + \value Qt.MenuBarFocusReason The menu bar took focus. + \value Qt.OtherFocusReason Another reason, usually application-specific. + + \sa Item::activeFocus +*/ +Qt::FocusReason QQuickTextField::focusReason() const +{ + Q_D(const QQuickTextField); + return d->focusReason; +} + +void QQuickTextField::setFocusReason(Qt::FocusReason reason) +{ + Q_D(QQuickTextField); + if (d->focusReason != reason) { + d->focusReason = reason; + emit focusReasonChanged(); + } +} + void QQuickTextField::classBegin() { Q_D(QQuickTextField); @@ -347,6 +382,18 @@ QSGNode *QQuickTextField::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData return clipNode; } +void QQuickTextField::focusInEvent(QFocusEvent *event) +{ + QQuickTextInput::focusInEvent(event); + setFocusReason(event->reason()); +} + +void QQuickTextField::focusOutEvent(QFocusEvent *event) +{ + QQuickTextInput::focusOutEvent(event); + setFocusReason(event->reason()); +} + void QQuickTextField::mousePressEvent(QMouseEvent *event) { Q_D(QQuickTextField); diff --git a/src/templates/qquicktextfield_p.h b/src/templates/qquicktextfield_p.h index d8b20225..23658cc6 100644 --- a/src/templates/qquicktextfield_p.h +++ b/src/templates/qquicktextfield_p.h @@ -65,6 +65,7 @@ class Q_LABSTEMPLATES_EXPORT QQuickTextField : public QQuickTextInput Q_PROPERTY(qreal implicitHeight READ implicitHeight WRITE setImplicitHeight NOTIFY implicitHeightChanged FINAL) Q_PROPERTY(QQuickItem *background READ background WRITE setBackground NOTIFY backgroundChanged FINAL) Q_PROPERTY(QString placeholderText READ placeholderText WRITE setPlaceholderText NOTIFY placeholderTextChanged FINAL) + Q_PROPERTY(Qt::FocusReason focusReason READ focusReason WRITE setFocusReason NOTIFY focusReasonChanged FINAL) public: explicit QQuickTextField(QQuickItem *parent = Q_NULLPTR); @@ -79,12 +80,16 @@ public: QString placeholderText() const; void setPlaceholderText(const QString &text); + Qt::FocusReason focusReason() const; + void setFocusReason(Qt::FocusReason reason); + Q_SIGNALS: void fontChanged(); void implicitWidthChanged(); void implicitHeightChanged(); void backgroundChanged(); void placeholderTextChanged(); + void focusReasonChanged(); void pressAndHold(QQuickMouseEvent *mouse); protected: @@ -93,6 +98,9 @@ protected: void itemChange(ItemChange change, const ItemChangeData &value) Q_DECL_OVERRIDE; void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) Q_DECL_OVERRIDE; QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data) Q_DECL_OVERRIDE; + + void focusInEvent(QFocusEvent *event) Q_DECL_OVERRIDE; + void focusOutEvent(QFocusEvent *event) Q_DECL_OVERRIDE; void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE; void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE; void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE; @@ -103,8 +111,8 @@ private: Q_DECLARE_PRIVATE(QQuickTextField) }; -Q_DECLARE_TYPEINFO(QQuickTextField, Q_COMPLEX_TYPE); - QT_END_NAMESPACE +QML_DECLARE_TYPE(QQuickTextField) + #endif // QQUICKTEXTFIELD_P_H diff --git a/src/templates/qquicktextfield_p_p.h b/src/templates/qquicktextfield_p_p.h index 459e0847..29b01f15 100644 --- a/src/templates/qquicktextfield_p_p.h +++ b/src/templates/qquicktextfield_p_p.h @@ -94,12 +94,11 @@ public: QQuickItem *background; QString placeholder; + Qt::FocusReason focusReason; QQuickPressAndHoldHelper pressAndHoldHelper; QQuickAccessibleAttached *accessibleAttached; }; -Q_DECLARE_TYPEINFO(QQuickTextFieldPrivate, Q_COMPLEX_TYPE); - QT_END_NAMESPACE #endif // QQUICKTEXTFIELD_P_P_H diff --git a/src/templates/qquicktoolbar_p.h b/src/templates/qquicktoolbar_p.h index 065f1f71..501f74c7 100644 --- a/src/templates/qquicktoolbar_p.h +++ b/src/templates/qquicktoolbar_p.h @@ -65,8 +65,8 @@ protected: #endif }; -Q_DECLARE_TYPEINFO(QQuickToolBar, Q_COMPLEX_TYPE); - QT_END_NAMESPACE +QML_DECLARE_TYPE(QQuickToolBar) + #endif // QQUICKTOOLBAR_P_H diff --git a/src/templates/qquicktoolbutton_p.h b/src/templates/qquicktoolbutton_p.h index d3bb4fe7..25f2134d 100644 --- a/src/templates/qquicktoolbutton_p.h +++ b/src/templates/qquicktoolbutton_p.h @@ -63,8 +63,8 @@ protected: QFont defaultFont() const Q_DECL_OVERRIDE; }; -Q_DECLARE_TYPEINFO(QQuickToolButton, Q_COMPLEX_TYPE); - QT_END_NAMESPACE +QML_DECLARE_TYPE(QQuickToolButton) + #endif // QQUICKTOOLBUTTON_P_H diff --git a/src/templates/qquicktumbler_p.h b/src/templates/qquicktumbler_p.h index 079cdbb3..ad57acbb 100644 --- a/src/templates/qquicktumbler_p.h +++ b/src/templates/qquicktumbler_p.h @@ -110,8 +110,6 @@ private: Q_PRIVATE_SLOT(d_func(), void _q_updateItemHeights()) }; -Q_DECLARE_TYPEINFO(QQuickTumbler, Q_COMPLEX_TYPE); - class QQuickTumblerAttachedPrivate; class Q_LABSTEMPLATES_EXPORT QQuickTumblerAttached : public QObject @@ -137,10 +135,9 @@ private: Q_PRIVATE_SLOT(d_func(), void _q_calculateDisplacement()) }; -Q_DECLARE_TYPEINFO(QQuickTumblerAttached, Q_COMPLEX_TYPE); - QT_END_NAMESPACE +QML_DECLARE_TYPE(QQuickTumbler) QML_DECLARE_TYPEINFO(QQuickTumbler, QML_HAS_ATTACHED_PROPERTIES) #endif // QQUICKTUMBLER_H diff --git a/src/templates/templates.pri b/src/templates/templates.pri index 22fad255..1ae46e85 100644 --- a/src/templates/templates.pri +++ b/src/templates/templates.pri @@ -8,6 +8,7 @@ HEADERS += \ $$PWD/qquickbutton_p.h \ $$PWD/qquickbuttongroup_p.h \ $$PWD/qquickcheckbox_p.h \ + $$PWD/qquickcombobox_p.h \ $$PWD/qquickcontainer_p.h \ $$PWD/qquickcontainer_p_p.h \ $$PWD/qquickcontrol_p.h \ @@ -25,8 +26,10 @@ HEADERS += \ $$PWD/qquickmenuitem_p.h \ $$PWD/qquickoverlay_p.h \ $$PWD/qquickpageindicator_p.h \ - $$PWD/qquickpanel_p.h \ - $$PWD/qquickpanel_p_p.h \ + $$PWD/qquickpane_p.h \ + $$PWD/qquickpane_p_p.h \ + $$PWD/qquickpopup_p.h \ + $$PWD/qquickpopup_p_p.h \ $$PWD/qquickpressandholdhelper_p.h \ $$PWD/qquickprogressbar_p.h \ $$PWD/qquickradiobutton_p.h \ @@ -56,6 +59,7 @@ SOURCES += \ $$PWD/qquickbutton.cpp \ $$PWD/qquickbuttongroup.cpp \ $$PWD/qquickcheckbox.cpp \ + $$PWD/qquickcombobox.cpp \ $$PWD/qquickcontainer.cpp \ $$PWD/qquickcontrol.cpp \ $$PWD/qquickdial.cpp \ @@ -68,7 +72,8 @@ SOURCES += \ $$PWD/qquickmenuitem.cpp \ $$PWD/qquickoverlay.cpp \ $$PWD/qquickpageindicator.cpp \ - $$PWD/qquickpanel.cpp \ + $$PWD/qquickpane.cpp \ + $$PWD/qquickpopup.cpp \ $$PWD/qquickpressandholdhelper.cpp \ $$PWD/qquickprogressbar.cpp \ $$PWD/qquickradiobutton.cpp \ |