diff options
Diffstat (limited to 'examples/quickcontrols')
753 files changed, 15755 insertions, 0 deletions
diff --git a/examples/quickcontrols/CMakeLists.txt b/examples/quickcontrols/CMakeLists.txt new file mode 100644 index 0000000000..e4021bf430 --- /dev/null +++ b/examples/quickcontrols/CMakeLists.txt @@ -0,0 +1,21 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +qt_internal_add_example(attachedstyleproperties) +qt_internal_add_example(gallery) +if (TARGET Qt::Sql) + add_subdirectory(chattutorial) +endif() +if (QT_FEATURE_quicktemplates2_calendar AND TARGET Qt::Sql) + qt_internal_add_example(eventcalendar) +endif() +qt_internal_add_example(texteditor) +qt_internal_add_example(contactlist) +qt_internal_add_example(sidepanel) +qt_internal_add_example(swipetoremove) +qt_internal_add_example(wearable) +qt_internal_add_example(imagine/automotive) +qt_internal_add_example(imagine/musicplayer) +if(TARGET Qt::Widgets) + qt_internal_add_example(flatstyle) +endif() diff --git a/examples/quickcontrols/attachedstyleproperties/CMakeLists.txt b/examples/quickcontrols/attachedstyleproperties/CMakeLists.txt new file mode 100644 index 0000000000..229129f5c6 --- /dev/null +++ b/examples/quickcontrols/attachedstyleproperties/CMakeLists.txt @@ -0,0 +1,52 @@ +cmake_minimum_required(VERSION 3.16) +project(attachedstyleproperties LANGUAGES CXX) + +set(CMAKE_AUTOMOC ON) + +if(NOT DEFINED INSTALL_EXAMPLESDIR) + set(INSTALL_EXAMPLESDIR "examples") +endif() + +set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/quickcontrols2/attachedstyleproperties") + +find_package(Qt6 REQUIRED COMPONENTS Core Gui Qml QuickControls2) +qt_standard_project_setup() + +add_subdirectory(MyStyle) + +qt_add_executable(attachedstylepropertiesexample + WIN32 + MACOSX_BUNDLE + attachedstyleproperties.cpp +) + +qt_add_qml_module(attachedstylepropertiesexample + URI App + VERSION 1.0 + QML_FILES + attachedstyleproperties.qml + NO_RESOURCE_TARGET_PATH +) + +target_link_libraries(attachedstylepropertiesexample PRIVATE + Qt::Core + Qt::Gui + Qt::Qml + Qt::QuickControls2 +) + +add_dependencies(attachedstylepropertiesexample MyStyle) + +install(TARGETS attachedstylepropertiesexample + RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" + LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" +) + +include(../../quick/shared/QtBundleQmlModuleForMacOS.cmake) + +set(app_target "attachedstylepropertiesexample") +set(qml_plugin_target "MyStyleplugin") +set(qml_module_uri "MyStyle") +add_qml_module_to_macos_app_bundle( + "${app_target}" "${qml_plugin_target}" "${qml_module_uri}") diff --git a/examples/quickcontrols/attachedstyleproperties/MyStyle/ApplicationWindow.qml b/examples/quickcontrols/attachedstyleproperties/MyStyle/ApplicationWindow.qml new file mode 100644 index 0000000000..8a7bbc7ed2 --- /dev/null +++ b/examples/quickcontrols/attachedstyleproperties/MyStyle/ApplicationWindow.qml @@ -0,0 +1,17 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Templates as T + +import MyStyle + +T.ApplicationWindow { + color: MyStyle.windowColor + + Behavior on color { + ColorAnimation { + duration: 150 + } + } +} diff --git a/examples/quickcontrols/attachedstyleproperties/MyStyle/Button.qml b/examples/quickcontrols/attachedstyleproperties/MyStyle/Button.qml new file mode 100644 index 0000000000..7eabcb0b35 --- /dev/null +++ b/examples/quickcontrols/attachedstyleproperties/MyStyle/Button.qml @@ -0,0 +1,33 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Templates as T + +import MyStyle + +T.Button { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + padding: 6 + horizontalPadding: padding + 2 + spacing: 6 + + contentItem: Text { + text: control.text + font: control.font + color: control.MyStyle.buttonTextColor + verticalAlignment: Text.AlignVCenter + } + + background: Rectangle { + implicitWidth: 60 + implicitHeight: 40 + color: control.down ? Qt.darker(control.MyStyle.buttonColor, 1.1) : control.MyStyle.buttonColor + } +} diff --git a/examples/quickcontrols/attachedstyleproperties/MyStyle/CMakeLists.txt b/examples/quickcontrols/attachedstyleproperties/MyStyle/CMakeLists.txt new file mode 100644 index 0000000000..81b15f128f --- /dev/null +++ b/examples/quickcontrols/attachedstyleproperties/MyStyle/CMakeLists.txt @@ -0,0 +1,45 @@ +if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) + message(FATAL_ERROR "MyStyle should be built as part of the 'attachedstyleproperties' project, and not in isolation.") +endif() + +set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/quickcontrols2/attachedstyleproperties") + +qt_add_qml_module(MyStyle + URI MyStyle + VERSION 1.0 + IMPORTS + QtQuick.Controls.Material + QML_FILES + ApplicationWindow.qml + Button.qml + Label.qml + Popup.qml + Switch.qml + ToolBar.qml + SOURCES + mystyle.cpp + mystyle.h +) + +include(GenerateExportHeader) +target_include_directories(MyStyle PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) # find autogenerated header +generate_export_header(MyStyle) + +find_package(Qt6 REQUIRED COMPONENTS Core Gui Qml QuickControls2) + +target_link_libraries(MyStyle PRIVATE + Qt::Core + Qt::Gui + Qt::Qml + Qt::QuickControls2 +) + +install(TARGETS MyStyle + RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" + LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" +) + +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/qmldir + DESTINATION "${INSTALL_EXAMPLEDIR}" +) diff --git a/examples/quickcontrols/attachedstyleproperties/MyStyle/Label.qml b/examples/quickcontrols/attachedstyleproperties/MyStyle/Label.qml new file mode 100644 index 0000000000..3d045aa70e --- /dev/null +++ b/examples/quickcontrols/attachedstyleproperties/MyStyle/Label.qml @@ -0,0 +1,11 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Templates as T + +import MyStyle + +T.Label { + color: MyStyle.windowTextColor +} diff --git a/examples/quickcontrols/attachedstyleproperties/MyStyle/Popup.qml b/examples/quickcontrols/attachedstyleproperties/MyStyle/Popup.qml new file mode 100644 index 0000000000..0f5e753f60 --- /dev/null +++ b/examples/quickcontrols/attachedstyleproperties/MyStyle/Popup.qml @@ -0,0 +1,48 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Templates as T +import MyStyle + +T.Popup { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + padding: 12 + + enter: Transition { + NumberAnimation { + property: "opacity" + from: 0.0 + to: 1.0 + easing.type: Easing.OutCubic + duration: 150 + } + } + + exit: Transition { + NumberAnimation { + property: "opacity" + from: 1.0 + to: 0.0 + easing.type: Easing.OutCubic + duration: 150 + } + } + + background: Rectangle { + radius: 2 + color: control.MyStyle.popupColor + border.color: control.MyStyle.popupBorderColor + } + + T.Overlay.modeless: Rectangle { + color: control.MyStyle.backgroundDimColor + Behavior on opacity { NumberAnimation { duration: 150 } } + } +} diff --git a/examples/quickcontrols/attachedstyleproperties/MyStyle/Switch.qml b/examples/quickcontrols/attachedstyleproperties/MyStyle/Switch.qml new file mode 100644 index 0000000000..59bda147b7 --- /dev/null +++ b/examples/quickcontrols/attachedstyleproperties/MyStyle/Switch.qml @@ -0,0 +1,58 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Templates as T + +import MyStyle + +T.Switch { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + padding: 6 + horizontalPadding: padding + 2 + spacing: 6 + + indicator: Rectangle { + implicitWidth: 56 + implicitHeight: 28 + + x: control.text + ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) + : control.leftPadding + (control.availableWidth - width) / 2 + y: control.topPadding + (control.availableHeight - height) / 2 + + radius: 8 + color: control.down ? Qt.darker(control.MyStyle.buttonColor, 1.1) : control.MyStyle.buttonColor + + 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: 8 + color: Qt.lighter(control.MyStyle.buttonColor) + + Behavior on x { + enabled: !control.down + SmoothedAnimation { velocity: 200 } + } + } + } + + contentItem: Text { + leftPadding: control.indicator && !control.mirrored ? control.indicator.width + control.spacing : 0 + rightPadding: control.indicator && control.mirrored ? control.indicator.width + control.spacing : 0 + + text: control.text + font: control.font + color: control.MyStyle.windowTextColor + elide: Text.ElideRight + verticalAlignment: Text.AlignVCenter + } +} diff --git a/examples/quickcontrols/attachedstyleproperties/MyStyle/ToolBar.qml b/examples/quickcontrols/attachedstyleproperties/MyStyle/ToolBar.qml new file mode 100644 index 0000000000..b0cd597c87 --- /dev/null +++ b/examples/quickcontrols/attachedstyleproperties/MyStyle/ToolBar.qml @@ -0,0 +1,24 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Templates as T + +import MyStyle + +T.ToolBar { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + background: Rectangle { + implicitHeight: 40 + // Ensure that we use Control's attached MyStyle object by qualifying + // the binding with its id. If we don't do this, an extra, unnecessary + // attached MyStyle object will be created for the Rectangle. + color: control.MyStyle.toolBarColor + } +} diff --git a/examples/quickcontrols/attachedstyleproperties/MyStyle/mystyle.cpp b/examples/quickcontrols/attachedstyleproperties/MyStyle/mystyle.cpp new file mode 100644 index 0000000000..40f7af702e --- /dev/null +++ b/examples/quickcontrols/attachedstyleproperties/MyStyle/mystyle.cpp @@ -0,0 +1,136 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#include "mystyle.h" + +// If no value was inherited from a parent or explicitly set, the "global" values are used. +static MyStyle::Theme globalTheme = MyStyle::Light; + +MyStyle::MyStyle(QObject *parent) + : QQuickAttachedPropertyPropagator(parent) + , m_theme(globalTheme) +{ + // A static function could be called here that reads globalTheme from a + // settings file once at startup. That value would override the global + // value. This is similar to what the Imagine and Material styles do, for + // example. + + initialize(); +} + +MyStyle *MyStyle::qmlAttachedProperties(QObject *object) +{ + return new MyStyle(object); +} + +MyStyle::Theme MyStyle::theme() const +{ + return m_theme; +} + +void MyStyle::setTheme(Theme theme) +{ + // When this function is called, we know that the user has explicitly + // set a theme on this attached object. We set this to true even if + // the effective theme didn't change, because it's important that + // the user's specified value is respected (and not inherited from + // from the parent). + m_explicitTheme = true; + if (m_theme == theme) + return; + + m_theme = theme; + propagateTheme(); + themeChange(); + +} + +void MyStyle::inheritTheme(Theme theme) +{ + if (m_explicitTheme || m_theme == theme) + return; + + m_theme = theme; + propagateTheme(); + themeChange(); +} + +void MyStyle::propagateTheme() +{ + const auto styles = attachedChildren(); + for (QQuickAttachedPropertyPropagator *child : styles) { + MyStyle *myStyle = qobject_cast<MyStyle *>(child); + if (myStyle) + myStyle->inheritTheme(m_theme); + } +} + +void MyStyle::resetTheme() +{ + if (!m_explicitTheme) + return; + + m_explicitTheme = false; + MyStyle *myStyle = qobject_cast<MyStyle *>(attachedParent()); + inheritTheme(myStyle ? myStyle->theme() : globalTheme); +} + +void MyStyle::themeChange() +{ + emit themeChanged(); + // Emit any other change signals for properties that depend on the theme here... +} + +QColor MyStyle::windowColor() const +{ + return m_theme == Light ? QColor::fromRgb(0xf0f0f0) : QColor::fromRgb(0x303030); +} + +QColor MyStyle::windowTextColor() const +{ + return m_theme == Light ? QColor::fromRgb(0x5c5c5c) : QColor::fromRgb(0xe0e0e0); +} + +QColor MyStyle::buttonColor() const +{ + return m_theme == Light ? QColor::fromRgb(0xc2e1ff) : QColor::fromRgb(0x74bbff); +} + +QColor MyStyle::buttonTextColor() const +{ + return m_theme == Light ? QColor::fromRgb(0x5c5c5c) : QColor::fromRgb(0xffffff); +} + +QColor MyStyle::toolBarColor() const +{ + return m_theme == Light ? QColor::fromRgb(0x4da6ff) : QColor::fromRgb(0x0066cc); +} + +QColor MyStyle::popupColor() const +{ +// const QColor winColor = windowColor(); +// return m_theme == Light ? winColor.darker(120) : winColor.lighter(120); + return windowColor().lighter(120); +} + +QColor MyStyle::popupBorderColor() const +{ + const QColor winColor = windowColor(); + return m_theme == Light ? winColor.darker(140) : winColor.lighter(140); +} + +QColor MyStyle::backgroundDimColor() const +{ + const QColor winColor = windowColor().darker(); + return QColor::fromRgb(winColor.red(), winColor.green(), winColor.blue(), 100); +} + +void MyStyle::attachedParentChange(QQuickAttachedPropertyPropagator *newParent, QQuickAttachedPropertyPropagator *oldParent) +{ + Q_UNUSED(oldParent); + MyStyle *attachedParentStyle = qobject_cast<MyStyle *>(newParent); + if (attachedParentStyle) { + inheritTheme(attachedParentStyle->theme()); + // Do any other inheriting here... + } +} diff --git a/examples/quickcontrols/attachedstyleproperties/MyStyle/mystyle.h b/examples/quickcontrols/attachedstyleproperties/MyStyle/mystyle.h new file mode 100644 index 0000000000..da87ab4718 --- /dev/null +++ b/examples/quickcontrols/attachedstyleproperties/MyStyle/mystyle.h @@ -0,0 +1,76 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#ifndef MYSTYLE_H +#define MYSTYLE_H + +#include <QColor> +#include <QQmlEngine> +#include <QQuickAttachedPropertyPropagator> + +#include "mystyle_export.h" + +class MYSTYLE_EXPORT MyStyle : public QQuickAttachedPropertyPropagator +{ + Q_OBJECT + // Provide a RESET function in order to allow an item to set MyStyle.theme to undefined + // in order to use its parent's (or global) theme after one was explicitly set on it. + Q_PROPERTY(Theme theme READ theme WRITE setTheme RESET resetTheme NOTIFY themeChanged FINAL) + // As the values of these properties only depend on the theme, they can all use the theme + // property's change signal. + Q_PROPERTY(QColor windowColor READ windowColor NOTIFY themeChanged FINAL) + Q_PROPERTY(QColor windowTextColor READ windowTextColor NOTIFY themeChanged FINAL) + Q_PROPERTY(QColor buttonColor READ buttonColor NOTIFY themeChanged FINAL) + Q_PROPERTY(QColor buttonTextColor READ buttonTextColor NOTIFY themeChanged FINAL) + Q_PROPERTY(QColor toolBarColor READ toolBarColor NOTIFY themeChanged FINAL) + Q_PROPERTY(QColor popupColor READ popupColor NOTIFY themeChanged FINAL) + Q_PROPERTY(QColor popupBorderColor READ popupBorderColor NOTIFY themeChanged FINAL) + Q_PROPERTY(QColor backgroundDimColor READ backgroundDimColor NOTIFY themeChanged FINAL) + + QML_ELEMENT + QML_ATTACHED(MyStyle) + QML_UNCREATABLE("") + QML_ADDED_IN_VERSION(1, 0) + +public: + enum Theme { + Light, + Dark + }; + + Q_ENUM(Theme) + + explicit MyStyle(QObject *parent = nullptr); + + static MyStyle *qmlAttachedProperties(QObject *object); + + Theme theme() const; + void setTheme(Theme theme); + void inheritTheme(Theme theme); + void propagateTheme(); + void resetTheme(); + void themeChange(); + + QColor windowColor() const; + QColor windowTextColor() const; + QColor buttonColor() const; + QColor buttonTextColor() const; + QColor toolBarColor() const; + QColor popupColor() const; + QColor popupBorderColor() const; + QColor backgroundDimColor() const; + +Q_SIGNALS: + void themeChanged(); + +protected: + void attachedParentChange(QQuickAttachedPropertyPropagator *newParent, QQuickAttachedPropertyPropagator *oldParent) override; + +private: + // Whether a color value was explicitly set on the specific object that this attached style object represents. + bool m_explicitTheme = false; + // The actual values for this item, whether explicit, inherited or globally set. + Theme m_theme = Light; +}; + +#endif // MYSTYLE_H diff --git a/examples/quickcontrols/attachedstyleproperties/attachedstyleproperties.cpp b/examples/quickcontrols/attachedstyleproperties/attachedstyleproperties.cpp new file mode 100644 index 0000000000..376e53c055 --- /dev/null +++ b/examples/quickcontrols/attachedstyleproperties/attachedstyleproperties.cpp @@ -0,0 +1,28 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#include <QGuiApplication> +#include <QQmlApplicationEngine> +#include <QDir> + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + app.setOrganizationName("QtProject"); + app.setOrganizationDomain("qt-project.org"); + app.setApplicationName("Attached Objects"); + + QQmlApplicationEngine engine; +#ifdef Q_OS_MACOS + engine.addImportPath(app.applicationDirPath() + "/../PlugIns"); +#endif + const QUrl url(QStringLiteral("qrc:/attachedstyleproperties.qml")); + QObject::connect(&engine, &QQmlApplicationEngine::objectCreated, + &app, [url](QObject *obj, const QUrl &objUrl) { + if (!obj && url == objUrl) + QCoreApplication::exit(-1); + }, Qt::QueuedConnection); + engine.load(url); + + return app.exec(); +} diff --git a/examples/quickcontrols/attachedstyleproperties/attachedstyleproperties.qml b/examples/quickcontrols/attachedstyleproperties/attachedstyleproperties.qml new file mode 100644 index 0000000000..e08e19801f --- /dev/null +++ b/examples/quickcontrols/attachedstyleproperties/attachedstyleproperties.qml @@ -0,0 +1,110 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Layouts + +import MyStyle + +ApplicationWindow { + width: 800 + height: 600 + title: qsTr("Attached Objects") + visible: true + + MyStyle.theme: darkModeSwitch.checked ? MyStyle.Dark : MyStyle.Light + + header: ToolBar { + MyStyle.theme: MyStyle.Dark + + RowLayout { + anchors.fill: parent + anchors.leftMargin: 12 + + Label { + text: qsTr("This is a Label in a ToolBar") + } + + Item { + Layout.fillWidth: true + } + + Switch { + id: darkModeSwitch + text: qsTr("Dark mode") + } + } + } + + ColumnLayout { + anchors.centerIn: parent + spacing: 20 + + Label { + text: qsTr("This is a Label in an ApplicationWindow") + Layout.alignment: Qt.AlignHCenter + } + + RowLayout { + Button { + text: qsTr("Open Popup") + onClicked: popup.open() + } + + Button { + text: qsTr("Open Window") + onClicked: { + if (!childWindow.active) + childWindow.show() + else + childWindow.raise() + } + } + } + } + + Popup { + id: popup + dim: true + anchors.centerIn: parent + + ColumnLayout { + anchors.centerIn: parent + spacing: 20 + + Label { + text: qsTr("This is a Label in a Popup") + Layout.alignment: Qt.AlignHCenter + } + + Button { + text: qsTr("Close Popup") + Layout.alignment: Qt.AlignHCenter + onClicked: popup.close() + } + } + } + + ApplicationWindow { + id: childWindow + width: 600 + height: 400 + title: qsTr("Attached Objects - Child Window") + + ColumnLayout { + anchors.centerIn: parent + spacing: 20 + + Label { + text: qsTr("This is a Label in a child ApplicationWindow") + Layout.alignment: Qt.AlignHCenter + } + + Button { + text: qsTr("Close Window") + Layout.alignment: Qt.AlignHCenter + onClicked: childWindow.close() + } + } + } +} diff --git a/examples/quickcontrols/attachedstyleproperties/doc/images/qtquickcontrols2-attachedstyleproperties.png b/examples/quickcontrols/attachedstyleproperties/doc/images/qtquickcontrols2-attachedstyleproperties.png Binary files differnew file mode 100644 index 0000000000..2cd5f214f7 --- /dev/null +++ b/examples/quickcontrols/attachedstyleproperties/doc/images/qtquickcontrols2-attachedstyleproperties.png diff --git a/examples/quickcontrols/attachedstyleproperties/doc/src/qtquickcontrols2-attachedstyleproperties.qdoc b/examples/quickcontrols/attachedstyleproperties/doc/src/qtquickcontrols2-attachedstyleproperties.qdoc new file mode 100644 index 0000000000..de43fc80bd --- /dev/null +++ b/examples/quickcontrols/attachedstyleproperties/doc/src/qtquickcontrols2-attachedstyleproperties.qdoc @@ -0,0 +1,18 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only + +/*! + \example attachedstyleproperties + \keyword Qt Quick Controls - Attached Style Properties Example + \title Qt Quick Controls - Attached Style Properties Example + \ingroup qtquickcontrols2-examples + \brief Demonstrates use of QQuickAttachedPropertyPropagator. + + \image qtquickcontrols2-attachedstyleproperties.png + + The Attached Style Properties example is a simple application that shows + how to use \l QQuickAttachedPropertyPropagator to propagate attached + property values to child objects. + + \include examples-run.qdocinc +*/ diff --git a/examples/quickcontrols/chattutorial/CMakeLists.txt b/examples/quickcontrols/chattutorial/CMakeLists.txt new file mode 100644 index 0000000000..4da558f2f5 --- /dev/null +++ b/examples/quickcontrols/chattutorial/CMakeLists.txt @@ -0,0 +1,10 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +qt_internal_add_example(chapter1) +qt_internal_add_example(chapter2) +qt_internal_add_example(chapter3) +if (TARGET Qt::Sql) + qt_internal_add_example(chapter4) + qt_internal_add_example(chapter5) +endif() diff --git a/examples/quickcontrols/chattutorial/chapter1/CMakeLists.txt b/examples/quickcontrols/chattutorial/chapter1/CMakeLists.txt new file mode 100644 index 0000000000..3320012cb4 --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter1/CMakeLists.txt @@ -0,0 +1,46 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +cmake_minimum_required(VERSION 3.16) +project(chapter1 LANGUAGES CXX) + +set(CMAKE_AUTOMOC ON) + +if(NOT DEFINED INSTALL_EXAMPLESDIR) + set(INSTALL_EXAMPLESDIR "examples") +endif() + +set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/quickcontrols2/chattutorial/chapter1") + +find_package(Qt6 REQUIRED COMPONENTS Core Gui Qml Quick) + +qt_add_executable(chattutorial-chapter1 WIN32 MACOSX_BUNDLE + main.cpp +) + +target_link_libraries(chattutorial-chapter1 PRIVATE + Qt::Core + Qt::Gui + Qt::Qml + Qt::Quick +) + +qt_add_qml_module(chattutorial-chapter1 + URI chapter1 + VERSION 1.0 + QML_FILES + "main.qml" +) + +qt6_add_resources(chattutorial-chapter1 "conf" + PREFIX + "/" + FILES + "qtquickcontrols2.conf" +) + +install(TARGETS chattutorial-chapter1 + RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" + LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" +) diff --git a/examples/quickcontrols/chattutorial/chapter1/chapter1.pro b/examples/quickcontrols/chattutorial/chapter1/chapter1.pro new file mode 100644 index 0000000000..6b50809f20 --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter1/chapter1.pro @@ -0,0 +1,14 @@ +TEMPLATE = app + +QT += qml quick +CONFIG += c++11 + +SOURCES += main.cpp + +resources.files = main.qml +resources.prefix = chapter1/ +RESOURCES += resources \ + qtquickcontrols2.conf + +target.path = $$[QT_INSTALL_EXAMPLES]/quickcontrols2/chattutorial/chapter1 +INSTALLS += target diff --git a/examples/quickcontrols/chattutorial/chapter1/main.cpp b/examples/quickcontrols/chattutorial/chapter1/main.cpp new file mode 100644 index 0000000000..3752f91d90 --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter1/main.cpp @@ -0,0 +1,16 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#include <QGuiApplication> +#include <QQmlApplicationEngine> + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + engine.load(QUrl(QStringLiteral("qrc:/chapter1/main.qml"))); + + return app.exec(); +} + diff --git a/examples/quickcontrols/chattutorial/chapter1/main.qml b/examples/quickcontrols/chattutorial/chapter1/main.qml new file mode 100644 index 0000000000..d0651b5816 --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter1/main.qml @@ -0,0 +1,23 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + width: 540 + height: 960 + visible: true + + Page { + anchors.fill: parent + header: Label { + padding: 10 + text: qsTr("Contacts") + font.pixelSize: 20 + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + } +} + diff --git a/examples/quickcontrols/chattutorial/chapter1/qtquickcontrols2.conf b/examples/quickcontrols/chattutorial/chapter1/qtquickcontrols2.conf new file mode 100644 index 0000000000..db9486764e --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter1/qtquickcontrols2.conf @@ -0,0 +1,2 @@ +[Controls] +Style=Basic diff --git a/examples/quickcontrols/chattutorial/chapter2/CMakeLists.txt b/examples/quickcontrols/chattutorial/chapter2/CMakeLists.txt new file mode 100644 index 0000000000..c011336802 --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter2/CMakeLists.txt @@ -0,0 +1,59 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +cmake_minimum_required(VERSION 3.16) +project(chapter2 LANGUAGES CXX) + +set(CMAKE_AUTOMOC ON) + +if(NOT DEFINED INSTALL_EXAMPLESDIR) + set(INSTALL_EXAMPLESDIR "examples") +endif() + +set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/quickcontrols2/chattutorial/chapter2") + +find_package(Qt6 REQUIRED COMPONENTS Core Gui Qml Quick) + +qt_add_executable(chattutorial-chapter2 WIN32 MACOSX_BUNDLE + main.cpp +) + +target_link_libraries(chattutorial-chapter2 PRIVATE + Qt::Core + Qt::Gui + Qt::Qml + Qt::Quick +) + +qt_add_qml_module(chattutorial-chapter2 + URI chapter2 + VERSION 1.0 + QML_FILES + "main.qml" + RESOURCES + "images/Albert_Einstein.png" + "images/Albert_Einstein@2x.png" + "images/Albert_Einstein@3x.png" + "images/Albert_Einstein@4x.png" + "images/Ernest_Hemingway.png" + "images/Ernest_Hemingway@2x.png" + "images/Ernest_Hemingway@3x.png" + "images/Ernest_Hemingway@4x.png" + "images/Hans_Gude.png" + "images/Hans_Gude@2x.png" + "images/Hans_Gude@3x.png" + "images/Hans_Gude@4x.png" +) + +qt6_add_resources(chattutorial-chapter2 "conf" + PREFIX + "/" + FILES + "qtquickcontrols2.conf" +) + +install(TARGETS chattutorial-chapter2 + RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" + LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" +) diff --git a/examples/quickcontrols/chattutorial/chapter2/chapter2.pro b/examples/quickcontrols/chattutorial/chapter2/chapter2.pro new file mode 100644 index 0000000000..15429b7c89 --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter2/chapter2.pro @@ -0,0 +1,27 @@ +TEMPLATE = app + +QT += qml quick +CONFIG += c++11 + +SOURCES += main.cpp + +resources.files = \ + images/Albert_Einstein.png \ + images/Albert_Einstein@2x.png \ + images/Albert_Einstein@3x.png \ + images/Albert_Einstein@4x.png \ + images/Ernest_Hemingway.png \ + images/Ernest_Hemingway@2x.png \ + images/Ernest_Hemingway@3x.png \ + images/Ernest_Hemingway@4x.png \ + images/Hans_Gude.png \ + images/Hans_Gude@2x.png \ + images/Hans_Gude@3x.png \ + images/Hans_Gude@4x.png \ + main.qml +resources.prefix = chapter2/ +RESOURCES += resources \ + qtquickcontrols2.conf + +target.path = $$[QT_INSTALL_EXAMPLES]/quickcontrols2/chattutorial/chapter2 +INSTALLS += target diff --git a/examples/quickcontrols/chattutorial/chapter2/images/Albert_Einstein.png b/examples/quickcontrols/chattutorial/chapter2/images/Albert_Einstein.png Binary files differnew file mode 100644 index 0000000000..7c44b90b8d --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter2/images/Albert_Einstein.png diff --git a/examples/quickcontrols/chattutorial/chapter2/images/Albert_Einstein@2x.png b/examples/quickcontrols/chattutorial/chapter2/images/Albert_Einstein@2x.png Binary files differnew file mode 100644 index 0000000000..6ce9c39b6c --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter2/images/Albert_Einstein@2x.png diff --git a/examples/quickcontrols/chattutorial/chapter2/images/Albert_Einstein@3x.png b/examples/quickcontrols/chattutorial/chapter2/images/Albert_Einstein@3x.png Binary files differnew file mode 100644 index 0000000000..aab6a6a162 --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter2/images/Albert_Einstein@3x.png diff --git a/examples/quickcontrols/chattutorial/chapter2/images/Albert_Einstein@4x.png b/examples/quickcontrols/chattutorial/chapter2/images/Albert_Einstein@4x.png Binary files differnew file mode 100644 index 0000000000..3611284df4 --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter2/images/Albert_Einstein@4x.png diff --git a/examples/quickcontrols/chattutorial/chapter2/images/Ernest_Hemingway.png b/examples/quickcontrols/chattutorial/chapter2/images/Ernest_Hemingway.png Binary files differnew file mode 100644 index 0000000000..3ac8992fd9 --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter2/images/Ernest_Hemingway.png diff --git a/examples/quickcontrols/chattutorial/chapter2/images/Ernest_Hemingway@2x.png b/examples/quickcontrols/chattutorial/chapter2/images/Ernest_Hemingway@2x.png Binary files differnew file mode 100644 index 0000000000..122d9f1e53 --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter2/images/Ernest_Hemingway@2x.png diff --git a/examples/quickcontrols/chattutorial/chapter2/images/Ernest_Hemingway@3x.png b/examples/quickcontrols/chattutorial/chapter2/images/Ernest_Hemingway@3x.png Binary files differnew file mode 100644 index 0000000000..2fe9c2cc1c --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter2/images/Ernest_Hemingway@3x.png diff --git a/examples/quickcontrols/chattutorial/chapter2/images/Ernest_Hemingway@4x.png b/examples/quickcontrols/chattutorial/chapter2/images/Ernest_Hemingway@4x.png Binary files differnew file mode 100644 index 0000000000..96fb6788b5 --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter2/images/Ernest_Hemingway@4x.png diff --git a/examples/quickcontrols/chattutorial/chapter2/images/Hans_Gude.png b/examples/quickcontrols/chattutorial/chapter2/images/Hans_Gude.png Binary files differnew file mode 100644 index 0000000000..907e38bc61 --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter2/images/Hans_Gude.png diff --git a/examples/quickcontrols/chattutorial/chapter2/images/Hans_Gude@2x.png b/examples/quickcontrols/chattutorial/chapter2/images/Hans_Gude@2x.png Binary files differnew file mode 100644 index 0000000000..6837796a83 --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter2/images/Hans_Gude@2x.png diff --git a/examples/quickcontrols/chattutorial/chapter2/images/Hans_Gude@3x.png b/examples/quickcontrols/chattutorial/chapter2/images/Hans_Gude@3x.png Binary files differnew file mode 100644 index 0000000000..29af422ad3 --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter2/images/Hans_Gude@3x.png diff --git a/examples/quickcontrols/chattutorial/chapter2/images/Hans_Gude@4x.png b/examples/quickcontrols/chattutorial/chapter2/images/Hans_Gude@4x.png Binary files differnew file mode 100644 index 0000000000..bc35eeaa79 --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter2/images/Hans_Gude@4x.png diff --git a/examples/quickcontrols/chattutorial/chapter2/images/images.qrc b/examples/quickcontrols/chattutorial/chapter2/images/images.qrc new file mode 100644 index 0000000000..9eda6aa29c --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter2/images/images.qrc @@ -0,0 +1,16 @@ +<RCC> + <qresource prefix="/"> + <file>Albert_Einstein.png</file> + <file>Albert_Einstein@2x.png</file> + <file>Albert_Einstein@3x.png</file> + <file>Albert_Einstein@4x.png</file> + <file>Ernest_Hemingway.png</file> + <file>Ernest_Hemingway@2x.png</file> + <file>Ernest_Hemingway@3x.png</file> + <file>Ernest_Hemingway@4x.png</file> + <file>Hans_Gude.png</file> + <file>Hans_Gude@2x.png</file> + <file>Hans_Gude@3x.png</file> + <file>Hans_Gude@4x.png</file> + </qresource> +</RCC> diff --git a/examples/quickcontrols/chattutorial/chapter2/main.cpp b/examples/quickcontrols/chattutorial/chapter2/main.cpp new file mode 100644 index 0000000000..eeb87becca --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter2/main.cpp @@ -0,0 +1,16 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#include <QGuiApplication> +#include <QQmlApplicationEngine> + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + engine.load(QUrl(QStringLiteral("qrc:/chapter2/main.qml"))); + + return app.exec(); +} + diff --git a/examples/quickcontrols/chattutorial/chapter2/main.qml b/examples/quickcontrols/chattutorial/chapter2/main.qml new file mode 100644 index 0000000000..851b482b01 --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter2/main.qml @@ -0,0 +1,45 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + width: 540 + height: 960 + visible: true + + Page { + anchors.fill: parent + header: Label { + padding: 10 + text: qsTr("Contacts") + font.pixelSize: 20 + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + + ListView { + id: listView + anchors.fill: parent + topMargin: 48 + leftMargin: 48 + bottomMargin: 48 + rightMargin: 48 + spacing: 20 + model: ["Albert Einstein", "Ernest Hemingway", "Hans Gude"] + delegate: ItemDelegate { + text: modelData + width: listView.width - listView.leftMargin - listView.rightMargin + height: avatar.implicitHeight + leftPadding: avatar.implicitWidth + 32 + + Image { + id: avatar + source: "images/" + modelData.replace(" ", "_") + ".png" + } + } + } + } +} + diff --git a/examples/quickcontrols/chattutorial/chapter2/qtquickcontrols2.conf b/examples/quickcontrols/chattutorial/chapter2/qtquickcontrols2.conf new file mode 100644 index 0000000000..db9486764e --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter2/qtquickcontrols2.conf @@ -0,0 +1,2 @@ +[Controls] +Style=Basic diff --git a/examples/quickcontrols/chattutorial/chapter3/CMakeLists.txt b/examples/quickcontrols/chattutorial/chapter3/CMakeLists.txt new file mode 100644 index 0000000000..92545ec1d0 --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter3/CMakeLists.txt @@ -0,0 +1,62 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +cmake_minimum_required(VERSION 3.16) +project(chapter3 LANGUAGES CXX) + +set(CMAKE_AUTOMOC ON) + +if(NOT DEFINED INSTALL_EXAMPLESDIR) + set(INSTALL_EXAMPLESDIR "examples") +endif() + +set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/quickcontrols2/chattutorial/chapter3") + +find_package(Qt6 REQUIRED COMPONENTS Core Gui Qml Quick) + +qt_add_executable(chattutorial-chapter3 WIN32 MACOSX_BUNDLE + main.cpp +) + +target_link_libraries(chattutorial-chapter3 PRIVATE + Qt::Core + Qt::Gui + Qt::Qml + Qt::Quick +) + +# Resources: +qt_add_qml_module(chattutorial-chapter3 + URI chapter3 + VERSION 1.0 + QML_FILES + "ContactPage.qml" + "ConversationPage.qml" + "main.qml" + RESOURCES + "images/Albert_Einstein.png" + "images/Albert_Einstein@2x.png" + "images/Albert_Einstein@3x.png" + "images/Albert_Einstein@4x.png" + "images/Ernest_Hemingway.png" + "images/Ernest_Hemingway@2x.png" + "images/Ernest_Hemingway@3x.png" + "images/Ernest_Hemingway@4x.png" + "images/Hans_Gude.png" + "images/Hans_Gude@2x.png" + "images/Hans_Gude@3x.png" + "images/Hans_Gude@4x.png" +) + +qt6_add_resources(chattutorial-chapter3 "conf" + PREFIX + "/" + FILES + "qtquickcontrols2.conf" +) + +install(TARGETS chattutorial-chapter3 + RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" + LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" +) diff --git a/examples/quickcontrols/chattutorial/chapter3/ContactPage.qml b/examples/quickcontrols/chattutorial/chapter3/ContactPage.qml new file mode 100644 index 0000000000..88979a40b2 --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter3/ContactPage.qml @@ -0,0 +1,41 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Controls + +Page { + id: root + + header: ToolBar { + Label { + text: qsTr("Contacts") + font.pixelSize: 20 + anchors.centerIn: parent + } + } + + ListView { + id: listView + anchors.fill: parent + topMargin: 48 + leftMargin: 48 + bottomMargin: 48 + rightMargin: 48 + spacing: 20 + model: ["Albert Einstein", "Ernest Hemingway", "Hans Gude"] + delegate: ItemDelegate { + text: modelData + width: listView.width - listView.leftMargin - listView.rightMargin + height: avatar.implicitHeight + leftPadding: avatar.implicitWidth + 32 + onClicked: root.StackView.view.push("ConversationPage.qml", { inConversationWith: modelData }) + + Image { + id: avatar + source: "images/" + modelData.replace(" ", "_") + ".png" + } + } + } +} + diff --git a/examples/quickcontrols/chattutorial/chapter3/ConversationPage.qml b/examples/quickcontrols/chattutorial/chapter3/ConversationPage.qml new file mode 100644 index 0000000000..e61d014e6e --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter3/ConversationPage.qml @@ -0,0 +1,96 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls + +Page { + id: root + + property string inConversationWith + + header: ToolBar { + ToolButton { + text: qsTr("Back") + anchors.left: parent.left + anchors.leftMargin: 10 + anchors.verticalCenter: parent.verticalCenter + onClicked: root.StackView.view.pop() + } + + Label { + id: pageTitle + text: inConversationWith + font.pixelSize: 20 + anchors.centerIn: parent + } + } + + ColumnLayout { + anchors.fill: parent + + ListView { + id: listView + Layout.fillWidth: true + Layout.fillHeight: true + Layout.margins: pane.leftPadding + messageField.leftPadding + displayMarginBeginning: 40 + displayMarginEnd: 40 + verticalLayoutDirection: ListView.BottomToTop + spacing: 12 + model: 10 + delegate: Row { + readonly property bool sentByMe: index % 2 == 0 + + anchors.right: sentByMe ? listView.contentItem.right : undefined + spacing: 6 + + Rectangle { + id: avatar + width: height + height: parent.height + color: "grey" + visible: !sentByMe + } + + Rectangle { + width: 80 + height: 40 + color: sentByMe ? "lightgrey" : "steelblue" + + Label { + anchors.centerIn: parent + text: index + color: sentByMe ? "black" : "white" + } + } + } + + ScrollBar.vertical: ScrollBar {} + } + + Pane { + id: pane + Layout.fillWidth: true + + RowLayout { + width: parent.width + + TextArea { + id: messageField + Layout.fillWidth: true + placeholderText: qsTr("Compose message") + wrapMode: TextArea.Wrap + } + + Button { + id: sendButton + text: qsTr("Send") + enabled: messageField.length > 0 + } + } + } + } +} + diff --git a/examples/quickcontrols/chattutorial/chapter3/chapter3.pro b/examples/quickcontrols/chattutorial/chapter3/chapter3.pro new file mode 100644 index 0000000000..42adc69fe9 --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter3/chapter3.pro @@ -0,0 +1,29 @@ +TEMPLATE = app + +QT += qml quick +CONFIG += c++11 + +SOURCES += main.cpp + +resources.files = \ + ContactPage.qml \ + ConversationPage.qml \ + images/Albert_Einstein.png \ + images/Albert_Einstein@2x.png \ + images/Albert_Einstein@3x.png \ + images/Albert_Einstein@4x.png \ + images/Ernest_Hemingway.png \ + images/Ernest_Hemingway@2x.png \ + images/Ernest_Hemingway@3x.png \ + images/Ernest_Hemingway@4x.png \ + images/Hans_Gude.png \ + images/Hans_Gude@2x.png \ + images/Hans_Gude@3x.png \ + images/Hans_Gude@4x.png \ + main.qml +resources.prefix = chapter3/ +RESOURCES += resources \ + qtquickcontrols2.conf + +target.path = $$[QT_INSTALL_EXAMPLES]/quickcontrols2/chattutorial/chapter3 +INSTALLS += target diff --git a/examples/quickcontrols/chattutorial/chapter3/images/Albert_Einstein.png b/examples/quickcontrols/chattutorial/chapter3/images/Albert_Einstein.png Binary files differnew file mode 100644 index 0000000000..7c44b90b8d --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter3/images/Albert_Einstein.png diff --git a/examples/quickcontrols/chattutorial/chapter3/images/Albert_Einstein@2x.png b/examples/quickcontrols/chattutorial/chapter3/images/Albert_Einstein@2x.png Binary files differnew file mode 100644 index 0000000000..6ce9c39b6c --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter3/images/Albert_Einstein@2x.png diff --git a/examples/quickcontrols/chattutorial/chapter3/images/Albert_Einstein@3x.png b/examples/quickcontrols/chattutorial/chapter3/images/Albert_Einstein@3x.png Binary files differnew file mode 100644 index 0000000000..aab6a6a162 --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter3/images/Albert_Einstein@3x.png diff --git a/examples/quickcontrols/chattutorial/chapter3/images/Albert_Einstein@4x.png b/examples/quickcontrols/chattutorial/chapter3/images/Albert_Einstein@4x.png Binary files differnew file mode 100644 index 0000000000..3611284df4 --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter3/images/Albert_Einstein@4x.png diff --git a/examples/quickcontrols/chattutorial/chapter3/images/Ernest_Hemingway.png b/examples/quickcontrols/chattutorial/chapter3/images/Ernest_Hemingway.png Binary files differnew file mode 100644 index 0000000000..3ac8992fd9 --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter3/images/Ernest_Hemingway.png diff --git a/examples/quickcontrols/chattutorial/chapter3/images/Ernest_Hemingway@2x.png b/examples/quickcontrols/chattutorial/chapter3/images/Ernest_Hemingway@2x.png Binary files differnew file mode 100644 index 0000000000..122d9f1e53 --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter3/images/Ernest_Hemingway@2x.png diff --git a/examples/quickcontrols/chattutorial/chapter3/images/Ernest_Hemingway@3x.png b/examples/quickcontrols/chattutorial/chapter3/images/Ernest_Hemingway@3x.png Binary files differnew file mode 100644 index 0000000000..2fe9c2cc1c --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter3/images/Ernest_Hemingway@3x.png diff --git a/examples/quickcontrols/chattutorial/chapter3/images/Ernest_Hemingway@4x.png b/examples/quickcontrols/chattutorial/chapter3/images/Ernest_Hemingway@4x.png Binary files differnew file mode 100644 index 0000000000..96fb6788b5 --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter3/images/Ernest_Hemingway@4x.png diff --git a/examples/quickcontrols/chattutorial/chapter3/images/Hans_Gude.png b/examples/quickcontrols/chattutorial/chapter3/images/Hans_Gude.png Binary files differnew file mode 100644 index 0000000000..907e38bc61 --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter3/images/Hans_Gude.png diff --git a/examples/quickcontrols/chattutorial/chapter3/images/Hans_Gude@2x.png b/examples/quickcontrols/chattutorial/chapter3/images/Hans_Gude@2x.png Binary files differnew file mode 100644 index 0000000000..6837796a83 --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter3/images/Hans_Gude@2x.png diff --git a/examples/quickcontrols/chattutorial/chapter3/images/Hans_Gude@3x.png b/examples/quickcontrols/chattutorial/chapter3/images/Hans_Gude@3x.png Binary files differnew file mode 100644 index 0000000000..29af422ad3 --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter3/images/Hans_Gude@3x.png diff --git a/examples/quickcontrols/chattutorial/chapter3/images/Hans_Gude@4x.png b/examples/quickcontrols/chattutorial/chapter3/images/Hans_Gude@4x.png Binary files differnew file mode 100644 index 0000000000..bc35eeaa79 --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter3/images/Hans_Gude@4x.png diff --git a/examples/quickcontrols/chattutorial/chapter3/images/images.qrc b/examples/quickcontrols/chattutorial/chapter3/images/images.qrc new file mode 100644 index 0000000000..9eda6aa29c --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter3/images/images.qrc @@ -0,0 +1,16 @@ +<RCC> + <qresource prefix="/"> + <file>Albert_Einstein.png</file> + <file>Albert_Einstein@2x.png</file> + <file>Albert_Einstein@3x.png</file> + <file>Albert_Einstein@4x.png</file> + <file>Ernest_Hemingway.png</file> + <file>Ernest_Hemingway@2x.png</file> + <file>Ernest_Hemingway@3x.png</file> + <file>Ernest_Hemingway@4x.png</file> + <file>Hans_Gude.png</file> + <file>Hans_Gude@2x.png</file> + <file>Hans_Gude@3x.png</file> + <file>Hans_Gude@4x.png</file> + </qresource> +</RCC> diff --git a/examples/quickcontrols/chattutorial/chapter3/main.cpp b/examples/quickcontrols/chattutorial/chapter3/main.cpp new file mode 100644 index 0000000000..4347d3ff6c --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter3/main.cpp @@ -0,0 +1,16 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#include <QGuiApplication> +#include <QQmlApplicationEngine> + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + engine.load(QUrl(QStringLiteral("qrc:/chapter3/main.qml"))); + + return app.exec(); +} + diff --git a/examples/quickcontrols/chattutorial/chapter3/main.qml b/examples/quickcontrols/chattutorial/chapter3/main.qml new file mode 100644 index 0000000000..da080e3a45 --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter3/main.qml @@ -0,0 +1,19 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + id: window + width: 540 + height: 960 + visible: true + + StackView { + id: stackView + anchors.fill: parent + initialItem: ContactPage {} + } +} + diff --git a/examples/quickcontrols/chattutorial/chapter3/qtquickcontrols2.conf b/examples/quickcontrols/chattutorial/chapter3/qtquickcontrols2.conf new file mode 100644 index 0000000000..db9486764e --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter3/qtquickcontrols2.conf @@ -0,0 +1,2 @@ +[Controls] +Style=Basic diff --git a/examples/quickcontrols/chattutorial/chapter4/CMakeLists.txt b/examples/quickcontrols/chattutorial/chapter4/CMakeLists.txt new file mode 100644 index 0000000000..024430a495 --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter4/CMakeLists.txt @@ -0,0 +1,65 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +cmake_minimum_required(VERSION 3.16) +project(chapter4 LANGUAGES CXX) + +set(CMAKE_AUTOMOC ON) + +if(NOT DEFINED INSTALL_EXAMPLESDIR) + set(INSTALL_EXAMPLESDIR "examples") +endif() + +set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/quickcontrols2/chattutorial/chapter4") + +find_package(Qt6 REQUIRED COMPONENTS Core Gui Qml Quick Sql) + +qt_add_executable(chattutorial-chapter4 WIN32 MACOSX_BUNDLE + main.cpp + sqlcontactmodel.cpp sqlcontactmodel.h + sqlconversationmodel.cpp sqlconversationmodel.h +) + +target_link_libraries(chattutorial-chapter4 PRIVATE + Qt::Core + Qt::Gui + Qt::Qml + Qt::Quick + Qt::Sql +) + +# Resources: +qt_add_qml_module(chattutorial-chapter4 + URI chapter4 + VERSION 1.0 + QML_FILES + "ContactPage.qml" + "ConversationPage.qml" + "main.qml" + RESOURCES + "images/Albert_Einstein.png" + "images/Albert_Einstein@2x.png" + "images/Albert_Einstein@3x.png" + "images/Albert_Einstein@4x.png" + "images/Ernest_Hemingway.png" + "images/Ernest_Hemingway@2x.png" + "images/Ernest_Hemingway@3x.png" + "images/Ernest_Hemingway@4x.png" + "images/Hans_Gude.png" + "images/Hans_Gude@2x.png" + "images/Hans_Gude@3x.png" + "images/Hans_Gude@4x.png" +) + +qt6_add_resources(chattutorial-chapter4 "conf" + PREFIX + "/" + FILES + "qtquickcontrols2.conf" +) + +install(TARGETS chattutorial-chapter4 + RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" + LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" +) diff --git a/examples/quickcontrols/chattutorial/chapter4/ContactPage.qml b/examples/quickcontrols/chattutorial/chapter4/ContactPage.qml new file mode 100644 index 0000000000..739d0b5402 --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter4/ContactPage.qml @@ -0,0 +1,43 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Controls + +import io.qt.examples.chattutorial + +Page { + id: root + + header: ToolBar { + Label { + text: qsTr("Contacts") + font.pixelSize: 20 + anchors.centerIn: parent + } + } + + ListView { + id: listView + anchors.fill: parent + topMargin: 48 + leftMargin: 48 + bottomMargin: 48 + rightMargin: 48 + spacing: 20 + model: SqlContactModel {} + delegate: ItemDelegate { + text: model.display + width: listView.width - listView.leftMargin - listView.rightMargin + height: avatar.implicitHeight + leftPadding: avatar.implicitWidth + 32 + onClicked: root.StackView.view.push("ConversationPage.qml", { inConversationWith: model.display }) + + Image { + id: avatar + source: "images/" + model.display.replace(" ", "_") + ".png" + } + } + } +} + diff --git a/examples/quickcontrols/chattutorial/chapter4/ConversationPage.qml b/examples/quickcontrols/chattutorial/chapter4/ConversationPage.qml new file mode 100644 index 0000000000..ef5b959aec --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter4/ConversationPage.qml @@ -0,0 +1,118 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls + +import io.qt.examples.chattutorial + +Page { + id: root + + property string inConversationWith + + header: ToolBar { + ToolButton { + text: qsTr("Back") + anchors.left: parent.left + anchors.leftMargin: 10 + anchors.verticalCenter: parent.verticalCenter + onClicked: root.StackView.view.pop() + } + + Label { + id: pageTitle + text: inConversationWith + font.pixelSize: 20 + anchors.centerIn: parent + } + } + + ColumnLayout { + anchors.fill: parent + + ListView { + id: listView + Layout.fillWidth: true + Layout.fillHeight: true + Layout.margins: pane.leftPadding + messageField.leftPadding + displayMarginBeginning: 40 + displayMarginEnd: 40 + verticalLayoutDirection: ListView.BottomToTop + spacing: 12 + model: SqlConversationModel { + recipient: inConversationWith + } + delegate: Column { + anchors.right: sentByMe ? listView.contentItem.right : undefined + spacing: 6 + + readonly property bool sentByMe: model.recipient !== "Me" + + Row { + id: messageRow + spacing: 6 + anchors.right: sentByMe ? parent.right : undefined + + Image { + id: avatar + source: !sentByMe ? "images/" + model.author.replace(" ", "_") + ".png" : "" + } + + Rectangle { + width: Math.min(messageText.implicitWidth + 24, + listView.width - (!sentByMe ? avatar.width + messageRow.spacing : 0)) + height: messageText.implicitHeight + 24 + color: sentByMe ? "lightgrey" : "steelblue" + + Label { + id: messageText + text: model.message + color: sentByMe ? "black" : "white" + anchors.fill: parent + anchors.margins: 12 + wrapMode: Label.Wrap + } + } + } + + Label { + id: timestampText + text: Qt.formatDateTime(model.timestamp, "d MMM hh:mm") + color: "lightgrey" + anchors.right: sentByMe ? parent.right : undefined + } + } + + ScrollBar.vertical: ScrollBar {} + } + + Pane { + id: pane + Layout.fillWidth: true + + RowLayout { + width: parent.width + + TextArea { + id: messageField + Layout.fillWidth: true + placeholderText: qsTr("Compose message") + wrapMode: TextArea.Wrap + } + + Button { + id: sendButton + text: qsTr("Send") + enabled: messageField.length > 0 + onClicked: { + listView.model.sendMessage(inConversationWith, messageField.text); + messageField.text = ""; + } + } + } + } + } +} + diff --git a/examples/quickcontrols/chattutorial/chapter4/chapter4.pro b/examples/quickcontrols/chattutorial/chapter4/chapter4.pro new file mode 100644 index 0000000000..ae8141f7f1 --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter4/chapter4.pro @@ -0,0 +1,34 @@ +TEMPLATE = app + +QT += qml quick sql +CONFIG += c++11 + +HEADERS += sqlcontactmodel.h \ + sqlconversationmodel.h + +SOURCES += main.cpp \ + sqlcontactmodel.cpp \ + sqlconversationmodel.cpp + +resources.files = \ + ContactPage.qml \ + ConversationPage.qml \ + images/Albert_Einstein.png \ + images/Albert_Einstein@2x.png \ + images/Albert_Einstein@3x.png \ + images/Albert_Einstein@4x.png \ + images/Ernest_Hemingway.png \ + images/Ernest_Hemingway@2x.png \ + images/Ernest_Hemingway@3x.png \ + images/Ernest_Hemingway@4x.png \ + images/Hans_Gude.png \ + images/Hans_Gude@2x.png \ + images/Hans_Gude@3x.png \ + images/Hans_Gude@4x.png \ + main.qml +resources.prefix = chapter4/ +RESOURCES += resources \ + qtquickcontrols2.conf + +target.path = $$[QT_INSTALL_EXAMPLES]/quickcontrols2/chattutorial/chapter4 +INSTALLS += target diff --git a/examples/quickcontrols/chattutorial/chapter4/images/Albert_Einstein.png b/examples/quickcontrols/chattutorial/chapter4/images/Albert_Einstein.png Binary files differnew file mode 100644 index 0000000000..7c44b90b8d --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter4/images/Albert_Einstein.png diff --git a/examples/quickcontrols/chattutorial/chapter4/images/Albert_Einstein@2x.png b/examples/quickcontrols/chattutorial/chapter4/images/Albert_Einstein@2x.png Binary files differnew file mode 100644 index 0000000000..6ce9c39b6c --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter4/images/Albert_Einstein@2x.png diff --git a/examples/quickcontrols/chattutorial/chapter4/images/Albert_Einstein@3x.png b/examples/quickcontrols/chattutorial/chapter4/images/Albert_Einstein@3x.png Binary files differnew file mode 100644 index 0000000000..aab6a6a162 --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter4/images/Albert_Einstein@3x.png diff --git a/examples/quickcontrols/chattutorial/chapter4/images/Albert_Einstein@4x.png b/examples/quickcontrols/chattutorial/chapter4/images/Albert_Einstein@4x.png Binary files differnew file mode 100644 index 0000000000..3611284df4 --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter4/images/Albert_Einstein@4x.png diff --git a/examples/quickcontrols/chattutorial/chapter4/images/Ernest_Hemingway.png b/examples/quickcontrols/chattutorial/chapter4/images/Ernest_Hemingway.png Binary files differnew file mode 100644 index 0000000000..3ac8992fd9 --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter4/images/Ernest_Hemingway.png diff --git a/examples/quickcontrols/chattutorial/chapter4/images/Ernest_Hemingway@2x.png b/examples/quickcontrols/chattutorial/chapter4/images/Ernest_Hemingway@2x.png Binary files differnew file mode 100644 index 0000000000..122d9f1e53 --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter4/images/Ernest_Hemingway@2x.png diff --git a/examples/quickcontrols/chattutorial/chapter4/images/Ernest_Hemingway@3x.png b/examples/quickcontrols/chattutorial/chapter4/images/Ernest_Hemingway@3x.png Binary files differnew file mode 100644 index 0000000000..2fe9c2cc1c --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter4/images/Ernest_Hemingway@3x.png diff --git a/examples/quickcontrols/chattutorial/chapter4/images/Ernest_Hemingway@4x.png b/examples/quickcontrols/chattutorial/chapter4/images/Ernest_Hemingway@4x.png Binary files differnew file mode 100644 index 0000000000..96fb6788b5 --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter4/images/Ernest_Hemingway@4x.png diff --git a/examples/quickcontrols/chattutorial/chapter4/images/Hans_Gude.png b/examples/quickcontrols/chattutorial/chapter4/images/Hans_Gude.png Binary files differnew file mode 100644 index 0000000000..907e38bc61 --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter4/images/Hans_Gude.png diff --git a/examples/quickcontrols/chattutorial/chapter4/images/Hans_Gude@2x.png b/examples/quickcontrols/chattutorial/chapter4/images/Hans_Gude@2x.png Binary files differnew file mode 100644 index 0000000000..6837796a83 --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter4/images/Hans_Gude@2x.png diff --git a/examples/quickcontrols/chattutorial/chapter4/images/Hans_Gude@3x.png b/examples/quickcontrols/chattutorial/chapter4/images/Hans_Gude@3x.png Binary files differnew file mode 100644 index 0000000000..29af422ad3 --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter4/images/Hans_Gude@3x.png diff --git a/examples/quickcontrols/chattutorial/chapter4/images/Hans_Gude@4x.png b/examples/quickcontrols/chattutorial/chapter4/images/Hans_Gude@4x.png Binary files differnew file mode 100644 index 0000000000..bc35eeaa79 --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter4/images/Hans_Gude@4x.png diff --git a/examples/quickcontrols/chattutorial/chapter4/images/images.qrc b/examples/quickcontrols/chattutorial/chapter4/images/images.qrc new file mode 100644 index 0000000000..9eda6aa29c --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter4/images/images.qrc @@ -0,0 +1,16 @@ +<RCC> + <qresource prefix="/"> + <file>Albert_Einstein.png</file> + <file>Albert_Einstein@2x.png</file> + <file>Albert_Einstein@3x.png</file> + <file>Albert_Einstein@4x.png</file> + <file>Ernest_Hemingway.png</file> + <file>Ernest_Hemingway@2x.png</file> + <file>Ernest_Hemingway@3x.png</file> + <file>Ernest_Hemingway@4x.png</file> + <file>Hans_Gude.png</file> + <file>Hans_Gude@2x.png</file> + <file>Hans_Gude@3x.png</file> + <file>Hans_Gude@4x.png</file> + </qresource> +</RCC> diff --git a/examples/quickcontrols/chattutorial/chapter4/main.cpp b/examples/quickcontrols/chattutorial/chapter4/main.cpp new file mode 100644 index 0000000000..0ca281c7d9 --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter4/main.cpp @@ -0,0 +1,52 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#include <QtCore> +#include <QGuiApplication> +#include <QSqlDatabase> +#include <QSqlError> +#include <QtQml> + +#include "sqlcontactmodel.h" +#include "sqlconversationmodel.h" + +static void connectToDatabase() +{ + QSqlDatabase database = QSqlDatabase::database(); + if (!database.isValid()) { + database = QSqlDatabase::addDatabase("QSQLITE"); + if (!database.isValid()) + qFatal("Cannot add database: %s", qPrintable(database.lastError().text())); + } + + const QDir writeDir = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation); + if (!writeDir.mkpath(".")) + qFatal("Failed to create writable directory at %s", qPrintable(writeDir.absolutePath())); + + // Ensure that we have a writable location on all devices. + const QString fileName = writeDir.absolutePath() + "/chat-database.sqlite3"; + // When using the SQLite driver, open() will create the SQLite database if it doesn't exist. + database.setDatabaseName(fileName); + if (!database.open()) { + qFatal("Cannot open database: %s", qPrintable(database.lastError().text())); + QFile::remove(fileName); + } +} + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + qmlRegisterType<SqlContactModel>("io.qt.examples.chattutorial", 1, 0, "SqlContactModel"); + qmlRegisterType<SqlConversationModel>("io.qt.examples.chattutorial", 1, 0, "SqlConversationModel"); + + connectToDatabase(); + + QQmlApplicationEngine engine; + engine.load(QUrl(QStringLiteral("qrc:/chapter4/main.qml"))); + if (engine.rootObjects().isEmpty()) + return -1; + + return app.exec(); +} + diff --git a/examples/quickcontrols/chattutorial/chapter4/main.qml b/examples/quickcontrols/chattutorial/chapter4/main.qml new file mode 100644 index 0000000000..da080e3a45 --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter4/main.qml @@ -0,0 +1,19 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + id: window + width: 540 + height: 960 + visible: true + + StackView { + id: stackView + anchors.fill: parent + initialItem: ContactPage {} + } +} + diff --git a/examples/quickcontrols/chattutorial/chapter4/qtquickcontrols2.conf b/examples/quickcontrols/chattutorial/chapter4/qtquickcontrols2.conf new file mode 100644 index 0000000000..db9486764e --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter4/qtquickcontrols2.conf @@ -0,0 +1,2 @@ +[Controls] +Style=Basic diff --git a/examples/quickcontrols/chattutorial/chapter4/sqlcontactmodel.cpp b/examples/quickcontrols/chattutorial/chapter4/sqlcontactmodel.cpp new file mode 100644 index 0000000000..0bccc0d7af --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter4/sqlcontactmodel.cpp @@ -0,0 +1,43 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#include "sqlcontactmodel.h" + +#include <QDebug> +#include <QSqlError> +#include <QSqlQuery> + +static void createTable() +{ + if (QSqlDatabase::database().tables().contains(QStringLiteral("Contacts"))) { + // The table already exists; we don't need to do anything. + return; + } + + QSqlQuery query; + if (!query.exec( + "CREATE TABLE IF NOT EXISTS 'Contacts' (" + " 'name' TEXT NOT NULL," + " PRIMARY KEY(name)" + ")")) { + qFatal("Failed to query database: %s", qPrintable(query.lastError().text())); + } + + query.exec("INSERT INTO Contacts VALUES('Albert Einstein')"); + query.exec("INSERT INTO Contacts VALUES('Ernest Hemingway')"); + query.exec("INSERT INTO Contacts VALUES('Hans Gude')"); +} + +SqlContactModel::SqlContactModel(QObject *parent) : + QSqlQueryModel(parent) +{ + createTable(); + + QSqlQuery query; + if (!query.exec("SELECT * FROM Contacts")) + qFatal("Contacts SELECT query failed: %s", qPrintable(query.lastError().text())); + + setQuery(query); + if (lastError().isValid()) + qFatal("Cannot set query on SqlContactModel: %s", qPrintable(lastError().text())); +} diff --git a/examples/quickcontrols/chattutorial/chapter4/sqlcontactmodel.h b/examples/quickcontrols/chattutorial/chapter4/sqlcontactmodel.h new file mode 100644 index 0000000000..a6d24a4774 --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter4/sqlcontactmodel.h @@ -0,0 +1,15 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#ifndef SQLCONTACTMODEL_H +#define SQLCONTACTMODEL_H + +#include <QSqlQueryModel> + +class SqlContactModel : public QSqlQueryModel +{ +public: + SqlContactModel(QObject *parent = nullptr); +}; + +#endif // SQLCONTACTMODEL_H diff --git a/examples/quickcontrols/chattutorial/chapter4/sqlconversationmodel.cpp b/examples/quickcontrols/chattutorial/chapter4/sqlconversationmodel.cpp new file mode 100644 index 0000000000..1a1594b094 --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter4/sqlconversationmodel.cpp @@ -0,0 +1,107 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#include "sqlconversationmodel.h" + +#include <QDateTime> +#include <QDebug> +#include <QSqlError> +#include <QSqlRecord> +#include <QSqlQuery> + +static const char *conversationsTableName = "Conversations"; + +static void createTable() +{ + if (QSqlDatabase::database().tables().contains(conversationsTableName)) { + // The table already exists; we don't need to do anything. + return; + } + + QSqlQuery query; + if (!query.exec( + "CREATE TABLE IF NOT EXISTS 'Conversations' (" + "'author' TEXT NOT NULL," + "'recipient' TEXT NOT NULL," + "'timestamp' TEXT NOT NULL," + "'message' TEXT NOT NULL," + "FOREIGN KEY('author') REFERENCES Contacts ( name )," + "FOREIGN KEY('recipient') REFERENCES Contacts ( name )" + ")")) { + qFatal("Failed to query database: %s", qPrintable(query.lastError().text())); + } + + query.exec("INSERT INTO Conversations VALUES('Me', 'Ernest Hemingway', '2016-01-07T14:36:06', 'Hello!')"); + query.exec("INSERT INTO Conversations VALUES('Ernest Hemingway', 'Me', '2016-01-07T14:36:16', 'Good afternoon.')"); + query.exec("INSERT INTO Conversations VALUES('Me', 'Albert Einstein', '2016-01-01T11:24:53', 'Hi!')"); + query.exec("INSERT INTO Conversations VALUES('Albert Einstein', 'Me', '2016-01-07T14:36:16', 'Good morning.')"); + query.exec("INSERT INTO Conversations VALUES('Hans Gude', 'Me', '2015-11-20T06:30:02', 'God morgen. Har du fått mitt maleri?')"); + query.exec("INSERT INTO Conversations VALUES('Me', 'Hans Gude', '2015-11-20T08:21:03', 'God morgen, Hans. Ja, det er veldig fint. Tusen takk! " + "Hvor mange timer har du brukt på den?')"); +} + +SqlConversationModel::SqlConversationModel(QObject *parent) : + QSqlTableModel(parent) +{ + createTable(); + setTable(conversationsTableName); + setSort(2, Qt::DescendingOrder); + // Ensures that the model is sorted correctly after submitting a new row. + setEditStrategy(QSqlTableModel::OnManualSubmit); +} + +QString SqlConversationModel::recipient() const +{ + return m_recipient; +} + +void SqlConversationModel::setRecipient(const QString &recipient) +{ + if (recipient == m_recipient) + return; + + m_recipient = recipient; + + const QString filterString = QString::fromLatin1( + "(recipient = '%1' AND author = 'Me') OR (recipient = 'Me' AND author='%1')").arg(m_recipient); + setFilter(filterString); + select(); + + emit recipientChanged(); +} + +QVariant SqlConversationModel::data(const QModelIndex &index, int role) const +{ + if (role < Qt::UserRole) + return QSqlTableModel::data(index, role); + + const QSqlRecord sqlRecord = record(index.row()); + return sqlRecord.value(role - Qt::UserRole); +} + +QHash<int, QByteArray> SqlConversationModel::roleNames() const +{ + QHash<int, QByteArray> names; + names[Qt::UserRole] = "author"; + names[Qt::UserRole + 1] = "recipient"; + names[Qt::UserRole + 2] = "timestamp"; + names[Qt::UserRole + 3] = "message"; + return names; +} + +void SqlConversationModel::sendMessage(const QString &recipient, const QString &message) +{ + const QString timestamp = QDateTime::currentDateTime().toString(Qt::ISODate); + + QSqlRecord newRecord = record(); + newRecord.setValue("author", "Me"); + newRecord.setValue("recipient", recipient); + newRecord.setValue("timestamp", timestamp); + newRecord.setValue("message", message); + if (!insertRecord(rowCount(), newRecord)) { + qWarning() << "Failed to send message:" << lastError().text(); + return; + } + + submitAll(); +} diff --git a/examples/quickcontrols/chattutorial/chapter4/sqlconversationmodel.h b/examples/quickcontrols/chattutorial/chapter4/sqlconversationmodel.h new file mode 100644 index 0000000000..8a3cdd4c43 --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter4/sqlconversationmodel.h @@ -0,0 +1,32 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#ifndef SQLCONVERSATIONMODEL_H +#define SQLCONVERSATIONMODEL_H + +#include <QSqlTableModel> + +class SqlConversationModel : public QSqlTableModel +{ + Q_OBJECT + Q_PROPERTY(QString recipient READ recipient WRITE setRecipient NOTIFY recipientChanged) + +public: + SqlConversationModel(QObject *parent = nullptr); + + QString recipient() const; + void setRecipient(const QString &recipient); + + QVariant data(const QModelIndex &index, int role) const override; + QHash<int, QByteArray> roleNames() const override; + + Q_INVOKABLE void sendMessage(const QString &recipient, const QString &message); + +signals: + void recipientChanged(); + +private: + QString m_recipient; +}; + +#endif // SQLCONVERSATIONMODEL_H diff --git a/examples/quickcontrols/chattutorial/chapter5/+Material/ChatToolBar.qml b/examples/quickcontrols/chattutorial/chapter5/+Material/ChatToolBar.qml new file mode 100644 index 0000000000..3fa10c7f13 --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter5/+Material/ChatToolBar.qml @@ -0,0 +1,9 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick.Controls +import QtQuick.Controls.Material + +ToolBar { + Material.theme: Material.Dark +} diff --git a/examples/quickcontrols/chattutorial/chapter5/CMakeLists.txt b/examples/quickcontrols/chattutorial/chapter5/CMakeLists.txt new file mode 100644 index 0000000000..657684fc34 --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter5/CMakeLists.txt @@ -0,0 +1,67 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +cmake_minimum_required(VERSION 3.16) +project(chapter5 LANGUAGES CXX) + +set(CMAKE_AUTOMOC ON) + +if(NOT DEFINED INSTALL_EXAMPLESDIR) + set(INSTALL_EXAMPLESDIR "examples") +endif() + +set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/quickcontrols2/chattutorial/chapter5") + +find_package(Qt6 REQUIRED COMPONENTS Core Gui Qml Quick Sql) + +qt_add_executable(chattutorial-chapter5 WIN32 MACOSX_BUNDLE + main.cpp + sqlcontactmodel.cpp sqlcontactmodel.h + sqlconversationmodel.cpp sqlconversationmodel.h +) + +target_link_libraries(chattutorial-chapter5 PRIVATE + Qt::Core + Qt::Gui + Qt::Qml + Qt::Quick + Qt::Sql +) + +# Resources: +qt_add_qml_module(chattutorial-chapter5 + URI chapter5 + VERSION 1.0 + QML_FILES + "+Material/ChatToolBar.qml" + "ChatToolBar.qml" + "ContactPage.qml" + "ConversationPage.qml" + "main.qml" + RESOURCES + "images/Albert_Einstein.png" + "images/Albert_Einstein@2x.png" + "images/Albert_Einstein@3x.png" + "images/Albert_Einstein@4x.png" + "images/Ernest_Hemingway.png" + "images/Ernest_Hemingway@2x.png" + "images/Ernest_Hemingway@3x.png" + "images/Ernest_Hemingway@4x.png" + "images/Hans_Gude.png" + "images/Hans_Gude@2x.png" + "images/Hans_Gude@3x.png" + "images/Hans_Gude@4x.png" +) + +qt6_add_resources(chattutorial-chapter5 "conf" + PREFIX + "/" + FILES + "qtquickcontrols2.conf" +) + +install(TARGETS chattutorial-chapter5 + RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" + LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" +) diff --git a/examples/quickcontrols/chattutorial/chapter5/ChatToolBar.qml b/examples/quickcontrols/chattutorial/chapter5/ChatToolBar.qml new file mode 100644 index 0000000000..73f2c655a9 --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter5/ChatToolBar.qml @@ -0,0 +1,7 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick.Controls + +ToolBar { +} diff --git a/examples/quickcontrols/chattutorial/chapter5/ContactPage.qml b/examples/quickcontrols/chattutorial/chapter5/ContactPage.qml new file mode 100644 index 0000000000..920c824090 --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter5/ContactPage.qml @@ -0,0 +1,43 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Controls + +import io.qt.examples.chattutorial + +Page { + id: root + + header: ChatToolBar { + Label { + text: qsTr("Contacts") + font.pixelSize: 20 + anchors.centerIn: parent + } + } + + ListView { + id: listView + anchors.fill: parent + topMargin: 48 + leftMargin: 48 + bottomMargin: 48 + rightMargin: 48 + spacing: 20 + model: SqlContactModel {} + delegate: ItemDelegate { + text: model.display + width: listView.width - listView.leftMargin - listView.rightMargin + height: avatar.implicitHeight + leftPadding: avatar.implicitWidth + 32 + onClicked: root.StackView.view.push("ConversationPage.qml", { inConversationWith: model.display }) + + Image { + id: avatar + source: "images/" + model.display.replace(" ", "_") + ".png" + } + } + } +} + diff --git a/examples/quickcontrols/chattutorial/chapter5/ConversationPage.qml b/examples/quickcontrols/chattutorial/chapter5/ConversationPage.qml new file mode 100644 index 0000000000..6e209b7a85 --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter5/ConversationPage.qml @@ -0,0 +1,117 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls + +import io.qt.examples.chattutorial + +Page { + id: root + + property string inConversationWith + + header: ChatToolBar { + ToolButton { + text: qsTr("Back") + anchors.left: parent.left + anchors.leftMargin: 10 + anchors.verticalCenter: parent.verticalCenter + onClicked: root.StackView.view.pop() + } + + Label { + id: pageTitle + text: inConversationWith + font.pixelSize: 20 + anchors.centerIn: parent + } + } + + ColumnLayout { + anchors.fill: parent + + ListView { + id: listView + Layout.fillWidth: true + Layout.fillHeight: true + Layout.margins: pane.leftPadding + messageField.leftPadding + displayMarginBeginning: 40 + displayMarginEnd: 40 + verticalLayoutDirection: ListView.BottomToTop + spacing: 12 + model: SqlConversationModel { + recipient: inConversationWith + } + delegate: Column { + anchors.right: sentByMe ? listView.contentItem.right : undefined + spacing: 6 + + readonly property bool sentByMe: model.recipient !== "Me" + + Row { + id: messageRow + spacing: 6 + anchors.right: sentByMe ? parent.right : undefined + + Image { + id: avatar + source: !sentByMe ? "images/" + model.author.replace(" ", "_") + ".png" : "" + } + + Rectangle { + width: Math.min(messageText.implicitWidth + 24, listView.width - avatar.width - messageRow.spacing) + height: messageText.implicitHeight + 24 + color: sentByMe ? "lightgrey" : "steelblue" + + Label { + id: messageText + text: model.message + color: sentByMe ? "black" : "white" + anchors.fill: parent + anchors.margins: 12 + wrapMode: Label.Wrap + } + } + } + + Label { + id: timestampText + text: Qt.formatDateTime(model.timestamp, "d MMM hh:mm") + color: "lightgrey" + anchors.right: sentByMe ? parent.right : undefined + } + } + + ScrollBar.vertical: ScrollBar {} + } + + Pane { + id: pane + Layout.fillWidth: true + + RowLayout { + width: parent.width + + TextArea { + id: messageField + Layout.fillWidth: true + placeholderText: qsTr("Compose message") + wrapMode: TextArea.Wrap + } + + Button { + id: sendButton + text: qsTr("Send") + enabled: messageField.length > 0 + onClicked: { + listView.model.sendMessage(inConversationWith, messageField.text); + messageField.text = ""; + } + } + } + } + } +} + diff --git a/examples/quickcontrols/chattutorial/chapter5/chapter5.pro b/examples/quickcontrols/chattutorial/chapter5/chapter5.pro new file mode 100644 index 0000000000..625642d7b5 --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter5/chapter5.pro @@ -0,0 +1,36 @@ +TEMPLATE = app + +QT += qml quick sql +CONFIG += c++11 + +HEADERS += sqlcontactmodel.h \ + sqlconversationmodel.h + +SOURCES += main.cpp \ + sqlcontactmodel.cpp \ + sqlconversationmodel.cpp + +resources.files = \ + +Material/ChatToolBar.qml \ + ChatToolBar.qml \ + ContactPage.qml \ + ConversationPage.qml \ + images/Albert_Einstein.png \ + images/Albert_Einstein@2x.png \ + images/Albert_Einstein@3x.png \ + images/Albert_Einstein@4x.png \ + images/Ernest_Hemingway.png \ + images/Ernest_Hemingway@2x.png \ + images/Ernest_Hemingway@3x.png \ + images/Ernest_Hemingway@4x.png \ + images/Hans_Gude.png \ + images/Hans_Gude@2x.png \ + images/Hans_Gude@3x.png \ + images/Hans_Gude@4x.png \ + main.qml +resources.prefix = chapter5/ +RESOURCES += resources \ + qtquickcontrols2.conf + +target.path = $$[QT_INSTALL_EXAMPLES]/quickcontrols2/chattutorial/chapter5 +INSTALLS += target diff --git a/examples/quickcontrols/chattutorial/chapter5/images/Albert_Einstein.png b/examples/quickcontrols/chattutorial/chapter5/images/Albert_Einstein.png Binary files differnew file mode 100644 index 0000000000..7c44b90b8d --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter5/images/Albert_Einstein.png diff --git a/examples/quickcontrols/chattutorial/chapter5/images/Albert_Einstein@2x.png b/examples/quickcontrols/chattutorial/chapter5/images/Albert_Einstein@2x.png Binary files differnew file mode 100644 index 0000000000..6ce9c39b6c --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter5/images/Albert_Einstein@2x.png diff --git a/examples/quickcontrols/chattutorial/chapter5/images/Albert_Einstein@3x.png b/examples/quickcontrols/chattutorial/chapter5/images/Albert_Einstein@3x.png Binary files differnew file mode 100644 index 0000000000..aab6a6a162 --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter5/images/Albert_Einstein@3x.png diff --git a/examples/quickcontrols/chattutorial/chapter5/images/Albert_Einstein@4x.png b/examples/quickcontrols/chattutorial/chapter5/images/Albert_Einstein@4x.png Binary files differnew file mode 100644 index 0000000000..3611284df4 --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter5/images/Albert_Einstein@4x.png diff --git a/examples/quickcontrols/chattutorial/chapter5/images/Ernest_Hemingway.png b/examples/quickcontrols/chattutorial/chapter5/images/Ernest_Hemingway.png Binary files differnew file mode 100644 index 0000000000..3ac8992fd9 --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter5/images/Ernest_Hemingway.png diff --git a/examples/quickcontrols/chattutorial/chapter5/images/Ernest_Hemingway@2x.png b/examples/quickcontrols/chattutorial/chapter5/images/Ernest_Hemingway@2x.png Binary files differnew file mode 100644 index 0000000000..122d9f1e53 --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter5/images/Ernest_Hemingway@2x.png diff --git a/examples/quickcontrols/chattutorial/chapter5/images/Ernest_Hemingway@3x.png b/examples/quickcontrols/chattutorial/chapter5/images/Ernest_Hemingway@3x.png Binary files differnew file mode 100644 index 0000000000..2fe9c2cc1c --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter5/images/Ernest_Hemingway@3x.png diff --git a/examples/quickcontrols/chattutorial/chapter5/images/Ernest_Hemingway@4x.png b/examples/quickcontrols/chattutorial/chapter5/images/Ernest_Hemingway@4x.png Binary files differnew file mode 100644 index 0000000000..96fb6788b5 --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter5/images/Ernest_Hemingway@4x.png diff --git a/examples/quickcontrols/chattutorial/chapter5/images/Hans_Gude.png b/examples/quickcontrols/chattutorial/chapter5/images/Hans_Gude.png Binary files differnew file mode 100644 index 0000000000..907e38bc61 --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter5/images/Hans_Gude.png diff --git a/examples/quickcontrols/chattutorial/chapter5/images/Hans_Gude@2x.png b/examples/quickcontrols/chattutorial/chapter5/images/Hans_Gude@2x.png Binary files differnew file mode 100644 index 0000000000..6837796a83 --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter5/images/Hans_Gude@2x.png diff --git a/examples/quickcontrols/chattutorial/chapter5/images/Hans_Gude@3x.png b/examples/quickcontrols/chattutorial/chapter5/images/Hans_Gude@3x.png Binary files differnew file mode 100644 index 0000000000..29af422ad3 --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter5/images/Hans_Gude@3x.png diff --git a/examples/quickcontrols/chattutorial/chapter5/images/Hans_Gude@4x.png b/examples/quickcontrols/chattutorial/chapter5/images/Hans_Gude@4x.png Binary files differnew file mode 100644 index 0000000000..bc35eeaa79 --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter5/images/Hans_Gude@4x.png diff --git a/examples/quickcontrols/chattutorial/chapter5/images/images.qrc b/examples/quickcontrols/chattutorial/chapter5/images/images.qrc new file mode 100644 index 0000000000..9eda6aa29c --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter5/images/images.qrc @@ -0,0 +1,16 @@ +<RCC> + <qresource prefix="/"> + <file>Albert_Einstein.png</file> + <file>Albert_Einstein@2x.png</file> + <file>Albert_Einstein@3x.png</file> + <file>Albert_Einstein@4x.png</file> + <file>Ernest_Hemingway.png</file> + <file>Ernest_Hemingway@2x.png</file> + <file>Ernest_Hemingway@3x.png</file> + <file>Ernest_Hemingway@4x.png</file> + <file>Hans_Gude.png</file> + <file>Hans_Gude@2x.png</file> + <file>Hans_Gude@3x.png</file> + <file>Hans_Gude@4x.png</file> + </qresource> +</RCC> diff --git a/examples/quickcontrols/chattutorial/chapter5/main.cpp b/examples/quickcontrols/chattutorial/chapter5/main.cpp new file mode 100644 index 0000000000..cfa5aa6f57 --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter5/main.cpp @@ -0,0 +1,52 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#include <QtCore> +#include <QGuiApplication> +#include <QSqlDatabase> +#include <QSqlError> +#include <QtQml> + +#include "sqlcontactmodel.h" +#include "sqlconversationmodel.h" + +static void connectToDatabase() +{ + QSqlDatabase database = QSqlDatabase::database(); + if (!database.isValid()) { + database = QSqlDatabase::addDatabase("QSQLITE"); + if (!database.isValid()) + qFatal("Cannot add database: %s", qPrintable(database.lastError().text())); + } + + const QDir writeDir = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation); + if (!writeDir.mkpath(".")) + qFatal("Failed to create writable directory at %s", qPrintable(writeDir.absolutePath())); + + // Ensure that we have a writable location on all devices. + const QString fileName = writeDir.absolutePath() + "/chat-database.sqlite3"; + // When using the SQLite driver, open() will create the SQLite database if it doesn't exist. + database.setDatabaseName(fileName); + if (!database.open()) { + qFatal("Cannot open database: %s", qPrintable(database.lastError().text())); + QFile::remove(fileName); + } +} + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + qmlRegisterType<SqlContactModel>("io.qt.examples.chattutorial", 1, 0, "SqlContactModel"); + qmlRegisterType<SqlConversationModel>("io.qt.examples.chattutorial", 1, 0, "SqlConversationModel"); + + connectToDatabase(); + + QQmlApplicationEngine engine; + engine.load(QUrl(QStringLiteral("qrc:/chapter5/main.qml"))); + if (engine.rootObjects().isEmpty()) + return -1; + + return app.exec(); +} + diff --git a/examples/quickcontrols/chattutorial/chapter5/main.qml b/examples/quickcontrols/chattutorial/chapter5/main.qml new file mode 100644 index 0000000000..da080e3a45 --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter5/main.qml @@ -0,0 +1,19 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + id: window + width: 540 + height: 960 + visible: true + + StackView { + id: stackView + anchors.fill: parent + initialItem: ContactPage {} + } +} + diff --git a/examples/quickcontrols/chattutorial/chapter5/qtquickcontrols2.conf b/examples/quickcontrols/chattutorial/chapter5/qtquickcontrols2.conf new file mode 100644 index 0000000000..c8a8eeeb05 --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter5/qtquickcontrols2.conf @@ -0,0 +1,10 @@ +[Controls] +Style=Basic + +[Material] +Primary=Indigo +Accent=Indigo +Theme=Dark + +[Universal] +Theme=Dark diff --git a/examples/quickcontrols/chattutorial/chapter5/sqlcontactmodel.cpp b/examples/quickcontrols/chattutorial/chapter5/sqlcontactmodel.cpp new file mode 100644 index 0000000000..0bccc0d7af --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter5/sqlcontactmodel.cpp @@ -0,0 +1,43 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#include "sqlcontactmodel.h" + +#include <QDebug> +#include <QSqlError> +#include <QSqlQuery> + +static void createTable() +{ + if (QSqlDatabase::database().tables().contains(QStringLiteral("Contacts"))) { + // The table already exists; we don't need to do anything. + return; + } + + QSqlQuery query; + if (!query.exec( + "CREATE TABLE IF NOT EXISTS 'Contacts' (" + " 'name' TEXT NOT NULL," + " PRIMARY KEY(name)" + ")")) { + qFatal("Failed to query database: %s", qPrintable(query.lastError().text())); + } + + query.exec("INSERT INTO Contacts VALUES('Albert Einstein')"); + query.exec("INSERT INTO Contacts VALUES('Ernest Hemingway')"); + query.exec("INSERT INTO Contacts VALUES('Hans Gude')"); +} + +SqlContactModel::SqlContactModel(QObject *parent) : + QSqlQueryModel(parent) +{ + createTable(); + + QSqlQuery query; + if (!query.exec("SELECT * FROM Contacts")) + qFatal("Contacts SELECT query failed: %s", qPrintable(query.lastError().text())); + + setQuery(query); + if (lastError().isValid()) + qFatal("Cannot set query on SqlContactModel: %s", qPrintable(lastError().text())); +} diff --git a/examples/quickcontrols/chattutorial/chapter5/sqlcontactmodel.h b/examples/quickcontrols/chattutorial/chapter5/sqlcontactmodel.h new file mode 100644 index 0000000000..a6d24a4774 --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter5/sqlcontactmodel.h @@ -0,0 +1,15 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#ifndef SQLCONTACTMODEL_H +#define SQLCONTACTMODEL_H + +#include <QSqlQueryModel> + +class SqlContactModel : public QSqlQueryModel +{ +public: + SqlContactModel(QObject *parent = nullptr); +}; + +#endif // SQLCONTACTMODEL_H diff --git a/examples/quickcontrols/chattutorial/chapter5/sqlconversationmodel.cpp b/examples/quickcontrols/chattutorial/chapter5/sqlconversationmodel.cpp new file mode 100644 index 0000000000..1a1594b094 --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter5/sqlconversationmodel.cpp @@ -0,0 +1,107 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#include "sqlconversationmodel.h" + +#include <QDateTime> +#include <QDebug> +#include <QSqlError> +#include <QSqlRecord> +#include <QSqlQuery> + +static const char *conversationsTableName = "Conversations"; + +static void createTable() +{ + if (QSqlDatabase::database().tables().contains(conversationsTableName)) { + // The table already exists; we don't need to do anything. + return; + } + + QSqlQuery query; + if (!query.exec( + "CREATE TABLE IF NOT EXISTS 'Conversations' (" + "'author' TEXT NOT NULL," + "'recipient' TEXT NOT NULL," + "'timestamp' TEXT NOT NULL," + "'message' TEXT NOT NULL," + "FOREIGN KEY('author') REFERENCES Contacts ( name )," + "FOREIGN KEY('recipient') REFERENCES Contacts ( name )" + ")")) { + qFatal("Failed to query database: %s", qPrintable(query.lastError().text())); + } + + query.exec("INSERT INTO Conversations VALUES('Me', 'Ernest Hemingway', '2016-01-07T14:36:06', 'Hello!')"); + query.exec("INSERT INTO Conversations VALUES('Ernest Hemingway', 'Me', '2016-01-07T14:36:16', 'Good afternoon.')"); + query.exec("INSERT INTO Conversations VALUES('Me', 'Albert Einstein', '2016-01-01T11:24:53', 'Hi!')"); + query.exec("INSERT INTO Conversations VALUES('Albert Einstein', 'Me', '2016-01-07T14:36:16', 'Good morning.')"); + query.exec("INSERT INTO Conversations VALUES('Hans Gude', 'Me', '2015-11-20T06:30:02', 'God morgen. Har du fått mitt maleri?')"); + query.exec("INSERT INTO Conversations VALUES('Me', 'Hans Gude', '2015-11-20T08:21:03', 'God morgen, Hans. Ja, det er veldig fint. Tusen takk! " + "Hvor mange timer har du brukt på den?')"); +} + +SqlConversationModel::SqlConversationModel(QObject *parent) : + QSqlTableModel(parent) +{ + createTable(); + setTable(conversationsTableName); + setSort(2, Qt::DescendingOrder); + // Ensures that the model is sorted correctly after submitting a new row. + setEditStrategy(QSqlTableModel::OnManualSubmit); +} + +QString SqlConversationModel::recipient() const +{ + return m_recipient; +} + +void SqlConversationModel::setRecipient(const QString &recipient) +{ + if (recipient == m_recipient) + return; + + m_recipient = recipient; + + const QString filterString = QString::fromLatin1( + "(recipient = '%1' AND author = 'Me') OR (recipient = 'Me' AND author='%1')").arg(m_recipient); + setFilter(filterString); + select(); + + emit recipientChanged(); +} + +QVariant SqlConversationModel::data(const QModelIndex &index, int role) const +{ + if (role < Qt::UserRole) + return QSqlTableModel::data(index, role); + + const QSqlRecord sqlRecord = record(index.row()); + return sqlRecord.value(role - Qt::UserRole); +} + +QHash<int, QByteArray> SqlConversationModel::roleNames() const +{ + QHash<int, QByteArray> names; + names[Qt::UserRole] = "author"; + names[Qt::UserRole + 1] = "recipient"; + names[Qt::UserRole + 2] = "timestamp"; + names[Qt::UserRole + 3] = "message"; + return names; +} + +void SqlConversationModel::sendMessage(const QString &recipient, const QString &message) +{ + const QString timestamp = QDateTime::currentDateTime().toString(Qt::ISODate); + + QSqlRecord newRecord = record(); + newRecord.setValue("author", "Me"); + newRecord.setValue("recipient", recipient); + newRecord.setValue("timestamp", timestamp); + newRecord.setValue("message", message); + if (!insertRecord(rowCount(), newRecord)) { + qWarning() << "Failed to send message:" << lastError().text(); + return; + } + + submitAll(); +} diff --git a/examples/quickcontrols/chattutorial/chapter5/sqlconversationmodel.h b/examples/quickcontrols/chattutorial/chapter5/sqlconversationmodel.h new file mode 100644 index 0000000000..8a3cdd4c43 --- /dev/null +++ b/examples/quickcontrols/chattutorial/chapter5/sqlconversationmodel.h @@ -0,0 +1,32 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#ifndef SQLCONVERSATIONMODEL_H +#define SQLCONVERSATIONMODEL_H + +#include <QSqlTableModel> + +class SqlConversationModel : public QSqlTableModel +{ + Q_OBJECT + Q_PROPERTY(QString recipient READ recipient WRITE setRecipient NOTIFY recipientChanged) + +public: + SqlConversationModel(QObject *parent = nullptr); + + QString recipient() const; + void setRecipient(const QString &recipient); + + QVariant data(const QModelIndex &index, int role) const override; + QHash<int, QByteArray> roleNames() const override; + + Q_INVOKABLE void sendMessage(const QString &recipient, const QString &message); + +signals: + void recipientChanged(); + +private: + QString m_recipient; +}; + +#endif // SQLCONVERSATIONMODEL_H diff --git a/examples/quickcontrols/chattutorial/chattutorial.pro b/examples/quickcontrols/chattutorial/chattutorial.pro new file mode 100644 index 0000000000..1c70b2653e --- /dev/null +++ b/examples/quickcontrols/chattutorial/chattutorial.pro @@ -0,0 +1,8 @@ +TEMPLATE = subdirs + +SUBDIRS += \ + chapter1 \ + chapter2 \ + chapter3 \ + chapter4 \ + chapter5 diff --git a/examples/quickcontrols/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter1.png b/examples/quickcontrols/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter1.png Binary files differnew file mode 100644 index 0000000000..aa3c4bb5be --- /dev/null +++ b/examples/quickcontrols/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter1.png diff --git a/examples/quickcontrols/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter2-listview-header.gif b/examples/quickcontrols/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter2-listview-header.gif Binary files differnew file mode 100644 index 0000000000..17096519b0 --- /dev/null +++ b/examples/quickcontrols/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter2-listview-header.gif diff --git a/examples/quickcontrols/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter2.png b/examples/quickcontrols/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter2.png Binary files differnew file mode 100644 index 0000000000..af25cff94e --- /dev/null +++ b/examples/quickcontrols/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter2.png diff --git a/examples/quickcontrols/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter3-listview-header.gif b/examples/quickcontrols/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter3-listview-header.gif Binary files differnew file mode 100644 index 0000000000..07eb93b191 --- /dev/null +++ b/examples/quickcontrols/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter3-listview-header.gif diff --git a/examples/quickcontrols/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter3-view-margins.png b/examples/quickcontrols/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter3-view-margins.png Binary files differnew file mode 100644 index 0000000000..1c8ffbf46e --- /dev/null +++ b/examples/quickcontrols/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter3-view-margins.png diff --git a/examples/quickcontrols/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter3.gif b/examples/quickcontrols/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter3.gif Binary files differnew file mode 100644 index 0000000000..1763b1f3a5 --- /dev/null +++ b/examples/quickcontrols/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter3.gif diff --git a/examples/quickcontrols/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter4-long-message.png b/examples/quickcontrols/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter4-long-message.png Binary files differnew file mode 100644 index 0000000000..b2f4c2adf8 --- /dev/null +++ b/examples/quickcontrols/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter4-long-message.png diff --git a/examples/quickcontrols/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter4-message-timestamp.png b/examples/quickcontrols/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter4-message-timestamp.png Binary files differnew file mode 100644 index 0000000000..ea75b1dce5 --- /dev/null +++ b/examples/quickcontrols/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter4-message-timestamp.png diff --git a/examples/quickcontrols/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter4.gif b/examples/quickcontrols/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter4.gif Binary files differnew file mode 100644 index 0000000000..dd47c4cbf8 --- /dev/null +++ b/examples/quickcontrols/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter4.gif diff --git a/examples/quickcontrols/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter5-contacts-material-dark.png b/examples/quickcontrols/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter5-contacts-material-dark.png Binary files differnew file mode 100644 index 0000000000..8b8f05faa1 --- /dev/null +++ b/examples/quickcontrols/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter5-contacts-material-dark.png diff --git a/examples/quickcontrols/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter5-contacts-material-test.png b/examples/quickcontrols/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter5-contacts-material-test.png Binary files differnew file mode 100644 index 0000000000..29e149df9f --- /dev/null +++ b/examples/quickcontrols/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter5-contacts-material-test.png diff --git a/examples/quickcontrols/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter5-contacts-material.png b/examples/quickcontrols/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter5-contacts-material.png Binary files differnew file mode 100644 index 0000000000..23d744e7be --- /dev/null +++ b/examples/quickcontrols/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter5-contacts-material.png diff --git a/examples/quickcontrols/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter5-contacts-universal-dark.png b/examples/quickcontrols/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter5-contacts-universal-dark.png Binary files differnew file mode 100644 index 0000000000..2aef535c39 --- /dev/null +++ b/examples/quickcontrols/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter5-contacts-universal-dark.png diff --git a/examples/quickcontrols/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter5-contacts-universal.png b/examples/quickcontrols/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter5-contacts-universal.png Binary files differnew file mode 100644 index 0000000000..c18a341b42 --- /dev/null +++ b/examples/quickcontrols/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter5-contacts-universal.png diff --git a/examples/quickcontrols/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter5-conversations-material-dark.png b/examples/quickcontrols/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter5-conversations-material-dark.png Binary files differnew file mode 100644 index 0000000000..f15c7d7d76 --- /dev/null +++ b/examples/quickcontrols/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter5-conversations-material-dark.png diff --git a/examples/quickcontrols/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter5-conversations-material-test.png b/examples/quickcontrols/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter5-conversations-material-test.png Binary files differnew file mode 100644 index 0000000000..b33fc74ea6 --- /dev/null +++ b/examples/quickcontrols/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter5-conversations-material-test.png diff --git a/examples/quickcontrols/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter5-conversations-material.png b/examples/quickcontrols/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter5-conversations-material.png Binary files differnew file mode 100644 index 0000000000..31833164d8 --- /dev/null +++ b/examples/quickcontrols/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter5-conversations-material.png diff --git a/examples/quickcontrols/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter5-conversations-universal-dark.png b/examples/quickcontrols/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter5-conversations-universal-dark.png Binary files differnew file mode 100644 index 0000000000..b4bd7e9f4f --- /dev/null +++ b/examples/quickcontrols/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter5-conversations-universal-dark.png diff --git a/examples/quickcontrols/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter5-conversations-universal.png b/examples/quickcontrols/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter5-conversations-universal.png Binary files differnew file mode 100644 index 0000000000..09ed5ceb94 --- /dev/null +++ b/examples/quickcontrols/chattutorial/doc/images/qtquickcontrols2-chattutorial-chapter5-conversations-universal.png diff --git a/examples/quickcontrols/chattutorial/doc/src/qtquickcontrols2-chattutorial.qdoc b/examples/quickcontrols/chattutorial/doc/src/qtquickcontrols2-chattutorial.qdoc new file mode 100644 index 0000000000..52228b900d --- /dev/null +++ b/examples/quickcontrols/chattutorial/doc/src/qtquickcontrols2-chattutorial.qdoc @@ -0,0 +1,874 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only + +/*! +\example chattutorial +\keyword Qt Quick Controls - Chat Tutorial +\title Qt Quick Controls - Chat Tutorial +\keyword Qt Quick Controls 2 - Chat Tutorial +\brief Tutorial about writing a basic chat client using Qt Quick Controls. +\ingroup qtquickcontrols2-examples + +This tutorial shows how to write a basic chat application using Qt Quick +Controls. It will also explain how to integrate an SQL database into a Qt +application. + +\section1 Chapter 1: Setting Up + +When setting up a new project, it's easiest to use +\l {Qt Creator Manual}{Qt Creator}. For this project, we chose the +\l {Qt Creator: Creating Qt Quick Projects}{Qt Quick application} template, which creates a +basic "Hello World" application with the following files: + +\list +\li \c MainForm.ui.qml - Defines the default UI +\li \c main.qml - Embeds the default UI in a Window +\li \c qml.qrc - Lists the \c .qml files that are built into the binary +\li \c main.cpp - Loads \c main.qml +\li \c chattutorial.pro - Provides the qmake configuration +\endlist + +\note Delete the \c MainForm.ui.qml and \c qml.qrc files from the project, as +we will not use them in this tutorial. + +\section2 main.cpp + +The default code in \c main.cpp has two includes: + +\quotefromfile chattutorial/chapter1/main.cpp +\skipto include +\printline include +\printline include + +The first gives us access to QGuiApplication. All Qt applications require +an application object, but the precise type depends on what the application +does. QCoreApplication is sufficient for non-graphical applications. +QGuiApplication is sufficient for graphical applications that do not use +\l {Qt Widgets}, while QApplication is required for those that do. + +The second include makes QQmlApplicationEngine available, along with +some useful functions required for making C++ types accessible from QML. + +Within \c main(), we set up the application object and QML engine: + +\skipto main +\printuntil } + +It begins with enabling \l {High DPI}{high DPI scaling}, which is not +part of the default code. It is necessary to do so before the application +object is constructed. + +After that's done, we construct the application object, passing any application +arguments provided by the user. + +Next, the QML engine is created. \l QQmlApplicationEngine is a convenient +wrapper over QQmlEngine, providing the \l {QQmlApplicationEngine::load}{load()} +function to easily load QML for an application. It also adds some convenience +for using \l {Using File Selectors with Qt Quick Controls}{file selectors}. + +Once we've set up things in C++, we can move on to the user interface in QML. + +\section2 main.qml + +Let's modify the default QML code to suit our needs. + +\quotefromfile chattutorial/chapter1/main.qml +\skipto import +\printuntil import QtQuick.Controls + +First, import the \l {Qt Quick} module. This gives us +access to graphical primitives such as \l Item, \l Rectangle, \l Text, and so +on. +For the full list of types, see the \l {Qt Quick QML Types} documentation. + +Next, import the Qt Quick Controls module. Amongst other things, this +provides access to \l ApplicationWindow, which will replace the existing +root type, \c Window: + +\skipto ApplicationWindow +\printuntil visible: true +\dots +\skipto } +\skipuntil } +\printuntil } + +ApplicationWindow is a \l Window with some added convenience for creating a +\l {ApplicationWindow::}{header} and a \l {ApplicationWindow::}{footer}. +It also provides the foundation for \l {Popup}{popups} and supports some +basic styling, such as the background \l {Window::}{color}. + +There are three properties that are almost always set when using +ApplicationWindow: \l {Window::}{width}, \l {Window::}{height}, and +\l {Window::}{visible}. +Once we've set these, we have a properly sized, empty window ready to be +filled with content. + +\note The \c title property from the default code is removed. + +The first \e "screen" in our application will be a list of contacts. It would +be nice to have some text at the top of each screen that describes its purpose. +The header and footer properties of ApplicationWindow could work in +this situation. They have some characteristics that make them ideal for +items that should be displayed on every screen of an application: + +\list +\li They are anchored to the top and bottom of the window, respectively. +\li They fill the width of the window. +\endlist + +However, when the contents of the header and footer varies depending on +which screen the user is viewing, it is much easier to use \l Page. +For now, we'll just add one page, but in the next chapter, we'll demonstrate +how to navigate between several pages. + +\quotefromfile chattutorial/chapter1/main.qml +\skipto Page +\printuntil } +\printuntil } + +We replace the default \c{MainForm {...}} code block with a Page, which is +sized to occupy all the space on the window using the \l {Item::}{anchors.fill} +property. + +Then, we assign a \l Label to its \l {Page::}{header} property. Label extends +the primitive \l Text item from the Qt Quick module by adding +\l{Styling Qt Quick Controls}{styling} and \l {Control::}{font} inheritance. +This means that a Label can look different depending on which style is in use, +and can also propagate its pixel size to its children. + +We want some distance between the top of the application window and the text, +so we set the \l {Text::padding}{padding} property. This allocates extra +space on each side of the label (within its bounds). We can also explicitly set +the \l {Text::}{topPadding} and \l {Text::}{bottomPadding} properties instead. + +We set the text of the label using the \c qsTr() function, which ensures that +the text can be translated by \l {Writing Source Code for Translation}{Qt's +translation system}. It's a good practice to follow for text that is visible to +the end users of your application. + +By default, text is vertically aligned to the top of its bounds, while the +horizontal alignment depends on the natural direction of the text; for example, +text that is read from left to right will be aligned to the left. If we +used these defaults, our text would be at the top-left corner of the window. +This is not desirable for a header, so we align the text to the center of its +bounds, both horizontally and vertically. + +\section2 The Project File + +The \c .pro or \l {Creating Project Files}{project} file contains all of the +information needed by \l {qmake Manual}{qmake} to generate a Makefile, which is +then used to compile and link the application. + +\quotefromfile chattutorial/chapter1/chapter1.pro +\printline TEMPLATE + +The first line tells \c qmake which kind of project this is. We're building an +application, so we use the \c app template. + +\printline QT + +The next line declares the Qt libraries that we want to use from C++. + +\printline CONFIG + +This line states that a C++11 compatible compiler is required to build the +project. + +\printline SOURCES + +The \c SOURCES variable lists all of the source files that should be compiled. +A similar variable, \c HEADERS, is available for header files. + +\printuntil qtquickcontrols2 + +The next line tells \c qmake that we have a collection of +\l {The Qt Resource System}{resources} that should be built into the +executable. + +\skipto target +\printline + +This line replaces deployment settings that come with the default project file. +It determines where the example is copied, on running "\c{make install}". + +Now we can build and run the application: + +\borderedimage qtquickcontrols2-chattutorial-chapter1.png + +\noautolist +\generatelist examplefiles .*chapter1.* + +\section1 Chapter 2: Lists + +In this chapter, we'll explain how to create a list of interactive items using +\l ListView and \l ItemDelegate. + +ListView comes from the Qt Quick module, and displays a list of items +populated from a \l {Models and Views in Qt Quick}{model}. ItemDelegate comes from +the Qt Quick Controls module, and provides a standard view item for use in views +and controls such as ListView and \l ComboBox. For example, each ItemDelegate +can display text, be checked on and off, and react to mouse clicks. + +Here is our ListView: + +\quotefromfile chattutorial/chapter2/main.qml +\dots 8 +\codeline +\skipto ListView +\printuntil } +\printuntil } +\printuntil } +\codeline +\dots 8 + +\section2 Sizing and Positioning + +The first thing we do is set a size for the view. It should fill the available +space on the page, so we use \l {Item::}{anchors.fill}. Note that +Page ensures that its header and footer have enough of their own space +reserved, so the view in this case will sit below the header, for example. + +Next, we set \l {Flickable::leftMargin}{margins} around the ListView to put +some distance between it and the edges of the window. The margin properties +reserve space within the bounds of the view, which means that the empty areas +can still be \e "flicked" by the user. + +The items should be nicely spaced out within the view, so the +\l {ListView::}{spacing} property is set to \c 20. + +\section2 Model + +In order to quickly populate the view with some items, we've used a JavaScript +array as the model. One of the greatest strengths of QML is its ability to +make prototyping an application extremely quick, and this is an example of +that. It's also possible to simply assign a \l {Integers as Models}{number} to +the model property to indicate how many items you need. For example, if you +assign \c 10 to the \c model property, each item's display text will be a +number from \c 0 to \c 9. + +However, once the application gets past the prototype stage, it quickly becomes +necessary to use some real data. For this, it's best to use a proper C++ model +by \l {QAbstractItemModel}{subclassing QAbstractItemModel}. + +\section2 Delegate + +On to the \l {ListView::}{delegate}. We assign the corresponding text from the +model to the \l {AbstractButton::text}{text} property of ItemDelegate. The exact +manner in which the data from the model is made available to each delegate +depends on the type of model used. See \l {Models and Views in Qt Quick} for +more information. + +In our application, the width of each item in the view should be the same +as the width of the view. This ensures that the user has a lot of room with +which to select a contact from the list, which is an important factor on +devices with small touch screens, like mobile phones. However, the width of the +view includes our \c 48 pixel margins, so we must account for that in our +assignment to the width property. + +Next, we define an \l Image. This will display a picture of the user's contact. +The image will be \c 40 pixels wide and \c 40 pixels high. We'll base the +height of the delegate on the image's height, so that we don't have any empty +vertical space. + +\borderedimage qtquickcontrols2-chattutorial-chapter2.png + +\generatelist examplefiles .*(chapter2|shared).* +\generatelist exampleimages .*shared.*(Einstein|Hemingway|Gude)\.png + +\section1 Chapter 3: Navigation + +In this chapter, you'll learn how to use \l StackView to navigate between pages +in an application. Here's the revised \c main.qml: + +\quotefromfile chattutorial/chapter3/main.qml +\skipto import +\printuntil } +\printuntil } +\printuntil } + +\section2 Navigating with StackView + +As its name suggests, StackView provides stack-based navigation. The last item +to be \e "pushed" onto the stack is the first one to be removed, and the +top-most item is always the one that is visible. + +In the same manner as we did with Page, we tell the StackView to fill the +application window. The only thing left to do after that is to give it an item +to display, via \l {StackView::}{initialItem}. StackView accepts +\l {Item}{items}, \l {Component}{components} and \l [QML]{url}{URLs}. + +You'll notice that we moved the code for the contact list into +\c ContactPage.qml. It's a good idea to do this as soon as you have a general +idea of which screens your application will contain. Doing so not only makes +your code easier to read, but ensures that items are only instantiated from +a given component when completely necessary, reducing memory usage. + +\note Qt Creator provides several convenient \l {http://doc.qt.io/qtcreator/creator-editor-refactoring.html#refactoring-qml-code}{refactoring options for QML}, +one of which allows you to move a block of code into a separate file + (\c {Alt + Enter > Move Component into Separate File}). + +Another thing to consider when using ListView is whether to refer to it by +\c id, or use the attached \l {ListView::view}{ListView.view} +property. The best approach depends on a few different factors. Giving the +view an id will result in shorter and more efficient binding expressions, as +the attached property has a very small amount of overhead. However, if you plan +on reusing the delegate in other views, it is better to use the attached +properties to avoid tying the delegate to a particular view. For example, using +the attached properties, the \c width assignment in our delegate becomes: + +\code +width: ListView.view.width - ListView.view.leftMargin - ListView.view.rightMargin +\endcode + +In chapter 2, we added a ListView below the header. If you run the application +for that chapter, you'll see that the contents of the view can be scrolled over +the top of the header: + +\borderedimage qtquickcontrols2-chattutorial-chapter2-listview-header.gif + +This is not that nice, especially if the text in the +delegates is long enough that it reaches the text in the header. What we +ideally want to do is to have a solid block of color under the header text, but +\e {above} the view. This ensures that the listview contents can't visually +interfere with the header contents. Note that it's also possible to achieve +this by setting the \l {Item::}{clip} property of the view to \c true, but +doing so \l {Clipping}{can affect performance}. + +\l ToolBar is the right tool for this job. It is a container of both +application-wide and context-sensitive actions and controls, such as navigation +buttons and search fields. Best of all, it has a background color that, as +usual, comes from the application style. Here it is in action: + +\quotefromfile chattutorial/chapter3/ContactPage.qml +\skipto header +\printuntil } +\printuntil } + +\borderedimage qtquickcontrols2-chattutorial-chapter3-listview-header.gif + +It has no layout of its own, so we center the label within it ourselves. + +The rest of the code is the same as it was in chapter 2, except that we've +taken advantage of the \l {AbstractButton::}{clicked} signal to push the next +page onto the stackview: + +\skipto onClicked +\printline onClicked + +When pushing a \l Component or \l [QML] url onto StackView, it's often +necessary to initialize the (eventually) instantiated item with some variables. +StackView's \l {StackView::push}{push()} function accounts for this, by taking a JavaScript object +as the second argument. We use this to provide the next page with a contact's +name, which it then uses to display the relevant conversation. Note the +\c {root.StackView.view.push} syntax; this is necessary because of how +\l {A Note About Accessing Attached Properties and Signal Handlers} +{attached properties} work. + +Let's step through \c ConversationPage.qml, beginning with the imports: + +\quotefromfile chattutorial/chapter3/ConversationPage.qml +\skipto import +\printline import +\printline import +\printline import + +These are the same as before, except for the addition of the \c QtQuick.Layouts +import, which we'll cover shortly. + +\skipto Page +\printuntil } +\printuntil } +\printuntil } +\dots 4 + +The root item of this component is another Page, which has a custom property +called \c inConversationWith. For now, this property will simply determine what +the label in the header displays. Later on, we'll use it in the SQL query that +populates the list of messages in the conversation. + +To allow the user to go back to the Contact page, we add a \l ToolButton that +calls \l {StackView::pop}{pop()} when clicked. A \l ToolButton is functionally +similar to \l Button, but provides a look that is more suitable within a +ToolBar. + +There are two ways of laying out items in QML: \l {Item Positioners} +and \l {Qt Quick Layouts}. Item positioners (\l Row, \l Column, and so on) are +useful for situations where the size of items is known or fixed, and all that +is required is to neatly position them in a certain formation. The layouts in +Qt Quick Layouts can both position and resize items, making them well suited +for resizable user interfaces. Below, we use \l ColumnLayout to vertically +lay out a ListView and a \l Pane: + +\skipto ColumnLayout +\printto Layout.margins +\codeline +\dots 12 +\codeline +\skipuntil ScrollBar +\printline } +\codeline +\dots 8 +\codeline +\printuntil Layout.fillWidth: true +\dots 12 +\skipuntil } +\skipuntil } +\skipuntil } +\skipuntil } +\printline } + +Pane is basically a rectangle whose color comes from the application's style. +It is similar to \l Frame, with the only difference being that it has no stroke +around its border. + +Items that are direct children of a layout have various +\l {Layout}{attached properties} available to them. We use +\l {Layout::fillWidth}{Layout.fillWidth} and +\l {Layout::fillHeight}{Layout.fillHeight} on the ListView to ensure +that it takes as much space within the ColumnLayout as it can. The +same is done for the Pane. As ColumnLayout is a vertical layout, there +aren't any items to the left or right of each child, so this will result in +each item consuming the entire width of the layout. + +On the other hand, the \l {Layout::fillHeight}{Layout.fillHeight} statement in +the ListView will enable it to occupy the remaining space that is left after +accommodating the Pane. + +Let's look at the listview in detail: + +\quotefromfile chattutorial/chapter3/ConversationPage.qml +\skipto ListView +\printuntil ScrollBar +\printuntil } + +After filling the width and height of its parent, we also set some margins on +the view. This gives us a nice alignment with the placeholder text in the +"compose message" field: + +\borderedimage qtquickcontrols2-chattutorial-chapter3-view-margins.png + +Next, we set \l {ListView::}{displayMarginBeginning} and \l +{ListView::}{displayMarginEnd}. These properties ensure that the delegates +outside the bounds of the view do not disappear while scrolling at the edges of +the view. It's easiest to understand this by commenting out the properties and +seeing what happens when scrolling the view. + +We then flip the vertical direction of the view, so that first items are at the +bottom. The delegates are spaced out by 12 pixels, and a \e "dummy" model is +assigned for testing purposes, until we implement the real model in chapter 4. + +Within the delegate, we declare a \l Row as the root item, as we want the +avatar to be followed by the message contents, as shown in the image above. + +Messages sent by the user should be distinguished from those sent by a contact. +For now, we set a dummy property \c sentByMe, which simply uses the index +of the delegate to alternate between different authors. Using this property, +we distinguish between different authors in three ways: + +\list +\li Messages sent by the user are aligned to the right side of the screen +by setting \c anchors.right to \c listView.contentItem.right. + +\li By setting the \c visible property of the avatar (which is simply a +Rectangle for now) based on \c sentByMe, we only show it if the message was +sent by a contact. + +\li We change the color of the rectangle depending on the author. Since we +do not want to display dark text on a dark background, and vice versa, we also +set the text color depending on who the author is. In chapter 5, we'll see how +styling takes care of matters like this for us. +\endlist + +At the bottom of the screen, we place a \l TextArea item to allow multi-line +text input, and a button to send the message. We use Pane to cover the area +under these two items, in the same way that we use ToolBar to prevent the +contents of the listview from interfering with the page header: + +\skipto Pane +\printuntil } +\printuntil } +\printuntil } +\printuntil } + +The TextArea should fill the available width of the screen. We assign some +placeholder text to provide a visual cue to the user as to where they should +begin typing. The text within the input area is wrapped to ensure that it +does not go outside of the screen. + +Finally, the button is only enabled when there is actually a message to send. + +\borderedimage qtquickcontrols2-chattutorial-chapter3.gif + +\generatelist examplefiles .*(chapter3|shared).* +\generatelist exampleimages .*shared.*(Einstein|Hemingway|Gude)\.png + +\section1 Chapter 4: Models + +In chapter 4, we'll take you through the process of creating both read-only and +read-write SQL models in C++ and exposing them to QML to populate views. + +\section2 QSqlQueryModel + +In order to keep the tutorial simple, we've chosen to make the list of user +contacts non-editable. \l QSqlQueryModel is the logical choice for this +purpose, as it provides a read-only data model for SQL result sets. + +Let's take a look at our \c SqlContactModel class that derives from +QSqlQueryModel: + +\quotefromfile chattutorial/chapter4/sqlcontactmodel.h +\skipto #include +\printuntil }; + +There's not much going on here, so let's move on to the \c .cpp file: + +\quotefromfile chattutorial/chapter4/sqlcontactmodel.cpp +\skipto #include +\printuntil } +\printuntil } +\printuntil } + +We include the header file of our class and those that we require from Qt. We +then define a static function named \c createTable() that we'll use to create +the SQL table (if it doesn't already exist), and then populate it with some +dummy contacts. + +The call to \l {QSqlDatabase::database}{database()} might look a little bit +confusing because we have not set up a specific database yet. If no connection +name is passed to this function, it will return a \e {"default connection"}, +whose creation we will cover soon. + +\skipto SqlContactModel +\printuntil } + +In the constructor, we call \c createTable(). We then construct a query that +will be used to populate the model. In this case, we are simply interested in +all rows of the \c Contacts table. + +\section2 QSqlTableModel + +\c SqlConversationModel is more complex: + +\quotefromfile chattutorial/chapter4/sqlconversationmodel.h +\skipto #include +\printuntil }; + +We use both the \c Q_PROPERTY and \c Q_INVOKABLE macros, and therefore we must +let \l {Using the Meta-Object Compiler (moc)}{moc} know by using the \c +Q_OBJECT macro. + +The \c recipient property will be set from QML to let the model know which +conversation it should retrieve messages for. + +We override the \l {QSqlTableModel::data}{data()} and +\l {QAbstractItemModel::}{roleNames()} functions so that we can use our +custom roles in QML. + +We also define the \c sendMessage() function that we want to call from +QML, hence the \c Q_INVOKABLE macro. + +Let's take a look at the \c .cpp file: + +\quotefromfile chattutorial/chapter4/sqlconversationmodel.cpp +\skipto #include +\printuntil } +\printuntil } +\printuntil } + +This is very similar to \c sqlcontactmodel.cpp, with the exception that we are +now operating on the \c Conversations table. We also define +\c conversationsTableName as a static const variable, as we use it in a couple +of places throughout the file. + +\skipto SqlConversationModel +\printuntil } + +As with \c SqlContactModel, the first thing that we do in the constructor is +create the table. We tell QSqlTableModel the name of the table we'll be using +via the \l {QSqlTableModel::setTable}{setTable()} function. To ensure that the +latest messages in the conversation are shown first, we sort the query results +by the \c timestamp field in descending order. This goes hand in hand with +setting ListView's \l {ListView::}{verticalLayoutDirection} property to +\c ListView.BottomToTop (which we covered in chapter 3). + +\skipto ::recipient( +\printuntil } +\printuntil } + +In \c setRecipient(), we set a filter over the results returned from +the database. + +\skipto ::data( +\printuntil } + +The \c data() function falls back to QSqlTableModel's implementation if the +role is not a custom user role. If the role is a user role, we can subtract +Qt::UserRole from it to get the index of that field and then use that to find +the value that we need to return. + +\skipto ::roleNames( +\printuntil } + +In \c roleNames(), we return a mapping of our custom role values to role names. +This enables us to use these roles in QML. It can be useful to declare an enum +to hold all of the role values, but since we don't refer to any specific value +in code outside of this function, we don't bother. + +\skipto ::sendMessage( +\printuntil } + +The \c sendMessage() function uses the given \c recipient and a \c message to +insert a new record into the database. Due to our usage +of \l QSqlTableModel::OnManualSubmit, we must manually call +\l {QSqlTableModel::submitAll}{submitAll()}. + +\section2 Connecting to the Database and Registering Types With QML + +Now that we've established the model classes, let's take a look at \c main.cpp: + +\quotefromfile chattutorial/chapter4/main.cpp +\skipto #include +\printuntil return app.exec(); +\printuntil } + +\c connectToDatabase() creates the connection to the SQLite database, creating +the actual file if it doesn't already exist. + +Within \c main(), we call \l {qmlRegisterType}{qmlRegisterType()} to +register our models as types within QML. + +\section2 Using the Models in QML + +Now that we have the models available as QML types, there are some minor +changes to be done to \c ContactPage.qml. To be able to use the types, +we must first import them using the URI we set in \c main.cpp: + +\quotefromfile chattutorial/chapter4/ContactPage.qml +\skipto import io.qt.examples.chattutorial +\printline import io.qt.examples.chattutorial + +We then replace the dummy model with the proper one: + +\skipto model: SqlContactModel {} +\printline model: SqlContactModel {} + +Within the delegate, we use a different syntax for accessing the model data: + +\skipto text: model.display +\printline text: model.display + +In \c ConversationPage.qml, we add the same \c chattutorial import, and replace +the dummy model: + +\quotefromfile chattutorial/chapter4/ConversationPage.qml +\skipto model: SqlConversationModel { +\printuntil } + +Within the model, we set the \c recipient property to the name of the contact +for which the page is being displayed. + +The root delegate item changes from a Row to a Column, to accommodate the +timestamp that we want to display below every message: + +\skipto delegate: Column { +\printuntil Label { +\printuntil } +\printuntil } +\printuntil } +\printuntil } +\printuntil } + +\borderedimage qtquickcontrols2-chattutorial-chapter4-message-timestamp.png + +Now that we have a proper model, we can use its \c recipient role in the +expression for the \c sentByMe property. + +The Rectangle that was used for the avatar has been converted into an Image. +The image has its own implicit size, so we don't need to specify it explicitly. +As before, we only show the avatar when the author isn't the user, except this +time we set the \c source of the image to an empty URL instead of using the +\c visible property. + +We want each message background to be slightly wider (12 pixels each side) than +its text. However, if it's too long, we want to limit its width to the edge +of the listview, hence the usage of \c Math.min(). When the message wasn't sent +by us, an avatar will always come before it, so we account for that by +subtracting the width of the avatar and the row spacing. + +For example, in the image above, the implicit width of the message text is the +smaller value. However, in the image below, the message text is quite long, so +the smaller value (the width of the view) is chosen, ensuring that the text +stops at the opposite edge of the screen: + +\borderedimage qtquickcontrols2-chattutorial-chapter4-long-message.png + +In order to display the timestamp for each message that we discussed earlier, +we use a Label. The date and time are formatted with +\l {QtQml::Qt::formatDateTime}{Qt.formatDateTime()}, using a custom format. + +The \e "send" button must now react to being clicked: + +\skipto Button +\printuntil } +\printuntil } + +First, we call the invokable \c sendMessage() function of the model, which +inserts a new row into the Conversations database table. Then, we clear the +text field to make way for future input. + +\borderedimage qtquickcontrols2-chattutorial-chapter4.gif + +\generatelist examplefiles .*(chapter4|shared).* +\generatelist exampleimages + +\section1 Chapter 5: Styling + +Styles in Qt Quick Controls are designed to work on any platform. In this +chapter, we'll do some minor visual tweaks to make sure our application +looks good when run with the \l {Basic Style}{Basic}, +\l {Material Style}{Material}, and \l {Universal Style}{Universal} styles. + +So far, we've just been testing the application with the Basic style. If we +run it with the \l {Material Style}, for example, we'll immediately see some issues. +Here is the Contacts page: + +\borderedimage qtquickcontrols2-chattutorial-chapter5-contacts-material-test.png + +The header text is black on a dark blue background, which is very difficult to +read. The same thing occurs with the Conversations page: + +\borderedimage qtquickcontrols2-chattutorial-chapter5-conversations-material-test.png + +The solution is to tell the toolbar that it should use the \e "Dark" theme, so +that this information is propagated to its children, allowing them to switch +their text color to something lighter. The simplest way of doing so is to +import the Material style directly and use the Material attached property: + +\code + import QtQuick.Controls.Material 2.12 + + // ... + + header: ToolBar { + Material.theme: Material.Dark + + // ... + } +\endcode + +However, this brings with it a hard dependency to the Material style; the +Material style plugin \e must be deployed with the application, even if the +target device doesn't use it, otherwise the QML engine will fail to find the +import. + +Instead, it is better to rely on Qt Quick Controls's built-in support for +\l {Using File Selectors with Qt Quick Controls}{style-based file selectors}. +To do this, we must move the ToolBar out into its own file. We'll call it +\c ChatToolBar.qml. This will be the \e "default" version of the file, which +means that it will be used when the \l {Basic Style}{Basic style} (which is the +style that is used when none is specified) is in +use. Here's the new file: + +\quotefromfile chattutorial/chapter5/ChatToolBar.qml +\skipto import +\printuntil } + +As we only use the ToolBar type within this file, we only need the +Qt Quick Controls import. The code itself has not changed from how it was +in \c ContactPage.qml, which is how it should be; for the default version +of the file, nothing needs to be different. + +Back in \c ContactPage.qml, we update the code to use the new type: + +\quotefromfile chattutorial/chapter5/ContactPage.qml +\skipto ToolBar +\printuntil } +\printuntil } + +Now we need to add the Material version of the toolbar. File selectors expect +variants of a file to be in appropriately named directories that exist +alongside the default version of the file. This means that we need to add a +folder named "+Material" in the same directory that ChatToolBar.qml is in: +the root folder. The "+" is required by \l QFileSelector as a way of ensuring +that the selection feature is not accidentally triggered. + +Here's \c +Material/ChatToolBar.qml: + +\quotefromfile chattutorial/chapter5/+Material/ChatToolBar.qml +\skipto import +\printuntil } + +We'll make the same changes to \c ConversationPage.qml: + +\quotefromfile chattutorial/chapter5/ConversationPage.qml +\skipto header: ChatToolBar +\printuntil } +\printuntil } +\printuntil } + +Now both pages look correct: + +\borderedimage qtquickcontrols2-chattutorial-chapter5-contacts-material.png +\borderedimage qtquickcontrols2-chattutorial-chapter5-conversations-material.png + +Let's try out the Universal style: + +\borderedimage qtquickcontrols2-chattutorial-chapter5-contacts-universal.png +\borderedimage qtquickcontrols2-chattutorial-chapter5-conversations-universal.png + +No issues there. For a relatively simple application such as this one, there +should be very few adjustments necessary when switching styles. + +Now let's try each style's dark theme. The Basic style has no dark theme, as +it would add a slight overhead to a style that is designed to be as performant +as possible. We'll test out the Material style first, so add an entry to +\c qtquickcontrols2.conf that tells it to use its dark theme: + +\code +[Material] +Primary=Indigo +Accent=Indigo +Theme=Dark +\endcode + +Once this is done, build and run the application. This is what you should see: + +\borderedimage qtquickcontrols2-chattutorial-chapter5-contacts-material-dark.png +\borderedimage qtquickcontrols2-chattutorial-chapter5-conversations-material-dark.png + +Both pages look fine. Now add an entry for the Universal style: + +\code +[universal] +Theme=Dark +\endcode + +After building and running the application, you should see these results: + +\borderedimage qtquickcontrols2-chattutorial-chapter5-contacts-universal-dark.png +\borderedimage qtquickcontrols2-chattutorial-chapter5-conversations-universal-dark.png + +\generatelist examplefiles .*(chapter5|shared).* +\generatelist exampleimages + +\section1 Summary + +In this tutorial, we've taken you through the following steps of writing a +basic application using Qt Quick Controls: + +\list +\li Creating a new project using Qt Creator. +\li Setting up a basic ApplicationWindow. +\li Defining headers and footers with Page. +\li Displaying content in a ListView. +\li Refactoring components into their own files. +\li Navigating between screens with StackView. +\li Using layouts to allow an application to resize gracefully. +\li Implementing both custom read-only and writable models that integrate an +SQL database into the application. +\li Integrating C++ with QML via \l Q_PROPERTY, \l Q_INVOKABLE, and +\l qmlRegisterType(). +\li Testing and configuring multiple styles. +\endlist + +*/ diff --git a/examples/quickcontrols/contactlist/CMakeLists.txt b/examples/quickcontrols/contactlist/CMakeLists.txt new file mode 100644 index 0000000000..ac7eccd9a7 --- /dev/null +++ b/examples/quickcontrols/contactlist/CMakeLists.txt @@ -0,0 +1,46 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +cmake_minimum_required(VERSION 3.16) +project(contactlist LANGUAGES CXX) + +set(CMAKE_AUTOMOC ON) + +if(NOT DEFINED INSTALL_EXAMPLESDIR) + set(INSTALL_EXAMPLESDIR "examples") +endif() + +set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/quickcontrols2/contactlist") + +find_package(Qt6 REQUIRED COMPONENTS Core Gui Quick) + +qt_add_executable(contactlistexample WIN32 MACOSX_BUNDLE + contactmodel.cpp contactmodel.h + main.cpp +) + +qt_add_qml_module(contactlistexample + URI contactlist + VERSION 1.0 + NO_RESOURCE_TARGET_PATH + QML_FILES + "ContactDelegate.ui.qml" + "ContactDialog.qml" + "ContactForm.ui.qml" + "ContactView.ui.qml" + "SectionDelegate.ui.qml" + "contactlist.qml" + "designer/Backend/ContactModel.qml" +) + +target_link_libraries(contactlistexample PUBLIC + Qt::Core + Qt::Gui + Qt::Quick +) + +install(TARGETS contactlistexample + RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" + LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" +) diff --git a/examples/quickcontrols/contactlist/ContactDelegate.ui.qml b/examples/quickcontrols/contactlist/ContactDelegate.ui.qml new file mode 100644 index 0000000000..3591b2f3fd --- /dev/null +++ b/examples/quickcontrols/contactlist/ContactDelegate.ui.qml @@ -0,0 +1,82 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls + +ItemDelegate { + id: delegate + + checkable: true + + contentItem: ColumnLayout { + spacing: 10 + + Label { + text: fullName + font.bold: true + elide: Text.ElideRight + Layout.fillWidth: true + } + + GridLayout { + id: grid + visible: false + + columns: 2 + rowSpacing: 10 + columnSpacing: 10 + + Label { + text: qsTr("Address:") + Layout.leftMargin: 60 + } + + Label { + text: address + font.bold: true + elide: Text.ElideRight + Layout.fillWidth: true + } + + Label { + text: qsTr("City:") + Layout.leftMargin: 60 + } + + Label { + text: city + font.bold: true + elide: Text.ElideRight + Layout.fillWidth: true + } + + Label { + text: qsTr("Number:") + Layout.leftMargin: 60 + } + + Label { + text: number + font.bold: true + elide: Text.ElideRight + Layout.fillWidth: true + } + } + } + + states: [ + State { + name: "expanded" + when: delegate.checked + + PropertyChanges { + // TODO: When Qt Design Studio supports generalized grouped properties, change to: + // grid.visible: true + target: grid + visible: true + } + } + ] +} diff --git a/examples/quickcontrols/contactlist/ContactDialog.qml b/examples/quickcontrols/contactlist/ContactDialog.qml new file mode 100644 index 0000000000..9bb990f2ad --- /dev/null +++ b/examples/quickcontrols/contactlist/ContactDialog.qml @@ -0,0 +1,45 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Controls + +Dialog { + id: dialog + + signal finished(string fullName, string address, string city, string number) + + function createContact() { + form.fullName.clear(); + form.address.clear(); + form.city.clear(); + form.number.clear(); + + dialog.title = qsTr("Add Contact"); + dialog.open(); + } + + function editContact(contact) { + form.fullName.text = contact.fullName; + form.address.text = contact.address; + form.city.text = contact.city; + form.number.text = contact.number; + + dialog.title = qsTr("Edit Contact"); + dialog.open(); + } + + x: parent.width / 2 - width / 2 + y: parent.height / 2 - height / 2 + + focus: true + modal: true + title: qsTr("Add Contact") + standardButtons: Dialog.Ok | Dialog.Cancel + + contentItem: ContactForm { + id: form + } + + onAccepted: finished(form.fullName.text, form.address.text, form.city.text, form.number.text) +} diff --git a/examples/quickcontrols/contactlist/ContactForm.ui.qml b/examples/quickcontrols/contactlist/ContactForm.ui.qml new file mode 100644 index 0000000000..918da57f30 --- /dev/null +++ b/examples/quickcontrols/contactlist/ContactForm.ui.qml @@ -0,0 +1,72 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls + +GridLayout { + id: grid + property alias fullName: fullName + property alias address: address + property alias city: city + property alias number: number + property int minimumInputSize: 120 + property string placeholderText: qsTr("<enter>") + + rows: 4 + columns: 2 + + Label { + text: qsTr("Full Name") + Layout.alignment: Qt.AlignLeft | Qt.AlignBaseline + } + + TextField { + id: fullName + focus: true + Layout.fillWidth: true + Layout.minimumWidth: grid.minimumInputSize + Layout.alignment: Qt.AlignLeft | Qt.AlignBaseline + placeholderText: grid.placeholderText + } + + Label { + text: qsTr("Address") + Layout.alignment: Qt.AlignLeft | Qt.AlignBaseline + } + + TextField { + id: address + Layout.fillWidth: true + Layout.minimumWidth: grid.minimumInputSize + Layout.alignment: Qt.AlignLeft | Qt.AlignBaseline + placeholderText: grid.placeholderText + } + + Label { + text: qsTr("City") + Layout.alignment: Qt.AlignLeft | Qt.AlignBaseline + } + + TextField { + id: city + Layout.fillWidth: true + Layout.minimumWidth: grid.minimumInputSize + Layout.alignment: Qt.AlignLeft | Qt.AlignBaseline + placeholderText: grid.placeholderText + } + + Label { + text: qsTr("Number") + Layout.alignment: Qt.AlignLeft | Qt.AlignBaseline + } + + TextField { + id: number + Layout.fillWidth: true + Layout.minimumWidth: grid.minimumInputSize + Layout.alignment: Qt.AlignLeft | Qt.AlignBaseline + placeholderText: grid.placeholderText + } +} diff --git a/examples/quickcontrols/contactlist/ContactView.ui.qml b/examples/quickcontrols/contactlist/ContactView.ui.qml new file mode 100644 index 0000000000..6e80d05bac --- /dev/null +++ b/examples/quickcontrols/contactlist/ContactView.ui.qml @@ -0,0 +1,36 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Controls +import Backend + +ListView { + id: listView + + signal pressAndHold(int index) + + width: 320 + height: 480 + + focus: true + boundsBehavior: Flickable.StopAtBounds + + section.property: "fullName" + section.criteria: ViewSection.FirstCharacter + section.delegate: SectionDelegate { + width: listView.width + } + + delegate: ContactDelegate { + id: delegate + width: listView.width + onPressAndHold: listView.pressAndHold(index) + } + + model: ContactModel { + id: contactModel + } + + ScrollBar.vertical: ScrollBar { } +} diff --git a/examples/quickcontrols/contactlist/SectionDelegate.ui.qml b/examples/quickcontrols/contactlist/SectionDelegate.ui.qml new file mode 100644 index 0000000000..05b2147288 --- /dev/null +++ b/examples/quickcontrols/contactlist/SectionDelegate.ui.qml @@ -0,0 +1,17 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Controls + +ToolBar { + id: background + + Label { + id: label + text: section + anchors.fill: parent + horizontalAlignment: Qt.AlignHCenter + verticalAlignment: Qt.AlignVCenter + } +} diff --git a/examples/quickcontrols/contactlist/contactlist.pro b/examples/quickcontrols/contactlist/contactlist.pro new file mode 100644 index 0000000000..101db15a3d --- /dev/null +++ b/examples/quickcontrols/contactlist/contactlist.pro @@ -0,0 +1,28 @@ +TEMPLATE = app +TARGET = contactlist +QT += quick + +HEADERS += \ + contactmodel.h + +SOURCES += \ + main.cpp \ + contactmodel.cpp + +RESOURCES += \ + ContactDelegate.ui.qml \ + ContactDialog.qml \ + ContactForm.ui.qml \ + contactlist.qml \ + ContactView.ui.qml \ + designer/Backend/ContactModel.qml \ + SectionDelegate.ui.qml + +# Additional import path used to resolve QML modules just for Qt Quick Designer +QML_DESIGNER_IMPORT_PATH = $$PWD/designer + +OTHER_FILES += \ + designer/Backend/*.qml + +target.path = $$[QT_INSTALL_EXAMPLES]/quickcontrols2/contactlist +INSTALLS += target diff --git a/examples/quickcontrols/contactlist/contactlist.qml b/examples/quickcontrols/contactlist/contactlist.qml new file mode 100644 index 0000000000..28f887f2db --- /dev/null +++ b/examples/quickcontrols/contactlist/contactlist.qml @@ -0,0 +1,70 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + id: window + + property int currentContact: -1 + + width: 320 + height: 480 + visible: true + title: qsTr("Contact List") + + ContactDialog { + id: contactDialog + onFinished: function(fullName, address, city, number) { + if (currentContact === -1) + contactView.model.append(fullName, address, city, number) + else + contactView.model.set(currentContact, fullName, address, city, number) + } + } + + Menu { + id: contactMenu + x: parent.width / 2 - width / 2 + y: parent.height / 2 - height / 2 + modal: true + + Label { + padding: 10 + font.bold: true + width: parent.width + horizontalAlignment: Qt.AlignHCenter + text: currentContact >= 0 ? contactView.model.get(currentContact).fullName : "" + } + MenuItem { + text: qsTr("Edit...") + onTriggered: contactDialog.editContact(contactView.model.get(currentContact)) + } + MenuItem { + text: qsTr("Remove") + onTriggered: contactView.model.remove(currentContact) + } + } + + ContactView { + id: contactView + anchors.fill: parent + onPressAndHold: { + currentContact = index + contactMenu.open() + } + } + + RoundButton { + text: qsTr("+") + highlighted: true + anchors.margins: 10 + anchors.right: parent.right + anchors.bottom: parent.bottom + onClicked: { + currentContact = -1 + contactDialog.createContact() + } + } +} diff --git a/examples/quickcontrols/contactlist/contactmodel.cpp b/examples/quickcontrols/contactlist/contactmodel.cpp new file mode 100644 index 0000000000..1add2e7776 --- /dev/null +++ b/examples/quickcontrols/contactlist/contactmodel.cpp @@ -0,0 +1,83 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#include "contactmodel.h" + +ContactModel::ContactModel(QObject *parent ) : QAbstractListModel(parent) +{ + m_contacts.append({ "Angel Hogan", "Chapel St. 368 ", "Clearwater" , "0311 1823993" }); + m_contacts.append({ "Felicia Patton", "Annadale Lane 2", "Knoxville" , "0368 1244494" }); + m_contacts.append({ "Grant Crawford", "Windsor Drive 34", "Riverdale" , "0351 7826892" }); + m_contacts.append({ "Gretchen Little", "Sunset Drive 348", "Virginia Beach" , "0343 1234991" }); + m_contacts.append({ "Geoffrey Richards", "University Lane 54", "Trussville" , "0423 2144944" }); + m_contacts.append({ "Henrietta Chavez", "Via Volto San Luca 3", "Piobesi Torinese" , "0399 2826994" }); + m_contacts.append({ "Harvey Chandler", "North Squaw Creek 11", "Madisonville" , "0343 1244492" }); + m_contacts.append({ "Miguel Gomez", "Wild Rose Street 13", "Trussville" , "0343 9826996" }); + m_contacts.append({ "Norma Rodriguez", " Glen Eagles Street 53", "Buffalo" , "0241 5826596" }); + m_contacts.append({ "Shelia Ramirez", "East Miller Ave 68", "Pickerington" , "0346 4844556" }); + m_contacts.append({ "Stephanie Moss", "Piazza Trieste e Trento 77", "Roata Chiusani" , "0363 0510490" }); +} + +int ContactModel::rowCount(const QModelIndex &) const +{ + return m_contacts.count(); +} + +QVariant ContactModel::data(const QModelIndex &index, int role) const +{ + if (index.row() < rowCount()) + switch (role) { + case FullNameRole: return m_contacts.at(index.row()).fullName; + case AddressRole: return m_contacts.at(index.row()).address; + case CityRole: return m_contacts.at(index.row()).city; + case NumberRole: return m_contacts.at(index.row()).number; + default: return QVariant(); + } + return QVariant(); +} + +QHash<int, QByteArray> ContactModel::roleNames() const +{ + static const QHash<int, QByteArray> roles { + { FullNameRole, "fullName" }, + { AddressRole, "address" }, + { CityRole, "city" }, + { NumberRole, "number" } + }; + return roles; +} + +QVariantMap ContactModel::get(int row) const +{ + const Contact contact = m_contacts.value(row); + return { {"fullName", contact.fullName}, {"address", contact.address}, {"city", contact.city}, {"number", contact.number} }; +} + +void ContactModel::append(const QString &fullName, const QString &address, const QString &city, const QString &number) +{ + int row = 0; + while (row < m_contacts.count() && fullName > m_contacts.at(row).fullName) + ++row; + beginInsertRows(QModelIndex(), row, row); + m_contacts.insert(row, {fullName, address, city, number}); + endInsertRows(); +} + +void ContactModel::set(int row, const QString &fullName, const QString &address, const QString &city, const QString &number) +{ + if (row < 0 || row >= m_contacts.count()) + return; + + m_contacts.replace(row, { fullName, address, city, number }); + dataChanged(index(row, 0), index(row, 0), { FullNameRole, AddressRole, CityRole, NumberRole }); +} + +void ContactModel::remove(int row) +{ + if (row < 0 || row >= m_contacts.count()) + return; + + beginRemoveRows(QModelIndex(), row, row); + m_contacts.removeAt(row); + endRemoveRows(); +} diff --git a/examples/quickcontrols/contactlist/contactmodel.h b/examples/quickcontrols/contactlist/contactmodel.h new file mode 100644 index 0000000000..564ec0fab3 --- /dev/null +++ b/examples/quickcontrols/contactlist/contactmodel.h @@ -0,0 +1,44 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#ifndef CONTACTMODEL_H +#define CONTACTMODEL_H + +#include <QAbstractListModel> + +class ContactModel : public QAbstractListModel +{ + Q_OBJECT + +public: + enum ContactRole { + FullNameRole = Qt::DisplayRole, + AddressRole = Qt::UserRole, + CityRole, + NumberRole + }; + Q_ENUM(ContactRole) + + ContactModel(QObject *parent = nullptr); + + int rowCount(const QModelIndex & = QModelIndex()) const; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + QHash<int, QByteArray> roleNames() const; + + Q_INVOKABLE QVariantMap get(int row) const; + Q_INVOKABLE void append(const QString &fullName, const QString &address, const QString &city, const QString &number); + Q_INVOKABLE void set(int row, const QString &fullName, const QString &address, const QString &city, const QString &number); + Q_INVOKABLE void remove(int row); + +private: + struct Contact { + QString fullName; + QString address; + QString city; + QString number; + }; + + QList<Contact> m_contacts; +}; + +#endif // CONTACTMODEL_H diff --git a/examples/quickcontrols/contactlist/designer/Backend/ContactModel.qml b/examples/quickcontrols/contactlist/designer/Backend/ContactModel.qml new file mode 100644 index 0000000000..c7a3f4817b --- /dev/null +++ b/examples/quickcontrols/contactlist/designer/Backend/ContactModel.qml @@ -0,0 +1,41 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick + +ListModel { + ListElement { + address: "Chapel St. 368" + city: "Knoxville" + number: "0311 1823993" + fullName: "Angel Hogan" + } + + ListElement { + address: "Annadale Lane 2" + city: "Clearwater" + number: "0368 1244494" + fullName: "Felicia Patton" + } + + ListElement { + address: "Windsor Drive 34" + city: "Riverdale" + number: "0368 1244494" + fullName: "Grant Crawford" + } + + ListElement { + address: "Sunset Drive 348" + city: "Virginia Beach" + number: "0351 7826892" + fullName: "Gretchen Little" + } + + ListElement { + address: "University Lane 54" + city: "Trussville" + number: "0399 2826994" + fullName: "Geoffrey Richards" + } +} diff --git a/examples/quickcontrols/contactlist/designer/Backend/qmldir b/examples/quickcontrols/contactlist/designer/Backend/qmldir new file mode 100644 index 0000000000..8e2037d4d7 --- /dev/null +++ b/examples/quickcontrols/contactlist/designer/Backend/qmldir @@ -0,0 +1,2 @@ +module Backend +ContactModel 1.0 ContactModel.qml diff --git a/examples/quickcontrols/contactlist/doc/images/qtquickcontrols2-contactlist.png b/examples/quickcontrols/contactlist/doc/images/qtquickcontrols2-contactlist.png Binary files differnew file mode 100644 index 0000000000..9f1c306544 --- /dev/null +++ b/examples/quickcontrols/contactlist/doc/images/qtquickcontrols2-contactlist.png diff --git a/examples/quickcontrols/contactlist/doc/src/qtquickcontrols2-contactlist.qdoc b/examples/quickcontrols/contactlist/doc/src/qtquickcontrols2-contactlist.qdoc new file mode 100644 index 0000000000..3f88d9dc74 --- /dev/null +++ b/examples/quickcontrols/contactlist/doc/src/qtquickcontrols2-contactlist.qdoc @@ -0,0 +1,49 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only +/*! + \example contactlist + \keyword Qt Quick Controls - Contact List + \title Qt Quick Controls - Contact List + \keyword Qt Quick Controls 2 - Contact List + \ingroup qtquickcontrols2-examples + \brief A QML app using Qt Quick Controls and a C++ class that implements + a simple contact list. + + The \e {Contact List Example} shows how to integrate a C++ backend in a way that + is compatible with Qt Quick Designer. + For the declarative parts of the UI, .ui.qml files are used that can be edited + visually in the Qt Quick Designer. + + \image qtquickcontrols2-contactlist.png + + \section1 C++ Backend + + The contact list application allows the user to add, edit, and remove contacts. + The actual implementation is done in C++ and exposed as a QAbstractListModel. + + The ContactModel C++ class is registered under a namespace and later + imported and instantiated by \e MainForm.ui.qml. For more information about registering C++ + classes as QML types, see \l {Defining QML Types from C++}. + + \code + #include <QtQml/qqml.h> + ... + qmlRegisterType<ContactModel>("Backend", 1, 0, "ContactModel"); + ... + \endcode + + \section1 Designer Support + + In the designer subdirectory, we create a plugin that replaces the ContactModel + in Qt Quick Designer. For this to work we add the following line to \e contactlist.pro. + + \code + QML_DESIGNER_IMPORT_PATH = $$PWD/designer + \endcode + + Because Qt Quick Designer cannot instantiate the ContactModel C++ class, we define + a mockup using a ListModel. This ensures that the ListView using the model shows something + in Qt Quick Designer. + + \include examples-run.qdocinc +*/ diff --git a/examples/quickcontrols/contactlist/main.cpp b/examples/quickcontrols/contactlist/main.cpp new file mode 100644 index 0000000000..32a88def4c --- /dev/null +++ b/examples/quickcontrols/contactlist/main.cpp @@ -0,0 +1,19 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#include <QGuiApplication> +#include <QQmlApplicationEngine> + +#include "contactmodel.h" + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + qmlRegisterType<ContactModel>("Backend", 1, 0, "ContactModel"); + + QQmlApplicationEngine engine; + engine.load(QUrl(QStringLiteral("qrc:/contactlist.qml"))); + + return app.exec(); +} diff --git a/examples/quickcontrols/eventcalendar/CMakeLists.txt b/examples/quickcontrols/eventcalendar/CMakeLists.txt new file mode 100644 index 0000000000..6c44eb82ec --- /dev/null +++ b/examples/quickcontrols/eventcalendar/CMakeLists.txt @@ -0,0 +1,51 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +cmake_minimum_required(VERSION 3.16) +project(eventcalendar LANGUAGES CXX) + +set(CMAKE_AUTOMOC ON) + +if(NOT DEFINED INSTALL_EXAMPLESDIR) + set(INSTALL_EXAMPLESDIR "examples") +endif() + +set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/quickcontrols2/eventcalendar") + +find_package(Qt6 REQUIRED COMPONENTS Core Gui Qml Sql) + +qt_add_executable(eventcalendar + event.h + eventcalendar.cpp + eventmodel.cpp eventmodel.h + sqleventdatabase.cpp sqleventdatabase.h +) + +set_target_properties(eventcalendar PROPERTIES + WIN32_EXECUTABLE TRUE + MACOSX_BUNDLE TRUE +) + +target_link_libraries(eventcalendar PUBLIC + Qt::Core + Qt::Gui + Qt::Qml + Qt::Sql +) + +qt_add_qml_module(eventcalendar + URI App + VERSION 1.0 + QML_FILES + MonthGridDelegate.qml + eventcalendar.qml + RESOURCES + qtquickcontrols2.conf + NO_RESOURCE_TARGET_PATH +) + +install(TARGETS eventcalendar + RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" + LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" +) diff --git a/examples/quickcontrols/eventcalendar/MonthGridDelegate.qml b/examples/quickcontrols/eventcalendar/MonthGridDelegate.qml new file mode 100644 index 0000000000..c49dfda1ae --- /dev/null +++ b/examples/quickcontrols/eventcalendar/MonthGridDelegate.qml @@ -0,0 +1,78 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import QtQuick.Controls.Material + +import App + +ColumnLayout { + id: root + + required property EventDatabase eventDatabase + + required property bool today + required property int year + required property int month + required property int day + + required property int visibleMonth + + Material.theme: today ? Material.Dark : undefined + + Label { + id: dayText + horizontalAlignment: Text.AlignHCenter + topPadding: 4 + opacity: month === root.visibleMonth ? 1 : 0 + text: day + + Layout.fillWidth: true + + Rectangle { + width: height + height: Math.max(dayText.implicitWidth, dayText.implicitHeight) + radius: width / 2 + color: Material.primary + anchors.centerIn: dayText + anchors.verticalCenterOffset: dayText.height - dayText.baselineOffset + z: -1 + visible: root.today + } + } + + ListView { + spacing: 1 + clip: true + + Layout.fillWidth: true + Layout.fillHeight: true + Layout.topMargin: 4 + + delegate: ItemDelegate { + id: itemDelegate + width: parent.width + text: name + font.pixelSize: Qt.application.font.pixelSize * 0.8 + leftPadding: 4 + rightPadding: 4 + topPadding: 4 + bottomPadding: 4 + + required property string name + + Material.theme: Material.Dark + + background: Rectangle { + color: itemDelegate.Material.primary + radius: 3 + } + } + model: EventModel { + eventDatabase: root.eventDatabase + date: new Date(root.year, root.month, root.day) + } + } +} diff --git a/examples/quickcontrols/eventcalendar/doc/images/qtquickcalendar-eventcalendar.png b/examples/quickcontrols/eventcalendar/doc/images/qtquickcalendar-eventcalendar.png Binary files differnew file mode 100644 index 0000000000..35d905be6d --- /dev/null +++ b/examples/quickcontrols/eventcalendar/doc/images/qtquickcalendar-eventcalendar.png diff --git a/examples/quickcontrols/eventcalendar/doc/src/qtquickcontrols2-eventcalendar.qdoc b/examples/quickcontrols/eventcalendar/doc/src/qtquickcontrols2-eventcalendar.qdoc new file mode 100644 index 0000000000..cc0b031b51 --- /dev/null +++ b/examples/quickcontrols/eventcalendar/doc/src/qtquickcontrols2-eventcalendar.qdoc @@ -0,0 +1,19 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only + +/*! + \example eventcalendar + \keyword Qt Quick Controls - Event Calendar + \title Qt Quick Controls - Event Calendar + \ingroup qtquickcontrols2-examples + \brief A simple event calendar. + + \image qtquickcalendar-eventcalendar.png + + The Event Calendar example is a simple application that shows how to use + \l DayOfWeekRow, \l WeekNumberColumn, and \l MonthGrid to create a calendar. + It uses an in-memory SQL database to populate the calendar with events. + The example uses the \l {Material Style}{Material style}. + + \include examples-run.qdocinc +*/ diff --git a/examples/quickcontrols/eventcalendar/event.h b/examples/quickcontrols/eventcalendar/event.h new file mode 100644 index 0000000000..b2cc6b45cf --- /dev/null +++ b/examples/quickcontrols/eventcalendar/event.h @@ -0,0 +1,16 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#ifndef EVENT_H +#define EVENT_H + +#include <QAbstractListModel> +#include <QDateTime> + +struct Event { + QString name; + QDateTime startDate; + QDateTime endDate; +}; + +#endif // EVENT_H diff --git a/examples/quickcontrols/eventcalendar/eventcalendar.cpp b/examples/quickcontrols/eventcalendar/eventcalendar.cpp new file mode 100644 index 0000000000..bc952a3f9a --- /dev/null +++ b/examples/quickcontrols/eventcalendar/eventcalendar.cpp @@ -0,0 +1,29 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#include <QGuiApplication> +#include <QQmlApplicationEngine> +#include <QIcon> + +#include "sqleventdatabase.h" + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + QIcon::setThemeName("eventcalendar"); + + QQmlApplicationEngine engine; + SqlEventDatabase eventDatabase; + engine.setInitialProperties({{ "eventDatabase", QVariant::fromValue(&eventDatabase) }}); + + const QUrl url(QStringLiteral("qrc:/eventcalendar.qml")); + QObject::connect(&engine, &QQmlApplicationEngine::objectCreated, + &app, [url](QObject *obj, const QUrl &objUrl) { + if (!obj && url == objUrl) + QCoreApplication::exit(-1); + }, Qt::QueuedConnection); + engine.load(url); + + return app.exec(); +} diff --git a/examples/quickcontrols/eventcalendar/eventcalendar.pro b/examples/quickcontrols/eventcalendar/eventcalendar.pro new file mode 100644 index 0000000000..742c5d09e8 --- /dev/null +++ b/examples/quickcontrols/eventcalendar/eventcalendar.pro @@ -0,0 +1,25 @@ +TEMPLATE = app +TARGET = eventcalendar +QT += sql qml + +CONFIG += qmltypes +QML_IMPORT_NAME = App +QML_IMPORT_MAJOR_VERSION = 1 + +HEADERS += \ + event.h \ + eventmodel.h \ + sqleventdatabase.h + +SOURCES += \ + eventcalendar.cpp \ + eventmodel.cpp \ + sqleventdatabase.cpp + +RESOURCES += \ + eventcalendar.qml \ + MonthGridDelegate.qml \ + qtquickcontrols2.conf + +target.path = $$[QT_INSTALL_EXAMPLES]/quickcalendar/eventcalendar +INSTALLS += target diff --git a/examples/quickcontrols/eventcalendar/eventcalendar.qml b/examples/quickcontrols/eventcalendar/eventcalendar.qml new file mode 100644 index 0000000000..65d85d8d4e --- /dev/null +++ b/examples/quickcontrols/eventcalendar/eventcalendar.qml @@ -0,0 +1,113 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material +import QtQuick.Layouts + +import App + +ApplicationWindow { + id: window + width: 800 + height: 600 + title: qsTr("Event Calendar") + visible: true + + required property EventDatabase eventDatabase + + readonly property date currentDate: new Date() + + header: ToolBar { + Label { + text: window.currentDate.toLocaleString(locale, "MMMM yyyy") + font.pixelSize: Qt.application.font.pixelSize * 1.25 + anchors.centerIn: parent + } + } + + GridLayout { + anchors.fill: parent + columns: 2 + + DayOfWeekRow { + id: dayOfWeekRow + locale: grid.locale + font.bold: false + delegate: Label { + text: model.shortName + font: dayOfWeekRow.font + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + + Layout.column: 1 + Layout.fillWidth: true + } + + WeekNumberColumn { + month: grid.month + year: grid.year + locale: grid.locale + font.bold: false + + Layout.fillHeight: true + } + + MonthGrid { + id: grid + month: window.currentDate.getMonth() + year: window.currentDate.getFullYear() + spacing: 0 + + readonly property int gridLineThickness: 1 + + Layout.fillWidth: true + Layout.fillHeight: true + + delegate: MonthGridDelegate { + id: gridDelegate + visibleMonth: grid.month + eventDatabase: window.eventDatabase + } + + background: Item { + x: grid.leftPadding + y: grid.topPadding + width: grid.availableWidth + height: grid.availableHeight + + // Vertical lines + Row { + spacing: (parent.width - (grid.gridLineThickness * rowRepeater.model)) / rowRepeater.model + + Repeater { + id: rowRepeater + model: 7 + delegate: Rectangle { + width: 1 + height: grid.height + color: "#ccc" + } + } + } + + // Horizontal lines + Column { + spacing: (parent.height - (grid.gridLineThickness * columnRepeater.model)) / columnRepeater.model + + Repeater { + id: columnRepeater + model: 6 + delegate: Rectangle { + width: grid.width + height: 1 + color: "#ccc" + } + } + } + } + } + } +} diff --git a/examples/quickcontrols/eventcalendar/eventmodel.cpp b/examples/quickcontrols/eventcalendar/eventmodel.cpp new file mode 100644 index 0000000000..a380e00d11 --- /dev/null +++ b/examples/quickcontrols/eventcalendar/eventmodel.cpp @@ -0,0 +1,88 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#include "eventmodel.h" + +#include "sqleventdatabase.h" + +EventModel::EventModel(QObject *parent) + : QAbstractListModel(parent) +{ +} + +SqlEventDatabase *EventModel::eventDatabase() +{ + return m_eventDatabase; +} + +void EventModel::setEventDatabase(SqlEventDatabase *eventDatabase) +{ + if (eventDatabase == m_eventDatabase) + return; + + m_eventDatabase = eventDatabase; + repopulate(); + emit eventDatabaseChanged(); +} + +QDate EventModel::date() const +{ + return m_date; +} + +void EventModel::setDate(const QDate &date) +{ + if (date == m_date) + return; + + m_date = date; + repopulate(); + emit dateChanged(); +} + +int EventModel::rowCount(const QModelIndex &) const +{ + return m_events.size(); +} + +QVariant EventModel::data(const QModelIndex &index, int role) const +{ + if (!checkIndex(index, CheckIndexOption::IndexIsValid)) + return QVariant(); + + switch (role) { + case NameRole: return m_events.at(index.row()).name; + case StartDateRole: return m_events.at(index.row()).startDate; + case EndDateRole: return m_events.at(index.row()).endDate; + default: return QVariant(); + } +} + +QHash<int, QByteArray> EventModel::roleNames() const +{ + static const QHash<int, QByteArray> roles { + { NameRole, "name" }, + { StartDateRole, "startDate" }, + { EndDateRole, "endDate" } + }; + return roles; +} + +bool EventModel::isValid() const +{ + return m_eventDatabase && !m_date.isNull(); +} + +void EventModel::repopulate() +{ + beginResetModel(); + + if (!m_eventDatabase || m_date.isNull()) { + m_events.clear(); + return; + } + + m_events = m_eventDatabase->eventsForDate(m_date); + + endResetModel(); +} diff --git a/examples/quickcontrols/eventcalendar/eventmodel.h b/examples/quickcontrols/eventcalendar/eventmodel.h new file mode 100644 index 0000000000..3dc391fdd7 --- /dev/null +++ b/examples/quickcontrols/eventcalendar/eventmodel.h @@ -0,0 +1,56 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#ifndef CONTACTMODEL_H +#define CONTACTMODEL_H + +#include <QAbstractListModel> +#include <QDate> +#include <QtQml> + +#include "event.h" + +class SqlEventDatabase; + +class EventModel : public QAbstractListModel +{ + Q_OBJECT + Q_PROPERTY(SqlEventDatabase *eventDatabase READ eventDatabase WRITE setEventDatabase NOTIFY eventDatabaseChanged) + Q_PROPERTY(QDate date READ date WRITE setDate NOTIFY dateChanged) + QML_ELEMENT + Q_MOC_INCLUDE("sqleventdatabase.h") + +public: + EventModel(QObject *parent = nullptr); + + enum ContactRole { + NameRole = Qt::UserRole, + StartDateRole, + EndDateRole + }; + Q_ENUM(ContactRole) + + SqlEventDatabase *eventDatabase(); + void setEventDatabase(SqlEventDatabase *eventDatabase); + + QDate date() const; + void setDate(const QDate &date); + + int rowCount(const QModelIndex & = QModelIndex()) const; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + QHash<int, QByteArray> roleNames() const; + +signals: + void eventDatabaseChanged(); + void dateChanged(); + +private: + bool isValid() const; + void repopulate(); + + SqlEventDatabase *m_eventDatabase = nullptr; + QDate m_date; + QVector<Event> m_events; +}; + +#endif // CONTACTMODEL_H diff --git a/examples/quickcontrols/eventcalendar/qmldir b/examples/quickcontrols/eventcalendar/qmldir new file mode 100644 index 0000000000..6b7f86bfac --- /dev/null +++ b/examples/quickcontrols/eventcalendar/qmldir @@ -0,0 +1 @@ +module App diff --git a/examples/quickcontrols/eventcalendar/qtquickcontrols2.conf b/examples/quickcontrols/eventcalendar/qtquickcontrols2.conf new file mode 100644 index 0000000000..b6c7c87ea1 --- /dev/null +++ b/examples/quickcontrols/eventcalendar/qtquickcontrols2.conf @@ -0,0 +1,2 @@ +[Controls] +Style=Material diff --git a/examples/quickcontrols/eventcalendar/sqleventdatabase.cpp b/examples/quickcontrols/eventcalendar/sqleventdatabase.cpp new file mode 100644 index 0000000000..e958448695 --- /dev/null +++ b/examples/quickcontrols/eventcalendar/sqleventdatabase.cpp @@ -0,0 +1,70 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#include "sqleventdatabase.h" + +#include <QDebug> +#include <QFileInfo> +#include <QSqlError> +#include <QSqlQuery> + +SqlEventDatabase::SqlEventDatabase() +{ + createConnection(); +} + +QVector<Event> SqlEventDatabase::eventsForDate(const QDate &date) +{ + const QString queryStr = QString::fromLatin1("SELECT * FROM Event WHERE '%1' >= startDate AND '%1' <= endDate").arg(date.toString("yyyy-MM-dd")); + QSqlQuery query(queryStr); + if (!query.exec()) { + qWarning() << "SQL query failed"; + return {}; + } + + QVector<Event> events; + while (query.next()) { + Event event; + event.name = query.value("name").toString(); + + QDateTime startDate; + startDate.setDate(query.value("startDate").toDate()); + startDate.setTime(QTime(0, 0).addSecs(query.value("startTime").toInt())); + event.startDate = startDate; + + QDateTime endDate; + endDate.setDate(query.value("endDate").toDate()); + endDate.setTime(QTime(0, 0).addSecs(query.value("endTime").toInt())); + event.endDate = endDate; + + events.append(event); + } + return events; +} + +/* + Defines a helper function to open a connection to an + in-memory SQLITE database and to create a table. +*/ +void SqlEventDatabase::createConnection() +{ + QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE"); + db.setDatabaseName(":memory:"); + if (!db.open()) { + qFatal("Cannot open database"); + return; + } + + QSqlQuery query; + const QString year = QDate::currentDate().toString("yyyy"); + const QString month = QDate::currentDate().toString("MM"); + // Keep the example up-to-date by making the events fall in the current year and month. + // We store the time as seconds because it's easier to query. + query.exec("create table Event (name TEXT, startDate DATE, startTime INT, endDate DATE, endTime INT)"); + query.exec(QString::fromLatin1("insert into Event values('Grocery shopping', '%1-%2-01', 36000, '%1-%2-01', 39600)").arg(year, month)); + query.exec(QString::fromLatin1("insert into Event values('Ice skating', '%1-%2-01', 57600, '%1-%2-01', 61200)").arg(year, month)); + query.exec(QString::fromLatin1("insert into Event values('Doctor''s appointment', '%1-%2-15', 57600, '%1-%2-15', 63000)").arg(year, month)); + query.exec(QString::fromLatin1("insert into Event values('Conference', '%1-%2-24', 32400, '%1-%2-28', 61200)").arg(year, month)); + + return; +} diff --git a/examples/quickcontrols/eventcalendar/sqleventdatabase.h b/examples/quickcontrols/eventcalendar/sqleventdatabase.h new file mode 100644 index 0000000000..aa59bfb6b1 --- /dev/null +++ b/examples/quickcontrols/eventcalendar/sqleventdatabase.h @@ -0,0 +1,28 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#ifndef SQLEVENTDATABASE_H +#define SQLEVENTDATABASE_H + +#include <QObject> +#include <QtQml> +#include <QVector> + +#include "event.h" + +class SqlEventDatabase : public QObject +{ + Q_OBJECT + QML_NAMED_ELEMENT(EventDatabase) + QML_UNCREATABLE("EventDatabase should not be created in QML") + +public: + SqlEventDatabase(); + + QVector<Event> eventsForDate(const QDate &date); + +private: + static void createConnection(); +}; + +#endif // SQLEVENTDATABASE_H diff --git a/examples/quickcontrols/flatstyle/CMakeLists.txt b/examples/quickcontrols/flatstyle/CMakeLists.txt new file mode 100644 index 0000000000..7ddb17c99b --- /dev/null +++ b/examples/quickcontrols/flatstyle/CMakeLists.txt @@ -0,0 +1,50 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +cmake_minimum_required(VERSION 3.16) +project(flatstyle LANGUAGES CXX) + +set(CMAKE_AUTOMOC ON) + +if(NOT DEFINED INSTALL_EXAMPLESDIR) + set(INSTALL_EXAMPLESDIR "examples") +endif() + +set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/quickcontrols2/flatstyle") + +find_package(Qt6 REQUIRED COMPONENTS Core Gui Quick QuickControls2 Widgets) + +qt_add_executable(flatstyleexample WIN32 MACOSX_BUNDLE + main.cpp +) + +qt_add_qml_module(flatstyleexample + URI flatstyle + VERSION 1.0 + NO_RESOURCE_TARGET_PATH + QML_FILES + "MainForm.ui.qml" + "flatstyle.qml" + "imports/Flat/Button.qml" + "imports/Flat/CheckBox.qml" + "imports/Flat/Switch.qml" + "imports/Theme/Theme.qml" + RESOURCES + "imports/Flat/qmldir" + "imports/Theme/qmldir" + "qtquickcontrols2.conf" +) + +target_link_libraries(flatstyleexample PUBLIC + Qt::Core + Qt::Gui + Qt::Quick + Qt::QuickControls2 + Qt::Widgets +) + +install(TARGETS flatstyleexample + RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" + LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" +) diff --git a/examples/quickcontrols/flatstyle/MainForm.ui.qml b/examples/quickcontrols/flatstyle/MainForm.ui.qml new file mode 100644 index 0000000000..389ee893c3 --- /dev/null +++ b/examples/quickcontrols/flatstyle/MainForm.ui.qml @@ -0,0 +1,99 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Theme + +Item { + id: form + + width: 320 + height: 480 + property alias slider: slider + property alias checkBoxUnderline: checkBoxUnderline + property alias checkBoxBold: checkBoxBold + property alias sizeSwitch: sizeSwitch + property alias button: button + + Slider { + id: slider + width: 297 + height: 38 + stepSize: 1 + to: 18 + from: 10 + value: 14 + anchors.topMargin: Theme.baseSize + anchors.top: gridLayout.bottom + anchors.right: gridLayout.right + anchors.left: gridLayout.left + handle: Rectangle { + id: sliderHandle + x: slider.leftPadding + slider.visualPosition * (slider.availableWidth - width) + y: slider.topPadding + slider.availableHeight / 2 - height / 2 + implicitWidth: 26 + implicitHeight: 26 + radius: 13 + color: slider.pressed ? Theme.mainColorDarker : Theme.mainColor + border.color: Theme.gray + } + } + + GridLayout { + id: gridLayout + anchors.top: parent.top + anchors.topMargin: 64 + + anchors.horizontalCenter: parent.horizontalCenter + columnSpacing: Theme.baseSize * 0.5 + rowSpacing: Theme.baseSize * 0.5 + rows: 4 + columns: 2 + + Label { + text: qsTr("Toggle Size") + font: Theme.font + } + + Switch { + id: sizeSwitch + Layout.fillWidth: true + } + + CheckBox { + id: checkBoxBold + text: qsTr("Bold") + checked: true + Layout.fillWidth: true + } + + CheckBox { + id: checkBoxUnderline + text: qsTr("Underline") + Layout.fillWidth: true + } + + Rectangle { + id: rectangle + color: Theme.mainColor + Layout.fillWidth: true + Layout.columnSpan: 2 + Layout.preferredHeight: 38 + Layout.preferredWidth: 297 + } + + Label { + id: label + text: qsTr("Customization") + font: Theme.font + } + + Button { + id: button + text: qsTr("Change Color") + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + } + } +} diff --git a/examples/quickcontrols/flatstyle/doc/images/qtquickcontrols2-flatstyle-creator.png b/examples/quickcontrols/flatstyle/doc/images/qtquickcontrols2-flatstyle-creator.png Binary files differnew file mode 100644 index 0000000000..d77a7ffc4b --- /dev/null +++ b/examples/quickcontrols/flatstyle/doc/images/qtquickcontrols2-flatstyle-creator.png diff --git a/examples/quickcontrols/flatstyle/doc/images/qtquickcontrols2-flatstyle.png b/examples/quickcontrols/flatstyle/doc/images/qtquickcontrols2-flatstyle.png Binary files differnew file mode 100644 index 0000000000..a43b4c39fa --- /dev/null +++ b/examples/quickcontrols/flatstyle/doc/images/qtquickcontrols2-flatstyle.png diff --git a/examples/quickcontrols/flatstyle/doc/src/qtquickcontrols2-flatstyle.qdoc b/examples/quickcontrols/flatstyle/doc/src/qtquickcontrols2-flatstyle.qdoc new file mode 100644 index 0000000000..b077ef71c6 --- /dev/null +++ b/examples/quickcontrols/flatstyle/doc/src/qtquickcontrols2-flatstyle.qdoc @@ -0,0 +1,71 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only + +/*! + \example flatstyle + \keyword Qt Quick Controls - Flat Style + \title Qt Quick Controls - Flat Style + \keyword Qt Quick Controls 2 - Flat Style + \ingroup qtquickcontrols2-examples + \brief A QML app using Qt Quick Controls and a QML plugin + with customized controls. + + \e Flat Style shows how to integrate customized controls into Qt Quick Designer. + The example uses a pure QML plugin to define constants in a singleton. For the + declarative parts of the UI, \c .ui.qml files are used. These can be edited + visually in Qt Quick Designer. + + \borderedimage qtquickcontrols2-flatstyle.png + + \section1 QML Plugin + + The example contains a plugin called Theme. The plugin consists of a QML file + \c Theme.qml and a \c qmldir file. The plugin is located in the imports subdirectory + and added as a resource. + To ensure the plugin is found by QML, we add the import directory to the import + paths of the engine in \c main.cpp. + + \code + ... + engine.addImportPath(":/imports"); + ... + \endcode + + To ensure the code model and Qt Quick Designer can find the plugin, we add the following + line to \e flatstyle.pro. + + \code + QML_IMPORT_PATH = $$PWD/imports + \endcode + + All colors, font parameters, and size constants that are used in this example + are defined as properties in the singleton called \e Theme.qml. + Usually such attribute values are defined as constants as they are not suppose to change at run time. + In this example, we allow the user to change some attributes like the main color, the size parameter, + and some font parameters while the application is running. + + Defining these attribute values in a singleton makes it easy to maintain and change them. + This pattern makes it easy to implement theming. + + \section1 Implementing Custom Controls + + The plugin also contains a style for a couple of controls that implement a custom look and feel. + This style is located in \c Flat and is set as the style for the application in \c qtquickcontrols2.conf. + + The example uses the states of a Qt Quick Item to implement the different states of a control. + This has the advantage that we can define the custom look in Qt Quick Designer and we can easily + verify the different states of a control. + To edit the indicator of a switch in Qt Quick Designer we can open Switch.qml and then enter the implementation + of the indicator called \c switchHandle using the combo box on the top next to the combo box for the open documents. + + \borderedimage qtquickcontrols2-flatstyle-creator.png + + The application itself is just a simple form that allows the user to adjust a couple of parameters of the custom controls. + The user can choose another main color, set the font to bold or underline, and increase the size of the controls by + toggling a switch. + + \e MainForm.ui.qml is just the pure declarative definition of the form, while \e flatstyle.qml instantiates the form + and implements the logic. + + \include examples-run.qdocinc +*/ diff --git a/examples/quickcontrols/flatstyle/flatstyle.pro b/examples/quickcontrols/flatstyle/flatstyle.pro new file mode 100644 index 0000000000..c430a30af4 --- /dev/null +++ b/examples/quickcontrols/flatstyle/flatstyle.pro @@ -0,0 +1,23 @@ +TEMPLATE = app +TARGET = flatstyle + +QT += quick quickcontrols2 widgets + +SOURCES += main.cpp + +RESOURCES += \ + qtquickcontrols2.conf \ + flatstyle.qml \ + MainForm.ui.qml \ + imports/Flat/Button.qml \ + imports/Flat/CheckBox.qml \ + imports/Flat/qmldir \ + imports/Flat/Switch.qml \ + imports/Theme/Theme.qml \ + imports/Theme/qmldir + +# Additional import path used to resolve QML modules in Qt Creator's code model +QML_IMPORT_PATH = $$PWD/imports + +target.path = $$[QT_INSTALL_EXAMPLES]/quickcontrols2/flatstyle +INSTALLS += target diff --git a/examples/quickcontrols/flatstyle/flatstyle.qml b/examples/quickcontrols/flatstyle/flatstyle.qml new file mode 100644 index 0000000000..17b868ba5e --- /dev/null +++ b/examples/quickcontrols/flatstyle/flatstyle.qml @@ -0,0 +1,33 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Controls +import Qt.labs.platform +import Theme + +ApplicationWindow { + id: window + visible: true + minimumWidth: 360 + height: 480 + + title: qsTr("Flat Style") + + MainForm { + id: form + + anchors.fill: parent + button.onClicked: colorDialog.open() + + sizeSwitch.onCheckedChanged: Theme.baseSize = (sizeSwitch.checked ? Theme.largeSize : Theme.smallSize) + checkBoxBold.onCheckedChanged: Theme.font.bold = checkBoxBold.checked + checkBoxUnderline.onCheckedChanged: Theme.font.underline = checkBoxUnderline.checked + slider.onPositionChanged: Theme.font.pixelSize = slider.valueAt(slider.position) + } + + ColorDialog { + id: colorDialog + onCurrentColorChanged: Theme.mainColor = currentColor + } +} diff --git a/examples/quickcontrols/flatstyle/flatstyle.qmlproject b/examples/quickcontrols/flatstyle/flatstyle.qmlproject new file mode 100644 index 0000000000..80b42820ad --- /dev/null +++ b/examples/quickcontrols/flatstyle/flatstyle.qmlproject @@ -0,0 +1,45 @@ +import QmlProject + +Project { + mainFile: "flatstyle.qml" + + /* Include .qml, .js, and image files from current directory and subdirectories */ + QmlFiles { + directory: "." + } + + JavaScriptFiles { + directory: "." + } + + ImageFiles { + directory: "." + } + + Files { + filter: "*.conf" + files: ["qtquickcontrols2.conf"] + } + + Files { + filter: "qmldir" + directory: "." + } + + Files { + filter: "*.ttf;*.otf" + } + + Environment { + QT_QUICK_CONTROLS_CONF: "qtquickcontrols2.conf" + QT_AUTO_SCREEN_SCALE_FACTOR: "1" + } + + qt6Project: true + + /* List of plugin directories passed to QML runtime */ + importPaths: [ ".", "imports" ] + + /* Required for deployment */ + targetDirectory: "/opt/flatstyle" +} diff --git a/examples/quickcontrols/flatstyle/imports/Flat/Button.qml b/examples/quickcontrols/flatstyle/imports/Flat/Button.qml new file mode 100644 index 0000000000..ec8b904a4c --- /dev/null +++ b/examples/quickcontrols/flatstyle/imports/Flat/Button.qml @@ -0,0 +1,70 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Templates as T +import Theme + +T.Button { + id: control + + font: Theme.font + + implicitWidth: Math.max(background ? background.implicitWidth : 0, + contentItem.implicitWidth + leftPadding + rightPadding) + implicitHeight: Math.max(background ? background.implicitHeight : 0, + contentItem.implicitHeight + topPadding + bottomPadding) + leftPadding: 4 + rightPadding: 4 + + background: Rectangle { + id: buttonBackground + implicitWidth: 100 + implicitHeight: 40 + opacity: enabled ? 1 : 0.3 + border.color: Theme.mainColor + border.width: 1 + radius: 2 + + states: [ + State { + name: "normal" + when: !control.down + }, + State { + name: "down" + when: control.down + PropertyChanges { + buttonBackground.border.color: Theme.mainColorDarker + } + } + ] + } + + contentItem: Text { + id: textItem + text: control.text + + font: control.font + opacity: enabled ? 1.0 : 0.3 + color: Theme.mainColor + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + elide: Text.ElideRight + + states: [ + State { + name: "normal" + when: !control.down + }, + State { + name: "down" + when: control.down + PropertyChanges { + textItem.color: Theme.mainColorDarker + } + } + ] + } +} + diff --git a/examples/quickcontrols/flatstyle/imports/Flat/CheckBox.qml b/examples/quickcontrols/flatstyle/imports/Flat/CheckBox.qml new file mode 100644 index 0000000000..ef6a4307a4 --- /dev/null +++ b/examples/quickcontrols/flatstyle/imports/Flat/CheckBox.qml @@ -0,0 +1,92 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Templates as T +import Theme + +T.CheckBox { + id: control + + font: Theme.font + + implicitWidth: Math.max(background ? background.implicitWidth : 0, + contentItem.implicitWidth + leftPadding + rightPadding) + implicitHeight: Math.max(background ? background.implicitHeight : 0, + Math.max(contentItem.implicitHeight, + indicator ? indicator.implicitHeight : 0) + topPadding + bottomPadding) + leftPadding: 4 + indicator: Rectangle { + id: checkboxHandle + implicitWidth: Theme.baseSize * 2.6 + implicitHeight: Theme.baseSize * 2.6 + x: control.leftPadding + anchors.verticalCenter: parent.verticalCenter + radius: 2 + border.color: Theme.mainColor + + Rectangle { + id: rectangle + width: Theme.baseSize * 1.4 + height: Theme.baseSize * 1.4 + x: Theme.baseSize * 0.6 + y: Theme.baseSize * 0.6 + radius: Theme.baseSize * 0.4 + visible: false + color: Theme.mainColor + } + + states: [ + State { + name: "unchecked" + when: !control.checked && !control.down + }, + State { + name: "checked" + when: control.checked && !control.down + + PropertyChanges { + rectangle.visible: true + } + }, + State { + name: "unchecked_down" + when: !control.checked && control.down + + PropertyChanges { + rectangle.color: Theme.mainColorDarker + checkboxHandle.border.color: Theme.mainColorDarker + } + }, + State { + name: "checked_down" + extend: "unchecked_down" + when: control.checked && control.down + + PropertyChanges { + rectangle.visible: true + } + } + ] + } + + background: Rectangle { + implicitWidth: 140 + implicitHeight: Theme.baseSize * 3.8 + color: Theme.lightGray + border.color: Theme.gray + } + + contentItem: Text { + leftPadding: control.indicator.width + 4 + + text: control.text + font: control.font + color: Theme.dark + elide: Text.ElideRight + visible: control.text + horizontalAlignment: Text.AlignLeft + verticalAlignment: Text.AlignVCenter + } +} + diff --git a/examples/quickcontrols/flatstyle/imports/Flat/Switch.qml b/examples/quickcontrols/flatstyle/imports/Flat/Switch.qml new file mode 100644 index 0000000000..25f1a7d49b --- /dev/null +++ b/examples/quickcontrols/flatstyle/imports/Flat/Switch.qml @@ -0,0 +1,88 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Templates as T +import Theme + +T.Switch { + id: control + + implicitWidth: indicator.implicitWidth + implicitHeight: background.implicitHeight + + background: Rectangle { + implicitWidth: 140 + implicitHeight: Theme.baseSize * 3.8 + color: Theme.lightGray + border.color: Theme.gray + } + + leftPadding: 4 + + indicator: Rectangle { + id: switchHandle + implicitWidth: Theme.baseSize * 4.8 + implicitHeight: Theme.baseSize * 2.6 + x: control.leftPadding + anchors.verticalCenter: parent.verticalCenter + radius: Theme.baseSize * 1.3 + color: Theme.light + border.color: Theme.lightGray + + Rectangle { + id: nub + + width: Theme.baseSize * 2.6 + height: Theme.baseSize * 2.6 + radius: Theme.baseSize * 1.3 + color: Theme.light + border.color: Theme.gray + } + + states: [ + State { + name: "off" + when: !control.checked && !control.down + }, + State { + name: "on" + when: control.checked && !control.down + + PropertyChanges { + switchHandle { + color: Theme.mainColor + border.color: Theme.mainColor + } + nub.x: switchHandle.width - nub.width + + } + }, + State { + name: "off_down" + when: !control.checked && control.down + + PropertyChanges { + nub.color: Theme.light + } + + }, + State { + name: "on_down" + extend: "off_down" + when: control.checked && control.down + + PropertyChanges { + nub { + x: switchHandle.width - nub.width + color: Theme.light + } + switchHandle { + color: Theme.mainColorDarker + border.color: Theme.mainColorDarker + } + } + } + ] + } +} diff --git a/examples/quickcontrols/flatstyle/imports/Flat/qmldir b/examples/quickcontrols/flatstyle/imports/Flat/qmldir new file mode 100644 index 0000000000..451a865969 --- /dev/null +++ b/examples/quickcontrols/flatstyle/imports/Flat/qmldir @@ -0,0 +1,5 @@ +module Flat + +Button 1.0 Button.qml +CheckBox 1.0 CheckBox.qml +Switch 1.0 Switch.qml diff --git a/examples/quickcontrols/flatstyle/imports/Theme/Theme.qml b/examples/quickcontrols/flatstyle/imports/Theme/Theme.qml new file mode 100644 index 0000000000..f4d5156989 --- /dev/null +++ b/examples/quickcontrols/flatstyle/imports/Theme/Theme.qml @@ -0,0 +1,27 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +pragma Singleton + +import QtQuick + +QtObject { + readonly property color gray: "#b2b1b1" + readonly property color lightGray: "#dddddd" + readonly property color light: "#ffffff" + readonly property color blue: "#2d548b" + property color mainColor: "#17a81a" + readonly property color dark: "#222222" + readonly property color mainColorDarker: Qt.darker(mainColor, 1.5) + + property int baseSize: 10 + + readonly property int smallSize: 10 + readonly property int largeSize: 16 + + property font font + font.bold: true + font.underline: false + font.pixelSize: 14 + font.family: "arial" +} diff --git a/examples/quickcontrols/flatstyle/imports/Theme/qmldir b/examples/quickcontrols/flatstyle/imports/Theme/qmldir new file mode 100644 index 0000000000..4a58c13a90 --- /dev/null +++ b/examples/quickcontrols/flatstyle/imports/Theme/qmldir @@ -0,0 +1,2 @@ +module Theme +singleton Theme 1.0 Theme.qml diff --git a/examples/quickcontrols/flatstyle/main.cpp b/examples/quickcontrols/flatstyle/main.cpp new file mode 100644 index 0000000000..4aadd92015 --- /dev/null +++ b/examples/quickcontrols/flatstyle/main.cpp @@ -0,0 +1,16 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#include <QApplication> +#include <QQmlApplicationEngine> + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + + QQmlApplicationEngine engine; + engine.addImportPath(":/imports"); + engine.load(QUrl(QStringLiteral("qrc:/flatstyle.qml"))); + + return app.exec(); +} diff --git a/examples/quickcontrols/flatstyle/qtquickcontrols2.conf b/examples/quickcontrols/flatstyle/qtquickcontrols2.conf new file mode 100644 index 0000000000..9cd59e5aa0 --- /dev/null +++ b/examples/quickcontrols/flatstyle/qtquickcontrols2.conf @@ -0,0 +1,2 @@ +[Controls] +Style=Flat diff --git a/examples/quickcontrols/gallery/+Material/ToolBar.qml b/examples/quickcontrols/gallery/+Material/ToolBar.qml new file mode 100644 index 0000000000..f7ecbf116e --- /dev/null +++ b/examples/quickcontrols/gallery/+Material/ToolBar.qml @@ -0,0 +1,8 @@ +// Copyright (C) 2020 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick.Controls.Material + +ToolBar { + Material.foreground: "white" +} diff --git a/examples/quickcontrols/gallery/CMakeLists.txt b/examples/quickcontrols/gallery/CMakeLists.txt new file mode 100644 index 0000000000..d2858c8c59 --- /dev/null +++ b/examples/quickcontrols/gallery/CMakeLists.txt @@ -0,0 +1,104 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +cmake_minimum_required(VERSION 3.16) +project(gallery_controls2 LANGUAGES CXX) + +set(CMAKE_AUTOMOC ON) + +if(NOT DEFINED INSTALL_EXAMPLESDIR) + set(INSTALL_EXAMPLESDIR "examples") +endif() + +set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/quickcontrols2/gallery") + +find_package(Qt6 REQUIRED COMPONENTS Core Gui Quick QuickControls2) + +qt_add_executable(galleryexample WIN32 MACOSX_BUNDLE + gallery.cpp +) + +qt_add_qml_module(galleryexample + URI gallery + VERSION 1.0 + NO_RESOURCE_TARGET_PATH + QML_FILES + "+Material/ToolBar.qml" + "ToolBar.qml" + "gallery.qml" + "pages/BusyIndicatorPage.qml" + "pages/ButtonPage.qml" + "pages/CheckBoxPage.qml" + "pages/ComboBoxPage.qml" + "pages/DelayButtonPage.qml" + "pages/DelegatePage.qml" + "pages/DialPage.qml" + "pages/DialogPage.qml" + "pages/FramePage.qml" + "pages/GroupBoxPage.qml" + "pages/PageIndicatorPage.qml" + "pages/ProgressBarPage.qml" + "pages/RadioButtonPage.qml" + "pages/RangeSliderPage.qml" + "pages/ScrollBarPage.qml" + "pages/ScrollIndicatorPage.qml" + "pages/ScrollablePage.qml" + "pages/SliderPage.qml" + "pages/SpinBoxPage.qml" + "pages/StackViewPage.qml" + "pages/SwipeViewPage.qml" + "pages/SwitchPage.qml" + "pages/TabBarPage.qml" + "pages/TextAreaPage.qml" + "pages/TextFieldPage.qml" + "pages/ToolTipPage.qml" + "pages/TumblerPage.qml" + RESOURCES + "icons/gallery/20x20/back.png" + "icons/gallery/20x20/drawer.png" + "icons/gallery/20x20/menu.png" + "icons/gallery/20x20@2/back.png" + "icons/gallery/20x20@2/drawer.png" + "icons/gallery/20x20@2/menu.png" + "icons/gallery/20x20@3/back.png" + "icons/gallery/20x20@3/drawer.png" + "icons/gallery/20x20@3/menu.png" + "icons/gallery/20x20@4/back.png" + "icons/gallery/20x20@4/drawer.png" + "icons/gallery/20x20@4/menu.png" + "icons/gallery/index.theme" + "images/arrow.png" + "images/arrow@2x.png" + "images/arrow@3x.png" + "images/arrow@4x.png" + "images/arrows.png" + "images/arrows@2x.png" + "images/arrows@3x.png" + "images/arrows@4x.png" + "images/qt-logo.png" + "images/qt-logo@2x.png" + "images/qt-logo@3x.png" + "images/qt-logo@4x.png" + "qmldir" + "qtquickcontrols2.conf" +) + +target_link_libraries(galleryexample PUBLIC + Qt::Core + Qt::Gui + Qt::Quick + Qt::QuickControls2 +) + +if(UNIX AND NOT APPLE AND CMAKE_CROSSCOMPILING) + find_package(Qt6 REQUIRED COMPONENTS QuickTemplates2) + + # Work around QTBUG-86533 + target_link_libraries(galleryexample PRIVATE Qt::QuickTemplates2) +endif() + +install(TARGETS galleryexample + RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" + LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" +) diff --git a/examples/quickcontrols/gallery/ToolBar.qml b/examples/quickcontrols/gallery/ToolBar.qml new file mode 100644 index 0000000000..ffbf422a76 --- /dev/null +++ b/examples/quickcontrols/gallery/ToolBar.qml @@ -0,0 +1,6 @@ +// Copyright (C) 2020 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick.Controls + +ToolBar {} diff --git a/examples/quickcontrols/gallery/doc/images/qtquickcontrols2-gallery-drawer.png b/examples/quickcontrols/gallery/doc/images/qtquickcontrols2-gallery-drawer.png Binary files differnew file mode 100644 index 0000000000..0df43fbc4b --- /dev/null +++ b/examples/quickcontrols/gallery/doc/images/qtquickcontrols2-gallery-drawer.png diff --git a/examples/quickcontrols/gallery/doc/images/qtquickcontrols2-gallery-menu.png b/examples/quickcontrols/gallery/doc/images/qtquickcontrols2-gallery-menu.png Binary files differnew file mode 100644 index 0000000000..3bdaae942a --- /dev/null +++ b/examples/quickcontrols/gallery/doc/images/qtquickcontrols2-gallery-menu.png diff --git a/examples/quickcontrols/gallery/doc/images/qtquickcontrols2-gallery-welcome.png b/examples/quickcontrols/gallery/doc/images/qtquickcontrols2-gallery-welcome.png Binary files differnew file mode 100644 index 0000000000..ded30381d2 --- /dev/null +++ b/examples/quickcontrols/gallery/doc/images/qtquickcontrols2-gallery-welcome.png diff --git a/examples/quickcontrols/gallery/doc/src/qtquickcontrols2-gallery.qdoc b/examples/quickcontrols/gallery/doc/src/qtquickcontrols2-gallery.qdoc new file mode 100644 index 0000000000..814768fe61 --- /dev/null +++ b/examples/quickcontrols/gallery/doc/src/qtquickcontrols2-gallery.qdoc @@ -0,0 +1,39 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only + +/*! + \example gallery + \keyword Qt Quick Controls - Gallery + \title Qt Quick Controls - Gallery + \keyword Qt Quick Controls 2 - Gallery + \ingroup qtquickcontrols2-examples + \brief A gallery of controls. + + \raw HTML + <div class="table"><table style="background:transparent; border:0px"> + <tr><td style="border:0px"> + \endraw + \image qtquickcontrols2-gallery-welcome.png + \caption Welcome Screen + \raw HTML + </td><td style="border:0px"> + \endraw + \image qtquickcontrols2-gallery-drawer.png + \caption Side Drawer + \raw HTML + </td><td style="border:0px"> + \endraw + \image qtquickcontrols2-gallery-menu.png + \caption Options Menu + \raw HTML + </td></tr> + </table></div> + \endraw + + The gallery example is a simple application with a drawer menu that contains + all the \l {Qt Quick Controls}. Each menu item opens a page that shows the + graphical appearance of a control, allows you to interact with the control, + and explains in which circumstances it is handy to use this control. + + \include examples-run.qdocinc +*/ diff --git a/examples/quickcontrols/gallery/gallery.cpp b/examples/quickcontrols/gallery/gallery.cpp new file mode 100644 index 0000000000..0242f93b9f --- /dev/null +++ b/examples/quickcontrols/gallery/gallery.cpp @@ -0,0 +1,50 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#include <QGuiApplication> +#include <QQmlApplicationEngine> +#include <QQmlContext> +#include <QSettings> +#include <QQuickStyle> +#include <QIcon> + +int main(int argc, char *argv[]) +{ + QGuiApplication::setApplicationName("Gallery"); + QGuiApplication::setOrganizationName("QtProject"); + + QGuiApplication app(argc, argv); + + QIcon::setThemeName("gallery"); + + QSettings settings; + if (qEnvironmentVariableIsEmpty("QT_QUICK_CONTROLS_STYLE")) + QQuickStyle::setStyle(settings.value("style").toString()); + + // If this is the first time we're running the application, + // we need to set a style in the settings so that the QML + // can find it in the list of built-in styles. + const QString styleInSettings = settings.value("style").toString(); + if (styleInSettings.isEmpty()) + settings.setValue(QLatin1String("style"), QQuickStyle::name()); + + QQmlApplicationEngine engine; + + QStringList builtInStyles = { QLatin1String("Basic"), QLatin1String("Fusion"), + QLatin1String("Imagine"), QLatin1String("Material"), QLatin1String("Universal") }; +#if defined(Q_OS_MACOS) + builtInStyles << QLatin1String("macOS"); + builtInStyles << QLatin1String("iOS"); +#elif defined(Q_OS_IOS) + builtInStyles << QLatin1String("iOS"); +#elif defined(Q_OS_WINDOWS) + builtInStyles << QLatin1String("Windows"); +#endif + + engine.setInitialProperties({{ "builtInStyles", builtInStyles }}); + engine.load(QUrl("qrc:/gallery.qml")); + if (engine.rootObjects().isEmpty()) + return -1; + + return app.exec(); +} diff --git a/examples/quickcontrols/gallery/gallery.pro b/examples/quickcontrols/gallery/gallery.pro new file mode 100644 index 0000000000..e1ac462a7c --- /dev/null +++ b/examples/quickcontrols/gallery/gallery.pro @@ -0,0 +1,68 @@ +TEMPLATE = app +TARGET = gallery +QT += quick quickcontrols2 + +SOURCES += \ + gallery.cpp + +RESOURCES += \ + gallery.qml \ + pages/BusyIndicatorPage.qml \ + pages/ButtonPage.qml \ + pages/CheckBoxPage.qml \ + pages/ComboBoxPage.qml \ + pages/DelayButtonPage.qml \ + pages/DelegatePage.qml \ + pages/DialogPage.qml \ + pages/DialPage.qml \ + pages/FramePage.qml \ + pages/GroupBoxPage.qml \ + pages/PageIndicatorPage.qml \ + pages/ProgressBarPage.qml \ + pages/RadioButtonPage.qml \ + pages/RangeSliderPage.qml \ + pages/ScrollablePage.qml \ + pages/ScrollBarPage.qml \ + pages/ScrollIndicatorPage.qml \ + pages/SliderPage.qml \ + pages/SpinBoxPage.qml \ + pages/StackViewPage.qml \ + pages/SwipeViewPage.qml \ + pages/SwitchPage.qml \ + pages/TabBarPage.qml \ + pages/TextAreaPage.qml \ + pages/TextFieldPage.qml \ + pages/ToolTipPage.qml \ + pages/TumblerPage.qml \ + qmldir \ + qtquickcontrols2.conf \ + icons/gallery/index.theme \ + icons/gallery/20x20/back.png \ + icons/gallery/20x20/drawer.png \ + icons/gallery/20x20/menu.png \ + icons/gallery/20x20@2/back.png \ + icons/gallery/20x20@2/drawer.png \ + icons/gallery/20x20@2/menu.png \ + icons/gallery/20x20@3/back.png \ + icons/gallery/20x20@3/drawer.png \ + icons/gallery/20x20@3/menu.png \ + icons/gallery/20x20@4/back.png \ + icons/gallery/20x20@4/drawer.png \ + icons/gallery/20x20@4/menu.png \ + images/arrow.png \ + images/arrow@2x.png \ + images/arrow@3x.png \ + images/arrow@4x.png \ + images/arrows.png \ + images/arrows@2x.png \ + images/arrows@3x.png \ + images/arrows@4x.png \ + images/qt-logo.png \ + images/qt-logo@2x.png \ + images/qt-logo@3x.png \ + images/qt-logo@4x.png \ + ToolBar.qml \ + +Material/ToolBar.qml + +target.path = $$[QT_INSTALL_EXAMPLES]/quickcontrols2/gallery +INSTALLS += target diff --git a/examples/quickcontrols/gallery/gallery.qml b/examples/quickcontrols/gallery/gallery.qml new file mode 100644 index 0000000000..35eaed9f11 --- /dev/null +++ b/examples/quickcontrols/gallery/gallery.qml @@ -0,0 +1,295 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtCore +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls + +import "." as App + +ApplicationWindow { + id: window + width: 360 + height: 520 + visible: true + title: "Qt Quick Controls" + + function help() { + let displayingControl = listView.currentIndex !== -1 + let currentControlName = displayingControl + ? listView.model.get(listView.currentIndex).title.toLowerCase() : "" + let url = "https://doc.qt.io/qt-6/" + + (displayingControl + ? "qml-qtquick-controls2-" + currentControlName + ".html" + : "qtquick-controls2-qmlmodule.html"); + Qt.openUrlExternally(url) + } + + required property var builtInStyles + + Settings { + id: settings + property string style + } + + Shortcut { + sequences: ["Esc", "Back"] + enabled: stackView.depth > 1 + onActivated: navigateBackAction.trigger() + } + + Shortcut { + sequence: StandardKey.HelpContents + onActivated: help() + } + + Action { + id: navigateBackAction + icon.name: stackView.depth > 1 ? "back" : "drawer" + onTriggered: { + if (stackView.depth > 1) { + stackView.pop() + listView.currentIndex = -1 + } else { + drawer.open() + } + } + } + + Shortcut { + sequence: "Menu" + onActivated: optionsMenuAction.trigger() + } + + Action { + id: optionsMenuAction + icon.name: "menu" + onTriggered: optionsMenu.open() + } + + header: App.ToolBar { + RowLayout { + spacing: 20 + anchors.fill: parent + + ToolButton { + action: navigateBackAction + } + + Label { + id: titleLabel + text: listView.currentItem ? listView.currentItem.text : "Gallery" + font.pixelSize: 20 + elide: Label.ElideRight + horizontalAlignment: Qt.AlignHCenter + verticalAlignment: Qt.AlignVCenter + Layout.fillWidth: true + } + + ToolButton { + action: optionsMenuAction + + Menu { + id: optionsMenu + x: parent.width - width + transformOrigin: Menu.TopRight + + Action { + text: "Settings" + onTriggered: settingsDialog.open() + } + Action { + text: "Help" + onTriggered: help() + } + Action { + text: "About" + onTriggered: aboutDialog.open() + } + } + } + } + } + + Drawer { + id: drawer + width: Math.min(window.width, window.height) / 3 * 2 + height: window.height + interactive: stackView.depth === 1 + + ListView { + id: listView + + focus: true + currentIndex: -1 + anchors.fill: parent + + delegate: ItemDelegate { + width: listView.width + text: model.title + highlighted: ListView.isCurrentItem + onClicked: { + listView.currentIndex = index + stackView.push(model.source) + drawer.close() + } + } + + model: ListModel { + ListElement { title: "BusyIndicator"; source: "qrc:/pages/BusyIndicatorPage.qml" } + ListElement { title: "Button"; source: "qrc:/pages/ButtonPage.qml" } + ListElement { title: "CheckBox"; source: "qrc:/pages/CheckBoxPage.qml" } + ListElement { title: "ComboBox"; source: "qrc:/pages/ComboBoxPage.qml" } + ListElement { title: "DelayButton"; source: "qrc:/pages/DelayButtonPage.qml" } + ListElement { title: "Dial"; source: "qrc:/pages/DialPage.qml" } + ListElement { title: "Dialog"; source: "qrc:/pages/DialogPage.qml" } + ListElement { title: "Delegates"; source: "qrc:/pages/DelegatePage.qml" } + ListElement { title: "Frame"; source: "qrc:/pages/FramePage.qml" } + ListElement { title: "GroupBox"; source: "qrc:/pages/GroupBoxPage.qml" } + ListElement { title: "PageIndicator"; source: "qrc:/pages/PageIndicatorPage.qml" } + ListElement { title: "ProgressBar"; source: "qrc:/pages/ProgressBarPage.qml" } + ListElement { title: "RadioButton"; source: "qrc:/pages/RadioButtonPage.qml" } + ListElement { title: "RangeSlider"; source: "qrc:/pages/RangeSliderPage.qml" } + ListElement { title: "ScrollBar"; source: "qrc:/pages/ScrollBarPage.qml" } + ListElement { title: "ScrollIndicator"; source: "qrc:/pages/ScrollIndicatorPage.qml" } + ListElement { title: "Slider"; source: "qrc:/pages/SliderPage.qml" } + ListElement { title: "SpinBox"; source: "qrc:/pages/SpinBoxPage.qml" } + ListElement { title: "StackView"; source: "qrc:/pages/StackViewPage.qml" } + ListElement { title: "SwipeView"; source: "qrc:/pages/SwipeViewPage.qml" } + ListElement { title: "Switch"; source: "qrc:/pages/SwitchPage.qml" } + ListElement { title: "TabBar"; source: "qrc:/pages/TabBarPage.qml" } + ListElement { title: "TextArea"; source: "qrc:/pages/TextAreaPage.qml" } + ListElement { title: "TextField"; source: "qrc:/pages/TextFieldPage.qml" } + ListElement { title: "ToolTip"; source: "qrc:/pages/ToolTipPage.qml" } + ListElement { title: "Tumbler"; source: "qrc:/pages/TumblerPage.qml" } + } + + ScrollIndicator.vertical: ScrollIndicator { } + } + } + + StackView { + id: stackView + anchors.fill: parent + + initialItem: Pane { + id: pane + + Image { + id: logo + width: pane.availableWidth / 2 + height: pane.availableHeight / 2 + anchors.centerIn: parent + anchors.verticalCenterOffset: -50 + fillMode: Image.PreserveAspectFit + source: "images/qt-logo.png" + } + + Label { + text: "Qt Quick Controls provides a set of controls that can be used to build complete interfaces in Qt Quick." + anchors.margins: 20 + anchors.top: logo.bottom + anchors.left: parent.left + anchors.right: parent.right + anchors.bottom: arrow.top + horizontalAlignment: Label.AlignHCenter + verticalAlignment: Label.AlignVCenter + wrapMode: Label.Wrap + } + + Image { + id: arrow + source: "images/arrow.png" + anchors.left: parent.left + anchors.bottom: parent.bottom + } + } + } + + Dialog { + id: settingsDialog + x: Math.round((window.width - width) / 2) + y: Math.round(window.height / 6) + width: Math.round(Math.min(window.width, window.height) / 3 * 2) + modal: true + focus: true + title: "Settings" + + standardButtons: Dialog.Ok | Dialog.Cancel + onAccepted: { + settings.style = styleBox.displayText + settingsDialog.close() + } + onRejected: { + styleBox.currentIndex = styleBox.styleIndex + settingsDialog.close() + } + + contentItem: ColumnLayout { + id: settingsColumn + spacing: 20 + + RowLayout { + spacing: 10 + + Label { + text: "Style:" + } + + ComboBox { + id: styleBox + property int styleIndex: -1 + model: window.builtInStyles + Component.onCompleted: { + styleIndex = find(settings.style, Qt.MatchFixedString) + if (styleIndex !== -1) + currentIndex = styleIndex + } + Layout.fillWidth: true + } + } + + Label { + text: "Restart required" + color: "#e41e25" + opacity: styleBox.currentIndex !== styleBox.styleIndex ? 1.0 : 0.0 + horizontalAlignment: Label.AlignHCenter + verticalAlignment: Label.AlignVCenter + Layout.fillWidth: true + Layout.fillHeight: true + } + } + } + + Dialog { + id: aboutDialog + modal: true + focus: true + title: "About" + x: (window.width - width) / 2 + y: window.height / 6 + width: Math.min(window.width, window.height) / 3 * 2 + contentHeight: aboutColumn.height + + Column { + id: aboutColumn + spacing: 20 + + Label { + width: aboutDialog.availableWidth + text: "The Qt Quick Controls module delivers the next generation user interface controls based on Qt Quick." + wrapMode: Label.Wrap + font.pixelSize: 12 + } + + Label { + width: aboutDialog.availableWidth + text: "In comparison to Qt Quick Controls 1, Qt Quick Controls " + + "are an order of magnitude simpler, lighter, and faster." + wrapMode: Label.Wrap + font.pixelSize: 12 + } + } + } +} diff --git a/examples/quickcontrols/gallery/icons/gallery/20x20/back.png b/examples/quickcontrols/gallery/icons/gallery/20x20/back.png Binary files differnew file mode 100644 index 0000000000..1f89ee058c --- /dev/null +++ b/examples/quickcontrols/gallery/icons/gallery/20x20/back.png diff --git a/examples/quickcontrols/gallery/icons/gallery/20x20/drawer.png b/examples/quickcontrols/gallery/icons/gallery/20x20/drawer.png Binary files differnew file mode 100644 index 0000000000..1e974efae8 --- /dev/null +++ b/examples/quickcontrols/gallery/icons/gallery/20x20/drawer.png diff --git a/examples/quickcontrols/gallery/icons/gallery/20x20/menu.png b/examples/quickcontrols/gallery/icons/gallery/20x20/menu.png Binary files differnew file mode 100644 index 0000000000..a10473d9e1 --- /dev/null +++ b/examples/quickcontrols/gallery/icons/gallery/20x20/menu.png diff --git a/examples/quickcontrols/gallery/icons/gallery/20x20@2/back.png b/examples/quickcontrols/gallery/icons/gallery/20x20@2/back.png Binary files differnew file mode 100644 index 0000000000..88e290b132 --- /dev/null +++ b/examples/quickcontrols/gallery/icons/gallery/20x20@2/back.png diff --git a/examples/quickcontrols/gallery/icons/gallery/20x20@2/drawer.png b/examples/quickcontrols/gallery/icons/gallery/20x20@2/drawer.png Binary files differnew file mode 100644 index 0000000000..eba3b6cccf --- /dev/null +++ b/examples/quickcontrols/gallery/icons/gallery/20x20@2/drawer.png diff --git a/examples/quickcontrols/gallery/icons/gallery/20x20@2/menu.png b/examples/quickcontrols/gallery/icons/gallery/20x20@2/menu.png Binary files differnew file mode 100644 index 0000000000..649c2a08c6 --- /dev/null +++ b/examples/quickcontrols/gallery/icons/gallery/20x20@2/menu.png diff --git a/examples/quickcontrols/gallery/icons/gallery/20x20@3/back.png b/examples/quickcontrols/gallery/icons/gallery/20x20@3/back.png Binary files differnew file mode 100644 index 0000000000..4402c7d30b --- /dev/null +++ b/examples/quickcontrols/gallery/icons/gallery/20x20@3/back.png diff --git a/examples/quickcontrols/gallery/icons/gallery/20x20@3/drawer.png b/examples/quickcontrols/gallery/icons/gallery/20x20@3/drawer.png Binary files differnew file mode 100644 index 0000000000..3584ed6d8b --- /dev/null +++ b/examples/quickcontrols/gallery/icons/gallery/20x20@3/drawer.png diff --git a/examples/quickcontrols/gallery/icons/gallery/20x20@3/menu.png b/examples/quickcontrols/gallery/icons/gallery/20x20@3/menu.png Binary files differnew file mode 100644 index 0000000000..9554b6952b --- /dev/null +++ b/examples/quickcontrols/gallery/icons/gallery/20x20@3/menu.png diff --git a/examples/quickcontrols/gallery/icons/gallery/20x20@4/back.png b/examples/quickcontrols/gallery/icons/gallery/20x20@4/back.png Binary files differnew file mode 100644 index 0000000000..9982478c18 --- /dev/null +++ b/examples/quickcontrols/gallery/icons/gallery/20x20@4/back.png diff --git a/examples/quickcontrols/gallery/icons/gallery/20x20@4/drawer.png b/examples/quickcontrols/gallery/icons/gallery/20x20@4/drawer.png Binary files differnew file mode 100644 index 0000000000..60d93aff7b --- /dev/null +++ b/examples/quickcontrols/gallery/icons/gallery/20x20@4/drawer.png diff --git a/examples/quickcontrols/gallery/icons/gallery/20x20@4/menu.png b/examples/quickcontrols/gallery/icons/gallery/20x20@4/menu.png Binary files differnew file mode 100644 index 0000000000..187c171cde --- /dev/null +++ b/examples/quickcontrols/gallery/icons/gallery/20x20@4/menu.png diff --git a/examples/quickcontrols/gallery/icons/gallery/index.theme b/examples/quickcontrols/gallery/icons/gallery/index.theme new file mode 100644 index 0000000000..a1bcd5e03c --- /dev/null +++ b/examples/quickcontrols/gallery/icons/gallery/index.theme @@ -0,0 +1,24 @@ +[Icon Theme] +Name=Gallery +Comment=Qt Quick Controls 2 Gallery Example Icon Theme + +Directories=20x20,20x20@2,20x20@3,20x20@4 + +[20x20] +Size=20 +Type=Fixed + +[20x20@2] +Size=20 +Scale=2 +Type=Fixed + +[20x20@3] +Size=20 +Scale=3 +Type=Fixed + +[20x20@4] +Size=20 +Scale=4 +Type=Fixed diff --git a/examples/quickcontrols/gallery/images/arrow.png b/examples/quickcontrols/gallery/images/arrow.png Binary files differnew file mode 100644 index 0000000000..9835108eb9 --- /dev/null +++ b/examples/quickcontrols/gallery/images/arrow.png diff --git a/examples/quickcontrols/gallery/images/arrow@2x.png b/examples/quickcontrols/gallery/images/arrow@2x.png Binary files differnew file mode 100644 index 0000000000..a5187d48cf --- /dev/null +++ b/examples/quickcontrols/gallery/images/arrow@2x.png diff --git a/examples/quickcontrols/gallery/images/arrow@3x.png b/examples/quickcontrols/gallery/images/arrow@3x.png Binary files differnew file mode 100644 index 0000000000..a512f648c8 --- /dev/null +++ b/examples/quickcontrols/gallery/images/arrow@3x.png diff --git a/examples/quickcontrols/gallery/images/arrow@4x.png b/examples/quickcontrols/gallery/images/arrow@4x.png Binary files differnew file mode 100644 index 0000000000..fd893ebb0d --- /dev/null +++ b/examples/quickcontrols/gallery/images/arrow@4x.png diff --git a/examples/quickcontrols/gallery/images/arrows.png b/examples/quickcontrols/gallery/images/arrows.png Binary files differnew file mode 100644 index 0000000000..3a4cc9b95f --- /dev/null +++ b/examples/quickcontrols/gallery/images/arrows.png diff --git a/examples/quickcontrols/gallery/images/arrows@2x.png b/examples/quickcontrols/gallery/images/arrows@2x.png Binary files differnew file mode 100644 index 0000000000..8c80a2b45b --- /dev/null +++ b/examples/quickcontrols/gallery/images/arrows@2x.png diff --git a/examples/quickcontrols/gallery/images/arrows@3x.png b/examples/quickcontrols/gallery/images/arrows@3x.png Binary files differnew file mode 100644 index 0000000000..22f23cefb9 --- /dev/null +++ b/examples/quickcontrols/gallery/images/arrows@3x.png diff --git a/examples/quickcontrols/gallery/images/arrows@4x.png b/examples/quickcontrols/gallery/images/arrows@4x.png Binary files differnew file mode 100644 index 0000000000..6d1afeef5c --- /dev/null +++ b/examples/quickcontrols/gallery/images/arrows@4x.png diff --git a/examples/quickcontrols/gallery/images/qt-logo.png b/examples/quickcontrols/gallery/images/qt-logo.png Binary files differnew file mode 100644 index 0000000000..dff7729515 --- /dev/null +++ b/examples/quickcontrols/gallery/images/qt-logo.png diff --git a/examples/quickcontrols/gallery/images/qt-logo@2x.png b/examples/quickcontrols/gallery/images/qt-logo@2x.png Binary files differnew file mode 100644 index 0000000000..dbd73aab77 --- /dev/null +++ b/examples/quickcontrols/gallery/images/qt-logo@2x.png diff --git a/examples/quickcontrols/gallery/images/qt-logo@3x.png b/examples/quickcontrols/gallery/images/qt-logo@3x.png Binary files differnew file mode 100644 index 0000000000..68e763b597 --- /dev/null +++ b/examples/quickcontrols/gallery/images/qt-logo@3x.png diff --git a/examples/quickcontrols/gallery/images/qt-logo@4x.png b/examples/quickcontrols/gallery/images/qt-logo@4x.png Binary files differnew file mode 100644 index 0000000000..08fd882572 --- /dev/null +++ b/examples/quickcontrols/gallery/images/qt-logo@4x.png diff --git a/examples/quickcontrols/gallery/pages/BusyIndicatorPage.qml b/examples/quickcontrols/gallery/pages/BusyIndicatorPage.qml new file mode 100644 index 0000000000..616e645688 --- /dev/null +++ b/examples/quickcontrols/gallery/pages/BusyIndicatorPage.qml @@ -0,0 +1,26 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Controls + +ScrollablePage { + id: page + + Column { + spacing: 40 + width: parent.width + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "BusyIndicator is used to indicate activity while content is being loaded," + + " or when the UI is blocked waiting for a resource to become available." + } + + BusyIndicator { + anchors.horizontalCenter: parent.horizontalCenter + } + } +} diff --git a/examples/quickcontrols/gallery/pages/ButtonPage.qml b/examples/quickcontrols/gallery/pages/ButtonPage.qml new file mode 100644 index 0000000000..06051767e9 --- /dev/null +++ b/examples/quickcontrols/gallery/pages/ButtonPage.qml @@ -0,0 +1,44 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls + +ScrollablePage { + id: page + + Column { + spacing: 40 + width: parent.width + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "Button presents a push-button that can be pushed or clicked by the user. " + + "Buttons are normally used to perform an action, or to answer a question." + } + + ColumnLayout { + spacing: 20 + anchors.horizontalCenter: parent.horizontalCenter + + Button { + text: "First" + Layout.fillWidth: true + } + Button { + id: button + text: "Second" + highlighted: true + Layout.fillWidth: true + } + Button { + text: "Third" + enabled: false + Layout.fillWidth: true + } + } + } +} diff --git a/examples/quickcontrols/gallery/pages/CheckBoxPage.qml b/examples/quickcontrols/gallery/pages/CheckBoxPage.qml new file mode 100644 index 0000000000..003e44c82c --- /dev/null +++ b/examples/quickcontrols/gallery/pages/CheckBoxPage.qml @@ -0,0 +1,40 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Controls + +ScrollablePage { + id: page + + Column { + spacing: 40 + width: parent.width + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "CheckBox presents an option button that can be toggled on or off. " + + "Check boxes are typically used to select one or more options from a set of options." + } + + Column { + spacing: 20 + anchors.horizontalCenter: parent.horizontalCenter + + CheckBox { + text: "First" + checked: true + } + CheckBox { + text: "Second" + } + CheckBox { + text: "Third" + checked: true + enabled: false + } + } + } +} diff --git a/examples/quickcontrols/gallery/pages/ComboBoxPage.qml b/examples/quickcontrols/gallery/pages/ComboBoxPage.qml new file mode 100644 index 0000000000..35c3d60d16 --- /dev/null +++ b/examples/quickcontrols/gallery/pages/ComboBoxPage.qml @@ -0,0 +1,50 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Controls + +ScrollablePage { + id: page + + Column { + spacing: 40 + width: parent.width + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "ComboBox is a combined button and popup list. It presents " + + "a list of options to the user that occupies minimal screen space." + } + + ComboBox { + model: ["First", "Second", "Third"] + anchors.horizontalCenter: parent.horizontalCenter + } + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "ComboBox can be made \l editable. An editable combo box auto-" + + "completes its text based on what is available in the model." + } + + ComboBox { + editable: true + model: ListModel { + id: model + ListElement { text: "Banana" } + ListElement { text: "Apple" } + ListElement { text: "Coconut" } + } + onAccepted: { + if (find(editText) === -1) + model.append({text: editText}) + } + anchors.horizontalCenter: parent.horizontalCenter + } + } +} diff --git a/examples/quickcontrols/gallery/pages/DelayButtonPage.qml b/examples/quickcontrols/gallery/pages/DelayButtonPage.qml new file mode 100644 index 0000000000..4c0e8725b9 --- /dev/null +++ b/examples/quickcontrols/gallery/pages/DelayButtonPage.qml @@ -0,0 +1,27 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Controls + +ScrollablePage { + id: page + + Column { + spacing: 40 + width: parent.width + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "DelayButton is a checkable button that incorporates a delay before the " + + "button is activated. This delay prevents accidental presses." + } + + DelayButton { + text: "DelayButton" + anchors.horizontalCenter: parent.horizontalCenter + } + } +} diff --git a/examples/quickcontrols/gallery/pages/DelegatePage.qml b/examples/quickcontrols/gallery/pages/DelegatePage.qml new file mode 100644 index 0000000000..c57388cc6a --- /dev/null +++ b/examples/quickcontrols/gallery/pages/DelegatePage.qml @@ -0,0 +1,173 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls + +Pane { + padding: 0 + + property var delegateComponentMap: { + "ItemDelegate": itemDelegateComponent, + "SwipeDelegate": swipeDelegateComponent, + "CheckDelegate": checkDelegateComponent, + "RadioDelegate": radioDelegateComponent, + "SwitchDelegate": switchDelegateComponent + } + + Component { + id: itemDelegateComponent + + ItemDelegate { + text: labelText + width: parent.width + } + } + + Component { + id: swipeDelegateComponent + + SwipeDelegate { + id: swipeDelegate + text: labelText + width: parent.width + + Component { + id: removeComponent + + Rectangle { + color: SwipeDelegate.pressed ? "#333" : "#444" + width: parent.width + height: parent.height + clip: true + + SwipeDelegate.onClicked: view.model.remove(ourIndex) + + Label { + font.pixelSize: swipeDelegate.font.pixelSize + text: "Remove" + color: "white" + anchors.centerIn: parent + } + } + } + + swipe.left: removeComponent + swipe.right: removeComponent + } + } + + Component { + id: checkDelegateComponent + + CheckDelegate { + text: labelText + } + } + + ButtonGroup { + id: radioButtonGroup + } + + Component { + id: radioDelegateComponent + + RadioDelegate { + text: labelText + ButtonGroup.group: radioButtonGroup + } + } + + Component { + id: switchDelegateComponent + + SwitchDelegate { + text: labelText + } + } + + ColumnLayout { + id: column + spacing: 40 + anchors.fill: parent + anchors.topMargin: 20 + + Label { + Layout.fillWidth: true + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "Delegate controls are used as delegates in views such as ListView." + } + + ListView { + id: listView + Layout.fillWidth: true + Layout.fillHeight: true + clip: true + model: ListModel { + ListElement { type: "ItemDelegate"; text: "ItemDelegate" } + ListElement { type: "ItemDelegate"; text: "ItemDelegate" } + ListElement { type: "ItemDelegate"; text: "ItemDelegate" } + ListElement { type: "SwipeDelegate"; text: "SwipeDelegate" } + ListElement { type: "SwipeDelegate"; text: "SwipeDelegate" } + ListElement { type: "SwipeDelegate"; text: "SwipeDelegate" } + ListElement { type: "CheckDelegate"; text: "CheckDelegate" } + ListElement { type: "CheckDelegate"; text: "CheckDelegate" } + ListElement { type: "CheckDelegate"; text: "CheckDelegate" } + ListElement { type: "RadioDelegate"; text: "RadioDelegate" } + ListElement { type: "RadioDelegate"; text: "RadioDelegate" } + ListElement { type: "RadioDelegate"; text: "RadioDelegate" } + ListElement { type: "SwitchDelegate"; text: "SwitchDelegate" } + ListElement { type: "SwitchDelegate"; text: "SwitchDelegate" } + ListElement { type: "SwitchDelegate"; text: "SwitchDelegate" } + } + + section.property: "type" + section.delegate: Pane { + width: listView.width + height: sectionLabel.implicitHeight + 20 + + Label { + id: sectionLabel + text: section + anchors.centerIn: parent + } + } + + delegate: Loader { + id: delegateLoader + width: listView.width + sourceComponent: delegateComponentMap[text] + + property string labelText: text + property ListView view: listView + property int ourIndex: index + + // Can't find a way to do this in the SwipeDelegate component itself, + // so do it here instead. + SequentialAnimation { + id: removeAnimation + + PropertyAction { + target: delegateLoader + property: "ListView.delayRemove" + value: true + } + NumberAnimation { + target: item + property: "height" + to: 0 + easing.type: Easing.InOutQuad + } + PropertyAction { + target: delegateLoader + property: "ListView.delayRemove" + value: false + } + } + ListView.onRemove: removeAnimation.start() + } + } + } +} diff --git a/examples/quickcontrols/gallery/pages/DialPage.qml b/examples/quickcontrols/gallery/pages/DialPage.qml new file mode 100644 index 0000000000..17c9e090ba --- /dev/null +++ b/examples/quickcontrols/gallery/pages/DialPage.qml @@ -0,0 +1,27 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Controls + +ScrollablePage { + id: page + + Column { + spacing: 40 + width: parent.width + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "The Dial is similar to a traditional dial knob that is found on devices such as " + + "stereos or industrial equipment. It allows the user to specify a value within a range." + } + + Dial { + value: 0.5 + anchors.horizontalCenter: parent.horizontalCenter + } + } +} diff --git a/examples/quickcontrols/gallery/pages/DialogPage.qml b/examples/quickcontrols/gallery/pages/DialogPage.qml new file mode 100644 index 0000000000..982a7f38d4 --- /dev/null +++ b/examples/quickcontrols/gallery/pages/DialogPage.qml @@ -0,0 +1,179 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls + +ScrollablePage { + id: page + + readonly property int buttonWidth: Math.max(button.implicitWidth, Math.min(button.implicitWidth * 2, page.availableWidth / 3)) + + Column { + spacing: 40 + width: parent.width + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "Dialog is a popup that is mostly used for short-term tasks " + + "and brief communications with the user." + } + + Button { + text: "Message" + anchors.horizontalCenter: parent.horizontalCenter + width: buttonWidth + onClicked: messageDialog.open() + + Dialog { + id: messageDialog + + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + + title: "Message" + + Label { + text: "Lorem ipsum dolor sit amet..." + } + } + } + + Button { + id: button + text: "Confirmation" + anchors.horizontalCenter: parent.horizontalCenter + width: buttonWidth + onClicked: confirmationDialog.open() + + Dialog { + id: confirmationDialog + + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + parent: Overlay.overlay + + modal: true + title: "Confirmation" + standardButtons: Dialog.Yes | Dialog.No + + Column { + spacing: 20 + anchors.fill: parent + Label { + text: "The document has been modified.\nDo you want to save your changes?" + } + CheckBox { + text: "Do not ask again" + anchors.right: parent.right + } + } + } + } + + Button { + text: "Content" + anchors.horizontalCenter: parent.horizontalCenter + width: buttonWidth + onClicked: contentDialog.open() + + Dialog { + id: contentDialog + + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + width: Math.min(page.width, page.height) / 3 * 2 + contentHeight: logo.height * 2 + parent: Overlay.overlay + + modal: true + title: "Content" + standardButtons: Dialog.Close + + Flickable { + id: flickable + clip: true + anchors.fill: parent + contentHeight: column.height + + Column { + id: column + spacing: 20 + width: parent.width + + Image { + id: logo + width: parent.width / 2 + anchors.horizontalCenter: parent.horizontalCenter + fillMode: Image.PreserveAspectFit + source: "../images/qt-logo.png" + } + + Label { + width: parent.width + text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc finibus " + + "in est quis laoreet. Interdum et malesuada fames ac ante ipsum primis " + + "in faucibus. Curabitur eget justo sollicitudin enim faucibus bibendum. " + + "Suspendisse potenti. Vestibulum cursus consequat mauris id sollicitudin. " + + "Duis facilisis hendrerit consectetur. Curabitur sapien tortor, efficitur " + + "id auctor nec, efficitur et nisl. Ut venenatis eros in nunc placerat, " + + "eu aliquam enim suscipit." + wrapMode: Label.Wrap + } + } + + ScrollIndicator.vertical: ScrollIndicator { + parent: contentDialog.contentItem + anchors.top: flickable.top + anchors.bottom: flickable.bottom + anchors.right: parent.right + anchors.rightMargin: -contentDialog.rightPadding + 1 + } + } + } + } + + Button { + text: "Input" + anchors.horizontalCenter: parent.horizontalCenter + width: buttonWidth + onClicked: inputDialog.open() + + Dialog { + id: inputDialog + + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + parent: Overlay.overlay + + focus: true + modal: true + title: "Input" + standardButtons: Dialog.Ok | Dialog.Cancel + + ColumnLayout { + spacing: 20 + anchors.fill: parent + Label { + elide: Label.ElideRight + text: "Please enter the credentials:" + Layout.fillWidth: true + } + TextField { + focus: true + placeholderText: "Username" + Layout.fillWidth: true + } + TextField { + placeholderText: "Password" + echoMode: TextField.PasswordEchoOnEdit + Layout.fillWidth: true + } + } + } + } + } +} diff --git a/examples/quickcontrols/gallery/pages/FramePage.qml b/examples/quickcontrols/gallery/pages/FramePage.qml new file mode 100644 index 0000000000..8526442537 --- /dev/null +++ b/examples/quickcontrols/gallery/pages/FramePage.qml @@ -0,0 +1,47 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Controls + +ScrollablePage { + id: page + + readonly property int itemWidth: Math.max(button.implicitWidth, Math.min(button.implicitWidth * 3, page.availableWidth / 3 * 2)) + + Column { + spacing: 40 + width: parent.width + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "Frame is used to layout a logical group of controls together, within a visual frame." + } + + Frame { + anchors.horizontalCenter: parent.horizontalCenter + + Column { + spacing: 20 + width: page.itemWidth + + RadioButton { + text: "First" + checked: true + width: parent.width + } + RadioButton { + id: button + text: "Second" + width: parent.width + } + RadioButton { + text: "Third" + width: parent.width + } + } + } + } +} diff --git a/examples/quickcontrols/gallery/pages/GroupBoxPage.qml b/examples/quickcontrols/gallery/pages/GroupBoxPage.qml new file mode 100644 index 0000000000..9e24d8e6ca --- /dev/null +++ b/examples/quickcontrols/gallery/pages/GroupBoxPage.qml @@ -0,0 +1,48 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Controls + +ScrollablePage { + id: page + + readonly property int itemWidth: Math.max(button.implicitWidth, Math.min(button.implicitWidth * 3, page.availableWidth / 3 * 2)) + + Column { + spacing: 40 + width: parent.width + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "A GroupBox provides a frame, a title on top of it, and a logical group of controls within that frame." + } + + GroupBox { + title: "Title" + anchors.horizontalCenter: parent.horizontalCenter + + Column { + spacing: 20 + width: page.itemWidth + + RadioButton { + text: "First" + checked: true + width: parent.width + } + RadioButton { + id: button + text: "Second" + width: parent.width + } + RadioButton { + text: "Third" + width: parent.width + } + } + } + } +} diff --git a/examples/quickcontrols/gallery/pages/PageIndicatorPage.qml b/examples/quickcontrols/gallery/pages/PageIndicatorPage.qml new file mode 100644 index 0000000000..e83c86563e --- /dev/null +++ b/examples/quickcontrols/gallery/pages/PageIndicatorPage.qml @@ -0,0 +1,27 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Controls + +ScrollablePage { + id: page + + Column { + spacing: 40 + width: parent.width + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "PageIndicator is used to indicate the currently active page in a container of pages." + } + + PageIndicator { + count: 5 + currentIndex: 2 + anchors.horizontalCenter: parent.horizontalCenter + } + } +} diff --git a/examples/quickcontrols/gallery/pages/ProgressBarPage.qml b/examples/quickcontrols/gallery/pages/ProgressBarPage.qml new file mode 100644 index 0000000000..d712aae10c --- /dev/null +++ b/examples/quickcontrols/gallery/pages/ProgressBarPage.qml @@ -0,0 +1,33 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Controls + +ScrollablePage { + id: page + + Column { + spacing: 40 + width: parent.width + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "ProgressBar indicates the progress of an operation. It can be set in an " + + "indeterminate mode to indicate that the length of the operation is unknown." + } + + ProgressBar { + id: bar + value: 0.5 + anchors.horizontalCenter: parent.horizontalCenter + } + + ProgressBar { + indeterminate: true + anchors.horizontalCenter: parent.horizontalCenter + } + } +} diff --git a/examples/quickcontrols/gallery/pages/RadioButtonPage.qml b/examples/quickcontrols/gallery/pages/RadioButtonPage.qml new file mode 100644 index 0000000000..644543c007 --- /dev/null +++ b/examples/quickcontrols/gallery/pages/RadioButtonPage.qml @@ -0,0 +1,39 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Controls + +ScrollablePage { + id: page + + Column { + spacing: 40 + width: parent.width + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "RadioButton presents an option button that can be toggled on or off. " + + "Radio buttons are typically used to select one option from a set of options." + } + + Column { + spacing: 20 + anchors.horizontalCenter: parent.horizontalCenter + + RadioButton { + text: "First" + } + RadioButton { + text: "Second" + checked: true + } + RadioButton { + text: "Third" + enabled: false + } + } + } +} diff --git a/examples/quickcontrols/gallery/pages/RangeSliderPage.qml b/examples/quickcontrols/gallery/pages/RangeSliderPage.qml new file mode 100644 index 0000000000..0ca235822f --- /dev/null +++ b/examples/quickcontrols/gallery/pages/RangeSliderPage.qml @@ -0,0 +1,35 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Controls + +ScrollablePage { + id: page + + Column { + spacing: 40 + width: parent.width + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "RangeSlider is used to select a range specified by two values, by sliding each handle along a track." + } + + RangeSlider { + id: slider + first.value: 0.25 + second.value: 0.75 + anchors.horizontalCenter: parent.horizontalCenter + } + + RangeSlider { + orientation: Qt.Vertical + first.value: 0.25 + second.value: 0.75 + anchors.horizontalCenter: parent.horizontalCenter + } + } +} diff --git a/examples/quickcontrols/gallery/pages/ScrollBarPage.qml b/examples/quickcontrols/gallery/pages/ScrollBarPage.qml new file mode 100644 index 0000000000..248e74ca7f --- /dev/null +++ b/examples/quickcontrols/gallery/pages/ScrollBarPage.qml @@ -0,0 +1,40 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Controls + +Flickable { + id: flickable + + contentHeight: pane.height + + Pane { + id: pane + width: flickable.width + height: flickable.height * 1.25 + + Column { + id: column + spacing: 40 + width: parent.width + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "ScrollBar is an interactive bar that can be used to scroll to a specific position. " + + "A scroll bar can be either vertical or horizontal, and can be attached to any Flickable, " + + "such as ListView and GridView." + } + + Image { + rotation: 90 + source: "../images/arrows.png" + anchors.horizontalCenter: parent.horizontalCenter + } + } + } + + ScrollBar.vertical: ScrollBar { } +} diff --git a/examples/quickcontrols/gallery/pages/ScrollIndicatorPage.qml b/examples/quickcontrols/gallery/pages/ScrollIndicatorPage.qml new file mode 100644 index 0000000000..04ce97483a --- /dev/null +++ b/examples/quickcontrols/gallery/pages/ScrollIndicatorPage.qml @@ -0,0 +1,40 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Controls + +Flickable { + id: flickable + + contentHeight: pane.height + + Pane { + id: pane + width: flickable.width + height: flickable.height * 1.25 + + Column { + id: column + spacing: 40 + width: parent.width + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "ScrollIndicator is a non-interactive indicator that indicates the current scroll position. " + + "A scroll indicator can be either vertical or horizontal, and can be attached to any Flickable, " + + "such as ListView and GridView." + } + + Image { + rotation: 90 + source: "../images/arrows.png" + anchors.horizontalCenter: parent.horizontalCenter + } + } + } + + ScrollIndicator.vertical: ScrollIndicator { } +} diff --git a/examples/quickcontrols/gallery/pages/ScrollablePage.qml b/examples/quickcontrols/gallery/pages/ScrollablePage.qml new file mode 100644 index 0000000000..69bc0cd973 --- /dev/null +++ b/examples/quickcontrols/gallery/pages/ScrollablePage.qml @@ -0,0 +1,24 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Controls + +Page { + id: page + + default property alias content: pane.contentItem + + Flickable { + anchors.fill: parent + contentHeight: pane.implicitHeight + flickableDirection: Flickable.AutoFlickIfNeeded + + Pane { + id: pane + width: parent.width + } + + ScrollIndicator.vertical: ScrollIndicator { } + } +} diff --git a/examples/quickcontrols/gallery/pages/SliderPage.qml b/examples/quickcontrols/gallery/pages/SliderPage.qml new file mode 100644 index 0000000000..fd03680a0e --- /dev/null +++ b/examples/quickcontrols/gallery/pages/SliderPage.qml @@ -0,0 +1,33 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Controls + +ScrollablePage { + id: page + + Column { + spacing: 40 + width: parent.width + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "Slider is used to select a value by sliding a handle along a track." + } + + Slider { + id: slider + value: 0.5 + anchors.horizontalCenter: parent.horizontalCenter + } + + Slider { + orientation: Qt.Vertical + value: 0.5 + anchors.horizontalCenter: parent.horizontalCenter + } + } +} diff --git a/examples/quickcontrols/gallery/pages/SpinBoxPage.qml b/examples/quickcontrols/gallery/pages/SpinBoxPage.qml new file mode 100644 index 0000000000..18c9b06c1f --- /dev/null +++ b/examples/quickcontrols/gallery/pages/SpinBoxPage.qml @@ -0,0 +1,29 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Controls + +ScrollablePage { + id: page + + Column { + spacing: 40 + width: parent.width + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "SpinBox allows the user to choose an integer value by clicking the up or down indicator buttons, " + + "by pressing up or down on the keyboard, or by entering a text value in the input field." + } + + SpinBox { + id: box + value: 50 + anchors.horizontalCenter: parent.horizontalCenter + editable: true + } + } +} diff --git a/examples/quickcontrols/gallery/pages/StackViewPage.qml b/examples/quickcontrols/gallery/pages/StackViewPage.qml new file mode 100644 index 0000000000..4472150e56 --- /dev/null +++ b/examples/quickcontrols/gallery/pages/StackViewPage.qml @@ -0,0 +1,49 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Controls + +StackView { + id: stackView + initialItem: page + + Component { + id: page + + Pane { + id: pane + width: parent ? parent.width : 0 // TODO: fix null parent on destruction + + Column { + spacing: 40 + width: parent.width + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "StackView provides a stack-based navigation model which can be used with a set of interlinked pages. " + + "Items are pushed onto the stack as the user navigates deeper into the material, and popped off again " + + "when he chooses to go back." + } + + Button { + id: button + text: "Push" + anchors.horizontalCenter: parent.horizontalCenter + width: Math.max(button.implicitWidth, Math.min(button.implicitWidth * 2, pane.availableWidth / 3)) + onClicked: stackView.push(page) + } + + Button { + text: "Pop" + enabled: stackView.depth > 1 + width: Math.max(button.implicitWidth, Math.min(button.implicitWidth * 2, pane.availableWidth / 3)) + anchors.horizontalCenter: parent.horizontalCenter + onClicked: stackView.pop() + } + } + } + } +} diff --git a/examples/quickcontrols/gallery/pages/SwipeViewPage.qml b/examples/quickcontrols/gallery/pages/SwipeViewPage.qml new file mode 100644 index 0000000000..f982f4cf26 --- /dev/null +++ b/examples/quickcontrols/gallery/pages/SwipeViewPage.qml @@ -0,0 +1,49 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Controls + +Pane { + id: pane + + SwipeView { + id: view + currentIndex: 1 + anchors.fill: parent + + Repeater { + model: 3 + + Pane { + width: view.width + height: view.height + + Column { + spacing: 40 + width: parent.width + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "SwipeView provides a navigation model that simplifies horizontal paged scrolling. " + + "The page indicator on the bottom shows which is the presently active page." + } + + Image { + source: "../images/arrows.png" + anchors.horizontalCenter: parent.horizontalCenter + } + } + } + } + } + + PageIndicator { + count: view.count + currentIndex: view.currentIndex + anchors.bottom: parent.bottom + anchors.horizontalCenter: parent.horizontalCenter + } +} diff --git a/examples/quickcontrols/gallery/pages/SwitchPage.qml b/examples/quickcontrols/gallery/pages/SwitchPage.qml new file mode 100644 index 0000000000..cca200582e --- /dev/null +++ b/examples/quickcontrols/gallery/pages/SwitchPage.qml @@ -0,0 +1,39 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Controls + +ScrollablePage { + id: page + + Column { + spacing: 40 + width: parent.width + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "Switch is an option button that can be dragged or toggled on or off. " + + "Switches are typically used to select between two states." + } + + Column { + spacing: 20 + anchors.horizontalCenter: parent.horizontalCenter + + Switch { + text: "First" + } + Switch { + text: "Second" + checked: true + } + Switch { + text: "Third" + enabled: false + } + } + } +} diff --git a/examples/quickcontrols/gallery/pages/TabBarPage.qml b/examples/quickcontrols/gallery/pages/TabBarPage.qml new file mode 100644 index 0000000000..c03e4a014c --- /dev/null +++ b/examples/quickcontrols/gallery/pages/TabBarPage.qml @@ -0,0 +1,57 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Controls + +Page { + id: page + + SwipeView { + id: swipeView + anchors.fill: parent + currentIndex: tabBar.currentIndex + + Repeater { + model: 3 + + Pane { + width: swipeView.width + height: swipeView.height + + Column { + spacing: 40 + width: parent.width + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "TabBar is a bar with icons or text which allows the user " + + "to switch between different subtasks, views, or modes." + } + + Image { + source: "../images/arrows.png" + anchors.horizontalCenter: parent.horizontalCenter + } + } + } + } + } + + footer: TabBar { + id: tabBar + currentIndex: swipeView.currentIndex + + TabButton { + text: "First" + } + TabButton { + text: "Second" + } + TabButton { + text: "Third" + } + } +} diff --git a/examples/quickcontrols/gallery/pages/TextAreaPage.qml b/examples/quickcontrols/gallery/pages/TextAreaPage.qml new file mode 100644 index 0000000000..6a09846973 --- /dev/null +++ b/examples/quickcontrols/gallery/pages/TextAreaPage.qml @@ -0,0 +1,29 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Controls + +ScrollablePage { + id: page + + Column { + spacing: 40 + width: parent.width + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "TextArea is a multi-line text editor." + } + + TextArea { + width: pane.availableWidth / 3 + anchors.horizontalCenter: parent.horizontalCenter + + wrapMode: TextArea.Wrap + text: "TextArea\n...\n...\n..." + } + } +} diff --git a/examples/quickcontrols/gallery/pages/TextFieldPage.qml b/examples/quickcontrols/gallery/pages/TextFieldPage.qml new file mode 100644 index 0000000000..2b06894c8f --- /dev/null +++ b/examples/quickcontrols/gallery/pages/TextFieldPage.qml @@ -0,0 +1,27 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Controls + +ScrollablePage { + id: page + + Column { + spacing: 40 + width: parent.width + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "TextField is a single-line text editor." + } + + TextField { + id: field + placeholderText: "TextField" + anchors.horizontalCenter: parent.horizontalCenter + } + } +} diff --git a/examples/quickcontrols/gallery/pages/ToolTipPage.qml b/examples/quickcontrols/gallery/pages/ToolTipPage.qml new file mode 100644 index 0000000000..dd92c89b4f --- /dev/null +++ b/examples/quickcontrols/gallery/pages/ToolTipPage.qml @@ -0,0 +1,30 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Controls + +ScrollablePage { + id: page + + Column { + spacing: 40 + width: parent.width + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "A tool tip is a short piece of text that informs the user of a control's function." + } + + Button { + text: "Tip" + anchors.horizontalCenter: parent.horizontalCenter + + ToolTip.timeout: 5000 + ToolTip.visible: pressed + ToolTip.text: "This is a tool tip." + } + } +} diff --git a/examples/quickcontrols/gallery/pages/TumblerPage.qml b/examples/quickcontrols/gallery/pages/TumblerPage.qml new file mode 100644 index 0000000000..4d01f02e89 --- /dev/null +++ b/examples/quickcontrols/gallery/pages/TumblerPage.qml @@ -0,0 +1,26 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Controls + +ScrollablePage { + id: page + + Column { + spacing: 40 + width: parent.width + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "Tumbler is used to select a value by spinning a wheel." + } + + Tumbler { + model: 10 + anchors.horizontalCenter: parent.horizontalCenter + } + } +} diff --git a/examples/quickcontrols/gallery/qmldir b/examples/quickcontrols/gallery/qmldir new file mode 100644 index 0000000000..6b7f86bfac --- /dev/null +++ b/examples/quickcontrols/gallery/qmldir @@ -0,0 +1 @@ +module App diff --git a/examples/quickcontrols/gallery/qtquickcontrols2.conf b/examples/quickcontrols/gallery/qtquickcontrols2.conf new file mode 100644 index 0000000000..da1a8f41d2 --- /dev/null +++ b/examples/quickcontrols/gallery/qtquickcontrols2.conf @@ -0,0 +1,8 @@ +[Material] +Primary=#41cd52 +Accent=#41cd52 +Theme=System + +[Universal] +Accent=#41cd52 +Theme=System diff --git a/examples/quickcontrols/imagine/automotive/CMakeLists.txt b/examples/quickcontrols/imagine/automotive/CMakeLists.txt new file mode 100644 index 0000000000..2f213f8e79 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/CMakeLists.txt @@ -0,0 +1,146 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +cmake_minimum_required(VERSION 3.16) +project(automotive LANGUAGES CXX) + +set(CMAKE_AUTOMOC ON) + +if(NOT DEFINED INSTALL_EXAMPLESDIR) + set(INSTALL_EXAMPLESDIR "examples") +endif() + +set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/quickcontrols2/imagine/automotive") + +find_package(Qt6 REQUIRED COMPONENTS Core Gui Quick QuickControls2) + +qt_add_executable(automotiveexample WIN32 MACOSX_BUNDLE + automotive.cpp +) + +qt_add_qml_module(automotiveexample + URI automotive + VERSION 1.0 + NO_RESOURCE_TARGET_PATH + QML_FILES + "qml/FeatureButton.qml" + "qml/LargeLabel.qml" + "qml/automotive.qml" + + RESOURCES + "icons/automotive/44x44/air-con.png" + "icons/automotive/44x44/command.png" + "icons/automotive/44x44/message.png" + "icons/automotive/44x44/music.png" + "icons/automotive/44x44/seats.png" + "icons/automotive/44x44/settings.png" + "icons/automotive/44x44/statistics.png" + "icons/automotive/44x44/windows.png" + "icons/automotive/44x44@2/air-con.png" + "icons/automotive/44x44@2/command.png" + "icons/automotive/44x44@2/message.png" + "icons/automotive/44x44@2/music.png" + "icons/automotive/44x44@2/navigation.png" + "icons/automotive/44x44@2/seats.png" + "icons/automotive/44x44@2/settings.png" + "icons/automotive/44x44@2/statistics.png" + "icons/automotive/44x44@2/windows.png" + "icons/automotive/icons.svg" + "icons/automotive/index.theme" + "icons/car.png" + "icons/car@2x.png" + "icons/warning.png" + "icons/warning@2x.png" + "icons/weather.png" + "icons/weather@2x.png" + "imagine-assets/applicationwindow-background.png" + "imagine-assets/applicationwindow-background@2x.png" + "imagine-assets/button-background-checked-hovered.9.png" + "imagine-assets/button-background-checked-hovered@2x.9.png" + "imagine-assets/button-background-checked.9.png" + "imagine-assets/button-background-checked@2x.9.png" + "imagine-assets/button-background-hovered.9.png" + "imagine-assets/button-background-hovered@2x.9.png" + "imagine-assets/button-background-pressed.9.png" + "imagine-assets/button-background-pressed@2x.9.png" + "imagine-assets/button-background.9.png" + "imagine-assets/button-background@2x.9.png" + "imagine-assets/dial-background-hovered.png" + "imagine-assets/dial-background-hovered@2x.png" + "imagine-assets/dial-background-pressed.png" + "imagine-assets/dial-background-pressed@2x.png" + "imagine-assets/dial-background.png" + "imagine-assets/dial-background@2x.png" + "imagine-assets/dial-handle-pressed.png" + "imagine-assets/dial-handle-pressed@2x.png" + "imagine-assets/dial-handle.png" + "imagine-assets/dial-handle@2x.png" + "imagine-assets/frame-background.9.png" + "imagine-assets/frame-background@2x.9.png" + "imagine-assets/itemdelegate-background-checked.9.png" + "imagine-assets/itemdelegate-background-checked@2x.9.png" + "imagine-assets/itemdelegate-background-hovered.9.png" + "imagine-assets/itemdelegate-background-hovered@2x.9.png" + "imagine-assets/itemdelegate-background-pressed.9.png" + "imagine-assets/itemdelegate-background-pressed@2x.9.png" + "imagine-assets/itemdelegate-background.9.png" + "imagine-assets/itemdelegate-background@2x.9.png" + "imagine-assets/radiobutton-indicator-checked-hovered.png" + "imagine-assets/radiobutton-indicator-checked-hovered@2x.png" + "imagine-assets/radiobutton-indicator-checked-pressed.png" + "imagine-assets/radiobutton-indicator-checked-pressed@2x.png" + "imagine-assets/radiobutton-indicator-checked.png" + "imagine-assets/radiobutton-indicator-checked@2x.png" + "imagine-assets/radiobutton-indicator-hovered.png" + "imagine-assets/radiobutton-indicator-hovered@2x.png" + "imagine-assets/radiobutton-indicator-pressed.png" + "imagine-assets/radiobutton-indicator-pressed@2x.png" + "imagine-assets/radiobutton-indicator.png" + "imagine-assets/radiobutton-indicator@2x.png" + "imagine-assets/scrollindicator-handle.png" + "imagine-assets/scrollindicator-handle@2x.png" + "imagine-assets/slider-background-horizontal.9.png" + "imagine-assets/slider-background-horizontal@2x.9.png" + "imagine-assets/slider-handle-hovered.png" + "imagine-assets/slider-handle-hovered@2x.png" + "imagine-assets/slider-handle-pressed.png" + "imagine-assets/slider-handle-pressed@2x.png" + "imagine-assets/slider-handle.png" + "imagine-assets/slider-handle@2x.png" + "imagine-assets/slider-progress-horizontal-pressed.9.png" + "imagine-assets/slider-progress-horizontal-pressed@2x.9.png" + "imagine-assets/slider-progress-horizontal.9.png" + "imagine-assets/slider-progress-horizontal@2x.9.png" + "imagine-assets/switchdelegate-background.9.png" + "imagine-assets/switchdelegate-background@2x.9.png" + "imagine-assets/switchdelegate-handle-checked-hovered.png" + "imagine-assets/switchdelegate-handle-checked-hovered@2x.png" + "imagine-assets/switchdelegate-handle-checked.png" + "imagine-assets/switchdelegate-handle-checked@2x.png" + "imagine-assets/switchdelegate-handle-hovered.png" + "imagine-assets/switchdelegate-handle-hovered@2x.png" + "imagine-assets/switchdelegate-handle-pressed.png" + "imagine-assets/switchdelegate-handle-pressed@2x.png" + "imagine-assets/switchdelegate-handle.png" + "imagine-assets/switchdelegate-handle@2x.png" + "imagine-assets/switchdelegate-indicator-pressed.png" + "imagine-assets/switchdelegate-indicator-pressed@2x.png" + "imagine-assets/switchdelegate-indicator.png" + "imagine-assets/switchdelegate-indicator@2x.png" + "imagine-assets/toolseparator-separator-vertical.9.png" + "imagine-assets/toolseparator-separator-vertical@2x.9.png" + "qtquickcontrols2.conf" +) + +target_link_libraries(automotiveexample PUBLIC + Qt::Core + Qt::Gui + Qt::Quick + Qt::QuickControls2 +) + +install(TARGETS automotiveexample + RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" + LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" +) diff --git a/examples/quickcontrols/imagine/automotive/automotive.cpp b/examples/quickcontrols/imagine/automotive/automotive.cpp new file mode 100644 index 0000000000..e64780f2b1 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/automotive.cpp @@ -0,0 +1,26 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#include <QGuiApplication> +#include <QQmlApplicationEngine> +#include <QQmlContext> +#include <QSettings> +#include <QQuickStyle> +#include <QIcon> + +int main(int argc, char *argv[]) +{ + QGuiApplication::setApplicationName("Automotive"); + QGuiApplication::setOrganizationName("QtProject"); + + QGuiApplication app(argc, argv); + + QIcon::setThemeName("automotive"); + + QQmlApplicationEngine engine; + engine.load(QUrl("qrc:/qml/automotive.qml")); + if (engine.rootObjects().isEmpty()) + return -1; + + return app.exec(); +} diff --git a/examples/quickcontrols/imagine/automotive/automotive.pro b/examples/quickcontrols/imagine/automotive/automotive.pro new file mode 100644 index 0000000000..890e63d84b --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/automotive.pro @@ -0,0 +1,15 @@ +TEMPLATE = app +TARGET = automotive +QT += quick quickcontrols2 + +SOURCES += \ + automotive.cpp + +RESOURCES += \ + icons/icons.qrc \ + imagine-assets/imagine-assets.qrc \ + qml/qml.qrc \ + qtquickcontrols2.conf + +target.path = $$[QT_INSTALL_EXAMPLES]/quickcontrols2/imagine/automotive +INSTALLS += target diff --git a/examples/quickcontrols/imagine/automotive/doc/images/qtquickcontrols2-automotive.png b/examples/quickcontrols/imagine/automotive/doc/images/qtquickcontrols2-automotive.png Binary files differnew file mode 100644 index 0000000000..93ea28545b --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/doc/images/qtquickcontrols2-automotive.png diff --git a/examples/quickcontrols/imagine/automotive/doc/src/qtquickcontrols2-automotive.qdoc b/examples/quickcontrols/imagine/automotive/doc/src/qtquickcontrols2-automotive.qdoc new file mode 100644 index 0000000000..6e228efd8e --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/doc/src/qtquickcontrols2-automotive.qdoc @@ -0,0 +1,18 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only + +/*! + \example imagine/automotive + \keyword Qt Quick Controls - Imagine Style Example: Automotive + \title Qt Quick Controls - Imagine Style Example: Automotive + \keyword Qt Quick Controls 2 - Imagine Style Example: Automotive + \ingroup qtquickcontrols2-examples + \brief An automotive user interface using custom Imagine style assets. + + This example demonstrates how custom Imagine style assets can be used to + style an automotive user interface. + + \image qtquickcontrols2-automotive.png + + \include examples-run.qdocinc +*/ diff --git a/examples/quickcontrols/imagine/automotive/icons/automotive/44x44/air-con.png b/examples/quickcontrols/imagine/automotive/icons/automotive/44x44/air-con.png Binary files differnew file mode 100644 index 0000000000..70175f6f05 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/icons/automotive/44x44/air-con.png diff --git a/examples/quickcontrols/imagine/automotive/icons/automotive/44x44/command.png b/examples/quickcontrols/imagine/automotive/icons/automotive/44x44/command.png Binary files differnew file mode 100644 index 0000000000..8f712c7881 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/icons/automotive/44x44/command.png diff --git a/examples/quickcontrols/imagine/automotive/icons/automotive/44x44/message.png b/examples/quickcontrols/imagine/automotive/icons/automotive/44x44/message.png Binary files differnew file mode 100644 index 0000000000..7773ca63ba --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/icons/automotive/44x44/message.png diff --git a/examples/quickcontrols/imagine/automotive/icons/automotive/44x44/music.png b/examples/quickcontrols/imagine/automotive/icons/automotive/44x44/music.png Binary files differnew file mode 100644 index 0000000000..dc73322bfe --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/icons/automotive/44x44/music.png diff --git a/examples/quickcontrols/imagine/automotive/icons/automotive/44x44/seats.png b/examples/quickcontrols/imagine/automotive/icons/automotive/44x44/seats.png Binary files differnew file mode 100644 index 0000000000..2f9eaa6227 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/icons/automotive/44x44/seats.png diff --git a/examples/quickcontrols/imagine/automotive/icons/automotive/44x44/settings.png b/examples/quickcontrols/imagine/automotive/icons/automotive/44x44/settings.png Binary files differnew file mode 100644 index 0000000000..b65598b58c --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/icons/automotive/44x44/settings.png diff --git a/examples/quickcontrols/imagine/automotive/icons/automotive/44x44/statistics.png b/examples/quickcontrols/imagine/automotive/icons/automotive/44x44/statistics.png Binary files differnew file mode 100644 index 0000000000..979702989b --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/icons/automotive/44x44/statistics.png diff --git a/examples/quickcontrols/imagine/automotive/icons/automotive/44x44/windows.png b/examples/quickcontrols/imagine/automotive/icons/automotive/44x44/windows.png Binary files differnew file mode 100644 index 0000000000..8ed8cec4bf --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/icons/automotive/44x44/windows.png diff --git a/examples/quickcontrols/imagine/automotive/icons/automotive/44x44@2/air-con.png b/examples/quickcontrols/imagine/automotive/icons/automotive/44x44@2/air-con.png Binary files differnew file mode 100644 index 0000000000..8822979e6a --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/icons/automotive/44x44@2/air-con.png diff --git a/examples/quickcontrols/imagine/automotive/icons/automotive/44x44@2/command.png b/examples/quickcontrols/imagine/automotive/icons/automotive/44x44@2/command.png Binary files differnew file mode 100644 index 0000000000..918e2b69eb --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/icons/automotive/44x44@2/command.png diff --git a/examples/quickcontrols/imagine/automotive/icons/automotive/44x44@2/message.png b/examples/quickcontrols/imagine/automotive/icons/automotive/44x44@2/message.png Binary files differnew file mode 100644 index 0000000000..1debfdfb26 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/icons/automotive/44x44@2/message.png diff --git a/examples/quickcontrols/imagine/automotive/icons/automotive/44x44@2/music.png b/examples/quickcontrols/imagine/automotive/icons/automotive/44x44@2/music.png Binary files differnew file mode 100644 index 0000000000..01a3ece417 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/icons/automotive/44x44@2/music.png diff --git a/examples/quickcontrols/imagine/automotive/icons/automotive/44x44@2/navigation.png b/examples/quickcontrols/imagine/automotive/icons/automotive/44x44@2/navigation.png Binary files differnew file mode 100644 index 0000000000..3a18fb5f4e --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/icons/automotive/44x44@2/navigation.png diff --git a/examples/quickcontrols/imagine/automotive/icons/automotive/44x44@2/seats.png b/examples/quickcontrols/imagine/automotive/icons/automotive/44x44@2/seats.png Binary files differnew file mode 100644 index 0000000000..7d67f1be3f --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/icons/automotive/44x44@2/seats.png diff --git a/examples/quickcontrols/imagine/automotive/icons/automotive/44x44@2/settings.png b/examples/quickcontrols/imagine/automotive/icons/automotive/44x44@2/settings.png Binary files differnew file mode 100644 index 0000000000..3ce2a1f1b4 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/icons/automotive/44x44@2/settings.png diff --git a/examples/quickcontrols/imagine/automotive/icons/automotive/44x44@2/statistics.png b/examples/quickcontrols/imagine/automotive/icons/automotive/44x44@2/statistics.png Binary files differnew file mode 100644 index 0000000000..afc2cc0906 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/icons/automotive/44x44@2/statistics.png diff --git a/examples/quickcontrols/imagine/automotive/icons/automotive/44x44@2/windows.png b/examples/quickcontrols/imagine/automotive/icons/automotive/44x44@2/windows.png Binary files differnew file mode 100644 index 0000000000..59bac584ed --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/icons/automotive/44x44@2/windows.png diff --git a/examples/quickcontrols/imagine/automotive/icons/automotive/icons.svg b/examples/quickcontrols/imagine/automotive/icons/automotive/icons.svg new file mode 100644 index 0000000000..daf4633c25 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/icons/automotive/icons.svg @@ -0,0 +1,526 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="449" + height="384.99988" + viewBox="0 0 449.00001 384.99988" + id="svg2" + version="1.1" + inkscape:version="0.92.1 r15371" + sodipodi:docname="icons.svg" + inkscape:export-filename="/home/mitch/dev/qqc2-futuristic-style-demo/icons/futuristic/44x44@2/settings.png" + inkscape:export-xdpi="180" + inkscape:export-ydpi="180"> + <defs + id="defs4" /> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="2.3750001" + inkscape:cx="227.69632" + inkscape:cy="173.66895" + inkscape:document-units="px" + inkscape:current-layer="layer1" + showgrid="true" + units="px" + inkscape:window-width="1920" + inkscape:window-height="1137" + inkscape:window-x="-8" + inkscape:window-y="-8" + inkscape:window-maximized="1" + showguides="true" + inkscape:snap-grids="false" + inkscape:snap-midpoints="false" + inkscape:object-paths="false" + inkscape:guide-bbox="true" + fit-margin-top="0" + fit-margin-left="0" + fit-margin-right="0" + fit-margin-bottom="0"> + <inkscape:grid + type="xygrid" + id="grid4380" + originx="-0.042045451" + originy="0.87827274" /> + </sodipodi:namedview> + <metadata + id="metadata7"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1" + transform="translate(-0.04204545,-668.2406)" + style="display:inline"> + <g + id="g4481" + inkscape:export-filename="C:\dev\qt5.10\qtquickcontrols2\examples\quickcontrols2\imagine\automotive\icons\automotive\44x44@4\navigation.png" + inkscape:export-xdpi="384" + inkscape:export-ydpi="384"> + <rect + y="1009.2405" + x="180.04205" + height="44" + width="44" + id="rect4273" + style="opacity:1;fill:#dc7878;fill-opacity:0;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + <path + inkscape:connector-curvature="0" + id="path4147" + d="m 187.6832,1027.7359 29.7995,-11.9955 -8.46002,30.1783 -5.42957,-15.5311 z" + style="fill:none;fill-rule:evenodd;stroke:#6affcd;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> + </g> + <g + id="g4474" + inkscape:export-filename="C:\dev\qt5.10\qtquickcontrols2\examples\quickcontrols2\imagine\automotive\icons\automotive\44x44@4\music.png" + inkscape:export-xdpi="384" + inkscape:export-ydpi="384"> + <rect + style="opacity:1;fill:#dc7878;fill-opacity:0;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect4279" + width="44" + height="44" + x="135.04205" + y="1009.2405" /> + <path + sodipodi:nodetypes="cscccc" + inkscape:connector-curvature="0" + id="path4140" + d="m 167.59902,1035.8159 c -1.31413,-1.8397 -8.0497,1.4976 -5.98214,5.5357 1.67413,3.2698 7.60481,-0.9006 7.23214,-2.1428 l 0.043,-22.367 -1.3203,2.4448 z" + style="fill:#6affcd;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> + <path + sodipodi:nodetypes="cscccccc" + inkscape:connector-curvature="0" + id="path4149-3" + d="m 151.55515,1038.884 c -1.31413,-1.8398 -8.0497,1.4975 -5.98214,5.5357 1.67413,3.2698 7.60481,-0.9006 7.23214,-2.1428 v -19.7322 l 14.7673,-3.2197 1.32996,-2.4891 -17.34726,3.4767 z" + style="fill:#6affcd;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> + </g> + <g + id="g4518" + inkscape:export-filename="C:\dev\qt5.10\qtquickcontrols2\examples\quickcontrols2\imagine\automotive\icons\automotive\44x44@4\message.png" + inkscape:export-xdpi="384" + inkscape:export-ydpi="384"> + <rect + y="1009.2405" + x="315.04205" + height="44" + width="44" + id="rect4281" + style="opacity:1;fill:#dc7878;fill-opacity:0;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + <rect + y="1019.9489" + x="321.94974" + height="22.583223" + width="30.18462" + id="rect4144" + style="opacity:1;fill:none;fill-opacity:1;stroke:#6affcd;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + <path + inkscape:connector-curvature="0" + id="path4146" + d="m 322.03814,1020.1699 15.1144,15.1144 14.95973,-14.9597" + style="fill:none;fill-rule:evenodd;stroke:#6affcd;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> + <path + inkscape:connector-curvature="0" + id="path4148" + d="m 352.09018,1042.3996 -11.00435,-11.0044" + style="fill:none;fill-rule:evenodd;stroke:#6affcd;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> + <path + inkscape:connector-curvature="0" + id="path4150" + d="m 321.99394,1042.4438 11.13693,-11.137" + style="fill:none;fill-rule:evenodd;stroke:#6affcd;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> + </g> + <g + id="g4460" + inkscape:export-filename="C:\dev\qt5.10\qtquickcontrols2\examples\quickcontrols2\imagine\automotive\icons\automotive\44x44@4\command.png" + inkscape:export-xdpi="384" + inkscape:export-ydpi="384"> + <rect + style="opacity:1;fill:#dc7878;fill-opacity:0;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect4287" + width="44" + height="44" + x="90.042053" + y="1009.2405" /> + <circle + r="19.047689" + cy="1031.2406" + cx="112.04205" + id="path4152" + style="opacity:1;fill:none;fill-opacity:1;stroke:#6affcd;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + <rect + ry="5.5033379" + rx="4.5719934" + y="1018.0177" + x="107.24899" + height="17.67367" + width="9.1883745" + id="rect4156" + style="opacity:1;fill:none;fill-opacity:1;stroke:#6affcd;stroke-width:0.9598186;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + <path + sodipodi:open="true" + d="m 118.4944,1031.2297 a 6.6733203,6.6733203 0 0 1 -3.33666,5.7793 6.6733203,6.6733203 0 0 1 -6.67332,0 6.6733203,6.6733203 0 0 1 -3.33666,-5.7793" + sodipodi:end="3.1415927" + sodipodi:start="0" + sodipodi:ry="6.6733203" + sodipodi:rx="6.6733203" + sodipodi:cy="1031.2297" + sodipodi:cx="111.82108" + sodipodi:type="arc" + id="path4160" + style="opacity:1;fill:none;fill-opacity:1;stroke:#6affcd;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + <path + inkscape:connector-curvature="0" + id="path4171" + d="m 111.68097,1037.9274 v 6.75" + style="fill:none;fill-rule:evenodd;stroke:#6affcd;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> + <path + inkscape:connector-curvature="0" + id="path4173" + d="m 108.71222,1044.6618 h 5.96875" + style="fill:none;fill-rule:evenodd;stroke:#6affcd;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> + </g> + <g + id="g4547" + inkscape:export-filename="C:\dev\qt5.10\qtquickcontrols2\examples\quickcontrols2\imagine\automotive\icons\weather@4x.png" + inkscape:export-xdpi="384" + inkscape:export-ydpi="384"> + <rect + style="opacity:1;fill:#dc7878;fill-opacity:0;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect4275" + width="44" + height="44" + x="405.04205" + y="1009.2405" /> + <path + sodipodi:nodetypes="sccssssssss" + inkscape:connector-curvature="0" + id="rect4181" + d="m 415.77154,1020.3319 h 1.72458 c 1.92048,-6.3943 13.78409,-9.9869 18.47317,0 h 2.34328 c 4.38985,0 7.92391,3.3764 7.92391,7.5705 v 0.3996 c 0,4.194 -3.53406,7.5704 -7.92391,7.5704 h -22.54103 c -4.38985,0 -7.92392,-3.3764 -7.92392,-7.5704 v -0.3996 c 0,-4.1941 3.53407,-7.5705 7.92392,-7.5705 z" + style="opacity:1;fill:none;fill-opacity:1;stroke:#c6c6c6;stroke-width:1.06007564;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + <path + inkscape:connector-curvature="0" + id="path4184" + d="m 418.4242,1048.7629 2.37846,-8.8765" + style="fill:none;fill-rule:evenodd;stroke:#c6c6c6;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> + <path + style="fill:none;fill-rule:evenodd;stroke:#c6c6c6;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="m 425.80463,1048.7629 2.37846,-8.8765" + id="path4186" + inkscape:connector-curvature="0" /> + <path + inkscape:connector-curvature="0" + id="path4188" + d="m 433.36269,1048.7629 2.37846,-8.8765" + style="fill:none;fill-rule:evenodd;stroke:#c6c6c6;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> + </g> + <g + id="g4408" + inkscape:export-filename="C:\dev\qt5.10\qtquickcontrols2\examples\quickcontrols2\imagine\automotive\icons\automotive\44x44@4\settings.png" + inkscape:export-xdpi="384" + inkscape:export-ydpi="384"> + <rect + y="1009.2405" + x="0.042050309" + height="44" + width="44" + id="rect4289" + style="opacity:1;fill:#dc7878;fill-opacity:0;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + <path + inkscape:connector-curvature="0" + id="path4175" + d="m 18.04247,1017.9491 1.40804,-5.2549 h 5.24319 l 1.47,5.4862 2.38326,1.376 4.34476,-3.4414 4.37522,4.3753 -3.31456,4.3973 1.149046,2.6737 h 5.08233 v 6.7396 l -4.596194,0.3315 -1.590992,3.1157 3.137788,4.0438 -4.209498,4.2095 -4.56007,-2.6328 -2.72092,1.5389 -1.3074,4.8793 h -5.14495 l -1.06066,-5.6527 -2.65524,-0.7114 -4.4148,2.5489 -3.89011,-4.3123 3.13778,-4.088 -1.73918,-3.0124 -4.66897,-0.8988 v -5.5905 l 4.83926,-0.4862 1.41421,-2.9831 -3.13778,-4.1321 4.08796,-4.088 4.04377,2.3644 z" + style="fill:none;fill-rule:evenodd;stroke:#6affcd;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> + <circle + r="5.5242715" + cy="1031.0306" + cx="22.064146" + id="path4177" + style="opacity:1;fill:none;fill-opacity:1;stroke:#6affcd;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + </g> + <g + id="g4487" + inkscape:export-filename="C:\dev\qt5.10\qtquickcontrols2\examples\quickcontrols2\imagine\automotive\icons\automotive\44x44@4\windows.png" + inkscape:export-xdpi="384" + inkscape:export-ydpi="384"> + <rect + y="1009.2405" + x="225.04205" + height="44" + width="44" + id="rect4277" + style="opacity:1;fill:#dc7878;fill-opacity:0;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + <path + sodipodi:nodetypes="cccc" + inkscape:connector-curvature="0" + id="rect4190" + d="m 261.03309,1017.2897 v 28 h -27.9375 c 2.35953,-27.5958 7.73302,-28.5625 27.9375,-28 z" + style="opacity:1;fill:none;fill-opacity:1;stroke:#6affcd;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + </g> + <g + id="g4538" + inkscape:export-filename="C:\dev\qt5.10\qtquickcontrols2\examples\quickcontrols2\imagine\automotive\icons\automotive\44x44@4\air-con.png" + inkscape:export-xdpi="384" + inkscape:export-ydpi="384" + transform="translate(-45.000003)"> + <rect + style="opacity:1;fill:#dc7878;fill-opacity:0;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect4283" + width="44" + height="44" + x="405.04205" + y="1009.2405" /> + <path + sodipodi:nodetypes="sscsscsscsscs" + inkscape:connector-curvature="0" + id="path4197" + d="m 421.26481,1044.4851 c -3.23157,3.5413 -10.47885,-3.4697 -9.9718,-8.4477 0.83559,-8.2035 7.65867,-5.1475 12.04763,-6.9077 -1.79559,-3.4382 -6.54603,-1.0408 -9.27801,-3.5338 -3.54131,-3.2316 3.46971,-10.4789 8.44775,-9.9718 8.20348,0.8356 5.14746,7.6586 6.84142,12.0034 3.37187,-1.8398 0.97447,-6.5902 3.4675,-9.3222 3.23157,-3.5413 10.47885,3.4697 9.9718,8.4478 -0.83559,8.2034 -7.65867,5.1474 -12.00344,6.753 1.83978,3.2835 6.59022,0.8861 9.3222,3.3791 3.54131,3.2316 -3.46971,10.4789 -8.44775,9.9718 -8.20348,-0.8356 -5.14746,-7.6587 -6.88561,-11.8488 -3.41606,1.9945 -1.01866,6.7449 -3.51169,9.4769 z" + style="fill:none;fill-rule:evenodd;stroke:#6affcd;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> + </g> + <g + id="g4531" + inkscape:export-filename="C:\dev\qt5.10\qtquickcontrols2\examples\quickcontrols2\imagine\automotive\icons\automotive\44x44@4\seats.png" + inkscape:export-xdpi="384" + inkscape:export-ydpi="384" + transform="translate(-90.000003)"> + <rect + y="1009.2405" + x="360.04205" + height="44" + width="44" + id="rect4285" + style="opacity:1;fill:#dc7878;fill-opacity:0;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + <path + sodipodi:nodetypes="sccs" + inkscape:connector-curvature="0" + id="rect4203" + d="m 391.91622,1017.2238 c 0.17067,-5.6932 5.2149,-4.4637 5.2149,-4.4637 v 9.1924 c -0.7292,-0.07 -5.33548,-0.7063 -5.2149,-4.7287 z" + style="opacity:1;fill:none;fill-opacity:1;stroke:#6affcd;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + <path + sodipodi:nodetypes="cscccsc" + inkscape:connector-curvature="0" + id="path4206" + d="m 386.60297,1040.4014 c -5.60375,-1.1635 -16.63421,-2.7578 -18.84543,0.6535 -1.53027,2.3608 -0.87435,7.5961 2.06641,8.7796 h 21.0795 c 3.59502,-0.5935 6.26483,-6.7048 2.51333,-8.7058 3.19134,-0.9113 5.05406,-18.5249 2.48667,-19.5701 -1.7401,-0.7084 -5.84062,6.4475 -9.30048,18.8428 z" + style="fill:none;fill-rule:evenodd;stroke:#6affcd;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> + </g> + <g + id="g4435" + inkscape:export-filename="C:\dev\qt5.10\qtquickcontrols2\examples\quickcontrols2\imagine\automotive\icons\automotive\44x44@4\statistics.png" + inkscape:export-xdpi="384" + inkscape:export-ydpi="384"> + <rect + style="opacity:1;fill:#dc7878;fill-opacity:0;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect4291" + width="44" + height="44" + x="45.042053" + y="1009.2405" /> + <path + inkscape:connector-curvature="0" + id="path4208" + d="M 51.05768,1048.9905 V 1032.553" + style="fill:none;fill-rule:evenodd;stroke:#6affcd;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + <path + style="fill:none;fill-rule:evenodd;stroke:#6affcd;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 54.60974,1048.9905 v -35.5" + id="path4210" + inkscape:connector-curvature="0" /> + <path + inkscape:connector-curvature="0" + id="path4212" + d="M 58.16187,1048.9905 V 1019.178" + style="fill:none;fill-rule:evenodd;stroke:#6affcd;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + <path + style="fill:none;fill-rule:evenodd;stroke:#6affcd;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 61.71393,1048.9905 v -20" + id="path4214" + inkscape:connector-curvature="0" /> + <path + inkscape:connector-curvature="0" + id="path4216" + d="m 65.26599,1048.9905 v -22.875" + style="fill:none;fill-rule:evenodd;stroke:#6affcd;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + <path + style="fill:none;fill-rule:evenodd;stroke:#6affcd;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 68.81812,1048.9905 V 1034.178" + id="path4218" + inkscape:connector-curvature="0" /> + <path + inkscape:connector-curvature="0" + id="path4220" + d="m 72.37018,1048.9905 v -6.8125" + style="fill:none;fill-rule:evenodd;stroke:#6affcd;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + <path + style="fill:none;fill-rule:evenodd;stroke:#6affcd;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 75.92224,1048.9905 v -9.75" + id="path4222" + inkscape:connector-curvature="0" /> + <path + inkscape:connector-curvature="0" + id="path4224" + d="m 79.47437,1048.9905 v -19.75" + style="fill:none;fill-rule:evenodd;stroke:#6affcd;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + <path + style="fill:none;fill-rule:evenodd;stroke:#6affcd;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 83.02643,1048.9905 V 1026.303" + id="path4226" + inkscape:connector-curvature="0" /> + </g> + <g + id="g4957" + inkscape:export-filename="C:\dev\qt5.10\qtquickcontrols2\examples\quickcontrols2\imagine\automotive\icons\warning@4x.png" + inkscape:export-xdpi="384" + inkscape:export-ydpi="384"> + <g + id="g4952"> + <g + id="g4984"> + <rect + style="display:inline;opacity:1;fill:#dc7878;fill-opacity:0;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect4888" + width="44" + height="44" + x="405.04205" + y="964.24048" /> + <path + transform="translate(91.459048,54.521538)" + d="m 335.89844,913.67383 a 6.7448861,6.7448861 0 0 0 -6.15625,3.36328 l -6.5293,11.30859 -6.5293,11.3086 a 6.7448861,6.7448861 0 0 0 5.83985,10.11718 h 13.05859 13.06055 a 6.7448861,6.7448861 0 0 0 5.83984,-10.11718 l -6.53125,-11.3086 -6.52929,-11.30859 a 6.7448861,6.7448861 0 0 0 -5.52344,-3.36328 z" + id="path4914" + style="opacity:1;fill:none;fill-opacity:1;stroke:#d5242f;stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + inkscape:original="M 335.58203 920.41016 L 329.05273 931.71875 L 322.52344 943.02734 L 335.58203 943.02734 L 348.64258 943.02734 L 342.11133 931.71875 L 335.58203 920.41016 z " + inkscape:radius="6.7442117" + sodipodi:type="inkscape:offset" /> + <text + id="text4916" + y="997.82135" + x="418.31409" + style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#d5232f;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + xml:space="preserve"><tspan + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:29.11217499px;line-height:1.25;font-family:'Liberation Mono';-inkscape-font-specification:'Liberation Mono';fill:#d5232f;fill-opacity:1" + y="997.82135" + x="418.31409" + id="tspan4918" + sodipodi:role="line">!</tspan></text> + </g> + </g> + </g> + <g + id="g4579" + transform="translate(0.91359708)" + inkscape:export-filename="C:\dev\qt5.10\qtquickcontrols2\examples\quickcontrols2\imagine\automotive\icons\car@4x.png" + inkscape:export-xdpi="384" + inkscape:export-ydpi="384"> + <g + transform="translate(0,-0.52629089)" + inkscape:export-ydpi="180.02795" + inkscape:export-xdpi="180.02795" + inkscape:export-filename="/home/mitch/dev/qqc2-futuristic-style-demo/icons/car@2x.png" + id="g4940"> + <g + inkscape:export-ydpi="288.18481" + inkscape:export-xdpi="288.18481" + inkscape:export-filename="C:\dev\qt5.10\qtquickcontrols2\examples\quickcontrols2\imagine\automotive\icons\car@3x.png" + transform="translate(-4.2105261)" + id="g5027"> + <g + id="g4990" + transform="translate(38)"> + <path + style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#6affcd;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="m 155.0705,782.17781 c 6.07598,2.81282 15.70745,5.54152 16.78045,0.12114 1.47822,-7.46742 -7.82673,-9.03073 -12.74213,-11.21517 0.35496,-28.39708 4.52948,-61.94987 -16.18718,-79.16009 -15.28126,-12.6948 -36.88923,-13.70761 -54.94737,-13.89474 -44.75939,1.12608 -72.2307,7.25376 -66.73684,92.42105 -5.10694,0.73154 -15.36618,6.19984 -11.96169,13.62693 2.26424,4.93957 10.32335,-1.55401 16.17222,-2.04798 l -4.42106,70.10526 c -4.88809,9.36444 -1.70447,13.26861 -0.21052,18.31579 l 2.31579,28.21053 c -5.87521,7.89365 -9.18606,65.22384 5.21645,80.45936 20.44842,21.63111 45.69753,20.41018 69.7353,20.35721 29.24164,-0.0644 46.2493,-7.41397 57.516,-25.0271 6.1501,-9.61441 6.80873,-24.11582 6.56857,-37.94412 -0.50608,-29.14019 -2.51723,-31.93372 -3.87843,-38.05588 0.24603,-10.87137 0.62319,-26.86855 0.62319,-26.86855 0.13708,-2.99847 -4.07078,-3.32117 -4.26379,-0.30212 -1.23557,19.32726 -2.52156,37.97398 -4.14887,52.01278 -5.15807,-50.19881 -8.22005,-100.65169 -0.42106,-152.42105 l 1.77142,14.22858" + id="path4198" + inkscape:connector-curvature="0" + sodipodi:nodetypes="cscsccsccccssssccsccc" /> + <rect + style="opacity:0;fill:none;fill-opacity:1;stroke:#6affcd;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect4200" + width="75.39991" + height="41.533218" + x="52.331917" + y="811.89917" /> + <rect + ry="5.0999999" + style="opacity:1;fill:none;fill-opacity:1;stroke:#6affcd;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect4204" + width="74.730019" + height="42.277542" + x="53.001808" + y="811.97357" + rx="5.0999999" /> + <path + style="fill:none;fill-rule:evenodd;stroke:#6affcd;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="m 33.76375,753.50264 c 21.81505,-33.62758 93.76507,-29.21973 112.94736,0.52631 l -6.52631,45.1579 c -32.75184,-8.71732 -66.12565,-8.2607 -100,-0.42106 z" + id="path4207" + inkscape:connector-curvature="0" + sodipodi:nodetypes="ccccc" /> + <path + style="fill:none;fill-rule:evenodd;stroke:#6affcd;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="M 30.39532,772.45 C 39.7558,824.45977 33.67511,874.57878 29.86901,924.97632 27.0264,874.92466 21.98491,825.44889 30.39532,772.45 Z" + id="path4209" + inkscape:connector-curvature="0" + sodipodi:nodetypes="ccc" /> + <path + style="fill:none;fill-rule:evenodd;stroke:#6affcd;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="m 40.07953,905.29211 c 31.5016,11.5654 64.23888,15.63953 100.21053,0.10526 l -1.68421,49.36842 c -34.36634,20.89476 -66.32657,16.8029 -97.05263,-0.10526 z" + id="path4211" + inkscape:connector-curvature="0" + sodipodi:nodetypes="ccccc" /> + <path + style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#6affcd;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="m 132.39532,693.08158 c -0.1013,1.76525 -0.0679,3.42272 0.52632,4.63158 4.7808,3.23458 8.19086,9.38341 11.57895,15.57895 1.5083,-0.0482 2.87102,0.42463 4.63157,-0.52632 0.15986,-2.57309 0.37258,-5.12353 -0.42105,-8.10526 -3.09684,-4.12667 -6.44714,-7.87314 -10.10526,-11.15789 -2.00632,-0.36221 -3.93976,-0.97762 -6.21053,-0.42106 z" + id="path4213" + inkscape:connector-curvature="0" + sodipodi:nodetypes="ccccccc" /> + <path + sodipodi:nodetypes="ccccccc" + inkscape:connector-curvature="0" + id="path4215" + d="m 48.05537,693.08158 c 0.1013,1.76525 0.0679,3.42272 -0.52632,4.63158 -4.7808,3.23458 -8.19086,9.38341 -11.57895,15.57895 -1.5083,-0.0482 -2.87102,0.42463 -4.63157,-0.52632 -0.15986,-2.57309 -0.37258,-5.12353 0.42105,-8.10526 3.09684,-4.12667 6.44714,-7.87314 10.10526,-11.15789 2.00632,-0.36221 3.93976,-0.97762 6.21053,-0.42106 z" + style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#6affcd;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> + <path + style="display:inline;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#d5222f;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:0.87843137" + d="m 151.92716,785.02141 59.0707,63.0345 c 1.5809,-0.4544 3.3564,-1.3935 2.958,-3.8128 -1.0167,-6.1727 -4.9133,-10.6123 -10.7475,-11.7661 l -48.0616,-50.3775" + id="path4240" + inkscape:connector-curvature="0" + sodipodi:nodetypes="ccccc" /> + </g> + <rect + y="669.29321" + x="4.2525716" + height="338.94736" + width="250.17281" + id="rect4844" + style="opacity:1;fill:none;fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + </g> + </g> + <rect + y="668.2406" + x="-0.87155163" + height="340" + width="252" + id="rect4563" + style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.01560712;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal" /> + </g> + </g> +</svg> diff --git a/examples/quickcontrols/imagine/automotive/icons/automotive/index.theme b/examples/quickcontrols/imagine/automotive/icons/automotive/index.theme new file mode 100644 index 0000000000..cd84146e95 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/icons/automotive/index.theme @@ -0,0 +1,14 @@ +[Icon Theme] +Name=Automotive +Comment=Icon theme for the Qt Quick Controls 2 Automotive Imagine Style Example + +Directories=44x44,44x44@2 + +[44x44] +Size=44 +Type=Fixed + +[44x44@2] +Size=44 +Scale=2 +Type=Fixed diff --git a/examples/quickcontrols/imagine/automotive/icons/car.png b/examples/quickcontrols/imagine/automotive/icons/car.png Binary files differnew file mode 100644 index 0000000000..4bfc9a474a --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/icons/car.png diff --git a/examples/quickcontrols/imagine/automotive/icons/car@2x.png b/examples/quickcontrols/imagine/automotive/icons/car@2x.png Binary files differnew file mode 100644 index 0000000000..966bc47bc7 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/icons/car@2x.png diff --git a/examples/quickcontrols/imagine/automotive/icons/icons.qrc b/examples/quickcontrols/imagine/automotive/icons/icons.qrc new file mode 100644 index 0000000000..5cb797817b --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/icons/icons.qrc @@ -0,0 +1,29 @@ +<RCC> + <qresource prefix="/icons"> + <file>car.png</file> + <file>car@2x.png</file> + <file>warning.png</file> + <file>warning@2x.png</file> + <file>weather.png</file> + <file>weather@2x.png</file> + <file>automotive/icons.svg</file> + <file>automotive/index.theme</file> + <file>automotive/44x44/air-con.png</file> + <file>automotive/44x44/command.png</file> + <file>automotive/44x44/message.png</file> + <file>automotive/44x44/music.png</file> + <file>automotive/44x44/seats.png</file> + <file>automotive/44x44/settings.png</file> + <file>automotive/44x44/statistics.png</file> + <file>automotive/44x44/windows.png</file> + <file>automotive/44x44@2/air-con.png</file> + <file>automotive/44x44@2/command.png</file> + <file>automotive/44x44@2/message.png</file> + <file>automotive/44x44@2/music.png</file> + <file>automotive/44x44@2/navigation.png</file> + <file>automotive/44x44@2/seats.png</file> + <file>automotive/44x44@2/settings.png</file> + <file>automotive/44x44@2/statistics.png</file> + <file>automotive/44x44@2/windows.png</file> + </qresource> +</RCC> diff --git a/examples/quickcontrols/imagine/automotive/icons/warning.png b/examples/quickcontrols/imagine/automotive/icons/warning.png Binary files differnew file mode 100644 index 0000000000..590a61eb80 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/icons/warning.png diff --git a/examples/quickcontrols/imagine/automotive/icons/warning@2x.png b/examples/quickcontrols/imagine/automotive/icons/warning@2x.png Binary files differnew file mode 100644 index 0000000000..487fbafcfd --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/icons/warning@2x.png diff --git a/examples/quickcontrols/imagine/automotive/icons/weather.png b/examples/quickcontrols/imagine/automotive/icons/weather.png Binary files differnew file mode 100644 index 0000000000..b1479de27a --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/icons/weather.png diff --git a/examples/quickcontrols/imagine/automotive/icons/weather@2x.png b/examples/quickcontrols/imagine/automotive/icons/weather@2x.png Binary files differnew file mode 100644 index 0000000000..8b4333ab15 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/icons/weather@2x.png diff --git a/examples/quickcontrols/imagine/automotive/imagine-assets/applicationwindow-background.png b/examples/quickcontrols/imagine/automotive/imagine-assets/applicationwindow-background.png Binary files differnew file mode 100644 index 0000000000..aac403dbb1 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/imagine-assets/applicationwindow-background.png diff --git a/examples/quickcontrols/imagine/automotive/imagine-assets/applicationwindow-background@2x.png b/examples/quickcontrols/imagine/automotive/imagine-assets/applicationwindow-background@2x.png Binary files differnew file mode 100644 index 0000000000..a8ef3dd456 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/imagine-assets/applicationwindow-background@2x.png diff --git a/examples/quickcontrols/imagine/automotive/imagine-assets/button-background-checked-hovered.9.png b/examples/quickcontrols/imagine/automotive/imagine-assets/button-background-checked-hovered.9.png Binary files differnew file mode 100644 index 0000000000..f92dd66afe --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/imagine-assets/button-background-checked-hovered.9.png diff --git a/examples/quickcontrols/imagine/automotive/imagine-assets/button-background-checked-hovered@2x.9.png b/examples/quickcontrols/imagine/automotive/imagine-assets/button-background-checked-hovered@2x.9.png Binary files differnew file mode 100644 index 0000000000..b64640e2b1 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/imagine-assets/button-background-checked-hovered@2x.9.png diff --git a/examples/quickcontrols/imagine/automotive/imagine-assets/button-background-checked.9.png b/examples/quickcontrols/imagine/automotive/imagine-assets/button-background-checked.9.png Binary files differnew file mode 100644 index 0000000000..5a70d1d302 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/imagine-assets/button-background-checked.9.png diff --git a/examples/quickcontrols/imagine/automotive/imagine-assets/button-background-checked@2x.9.png b/examples/quickcontrols/imagine/automotive/imagine-assets/button-background-checked@2x.9.png Binary files differnew file mode 100644 index 0000000000..9d080dc823 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/imagine-assets/button-background-checked@2x.9.png diff --git a/examples/quickcontrols/imagine/automotive/imagine-assets/button-background-hovered.9.png b/examples/quickcontrols/imagine/automotive/imagine-assets/button-background-hovered.9.png Binary files differnew file mode 100644 index 0000000000..94e37b8334 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/imagine-assets/button-background-hovered.9.png diff --git a/examples/quickcontrols/imagine/automotive/imagine-assets/button-background-hovered@2x.9.png b/examples/quickcontrols/imagine/automotive/imagine-assets/button-background-hovered@2x.9.png Binary files differnew file mode 100644 index 0000000000..905d9e4705 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/imagine-assets/button-background-hovered@2x.9.png diff --git a/examples/quickcontrols/imagine/automotive/imagine-assets/button-background-pressed.9.png b/examples/quickcontrols/imagine/automotive/imagine-assets/button-background-pressed.9.png Binary files differnew file mode 100644 index 0000000000..bc4c3b3880 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/imagine-assets/button-background-pressed.9.png diff --git a/examples/quickcontrols/imagine/automotive/imagine-assets/button-background-pressed@2x.9.png b/examples/quickcontrols/imagine/automotive/imagine-assets/button-background-pressed@2x.9.png Binary files differnew file mode 100644 index 0000000000..778fe53752 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/imagine-assets/button-background-pressed@2x.9.png diff --git a/examples/quickcontrols/imagine/automotive/imagine-assets/button-background.9.png b/examples/quickcontrols/imagine/automotive/imagine-assets/button-background.9.png Binary files differnew file mode 100644 index 0000000000..85ed1a03ba --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/imagine-assets/button-background.9.png diff --git a/examples/quickcontrols/imagine/automotive/imagine-assets/button-background@2x.9.png b/examples/quickcontrols/imagine/automotive/imagine-assets/button-background@2x.9.png Binary files differnew file mode 100644 index 0000000000..1eb7ebed20 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/imagine-assets/button-background@2x.9.png diff --git a/examples/quickcontrols/imagine/automotive/imagine-assets/dial-background-hovered.png b/examples/quickcontrols/imagine/automotive/imagine-assets/dial-background-hovered.png Binary files differnew file mode 100644 index 0000000000..26add20cfc --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/imagine-assets/dial-background-hovered.png diff --git a/examples/quickcontrols/imagine/automotive/imagine-assets/dial-background-hovered@2x.png b/examples/quickcontrols/imagine/automotive/imagine-assets/dial-background-hovered@2x.png Binary files differnew file mode 100644 index 0000000000..01d8136d51 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/imagine-assets/dial-background-hovered@2x.png diff --git a/examples/quickcontrols/imagine/automotive/imagine-assets/dial-background-pressed.png b/examples/quickcontrols/imagine/automotive/imagine-assets/dial-background-pressed.png Binary files differnew file mode 100644 index 0000000000..435acd1466 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/imagine-assets/dial-background-pressed.png diff --git a/examples/quickcontrols/imagine/automotive/imagine-assets/dial-background-pressed@2x.png b/examples/quickcontrols/imagine/automotive/imagine-assets/dial-background-pressed@2x.png Binary files differnew file mode 100644 index 0000000000..9bab57904d --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/imagine-assets/dial-background-pressed@2x.png diff --git a/examples/quickcontrols/imagine/automotive/imagine-assets/dial-background.png b/examples/quickcontrols/imagine/automotive/imagine-assets/dial-background.png Binary files differnew file mode 100644 index 0000000000..8aab4d3280 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/imagine-assets/dial-background.png diff --git a/examples/quickcontrols/imagine/automotive/imagine-assets/dial-background@2x.png b/examples/quickcontrols/imagine/automotive/imagine-assets/dial-background@2x.png Binary files differnew file mode 100644 index 0000000000..a856971185 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/imagine-assets/dial-background@2x.png diff --git a/examples/quickcontrols/imagine/automotive/imagine-assets/dial-handle-pressed.png b/examples/quickcontrols/imagine/automotive/imagine-assets/dial-handle-pressed.png Binary files differnew file mode 100644 index 0000000000..93992626ce --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/imagine-assets/dial-handle-pressed.png diff --git a/examples/quickcontrols/imagine/automotive/imagine-assets/dial-handle-pressed@2x.png b/examples/quickcontrols/imagine/automotive/imagine-assets/dial-handle-pressed@2x.png Binary files differnew file mode 100644 index 0000000000..5c563abba5 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/imagine-assets/dial-handle-pressed@2x.png diff --git a/examples/quickcontrols/imagine/automotive/imagine-assets/dial-handle.png b/examples/quickcontrols/imagine/automotive/imagine-assets/dial-handle.png Binary files differnew file mode 100644 index 0000000000..a997dd58f8 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/imagine-assets/dial-handle.png diff --git a/examples/quickcontrols/imagine/automotive/imagine-assets/dial-handle@2x.png b/examples/quickcontrols/imagine/automotive/imagine-assets/dial-handle@2x.png Binary files differnew file mode 100644 index 0000000000..afd1330704 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/imagine-assets/dial-handle@2x.png diff --git a/examples/quickcontrols/imagine/automotive/imagine-assets/frame-background.9.png b/examples/quickcontrols/imagine/automotive/imagine-assets/frame-background.9.png Binary files differnew file mode 100644 index 0000000000..fd7d5453ff --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/imagine-assets/frame-background.9.png diff --git a/examples/quickcontrols/imagine/automotive/imagine-assets/frame-background@2x.9.png b/examples/quickcontrols/imagine/automotive/imagine-assets/frame-background@2x.9.png Binary files differnew file mode 100644 index 0000000000..83284457e4 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/imagine-assets/frame-background@2x.9.png diff --git a/examples/quickcontrols/imagine/automotive/imagine-assets/imagine-assets.qrc b/examples/quickcontrols/imagine/automotive/imagine-assets/imagine-assets.qrc new file mode 100644 index 0000000000..81eadda617 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/imagine-assets/imagine-assets.qrc @@ -0,0 +1,80 @@ +<RCC> + <qresource prefix="/imagine-assets"> + <file>applicationwindow-background.png</file> + <file>applicationwindow-background@2x.png</file> + <file>button-background.9.png</file> + <file>button-background@2x.9.png</file> + <file>button-background-checked.9.png</file> + <file>button-background-checked@2x.9.png</file> + <file>button-background-checked-hovered.9.png</file> + <file>button-background-checked-hovered@2x.9.png</file> + <file>button-background-hovered.9.png</file> + <file>button-background-hovered@2x.9.png</file> + <file>button-background-pressed.9.png</file> + <file>button-background-pressed@2x.9.png</file> + <file>dial-background.png</file> + <file>dial-background@2x.png</file> + <file>dial-background-hovered.png</file> + <file>dial-background-hovered@2x.png</file> + <file>dial-background-pressed.png</file> + <file>dial-background-pressed@2x.png</file> + <file>dial-handle.png</file> + <file>dial-handle@2x.png</file> + <file>dial-handle-pressed.png</file> + <file>dial-handle-pressed@2x.png</file> + <file>frame-background.9.png</file> + <file>frame-background@2x.9.png</file> + <file>itemdelegate-background.9.png</file> + <file>itemdelegate-background@2x.9.png</file> + <file>itemdelegate-background-checked.9.png</file> + <file>itemdelegate-background-checked@2x.9.png</file> + <file>itemdelegate-background-hovered.9.png</file> + <file>itemdelegate-background-hovered@2x.9.png</file> + <file>itemdelegate-background-pressed.9.png</file> + <file>itemdelegate-background-pressed@2x.9.png</file> + <file>radiobutton-indicator.png</file> + <file>radiobutton-indicator@2x.png</file> + <file>radiobutton-indicator-checked.png</file> + <file>radiobutton-indicator-checked@2x.png</file> + <file>radiobutton-indicator-checked-hovered.png</file> + <file>radiobutton-indicator-checked-hovered@2x.png</file> + <file>radiobutton-indicator-checked-pressed.png</file> + <file>radiobutton-indicator-checked-pressed@2x.png</file> + <file>radiobutton-indicator-hovered.png</file> + <file>radiobutton-indicator-hovered@2x.png</file> + <file>radiobutton-indicator-pressed.png</file> + <file>radiobutton-indicator-pressed@2x.png</file> + <file>scrollindicator-handle.png</file> + <file>scrollindicator-handle@2x.png</file> + <file>slider-background-horizontal.9.png</file> + <file>slider-background-horizontal@2x.9.png</file> + <file>slider-handle.png</file> + <file>slider-handle@2x.png</file> + <file>slider-handle-hovered.png</file> + <file>slider-handle-hovered@2x.png</file> + <file>slider-handle-pressed.png</file> + <file>slider-handle-pressed@2x.png</file> + <file>slider-progress-horizontal.9.png</file> + <file>slider-progress-horizontal@2x.9.png</file> + <file>slider-progress-horizontal-pressed.9.png</file> + <file>slider-progress-horizontal-pressed@2x.9.png</file> + <file>switchdelegate-background.9.png</file> + <file>switchdelegate-background@2x.9.png</file> + <file>switchdelegate-handle.png</file> + <file>switchdelegate-handle@2x.png</file> + <file>switchdelegate-handle-checked.png</file> + <file>switchdelegate-handle-checked@2x.png</file> + <file>switchdelegate-handle-checked-hovered.png</file> + <file>switchdelegate-handle-checked-hovered@2x.png</file> + <file>switchdelegate-handle-hovered.png</file> + <file>switchdelegate-handle-hovered@2x.png</file> + <file>switchdelegate-handle-pressed.png</file> + <file>switchdelegate-handle-pressed@2x.png</file> + <file>switchdelegate-indicator.png</file> + <file>switchdelegate-indicator@2x.png</file> + <file>switchdelegate-indicator-pressed.png</file> + <file>switchdelegate-indicator-pressed@2x.png</file> + <file>toolseparator-separator-vertical.9.png</file> + <file>toolseparator-separator-vertical@2x.9.png</file> + </qresource> +</RCC> diff --git a/examples/quickcontrols/imagine/automotive/imagine-assets/itemdelegate-background-checked.9.png b/examples/quickcontrols/imagine/automotive/imagine-assets/itemdelegate-background-checked.9.png Binary files differnew file mode 100644 index 0000000000..4c6b475441 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/imagine-assets/itemdelegate-background-checked.9.png diff --git a/examples/quickcontrols/imagine/automotive/imagine-assets/itemdelegate-background-checked@2x.9.png b/examples/quickcontrols/imagine/automotive/imagine-assets/itemdelegate-background-checked@2x.9.png Binary files differnew file mode 100644 index 0000000000..9f4f70575f --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/imagine-assets/itemdelegate-background-checked@2x.9.png diff --git a/examples/quickcontrols/imagine/automotive/imagine-assets/itemdelegate-background-hovered.9.png b/examples/quickcontrols/imagine/automotive/imagine-assets/itemdelegate-background-hovered.9.png Binary files differnew file mode 100644 index 0000000000..a5c189c9e3 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/imagine-assets/itemdelegate-background-hovered.9.png diff --git a/examples/quickcontrols/imagine/automotive/imagine-assets/itemdelegate-background-hovered@2x.9.png b/examples/quickcontrols/imagine/automotive/imagine-assets/itemdelegate-background-hovered@2x.9.png Binary files differnew file mode 100644 index 0000000000..2b3c9c6743 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/imagine-assets/itemdelegate-background-hovered@2x.9.png diff --git a/examples/quickcontrols/imagine/automotive/imagine-assets/itemdelegate-background-pressed.9.png b/examples/quickcontrols/imagine/automotive/imagine-assets/itemdelegate-background-pressed.9.png Binary files differnew file mode 100644 index 0000000000..56b5534ea6 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/imagine-assets/itemdelegate-background-pressed.9.png diff --git a/examples/quickcontrols/imagine/automotive/imagine-assets/itemdelegate-background-pressed@2x.9.png b/examples/quickcontrols/imagine/automotive/imagine-assets/itemdelegate-background-pressed@2x.9.png Binary files differnew file mode 100644 index 0000000000..bbbbb8b1d8 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/imagine-assets/itemdelegate-background-pressed@2x.9.png diff --git a/examples/quickcontrols/imagine/automotive/imagine-assets/itemdelegate-background.9.png b/examples/quickcontrols/imagine/automotive/imagine-assets/itemdelegate-background.9.png Binary files differnew file mode 100644 index 0000000000..1fbb562689 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/imagine-assets/itemdelegate-background.9.png diff --git a/examples/quickcontrols/imagine/automotive/imagine-assets/itemdelegate-background@2x.9.png b/examples/quickcontrols/imagine/automotive/imagine-assets/itemdelegate-background@2x.9.png Binary files differnew file mode 100644 index 0000000000..18880980f0 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/imagine-assets/itemdelegate-background@2x.9.png diff --git a/examples/quickcontrols/imagine/automotive/imagine-assets/radiobutton-indicator-checked-hovered.png b/examples/quickcontrols/imagine/automotive/imagine-assets/radiobutton-indicator-checked-hovered.png Binary files differnew file mode 100644 index 0000000000..f64c9665b2 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/imagine-assets/radiobutton-indicator-checked-hovered.png diff --git a/examples/quickcontrols/imagine/automotive/imagine-assets/radiobutton-indicator-checked-hovered@2x.png b/examples/quickcontrols/imagine/automotive/imagine-assets/radiobutton-indicator-checked-hovered@2x.png Binary files differnew file mode 100644 index 0000000000..ace1717a97 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/imagine-assets/radiobutton-indicator-checked-hovered@2x.png diff --git a/examples/quickcontrols/imagine/automotive/imagine-assets/radiobutton-indicator-checked-pressed.png b/examples/quickcontrols/imagine/automotive/imagine-assets/radiobutton-indicator-checked-pressed.png Binary files differnew file mode 100644 index 0000000000..c77ad470c0 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/imagine-assets/radiobutton-indicator-checked-pressed.png diff --git a/examples/quickcontrols/imagine/automotive/imagine-assets/radiobutton-indicator-checked-pressed@2x.png b/examples/quickcontrols/imagine/automotive/imagine-assets/radiobutton-indicator-checked-pressed@2x.png Binary files differnew file mode 100644 index 0000000000..2798f77f0f --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/imagine-assets/radiobutton-indicator-checked-pressed@2x.png diff --git a/examples/quickcontrols/imagine/automotive/imagine-assets/radiobutton-indicator-checked.png b/examples/quickcontrols/imagine/automotive/imagine-assets/radiobutton-indicator-checked.png Binary files differnew file mode 100644 index 0000000000..ea714eaaf9 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/imagine-assets/radiobutton-indicator-checked.png diff --git a/examples/quickcontrols/imagine/automotive/imagine-assets/radiobutton-indicator-checked@2x.png b/examples/quickcontrols/imagine/automotive/imagine-assets/radiobutton-indicator-checked@2x.png Binary files differnew file mode 100644 index 0000000000..4f29b80b31 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/imagine-assets/radiobutton-indicator-checked@2x.png diff --git a/examples/quickcontrols/imagine/automotive/imagine-assets/radiobutton-indicator-hovered.png b/examples/quickcontrols/imagine/automotive/imagine-assets/radiobutton-indicator-hovered.png Binary files differnew file mode 100644 index 0000000000..a7d07ed17c --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/imagine-assets/radiobutton-indicator-hovered.png diff --git a/examples/quickcontrols/imagine/automotive/imagine-assets/radiobutton-indicator-hovered@2x.png b/examples/quickcontrols/imagine/automotive/imagine-assets/radiobutton-indicator-hovered@2x.png Binary files differnew file mode 100644 index 0000000000..b0fff06e51 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/imagine-assets/radiobutton-indicator-hovered@2x.png diff --git a/examples/quickcontrols/imagine/automotive/imagine-assets/radiobutton-indicator-pressed.png b/examples/quickcontrols/imagine/automotive/imagine-assets/radiobutton-indicator-pressed.png Binary files differnew file mode 100644 index 0000000000..7d657ac9c2 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/imagine-assets/radiobutton-indicator-pressed.png diff --git a/examples/quickcontrols/imagine/automotive/imagine-assets/radiobutton-indicator-pressed@2x.png b/examples/quickcontrols/imagine/automotive/imagine-assets/radiobutton-indicator-pressed@2x.png Binary files differnew file mode 100644 index 0000000000..9a8b9cd829 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/imagine-assets/radiobutton-indicator-pressed@2x.png diff --git a/examples/quickcontrols/imagine/automotive/imagine-assets/radiobutton-indicator.png b/examples/quickcontrols/imagine/automotive/imagine-assets/radiobutton-indicator.png Binary files differnew file mode 100644 index 0000000000..b59ba0cef8 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/imagine-assets/radiobutton-indicator.png diff --git a/examples/quickcontrols/imagine/automotive/imagine-assets/radiobutton-indicator@2x.png b/examples/quickcontrols/imagine/automotive/imagine-assets/radiobutton-indicator@2x.png Binary files differnew file mode 100644 index 0000000000..e4a2b9a2b9 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/imagine-assets/radiobutton-indicator@2x.png diff --git a/examples/quickcontrols/imagine/automotive/imagine-assets/scrollindicator-handle.png b/examples/quickcontrols/imagine/automotive/imagine-assets/scrollindicator-handle.png Binary files differnew file mode 100644 index 0000000000..99206d7e26 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/imagine-assets/scrollindicator-handle.png diff --git a/examples/quickcontrols/imagine/automotive/imagine-assets/scrollindicator-handle@2x.png b/examples/quickcontrols/imagine/automotive/imagine-assets/scrollindicator-handle@2x.png Binary files differnew file mode 100644 index 0000000000..85a9ebccf7 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/imagine-assets/scrollindicator-handle@2x.png diff --git a/examples/quickcontrols/imagine/automotive/imagine-assets/slider-background-horizontal.9.png b/examples/quickcontrols/imagine/automotive/imagine-assets/slider-background-horizontal.9.png Binary files differnew file mode 100644 index 0000000000..3d2406cf06 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/imagine-assets/slider-background-horizontal.9.png diff --git a/examples/quickcontrols/imagine/automotive/imagine-assets/slider-background-horizontal@2x.9.png b/examples/quickcontrols/imagine/automotive/imagine-assets/slider-background-horizontal@2x.9.png Binary files differnew file mode 100644 index 0000000000..6c8104ff97 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/imagine-assets/slider-background-horizontal@2x.9.png diff --git a/examples/quickcontrols/imagine/automotive/imagine-assets/slider-handle-hovered.png b/examples/quickcontrols/imagine/automotive/imagine-assets/slider-handle-hovered.png Binary files differnew file mode 100644 index 0000000000..bd26d82451 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/imagine-assets/slider-handle-hovered.png diff --git a/examples/quickcontrols/imagine/automotive/imagine-assets/slider-handle-hovered@2x.png b/examples/quickcontrols/imagine/automotive/imagine-assets/slider-handle-hovered@2x.png Binary files differnew file mode 100644 index 0000000000..000db40444 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/imagine-assets/slider-handle-hovered@2x.png diff --git a/examples/quickcontrols/imagine/automotive/imagine-assets/slider-handle-pressed.png b/examples/quickcontrols/imagine/automotive/imagine-assets/slider-handle-pressed.png Binary files differnew file mode 100644 index 0000000000..4a4d0be7f8 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/imagine-assets/slider-handle-pressed.png diff --git a/examples/quickcontrols/imagine/automotive/imagine-assets/slider-handle-pressed@2x.png b/examples/quickcontrols/imagine/automotive/imagine-assets/slider-handle-pressed@2x.png Binary files differnew file mode 100644 index 0000000000..903c102440 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/imagine-assets/slider-handle-pressed@2x.png diff --git a/examples/quickcontrols/imagine/automotive/imagine-assets/slider-handle.png b/examples/quickcontrols/imagine/automotive/imagine-assets/slider-handle.png Binary files differnew file mode 100644 index 0000000000..8f812dae34 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/imagine-assets/slider-handle.png diff --git a/examples/quickcontrols/imagine/automotive/imagine-assets/slider-handle@2x.png b/examples/quickcontrols/imagine/automotive/imagine-assets/slider-handle@2x.png Binary files differnew file mode 100644 index 0000000000..b30a4f38f0 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/imagine-assets/slider-handle@2x.png diff --git a/examples/quickcontrols/imagine/automotive/imagine-assets/slider-progress-horizontal-pressed.9.png b/examples/quickcontrols/imagine/automotive/imagine-assets/slider-progress-horizontal-pressed.9.png Binary files differnew file mode 100644 index 0000000000..7789f09f2c --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/imagine-assets/slider-progress-horizontal-pressed.9.png diff --git a/examples/quickcontrols/imagine/automotive/imagine-assets/slider-progress-horizontal-pressed@2x.9.png b/examples/quickcontrols/imagine/automotive/imagine-assets/slider-progress-horizontal-pressed@2x.9.png Binary files differnew file mode 100644 index 0000000000..e64c13dc39 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/imagine-assets/slider-progress-horizontal-pressed@2x.9.png diff --git a/examples/quickcontrols/imagine/automotive/imagine-assets/slider-progress-horizontal.9.png b/examples/quickcontrols/imagine/automotive/imagine-assets/slider-progress-horizontal.9.png Binary files differnew file mode 100644 index 0000000000..8e65ca35c5 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/imagine-assets/slider-progress-horizontal.9.png diff --git a/examples/quickcontrols/imagine/automotive/imagine-assets/slider-progress-horizontal@2x.9.png b/examples/quickcontrols/imagine/automotive/imagine-assets/slider-progress-horizontal@2x.9.png Binary files differnew file mode 100644 index 0000000000..d512e40708 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/imagine-assets/slider-progress-horizontal@2x.9.png diff --git a/examples/quickcontrols/imagine/automotive/imagine-assets/switchdelegate-background.9.png b/examples/quickcontrols/imagine/automotive/imagine-assets/switchdelegate-background.9.png Binary files differnew file mode 100644 index 0000000000..1fbb562689 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/imagine-assets/switchdelegate-background.9.png diff --git a/examples/quickcontrols/imagine/automotive/imagine-assets/switchdelegate-background@2x.9.png b/examples/quickcontrols/imagine/automotive/imagine-assets/switchdelegate-background@2x.9.png Binary files differnew file mode 100644 index 0000000000..18880980f0 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/imagine-assets/switchdelegate-background@2x.9.png diff --git a/examples/quickcontrols/imagine/automotive/imagine-assets/switchdelegate-handle-checked-hovered.png b/examples/quickcontrols/imagine/automotive/imagine-assets/switchdelegate-handle-checked-hovered.png Binary files differnew file mode 100644 index 0000000000..e66ef7137c --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/imagine-assets/switchdelegate-handle-checked-hovered.png diff --git a/examples/quickcontrols/imagine/automotive/imagine-assets/switchdelegate-handle-checked-hovered@2x.png b/examples/quickcontrols/imagine/automotive/imagine-assets/switchdelegate-handle-checked-hovered@2x.png Binary files differnew file mode 100644 index 0000000000..05d6f82e7a --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/imagine-assets/switchdelegate-handle-checked-hovered@2x.png diff --git a/examples/quickcontrols/imagine/automotive/imagine-assets/switchdelegate-handle-checked.png b/examples/quickcontrols/imagine/automotive/imagine-assets/switchdelegate-handle-checked.png Binary files differnew file mode 100644 index 0000000000..bcfa06aec6 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/imagine-assets/switchdelegate-handle-checked.png diff --git a/examples/quickcontrols/imagine/automotive/imagine-assets/switchdelegate-handle-checked@2x.png b/examples/quickcontrols/imagine/automotive/imagine-assets/switchdelegate-handle-checked@2x.png Binary files differnew file mode 100644 index 0000000000..b9985f0fe3 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/imagine-assets/switchdelegate-handle-checked@2x.png diff --git a/examples/quickcontrols/imagine/automotive/imagine-assets/switchdelegate-handle-hovered.png b/examples/quickcontrols/imagine/automotive/imagine-assets/switchdelegate-handle-hovered.png Binary files differnew file mode 100644 index 0000000000..3de8aa1512 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/imagine-assets/switchdelegate-handle-hovered.png diff --git a/examples/quickcontrols/imagine/automotive/imagine-assets/switchdelegate-handle-hovered@2x.png b/examples/quickcontrols/imagine/automotive/imagine-assets/switchdelegate-handle-hovered@2x.png Binary files differnew file mode 100644 index 0000000000..b955159055 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/imagine-assets/switchdelegate-handle-hovered@2x.png diff --git a/examples/quickcontrols/imagine/automotive/imagine-assets/switchdelegate-handle-pressed.png b/examples/quickcontrols/imagine/automotive/imagine-assets/switchdelegate-handle-pressed.png Binary files differnew file mode 100644 index 0000000000..547b2c1758 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/imagine-assets/switchdelegate-handle-pressed.png diff --git a/examples/quickcontrols/imagine/automotive/imagine-assets/switchdelegate-handle-pressed@2x.png b/examples/quickcontrols/imagine/automotive/imagine-assets/switchdelegate-handle-pressed@2x.png Binary files differnew file mode 100644 index 0000000000..b4bb748aa4 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/imagine-assets/switchdelegate-handle-pressed@2x.png diff --git a/examples/quickcontrols/imagine/automotive/imagine-assets/switchdelegate-handle.png b/examples/quickcontrols/imagine/automotive/imagine-assets/switchdelegate-handle.png Binary files differnew file mode 100644 index 0000000000..fd81422a88 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/imagine-assets/switchdelegate-handle.png diff --git a/examples/quickcontrols/imagine/automotive/imagine-assets/switchdelegate-handle@2x.png b/examples/quickcontrols/imagine/automotive/imagine-assets/switchdelegate-handle@2x.png Binary files differnew file mode 100644 index 0000000000..9a7456aa41 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/imagine-assets/switchdelegate-handle@2x.png diff --git a/examples/quickcontrols/imagine/automotive/imagine-assets/switchdelegate-indicator-pressed.png b/examples/quickcontrols/imagine/automotive/imagine-assets/switchdelegate-indicator-pressed.png Binary files differnew file mode 100644 index 0000000000..6833d624ae --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/imagine-assets/switchdelegate-indicator-pressed.png diff --git a/examples/quickcontrols/imagine/automotive/imagine-assets/switchdelegate-indicator-pressed@2x.png b/examples/quickcontrols/imagine/automotive/imagine-assets/switchdelegate-indicator-pressed@2x.png Binary files differnew file mode 100644 index 0000000000..3d5498a090 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/imagine-assets/switchdelegate-indicator-pressed@2x.png diff --git a/examples/quickcontrols/imagine/automotive/imagine-assets/switchdelegate-indicator.png b/examples/quickcontrols/imagine/automotive/imagine-assets/switchdelegate-indicator.png Binary files differnew file mode 100644 index 0000000000..3db5fe2042 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/imagine-assets/switchdelegate-indicator.png diff --git a/examples/quickcontrols/imagine/automotive/imagine-assets/switchdelegate-indicator@2x.png b/examples/quickcontrols/imagine/automotive/imagine-assets/switchdelegate-indicator@2x.png Binary files differnew file mode 100644 index 0000000000..b5c10f7497 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/imagine-assets/switchdelegate-indicator@2x.png diff --git a/examples/quickcontrols/imagine/automotive/imagine-assets/toolseparator-separator-vertical.9.png b/examples/quickcontrols/imagine/automotive/imagine-assets/toolseparator-separator-vertical.9.png Binary files differnew file mode 100644 index 0000000000..02c7a564be --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/imagine-assets/toolseparator-separator-vertical.9.png diff --git a/examples/quickcontrols/imagine/automotive/imagine-assets/toolseparator-separator-vertical@2x.9.png b/examples/quickcontrols/imagine/automotive/imagine-assets/toolseparator-separator-vertical@2x.9.png Binary files differnew file mode 100644 index 0000000000..e0390d36f5 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/imagine-assets/toolseparator-separator-vertical@2x.9.png diff --git a/examples/quickcontrols/imagine/automotive/qml/FeatureButton.qml b/examples/quickcontrols/imagine/automotive/qml/FeatureButton.qml new file mode 100644 index 0000000000..a9dee571fb --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/qml/FeatureButton.qml @@ -0,0 +1,23 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls + +Button { + id: button + checkable: true + font.pixelSize: fontSizeExtraSmall + leftPadding: 4 + rightPadding: 4 + topPadding: 12 + bottomPadding: 12 + implicitWidth: 60 + implicitHeight: 90 + + icon.name: "placeholder" + icon.width: 44 + icon.height: 44 + display: Button.TextUnderIcon +} diff --git a/examples/quickcontrols/imagine/automotive/qml/LargeLabel.qml b/examples/quickcontrols/imagine/automotive/qml/LargeLabel.qml new file mode 100644 index 0000000000..af03c782ff --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/qml/LargeLabel.qml @@ -0,0 +1,37 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Controls + +// This container and the transform on the Label are +// necessary to get precise bounding rect of the text for layouting reasons, +// since some of the labels' font sizes can get quite large. +Item { + id: root + implicitHeight: labelTextMetrics.tightBoundingRect.height + implicitWidth: label.implicitWidth + + property alias text: label.text + property alias font: label.font + property alias horizontalAlignment: label.horizontalAlignment + property alias verticalAlignment: label.verticalAlignment + property bool glowEnabled: true + property color color: colorBright + + Label { + id: label + anchors.baseline: root.baseline + color: root.color + + TextMetrics { + id: labelTextMetrics + text: label.text + font: label.font + } + + transform: Translate { + y: -labelTextMetrics.tightBoundingRect.y + } + } +} diff --git a/examples/quickcontrols/imagine/automotive/qml/automotive.qml b/examples/quickcontrols/imagine/automotive/qml/automotive.qml new file mode 100644 index 0000000000..5f7868e760 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/qml/automotive.qml @@ -0,0 +1,588 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Controls.Imagine +import QtQuick.Window + +ApplicationWindow { + id: window + width: 1280 + height: 720 + minimumWidth: 1180 + minimumHeight: 663 + visible: true + title: "Qt Quick Controls - Imagine Style Example: Automotive" + + readonly property color colorGlow: "#1d6d64" + readonly property color colorWarning: "#d5232f" + readonly property color colorMain: "#6affcd" + readonly property color colorBright: "#ffffff" + readonly property color colorLightGrey: "#888" + readonly property color colorDarkGrey: "#333" + + readonly property int fontSizeExtraSmall: Qt.application.font.pixelSize * 0.8 + readonly property int fontSizeMedium: Qt.application.font.pixelSize * 1.5 + readonly property int fontSizeLarge: Qt.application.font.pixelSize * 2 + readonly property int fontSizeExtraLarge: Qt.application.font.pixelSize * 5 + + Component.onCompleted: { + x = Screen.width / 2 - width / 2 + y = Screen.height / 2 - height / 2 + } + + Shortcut { + sequence: "Ctrl+Q" + onActivated: Qt.quit() + } + + Frame { + id: frame + anchors.fill: parent + anchors.margins: 90 + + RowLayout { + id: mainRowLayout + anchors.fill: parent + anchors.margins: 24 + spacing: 36 + + Container { + id: leftTabBar + + currentIndex: 1 + + Layout.fillWidth: false + Layout.fillHeight: true + + ButtonGroup { + buttons: columnLayout.children + } + + contentItem: ColumnLayout { + id: columnLayout + spacing: 3 + + Repeater { + model: leftTabBar.contentModel + } + } + + FeatureButton { + id: navigationFeatureButton + text: qsTr("Navigation") + icon.name: "navigation" + Layout.fillHeight: true + } + + FeatureButton { + text: qsTr("Music") + icon.name: "music" + checked: true + Layout.fillHeight: true + } + + FeatureButton { + text: qsTr("Message") + icon.name: "message" + Layout.fillHeight: true + } + + FeatureButton { + text: qsTr("Command") + icon.name: "command" + Layout.fillHeight: true + } + + FeatureButton { + text: qsTr("Settings") + icon.name: "settings" + Layout.fillHeight: true + } + } + + StackLayout { + currentIndex: leftTabBar.currentIndex + + Layout.preferredWidth: 150 + Layout.maximumWidth: 150 + Layout.fillWidth: false + + Item {} + + ColumnLayout { + spacing: 16 + + ButtonGroup { + id: viewButtonGroup + buttons: viewTypeRowLayout.children + } + + RowLayout { + id: viewTypeRowLayout + spacing: 3 + + Layout.bottomMargin: 12 + + Button { + text: qsTr("Compact") + font.pixelSize: fontSizeExtraSmall + checked: true + + Layout.fillWidth: true + } + Button { + text: qsTr("Full") + font.pixelSize: fontSizeExtraSmall + checkable: true + + Layout.fillWidth: true + } + } + + LargeLabel { + text: qsTr("VOLUME") + color: "white" + font.pixelSize: fontSizeMedium + } + + Dial { + id: volumeDial + from: 0 + value: 42 + to: 100 + stepSize: 1 + + Layout.alignment: Qt.AlignHCenter + Layout.minimumWidth: 64 + Layout.minimumHeight: 64 + Layout.preferredWidth: 128 + Layout.preferredHeight: 128 + Layout.maximumWidth: 128 + Layout.maximumHeight: 128 + Layout.fillHeight: true + + Label { + text: volumeDial.value.toFixed(0) + color: "white" + font.pixelSize: Qt.application.font.pixelSize * 3 + anchors.centerIn: parent + } + } + + ButtonGroup { + id: audioSourceButtonGroup + } + + RowLayout { + Layout.topMargin: 16 + + LargeLabel { + id: radioOption + text: qsTr("RADIO") + color: "white" + font.pixelSize: fontSizeMedium + horizontalAlignment: Label.AlignLeft + + Layout.fillWidth: true + } + LargeLabel { + text: qsTr("AUX") + color: colorLightGrey + font.pixelSize: fontSizeMedium * 0.8 + horizontalAlignment: Label.AlignHCenter + glowEnabled: false + + Layout.alignment: Qt.AlignBottom + Layout.fillWidth: true + } + LargeLabel { + text: qsTr("MP3") + color: colorDarkGrey + font.pixelSize: fontSizeMedium * 0.6 + horizontalAlignment: Label.AlignRight + glowEnabled: false + + Layout.alignment: Qt.AlignBottom + Layout.fillWidth: true + } + } + + Frame { + id: stationFrame + leftPadding: 1 + rightPadding: 1 + topPadding: 1 + bottomPadding: 1 + + Layout.fillWidth: true + Layout.fillHeight: true + Layout.preferredHeight: 128 + + ListView { + id: stationListView + clip: true + anchors.fill: parent + + ScrollIndicator.vertical: ScrollIndicator { + parent: stationFrame + anchors.top: parent.top + anchors.right: parent.right + anchors.rightMargin: 1 + anchors.bottom: parent.bottom + } + + model: ListModel { + ListElement { name: "V-Radio"; frequency: "105.5 MHz" } + ListElement { name: "World News"; frequency: "93.4 MHz" } + ListElement { name: "TekStep FM"; frequency: "95.0 MHz" } + ListElement { name: "Classic Radio"; frequency: "89.9 MHz" } + ListElement { name: "Buena Vista FM"; frequency: "100.8 MHz" } + ListElement { name: "Drive-by Radio"; frequency: "99.1 MHz" } + ListElement { name: "Unknown #1"; frequency: "104.5 MHz" } + ListElement { name: "Unknown #2"; frequency: "91.2 MHz" } + ListElement { name: "Unknown #3"; frequency: "93.8 MHz" } + ListElement { name: "Unknown #4"; frequency: "80.4 MHz" } + ListElement { name: "Unknown #5"; frequency: "101.1 MHz" } + ListElement { name: "Unknown #6"; frequency: "92.2 MHz" } + } + delegate: ItemDelegate { + id: stationDelegate + width: stationListView.width + height: 22 + text: model.name + font.pixelSize: fontSizeExtraSmall + topPadding: 0 + bottomPadding: 0 + + contentItem: RowLayout { + Label { + text: model.name + font: stationDelegate.font + horizontalAlignment: Text.AlignLeft + Layout.fillWidth: true + } + Label { + text: model.frequency + font: stationDelegate.font + horizontalAlignment: Text.AlignRight + Layout.fillWidth: true + } + } + } + } + } + + Frame { + Layout.fillWidth: true + + RowLayout { + anchors.fill: parent + + Label { + text: qsTr("Sort by") + font.pixelSize: fontSizeExtraSmall + + Layout.alignment: Qt.AlignTop + } + + ColumnLayout { + RadioButton { + text: qsTr("Name") + font.pixelSize: fontSizeExtraSmall + } + RadioButton { + text: qsTr("Frequency") + font.pixelSize: fontSizeExtraSmall + } + RadioButton { + text: qsTr("Favourites") + font.pixelSize: fontSizeExtraSmall + checked: true + } + } + } + } + } + } + + Rectangle { + color: colorMain + implicitWidth: 1 + Layout.fillHeight: true + } + + ColumnLayout { + Layout.preferredWidth: 350 + Layout.fillWidth: true + Layout.fillHeight: true + + LargeLabel { + id: timeLabel + text: qsTr("11:02") + font.pixelSize: fontSizeExtraLarge + + Layout.alignment: Qt.AlignHCenter + + LargeLabel { + text: qsTr("AM") + font.pixelSize: fontSizeLarge + anchors.left: parent.right + anchors.leftMargin: 8 + } + } + + Label { + text: qsTr("01/01/2018") + color: colorLightGrey + font.pixelSize: fontSizeMedium + + Layout.alignment: Qt.AlignHCenter + Layout.topMargin: 2 + Layout.bottomMargin: 10 + } + + Image { + source: "qrc:/icons/car.png" + fillMode: Image.PreserveAspectFit + + Layout.fillHeight: true + + Column { + x: parent.width * 0.88 + y: parent.height * 0.56 + spacing: 3 + + Image { + source: "qrc:/icons/warning.png" + anchors.horizontalCenter: parent.horizontalCenter + } + + LargeLabel { + text: qsTr("Door open") + color: colorWarning + } + } + } + } + + Rectangle { + color: colorMain + implicitWidth: 1 + Layout.fillHeight: true + } + + ColumnLayout { + Row { + spacing: 8 + + Image { + source: "qrc:/icons/weather.png" + } + + Column { + spacing: 8 + + Row { + anchors.horizontalCenter: parent.horizontalCenter + + LargeLabel { + id: outsideTempValueLabel + text: qsTr("31") + font.pixelSize: fontSizeExtraLarge + } + + LargeLabel { + text: qsTr("°C") + font.pixelSize: Qt.application.font.pixelSize * 2.5 + anchors.baseline: outsideTempValueLabel.baseline + } + } + + Label { + text: qsTr("Osaka, Japan") + color: colorLightGrey + font.pixelSize: fontSizeMedium + } + } + } + + ColumnLayout { + id: airConRowLayout + spacing: 8 + + Layout.preferredWidth: 128 + Layout.preferredHeight: 380 + Layout.fillHeight: true + + Item { + Layout.fillHeight: true + } + + SwitchDelegate { + text: qsTr("AC") + leftPadding: 0 + rightPadding: 0 + topPadding: 0 + bottomPadding: 0 + + Layout.fillWidth: true + } + + // QTBUG-63269 + Item { + implicitHeight: temperatureValueLabel.implicitHeight + Layout.fillWidth: true + Layout.topMargin: 16 + + Label { + text: qsTr("Temperature") + anchors.baseline: temperatureValueLabel.bottom + anchors.left: parent.left + } + + LargeLabel { + id: temperatureValueLabel + text: qsTr("24°C") + font.pixelSize: fontSizeLarge + anchors.right: parent.right + } + } + + Slider { + value: 0.35 + Layout.fillWidth: true + } + + // QTBUG-63269 + Item { + implicitHeight: powerValueLabel.implicitHeight + Layout.fillWidth: true + Layout.topMargin: 16 + + Label { + text: qsTr("Power") + anchors.baseline: powerValueLabel.bottom + anchors.left: parent.left + } + + LargeLabel { + id: powerValueLabel + text: qsTr("10%") + font.pixelSize: fontSizeLarge + anchors.right: parent.right + } + } + + Slider { + value: 0.25 + Layout.fillWidth: true + } + + SwitchDelegate { + text: qsTr("Low") + leftPadding: 0 + rightPadding: 0 + topPadding: 0 + bottomPadding: 0 + + Layout.fillWidth: true + Layout.topMargin: 16 + } + + SwitchDelegate { + text: qsTr("High") + checked: true + leftPadding: 0 + rightPadding: 0 + topPadding: 0 + bottomPadding: 0 + + Layout.fillWidth: true + } + + SwitchDelegate { + text: qsTr("Defog") + leftPadding: 0 + rightPadding: 0 + topPadding: 0 + bottomPadding: 0 + + Layout.fillWidth: true + } + + SwitchDelegate { + text: qsTr("Recirculate") + leftPadding: 0 + rightPadding: 0 + topPadding: 0 + bottomPadding: 0 + + Layout.fillWidth: true + } + + Item { + Layout.fillHeight: true + } + } + } + + Container { + id: rightTabBar + + currentIndex: 1 + + Layout.fillHeight: true + + ButtonGroup { + buttons: rightTabBarContentLayout.children + } + + contentItem: ColumnLayout { + id: rightTabBarContentLayout + spacing: 3 + + Repeater { + model: rightTabBar.contentModel + } + } + + Item { + Layout.fillHeight: true + } + + FeatureButton { + text: qsTr("Windows") + icon.name: "windows" + + Layout.maximumHeight: navigationFeatureButton.height + Layout.fillHeight: true + } + FeatureButton { + text: qsTr("Air Con.") + icon.name: "air-con" + checked: true + + Layout.maximumHeight: navigationFeatureButton.height + Layout.fillHeight: true + } + FeatureButton { + text: qsTr("Seats") + icon.name: "seats" + + Layout.maximumHeight: navigationFeatureButton.height + Layout.fillHeight: true + } + FeatureButton { + text: qsTr("Statistics") + icon.name: "statistics" + + Layout.maximumHeight: navigationFeatureButton.height + Layout.fillHeight: true + } + } + } + } +} diff --git a/examples/quickcontrols/imagine/automotive/qml/qml.qrc b/examples/quickcontrols/imagine/automotive/qml/qml.qrc new file mode 100644 index 0000000000..b0e4e558a8 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/qml/qml.qrc @@ -0,0 +1,7 @@ +<RCC> + <qresource prefix="/qml"> + <file>FeatureButton.qml</file> + <file>automotive.qml</file> + <file>LargeLabel.qml</file> + </qresource> +</RCC> diff --git a/examples/quickcontrols/imagine/automotive/qtquickcontrols2.conf b/examples/quickcontrols/imagine/automotive/qtquickcontrols2.conf new file mode 100644 index 0000000000..c7fc7a6169 --- /dev/null +++ b/examples/quickcontrols/imagine/automotive/qtquickcontrols2.conf @@ -0,0 +1,10 @@ +[Controls] +Style=Imagine + +[Imagine] +Path=:/imagine-assets + +[Imagine\Palette] +Text=#6affcd +ButtonText=#6affcd +WindowText=#6affcd diff --git a/examples/quickcontrols/imagine/musicplayer/CMakeLists.txt b/examples/quickcontrols/imagine/musicplayer/CMakeLists.txt new file mode 100644 index 0000000000..a3f0bf5683 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/CMakeLists.txt @@ -0,0 +1,188 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +cmake_minimum_required(VERSION 3.16) +project(musicplayer LANGUAGES CXX) + +set(CMAKE_AUTOMOC ON) + +if(NOT DEFINED INSTALL_EXAMPLESDIR) + set(INSTALL_EXAMPLESDIR "examples") +endif() + +set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/quickcontrols2/imagine/musicplayer") + +find_package(Qt6 REQUIRED COMPONENTS Core Gui Quick QuickControls2) + +qt_add_executable(musicplayerexample WIN32 MACOSX_BUNDLE + musicplayer.cpp +) + +qt_add_qml_module(musicplayerexample + URI musicplayer + VERSION 1.0 + NO_RESOURCE_TARGET_PATH + QML_FILES + "musicplayer.qml" + RESOURCES + "icons/musicplayer/32x32/bluetooth.png" + "icons/musicplayer/32x32/cart.png" + "icons/musicplayer/32x32/cloud.png" + "icons/musicplayer/32x32/favorite.png" + "icons/musicplayer/32x32/filter.png" + "icons/musicplayer/32x32/folder.png" + "icons/musicplayer/32x32/message.png" + "icons/musicplayer/32x32/music.png" + "icons/musicplayer/32x32/next.png" + "icons/musicplayer/32x32/pause.png" + "icons/musicplayer/32x32/power.png" + "icons/musicplayer/32x32/previous.png" + "icons/musicplayer/32x32/repeat.png" + "icons/musicplayer/32x32/save.png" + "icons/musicplayer/32x32/settings.png" + "icons/musicplayer/32x32/shuffle.png" + "icons/musicplayer/32x32/stop.png" + "icons/musicplayer/32x32@2/bluetooth.png" + "icons/musicplayer/32x32@2/cart.png" + "icons/musicplayer/32x32@2/cloud.png" + "icons/musicplayer/32x32@2/favorite.png" + "icons/musicplayer/32x32@2/filter.png" + "icons/musicplayer/32x32@2/folder.png" + "icons/musicplayer/32x32@2/grid.png" + "icons/musicplayer/32x32@2/message.png" + "icons/musicplayer/32x32@2/music.png" + "icons/musicplayer/32x32@2/next.png" + "icons/musicplayer/32x32@2/pause.png" + "icons/musicplayer/32x32@2/power.png" + "icons/musicplayer/32x32@2/previous.png" + "icons/musicplayer/32x32@2/repeat.png" + "icons/musicplayer/32x32@2/save.png" + "icons/musicplayer/32x32@2/settings.png" + "icons/musicplayer/32x32@2/shuffle.png" + "icons/musicplayer/32x32@2/stop.png" + "icons/musicplayer/index.theme" + "images/album-cover.jpg" + "imagine-assets/applicationwindow-background.png" + "imagine-assets/button-background-checked-hovered.9.png" + "imagine-assets/button-background-checked-hovered@2x.9.png" + "imagine-assets/button-background-checked.9.png" + "imagine-assets/button-background-checked@2x.9.png" + "imagine-assets/button-background-disabled.9.png" + "imagine-assets/button-background-disabled@2x.9.png" + "imagine-assets/button-background-hovered.9.png" + "imagine-assets/button-background-hovered@2x.9.png" + "imagine-assets/button-background-pressed.9.png" + "imagine-assets/button-background-pressed@2x.9.png" + "imagine-assets/button-background.9.png" + "imagine-assets/button-background@2x.9.png" + "imagine-assets/combobox-background-hovered.9.png" + "imagine-assets/combobox-background-hovered@2x.9.png" + "imagine-assets/combobox-background-open.9.png" + "imagine-assets/combobox-background-open@2x.9.png" + "imagine-assets/combobox-background-pressed.9.png" + "imagine-assets/combobox-background-pressed@2x.9.png" + "imagine-assets/combobox-background.9.png" + "imagine-assets/combobox-background@2x.9.png" + "imagine-assets/combobox-indicator-hovered.png" + "imagine-assets/combobox-indicator-hovered@2x.png" + "imagine-assets/combobox-indicator-open.png" + "imagine-assets/combobox-indicator-open@2x.png" + "imagine-assets/combobox-indicator-pressed.png" + "imagine-assets/combobox-indicator-pressed@2x.png" + "imagine-assets/combobox-indicator.png" + "imagine-assets/combobox-indicator@2x.png" + "imagine-assets/combobox-popup.9.png" + "imagine-assets/combobox-popup@2x.9.png" + "imagine-assets/dial-background-hovered.png" + "imagine-assets/dial-background-hovered@2x.png" + "imagine-assets/dial-background-pressed.png" + "imagine-assets/dial-background-pressed@2x.png" + "imagine-assets/dial-background.png" + "imagine-assets/dial-background@2x.png" + "imagine-assets/dial-handle-pressed.png" + "imagine-assets/dial-handle-pressed@2x.png" + "imagine-assets/dial-handle.png" + "imagine-assets/dial-handle@2x.png" + "imagine-assets/frame-background.9.png" + "imagine-assets/frame-background@2x.9.png" + "imagine-assets/itemdelegate-background-checked.9.png" + "imagine-assets/itemdelegate-background-checked@2x.9.png" + "imagine-assets/itemdelegate-background-disabled.9.png" + "imagine-assets/itemdelegate-background-disabled@2x.9.png" + "imagine-assets/itemdelegate-background-hovered.9.png" + "imagine-assets/itemdelegate-background-hovered@2x.9.png" + "imagine-assets/itemdelegate-background-pressed.9.png" + "imagine-assets/itemdelegate-background-pressed@2x.9.png" + "imagine-assets/itemdelegate-background.9.png" + "imagine-assets/itemdelegate-background@2x.9.png" + "imagine-assets/roundbutton-background-checked-hovered.png" + "imagine-assets/roundbutton-background-checked-hovered@2x.png" + "imagine-assets/roundbutton-background-checked.png" + "imagine-assets/roundbutton-background-checked@2x.png" + "imagine-assets/roundbutton-background-disabled.png" + "imagine-assets/roundbutton-background-disabled@2x.png" + "imagine-assets/roundbutton-background-hovered.png" + "imagine-assets/roundbutton-background-hovered@2x.png" + "imagine-assets/roundbutton-background-pressed.png" + "imagine-assets/roundbutton-background-pressed@2x.png" + "imagine-assets/roundbutton-background.png" + "imagine-assets/roundbutton-background@2x.png" + "imagine-assets/scrollbar-handle-interactive-hovered.png" + "imagine-assets/scrollbar-handle-interactive-hovered@2x.png" + "imagine-assets/scrollbar-handle-interactive-pressed.png" + "imagine-assets/scrollbar-handle-interactive-pressed@2x.png" + "imagine-assets/scrollbar-handle-interactive.png" + "imagine-assets/scrollbar-handle-interactive@2x.png" + "imagine-assets/slider-background-horizontal-disabled.9.png" + "imagine-assets/slider-background-horizontal-disabled@2x.9.png" + "imagine-assets/slider-background-horizontal.9.png" + "imagine-assets/slider-background-horizontal@2x.9.png" + "imagine-assets/slider-background-vertical-disabled.9.png" + "imagine-assets/slider-background-vertical-disabled@2x.9.png" + "imagine-assets/slider-background-vertical.9.png" + "imagine-assets/slider-background-vertical@2x.9.png" + "imagine-assets/slider-handle-disabled.png" + "imagine-assets/slider-handle-disabled@2x.png" + "imagine-assets/slider-handle-hovered.png" + "imagine-assets/slider-handle-hovered@2x.png" + "imagine-assets/slider-handle.png" + "imagine-assets/slider-handle@2x.png" + "imagine-assets/slider-progress-horizontal.9.png" + "imagine-assets/slider-progress-horizontal@2x.9.png" + "imagine-assets/slider-progress-vertical-disabled.9.png" + "imagine-assets/slider-progress-vertical-disabled@2x.9.png" + "imagine-assets/slider-progress-vertical.9.png" + "imagine-assets/slider-progress-vertical@2x.9.png" + "imagine-assets/textfield-background-disabled.9.png" + "imagine-assets/textfield-background-disabled@2x.9.png" + "imagine-assets/textfield-background.9.png" + "imagine-assets/textfield-background@2x.9.png" + "imagine-assets/toolbar-background.9.png" + "imagine-assets/toolbar-background@2x.9.png" + "imagine-assets/toolbutton-background-checked-hovered.9.png" + "imagine-assets/toolbutton-background-checked-hovered@2x.9.png" + "imagine-assets/toolbutton-background-checked.9.png" + "imagine-assets/toolbutton-background-checked@2x.9.png" + "imagine-assets/toolbutton-background-hovered.9.png" + "imagine-assets/toolbutton-background-hovered@2x.9.png" + "imagine-assets/toolbutton-background-pressed.9.png" + "imagine-assets/toolbutton-background-pressed@2x.9.png" + "imagine-assets/toolbutton-background.9.png" + "imagine-assets/toolbutton-background@2x.9.png" + "imagine-assets/tooltip-background.9.png" + "imagine-assets/tooltip-background@2x.9.png" + "qtquickcontrols2.conf" +) + +target_link_libraries(musicplayerexample PUBLIC + Qt::Core + Qt::Gui + Qt::Quick + Qt::QuickControls2 +) + +install(TARGETS musicplayerexample + RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" + LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" +) diff --git a/examples/quickcontrols/imagine/musicplayer/doc/images/qtquickcontrols2-musicplayer.png b/examples/quickcontrols/imagine/musicplayer/doc/images/qtquickcontrols2-musicplayer.png Binary files differnew file mode 100644 index 0000000000..25b6344f3e --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/doc/images/qtquickcontrols2-musicplayer.png diff --git a/examples/quickcontrols/imagine/musicplayer/doc/src/qtquickcontrols2-musicplayer.qdoc b/examples/quickcontrols/imagine/musicplayer/doc/src/qtquickcontrols2-musicplayer.qdoc new file mode 100644 index 0000000000..742b412c96 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/doc/src/qtquickcontrols2-musicplayer.qdoc @@ -0,0 +1,35 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only + +/*! + \example imagine/musicplayer + \keyword Qt Quick Controls - Imagine Style Example: Music Player + \title Qt Quick Controls - Imagine Style Example: Music Player + \keyword Qt Quick Controls 2 - Imagine Style Example: Music Player + \ingroup qtquickcontrols2-examples + \brief An audio player user interface using custom Imagine style assets. + + This example demonstrates how custom Imagine style assets + can be used to style a user interface for an audio player application. + + \image qtquickcontrols2-musicplayer.png + + \omit + The assets are generated from a Photoshop file: \e musicplayer.psd. + This file can found in the \e design folder in the example directory. + All objects related to a particular asset are collected in a layer group. + For example, the assets for Button's background element are under a layer group with the following name: + + \badcode + 100% button-background.9.png, 200% button-background@2x.9.png, 300% button-background@3x.9.png, 400% button-background@4x.9.png + \endcode + + Using Photoshop's \l {Generate Image Assets}{https://helpx.adobe.com/photoshop/using/generate-assets-layers.html} feature, + the size and name for each asset are encoded into the name of the layer group. + + Where applicable, \l {Smart Objects}{https://helpx.adobe.com/photoshop/using/create-smart-objects.html} + are used to reduce duplication for common objects such as 9-patch lines. + \endomit + + \include examples-run.qdocinc +*/ diff --git a/examples/quickcontrols/imagine/musicplayer/icons/icons.qrc b/examples/quickcontrols/imagine/musicplayer/icons/icons.qrc new file mode 100644 index 0000000000..870b4445e5 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/icons/icons.qrc @@ -0,0 +1,40 @@ +<RCC> + <qresource prefix="/icons"> + <file>musicplayer/index.theme</file> + <file>musicplayer/32x32/bluetooth.png</file> + <file>musicplayer/32x32/cart.png</file> + <file>musicplayer/32x32/cloud.png</file> + <file>musicplayer/32x32/filter.png</file> + <file>musicplayer/32x32/folder.png</file> + <file>musicplayer/32x32/message.png</file> + <file>musicplayer/32x32/music.png</file> + <file>musicplayer/32x32/next.png</file> + <file>musicplayer/32x32/pause.png</file> + <file>musicplayer/32x32/power.png</file> + <file>musicplayer/32x32/previous.png</file> + <file>musicplayer/32x32/repeat.png</file> + <file>musicplayer/32x32/save.png</file> + <file>musicplayer/32x32/settings.png</file> + <file>musicplayer/32x32/shuffle.png</file> + <file>musicplayer/32x32/stop.png</file> + <file>musicplayer/32x32@2/bluetooth.png</file> + <file>musicplayer/32x32@2/cart.png</file> + <file>musicplayer/32x32@2/cloud.png</file> + <file>musicplayer/32x32@2/filter.png</file> + <file>musicplayer/32x32@2/folder.png</file> + <file>musicplayer/32x32@2/grid.png</file> + <file>musicplayer/32x32@2/message.png</file> + <file>musicplayer/32x32@2/music.png</file> + <file>musicplayer/32x32@2/next.png</file> + <file>musicplayer/32x32@2/pause.png</file> + <file>musicplayer/32x32@2/power.png</file> + <file>musicplayer/32x32@2/previous.png</file> + <file>musicplayer/32x32@2/repeat.png</file> + <file>musicplayer/32x32@2/save.png</file> + <file>musicplayer/32x32@2/settings.png</file> + <file>musicplayer/32x32@2/shuffle.png</file> + <file>musicplayer/32x32@2/stop.png</file> + <file>musicplayer/32x32/favorite.png</file> + <file>musicplayer/32x32@2/favorite.png</file> + </qresource> +</RCC> diff --git a/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32/bluetooth.png b/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32/bluetooth.png Binary files differnew file mode 100644 index 0000000000..925f564c9e --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32/bluetooth.png diff --git a/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32/cart.png b/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32/cart.png Binary files differnew file mode 100644 index 0000000000..4d5ad09955 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32/cart.png diff --git a/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32/cloud.png b/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32/cloud.png Binary files differnew file mode 100644 index 0000000000..62ef511833 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32/cloud.png diff --git a/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32/favorite.png b/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32/favorite.png Binary files differnew file mode 100644 index 0000000000..16ea84deb6 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32/favorite.png diff --git a/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32/filter.png b/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32/filter.png Binary files differnew file mode 100644 index 0000000000..4472cead58 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32/filter.png diff --git a/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32/folder.png b/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32/folder.png Binary files differnew file mode 100644 index 0000000000..5dd05778fd --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32/folder.png diff --git a/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32/message.png b/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32/message.png Binary files differnew file mode 100644 index 0000000000..1d93b3c660 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32/message.png diff --git a/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32/music.png b/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32/music.png Binary files differnew file mode 100644 index 0000000000..4448921389 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32/music.png diff --git a/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32/next.png b/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32/next.png Binary files differnew file mode 100644 index 0000000000..ab9164e877 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32/next.png diff --git a/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32/pause.png b/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32/pause.png Binary files differnew file mode 100644 index 0000000000..9c9ef8fa60 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32/pause.png diff --git a/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32/power.png b/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32/power.png Binary files differnew file mode 100644 index 0000000000..8f7d0c778c --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32/power.png diff --git a/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32/previous.png b/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32/previous.png Binary files differnew file mode 100644 index 0000000000..3a0880fdbc --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32/previous.png diff --git a/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32/repeat.png b/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32/repeat.png Binary files differnew file mode 100644 index 0000000000..7c8e8c1c2d --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32/repeat.png diff --git a/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32/save.png b/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32/save.png Binary files differnew file mode 100644 index 0000000000..c0b2748327 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32/save.png diff --git a/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32/settings.png b/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32/settings.png Binary files differnew file mode 100644 index 0000000000..7992146a6e --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32/settings.png diff --git a/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32/shuffle.png b/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32/shuffle.png Binary files differnew file mode 100644 index 0000000000..885782a219 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32/shuffle.png diff --git a/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32/stop.png b/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32/stop.png Binary files differnew file mode 100644 index 0000000000..3e9c332732 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32/stop.png diff --git a/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32@2/bluetooth.png b/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32@2/bluetooth.png Binary files differnew file mode 100644 index 0000000000..2e70afc396 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32@2/bluetooth.png diff --git a/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32@2/cart.png b/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32@2/cart.png Binary files differnew file mode 100644 index 0000000000..5717dd6582 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32@2/cart.png diff --git a/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32@2/cloud.png b/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32@2/cloud.png Binary files differnew file mode 100644 index 0000000000..ce5ab9f991 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32@2/cloud.png diff --git a/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32@2/favorite.png b/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32@2/favorite.png Binary files differnew file mode 100644 index 0000000000..ddc9aa45c8 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32@2/favorite.png diff --git a/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32@2/filter.png b/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32@2/filter.png Binary files differnew file mode 100644 index 0000000000..3632c556fe --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32@2/filter.png diff --git a/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32@2/folder.png b/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32@2/folder.png Binary files differnew file mode 100644 index 0000000000..49d41e202e --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32@2/folder.png diff --git a/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32@2/grid.png b/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32@2/grid.png Binary files differnew file mode 100644 index 0000000000..8a1624e70b --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32@2/grid.png diff --git a/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32@2/message.png b/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32@2/message.png Binary files differnew file mode 100644 index 0000000000..6650f26b6a --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32@2/message.png diff --git a/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32@2/music.png b/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32@2/music.png Binary files differnew file mode 100644 index 0000000000..2cb8d49a67 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32@2/music.png diff --git a/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32@2/next.png b/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32@2/next.png Binary files differnew file mode 100644 index 0000000000..d7bb4b278e --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32@2/next.png diff --git a/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32@2/pause.png b/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32@2/pause.png Binary files differnew file mode 100644 index 0000000000..8a081d02f3 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32@2/pause.png diff --git a/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32@2/power.png b/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32@2/power.png Binary files differnew file mode 100644 index 0000000000..1201e55b4f --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32@2/power.png diff --git a/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32@2/previous.png b/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32@2/previous.png Binary files differnew file mode 100644 index 0000000000..4236afdbbd --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32@2/previous.png diff --git a/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32@2/repeat.png b/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32@2/repeat.png Binary files differnew file mode 100644 index 0000000000..c8cb06d84d --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32@2/repeat.png diff --git a/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32@2/save.png b/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32@2/save.png Binary files differnew file mode 100644 index 0000000000..448b25e4be --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32@2/save.png diff --git a/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32@2/settings.png b/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32@2/settings.png Binary files differnew file mode 100644 index 0000000000..12a0cf6b76 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32@2/settings.png diff --git a/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32@2/shuffle.png b/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32@2/shuffle.png Binary files differnew file mode 100644 index 0000000000..22b901cce9 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32@2/shuffle.png diff --git a/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32@2/stop.png b/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32@2/stop.png Binary files differnew file mode 100644 index 0000000000..0521a943d4 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/32x32@2/stop.png diff --git a/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/icons.svg b/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/icons.svg new file mode 100644 index 0000000000..4cede992c3 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/icons.svg @@ -0,0 +1,648 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + version="1.1" + id="svg4485" + width="1116.5374" + height="64" + viewBox="0 0 1116.5374 63.999997" + sodipodi:docname="icons.svg" + inkscape:version="0.92.2 (5c3e80d, 2017-08-06)"> + <metadata + id="metadata4491"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title /> + </cc:Work> + </rdf:RDF> + </metadata> + <defs + id="defs4489" /> + <sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="1920" + inkscape:window-height="1017" + id="namedview4487" + showgrid="true" + inkscape:zoom="1.9019737" + inkscape:cx="833.25423" + inkscape:cy="74.046593" + inkscape:window-x="-8" + inkscape:window-y="-8" + inkscape:window-maximized="1" + inkscape:current-layer="svg4485" + inkscape:snap-grids="false" + inkscape:object-nodes="false" + fit-margin-top="2.7755576e-017" + fit-margin-left="0" + fit-margin-right="0" + fit-margin-bottom="0"> + <inkscape:grid + type="xygrid" + id="grid4517" + originx="-8.3788162" + originy="-6.3974667" /> + </sodipodi:namedview> + <g + id="g5472" + transform="translate(0,3.2401047)" + inkscape:export-filename="C:\dev\qqc2-technical-style-demo\icons\technical\32x32@2\grid.png" + inkscape:export-xdpi="192" + inkscape:export-ydpi="192"> + <g + transform="translate(-8.3787758,-966.40258)" + id="g5318"> + <rect + y="998.53882" + x="27.755102" + height="9.2473469" + width="9.2473469" + id="rect4501" + style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:3;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal" /> + <rect + y="1014.5388" + x="11.755102" + height="9.2473469" + width="9.2473469" + id="rect4513" + style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:3;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal" /> + <rect + style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:3;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal" + id="rect4515" + width="9.2473469" + height="9.2473469" + x="27.755102" + y="1014.5388" /> + <rect + style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:3;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal" + id="rect4519" + width="9.2473469" + height="9.2473469" + x="11.755102" + y="998.53882" /> + </g> + <rect + y="28.759895" + x="0" + height="32" + width="32" + id="rect5360" + style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal" /> + </g> + <g + id="g5478" + transform="translate(0,3.6478805)" + inkscape:export-filename="C:\dev\qqc2-technical-style-demo\icons\technical\32x32\settings.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96"> + <g + transform="translate(-8.3787758,-966.40258)" + id="g5322"> + <path + style="fill:none;stroke:#000000;stroke-width:5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 84.166529,1022.8327 69.433468,1008.4131" + id="path4507" + inkscape:connector-curvature="0" /> + <path + style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="m 64.778344,1000.0771 c 0.15838,-2.21589 0.892654,-3.97239 4.064921,-3.9244 l 5.79089,5.4089 -0.06518,5.0971 -6.56108,6.4293 -4.0079,0.3962 -6.391837,-5.0204 c 0.003,-1.8969 0.615654,-4.5976 3.391837,-4.2539 l 3.804082,2.5118 c 1.756369,-0.3456 2.524226,-1.6258 3.156295,-3.1014 z" + id="path4523" + inkscape:connector-curvature="0" + sodipodi:nodetypes="ccccccccccc" /> + </g> + <rect + style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal" + id="rect5362" + width="32" + height="32" + x="47.771301" + y="28.352119" /> + </g> + <g + id="g5484" + transform="translate(0,1.8732223)" + inkscape:export-filename="C:\dev\qqc2-technical-style-demo\icons\technical\32x32@2\filter.png" + inkscape:export-xdpi="192" + inkscape:export-ydpi="192"> + <g + transform="translate(-8.3787758,-966.40258)" + id="g5326"> + <path + style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 124.017,1012.8017 9.67769,-13.7927 H 108.6116 l 9.37299,13.931 v 13.1097 h 6.03241 z" + id="path4509" + inkscape:connector-curvature="0" + sodipodi:nodetypes="ccccccc" /> + <path + style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 116.70205,1019.6217 h 7.31466" + id="path4525" + inkscape:connector-curvature="0" /> + </g> + <rect + y="30.126778" + x="96.808228" + height="32" + width="32" + id="rect5364" + style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal" /> + </g> + <g + id="g5490" + transform="translate(0,3.322319)" + inkscape:export-filename="C:\dev\qqc2-technical-style-demo\icons\technical\32x32@2\message.png" + inkscape:export-xdpi="192" + inkscape:export-ydpi="192"> + <g + transform="translate(-8.3787758,-966.40258)" + id="g5330"> + <path + style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal" + d="m 155.38109,1005.6573 14.74014,12.3019 14.29684,-12.3019 v 16.8459 h -29.03698 z" + id="rect4527" + inkscape:connector-curvature="0" + sodipodi:nodetypes="cccccc" /> + <path + sodipodi:nodetypes="cccccc" + inkscape:connector-curvature="0" + id="path4532" + d="m 155.38109,1002.206 14.74014,12.8565 14.29684,-12.8565 v -2.5487 h -29.03698 z" + style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal" /> + </g> + <rect + style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal" + id="rect5366" + width="32" + height="32" + x="145.52081" + y="28.677681" /> + </g> + <g + id="g5497" + transform="translate(0,3.5476608)" + inkscape:export-filename="C:\dev\qqc2-technical-style-demo\icons\technical\32x32@2\music.png" + inkscape:export-xdpi="192" + inkscape:export-ydpi="192"> + <g + transform="translate(-8.3787758,-966.40258)" + id="g5335"> + <circle + style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal" + id="path4534" + cx="210.02449" + cy="1019.4025" + r="5.7991834" /> + <circle + r="5.7991834" + cy="1019.4025" + cx="227.51147" + id="circle4536" + style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal" /> + <path + style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:2.77122235;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal" + d="m 214.45548,1019.7112 v -19.81316 c 0,-1.11042 0.86314,-2.00436 1.93529,-2.00436 h 13.59886 c 1.07214,0 1.93528,0.89394 1.93528,2.00436 v 19.81316" + id="rect4538" + inkscape:connector-curvature="0" + sodipodi:nodetypes="cssssc" /> + </g> + <rect + y="28.452339" + x="194.38922" + height="32" + width="32" + id="rect5368" + style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal" /> + </g> + <g + id="g5501" + transform="translate(0,3.1662521)" + inkscape:export-filename="C:\dev\qqc2-technical-style-demo\icons\technical\32x32@2\cloud.png" + inkscape:export-xdpi="192" + inkscape:export-ydpi="192"> + <path + sodipodi:nodetypes="cccscc" + inkscape:connector-curvature="0" + id="rect4181" + d="m 251.48461,45.034419 c 0.4638,-10.8715 12.40207,-12.59447 15.43885,-2.5078 2.73388,0.2127 5.14555,2.6373 5.18665,5.068 0,3.4504 -2.90742,6.2281 -6.51889,6.2281 h -16.54418 c -5.83464,-1.7769 -4.57322,-9.6738 2.43757,-8.7883 z" + style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:2.46805668;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + <rect + style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal" + id="rect5370" + width="32" + height="32" + x="242.73279" + y="28.833748" /> + </g> + <g + id="g5506" + transform="translate(0,2.188591)" + inkscape:export-filename="C:\dev\qqc2-technical-style-demo\icons\technical\32x32\bluetooth.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96"> + <g + transform="translate(-8.3787758,-966.40258)" + id="g5338"> + <path + style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 302.67171,1006.3777 22.49812,12.0249 -9.75572,5.6324 v -23.642 l 9.85555,5.6901 -22.32088,12.5411" + id="path5197" + inkscape:connector-curvature="0" /> + </g> + <rect + y="29.811409" + x="290.75372" + height="32" + width="32" + id="rect5372" + style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal" /> + </g> + <g + id="g5514" + transform="translate(0,3.6180954)" + inkscape:export-filename="C:\dev\qqc2-technical-style-demo\icons\technical\32x32@2\cart.png" + inkscape:export-xdpi="192" + inkscape:export-ydpi="192"> + <g + transform="translate(-8.3787758,-966.40258)" + id="g5344"> + <rect + style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.30289125;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal" + id="rect5199" + width="19.591835" + height="14.419591" + x="355.70938" + y="1002.3185" /> + <path + style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 373.79839,1003.2635 v -5.25054 h 7.75837" + id="path5201" + inkscape:connector-curvature="0" + sodipodi:nodetypes="ccc" /> + <circle + style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal" + id="path5207" + cx="357.12" + cy="1020.8915" + r="2.6644897" /> + <circle + r="2.6644897" + cy="1020.8915" + cx="374.64978" + id="circle5209" + style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal" /> + </g> + <rect + style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal" + id="rect5374" + width="32" + height="32" + x="342.87732" + y="28.381905" /> + </g> + <g + id="g5520" + transform="translate(0,3.3700485)" + inkscape:export-filename="C:\dev\qqc2-technical-style-demo\icons\technical\32x32\power.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96"> + <g + transform="translate(-8.3787758,-966.40258)" + id="g5348"> + <path + style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal" + d="m 423.9111,999.19805 c 4.9899,1.81935 7.7689,6.19995 7.7689,11.81915 0,7.1847 -5.8243,13.009 -13.009,13.009 -7.1847,0 -13.009,-5.8243 -13.009,-13.009 0,-5.2414 3.0998,-9.7589 7.5661,-11.81915" + id="path5211" + inkscape:connector-curvature="0" + sodipodi:nodetypes="cscsc" /> + <rect + style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.90877056;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal" + id="rect5214" + width="3" + height="14.321534" + x="417.20502" + y="996.53888" /> + </g> + <rect + y="28.629951" + x="394.29221" + height="32" + width="32" + id="rect5376" + style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal" /> + </g> + <g + id="g5528" + transform="translate(0,1.3681564)" + inkscape:export-filename="C:\dev\qqc2-technical-style-demo\icons\technical\32x32@2\save.png" + inkscape:export-xdpi="192" + inkscape:export-ydpi="192"> + <g + transform="translate(-8.3787758,-966.40258)" + id="g5354"> + <path + style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 461.313,1007.55 7.71825,-7.7187 H 486.75 v 26.4062 h -25.437 z" + id="path5250" + inkscape:connector-curvature="0" + sodipodi:nodetypes="cccccc" /> + <path + style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 466.625,1002.4875 v 5.625 h 14.1875 v -7.5625" + id="path5252" + inkscape:connector-curvature="0" /> + <rect + style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.85498571;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal" + id="rect5254" + width="3" + height="3" + x="469.43436" + y="1002.7332" /> + <path + inkscape:connector-curvature="0" + id="path5256" + d="m 466.625,1025.1125 v -7.9375 h 14.1875 v 7.875" + style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + sodipodi:nodetypes="cccc" /> + </g> + <rect + style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal" + id="rect5378" + width="32" + height="32" + x="449.65271" + y="30.631844" /> + </g> + <g + id="g5534" + transform="translate(0,2.5602951)" + inkscape:export-filename="C:\dev\qqc2-technical-style-demo\icons\technical\32x32\folder.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96"> + <g + transform="translate(-8.3787758,-972.40258)" + id="g5358"> + <path + id="rect5216" + style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal" + d="m 510.7344,1007.7803 h 6.307 c 1.108,0 2,0.892 2,2 0.058,1.9158 0.4001,5.5746 -2,5.6471 l -6.307,-4e-4 h -2.0004 v -1.9996 l 4e-4,-3.6471 c 1e-4,-1.108 0.892,-2 2,-2 z m 3.3587,3.7123 h 13.2014 c 1.108,0 2.001,0.8774 2.0005,1.9674 v 1.967 h -2.0005 l -13.2014,5e-4 c -1.108,0 -2,-0.8775 -2,-1.9674 0,-1.09 0.892,-1.9674 2,-1.9674 z" + inkscape:connector-curvature="0" + sodipodi:nodetypes="sscccccsscssccsssc" /> + <path + style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal" + d="m 508.8555,1017.2315 v 8.6728 c 0,1.108 0.892,2 2,2 h 16.5957 c 1.108,0 2,-0.892 2,-2 v -8.6728 z" + id="rect5242" + inkscape:connector-curvature="0" + sodipodi:nodetypes="csssscc" /> + </g> + <rect + y="29.439705" + x="494.71381" + height="32" + width="32" + id="rect5380" + style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal" /> + </g> + <g + id="g3966" + inkscape:export-filename="C:\dev\qqc2-technical-style-demo\icons\technical\32x32@2\favorite.png" + inkscape:export-xdpi="192" + inkscape:export-ydpi="192"> + <path + sodipodi:nodetypes="ccc" + inkscape:connector-curvature="0" + id="path5258" + d="m 679.76049,43.397888 c -11.16654,-4.90607 -6.54023,-14.887481 0.0528,-8.582499 6.18385,-6.259313 11.86465,3.625989 -0.0528,8.582499 z" + style="fill:none;stroke:#000000;stroke-width:2.2720654;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + <rect + y="22.143074" + x="663.8728" + height="32" + width="32" + id="rect5399" + style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal" /> + </g> + <g + id="g3970" + inkscape:export-filename="C:\dev\qqc2-technical-style-demo\icons\technical\32x32\stop.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96"> + <rect + ry="2" + rx="2" + y="30.209908" + x="730.55872" + height="13.875" + width="13.875" + id="rect5260" + style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal" /> + <rect + style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal" + id="rect5405" + width="32" + height="32" + x="721.49622" + y="21.147408" /> + </g> + <g + id="g3976" + inkscape:export-filename="C:\dev\qqc2-technical-style-demo\icons\technical\32x32\previous.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96"> + <g + transform="matrix(0.92512795,0,0,0.92512795,49.646365,-1594.3495)" + id="g5275"> + <path + style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.84269726;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal" + inkscape:transform-center-x="1.6220757" + inkscape:transform-center-y="-9.5697762e-005" + d="m 809.37017,1768.9096 h -8.55767 -8.55877 v -4.1758 l 8.55877,-10.6475 8.55767,10.6475 z" + id="path5264" + inkscape:connector-curvature="0" + sodipodi:nodetypes="ccccccc" + transform="matrix(0,-0.65656157,0.65656157,0,-358.61037,2289.4994)" /> + <path + sodipodi:nodetypes="ccccccc" + inkscape:connector-curvature="0" + id="path5267" + d="m 810.35019,1758.0981 v 5.6186 5.6193 h -2.74167 l -6.99073,-5.6193 6.99073,-5.6186 z" + inkscape:transform-center-y="-9.5697762e-005" + inkscape:transform-center-x="1.6220757" + style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.20984423;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal" /> + </g> + <rect + y="21.314461" + x="777.32397" + height="32" + width="32" + id="rect5407" + style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal" /> + </g> + <g + id="g3988" + inkscape:export-filename="C:\dev\qqc2-technical-style-demo\icons\technical\32x32@2\next.png" + inkscape:export-xdpi="192" + inkscape:export-ydpi="192"> + <g + transform="matrix(-0.92512795,0,0,0.92512795,1729.0016,-1594.3495)" + id="g5281"> + <path + transform="matrix(0,-0.65656157,0.65656157,0,-358.61037,2289.4994)" + sodipodi:nodetypes="ccccccc" + inkscape:connector-curvature="0" + id="path5277" + d="m 809.37017,1768.9096 h -8.55767 -8.55877 v -4.1758 l 8.55877,-10.6475 8.55767,10.6475 z" + inkscape:transform-center-y="-9.5697762e-005" + inkscape:transform-center-x="1.6220757" + style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.84269726;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal" /> + <path + style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.20984423;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal" + inkscape:transform-center-x="1.6220757" + inkscape:transform-center-y="-9.5697762e-005" + d="m 810.35019,1758.0981 v 5.6186 5.6193 h -2.74167 l -6.99073,-5.6193 6.99073,-5.6186 z" + id="path5279" + inkscape:connector-curvature="0" + sodipodi:nodetypes="ccccccc" /> + </g> + <rect + style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal" + id="rect5409" + width="32" + height="32" + x="969.32397" + y="21.314461" /> + </g> + <g + id="g3996" + inkscape:export-filename="C:\dev\qqc2-technical-style-demo\icons\technical\32x32@2\repeat.png" + inkscape:export-xdpi="192" + inkscape:export-ydpi="192"> + <g + transform="matrix(0.61777671,0,0,0.61777671,393.26213,-582.60358)" + id="g5386"> + <path + style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 1057,996.9258 h -11 c -1.7949,2e-4 -3.2498,1.4551 -3.25,3.25 v 3.375" + id="path5283" + inkscape:connector-curvature="0" + sodipodi:nodetypes="cccc" /> + <path + style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 1055.4787,992.6896 3.375,4.25 -3.75,3.875" + id="path5288" + inkscape:connector-curvature="0" /> + <path + sodipodi:nodetypes="cccc" + inkscape:connector-curvature="0" + id="path5290" + d="m 1044.6035,1011.3192 h 11 c 1.7949,-2e-4 3.2498,-1.4551 3.25,-3.25 v -3.375" + style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + <path + inkscape:connector-curvature="0" + id="path5292" + d="m 1046.1248,1015.5554 -3.375,-4.25 3.75,-3.875" + style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + </g> + <rect + y="21.719917" + x="1026.423" + height="32" + width="32" + id="rect5411" + style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal" /> + </g> + <g + id="g4005" + inkscape:export-filename="C:\dev\qqc2-technical-style-demo\icons\technical\32x32@2\shuffle.png" + inkscape:export-xdpi="192" + inkscape:export-ydpi="192"> + <g + transform="matrix(0.6410961,0,0,0.6410961,389.61554,-606.18813)" + id="g5393"> + <path + style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 1101,997.8001 c 10.7776,0 1.9407,12.75 14.125,12.75" + id="path5294" + inkscape:connector-curvature="0" + sodipodi:nodetypes="cc" /> + <path + inkscape:connector-curvature="0" + id="path5298" + d="m 1113.4787,992.6896 3.375,4.25 -3.75,3.875" + style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + <path + style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 1113.4787,1006.4897 3.375,4.25 -3.75,3.875" + id="path5300" + inkscape:connector-curvature="0" /> + <path + style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 1101.2501,1010.2375 c 1.479,0.07 2.6346,-0.5915 3.875,-1.6562" + id="path5302" + inkscape:connector-curvature="0" + sodipodi:nodetypes="cc" /> + <path + sodipodi:nodetypes="cc" + inkscape:connector-curvature="0" + id="path5312" + d="m 1113.6825,996.9157 c -1.479,-0.07 -2.6346,0.5915 -3.875,1.6562" + style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + </g> + <rect + style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal" + id="rect5413" + width="32" + height="32" + x="1084.5374" + y="21.248909" /> + </g> + <g + id="g3982" + inkscape:export-filename="C:\dev\qqc2-technical-style-demo\icons\technical\32x32@2\pause.png" + inkscape:export-xdpi="192" + inkscape:export-ydpi="192"> + <g + transform="matrix(0.26732473,0,0,0.26732473,607.52158,-229.58324)" + id="g5397"> + <rect + style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.19984221;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal" + id="rect5269" + width="14.495689" + height="54.800774" + x="877.34277" + y="971.0022" /> + <rect + y="971.0022" + x="904.9892" + height="54.800774" + width="14.495689" + id="rect5271" + style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.19984221;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal" /> + </g> + <rect + y="21.314461" + x="831.68982" + height="32" + width="32" + id="rect5458" + style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.49999988;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal" /> + </g> +</svg> diff --git a/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/index.theme b/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/index.theme new file mode 100644 index 0000000000..2523293552 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/icons/musicplayer/index.theme @@ -0,0 +1,14 @@ +[Icon Theme] +Name=Music Player +Comment=Icon theme for the Qt Quick Controls 2 Music Player Imagine Style Example + +Directories=32x32,32x32@2 + +[32x32] +Size=32 +Type=Fixed + +[32x32@2] +Size=32 +Scale=2 +Type=Fixed diff --git a/examples/quickcontrols/imagine/musicplayer/images/album-cover.jpg b/examples/quickcontrols/imagine/musicplayer/images/album-cover.jpg Binary files differnew file mode 100644 index 0000000000..48bd6231ba --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/images/album-cover.jpg diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/applicationwindow-background.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/applicationwindow-background.png Binary files differnew file mode 100644 index 0000000000..036bf74692 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/applicationwindow-background.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/button-background-checked-hovered.9.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/button-background-checked-hovered.9.png Binary files differnew file mode 100644 index 0000000000..c275d3242d --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/button-background-checked-hovered.9.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/button-background-checked-hovered@2x.9.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/button-background-checked-hovered@2x.9.png Binary files differnew file mode 100644 index 0000000000..eec285f305 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/button-background-checked-hovered@2x.9.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/button-background-checked.9.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/button-background-checked.9.png Binary files differnew file mode 100644 index 0000000000..2d284a5bc8 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/button-background-checked.9.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/button-background-checked@2x.9.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/button-background-checked@2x.9.png Binary files differnew file mode 100644 index 0000000000..fec385f539 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/button-background-checked@2x.9.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/button-background-disabled.9.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/button-background-disabled.9.png Binary files differnew file mode 100644 index 0000000000..bcad147094 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/button-background-disabled.9.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/button-background-disabled@2x.9.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/button-background-disabled@2x.9.png Binary files differnew file mode 100644 index 0000000000..03aba1535c --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/button-background-disabled@2x.9.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/button-background-hovered.9.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/button-background-hovered.9.png Binary files differnew file mode 100644 index 0000000000..962cf6778e --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/button-background-hovered.9.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/button-background-hovered@2x.9.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/button-background-hovered@2x.9.png Binary files differnew file mode 100644 index 0000000000..841c0064e7 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/button-background-hovered@2x.9.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/button-background-pressed.9.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/button-background-pressed.9.png Binary files differnew file mode 100644 index 0000000000..f97f42b809 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/button-background-pressed.9.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/button-background-pressed@2x.9.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/button-background-pressed@2x.9.png Binary files differnew file mode 100644 index 0000000000..970583495c --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/button-background-pressed@2x.9.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/button-background.9.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/button-background.9.png Binary files differnew file mode 100644 index 0000000000..74a8574fd3 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/button-background.9.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/button-background@2x.9.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/button-background@2x.9.png Binary files differnew file mode 100644 index 0000000000..251633853e --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/button-background@2x.9.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/combobox-background-hovered.9.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/combobox-background-hovered.9.png Binary files differnew file mode 100644 index 0000000000..f9f90df4f4 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/combobox-background-hovered.9.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/combobox-background-hovered@2x.9.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/combobox-background-hovered@2x.9.png Binary files differnew file mode 100644 index 0000000000..a4be50e154 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/combobox-background-hovered@2x.9.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/combobox-background-open.9.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/combobox-background-open.9.png Binary files differnew file mode 100644 index 0000000000..147231ecb7 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/combobox-background-open.9.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/combobox-background-open@2x.9.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/combobox-background-open@2x.9.png Binary files differnew file mode 100644 index 0000000000..0a978572e7 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/combobox-background-open@2x.9.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/combobox-background-pressed.9.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/combobox-background-pressed.9.png Binary files differnew file mode 100644 index 0000000000..7726198ab1 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/combobox-background-pressed.9.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/combobox-background-pressed@2x.9.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/combobox-background-pressed@2x.9.png Binary files differnew file mode 100644 index 0000000000..d64d405239 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/combobox-background-pressed@2x.9.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/combobox-background.9.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/combobox-background.9.png Binary files differnew file mode 100644 index 0000000000..e919d50aa0 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/combobox-background.9.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/combobox-background@2x.9.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/combobox-background@2x.9.png Binary files differnew file mode 100644 index 0000000000..5effba7e8b --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/combobox-background@2x.9.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/combobox-indicator-hovered.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/combobox-indicator-hovered.png Binary files differnew file mode 100644 index 0000000000..78b0650555 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/combobox-indicator-hovered.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/combobox-indicator-hovered@2x.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/combobox-indicator-hovered@2x.png Binary files differnew file mode 100644 index 0000000000..ec3c8734c8 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/combobox-indicator-hovered@2x.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/combobox-indicator-open.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/combobox-indicator-open.png Binary files differnew file mode 100644 index 0000000000..7a831632fe --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/combobox-indicator-open.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/combobox-indicator-open@2x.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/combobox-indicator-open@2x.png Binary files differnew file mode 100644 index 0000000000..47c664a2c8 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/combobox-indicator-open@2x.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/combobox-indicator-pressed.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/combobox-indicator-pressed.png Binary files differnew file mode 100644 index 0000000000..3340294f05 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/combobox-indicator-pressed.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/combobox-indicator-pressed@2x.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/combobox-indicator-pressed@2x.png Binary files differnew file mode 100644 index 0000000000..aa35b88200 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/combobox-indicator-pressed@2x.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/combobox-indicator.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/combobox-indicator.png Binary files differnew file mode 100644 index 0000000000..2c7f557819 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/combobox-indicator.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/combobox-indicator@2x.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/combobox-indicator@2x.png Binary files differnew file mode 100644 index 0000000000..20b9c44c34 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/combobox-indicator@2x.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/combobox-popup.9.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/combobox-popup.9.png Binary files differnew file mode 100644 index 0000000000..cae75cd78e --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/combobox-popup.9.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/combobox-popup@2x.9.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/combobox-popup@2x.9.png Binary files differnew file mode 100644 index 0000000000..392607bcdf --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/combobox-popup@2x.9.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/dial-background-hovered.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/dial-background-hovered.png Binary files differnew file mode 100644 index 0000000000..ac614678b3 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/dial-background-hovered.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/dial-background-hovered@2x.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/dial-background-hovered@2x.png Binary files differnew file mode 100644 index 0000000000..b13783c23a --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/dial-background-hovered@2x.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/dial-background-pressed.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/dial-background-pressed.png Binary files differnew file mode 100644 index 0000000000..1bd74acac6 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/dial-background-pressed.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/dial-background-pressed@2x.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/dial-background-pressed@2x.png Binary files differnew file mode 100644 index 0000000000..ffd7d009eb --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/dial-background-pressed@2x.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/dial-background.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/dial-background.png Binary files differnew file mode 100644 index 0000000000..c81fcb700b --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/dial-background.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/dial-background@2x.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/dial-background@2x.png Binary files differnew file mode 100644 index 0000000000..be3e15476b --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/dial-background@2x.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/dial-handle-pressed.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/dial-handle-pressed.png Binary files differnew file mode 100644 index 0000000000..d27f9355d5 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/dial-handle-pressed.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/dial-handle-pressed@2x.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/dial-handle-pressed@2x.png Binary files differnew file mode 100644 index 0000000000..a44e141066 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/dial-handle-pressed@2x.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/dial-handle.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/dial-handle.png Binary files differnew file mode 100644 index 0000000000..9992a83990 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/dial-handle.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/dial-handle@2x.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/dial-handle@2x.png Binary files differnew file mode 100644 index 0000000000..8816482a08 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/dial-handle@2x.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/frame-background.9.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/frame-background.9.png Binary files differnew file mode 100644 index 0000000000..1e436f2b36 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/frame-background.9.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/frame-background@2x.9.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/frame-background@2x.9.png Binary files differnew file mode 100644 index 0000000000..abdf3ab8e3 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/frame-background@2x.9.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/imagine-assets.qrc b/examples/quickcontrols/imagine/musicplayer/imagine-assets/imagine-assets.qrc new file mode 100644 index 0000000000..7bda4995d4 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/imagine-assets.qrc @@ -0,0 +1,113 @@ +<RCC> + <qresource prefix="/imagine-assets"> + <file>applicationwindow-background.png</file> + <file>button-background-checked-hovered.9.png</file> + <file>button-background-checked-hovered@2x.9.png</file> + <file>button-background-checked.9.png</file> + <file>button-background-checked@2x.9.png</file> + <file>button-background-disabled.9.png</file> + <file>button-background-disabled@2x.9.png</file> + <file>button-background-hovered.9.png</file> + <file>button-background-hovered@2x.9.png</file> + <file>button-background-pressed.9.png</file> + <file>button-background-pressed@2x.9.png</file> + <file>button-background.9.png</file> + <file>button-background@2x.9.png</file> + <file>combobox-background-hovered.9.png</file> + <file>combobox-background-hovered@2x.9.png</file> + <file>combobox-background-open.9.png</file> + <file>combobox-background-open@2x.9.png</file> + <file>combobox-background-pressed.9.png</file> + <file>combobox-background-pressed@2x.9.png</file> + <file>combobox-background.9.png</file> + <file>combobox-background@2x.9.png</file> + <file>combobox-indicator-hovered.png</file> + <file>combobox-indicator-hovered@2x.png</file> + <file>combobox-indicator-open.png</file> + <file>combobox-indicator-open@2x.png</file> + <file>combobox-indicator-pressed.png</file> + <file>combobox-indicator-pressed@2x.png</file> + <file>combobox-indicator.png</file> + <file>combobox-indicator@2x.png</file> + <file>combobox-popup.9.png</file> + <file>combobox-popup@2x.9.png</file> + <file>dial-background-hovered.png</file> + <file>dial-background-hovered@2x.png</file> + <file>dial-background-pressed.png</file> + <file>dial-background-pressed@2x.png</file> + <file>dial-background.png</file> + <file>dial-background@2x.png</file> + <file>dial-handle-pressed.png</file> + <file>dial-handle-pressed@2x.png</file> + <file>dial-handle.png</file> + <file>dial-handle@2x.png</file> + <file>frame-background.9.png</file> + <file>frame-background@2x.9.png</file> + <file>itemdelegate-background-checked.9.png</file> + <file>itemdelegate-background-checked@2x.9.png</file> + <file>itemdelegate-background-disabled.9.png</file> + <file>itemdelegate-background-disabled@2x.9.png</file> + <file>itemdelegate-background-hovered.9.png</file> + <file>itemdelegate-background-hovered@2x.9.png</file> + <file>itemdelegate-background-pressed.9.png</file> + <file>itemdelegate-background-pressed@2x.9.png</file> + <file>itemdelegate-background.9.png</file> + <file>itemdelegate-background@2x.9.png</file> + <file>roundbutton-background-checked-hovered.png</file> + <file>roundbutton-background-checked-hovered@2x.png</file> + <file>roundbutton-background-checked.png</file> + <file>roundbutton-background-checked@2x.png</file> + <file>roundbutton-background-disabled.png</file> + <file>roundbutton-background-disabled@2x.png</file> + <file>roundbutton-background-hovered.png</file> + <file>roundbutton-background-hovered@2x.png</file> + <file>roundbutton-background-pressed.png</file> + <file>roundbutton-background-pressed@2x.png</file> + <file>roundbutton-background.png</file> + <file>roundbutton-background@2x.png</file> + <file>scrollbar-handle-interactive-hovered.png</file> + <file>scrollbar-handle-interactive-hovered@2x.png</file> + <file>scrollbar-handle-interactive-pressed.png</file> + <file>scrollbar-handle-interactive-pressed@2x.png</file> + <file>scrollbar-handle-interactive.png</file> + <file>scrollbar-handle-interactive@2x.png</file> + <file>slider-background-horizontal-disabled.9.png</file> + <file>slider-background-horizontal-disabled@2x.9.png</file> + <file>slider-background-horizontal.9.png</file> + <file>slider-background-horizontal@2x.9.png</file> + <file>slider-background-vertical-disabled.9.png</file> + <file>slider-background-vertical-disabled@2x.9.png</file> + <file>slider-background-vertical.9.png</file> + <file>slider-background-vertical@2x.9.png</file> + <file>slider-handle-disabled.png</file> + <file>slider-handle-disabled@2x.png</file> + <file>slider-handle-hovered.png</file> + <file>slider-handle-hovered@2x.png</file> + <file>slider-handle.png</file> + <file>slider-handle@2x.png</file> + <file>slider-progress-horizontal.9.png</file> + <file>slider-progress-horizontal@2x.9.png</file> + <file>slider-progress-vertical-disabled.9.png</file> + <file>slider-progress-vertical-disabled@2x.9.png</file> + <file>slider-progress-vertical.9.png</file> + <file>slider-progress-vertical@2x.9.png</file> + <file>textfield-background-disabled.9.png</file> + <file>textfield-background-disabled@2x.9.png</file> + <file>textfield-background.9.png</file> + <file>textfield-background@2x.9.png</file> + <file>toolbar-background.9.png</file> + <file>toolbar-background@2x.9.png</file> + <file>toolbutton-background-checked-hovered.9.png</file> + <file>toolbutton-background-checked-hovered@2x.9.png</file> + <file>toolbutton-background-checked.9.png</file> + <file>toolbutton-background-checked@2x.9.png</file> + <file>toolbutton-background-hovered.9.png</file> + <file>toolbutton-background-hovered@2x.9.png</file> + <file>toolbutton-background-pressed.9.png</file> + <file>toolbutton-background-pressed@2x.9.png</file> + <file>toolbutton-background.9.png</file> + <file>toolbutton-background@2x.9.png</file> + <file>tooltip-background.9.png</file> + <file>tooltip-background@2x.9.png</file> + </qresource> +</RCC> diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/itemdelegate-background-checked.9.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/itemdelegate-background-checked.9.png Binary files differnew file mode 100644 index 0000000000..6c7915aab9 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/itemdelegate-background-checked.9.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/itemdelegate-background-checked@2x.9.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/itemdelegate-background-checked@2x.9.png Binary files differnew file mode 100644 index 0000000000..24ddbce09a --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/itemdelegate-background-checked@2x.9.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/itemdelegate-background-disabled.9.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/itemdelegate-background-disabled.9.png Binary files differnew file mode 100644 index 0000000000..65a670ebb5 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/itemdelegate-background-disabled.9.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/itemdelegate-background-disabled@2x.9.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/itemdelegate-background-disabled@2x.9.png Binary files differnew file mode 100644 index 0000000000..df81dd0a98 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/itemdelegate-background-disabled@2x.9.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/itemdelegate-background-hovered.9.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/itemdelegate-background-hovered.9.png Binary files differnew file mode 100644 index 0000000000..a8eb9e7a13 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/itemdelegate-background-hovered.9.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/itemdelegate-background-hovered@2x.9.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/itemdelegate-background-hovered@2x.9.png Binary files differnew file mode 100644 index 0000000000..23559a28b4 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/itemdelegate-background-hovered@2x.9.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/itemdelegate-background-pressed.9.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/itemdelegate-background-pressed.9.png Binary files differnew file mode 100644 index 0000000000..7d7a2bb960 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/itemdelegate-background-pressed.9.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/itemdelegate-background-pressed@2x.9.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/itemdelegate-background-pressed@2x.9.png Binary files differnew file mode 100644 index 0000000000..911563fc0e --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/itemdelegate-background-pressed@2x.9.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/itemdelegate-background.9.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/itemdelegate-background.9.png Binary files differnew file mode 100644 index 0000000000..65a670ebb5 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/itemdelegate-background.9.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/itemdelegate-background@2x.9.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/itemdelegate-background@2x.9.png Binary files differnew file mode 100644 index 0000000000..df81dd0a98 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/itemdelegate-background@2x.9.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/roundbutton-background-checked-hovered.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/roundbutton-background-checked-hovered.png Binary files differnew file mode 100644 index 0000000000..fae98b91b7 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/roundbutton-background-checked-hovered.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/roundbutton-background-checked-hovered@2x.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/roundbutton-background-checked-hovered@2x.png Binary files differnew file mode 100644 index 0000000000..1b575b0354 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/roundbutton-background-checked-hovered@2x.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/roundbutton-background-checked.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/roundbutton-background-checked.png Binary files differnew file mode 100644 index 0000000000..859232e2e5 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/roundbutton-background-checked.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/roundbutton-background-checked@2x.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/roundbutton-background-checked@2x.png Binary files differnew file mode 100644 index 0000000000..ef147a334a --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/roundbutton-background-checked@2x.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/roundbutton-background-disabled.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/roundbutton-background-disabled.png Binary files differnew file mode 100644 index 0000000000..862f4a26d8 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/roundbutton-background-disabled.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/roundbutton-background-disabled@2x.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/roundbutton-background-disabled@2x.png Binary files differnew file mode 100644 index 0000000000..f99e11fd08 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/roundbutton-background-disabled@2x.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/roundbutton-background-hovered.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/roundbutton-background-hovered.png Binary files differnew file mode 100644 index 0000000000..6239eb3214 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/roundbutton-background-hovered.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/roundbutton-background-hovered@2x.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/roundbutton-background-hovered@2x.png Binary files differnew file mode 100644 index 0000000000..aa2e8f46d8 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/roundbutton-background-hovered@2x.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/roundbutton-background-pressed.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/roundbutton-background-pressed.png Binary files differnew file mode 100644 index 0000000000..81d2cd7442 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/roundbutton-background-pressed.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/roundbutton-background-pressed@2x.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/roundbutton-background-pressed@2x.png Binary files differnew file mode 100644 index 0000000000..fd82c0c38c --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/roundbutton-background-pressed@2x.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/roundbutton-background.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/roundbutton-background.png Binary files differnew file mode 100644 index 0000000000..ab2e9ceea8 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/roundbutton-background.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/roundbutton-background@2x.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/roundbutton-background@2x.png Binary files differnew file mode 100644 index 0000000000..33e81bf619 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/roundbutton-background@2x.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/scrollbar-handle-interactive-hovered.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/scrollbar-handle-interactive-hovered.png Binary files differnew file mode 100644 index 0000000000..2657743a81 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/scrollbar-handle-interactive-hovered.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/scrollbar-handle-interactive-hovered@2x.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/scrollbar-handle-interactive-hovered@2x.png Binary files differnew file mode 100644 index 0000000000..60ade78071 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/scrollbar-handle-interactive-hovered@2x.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/scrollbar-handle-interactive-pressed.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/scrollbar-handle-interactive-pressed.png Binary files differnew file mode 100644 index 0000000000..626ab8b6bb --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/scrollbar-handle-interactive-pressed.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/scrollbar-handle-interactive-pressed@2x.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/scrollbar-handle-interactive-pressed@2x.png Binary files differnew file mode 100644 index 0000000000..92789571d1 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/scrollbar-handle-interactive-pressed@2x.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/scrollbar-handle-interactive.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/scrollbar-handle-interactive.png Binary files differnew file mode 100644 index 0000000000..a7a7347120 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/scrollbar-handle-interactive.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/scrollbar-handle-interactive@2x.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/scrollbar-handle-interactive@2x.png Binary files differnew file mode 100644 index 0000000000..837e179553 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/scrollbar-handle-interactive@2x.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/slider-background-horizontal-disabled.9.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/slider-background-horizontal-disabled.9.png Binary files differnew file mode 100644 index 0000000000..f45f588838 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/slider-background-horizontal-disabled.9.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/slider-background-horizontal-disabled@2x.9.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/slider-background-horizontal-disabled@2x.9.png Binary files differnew file mode 100644 index 0000000000..40e6d50567 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/slider-background-horizontal-disabled@2x.9.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/slider-background-horizontal.9.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/slider-background-horizontal.9.png Binary files differnew file mode 100644 index 0000000000..a465f300cc --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/slider-background-horizontal.9.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/slider-background-horizontal@2x.9.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/slider-background-horizontal@2x.9.png Binary files differnew file mode 100644 index 0000000000..7a3170f529 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/slider-background-horizontal@2x.9.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/slider-background-vertical-disabled.9.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/slider-background-vertical-disabled.9.png Binary files differnew file mode 100644 index 0000000000..0bee2685a0 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/slider-background-vertical-disabled.9.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/slider-background-vertical-disabled@2x.9.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/slider-background-vertical-disabled@2x.9.png Binary files differnew file mode 100644 index 0000000000..7fed90c816 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/slider-background-vertical-disabled@2x.9.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/slider-background-vertical.9.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/slider-background-vertical.9.png Binary files differnew file mode 100644 index 0000000000..a5074864b0 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/slider-background-vertical.9.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/slider-background-vertical@2x.9.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/slider-background-vertical@2x.9.png Binary files differnew file mode 100644 index 0000000000..a3974ebe3c --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/slider-background-vertical@2x.9.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/slider-handle-disabled.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/slider-handle-disabled.png Binary files differnew file mode 100644 index 0000000000..02a9df388d --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/slider-handle-disabled.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/slider-handle-disabled@2x.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/slider-handle-disabled@2x.png Binary files differnew file mode 100644 index 0000000000..b37cef3272 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/slider-handle-disabled@2x.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/slider-handle-hovered.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/slider-handle-hovered.png Binary files differnew file mode 100644 index 0000000000..2048aa6b07 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/slider-handle-hovered.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/slider-handle-hovered@2x.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/slider-handle-hovered@2x.png Binary files differnew file mode 100644 index 0000000000..0515be8e11 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/slider-handle-hovered@2x.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/slider-handle.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/slider-handle.png Binary files differnew file mode 100644 index 0000000000..2a80f27f27 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/slider-handle.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/slider-handle@2x.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/slider-handle@2x.png Binary files differnew file mode 100644 index 0000000000..2944704118 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/slider-handle@2x.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/slider-progress-horizontal.9.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/slider-progress-horizontal.9.png Binary files differnew file mode 100644 index 0000000000..1224522f9d --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/slider-progress-horizontal.9.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/slider-progress-horizontal@2x.9.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/slider-progress-horizontal@2x.9.png Binary files differnew file mode 100644 index 0000000000..c304bfe5ad --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/slider-progress-horizontal@2x.9.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/slider-progress-vertical-disabled.9.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/slider-progress-vertical-disabled.9.png Binary files differnew file mode 100644 index 0000000000..0e7b08bd0e --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/slider-progress-vertical-disabled.9.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/slider-progress-vertical-disabled@2x.9.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/slider-progress-vertical-disabled@2x.9.png Binary files differnew file mode 100644 index 0000000000..d9654ceec4 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/slider-progress-vertical-disabled@2x.9.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/slider-progress-vertical.9.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/slider-progress-vertical.9.png Binary files differnew file mode 100644 index 0000000000..928ff864f0 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/slider-progress-vertical.9.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/slider-progress-vertical@2x.9.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/slider-progress-vertical@2x.9.png Binary files differnew file mode 100644 index 0000000000..3d640b277a --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/slider-progress-vertical@2x.9.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/textfield-background-disabled.9.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/textfield-background-disabled.9.png Binary files differnew file mode 100644 index 0000000000..de557cbc5f --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/textfield-background-disabled.9.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/textfield-background-disabled@2x.9.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/textfield-background-disabled@2x.9.png Binary files differnew file mode 100644 index 0000000000..23984d715d --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/textfield-background-disabled@2x.9.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/textfield-background.9.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/textfield-background.9.png Binary files differnew file mode 100644 index 0000000000..0dc163a4a3 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/textfield-background.9.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/textfield-background@2x.9.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/textfield-background@2x.9.png Binary files differnew file mode 100644 index 0000000000..41aae23d7f --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/textfield-background@2x.9.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/toolbar-background.9.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/toolbar-background.9.png Binary files differnew file mode 100644 index 0000000000..ab2f47e243 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/toolbar-background.9.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/toolbar-background@2x.9.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/toolbar-background@2x.9.png Binary files differnew file mode 100644 index 0000000000..7e389fe0f0 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/toolbar-background@2x.9.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/toolbutton-background-checked-hovered.9.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/toolbutton-background-checked-hovered.9.png Binary files differnew file mode 100644 index 0000000000..3acf92e12a --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/toolbutton-background-checked-hovered.9.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/toolbutton-background-checked-hovered@2x.9.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/toolbutton-background-checked-hovered@2x.9.png Binary files differnew file mode 100644 index 0000000000..0f43f93337 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/toolbutton-background-checked-hovered@2x.9.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/toolbutton-background-checked.9.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/toolbutton-background-checked.9.png Binary files differnew file mode 100644 index 0000000000..ff0faa567b --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/toolbutton-background-checked.9.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/toolbutton-background-checked@2x.9.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/toolbutton-background-checked@2x.9.png Binary files differnew file mode 100644 index 0000000000..694f5eab88 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/toolbutton-background-checked@2x.9.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/toolbutton-background-hovered.9.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/toolbutton-background-hovered.9.png Binary files differnew file mode 100644 index 0000000000..c60e64d10c --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/toolbutton-background-hovered.9.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/toolbutton-background-hovered@2x.9.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/toolbutton-background-hovered@2x.9.png Binary files differnew file mode 100644 index 0000000000..d0103202bd --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/toolbutton-background-hovered@2x.9.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/toolbutton-background-pressed.9.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/toolbutton-background-pressed.9.png Binary files differnew file mode 100644 index 0000000000..f2ec9c6e4b --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/toolbutton-background-pressed.9.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/toolbutton-background-pressed@2x.9.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/toolbutton-background-pressed@2x.9.png Binary files differnew file mode 100644 index 0000000000..e3a86911ee --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/toolbutton-background-pressed@2x.9.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/toolbutton-background.9.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/toolbutton-background.9.png Binary files differnew file mode 100644 index 0000000000..a292ac0959 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/toolbutton-background.9.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/toolbutton-background@2x.9.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/toolbutton-background@2x.9.png Binary files differnew file mode 100644 index 0000000000..6f8880c393 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/toolbutton-background@2x.9.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/tooltip-background.9.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/tooltip-background.9.png Binary files differnew file mode 100644 index 0000000000..a74441c92a --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/tooltip-background.9.png diff --git a/examples/quickcontrols/imagine/musicplayer/imagine-assets/tooltip-background@2x.9.png b/examples/quickcontrols/imagine/musicplayer/imagine-assets/tooltip-background@2x.9.png Binary files differnew file mode 100644 index 0000000000..d4b20b74b3 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/imagine-assets/tooltip-background@2x.9.png diff --git a/examples/quickcontrols/imagine/musicplayer/musicplayer.cpp b/examples/quickcontrols/imagine/musicplayer/musicplayer.cpp new file mode 100644 index 0000000000..54727af696 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/musicplayer.cpp @@ -0,0 +1,24 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#include <QGuiApplication> +#include <QQmlApplicationEngine> +#include <QSettings> +#include <QIcon> + +int main(int argc, char *argv[]) +{ + QGuiApplication::setApplicationName("Music Player"); + QGuiApplication::setOrganizationName("QtProject"); + + QGuiApplication app(argc, argv); + + QIcon::setThemeName("musicplayer"); + + QQmlApplicationEngine engine; + engine.load(QUrl("qrc:/musicplayer.qml")); + if (engine.rootObjects().isEmpty()) + return -1; + + return app.exec(); +} diff --git a/examples/quickcontrols/imagine/musicplayer/musicplayer.pro b/examples/quickcontrols/imagine/musicplayer/musicplayer.pro new file mode 100644 index 0000000000..b1970ee905 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/musicplayer.pro @@ -0,0 +1,16 @@ +TEMPLATE = app +TARGET = musicplayer +QT += quick quickcontrols2 + +SOURCES += \ + musicplayer.cpp + +RESOURCES += \ + icons/icons.qrc \ + images/album-cover.jpg \ + imagine-assets/imagine-assets.qrc \ + qtquickcontrols2.conf \ + musicplayer.qml + +target.path = $$[QT_INSTALL_EXAMPLES]/quickcontrols2/imagine/musicplayer +INSTALLS += target diff --git a/examples/quickcontrols/imagine/musicplayer/musicplayer.qml b/examples/quickcontrols/imagine/musicplayer/musicplayer.qml new file mode 100644 index 0000000000..7d321534a7 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/musicplayer.qml @@ -0,0 +1,420 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import QtQuick.Window + +ApplicationWindow { + id: window + width: 1280 + height: 720 + visible: true + title: "Qt Quick Controls - Imagine Style Example: Music Player" + + Component.onCompleted: { + x = Screen.width / 2 - width / 2 + y = Screen.height / 2 - height / 2 + } + + Shortcut { + sequence: "Ctrl+Q" + onActivated: Qt.quit() + } + + header: ToolBar { + RowLayout { + id: headerRowLayout + anchors.fill: parent + spacing: 0 + + ToolButton { + icon.name: "grid" + } + ToolButton { + icon.name: "settings" + } + ToolButton { + icon.name: "filter" + } + ToolButton { + icon.name: "message" + } + ToolButton { + icon.name: "music" + } + ToolButton { + icon.name: "cloud" + } + ToolButton { + icon.name: "bluetooth" + } + ToolButton { + icon.name: "cart" + } + + Item { + Layout.fillWidth: true + } + + ToolButton { + icon.name: "power" + onClicked: Qt.quit() + } + } + } + + Label { + text: "Qtify" + font.pixelSize: Qt.application.font.pixelSize * 1.3 + anchors.centerIn: header + z: header.z + 1 + } + + RowLayout { + spacing: 115 + anchors.fill: parent + anchors.margins: 70 + + ColumnLayout { + spacing: 0 + Layout.preferredWidth: 230 + + RowLayout { + Layout.maximumHeight: 170 + + ColumnLayout { + Label { + text: "12 dB" + Layout.fillHeight: true + } + Label { + text: "6 dB" + Layout.fillHeight: true + } + Label { + text: "0 dB" + Layout.fillHeight: true + } + Label { + text: "-6 dB" + Layout.fillHeight: true + } + Label { + text: "-12 dB" + Layout.fillHeight: true + } + } + + Repeater { + model: 7 + + Slider { + value: Math.random() + orientation: Qt.Vertical + + Layout.fillWidth: true + Layout.fillHeight: true + } + } + } + + RowLayout { + spacing: 10 + Layout.topMargin: 23 + + ComboBox { + currentIndex: 1 + model: ["Blues", "Classical", "Jazz", "Metal"] + Layout.fillWidth: true + } + + Button { + icon.name: "folder" + } + + Button { + icon.name: "save" + enabled: false + } + } + + Dial { + Layout.alignment: Qt.AlignHCenter + Layout.topMargin: 50 + } + + Label { + text: "Volume" + + Layout.alignment: Qt.AlignHCenter + Layout.topMargin: 12 + } + } + + ColumnLayout { + spacing: 26 + Layout.preferredWidth: 230 + + Item { + Layout.fillWidth: true + Layout.fillHeight: true + + Image { + anchors.fill: parent + fillMode: Image.PreserveAspectCrop + source: "images/album-cover.jpg" + } + } + + Item { + id: songLabelContainer + clip: true + + Layout.fillWidth: true + Layout.preferredHeight: songNameLabel.implicitHeight + + SequentialAnimation { + running: true + loops: Animation.Infinite + + PauseAnimation { + duration: 2000 + } + ParallelAnimation { + XAnimator { + target: songNameLabel + from: 0 + to: songLabelContainer.width - songNameLabel.implicitWidth + duration: 5000 + } + OpacityAnimator { + target: leftGradient + from: 0 + to: 1 + } + } + OpacityAnimator { + target: rightGradient + from: 1 + to: 0 + } + PauseAnimation { + duration: 1000 + } + OpacityAnimator { + target: rightGradient + from: 0 + to: 1 + } + ParallelAnimation { + XAnimator { + target: songNameLabel + from: songLabelContainer.width - songNameLabel.implicitWidth + to: 0 + duration: 5000 + } + OpacityAnimator { + target: leftGradient + from: 0 + to: 1 + } + } + OpacityAnimator { + target: leftGradient + from: 1 + to: 0 + } + } + + Rectangle { + id: leftGradient + gradient: Gradient { + GradientStop { + position: 0 + color: "#dfe4ea" + } + GradientStop { + position: 1 + color: "#00dfe4ea" + } + } + + width: height + height: parent.height + anchors.left: parent.left + z: 1 + rotation: -90 + opacity: 0 + } + + Label { + id: songNameLabel + text: "Edvard Grieg - In the Hall of the Mountain King" + font.pixelSize: Qt.application.font.pixelSize * 1.4 + } + + Rectangle { + id: rightGradient + gradient: Gradient { + GradientStop { + position: 0 + color: "#00dfe4ea" + } + GradientStop { + position: 1 + color: "#dfe4ea" + } + } + + width: height + height: parent.height + anchors.right: parent.right + rotation: -90 + } + } + + RowLayout { + spacing: 8 + Layout.alignment: Qt.AlignHCenter + + RoundButton { + icon.name: "favorite" + icon.width: 32 + icon.height: 32 + } + RoundButton { + icon.name: "stop" + icon.width: 32 + icon.height: 32 + } + RoundButton { + icon.name: "previous" + icon.width: 32 + icon.height: 32 + } + RoundButton { + icon.name: "pause" + icon.width: 32 + icon.height: 32 + } + RoundButton { + icon.name: "next" + icon.width: 32 + icon.height: 32 + } + RoundButton { + icon.name: "repeat" + icon.width: 32 + icon.height: 32 + } + RoundButton { + icon.name: "shuffle" + icon.width: 32 + icon.height: 32 + } + } + + Slider { + id: seekSlider + value: 113 + to: 261 + + Layout.fillWidth: true + + ToolTip { + parent: seekSlider.handle + visible: seekSlider.pressed + text: pad(Math.floor(value / 60)) + ":" + pad(Math.floor(value % 60)) + y: parent.height + + readonly property int value: seekSlider.valueAt(seekSlider.position) + + function pad(number) { + if (number <= 9) + return "0" + number; + return number; + } + } + } + } + + ColumnLayout { + spacing: 16 + Layout.preferredWidth: 230 + + ButtonGroup { + buttons: libraryRowLayout.children + } + + RowLayout { + id: libraryRowLayout + Layout.alignment: Qt.AlignHCenter + + Button { + text: "Files" + checked: true + } + Button { + text: "Playlists" + checkable: true + } + Button { + text: "Favourites" + checkable: true + } + } + + RowLayout { + TextField { + Layout.fillWidth: true + } + Button { + icon.name: "folder" + } + } + + Frame { + id: filesFrame + leftPadding: 1 + rightPadding: 1 + + Layout.fillWidth: true + Layout.fillHeight: true + + ListView { + id: filesListView + clip: true + anchors.fill: parent + model: ListModel { + Component.onCompleted: { + for (var i = 0; i < 100; ++i) { + append({ + author: "Author", + album: "Album", + track: "Track 0" + (i % 9 + 1), + }); + } + } + } + delegate: ItemDelegate { + text: model.author + " - " + model.album + " - " + model.track + width: filesListView.width + } + + ScrollBar.vertical: ScrollBar { + parent: filesFrame + policy: ScrollBar.AlwaysOn + anchors.top: parent.top + anchors.topMargin: filesFrame.topPadding + anchors.right: parent.right + anchors.rightMargin: 1 + anchors.bottom: parent.bottom + anchors.bottomMargin: filesFrame.bottomPadding + } + } + } + } + } +} diff --git a/examples/quickcontrols/imagine/musicplayer/qtquickcontrols2.conf b/examples/quickcontrols/imagine/musicplayer/qtquickcontrols2.conf new file mode 100644 index 0000000000..33eab6a563 --- /dev/null +++ b/examples/quickcontrols/imagine/musicplayer/qtquickcontrols2.conf @@ -0,0 +1,10 @@ +[Controls] +Style=Imagine + +[Imagine] +Path=:/imagine-assets + +[Imagine\Palette] +Text=#6b7b89 +ButtonText=#6b7b89 +WindowText=#6b7b89 diff --git a/examples/quickcontrols/ios/todolist/AppSettings.qml b/examples/quickcontrols/ios/todolist/AppSettings.qml new file mode 100644 index 0000000000..764ba8b8fc --- /dev/null +++ b/examples/quickcontrols/ios/todolist/AppSettings.qml @@ -0,0 +1,14 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +pragma Singleton + +import QtCore + +Settings { + // The properties here are given default values to account for the first run of the application. + // After the application has run once, future values will come from the stored settings. + property bool showDoneTasks: true + property int maxTasks: 30 + property int fontSize: 18 +} diff --git a/examples/quickcontrols/ios/todolist/CMakeLists.txt b/examples/quickcontrols/ios/todolist/CMakeLists.txt new file mode 100644 index 0000000000..413ea6ad97 --- /dev/null +++ b/examples/quickcontrols/ios/todolist/CMakeLists.txt @@ -0,0 +1,84 @@ +cmake_minimum_required(VERSION 3.18) +project(todolist LANGUAGES CXX) + +set(CMAKE_AUTOMOC ON) + +if(NOT DEFINED INSTALL_EXAMPLESDIR) + set(INSTALL_EXAMPLESDIR "examples") +endif() + +set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/todolist") + +find_package(Qt6 COMPONENTS Gui Qml Quick QuickControls2) + +qt_add_executable(todolist + src/main.cpp +) + +set_target_properties(todolist PROPERTIES + WIN32_EXECUTABLE TRUE + MACOSX_BUNDLE TRUE +) + +target_link_libraries(todolist PUBLIC + Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::Gui + Qt${QT_VERSION_MAJOR}::Qml + Qt${QT_VERSION_MAJOR}::Quick + Qt${QT_VERSION_MAJOR}::QuickControls2 +) + +set_source_files_properties(AppSettings.qml PROPERTIES + QT_QML_SINGLETON_TYPE TRUE +) + +set_source_files_properties(Database.qml PROPERTIES + QT_QML_SINGLETON_TYPE TRUE +) + +qt_add_qml_module(todolist + URI App + VERSION 1.0 + QML_FILES + AppSettings.qml + Database.qml + FontSizePage.qml + HomePage.qml + MaxTasksPage.qml + NavBar.qml + ProjectPage.qml + SettingsPage.qml + ToggleCompletedTasksPage.qml + main.qml + RESOURCES + images/back.png + images/back@2x.png + images/back@3x.png + images/back-white.png + images/back-white@2x.png + images/back-white@3x.png + images/close.png + images/close@2x.png + images/close@3x.png + images/close-white.png + images/close-white@2x.png + images/close-white@3x.png + images/plus-math.png + images/plus-math@2x.png + images/plus-math@3x.png + images/settings.png + images/settings@2x.png + images/settings@3x.png + images/add-new.png + images/add-new@2x.png + images/add-new@3x.png + NO_RESOURCE_TARGET_PATH +) + +set_property(GLOBAL PROPERTY XCODE_EMIT_EFFECTIVE_PLATFORM_NAME ON) + +install(TARGETS todolist + RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" + LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" +) diff --git a/examples/quickcontrols/ios/todolist/Database.qml b/examples/quickcontrols/ios/todolist/Database.qml new file mode 100644 index 0000000000..31bbd8c1e7 --- /dev/null +++ b/examples/quickcontrols/ios/todolist/Database.qml @@ -0,0 +1,161 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +pragma Singleton + +import QtQml +import QtQuick.LocalStorage + +QtObject { + id: root + + property var _db + + function _database() { + if (_db) + return _db + + try { + let db = LocalStorage.openDatabaseSync("ToDoList", "1.0", "ToDoList application database") + + db.transaction(function (tx) { + tx.executeSql(`CREATE TABLE IF NOT EXISTS projects ( + project_id INTEGER PRIMARY KEY AUTOINCREMENT, + project_name TEXT NOT NULL CHECK(project_name != ''), + project_note TEXT + )`); + }) + + db.transaction(function (tx) { + tx.executeSql(`CREATE TABLE IF NOT EXISTS tasks ( + task_id INTEGER PRIMARY KEY AUTOINCREMENT, + task_name TEXT CHECK(task_name != ''), + done INTEGER, + project_id, + FOREIGN KEY(project_id) REFERENCES projects(project_id) + )`); + }) + + _db = db + } catch (error) { + console.log("Error opening database: " + error) + }; + + return _db + } + + function getProjects() { + let projects = [] + root._database().transaction(function (tx) { + let results = tx.executeSql('SELECT * FROM projects') + for (let i = 0; i < results.rows.length; i++) { + let projectRow = results.rows.item(i) + let projectId = projectRow.project_id + let completedTasks = Math.max(countDoneTasksByProject(projectId).rows.length, 0) + let totalTasks = Math.max(countTaskByProject(projectId).rows.length, 0) + projects.push({ + "projectName": projectRow.project_name, + "projectId": projectId, + "projectNote": projectRow.project_note ?? "", + "completedTasks": completedTasks, + "totalTasks": totalTasks + }) + } + }) + return projects + } + + function newProject(projectName) { + let results + root._database().transaction(function (tx) { + results = tx.executeSql("INSERT INTO projects (project_name) VALUES(?)", [projectName]) + }) + return results + } + + function updateProjectNote(projectId, projectNote) { + root._database().transaction(function (tx) { + tx.executeSql("UPDATE projects set project_note=? WHERE project_id=?", [projectNote, projectId]) + }) + } + + function updateProjectName(projectId, projectName) { + root._database().transaction(function (tx) { + tx.executeSql("UPDATE projects set project_name=? WHERE project_id=?", [projectName, projectId]) + }) + } + + function deleteProject(projectId) { + root._database().transaction(function (tx) { + deleteAllTasks(projectId) + tx.executeSql("DELETE FROM projects WHERE project_id = ?", [projectId]) + }) + } + + function getTaskByProject(projectId) { + if (!projectId) + return + + let tasks = [] + root._database().transaction(function (tx) { + let results = tx.executeSql("SELECT * FROM tasks WHERE project_id = " + [projectId] + " ORDER BY done") + for (let i = 0; i < results.rows.length; i++) { + let row = results.rows.item(i) + tasks.push({ + "taskId": row.task_id, + "taskName": row.task_name, + "done": row.done === 1 ? true : false + }) + } + }) + return tasks + } + + function countTaskByProject(projectId) { + let results + root._database().transaction(function (tx) { + results = tx.executeSql('SELECT task_id FROM tasks WHERE project_id =' + [projectId]) + }) + return results + } + + function countDoneTasksByProject(projectId) { + let results + root._database().transaction(function (tx) { + results = tx.executeSql("SELECT task_id FROM tasks WHERE project_id =" + [projectId] + " AND done = 1") + }) + return results + } + + function newTask(projectId, taskName) { + let results + root._database().transaction(function (tx) { + results = tx.executeSql("INSERT INTO tasks (task_name, done, project_id) VALUES(?, 0, ?)", [taskName, projectId]) + }) + return results + } + + function updateTaskName(taskId, taskName) { + root._database().transaction(function (tx) { + tx.executeSql("UPDATE tasks set task_name=? WHERE task_id=?", [taskName, taskId]) + }) + } + + function updateDoneState(taskId, doneState) { + root._database().transaction(function (tx) { + tx.executeSql("UPDATE tasks set done=? WHERE task_id=?", [doneState, taskId]) + }) + } + + function deleteAllTasks(projectId) { + root._database().transaction(function (tx) { + tx.executeSql("DELETE FROM tasks WHERE project_id =" + projectId) + }) + } + + function deleteTask(taskId) { + root._database().transaction(function (tx) { + tx.executeSql("DELETE FROM tasks WHERE task_id = ?", [taskId]) + }) + } +} diff --git a/examples/quickcontrols/ios/todolist/FontSizePage.qml b/examples/quickcontrols/ios/todolist/FontSizePage.qml new file mode 100644 index 0000000000..2b0e5b16db --- /dev/null +++ b/examples/quickcontrols/ios/todolist/FontSizePage.qml @@ -0,0 +1,44 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +Page { + Frame { + width: parent.width - 60 + anchors.centerIn: parent + topPadding: 12 + bottomPadding: 12 + + RowLayout { + anchors.fill: parent + spacing: 12 + + Label { + text: qsTr("A") + font.pointSize: 15 + font.weight: 400 + } + + Slider { + snapMode: Slider.SnapAlways + stepSize: 1 + from: 15 + value: AppSettings.fontSize + to: 21 + + Layout.fillWidth: true + + onMoved: AppSettings.fontSize = value + } + + Label { + text: qsTr("A") + font.pointSize: 21 + font.weight: 400 + } + } + } +} diff --git a/examples/quickcontrols/ios/todolist/HomePage.qml b/examples/quickcontrols/ios/todolist/HomePage.qml new file mode 100644 index 0000000000..94221146e2 --- /dev/null +++ b/examples/quickcontrols/ios/todolist/HomePage.qml @@ -0,0 +1,172 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import QtQuick.LocalStorage + +Page { + id: root + + header: Label { + text: qsTr("Projects") + font.pointSize: AppSettings.fontSize + 20 + font.styleName: "Semibold" + leftPadding: 30 + topPadding: 20 + bottomPadding: 20 + } + + ListView { + id: projectListView + anchors.fill: parent + clip: true + + model: ListModel { + id: projectsModel + + Component.onCompleted: { + let projects = Database.getProjects() + for (let project of projects) + append(project) + } + } + + delegate: SwipeDelegate { + id: projectDelegate + width: ListView.view.width + height: projectContent.implicitHeight + + required property int index + required property int projectId + required property string projectName + required property int completedTasks + required property int totalTasks + + swipe.right: Rectangle { + width: 50 + height: parent.height + color: "red" + anchors.right: parent.right + + SwipeDelegate.onClicked: { + Database.deleteProject(projectDelegate.projectId) + projectsModel.remove(projectDelegate.index, 1) + } + + Image { + source: Qt.styleHints.appearance === Qt.Dark ? "images/close-white.png" + : "images/close.png" + width: 20 + height: 20 + anchors.centerIn: parent + } + } + + Column { + id: projectContent + topPadding: 8 + bottomPadding: 10 + leftPadding: 30 + + Label { + text: completedTasks + " / " + totalTasks + font.pointSize: AppSettings.fontSize + } + + Label { + id: project + text: projectName + font.pointSize: AppSettings.fontSize + font.styleName: "Semibold" + } + } + + Connections { + target: projectDelegate + function onClicked() { + let project = projectsModel.get(index) + root.StackView.view.push("ProjectPage.qml", { + "projectsModel": projectsModel, + "projectId": project.projectId, + "projectName": project.projectName, + "projectIndex": index, + "projectNote": project.projectNote, + "completedTasks": project.completedTasks, + "totalTasks": project.totalTasks + }) + } + } + } + } + + Popup { + id: newProjectPopup + anchors.centerIn: parent + height: 200 + modal: true + + ColumnLayout { + anchors.fill: parent + + Label { + text: qsTr("Project Name") + font.pointSize: AppSettings.fontSize + 2.0 + font.bold: true + + Layout.alignment: Qt.AlignHCenter + } + + TextField { + id: newProjectTextField + placeholderText: qsTr("Enter project name") + font.pointSize: AppSettings.fontSize + + Layout.fillWidth: true + Layout.leftMargin: 10 + Layout.rightMargin: 10 + + Keys.onReturnPressed: { + if (createProjectButton.enabled) + createProjectButton.clicked() + } + } + + Button { + id: createProjectButton + text: qsTr("Create project") + flat: true + font.pointSize: AppSettings.fontSize + enabled: newProjectTextField.length > 0 + + Layout.alignment: Qt.AlignHCenter + + onClicked: { + let results = Database.newProject(newProjectTextField.text) + projectsModel.append({ + projectId: parseInt(results.insertId), + projectName: newProjectTextField.text, + totalTasks: 0, + completedTasks: 0, + projectNote: "" + }) + newProjectTextField.text = "" + newProjectPopup.close() + } + } + } + } + + footer: ToolBar { + ToolButton { + anchors.right: parent.right + anchors.rightMargin: 5 + text: qsTr("New project") + font.pointSize: AppSettings.fontSize - 2 + icon.source: "images/add-new.png" + + onClicked: newProjectPopup.open() + } + } +} diff --git a/examples/quickcontrols/ios/todolist/MaxTasksPage.qml b/examples/quickcontrols/ios/todolist/MaxTasksPage.qml new file mode 100644 index 0000000000..509a460357 --- /dev/null +++ b/examples/quickcontrols/ios/todolist/MaxTasksPage.qml @@ -0,0 +1,36 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +Page { + ColumnLayout { + width: parent.width + anchors.verticalCenter: parent.verticalCenter + + Label { + id: maxTasksText + horizontalAlignment: Text.AlignHCenter + wrapMode: Text.Wrap + text: qsTr("Choose the maximum amount of tasks each project can have.") + font.pointSize: AppSettings.fontSize + + Layout.fillWidth: true + } + + SpinBox { + id: maxTasksSpinbox + editable: true + from: 5 + value: AppSettings.maxTasks + to: 30 + + Layout.alignment: Qt.AlignHCenter + Layout.topMargin: 10 + + onValueModified: AppSettings.maxTasks = maxTasksSpinbox.value + } + } +} diff --git a/examples/quickcontrols/ios/todolist/NavBar.qml b/examples/quickcontrols/ios/todolist/NavBar.qml new file mode 100644 index 0000000000..4f57353dca --- /dev/null +++ b/examples/quickcontrols/ios/todolist/NavBar.qml @@ -0,0 +1,44 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +import QtQuick +import QtQuick.Controls + +ToolBar { + id: root + width: parent.width + + required property StackView stackView + + ToolButton { + enabled: root.stackView.depth >= 2 + anchors.left: parent.left + anchors.leftMargin: 5 + visible: root.stackView.depth >= 2 + anchors.verticalCenter: parent.verticalCenter + display: AbstractButton.TextBesideIcon + text: root.stackView.depth > 2 ? qsTr("Back") : qsTr("Home") + font.pointSize: AppSettings.fontSize + icon.source: "images/back.png" + icon.height: 20 + icon.width: 20 + + onClicked: root.stackView.pop() + } + + ToolButton { + anchors.right: parent.right + anchors.rightMargin: 5 + icon.source: "images/settings.png" + icon.height: 20 + icon.width: 20 + visible: { + // Force the binding to re-evaluate so that the title check is run each time the page changes. + root.stackView.currentItem + !root.stackView.find((item, index) => { return item.title === "settingsPage" }) + } + + onClicked: root.stackView.push("SettingsPage.qml") + } +} + diff --git a/examples/quickcontrols/ios/todolist/ProjectPage.qml b/examples/quickcontrols/ios/todolist/ProjectPage.qml new file mode 100644 index 0000000000..a38ad04554 --- /dev/null +++ b/examples/quickcontrols/ios/todolist/ProjectPage.qml @@ -0,0 +1,255 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +Page { + id: root + + required property int projectIndex + required property int projectId + required property string projectName + required property string projectNote + + required property int completedTasks + required property int totalTasks + + required property ListModel projectsModel + + header: ColumnLayout { + id: titleRow + spacing: 4 + + TextField { + id: projectNameLabel + Layout.fillWidth: true + text: root.projectName + font.pointSize: AppSettings.fontSize + 10 + font.styleName: "Bold" + padding: 0 + background: null + wrapMode: TextField.Wrap + + Layout.topMargin: 10 + Layout.leftMargin: 20 + Layout.rightMargin: 20 + + onEditingFinished: { + Database.updateProjectName(root.projectId, text) + projectsModel.setProperty(projectIndex, "projectName", projectNameLabel.text) + } + } + + Label { + text: root.completedTasks + " / " + root.totalTasks + Layout.leftMargin: 20 + } + + ProgressBar { + id: progressBar + from: 0 + value: root.completedTasks + to: root.totalTasks + Layout.leftMargin: 20 + } + } + + ColumnLayout { + anchors.fill: parent + + TextArea { + id: textArea + leftPadding: 15 + rightPadding: doneButton.width + bottomPadding: 10 + topPadding: 10 + font.pointSize: AppSettings.fontSize + placeholderText: qsTr("Write a note...") + text: root.projectNote + wrapMode: TextArea.Wrap + clip: true + + Layout.fillWidth: true + Layout.preferredHeight: 80 + Layout.topMargin: 20 + + onEditingFinished: { + Database.updateProjectNote(root.projectId, text) + projectsModel.setProperty(projectIndex, "projectNote", textArea.text) + } + + Button { + id: doneButton + text: qsTr("Done") + flat: true + visible: textArea.focus + onClicked: textArea.editingFinished() + anchors.right: parent.right + anchors.bottom: parent.bottom + } + } + + ListView { + id: taskListView + model: taskModel + clip: true + + Layout.fillWidth: true + Layout.fillHeight: true + Layout.topMargin: 20 + + ListModel { + id: taskModel + + Component.onCompleted: { + let tasks = Database.getTaskByProject(projectId) + for (let task of tasks) + append(task) + } + } + + delegate: CheckDelegate { + id: taskList + width: taskListView.width + height: visible ? 40 : 0 + checked: done + visible: !done || (done && AppSettings.showDoneTasks) + + required property bool done + required property int taskId + required property string taskName + required property int index + + onClicked: { + Database.updateDoneState(taskId, checked ? 1 : 0) + taskModel.setProperty(index, "done", checked) + root.completedTasks = Math.max(Database.countDoneTasksByProject(root.projectId).rows.length, 0) + root.totalTasks = Math.max(Database.countTaskByProject(root.projectId).rows.length, 0) + root.projectsModel.setProperty(projectIndex, "completedTasks", root.completedTasks) + } + + TextField { + id: taskNameLabel + text: taskList.taskName + anchors.left: deleteTaskButton.right + anchors.leftMargin: 10 + padding: 0 + font.pointSize: AppSettings.fontSize + anchors.verticalCenter: parent.verticalCenter + background: null + + onEditingFinished: { + Database.updateTaskName(taskList.taskId, taskNameLabel.text) + taskModel.setProperty(index, "taskName", taskNameLabel.text) + } + } + + Button { + id: deleteTaskButton + anchors.left: parent.left + width: 15 + height: 15 + flat: true + topPadding: 0 + bottomPadding: 0 + rightPadding: 0 + leftPadding: 0 + anchors.leftMargin: 10 + anchors.verticalCenter: parent.verticalCenter + icon.source: "images/close.png" + icon.color: Qt.styleHints.appearance === Qt.Dark ? "white" : "black" + + onClicked: { + Database.deleteTask(taskList.taskId) + taskModel.remove(index, 1) + root.totalTasks-- + if (taskList.done) + root.completedTasks-- + } + } + } + } + + Popup { + id: addTaskPopup + parent: root + anchors.centerIn: parent + height: 200 + modal: true + focus: true + + ColumnLayout { + anchors.fill: parent + + Label { + text: qsTr("Add New Task") + font.pointSize: AppSettings.fontSize + 2.0 + font.bold: true + + Layout.alignment: Qt.AlignHCenter + } + + TextField { + id: newTaskNameTextField + placeholderText: qsTr("Enter task name") + font.pointSize: AppSettings.fontSize + + Keys.onReturnPressed: { + if (addTaskButton.enabled) + addTaskButton.clicked() + } + + Layout.fillWidth: true + Layout.leftMargin: 10 + Layout.rightMargin: 10 + Layout.alignment: Qt.AlignHCenter + } + + Button { + id: addTaskButton + text: qsTr("Add task") + flat: true + font.pointSize: AppSettings.fontSize + enabled: newTaskNameTextField.length > 0 + + Layout.alignment: Qt.AlignHCenter + + onClicked: { + const result = Database.newTask(root.projectId, newTaskNameTextField.text) + taskModel.append({ + "taskId": parseInt(result.insertId), + "taskName": newTaskNameTextField.text, "done": false + }) + root.projectsModel.setProperty(projectIndex, "totalTasks", taskListView.count) + newTaskNameTextField.text = "" + root.totalTasks++ + addTaskPopup.close() + } + } + } + } + + Label { + text: qsTr("Task limit reached.") + Layout.alignment: Qt.AlignHCenter + Layout.bottomMargin: 20 + font.pointSize: AppSettings.fontSize + visible: taskListView.count >= AppSettings.maxTasks + } + } + + footer: ToolBar { + ToolButton { + anchors.right: parent.right + anchors.rightMargin: 5 + text: qsTr("New task") + font.pointSize: AppSettings.fontSize - 2 + icon.source: "images/add-new.png" + enabled: taskListView.count < AppSettings.maxTasks + + onClicked: addTaskPopup.open() + } + } +} diff --git a/examples/quickcontrols/ios/todolist/SettingsPage.qml b/examples/quickcontrols/ios/todolist/SettingsPage.qml new file mode 100644 index 0000000000..4d2d7bef9f --- /dev/null +++ b/examples/quickcontrols/ios/todolist/SettingsPage.qml @@ -0,0 +1,67 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +import QtQuick +import QtQuick.Controls + +Page { + title: "settingsPage" + + property bool showDoneTasks: true + + header: Label { + text: qsTr("Settings") + font.pointSize: AppSettings.fontSize + 20 + font.styleName: "Semibold" + leftPadding: 20 + topPadding: 20 + } + + ListView { + anchors.fill: parent + topMargin: 20 + model: listModel + clip: true + + ListModel { + id: listModel + ListElement { + setting: qsTr("Font size") + page: "FontSize" + } + + ListElement { + setting: qsTr("Maximum number of tasks per project") + page: "MaxTasks" + } + + ListElement { + setting: qsTr("Show completed tasks") + page: "ToggleCompletedTasks" + } + } + + delegate: ItemDelegate { + width: parent.width + text: setting + font.pointSize: AppSettings.fontSize + + onClicked: stackView.push(page + "Page.qml") + + required property string setting + required property string page + + Image { + source: Qt.styleHints.appearance === Qt.Dark ? "images/back-white.png" + : "images/back.png" + width: 20 + height: 20 + anchors.right: parent.right + anchors.rightMargin: 10 + fillMode: Image.PreserveAspectFit + anchors.verticalCenter: parent.verticalCenter + mirror: true + } + } + } +} diff --git a/examples/quickcontrols/ios/todolist/ToggleCompletedTasksPage.qml b/examples/quickcontrols/ios/todolist/ToggleCompletedTasksPage.qml new file mode 100644 index 0000000000..df2145866a --- /dev/null +++ b/examples/quickcontrols/ios/todolist/ToggleCompletedTasksPage.qml @@ -0,0 +1,34 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +Page { + ColumnLayout { + width: parent.width + anchors.verticalCenter: parent.verticalCenter + + Label { + id: toggleText + horizontalAlignment: Text.AlignHCenter + wrapMode: Text.Wrap + text: toggleTasksSwitch.checked ? qsTr("Completed tasks will be shown.") + : qsTr("Completed tasks will be hidden.") + font.pointSize: AppSettings.fontSize + + Layout.fillWidth: true + } + + Switch { + id: toggleTasksSwitch + checked: AppSettings.showDoneTasks + + Layout.alignment: Qt.AlignHCenter + Layout.topMargin: 10 + + onClicked: AppSettings.showDoneTasks = checked + } + } +} diff --git a/examples/quickcontrols/ios/todolist/doc/images/qtquickcontrols2-todolist.png b/examples/quickcontrols/ios/todolist/doc/images/qtquickcontrols2-todolist.png Binary files differnew file mode 100644 index 0000000000..5be7190a43 --- /dev/null +++ b/examples/quickcontrols/ios/todolist/doc/images/qtquickcontrols2-todolist.png diff --git a/examples/quickcontrols/ios/todolist/doc/src/qtquickcontrols2-todolist.qdoc b/examples/quickcontrols/ios/todolist/doc/src/qtquickcontrols2-todolist.qdoc new file mode 100644 index 0000000000..12e2d4fca5 --- /dev/null +++ b/examples/quickcontrols/ios/todolist/doc/src/qtquickcontrols2-todolist.qdoc @@ -0,0 +1,22 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only + +/*! + \example ios/todolist + \keyword Qt Quick Controls - To Do List + \title Qt Quick Controls - To Do List + \keyword Qt Quick Controls 2 - To Do List + \ingroup qtquickcontrols2-examples + \brief To do list application for iOS. + + This example demonstrates how to create a simple to do list application for + iOS using the \l {iOS Style}. + + \image qtquickcontrols2-todolist.png + + The example also shows how an in-memory SQL database can be created and + used purely through QML, without needing C++, through the use of + \l {Qt Quick Local Storage QML Types}{LocalStorage}. + + \include examples-run.qdocinc +*/ diff --git a/examples/quickcontrols/ios/todolist/images/add-new.png b/examples/quickcontrols/ios/todolist/images/add-new.png Binary files differnew file mode 100644 index 0000000000..2e60e48a2d --- /dev/null +++ b/examples/quickcontrols/ios/todolist/images/add-new.png diff --git a/examples/quickcontrols/ios/todolist/images/add-new@2x.png b/examples/quickcontrols/ios/todolist/images/add-new@2x.png Binary files differnew file mode 100644 index 0000000000..edb8b62847 --- /dev/null +++ b/examples/quickcontrols/ios/todolist/images/add-new@2x.png diff --git a/examples/quickcontrols/ios/todolist/images/add-new@3x.png b/examples/quickcontrols/ios/todolist/images/add-new@3x.png Binary files differnew file mode 100644 index 0000000000..b5b9b6a5d6 --- /dev/null +++ b/examples/quickcontrols/ios/todolist/images/add-new@3x.png diff --git a/examples/quickcontrols/ios/todolist/images/back-white.png b/examples/quickcontrols/ios/todolist/images/back-white.png Binary files differnew file mode 100644 index 0000000000..503bdf4d48 --- /dev/null +++ b/examples/quickcontrols/ios/todolist/images/back-white.png diff --git a/examples/quickcontrols/ios/todolist/images/back-white@2x.png b/examples/quickcontrols/ios/todolist/images/back-white@2x.png Binary files differnew file mode 100644 index 0000000000..e201ec6d5b --- /dev/null +++ b/examples/quickcontrols/ios/todolist/images/back-white@2x.png diff --git a/examples/quickcontrols/ios/todolist/images/back-white@3x.png b/examples/quickcontrols/ios/todolist/images/back-white@3x.png Binary files differnew file mode 100644 index 0000000000..eb8b7ffc68 --- /dev/null +++ b/examples/quickcontrols/ios/todolist/images/back-white@3x.png diff --git a/examples/quickcontrols/ios/todolist/images/back.png b/examples/quickcontrols/ios/todolist/images/back.png Binary files differnew file mode 100644 index 0000000000..94580efd7f --- /dev/null +++ b/examples/quickcontrols/ios/todolist/images/back.png diff --git a/examples/quickcontrols/ios/todolist/images/back@2x.png b/examples/quickcontrols/ios/todolist/images/back@2x.png Binary files differnew file mode 100644 index 0000000000..b5cf424e91 --- /dev/null +++ b/examples/quickcontrols/ios/todolist/images/back@2x.png diff --git a/examples/quickcontrols/ios/todolist/images/back@3x.png b/examples/quickcontrols/ios/todolist/images/back@3x.png Binary files differnew file mode 100644 index 0000000000..50d5102f4e --- /dev/null +++ b/examples/quickcontrols/ios/todolist/images/back@3x.png diff --git a/examples/quickcontrols/ios/todolist/images/close-white.png b/examples/quickcontrols/ios/todolist/images/close-white.png Binary files differnew file mode 100644 index 0000000000..72163067a6 --- /dev/null +++ b/examples/quickcontrols/ios/todolist/images/close-white.png diff --git a/examples/quickcontrols/ios/todolist/images/close-white@2x.png b/examples/quickcontrols/ios/todolist/images/close-white@2x.png Binary files differnew file mode 100644 index 0000000000..54828e84d1 --- /dev/null +++ b/examples/quickcontrols/ios/todolist/images/close-white@2x.png diff --git a/examples/quickcontrols/ios/todolist/images/close-white@3x.png b/examples/quickcontrols/ios/todolist/images/close-white@3x.png Binary files differnew file mode 100644 index 0000000000..dd67cf1b69 --- /dev/null +++ b/examples/quickcontrols/ios/todolist/images/close-white@3x.png diff --git a/examples/quickcontrols/ios/todolist/images/close.png b/examples/quickcontrols/ios/todolist/images/close.png Binary files differnew file mode 100644 index 0000000000..eba32b637d --- /dev/null +++ b/examples/quickcontrols/ios/todolist/images/close.png diff --git a/examples/quickcontrols/ios/todolist/images/close@2x.png b/examples/quickcontrols/ios/todolist/images/close@2x.png Binary files differnew file mode 100644 index 0000000000..72cf76317a --- /dev/null +++ b/examples/quickcontrols/ios/todolist/images/close@2x.png diff --git a/examples/quickcontrols/ios/todolist/images/close@3x.png b/examples/quickcontrols/ios/todolist/images/close@3x.png Binary files differnew file mode 100644 index 0000000000..6cb2ea58d9 --- /dev/null +++ b/examples/quickcontrols/ios/todolist/images/close@3x.png diff --git a/examples/quickcontrols/ios/todolist/images/plus-math.png b/examples/quickcontrols/ios/todolist/images/plus-math.png Binary files differnew file mode 100644 index 0000000000..b0d182d23e --- /dev/null +++ b/examples/quickcontrols/ios/todolist/images/plus-math.png diff --git a/examples/quickcontrols/ios/todolist/images/plus-math@2x.png b/examples/quickcontrols/ios/todolist/images/plus-math@2x.png Binary files differnew file mode 100644 index 0000000000..112a132084 --- /dev/null +++ b/examples/quickcontrols/ios/todolist/images/plus-math@2x.png diff --git a/examples/quickcontrols/ios/todolist/images/plus-math@3x.png b/examples/quickcontrols/ios/todolist/images/plus-math@3x.png Binary files differnew file mode 100644 index 0000000000..ca513d200b --- /dev/null +++ b/examples/quickcontrols/ios/todolist/images/plus-math@3x.png diff --git a/examples/quickcontrols/ios/todolist/images/settings.png b/examples/quickcontrols/ios/todolist/images/settings.png Binary files differnew file mode 100644 index 0000000000..600981fb35 --- /dev/null +++ b/examples/quickcontrols/ios/todolist/images/settings.png diff --git a/examples/quickcontrols/ios/todolist/images/settings@2x.png b/examples/quickcontrols/ios/todolist/images/settings@2x.png Binary files differnew file mode 100644 index 0000000000..80541aa028 --- /dev/null +++ b/examples/quickcontrols/ios/todolist/images/settings@2x.png diff --git a/examples/quickcontrols/ios/todolist/images/settings@3x.png b/examples/quickcontrols/ios/todolist/images/settings@3x.png Binary files differnew file mode 100644 index 0000000000..48c2b2a8c0 --- /dev/null +++ b/examples/quickcontrols/ios/todolist/images/settings@3x.png diff --git a/examples/quickcontrols/ios/todolist/main.qml b/examples/quickcontrols/ios/todolist/main.qml new file mode 100644 index 0000000000..a0067643f1 --- /dev/null +++ b/examples/quickcontrols/ios/todolist/main.qml @@ -0,0 +1,32 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +import QtQuick +import QtQuick.Window +import QtQuick.Controls + +ApplicationWindow { + width: 390 + height: 844 + visible: true + title: "To Do List" + + header: NavBar { + stackView: stackView + } + + Flickable { + width: parent.width + height: parent.height + flickableDirection: Flickable.VerticalFlick + boundsBehavior: Flickable.StopAtBounds + + ScrollIndicator.vertical: ScrollIndicator {} + + StackView { + id: stackView + anchors.fill: parent + initialItem: HomePage {} + } + } +} diff --git a/examples/quickcontrols/ios/todolist/qmldir b/examples/quickcontrols/ios/todolist/qmldir new file mode 100644 index 0000000000..e0c443110e --- /dev/null +++ b/examples/quickcontrols/ios/todolist/qmldir @@ -0,0 +1,2 @@ +singleton Database 1.0 Database.qml +singleton AppSettings 1.0 AppSettings.qml diff --git a/examples/quickcontrols/ios/todolist/src/main.cpp b/examples/quickcontrols/ios/todolist/src/main.cpp new file mode 100644 index 0000000000..4f158402a2 --- /dev/null +++ b/examples/quickcontrols/ios/todolist/src/main.cpp @@ -0,0 +1,34 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#include <QGuiApplication> +#include <QQmlApplicationEngine> +#include <QtQml/qqmlextensionplugin.h> +#include <QtQuickControls2/qquickstyle.h> + +using namespace Qt::StringLiterals; + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + QQuickStyle::setStyle("iOS"); + + QQmlApplicationEngine engine; + const QUrl url(u"qrc:/main.qml"_s); + QObject::connect( + &engine, &QQmlApplicationEngine::objectCreated, &app, + [url](QObject *obj, const QUrl &objUrl) { + if (!obj && url == objUrl) + QCoreApplication::exit(-1); + }, + Qt::QueuedConnection); + + engine.addImportPath(":/"); + + engine.load(url); + if (engine.rootObjects().isEmpty()) + return -1; + + return app.exec(); +} diff --git a/examples/quickcontrols/ios/todolist/todolist.pro b/examples/quickcontrols/ios/todolist/todolist.pro new file mode 100644 index 0000000000..d77d718a62 --- /dev/null +++ b/examples/quickcontrols/ios/todolist/todolist.pro @@ -0,0 +1,42 @@ +TEMPLATE = app +TARGET = todolist +QT += quick quickcontrols2 + +SOURCES += src/main.cpp + +RESOURCES += \ + images/back.png \ + images/back@2x.png \ + images/back@3x.png \ + images/back-white.png \ + images/back-white@2x.png \ + images/back-white@3x.png \ + images/close.png \ + images/close@2x.png \ + images/close@3x.png \ + images/close-white.png \ + images/close-white@2x.png \ + images/close-white@3x.png \ + images/plus-math.png \ + images/plus-math@2x.png \ + images/plus-math@3x.png \ + images/settings.png \ + images/settings@2x.png \ + images/settings@3x.png \ + images/add-new.png \ + images/add-new@2x.png \ + images/add-new@3x.png \ + main.qml \ + AppSettings.qml \ + Database.qml \ + FontSizePage.qml \ + HomePage.qml \ + MaxTasksPage.qml \ + NavBar.qml \ + ProjectPage.qml \ + SettingsPage.qml \ + ToggleCompletedTasksPage.qml \ + qmldir + +target.path = $$[QT_INSTALL_EXAMPLES]/quickcontrols2/ios/todolist +INSTALLS += target diff --git a/examples/quickcontrols/quickcontrols2.pro b/examples/quickcontrols/quickcontrols2.pro new file mode 100644 index 0000000000..b7fc57bca6 --- /dev/null +++ b/examples/quickcontrols/quickcontrols2.pro @@ -0,0 +1,14 @@ +TEMPLATE = subdirs +SUBDIRS += \ + gallery \ + chattutorial \ + texteditor \ + contactlist \ + sidepanel \ + swipetoremove \ + wearable \ + imagine/automotive \ + imagine/musicplayer + +qtHaveModule(sql): SUBDIRS += eventcalendar +qtHaveModule(widgets): SUBDIRS += flatstyle diff --git a/examples/quickcontrols/sidepanel/CMakeLists.txt b/examples/quickcontrols/sidepanel/CMakeLists.txt new file mode 100644 index 0000000000..7a832eda13 --- /dev/null +++ b/examples/quickcontrols/sidepanel/CMakeLists.txt @@ -0,0 +1,47 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +cmake_minimum_required(VERSION 3.16) +project(sidepanel LANGUAGES CXX) + +set(CMAKE_AUTOMOC ON) + +if(NOT DEFINED INSTALL_EXAMPLESDIR) + set(INSTALL_EXAMPLESDIR "examples") +endif() + +set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/quickcontrols2/sidepanel") + +find_package(Qt6 REQUIRED COMPONENTS Core Gui Quick) + +qt_add_executable(sidepanelexample WIN32 MACOSX_BUNDLE + sidepanel.cpp +) + +qt_add_qml_module(sidepanelexample + URI sidepanel + VERSION 1.0 + NO_RESOURCE_TARGET_PATH + QML_FILES + "sidepanel.qml" + RESOURCES + "images/qt-logo.png" + "images/qt-logo@2x.png" + "images/qt-logo@3x.png" + "images/qt-logo@4x.png" + "qtquickcontrols2.conf" + "doc/images/qtquickcontrols2-sidepanel-landscape.png" + "doc/images/qtquickcontrols2-sidepanel-portrait.png" +) + +target_link_libraries(sidepanelexample PUBLIC + Qt::Core + Qt::Gui + Qt::Quick +) + +install(TARGETS sidepanelexample + RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" + LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" +) diff --git a/examples/quickcontrols/sidepanel/doc/images/qtquickcontrols2-sidepanel-landscape.png b/examples/quickcontrols/sidepanel/doc/images/qtquickcontrols2-sidepanel-landscape.png Binary files differnew file mode 100644 index 0000000000..86907591b2 --- /dev/null +++ b/examples/quickcontrols/sidepanel/doc/images/qtquickcontrols2-sidepanel-landscape.png diff --git a/examples/quickcontrols/sidepanel/doc/images/qtquickcontrols2-sidepanel-portrait.png b/examples/quickcontrols/sidepanel/doc/images/qtquickcontrols2-sidepanel-portrait.png Binary files differnew file mode 100644 index 0000000000..cf1ed2efd0 --- /dev/null +++ b/examples/quickcontrols/sidepanel/doc/images/qtquickcontrols2-sidepanel-portrait.png diff --git a/examples/quickcontrols/sidepanel/doc/src/qtquickcontrols2-sidepanel.qdoc b/examples/quickcontrols/sidepanel/doc/src/qtquickcontrols2-sidepanel.qdoc new file mode 100644 index 0000000000..d5baa46eef --- /dev/null +++ b/examples/quickcontrols/sidepanel/doc/src/qtquickcontrols2-sidepanel.qdoc @@ -0,0 +1,59 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only + +/*! + \example sidepanel + \keyword Qt Quick Controls - Side Panel + \title Qt Quick Controls - Side Panel + \keyword Qt Quick Controls 2 - Side Panel + \ingroup qtquickcontrols2-examples + \brief A persistent side panel with Drawer. + + This example demonstrates how \l Drawer can be used as a persistent side + panel. + + \raw HTML + <div class="table"><table style="background:transparent; border:0px"> + <tr><td style="border:0px"> + \endraw + \image qtquickcontrols2-sidepanel-portrait.png + \caption An interactive Drawer in portrait mode + \raw HTML + </td><td style="border:0px"> + \endraw + \image qtquickcontrols2-sidepanel-landscape.png + \caption A non-interactive Drawer in landscape mode + \raw HTML + </td></tr> + </table></div> + \endraw + + When the application is in portrait mode, the drawer is an interactive + side panel that can be swiped open from the left edge. It appears on + top of the content, blocking user interaction through its modal + background. When the application is in landscape mode, the drawer and + the content are laid out side-by-side. + + The current orientation of the application is determined by comparing + the width and height of the window: + + \snippet sidepanel/sidepanel.qml orientation + + This is used to determine whether the drawer should be \l {Popup::}{modal} + and \l {Drawer::}{interactive}, and to configure its \l {Drawer::}{position} + and \l {Popup::visible}{visibility} accordingly. + + \quotefromfile sidepanel/sidepanel.qml + \skipto Drawer + \printline Drawer + \dots 8 + \codeline + \skipto modal + \printuntil visible + \dots 8 + \skipuntil ScrollIndicator + \skipuntil } + \printline } + + \include examples-run.qdocinc +*/ diff --git a/examples/quickcontrols/sidepanel/images/qt-logo.png b/examples/quickcontrols/sidepanel/images/qt-logo.png Binary files differnew file mode 100644 index 0000000000..dff7729515 --- /dev/null +++ b/examples/quickcontrols/sidepanel/images/qt-logo.png diff --git a/examples/quickcontrols/sidepanel/images/qt-logo@2x.png b/examples/quickcontrols/sidepanel/images/qt-logo@2x.png Binary files differnew file mode 100644 index 0000000000..dbd73aab77 --- /dev/null +++ b/examples/quickcontrols/sidepanel/images/qt-logo@2x.png diff --git a/examples/quickcontrols/sidepanel/images/qt-logo@3x.png b/examples/quickcontrols/sidepanel/images/qt-logo@3x.png Binary files differnew file mode 100644 index 0000000000..68e763b597 --- /dev/null +++ b/examples/quickcontrols/sidepanel/images/qt-logo@3x.png diff --git a/examples/quickcontrols/sidepanel/images/qt-logo@4x.png b/examples/quickcontrols/sidepanel/images/qt-logo@4x.png Binary files differnew file mode 100644 index 0000000000..08fd882572 --- /dev/null +++ b/examples/quickcontrols/sidepanel/images/qt-logo@4x.png diff --git a/examples/quickcontrols/sidepanel/qtquickcontrols2.conf b/examples/quickcontrols/sidepanel/qtquickcontrols2.conf new file mode 100644 index 0000000000..b6c7c87ea1 --- /dev/null +++ b/examples/quickcontrols/sidepanel/qtquickcontrols2.conf @@ -0,0 +1,2 @@ +[Controls] +Style=Material diff --git a/examples/quickcontrols/sidepanel/sidepanel.cpp b/examples/quickcontrols/sidepanel/sidepanel.cpp new file mode 100644 index 0000000000..c78329d9de --- /dev/null +++ b/examples/quickcontrols/sidepanel/sidepanel.cpp @@ -0,0 +1,17 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#include <QGuiApplication> +#include <QQmlApplicationEngine> + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + engine.load(QUrl("qrc:/sidepanel.qml")); + if (engine.rootObjects().isEmpty()) + return -1; + + return app.exec(); +} diff --git a/examples/quickcontrols/sidepanel/sidepanel.pro b/examples/quickcontrols/sidepanel/sidepanel.pro new file mode 100644 index 0000000000..3ae9cd8d6b --- /dev/null +++ b/examples/quickcontrols/sidepanel/sidepanel.pro @@ -0,0 +1,19 @@ +TEMPLATE = app +TARGET = sidepanel +QT += quick + +SOURCES += \ + sidepanel.cpp + +RESOURCES += \ + doc/images/qtquickcontrols2-sidepanel-landscape.png \ + doc/images/qtquickcontrols2-sidepanel-portrait.png \ + images/qt-logo@2x.png \ + images/qt-logo@3x.png \ + images/qt-logo@4x.png \ + images/qt-logo.png \ + qtquickcontrols2.conf \ + sidepanel.qml + +target.path = $$[QT_INSTALL_EXAMPLES]/quickcontrols2/sidepanel +INSTALLS += target diff --git a/examples/quickcontrols/sidepanel/sidepanel.qml b/examples/quickcontrols/sidepanel/sidepanel.qml new file mode 100644 index 0000000000..de767a9bb6 --- /dev/null +++ b/examples/quickcontrols/sidepanel/sidepanel.qml @@ -0,0 +1,132 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + id: window + width: 360 + height: 520 + visible: true + title: qsTr("Side Panel") + + //! [orientation] + readonly property bool inPortrait: window.width < window.height + //! [orientation] + + ToolBar { + id: overlayHeader + + z: 1 + width: parent.width + parent: Overlay.overlay + + Label { + id: label + anchors.centerIn: parent + text: "Qt Quick Controls" + } + } + + Drawer { + id: drawer + + y: overlayHeader.height + width: window.width / 2 + height: window.height - overlayHeader.height + + modal: inPortrait + interactive: inPortrait + position: inPortrait ? 0 : 1 + visible: !inPortrait + + ListView { + id: listView + anchors.fill: parent + + headerPositioning: ListView.OverlayHeader + header: Pane { + id: header + z: 2 + width: parent.width + + contentHeight: logo.height + + Image { + id: logo + width: parent.width + source: "images/qt-logo.png" + fillMode: implicitWidth > width ? Image.PreserveAspectFit : Image.Pad + } + + MenuSeparator { + parent: header + width: parent.width + anchors.verticalCenter: parent.bottom + visible: !listView.atYBeginning + } + } + + footer: ItemDelegate { + id: footer + text: qsTr("Footer") + width: parent.width + + MenuSeparator { + parent: footer + width: parent.width + anchors.verticalCenter: parent.top + } + } + + model: 10 + + delegate: ItemDelegate { + text: qsTr("Title %1").arg(index + 1) + width: listView.width + } + + ScrollIndicator.vertical: ScrollIndicator { } + } + } + + Flickable { + id: flickable + + anchors.fill: parent + anchors.topMargin: overlayHeader.height + anchors.leftMargin: !inPortrait ? drawer.width : undefined + + topMargin: 20 + bottomMargin: 20 + contentHeight: column.height + + Column { + id: column + spacing: 20 + anchors.margins: 20 + anchors.left: parent.left + anchors.right: parent.right + + Label { + font.pixelSize: 22 + width: parent.width + elide: Label.ElideRight + horizontalAlignment: Qt.AlignHCenter + text: qsTr("Side Panel Example") + } + + Label { + width: parent.width + wrapMode: Label.WordWrap + text: qsTr("This example demonstrates how Drawer can be used as a non-closable persistent side panel.\n\n" + + "When the application is in portrait mode, the drawer is an interactive side panel that can " + + "be swiped open from the left edge. When the application is in landscape mode, the drawer " + + "and the content are laid out side by side.\n\nThe application is currently in %1 mode.").arg(inPortrait ? qsTr("portrait") : qsTr("landscape")) + } + } + + ScrollIndicator.vertical: ScrollIndicator { } + } +} diff --git a/examples/quickcontrols/swipetoremove/CMakeLists.txt b/examples/quickcontrols/swipetoremove/CMakeLists.txt new file mode 100644 index 0000000000..813f9f1e1f --- /dev/null +++ b/examples/quickcontrols/swipetoremove/CMakeLists.txt @@ -0,0 +1,41 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +cmake_minimum_required(VERSION 3.16) +project(swipetoremove LANGUAGES CXX) + +set(CMAKE_AUTOMOC ON) + +if(NOT DEFINED INSTALL_EXAMPLESDIR) + set(INSTALL_EXAMPLESDIR "examples") +endif() + +set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/quickcontrols2/swipetoremove") + +find_package(Qt6 REQUIRED COMPONENTS Core Gui Qml) + +qt_add_executable(swipetoremoveexample WIN32 MACOSX_BUNDLE + swipetoremove.cpp +) +target_link_libraries(swipetoremoveexample PUBLIC + Qt::Core + Qt::Gui + Qt::Qml +) + +# Resources: +qt_add_qml_module(swipetoremoveexample + URI swipetoremove + VERSION 1.0 + NO_RESOURCE_TARGET_PATH + QML_FILES + "swipetoremove.qml" + RESOURCES + "fonts/fontello.ttf" +) + +install(TARGETS swipetoremoveexample + RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" + LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" +) diff --git a/examples/quickcontrols/swipetoremove/doc/images/qtquickcontrols2-swipetoremove.png b/examples/quickcontrols/swipetoremove/doc/images/qtquickcontrols2-swipetoremove.png Binary files differnew file mode 100644 index 0000000000..07a200fe92 --- /dev/null +++ b/examples/quickcontrols/swipetoremove/doc/images/qtquickcontrols2-swipetoremove.png diff --git a/examples/quickcontrols/swipetoremove/doc/src/qtquickcontrols2-swipetoremove.qdoc b/examples/quickcontrols/swipetoremove/doc/src/qtquickcontrols2-swipetoremove.qdoc new file mode 100644 index 0000000000..a8f36912b2 --- /dev/null +++ b/examples/quickcontrols/swipetoremove/doc/src/qtquickcontrols2-swipetoremove.qdoc @@ -0,0 +1,40 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only + +/*! + \example swipetoremove + \keyword Qt Quick Controls - Swipe to Remove + \title Qt Quick Controls - Swipe to Remove + \keyword Qt Quick Controls 2 - Swipe to Remove + \ingroup qtquickcontrols2-examples + \brief Demonstrates removal of list items by swipe gesture. + + This example demonstrates how \l SwipeDelegate can be used to implement + removal of list items by swiping. This UI pattern is often used in touch + user interfaces. + + \image qtquickcontrols2-swipetoremove.png + + Each list item can be swiped to the left, which reveals a label on the + \l {SwipeDelegate::swipe}{right} side indicating that the item will be + removed if the swipe is completed. The following snippet contains the + implementation of the side item. + + \snippet swipetoremove/swipetoremove.qml delegate + + The following snippet presents how the logic of removing items is + implemented. When the swipe is \l {SwipeDelegate::swipe}{completed}, it + starts a timer that waits a few seconds to let the user undo the remove + action. Once the undo timer triggers, the item is removed from the list: + + \snippet swipetoremove/swipetoremove.qml removal + + Finally, the removal of an item triggers the following transitions. The + \l {ListView::} {remove} transition applies to the item that is removed, + and the \l {ListView::}{displaced} transition applies to the other items + that got displaced due to the removal: + + \snippet swipetoremove/swipetoremove.qml transitions + + \include examples-run.qdocinc +*/ diff --git a/examples/quickcontrols/swipetoremove/fonts/LICENSE.txt b/examples/quickcontrols/swipetoremove/fonts/LICENSE.txt new file mode 100644 index 0000000000..7394a58ddf --- /dev/null +++ b/examples/quickcontrols/swipetoremove/fonts/LICENSE.txt @@ -0,0 +1,12 @@ +Font license info + + +## Elusive + + Copyright (C) 2013 by Aristeides Stathopoulos + + Author: Aristeides Stathopoulos + License: SIL (http://scripts.sil.org/OFL) + Homepage: http://aristeides.com/ + + diff --git a/examples/quickcontrols/swipetoremove/fonts/fontello.ttf b/examples/quickcontrols/swipetoremove/fonts/fontello.ttf Binary files differnew file mode 100644 index 0000000000..553fd2efca --- /dev/null +++ b/examples/quickcontrols/swipetoremove/fonts/fontello.ttf diff --git a/examples/quickcontrols/swipetoremove/swipetoremove.cpp b/examples/quickcontrols/swipetoremove/swipetoremove.cpp new file mode 100644 index 0000000000..0bd8e24521 --- /dev/null +++ b/examples/quickcontrols/swipetoremove/swipetoremove.cpp @@ -0,0 +1,20 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#include <QGuiApplication> +#include <QQmlApplicationEngine> +#include <QFontDatabase> + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + QFontDatabase::addApplicationFont(":/fonts/fontello.ttf"); + + QQmlApplicationEngine engine; + engine.load(QUrl("qrc:/swipetoremove.qml")); + if (engine.rootObjects().isEmpty()) + return -1; + + return app.exec(); +} diff --git a/examples/quickcontrols/swipetoremove/swipetoremove.pro b/examples/quickcontrols/swipetoremove/swipetoremove.pro new file mode 100644 index 0000000000..bcdb45cd45 --- /dev/null +++ b/examples/quickcontrols/swipetoremove/swipetoremove.pro @@ -0,0 +1,10 @@ +TEMPLATE = app +TARGET = swipetoremove +QT += qml + +SOURCES += swipetoremove.cpp + +RESOURCES += swipetoremove.qml + +target.path = $$[QT_INSTALL_EXAMPLES]/quickcontrols2/swipetoremove +INSTALLS += target diff --git a/examples/quickcontrols/swipetoremove/swipetoremove.qml b/examples/quickcontrols/swipetoremove/swipetoremove.qml new file mode 100644 index 0000000000..a7820eb024 --- /dev/null +++ b/examples/quickcontrols/swipetoremove/swipetoremove.qml @@ -0,0 +1,130 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Material + +ApplicationWindow { + id: window + width: 300 + height: 400 + visible: true + title: qsTr("Swipe to Remove") + + ListView { + id: listView + anchors.fill: parent + + delegate: SwipeDelegate { + id: delegate + + text: modelData + width: listView.width + + //! [delegate] + swipe.right: Rectangle { + width: parent.width + height: parent.height + + clip: true + color: SwipeDelegate.pressed ? "#555" : "#666" + + Label { + font.family: "Fontello" + text: delegate.swipe.complete ? "\ue805" // icon-cw-circled + : "\ue801" // icon-cancel-circled-1 + + padding: 20 + anchors.fill: parent + horizontalAlignment: Qt.AlignRight + verticalAlignment: Qt.AlignVCenter + + opacity: 2 * -delegate.swipe.position + + color: Material.color(delegate.swipe.complete ? Material.Green : Material.Red, Material.Shade200) + Behavior on color { ColorAnimation { } } + } + + Label { + text: qsTr("Removed") + color: "white" + + padding: 20 + anchors.fill: parent + horizontalAlignment: Qt.AlignLeft + verticalAlignment: Qt.AlignVCenter + + opacity: delegate.swipe.complete ? 1 : 0 + Behavior on opacity { NumberAnimation { } } + } + + SwipeDelegate.onClicked: delegate.swipe.close() + SwipeDelegate.onPressedChanged: undoTimer.stop() + } + //! [delegate] + + //! [removal] + Timer { + id: undoTimer + interval: 3600 + onTriggered: listModel.remove(index) + } + + swipe.onCompleted: undoTimer.start() + //! [removal] + } + + model: ListModel { + id: listModel + ListElement { text: "Lorem ipsum dolor sit amet" } + ListElement { text: "Curabitur sit amet risus" } + ListElement { text: "Suspendisse vehicula nisi" } + ListElement { text: "Mauris imperdiet libero" } + ListElement { text: "Sed vitae dui aliquet augue" } + ListElement { text: "Praesent in elit eu nulla" } + ListElement { text: "Etiam vitae magna" } + ListElement { text: "Pellentesque eget elit euismod" } + ListElement { text: "Nulla at enim porta" } + ListElement { text: "Fusce tincidunt odio" } + ListElement { text: "Ut non ex a ligula molestie" } + ListElement { text: "Nam vitae justo scelerisque" } + ListElement { text: "Vestibulum pulvinar tellus" } + ListElement { text: "Quisque dignissim leo sed gravida" } + } + + //! [transitions] + remove: Transition { + SequentialAnimation { + PauseAnimation { duration: 125 } + NumberAnimation { property: "height"; to: 0; easing.type: Easing.InOutQuad } + } + } + + displaced: Transition { + SequentialAnimation { + PauseAnimation { duration: 125 } + NumberAnimation { property: "y"; easing.type: Easing.InOutQuad } + } + } + //! [transitions] + + ScrollIndicator.vertical: ScrollIndicator { } + } + + Label { + id: placeholder + text: qsTr("Swipe no more") + + anchors.margins: 60 + anchors.fill: parent + + opacity: 0.5 + visible: listView.count === 0 + + horizontalAlignment: Qt.AlignHCenter + verticalAlignment: Qt.AlignVCenter + wrapMode: Label.WordWrap + font.pixelSize: 18 + } +} diff --git a/examples/quickcontrols/texteditor/+touch/texteditor.html b/examples/quickcontrols/texteditor/+touch/texteditor.html new file mode 100644 index 0000000000..b5f03f258e --- /dev/null +++ b/examples/quickcontrols/texteditor/+touch/texteditor.html @@ -0,0 +1,19 @@ +<html> +<head> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <meta name="qrichtext" content="1"> + <title>Text Editor Example</title> +</head> +<body> +<body> + <p align="center"> + <img src="qrc:/images/qt-logo.png" /> + </p> + <h2 align="center"> + Qt Quick Controls 2 + </h2> + <p align="center"> + This example demonstrates a modern rich text editor. + </p> +</body> +</html> diff --git a/examples/quickcontrols/texteditor/CMakeLists.txt b/examples/quickcontrols/texteditor/CMakeLists.txt new file mode 100644 index 0000000000..d978d82fce --- /dev/null +++ b/examples/quickcontrols/texteditor/CMakeLists.txt @@ -0,0 +1,59 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +cmake_minimum_required(VERSION 3.16) +project(texteditor LANGUAGES CXX) + +set(CMAKE_AUTOMOC ON) + +if(NOT DEFINED INSTALL_EXAMPLESDIR) + set(INSTALL_EXAMPLESDIR "examples") +endif() + +set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/quickcontrols2/texteditor") + +find_package(Qt6 REQUIRED COMPONENTS Core Gui Quick QuickControls2 OPTIONAL_COMPONENTS Widgets) + +qt_add_executable(texteditorexample WIN32 MACOSX_BUNDLE + documenthandler.cpp + texteditor.cpp +) + +qt_add_qml_module(texteditorexample + URI texteditor + VERSION 1.0 + NO_RESOURCE_TARGET_PATH + QML_FILES + "qml/+touch/texteditor.qml" + "qml/texteditor.qml" + RESOURCES + "texteditor.html" + "+touch/texteditor.html" + "fonts/fontello.ttf" + "images/qt-logo.png" +) + +target_link_libraries(texteditorexample PUBLIC + Qt::Core + Qt::Gui + Qt::Quick + Qt::QuickControls2 +) + +if(TARGET Qt::Widgets) + target_link_libraries(texteditorexample PUBLIC + Qt::Widgets + ) +endif() + +if(CMAKE_CROSSCOMPILING) + target_compile_definitions(texteditorexample PUBLIC + QT_EXTRA_FILE_SELECTOR="touch" + ) +endif() + +install(TARGETS texteditorexample + RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" + LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" +) diff --git a/examples/quickcontrols/texteditor/creatorKateHighlighter.png b/examples/quickcontrols/texteditor/creatorKateHighlighter.png Binary files differnew file mode 100644 index 0000000000..7dd819507f --- /dev/null +++ b/examples/quickcontrols/texteditor/creatorKateHighlighter.png diff --git a/examples/quickcontrols/texteditor/doc/images/qtquickcontrols2-texteditor-desktop.jpg b/examples/quickcontrols/texteditor/doc/images/qtquickcontrols2-texteditor-desktop.jpg Binary files differnew file mode 100644 index 0000000000..259e0e8b07 --- /dev/null +++ b/examples/quickcontrols/texteditor/doc/images/qtquickcontrols2-texteditor-desktop.jpg diff --git a/examples/quickcontrols/texteditor/doc/images/qtquickcontrols2-texteditor-touch.jpg b/examples/quickcontrols/texteditor/doc/images/qtquickcontrols2-texteditor-touch.jpg Binary files differnew file mode 100644 index 0000000000..6a924cdf52 --- /dev/null +++ b/examples/quickcontrols/texteditor/doc/images/qtquickcontrols2-texteditor-touch.jpg diff --git a/examples/quickcontrols/texteditor/doc/src/qtquickcontrols2-texteditor.qdoc b/examples/quickcontrols/texteditor/doc/src/qtquickcontrols2-texteditor.qdoc new file mode 100644 index 0000000000..d626a6a04e --- /dev/null +++ b/examples/quickcontrols/texteditor/doc/src/qtquickcontrols2-texteditor.qdoc @@ -0,0 +1,100 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only +/*! + \example texteditor + \keyword Qt Quick Controls - Text Editor + \title Qt Quick Controls - Text Editor + \keyword Qt Quick Controls 2 - Text Editor + \ingroup qtquickcontrols2-examples + \brief A QML app using Qt Quick Controls and a C++ class to + provide a fully-functional rich-text editor application. + + The \e {Text Editor Example} presents a sample HTML file using the TextArea + control, preserving the HTML formatting. The application comes with two user + interfaces; one for traditional desktop platforms with a mouse pointer, and + another simpler, touch-oriented version. + + \section1 Desktop User Interface + + \image qtquickcontrols2-texteditor-desktop.jpg + + The desktop version is a complete text editor with capabilities for formatting + text, and opening and saving HTML and plain text files. It demonstrates the + native-looking dialogs and menus using the \l{Qt Labs Platform} module. These + types are mostly suitable for desktop platforms with support for multiple + top-level windows, a mouse pointer, and moderate screen size. + + The desktop UI uses FileDialog for opening and saving files: + + \quotefromfile texteditor/qml/texteditor.qml + \skipto FileDialog + \printuntil /\bsaveAs\b/ + \printline } + + It uses FontDialog and ColorDialog for choosing fonts and colors: + + \skipto FontDialog + \printuntil /.*colorDialog$/ + \printuntil /^\s{4}\}$/ + + It also uses \l[QML QtLabsPlatform]{Menu} and + \l[QML QtLabsPlatform]{MenuItem} that provide a context menu to format text + within: + + \skipto /\bMenu\b/ + \printuntil /^\s{4}\}$/ + + \note There is also a standard menubar with more options than the + context menu. + + \section1 Touch User Interface + + \image qtquickcontrols2-texteditor-touch.jpg + + The touch user interface is a simplified version of the text editor. It is + suitable for touch devices with limited screen size. The example uses + \l{Using File Selectors with Qt Quick Controls}{file selectors} to load + the appropriate user interface automatically. + + Unlike the desktop version, which uses top-level dialogs, the touch version + uses the QML \l Dialog type, which is not a top-level window. This type of + dialog is fully supported on mobile and embedded platforms that do not support + multiple top-level windows. + + \quotefromfile texteditor/qml/+touch/texteditor.qml + \skipto /\bDialog\b/ + \printuntil /^\s{4}\}$/ + + \section1 C++ Backend + + Both user interfaces use the same C++ backend, which supports opening, formatting, + and editing a document. The C++ class, \c DocumentHandler, extends QObject and is + registered as a QML type under the namespace \c {io.qt.examples.texteditor 1.0}. + + The following snippets show how the type is registered under a namespace and later + imported and instantiated by \e main.qml. For more information about registering C++ + classes as QML types, see \l {Defining QML Types from C++}. + + QML type registration: + + \code + #include <QtQml/qqml.h> + ... + qmlRegisterType<DocumentHandler>("io.qt.examples.texteditor", 1, 0, "DocumentHandler"); + ... + \endcode + + QML namespace import: + + \code + import io.qt.examples.texteditor 1.0 + \endcode + + QML instance: + + \quotefromfile texteditor/qml/texteditor.qml + \skipto DocumentHandler + \printuntil /^\s{4}\}$/ + + \include examples-run.qdocinc +*/ diff --git a/examples/quickcontrols/texteditor/documenthandler.cpp b/examples/quickcontrols/texteditor/documenthandler.cpp new file mode 100644 index 0000000000..9571aa03ba --- /dev/null +++ b/examples/quickcontrols/texteditor/documenthandler.cpp @@ -0,0 +1,348 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#include "documenthandler.h" + +#include <QFile> +#include <QFileInfo> +#include <QFileSelector> +#include <QMimeDatabase> +#include <QQmlFile> +#include <QQmlFileSelector> +#include <QQuickTextDocument> +#include <QTextCharFormat> +#include <QStringDecoder> +#include <QTextDocument> +#include <QDebug> + +DocumentHandler::DocumentHandler(QObject *parent) + : QObject(parent) + , m_document(nullptr) + , m_cursorPosition(-1) + , m_selectionStart(0) + , m_selectionEnd(0) +{ +} + +QQuickTextDocument *DocumentHandler::document() const +{ + return m_document; +} + +void DocumentHandler::setDocument(QQuickTextDocument *document) +{ + if (document == m_document) + return; + + if (m_document) + disconnect(m_document->textDocument(), &QTextDocument::modificationChanged, this, &DocumentHandler::modifiedChanged); + m_document = document; + if (m_document) + connect(m_document->textDocument(), &QTextDocument::modificationChanged, this, &DocumentHandler::modifiedChanged); + emit documentChanged(); +} + +int DocumentHandler::cursorPosition() const +{ + return m_cursorPosition; +} + +void DocumentHandler::setCursorPosition(int position) +{ + if (position == m_cursorPosition) + return; + + m_cursorPosition = position; + reset(); + emit cursorPositionChanged(); +} + +int DocumentHandler::selectionStart() const +{ + return m_selectionStart; +} + +void DocumentHandler::setSelectionStart(int position) +{ + if (position == m_selectionStart) + return; + + m_selectionStart = position; + emit selectionStartChanged(); +} + +int DocumentHandler::selectionEnd() const +{ + return m_selectionEnd; +} + +void DocumentHandler::setSelectionEnd(int position) +{ + if (position == m_selectionEnd) + return; + + m_selectionEnd = position; + emit selectionEndChanged(); +} + +QColor DocumentHandler::textColor() const +{ + QTextCursor cursor = textCursor(); + if (cursor.isNull()) + return QColor(Qt::black); + QTextCharFormat format = cursor.charFormat(); + return format.foreground().color(); +} + +void DocumentHandler::setTextColor(const QColor &color) +{ + QTextCharFormat format; + format.setForeground(QBrush(color)); + mergeFormatOnWordOrSelection(format); + emit textColorChanged(); +} + +Qt::Alignment DocumentHandler::alignment() const +{ + QTextCursor cursor = textCursor(); + if (cursor.isNull()) + return Qt::AlignLeft; + return textCursor().blockFormat().alignment(); +} + +void DocumentHandler::setAlignment(Qt::Alignment alignment) +{ + QTextBlockFormat format; + format.setAlignment(alignment); + QTextCursor cursor = textCursor(); + cursor.mergeBlockFormat(format); + emit alignmentChanged(); +} + +QString DocumentHandler::fileName() const +{ + const QString filePath = QQmlFile::urlToLocalFileOrQrc(m_fileUrl); + const QString fileName = QFileInfo(filePath).fileName(); + if (fileName.isEmpty()) + return QStringLiteral("untitled.txt"); + return fileName; +} + +QString DocumentHandler::fileType() const +{ + return QFileInfo(fileName()).suffix(); +} + +QUrl DocumentHandler::fileUrl() const +{ + return m_fileUrl; +} + +void DocumentHandler::load(const QUrl &fileUrl) +{ + if (fileUrl == m_fileUrl) + return; + + QQmlEngine *engine = qmlEngine(this); + if (!engine) { + qWarning() << "load() called before DocumentHandler has QQmlEngine"; + return; + } + + const QUrl path = QQmlFileSelector::get(engine)->selector()->select(fileUrl); + const QString fileName = QQmlFile::urlToLocalFileOrQrc(path); + if (QFile::exists(fileName)) { + QMimeType mime = QMimeDatabase().mimeTypeForFile(fileName); + QFile file(fileName); + if (file.open(QFile::ReadOnly)) { + QByteArray data = file.readAll(); + if (QTextDocument *doc = textDocument()) { + doc->setBaseUrl(path.adjusted(QUrl::RemoveFilename)); + doc->setModified(false); + if (mime.inherits("text/markdown")) { + emit loaded(QString::fromUtf8(data), Qt::MarkdownText); + } else { + auto encoding = QStringConverter::encodingForHtml(data); + if (encoding) { + QStringDecoder decoder(*encoding); + emit loaded(decoder(data), Qt::AutoText); + } else { + // fall back to utf8 + emit loaded(QString::fromUtf8(data), Qt::AutoText); + } + } + } + + reset(); + } + } + + m_fileUrl = fileUrl; + emit fileUrlChanged(); +} + +void DocumentHandler::saveAs(const QUrl &fileUrl) +{ + QTextDocument *doc = textDocument(); + if (!doc) + return; + + const QString filePath = fileUrl.toLocalFile(); + const bool isHtml = QFileInfo(filePath).suffix().contains(QLatin1String("htm")); + QFile file(filePath); + if (!file.open(QFile::WriteOnly | QFile::Truncate | (isHtml ? QFile::NotOpen : QFile::Text))) { + emit error(tr("Cannot save: ") + file.errorString()); + return; + } + file.write((isHtml ? doc->toHtml() : doc->toPlainText()).toUtf8()); + file.close(); + + if (fileUrl == m_fileUrl) + return; + + m_fileUrl = fileUrl; + emit fileUrlChanged(); +} + +void DocumentHandler::reset() +{ + emit alignmentChanged(); + emit textColorChanged(); + emit fontChanged(); +} + +QTextCursor DocumentHandler::textCursor() const +{ + QTextDocument *doc = textDocument(); + if (!doc) + return QTextCursor(); + + QTextCursor cursor = QTextCursor(doc); + if (m_selectionStart != m_selectionEnd) { + cursor.setPosition(m_selectionStart); + cursor.setPosition(m_selectionEnd, QTextCursor::KeepAnchor); + } else { + cursor.setPosition(m_cursorPosition); + } + return cursor; +} + +QTextDocument *DocumentHandler::textDocument() const +{ + if (!m_document) + return nullptr; + + return m_document->textDocument(); +} + +void DocumentHandler::mergeFormatOnWordOrSelection(const QTextCharFormat &format) +{ + QTextCursor cursor = textCursor(); + if (!cursor.hasSelection()) + cursor.select(QTextCursor::WordUnderCursor); + cursor.mergeCharFormat(format); +} + +bool DocumentHandler::modified() const +{ + return m_document && m_document->textDocument()->isModified(); +} + +void DocumentHandler::setModified(bool m) +{ + if (m_document) + m_document->textDocument()->setModified(m); +} + +QFont DocumentHandler::font() const +{ + QTextCursor cursor = textCursor(); + if (cursor.isNull()) + return m_document->textDocument()->defaultFont(); + QTextCharFormat format = cursor.charFormat(); + return format.font(); +} + +void DocumentHandler::setFont(const QFont & font){ + + QTextCursor cursor = textCursor(); + if (!cursor.isNull() && cursor.charFormat().font() == font) + return; + + QTextCharFormat format; + format.setFont(font); + mergeFormatOnWordOrSelection(format); + + emit fontChanged(); +} + +bool DocumentHandler::bold() const +{ + const QTextCursor cursor = textCursor(); + if (cursor.isNull()) + return m_document->textDocument()->defaultFont().bold(); + return cursor.charFormat().font().bold(); +} + +void DocumentHandler::setBold(bool bold) +{ + const QTextCursor cursor = textCursor(); + if (!cursor.isNull() && cursor.charFormat().font().bold() == bold) + return; + + QFont font = cursor.charFormat().font(); + font.setBold(bold); + QTextCharFormat format; + format.setFont(font); + mergeFormatOnWordOrSelection(format); + + emit boldChanged(); +} + +bool DocumentHandler::underline() const +{ + const QTextCursor cursor = textCursor(); + if (cursor.isNull()) + return m_document->textDocument()->defaultFont().underline(); + return cursor.charFormat().font().underline(); +} + +void DocumentHandler::setUnderline(bool underline) +{ + const QTextCursor cursor = textCursor(); + if (!cursor.isNull() && cursor.charFormat().font().underline() == underline) + return; + + QFont font = cursor.charFormat().font(); + font.setUnderline(underline); + QTextCharFormat format; + format.setFont(font); + mergeFormatOnWordOrSelection(format); + + emit underlineChanged(); +} + +bool DocumentHandler::italic() const +{ + const QTextCursor cursor = textCursor(); + if (cursor.isNull()) + return m_document->textDocument()->defaultFont().italic(); + return cursor.charFormat().font().italic(); +} + +void DocumentHandler::setItalic(bool italic) +{ + const QTextCursor cursor = textCursor(); + if (!cursor.isNull() && cursor.charFormat().font().italic() == italic) + return; + + QFont font = cursor.charFormat().font(); + font.setItalic(italic); + QTextCharFormat format; + format.setFont(font); + mergeFormatOnWordOrSelection(format); + + emit italicChanged(); +} + +#include "moc_documenthandler.cpp" diff --git a/examples/quickcontrols/texteditor/documenthandler.h b/examples/quickcontrols/texteditor/documenthandler.h new file mode 100644 index 0000000000..b750997885 --- /dev/null +++ b/examples/quickcontrols/texteditor/documenthandler.h @@ -0,0 +1,121 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#ifndef DOCUMENTHANDLER_H +#define DOCUMENTHANDLER_H + +#include <QFont> +#include <QObject> +#include <QTextCursor> +#include <QUrl> + +QT_BEGIN_NAMESPACE +class QTextDocument; +class QQuickTextDocument; +QT_END_NAMESPACE + +class DocumentHandler : public QObject +{ + Q_OBJECT + + Q_PROPERTY(QQuickTextDocument *document READ document WRITE setDocument NOTIFY documentChanged) + Q_PROPERTY(int cursorPosition READ cursorPosition WRITE setCursorPosition NOTIFY cursorPositionChanged) + Q_PROPERTY(int selectionStart READ selectionStart WRITE setSelectionStart NOTIFY selectionStartChanged) + Q_PROPERTY(int selectionEnd READ selectionEnd WRITE setSelectionEnd NOTIFY selectionEndChanged) + + Q_PROPERTY(QColor textColor READ textColor WRITE setTextColor NOTIFY textColorChanged) + Q_PROPERTY(Qt::Alignment alignment READ alignment WRITE setAlignment NOTIFY alignmentChanged) + + Q_PROPERTY(QFont font READ font WRITE setFont NOTIFY fontChanged) + + Q_PROPERTY(bool bold READ bold WRITE setBold NOTIFY boldChanged) + Q_PROPERTY(bool underline READ underline WRITE setUnderline NOTIFY underlineChanged) + Q_PROPERTY(bool italic READ italic WRITE setItalic NOTIFY italicChanged) + + Q_PROPERTY(QString fileName READ fileName NOTIFY fileUrlChanged) + Q_PROPERTY(QString fileType READ fileType NOTIFY fileUrlChanged) + Q_PROPERTY(QUrl fileUrl READ fileUrl NOTIFY fileUrlChanged) + + Q_PROPERTY(bool modified READ modified WRITE setModified NOTIFY modifiedChanged) + +public: + explicit DocumentHandler(QObject *parent = nullptr); + + QQuickTextDocument *document() const; + void setDocument(QQuickTextDocument *document); + + int cursorPosition() const; + void setCursorPosition(int position); + + int selectionStart() const; + void setSelectionStart(int position); + + int selectionEnd() const; + void setSelectionEnd(int position); + + QColor textColor() const; + void setTextColor(const QColor &color); + + Qt::Alignment alignment() const; + void setAlignment(Qt::Alignment alignment); + + QFont font() const; + void setFont(const QFont & font); + + bool bold() const; + void setBold(bool bold); + + bool underline() const; + void setUnderline(bool underline); + + bool italic() const; + void setItalic(bool italic); + + QString fileName() const; + QString fileType() const; + QUrl fileUrl() const; + + bool modified() const; + void setModified(bool m); + +public Q_SLOTS: + void load(const QUrl &fileUrl); + void saveAs(const QUrl &fileUrl); + +Q_SIGNALS: + void documentChanged(); + void cursorPositionChanged(); + void selectionStartChanged(); + void selectionEndChanged(); + + void fontChanged(); + void boldChanged(); + void underlineChanged(); + void italicChanged(); + void textColorChanged(); + void alignmentChanged(); + + void textChanged(); + void fileUrlChanged(); + + void loaded(const QString &text, int format); + void error(const QString &message); + + void modifiedChanged(); + +private: + void reset(); + QTextCursor textCursor() const; + QTextDocument *textDocument() const; + void mergeFormatOnWordOrSelection(const QTextCharFormat &format); + + QQuickTextDocument *m_document; + + int m_cursorPosition; + int m_selectionStart; + int m_selectionEnd; + + QUrl m_fileUrl; +}; + +#endif // DOCUMENTHANDLER_H diff --git a/examples/quickcontrols/texteditor/einstein.png b/examples/quickcontrols/texteditor/einstein.png Binary files differnew file mode 100644 index 0000000000..3611284df4 --- /dev/null +++ b/examples/quickcontrols/texteditor/einstein.png diff --git a/examples/quickcontrols/texteditor/example.md b/examples/quickcontrols/texteditor/example.md new file mode 100644 index 0000000000..e385227e3b --- /dev/null +++ b/examples/quickcontrols/texteditor/example.md @@ -0,0 +1,179 @@ +# Markdown in Qt Quick + +The Text, TextEdit and TextArea items support rich text formatted in HTML. +Since Qt 5.14, they now support two dialects of Markdown as well: +[The CommonMark Specification](https://spec.commonmark.org/0.29/) is the +conservative formal specification, while +[GitHub Flavored Markdown](https://guides.github.com/features/mastering-markdown/#GitHub-flavored-markdown) +adds extra features such as task lists and tables. + +If you are viewing this document in the Qt Quick Controls Text Editor example, +you can edit this document to explore Qt's rich text editing features. +We have included some comments in each of the following sections to +encourage you to experiment. + +## Font and Paragraph Styles + +Markdown supports **bold**, *italic*, ~~strikethrough~~ and `monospace` font +styles. + +> A block quote is indented according to the convention for email quoting. + + A block of code; + can be indented; + with 4 spaces or a tab; + +or + +``` +Block { + id: code + CanBe { + wrappedBy: "triple backticks" + } +} +``` + +Block quotes can be nested, and block quotes can include indented code blocks. + +In [The CommonMark Specification](https://spec.commonmark.org/0.29/) +John MacFarlane writes: + +> What distinguishes Markdown from many other lightweight markup syntaxes, +> which are often easier to write, is its readability. As Gruber writes: + +> > The overriding design goal for Markdown's formatting syntax is to make it +> > as readable as possible. The idea is that a Markdown-formatted document should +> > be publishable as-is, as plain text, without looking like it's been marked up +> > with tags or formatting instructions. ( +> > [http://daringfireball.net/projects/markdown/](http://daringfireball.net/projects/markdown/)) + +> The point can be illustrated by comparing a sample of AsciiDoc with an +> equivalent sample of Markdown. Here is a sample of AsciiDoc from the AsciiDoc +> manual: + +> 1. List item one. +> + +> List item one continued with a second paragraph followed by an +> Indented block. +> + +> ................. +> $ ls *.sh +> $ mv *.sh ~/tmp +> ................. +> + +> List item continued with a third paragraph. +> +> 2. List item two continued with an open block. +> ... +> + +## Hyperlinks + +Hyperlinks can be written with the link text first, and the URL immediately +following: [Qt Assistant](http://doc.qt.io/qt-6/qtassistant-index.html) + +A plain url is automatically recognized: https://doc.qt.io/qt-6/qml-qtquick-text.html + +There are also "reference links" where the link text is first labeled +and then the URL for the label is given elsewhere: +[The Qt Creator Manual][creatormanual] + +## Images + +Inline images like this one ![red square](red.png) flow with the surrounding text. + +The code for including an image is just a link that starts with a bang. +An image in its own paragraph is given its own space: + +![Albert Einstein image](einstein.png) + +## Lists + +Different kinds of lists can be included. Standard bullet lists can be nested, +using different symbols for each level of the list. List items can have nested +items such as block quotes, code blocks and images. Check boxes can be included +to form a task list. + +- Disc symbols are typically used for top-level list items. + * Circle symbols can be used to distinguish between items in lower-level + lists. + + Square symbols provide a reasonable alternative to discs and circles. + * Lists can be continued... + * further down +- List items can include images: ![red square](red.png) +- and even nested quotes, like this: + + The [Qt Documentation](https://doc.qt.io/qt-6/qml-qtquick-textedit.html#details) + points out that + > The TextEdit item displays a block of editable, formatted text. + > + > It can display both plain and rich text. For example: + > + > TextEdit { + > width: 240 + > text: "<b>Hello</b> <i>World!</i>" + > font.family: "Helvetica" + > font.pointSize: 20 + > color: "blue" + > focus: true + > } +- List items with check boxes allow task lists to be incorporated: + * [ ] This task is not yet done + * [x] We aced this one! + +Ordered lists can be used for tables of contents, for example. Each number +should end with a period or a parenthesis: + +1. Markdown in Qt Quick + 1) Font and Paragraph Styles + 5) Hyperlinks + 3) Images ![red square](red.png) + 2) Lists + 4) Tables +2. Related work + +The list will automatically be renumbered during rendering. + +## Thematic Breaks + +A horizontal rule is possible, as in HTML: + +- - - + +## Tables + +One of the GitHub extensions is support for tables: + +| |Development Tools |Programming Techniques |Graphical User Interfaces| +|-------------|------------------------------------|---------------------------|-------------------------| +|9:00 - 11:00 |Introduction to Qt ||| +|11:00 - 13:00|Using Qt Creator |QML and its runtime |Layouts in Qt | +|13:00 - 15:00|Qt Quick Designer Tutorial |Extreme Programming |Writing Custom Styles | +|15:00 - 17:00|Qt Linguist and Internationalization| | | + +# Related Work + +Some Qt Widgets also support Markdown. +[QTextEdit](https://doc.qt.io/qt-6/qtextedit.html) has similar WYSIWYG +editing features as TextEdit and TextArea: you can edit the rendered text +directly. You can use +[QTextDocument::toMarkdown](https://doc-snapshots.qt.io/qt5-dev/qtextdocument.html#toMarkdown) +to rewrite the Markdown format, and save it back to a file. + +If you have the [KDE Kate Editor](https://kate-editor.org/) installed on your +system, you probably also have the `markdown.xml` syntax highlighting +definition file; that can be reused to add Markdown syntax highlighting to +Qt Creator. + +![creator markdown highlighting from Kate](creatorKateHighlighter.png) + +Qt owes thanks to the authors of the [MD4C parser](https://github.com/mity/md4c) +for making markdown import possible. The QTextMarkdownWriter class does not +have such dependencies, and also has not yet been tested as extensively, so we +do not yet guarantee that we are able to rewrite every Markdown document that +you are able to read and display with Text or TextEdit. But you are free to +write [bugs](https://bugreports.qt.io) about any troublesome cases that you +encounter. + +[creatormanual]: https://doc.qt.io/qtcreator/ "Qt Creator Manual" diff --git a/examples/quickcontrols/texteditor/fonts/fontello.ttf b/examples/quickcontrols/texteditor/fonts/fontello.ttf Binary files differnew file mode 100644 index 0000000000..f02b44ec12 --- /dev/null +++ b/examples/quickcontrols/texteditor/fonts/fontello.ttf diff --git a/examples/quickcontrols/texteditor/images/qt-logo.png b/examples/quickcontrols/texteditor/images/qt-logo.png Binary files differnew file mode 100644 index 0000000000..2ebc01aafa --- /dev/null +++ b/examples/quickcontrols/texteditor/images/qt-logo.png diff --git a/examples/quickcontrols/texteditor/qml/+touch/texteditor.qml b/examples/quickcontrols/texteditor/qml/+touch/texteditor.qml new file mode 100644 index 0000000000..2a0d9f117f --- /dev/null +++ b/examples/quickcontrols/texteditor/qml/+touch/texteditor.qml @@ -0,0 +1,217 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import QtQuick.Window + +import io.qt.examples.texteditor + +// TODO: +// - make designer-friendly + +ApplicationWindow { + id: window + visible: true + title: document.fileName + " - Text Editor Example" + + header: ToolBar { + leftPadding: 5 + + RowLayout { + anchors.fill: parent + spacing: 0 + + ToolButton { + id: doneEditingButton + font.family: "fontello" + text: "\uE80A" // icon-ok + opacity: !textArea.readOnly ? 1 : 0 + onClicked: textArea.readOnly = true + } + + Label { + text: qsTr("Text Editor Example") + font.bold: true + font.pixelSize: 20 + elide: Label.ElideRight + Layout.fillWidth: true + } + + ToolButton { + font.family: "fontello" + text: "\uF142" // icon-ellipsis-vert + onClicked: menu.open() + + Menu { + id: menu + + MenuItem { + text: qsTr("About") + onTriggered: aboutDialog.open() + } + } + } + } + } + + DocumentHandler { + id: document + document: textArea.textDocument + cursorPosition: textArea.cursorPosition + selectionStart: textArea.selectionStart + selectionEnd: textArea.selectionEnd + // textColor: TODO + Component.onCompleted: document.load("qrc:/texteditor.html") + onLoaded: { + textArea.text = text + } + onError: { + errorDialog.text = message + errorDialog.visible = true + } + } + + Flickable { + id: flickable + flickableDirection: Flickable.VerticalFlick + anchors.fill: parent + + TextArea.flickable: TextArea { + id: textArea + textFormat: Qt.RichText + wrapMode: TextArea.Wrap + readOnly: true + persistentSelection: true + // Different styles have different padding and background + // decorations, but since this editor is almost taking up the + // entire window, we don't need them. + leftPadding: 6 + rightPadding: 6 + topPadding: 0 + bottomPadding: 0 + background: null + + onLinkActivated: Qt.openUrlExternally(link) + } + + ScrollBar.vertical: ScrollBar {} + } + + footer: ToolBar { + visible: !textArea.readOnly && textArea.activeFocus + + Flickable { + anchors.fill: parent + contentWidth: toolRow.implicitWidth + flickableDirection: Qt.Horizontal + boundsBehavior: Flickable.StopAtBounds + + Row { + id: toolRow + + ToolButton { + id: boldButton + text: "\uE800" // icon-bold + font.family: "fontello" + // Don't want to close the virtual keyboard when this is clicked. + focusPolicy: Qt.NoFocus + checkable: true + checked: document.bold + onClicked: document.bold = !document.bold + } + ToolButton { + id: italicButton + text: "\uE801" // icon-italic + font.family: "fontello" + focusPolicy: Qt.NoFocus + checkable: true + checked: document.italic + onClicked: document.italic = !document.italic + } + ToolButton { + id: underlineButton + text: "\uF0CD" // icon-underline + font.family: "fontello" + focusPolicy: Qt.NoFocus + checkable: true + checked: document.underline + onClicked: document.underline = !document.underline + } + + ToolSeparator {} + + ToolButton { + id: alignLeftButton + text: "\uE803" // icon-align-left + font.family: "fontello" + focusPolicy: Qt.NoFocus + checkable: true + checked: document.alignment == Qt.AlignLeft + onClicked: document.alignment = Qt.AlignLeft + } + ToolButton { + id: alignCenterButton + text: "\uE804" // icon-align-center + font.family: "fontello" + focusPolicy: Qt.NoFocus + checkable: true + checked: document.alignment == Qt.AlignHCenter + onClicked: document.alignment = Qt.AlignHCenter + } + ToolButton { + id: alignRightButton + text: "\uE805" // icon-align-right + font.family: "fontello" + focusPolicy: Qt.NoFocus + checkable: true + checked: document.alignment == Qt.AlignRight + onClicked: document.alignment = Qt.AlignRight + } + ToolButton { + id: alignJustifyButton + text: "\uE806" // icon-align-justify + font.family: "fontello" + focusPolicy: Qt.NoFocus + checkable: true + checked: document.alignment == Qt.AlignJustify + onClicked: document.alignment = Qt.AlignJustify + } + } + } + } + + RoundButton { + id: editButton + font.family: "fontello" + text: "\uE809" // icon-pencil + width: 48 + height: width + // Don't want to use anchors for the y position, because it will anchor + // to the footer, leaving a large vertical gap. + y: parent.height - height - 12 + anchors.right: parent.right + anchors.margins: 12 + visible: textArea.readOnly + highlighted: true + + onClicked: { + textArea.readOnly = false + // Force focus on the text area so the cursor and footer show up. + textArea.forceActiveFocus() + } + } + + Dialog { + id: aboutDialog + standardButtons: Dialog.Ok + modal: true + x: parent.width / 2 - width / 2 + y: parent.height / 2 - height / 2 + + contentItem: Label { + text: qsTr("Qt Quick Controls - Text Editor Example") + } + } +} diff --git a/examples/quickcontrols/texteditor/qml/texteditor.qml b/examples/quickcontrols/texteditor/qml/texteditor.qml new file mode 100644 index 0000000000..decf0801e4 --- /dev/null +++ b/examples/quickcontrols/texteditor/qml/texteditor.qml @@ -0,0 +1,479 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtCore +import QtQuick.Controls +import QtQuick.Window +import QtQuick.Dialogs +import Qt.labs.platform as Platform + +import io.qt.examples.texteditor + +// TODO: +// - make designer-friendly + +ApplicationWindow { + id: window + width: 1024 + height: 600 + visible: true + title: document.fileName + " - Text Editor Example" + + Component.onCompleted: { + x = Screen.width / 2 - width / 2 + y = Screen.height / 2 - height / 2 + } + + Action { + id: openAction + shortcut: StandardKey.Open + onTriggered: openDialog.open() + } + + Action { + id: saveAsAction + shortcut: StandardKey.SaveAs + onTriggered: saveDialog.open() + } + + Action { + id: quitAction + shortcut: StandardKey.Quit + onTriggered: close() + } + + Action { + id: copyAction + shortcut: StandardKey.Copy + onTriggered: textArea.copy() + } + + Action { + id: cutAction + shortcut: StandardKey.Cut + onTriggered: textArea.cut() + } + + Action { + id: pasteAction + shortcut: StandardKey.Paste + onTriggered: textArea.paste() + } + + Action { + id: boldAction + shortcut: StandardKey.Bold + onTriggered: document.bold = !document.bold + } + + Action { + id: italicAction + shortcut: StandardKey.Italic + onTriggered: document.italic = !document.italic + } + + Action { + id: underlineAction + shortcut: StandardKey.Underline + onTriggered: document.underline = !document.underline + } + + Platform.MenuBar { + Platform.Menu { + title: qsTr("&File") + + Platform.MenuItem { + text: qsTr("&Open") + onTriggered: openDialog.open() + } + Platform.MenuItem { + text: qsTr("&Save As...") + onTriggered: saveDialog.open() + } + Platform.MenuItem { + text: qsTr("&Quit") + onTriggered: close() + } + } + + Platform.Menu { + title: qsTr("&Edit") + + Platform.MenuItem { + text: qsTr("&Copy") + enabled: textArea.selectedText + onTriggered: textArea.copy() + } + Platform.MenuItem { + text: qsTr("Cu&t") + enabled: textArea.selectedText + onTriggered: textArea.cut() + } + Platform.MenuItem { + text: qsTr("&Paste") + enabled: textArea.canPaste + onTriggered: textArea.paste() + } + } + + Platform.Menu { + title: qsTr("F&ormat") + + Platform.MenuItem { + text: qsTr("&Bold") + checkable: true + checked: document.bold + onTriggered: document.bold = !document.bold + } + Platform.MenuItem { + text: qsTr("&Italic") + checkable: true + checked: document.italic + onTriggered: document.italic = !document.italic + } + Platform.MenuItem { + text: qsTr("&Underline") + checkable: true + checked: document.underline + onTriggered: document.underline = !document.underline + } + Platform.MenuItem { + text: qsTr("&Strikeout") + checkable: true + checked: document.strikeout + onTriggered: document.strikeout = !document.strikeout + } + } + } + + FileDialog { + id: openDialog + fileMode: FileDialog.OpenFile + selectedNameFilter.index: 1 + nameFilters: ["Text files (*.txt)", "HTML files (*.html *.htm)", "Markdown files (*.md *.markdown)"] + currentFolder: StandardPaths.writableLocation(StandardPaths.DocumentsLocation) + onAccepted: document.load(selectedFile) + } + + FileDialog { + id: saveDialog + fileMode: FileDialog.SaveFile + defaultSuffix: document.fileType + nameFilters: openDialog.nameFilters + selectedNameFilter.index: document.fileType === "txt" ? 0 : 1 + currentFolder: StandardPaths.writableLocation(StandardPaths.DocumentsLocation) + onAccepted: document.saveAs(selectedFile) + } + + FontDialog { + id: fontDialog + onAccepted: document.font = selectedFont + } + + ColorDialog { + id: colorDialog + selectedColor: "black" + onAccepted: document.textColor = selectedColor + } + + MessageDialog { + title: qsTr("Error") + id: errorDialog + } + + MessageDialog { + id : quitDialog + title: qsTr("Quit?") + text: qsTr("The file has been modified. Quit anyway?") + buttons: MessageDialog.Yes | MessageDialog.No + onButtonClicked: function (button, role) { if (role === MessageDialog.YesRole) Qt.quit() } + } + + header: ToolBar { + leftPadding: 8 + + Flow { + id: flow + width: parent.width + + Row { + id: fileRow + ToolButton { + id: openButton + text: "\uF115" // icon-folder-open-empty + font.family: "fontello" + action: openAction + focusPolicy: Qt.TabFocus + } + ToolSeparator { + contentItem.visible: fileRow.y === editRow.y + } + } + + Row { + id: editRow + ToolButton { + id: copyButton + text: "\uF0C5" // icon-docs + font.family: "fontello" + focusPolicy: Qt.TabFocus + enabled: textArea.selectedText + action: copyAction + } + ToolButton { + id: cutButton + text: "\uE802" // icon-scissors + font.family: "fontello" + focusPolicy: Qt.TabFocus + enabled: textArea.selectedText + action: cutAction + } + ToolButton { + id: pasteButton + text: "\uF0EA" // icon-paste + font.family: "fontello" + focusPolicy: Qt.TabFocus + enabled: textArea.canPaste + action: pasteAction + } + ToolSeparator { + contentItem.visible: editRow.y === formatRow.y + } + } + + Row { + id: formatRow + ToolButton { + id: boldButton + text: "\uE800" // icon-bold + font.family: "fontello" + focusPolicy: Qt.TabFocus + checkable: true + checked: document.bold + action: boldAction + } + ToolButton { + id: italicButton + text: "\uE801" // icon-italic + font.family: "fontello" + focusPolicy: Qt.TabFocus + checkable: true + checked: document.italic + action: italicAction + } + ToolButton { + id: underlineButton + text: "\uF0CD" // icon-underline + font.family: "fontello" + focusPolicy: Qt.TabFocus + checkable: true + checked: document.underline + action: underlineAction + } + ToolButton { + id: strikeoutButton + text: "\uF0CC" + font.family: "fontello" + focusPolicy: Qt.TabFocus + checkable: true + checked: document.strikeout + onClicked: document.strikeout = !document.strikeout + } + ToolButton { + id: fontFamilyToolButton + text: qsTr("\uE808") // icon-font + font.family: "fontello" + font.bold: document.bold + font.italic: document.italic + font.underline: document.underline + font.strikeout: document.strikeout + focusPolicy: Qt.TabFocus + onClicked: function () { + fontDialog.selectedFont = document.font + fontDialog.open() + } + } + ToolButton { + id: textColorButton + text: "\uF1FC" // icon-brush + font.family: "fontello" + focusPolicy: Qt.TabFocus + onClicked: function () { + colorDialog.selectedColor = document.textColor + colorDialog.open() + } + + Rectangle { + width: aFontMetrics.width + 3 + height: 2 + color: document.textColor + parent: textColorButton.contentItem + anchors.horizontalCenter: parent.horizontalCenter + anchors.baseline: parent.baseline + anchors.baselineOffset: 6 + + TextMetrics { + id: aFontMetrics + font: textColorButton.font + text: textColorButton.text + } + } + } + ToolSeparator { + contentItem.visible: formatRow.y === alignRow.y + } + } + + Row { + id: alignRow + ToolButton { + id: alignLeftButton + text: "\uE803" // icon-align-left + font.family: "fontello" + focusPolicy: Qt.TabFocus + checkable: true + checked: document.alignment == Qt.AlignLeft + onClicked: document.alignment = Qt.AlignLeft + } + ToolButton { + id: alignCenterButton + text: "\uE804" // icon-align-center + font.family: "fontello" + focusPolicy: Qt.TabFocus + checkable: true + checked: document.alignment == Qt.AlignHCenter + onClicked: document.alignment = Qt.AlignHCenter + } + ToolButton { + id: alignRightButton + text: "\uE805" // icon-align-right + font.family: "fontello" + focusPolicy: Qt.TabFocus + checkable: true + checked: document.alignment == Qt.AlignRight + onClicked: document.alignment = Qt.AlignRight + } + ToolButton { + id: alignJustifyButton + text: "\uE806" // icon-align-justify + font.family: "fontello" + focusPolicy: Qt.TabFocus + checkable: true + checked: document.alignment == Qt.AlignJustify + onClicked: document.alignment = Qt.AlignJustify + } + } + } + } + + DocumentHandler { + id: document + document: textArea.textDocument + cursorPosition: textArea.cursorPosition + selectionStart: textArea.selectionStart + selectionEnd: textArea.selectionEnd + + property alias family: document.font.family + property alias bold: document.font.bold + property alias italic: document.font.italic + property alias underline: document.font.underline + property alias strikeout: document.font.strikeout + property alias size: document.font.pointSize + + Component.onCompleted: { + if (Qt.application.arguments.length === 2) + document.load("file:" + Qt.application.arguments[1]); + else + document.load("qrc:/texteditor.html") + } + onLoaded: function (text, format) { + textArea.textFormat = format + textArea.text = text + } + onError: function (message) { + errorDialog.text = message + errorDialog.open() + } + } + + Flickable { + id: flickable + flickableDirection: Flickable.VerticalFlick + anchors.fill: parent + + TextArea.flickable: TextArea { + id: textArea + textFormat: Qt.RichText + wrapMode: TextArea.Wrap + focus: true + selectByMouse: true + persistentSelection: true + // Different styles have different padding and background + // decorations, but since this editor is almost taking up the + // entire window, we don't need them. + leftPadding: 6 + rightPadding: 6 + topPadding: 0 + bottomPadding: 0 + background: null + + MouseArea { + acceptedButtons: Qt.RightButton + anchors.fill: parent + onClicked: contextMenu.open() + } + + onLinkActivated: function (link) { + Qt.openUrlExternally(link) + } + } + + ScrollBar.vertical: ScrollBar {} + } + + Platform.Menu { + id: contextMenu + + Platform.MenuItem { + text: qsTr("Copy") + enabled: textArea.selectedText + onTriggered: textArea.copy() + } + Platform.MenuItem { + text: qsTr("Cut") + enabled: textArea.selectedText + onTriggered: textArea.cut() + } + Platform.MenuItem { + text: qsTr("Paste") + enabled: textArea.canPaste + onTriggered: textArea.paste() + } + + Platform.MenuSeparator {} + + Platform.MenuItem { + text: qsTr("Font...") + onTriggered: function () { + fontDialog.selectedFont = document.font + fontDialog.open() + } + } + + Platform.MenuItem { + text: qsTr("Color...") + onTriggered: function () { + colorDialog.selectedColor = document.textColor + colorDialog.open() + } + } + } + + onClosing: function (close) { + if (document.modified) { + quitDialog.open() + close.accepted = false + } + } +} diff --git a/examples/quickcontrols/texteditor/red.png b/examples/quickcontrols/texteditor/red.png Binary files differnew file mode 100644 index 0000000000..9038fef784 --- /dev/null +++ b/examples/quickcontrols/texteditor/red.png diff --git a/examples/quickcontrols/texteditor/texteditor.cpp b/examples/quickcontrols/texteditor/texteditor.cpp new file mode 100644 index 0000000000..79cd6d8071 --- /dev/null +++ b/examples/quickcontrols/texteditor/texteditor.cpp @@ -0,0 +1,49 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#ifdef QT_WIDGETS_LIB +#include <QApplication> +#else +#include <QGuiApplication> +#endif +#include <QFontDatabase> +#include <QDebug> +#include <QQmlApplicationEngine> +#include <QQmlContext> +#include <QQuickStyle> + +#include "documenthandler.h" + +int main(int argc, char *argv[]) +{ + QGuiApplication::setApplicationName("Text Editor"); + QGuiApplication::setOrganizationName("QtProject"); + +#ifdef QT_WIDGETS_LIB + QApplication app(argc, argv); +#else + QGuiApplication app(argc, argv); +#endif + + if (QFontDatabase::addApplicationFont(":/fonts/fontello.ttf") == -1) + qWarning() << "Failed to load fontello.ttf"; + + qmlRegisterType<DocumentHandler>("io.qt.examples.texteditor", 1, 0, "DocumentHandler"); + + QStringList selectors; +#ifdef QT_EXTRA_FILE_SELECTOR + selectors += QT_EXTRA_FILE_SELECTOR; +#else + if (app.arguments().contains("-touch")) + selectors += "touch"; +#endif + + QQmlApplicationEngine engine; + engine.setExtraFileSelectors(selectors); + + engine.load(QUrl("qrc:/qml/texteditor.qml")); + if (engine.rootObjects().isEmpty()) + return -1; + + return app.exec(); +} diff --git a/examples/quickcontrols/texteditor/texteditor.html b/examples/quickcontrols/texteditor/texteditor.html new file mode 100644 index 0000000000..3c59a053c5 --- /dev/null +++ b/examples/quickcontrols/texteditor/texteditor.html @@ -0,0 +1,43 @@ +<html> +<head> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <meta name="qrichtext" content="1"> + <title>Text Editor Example</title> + <style type="text/css"> + p, + body, <!-- specifiying font-size for body seems to be necessary to avoid bullet points being incorrectly positioned --> + li { + white-space: pre-wrap; + font-size:11pt; + } + </style> +</head> +<body> + <p align="center"> + <img src="qrc:/images/qt-logo.png" /> + </p> + <h2 align="center"> + Qt Quick Controls 2 + </h2> + <p align="center"> + This example demonstrates a modern rich text editor. The UI uses Qt Labs Platforms to provide native menus and dialogs. + </p> + <br /> + <br /> + <br /> + + <p> + Below you'll find a list of the native controls used in this application. + </p> + + <ul> + <li><a href="https://doc.qt.io/qt-6/qml-qt-labs-platform-menu.html">Menu</a> - provides a QML API for native platform menu popups.</li> + <li><a href="https://doc.qt.io/qt-6/qml-qt-labs-platform-menubar.html">MenuBar</a> - provides a QML API for native platform menubars.</li> + <li><a href="https://doc.qt.io/qt-6/qml-qt-labs-platform-menuitem.html">MenuItem</a> - provides a QML API for native platform menu items.</li> + <li><a href="https://doc.qt.io/qt-6/qml-qt-labs-platform-filedialog.html">FileDialog</a> - provides a QML API for native platform file dialogs.</li> + <li><a href="https://doc.qt.io/qt-6/qml-qt-labs-platform-fontdialog.html">FontDialog</a> - provides a QML API for native platform font dialogs.</li> + <li><a href="https://doc.qt.io/qt-6/qml-qt-labs-platform-colordialog.html">ColorDialog</a> - provides a QML API for native platform color dialogs.</li> + <li><a href="https://doc.qt.io/qt-6/qml-qt-labs-platform-messagedialog.html">MessageDialog</a> - provides a QML API for native platform message dialogs.</li> + </ul> +</body> +</html> diff --git a/examples/quickcontrols/texteditor/texteditor.pro b/examples/quickcontrols/texteditor/texteditor.pro new file mode 100644 index 0000000000..deb2457615 --- /dev/null +++ b/examples/quickcontrols/texteditor/texteditor.pro @@ -0,0 +1,22 @@ +TEMPLATE = app +TARGET = texteditor +QT += quick quickcontrols2 +qtHaveModule(widgets): QT += widgets + +cross_compile: DEFINES += QT_EXTRA_FILE_SELECTOR=\\\"touch\\\" + +HEADERS += \ + documenthandler.h + +SOURCES += \ + texteditor.cpp \ + documenthandler.cpp + +OTHER_FILES += \ + qml/*.qml + +RESOURCES += \ + texteditor.qrc + +target.path = $$[QT_INSTALL_EXAMPLES]/quickcontrols2/texteditor +INSTALLS += target diff --git a/examples/quickcontrols/texteditor/texteditor.qrc b/examples/quickcontrols/texteditor/texteditor.qrc new file mode 100644 index 0000000000..cdb7225a39 --- /dev/null +++ b/examples/quickcontrols/texteditor/texteditor.qrc @@ -0,0 +1,10 @@ +<RCC> + <qresource prefix="/"> + <file>images/qt-logo.png</file> + <file>fonts/fontello.ttf</file> + <file>qml/texteditor.qml</file> + <file>texteditor.html</file> + <file>qml/+touch/texteditor.qml</file> + <file>+touch/texteditor.html</file> + </qresource> +</RCC> diff --git a/examples/quickcontrols/wearable/CMakeLists.txt b/examples/quickcontrols/wearable/CMakeLists.txt new file mode 100644 index 0000000000..b61064d5d9 --- /dev/null +++ b/examples/quickcontrols/wearable/CMakeLists.txt @@ -0,0 +1,206 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +cmake_minimum_required(VERSION 3.16) +project(wearable LANGUAGES CXX) + +set(CMAKE_AUTOMOC ON) + +if(NOT DEFINED INSTALL_EXAMPLESDIR) + set(INSTALL_EXAMPLESDIR "examples") +endif() + +set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/quickcontrols2/wearable") + +find_package(Qt6 REQUIRED COMPONENTS Core Gui Quick QuickControls2) + +qt_add_executable(wearable + wearable.cpp +) + +set_target_properties(wearable PROPERTIES + WIN32_EXECUTABLE TRUE + MACOSX_BUNDLE TRUE +) + +target_link_libraries(wearable PUBLIC + Qt::Core + Qt::Gui + Qt::Quick + Qt::QuickControls2 +) + +if(UNIX AND NOT APPLE AND CMAKE_CROSSCOMPILING) + find_package(Qt6 REQUIRED COMPONENTS QuickTemplates2) + + # Work around QTBUG-86533 + target_link_libraries(wearable PRIVATE Qt::QuickTemplates2) +endif() + +# Resources: +set(wearable_resource_files + "icons/wearable/36x36/alarms.png" + "icons/wearable/36x36/fitness.png" + "icons/wearable/36x36/navigation.png" + "icons/wearable/36x36/notifications.png" + "icons/wearable/36x36/settings.png" + "icons/wearable/36x36/weather.png" + "icons/wearable/36x36/worldclock.png" + "icons/wearable/36x36@2/alarms.png" + "icons/wearable/36x36@2/fitness.png" + "icons/wearable/36x36@2/navigation.png" + "icons/wearable/36x36@2/notifications.png" + "icons/wearable/36x36@2/settings.png" + "icons/wearable/36x36@2/weather.png" + "icons/wearable/36x36@2/worldclock.png" + "icons/wearable/index.theme" + "images/back.png" + "images/back@2x.png" + "images/background-dark.png" + "images/background-light.png" + "images/home.png" + "images/home@2x.png" + "qml/Alarms/AlarmsPage.qml" + "qml/DemoMode.qml" + "qml/DemoModeIndicator.qml" + "qml/Fitness/FitnessPage.qml" + "qml/Fitness/fitness.js" + "qml/Fitness/images/man-running-dark.png" + "qml/Fitness/images/man-running-dark@2x.png" + "qml/Fitness/images/man-running-light.png" + "qml/Fitness/images/man-running-light@2x.png" + "qml/Fitness/images/man-walking-dark.png" + "qml/Fitness/images/man-walking-dark@2x.png" + "qml/Fitness/images/man-walking-light.png" + "qml/Fitness/images/man-walking-light@2x.png" + "qml/LauncherPage.qml" + "qml/NaviButton.qml" + "qml/Navigation/NavigationPage.qml" + "qml/Navigation/RouteElement.qml" + "qml/Navigation/images/end.png" + "qml/Navigation/images/end@2x.png" + "qml/Navigation/images/leftturn-dark.png" + "qml/Navigation/images/leftturn-dark@2x.png" + "qml/Navigation/images/leftturn-light.png" + "qml/Navigation/images/leftturn-light@2x.png" + "qml/Navigation/images/navigation-dark.png" + "qml/Navigation/images/navigation-dark@2x.png" + "qml/Navigation/images/navigation-light.png" + "qml/Navigation/images/navigation-light@2x.png" + "qml/Navigation/images/rightturn-dark.png" + "qml/Navigation/images/rightturn-dark@2x.png" + "qml/Navigation/images/rightturn-light.png" + "qml/Navigation/images/rightturn-light@2x.png" + "qml/Navigation/images/start.png" + "qml/Navigation/images/start@2x.png" + "qml/Navigation/images/straight-dark.png" + "qml/Navigation/images/straight-dark@2x.png" + "qml/Navigation/images/straight-light.png" + "qml/Navigation/images/straight-light@2x.png" + "qml/Navigation/images/uturn.png" + "qml/Navigation/images/uturn@2x.png" + "qml/Navigation/navigation.js" + "qml/Navigation/walk_route.json" + "qml/Notifications/NotificationsPage.qml" + "qml/Notifications/images/avatarf-dark.png" + "qml/Notifications/images/avatarf-dark@2x.png" + "qml/Notifications/images/avatarf-light.png" + "qml/Notifications/images/avatarf-light@2x.png" + "qml/Notifications/images/avatarm-dark.png" + "qml/Notifications/images/avatarm-dark@2x.png" + "qml/Notifications/images/avatarm-light.png" + "qml/Notifications/images/avatarm-light@2x.png" + "qml/Notifications/images/missedcall-dark.png" + "qml/Notifications/images/missedcall-dark@2x.png" + "qml/Notifications/images/missedcall-light.png" + "qml/Notifications/images/missedcall-light@2x.png" + "qml/Notifications/notifications.js" + "qml/Settings/SettingsPage.qml" + "qml/Settings/images/bluetooth-dark.png" + "qml/Settings/images/bluetooth-dark@2x.png" + "qml/Settings/images/bluetooth-light.png" + "qml/Settings/images/bluetooth-light@2x.png" + "qml/Settings/images/brightness-dark.png" + "qml/Settings/images/brightness-dark@2x.png" + "qml/Settings/images/brightness-light.png" + "qml/Settings/images/brightness-light@2x.png" + "qml/Settings/images/demo-mode-dark.png" + "qml/Settings/images/demo-mode-dark@2x.png" + "qml/Settings/images/demo-mode-light.png" + "qml/Settings/images/demo-mode-light@2x.png" + "qml/Settings/images/demo-mode-white.png" + "qml/Settings/images/demo-mode-white@2x.png" + "qml/Settings/images/theme-dark.png" + "qml/Settings/images/theme-dark@2x.png" + "qml/Settings/images/theme-light.png" + "qml/Settings/images/theme-light@2x.png" + "qml/Settings/images/wifi-dark.png" + "qml/Settings/images/wifi-dark@2x.png" + "qml/Settings/images/wifi-light.png" + "qml/Settings/images/wifi-light@2x.png" + "qml/Style/PageIndicator.qml" + "qml/Style/Slider.qml" + "qml/Style/Switch.qml" + "qml/Style/UIStyle.qml" + "qml/Style/qmldir" + "qml/SwipeViewPage.qml" + "qml/Weather/WeatherPage.qml" + "qml/Weather/images/humidity-dark.png" + "qml/Weather/images/humidity-dark@2x.png" + "qml/Weather/images/humidity-light.png" + "qml/Weather/images/humidity-light@2x.png" + "qml/Weather/images/pressure-dark.png" + "qml/Weather/images/pressure-dark@2x.png" + "qml/Weather/images/pressure-light.png" + "qml/Weather/images/pressure-light@2x.png" + "qml/Weather/images/sunrise-dark.png" + "qml/Weather/images/sunrise-dark@2x.png" + "qml/Weather/images/sunrise-light.png" + "qml/Weather/images/sunrise-light@2x.png" + "qml/Weather/images/sunset-dark.png" + "qml/Weather/images/sunset-dark@2x.png" + "qml/Weather/images/sunset-light.png" + "qml/Weather/images/sunset-light@2x.png" + "qml/Weather/images/temperature-dark.png" + "qml/Weather/images/temperature-dark@2x.png" + "qml/Weather/images/temperature-light.png" + "qml/Weather/images/temperature-light@2x.png" + "qml/Weather/images/wind-dark.png" + "qml/Weather/images/wind-dark@2x.png" + "qml/Weather/images/wind-light.png" + "qml/Weather/images/wind-light@2x.png" + "qml/Weather/weather.js" + "qml/Weather/weather.json" + "qml/WorldClock/Clock.qml" + "qml/WorldClock/WorldClockPage.qml" + "qml/WorldClock/images/center.png" + "qml/WorldClock/images/center@2x.png" + "qml/WorldClock/images/second.png" + "qml/WorldClock/images/second@2x.png" + "qml/WorldClock/images/swissdaydial.png" + "qml/WorldClock/images/swissdaydial@2x.png" + "qml/WorldClock/images/swissdayhour.png" + "qml/WorldClock/images/swissdayhour@2x.png" + "qml/WorldClock/images/swissdayminute.png" + "qml/WorldClock/images/swissdayminute@2x.png" + "qml/WorldClock/images/swissnightdial.png" + "qml/WorldClock/images/swissnightdial@2x.png" + "qml/WorldClock/images/swissnighthour.png" + "qml/WorldClock/images/swissnighthour@2x.png" + "qml/WorldClock/images/swissnightminute.png" + "qml/WorldClock/images/swissnightminute@2x.png" + "wearable.qml" +) + +qt6_add_resources(wearable "wearable" + PREFIX + "/" + FILES + ${wearable_resource_files} +) + +install(TARGETS wearable + RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" + LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" +) diff --git a/examples/quickcontrols/wearable/doc/images/qtquickcontrols2-wearable.png b/examples/quickcontrols/wearable/doc/images/qtquickcontrols2-wearable.png Binary files differnew file mode 100644 index 0000000000..c61055340c --- /dev/null +++ b/examples/quickcontrols/wearable/doc/images/qtquickcontrols2-wearable.png diff --git a/examples/quickcontrols/wearable/doc/src/qtquickcontrols2-wearable.qdoc b/examples/quickcontrols/wearable/doc/src/qtquickcontrols2-wearable.qdoc new file mode 100644 index 0000000000..8a1e021663 --- /dev/null +++ b/examples/quickcontrols/wearable/doc/src/qtquickcontrols2-wearable.qdoc @@ -0,0 +1,167 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only + +/*! + \example wearable + \keyword Qt Quick Controls - Wearable Demo + \title Qt Quick Controls - Wearable Demo + \keyword Qt Quick Controls 2 - Wearable Demo + \ingroup qtquickcontrols2-examples + \brief Demonstrates an application launcher designed for wearable devices. + + \image qtquickcontrols2-wearable.png + + The \e {Wearable Demo} consists of an application launcher and a collection + of small and simple example applications aimed at wearable devices. + + \section1 Structure + + The main .qml file, \c wearable.qml, consists of an ApplicationWindow, a StackView + for a stack-based navigation model, and buttons for interactive navigation. + + \quotefromfile wearable/wearable.qml + \skipuntil import "qml/Style" + \printuntil id: window + \dots + \skipto header + \printuntil id: homeButton + \dots 8 + \skipto onClicked + \printuntil } + \printuntil id: backButton + \dots 8 + \skipto onClicked + \printuntil id: stackView + \dots 8 + \skipuntil initialItem + \printuntil /^\}/ + + \section1 Styling + + The demo uses a custom \l {Styling Qt Quick Controls}{Qt Quick Controls 2 style} + embedded into the demo's resources. The custom style is implemented for a + few controls only, as it is specific to this particular demo. It uses a + singleton type for various styling attributes, such as fonts and colors. + + \list + \li \c qml/Style/PageIndicator.qml + \li \c qml/Style/Slider.qml + \li \c qml/Style/Switch.qml + \li \c qml/Style/UIStyle.qml + \endlist + + The style is applied in \c main() in \c wearable.cpp: + + \snippet wearable/wearable.cpp style + + The main benefit of using the built-in styling system is that the style selection + is fully transparent to the application code. There is no need to import a specific + folder that contains the styled controls. This way, the application can be run with + other styles too. + + \section1 Custom Type + + The demo application contains a custom button type implemented in + \c qml/NaviButton.qml. The navigation button is used as a home and back + button in \c wearable.qml. \c NaviButton extends the AbstractButton type + with properties that control the slide in and slide out transitions and + the button image. + + \quotefromfile wearable/qml/NaviButton.qml + \skipuntil import "Style" + \printuntil id: image + \dots 8 + \skipuntil } + \printuntil background: + \dots 8 + \skipto } + \printuntil /^\}/ + + \section1 Icons + + The demo ships a custom icon theme. The icons are bundled into the \c :/icons + folder in the application's resources. The \c index.theme file lists the contents + of the icon theme: + + \quotefile wearable/icons/wearable/index.theme + + Finally, the icon theme is selected in \c main(): + + \snippet wearable/wearable.cpp icons + + The icons are used on the Launcher Page, which is presented below. See + \l {Icons in Qt Quick Controls} for more details about icons and themes. + + \section1 Launcher Page + + The application launcher is implemented using a circular PathView in + \c LauncherPage.qml. Each application is in a separate .qml file, + which is added to the ListModel on the launcher page. + + \quotefromfile wearable/qml/LauncherPage.qml + \skipto PathView + \printuntil signal launched + \dots + \skipto ListModel + \printuntil } + \dots 8 + \printline ListElement + \skipto "Settings" + \printuntil delegate: + \dots 8 + \skipto icon.width + \printuntil icon.name + \dots 8 + \skipto onClicked: + \printto path: + \dots + \skipto /^\}/ + \printline } + + \section1 Applications + + The applications are designed for touch input based on what input methods + or communication means are typically offered by wearable devices. + + Most applications have their own JavaScript files that act as dummy + application backends. They illustrate fetching external data and help + manipulating or converting the data. In the \c Navigation and \c Weather + applications, data acquisition is implemented using \l XMLHttpRequest to + read from local files. These files were generated by storing responses from + remote servers in JSON format. This code can be easily modified to acquire + data from remote servers. + + \section2 Navigation + + This application displays a walking route from source to destination. This + route information is obtained using the REST API provided by + \l {https://www.openstreetmap.org/}. The API response is in JSON format, which + is parsed using JavaScript by the application. Currently, it is not possible + to specify the source and destination from within the application, but it can + be added based on the device's capabilities. For example, user input + could be implemented as screens with input fields, or can be communicated + over Bluetooth/Wifi from a paired application running on another device + such as a smart phone or PC. + + \section2 Weather + + This application displays weather information such as temperature, sunrise + and sunset times, air pressure, and so on. This information is obtained + from \l {https://openweathermap.org/} using its REST API. The API response is + in JSON format, which is parsed using JavaScript by the application. This + application can also be modified by adding screens to obtain weather data for + a given location. + + \section2 World Clock + + This application displays a world clock for different cities. As of now, the + list of cities is hard-coded in the application, but that can be changed based + on the input capabilities of the device. + + \section2 Others + + The remaining applications return static data for now, but they can be + modified to process response data obtained from respective services. + + \include examples-run.qdocinc +*/ diff --git a/examples/quickcontrols/wearable/icons/wearable/36x36/alarms.png b/examples/quickcontrols/wearable/icons/wearable/36x36/alarms.png Binary files differnew file mode 100644 index 0000000000..252dcf938f --- /dev/null +++ b/examples/quickcontrols/wearable/icons/wearable/36x36/alarms.png diff --git a/examples/quickcontrols/wearable/icons/wearable/36x36/fitness.png b/examples/quickcontrols/wearable/icons/wearable/36x36/fitness.png Binary files differnew file mode 100644 index 0000000000..4b0679e271 --- /dev/null +++ b/examples/quickcontrols/wearable/icons/wearable/36x36/fitness.png diff --git a/examples/quickcontrols/wearable/icons/wearable/36x36/navigation.png b/examples/quickcontrols/wearable/icons/wearable/36x36/navigation.png Binary files differnew file mode 100644 index 0000000000..08e73005fd --- /dev/null +++ b/examples/quickcontrols/wearable/icons/wearable/36x36/navigation.png diff --git a/examples/quickcontrols/wearable/icons/wearable/36x36/notifications.png b/examples/quickcontrols/wearable/icons/wearable/36x36/notifications.png Binary files differnew file mode 100644 index 0000000000..6309312122 --- /dev/null +++ b/examples/quickcontrols/wearable/icons/wearable/36x36/notifications.png diff --git a/examples/quickcontrols/wearable/icons/wearable/36x36/settings.png b/examples/quickcontrols/wearable/icons/wearable/36x36/settings.png Binary files differnew file mode 100644 index 0000000000..c1552fb360 --- /dev/null +++ b/examples/quickcontrols/wearable/icons/wearable/36x36/settings.png diff --git a/examples/quickcontrols/wearable/icons/wearable/36x36/weather.png b/examples/quickcontrols/wearable/icons/wearable/36x36/weather.png Binary files differnew file mode 100644 index 0000000000..61be79a24f --- /dev/null +++ b/examples/quickcontrols/wearable/icons/wearable/36x36/weather.png diff --git a/examples/quickcontrols/wearable/icons/wearable/36x36/worldclock.png b/examples/quickcontrols/wearable/icons/wearable/36x36/worldclock.png Binary files differnew file mode 100644 index 0000000000..d23e32e512 --- /dev/null +++ b/examples/quickcontrols/wearable/icons/wearable/36x36/worldclock.png diff --git a/examples/quickcontrols/wearable/icons/wearable/36x36@2/alarms.png b/examples/quickcontrols/wearable/icons/wearable/36x36@2/alarms.png Binary files differnew file mode 100644 index 0000000000..6047e231fc --- /dev/null +++ b/examples/quickcontrols/wearable/icons/wearable/36x36@2/alarms.png diff --git a/examples/quickcontrols/wearable/icons/wearable/36x36@2/fitness.png b/examples/quickcontrols/wearable/icons/wearable/36x36@2/fitness.png Binary files differnew file mode 100644 index 0000000000..1d2caa3385 --- /dev/null +++ b/examples/quickcontrols/wearable/icons/wearable/36x36@2/fitness.png diff --git a/examples/quickcontrols/wearable/icons/wearable/36x36@2/navigation.png b/examples/quickcontrols/wearable/icons/wearable/36x36@2/navigation.png Binary files differnew file mode 100644 index 0000000000..7d4a62b9e1 --- /dev/null +++ b/examples/quickcontrols/wearable/icons/wearable/36x36@2/navigation.png diff --git a/examples/quickcontrols/wearable/icons/wearable/36x36@2/notifications.png b/examples/quickcontrols/wearable/icons/wearable/36x36@2/notifications.png Binary files differnew file mode 100644 index 0000000000..8d3b333350 --- /dev/null +++ b/examples/quickcontrols/wearable/icons/wearable/36x36@2/notifications.png diff --git a/examples/quickcontrols/wearable/icons/wearable/36x36@2/settings.png b/examples/quickcontrols/wearable/icons/wearable/36x36@2/settings.png Binary files differnew file mode 100644 index 0000000000..e89188743d --- /dev/null +++ b/examples/quickcontrols/wearable/icons/wearable/36x36@2/settings.png diff --git a/examples/quickcontrols/wearable/icons/wearable/36x36@2/weather.png b/examples/quickcontrols/wearable/icons/wearable/36x36@2/weather.png Binary files differnew file mode 100644 index 0000000000..0a2ae7d54e --- /dev/null +++ b/examples/quickcontrols/wearable/icons/wearable/36x36@2/weather.png diff --git a/examples/quickcontrols/wearable/icons/wearable/36x36@2/worldclock.png b/examples/quickcontrols/wearable/icons/wearable/36x36@2/worldclock.png Binary files differnew file mode 100644 index 0000000000..ca6eb879e1 --- /dev/null +++ b/examples/quickcontrols/wearable/icons/wearable/36x36@2/worldclock.png diff --git a/examples/quickcontrols/wearable/icons/wearable/index.theme b/examples/quickcontrols/wearable/icons/wearable/index.theme new file mode 100644 index 0000000000..da702d4a92 --- /dev/null +++ b/examples/quickcontrols/wearable/icons/wearable/index.theme @@ -0,0 +1,14 @@ +[Icon Theme] +Name=Wearable +Comment=Qt Quick Controls 2 Wearable Demo Icon Theme + +Directories=36x36,36x36@2 + +[36x36] +Size=36 +Type=Fixed + +[36x36@2] +Size=36 +Scale=2 +Type=Fixed diff --git a/examples/quickcontrols/wearable/images/back.png b/examples/quickcontrols/wearable/images/back.png Binary files differnew file mode 100644 index 0000000000..cf80aa65f5 --- /dev/null +++ b/examples/quickcontrols/wearable/images/back.png diff --git a/examples/quickcontrols/wearable/images/back@2x.png b/examples/quickcontrols/wearable/images/back@2x.png Binary files differnew file mode 100644 index 0000000000..02f27981e0 --- /dev/null +++ b/examples/quickcontrols/wearable/images/back@2x.png diff --git a/examples/quickcontrols/wearable/images/back@3x.png b/examples/quickcontrols/wearable/images/back@3x.png Binary files differnew file mode 100644 index 0000000000..6d2d6cf120 --- /dev/null +++ b/examples/quickcontrols/wearable/images/back@3x.png diff --git a/examples/quickcontrols/wearable/images/back@4x.png b/examples/quickcontrols/wearable/images/back@4x.png Binary files differnew file mode 100644 index 0000000000..03193681b1 --- /dev/null +++ b/examples/quickcontrols/wearable/images/back@4x.png diff --git a/examples/quickcontrols/wearable/images/background-dark.png b/examples/quickcontrols/wearable/images/background-dark.png Binary files differnew file mode 100644 index 0000000000..6a8c0761aa --- /dev/null +++ b/examples/quickcontrols/wearable/images/background-dark.png diff --git a/examples/quickcontrols/wearable/images/background-light.png b/examples/quickcontrols/wearable/images/background-light.png Binary files differnew file mode 100644 index 0000000000..913befab82 --- /dev/null +++ b/examples/quickcontrols/wearable/images/background-light.png diff --git a/examples/quickcontrols/wearable/images/home.png b/examples/quickcontrols/wearable/images/home.png Binary files differnew file mode 100644 index 0000000000..b6ee1459f7 --- /dev/null +++ b/examples/quickcontrols/wearable/images/home.png diff --git a/examples/quickcontrols/wearable/images/home@2x.png b/examples/quickcontrols/wearable/images/home@2x.png Binary files differnew file mode 100644 index 0000000000..d5595b2378 --- /dev/null +++ b/examples/quickcontrols/wearable/images/home@2x.png diff --git a/examples/quickcontrols/wearable/images/home@3x.png b/examples/quickcontrols/wearable/images/home@3x.png Binary files differnew file mode 100644 index 0000000000..9a5188d22b --- /dev/null +++ b/examples/quickcontrols/wearable/images/home@3x.png diff --git a/examples/quickcontrols/wearable/images/home@4x.png b/examples/quickcontrols/wearable/images/home@4x.png Binary files differnew file mode 100644 index 0000000000..c4d2eb515a --- /dev/null +++ b/examples/quickcontrols/wearable/images/home@4x.png diff --git a/examples/quickcontrols/wearable/qml/Alarms/AlarmsPage.qml b/examples/quickcontrols/wearable/qml/Alarms/AlarmsPage.qml new file mode 100644 index 0000000000..65b34b83cb --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Alarms/AlarmsPage.qml @@ -0,0 +1,67 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Controls as QQC2 +import ".." +import "../Style" + +Item { + QQC2.SwipeView { + id: svAlarmsContainer + + anchors.fill: parent + + Repeater { + model: ListModel { + ListElement { name: qsTr("Week Days"); state: true; time: "06:00 AM" } + ListElement { name: qsTr("Week Ends"); state: false; time: "07:30 AM" } + } + + SwipeViewPage { + property alias stateSwitch: stateSwitch + + Column { + spacing: 30 + anchors.centerIn: parent + + QQC2.Switch { + id: stateSwitch + checked: model.state + anchors.left: nameLabel.right + } + + Text { + text: model.time + anchors.horizontalCenter: parent.horizontalCenter + verticalAlignment: Text.AlignVCenter + height: UIStyle.fontSizeXL + font.bold: stateSwitch.checked + font.pixelSize: stateSwitch.checked ? UIStyle.fontSizeXL : UIStyle.fontSizeL + font.letterSpacing: 4 + color: UIStyle.themeColorQtGray1 + } + + Text { + id: nameLabel + text: model.name + anchors.horizontalCenter: parent.horizontalCenter + font.pixelSize: UIStyle.fontSizeS + font.italic: true + font.bold: true + font.letterSpacing: 1 + color: UIStyle.themeColorQtGray2 + } + } + } + } + } + + QQC2.PageIndicator { + count: svAlarmsContainer.count + currentIndex: svAlarmsContainer.currentIndex + + anchors.bottom: svAlarmsContainer.bottom + anchors.horizontalCenter: parent.horizontalCenter + } +} diff --git a/examples/quickcontrols/wearable/qml/DemoMode.qml b/examples/quickcontrols/wearable/qml/DemoMode.qml new file mode 100644 index 0000000000..d7d4b6e61f --- /dev/null +++ b/examples/quickcontrols/wearable/qml/DemoMode.qml @@ -0,0 +1,211 @@ +// Copyright (C) 2018 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Controls + +import "Style" + +Item { + property StackView stackView + + SequentialAnimation { + id: demoModeAnimation + running: settings.demoMode + + // Set brightness back to normal. + ScriptAction { script: settings.brightness = 0 } + + // Go back to the launcher page. + PauseAnimation { duration: 1000 } + ScriptAction { script: stackView.pop(null) } + PauseAnimation { duration: 2000 } + + // Open the world clock page. + ScriptAction { script: stackView.currentItem.launched(Qt.resolvedUrl("WorldClock/WorldClockPage.qml")) } + PauseAnimation { duration: 2000 } + + // Swipe across a few times. + SequentialAnimation { + loops: 6 + + ScriptAction { script: stackView.currentItem.children[0].incrementCurrentIndex() } + PauseAnimation { duration: 2500 } + } + + + // Go back to the launcher page. + ScriptAction { script: stackView.pop(null) } + PauseAnimation { duration: 2000 } + + // Open the navigation page. + ScriptAction { script: stackView.currentItem.incrementCurrentIndex() } + PauseAnimation { duration: 1000 } + ScriptAction { script: stackView.currentItem.launched(Qt.resolvedUrl("Navigation/NavigationPage.qml")) } + PauseAnimation { duration: 2000 } + + // Flick down a few times. + SequentialAnimation { + loops: 6 + + ScriptAction { script: stackView.currentItem.routeListView.incrementCurrentIndex() } + PauseAnimation { duration: 2000 } + } + + + // Go back to the launcher page. + ScriptAction { script: stackView.pop(null) } + PauseAnimation { duration: 2000 } + + // Open the weather page. + ScriptAction { script: stackView.currentItem.incrementCurrentIndex() } + PauseAnimation { duration: 1000 } + ScriptAction { script: stackView.currentItem.launched(Qt.resolvedUrl("Weather/WeatherPage.qml")) } + PauseAnimation { duration: 2000 } + + // Swipe across a few times. + SequentialAnimation { + loops: 4 + + ScriptAction { script: stackView.currentItem.children[0].incrementCurrentIndex() } + PauseAnimation { duration: 2000 } + } + + + // Go back to the launcher page. + ScriptAction { script: stackView.pop(null) } + PauseAnimation { duration: 2000 } + + // Open the fitness page. + ScriptAction { script: stackView.currentItem.incrementCurrentIndex() } + PauseAnimation { duration: 1000 } + ScriptAction { script: stackView.currentItem.launched(Qt.resolvedUrl("Fitness/FitnessPage.qml")) } + PauseAnimation { duration: 2000 } + + // Swipe across a few times. + SequentialAnimation { + loops: 2 + + ScriptAction { script: stackView.currentItem.children[0].incrementCurrentIndex() } + PauseAnimation { duration: 2000 } + } + + + // Go back to the launcher page. + ScriptAction { script: stackView.pop(null) } + PauseAnimation { duration: 2000 } + + // Open the notifications page. + ScriptAction { script: stackView.currentItem.incrementCurrentIndex() } + PauseAnimation { duration: 1000 } + ScriptAction { script: stackView.currentItem.launched(Qt.resolvedUrl("Notifications/NotificationsPage.qml")) } + + // Flick down a few times. + SequentialAnimation { + loops: 3 + + PauseAnimation { duration: 2000 } + ScriptAction { script: stackView.currentItem.incrementCurrentIndex() } + } + + + // Go back to the launcher page. + ScriptAction { script: stackView.pop(null) } + PauseAnimation { duration: 2000 } + + // Open the alarms page. + ScriptAction { script: stackView.currentItem.incrementCurrentIndex() } + PauseAnimation { duration: 1000 } + ScriptAction { script: stackView.currentItem.launched(Qt.resolvedUrl("Alarms/AlarmsPage.qml")) } + PauseAnimation { duration: 2000 } + + // Toggle the switch. + ScriptAction { script: stackView.currentItem.children[0].currentItem.stateSwitch.toggle() } + PauseAnimation { duration: 2000 } + + // Go to the next alarm. + ScriptAction { script: stackView.currentItem.children[0].incrementCurrentIndex() } + PauseAnimation { duration: 2000 } + + // Toggle the switch there too. + ScriptAction { script: stackView.currentItem.children[0].currentItem.stateSwitch.toggle() } + PauseAnimation { duration: 2000 } + + + // Go back to the launcher page. + ScriptAction { script: stackView.pop(null) } + PauseAnimation { duration: 2000 } + + // Open the settings page. + ScriptAction { script: stackView.currentItem.incrementCurrentIndex() } + PauseAnimation { duration: 1000 } + ScriptAction { script: stackView.currentItem.launched(Qt.resolvedUrl("Settings/SettingsPage.qml")) } + PauseAnimation { duration: 3000 } + + // Toggle the switches. + ScriptAction { script: stackView.currentItem.children[0].currentItem.bluetoothSwitch.toggle() } + PauseAnimation { duration: 1000 } + ScriptAction { script: stackView.currentItem.children[0].currentItem.wirelessSwitch.toggle() } + PauseAnimation { duration: 3000 } + + // Go to the next page. + ScriptAction { script: stackView.currentItem.children[0].incrementCurrentIndex() } + + // Play with the brightness slider. + // First, set it to full brightness so we start in the correct state. + ScriptAction { + script: { + var brightnessSlider = stackView.currentItem.children[0].currentItem.brightnessSlider + brightnessSlider.value = 0 + // increase()/decrease() are not a result of user interaction and + // hence moved() will not be emitted, so we do it ourselves. + brightnessSlider.moved() + } + } + + // Decrease the brightness. + SequentialAnimation { + loops: 3 + + PauseAnimation { duration: 1000 } + ScriptAction { + script: { + var brightnessSlider = stackView.currentItem.children[0].currentItem.brightnessSlider + brightnessSlider.decrease() + brightnessSlider.moved() + } + } + } + + // Increase the brightness back to full. + PauseAnimation { duration: 3000 } + SequentialAnimation { + loops: 3 + + PauseAnimation { duration: 1000 } + ScriptAction { + script: { + var brightnessSlider = stackView.currentItem.children[0].currentItem.brightnessSlider + brightnessSlider.increase() + brightnessSlider.moved() + } + } + } + + // Toggle the dark theme switch. + PauseAnimation { duration: 2000 } + ScriptAction { + script: { + var darkThemeSwitch = stackView.currentItem.children[0].currentItem.darkThemeSwitch + darkThemeSwitch.toggle() + // As above, only proper user interaction results in toggled() being emitted, + // so we do it ourselves. + darkThemeSwitch.toggled() + } + } + PauseAnimation { duration: 4000 } + + // Go back to the launcher page. + ScriptAction { script: stackView.pop(null) } + } +} diff --git a/examples/quickcontrols/wearable/qml/DemoModeIndicator.qml b/examples/quickcontrols/wearable/qml/DemoModeIndicator.qml new file mode 100644 index 0000000000..977c600653 --- /dev/null +++ b/examples/quickcontrols/wearable/qml/DemoModeIndicator.qml @@ -0,0 +1,47 @@ +// Copyright (C) 2018 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Controls as QQC2 +import "Style" + +Item { + id: root + width: row.implicitWidth + margins * 2 + + readonly property int topMargin: 24 + readonly property int margins: 12 + + Behavior on y { + NumberAnimation {} + } + + Rectangle { + id: demoModeIndicatorBg + anchors.fill: parent + anchors.topMargin: -topMargin + radius: 20 + color: UIStyle.colorRed + } + + Row { + id: row + spacing: 8 + anchors.fill: parent + anchors.leftMargin: margins + anchors.rightMargin: margins + + Image { + source: "Settings/images/demo-mode-white.png" + width: height + height: instructionLabel.height * 2 + anchors.verticalCenter: parent.verticalCenter + } + QQC2.Label { + id: instructionLabel + text: "Tap screen to use" + color: UIStyle.colorQtGray10 + anchors.verticalCenter: parent.verticalCenter + } + } +} diff --git a/examples/quickcontrols/wearable/qml/Fitness/FitnessPage.qml b/examples/quickcontrols/wearable/qml/Fitness/FitnessPage.qml new file mode 100644 index 0000000000..c1047de9aa --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Fitness/FitnessPage.qml @@ -0,0 +1,84 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Controls as QQC2 +import ".." +import "../Style" +import "fitness.js" as FitnessData + +Item { + QQC2.SwipeView { + id: svFitnessContainer + + anchors.fill: parent + + SwipeViewPage { + id: fitnessPage1 + + Column { + anchors.centerIn: parent + spacing: 15 + + Text { + anchors.horizontalCenter: parent.horizontalCenter + text: qsTr("Steps: ") + FitnessData.getSteps() + font.italic: true + font.pixelSize: UIStyle.fontSizeM + color: UIStyle.themeColorQtGray1 + } + Image { + anchors.horizontalCenter: parent.horizontalCenter + source: UIStyle.themeImagePath("images/man-walking") + } + Text { + anchors.horizontalCenter: parent.horizontalCenter + text: qsTr("Calories: ") + FitnessData.getCalories() + font.pixelSize: UIStyle.fontSizeS + font.italic: true + color: UIStyle.themeColorQtGray3 + } + } + } + + SwipeViewPage { + id: fitnessPage2 + + Column { + anchors.centerIn: parent + spacing: 15 + + Text { + anchors.horizontalCenter: parent.horizontalCenter + text: qsTr("Distance: ") + + FitnessData.getDistance() + + qsTr(" miles") + font.italic: true + font.pixelSize: UIStyle.fontSizeM + color: UIStyle.themeColorQtGray1 + } + Image { + anchors.horizontalCenter: parent.horizontalCenter + source: UIStyle.themeImagePath("images/man-running") + } + Text { + anchors.horizontalCenter: parent.horizontalCenter + text: qsTr("Time: ") + + FitnessData.getTime() + + qsTr(" mins") + font.pixelSize: UIStyle.fontSizeS + font.italic: true + color: UIStyle.themeColorQtGray3 + } + } + } + } + + QQC2.PageIndicator { + count: svFitnessContainer.count + currentIndex: svFitnessContainer.currentIndex + + anchors.bottom: svFitnessContainer.bottom + anchors.horizontalCenter: parent.horizontalCenter + } +} diff --git a/examples/quickcontrols/wearable/qml/Fitness/fitness.js b/examples/quickcontrols/wearable/qml/Fitness/fitness.js new file mode 100644 index 0000000000..95ce06cdc1 --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Fitness/fitness.js @@ -0,0 +1,18 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +function getSteps() { + return 105; +} + +function getCalories() { + return 150; +} + +function getDistance() { + return 10; +} + +function getTime() { + return "00:30"; +} diff --git a/examples/quickcontrols/wearable/qml/Fitness/images/man-running-dark.png b/examples/quickcontrols/wearable/qml/Fitness/images/man-running-dark.png Binary files differnew file mode 100644 index 0000000000..6c791d6170 --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Fitness/images/man-running-dark.png diff --git a/examples/quickcontrols/wearable/qml/Fitness/images/man-running-dark@2x.png b/examples/quickcontrols/wearable/qml/Fitness/images/man-running-dark@2x.png Binary files differnew file mode 100644 index 0000000000..e9abae9de4 --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Fitness/images/man-running-dark@2x.png diff --git a/examples/quickcontrols/wearable/qml/Fitness/images/man-running-light.png b/examples/quickcontrols/wearable/qml/Fitness/images/man-running-light.png Binary files differnew file mode 100644 index 0000000000..e7eef12cb3 --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Fitness/images/man-running-light.png diff --git a/examples/quickcontrols/wearable/qml/Fitness/images/man-running-light@2x.png b/examples/quickcontrols/wearable/qml/Fitness/images/man-running-light@2x.png Binary files differnew file mode 100644 index 0000000000..79861f5718 --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Fitness/images/man-running-light@2x.png diff --git a/examples/quickcontrols/wearable/qml/Fitness/images/man-walking-dark.png b/examples/quickcontrols/wearable/qml/Fitness/images/man-walking-dark.png Binary files differnew file mode 100644 index 0000000000..6d455b4925 --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Fitness/images/man-walking-dark.png diff --git a/examples/quickcontrols/wearable/qml/Fitness/images/man-walking-dark@2x.png b/examples/quickcontrols/wearable/qml/Fitness/images/man-walking-dark@2x.png Binary files differnew file mode 100644 index 0000000000..a3ac08baf3 --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Fitness/images/man-walking-dark@2x.png diff --git a/examples/quickcontrols/wearable/qml/Fitness/images/man-walking-light.png b/examples/quickcontrols/wearable/qml/Fitness/images/man-walking-light.png Binary files differnew file mode 100644 index 0000000000..f963f8897b --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Fitness/images/man-walking-light.png diff --git a/examples/quickcontrols/wearable/qml/Fitness/images/man-walking-light@2x.png b/examples/quickcontrols/wearable/qml/Fitness/images/man-walking-light@2x.png Binary files differnew file mode 100644 index 0000000000..1b4d7592d6 --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Fitness/images/man-walking-light@2x.png diff --git a/examples/quickcontrols/wearable/qml/LauncherPage.qml b/examples/quickcontrols/wearable/qml/LauncherPage.qml new file mode 100644 index 0000000000..4017a81c57 --- /dev/null +++ b/examples/quickcontrols/wearable/qml/LauncherPage.qml @@ -0,0 +1,142 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Controls as QQC2 +import "Style" + +PathView { + id: circularView + + signal launched(string page) + + readonly property int cX: width / 2 + readonly property int cY: height / 2 + readonly property int itemSize: size / 4 + readonly property int size: Math.min(width - 80, height) + readonly property int radius: size / 2 - itemSize / 3 + + snapMode: PathView.SnapToItem + + model: ListModel { + ListElement { + title: qsTr("World Clock") + icon: "worldclock" + page: "WorldClock/WorldClockPage.qml" + } + ListElement { + title: qsTr("Navigation") + icon: "navigation" + page: "Navigation/NavigationPage.qml" + } + ListElement { + title: qsTr("Weather") + icon: "weather" + page: "Weather/WeatherPage.qml" + } + ListElement { + title: qsTr("Fitness") + icon: "fitness" + page: "Fitness/FitnessPage.qml" + } + ListElement { + title: qsTr("Notifications") + icon: "notifications" + page: "Notifications/NotificationsPage.qml" + } + ListElement { + title: qsTr("Alarm") + icon: "alarms" + page: "Alarms/AlarmsPage.qml" + } + ListElement { + title: qsTr("Settings") + icon: "settings" + page: "Settings/SettingsPage.qml" + } + } + + delegate: QQC2.RoundButton { + width: circularView.itemSize + height: circularView.itemSize + + property string title: model.title + + icon.width: 36 + icon.height: 36 + icon.name: model.icon + opacity: PathView.itemOpacity + padding: 12 + + background: Rectangle { + radius: width / 2 + border.width: 3 + border.color: parent.PathView.isCurrentItem ? UIStyle.colorQtPrimGreen : UIStyle.themeColorQtGray4 + } + + onClicked: { + if (PathView.isCurrentItem) + circularView.launched(Qt.resolvedUrl(page)) + else + circularView.currentIndex = index + } + } + + path: Path { + startX: circularView.cX + startY: circularView.cY + PathAttribute { + name: "itemOpacity" + value: 1.0 + } + PathLine { + x: circularView.cX + circularView.radius + y: circularView.cY + } + PathAttribute { + name: "itemOpacity" + value: 0.7 + } + PathArc { + x: circularView.cX - circularView.radius + y: circularView.cY + radiusX: circularView.radius + radiusY: circularView.radius + useLargeArc: true + direction: PathArc.Clockwise + } + PathAttribute { + name: "itemOpacity" + value: 0.5 + } + PathArc { + x: circularView.cX + circularView.radius + y: circularView.cY + radiusX: circularView.radius + radiusY: circularView.radius + useLargeArc: true + direction: PathArc.Clockwise + } + PathAttribute { + name: "itemOpacity" + value: 0.3 + } + } + + Text { + id: appTitle + + property Item currentItem: circularView.currentItem + + visible: currentItem ? currentItem.PathView.itemOpacity === 1.0 : 0 + + text: currentItem ? currentItem.title : "" + anchors.centerIn: parent + anchors.verticalCenterOffset: (circularView.itemSize + height) / 2 + + font.bold: true + font.pixelSize: circularView.itemSize / 3 + font.letterSpacing: 1 + color: UIStyle.themeColorQtGray1 + } +} diff --git a/examples/quickcontrols/wearable/qml/NaviButton.qml b/examples/quickcontrols/wearable/qml/NaviButton.qml new file mode 100644 index 0000000000..3c1c30fb7f --- /dev/null +++ b/examples/quickcontrols/wearable/qml/NaviButton.qml @@ -0,0 +1,36 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Controls as QQC2 +import "Style" + +QQC2.AbstractButton { + id: button + + property int edge: Qt.TopEdge + property alias imageSource: image.source + + contentItem: Image { + id: image + fillMode: Image.Pad + sourceSize { width: 40; height: 40 } // ### TODO: resize the image + } + + background: Rectangle { + height: button.height * 4 + width: height + radius: width / 2 + + anchors.horizontalCenter: button.horizontalCenter + anchors.top: edge === Qt.BottomEdge ? button.top : undefined + anchors.bottom: edge === Qt.TopEdge ? button.bottom : undefined + + color: UIStyle.colorQtGray2 + } + + transform: Translate { + Behavior on y { NumberAnimation { } } + y: enabled ? 0 : edge === Qt.TopEdge ? -button.height : button.height + } +} diff --git a/examples/quickcontrols/wearable/qml/Navigation/NavigationPage.qml b/examples/quickcontrols/wearable/qml/Navigation/NavigationPage.qml new file mode 100644 index 0000000000..f9fdd61b47 --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Navigation/NavigationPage.qml @@ -0,0 +1,73 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import "../Style" +import "navigation.js" as NavigationData + +Item { + property alias routeListView: routeView + + Column { + anchors.fill: parent + anchors.margins: 2 + spacing: 2 + + Rectangle { + anchors.horizontalCenter: parent.horizontalCenter + width: parent.width + height: titleRow.height + + color: UIStyle.themeColorQtGray9 + + Row { + id: titleRow + spacing: 10 + anchors.centerIn: parent + + Image { + anchors.verticalCenter: parent.verticalCenter + source: UIStyle.themeImagePath("images/navigation") + fillMode: Image.PreserveAspectCrop + } + Text { + anchors.verticalCenter: parent.verticalCenter + text: qsTr("Walking") + font.pixelSize: UIStyle.fontSizeM + font.letterSpacing: 2 + color: UIStyle.themeColorQtGray2 + } + } + } + + ListModel { + id: routeModel + } + + ListView { + id: routeView + + width: parent.width + height: parent.height - titleRow.height - parent.spacing + property var imageList: [UIStyle.themeImagePath("images/straight"), + UIStyle.themeImagePath("images/leftturn"), + UIStyle.themeImagePath("images/rightturn"), + "images/uturn.png", + "images/start.png", + "images/end.png"] + + clip: true + focus: true + boundsBehavior: Flickable.StopAtBounds + snapMode: ListView.SnapToItem + model: routeModel + delegate: RouteElement { + width: routeView.width + height: routeView.height + } + } + } + Component.onCompleted: { + NavigationData.requestNavigationRoute(routeModel) + } +} diff --git a/examples/quickcontrols/wearable/qml/Navigation/RouteElement.qml b/examples/quickcontrols/wearable/qml/Navigation/RouteElement.qml new file mode 100644 index 0000000000..dd4aebbb2f --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Navigation/RouteElement.qml @@ -0,0 +1,48 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import "../Style" + +Rectangle { + color: UIStyle.themeColorQtGray8 + + Row { + spacing: 5 + width: parent.width - 80 + anchors.centerIn: parent + + Image { + id: img + anchors.verticalCenter: parent.verticalCenter + source: navImage + fillMode: Image.PreserveAspectFit + } + + Column { + spacing: 5 + width: parent.width - img.width + anchors.verticalCenter: parent.verticalCenter + + Text { + width: parent.width + wrapMode: Text.WordWrap + text: navInstruction + font.pixelSize: UIStyle.fontSizeS + verticalAlignment: Text.AlignVCenter + padding: 1 + color: UIStyle.themeColorQtGray1 + } + + Text { + width: parent.width + wrapMode: Text.WordWrap + text: navAuxInfo + font.pixelSize: UIStyle.fontSizeXS + verticalAlignment: Text.AlignVCenter + padding: 1 + color: UIStyle.themeColorQtGray2 + } + } + } +} diff --git a/examples/quickcontrols/wearable/qml/Navigation/images/end.png b/examples/quickcontrols/wearable/qml/Navigation/images/end.png Binary files differnew file mode 100644 index 0000000000..4805ad8207 --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Navigation/images/end.png diff --git a/examples/quickcontrols/wearable/qml/Navigation/images/end@2x.png b/examples/quickcontrols/wearable/qml/Navigation/images/end@2x.png Binary files differnew file mode 100644 index 0000000000..e91d537465 --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Navigation/images/end@2x.png diff --git a/examples/quickcontrols/wearable/qml/Navigation/images/leftturn-dark.png b/examples/quickcontrols/wearable/qml/Navigation/images/leftturn-dark.png Binary files differnew file mode 100644 index 0000000000..66d258f5ac --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Navigation/images/leftturn-dark.png diff --git a/examples/quickcontrols/wearable/qml/Navigation/images/leftturn-dark@2x.png b/examples/quickcontrols/wearable/qml/Navigation/images/leftturn-dark@2x.png Binary files differnew file mode 100644 index 0000000000..639deb81cf --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Navigation/images/leftturn-dark@2x.png diff --git a/examples/quickcontrols/wearable/qml/Navigation/images/leftturn-light.png b/examples/quickcontrols/wearable/qml/Navigation/images/leftturn-light.png Binary files differnew file mode 100644 index 0000000000..1346e8eaff --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Navigation/images/leftturn-light.png diff --git a/examples/quickcontrols/wearable/qml/Navigation/images/leftturn-light@2x.png b/examples/quickcontrols/wearable/qml/Navigation/images/leftturn-light@2x.png Binary files differnew file mode 100644 index 0000000000..268a6283f9 --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Navigation/images/leftturn-light@2x.png diff --git a/examples/quickcontrols/wearable/qml/Navigation/images/marker.png b/examples/quickcontrols/wearable/qml/Navigation/images/marker.png Binary files differnew file mode 100644 index 0000000000..4805ad8207 --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Navigation/images/marker.png diff --git a/examples/quickcontrols/wearable/qml/Navigation/images/navigation-dark.png b/examples/quickcontrols/wearable/qml/Navigation/images/navigation-dark.png Binary files differnew file mode 100644 index 0000000000..b80b7b610f --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Navigation/images/navigation-dark.png diff --git a/examples/quickcontrols/wearable/qml/Navigation/images/navigation-dark@2x.png b/examples/quickcontrols/wearable/qml/Navigation/images/navigation-dark@2x.png Binary files differnew file mode 100644 index 0000000000..b198aa3d9a --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Navigation/images/navigation-dark@2x.png diff --git a/examples/quickcontrols/wearable/qml/Navigation/images/navigation-light.png b/examples/quickcontrols/wearable/qml/Navigation/images/navigation-light.png Binary files differnew file mode 100644 index 0000000000..08e73005fd --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Navigation/images/navigation-light.png diff --git a/examples/quickcontrols/wearable/qml/Navigation/images/navigation-light@2x.png b/examples/quickcontrols/wearable/qml/Navigation/images/navigation-light@2x.png Binary files differnew file mode 100644 index 0000000000..7d4a62b9e1 --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Navigation/images/navigation-light@2x.png diff --git a/examples/quickcontrols/wearable/qml/Navigation/images/rightturn-dark.png b/examples/quickcontrols/wearable/qml/Navigation/images/rightturn-dark.png Binary files differnew file mode 100644 index 0000000000..6a779dadc4 --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Navigation/images/rightturn-dark.png diff --git a/examples/quickcontrols/wearable/qml/Navigation/images/rightturn-dark@2x.png b/examples/quickcontrols/wearable/qml/Navigation/images/rightturn-dark@2x.png Binary files differnew file mode 100644 index 0000000000..13143c2e2c --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Navigation/images/rightturn-dark@2x.png diff --git a/examples/quickcontrols/wearable/qml/Navigation/images/rightturn-light.png b/examples/quickcontrols/wearable/qml/Navigation/images/rightturn-light.png Binary files differnew file mode 100644 index 0000000000..a6be08c1a1 --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Navigation/images/rightturn-light.png diff --git a/examples/quickcontrols/wearable/qml/Navigation/images/rightturn-light@2x.png b/examples/quickcontrols/wearable/qml/Navigation/images/rightturn-light@2x.png Binary files differnew file mode 100644 index 0000000000..58f04b5052 --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Navigation/images/rightturn-light@2x.png diff --git a/examples/quickcontrols/wearable/qml/Navigation/images/start.png b/examples/quickcontrols/wearable/qml/Navigation/images/start.png Binary files differnew file mode 100644 index 0000000000..41de60e60c --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Navigation/images/start.png diff --git a/examples/quickcontrols/wearable/qml/Navigation/images/start@2x.png b/examples/quickcontrols/wearable/qml/Navigation/images/start@2x.png Binary files differnew file mode 100644 index 0000000000..6fe3ba9dbd --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Navigation/images/start@2x.png diff --git a/examples/quickcontrols/wearable/qml/Navigation/images/straight-dark.png b/examples/quickcontrols/wearable/qml/Navigation/images/straight-dark.png Binary files differnew file mode 100644 index 0000000000..3f4ab66430 --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Navigation/images/straight-dark.png diff --git a/examples/quickcontrols/wearable/qml/Navigation/images/straight-dark@2x.png b/examples/quickcontrols/wearable/qml/Navigation/images/straight-dark@2x.png Binary files differnew file mode 100644 index 0000000000..f5baa6da42 --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Navigation/images/straight-dark@2x.png diff --git a/examples/quickcontrols/wearable/qml/Navigation/images/straight-light.png b/examples/quickcontrols/wearable/qml/Navigation/images/straight-light.png Binary files differnew file mode 100644 index 0000000000..1321b97aa5 --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Navigation/images/straight-light.png diff --git a/examples/quickcontrols/wearable/qml/Navigation/images/straight-light@2x.png b/examples/quickcontrols/wearable/qml/Navigation/images/straight-light@2x.png Binary files differnew file mode 100644 index 0000000000..a2d3c4c2ab --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Navigation/images/straight-light@2x.png diff --git a/examples/quickcontrols/wearable/qml/Navigation/images/uturn.png b/examples/quickcontrols/wearable/qml/Navigation/images/uturn.png Binary files differnew file mode 100644 index 0000000000..596046ca9a --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Navigation/images/uturn.png diff --git a/examples/quickcontrols/wearable/qml/Navigation/images/uturn@2x.png b/examples/quickcontrols/wearable/qml/Navigation/images/uturn@2x.png Binary files differnew file mode 100644 index 0000000000..659f103573 --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Navigation/images/uturn@2x.png diff --git a/examples/quickcontrols/wearable/qml/Navigation/navigation.js b/examples/quickcontrols/wearable/qml/Navigation/navigation.js new file mode 100644 index 0000000000..e82cccbea5 --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Navigation/navigation.js @@ -0,0 +1,84 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +function requestNavigationRoute(rModel) { + var xhr = new XMLHttpRequest; + xhr.open("GET", "walk_route.json"); + xhr.onreadystatechange = function () { + if (xhr.readyState === XMLHttpRequest.DONE) { + var a = JSON.parse(xhr.responseText); + var steps = a.routes[0].legs[0].steps; + + for (var step in steps) { + var maneuver = steps[step].maneuver; + var duration = steps[step].duration; + var distance = steps[step].distance; + + rModel.append({ + navInstruction: maneuver.instruction, + navImage: getNavigationImage( + maneuver.type, + maneuver.modifier, + routeView.imageList), + navAuxInfo: getAuxInfo(distance, + duration) + }); + } + } + } + xhr.send(); +} + +function getNavigationImage(maneuverType, maneuverModifier, imageList) { + var imageToReturn; + if (maneuverType === "depart") { + imageToReturn = imageList[4]; + } else if (maneuverType === "arrive") { + imageToReturn = imageList[5]; + } else if (maneuverType === "turn") { + if (maneuverModifier.search("left") >= 0) + imageToReturn = imageList[1]; + else if (maneuverModifier.search("right") >= 0) + imageToReturn = imageList[2]; + else + imageToReturn = imageList[0]; + } else { + if (maneuverModifier === "uturn") { + imageToReturn = imageList[3]; + } else { + imageToReturn = imageList[0]; + } + } + + return imageToReturn; +} + +function getAuxInfo(distInMeters, timeInSecs) { + var distance = convertDistance(distInMeters); + if (distance.length > 0) + return "Distance: " + distance + "\nTime: " + formatSeconds( + timeInSecs); + else + return ""; +} + +function convertDistance(meter) { + var dist = ""; + var feet = (meter * 0.3048).toPrecision(6); + var miles = (meter * 0.000621371).toPrecision(6); + + if (Math.floor(miles) > 1) { + dist += Math.floor(miles) + " mi"; + feet = ((miles - Math.floor(miles)) * 0.3048).toPrecision(6); + } + if (Math.floor(feet) > 1) + dist += Math.floor(feet) + " ft"; + + return dist +} + +function formatSeconds(seconds) { + var date = new Date(1970, 0, 1); + date.setSeconds(seconds); + return date.toTimeString().replace(/.*(\d{2}:\d{2}:\d{2}).*/, "$1"); +} diff --git a/examples/quickcontrols/wearable/qml/Navigation/walk_route.json b/examples/quickcontrols/wearable/qml/Navigation/walk_route.json new file mode 100644 index 0000000000..e69b5cc187 --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Navigation/walk_route.json @@ -0,0 +1 @@ +{"routes":[{"legs":[{"steps":[{"intersections":[{"out":0,"entry":[true],"bearings":[144],"location":[-122.394553,37.795984]},{"out":1,"location":[-122.393896,37.795268],"bearings":[60,150,225,330],"entry":[true,true,true,false],"in":3},{"out":1,"location":[-122.393179,37.79453],"bearings":[60,135,180,225,315],"entry":[true,true,true,true,false],"in":4},{"out":1,"location":[-122.393072,37.79443],"bearings":[45,135,225,315],"entry":[true,true,true,false],"in":3},{"out":1,"location":[-122.392787,37.79415],"bearings":[60,135,315],"entry":[true,true,false],"in":2},{"out":1,"location":[-122.392537,37.793915],"bearings":[45,135,225,315],"entry":[true,true,true,false],"in":3},{"out":0,"location":[-122.392448,37.793831],"bearings":[135,225,315],"entry":[true,true,false],"in":2}],"geometry":"{_ueF|d`jVRQdB}ARQh@g@XUVWVW^a@RUv@w@l@q@PQNQ","maneuver":{"bearing_after":144,"location":[-122.394553,37.795984],"bearing_before":0,"type":"depart","instruction":"Head southeast on The Embarcadero"},"duration":230.8,"distance":314.8,"name":"The Embarcadero","mode":"walking"},{"intersections":[{"out":2,"location":[-122.392361,37.793748],"bearings":[45,135,225,315],"entry":[true,true,true,false],"in":3}],"geometry":"}qteFfw_jVHJBDHJ","maneuver":{"bearing_after":225,"type":"turn","modifier":"right","bearing_before":140,"location":[-122.392361,37.793748],"instruction":"Turn right"},"duration":13.2,"distance":18.5,"name":"","mode":"walking"},{"intersections":[{"out":1,"location":[-122.39251,37.793631],"bearings":[45,135,225,315],"entry":[false,true,true,true],"in":0},{"out":1,"location":[-122.391284,37.792459],"bearings":[45,150,225,330],"entry":[true,true,true,false],"in":3},{"out":1,"location":[-122.391217,37.792342],"bearings":[45,165,225,330],"entry":[true,true,true,false],"in":3},{"out":1,"location":[-122.391165,37.792231],"bearings":[45,165,225,345],"entry":[true,true,true,false],"in":3},{"out":0,"location":[-122.390884,37.791536],"bearings":[150,285,345],"entry":[true,true,false],"in":2},{"out":1,"location":[-122.390254,37.790827],"bearings":[45,135,210,315],"entry":[true,true,true,false],"in":3},{"out":1,"location":[-122.390144,37.790745],"bearings":[45,135,225,315],"entry":[true,true,true,false],"in":3},{"out":1,"location":[-122.390038,37.790665],"bearings":[45,135,240,315],"entry":[true,true,true,false],"in":3},{"out":0,"location":[-122.389245,37.790036],"bearings":[135,225,315],"entry":[true,true,false],"in":2},{"out":1,"location":[-122.38871,37.789596],"bearings":[45,150,210,315],"entry":[true,true,true,false],"in":3},{"out":1,"location":[-122.388618,37.789494],"bearings":[45,150,225,330],"entry":[true,true,true,false],"in":3},{"out":1,"location":[-122.388527,37.789394],"bearings":[45,150,225,330],"entry":[true,true,true,false],"in":3},{"out":1,"location":[-122.388005,37.787907],"bearings":[0,180,270],"entry":[false,true,true],"in":0},{"out":1,"location":[-122.387985,37.787622],"bearings":[0,180,240],"entry":[false,true,true],"in":0},{"out":2,"location":[-122.388005,37.787197],"bearings":[0,90,180,270],"entry":[false,true,true,true],"in":0},{"out":2,"location":[-122.388015,37.787093],"bearings":[0,90,180,270],"entry":[false,true,true,true],"in":0},{"out":2,"location":[-122.388022,37.786994],"bearings":[0,90,180,285],"entry":[false,true,true,true],"in":0},{"out":1,"location":[-122.388163,37.785186],"bearings":[0,180,315],"entry":[false,true,true],"in":0},{"out":1,"location":[-122.388184,37.784944],"bearings":[0,180,315],"entry":[false,true,true],"in":0},{"out":2,"location":[-122.388191,37.784855],"bearings":[0,90,180,270],"entry":[false,true,true,true],"in":0},{"out":2,"location":[-122.388198,37.784748],"bearings":[0,90,180,270],"entry":[false,true,true,true],"in":0},{"out":2,"location":[-122.388207,37.784633],"bearings":[0,90,180,270],"entry":[false,true,true,true],"in":0},{"out":2,"location":[-122.388309,37.783373],"bearings":[0,60,180,270],"entry":[false,true,true,true],"in":0},{"out":1,"location":[-122.388376,37.782545],"bearings":[0,180,315],"entry":[false,true,true],"in":0},{"out":1,"location":[-122.388394,37.782316],"bearings":[0,180,315],"entry":[false,true,true],"in":0}],"geometry":"eqteFdx_jVf@k@\\a@|@iAV[FGJMPOTOPKDAPITItAa@r@WXOXQXSTUTWRYNUNS|B}CdAwAPSTQRQ\\W^Q\\KZIrB]^EPCH?\\CZ?Z?\\?XBT@R?~IZF?H@f@@N@T@V@zFRbDLl@@pADV@","maneuver":{"bearing_after":139,"type":"turn","modifier":"left","bearing_before":226,"location":[-122.39251,37.793631],"instruction":"Turn left onto The Embarcadero"},"duration":1055.9,"distance":1450.3,"name":"The Embarcadero","mode":"walking"},{"intersections":[{"out":2,"location":[-122.388431,37.781791],"bearings":[0,90,180,285],"entry":[false,true,true,true],"in":0},{"out":2,"location":[-122.389672,37.779922],"bearings":[45,135,225,315],"entry":[false,true,true,true],"in":0},{"out":1,"location":[-122.390803,37.77905],"bearings":[45,225,315],"entry":[false,true,true],"in":0},{"out":2,"location":[-122.391916,37.778155],"bearings":[45,135,225,315],"entry":[false,true,true,true],"in":0},{"out":2,"location":[-122.393073,37.777251],"bearings":[45,75,225,315],"entry":[false,true,true,true],"in":0}],"geometry":"egreFt~~iVR@bABXDVDXHVNXNXVVZp@|@z@hAnCvDLRNTHLFJbArAzApBdB`CTZZb@\\b@@@pCvD","maneuver":{"bearing_after":183,"type":"new name","modifier":"straight","bearing_before":183,"location":[-122.388431,37.781791],"instruction":"Continue straight onto King Street"},"duration":567.4,"distance":782.5,"name":"King Street","mode":"walking"},{"intersections":[{"out":3,"location":[-122.394003,37.776513],"bearings":[45,135,225,300],"entry":[false,true,true,true],"in":0},{"out":2,"location":[-122.394218,37.776486],"bearings":[45,135,225,315],"entry":[false,true,true,true],"in":0}],"geometry":"efqeFna`jVGJ?NJNNR","maneuver":{"bearing_after":313,"type":"turn","modifier":"straight","bearing_before":225,"location":[-122.394003,37.776513],"instruction":"Go straight"},"duration":26.1,"distance":36.2,"name":"","mode":"walking"},{"intersections":[{"out":2,"location":[-122.394321,37.776405],"bearings":[45,180,315],"entry":[false,true,true],"in":0},{"out":1,"location":[-122.394729,37.776487],"bearings":[45,180],"entry":[false,true],"in":0}],"geometry":"qeqeFnc`jVe@p@A@V\\DF","maneuver":{"bearing_after":315,"type":"turn","modifier":"right","bearing_before":225,"location":[-122.394321,37.776405],"instruction":"Turn right"},"duration":39.9,"distance":55.6,"name":"","mode":"walking"},{"intersections":[{"in":0,"entry":[true],"bearings":[45],"location":[-122.394768,37.776455]}],"geometry":"{eqeFhf`jV","maneuver":{"bearing_after":0,"type":"arrive","modifier":"straight","bearing_before":225,"location":[-122.394729,37.776487],"instruction":"You have arrived at your destination, straight ahead"},"duration":0,"distance":0,"name":"","mode":"walking"}],"summary":"The Embarcadero, King Street","duration":1933.3,"distance":2657.8}],"geometry":"{_ueF|d`jV|LuLV\\`EyElHaD~I_LvB_AdGk@he@|AbBd@bZl`@R~@g@r@\\d@","duration":1933.3,"distance":2657.8}],"waypoints":[{"name":"The Embarcadero","location":[-122.394553,37.795984]},{"name":"","location":[-122.394768,37.776455]}],"code":"Ok"} diff --git a/examples/quickcontrols/wearable/qml/Notifications/NotificationsPage.qml b/examples/quickcontrols/wearable/qml/Notifications/NotificationsPage.qml new file mode 100644 index 0000000000..6cbf2d92cf --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Notifications/NotificationsPage.qml @@ -0,0 +1,65 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Controls as QQC2 +import "../Style" +import "notifications.js" as NotificationData + +ListView { + id: missedCallsView + + clip: true + focus: true + boundsBehavior: Flickable.StopAtBounds + snapMode: ListView.SnapToItem + + model: ListModel { + id: missedCallsList + } + + Image { + id: missedCallIcon + width: parent.width / 2 + anchors.right: parent.horizontalCenter + anchors.verticalCenter: parent.verticalCenter + source: UIStyle.themeImagePath("images/missedcall") + fillMode: Image.Pad + } + + delegate: Item { + height: missedCallsView.height + width: missedCallsView.width / 2 + anchors.left: missedCallsView.contentItem.horizontalCenter + + Column { + spacing: 15 + anchors.verticalCenter: parent.verticalCenter + + Image { + anchors.horizontalCenter: parent.horizontalCenter + source: qsTr("images/avatar%1-%2.png").arg(model.gender).arg(UIStyle.darkTheme ? "dark" : "light") + } + + Text { + text: model.name + anchors.horizontalCenter: parent.horizontalCenter + font.bold: true + font.pixelSize: UIStyle.fontSizeS + color: UIStyle.themeColorQtGray1 + } + + Text { + anchors.horizontalCenter: parent.horizontalCenter + text: date + " " + time + font.pixelSize: UIStyle.fontSizeXS + font.italic: true + color: UIStyle.themeColorQtGray2 + } + } + } + + Component.onCompleted: { + NotificationData.populateData(missedCallsList) + } +} diff --git a/examples/quickcontrols/wearable/qml/Notifications/images/avatarf-dark.png b/examples/quickcontrols/wearable/qml/Notifications/images/avatarf-dark.png Binary files differnew file mode 100644 index 0000000000..37bc1f291b --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Notifications/images/avatarf-dark.png diff --git a/examples/quickcontrols/wearable/qml/Notifications/images/avatarf-dark@2x.png b/examples/quickcontrols/wearable/qml/Notifications/images/avatarf-dark@2x.png Binary files differnew file mode 100644 index 0000000000..efcd7cba74 --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Notifications/images/avatarf-dark@2x.png diff --git a/examples/quickcontrols/wearable/qml/Notifications/images/avatarf-light.png b/examples/quickcontrols/wearable/qml/Notifications/images/avatarf-light.png Binary files differnew file mode 100644 index 0000000000..e38b260724 --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Notifications/images/avatarf-light.png diff --git a/examples/quickcontrols/wearable/qml/Notifications/images/avatarf-light@2x.png b/examples/quickcontrols/wearable/qml/Notifications/images/avatarf-light@2x.png Binary files differnew file mode 100644 index 0000000000..1f28beac6c --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Notifications/images/avatarf-light@2x.png diff --git a/examples/quickcontrols/wearable/qml/Notifications/images/avatarm-dark.png b/examples/quickcontrols/wearable/qml/Notifications/images/avatarm-dark.png Binary files differnew file mode 100644 index 0000000000..5a2a394d8c --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Notifications/images/avatarm-dark.png diff --git a/examples/quickcontrols/wearable/qml/Notifications/images/avatarm-dark@2x.png b/examples/quickcontrols/wearable/qml/Notifications/images/avatarm-dark@2x.png Binary files differnew file mode 100644 index 0000000000..1a19b0fc8e --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Notifications/images/avatarm-dark@2x.png diff --git a/examples/quickcontrols/wearable/qml/Notifications/images/avatarm-light.png b/examples/quickcontrols/wearable/qml/Notifications/images/avatarm-light.png Binary files differnew file mode 100644 index 0000000000..f0fc7a9606 --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Notifications/images/avatarm-light.png diff --git a/examples/quickcontrols/wearable/qml/Notifications/images/avatarm-light@2x.png b/examples/quickcontrols/wearable/qml/Notifications/images/avatarm-light@2x.png Binary files differnew file mode 100644 index 0000000000..64a0f1f9ac --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Notifications/images/avatarm-light@2x.png diff --git a/examples/quickcontrols/wearable/qml/Notifications/images/missedcall-dark.png b/examples/quickcontrols/wearable/qml/Notifications/images/missedcall-dark.png Binary files differnew file mode 100644 index 0000000000..26bcf98ad3 --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Notifications/images/missedcall-dark.png diff --git a/examples/quickcontrols/wearable/qml/Notifications/images/missedcall-dark@2x.png b/examples/quickcontrols/wearable/qml/Notifications/images/missedcall-dark@2x.png Binary files differnew file mode 100644 index 0000000000..5eb54ce809 --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Notifications/images/missedcall-dark@2x.png diff --git a/examples/quickcontrols/wearable/qml/Notifications/images/missedcall-light.png b/examples/quickcontrols/wearable/qml/Notifications/images/missedcall-light.png Binary files differnew file mode 100644 index 0000000000..641e1f0c43 --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Notifications/images/missedcall-light.png diff --git a/examples/quickcontrols/wearable/qml/Notifications/images/missedcall-light@2x.png b/examples/quickcontrols/wearable/qml/Notifications/images/missedcall-light@2x.png Binary files differnew file mode 100644 index 0000000000..e8d2d81c9a --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Notifications/images/missedcall-light@2x.png diff --git a/examples/quickcontrols/wearable/qml/Notifications/notifications.js b/examples/quickcontrols/wearable/qml/Notifications/notifications.js new file mode 100644 index 0000000000..62f46e0a0b --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Notifications/notifications.js @@ -0,0 +1,25 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +function populateData(listData) { + listData.append({ + name: "John Doe", + gender: "m", + date: "02/15/2017", + time: "09:20 am" + }); + + listData.append({ + name: "Jane Worldege", + gender: "f", + date: "02/06/2017", + time: "10:15 am" + }); + + listData.append({ + name: "Jennifer Wang", + gender: "f", + date: "02/03/2017", + time: "05:16 pm" + }); +} diff --git a/examples/quickcontrols/wearable/qml/Settings/SettingsPage.qml b/examples/quickcontrols/wearable/qml/Settings/SettingsPage.qml new file mode 100644 index 0000000000..68fb17990d --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Settings/SettingsPage.qml @@ -0,0 +1,129 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Controls as QQC2 +import ".." +import "../Style" + +Item { + + QQC2.SwipeView { + id: svSettingsContainer + + anchors.fill: parent + + SwipeViewPage { + id: settingsPage1 + + property alias bluetoothSwitch: bluetoothSwitch + property alias wirelessSwitch: wirelessSwitch + + Column { + anchors.centerIn: parent + spacing: 25 + + Row { + spacing: 50 + Image { + anchors.verticalCenter: parent.verticalCenter + source: UIStyle.themeImagePath("images/bluetooth") + } + QQC2.Switch { + id: bluetoothSwitch + anchors.verticalCenter: parent.verticalCenter + checked: settings.bluetooth + onToggled: settings.bluetooth = checked + } + } + Row { + spacing: 50 + Image { + anchors.verticalCenter: parent.verticalCenter + source: UIStyle.themeImagePath("images/wifi") + } + QQC2.Switch { + id: wirelessSwitch + anchors.verticalCenter: parent.verticalCenter + checked: settings.wireless + onToggled: settings.wireless = checked + } + } + } + } + + SwipeViewPage { + id: settingsPage2 + + property alias brightnessSlider: brightnessSlider + property alias darkThemeSwitch: darkThemeSwitch + + Column { + anchors.centerIn: parent + spacing: 2 + + Column { + Image { + anchors.horizontalCenter: parent.horizontalCenter + source: UIStyle.themeImagePath("images/brightness") + } + QQC2.Slider { + id: brightnessSlider + anchors.horizontalCenter: parent.horizontalCenter + from: 0 + to: 5 + stepSize: 1 + value: settings.brightness + onMoved: settings.brightness = value + } + } + Column { + anchors.horizontalCenter: parent.horizontalCenter + + Image { + anchors.horizontalCenter: parent.horizontalCenter + source: UIStyle.themeImagePath("images/theme") + } + QQC2.Switch { + id: darkThemeSwitch + anchors.horizontalCenter: parent.horizontalCenter + checked: settings.darkTheme + onToggled: settings.darkTheme = checked + } + } + } + } + + SwipeViewPage { + id: settingsPage3 + + Column { + anchors.centerIn: parent + + Column { + anchors.horizontalCenter: parent.horizontalCenter + spacing: 6 + + Image { + anchors.horizontalCenter: parent.horizontalCenter + source: UIStyle.themeImagePath("images/demo-mode") + } + QQC2.Switch { + id: demoModeSwitch + anchors.horizontalCenter: parent.horizontalCenter + checked: settings.demoMode + onToggled: settings.demoMode = checked + } + } + } + } + } + + QQC2.PageIndicator { + count: svSettingsContainer.count + currentIndex: svSettingsContainer.currentIndex + + anchors.bottom: svSettingsContainer.bottom + anchors.horizontalCenter: parent.horizontalCenter + } +} diff --git a/examples/quickcontrols/wearable/qml/Settings/images/bluetooth-dark.png b/examples/quickcontrols/wearable/qml/Settings/images/bluetooth-dark.png Binary files differnew file mode 100644 index 0000000000..0f1f4d0a54 --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Settings/images/bluetooth-dark.png diff --git a/examples/quickcontrols/wearable/qml/Settings/images/bluetooth-dark@2x.png b/examples/quickcontrols/wearable/qml/Settings/images/bluetooth-dark@2x.png Binary files differnew file mode 100644 index 0000000000..7496fc5685 --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Settings/images/bluetooth-dark@2x.png diff --git a/examples/quickcontrols/wearable/qml/Settings/images/bluetooth-light.png b/examples/quickcontrols/wearable/qml/Settings/images/bluetooth-light.png Binary files differnew file mode 100644 index 0000000000..6e297cfab3 --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Settings/images/bluetooth-light.png diff --git a/examples/quickcontrols/wearable/qml/Settings/images/bluetooth-light@2x.png b/examples/quickcontrols/wearable/qml/Settings/images/bluetooth-light@2x.png Binary files differnew file mode 100644 index 0000000000..62d084032f --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Settings/images/bluetooth-light@2x.png diff --git a/examples/quickcontrols/wearable/qml/Settings/images/brightness-dark.png b/examples/quickcontrols/wearable/qml/Settings/images/brightness-dark.png Binary files differnew file mode 100644 index 0000000000..f9eb07b583 --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Settings/images/brightness-dark.png diff --git a/examples/quickcontrols/wearable/qml/Settings/images/brightness-dark@2x.png b/examples/quickcontrols/wearable/qml/Settings/images/brightness-dark@2x.png Binary files differnew file mode 100644 index 0000000000..3efc5a6c4b --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Settings/images/brightness-dark@2x.png diff --git a/examples/quickcontrols/wearable/qml/Settings/images/brightness-light.png b/examples/quickcontrols/wearable/qml/Settings/images/brightness-light.png Binary files differnew file mode 100644 index 0000000000..ce3023b565 --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Settings/images/brightness-light.png diff --git a/examples/quickcontrols/wearable/qml/Settings/images/brightness-light@2x.png b/examples/quickcontrols/wearable/qml/Settings/images/brightness-light@2x.png Binary files differnew file mode 100644 index 0000000000..dc01aae1fd --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Settings/images/brightness-light@2x.png diff --git a/examples/quickcontrols/wearable/qml/Settings/images/demo-mode-dark.png b/examples/quickcontrols/wearable/qml/Settings/images/demo-mode-dark.png Binary files differnew file mode 100644 index 0000000000..e93c417d79 --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Settings/images/demo-mode-dark.png diff --git a/examples/quickcontrols/wearable/qml/Settings/images/demo-mode-dark@2x.png b/examples/quickcontrols/wearable/qml/Settings/images/demo-mode-dark@2x.png Binary files differnew file mode 100644 index 0000000000..faa1bf6d11 --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Settings/images/demo-mode-dark@2x.png diff --git a/examples/quickcontrols/wearable/qml/Settings/images/demo-mode-light.png b/examples/quickcontrols/wearable/qml/Settings/images/demo-mode-light.png Binary files differnew file mode 100644 index 0000000000..c38d146d37 --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Settings/images/demo-mode-light.png diff --git a/examples/quickcontrols/wearable/qml/Settings/images/demo-mode-light@2x.png b/examples/quickcontrols/wearable/qml/Settings/images/demo-mode-light@2x.png Binary files differnew file mode 100644 index 0000000000..b9d6409cbc --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Settings/images/demo-mode-light@2x.png diff --git a/examples/quickcontrols/wearable/qml/Settings/images/demo-mode-white.png b/examples/quickcontrols/wearable/qml/Settings/images/demo-mode-white.png Binary files differnew file mode 100644 index 0000000000..aac8ef3f6c --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Settings/images/demo-mode-white.png diff --git a/examples/quickcontrols/wearable/qml/Settings/images/demo-mode-white@2x.png b/examples/quickcontrols/wearable/qml/Settings/images/demo-mode-white@2x.png Binary files differnew file mode 100644 index 0000000000..b4d8954f5d --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Settings/images/demo-mode-white@2x.png diff --git a/examples/quickcontrols/wearable/qml/Settings/images/demo-mode.svg b/examples/quickcontrols/wearable/qml/Settings/images/demo-mode.svg new file mode 100644 index 0000000000..ad1ce44873 --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Settings/images/demo-mode.svg @@ -0,0 +1,93 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="64" + height="64" + viewBox="0 0 16.933333 16.933333" + version="1.1" + id="svg8" + inkscape:version="0.92.3 (d244b95, 2018-08-02)" + sodipodi:docname="demo-mode.svg" + inkscape:export-filename="/home/mitch/dev/qt5.12/qtquickcontrols2/examples/quickcontrols2/wearable/qml/Settings/images/demo-mode-light@2x.png" + inkscape:export-xdpi="192" + inkscape:export-ydpi="192"> + <defs + id="defs2" /> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="15.839192" + inkscape:cx="26.498574" + inkscape:cy="25.685519" + inkscape:document-units="px" + inkscape:current-layer="layer1" + showgrid="true" + units="px" + fit-margin-top="1" + fit-margin-left="1" + fit-margin-right="1" + fit-margin-bottom="1" + inkscape:window-width="3706" + inkscape:window-height="2031" + inkscape:window-x="134" + inkscape:window-y="55" + inkscape:window-maximized="1" + inkscape:snap-global="false"> + <inkscape:grid + type="xygrid" + id="grid3713" + originx="-0.0070880335" + originy="-280.58354" /> + </sodipodi:namedview> + <metadata + id="metadata5"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title /> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1" + transform="translate(-0.00708803,0.51688025)"> + <path + style="fill:#141f3a;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="m 1.6489221,4.3034973 h 0.7205171 v 7.0102767 c 0.01422,0.27678 0.1921164,0.348966 0.392741,0.392741 H 14.169383 c 0.276028,-0.04241 0.382882,-0.208883 0.423747,-0.423747 V 4.3094031 h 0.692464 v 7.0279949 c -0.111554,0.831949 -0.589986,1.000696 -1.104399,1.104399 H 9.3324693 l 2.2589977,2.258998 c -0.0189,0.375139 -0.204956,0.516261 -0.501999,0.502 L 8.8304698,12.943797 v 1.972563 c -0.051861,0.342631 -0.6681357,0.36382 -0.7323291,0 V 12.949702 L 5.8391425,15.208701 C 5.5142667,15.206145 5.3522558,15.056484 5.3725781,14.742136 L 7.7172116,12.397503 H 2.7415096 C 2.1429244,12.357576 1.6879444,12.049089 1.6444927,11.300486 Z" + id="path826" + inkscape:connector-curvature="0" + sodipodi:nodetypes="ccccccccccccccccccccccc" /> + <rect + style="fill:#141f3a;fill-opacity:1;stroke:none;stroke-width:0.2619375;stroke-miterlimit:4;stroke-dasharray:0.523875, 0.2619375;stroke-dashoffset:0" + id="rect828" + width="16.044523" + height="1.9126476" + x="0.441401" + y="2.0340116" + rx="1.0583333" + ry="1.0583333" /> + <path + style="fill:#141f3a;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="M 7.8323763,1.681278 V 1.1615701 c 0.1987987,-0.67546179 1.0821701,-0.66495897 1.2992931,0 V 1.681278 Z" + id="path830" + inkscape:connector-curvature="0" + sodipodi:nodetypes="ccccc" /> + </g> +</svg> diff --git a/examples/quickcontrols/wearable/qml/Settings/images/theme-dark.png b/examples/quickcontrols/wearable/qml/Settings/images/theme-dark.png Binary files differnew file mode 100644 index 0000000000..d4c4a8c094 --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Settings/images/theme-dark.png diff --git a/examples/quickcontrols/wearable/qml/Settings/images/theme-dark@2x.png b/examples/quickcontrols/wearable/qml/Settings/images/theme-dark@2x.png Binary files differnew file mode 100644 index 0000000000..30d8c6de28 --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Settings/images/theme-dark@2x.png diff --git a/examples/quickcontrols/wearable/qml/Settings/images/theme-light.png b/examples/quickcontrols/wearable/qml/Settings/images/theme-light.png Binary files differnew file mode 100644 index 0000000000..e7a0771b94 --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Settings/images/theme-light.png diff --git a/examples/quickcontrols/wearable/qml/Settings/images/theme-light@2x.png b/examples/quickcontrols/wearable/qml/Settings/images/theme-light@2x.png Binary files differnew file mode 100644 index 0000000000..83bc878b03 --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Settings/images/theme-light@2x.png diff --git a/examples/quickcontrols/wearable/qml/Settings/images/theme.svg b/examples/quickcontrols/wearable/qml/Settings/images/theme.svg new file mode 100644 index 0000000000..bf3f1e57d7 --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Settings/images/theme.svg @@ -0,0 +1,84 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="64" + height="64" + viewBox="0 0 16.933333 16.933333" + version="1.1" + id="svg8" + inkscape:version="0.92.3 (2405546, 2018-03-11)" + sodipodi:docname="theme.svg" + inkscape:export-filename="C:\dev\qt5.11\qtquickcontrols2\examples\quickcontrols2\wearable\qml\Settings\images\theme@2x.png" + inkscape:export-xdpi="192" + inkscape:export-ydpi="192"> + <defs + id="defs2" /> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="7.9195959" + inkscape:cx="-11.371874" + inkscape:cy="28.405259" + inkscape:document-units="px" + inkscape:current-layer="layer1" + showgrid="true" + units="px" + fit-margin-top="1" + fit-margin-left="1" + fit-margin-right="1" + fit-margin-bottom="1" + inkscape:window-width="3840" + inkscape:window-height="2066" + inkscape:window-x="-11" + inkscape:window-y="-11" + inkscape:window-maximized="1" + inkscape:snap-global="false"> + <inkscape:grid + type="xygrid" + id="grid3713" + originx="-0.0070880335" + originy="-280.58354" /> + </sodipodi:namedview> + <metadata + id="metadata5"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title /> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1" + transform="translate(-0.00708803,0.51688025)"> + <path + style="fill:#141f3a;fill-opacity:1;stroke:none;stroke-width:0.25668776px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="M 2.7296861,14.56437 H 12.831038 C 13.464556,14.411157 15.01089,14.101758 15.231756,11.825604 15.232242,10.48538 13.96701,8.4813248 11.69084,9.0467292 10.687852,7.3630573 9.1232541,7.2558172 8.2817051,7.654427 6.9050791,4.9744381 2.9222535,5.8560797 2.9703307,8.9435956 1.7108806,9.1004362 0.37826375,9.7182846 0.27167137,11.745388 0.31660717,13.546059 1.5831259,14.350467 2.7296861,14.56437 Z" + id="path4535" + inkscape:connector-curvature="0" + sodipodi:nodetypes="cccccccc" /> + <path + style="fill:#141f3a;fill-opacity:1;stroke:none;stroke-width:0.25668776px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="M 11.392726,0.92763044 C 8.8246143,2.2754379 7.9809615,4.3443829 8.9780532,7.1830936 10.167295,7.1426991 11.108291,7.6664967 11.822182,8.7064442 12.799984,8.6194307 13.765772,8.6795708 14.658208,9.6382815 15.605885,9.3257847 16.200803,8.852941 16.675838,8.325607 13.735088,9.4033595 8.6151974,5.957728 11.392726,0.92763044 Z" + id="path4537" + inkscape:connector-curvature="0" + sodipodi:nodetypes="cccccc" /> + </g> +</svg> diff --git a/examples/quickcontrols/wearable/qml/Settings/images/wifi-dark.png b/examples/quickcontrols/wearable/qml/Settings/images/wifi-dark.png Binary files differnew file mode 100644 index 0000000000..14bfe8f5c8 --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Settings/images/wifi-dark.png diff --git a/examples/quickcontrols/wearable/qml/Settings/images/wifi-dark@2x.png b/examples/quickcontrols/wearable/qml/Settings/images/wifi-dark@2x.png Binary files differnew file mode 100644 index 0000000000..b70d04290b --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Settings/images/wifi-dark@2x.png diff --git a/examples/quickcontrols/wearable/qml/Settings/images/wifi-light.png b/examples/quickcontrols/wearable/qml/Settings/images/wifi-light.png Binary files differnew file mode 100644 index 0000000000..2de34118a7 --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Settings/images/wifi-light.png diff --git a/examples/quickcontrols/wearable/qml/Settings/images/wifi-light@2x.png b/examples/quickcontrols/wearable/qml/Settings/images/wifi-light@2x.png Binary files differnew file mode 100644 index 0000000000..64b5f1725c --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Settings/images/wifi-light@2x.png diff --git a/examples/quickcontrols/wearable/qml/Style/PageIndicator.qml b/examples/quickcontrols/wearable/qml/Style/PageIndicator.qml new file mode 100644 index 0000000000..593b50afb5 --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Style/PageIndicator.qml @@ -0,0 +1,42 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Templates as T +import "." + +T.PageIndicator { + id: control + + implicitWidth: contentItem.implicitWidth + leftPadding + rightPadding + implicitHeight: contentItem.implicitHeight + topPadding + bottomPadding + + spacing: 6 + padding: 6 + bottomPadding: 7 + + delegate: Rectangle { + implicitWidth: 8 + implicitHeight: 8 + + radius: width / 2 + color: UIStyle.themeColorQtGray3 + + opacity: index === control.currentIndex ? 1.0 : 0.35 + + Behavior on opacity { + OpacityAnimator { + duration: 100 + } + } + } + + contentItem: Row { + spacing: control.spacing + + Repeater { + model: control.count + delegate: control.delegate + } + } +} diff --git a/examples/quickcontrols/wearable/qml/Style/Slider.qml b/examples/quickcontrols/wearable/qml/Style/Slider.qml new file mode 100644 index 0000000000..79c664280f --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Style/Slider.qml @@ -0,0 +1,39 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Templates as T +import "." + +T.Slider { + id: control + + implicitWidth: 200 + implicitHeight: 26 + + handle: Rectangle { + x: control.visualPosition * (control.width - width) + y: (control.height - height) / 2 + width: 20 + height: 15 + + radius: 5 + color: control.pressed ? "#f0f0f0" : "#f6f6f6" + border.color: UIStyle.themeColorQtGray7 + } + + background: Rectangle { + y: (control.height - height) / 2 + height: 4 + radius: 2 + color: UIStyle.themeColorQtGray3 + + Rectangle { + width: control.visualPosition * parent.width + height: parent.height + color: UIStyle.colorQtAuxGreen2 + radius: 2 + } + } +} + diff --git a/examples/quickcontrols/wearable/qml/Style/Switch.qml b/examples/quickcontrols/wearable/qml/Style/Switch.qml new file mode 100644 index 0000000000..6219bf231e --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Style/Switch.qml @@ -0,0 +1,39 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Templates as T +import "." + +T.Switch { + id: control + + implicitWidth: 48 + implicitHeight: 26 + + indicator: Rectangle { + x: control.visualPosition * (control.width - width) + y: (control.height - height) / 2 + width: 26 + height: 26 + + radius: 13 + color: control.down ? UIStyle.themeColorQtGray6 : UIStyle.themeColorQtGray10 + border.color: !control.checked ? "#999999" + : (control.down ? UIStyle.colorQtAuxGreen2 + : UIStyle.colorQtAuxGreen1) + + Behavior on x { + enabled: !control.pressed + SmoothedAnimation { velocity: 200 } + } + } + + background: Rectangle { + radius: 13 + color: control.checked ? UIStyle.colorQtAuxGreen2 : UIStyle.colorRed + border.color: control.checked ? UIStyle.colorQtAuxGreen2 + : UIStyle.themeColorQtGray6 + } +} + diff --git a/examples/quickcontrols/wearable/qml/Style/UIStyle.qml b/examples/quickcontrols/wearable/qml/Style/UIStyle.qml new file mode 100644 index 0000000000..524b8394f5 --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Style/UIStyle.qml @@ -0,0 +1,60 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick + +pragma Singleton + +QtObject { + id: uiStyle + + // Font Sizes + readonly property int fontSizeXXS: 10 + readonly property int fontSizeXS: 15 + readonly property int fontSizeS: 20 + readonly property int fontSizeM: 25 + readonly property int fontSizeL: 30 + readonly property int fontSizeXL: 35 + readonly property int fontSizeXXL: 40 + + // Color Scheme + // Green + readonly property color colorQtPrimGreen: "#41cd52" + readonly property color colorQtAuxGreen1: "#21be2b" + readonly property color colorQtAuxGreen2: "#17a81a" + + // Red + readonly property color colorRed: "#e6173d" + + // Gray + readonly property color colorQtGray1: "#09102b" + readonly property color colorQtGray2: "#222840" + readonly property color colorQtGray3: "#3a4055" + readonly property color colorQtGray4: "#53586b" + readonly property color colorQtGray5: "#53586b" + readonly property color colorQtGray6: "#848895" + readonly property color colorQtGray7: "#9d9faa" + readonly property color colorQtGray8: "#b5b7bf" + readonly property color colorQtGray9: "#cecfd5" + readonly property color colorQtGray10: "#f3f3f4" + + // Light/dark versions of the colors above. + // Some UI elements always use a specific color regardless of theme, + // which is why we have both sets: so that those elements don't need to hard-code the hex string. + readonly property color themeColorQtGray1: darkTheme ? colorQtGray10 : colorQtGray1 + readonly property color themeColorQtGray2: darkTheme ? colorQtGray9 : colorQtGray2 + readonly property color themeColorQtGray3: darkTheme ? colorQtGray8 : colorQtGray3 + readonly property color themeColorQtGray4: darkTheme ? colorQtGray7 : colorQtGray4 + readonly property color themeColorQtGray5: darkTheme ? colorQtGray6 : colorQtGray5 + readonly property color themeColorQtGray6: darkTheme ? colorQtGray5 : colorQtGray6 + readonly property color themeColorQtGray7: darkTheme ? colorQtGray4 : colorQtGray7 + readonly property color themeColorQtGray8: darkTheme ? colorQtGray3 : colorQtGray8 + readonly property color themeColorQtGray9: darkTheme ? colorQtGray2 : colorQtGray9 + readonly property color themeColorQtGray10: darkTheme ? colorQtGray1 : colorQtGray10 + + property bool darkTheme: false + + function themeImagePath(baseImagePath) { + return baseImagePath + (darkTheme ? "-dark" : "-light") + ".png" + } +} diff --git a/examples/quickcontrols/wearable/qml/Style/qmldir b/examples/quickcontrols/wearable/qml/Style/qmldir new file mode 100644 index 0000000000..a04072bed6 --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Style/qmldir @@ -0,0 +1 @@ +singleton UIStyle 1.0 UIStyle.qml diff --git a/examples/quickcontrols/wearable/qml/SwipeViewPage.qml b/examples/quickcontrols/wearable/qml/SwipeViewPage.qml new file mode 100644 index 0000000000..1f005363dc --- /dev/null +++ b/examples/quickcontrols/wearable/qml/SwipeViewPage.qml @@ -0,0 +1,13 @@ +// Copyright (C) 2018 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Controls + +Item { + // Don't show the item when the StackView that contains us + // is being popped off the stack, as we use an x animation + // and hence would show pages that we shouldn't since we + // also don't have our own background. + visible: SwipeView.isCurrentItem || (SwipeView.view.contentItem.moving && (SwipeView.isPreviousItem || SwipeView.isNextItem)) +} diff --git a/examples/quickcontrols/wearable/qml/Weather/WeatherPage.qml b/examples/quickcontrols/wearable/qml/Weather/WeatherPage.qml new file mode 100644 index 0000000000..d110fabdf9 --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Weather/WeatherPage.qml @@ -0,0 +1,250 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Controls as QQC2 +import ".." +import "../Style" +import "weather.js" as WeatherData + +Item { + QQC2.SwipeView { + id: svWeatherContainer + + anchors.fill: parent + + SwipeViewPage { + id: weatherPage1 + + Row { + anchors.centerIn: parent + spacing: 2 + + Image { + anchors.verticalCenter: parent.verticalCenter + source: UIStyle.themeImagePath("images/temperature") + } + + Column { + anchors.verticalCenter: parent.verticalCenter + spacing: 40 + + Text { + text: (wDataCntr.weatherData + && wDataCntr.weatherData.main + && wDataCntr.weatherData.main.temp) ? + qsTr("Avg: ") + + String(wDataCntr.weatherData.main.temp) + + " °F" : "N/A" + font.pixelSize: UIStyle.fontSizeM + font.letterSpacing: 1 + color: UIStyle.themeColorQtGray1 + } + + Text { + text: (wDataCntr.weatherData + && wDataCntr.weatherData.main + && wDataCntr.weatherData.main.temp_min) ? + qsTr("Min: ") + + String(wDataCntr.weatherData.main.temp_min) + + " °F" : "N/A" + font.pixelSize: UIStyle.fontSizeM + font.letterSpacing: 1 + color: UIStyle.themeColorQtGray1 + } + + Text { + text: (wDataCntr.weatherData + && wDataCntr.weatherData.main + && wDataCntr.weatherData.main.temp_max) ? + qsTr("Max: ") + + String(wDataCntr.weatherData.main.temp_max) + + " °F " : "N/A" + font.pixelSize: UIStyle.fontSizeM + font.letterSpacing: 1 + color: UIStyle.themeColorQtGray1 + } + } + } + } + + SwipeViewPage { + id: weatherPage2 + + Column { + spacing: 40 + anchors.centerIn: parent + + Row { + spacing: 20 + anchors.horizontalCenter: parent.horizontalCenter + + Image { + id: wImg + anchors.verticalCenter: parent.verticalCenter + source: UIStyle.themeImagePath("images/wind") + } + + Text { + anchors.verticalCenter: parent.verticalCenter + text: (wDataCntr.weatherData + && wDataCntr.weatherData.wind + && wDataCntr.weatherData.wind.speed) ? + String(wDataCntr.weatherData.wind.speed) + + " mph" : "N/A" + font.pixelSize: UIStyle.fontSizeM + font.letterSpacing: 1 + color: UIStyle.themeColorQtGray1 + } + } + + Row { + spacing: 20 + anchors.horizontalCenter: parent.horizontalCenter + + Image { + id: hImg + anchors.verticalCenter: parent.verticalCenter + source: UIStyle.themeImagePath("images/humidity") + } + + Text { + anchors.verticalCenter: parent.verticalCenter + text: (wDataCntr.weatherData + && wDataCntr.weatherData.main + && wDataCntr.weatherData.main.humidity) ? + String(wDataCntr.weatherData.main.humidity) + + " %" : "N/A" + font.pixelSize: UIStyle.fontSizeM + font.letterSpacing: 1 + color: UIStyle.themeColorQtGray1 + } + } + } + } + + SwipeViewPage { + id: weatherPage3 + + Row { + anchors.centerIn: parent + spacing: 10 + + Image { + anchors.verticalCenter: parent.verticalCenter + source: UIStyle.themeImagePath("images/pressure") + } + + Column { + anchors.verticalCenter: parent.verticalCenter + spacing: 40 + + Text { + anchors.horizontalCenter: parent.horizontalCenter + text: (wDataCntr.weatherData + && wDataCntr.weatherData.main + && wDataCntr.weatherData.main.pressure) ? + String(wDataCntr.weatherData.main.pressure) + + " hPa" : "N/A" + font.pixelSize: UIStyle.fontSizeM + font.letterSpacing: 1 + color: UIStyle.themeColorQtGray1 + } + + Text { + anchors.horizontalCenter: parent.horizontalCenter + text: (wDataCntr.weatherData + && wDataCntr.weatherData.main + && wDataCntr.weatherData.main.sea_level) ? + String(wDataCntr.weatherData.main.sea_level) + + " hPa" : "N/A" + font.pixelSize: UIStyle.fontSizeM + font.letterSpacing: 1 + color: UIStyle.themeColorQtGray1 + } + + Text { + anchors.horizontalCenter: parent.horizontalCenter + text: (wDataCntr.weatherData + && wDataCntr.weatherData.main + && wDataCntr.weatherData.main.grnd_level) ? + String(wDataCntr.weatherData.main.grnd_level) + + " hPa" : "N/A" + font.pixelSize: UIStyle.fontSizeM + font.letterSpacing: 1 + color: UIStyle.themeColorQtGray1 + } + } + } + } + + SwipeViewPage { + id: weatherPage4 + + Column { + spacing: 40 + anchors.centerIn: parent + + Row { + spacing: 30 + anchors.horizontalCenter: parent.horizontalCenter + + Image { + anchors.verticalCenter: parent.verticalCenter + source: UIStyle.themeImagePath("images/sunrise") + } + + Text { + anchors.verticalCenter: parent.verticalCenter + text: (wDataCntr.weatherData + && wDataCntr.weatherData.sys + && wDataCntr.weatherData.sys.sunrise) ? + WeatherData.getTimeHMS(wDataCntr.weatherData.sys.sunrise) + : "N/A" + font.pixelSize: UIStyle.fontSizeM + font.letterSpacing: 1 + color: UIStyle.themeColorQtGray1 + } + } + + Row { + spacing: 30 + anchors.horizontalCenter: parent.horizontalCenter + + Image { + anchors.verticalCenter: parent.verticalCenter + source: UIStyle.themeImagePath("images/sunset") + } + + Text { + anchors.verticalCenter: parent.verticalCenter + text: (wDataCntr.weatherData + && wDataCntr.weatherData.sys + && wDataCntr.weatherData.sys.sunset) ? + WeatherData.getTimeHMS(wDataCntr.weatherData.sys.sunset) + : "N/A" + font.pixelSize: UIStyle.fontSizeM + font.letterSpacing: 1 + color: UIStyle.themeColorQtGray1 + } + } + } + } + } + + QtObject { + id: wDataCntr + property var weatherData + } + + QQC2.PageIndicator { + count: svWeatherContainer.count + currentIndex: svWeatherContainer.currentIndex + + anchors.bottom: svWeatherContainer.bottom + anchors.horizontalCenter: parent.horizontalCenter + } + Component.onCompleted: { + WeatherData.requestWeatherData(wDataCntr) + } +} diff --git a/examples/quickcontrols/wearable/qml/Weather/images/humidity-dark.png b/examples/quickcontrols/wearable/qml/Weather/images/humidity-dark.png Binary files differnew file mode 100644 index 0000000000..5d82238cdb --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Weather/images/humidity-dark.png diff --git a/examples/quickcontrols/wearable/qml/Weather/images/humidity-dark@2x.png b/examples/quickcontrols/wearable/qml/Weather/images/humidity-dark@2x.png Binary files differnew file mode 100644 index 0000000000..d83bb4f00c --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Weather/images/humidity-dark@2x.png diff --git a/examples/quickcontrols/wearable/qml/Weather/images/humidity-light.png b/examples/quickcontrols/wearable/qml/Weather/images/humidity-light.png Binary files differnew file mode 100644 index 0000000000..5f3bf714e6 --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Weather/images/humidity-light.png diff --git a/examples/quickcontrols/wearable/qml/Weather/images/humidity-light@2x.png b/examples/quickcontrols/wearable/qml/Weather/images/humidity-light@2x.png Binary files differnew file mode 100644 index 0000000000..a23364c52c --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Weather/images/humidity-light@2x.png diff --git a/examples/quickcontrols/wearable/qml/Weather/images/pressure-dark.png b/examples/quickcontrols/wearable/qml/Weather/images/pressure-dark.png Binary files differnew file mode 100644 index 0000000000..b2870a55a6 --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Weather/images/pressure-dark.png diff --git a/examples/quickcontrols/wearable/qml/Weather/images/pressure-dark@2x.png b/examples/quickcontrols/wearable/qml/Weather/images/pressure-dark@2x.png Binary files differnew file mode 100644 index 0000000000..061f9b8266 --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Weather/images/pressure-dark@2x.png diff --git a/examples/quickcontrols/wearable/qml/Weather/images/pressure-light.png b/examples/quickcontrols/wearable/qml/Weather/images/pressure-light.png Binary files differnew file mode 100644 index 0000000000..7b1b158734 --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Weather/images/pressure-light.png diff --git a/examples/quickcontrols/wearable/qml/Weather/images/pressure-light@2x.png b/examples/quickcontrols/wearable/qml/Weather/images/pressure-light@2x.png Binary files differnew file mode 100644 index 0000000000..1a40c6422a --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Weather/images/pressure-light@2x.png diff --git a/examples/quickcontrols/wearable/qml/Weather/images/sunrise-dark.png b/examples/quickcontrols/wearable/qml/Weather/images/sunrise-dark.png Binary files differnew file mode 100644 index 0000000000..9cac22e1e1 --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Weather/images/sunrise-dark.png diff --git a/examples/quickcontrols/wearable/qml/Weather/images/sunrise-dark@2x.png b/examples/quickcontrols/wearable/qml/Weather/images/sunrise-dark@2x.png Binary files differnew file mode 100644 index 0000000000..fe32682386b --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Weather/images/sunrise-dark@2x.png diff --git a/examples/quickcontrols/wearable/qml/Weather/images/sunrise-light.png b/examples/quickcontrols/wearable/qml/Weather/images/sunrise-light.png Binary files differnew file mode 100644 index 0000000000..f67a5dff34 --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Weather/images/sunrise-light.png diff --git a/examples/quickcontrols/wearable/qml/Weather/images/sunrise-light@2x.png b/examples/quickcontrols/wearable/qml/Weather/images/sunrise-light@2x.png Binary files differnew file mode 100644 index 0000000000..86f5483761 --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Weather/images/sunrise-light@2x.png diff --git a/examples/quickcontrols/wearable/qml/Weather/images/sunset-dark.png b/examples/quickcontrols/wearable/qml/Weather/images/sunset-dark.png Binary files differnew file mode 100644 index 0000000000..0068d30539 --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Weather/images/sunset-dark.png diff --git a/examples/quickcontrols/wearable/qml/Weather/images/sunset-dark@2x.png b/examples/quickcontrols/wearable/qml/Weather/images/sunset-dark@2x.png Binary files differnew file mode 100644 index 0000000000..e515bcc37c --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Weather/images/sunset-dark@2x.png diff --git a/examples/quickcontrols/wearable/qml/Weather/images/sunset-light.png b/examples/quickcontrols/wearable/qml/Weather/images/sunset-light.png Binary files differnew file mode 100644 index 0000000000..495f78a786 --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Weather/images/sunset-light.png diff --git a/examples/quickcontrols/wearable/qml/Weather/images/sunset-light@2x.png b/examples/quickcontrols/wearable/qml/Weather/images/sunset-light@2x.png Binary files differnew file mode 100644 index 0000000000..d220e829d1 --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Weather/images/sunset-light@2x.png diff --git a/examples/quickcontrols/wearable/qml/Weather/images/temperature-dark.png b/examples/quickcontrols/wearable/qml/Weather/images/temperature-dark.png Binary files differnew file mode 100644 index 0000000000..a207d9440d --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Weather/images/temperature-dark.png diff --git a/examples/quickcontrols/wearable/qml/Weather/images/temperature-dark@2x.png b/examples/quickcontrols/wearable/qml/Weather/images/temperature-dark@2x.png Binary files differnew file mode 100644 index 0000000000..c0e4ef39bf --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Weather/images/temperature-dark@2x.png diff --git a/examples/quickcontrols/wearable/qml/Weather/images/temperature-light.png b/examples/quickcontrols/wearable/qml/Weather/images/temperature-light.png Binary files differnew file mode 100644 index 0000000000..c4f7b61c2e --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Weather/images/temperature-light.png diff --git a/examples/quickcontrols/wearable/qml/Weather/images/temperature-light@2x.png b/examples/quickcontrols/wearable/qml/Weather/images/temperature-light@2x.png Binary files differnew file mode 100644 index 0000000000..50d4f4c43c --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Weather/images/temperature-light@2x.png diff --git a/examples/quickcontrols/wearable/qml/Weather/images/wind-dark.png b/examples/quickcontrols/wearable/qml/Weather/images/wind-dark.png Binary files differnew file mode 100644 index 0000000000..6a530491af --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Weather/images/wind-dark.png diff --git a/examples/quickcontrols/wearable/qml/Weather/images/wind-dark@2x.png b/examples/quickcontrols/wearable/qml/Weather/images/wind-dark@2x.png Binary files differnew file mode 100644 index 0000000000..487e3e78a3 --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Weather/images/wind-dark@2x.png diff --git a/examples/quickcontrols/wearable/qml/Weather/images/wind-light.png b/examples/quickcontrols/wearable/qml/Weather/images/wind-light.png Binary files differnew file mode 100644 index 0000000000..97824bee8f --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Weather/images/wind-light.png diff --git a/examples/quickcontrols/wearable/qml/Weather/images/wind-light@2x.png b/examples/quickcontrols/wearable/qml/Weather/images/wind-light@2x.png Binary files differnew file mode 100644 index 0000000000..7f94bd8542 --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Weather/images/wind-light@2x.png diff --git a/examples/quickcontrols/wearable/qml/Weather/weather.js b/examples/quickcontrols/wearable/qml/Weather/weather.js new file mode 100644 index 0000000000..c08fd96e9e --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Weather/weather.js @@ -0,0 +1,30 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +function requestWeatherData(cntr) { + var xhr = new XMLHttpRequest; + xhr.open("GET", "weather.json"); + xhr.onreadystatechange = function () { + if (xhr.readyState === XMLHttpRequest.DONE) { + cntr.weatherData = JSON.parse(xhr.responseText) + } + } + xhr.send(); +} + +function getTimeHMS(utcTime) { + var date = new Date(utcTime * 1000); + // Hours part from the timestamp + var hours = date.getHours(); + var ampm = Math.floor((hours / 12)) ? " PM" : " AM"; + hours = (hours % 12); + + // Minutes part from the timestamp + var minutes = "0" + date.getMinutes(); + // Seconds part from the timestamp + var seconds = "0" + date.getSeconds(); + + // Will display time in 10:30:23 format + return hours % 12 + ':' + minutes.substr(-2) + ':' + seconds.substr(-2) + + ampm; +} diff --git a/examples/quickcontrols/wearable/qml/Weather/weather.json b/examples/quickcontrols/wearable/qml/Weather/weather.json new file mode 100644 index 0000000000..2cce95c60b --- /dev/null +++ b/examples/quickcontrols/wearable/qml/Weather/weather.json @@ -0,0 +1 @@ +{"coord":{"lon":-122.42,"lat":37.77},"weather":[{"id":803,"main":"Clouds","description":"broken clouds","icon":"04n"}],"base":"stations","main":{"temp":45.22,"pressure":1020.17,"humidity":88,"temp_min":36.92,"temp_max":58.92,"sea_level":1028.19,"grnd_level":1020.17},"wind":{"speed":6.73,"deg":201.002},"clouds":{"all":68},"dt":1476412232,"sys":{"message":0.012,"country":"US","sunrise":1476454666,"sunset":1476495156},"id":5391959,"name":"San Francisco","cod":200} diff --git a/examples/quickcontrols/wearable/qml/WorldClock/Clock.qml b/examples/quickcontrols/wearable/qml/WorldClock/Clock.qml new file mode 100644 index 0000000000..e89489b045 --- /dev/null +++ b/examples/quickcontrols/wearable/qml/WorldClock/Clock.qml @@ -0,0 +1,141 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Controls as QQC2 +import ".." +import "../Style" + +SwipeViewPage { + id: clock + + property int hours + property int minutes + property int seconds + property real shift: timeShift + property bool night: false + property bool internationalTime: true //Unset for local time + + function getWatchFaceImage(imageName) { + return "images/" + imageName + } + + function timeChanged() { + var date = new Date + hours = internationalTime ? date.getUTCHours() + Math.floor( + clock.shift) : date.getHours() + night = (hours < 7 || hours > 19) + minutes = internationalTime ? + date.getUTCMinutes() + ((clock.shift % 1) * 60) : date.getMinutes() + seconds = date.getUTCSeconds() + } + + Timer { + interval: 100 + running: true + repeat: true + onTriggered: clock.timeChanged() + } + + Item { + anchors.centerIn: parent + + width: 200 + height: 220 + + Rectangle { + color: clock.night ? UIStyle.colorQtGray1 : UIStyle.colorQtGray10 + radius: width / 2 + width: parent.width + height: parent.width + } + + Image { + id: background + source: getWatchFaceImage("swissdaydial.png") + visible: clock.night == false + } + Image { + source: getWatchFaceImage("swissnightdial.png") + visible: clock.night == true + } + + Image { + x: 92.5 + y: 27 + source: getWatchFaceImage(clock.night ? + "swissnighthour.png" + : "swissdayhour.png") + transform: Rotation { + id: hourRotation + origin.x: 7.5 + origin.y: 73 + angle: (clock.hours * 30) + (clock.minutes * 0.5) + Behavior on angle { + SpringAnimation { + spring: 2 + damping: 0.2 + modulus: 360 + } + } + } + } + + Image { + x: 93.5 + y: 17 + source: getWatchFaceImage(clock.night ? + "swissnightminute.png" + : "swissdayminute.png") + transform: Rotation { + id: minuteRotation + origin.x: 6.5 + origin.y: 83 + angle: clock.minutes * 6 + Behavior on angle { + SpringAnimation { + spring: 2 + damping: 0.2 + modulus: 360 + } + } + } + } + + Image { + x: 97.5 + y: 20 + source: getWatchFaceImage("second.png") + transform: Rotation { + id: secondRotation + origin.x: 2.5 + origin.y: 80 + angle: clock.seconds * 6 + Behavior on angle { + SpringAnimation { + spring: 2 + damping: 0.2 + modulus: 360 + } + } + } + } + + Image { + anchors.centerIn: background + source: getWatchFaceImage("center.png") + } + + Text { + id: cityLabel + anchors.bottom: parent.bottom + anchors.bottomMargin: 2 + anchors.horizontalCenter: parent.horizontalCenter + + text: cityName + color: UIStyle.themeColorQtGray1 + font.pixelSize: UIStyle.fontSizeXS + font.letterSpacing: 2 + } + } +} diff --git a/examples/quickcontrols/wearable/qml/WorldClock/WorldClockPage.qml b/examples/quickcontrols/wearable/qml/WorldClock/WorldClockPage.qml new file mode 100644 index 0000000000..34a51da5cf --- /dev/null +++ b/examples/quickcontrols/wearable/qml/WorldClock/WorldClockPage.qml @@ -0,0 +1,60 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Controls as QQC2 +import "../Style" + +Item { + QQC2.SwipeView { + id: svWatchContainer + + anchors.fill: parent + + ListModel { + id: placesList + ListElement { + cityName: "New York" + timeShift: -4 + } + ListElement { + cityName: "London" + timeShift: 0 + } + ListElement { + cityName: "Oslo" + timeShift: 1 + } + ListElement { + cityName: "Mumbai" + timeShift: 5.5 + } + ListElement { + cityName: "Tokyo" + timeShift: 9 + } + ListElement { + cityName: "Brisbane" + timeShift: 10 + } + ListElement { + cityName: "Los Angeles" + timeShift: -8 + } + } + + Repeater { + model: placesList + delegate: Clock { + } + } + } + + QQC2.PageIndicator { + count: svWatchContainer.count + currentIndex: svWatchContainer.currentIndex + + anchors.bottom: svWatchContainer.bottom + anchors.horizontalCenter: parent.horizontalCenter + } +} diff --git a/examples/quickcontrols/wearable/qml/WorldClock/images/center.png b/examples/quickcontrols/wearable/qml/WorldClock/images/center.png Binary files differnew file mode 100644 index 0000000000..0dec43a0aa --- /dev/null +++ b/examples/quickcontrols/wearable/qml/WorldClock/images/center.png diff --git a/examples/quickcontrols/wearable/qml/WorldClock/images/center@2x.png b/examples/quickcontrols/wearable/qml/WorldClock/images/center@2x.png Binary files differnew file mode 100644 index 0000000000..dffc5d60e4 --- /dev/null +++ b/examples/quickcontrols/wearable/qml/WorldClock/images/center@2x.png diff --git a/examples/quickcontrols/wearable/qml/WorldClock/images/clock-night.png b/examples/quickcontrols/wearable/qml/WorldClock/images/clock-night.png Binary files differnew file mode 100644 index 0000000000..2de330243a --- /dev/null +++ b/examples/quickcontrols/wearable/qml/WorldClock/images/clock-night.png diff --git a/examples/quickcontrols/wearable/qml/WorldClock/images/clock-night@2x.png b/examples/quickcontrols/wearable/qml/WorldClock/images/clock-night@2x.png Binary files differnew file mode 100644 index 0000000000..f675acea69 --- /dev/null +++ b/examples/quickcontrols/wearable/qml/WorldClock/images/clock-night@2x.png diff --git a/examples/quickcontrols/wearable/qml/WorldClock/images/clock.png b/examples/quickcontrols/wearable/qml/WorldClock/images/clock.png Binary files differnew file mode 100644 index 0000000000..686fb8c2f7 --- /dev/null +++ b/examples/quickcontrols/wearable/qml/WorldClock/images/clock.png diff --git a/examples/quickcontrols/wearable/qml/WorldClock/images/second.png b/examples/quickcontrols/wearable/qml/WorldClock/images/second.png Binary files differnew file mode 100644 index 0000000000..1e64f357df --- /dev/null +++ b/examples/quickcontrols/wearable/qml/WorldClock/images/second.png diff --git a/examples/quickcontrols/wearable/qml/WorldClock/images/second@2x.png b/examples/quickcontrols/wearable/qml/WorldClock/images/second@2x.png Binary files differnew file mode 100644 index 0000000000..cebc1deb06 --- /dev/null +++ b/examples/quickcontrols/wearable/qml/WorldClock/images/second@2x.png diff --git a/examples/quickcontrols/wearable/qml/WorldClock/images/swissdaydial.png b/examples/quickcontrols/wearable/qml/WorldClock/images/swissdaydial.png Binary files differnew file mode 100644 index 0000000000..0e6321537a --- /dev/null +++ b/examples/quickcontrols/wearable/qml/WorldClock/images/swissdaydial.png diff --git a/examples/quickcontrols/wearable/qml/WorldClock/images/swissdaydial@2x.png b/examples/quickcontrols/wearable/qml/WorldClock/images/swissdaydial@2x.png Binary files differnew file mode 100644 index 0000000000..ed5de8c646 --- /dev/null +++ b/examples/quickcontrols/wearable/qml/WorldClock/images/swissdaydial@2x.png diff --git a/examples/quickcontrols/wearable/qml/WorldClock/images/swissdayhour.png b/examples/quickcontrols/wearable/qml/WorldClock/images/swissdayhour.png Binary files differnew file mode 100644 index 0000000000..4a835ac3f0 --- /dev/null +++ b/examples/quickcontrols/wearable/qml/WorldClock/images/swissdayhour.png diff --git a/examples/quickcontrols/wearable/qml/WorldClock/images/swissdayhour@2x.png b/examples/quickcontrols/wearable/qml/WorldClock/images/swissdayhour@2x.png Binary files differnew file mode 100644 index 0000000000..70f3fa0eee --- /dev/null +++ b/examples/quickcontrols/wearable/qml/WorldClock/images/swissdayhour@2x.png diff --git a/examples/quickcontrols/wearable/qml/WorldClock/images/swissdayminute.png b/examples/quickcontrols/wearable/qml/WorldClock/images/swissdayminute.png Binary files differnew file mode 100644 index 0000000000..048acc7b3f --- /dev/null +++ b/examples/quickcontrols/wearable/qml/WorldClock/images/swissdayminute.png diff --git a/examples/quickcontrols/wearable/qml/WorldClock/images/swissdayminute@2x.png b/examples/quickcontrols/wearable/qml/WorldClock/images/swissdayminute@2x.png Binary files differnew file mode 100644 index 0000000000..4cc6ce64b4 --- /dev/null +++ b/examples/quickcontrols/wearable/qml/WorldClock/images/swissdayminute@2x.png diff --git a/examples/quickcontrols/wearable/qml/WorldClock/images/swissnightdial.png b/examples/quickcontrols/wearable/qml/WorldClock/images/swissnightdial.png Binary files differnew file mode 100644 index 0000000000..ee5a15bb9b --- /dev/null +++ b/examples/quickcontrols/wearable/qml/WorldClock/images/swissnightdial.png diff --git a/examples/quickcontrols/wearable/qml/WorldClock/images/swissnightdial@2x.png b/examples/quickcontrols/wearable/qml/WorldClock/images/swissnightdial@2x.png Binary files differnew file mode 100644 index 0000000000..ec7e5c77dc --- /dev/null +++ b/examples/quickcontrols/wearable/qml/WorldClock/images/swissnightdial@2x.png diff --git a/examples/quickcontrols/wearable/qml/WorldClock/images/swissnighthour.png b/examples/quickcontrols/wearable/qml/WorldClock/images/swissnighthour.png Binary files differnew file mode 100644 index 0000000000..c5b41cb043 --- /dev/null +++ b/examples/quickcontrols/wearable/qml/WorldClock/images/swissnighthour.png diff --git a/examples/quickcontrols/wearable/qml/WorldClock/images/swissnighthour@2x.png b/examples/quickcontrols/wearable/qml/WorldClock/images/swissnighthour@2x.png Binary files differnew file mode 100644 index 0000000000..bbbc36f1d7 --- /dev/null +++ b/examples/quickcontrols/wearable/qml/WorldClock/images/swissnighthour@2x.png diff --git a/examples/quickcontrols/wearable/qml/WorldClock/images/swissnightminute.png b/examples/quickcontrols/wearable/qml/WorldClock/images/swissnightminute.png Binary files differnew file mode 100644 index 0000000000..026c742446 --- /dev/null +++ b/examples/quickcontrols/wearable/qml/WorldClock/images/swissnightminute.png diff --git a/examples/quickcontrols/wearable/qml/WorldClock/images/swissnightminute@2x.png b/examples/quickcontrols/wearable/qml/WorldClock/images/swissnightminute@2x.png Binary files differnew file mode 100644 index 0000000000..8ad69047a4 --- /dev/null +++ b/examples/quickcontrols/wearable/qml/WorldClock/images/swissnightminute@2x.png diff --git a/examples/quickcontrols/wearable/qml/WorldClock/images/swissseconds.png b/examples/quickcontrols/wearable/qml/WorldClock/images/swissseconds.png Binary files differnew file mode 100644 index 0000000000..06446ac0fe --- /dev/null +++ b/examples/quickcontrols/wearable/qml/WorldClock/images/swissseconds.png diff --git a/examples/quickcontrols/wearable/wearable.cpp b/examples/quickcontrols/wearable/wearable.cpp new file mode 100644 index 0000000000..861d4b7610 --- /dev/null +++ b/examples/quickcontrols/wearable/wearable.cpp @@ -0,0 +1,28 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#include <QGuiApplication> +#include <QQmlApplicationEngine> +#include <QQuickStyle> +#include <QIcon> + +int main(int argc, char *argv[]) +{ + QCoreApplication::setApplicationName("Wearable"); + QCoreApplication::setOrganizationName("QtProject"); + + QGuiApplication app(argc, argv); + + //! [style] + QQuickStyle::setStyle(QStringLiteral("qrc:/qml/Style")); + //! [style] + + //! [icons] + QIcon::setThemeName(QStringLiteral("wearable")); + //! [icons] + + QQmlApplicationEngine engine; + engine.load(QUrl(QStringLiteral("qrc:/wearable.qml"))); + + return app.exec(); +} diff --git a/examples/quickcontrols/wearable/wearable.pro b/examples/quickcontrols/wearable/wearable.pro new file mode 100644 index 0000000000..8d55e44eaa --- /dev/null +++ b/examples/quickcontrols/wearable/wearable.pro @@ -0,0 +1,12 @@ +TEMPLATE = app +TARGET = wearable +QT += quick quickcontrols2 + +SOURCES += \ + wearable.cpp + +RESOURCES += \ + wearable.qrc + +target.path = $$[QT_INSTALL_EXAMPLES]/quickcontrols2/wearable +INSTALLS += target diff --git a/examples/quickcontrols/wearable/wearable.qml b/examples/quickcontrols/wearable/wearable.qml new file mode 100644 index 0000000000..27887354dc --- /dev/null +++ b/examples/quickcontrols/wearable/wearable.qml @@ -0,0 +1,93 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtCore +import QtQuick +import QtQuick.Controls as QQC2 +import "qml" +import "qml/Style" + +QQC2.ApplicationWindow { + id: window + visible: true + width: 320 + height: 320 + title: qsTr("Wearable") + + Settings { + id: settings + property bool wireless + property bool bluetooth + property int brightness + property bool darkTheme + property bool demoMode + } + + Binding { + target: UIStyle + property: "darkTheme" + value: settings.darkTheme + } + + // We need the settings object both here and in SettingsPage, + // so for convenience, we declare it as a property of the root object so that + // it will be available to all of the QML files that we load. + property alias settings: settings + + background: Image { + source: "images/background-" + (settings.darkTheme ? "dark" : "light") + ".png" + } + + header: NaviButton { + id: homeButton + + edge: Qt.TopEdge + enabled: stackView.depth > 1 + imageSource: "images/home.png" + + onClicked: stackView.pop(null) + } + + footer: NaviButton { + id: backButton + + edge: Qt.BottomEdge + enabled: stackView.depth > 1 + imageSource: "images/back.png" + + onClicked: stackView.pop() + } + + QQC2.StackView { + id: stackView + + focus: true + anchors.fill: parent + + initialItem: LauncherPage { + onLaunched: stackView.push(page) + } + } + + DemoMode { + stackView: stackView + } + + DemoModeIndicator { + id: demoModeIndicator + y: settings.demoMode ? -height : -height * 2 + anchors.horizontalCenter: parent.horizontalCenter + height: header.height + z: window.header.z + 1 + } + + MouseArea { + enabled: settings.demoMode + anchors.fill: parent + onClicked: { + // Stop demo mode and return to the launcher page. + settings.demoMode = false + stackView.pop(null) + } + } +} diff --git a/examples/quickcontrols/wearable/wearable.qrc b/examples/quickcontrols/wearable/wearable.qrc new file mode 100644 index 0000000000..db59d038f6 --- /dev/null +++ b/examples/quickcontrols/wearable/wearable.qrc @@ -0,0 +1,155 @@ +<RCC> + <qresource prefix="/"> + <file>wearable.qml</file> + <file>qml/LauncherPage.qml</file> + <file>qml/NaviButton.qml</file> + <file>icons/wearable/index.theme</file> + <file>icons/wearable/36x36/alarms.png</file> + <file>icons/wearable/36x36/fitness.png</file> + <file>icons/wearable/36x36/navigation.png</file> + <file>icons/wearable/36x36/notifications.png</file> + <file>icons/wearable/36x36/settings.png</file> + <file>icons/wearable/36x36/weather.png</file> + <file>icons/wearable/36x36/worldclock.png</file> + <file>icons/wearable/36x36@2/alarms.png</file> + <file>icons/wearable/36x36@2/fitness.png</file> + <file>icons/wearable/36x36@2/navigation.png</file> + <file>icons/wearable/36x36@2/notifications.png</file> + <file>icons/wearable/36x36@2/settings.png</file> + <file>icons/wearable/36x36@2/weather.png</file> + <file>icons/wearable/36x36@2/worldclock.png</file> + <file>images/background-light.png</file> + <file>images/background-dark.png</file> + <file>images/back.png</file> + <file>images/back@2x.png</file> + <file>images/home.png</file> + <file>images/home@2x.png</file> + <file>qml/Alarms/AlarmsPage.qml</file> + <file>qml/Fitness/fitness.js</file> + <file>qml/Fitness/FitnessPage.qml</file> + <file>qml/Fitness/images/man-running-light.png</file> + <file>qml/Fitness/images/man-running-light@2x.png</file> + <file>qml/Fitness/images/man-walking-light.png</file> + <file>qml/Fitness/images/man-walking-light@2x.png</file> + <file>qml/Fitness/images/man-running-dark.png</file> + <file>qml/Fitness/images/man-running-dark@2x.png</file> + <file>qml/Fitness/images/man-walking-dark.png</file> + <file>qml/Fitness/images/man-walking-dark@2x.png</file> + <file>qml/Navigation/navigation.js</file> + <file>qml/Navigation/NavigationPage.qml</file> + <file>qml/Navigation/RouteElement.qml</file> + <file>qml/Navigation/walk_route.json</file> + <file>qml/Navigation/images/end.png</file> + <file>qml/Navigation/images/end@2x.png</file> + <file>qml/Navigation/images/leftturn-light.png</file> + <file>qml/Navigation/images/leftturn-light@2x.png</file> + <file>qml/Navigation/images/leftturn-dark.png</file> + <file>qml/Navigation/images/leftturn-dark@2x.png</file> + <file>qml/Navigation/images/navigation-light.png</file> + <file>qml/Navigation/images/navigation-light@2x.png</file> + <file>qml/Navigation/images/navigation-dark.png</file> + <file>qml/Navigation/images/navigation-dark@2x.png</file> + <file>qml/Navigation/images/rightturn-light.png</file> + <file>qml/Navigation/images/rightturn-light@2x.png</file> + <file>qml/Navigation/images/rightturn-dark.png</file> + <file>qml/Navigation/images/rightturn-dark@2x.png</file> + <file>qml/Navigation/images/start.png</file> + <file>qml/Navigation/images/start@2x.png</file> + <file>qml/Navigation/images/straight-light.png</file> + <file>qml/Navigation/images/straight-light@2x.png</file> + <file>qml/Navigation/images/straight-dark.png</file> + <file>qml/Navigation/images/straight-dark@2x.png</file> + <file>qml/Navigation/images/uturn.png</file> + <file>qml/Navigation/images/uturn@2x.png</file> + <file>qml/Notifications/notifications.js</file> + <file>qml/Notifications/NotificationsPage.qml</file> + <file>qml/Notifications/images/avatarf-light.png</file> + <file>qml/Notifications/images/avatarf-light@2x.png</file> + <file>qml/Notifications/images/avatarm-light.png</file> + <file>qml/Notifications/images/avatarm-light@2x.png</file> + <file>qml/Notifications/images/missedcall-light.png</file> + <file>qml/Notifications/images/missedcall-light@2x.png</file> + <file>qml/Notifications/images/avatarf-dark.png</file> + <file>qml/Notifications/images/avatarf-dark@2x.png</file> + <file>qml/Notifications/images/avatarm-dark.png</file> + <file>qml/Notifications/images/avatarm-dark@2x.png</file> + <file>qml/Notifications/images/missedcall-dark.png</file> + <file>qml/Notifications/images/missedcall-dark@2x.png</file> + <file>qml/Settings/SettingsPage.qml</file> + <file>qml/Settings/images/bluetooth-light.png</file> + <file>qml/Settings/images/bluetooth-light@2x.png</file> + <file>qml/Settings/images/brightness-light.png</file> + <file>qml/Settings/images/brightness-light@2x.png</file> + <file>qml/Settings/images/demo-mode-light.png</file> + <file>qml/Settings/images/demo-mode-light@2x.png</file> + <file>qml/Settings/images/demo-mode-dark.png</file> + <file>qml/Settings/images/demo-mode-dark@2x.png</file> + <file>qml/Settings/images/demo-mode-white.png</file> + <file>qml/Settings/images/demo-mode-white@2x.png</file> + <file>qml/Settings/images/theme-light.png</file> + <file>qml/Settings/images/theme-light@2x.png</file> + <file>qml/Settings/images/wifi-light.png</file> + <file>qml/Settings/images/wifi-light@2x.png</file> + <file>qml/Settings/images/bluetooth-dark.png</file> + <file>qml/Settings/images/bluetooth-dark@2x.png</file> + <file>qml/Settings/images/brightness-dark.png</file> + <file>qml/Settings/images/brightness-dark@2x.png</file> + <file>qml/Settings/images/theme-dark.png</file> + <file>qml/Settings/images/theme-dark@2x.png</file> + <file>qml/Settings/images/wifi-dark.png</file> + <file>qml/Settings/images/wifi-dark@2x.png</file> + <file>qml/Style/qmldir</file> + <file>qml/Style/PageIndicator.qml</file> + <file>qml/Style/Slider.qml</file> + <file>qml/Style/Switch.qml</file> + <file>qml/Style/UIStyle.qml</file> + <file>qml/Weather/weather.js</file> + <file>qml/Weather/weather.json</file> + <file>qml/Weather/WeatherPage.qml</file> + <file>qml/Weather/images/humidity-light.png</file> + <file>qml/Weather/images/humidity-light@2x.png</file> + <file>qml/Weather/images/pressure-light.png</file> + <file>qml/Weather/images/pressure-light@2x.png</file> + <file>qml/Weather/images/sunrise-light.png</file> + <file>qml/Weather/images/sunrise-light@2x.png</file> + <file>qml/Weather/images/sunset-light.png</file> + <file>qml/Weather/images/sunset-light@2x.png</file> + <file>qml/Weather/images/temperature-light.png</file> + <file>qml/Weather/images/temperature-light@2x.png</file> + <file>qml/Weather/images/wind-light.png</file> + <file>qml/Weather/images/wind-light@2x.png</file> + <file>qml/Weather/images/humidity-dark.png</file> + <file>qml/Weather/images/humidity-dark@2x.png</file> + <file>qml/Weather/images/pressure-dark.png</file> + <file>qml/Weather/images/pressure-dark@2x.png</file> + <file>qml/Weather/images/sunrise-dark.png</file> + <file>qml/Weather/images/sunrise-dark@2x.png</file> + <file>qml/Weather/images/sunset-dark.png</file> + <file>qml/Weather/images/sunset-dark@2x.png</file> + <file>qml/Weather/images/temperature-dark.png</file> + <file>qml/Weather/images/temperature-dark@2x.png</file> + <file>qml/Weather/images/wind-dark.png</file> + <file>qml/Weather/images/wind-dark@2x.png</file> + <file>qml/WorldClock/Clock.qml</file> + <file>qml/WorldClock/WorldClockPage.qml</file> + <file>qml/WorldClock/images/center.png</file> + <file>qml/WorldClock/images/center@2x.png</file> + <file>qml/WorldClock/images/second.png</file> + <file>qml/WorldClock/images/second@2x.png</file> + <file>qml/WorldClock/images/swissdaydial.png</file> + <file>qml/WorldClock/images/swissdaydial@2x.png</file> + <file>qml/WorldClock/images/swissdayhour.png</file> + <file>qml/WorldClock/images/swissdayhour@2x.png</file> + <file>qml/WorldClock/images/swissdayminute.png</file> + <file>qml/WorldClock/images/swissdayminute@2x.png</file> + <file>qml/WorldClock/images/swissnightdial.png</file> + <file>qml/WorldClock/images/swissnightdial@2x.png</file> + <file>qml/WorldClock/images/swissnighthour.png</file> + <file>qml/WorldClock/images/swissnighthour@2x.png</file> + <file>qml/WorldClock/images/swissnightminute.png</file> + <file>qml/WorldClock/images/swissnightminute@2x.png</file> + <file>qml/SwipeViewPage.qml</file> + <file>qml/DemoMode.qml</file> + <file>qml/DemoModeIndicator.qml</file> + </qresource> +</RCC> |