diff options
Diffstat (limited to 'src/quickcontrols/fusion')
85 files changed, 3986 insertions, 0 deletions
diff --git a/src/quickcontrols/fusion/ApplicationWindow.qml b/src/quickcontrols/fusion/ApplicationWindow.qml new file mode 100644 index 0000000000..fbd1cc2e76 --- /dev/null +++ b/src/quickcontrols/fusion/ApplicationWindow.qml @@ -0,0 +1,14 @@ +// Copyright (C) 2017 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.Templates as T +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.ApplicationWindow { + id: window + + color: window.palette.window +} diff --git a/src/quickcontrols/fusion/BusyIndicator.qml b/src/quickcontrols/fusion/BusyIndicator.qml new file mode 100644 index 0000000000..8de02b6aea --- /dev/null +++ b/src/quickcontrols/fusion/BusyIndicator.qml @@ -0,0 +1,37 @@ +// Copyright (C) 2017 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.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.BusyIndicator { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + padding: 6 + + contentItem: BusyIndicatorImpl { + implicitWidth: 28 + implicitHeight: 28 + color: control.palette.text + + running: control.running + opacity: control.running ? 1 : 0 + Behavior on opacity { OpacityAnimator { duration: 250 } } + + RotationAnimator on rotation { + running: control.running && control.contentItem.visible + from: 0 + to: 360 + duration: 1000 + loops: Animation.Infinite + } + } +} diff --git a/src/quickcontrols/fusion/Button.qml b/src/quickcontrols/fusion/Button.qml new file mode 100644 index 0000000000..2ee8e12373 --- /dev/null +++ b/src/quickcontrols/fusion/Button.qml @@ -0,0 +1,43 @@ +// Copyright (C) 2017 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.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.Button { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + padding: 4 + spacing: 6 + + icon.width: 16 + icon.height: 16 + + contentItem: IconLabel { + spacing: control.spacing + mirrored: control.mirrored + display: control.display + + icon: control.icon + text: control.text + font: control.font + color: control.palette.buttonText + } + + background: ButtonPanel { + implicitWidth: 80 + implicitHeight: 24 + + control: control + visible: !control.flat || control.down || control.checked || control.highlighted || control.visualFocus + || (enabled && control.hovered) + } +} diff --git a/src/quickcontrols/fusion/CMakeLists.txt b/src/quickcontrols/fusion/CMakeLists.txt new file mode 100644 index 0000000000..572a3cf931 --- /dev/null +++ b/src/quickcontrols/fusion/CMakeLists.txt @@ -0,0 +1,162 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +##################################################################### +## qtquickcontrols2fusionstyleplugin Plugin: +##################################################################### + +set(qml_files + "ApplicationWindow.qml" + "BusyIndicator.qml" + "Button.qml" + "CheckBox.qml" + "CheckDelegate.qml" + "ComboBox.qml" + "DelayButton.qml" + "Dial.qml" + "Dialog.qml" + "DialogButtonBox.qml" + "Drawer.qml" + "Frame.qml" + "GroupBox.qml" + "HorizontalHeaderView.qml" + "ItemDelegate.qml" + "Label.qml" + "Menu.qml" + "MenuBar.qml" + "MenuBarItem.qml" + "MenuItem.qml" + "MenuSeparator.qml" + "Page.qml" + "PageIndicator.qml" + "Pane.qml" + "Popup.qml" + "ProgressBar.qml" + "RadioButton.qml" + "RadioDelegate.qml" + "RangeSlider.qml" + "RoundButton.qml" + "ScrollBar.qml" + "ScrollView.qml" + "ScrollIndicator.qml" + "SelectionRectangle.qml" + "Slider.qml" + "SpinBox.qml" + "SplitView.qml" + "SwipeDelegate.qml" + "SwitchDelegate.qml" + "Switch.qml" + "TabBar.qml" + "TabButton.qml" + "TextArea.qml" + "TextField.qml" + "ToolBar.qml" + "ToolButton.qml" + "ToolSeparator.qml" + "ToolTip.qml" + "TreeViewDelegate.qml" + "Tumbler.qml" + "VerticalHeaderView.qml" +) +set_source_files_properties(DelayButton.qml PROPERTIES + QT_QML_SOURCE_VERSIONS "2.2;6.0" +) +set_source_files_properties(Dialog.qml PROPERTIES + QT_QML_SOURCE_VERSIONS "2.1;6.0" +) +set_source_files_properties(DialogButtonBox.qml PROPERTIES + QT_QML_SOURCE_VERSIONS "2.1;6.0" +) +set_source_files_properties(HorizontalHeaderView.qml PROPERTIES + QT_QML_SOURCE_VERSIONS "2.15;6.0" +) +set_source_files_properties(MenuBar.qml PROPERTIES + QT_QML_SOURCE_VERSIONS "2.3;6.0" +) +set_source_files_properties(MenuBarItem.qml PROPERTIES + QT_QML_SOURCE_VERSIONS "2.3;6.0" +) +set_source_files_properties(MenuSeparator.qml PROPERTIES + QT_QML_SOURCE_VERSIONS "2.1;6.0" +) +set_source_files_properties(RoundButton.qml PROPERTIES + QT_QML_SOURCE_VERSIONS "2.1;6.0" +) +set_source_files_properties(SplitView.qml PROPERTIES + QT_QML_SOURCE_VERSIONS "2.13;6.0" +) +set_source_files_properties(ToolSeparator.qml PROPERTIES + QT_QML_SOURCE_VERSIONS "2.1;6.0" +) +set_source_files_properties(VerticalHeaderView.qml PROPERTIES + QT_QML_SOURCE_VERSIONS "2.15;6.0" +) + +add_subdirectory(impl) + +qt_internal_add_qml_module(QuickControls2Fusion + URI "QtQuick.Controls.Fusion" + VERSION "${PROJECT_VERSION}" + PAST_MAJOR_VERSIONS 2 + CLASS_NAME QtQuickControls2FusionStylePlugin + DEPENDENCIES + QtQuick/auto + IMPORTS + QtQuick.Controls.Basic/auto + PLUGIN_TARGET qtquickcontrols2fusionstyleplugin + NO_PLUGIN_OPTIONAL + NO_GENERATE_PLUGIN_SOURCE + SOURCES + qquickfusionstyle.cpp qquickfusionstyle_p.h + qquickfusiontheme.cpp qquickfusiontheme_p.h + QML_FILES + ${qml_files} + DEFINES + QT_NO_CAST_FROM_ASCII + QT_NO_CAST_TO_ASCII + LIBRARIES + Qt::CorePrivate + Qt::GuiPrivate + Qt::QmlPrivate + Qt::QuickControls2FusionStyleImpl + Qt::QuickControls2Private + Qt::QuickPrivate + Qt::QuickTemplates2Private + GENERATE_CPP_EXPORTS +) + +target_sources(qtquickcontrols2fusionstyleplugin + PRIVATE + qtquickcontrols2fusionstyleplugin.cpp +) + +target_link_libraries(qtquickcontrols2fusionstyleplugin + PRIVATE + Qt::QuickControls2Private +) + +qt_internal_add_resource(QuickControls2Fusion "qtquickcontrols2fusionstyle" + PREFIX + "/qt-project.org/imports/QtQuick/Controls/Fusion" + FILES + "images/arrow.png" + "images/arrow@2x.png" + "images/arrow@3x.png" + "images/arrow@4x.png" + "images/checkmark.png" + "images/checkmark@2x.png" + "images/checkmark@3x.png" + "images/checkmark@4x.png" + "images/progressmask.png" + "images/progressmask@2x.png" + "images/progressmask@3x.png" + "images/progressmask@4x.png" +) + +_qt_internal_add_qml_static_plugin_dependency(qtquickcontrols2fusionstyleplugin quickwindow) +_qt_internal_add_qml_static_plugin_dependency(qtquickcontrols2fusionstyleplugin + qtquickcontrols2fusionstyleimplplugin) + +# Basic style is the required fallback style. +_qt_internal_add_qml_static_plugin_dependency(qtquickcontrols2fusionstyleplugin + qtquickcontrols2basicstyleplugin) diff --git a/src/quickcontrols/fusion/CheckBox.qml b/src/quickcontrols/fusion/CheckBox.qml new file mode 100644 index 0000000000..414414804d --- /dev/null +++ b/src/quickcontrols/fusion/CheckBox.qml @@ -0,0 +1,38 @@ +// Copyright (C) 2017 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.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.CheckBox { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + padding: 6 + spacing: 6 + + indicator: CheckIndicator { + 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 + control: control + } + + 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.palette.windowText + elide: Text.ElideRight + verticalAlignment: Text.AlignVCenter + } +} diff --git a/src/quickcontrols/fusion/CheckDelegate.qml b/src/quickcontrols/fusion/CheckDelegate.qml new file mode 100644 index 0000000000..f14deaa16a --- /dev/null +++ b/src/quickcontrols/fusion/CheckDelegate.qml @@ -0,0 +1,53 @@ +// Copyright (C) 2017 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.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.CheckDelegate { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + padding: 6 + spacing: 6 + + icon.width: 16 + icon.height: 16 + + contentItem: IconLabel { + leftPadding: control.mirrored ? control.indicator.width + control.spacing : 0 + rightPadding: !control.mirrored ? control.indicator.width + control.spacing : 0 + + spacing: control.spacing + mirrored: control.mirrored + display: control.display + alignment: control.display === IconLabel.IconOnly || control.display === IconLabel.TextUnderIcon ? Qt.AlignCenter : Qt.AlignLeft + + icon: control.icon + text: control.text + font: control.font + color: control.highlighted ? Fusion.highlightedText(control.palette) : control.palette.text + } + + indicator: CheckIndicator { + x: control.mirrored ? control.leftPadding : control.width - width - control.rightPadding + y: control.topPadding + (control.availableHeight - height) / 2 + + control: control + } + + background: Rectangle { + implicitWidth: 100 + implicitHeight: 20 + color: control.down ? Fusion.buttonColor(control.palette, false, true, true) + : control.highlighted ? Fusion.highlight(control.palette) : control.palette.base + } +} diff --git a/src/quickcontrols/fusion/ComboBox.qml b/src/quickcontrols/fusion/ComboBox.qml new file mode 100644 index 0000000000..55d91e65ed --- /dev/null +++ b/src/quickcontrols/fusion/ComboBox.qml @@ -0,0 +1,146 @@ +// Copyright (C) 2017 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 ComponentBehavior: Bound + +import QtQuick +import QtQuick.Window +import QtQuick.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.ComboBox { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + leftPadding: padding + (!control.mirrored || !indicator || !indicator.visible ? 0 : indicator.width + spacing) + rightPadding: padding + (control.mirrored || !indicator || !indicator.visible ? 0 : indicator.width + spacing) + + delegate: MenuItem { + required property var model + required property int index + + width: ListView.view.width + text: model[control.textRole] + font.weight: control.currentIndex === index ? Font.DemiBold : Font.Normal + highlighted: control.highlightedIndex === index + hoverEnabled: control.hoverEnabled + } + + indicator: ColorImage { + x: control.mirrored ? control.padding : control.width - width - control.padding + y: control.topPadding + (control.availableHeight - height) / 2 + color: control.editable ? control.palette.text : control.palette.buttonText + source: "qrc:/qt-project.org/imports/QtQuick/Controls/Fusion/images/arrow.png" + width: 20 + fillMode: Image.Pad + } + + contentItem: T.TextField { + topPadding: 4 + leftPadding: 4 - control.padding + rightPadding: 4 - control.padding + bottomPadding: 4 + + text: control.editable ? control.editText : control.displayText + + enabled: control.editable + autoScroll: control.editable + readOnly: control.down + inputMethodHints: control.inputMethodHints + validator: control.validator + selectByMouse: control.selectTextByMouse + + color: control.editable ? control.palette.text : control.palette.buttonText + selectionColor: control.palette.highlight + selectedTextColor: control.palette.highlightedText + verticalAlignment: Text.AlignVCenter + + background: PaddedRectangle { + clip: true + radius: 2 + padding: 1 + leftPadding: control.mirrored ? -2 : padding + rightPadding: !control.mirrored ? -2 : padding + color: control.palette.base + visible: control.editable && !control.flat + + Rectangle { + x: parent.width - width + y: 1 + width: 1 + height: parent.height - 2 + color: Fusion.buttonOutline(control.palette, control.activeFocus, control.enabled) + } + + Rectangle { + x: 1 + y: 1 + width: parent.width - 3 + height: 1 + color: Fusion.topShadow + } + } + + Rectangle { + x: 1 - control.leftPadding + y: 1 + width: control.width - 2 + height: control.height - 2 + color: "transparent" + border.color: Color.transparent(Fusion.highlightedOutline(control.palette), 40 / 255) + visible: control.activeFocus + radius: 1.7 + } + } + + background: ButtonPanel { + implicitWidth: 120 + implicitHeight: 24 + + control: control + visible: !control.flat || control.down + // ### TODO: fix control.contentItem.activeFocus + highlighted: control.visualFocus || control.contentItem.activeFocus + } + + popup: T.Popup { + width: control.width + height: Math.min(contentItem.implicitHeight + 2, control.Window.height - topMargin - bottomMargin) + topMargin: 6 + bottomMargin: 6 + padding: 1 + palette: control.palette + + contentItem: ListView { + clip: true + implicitHeight: contentHeight + model: control.delegateModel + currentIndex: control.highlightedIndex + highlightRangeMode: ListView.ApplyRange + highlightMoveDuration: 0 + + T.ScrollBar.vertical: ScrollBar { } + } + + background: Rectangle { + color: palette.window + border.color: Fusion.outline(palette) + + Rectangle { + z: -1 + x: 1; y: 1 + width: parent.width + height: parent.height + color: palette.shadow + opacity: 0.2 + } + } + } +} diff --git a/src/quickcontrols/fusion/DelayButton.qml b/src/quickcontrols/fusion/DelayButton.qml new file mode 100644 index 0000000000..8dde74f468 --- /dev/null +++ b/src/quickcontrols/fusion/DelayButton.qml @@ -0,0 +1,82 @@ +// Copyright (C) 2017 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.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.DelayButton { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + padding: 6 + + transition: Transition { + NumberAnimation { + duration: control.delay * (control.pressed ? 1.0 - control.progress : 0.3 * control.progress) + } + } + + contentItem: ItemGroup { + ClippedText { + clip: control.progress > 0 + clipX: -control.leftPadding + (control.mirrored ? 0 : control.progress * control.width) + clipWidth: control.width + visible: control.mirrored ? control.progress > 0 : control.progress < 1 + + text: control.text + font: control.font + color: control.mirrored ? control.palette.brightText : control.palette.buttonText + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + elide: Text.ElideRight + } + + ClippedText { + clip: control.progress > 0 + clipX: -control.leftPadding + clipWidth: (control.mirrored ? 1.0 - control.progress : control.progress) * control.width + visible: control.mirrored ? control.progress < 1 : control.progress > 0 + + text: control.text + font: control.font + color: control.mirrored ? control.palette.buttonText : control.palette.brightText + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + elide: Text.ElideRight + } + } + + background: ButtonPanel { + implicitWidth: 80 + implicitHeight: 24 + + control: control + highlighted: false + scale: control.mirrored ? -1 : 1 + + Rectangle { + width: control.progress * parent.width + height: parent.height + + radius: 2 + border.color: Qt.darker(Fusion.highlight(control.palette), 1.4) + gradient: Gradient { + GradientStop { + position: 0 + color: Qt.lighter(Fusion.highlight(control.palette), 1.2) + } + GradientStop { + position: 1 + color: Fusion.highlight(control.palette) + } + } + } + } +} diff --git a/src/quickcontrols/fusion/Dial.qml b/src/quickcontrols/fusion/Dial.qml new file mode 100644 index 0000000000..6efd2581c3 --- /dev/null +++ b/src/quickcontrols/fusion/Dial.qml @@ -0,0 +1,41 @@ +// Copyright (C) 2017 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.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.Dial { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + background: DialImpl { + implicitWidth: 100 + implicitHeight: 100 + highlight: control.visualFocus + } + + handle: KnobImpl { + x: control.background.x + control.background.width / 2 - width / 2 + y: control.background.y + control.background.height / 2 - height / 2 + width: control.width / 7 + height: control.height / 7 + transform: [ + Translate { + y: -Math.min(control.background.width, control.background.height) * 0.35 + + (control.handle ? control.handle.height / 2 : 0) + }, + Rotation { + angle: control.angle + origin.x: control.handle ? control.handle.width / 2 : 0 + origin.y: control.handle ? control.handle.height / 2 : 0 + } + ] + } +} diff --git a/src/quickcontrols/fusion/Dialog.qml b/src/quickcontrols/fusion/Dialog.qml new file mode 100644 index 0000000000..f17321bcc0 --- /dev/null +++ b/src/quickcontrols/fusion/Dialog.qml @@ -0,0 +1,66 @@ +// Copyright (C) 2017 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.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.Dialog { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding, + implicitHeaderWidth, + implicitFooterWidth) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding + + (implicitHeaderHeight > 0 ? implicitHeaderHeight + spacing : 0) + + (implicitFooterHeight > 0 ? implicitFooterHeight + spacing : 0)) + + padding: 6 + + background: Rectangle { + color: control.palette.window + border.color: control.palette.mid + radius: 2 + + Rectangle { + z: -1 + x: 1; y: 1 + width: parent.width + height: parent.height + color: control.palette.shadow + opacity: 0.2 + radius: 2 + } + } + + header: Label { + text: control.title + visible: control.title + elide: Label.ElideRight + font.bold: true + padding: 6 + background: Rectangle { + x: 1; y: 1 + width: parent.width - 2 + height: parent.height - 1 + color: control.palette.window + radius: 2 + } + } + + footer: DialogButtonBox { + visible: count > 0 + } + + T.Overlay.modal: Rectangle { + color: Fusion.topShadow + } + + T.Overlay.modeless: Rectangle { + color: Fusion.topShadow + } +} diff --git a/src/quickcontrols/fusion/DialogButtonBox.qml b/src/quickcontrols/fusion/DialogButtonBox.qml new file mode 100644 index 0000000000..566058fa73 --- /dev/null +++ b/src/quickcontrols/fusion/DialogButtonBox.qml @@ -0,0 +1,41 @@ +// Copyright (C) 2017 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.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.DialogButtonBox { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + spacing: 6 + padding: 6 + alignment: Qt.AlignRight + + delegate: Button { } + + contentItem: ListView { + implicitWidth: contentWidth + model: control.contentModel + spacing: control.spacing + orientation: ListView.Horizontal + boundsBehavior: Flickable.StopAtBounds + snapMode: ListView.SnapToItem + } + + background: Rectangle { + implicitHeight: 32 + x: 1; y: 1 + width: parent.width - 2 + height: parent.height - 2 + color: control.palette.window + radius: 2 + } +} diff --git a/src/quickcontrols/fusion/Drawer.qml b/src/quickcontrols/fusion/Drawer.qml new file mode 100644 index 0000000000..713ac0c076 --- /dev/null +++ b/src/quickcontrols/fusion/Drawer.qml @@ -0,0 +1,55 @@ +// Copyright (C) 2017 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.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.Drawer { + id: control + + parent: T.Overlay.overlay + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + topPadding: control.edge === Qt.BottomEdge + leftPadding: control.edge === Qt.RightEdge + rightPadding: control.edge === Qt.LeftEdge + bottomPadding: control.edge === Qt.TopEdge + + enter: Transition { SmoothedAnimation { velocity: 5 } } + exit: Transition { SmoothedAnimation { velocity: 5 } } + + background: Rectangle { + color: control.palette.window + readonly property bool horizontal: control.edge === Qt.LeftEdge || control.edge === Qt.RightEdge + Rectangle { + width: parent.horizontal ? 1 : parent.width + height: parent.horizontal ? parent.height : 1 + color: control.palette.mid + x: control.edge === Qt.LeftEdge ? parent.width - 1 : 0 + y: control.edge === Qt.TopEdge ? parent.height - 1 : 0 + } + Rectangle { + width: parent.horizontal ? 1 : parent.width + height: parent.horizontal ? parent.height : 1 + color: control.palette.shadow + opacity: 0.2 + x: control.edge === Qt.LeftEdge ? parent.width : 0 + y: control.edge === Qt.TopEdge ? parent.height : 0 + } + } + + T.Overlay.modal: Rectangle { + color: Fusion.topShadow + } + + T.Overlay.modeless: Rectangle { + color: Fusion.topShadow + } +} diff --git a/src/quickcontrols/fusion/Frame.qml b/src/quickcontrols/fusion/Frame.qml new file mode 100644 index 0000000000..0512639f4e --- /dev/null +++ b/src/quickcontrols/fusion/Frame.qml @@ -0,0 +1,24 @@ +// Copyright (C) 2017 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.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.Frame { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + padding: 9 + + background: Rectangle { + color: "transparent" + border.color: Qt.lighter(Fusion.outline(control.palette), 1.08) + } +} diff --git a/src/quickcontrols/fusion/GroupBox.qml b/src/quickcontrols/fusion/GroupBox.qml new file mode 100644 index 0000000000..5e949dc5cb --- /dev/null +++ b/src/quickcontrols/fusion/GroupBox.qml @@ -0,0 +1,43 @@ +// Copyright (C) 2017 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.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.GroupBox { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding, + implicitLabelWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + spacing: 6 + padding: 9 + topPadding: padding + (implicitLabelWidth > 0 ? implicitLabelHeight + spacing : 0) + + label: Text { + x: control.leftPadding + width: control.availableWidth + + text: control.title + font: control.font + color: control.palette.windowText + elide: Text.ElideRight + verticalAlignment: Text.AlignVCenter + } + + background: Rectangle { + y: control.topPadding - control.bottomPadding + width: parent.width + height: parent.height - control.topPadding + control.bottomPadding + + radius: 2 + color: Color.transparent("black", 3 / 255) + border.color: Qt.lighter(Fusion.outline(control.palette), 1.08) + } +} diff --git a/src/quickcontrols/fusion/HorizontalHeaderView.qml b/src/quickcontrols/fusion/HorizontalHeaderView.qml new file mode 100644 index 0000000000..dbea743aca --- /dev/null +++ b/src/quickcontrols/fusion/HorizontalHeaderView.qml @@ -0,0 +1,53 @@ +// Copyright (C) 2020 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 ComponentBehavior: Bound + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Fusion.impl + +T.HorizontalHeaderView { + id: control + + implicitWidth: syncView ? syncView.width : 0 + // The contentHeight of TableView will be zero at start-up, until the delegate + // items have been loaded. This means that even if the implicit height of + // HorizontalHeaderView should be the same as the content height in the end, we + // need to ensure that it has at least a height of 1 at start-up, otherwise + // TableView won't bother loading any delegates at all. + implicitHeight: Math.max(1, contentHeight) + + delegate: Rectangle { + id: delegate + + required property var model + + // Qt6: add cellPadding (and font etc) as public API in headerview + readonly property real cellPadding: 8 + + implicitWidth: text.implicitWidth + (cellPadding * 2) + implicitHeight: Math.max(control.height, text.implicitHeight + (cellPadding * 2)) + + gradient: Gradient { + id: buttonGradient + GradientStop { + position: 0 + color: Fusion.gradientStart(control.palette.button) + } + GradientStop { + position: 1 + color: Fusion.gradientStop(control.palette.button) + } + } + + Label { + id: text + text: delegate.model[control.textRole] + width: delegate.width + height: delegate.height + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + } +} diff --git a/src/quickcontrols/fusion/ItemDelegate.qml b/src/quickcontrols/fusion/ItemDelegate.qml new file mode 100644 index 0000000000..5a3e9c45ea --- /dev/null +++ b/src/quickcontrols/fusion/ItemDelegate.qml @@ -0,0 +1,43 @@ +// Copyright (C) 2017 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.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.ItemDelegate { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + padding: 6 + spacing: 6 + + icon.width: 16 + icon.height: 16 + + contentItem: IconLabel { + spacing: control.spacing + mirrored: control.mirrored + display: control.display + alignment: control.display === IconLabel.IconOnly || control.display === IconLabel.TextUnderIcon ? Qt.AlignCenter : Qt.AlignLeft + + icon: control.icon + text: control.text + font: control.font + color: control.highlighted ? Fusion.highlightedText(control.palette) : control.palette.text + } + + background: Rectangle { + implicitWidth: 100 + implicitHeight: 20 + color: control.down ? Fusion.buttonColor(control.palette, false, true, true) + : control.highlighted ? Fusion.highlight(control.palette) : control.palette.base + } +} diff --git a/src/quickcontrols/fusion/Label.qml b/src/quickcontrols/fusion/Label.qml new file mode 100644 index 0000000000..9a715d9ed8 --- /dev/null +++ b/src/quickcontrols/fusion/Label.qml @@ -0,0 +1,15 @@ +// Copyright (C) 2017 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.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.Label { + id: control + + color: control.palette.windowText + linkColor: control.palette.link +} diff --git a/src/quickcontrols/fusion/Menu.qml b/src/quickcontrols/fusion/Menu.qml new file mode 100644 index 0000000000..bfd1feddb6 --- /dev/null +++ b/src/quickcontrols/fusion/Menu.qml @@ -0,0 +1,61 @@ +// Copyright (C) 2017 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.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl +import QtQuick.Window + +T.Menu { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + margins: 0 + padding: 1 + overlap: 2 + + delegate: MenuItem { } + + contentItem: ListView { + implicitHeight: contentHeight + model: control.contentModel + interactive: Window.window + ? contentHeight + control.topPadding + control.bottomPadding > control.height + : false + clip: true + currentIndex: control.currentIndex + + ScrollIndicator.vertical: ScrollIndicator {} + } + + background: Rectangle { + implicitWidth: 200 + implicitHeight: 20 + + color: control.palette.base + border.color: Fusion.outline(control.palette) + + Rectangle { + z: -1 + x: 1; y: 1 + width: parent.width + height: parent.height + color: control.palette.shadow + opacity: 0.2 + } + } + + T.Overlay.modal: Rectangle { + color: Fusion.topShadow + } + + T.Overlay.modeless: Rectangle { + color: Fusion.topShadow + } +} diff --git a/src/quickcontrols/fusion/MenuBar.qml b/src/quickcontrols/fusion/MenuBar.qml new file mode 100644 index 0000000000..6e039d8a3e --- /dev/null +++ b/src/quickcontrols/fusion/MenuBar.qml @@ -0,0 +1,40 @@ +// Copyright (C) 2017 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.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.MenuBar { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + delegate: MenuBarItem { } + + contentItem: Row { + spacing: control.spacing + Repeater { + model: control.contentModel + } + } + + background: Rectangle { + implicitHeight: 20 + + color: control.palette.window + + Rectangle { + y: parent.height - height + width: parent.width + height: 1 + color: Fusion.mergedColors(Qt.darker(control.palette.window, 1.2), + Qt.lighter(Fusion.outline(control.palette), 1.4), 60) + } + } +} diff --git a/src/quickcontrols/fusion/MenuBarItem.qml b/src/quickcontrols/fusion/MenuBarItem.qml new file mode 100644 index 0000000000..299c34416b --- /dev/null +++ b/src/quickcontrols/fusion/MenuBarItem.qml @@ -0,0 +1,44 @@ +// Copyright (C) 2017 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.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.MenuBarItem { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + padding: 6 + spacing: 6 + + icon.width: 16 + icon.height: 16 + + contentItem: IconLabel { + spacing: control.spacing + mirrored: control.mirrored + display: control.display + alignment: Qt.AlignLeft + + icon: control.icon + text: control.text + font: control.font + color: control.down || control.highlighted ? Fusion.highlightedText(control.palette) : control.palette.text + } + + background: Rectangle { + implicitWidth: 20 + implicitHeight: 20 + + color: Fusion.highlight(control.palette) + visible: control.down || control.highlighted + } +} diff --git a/src/quickcontrols/fusion/MenuItem.qml b/src/quickcontrols/fusion/MenuItem.qml new file mode 100644 index 0000000000..ce701b74f4 --- /dev/null +++ b/src/quickcontrols/fusion/MenuItem.qml @@ -0,0 +1,69 @@ +// Copyright (C) 2017 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.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.MenuItem { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + padding: 6 + spacing: 6 + + icon.width: 16 + icon.height: 16 + + contentItem: IconLabel { + readonly property real arrowPadding: control.subMenu && control.arrow ? control.arrow.width + control.spacing : 0 + readonly property real indicatorPadding: control.checkable && control.indicator ? control.indicator.width + control.spacing : 0 + leftPadding: !control.mirrored ? indicatorPadding : arrowPadding + rightPadding: control.mirrored ? indicatorPadding : arrowPadding + + spacing: control.spacing + mirrored: control.mirrored + display: control.display + alignment: Qt.AlignLeft + + icon: control.icon + text: control.text + font: control.font + color: control.down || control.highlighted ? Fusion.highlightedText(control.palette) : control.palette.text + } + + arrow: ColorImage { + x: control.mirrored ? control.padding : control.width - width - control.padding + y: control.topPadding + (control.availableHeight - height) / 2 + width: 20 + + visible: control.subMenu + rotation: control.mirrored ? 90 : -90 + color: control.down || control.hovered || control.highlighted ? Fusion.highlightedText(control.palette) : control.palette.text + source: "qrc:/qt-project.org/imports/QtQuick/Controls/Fusion/images/arrow.png" + fillMode: Image.Pad + } + + indicator: CheckIndicator { + x: control.mirrored ? control.width - width - control.rightPadding : control.leftPadding + y: control.topPadding + (control.availableHeight - height) / 2 + + control: control + visible: control.checkable + } + + background: Rectangle { + implicitWidth: 200 + implicitHeight: 20 + + color: Fusion.highlight(control.palette) + visible: control.down || control.highlighted + } +} diff --git a/src/quickcontrols/fusion/MenuSeparator.qml b/src/quickcontrols/fusion/MenuSeparator.qml new file mode 100644 index 0000000000..b27dcf4a59 --- /dev/null +++ b/src/quickcontrols/fusion/MenuSeparator.qml @@ -0,0 +1,26 @@ +// Copyright (C) 2017 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.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.MenuSeparator { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + padding: 5 + verticalPadding: 1 + + contentItem: Rectangle { + implicitWidth: 188 + implicitHeight: 1 + color: Qt.lighter(Fusion.darkShade, 1.06) + } +} diff --git a/src/quickcontrols/fusion/Page.qml b/src/quickcontrols/fusion/Page.qml new file mode 100644 index 0000000000..65a752318d --- /dev/null +++ b/src/quickcontrols/fusion/Page.qml @@ -0,0 +1,25 @@ +// Copyright (C) 2017 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.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.Page { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding, + implicitHeaderWidth, + implicitFooterWidth) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding + + (implicitHeaderHeight > 0 ? implicitHeaderHeight + spacing : 0) + + (implicitFooterHeight > 0 ? implicitFooterHeight + spacing : 0)) + + background: Rectangle { + color: control.palette.window + } +} diff --git a/src/quickcontrols/fusion/PageIndicator.qml b/src/quickcontrols/fusion/PageIndicator.qml new file mode 100644 index 0000000000..c6f235a9da --- /dev/null +++ b/src/quickcontrols/fusion/PageIndicator.qml @@ -0,0 +1,43 @@ +// Copyright (C) 2017 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.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.PageIndicator { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + padding: 4 + spacing: 4 + + delegate: Rectangle { + implicitWidth: 6 + implicitHeight: 6 + + radius: width / 2 + color: control.palette.shadow + + opacity: index === currentIndex ? 0.95 : pressed ? 0.75 : 0.45 + + required property int index + + Behavior on opacity { OpacityAnimator { duration: 100 } } + } + + contentItem: Row { + spacing: control.spacing + + Repeater { + model: control.count + delegate: control.delegate + } + } +} diff --git a/src/quickcontrols/fusion/Pane.qml b/src/quickcontrols/fusion/Pane.qml new file mode 100644 index 0000000000..366c2fffe0 --- /dev/null +++ b/src/quickcontrols/fusion/Pane.qml @@ -0,0 +1,23 @@ +// Copyright (C) 2017 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.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.Pane { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + padding: 9 + + background: Rectangle { + color: control.palette.window + } +} diff --git a/src/quickcontrols/fusion/Popup.qml b/src/quickcontrols/fusion/Popup.qml new file mode 100644 index 0000000000..d669b5e758 --- /dev/null +++ b/src/quickcontrols/fusion/Popup.qml @@ -0,0 +1,33 @@ +// Copyright (C) 2017 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.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.Popup { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + padding: 6 + + background: Rectangle { + color: control.palette.window + border.color: control.palette.mid + radius: 2 + } + + T.Overlay.modal: Rectangle { + color: Fusion.topShadow + } + + T.Overlay.modeless: Rectangle { + color: Fusion.topShadow + } +} diff --git a/src/quickcontrols/fusion/ProgressBar.qml b/src/quickcontrols/fusion/ProgressBar.qml new file mode 100644 index 0000000000..c05f1898db --- /dev/null +++ b/src/quickcontrols/fusion/ProgressBar.qml @@ -0,0 +1,83 @@ +// Copyright (C) 2017 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.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.ProgressBar { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + contentItem: Item { + implicitWidth: 120 + implicitHeight: 24 + scale: control.mirrored ? -1 : 1 + + Rectangle { + height: parent.height + width: (control.indeterminate ? 1.0 : control.position) * parent.width + + radius: 2 + border.color: Qt.darker(Fusion.highlight(control.palette), 1.4) + gradient: Gradient { + GradientStop { + position: 0 + color: Qt.lighter(Fusion.highlight(control.palette), 1.2) + } + GradientStop { + position: 1 + color: Fusion.highlight(control.palette) + } + } + } + + Item { + x: 1; y: 1 + width: parent.width - 2 + height: parent.height - 2 + visible: control.indeterminate + clip: true + + ColorImage { + width: Math.ceil(parent.width / implicitWidth + 1) * implicitWidth + height: parent.height + + mirror: control.mirrored + fillMode: Image.TileHorizontally + source: "qrc:/qt-project.org/imports/QtQuick/Controls/Fusion/images/progressmask.png" + color: Color.transparent(Qt.lighter(Fusion.highlight(control.palette), 1.2), 160 / 255) + + visible: control.indeterminate + NumberAnimation on x { + running: control.indeterminate && control.visible + from: -31 // progressmask.png width + to: 0 + loops: Animation.Infinite + duration: 750 + } + } + } + } + + background: Rectangle { + implicitWidth: 120 + implicitHeight: 24 + + radius: 2 + color: control.palette.base + border.color: Fusion.outline(control.palette) + + Rectangle { + x: 1; y: 1; height: 1 + width: parent.width - 2 + color: Fusion.topShadow + } + } +} diff --git a/src/quickcontrols/fusion/RadioButton.qml b/src/quickcontrols/fusion/RadioButton.qml new file mode 100644 index 0000000000..2553679bc4 --- /dev/null +++ b/src/quickcontrols/fusion/RadioButton.qml @@ -0,0 +1,38 @@ +// Copyright (C) 2017 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.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.RadioButton { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + padding: 6 + spacing: 6 + + indicator: RadioIndicator { + 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 + control: control + } + + 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.palette.windowText + elide: Text.ElideRight + verticalAlignment: Text.AlignVCenter + } +} diff --git a/src/quickcontrols/fusion/RadioDelegate.qml b/src/quickcontrols/fusion/RadioDelegate.qml new file mode 100644 index 0000000000..f99cf81d21 --- /dev/null +++ b/src/quickcontrols/fusion/RadioDelegate.qml @@ -0,0 +1,53 @@ +// Copyright (C) 2017 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.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.RadioDelegate { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + padding: 6 + spacing: 6 + + icon.width: 16 + icon.height: 16 + + contentItem: IconLabel { + leftPadding: control.mirrored ? control.indicator.width + control.spacing : 0 + rightPadding: !control.mirrored ? control.indicator.width + control.spacing : 0 + + spacing: control.spacing + mirrored: control.mirrored + display: control.display + alignment: control.display === IconLabel.IconOnly || control.display === IconLabel.TextUnderIcon ? Qt.AlignCenter : Qt.AlignLeft + + icon: control.icon + text: control.text + font: control.font + color: control.highlighted ? Fusion.highlightedText(control.palette) : control.palette.text + } + + indicator: RadioIndicator { + x: control.mirrored ? control.leftPadding : control.width - width - control.rightPadding + y: control.topPadding + (control.availableHeight - height) / 2 + + control: control + } + + background: Rectangle { + implicitWidth: 100 + implicitHeight: 20 + color: control.down ? Fusion.buttonColor(control.palette, false, true, true) + : control.highlighted ? Fusion.highlight(control.palette) : control.palette.base + } +} diff --git a/src/quickcontrols/fusion/RangeSlider.qml b/src/quickcontrols/fusion/RangeSlider.qml new file mode 100644 index 0000000000..b9052c04eb --- /dev/null +++ b/src/quickcontrols/fusion/RangeSlider.qml @@ -0,0 +1,48 @@ +// Copyright (C) 2017 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.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.RangeSlider { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + Math.max(first.implicitHandleWidth, + second.implicitHandleWidth) + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + Math.max(first.implicitHandleHeight, + second.implicitHandleHeight) + topPadding + bottomPadding) + + first.handle: SliderHandle { + x: control.leftPadding + Math.round(control.horizontal ? control.first.visualPosition * (control.availableWidth - width) : (control.availableWidth - width) / 2) + y: control.topPadding + Math.round(control.horizontal ? (control.availableHeight - height) / 2 : control.first.visualPosition * (control.availableHeight - height)) + + palette: control.palette + pressed: control.first.pressed + hovered: control.first.hovered + vertical: control.vertical + visualFocus: activeFocus + } + + second.handle: SliderHandle { + x: control.leftPadding + Math.round(control.horizontal ? control.second.visualPosition * (control.availableWidth - width) : (control.availableWidth - width) / 2) + y: control.topPadding + Math.round(control.horizontal ? (control.availableHeight - height) / 2 : control.second.visualPosition * (control.availableHeight - height)) + + palette: control.palette + pressed: control.second.pressed + hovered: control.second.hovered + vertical: control.vertical + visualFocus: activeFocus + } + + background: SliderGroove { + control: control + offset: control.first.position + progress: control.second.position + visualProgress: control.second.visualPosition + } +} diff --git a/src/quickcontrols/fusion/RoundButton.qml b/src/quickcontrols/fusion/RoundButton.qml new file mode 100644 index 0000000000..1952e2ccac --- /dev/null +++ b/src/quickcontrols/fusion/RoundButton.qml @@ -0,0 +1,67 @@ +// Copyright (C) 2017 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.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.RoundButton { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + padding: 6 + spacing: 6 + + icon.width: 16 + icon.height: 16 + + contentItem: IconLabel { + spacing: control.spacing + mirrored: control.mirrored + display: control.display + + icon: control.icon + text: control.text + font: control.font + color: control.palette.buttonText + } + + background: Rectangle { + implicitWidth: 32 + implicitHeight: 32 + visible: !control.flat || control.down || control.checked + + gradient: Gradient { + GradientStop { + position: 0 + color: control.down || control.checked + ? Fusion.buttonColor(control.palette, control.highlighted, control.down || control.checked, control.enabled && control.hovered) + : Fusion.gradientStart(Fusion.buttonColor(control.palette, control.highlighted, control.down, control.enabled && control.hovered)) + } + GradientStop { + position: 1 + color: control.down || control.checked + ? Fusion.buttonColor(control.palette, control.highlighted, control.down || control.checked, control.enabled && control.hovered) + : Fusion.gradientStop(Fusion.buttonColor(control.palette, control.highlighted, control.down, control.enabled && control.hovered)) + } + } + + radius: control.radius + border.color: Fusion.buttonOutline(control.palette, control.highlighted || control.visualFocus, control.enabled) + + Rectangle { + x: 1; y: 1 + width: parent.width - 2 + height: parent.height - 2 + border.color: Fusion.innerContrastLine + color: "transparent" + radius: control.radius + } + } +} diff --git a/src/quickcontrols/fusion/ScrollBar.qml b/src/quickcontrols/fusion/ScrollBar.qml new file mode 100644 index 0000000000..616050df69 --- /dev/null +++ b/src/quickcontrols/fusion/ScrollBar.qml @@ -0,0 +1,44 @@ +// Copyright (C) 2017 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.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.ScrollBar { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + padding: 2 + visible: control.policy !== T.ScrollBar.AlwaysOff + minimumSize: orientation === Qt.Horizontal ? height / width : width / height + + contentItem: Rectangle { + implicitWidth: control.interactive ? 6 : 2 + implicitHeight: control.interactive ? 6 : 2 + + radius: width / 2 + color: control.pressed ? control.palette.dark : control.palette.mid + opacity: 0.0 + + states: State { + name: "active" + when: control.policy === T.ScrollBar.AlwaysOn || (control.active && control.size < 1.0) + PropertyChanges { control.contentItem.opacity: 0.75 } + } + + transitions: Transition { + from: "active" + SequentialAnimation { + PauseAnimation { duration: 450 } + NumberAnimation { target: control.contentItem; duration: 200; property: "opacity"; to: 0.0 } + } + } + } +} diff --git a/src/quickcontrols/fusion/ScrollIndicator.qml b/src/quickcontrols/fusion/ScrollIndicator.qml new file mode 100644 index 0000000000..a324c049e3 --- /dev/null +++ b/src/quickcontrols/fusion/ScrollIndicator.qml @@ -0,0 +1,44 @@ +// Copyright (C) 2017 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.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.ScrollIndicator { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + padding: 2 + + contentItem: Rectangle { + implicitWidth: 2 + implicitHeight: 2 + + color: control.palette.mid + visible: control.size < 1.0 + opacity: 0.0 + + states: State { + name: "active" + when: control.active + PropertyChanges { control.contentItem.opacity: 0.75 } + } + + transitions: [ + Transition { + from: "active" + SequentialAnimation { + PauseAnimation { duration: 450 } + NumberAnimation { target: control.contentItem; duration: 200; property: "opacity"; to: 0.0 } + } + } + ] + } +} diff --git a/src/quickcontrols/fusion/ScrollView.qml b/src/quickcontrols/fusion/ScrollView.qml new file mode 100644 index 0000000000..60789313c9 --- /dev/null +++ b/src/quickcontrols/fusion/ScrollView.qml @@ -0,0 +1,31 @@ +// Copyright (C) 2020 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.impl +import QtQuick.Templates as T + +T.ScrollView { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + ScrollBar.vertical: ScrollBar { + parent: control + x: control.mirrored ? 0 : control.width - width + y: control.topPadding + height: control.availableHeight + active: control.ScrollBar.horizontal.active + } + + ScrollBar.horizontal: ScrollBar { + parent: control + x: control.leftPadding + y: control.height - height + width: control.availableWidth + active: control.ScrollBar.vertical.active + } +} diff --git a/src/quickcontrols/fusion/SelectionRectangle.qml b/src/quickcontrols/fusion/SelectionRectangle.qml new file mode 100644 index 0000000000..762fec30c8 --- /dev/null +++ b/src/quickcontrols/fusion/SelectionRectangle.qml @@ -0,0 +1,30 @@ +// Copyright (C) 2021 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.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.SelectionRectangle { + id: control + + topLeftHandle: Item { + width: 20 + height: 20 + visible: SelectionRectangle.control.active + // This item is deliberately empty. Selection handles don't feel at home + // for this style. But we provide an invisible handle that the user can + // drag on. + } + + bottomRightHandle: Item { + width: 20 + height: 20 + visible: SelectionRectangle.control.active + // This item is deliberately empty. Selection handles don't feel at home + // for this style. But we provide an invisible handle that the user can + // drag on. + } +} diff --git a/src/quickcontrols/fusion/Slider.qml b/src/quickcontrols/fusion/Slider.qml new file mode 100644 index 0000000000..c78dbed468 --- /dev/null +++ b/src/quickcontrols/fusion/Slider.qml @@ -0,0 +1,34 @@ +// Copyright (C) 2017 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.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.Slider { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitHandleWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitHandleHeight + topPadding + bottomPadding) + + handle: SliderHandle { + x: control.leftPadding + Math.round(control.horizontal ? control.visualPosition * (control.availableWidth - width) : (control.availableWidth - width) / 2) + y: control.topPadding + Math.round(control.horizontal ? (control.availableHeight - height) / 2 : control.visualPosition * (control.availableHeight - height)) + + palette: control.palette + pressed: control.pressed + hovered: control.hovered + vertical: control.vertical + visualFocus: control.visualFocus + } + + background: SliderGroove { + control: control + progress: control.position + visualProgress: control.visualPosition + } +} diff --git a/src/quickcontrols/fusion/SpinBox.qml b/src/quickcontrols/fusion/SpinBox.qml new file mode 100644 index 0000000000..1e7d05d7ce --- /dev/null +++ b/src/quickcontrols/fusion/SpinBox.qml @@ -0,0 +1,147 @@ +// Copyright (C) 2017 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.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.SpinBox { + id: control + + // Note: the width of the indicators are calculated into the padding + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentItem.implicitWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + up.implicitIndicatorHeight + down.implicitIndicatorHeight) + + padding: 4 + leftPadding: padding + (control.mirrored ? (up.indicator ? up.indicator.width : 0) : 0) + rightPadding: padding + (!control.mirrored ? (up.indicator ? up.indicator.width : 0) : 0) + + validator: IntValidator { + locale: control.locale.name + bottom: Math.min(control.from, control.to) + top: Math.max(control.from, control.to) + } + + contentItem: TextInput { + z: 2 + text: control.displayText + + font: control.font + color: control.palette.text + selectionColor: control.palette.highlight + selectedTextColor: control.palette.highlightedText + horizontalAlignment: Qt.AlignHCenter + verticalAlignment: Qt.AlignVCenter + + readOnly: !control.editable + validator: control.validator + inputMethodHints: control.inputMethodHints + clip: width < implicitWidth + } + + up.indicator: PaddedRectangle { + x: control.mirrored ? 1 : control.width - width - 1 + y: 1 + height: control.height / 2 - 1 + implicitWidth: 16 + implicitHeight: 10 + + radius: 1.7 + clip: true + topPadding: -2 + leftPadding: -2 + color: control.up.pressed ? Fusion.buttonColor(control.palette, false, true, true) : "transparent" + + ColorImage { + scale: -1 + width: parent.width + height: parent.height + opacity: enabled ? 1.0 : 0.5 + color: control.palette.buttonText + source: "qrc:/qt-project.org/imports/QtQuick/Controls/Fusion/images/arrow.png" + fillMode: Image.Pad + } + } + + down.indicator: PaddedRectangle { + x: control.mirrored ? 1 : control.width - width - 1 + y: control.height - height - 1 + height: control.height / 2 - 1 + implicitWidth: 16 + implicitHeight: 10 + + radius: 1.7 + clip: true + topPadding: -2 + leftPadding: -2 + color: control.down.pressed ? Fusion.buttonColor(control.palette, false, true, true) : "transparent" + + ColorImage { + width: parent.width + height: parent.height + opacity: enabled ? 1.0 : 0.5 + color: control.palette.buttonText + source: "qrc:/qt-project.org/imports/QtQuick/Controls/Fusion/images/arrow.png" + fillMode: Image.Pad + } + } + + background: Rectangle { + implicitWidth: 120 + implicitHeight: 24 + + radius: 2 + color: control.palette.base + border.color: control.activeFocus ? Fusion.highlightedOutline(control.palette) : Fusion.outline(control.palette) + + Rectangle { + x: 2 + y: 1 + width: parent.width - 4 + height: 1 + color: Fusion.topShadow + } + + Rectangle { + x: control.mirrored ? 1 : parent.width - width - 1 + y: 1 + width: Math.max(control.up.indicator ? control.up.indicator.width : 0, + control.down.indicator ? control.down.indicator.width : 0) + 1 + height: parent.height - 2 + + radius: 2 + gradient: Gradient { + GradientStop { + position: 0 + color: Fusion.gradientStart(Fusion.buttonColor(control.palette, control.visualFocus, false, control.up.hovered || control.down.hovered)) + } + GradientStop { + position: 1 + color: Fusion.gradientStop(Fusion.buttonColor(control.palette, control.visualFocus, false, control.up.hovered || control.down.hovered)) + } + } + + Rectangle { + x: control.mirrored ? parent.width - 1 : 0 + height: parent.height + width: 1 + color: Fusion.outline(control.palette) + } + } + + Rectangle { + x: 1; y: 1 + width: parent.width - 2 + height: parent.height - 2 + color: "transparent" + border.color: Color.transparent(Fusion.highlightedOutline(control.palette), 40 / 255) + visible: control.activeFocus + radius: 1.7 + } + } +} diff --git a/src/quickcontrols/fusion/SplitView.qml b/src/quickcontrols/fusion/SplitView.qml new file mode 100644 index 0000000000..1046d800eb --- /dev/null +++ b/src/quickcontrols/fusion/SplitView.qml @@ -0,0 +1,22 @@ +// Copyright (C) 2018 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.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion + +T.SplitView { + id: control + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + handle: Rectangle { + implicitWidth: control.orientation === Qt.Horizontal ? 2 : control.width + implicitHeight: control.orientation === Qt.Horizontal ? control.height : 2 + color: T.SplitHandle.pressed ? control.palette.dark + : (enabled && T.SplitHandle.hovered ? control.palette.midlight : control.palette.mid) + } +} diff --git a/src/quickcontrols/fusion/SwipeDelegate.qml b/src/quickcontrols/fusion/SwipeDelegate.qml new file mode 100644 index 0000000000..1c47433bba --- /dev/null +++ b/src/quickcontrols/fusion/SwipeDelegate.qml @@ -0,0 +1,45 @@ +// Copyright (C) 2017 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.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.SwipeDelegate { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + padding: 6 + spacing: 6 + + icon.width: 16 + icon.height: 16 + + swipe.transition: Transition { SmoothedAnimation { velocity: 3; easing.type: Easing.InOutCubic } } + + contentItem: IconLabel { + spacing: control.spacing + mirrored: control.mirrored + display: control.display + alignment: control.display === IconLabel.IconOnly || control.display === IconLabel.TextUnderIcon ? Qt.AlignCenter : Qt.AlignLeft + + icon: control.icon + text: control.text + font: control.font + color: control.highlighted ? Fusion.highlightedText(control.palette) : control.palette.text + } + + background: Rectangle { + implicitWidth: 100 + implicitHeight: 20 + color: control.down ? Fusion.buttonColor(control.palette, false, true, true) + : control.highlighted ? Fusion.highlight(control.palette) : control.palette.base + } +} diff --git a/src/quickcontrols/fusion/Switch.qml b/src/quickcontrols/fusion/Switch.qml new file mode 100644 index 0000000000..3965b29c36 --- /dev/null +++ b/src/quickcontrols/fusion/Switch.qml @@ -0,0 +1,38 @@ +// Copyright (C) 2017 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.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.Switch { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + padding: 6 + spacing: 6 + + indicator: SwitchIndicator { + 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 + control: control + } + + 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.palette.text + elide: Text.ElideRight + verticalAlignment: Text.AlignVCenter + } +} diff --git a/src/quickcontrols/fusion/SwitchDelegate.qml b/src/quickcontrols/fusion/SwitchDelegate.qml new file mode 100644 index 0000000000..b7c4278c71 --- /dev/null +++ b/src/quickcontrols/fusion/SwitchDelegate.qml @@ -0,0 +1,52 @@ +// Copyright (C) 2017 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.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.SwitchDelegate { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + padding: 6 + spacing: 6 + + icon.width: 16 + icon.height: 16 + + indicator: SwitchIndicator { + x: control.text ? (control.mirrored ? control.leftPadding : control.width - width - control.rightPadding) : control.leftPadding + (control.availableWidth - width) / 2 + y: control.topPadding + (control.availableHeight - height) / 2 + control: control + } + + contentItem: IconLabel { + leftPadding: control.mirrored ? control.indicator.width + control.spacing : 0 + rightPadding: !control.mirrored ? control.indicator.width + control.spacing : 0 + + spacing: control.spacing + mirrored: control.mirrored + display: control.display + alignment: control.display === IconLabel.IconOnly || control.display === IconLabel.TextUnderIcon ? Qt.AlignCenter : Qt.AlignLeft + + icon: control.icon + text: control.text + font: control.font + color: control.highlighted ? Fusion.highlightedText(control.palette) : control.palette.text + } + + background: Rectangle { + implicitWidth: 100 + implicitHeight: 20 + color: control.down ? Fusion.buttonColor(control.palette, false, true, true) + : control.highlighted ? Fusion.highlight(control.palette) : control.palette.base + } +} diff --git a/src/quickcontrols/fusion/TabBar.qml b/src/quickcontrols/fusion/TabBar.qml new file mode 100644 index 0000000000..275bcf5a2a --- /dev/null +++ b/src/quickcontrols/fusion/TabBar.qml @@ -0,0 +1,46 @@ +// Copyright (C) 2017 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.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.TabBar { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + spacing: -1 + + contentItem: ListView { + model: control.contentModel + currentIndex: control.currentIndex + + spacing: control.spacing + orientation: ListView.Horizontal + boundsBehavior: Flickable.StopAtBounds + flickableDirection: Flickable.AutoFlickIfNeeded + snapMode: ListView.SnapToItem + + highlightMoveDuration: 0 + highlightRangeMode: ListView.ApplyRange + preferredHighlightBegin: 40 + preferredHighlightEnd: width - 40 + } + + background: Item { + implicitHeight: 21 + + Rectangle { + width: parent.width + height: 1 + y: control.position === T.TabBar.Header ? parent.height - 1 : 0 + color: Fusion.outline(control.palette) + } + } +} diff --git a/src/quickcontrols/fusion/TabButton.qml b/src/quickcontrols/fusion/TabButton.qml new file mode 100644 index 0000000000..48ee303f63 --- /dev/null +++ b/src/quickcontrols/fusion/TabButton.qml @@ -0,0 +1,64 @@ +// Copyright (C) 2017 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.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.TabButton { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + padding: 2 + horizontalPadding: 4 + spacing: 6 + + icon.width: 16 + icon.height: 16 + + z: checked + + contentItem: IconLabel { + spacing: control.spacing + mirrored: control.mirrored + display: control.display + + icon: control.icon + text: control.text + font: control.font + color: control.palette.buttonText + } + + + background: Rectangle { + y: control.checked || control.TabBar.position !== T.TabBar.Header ? 0 : 2 + implicitHeight: 21 + height: control.height - (control.checked ? 0 : 2) + + border.color: Qt.lighter(Fusion.outline(control.palette), 1.1) + + gradient: Gradient { + GradientStop { + position: 0 + color: control.checked ? Qt.lighter(Fusion.tabFrameColor(control.palette), 1.04) + : Qt.darker(Fusion.tabFrameColor(control.palette), 1.08) + } + GradientStop { + position: control.checked ? 0 : 0.85 + color: control.checked ? Qt.lighter(Fusion.tabFrameColor(control.palette), 1.04) + : Qt.darker(Fusion.tabFrameColor(control.palette), 1.08) + } + GradientStop { + position: 1 + color: control.checked ? Fusion.tabFrameColor(control.palette) + : Qt.darker(Fusion.tabFrameColor(control.palette), 1.16) + } + } + } +} diff --git a/src/quickcontrols/fusion/TextArea.qml b/src/quickcontrols/fusion/TextArea.qml new file mode 100644 index 0000000000..5e1ecfa905 --- /dev/null +++ b/src/quickcontrols/fusion/TextArea.qml @@ -0,0 +1,43 @@ +// Copyright (C) 2017 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.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.TextArea { + id: control + + implicitWidth: Math.max(contentWidth + leftPadding + rightPadding, + implicitBackgroundWidth + leftInset + rightInset, + placeholder.implicitWidth + leftPadding + rightPadding) + implicitHeight: Math.max(contentHeight + topPadding + bottomPadding, + implicitBackgroundHeight + topInset + bottomInset, + placeholder.implicitHeight + topPadding + bottomPadding) + + padding: 6 + leftPadding: padding + 4 + + color: control.palette.text + selectionColor: control.palette.highlight + selectedTextColor: control.palette.highlightedText + placeholderTextColor: control.palette.placeholderText + + PlaceholderText { + id: placeholder + x: control.leftPadding + y: control.topPadding + width: control.width - (control.leftPadding + control.rightPadding) + height: control.height - (control.topPadding + control.bottomPadding) + + text: control.placeholderText + font: control.font + color: control.placeholderTextColor + verticalAlignment: control.verticalAlignment + visible: !control.length && !control.preeditText && (!control.activeFocus || control.horizontalAlignment !== Qt.AlignHCenter) + elide: Text.ElideRight + renderType: control.renderType + } +} diff --git a/src/quickcontrols/fusion/TextField.qml b/src/quickcontrols/fusion/TextField.qml new file mode 100644 index 0000000000..b358c668d8 --- /dev/null +++ b/src/quickcontrols/fusion/TextField.qml @@ -0,0 +1,69 @@ +// Copyright (C) 2017 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.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.TextField { + id: control + + implicitWidth: implicitBackgroundWidth + leftInset + rightInset + || Math.max(contentWidth, placeholder.implicitWidth) + leftPadding + rightPadding + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding, + placeholder.implicitHeight + topPadding + bottomPadding) + + padding: 4 + + color: control.palette.text + selectionColor: control.palette.highlight + selectedTextColor: control.palette.highlightedText + placeholderTextColor: control.palette.placeholderText + verticalAlignment: TextInput.AlignVCenter + + PlaceholderText { + id: placeholder + x: control.leftPadding + y: control.topPadding + width: control.width - (control.leftPadding + control.rightPadding) + height: control.height - (control.topPadding + control.bottomPadding) + + text: control.placeholderText + font: control.font + color: control.placeholderTextColor + verticalAlignment: control.verticalAlignment + visible: !control.length && !control.preeditText && (!control.activeFocus || control.horizontalAlignment !== Qt.AlignHCenter) + elide: Text.ElideRight + renderType: control.renderType + } + + background: Rectangle { + implicitWidth: 120 + implicitHeight: 24 + + radius: 2 + color: control.palette.base + border.color: control.activeFocus ? Fusion.highlightedOutline(control.palette) : Fusion.outline(control.palette) + + Rectangle { + x: 1; y: 1 + width: parent.width - 2 + height: parent.height - 2 + color: "transparent" + border.color: Color.transparent(Fusion.highlightedOutline(control.palette), 40 / 255) + visible: control.activeFocus + radius: 1.7 + } + + Rectangle { + x: 2 + y: 1 + width: parent.width - 4 + height: 1 + color: Fusion.topShadow + } + } +} diff --git a/src/quickcontrols/fusion/ToolBar.qml b/src/quickcontrols/fusion/ToolBar.qml new file mode 100644 index 0000000000..13b269e9df --- /dev/null +++ b/src/quickcontrols/fusion/ToolBar.qml @@ -0,0 +1,49 @@ +// Copyright (C) 2017 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.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.ToolBar { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + horizontalPadding: 6 + topPadding: control.position === T.ToolBar.Footer ? 1 : 0 + bottomPadding: control.position === T.ToolBar.Header ? 1 : 0 + + background: Rectangle { + implicitHeight: 26 + + gradient: Gradient { + GradientStop { + position: 0 + color: Qt.lighter(control.palette.window, 1.04) + } + GradientStop { + position: 1 + color: control.palette.window + } + } + + Rectangle { + width: parent.width + height: 1 + color: control.position === T.ToolBar.Header ? Fusion.lightShade : Fusion.darkShade + } + + Rectangle { + y: parent.height - height + width: parent.width + height: 1 + color: control.position === T.ToolBar.Header ? Fusion.darkShade : Fusion.lightShade + } + } +} diff --git a/src/quickcontrols/fusion/ToolButton.qml b/src/quickcontrols/fusion/ToolButton.qml new file mode 100644 index 0000000000..dd9b628261 --- /dev/null +++ b/src/quickcontrols/fusion/ToolButton.qml @@ -0,0 +1,43 @@ +// Copyright (C) 2017 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.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.ToolButton { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + padding: 6 + spacing: 6 + + icon.width: 16 + icon.height: 16 + + contentItem: IconLabel { + spacing: control.spacing + mirrored: control.mirrored + display: control.display + + icon: control.icon + text: control.text + font: control.font + color: control.palette.buttonText + } + + background: ButtonPanel { + implicitWidth: 20 + implicitHeight: 20 + + control: control + visible: control.down || control.checked || control.highlighted || control.visualFocus + || (enabled && control.hovered) + } +} diff --git a/src/quickcontrols/fusion/ToolSeparator.qml b/src/quickcontrols/fusion/ToolSeparator.qml new file mode 100644 index 0000000000..569ee66ec5 --- /dev/null +++ b/src/quickcontrols/fusion/ToolSeparator.qml @@ -0,0 +1,33 @@ +// Copyright (C) 2017 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.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.ToolSeparator { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + padding: vertical ? 6 : 2 + verticalPadding: vertical ? 2 : 6 + + contentItem: Rectangle { + implicitWidth: control.vertical ? 2 : 8 + implicitHeight: control.vertical ? 8 : 2 + color: Qt.darker(control.palette.window, 1.1) + + Rectangle { + x: 1 + width: 1 + height: parent.height + color: Qt.lighter(control.palette.window, 1.1) + } + } +} diff --git a/src/quickcontrols/fusion/ToolTip.qml b/src/quickcontrols/fusion/ToolTip.qml new file mode 100644 index 0000000000..5166d2b8b6 --- /dev/null +++ b/src/quickcontrols/fusion/ToolTip.qml @@ -0,0 +1,46 @@ +// Copyright (C) 2017 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.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.ToolTip { + id: control + + x: parent ? (parent.width - implicitWidth) / 2 : 0 + y: -implicitHeight - 3 + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding) + + margins: 6 + padding: 6 + + closePolicy: T.Popup.CloseOnEscape | T.Popup.CloseOnPressOutsideParent | T.Popup.CloseOnReleaseOutsideParent + + contentItem: Text { + text: control.text + font: control.font + wrapMode: Text.Wrap + color: control.palette.toolTipText + } + + background: Rectangle { + color: control.palette.toolTipBase + border.color: control.palette.toolTipText + + Rectangle { + z: -1 + x: 1; y: 1 + width: parent.width + height: parent.height + color: control.palette.shadow + opacity: 0.5 + } + } +} diff --git a/src/quickcontrols/fusion/TreeViewDelegate.qml b/src/quickcontrols/fusion/TreeViewDelegate.qml new file mode 100644 index 0000000000..195693614b --- /dev/null +++ b/src/quickcontrols/fusion/TreeViewDelegate.qml @@ -0,0 +1,99 @@ +// 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.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion + +T.TreeViewDelegate { + id: control + + implicitWidth: leftMargin + __contentIndent + implicitContentWidth + rightPadding + rightMargin + implicitHeight: Math.max(implicitBackgroundHeight, implicitContentHeight, implicitIndicatorHeight) + + indentation: indicator ? indicator.width : 12 + leftMargin: 5 + rightMargin: 5 + spacing: 5 + + topPadding: contentItem ? (height - contentItem.implicitHeight) / 2 : 0 + leftPadding: !mirrored ? leftMargin + __contentIndent : width - leftMargin - __contentIndent - implicitContentWidth + + highlighted: control.selected || control.current + || ((control.treeView.selectionBehavior === TableView.SelectRows + || control.treeView.selectionBehavior === TableView.SelectionDisabled) + && control.row === control.treeView.currentRow) + + required property int row + required property var model + readonly property real __contentIndent: !isTreeNode ? 0 : (depth * indentation) + (indicator ? indicator.width + spacing : 0) + + indicator: Item { + readonly property real __indicatorIndent: control.leftMargin + (control.depth * control.indentation) + x: !control.mirrored ? __indicatorIndent : control.width - __indicatorIndent - width + y: (control.height - height) / 2 + implicitWidth: Math.max(arrow.implicitWidth, 20) + implicitHeight: 24 // same as Button.qml + + property ColorImage arrow : ColorImage { + parent: control.indicator + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + rotation: control.expanded ? 0 : (control.mirrored ? 90 : -90) + source: "qrc:/qt-project.org/imports/QtQuick/Controls/Fusion/images/arrow.png" + color: control.palette.windowText + defaultColor: "#353637" + } + } + + background: Rectangle { + implicitHeight: 24 // same as Button.qml + color: control.highlighted + ? control.palette.highlight + : (control.treeView.alternatingRows && control.row % 2 !== 0 + ? control.palette.alternateBase : control.palette.base) + } + + contentItem: Label { + text: control.model.display + elide: Text.ElideRight + visible: !control.editing + } + + // The edit delegate is a separate component, and doesn't need + // to follow the same strict rules that are applied to a control. + // qmllint disable attached-property-reuse + // qmllint disable controls-attached-property-reuse + // qmllint disable controls-sanity + TableView.editDelegate: FocusScope { + width: parent.width + height: parent.height + + readonly property int __role: { + let model = control.treeView.model + let index = control.treeView.index(row, column) + let editText = model.data(index, Qt.EditRole) + return editText !== undefined ? Qt.EditRole : Qt.DisplayRole + } + + TextField { + id: textField + x: control.contentItem.x + y: (parent.height - height) / 2 + width: control.contentItem.width + text: control.treeView.model.data(control.treeView.index(row, column), __role) + focus: true + } + + TableView.onCommit: { + let index = TableView.view.index(row, column) + TableView.view.model.setData(index, textField.text, __role) + } + + Component.onCompleted: textField.selectAll() + } + // qmllint enable attached-property-reuse + // qmllint enable controls-attached-property-reuse + // qmllint enable controls-sanity +} diff --git a/src/quickcontrols/fusion/Tumbler.qml b/src/quickcontrols/fusion/Tumbler.qml new file mode 100644 index 0000000000..447765dce7 --- /dev/null +++ b/src/quickcontrols/fusion/Tumbler.qml @@ -0,0 +1,46 @@ +// Copyright (C) 2017 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.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +T.Tumbler { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + + delegate: Text { + text: modelData + color: control.palette.windowText + font: control.font + opacity: (1.0 - Math.abs(Tumbler.displacement) / (control.visibleItemCount / 2)) * (control.enabled ? 1 : 0.6) + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + + required property var modelData + required property int index + } + + contentItem: TumblerView { + implicitWidth: 60 + implicitHeight: 200 + model: control.model + delegate: control.delegate + path: Path { + startX: control.contentItem.width / 2 + startY: -control.contentItem.delegateHeight / 2 + PathLine { + x: control.contentItem.width / 2 + y: (control.visibleItemCount + 1) * control.contentItem.delegateHeight - control.contentItem.delegateHeight / 2 + } + } + + property real delegateHeight: control.availableHeight / control.visibleItemCount + } +} diff --git a/src/quickcontrols/fusion/VerticalHeaderView.qml b/src/quickcontrols/fusion/VerticalHeaderView.qml new file mode 100644 index 0000000000..c2cb281a24 --- /dev/null +++ b/src/quickcontrols/fusion/VerticalHeaderView.qml @@ -0,0 +1,52 @@ +// Copyright (C) 2020 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 ComponentBehavior: Bound + +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Fusion.impl + +T.VerticalHeaderView { + id: control + + // The contentWidth of TableView will be zero at start-up, until the delegate + // items have been loaded. This means that even if the implicit width of + // VerticalHeaderView should be the same as the content width in the end, we + // need to ensure that it has at least a width of 1 at start-up, otherwise + // TableView won't bother loading any delegates at all. + implicitWidth: Math.max(1, contentWidth) + implicitHeight: syncView ? syncView.height : 0 + + delegate: Rectangle { + id: delegate + + required property var model + + // Qt6: add cellPadding (and font etc) as public API in headerview + readonly property real cellPadding: 8 + + implicitWidth: Math.max(control.width, text.implicitWidth + (cellPadding * 2)) + implicitHeight: text.implicitHeight + (cellPadding * 2) + + gradient: Gradient { + GradientStop { + position: 0 + color: Fusion.gradientStart(control.palette.button) + } + GradientStop { + position: 1 + color: Fusion.gradientStop(control.palette.button) + } + } + + Label { + id: text + text: delegate.model[control.textRole] + width: delegate.width + height: delegate.height + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + } +} diff --git a/src/quickcontrols/fusion/images/arrow.png b/src/quickcontrols/fusion/images/arrow.png Binary files differnew file mode 100644 index 0000000000..97ef0238e5 --- /dev/null +++ b/src/quickcontrols/fusion/images/arrow.png diff --git a/src/quickcontrols/fusion/images/arrow.svg b/src/quickcontrols/fusion/images/arrow.svg new file mode 100644 index 0000000000..4438392495 --- /dev/null +++ b/src/quickcontrols/fusion/images/arrow.svg @@ -0,0 +1,75 @@ +<?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="10" + height="6" + viewBox="0 0 10 6" + id="svg2" + version="1.1" + inkscape:version="0.91 r13725" + inkscape:export-filename="/Users/jpnurmi/Downloads/arrow@4x.png" + inkscape:export-xdpi="360" + inkscape:export-ydpi="360" + sodipodi:docname="arrow.svg"> + <defs + id="defs4" /> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="31.678384" + inkscape:cx="7.9810383" + inkscape:cy="3.0344775" + inkscape:document-units="px" + inkscape:current-layer="layer1" + showgrid="true" + units="px" + inkscape:snap-to-guides="true" + inkscape:snap-page="true" + inkscape:window-width="1440" + inkscape:window-height="851" + inkscape:window-x="0" + inkscape:window-y="1" + inkscape:window-maximized="1"> + <inkscape:grid + type="xygrid" + id="grid3336" /> + </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,-1046.3622)"> + <path + transform="matrix(1.2371791,0,0,0.85714284,1.0769252,150.19463)" + style="fill:#000000;fill-opacity:0.7254902" + inkscape:transform-center-y="1.4999605" + d="m 3.1709837,1051.3622 -3.2331616,-4.6667 6.4663233,0 z" + id="path3365" + inkscape:connector-curvature="0" + sodipodi:nodetypes="cccc" /> + </g> +</svg> diff --git a/src/quickcontrols/fusion/images/arrow@2x.png b/src/quickcontrols/fusion/images/arrow@2x.png Binary files differnew file mode 100644 index 0000000000..9bfc4e6eed --- /dev/null +++ b/src/quickcontrols/fusion/images/arrow@2x.png diff --git a/src/quickcontrols/fusion/images/arrow@3x.png b/src/quickcontrols/fusion/images/arrow@3x.png Binary files differnew file mode 100644 index 0000000000..6fd9c988dc --- /dev/null +++ b/src/quickcontrols/fusion/images/arrow@3x.png diff --git a/src/quickcontrols/fusion/images/arrow@4x.png b/src/quickcontrols/fusion/images/arrow@4x.png Binary files differnew file mode 100644 index 0000000000..f5e1e66a1d --- /dev/null +++ b/src/quickcontrols/fusion/images/arrow@4x.png diff --git a/src/quickcontrols/fusion/images/checkmark.png b/src/quickcontrols/fusion/images/checkmark.png Binary files differnew file mode 100644 index 0000000000..deb30419d0 --- /dev/null +++ b/src/quickcontrols/fusion/images/checkmark.png diff --git a/src/quickcontrols/fusion/images/checkmark.svg b/src/quickcontrols/fusion/images/checkmark.svg new file mode 100644 index 0000000000..f1afdc4f9f --- /dev/null +++ b/src/quickcontrols/fusion/images/checkmark.svg @@ -0,0 +1,72 @@ +<?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="14" + height="14" + viewBox="0 0 14 14" + id="svg3386" + version="1.1" + inkscape:version="0.91 r13725" + inkscape:export-filename="/Users/jpnurmi/Downloads/checkmark@4x.png" + inkscape:export-xdpi="360" + inkscape:export-ydpi="360" + sodipodi:docname="checkmark.svg"> + <defs + id="defs3388" /> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="32" + inkscape:cx="1.9865044" + inkscape:cy="6.0706667" + inkscape:document-units="px" + inkscape:current-layer="layer1" + showgrid="false" + units="px" + inkscape:snap-page="true" + inkscape:snap-grids="true" + inkscape:snap-to-guides="true" + inkscape:window-width="1440" + inkscape:window-height="851" + inkscape:window-x="0" + inkscape:window-y="1" + inkscape:window-maximized="1" /> + <metadata + id="metadata3391"> + <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,-1038.3622)"> + <path + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.79999995;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 5,1045.3622 2,4 2.5,-8" + id="path4198" + inkscape:connector-curvature="0" + sodipodi:nodetypes="ccc" + inkscape:export-xdpi="90" + inkscape:export-ydpi="90" /> + </g> +</svg> diff --git a/src/quickcontrols/fusion/images/checkmark@2x.png b/src/quickcontrols/fusion/images/checkmark@2x.png Binary files differnew file mode 100644 index 0000000000..f80de0a425 --- /dev/null +++ b/src/quickcontrols/fusion/images/checkmark@2x.png diff --git a/src/quickcontrols/fusion/images/checkmark@3x.png b/src/quickcontrols/fusion/images/checkmark@3x.png Binary files differnew file mode 100644 index 0000000000..c095eed18a --- /dev/null +++ b/src/quickcontrols/fusion/images/checkmark@3x.png diff --git a/src/quickcontrols/fusion/images/checkmark@4x.png b/src/quickcontrols/fusion/images/checkmark@4x.png Binary files differnew file mode 100644 index 0000000000..e58c7b4df4 --- /dev/null +++ b/src/quickcontrols/fusion/images/checkmark@4x.png diff --git a/src/quickcontrols/fusion/images/progressmask.png b/src/quickcontrols/fusion/images/progressmask.png Binary files differnew file mode 100644 index 0000000000..a354377c4a --- /dev/null +++ b/src/quickcontrols/fusion/images/progressmask.png diff --git a/src/quickcontrols/fusion/images/progressmask.svg b/src/quickcontrols/fusion/images/progressmask.svg new file mode 100644 index 0000000000..a0dfc4269d --- /dev/null +++ b/src/quickcontrols/fusion/images/progressmask.svg @@ -0,0 +1,74 @@ +<?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="31" + height="22" + viewBox="0 0 8.202083 5.8208335" + version="1.1" + id="svg8" + inkscape:export-filename="/home/jpnurmi/Projects/qt-dev/qtquickcontrols2/src/imports/controls/fusion/images/progressmask@4x.png" + inkscape:export-xdpi="384" + inkscape:export-ydpi="384" + inkscape:version="0.92.1 r" + sodipodi:docname="progressmask.svg"> + <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="61.144853" + inkscape:cy="14.574824" + inkscape:document-units="mm" + inkscape:current-layer="layer1" + showgrid="false" + units="px" + inkscape:pagecheckerboard="true" + inkscape:window-width="3840" + inkscape:window-height="2031" + inkscape:window-x="0" + inkscape:window-y="55" + inkscape:window-maximized="1" /> + <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></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1" + transform="translate(0,-291.17915)"> + <path + style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:4.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 0,296.99998 4.7625,-5.82083" + id="path4485" + inkscape:connector-curvature="0" + sodipodi:nodetypes="cc" /> + <path + style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:4.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 8.2020833,296.99998 4.7624997,-5.82083" + id="path4485-3" + inkscape:connector-curvature="0" + sodipodi:nodetypes="cc" /> + </g> +</svg> diff --git a/src/quickcontrols/fusion/images/progressmask@2x.png b/src/quickcontrols/fusion/images/progressmask@2x.png Binary files differnew file mode 100644 index 0000000000..69476bf4a0 --- /dev/null +++ b/src/quickcontrols/fusion/images/progressmask@2x.png diff --git a/src/quickcontrols/fusion/images/progressmask@3x.png b/src/quickcontrols/fusion/images/progressmask@3x.png Binary files differnew file mode 100644 index 0000000000..00a1c09d87 --- /dev/null +++ b/src/quickcontrols/fusion/images/progressmask@3x.png diff --git a/src/quickcontrols/fusion/images/progressmask@4x.png b/src/quickcontrols/fusion/images/progressmask@4x.png Binary files differnew file mode 100644 index 0000000000..263110d5fe --- /dev/null +++ b/src/quickcontrols/fusion/images/progressmask@4x.png diff --git a/src/quickcontrols/fusion/impl/ButtonPanel.qml b/src/quickcontrols/fusion/impl/ButtonPanel.qml new file mode 100644 index 0000000000..b7fa6a7a8e --- /dev/null +++ b/src/quickcontrols/fusion/impl/ButtonPanel.qml @@ -0,0 +1,46 @@ +// Copyright (C) 2017 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.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +Rectangle { + id: panel + + property Item control + property bool highlighted: control.highlighted + + visible: !control.flat || control.down || control.checked + + color: Fusion.buttonColor(control.palette, panel.highlighted, control.down || control.checked, + enabled && control.hovered) + gradient: control.down || control.checked ? null : buttonGradient + + Gradient { + id: buttonGradient + GradientStop { + position: 0 + color: Fusion.gradientStart(Fusion.buttonColor(panel.control.palette, panel.highlighted, + panel.control.down, panel.enabled && panel.control.hovered)) + } + GradientStop { + position: 1 + color: Fusion.gradientStop(Fusion.buttonColor(panel.control.palette, panel.highlighted, + panel.control.down, panel.enabled && panel.control.hovered)) + } + } + + radius: 2 + border.color: Fusion.buttonOutline(control.palette, panel.highlighted || control.visualFocus, control.enabled) + + Rectangle { + x: 1; y: 1 + width: parent.width - 2 + height: parent.height - 2 + border.color: Fusion.innerContrastLine + color: "transparent" + radius: 2 + } +} diff --git a/src/quickcontrols/fusion/impl/CMakeLists.txt b/src/quickcontrols/fusion/impl/CMakeLists.txt new file mode 100644 index 0000000000..64ee4851fb --- /dev/null +++ b/src/quickcontrols/fusion/impl/CMakeLists.txt @@ -0,0 +1,41 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +##################################################################### +## qtquickcontrols2fusionstyleimplplugin Plugin: +##################################################################### + +set(qml_files + "ButtonPanel.qml" + "CheckIndicator.qml" + "RadioIndicator.qml" + "SliderGroove.qml" + "SliderHandle.qml" + "SwitchIndicator.qml" +) + +qt_internal_add_qml_module(QuickControls2FusionStyleImpl + URI "QtQuick.Controls.Fusion.impl" + VERSION "${PROJECT_VERSION}" + PAST_MAJOR_VERSIONS 2 + CLASS_NAME QtQuickControls2FusionStyleImplPlugin + DEPENDENCIES + QtQuick/auto + PLUGIN_TARGET qtquickcontrols2fusionstyleimplplugin + SOURCES + qquickfusionbusyindicator.cpp qquickfusionbusyindicator_p.h + qquickfusiondial.cpp qquickfusiondial_p.h + qquickfusionknob.cpp qquickfusionknob_p.h + QML_FILES + ${qml_files} + DEFINES + QT_NO_CAST_FROM_ASCII + QT_NO_CAST_TO_ASCII + LIBRARIES + Qt::CorePrivate + Qt::Gui + Qt::QmlPrivate + Qt::QuickControls2ImplPrivate + Qt::QuickPrivate + Qt::QuickTemplates2Private +) diff --git a/src/quickcontrols/fusion/impl/CheckIndicator.qml b/src/quickcontrols/fusion/impl/CheckIndicator.qml new file mode 100644 index 0000000000..58de99654a --- /dev/null +++ b/src/quickcontrols/fusion/impl/CheckIndicator.qml @@ -0,0 +1,58 @@ +// Copyright (C) 2017 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.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +Rectangle { + id: indicator + + property Item control + readonly property color pressedColor: Fusion.mergedColors(control.palette.base, control.palette.windowText, 85) + readonly property color checkMarkColor: Qt.darker(control.palette.text, 1.2) + + implicitWidth: 14 + implicitHeight: 14 + + color: control.down ? indicator.pressedColor : control.palette.base + border.color: control.visualFocus ? Fusion.highlightedOutline(control.palette) + : Qt.lighter(Fusion.outline(control.palette), 1.1) + + Rectangle { + x: 1; y: 1 + width: parent.width - 2 + height: 1 + color: Fusion.topShadow + visible: indicator.control.enabled && !indicator.control.down + } + + ColorImage { + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + color: Color.transparent(indicator.checkMarkColor, 210 / 255) + source: "qrc:/qt-project.org/imports/QtQuick/Controls/Fusion/images/checkmark.png" + visible: indicator.control.checkState === Qt.Checked || (indicator.control.checked && indicator.control.checkState === undefined) + } + + Rectangle { + x: 3; y: 3 + width: parent.width - 6 + height: parent.width - 6 + + visible: indicator.control.checkState === Qt.PartiallyChecked + + gradient: Gradient { + GradientStop { + position: 0 + color: Color.transparent(indicator.checkMarkColor, 80 / 255) + } + GradientStop { + position: 1 + color: Color.transparent(indicator.checkMarkColor, 140 / 255) + } + } + border.color: Color.transparent(indicator.checkMarkColor, 180 / 255) + } +} diff --git a/src/quickcontrols/fusion/impl/RadioIndicator.qml b/src/quickcontrols/fusion/impl/RadioIndicator.qml new file mode 100644 index 0000000000..0949b904a9 --- /dev/null +++ b/src/quickcontrols/fusion/impl/RadioIndicator.qml @@ -0,0 +1,44 @@ +// Copyright (C) 2017 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.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +Rectangle { + id: indicator + + property Item control + readonly property color pressedColor: Fusion.mergedColors(control.palette.base, control.palette.windowText, 85) + readonly property color checkMarkColor: Qt.darker(control.palette.text, 1.2) + + implicitWidth: 14 + implicitHeight: 14 + + radius: width / 2 + color: control.down ? indicator.pressedColor : control.palette.base + border.color: control.visualFocus ? Fusion.highlightedOutline(control.palette) + : Qt.darker(control.palette.window, 1.5) + + Rectangle { + y: 1 + width: parent.width + height: parent.height - 1 + radius: width / 2 + color: "transparent" + border.color: Fusion.topShadow + visible: indicator.control.enabled && !indicator.control.down + } + + Rectangle { + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + width: parent.width / 2.32 + height: parent.height / 2.32 + radius: width / 2 + color: Color.transparent(indicator.checkMarkColor, 180 / 255) + border.color: Color.transparent(indicator.checkMarkColor, 200 / 255) + visible: indicator.control.checked + } +} diff --git a/src/quickcontrols/fusion/impl/SliderGroove.qml b/src/quickcontrols/fusion/impl/SliderGroove.qml new file mode 100644 index 0000000000..8cfdd836b3 --- /dev/null +++ b/src/quickcontrols/fusion/impl/SliderGroove.qml @@ -0,0 +1,60 @@ +// Copyright (C) 2017 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.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +Rectangle { + id: groove + + property Item control + property real offset + property real progress + property real visualProgress + + x: control.horizontal ? 0 : (control.availableWidth - width) / 2 + y: control.horizontal ? (control.availableHeight - height) / 2 : 0 + + implicitWidth: control.horizontal ? 160 : 5 + implicitHeight: control.horizontal ? 5 : 160 + width: control.horizontal ? control.availableWidth : implicitWidth + height: control.horizontal ? implicitHeight : control.availableHeight + + radius: 2 + border.color: Fusion.outline(control.palette) + scale: control.horizontal && control.mirrored ? -1 : 1 + + gradient: Gradient { + GradientStop { + position: 0 + color: Qt.darker(Fusion.grooveColor(groove.control.palette), 1.1) + } + GradientStop { + position: 1 + color: Qt.lighter(Fusion.grooveColor(groove.control.palette), 1.1) + } + } + + Rectangle { + x: groove.control.horizontal ? groove.offset * parent.width : 0 + y: groove.control.horizontal ? 0 : groove.visualProgress * parent.height + width: groove.control.horizontal ? groove.progress * parent.width - groove.offset * parent.width : 5 + height: groove.control.horizontal ? 5 : groove.progress * parent.height - groove.offset * parent.height + + radius: 2 + border.color: Qt.darker(Fusion.highlightedOutline(groove.control.palette), 1.1) + + gradient: Gradient { + GradientStop { + position: 0 + color: Fusion.highlight(groove.control.palette) + } + GradientStop { + position: 1 + color: Qt.lighter(Fusion.highlight(groove.control.palette), 1.2) + } + } + } +} diff --git a/src/quickcontrols/fusion/impl/SliderHandle.qml b/src/quickcontrols/fusion/impl/SliderHandle.qml new file mode 100644 index 0000000000..e12d4c0bb7 --- /dev/null +++ b/src/quickcontrols/fusion/impl/SliderHandle.qml @@ -0,0 +1,54 @@ +// Copyright (C) 2017 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.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +Rectangle { + id: handle + + property var palette + property bool pressed + property bool hovered + property bool vertical + property bool visualFocus + + implicitWidth: 13 + implicitHeight: 13 + + gradient: Gradient { + GradientStop { + position: 0 + color: Fusion.gradientStart(Fusion.buttonColor(handle.palette, handle.visualFocus, + handle.pressed, handle.enabled && handle.hovered)) + } + GradientStop { + position: 1 + color: Fusion.gradientStop(Fusion.buttonColor(handle.palette, handle.visualFocus, + handle.pressed, handle.enabled && handle.hovered)) + } + } + rotation: handle.vertical ? -90 : 0 + border.width: 1 + border.color: "transparent" + radius: 2 + + Rectangle { + width: parent.width + height: parent.height + border.color: handle.visualFocus ? Fusion.highlightedOutline(handle.palette) : Fusion.outline(handle.palette) + color: "transparent" + radius: 2 + + Rectangle { + x: 1; y: 1 + width: parent.width - 2 + height: parent.height - 2 + border.color: Fusion.innerContrastLine + color: "transparent" + radius: 2 + } + } +} diff --git a/src/quickcontrols/fusion/impl/SwitchIndicator.qml b/src/quickcontrols/fusion/impl/SwitchIndicator.qml new file mode 100644 index 0000000000..39e47c0e91 --- /dev/null +++ b/src/quickcontrols/fusion/impl/SwitchIndicator.qml @@ -0,0 +1,109 @@ +// Copyright (C) 2017 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.Templates as T +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl + +Rectangle { + id: indicator + + property T.AbstractButton control + readonly property color pressedColor: Fusion.mergedColors(control.palette.base, control.palette.windowText, 85) + readonly property color checkMarkColor: Qt.darker(control.palette.text, 1.2) + + implicitWidth: 40 + implicitHeight: 16 + + radius: 2 + border.color: Fusion.outline(control.palette) + + gradient: Gradient { + GradientStop { + position: 0 + color: Qt.darker(Fusion.grooveColor(indicator.control.palette), 1.1) + } + GradientStop { + position: 1 + color: Qt.lighter(Fusion.grooveColor(indicator.control.palette), 1.1) + } + } + + Rectangle { + x: indicator.control.mirrored ? handle.x : 0 + width: indicator.control.mirrored ? parent.width - handle.x : handle.x + handle.width + height: parent.height + + opacity: indicator.control.checked ? 1 : 0 + Behavior on opacity { + enabled: !indicator.control.down + NumberAnimation { duration: 80 } + } + + radius: 2 + border.color: Qt.darker(Fusion.highlightedOutline(indicator.control.palette), 1.1) + border.width: indicator.control.enabled ? 1 : 0 + + gradient: Gradient { + GradientStop { + position: 0 + color: Qt.alpha(indicator.control.palette.active.highlight, + indicator.Window ? indicator.Window.active ? 1 : 0.5 : 1) + } + GradientStop { + position: 1 + color: Qt.alpha(Qt.lighter(indicator.control.palette.active.highlight, 1.2), + indicator.Window ? indicator.Window.active ? 1 : 0.5 : 1) + } + } + } + + Rectangle { + id: handle + x: Math.max(0, Math.min(parent.width - width, indicator.control.visualPosition * parent.width - (width / 2))) + y: (parent.height - height) / 2 + width: 20 + height: 16 + radius: 2 + + gradient: Gradient { + GradientStop { + position: 0 + color: Fusion.gradientStart(Fusion.buttonColor(indicator.control.palette, + indicator.control.visualFocus, indicator.control.pressed, indicator.enabled && indicator.control.hovered)) + } + GradientStop { + position: 1 + color: Fusion.gradientStop(Fusion.buttonColor(indicator.control.palette, + indicator.control.visualFocus, indicator.control.pressed, indicator.enabled && indicator.control.hovered)) + } + } + border.width: 1 + border.color: "transparent" + + Rectangle { + width: parent.width + height: parent.height + border.color: indicator.control.visualFocus ? Fusion.highlightedOutline(indicator.control.palette) : Fusion.outline(indicator.control.palette) + color: "transparent" + radius: 2 + + Rectangle { + x: 1; y: 1 + width: parent.width - 2 + height: parent.height - 2 + border.color: Fusion.innerContrastLine + color: "transparent" + radius: 2 + } + } + + Behavior on x { + enabled: !indicator.control.down + SmoothedAnimation { velocity: 200 } + } + } +} diff --git a/src/quickcontrols/fusion/impl/qquickfusionbusyindicator.cpp b/src/quickcontrols/fusion/impl/qquickfusionbusyindicator.cpp new file mode 100644 index 0000000000..8e58b09ed3 --- /dev/null +++ b/src/quickcontrols/fusion/impl/qquickfusionbusyindicator.cpp @@ -0,0 +1,89 @@ +// Copyright (C) 2017 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 "qquickfusionbusyindicator_p.h" + +#include <QtGui/qpainter.h> + +QT_BEGIN_NAMESPACE + +QQuickFusionBusyIndicator::QQuickFusionBusyIndicator(QQuickItem *parent) + : QQuickPaintedItem(parent) +{ +} + +QColor QQuickFusionBusyIndicator::color() const +{ + return m_color; +} + +void QQuickFusionBusyIndicator::setColor(const QColor &color) +{ + if (color == m_color) + return; + + m_color = color; + update(); +} + +bool QQuickFusionBusyIndicator::isRunning() const +{ + return isVisible(); +} + +void QQuickFusionBusyIndicator::setRunning(bool running) +{ + if (running) { + setVisible(true); + update(); + } +} + +void QQuickFusionBusyIndicator::paint(QPainter *painter) +{ + const qreal w = width(); + const qreal h = height(); + if (w <= 0 || h <= 0 || !isRunning()) + return; + + const qreal sz = qMin(w, h); + const qreal dx = (w - sz) / 2; + const qreal dy = (h - sz) / 2; + const int hpw = qRound(qMax(qreal(1), sz / 14)) & -1; + const int pw = 2 * hpw; + const QRectF bounds(dx + hpw, dy + hpw, sz - pw - 1, sz - pw - 1); + + QConicalGradient gradient; + gradient.setCenter(QPointF(dx + sz / 2, dy + sz / 2)); + gradient.setColorAt(0, m_color); + gradient.setColorAt(0.1, m_color); + gradient.setColorAt(1, Qt::transparent); + + painter->translate(0.5, 0.5); + painter->setRenderHint(QPainter::Antialiasing, true); + painter->setPen(QPen(gradient, pw, Qt::SolidLine)); + painter->drawArc(bounds, 0, 360 * 16); + painter->setPen(QPen(m_color, pw, Qt::SolidLine, Qt::RoundCap)); + painter->drawArc(bounds, 0, 20 * 16); +} + +void QQuickFusionBusyIndicator::itemChange(ItemChange change, const ItemChangeData &data) +{ + QQuickPaintedItem::itemChange(change, data); + + switch (change) { + case ItemOpacityHasChanged: + if (qFuzzyIsNull(data.realValue)) + setVisible(false); + break; + case ItemVisibleHasChanged: + update(); + break; + default: + break; + } +} + +QT_END_NAMESPACE + +#include "moc_qquickfusionbusyindicator_p.cpp" diff --git a/src/quickcontrols/fusion/impl/qquickfusionbusyindicator_p.h b/src/quickcontrols/fusion/impl/qquickfusionbusyindicator_p.h new file mode 100644 index 0000000000..22ff2af788 --- /dev/null +++ b/src/quickcontrols/fusion/impl/qquickfusionbusyindicator_p.h @@ -0,0 +1,52 @@ +// Copyright (C) 2021 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 + +#ifndef QQUICKFUSIONBUSYINDICATOR_P_H +#define QQUICKFUSIONBUSYINDICATOR_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtGui/qcolor.h> +#include <QtQuick/qquickpainteditem.h> +#include <QtCore/private/qglobal_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickFusionBusyIndicator : public QQuickPaintedItem +{ + Q_OBJECT + Q_PROPERTY(QColor color READ color WRITE setColor FINAL) + Q_PROPERTY(bool running READ isRunning WRITE setRunning) + QML_NAMED_ELEMENT(BusyIndicatorImpl) + QML_ADDED_IN_VERSION(2, 3) + +public: + explicit QQuickFusionBusyIndicator(QQuickItem *parent = nullptr); + + QColor color() const; + void setColor(const QColor &color); + + bool isRunning() const; + void setRunning(bool running); + + void paint(QPainter *painter) override; + +protected: + void itemChange(ItemChange change, const ItemChangeData &data) override; + +private: + QColor m_color; +}; + +QT_END_NAMESPACE + +#endif // QQUICKFUSIONBUSYINDICATOR_P_H diff --git a/src/quickcontrols/fusion/impl/qquickfusiondial.cpp b/src/quickcontrols/fusion/impl/qquickfusiondial.cpp new file mode 100644 index 0000000000..99b022726c --- /dev/null +++ b/src/quickcontrols/fusion/impl/qquickfusiondial.cpp @@ -0,0 +1,108 @@ +// Copyright (C) 2017 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 "qquickfusiondial_p.h" + +#include <QtGui/qpainter.h> +#include <QtGui/private/qmath_p.h> +#include <QtQuick/private/qquickpalette_p.h> +#include <QtQuick/private/qquickitem_p.h> + +QT_BEGIN_NAMESPACE + +QQuickFusionDial::QQuickFusionDial(QQuickItem *parent) + : QQuickPaintedItem(parent) +{ +} + +bool QQuickFusionDial::highlight() const +{ + return m_highlight; +} + +void QQuickFusionDial::setHighlight(bool highlight) +{ + if (m_highlight == highlight) + return; + + m_highlight = highlight; + update(); +} + +// based on QStyleHelper::drawDial() +void QQuickFusionDial::paint(QPainter *painter) +{ + const int width = QQuickItem::width(); + const int height = QQuickItem::height(); + if (width <= 0 || height <= 0 || !isVisible()) + return; + + const bool enabled = isEnabled(); + qreal r = qMin(width, height) / 2.0; + r -= r/50; + const qreal penSize = r/20.0; + + painter->setRenderHint(QPainter::Antialiasing); + + const qreal d_ = r / 6; + const qreal dx = d_ + (width - 2 * r) / 2 + 1; + const qreal dy = d_ + (height - 2 * r) / 2 + 1; + + QRectF br = QRectF(dx + 0.5, dy + 0.5, + int(r * 2 - 2 * d_ - 2), + int(r * 2 - 2 * d_ - 2)); + QColor buttonColor = QQuickItemPrivate::get(this)->palette()->button().toHsv(); + buttonColor.setHsv(buttonColor .hue(), + qMin(140, buttonColor .saturation()), + qMax(180, buttonColor.value())); + + if (enabled) { + // Drop shadow + qreal shadowSize = qMax(1.0, penSize/2.0); + QRectF shadowRect= br.adjusted(-2*shadowSize, -2*shadowSize, + 2*shadowSize, 2*shadowSize); + QRadialGradient shadowGradient(shadowRect.center().x(), + shadowRect.center().y(), shadowRect.width()/2.0, + shadowRect.center().x(), shadowRect.center().y()); + shadowGradient.setColorAt(qreal(0.91), QColor(0, 0, 0, 40)); + shadowGradient.setColorAt(qreal(1.0), Qt::transparent); + painter->setBrush(shadowGradient); + painter->setPen(Qt::NoPen); + painter->translate(shadowSize, shadowSize); + painter->drawEllipse(shadowRect); + painter->translate(-shadowSize, -shadowSize); + + // Main gradient + QRadialGradient gradient(br.center().x() - br.width()/3, dy, + br.width()*1.3, br.center().x(), + br.center().y() - br.height()/2); + gradient.setColorAt(0, buttonColor.lighter(110)); + gradient.setColorAt(qreal(0.5), buttonColor); + gradient.setColorAt(qreal(0.501), buttonColor.darker(102)); + gradient.setColorAt(1, buttonColor.darker(115)); + painter->setBrush(gradient); + } else { + painter->setBrush(Qt::NoBrush); + } + + painter->setPen(QPen(buttonColor.darker(280))); + painter->drawEllipse(br); + painter->setBrush(Qt::NoBrush); + painter->setPen(buttonColor.lighter(110)); + painter->drawEllipse(br.adjusted(1, 1, -1, -1)); + + if (m_highlight) { + QColor highlight = QQuickItemPrivate::get(this)->palette()->highlight().toHsv(); + highlight.setHsv(highlight.hue(), + qMin(160, highlight.saturation()), + qMax(230, highlight.value())); + highlight.setAlpha(127); + painter->setPen(QPen(highlight, 2.0)); + painter->setBrush(Qt::NoBrush); + painter->drawEllipse(br.adjusted(-1, -1, 1, 1)); + } +} + +QT_END_NAMESPACE + +#include "moc_qquickfusiondial_p.cpp" diff --git a/src/quickcontrols/fusion/impl/qquickfusiondial_p.h b/src/quickcontrols/fusion/impl/qquickfusiondial_p.h new file mode 100644 index 0000000000..3167c81515 --- /dev/null +++ b/src/quickcontrols/fusion/impl/qquickfusiondial_p.h @@ -0,0 +1,44 @@ +// Copyright (C) 2021 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 + +#ifndef QQUICKFUSIONDIAL_P_H +#define QQUICKFUSIONDIAL_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuick/qquickpainteditem.h> +#include <QtCore/private/qglobal_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickFusionDial : public QQuickPaintedItem +{ + Q_OBJECT + Q_PROPERTY(bool highlight READ highlight WRITE setHighlight FINAL) + QML_NAMED_ELEMENT(DialImpl) + QML_ADDED_IN_VERSION(2, 3) + +public: + explicit QQuickFusionDial(QQuickItem *parent = nullptr); + + bool highlight() const; + void setHighlight(bool highlight); + + void paint(QPainter *painter) override; + +private: + bool m_highlight = false; +}; + +QT_END_NAMESPACE + +#endif // QQUICKFUSIONDIAL_P_H diff --git a/src/quickcontrols/fusion/impl/qquickfusionknob.cpp b/src/quickcontrols/fusion/impl/qquickfusionknob.cpp new file mode 100644 index 0000000000..00be4bd759 --- /dev/null +++ b/src/quickcontrols/fusion/impl/qquickfusionknob.cpp @@ -0,0 +1,57 @@ +// Copyright (C) 2017 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 "qquickfusionknob_p.h" + +#include <QtCore/qmath.h> +#include <QtGui/qpainter.h> +#include <QtQuick/private/qquickpalette_p.h> +#include <QtQuick/private/qquickitem_p.h> + +QT_BEGIN_NAMESPACE + +QQuickFusionKnob::QQuickFusionKnob(QQuickItem *parent) + : QQuickPaintedItem(parent) +{ + connect(this, &QQuickItem::paletteChanged, this, [this](){ update(); }); +} + +// extracted from QStyleHelper::drawDial() +void QQuickFusionKnob::paint(QPainter *painter) +{ + const qreal w = width(); + const qreal h = height(); + if (w <= 0 || h <= 0) + return; + + QColor color = QQuickItemPrivate::get(this)->palette()->button().toHsv(); + color.setHsv(color.hue(), + qMin(140, color .saturation()), + qMax(180, color.value())); + color = color.lighter(104); + color.setAlphaF(0.8f); + + const qreal sz = qMin(w, h); + QRectF rect(0, 0, sz, sz); + rect.moveCenter(QPointF(w / 2.0, h / 2.0)); + const QPointF center = rect.center(); + + QRadialGradient gradient(center.x() + rect.width() / 2, + center.y() + rect.width(), + rect.width() * 2, + center.x(), center.y()); + gradient.setColorAt(1, color.darker(140)); + gradient.setColorAt(qreal(0.4), color.darker(120)); + gradient.setColorAt(0, color.darker(110)); + + painter->setRenderHint(QPainter::Antialiasing); + painter->setBrush(gradient); + painter->setPen(QColor(255, 255, 255, 150)); + painter->drawEllipse(rect); + painter->setPen(QColor(0, 0, 0, 80)); + painter->drawEllipse(rect.adjusted(1, 1, -1, -1)); +} + +QT_END_NAMESPACE + +#include "moc_qquickfusionknob_p.cpp" diff --git a/src/quickcontrols/fusion/impl/qquickfusionknob_p.h b/src/quickcontrols/fusion/impl/qquickfusionknob_p.h new file mode 100644 index 0000000000..909aa4ffc6 --- /dev/null +++ b/src/quickcontrols/fusion/impl/qquickfusionknob_p.h @@ -0,0 +1,37 @@ +// Copyright (C) 2021 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 + +#ifndef QQUICKFUSIONKNOB_P_H +#define QQUICKFUSIONKNOB_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuick/qquickpainteditem.h> +#include <QtCore/private/qglobal_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickFusionKnob : public QQuickPaintedItem +{ + Q_OBJECT + QML_NAMED_ELEMENT(KnobImpl) + QML_ADDED_IN_VERSION(2, 3) + +public: + explicit QQuickFusionKnob(QQuickItem *parent = nullptr); + + void paint(QPainter *painter) override; +}; + +QT_END_NAMESPACE + +#endif // QQUICKFUSIONKNOB_P_H diff --git a/src/quickcontrols/fusion/qquickfusionstyle.cpp b/src/quickcontrols/fusion/qquickfusionstyle.cpp new file mode 100644 index 0000000000..fec1a674bf --- /dev/null +++ b/src/quickcontrols/fusion/qquickfusionstyle.cpp @@ -0,0 +1,122 @@ +// Copyright (C) 2017 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 "qquickfusionstyle_p.h" + +#include <QtGui/qcolor.h> +#include <QtGui/qpalette.h> +#include <QtGui/qpa/qplatformtheme.h> +#include <QtGui/private/qguiapplication_p.h> + +#include <QtQuick/private/qquickpalette_p.h> + +QT_BEGIN_NAMESPACE + +QQuickFusionStyle::QQuickFusionStyle(QObject *parent) + : QObject(parent) +{ +} + +QColor QQuickFusionStyle::lightShade() +{ + return QColor(255, 255, 255, 90); +} + +QColor QQuickFusionStyle::darkShade() +{ + return QColor(0, 0, 0, 60); +} + +QColor QQuickFusionStyle::topShadow() +{ + return QColor(0, 0, 0, 18); +} + +QColor QQuickFusionStyle::innerContrastLine() +{ + return QColor(255, 255, 255, 30); +} + +QColor QQuickFusionStyle::highlight(QQuickPalette *palette) +{ + return palette->highlight(); +} + +QColor QQuickFusionStyle::highlightedText(QQuickPalette *palette) +{ + return palette->highlightedText(); +} + +QColor QQuickFusionStyle::outline(QQuickPalette *palette) +{ + return palette->window().darker(140); +} + +QColor QQuickFusionStyle::highlightedOutline(QQuickPalette *palette) +{ + QColor highlightedOutline = highlight(palette).darker(125).toHsv(); + if (highlightedOutline.value() > 160) + highlightedOutline.setHsl(highlightedOutline.hue(), highlightedOutline.saturation(), 160); + return highlightedOutline; +} + +QColor QQuickFusionStyle::tabFrameColor(QQuickPalette *palette) +{ + return buttonColor(palette).lighter(104); +} + +QColor QQuickFusionStyle::buttonColor(QQuickPalette *palette, bool highlighted, bool down, bool hovered) +{ + QColor buttonColor = palette->button(); + int val = qGray(buttonColor.rgb()); + buttonColor = buttonColor.lighter(100 + qMax(1, (180 - val)/6)); + buttonColor = buttonColor.toHsv(); + buttonColor.setHsv(buttonColor.hue(), int(buttonColor.saturation() * 0.75), buttonColor.value()); + if (highlighted) + buttonColor = mergedColors(buttonColor, highlightedOutline(palette).lighter(130), 90); + if (!hovered) + buttonColor = buttonColor.darker(104); + if (down) + buttonColor = buttonColor.darker(110); + return buttonColor; +} + +QColor QQuickFusionStyle::buttonOutline(QQuickPalette *palette, bool highlighted, bool enabled) +{ + QColor darkOutline = enabled && highlighted ? highlightedOutline(palette) : outline(palette); + return !enabled ? darkOutline.lighter(115) : darkOutline; +} + +QColor QQuickFusionStyle::gradientStart(const QColor &baseColor) +{ + return baseColor.lighter(124); +} + +QColor QQuickFusionStyle::gradientStop(const QColor &baseColor) +{ + return baseColor.lighter(102); +} + +QColor QQuickFusionStyle::mergedColors(const QColor &colorA, const QColor &colorB, int factor) +{ + const int maxFactor = 100; + const auto rgbColorB = colorB.toRgb(); + QColor tmp = colorA.toRgb(); + tmp.setRed((tmp.red() * factor) / maxFactor + (rgbColorB.red() * (maxFactor - factor)) / maxFactor); + tmp.setGreen((tmp.green() * factor) / maxFactor + (rgbColorB.green() * (maxFactor - factor)) / maxFactor); + tmp.setBlue((tmp.blue() * factor) / maxFactor + (rgbColorB.blue() * (maxFactor - factor)) / maxFactor); + return tmp; +} + +QColor QQuickFusionStyle::grooveColor(QQuickPalette *palette) +{ + QColor color = buttonColor(palette).toHsv(); + color.setHsv(color.hue(), + qMin(255, color.saturation()), + qMin<int>(255, color.value() * 0.9)); + return color; +} + +QT_END_NAMESPACE + +#include "moc_qquickfusionstyle_p.cpp" diff --git a/src/quickcontrols/fusion/qquickfusionstyle_p.h b/src/quickcontrols/fusion/qquickfusionstyle_p.h new file mode 100644 index 0000000000..47fdd77fd7 --- /dev/null +++ b/src/quickcontrols/fusion/qquickfusionstyle_p.h @@ -0,0 +1,61 @@ +// Copyright (C) 2017 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 + +#ifndef QQUICKFUSIONSTYLE_P_H +#define QQUICKFUSIONSTYLE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qobject.h> +#include <QtGui/qcolor.h> +#include <QtQml/qqml.h> +#include <QtQuickControls2Fusion/qtquickcontrols2fusionexports.h> + +QT_BEGIN_NAMESPACE + +class QQuickPalette; + +class Q_QUICKCONTROLS2FUSION_EXPORT QQuickFusionStyle : public QObject +{ + Q_OBJECT + Q_PROPERTY(QColor lightShade READ lightShade CONSTANT FINAL) + Q_PROPERTY(QColor darkShade READ darkShade CONSTANT FINAL) + Q_PROPERTY(QColor topShadow READ topShadow CONSTANT FINAL) + Q_PROPERTY(QColor innerContrastLine READ innerContrastLine CONSTANT FINAL) + QML_NAMED_ELEMENT(Fusion) + QML_SINGLETON + QML_ADDED_IN_VERSION(2, 3) + +public: + explicit QQuickFusionStyle(QObject *parent = nullptr); + + static QColor lightShade(); + static QColor darkShade(); + static QColor topShadow(); + static QColor innerContrastLine(); + + Q_INVOKABLE static QColor highlight(QQuickPalette *palette); + Q_INVOKABLE static QColor highlightedText(QQuickPalette *palette); + Q_INVOKABLE static QColor outline(QQuickPalette *palette); + Q_INVOKABLE static QColor highlightedOutline(QQuickPalette *palette); + Q_INVOKABLE static QColor tabFrameColor(QQuickPalette *palette); + Q_INVOKABLE static QColor buttonColor(QQuickPalette *palette, bool highlighted = false, bool down = false, bool hovered = false); + Q_INVOKABLE static QColor buttonOutline(QQuickPalette *palette, bool highlighted = false, bool enabled = true); + Q_INVOKABLE static QColor gradientStart(const QColor &baseColor); + Q_INVOKABLE static QColor gradientStop(const QColor &baseColor); + Q_INVOKABLE static QColor mergedColors(const QColor &colorA, const QColor &colorB, int factor = 50); + Q_INVOKABLE static QColor grooveColor(QQuickPalette *palette); +}; + +QT_END_NAMESPACE + +#endif // QQUICKFUSIONSTYLE_P_H diff --git a/src/quickcontrols/fusion/qquickfusiontheme.cpp b/src/quickcontrols/fusion/qquickfusiontheme.cpp new file mode 100644 index 0000000000..9d8086b608 --- /dev/null +++ b/src/quickcontrols/fusion/qquickfusiontheme.cpp @@ -0,0 +1,18 @@ +// 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 "qquickfusiontheme_p.h" + +#include <QtQuickTemplates2/private/qquicktheme_p.h> +#include <QtQuickControls2/private/qquickstyle_p.h> + +QT_BEGIN_NAMESPACE + +void QQuickFusionTheme::initialize(QQuickTheme *theme) +{ + // Enable platform palettes for fusion theme. + if (theme) + theme->setUsePlatformPalette(true); +} + +QT_END_NAMESPACE diff --git a/src/quickcontrols/fusion/qquickfusiontheme_p.h b/src/quickcontrols/fusion/qquickfusiontheme_p.h new file mode 100644 index 0000000000..b60521394c --- /dev/null +++ b/src/quickcontrols/fusion/qquickfusiontheme_p.h @@ -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 + +#ifndef QQUICKFUSIONTHEME_P_H +#define QQUICKFUSIONTHEME_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickControls2Fusion/qtquickcontrols2fusionexports.h> + +QT_BEGIN_NAMESPACE + +class QQuickTheme; + +class Q_QUICKCONTROLS2FUSION_EXPORT QQuickFusionTheme +{ +public: + static void initialize(QQuickTheme *theme); +}; + +QT_END_NAMESPACE + +#endif // QQUICKFUSIONTHEME_P_H diff --git a/src/quickcontrols/fusion/qtquickcontrols2fusionstyleplugin.cpp b/src/quickcontrols/fusion/qtquickcontrols2fusionstyleplugin.cpp new file mode 100644 index 0000000000..f61dafa478 --- /dev/null +++ b/src/quickcontrols/fusion/qtquickcontrols2fusionstyleplugin.cpp @@ -0,0 +1,47 @@ +// Copyright (C) 2017 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 "qquickfusionstyle_p.h" +#include "qquickfusiontheme_p.h" + +#include <QtQml/qqml.h> +#include <QtQuickControls2/private/qquickstyleplugin_p.h> + +QT_BEGIN_NAMESPACE + +extern void qml_register_types_QtQuick_Controls_Fusion(); +Q_GHS_KEEP_REFERENCE(qml_register_types_QtQuick_Controls_Fusion); + +class QtQuickControls2FusionStylePlugin : public QQuickStylePlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid) + +public: + QtQuickControls2FusionStylePlugin(QObject *parent = nullptr); + + QString name() const override; + void initializeTheme(QQuickTheme *theme) override; + + QQuickFusionTheme theme; +}; + +QtQuickControls2FusionStylePlugin::QtQuickControls2FusionStylePlugin(QObject *parent) : QQuickStylePlugin(parent) +{ + volatile auto registration = &qml_register_types_QtQuick_Controls_Fusion; + Q_UNUSED(registration); +} + +QString QtQuickControls2FusionStylePlugin::name() const +{ + return QStringLiteral("Fusion"); +} + +void QtQuickControls2FusionStylePlugin::initializeTheme(QQuickTheme *theme) +{ + this->theme.initialize(theme); +} + +QT_END_NAMESPACE + +#include "qtquickcontrols2fusionstyleplugin.moc" |