diff options
author | Liang Qi <liang.qi@theqtcompany.com> | 2015-12-02 19:32:35 +0100 |
---|---|---|
committer | Liang Qi <liang.qi@theqtcompany.com> | 2015-12-02 19:32:35 +0100 |
commit | 1c7daa22ebfb4682e18c8afb911e8c784127ade3 (patch) | |
tree | 56633d70f422fde85741382ab4fde847de78c7e7 | |
parent | 0b11c7f5f4bd913abbc1362e71a2b68dc29a8ffe (diff) | |
parent | cd4467753105e69b967d3aad8e6d890609dc830b (diff) |
Merge remote-tracking branch 'origin/5.6' into dev
Change-Id: Ia451c8896fd5068bd64a5b12f1b8358afbe4758a
326 files changed, 15923 insertions, 5696 deletions
@@ -5,22 +5,20 @@ /lib /mkspecs -/examples/labs/calendar/calendar -/examples/labs/controls/mirroring/mirroring -/examples/labs/controls/theme/theme -/examples/labs/controls/tabs/tabs -/examples/labs/controls/drawer/drawer - /tests/auto/accessibility/tst_accessibility /tests/auto/activeFocusOnTab/tst_activeFocusOnTab /tests/auto/applicationwindow/tst_applicationwindow /tests/auto/calendar/tst_calendar /tests/auto/controls/tst_controls +/tests/auto/material/tst_material +/tests/auto/pressandhold/tst_pressandhold /tests/auto/sanity/tst_sanity /tests/auto/snippets/tst_snippets -/tests/auto/theme/tst_theme +/tests/auto/styles/tst_styles +/tests/auto/universal/tst_universal /tests/benchmarks/creationtime/tst_creationtime /tests/benchmarks/objectcount/tst_objectcount +/tests/manual/fonts/fonts /tests/manual/gifs/tst_gifs /tests/manual/testbench/testbench @@ -91,3 +89,4 @@ android-build app_process qtc-debugging-helper android-*.so-deployment-settings.json +*.directory diff --git a/examples/examples.pro b/examples/examples.pro deleted file mode 100644 index 29810159..00000000 --- a/examples/examples.pro +++ /dev/null @@ -1,3 +0,0 @@ -TEMPLATE = subdirs -SUBDIRS += \ - labs diff --git a/examples/labs/calendar/DateTimePicker.qml b/examples/labs/calendar/DateTimePicker.qml deleted file mode 100644 index 091cf267..00000000 --- a/examples/labs/calendar/DateTimePicker.qml +++ /dev/null @@ -1,175 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.6 -import Qt.labs.calendar 1.0 -import Qt.labs.controls 1.0 - -Item { - id: dateTimePicker - enabled: dateToShow.getFullYear() >= fromYear || dateToShow.getFullYear() <= toYear - implicitWidth: row.implicitWidth - implicitHeight: row.implicitHeight - - readonly property var days: [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] - - readonly property int fromYear: 2000 - readonly property int toYear: 2020 - - readonly property alias chosenDate: dateTimePicker.__date - property var __date: new Date( - fromYear + yearTumbler.currentIndex, - monthTumbler.currentIndex, - dayTumbler.currentIndex + 1, - hoursTumbler.currentIndex + (amPmTumbler.currentIndex == 0 ? 0 : 12), - minutesTumbler.currentIndex); - - property date dateToShow: new Date() - onDateToShowChanged: { - yearTumbler.currentIndex = dateToShow.getFullYear() - fromYear; - monthTumbler.currentIndex = dateToShow.getMonth(); - dayTumbler.currentIndex = dateToShow.getDate() - 1; - } - - FontMetrics { - id: fontMetrics - } - - Row { - id: row - spacing: 2 - - Frame { - padding: 0 - - Row { - Tumbler { - id: dayTumbler - - delegate: TumblerDelegate { - text: modelData - font.pixelSize: fontMetrics.font.pixelSize * (Tumbler.tumbler.activeFocus ? 2 : 1.25) - } - - function updateModel() { - var previousIndex = dayTumbler.currentIndex; - var array = []; - var newDays = dateTimePicker.days[monthTumbler.currentIndex]; - for (var i = 0; i < newDays; ++i) { - array.push(i + 1); - } - dayTumbler.model = array; - dayTumbler.currentIndex = Math.min(newDays - 1, previousIndex); - } - - Component.onCompleted: updateModel() - } - Tumbler { - id: monthTumbler - model: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"] - delegate: TumblerDelegate { - text: modelData - font.pixelSize: fontMetrics.font.pixelSize * (Tumbler.tumbler.activeFocus ? 2 : 1.25) - } - onCurrentIndexChanged: dayTumbler.updateModel() - } - Tumbler { - id: yearTumbler - width: 80 - model: { - var years = []; - for (var i = fromYear; i <= toYear; ++i) { - years.push(i); - } - return years; - } - delegate: TumblerDelegate { - text: modelData - font.pixelSize: fontMetrics.font.pixelSize * (Tumbler.tumbler.activeFocus ? 2 : 1.25) - } - } - } - } - - Frame { - padding: 0 - - Row { - Tumbler { - id: hoursTumbler - model: 12 - delegate: TumblerDelegate { - text: modelData.toString().length < 2 ? "0" + modelData : modelData - font.pixelSize: fontMetrics.font.pixelSize * (Tumbler.tumbler.activeFocus ? 2 : 1.25) - } - } - - Tumbler { - id: minutesTumbler - model: 60 - delegate: TumblerDelegate { - text: modelData.toString().length < 2 ? "0" + modelData : modelData - font.pixelSize: fontMetrics.font.pixelSize * (Tumbler.tumbler.activeFocus ? 2 : 1.25) - } - } - - Tumbler { - id: amPmTumbler - model: ["AM", "PM"] - delegate: TumblerDelegate { - font.pixelSize: fontMetrics.font.pixelSize * (Tumbler.tumbler.activeFocus ? 2 : 1.25) - } - - contentItem: ListView { - anchors.fill: parent - model: amPmTumbler.model - delegate: amPmTumbler.delegate - - snapMode: ListView.SnapToItem - highlightRangeMode: ListView.StrictlyEnforceRange - preferredHighlightBegin: height / 2 - (height / 3 / 2) - preferredHighlightEnd: height / 2 + (height / 3 / 2) - clip: true - } - } - } - } - } -} diff --git a/examples/labs/calendar/EventView.qml b/examples/labs/calendar/EventView.qml deleted file mode 100644 index e47e7486..00000000 --- a/examples/labs/calendar/EventView.qml +++ /dev/null @@ -1,209 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.6 -import Qt.labs.controls 1.0 - -Rectangle { - border.color: Theme.frameColor - - property date selectedDate - property var locale - property var eventModel - - signal addEventClicked - - Component { - id: eventListHeader - - Row { - id: eventDateRow - width: parent.width - height: eventDayLabel.height - spacing: 10 - - Label { - id: eventDayLabel - text: selectedDate.getDate() - font.pointSize: 35 - } - - Column { - height: eventDayLabel.height - - Label { - readonly property var options: { weekday: "long" } - text: Qt.locale().standaloneDayName(selectedDate.getDay(), Locale.LongFormat) - font.pointSize: 18 - } - Label { - text: Qt.locale().standaloneMonthName(selectedDate.getMonth()) - + selectedDate.toLocaleDateString(Qt.locale(), " yyyy") - font.pointSize: 12 - } - } - } - } - - ListView { - id: eventsListView - spacing: 4 - clip: true - header: eventListHeader - anchors.fill: parent - anchors.margins: 10 - model: eventModel - - delegate: Rectangle { - width: eventsListView.width - height: eventItemColumn.height - anchors.horizontalCenter: parent.horizontalCenter - - Rectangle { - width: parent.width - height: 1 - color: "#eee" - } - - Column { - id: eventItemColumn - x: 4 - y: 4 - width: parent.width - 8 - height: timeRow.height + descriptionLabel.height + 8 - - Label { - id: descriptionLabel - width: parent.width - wrapMode: Text.Wrap - text: description - } - Row { - id: timeRow - width: parent.width - Label { - text: start.toLocaleTimeString(locale, Locale.ShortFormat) - color: "#aaa" - } - Label { - text: "-" + end.toLocaleTimeString(locale, Locale.ShortFormat) - visible: start.getTime() !== end.getTime() && start.getDate() === end.getDate() - color: "#aaa" - } - } - } - - MouseArea { - anchors.fill: parent - onPressAndHold: removeButton.opacity = 1 - onClicked: removeButton.opacity = 0 - } - - Button { - id: removeButton - opacity: 0 - - Behavior on opacity { - NumberAnimation { - duration: 150 - } - } - - anchors.right: parent.right - anchors.rightMargin: 12 - anchors.verticalCenter: parent.verticalCenter - - onClicked: eventModel.removeEvent(index) - - background: Rectangle { - implicitWidth: 32 - implicitHeight: 32 - - radius: width / 2 - color: Qt.tint(!addButton.enabled ? addButton.Theme.disabledColor : - addButton.activeFocus ? addButton.Theme.focusColor : "red", - addButton.pressed ? addButton.Theme.pressColor : "transparent") - } - } - - // Don't want the white icon to change opacity. - Rectangle { - anchors.centerIn: removeButton - width: 18 - height: 4 - radius: 1 - } - } - } - - Button { - id: addButton - - anchors.right: parent.right - anchors.bottom: parent.bottom - anchors.margins: 12 - - onClicked: addEventClicked() - - background: Rectangle { - implicitWidth: 32 - implicitHeight: 32 - - radius: width / 2 - color: Qt.tint(!addButton.enabled ? addButton.Theme.disabledColor : - addButton.activeFocus ? addButton.Theme.focusColor : addButton.Theme.accentColor, - addButton.pressed ? addButton.Theme.pressColor : "transparent") - } - - Rectangle { - anchors.centerIn: parent - width: 4 - height: 18 - radius: 1 - } - - Rectangle { - anchors.centerIn: parent - width: 18 - height: 4 - radius: 1 - } - } -} diff --git a/examples/labs/calendar/calendar.pro b/examples/labs/calendar/calendar.pro deleted file mode 100644 index 9ee101b7..00000000 --- a/examples/labs/calendar/calendar.pro +++ /dev/null @@ -1,19 +0,0 @@ -TEMPLATE = app -TARGET = calendar -QT += quick sql - -SOURCES += \ - main.cpp - -OTHER_FILES += \ - main.qml - -RESOURCES += \ - calendar.qrc - -target.path = $$[QT_INSTALL_EXAMPLES]/labs/calendar/calendar -INSTALLS += target - -DISTFILES += \ - DateTimePicker.qml \ - EventView.qml diff --git a/examples/labs/calendar/calendar.qrc b/examples/labs/calendar/calendar.qrc deleted file mode 100644 index d0f67b26..00000000 --- a/examples/labs/calendar/calendar.qrc +++ /dev/null @@ -1,8 +0,0 @@ -<RCC> - <qresource prefix="/"> - <file>main.qml</file> - <file>DateTimePicker.qml</file> - <file>TumblerDelegate.qml</file> - <file>EventView.qml</file> - </qresource> -</RCC> diff --git a/examples/labs/calendar/main.cpp b/examples/labs/calendar/main.cpp deleted file mode 100644 index 651a51ec..00000000 --- a/examples/labs/calendar/main.cpp +++ /dev/null @@ -1,233 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QtGui> -#include <QtQml> -#include <QtSql> - -class Event : public QObject -{ - Q_OBJECT - Q_PROPERTY(QString description MEMBER description NOTIFY descriptionChanged) - Q_PROPERTY(QDateTime start MEMBER start NOTIFY startChanged) - Q_PROPERTY(QDateTime end MEMBER end NOTIFY endChanged) - -public: - explicit Event(const QString &description, QObject *parent = 0) : - QObject(parent), - description(description) - { - - } - - QString description; - QDateTime start; - QDateTime end; - -signals: - void descriptionChanged(); - void startChanged(); - void endChanged(); -}; - -static void addEvent(const QString &description, const QDateTime &start, qint64 duration = 0) -{ - QSqlQuery query; - QDateTime end = start.addSecs(duration); - if (!query.exec(QStringLiteral("INSERT INTO Event (description, start, end) VALUES ('%1', %2, %3)") - .arg(description).arg(start.toMSecsSinceEpoch()).arg(end.toMSecsSinceEpoch()))) { - qWarning() << query.lastError(); - } -} - -// create an in-memory SQLITE database -static void createDatabase() -{ - QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE"); - db.setDatabaseName(":memory:"); - if (!db.open()) { - qFatal("Cannot open database"); - return; - } - - QSqlQuery query; - query.exec("CREATE TABLE IF NOT EXISTS Event (description TEXT, start BIGINT, end BIGINT)"); - - const QDate current = QDate::currentDate(); - addEvent("Job interview", QDateTime(current.addDays(-19), QTime(12, 0))); - addEvent("Grocery shopping", QDateTime(current.addDays(-14), QTime(18, 0))); - addEvent("Ice skating", QDateTime(current.addDays(-14), QTime(20, 0)), 5400); - addEvent("Dentist''s appointment", QDateTime(current.addDays(-8), QTime(14, 0)), 1800); - addEvent("Cross-country skiing", QDateTime(current.addDays(1), QTime(19, 30)), 3600); - addEvent("Conference", QDateTime(current.addDays(10), QTime(9, 0)), 432000); - addEvent("Hairdresser", QDateTime(current.addDays(19), QTime(13, 0))); - addEvent("Doctor''s appointment", QDateTime(current.addDays(21), QTime(16, 0))); - addEvent("Vacation", QDateTime(current.addDays(35), QTime(0, 0)), 604800); -} - -class SqlEventModel : public QSqlTableModel -{ - Q_OBJECT - Q_PROPERTY(QDate min READ min CONSTANT) - Q_PROPERTY(QDate max READ max CONSTANT) - Q_PROPERTY(QDate date READ date WRITE setDate NOTIFY dateChanged FINAL) - Q_PROPERTY(int rowCount READ rowCount NOTIFY rowCountChanged) - -public: - SqlEventModel(QObject *parent = 0) : - QSqlTableModel(parent, QSqlDatabase::database(":memory:")) - { - connect(this, SIGNAL(rowsInserted(QModelIndex,int,int)), this, SIGNAL(rowCountChanged())); - connect(this, SIGNAL(rowsRemoved(QModelIndex,int,int)), this, SIGNAL(rowCountChanged())); - - setTable("Event"); - setEditStrategy(QSqlTableModel::OnManualSubmit); - select(); - - setDate(QDate::currentDate()); - } - - QDate min() const - { - QSqlQuery query(QStringLiteral("SELECT MIN(start) FROM Event")); - if (query.next()) - return QDateTime::fromMSecsSinceEpoch(query.value(0).toLongLong()).date(); - return QDate(); - } - - QDate max() const - { - QSqlQuery query(QStringLiteral("SELECT MAX(end) FROM Event")); - if (query.next()) - return QDateTime::fromMSecsSinceEpoch(query.value(0).toLongLong()).date(); - return QDate(); - } - - QDate date() const - { - return mDate; - } - - void setDate(const QDate &date) - { - if (date != mDate) { - mDate = date; - - qint64 from = QDateTime(mDate, QTime(0, 0)).toMSecsSinceEpoch(); - qint64 to = QDateTime(mDate, QTime(23, 59)).toMSecsSinceEpoch(); - - setFilter(QStringLiteral("start <= %1 AND end >= %2").arg(to).arg(from)); - - emit dateChanged(); - } - } - - enum { - DescriptionRole = Qt::UserRole, - StartDateRole, - EndDateRole - }; - - QHash<int,QByteArray> roleNames() const Q_DECL_OVERRIDE - { - QHash<int,QByteArray> names; - names[DescriptionRole] = "description"; - names[StartDateRole] = "start"; - names[EndDateRole] = "end"; - return names; - } - - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE - { - if (role < Qt::UserRole) - return QSqlTableModel::data(index, role); - - int columnIndex = role - DescriptionRole; - QModelIndex modelIndex = this->index(index.row(), columnIndex); - QVariant eventData = QSqlTableModel::data(modelIndex, Qt::DisplayRole); - if (role == DescriptionRole) - return eventData; - - return QDateTime::fromMSecsSinceEpoch(eventData.toLongLong()); - } - - Q_INVOKABLE void addEvent(const QString &description, const QDateTime &date) - { - const int row = rowCount(); - insertRows(row, 1); - setData(index(row, 0), description); - setData(index(row, 1), date.toMSecsSinceEpoch()); - setData(index(row, 2), date.toMSecsSinceEpoch()); - submitAll(); - } - - Q_INVOKABLE void removeEvent(int modelRow) - { - if (modelRow < 0 || modelRow >= rowCount()) { - qWarning() << "Invalid model row:" << modelRow; - return; - } - - removeRows(modelRow, 1); - submitAll(); - } - -signals: - void dateChanged(); - void rowCountChanged(); - -private: - // The date to show events for. - QDate mDate; -}; - -int main(int argc, char *argv[]) -{ - QGuiApplication app(argc, argv); - createDatabase(); - qmlRegisterType<SqlEventModel>("io.qt.examples.calendar", 1, 0, "SqlEventModel"); - QQmlApplicationEngine engine; - engine.load(QUrl("qrc:/main.qml")); - if (engine.rootObjects().isEmpty()) - return -1; - return app.exec(); -} - -#include "main.moc" diff --git a/examples/labs/calendar/main.qml b/examples/labs/calendar/main.qml deleted file mode 100644 index d7088fbe..00000000 --- a/examples/labs/calendar/main.qml +++ /dev/null @@ -1,220 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.6 -import Qt.labs.controls 1.0 -import Qt.labs.calendar 1.0 -import QtQuick.Layouts 1.0 -import io.qt.examples.calendar 1.0 - -ApplicationWindow { - id: window - width: 640 - height: 400 - minimumWidth: 400 - minimumHeight: 300 - color: "#f4f4f4" - visible: true - title: "Qt Labs Calendar - Example" - - SqlEventModel { - id: eventModel - date: calendar.selectedDate - } - - StackView { - id: stackView - anchors.fill: parent - anchors.margins: 20 - - initialItem: flow - } - - Flow { - id: flow - spacing: 10 - layoutDirection: Qt.RightToLeft - - ListView { - id: calendar - property date selectedDate: new Date() - - clip: true - width: (parent.width > parent.height ? (parent.width - parent.spacing) * 0.6 : parent.width) - height: (parent.height > parent.width ? (parent.height - parent.spacing) * 0.6 : parent.height) - - model: CalendarModel { - id: model - from: eventModel.min - to: eventModel.max - } - - focus: true - currentIndex: model.indexOf(selectedDate.getFullYear(), selectedDate.getMonth() + 1) - snapMode: ListView.SnapOneItem - highlightMoveDuration: 250 - highlightRangeMode: ListView.StrictlyEnforceRange - orientation: parent.width > parent.height ? ListView.Vertical : ListView.Horizontal - - delegate: MonthGrid { - id: delegate - - width: calendar.width - height: calendar.height - - month: model.month - year: model.year - - topPadding: title.height - Column { - id: title - x: delegate.contentItem.x - width: delegate.contentItem.width - spacing: 6 - Text { - width: parent.width - height: implicitHeight * 2 - text: delegate.title - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter - font.pointSize: 18 - } - DayOfWeekRow { - width: parent.width - } - } - - leftPadding: weekNumbers.width - WeekNumberColumn { - id: weekNumbers - month: model.month - year: model.year - y: delegate.contentItem.y - height: delegate.contentItem.height - } - - onClicked: calendar.selectedDate = date - - delegate: Text { - text: model.day - opacity: model.month === delegate.month ? 1 : 0 - color: model.today ? Theme.accentColor : Theme.textColor - minimumPointSize: 8 - fontSizeMode: Text.Fit - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter - Rectangle { - z: -1 - anchors.centerIn: parent - width: Math.min(parent.width * 0.6, parent.width * 0.6) - height: width - radius: width / 2 - opacity: 0.5 - color: pressed ? Theme.pressColor : "transparent"; - - SqlEventModel { - id: delegateEventModel - } - - border.color: delegateEventModel.rowCount > 0 ? Theme.accentColor : "transparent" - } - } - } - Rectangle { - z: -1 - parent: calendar - anchors.fill: parent - border.color: Theme.frameColor - } - } - - EventView { - width: (parent.width > parent.height ? (parent.width - parent.spacing) * 0.4 : parent.width) - height: (parent.height > parent.width ? (parent.height - parent.spacing) * 0.4 : parent.height) - selectedDate: calendar.selectedDate - eventModel: eventModel - locale: calendar.locale - - onAddEventClicked: stackView.push(createEventComponent) - } - } - - Component { - id: createEventComponent - - ColumnLayout { - spacing: 10 - visible: StackView.index === stackView.currentIndex - - DateTimePicker { - id: dateTimePicker - anchors.horizontalCenter: parent.horizontalCenter - dateToShow: calendar.selectedDate - } - Frame { - Layout.fillWidth: true - - TextArea { - id: descriptionField - placeholderText: "Description" - anchors.fill: parent - } - } - RowLayout { - Layout.fillWidth: true - - Button { - text: "Cancel" - Layout.fillWidth: true - onClicked: stackView.pop() - } - Button { - text: "Create" - enabled: dateTimePicker.enabled - Layout.fillWidth: true - onClicked: { - eventModel.addEvent(descriptionField.text, dateTimePicker.chosenDate); - stackView.pop(); - } - } - } - } - } -} diff --git a/examples/labs/controls/controls.pro b/examples/labs/controls/controls.pro deleted file mode 100644 index 4c0cd6e4..00000000 --- a/examples/labs/controls/controls.pro +++ /dev/null @@ -1,9 +0,0 @@ -TEMPLATE = subdirs -SUBDIRS += \ - mirroring \ - theme \ - tabs \ - drawer - -EXAMPLE_FILES += \ - shared diff --git a/examples/labs/controls/drawer/drawer.pro b/examples/labs/controls/drawer/drawer.pro deleted file mode 100644 index 02e40200..00000000 --- a/examples/labs/controls/drawer/drawer.pro +++ /dev/null @@ -1,15 +0,0 @@ -TEMPLATE = app -TARGET = drawer -QT += quick - -SOURCES += \ - main.cpp - -OTHER_FILES += \ - main.qml - -RESOURCES += \ - drawer.qrc - -target.path = $$[QT_INSTALL_EXAMPLES]/labs/controls/drawer -INSTALLS += target diff --git a/examples/labs/controls/drawer/drawer.qrc b/examples/labs/controls/drawer/drawer.qrc deleted file mode 100644 index 25cc5cbe..00000000 --- a/examples/labs/controls/drawer/drawer.qrc +++ /dev/null @@ -1,7 +0,0 @@ -<RCC> - <qresource prefix="/"> - <file>main.qml</file> - <file>images/arrow.png</file> - <file>images/qt-logo.png</file> - </qresource> -</RCC> diff --git a/examples/labs/controls/drawer/images/arrow.png b/examples/labs/controls/drawer/images/arrow.png Binary files differdeleted file mode 100644 index 4981e0de..00000000 --- a/examples/labs/controls/drawer/images/arrow.png +++ /dev/null diff --git a/examples/labs/controls/drawer/images/qt-logo.png b/examples/labs/controls/drawer/images/qt-logo.png Binary files differdeleted file mode 100644 index cf350dad..00000000 --- a/examples/labs/controls/drawer/images/qt-logo.png +++ /dev/null diff --git a/examples/labs/controls/drawer/main.qml b/examples/labs/controls/drawer/main.qml deleted file mode 100644 index 5b30a098..00000000 --- a/examples/labs/controls/drawer/main.qml +++ /dev/null @@ -1,157 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.6 -import Qt.labs.controls 1.0 - -ApplicationWindow { - id: window - width: 360 - height: 520 - visible: true - title: "Qt Labs Controls - Drawer Example" - - Rectangle { - id: content - anchors.fill: parent - anchors.margins: -1 - border.color: Theme.frameColor - - Image { - width: window.width / 2 - height: window.height / 2 - anchors.centerIn: parent - anchors.horizontalCenterOffset: window.width > window.height ? width / 2 : 0 - anchors.verticalCenterOffset: window.width < window.height ? -height / 4 : 0 - fillMode: Image.PreserveAspectFit - source: "qrc:/images/qt-logo.png" - } - - Image { - width: window.width / 2 - anchors.bottom: parent.bottom - anchors.bottomMargin: height / 2 - fillMode: Image.PreserveAspectFit - source: "qrc:/images/arrow.png" - } - - transform: Translate { - x: effect.current === uncover ? drawer.position * listview.width : - effect.current === push ? drawer.position * listview.width * 0.5 : 0 - } - - z: effect.current === uncover ? 2 : 0 - } - - Drawer { - id: drawer - anchors.fill: parent - - ListView { - id: listview - - width: window.width / 3 * 2 - height: window.height - - ExclusiveGroup { - id: effect - } - - model: VisualItemModel { - Label { - text: "Settings" - x: 6 - width: parent.width - 12 - lineHeight: 2.0 - color: Theme.accentColor - verticalAlignment: Text.AlignVCenter - } - Rectangle { width: parent.width; height: 1; color: Theme.frameColor } - Switch { - id: dim - text: "Dim" - checked: true - width: parent.width - layoutDirection: Qt.RightToLeft - enabled: effect.current != uncover - } - Rectangle { width: parent.width; height: 1; color: Theme.frameColor } - RadioButton { - id: overlay - text: "Overlay" - checked: true - width: parent.width - ExclusiveGroup.group: effect - layoutDirection: Qt.RightToLeft - } - RadioButton { - id: push - text: "Push" - width: parent.width - ExclusiveGroup.group: effect - layoutDirection: Qt.RightToLeft - } - RadioButton { - id: uncover - text: "Uncover" - width: parent.width - ExclusiveGroup.group: effect - layoutDirection: Qt.RightToLeft - } - Rectangle { width: parent.width; height: 1; color: Theme.frameColor } - } - Rectangle { - z: -1 - anchors.fill: parent - anchors.topMargin: -1 - anchors.bottomMargin: -1 - border.color: Theme.frameColor - } - - transform: Translate { - x: effect.current === uncover ? (1.0 - drawer.position) * listview.width : 0 - } - } - - background.visible: dim.checked - - onClicked: close() - } -} diff --git a/examples/labs/controls/mirroring/main.cpp b/examples/labs/controls/mirroring/main.cpp deleted file mode 100644 index 2abdc16d..00000000 --- a/examples/labs/controls/mirroring/main.cpp +++ /dev/null @@ -1,52 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QGuiApplication> -#include <QQmlApplicationEngine> - -int main(int argc, char *argv[]) -{ - QGuiApplication app(argc, argv); - QQmlApplicationEngine engine; - engine.load(QUrl("qrc:/main.qml")); - if (engine.rootObjects().isEmpty()) - return -1; - return app.exec(); -} diff --git a/examples/labs/controls/mirroring/main.qml b/examples/labs/controls/mirroring/main.qml deleted file mode 100644 index 3cc6f502..00000000 --- a/examples/labs/controls/mirroring/main.qml +++ /dev/null @@ -1,237 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.6 -import QtQuick.Layouts 1.0 -import Qt.labs.controls 1.0 - -ApplicationWindow { - id: window - width: 360 - height: 520 - visible: true - title: "Qt Labs Controls - Mirroring Example" - - ListView { - id: listview - anchors.fill: parent - - LayoutMirroring.enabled: headerItem.mirror - LayoutMirroring.childrenInherit: true - - headerPositioning: ListView.PullBackHeader - header: Rectangle { - property alias mirror: mirrorSwitch.checked - - z: 2 - width: parent.width - height: label.implicitHeight + 96 - - Label { - id: label - text: "Beyond the essentials." - color: Theme.accentColor - anchors.fill: parent - anchors.margins: 48 - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter - wrapMode: Text.WordWrap - font.pointSize: 26 - } - - Switch { - id: mirrorSwitch - text: "Mirror" - anchors.right: parent.right - anchors.bottom: parent.bottom - layoutDirection: Qt.RightToLeft - LayoutMirroring.enabled: false - } - - Rectangle { - width: parent.width - height: 1 - anchors.bottom: parent.bottom - color: Theme.frameColor - } - } - - model: VisualItemModel { - - Item { width: 1; height: 24 } - - Flow { - id: flow - spacing: 12 - width: Math.min(window.width, window.height) - 24 - anchors.horizontalCenter: parent.horizontalCenter - - GroupBox { - title: "CheckBox" - readonly property real preferredWidth: (flow.width - 12) / 2 - width: window.width > window.height || contentWidth > preferredWidth ? flow.width : preferredWidth - ColumnLayout { - width: parent.width - CheckBox { - width: parent.width - text: "E-mail" - checked: true - } - CheckBox { - width: parent.width - text: "Calendar" - checked: true - } - CheckBox { - width: parent.width - text: "Contacts" - } - } - } - - GroupBox { - title: "RadioButton" - readonly property real preferredWidth: (flow.width - 12) / 2 - width: window.width > window.height || contentWidth > preferredWidth ? flow.width : preferredWidth - ExclusiveGroup { id: eg } - ColumnLayout { - width: parent.width - RadioButton { - width: parent.width - text: "Portrait" - ExclusiveGroup.group: eg - } - RadioButton { - width: parent.width - text: "Landscape" - ExclusiveGroup.group: eg - } - RadioButton { - width: parent.width - text: "Automatic" - checked: true - ExclusiveGroup.group: eg - } - } - } - - GroupBox { - title: "Button" - width: flow.width - Row { - width: parent.width - spacing: 6 - readonly property real availableWidth: (flow.width - 12) / 2 - readonly property real contentWidth: okButton.implicitWidth + cancelButton.implicitWidth + 12 - readonly property real buttonWidth: implicitWidth > availableWidth ? (width / 2 - spacing) : (width / 2 - 2 * spacing) / 2 - Button { - id: okButton - text: "Ok" - width: parent.buttonWidth - } - Button { - id: cancelButton - text: "Cancel" - width: parent.buttonWidth - } - } - } - - GroupBox { - title: "Switch" - width: flow.width - Column { - width: parent.width - Switch { - width: parent.width - text: "Wifi" - checked: true - } - Switch { - width: parent.width - text: "Bluetooth" - } - } - } - - GroupBox { - title: "ProgressBar" - width: flow.width - Column { - width: parent.width - spacing: 6 - ProgressBar { - width: parent.width - indeterminate: true - } - ProgressBar { - width: parent.width - value: slider.position - } - } - } - - GroupBox { - title: "Slider" - width: flow.width - Column { - width: parent.width - spacing: 6 - Slider { - id: slider - value: 0.4 - width: parent.width - } - Slider { - width: parent.width - snapMode: Slider.SnapAlways - stepSize: 0.2 - value: 0.8 - } - } - } - } - - Item { width: 1; height: 12 } - } - - ScrollIndicator.vertical: ScrollIndicator { anchors.right: parent.right } - } -} diff --git a/examples/labs/controls/mirroring/mirroring.pro b/examples/labs/controls/mirroring/mirroring.pro deleted file mode 100644 index 60b73f94..00000000 --- a/examples/labs/controls/mirroring/mirroring.pro +++ /dev/null @@ -1,15 +0,0 @@ -TEMPLATE = app -TARGET = mirroring -QT += quick - -SOURCES += \ - main.cpp - -OTHER_FILES += \ - main.qml - -RESOURCES += \ - mirroring.qrc - -target.path = $$[QT_INSTALL_EXAMPLES]/labs/controls/mirroring -INSTALLS += target diff --git a/examples/labs/controls/mirroring/mirroring.qrc b/examples/labs/controls/mirroring/mirroring.qrc deleted file mode 100644 index 5f6483ac..00000000 --- a/examples/labs/controls/mirroring/mirroring.qrc +++ /dev/null @@ -1,5 +0,0 @@ -<RCC> - <qresource prefix="/"> - <file>main.qml</file> - </qresource> -</RCC> diff --git a/examples/labs/controls/tabs/images/qt-logo.png b/examples/labs/controls/tabs/images/qt-logo.png Binary files differdeleted file mode 100644 index cf350dad..00000000 --- a/examples/labs/controls/tabs/images/qt-logo.png +++ /dev/null diff --git a/examples/labs/controls/tabs/main.cpp b/examples/labs/controls/tabs/main.cpp deleted file mode 100644 index 2abdc16d..00000000 --- a/examples/labs/controls/tabs/main.cpp +++ /dev/null @@ -1,52 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QGuiApplication> -#include <QQmlApplicationEngine> - -int main(int argc, char *argv[]) -{ - QGuiApplication app(argc, argv); - QQmlApplicationEngine engine; - engine.load(QUrl("qrc:/main.qml")); - if (engine.rootObjects().isEmpty()) - return -1; - return app.exec(); -} diff --git a/examples/labs/controls/tabs/main.qml b/examples/labs/controls/tabs/main.qml deleted file mode 100644 index ceebc622..00000000 --- a/examples/labs/controls/tabs/main.qml +++ /dev/null @@ -1,290 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.6 -import QtQuick.Layouts 1.0 -import Qt.labs.controls 1.0 -import QtQuick.XmlListModel 2.0 - -ApplicationWindow { - id: window - width: 360 - height: 520 - visible: true - title: "Qt Labs Controls - Tabs Example" - - header: TabBar { - id: bar - currentIndex: view.currentIndex - TabButton { - text: "Home" - } - TabButton { - text: "Discover" - } - TabButton { - text: "Activity" - } - } - - SwipeView { - id: view - - spacing: 1 - anchors.fill: parent - currentIndex: bar.currentIndex - background: Rectangle { color: Theme.frameColor } - - Rectangle { - Image { - id: logo - width: window.width / 2 - height: window.height / 2 - anchors.centerIn: parent - fillMode: Image.PreserveAspectFit - source: "qrc:/images/qt-logo.png" - } - - Label { - text: "Things just got better" - color: Theme.accentColor - anchors.margins: 40 - anchors.top: logo.bottom - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: parent.bottom - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter - wrapMode: Text.WordWrap - font.pointSize: 26 - } - } - - Rectangle { - ListView { - anchors.fill: parent - anchors.topMargin: -1 - model: XmlListModel { - id: feedModel - query: "/rss/channel/item" - source: "http://blog.qt.io/feed/" - namespaceDeclarations: "declare namespace dc='http://purl.org/dc/elements/1.1/';" - XmlRole { name: "title"; query: "title/string()" } - XmlRole { name: "link"; query: "link/string()" } - XmlRole { name: "pubDate"; query: "pubDate/string()" } - XmlRole { name: "creator"; query: "dc:creator/string()" } - XmlRole { name: "description"; query: "description/string()" } - } - - delegate: Item { - width: parent.width - height: feedItem.height - Column { - id: feedItem - width: parent.width - spacing: 6 - Rectangle { - width: parent.width - height: 1 - color: Theme.frameColor - visible: index == 0 - } - Item { width: 1; height: 6 } - Label { - text: model.title - x: 6 - width: parent.width - 12 - elide: Text.ElideRight - color: Theme.accentColor - font.pointSize: 20 - lineHeight: 0.75 - } - Label { - text: model.description - textFormat: Text.StyledText - x: 6 - width: parent.width - 12 - wrapMode: Text.WordWrap - } - RowLayout { - x: 6 - width: parent.width - 12 - spacing: 6 - Label { - id: discoverCreator - text: model.creator - height: parent.height - verticalAlignment: Text.AlignVCenter - color: Theme.focusColor - font.pointSize: 8 - } - Label { - text: model.pubDate - height: parent.height - elide: Text.ElideRight - verticalAlignment: Text.AlignVCenter - color: Theme.disabledColor - font.pointSize: 8 - Layout.preferredWidth: parent.width - discoverCreator.width - discoverMore.width - 2 * parent.spacing - visible: Layout.preferredWidth > 0 - } - Button { - id: discoverMore - text: "Read more..." - onClicked: Qt.openUrlExternally(model.link) - } - } - Rectangle { - width: parent.width - height: 1 - color: Theme.frameColor - } - } - } - - ScrollIndicator.vertical: ScrollIndicator { } - } - - BusyIndicator { - anchors.centerIn: parent - running: feedModel.status === XmlListModel.Loading - } - } - - Rectangle { - ListView { - anchors.fill: parent - anchors.topMargin: -1 - model: XmlListModel { - id: commentModel - query: "/rss/channel/item" - source: "http://blog.qt.io/comments/feed/" - namespaceDeclarations: "declare namespace dc='http://purl.org/dc/elements/1.1/';" - XmlRole { name: "title"; query: "title/string()" } - XmlRole { name: "link"; query: "link/string()" } - XmlRole { name: "pubDate"; query: "pubDate/string()" } - XmlRole { name: "creator"; query: "dc:creator/string()" } - XmlRole { name: "description"; query: "description/string()" } - } - - delegate: Rectangle { - width: parent.width - height: commentItem.height - Column { - id: commentItem - width: parent.width - spacing: 6 - Rectangle { - width: parent.width - height: 1 - color: Theme.frameColor - visible: index == 0 - } - Item { width: 1; height: 6 } - Label { - text: model.title - x: 6 - width: parent.width - 12 - elide: Text.ElideRight - color: Theme.accentColor - font.pointSize: 14 - lineHeight: 0.75 - } - Item { width: 1; height: 6 } - Label { - text: model.description - textFormat: Text.StyledText - x: 6 - width: parent.width - 12 - wrapMode: Text.WordWrap - } - RowLayout { - x: 6 - width: parent.width - 12 - spacing: 6 - Label { - id: activityCreator - text: model.creator - height: parent.height - verticalAlignment: Text.AlignVCenter - color: Theme.focusColor - font.pointSize: 8 - } - Label { - text: model.pubDate - height: parent.height - elide: Text.ElideRight - verticalAlignment: Text.AlignVCenter - color: Theme.disabledColor - font.pointSize: 8 - Layout.preferredWidth: parent.width - activityCreator.width - activityMore.width - 2 * parent.spacing - visible: Layout.preferredWidth > 0 - } - Button { - id: activityMore - text: "Read more..." - onClicked: Qt.openUrlExternally(model.link) - } - } - Rectangle { - width: parent.width - height: 1 - color: Theme.frameColor - } - } - } - - ScrollIndicator.vertical: ScrollIndicator { } - } - - BusyIndicator { - anchors.centerIn: parent - running: feedModel.status === XmlListModel.Loading - } - } - } - - PageIndicator { - count: view.count - currentIndex: view.currentIndex - anchors.bottom: parent.bottom - anchors.horizontalCenter: parent.horizontalCenter - } -} diff --git a/examples/labs/controls/tabs/tabs.pro b/examples/labs/controls/tabs/tabs.pro deleted file mode 100644 index f9b85c1a..00000000 --- a/examples/labs/controls/tabs/tabs.pro +++ /dev/null @@ -1,15 +0,0 @@ -TEMPLATE = app -TARGET = tabs -QT += quick - -SOURCES += \ - main.cpp - -OTHER_FILES += \ - main.qml - -RESOURCES += \ - tabs.qrc - -target.path = $$[QT_INSTALL_EXAMPLES]/labs/controls/tabs -INSTALLS += target diff --git a/examples/labs/controls/tabs/tabs.qrc b/examples/labs/controls/tabs/tabs.qrc deleted file mode 100644 index b48259b1..00000000 --- a/examples/labs/controls/tabs/tabs.qrc +++ /dev/null @@ -1,6 +0,0 @@ -<RCC> - <qresource prefix="/"> - <file>main.qml</file> - <file>images/qt-logo.png</file> - </qresource> -</RCC> diff --git a/examples/labs/controls/theme/main.cpp b/examples/labs/controls/theme/main.cpp deleted file mode 100644 index 2abdc16d..00000000 --- a/examples/labs/controls/theme/main.cpp +++ /dev/null @@ -1,52 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QGuiApplication> -#include <QQmlApplicationEngine> - -int main(int argc, char *argv[]) -{ - QGuiApplication app(argc, argv); - QQmlApplicationEngine engine; - engine.load(QUrl("qrc:/main.qml")); - if (engine.rootObjects().isEmpty()) - return -1; - return app.exec(); -} diff --git a/examples/labs/controls/theme/main.qml b/examples/labs/controls/theme/main.qml deleted file mode 100644 index 3b970f58..00000000 --- a/examples/labs/controls/theme/main.qml +++ /dev/null @@ -1,174 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.6 -import Qt.labs.controls 1.0 - -ApplicationWindow { - id: window - width: 360 - height: 520 - visible: true - title: "Qt Labs Controls - Theme Example" - - header: ToolBar { - ToolButton { - label: Text { - // \u25C0 (black left-pointing triangle is) missing in some fonts - // => use a rotated \u25B2 (black up-pointing triangle) instead - text: "\u25B2" - rotation: -90 - color: enabled ? Theme.accentColor : Theme.frameColor - anchors.centerIn: parent - } - enabled: stackview.depth > 1 - onClicked: stackview.pop() - } - } - - StackView { - id: stackview - anchors.fill: parent - initialItem: pageComponent - } - - Component { - id: pageComponent - Rectangle { - id: page - Theme.accentColor: Qt.hsla(colorSlider.position, 0.5, 0.5, 1.0) - Theme.backgroundColor: darkButton.checked ? "#444" : "#fff" - Theme.frameColor: darkButton.checked ? "#666" : "#ccc" - Theme.textColor: darkButton.checked ? "#eee" : "#111" - Theme.pressColor: darkButton.checked ? "#33ffffff" : "#33333333" - Theme.baseColor: darkButton.checked ? "#444" : "#eee" - color: Theme.backgroundColor - Flickable { - anchors.fill: parent - contentHeight: column.height + 48 - - Column { - id: column - - x: (window.width - width) / 2 - y: 24 - width: window.width / 2 - spacing: 12 - - Label { - text: "Code less. Create more." - color: Theme.accentColor - width: parent.width - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter - wrapMode: Text.WordWrap - font.pointSize: 26 - } - - Item { width: 1; height: 48 } - - Rectangle { - width: parent.width - height: 1 - color: Theme.frameColor - } - - Column { - spacing: 6 - width: parent.width - Label { - text: "Accent color" - color: Theme.textColor - } - Slider { - id: colorSlider - width: parent.width - value: 0.275 - } - } - - Rectangle { - width: parent.width - height: 1 - color: Theme.frameColor - } - - ExclusiveGroup { - id: themeGroup - } - - Column { - width: parent.width - spacing: 6 - RadioButton { - id: lightButton - text: "Light" - width: parent.width - checked: true - layoutDirection: Qt.RightToLeft - ExclusiveGroup.group: themeGroup - } - RadioButton { - id: darkButton - text: "Dark" - width: parent.width - layoutDirection: Qt.RightToLeft - ExclusiveGroup.group: themeGroup - } - } - - Rectangle { - width: parent.width - height: 1 - color: Theme.frameColor - } - - Button { - text: "Push" - anchors.right: parent.right - onClicked: stackview.push(pageComponent) - } - } - - ScrollIndicator.vertical: ScrollIndicator { } - } - } - } -} diff --git a/examples/labs/controls/theme/theme.pro b/examples/labs/controls/theme/theme.pro deleted file mode 100644 index 7672a2cb..00000000 --- a/examples/labs/controls/theme/theme.pro +++ /dev/null @@ -1,15 +0,0 @@ -TEMPLATE = app -TARGET = theme -QT += quick - -SOURCES += \ - main.cpp - -OTHER_FILES += \ - main.qml - -RESOURCES += \ - theme.qrc - -target.path = $$[QT_INSTALL_EXAMPLES]/labs/controls/theme -INSTALLS += target diff --git a/examples/labs/controls/theme/theme.qrc b/examples/labs/controls/theme/theme.qrc deleted file mode 100644 index 5f6483ac..00000000 --- a/examples/labs/controls/theme/theme.qrc +++ /dev/null @@ -1,5 +0,0 @@ -<RCC> - <qresource prefix="/"> - <file>main.qml</file> - </qresource> -</RCC> diff --git a/examples/labs/labs.pro b/examples/labs/labs.pro deleted file mode 100644 index 80f94e86..00000000 --- a/examples/labs/labs.pro +++ /dev/null @@ -1,4 +0,0 @@ -TEMPLATE = subdirs -SUBDIRS += \ - calendar \ - controls diff --git a/src/controls/controls.pri b/src/controls/controls.pri new file mode 100644 index 00000000..005ee839 --- /dev/null +++ b/src/controls/controls.pri @@ -0,0 +1,12 @@ +HEADERS += \ + $$PWD/qquickproxytheme_p.h \ + $$PWD/qquickstyle_p.h \ + $$PWD/qquickstyleselector_p.h \ + $$PWD/qquickstyleselector_p_p.h \ + $$PWD/qquickpaddedrectangle_p.h + +SOURCES += \ + $$PWD/qquickproxytheme.cpp \ + $$PWD/qquickstyle.cpp \ + $$PWD/qquickstyleselector.cpp \ + $$PWD/qquickpaddedrectangle.cpp diff --git a/src/controls/controls.pro b/src/controls/controls.pro new file mode 100644 index 00000000..ecb3a9d6 --- /dev/null +++ b/src/controls/controls.pro @@ -0,0 +1,11 @@ +TARGET = QtLabsControls +MODULE = labscontrols +CONFIG += static internal_module + +QT += quick +QT_PRIVATE += core-private gui-private qml-private quick-private + +DEFINES += QT_NO_CAST_TO_ASCII QT_NO_CAST_FROM_ASCII + +include(controls.pri) +load(qt_module) diff --git a/src/controls/qquickpaddedrectangle.cpp b/src/controls/qquickpaddedrectangle.cpp new file mode 100644 index 00000000..ee66a5a5 --- /dev/null +++ b/src/controls/qquickpaddedrectangle.cpp @@ -0,0 +1,197 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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 "qquickpaddedrectangle_p.h" + +#include <QtQuick/private/qsgadaptationlayer_p.h> + +QT_BEGIN_NAMESPACE + +QQuickPaddedRectangle::QQuickPaddedRectangle(QQuickItem *parent) : + QQuickRectangle(parent), m_padding(0), + m_topPadding(0), m_leftPadding(0), m_rightPadding(0), m_bottomPadding(0), + m_hasTopPadding(false), m_hasLeftPadding(false), m_hasRightPadding(false), m_hasBottomPadding(false) +{ +} + +qreal QQuickPaddedRectangle::padding() const +{ + return m_padding; +} + +void QQuickPaddedRectangle::setPadding(qreal padding) +{ + if (!qFuzzyCompare(m_padding, padding)) { + m_padding = padding; + update(); + emit paddingChanged(); + if (m_hasTopPadding) + emit topPaddingChanged(); + if (!m_hasLeftPadding) + emit leftPaddingChanged(); + if (!m_hasRightPadding) + emit rightPaddingChanged(); + if (!m_hasBottomPadding) + emit bottomPaddingChanged(); + } +} + +void QQuickPaddedRectangle::resetPadding() +{ + setPadding(0); +} + +qreal QQuickPaddedRectangle::topPadding() const +{ + return m_hasTopPadding ? m_topPadding : m_padding; +} + +void QQuickPaddedRectangle::setTopPadding(qreal padding) +{ + setTopPadding(padding, true); +} + +void QQuickPaddedRectangle::resetTopPadding() +{ + setTopPadding(0, false); +} + +qreal QQuickPaddedRectangle::leftPadding() const +{ + return m_hasLeftPadding ? m_leftPadding : m_padding; +} + +void QQuickPaddedRectangle::setLeftPadding(qreal padding) +{ + setLeftPadding(padding, true); +} + +void QQuickPaddedRectangle::resetLeftPadding() +{ + setLeftPadding(0, false); +} + +qreal QQuickPaddedRectangle::rightPadding() const +{ + return m_hasRightPadding ? m_rightPadding : m_padding; +} + +void QQuickPaddedRectangle::setRightPadding(qreal padding) +{ + setRightPadding(padding, true); +} + +void QQuickPaddedRectangle::resetRightPadding() +{ + setRightPadding(0, false); +} + +qreal QQuickPaddedRectangle::bottomPadding() const +{ + return m_hasBottomPadding ? m_bottomPadding : m_padding; +} + +void QQuickPaddedRectangle::setBottomPadding(qreal padding) +{ + setBottomPadding(padding, true); +} + +void QQuickPaddedRectangle::resetBottomPadding() +{ + setBottomPadding(0, false); +} + +void QQuickPaddedRectangle::setTopPadding(qreal padding, bool has) +{ + qreal oldPadding = topPadding(); + m_hasTopPadding = has; + m_topPadding = padding; + if (!qFuzzyCompare(oldPadding, padding)) { + update(); + emit topPaddingChanged(); + } +} + +void QQuickPaddedRectangle::setLeftPadding(qreal padding, bool has) +{ + qreal oldPadding = leftPadding(); + m_hasLeftPadding = has; + m_leftPadding = padding; + if (!qFuzzyCompare(oldPadding, padding)) { + update(); + emit leftPaddingChanged(); + } +} + +void QQuickPaddedRectangle::setRightPadding(qreal padding, bool has) +{ + qreal oldPadding = rightPadding(); + m_hasRightPadding = has; + m_rightPadding = padding; + if (!qFuzzyCompare(oldPadding, padding)) { + update(); + emit rightPaddingChanged(); + } +} + +void QQuickPaddedRectangle::setBottomPadding(qreal padding, bool has) +{ + qreal oldPadding = bottomPadding(); + m_hasBottomPadding = has; + m_bottomPadding = padding; + if (!qFuzzyCompare(oldPadding, padding)) { + update(); + emit bottomPaddingChanged(); + } +} + +QSGNode *QQuickPaddedRectangle::updatePaintNode(QSGNode *node, UpdatePaintNodeData *data) +{ + QSGRectangleNode *rectangle = static_cast<QSGRectangleNode *>(QQuickRectangle::updatePaintNode(node, data)); + if (rectangle) { + qreal top = topPadding(); + qreal left = leftPadding(); + qreal right = rightPadding(); + qreal bottom = bottomPadding(); + if (!qFuzzyIsNull(top) || !qFuzzyIsNull(left) || !qFuzzyIsNull(right) || !qFuzzyIsNull(bottom)) { + rectangle->setRect(boundingRect().adjusted(left, top, -right, -bottom)); + rectangle->update(); + } + } + return rectangle; +} + +QT_END_NAMESPACE diff --git a/src/controls/qquickpaddedrectangle_p.h b/src/controls/qquickpaddedrectangle_p.h new file mode 100644 index 00000000..3ebb75b8 --- /dev/null +++ b/src/controls/qquickpaddedrectangle_p.h @@ -0,0 +1,118 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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 QQUICKPADDEDRECTANGLE_P_H +#define QQUICKPADDEDRECTANGLE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuick/private/qquickrectangle_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickPaddedRectangle : public QQuickRectangle +{ + Q_OBJECT + Q_PROPERTY(qreal padding READ padding WRITE setPadding RESET resetPadding NOTIFY paddingChanged FINAL) + Q_PROPERTY(qreal topPadding READ topPadding WRITE setTopPadding RESET resetTopPadding NOTIFY topPaddingChanged FINAL) + Q_PROPERTY(qreal leftPadding READ leftPadding WRITE setLeftPadding RESET resetLeftPadding NOTIFY leftPaddingChanged FINAL) + 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) + +public: + QQuickPaddedRectangle(QQuickItem *parent = Q_NULLPTR); + + qreal padding() const; + void setPadding(qreal padding); + void resetPadding(); + + qreal topPadding() const; + void setTopPadding(qreal padding); + void resetTopPadding(); + + qreal leftPadding() const; + void setLeftPadding(qreal padding); + void resetLeftPadding(); + + qreal rightPadding() const; + void setRightPadding(qreal padding); + void resetRightPadding(); + + qreal bottomPadding() const; + void setBottomPadding(qreal padding); + void resetBottomPadding(); + +Q_SIGNALS: + void paddingChanged(); + void topPaddingChanged(); + void leftPaddingChanged(); + void rightPaddingChanged(); + void bottomPaddingChanged(); + +protected: + QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *) Q_DECL_OVERRIDE; + +private: + void setTopPadding(qreal padding, bool has); + void setLeftPadding(qreal padding, bool has); + void setRightPadding(qreal padding, bool has); + void setBottomPadding(qreal padding, bool has); + + qreal m_padding; + qreal m_topPadding; + qreal m_leftPadding; + qreal m_rightPadding; + qreal m_bottomPadding; + bool m_hasTopPadding; + bool m_hasLeftPadding; + bool m_hasRightPadding; + bool m_hasBottomPadding; +}; + +Q_DECLARE_TYPEINFO(QQuickPaddedRectangle, Q_COMPLEX_TYPE); + +QT_END_NAMESPACE + +#endif // QQUICKPADDEDRECTANGLE_P_H diff --git a/src/controls/qquickproxytheme.cpp b/src/controls/qquickproxytheme.cpp new file mode 100644 index 00000000..dccd7f22 --- /dev/null +++ b/src/controls/qquickproxytheme.cpp @@ -0,0 +1,181 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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 "qquickproxytheme_p.h" + +#include <QtGui/qguiapplication.h> +#include <QtGui/qpixmap.h> +#include <QtGui/qfont.h> + +QT_BEGIN_NAMESPACE + +QQuickProxyTheme::QQuickProxyTheme(QPlatformTheme *theme) + : m_theme(theme) +{ +} + +QQuickProxyTheme::~QQuickProxyTheme() +{ +} + +QPlatformTheme *QQuickProxyTheme::theme() const +{ + return m_theme; +} + +QPlatformMenuItem *QQuickProxyTheme::createPlatformMenuItem() const +{ + if (m_theme) + return m_theme->createPlatformMenuItem(); + else + return QPlatformTheme::createPlatformMenuItem(); +} + +QPlatformMenu *QQuickProxyTheme::createPlatformMenu() const +{ + if (m_theme) + return m_theme->createPlatformMenu(); + else + return QPlatformTheme::createPlatformMenu(); +} + +QPlatformMenuBar *QQuickProxyTheme::createPlatformMenuBar() const +{ + if (m_theme) + return m_theme->createPlatformMenuBar(); + else + return QPlatformTheme::createPlatformMenuBar(); +} + +void QQuickProxyTheme::showPlatformMenuBar() +{ + if (m_theme) + m_theme->showPlatformMenuBar(); + else + QPlatformTheme::showPlatformMenuBar(); +} + +bool QQuickProxyTheme::usePlatformNativeDialog(QPlatformTheme::DialogType type) const +{ + if (m_theme) + return m_theme->usePlatformNativeDialog(type); + else + return QPlatformTheme::usePlatformNativeDialog(type); +} + +QPlatformDialogHelper *QQuickProxyTheme::createPlatformDialogHelper(QPlatformTheme::DialogType type) const +{ + if (m_theme) + return m_theme->createPlatformDialogHelper(type); + else + return QPlatformTheme::createPlatformDialogHelper(type); +} + +#ifndef QT_NO_SYSTEMTRAYICON +QPlatformSystemTrayIcon *QQuickProxyTheme::createPlatformSystemTrayIcon() const +{ + if (m_theme) + return m_theme->createPlatformSystemTrayIcon(); + else + return QPlatformTheme::createPlatformSystemTrayIcon(); +} +#endif + +const QPalette *QQuickProxyTheme::palette(QPlatformTheme::Palette type) const +{ + if (m_theme) + return m_theme->palette(type); + else + return QPlatformTheme::palette(type); +} + +const QFont *QQuickProxyTheme::font(QPlatformTheme::Font type) const +{ + if (m_theme) + return m_theme->font(type); + else + return QPlatformTheme::font(type); +} + +QVariant QQuickProxyTheme::themeHint(QPlatformTheme::ThemeHint hint) const +{ + if (m_theme) + return m_theme->themeHint(hint); + else + return QPlatformTheme::themeHint(hint); +} + +QPixmap QQuickProxyTheme::standardPixmap(QPlatformTheme::StandardPixmap sp, const QSizeF &size) const +{ + if (m_theme) + return m_theme->standardPixmap(sp, size); + else + return QPlatformTheme::standardPixmap(sp, size); +} + +QPixmap QQuickProxyTheme::fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &size, QPlatformTheme::IconOptions iconOptions) const +{ + if (m_theme) + return m_theme->fileIconPixmap(fileInfo, size, iconOptions); + else + return QPlatformTheme::fileIconPixmap(fileInfo, size, iconOptions); +} + +QIconEngine *QQuickProxyTheme::createIconEngine(const QString &iconName) const +{ + if (m_theme) + return m_theme->createIconEngine(iconName); + else + return QPlatformTheme::createIconEngine(iconName); +} + +QList<QKeySequence> QQuickProxyTheme::keyBindings(QKeySequence::StandardKey key) const +{ + if (m_theme) + return m_theme->keyBindings(key); + else + return QPlatformTheme::keyBindings(key); +} + +QString QQuickProxyTheme::standardButtonText(int button) const +{ + if (m_theme) + return m_theme->standardButtonText(button); + else + return QPlatformTheme::standardButtonText(button); +} + +QT_END_NAMESPACE diff --git a/src/controls/qquickproxytheme_p.h b/src/controls/qquickproxytheme_p.h new file mode 100644 index 00000000..47f931b5 --- /dev/null +++ b/src/controls/qquickproxytheme_p.h @@ -0,0 +1,98 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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 QQUICKPROXYTHEME_H +#define QQUICKPROXYTHEME_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 <QtGui/qpa/qplatformtheme.h> + +QT_BEGIN_NAMESPACE + +class QQuickProxyTheme : public QPlatformTheme +{ +public: + QQuickProxyTheme(QPlatformTheme *theme); + + ~QQuickProxyTheme(); + + QPlatformTheme* theme() const; + + QPlatformMenuItem* createPlatformMenuItem() const Q_DECL_OVERRIDE; + QPlatformMenu* createPlatformMenu() const Q_DECL_OVERRIDE; + QPlatformMenuBar* createPlatformMenuBar() const Q_DECL_OVERRIDE; + void showPlatformMenuBar() Q_DECL_OVERRIDE; + + bool usePlatformNativeDialog(DialogType type) const Q_DECL_OVERRIDE; + QPlatformDialogHelper *createPlatformDialogHelper(DialogType type) const Q_DECL_OVERRIDE; + +#ifndef QT_NO_SYSTEMTRAYICON + QPlatformSystemTrayIcon *createPlatformSystemTrayIcon() const Q_DECL_OVERRIDE; +#endif + + const QPalette *palette(Palette type = SystemPalette) const Q_DECL_OVERRIDE; + + const QFont *font(Font type = SystemFont) const Q_DECL_OVERRIDE; + + QVariant themeHint(ThemeHint hint) const Q_DECL_OVERRIDE; + + QPixmap standardPixmap(StandardPixmap sp, const QSizeF &size) const Q_DECL_OVERRIDE; + QPixmap fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &size, + QPlatformTheme::IconOptions iconOptions = 0) const Q_DECL_OVERRIDE; + + QIconEngine *createIconEngine(const QString &iconName) const Q_DECL_OVERRIDE; + + QList<QKeySequence> keyBindings(QKeySequence::StandardKey key) const Q_DECL_OVERRIDE; + + QString standardButtonText(int button) const Q_DECL_OVERRIDE; + +private: + QPlatformTheme *m_theme; +}; + +QT_END_NAMESPACE + +#endif // QQUICKPROXYTHEME_H diff --git a/src/controls/qquickstyle.cpp b/src/controls/qquickstyle.cpp new file mode 100644 index 00000000..b83f8c2a --- /dev/null +++ b/src/controls/qquickstyle.cpp @@ -0,0 +1,201 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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 "qquickstyle_p.h" + +#include <QtQuick/private/qquickitem_p.h> + +QT_BEGIN_NAMESPACE + +static QQuickStyle *attachedStyle(const QMetaObject *type, QObject *object, bool create = false) +{ + if (!object) + return Q_NULLPTR; + int idx = -1; + return qobject_cast<QQuickStyle *>(qmlAttachedPropertiesObject(&idx, object, type, create)); +} + +static QQuickStyle *findParentStyle(const QMetaObject *type, QObject *object) +{ + QQuickItem *item = qobject_cast<QQuickItem *>(object); + if (item) { + // lookup parent items + QQuickItem *parent = item->parentItem(); + while (parent) { + QQuickStyle *style = attachedStyle(type, parent); + if (style) + return style; + parent = parent->parentItem(); + } + + // fallback to item's window + QQuickWindow *window = item->window(); + if (window) { + QQuickStyle *style = attachedStyle(type, window); + if (style) + return style; + } + } + + // lookup parent window + QQuickWindow *window = qobject_cast<QQuickWindow *>(object); + if (window) { + QQuickWindow *parentWindow = qobject_cast<QQuickWindow *>(window->parent()); + if (parentWindow) { + QQuickStyle *style = attachedStyle(type, window); + if (style) + return style; + } + } + + // fallback to engine (global) + if (object) { + QQmlEngine *engine = qmlEngine(object); + if (engine) { + QByteArray name = QByteArray("_q_") + type->className(); + QQuickStyle *style = engine->property(name).value<QQuickStyle*>(); + if (!style) { + style = attachedStyle(type, engine, true); + engine->setProperty(name, QVariant::fromValue(style)); + } + return style; + } + } + + return Q_NULLPTR; +} + +static QList<QQuickStyle *> findChildStyles(const QMetaObject *type, QObject *object) +{ + QList<QQuickStyle *> children; + + QQuickItem *item = qobject_cast<QQuickItem *>(object); + if (!item) { + QQuickWindow *window = qobject_cast<QQuickWindow *>(object); + if (window) { + item = window->contentItem(); + + foreach (QObject *child, window->children()) { + QQuickWindow *childWindow = qobject_cast<QQuickWindow *>(child); + if (childWindow) { + QQuickStyle *style = attachedStyle(type, childWindow); + if (style) + children += style; + } + } + } + } + + if (item) { + foreach (QQuickItem *child, item->childItems()) { + QQuickStyle *style = attachedStyle(type, child); + if (style) + children += style; + else + children += findChildStyles(type, child); + } + } + + return children; +} + +QQuickStyle::QQuickStyle(QObject *parent) : QObject(parent) +{ + QQuickItem *item = qobject_cast<QQuickItem *>(parent); + if (item) + QQuickItemPrivate::get(item)->addItemChangeListener(this, QQuickItemPrivate::Parent); +} + +QQuickStyle::~QQuickStyle() +{ + QQuickItem *item = qobject_cast<QQuickItem *>(parent()); + if (item) + QQuickItemPrivate::get(item)->removeItemChangeListener(this, QQuickItemPrivate::Parent); + + setParentStyle(Q_NULLPTR); +} + +QList<QQuickStyle *> QQuickStyle::childStyles() const +{ + return m_childStyles; +} + +QQuickStyle *QQuickStyle::parentStyle() const +{ + return m_parentStyle; +} + +void QQuickStyle::setParentStyle(QQuickStyle *style) +{ + if (m_parentStyle != style) { + QQuickStyle *oldParent = m_parentStyle; + if (m_parentStyle) + m_parentStyle->m_childStyles.removeOne(this); + m_parentStyle = style; + if (style) + style->m_childStyles.append(this); + parentStyleChange(style, oldParent); + } +} + +void QQuickStyle::init() +{ + QQuickStyle *parentStyle = findParentStyle(metaObject(), parent()); + if (parentStyle) + setParentStyle(parentStyle); + + QList<QQuickStyle *> children = findChildStyles(metaObject(), parent()); + foreach (QQuickStyle *child, children) + child->setParentStyle(this); +} + +void QQuickStyle::parentStyleChange(QQuickStyle *newParent, QQuickStyle *oldParent) +{ + Q_UNUSED(newParent); + Q_UNUSED(oldParent); +} + +void QQuickStyle::itemParentChanged(QQuickItem *item, QQuickItem *parent) +{ + QQuickStyle *style = attachedStyle(metaObject(), item); + if (style) { + QQuickStyle *parentStyle = findParentStyle(metaObject(), parent); + if (parentStyle) + style->setParentStyle(parentStyle); + } +} + +QT_END_NAMESPACE diff --git a/src/controls/qquickstyle_p.h b/src/controls/qquickstyle_p.h new file mode 100644 index 00000000..3d4431cd --- /dev/null +++ b/src/controls/qquickstyle_p.h @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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 QQUICKSTYLE_P_H +#define QQUICKSTYLE_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 <QtQml/qqml.h> +#include <QtCore/qlist.h> +#include <QtCore/qobject.h> +#include <QtCore/qpointer.h> +#include <QtQuick/private/qquickitemchangelistener_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickStyle : public QObject, public QQuickItemChangeListener +{ + Q_OBJECT + +public: + explicit QQuickStyle(QObject *parent = Q_NULLPTR); + ~QQuickStyle(); + +protected: + void init(); + + QList<QQuickStyle *> childStyles() const; + + QQuickStyle *parentStyle() const; + void setParentStyle(QQuickStyle *style); + + virtual void parentStyleChange(QQuickStyle *newParent, QQuickStyle *oldParent); + + void itemParentChanged(QQuickItem *item, QQuickItem *parent) Q_DECL_OVERRIDE; + +private: + QList<QQuickStyle *> m_childStyles; + QPointer<QQuickStyle> m_parentStyle; +}; + +QT_END_NAMESPACE + +#endif // QQUICKSTYLE_P_H diff --git a/src/imports/controls/qquickfileselector.cpp b/src/controls/qquickstyleselector.cpp index bc09df9f..a84645d2 100644 --- a/src/imports/controls/qquickfileselector.cpp +++ b/src/controls/qquickstyleselector.cpp @@ -1,5 +1,6 @@ /*************************************************************************** ** +** Copyright (C) 2015 The Qt Company Ltd. ** Copyright (C) 2013 BlackBerry Limited. All rights reserved. ** Contact: http://www.qt.io/licensing/ ** @@ -31,8 +32,8 @@ ** ****************************************************************************/ -#include "qquickfileselector_p.h" -#include "qquickfileselector_p_p.h" +#include "qquickstyleselector_p.h" +#include "qquickstyleselector_p_p.h" #include <QtCore/QFile> #include <QtCore/QDir> @@ -43,31 +44,32 @@ #include <QtCore/QLocale> #include <QtCore/QDebug> -QT_BEGIN_NAMESPACE +#include <QtGui/private/qguiapplication_p.h> -//Environment variable to allow tooling full control of file selectors -static const char env_override[] = "QT_LABS_CONTROLS_NO_STYLE"; +QT_BEGIN_NAMESPACE -Q_GLOBAL_STATIC(QQuickFileSelectorSharedData, sharedData); +Q_GLOBAL_STATIC(QQuickStyleSelectorSharedData, sharedData); static QBasicMutex sharedDataMutex; -QQuickFileSelectorPrivate::QQuickFileSelectorPrivate() - : QObjectPrivate() +QQuickStyleSelectorPrivate::QQuickStyleSelectorPrivate() { } -QQuickFileSelector::QQuickFileSelector(QObject *parent) - : QObject(*(new QQuickFileSelectorPrivate()), parent) +QQuickStyleSelector::QQuickStyleSelector() : d_ptr(new QQuickStyleSelectorPrivate) { + Q_D(QQuickStyleSelector); + d->style = QGuiApplicationPrivate::styleOverride; + if (d->style.isEmpty()) + d->style = QString::fromLatin1(qgetenv("QT_LABS_CONTROLS_STYLE")); } -QQuickFileSelector::~QQuickFileSelector() +QQuickStyleSelector::~QQuickStyleSelector() { } -QString QQuickFileSelector::select(const QString &filePath) const +QString QQuickStyleSelector::select(const QString &filePath) const { - Q_D(const QQuickFileSelector); + Q_D(const QQuickStyleSelector); return select(QUrl(d->baseUrl.toString() + filePath)).toString(); } @@ -80,18 +82,18 @@ static bool isLocalScheme(const QString &file) return local; } -QUrl QQuickFileSelector::select(const QUrl &filePath) const +QUrl QQuickStyleSelector::select(const QUrl &filePath) const { - Q_D(const QQuickFileSelector); + Q_D(const QQuickStyleSelector); if (!isLocalScheme(filePath.scheme()) && !filePath.isLocalFile()) return filePath; QUrl ret(filePath); if (isLocalScheme(filePath.scheme())) { QString equivalentPath = QLatin1Char(':') + filePath.path(); - QString selectedPath = d->select(equivalentPath); + QString selectedPath = d->select(equivalentPath, allSelectors()); ret.setPath(selectedPath.remove(0, 1)); } else { - ret = QUrl::fromLocalFile(d->select(ret.toLocalFile())); + ret = QUrl::fromLocalFile(d->select(ret.toLocalFile(), allSelectors())); } return ret; } @@ -122,69 +124,65 @@ static QString selectionHelper(const QString &path, const QString &fileName, con return path + fileName; } -QString QQuickFileSelectorPrivate::select(const QString &filePath) const +QString QQuickStyleSelectorPrivate::select(const QString &filePath, const QStringList &allSelectors) const { - Q_Q(const QQuickFileSelector); QFileInfo fi(filePath); // If file doesn't exist, don't select if (!fi.exists()) return filePath; QString ret = selectionHelper(fi.path().isEmpty() ? QString() : fi.path() + QLatin1Char('/'), - fi.fileName(), q->allSelectors()); + fi.fileName(), allSelectors); if (!ret.isEmpty()) return ret; return filePath; } -QString QQuickFileSelector::style() const +QString QQuickStyleSelector::style() const { - Q_D(const QQuickFileSelector); + Q_D(const QQuickStyleSelector); return d->style; } -void QQuickFileSelector::setStyle(const QString &s) +void QQuickStyleSelector::setStyle(const QString &s) { - Q_D(QQuickFileSelector); + Q_D(QQuickStyleSelector); d->style = s; } -QStringList QQuickFileSelector::allSelectors() const +QStringList QQuickStyleSelector::allSelectors() const { - Q_D(const QQuickFileSelector); + Q_D(const QQuickStyleSelector); QMutexLocker locker(&sharedDataMutex); - QQuickFileSelectorPrivate::updateSelectors(); + QQuickStyleSelectorPrivate::updateSelectors(); return QStringList(d->style) + sharedData->staticSelectors; } -void QQuickFileSelector::setBaseUrl(const QUrl &base) +void QQuickStyleSelector::setBaseUrl(const QUrl &base) { - Q_D(QQuickFileSelector); + Q_D(QQuickStyleSelector); if (d->baseUrl != base) d->baseUrl = base; } -QUrl QQuickFileSelector::baseUrl() const +QUrl QQuickStyleSelector::baseUrl() const { - Q_D(const QQuickFileSelector); + Q_D(const QQuickStyleSelector); return d->baseUrl; } -void QQuickFileSelectorPrivate::updateSelectors() +QQuickStyleSelector *QQuickStyleSelector::instance() +{ + static QQuickStyleSelector self; + return &self; +} + +void QQuickStyleSelectorPrivate::updateSelectors() { if (!sharedData->staticSelectors.isEmpty()) return; //Already loaded - QLatin1Char pathSep(','); - QStringList envSelectors = QString::fromLatin1(qgetenv("QT_LABS_CONTROLS_STYLE")) - .split(pathSep, QString::SkipEmptyParts); - if (envSelectors.count()) - sharedData->staticSelectors << envSelectors; - - if (!qEnvironmentVariableIsEmpty(env_override)) - return; - sharedData->staticSelectors << sharedData->preloadedStatics; //Potential for static selectors from other modules // TODO: Update on locale changed? @@ -193,7 +191,7 @@ void QQuickFileSelectorPrivate::updateSelectors() sharedData->staticSelectors << platformSelectors(); } -QStringList QQuickFileSelectorPrivate::platformSelectors() +QStringList QQuickStyleSelectorPrivate::platformSelectors() { // similar, but not identical to QSysInfo::osType QStringList ret; @@ -223,12 +221,10 @@ QStringList QQuickFileSelectorPrivate::platformSelectors() return ret; } -void QQuickFileSelectorPrivate::addStatics(const QStringList &statics) +void QQuickStyleSelectorPrivate::addStatics(const QStringList &statics) { QMutexLocker locker(&sharedDataMutex); sharedData->preloadedStatics << statics; } QT_END_NAMESPACE - -#include "moc_qquickfileselector_p.cpp" diff --git a/src/imports/controls/qquickfileselector_p.h b/src/controls/qquickstyleselector_p.h index ed1cd7d5..36ccf07c 100644 --- a/src/imports/controls/qquickfileselector_p.h +++ b/src/controls/qquickstyleselector_p.h @@ -1,5 +1,6 @@ /*************************************************************************** ** +** Copyright (C) 2015 The Qt Company Ltd. ** Copyright (C) 2013 BlackBerry Limited. All rights reserved. ** Contact: http://www.qt.io/licensing/ ** @@ -31,8 +32,8 @@ ** ****************************************************************************/ -#ifndef QFILESELECTOR_H -#define QFILESELECTOR_H +#ifndef QQUICKSTYLESELECTOR_P_H +#define QQUICKSTYLESELECTOR_P_H // // W A R N I N G @@ -45,18 +46,18 @@ // We mean it. // -#include <QtCore/QObject> -#include <QtCore/QStringList> +#include <QtCore/qurl.h> +#include <QtCore/qstringlist.h> +#include <QtCore/qscopedpointer.h> QT_BEGIN_NAMESPACE -class QQuickFileSelectorPrivate; -class QQuickFileSelector : public QObject +class QQuickStyleSelectorPrivate; +class QQuickStyleSelector { - Q_OBJECT public: - explicit QQuickFileSelector(QObject *parent = Q_NULLPTR); - ~QQuickFileSelector(); + explicit QQuickStyleSelector(); + ~QQuickStyleSelector(); QString select(const QString &filePath) const; @@ -68,12 +69,15 @@ public: void setBaseUrl(const QUrl &base); QUrl baseUrl() const; + static QQuickStyleSelector *instance(); + private: QUrl select(const QUrl &filePath) const; - Q_DECLARE_PRIVATE(QQuickFileSelector) + Q_DECLARE_PRIVATE(QQuickStyleSelector) + QScopedPointer<QQuickStyleSelectorPrivate> d_ptr; }; QT_END_NAMESPACE -#endif +#endif // QQUICKSTYLESELECTOR_P_H diff --git a/src/imports/controls/qquickfileselector_p_p.h b/src/controls/qquickstyleselector_p_p.h index eb849554..b0de326b 100644 --- a/src/imports/controls/qquickfileselector_p_p.h +++ b/src/controls/qquickstyleselector_p_p.h @@ -1,5 +1,6 @@ /*************************************************************************** ** +** Copyright (C) 2015 The Qt Company Ltd. ** Copyright (C) 2013 BlackBerry Limited. All rights reserved. ** Contact: http://www.qt.io/licensing/ ** @@ -31,8 +32,8 @@ ** ****************************************************************************/ -#ifndef QFILESELECTOR_P_H -#define QFILESELECTOR_P_H +#ifndef QQUICKSTYLESELECTOR_P_P_H +#define QQUICKSTYLESELECTOR_P_P_H // // W A R N I N G @@ -49,25 +50,24 @@ #include <QtCore/QUrl> #include <private/qobject_p.h> -#include "qquickfileselector_p.h" +#include "qquickstyleselector_p.h" QT_BEGIN_NAMESPACE -struct QQuickFileSelectorSharedData //Not QSharedData because currently is just a global store +struct QQuickStyleSelectorSharedData //Not QSharedData because currently is just a global store { QStringList staticSelectors; QStringList preloadedStatics; }; -class QQuickFileSelectorPrivate : QObjectPrivate //Exported for use in other modules (like QtGui) +class QQuickStyleSelectorPrivate { - Q_DECLARE_PUBLIC(QQuickFileSelector) public: static void updateSelectors(); static QStringList platformSelectors(); static void addStatics(const QStringList &); //For loading GUI statics from other Qt modules - QQuickFileSelectorPrivate(); - QString select(const QString &filePath) const; + QQuickStyleSelectorPrivate(); + QString select(const QString &filePath, const QStringList &allSelectors) const; QString style; QUrl baseUrl; @@ -75,5 +75,5 @@ public: QT_END_NAMESPACE -#endif +#endif // QQUICKSTYLESELECTOR_P_P_H diff --git a/src/imports/calendar/calendar.pro b/src/imports/calendar/calendar.pro index ff71c324..0dee3cb1 100644 --- a/src/imports/calendar/calendar.pro +++ b/src/imports/calendar/calendar.pro @@ -1,14 +1,12 @@ -TARGET = qtlabscalendarplugin +TARGET = qtlabscalendarplugin TARGETPATH = Qt/labs/calendar IMPORT_VERSION = 1.0 QT += qml quick -QT += core-private gui-private qml-private quick-private labstemplates-private +QT_PRIVATE += core-private gui-private qml-private quick-private labstemplates-private DEFINES += QT_NO_CAST_TO_ASCII QT_NO_CAST_FROM_ASCII -INCLUDEPATH += $$PWD - OTHER_FILES += \ qmldir diff --git a/src/imports/controls/ApplicationWindow.qml b/src/imports/controls/ApplicationWindow.qml index cb918b84..247752cb 100644 --- a/src/imports/controls/ApplicationWindow.qml +++ b/src/imports/controls/ApplicationWindow.qml @@ -36,11 +36,10 @@ import QtQuick 2.6 import QtQuick.Window 2.2 -import Qt.labs.controls 1.0 import Qt.labs.templates 1.0 as T T.ApplicationWindow { id: window - color: Theme.backgroundColor + color: "#ffffff" } diff --git a/src/imports/controls/Button.qml b/src/imports/controls/Button.qml index 82fe82b4..cc7a65b8 100644 --- a/src/imports/controls/Button.qml +++ b/src/imports/controls/Button.qml @@ -35,7 +35,6 @@ ****************************************************************************/ import QtQuick 2.6 -import Qt.labs.controls 1.0 import Qt.labs.templates 1.0 as T T.Button { @@ -45,6 +44,7 @@ T.Button { label ? label.implicitWidth + leftPadding + rightPadding : 0) implicitHeight: Math.max(background ? background.implicitHeight : 0, label ? label.implicitHeight + topPadding + bottomPadding : 0) + baselineOffset: label ? label.y + label.baselineOffset : 0 padding: 6 leftPadding: 8 @@ -56,10 +56,9 @@ T.Button { y: control.topPadding width: control.availableWidth height: control.availableHeight - text: control.text font: control.font - color: control.Theme.selectedTextColor + color: control.highlighted ? "#ffffff" : (control.pressed ? "#26282a" : "#353637") horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter elide: Text.ElideRight @@ -68,14 +67,10 @@ T.Button { //! [background] background: Rectangle { - implicitWidth: 36 - implicitHeight: 36 - - radius: 3 - color: Qt.darker(Qt.tint(!control.enabled ? control.Theme.disabledColor : - control.activeFocus ? control.Theme.focusColor : control.Theme.accentColor, - control.pressed ? control.Theme.pressColor : "transparent"), - control.checkable && control.checked ? 1.5 : 1.0) + implicitWidth: 100 + implicitHeight: 40 + color: control.pressed ? (control.highlighted ? "#585a5c" : "#bdbebf") : (control.highlighted ? "#353637" : "#ffffff") + border.color: control.pressed ? "#26282a" : "#353637" } //! [background] } diff --git a/src/imports/controls/CheckBox.qml b/src/imports/controls/CheckBox.qml index 565187a4..5bfddbf3 100644 --- a/src/imports/controls/CheckBox.qml +++ b/src/imports/controls/CheckBox.qml @@ -35,7 +35,6 @@ ****************************************************************************/ import QtQuick 2.6 -import Qt.labs.controls 1.0 import Qt.labs.templates 1.0 as T T.CheckBox { @@ -48,34 +47,27 @@ T.CheckBox { implicitHeight: Math.max(background ? background.implicitHeight : 0, Math.max(label ? label.implicitHeight : 0, indicator ? indicator.implicitHeight : 0) + topPadding + bottomPadding) + baselineOffset: label ? label.y + label.baselineOffset : 0 padding: 6 spacing: 6 + opacity: enabled ? 1 : 0.2 //! [indicator] indicator: Rectangle { - implicitWidth: 20 - implicitHeight: 20 + implicitWidth: 28 + implicitHeight: 28 x: text ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) : control.leftPadding + (control.availableWidth - width) / 2 y: control.topPadding + (control.availableHeight - height) / 2 - radius: 3 - border.width: control.activeFocus ? 2 : 1 - border.color: control.activeFocus ? control.Theme.focusColor : control.Theme.frameColor - color: control.Theme.backgroundColor + color: control.enabled ? (control.pressed ? "#bdbebf" : "#ffffff") : "#353637" + border.color: control.enabled ? (control.pressed ? "#26282a" : "#353637") : "transparent" - Rectangle { + Image { x: (parent.width - width) / 2 y: (parent.height - height) / 2 - width: 12 - height: 12 - opacity: control.tristate && control.checkState === Qt.PartiallyChecked ? 0.5 : 1.0 - color: Qt.tint(control.checked && !control.enabled ? control.Theme.disabledColor : - control.checked && control.activeFocus ? control.Theme.focusColor : - control.checked ? control.Theme.accentColor : control.Theme.baseColor, - control.pressed ? control.Theme.pressColor : "transparent") - border.width: control.checked || control.pressed ? 0 : 1 - border.color: control.Theme.frameColor + source: "qrc:/images/check.png" + visible: control.checked } } //! [indicator] @@ -89,7 +81,7 @@ T.CheckBox { text: control.text font: control.font - color: control.enabled ? control.Theme.textColor : control.Theme.disabledColor + color: control.pressed ? "#26282a" : "#353637" elide: Text.ElideRight visible: control.text horizontalAlignment: Text.AlignLeft diff --git a/src/imports/controls/Dial.qml b/src/imports/controls/Dial.qml index 378a9339..951d33ec 100644 --- a/src/imports/controls/Dial.qml +++ b/src/imports/controls/Dial.qml @@ -35,33 +35,41 @@ ****************************************************************************/ import QtQuick 2.6 -import Qt.labs.controls 1.0 import Qt.labs.templates 1.0 as T T.Dial { id: control - implicitWidth: 100 - implicitHeight: 100 + implicitWidth: 184 + implicitHeight: 184 //! [background] background: Rectangle { - color: control.Theme.backgroundColor radius: width / 2 + border.color: "#353637" - border.color: control.activeFocus ? control.Theme.focusColor : control.Theme.frameColor + Text { + text: control.position.toFixed(1) + color: "#353637" + font.pixelSize: 60 + x: parent.width / 2 - width / 2 + y: parent.height / 2 - height / 2 + } } //! [background] //! [handle] - handle: Rectangle { + handle: Image { id: handleItem - x: background.width / 2 - handle.width / 2 y: background.height / 2 - handle.height / 2 + width: 14 + height: 10 + source: "qrc:/images/dial-indicator.png" + antialiasing: true transform: [ Translate { - y: -background.height * 0.35 + y: -background.height * 0.4 }, Rotation { angle: control.angle @@ -69,12 +77,6 @@ T.Dial { origin.y: handle.height / 2 } ] - implicitWidth: 20 - implicitHeight: 20 - radius: width / 2 - border.width: control.activeFocus ? 2 : 1 - border.color: control.activeFocus ? control.Theme.focusColor : control.Theme.frameColor - color: control.Theme.baseColor } //! [handle] } diff --git a/src/imports/controls/Drawer.qml b/src/imports/controls/Drawer.qml index 5cf0994a..2b50b7d4 100644 --- a/src/imports/controls/Drawer.qml +++ b/src/imports/controls/Drawer.qml @@ -35,7 +35,6 @@ ****************************************************************************/ import QtQuick 2.6 -import Qt.labs.controls 1.0 import Qt.labs.templates 1.0 as T T.Drawer { @@ -46,7 +45,7 @@ T.Drawer { //! [background] background: Rectangle { - color: control.Theme.shadowColor + color: "#28282a" opacity: position * 0.75 } //! [background] diff --git a/src/imports/controls/Frame.qml b/src/imports/controls/Frame.qml index 2d72acb5..18592b1c 100644 --- a/src/imports/controls/Frame.qml +++ b/src/imports/controls/Frame.qml @@ -35,7 +35,6 @@ ****************************************************************************/ import QtQuick 2.6 -import Qt.labs.controls 1.0 import Qt.labs.templates 1.0 as T T.Frame { @@ -58,9 +57,8 @@ T.Frame { width: parent.width height: parent.height - radius: 3 color: "transparent" - border.color: control.Theme.frameColor + border.color: "#bdbebf" } //! [frame] } diff --git a/src/imports/controls/GroupBox.qml b/src/imports/controls/GroupBox.qml index c7e93c63..8504fae9 100644 --- a/src/imports/controls/GroupBox.qml +++ b/src/imports/controls/GroupBox.qml @@ -35,7 +35,6 @@ ****************************************************************************/ import QtQuick 2.6 -import Qt.labs.controls 1.0 import Qt.labs.templates 1.0 as T T.GroupBox { @@ -62,7 +61,7 @@ T.GroupBox { text: control.title font: control.font - color: control.enabled ? control.Theme.textColor : control.Theme.disabledColor + color: control.enabled ? "#353637" : "#bdbebf" elide: Text.ElideRight horizontalAlignment: Text.AlignLeft verticalAlignment: Text.AlignVCenter @@ -75,9 +74,8 @@ T.GroupBox { width: parent.width height: parent.height - control.topPadding + control.padding - radius: 3 color: "transparent" - border.color: control.Theme.frameColor + border.color: "#bdbebf" } //! [frame] } diff --git a/src/imports/controls/ItemDelegate.qml b/src/imports/controls/ItemDelegate.qml new file mode 100644 index 00000000..5735d0b3 --- /dev/null +++ b/src/imports/controls/ItemDelegate.qml @@ -0,0 +1,88 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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$ +** +****************************************************************************/ + +import QtQuick 2.6 +import Qt.labs.templates 1.0 as T + +T.ItemDelegate { + id: control + + implicitWidth: Math.max(background ? background.implicitWidth : 0, + (label ? label.implicitWidth : 0) + + (indicator ? indicator.implicitWidth : 0) + + (label && indicator ? spacing : 0) + leftPadding + rightPadding) + implicitHeight: Math.max(background ? background.implicitHeight : 0, + Math.max(label ? label.implicitHeight : 0, + indicator ? indicator.implicitHeight : 0) + topPadding + bottomPadding) + + padding: 12 + spacing: 12 + + //! [label] + label: Text { + x: control.mirrored ? control.width - width - control.rightPadding : control.leftPadding + y: control.topPadding + width: control.availableWidth - (control.checkable ? indicator.width + control.spacing : 0) + height: control.availableHeight + + text: control.text + font: control.font + color: control.enabled ? "#26282a" : "#bdbebf" + elide: Text.ElideRight + visible: control.text + horizontalAlignment: Text.AlignLeft + verticalAlignment: Text.AlignVCenter + } + //! [label] + + //! [indicator] + indicator: Image { + x: control.mirrored ? control.leftPadding : control.width - width - control.rightPadding + y: control.topPadding + (control.availableHeight - height) / 2 + + visible: control.checked + source: control.checkable ? "qrc:/images/check.png" : "" + } + //! [indicator] + + //! [background] + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + color: control.pressed ? "#bdbebf" : "transparent" + } + //! [background] +} diff --git a/src/imports/controls/Label.qml b/src/imports/controls/Label.qml index 82b2c629..1047bfaa 100644 --- a/src/imports/controls/Label.qml +++ b/src/imports/controls/Label.qml @@ -35,12 +35,11 @@ ****************************************************************************/ import QtQuick 2.6 -import Qt.labs.controls 1.0 import Qt.labs.templates 1.0 as T T.Label { id: control - color: Theme.textColor - linkColor: Theme.focusColor // TODO + color: "#26282a" + linkColor: "#45a7d7" // TODO } diff --git a/src/imports/controls/Menu.qml b/src/imports/controls/Menu.qml new file mode 100644 index 00000000..f4a4243e --- /dev/null +++ b/src/imports/controls/Menu.qml @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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$ +** +****************************************************************************/ + +import QtQuick 2.6 +import Qt.labs.controls 1.0 +import Qt.labs.templates 1.0 as T + +T.Menu { + id: control + + //! [contentItem] + contentItem: ListView { + implicitWidth: 200 + implicitHeight: Math.min(contentHeight, 200) + model: control.contentModel + // TODO: improve this? + interactive: ApplicationWindow.window ? contentHeight > ApplicationWindow.window.height : false + clip: true + keyNavigationWraps: false + currentIndex: -1 + + ScrollIndicator.vertical: ScrollIndicator {} + + Rectangle { + width: parent.width + height: parent.height + color: "#ffffff" + border.color: "#353637" + z: -1 + } + } + //! [contentItem] +} diff --git a/src/imports/controls/MenuItem.qml b/src/imports/controls/MenuItem.qml new file mode 100644 index 00000000..df51fc72 --- /dev/null +++ b/src/imports/controls/MenuItem.qml @@ -0,0 +1,93 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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$ +** +****************************************************************************/ + +import QtQuick 2.6 +import Qt.labs.templates 1.0 as T + +T.MenuItem { + id: control + + implicitWidth: background ? background.implicitWidth + : (label ? label.implicitWidth : 0) + (indicator ? indicator.implicitWidth : 0) + + (label && indicator ? spacing : 0) + leftPadding + rightPadding + implicitHeight: background ? background.implicitHeight + : (label ? label.implicitHeight : 0) + (indicator ? indicator.implicitHeight : 0) + topPadding + bottomPadding + + padding: 12 + spacing: 12 + + //! [label] + label: Text { + x: control.mirrored ? control.width - width - control.rightPadding : control.leftPadding + y: control.topPadding + width: control.availableWidth - (control.checkable ? indicator.width + control.spacing : 0) + height: control.availableHeight + + text: control.text + font: control.font + color: control.enabled ? "#26282a" : "#bdbebf" + elide: Text.ElideRight + visible: control.text + horizontalAlignment: Text.AlignLeft + verticalAlignment: Text.AlignVCenter + } + //! [label] + + //! [indicator] + indicator: Image { + x: control.mirrored ? control.leftPadding : control.width - width - control.rightPadding + y: control.topPadding + (control.availableHeight - height) / 2 + + visible: control.checked + source: control.checkable ? "qrc:/images/check.png" : "" + } + //! [indicator] + + //! [background] + background: Item { + implicitWidth: 200 + implicitHeight: 40 + + Rectangle { + x: 1 + y: 1 + width: parent.width - 2 + height: parent.height - 2 + color: control.activeFocus || control.pressed ? "#eeeeee" : "transparent" + } + } + //! [background] +} diff --git a/src/imports/controls/PageIndicator.qml b/src/imports/controls/PageIndicator.qml index e1361b83..e569a0de 100644 --- a/src/imports/controls/PageIndicator.qml +++ b/src/imports/controls/PageIndicator.qml @@ -35,7 +35,6 @@ ****************************************************************************/ import QtQuick 2.6 -import Qt.labs.controls 1.0 import Qt.labs.templates 1.0 as T T.PageIndicator { @@ -55,7 +54,7 @@ T.PageIndicator { implicitHeight: 8 radius: width / 2 - color: control.Theme.shadowColor // TODO + color: "#28282a" // TODO opacity: index === currentIndex ? 0.95 : pressed ? 0.7 : 0.45 Behavior on opacity { OpacityAnimator { duration: 100 } } diff --git a/src/imports/controls/ProgressBar.qml b/src/imports/controls/ProgressBar.qml index 6fb5f515..61e35921 100644 --- a/src/imports/controls/ProgressBar.qml +++ b/src/imports/controls/ProgressBar.qml @@ -35,7 +35,6 @@ ****************************************************************************/ import QtQuick 2.6 -import Qt.labs.controls 1.0 import Qt.labs.templates 1.0 as T T.ProgressBar { @@ -69,7 +68,7 @@ T.ProgressBar { height: 2 radius: 3 - color: control.enabled ? control.Theme.accentColor : control.Theme.disabledColor + color: control.enabled ? "#353637" : "#bdbebf" SequentialAnimation on offset { loops: Animation.Infinite @@ -98,7 +97,7 @@ T.ProgressBar { height: 6 radius: 3 - border.color: control.Theme.frameColor + border.color: "#bdbebf" color: "transparent" } //! [background] diff --git a/src/imports/controls/RadioButton.qml b/src/imports/controls/RadioButton.qml index 0c4d0edd..e41d2d11 100644 --- a/src/imports/controls/RadioButton.qml +++ b/src/imports/controls/RadioButton.qml @@ -48,34 +48,32 @@ T.RadioButton { implicitHeight: Math.max(background ? background.implicitHeight : 0, Math.max(label ? label.implicitHeight : 0, indicator ? indicator.implicitHeight : 0) + topPadding + bottomPadding) + baselineOffset: label ? label.y + label.baselineOffset : 0 padding: 6 spacing: 6 + opacity: enabled ? 1 : 0.2 //! [indicator] indicator: Rectangle { - implicitWidth: 20 - implicitHeight: 20 + implicitWidth: 28 + implicitHeight: 28 x: text ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) : control.leftPadding + (control.availableWidth - width) / 2 y: control.topPadding + (control.availableHeight - height) / 2 radius: width / 2 - border.width: control.activeFocus ? 2 : 1 - border.color: control.activeFocus ? control.Theme.focusColor : control.Theme.frameColor - color: control.Theme.backgroundColor + border.width: 1 + border.color: (control.pressed ? "#26282a" : "#353637") + color: control.pressed ? "#bdbebf" : "#ffffff" Rectangle { x: (parent.width - width) / 2 y: (parent.height - height) / 2 - width: 12 - height: 12 + width: 20 + height: 20 radius: width / 2 - color: Qt.tint(control.checked && !control.enabled ? control.Theme.disabledColor : - control.checked && control.activeFocus ? control.Theme.focusColor : - control.checked ? control.Theme.accentColor : control.Theme.baseColor, - control.pressed ? control.Theme.pressColor : "transparent") - border.width: control.checked || control.pressed ? 0 : 1 - border.color: control.Theme.frameColor + color: control.pressed ? "#26282a" : "#353637" + visible: control.checked } } //! [indicator] @@ -89,7 +87,7 @@ T.RadioButton { text: control.text font: control.font - color: control.enabled ? control.Theme.textColor : control.Theme.disabledColor + color: control.pressed ? "#26282a" : "#353637" elide: Text.ElideRight visible: control.text horizontalAlignment: Text.AlignLeft diff --git a/src/imports/controls/RangeSlider.qml b/src/imports/controls/RangeSlider.qml index e301eed2..9a74d4c8 100644 --- a/src/imports/controls/RangeSlider.qml +++ b/src/imports/controls/RangeSlider.qml @@ -35,7 +35,6 @@ ****************************************************************************/ import QtQuick 2.6 -import Qt.labs.controls 1.0 import Qt.labs.templates 1.0 as T T.RangeSlider { @@ -56,26 +55,14 @@ T.RangeSlider { first.handle: Rectangle { x: control.leftPadding + (horizontal ? control.first.visualPosition * (control.availableWidth - width) : (control.availableWidth - width) / 2) y: control.topPadding + (horizontal ? (control.availableHeight - height) / 2 : control.first.visualPosition * (control.availableHeight - height)) - implicitWidth: 20 - implicitHeight: 20 + implicitWidth: 28 + implicitHeight: 28 radius: width / 2 border.width: activeFocus ? 2 : 1 - border.color: activeFocus ? control.Theme.focusColor : control.Theme.frameColor - color: control.Theme.backgroundColor + border.color: "#353637" + color: first.pressed ? "#bdbebf" : "#ffffff" readonly property bool horizontal: control.orientation === Qt.Horizontal - - Rectangle { - x: (parent.width - width) / 2 - y: (parent.height - height) / 2 - width: 12 - height: 12 - radius: width / 2 - - color: Qt.tint(!control.enabled ? control.Theme.disabledColor : - parent.activeFocus ? control.Theme.focusColor : control.Theme.accentColor, - control.first.pressed ? control.Theme.pressColor : "transparent") - } } //! [firstHandle] @@ -83,26 +70,14 @@ T.RangeSlider { second.handle: Rectangle { x: control.leftPadding + (horizontal ? control.second.visualPosition * (control.availableWidth - width) : (control.availableWidth - width) / 2) y: control.topPadding + (horizontal ? (control.availableHeight - height) / 2 : control.second.visualPosition * (control.availableHeight - height)) - implicitWidth: 20 - implicitHeight: 20 + implicitWidth: 28 + implicitHeight: 28 radius: width / 2 border.width: activeFocus ? 2 : 1 - border.color: activeFocus ? control.Theme.focusColor : control.Theme.frameColor - color: control.Theme.backgroundColor + border.color: "#353637" + color: second.pressed ? "#bdbebf" : "#ffffff" readonly property bool horizontal: control.orientation === Qt.Horizontal - - Rectangle { - x: (parent.width - width) / 2 - y: (parent.height - height) / 2 - width: 12 - height: 12 - radius: width / 2 - - color: Qt.tint(!control.enabled ? control.Theme.disabledColor : - parent.activeFocus ? control.Theme.focusColor : control.Theme.accentColor, - control.second.pressed ? control.Theme.pressColor : "transparent") - } } //! [secondHandle] @@ -114,23 +89,12 @@ T.RangeSlider { implicitHeight: horizontal ? 6 : 200 width: horizontal ? control.availableWidth : implicitWidth height: horizontal ? implicitHeight : control.availableHeight - - readonly property bool horizontal: control.orientation === Qt.Horizontal - radius: 3 - border.color: control.Theme.frameColor - color: control.Theme.backgroundColor + border.color: "#353637" + color: "#ffffff" scale: horizontal && control.mirrored ? -1 : 1 - Rectangle { - x: parent.horizontal ? control.first.position * parent.width : 2 - y: parent.horizontal ? 2 : control.second.visualPosition * parent.height + 2 - width: parent.horizontal ? control.second.position * parent.width - control.first.position * parent.width - 4 : 2 - height: parent.horizontal ? 2 : control.second.position * parent.height - control.first.position * parent.height - 4 - - radius: 3 - color: control.enabled ? control.Theme.accentColor : control.Theme.disabledColor - } + readonly property bool horizontal: control.orientation === Qt.Horizontal } //! [track] } diff --git a/src/imports/controls/ScrollBar.qml b/src/imports/controls/ScrollBar.qml index d1a45a71..55d53191 100644 --- a/src/imports/controls/ScrollBar.qml +++ b/src/imports/controls/ScrollBar.qml @@ -35,7 +35,6 @@ ****************************************************************************/ import QtQuick 2.6 -import Qt.labs.controls 1.0 import Qt.labs.templates 1.0 as T T.ScrollBar { @@ -56,7 +55,7 @@ T.ScrollBar { implicitHeight: 6 radius: width / 2 - color: control.pressed ? control.Theme.shadowColor : control.Theme.frameColor + color: control.pressed ? "#28282a" : "#bdbebf" visible: control.size < 1.0 opacity: 0.0 diff --git a/src/imports/controls/ScrollIndicator.qml b/src/imports/controls/ScrollIndicator.qml index 8c4fc1d5..e2fc23b1 100644 --- a/src/imports/controls/ScrollIndicator.qml +++ b/src/imports/controls/ScrollIndicator.qml @@ -35,7 +35,6 @@ ****************************************************************************/ import QtQuick 2.6 -import Qt.labs.controls 1.0 import Qt.labs.templates 1.0 as T T.ScrollIndicator { @@ -55,7 +54,7 @@ T.ScrollIndicator { implicitWidth: 2 implicitHeight: 2 - color: control.Theme.frameColor + color: "#bdbebf" visible: control.size < 1.0 opacity: 0.0 diff --git a/src/imports/controls/Slider.qml b/src/imports/controls/Slider.qml index c1309d5a..250dbd3a 100644 --- a/src/imports/controls/Slider.qml +++ b/src/imports/controls/Slider.qml @@ -35,7 +35,6 @@ ****************************************************************************/ import QtQuick 2.6 -import Qt.labs.controls 1.0 import Qt.labs.templates 1.0 as T T.Slider { @@ -52,56 +51,32 @@ T.Slider { //! [handle] handle: Rectangle { - implicitWidth: 20 - implicitHeight: 20 - radius: width / 2 - border.width: control.activeFocus ? 2 : 1 - border.color: control.activeFocus ? control.Theme.focusColor : control.Theme.frameColor - color: control.Theme.backgroundColor - - readonly property bool horizontal: control.orientation === Qt.Horizontal x: control.leftPadding + (horizontal ? control.visualPosition * (control.availableWidth - width) : (control.availableWidth - width) / 2) y: control.topPadding + (horizontal ? (control.availableHeight - height) / 2 : control.visualPosition * (control.availableHeight - height)) + implicitWidth: 28 + implicitHeight: 28 + radius: width / 2 + border.color: "#353637" + color: control.pressed ? "#bdbebf" : "#ffffff" - Rectangle { - x: (parent.width - width) / 2 - y: (parent.height - height) / 2 - width: 12 - height: 12 - radius: width / 2 - - color: Qt.tint(!control.enabled ? control.Theme.disabledColor : - control.activeFocus ? control.Theme.focusColor : control.Theme.accentColor, - control.pressed ? control.Theme.pressColor : "transparent") - } + readonly property bool horizontal: control.orientation === Qt.Horizontal } //! [handle] //! [track] track: Rectangle { - readonly property bool horizontal: control.orientation === Qt.Horizontal - - implicitWidth: horizontal ? 200 : 6 - implicitHeight: horizontal ? 6 : 200 x: control.leftPadding + (horizontal ? 0 : (control.availableWidth - width) / 2) y: control.topPadding + (horizontal ? (control.availableHeight - height) / 2 : 0) + implicitWidth: horizontal ? 200 : 6 + implicitHeight: horizontal ? 6 : 200 width: horizontal ? control.availableWidth : implicitWidth height: horizontal ? implicitHeight : control.availableHeight - radius: 3 - border.color: control.Theme.frameColor - color: control.Theme.backgroundColor + border.color: "#353637" + color: "#ffffff" scale: horizontal && control.mirrored ? -1 : 1 - Rectangle { - x: 2 - y: parent.horizontal ? 2 : control.visualPosition * parent.height + 2 - width: parent.horizontal ? control.position * parent.width - 4 : 2 - height: parent.horizontal ? 2 : control.position * parent.height - 4 - - radius: 3 - color: control.enabled ? control.Theme.accentColor : control.Theme.disabledColor - } + readonly property bool horizontal: control.orientation === Qt.Horizontal } //! [track] } diff --git a/src/imports/controls/SpinBox.qml b/src/imports/controls/SpinBox.qml index 5aeebe78..ff27d8ba 100644 --- a/src/imports/controls/SpinBox.qml +++ b/src/imports/controls/SpinBox.qml @@ -35,7 +35,6 @@ ****************************************************************************/ import QtQuick 2.6 -import Qt.labs.controls 1.0 import Qt.labs.templates 1.0 as T T.SpinBox { @@ -53,6 +52,7 @@ T.SpinBox { padding: 6 leftPadding: 6 + (control.mirrored ? (up.indicator ? up.indicator.width : 0) : (down.indicator ? down.indicator.width : 0)) rightPadding: 6 + (control.mirrored ? (down.indicator ? down.indicator.width : 0) : (up.indicator ? up.indicator.width : 0)) + opacity: control.enabled ? 1 : 0.3 //! [validator] validator: IntValidator { @@ -67,9 +67,9 @@ T.SpinBox { text: control.textFromValue(control.value, control.locale) font: control.font - color: control.Theme.textColor - selectionColor: control.Theme.selectionColor - selectedTextColor: control.Theme.selectedTextColor + color: control.enabled ? "#353637" : "#bdbebf" +// selectionColor: TODO +// selectedTextColor: TODO horizontalAlignment: Qt.AlignHCenter verticalAlignment: Qt.AlignVCenter @@ -79,69 +79,52 @@ T.SpinBox { //! [contentItem] //! [up.indicator] - up.indicator: Item { - implicitWidth: 26 - height: parent.height + up.indicator: Rectangle { x: control.mirrored ? 0 : parent.width - width + implicitWidth: 40 + implicitHeight: 40 + color: up.pressed ? "#bdbebf" : "#ffffff" + border.color: control.enabled ? "#353637" : "#bdbebf" - clip: true - Rectangle { - x: -radius - width: parent.width + radius - height: parent.height - radius: 3 - color: Qt.tint(Qt.tint(control.Theme.accentColor, - control.activeFocus ? control.Theme.focusColor : "transparent"), - control.up.pressed ? control.Theme.pressColor : "transparent") - } Rectangle { x: (parent.width - width) / 2 y: (parent.height - height) / 2 width: parent.width / 3 height: 2 - color: control.Theme.selectedTextColor + color: control.enabled ? "#353637" : "#bdbebf" } Rectangle { x: (parent.width - width) / 2 y: (parent.height - height) / 2 width: 2 height: parent.height / 3 - color: control.Theme.selectedTextColor + color: control.enabled ? "#353637" : "#bdbebf" } } //! [up.indicator] //! [down.indicator] - down.indicator: Item { - implicitWidth: 26 - height: parent.height + down.indicator: Rectangle { x: control.mirrored ? parent.width - width : 0 + implicitWidth: 40 + implicitHeight: 40 + color: down.pressed ? "#bdbebf" : "#ffffff" + border.color: control.enabled ? "#353637" : "#bdbebf" - clip: true - Rectangle { - width: parent.width + radius - height: parent.height - radius: 3 - color: Qt.tint(Qt.tint(control.Theme.accentColor, - control.activeFocus ? control.Theme.focusColor : "transparent"), - control.down.pressed ? control.Theme.pressColor : "transparent") - } Rectangle { x: (parent.width - width) / 2 y: (parent.height - height) / 2 width: parent.width / 3 height: 2 - color: control.Theme.selectedTextColor + color: control.enabled ? "#353637" : "#bdbebf" } } //! [down.indicator] //! [background] background: Rectangle { - implicitWidth: 80 - radius: 3 - border.width: control.activeFocus ? 2 : 1 - border.color: control.activeFocus ? control.Theme.focusColor : control.Theme.frameColor + implicitWidth: 140 + border.color: "#bdbebf" } //! [background] } diff --git a/src/imports/controls/Switch.qml b/src/imports/controls/Switch.qml index 2768c2c7..3e224383 100644 --- a/src/imports/controls/Switch.qml +++ b/src/imports/controls/Switch.qml @@ -35,7 +35,6 @@ ****************************************************************************/ import QtQuick 2.6 -import Qt.labs.controls 1.0 import Qt.labs.templates 1.0 as T T.Switch { @@ -48,37 +47,37 @@ T.Switch { implicitHeight: Math.max(background ? background.implicitHeight : 0, Math.max(label ? label.implicitHeight : 0, indicator ? indicator.implicitHeight : 0) + topPadding + bottomPadding) + baselineOffset: label ? label.y + label.baselineOffset : 0 padding: 6 spacing: 6 //! [indicator] - indicator: Rectangle { - implicitWidth: 36 - implicitHeight: 20 + indicator: Item { x: text ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) : control.leftPadding + (control.availableWidth - width) / 2 y: control.topPadding + (control.availableHeight - height) / 2 - - radius: 10 - border.width: control.activeFocus ? 2 : 1 - border.color: control.activeFocus ? control.Theme.focusColor : control.Theme.frameColor - color: control.Theme.backgroundColor + implicitWidth: 56 + implicitHeight: 28 Rectangle { - width: 20 - height: 20 - radius: 10 - - color: Qt.tint(control.checked && !control.enabled ? control.Theme.disabledColor : - control.checked && control.activeFocus ? control.Theme.focusColor : - control.checked ? control.Theme.accentColor : control.Theme.baseColor, - control.pressed ? control.Theme.pressColor : "transparent") - border.width: control.checked || control.pressed ? 0 : 1 - border.color: control.Theme.frameColor + y: parent.height / 2 - height / 2 + width: 56 + height: 16 + radius: 8 + border.width: 1 + color: control.checked ? "#353637" : "transparent" + border.color: control.checked ? "transparent" : "#353637" + } - x: Math.max(0, Math.min(parent.width - width, - control.visualPosition * parent.width - (width / 2))) + Rectangle { + x: Math.max(0, Math.min(parent.width - width, control.visualPosition * parent.width - (width / 2))) y: (parent.height - height) / 2 + width: 28 + height: 28 + radius: 16 + color: control.pressed ? "#bdbebf" : "#ffffff" + border.width: 1 + border.color: control.pressed ? "#26282a" : "#353637" Behavior on x { enabled: !control.pressed @@ -97,7 +96,7 @@ T.Switch { text: control.text font: control.font - color: control.enabled ? control.Theme.textColor : control.Theme.disabledColor + color: control.enabled ? "#26282a" : "#bdbebf" elide: Text.ElideRight visible: control.text horizontalAlignment: Text.AlignLeft diff --git a/src/imports/controls/TabBar.qml b/src/imports/controls/TabBar.qml index 28d6a5db..773382a3 100644 --- a/src/imports/controls/TabBar.qml +++ b/src/imports/controls/TabBar.qml @@ -35,7 +35,6 @@ ****************************************************************************/ import QtQuick 2.6 -import Qt.labs.controls 1.0 import Qt.labs.templates 1.0 as T T.TabBar { @@ -70,7 +69,7 @@ T.TabBar { height: 4 width: parent.width y: parent.height - height - color: control.Theme.accentColor + color: "#353637" } } } @@ -81,15 +80,15 @@ T.TabBar { implicitWidth: 26 implicitHeight: 26 - border.color: control.Theme.backgroundColor + border.color: "#ffffff" border.width: 8 - color: control.count > 1 ? control.Theme.frameColor : control.Theme.backgroundColor + color: control.count > 1 ? "#bdbebf" : "#ffffff" Rectangle { y: parent.height - height width: parent.width height: 1 - color: control.Theme.frameColor + color: "#bdbebf" } } //! [background] diff --git a/src/imports/controls/TabButton.qml b/src/imports/controls/TabButton.qml index 33e0911f..1fbb6050 100644 --- a/src/imports/controls/TabButton.qml +++ b/src/imports/controls/TabButton.qml @@ -35,7 +35,6 @@ ****************************************************************************/ import QtQuick 2.6 -import Qt.labs.controls 1.0 import Qt.labs.templates 1.0 as T T.TabButton { @@ -45,6 +44,7 @@ T.TabButton { label ? label.contentWidth + leftPadding + rightPadding : 0) implicitHeight: Math.max(background ? background.implicitHeight : 0, label ? label.contentHeight + topPadding + bottomPadding : 0) + baselineOffset: label ? label.y + label.baselineOffset : 0 padding: 6 @@ -60,7 +60,7 @@ T.TabButton { text: control.text font: control.font elide: Text.ElideRight - color: !control.enabled ? control.Theme.disabledColor : control.pressed ? control.Theme.accentColor : control.Theme.textColor + color: !control.enabled ? "#bdbebf" : control.pressed ? "#000000" : "#353637" horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter } @@ -70,7 +70,7 @@ T.TabButton { background: Rectangle { height: parent.height - 1 implicitHeight: 26 - color: control.Theme.backgroundColor + color: "#ffffff" } //! [background] } diff --git a/src/imports/controls/TextArea.qml b/src/imports/controls/TextArea.qml index d4fa9497..de5994e8 100644 --- a/src/imports/controls/TextArea.qml +++ b/src/imports/controls/TextArea.qml @@ -35,7 +35,6 @@ ****************************************************************************/ import QtQuick 2.6 -import Qt.labs.controls 1.0 import Qt.labs.templates 1.0 as T T.TextArea { @@ -50,9 +49,9 @@ T.TextArea { padding: 6 - color: enabled ? Theme.textColor : Theme.disabledColor - selectionColor: Theme.selectionColor - selectedTextColor: Theme.selectedTextColor + color: enabled ? "#26282a" : "#c2c2c2" +// selectionColor: TODO +// selectedTextColor: TODO Text { id: placeholder @@ -63,7 +62,7 @@ T.TextArea { text: control.placeholderText font: control.font - color: control.Theme.disabledColor + color: "#c2c2c2" horizontalAlignment: control.horizontalAlignment verticalAlignment: control.verticalAlignment visible: !control.length && (!control.activeFocus || control.horizontalAlignment !== Qt.AlignHCenter) diff --git a/src/imports/controls/TextField.qml b/src/imports/controls/TextField.qml index ce5534e4..7b778b0e 100644 --- a/src/imports/controls/TextField.qml +++ b/src/imports/controls/TextField.qml @@ -35,7 +35,6 @@ ****************************************************************************/ import QtQuick 2.6 -import Qt.labs.controls 1.0 import Qt.labs.templates 1.0 as T T.TextField { @@ -47,10 +46,12 @@ T.TextField { placeholder.implicitHeight + topPadding + bottomPadding) padding: 6 + leftPadding: 10 - color: enabled ? Theme.textColor : Theme.disabledColor - selectionColor: Theme.selectionColor - selectedTextColor: Theme.selectedTextColor + opacity: enabled ? 1 : 0.2 + color: "#353637" + selectionColor: "#fddd5c" + selectedTextColor: color verticalAlignment: TextInput.AlignVCenter Text { @@ -62,7 +63,7 @@ T.TextField { text: control.placeholderText font: control.font - color: control.Theme.disabledColor + color: "#a0a1a2" horizontalAlignment: control.horizontalAlignment verticalAlignment: control.verticalAlignment visible: !control.displayText && (!control.activeFocus || control.horizontalAlignment !== Qt.AlignHCenter) @@ -71,10 +72,11 @@ T.TextField { //! [background] background: Rectangle { - implicitWidth: 120 // TODO - border.width: control.activeFocus ? 2 : 1 - border.color: control.activeFocus ? control.Theme.focusColor : control.Theme.frameColor - radius: 3 + implicitWidth: 200 + implicitHeight: 40 +// border.width: control.activeFocus ? 2 : 1 + color: control.enabled ? "transparent" : "#353637" + border.color: control.enabled ? "#bdbebf" : "transparent" } //! [background] } diff --git a/src/imports/controls/ToolBar.qml b/src/imports/controls/ToolBar.qml index be1b5d7a..3d3fc74c 100644 --- a/src/imports/controls/ToolBar.qml +++ b/src/imports/controls/ToolBar.qml @@ -35,7 +35,6 @@ ****************************************************************************/ import QtQuick 2.6 -import Qt.labs.controls 1.0 import Qt.labs.templates 1.0 as T T.ToolBar { @@ -54,7 +53,7 @@ T.ToolBar { //! [background] background: Rectangle { implicitHeight: 26 - color: control.Theme.baseColor + color: "#eeeeee" } //! [background] } diff --git a/src/imports/controls/ToolButton.qml b/src/imports/controls/ToolButton.qml index b6d33549..17fd03c5 100644 --- a/src/imports/controls/ToolButton.qml +++ b/src/imports/controls/ToolButton.qml @@ -35,7 +35,6 @@ ****************************************************************************/ import QtQuick 2.6 -import Qt.labs.controls 1.0 import Qt.labs.templates 1.0 as T T.ToolButton { @@ -45,6 +44,7 @@ T.ToolButton { label ? label.implicitWidth + leftPadding + rightPadding : 0) implicitHeight: Math.max(background ? background.implicitHeight : 0, label ? label.implicitHeight + topPadding + bottomPadding : 0) + baselineOffset: label ? label.y + label.baselineOffset : 0 padding: 6 @@ -57,7 +57,7 @@ T.ToolButton { text: control.text font: control.font - color: control.enabled ? control.Theme.textColor : control.Theme.disabledColor + color: control.enabled ? "#26282a" : "#c2c2c2" elide: Text.ElideRight horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter @@ -69,7 +69,7 @@ T.ToolButton { implicitWidth: 26 implicitHeight: 26 - color: Qt.darker(control.Theme.pressColor, control.checkable && control.checked ? 1.5 : 1.0) + color: Qt.darker("#33333333", control.checkable && control.checked ? 1.5 : 1.0) opacity: control.pressed ? 1.0 : control.checkable && control.checked ? 0.5 : 0 visible: control.pressed || (control.checkable && control.checked) } diff --git a/src/imports/controls/controls.pri b/src/imports/controls/controls.pri index 41f25c45..78c9a1d0 100644 --- a/src/imports/controls/controls.pri +++ b/src/imports/controls/controls.pri @@ -7,7 +7,10 @@ QML_FILES = \ Drawer.qml \ Frame.qml \ GroupBox.qml \ + ItemDelegate.qml \ Label.qml \ + Menu.qml \ + MenuItem.qml \ PageIndicator.qml \ ProgressBar.qml \ RadioButton.qml \ @@ -26,14 +29,3 @@ QML_FILES = \ ToolBar.qml \ ToolButton.qml \ Tumbler.qml - -HEADERS += \ - $$PWD/qquickfileselector_p.h \ - $$PWD/qquickfileselector_p_p.h \ - $$PWD/qquickthemedata_p.h \ - $$PWD/qquicktheme_p.h - -SOURCES += \ - $$PWD/qquickfileselector.cpp \ - $$PWD/qquicktheme.cpp \ - $$PWD/qquickthemedata.cpp diff --git a/src/imports/controls/controls.pro b/src/imports/controls/controls.pro index a7aec7e5..c3c5702c 100644 --- a/src/imports/controls/controls.pro +++ b/src/imports/controls/controls.pro @@ -1,9 +1,11 @@ -TARGET = qtlabscontrolsplugin +TARGET = qtlabscontrolsplugin TARGETPATH = Qt/labs/controls IMPORT_VERSION = 1.0 QT += qml quick -QT += core-private gui-private qml-private quick-private labstemplates-private +QT_PRIVATE += core-private gui-private qml-private quick-private labstemplates-private labscontrols-private + +DEFINES += QT_NO_CAST_TO_ASCII QT_NO_CAST_FROM_ASCII QMAKE_DOCS = $$PWD/doc/qtlabscontrols.qdocconf @@ -16,11 +18,7 @@ SOURCES += \ RESOURCES += \ $$PWD/qtlabscontrolsplugin.qrc -OTHER_FILES += \ - $$PWD/theme.json - include(controls.pri) -include(shared/shared.pri) include(designer/designer.pri) CONFIG += no_cxx_module diff --git a/src/imports/controls/doc/images/qtlabscontrols-drawer-expanded-wireframe.png b/src/imports/controls/doc/images/qtlabscontrols-drawer-expanded-wireframe.png Binary files differnew file mode 100644 index 00000000..8a8078bf --- /dev/null +++ b/src/imports/controls/doc/images/qtlabscontrols-drawer-expanded-wireframe.png diff --git a/src/imports/controls/doc/images/qtlabscontrols-drawer-wireframe.png b/src/imports/controls/doc/images/qtlabscontrols-drawer-wireframe.png Binary files differnew file mode 100644 index 00000000..d1ef1801 --- /dev/null +++ b/src/imports/controls/doc/images/qtlabscontrols-drawer-wireframe.png diff --git a/src/imports/controls/doc/images/qtlabscontrols-itemdelegate-background.png b/src/imports/controls/doc/images/qtlabscontrols-itemdelegate-background.png Binary files differnew file mode 100644 index 00000000..a311c109 --- /dev/null +++ b/src/imports/controls/doc/images/qtlabscontrols-itemdelegate-background.png diff --git a/src/imports/controls/doc/images/qtlabscontrols-itemdelegate-indicator.png b/src/imports/controls/doc/images/qtlabscontrols-itemdelegate-indicator.png Binary files differnew file mode 100644 index 00000000..b458b1a0 --- /dev/null +++ b/src/imports/controls/doc/images/qtlabscontrols-itemdelegate-indicator.png diff --git a/src/imports/controls/doc/images/qtlabscontrols-itemdelegate-label.png b/src/imports/controls/doc/images/qtlabscontrols-itemdelegate-label.png Binary files differnew file mode 100644 index 00000000..6b43db0f --- /dev/null +++ b/src/imports/controls/doc/images/qtlabscontrols-itemdelegate-label.png diff --git a/src/imports/controls/doc/images/qtlabscontrols-menu-contentItem.png b/src/imports/controls/doc/images/qtlabscontrols-menu-contentItem.png Binary files differnew file mode 100644 index 00000000..e16e196e --- /dev/null +++ b/src/imports/controls/doc/images/qtlabscontrols-menu-contentItem.png diff --git a/src/imports/controls/doc/images/qtlabscontrols-menu.png b/src/imports/controls/doc/images/qtlabscontrols-menu.png Binary files differnew file mode 100644 index 00000000..b782b9fe --- /dev/null +++ b/src/imports/controls/doc/images/qtlabscontrols-menu.png diff --git a/src/imports/controls/doc/images/qtlabscontrols-pageindicator.png b/src/imports/controls/doc/images/qtlabscontrols-pageindicator.png Binary files differindex 4bef41e6..3f47fb9f 100644 --- a/src/imports/controls/doc/images/qtlabscontrols-pageindicator.png +++ b/src/imports/controls/doc/images/qtlabscontrols-pageindicator.png diff --git a/src/imports/controls/doc/images/qtlabscontrols-scrollbar.png b/src/imports/controls/doc/images/qtlabscontrols-scrollbar.png Binary files differindex 6756fd3c..65db9ad8 100644 --- a/src/imports/controls/doc/images/qtlabscontrols-scrollbar.png +++ b/src/imports/controls/doc/images/qtlabscontrols-scrollbar.png diff --git a/src/imports/controls/doc/images/qtlabscontrols-scrollindicator.png b/src/imports/controls/doc/images/qtlabscontrols-scrollindicator.png Binary files differindex f1ab6107..ea0923cc 100644 --- a/src/imports/controls/doc/images/qtlabscontrols-scrollindicator.png +++ b/src/imports/controls/doc/images/qtlabscontrols-scrollindicator.png diff --git a/src/imports/controls/doc/snippets/qtlabscontrols-itemdelegate-background.qml b/src/imports/controls/doc/snippets/qtlabscontrols-itemdelegate-background.qml new file mode 100644 index 00000000..10d5696e --- /dev/null +++ b/src/imports/controls/doc/snippets/qtlabscontrols-itemdelegate-background.qml @@ -0,0 +1,39 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: http://www.gnu.org/copyleft/fdl.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 +import Qt.labs.controls 1.0 + +ItemDelegate { + text: "ItemDelegate" + checked: true + checkable: true + background: Rectangle { + color: 'transparent' + border.color: 'red' + } +} diff --git a/src/imports/controls/doc/snippets/qtlabscontrols-itemdelegate-indicator.qml b/src/imports/controls/doc/snippets/qtlabscontrols-itemdelegate-indicator.qml new file mode 100644 index 00000000..fb80957d --- /dev/null +++ b/src/imports/controls/doc/snippets/qtlabscontrols-itemdelegate-indicator.qml @@ -0,0 +1,40 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: http://www.gnu.org/copyleft/fdl.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 +import Qt.labs.controls 1.0 + +ItemDelegate { + text: "ItemDelegate" + checked: true + checkable: true + Rectangle { + anchors.fill: indicator + color: "transparent" + border.color: "red" + } +} diff --git a/src/imports/controls/doc/snippets/qtlabscontrols-itemdelegate-label.qml b/src/imports/controls/doc/snippets/qtlabscontrols-itemdelegate-label.qml new file mode 100644 index 00000000..696560a5 --- /dev/null +++ b/src/imports/controls/doc/snippets/qtlabscontrols-itemdelegate-label.qml @@ -0,0 +1,40 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: http://www.gnu.org/copyleft/fdl.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 +import Qt.labs.controls 1.0 + +ItemDelegate { + text: "ItemDelegate" + checked: true + checkable: true + Rectangle { + anchors.fill: label + color: "transparent" + border.color: "red" + } +} diff --git a/src/imports/controls/doc/snippets/qtlabscontrols-itemdelegate.qml b/src/imports/controls/doc/snippets/qtlabscontrols-itemdelegate.qml new file mode 100644 index 00000000..d02f722a --- /dev/null +++ b/src/imports/controls/doc/snippets/qtlabscontrols-itemdelegate.qml @@ -0,0 +1,46 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: http://www.gnu.org/copyleft/fdl.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 +import Qt.labs.controls 1.0 + +//! [1] +ListView { + width: 160 + height: 240 + + model: Qt.fontFamilies() + + delegate: ItemDelegate { + text: modelData + width: parent.width + onClicked: console.log("clicked:", modelData) + } + + ScrollIndicator.vertical: ScrollIndicator { } +} +//! [1] diff --git a/src/imports/controls/doc/snippets/qtlabscontrols-menu-contentItem.qml b/src/imports/controls/doc/snippets/qtlabscontrols-menu-contentItem.qml new file mode 100644 index 00000000..0c270d34 --- /dev/null +++ b/src/imports/controls/doc/snippets/qtlabscontrols-menu-contentItem.qml @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: http://www.gnu.org/copyleft/fdl.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 +import Qt.labs.controls 1.0 + +Item { + id: window + width: menu.contentItem.width + height: menu.contentItem.height + visible: true + + Menu { + id: menu + contentItem.parent: window + + MenuItem { + text: "New..." + } + MenuItem { + text: "Open..." + } + MenuItem { + text: "Save" + } + } + + Rectangle { + parent: menu.contentItem + anchors.fill: parent + color: 'transparent' + border.color: 'red' + } +} diff --git a/src/imports/controls/doc/snippets/qtlabscontrols-menu.qml b/src/imports/controls/doc/snippets/qtlabscontrols-menu.qml new file mode 100644 index 00000000..b0f32203 --- /dev/null +++ b/src/imports/controls/doc/snippets/qtlabscontrols-menu.qml @@ -0,0 +1,51 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: http://www.gnu.org/copyleft/fdl.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 +import Qt.labs.controls 1.0 + +Item { + id: window + width: menu.contentItem.width + height: menu.contentItem.height + visible: true + + Menu { + id: menu + contentItem.parent: window + + MenuItem { + text: "New..." + } + MenuItem { + text: "Open..." + } + MenuItem { + text: "Save" + } + } +} diff --git a/src/imports/controls/doc/snippets/qtlabscontrols-pageindicator.qml b/src/imports/controls/doc/snippets/qtlabscontrols-pageindicator.qml index 7118d99f..f13e1213 100644 --- a/src/imports/controls/doc/snippets/qtlabscontrols-pageindicator.qml +++ b/src/imports/controls/doc/snippets/qtlabscontrols-pageindicator.qml @@ -28,10 +28,9 @@ import QtQuick 2.0 import Qt.labs.controls 1.0 -Rectangle { +Frame { width: 100 height: 100 - border.color: Theme.frameColor //! [1] PageIndicator { diff --git a/src/imports/controls/doc/snippets/qtlabscontrols-scrollbar.qml b/src/imports/controls/doc/snippets/qtlabscontrols-scrollbar.qml index 49416f84..b677137d 100644 --- a/src/imports/controls/doc/snippets/qtlabscontrols-scrollbar.qml +++ b/src/imports/controls/doc/snippets/qtlabscontrols-scrollbar.qml @@ -28,10 +28,9 @@ import QtQuick 2.0 import Qt.labs.controls 1.0 -Rectangle { +Frame { width: 100 height: 100 - border.color: Theme.frameColor ScrollBar { size: 0.3 diff --git a/src/imports/controls/doc/snippets/qtlabscontrols-scrollindicator.qml b/src/imports/controls/doc/snippets/qtlabscontrols-scrollindicator.qml index 38a9e2eb..8efa0eed 100644 --- a/src/imports/controls/doc/snippets/qtlabscontrols-scrollindicator.qml +++ b/src/imports/controls/doc/snippets/qtlabscontrols-scrollindicator.qml @@ -28,10 +28,9 @@ import QtQuick 2.0 import Qt.labs.controls 1.0 -Rectangle { +Frame { width: 100 height: 100 - border.color: Theme.frameColor ScrollIndicator { size: 0.3 diff --git a/src/imports/controls/doc/src/qtlabscontrols-customize.qdoc b/src/imports/controls/doc/src/qtlabscontrols-customize.qdoc index a820e260..a7bd7d8b 100644 --- a/src/imports/controls/doc/src/qtlabscontrols-customize.qdoc +++ b/src/imports/controls/doc/src/qtlabscontrols-customize.qdoc @@ -113,6 +113,21 @@ \snippet Dial.qml handle + \section1 Customizing Drawer + + Drawer can have a visual \l {Control::background}{background} + item. The navigation is implemented by the \l {Control::contentItem} + {content item}. + + \section3 Background + + \snippet Drawer.qml background + + \section3 Content item + + Drawer has no content item by default. + + \section1 Customizing Frame Frame consists of two visual items: \l {Control::background}{background} @@ -155,6 +170,31 @@ \snippet GroupBox.qml label + \section1 Customizing ItemDelegate + + ItemDelegate consists of three visual items: \l {Control::background}{background}, + \l {AbstractButton::label}{label} and \l {AbstractButton::indicator}{indicator}. + The indicator is only visible for \l {AbstractButton::checkable}{checkable} items. + + \section3 Background + + \image qtlabscontrols-itemdelegate-background.png + + \snippet ItemDelegate.qml background + + \section3 Label + + \image qtlabscontrols-itemdelegate-label.png + + \snippet ItemDelegate.qml label + + \section3 Indicator + + \image qtlabscontrols-itemdelegate-indicator.png + + \snippet ItemDelegate.qml indicator + + \section1 Customizing Label Label can have a visual \l {Label::background}{background} item. @@ -166,6 +206,23 @@ Label has no background item by default. + \section1 Customizing Menu + + Menu consists of a \l {Panel::}{contentItem}. + + \section3 Content item + + \image qtlabscontrols-menu-contentItem.png + + \snippet Menu.qml contentItem + + + \section1 Customizing MenuItem + + MenuItem can be customized in the same manner as + \l {Customizing Button}{Button}. + + \section1 Customizing PageIndicator TODO diff --git a/src/imports/controls/doc/src/qtlabscontrols-index.qdoc b/src/imports/controls/doc/src/qtlabscontrols-index.qdoc index c105ede9..936e65e8 100644 --- a/src/imports/controls/doc/src/qtlabscontrols-index.qdoc +++ b/src/imports/controls/doc/src/qtlabscontrols-index.qdoc @@ -78,11 +78,6 @@ are Qt Quick items that are instantiated on the spot, as properties of the control, and are simply parented to the control. - Control-specific style objects have been replaced by a Theme object that - offers a simple set of themable attributes. Basic color adjustments can be - made by setting a few properties that are automatically inherited by the - hierarchy of children. - \section2 Modularity and Simplicity When it comes to more complex controls, it is sometimes better to split @@ -225,7 +220,7 @@ \li \l [QtLabsControls] {CheckBox} \row \li \l [QtQuickControls] {ExclusiveGroup} - \li \l [QtLabsControls] {ExclusiveGroup} + \li \l [QtLabsControls] {ButtonGroup} \row \li \l [QtQuickControls] {GroupBox} @@ -236,6 +231,9 @@ \li \l [QtQuickControls] {Label} \li \l [QtLabsControls] {Label} \row + \li \l [QtQuickControls] {Menu} + \li \l [QtLabsControls] {Menu} + \row \li \l [QtQuickControls] {ProgressBar} \li \l [QtLabsControls] {ProgressBar} \row diff --git a/src/imports/controls/doc/src/qtlabscontrols-menus.qdoc b/src/imports/controls/doc/src/qtlabscontrols-menus.qdoc new file mode 100644 index 00000000..65b4f04c --- /dev/null +++ b/src/imports/controls/doc/src/qtlabscontrols-menus.qdoc @@ -0,0 +1,43 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: http://www.gnu.org/copyleft/fdl.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page qtlabscontrols-menus.html + \title Menu Controls + + \annotatedlist qtlabscontrols-menus + + Each type of menu control has its own specific target use case. The + following sections offer guidelines for choosing the appropriate type + of menu control, depending on the use case. + + \section1 Menu Control + + \image qtlabscontrols-menu.png + + \l Menu is a traditional menu. +*/ diff --git a/src/imports/controls/images/check.png b/src/imports/controls/images/check.png Binary files differnew file mode 100644 index 00000000..28d86ef2 --- /dev/null +++ b/src/imports/controls/images/check.png diff --git a/src/imports/controls/images/check@2x.png b/src/imports/controls/images/check@2x.png Binary files differnew file mode 100644 index 00000000..46c3dafa --- /dev/null +++ b/src/imports/controls/images/check@2x.png diff --git a/src/imports/controls/images/check@3x.png b/src/imports/controls/images/check@3x.png Binary files differnew file mode 100644 index 00000000..7ad7818b --- /dev/null +++ b/src/imports/controls/images/check@3x.png diff --git a/src/imports/controls/images/check@4x.png b/src/imports/controls/images/check@4x.png Binary files differnew file mode 100644 index 00000000..ce3d9e76 --- /dev/null +++ b/src/imports/controls/images/check@4x.png diff --git a/src/imports/controls/images/dial-indicator.png b/src/imports/controls/images/dial-indicator.png Binary files differnew file mode 100644 index 00000000..53f70c49 --- /dev/null +++ b/src/imports/controls/images/dial-indicator.png diff --git a/src/imports/controls/images/dial-indicator@2x.png b/src/imports/controls/images/dial-indicator@2x.png Binary files differnew file mode 100644 index 00000000..c0d24bd5 --- /dev/null +++ b/src/imports/controls/images/dial-indicator@2x.png diff --git a/src/imports/controls/images/dial-indicator@3x.png b/src/imports/controls/images/dial-indicator@3x.png Binary files differnew file mode 100644 index 00000000..2161193b --- /dev/null +++ b/src/imports/controls/images/dial-indicator@3x.png diff --git a/src/imports/controls/images/dial-indicator@4x.png b/src/imports/controls/images/dial-indicator@4x.png Binary files differnew file mode 100644 index 00000000..79bba975 --- /dev/null +++ b/src/imports/controls/images/dial-indicator@4x.png diff --git a/src/imports/controls/material/ApplicationWindow.qml b/src/imports/controls/material/ApplicationWindow.qml new file mode 100644 index 00000000..bf8b62bc --- /dev/null +++ b/src/imports/controls/material/ApplicationWindow.qml @@ -0,0 +1,46 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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$ +** +****************************************************************************/ + +import QtQuick 2.6 +import QtQuick.Window 2.2 +import Qt.labs.templates 1.0 as T +import Qt.labs.controls.material 1.0 + +T.ApplicationWindow { + id: window + + color: Material.backgroundColor +} diff --git a/src/imports/controls/material/BusyIndicator.qml b/src/imports/controls/material/BusyIndicator.qml new file mode 100644 index 00000000..6d5e4e8d --- /dev/null +++ b/src/imports/controls/material/BusyIndicator.qml @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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$ +** +****************************************************************************/ + +import QtQuick 2.6 +import Qt.labs.templates 1.0 as T +import Qt.labs.controls.material 1.0 + +T.BusyIndicator { + id: control + + implicitWidth: contentItem.implicitWidth + leftPadding + rightPadding + implicitHeight: contentItem.implicitHeight + topPadding + bottomPadding + + padding: 6 + + //! [contentItem] + contentItem: ProgressRing { + id: ring + x: control.leftPadding + (control.availableWidth - width) / 2 + y: control.topPadding + (control.availableHeight - height) / 2 + implicitWidth: 48 + implicitHeight: 48 + width: size + height: size + opacity: control.running ? 1 : 0 + color: control.Material.accentColor + + readonly property real size: Math.min(control.availableWidth, control.availableHeight) + + Behavior on opacity { OpacityAnimator { duration: 250 } } + + RingAnimator { + target: ring + running: control.visible && control.running + } + } + //! [contentItem] +} diff --git a/src/imports/controls/material/Button.qml b/src/imports/controls/material/Button.qml new file mode 100644 index 00000000..6d2ab499 --- /dev/null +++ b/src/imports/controls/material/Button.qml @@ -0,0 +1,101 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 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$ +** +****************************************************************************/ + +import QtQuick 2.6 +import Qt.labs.templates 1.0 as T +import Qt.labs.controls.material 1.0 +import QtGraphicalEffects 1.0 + +T.Button { + id: control + + implicitWidth: Math.max(background ? background.implicitWidth : 0, + label ? label.implicitWidth + leftPadding + rightPadding : 0) + implicitHeight: Math.max(background ? background.implicitHeight : 0, + label ? label.implicitHeight + topPadding + bottomPadding : 0) + baselineOffset: label ? label.y + label.baselineOffset : 0 + + padding: 6 + leftPadding: 8 + rightPadding: 8 + + //! [label] + label: Text { + x: control.leftPadding + y: control.topPadding + width: control.availableWidth + height: control.availableHeight + + text: control.text + color: control.highlighted ? control.Material.primaryHighlightedTextColor : control.Material.primaryTextColor + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + elide: Text.ElideRight + } + //! [label] + + //! [background] + background: Rectangle { + implicitWidth: 36 + implicitHeight: 36 + + radius: 2 + color: !control.enabled ? (control.highlighted ? control.Material.raisedHighlightedButtonDisabledColor : control.Material.raisedButtonDisabledColor) : + (control.pressed ? (control.highlighted ? control.Material.raisedHighlightedButtonPressColor : control.Material.raisedButtonPressColor) : + (control.activeFocus ? (control.highlighted ? control.Material.raisedHighlightedButtonHoverColor : control.Material.raisedButtonHoverColor) : + (control.highlighted ? control.Material.raisedHighlightedButtonColor : control.Material.raisedButtonColor))) + + Behavior on color { + ColorAnimation { + duration: 400 + } + } + + layer.enabled: control.enabled + layer.effect: DropShadow { + verticalOffset: 1 + color: control.Material.dropShadowColor + samples: control.pressed ? 15 : 9 + spread: 0.5 + + // TODO: Doesn't work because of QTBUG-49072 + Behavior on radius { + NumberAnimation { duration: 1000 } + } + } + } + //! [background] +} diff --git a/src/imports/controls/material/CheckBox.qml b/src/imports/controls/material/CheckBox.qml new file mode 100644 index 00000000..939d5a31 --- /dev/null +++ b/src/imports/controls/material/CheckBox.qml @@ -0,0 +1,145 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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$ +** +****************************************************************************/ + +import QtQuick 2.6 +import Qt.labs.templates 1.0 as T +import Qt.labs.controls.material 1.0 + +T.CheckBox { + id: control + + implicitWidth: Math.max(background ? background.implicitWidth : 0, + (label ? label.implicitWidth : 0) + + (indicator ? indicator.implicitWidth : 0) + + (label && indicator ? spacing : 0) + leftPadding + rightPadding) + implicitHeight: Math.max(background ? background.implicitHeight : 0, + Math.max(label ? label.implicitHeight : 0, + indicator ? indicator.implicitHeight : 0) + topPadding + bottomPadding) + baselineOffset: label ? label.y + label.baselineOffset : 0 + + padding: 6 + spacing: 6 + + //! [indicator] + indicator: Rectangle { + id: indicatorItem + x: text ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) : control.leftPadding + (control.availableWidth - width) / 2 + y: control.topPadding + (control.availableHeight - height) / 2 + implicitWidth: 20 + implicitHeight: 20 + color: "transparent" + border.color: control.checked ? control.Material.accentColor : control.Material.secondaryTextColor + border.width: control.checked ? width / 2 : 2 + radius: 2 + + Behavior on border.width { + NumberAnimation { + duration: 100 + easing.type: Easing.OutCubic + } + } + + Behavior on border.color { + ColorAnimation { + duration: 100 + easing.type: Easing.OutCubic + } + } + + Ripple { + width: parent.width + height: width + control: control + colored: control.checked + opacity: control.pressed ? 1 : 0 + } + + // TODO: This needs to be transparent + Image { + id: checkImage + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + width: 16 + height: 16 + source: "qrc:/qt-project.org/imports/Qt/labs/controls/material/images/check.png" + fillMode: Image.PreserveAspectFit + + scale: control.checked ? 1 : 0 + Behavior on scale { NumberAnimation { duration: 100 } } + } + + states: State { + name: "checked" + when: control.checked + } + + transitions: Transition { + SequentialAnimation { + NumberAnimation { + target: indicatorItem + property: "scale" + // Go down 2 pixels in size. + to: 1 - 2 / indicatorItem.width + duration: 120 + } + NumberAnimation { + target: indicatorItem + property: "scale" + to: 1 + duration: 120 + } + } + } + } + //! [indicator] + + //! [label] + label: Text { + x: control.mirrored ? control.leftPadding : (indicator.x + indicator.width + control.spacing) + y: control.topPadding + width: control.availableWidth - indicator.width - control.spacing + height: control.availableHeight + + text: control.text + font: control.font + color: control.enabled ? control.Material.primaryTextColor : control.Material.hintTextColor + elide: Text.ElideRight + visible: control.text + horizontalAlignment: Text.AlignLeft + verticalAlignment: Text.AlignVCenter + } + //! [label] +} diff --git a/src/imports/controls/material/Dial.qml b/src/imports/controls/material/Dial.qml new file mode 100644 index 00000000..d3f6bb65 --- /dev/null +++ b/src/imports/controls/material/Dial.qml @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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$ +** +****************************************************************************/ + +import QtQuick 2.6 +import Qt.labs.templates 1.0 as T +import Qt.labs.controls.material 1.0 + +T.Dial { + id: control + + implicitWidth: 100 + implicitHeight: 100 + + //! [background] + background: Rectangle { + color: "transparent" + radius: width / 2 + + border.color: control.enabled ? control.Material.accentColor : control.Material.hintTextColor + } + //! [background] + + //! [handle] + handle: Rectangle { + id: handleItem + + x: background.width / 2 - handle.width / 2 + y: background.height / 2 - handle.height / 2 + transform: [ + Translate { + y: -background.height * 0.35 + }, + Rotation { + angle: control.angle + origin.x: handle.width / 2 + origin.y: handle.height / 2 + } + ] + implicitWidth: 14 + implicitHeight: 14 + radius: width / 2 + color: control.enabled ? control.Material.accentColor : control.Material.hintTextColor + } + //! [handle] +} diff --git a/src/imports/controls/material/Drawer.qml b/src/imports/controls/material/Drawer.qml new file mode 100644 index 00000000..baaa4453 --- /dev/null +++ b/src/imports/controls/material/Drawer.qml @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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$ +** +****************************************************************************/ + +import QtQuick 2.6 +import Qt.labs.templates 1.0 as T +import Qt.labs.controls.material 1.0 + +T.Drawer { + id: control + + width: parent ? parent.width : 0 // TODO: Window.width + height: parent ? parent.height : 0 // TODO: Window.height + + //! [background] + background: Rectangle { + color: control.Material.drawerBackgroundColor + opacity: position * 0.75 + } + //! [background] + + // TODO: make this a proper transition + animation: SmoothedAnimation { + velocity: 5 + } +} diff --git a/src/imports/controls/material/Frame.qml b/src/imports/controls/material/Frame.qml new file mode 100644 index 00000000..3b4c8bd5 --- /dev/null +++ b/src/imports/controls/material/Frame.qml @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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$ +** +****************************************************************************/ + +import QtQuick 2.6 +import Qt.labs.templates 1.0 as T +import Qt.labs.controls.material 1.0 + +T.Frame { + id: control + + implicitWidth: Math.max(background ? background.implicitWidth : 0, contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(background ? background.implicitHeight : 0, contentHeight + topPadding + bottomPadding) + + contentWidth: contentChildren.length === 1 ? contentChildren[0].implicitWidth : 0 + contentHeight: contentChildren.length === 1 ? contentChildren[0].implicitHeight : 0 + + padding: 6 + + //! [contentItem] + contentItem: Item { } + //! [contentItem] + + //! [frame] + frame: Rectangle { + width: parent.width + height: parent.height + + radius: 3 + color: "transparent" + border.color: control.Material.frameColor + } + //! [frame] +} diff --git a/src/imports/controls/material/GroupBox.qml b/src/imports/controls/material/GroupBox.qml new file mode 100644 index 00000000..de47ff14 --- /dev/null +++ b/src/imports/controls/material/GroupBox.qml @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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$ +** +****************************************************************************/ + +import QtQuick 2.6 +import Qt.labs.templates 1.0 as T +import Qt.labs.controls.material 1.0 + +T.GroupBox { + id: control + + implicitWidth: Math.max(background ? background.implicitWidth : 0, contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(background ? background.implicitHeight : 0, contentHeight + topPadding + bottomPadding) + + contentWidth: contentChildren.length === 1 ? contentChildren[0].implicitWidth : 0 + contentHeight: contentChildren.length === 1 ? contentChildren[0].implicitHeight : 0 + + spacing: 6 + padding: 6 + topPadding: 6 + (label && title ? label.implicitHeight + spacing : 0) + + //! [contentItem] + contentItem: Item {} + //! [contentItem] + + //! [label] + label: Text { + x: control.leftPadding + width: control.availableWidth + + text: control.title + font: control.font + color: control.enabled ? control.Material.primaryTextColor : control.Material.hintTextColor + elide: Text.ElideRight + horizontalAlignment: Text.AlignLeft + verticalAlignment: Text.AlignVCenter + } + //! [label] + + //! [frame] + frame: Rectangle { + y: control.topPadding - control.padding + width: parent.width + height: parent.height - control.topPadding + control.padding + + radius: 3 + color: "transparent" + border.color: control.Material.frameColor + } + //! [frame] +} diff --git a/src/imports/controls/material/ItemDelegate.qml b/src/imports/controls/material/ItemDelegate.qml new file mode 100644 index 00000000..73a63397 --- /dev/null +++ b/src/imports/controls/material/ItemDelegate.qml @@ -0,0 +1,152 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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$ +** +****************************************************************************/ + +import QtQuick 2.6 +import Qt.labs.templates 1.0 as T +import Qt.labs.controls.material 1.0 + +T.ItemDelegate { + id: control + + implicitWidth: Math.max(background ? background.implicitWidth : 0, + (label ? label.implicitWidth : 0) + + (indicator ? indicator.implicitWidth : 0) + + (label && indicator ? spacing : 0) + leftPadding + rightPadding) + implicitHeight: Math.max(background ? background.implicitHeight : 0, + Math.max(label ? label.implicitHeight : 0, + indicator ? indicator.implicitHeight : 0) + topPadding + bottomPadding) + + padding: 16 + spacing: 16 + + //! [indicator] + indicator: Rectangle { + id: indicatorItem + x: text ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) : control.leftPadding + (control.availableWidth - width) / 2 + y: control.topPadding + (control.availableHeight - height) / 2 + implicitWidth: 20 + implicitHeight: 20 + color: "transparent" + border.color: control.checked ? control.Material.accentColor : control.Material.secondaryTextColor + border.width: control.checked ? width / 2 : 2 + radius: 2 + + visible: control.checkable + + Behavior on border.width { + NumberAnimation { + duration: 100 + easing.type: Easing.OutCubic + } + } + + Behavior on border.color { + ColorAnimation { + duration: 100 + easing.type: Easing.OutCubic + } + } + + Ripple { + width: parent.width + height: width + control: control + colored: control.checked + opacity: control.pressed ? 1 : 0 + } + + // TODO: This needs to be transparent + Image { + id: checkImage + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + width: 16 + height: 16 + source: "qrc:/qt-project.org/imports/Qt/labs/controls/material/images/check.png" + fillMode: Image.PreserveAspectFit + + scale: control.checked ? 1 : 0 + Behavior on scale { NumberAnimation { duration: 100 } } + } + + states: State { + name: "checked" + when: control.checked + } + + transitions: Transition { + SequentialAnimation { + NumberAnimation { + target: indicatorItem + property: "scale" + // Go down 2 pixels in size. + to: 1 - 2 / indicatorItem.width + duration: 120 + } + NumberAnimation { + target: indicatorItem + property: "scale" + to: 1 + duration: 120 + } + } + } + } + //! [indicator] + + //! [label] + label: Text { + x: control.mirrored || !control.checkable ? control.leftPadding : (indicator.x + indicator.width + control.spacing) + y: control.topPadding + width: control.availableWidth - (control.checkable ? indicator.width + control.spacing : 0) + height: control.availableHeight + + text: control.text + font: control.font + color: control.enabled ? control.Material.primaryTextColor : control.Material.hintTextColor + elide: Text.ElideRight + visible: control.text + horizontalAlignment: Text.AlignLeft + verticalAlignment: Text.AlignVCenter + } + //! [label] + + //! [background] + background: Rectangle { + color: control.pressed ? control.Material.flatButtonPressColor : control.Material.backgroundColor + } + //! [background] +} diff --git a/src/imports/controls/material/Label.qml b/src/imports/controls/material/Label.qml new file mode 100644 index 00000000..3d8952f2 --- /dev/null +++ b/src/imports/controls/material/Label.qml @@ -0,0 +1,46 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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$ +** +****************************************************************************/ + +import QtQuick 2.6 +import Qt.labs.templates 1.0 as T +import Qt.labs.controls.material 1.0 + +T.Label { + id: control + + color: Material.primaryTextColor + linkColor: Material.accentColor +} diff --git a/src/imports/controls/material/PageIndicator.qml b/src/imports/controls/material/PageIndicator.qml new file mode 100644 index 00000000..1d646f97 --- /dev/null +++ b/src/imports/controls/material/PageIndicator.qml @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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$ +** +****************************************************************************/ + +import QtQuick 2.6 +import Qt.labs.templates 1.0 as T +import Qt.labs.controls.material 1.0 + +T.PageIndicator { + id: control + + implicitWidth: Math.max(background ? background.implicitWidth : 0, + contentItem.implicitWidth + leftPadding + rightPadding) + implicitHeight: Math.max(background ? background.implicitHeight : 0, + contentItem.implicitHeight + topPadding + bottomPadding) + + padding: 6 + spacing: 6 + + //! [delegate] + delegate: Rectangle { + implicitWidth: 8 + implicitHeight: 8 + + radius: width / 2 + color: control.Material.primaryTextColor + + opacity: index === currentIndex ? 0.95 : pressed ? 0.7 : 0.45 + Behavior on opacity { OpacityAnimator { duration: 100 } } + } + //! [delegate] + + //! [contentItem] + contentItem: Row { + spacing: control.spacing + + Repeater { + model: control.count + delegate: control.delegate + } + } + //! [contentItem] +} diff --git a/src/imports/controls/material/ProgressBar.qml b/src/imports/controls/material/ProgressBar.qml new file mode 100644 index 00000000..34e1aaea --- /dev/null +++ b/src/imports/controls/material/ProgressBar.qml @@ -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 Controls 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$ +** +****************************************************************************/ + +import QtQuick 2.6 +import Qt.labs.templates 1.0 as T +import Qt.labs.controls.material 1.0 + +T.ProgressBar { + id: control + + implicitWidth: Math.max(background ? background.implicitWidth : 0, + indicator ? indicator.implicitWidth : 0) + leftPadding + rightPadding + implicitHeight: Math.max(background ? background.implicitHeight : 0, + indicator ? indicator.implicitHeight : 0) + topPadding + bottomPadding + + padding: 6 + + //! [indicator] + indicator: Item { + x: control.leftPadding + y: control.topPadding + width: control.availableWidth + height: control.availableHeight + + scale: control.mirrored ? -1 : 1 + + Repeater { + model: indeterminate ? 2 : 1 + + Rectangle { + property real offset: indeterminate ? 0 : control.position + + x: (indeterminate ? offset * parent.width : 0) + y: (parent.height - height) / 2 + width: offset * (parent.width - x) + height: 6 + + color: control.Material.accentColor + + SequentialAnimation on offset { + loops: Animation.Infinite + running: indeterminate && visible + PauseAnimation { duration: index ? 520 : 0 } + NumberAnimation { + easing.type: Easing.OutCubic + duration: 1240 + from: 0 + to: 1 + } + PauseAnimation { duration: index ? 0 : 520 } + } + } + } + } + //! [indicator] + + //! [background] + background: Rectangle { + implicitWidth: 200 + implicitHeight: 6 + x: control.leftPadding + y: control.topPadding + (control.availableHeight - height) / 2 + width: control.availableWidth + height: 6 + + color: Qt.rgba(control.Material.accentColor.r, control.Material.accentColor.g, control.Material.accentColor.b, 0.25) + } + //! [background] +} diff --git a/src/imports/controls/material/RadioButton.qml b/src/imports/controls/material/RadioButton.qml new file mode 100644 index 00000000..96605311 --- /dev/null +++ b/src/imports/controls/material/RadioButton.qml @@ -0,0 +1,103 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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$ +** +****************************************************************************/ + +import QtQuick 2.6 +import Qt.labs.templates 1.0 as T +import Qt.labs.controls.material 1.0 + +T.RadioButton { + id: control + + implicitWidth: Math.max(background ? background.implicitWidth : 0, + (label ? label.implicitWidth : 0) + + (indicator ? indicator.implicitWidth : 0) + + (label && indicator ? spacing : 0) + leftPadding + rightPadding) + implicitHeight: Math.max(background ? background.implicitHeight : 0, + Math.max(label ? label.implicitHeight : 0, + indicator ? indicator.implicitHeight : 0) + topPadding + bottomPadding) + baselineOffset: label ? label.y + label.baselineOffset : 0 + + padding: 6 + spacing: 6 + + //! [indicator] + indicator: Rectangle { + x: text ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) : control.leftPadding + (control.availableWidth - width) / 2 + y: control.topPadding + (control.availableHeight - height) / 2 + implicitWidth: 20 + implicitHeight: 20 + radius: width / 2 + border.width: 2 + border.color: control.checked || control.pressed ? control.Material.accentColor : control.Material.secondaryTextColor + color: "transparent" + + Ripple { + width: parent.width + height: width + control: control + colored: control.checked + opacity: control.pressed ? 1 : 0 + } + + Rectangle { + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + width: 10 + height: 10 + radius: width / 2 + color: parent.border.color + visible: control.checked || control.pressed + } + } + //! [indicator] + + //! [label] + label: Text { + x: control.mirrored ? control.leftPadding : (indicator.x + indicator.width + control.spacing) + y: control.topPadding + width: control.availableWidth - indicator.width - control.spacing + height: control.availableHeight + + text: control.text + font: control.font + color: control.enabled ? control.Material.primaryTextColor : control.Material.hintTextColor + elide: Text.ElideRight + visible: control.text + horizontalAlignment: Text.AlignLeft + verticalAlignment: Text.AlignVCenter + } + //! [label] +} diff --git a/src/imports/controls/material/RangeSlider.qml b/src/imports/controls/material/RangeSlider.qml new file mode 100644 index 00000000..bf8c16ef --- /dev/null +++ b/src/imports/controls/material/RangeSlider.qml @@ -0,0 +1,98 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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$ +** +****************************************************************************/ + +import QtQuick 2.6 +import Qt.labs.templates 1.0 as T +import Qt.labs.controls.material 1.0 + +T.RangeSlider { + id: control + + implicitWidth: Math.max(background ? background.implicitWidth : 0, + Math.max(track ? track.implicitWidth : 0, + first.handle ? first.handle.implicitWidth : 0, + second.handle ? second.handle.implicitWidth : 0) + leftPadding + rightPadding) + implicitHeight: Math.max(background ? background.implicitHeight : 0, + Math.max(track ? track.implicitHeight : 0, + first.handle ? first.handle.implicitHeight : 0, + second.handle ? second.handle.implicitHeight : 0) + topPadding + bottomPadding) + + padding: 6 + + //! [firstHandle] + first.handle: SliderHandle { + x: control.leftPadding + (horizontal ? control.first.visualPosition * (control.availableWidth - width) : (control.availableWidth - width) / 2) + y: control.topPadding + (horizontal ? (control.availableHeight - height) / 2 : control.first.visualPosition * (control.availableHeight - height)) + value: first.value + handleHasFocus: activeFocus + handlePressed: first.pressed + } + //! [firstHandle] + + //! [secondHandle] + second.handle: SliderHandle { + x: control.leftPadding + (horizontal ? control.second.visualPosition * (control.availableWidth - width) : (control.availableWidth - width) / 2) + y: control.topPadding + (horizontal ? (control.availableHeight - height) / 2 : control.second.visualPosition * (control.availableHeight - height)) + value: second.value + handleHasFocus: activeFocus + handlePressed: second.pressed + } + //! [secondHandle] + + //! [track] + track: Rectangle { + x: control.leftPadding + (horizontal ? 0 : (control.availableWidth - width) / 2) + y: control.topPadding + (horizontal ? (control.availableHeight - height) / 2 : 0) + implicitWidth: horizontal ? 200 : 1 + implicitHeight: horizontal ? 1 : 200 + width: horizontal ? control.availableWidth : implicitWidth + height: horizontal ? implicitHeight : control.availableHeight + color: control.Material.primaryTextColor + scale: horizontal && control.mirrored ? -1 : 1 + + readonly property bool horizontal: control.orientation === Qt.Horizontal + + Rectangle { + x: parent.horizontal ? control.first.position * parent.width : -1 + y: parent.horizontal ? -1 : control.second.visualPosition * parent.height + 3 + width: parent.horizontal ? control.second.position * parent.width - control.first.position * parent.width - 3 : 3 + height: parent.horizontal ? 3 : control.second.position * parent.height - control.first.position * parent.height - 3 + + color: control.Material.accentColor + } + } + //! [track] +} diff --git a/src/imports/controls/material/Ripple.qml b/src/imports/controls/material/Ripple.qml new file mode 100644 index 00000000..a8fd27e8 --- /dev/null +++ b/src/imports/controls/material/Ripple.qml @@ -0,0 +1,51 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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$ +** +****************************************************************************/ + +import QtQuick 2.6 +import Qt.labs.controls.material 1.0 + +Rectangle { + property Item control + property bool colored: false + + radius: width / 2 + scale: 2.5 + color: colored ? control.Material.checkBoxCheckedRippleColor : control.Material.checkBoxUncheckedRippleColor + + Behavior on opacity { + NumberAnimation {} + } +} diff --git a/src/imports/controls/material/ScrollBar.qml b/src/imports/controls/material/ScrollBar.qml new file mode 100644 index 00000000..539b9243 --- /dev/null +++ b/src/imports/controls/material/ScrollBar.qml @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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$ +** +****************************************************************************/ + +import QtQuick 2.6 +import Qt.labs.templates 1.0 as T +import Qt.labs.controls.material 1.0 + +T.ScrollBar { + id: control + + implicitWidth: Math.max(background ? background.implicitWidth : 0, + handle.implicitWidth + leftPadding + rightPadding) + implicitHeight: Math.max(background ? background.implicitHeight : 0, + handle.implicitHeight + topPadding + bottomPadding) + + padding: 2 + + //! [handle] + handle: Rectangle { + id: handle + + implicitWidth: 4 + implicitHeight: 4 + + color: control.pressed ? control.Material.scrollBarPressedColor : control.Material.scrollBarColor + visible: control.size < 1.0 + opacity: 0.0 + + readonly property bool horizontal: control.orientation === Qt.Horizontal + x: control.leftPadding + (horizontal ? control.position * control.width : 0) + y: control.topPadding + (horizontal ? 0 : control.position * control.height) + width: horizontal ? control.size * control.availableWidth : implicitWidth + height: horizontal ? implicitHeight : control.size * control.availableHeight + + states: State { + name: "active" + when: control.active + PropertyChanges { target: handle; opacity: 0.75 } + } + + transitions: Transition { + from: "active" + SequentialAnimation { + PauseAnimation { duration: 450 } + NumberAnimation { target: handle; duration: 200; property: "opacity"; to: 0.0 } + } + } + } + //! [handle] +} diff --git a/src/imports/controls/material/ScrollIndicator.qml b/src/imports/controls/material/ScrollIndicator.qml new file mode 100644 index 00000000..f92b366f --- /dev/null +++ b/src/imports/controls/material/ScrollIndicator.qml @@ -0,0 +1,85 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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$ +** +****************************************************************************/ + +import QtQuick 2.6 +import Qt.labs.templates 1.0 as T +import Qt.labs.controls.material 1.0 + +T.ScrollIndicator { + id: control + + implicitWidth: Math.max(background ? background.implicitWidth : 0, + indicator.implicitWidth + leftPadding + rightPadding) + implicitHeight: Math.max(background ? background.implicitHeight : 0, + indicator.implicitHeight + topPadding + bottomPadding) + + padding: 2 + + //! [indicator] + indicator: Rectangle { + id: indicator + + implicitWidth: 4 + implicitHeight: 4 + + color: control.Material.scrollBarColor + visible: control.size < 1.0 + opacity: 0.0 + + readonly property bool horizontal: control.orientation === Qt.Horizontal + x: control.leftPadding + (horizontal ? control.position * control.width : 0) + y: control.topPadding + (horizontal ? 0 : control.position * control.height) + width: horizontal ? control.size * control.availableWidth : implicitWidth + height: horizontal ? implicitHeight : control.size * control.availableHeight + + states: State { + name: "active" + when: control.active + PropertyChanges { target: indicator; opacity: 0.75 } + } + + transitions: [ + Transition { + from: "active" + SequentialAnimation { + PauseAnimation { duration: 450 } + NumberAnimation { target: indicator; duration: 200; property: "opacity"; to: 0.0 } + } + } + ] + } + //! [indicator] +} diff --git a/src/imports/controls/material/Slider.qml b/src/imports/controls/material/Slider.qml new file mode 100644 index 00000000..139c9151 --- /dev/null +++ b/src/imports/controls/material/Slider.qml @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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$ +** +****************************************************************************/ + +import QtQuick 2.6 +import Qt.labs.templates 1.0 as T +import Qt.labs.controls.material 1.0 + +T.Slider { + id: control + + implicitWidth: Math.max(background ? background.implicitWidth : 0, + Math.max(track ? track.implicitWidth : 0, + handle ? handle.implicitWidth : 0) + leftPadding + rightPadding) + implicitHeight: Math.max(background ? background.implicitHeight : 0, + Math.max(track ? track.implicitHeight : 0, + handle ? handle.implicitHeight : 0) + topPadding + bottomPadding) + + padding: 6 + + //! [handle] + handle: SliderHandle { + x: control.leftPadding + (horizontal ? control.visualPosition * (control.availableWidth - width) : (control.availableWidth - width) / 2) + y: control.topPadding + (horizontal ? (control.availableHeight - height) / 2 : control.visualPosition * (control.availableHeight - height)) + value: control.value + handleHasFocus: control.activeFocus + handlePressed: control.pressed + } + //! [handle] + + //! [track] + track: Rectangle { + x: control.leftPadding + (horizontal ? 0 : (control.availableWidth - width) / 2) + y: control.topPadding + (horizontal ? (control.availableHeight - height) / 2 : 0) + implicitWidth: horizontal ? 200 : 1 + implicitHeight: horizontal ? 1 : 200 + width: horizontal ? control.availableWidth : implicitWidth + height: horizontal ? 1 : control.position * implicitHeight - 4 + color: control.Material.primaryTextColor + scale: horizontal && control.mirrored ? -1 : 1 + + readonly property bool horizontal: control.orientation === Qt.Horizontal + + Rectangle { + x: 0 + y: parent.horizontal ? -1 : control.visualPosition * parent.height + 3 + width: parent.horizontal ? control.position * parent.width : 3 + height: parent.horizontal ? 3 : control.availableHeight + + color: control.Material.accentColor + } + } + //! [track] +} diff --git a/src/imports/controls/material/SliderHandle.qml b/src/imports/controls/material/SliderHandle.qml new file mode 100644 index 00000000..dc1a836d --- /dev/null +++ b/src/imports/controls/material/SliderHandle.qml @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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$ +** +****************************************************************************/ + +import QtQuick 2.6 +import Qt.labs.controls.material 1.0 + +Item { + id: root + implicitWidth: initialSize + implicitHeight: initialSize + + property real value: 0 + property bool handleHasFocus: false + property bool handlePressed: false + readonly property int initialSize: 13 + readonly property bool horizontal: control.orientation === Qt.Horizontal + readonly property var control: parent + + Rectangle { + id: handleRect + width: parent.width + height: parent.height + radius: width / 2 + color: root.control.Material.accentColor + scale: root.handlePressed || root.handleHasFocus ? 1.5 : 1 + + Behavior on scale { + NumberAnimation { + duration: 250 + } + } + } +} diff --git a/src/imports/controls/material/SpinBox.qml b/src/imports/controls/material/SpinBox.qml new file mode 100644 index 00000000..3020efae --- /dev/null +++ b/src/imports/controls/material/SpinBox.qml @@ -0,0 +1,143 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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$ +** +****************************************************************************/ + +import QtQuick 2.6 +import QtGraphicalEffects 1.0 +import Qt.labs.templates 1.0 as T +import Qt.labs.controls.material 1.0 + +T.SpinBox { + id: control + + implicitWidth: Math.max(background ? background.implicitWidth : 0, + contentItem.implicitWidth + 2 * padding + + (up.indicator ? up.indicator.implicitWidth : 0) + + (down.indicator ? down.indicator.implicitWidth : 0)) + implicitHeight: Math.max(contentItem.implicitHeight + topPadding + bottomPadding, + background ? background.implicitHeight : 0, + up.indicator ? up.indicator.implicitHeight : 0, + down.indicator ? down.indicator.implicitHeight : 0) + + padding: 6 + leftPadding: 6 + (control.mirrored ? (up.indicator ? up.indicator.width : 0) : (down.indicator ? down.indicator.width : 0)) + rightPadding: 6 + (control.mirrored ? (down.indicator ? down.indicator.width : 0) : (up.indicator ? up.indicator.width : 0)) + + //! [validator] + validator: IntValidator { + locale: control.locale.name + bottom: Math.min(control.from, control.to) + top: Math.max(control.from, control.to) + } + //! [validator] + + //! [contentItem] + contentItem: TextInput { + text: control.textFromValue(control.value, control.locale) + + font: control.font + color: control.Material.primaryTextColor + selectionColor: control.Material.textSelectionColor + selectedTextColor: control.Material.primaryTextColor + horizontalAlignment: Qt.AlignHCenter + verticalAlignment: Qt.AlignVCenter + + validator: control.validator + inputMethodHints: Qt.ImhFormattedNumbersOnly + } + //! [contentItem] + + //! [up.indicator] + up.indicator: Rectangle { + x: control.mirrored ? 0 : parent.width - width + implicitWidth: 26 + height: parent.height + radius: 3 + color: Qt.tint(Qt.tint(control.Material.raisedButtonColor, + control.activeFocus ? control.Material.raisedButtonHoverColor : "transparent"), + control.up.pressed ? control.Material.raisedButtonPressColor: "transparent") + + Rectangle { + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + width: Math.min(parent.width / 3, parent.width / 3) + height: 2 + color: control.Material.primaryTextColor + } + Rectangle { + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + width: 2 + height: Math.min(parent.width / 3, parent.width / 3) + color: control.Material.primaryTextColor + } + } + //! [up.indicator] + + //! [down.indicator] + down.indicator: Rectangle { + x: control.mirrored ? parent.width - width : 0 + implicitWidth: 26 + height: parent.height + radius: 3 + color: Qt.tint(Qt.tint(control.Material.raisedButtonColor, + control.activeFocus ? control.Material.raisedButtonHoverColor : "transparent"), + control.down.pressed ? control.Material.raisedButtonPressColor : "transparent") + + Rectangle { + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + width: parent.width / 3 + height: 2 + color: control.Material.primaryTextColor + } + } + //! [down.indicator] + + //! [background] + background: Item { + implicitWidth: 100 + implicitHeight: 26 + + Rectangle { + x: parent.width / 2 - width / 2 + y: parent.y + parent.height - height + width: Math.max(26, control.contentItem.implicitWidth) + height: control.activeFocus ? 2 : 1 + color: control.activeFocus ? control.Material.accentColor : control.Material.hintTextColor + } + } + //! [background] +} diff --git a/src/imports/controls/material/StackView.qml b/src/imports/controls/material/StackView.qml new file mode 100644 index 00000000..c4ed33e5 --- /dev/null +++ b/src/imports/controls/material/StackView.qml @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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$ +** +****************************************************************************/ + +import QtQuick 2.4 +import Qt.labs.templates 1.0 as T + +T.StackView { + id: root + + //! [popEnter] + popEnter: Transition { + XAnimator { from: -root.width; to: 0; duration: 400; easing.type: Easing.OutCubic } + } + //! [popEnter] + + //! [popExit] + popExit: Transition { + XAnimator { from: 0; to: root.width; duration: 400; easing.type: Easing.OutCubic } + } + //! [popExit] + + //! [pushEnter] + pushEnter: Transition { + XAnimator { from: root.width; to: 0; duration: 400; easing.type: Easing.OutCubic } + } + //! [pushEnter] + + //! [pushExit] + pushExit: Transition { + XAnimator { from: 0; to: -root.width; duration: 400; easing.type: Easing.OutCubic } + } + //! [pushExit] + + //! [replaceEnter] + replaceEnter: Transition { + XAnimator { from: root.width; to: 0; duration: 400; easing.type: Easing.OutCubic } + } + //! [replaceEnter] + + //! [replaceExit] + replaceExit: Transition { + XAnimator { from: 0; to: -root.width; duration: 400; easing.type: Easing.OutCubic } + } + //! [replaceExit] +} diff --git a/src/imports/controls/material/SwipeView.qml b/src/imports/controls/material/SwipeView.qml new file mode 100644 index 00000000..00655bcb --- /dev/null +++ b/src/imports/controls/material/SwipeView.qml @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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$ +** +****************************************************************************/ + +import QtQuick 2.6 +import Qt.labs.templates 1.0 as T + +T.SwipeView { + id: control + + implicitWidth: Math.max(background ? background.implicitWidth : 0, + contentItem.implicitWidth + leftPadding + rightPadding) + implicitHeight: Math.max(background ? background.implicitHeight : 0, + contentItem.implicitHeight + topPadding + bottomPadding) + + //! [contentItem] + contentItem: ListView { + model: control.contentModel + currentIndex: control.currentIndex + + spacing: control.spacing + orientation: Qt.Horizontal + snapMode: ListView.SnapOneItem + boundsBehavior: Flickable.StopAtBounds + + highlightRangeMode: ListView.StrictlyEnforceRange + preferredHighlightBegin: 0 + preferredHighlightEnd: 0 + highlightMoveDuration: 250 + } + //! [contentItem] +} diff --git a/src/imports/controls/material/Switch.qml b/src/imports/controls/material/Switch.qml new file mode 100644 index 00000000..6e612d40 --- /dev/null +++ b/src/imports/controls/material/Switch.qml @@ -0,0 +1,125 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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$ +** +****************************************************************************/ + +import QtQuick 2.6 +import Qt.labs.controls.material 1.0 +import Qt.labs.templates 1.0 as T +import QtGraphicalEffects 1.0 + +T.Switch { + id: control + + implicitWidth: Math.max(background ? background.implicitWidth : 0, + (label ? label.implicitWidth : 0) + + (indicator ? indicator.implicitWidth : 0) + + (label && indicator ? spacing : 0) + leftPadding + rightPadding) + implicitHeight: Math.max(background ? background.implicitHeight : 0, + Math.max(label ? label.implicitHeight : 0, + indicator ? indicator.implicitHeight : 0) + topPadding + bottomPadding) + baselineOffset: label ? label.y + label.baselineOffset : 0 + + padding: 6 + spacing: 6 + + //! [indicator] + indicator: Item { + x: text ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) : control.leftPadding + (control.availableWidth - width) / 2 + y: control.topPadding + (control.availableHeight - height) / 2 + implicitWidth: 40 + implicitHeight: 20 + + Ripple { + x: handle.x + handle.width / 2 - width / 2 + y: handle.y + handle.height / 2 - height / 2 + width: handle.width - 4 + height: width + control: control + colored: control.checked + opacity: control.pressed ? 1 : 0 + } + + Rectangle { + width: parent.width + height: 16 + radius: height / 2 + y: parent.height / 2 - height / 2 + color: control.enabled ? (control.checked ? control.Material.switchCheckedTrackColor : control.Material.switchUncheckedTrackColor) + : control.Material.switchDisabledTrackColor + } + + Rectangle { + id: handle + x: Math.max(0, Math.min(parent.width - width, control.visualPosition * parent.width - (width / 2))) + y: (parent.height - height) / 2 + width: 24 + height: 24 + radius: width / 2 + color: control.enabled ? (control.checked ? control.Material.switchCheckedHandleColor : control.Material.switchUncheckedHandleColor) + : control.Material.switchDisabledHandleColor + layer.enabled: true + layer.effect: DropShadow { + verticalOffset: 1 + color: control.Material.dropShadowColor + spread: 0.3 + } + + Behavior on x { + enabled: !control.pressed + SmoothedAnimation { + duration: 300 + } + } + } + } + //! [indicator] + + //! [label] + label: Text { + x: control.mirrored ? control.leftPadding : (indicator.x + indicator.width + control.spacing) + y: control.topPadding + width: control.availableWidth - indicator.width - control.spacing + height: control.availableHeight + + text: control.text + font: control.font + color: control.enabled ? control.Material.primaryTextColor : control.Material.hintTextColor + elide: Text.ElideRight + visible: control.text + horizontalAlignment: Text.AlignLeft + verticalAlignment: Text.AlignVCenter + } + //! [label] +} diff --git a/src/imports/controls/material/TabBar.qml b/src/imports/controls/material/TabBar.qml new file mode 100644 index 00000000..4aaef818 --- /dev/null +++ b/src/imports/controls/material/TabBar.qml @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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$ +** +****************************************************************************/ + +import QtQuick 2.6 +import Qt.labs.templates 1.0 as T +import Qt.labs.controls.material 1.0 + +T.TabBar { + id: control + + implicitWidth: Math.max(26, contentItem.implicitWidth + leftPadding + rightPadding) + implicitHeight: Math.max(26, contentItem.implicitHeight + topPadding + bottomPadding) + + spacing: 1 + + //! [contentItem] + contentItem: ListView { + implicitWidth: contentWidth + implicitHeight: contentHeight + + model: control.contentModel + currentIndex: control.currentIndex + + spacing: control.spacing + orientation: ListView.Horizontal + boundsBehavior: Flickable.StopAtBounds + snapMode: ListView.SnapToItem + + highlightMoveDuration: 250 + highlightResizeDuration: 0 + highlightFollowsCurrentItem: true + highlight: Item { + z: 2 + Rectangle { + height: 2 + width: parent.width + y: parent.height - height + color: control.Material.accentColor + } + } + } + //! [contentItem] +} diff --git a/src/imports/controls/material/TabButton.qml b/src/imports/controls/material/TabButton.qml new file mode 100644 index 00000000..67473744 --- /dev/null +++ b/src/imports/controls/material/TabButton.qml @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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$ +** +****************************************************************************/ + +import QtQuick 2.6 +import Qt.labs.templates 1.0 as T +import Qt.labs.controls.material 1.0 + +T.TabButton { + id: control + + implicitWidth: Math.max(background ? background.implicitWidth : 0, + label ? label.implicitWidth + leftPadding + rightPadding : 0) + implicitHeight: Math.max(background ? background.implicitHeight : 0, + label ? label.implicitHeight + topPadding + bottomPadding : 0) + baselineOffset: label ? label.y + label.baselineOffset : 0 + + padding: 6 + + //! [label] + label: Text { + x: control.leftPadding + y: control.topPadding + width: control.availableWidth + height: control.availableHeight + + text: control.text + font: control.font + elide: Text.ElideRight + color: !control.enabled ? control.Material.hintTextColor : control.pressed || control.checked ? control.Material.accentColor : control.Material.primaryTextColor + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + //! [label] + + //! [background] + background: Item { + height: parent.height - 1 + implicitHeight: 26 + } + //! [background] +} diff --git a/src/imports/controls/material/TextArea.qml b/src/imports/controls/material/TextArea.qml new file mode 100644 index 00000000..a5423727 --- /dev/null +++ b/src/imports/controls/material/TextArea.qml @@ -0,0 +1,107 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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$ +** +****************************************************************************/ + +import QtQuick 2.6 +import Qt.labs.templates 1.0 as T +import Qt.labs.controls.material 1.0 + +T.TextArea { + id: control + + implicitWidth: Math.max(contentWidth + leftPadding + rightPadding, + background ? background.implicitWidth : 0, + placeholder.implicitWidth + leftPadding + rightPadding) + implicitHeight: Math.max(contentHeight + topPadding + bottomPadding, + background ? background.implicitHeight : 0, + placeholder.implicitHeight + topPadding + bottomPadding) + + padding: 6 + + color: enabled ? Material.primaryTextColor : Material.hintTextColor + selectionColor: Material.accentColor + selectedTextColor: Material.primaryHighlightedTextColor + cursorDelegate: Rectangle { + id: cursor + color: control.Material.accentColor + width: 2 + visible: control.activeFocus && control.selectionStart === control.selectionEnd + + Connections { + target: control + onCursorPositionChanged: { + // keep a moving cursor visible + cursor.opacity = 1 + timer.restart() + } + } + + Timer { + id: timer + running: control.activeFocus + repeat: true + interval: Qt.styleHints.cursorFlashTime + onTriggered: cursor.opacity = !cursor.opacity ? 1 : 0 + // force the cursor visible when gaining focus + onRunningChanged: cursor.opacity = 1 + } + } + + //! [placeholder] + Text { + id: placeholder + x: control.leftPadding + y: control.topPadding + width: control.width - (control.leftPadding + control.rightPadding) + height: control.height - (control.topPadding + control.bottomPadding) + text: control.placeholderText + font: control.font + color: control.Material.hintTextColor + horizontalAlignment: control.horizontalAlignment + verticalAlignment: control.verticalAlignment + elide: Text.ElideRight + visible: !control.length && (!control.activeFocus || control.horizontalAlignment !== Qt.AlignHCenter) + } + //! [placeholder] + + //! [background] + background: Rectangle { + y: control.height - height + implicitWidth: 120 + height: control.activeFocus ? 2 : 1 + color: control.activeFocus ? control.Material.accentColor : control.Material.hintTextColor + } + //! [background] +} diff --git a/src/imports/controls/material/TextField.qml b/src/imports/controls/material/TextField.qml new file mode 100644 index 00000000..6a0010f7 --- /dev/null +++ b/src/imports/controls/material/TextField.qml @@ -0,0 +1,107 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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$ +** +****************************************************************************/ + +import QtQuick 2.6 +import Qt.labs.templates 1.0 as T +import Qt.labs.controls.material 1.0 + +T.TextField { + id: control + + implicitWidth: Math.max(background ? background.implicitWidth : 0, + placeholder.implicitWidth + leftPadding + rightPadding) + implicitHeight: Math.max(background ? background.implicitHeight : 0, + placeholder.implicitHeight + topPadding + bottomPadding) + + padding: 6 + + color: enabled ? Material.primaryTextColor : Material.hintTextColor + selectionColor: Material.accentColor + selectedTextColor: Material.primaryHighlightedTextColor + verticalAlignment: TextInput.AlignVCenter + cursorDelegate: Rectangle { + id: cursor + color: control.Material.accentColor + width: 2 + visible: control.activeFocus && control.selectionStart === control.selectionEnd + + Connections { + target: control + onCursorPositionChanged: { + // keep a moving cursor visible + cursor.opacity = 1 + timer.restart() + } + } + + Timer { + id: timer + running: control.activeFocus + repeat: true + interval: Qt.styleHints.cursorFlashTime + onTriggered: cursor.opacity = !cursor.opacity ? 1 : 0 + // force the cursor visible when gaining focus + onRunningChanged: cursor.opacity = 1 + } + } + + //! [placeholder] + Text { + id: placeholder + x: control.leftPadding + y: control.topPadding + width: control.width - (control.leftPadding + control.rightPadding) + height: control.height - (control.topPadding + control.bottomPadding) + text: control.placeholderText + font: control.font + color: control.Material.hintTextColor + horizontalAlignment: control.horizontalAlignment + verticalAlignment: control.verticalAlignment + elide: Text.ElideRight + visible: !control.displayText && (!control.activeFocus || control.horizontalAlignment !== Qt.AlignHCenter) + + } + //! [placeholder] + + //! [background] + background: Rectangle { + y: control.height - height + implicitWidth: 120 + height: control.activeFocus ? 2 : 1 + color: control.activeFocus ? control.Material.accentColor : control.Material.hintTextColor + } + //! [background] +} diff --git a/src/imports/controls/material/ToolBar.qml b/src/imports/controls/material/ToolBar.qml new file mode 100644 index 00000000..59a0e599 --- /dev/null +++ b/src/imports/controls/material/ToolBar.qml @@ -0,0 +1,52 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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$ +** +****************************************************************************/ + +import QtQuick 2.6 +import Qt.labs.templates 1.0 as T + +T.ToolBar { + id: control + + implicitWidth: contentWidth + leftPadding + rightPadding + implicitHeight: Math.max(26, contentHeight + topPadding + bottomPadding) + + contentWidth: contentChildren.length === 1 ? contentChildren[0].implicitWidth : 0 + contentHeight: contentChildren.length === 1 ? contentChildren[0].implicitHeight : 0 + + //! [contentItem] + contentItem: Item { } + //! [contentItem] +} diff --git a/src/imports/controls/material/ToolButton.qml b/src/imports/controls/material/ToolButton.qml new file mode 100644 index 00000000..4f72f4ef --- /dev/null +++ b/src/imports/controls/material/ToolButton.qml @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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$ +** +****************************************************************************/ + +import QtQuick 2.6 +import Qt.labs.templates 1.0 as T +import Qt.labs.controls.material 1.0 + +T.ToolButton { + id: control + + implicitWidth: Math.max(background ? background.implicitWidth : 0, + label ? label.implicitWidth + leftPadding + rightPadding : 0) + implicitHeight: Math.max(background ? background.implicitHeight : 0, + label ? label.implicitHeight + topPadding + bottomPadding : 0) + baselineOffset: label ? label.y + label.baselineOffset : 0 + + padding: 6 + + //! [label] + label: Text { + x: control.leftPadding + y: control.topPadding + width: control.availableWidth + height: control.availableHeight + + text: control.text + font: control.font + color: control.enabled ? control.Material.primaryTextColor : control.Material.hintTextColor + elide: Text.ElideRight + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + //! [label] + + //! [background] + background: Rectangle { + implicitWidth: 26 + implicitHeight: 26 + + color: control.activeFocus || (control.checkable && control.checked) + ? control.Material.flatButtonFocusColor : control.Material.flatButtonPressColor + visible: control.pressed || control.activeFocus || (control.checkable && control.checked) + } + //! [background] +} diff --git a/src/imports/controls/material/Tumbler.qml b/src/imports/controls/material/Tumbler.qml new file mode 100644 index 00000000..e5b930a8 --- /dev/null +++ b/src/imports/controls/material/Tumbler.qml @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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$ +** +****************************************************************************/ + +import QtQuick 2.6 +import Qt.labs.controls 1.0 +import Qt.labs.templates 1.0 as T +import Qt.labs.controls.material 1.0 + +T.Tumbler { + id: control + implicitWidth: 60 + implicitHeight: 200 + + //! [delegate] + delegate: Text { + id: label + text: modelData + color: control.Material.primaryTextColor + font: control.font + opacity: 0.4 + Math.max(0, 1 - Math.abs(Tumbler.displacement)) * 0.6 + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + //! [delegate] + + //! [contentItem] + contentItem: PathView { + id: pathView + model: control.model + delegate: control.delegate + clip: true + pathItemCount: control.visibleItemCount + 1 + preferredHighlightBegin: 0.5 + preferredHighlightEnd: 0.5 + dragMargin: width / 2 + + path: Path { + startX: pathView.width / 2 + startY: -pathView.delegateHeight / 2 + PathLine { + x: pathView.width / 2 + y: pathView.pathItemCount * pathView.delegateHeight - pathView.delegateHeight / 2 + } + } + + property real delegateHeight: control.availableHeight / control.visibleItemCount + } + //! [contentItem] +} diff --git a/src/imports/controls/material/images/check.png b/src/imports/controls/material/images/check.png Binary files differnew file mode 100644 index 00000000..4e4e3be8 --- /dev/null +++ b/src/imports/controls/material/images/check.png diff --git a/src/imports/controls/material/images/check@2x.png b/src/imports/controls/material/images/check@2x.png Binary files differnew file mode 100644 index 00000000..744f80b5 --- /dev/null +++ b/src/imports/controls/material/images/check@2x.png diff --git a/src/imports/controls/material/images/check@3x.png b/src/imports/controls/material/images/check@3x.png Binary files differnew file mode 100644 index 00000000..dbf12b6d --- /dev/null +++ b/src/imports/controls/material/images/check@3x.png diff --git a/src/imports/controls/material/images/check@4x.png b/src/imports/controls/material/images/check@4x.png Binary files differnew file mode 100644 index 00000000..764dd7ee --- /dev/null +++ b/src/imports/controls/material/images/check@4x.png diff --git a/src/imports/controls/material/material.pri b/src/imports/controls/material/material.pri new file mode 100644 index 00000000..a238dcfe --- /dev/null +++ b/src/imports/controls/material/material.pri @@ -0,0 +1,41 @@ +HEADERS += \ + $$PWD/qquickmaterialstyle_p.h \ + $$PWD/qquickmaterialtheme_p.h \ + $$PWD/qquickmaterialprogressring_p.h + +SOURCES += \ + $$PWD/qquickmaterialstyle.cpp \ + $$PWD/qquickmaterialtheme.cpp \ + $$PWD/qquickmaterialprogressring.cpp + +QML_FILES += \ + $$PWD/ApplicationWindow.qml \ + $$PWD/BusyIndicator.qml \ + $$PWD/Button.qml \ + $$PWD/CheckBox.qml \ + $$PWD/Dial.qml \ + $$PWD/Drawer.qml \ + $$PWD/Frame.qml \ + $$PWD/GroupBox.qml \ + $$PWD/ItemDelegate.qml \ + $$PWD/Label.qml \ + $$PWD/PageIndicator.qml \ + $$PWD/ProgressBar.qml \ + $$PWD/RadioButton.qml \ + $$PWD/RangeSlider.qml \ + $$PWD/Ripple.qml \ + $$PWD/ScrollBar.qml \ + $$PWD/ScrollIndicator.qml \ + $$PWD/Slider.qml \ + $$PWD/SliderHandle.qml \ + $$PWD/SpinBox.qml \ + $$PWD/StackView.qml \ + $$PWD/SwipeView.qml \ + $$PWD/Switch.qml \ + $$PWD/TabBar.qml \ + $$PWD/TabButton.qml \ + $$PWD/TextArea.qml \ + $$PWD/TextField.qml \ + $$PWD/ToolBar.qml \ + $$PWD/ToolButton.qml \ + $$PWD/Tumbler.qml diff --git a/src/imports/controls/material/material.pro b/src/imports/controls/material/material.pro new file mode 100644 index 00000000..06b9ed7d --- /dev/null +++ b/src/imports/controls/material/material.pro @@ -0,0 +1,22 @@ +TARGET = qtlabsmaterialstyleplugin +TARGETPATH = Qt/labs/controls/material +IMPORT_VERSION = 1.0 + +QT += qml quick +QT_PRIVATE += core-private gui-private qml-private quick-private labscontrols-private + +DEFINES += QT_NO_CAST_TO_ASCII QT_NO_CAST_FROM_ASCII + +OTHER_FILES += \ + qmldir + +SOURCES += \ + $$PWD/qtlabsmaterialstyleplugin.cpp + +RESOURCES += \ + $$PWD/qtlabsmaterialstyleplugin.qrc + +include(material.pri) + +CONFIG += no_cxx_module +load(qml_plugin) diff --git a/src/imports/controls/material/qmldir b/src/imports/controls/material/qmldir new file mode 100644 index 00000000..19f71b4a --- /dev/null +++ b/src/imports/controls/material/qmldir @@ -0,0 +1,4 @@ +module Qt.labs.controls.material +plugin qtlabsmaterialstyleplugin +classname QtLabsMaterialStylePlugin +depends Qt.labs.controls 1.0 diff --git a/src/imports/controls/material/qquickmaterialprogressring.cpp b/src/imports/controls/material/qquickmaterialprogressring.cpp new file mode 100644 index 00000000..9953266d --- /dev/null +++ b/src/imports/controls/material/qquickmaterialprogressring.cpp @@ -0,0 +1,280 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 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 "qquickmaterialprogressring_p.h" + +#include <cmath> + +#include <QtCore/qset.h> +#include <QtGui/qpainter.h> +#include <QtQuick/private/qquickitem_p.h> +#include <QtQuick/qsgsimplerectnode.h> +#include <QtQuick/qsgsimpletexturenode.h> +#include <QtQuick/qquickwindow.h> + +QT_BEGIN_NAMESPACE + +/* + Relevant Android code: + + - core/res/res/anim/progress_indeterminate_rotation_material.xml contains + the rotation animation data. + - core/res/res/anim/progress_indeterminate_material.xml contains the trim + animation data. + - core/res/res/interpolator/trim_start_interpolator.xml and + core/res/res/interpolator/trim_end_interpolator.xml contain the start + and end trim path interpolators. + - addCommand() in core/java/android/util/PathParser.java has a list of the + different path commands available. +*/ + +class QQuickMaterialRingAnimatorJob : public QQuickAnimatorJob +{ +public: + QQuickMaterialRingAnimatorJob(); + ~QQuickMaterialRingAnimatorJob(); + + void initialize(QQuickAnimatorController *controller) Q_DECL_OVERRIDE; + void updateCurrentTime(int time) Q_DECL_OVERRIDE; + void writeBack() Q_DECL_OVERRIDE; + void nodeWasDestroyed() Q_DECL_OVERRIDE; + +private: + QSGNode *m_itemNode; + QQuickWindow *m_window; +}; + +class QQuickMaterialRingTexture : public QSGSimpleTextureNode +{ +public: + QQuickMaterialRingTexture(); + ~QQuickMaterialRingTexture(); + + QColor color() const; + void setColor(QColor color); + +private: + QColor m_color; +}; + +QQuickMaterialProgressRing::QQuickMaterialProgressRing(QQuickItem *parent) : + QQuickItem(parent) +{ + setFlag(QQuickItem::ItemHasContents); +} + +QQuickMaterialProgressRing::~QQuickMaterialProgressRing() +{ +} + +QSGNode *QQuickMaterialProgressRing::updatePaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *) +{ + if (!oldNode) + oldNode = new QSGSimpleRectNode(boundingRect(), Qt::transparent); + + static_cast<QSGSimpleRectNode *>(oldNode)->setRect(boundingRect()); + + QQuickMaterialRingTexture *textureNode = static_cast<QQuickMaterialRingTexture*>(oldNode->firstChild()); + if (!textureNode) { + textureNode = new QQuickMaterialRingTexture; + textureNode->setOwnsTexture(true); + oldNode->appendChildNode(textureNode); + } + + // A texture seems to be required here, but we don't have one yet, as we haven't drawn anything, + // so just use a blank image. + QImage blankImage(width(), height(), QImage::Format_ARGB32_Premultiplied); + blankImage.fill(Qt::transparent); + textureNode->setColor(m_color); + textureNode->setRect(boundingRect()); + textureNode->setTexture(window()->createTextureFromImage(blankImage)); + + return oldNode; +} + +QColor QQuickMaterialProgressRing::color() const +{ + return m_color; +} + +void QQuickMaterialProgressRing::setColor(QColor color) +{ + if (m_color != color) { + m_color = color; + update(); + emit colorChanged(); + } +} + +static const int spanAnimationDuration = 700; +static const int rotationAnimationDuration = spanAnimationDuration * 6; +static const int targetRotation = 720; +static const int oneDegree = 16; +static const qreal minSweepSpan = 10 * oneDegree; +static const qreal maxSweepSpan = 300 * oneDegree; + +QQuickMaterialRingAnimator::QQuickMaterialRingAnimator(QObject *parent) : + QQuickAnimator(parent) +{ + setDuration(rotationAnimationDuration); + setLoops(QQuickAnimator::Infinite); +} + +QString QQuickMaterialRingAnimator::propertyName() const +{ + return QString(); +} + +QQuickAnimatorJob *QQuickMaterialRingAnimator::createJob() const +{ + return new QQuickMaterialRingAnimatorJob; +} + +QQuickMaterialRingAnimatorJob::QQuickMaterialRingAnimatorJob() : + m_itemNode(Q_NULLPTR), + m_window(Q_NULLPTR) +{ +} + +QQuickMaterialRingAnimatorJob::~QQuickMaterialRingAnimatorJob() +{ +} + +void QQuickMaterialRingAnimatorJob::initialize(QQuickAnimatorController *controller) +{ + QQuickAnimatorJob::initialize(controller); + m_itemNode = QQuickItemPrivate::get(m_target)->itemNode(); + m_window = m_target->window(); +} + +void QQuickMaterialRingAnimatorJob::updateCurrentTime(int time) +{ + QSGNode *childContainerNode = QQuickItemPrivate::get(m_target)->childContainerNode(); + QSGSimpleRectNode *rectNode = static_cast<QSGSimpleRectNode*>(childContainerNode->firstChild()); + if (!rectNode) + return; + + Q_ASSERT(rectNode->type() == QSGNode::GeometryNodeType); + + const qreal width = rectNode->rect().width(); + const qreal height = rectNode->rect().height(); + QImage image(width, height, QImage::Format_ARGB32_Premultiplied); + image.fill(Qt::transparent); + + QPainter painter(&image); + painter.setRenderHint(QPainter::Antialiasing); + + QPen pen; + QQuickMaterialRingTexture *textureNode = static_cast<QQuickMaterialRingTexture*>(rectNode->firstChild()); + pen.setColor(textureNode->color()); + pen.setWidth(4); + painter.setPen(pen); + + const qreal percentageComplete = time / qreal(rotationAnimationDuration); + const qreal spanPercentageComplete = (time % spanAnimationDuration) / qreal(spanAnimationDuration); + const int iteration = time / spanAnimationDuration; + int startAngle = 0; + int endAngle = 0; + static int lastStartAngle = 0; + static int lastEndAngle = 0; + + if (iteration % 2 == 0) { + if (lastStartAngle > 360 * oneDegree) { + lastStartAngle -= 360 * oneDegree; + } + + // The start angle is only affected by the rotation animation for the "grow" phase. + startAngle = lastStartAngle; + // TODO: use the correct curve here. QEasingCurve's bezier API doesn't support SVG path data. + QEasingCurve angleCurve(QEasingCurve::OutQuad); + const qreal percentage = angleCurve.valueForProgress(spanPercentageComplete); + endAngle = lastStartAngle + minSweepSpan + percentage * (maxSweepSpan - minSweepSpan); + lastEndAngle = endAngle; + } else { + // Both the start angle *and* the span are affected by the "shrink" phase. + // TODO: use the correct curve here. QEasingCurve's bezier API doesn't support SVG path data. + QEasingCurve angleCurve(QEasingCurve::InQuad); + const qreal percentage = angleCurve.valueForProgress(spanPercentageComplete); + startAngle = lastEndAngle - maxSweepSpan + percentage * (maxSweepSpan - minSweepSpan); + endAngle = lastEndAngle; + lastStartAngle = startAngle; + } + + const int halfPen = pen.width() / 2; + const QRectF arcBounds = QRectF(rectNode->rect().adjusted(halfPen, halfPen, -halfPen, -halfPen)); + // The current angle of the rotation animation. + const qreal rotation = oneDegree * percentageComplete * -targetRotation; + startAngle -= rotation; + endAngle -= rotation; + const int angleSpan = endAngle - startAngle; + painter.drawArc(arcBounds, -startAngle, -angleSpan); + painter.end(); + + textureNode->setTexture(m_window->createTextureFromImage(image)); +} + +void QQuickMaterialRingAnimatorJob::writeBack() +{ +} + +void QQuickMaterialRingAnimatorJob::nodeWasDestroyed() +{ + m_itemNode = Q_NULLPTR; + m_window = Q_NULLPTR; +} + +QQuickMaterialRingTexture::QQuickMaterialRingTexture() +{ +} + +QQuickMaterialRingTexture::~QQuickMaterialRingTexture() +{ +} + +QColor QQuickMaterialRingTexture::color() const +{ + return m_color; +} + +void QQuickMaterialRingTexture::setColor(QColor color) +{ + m_color = color; +} + +Q_DECLARE_TYPEINFO(QQuickMaterialRingAnimatorJob, Q_COMPLEX_TYPE); +Q_DECLARE_TYPEINFO(QQuickMaterialRingTexture, Q_COMPLEX_TYPE); + +QT_END_NAMESPACE diff --git a/src/imports/controls/material/qquickmaterialprogressring_p.h b/src/imports/controls/material/qquickmaterialprogressring_p.h new file mode 100644 index 00000000..17845a66 --- /dev/null +++ b/src/imports/controls/material/qquickmaterialprogressring_p.h @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 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 QQUICKMATERIALPROGRESSRING_P_H +#define QQUICKMATERIALPROGRESSRING_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 <QtGui/qcolor.h> +#include <QtQuick/qquickitem.h> +#include <QtQuick/private/qquickanimatorjob_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickMaterialProgressRing : public QQuickItem +{ + Q_OBJECT + Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged FINAL) + +public: + explicit QQuickMaterialProgressRing(QQuickItem *parent = Q_NULLPTR); + ~QQuickMaterialProgressRing(); + + QColor color() const; + void setColor(QColor color); + +Q_SIGNALS: + void colorChanged(); + +protected: + QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) Q_DECL_OVERRIDE; + +private: + QColor m_color; +}; + +class QQuickMaterialRingAnimator : public QQuickAnimator +{ +public: + QQuickMaterialRingAnimator(QObject *parent = Q_NULLPTR); + +protected: + QString propertyName() const Q_DECL_OVERRIDE; + QQuickAnimatorJob *createJob() const Q_DECL_OVERRIDE; +}; + +Q_DECLARE_TYPEINFO(QQuickMaterialProgressRing, Q_COMPLEX_TYPE); +Q_DECLARE_TYPEINFO(QQuickMaterialRingAnimator, Q_COMPLEX_TYPE); + +QT_END_NAMESPACE + +#endif // QQUICKMATERIALPROGRESSRING_P_H diff --git a/src/imports/controls/material/qquickmaterialstyle.cpp b/src/imports/controls/material/qquickmaterialstyle.cpp new file mode 100644 index 00000000..a3d2329a --- /dev/null +++ b/src/imports/controls/material/qquickmaterialstyle.cpp @@ -0,0 +1,751 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 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 "qquickmaterialstyle_p.h" + +#include <QtLabsControls/private/qquickstyle_p.h> + +QT_BEGIN_NAMESPACE + +/*! + \qmltype Material + \inherits QtObject + \instantiates QQuickMaterialStyleAttached + \inqmlmodule QtQuick.Controls.Material + \ingroup utilities + \brief A style interface. + + TODO +*/ + +/*! + \qmlattachedproperty color QtQuickControls2::Material::textColorPrimaray +*/ + +static const QColor colors[][14] = { + // Red + { + "#FFEBEE", // Shade50 + "#FFCDD2", // Shade100 + "#EF9A9A", // Shade200 + "#E57373", // Shade300 + "#EF5350", // Shade400 + "#F44336", // Shade500 + "#E53935", // Shade600 + "#D32F2F", // Shade700 + "#C62828", // Shade800 + "#B71C1C", // Shade900 + "#FF8A80", // ShadeA100 + "#FF5252", // ShadeA200 + "#FF1744", // ShadeA400 + "#D50000" // ShadeA700 + }, + // Pink + { + "#FCE4EC", // Shade50 + "#F8BBD0", // Shade100 + "#F48FB1", // Shade200 + "#F06292", // Shade300 + "#EC407A", // Shade400 + "#E91E63", // Shade500 + "#D81B60", // Shade600 + "#C2185B", // Shade700 + "#AD1457", // Shade800 + "#880E4F", // Shade900 + "#FF80AB", // ShadeA100 + "#FF4081", // ShadeA200 + "#F50057", // ShadeA400 + "#C51162" // ShadeA700 + }, + // Purple + { + "#F3E5F5", // Shade50 + "#E1BEE7", // Shade100 + "#CE93D8", // Shade200 + "#BA68C8", // Shade300 + "#AB47BC", // Shade400 + "#9C27B0", // Shade500 + "#8E24AA", // Shade600 + "#7B1FA2", // Shade700 + "#6A1B9A", // Shade800 + "#4A148C", // Shade900 + "#EA80FC", // ShadeA100 + "#E040FB", // ShadeA200 + "#D500F9", // ShadeA400 + "#AA00FF" // ShadeA700 + }, + // DeepPurple + { + "#EDE7F6", // Shade50 + "#D1C4E9", // Shade100 + "#B39DDB", // Shade200 + "#9575CD", // Shade300 + "#7E57C2", // Shade400 + "#673AB7", // Shade500 + "#5E35B1", // Shade600 + "#512DA8", // Shade700 + "#4527A0", // Shade800 + "#311B92", // Shade900 + "#B388FF", // ShadeA100 + "#7C4DFF", // ShadeA200 + "#651FFF", // ShadeA400 + "#6200EA" // ShadeA700 + }, + // Indigo + { + "#E8EAF6", // Shade50 + "#C5CAE9", // Shade100 + "#9FA8DA", // Shade200 + "#7986CB", // Shade300 + "#5C6BC0", // Shade400 + "#3F51B5", // Shade500 + "#3949AB", // Shade600 + "#303F9F", // Shade700 + "#283593", // Shade800 + "#1A237E", // Shade900 + "#8C9EFF", // ShadeA100 + "#536DFE", // ShadeA200 + "#3D5AFE", // ShadeA400 + "#304FFE" // ShadeA700 + }, + // Blue + { + "#E3F2FD", // Shade50 + "#BBDEFB", // Shade100 + "#90CAF9", // Shade200 + "#64B5F6", // Shade300 + "#42A5F5", // Shade400 + "#2196F3", // Shade500 + "#1E88E5", // Shade600 + "#1976D2", // Shade700 + "#1565C0", // Shade800 + "#0D47A1", // Shade900 + "#82B1FF", // ShadeA100 + "#448AFF", // ShadeA200 + "#2979FF", // ShadeA400 + "#2962FF" // ShadeA700 + }, + // LightBlue + { + "#E1F5FE", // Shade50 + "#B3E5FC", // Shade100 + "#81D4FA", // Shade200 + "#4FC3F7", // Shade300 + "#29B6F6", // Shade400 + "#03A9F4", // Shade500 + "#039BE5", // Shade600 + "#0288D1", // Shade700 + "#0277BD", // Shade800 + "#01579B", // Shade900 + "#80D8FF", // ShadeA100 + "#40C4FF", // ShadeA200 + "#00B0FF", // ShadeA400 + "#0091EA" // ShadeA700 + }, + // Cyan + { + "#E0F7FA", // Shade50 + "#B2EBF2", // Shade100 + "#80DEEA", // Shade200 + "#4DD0E1", // Shade300 + "#26C6DA", // Shade400 + "#00BCD4", // Shade500 + "#00ACC1", // Shade600 + "#0097A7", // Shade700 + "#00838F", // Shade800 + "#006064", // Shade900 + "#84FFFF", // ShadeA100 + "#18FFFF", // ShadeA200 + "#00E5FF", // ShadeA400 + "#00B8D4" // ShadeA700 + }, + // Teal + { + "#E0F2F1", // Shade50 + "#B2DFDB", // Shade100 + "#80CBC4", // Shade200 + "#4DB6AC", // Shade300 + "#26A69A", // Shade400 + "#009688", // Shade500 + "#00897B", // Shade600 + "#00796B", // Shade700 + "#00695C", // Shade800 + "#004D40", // Shade900 + "#A7FFEB", // ShadeA100 + "#64FFDA", // ShadeA200 + "#1DE9B6", // ShadeA400 + "#00BFA5" // ShadeA700 + }, + // Green + { + "#E8F5E9", // Shade50 + "#C8E6C9", // Shade100 + "#A5D6A7", // Shade200 + "#81C784", // Shade300 + "#66BB6A", // Shade400 + "#4CAF50", // Shade500 + "#43A047", // Shade600 + "#388E3C", // Shade700 + "#2E7D32", // Shade800 + "#1B5E20", // Shade900 + "#B9F6CA", // ShadeA100 + "#69F0AE", // ShadeA200 + "#00E676", // ShadeA400 + "#00C853" // ShadeA700 + }, + // LightGreen + { + "#F1F8E9", // Shade50 + "#DCEDC8", // Shade100 + "#C5E1A5", // Shade200 + "#AED581", // Shade300 + "#9CCC65", // Shade400 + "#8BC34A", // Shade500 + "#7CB342", // Shade600 + "#689F38", // Shade700 + "#558B2F", // Shade800 + "#33691E", // Shade900 + "#CCFF90", // ShadeA100 + "#B2FF59", // ShadeA200 + "#76FF03", // ShadeA400 + "#64DD17" // ShadeA700 + }, + // Lime + { + "#F9FBE7", // Shade50 + "#F0F4C3", // Shade100 + "#E6EE9C", // Shade200 + "#DCE775", // Shade300 + "#D4E157", // Shade400 + "#CDDC39", // Shade500 + "#C0CA33", // Shade600 + "#AFB42B", // Shade700 + "#9E9D24", // Shade800 + "#827717", // Shade900 + "#F4FF81", // ShadeA100 + "#EEFF41", // ShadeA200 + "#C6FF00", // ShadeA400 + "#AEEA00" // ShadeA700 + }, + // Yellow + { + "#FFFDE7", // Shade50 + "#FFF9C4", // Shade100 + "#FFF59D", // Shade200 + "#FFF176", // Shade300 + "#FFEE58", // Shade400 + "#FFEB3B", // Shade500 + "#FDD835", // Shade600 + "#FBC02D", // Shade700 + "#F9A825", // Shade800 + "#F57F17", // Shade900 + "#FFFF8D", // ShadeA100 + "#FFFF00", // ShadeA200 + "#FFEA00", // ShadeA400 + "#FFD600" // ShadeA700 + }, + // Amber + { + "#FFF8E1", // Shade50 + "#FFECB3", // Shade100 + "#FFE082", // Shade200 + "#FFD54F", // Shade300 + "#FFCA28", // Shade400 + "#FFC107", // Shade500 + "#FFB300", // Shade600 + "#FFA000", // Shade700 + "#FF8F00", // Shade800 + "#FF6F00", // Shade900 + "#FFE57F", // ShadeA100 + "#FFD740", // ShadeA200 + "#FFC400", // ShadeA400 + "#FFAB00" // ShadeA700 + }, + // Orange + { + "#FFF3E0", // Shade50 + "#FFE0B2", // Shade100 + "#FFCC80", // Shade200 + "#FFB74D", // Shade300 + "#FFA726", // Shade400 + "#FF9800", // Shade500 + "#FB8C00", // Shade600 + "#F57C00", // Shade700 + "#EF6C00", // Shade800 + "#E65100", // Shade900 + "#FFD180", // ShadeA100 + "#FFAB40", // ShadeA200 + "#FF9100", // ShadeA400 + "#FF6D00" // ShadeA700 + }, + // DeepOrange + { + "#FBE9E7", // Shade50 + "#FFCCBC", // Shade100 + "#FFAB91", // Shade200 + "#FF8A65", // Shade300 + "#FF7043", // Shade400 + "#FF5722", // Shade500 + "#F4511E", // Shade600 + "#E64A19", // Shade700 + "#D84315", // Shade800 + "#BF360C", // Shade900 + "#FF9E80", // ShadeA100 + "#FF6E40", // ShadeA200 + "#FF3D00", // ShadeA400 + "#DD2C00" // ShadeA700 + }, + // Brown + { + "#EFEBE9", // Shade50 + "#D7CCC8", // Shade100 + "#BCAAA4", // Shade200 + "#A1887F", // Shade300 + "#8D6E63", // Shade400 + "#795548", // Shade500 + "#6D4C41", // Shade600 + "#5D4037", // Shade700 + "#4E342E", // Shade800 + "#3E2723", // Shade900 + "#000000", // ShadeA100 + "#000000", // ShadeA200 + "#000000", // ShadeA400 + "#000000" // ShadeA700 + }, + // Grey + { + "#FAFAFA", // Shade50 + "#F5F5F5", // Shade100 + "#EEEEEE", // Shade200 + "#E0E0E0", // Shade300 + "#BDBDBD", // Shade400 + "#9E9E9E", // Shade500 + "#757575", // Shade600 + "#616161", // Shade700 + "#424242", // Shade800 + "#212121", // Shade900 + "#000000", // ShadeA100 + "#000000", // ShadeA200 + "#000000", // ShadeA400 + "#000000" // ShadeA700 + }, + // BlueGrey + { + "#ECEFF1", // Shade50 + "#CFD8DC", // Shade100 + "#B0BEC5", // Shade200 + "#90A4AE", // Shade300 + "#78909C", // Shade400 + "#607D8B", // Shade500 + "#546E7A", // Shade600 + "#455A64", // Shade700 + "#37474F", // Shade800 + "#263238", // Shade900 + "#000000", // ShadeA100 + "#000000", // ShadeA200 + "#000000", // ShadeA400 + "#000000" // ShadeA700 + } +}; + +static const QQuickMaterialStyle::Theme defaultTheme = QQuickMaterialStyle::Light; +static const QQuickMaterialStyle::Color defaultPrimary = QQuickMaterialStyle::BlueGrey; +static const QQuickMaterialStyle::Color defaultAccent = QQuickMaterialStyle::Teal; +static const QColor backgroundColorLight = "#FFFAFAFA"; +static const QColor backgroundColorDark = "#FF303030"; +static const QColor dialogColorLight = "#FFFFFFFF"; +static const QColor dialogColorDark = "#FF303030"; +static const QColor primaryTextColorLight = "#DD000000"; +static const QColor primaryTextColorDark = "#FFFFFFFF"; +static const QColor secondaryTextColorLight = "#89000000"; +static const QColor secondaryTextColorDark = "#B2FFFFFF"; +static const QColor hintTextColorLight = "#60000000"; +static const QColor hintTextColorDark = "#4CFFFFFF"; +static const QColor dividerTextColorLight = "#1E000000"; +static const QColor dividerTextColorDark = "#1EFFFFFF"; +static const QColor raisedButtonColorLight = "#FFD6D7D7"; +// TODO: find out actual value +static const QColor raisedButtonPressColorLight = "#FFCCCDCD"; +static const QColor raisedButtonDisabledColorLight = dividerTextColorLight; +static const QColor raisedButtonDisabledColorDark = dividerTextColorDark; +static const QColor flatButtonPressColorLight = "#66999999"; +static const QColor flatButtonPressColorDark = "#3FCCCCCC"; +static const QColor flatButtonFocusColorLight = "#33CCCCCC"; +static const QColor flatButtonFocusColorDark = "#26CCCCCC"; +static const QColor frameColorLight = hintTextColorLight; +static const QColor frameColorDark = hintTextColorDark; +static const QColor switchUncheckedTrackColorLight = "#42000000"; +static const QColor switchUncheckedTrackColorDark = "#4CFFFFFF"; +static const QColor switchDisabledTrackColorLight = "#1E000000"; +static const QColor switchDisabledTrackColorDark = "#19FFFFFF"; +// TODO: find out actual values +static const QColor checkBoxUncheckedRippleColorLight = "#10000000"; +static const QColor checkBoxUncheckedRippleColorDark = "#20FFFFFF"; + +QQuickMaterialStyle::QQuickMaterialStyle(QObject *parent) : QQuickStyle(parent), + m_explicitTheme(false), + m_explicitPrimary(false), + m_explicitAccent(false), + m_theme(defaultTheme), + m_primary(defaultPrimary), + m_accent(defaultAccent) +{ + init(); // TODO: lazy init? +} + +QQuickMaterialStyle *QQuickMaterialStyle::qmlAttachedProperties(QObject *object) +{ + return new QQuickMaterialStyle(object); +} + +QQuickMaterialStyle::Theme QQuickMaterialStyle::theme() const +{ + return m_theme; +} + +void QQuickMaterialStyle::setTheme(Theme theme) +{ + m_explicitTheme = true; + if (m_theme != theme) { + m_theme = theme; + propagateTheme(); + emit themeChanged(); + emit paletteChanged(); + } +} + +void QQuickMaterialStyle::inheritTheme(Theme theme) +{ + if (!m_explicitTheme && m_theme != theme) { + m_theme = theme; + propagateTheme(); + emit themeChanged(); + emit paletteChanged(); + } +} + +void QQuickMaterialStyle::propagateTheme() +{ + foreach (QQuickStyle *child, childStyles()) { + QQuickMaterialStyle *material = qobject_cast<QQuickMaterialStyle *>(child); + if (material) + material->inheritTheme(m_theme); + } +} + +void QQuickMaterialStyle::resetTheme() +{ + if (m_explicitTheme) { + m_explicitTheme = false; + QQuickMaterialStyle *material = qobject_cast<QQuickMaterialStyle *>(parentStyle()); + inheritTheme(material ? material->theme() : defaultTheme); + } +} + +QQuickMaterialStyle::Color QQuickMaterialStyle::primary() const +{ + return m_primary; +} + +void QQuickMaterialStyle::setPrimary(QQuickMaterialStyle::Color color) +{ + m_explicitPrimary = true; + if (m_primary != color) { + m_primary = color; + propagatePrimary(); + emit primaryChanged(); + emit paletteChanged(); + } +} + +void QQuickMaterialStyle::inheritPrimary(QQuickMaterialStyle::Color color) +{ + if (!m_explicitPrimary && m_primary != color) { + m_primary = color; + propagatePrimary(); + emit primaryChanged(); + } +} + +void QQuickMaterialStyle::propagatePrimary() +{ + foreach (QQuickStyle *child, childStyles()) { + QQuickMaterialStyle *material = qobject_cast<QQuickMaterialStyle *>(child); + if (material) + material->inheritPrimary(m_primary); + } +} + +void QQuickMaterialStyle::resetPrimary() +{ + if (m_explicitPrimary) { + m_explicitPrimary = false; + QQuickMaterialStyle *material = qobject_cast<QQuickMaterialStyle *>(parentStyle()); + inheritPrimary(material ? material->primary() : defaultPrimary); + } +} + +QQuickMaterialStyle::Color QQuickMaterialStyle::accent() const +{ + return m_accent; +} + +void QQuickMaterialStyle::setAccent(QQuickMaterialStyle::Color color) +{ + m_explicitAccent = true; + if (m_accent != color) { + m_accent = color; + propagateAccent(); + emit accentChanged(); + emit paletteChanged(); + } +} + +void QQuickMaterialStyle::inheritAccent(QQuickMaterialStyle::Color color) +{ + if (!m_explicitAccent && m_accent != color) { + m_accent = color; + propagateAccent(); + emit accentChanged(); + } +} + +void QQuickMaterialStyle::propagateAccent() +{ + foreach (QQuickStyle *child, childStyles()) { + QQuickMaterialStyle *material = qobject_cast<QQuickMaterialStyle *>(child); + if (material) + material->inheritAccent(m_accent); + } +} + +void QQuickMaterialStyle::resetAccent() +{ + if (m_explicitAccent) { + m_explicitAccent = false; + QQuickMaterialStyle *material = qobject_cast<QQuickMaterialStyle *>(parentStyle()); + inheritAccent(material ? material->accent() : defaultAccent); + } +} + +QColor QQuickMaterialStyle::accentColor() const +{ + return color(m_accent, Shade500); +} + +QColor QQuickMaterialStyle::backgroundColor() const +{ + return m_theme == Light ? backgroundColorLight : backgroundColorDark; +} + +QColor QQuickMaterialStyle::primaryTextColor() const +{ + return m_theme == Light ? primaryTextColorLight : primaryTextColorDark; +} + +QColor QQuickMaterialStyle::primaryHighlightedTextColor() const +{ + return primaryTextColorDark; +} + +QColor QQuickMaterialStyle::secondaryTextColor() const +{ + return m_theme == Light ? secondaryTextColorLight : secondaryTextColorDark; +} + +QColor QQuickMaterialStyle::hintTextColor() const +{ + return m_theme == Light ? hintTextColorLight : hintTextColorDark; +} + +QColor QQuickMaterialStyle::textSelectionColor() const +{ + QColor color = accentColor(); + color.setAlphaF(0.4); + return color; +} + +QColor QQuickMaterialStyle::dropShadowColor() const +{ + return QColor("#40000000"); +} + +QColor QQuickMaterialStyle::dividerColor() const +{ + return m_theme == Light ? dividerTextColorLight : dividerTextColorDark; +} + +QColor QQuickMaterialStyle::raisedButtonColor() const +{ + return m_theme == Light ? raisedButtonColorLight : flatButtonFocusColorDark; +} + +QColor QQuickMaterialStyle::raisedButtonHoverColor() const +{ + // The specs don't specify different colors here for the light theme. + return m_theme == Light ? raisedButtonColorLight : flatButtonPressColorDark; +} + +QColor QQuickMaterialStyle::raisedButtonPressColor() const +{ + return m_theme == Light ? raisedButtonPressColorLight : flatButtonPressColorDark; +} + +QColor QQuickMaterialStyle::raisedButtonDisabledColor() const +{ + return m_theme == Light ? raisedButtonDisabledColorLight : raisedButtonDisabledColorDark; +} + +QColor QQuickMaterialStyle::raisedHighlightedButtonColor() const +{ + return accentColor(); +} + +QColor QQuickMaterialStyle::raisedHighlightedButtonHoverColor() const +{ + return color(m_accent, Shade600); +} + +QColor QQuickMaterialStyle::raisedHighlightedButtonPressColor() const +{ + return color(m_accent, Shade700); +} + +QColor QQuickMaterialStyle::raisedHighlightedButtonDisabledColor() const +{ + return m_theme == Light ? raisedButtonDisabledColorLight : raisedButtonDisabledColorDark; +} + +QColor QQuickMaterialStyle::flatButtonPressColor() const +{ + return m_theme == Light ? flatButtonPressColorLight : flatButtonPressColorDark; +} + +QColor QQuickMaterialStyle::flatButtonFocusColor() const +{ + return m_theme == Light ? flatButtonFocusColorLight : flatButtonFocusColorDark; +} + +QColor QQuickMaterialStyle::frameColor() const +{ + return m_theme == Light ? frameColorLight : frameColorDark; +} + +QColor QQuickMaterialStyle::checkBoxUncheckedRippleColor() const +{ + return m_theme == Light ? checkBoxUncheckedRippleColorLight : checkBoxUncheckedRippleColorDark; +} + +QColor QQuickMaterialStyle::checkBoxCheckedRippleColor() const +{ + QColor pressColor = color(m_accent, Shade500); + // TODO: find out actual value + pressColor.setAlpha(30); + return pressColor; +} + +QColor QQuickMaterialStyle::switchUncheckedTrackColor() const +{ + return m_theme == Light ? switchUncheckedTrackColorLight : switchUncheckedTrackColorDark; +} + +QColor QQuickMaterialStyle::switchCheckedTrackColor() const +{ + QColor trackColor = m_theme == Light ? accentColor() : color(m_accent, Shade200); + trackColor.setAlphaF(0.5); + return trackColor; +} + +QColor QQuickMaterialStyle::switchUncheckedHandleColor() const +{ + return m_theme == Light ? color(Grey, Shade50) : color(Grey, Shade400); +} + +QColor QQuickMaterialStyle::switchCheckedHandleColor() const +{ + return m_theme == Light ? accentColor() : color(m_accent, Shade200); +} + +QColor QQuickMaterialStyle::switchDisabledTrackColor() const +{ + return m_theme == Light ? switchDisabledTrackColorLight : switchDisabledTrackColorDark; +} + +QColor QQuickMaterialStyle::switchDisabledHandleColor() const +{ + return m_theme == Light ? color(Grey, Shade400) : color(Grey, Shade800); +} + +QColor QQuickMaterialStyle::scrollBarColor() const +{ + return m_theme == Light ? "#40000000" : "#40FFFFFF"; +} + +QColor QQuickMaterialStyle::scrollBarPressedColor() const +{ + return m_theme == Light ? "#80000000" : "#80FFFFFF"; +} + +QColor QQuickMaterialStyle::drawerBackgroundColor() const +{ + return dividerTextColorLight; +} + +QColor QQuickMaterialStyle::color(QQuickMaterialStyle::Color color, QQuickMaterialStyle::Shade shade) const +{ + int count = sizeof(colors) / sizeof(colors[0]); + if (color < 0 || color >= count) + return QColor(); + + count = sizeof(colors[0]) / sizeof(colors[0][0]); + if (shade < 0 || shade >= count) + return QColor(); + + return colors[color][shade]; +} + +void QQuickMaterialStyle::parentStyleChange(QQuickStyle *newParent, QQuickStyle *oldParent) +{ + Q_UNUSED(oldParent); + QQuickMaterialStyle *material = qobject_cast<QQuickMaterialStyle *>(newParent); + if (material) { + inheritPrimary(material->primary()); + inheritAccent(material->accent()); + inheritTheme(material->theme()); + } +} + +QT_END_NAMESPACE diff --git a/src/imports/controls/material/qquickmaterialstyle_p.h b/src/imports/controls/material/qquickmaterialstyle_p.h new file mode 100644 index 00000000..69891b9c --- /dev/null +++ b/src/imports/controls/material/qquickmaterialstyle_p.h @@ -0,0 +1,227 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 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 QQUICKMATERIALSTYLE_P_H +#define QQUICKMATERIALSTYLE_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 <QtGui/qcolor.h> +#include <QtLabsControls/private/qquickstyle_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickMaterialStylePrivate; + +class QQuickMaterialStyle : public QQuickStyle +{ + Q_OBJECT + Q_PROPERTY(Theme theme READ theme WRITE setTheme RESET resetTheme NOTIFY themeChanged FINAL) + Q_PROPERTY(Color primary READ primary WRITE setPrimary RESET resetPrimary NOTIFY primaryChanged FINAL) + Q_PROPERTY(Color accent READ accent WRITE setAccent RESET resetAccent NOTIFY accentChanged FINAL) + Q_PROPERTY(QColor accentColor READ accentColor NOTIFY accentChanged FINAL) + Q_PROPERTY(QColor backgroundColor READ backgroundColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor primaryTextColor READ primaryTextColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor primaryHighlightedTextColor READ primaryHighlightedTextColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor secondaryTextColor READ secondaryTextColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor hintTextColor READ hintTextColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor textSelectionColor READ textSelectionColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor dropShadowColor READ dropShadowColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor dividerColor READ dividerColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor raisedButtonColor READ raisedButtonColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor raisedButtonHoverColor READ raisedButtonHoverColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor raisedButtonPressColor READ raisedButtonPressColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor raisedButtonDisabledColor READ raisedButtonDisabledColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor raisedHighlightedButtonColor READ raisedHighlightedButtonColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor raisedHighlightedButtonHoverColor READ raisedHighlightedButtonHoverColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor raisedHighlightedButtonPressColor READ raisedHighlightedButtonPressColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor raisedHighlightedButtonDisabledColor READ raisedHighlightedButtonDisabledColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor flatButtonPressColor READ flatButtonPressColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor flatButtonFocusColor READ flatButtonFocusColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor frameColor READ frameColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor checkBoxUncheckedRippleColor READ checkBoxUncheckedRippleColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor checkBoxCheckedRippleColor READ checkBoxCheckedRippleColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor switchUncheckedTrackColor READ switchUncheckedTrackColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor switchCheckedTrackColor READ switchCheckedTrackColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor switchUncheckedHandleColor READ switchUncheckedHandleColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor switchCheckedHandleColor READ switchCheckedHandleColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor switchDisabledTrackColor READ switchDisabledTrackColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor switchDisabledHandleColor READ switchDisabledHandleColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor scrollBarColor READ scrollBarColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor scrollBarPressedColor READ scrollBarPressedColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor drawerBackgroundColor READ drawerBackgroundColor NOTIFY paletteChanged FINAL) + +public: + enum Theme { + Light, + Dark + }; + + enum Color { + Red, + Pink, + Purple, + DeepPurple, + Indigo, + Blue, + LightBlue, + Cyan, + Teal, + Green, + LightGreen, + Lime, + Yellow, + Amber, + Orange, + DeepOrange, + Brown, + Grey, + BlueGrey + }; + + enum Shade { + Shade50, + Shade100, + Shade200, + Shade300, + Shade400, + Shade500, + Shade600, + Shade700, + Shade800, + Shade900, + ShadeA100, + ShadeA200, + ShadeA400, + ShadeA700, + }; + + Q_ENUM(Theme) + Q_ENUM(Color) + Q_ENUM(Shade) + + explicit QQuickMaterialStyle(QObject *parent = Q_NULLPTR); + + static QQuickMaterialStyle *qmlAttachedProperties(QObject *object); + + Theme theme() const; + void setTheme(Theme theme); + void inheritTheme(Theme theme); + void propagateTheme(); + void resetTheme(); + + QColor primaryColorLight() const; + + Color primary() const; + void setPrimary(Color color); + void inheritPrimary(Color color); + void propagatePrimary(); + void resetPrimary(); + + QColor primaryColorDark() const; + + Color accent() const; + void setAccent(Color color); + void inheritAccent(Color color); + void propagateAccent(); + void resetAccent(); + + QColor accentColor() const; + QColor backgroundColor() const; + QColor primaryTextColor() const; + QColor primaryHighlightedTextColor() const; + QColor secondaryTextColor() const; + QColor hintTextColor() const; + QColor textSelectionColor() const; + QColor dropShadowColor() const; + QColor dividerColor() const; + QColor raisedButtonColor() const; + QColor raisedButtonHoverColor() const; + QColor raisedButtonPressColor() const; + QColor raisedButtonDisabledColor() const; + QColor raisedHighlightedButtonColor() const; + QColor raisedHighlightedButtonHoverColor() const; + QColor raisedHighlightedButtonPressColor() const; + QColor raisedHighlightedButtonDisabledColor() const; + QColor flatButtonPressColor() const; + QColor flatButtonFocusColor() const; + QColor frameColor() const; + QColor checkBoxUncheckedRippleColor() const; + QColor checkBoxCheckedRippleColor() const; + QColor switchUncheckedTrackColor() const; + QColor switchCheckedTrackColor() const; + QColor switchUncheckedHandleColor() const; + QColor switchCheckedHandleColor() const; + QColor switchDisabledTrackColor() const; + QColor switchDisabledHandleColor() const; + QColor scrollBarColor() const; + QColor scrollBarPressedColor() const; + QColor drawerBackgroundColor() const; + + Q_INVOKABLE QColor color(Color color, Shade shade) const; + +Q_SIGNALS: + void themeChanged(); + void primaryChanged(); + void accentChanged(); + void paletteChanged(); + +protected: + void parentStyleChange(QQuickStyle *newParent, QQuickStyle *oldParent) Q_DECL_OVERRIDE; + +private: + bool m_explicitTheme; + bool m_explicitPrimary; + bool m_explicitAccent; + Theme m_theme; + Color m_primary; + Color m_accent; +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPEINFO(QQuickMaterialStyle, QML_HAS_ATTACHED_PROPERTIES) + +#endif // QQUICKMATERIALSTYLE_P_H diff --git a/src/imports/controls/material/qquickmaterialtheme.cpp b/src/imports/controls/material/qquickmaterialtheme.cpp new file mode 100644 index 00000000..ee98c35c --- /dev/null +++ b/src/imports/controls/material/qquickmaterialtheme.cpp @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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 "qquickmaterialtheme_p.h" + +#include <QtGui/qfont.h> + +QT_BEGIN_NAMESPACE + +QQuickMaterialTheme::QQuickMaterialTheme(QPlatformTheme *theme) + : QQuickProxyTheme(theme) +{ + systemFont = QFont(QLatin1Literal("Roboto")); + dockWidgetTitleFont = QFont(QLatin1Literal("Roboto"), 10); +} + +QQuickMaterialTheme::~QQuickMaterialTheme() +{ +} + +const QFont *QQuickMaterialTheme::font(QPlatformTheme::Font type) const +{ + switch (type) { + case QPlatformTheme::DockWidgetTitleFont: + return &dockWidgetTitleFont; + default: + return &systemFont; + } +} + +QT_END_NAMESPACE diff --git a/src/imports/controls/material/qquickmaterialtheme_p.h b/src/imports/controls/material/qquickmaterialtheme_p.h new file mode 100644 index 00000000..e3d6ce9b --- /dev/null +++ b/src/imports/controls/material/qquickmaterialtheme_p.h @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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 QQUICKMATERIALTHEME_H +#define QQUICKMATERIALTHEME_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 <QtGui/qpa/qplatformtheme.h> +#include <QtGui/qfont.h> +#include <QtLabsControls/private/qquickproxytheme_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickMaterialTheme : public QQuickProxyTheme +{ +public: + QQuickMaterialTheme(QPlatformTheme *theme); + + ~QQuickMaterialTheme(); + + const QFont *font(Font type = SystemFont) const Q_DECL_OVERRIDE; + +private: + QFont systemFont; + QFont dockWidgetTitleFont; // QQuickTabButton +}; + +QT_END_NAMESPACE + +#endif // QQUICKMATERIALTHEME_H diff --git a/src/imports/controls/material/qtlabsmaterialstyleplugin.cpp b/src/imports/controls/material/qtlabsmaterialstyleplugin.cpp new file mode 100644 index 00000000..ab98991a --- /dev/null +++ b/src/imports/controls/material/qtlabsmaterialstyleplugin.cpp @@ -0,0 +1,104 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls 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 <QtQml/qqmlextensionplugin.h> + +#include "qquickmaterialstyle_p.h" +#include "qquickmaterialtheme_p.h" +#include "qquickmaterialprogressring_p.h" + +#include <QtGui/private/qguiapplication_p.h> +#include <QtLabsControls/private/qquickstyleselector_p.h> + +static inline void initResources() +{ + Q_INIT_RESOURCE(qtlabsmaterialstyleplugin); +} + +QT_BEGIN_NAMESPACE + +class QtLabsMaterialStylePlugin : public QQmlExtensionPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface/1.0") + +public: + ~QtLabsMaterialStylePlugin(); + void registerTypes(const char *uri) Q_DECL_OVERRIDE; + void initializeEngine(QQmlEngine *engine, const char *uri) Q_DECL_OVERRIDE; + +private: + QQuickProxyTheme *theme; +}; + +QtLabsMaterialStylePlugin::~QtLabsMaterialStylePlugin() +{ + if (theme) { + QPlatformTheme *old = theme->theme(); + QGuiApplicationPrivate::platform_theme = old; + delete theme; + } +} + +void QtLabsMaterialStylePlugin::registerTypes(const char *uri) +{ + qmlRegisterUncreatableType<QQuickMaterialStyle>(uri, 1, 0, "Material", tr("Material is an attached property")); + qmlRegisterType<QQuickMaterialProgressRing>(uri, 1, 0, "ProgressRing"); + qmlRegisterType<QQuickMaterialRingAnimator>(uri, 1, 0, "RingAnimator"); +} + +void QtLabsMaterialStylePlugin::initializeEngine(QQmlEngine *engine, const char *uri) +{ + Q_UNUSED(engine); + Q_UNUSED(uri); + + QQuickStyleSelector *selector = QQuickStyleSelector::instance(); + if (selector && selector->style() == QStringLiteral("material")) { + if (QFont(QStringLiteral("Roboto")).family() == QStringLiteral("Roboto")) { + QPlatformTheme *old = QGuiApplicationPrivate::platform_theme; + if (old) { + QQuickProxyTheme *theme = new QQuickMaterialTheme(old); + QGuiApplicationPrivate::platform_theme = theme; + } + } + } + + initResources(); +} + +QT_END_NAMESPACE + +#include "qtlabsmaterialstyleplugin.moc" diff --git a/src/imports/controls/material/qtlabsmaterialstyleplugin.qrc b/src/imports/controls/material/qtlabsmaterialstyleplugin.qrc new file mode 100644 index 00000000..6c7b65f1 --- /dev/null +++ b/src/imports/controls/material/qtlabsmaterialstyleplugin.qrc @@ -0,0 +1,8 @@ +<RCC> + <qresource prefix="/qt-project.org/imports/Qt/labs/controls/material"> + <file>images/check.png</file> + <file>images/check@2x.png</file> + <file>images/check@3x.png</file> + <file>images/check@4x.png</file> + </qresource> +</RCC> diff --git a/src/imports/controls/plugins.qmltypes b/src/imports/controls/plugins.qmltypes index c3e6f8f6..57ae4cd0 100644 --- a/src/imports/controls/plugins.qmltypes +++ b/src/imports/controls/plugins.qmltypes @@ -8,59 +8,40 @@ import QtQuick.tooling 1.2 Module { dependencies: [ + "Qt.labs.controls.material 1.0", + "Qt.labs.controls.universal 1.0", + "Qt.labs.controls.universal.impl 1.0", "Qt.labs.templates 1.0", + "QtGraphicalEffects 1.0", + "QtGraphicalEffects.private 1.0", "QtQuick 2.6", "QtQuick.Window 2.2" ] Component { - name: "QQuickExclusiveGroup" - defaultProperty: "checkables" + name: "QQuickButtonGroup" prototype: "QObject" - exports: ["Qt.labs.controls/ExclusiveGroup 1.0"] + exports: ["Qt.labs.controls/ButtonGroup 1.0"] exportMetaObjectRevisions: [0] - attachedType: "QQuickExclusiveGroupAttached" - Property { name: "current"; type: "QObject"; isPointer: true } - Property { name: "checkables"; type: "QObject"; isList: true; isReadonly: true } + attachedType: "QQuickButtonGroupAttached" + Property { name: "checkedButton"; type: "QQuickAbstractButton"; isPointer: true } + Property { name: "buttons"; type: "QQuickAbstractButton"; isList: true; isReadonly: true } Method { - name: "addCheckable" - Parameter { name: "object"; type: "QObject"; isPointer: true } + name: "addButton" + Parameter { name: "button"; type: "QQuickAbstractButton"; isPointer: true } } Method { - name: "removeCheckable" - Parameter { name: "object"; type: "QObject"; isPointer: true } + name: "removeButton" + Parameter { name: "button"; type: "QQuickAbstractButton"; isPointer: true } } - Method { - name: "isCheckable" - type: "bool" - Parameter { name: "object"; type: "QObject"; isPointer: true } - } - } - Component { - name: "QQuickExclusiveGroupAttached" - prototype: "QObject" - Property { name: "group"; type: "QQuickExclusiveGroup"; isPointer: true } } Component { - name: "QQuickThemeAttached" + name: "QQuickButtonGroupAttached" prototype: "QObject" - exports: ["Qt.labs.controls/Theme 1.0"] - isCreatable: false - exportMetaObjectRevisions: [0] - Property { name: "accentColor"; type: "QColor" } - Property { name: "backgroundColor"; type: "QColor" } - Property { name: "baseColor"; type: "QColor" } - Property { name: "disabledColor"; type: "QColor" } - Property { name: "focusColor"; type: "QColor" } - Property { name: "frameColor"; type: "QColor" } - Property { name: "pressColor"; type: "QColor" } - Property { name: "selectedTextColor"; type: "QColor" } - Property { name: "selectionColor"; type: "QColor" } - Property { name: "shadowColor"; type: "QColor" } - Property { name: "textColor"; type: "QColor" } + Property { name: "group"; type: "QQuickButtonGroup"; isPointer: true } } Component { prototype: "QQuickApplicationWindow" - name: "Qt.labs.controls/ApplicationWindow" + name: "Qt.labs.controls/ApplicationWindow 1.0" exports: ["Qt.labs.controls/ApplicationWindow 1.0"] exportMetaObjectRevisions: [0] isComposite: true @@ -68,7 +49,7 @@ Module { } Component { prototype: "QQuickBusyIndicator" - name: "Qt.labs.controls/BusyIndicator" + name: "Qt.labs.controls/BusyIndicator 1.0" exports: ["Qt.labs.controls/BusyIndicator 1.0"] exportMetaObjectRevisions: [0] isComposite: true @@ -76,7 +57,7 @@ Module { } Component { prototype: "QQuickButton" - name: "Qt.labs.controls/Button" + name: "Qt.labs.controls/Button 1.0" exports: ["Qt.labs.controls/Button 1.0"] exportMetaObjectRevisions: [0] isComposite: true @@ -84,7 +65,7 @@ Module { } Component { prototype: "QQuickCheckBox" - name: "Qt.labs.controls/CheckBox" + name: "Qt.labs.controls/CheckBox 1.0" exports: ["Qt.labs.controls/CheckBox 1.0"] exportMetaObjectRevisions: [0] isComposite: true @@ -92,7 +73,7 @@ Module { } Component { prototype: "QQuickDial" - name: "Qt.labs.controls/Dial" + name: "Qt.labs.controls/Dial 1.0" exports: ["Qt.labs.controls/Dial 1.0"] exportMetaObjectRevisions: [0] isComposite: true @@ -100,7 +81,7 @@ Module { } Component { prototype: "QQuickDrawer" - name: "Qt.labs.controls/Drawer" + name: "Qt.labs.controls/Drawer 1.0" exports: ["Qt.labs.controls/Drawer 1.0"] exportMetaObjectRevisions: [0] isComposite: true @@ -108,7 +89,7 @@ Module { } Component { prototype: "QQuickFrame" - name: "Qt.labs.controls/Frame" + name: "Qt.labs.controls/Frame 1.0" exports: ["Qt.labs.controls/Frame 1.0"] exportMetaObjectRevisions: [0] isComposite: true @@ -116,15 +97,23 @@ Module { } Component { prototype: "QQuickGroupBox" - name: "Qt.labs.controls/GroupBox" + name: "Qt.labs.controls/GroupBox 1.0" exports: ["Qt.labs.controls/GroupBox 1.0"] exportMetaObjectRevisions: [0] isComposite: true defaultProperty: "contentData" } Component { + prototype: "QQuickItemDelegate" + name: "Qt.labs.controls/ItemDelegate 1.0" + exports: ["Qt.labs.controls/ItemDelegate 1.0"] + exportMetaObjectRevisions: [0] + isComposite: true + defaultProperty: "data" + } + Component { prototype: "QQuickLabel" - name: "Qt.labs.controls/Label" + name: "Qt.labs.controls/Label 1.0" exports: ["Qt.labs.controls/Label 1.0"] exportMetaObjectRevisions: [0] isComposite: true @@ -132,7 +121,7 @@ Module { } Component { prototype: "QQuickPageIndicator" - name: "Qt.labs.controls/PageIndicator" + name: "Qt.labs.controls/PageIndicator 1.0" exports: ["Qt.labs.controls/PageIndicator 1.0"] exportMetaObjectRevisions: [0] isComposite: true @@ -140,7 +129,7 @@ Module { } Component { prototype: "QQuickProgressBar" - name: "Qt.labs.controls/ProgressBar" + name: "Qt.labs.controls/ProgressBar 1.0" exports: ["Qt.labs.controls/ProgressBar 1.0"] exportMetaObjectRevisions: [0] isComposite: true @@ -148,7 +137,7 @@ Module { } Component { prototype: "QQuickRadioButton" - name: "Qt.labs.controls/RadioButton" + name: "Qt.labs.controls/RadioButton 1.0" exports: ["Qt.labs.controls/RadioButton 1.0"] exportMetaObjectRevisions: [0] isComposite: true @@ -156,7 +145,7 @@ Module { } Component { prototype: "QQuickRangeSlider" - name: "Qt.labs.controls/RangeSlider" + name: "Qt.labs.controls/RangeSlider 1.0" exports: ["Qt.labs.controls/RangeSlider 1.0"] exportMetaObjectRevisions: [0] isComposite: true @@ -164,7 +153,7 @@ Module { } Component { prototype: "QQuickScrollBar" - name: "Qt.labs.controls/ScrollBar" + name: "Qt.labs.controls/ScrollBar 1.0" exports: ["Qt.labs.controls/ScrollBar 1.0"] exportMetaObjectRevisions: [0] isComposite: true @@ -172,7 +161,7 @@ Module { } Component { prototype: "QQuickScrollIndicator" - name: "Qt.labs.controls/ScrollIndicator" + name: "Qt.labs.controls/ScrollIndicator 1.0" exports: ["Qt.labs.controls/ScrollIndicator 1.0"] exportMetaObjectRevisions: [0] isComposite: true @@ -180,7 +169,7 @@ Module { } Component { prototype: "QQuickSlider" - name: "Qt.labs.controls/Slider" + name: "Qt.labs.controls/Slider 1.0" exports: ["Qt.labs.controls/Slider 1.0"] exportMetaObjectRevisions: [0] isComposite: true @@ -188,7 +177,7 @@ Module { } Component { prototype: "QQuickSpinBox" - name: "Qt.labs.controls/SpinBox" + name: "Qt.labs.controls/SpinBox 1.0" exports: ["Qt.labs.controls/SpinBox 1.0"] exportMetaObjectRevisions: [0] isComposite: true @@ -196,7 +185,7 @@ Module { } Component { prototype: "QQuickStackView" - name: "Qt.labs.controls/StackView" + name: "Qt.labs.controls/StackView 1.0" exports: ["Qt.labs.controls/StackView 1.0"] exportMetaObjectRevisions: [0] isComposite: true @@ -204,7 +193,7 @@ Module { } Component { prototype: "QQuickSwipeView" - name: "Qt.labs.controls/SwipeView" + name: "Qt.labs.controls/SwipeView 1.0" exports: ["Qt.labs.controls/SwipeView 1.0"] exportMetaObjectRevisions: [0] isComposite: true @@ -212,7 +201,7 @@ Module { } Component { prototype: "QQuickSwitch" - name: "Qt.labs.controls/Switch" + name: "Qt.labs.controls/Switch 1.0" exports: ["Qt.labs.controls/Switch 1.0"] exportMetaObjectRevisions: [0] isComposite: true @@ -220,7 +209,7 @@ Module { } Component { prototype: "QQuickTabBar" - name: "Qt.labs.controls/TabBar" + name: "Qt.labs.controls/TabBar 1.0" exports: ["Qt.labs.controls/TabBar 1.0"] exportMetaObjectRevisions: [0] isComposite: true @@ -228,7 +217,7 @@ Module { } Component { prototype: "QQuickTabButton" - name: "Qt.labs.controls/TabButton" + name: "Qt.labs.controls/TabButton 1.0" exports: ["Qt.labs.controls/TabButton 1.0"] exportMetaObjectRevisions: [0] isComposite: true @@ -236,7 +225,7 @@ Module { } Component { prototype: "QQuickTextArea" - name: "Qt.labs.controls/TextArea" + name: "Qt.labs.controls/TextArea 1.0" exports: ["Qt.labs.controls/TextArea 1.0"] exportMetaObjectRevisions: [0] isComposite: true @@ -244,7 +233,7 @@ Module { } Component { prototype: "QQuickTextField" - name: "Qt.labs.controls/TextField" + name: "Qt.labs.controls/TextField 1.0" exports: ["Qt.labs.controls/TextField 1.0"] exportMetaObjectRevisions: [0] isComposite: true @@ -252,7 +241,7 @@ Module { } Component { prototype: "QQuickToolBar" - name: "Qt.labs.controls/ToolBar" + name: "Qt.labs.controls/ToolBar 1.0" exports: ["Qt.labs.controls/ToolBar 1.0"] exportMetaObjectRevisions: [0] isComposite: true @@ -260,7 +249,7 @@ Module { } Component { prototype: "QQuickToolButton" - name: "Qt.labs.controls/ToolButton" + name: "Qt.labs.controls/ToolButton 1.0" exports: ["Qt.labs.controls/ToolButton 1.0"] exportMetaObjectRevisions: [0] isComposite: true @@ -268,7 +257,7 @@ Module { } Component { prototype: "QQuickTumbler" - name: "Qt.labs.controls/Tumbler" + name: "Qt.labs.controls/Tumbler 1.0" exports: ["Qt.labs.controls/Tumbler 1.0"] exportMetaObjectRevisions: [0] isComposite: true diff --git a/src/imports/controls/qmldir b/src/imports/controls/qmldir index 437adfb3..98c57fe1 100644 --- a/src/imports/controls/qmldir +++ b/src/imports/controls/qmldir @@ -2,3 +2,4 @@ module Qt.labs.controls plugin qtlabscontrolsplugin classname QtLabsControlsPlugin depends Qt.labs.templates 1.0 +designersupported diff --git a/src/imports/controls/qquicktheme.cpp b/src/imports/controls/qquicktheme.cpp deleted file mode 100644 index 923d452b..00000000 --- a/src/imports/controls/qquicktheme.cpp +++ /dev/null @@ -1,620 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt Labs Controls module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL3$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or later as published by the Free -** Software Foundation and appearing in the file LICENSE.GPL included in -** the packaging of this file. Please review the following information to -** ensure the GNU General Public License version 2.0 requirements will be -** met: http://www.gnu.org/licenses/gpl-2.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qquicktheme_p.h" -#include "qquickthemedata_p.h" -#include "qquickstyle_p.h" - -#include <QtCore/qset.h> -#include <QtCore/qpointer.h> -#include <QtQml/qqmlengine.h> -#include <QtQuick/qquickitem.h> -#include <QtQuick/qquickwindow.h> -#include <QtQuick/private/qquickitem_p.h> -#include <QtQuick/private/qquickitemchangelistener_p.h> - -QT_BEGIN_NAMESPACE - -/*! - \qmltype Theme - \inherits QtObject - \instantiates QQuickThemeAttached - \inqmlmodule Qt.labs.controls - \ingroup utilities - \brief A theme interface. - - TODO -*/ - -/*! - \qmlattachedproperty color Qt.labs.controls::Theme::accentColor -*/ - -/*! - \qmlattachedproperty color Qt.labs.controls::Theme::backgroundColor -*/ - -/*! - \qmlattachedproperty color Qt.labs.controls::Theme::disabledColor -*/ - -/*! - \qmlattachedproperty color Qt.labs.controls::Theme::focusColor -*/ - -/*! - \qmlattachedproperty color Qt.labs.controls::Theme::frameColor -*/ - -/*! - \qmlattachedproperty color Qt.labs.controls::Theme::pressColor -*/ - -/*! - \qmlattachedproperty color Qt.labs.controls::Theme::selectedTextColor -*/ - -/*! - \qmlattachedproperty color Qt.labs.controls::Theme::selectionColor -*/ - -/*! - \qmlattachedproperty color Qt.labs.controls::Theme::shadowColor -*/ - -/*! - \qmlattachedproperty color Qt.labs.controls::Theme::textColor -*/ - -Q_GLOBAL_STATIC_WITH_ARGS(QQuickThemeData, globalThemeData, (QString::fromLatin1(":/qtlabscontrols/theme.json"))) - -class QQuickThemeAttachedPrivate : public QObjectPrivate, public QQuickItemChangeListener -{ - Q_DECLARE_PUBLIC(QQuickThemeAttached) - -public: - QQuickThemeAttachedPrivate(const QQuickThemeData &data) : data(data), - explicitAccentColor(false), - explicitBackgroundColor(false), - explicitBaseColor(false), - explicitDisabledColor(false), - explicitFocusColor(false), - explicitFrameColor(false), - explicitPressColor(false), - explicitSelectedTextColor(false), - explicitSelectionColor(false), - explicitShadowColor(false), - explicitTextColor(false) { } - - enum Method { Implicit, Explicit, Inherit }; - - void setAccentColor(const QColor &color, Method method); - void setBackgroundColor(const QColor &color, Method method); - void setBaseColor(const QColor &color, Method method); - void setDisabledColor(const QColor &color, Method method); - void setFocusColor(const QColor &color, Method method); - void setFrameColor(const QColor &color, Method method); - void setPressColor(const QColor &color, Method method); - void setSelectedTextColor(const QColor &color, Method method); - void setSelectionColor(const QColor &color, Method method); - void setShadowColor(const QColor &color, Method method); - void setTextColor(const QColor &color, Method method); - - void inherit(QQuickThemeAttached *theme); - - const QQuickThemeData &resolve() const; - - // TODO: add QQuickItemChangeListener::itemSceneChanged() - void itemParentChanged(QQuickItem *item, QQuickItem *parent) Q_DECL_OVERRIDE; - - QQuickThemeData data; - QPointer<QQuickThemeAttached> parentTheme; - QSet<QQuickThemeAttached *> childThemes; - - bool explicitAccentColor; - bool explicitBackgroundColor; - bool explicitBaseColor; - bool explicitDisabledColor; - bool explicitFocusColor; - bool explicitFrameColor; - bool explicitPressColor; - bool explicitSelectedTextColor; - bool explicitSelectionColor; - bool explicitShadowColor; - bool explicitTextColor; -}; - -void QQuickThemeAttachedPrivate::setAccentColor(const QColor &color, Method method) -{ - Q_Q(QQuickThemeAttached); - if (!explicitAccentColor || method != Inherit) { - explicitAccentColor = method == Explicit; - if (data.accentColor() != color) { - data.setAccentColor(color); - emit q->accentColorChanged(); - - foreach (QQuickThemeAttached *child, childThemes) - child->d_func()->setAccentColor(color, Inherit); - } - } -} - -void QQuickThemeAttachedPrivate::setBackgroundColor(const QColor &color, Method method) -{ - Q_Q(QQuickThemeAttached); - if (!explicitBackgroundColor || method != Inherit) { - explicitBackgroundColor = method == Explicit; - if (data.backgroundColor() != color) { - data.setBackgroundColor(color); - emit q->backgroundColorChanged(); - - foreach (QQuickThemeAttached *child, childThemes) - child->d_func()->setBackgroundColor(color, Inherit); - } - } -} - -void QQuickThemeAttachedPrivate::setBaseColor(const QColor &color, Method method) -{ - Q_Q(QQuickThemeAttached); - if (!explicitBaseColor || method != Inherit) { - explicitBaseColor = method == Explicit; - if (data.baseColor() != color) { - data.setBaseColor(color); - emit q->baseColorChanged(); - - foreach (QQuickThemeAttached *child, childThemes) - child->d_func()->setBaseColor(color, Inherit); - } - } -} - -void QQuickThemeAttachedPrivate::setDisabledColor(const QColor &color, Method method) -{ - Q_Q(QQuickThemeAttached); - if (!explicitDisabledColor || method != Inherit) { - explicitDisabledColor = method == Explicit; - if (data.disabledColor() != color) { - data.setDisabledColor(color); - emit q->disabledColorChanged(); - - foreach (QQuickThemeAttached *child, childThemes) - child->d_func()->setDisabledColor(color, Inherit); - } - } -} - -void QQuickThemeAttachedPrivate::setFocusColor(const QColor &color, Method method) -{ - Q_Q(QQuickThemeAttached); - if (!explicitFocusColor || method != Inherit) { - explicitFocusColor = method == Explicit; - if (data.focusColor() != color) { - data.setFocusColor(color); - emit q->focusColorChanged(); - - foreach (QQuickThemeAttached *child, childThemes) - child->d_func()->setFocusColor(color, Inherit); - } - } -} - -void QQuickThemeAttachedPrivate::setFrameColor(const QColor &color, Method method) -{ - Q_Q(QQuickThemeAttached); - if (!explicitFrameColor || method != Inherit) { - explicitFrameColor = method == Explicit; - if (data.frameColor() != color) { - data.setFrameColor(color); - emit q->frameColorChanged(); - - foreach (QQuickThemeAttached *child, childThemes) - child->d_func()->setFrameColor(color, Inherit); - } - } -} - -void QQuickThemeAttachedPrivate::setPressColor(const QColor &color, Method method) -{ - Q_Q(QQuickThemeAttached); - if (!explicitPressColor || method != Inherit) { - explicitPressColor = method == Explicit; - if (data.pressColor() != color) { - data.setPressColor(color); - emit q->pressColorChanged(); - - foreach (QQuickThemeAttached *child, childThemes) - child->d_func()->setPressColor(color, Inherit); - } - } -} - -void QQuickThemeAttachedPrivate::setSelectedTextColor(const QColor &color, Method method) -{ - Q_Q(QQuickThemeAttached); - if (!explicitSelectedTextColor || method != Inherit) { - explicitSelectedTextColor = method == Explicit; - if (data.selectedTextColor() != color) { - data.setSelectedTextColor(color); - q->selectedTextColorChanged(); - - foreach (QQuickThemeAttached *child, childThemes) - child->d_func()->setSelectedTextColor(color, Inherit); - } - } -} - -void QQuickThemeAttachedPrivate::setSelectionColor(const QColor &color, Method method) -{ - Q_Q(QQuickThemeAttached); - if (!explicitSelectionColor || method != Inherit) { - explicitSelectionColor = method == Explicit; - if (data.selectionColor() != color) { - data.setSelectionColor(color); - emit q->selectionColorChanged(); - - foreach (QQuickThemeAttached *child, childThemes) - child->d_func()->setSelectionColor(color, Inherit); - } - } -} - -void QQuickThemeAttachedPrivate::setShadowColor(const QColor &color, Method method) -{ - Q_Q(QQuickThemeAttached); - if (!explicitShadowColor || method != Inherit) { - explicitShadowColor = method == Explicit; - if (data.shadowColor() != color) { - data.setShadowColor(color); - emit q->shadowColorChanged(); - - foreach (QQuickThemeAttached *child, childThemes) - child->d_func()->setShadowColor(color, Inherit); - } - } -} - -void QQuickThemeAttachedPrivate::setTextColor(const QColor &color, Method method) -{ - Q_Q(QQuickThemeAttached); - if (!explicitTextColor || method != Inherit) { - explicitTextColor = method == Explicit; - if (data.textColor() != color) { - data.setTextColor(color); - emit q->textColorChanged(); - - foreach (QQuickThemeAttached *child, childThemes) - child->d_func()->setTextColor(color, Inherit); - } - } -} - -void QQuickThemeAttachedPrivate::inherit(QQuickThemeAttached *theme) -{ - setAccentColor(theme->accentColor(), Inherit); - setBackgroundColor(theme->backgroundColor(), Inherit); - setBaseColor(theme->baseColor(), QQuickThemeAttachedPrivate::Inherit); - setDisabledColor(theme->disabledColor(), QQuickThemeAttachedPrivate::Inherit); - setFocusColor(theme->focusColor(), Inherit); - setFrameColor(theme->frameColor(), Inherit); - setPressColor(theme->pressColor(), Inherit); - setSelectedTextColor(theme->selectedTextColor(), Inherit); - setSelectionColor(theme->selectionColor(), Inherit); - setShadowColor(theme->shadowColor(), Inherit); - setTextColor(theme->textColor(), Inherit); -} - -const QQuickThemeData &QQuickThemeAttachedPrivate::resolve() const -{ - Q_Q(const QQuickThemeAttached); - QQuickThemeAttached *theme = QQuickStyle::findParent<QQuickThemeAttached>(const_cast<QQuickThemeAttached *>(q)); - return theme ? theme->d_func()->data : *globalThemeData(); -} - -void QQuickThemeAttachedPrivate::itemParentChanged(QQuickItem *item, QQuickItem *parentItem) -{ - QQuickThemeAttached *theme = QQuickStyle::instance<QQuickThemeAttached>(item); - if (theme) { - QQuickThemeAttached *parent = QQuickStyle::findParent<QQuickThemeAttached>(parentItem); - if (parent) - theme->setParentTheme(parent); - } -} - -QQuickThemeAttached::QQuickThemeAttached(QObject *parent) : - QObject(*(new QQuickThemeAttachedPrivate(*globalThemeData())), parent) -{ - Q_D(QQuickThemeAttached); - QQuickItem *item = qobject_cast<QQuickItem *>(parent); - if (item) - QQuickItemPrivate::get(item)->addItemChangeListener(d, QQuickItemPrivate::Parent); -} - -QQuickThemeAttached::QQuickThemeAttached(const QQuickThemeData &data, QObject *parent) : - QObject(*(new QQuickThemeAttachedPrivate(data)), parent) -{ - Q_D(QQuickThemeAttached); - QQuickItem *item = qobject_cast<QQuickItem *>(parent); - if (item) - QQuickItemPrivate::get(item)->addItemChangeListener(d, QQuickItemPrivate::Parent); -} - -QQuickThemeAttached::~QQuickThemeAttached() -{ - Q_D(QQuickThemeAttached); - QQuickItem *item = qobject_cast<QQuickItem *>(parent()); - if (item) - QQuickItemPrivate::get(item)->removeItemChangeListener(d, QQuickItemPrivate::Parent); - - setParentTheme(Q_NULLPTR); -} - -QQuickThemeAttached *QQuickThemeAttached::qmlAttachedProperties(QObject *object) -{ - QQuickThemeAttached *theme = Q_NULLPTR; - QQuickThemeAttached *parent = QQuickStyle::findParent<QQuickThemeAttached>(object); - if (parent) { - theme = new QQuickThemeAttached(parent->d_func()->data, object); - theme->setParentTheme(parent); - } else { - theme = new QQuickThemeAttached(object); - } - - QList<QQuickThemeAttached *> childThemes = QQuickStyle::findChildren<QQuickThemeAttached>(object); - foreach (QQuickThemeAttached *child, childThemes) - child->setParentTheme(theme); - return theme; -} - -QQuickThemeAttached *QQuickThemeAttached::parentTheme() const -{ - Q_D(const QQuickThemeAttached); - return d->parentTheme; -} - -void QQuickThemeAttached::setParentTheme(QQuickThemeAttached *theme) -{ - Q_D(QQuickThemeAttached); - if (d->parentTheme != theme) { - if (d->parentTheme) - d->parentTheme->d_func()->childThemes.remove(this); - d->parentTheme = theme; - if (theme) { - theme->d_func()->childThemes.insert(this); - d->inherit(theme); - } - } -} - -QColor QQuickThemeAttached::accentColor() const -{ - Q_D(const QQuickThemeAttached); - return d->data.accentColor(); -} - -void QQuickThemeAttached::setAccentColor(const QColor &color) -{ - Q_D(QQuickThemeAttached); - d->setAccentColor(color, QQuickThemeAttachedPrivate::Explicit); -} - -void QQuickThemeAttached::resetAccentColor() -{ - Q_D(QQuickThemeAttached); - d->setAccentColor(d->resolve().accentColor(), QQuickThemeAttachedPrivate::Implicit); -} - -QColor QQuickThemeAttached::backgroundColor() const -{ - Q_D(const QQuickThemeAttached); - return d->data.backgroundColor(); -} - -void QQuickThemeAttached::setBackgroundColor(const QColor &color) -{ - Q_D(QQuickThemeAttached); - d->setBackgroundColor(color, QQuickThemeAttachedPrivate::Explicit); -} - -void QQuickThemeAttached::resetBackgroundColor() -{ - Q_D(QQuickThemeAttached); - d->setBackgroundColor(d->resolve().backgroundColor(), QQuickThemeAttachedPrivate::Implicit); -} - -QColor QQuickThemeAttached::baseColor() const -{ - Q_D(const QQuickThemeAttached); - return d->data.baseColor(); -} - -void QQuickThemeAttached::setBaseColor(const QColor &color) -{ - Q_D(QQuickThemeAttached); - d->setBaseColor(color, QQuickThemeAttachedPrivate::Explicit); -} - -void QQuickThemeAttached::resetBaseColor() -{ - Q_D(QQuickThemeAttached); - d->setBaseColor(d->resolve().baseColor(), QQuickThemeAttachedPrivate::Implicit); -} - -QColor QQuickThemeAttached::disabledColor() const -{ - Q_D(const QQuickThemeAttached); - return d->data.disabledColor(); -} - -void QQuickThemeAttached::setDisabledColor(const QColor &color) -{ - Q_D(QQuickThemeAttached); - d->setDisabledColor(color, QQuickThemeAttachedPrivate::Explicit); -} - -void QQuickThemeAttached::resetDisabledColor() -{ - Q_D(QQuickThemeAttached); - d->setDisabledColor(d->resolve().disabledColor(), QQuickThemeAttachedPrivate::Implicit); -} - -QColor QQuickThemeAttached::focusColor() const -{ - Q_D(const QQuickThemeAttached); - return d->data.focusColor(); -} - -void QQuickThemeAttached::setFocusColor(const QColor &color) -{ - Q_D(QQuickThemeAttached); - d->setFocusColor(color, QQuickThemeAttachedPrivate::Explicit); -} - -void QQuickThemeAttached::resetFocusColor() -{ - Q_D(QQuickThemeAttached); - d->setFocusColor(d->resolve().focusColor(), QQuickThemeAttachedPrivate::Implicit); -} - -QColor QQuickThemeAttached::frameColor() const -{ - Q_D(const QQuickThemeAttached); - return d->data.frameColor(); -} - -void QQuickThemeAttached::setFrameColor(const QColor &color) -{ - Q_D(QQuickThemeAttached); - d->setFrameColor(color, QQuickThemeAttachedPrivate::Explicit); -} - -void QQuickThemeAttached::resetFrameColor() -{ - Q_D(QQuickThemeAttached); - d->setFrameColor(d->resolve().frameColor(), QQuickThemeAttachedPrivate::Implicit); -} - -QColor QQuickThemeAttached::pressColor() const -{ - Q_D(const QQuickThemeAttached); - return d->data.pressColor(); -} - -void QQuickThemeAttached::setPressColor(const QColor &color) -{ - Q_D(QQuickThemeAttached); - d->setPressColor(color, QQuickThemeAttachedPrivate::Explicit); -} - -void QQuickThemeAttached::resetPressColor() -{ - Q_D(QQuickThemeAttached); - d->setPressColor(d->resolve().pressColor(), QQuickThemeAttachedPrivate::Implicit); -} - -QColor QQuickThemeAttached::selectedTextColor() const -{ - Q_D(const QQuickThemeAttached); - return d->data.selectedTextColor(); -} - -void QQuickThemeAttached::setSelectedTextColor(const QColor &color) -{ - Q_D(QQuickThemeAttached); - d->setSelectedTextColor(color, QQuickThemeAttachedPrivate::Explicit); -} - -void QQuickThemeAttached::resetSelectedTextColor() -{ - Q_D(QQuickThemeAttached); - d->setSelectedTextColor(d->resolve().selectedTextColor(), QQuickThemeAttachedPrivate::Implicit); -} - -QColor QQuickThemeAttached::selectionColor() const -{ - Q_D(const QQuickThemeAttached); - return d->data.selectionColor(); -} - -void QQuickThemeAttached::setSelectionColor(const QColor &color) -{ - Q_D(QQuickThemeAttached); - d->setSelectionColor(color, QQuickThemeAttachedPrivate::Explicit); -} - -void QQuickThemeAttached::resetSelectionColor() -{ - Q_D(QQuickThemeAttached); - d->setSelectionColor(d->resolve().selectionColor(), QQuickThemeAttachedPrivate::Implicit); -} - -QColor QQuickThemeAttached::shadowColor() const -{ - Q_D(const QQuickThemeAttached); - return d->data.shadowColor(); -} - -void QQuickThemeAttached::setShadowColor(const QColor &color) -{ - Q_D(QQuickThemeAttached); - d->setShadowColor(color, QQuickThemeAttachedPrivate::Explicit); -} - -void QQuickThemeAttached::resetShadowColor() -{ - Q_D(QQuickThemeAttached); - d->setShadowColor(d->resolve().shadowColor(), QQuickThemeAttachedPrivate::Implicit); -} - -QColor QQuickThemeAttached::textColor() const -{ - Q_D(const QQuickThemeAttached); - return d->data.textColor(); -} - -void QQuickThemeAttached::setTextColor(const QColor &color) -{ - Q_D(QQuickThemeAttached); - d->setTextColor(color, QQuickThemeAttachedPrivate::Explicit); -} - -void QQuickThemeAttached::resetTextColor() -{ - Q_D(QQuickThemeAttached); - d->setTextColor(d->resolve().textColor(), QQuickThemeAttachedPrivate::Implicit); -} - -QT_END_NAMESPACE diff --git a/src/imports/controls/qquicktheme_p.h b/src/imports/controls/qquicktheme_p.h deleted file mode 100644 index 0d204537..00000000 --- a/src/imports/controls/qquicktheme_p.h +++ /dev/null @@ -1,151 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt Labs Controls module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL3$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or later as published by the Free -** Software Foundation and appearing in the file LICENSE.GPL included in -** the packaging of this file. Please review the following information to -** ensure the GNU General Public License version 2.0 requirements will be -** met: http://www.gnu.org/licenses/gpl-2.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QQUICKTHEME_P_H -#define QQUICKTHEME_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtQml/qqml.h> -#include <QtGui/qcolor.h> -#include <QtCore/qobject.h> - -QT_BEGIN_NAMESPACE - -class QQuickThemeData; -class QQuickThemeAttachedPrivate; - -class QQuickThemeAttached : public QObject -{ - Q_OBJECT - Q_PROPERTY(QColor accentColor READ accentColor WRITE setAccentColor RESET resetAccentColor NOTIFY accentColorChanged FINAL) - Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setBackgroundColor RESET resetBackgroundColor NOTIFY backgroundColorChanged FINAL) - Q_PROPERTY(QColor baseColor READ baseColor WRITE setBaseColor RESET resetBaseColor NOTIFY baseColorChanged FINAL) - Q_PROPERTY(QColor disabledColor READ disabledColor WRITE setDisabledColor RESET resetDisabledColor NOTIFY disabledColorChanged FINAL) - Q_PROPERTY(QColor focusColor READ focusColor WRITE setFocusColor RESET resetFocusColor NOTIFY focusColorChanged FINAL) - Q_PROPERTY(QColor frameColor READ frameColor WRITE setFrameColor RESET resetFrameColor NOTIFY frameColorChanged FINAL) - Q_PROPERTY(QColor pressColor READ pressColor WRITE setPressColor RESET resetPressColor NOTIFY pressColorChanged FINAL) - Q_PROPERTY(QColor selectedTextColor READ selectedTextColor WRITE setSelectedTextColor RESET resetSelectedTextColor NOTIFY selectedTextColorChanged FINAL) - Q_PROPERTY(QColor selectionColor READ selectionColor WRITE setSelectionColor RESET resetSelectionColor NOTIFY selectionColorChanged FINAL) - Q_PROPERTY(QColor shadowColor READ shadowColor WRITE setShadowColor RESET resetShadowColor NOTIFY shadowColorChanged FINAL) - Q_PROPERTY(QColor textColor READ textColor WRITE setTextColor RESET resetTextColor NOTIFY textColorChanged FINAL) - -public: - explicit QQuickThemeAttached(QObject *parent = Q_NULLPTR); - explicit QQuickThemeAttached(const QQuickThemeData &data, QObject *parent = Q_NULLPTR); - ~QQuickThemeAttached(); - - static QQuickThemeAttached *qmlAttachedProperties(QObject *object); - - QQuickThemeAttached *parentTheme() const; - void setParentTheme(QQuickThemeAttached *theme); - - QColor accentColor() const; - void setAccentColor(const QColor &color); - void resetAccentColor(); - - QColor disabledColor() const; - void setDisabledColor(const QColor &color); - void resetDisabledColor(); - - QColor backgroundColor() const; - void setBackgroundColor(const QColor &color); - void resetBackgroundColor(); - - QColor baseColor() const; - void setBaseColor(const QColor &color); - void resetBaseColor(); - - QColor focusColor() const; - void setFocusColor(const QColor &color); - void resetFocusColor(); - - QColor frameColor() const; - void setFrameColor(const QColor &color); - void resetFrameColor(); - - QColor pressColor() const; - void setPressColor(const QColor &color); - void resetPressColor(); - - QColor selectedTextColor() const; - void setSelectedTextColor(const QColor &color); - void resetSelectedTextColor(); - - QColor selectionColor() const; - void setSelectionColor(const QColor &color); - void resetSelectionColor(); - - QColor shadowColor() const; - void setShadowColor(const QColor &color); - void resetShadowColor(); - - QColor textColor() const; - void setTextColor(const QColor &color); - void resetTextColor(); - -Q_SIGNALS: - void accentColorChanged(); - void backgroundColorChanged(); - void baseColorChanged(); - void disabledColorChanged(); - void focusColorChanged(); - void frameColorChanged(); - void pressColorChanged(); - void selectedTextColorChanged(); - void selectionColorChanged(); - void shadowColorChanged(); - void textColorChanged(); - -private: - Q_DISABLE_COPY(QQuickThemeAttached) - Q_DECLARE_PRIVATE(QQuickThemeAttached) -}; - -QT_END_NAMESPACE - -QML_DECLARE_TYPEINFO(QQuickThemeAttached, QML_HAS_ATTACHED_PROPERTIES) - -#endif // QQUICKTHEME_P_H diff --git a/src/imports/controls/qquickthemedata.cpp b/src/imports/controls/qquickthemedata.cpp deleted file mode 100644 index e5624412..00000000 --- a/src/imports/controls/qquickthemedata.cpp +++ /dev/null @@ -1,93 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt Labs Controls 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 "qquickthemedata_p.h" - -#include <QtCore/qfile.h> -#include <QtCore/qjsondocument.h> -#include <QtCore/qjsonobject.h> -#include <QtCore/qjsonvalue.h> -#include <QtCore/qdebug.h> - -QT_BEGIN_NAMESPACE - -QQuickThemeData::QQuickThemeData(const QString &filePath) : d(new Data) -{ - if (!filePath.isEmpty()) - load(filePath); -} - -static QColor readColorValue(const QJsonValue &value, const QColor &defaultValue) -{ - if (value.isString()) - return QColor(value.toString()); - return QColor::fromRgba(value.toInt(defaultValue.rgba())); -} - -bool QQuickThemeData::load(const QString &filePath) -{ - QJsonDocument doc; - - QFile file(filePath); - if (!file.open(QFile::ReadOnly | QFile::Text)) { - qDebug() << file.error(); - qWarning() << "QQuickTheme: failed to open ':/qtlabscontrols/theme.json': " << qPrintable(file.errorString()); - return false; - } else { - QJsonParseError error; - doc = QJsonDocument::fromJson(file.readAll(), &error); - if (error.error != QJsonParseError::NoError) { - qWarning() << "QQuickTheme: failed to parse ':/qtlabscontrols/theme.json': " << qPrintable(error.errorString()); - return false; - } - } - - QJsonObject theme = doc.object(); - d->accentColor = readColorValue(theme.value(QStringLiteral("accentColor")), QColor("#7bc258")); - d->backgroundColor = readColorValue(theme.value(QStringLiteral("backgroundColor")), QColor("#ffffff")); - d->baseColor = readColorValue(theme.value(QStringLiteral("baseColor")), QColor("#eeeeee")); - d->disabledColor = readColorValue(theme.value(QStringLiteral("disabledColor")), QColor("#c2c2c2")); - d->focusColor = readColorValue(theme.value(QStringLiteral("focusColor")), QColor("#45a7d7")); - d->frameColor = readColorValue(theme.value(QStringLiteral("frameColor")), QColor("#bdbebf")); - d->pressColor = readColorValue(theme.value(QStringLiteral("pressColor")), QColor("#33333333")); - d->selectedTextColor = readColorValue(theme.value(QStringLiteral("selectedTextColor")), QColor("#ffffff")); - d->selectionColor = readColorValue(theme.value(QStringLiteral("selectionColor")), QColor("#45a7d7")); - d->shadowColor = readColorValue(theme.value(QStringLiteral("shadowColor")), QColor("#28282a")); - d->textColor = readColorValue(theme.value(QStringLiteral("textColor")), QColor("#26282a")); - return true; -} - -QT_END_NAMESPACE diff --git a/src/imports/controls/qquickthemedata_p.h b/src/imports/controls/qquickthemedata_p.h deleted file mode 100644 index 6154aa2a..00000000 --- a/src/imports/controls/qquickthemedata_p.h +++ /dev/null @@ -1,116 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt Labs Controls 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 QQUICKTHEMEDATA_P_H -#define QQUICKTHEMEDATA_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 <QtGui/qcolor.h> -#include <QtCore/qstring.h> -#include <QtCore/qshareddata.h> - -QT_BEGIN_NAMESPACE - -class QQuickThemeData -{ -public: - QQuickThemeData(const QString &filePath = QString()); - - bool load(const QString &filePath); - - QColor accentColor() const { return d->accentColor; } - void setAccentColor(const QColor &color) { d->accentColor = color; } - - QColor backgroundColor() const { return d->backgroundColor; } - void setBackgroundColor(const QColor &color) { d->backgroundColor = color; } - - QColor baseColor() const { return d->baseColor; } - void setBaseColor(const QColor &color) { d->baseColor = color; } - - QColor disabledColor() const { return d->disabledColor; } - void setDisabledColor(const QColor &color) { d->disabledColor = color; } - - QColor focusColor() const { return d->focusColor; } - void setFocusColor(const QColor &color) { d->focusColor = color; } - - QColor frameColor() const { return d->frameColor; } - void setFrameColor(const QColor &color) { d->frameColor = color; } - - QColor pressColor() const { return d->pressColor; } - void setPressColor(const QColor &color) { d->pressColor = color; } - - QColor selectedTextColor() const { return d->selectedTextColor; } - void setSelectedTextColor(const QColor &color) { d->selectedTextColor = color; } - - QColor selectionColor() const { return d->selectionColor; } - void setSelectionColor(const QColor &color) { d->selectionColor = color; } - - QColor shadowColor() const { return d->shadowColor; } - void setShadowColor(const QColor &color) { d->shadowColor = color; } - - QColor textColor() const { return d->textColor; } - void setTextColor(const QColor &color) { d->textColor = color; } - -private: - struct Data : public QSharedData { - QColor accentColor; - QColor baseColor; - QColor backgroundColor; - QColor disabledColor; - QColor focusColor; - QColor frameColor; - QColor pressColor; - QColor selectedTextColor; - QColor selectionColor; - QColor shadowColor; - QColor textColor; - }; - QSharedDataPointer<Data> d; -}; - -QT_END_NAMESPACE - -#endif // QQUICKTHEMEDATA_P_H diff --git a/src/imports/controls/qtlabscontrolsplugin.cpp b/src/imports/controls/qtlabscontrolsplugin.cpp index 0194e033..079d843d 100644 --- a/src/imports/controls/qtlabscontrolsplugin.cpp +++ b/src/imports/controls/qtlabscontrolsplugin.cpp @@ -37,14 +37,11 @@ #include <QtQml/qqmlextensionplugin.h> #include <QtCore/qurl.h> #include <QtCore/qcoreapplication.h> -#include <QtCore/qcommandlineparser.h> -#include <QtLabsTemplates/private/qquickexclusivegroup_p.h> +#include <QtLabsTemplates/private/qquickbuttongroup_p.h> +#include <QtLabsControls/private/qquickstyleselector_p.h> -#include "qquicktheme_p.h" -#include "qquickfileselector_p.h" - -void initResources() +static inline void initResources() { Q_INIT_RESOURCE(qtlabscontrolsplugin); } @@ -63,53 +60,43 @@ public: void QtLabsControlsPlugin::registerTypes(const char *uri) { - qmlRegisterUncreatableType<QQuickThemeAttached>(uri, 1, 0, "Theme", "Theme is an attached property"); - - qmlRegisterType<QQuickExclusiveGroup>(uri, 1, 0, "ExclusiveGroup"); - qmlRegisterType<QQuickExclusiveGroupAttached>(); - - QCommandLineParser parser; - QCommandLineOption styleOption(QStringList() << "s" << "style", tr("the style to use for the application"), tr("style")); - parser.addOption(styleOption); - parser.setSingleDashWordOptionMode(QCommandLineParser::ParseAsLongOptions); - parser.parse(QCoreApplication::arguments()); + qmlRegisterType<QQuickButtonGroup>(uri, 1, 0, "ButtonGroup"); + qmlRegisterType<QQuickButtonGroupAttached>(); // TODO: read the style from application manifest file - QQuickFileSelector selector; - selector.setBaseUrl(baseUrl()); - - if (parser.isSet(styleOption)) { - QString style = parser.value(styleOption); - selector.setStyle(style); - } - - qmlRegisterType(selector.select(QStringLiteral("/ApplicationWindow.qml")), uri, 1, 0, "ApplicationWindow"); - qmlRegisterType(selector.select(QStringLiteral("/BusyIndicator.qml")), uri, 1, 0, "BusyIndicator"); - qmlRegisterType(selector.select(QStringLiteral("/Button.qml")), uri, 1, 0, "Button"); - qmlRegisterType(selector.select(QStringLiteral("/CheckBox.qml")), uri, 1, 0, "CheckBox"); - qmlRegisterType(selector.select(QStringLiteral("/Dial.qml")), uri, 1, 0, "Dial"); - qmlRegisterType(selector.select(QStringLiteral("/Drawer.qml")), uri, 1, 0, "Drawer"); - qmlRegisterType(selector.select(QStringLiteral("/Frame.qml")), uri, 1, 0, "Frame"); - qmlRegisterType(selector.select(QStringLiteral("/GroupBox.qml")), uri, 1, 0, "GroupBox"); - qmlRegisterType(selector.select(QStringLiteral("/Label.qml")), uri, 1, 0, "Label"); - qmlRegisterType(selector.select(QStringLiteral("/PageIndicator.qml")), uri, 1, 0, "PageIndicator"); - qmlRegisterType(selector.select(QStringLiteral("/ProgressBar.qml")), uri, 1, 0, "ProgressBar"); - qmlRegisterType(selector.select(QStringLiteral("/RadioButton.qml")), uri, 1, 0, "RadioButton"); - qmlRegisterType(selector.select(QStringLiteral("/RangeSlider.qml")), uri, 1, 0, "RangeSlider"); - qmlRegisterType(selector.select(QStringLiteral("/ScrollBar.qml")), uri, 1, 0, "ScrollBar"); - qmlRegisterType(selector.select(QStringLiteral("/ScrollIndicator.qml")), uri, 1, 0, "ScrollIndicator"); - qmlRegisterType(selector.select(QStringLiteral("/Slider.qml")), uri, 1, 0, "Slider"); - qmlRegisterType(selector.select(QStringLiteral("/SpinBox.qml")), uri, 1, 0, "SpinBox"); - qmlRegisterType(selector.select(QStringLiteral("/StackView.qml")), uri, 1, 0, "StackView"); - qmlRegisterType(selector.select(QStringLiteral("/SwipeView.qml")), uri, 1, 0, "SwipeView"); - qmlRegisterType(selector.select(QStringLiteral("/Switch.qml")), uri, 1, 0, "Switch"); - qmlRegisterType(selector.select(QStringLiteral("/TabBar.qml")), uri, 1, 0, "TabBar"); - qmlRegisterType(selector.select(QStringLiteral("/TabButton.qml")), uri, 1, 0, "TabButton"); - qmlRegisterType(selector.select(QStringLiteral("/TextArea.qml")), uri, 1, 0, "TextArea"); - qmlRegisterType(selector.select(QStringLiteral("/TextField.qml")), uri, 1, 0, "TextField"); - qmlRegisterType(selector.select(QStringLiteral("/ToolBar.qml")), uri, 1, 0, "ToolBar"); - qmlRegisterType(selector.select(QStringLiteral("/ToolButton.qml")), uri, 1, 0, "ToolButton"); - qmlRegisterType(selector.select(QStringLiteral("/Tumbler.qml")), uri, 1, 0, "Tumbler"); + QQuickStyleSelector *selector = QQuickStyleSelector::instance(); + selector->setBaseUrl(baseUrl()); + + qmlRegisterType(selector->select(QStringLiteral("/ApplicationWindow.qml")), uri, 1, 0, "ApplicationWindow"); + qmlRegisterType(selector->select(QStringLiteral("/BusyIndicator.qml")), uri, 1, 0, "BusyIndicator"); + qmlRegisterType(selector->select(QStringLiteral("/Button.qml")), uri, 1, 0, "Button"); + qmlRegisterType(selector->select(QStringLiteral("/CheckBox.qml")), uri, 1, 0, "CheckBox"); + qmlRegisterType(selector->select(QStringLiteral("/Dial.qml")), uri, 1, 0, "Dial"); + qmlRegisterType(selector->select(QStringLiteral("/Drawer.qml")), uri, 1, 0, "Drawer"); + qmlRegisterType(selector->select(QStringLiteral("/Frame.qml")), uri, 1, 0, "Frame"); + qmlRegisterType(selector->select(QStringLiteral("/GroupBox.qml")), uri, 1, 0, "GroupBox"); + qmlRegisterType(selector->select(QStringLiteral("/ItemDelegate.qml")), uri, 1, 0, "ItemDelegate"); + qmlRegisterType(selector->select(QStringLiteral("/Label.qml")), uri, 1, 0, "Label"); + qmlRegisterType(selector->select(QStringLiteral("/Menu.qml")), uri, 1, 0, "Menu"); + qmlRegisterType(selector->select(QStringLiteral("/MenuItem.qml")), uri, 1, 0, "MenuItem"); + qmlRegisterType(selector->select(QStringLiteral("/PageIndicator.qml")), uri, 1, 0, "PageIndicator"); + qmlRegisterType(selector->select(QStringLiteral("/ProgressBar.qml")), uri, 1, 0, "ProgressBar"); + qmlRegisterType(selector->select(QStringLiteral("/RadioButton.qml")), uri, 1, 0, "RadioButton"); + qmlRegisterType(selector->select(QStringLiteral("/RangeSlider.qml")), uri, 1, 0, "RangeSlider"); + qmlRegisterType(selector->select(QStringLiteral("/ScrollBar.qml")), uri, 1, 0, "ScrollBar"); + qmlRegisterType(selector->select(QStringLiteral("/ScrollIndicator.qml")), uri, 1, 0, "ScrollIndicator"); + qmlRegisterType(selector->select(QStringLiteral("/Slider.qml")), uri, 1, 0, "Slider"); + qmlRegisterType(selector->select(QStringLiteral("/SpinBox.qml")), uri, 1, 0, "SpinBox"); + qmlRegisterType(selector->select(QStringLiteral("/StackView.qml")), uri, 1, 0, "StackView"); + qmlRegisterType(selector->select(QStringLiteral("/SwipeView.qml")), uri, 1, 0, "SwipeView"); + qmlRegisterType(selector->select(QStringLiteral("/Switch.qml")), uri, 1, 0, "Switch"); + qmlRegisterType(selector->select(QStringLiteral("/TabBar.qml")), uri, 1, 0, "TabBar"); + qmlRegisterType(selector->select(QStringLiteral("/TabButton.qml")), uri, 1, 0, "TabButton"); + qmlRegisterType(selector->select(QStringLiteral("/TextArea.qml")), uri, 1, 0, "TextArea"); + qmlRegisterType(selector->select(QStringLiteral("/TextField.qml")), uri, 1, 0, "TextField"); + qmlRegisterType(selector->select(QStringLiteral("/ToolBar.qml")), uri, 1, 0, "ToolBar"); + qmlRegisterType(selector->select(QStringLiteral("/ToolButton.qml")), uri, 1, 0, "ToolButton"); + qmlRegisterType(selector->select(QStringLiteral("/Tumbler.qml")), uri, 1, 0, "Tumbler"); } void QtLabsControlsPlugin::initializeEngine(QQmlEngine *engine, const char *uri) diff --git a/src/imports/controls/qtlabscontrolsplugin.qrc b/src/imports/controls/qtlabscontrolsplugin.qrc index b71ec91c..c54083ed 100644 --- a/src/imports/controls/qtlabscontrolsplugin.qrc +++ b/src/imports/controls/qtlabscontrolsplugin.qrc @@ -1,10 +1,15 @@ -<!DOCTYPE RCC><RCC version="1.0"> -<qresource prefix="/qtlabscontrols"> - <file>theme.json</file> -</qresource> -<qresource> - <file>images/spinner_small.png</file> - <file>images/spinner_medium.png</file> - <file>images/spinner_large.png</file> -</qresource> +<RCC> + <qresource prefix="/"> + <file>images/spinner_small.png</file> + <file>images/spinner_medium.png</file> + <file>images/spinner_large.png</file> + <file>images/check.png</file> + <file>images/check@2x.png</file> + <file>images/check@3x.png</file> + <file>images/check@4x.png</file> + <file>images/dial-indicator.png</file> + <file>images/dial-indicator@2x.png</file> + <file>images/dial-indicator@3x.png</file> + <file>images/dial-indicator@4x.png</file> + </qresource> </RCC> diff --git a/src/imports/controls/shared/qquickstyle_p.h b/src/imports/controls/shared/qquickstyle_p.h deleted file mode 100644 index 0fd4f612..00000000 --- a/src/imports/controls/shared/qquickstyle_p.h +++ /dev/null @@ -1,157 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt Labs Controls 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 QQUICKSTYLE_P_H -#define QQUICKSTYLE_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 <QtQml/qqml.h> -#include <QtQml/qqmlengine.h> -#include <QtQuick/qquickitem.h> -#include <QtQuick/qquickwindow.h> - -QT_BEGIN_NAMESPACE - -namespace QQuickStyle -{ - template <typename T> - static T *instance(QObject *object) - { - if (object) - return qobject_cast<T*>(qmlAttachedPropertiesObject<T>(object, false)); - return Q_NULLPTR; - } - - template <typename T> - static T *findParent(QObject *object) - { - QQuickItem *item = qobject_cast<QQuickItem *>(object); - if (item) { - // lookup parent items - QQuickItem *parent = item->parentItem(); - while (parent) { - T *attached = instance<T>(parent); - if (attached) - return attached; - parent = parent->parentItem(); - } - - // fallback to item's window - QQuickWindow *window = item->window(); - if (window) { - T *attached = instance<T>(window); - if (attached) - return attached; - } - } - - // lookup parent window - QQuickWindow *window = qobject_cast<QQuickWindow *>(object); - if (window) { - QQuickWindow *parentWindow = qobject_cast<QQuickWindow *>(window->parent()); - if (parentWindow) { - T *attached = instance<T>(window); - if (attached) - return attached; - } - } - - // fallback to engine (global) - if (object) { - QQmlEngine *engine = qmlEngine(object); - if (engine) { - QByteArray name = QByteArray("_q_") + T::staticMetaObject.className(); - T *instance = engine->property(name).value<T*>(); - if (!instance) { - instance = new T(engine); - engine->setProperty(name, QVariant::fromValue(instance)); - } - return instance; - } - } - - return Q_NULLPTR; - } - - template <typename T> - static QList<T *> findChildren(QObject *object) - { - QList<T *> children; - - QQuickItem *item = qobject_cast<QQuickItem *>(object); - if (!item) { - QQuickWindow *window = qobject_cast<QQuickWindow *>(object); - if (window) { - item = window->contentItem(); - - foreach (QObject *child, window->children()) { - QQuickWindow *childWindow = qobject_cast<QQuickWindow *>(child); - if (childWindow) { - T *attached = instance<T>(childWindow); - if (attached) - children += attached; - } - } - } - } - - if (item) { - foreach (QQuickItem *child, item->childItems()) { - T *attached = instance<T>(child); - if (attached) - children += attached; - else - children += findChildren<T>(child); - } - } - - return children; - } -} - -QT_END_NAMESPACE - -#endif // QQUICKSTYLE_P_H diff --git a/src/imports/controls/shared/shared.pri b/src/imports/controls/shared/shared.pri deleted file mode 100644 index 2979a615..00000000 --- a/src/imports/controls/shared/shared.pri +++ /dev/null @@ -1,4 +0,0 @@ -INCLUDEPATH += $$PWD - -HEADERS += \ - $$PWD/qquickstyle_p.h diff --git a/src/imports/controls/theme.json b/src/imports/controls/theme.json deleted file mode 100644 index c5c19d47..00000000 --- a/src/imports/controls/theme.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "accentColor": "#7bc258", - "backgroundColor": "#ffffff", - "baseColor": "#eeeeee", - "disabledColor": "#c2c2c2", - "focusColor": "#45a7d7", - "frameColor": "#bdbebf", - "pressColor": "#33333333", - "selectedTextColor": "#ffffff", - "selectionColor": "#45a7d7", - "shadowColor": "#28282a", - "textColor": "#26282a" -} diff --git a/src/imports/controls/universal/ApplicationWindow.qml b/src/imports/controls/universal/ApplicationWindow.qml new file mode 100644 index 00000000..46b8e740 --- /dev/null +++ b/src/imports/controls/universal/ApplicationWindow.qml @@ -0,0 +1,45 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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$ +** +****************************************************************************/ + +import QtQuick 2.6 +import Qt.labs.templates 1.0 as T +import Qt.labs.controls.universal 1.0 + +T.ApplicationWindow { + id: window + + color: Universal.altHighColor +} diff --git a/src/imports/controls/universal/BusyIndicator.qml b/src/imports/controls/universal/BusyIndicator.qml new file mode 100644 index 00000000..3e0e1f89 --- /dev/null +++ b/src/imports/controls/universal/BusyIndicator.qml @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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$ +** +****************************************************************************/ + +import QtQuick 2.6 +import Qt.labs.templates 1.0 as T +import Qt.labs.controls.universal 1.0 +import Qt.labs.controls.universal.impl 1.0 + +T.BusyIndicator { + id: control + + implicitWidth: contentItem.implicitWidth + leftPadding + rightPadding + implicitHeight: contentItem.implicitHeight + topPadding + bottomPadding + + //! [contentItem] + contentItem: ProgressRing { + id: ring + + implicitWidth: 20 + implicitHeight: 20 + + readonly property real size: Math.min(control.availableWidth, control.availableHeight) + + count: size < 60 ? 5 : 6 // "Small" vs. "Large" + color: control.Universal.accentColor + + ProgressRingAnimator { + target: ring + running: control.visible && control.running + } + } + //! [contentItem] +} diff --git a/src/imports/controls/universal/Button.qml b/src/imports/controls/universal/Button.qml new file mode 100644 index 00000000..41198f89 --- /dev/null +++ b/src/imports/controls/universal/Button.qml @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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$ +** +****************************************************************************/ + +import QtQuick 2.6 +import Qt.labs.templates 1.0 as T +import Qt.labs.controls.universal 1.0 + +T.Button { + id: control + + implicitWidth: Math.max(background ? background.implicitWidth : 0, + label ? label.implicitWidth + leftPadding + rightPadding : 0) + implicitHeight: Math.max(background ? background.implicitHeight : 0, + label ? label.implicitHeight + topPadding + bottomPadding : 0) + baselineOffset: label ? label.y + label.baselineOffset : 0 + + topPadding: 4 + leftPadding: 8 + rightPadding: 8 + bottomPadding: 4 + + //! [label] + label: Text { + x: control.leftPadding + y: control.topPadding + width: control.availableWidth + height: control.availableHeight + + text: control.text + font: control.font + elide: Text.ElideRight + horizontalAlignment: Text.AlignLeft + verticalAlignment: Text.AlignVCenter + renderType: Text.NativeRendering + + color: !control.enabled ? control.Universal.baseLowColor : control.Universal.baseHighColor + } + //! [label] + + //! [background] + background: Rectangle { + implicitWidth: 32 + implicitHeight: 32 + + color: control.pressed ? control.Universal.baseMediumLowColor : + control.enabled && (control.highlighted || control.checked) ? control.Universal.accentColor : + control.Universal.baseLowColor + } + //! [background] +} diff --git a/src/imports/controls/universal/CheckBox.qml b/src/imports/controls/universal/CheckBox.qml new file mode 100644 index 00000000..52523ffd --- /dev/null +++ b/src/imports/controls/universal/CheckBox.qml @@ -0,0 +1,111 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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$ +** +****************************************************************************/ + +import QtQuick 2.6 +import Qt.labs.templates 1.0 as T +import Qt.labs.controls.universal 1.0 + +T.CheckBox { + id: control + + implicitWidth: Math.max(background ? background.implicitWidth : 0, + (label ? label.implicitWidth : 0) + + (indicator ? indicator.implicitWidth : 0) + + (label && indicator ? spacing : 0) + leftPadding + rightPadding) + implicitHeight: Math.max(background ? background.implicitHeight : 0, + Math.max(label ? label.implicitHeight : 0, + indicator ? indicator.implicitHeight : 0) + topPadding + bottomPadding) + baselineOffset: label ? label.y + label.baselineOffset : 0 + + padding: 6 + spacing: 8 + + //! [indicator] + indicator: Rectangle { + id: normalRectangle + implicitWidth: 20 + implicitHeight: 20 + x: text ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) : control.leftPadding + (control.availableWidth - width) / 2 + y: control.topPadding + (control.availableHeight - height) / 2 + + color: !control.enabled ? "transparent" : + control.pressed && control.checkState !== Qt.PartiallyChecked ? control.Universal.baseMediumColor : + control.checkState === Qt.Checked ? control.Universal.accentColor : "transparent" + border.color: !control.enabled ? control.Universal.baseLowColor : + control.pressed ? control.Universal.baseMediumColor : + control.checked ? control.Universal.accentColor : control.Universal.baseMediumHighColor + border.width: 2 // CheckBoxBorderThemeThickness + + Image { + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + + visible: control.checkState === Qt.Checked + source: "image://universal/checkmark/" + (!control.enabled ? control.Universal.baseLowColor : control.Universal.chromeWhiteColor) + } + + Rectangle { + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + width: parent.width / 2 + height: parent.height / 2 + + visible: control.checkState === Qt.PartiallyChecked + color: !control.enabled ? control.Universal.baseLowColor : + control.pressed ? control.Universal.baseMediumColor : control.Universal.baseMediumHighColor + } + } + //! [indicator] + + //! [label] + label: Text { + x: control.mirrored ? control.leftPadding : (indicator.x + indicator.width + control.spacing) + y: control.topPadding + width: control.availableWidth - indicator.width - control.spacing + height: control.availableHeight + + text: control.text + font: control.font + elide: Text.ElideRight + visible: control.text + horizontalAlignment: Text.AlignLeft + verticalAlignment: Text.AlignVCenter + renderType: Text.NativeRendering + + color: !control.enabled ? control.Universal.baseLowColor : control.Universal.baseHighColor + } + //! [label] +} diff --git a/src/imports/controls/universal/Dial.qml b/src/imports/controls/universal/Dial.qml new file mode 100644 index 00000000..f80ff18b --- /dev/null +++ b/src/imports/controls/universal/Dial.qml @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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$ +** +****************************************************************************/ + +import QtQuick 2.6 +import Qt.labs.templates 1.0 as T +import Qt.labs.controls.universal 1.0 + +T.Dial { + id: control + + implicitWidth: 100 + implicitHeight: 100 + + //! [background] + background: Rectangle { + radius: width / 2 + color: "transparent" + border.color: !control.enabled ? control.Universal.baseLowColor : control.Universal.baseMediumColor + border.width: 2 + } + //! [background] + + //! [handle] + handle: Rectangle { + implicitWidth: 20 + implicitHeight: 20 + + x: background.width / 2 - handle.width / 2 + y: background.height / 2 - handle.height / 2 + + radius: width / 2 + color: !control.enabled ? control.Universal.baseLowColor : + control.pressed ? control.Universal.baseMediumColor : control.Universal.baseMediumHighColor + + transform: [ + Translate { + y: -control.height * 0.35 + }, + Rotation { + angle: control.angle + origin.x: handle.width / 2 + origin.y: handle.height / 2 + } + ] + } + //! [handle] +} diff --git a/src/imports/controls/universal/Frame.qml b/src/imports/controls/universal/Frame.qml new file mode 100644 index 00000000..47e9e389 --- /dev/null +++ b/src/imports/controls/universal/Frame.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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$ +** +****************************************************************************/ + +import QtQuick 2.6 +import Qt.labs.templates 1.0 as T +import Qt.labs.controls.universal 1.0 + +T.Frame { + id: control + + implicitWidth: Math.max(background ? background.implicitWidth : 0, contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(background ? background.implicitHeight : 0, contentHeight + topPadding + bottomPadding) + + contentWidth: contentChildren.length === 1 ? contentChildren[0].implicitWidth : 0 + contentHeight: contentChildren.length === 1 ? contentChildren[0].implicitHeight : 0 + + padding: 12 + + //! [contentItem] + contentItem: Item { } + //! [contentItem] + + //! [frame] + frame: Rectangle { + width: parent.width + height: parent.height + + color: "transparent" + border.color: control.Universal.chromeDisabledLowColor + } + //! [frame] +} diff --git a/src/imports/controls/universal/GroupBox.qml b/src/imports/controls/universal/GroupBox.qml new file mode 100644 index 00000000..cf7b7405 --- /dev/null +++ b/src/imports/controls/universal/GroupBox.qml @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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$ +** +****************************************************************************/ + +import QtQuick 2.6 +import Qt.labs.templates 1.0 as T +import Qt.labs.controls.universal 1.0 + +T.GroupBox { + id: control + + implicitWidth: Math.max(background ? background.implicitWidth : 0, contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(background ? background.implicitHeight : 0, contentHeight + topPadding + bottomPadding) + + contentWidth: contentChildren.length === 1 ? contentChildren[0].implicitWidth : 0 + contentHeight: contentChildren.length === 1 ? contentChildren[0].implicitHeight : 0 + + spacing: 12 + padding: 12 + topPadding: 12 + (label && title ? label.implicitHeight + spacing : 0) + + //! [contentItem] + contentItem: Item { } + //! [contentItem] + + //! [label] + label: Text { + x: control.leftPadding + width: control.availableWidth + + text: control.title + font: control.font + color: !control.enabled ? control.Universal.baseLowColor : control.Universal.baseHighColor + elide: Text.ElideRight + horizontalAlignment: Text.AlignLeft + verticalAlignment: Text.AlignVCenter + renderType: Text.NativeRendering + } + //! [label] + + //! [frame] + frame: Rectangle { + y: control.topPadding - control.padding + width: parent.width + height: parent.height - control.topPadding + control.padding + + color: "transparent" + border.color: control.Universal.chromeDisabledLowColor + } + //! [frame] +} diff --git a/src/imports/controls/universal/ItemDelegate.qml b/src/imports/controls/universal/ItemDelegate.qml new file mode 100644 index 00000000..d9156177 --- /dev/null +++ b/src/imports/controls/universal/ItemDelegate.qml @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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$ +** +****************************************************************************/ + +import QtQuick 2.6 +import Qt.labs.templates 1.0 as T +import Qt.labs.controls.universal 1.0 + +T.ItemDelegate { + id: control + + implicitWidth: Math.max(background ? background.implicitWidth : 0, + (label ? label.implicitWidth : 0) + + (indicator ? indicator.implicitWidth : 0) + + (label && indicator ? spacing : 0) + leftPadding + rightPadding) + implicitHeight: Math.max(background ? background.implicitHeight : 0, + Math.max(label ? label.implicitHeight : 0, + indicator ? indicator.implicitHeight : 0) + topPadding + bottomPadding) + + spacing: 12 + + topPadding: 11 + leftPadding: 12 + rightPadding: 12 + bottomPadding: 13 + + //! [indicator] + indicator: Image { + x: text ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) : control.leftPadding + (control.availableWidth - width) / 2 + y: control.topPadding + (control.availableHeight - height) / 2 + + visible: control.checked + source: !control.checkable ? "" : "image://universal/checkmark/" + (!control.enabled ? control.Universal.baseLowColor : control.pressed ? control.Universal.baseHighColor : control.Universal.baseMediumHighColor) + } + //! [indicator] + + //! [label] + label: Text { + x: control.mirrored || !control.checkable ? control.leftPadding : (indicator.x + indicator.width + control.spacing) + y: control.topPadding + width: control.availableWidth - (control.checkable ? indicator.width + control.spacing : 0) + height: control.availableHeight + + text: control.text + font: control.font + elide: Text.ElideRight + visible: control.text + horizontalAlignment: Text.AlignLeft + verticalAlignment: Text.AlignVCenter + renderType: Text.NativeRendering + + color: !control.enabled ? control.Universal.baseLowColor : control.Universal.baseHighColor + } + //! [label] + + //! [background] + background: Rectangle { + visible: control.pressed + color: control.Universal.listMediumColor + } + //! [background] +} diff --git a/src/imports/controls/universal/Label.qml b/src/imports/controls/universal/Label.qml new file mode 100644 index 00000000..ee51c8cd --- /dev/null +++ b/src/imports/controls/universal/Label.qml @@ -0,0 +1,47 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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$ +** +****************************************************************************/ + +import QtQuick 2.6 +import Qt.labs.templates 1.0 as T +import Qt.labs.controls.universal 1.0 + +T.Label { + id: control + + color: !control.enabled ? Universal.baseLowColor : Universal.baseHighColor + linkColor: Universal.accentColor + renderType: Text.NativeRendering +} diff --git a/src/imports/controls/universal/PageIndicator.qml b/src/imports/controls/universal/PageIndicator.qml new file mode 100644 index 00000000..f3ec9a7b --- /dev/null +++ b/src/imports/controls/universal/PageIndicator.qml @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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$ +** +****************************************************************************/ + +import QtQuick 2.6 +import Qt.labs.templates 1.0 as T +import Qt.labs.controls.universal 1.0 + +T.PageIndicator { + id: control + + implicitWidth: Math.max(background ? background.implicitWidth : 0, + contentItem.implicitWidth + leftPadding + rightPadding) + implicitHeight: Math.max(background ? background.implicitHeight : 0, + contentItem.implicitHeight + topPadding + bottomPadding) + + padding: 6 + spacing: 7 + + //! [delegate] + delegate: Rectangle { + implicitWidth: 5 + implicitHeight: 5 + + radius: width / 2 + color: index === control.currentIndex ? control.Universal.baseMediumHighColor : + pressed ? control.Universal.baseMediumLowColor : control.Universal.baseLowColor + } + //! [delegate] + + //! [contentItem] + contentItem: Row { + spacing: control.spacing + + Repeater { + model: control.count + delegate: control.delegate + } + } + //! [contentItem] +} diff --git a/src/imports/controls/universal/ProgressBar.qml b/src/imports/controls/universal/ProgressBar.qml new file mode 100644 index 00000000..14fd9bd7 --- /dev/null +++ b/src/imports/controls/universal/ProgressBar.qml @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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$ +** +****************************************************************************/ + +import QtQuick 2.6 +import Qt.labs.templates 1.0 as T +import Qt.labs.controls.universal 1.0 +import Qt.labs.controls.universal.impl 1.0 + +T.ProgressBar { + id: control + + implicitWidth: Math.max(background ? background.implicitWidth : 0, + indicator ? indicator.implicitWidth : 0) + leftPadding + rightPadding + implicitHeight: Math.max(background ? background.implicitHeight : 0, + indicator ? indicator.implicitHeight : 0) + topPadding + bottomPadding + + //! [indicator] + indicator: Rectangle { + x: control.leftPadding + y: control.topPadding + width: control.indeterminate ? 0 : control.position * control.availableWidth + height: control.availableHeight + + scale: control.mirrored ? -1 : 1 + color: control.Universal.accentColor + + ProgressStrip { + id: strip + + width: control.availableWidth + height: control.availableHeight + + clip: control.indeterminate + visible: control.indeterminate + color: control.Universal.accentColor + + ProgressStripAnimator { + target: strip + running: strip.visible + } + } + } + //! [indicator] + + //! [background] + background: Rectangle { + implicitWidth: 100 + implicitHeight: 10 + + x: control.leftPadding + y: control.topPadding + width: control.availableWidth + height: control.availableHeight + + visible: !control.indeterminate + color: control.Universal.baseLowColor + } + //! [background] +} diff --git a/src/imports/controls/universal/README.md b/src/imports/controls/universal/README.md new file mode 100644 index 00000000..8d02d18b --- /dev/null +++ b/src/imports/controls/universal/README.md @@ -0,0 +1,9 @@ +# Universal Style + +This style is based on the [Microsoft Universal Design Guidelines](https://dev.windows.com/design). + +The colors and metrics used all around the QML and C++ files originate from the Windows 10 SDK. The files are called **generic.xaml** and **themeresources.xml**, and they are located in the following folder: + + \(Program Files)\Windows Kits\10\DesignTime\CommonConfiguration\Neutral\UAP\<SDK version>\Generic + +See also [XAML theme resources](https://msdn.microsoft.com/en-us/library/windows/apps/mt187274.aspx). diff --git a/src/imports/controls/universal/RadioButton.qml b/src/imports/controls/universal/RadioButton.qml new file mode 100644 index 00000000..02212c4f --- /dev/null +++ b/src/imports/controls/universal/RadioButton.qml @@ -0,0 +1,117 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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$ +** +****************************************************************************/ + +import QtQuick 2.6 +import Qt.labs.templates 1.0 as T +import Qt.labs.controls.universal 1.0 + +T.RadioButton { + id: control + + implicitWidth: Math.max(background ? background.implicitWidth : 0, + (label ? label.implicitWidth : 0) + + (indicator ? indicator.implicitWidth : 0) + + (label && indicator ? spacing : 0) + leftPadding + rightPadding) + implicitHeight: Math.max(background ? background.implicitHeight : 0, + Math.max(label ? label.implicitHeight : 0, + indicator ? indicator.implicitHeight : 0) + topPadding + bottomPadding) + baselineOffset: label ? label.y + label.baselineOffset : 0 + + padding: 6 + spacing: 8 + + //! [indicator] + indicator: Rectangle { + id: outerEllipse + implicitWidth: 20 + implicitHeight: 20 + x: text ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) : control.leftPadding + (control.availableWidth - width) / 2 + y: control.topPadding + (control.availableHeight - height) / 2 + + radius: width / 2 + color: "transparent" + border.width: 2 // RadioButtonBorderThemeThickness + border.color: control.checked ? "transparent" : + !control.enabled ? control.Universal.baseLowColor : + control.pressed ? control.Universal.baseMediumColor : control.Universal.baseMediumHighColor + + Rectangle { + id: checkOuterEllipse + width: parent.width + height: parent.height + + radius: width / 2 + opacity: control.checked ? 1 : 0 + color: "transparent" + border.width: 2 // RadioButtonBorderThemeThickness + border.color: !control.enabled ? control.Universal.baseLowColor : + control.pressed ? control.Universal.baseMediumColor : control.Universal.accentColor + } + + Rectangle { + id: checkGlyph + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + width: parent.width / 2 + height: parent.height / 2 + + radius: width / 2 + opacity: control.checked ? 1 : 0 + color: !control.enabled ? control.Universal.baseLowColor : + control.pressed ? control.Universal.baseMediumColor : control.Universal.baseMediumHighColor + } + } + //! [indicator] + + //! [label] + label: Text { + x: control.mirrored ? control.leftPadding : (indicator.x + indicator.width + control.spacing) + y: control.topPadding + width: control.availableWidth - indicator.width - control.spacing + height: control.availableHeight + + text: control.text + font: control.font + elide: Text.ElideRight + visible: control.text + horizontalAlignment: Text.AlignLeft + verticalAlignment: Text.AlignVCenter + renderType: Text.NativeRendering + + color: !control.enabled ? control.Universal.baseLowColor : control.Universal.baseHighColor + } + //! [label] +} diff --git a/src/imports/controls/universal/RangeSlider.qml b/src/imports/controls/universal/RangeSlider.qml new file mode 100644 index 00000000..285a04a7 --- /dev/null +++ b/src/imports/controls/universal/RangeSlider.qml @@ -0,0 +1,118 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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$ +** +****************************************************************************/ + +import QtQuick 2.6 +import Qt.labs.templates 1.0 as T +import Qt.labs.controls.universal 1.0 + +T.RangeSlider { + id: control + + implicitWidth: Math.max(background ? background.implicitWidth : 0, + Math.max(track ? track.implicitWidth : 0, + first.handle ? first.handle.implicitWidth : 0, + second.handle ? second.handle.implicitWidth : 0) + leftPadding + rightPadding) + implicitHeight: Math.max(background ? background.implicitHeight : 0, + Math.max(track ? track.implicitHeight : 0, + first.handle ? first.handle.implicitHeight : 0, + second.handle ? second.handle.implicitHeight : 0) + topPadding + bottomPadding) + + padding: 6 + + //! [firstHandle] + first.handle: Rectangle { + implicitWidth: horizontal ? 8 : 24 + implicitHeight: horizontal ? 24 : 8 + + readonly property bool horizontal: control.orientation === Qt.Horizontal + + x: control.leftPadding + (horizontal ? control.first.visualPosition * (control.availableWidth - width) : (control.availableWidth - width) / 2) + y: control.topPadding + (horizontal ? (control.availableHeight - height) / 2 : control.first.visualPosition * (control.availableHeight - height)) + + radius: 4 + color: control.first.pressed ? control.Universal.chromeHighColor : control.enabled ? control.Universal.accentColor : control.Universal.chromeDisabledHighColor + } + //! [firstHandle] + + //! [secondHandle] + second.handle: Rectangle { + implicitWidth: horizontal ? 8 : 24 + implicitHeight: horizontal ? 24 : 8 + + readonly property bool horizontal: control.orientation === Qt.Horizontal + + x: control.leftPadding + (horizontal ? control.second.visualPosition * (control.availableWidth - width) : (control.availableWidth - width) / 2) + y: control.topPadding + (horizontal ? (control.availableHeight - height) / 2 : control.second.visualPosition * (control.availableHeight - height)) + + radius: 4 + color: control.second.pressed ? control.Universal.chromeHighColor : control.enabled ? control.Universal.accentColor : control.Universal.chromeDisabledHighColor + } + //! [secondHandle] + + //! [track] + track: Item { + implicitWidth: horizontal ? 200 : 18 + implicitHeight: horizontal ? 18 : 200 + + readonly property bool horizontal: control.orientation === Qt.Horizontal + + x: control.leftPadding + (horizontal ? 0 : (control.availableWidth - width) / 2) + y: control.topPadding + (horizontal ? (control.availableHeight - height) / 2 : 0) + width: horizontal ? control.availableWidth : implicitWidth + height: horizontal ? implicitHeight : control.availableHeight + + scale: horizontal && control.mirrored ? -1 : 1 + + Rectangle { + x: parent.horizontal ? 0 : (parent.width - width) / 2 + y: parent.horizontal ? (parent.height - height) / 2 : 0 + width: parent.horizontal ? parent.width : 2 // SliderTrackThemeHeight + height: !parent.horizontal ? parent.height : 2 // SliderTrackThemeHeight + + color: control.enabled ? control.Universal.baseMediumLowColor : control.Universal.chromeDisabledHighColor + } + + Rectangle { + x: parent.horizontal ? control.first.position * parent.width : 0 + y: parent.horizontal ? (parent.height - height) / 2 : control.second.visualPosition * parent.height + width: parent.horizontal ? control.second.position * parent.width - control.first.position * parent.width : 2 // SliderTrackThemeHeight + height: !parent.horizontal ? control.second.position * parent.height - control.first.position * parent.height : 2 // SliderTrackThemeHeight + + color: control.enabled ? control.Universal.accentColor : control.Universal.chromeDisabledHighColor + } + } + //! [track] +} diff --git a/src/imports/controls/universal/ScrollBar.qml b/src/imports/controls/universal/ScrollBar.qml new file mode 100644 index 00000000..b1bc8f6a --- /dev/null +++ b/src/imports/controls/universal/ScrollBar.qml @@ -0,0 +1,99 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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$ +** +****************************************************************************/ + +import QtQuick 2.6 +import Qt.labs.templates 1.0 as T +import Qt.labs.controls.universal 1.0 + +T.ScrollBar { + id: control + + implicitWidth: Math.max(background ? background.implicitWidth : 0, + handle.implicitWidth + leftPadding + rightPadding) + implicitHeight: Math.max(background ? background.implicitHeight : 0, + handle.implicitHeight + topPadding + bottomPadding) + + // TODO: arrows + + //! [handle] + handle: Rectangle { + implicitWidth: 12 + implicitHeight: 12 + + color: control.pressed ? control.Universal.baseMediumColor : control.Universal.chromeHighColor + visible: control.size < 1.0 + opacity: 0.0 + + readonly property bool horizontal: control.orientation === Qt.Horizontal + x: control.leftPadding + (horizontal ? control.position * control.width : 0) + y: control.topPadding + (horizontal ? 0 : control.position * control.height) + width: horizontal ? control.size * control.availableWidth : implicitWidth + height: horizontal ? implicitHeight : control.size * control.availableHeight + } + //! [handle] + + //! [background] + background: Rectangle { + implicitWidth: 12 + implicitHeight: 12 + + color: control.Universal.chromeLowColor + visible: control.size < 1.0 + opacity: 0.0 + } + //! [background] + + states: [ + State { + name: "active" + when: control.active + } + ] + + transitions: [ + Transition { + to: "active" + NumberAnimation { targets: [handle, background]; property: "opacity"; to: 1.0 } + }, + Transition { + from: "active" + SequentialAnimation { + PauseAnimation { duration: 3000 } + NumberAnimation { targets: [handle, background]; property: "opacity"; to: 0.0 } + } + } + ] +} diff --git a/src/imports/controls/universal/ScrollIndicator.qml b/src/imports/controls/universal/ScrollIndicator.qml new file mode 100644 index 00000000..5787b60a --- /dev/null +++ b/src/imports/controls/universal/ScrollIndicator.qml @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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$ +** +****************************************************************************/ + +import QtQuick 2.6 +import Qt.labs.templates 1.0 as T +import Qt.labs.controls.universal 1.0 + +T.ScrollIndicator { + id: control + + implicitWidth: Math.max(background ? background.implicitWidth : 0, + indicator.implicitWidth + leftPadding + rightPadding) + implicitHeight: Math.max(background ? background.implicitHeight : 0, + indicator.implicitHeight + topPadding + bottomPadding) + + //! [indicator] + indicator: Rectangle { + implicitWidth: 6 + implicitHeight: 6 + + color: control.Universal.baseMediumLowColor + visible: control.size < 1.0 + opacity: 0.0 + + readonly property bool horizontal: control.orientation === Qt.Horizontal + x: control.leftPadding + (horizontal ? control.position * control.width : 0) + y: control.topPadding + (horizontal ? 0 : control.position * control.height) + width: horizontal ? control.size * control.availableWidth : implicitWidth + height: horizontal ? implicitHeight : control.size * control.availableHeight + + states: [ + State { + name: "active" + when: control.active + } + ] + + transitions: [ + Transition { + to: "active" + NumberAnimation { target: indicator; property: "opacity"; to: 1.0 } + }, + Transition { + from: "active" + SequentialAnimation { + PauseAnimation { duration: 5000 } + NumberAnimation { target: indicator; property: "opacity"; to: 0.0 } + } + } + ] + } + //! [indicator] +} diff --git a/src/imports/controls/universal/Slider.qml b/src/imports/controls/universal/Slider.qml new file mode 100644 index 00000000..6a4107e6 --- /dev/null +++ b/src/imports/controls/universal/Slider.qml @@ -0,0 +1,101 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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$ +** +****************************************************************************/ + +import QtQuick 2.6 +import Qt.labs.templates 1.0 as T +import Qt.labs.controls.universal 1.0 + +T.Slider { + id: control + + implicitWidth: Math.max(background ? background.implicitWidth : 0, + Math.max(track ? track.implicitWidth : 0, + handle ? handle.implicitWidth : 0) + leftPadding + rightPadding) + implicitHeight: Math.max(background ? background.implicitHeight : 0, + Math.max(track ? track.implicitHeight : 0, + handle ? handle.implicitHeight : 0) + topPadding + bottomPadding) + + padding: 6 + + //! [handle] + handle: Rectangle { + implicitWidth: horizontal ? 8 : 24 + implicitHeight: horizontal ? 24 : 8 + + readonly property bool horizontal: control.orientation === Qt.Horizontal + + x: control.leftPadding + (horizontal ? control.visualPosition * (control.availableWidth - width) : (control.availableWidth - width) / 2) + y: control.topPadding + (horizontal ? (control.availableHeight - height) / 2 : control.visualPosition * (control.availableHeight - height)) + + radius: 4 + color: control.pressed ? control.Universal.chromeHighColor : control.enabled ? control.Universal.accentColor : control.Universal.chromeDisabledHighColor + } + //! [handle] + + //! [track] + track: Item { + implicitWidth: horizontal ? 200 : 18 + implicitHeight: horizontal ? 18 : 200 + + readonly property bool horizontal: control.orientation === Qt.Horizontal + + x: control.leftPadding + (horizontal ? 0 : (control.availableWidth - width) / 2) + y: control.topPadding + (horizontal ? (control.availableHeight - height) / 2 : 0) + width: horizontal ? control.availableWidth : implicitWidth + height: horizontal ? implicitHeight : control.availableHeight + + scale: horizontal && control.mirrored ? -1 : 1 + + Rectangle { + x: parent.horizontal ? 0 : (parent.width - width) / 2 + y: parent.horizontal ? (parent.height - height) / 2 : 0 + width: parent.horizontal ? parent.width : 2 // SliderTrackThemeHeight + height: !parent.horizontal ? parent.height : 2 // SliderTrackThemeHeight + + color: control.enabled ? control.Universal.baseMediumLowColor : control.Universal.chromeDisabledHighColor + } + + Rectangle { + x: parent.horizontal ? 0 : (parent.width - width) / 2 + y: parent.horizontal ? (parent.height - height) / 2 : control.visualPosition * parent.height + width: parent.horizontal ? control.position * parent.width : 2 // SliderTrackThemeHeight + height: !parent.horizontal ? control.position * parent.height : 2 // SliderTrackThemeHeight + + color: control.enabled ? control.Universal.accentColor : control.Universal.chromeDisabledHighColor + } + } + //! [track] +} diff --git a/src/imports/controls/universal/SpinBox.qml b/src/imports/controls/universal/SpinBox.qml new file mode 100644 index 00000000..97ea6c57 --- /dev/null +++ b/src/imports/controls/universal/SpinBox.qml @@ -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 Controls 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$ +** +****************************************************************************/ + +import QtQuick 2.6 +import Qt.labs.templates 1.0 as T +import Qt.labs.controls.universal 1.0 + +T.SpinBox { + id: control + + implicitWidth: Math.max(background ? background.implicitWidth : 0, + contentItem.implicitWidth + 16 + + (up.indicator ? up.indicator.implicitWidth : 0) + + (down.indicator ? down.indicator.implicitWidth : 0)) + implicitHeight: Math.max(contentItem.implicitHeight + topPadding + bottomPadding, + background ? background.implicitHeight : 0, + up.indicator ? up.indicator.implicitHeight : 0, + down.indicator ? down.indicator.implicitHeight : 0) + + // TextControlThemePadding + 2 (border) + topPadding: 5 + bottomPadding: 7 + leftPadding: 12 + (control.mirrored ? (up.indicator ? up.indicator.width : 0) : (down.indicator ? down.indicator.width : 0)) + rightPadding: 8 + (control.mirrored ? (down.indicator ? down.indicator.width : 0) : (up.indicator ? up.indicator.width : 0)) + + Universal.theme: activeFocus ? Universal.Light : undefined + + //! [validator] + validator: IntValidator { + locale: control.locale.name + bottom: Math.min(control.from, control.to) + top: Math.max(control.from, control.to) + } + //! [validator] + + //! [contentItem] + contentItem: TextInput { + text: control.textFromValue(control.value, control.locale) + + font: control.font + color: !enabled ? control.Universal.chromeDisabledLowColor : + activeFocus ? control.Universal.chromeBlackHighColor : control.Universal.baseHighColor + selectionColor: control.Universal.accentColor + selectedTextColor: control.Universal.chromeWhiteColor + horizontalAlignment: Qt.AlignHCenter + verticalAlignment: TextInput.AlignVCenter + renderType: Text.NativeRendering + + validator: control.validator + inputMethodHints: Qt.ImhFormattedNumbersOnly + } + //! [contentItem] + + //! [up.indicator] + up.indicator: Item { + implicitWidth: 26 + height: parent.height + x: control.mirrored ? 0 : parent.width - width + + Rectangle { + x: 2; y: 2 + width: parent.width - 4 + height: parent.height - 4 + color: !control.up.pressed ? "transparent" : + control.activeFocus ? control.Universal.accentColor + : control.Universal.chromeDisabledLowColor + } + + Image { + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + source: "image://universal/rightarrow/" + (!control.enabled ? control.Universal.chromeDisabledLowColor : + control.activeFocus ? control.Universal.chromeBlackHighColor : control.Universal.baseHighColor) + } + } + //! [up.indicator] + + //! [down.indicator] + down.indicator: Item { + implicitWidth: 26 + height: parent.height + x: control.mirrored ? parent.width - width : 0 + + Rectangle { + x: 2; y: 2 + width: parent.width - 4 + height: parent.height - 4 + color: !control.down.pressed ? "transparent" : + control.activeFocus ? control.Universal.accentColor + : control.Universal.chromeDisabledLowColor + } + + Image { + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + source: "image://universal/leftarrow/" + (!control.enabled ? control.Universal.chromeDisabledLowColor : + control.activeFocus ? control.Universal.chromeBlackHighColor : control.Universal.baseHighColor) + } + } + //! [down.indicator] + + //! [background] + background: Rectangle { + implicitWidth: 60 + 26 // TextControlThemeMinWidth - 4 (border) + implicitHeight: 28 // TextControlThemeMinHeight - 4 (border) + + border.width: 2 // TextControlBorderThemeThickness + border.color: !control.enabled ? control.Universal.baseLowColor : + control.activeFocus ? control.Universal.accentColor : control.Universal.chromeDisabledLowColor + color: control.enabled ? control.Universal.altHighColor : control.Universal.baseLowColor + } + //! [background] +} diff --git a/src/imports/controls/universal/StackView.qml b/src/imports/controls/universal/StackView.qml new file mode 100644 index 00000000..b09359b6 --- /dev/null +++ b/src/imports/controls/universal/StackView.qml @@ -0,0 +1,88 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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$ +** +****************************************************************************/ + +import QtQuick 2.6 +import Qt.labs.templates 1.0 as T +import Qt.labs.controls.universal 1.0 + +T.StackView { + id: root + + //! [popEnter] + popEnter: Transition { + ParallelAnimation { + NumberAnimation { property: "opacity"; from: 0; to: 1; duration: 200; easing.type: Easing.InQuint } + NumberAnimation { property: "x"; from: -root.width / 3; to: 0; duration: 400; easing.type: Easing.OutCubic } + } + } + //! [popEnter] + + //! [popExit] + popExit: Transition { + NumberAnimation { property: "opacity"; from: 1; to: 0; duration: 200; easing.type: Easing.OutQuint } + } + //! [popExit] + + //! [pushEnter] + pushEnter: Transition { + ParallelAnimation { + NumberAnimation { property: "opacity"; from: 0; to: 1; duration: 200; easing.type: Easing.InQuint } + NumberAnimation { property: "x"; from: root.width / 3; to: 0; duration: 400; easing.type: Easing.OutCubic } + } + } + //! [pushEnter] + + //! [pushExit] + pushExit: Transition { + NumberAnimation { property: "opacity"; from: 1; to: 0; duration: 200; easing.type: Easing.OutQuint } + } + //! [pushExit] + + //! [replaceEnter] + replaceEnter: Transition { + ParallelAnimation { + NumberAnimation { property: "opacity"; from: 0; to: 1; duration: 200; easing.type: Easing.InQuint } + NumberAnimation { property: "x"; from: root.width / 3; to: 0; duration: 400; easing.type: Easing.OutCubic } + } + } + //! [replaceEnter] + + //! [replaceExit] + replaceExit: Transition { + NumberAnimation { property: "opacity"; from: 1; to: 0; duration: 200; easing.type: Easing.OutQuint } + } + //! [replaceExit] +} diff --git a/src/imports/controls/universal/Switch.qml b/src/imports/controls/universal/Switch.qml new file mode 100644 index 00000000..8b7c73f3 --- /dev/null +++ b/src/imports/controls/universal/Switch.qml @@ -0,0 +1,109 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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$ +** +****************************************************************************/ + +import QtQuick 2.6 +import Qt.labs.templates 1.0 as T +import Qt.labs.controls.universal 1.0 + +T.Switch { + id: control + + implicitWidth: Math.max(background ? background.implicitWidth : 0, + (label ? label.implicitWidth : 0) + + (indicator ? indicator.implicitWidth : 0) + + (label && indicator ? spacing : 0) + leftPadding + rightPadding) + implicitHeight: Math.max(background ? background.implicitHeight : 0, + Math.max(label ? label.implicitHeight : 0, + indicator ? indicator.implicitHeight : 0) + topPadding + bottomPadding) + baselineOffset: label ? label.y + label.baselineOffset : 0 + + padding: 5 + spacing: 8 + + //! [indicator] + indicator: Rectangle { + implicitWidth: 44 + implicitHeight: 20 + x: text ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) : control.leftPadding + (control.availableWidth - width) / 2 + y: control.topPadding + (control.availableHeight - height) / 2 + + radius: 10 + color: !control.enabled ? "transparent" : + control.pressed ? control.Universal.baseMediumColor : + control.checked ? control.Universal.accentColor : "transparent" + border.color: !control.enabled ? control.Universal.baseLowColor : + control.checked && !control.pressed ? control.Universal.accentColor : control.Universal.baseMediumColor + border.width: 2 + + Rectangle { + width: 10 + height: 10 + radius: 5 + + color: !control.enabled ? control.Universal.baseLowColor : + control.pressed || control.checked ? control.Universal.chromeWhiteColor : control.Universal.baseMediumHighColor + + x: Math.max(5, Math.min(parent.width - width - 5, + control.visualPosition * parent.width - (width / 2))) + y: (parent.height - height) / 2 + + Behavior on x { + enabled: !control.pressed + SmoothedAnimation { velocity: 200 } + } + } + } + //! [indicator] + + //! [label] + label: Text { + x: control.mirrored ? control.leftPadding : (indicator.x + indicator.width + control.spacing) + y: control.topPadding + width: control.availableWidth - indicator.width - control.spacing + height: control.availableHeight + + text: control.text + font: control.font + elide: Text.ElideRight + visible: control.text + horizontalAlignment: Text.AlignLeft + verticalAlignment: Text.AlignVCenter + renderType: Text.NativeRendering + + color: !control.enabled ? control.Universal.baseLowColor : control.Universal.baseHighColor + } + //! [label] +} diff --git a/src/imports/controls/universal/TabBar.qml b/src/imports/controls/universal/TabBar.qml new file mode 100644 index 00000000..1eee3b06 --- /dev/null +++ b/src/imports/controls/universal/TabBar.qml @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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$ +** +****************************************************************************/ + +import QtQuick 2.6 +import Qt.labs.templates 1.0 as T +import Qt.labs.controls.universal 1.0 + +T.TabBar { + id: control + + implicitWidth: Math.max(background ? background.implicitWidth : 0, + contentItem.implicitWidth + leftPadding + rightPadding) + implicitHeight: Math.max(background ? background.implicitHeight : 0, + contentItem.implicitHeight + topPadding + bottomPadding) + + //! [contentItem] + contentItem: PathView { + implicitWidth: 200 + implicitHeight: 48 + + model: control.contentModel + currentIndex: control.currentIndex + + interactive: false + snapMode: PathView.SnapToItem + highlightMoveDuration: 100 + + path: Path { + startX: control.count ? control.availableWidth / control.count / 2 : 0 + startY: control.availableHeight / 2 + PathLine { + x: control.count ? control.availableWidth + (control.availableWidth / control.count / 2) : 0 + y: control.availableHeight / 2 + } + } + } + //! [contentItem] + + //! [background] + background: Rectangle { + implicitWidth: 200 + implicitHeight: 48 + color: control.Universal.altHighColor + } + //! [background] +} diff --git a/src/imports/controls/universal/TabButton.qml b/src/imports/controls/universal/TabButton.qml new file mode 100644 index 00000000..3b9fc60c --- /dev/null +++ b/src/imports/controls/universal/TabButton.qml @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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$ +** +****************************************************************************/ + +import QtQuick 2.6 +import Qt.labs.templates 1.0 as T +import Qt.labs.controls.universal 1.0 + +T.TabButton { + id: control + + implicitWidth: Math.max(background ? background.implicitWidth : 0, + label ? label.implicitWidth + leftPadding + rightPadding : 0) + implicitHeight: Math.max(background ? background.implicitHeight : 0, + label ? label.implicitHeight + topPadding + bottomPadding : 0) + baselineOffset: label ? label.y + label.baselineOffset : 0 + + padding: 12 // PivotItemMargin + + //! [label] + label: Text { + x: control.leftPadding + y: control.topPadding + width: control.availableWidth + height: control.availableHeight + + text: control.text + font: control.font + elide: Text.ElideRight + color: control.checked || control.pressed ? control.Universal.baseHighColor : control.Universal.baseLowColor + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + renderType: Text.NativeRendering + } + //! [label] +} diff --git a/src/imports/controls/universal/TextArea.qml b/src/imports/controls/universal/TextArea.qml new file mode 100644 index 00000000..ec319b86 --- /dev/null +++ b/src/imports/controls/universal/TextArea.qml @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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$ +** +****************************************************************************/ + +import QtQuick 2.6 +import Qt.labs.templates 1.0 as T +import Qt.labs.controls.universal 1.0 + +T.TextArea { + id: control + + implicitWidth: Math.max(contentWidth + leftPadding + rightPadding, + background ? background.implicitWidth : 0, + placeholder.implicitWidth + leftPadding + rightPadding) + implicitHeight: Math.max(contentHeight + topPadding + bottomPadding, + background ? background.implicitHeight : 0, + placeholder.implicitHeight + topPadding + bottomPadding) + + // TextControlThemePadding + 2 (border) + topPadding: 5 + leftPadding: 12 + rightPadding: 8 + bottomPadding: 7 + + Universal.theme: activeFocus ? Universal.Light : undefined + + color: !enabled ? Universal.chromeDisabledLowColor : + activeFocus ? Universal.chromeBlackHighColor : Universal.baseHighColor + selectionColor: Universal.accentColor + selectedTextColor: Universal.chromeWhiteColor + renderType: Text.NativeRendering + + Text { + id: placeholder + x: control.leftPadding + y: control.topPadding + width: control.width - (control.leftPadding + control.rightPadding) + height: control.height - (control.topPadding + control.bottomPadding) + + text: control.placeholderText + font: control.font + color: !control.enabled ? control.Universal.chromeDisabledLowColor : + control.activeFocus ? control.Universal.chromeBlackMediumLowColor : control.Universal.baseMediumColor + visible: !control.length && (!control.activeFocus || control.horizontalAlignment !== Qt.AlignHCenter) + horizontalAlignment: control.horizontalAlignment + verticalAlignment: control.verticalAlignment + renderType: Text.NativeRendering + elide: Text.ElideRight + } + + //! [background] + background: Rectangle { + implicitWidth: 60 // TextControlThemeMinWidth - 4 (border) + implicitHeight: 28 // TextControlThemeMinHeight - 4 (border) + + border.width: 2 // TextControlBorderThemeThickness + border.color: !control.enabled ? control.Universal.baseLowColor : + control.activeFocus ? control.Universal.accentColor : control.Universal.chromeDisabledLowColor + color: control.enabled ? control.Universal.altHighColor : control.Universal.baseLowColor + } + //! [background] +} diff --git a/src/imports/controls/universal/TextField.qml b/src/imports/controls/universal/TextField.qml new file mode 100644 index 00000000..b4e217d2 --- /dev/null +++ b/src/imports/controls/universal/TextField.qml @@ -0,0 +1,95 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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$ +** +****************************************************************************/ + +import QtQuick 2.6 +import Qt.labs.templates 1.0 as T +import Qt.labs.controls.universal 1.0 + +T.TextField { + id: control + + implicitWidth: Math.max(contentWidth + leftPadding + rightPadding, + background ? background.implicitWidth : 0, + placeholder.implicitWidth + leftPadding + rightPadding) + implicitHeight: Math.max(contentHeight + topPadding + bottomPadding, + background ? background.implicitHeight : 0, + placeholder.implicitHeight + topPadding + bottomPadding) + + // TextControlThemePadding + 2 (border) + topPadding: 5 + leftPadding: 12 + rightPadding: 8 + bottomPadding: 7 + + Universal.theme: activeFocus ? Universal.Light : undefined + + color: !enabled ? Universal.chromeDisabledLowColor : + activeFocus ? Universal.chromeBlackHighColor : Universal.baseHighColor + selectionColor: Universal.accentColor + selectedTextColor: Universal.chromeWhiteColor + verticalAlignment: TextInput.AlignVCenter + renderType: Text.NativeRendering + + Text { + id: placeholder + x: control.leftPadding + y: control.topPadding + width: control.width - (control.leftPadding + control.rightPadding) + height: control.height - (control.topPadding + control.bottomPadding) + + text: control.placeholderText + font: control.font + color: !control.enabled ? control.Universal.chromeDisabledLowColor : + control.activeFocus ? control.Universal.chromeBlackMediumLowColor : control.Universal.baseMediumColor + visible: !control.displayText && (!control.activeFocus || control.horizontalAlignment !== Qt.AlignHCenter) + horizontalAlignment: control.horizontalAlignment + verticalAlignment: control.verticalAlignment + renderType: Text.NativeRendering + elide: Text.ElideRight + } + + //! [background] + background: Rectangle { + implicitWidth: 60 // TextControlThemeMinWidth - 4 (border) + implicitHeight: 28 // TextControlThemeMinHeight - 4 (border) + + border.width: 2 // TextControlBorderThemeThickness + border.color: !control.enabled ? control.Universal.baseLowColor : + control.activeFocus ? control.Universal.accentColor : control.Universal.chromeDisabledLowColor + color: control.enabled ? control.Universal.altHighColor : control.Universal.baseLowColor + } + //! [background] +} diff --git a/src/imports/controls/universal/ToolBar.qml b/src/imports/controls/universal/ToolBar.qml new file mode 100644 index 00000000..e83fcc1d --- /dev/null +++ b/src/imports/controls/universal/ToolBar.qml @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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$ +** +****************************************************************************/ + +import QtQuick 2.6 +import Qt.labs.templates 1.0 as T +import Qt.labs.controls.universal 1.0 + +T.ToolBar { + id: control + + implicitWidth: Math.max(background ? background.implicitWidth : 0, contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(background ? background.implicitHeight : 0, contentHeight + topPadding + bottomPadding) + + contentWidth: contentChildren.length === 1 ? contentChildren[0].implicitWidth : 0 + contentHeight: contentChildren.length === 1 ? contentChildren[0].implicitHeight : 0 + + //! [contentItem] + contentItem: Item { } + //! [contentItem] + + //! [background] + background: Rectangle { + implicitHeight: 48 // AppBarThemeCompactHeight + color: control.Universal.chromeMediumColor + } + //! [background] +} diff --git a/src/imports/controls/universal/ToolButton.qml b/src/imports/controls/universal/ToolButton.qml new file mode 100644 index 00000000..6488044b --- /dev/null +++ b/src/imports/controls/universal/ToolButton.qml @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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$ +** +****************************************************************************/ + +import QtQuick 2.6 +import Qt.labs.templates 1.0 as T +import Qt.labs.controls.universal 1.0 + +T.ToolButton { + id: control + + implicitWidth: Math.max(background ? background.implicitWidth : 0, + label ? label.implicitWidth + leftPadding + rightPadding : 0) + implicitHeight: Math.max(background ? background.implicitHeight : 0, + label ? label.implicitHeight + topPadding + bottomPadding : 0) + baselineOffset: label ? label.y + label.baselineOffset : 0 + + padding: 6 + + //! [label] + label: Text { + x: control.leftPadding + y: control.topPadding + width: control.availableWidth + height: control.availableHeight + + text: control.text + font: control.font + color: control.enabled ? control.Universal.baseHighColor : control.Universal.baseLowColor + elide: Text.ElideRight + horizontalAlignment: Text.AlignLeft + verticalAlignment: Text.AlignVCenter + renderType: Text.NativeRendering + } + //! [label] + + //! [background] + background: Rectangle { + implicitWidth: 68 + implicitHeight: 48 // AppBarThemeCompactHeight + + color: control.pressed ? control.Universal.listMediumColor : + control.checkable && control.checked ? control.Universal.accentColor : "transparent" + } + //! [background] +} diff --git a/src/imports/controls/universal/Tumbler.qml b/src/imports/controls/universal/Tumbler.qml new file mode 100644 index 00000000..d327733c --- /dev/null +++ b/src/imports/controls/universal/Tumbler.qml @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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$ +** +****************************************************************************/ + +import QtQuick 2.6 +import Qt.labs.templates 1.0 as T +import Qt.labs.controls.universal 1.0 +import Qt.labs.controls 1.0 + +T.Tumbler { + id: control + + implicitWidth: 60 + implicitHeight: 200 + + //! [delegate] + delegate: Text { + text: modelData + color: !control.enabled ? control.Universal.baseLowColor : control.Universal.baseHighColor + font: control.font + opacity: 0.4 + Math.max(0, 1 - Math.abs(Tumbler.displacement)) * 0.6 + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + renderType: Text.NativeRendering + } + //! [delegate] + + //! [contentItem] + contentItem: PathView { + id: pathView + model: control.model + delegate: control.delegate + clip: true + pathItemCount: control.visibleItemCount + 1 + preferredHighlightBegin: 0.5 + preferredHighlightEnd: 0.5 + dragMargin: width / 2 + + path: Path { + startX: pathView.width / 2 + startY: -pathView.delegateHeight / 2 + PathLine { + x: pathView.width / 2 + y: pathView.pathItemCount * pathView.delegateHeight - pathView.delegateHeight / 2 + } + } + + property real delegateHeight: control.availableHeight / control.visibleItemCount + } + //! [contentItem] +} diff --git a/src/imports/controls/universal/images/checkmark.png b/src/imports/controls/universal/images/checkmark.png Binary files differnew file mode 100644 index 00000000..4397f3b4 --- /dev/null +++ b/src/imports/controls/universal/images/checkmark.png diff --git a/src/imports/controls/universal/images/checkmark@2x.png b/src/imports/controls/universal/images/checkmark@2x.png Binary files differnew file mode 100644 index 00000000..1e3a41fc --- /dev/null +++ b/src/imports/controls/universal/images/checkmark@2x.png diff --git a/src/imports/controls/universal/images/checkmark@3x.png b/src/imports/controls/universal/images/checkmark@3x.png Binary files differnew file mode 100644 index 00000000..d69ebb2e --- /dev/null +++ b/src/imports/controls/universal/images/checkmark@3x.png diff --git a/src/imports/controls/universal/images/checkmark@4x.png b/src/imports/controls/universal/images/checkmark@4x.png Binary files differnew file mode 100644 index 00000000..0837c6a5 --- /dev/null +++ b/src/imports/controls/universal/images/checkmark@4x.png diff --git a/src/imports/controls/universal/images/leftarrow.png b/src/imports/controls/universal/images/leftarrow.png Binary files differnew file mode 100644 index 00000000..2646aafc --- /dev/null +++ b/src/imports/controls/universal/images/leftarrow.png diff --git a/src/imports/controls/universal/images/leftarrow@2x.png b/src/imports/controls/universal/images/leftarrow@2x.png Binary files differnew file mode 100644 index 00000000..500396f7 --- /dev/null +++ b/src/imports/controls/universal/images/leftarrow@2x.png diff --git a/src/imports/controls/universal/images/leftarrow@3x.png b/src/imports/controls/universal/images/leftarrow@3x.png Binary files differnew file mode 100644 index 00000000..7ae2cafd --- /dev/null +++ b/src/imports/controls/universal/images/leftarrow@3x.png diff --git a/src/imports/controls/universal/images/leftarrow@4x.png b/src/imports/controls/universal/images/leftarrow@4x.png Binary files differnew file mode 100644 index 00000000..ade9df95 --- /dev/null +++ b/src/imports/controls/universal/images/leftarrow@4x.png diff --git a/src/imports/controls/universal/images/rightarrow.png b/src/imports/controls/universal/images/rightarrow.png Binary files differnew file mode 100644 index 00000000..2e730d46 --- /dev/null +++ b/src/imports/controls/universal/images/rightarrow.png diff --git a/src/imports/controls/universal/images/rightarrow@2x.png b/src/imports/controls/universal/images/rightarrow@2x.png Binary files differnew file mode 100644 index 00000000..a089d030 --- /dev/null +++ b/src/imports/controls/universal/images/rightarrow@2x.png diff --git a/src/imports/controls/universal/images/rightarrow@3x.png b/src/imports/controls/universal/images/rightarrow@3x.png Binary files differnew file mode 100644 index 00000000..2e8921a9 --- /dev/null +++ b/src/imports/controls/universal/images/rightarrow@3x.png diff --git a/src/imports/controls/universal/images/rightarrow@4x.png b/src/imports/controls/universal/images/rightarrow@4x.png Binary files differnew file mode 100644 index 00000000..9ecb8e88 --- /dev/null +++ b/src/imports/controls/universal/images/rightarrow@4x.png diff --git a/src/imports/controls/universal/qmldir b/src/imports/controls/universal/qmldir new file mode 100644 index 00000000..ebf841fb --- /dev/null +++ b/src/imports/controls/universal/qmldir @@ -0,0 +1,4 @@ +module Qt.labs.controls.universal +plugin qtlabsuniversalstyleplugin +classname QtLabsUniversalStylePlugin +depends Qt.labs.controls 1.0 diff --git a/src/imports/controls/universal/qquickuniversalimageprovider.cpp b/src/imports/controls/universal/qquickuniversalimageprovider.cpp new file mode 100644 index 00000000..8e63e6d8 --- /dev/null +++ b/src/imports/controls/universal/qquickuniversalimageprovider.cpp @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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 "qquickuniversalimageprovider_p.h" + +#include <QtCore/qdebug.h> +#include <QtGui/qpainter.h> +#include <QtGui/qguiapplication.h> +#include <QtGui/qscreen.h> +#include <QtGui/qicon.h> + +QT_BEGIN_NAMESPACE + +QQuickUniversalImageProvider::QQuickUniversalImageProvider() : QQuickImageProvider(Image) +{ +} + +QImage QQuickUniversalImageProvider::requestImage(const QString &id, QSize *size, const QSize &requestedSize) +{ + Q_UNUSED(requestedSize); + + int sep = id.indexOf(QLatin1Char('/')); + QString name = id.left(sep); + QString color = id.mid(sep + 1); + qreal dpr = qApp->primaryScreen()->devicePixelRatio(); + QString file = qt_findAtNxFile(QStringLiteral(":/org.qt-project/imports/Qt/labs/controls/universal/images/") + name + QStringLiteral(".png"), dpr); + + QImage image(file); + if (image.isNull()) { + qWarning() << "QQuickUniversalImageProvider: unknown id:" << id; + return QImage(); + } + + if (size) + *size = image.size(); + + if (!color.isEmpty()) { + QPainter painter(&image); + painter.setCompositionMode(QPainter::CompositionMode_SourceIn); + painter.fillRect(image.rect(), QColor(color)); + } + + return image; +} + +QT_END_NAMESPACE diff --git a/src/imports/controls/universal/qquickuniversalimageprovider_p.h b/src/imports/controls/universal/qquickuniversalimageprovider_p.h new file mode 100644 index 00000000..374d842d --- /dev/null +++ b/src/imports/controls/universal/qquickuniversalimageprovider_p.h @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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 QQUICKUNIVERSALIMAGEPROVIDER_P_H +#define QQUICKUNIVERSALIMAGEPROVIDER_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuick/qquickimageprovider.h> + +QT_BEGIN_NAMESPACE + +class QQuickUniversalImageProvider : public QQuickImageProvider +{ +public: + QQuickUniversalImageProvider(); + + QImage requestImage(const QString &id, QSize *size, const QSize &requestedSize) Q_DECL_OVERRIDE; +}; + +Q_DECLARE_TYPEINFO(QQuickUniversalImageProvider, Q_COMPLEX_TYPE); + +QT_END_NAMESPACE + +#endif // QQUICKUNIVERSALIMAGEPROVIDER_P_H diff --git a/src/imports/controls/universal/qquickuniversalprogressring.cpp b/src/imports/controls/universal/qquickuniversalprogressring.cpp new file mode 100644 index 00000000..2fe66047 --- /dev/null +++ b/src/imports/controls/universal/qquickuniversalprogressring.cpp @@ -0,0 +1,269 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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 "qquickuniversalprogressring_p.h" + +#include <QtCore/qmath.h> +#include <QtCore/qeasingcurve.h> +#include <QtQuick/private/qquickitem_p.h> +#include <QtQuick/private/qquickanimatorjob_p.h> +#include <QtQuick/private/qsgadaptationlayer_p.h> + +QT_BEGIN_NAMESPACE + +static const int PhaseCount = 6; +static const int Interval = 167; +static const int TotalDuration = 4052; + +class QQuickUniversalProgressRingAnimatorJob : public QQuickAnimatorJob +{ +public: + QQuickUniversalProgressRingAnimatorJob(); + + void initialize(QQuickAnimatorController *controller) Q_DECL_OVERRIDE; + void updateCurrentTime(int time) Q_DECL_OVERRIDE; + void writeBack() Q_DECL_OVERRIDE; + void nodeWasDestroyed() Q_DECL_OVERRIDE; + void afterNodeSync() Q_DECL_OVERRIDE; + +private: + struct Phase { + Phase() : duration(0), from(0), to(0), curve(QEasingCurve::Linear) { } + Phase(int d, qreal f, qreal t, QEasingCurve::Type c) : duration(d), from(f), to(t), curve(c) { } + int duration; + qreal from; + qreal to; + QEasingCurve curve; + }; + + QSGNode *m_node; + Phase m_phases[PhaseCount]; +}; + +QQuickUniversalProgressRingAnimatorJob::QQuickUniversalProgressRingAnimatorJob() : m_node(Q_NULLPTR) +{ + m_phases[0] = Phase(433, -110, 10, QEasingCurve::BezierSpline); + m_phases[1] = Phase(767, 10, 93, QEasingCurve::Linear ); + m_phases[2] = Phase(417, 93, 205, QEasingCurve::BezierSpline); + m_phases[3] = Phase(400, 205, 357, QEasingCurve::BezierSpline); + m_phases[4] = Phase(766, 357, 439, QEasingCurve::Linear ); + m_phases[5] = Phase(434, 439, 585, QEasingCurve::BezierSpline); + + m_phases[0].curve.addCubicBezierSegment(QPointF(0.02, 0.33), QPointF(0.38, 0.77), QPointF(1.00, 1.00)); + m_phases[2].curve.addCubicBezierSegment(QPointF(0.57, 0.17), QPointF(0.95, 0.75), QPointF(1.00, 1.00)); + m_phases[3].curve.addCubicBezierSegment(QPointF(0.00, 0.19), QPointF(0.07, 0.72), QPointF(1.00, 1.00)); + m_phases[5].curve.addCubicBezierSegment(QPointF(0.00, 0.00), QPointF(0.95, 0.37), QPointF(1.00, 1.00)); +} + +void QQuickUniversalProgressRingAnimatorJob::initialize(QQuickAnimatorController *controller) +{ + QQuickAnimatorJob::initialize(controller); + m_node = QQuickItemPrivate::get(m_target)->childContainerNode(); +} + +void QQuickUniversalProgressRingAnimatorJob::updateCurrentTime(int time) +{ + if (!m_node) + return; + + QSGNode *containerNode = m_node->firstChild(); + Q_ASSERT(!containerNode || containerNode->type() == QSGNode::TransformNodeType); + if (!containerNode) + return; + + int nodeIndex = 0; + int count = containerNode->childCount(); + QSGTransformNode *transformNode = static_cast<QSGTransformNode *>(containerNode->firstChild()); + while (transformNode) { + Q_ASSERT(transformNode->type() == QSGNode::TransformNodeType); + + QSGOpacityNode *opacityNode = static_cast<QSGOpacityNode *>(transformNode->firstChild()); + Q_ASSERT(opacityNode->type() == QSGNode::OpacityNodeType); + + int begin = nodeIndex * Interval; + int end = TotalDuration - (PhaseCount - nodeIndex - 1) * Interval; + + bool visible = time >= begin && time <= end; + opacityNode->setOpacity(visible ? 1.0 : 0.0); + + if (visible) { + int phaseIndex, remain = time, elapsed = 0; + for (phaseIndex = 0; phaseIndex < PhaseCount; ++phaseIndex) { + if (remain <= m_phases[phaseIndex].duration + begin) + break; + remain -= m_phases[phaseIndex].duration; + elapsed += m_phases[phaseIndex].duration; + } + + const Phase &phase = m_phases[phaseIndex]; + + qreal from = phase.from - nodeIndex * count; + qreal to = phase.to - nodeIndex * count; + qreal pos = time - elapsed - begin; + + qreal value = phase.curve.valueForProgress(pos / phase.duration); + qreal rotation = from + (to - from) * value; + + QMatrix4x4 matrix; + matrix.rotate(rotation, 0, 0, 1); + transformNode->setMatrix(matrix); + } + + transformNode = static_cast<QSGTransformNode *>(transformNode->nextSibling()); + ++nodeIndex; + } +} + +void QQuickUniversalProgressRingAnimatorJob::writeBack() +{ +} + +void QQuickUniversalProgressRingAnimatorJob::nodeWasDestroyed() +{ + m_node = Q_NULLPTR; +} + +void QQuickUniversalProgressRingAnimatorJob::afterNodeSync() +{ + m_node = QQuickItemPrivate::get(m_target)->childContainerNode(); +} + +QQuickUniversalProgressRingAnimator::QQuickUniversalProgressRingAnimator(QObject *parent) + : QQuickAnimator(parent) +{ + setDuration(TotalDuration); + setLoops(QQuickAnimator::Infinite); +} + +QString QQuickUniversalProgressRingAnimator::propertyName() const +{ + return QString(); +} + +QQuickAnimatorJob *QQuickUniversalProgressRingAnimator::createJob() const +{ + return new QQuickUniversalProgressRingAnimatorJob; +} + +QQuickUniversalProgressRing::QQuickUniversalProgressRing(QQuickItem *parent) + : QQuickItem(parent), m_count(5), m_color(Qt::black) +{ + setFlag(ItemHasContents); +} + +int QQuickUniversalProgressRing::count() const +{ + return m_count; +} + +void QQuickUniversalProgressRing::setCount(int count) +{ + if (m_count != count) { + m_count = count; + update(); + emit countChanged(); + } +} + +QColor QQuickUniversalProgressRing::color() const +{ + return m_color; +} + +void QQuickUniversalProgressRing::setColor(const QColor &color) +{ + if (m_color != color) { + m_color = color; + update(); + emit colorChanged(); + } +} + +QSGNode *QQuickUniversalProgressRing::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) +{ + QQuickItemPrivate *d = QQuickItemPrivate::get(this); + + if (!oldNode) + oldNode = new QSGTransformNode; + Q_ASSERT(oldNode->type() == QSGNode::TransformNodeType); + + QMatrix4x4 matrix; + matrix.translate(width() / 2, height() / 2); + static_cast<QSGTransformNode *>(oldNode)->setMatrix(matrix); + + qreal size = qMin(width(), height()); + qreal diameter = size / 10.0; + qreal radius = diameter / 2; + qreal offset = (size - diameter * 2) / M_PI; + + QSGNode *transformNode = oldNode->firstChild(); + for (int i = 0; i < m_count; ++i) { + if (!transformNode) { + transformNode = new QSGTransformNode; + oldNode->appendChildNode(transformNode); + + QSGOpacityNode *opacityNode = new QSGOpacityNode; + transformNode->appendChildNode(opacityNode); + + QSGRectangleNode *rectNode = d->sceneGraphContext()->createRectangleNode(); + rectNode->setAntialiasing(true); + opacityNode->appendChildNode(rectNode); + } + + QSGNode *opacityNode = transformNode->firstChild(); + Q_ASSERT(opacityNode->type() == QSGNode::OpacityNodeType); + + QSGRectangleNode *rectNode = static_cast<QSGRectangleNode *>(opacityNode->firstChild()); + Q_ASSERT(rectNode->type() == QSGNode::GeometryNodeType); + + rectNode->setRect(QRectF(offset, offset, diameter, diameter)); + rectNode->setColor(m_color); + rectNode->setRadius(radius); + rectNode->update(); + + transformNode = transformNode->nextSibling(); + } + + while (transformNode) { + QSGNode *nextSibling = transformNode->nextSibling(); + delete transformNode; + transformNode = nextSibling; + } + + return oldNode; +} + +QT_END_NAMESPACE diff --git a/src/imports/controls/universal/qquickuniversalprogressring_p.h b/src/imports/controls/universal/qquickuniversalprogressring_p.h new file mode 100644 index 00000000..f8ed212c --- /dev/null +++ b/src/imports/controls/universal/qquickuniversalprogressring_p.h @@ -0,0 +1,100 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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 QQUICKUNIVERSALPROGRESSRING_P_H +#define QQUICKUNIVERSALPROGRESSRING_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuick/qquickitem.h> +#include <QtQuick/private/qquickanimator_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickUniversalProgressRing : public QQuickItem +{ + Q_OBJECT + Q_PROPERTY(int count READ count WRITE setCount NOTIFY countChanged FINAL) + Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged FINAL) + +public: + QQuickUniversalProgressRing(QQuickItem *parent = Q_NULLPTR); + + int count() const; + void setCount(int count); + + QColor color() const; + void setColor(const QColor &color); + +Q_SIGNALS: + void countChanged(); + void colorChanged(); + +protected: + QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) Q_DECL_OVERRIDE; + +private: + int m_count; + QColor m_color; +}; + +class QQuickUniversalProgressRingAnimator : public QQuickAnimator +{ + Q_OBJECT + +public: + QQuickUniversalProgressRingAnimator(QObject *parent = Q_NULLPTR); + +protected: + QString propertyName() const Q_DECL_OVERRIDE; + QQuickAnimatorJob *createJob() const Q_DECL_OVERRIDE; +}; + +Q_DECLARE_TYPEINFO(QQuickUniversalProgressRing, Q_COMPLEX_TYPE); +Q_DECLARE_TYPEINFO(QQuickUniversalProgressRingAnimator, Q_COMPLEX_TYPE); + +QT_END_NAMESPACE + +#endif // QQUICKUNIVERSALPROGRESSRING_P_H diff --git a/src/imports/controls/universal/qquickuniversalprogressstrip.cpp b/src/imports/controls/universal/qquickuniversalprogressstrip.cpp new file mode 100644 index 00000000..39ce1b5c --- /dev/null +++ b/src/imports/controls/universal/qquickuniversalprogressstrip.cpp @@ -0,0 +1,304 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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 "qquickuniversalprogressstrip_p.h" + +#include <QtCore/qmath.h> +#include <QtCore/qeasingcurve.h> +#include <QtQuick/qsgsimplerectnode.h> +#include <QtQuick/private/qquickitem_p.h> +#include <QtQuick/private/qquickanimatorjob_p.h> +#include <QtQuick/private/qsgadaptationlayer_p.h> + +QT_BEGIN_NAMESPACE + +static const int PhaseCount = 4; +static const int EllipseCount = 5; +static const int Interval = 167; +static const int TotalDuration = 3917; +static const int VisibleDuration = 3000; +static const qreal EllipseDiameter = 4; +static const qreal EllipseOffset = 4; +static const qreal ContainerAnimationStartPosition = -34; // absolute +static const qreal ContainerAnimationEndPosition = 0.435222; // relative +static const qreal EllipseAnimationWellPosition = 0.333333333333333; // relative +static const qreal EllipseAnimationEndPosition = 0.666666666666667; // relative + +class QQuickUniversalProgressStripAnimatorJob : public QQuickAnimatorJob +{ +public: + QQuickUniversalProgressStripAnimatorJob(); + + void initialize(QQuickAnimatorController *controller) Q_DECL_OVERRIDE; + void updateCurrentTime(int time) Q_DECL_OVERRIDE; + void writeBack() Q_DECL_OVERRIDE; + void nodeWasDestroyed() Q_DECL_OVERRIDE; + void afterNodeSync() Q_DECL_OVERRIDE; + +private: + struct Phase { + Phase() : duration(0), from(0), to(0) { } + Phase(int d, qreal f, qreal t) : duration(d), from(f), to(t) { } + int duration; + qreal from; + qreal to; + }; + + QSGNode *m_node; + Phase m_borderPhases[PhaseCount]; + Phase m_ellipsePhases[PhaseCount]; +}; + +QQuickUniversalProgressStripAnimatorJob::QQuickUniversalProgressStripAnimatorJob() : m_node(Q_NULLPTR) +{ + m_borderPhases[0] = Phase( 500, -50, 0); + m_borderPhases[1] = Phase(1500, 0, 0); + m_borderPhases[2] = Phase(1000, 0, 100); + m_borderPhases[3] = Phase( 917, 100, 100); + + m_ellipsePhases[0] = Phase(1000, 0, EllipseAnimationWellPosition); + m_ellipsePhases[1] = Phase(1000, EllipseAnimationWellPosition, EllipseAnimationWellPosition); + m_ellipsePhases[2] = Phase(1000, EllipseAnimationWellPosition, EllipseAnimationEndPosition); + m_ellipsePhases[3] = Phase(1000, EllipseAnimationWellPosition, EllipseAnimationEndPosition); +} + +void QQuickUniversalProgressStripAnimatorJob::initialize(QQuickAnimatorController *controller) +{ + QQuickAnimatorJob::initialize(controller); + m_node = QQuickItemPrivate::get(m_target)->childContainerNode(); +} + +void QQuickUniversalProgressStripAnimatorJob::updateCurrentTime(int time) +{ + if (!m_node) + return; + + QSGSimpleRectNode *geometryNode = static_cast<QSGSimpleRectNode *>(m_node->firstChild()); + Q_ASSERT(!geometryNode || geometryNode->type() == QSGNode::GeometryNodeType); + if (!geometryNode) + return; + + QSGTransformNode *gridNode = static_cast<QSGTransformNode *>(geometryNode->firstChild()); + Q_ASSERT(!gridNode || gridNode->type() == QSGNode::TransformNodeType); + if (!gridNode) + return; + + qreal width = geometryNode->rect().width(); + { + qreal from = ContainerAnimationStartPosition; + qreal to = from + ContainerAnimationEndPosition * width; + qreal progress = static_cast<qreal>(time) / TotalDuration; + qreal dx = from + (to - from) * progress; + + QMatrix4x4 matrix; + matrix.translate(dx, 0); + gridNode->setMatrix(matrix); + } + + int nodeIndex = 0; + QSGTransformNode *borderNode = static_cast<QSGTransformNode *>(gridNode->firstChild()); + while (borderNode) { + Q_ASSERT(borderNode->type() == QSGNode::TransformNodeType); + + QSGTransformNode *ellipseNode = static_cast<QSGTransformNode *>(borderNode->firstChild()); + Q_ASSERT(ellipseNode->type() == QSGNode::TransformNodeType); + + QSGOpacityNode *opacityNode = static_cast<QSGOpacityNode *>(ellipseNode->firstChild()); + Q_ASSERT(opacityNode->type() == QSGNode::OpacityNodeType); + + int begin = nodeIndex * Interval; + int end = VisibleDuration + nodeIndex * Interval; + + bool visible = time >= begin && time <= end; + opacityNode->setOpacity(visible ? 1.0 : 0.0); + + if (visible) { + { + int phaseIndex, remain = time, elapsed = 0; + for (phaseIndex = 0; phaseIndex < PhaseCount; ++phaseIndex) { + if (remain <= m_borderPhases[phaseIndex].duration + begin) + break; + remain -= m_borderPhases[phaseIndex].duration; + elapsed += m_borderPhases[phaseIndex].duration; + } + + const Phase &phase = m_borderPhases[phaseIndex]; + + qreal pos = time - elapsed - begin; + qreal progress = pos / phase.duration; + qreal dx = phase.from + (phase.to - phase.from) * progress; + + QMatrix4x4 matrix; + matrix.translate(dx, 0); + borderNode->setMatrix(matrix); + } + + { + QEasingCurve curve(QEasingCurve::BezierSpline); + curve.addCubicBezierSegment(QPointF(0.4, 0.0), QPointF(0.6, 1.0), QPointF(1.0, 1.0)); + + int phaseIndex, remain = time, elapsed = 0; + for (phaseIndex = 0; phaseIndex < PhaseCount; ++phaseIndex) { + if (remain <= m_ellipsePhases[phaseIndex].duration + begin) + break; + remain -= m_ellipsePhases[phaseIndex].duration; + elapsed += m_ellipsePhases[phaseIndex].duration; + } + + const Phase &phase = m_ellipsePhases[phaseIndex]; + + qreal from = phase.from * width; + qreal to = phase.to * width; + qreal pos = time - elapsed - begin; + qreal progress = curve.valueForProgress(pos / phase.duration); + qreal dx = from + (to - from) * progress; + + QMatrix4x4 matrix; + matrix.translate(dx, 0); + ellipseNode->setMatrix(matrix); + } + } + + borderNode = static_cast<QSGTransformNode *>(borderNode->nextSibling()); + ++nodeIndex; + } +} + +void QQuickUniversalProgressStripAnimatorJob::writeBack() +{ +} + +void QQuickUniversalProgressStripAnimatorJob::nodeWasDestroyed() +{ + m_node = Q_NULLPTR; +} + +void QQuickUniversalProgressStripAnimatorJob::afterNodeSync() +{ + m_node = QQuickItemPrivate::get(m_target)->childContainerNode(); +} + +QQuickUniversalProgressStripAnimator::QQuickUniversalProgressStripAnimator(QObject *parent) + : QQuickAnimator(parent) +{ + setDuration(TotalDuration); + setLoops(QQuickAnimator::Infinite); +} + +QString QQuickUniversalProgressStripAnimator::propertyName() const +{ + return QString(); +} + +QQuickAnimatorJob *QQuickUniversalProgressStripAnimator::createJob() const +{ + return new QQuickUniversalProgressStripAnimatorJob; +} + +QQuickUniversalProgressStrip::QQuickUniversalProgressStrip(QQuickItem *parent) + : QQuickItem(parent), m_color(Qt::black) +{ + setFlag(ItemHasContents); +} + +QColor QQuickUniversalProgressStrip::color() const +{ + return m_color; +} + +void QQuickUniversalProgressStrip::setColor(const QColor &color) +{ + if (m_color != color) { + m_color = color; + update(); + emit colorChanged(); + } +} + +QSGNode *QQuickUniversalProgressStrip::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) +{ + QQuickItemPrivate *d = QQuickItemPrivate::get(this); + + if (!oldNode) + oldNode = new QSGSimpleRectNode(boundingRect(), Qt::transparent); + static_cast<QSGSimpleRectNode *>(oldNode)->setRect(boundingRect()); + + QSGTransformNode *gridNode = static_cast<QSGTransformNode *>(oldNode->firstChild()); + if (!gridNode) { + gridNode = new QSGTransformNode; + oldNode->appendChildNode(gridNode); + } + Q_ASSERT(gridNode->type() == QSGNode::TransformNodeType); + + QSGNode *borderNode = gridNode->firstChild(); + for (int i = 0; i < EllipseCount; ++i) { + if (!borderNode) { + borderNode = new QSGTransformNode; + gridNode->appendChildNode(borderNode); + + QSGTransformNode *ellipseNode = new QSGTransformNode; + borderNode->appendChildNode(ellipseNode); + + QSGOpacityNode *opacityNode = new QSGOpacityNode; + ellipseNode->appendChildNode(opacityNode); + + QSGRectangleNode *rectNode = d->sceneGraphContext()->createRectangleNode(); + rectNode->setAntialiasing(true); + rectNode->setRadius(EllipseDiameter / 2); + opacityNode->appendChildNode(rectNode); + } + Q_ASSERT(borderNode->type() == QSGNode::TransformNodeType); + + QSGNode *ellipseNode = borderNode->firstChild(); + Q_ASSERT(ellipseNode->type() == QSGNode::TransformNodeType); + + QSGNode *opacityNode = ellipseNode->firstChild(); + Q_ASSERT(opacityNode->type() == QSGNode::OpacityNodeType); + + QSGRectangleNode *rectNode = static_cast<QSGRectangleNode *>(opacityNode->firstChild()); + Q_ASSERT(rectNode->type() == QSGNode::GeometryNodeType); + + rectNode->setRect(QRectF((EllipseCount - i - 1) * (EllipseDiameter + EllipseOffset), (height() - EllipseDiameter) / 2, EllipseDiameter, EllipseDiameter)); + rectNode->setColor(m_color); + rectNode->update(); + + borderNode = borderNode->nextSibling(); + } + + return oldNode; +} + +QT_END_NAMESPACE diff --git a/src/imports/controls/universal/qquickuniversalprogressstrip_p.h b/src/imports/controls/universal/qquickuniversalprogressstrip_p.h new file mode 100644 index 00000000..f7c063b6 --- /dev/null +++ b/src/imports/controls/universal/qquickuniversalprogressstrip_p.h @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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 QQUICKUNIVERSALPROGRESSSTRIP_P_H +#define QQUICKUNIVERSALPROGRESSSTRIP_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuick/qquickitem.h> +#include <QtQuick/private/qquickanimator_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickUniversalProgressStrip : public QQuickItem +{ + Q_OBJECT + Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged FINAL) + +public: + QQuickUniversalProgressStrip(QQuickItem *parent = Q_NULLPTR); + + QColor color() const; + void setColor(const QColor &color); + +Q_SIGNALS: + void colorChanged(); + +protected: + QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) Q_DECL_OVERRIDE; + +private: + QColor m_color; +}; + +class QQuickUniversalProgressStripAnimator : public QQuickAnimator +{ + Q_OBJECT + +public: + QQuickUniversalProgressStripAnimator(QObject *parent = Q_NULLPTR); + +protected: + QString propertyName() const Q_DECL_OVERRIDE; + QQuickAnimatorJob *createJob() const Q_DECL_OVERRIDE; +}; + +Q_DECLARE_TYPEINFO(QQuickUniversalProgressStrip, Q_COMPLEX_TYPE); +Q_DECLARE_TYPEINFO(QQuickUniversalProgressStripAnimator, Q_COMPLEX_TYPE); + +QT_END_NAMESPACE + +#endif // QQUICKUNIVERSALPROGRESSSTRIP_P_H diff --git a/src/imports/controls/universal/qquickuniversalstyle.cpp b/src/imports/controls/universal/qquickuniversalstyle.cpp new file mode 100644 index 00000000..f2bfd70d --- /dev/null +++ b/src/imports/controls/universal/qquickuniversalstyle.cpp @@ -0,0 +1,377 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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 "qquickuniversalstyle_p.h" + +#include <QtCore/qdebug.h> +#include <QtLabsControls/private/qquickstyle_p.h> + +QT_BEGIN_NAMESPACE + +static const QQuickUniversalStyle::Theme DefaultTheme = QQuickUniversalStyle::Light; +static const QQuickUniversalStyle::Accent DefaultAccent = QQuickUniversalStyle::Cobalt; + +static QColor qquickuniversal_light_color(QQuickUniversalStyle::SystemColor role) +{ + static const QRgb colors[] = { + 0xFFFFFFFF, // SystemAltHighColor + 0x33FFFFFF, // SystemAltLowColor + 0x99FFFFFF, // SystemAltMediumColor + 0xCCFFFFFF, // SystemAltMediumHighColor + 0x66FFFFFF, // SystemAltMediumLowColor + 0xFF000000, // SystemBaseHighColor + 0x33000000, // SystemBaseLowColor + 0x99000000, // SystemBaseMediumColor + 0xCC000000, // SystemBaseMediumHighColor + 0x66000000, // SystemBaseMediumLowColor + 0xFF171717, // SystemChromeAltLowColor + 0xFF000000, // SystemChromeBlackHighColor + 0x33000000, // SystemChromeBlackLowColor + 0x66000000, // SystemChromeBlackMediumLowColor + 0xCC000000, // SystemChromeBlackMediumColor + 0xFFCCCCCC, // SystemChromeDisabledHighColor + 0xFF7A7A7A, // SystemChromeDisabledLowColor + 0xFFCCCCCC, // SystemChromeHighColor + 0xFFF2F2F2, // SystemChromeLowColor + 0xFFE6E6E6, // SystemChromeMediumColor + 0xFFF2F2F2, // SystemChromeMediumLowColor + 0xFFFFFFFF, // SystemChromeWhiteColor + 0x19000000, // SystemListLowColor + 0x33000000 // SystemListMediumColor + }; + return QColor::fromRgba(colors[role]); +} + +static QColor qquickuniversal_dark_color(QQuickUniversalStyle::SystemColor role) +{ + static const QRgb colors[] = { + 0xFF000000, // SystemAltHighColor + 0x33000000, // SystemAltLowColor + 0x99000000, // SystemAltMediumColor + 0xCC000000, // SystemAltMediumHighColor + 0x66000000, // SystemAltMediumLowColor + 0xFFFFFFFF, // SystemBaseHighColor + 0x33FFFFFF, // SystemBaseLowColor + 0x99FFFFFF, // SystemBaseMediumColor + 0xCCFFFFFF, // SystemBaseMediumHighColor + 0x66FFFFFF, // SystemBaseMediumLowColor + 0xFFF2F2F2, // SystemChromeAltLowColor + 0xFF000000, // SystemChromeBlackHighColor + 0x33000000, // SystemChromeBlackLowColor + 0x66000000, // SystemChromeBlackMediumLowColor + 0xCC000000, // SystemChromeBlackMediumColor + 0xFF333333, // SystemChromeDisabledHighColor + 0xFF858585, // SystemChromeDisabledLowColor + 0xFF767676, // SystemChromeHighColor + 0xFF171717, // SystemChromeLowColor + 0xFF1F1F1F, // SystemChromeMediumColor + 0xFF2B2B2B, // SystemChromeMediumLowColor + 0xFFFFFFFF, // SystemChromeWhiteColor + 0x19FFFFFF, // SystemListLowColor + 0x33FFFFFF // SystemListMediumColor + }; + return QColor::fromRgba(colors[role]); +} + +static QColor qquickuniversal_accent_color(QQuickUniversalStyle::Accent accent) +{ + static const QRgb colors[] = { + 0xA4C400, // Lime + 0x60A917, // Green + 0x008A00, // Emerald + 0x00ABA9, // Teal + 0x1BA1E2, // Cyan + 0x3E65FF, // Cobalt + 0x6A00FF, // Indigo + 0xAA00FF, // Violet + 0xF472D0, // Pink + 0xD80073, // Magenta + 0xA20025, // Crimson + 0xE51400, // Red + 0xFA6800, // Orange + 0xF0A30A, // Amber + 0xE3C800, // Yellow + 0x825A2C, // Brown + 0x6D8764, // Olive + 0x647687, // Steel + 0x76608A, // Mauve + 0x87794E // Taupe + }; + return colors[accent]; +} + +QQuickUniversalStyle::QQuickUniversalStyle(QObject *parent) : QQuickStyle(parent), + m_hasTheme(false), m_hasAccent(false), m_theme(DefaultTheme), m_accent(DefaultAccent) +{ + init(); // TODO: lazy init? +} + +QQuickUniversalStyle *QQuickUniversalStyle::qmlAttachedProperties(QObject *object) +{ + return new QQuickUniversalStyle(object); +} + +QQuickUniversalStyle::Theme QQuickUniversalStyle::theme() const +{ + return m_theme; +} + +void QQuickUniversalStyle::setTheme(Theme theme) +{ + m_hasTheme = true; + if (m_theme != theme) { + m_theme = theme; + propagateTheme(); + emit themeChanged(); + emit paletteChanged(); + } +} + +void QQuickUniversalStyle::inheritTheme(Theme theme) +{ + if (!m_hasTheme && m_theme != theme) { + m_theme = theme; + propagateTheme(); + emit themeChanged(); + emit paletteChanged(); + } +} + +void QQuickUniversalStyle::propagateTheme() +{ + foreach (QQuickStyle *child, childStyles()) { + QQuickUniversalStyle *universal = qobject_cast<QQuickUniversalStyle *>(child); + if (universal) + universal->inheritTheme(m_theme); + } +} + +void QQuickUniversalStyle::resetTheme() +{ + if (m_hasTheme) { + m_hasTheme = false; + QQuickUniversalStyle *universal = qobject_cast<QQuickUniversalStyle *>(parentStyle()); + inheritTheme(universal ? universal->theme() : DefaultTheme); + } +} + +QQuickUniversalStyle::Accent QQuickUniversalStyle::accent() const +{ + return m_accent; +} + +void QQuickUniversalStyle::setAccent(Accent accent) +{ + if (accent < Lime || accent > Taupe) { + qWarning() << "QQuickUniversalStyle: unknown accent" << accent; + return; + } + m_hasAccent = true; + if (m_accent != accent) { + m_accent = accent; + propagateAccent(); + emit accentChanged(); + } +} + +void QQuickUniversalStyle::inheritAccent(Accent accent) +{ + if (!m_hasAccent && m_accent != accent) { + m_accent = accent; + propagateAccent(); + emit accentChanged(); + } +} + +void QQuickUniversalStyle::propagateAccent() +{ + foreach (QQuickStyle *child, childStyles()) { + QQuickUniversalStyle *universal = qobject_cast<QQuickUniversalStyle *>(child); + if (universal) + universal->inheritAccent(m_accent); + } +} + +void QQuickUniversalStyle::resetAccent() +{ + if (m_hasAccent) { + m_hasAccent = false; + QQuickUniversalStyle *universal = qobject_cast<QQuickUniversalStyle *>(parentStyle()); + inheritAccent(universal ? universal->accent() : DefaultAccent); + } +} + +QColor QQuickUniversalStyle::accentColor() const +{ + return qquickuniversal_accent_color(m_accent); +} + +QColor QQuickUniversalStyle::altHighColor() const +{ + return getColor(AltHigh); +} + +QColor QQuickUniversalStyle::altLowColor() const +{ + return getColor(AltLow); +} + +QColor QQuickUniversalStyle::altMediumColor() const +{ + return getColor(AltMedium); +} + +QColor QQuickUniversalStyle::altMediumHighColor() const +{ + return getColor(AltMediumHigh); +} + +QColor QQuickUniversalStyle::altMediumLowColor() const +{ + return getColor(AltMediumLow); +} + +QColor QQuickUniversalStyle::baseHighColor() const +{ + return getColor(BaseHighColor); +} + +QColor QQuickUniversalStyle::baseLowColor() const +{ + return getColor(BaseLow); +} + +QColor QQuickUniversalStyle::baseMediumColor() const +{ + return getColor(BaseMedium); +} + +QColor QQuickUniversalStyle::baseMediumHighColor() const +{ + return getColor(BaseMediumHigh); +} + +QColor QQuickUniversalStyle::baseMediumLowColor() const +{ + return getColor(BaseMediumLow); +} + +QColor QQuickUniversalStyle::chromeAltLowColor() const +{ + return getColor(ChromeAltLow); +} + +QColor QQuickUniversalStyle::chromeBlackHighColor() const +{ + return getColor(ChromeBlackHigh); +} + +QColor QQuickUniversalStyle::chromeBlackLowColor() const +{ + return getColor(ChromeBlackLow); +} + +QColor QQuickUniversalStyle::chromeBlackMediumLowColor() const +{ + return getColor(ChromeBlackMediumLow); +} + +QColor QQuickUniversalStyle::chromeBlackMediumColor() const +{ + return getColor(ChromeBlackMedium); +} + +QColor QQuickUniversalStyle::chromeDisabledHighColor() const +{ + return getColor(ChromeDisabledHigh); +} + +QColor QQuickUniversalStyle::chromeDisabledLowColor() const +{ + return getColor(ChromeDisabledLow); +} + +QColor QQuickUniversalStyle::chromeHighColor() const +{ + return getColor(ChromeHigh); +} + +QColor QQuickUniversalStyle::chromeLowColor() const +{ + return getColor(ChromeLow); +} + +QColor QQuickUniversalStyle::chromeMediumColor() const +{ + return getColor(ChromeMedium); +} + +QColor QQuickUniversalStyle::chromeMediumLowColor() const +{ + return getColor(ChromeMediumLow); +} + +QColor QQuickUniversalStyle::chromeWhiteColor() const +{ + return getColor(ChromeWhite); +} + +QColor QQuickUniversalStyle::listLowColor() const +{ + return getColor(ListLow); +} + +QColor QQuickUniversalStyle::listMediumColor() const +{ + return getColor(ListMedium); +} + +QColor QQuickUniversalStyle::getColor(SystemColor role) const +{ + return m_theme == QQuickUniversalStyle::Dark ? qquickuniversal_dark_color(role) : qquickuniversal_light_color(role); +} + +void QQuickUniversalStyle::parentStyleChange(QQuickStyle *newParent, QQuickStyle *oldParent) +{ + Q_UNUSED(oldParent); + QQuickUniversalStyle *universal = qobject_cast<QQuickUniversalStyle *>(newParent); + if (universal) { + inheritTheme(universal->theme()); + inheritAccent(universal->accent()); + } +} + +QT_END_NAMESPACE diff --git a/src/imports/controls/universal/qquickuniversalstyle_p.h b/src/imports/controls/universal/qquickuniversalstyle_p.h new file mode 100644 index 00000000..3bf0bb5d --- /dev/null +++ b/src/imports/controls/universal/qquickuniversalstyle_p.h @@ -0,0 +1,208 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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 QQUICKUNIVERSALSTYLE_P_H +#define QQUICKUNIVERSALSTYLE_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 <QtGui/qcolor.h> +#include <QtLabsControls/private/qquickstyle_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickUniversalStylePrivate; + +class QQuickUniversalStyle : public QQuickStyle +{ + Q_OBJECT + Q_PROPERTY(Theme theme READ theme WRITE setTheme RESET resetTheme NOTIFY themeChanged FINAL) + Q_PROPERTY(Accent accent READ accent WRITE setAccent RESET resetAccent NOTIFY accentChanged FINAL) + + Q_PROPERTY(QColor accentColor READ accentColor NOTIFY accentChanged FINAL) + Q_PROPERTY(QColor altHighColor READ altHighColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor altLowColor READ altLowColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor altMediumColor READ altMediumColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor altMediumHighColor READ altMediumHighColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor altMediumLowColor READ altMediumLowColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor baseHighColor READ baseHighColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor baseLowColor READ baseLowColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor baseMediumColor READ baseMediumColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor baseMediumHighColor READ baseMediumHighColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor baseMediumLowColor READ baseMediumLowColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor chromeAltLowColor READ chromeAltLowColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor chromeBlackHighColor READ chromeBlackHighColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor chromeBlackLowColor READ chromeBlackLowColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor chromeBlackMediumLowColor READ chromeBlackMediumLowColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor chromeBlackMediumColor READ chromeBlackMediumColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor chromeDisabledHighColor READ chromeDisabledHighColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor chromeDisabledLowColor READ chromeDisabledLowColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor chromeHighColor READ chromeHighColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor chromeLowColor READ chromeLowColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor chromeMediumColor READ chromeMediumColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor chromeMediumLowColor READ chromeMediumLowColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor chromeWhiteColor READ chromeWhiteColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor listLowColor READ listLowColor NOTIFY paletteChanged FINAL) + Q_PROPERTY(QColor listMediumColor READ listMediumColor NOTIFY paletteChanged FINAL) + +public: + explicit QQuickUniversalStyle(QObject *parent = Q_NULLPTR); + + static QQuickUniversalStyle *qmlAttachedProperties(QObject *object); + + enum Theme { Light, Dark }; + Q_ENUM(Theme) + + Theme theme() const; + void setTheme(Theme theme); + void inheritTheme(Theme theme); + void propagateTheme(); + void resetTheme(); + + enum Accent { + Lime, + Green, + Emerald, + Teal, + Cyan, + Cobalt, + Indigo, + Violet, + Pink, + Magenta, + Crimson, + Red, + Orange, + Amber, + Yellow, + Brown, + Olive, + Steel, + Mauve, + Taupe + }; + Q_ENUM(Accent) + + Accent accent() const; + void setAccent(Accent accent); + void inheritAccent(Accent accent); + void propagateAccent(); + void resetAccent(); + + QColor accentColor() const; + QColor altHighColor() const; + QColor altLowColor() const; + QColor altMediumColor() const; + QColor altMediumHighColor() const; + QColor altMediumLowColor() const; + QColor baseHighColor() const; + QColor baseLowColor() const; + QColor baseMediumColor() const; + QColor baseMediumHighColor() const; + QColor baseMediumLowColor() const; + QColor chromeAltLowColor() const; + QColor chromeBlackHighColor() const; + QColor chromeBlackLowColor() const; + QColor chromeBlackMediumLowColor() const; + QColor chromeBlackMediumColor() const; + QColor chromeDisabledHighColor() const; + QColor chromeDisabledLowColor() const; + QColor chromeHighColor() const; + QColor chromeLowColor() const; + QColor chromeMediumColor() const; + QColor chromeMediumLowColor() const; + QColor chromeWhiteColor() const; + QColor listLowColor() const; + QColor listMediumColor() const; + + enum SystemColor { + AltHigh, + AltLow, + AltMedium, + AltMediumHigh, + AltMediumLow, + BaseHighColor, + BaseLow, + BaseMedium, + BaseMediumHigh, + BaseMediumLow, + ChromeAltLow, + ChromeBlackHigh, + ChromeBlackLow, + ChromeBlackMediumLow, + ChromeBlackMedium, + ChromeDisabledHigh, + ChromeDisabledLow, + ChromeHigh, + ChromeLow, + ChromeMedium, + ChromeMediumLow, + ChromeWhite, + ListLow, + ListMedium + }; + + QColor getColor(SystemColor role) const; + +Q_SIGNALS: + void themeChanged(); + void accentChanged(); + void paletteChanged(); + +protected: + void parentStyleChange(QQuickStyle *newParent, QQuickStyle *oldParent) Q_DECL_OVERRIDE; + +private: + bool m_hasTheme; + bool m_hasAccent; + QQuickUniversalStyle::Theme m_theme; + QQuickUniversalStyle::Accent m_accent; +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPEINFO(QQuickUniversalStyle, QML_HAS_ATTACHED_PROPERTIES) + +#endif // QQUICKUNIVERSALSTYLE_P_H diff --git a/src/imports/controls/universal/qquickuniversaltheme.cpp b/src/imports/controls/universal/qquickuniversaltheme.cpp new file mode 100644 index 00000000..fd470ba6 --- /dev/null +++ b/src/imports/controls/universal/qquickuniversaltheme.cpp @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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 "qquickuniversaltheme_p.h" + +#include <QtGui/qfont.h> + +QT_BEGIN_NAMESPACE + +QQuickUniversalTheme::QQuickUniversalTheme(QPlatformTheme *theme) + : QQuickProxyTheme(theme) +{ + systemFont = QFont(QLatin1Literal("Sege UI")); + systemFont.setPixelSize(15); + mdiSubWindowTitleFont = systemFont; + mdiSubWindowTitleFont.setWeight(QFont::DemiBold); + dockWidgetTitleFont = QFont(QLatin1Literal("Sege UI")); + dockWidgetTitleFont.setPixelSize(24); + dockWidgetTitleFont.setWeight(QFont::Light); +} + +QQuickUniversalTheme::~QQuickUniversalTheme() +{ +} + +const QFont *QQuickUniversalTheme::font(QPlatformTheme::Font type) const +{ + switch (type) { + case QPlatformTheme::MdiSubWindowTitleFont: + return &mdiSubWindowTitleFont; + case QPlatformTheme::DockWidgetTitleFont: + return &dockWidgetTitleFont; + default: + return &systemFont; + } +} + +QT_END_NAMESPACE diff --git a/src/imports/controls/universal/qquickuniversaltheme_p.h b/src/imports/controls/universal/qquickuniversaltheme_p.h new file mode 100644 index 00000000..c014ead2 --- /dev/null +++ b/src/imports/controls/universal/qquickuniversaltheme_p.h @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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 QQUICKUNIVERSALTHEME_H +#define QQUICKUNIVERSALTHEME_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 <QtGui/qpa/qplatformtheme.h> +#include <QtGui/qfont.h> +#include <QtLabsControls/private/qquickproxytheme_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickUniversalTheme : public QQuickProxyTheme +{ +public: + QQuickUniversalTheme(QPlatformTheme *theme); + + ~QQuickUniversalTheme(); + + const QFont *font(Font type = SystemFont) const Q_DECL_OVERRIDE; + +private: + QFont systemFont; + QFont mdiSubWindowTitleFont; // QQuickGroupBox + QFont dockWidgetTitleFont; // QQuickTabButton +}; + +QT_END_NAMESPACE + +#endif // QQUICKUNIVERSALTHEME_H diff --git a/src/imports/controls/universal/qtlabsuniversalstyleplugin.cpp b/src/imports/controls/universal/qtlabsuniversalstyleplugin.cpp new file mode 100644 index 00000000..2cf6fb67 --- /dev/null +++ b/src/imports/controls/universal/qtlabsuniversalstyleplugin.cpp @@ -0,0 +1,107 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls 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 <QtQml/qqmlextensionplugin.h> +#include "qquickuniversalimageprovider_p.h" +#include "qquickuniversalprogressring_p.h" +#include "qquickuniversalprogressstrip_p.h" +#include "qquickuniversalstyle_p.h" +#include "qquickuniversaltheme_p.h" + +#include <QtGui/private/qguiapplication_p.h> +#include <QtLabsControls/private/qquickstyleselector_p.h> + +static inline void initResources() +{ + Q_INIT_RESOURCE(qtlabsuniversalstyleplugin); +} + +QT_BEGIN_NAMESPACE + +class QtLabsUniversalStylePlugin: public QQmlExtensionPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface/1.0") + +public: + ~QtLabsUniversalStylePlugin(); + void registerTypes(const char *uri) Q_DECL_OVERRIDE; + void initializeEngine(QQmlEngine *engine, const char *uri) Q_DECL_OVERRIDE; + +private: + QQuickProxyTheme *theme; +}; + +QtLabsUniversalStylePlugin::~QtLabsUniversalStylePlugin() +{ + if (theme) { + QPlatformTheme *old = theme->theme(); + QGuiApplicationPrivate::platform_theme = old; + delete theme; + } +} + +void QtLabsUniversalStylePlugin::registerTypes(const char *uri) +{ + qmlRegisterUncreatableType<QQuickUniversalStyle>(uri, 1, 0, "Universal", tr("Universal is an attached property")); +} + +void QtLabsUniversalStylePlugin::initializeEngine(QQmlEngine *engine, const char *uri) +{ + QQuickStyleSelector *selector = QQuickStyleSelector::instance(); + if (selector && selector->style() == QStringLiteral("universal")) { + if (QFont(QStringLiteral("Segoe UI")).family() == QStringLiteral("Segoe UI")) { + QPlatformTheme *old = QGuiApplicationPrivate::platform_theme; + if (old) { + QQuickProxyTheme *theme = new QQuickUniversalTheme(old); + QGuiApplicationPrivate::platform_theme = theme; + } + } + } + + initResources(); + engine->addImageProvider(QStringLiteral("universal"), new QQuickUniversalImageProvider); + + QByteArray import = QByteArray(uri) + ".impl"; + qmlRegisterType<QQuickUniversalProgressRing>(import, 1, 0, "ProgressRing"); + qmlRegisterType<QQuickUniversalProgressRingAnimator>(import, 1, 0, "ProgressRingAnimator"); + qmlRegisterType<QQuickUniversalProgressStrip>(import, 1, 0, "ProgressStrip"); + qmlRegisterType<QQuickUniversalProgressStripAnimator>(import, 1, 0, "ProgressStripAnimator"); +} + +QT_END_NAMESPACE + +#include "qtlabsuniversalstyleplugin.moc" diff --git a/src/imports/controls/universal/qtlabsuniversalstyleplugin.qrc b/src/imports/controls/universal/qtlabsuniversalstyleplugin.qrc new file mode 100644 index 00000000..6cd57f89 --- /dev/null +++ b/src/imports/controls/universal/qtlabsuniversalstyleplugin.qrc @@ -0,0 +1,16 @@ +<!DOCTYPE RCC><RCC version="1.0"> +<qresource prefix="org.qt-project/imports/Qt/labs/controls/universal"> + <file>images/checkmark.png</file> + <file>images/checkmark@2x.png</file> + <file>images/checkmark@3x.png</file> + <file>images/checkmark@4x.png</file> + <file>images/leftarrow.png</file> + <file>images/leftarrow@2x.png</file> + <file>images/leftarrow@3x.png</file> + <file>images/leftarrow@4x.png</file> + <file>images/rightarrow.png</file> + <file>images/rightarrow@2x.png</file> + <file>images/rightarrow@3x.png</file> + <file>images/rightarrow@4x.png</file> +</qresource> +</RCC> diff --git a/src/imports/controls/universal/universal.pri b/src/imports/controls/universal/universal.pri new file mode 100644 index 00000000..4865e499 --- /dev/null +++ b/src/imports/controls/universal/universal.pri @@ -0,0 +1,41 @@ +QML_FILES += \ + $$PWD/ApplicationWindow.qml \ + $$PWD/BusyIndicator.qml \ + $$PWD/Button.qml \ + $$PWD/CheckBox.qml \ + $$PWD/Dial.qml \ + $$PWD/Frame.qml \ + $$PWD/GroupBox.qml \ + $$PWD/ItemDelegate.qml \ + $$PWD/Label.qml \ + $$PWD/PageIndicator.qml \ + $$PWD/ProgressBar.qml \ + $$PWD/RadioButton.qml \ + $$PWD/RangeSlider.qml \ + $$PWD/ScrollBar.qml \ + $$PWD/ScrollIndicator.qml \ + $$PWD/Slider.qml \ + $$PWD/SpinBox.qml \ + $$PWD/StackView.qml \ + $$PWD/Switch.qml \ + $$PWD/TabBar.qml \ + $$PWD/TabButton.qml \ + $$PWD/TextArea.qml \ + $$PWD/TextField.qml \ + $$PWD/ToolBar.qml \ + $$PWD/ToolButton.qml \ + $$PWD/Tumbler.qml + +HEADERS += \ + $$PWD/qquickuniversalimageprovider_p.h \ + $$PWD/qquickuniversalprogressring_p.h \ + $$PWD/qquickuniversalprogressstrip_p.h \ + $$PWD/qquickuniversalstyle_p.h \ + $$PWD/qquickuniversaltheme_p.h + +SOURCES += \ + $$PWD/qquickuniversalimageprovider.cpp \ + $$PWD/qquickuniversalprogressring.cpp \ + $$PWD/qquickuniversalprogressstrip.cpp \ + $$PWD/qquickuniversalstyle.cpp \ + $$PWD/qquickuniversaltheme.cpp diff --git a/src/imports/controls/universal/universal.pro b/src/imports/controls/universal/universal.pro new file mode 100644 index 00000000..41cef97d --- /dev/null +++ b/src/imports/controls/universal/universal.pro @@ -0,0 +1,22 @@ +TARGET = qtlabsuniversalstyleplugin +TARGETPATH = Qt/labs/controls/universal +IMPORT_VERSION = 1.0 + +QT += qml quick +QT_PRIVATE += core-private gui-private qml-private quick-private labscontrols-private + +DEFINES += QT_NO_CAST_TO_ASCII QT_NO_CAST_FROM_ASCII + +OTHER_FILES += \ + qmldir + +SOURCES += \ + $$PWD/qtlabsuniversalstyleplugin.cpp + +RESOURCES += \ + $$PWD/qtlabsuniversalstyleplugin.qrc + +include(universal.pri) + +CONFIG += no_cxx_module +load(qml_plugin) diff --git a/src/imports/imports.pro b/src/imports/imports.pro index 7a5e5bf5..3227cb99 100644 --- a/src/imports/imports.pro +++ b/src/imports/imports.pro @@ -3,3 +3,7 @@ SUBDIRS += \ controls \ calendar \ templates + +SUBDIRS += \ + controls/material/material.pro \ + controls/universal/universal.pro diff --git a/src/imports/templates/qtlabstemplatesplugin.cpp b/src/imports/templates/qtlabstemplatesplugin.cpp index 5a976aca..721e4cab 100644 --- a/src/imports/templates/qtlabstemplatesplugin.cpp +++ b/src/imports/templates/qtlabstemplatesplugin.cpp @@ -47,8 +47,12 @@ #include <QtLabsTemplates/private/qquickdrawer_p.h> #include <QtLabsTemplates/private/qquickframe_p.h> #include <QtLabsTemplates/private/qquickgroupbox_p.h> +#include <QtLabsTemplates/private/qquickitemdelegate_p.h> #include <QtLabsTemplates/private/qquicklabel_p.h> +#include <QtLabsTemplates/private/qquickmenu_p.h> +#include <QtLabsTemplates/private/qquickmenuitem_p.h> #include <QtLabsTemplates/private/qquickpageindicator_p.h> +#include <QtLabsTemplates/private/qquickpanel_p.h> #include <QtLabsTemplates/private/qquickprogressbar_p.h> #include <QtLabsTemplates/private/qquickradiobutton_p.h> #include <QtLabsTemplates/private/qquickrangeslider_p.h> @@ -82,6 +86,7 @@ void QtLabsTemplatesPlugin::registerTypes(const char *uri) { qmlRegisterType<QQuickAbstractButton>(uri, 1, 0, "AbstractButton"); qmlRegisterType<QQuickApplicationWindow>(uri, 1, 0, "ApplicationWindow"); + qmlRegisterType<QQuickApplicationWindowAttached>(); qmlRegisterType<QQuickBusyIndicator>(uri, 1, 0, "BusyIndicator"); qmlRegisterType<QQuickButton>(uri, 1, 0, "Button"); qmlRegisterType<QQuickCheckBox>(uri, 1, 0, "CheckBox"); @@ -91,8 +96,12 @@ void QtLabsTemplatesPlugin::registerTypes(const char *uri) qmlRegisterType<QQuickDrawer>(uri, 1, 0, "Drawer"); qmlRegisterType<QQuickFrame>(uri, 1, 0, "Frame"); qmlRegisterType<QQuickGroupBox>(uri, 1, 0, "GroupBox"); + qmlRegisterType<QQuickItemDelegate>(uri, 1, 0, "ItemDelegate"); qmlRegisterType<QQuickLabel>(uri, 1, 0, "Label"); + qmlRegisterType<QQuickMenu>(uri, 1, 0, "Menu"); + qmlRegisterType<QQuickMenuItem>(uri, 1, 0, "MenuItem"); qmlRegisterType<QQuickPageIndicator>(uri, 1, 0, "PageIndicator"); + qmlRegisterType<QQuickPanel>(uri, 1, 0, "Panel"); qmlRegisterType<QQuickProgressBar>(uri, 1, 0, "ProgressBar"); qmlRegisterType<QQuickRadioButton>(uri, 1, 0, "RadioButton"); qmlRegisterType<QQuickRangeSlider>(uri, 1, 0, "RangeSlider"); @@ -115,6 +124,7 @@ void QtLabsTemplatesPlugin::registerTypes(const char *uri) qmlRegisterType<QQuickTumblerAttached>(); qmlRegisterType<QQuickTumbler>(uri, 1, 0, "Tumbler"); + qmlRegisterRevision<QQuickWindow, 2>(uri, 1, 0); qmlRegisterRevision<QQuickText, 6>(uri, 1, 0); qmlRegisterRevision<QQuickTextInput, 6>(uri, 1, 0); qmlRegisterRevision<QQuickTextEdit, 6>(uri, 1, 0); diff --git a/src/imports/templates/templates.pro b/src/imports/templates/templates.pro index e49486f7..0e48168c 100644 --- a/src/imports/templates/templates.pro +++ b/src/imports/templates/templates.pro @@ -1,9 +1,11 @@ -TARGET = qtlabstemplatesplugin +TARGET = qtlabstemplatesplugin TARGETPATH = Qt/labs/templates IMPORT_VERSION = 1.0 QT += qml quick -QT += core-private gui-private qml-private quick-private labstemplates-private +QT_PRIVATE += core-private gui-private qml-private quick-private labstemplates-private + +DEFINES += QT_NO_CAST_TO_ASCII QT_NO_CAST_FROM_ASCII OTHER_FILES += \ qmldir diff --git a/src/src.pro b/src/src.pro index ab08ac5e..7223eec9 100644 --- a/src/src.pro +++ b/src/src.pro @@ -1,6 +1,7 @@ TEMPLATE = subdirs SUBDIRS += \ + controls \ imports \ templates -imports.depends = templates +imports.depends = controls templates diff --git a/src/templates/qquickabstractbutton.cpp b/src/templates/qquickabstractbutton.cpp index 6c404988..74058daf 100644 --- a/src/templates/qquickabstractbutton.cpp +++ b/src/templates/qquickabstractbutton.cpp @@ -36,7 +36,7 @@ #include "qquickabstractbutton_p.h" #include "qquickabstractbutton_p_p.h" -#include "qquickexclusivegroup_p.h" +#include "qquickbuttongroup_p.h" #include <QtGui/qguiapplication.h> #include <QtQuick/private/qquickevents_p_p.h> @@ -53,7 +53,6 @@ static const int AUTO_REPEAT_INTERVAL = 100; \inherits Control \instantiates QQuickAbstractButton \inqmlmodule Qt.labs.controls - \qmlabstract \ingroup qtlabscontrols-buttons \brief The base of all button controls. @@ -111,7 +110,7 @@ static const int AUTO_REPEAT_INTERVAL = 100; QQuickAbstractButtonPrivate::QQuickAbstractButtonPrivate() : pressed(false), checked(false), checkable(false), autoExclusive(false), autoRepeat(false), - delayTimer(0), repeatTimer(0), repeatButton(Qt::NoButton), label(Q_NULLPTR), indicator(Q_NULLPTR) + delayTimer(0), repeatTimer(0), repeatButton(Qt::NoButton), label(Q_NULLPTR), indicator(Q_NULLPTR), group(Q_NULLPTR) { } @@ -142,21 +141,11 @@ void QQuickAbstractButtonPrivate::stopPressRepeat() } } -QQuickExclusiveGroup *QQuickAbstractButtonPrivate::exclusiveGroup() const -{ - Q_Q(const QQuickAbstractButton); - QQuickExclusiveGroupAttached *attached = qobject_cast<QQuickExclusiveGroupAttached *>(qmlAttachedPropertiesObject<QQuickExclusiveGroup>(q, false)); - if (attached) - return attached->group(); - return Q_NULLPTR; -} - QQuickAbstractButton *QQuickAbstractButtonPrivate::findCheckedButton() const { Q_Q(const QQuickAbstractButton); - QQuickExclusiveGroup *group = exclusiveGroup(); if (group) - return qobject_cast<QQuickAbstractButton *>(group->current()); + return qobject_cast<QQuickAbstractButton *>(group->checkedButton()); QList<QQuickAbstractButton *> buttons = findExclusiveButtons(); // TODO: A singular QRadioButton can be unchecked, which seems logical, @@ -178,19 +167,18 @@ QQuickAbstractButton *QQuickAbstractButtonPrivate::findCheckedButton() const QList<QQuickAbstractButton *> QQuickAbstractButtonPrivate::findExclusiveButtons() const { QList<QQuickAbstractButton *> buttons; - QQuickExclusiveGroup *group = exclusiveGroup(); if (group) { - QQmlListProperty<QObject> checkables = group->checkables(); - int count = checkables.count(&checkables); + QQmlListProperty<QQuickAbstractButton> groupButtons = group->buttons(); + int count = groupButtons.count(&groupButtons); for (int i = 0; i < count; ++i) { - QQuickAbstractButton *button = qobject_cast<QQuickAbstractButton *>(checkables.at(&checkables, i)); + QQuickAbstractButton *button = qobject_cast<QQuickAbstractButton *>(groupButtons.at(&groupButtons, i)); if (button) buttons += button; } } else if (parentItem) { foreach (QQuickItem *child, parentItem->childItems()) { QQuickAbstractButton *button = qobject_cast<QQuickAbstractButton *>(child); - if (button && button->autoExclusive() && !button->d_func()->exclusiveGroup()) + if (button && button->autoExclusive() && !QQuickAbstractButtonPrivate::get(button)->group) buttons += button; } } @@ -211,6 +199,13 @@ QQuickAbstractButton::QQuickAbstractButton(QQuickAbstractButtonPrivate &dd, QQui setAcceptedMouseButtons(Qt::LeftButton); } +QQuickAbstractButton::~QQuickAbstractButton() +{ + Q_D(QQuickAbstractButton); + if (d->group) + d->group->removeButton(this); +} + /*! \qmlproperty string Qt.labs.controls::AbstractButton::text @@ -307,11 +302,11 @@ void QQuickAbstractButton::setCheckable(bool checkable) This property holds whether auto-exclusivity is enabled. If auto-exclusivity is enabled, checkable buttons that belong to the same - parent item behave as if they were part of the same ExclusiveGroup. Only + parent item behave as if they were part of the same ButtonGroup. Only one button can be checked at any time; checking another button automatically unchecks the previously checked one. - \note The property has no effect on buttons that belong to an ExclusiveGroup. + \note The property has no effect on buttons that belong to an ButtonGroup. RadioButton and TabButton are auto-exclusive by default. */ diff --git a/src/templates/qquickabstractbutton_p.h b/src/templates/qquickabstractbutton_p.h index 53d17af3..24998520 100644 --- a/src/templates/qquickabstractbutton_p.h +++ b/src/templates/qquickabstractbutton_p.h @@ -69,6 +69,7 @@ class Q_LABSTEMPLATES_EXPORT QQuickAbstractButton : public QQuickControl public: explicit QQuickAbstractButton(QQuickItem *parent = Q_NULLPTR); + ~QQuickAbstractButton(); QString text() const; void setText(const QString &text); diff --git a/src/templates/qquickabstractbutton_p_p.h b/src/templates/qquickabstractbutton_p_p.h index dfa87e7f..ed0a8d9d 100644 --- a/src/templates/qquickabstractbutton_p_p.h +++ b/src/templates/qquickabstractbutton_p_p.h @@ -48,12 +48,12 @@ // We mean it. // +#include <QtLabsTemplates/private/qquickabstractbutton_p.h> #include <QtLabsTemplates/private/qquickcontrol_p_p.h> QT_BEGIN_NAMESPACE -class QQuickAbstractButton; -class QQuickExclusiveGroup; +class QQuickButtonGroup; class QQuickAbstractButtonPrivate : public QQuickControlPrivate { @@ -62,11 +62,15 @@ class QQuickAbstractButtonPrivate : public QQuickControlPrivate public: QQuickAbstractButtonPrivate(); + static QQuickAbstractButtonPrivate *get(QQuickAbstractButton *button) + { + return button->d_func(); + } + void startRepeatDelay(); void startPressRepeat(); void stopPressRepeat(); - QQuickExclusiveGroup *exclusiveGroup() const; QQuickAbstractButton *findCheckedButton() const; QList<QQuickAbstractButton *> findExclusiveButtons() const; @@ -82,6 +86,7 @@ public: Qt::MouseButton repeatButton; QQuickItem *label; QQuickItem *indicator; + QQuickButtonGroup *group; }; Q_DECLARE_TYPEINFO(QQuickAbstractButtonPrivate, Q_COMPLEX_TYPE); diff --git a/src/templates/qquickapplicationwindow.cpp b/src/templates/qquickapplicationwindow.cpp index ae64b06b..2c4cd7c9 100644 --- a/src/templates/qquickapplicationwindow.cpp +++ b/src/templates/qquickapplicationwindow.cpp @@ -35,7 +35,9 @@ ****************************************************************************/ #include "qquickapplicationwindow_p.h" +#include "qquickoverlay_p.h" +#include <QtCore/private/qobject_p.h> #include <QtQuick/private/qquickitem_p.h> #include <QtQuick/private/qquickitemchangelistener_p.h> @@ -69,6 +71,7 @@ public: , contentItem(Q_NULLPTR) , header(Q_NULLPTR) , footer(Q_NULLPTR) + , overlay(Q_NULLPTR) { } void relayout(); @@ -80,6 +83,7 @@ public: QQuickItem *contentItem; QQuickItem *header; QQuickItem *footer; + QQuickOverlay *overlay; QQuickApplicationWindow *q_ptr; }; @@ -90,11 +94,16 @@ void QQuickApplicationWindowPrivate::relayout() qreal hh = header ? header->height() : 0; qreal fh = footer ? footer->height() : 0; - content->setX(0); content->setY(hh); content->setWidth(q->width()); content->setHeight(q->height() - hh - fh); + if (overlay) { + overlay->setWidth(q->width()); + overlay->setHeight(q->height()); + overlay->stackAfter(content); + } + if (header) { header->setY(-hh); QQuickItemPrivate *p = QQuickItemPrivate::get(header); @@ -207,7 +216,6 @@ void QQuickApplicationWindow::setFooter(QQuickItem *footer) } } - QQmlListProperty<QObject> QQuickApplicationWindow::contentData() { return QQuickItemPrivate::get(contentItem())->data(); @@ -215,15 +223,29 @@ QQmlListProperty<QObject> QQuickApplicationWindow::contentData() QQuickItem *QQuickApplicationWindow::contentItem() const { - Q_D(const QQuickApplicationWindow); + QQuickApplicationWindowPrivate *d = const_cast<QQuickApplicationWindowPrivate *>(d_func()); if (!d->contentItem) { - QQuickApplicationWindowPrivate *ncd = const_cast<QQuickApplicationWindowPrivate *>(d); - ncd->contentItem = new QQuickItem(QQuickWindow::contentItem()); - ncd->relayout(); + d->contentItem = new QQuickItem(QQuickWindow::contentItem()); + d->relayout(); } return d->contentItem; } +QQuickItem *QQuickApplicationWindow::overlay() const +{ + QQuickApplicationWindowPrivate *d = const_cast<QQuickApplicationWindowPrivate *>(d_func()); + if (!d->overlay) { + d->overlay = new QQuickOverlay(QQuickWindow::contentItem()); + d->relayout(); + } + return d->overlay; +} + +QQuickApplicationWindowAttached *QQuickApplicationWindow::qmlAttachedProperties(QObject *object) +{ + return new QQuickApplicationWindowAttached(object); +} + bool QQuickApplicationWindow::isComponentComplete() const { Q_D(const QQuickApplicationWindow); @@ -244,4 +266,141 @@ void QQuickApplicationWindow::resizeEvent(QResizeEvent *event) d->relayout(); } +class QQuickApplicationWindowAttachedPrivate : public QObjectPrivate +{ + Q_DECLARE_PUBLIC(QQuickApplicationWindowAttached) + +public: + QQuickApplicationWindowAttachedPrivate() : window(Q_NULLPTR) { } + + void windowChange(QQuickWindow *wnd); + + QQuickApplicationWindow *window; +}; + +void QQuickApplicationWindowAttachedPrivate::windowChange(QQuickWindow *wnd) +{ + Q_Q(QQuickApplicationWindowAttached); + QQuickApplicationWindow *newWindow = qobject_cast<QQuickApplicationWindow *>(wnd); + if (window != newWindow) { + QQuickApplicationWindow *oldWindow = window; + if (oldWindow) { + QObject::disconnect(oldWindow, &QQuickApplicationWindow::activeFocusItemChanged, + q, &QQuickApplicationWindowAttached::activeFocusItemChanged); + 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::headerChanged, + q, &QQuickApplicationWindowAttached::headerChanged); + QObject::connect(newWindow, &QQuickApplicationWindow::footerChanged, + q, &QQuickApplicationWindowAttached::footerChanged); + } + + window = newWindow; + emit q->windowChanged(); + emit q->contentItemChanged(); + emit q->overlayChanged(); + + if ((oldWindow && oldWindow->activeFocusItem()) || (newWindow && newWindow->activeFocusItem())) + emit q->activeFocusItemChanged(); + if ((oldWindow && oldWindow->header()) || (newWindow && newWindow->header())) + emit q->headerChanged(); + if ((oldWindow && oldWindow->footer()) || (newWindow && newWindow->footer())) + emit q->footerChanged(); + } +} + +QQuickApplicationWindowAttached::QQuickApplicationWindowAttached(QObject *parent) + : QObject(*(new QQuickApplicationWindowAttachedPrivate), parent) +{ + Q_D(QQuickApplicationWindowAttached); + QQuickItem *item = qobject_cast<QQuickItem *>(parent); + if (item) { + d->windowChange(item->window()); + QObjectPrivate::connect(item, &QQuickItem::windowChanged, d, &QQuickApplicationWindowAttachedPrivate::windowChange); + } +} + +/*! + \qmlattachedproperty ApplicationWindow Qt.labs.controls::ApplicationWindow::window + + This attached property holds the application window. The property can be attached + to any item. The value is \c null if the item is not in an ApplicationWindow. +*/ +QQuickApplicationWindow *QQuickApplicationWindowAttached::window() const +{ + Q_D(const QQuickApplicationWindowAttached); + return d->window; +} + +/*! + \qmlattachedproperty Item Qt.labs.controls::ApplicationWindow::contentItem + + This attached property holds the window content item. The property can be attached + to any item. The value is \c null if the item is not in an ApplicationWindow. +*/ +QQuickItem *QQuickApplicationWindowAttached::contentItem() const +{ + Q_D(const QQuickApplicationWindowAttached); + return d->window ? d->window->contentItem() : Q_NULLPTR; +} + +/*! + \qmlattachedproperty Item Qt.labs.controls::ApplicationWindow::activeFocusItem + + 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. + + \sa Window::activeFocusItem +*/ +QQuickItem *QQuickApplicationWindowAttached::activeFocusItem() const +{ + Q_D(const QQuickApplicationWindowAttached); + return d->window ? d->window->activeFocusItem() : Q_NULLPTR; +} + +/*! + \qmlattachedproperty Item Qt.labs.controls::ApplicationWindow::header + + This attached property holds the window header 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 header item. +*/ +QQuickItem *QQuickApplicationWindowAttached::header() const +{ + Q_D(const QQuickApplicationWindowAttached); + return d->window ? d->window->header() : Q_NULLPTR; +} + +/*! + \qmlattachedproperty Item Qt.labs.controls::ApplicationWindow::footer + + This attached property holds the window footer 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 footer item. +*/ +QQuickItem *QQuickApplicationWindowAttached::footer() const +{ + Q_D(const QQuickApplicationWindowAttached); + return d->window ? d->window->footer() : Q_NULLPTR; +} + +/*! + \qmlattachedproperty Item Qt.labs.controls::ApplicationWindow::overlay + + 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 +{ + Q_D(const QQuickApplicationWindowAttached); + return d->window ? d->window->overlay() : Q_NULLPTR; +} + QT_END_NAMESPACE diff --git a/src/templates/qquickapplicationwindow_p.h b/src/templates/qquickapplicationwindow_p.h index e23e3ba9..c5b0dc42 100644 --- a/src/templates/qquickapplicationwindow_p.h +++ b/src/templates/qquickapplicationwindow_p.h @@ -54,6 +54,8 @@ QT_BEGIN_NAMESPACE class QQuickApplicationWindowPrivate; +class QQuickApplicationWindowAttached; +class QQuickApplicationWindowAttachedPrivate; class Q_LABSTEMPLATES_EXPORT QQuickApplicationWindow : public QQuickWindowQmlImpl { @@ -62,6 +64,7 @@ class Q_LABSTEMPLATES_EXPORT QQuickApplicationWindow : public QQuickWindowQmlImp Q_PROPERTY(QQmlListProperty<QObject> data READ contentData 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_CLASSINFO("DefaultProperty", "data") public: @@ -77,6 +80,10 @@ public: QQuickItem *footer() const; void setFooter(QQuickItem *footer); + QQuickItem *overlay() const; + + static QQuickApplicationWindowAttached *qmlAttachedProperties(QObject *object); + Q_SIGNALS: void headerChanged(); void footerChanged(); @@ -92,8 +99,44 @@ private: QScopedPointer<QQuickApplicationWindowPrivate> d_ptr; }; +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 *header READ header NOTIFY headerChanged FINAL) + Q_PROPERTY(QQuickItem *footer READ footer NOTIFY footerChanged FINAL) + Q_PROPERTY(QQuickItem *overlay READ overlay NOTIFY overlayChanged FINAL) + +public: + explicit QQuickApplicationWindowAttached(QObject *parent = Q_NULLPTR); + + QQuickApplicationWindow *window() const; + QQuickItem *contentItem() const; + QQuickItem *activeFocusItem() const; + QQuickItem *header() const; + QQuickItem *footer() const; + QQuickItem *overlay() const; + +Q_SIGNALS: + void windowChanged(); + void contentItemChanged(); + void activeFocusItemChanged(); + void headerChanged(); + void footerChanged(); + void overlayChanged(); + +private: + Q_DISABLE_COPY(QQuickApplicationWindowAttached) + Q_DECLARE_PRIVATE(QQuickApplicationWindowAttached) +}; + Q_DECLARE_TYPEINFO(QQuickApplicationWindow, Q_COMPLEX_TYPE); +Q_DECLARE_TYPEINFO(QQuickApplicationWindowAttached, Q_COMPLEX_TYPE); QT_END_NAMESPACE +QML_DECLARE_TYPEINFO(QQuickApplicationWindow, QML_HAS_ATTACHED_PROPERTIES) + #endif // QQUICKAPPLICATIONWINDOW_P_H diff --git a/src/templates/qquickbutton.cpp b/src/templates/qquickbutton.cpp index 179e5bcd..4f5df5fa 100644 --- a/src/templates/qquickbutton.cpp +++ b/src/templates/qquickbutton.cpp @@ -37,6 +37,8 @@ #include "qquickbutton_p.h" #include "qquickabstractbutton_p_p.h" +#include <QtGui/qpa/qplatformtheme.h> + QT_BEGIN_NAMESPACE /*! @@ -83,11 +85,50 @@ QT_BEGIN_NAMESPACE class QQuickButtonPrivate : public QQuickAbstractButtonPrivate { +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 +{ + return QQuickControlPrivate::themeFont(QPlatformTheme::PushButtonFont); +} + QT_END_NAMESPACE diff --git a/src/templates/qquickbutton_p.h b/src/templates/qquickbutton_p.h index 1ee96a07..5b9c7df5 100644 --- a/src/templates/qquickbutton_p.h +++ b/src/templates/qquickbutton_p.h @@ -57,10 +57,20 @@ 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) diff --git a/src/templates/qquickbuttongroup.cpp b/src/templates/qquickbuttongroup.cpp new file mode 100644 index 00000000..6fddcbc4 --- /dev/null +++ b/src/templates/qquickbuttongroup.cpp @@ -0,0 +1,379 @@ +/**************************************************************************** +** +** 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 "qquickbuttongroup_p.h" + +#include <QtCore/private/qobject_p.h> +#include <QtCore/qmetaobject.h> +#include <QtCore/qvariant.h> +#include <QtQml/qqmlinfo.h> + +#include "qquickabstractbutton_p_p.h" + +QT_BEGIN_NAMESPACE + +/*! + \qmltype ButtonGroup + \inherits QtObject + \instantiates QQuickButtonGroup + \inqmlmodule Qt.labs.controls + \ingroup utilities + \brief An exclusive group of checkable controls. + + ButtonGroup is a non-visual, mutually exclusive group of buttons. + It is used with controls such as RadioButton, where only one of the options + can be selected at a time. + + The most straight-forward way to use ButtonGroup is to assign + a list of buttons. For example, the list of children of a + \l{Item Positioners}{positioner} or a \l{Qt Quick Layouts}{layout} + that manages a group of mutually exclusive buttons. + + \code + ButtonGroup { + buttons: column.children + } + + Column { + id: column + + RadioButton { + checked: true + text: qsTr("DAB") + } + + RadioButton { + text: qsTr("FM") + } + + RadioButton { + text: qsTr("AM") + } + } + \endcode + + Mutually exclusive buttons do not always share the same parent item, + or the parent layout may sometimes contain items that should not be + included in the button group. Such cases are best handled using + the \l group attached property. + + \code + ButtonGroup { id: radioGroup } + + Column { + Label { + text: qsTr("Radio:") + } + + RadioButton { + checked: true + text: qsTr("DAB") + ButtonGroup.group: radioGroup + } + + RadioButton { + text: qsTr("FM") + ButtonGroup.group: radioGroup + } + + RadioButton { + text: qsTr("AM") + ButtonGroup.group: radioGroup + } + } + \endcode + + More advanced use cases can be handled using the addButton() and + removeButton() methods. + + \sa RadioButton +*/ + +class QQuickButtonGroupPrivate : public QObjectPrivate +{ + Q_DECLARE_PUBLIC(QQuickButtonGroup) + +public: + QQuickButtonGroupPrivate() : checkedButton(Q_NULLPTR) { } + + void clear(); + void updateCurrent(); + + static void buttons_append(QQmlListProperty<QQuickAbstractButton> *prop, QQuickAbstractButton *obj); + static int buttons_count(QQmlListProperty<QQuickAbstractButton> *prop); + static QQuickAbstractButton *buttons_at(QQmlListProperty<QQuickAbstractButton> *prop, int index); + static void buttons_clear(QQmlListProperty<QQuickAbstractButton> *prop); + + QQuickAbstractButton *checkedButton; + QVector<QQuickAbstractButton*> buttons; +}; + +void QQuickButtonGroupPrivate::clear() +{ + foreach (QQuickAbstractButton *button, buttons) { + QQuickAbstractButtonPrivate::get(button)->group = Q_NULLPTR; + QObjectPrivate::disconnect(button, &QQuickAbstractButton::checkedChanged, this, &QQuickButtonGroupPrivate::updateCurrent); + } + buttons.clear(); +} + +void QQuickButtonGroupPrivate::updateCurrent() +{ + Q_Q(QQuickButtonGroup); + QQuickAbstractButton *button = qobject_cast<QQuickAbstractButton*>(q->sender()); + if (button && button->isChecked()) + q->setCheckedButton(button); +} + +void QQuickButtonGroupPrivate::buttons_append(QQmlListProperty<QQuickAbstractButton> *prop, QQuickAbstractButton *obj) +{ + QQuickButtonGroup *q = static_cast<QQuickButtonGroup *>(prop->object); + q->addButton(obj); +} + +int QQuickButtonGroupPrivate::buttons_count(QQmlListProperty<QQuickAbstractButton> *prop) +{ + QQuickButtonGroupPrivate *p = static_cast<QQuickButtonGroupPrivate *>(prop->data); + return p->buttons.count(); +} + +QQuickAbstractButton *QQuickButtonGroupPrivate::buttons_at(QQmlListProperty<QQuickAbstractButton> *prop, int index) +{ + QQuickButtonGroupPrivate *p = static_cast<QQuickButtonGroupPrivate *>(prop->data); + return p->buttons.value(index); +} + +void QQuickButtonGroupPrivate::buttons_clear(QQmlListProperty<QQuickAbstractButton> *prop) +{ + QQuickButtonGroupPrivate *p = static_cast<QQuickButtonGroupPrivate *>(prop->data); + if (!p->buttons.isEmpty()) { + p->clear(); + QQuickButtonGroup *q = static_cast<QQuickButtonGroup *>(prop->object); + q->setCheckedButton(Q_NULLPTR); + emit q->buttonsChanged(); + } +} + +QQuickButtonGroup::QQuickButtonGroup(QObject *parent) + : QObject(*(new QQuickButtonGroupPrivate), parent) +{ +} + +QQuickButtonGroup::~QQuickButtonGroup() +{ + Q_D(QQuickButtonGroup); + d->clear(); +} + +QQuickButtonGroupAttached *QQuickButtonGroup::qmlAttachedProperties(QObject *object) +{ + return new QQuickButtonGroupAttached(object); +} + +/*! + \qmlproperty AbstractButton Qt.labs.controls::ButtonGroup::current + + This property holds the currently selected button, or \c null if there is none. + + By default, it is the first checked button added to the button group. +*/ +QQuickAbstractButton *QQuickButtonGroup::checkedButton() const +{ + Q_D(const QQuickButtonGroup); + return d->checkedButton; +} + +void QQuickButtonGroup::setCheckedButton(QQuickAbstractButton *checkedButton) +{ + Q_D(QQuickButtonGroup); + if (d->checkedButton != checkedButton) { + if (d->checkedButton) + d->checkedButton->setChecked(false); + d->checkedButton = checkedButton; + if (checkedButton) + checkedButton->setChecked(true); + emit checkedButtonChanged(); + } +} + +/*! + \qmlproperty list<Object> Qt.labs.controls::ButtonGroup::buttons + \default + + This property holds the list of buttons. + + \code + ButtonGroup { + buttons: column.children + } + + Column { + id: column + + RadioButton { + checked: true + text: qsTr("Option A") + } + + RadioButton { + text: qsTr("Option B") + } + } + \endcode + + \sa group +*/ +QQmlListProperty<QQuickAbstractButton> QQuickButtonGroup::buttons() +{ + Q_D(QQuickButtonGroup); + return QQmlListProperty<QQuickAbstractButton>(this, d, + QQuickButtonGroupPrivate::buttons_append, + QQuickButtonGroupPrivate::buttons_count, + QQuickButtonGroupPrivate::buttons_at, + QQuickButtonGroupPrivate::buttons_clear); +} + +/*! + \qmlmethod void Qt.labs.controls::ButtonGroup::addButton(AbstractButton button) + + Adds a \a button to the button group. + + \note Manually adding objects to a button group is typically unnecessary. + The \l buttons property and the \l group attached property provide a + convenient and declarative syntax. + + \sa buttons, group +*/ +void QQuickButtonGroup::addButton(QQuickAbstractButton *button) +{ + Q_D(QQuickButtonGroup); + if (!button || d->buttons.contains(button)) + return; + + QQuickAbstractButtonPrivate::get(button)->group = this; + QObjectPrivate::connect(button, &QQuickAbstractButton::checkedChanged, d, &QQuickButtonGroupPrivate::updateCurrent); + + if (button->isChecked()) + setCheckedButton(button); + + d->buttons.append(button); + emit buttonsChanged(); +} + +/*! + \qmlmethod void Qt.labs.controls::ButtonGroup::removeButton(AbstractButton button) + + Removes a \a button from the button group. + + \note Manually removing objects from a button group is typically unnecessary. + The \l buttons property and the \l group attached property provide a + convenient and declarative syntax. + + \sa buttons, group +*/ +void QQuickButtonGroup::removeButton(QQuickAbstractButton *button) +{ + Q_D(QQuickButtonGroup); + if (!button || !d->buttons.contains(button)) + return; + + QQuickAbstractButtonPrivate::get(button)->group = Q_NULLPTR; + QObjectPrivate::disconnect(button, &QQuickAbstractButton::checkedChanged, d, &QQuickButtonGroupPrivate::updateCurrent); + + if (d->checkedButton == button) + setCheckedButton(Q_NULLPTR); + + d->buttons.removeOne(button); + emit buttonsChanged(); +} + +class QQuickButtonGroupAttachedPrivate : public QObjectPrivate +{ +public: + QQuickButtonGroupAttachedPrivate() : group(Q_NULLPTR) { } + + QQuickButtonGroup *group; +}; + +QQuickButtonGroupAttached::QQuickButtonGroupAttached(QObject *parent) : + QObject(*(new QQuickButtonGroupAttachedPrivate), parent) +{ +} + +/*! + \qmlattachedproperty ButtonGroup Qt.labs.controls::ButtonGroup::group + + This property attaches a button to a button group. + + \code + ButtonGroup { id: group } + + RadioButton { + checked: true + text: qsTr("Option A") + ButtonGroup.group: group + } + + RadioButton { + text: qsTr("Option B") + ButtonGroup.group: group + } + \endcode + + \sa buttons +*/ +QQuickButtonGroup *QQuickButtonGroupAttached::group() const +{ + Q_D(const QQuickButtonGroupAttached); + return d->group; +} + +void QQuickButtonGroupAttached::setGroup(QQuickButtonGroup *group) +{ + Q_D(QQuickButtonGroupAttached); + if (d->group != group) { + if (d->group) + d->group->removeButton(qobject_cast<QQuickAbstractButton*>(parent())); + d->group = group; + if (group) + group->addButton(qobject_cast<QQuickAbstractButton*>(parent())); + emit groupChanged(); + } +} + +QT_END_NAMESPACE + +#include "moc_qquickbuttongroup_p.cpp" diff --git a/src/templates/qquickexclusivegroup_p.h b/src/templates/qquickbuttongroup_p.h index 61dd8a36..366d2b2a 100644 --- a/src/templates/qquickexclusivegroup_p.h +++ b/src/templates/qquickbuttongroup_p.h @@ -34,8 +34,8 @@ ** ****************************************************************************/ -#ifndef QQUICKEXCLUSIVEGROUP_P_H -#define QQUICKEXCLUSIVEGROUP_P_H +#ifndef QQUICKBUTTONGROUP_P_H +#define QQUICKBUTTONGROUP_P_H // // W A R N I N G @@ -54,67 +54,64 @@ QT_BEGIN_NAMESPACE -class QQuickExclusiveGroupPrivate; -class QQuickExclusiveGroupAttached; -class QQuickExclusiveGroupAttachedPrivate; +class QQuickAbstractButton; +class QQuickButtonGroupPrivate; +class QQuickButtonGroupAttached; +class QQuickButtonGroupAttachedPrivate; -class Q_LABSTEMPLATES_EXPORT QQuickExclusiveGroup : public QObject +class Q_LABSTEMPLATES_EXPORT QQuickButtonGroup : public QObject { Q_OBJECT - Q_PROPERTY(QObject *current READ current WRITE setCurrent NOTIFY currentChanged) - Q_PROPERTY(QQmlListProperty<QObject> checkables READ checkables NOTIFY checkablesChanged FINAL) - Q_CLASSINFO("DefaultProperty", "checkables") + Q_PROPERTY(QQuickAbstractButton *checkedButton READ checkedButton WRITE setCheckedButton NOTIFY checkedButtonChanged) + Q_PROPERTY(QQmlListProperty<QQuickAbstractButton> buttons READ buttons NOTIFY buttonsChanged FINAL) public: - explicit QQuickExclusiveGroup(QObject *parent = Q_NULLPTR); + explicit QQuickButtonGroup(QObject *parent = Q_NULLPTR); + ~QQuickButtonGroup(); - static QQuickExclusiveGroupAttached *qmlAttachedProperties(QObject *object); + static QQuickButtonGroupAttached *qmlAttachedProperties(QObject *object); - QObject *current() const; - void setCurrent(QObject *current); + QQuickAbstractButton *checkedButton() const; + void setCheckedButton(QQuickAbstractButton *checkedButton); - QQmlListProperty<QObject> checkables(); - - Q_INVOKABLE bool isCheckable(QObject *object) const; + QQmlListProperty<QQuickAbstractButton> buttons(); public Q_SLOTS: - void addCheckable(QObject *object); - void removeCheckable(QObject *object); + void addButton(QQuickAbstractButton *button); + void removeButton(QQuickAbstractButton *button); Q_SIGNALS: - void currentChanged(); - void checkablesChanged(); + void checkedButtonChanged(); + void buttonsChanged(); private: - Q_DISABLE_COPY(QQuickExclusiveGroup) - Q_DECLARE_PRIVATE(QQuickExclusiveGroup) - - Q_PRIVATE_SLOT(d_func(), void _q_updateCurrent()) + Q_DISABLE_COPY(QQuickButtonGroup) + Q_DECLARE_PRIVATE(QQuickButtonGroup) }; -class Q_LABSTEMPLATES_EXPORT QQuickExclusiveGroupAttached : public QObject +class Q_LABSTEMPLATES_EXPORT QQuickButtonGroupAttached : public QObject { Q_OBJECT - Q_PROPERTY(QQuickExclusiveGroup *group READ group WRITE setGroup NOTIFY groupChanged FINAL) + Q_PROPERTY(QQuickButtonGroup *group READ group WRITE setGroup NOTIFY groupChanged FINAL) public: - explicit QQuickExclusiveGroupAttached(QObject *parent = Q_NULLPTR); + explicit QQuickButtonGroupAttached(QObject *parent = Q_NULLPTR); - QQuickExclusiveGroup *group() const; - void setGroup(QQuickExclusiveGroup *group); + QQuickButtonGroup *group() const; + void setGroup(QQuickButtonGroup *group); Q_SIGNALS: void groupChanged(); private: - Q_DISABLE_COPY(QQuickExclusiveGroupAttached) - Q_DECLARE_PRIVATE(QQuickExclusiveGroupAttached) + Q_DISABLE_COPY(QQuickButtonGroupAttached) + Q_DECLARE_PRIVATE(QQuickButtonGroupAttached) }; -Q_DECLARE_TYPEINFO(QQuickExclusiveGroup, Q_COMPLEX_TYPE); +Q_DECLARE_TYPEINFO(QQuickButtonGroup, Q_COMPLEX_TYPE); QT_END_NAMESPACE -QML_DECLARE_TYPEINFO(QQuickExclusiveGroup, QML_HAS_ATTACHED_PROPERTIES) +QML_DECLARE_TYPEINFO(QQuickButtonGroup, QML_HAS_ATTACHED_PROPERTIES) -#endif // QQUICKEXCLUSIVEGROUP_H +#endif // QQuickButtonGroup_H diff --git a/src/templates/qquickcheckbox.cpp b/src/templates/qquickcheckbox.cpp index 5cef0c47..9a416419 100644 --- a/src/templates/qquickcheckbox.cpp +++ b/src/templates/qquickcheckbox.cpp @@ -37,6 +37,8 @@ #include "qquickcheckbox_p.h" #include "qquickabstractbutton_p_p.h" +#include <QtGui/qpa/qplatformtheme.h> + QT_BEGIN_NAMESPACE /*! @@ -156,6 +158,11 @@ void QQuickCheckBox::setCheckState(Qt::CheckState state) } } +QFont QQuickCheckBox::defaultFont() const +{ + return QQuickControlPrivate::themeFont(QPlatformTheme::CheckBoxFont); +} + void QQuickCheckBox::checkStateSet() { setCheckState(isChecked() ? Qt::Checked : Qt::Unchecked); diff --git a/src/templates/qquickcheckbox_p.h b/src/templates/qquickcheckbox_p.h index f347ef82..5cf97476 100644 --- a/src/templates/qquickcheckbox_p.h +++ b/src/templates/qquickcheckbox_p.h @@ -74,6 +74,8 @@ Q_SIGNALS: void checkStateChanged(); protected: + QFont defaultFont() const Q_DECL_OVERRIDE; + void checkStateSet() Q_DECL_OVERRIDE; void nextCheckState() Q_DECL_OVERRIDE; diff --git a/src/templates/qquickcontainer.cpp b/src/templates/qquickcontainer.cpp index ce2031a5..90c46e14 100644 --- a/src/templates/qquickcontainer.cpp +++ b/src/templates/qquickcontainer.cpp @@ -37,6 +37,8 @@ #include "qquickcontainer_p.h" #include "qquickcontainer_p_p.h" +#include <QtQuick/private/qquickflickable_p.h> + QT_BEGIN_NAMESPACE /*! @@ -52,6 +54,14 @@ QT_BEGIN_NAMESPACE \sa {Container Controls} */ +static QQuickItem *effectiveContentItem(QQuickItem *item) +{ + QQuickFlickable *flickable = qobject_cast<QQuickFlickable *>(item); + if (flickable) + return flickable->contentItem(); + return item; +} + QQuickContainerPrivate::QQuickContainerPrivate() : contentModel(Q_NULLPTR), currentIndex(-1), updatingCurrent(false) { } @@ -87,10 +97,13 @@ QQuickItem *QQuickContainerPrivate::itemAt(int index) const void QQuickContainerPrivate::insertItem(int index, QQuickItem *item) { Q_Q(QQuickContainer); - contentData.append(item); if (!q->isContent(item)) return; + contentData.append(item); + updatingCurrent = true; + + item->setParentItem(effectiveContentItem(contentItem)); QQuickItemPrivate::get(item)->addItemChangeListener(this, QQuickItemPrivate::Destroyed | QQuickItemPrivate::Parent); contentModel->insert(index, item); @@ -100,28 +113,36 @@ void QQuickContainerPrivate::insertItem(int index, QQuickItem *item) Q_Q(QQuickContainer); q->setCurrentIndex(index); } + + updatingCurrent = false; } void QQuickContainerPrivate::moveItem(int from, int to) { Q_Q(QQuickContainer); + int oldCurrent = currentIndex; contentModel->move(from, to); + updatingCurrent = true; - if (from == currentIndex) + + if (from == oldCurrent) q->setCurrentIndex(to); - else if (from < currentIndex && to >= currentIndex) - q->setCurrentIndex(currentIndex - 1); - else if (from > currentIndex && to <= currentIndex) - q->setCurrentIndex(currentIndex + 1); + else if (from < oldCurrent && to >= oldCurrent) + q->setCurrentIndex(oldCurrent - 1); + else if (from > oldCurrent && to <= oldCurrent) + q->setCurrentIndex(oldCurrent + 1); + updatingCurrent = false; } void QQuickContainerPrivate::removeItem(int index, QQuickItem *item) { Q_Q(QQuickContainer); - contentData.removeOne(item); if (!q->isContent(item)) return; + contentData.removeOne(item); + + updatingCurrent = true; bool currentChanged = false; if (index == currentIndex) { @@ -139,6 +160,8 @@ void QQuickContainerPrivate::removeItem(int index, QQuickItem *item) if (currentChanged) emit q->currentIndexChanged(); + + updatingCurrent = false; } void QQuickContainerPrivate::_q_currentIndexChanged() @@ -151,7 +174,7 @@ void QQuickContainerPrivate::_q_currentIndexChanged() void QQuickContainerPrivate::itemChildAdded(QQuickItem *, QQuickItem *child) { // add dynamically reparented items (eg. by a Repeater) - if (!QQuickItemPrivate::get(child)->isTransparentForPositioner() && contentModel->indexOf(child, Q_NULLPTR) == -1) + if (!QQuickItemPrivate::get(child)->isTransparentForPositioner() && !contentData.contains(child)) insertItem(contentModel->count(), child); } @@ -166,7 +189,7 @@ void QQuickContainerPrivate::itemSiblingOrderChanged(QQuickItem *) { // reorder the restacked items (eg. by a Repeater) Q_Q(QQuickContainer); - QList<QQuickItem *> siblings = contentItem->childItems(); + QList<QQuickItem *> siblings = effectiveContentItem(contentItem)->childItems(); for (int i = 0; i < siblings.count(); ++i) { QQuickItem* sibling = siblings.at(i); int index = contentModel->indexOf(sibling, Q_NULLPTR); @@ -189,7 +212,7 @@ void QQuickContainerPrivate::contentData_append(QQmlListProperty<QObject> *prop, if (item) { if (QQuickItemPrivate::get(item)->isTransparentForPositioner()) { QQuickItemPrivate::get(item)->addItemChangeListener(p, QQuickItemPrivate::SiblingOrder); - item->setParentItem(p->contentItem); + item->setParentItem(effectiveContentItem(p->contentItem)); } else if (p->contentModel->indexOf(item, Q_NULLPTR) == -1) { q->addItem(item); } @@ -454,6 +477,9 @@ void QQuickContainer::contentItemChange(QQuickItem *newItem, QQuickItem *oldItem if (oldItem) { QQuickItemPrivate::get(oldItem)->removeItemChangeListener(d, QQuickItemPrivate::Children); + QQuickItem *oldContentItem = effectiveContentItem(oldItem); + if (oldContentItem != oldItem) + QQuickItemPrivate::get(oldContentItem)->removeItemChangeListener(d, QQuickItemPrivate::Children); int signalIndex = oldItem->metaObject()->indexOfSignal("currentIndexChanged()"); if (signalIndex != -1) @@ -462,6 +488,9 @@ void QQuickContainer::contentItemChange(QQuickItem *newItem, QQuickItem *oldItem if (newItem) { QQuickItemPrivate::get(newItem)->addItemChangeListener(d, QQuickItemPrivate::Children); + QQuickItem *newContentItem = effectiveContentItem(newItem); + if (newContentItem != newItem) + QQuickItemPrivate::get(newContentItem)->addItemChangeListener(d, QQuickItemPrivate::Children); int signalIndex = newItem->metaObject()->indexOfSignal("currentIndexChanged()"); if (signalIndex != -1) @@ -471,8 +500,13 @@ void QQuickContainer::contentItemChange(QQuickItem *newItem, QQuickItem *oldItem bool QQuickContainer::isContent(QQuickItem *item) const { - Q_UNUSED(item); - return true; + // If the item has a QML context associated to it (it was created in QML), + // we add it to the content model. Otherwise, it's probably the default + // highlight item that is always created by the item views, which we need + // to exclude. + // + // TODO: Find a better way to identify/exclude the highlight item... + return qmlContext(item); } void QQuickContainer::itemAdded(int index, QQuickItem *item) diff --git a/src/templates/qquickcontrol.cpp b/src/templates/qquickcontrol.cpp index c8b5287b..908abeda 100644 --- a/src/templates/qquickcontrol.cpp +++ b/src/templates/qquickcontrol.cpp @@ -45,6 +45,9 @@ #include "qquicktextfield_p.h" #include "qquicktextfield_p_p.h" +#include <QtGui/private/qguiapplication_p.h> +#include <QtGui/qpa/qplatformtheme.h> + #ifndef QT_NO_ACCESSIBILITY #include <QtQuick/private/qquickaccessibleattached_p.h> #endif @@ -206,7 +209,14 @@ void QQuickControl::accessibilityActiveChanged(bool active) */ QFont QQuickControlPrivate::naturalControlFont(const QQuickItem *q) { - QFont naturalFont = QGuiApplication::font(); + QFont naturalFont = themeFont(QPlatformTheme::SystemFont); + if (const QQuickControl *qc = qobject_cast<const QQuickControl *>(q)) { + naturalFont = qc->defaultFont(); + } else if (const QQuickLabel *label = qobject_cast<const QQuickLabel *>(q)) { + Q_UNUSED(label); + naturalFont = themeFont(QPlatformTheme::LabelFont); + } + QQuickItem *p = q->parentItem(); while (p) { if (QQuickControl *qc = qobject_cast<QQuickControl *>(p)) { @@ -221,6 +231,16 @@ QFont QQuickControlPrivate::naturalControlFont(const QQuickItem *q) return naturalFont; } +QFont QQuickControlPrivate::themeFont(QPlatformTheme::Font type) +{ + if (QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) { + if (const QFont *font = theme->font(type)) + return *font; + } + + return QGuiApplication::font(); +} + /*! \internal @@ -322,11 +342,18 @@ QQuickControl::QQuickControl(QQuickControlPrivate &dd, QQuickItem *parent) : { } +void QQuickControl::classBegin() +{ + Q_D(QQuickControl); + QQuickItem::classBegin(); + d->resolveFont(); +} + void QQuickControl::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &value) { Q_D(QQuickControl); QQuickItem::itemChange(change, value); - if (change == ItemParentHasChanged) + if (change == ItemParentHasChanged && isComponentComplete()) d->resolveFont(); } @@ -700,6 +727,21 @@ void QQuickControl::setContentItem(QQuickItem *item) } } +void QQuickControl::componentComplete() +{ + Q_D(QQuickControl); + QQuickItem::componentComplete(); +#ifndef QT_NO_ACCESSIBILITY + if (!d->accessibleAttached && QAccessible::isActive()) + accessibilityActiveChanged(true); +#endif +} + +QFont QQuickControl::defaultFont() const +{ + return QQuickControlPrivate::themeFont(QPlatformTheme::SystemFont); +} + void QQuickControl::mousePressEvent(QMouseEvent *event) { event->accept(); diff --git a/src/templates/qquickcontrol_p.h b/src/templates/qquickcontrol_p.h index d5024bae..346b45b3 100644 --- a/src/templates/qquickcontrol_p.h +++ b/src/templates/qquickcontrol_p.h @@ -136,8 +136,13 @@ Q_SIGNALS: void contentItemChanged(); protected: + virtual QFont defaultFont() const; + QQuickControl(QQuickControlPrivate &dd, QQuickItem *parent); + void classBegin() Q_DECL_OVERRIDE; + void componentComplete() Q_DECL_OVERRIDE; + void itemChange(ItemChange change, const ItemChangeData &value) Q_DECL_OVERRIDE; void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE; diff --git a/src/templates/qquickcontrol_p_p.h b/src/templates/qquickcontrol_p_p.h index 126eab60..ab185952 100644 --- a/src/templates/qquickcontrol_p_p.h +++ b/src/templates/qquickcontrol_p_p.h @@ -48,7 +48,10 @@ // We mean it. // +#include "qquickcontrol_p.h" + #include <QtQuick/private/qquickitem_p.h> +#include <qpa/qplatformtheme.h> #ifndef QT_NO_ACCESSIBILITY #include <QtGui/qaccessible.h> @@ -98,6 +101,7 @@ public: } void resolveFont(); static QFont naturalControlFont(const QQuickItem *); + static QFont themeFont(QPlatformTheme::Font type); QFont font; bool hasTopPadding; diff --git a/src/templates/qquickdrawer.cpp b/src/templates/qquickdrawer.cpp index 8752c803..a1fdf8f8 100644 --- a/src/templates/qquickdrawer.cpp +++ b/src/templates/qquickdrawer.cpp @@ -44,6 +44,50 @@ QT_BEGIN_NAMESPACE +/*! + \qmltype Drawer + \inherits Container + \instantiates QQuickDrawer + \inqmlmodule Qt.labs.controls + \ingroup qtlabscontrols-navigation + \ingroup qtlabscontrols-containers + \brief A side panel control. + + Drawer provides a swipe-based side panel, similar to those often used in + touch interfaces to provide a central location for navigation. + + \table + \row + \li \image qtlabscontrols-drawer-wireframe.png + Drawer can be positioned at any of the four edges of the content item. \br + In this image, it is against the left edge of the window. + + \li \image qtlabscontrols-drawer-expanded-wireframe.png + The drawer is then opened by \e "dragging" it out from the left edge \br + of the window. + \endtable + + In the image above, the application's contents are \e "pushed" across the + screen. This is achieved by applying a translation to the contents: + + \code + transform: Translate { + x: (1.0 - drawer.position) * listview.width + } + \endcode + + If you would like the application's contents to stay where they are when + the drawer is opened, don't apply a translation. + + \sa SwipeView, {Customizing Drawer}, {Navigation Controls}, {Container Controls} +*/ + +/*! + \qmlsignal Qt.labs.controls::Drawer::clicked() + + This signal is emitted when the drawer is clicked. +*/ + class QQuickDrawerPrivate : public QQuickControlPrivate { Q_DECLARE_PUBLIC(QQuickDrawer) @@ -206,6 +250,17 @@ QQuickDrawer::QQuickDrawer(QQuickItem *parent) : setAcceptedMouseButtons(Qt::LeftButton); } +/*! + \qmlproperty enumeration Qt.labs.controls::Drawer::edge + + This property holds the edge of the content item at which the drawer will + open from. The acceptable values are: + + \value Qt.TopEdge The top edge of the content item. + \value Qt.LeftEdge The left edge of the content item (default). + \value Qt.RightEdge The right edge of the content item. + \value Qt.BottomEdge The bottom edge of the content item. +*/ Qt::Edge QQuickDrawer::edge() const { Q_D(const QQuickDrawer); @@ -223,6 +278,13 @@ void QQuickDrawer::setEdge(Qt::Edge edge) } } +/*! + \qmlproperty real Qt.labs.controls::Drawer::position + + This property holds the position of the drawer relative to its final + destination. That is, the position will be \c 0 when the drawer + is fully closed, and \c 1 when fully open. +*/ qreal QQuickDrawer::position() const { Q_D(const QQuickDrawer); @@ -241,6 +303,12 @@ void QQuickDrawer::setPosition(qreal position) } } + +/*! + \qmlproperty Item Qt.labs.controls::Drawer::contentItem + + This property holds the content item that the drawer displays when opened. +*/ QQuickItem *QQuickDrawer::contentItem() const { Q_D(const QQuickDrawer); @@ -261,6 +329,14 @@ void QQuickDrawer::setContentItem(QQuickItem *item) } } +/*! + \qmlproperty Animation Qt.labs.controls::Drawer::animation + + This property holds the animation for the \l position property. It is used + to animate the drawer's movement. + + If no valid animation is set, the drawer's movement will not be animated. +*/ QQuickPropertyAnimation *QQuickDrawer::animation() const { Q_D(const QQuickDrawer); @@ -281,6 +357,12 @@ void QQuickDrawer::setAnimation(QQuickPropertyAnimation *animation) } } +/*! + \qmlmethod void Qt.labs.controls::Drawer::open() + + This method opens the drawer, animating the movement if a valid + \l animation has been set. +*/ void QQuickDrawer::open() { Q_D(QQuickDrawer); @@ -294,6 +376,12 @@ void QQuickDrawer::open() } } +/*! + \qmlmethod void Qt.labs.controls::Drawer::close() + + This method closes the drawer, animating the movement if a valid + \l animation has been set. +*/ void QQuickDrawer::close() { Q_D(QQuickDrawer); diff --git a/src/templates/qquickexclusivegroup.cpp b/src/templates/qquickexclusivegroup.cpp deleted file mode 100644 index f583df8f..00000000 --- a/src/templates/qquickexclusivegroup.cpp +++ /dev/null @@ -1,422 +0,0 @@ -/**************************************************************************** -** -** 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 "qquickexclusivegroup_p.h" -#include <QtCore/private/qobject_p.h> -#include <QtCore/qmetaobject.h> -#include <QtCore/qvariant.h> -#include <QtQml/qqmlinfo.h> - -QT_BEGIN_NAMESPACE - -/*! - \qmltype ExclusiveGroup - \inherits QtObject - \instantiates QQuickExclusiveGroup - \inqmlmodule Qt.labs.controls - \ingroup utilities - \brief An exclusive group of checkable controls. - - ExclusiveGroup is a non-visual, mutually exclusive group of checkable - controls and objects. It is used with controls such as RadioButton, - where only one of the options can be selected at a time. - - Any control or object that has a \c checked property, and either a - \c checkedChanged(), \c toggled(), or \c toggled(bool) signal, can be - added to an ExclusiveGroup. - - The most straight-forward way to use ExclusiveGroup is to assign - a list of checkable items. For example, the list of children of a - \l{Item Positioners}{positioner} or a \l{Qt Quick Layouts}{layout} - that manages a group of mutually exclusive controls. - - \code - ExclusiveGroup { - checkables: column.children - } - - Column { - id: column - - RadioButton { - checked: true - text: qsTr("DAB") - } - - RadioButton { - text: qsTr("FM") - } - - RadioButton { - text: qsTr("AM") - } - } - \endcode - - Mutually exclusive controls do not always share the same parent item, - or the parent layout may sometimes contain items that should not be - included to the exclusive group. Such cases are best handled using - the \l group attached property. - - \code - ExclusiveGroup { id: radioGroup } - - Column { - Label { - text: qsTr("Radio:") - } - - RadioButton { - checked: true - text: qsTr("DAB") - ExclusiveGroup.group: radioGroup - } - - RadioButton { - text: qsTr("FM") - ExclusiveGroup.group: radioGroup - } - - RadioButton { - text: qsTr("AM") - ExclusiveGroup.group: radioGroup - } - } - \endcode - - More advanced use cases can be handled using the addCheckable() and - removeCheckable() methods. - - \sa RadioButton -*/ - -#define CHECKED_PROPERTY "checked" - -static const char *checkableSignals[] = { - CHECKED_PROPERTY"Changed()", - "toggled(bool)", - "toggled()", - 0 -}; - -static QMetaMethod checkableSignal(QObject *object) -{ - const QMetaObject *mo = object->metaObject(); - for (const char **signal = checkableSignals; *signal; ++signal) { - int index = mo->indexOfSignal(*signal); - if (index != -1) - return mo->method(index); - } - return QMetaMethod(); -} - -static bool isChecked(const QObject *object) -{ - if (!object) - return false; - QVariant checked = object->property(CHECKED_PROPERTY); - return checked.isValid() && checked.toBool(); -} - -class QQuickExclusiveGroupPrivate : public QObjectPrivate -{ - Q_DECLARE_PUBLIC(QQuickExclusiveGroup) - -public: - QQuickExclusiveGroupPrivate() : current(Q_NULLPTR) { } - - void _q_updateCurrent(); - - static void checkables_append(QQmlListProperty<QObject> *prop, QObject *obj); - static int checkables_count(QQmlListProperty<QObject> *prop); - static QObject *checkables_at(QQmlListProperty<QObject> *prop, int index); - static void checkables_clear(QQmlListProperty<QObject> *prop); - - QObject *current; - QObjectList checkables; - QMetaMethod updateCurrentMethod; -}; - -void QQuickExclusiveGroupPrivate::_q_updateCurrent() -{ - Q_Q(QQuickExclusiveGroup); - QObject *object = q->sender(); - if (isChecked(object)) - q->setCurrent(object); -} - -void QQuickExclusiveGroupPrivate::checkables_append(QQmlListProperty<QObject> *prop, QObject *obj) -{ - QQuickExclusiveGroup *q = static_cast<QQuickExclusiveGroup *>(prop->object); - q->addCheckable(obj); -} - -int QQuickExclusiveGroupPrivate::checkables_count(QQmlListProperty<QObject> *prop) -{ - QQuickExclusiveGroupPrivate *p = static_cast<QQuickExclusiveGroupPrivate *>(prop->data); - return p->checkables.count(); -} - -QObject *QQuickExclusiveGroupPrivate::checkables_at(QQmlListProperty<QObject> *prop, int index) -{ - QQuickExclusiveGroupPrivate *p = static_cast<QQuickExclusiveGroupPrivate *>(prop->data); - return p->checkables.value(index); -} - -void QQuickExclusiveGroupPrivate::checkables_clear(QQmlListProperty<QObject> *prop) -{ - QQuickExclusiveGroupPrivate *p = static_cast<QQuickExclusiveGroupPrivate *>(prop->data); - if (!p->checkables.isEmpty()) { - p->checkables.clear(); - QQuickExclusiveGroup *q = static_cast<QQuickExclusiveGroup *>(prop->object); - q->setCurrent(0); - emit q->checkablesChanged(); - } -} - -QQuickExclusiveGroup::QQuickExclusiveGroup(QObject *parent) - : QObject(*(new QQuickExclusiveGroupPrivate), parent) -{ - Q_D(QQuickExclusiveGroup); - int index = metaObject()->indexOfMethod("_q_updateCurrent()"); - d->updateCurrentMethod = metaObject()->method(index); -} - -QQuickExclusiveGroupAttached *QQuickExclusiveGroup::qmlAttachedProperties(QObject *object) -{ - return new QQuickExclusiveGroupAttached(object); -} - -/*! - \qmlproperty QtObject Qt.labs.controls::ExclusiveGroup::current - - This property holds the currently selected object or \c null if there is none. - - By default, it is the first checked object added to the exclusive group. -*/ -QObject *QQuickExclusiveGroup::current() const -{ - Q_D(const QQuickExclusiveGroup); - return d->current; -} - -void QQuickExclusiveGroup::setCurrent(QObject *current) -{ - Q_D(QQuickExclusiveGroup); - if (d->current != current) { - if (d->current) - d->current->setProperty(CHECKED_PROPERTY, false); - d->current = current; - if (current) - current->setProperty(CHECKED_PROPERTY, true); - emit currentChanged(); - } -} - -/*! - \qmlproperty list<Object> Qt.labs.controls::ExclusiveGroup::checkables - \default - - This property holds the list of checkables. - - \code - ExclusiveGroup { - checkables: column.children - } - - Column { - id: column - - RadioButton { - checked: true - text: qsTr("Option A") - } - - RadioButton { - text: qsTr("Option B") - } - } - \endcode - - \sa group -*/ -QQmlListProperty<QObject> QQuickExclusiveGroup::checkables() -{ - Q_D(QQuickExclusiveGroup); - return QQmlListProperty<QObject>(this, d, - QQuickExclusiveGroupPrivate::checkables_append, - QQuickExclusiveGroupPrivate::checkables_count, - QQuickExclusiveGroupPrivate::checkables_at, - QQuickExclusiveGroupPrivate::checkables_clear); -} - -/*! - \qmlmethod bool Qt.labs.controls::ExclusiveGroup::isCheckable(QtObject object) - - Returns \c true if the \a object is checkable, and \c false otherwise. -*/ -bool QQuickExclusiveGroup::isCheckable(QObject *object) const -{ - if (!object) - return false; - - QVariant checked = object->property(CHECKED_PROPERTY); - if (!checked.isValid()) - return false; - - QMetaMethod signal = checkableSignal(object); - return signal.isValid(); -} - -/*! - \qmlmethod void Qt.labs.controls::ExclusiveGroup::addCheckable(QtObject object) - - Adds an \a object to the exclusive group. - - \note Manually adding objects to an exclusive group is typically unnecessary. - The \l checkables property and the \l group attached property provide a - convenient and declarative syntax. - - \sa checkables, group -*/ -void QQuickExclusiveGroup::addCheckable(QObject *object) -{ - Q_D(QQuickExclusiveGroup); - if (!object || d->checkables.contains(object)) - return; - - QMetaMethod signal = checkableSignal(object); - if (signal.isValid()) { - connect(object, signal, this, d->updateCurrentMethod, Qt::UniqueConnection); - connect(object, SIGNAL(destroyed(QObject*)), this, SLOT(removeCheckable(QObject*)), Qt::UniqueConnection); - - if (isChecked(object)) - setCurrent(object); - - d->checkables.append(object); - emit checkablesChanged(); - } else { - qmlInfo(this) << "The object has no checkedChanged() or toggled() signal."; - } -} - -/*! - \qmlmethod void Qt.labs.controls::ExclusiveGroup::removeCheckable(QtObject object) - - Removes an \a object from the exclusive group. - - \note Manually removing objects from an exclusive group is typically unnecessary. - The \l checkables property and the \l group attached property provide a - convenient and declarative syntax. - - \sa checkables, group -*/ -void QQuickExclusiveGroup::removeCheckable(QObject *object) -{ - Q_D(QQuickExclusiveGroup); - if (!object || !d->checkables.contains(object)) - return; - - QMetaMethod signal = checkableSignal(object); - if (signal.isValid()) { - if (disconnect(object, signal, this, d->updateCurrentMethod)) - disconnect(object, SIGNAL(destroyed(QObject*)), this, SLOT(removeCheckable(QObject*))); - } - - if (d->current == object) - setCurrent(Q_NULLPTR); - - d->checkables.removeOne(object); - emit checkablesChanged(); -} - -class QQuickExclusiveGroupAttachedPrivate : public QObjectPrivate -{ -public: - QQuickExclusiveGroupAttachedPrivate() : group(Q_NULLPTR) { } - - QQuickExclusiveGroup *group; -}; - -QQuickExclusiveGroupAttached::QQuickExclusiveGroupAttached(QObject *parent) : - QObject(*(new QQuickExclusiveGroupAttachedPrivate), parent) -{ -} - -/*! - \qmlattachedproperty ExclusiveGroup Qt.labs.controls::ExclusiveGroup::group - - This property attaches a checkable control or object to an exclusive group. - - \code - ExclusiveGroup { id: group } - - RadioButton { - checked: true - text: qsTr("Option A") - ExclusiveGroup.group: group - } - - RadioButton { - text: qsTr("Option B") - ExclusiveGroup.group: group - } - \endcode - - \sa checkables -*/ -QQuickExclusiveGroup *QQuickExclusiveGroupAttached::group() const -{ - Q_D(const QQuickExclusiveGroupAttached); - return d->group; -} - -void QQuickExclusiveGroupAttached::setGroup(QQuickExclusiveGroup *group) -{ - Q_D(QQuickExclusiveGroupAttached); - if (d->group != group) { - if (d->group) - d->group->removeCheckable(parent()); - d->group = group; - if (group) - group->addCheckable(parent()); - emit groupChanged(); - } -} - -QT_END_NAMESPACE - -#include "moc_qquickexclusivegroup_p.cpp" diff --git a/src/templates/qquickgroupbox.cpp b/src/templates/qquickgroupbox.cpp index 1f1e5f2f..2f120879 100644 --- a/src/templates/qquickgroupbox.cpp +++ b/src/templates/qquickgroupbox.cpp @@ -37,6 +37,8 @@ #include "qquickgroupbox_p.h" #include "qquickframe_p_p.h" +#include <QtGui/qpa/qplatformtheme.h> + QT_BEGIN_NAMESPACE /*! @@ -122,4 +124,9 @@ void QQuickGroupBox::setLabel(QQuickItem *label) } } +QFont QQuickGroupBox::defaultFont() const +{ + return QQuickControlPrivate::themeFont(QPlatformTheme::MdiSubWindowTitleFont); // tmp +} + QT_END_NAMESPACE diff --git a/src/templates/qquickgroupbox_p.h b/src/templates/qquickgroupbox_p.h index dfaa6de0..5dcfe971 100644 --- a/src/templates/qquickgroupbox_p.h +++ b/src/templates/qquickgroupbox_p.h @@ -73,6 +73,9 @@ Q_SIGNALS: void titleChanged(); void labelChanged(); +protected: + QFont defaultFont() const Q_DECL_OVERRIDE; + private: Q_DISABLE_COPY(QQuickGroupBox) Q_DECLARE_PRIVATE(QQuickGroupBox) diff --git a/src/templates/qquickitemdelegate.cpp b/src/templates/qquickitemdelegate.cpp new file mode 100644 index 00000000..7e13b638 --- /dev/null +++ b/src/templates/qquickitemdelegate.cpp @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** 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 "qquickitemdelegate_p.h" + +QT_BEGIN_NAMESPACE + +/*! + \qmltype ItemDelegate + \inherits AbstractButton + \instantiates QQuickItemDelegate + \inqmlmodule Qt.labs.controls + \brief An item delegate. + + ItemDelegate presents a standard view item. It can be used as a delegate + in various views and controls, such as \l ListView and \l ComboBox. + + ItemDelegate inherits its API from AbstractButton. For instance, you can set + \l {AbstractButton::text}{text}, make items \l {AbstractButton::checkable}{checkable}, + and react to \l {AbstractButton::clicked}{clicks} using the AbstractButton API. + + \snippet qtlabscontrols-itemdelegate.qml 1 + + \sa {Customizing ItemDelegate} +*/ + +QQuickItemDelegate::QQuickItemDelegate(QQuickItem *parent) : QQuickAbstractButton(parent) +{ +} + +#ifndef QT_NO_ACCESSIBILITY +QAccessible::Role QQuickItemDelegate::accessibleRole() const +{ + return QAccessible::ListItem; +} +#endif + +QT_END_NAMESPACE diff --git a/src/templates/qquickitemdelegate_p.h b/src/templates/qquickitemdelegate_p.h new file mode 100644 index 00000000..e3f415a6 --- /dev/null +++ b/src/templates/qquickitemdelegate_p.h @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** 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 QQUICKITEMDELEGATE_P_H +#define QQUICKITEMDELEGATE_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/qquickabstractbutton_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickItemDelegatePrivate; + +class Q_LABSTEMPLATES_EXPORT QQuickItemDelegate : public QQuickAbstractButton +{ + Q_OBJECT + +public: + explicit QQuickItemDelegate(QQuickItem *parent = Q_NULLPTR); + +protected: +#ifndef QT_NO_ACCESSIBILITY + QAccessible::Role accessibleRole() const Q_DECL_OVERRIDE; +#endif + +private: + Q_DISABLE_COPY(QQuickItemDelegate) + Q_DECLARE_PRIVATE(QQuickItemDelegate) +}; + +Q_DECLARE_TYPEINFO(QQuickItemDelegate, Q_COMPLEX_TYPE); + +QT_END_NAMESPACE + +#endif // QQUICKITEMDELEGATE_P_H diff --git a/src/templates/qquicklabel.cpp b/src/templates/qquicklabel.cpp index 2b4b9a12..d2c86037 100644 --- a/src/templates/qquicklabel.cpp +++ b/src/templates/qquicklabel.cpp @@ -205,6 +205,21 @@ void QQuickLabel::setBackground(QQuickItem *background) } } +void QQuickLabel::classBegin() +{ + Q_D(QQuickLabel); + QQuickText::classBegin(); + d->resolveFont(); +} + +void QQuickLabel::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &value) +{ + Q_D(QQuickLabel); + QQuickText::itemChange(change, value); + if (change == ItemParentHasChanged && isComponentComplete()) + d->resolveFont(); +} + void QQuickLabel::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) { Q_D(QQuickLabel); diff --git a/src/templates/qquicklabel_p.h b/src/templates/qquicklabel_p.h index 77258e84..d753320d 100644 --- a/src/templates/qquicklabel_p.h +++ b/src/templates/qquicklabel_p.h @@ -76,6 +76,9 @@ Q_SIGNALS: void backgroundChanged(); protected: + void classBegin() Q_DECL_OVERRIDE; + + void itemChange(ItemChange change, const ItemChangeData &value) Q_DECL_OVERRIDE; void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) Q_DECL_OVERRIDE; private: diff --git a/src/templates/qquickmenu.cpp b/src/templates/qquickmenu.cpp new file mode 100644 index 00000000..b21a7a3e --- /dev/null +++ b/src/templates/qquickmenu.cpp @@ -0,0 +1,455 @@ +/**************************************************************************** +** +** 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 "qquickmenu_p.h" +#include "qquickmenu_p_p.h" +#include "qquickpanel_p_p.h" +#include "qquickmenuitem_p.h" + +#include <QtGui/qevent.h> +#include <QtQml/private/qqmlobjectmodel_p.h> +#include <QtQuick/private/qquickitem_p.h> +#include <QtQuick/private/qquickitemchangelistener_p.h> +#include <QtQuick/private/qquickflickable_p.h> +#include <QtQuick/private/qquickevents_p_p.h> + +QT_BEGIN_NAMESPACE + +/*! + \qmltype Menu + \inherits Panel + \instantiates QQuickMenu + \inqmlmodule Qt.labs.controls + \ingroup qtlabscontrols-menus + \brief A menu control. + + \image qtlabscontrols-menu.png + + Menu has two main use cases: + \list + \li Context menus; for example, a menu that is shown after right clicking + \li Popup menus; for example, a menu that is shown after clicking a button + \endlist + + \code + Button { + id: fileButton + text: "File" + onClicked: menu.show() + } + Menu { + id: menu + contentItem.y: fileButton.height + + MenuItem { + text: "New..." + } + MenuItem { + text: "Open..." + } + MenuItem { + text: "Save" + } + } + \endcode + + \sa {Customizing Menu}, {Menu Controls} +*/ + +QQuickMenuPrivate::QQuickMenuPrivate() : + contentModel(Q_NULLPTR), + dummyFocusItem(Q_NULLPTR), + ignoreActiveFocusChanges(false) +{ + Q_Q(QQuickMenu); + contentModel = new QQmlObjectModel(q); +} + +QQuickItem *QQuickMenuPrivate::itemAt(int index) const +{ + return qobject_cast<QQuickItem *>(contentModel->get(index)); +} + +void QQuickMenuPrivate::insertItem(int index, QQuickItem *item) +{ + contentData.append(item); + item->setParentItem(contentItem); + QQuickItemPrivate::get(item)->addItemChangeListener(this, QQuickItemPrivate::Destroyed | QQuickItemPrivate::Parent); + contentModel->insert(index, item); +} + +void QQuickMenuPrivate::moveItem(int from, int to) +{ + contentModel->move(from, to); +} + +void QQuickMenuPrivate::removeItem(int index, QQuickItem *item) +{ + contentData.removeOne(item); + + QQuickItemPrivate::get(item)->removeItemChangeListener(this, QQuickItemPrivate::Destroyed | QQuickItemPrivate::Parent); + item->setParentItem(Q_NULLPTR); + contentModel->remove(index); +} + +void QQuickMenuPrivate::itemChildAdded(QQuickItem *, QQuickItem *child) +{ + // add dynamically reparented items (eg. by a Repeater) + if (!QQuickItemPrivate::get(child)->isTransparentForPositioner() && !contentData.contains(child)) + insertItem(contentModel->count(), child); +} + +void QQuickMenuPrivate::itemParentChanged(QQuickItem *item, QQuickItem *parent) +{ + // remove dynamically unparented items (eg. by a Repeater) + if (!parent) + removeItem(contentModel->indexOf(item, Q_NULLPTR), item); +} + +void QQuickMenuPrivate::itemSiblingOrderChanged(QQuickItem *) +{ + // reorder the restacked items (eg. by a Repeater) + Q_Q(QQuickMenu); + QList<QQuickItem *> siblings = contentItem->childItems(); + for (int i = 0; i < siblings.count(); ++i) { + QQuickItem* sibling = siblings.at(i); + int index = contentModel->indexOf(sibling, Q_NULLPTR); + q->moveItem(index, i); + } +} + +void QQuickMenuPrivate::itemDestroyed(QQuickItem *item) +{ + int index = contentModel->indexOf(item, Q_NULLPTR); + if (index != -1) + removeItem(index, item); +} + +void QQuickMenuPrivate::onContentItemChanged() +{ + Q_Q(QQuickMenu); + if (contentItem) { + contentItem->installEventFilter(q); + contentItem->setFlag(QQuickItem::ItemIsFocusScope); + contentItem->setActiveFocusOnTab(true); + + // Trying to give active focus to the contentItem (ListView, by default) + // when the menu first opens, without also giving it to the first delegate item + // doesn't seem to be possible, but this is what we need to do. QMenu behaves + // similarly to this; it receives focus if a button that has it as a menu is clicked, + // and only after pressing tab is the first menu item then given active focus. + if (!dummyFocusItem) { + dummyFocusItem = new QQuickItem(contentItem); + dummyFocusItem->setObjectName(QStringLiteral("dummyMenuFocusItem")); + } else { + dummyFocusItem->setParentItem(contentItem); + } + + dummyFocusItem->setActiveFocusOnTab(true); + dummyFocusItem->stackBefore(contentItem->childItems().first()); + + QObjectPrivate::connect(q, &QQuickMenu::visibleChanged, this, &QQuickMenuPrivate::onMenuVisibleChanged); + QObjectPrivate::connect(dummyFocusItem, &QQuickItem::activeFocusChanged, this, &QQuickMenuPrivate::maybeUnsetDummyFocusOnTab); + } +} + +void QQuickMenuPrivate::onItemPressed() +{ + Q_Q(QQuickMenu); + QQuickItem *item = qobject_cast<QQuickItem*>(q->sender()); + int itemIndex = contentModel->indexOf(item, Q_NULLPTR); + Q_ASSERT(itemIndex != -1); + + if (!contentItem->property("currentIndex").isValid()) + return; + + contentItem->setProperty("currentIndex", itemIndex); +} + +void QQuickMenuPrivate::onItemActiveFocusChanged() +{ + if (ignoreActiveFocusChanges) + return; + + Q_Q(QQuickMenu); + QQuickItem *item = qobject_cast<QQuickItem*>(q->sender()); + if (!item->hasActiveFocus()) + return; + + if (!contentItem->property("currentIndex").isValid()) + return; + + int indexOfItem = contentModel->indexOf(item, Q_NULLPTR); + contentItem->setProperty("currentIndex", indexOfItem); +} + +void QQuickMenuPrivate::onMenuVisibleChanged() +{ + Q_Q(QQuickMenu); + if (q->isVisible()) { + // Don't react to active focus changes here, as we're causing them. + ignoreActiveFocusChanges = true; + for (int i = 0; i < contentModel->count(); ++i) { + QQuickItem *item = qobject_cast<QQuickItem*>(contentModel->get(i)); + item->setFocus(true); + } + ignoreActiveFocusChanges = false; + + // We must do this last so that none of the menu items have focus. + dummyFocusItem->forceActiveFocus(); + } else { + // Ensure that when the menu isn't visible, there's no current item + // the next time it's opened. + if (contentItem->property("currentIndex").isValid()) + contentItem->setProperty("currentIndex", -1); + + // The menu items are sneaky and will steal the focus if they can. + for (int i = 0; i < contentModel->count(); ++i) { + QQuickItem *item = qobject_cast<QQuickItem*>(contentModel->get(i)); + item->setFocus(false); + } + } + +} + +void QQuickMenuPrivate::maybeUnsetDummyFocusOnTab() +{ + if (!dummyFocusItem->hasActiveFocus()) { + // Only unset the flag once the dummy item no longer has focus, otherwise we get warnings. + dummyFocusItem->setActiveFocusOnTab(false); + } +} + +void QQuickMenuPrivate::contentData_append(QQmlListProperty<QObject> *prop, QObject *obj) +{ + QQuickMenuPrivate *p = static_cast<QQuickMenuPrivate *>(prop->data); + QQuickMenu *q = static_cast<QQuickMenu *>(prop->object); + QQuickItem *item = qobject_cast<QQuickItem *>(obj); + if (item) { + if (QQuickItemPrivate::get(item)->isTransparentForPositioner()) { + QQuickItemPrivate::get(item)->addItemChangeListener(p, QQuickItemPrivate::SiblingOrder); + item->setParentItem(p->contentItem); + } else if (p->contentModel->indexOf(item, Q_NULLPTR) == -1) { + q->addItem(item); + + QQuickMenuItem *menuItem = qobject_cast<QQuickMenuItem *>(item); + if (menuItem) { + QObjectPrivate::connect(menuItem, &QQuickMenuItem::pressed, p, &QQuickMenuPrivate::onItemPressed); + QObject::connect(menuItem, &QQuickMenuItem::triggered, q, &QQuickPanel::hide); + QObjectPrivate::connect(menuItem, &QQuickItem::activeFocusChanged, p, &QQuickMenuPrivate::onItemActiveFocusChanged); + } + } + } else { + p->contentData.append(obj); + } +} + +int QQuickMenuPrivate::contentData_count(QQmlListProperty<QObject> *prop) +{ + QQuickMenuPrivate *p = static_cast<QQuickMenuPrivate *>(prop->data); + return p->contentData.count(); +} + +QObject *QQuickMenuPrivate::contentData_at(QQmlListProperty<QObject> *prop, int index) +{ + QQuickMenuPrivate *p = static_cast<QQuickMenuPrivate *>(prop->data); + return p->contentData.value(index); +} + +void QQuickMenuPrivate::contentData_clear(QQmlListProperty<QObject> *prop) +{ + QQuickMenuPrivate *p = static_cast<QQuickMenuPrivate *>(prop->data); + p->contentData.clear(); +} + +QQuickMenu::QQuickMenu(QObject *parent) : + QQuickPanel(*(new QQuickMenuPrivate), parent) +{ + Q_D(QQuickMenu); + connect(this, &QQuickMenu::pressedOutside, this, &QQuickMenu::hide); + connect(this, &QQuickMenu::releasedOutside, this, &QQuickMenu::hide); + QObjectPrivate::connect(this, &QQuickMenu::contentItemChanged, d, &QQuickMenuPrivate::onContentItemChanged); +} + +/*! + \qmlmethod Item Qt.labs.controls::Menu::itemAt(int index) + + Returns the item at \a index, or \c null if it does not exist. +*/ +QQuickItem *QQuickMenu::itemAt(int index) const +{ + Q_D(const QQuickMenu); + return d->itemAt(index); +} + +/*! + \qmlmethod void Qt.labs.controls::Menu::addItem(Item item) + + Adds \a item to the end of the list of items. +*/ +void QQuickMenu::addItem(QQuickItem *item) +{ + Q_D(QQuickMenu); + insertItem(d->contentModel->count(), item); +} + +/*! + \qmlmethod void Qt.labs.controls::Menu::insertItem(int index, Item item) + + Inserts \a item at \a index. +*/ +void QQuickMenu::insertItem(int index, QQuickItem *item) +{ + Q_D(QQuickMenu); + if (!item) + return; + const int count = d->contentModel->count(); + if (index < 0 || index > count) + index = count; + + int oldIndex = d->contentModel->indexOf(item, Q_NULLPTR); + if (oldIndex != -1) { + if (oldIndex < index) + --index; + if (oldIndex != index) + d->moveItem(oldIndex, index); + } else { + d->insertItem(index, item); + } +} + +/*! + \qmlmethod void Qt.labs.controls::Menu::moveItem(int from, int to) + + Moves an item \a from one index \a to another. +*/ +void QQuickMenu::moveItem(int from, int to) +{ + Q_D(QQuickMenu); + const int count = d->contentModel->count(); + if (from < 0 || from > count - 1) + return; + if (to < 0 || to > count - 1) + to = count - 1; + + if (from != to) + d->moveItem(from, to); +} + +/*! + \qmlmethod void Qt.labs.controls::Menu::removeItem(int index) + + Removes an item at \a index. + + \note The ownership of the item is transferred to the caller. +*/ +void QQuickMenu::removeItem(int index) +{ + Q_D(QQuickMenu); + const int count = d->contentModel->count(); + if (index < 0 || index >= count) + return; + + QQuickItem *item = itemAt(index); + if (item) + d->removeItem(index, item); +} + +/*! + \qmlproperty model Qt.labs.controls::Menu::contentModel + \readonly + + This property holds the model used to display menu items. + + By default, the model is an \l ObjectModel, in order to allow declaring + menu items as children of the menu. +*/ +QVariant QQuickMenu::contentModel() const +{ + Q_D(const QQuickMenu); + return QVariant::fromValue(d->contentModel); +} + +/*! + \qmlproperty list<Object> Qt.labs.controls::Menu::contentData + \default + + This property holds the list of content data. + + \sa Item::data +*/ +QQmlListProperty<QObject> QQuickMenu::contentData() +{ + Q_D(QQuickMenu); + return QQmlListProperty<QObject>(this, d, + QQuickMenuPrivate::contentData_append, + QQuickMenuPrivate::contentData_count, + QQuickMenuPrivate::contentData_at, + QQuickMenuPrivate::contentData_clear); +} + +bool QQuickMenu::eventFilter(QObject *object, QEvent *event) +{ + Q_D(QQuickMenu); + if (d->contentModel->count() == 0) + return false; + + if (object != d->contentItem || event->type() != QEvent::KeyRelease) + return false; + + // QTBUG-17051 + // Work around the fact that ListView has no way of distinguishing between + // mouse and keyboard interaction, thanks to the "interactive" bool in Flickable. + // What we actually want is to have a way to always allow keyboard interaction but + // only allow flicking with the mouse when there are too many menu items to be + // shown at once. + QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event); + if (keyEvent->key() == Qt::Key_Up) { + if (d->contentItem->metaObject()->indexOfMethod("decrementCurrentIndex()") != -1) + QMetaObject::invokeMethod(d->contentItem, "decrementCurrentIndex"); + return true; + } else if (keyEvent->key() == Qt::Key_Down) { + if (d->contentItem->metaObject()->indexOfMethod("incrementCurrentIndex()") != -1) + QMetaObject::invokeMethod(d->contentItem, "incrementCurrentIndex"); + return true; + } + + return false; +} + +QT_END_NAMESPACE + +#include "moc_qquickmenu_p.cpp" diff --git a/src/templates/qquickmenu_p.h b/src/templates/qquickmenu_p.h new file mode 100644 index 00000000..cd079d4e --- /dev/null +++ b/src/templates/qquickmenu_p.h @@ -0,0 +1,91 @@ +/**************************************************************************** +** +** 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 QQUICKMENU_P_H +#define QQUICKMENU_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 <QtQml/qqmllist.h> + +#include "qquickpanel_p.h" + +QT_BEGIN_NAMESPACE + +class QQuickMenuItem; +class QQuickMenuPrivate; + +class Q_LABSTEMPLATES_EXPORT QQuickMenu : public QQuickPanel +{ + Q_OBJECT + Q_PROPERTY(QVariant contentModel READ contentModel CONSTANT FINAL) + Q_PROPERTY(QQmlListProperty<QObject> contentData READ contentData FINAL) + Q_CLASSINFO("DefaultProperty", "contentData") + +public: + explicit QQuickMenu(QObject *parent = Q_NULLPTR); + + Q_INVOKABLE QQuickItem *itemAt(int index) const; + Q_INVOKABLE void addItem(QQuickItem *item); + Q_INVOKABLE void insertItem(int index, QQuickItem *item); + Q_INVOKABLE void moveItem(int from, int to); + Q_INVOKABLE void removeItem(int index); + + QVariant contentModel() const; + QQmlListProperty<QObject> contentData(); + +protected: + bool eventFilter(QObject *object, QEvent *event) Q_DECL_OVERRIDE; + +private: + Q_DISABLE_COPY(QQuickMenu) + Q_DECLARE_PRIVATE(QQuickMenu) +}; + +Q_DECLARE_TYPEINFO(QQuickMenu, Q_COMPLEX_TYPE); + +QT_END_NAMESPACE + +#endif // QQUICKMENU_P_H diff --git a/src/templates/qquickmenu_p_p.h b/src/templates/qquickmenu_p_p.h new file mode 100644 index 00000000..166d184b --- /dev/null +++ b/src/templates/qquickmenu_p_p.h @@ -0,0 +1,99 @@ +/**************************************************************************** +** +** 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 QQUICKMENU_P_P_H +#define QQUICKMENU_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qvector.h> +#include <QtQuick/private/qquickitemchangelistener_p.h> + +#include <QtLabsTemplates/private/qquickpanel_p_p.h> + +QT_BEGIN_NAMESPACE + +class QQmlObjectModel; + +class Q_LABSTEMPLATES_EXPORT QQuickMenuPrivate : public QQuickPanelPrivate, public QQuickItemChangeListener +{ + Q_DECLARE_PUBLIC(QQuickMenu) + +public: + QQuickMenuPrivate(); + + QQuickItem *itemAt(int index) const; + void insertItem(int index, QQuickItem *item); + void moveItem(int from, int to); + void removeItem(int index, QQuickItem *item); + + void itemChildAdded(QQuickItem *item, QQuickItem *child) Q_DECL_OVERRIDE; + void itemSiblingOrderChanged(QQuickItem *item) Q_DECL_OVERRIDE; + void itemParentChanged(QQuickItem *item, QQuickItem *parent) Q_DECL_OVERRIDE; + void itemDestroyed(QQuickItem *item) Q_DECL_OVERRIDE; + + void onContentItemChanged(); + void onItemPressed(); + void onItemActiveFocusChanged(); + void onMenuVisibleChanged(); + void maybeUnsetDummyFocusOnTab(); + + static void contentData_append(QQmlListProperty<QObject> *prop, QObject *obj); + static int contentData_count(QQmlListProperty<QObject> *prop); + static QObject *contentData_at(QQmlListProperty<QObject> *prop, int index); + static void contentData_clear(QQmlListProperty<QObject> *prop); + + QVector<QObject *> contentData; + QQmlObjectModel *contentModel; + QQuickItem *dummyFocusItem; + 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 new file mode 100644 index 00000000..83696535 --- /dev/null +++ b/src/templates/qquickmenuitem.cpp @@ -0,0 +1,99 @@ +/**************************************************************************** +** +** 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 "qquickmenuitem_p.h" +#include "qquickabstractbutton_p_p.h" + +#include <QtQuick/private/qquickevents_p_p.h> + +QT_BEGIN_NAMESPACE + +/*! + \qmltype MenuItem + \inherits Control + \instantiates QQuickMenuItem + \inqmlmodule Qt.labs.controls + \ingroup qtlabscontrols-menus + \brief A menu item within a Menu. + + MenuItem is a convenience type that implements the AbstractButton API, + providing an easy way to respond to menu items being clicked, for example. + + \code + Button { + id: fileButton + text: "File" + onClicked: menu.show() + } + Menu { + id: menu + anchor.target: fileButton + + MenuItem { + text: "New..." + } + MenuItem { + text: "Open..." + } + MenuItem { + text: "Save" + } + } + \endcode + + \sa {Customizing MenuItem}, {Menu Controls} +*/ + +/*! + \qmlsignal void Qt.labs.controls::MenuItem::triggered() + + This signal is emitted when the menu item is triggered by the user. +*/ + +QQuickMenuItem::QQuickMenuItem(QQuickItem *parent) : + QQuickAbstractButton(parent) +{ + connect(this, &QQuickAbstractButton::clicked, this, &QQuickMenuItem::triggered); +} + +#ifndef QT_NO_ACCESSIBILITY +QAccessible::Role QQuickMenuItem::accessibleRole() const +{ + return QAccessible::MenuItem; +} +#endif + +QT_END_NAMESPACE diff --git a/src/templates/qquickmenuitem_p.h b/src/templates/qquickmenuitem_p.h new file mode 100644 index 00000000..3f86fe2e --- /dev/null +++ b/src/templates/qquickmenuitem_p.h @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** 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 QQUICKMENUITEM_P_H +#define QQUICKMENUITEM_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/qquickabstractbutton_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickMenuItemPrivate; + +class Q_LABSTEMPLATES_EXPORT QQuickMenuItem : public QQuickAbstractButton +{ + Q_OBJECT + +public: + explicit QQuickMenuItem(QQuickItem *parent = Q_NULLPTR); + +Q_SIGNALS: + void triggered(); + +protected: +#ifndef QT_NO_ACCESSIBILITY + QAccessible::Role accessibleRole() const Q_DECL_OVERRIDE; +#endif + +private: + Q_DISABLE_COPY(QQuickMenuItem) + Q_DECLARE_PRIVATE(QQuickMenuItem) +}; + +Q_DECLARE_TYPEINFO(QQuickMenuItem, Q_COMPLEX_TYPE); + +QT_END_NAMESPACE + +#endif // QQUICKMENUITEM_P_H diff --git a/src/templates/qquickoverlay.cpp b/src/templates/qquickoverlay.cpp new file mode 100644 index 00000000..4a00387a --- /dev/null +++ b/src/templates/qquickoverlay.cpp @@ -0,0 +1,147 @@ +/**************************************************************************** +** +** 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 "qquickoverlay_p.h" +#include "qquickpanel_p.h" +#include <QtQml/qqmlinfo.h> +#include <QtQuick/private/qquickitem_p.h> + +QT_BEGIN_NAMESPACE + +QQuickOverlay::QQuickOverlay(QQuickItem *parent) + : QQuickItem(parent), m_modalPanels(0) +{ + setAcceptedMouseButtons(Qt::AllButtons); + setFiltersChildMouseEvents(true); + setVisible(false); +} + +void QQuickOverlay::itemChange(ItemChange change, const ItemChangeData &data) +{ + QQuickItem::itemChange(change, data); + + QQuickItem *panelItem = const_cast<QQuickItem *>(data.item); + QQuickPanel *panel = Q_NULLPTR; + if (change == ItemChildAddedChange || change == ItemChildRemovedChange) { + panel = qobject_cast<QQuickPanel *>(panelItem->parent()); + setVisible(!childItems().isEmpty()); + } + if (!panel) + return; + + if (change == ItemChildAddedChange) { + if (QQuickPanel *prevPanel = m_panels.value(panelItem)) { + qmlInfo(panel).nospace() << "Panel is sharing item " << panelItem << " with " << prevPanel + << ". This is not supported and strange things are about to happen."; + return; + } + + m_panels.insert(panelItem, panel); + if (panel->isModal()) + ++m_modalPanels; + + connect(this, &QQuickOverlay::pressed, panel, &QQuickPanel::pressedOutside); + connect(this, &QQuickOverlay::released, panel, &QQuickPanel::releasedOutside); + } else if (change == ItemChildRemovedChange) { + Q_ASSERT(panel == m_panels.value(panelItem)); + + disconnect(this, &QQuickOverlay::pressed, panel, &QQuickPanel::pressedOutside); + disconnect(this, &QQuickOverlay::released, panel, &QQuickPanel::releasedOutside); + + if (panel->isModal()) + --m_modalPanels; + m_panels.remove(panelItem); + } +} + +void QQuickOverlay::keyPressEvent(QKeyEvent *event) +{ + event->setAccepted(m_modalPanels > 0); +} + +void QQuickOverlay::keyReleaseEvent(QKeyEvent *event) +{ + event->setAccepted(m_modalPanels > 0); +} + +void QQuickOverlay::mousePressEvent(QMouseEvent *event) +{ + event->setAccepted(m_modalPanels > 0); + emit pressed(); +} + +void QQuickOverlay::mouseMoveEvent(QMouseEvent *event) +{ + event->setAccepted(m_modalPanels > 0); +} + +void QQuickOverlay::mouseReleaseEvent(QMouseEvent *event) +{ + event->setAccepted(m_modalPanels > 0); + emit released(); +} + +bool QQuickOverlay::childMouseEventFilter(QQuickItem *item, QEvent *event) +{ + if (m_modalPanels == 0) + return false; + // TODO Filter touch events + if (event->type() != QEvent::MouseButtonPress) + return false; + while (item->parentItem() != this) + item = item->parentItem(); + + bool modalBlocked = false; + 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) + break; + + QQuickPanel *panel = m_panels.value(panelItem); + if (panel) { + emit panel->pressedOutside(); + + if (!modalBlocked && panel->isModal()) + modalBlocked = true; + } + } + + return modalBlocked; +} + +QT_END_NAMESPACE diff --git a/src/templates/qquickoverlay_p.h b/src/templates/qquickoverlay_p.h new file mode 100644 index 00000000..c5f9b719 --- /dev/null +++ b/src/templates/qquickoverlay_p.h @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** 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 QQUICKOVERLAY_P_H +#define QQUICKOVERLAY_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuick/qquickitem.h> + +QT_BEGIN_NAMESPACE + +class QQuickPanel; + +class QQuickOverlay : public QQuickItem +{ + Q_OBJECT + +public: + explicit QQuickOverlay(QQuickItem *parent = Q_NULLPTR); + +Q_SIGNALS: + void pressed(); + void released(); + +protected: + void itemChange(ItemChange change, const ItemChangeData &data) 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; + bool childMouseEventFilter(QQuickItem *item, QEvent *event) Q_DECL_OVERRIDE; + +private: + Q_DISABLE_COPY(QQuickOverlay) + QHash<QQuickItem *, QQuickPanel *> m_panels; + int m_modalPanels; +}; + +QT_END_NAMESPACE + +#endif // QQUICKOVERLAY_P_H diff --git a/src/templates/qquickpanel.cpp b/src/templates/qquickpanel.cpp new file mode 100644 index 00000000..38f1a73c --- /dev/null +++ b/src/templates/qquickpanel.cpp @@ -0,0 +1,330 @@ +/**************************************************************************** +** +** 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 "qquickpanel_p.h" +#include "qquickpanel_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> +#include <QtQuick/private/qquickitem_p.h> + +QT_BEGIN_NAMESPACE + +/*! + \qmltype Panel + \inherits QtObject + \instantiates QQuickPanel + \inqmlmodule Qt.labs.controls + \ingroup qtlabscontrols-popups + \brief A popup panel. + + Panel is the base type of popup-like user interface controls. +*/ + +QQuickPanelPrivate::QQuickPanelPrivate() + : QObjectPrivate() + , contentItem(Q_NULLPTR) + , overlay(Q_NULLPTR) + , focus(false) + , modal(false) + , showTransition(Q_NULLPTR) + , hideTransition(Q_NULLPTR) + , transitionManager(this) +{ } + +QQuickPanelPrivate::~QQuickPanelPrivate() +{ } + +void QQuickPanelPrivate::finalizeShowTransition() +{ + if (focus) + contentItem->setFocus(true); +} + +void QQuickPanelPrivate::finalizeHideTransition() +{ + overlay = Q_NULLPTR; + contentItem->setParentItem(Q_NULLPTR); + emit q_func()->visibleChanged(); +} + +QQuickPanelTransitionManager::QQuickPanelTransitionManager(QQuickPanelPrivate *priv) + : QQuickTransitionManager() + , state(Off) + , pp(priv) +{ } + +void QQuickPanelTransitionManager::transitionShow() +{ + if (isRunning()) + return; + QList<QQuickStateAction> actions; + state = Show; + transition(actions, pp->showTransition, pp->contentItem); +} + +void QQuickPanelTransitionManager::transitionHide() +{ + if (isRunning()) + return; + QList<QQuickStateAction> actions; + state = Hide; + transition(actions, pp->hideTransition, pp->contentItem); +} + +void QQuickPanelTransitionManager::finished() +{ + if (state == Show) + pp->finalizeShowTransition(); + else if (state == Hide) + pp->finalizeHideTransition(); + + state = Off; +} + +QQuickPanel::QQuickPanel(QObject *parent) + : QObject(*(new QQuickPanelPrivate), parent) +{ +} + +QQuickPanel::QQuickPanel(QQuickPanelPrivate &dd, QObject *parent) + : QObject(dd, parent) +{ +} + +QQuickPanel::~QQuickPanel() +{ +} + +/*! + \qmlmethod void Qt.labs.controls::Panel::show() + + Shows the panel. +*/ +void QQuickPanel::show() +{ + Q_D(QQuickPanel); + if (!d->contentItem) { + qmlInfo(this) << "no panel 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(); + return; + } + + QQuickWindow *win = Q_NULLPTR; + QObject *p = parent(); + while (p && !win) { + if (QQuickItem *item = qobject_cast<QQuickItem *>(p)) { + win = item->window(); + if (!win) + p = item->parentItem(); + } else { + win = qobject_cast<QQuickWindow *>(p); + if (!win) + p = p->parent(); + } + } + if (!win) { + qmlInfo(this) << "cannot find any window to show panel."; + 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 + qmlInfo(this) << "is not in an ApplicationWindow."; + return; + } + + emit aboutToShow(); + d->transitionManager.transitionShow(); + emit visibleChanged(); +} + +/*! + \qmlmethod void Qt.labs.controls::Panel::hide() + + Hides the panel. +*/ +void QQuickPanel::hide() +{ + Q_D(QQuickPanel); + + if (!d->overlay) { + // TODO This could mean we showed the panel item on a plain QQuickWindow + qmlInfo(this) << "trying to hide non-visible Panel."; + return; + } + + d->contentItem->setFocus(false); + emit aboutToHide(); + d->transitionManager.transitionHide(); +} + +/*! + \qmlproperty Item Qt.labs.controls::Panel::contentItem + + This property holds the content item of the panel. + + The content item is the visual implementation of the panel. When the + panel is made visible, the content item is automatically reparented to + the \l {ApplicationWindow::overlay}{overlay item} of its application + window. +*/ +QQuickItem *QQuickPanel::contentItem() const +{ + Q_D(const QQuickPanel); + return d->contentItem; +} + +void QQuickPanel::setContentItem(QQuickItem *item) +{ + Q_D(QQuickPanel); + 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."; + return; + } + if (d->contentItem != item) { + delete d->contentItem; + d->contentItem = item; + if (item) + QQuickItemPrivate::get(item)->isTabFence = true; + emit contentItemChanged(); + } +} + +/*! + \qmlproperty bool Qt.labs.controls::Panel::focus + + This property holds whether the panel has focus. +*/ +bool QQuickPanel::hasFocus() const +{ + Q_D(const QQuickPanel); + return d->focus; +} + +void QQuickPanel::setFocus(bool focus) +{ + Q_D(QQuickPanel); + if (d->focus == focus) + return; + d->focus = focus; + emit focusChanged(); +} + +/*! + \qmlproperty bool Qt.labs.controls::Panel::modal + + This property holds whether the panel is modal. +*/ +bool QQuickPanel::isModal() const +{ + Q_D(const QQuickPanel); + return d->modal; +} + +void QQuickPanel::setModal(bool modal) +{ + Q_D(QQuickPanel); + if (d->modal == modal) + return; + d->modal = modal; + emit modalChanged(); +} + +/*! + \qmlproperty bool Qt.labs.controls::Panel::visible + + This property holds whether the panel is visible. +*/ +bool QQuickPanel::isVisible() const +{ + Q_D(const QQuickPanel); + return d->overlay != Q_NULLPTR /*&& !d->transitionManager.isRunning()*/; +} + +/*! + \qmlproperty Transition Qt.labs.controls::Panel::showTransition + + This property holds the transition that is applied to the content item + when the panel is shown. +*/ +QQuickTransition *QQuickPanel::showTransition() const +{ + return d_func()->showTransition; +} + +void QQuickPanel::setShowTransition(QQuickTransition *t) +{ + Q_D(QQuickPanel); + if (d->showTransition == t) + return; + d->showTransition = t; + emit showTransitionChanged(); +} + +/*! + \qmlproperty Transition Qt.labs.controls::Panel::hideTransition + + This property holds the transition that is applied to the content item + when the panel is hidden. +*/ +QQuickTransition *QQuickPanel::hideTransition() const +{ + return d_func()->hideTransition; +} + +void QQuickPanel::setHideTransition(QQuickTransition *t) +{ + Q_D(QQuickPanel); + if (d->hideTransition == t) + return; + d->hideTransition = t; + emit hideTransitionChanged(); +} + +QT_END_NAMESPACE + +#include "moc_qquickpanel_p.cpp" diff --git a/src/templates/qquickpanel_p.h b/src/templates/qquickpanel_p.h new file mode 100644 index 00000000..6d6f4df9 --- /dev/null +++ b/src/templates/qquickpanel_p.h @@ -0,0 +1,121 @@ +/**************************************************************************** +** +** 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 QQUICKPANEL_P_H +#define QQUICKPANEL_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qobject.h> +#include <QtLabsTemplates/private/qtlabstemplatesglobal_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickItem; +class QQuickPanelPrivate; +class QQuickTransition; + +class Q_LABSTEMPLATES_EXPORT QQuickPanel : 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) + +public: + explicit QQuickPanel(QObject *parent = Q_NULLPTR); + ~QQuickPanel(); + + QQuickItem *contentItem() const; + void setContentItem(QQuickItem *item); + + bool hasFocus() const; + void setFocus(bool focus); + + bool isModal() const; + void setModal(bool modal); + + bool isVisible() const; + + QQuickTransition *showTransition() const; + void setShowTransition(QQuickTransition *); + + QQuickTransition *hideTransition() const; + void setHideTransition(QQuickTransition *); + +Q_SIGNALS: + void contentItemChanged(); + void focusChanged(); + void modalChanged(); + void visibleChanged(); + void showTransitionChanged(); + void hideTransitionChanged(); + + void pressedOutside(); + void releasedOutside(); + void clickedOutside(); + + void aboutToShow(); + void aboutToHide(); + + +public Q_SLOTS: + void show(); + void hide(); + +protected: + QQuickPanel(QQuickPanelPrivate &dd, QObject *parent); + +private: + Q_DISABLE_COPY(QQuickPanel) + Q_DECLARE_PRIVATE(QQuickPanel) +}; + +QT_END_NAMESPACE + +#endif // QQUICKPANEL_P_H diff --git a/src/templates/qquickpanel_p_p.h b/src/templates/qquickpanel_p_p.h new file mode 100644 index 00000000..42c06cd9 --- /dev/null +++ b/src/templates/qquickpanel_p_p.h @@ -0,0 +1,105 @@ +/**************************************************************************** +** +** 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 QQUICKPANEL_P_P_H +#define QQUICKPANEL_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/private/qobject_p.h> +#include <QtQuick/private/qquicktransitionmanager_p_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickItem; +class QQuickTransition; +class QQuickTransitionManager; +class QQuickPanel; +class QQuickPanelPrivate; +class QQuickOverlay; + +class QQuickPanelTransitionManager : public QQuickTransitionManager +{ +public: + QQuickPanelTransitionManager(QQuickPanelPrivate *); + void transitionShow(); + void transitionHide(); + +protected: + void finished() Q_DECL_OVERRIDE; + +private: + enum TransitionState { + Off, Show, Hide + }; + + TransitionState state; + QQuickPanelPrivate *pp; +}; + +class QQuickPanelPrivate : public QObjectPrivate +{ + Q_DECLARE_PUBLIC(QQuickPanel) + +public: + QQuickPanelPrivate(); + ~QQuickPanelPrivate(); + + void finalizeShowTransition(); + void finalizeHideTransition(); + + QQuickItem *contentItem; + QQuickOverlay *overlay; + bool focus; + bool modal; + QQuickTransition *showTransition; + QQuickTransition *hideTransition; + QQuickPanelTransitionManager transitionManager; +}; + +QT_END_NAMESPACE + +#endif // QQUICKPANEL_P_P_H + diff --git a/src/templates/qquickradiobutton.cpp b/src/templates/qquickradiobutton.cpp index 92a14394..9aca5808 100644 --- a/src/templates/qquickradiobutton.cpp +++ b/src/templates/qquickradiobutton.cpp @@ -35,6 +35,9 @@ ****************************************************************************/ #include "qquickradiobutton_p.h" +#include "qquickcontrol_p_p.h" + +#include <QtGui/qpa/qplatformtheme.h> QT_BEGIN_NAMESPACE @@ -81,7 +84,7 @@ QT_BEGIN_NAMESPACE } \endcode - \sa ExclusiveGroup, {Customizing RadioButton}, {Button Controls} + \sa ButtonGroup, {Customizing RadioButton}, {Button Controls} */ QQuickRadioButton::QQuickRadioButton(QQuickItem *parent) : @@ -91,6 +94,11 @@ QQuickRadioButton::QQuickRadioButton(QQuickItem *parent) : setAutoExclusive(true); } +QFont QQuickRadioButton::defaultFont() const +{ + return QQuickControlPrivate::themeFont(QPlatformTheme::RadioButtonFont); +} + #ifndef QT_NO_ACCESSIBILITY QAccessible::Role QQuickRadioButton::accessibleRole() const { diff --git a/src/templates/qquickradiobutton_p.h b/src/templates/qquickradiobutton_p.h index 87ac919b..1667de22 100644 --- a/src/templates/qquickradiobutton_p.h +++ b/src/templates/qquickradiobutton_p.h @@ -60,6 +60,8 @@ public: explicit QQuickRadioButton(QQuickItem *parent = Q_NULLPTR); protected: + QFont defaultFont() const Q_DECL_OVERRIDE; + #ifndef QT_NO_ACCESSIBILITY QAccessible::Role accessibleRole() const Q_DECL_OVERRIDE; #endif diff --git a/src/templates/qquickscrollbar.cpp b/src/templates/qquickscrollbar.cpp index a2c399c3..f6499004 100644 --- a/src/templates/qquickscrollbar.cpp +++ b/src/templates/qquickscrollbar.cpp @@ -314,6 +314,9 @@ public: void scrollHorizontal(); void scrollVertical(); + void layoutHorizontal(bool move = true); + void layoutVertical(bool move = true); + void itemGeometryChanged(QQuickItem *item, const QRectF &newGeometry, const QRectF &oldGeometry) Q_DECL_OVERRIDE; QQuickFlickable *flickable; @@ -363,27 +366,34 @@ void QQuickScrollBarAttachedPrivate::scrollVertical() flickable->setContentY(cy); } +void QQuickScrollBarAttachedPrivate::layoutHorizontal(bool move) +{ + Q_ASSERT(horizontal && flickable); + horizontal->setWidth(flickable->width()); + if (move) + horizontal->setY(flickable->height() - horizontal->height()); +} + +void QQuickScrollBarAttachedPrivate::layoutVertical(bool move) +{ + Q_ASSERT(vertical && flickable); + vertical->setHeight(flickable->height()); + if (move && !QQuickItemPrivate::get(vertical)->isMirrored()) + vertical->setX(flickable->width() - vertical->width()); +} + void QQuickScrollBarAttachedPrivate::itemGeometryChanged(QQuickItem *item, const QRectF &newGeometry, const QRectF &oldGeometry) { Q_UNUSED(item); + Q_UNUSED(newGeometry); Q_ASSERT(item == flickable); if (horizontal) { - QQuickItemPrivate *p = QQuickItemPrivate::get(horizontal); - if (!p->widthValid) { - horizontal->setWidth(newGeometry.width()); - p->widthValid = false; - } - if (qFuzzyIsNull(horizontal->y()) || qFuzzyCompare(horizontal->y(), oldGeometry.height() - horizontal->height())) - horizontal->setY(newGeometry.height() - horizontal->height()); + bool move = qFuzzyIsNull(horizontal->y()) || qFuzzyCompare(horizontal->y(), oldGeometry.height() - horizontal->height()); + layoutHorizontal(move); } if (vertical) { - QQuickItemPrivate *p = QQuickItemPrivate::get(vertical); - if (!p->heightValid) { - vertical->setHeight(newGeometry.height()); - p->heightValid = false; - } - if (!p->isMirrored() && (qFuzzyIsNull(vertical->x()) || qFuzzyCompare(vertical->x(), oldGeometry.width() - vertical->width()))) - vertical->setX(newGeometry.width() - vertical->width()); + bool move = qFuzzyIsNull(vertical->x()) || qFuzzyCompare(vertical->x(), oldGeometry.width() - vertical->width()); + layoutVertical(move); } } @@ -442,6 +452,7 @@ void QQuickScrollBarAttached::setHorizontal(QQuickScrollBar *horizontal) connect(area, SIGNAL(widthRatioChanged(qreal)), horizontal, SLOT(setSize(qreal))); connect(area, SIGNAL(xPositionChanged(qreal)), horizontal, SLOT(setPosition(qreal))); + d->layoutHorizontal(); horizontal->setSize(area->property("widthRatio").toReal()); horizontal->setPosition(area->property("xPosition").toReal()); } @@ -496,6 +507,7 @@ void QQuickScrollBarAttached::setVertical(QQuickScrollBar *vertical) connect(area, SIGNAL(heightRatioChanged(qreal)), vertical, SLOT(setSize(qreal))); connect(area, SIGNAL(yPositionChanged(qreal)), vertical, SLOT(setPosition(qreal))); + d->layoutVertical(); vertical->setSize(area->property("heightRatio").toReal()); vertical->setPosition(area->property("yPosition").toReal()); } diff --git a/src/templates/qquickscrollindicator.cpp b/src/templates/qquickscrollindicator.cpp index 81a96ac5..94b47e4d 100644 --- a/src/templates/qquickscrollindicator.cpp +++ b/src/templates/qquickscrollindicator.cpp @@ -228,6 +228,9 @@ public: void activateHorizontal(); void activateVertical(); + void layoutHorizontal(bool move = true); + void layoutVertical(bool move = true); + void itemGeometryChanged(QQuickItem *item, const QRectF &newGeometry, const QRectF &oldGeometry) Q_DECL_OVERRIDE; QQuickFlickable *flickable; @@ -245,27 +248,34 @@ void QQuickScrollIndicatorAttachedPrivate::activateVertical() vertical->setActive(flickable->isMovingVertically()); } +void QQuickScrollIndicatorAttachedPrivate::layoutHorizontal(bool move) +{ + Q_ASSERT(horizontal && flickable); + horizontal->setWidth(flickable->width()); + if (move) + horizontal->setY(flickable->height() - horizontal->height()); +} + +void QQuickScrollIndicatorAttachedPrivate::layoutVertical(bool move) +{ + Q_ASSERT(vertical && flickable); + vertical->setHeight(flickable->height()); + if (move && !QQuickItemPrivate::get(vertical)->isMirrored()) + vertical->setX(flickable->width() - vertical->width()); +} + void QQuickScrollIndicatorAttachedPrivate::itemGeometryChanged(QQuickItem *item, const QRectF &newGeometry, const QRectF &oldGeometry) { Q_UNUSED(item); + Q_UNUSED(newGeometry); Q_ASSERT(item == flickable); if (horizontal) { - QQuickItemPrivate *p = QQuickItemPrivate::get(horizontal); - if (!p->widthValid) { - horizontal->setWidth(newGeometry.width()); - p->widthValid = false; - } - if (qFuzzyIsNull(horizontal->y()) || qFuzzyCompare(horizontal->y(), oldGeometry.height() - horizontal->height())) - horizontal->setY(newGeometry.height() - horizontal->height()); + bool move = qFuzzyIsNull(horizontal->y()) || qFuzzyCompare(horizontal->y(), oldGeometry.height() - horizontal->height()); + layoutHorizontal(move); } if (vertical) { - QQuickItemPrivate *p = QQuickItemPrivate::get(vertical); - if (!p->heightValid) { - vertical->setHeight(newGeometry.height()); - p->heightValid = false; - } - if (!p->isMirrored() && (qFuzzyIsNull(vertical->x()) || qFuzzyCompare(vertical->x(), oldGeometry.width() - vertical->width()))) - vertical->setX(newGeometry.width() - vertical->width()); + bool move = qFuzzyIsNull(vertical->x()) || qFuzzyCompare(vertical->x(), oldGeometry.width() - vertical->width()); + layoutVertical(move); } } @@ -322,6 +332,7 @@ void QQuickScrollIndicatorAttached::setHorizontal(QQuickScrollIndicator *horizon connect(area, SIGNAL(widthRatioChanged(qreal)), horizontal, SLOT(setSize(qreal))); connect(area, SIGNAL(xPositionChanged(qreal)), horizontal, SLOT(setPosition(qreal))); + d->layoutHorizontal(); horizontal->setSize(area->property("widthRatio").toReal()); horizontal->setPosition(area->property("xPosition").toReal()); } @@ -374,6 +385,7 @@ void QQuickScrollIndicatorAttached::setVertical(QQuickScrollIndicator *vertical) connect(area, SIGNAL(heightRatioChanged(qreal)), vertical, SLOT(setSize(qreal))); connect(area, SIGNAL(yPositionChanged(qreal)), vertical, SLOT(setPosition(qreal))); + d->layoutVertical(); vertical->setSize(area->property("heightRatio").toReal()); vertical->setPosition(area->property("yPosition").toReal()); } diff --git a/src/templates/qquicktabbutton.cpp b/src/templates/qquicktabbutton.cpp index 23e8a221..07dc533c 100644 --- a/src/templates/qquicktabbutton.cpp +++ b/src/templates/qquicktabbutton.cpp @@ -35,6 +35,9 @@ ****************************************************************************/ #include "qquicktabbutton_p.h" +#include "qquickcontrol_p_p.h" + +#include <QtGui/qpa/qplatformtheme.h> QT_BEGIN_NAMESPACE @@ -62,6 +65,11 @@ QQuickTabButton::QQuickTabButton(QQuickItem *parent) : setAutoExclusive(true); } +QFont QQuickTabButton::defaultFont() const +{ + return QQuickControlPrivate::themeFont(QPlatformTheme::DockWidgetTitleFont); // tmp +} + #ifndef QT_NO_ACCESSIBILITY QAccessible::Role QQuickTabButton::accessibleRole() const { diff --git a/src/templates/qquicktabbutton_p.h b/src/templates/qquicktabbutton_p.h index 820fa365..0170a2b0 100644 --- a/src/templates/qquicktabbutton_p.h +++ b/src/templates/qquicktabbutton_p.h @@ -60,6 +60,8 @@ public: explicit QQuickTabButton(QQuickItem *parent = Q_NULLPTR); protected: + QFont defaultFont() const Q_DECL_OVERRIDE; + #ifndef QT_NO_ACCESSIBILITY QAccessible::Role accessibleRole() const Q_DECL_OVERRIDE; #endif diff --git a/src/templates/qquicktextarea.cpp b/src/templates/qquicktextarea.cpp index 4c23ba9b..c78da815 100644 --- a/src/templates/qquicktextarea.cpp +++ b/src/templates/qquicktextarea.cpp @@ -277,6 +277,21 @@ void QQuickTextArea::setPlaceholderText(const QString &text) } } +void QQuickTextArea::classBegin() +{ + Q_D(QQuickTextArea); + QQuickTextEdit::classBegin(); + d->resolveFont(); +} + +void QQuickTextArea::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &value) +{ + Q_D(QQuickTextArea); + QQuickTextEdit::itemChange(change, value); + if (change == ItemParentHasChanged && isComponentComplete()) + d->resolveFont(); +} + void QQuickTextArea::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) { Q_D(QQuickTextArea); diff --git a/src/templates/qquicktextarea_p.h b/src/templates/qquicktextarea_p.h index 13022ce5..d8326f66 100644 --- a/src/templates/qquicktextarea_p.h +++ b/src/templates/qquicktextarea_p.h @@ -88,6 +88,9 @@ Q_SIGNALS: void pressAndHold(QQuickMouseEvent *event); protected: + void classBegin() Q_DECL_OVERRIDE; + + 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 mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE; diff --git a/src/templates/qquicktextfield.cpp b/src/templates/qquicktextfield.cpp index dd8ef362..50d49c11 100644 --- a/src/templates/qquicktextfield.cpp +++ b/src/templates/qquicktextfield.cpp @@ -309,6 +309,21 @@ void QQuickTextField::setPlaceholderText(const QString &text) } } +void QQuickTextField::classBegin() +{ + Q_D(QQuickTextField); + QQuickTextInput::classBegin(); + d->resolveFont(); +} + +void QQuickTextField::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &value) +{ + Q_D(QQuickTextField); + QQuickTextInput::itemChange(change, value); + if (change == ItemParentHasChanged && isComponentComplete()) + d->resolveFont(); +} + void QQuickTextField::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) { Q_D(QQuickTextField); diff --git a/src/templates/qquicktextfield_p.h b/src/templates/qquicktextfield_p.h index c219fa79..d8b20225 100644 --- a/src/templates/qquicktextfield_p.h +++ b/src/templates/qquicktextfield_p.h @@ -88,6 +88,9 @@ Q_SIGNALS: void pressAndHold(QQuickMouseEvent *mouse); protected: + void classBegin() Q_DECL_OVERRIDE; + + 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 mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE; diff --git a/src/templates/qquicktoolbutton.cpp b/src/templates/qquicktoolbutton.cpp index 4de82403..3505346c 100644 --- a/src/templates/qquicktoolbutton.cpp +++ b/src/templates/qquicktoolbutton.cpp @@ -35,6 +35,9 @@ ****************************************************************************/ #include "qquicktoolbutton_p.h" +#include "qquickcontrol_p_p.h" + +#include <QtGui/qpa/qplatformtheme.h> QT_BEGIN_NAMESPACE @@ -78,4 +81,9 @@ QQuickToolButton::QQuickToolButton(QQuickItem *parent) : { } +QFont QQuickToolButton::defaultFont() const +{ + return QQuickControlPrivate::themeFont(QPlatformTheme::ToolButtonFont); +} + QT_END_NAMESPACE diff --git a/src/templates/qquicktoolbutton_p.h b/src/templates/qquicktoolbutton_p.h index e0e7892d..d3bb4fe7 100644 --- a/src/templates/qquicktoolbutton_p.h +++ b/src/templates/qquicktoolbutton_p.h @@ -58,6 +58,9 @@ class Q_LABSTEMPLATES_EXPORT QQuickToolButton : public QQuickButton public: explicit QQuickToolButton(QQuickItem *parent = Q_NULLPTR); + +protected: + QFont defaultFont() const Q_DECL_OVERRIDE; }; Q_DECLARE_TYPEINFO(QQuickToolButton, Q_COMPLEX_TYPE); diff --git a/src/templates/templates.pri b/src/templates/templates.pri index 8dc9764d..22fad255 100644 --- a/src/templates/templates.pri +++ b/src/templates/templates.pri @@ -6,6 +6,7 @@ HEADERS += \ $$PWD/qquickapplicationwindow_p.h \ $$PWD/qquickbusyindicator_p.h \ $$PWD/qquickbutton_p.h \ + $$PWD/qquickbuttongroup_p.h \ $$PWD/qquickcheckbox_p.h \ $$PWD/qquickcontainer_p.h \ $$PWD/qquickcontainer_p_p.h \ @@ -13,13 +14,19 @@ HEADERS += \ $$PWD/qquickcontrol_p_p.h \ $$PWD/qquickdial_p.h \ $$PWD/qquickdrawer_p.h \ - $$PWD/qquickexclusivegroup_p.h \ $$PWD/qquickframe_p.h \ $$PWD/qquickframe_p_p.h \ $$PWD/qquickgroupbox_p.h \ + $$PWD/qquickitemdelegate_p.h \ $$PWD/qquicklabel_p.h \ $$PWD/qquicklabel_p_p.h \ + $$PWD/qquickmenu_p.h \ + $$PWD/qquickmenu_p_p.h \ + $$PWD/qquickmenuitem_p.h \ + $$PWD/qquickoverlay_p.h \ $$PWD/qquickpageindicator_p.h \ + $$PWD/qquickpanel_p.h \ + $$PWD/qquickpanel_p_p.h \ $$PWD/qquickpressandholdhelper_p.h \ $$PWD/qquickprogressbar_p.h \ $$PWD/qquickradiobutton_p.h \ @@ -47,16 +54,21 @@ SOURCES += \ $$PWD/qquickapplicationwindow.cpp \ $$PWD/qquickbusyindicator.cpp \ $$PWD/qquickbutton.cpp \ + $$PWD/qquickbuttongroup.cpp \ $$PWD/qquickcheckbox.cpp \ $$PWD/qquickcontainer.cpp \ $$PWD/qquickcontrol.cpp \ $$PWD/qquickdial.cpp \ $$PWD/qquickdrawer.cpp \ - $$PWD/qquickexclusivegroup.cpp \ $$PWD/qquickframe.cpp \ $$PWD/qquickgroupbox.cpp \ + $$PWD/qquickitemdelegate.cpp \ $$PWD/qquicklabel.cpp \ + $$PWD/qquickmenu.cpp \ + $$PWD/qquickmenuitem.cpp \ + $$PWD/qquickoverlay.cpp \ $$PWD/qquickpageindicator.cpp \ + $$PWD/qquickpanel.cpp \ $$PWD/qquickpressandholdhelper.cpp \ $$PWD/qquickprogressbar.cpp \ $$PWD/qquickradiobutton.cpp \ diff --git a/src/templates/templates.pro b/src/templates/templates.pro index 72c16b79..36273577 100644 --- a/src/templates/templates.pro +++ b/src/templates/templates.pro @@ -3,7 +3,7 @@ MODULE = labstemplates CONFIG += internal_module QT += quick -QT += core-private gui-private qml-private quick-private +QT_PRIVATE += core-private gui-private qml-private quick-private DEFINES += QT_NO_CAST_TO_ASCII QT_NO_CAST_FROM_ASCII diff --git a/sync.profile b/sync.profile index 904a3a62..ae91c340 100644 --- a/sync.profile +++ b/sync.profile @@ -1,4 +1,5 @@ %modules = ( # path to module name map + "QtLabsControls" => "$basedir/src/controls", "QtLabsTemplates" => "$basedir/src/templates", ); %moduleheaders = ( # restrict the module headers to those found in relative path @@ -15,4 +16,5 @@ "qtxmlpatterns" => "", "qtdeclarative" => "", "qtquickcontrols" => "", + "qtgraphicaleffects" => "" ); diff --git a/tests/auto/accessibility/tst_accessibility.cpp b/tests/auto/accessibility/tst_accessibility.cpp index a9e04d59..866d3b13 100644 --- a/tests/auto/accessibility/tst_accessibility.cpp +++ b/tests/auto/accessibility/tst_accessibility.cpp @@ -135,9 +135,13 @@ void tst_accessibility::a11y() if (name != QLatin1Literal("dayofweekrow") && name != QLatin1Literal("monthgrid") && name != QLatin1Literal("weeknumbercolumn")) { - QVERIFY(!acc); - QAccessible::setActive(true); - acc = qobject_cast<QQuickAccessibleAttached *>(qmlAttachedPropertiesObject<QQuickAccessibleAttached>(item, false)); + if (QAccessible::isActive()) { + QVERIFY(acc); + } else { + QVERIFY(!acc); + QAccessible::setActive(true); + acc = qobject_cast<QQuickAccessibleAttached *>(qmlAttachedPropertiesObject<QQuickAccessibleAttached>(item, false)); + } } QVERIFY(acc); QCOMPARE(acc->role(), (QAccessible::Role)role); diff --git a/tests/auto/applicationwindow/applicationwindow.pro b/tests/auto/applicationwindow/applicationwindow.pro index 6665a640..5a664b63 100644 --- a/tests/auto/applicationwindow/applicationwindow.pro +++ b/tests/auto/applicationwindow/applicationwindow.pro @@ -4,7 +4,7 @@ SOURCES += tst_applicationwindow.cpp osx:CONFIG -= app_bundle -QT += core-private gui-private qml-private quick-private testlib +QT += core-private gui-private qml-private quick-private labstemplates-private testlib include (../shared/util.pri) diff --git a/tests/auto/applicationwindow/data/attachedProperties.qml b/tests/auto/applicationwindow/data/attachedProperties.qml new file mode 100644 index 00000000..060a3093 --- /dev/null +++ b/tests/auto/applicationwindow/data/attachedProperties.qml @@ -0,0 +1,144 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.6 +import QtQuick.Window 2.2 +import Qt.labs.controls 1.0 + +ApplicationWindow { + property alias childItem: childItem + property alias childObject: childObject + + Item { + id: childItem + + property ApplicationWindow attached_window: ApplicationWindow.window + property Item attached_contentItem: ApplicationWindow.contentItem + property Item attached_activeFocusItem: ApplicationWindow.activeFocusItem + property Item attached_header: ApplicationWindow.header + property Item attached_footer: ApplicationWindow.footer + property Item attached_overlay: ApplicationWindow.overlay + } + + QtObject { + id: childObject + + property ApplicationWindow attached_window: ApplicationWindow.window + property Item attached_contentItem: ApplicationWindow.contentItem + property Item attached_activeFocusItem: ApplicationWindow.activeFocusItem + property Item attached_header: ApplicationWindow.header + property Item attached_footer: ApplicationWindow.footer + property Item attached_overlay: ApplicationWindow.overlay + } + + property alias childWindow: childWindow + property alias childWindowItem: childWindowItem + property alias childWindowObject: childWindowObject + + Window { + id: childWindow + + property ApplicationWindow attached_window: ApplicationWindow.window + property Item attached_contentItem: ApplicationWindow.contentItem + property Item attached_activeFocusItem: ApplicationWindow.activeFocusItem + property Item attached_header: ApplicationWindow.header + property Item attached_footer: ApplicationWindow.footer + property Item attached_overlay: ApplicationWindow.overlay + + Item { + id: childWindowItem + + property ApplicationWindow attached_window: ApplicationWindow.window + property Item attached_contentItem: ApplicationWindow.contentItem + property Item attached_activeFocusItem: ApplicationWindow.activeFocusItem + property Item attached_header: ApplicationWindow.header + property Item attached_footer: ApplicationWindow.footer + property Item attached_overlay: ApplicationWindow.overlay + } + + QtObject { + id: childWindowObject + + property ApplicationWindow attached_window: ApplicationWindow.window + property Item attached_contentItem: ApplicationWindow.contentItem + property Item attached_activeFocusItem: ApplicationWindow.activeFocusItem + property Item attached_header: ApplicationWindow.header + property Item attached_footer: ApplicationWindow.footer + property Item attached_overlay: ApplicationWindow.overlay + } + } + + property alias childAppWindow: childAppWindow + property alias childAppWindowItem: childAppWindowItem + property alias childAppWindowObject: childAppWindowObject + + ApplicationWindow { + id: childAppWindow + + property ApplicationWindow attached_window: ApplicationWindow.window + property Item attached_contentItem: ApplicationWindow.contentItem + property Item attached_activeFocusItem: ApplicationWindow.activeFocusItem + property Item attached_header: ApplicationWindow.header + property Item attached_footer: ApplicationWindow.footer + property Item attached_overlay: ApplicationWindow.overlay + + Item { + id: childAppWindowItem + + property ApplicationWindow attached_window: ApplicationWindow.window + property Item attached_contentItem: ApplicationWindow.contentItem + property Item attached_activeFocusItem: ApplicationWindow.activeFocusItem + property Item attached_header: ApplicationWindow.header + property Item attached_footer: ApplicationWindow.footer + property Item attached_overlay: ApplicationWindow.overlay + } + + QtObject { + id: childAppWindowObject + + property ApplicationWindow attached_window: ApplicationWindow.window + property Item attached_contentItem: ApplicationWindow.contentItem + property Item attached_activeFocusItem: ApplicationWindow.activeFocusItem + property Item attached_header: ApplicationWindow.header + property Item attached_footer: ApplicationWindow.footer + property Item attached_overlay: ApplicationWindow.overlay + } + } +} diff --git a/tests/auto/applicationwindow/data/fill.qml b/tests/auto/applicationwindow/data/fill.qml index 6d4c92c9..2a9c7bad 100644 --- a/tests/auto/applicationwindow/data/fill.qml +++ b/tests/auto/applicationwindow/data/fill.qml @@ -49,7 +49,7 @@ ApplicationWindow { property alias nextItem: nextItem function pushNextItem() { - stackView.push(nextItem); + stackView.push(nextItem, StackView.Immediate); } Rectangle { diff --git a/tests/auto/applicationwindow/tst_applicationwindow.cpp b/tests/auto/applicationwindow/tst_applicationwindow.cpp index e654437d..0f91d634 100644 --- a/tests/auto/applicationwindow/tst_applicationwindow.cpp +++ b/tests/auto/applicationwindow/tst_applicationwindow.cpp @@ -41,6 +41,7 @@ #include <QtQml/qqmlcontext.h> #include <QtQuick/qquickview.h> #include <QtQuick/private/qquickitem_p.h> +#include <QtLabsTemplates/private/qquickapplicationwindow_p.h> #include "../shared/util.h" #include "../shared/visualtestutil.h" @@ -57,6 +58,7 @@ private slots: void activeFocusOnTab2(); void defaultFocus(); void implicitFill(); + void attachedProperties(); }; void tst_applicationwindow::qmlCreation() @@ -247,6 +249,139 @@ void tst_applicationwindow::implicitFill() QCOMPARE(nextItem->height(), 400.0); } +void tst_applicationwindow::attachedProperties() +{ + QQmlEngine engine; + QQmlComponent component(&engine); + component.loadUrl(testFileUrl("attachedProperties.qml")); + + QScopedPointer<QObject> object(component.create()); + QVERIFY2(!object.isNull(), qPrintable(component.errorString())); + + QQuickApplicationWindow *window = qobject_cast<QQuickApplicationWindow *>(object.data()); + QVERIFY(window); + + QQuickItem *childItem = object->property("childItem").value<QQuickItem *>(); + QVERIFY(childItem); + QCOMPARE(childItem->property("attached_window").value<QQuickApplicationWindow *>(), window); + QCOMPARE(childItem->property("attached_contentItem").value<QQuickItem *>(), window->contentItem()); + QCOMPARE(childItem->property("attached_activeFocusItem").value<QQuickItem *>(), window->activeFocusItem()); + QCOMPARE(childItem->property("attached_header").value<QQuickItem *>(), window->header()); + QCOMPARE(childItem->property("attached_footer").value<QQuickItem *>(), window->footer()); + QCOMPARE(childItem->property("attached_overlay").value<QQuickItem *>(), window->overlay()); + + QObject *childObject = object->property("childObject").value<QObject *>(); + QVERIFY(childObject); + QVERIFY(!childObject->property("attached_window").value<QQuickApplicationWindow *>()); + QVERIFY(!childObject->property("attached_contentItem").value<QQuickItem *>()); + QVERIFY(!childObject->property("attached_activeFocusItem").value<QQuickItem *>()); + QVERIFY(!childObject->property("attached_header").value<QQuickItem *>()); + QVERIFY(!childObject->property("attached_footer").value<QQuickItem *>()); + QVERIFY(!childObject->property("attached_overlay").value<QQuickItem *>()); + + QQuickWindow *childWindow = object->property("childWindow").value<QQuickWindow *>(); + QVERIFY(childWindow); + QVERIFY(!childWindow->property("attached_window").value<QQuickApplicationWindow *>()); + QVERIFY(!childWindow->property("attached_contentItem").value<QQuickItem *>()); + QVERIFY(!childWindow->property("attached_activeFocusItem").value<QQuickItem *>()); + QVERIFY(!childWindow->property("attached_header").value<QQuickItem *>()); + QVERIFY(!childWindow->property("attached_footer").value<QQuickItem *>()); + QVERIFY(!childWindow->property("attached_overlay").value<QQuickItem *>()); + + QQuickItem *childWindowItem = object->property("childWindowItem").value<QQuickItem *>(); + QVERIFY(childWindowItem); + QVERIFY(!childWindowItem->property("attached_window").value<QQuickApplicationWindow *>()); + QVERIFY(!childWindowItem->property("attached_contentItem").value<QQuickItem *>()); + QVERIFY(!childWindowItem->property("attached_activeFocusItem").value<QQuickItem *>()); + QVERIFY(!childWindowItem->property("attached_header").value<QQuickItem *>()); + QVERIFY(!childWindowItem->property("attached_footer").value<QQuickItem *>()); + QVERIFY(!childWindowItem->property("attached_overlay").value<QQuickItem *>()); + + QObject *childWindowObject = object->property("childWindowObject").value<QObject *>(); + QVERIFY(childWindowObject); + QVERIFY(!childWindowObject->property("attached_window").value<QQuickApplicationWindow *>()); + QVERIFY(!childWindowObject->property("attached_contentItem").value<QQuickItem *>()); + QVERIFY(!childWindowObject->property("attached_activeFocusItem").value<QQuickItem *>()); + QVERIFY(!childWindowObject->property("attached_header").value<QQuickItem *>()); + QVERIFY(!childWindowObject->property("attached_footer").value<QQuickItem *>()); + QVERIFY(!childWindowObject->property("attached_overlay").value<QQuickItem *>()); + + QQuickApplicationWindow *childAppWindow = object->property("childAppWindow").value<QQuickApplicationWindow *>(); + QVERIFY(childAppWindow); + QVERIFY(!childAppWindow->property("attached_window").value<QQuickApplicationWindow *>()); + QVERIFY(!childAppWindow->property("attached_contentItem").value<QQuickItem *>()); + QVERIFY(!childAppWindow->property("attached_activeFocusItem").value<QQuickItem *>()); + QVERIFY(!childAppWindow->property("attached_header").value<QQuickItem *>()); + QVERIFY(!childAppWindow->property("attached_footer").value<QQuickItem *>()); + QVERIFY(!childAppWindow->property("attached_overlay").value<QQuickItem *>()); + + QQuickItem *childAppWindowItem = object->property("childAppWindowItem").value<QQuickItem *>(); + QVERIFY(childAppWindowItem); + QCOMPARE(childAppWindowItem->property("attached_window").value<QQuickApplicationWindow *>(), childAppWindow); + QCOMPARE(childAppWindowItem->property("attached_contentItem").value<QQuickItem *>(), childAppWindow->contentItem()); + QCOMPARE(childAppWindowItem->property("attached_activeFocusItem").value<QQuickItem *>(), childAppWindow->activeFocusItem()); + QCOMPARE(childAppWindowItem->property("attached_header").value<QQuickItem *>(), childAppWindow->header()); + QCOMPARE(childAppWindowItem->property("attached_footer").value<QQuickItem *>(), childAppWindow->footer()); + QCOMPARE(childAppWindowItem->property("attached_overlay").value<QQuickItem *>(), childAppWindow->overlay()); + + QObject *childAppWindowObject = object->property("childAppWindowObject").value<QObject *>(); + QVERIFY(childAppWindowObject); + QVERIFY(!childAppWindowObject->property("attached_window").value<QQuickApplicationWindow *>()); + QVERIFY(!childAppWindowObject->property("attached_contentItem").value<QQuickItem *>()); + QVERIFY(!childAppWindowObject->property("attached_activeFocusItem").value<QQuickItem *>()); + QVERIFY(!childAppWindowObject->property("attached_header").value<QQuickItem *>()); + QVERIFY(!childAppWindowObject->property("attached_footer").value<QQuickItem *>()); + QVERIFY(!childAppWindowObject->property("attached_overlay").value<QQuickItem *>()); + + window->show(); + window->requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(window)); + + QVERIFY(!childItem->hasActiveFocus()); + childItem->forceActiveFocus(); + QTRY_VERIFY(childItem->hasActiveFocus()); + QCOMPARE(window->activeFocusItem(), childItem); + QCOMPARE(childItem->property("attached_activeFocusItem").value<QQuickItem *>(), childItem); + + QQuickItem *header = new QQuickItem; + window->setHeader(header); + QCOMPARE(window->header(), header); + QCOMPARE(childItem->property("attached_header").value<QQuickItem *>(), header); + + QQuickItem *footer = new QQuickItem; + window->setFooter(footer); + QCOMPARE(window->footer(), footer); + QCOMPARE(childItem->property("attached_footer").value<QQuickItem *>(), footer); + + childAppWindow->show(); + childAppWindow->requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(childAppWindow)); + + QVERIFY(!childAppWindowItem->hasActiveFocus()); + childAppWindowItem->forceActiveFocus(); + QTRY_VERIFY(childAppWindowItem->hasActiveFocus()); + QCOMPARE(childAppWindow->activeFocusItem(), childAppWindowItem); + QCOMPARE(childAppWindowItem->property("attached_activeFocusItem").value<QQuickItem *>(), childAppWindowItem); + + childItem->setParentItem(childAppWindow->contentItem()); + QCOMPARE(childItem->window(), childAppWindow); + QCOMPARE(childItem->property("attached_window").value<QQuickApplicationWindow *>(), childAppWindow); + QCOMPARE(childItem->property("attached_contentItem").value<QQuickItem *>(), childAppWindow->contentItem()); + QCOMPARE(childItem->property("attached_activeFocusItem").value<QQuickItem *>(), childAppWindow->activeFocusItem()); + QCOMPARE(childItem->property("attached_header").value<QQuickItem *>(), childAppWindow->header()); + QCOMPARE(childItem->property("attached_footer").value<QQuickItem *>(), childAppWindow->footer()); + QCOMPARE(childItem->property("attached_overlay").value<QQuickItem *>(), childAppWindow->overlay()); + + childItem->setParentItem(Q_NULLPTR); + QVERIFY(!childItem->window()); + QVERIFY(!childItem->property("attached_window").value<QQuickApplicationWindow *>()); + QVERIFY(!childItem->property("attached_contentItem").value<QQuickItem *>()); + QVERIFY(!childItem->property("attached_activeFocusItem").value<QQuickItem *>()); + QVERIFY(!childItem->property("attached_header").value<QQuickItem *>()); + QVERIFY(!childItem->property("attached_footer").value<QQuickItem *>()); + QVERIFY(!childItem->property("attached_overlay").value<QQuickItem *>()); +} + QTEST_MAIN(tst_applicationwindow) #include "tst_applicationwindow.moc" diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro index ff3d32e1..3b3ee04a 100644 --- a/tests/auto/auto.pro +++ b/tests/auto/auto.pro @@ -5,6 +5,10 @@ SUBDIRS += \ applicationwindow \ calendar \ controls \ + material \ + menu \ + pressandhold \ sanity \ snippets \ - theme + styles \ + universal diff --git a/tests/auto/controls/data/PressAndHoldTests.qml b/tests/auto/controls/data/PressAndHoldTests.qml deleted file mode 100644 index 6be627cc..00000000 --- a/tests/auto/controls/data/PressAndHoldTests.qml +++ /dev/null @@ -1,139 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.6 -import QtTest 1.0 - -QtObject { - - property SignalSpy pressAndHoldSpy: SignalSpy { - signalName: "pressAndHold" - } - - function basicPressAndHold(control) { - control.width = 200 - pressAndHoldSpy.target = control - - mouseClick(control) - compare(pressAndHoldSpy.count, 0) - var interval = Qt.styleHints.mousePressAndHoldInterval - - // Short press duration => nothing happens - mousePress(control) - wait(interval * 0.3) - mouseRelease(control) - compare(pressAndHoldSpy.count, 0) - - // Long enough press duration => signal emitted - mousePress(control, 10, 10) - // Add 20% extra time to allow the control to - // receive the timer event before we come back here - wait(interval * 1.2) - compare(pressAndHoldSpy.count, 1) - mouseRelease(control) - compare(pressAndHoldSpy.count, 1) - - // Long enough, but move in between => nothing happens - pressAndHoldSpy.clear() - mousePress(control) - wait(interval * 0.6) - mouseMove(control, 5, 5, Qt.LeftButton) - wait(interval * 0.6) - compare(pressAndHoldSpy.count, 0) - mouseRelease(control) - compare(pressAndHoldSpy.count, 0) - - // Long enough, but 2nd press in between => nothing happens - pressAndHoldSpy.clear() - mousePress(control, 10, 10) - wait(interval * 0.6) - mousePress(control, 10, 10, Qt.RightButton) - wait(interval * 0.6) - compare(pressAndHoldSpy.count, 0) - mouseRelease(control, 10, 10, Qt.LeftButton|Qt.RightButton) - compare(pressAndHoldSpy.count, 0) - } - - function pressAndHoldKeepsSelection(control) { - control.width = 200 - control.text = "Cool stuff" - control.selectAll() - compare(control.selectedText, control.text) - - mouseClick(control) - compare(control.selectedText, "") - - control.selectAll() - compare(control.selectedText, control.text) - - var interval = Qt.styleHints.mousePressAndHoldInterval - pressAndHoldSpy.target = control - mousePress(control, 10, 10) - // Add 20% extra time to allow the control to - // receive the timer event before we come back here - wait(interval * 1.2) - mouseRelease(control) - compare(pressAndHoldSpy.count, 1) - compare(control.selectedText, control.text) - pressAndHoldSpy.clear() - - // Pre-timeout canceled pressAndHold should clear as usual - mousePress(control, 10, 10) - wait(interval * 0.5) - mouseRelease(control) - compare(pressAndHoldSpy.count, 0) - compare(control.selectedText, "") - - control.selectAll() - compare(control.selectedText, control.text) - - // Second button canceled pressAndHold should clear as usual - mousePress(control, 10, 10) - wait(interval * 0.6) - mouseRelease(control) - mousePress(control, 10, 10, Qt.RightButton) - compare(control.selectedText, "") - wait(interval * 0.6) - compare(pressAndHoldSpy.count, 0) - mouseRelease(control, 10, 10, Qt.LeftButton|Qt.RightButton) - compare(pressAndHoldSpy.count, 0) - compare(control.selectedText, "") - } -} diff --git a/tests/auto/controls/data/tst_button.qml b/tests/auto/controls/data/tst_button.qml index 76d45e03..873009e8 100644 --- a/tests/auto/controls/data/tst_button.qml +++ b/tests/auto/controls/data/tst_button.qml @@ -290,4 +290,20 @@ TestCase { control.destroy() } + + function test_highlighted() { + var control = button.createObject(testCase) + verify(control) + compare(control.highlighted, false) + + control.highlighted = true + compare(control.highlighted, true) + } + + function test_baseline() { + var control = button.createObject(testCase) + verify(control) + compare(control.baselineOffset, control.label.y + control.label.baselineOffset) + control.destroy() + } } diff --git a/tests/auto/controls/data/tst_buttongroup.qml b/tests/auto/controls/data/tst_buttongroup.qml new file mode 100644 index 00000000..b640a868 --- /dev/null +++ b/tests/auto/controls/data/tst_buttongroup.qml @@ -0,0 +1,324 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.2 +import QtTest 1.0 +import Qt.labs.controls 1.0 +import Qt.labs.templates 1.0 as T + +TestCase { + id: testCase + width: 200 + height: 200 + visible: true + when: windowShown + name: "ButtonGroup" + + Component { + id: buttonGroup + ButtonGroup { } + } + + SignalSpy { + id: checkedButtonSpy + signalName: "checkedButtonChanged" + } + + SignalSpy { + id: buttonsSpy + signalName: "buttonsChanged" + } + + function init() { + verify(!checkedButtonSpy.target) + compare(checkedButtonSpy.count, 0) + + verify(!buttonsSpy.target) + compare(buttonsSpy.count, 0) + } + + function cleanup() { + checkedButtonSpy.target = null + checkedButtonSpy.clear() + + buttonsSpy.target = null + buttonsSpy.clear() + } + + function test_null() { + var group = buttonGroup.createObject(testCase) + verify(group) + + group.addButton(null) + group.removeButton(null) + + group.destroy() + } + + Component { + id: button + Button { } + } + + Component { + id: nonCheckable + QtObject { } + } + + function test_current() { + var group = buttonGroup.createObject(testCase) + verify(group) + + checkedButtonSpy.target = group + verify(checkedButtonSpy.valid) + verify(!group.checkedButton) + + var button1 = button.createObject(testCase, {checked: true}) + var button2 = button.createObject(testCase, {checked: false}) + var button3 = button.createObject(testCase, {checked: true, objectName: "3"}) + + // add checked + group.addButton(button1) + compare(group.checkedButton, button1) + compare(button1.checked, true) + compare(button2.checked, false) + compare(button3.checked, true) + compare(checkedButtonSpy.count, 1) + + // add non-checked + group.addButton(button2) + compare(group.checkedButton, button1) + compare(button1.checked, true) + compare(button2.checked, false) + compare(button3.checked, true) + compare(checkedButtonSpy.count, 1) + + // add checked + group.addButton(button3) + compare(group.checkedButton, button3) + compare(button1.checked, false) + compare(button2.checked, false) + compare(button3.checked, true) + compare(checkedButtonSpy.count, 2) + + // change current + group.checkedButton = button2 + compare(group.checkedButton, button2) + compare(button1.checked, false) + compare(button2.checked, true) + compare(button3.checked, false) + compare(checkedButtonSpy.count, 3) + + // check + button1.checked = true + compare(group.checkedButton, button1) + compare(button1.checked, true) + compare(button2.checked, false) + compare(button3.checked, false) + compare(checkedButtonSpy.count, 4) + + // remove non-checked + group.removeButton(button2) + compare(group.checkedButton, button1) + compare(button1.checked, true) + compare(button2.checked, false) + compare(button3.checked, false) + compare(checkedButtonSpy.count, 4) + + // remove checked + group.removeButton(button1) + verify(!group.checkedButton) + compare(button1.checked, false) + compare(button2.checked, false) + compare(button3.checked, false) + compare(checkedButtonSpy.count, 5) + + group.destroy() + } + + function test_buttons() { + var group = buttonGroup.createObject(testCase) + verify(group) + + buttonsSpy.target = group + verify(buttonsSpy.valid) + + compare(group.buttons.length, 0) + compare(group.checkedButton, null) + + var button1 = button.createObject(testCase, {checked: true}) + var button2 = button.createObject(testCase, {checked: false}) + + group.buttons = [button1, button2] + compare(group.buttons.length, 2) + compare(group.buttons[0], button1) + compare(group.buttons[1], button2) + compare(group.checkedButton, button1) + compare(buttonsSpy.count, 2) + + var button3 = button.createObject(testCase, {checked: true}) + + group.addButton(button3) + compare(group.buttons.length, 3) + compare(group.buttons[0], button1) + compare(group.buttons[1], button2) + compare(group.buttons[2], button3) + compare(group.checkedButton, button3) + compare(buttonsSpy.count, 3) + + group.removeButton(button1) + compare(group.buttons.length, 2) + compare(group.buttons[0], button2) + compare(group.buttons[1], button3) + compare(group.checkedButton, button3) + compare(buttonsSpy.count, 4) + + group.buttons = [] + compare(group.buttons.length, 0) + compare(group.checkedButton, null) + compare(buttonsSpy.count, 5) + + group.destroy() + } + + Component { + id: checkBoxes + Item { + property ButtonGroup group: ButtonGroup { id: group } + property CheckBox control1: CheckBox { ButtonGroup.group: group } + property CheckBox control2: CheckBox { ButtonGroup.group: group } + property CheckBox control3: CheckBox { ButtonGroup.group: group } + } + } + + Component { + id: radioButtons + Item { + property ButtonGroup group: ButtonGroup { id: group } + property RadioButton control1: RadioButton { ButtonGroup.group: group } + property RadioButton control2: RadioButton { ButtonGroup.group: group } + property RadioButton control3: RadioButton { ButtonGroup.group: group } + } + } + + Component { + id: switches + Item { + property ButtonGroup group: ButtonGroup { id: group } + property Switch control1: Switch { ButtonGroup.group: group } + property Switch control2: Switch { ButtonGroup.group: group } + property Switch control3: Switch { ButtonGroup.group: group } + } + } + + Component { + id: childControls + Item { + id: container + property ButtonGroup group: ButtonGroup { id: group; buttons: container.children } + property alias control1: control1 + property alias control2: control2 + property alias control3: control3 + CheckBox { id: control1 } + RadioButton { id: control2 } + Switch { id: control3 } + } + } + + function test_controls_data() { + return [ + { tag: "CheckBox", component: checkBoxes }, + { tag: "RadioButton", component: radioButtons }, + { tag: "Switch", component: switches }, + { tag: "Children", component: childControls } + ] + } + + function test_controls(data) { + var container = data.component.createObject(testCase) + verify(container) + + verify(!container.group.checkedButton) + + container.control1.checked = true + compare(container.group.checkedButton, container.control1) + compare(container.control1.checked, true) + compare(container.control2.checked, false) + compare(container.control3.checked, false) + + container.control2.checked = true + compare(container.group.checkedButton, container.control2) + compare(container.control1.checked, false) + compare(container.control2.checked, true) + compare(container.control3.checked, false) + + container.control3.checked = true + compare(container.group.checkedButton, container.control3) + compare(container.control1.checked, false) + compare(container.control2.checked, false) + compare(container.control3.checked, true) + + container.destroy() + } + + function test_buttonDestroyed() { + var group = buttonGroup.createObject(testCase) + verify(group) + + buttonsSpy.target = group + verify(buttonsSpy.valid) + + var button1 = button.createObject(testCase, {objectName: "button1", checked: true}) + + group.addButton(button1) + compare(group.buttons.length, 1) + compare(group.buttons[0], button1) + compare(group.checkedButton, button1) + compare(buttonsSpy.count, 1) + + button1.destroy() + wait(0) + compare(group.buttons.length, 0) + compare(group.checkedButton, null) + compare(buttonsSpy.count, 2) + + group.destroy() + } +} diff --git a/tests/auto/controls/data/tst_checkbox.qml b/tests/auto/controls/data/tst_checkbox.qml index c61cab38..4efc7223 100644 --- a/tests/auto/controls/data/tst_checkbox.qml +++ b/tests/auto/controls/data/tst_checkbox.qml @@ -417,4 +417,11 @@ TestCase { control.destroy() } + + function test_baseline() { + var control = checkBox.createObject(testCase) + verify(control) + compare(control.baselineOffset, control.label.y + control.label.baselineOffset) + control.destroy() + } } diff --git a/tests/auto/controls/data/tst_control.qml b/tests/auto/controls/data/tst_control.qml index 7af160c2..15b25112 100644 --- a/tests/auto/controls/data/tst_control.qml +++ b/tests/auto/controls/data/tst_control.qml @@ -605,4 +605,55 @@ TestCase { control3.destroy() } + + Component { + id: component4 + T.Control { + id: item4 + objectName: "item4" + property alias item4_2: _item4_2; + property alias item4_3: _item4_3; + property alias item4_4: _item4_4; + T.Control { + id: _item4_2 + objectName: "_item4_2" + font.pixelSize: item4.font.pixelSize + 10 + T.Control { + id: _item4_3 + objectName: "_item4_3" + font.pixelSize: item4.font.pixelSize - 1 + } + T.Control { + id: _item4_4 + objectName: "_item4_4" + } + } + } + } + + function test_font_3() { + var control4 = component4.createObject(testCase) + verify(control4) + verify(control4.item4_2) + verify(control4.item4_3) + verify(control4.item4_4) + + var family = control4.font.family + var ps = control4.font.pixelSize + + compare(control4.item4_2.font.family, control4.font.family) + compare(control4.item4_3.font.family, control4.font.family) + compare(control4.item4_4.font.family, control4.font.family) + + compare(control4.item4_2.font.pixelSize, control4.font.pixelSize + 10) + compare(control4.item4_3.font.pixelSize, control4.font.pixelSize - 1) + compare(control4.item4_4.font.pixelSize, control4.font.pixelSize + 10) + + control4.item4_2.font.pixelSize = control4.font.pixelSize + 15 + compare(control4.item4_2.font.pixelSize, control4.font.pixelSize + 15) + compare(control4.item4_3.font.pixelSize, control4.font.pixelSize - 1) + compare(control4.item4_4.font.pixelSize, control4.font.pixelSize + 15) + + control4.destroy() + } } diff --git a/tests/auto/controls/data/tst_dial.qml b/tests/auto/controls/data/tst_dial.qml index 7468c530..e0eba27e 100644 --- a/tests/auto/controls/data/tst_dial.qml +++ b/tests/auto/controls/data/tst_dial.qml @@ -78,8 +78,6 @@ TestCase { function test_value() { compare(dial.value, 0.0); - compare(Math.floor(dial.handle.mapToItem(parent, 0, 0).x), 28); - compare(Math.floor(dial.handle.mapToItem(parent, 0, 0).y), 90); dial.value = 0.5; compare(dial.value, 0.5); diff --git a/tests/auto/controls/data/tst_exclusivegroup.qml b/tests/auto/controls/data/tst_exclusivegroup.qml deleted file mode 100644 index dcabb6c9..00000000 --- a/tests/auto/controls/data/tst_exclusivegroup.qml +++ /dev/null @@ -1,326 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.2 -import QtTest 1.0 -import Qt.labs.controls 1.0 - -TestCase { - id: testCase - width: 200 - height: 200 - visible: true - when: windowShown - name: "ExclusiveGroup" - - Component { - id: exclusiveGroup - ExclusiveGroup { } - } - - Component { - id: checkableGroup - ExclusiveGroup { - QtObject { objectName: "non-checkable" } - QtObject { objectName: "checkable1"; property bool checked: false } - QtObject { objectName: "checkable2"; property bool checked: true } - QtObject { objectName: "checkable3"; property bool checked: false } - } - } - - SignalSpy { - id: currentSpy - signalName: "currentChanged" - } - - SignalSpy { - id: checkablesSpy - signalName: "checkablesChanged" - } - - function init() { - verify(!currentSpy.target) - compare(currentSpy.count, 0) - - verify(!checkablesSpy.target) - compare(checkablesSpy.count, 0) - } - - function cleanup() { - currentSpy.target = null - currentSpy.clear() - - checkablesSpy.target = null - checkablesSpy.clear() - } - - function test_null() { - var group = exclusiveGroup.createObject(testCase) - verify(group) - - group.addCheckable(null) - group.removeCheckable(null) - - group.destroy() - } - - Component { - id: checkable - QtObject { property bool checked } - } - - Component { - id: nonCheckable - QtObject { } - } - - function test_current() { - var group = exclusiveGroup.createObject(testCase) - verify(group) - - currentSpy.target = group - verify(currentSpy.valid) - verify(!group.current) - - var checkable1 = checkable.createObject(testCase, {checked: true}) - var checkable2 = checkable.createObject(testCase, {checked: false}) - var checkable3 = checkable.createObject(testCase, {checked: true, objectName: "3"}) - - // add checked - group.addCheckable(checkable1) - compare(group.current, checkable1) - compare(checkable1.checked, true) - compare(checkable2.checked, false) - compare(checkable3.checked, true) - compare(currentSpy.count, 1) - - // add non-checked - group.addCheckable(checkable2) - compare(group.current, checkable1) - compare(checkable1.checked, true) - compare(checkable2.checked, false) - compare(checkable3.checked, true) - compare(currentSpy.count, 1) - - // add checked - group.addCheckable(checkable3) - compare(group.current, checkable3) - compare(checkable1.checked, false) - compare(checkable2.checked, false) - compare(checkable3.checked, true) - compare(currentSpy.count, 2) - - // change current - group.current = checkable2 - compare(group.current, checkable2) - compare(checkable1.checked, false) - compare(checkable2.checked, true) - compare(checkable3.checked, false) - compare(currentSpy.count, 3) - - // check - checkable1.checked = true - compare(group.current, checkable1) - compare(checkable1.checked, true) - compare(checkable2.checked, false) - compare(checkable3.checked, false) - compare(currentSpy.count, 4) - - // remove non-checked - group.removeCheckable(checkable2) - compare(group.current, checkable1) - compare(checkable1.checked, true) - compare(checkable2.checked, false) - compare(checkable3.checked, false) - compare(currentSpy.count, 4) - - // remove checked - group.removeCheckable(checkable1) - verify(!group.current) - compare(checkable1.checked, false) - compare(checkable2.checked, false) - compare(checkable3.checked, false) - compare(currentSpy.count, 5) - - group.destroy() - } - - function test_checkables() { - ignoreWarning(Qt.resolvedUrl("tst_exclusivegroup.qml") + ":60:9: QML ExclusiveGroup: The object has no checkedChanged() or toggled() signal.") - var group = checkableGroup.createObject(testCase) - verify(group) - - checkablesSpy.target = group - verify(checkablesSpy.valid) - - compare(group.checkables.length, 3) - compare(group.checkables[0].objectName, "checkable1") - compare(group.checkables[1].objectName, "checkable2") - compare(group.checkables[2].objectName, "checkable3") - compare(group.current, group.checkables[1]) - - var checkable4 = checkable.createObject(testCase, {checked: true}) - var checkable5 = checkable.createObject(testCase, {checked: false}) - - group.checkables = [checkable4, checkable5] - compare(group.checkables.length, 2) - compare(group.checkables[0], checkable4) - compare(group.checkables[1], checkable5) - compare(group.current, checkable4) - compare(checkablesSpy.count, 3) // clear + 2 * append :/ - - var checkable6 = checkable.createObject(testCase, {checked: true}) - - group.addCheckable(checkable6) - compare(group.checkables.length, 3) - compare(group.checkables[0], checkable4) - compare(group.checkables[1], checkable5) - compare(group.checkables[2], checkable6) - compare(group.current, checkable6) - compare(checkablesSpy.count, 4) - - group.removeCheckable(checkable4) - compare(group.checkables.length, 2) - compare(group.checkables[0], checkable5) - compare(group.checkables[1], checkable6) - compare(group.current, checkable6) - compare(checkablesSpy.count, 5) - - group.checkables = [] - compare(group.checkables.length, 0) - compare(group.current, null) - compare(checkablesSpy.count, 6) - - group.destroy() - } - - function test_isCheckable() { - var group = exclusiveGroup.createObject(testCase) - verify(group) - - var checkable1 = checkable.createObject(testCase) - compare(group.isCheckable(checkable1), true) - - var nonCheckable1 = nonCheckable.createObject(testCase) - compare(group.isCheckable(nonCheckable1), false) - - group.destroy() - } - - Component { - id: checkBoxes - Item { - property ExclusiveGroup group: ExclusiveGroup { id: group } - property CheckBox control1: CheckBox { ExclusiveGroup.group: group } - property CheckBox control2: CheckBox { ExclusiveGroup.group: group } - property CheckBox control3: CheckBox { ExclusiveGroup.group: group } - } - } - - Component { - id: radioButtons - Item { - property ExclusiveGroup group: ExclusiveGroup { id: group } - property RadioButton control1: RadioButton { ExclusiveGroup.group: group } - property RadioButton control2: RadioButton { ExclusiveGroup.group: group } - property RadioButton control3: RadioButton { ExclusiveGroup.group: group } - } - } - - Component { - id: switches - Item { - property ExclusiveGroup group: ExclusiveGroup { id: group } - property Switch control1: Switch { ExclusiveGroup.group: group } - property Switch control2: Switch { ExclusiveGroup.group: group } - property Switch control3: Switch { ExclusiveGroup.group: group } - } - } - - Component { - id: childControls - Item { - id: container - property ExclusiveGroup group: ExclusiveGroup { id: group; checkables: container.children } - property alias control1: control1 - property alias control2: control2 - property alias control3: control3 - CheckBox { id: control1 } - RadioButton { id: control2 } - Switch { id: control3 } - } - } - - function test_controls_data() { - return [ - { tag: "CheckBox", component: checkBoxes }, - { tag: "RadioButton", component: radioButtons }, - { tag: "Switch", component: switches }, - { tag: "Children", component: childControls } - ] - } - - function test_controls(data) { - var container = data.component.createObject(testCase) - verify(container) - - verify(!container.group.current) - - container.control1.checked = true - compare(container.group.current, container.control1) - compare(container.control1.checked, true) - compare(container.control2.checked, false) - compare(container.control3.checked, false) - - container.control2.checked = true - compare(container.group.current, container.control2) - compare(container.control1.checked, false) - compare(container.control2.checked, true) - compare(container.control3.checked, false) - - container.control3.checked = true - compare(container.group.current, container.control3) - compare(container.control1.checked, false) - compare(container.control2.checked, false) - compare(container.control3.checked, true) - - container.destroy() - } -} diff --git a/tests/auto/controls/data/tst_radiobutton.qml b/tests/auto/controls/data/tst_radiobutton.qml index 2df3542d..d4cdf0ad 100644 --- a/tests/auto/controls/data/tst_radiobutton.qml +++ b/tests/auto/controls/data/tst_radiobutton.qml @@ -235,9 +235,13 @@ TestCase { // explicitly grouped buttons are only exclusive with each other, not with // auto-exclusive buttons, and the autoExclusive property is ignored - ExclusiveGroup { id: eg } - RadioButton { ExclusiveGroup.group: eg } - RadioButton { ExclusiveGroup.group: eg; autoExclusive: false } + ButtonGroup { id: eg } + RadioButton { ButtonGroup.group: eg } + RadioButton { ButtonGroup.group: eg; autoExclusive: false } + + ButtonGroup { id: eg2 } + RadioButton { id: rb1; Component.onCompleted: eg2.addButton(rb1) } + RadioButton { id: rb2; Component.onCompleted: eg2.addButton(rb2) } // non-exclusive buttons don't affect the others RadioButton { autoExclusive: false } @@ -247,50 +251,68 @@ TestCase { function test_autoExclusive() { var container = radioButtonGroup.createObject(testCase) - compare(container.children.length, 6) + compare(container.children.length, 8) - var checkStates = [false, false, false, false, false, false] - for (var i = 0; i < 6; ++i) + var checkStates = [false, false, false, false, false, false, false, false] + for (var i = 0; i < 8; ++i) compare(container.children[i].checked, checkStates[i]) container.children[0].checked = true checkStates[0] = true - for (i = 0; i < 6; ++i) + for (i = 0; i < 8; ++i) compare(container.children[i].checked, checkStates[i]) container.children[1].checked = true checkStates[0] = false checkStates[1] = true - for (i = 0; i < 6; ++i) + for (i = 0; i < 8; ++i) compare(container.children[i].checked, checkStates[i]) container.children[2].checked = true checkStates[2] = true - for (i = 0; i < 6; ++i) + for (i = 0; i < 8; ++i) compare(container.children[i].checked, checkStates[i]) container.children[3].checked = true checkStates[2] = false checkStates[3] = true - for (i = 0; i < 6; ++i) + for (i = 0; i < 8; ++i) compare(container.children[i].checked, checkStates[i]) container.children[4].checked = true checkStates[4] = true - for (i = 0; i < 6; ++i) + for (i = 0; i < 8; ++i) compare(container.children[i].checked, checkStates[i]) container.children[5].checked = true + checkStates[4] = false checkStates[5] = true - for (i = 0; i < 6; ++i) + for (i = 0; i < 8; ++i) + compare(container.children[i].checked, checkStates[i]) + + container.children[6].checked = true + checkStates[6] = true + for (i = 0; i < 8; ++i) + compare(container.children[i].checked, checkStates[i]) + + container.children[7].checked = true + checkStates[7] = true + for (i = 0; i < 8; ++i) compare(container.children[i].checked, checkStates[i]) container.children[0].checked = true checkStates[0] = true checkStates[1] = false - for (i = 0; i < 6; ++i) + for (i = 0; i < 8; ++i) compare(container.children[i].checked, checkStates[i]) container.destroy() } + + function test_baseline() { + var control = radioButton.createObject(testCase) + verify(control) + compare(control.baselineOffset, control.label.y + control.label.baselineOffset) + control.destroy() + } } diff --git a/tests/auto/controls/data/tst_scrollbar.qml b/tests/auto/controls/data/tst_scrollbar.qml index 5baa0ba9..55f31e12 100644 --- a/tests/auto/controls/data/tst_scrollbar.qml +++ b/tests/auto/controls/data/tst_scrollbar.qml @@ -93,12 +93,20 @@ TestCase { compare(vertical.position, 0.0) compare(vertical.active, false) compare(vertical.orientation, Qt.Vertical) + compare(vertical.x, 0) + compare(vertical.y, 0) + verify(vertical.width > 0) + verify(vertical.height > 0) container.ScrollBar.vertical = vertical compare(vertical.parent, container) compare(vertical.orientation, Qt.Vertical) compare(vertical.size, container.visibleArea.heightRatio) compare(vertical.position, container.visibleArea.yPosition) + compare(vertical.x, container.width - vertical.width) + compare(vertical.y, 0) + verify(vertical.width > 0) + compare(vertical.height, container.height) var horizontal = scrollBar.createObject() verify(!horizontal.parent) @@ -106,12 +114,20 @@ TestCase { compare(horizontal.position, 0.0) compare(horizontal.active, false) compare(horizontal.orientation, Qt.Vertical) + compare(horizontal.x, 0) + compare(horizontal.y, 0) + verify(horizontal.width > 0) + verify(horizontal.height > 0) container.ScrollBar.horizontal = horizontal compare(horizontal.parent, container) compare(horizontal.orientation, Qt.Horizontal) compare(horizontal.size, container.visibleArea.widthRatio) compare(horizontal.position, container.visibleArea.xPosition) + compare(horizontal.x, 0) + compare(horizontal.y, container.height - horizontal.height) + compare(horizontal.width, container.width) + verify(horizontal.height > 0) var velocity = container.maximumFlickVelocity diff --git a/tests/auto/controls/data/tst_scrollindicator.qml b/tests/auto/controls/data/tst_scrollindicator.qml index 71e09784..99eef833 100644 --- a/tests/auto/controls/data/tst_scrollindicator.qml +++ b/tests/auto/controls/data/tst_scrollindicator.qml @@ -78,12 +78,20 @@ TestCase { compare(vertical.position, 0.0) compare(vertical.active, false) compare(vertical.orientation, Qt.Vertical) + compare(vertical.x, 0) + compare(vertical.y, 0) + verify(vertical.width > 0) + verify(vertical.height > 0) container.ScrollIndicator.vertical = vertical compare(vertical.parent, container) compare(vertical.orientation, Qt.Vertical) compare(vertical.size, container.visibleArea.heightRatio) compare(vertical.position, container.visibleArea.yPosition) + compare(vertical.x, container.width - vertical.width) + compare(vertical.y, 0) + verify(vertical.width > 0) + compare(vertical.height, container.height) var horizontal = scrollIndicator.createObject() verify(!horizontal.parent) @@ -91,12 +99,20 @@ TestCase { compare(horizontal.position, 0.0) compare(horizontal.active, false) compare(horizontal.orientation, Qt.Vertical) + compare(horizontal.x, 0) + compare(horizontal.y, 0) + verify(horizontal.width > 0) + verify(horizontal.height > 0) container.ScrollIndicator.horizontal = horizontal compare(horizontal.parent, container) compare(horizontal.orientation, Qt.Horizontal) compare(horizontal.size, container.visibleArea.widthRatio) compare(horizontal.position, container.visibleArea.xPosition) + compare(horizontal.x, 0) + compare(horizontal.y, container.height - horizontal.height) + compare(horizontal.width, container.width) + verify(horizontal.height > 0) var velocity = container.maximumFlickVelocity diff --git a/tests/auto/controls/data/tst_switch.qml b/tests/auto/controls/data/tst_switch.qml index 153a28b9..13924ed0 100644 --- a/tests/auto/controls/data/tst_switch.qml +++ b/tests/auto/controls/data/tst_switch.qml @@ -256,4 +256,11 @@ TestCase { container.destroy() } + + function test_baseline() { + var control = swtch.createObject(testCase) + verify(control) + compare(control.baselineOffset, control.label.y + control.label.baselineOffset) + control.destroy() + } } diff --git a/tests/auto/controls/data/tst_tabbutton.qml b/tests/auto/controls/data/tst_tabbutton.qml index da9e094b..3a817cfd 100644 --- a/tests/auto/controls/data/tst_tabbutton.qml +++ b/tests/auto/controls/data/tst_tabbutton.qml @@ -51,6 +51,11 @@ TestCase { name: "TabButton" Component { + id: tabButton + TabButton { } + } + + Component { id: repeater Column { Repeater { @@ -76,4 +81,11 @@ TestCase { container.destroy() } + + function test_baseline() { + var control = tabButton.createObject(testCase) + verify(control) + compare(control.baselineOffset, control.label.y + control.label.baselineOffset) + control.destroy() + } } diff --git a/tests/auto/controls/data/tst_textarea.qml b/tests/auto/controls/data/tst_textarea.qml index 286a32ce..b1225493 100644 --- a/tests/auto/controls/data/tst_textarea.qml +++ b/tests/auto/controls/data/tst_textarea.qml @@ -61,20 +61,6 @@ TestCase { control.destroy() } - PressAndHoldTests { id: pah } - - function test_pressAndHold() { - var control = textArea.createObject(testCase) - pah.basicPressAndHold(control) - control.destroy() - } - - function test_pressAndHoldKeepsSelection() { - var control = textArea.createObject(testCase) - pah.pressAndHoldKeepsSelection(control) - control.destroy() - } - function test_implicitSize() { var control = textArea.createObject(testCase) control.background.implicitWidth = 400 diff --git a/tests/auto/controls/data/tst_textfield.qml b/tests/auto/controls/data/tst_textfield.qml index 38bb7297..57675659 100644 --- a/tests/auto/controls/data/tst_textfield.qml +++ b/tests/auto/controls/data/tst_textfield.qml @@ -61,23 +61,6 @@ TestCase { control.destroy() } - PressAndHoldTests { id: pah } - - function test_pressAndHold() { - if (Qt.platform.os === "osx") - skip("QTBUG-47963"); - - var control = textField.createObject(testCase) - pah.basicPressAndHold(control) - control.destroy() - } - - function test_pressAndHoldKeepsSelection() { - var control = textField.createObject(testCase) - pah.pressAndHoldKeepsSelection(control) - control.destroy() - } - function test_implicitSize() { var control = textField.createObject(testCase) verify(control.implicitWidth > control.leftPadding + control.rightPadding) diff --git a/tests/auto/controls/data/tst_toolbutton.qml b/tests/auto/controls/data/tst_toolbutton.qml index 5dfac358..63a87ec2 100644 --- a/tests/auto/controls/data/tst_toolbutton.qml +++ b/tests/auto/controls/data/tst_toolbutton.qml @@ -169,4 +169,11 @@ TestCase { control.destroy() } + + function test_baseline() { + var control = toolButton.createObject(testCase) + verify(control) + compare(control.baselineOffset, control.label.y + control.label.baselineOffset) + control.destroy() + } } diff --git a/tests/auto/material/data/tst_material.qml b/tests/auto/material/data/tst_material.qml new file mode 100644 index 00000000..7797b8c3 --- /dev/null +++ b/tests/auto/material/data/tst_material.qml @@ -0,0 +1,225 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.2 +import QtQuick.Window 2.2 +import QtTest 1.0 +import Qt.labs.controls 1.0 +import Qt.labs.controls.material 1.0 + +TestCase { + id: testCase + width: 200 + height: 200 + visible: true + when: windowShown + name: "Material" + + Component { + id: button + Button { } + } + + Component { + id: styledButton + Button { + Material.theme: Material.Dark + Material.accent: Material.DeepPurple + } + } + + Component { + id: window + Window { } + } + + Component { + id: styledWindow + Window { + Material.theme: Material.Dark + Material.accent: Material.Green + } + } + + Component { + id: loader + Loader { + active: false + sourceComponent: Button { } + } + } + + Component { + id: swipeView + SwipeView { + Material.theme: Material.Dark + Button { } + } + } + + function test_defaults() { + var control = button.createObject(testCase) + verify(control) + verify(control.Material) + compare(control.Material.accent, Material.Teal) + compare(control.Material.theme, Material.Light) + control.destroy() + } + + function test_set() { + var control = button.createObject(testCase) + verify(control) + control.Material.accent = Material.Brown + control.Material.theme = Material.Dark + compare(control.Material.accent, Material.Brown) + compare(control.Material.theme, Material.Dark) + control.destroy() + } + + function test_reset() { + var control = styledButton.createObject(testCase) + verify(control) + compare(control.Material.accent, Material.DeepPurple) + compare(control.Material.theme, Material.Dark) + control.Material.accent = undefined + control.Material.theme = undefined + compare(control.Material.accent, testCase.Material.accent) + compare(control.Material.theme, testCase.Material.theme) + control.destroy() + } + + function test_inheritance_data() { + return [ + { tag: "accent", value1: Material.Amber, value2: Material.Indigo }, + { tag: "theme", value1: Material.Dark, value2: Material.Light }, + ] + } + + function test_inheritance(data) { + var prop = data.tag + var parent = button.createObject(testCase) + parent.Material[prop] = data.value1 + compare(parent.Material[prop], data.value1) + + var child1 = button.createObject(parent) + compare(child1.Material[prop], data.value1) + + parent.Material[prop] = data.value2 + compare(parent.Material[prop], data.value2) + compare(child1.Material[prop], data.value2) + + var child2 = button.createObject(parent) + compare(child2.Material[prop], data.value2) + + child2.Material[prop] = data.value1 + compare(child2.Material[prop], data.value1) + compare(child1.Material[prop], data.value2) + compare(parent.Material[prop], data.value2) + + parent.Material[prop] = undefined + verify(parent.Material[prop] !== data.value1) + verify(parent.Material[prop] !== undefined) + compare(child1.Material[prop], parent.Material[prop]) + verify(child2.Material[prop] !== parent.Material[prop]) + + var grandChild1 = button.createObject(child1) + var grandChild2 = button.createObject(child2) + compare(grandChild1.Material[prop], child1.Material[prop]) + compare(grandChild2.Material[prop], child2.Material[prop]) + + var themelessGrandGrandChild = button.createObject(grandChild1) + var grandGrandGrandChild1 = button.createObject(themelessGrandGrandChild) + compare(grandGrandGrandChild1.Material[prop], parent.Material[prop]) + + child1.Material[prop] = data.value2 + compare(child1.Material[prop], data.value2) + compare(grandChild1.Material[prop], data.value2) + compare(grandGrandGrandChild1.Material[prop], data.value2) + + parent.destroy() + } + + function test_window() { + var parent = window.createObject() + + var control = button.createObject(parent.contentItem) + compare(control.Material.accent, parent.Material.accent) + compare(control.Material.theme, parent.Material.theme) + + var styledChild = styledWindow.createObject(window) + verify(styledChild.Material.accent !== parent.Material.accent) + verify(styledChild.Material.theme !== parent.Material.theme) + + var unstyledChild = window.createObject(window) + compare(unstyledChild.Material.accent, parent.Material.accent) + compare(unstyledChild.Material.theme, parent.Material.theme) + + parent.Material.accent = Material.Cyan + compare(control.Material.accent, Material.Cyan) + verify(styledChild.Material.accent !== Material.Cyan) + // ### TODO: compare(unstyledChild.Material.accent, Material.Cyan) + + parent.destroy() + } + + function test_loader() { + var control = loader.createObject(testCase) + control.Material.accent = Material.Lime + control.active = true + compare(control.item.Material.accent, Material.Lime) + control.Material.accent = Material.Pink + compare(control.item.Material.accent, Material.Pink) + control.active = false + control.Material.accent = Material.Brown + control.active = true + compare(control.item.Material.accent, Material.Brown) + control.destroy() + } + + function test_swipeView() { + var control = swipeView.createObject(testCase) + verify(control) + var child = control.itemAt(0) + verify(child) + compare(control.Material.theme, Material.Dark) + compare(child.Material.theme, Material.Dark) + control.destroy() + } +} diff --git a/tests/auto/theme/theme.pro b/tests/auto/material/material.pro index e8d1133a..acd16cab 100644 --- a/tests/auto/theme/theme.pro +++ b/tests/auto/material/material.pro @@ -1,9 +1,9 @@ TEMPLATE = app -TARGET = tst_theme +TARGET = tst_material CONFIG += qmltestcase SOURCES += \ - $$PWD/tst_theme.cpp + $$PWD/tst_material.cpp OTHER_FILES += \ $$PWD/data/* diff --git a/tests/auto/theme/tst_theme.cpp b/tests/auto/material/tst_material.cpp index daa1b1fe..5db9c12b 100644 --- a/tests/auto/theme/tst_theme.cpp +++ b/tests/auto/material/tst_material.cpp @@ -35,23 +35,4 @@ ****************************************************************************/ #include <QtQuickTest/quicktest.h> -#include <QtGui/qguiapplication.h> -#include <QtQml/qqmlapplicationengine.h> - -// based on QUICK_TEST_MAIN() defined in quicktest.h -int main(int argc, char **argv) -{ - QTEST_ADD_GPU_BLACKLIST_SUPPORT - QTEST_SET_MAIN_SOURCE_PATH - - { - // QTBUG-48651 - QGuiApplication app(argc, argv); - QQmlApplicationEngine engine; - engine.loadData("import Qt.labs.controls 1.0; Slider { } "); - if (engine.rootObjects().isEmpty()) - return -1; - } - - return quick_test_main(argc, argv, "tst_theme", QUICK_TEST_SOURCE_DIR); -} +QUICK_TEST_MAIN(tst_material) diff --git a/examples/labs/calendar/TumblerDelegate.qml b/tests/auto/menu/data/applicationwindow.qml index e379e8c0..6855d66e 100644 --- a/examples/labs/calendar/TumblerDelegate.qml +++ b/tests/auto/menu/data/applicationwindow.qml @@ -3,7 +3,7 @@ ** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** -** This file is part of the examples of the Qt Toolkit. +** This file is part of the test suite of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:BSD$ ** You may use this file under the terms of the BSD license as follows: @@ -41,14 +41,41 @@ import QtQuick 2.6 import Qt.labs.controls 1.0 -Text { - text: isNaN(modelData) ? modelData : modelData + 1 - color: "#666666" - opacity: 0.4 + Math.max(0, 1 - Math.abs(Tumbler.displacement)) * 0.6 - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter +ApplicationWindow { + title: "Test Application Window" + width: 400 + height: 400 - Behavior on font.pixelSize { - NumberAnimation {} + property alias emptyMenu: emptyMenu + property alias menu: menu + property alias menuButton: menuButton + + Menu { + id: emptyMenu + } + + Menu { + id: menu + + MenuItem { + objectName: "firstMenuItem" + text: "A" + } + MenuItem { + objectName: "secondMenuItem" + text: "B" + } + MenuItem { + objectName: "thirdMenuItem" + text: "C" + } + } + + Button { + id: menuButton + x: 250 + visible: false + text: "Open Menu" + onClicked: menu.show() } } diff --git a/tests/auto/menu/menu.pro b/tests/auto/menu/menu.pro new file mode 100644 index 00000000..2dd2ac7f --- /dev/null +++ b/tests/auto/menu/menu.pro @@ -0,0 +1,15 @@ +CONFIG += testcase +TARGET = tst_menu +SOURCES += tst_menu.cpp + +osx:CONFIG -= app_bundle + +QT += core-private gui-private qml-private quick-private testlib labstemplates-private + +include (../shared/util.pri) + +TESTDATA = data/* + +OTHER_FILES += \ + data/* + diff --git a/tests/auto/menu/tst_menu.cpp b/tests/auto/menu/tst_menu.cpp new file mode 100644 index 00000000..226a8588 --- /dev/null +++ b/tests/auto/menu/tst_menu.cpp @@ -0,0 +1,272 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite 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 <qtest.h> +#include <QtTest/QSignalSpy> +#include <QtGui/qstylehints.h> +#include <QtQml/qqmlengine.h> +#include <QtQml/qqmlcomponent.h> +#include <QtQml/qqmlcontext.h> +#include <QtQuick/qquickview.h> +#include <QtQuick/private/qquickitem_p.h> +#include "../shared/util.h" +#include "../shared/visualtestutil.h" + +#include <QtLabsTemplates/private/qquickapplicationwindow_p.h> +#include <QtLabsTemplates/private/qquickbutton_p.h> +#include <QtLabsTemplates/private/qquickmenu_p.h> +#include <QtLabsTemplates/private/qquickmenuitem_p.h> + +using namespace QQuickVisualTestUtil; + +class ApplicationHelper +{ +public: + ApplicationHelper(QQmlDataTest *testCase, const QString &testFilePath = QLatin1String("applicationwindow.qml")) : + component(&engine) + { + component.loadUrl(testCase->testFileUrl(testFilePath)); + QObject *rootObject = component.create(); + cleanup.reset(rootObject); + QVERIFY2(rootObject, qPrintable(QString::fromLatin1("Failed to create ApplicationWindow: %1").arg(component.errorString()))); + + window = qobject_cast<QQuickApplicationWindow*>(rootObject); + QVERIFY(window); + QVERIFY(!window->isVisible()); + } + + QQmlEngine engine; + QQmlComponent component; + QScopedPointer<QObject> cleanup; + QQuickApplicationWindow *window; +}; + +class tst_menu : public QQmlDataTest +{ + Q_OBJECT + +public: + +private slots: + void defaults(); + void mouse(); + void contextMenuKeyboard(); + void menuButton(); +}; + +void tst_menu::defaults() +{ + ApplicationHelper helper(this); + + QQuickMenu *emptyMenu = helper.window->property("emptyMenu").value<QQuickMenu*>(); + QCOMPARE(emptyMenu->isVisible(), false); + QCOMPARE(emptyMenu->contentItem()->property("currentIndex"), QVariant(-1)); +} + +void tst_menu::mouse() +{ + ApplicationHelper helper(this); + + QQuickApplicationWindow *window = helper.window; + window->show(); + QVERIFY(QTest::qWaitForWindowActive(window)); + + QQuickMenu *menu = window->property("menu").value<QQuickMenu*>(); + menu->show(); + QVERIFY(menu->isVisible()); + QVERIFY(window->overlay()->childItems().contains(menu->contentItem())); + + QQuickItem *firstItem = menu->itemAt(0); + QSignalSpy clickedSpy(firstItem, SIGNAL(clicked(QQuickMouseEvent*))); + QSignalSpy triggeredSpy(firstItem, SIGNAL(triggered())); + QSignalSpy visibleSpy(menu, SIGNAL(visibleChanged())); + + // Ensure that presses cause the current index to change, + // so that the highlight acts as a way of illustrating press state. + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(firstItem->width() / 2, firstItem->height() / 2)); + QVERIFY(firstItem->hasActiveFocus()); + QCOMPARE(menu->contentItem()->property("currentIndex"), QVariant(0)); + QVERIFY(menu->isVisible()); + + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(firstItem->width() / 2, firstItem->height() / 2)); + QCOMPARE(clickedSpy.count(), 1); + QCOMPARE(triggeredSpy.count(), 1); + QCOMPARE(visibleSpy.count(), 1); + QVERIFY(!menu->isVisible()); + QVERIFY(!window->overlay()->childItems().contains(menu->contentItem())); + QCOMPARE(menu->contentItem()->property("currentIndex"), QVariant(-1)); + + menu->show(); + QCOMPARE(visibleSpy.count(), 2); + QVERIFY(menu->isVisible()); + QVERIFY(window->overlay()->childItems().contains(menu->contentItem())); + + // Ensure that we have enough space to click outside of the menu. + QVERIFY(window->width() > menu->contentItem()->width()); + QVERIFY(window->height() > menu->contentItem()->height()); + QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, + QPoint(menu->contentItem()->width() + 1, menu->contentItem()->height() + 1)); + QCOMPARE(visibleSpy.count(), 3); + QVERIFY(!menu->isVisible()); + QVERIFY(!window->overlay()->childItems().contains(menu->contentItem())); + + menu->show(); + QCOMPARE(visibleSpy.count(), 4); + QVERIFY(menu->isVisible()); + QVERIFY(window->overlay()->childItems().contains(menu->contentItem())); + + // Try pressing within the menu and releasing outside of it; it should close. + // TODO: won't work until QQuickPanel::releasedOutside() actually gets emitted +// QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(firstItem->width() / 2, firstItem->height() / 2)); +// QVERIFY(firstItem->hasActiveFocus()); +// QCOMPARE(menu->contentItem()->property("currentIndex"), QVariant(0)); +// QVERIFY(menu->isVisible()); +// QCOMPARE(triggeredSpy.count(), 1); + +// QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(menu->contentItem()->width() + 1, firstItem->height() / 2)); +// QCOMPARE(clickedSpy.count(), 1); +// QCOMPARE(triggeredSpy.count(), 1); +// QCOMPARE(visibleSpy.count(), 5); +// QVERIFY(!menu->isVisible()); +// QVERIFY(!window->overlay()->childItems().contains(menu->contentItem())); +// QCOMPARE(menu->contentItem()->property("currentIndex"), QVariant(-1)); +} + +void tst_menu::contextMenuKeyboard() +{ + if (QGuiApplication::styleHints()->tabFocusBehavior() != Qt::TabFocusAllControls) + QSKIP("This platform only allows tab focus for text controls"); + + ApplicationHelper helper(this); + + QQuickApplicationWindow *window = helper.window; + window->show(); + window->requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(window)); + QVERIFY(QGuiApplication::focusWindow() == window); + + QQuickMenu *menu = window->property("menu").value<QQuickMenu*>(); + QCOMPARE(menu->contentItem()->property("currentIndex"), QVariant(-1)); + + QQuickItem *firstItem = menu->itemAt(0); + QSignalSpy visibleSpy(menu, SIGNAL(visibleChanged())); + + menu->setFocus(true); + menu->show(); + QCOMPARE(visibleSpy.count(), 1); + QVERIFY(menu->isVisible()); + QVERIFY(window->overlay()->childItems().contains(menu->contentItem())); + QVERIFY(!firstItem->hasActiveFocus()); + QCOMPARE(menu->contentItem()->property("currentIndex"), QVariant(-1)); + + QTest::keyClick(window, Qt::Key_Tab); + QVERIFY(firstItem->hasActiveFocus()); + QCOMPARE(menu->contentItem()->property("currentIndex"), QVariant(0)); + + QQuickItem *secondItem = menu->itemAt(1); + QTest::keyClick(window, Qt::Key_Tab); + QVERIFY(!firstItem->hasActiveFocus()); + QVERIFY(secondItem->hasActiveFocus()); + QCOMPARE(menu->contentItem()->property("currentIndex"), QVariant(1)); + + QSignalSpy secondTriggeredSpy(secondItem, SIGNAL(triggered())); + QTest::keyClick(window, Qt::Key_Space); + QCOMPARE(secondTriggeredSpy.count(), 1); + QCOMPARE(visibleSpy.count(), 2); + QVERIFY(!menu->isVisible()); + QVERIFY(!window->overlay()->childItems().contains(menu->contentItem())); + QVERIFY(!firstItem->hasActiveFocus()); + QVERIFY(!secondItem->hasActiveFocus()); + QCOMPARE(menu->contentItem()->property("currentIndex"), QVariant(-1)); + + menu->show(); + QCOMPARE(visibleSpy.count(), 3); + QVERIFY(menu->isVisible()); + QVERIFY(window->overlay()->childItems().contains(menu->contentItem())); + QVERIFY(!firstItem->hasActiveFocus()); + QVERIFY(!secondItem->hasActiveFocus()); + QCOMPARE(menu->contentItem()->property("currentIndex"), QVariant(-1)); + + QTest::keyClick(window, Qt::Key_Down); + QVERIFY(firstItem->hasActiveFocus()); + + QTest::keyClick(window, Qt::Key_Down); + QVERIFY(secondItem->hasActiveFocus()); + + QTest::keyClick(window, Qt::Key_Down); + QQuickItem *thirdItem = menu->itemAt(2); + QVERIFY(!firstItem->hasActiveFocus()); + QVERIFY(!secondItem->hasActiveFocus()); + QVERIFY(thirdItem->hasActiveFocus()); + + // Key navigation shouldn't wrap by default. + QTest::keyClick(window, Qt::Key_Down); + QVERIFY(!firstItem->hasActiveFocus()); + QVERIFY(!secondItem->hasActiveFocus()); + QVERIFY(thirdItem->hasActiveFocus()); +} + +void tst_menu::menuButton() +{ + if (QGuiApplication::styleHints()->tabFocusBehavior() != Qt::TabFocusAllControls) + QSKIP("This platform only allows tab focus for text controls"); + + ApplicationHelper helper(this); + + QQuickApplicationWindow *window = helper.window; + window->show(); + window->requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(window)); + QVERIFY(QGuiApplication::focusWindow() == window); + + QQuickMenu *menu = window->property("menu").value<QQuickMenu*>(); + QQuickButton *menuButton = window->property("menuButton").value<QQuickButton*>(); + QSignalSpy visibleSpy(menu, SIGNAL(visibleChanged())); + + menuButton->setVisible(true); + QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, + menuButton->mapToScene(QPointF(menuButton->width() / 2, menuButton->height() / 2)).toPoint()); + QCOMPARE(visibleSpy.count(), 1); + QVERIFY(menu->isVisible()); + + QTest::keyClick(window, Qt::Key_Tab); + QQuickItem *firstItem = menu->itemAt(0); + QVERIFY(firstItem->hasActiveFocus()); +} + +QTEST_MAIN(tst_menu) + +#include "tst_menu.moc" diff --git a/tests/auto/pressandhold/pressandhold.pro b/tests/auto/pressandhold/pressandhold.pro new file mode 100644 index 00000000..ca76b74a --- /dev/null +++ b/tests/auto/pressandhold/pressandhold.pro @@ -0,0 +1,9 @@ +TEMPLATE = app +TARGET = tst_pressandhold + +QT += quick testlib +CONFIG += testcase +osx:CONFIG -= app_bundle + +SOURCES += \ + $$PWD/tst_pressandhold.cpp diff --git a/tests/auto/pressandhold/tst_pressandhold.cpp b/tests/auto/pressandhold/tst_pressandhold.cpp new file mode 100644 index 00000000..33d93cc0 --- /dev/null +++ b/tests/auto/pressandhold/tst_pressandhold.cpp @@ -0,0 +1,197 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite 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 <QtTest> +#include <QtQuick> + +// TODO: add QStyleHints::setMousePressAndHoldInterval() to speedup the test + +class tst_PressAndHold : public QObject +{ + Q_OBJECT + +private slots: + void pressAndHold_data(); + void pressAndHold(); + + void keepSelection_data(); + void keepSelection(); +}; + +void tst_PressAndHold::pressAndHold_data() +{ + QTest::addColumn<QByteArray>("data"); + + QTest::newRow("TextField") << QByteArray("import Qt.labs.controls 1.0; TextField { text: 'TextField' }"); + QTest::newRow("TextArea") << QByteArray("import Qt.labs.controls 1.0; TextArea { text: 'TextArea' }"); +} + +void tst_PressAndHold::pressAndHold() +{ + QFETCH(QByteArray, data); + + QQmlEngine engine; + QQmlComponent component(&engine); + component.setData(data, QUrl()); + + QScopedPointer<QObject> control(component.create()); + QScopedPointer<QObject> waitControl(component.create()); + QVERIFY(!control.isNull() && !waitControl.isNull()); + + QSignalSpy spy(control.data(), SIGNAL(pressAndHold(QQuickMouseEvent*))); + QSignalSpy waitSpy(waitControl.data(), SIGNAL(pressAndHold(QQuickMouseEvent*))); + QVERIFY(spy.isValid() && waitSpy.isValid()); + + int startDragDistance = QGuiApplication::styleHints()->startDragDistance(); + QMouseEvent press(QEvent::MouseButtonPress, QPointF(), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier); + QMouseEvent press2(QEvent::MouseButtonPress, QPointF(), Qt::RightButton, Qt::RightButton, Qt::NoModifier); + QMouseEvent move(QEvent::MouseMove, QPointF(2 * startDragDistance, 2 * startDragDistance), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier); + QMouseEvent release(QEvent::MouseButtonRelease, QPointF(), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier); + + // pressAndHold() emitted + QGuiApplication::sendEvent(control.data(), &press); + QTRY_COMPARE(spy.count(), 1); + QGuiApplication::sendEvent(control.data(), &release); + QCOMPARE(spy.count(), 1); + spy.clear(); + + // pressAndHold() canceled by release + QGuiApplication::sendEvent(control.data(), &press); + QGuiApplication::processEvents(); + QGuiApplication::sendEvent(control.data(), &release); + QCOMPARE(spy.count(), 0); + + // pressAndHold() canceled by move + QGuiApplication::sendEvent(control.data(), &press); + QGuiApplication::sendEvent(control.data(), &move); // cancels pressAndHold() + QGuiApplication::sendEvent(waitControl.data(), &press); + // by the time the second control emits pressAndHold(), we can reliably + // assume that the first control would have emitted pressAndHold() if it + // wasn't canceled as appropriate by the move event above + QTRY_COMPARE(waitSpy.count(), 1); + QCOMPARE(spy.count(), 0); + QGuiApplication::sendEvent(control.data(), &release); + QGuiApplication::sendEvent(waitControl.data(), &release); + QCOMPARE(waitSpy.count(), 1); + QCOMPARE(spy.count(), 0); + waitSpy.clear(); + + // pressAndHold() canceled by 2nd press + QGuiApplication::sendEvent(control.data(), &press); + QGuiApplication::sendEvent(control.data(), &press2); // cancels pressAndHold() + QGuiApplication::sendEvent(waitControl.data(), &press); + // by the time the second control emits pressAndHold(), we can reliably + // assume that the first control would have emitted pressAndHold() if it + // wasn't canceled as appropriate by the 2nd press event above + QTRY_COMPARE(waitSpy.count(), 1); + QCOMPARE(spy.count(), 0); + QGuiApplication::sendEvent(control.data(), &release); + QGuiApplication::sendEvent(waitControl.data(), &release); + QCOMPARE(waitSpy.count(), 1); + QCOMPARE(spy.count(), 0); + waitSpy.clear(); +} + +void tst_PressAndHold::keepSelection_data() +{ + QTest::addColumn<QByteArray>("data"); + + QTest::newRow("TextField") << QByteArray("import Qt.labs.controls 1.0; TextField { text: 'TextField' }"); + QTest::newRow("TextArea") << QByteArray("import Qt.labs.controls 1.0; TextArea { text: 'TextArea' }"); +} + +void tst_PressAndHold::keepSelection() +{ + QFETCH(QByteArray, data); + + QQmlEngine engine; + QQmlComponent component(&engine); + component.setData(data, QUrl()); + + QScopedPointer<QObject> control(component.create()); + QScopedPointer<QObject> waitControl(component.create()); + QVERIFY(!control.isNull() && !waitControl.isNull()); + + QSignalSpy spy(control.data(), SIGNAL(pressAndHold(QQuickMouseEvent*))); + QSignalSpy waitSpy(waitControl.data(), SIGNAL(pressAndHold(QQuickMouseEvent*))); + QVERIFY(spy.isValid() && waitSpy.isValid()); + + QMouseEvent press(QEvent::MouseButtonPress, QPointF(), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier); + QMouseEvent press2(QEvent::MouseButtonPress, QPointF(), Qt::RightButton, Qt::RightButton, Qt::NoModifier); + QMouseEvent release(QEvent::MouseButtonRelease, QPointF(), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier); + + QVERIFY(!control->property("text").toString().isEmpty()); + QVERIFY(QMetaObject::invokeMethod(control.data(), "selectAll")); + QCOMPARE(control->property("selectedText"), control->property("text")); + + // pressAndHold() emitted => selection remains + QGuiApplication::sendEvent(control.data(), &press); + QTRY_COMPARE(spy.count(), 1); + QGuiApplication::sendEvent(control.data(), &release); + QCOMPARE(spy.count(), 1); + QCOMPARE(control->property("selectedText"), control->property("text")); + spy.clear(); + + // pressAndHold() canceled by release => selection cleared + QGuiApplication::sendEvent(control.data(), &press); + QGuiApplication::processEvents(); + QGuiApplication::sendEvent(control.data(), &release); + QCOMPARE(spy.count(), 0); + QVERIFY(control->property("selectedText").toString().isEmpty()); + + QVERIFY(QMetaObject::invokeMethod(control.data(), "selectAll")); + QCOMPARE(control->property("selectedText"), control->property("text")); + + // pressAndHold() canceled by 2nd press => selection cleared + QGuiApplication::sendEvent(control.data(), &press); + QGuiApplication::sendEvent(control.data(), &press2); // cancels pressAndHold() + QGuiApplication::sendEvent(waitControl.data(), &press); + // by the time the second control emits pressAndHold(), we can reliably + // assume that the first control would have emitted pressAndHold() if it + // wasn't canceled as appropriate by the move event above + QTRY_COMPARE(waitSpy.count(), 1); + QCOMPARE(spy.count(), 0); + QGuiApplication::sendEvent(control.data(), &release); + QGuiApplication::sendEvent(waitControl.data(), &release); + QCOMPARE(waitSpy.count(), 1); + QCOMPARE(spy.count(), 0); + QVERIFY(control->property("selectedText").toString().isEmpty()); + waitSpy.clear(); +} + +QTEST_MAIN(tst_PressAndHold) + +#include "tst_pressandhold.moc" diff --git a/tests/auto/sanity/BLACKLIST b/tests/auto/sanity/BLACKLIST new file mode 100644 index 00000000..02e9a5f9 --- /dev/null +++ b/tests/auto/sanity/BLACKLIST @@ -0,0 +1,4 @@ +[signalHandlers:material/TextArea.qml] +* +[signalHandlers:material/TextField.qml] +* diff --git a/tests/auto/sanity/sanity.pro b/tests/auto/sanity/sanity.pro index 6eb87e37..3beb8fff 100644 --- a/tests/auto/sanity/sanity.pro +++ b/tests/auto/sanity/sanity.pro @@ -9,3 +9,6 @@ DEFINES += QQC2_IMPORT_PATH=\\\"$$QQC2_SOURCE_TREE/src/imports\\\" SOURCES += \ $$PWD/tst_sanity.cpp + +OTHER_FILES += \ + $$PWD/BLACKLIST diff --git a/tests/auto/sanity/tst_sanity.cpp b/tests/auto/sanity/tst_sanity.cpp index ac5bcfba..bc114d62 100644 --- a/tests/auto/sanity/tst_sanity.cpp +++ b/tests/auto/sanity/tst_sanity.cpp @@ -142,7 +142,7 @@ void tst_Sanity::initTestCase() it.next(); QFileInfo info = it.fileInfo(); if (info.dir().dirName() != QStringLiteral("snippets") && info.dir().dirName() != QStringLiteral("designer")) - files.insert(info.baseName(), info.filePath()); + files.insert(info.dir().dirName() + "/" + info.fileName(), info.filePath()); } } @@ -222,18 +222,26 @@ void tst_Sanity::signalHandlers_data() QTest::newRow(qPrintable(it.key())) << it.key() << it.value(); } +class AnchorValidator : public BaseValidator +{ +protected: + virtual bool visit(QQmlJS::AST::UiScriptBinding *node) + { + QQmlJS::AST::UiQualifiedId* id = node->qualifiedId; + if (id && id->name == QStringLiteral("anchors")) + addError("anchors are not allowed", node); + return true; + } +}; + void tst_Sanity::anchors() { QFETCH(QString, control); QFETCH(QString, filePath); - QQmlComponent component(&engine); - component.loadUrl(QUrl::fromLocalFile(filePath)); - - QScopedPointer<QObject> object(component.create()); - QVERIFY(object.data()); - foreach (QObject *object, *qt_qobjects) - QVERIFY2(!object->inherits("QQuickAnchors"), "Anchors are not allowed"); + AnchorValidator validator; + if (!validator.validate(filePath)) + QFAIL(qPrintable(validator.errors())); } void tst_Sanity::anchors_data() @@ -246,33 +254,61 @@ void tst_Sanity::anchors_data() QTest::newRow(qPrintable(it.key())) << it.key() << it.value(); } +static void addTestRows(QQmlEngine *engine, const QString &targetPath, const QStringList &skiplist = QStringList()) +{ + // We cannot use QQmlComponent to load QML files directly from the source tree. + // For styles that use internal QML types (eg. material/Ripple.qml), the source + // dir would be added as an "implicit" import path overriding the actual import + // path (qtbase/qml/Qt/labs/controls/material). => The QML engine fails to load + // the style C++ plugin from the implicit import path (the source dir). + // + // Therefore we only use the source tree for finding out the set of QML files that + // a particular style implements, and then we locate the respective QML files in + // the engine's import path. This way we can use QQmlComponent to load each QML file + // for benchmarking. + + QFileInfoList entries = QDir(QQC2_IMPORT_PATH + targetPath).entryInfoList(QStringList("*.qml"), QDir::Files); + foreach (const QFileInfo &entry, entries) { + QString name = entry.baseName(); + if (!skiplist.contains(name)) { + foreach (const QString &importPath, engine->importPathList()) { + QString filePath = QDir(importPath + "/Qt/labs/" + targetPath).absoluteFilePath(entry.fileName()); + if (QFile::exists(filePath)) { + QTest::newRow(qPrintable(entry.dir().dirName() + "/" + entry.fileName())) << QUrl::fromLocalFile(filePath); + break; + } + } + } + } +} + void tst_Sanity::attachedObjects() { - QFETCH(QString, control); - QFETCH(QString, filePath); + QFETCH(QUrl, url); QQmlComponent component(&engine); - component.loadUrl(QUrl::fromLocalFile(filePath)); + component.loadUrl(url); QSet<QString> classNames; QScopedPointer<QObject> object(component.create()); - QVERIFY(object.data()); + QVERIFY2(object.data(), qPrintable(component.errorString())); foreach (QObject *object, *qt_qobjects) { + if (object->parent() == &engine) + continue; // allow "global" instances QString className = object->metaObject()->className(); - if (className.endsWith("Attached")) - QVERIFY2(!classNames.contains(className), qPrintable(QString("Multiple instances of attached type %1").arg(className))); + if (className.endsWith("Attached") || className.endsWith("Style")) + QVERIFY2(!classNames.contains(className), qPrintable(QString("Multiple %1 instances").arg(className))); classNames.insert(className); } } void tst_Sanity::attachedObjects_data() { - QTest::addColumn<QString>("control"); - QTest::addColumn<QString>("filePath"); - - QMap<QString, QString>::const_iterator it; - for (it = files.constBegin(); it != files.constEnd(); ++it) - QTest::newRow(qPrintable(it.key())) << it.key() << it.value(); + QTest::addColumn<QUrl>("url"); + addTestRows(&engine, "/calendar"); + addTestRows(&engine, "/controls"); + addTestRows(&engine, "/controls/material", QStringList() << "Ripple" << "SliderHandle"); + addTestRows(&engine, "/controls/universal"); } QTEST_MAIN(tst_Sanity) diff --git a/tests/auto/snippets/tst_snippets.cpp b/tests/auto/snippets/tst_snippets.cpp index de9aa281..2c6fe6f8 100644 --- a/tests/auto/snippets/tst_snippets.cpp +++ b/tests/auto/snippets/tst_snippets.cpp @@ -3,7 +3,7 @@ ** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** -** This file is part of the tools applications of the Qt Toolkit. +** This file is part of the test suite of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL3$ ** Commercial License Usage diff --git a/tests/auto/styles/styles.pro b/tests/auto/styles/styles.pro new file mode 100644 index 00000000..3460900c --- /dev/null +++ b/tests/auto/styles/styles.pro @@ -0,0 +1,8 @@ +TEMPLATE = app +TARGET = tst_styles +CONFIG += qmltestcase + +DEFINES += TST_CONTROLS_DATA=\\\"$$QQC2_SOURCE_TREE/tests/auto/controls/data\\\" + +SOURCES += \ + $$PWD/tst_styles.cpp diff --git a/tests/auto/styles/tst_styles.cpp b/tests/auto/styles/tst_styles.cpp new file mode 100644 index 00000000..b45366b6 --- /dev/null +++ b/tests/auto/styles/tst_styles.cpp @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite 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 <QtCore/qcoreapplication.h> +#include <QtCore/qprocess.h> +#include <QtQuickTest/quicktest.h> + +static const char* styles[] = { "material", "universal" }; + +int main(int argc, char *argv[]) +{ + QByteArray style = qgetenv("QT_LABS_CONTROLS_STYLE"); + if (!style.isEmpty()) + return quick_test_main(argc, argv, "tst_styles(" + style + ")", TST_CONTROLS_DATA); + + QCoreApplication app(argc, argv); + + int failures = 0; + int count = sizeof(styles) / sizeof(styles[0]); + + for (int i = 0; i < count; ++i) { + QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); + env.insert("QT_LABS_CONTROLS_STYLE", styles[i]); + + QProcess process; + process.setProcessEnvironment(env); + process.setWorkingDirectory(QDir::currentPath()); + process.setProcessChannelMode(QProcess::ForwardedChannels); + + process.start(argv[0], app.arguments().mid(1)); + process.waitForFinished(); + + failures += process.exitCode(); + } + + return failures; +} diff --git a/tests/auto/theme/data/tst_theme.qml b/tests/auto/theme/data/tst_theme.qml deleted file mode 100644 index 03c19fc6..00000000 --- a/tests/auto/theme/data/tst_theme.qml +++ /dev/null @@ -1,295 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.2 -import QtQuick.Window 2.2 -import QtTest 1.0 -import Qt.labs.controls 1.0 - -TestCase { - id: testCase - width: 200 - height: 200 - visible: true - when: windowShown - name: "Theme" - - Component { - id: button - Button { } - } - - Component { - id: themedButton - Button { - Theme.accentColor: "#111111" - Theme.backgroundColor: "#222222" - Theme.baseColor: "#333333" - Theme.disabledColor: "#aaaaaa" - Theme.focusColor: "#444444" - Theme.frameColor: "#555555" - Theme.pressColor: "#666666" - Theme.selectedTextColor: "#777777" - Theme.selectionColor: "#888888" - Theme.textColor: "#999999" - } - } - - Component { - id: window - Window { } - } - - Component { - id: themedWindow - Window { - Theme.accentColor: "#111111" - Theme.backgroundColor: "#222222" - Theme.baseColor: "#333333" - Theme.disabledColor: "#aaaaaa" - Theme.focusColor: "#444444" - Theme.frameColor: "#555555" - Theme.pressColor: "#666666" - Theme.selectedTextColor: "#777777" - Theme.selectionColor: "#888888" - Theme.textColor: "#999999" - } - } - - Component { - id: loader - Loader { - active: false - sourceComponent: Button { } - } - } - - Component { - id: swipeView - SwipeView { - Theme.accentColor: "#111111" - Button { } - } - } - - function test_defaults() { - var control = button.createObject(testCase) - verify(control) - verify(control.Theme) - verify(control.Theme.accentColor !== undefined) - verify(control.Theme.backgroundColor !== undefined) - verify(control.Theme.baseColor !== undefined) - verify(control.Theme.disabledColor !== undefined) - verify(control.Theme.focusColor !== undefined) - verify(control.Theme.frameColor !== undefined) - verify(control.Theme.pressColor !== undefined) - verify(control.Theme.selectedTextColor !== undefined) - verify(control.Theme.selectionColor !== undefined) - verify(control.Theme.textColor !== undefined) - control.destroy() - } - - function test_set() { - var control = button.createObject(testCase) - verify(control) - control.Theme.accentColor = "#111111" - control.Theme.backgroundColor = "#222222" - control.Theme.baseColor = "#333333" - control.Theme.disabledColor = "#aaaaaa" - control.Theme.focusColor = "#444444" - control.Theme.frameColor = "#555555" - control.Theme.pressColor = "#666666" - control.Theme.selectedTextColor = "#777777" - control.Theme.selectionColor = "#888888" - control.Theme.textColor = "#999999" - compare(control.Theme.accentColor, "#111111") - compare(control.Theme.backgroundColor, "#222222") - compare(control.Theme.baseColor, "#333333") - compare(control.Theme.disabledColor, "#aaaaaa") - compare(control.Theme.focusColor, "#444444") - compare(control.Theme.frameColor, "#555555") - compare(control.Theme.pressColor, "#666666") - compare(control.Theme.selectedTextColor, "#777777") - compare(control.Theme.selectionColor, "#888888") - compare(control.Theme.textColor, "#999999") - control.destroy() - } - - function test_reset() { - var control = themedButton.createObject(testCase) - verify(control) - compare(control.Theme.accentColor, "#111111") - compare(control.Theme.backgroundColor, "#222222") - compare(control.Theme.baseColor, "#333333") - compare(control.Theme.disabledColor, "#aaaaaa") - compare(control.Theme.focusColor, "#444444") - compare(control.Theme.frameColor, "#555555") - compare(control.Theme.pressColor, "#666666") - compare(control.Theme.selectedTextColor, "#777777") - compare(control.Theme.selectionColor, "#888888") - compare(control.Theme.textColor, "#999999") - control.Theme.accentColor = undefined - control.Theme.backgroundColor = undefined - control.Theme.baseColor = undefined - control.Theme.disabledColor = undefined - control.Theme.focusColor = undefined - control.Theme.frameColor = undefined - control.Theme.pressColor = undefined - control.Theme.selectedTextColor = undefined - control.Theme.selectionColor = undefined - control.Theme.textColor = undefined - compare(control.Theme.accentColor, testCase.Theme.accentColor) - compare(control.Theme.backgroundColor, testCase.Theme.backgroundColor) - compare(control.Theme.baseColor, testCase.Theme.baseColor) - compare(control.Theme.disabledColor, testCase.Theme.disabledColor) - compare(control.Theme.focusColor, testCase.Theme.focusColor) - compare(control.Theme.frameColor, testCase.Theme.frameColor) - compare(control.Theme.pressColor, testCase.Theme.pressColor) - compare(control.Theme.selectedTextColor, testCase.Theme.selectedTextColor) - compare(control.Theme.selectionColor, testCase.Theme.selectionColor) - compare(control.Theme.textColor, testCase.Theme.textColor) - control.destroy() - } - - function test_inheritance_data() { - return [ - { tag: "accentColor", value1: "#111111", value2: "#101010" }, - { tag: "backgroundColor", value1: "#222222", value2: "#202020" }, - { tag: "baseColor", value1: "#333333", value2: "#303030" }, - { tag: "disabledColor", value1: "#aaaaaa", value2: "#a0a0a0" }, - { tag: "focusColor", value1: "#444444", value2: "#404040" }, - { tag: "frameColor", value1: "#555555", value2: "#505050" }, - { tag: "pressColor", value1: "#666666", value2: "#606060" }, - { tag: "selectedTextColor", value1: "#777777", value2: "#707070" }, - { tag: "selectionColor", value1: "#888888", value2: "#808080" }, - { tag: "textColor", value1: "#999999", value2: "#909090" } - ] - } - - function test_inheritance(data) { - var prop = data.tag - var parent = button.createObject(testCase) - parent.Theme[prop] = data.value1 - compare(parent.Theme[prop], data.value1) - - var child1 = button.createObject(parent) - compare(child1.Theme[prop], data.value1) - - parent.Theme[prop] = data.value2 - compare(parent.Theme[prop], data.value2) - compare(child1.Theme[prop], data.value2) - - var child2 = button.createObject(parent) - compare(child2.Theme[prop], data.value2) - - child2.Theme[prop] = data.value1 - compare(child2.Theme[prop], data.value1) - compare(child1.Theme[prop], data.value2) - compare(parent.Theme[prop], data.value2) - - parent.Theme[prop] = undefined - verify(parent.Theme[prop] !== data.value1) - verify(parent.Theme[prop] !== data.value2) - verify(parent.Theme[prop] !== undefined) - compare(child1.Theme[prop], parent.Theme[prop]) - verify(child2.Theme[prop] !== parent.Theme[prop]) - - var grandChild1 = button.createObject(child1) - var grandChild2 = button.createObject(child2) - compare(grandChild1.Theme[prop], child1.Theme[prop]) - compare(grandChild2.Theme[prop], child2.Theme[prop]) - - var themelessGrandGrandChild = button.createObject(grandChild1) - var grandGrandGrandChild1 = button.createObject(themelessGrandGrandChild) - compare(grandGrandGrandChild1.Theme[prop], parent.Theme[prop]) - - child1.Theme[prop] = data.value2 - verify(parent.Theme[prop] !== data.value2) - compare(child1.Theme[prop], data.value2) - compare(grandChild1.Theme[prop], data.value2) - compare(grandGrandGrandChild1.Theme[prop], data.value2) - - parent.destroy() - } - - function test_window() { - var parent = window.createObject() - - var control = button.createObject(parent.contentItem) - compare(control.Theme.backgroundColor, parent.Theme.backgroundColor) - - var themedChild = themedWindow.createObject(window) - verify(themedChild.Theme.backgroundColor !== parent.Theme.backgroundColor) - - var unthemedChild = window.createObject(window) - compare(unthemedChild.Theme.backgroundColor, parent.Theme.backgroundColor) - - parent.Theme.backgroundColor = "#123456" - compare(control.Theme.backgroundColor, "#123456") - verify(themedChild.Theme.backgroundColor !== "#123456") - // ### FIXME: compare(unthemedChild.Theme.backgroundColor, "#123456") - - parent.destroy() - } - - function test_loader() { - var control = loader.createObject(testCase) - control.Theme.accentColor = "#111111" - control.active = true - compare(control.item.Theme.accentColor, "#111111") - control.Theme.accentColor = "#222222" - compare(control.item.Theme.accentColor, "#222222") - control.active = false - control.Theme.accentColor = "#333333" - control.active = true - compare(control.item.Theme.accentColor, "#333333") - control.destroy() - } - - function test_swipeView() { - var control = swipeView.createObject(testCase) - verify(control) - var child = control.itemAt(0) - verify(child) - compare(control.Theme.accentColor, "#111111") - compare(child.Theme.accentColor, "#111111") - control.destroy() - } -} diff --git a/tests/auto/universal/data/tst_universal.qml b/tests/auto/universal/data/tst_universal.qml new file mode 100644 index 00000000..912b2117 --- /dev/null +++ b/tests/auto/universal/data/tst_universal.qml @@ -0,0 +1,225 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.2 +import QtQuick.Window 2.2 +import QtTest 1.0 +import Qt.labs.controls 1.0 +import Qt.labs.controls.universal 1.0 + +TestCase { + id: testCase + width: 200 + height: 200 + visible: true + when: windowShown + name: "Universal" + + Component { + id: button + Button { } + } + + Component { + id: styledButton + Button { + Universal.theme: Universal.Dark + Universal.accent: Universal.Violet + } + } + + Component { + id: window + Window { } + } + + Component { + id: styledWindow + Window { + Universal.theme: Universal.Dark + Universal.accent: Universal.Green + } + } + + Component { + id: loader + Loader { + active: false + sourceComponent: Button { } + } + } + + Component { + id: swipeView + SwipeView { + Universal.theme: Universal.Dark + Button { } + } + } + + function test_defaults() { + var control = button.createObject(testCase) + verify(control) + verify(control.Universal) + compare(control.Universal.accent, Universal.Cobalt) + compare(control.Universal.theme, Universal.Light) + control.destroy() + } + + function test_set() { + var control = button.createObject(testCase) + verify(control) + control.Universal.accent = Universal.Steel + control.Universal.theme = Universal.Dark + compare(control.Universal.accent, Universal.Steel) + compare(control.Universal.theme, Universal.Dark) + control.destroy() + } + + function test_reset() { + var control = styledButton.createObject(testCase) + verify(control) + compare(control.Universal.accent, Universal.Violet) + compare(control.Universal.theme, Universal.Dark) + control.Universal.accent = undefined + control.Universal.theme = undefined + compare(control.Universal.accent, testCase.Universal.accent) + compare(control.Universal.theme, testCase.Universal.theme) + control.destroy() + } + + function test_inheritance_data() { + return [ + { tag: "accent", value1: Universal.Crimson, value2: Universal.Indigo }, + { tag: "theme", value1: Universal.Dark, value2: Universal.Light }, + ] + } + + function test_inheritance(data) { + var prop = data.tag + var parent = button.createObject(testCase) + parent.Universal[prop] = data.value1 + compare(parent.Universal[prop], data.value1) + + var child1 = button.createObject(parent) + compare(child1.Universal[prop], data.value1) + + parent.Universal[prop] = data.value2 + compare(parent.Universal[prop], data.value2) + compare(child1.Universal[prop], data.value2) + + var child2 = button.createObject(parent) + compare(child2.Universal[prop], data.value2) + + child2.Universal[prop] = data.value1 + compare(child2.Universal[prop], data.value1) + compare(child1.Universal[prop], data.value2) + compare(parent.Universal[prop], data.value2) + + parent.Universal[prop] = undefined + verify(parent.Universal[prop] !== data.value1) + verify(parent.Universal[prop] !== undefined) + compare(child1.Universal[prop], parent.Universal[prop]) + verify(child2.Universal[prop] !== parent.Universal[prop]) + + var grandChild1 = button.createObject(child1) + var grandChild2 = button.createObject(child2) + compare(grandChild1.Universal[prop], child1.Universal[prop]) + compare(grandChild2.Universal[prop], child2.Universal[prop]) + + var themelessGrandGrandChild = button.createObject(grandChild1) + var grandGrandGrandChild1 = button.createObject(themelessGrandGrandChild) + compare(grandGrandGrandChild1.Universal[prop], parent.Universal[prop]) + + child1.Universal[prop] = data.value2 + compare(child1.Universal[prop], data.value2) + compare(grandChild1.Universal[prop], data.value2) + compare(grandGrandGrandChild1.Universal[prop], data.value2) + + parent.destroy() + } + + function test_window() { + var parent = window.createObject() + + var control = button.createObject(parent.contentItem) + compare(control.Universal.accent, parent.Universal.accent) + compare(control.Universal.theme, parent.Universal.theme) + + var styledChild = styledWindow.createObject(window) + verify(styledChild.Universal.accent !== parent.Universal.accent) + verify(styledChild.Universal.theme !== parent.Universal.theme) + + var unstyledChild = window.createObject(window) + compare(unstyledChild.Universal.accent, parent.Universal.accent) + compare(unstyledChild.Universal.theme, parent.Universal.theme) + + parent.Universal.accent = Universal.Cyan + compare(control.Universal.accent, Universal.Cyan) + verify(styledChild.Universal.accent !== Universal.Cyan) + // ### TODO: compare(unstyledChild.Universal.accent, Universal.Cyan) + + parent.destroy() + } + + function test_loader() { + var control = loader.createObject(testCase) + control.Universal.accent = Universal.Lime + control.active = true + compare(control.item.Universal.accent, Universal.Lime) + control.Universal.accent = Universal.Pink + compare(control.item.Universal.accent, Universal.Pink) + control.active = false + control.Universal.accent = Universal.Brown + control.active = true + compare(control.item.Universal.accent, Universal.Brown) + control.destroy() + } + + function test_swipeView() { + var control = swipeView.createObject(testCase) + verify(control) + var child = control.itemAt(0) + verify(child) + compare(control.Universal.theme, Universal.Dark) + compare(child.Universal.theme, Universal.Dark) + control.destroy() + } +} diff --git a/tests/auto/universal/tst_universal.cpp b/tests/auto/universal/tst_universal.cpp new file mode 100644 index 00000000..ea42cc5e --- /dev/null +++ b/tests/auto/universal/tst_universal.cpp @@ -0,0 +1,38 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite 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 <QtQuickTest/quicktest.h> +QUICK_TEST_MAIN(tst_universal) diff --git a/tests/auto/universal/universal.pro b/tests/auto/universal/universal.pro new file mode 100644 index 00000000..3a21957c --- /dev/null +++ b/tests/auto/universal/universal.pro @@ -0,0 +1,12 @@ +TEMPLATE = app +TARGET = tst_universal +CONFIG += qmltestcase + +SOURCES += \ + $$PWD/tst_universal.cpp + +OTHER_FILES += \ + $$PWD/data/* + +TESTDATA += \ + $$PWD/data/tst_* diff --git a/tests/benchmarks/creationtime/tst_creationtime.cpp b/tests/benchmarks/creationtime/tst_creationtime.cpp index 3eccc654..2a61b0ea 100644 --- a/tests/benchmarks/creationtime/tst_creationtime.cpp +++ b/tests/benchmarks/creationtime/tst_creationtime.cpp @@ -47,6 +47,12 @@ private slots: void controls(); void controls_data(); + void material(); + void material_data(); + + void universal(); + void universal_data(); + void calendar(); void calendar_data(); @@ -59,21 +65,44 @@ void tst_CreationTime::init() engine.clearComponentCache(); } -static void addTestRows(const QString &path) +static void addTestRows(QQmlEngine *engine, const QString &targetPath, const QStringList &skiplist = QStringList()) { - QFileInfoList entries = QDir(path).entryInfoList(QStringList("*.qml"), QDir::Files); - foreach (const QFileInfo &entry, entries) - QTest::newRow(qPrintable(entry.baseName())) << QUrl::fromLocalFile(entry.absoluteFilePath()); + // We cannot use QQmlComponent to load QML files directly from the source tree. + // For styles that use internal QML types (eg. material/Ripple.qml), the source + // dir would be added as an "implicit" import path overriding the actual import + // path (qtbase/qml/Qt/labs/controls/material). => The QML engine fails to load + // the style C++ plugin from the implicit import path (the source dir). + // + // Therefore we only use the source tree for finding out the set of QML files that + // a particular style implements, and then we locate the respective QML files in + // the engine's import path. This way we can use QQmlComponent to load each QML file + // for benchmarking. + + QFileInfoList entries = QDir(QQC2_IMPORT_PATH + targetPath).entryInfoList(QStringList("*.qml"), QDir::Files); + foreach (const QFileInfo &entry, entries) { + QString name = entry.baseName(); + if (!skiplist.contains(name)) { + foreach (const QString &importPath, engine->importPathList()) { + QString filePath = QDir(importPath + "/Qt/labs/" + targetPath).absoluteFilePath(entry.fileName()); + if (QFile::exists(filePath)) { + QTest::newRow(qPrintable(name)) << QUrl::fromLocalFile(filePath); + break; + } + } + } + } } -static void doBenchmark(QQmlComponent *component) +static void doBenchmark(QQmlEngine *engine, const QUrl &url) { + QQmlComponent component(engine); + component.loadUrl(url); + QObjectList objects; objects.reserve(4096); QBENCHMARK { - QObject *object = component->create(); - if (!object) - qFatal("%s", qPrintable(component->errorString())); + QObject *object = component.create(); + QVERIFY2(object, qPrintable(component.errorString())); objects += object; } qDeleteAll(objects); @@ -82,29 +111,49 @@ static void doBenchmark(QQmlComponent *component) void tst_CreationTime::controls() { QFETCH(QUrl, url); - QQmlComponent component(&engine); - component.loadUrl(url); - doBenchmark(&component); + doBenchmark(&engine, url); } void tst_CreationTime::controls_data() { QTest::addColumn<QUrl>("url"); - addTestRows(QQC2_IMPORT_PATH "/controls"); + addTestRows(&engine, "/controls"); +} + +void tst_CreationTime::material() +{ + QFETCH(QUrl, url); + doBenchmark(&engine, url); +} + +void tst_CreationTime::material_data() +{ + QTest::addColumn<QUrl>("url"); + addTestRows(&engine, "/controls/material", QStringList() << "Ripple" << "SliderHandle"); +} + +void tst_CreationTime::universal() +{ + QFETCH(QUrl, url); + doBenchmark(&engine, url); +} + +void tst_CreationTime::universal_data() +{ + QTest::addColumn<QUrl>("url"); + addTestRows(&engine, "/controls/universal"); } void tst_CreationTime::calendar() { QFETCH(QUrl, url); - QQmlComponent component(&engine); - component.loadUrl(url); - doBenchmark(&component); + doBenchmark(&engine, url); } void tst_CreationTime::calendar_data() { QTest::addColumn<QUrl>("url"); - addTestRows(QQC2_IMPORT_PATH "/calendar"); + addTestRows(&engine, "/calendar"); } QTEST_MAIN(tst_CreationTime) diff --git a/tests/benchmarks/objectcount/objectcount.pro b/tests/benchmarks/objectcount/objectcount.pro index f54d72d6..2cda43d5 100644 --- a/tests/benchmarks/objectcount/objectcount.pro +++ b/tests/benchmarks/objectcount/objectcount.pro @@ -5,5 +5,7 @@ QT += quick testlib core-private CONFIG += testcase osx:CONFIG -= app_bundle +DEFINES += QQC2_IMPORT_PATH=\\\"$$QQC2_SOURCE_TREE/src/imports\\\" + SOURCES += \ tst_objectcount.cpp diff --git a/tests/benchmarks/objectcount/tst_objectcount.cpp b/tests/benchmarks/objectcount/tst_objectcount.cpp index b2170cd5..2d14e9eb 100644 --- a/tests/benchmarks/objectcount/tst_objectcount.cpp +++ b/tests/benchmarks/objectcount/tst_objectcount.cpp @@ -37,6 +37,7 @@ #include <QtTest> #include <QtQuick> #include <QtCore/private/qhooks_p.h> +#include <iostream> static int qt_verbose = qgetenv("VERBOSE").toInt() != 0; @@ -60,8 +61,20 @@ private slots: void init(); void cleanup(); - void testCount(); - void testCount_data(); + void calendar(); + void calendar_data(); + + void legacy(); + void legacy_data(); + + void controls(); + void controls_data(); + + void material(); + void material_data(); + + void universal(); + void universal_data(); private: QQmlEngine engine; @@ -84,178 +97,177 @@ void tst_ObjectCount::cleanup() qtHookData[QHooks::RemoveQObject] = 0; } -static void printItems(const QString &prefix, const QList<QQuickItem *> &items) +static void printItems(const QList<QQuickItem *> &items) { - qInfo() << prefix << "QQuickItems:" << items.count() << "(total of QObjects:" << qt_qobjects->count() << ")"; + std::cout << "RESULT tst_ObjectCount::" << QTest::currentTestFunction() << "():\"" << QTest::currentDataTag() << "\":" << std::endl; + std::cout << " QQuickItems: " << items.count() << " (total of QObjects: " << qt_qobjects->count() << ")" << std::endl; + if (qt_verbose) { foreach (QObject *object, *qt_qobjects) qInfo() << "\t" << object; } } -void tst_ObjectCount::testCount() +static void addTestRows(QQmlEngine *engine, const QString &targetPath, const QStringList &skiplist = QStringList()) { - QFETCH(QByteArray, v1); - QFETCH(QByteArray, v2); + // We cannot use QQmlComponent to load QML files directly from the source tree. + // For styles that use internal QML types (eg. material/Ripple.qml), the source + // dir would be added as an "implicit" import path overriding the actual import + // path (qtbase/qml/Qt/labs/controls/material). => The QML engine fails to load + // the style C++ plugin from the implicit import path (the source dir). + // + // Therefore we only use the source tree for finding out the set of QML files that + // a particular style implements, and then we locate the respective QML files in + // the engine's import path. This way we can use QQmlComponent to load each QML file + // for benchmarking. + + QFileInfoList entries = QDir(QQC2_IMPORT_PATH + targetPath).entryInfoList(QStringList("*.qml"), QDir::Files); + foreach (const QFileInfo &entry, entries) { + QString name = entry.baseName(); + if (!skiplist.contains(name)) { + foreach (const QString &importPath, engine->importPathList()) { + QString filePath = QDir(importPath + "/Qt/labs/" + targetPath).absoluteFilePath(entry.fileName()); + if (QFile::exists(filePath)) { + QTest::newRow(qPrintable(name)) << QUrl::fromLocalFile(filePath); + break; + } + } + } + } +} - if (!v1.isEmpty()) { - QQmlComponent component(&engine); +static void doBenchmark(QQmlEngine *engine, const QUrl &url) +{ + QQmlComponent component(engine); - qt_qobjects->clear(); + qt_qobjects->clear(); - component.setData(v1, QUrl()); - QScopedPointer<QObject> object(component.create()); - QVERIFY2(object.data(), qPrintable(component.errorString())); + component.loadUrl(url); + QScopedPointer<QObject> object(component.create()); + QVERIFY2(object.data(), qPrintable(component.errorString())); - QList<QQuickItem *> items; - foreach (QObject *object, *qt_qobjects()) { - QQuickItem *item = qobject_cast<QQuickItem *>(object); - if (item) - items += item; - } - printItems("V1", items); + QList<QQuickItem *> items; + foreach (QObject *object, *qt_qobjects()) { + QQuickItem *item = qobject_cast<QQuickItem *>(object); + if (item) + items += item; } + printItems(items); +} +void tst_ObjectCount::calendar() +{ + QFETCH(QUrl, url); + doBenchmark(&engine, url); +} - if (!v2.isEmpty()) { - QQmlComponent component(&engine); +void tst_ObjectCount::calendar_data() +{ + QTest::addColumn<QUrl>("url"); + addTestRows(&engine, "/calendar"); +} - qt_qobjects->clear(); +void tst_ObjectCount::legacy() +{ + QFETCH(QByteArray, data); - component.setData(v2, QUrl()); - QScopedPointer<QObject> object(component.create()); - QVERIFY2(object.data(), qPrintable(component.errorString())); + QQmlComponent component(&engine); - QList<QQuickItem *> items; - foreach (QObject *object, *qt_qobjects()) { - QQuickItem *item = qobject_cast<QQuickItem *>(object); - if (item) - items += item; - } - printItems("V2", items); + qt_qobjects->clear(); + + component.setData(data, QUrl()); + QScopedPointer<QObject> object(component.create()); + QVERIFY2(object.data(), qPrintable(component.errorString())); + + QList<QQuickItem *> items; + foreach (QObject *object, *qt_qobjects()) { + QQuickItem *item = qobject_cast<QQuickItem *>(object); + if (item) + items += item; } + printItems(items); } -void tst_ObjectCount::testCount_data() +void tst_ObjectCount::legacy_data() { - QTest::addColumn<QByteArray>("v1"); - QTest::addColumn<QByteArray>("v2"); + QTest::addColumn<QByteArray>("data"); QTest::newRow("ApplicationWindow") - << QByteArray("import QtQuick.Controls 1.3; ApplicationWindow { }") - << QByteArray("import Qt.labs.controls 1.0; ApplicationWindow { }"); - + << QByteArray("import QtQuick.Controls 1.3; ApplicationWindow { }"); QTest::newRow("BusyIndicator") - << QByteArray("import QtQuick.Controls 1.3; BusyIndicator { }") - << QByteArray("import Qt.labs.controls 1.0; BusyIndicator { }"); - + << QByteArray("import QtQuick.Controls 1.3; BusyIndicator { }"); QTest::newRow("Button") - << QByteArray("import QtQuick.Controls 1.3; Button { }") - << QByteArray("import Qt.labs.controls 1.0; Button { }"); - + << QByteArray("import QtQuick.Controls 1.3; Button { }"); QTest::newRow("CheckBox") - << QByteArray("import QtQuick.Controls 1.3; CheckBox { }") - << QByteArray("import Qt.labs.controls 1.0; CheckBox { }"); - + << QByteArray("import QtQuick.Controls 1.3; CheckBox { }"); QTest::newRow("Dial") - << QByteArray("import QtQuick.Extras 1.3; Dial { }") - << QByteArray("import Qt.labs.controls 1.0; Dial { }"); - - QTest::newRow("Drawer") - << QByteArray() - << QByteArray("import Qt.labs.controls 1.0; Drawer { }"); - - QTest::newRow("Frame") - << QByteArray() - << QByteArray("import Qt.labs.controls 1.0; Frame { }"); - + << QByteArray("import QtQuick.Extras 1.3; Dial { }"); QTest::newRow("GroupBox") - << QByteArray("import QtQuick.Controls 1.3; GroupBox { }") - << QByteArray("import Qt.labs.controls 1.0; GroupBox { }"); - + << QByteArray("import QtQuick.Controls 1.3; GroupBox { }"); QTest::newRow("Label") - << QByteArray("import QtQuick.Controls 1.3; Label { }") - << QByteArray("import Qt.labs.controls 1.0; Label { }"); - - QTest::newRow("PageIndicator") - << QByteArray() - << QByteArray("import Qt.labs.controls 1.0; PageIndicator { }"); - + << QByteArray("import QtQuick.Controls 1.3; Label { }"); QTest::newRow("ProgressBar") - << QByteArray("import QtQuick.Controls 1.3; ProgressBar { }") - << QByteArray("import Qt.labs.controls 1.0; ProgressBar { }"); - + << QByteArray("import QtQuick.Controls 1.3; ProgressBar { }"); QTest::newRow("RadioButton") - << QByteArray("import QtQuick.Controls 1.3; RadioButton { }") - << QByteArray("import Qt.labs.controls 1.0; RadioButton { }"); - - QTest::newRow("RangeSlider") - << QByteArray() - << QByteArray("import Qt.labs.controls 1.0; RangeSlider { }"); - + << QByteArray("import QtQuick.Controls 1.3; RadioButton { }"); QTest::newRow("ScrollView") - << QByteArray("import QtQuick.Controls 1.3; ScrollView { }") - << QByteArray(); - - QTest::newRow("ScrollIndicator") - << QByteArray() - << QByteArray("import Qt.labs.controls 1.0; ScrollIndicator { }"); - - QTest::newRow("ScrollBar") - << QByteArray() - << QByteArray("import Qt.labs.controls 1.0; ScrollBar { }"); - + << QByteArray("import QtQuick.Controls 1.3; ScrollView { }"); QTest::newRow("Slider") - << QByteArray("import QtQuick.Controls 1.3; Slider { }") - << QByteArray("import Qt.labs.controls 1.0; Slider { }"); - + << QByteArray("import QtQuick.Controls 1.3; Slider { }"); QTest::newRow("SpinBox") - << QByteArray("import QtQuick.Controls 1.3; SpinBox { }") - << QByteArray("import Qt.labs.controls 1.0; SpinBox { }"); - + << QByteArray("import QtQuick.Controls 1.3; SpinBox { }"); QTest::newRow("StackView") - << QByteArray("import QtQuick.Controls 1.3; StackView { }") - << QByteArray("import Qt.labs.controls 1.0; StackView { }"); - - QTest::newRow("SwipeView") - << QByteArray() - << QByteArray("import Qt.labs.controls 1.0; SwipeView { }"); - + << QByteArray("import QtQuick.Controls 1.3; StackView { }"); QTest::newRow("Switch") - << QByteArray("import QtQuick.Controls 1.3; Switch { }") - << QByteArray("import Qt.labs.controls 1.0; Switch { }"); - - QTest::newRow("TabBar") - << QByteArray() - << QByteArray("import Qt.labs.controls 1.0; TabBar { }"); - - QTest::newRow("TabButton") - << QByteArray() - << QByteArray("import Qt.labs.controls 1.0; TabButton { }"); - + << QByteArray("import QtQuick.Controls 1.3; Switch { }"); QTest::newRow("TabView") - << QByteArray("import QtQuick.Controls 1.3; TabView { }") - << QByteArray(); - + << QByteArray("import QtQuick.Controls 1.3; TabView { }"); QTest::newRow("TextArea") - << QByteArray("import QtQuick.Controls 1.3; TextArea { }") - << QByteArray("import Qt.labs.controls 1.0; TextArea { }"); - + << QByteArray("import QtQuick.Controls 1.3; TextArea { }"); QTest::newRow("TextField") - << QByteArray("import QtQuick.Controls 1.3; TextField { }") - << QByteArray("import Qt.labs.controls 1.0; TextField { }"); - + << QByteArray("import QtQuick.Controls 1.3; TextField { }"); QTest::newRow("ToolBar") - << QByteArray("import QtQuick.Controls 1.3; ToolBar { }") - << QByteArray("import Qt.labs.controls 1.0; ToolBar { }"); - + << QByteArray("import QtQuick.Controls 1.3; ToolBar { }"); QTest::newRow("ToolButton") - << QByteArray("import QtQuick.Controls 1.3; ToolButton { }") - << QByteArray("import Qt.labs.controls 1.0; ToolButton { }"); - + << QByteArray("import QtQuick.Controls 1.3; ToolButton { }"); QTest::newRow("Tumbler") - << QByteArray("import QtQuick.Extras 1.3; Tumbler { }") - << QByteArray("import Qt.labs.controls 1.0; Tumbler { }"); + << QByteArray("import QtQuick.Extras 1.3; Tumbler { }"); +} + +void tst_ObjectCount::controls() +{ + QFETCH(QUrl, url); + doBenchmark(&engine, url); +} + +void tst_ObjectCount::controls_data() +{ + QTest::addColumn<QUrl>("url"); + addTestRows(&engine, "/controls"); +} + +void tst_ObjectCount::material() +{ + QFETCH(QUrl, url); + doBenchmark(&engine, url); +} + +void tst_ObjectCount::material_data() +{ + QTest::addColumn<QUrl>("url"); + addTestRows(&engine, "/controls/material", QStringList() << "Ripple" << "SliderHandle"); +} + +void tst_ObjectCount::universal() +{ + QFETCH(QUrl, url); + doBenchmark(&engine, url); +} + +void tst_ObjectCount::universal_data() +{ + QTest::addColumn<QUrl>("url"); + addTestRows(&engine, "/controls/universal"); } QTEST_MAIN(tst_ObjectCount) diff --git a/tests/manual/gifs/capturedevent.cpp b/tests/manual/gifs/capturedevent.cpp index a36086c8..4e21db79 100644 --- a/tests/manual/gifs/capturedevent.cpp +++ b/tests/manual/gifs/capturedevent.cpp @@ -3,7 +3,7 @@ ** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** -** This file is part of the tools applications of the Qt Toolkit. +** This file is part of the test suite of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL3$ ** Commercial License Usage diff --git a/tests/manual/gifs/capturedevent.h b/tests/manual/gifs/capturedevent.h index dd495c2d..ffac7d24 100644 --- a/tests/manual/gifs/capturedevent.h +++ b/tests/manual/gifs/capturedevent.h @@ -3,7 +3,7 @@ ** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** -** This file is part of the tools applications of the Qt Toolkit. +** This file is part of the test suite of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL3$ ** Commercial License Usage diff --git a/tests/manual/gifs/data/qtlabscontrols-busyindicator.qml b/tests/manual/gifs/data/qtlabscontrols-busyindicator.qml index 8b6940cc..e68af7dd 100644 --- a/tests/manual/gifs/data/qtlabscontrols-busyindicator.qml +++ b/tests/manual/gifs/data/qtlabscontrols-busyindicator.qml @@ -39,11 +39,13 @@ ****************************************************************************/ import QtQuick 2.6 +import QtQuick.Window 2.0 import Qt.labs.controls 1.0 -Item { +Window { width: busyIndicator.implicitWidth height: busyIndicator.implicitHeight + visible: true property alias busyIndicator: busyIndicator diff --git a/tests/manual/gifs/data/qtlabscontrols-button.qml b/tests/manual/gifs/data/qtlabscontrols-button.qml index c536d1e1..3d9a4f45 100644 --- a/tests/manual/gifs/data/qtlabscontrols-button.qml +++ b/tests/manual/gifs/data/qtlabscontrols-button.qml @@ -39,9 +39,17 @@ ****************************************************************************/ import QtQuick 2.6 +import QtQuick.Window 2.0 import Qt.labs.controls 1.0 -Button { - text: pressed ? "Pressed" : "Normal" - width: 80 +Window { + width: button.width + height: button.height + visible: true + + Button { + id: button + text: pressed ? "Pressed" : "Normal" + anchors.centerIn: parent + } } diff --git a/examples/labs/controls/drawer/main.cpp b/tests/manual/gifs/data/qtlabscontrols-menu.qml index 2abdc16d..65cd3563 100644 --- a/examples/labs/controls/drawer/main.cpp +++ b/tests/manual/gifs/data/qtlabscontrols-menu.qml @@ -3,7 +3,7 @@ ** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** -** This file is part of the examples of the Qt Toolkit. +** This file is part of the test suite of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:BSD$ ** You may use this file under the terms of the BSD license as follows: @@ -38,15 +38,38 @@ ** ****************************************************************************/ -#include <QGuiApplication> -#include <QQmlApplicationEngine> +import QtQuick 2.6 +import Qt.labs.controls 1.0 -int main(int argc, char *argv[]) -{ - QGuiApplication app(argc, argv); - QQmlApplicationEngine engine; - engine.load(QUrl("qrc:/main.qml")); - if (engine.rootObjects().isEmpty()) - return -1; - return app.exec(); +// TODO: restore and finish https://codereview.qt-project.org/#/c/123948/ +ApplicationWindow { + width: menu.contentItem.width + 20 + height: menu.contentItem.height + fileButton.height + 20 + + property alias fileButton: fileButton + property alias menu: menu + + Button { + id: fileButton + text: "File" + onClicked: menu.show() + x: 10 + y: 10 + } + Menu { + id: menu + // TODO + contentItem.x: fileButton.x + contentItem.y: fileButton.y + fileButton.height + + MenuItem { + text: "New..." + } + MenuItem { + text: "Open..." + } + MenuItem { + text: "Save" + } + } } diff --git a/tests/manual/gifs/data/qtlabscontrols-rangeslider.qml b/tests/manual/gifs/data/qtlabscontrols-rangeslider.qml index c7033f38..55056cf8 100644 --- a/tests/manual/gifs/data/qtlabscontrols-rangeslider.qml +++ b/tests/manual/gifs/data/qtlabscontrols-rangeslider.qml @@ -39,11 +39,13 @@ ****************************************************************************/ import QtQuick 2.6 +import QtQuick.Window 2.0 import Qt.labs.controls 1.0 -Item { +Window { width: slider.implicitWidth height: slider.implicitHeight + visible: true property alias slider: slider diff --git a/tests/manual/gifs/data/qtlabscontrols-slider.qml b/tests/manual/gifs/data/qtlabscontrols-slider.qml index 82cd3ad9..af582d7c 100644 --- a/tests/manual/gifs/data/qtlabscontrols-slider.qml +++ b/tests/manual/gifs/data/qtlabscontrols-slider.qml @@ -39,11 +39,15 @@ ****************************************************************************/ import QtQuick 2.6 +import QtQuick.Window 2.0 import Qt.labs.controls 1.0 -Item { +Window { width: slider.implicitWidth height: slider.implicitHeight + visible: true + + property alias slider: slider Slider { id: slider diff --git a/tests/manual/gifs/data/qtlabscontrols-switch.qml b/tests/manual/gifs/data/qtlabscontrols-switch.qml index 01818ba8..3968b60f 100644 --- a/tests/manual/gifs/data/qtlabscontrols-switch.qml +++ b/tests/manual/gifs/data/qtlabscontrols-switch.qml @@ -39,7 +39,16 @@ ****************************************************************************/ import QtQuick 2.6 +import QtQuick.Window 2.0 import Qt.labs.controls 1.0 -Switch { +Window { + width: theSwitch.width + height: theSwitch.height + visible: true + + Switch { + id: theSwitch + anchors.centerIn: parent + } } diff --git a/tests/manual/gifs/data/qtlabscontrols-tabbar.qml b/tests/manual/gifs/data/qtlabscontrols-tabbar.qml index c7a8653f..55bf5e27 100644 --- a/tests/manual/gifs/data/qtlabscontrols-tabbar.qml +++ b/tests/manual/gifs/data/qtlabscontrols-tabbar.qml @@ -39,11 +39,13 @@ ****************************************************************************/ import QtQuick 2.6 +import QtQuick.Window 2.0 import Qt.labs.controls 1.0 -Item { +Window { width: 200 height: tabBar.height + visible: true TabBar { id: tabBar diff --git a/tests/manual/gifs/data/qtlabscontrols-tumbler-wrap.qml b/tests/manual/gifs/data/qtlabscontrols-tumbler-wrap.qml index 8e9183c4..4b84c6d1 100644 --- a/tests/manual/gifs/data/qtlabscontrols-tumbler-wrap.qml +++ b/tests/manual/gifs/data/qtlabscontrols-tumbler-wrap.qml @@ -39,11 +39,13 @@ ****************************************************************************/ import QtQuick 2.6 +import QtQuick.Window 2.0 import Qt.labs.controls 1.0 -Item { +Window { width: 200 height: 200 + visible: true Frame { padding: 0 diff --git a/tests/manual/gifs/eventcapturer.cpp b/tests/manual/gifs/eventcapturer.cpp index 17994e3b..5b5905cd 100644 --- a/tests/manual/gifs/eventcapturer.cpp +++ b/tests/manual/gifs/eventcapturer.cpp @@ -3,7 +3,7 @@ ** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** -** This file is part of the tools applications of the Qt Toolkit. +** This file is part of the test suite of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL3$ ** Commercial License Usage diff --git a/tests/manual/gifs/eventcapturer.h b/tests/manual/gifs/eventcapturer.h index a1f48d32..b1f2b4ff 100644 --- a/tests/manual/gifs/eventcapturer.h +++ b/tests/manual/gifs/eventcapturer.h @@ -3,7 +3,7 @@ ** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** -** This file is part of the tools applications of the Qt Toolkit. +** This file is part of the test suite of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL3$ ** Commercial License Usage diff --git a/tests/manual/gifs/gifrecorder.cpp b/tests/manual/gifs/gifrecorder.cpp index 302dbec3..617ce506 100644 --- a/tests/manual/gifs/gifrecorder.cpp +++ b/tests/manual/gifs/gifrecorder.cpp @@ -3,7 +3,7 @@ ** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** -** This file is part of the tools applications of the Qt Toolkit. +** This file is part of the test suite of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL3$ ** Commercial License Usage @@ -65,7 +65,7 @@ namespace { GifRecorder::GifRecorder() : QObject(Q_NULLPTR), - mView(Q_NULLPTR), + mWindow(Q_NULLPTR), mHighQuality(false), mRecordingDuration(0), mRecordCursor(false), @@ -116,9 +116,9 @@ void GifRecorder::setQmlFileName(const QString &fileName) mQmlInputFileName = fileName; } -void GifRecorder::setView(QQuickView *view) +void GifRecorder::setView(QQuickWindow *view) { - this->mView = view; + this->mWindow = view; } /*! @@ -136,6 +136,11 @@ void GifRecorder::setHighQuality(bool highQuality) mHighQuality = highQuality; } +QQuickWindow *GifRecorder::window() const +{ + return mWindow; +} + namespace { void startProcess(QProcess &process, const QString &processName, const QString &args) { @@ -165,18 +170,19 @@ namespace { void GifRecorder::start() { - QVERIFY2(mView, "Must have a view to record"); - QDir gifQmlDir(mDataDirPath); QVERIFY(gifQmlDir.entryList().contains(mQmlInputFileName)); const QString qmlPath = gifQmlDir.absoluteFilePath(mQmlInputFileName); - mView->setSource(QUrl::fromLocalFile(qmlPath)); - QVERIFY(mView->rootObject()); + mEngine.load(QUrl::fromLocalFile(qmlPath)); + mWindow = qobject_cast<QQuickWindow*>(mEngine.rootObjects().first()); + QVERIFY2(mWindow, "Top level item must be a window"); + + mWindow->setFlags(mWindow->flags() | Qt::FramelessWindowHint); - mView->show(); - mView->requestActivate(); - QVERIFY(QTest::qWaitForWindowActive(mView, 500)); + mWindow->show(); + mWindow->requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(mWindow, 500)); if (mOutputFileBaseName.isEmpty()) { mOutputFileBaseName = mOutputDir.absoluteFilePath(mQmlInputFileName); @@ -195,10 +201,10 @@ void GifRecorder::start() QString args = QLatin1String("-d %1 -v %2 -x %3 -y %4 -w %5 -h %6 %7"); args = args.arg(QString::number(mRecordingDuration)) .arg(mRecordCursor ? QStringLiteral("-c") : QString()) - .arg(QString::number(mView->x())) - .arg(QString::number(mView->y())) - .arg(QString::number(mView->width())) - .arg(QString::number(mView->height())) + .arg(QString::number(mWindow->x())) + .arg(QString::number(mWindow->y())) + .arg(QString::number(mWindow->width())) + .arg(QString::number(mWindow->height())) .arg(mByzanzOutputFileName); @@ -208,7 +214,7 @@ void GifRecorder::start() // manually from the command line by recording any section of the screen // without moving the mouse and then running avprobe on the resulting .flv. // Our workaround is to force view updates. - connect(&mEventTimer, SIGNAL(timeout()), mView, SLOT(update())); + connect(&mEventTimer, SIGNAL(timeout()), mWindow, SLOT(update())); mEventTimer.start(100); startProcess(mByzanzProcess, byzanzProcessName, args); @@ -231,14 +237,14 @@ void GifRecorder::waitForFinish() if (mHighQuality) { // Indicate the end of recording and the beginning of conversion. - QQmlComponent busyComponent(mView->engine()); + QQmlComponent busyComponent(&mEngine); busyComponent.setData("import QtQuick 2.6; import Qt.labs.controls 1.0; Rectangle { anchors.fill: parent; " \ "BusyIndicator { width: 32; height: 32; anchors.centerIn: parent } }", QUrl()); QCOMPARE(busyComponent.status(), QQmlComponent::Ready); QQuickItem *busyRect = qobject_cast<QQuickItem*>(busyComponent.create()); QVERIFY(busyRect); - busyRect->setParentItem(mView->rootObject()); - QSignalSpy spy(mView, SIGNAL(frameSwapped())); + busyRect->setParentItem(mWindow->contentItem()); + QSignalSpy spy(mWindow, SIGNAL(frameSwapped())); QVERIFY(spy.wait()); QProcess avconvProcess; diff --git a/tests/manual/gifs/gifrecorder.h b/tests/manual/gifs/gifrecorder.h index c6ef3e5c..3f8aa1b6 100644 --- a/tests/manual/gifs/gifrecorder.h +++ b/tests/manual/gifs/gifrecorder.h @@ -3,7 +3,7 @@ ** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** -** This file is part of the tools applications of the Qt Toolkit. +** This file is part of the test suite of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL3$ ** Commercial License Usage @@ -39,7 +39,8 @@ #include <QObject> #include <QProcess> -#include <QQuickView> +#include <QQmlApplicationEngine> +#include <QQuickWindow> #include <QDir> #include <QString> #include <QTimer> @@ -57,9 +58,11 @@ public: void setOutputDir(const QDir &dir); void setOutputFileBaseName(const QString &fileBaseName); void setQmlFileName(const QString &fileName); - void setView(QQuickView *mView); + void setView(QQuickWindow *mWindow); void setHighQuality(bool highQuality); + QQuickWindow *window() const; + void start(); bool hasStarted() const; void waitForFinish(); @@ -75,7 +78,8 @@ private: QString mByzanzOutputFileName; QString mGifFileName; QString mQmlInputFileName; - QQuickView *mView; + QQmlApplicationEngine mEngine; + QQuickWindow *mWindow; bool mHighQuality; int mRecordingDuration; bool mRecordCursor; diff --git a/tests/manual/gifs/tst_gifs.cpp b/tests/manual/gifs/tst_gifs.cpp index 24b022d3..bd0cc61f 100644 --- a/tests/manual/gifs/tst_gifs.cpp +++ b/tests/manual/gifs/tst_gifs.cpp @@ -3,7 +3,7 @@ ** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** -** This file is part of the tools applications of the Qt Toolkit. +** This file is part of the test suite of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL3$ ** Commercial License Usage @@ -56,13 +56,12 @@ private slots: void switchGif(); void button(); void tabBar(); + void menu(); private: - void moveSmoothly(const QPoint &from, const QPoint &to, int movements, - QEasingCurve::Type easingCurveType = QEasingCurve::OutQuint, - int movementDelay = 15); + void moveSmoothly(QQuickWindow *window, const QPoint &from, const QPoint &to, int movements, + QEasingCurve::Type easingCurveType = QEasingCurve::OutQuint, int movementDelay = 15); - QQuickView view; QString dataDirPath; QDir outputDir; }; @@ -76,11 +75,10 @@ void tst_Gifs::initTestCase() outputDir = QDir(QDir::current().filePath("gifs")); QVERIFY(outputDir.exists() || QDir::current().mkpath("gifs")); qInfo() << "output directory:" << outputDir.absolutePath(); - - view.setFlags(view.flags() | Qt::FramelessWindowHint); } -void tst_Gifs::moveSmoothly(const QPoint &from, const QPoint &to, int movements, QEasingCurve::Type easingCurveType, int movementDelay) +void tst_Gifs::moveSmoothly(QQuickWindow *window, const QPoint &from, const QPoint &to, + int movements, QEasingCurve::Type easingCurveType, int movementDelay) { QEasingCurve curve(easingCurveType); int xDifference = to.x() - from.x(); @@ -89,7 +87,7 @@ void tst_Gifs::moveSmoothly(const QPoint &from, const QPoint &to, int movements, QPoint pos = QPoint( from.x() + curve.valueForProgress(movement / qreal(qAbs(xDifference))) * xDifference, from.y() + curve.valueForProgress(movement / qreal(qAbs(yDifference))) * yDifference); - QTest::mouseMove(&view, pos, movementDelay); + QTest::mouseMove(window, pos, movementDelay); } } @@ -100,69 +98,66 @@ void tst_Gifs::tumblerWrap() gifRecorder.setOutputDir(outputDir); gifRecorder.setRecordingDuration(4); gifRecorder.setQmlFileName("qtlabscontrols-tumbler-wrap.qml"); - gifRecorder.setView(&view); - - view.show(); gifRecorder.start(); // Left as an example. Usually EventCapturer code would be removed after // the GIF has been generated. + QQuickWindow *window = gifRecorder.window(); EventCapturer eventCapturer; #ifdef GENERATE_EVENT_CODE eventCapturer.setMoveEventTrimFlags(EventCapturer::TrimAll); - eventCapturer.startCapturing(&view, 4000); + eventCapturer.startCapturing(window, 4000); #else - QTest::mousePress(&view, Qt::LeftButton, Qt::NoModifier, QPoint(89, 75), 326); - QTest::mouseMove(&view, QPoint(89, 76), 31); - QTest::mouseMove(&view, QPoint(89, 80), 10); - QTest::mouseMove(&view, QPoint(93, 93), 10); - QTest::mouseMove(&view, QPoint(95, 101), 10); - QTest::mouseMove(&view, QPoint(97, 109), 11); - QTest::mouseMove(&view, QPoint(101, 125), 10); - QTest::mouseMove(&view, QPoint(103, 133), 11); - QTest::mouseMove(&view, QPoint(103, 141), 11); - QTest::mouseMove(&view, QPoint(105, 158), 10); - QTest::mouseMove(&view, QPoint(105, 162), 13); - QTest::mouseRelease(&view, Qt::LeftButton, Qt::NoModifier, QPoint(105, 162), 0); - QTest::mousePress(&view, Qt::LeftButton, Qt::NoModifier, QPoint(154, 130), 1098); - QTest::mouseMove(&view, QPoint(154, 129), 50); - QTest::mouseMove(&view, QPoint(153, 128), 0); - QTest::mouseMove(&view, QPoint(153, 125), 16); - QTest::mouseMove(&view, QPoint(152, 121), 0); - QTest::mouseMove(&view, QPoint(152, 117), 17); - QTest::mouseMove(&view, QPoint(151, 113), 0); - QTest::mouseMove(&view, QPoint(151, 106), 16); - QTest::mouseMove(&view, QPoint(150, 99), 1); - QTest::mouseMove(&view, QPoint(148, 93), 16); - QTest::mouseMove(&view, QPoint(148, 88), 0); - QTest::mouseMove(&view, QPoint(148, 84), 17); - QTest::mouseMove(&view, QPoint(147, 81), 0); - QTest::mouseRelease(&view, Qt::LeftButton, Qt::NoModifier, QPoint(147, 81), 0); - QTest::mousePress(&view, Qt::LeftButton, Qt::NoModifier, QPoint(147, 74), 550); - QTest::mouseMove(&view, QPoint(147, 75), 17); - QTest::mouseMove(&view, QPoint(147, 76), 17); - QTest::mouseMove(&view, QPoint(147, 80), 0); - QTest::mouseMove(&view, QPoint(148, 85), 16); - QTest::mouseMove(&view, QPoint(148, 92), 0); - QTest::mouseMove(&view, QPoint(148, 103), 17); - QTest::mouseMove(&view, QPoint(150, 119), 17); - QTest::mouseMove(&view, QPoint(151, 138), 16); - QTest::mouseMove(&view, QPoint(151, 145), 1); - QTest::mouseMove(&view, QPoint(153, 151), 16); - QTest::mouseMove(&view, QPoint(153, 157), 0); - QTest::mouseMove(&view, QPoint(153, 163), 17); - QTest::mouseMove(&view, QPoint(153, 167), 0); - QTest::mouseMove(&view, QPoint(155, 171), 17); - QTest::mouseMove(&view, QPoint(155, 175), 0); - QTest::mouseRelease(&view, Qt::LeftButton, Qt::NoModifier, QPoint(155, 175), 0); + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(89, 75), 326); + QTest::mouseMove(window, QPoint(89, 76), 31); + QTest::mouseMove(window, QPoint(89, 80), 10); + QTest::mouseMove(window, QPoint(93, 93), 10); + QTest::mouseMove(window, QPoint(95, 101), 10); + QTest::mouseMove(window, QPoint(97, 109), 11); + QTest::mouseMove(window, QPoint(101, 125), 10); + QTest::mouseMove(window, QPoint(103, 133), 11); + QTest::mouseMove(window, QPoint(103, 141), 11); + QTest::mouseMove(window, QPoint(105, 158), 10); + QTest::mouseMove(window, QPoint(105, 162), 13); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(105, 162), 0); + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(154, 130), 1098); + QTest::mouseMove(window, QPoint(154, 129), 50); + QTest::mouseMove(window, QPoint(153, 128), 0); + QTest::mouseMove(window, QPoint(153, 125), 16); + QTest::mouseMove(window, QPoint(152, 121), 0); + QTest::mouseMove(window, QPoint(152, 117), 17); + QTest::mouseMove(window, QPoint(151, 113), 0); + QTest::mouseMove(window, QPoint(151, 106), 16); + QTest::mouseMove(window, QPoint(150, 99), 1); + QTest::mouseMove(window, QPoint(148, 93), 16); + QTest::mouseMove(window, QPoint(148, 88), 0); + QTest::mouseMove(window, QPoint(148, 84), 17); + QTest::mouseMove(window, QPoint(147, 81), 0); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(147, 81), 0); + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(147, 74), 550); + QTest::mouseMove(window, QPoint(147, 75), 17); + QTest::mouseMove(window, QPoint(147, 76), 17); + QTest::mouseMove(window, QPoint(147, 80), 0); + QTest::mouseMove(window, QPoint(148, 85), 16); + QTest::mouseMove(window, QPoint(148, 92), 0); + QTest::mouseMove(window, QPoint(148, 103), 17); + QTest::mouseMove(window, QPoint(150, 119), 17); + QTest::mouseMove(window, QPoint(151, 138), 16); + QTest::mouseMove(window, QPoint(151, 145), 1); + QTest::mouseMove(window, QPoint(153, 151), 16); + QTest::mouseMove(window, QPoint(153, 157), 0); + QTest::mouseMove(window, QPoint(153, 163), 17); + QTest::mouseMove(window, QPoint(153, 167), 0); + QTest::mouseMove(window, QPoint(155, 171), 17); + QTest::mouseMove(window, QPoint(155, 175), 0); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(155, 175), 0); #endif gifRecorder.waitForFinish(); foreach (CapturedEvent event, eventCapturer.capturedEvents()) qDebug().noquote() << event.cppCommand(); - } void tst_Gifs::slider() @@ -173,113 +168,31 @@ void tst_Gifs::slider() gifRecorder.setRecordingDuration(4); gifRecorder.setHighQuality(true); gifRecorder.setQmlFileName("qtlabscontrols-slider.qml"); - gifRecorder.setView(&view); - - view.show(); gifRecorder.start(); - QTest::mousePress(&view, Qt::LeftButton, Qt::NoModifier, QPoint(18, 19), 122); - QTest::mouseMove(&view, QPoint(20, 19), 154); - QTest::mouseMove(&view, QPoint(22, 19), 10); - QTest::mouseMove(&view, QPoint(24, 20), 10); - QTest::mouseMove(&view, QPoint(27, 20), 11); - QTest::mouseMove(&view, QPoint(31, 20), 10); - QTest::mouseMove(&view, QPoint(33, 20), 10); - QTest::mouseMove(&view, QPoint(36, 21), 11); - QTest::mouseMove(&view, QPoint(40, 22), 10); - QTest::mouseMove(&view, QPoint(43, 22), 10); - QTest::mouseMove(&view, QPoint(45, 22), 11); - QTest::mouseMove(&view, QPoint(50, 23), 16); - QTest::mouseMove(&view, QPoint(54, 23), 17); - QTest::mouseMove(&view, QPoint(60, 24), 16); - QTest::mouseMove(&view, QPoint(63, 24), 17); - QTest::mouseMove(&view, QPoint(65, 24), 0); - QTest::mouseMove(&view, QPoint(66, 24), 17); - QTest::mouseMove(&view, QPoint(68, 24), 0); - QTest::mouseMove(&view, QPoint(70, 24), 16); - QTest::mouseMove(&view, QPoint(71, 24), 1); - QTest::mouseMove(&view, QPoint(73, 24), 16); - QTest::mouseMove(&view, QPoint(74, 24), 0); - QTest::mouseMove(&view, QPoint(76, 24), 16); - QTest::mouseMove(&view, QPoint(77, 24), 0); - QTest::mouseMove(&view, QPoint(78, 24), 17); - QTest::mouseMove(&view, QPoint(80, 24), 0); - QTest::mouseMove(&view, QPoint(81, 24), 17); - QTest::mouseMove(&view, QPoint(82, 24), 0); - QTest::mouseMove(&view, QPoint(83, 24), 17); - QTest::mouseMove(&view, QPoint(84, 24), 16); - QTest::mouseMove(&view, QPoint(85, 24), 48); - QTest::mouseMove(&view, QPoint(85, 23), 10); - QTest::mouseMove(&view, QPoint(86, 23), 11); - QTest::mouseRelease(&view, Qt::LeftButton, Qt::NoModifier, QPoint(86, 23), 71); - QTest::mousePress(&view, Qt::LeftButton, Qt::NoModifier, QPoint(86, 22), 246); - QTest::mouseMove(&view, QPoint(87, 21), 123); - QTest::mouseMove(&view, QPoint(89, 21), 10); - QTest::mouseMove(&view, QPoint(91, 20), 10); - QTest::mouseMove(&view, QPoint(97, 20), 10); - QTest::mouseMove(&view, QPoint(101, 20), 11); - QTest::mouseMove(&view, QPoint(105, 20), 11); - QTest::mouseMove(&view, QPoint(113, 20), 10); - QTest::mouseMove(&view, QPoint(120, 20), 13); - QTest::mouseMove(&view, QPoint(129, 20), 17); - QTest::mouseMove(&view, QPoint(140, 20), 17); - QTest::mouseMove(&view, QPoint(150, 20), 16); - QTest::mouseMove(&view, QPoint(156, 20), 1); - QTest::mouseMove(&view, QPoint(161, 20), 16); - QTest::mouseMove(&view, QPoint(166, 20), 0); - QTest::mouseMove(&view, QPoint(172, 20), 17); - QTest::mouseMove(&view, QPoint(177, 20), 0); - QTest::mouseMove(&view, QPoint(181, 20), 16); - QTest::mouseMove(&view, QPoint(186, 20), 1); - QTest::mouseMove(&view, QPoint(191, 22), 16); - QTest::mouseMove(&view, QPoint(194, 22), 0); - QTest::mouseMove(&view, QPoint(197, 22), 17); - QTest::mouseMove(&view, QPoint(201, 22), 0); - QTest::mouseMove(&view, QPoint(204, 22), 17); - QTest::mouseMove(&view, QPoint(207, 22), 0); - QTest::mouseMove(&view, QPoint(211, 22), 16); - QTest::mouseMove(&view, QPoint(214, 22), 0); - QTest::mouseMove(&view, QPoint(216, 22), 10); - QTest::mouseMove(&view, QPoint(222, 22), 11); - QTest::mouseMove(&view, QPoint(226, 22), 10); - QTest::mouseMove(&view, QPoint(227, 22), 10); - QTest::mouseMove(&view, QPoint(229, 22), 10); - QTest::mouseMove(&view, QPoint(230, 22), 11); - QTest::mouseMove(&view, QPoint(232, 22), 10); - QTest::mouseMove(&view, QPoint(231, 22), 101); - QTest::mouseMove(&view, QPoint(230, 23), 10); - QTest::mouseMove(&view, QPoint(229, 23), 10); - QTest::mouseMove(&view, QPoint(225, 24), 10); - QTest::mouseMove(&view, QPoint(221, 24), 10); - QTest::mouseMove(&view, QPoint(218, 25), 10); - QTest::mouseMove(&view, QPoint(214, 25), 11); - QTest::mouseMove(&view, QPoint(201, 25), 10); - QTest::mouseMove(&view, QPoint(192, 25), 10); - QTest::mouseMove(&view, QPoint(183, 25), 11); - QTest::mouseMove(&view, QPoint(163, 25), 10); - QTest::mouseMove(&view, QPoint(154, 25), 11); - QTest::mouseMove(&view, QPoint(145, 23), 13); - QTest::mouseMove(&view, QPoint(136, 23), 1); - QTest::mouseMove(&view, QPoint(128, 21), 16); - QTest::mouseMove(&view, QPoint(120, 21), 0); - QTest::mouseMove(&view, QPoint(112, 20), 17); - QTest::mouseMove(&view, QPoint(110, 20), 0); - QTest::mouseMove(&view, QPoint(102, 20), 16); - QTest::mouseMove(&view, QPoint(94, 18), 0); - QTest::mouseMove(&view, QPoint(86, 18), 16); - QTest::mouseMove(&view, QPoint(78, 18), 0); - QTest::mouseMove(&view, QPoint(70, 18), 17); - QTest::mouseMove(&view, QPoint(62, 18), 0); - QTest::mouseMove(&view, QPoint(54, 18), 16); - QTest::mouseMove(&view, QPoint(47, 16), 0); - QTest::mouseMove(&view, QPoint(39, 16), 16); - QTest::mouseMove(&view, QPoint(31, 16), 0); - QTest::mouseMove(&view, QPoint(26, 16), 17); - QTest::mouseMove(&view, QPoint(20, 15), 0); - QTest::mouseMove(&view, QPoint(8, 15), 17); - QTest::mouseMove(&view, QPoint(0, 15), 16); - QTest::mouseRelease(&view, Qt::LeftButton, Qt::NoModifier, QPoint(0, 15), 215); + QQuickWindow *window = gifRecorder.window(); + QQuickItem *slider = window->property("slider").value<QQuickItem*>(); + QVERIFY(slider); + QQuickItem *handle = slider->property("handle").value<QQuickItem*>(); + QVERIFY(handle); + + const QPoint handleCenter = handle->mapToItem(window->contentItem(), + QPoint(handle->width() / 2, handle->height() / 2)).toPoint(); + + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, handleCenter, 100); + QPoint pos1 = handleCenter + QPoint(slider->width() * 0.3, 0); + moveSmoothly(window, handleCenter, pos1, pos1.x() - handleCenter.x(), QEasingCurve::OutQuint, 10); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, pos1, 20); + + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, handleCenter, 100); + const QPoint pos2 = QPoint(slider->width() - handleCenter.x() + slider->property("rightPadding").toInt(), handleCenter.y()); + moveSmoothly(window, pos1, pos2, pos2.x() - pos1.x(), QEasingCurve::OutQuint, 10); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, pos2, 20); + + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, pos2, 100); + moveSmoothly(window, pos2, handleCenter, qAbs(handleCenter.x() - pos2.x()), QEasingCurve::OutQuint, 10); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, handleCenter, 20); gifRecorder.waitForFinish(); } @@ -292,13 +205,11 @@ void tst_Gifs::rangeSlider() gifRecorder.setRecordingDuration(6); gifRecorder.setHighQuality(true); gifRecorder.setQmlFileName("qtlabscontrols-rangeslider.qml"); - gifRecorder.setView(&view); - - view.show(); gifRecorder.start(); - QQuickItem *slider = view.rootObject()->property("slider").value<QQuickItem*>(); + QQuickWindow *window = gifRecorder.window(); + QQuickItem *slider = window->property("slider").value<QQuickItem*>(); QVERIFY(slider); QObject *first = slider->property("first").value<QObject*>(); QVERIFY(first); @@ -314,23 +225,23 @@ void tst_Gifs::rangeSlider() const QPoint secondCenter = secondHandle->mapToItem(slider, QPoint(secondHandle->width() / 2, secondHandle->height() / 2)).toPoint(); - QTest::mousePress(&view, Qt::LeftButton, Qt::NoModifier, firstCenter, 100); + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, firstCenter, 100); const QPoint firstTarget = firstCenter + QPoint(slider->width() * 0.25, 0); - moveSmoothly(firstCenter, firstTarget, firstTarget.x() - firstCenter.x()); - QTest::mouseRelease(&view, Qt::LeftButton, Qt::NoModifier, firstTarget, 20); + moveSmoothly(window, firstCenter, firstTarget, firstTarget.x() - firstCenter.x()); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, firstTarget, 20); - QTest::mousePress(&view, Qt::LeftButton, Qt::NoModifier, secondCenter, 100); + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, secondCenter, 100); const QPoint secondTarget = secondCenter - QPoint(slider->width() * 0.25, 0); - moveSmoothly(secondCenter, secondTarget, qAbs(secondTarget.x() - secondCenter.x())); - QTest::mouseRelease(&view, Qt::LeftButton, Qt::NoModifier, secondTarget, 20); + moveSmoothly(window, secondCenter, secondTarget, qAbs(secondTarget.x() - secondCenter.x())); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, secondTarget, 20); - QTest::mousePress(&view, Qt::LeftButton, Qt::NoModifier, secondTarget, 100); - moveSmoothly(secondTarget, secondCenter, qAbs(secondTarget.x() - secondCenter.x())); - QTest::mouseRelease(&view, Qt::LeftButton, Qt::NoModifier, secondCenter, 20); + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, secondTarget, 100); + moveSmoothly(window, secondTarget, secondCenter, qAbs(secondTarget.x() - secondCenter.x())); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, secondCenter, 20); - QTest::mousePress(&view, Qt::LeftButton, Qt::NoModifier, firstTarget, 100); - moveSmoothly(firstTarget, firstCenter, firstTarget.x() - firstCenter.x()); - QTest::mouseRelease(&view, Qt::LeftButton, Qt::NoModifier, firstCenter, 20); + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, firstTarget, 100); + moveSmoothly(window, firstTarget, firstCenter, firstTarget.x() - firstCenter.x()); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, firstCenter, 20); gifRecorder.waitForFinish(); } @@ -343,16 +254,14 @@ void tst_Gifs::busyIndicator() gifRecorder.setRecordingDuration(3); gifRecorder.setHighQuality(true); gifRecorder.setQmlFileName("qtlabscontrols-busyindicator.qml"); - gifRecorder.setView(&view); - - view.show(); gifRecorder.start(); + QQuickWindow *window = gifRecorder.window(); // Record nothing for a bit to make it smoother. QTest::qWait(400); - QQuickItem *busyIndicator = view.rootObject()->property("busyIndicator").value<QQuickItem*>(); + QQuickItem *busyIndicator = window->property("busyIndicator").value<QQuickItem*>(); QVERIFY(busyIndicator); busyIndicator->setProperty("running", true); @@ -373,14 +282,12 @@ void tst_Gifs::switchGif() gifRecorder.setRecordingDuration(3); gifRecorder.setQmlFileName("qtlabscontrols-switch.qml"); gifRecorder.setHighQuality(true); - gifRecorder.setView(&view); - - view.show(); gifRecorder.start(); - QTest::mouseClick(&view, Qt::LeftButton, Qt::NoModifier, QPoint(view.width() * 0.8, view.height() / 2), 0); - QTest::mouseClick(&view, Qt::LeftButton, Qt::NoModifier, QPoint(view.width() * 0.2, view.height() / 2), 800); + QQuickWindow *window = gifRecorder.window(); + QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() * 0.8, window->height() / 2), 0); + QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() * 0.2, window->height() / 2), 800); gifRecorder.waitForFinish(); } @@ -393,14 +300,12 @@ void tst_Gifs::button() gifRecorder.setRecordingDuration(3); gifRecorder.setQmlFileName("qtlabscontrols-button.qml"); gifRecorder.setHighQuality(true); - gifRecorder.setView(&view); - - view.show(); gifRecorder.start(); - QTest::mousePress(&view, Qt::LeftButton, Qt::NoModifier, QPoint(view.width() / 2, view.height() / 2), 0); - QTest::mouseRelease(&view, Qt::LeftButton, Qt::NoModifier, QPoint(view.width() / 2, view.height() / 2), 700); + QQuickWindow *window = gifRecorder.window(); + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() / 2, window->height() / 2), 0); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() / 2, window->height() / 2), 700); gifRecorder.waitForFinish(); } @@ -415,23 +320,54 @@ void tst_Gifs::tabBar() gifRecorder.setRecordingDuration(4); gifRecorder.setQmlFileName(qmlFileName); gifRecorder.setHighQuality(true); - gifRecorder.setView(&view); - view.show(); + gifRecorder.start(); + + QQuickWindow *window = gifRecorder.window(); + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() * 0.6, window->height() / 2), 0); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() * 0.6, window->height() / 2), 50); + + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() * 0.9, window->height() / 2), 400); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() * 0.9, window->height() / 2), 50); + + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() * 0.6, window->height() / 2), 800); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() * 0.6, window->height() / 2), 50); + + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() * 0.3, window->height() / 2), 400); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() * 0.3, window->height() / 2), 50); + + gifRecorder.waitForFinish(); +} + +void tst_Gifs::menu() +{ + const QString qmlFileName = QStringLiteral("qtlabscontrols-menu.qml"); + + GifRecorder gifRecorder; + gifRecorder.setDataDirPath(dataDirPath); + gifRecorder.setOutputDir(outputDir); + gifRecorder.setRecordingDuration(3); + gifRecorder.setQmlFileName(qmlFileName); + gifRecorder.setHighQuality(true); gifRecorder.start(); - QTest::mousePress(&view, Qt::LeftButton, Qt::NoModifier, QPoint(view.width() * 0.6, view.height() / 2), 0); - QTest::mouseRelease(&view, Qt::LeftButton, Qt::NoModifier, QPoint(view.width() * 0.6, view.height() / 2), 50); + QQuickWindow *window = gifRecorder.window(); + const QQuickItem *fileButton = window->property("fileButton").value<QQuickItem*>(); + QVERIFY(fileButton); - QTest::mousePress(&view, Qt::LeftButton, Qt::NoModifier, QPoint(view.width() * 0.9, view.height() / 2), 400); - QTest::mouseRelease(&view, Qt::LeftButton, Qt::NoModifier, QPoint(view.width() * 0.9, view.height() / 2), 50); + const QPoint fileButtonCenter = fileButton->mapToScene(QPointF(fileButton->width() / 2, fileButton->height() / 2)).toPoint(); + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, fileButtonCenter, 0); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, fileButtonCenter, 200); - QTest::mousePress(&view, Qt::LeftButton, Qt::NoModifier, QPoint(view.width() * 0.6, view.height() / 2), 800); - QTest::mouseRelease(&view, Qt::LeftButton, Qt::NoModifier, QPoint(view.width() * 0.6, view.height() / 2), 50); + const QObject *menu = window->property("menu").value<QObject*>(); + QVERIFY(menu); + const QQuickItem *menuContentItem = menu->property("contentItem").value<QQuickItem*>(); + QVERIFY(menuContentItem); - QTest::mousePress(&view, Qt::LeftButton, Qt::NoModifier, QPoint(view.width() * 0.3, view.height() / 2), 400); - QTest::mouseRelease(&view, Qt::LeftButton, Qt::NoModifier, QPoint(view.width() * 0.3, view.height() / 2), 50); + const QPoint lastItemPos = menuContentItem->mapToScene(QPointF(menuContentItem->width() / 2, menuContentItem->height() - 10)).toPoint(); + QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, lastItemPos, 1000); + QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, lastItemPos, 300); gifRecorder.waitForFinish(); } diff --git a/tests/manual/manual.pro b/tests/manual/manual.pro index 8dac1b34..b974ae29 100644 --- a/tests/manual/manual.pro +++ b/tests/manual/manual.pro @@ -1,4 +1,5 @@ TEMPLATE = subdirs SUBDIRS += \ gifs \ - fonts + fonts \ + testbench diff --git a/examples/labs/controls/shared/FontAwesome.otf b/tests/manual/shared/FontAwesome.otf Binary files differindex 681bdd4d..681bdd4d 100644 --- a/examples/labs/controls/shared/FontAwesome.otf +++ b/tests/manual/shared/FontAwesome.otf diff --git a/examples/labs/controls/shared/FontAwesome.qml b/tests/manual/shared/FontAwesome.qml index 6fa64991..6fa64991 100644 --- a/examples/labs/controls/shared/FontAwesome.qml +++ b/tests/manual/shared/FontAwesome.qml diff --git a/examples/labs/controls/shared/FontAwesomeIcon.qml b/tests/manual/shared/FontAwesomeIcon.qml index c085b21e..c085b21e 100644 --- a/examples/labs/controls/shared/FontAwesomeIcon.qml +++ b/tests/manual/shared/FontAwesomeIcon.qml diff --git a/examples/labs/controls/shared/qmldir b/tests/manual/shared/qmldir index 3cb55667..3cb55667 100644 --- a/examples/labs/controls/shared/qmldir +++ b/tests/manual/shared/qmldir diff --git a/examples/labs/controls/shared/shared.qrc b/tests/manual/shared/shared.qrc index 8dbb3421..8dbb3421 100644 --- a/examples/labs/controls/shared/shared.qrc +++ b/tests/manual/shared/shared.qrc diff --git a/tests/manual/testbench/main.cpp b/tests/manual/testbench/main.cpp index e1b65585..b6eec8d8 100644 --- a/tests/manual/testbench/main.cpp +++ b/tests/manual/testbench/main.cpp @@ -40,14 +40,19 @@ #include <QGuiApplication> #include <QQmlApplicationEngine> +#include <QtCore/private/qabstractanimation_p.h> int main(int argc, char *argv[]) { + QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling); + QGuiApplication app(argc, argv); + QUnifiedTimer::instance()->setSlowModeEnabled(app.arguments().contains("-slow")); + // These must be set before running. // TODO: move style selection into app UI and use settings to save choices. - // qsetenv("QT_FILE_SELECTORS", "material"); + // qsetenv("QT_QUICK_FILE_SELECTORS", "material"); // qsetenv("QT_LABS_CONTROLS_STYLE", "material"); QQmlApplicationEngine engine; engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); diff --git a/tests/manual/testbench/main.qml b/tests/manual/testbench/main.qml index 75c901f1..b375a098 100644 --- a/tests/manual/testbench/main.qml +++ b/tests/manual/testbench/main.qml @@ -42,376 +42,534 @@ import QtQuick 2.3 import QtQuick.Window 2.2 import QtQuick.Layouts 1.0 import Qt.labs.controls 1.0 -//import Qt.labs.controls.material 1.0 -//import Qt.labs.controls.universal 1.0 +import Qt.labs.controls.material 1.0 +import Qt.labs.controls.universal 1.0 ApplicationWindow { id: window visible: true - width: 700 + width: 750 height: 1000 - Theme.backgroundColor: themeSwitch.checked ? "#444" : "#fff" - Theme.frameColor: themeSwitch.checked ? "#666" : "#ccc" - Theme.textColor: themeSwitch.checked ? "#eee" : "#111" - Theme.pressColor: themeSwitch.checked ? "#33ffffff" : "#33333333" - Theme.baseColor: themeSwitch.checked ? "#444" : "#eee" + Material.theme: themeSwitch.checked ? Material.Dark : Material.Light + Universal.theme: themeSwitch.checked ? Universal.Dark : Universal.Light -// Material.theme: themeSwitch.checked ? Material.Dark : Material.Light -// Universal.theme: themeSwitch.checked ? Universal.Dark : Universal.Light - - property int margins: 30 - property int spacing: 10 - - Switch { - id: themeSwitch - text: "Light/Dark" - anchors.right: parent.right - } - - Flow { - id: flow - anchors.fill: parent - anchors.margins: 30 - spacing: 30 + property int controlSpacing: 10 + header: ToolBar { RowLayout { - BusyIndicator { - } - BusyIndicator { - enabled: false - } - } + anchors.fill: parent - RowLayout { - spacing: window.spacing - - Button { + ToolButton { text: "Normal" + onClicked: menu.visible ? menu.hide() : menu.show() } - Button { + ToolButton { text: "Pressed" pressed: true } - Button { + ToolButton { text: "Disabled" enabled: false } - } - - RowLayout { - Frame { - Label { - text: "Normal\nLabel" - horizontalAlignment: Text.AlignHCenter - } + Item { + Layout.fillWidth: true } - Frame { - enabled: false - - Label { - text: "Disabled\nLabel" - horizontalAlignment: Text.AlignHCenter - } + Label { + text: "Light/Dark" + } + Switch { + id: themeSwitch } } + } - RowLayout { - CheckBox { - text: "Normal" - } - CheckBox { - text: "Pressed" - pressed: true - } - CheckBox { - text: "Checked" - checked: true - } - CheckBox { - text: "Checked + Pressed" - checked: true - pressed: true - } - CheckBox { - text: "Disabled" - enabled: false - } + footer: TabBar { + TabButton { + text: "Normal" } + TabButton { + text: "Pressed" + pressed: true + } + TabButton { + text: "Disabled" + enabled: false + } + } - RowLayout { - Dial { - } - Dial { - enabled: false - } + Menu { + id: menu + contentItem.x: 1 + contentItem.y: header.height + + MenuItem { + text: "Option 1" + } + MenuItem { + text: "Option 2" } + MenuItem { + text: "Option 3" + } + } - RowLayout { - GroupBox { - title: "Normal" + Flickable { + anchors.fill: parent + topMargin: 30 + leftMargin: 30 + rightMargin: 30 + bottomMargin: 30 + contentHeight: flow.height - Item { - implicitWidth: 100 - implicitHeight: 100 - } - } - GroupBox { - enabled: false - title: "Disabled" + Flow { + id: flow + width: parent.width + spacing: 30 - Item { - implicitWidth: 100 - implicitHeight: 100 + RowLayout { + spacing: window.controlSpacing + + Button { + text: "Normal" + } + Button { + text: "Pressed" + pressed: true + } + Button { + text: "Checked" + checked: true + } + Button { + text: "CH + PR" + checked: true + pressed: true + } + Button { + text: "Disabled" + enabled: false + } + Button { + text: "CH + DIS" + enabled: false + checked: true } } - } - RowLayout { - PageIndicator { - count: 5 - } - PageIndicator { - count: 5 - enabled: false - } - } + RowLayout { + spacing: window.controlSpacing - RowLayout { - ProgressBar { - value: 0.5 - } - ProgressBar { - value: 0.5 - enabled: false + Button { + text: "HI" + highlighted: true + } + Button { + text: "HI + PR" + highlighted: true + pressed: true + } + Button { + text: "HI + CH" + highlighted: true + checked: true + } + Button { + text: "HI+CH+PR" + highlighted: true + pressed: true + checked: true + } + Button { + text: "HI + DIS" + highlighted: true + enabled: false + } + Button { + text: "HI+CH+DIS" + highlighted: true + enabled: false + checked: true + } } - } - RowLayout { - RadioButton { - text: "Normal" - } - RadioButton { - text: "Pressed" - pressed: true - } - RadioButton { - text: "Checked" - checked: true - } - RadioButton { - text: "Checked + Pressed" - checked: true - pressed: true - } - RadioButton { - text: "Disabled" - enabled: false + RowLayout { + CheckBox { + text: "Normal" + } + CheckBox { + text: "Pressed" + pressed: true + } + CheckBox { + text: "Checked" + checked: true + } + CheckBox { + text: "CH + PR" + checked: true + pressed: true + } + CheckBox { + text: "Disabled" + enabled: false + } + CheckBox { + text: "CH + DIS" + checked: true + enabled: false + } } - } - RowLayout { - Frame { - Layout.preferredWidth: 100 - Layout.preferredHeight: 100 - - ScrollBar { - size: 0.3 - position: 0.2 - active: true - orientation: Qt.Vertical - height: parent.height - anchors.right: parent.right + RowLayout { + RadioButton { + text: "Normal" + } + RadioButton { + text: "Pressed" + pressed: true + } + RadioButton { + text: "Checked" + checked: true + } + RadioButton { + text: "CH + PR" + checked: true + pressed: true + } + RadioButton { + text: "Disabled" + enabled: false + } + RadioButton { + text: "CH + DIS" + checked: true + enabled: false } } - Frame { - Layout.preferredWidth: 100 - Layout.preferredHeight: 100 - - ScrollBar { - size: 0.3 - position: 0.2 - active: true - orientation: Qt.Vertical - height: parent.height - anchors.right: parent.right + RowLayout { + Switch { + text: "Normal" + } + Switch { + text: "Pressed" + pressed: true + } + Switch { + text: "Checked" + checked: true + } + Switch { + text: "CH + PR" + checked: true pressed: true } + Switch { + text: "Disabled" + enabled: false + } } - Frame { - Layout.preferredWidth: 100 - Layout.preferredHeight: 100 - - ScrollBar { - size: 0.3 - position: 0.2 - active: true - orientation: Qt.Vertical - height: parent.height - anchors.right: parent.right + RowLayout { + ProgressBar { + value: 0.5 + } + ProgressBar { + value: 0.5 + indeterminate: true + } + ProgressBar { + value: 0.5 enabled: false } } - } - RowLayout { - Rectangle { - width: 100 - height: 100 - color: "transparent" - border.color: "#cccccc" - - ScrollIndicator { - size: 0.3 - position: 0.2 - active: true - orientation: Qt.Vertical - height: parent.height - anchors.right: parent.right + RowLayout { + Slider { + value: 0.5 + } + Slider { + value: 0.5 + pressed: true + } + Slider { + value: 0.5 + enabled: false } } - Rectangle { - width: 100 - height: 100 - color: "transparent" - border.color: "#cccccc" - - ScrollIndicator { - size: 0.3 - position: 0.2 - active: true - orientation: Qt.Vertical - height: parent.height - anchors.right: parent.right + RowLayout { + RangeSlider { + first.value: 0.25 + second.value: 0.75 + } + RangeSlider { + first.value: 0.25 + first.pressed: true + second.value: 0.75 + } + RangeSlider { + first.value: 0.25 + second.value: 0.75 enabled: false } } - } - RowLayout { - Slider { - value: 0.5 - } - Slider { - value: 0.5 - pressed: true - } - Slider { - value: 0.5 - enabled: false - } - } + RowLayout { + Item { + implicitWidth: normalGroupBox.width + implicitHeight: normalTextArea.implicitHeight - RowLayout { - RangeSlider { - first.value: 0.25 - second.value: 0.75 - } - RangeSlider { - first.value: 0.25 - first.pressed: true - second.value: 0.75 - } - RangeSlider { - first.value: 0.25 - second.value: 0.75 - enabled: false - } - } + TextArea { + id: normalTextArea + text: "Normal" + } + } + Item { + implicitWidth: normalGroupBox.width + implicitHeight: normalTextArea.implicitHeight - RowLayout { - Switch { - text: "Normal" - } - Switch { - text: "Pressed" - pressed: true - } - Switch { - text: "Checked" - checked: true + TextArea { + text: "Placeholder" + } + } + Item { + implicitWidth: normalGroupBox.width + implicitHeight: normalTextArea.implicitHeight + + TextArea { + text: "Disabled" + enabled: false + } + } } - Switch { - text: "Checked + Pressed" - checked: true - pressed: true + + RowLayout { + Item { + implicitWidth: normalGroupBox.implicitWidth + implicitHeight: normalTextField.implicitHeight + + TextField { + id: normalTextField + text: "Normal" + } + } + Item { + implicitWidth: normalGroupBox.implicitWidth + implicitHeight: normalTextField.implicitHeight + + TextField { + placeholderText: "Placeholder" + } + } + Item { + implicitWidth: normalGroupBox.implicitWidth + implicitHeight: normalTextField.implicitHeight + + TextField { + text: "Disabled" + enabled: false + } + } } - Switch { - text: "Disabled" - enabled: false + + RowLayout { + Item { + implicitWidth: normalGroupBox.implicitWidth + implicitHeight: normalSpinBox.implicitHeight + + SpinBox { + id: normalSpinBox + } + } + Item { + implicitWidth: normalGroupBox.implicitWidth + implicitHeight: normalSpinBox.implicitHeight + + SpinBox { + up.pressed: true + } + } + Item { + implicitWidth: normalGroupBox.implicitWidth + implicitHeight: normalSpinBox.implicitHeight + + SpinBox { + enabled: false + } + } } - } - RowLayout { - TabBar { - TabButton { - text: "Normal" + RowLayout { + GroupBox { + id: normalGroupBox + title: "Normal" + + Item { + implicitWidth: 200 + implicitHeight: 100 + + BusyIndicator { + anchors.centerIn: parent + } + } } - TabButton { - text: "Pressed" - pressed: true + GroupBox { + enabled: false + title: "Disabled" + + Item { + implicitWidth: 200 + implicitHeight: 100 + + BusyIndicator { + anchors.centerIn: parent + } + } } - TabButton { - text: "Disabled" + GroupBox { enabled: false + title: "." + label.visible: false + + Item { + implicitWidth: 200 + implicitHeight: 100 + + PageIndicator { + count: 5 + enabled: false + anchors.bottom: parent.bottom + anchors.horizontalCenter: parent.horizontalCenter + } + } } } - } - RowLayout { - TextArea { - text: "Normal" - } - TextArea { - text: "Disabled" - enabled: false - } - } + RowLayout { + Frame { + id: scrollBarFrame - RowLayout { - TextField { - text: "Normal" - } - TextField { - text: "Disabled" - enabled: false - } - } + Item { + implicitWidth: 200 + implicitHeight: 100 - RowLayout { - ToolBar { - Row { - ToolButton { - text: "Normal!" + Label { + text: "Normal" + anchors.centerIn: parent + } + + ScrollBar { + size: 0.3 + position: 0.2 + active: true + orientation: Qt.Vertical + height: parent.height + anchors.right: parent.right + } } - ToolButton { - text: "Pressed!" - pressed: true + } + + Frame { + Item { + implicitWidth: 200 + implicitHeight: 100 + + Label { + text: "Pressed" + anchors.centerIn: parent + } + + ScrollBar { + size: 0.3 + position: 0.2 + active: true + orientation: Qt.Vertical + height: parent.height + anchors.right: parent.right + pressed: true + } } - ToolButton { - text: "Disabled!" + } + + Frame { + Item { + implicitWidth: 200 + implicitHeight: 100 enabled: false + + Label { + text: "Disabled" + anchors.centerIn: parent + } + + ScrollBar { + size: 0.3 + position: 0.2 + active: true + orientation: Qt.Vertical + height: parent.height + anchors.right: parent.right + } } } } - } - RowLayout { - Frame { - Tumbler { - model: 5 - implicitWidth: 100 - implicitHeight: 100 + RowLayout { + Frame { + Layout.preferredWidth: 100 + Layout.preferredHeight: 100 + + ScrollIndicator { + size: 0.3 + position: 0.2 + active: true + orientation: Qt.Vertical + height: parent.height + anchors.right: parent.right + } + } + + Frame { + Layout.preferredWidth: 100 + Layout.preferredHeight: 100 + + ScrollIndicator { + size: 0.3 + position: 0.2 + active: true + orientation: Qt.Vertical + height: parent.height + anchors.right: parent.right + enabled: false + } + } + } + + RowLayout { + Frame { + Tumbler { + model: 5 + implicitWidth: 100 + implicitHeight: 100 + } + } + Frame { + Tumbler { + model: 5 + implicitWidth: 100 + implicitHeight: 100 + enabled: false + } } } - Frame { - Tumbler { - model: 5 - implicitWidth: 100 - implicitHeight: 100 + + RowLayout { + Dial { + } + Dial { enabled: false } } diff --git a/tests/manual/testbench/testbench.pro b/tests/manual/testbench/testbench.pro index 92eef0a0..082ca66f 100644 --- a/tests/manual/testbench/testbench.pro +++ b/tests/manual/testbench/testbench.pro @@ -1,6 +1,6 @@ TEMPLATE = app -QT += qml quick +QT += qml quick core-private CONFIG += c++11 SOURCES += main.cpp |