aboutsummaryrefslogtreecommitdiffstats
path: root/examples/quickcontrols/attachedstyleproperties/MyStyle
diff options
context:
space:
mode:
Diffstat (limited to 'examples/quickcontrols/attachedstyleproperties/MyStyle')
-rw-r--r--examples/quickcontrols/attachedstyleproperties/MyStyle/ApplicationWindow.qml17
-rw-r--r--examples/quickcontrols/attachedstyleproperties/MyStyle/Button.qml33
-rw-r--r--examples/quickcontrols/attachedstyleproperties/MyStyle/CMakeLists.txt45
-rw-r--r--examples/quickcontrols/attachedstyleproperties/MyStyle/Label.qml11
-rw-r--r--examples/quickcontrols/attachedstyleproperties/MyStyle/Popup.qml48
-rw-r--r--examples/quickcontrols/attachedstyleproperties/MyStyle/Switch.qml58
-rw-r--r--examples/quickcontrols/attachedstyleproperties/MyStyle/ToolBar.qml24
-rw-r--r--examples/quickcontrols/attachedstyleproperties/MyStyle/mystyle.cpp136
-rw-r--r--examples/quickcontrols/attachedstyleproperties/MyStyle/mystyle.h76
9 files changed, 448 insertions, 0 deletions
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