aboutsummaryrefslogtreecommitdiffstats
path: root/src/quicknativestyle
diff options
context:
space:
mode:
Diffstat (limited to 'src/quicknativestyle')
-rw-r--r--src/quicknativestyle/CMakeLists.txt34
-rw-r--r--src/quicknativestyle/controls/DefaultComboBox.qml7
-rw-r--r--src/quicknativestyle/controls/DefaultItemDelegate.qml32
-rw-r--r--src/quicknativestyle/controls/DefaultItemDelegateIconLabel.qml21
-rw-r--r--src/quicknativestyle/controls/DefaultProgressBar.qml5
-rw-r--r--src/quicknativestyle/controls/DefaultRadioDelegate.qml54
-rw-r--r--src/quicknativestyle/controls/DefaultScrollBar.qml2
-rw-r--r--src/quicknativestyle/controls/DefaultTextArea.qml4
-rw-r--r--src/quicknativestyle/controls/DefaultTreeViewDelegate.qml8
-rw-r--r--src/quicknativestyle/items/qquickstyleitem.h4
-rw-r--r--src/quicknativestyle/items/qquickstyleitembutton.h2
-rw-r--r--src/quicknativestyle/items/qquickstyleitemcheckbox.h2
-rw-r--r--src/quicknativestyle/items/qquickstyleitemcheckdelegate.cpp32
-rw-r--r--src/quicknativestyle/items/qquickstyleitemcheckdelegate.h25
-rw-r--r--src/quicknativestyle/items/qquickstyleitemdelaybutton.cpp28
-rw-r--r--src/quicknativestyle/items/qquickstyleitemdelaybutton.h25
-rw-r--r--src/quicknativestyle/items/qquickstyleitemdial.cpp4
-rw-r--r--src/quicknativestyle/items/qquickstyleitemradiobutton.h2
-rw-r--r--src/quicknativestyle/items/qquickstyleitemradiodelegate.cpp29
-rw-r--r--src/quicknativestyle/items/qquickstyleitemradiodelegate.h25
-rw-r--r--src/quicknativestyle/items/qquickstyleitemscrollbar.cpp8
-rw-r--r--src/quicknativestyle/items/qquickstyleitemscrollbar.h2
-rw-r--r--src/quicknativestyle/qstyle/mac/qquickmacstyle_mac.mm88
-rw-r--r--src/quicknativestyle/qstyle/qquickcommonstyle.cpp42
-rw-r--r--src/quicknativestyle/qstyle/qquickcommonstyle_p.h4
-rw-r--r--src/quicknativestyle/qstyle/qquickstylehelper.cpp9
-rw-r--r--src/quicknativestyle/qstyle/qquickstyleoption.cpp2
-rw-r--r--src/quicknativestyle/qstyle/qquickstyleoption.h11
-rw-r--r--src/quicknativestyle/qstyle/windows/qquickwindowsstyle.cpp2
-rw-r--r--src/quicknativestyle/qstyle/windows/qquickwindowsxpstyle.cpp18
-rw-r--r--src/quicknativestyle/qtquickcontrols2nativestyleplugin.cpp13
-rw-r--r--src/quicknativestyle/util/MacFocusFrame.qml (renamed from src/quicknativestyle/util/FocusFrame.qml)4
-rw-r--r--src/quicknativestyle/util/WindowsFocusFrame.qml58
-rw-r--r--src/quicknativestyle/util/qquickfocusframe.cpp118
-rw-r--r--src/quicknativestyle/util/qquickfocusframe.h39
-rw-r--r--src/quicknativestyle/util/qquickmacfocusframe.h26
-rw-r--r--src/quicknativestyle/util/qquickmacfocusframe.mm126
-rw-r--r--src/quicknativestyle/util/qquickwindowsfocusframe.cpp17
-rw-r--r--src/quicknativestyle/util/qquickwindowsfocusframe.h24
39 files changed, 680 insertions, 276 deletions
diff --git a/src/quicknativestyle/CMakeLists.txt b/src/quicknativestyle/CMakeLists.txt
index a1c1739d40..c5056d33b7 100644
--- a/src/quicknativestyle/CMakeLists.txt
+++ b/src/quicknativestyle/CMakeLists.txt
@@ -7,22 +7,27 @@
set(qml_files
"controls/DefaultButton.qml"
- "controls/DefaultSlider.qml"
- "controls/DefaultGroupBox.qml"
"controls/DefaultCheckBox.qml"
+ "controls/DefaultComboBox.qml"
+ "controls/DefaultDial.qml"
+ "controls/DefaultFrame.qml"
+ "controls/DefaultGroupBox.qml"
+ "controls/DefaultItemDelegate.qml"
+ "controls/DefaultItemDelegateIconLabel.qml"
+ "controls/DefaultProgressBar.qml"
"controls/DefaultRadioButton.qml"
+ "controls/DefaultRadioDelegate.qml"
+ "controls/DefaultScrollBar.qml"
+ "controls/DefaultSlider.qml"
"controls/DefaultSpinBox.qml"
- "controls/DefaultTextField.qml"
- "controls/DefaultFrame.qml"
"controls/DefaultTextArea.qml"
- "controls/DefaultComboBox.qml"
- "controls/DefaultScrollBar.qml"
- "controls/DefaultProgressBar.qml"
- "controls/DefaultDial.qml"
+ "controls/DefaultTextField.qml"
)
if(MACOS)
- list(APPEND qml_files "util/FocusFrame.qml")
+ list(APPEND qml_files "util/MacFocusFrame.qml")
+elseif(WIN32)
+ list(APPEND qml_files "util/WindowsFocusFrame.qml")
endif()
if(QT_FEATURE_quick_treeview)
@@ -45,12 +50,14 @@ qt_internal_add_qml_module(qtquickcontrols2nativestyleplugin
items/qquickstyleitem.cpp items/qquickstyleitem.h
items/qquickstyleitembutton.cpp items/qquickstyleitembutton.h
items/qquickstyleitemcheckbox.cpp items/qquickstyleitemcheckbox.h
- items/qquickstyleitemcombobox.cpp items/qquickstyleitemcombobox.h
+ items/qquickstyleitemdelaybutton.cpp items/qquickstyleitemdelaybutton.h
+ items/qquickstyleitemcheckdelegate.cpp items/qquickstyleitemcheckdelegate.h
items/qquickstyleitemdial.cpp items/qquickstyleitemdial.h
items/qquickstyleitemframe.cpp items/qquickstyleitemframe.h
items/qquickstyleitemgroupbox.cpp items/qquickstyleitemgroupbox.h
items/qquickstyleitemprogressbar.cpp items/qquickstyleitemprogressbar.h
items/qquickstyleitemradiobutton.cpp items/qquickstyleitemradiobutton.h
+ items/qquickstyleitemradiodelegate.cpp items/qquickstyleitemradiodelegate.h
items/qquickstyleitemscrollbar.cpp items/qquickstyleitemscrollbar.h
items/qquickstyleitemslider.cpp items/qquickstyleitemslider.h
items/qquickstyleitemspinbox.cpp items/qquickstyleitemspinbox.h
@@ -63,6 +70,7 @@ qt_internal_add_qml_module(qtquickcontrols2nativestyleplugin
qstyle/qquickstylehelper.cpp qstyle/qquickstylehelper_p.h
qstyle/qquickstyleoption.cpp qstyle/qquickstyleoption.h
qtquickcontrols2nativestyleplugin.cpp
+ util/qquickfocusframe.cpp util/qquickfocusframe.h
QML_FILES
${qml_files}
DEFINES
@@ -86,6 +94,11 @@ qt_internal_extend_target(qtquickcontrols2nativestyleplugin CONDITION QT_FEATURE
items/qquickstyleitemtreeindicator.cpp items/qquickstyleitemtreeindicator.h
)
+qt_internal_extend_target(qtquickcontrols2nativestyleplugin CONDITION QT_FEATURE_qml_delegate_model
+ SOURCES
+ items/qquickstyleitemcombobox.cpp items/qquickstyleitemcombobox.h
+)
+
qt_internal_extend_target(qtquickcontrols2nativestyleplugin CONDITION MACOS
SOURCES
items/qquickstyleitemscrollviewcorner.cpp items/qquickstyleitemscrollviewcorner.h
@@ -105,6 +118,7 @@ qt_internal_extend_target(qtquickcontrols2nativestyleplugin CONDITION WIN32
qstyle/windows/qquickwindowsxpstyle.cpp
qstyle/windows/qquickwindowsxpstyle_p.h
qstyle/windows/qquickwindowsxpstyle_p_p.h
+ util/qquickwindowsfocusframe.cpp util/qquickwindowsfocusframe.h
INCLUDE_DIRECTORIES
qstyle/windows
LIBRARIES
diff --git a/src/quicknativestyle/controls/DefaultComboBox.qml b/src/quicknativestyle/controls/DefaultComboBox.qml
index a9a820a2d1..0876c522b3 100644
--- a/src/quicknativestyle/controls/DefaultComboBox.qml
+++ b/src/quicknativestyle/controls/DefaultComboBox.qml
@@ -1,6 +1,8 @@
// 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.Window
import QtQuick.Controls
@@ -56,8 +58,11 @@ T.ComboBox {
}
delegate: ItemDelegate {
+ required property var model
+ required property int index
+
width: ListView.view.width
- text: control.textRole ? (Array.isArray(control.model) ? modelData[control.textRole] : model[control.textRole]) : modelData
+ text: model[control.textRole]
palette.text: control.palette.text
palette.highlightedText: control.palette.highlightedText
font.weight: control.currentIndex === index ? Font.DemiBold : Font.Normal
diff --git a/src/quicknativestyle/controls/DefaultItemDelegate.qml b/src/quicknativestyle/controls/DefaultItemDelegate.qml
new file mode 100644
index 0000000000..55c54dbca5
--- /dev/null
+++ b/src/quicknativestyle/controls/DefaultItemDelegate.qml
@@ -0,0 +1,32 @@
+// Copyright (C) 2023 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.NativeStyle as NativeStyle
+
+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: NativeStyle.DefaultItemDelegateIconLabel {}
+
+ background: Rectangle {
+ implicitWidth: 100
+ implicitHeight: 20
+ color: Qt.darker(control.highlighted
+ ? control.palette.highlight : control.palette.button, control.down ? 1.05 : 1)
+ }
+}
diff --git a/src/quicknativestyle/controls/DefaultItemDelegateIconLabel.qml b/src/quicknativestyle/controls/DefaultItemDelegateIconLabel.qml
new file mode 100644
index 0000000000..7ac31e9f3e
--- /dev/null
+++ b/src/quicknativestyle/controls/DefaultItemDelegateIconLabel.qml
@@ -0,0 +1,21 @@
+// Copyright (C) 2023 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.Controls.impl
+import QtQuick.Templates as T
+
+IconLabel {
+ text: control.text
+ font: control.font
+ icon: control.icon
+ color: control.palette.windowText
+ spacing: control.spacing
+ mirrored: control.mirrored
+ display: control.display
+ alignment: control.display === IconLabel.IconOnly || control.display === IconLabel.TextUnderIcon
+ ? Qt.AlignCenter : Qt.AlignLeft
+ leftPadding: control.indicator && control.mirrored ? control.indicator.width + control.spacing : 0
+ rightPadding: control.indicator && !control.mirrored ? control.indicator.width + control.spacing : 0
+
+ readonly property T.ItemDelegate control: parent as T.ItemDelegate
+}
diff --git a/src/quicknativestyle/controls/DefaultProgressBar.qml b/src/quicknativestyle/controls/DefaultProgressBar.qml
index 77dd4741b1..0b318a5635 100644
--- a/src/quicknativestyle/controls/DefaultProgressBar.qml
+++ b/src/quicknativestyle/controls/DefaultProgressBar.qml
@@ -14,10 +14,9 @@ T.ProgressBar {
implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
implicitContentWidth + leftPadding + rightPadding,
- control.horizontal ? 90 : 0 /* minimum */ )
+ 90)
implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
- implicitContentHeight + topPadding + bottomPadding,
- control.vertical ? 90 : 0 /* minimum */ )
+ implicitContentHeight + topPadding + bottomPadding)
background: NativeStyle.ProgressBar {
control: control
diff --git a/src/quicknativestyle/controls/DefaultRadioDelegate.qml b/src/quicknativestyle/controls/DefaultRadioDelegate.qml
new file mode 100644
index 0000000000..82bc0d26bf
--- /dev/null
+++ b/src/quicknativestyle/controls/DefaultRadioDelegate.qml
@@ -0,0 +1,54 @@
+// Copyright (C) 2023 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.NativeStyle as NativeStyle
+
+T.RadioDelegate {
+ id: control
+
+ readonly property bool __nativeIndicator: indicator instanceof NativeStyle.StyleItem
+ readonly property bool __notCustomizable: true
+ readonly property Item __focusFrameTarget: indicator
+ readonly property Item __focusFrameStyleItem: indicator
+
+ implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
+ implicitContentWidth + leftPadding + rightPadding)
+ implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
+ implicitContentHeight + topPadding + bottomPadding,
+ implicitIndicatorHeight + topPadding + bottomPadding)
+
+ spacing: 6
+ padding: 6
+
+ icon.width: 16
+ icon.height: 16
+
+ contentItem: NativeStyle.DefaultItemDelegateIconLabel {
+ readonly property bool __ignoreNotCustomizable: true
+ }
+
+ indicator: NativeStyle.RadioDelegate {
+ x: control.text
+ ? (control.mirrored ? control.leftPadding : control.width - width - control.rightPadding)
+ : control.leftPadding + (control.availableWidth - width) / 2
+ y: control.topPadding + Math.round((control.availableHeight - height) / 2)
+ contentWidth: control.implicitContentWidth
+ contentHeight: control.implicitContentHeight
+ useNinePatchImage: false
+ control: control
+
+ readonly property bool __ignoreNotCustomizable: true
+ }
+
+ background: Rectangle {
+ implicitWidth: 100
+ implicitHeight: 20
+ color: Qt.darker(control.highlighted
+ ? control.palette.highlight : control.palette.button, control.down ? 1.05 : 1)
+
+ readonly property bool __ignoreNotCustomizable: true
+ }
+}
diff --git a/src/quicknativestyle/controls/DefaultScrollBar.qml b/src/quicknativestyle/controls/DefaultScrollBar.qml
index 7394dd1e74..1fad8e9a41 100644
--- a/src/quicknativestyle/controls/DefaultScrollBar.qml
+++ b/src/quicknativestyle/controls/DefaultScrollBar.qml
@@ -17,7 +17,7 @@ T.ScrollBar {
implicitContentHeight + topPadding + bottomPadding)
visible: policy === T.ScrollBar.AlwaysOn || (policy === T.ScrollBar.AsNeeded && size < 1.0)
- minimumSize: !__nativeContentItem ? 10 : orientation === Qt.Vertical ?
+ minimumSize: !__nativeContentItem ? 0.1 : orientation === Qt.Vertical ?
contentItem.minimumSize.height / height : contentItem.minimumSize.width / width
background: NativeStyle.ScrollBar {
diff --git a/src/quicknativestyle/controls/DefaultTextArea.qml b/src/quicknativestyle/controls/DefaultTextArea.qml
index 4ed9427bab..faab250fae 100644
--- a/src/quicknativestyle/controls/DefaultTextArea.qml
+++ b/src/quicknativestyle/controls/DefaultTextArea.qml
@@ -34,8 +34,8 @@ T.TextArea {
id: placeholder
x: control.leftPadding
y: control.topPadding
- width: control.availableWidth
- height: control.availableHeight
+ width: control.width - (control.leftPadding + control.rightPadding)
+ height: control.height - (control.topPadding + control.bottomPadding)
text: control.placeholderText
font: control.font
color: control.placeholderTextColor
diff --git a/src/quicknativestyle/controls/DefaultTreeViewDelegate.qml b/src/quicknativestyle/controls/DefaultTreeViewDelegate.qml
index a15b4d36f1..89130947bb 100644
--- a/src/quicknativestyle/controls/DefaultTreeViewDelegate.qml
+++ b/src/quicknativestyle/controls/DefaultTreeViewDelegate.qml
@@ -69,6 +69,7 @@ T.TreeViewDelegate {
// 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
@@ -76,7 +77,7 @@ T.TreeViewDelegate {
readonly property int __role: {
let model = control.treeView.model
- let index = control.treeView.modelIndex(column, row)
+ let index = control.treeView.index(row, column)
let editText = model.data(index, Qt.EditRole)
return editText !== undefined ? Qt.EditRole : Qt.DisplayRole
}
@@ -86,17 +87,18 @@ T.TreeViewDelegate {
x: control.contentItem.x
y: (parent.height - height) / 2
width: control.contentItem.width
- text: control.treeView.model.data(control.treeView.modelIndex(column, row), __role)
+ text: control.treeView.model.data(control.treeView.index(row, column), __role)
focus: true
}
TableView.onCommit: {
- let index = TableView.view.modelIndex(column, row)
+ 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/quicknativestyle/items/qquickstyleitem.h b/src/quicknativestyle/items/qquickstyleitem.h
index 1ad8932d23..3d04371b7e 100644
--- a/src/quicknativestyle/items/qquickstyleitem.h
+++ b/src/quicknativestyle/items/qquickstyleitem.h
@@ -14,6 +14,8 @@
#include "qquickstyle.h"
#include "qquickstyleoption.h"
+#include <QtCore/qpointer.h>
+
// Work-around for now, to avoid creator getting confused
// about missing macros. Should eventually be defined
// in qt declarative somewhere I assume.
@@ -274,6 +276,4 @@ Q_DECLARE_OPERATORS_FOR_FLAGS(QQuickStyleItem::DebugFlags)
QT_END_NAMESPACE
-QML_DECLARE_TYPE(QQuickStyleItem)
-
#endif // QQUICKSTYLEITEM_H
diff --git a/src/quicknativestyle/items/qquickstyleitembutton.h b/src/quicknativestyle/items/qquickstyleitembutton.h
index 668013ac6f..82dff23048 100644
--- a/src/quicknativestyle/items/qquickstyleitembutton.h
+++ b/src/quicknativestyle/items/qquickstyleitembutton.h
@@ -23,7 +23,7 @@ protected:
StyleItemGeometry calculateGeometry() override;
private:
- void initStyleOption(QStyleOptionButton &styleOption) const;
+ virtual void initStyleOption(QStyleOptionButton &styleOption) const;
};
QT_END_NAMESPACE
diff --git a/src/quicknativestyle/items/qquickstyleitemcheckbox.h b/src/quicknativestyle/items/qquickstyleitemcheckbox.h
index 92cda579ef..f50c621d12 100644
--- a/src/quicknativestyle/items/qquickstyleitemcheckbox.h
+++ b/src/quicknativestyle/items/qquickstyleitemcheckbox.h
@@ -23,7 +23,7 @@ protected:
StyleItemGeometry calculateGeometry() override;
private:
- void initStyleOption(QStyleOptionButton &styleOption) const;
+ virtual void initStyleOption(QStyleOptionButton &styleOption) const;
};
QT_END_NAMESPACE
diff --git a/src/quicknativestyle/items/qquickstyleitemcheckdelegate.cpp b/src/quicknativestyle/items/qquickstyleitemcheckdelegate.cpp
new file mode 100644
index 0000000000..22576c50d2
--- /dev/null
+++ b/src/quicknativestyle/items/qquickstyleitemcheckdelegate.cpp
@@ -0,0 +1,32 @@
+// Copyright (C) 2023 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 "qquickstyleitemcheckdelegate.h"
+
+#include <QtQuickTemplates2/private/qquickcheckdelegate_p.h>
+
+QT_BEGIN_NAMESPACE
+
+void QQuickStyleItemCheckDelegate::connectToControl() const
+{
+ QQuickStyleItem::connectToControl();
+ auto checkDelegate = control<QQuickCheckDelegate>();
+ connect(checkDelegate, &QQuickCheckDelegate::downChanged, this, &QQuickStyleItem::markImageDirty);
+ connect(checkDelegate, &QQuickCheckDelegate::checkStateChanged, this, &QQuickStyleItem::markImageDirty);
+}
+
+void QQuickStyleItemCheckDelegate::initStyleOption(QStyleOptionButton &styleOption) const
+{
+ initStyleOptionBase(styleOption);
+ auto checkDelegate = control<QQuickCheckDelegate>();
+
+ styleOption.state |= checkDelegate->isDown() ? QStyle::State_Sunken : QStyle::State_Raised;
+ if (checkDelegate->isTristate() && checkDelegate->checkState() == Qt::PartiallyChecked)
+ styleOption.state |= QStyle::State_NoChange;
+ else
+ styleOption.state |= checkDelegate->isChecked() ? QStyle::State_On : QStyle::State_Off;
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qquickstyleitemcheckdelegate.cpp"
diff --git a/src/quicknativestyle/items/qquickstyleitemcheckdelegate.h b/src/quicknativestyle/items/qquickstyleitemcheckdelegate.h
new file mode 100644
index 0000000000..27ff42de25
--- /dev/null
+++ b/src/quicknativestyle/items/qquickstyleitemcheckdelegate.h
@@ -0,0 +1,25 @@
+// Copyright (C) 2023 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 QQUICKSTYLEITEMCHECKDELEGATE_H
+#define QQUICKSTYLEITEMCHECKDELEGATE_H
+
+#include "qquickstyleitemcheckbox.h"
+
+QT_BEGIN_NAMESPACE
+
+class QQuickStyleItemCheckDelegate : public QQuickStyleItemCheckBox
+{
+ Q_OBJECT
+ QML_NAMED_ELEMENT(CheckDelegate)
+
+protected:
+ void connectToControl() const override;
+
+private:
+ void initStyleOption(QStyleOptionButton &styleOption) const override;
+};
+
+QT_END_NAMESPACE
+
+#endif // QQUICKSTYLEITEMCHECKDELEGATE_H
diff --git a/src/quicknativestyle/items/qquickstyleitemdelaybutton.cpp b/src/quicknativestyle/items/qquickstyleitemdelaybutton.cpp
new file mode 100644
index 0000000000..19309d11b6
--- /dev/null
+++ b/src/quicknativestyle/items/qquickstyleitemdelaybutton.cpp
@@ -0,0 +1,28 @@
+// Copyright (C) 2023 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 "qquickstyleitemdelaybutton.h"
+
+#include <QtQuickTemplates2/private/qquickdelaybutton_p.h>
+
+QT_BEGIN_NAMESPACE
+
+void QQuickStyleItemDelayButton::connectToControl() const
+{
+ QQuickStyleItem::connectToControl();
+ auto button = control<QQuickDelayButton>();
+ connect(button, &QQuickButton::downChanged, this, &QQuickStyleItem::markImageDirty);
+ connect(button, &QQuickButton::checkedChanged, this, &QQuickStyleItem::markImageDirty);
+}
+
+void QQuickStyleItemDelayButton::initStyleOption(QStyleOptionButton &styleOption) const
+{
+ initStyleOptionBase(styleOption);
+ auto button = control<QQuickDelayButton>();
+
+ styleOption.state |= button->isDown() ? QStyle::State_Sunken : QStyle::State_Raised;
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qquickstyleitemdelaybutton.cpp"
diff --git a/src/quicknativestyle/items/qquickstyleitemdelaybutton.h b/src/quicknativestyle/items/qquickstyleitemdelaybutton.h
new file mode 100644
index 0000000000..e2a0bf2174
--- /dev/null
+++ b/src/quicknativestyle/items/qquickstyleitemdelaybutton.h
@@ -0,0 +1,25 @@
+// Copyright (C) 2023 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 QQUICKSTYLEITEMDELAYBUTTON_H
+#define QQUICKSTYLEITEMDELAYBUTTON_H
+
+#include "qquickstyleitembutton.h"
+
+QT_BEGIN_NAMESPACE
+
+class QQuickStyleItemDelayButton : public QQuickStyleItemButton
+{
+ Q_OBJECT
+ QML_NAMED_ELEMENT(DelayButton)
+
+protected:
+ void connectToControl() const override;
+
+private:
+ void initStyleOption(QStyleOptionButton &styleOption) const override;
+};
+
+QT_END_NAMESPACE
+
+#endif // QQUICKSTYLEITEMDELAYBUTTON_H
diff --git a/src/quicknativestyle/items/qquickstyleitemdial.cpp b/src/quicknativestyle/items/qquickstyleitemdial.cpp
index e2407e9e81..fe36f866e4 100644
--- a/src/quicknativestyle/items/qquickstyleitemdial.cpp
+++ b/src/quicknativestyle/items/qquickstyleitemdial.cpp
@@ -19,6 +19,8 @@ void QQuickStyleItemDial::connectToControl() const
connect(dial, &QQuickDial::positionChanged, this, &QQuickStyleItem::markImageDirty);
connect(dial, &QQuickDial::valueChanged, this, &QQuickStyleItem::markImageDirty);
connect(dial, &QQuickDial::stepSizeChanged, this, &QQuickStyleItem::markImageDirty);
+ connect(dial, &QQuickDial::startAngleChanged, this, &QQuickStyleItem::markImageDirty);
+ connect(dial, &QQuickDial::endAngleChanged, this, &QQuickStyleItem::markImageDirty);
connect(dial, &QQuickDial::pressedChanged, this, &QQuickStyleItem::markImageDirty);
}
@@ -54,6 +56,8 @@ void QQuickStyleItemDial::initStyleOption(QStyleOptionSlider &styleOption) const
styleOption.tickInterval = dial->stepSize();
styleOption.dialWrapping = dial->wrap();
styleOption.upsideDown = true;
+ styleOption.startAngle = dial->startAngle();
+ styleOption.endAngle = dial->endAngle();
if (dial->isPressed())
styleOption.state |= QStyle::State_Sunken;
diff --git a/src/quicknativestyle/items/qquickstyleitemradiobutton.h b/src/quicknativestyle/items/qquickstyleitemradiobutton.h
index 4674098116..209d2cc65f 100644
--- a/src/quicknativestyle/items/qquickstyleitemradiobutton.h
+++ b/src/quicknativestyle/items/qquickstyleitemradiobutton.h
@@ -23,7 +23,7 @@ protected:
StyleItemGeometry calculateGeometry() override;
private:
- void initStyleOption(QStyleOptionButton &styleOption) const;
+ virtual void initStyleOption(QStyleOptionButton &styleOption) const;
};
QT_END_NAMESPACE
diff --git a/src/quicknativestyle/items/qquickstyleitemradiodelegate.cpp b/src/quicknativestyle/items/qquickstyleitemradiodelegate.cpp
new file mode 100644
index 0000000000..a4325cfe15
--- /dev/null
+++ b/src/quicknativestyle/items/qquickstyleitemradiodelegate.cpp
@@ -0,0 +1,29 @@
+// Copyright (C) 2023 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 "qquickstyleitemradiodelegate.h"
+
+#include <QtQuickTemplates2/private/qquickradiodelegate_p.h>
+
+QT_BEGIN_NAMESPACE
+
+void QQuickStyleItemRadioDelegate::connectToControl() const
+{
+ QQuickStyleItem::connectToControl();
+ auto radioDelegate = control<QQuickRadioDelegate>();
+ connect(radioDelegate, &QQuickRadioDelegate::downChanged, this, &QQuickStyleItem::markImageDirty);
+ connect(radioDelegate, &QQuickRadioDelegate::checkedChanged, this, &QQuickStyleItem::markImageDirty);
+}
+
+void QQuickStyleItemRadioDelegate::initStyleOption(QStyleOptionButton &styleOption) const
+{
+ initStyleOptionBase(styleOption);
+ auto radioDelegate = control<QQuickRadioDelegate>();
+
+ styleOption.state |= radioDelegate->isDown() ? QStyle::State_Sunken : QStyle::State_Raised;
+ styleOption.state |= radioDelegate->isChecked() ? QStyle::State_On : QStyle::State_Off;
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qquickstyleitemradiodelegate.cpp"
diff --git a/src/quicknativestyle/items/qquickstyleitemradiodelegate.h b/src/quicknativestyle/items/qquickstyleitemradiodelegate.h
new file mode 100644
index 0000000000..3661ce792e
--- /dev/null
+++ b/src/quicknativestyle/items/qquickstyleitemradiodelegate.h
@@ -0,0 +1,25 @@
+// Copyright (C) 2023 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 QQUICKSTYLEITEMRADIODELEGATE_H
+#define QQUICKSTYLEITEMRADIODELEGATE_H
+
+#include "qquickstyleitemradiobutton.h"
+
+QT_BEGIN_NAMESPACE
+
+class QQuickStyleItemRadioDelegate : public QQuickStyleItemRadioButton
+{
+ Q_OBJECT
+ QML_NAMED_ELEMENT(RadioDelegate)
+
+protected:
+ void connectToControl() const override;
+
+private:
+ void initStyleOption(QStyleOptionButton &styleOption) const override;
+};
+
+QT_END_NAMESPACE
+
+#endif // QQUICKSTYLEITEMRADIODELEGATE_H
diff --git a/src/quicknativestyle/items/qquickstyleitemscrollbar.cpp b/src/quicknativestyle/items/qquickstyleitemscrollbar.cpp
index c328ab6d1f..097341eb56 100644
--- a/src/quicknativestyle/items/qquickstyleitemscrollbar.cpp
+++ b/src/quicknativestyle/items/qquickstyleitemscrollbar.cpp
@@ -5,6 +5,14 @@
QT_BEGIN_NAMESPACE
+QQuickStyleItemScrollBar::QQuickStyleItemScrollBar(QQuickItem *parent)
+ : QQuickStyleItem(parent)
+{
+#ifdef QT_DEBUG
+ setObjectName("styleItemScrollBar");
+#endif
+}
+
QFont QQuickStyleItemScrollBar::styleFont(QQuickItem *control) const
{
return style()->font(QStyle::CE_ProgressBarLabel, controlSize(control));
diff --git a/src/quicknativestyle/items/qquickstyleitemscrollbar.h b/src/quicknativestyle/items/qquickstyleitemscrollbar.h
index 6ef232420f..57a9c19059 100644
--- a/src/quicknativestyle/items/qquickstyleitemscrollbar.h
+++ b/src/quicknativestyle/items/qquickstyleitemscrollbar.h
@@ -26,6 +26,8 @@ public:
};
Q_ENUM(SubControl)
+ explicit QQuickStyleItemScrollBar(QQuickItem *parent = nullptr);
+
QFont styleFont(QQuickItem *control) const override;
protected:
diff --git a/src/quicknativestyle/qstyle/mac/qquickmacstyle_mac.mm b/src/quicknativestyle/qstyle/mac/qquickmacstyle_mac.mm
index eb777ea9f2..b92c380657 100644
--- a/src/quicknativestyle/qstyle/mac/qquickmacstyle_mac.mm
+++ b/src/quicknativestyle/qstyle/mac/qquickmacstyle_mac.mm
@@ -166,45 +166,6 @@ const int QMacStylePrivate::PushButtonContentPadding = 6;
QVector<QPointer<QObject> > QMacStylePrivate::scrollBars;
-// Title bar gradient colors for Lion were determined by inspecting PSDs exported
-// using CoreUI's CoreThemeDocument; there is no public API to retrieve them
-
-static QLinearGradient titlebarGradientActive()
-{
- static QLinearGradient darkGradient = [](){
- QLinearGradient gradient;
- // FIXME: colors are chosen somewhat arbitrarily and could be fine-tuned,
- // or ideally determined by calling a native API.
- gradient.setColorAt(0, QColor(47, 47, 47));
- return gradient;
- }();
- static QLinearGradient lightGradient = [](){
- QLinearGradient gradient;
- gradient.setColorAt(0, QColor(235, 235, 235));
- gradient.setColorAt(0.5, QColor(210, 210, 210));
- gradient.setColorAt(0.75, QColor(195, 195, 195));
- gradient.setColorAt(1, QColor(180, 180, 180));
- return gradient;
- }();
- return qt_mac_applicationIsInDarkMode() ? darkGradient : lightGradient;
-}
-
-static QLinearGradient titlebarGradientInactive()
-{
- static QLinearGradient darkGradient = [](){
- QLinearGradient gradient;
- gradient.setColorAt(1, QColor(42, 42, 42));
- return gradient;
- }();
- static QLinearGradient lightGradient = [](){
- QLinearGradient gradient;
- gradient.setColorAt(0, QColor(250, 250, 250));
- gradient.setColorAt(1, QColor(225, 225, 225));
- return gradient;
- }();
- return qt_mac_applicationIsInDarkMode() ? darkGradient : lightGradient;
-}
-
static const QColor titlebarSeparatorLineActive(111, 111, 111);
static const QColor titlebarSeparatorLineInactive(131, 131, 131);
static const QColor darkModeSeparatorLine(88, 88, 88);
@@ -2041,20 +2002,21 @@ int QMacStyle::pixelMetric(PixelMetric metric, const QStyleOption *opt) const
ret = 1;
break;
case PM_ScrollView_ScrollBarOverlap:
- ret = [NSScroller preferredScrollerStyle] == NSScrollerStyleOverlay ?
- pixelMetric(PM_ScrollBarExtent, opt) : 0;
+ ret = styleHint(SH_ScrollBar_Transient, opt, nullptr)
+ ? pixelMetric(PM_ScrollBarExtent, opt)
+ : 0;
break;
case PM_PushButtonFocusFrameRadius:
- ret = LargeSmallMini(opt, 8, 7, 5);
+ ret = LargeSmallMini(opt, 5, 4, 2);
break;
case PM_CheckBoxFocusFrameRadius:
- ret = LargeSmallMini(opt, 6, 5, 4);
+ ret = LargeSmallMini(opt, 3, 2, 1);
break;
case PM_ComboBoxFocusFrameRadius:
- ret = LargeSmallMini(opt, 8, 7, 4);
+ ret = LargeSmallMini(opt, 5, 4, 1);
break;
case PM_RadioButtonFocusFrameRadius:
- ret = 10;
+ ret = 7;
break;
case PM_SliderFocusFrameRadius:
// QTBUG-93423: We currently need to skip drawing a focus ring around the handle, since
@@ -2067,7 +2029,7 @@ int QMacStyle::pixelMetric(PixelMetric metric, const QStyleOption *opt) const
case PM_SpinBoxFocusFrameRadius:
case PM_TextAreaFocusFrameRadius:
case PM_TextFieldFocusFrameRadius:
- ret = 3;
+ ret = 0;
break;
default:
ret = QCommonStyle::pixelMetric(metric, opt);
@@ -2277,7 +2239,7 @@ int QMacStyle::styleHint(StyleHint sh, const QStyleOption *opt, QStyleHintReturn
++srow;
}
}
- QBitmap qmask = QBitmap::fromImage(img_mask);
+ QBitmap qmask = QBitmap::fromImage(std::move(img_mask));
mask->region = QRegion(qmask);
}
break; }
@@ -2878,20 +2840,10 @@ void QMacStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPai
// } break;
//#endif // QT_CONFIG(tabbar)
case PE_PanelStatusBar: {
- // Fill the status bar with the titlebar gradient.
- QLinearGradient linearGrad;
- const bool isMainWindow = qt_macWindowMainWindow(opt->window);
- if (isMainWindow)
- linearGrad = titlebarGradientActive();
- else
- linearGrad = titlebarGradientInactive();
-
- linearGrad.setStart(0, opt->rect.top());
- linearGrad.setFinalStop(0, opt->rect.bottom());
- p->fillRect(opt->rect, linearGrad);
+ p->fillRect(opt->rect, opt->palette.window());
// Draw the black separator line at the top of the status bar.
- if (isMainWindow)
+ if (qt_macWindowMainWindow(opt->window))
p->setPen(titlebarSeparatorLineActive);
else
p->setPen(titlebarSeparatorLineInactive);
@@ -3496,12 +3448,7 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
}
// fill title bar background
- QLinearGradient linearGrad;
- linearGrad.setStart(QPointF(0, 0));
- linearGrad.setFinalStop(QPointF(0, 2 * effectiveRect.height()));
- linearGrad.setColorAt(0, opt->palette.button().color());
- linearGrad.setColorAt(1, opt->palette.dark().color());
- p->fillRect(effectiveRect, linearGrad);
+ p->fillRect(effectiveRect, opt->palette.window());
// draw horizontal line at bottom
p->setPen(opt->palette.dark().color());
@@ -4859,16 +4806,7 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex
const auto frameAdjust = 1.0 / p->device()->devicePixelRatioF();
const auto innerFrameRect = outerFrameRect.adjusted(frameAdjust, frameAdjust, -frameAdjust, 0);
QPainterPath innerFramePath = d->windowPanelPath(innerFrameRect);
- if (isActive) {
- QLinearGradient g;
- g.setStart(QPointF(0, 0));
- g.setFinalStop(QPointF(0, 2 * opt->rect.height()));
- g.setColorAt(0, opt->palette.button().color());
- g.setColorAt(1, opt->palette.dark().color());
- p->fillPath(innerFramePath, g);
- } else {
- p->fillPath(innerFramePath, opt->palette.button());
- }
+ p->fillPath(innerFramePath, opt->palette.button());
if (titlebar->subControls & (SC_TitleBarCloseButton
| SC_TitleBarMaxButton
diff --git a/src/quicknativestyle/qstyle/qquickcommonstyle.cpp b/src/quicknativestyle/qstyle/qquickcommonstyle.cpp
index d8cac57486..02bd1a694c 100644
--- a/src/quicknativestyle/qstyle/qquickcommonstyle.cpp
+++ b/src/quicknativestyle/qstyle/qquickcommonstyle.cpp
@@ -24,7 +24,9 @@
#include <qtextformat.h>
#include <qfileinfo.h>
#include <qdir.h>
+#if QT_CONFIG(settings)
#include <qsettings.h>
+#endif
#include <qvariant.h>
#include <qpixmapcache.h>
#include <qmatrix4x4.h>
@@ -502,6 +504,7 @@ void QCommonStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, Q
proxy()->drawPrimitive(PE_FrameLineEdit, panel, p);
}
break;
+#if QT_CONFIG(quick_itemview)
case PE_IndicatorColumnViewArrow: {
if (const QStyleOptionViewItem *viewOpt = qstyleoption_cast<const QStyleOptionViewItem *>(opt)) {
bool reverse = (viewOpt->direction == Qt::RightToLeft);
@@ -595,6 +598,7 @@ void QCommonStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, Q
}
}
break;
+#endif // QT_CONFIG(quick_itemview)
case PE_PanelScrollAreaCorner: {
const QBrush brush(opt->palette.brush(QPalette::Window));
p->fillRect(opt->rect, brush);
@@ -665,7 +669,7 @@ void QCommonStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, Q
imagePainter.drawPolygon(a);
imagePainter.end();
- pixmap = QPixmap::fromImage(image);
+ pixmap = QPixmap::fromImage(std::move(image));
pixmap.setDevicePixelRatio(pixelRatio);
QPixmapCache::insert(pixmapName, pixmap);
}
@@ -811,6 +815,7 @@ QString QCommonStylePrivate::calculateElidedText(const QString &text, const QTex
return ret;
}
+#if QT_CONFIG(quick_itemview)
QSize QCommonStylePrivate::viewItemSize(const QStyleOptionViewItem *option, int role) const
{
switch (role) {
@@ -1028,6 +1033,7 @@ void QCommonStylePrivate::viewItemLayout(const QStyleOptionViewItem *opt, QRect
*textRect = display;
}
}
+#endif // QT_CONFIG(quick_itemview)
QString QCommonStylePrivate::toolButtonElideText(const QStyleOptionToolButton *option,
const QRect &textRect, int flags) const
@@ -2034,6 +2040,7 @@ void QCommonStyle::drawControl(ControlElement element, const QStyleOption *opt,
p->drawLine(line2starting, top, line2starting, bottom);
}
break;
+#if QT_CONFIG(quick_itemview)
case CE_ItemViewItem:
if (const QStyleOptionViewItem *vopt = qstyleoption_cast<const QStyleOptionViewItem *>(opt)) {
p->save();
@@ -2112,6 +2119,7 @@ void QCommonStyle::drawControl(ControlElement element, const QStyleOption *opt,
p->restore();
}
break;
+#endif // QT_CONFIG(quick_itemview)
case CE_ShapedFrame:
if (const QStyleOptionFrame *f = qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
int frameShape = f->frameShape;
@@ -2828,6 +2836,7 @@ QRect QCommonStyle::subElementRect(SubElement sr, const QStyleOption *opt) const
}
break;
}
+#if QT_CONFIG(quick_itemview)
case SE_ItemViewItemCheckIndicator:
if (!qstyleoption_cast<const QStyleOptionViewItem *>(opt)) {
r = subElementRect(SE_CheckBoxIndicator, opt);
@@ -2854,6 +2863,7 @@ QRect QCommonStyle::subElementRect(SubElement sr, const QStyleOption *opt) const
r = d->displayRect;
}
break;
+#endif // QT_CONFIG(quick_itemview)
case SE_ToolBarHandle:
if (const QStyleOptionToolBar *tbopt = qstyleoption_cast<const QStyleOptionToolBar *>(opt)) {
if (tbopt->features & QStyleOptionToolBar::Movable) {
@@ -2898,14 +2908,13 @@ static StaticPolygonF<3> calcArrow(const QStyleOptionSlider *dial, qreal &a)
int r = qMin(width, height) / 2;
int currentSliderPosition = dial->upsideDown ? dial->sliderPosition : (dial->maximum - dial->sliderPosition);
+ qreal startAngle = (90. - dial->startAngle) * Q_PI / 180.;
+ qreal spanAngle = (dial->endAngle - dial->startAngle) * Q_PI / 180.;
if (dial->maximum == dial->minimum)
a = Q_PI / 2;
- else if (dial->dialWrapping)
- a = Q_PI * 3 / 2 - (currentSliderPosition - dial->minimum) * 2 * Q_PI
- / (dial->maximum - dial->minimum);
else
- a = (Q_PI * 8 - (currentSliderPosition - dial->minimum) * 10 * Q_PI
- / (dial->maximum - dial->minimum)) / 6;
+ a = (startAngle - (currentSliderPosition - dial->minimum) * spanAngle
+ / (dial->maximum - dial->minimum));
int xc = width / 2;
int yc = height / 2;
@@ -3865,6 +3874,7 @@ QRect QCommonStyle::subControlRect(ComplexControl cc, const QStyleOptionComplex
break;
case SC_SpinBoxFrame:
ret = spinbox->rect;
+ break;
default:
break;
}
@@ -4433,7 +4443,7 @@ int QCommonStyle::pixelMetric(PixelMetric m, const QStyleOption *opt) const
ret = int(QStyleHelper::dpiScaled(13, opt));
break;
case PM_MessageBoxIconSize:
-#ifdef Q_OS_MAC
+#ifdef Q_OS_APPLE
if (QGuiApplication::desktopSettingsAware()) {
ret = 64; // No DPI scaling, it's handled elsewhere.
} else
@@ -4474,7 +4484,6 @@ int QCommonStyle::pixelMetric(PixelMetric m, const QStyleOption *opt) const
QSize QCommonStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt, const QSize &csz) const
{
- Q_D(const QCommonStyle);
QSize sz(!csz.isEmpty() ? csz : QSize(0,0));
switch (ct) {
@@ -4607,8 +4616,10 @@ QSize QCommonStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt, c
sz = QSize(1 + 3 * (buttonSize + 1), buttonSize);
}
break;
+#if QT_CONFIG(quick_itemview)
case CT_ItemViewItem:
if (const QStyleOptionViewItem *vopt = qstyleoption_cast<const QStyleOptionViewItem *>(opt)) {
+ Q_D(const QCommonStyle);
QRect decorationRect, displayRect, checkRect;
d->viewItemLayout(vopt, &checkRect, &decorationRect, &displayRect, true);
sz = (decorationRect|displayRect|checkRect).size();
@@ -4616,6 +4627,7 @@ QSize QCommonStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt, c
sz.rheight() += 2; // Prevent icons from overlapping.
}
break;
+#endif // QT_CONFIG(quick_itemview)
case CT_SpinBox:
if (const QStyleOptionSpinBox *vopt = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) {
// Add button + frame widths
@@ -4973,9 +4985,11 @@ int QCommonStyle::styleHint(StyleHint sh, const QStyleOption *opt, QStyleHintRet
case SH_Splitter_OpaqueResize:
ret = true;
break;
+#if QT_CONFIG(quick_itemview)
case SH_ItemView_ScrollMode:
ret = QStyleOptionViewItem::ScrollPerItem;
break;
+#endif // QT_CONFIG(quick_itemview)
case SH_TitleBar_ShowToolTipsOnButtons:
ret = true;
break;
@@ -5228,8 +5242,8 @@ QPixmap QCommonStyle::standardPixmap(StandardPixmap sp, const QStyleOption *opti
case SP_ToolBarHorizontalExtensionButton:
if (rtl) {
QImage im(tb_extension_arrow_h_xpm);
- im = im.convertToFormat(QImage::Format_ARGB32).mirrored(true, false);
- return QPixmap::fromImage(im);
+ im = std::move(im).convertToFormat(QImage::Format_ARGB32).mirrored(true, false);
+ return QPixmap::fromImage(std::move(im));
}
return cachedPixmapFromXPM(tb_extension_arrow_h_xpm);
case SP_ToolBarVerticalExtensionButton:
@@ -5648,7 +5662,7 @@ QIcon QCommonStyle::standardIcon(StandardPixmap standardIcon, const QStyleOption
if (!icon.isNull())
return icon;
-#if defined(Q_OS_MAC)
+#if defined(Q_OS_MACOS)
if (QGuiApplication::desktopSettingsAware()) {
switch (standardIcon) {
case SP_DirIcon: {
@@ -5716,7 +5730,7 @@ QIcon QCommonStyle::standardIcon(StandardPixmap standardIcon, const QStyleOption
break;
}
} // if (QGuiApplication::desktopSettingsAware())
-#endif // Q_OS_MAC
+#endif // Q_OS_MACOS
switch (standardIcon) {
#ifndef QT_NO_IMAGEFORMAT_PNG
@@ -6024,7 +6038,7 @@ QPixmap QCommonStyle::generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &p
}
}
- return QPixmap::fromImage(im);
+ return QPixmap::fromImage(std::move(im));
}
case QIcon::Selected: {
QImage img = pixmap.toImage().convertToFormat(QImage::Format_ARGB32_Premultiplied);
@@ -6034,7 +6048,7 @@ QPixmap QCommonStyle::generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &p
painter.setCompositionMode(QPainter::CompositionMode_SourceAtop);
painter.fillRect(0, 0, img.width(), img.height(), color);
painter.end();
- return QPixmap::fromImage(img); }
+ return QPixmap::fromImage(std::move(img)); }
case QIcon::Active:
return pixmap;
default:
diff --git a/src/quicknativestyle/qstyle/qquickcommonstyle_p.h b/src/quicknativestyle/qstyle/qquickcommonstyle_p.h
index 83ed85e51d..b597e478cf 100644
--- a/src/quicknativestyle/qstyle/qquickcommonstyle_p.h
+++ b/src/quicknativestyle/qstyle/qquickcommonstyle_p.h
@@ -30,15 +30,18 @@ class QCommonStylePrivate : public QStylePrivate
Q_DECLARE_PUBLIC(QCommonStyle)
public:
+#if QT_CONFIG(quick_itemview)
~QCommonStylePrivate()
{
delete cachedOption;
}
+#endif // QT_CONFIG(quick_itemview)
QString calculateElidedText(const QString &text, const QTextOption &textOption,
const QFont &font, const QRect &textRect, const Qt::Alignment valign,
Qt::TextElideMode textElideMode, int flags,
bool lastVisibleLineShouldBeElided, QPointF *paintStartPosition) const;
+#if QT_CONFIG(quick_itemview)
void viewItemDrawText(QPainter *p, const QStyleOptionViewItem *option, const QRect &rect) const;
void viewItemLayout(const QStyleOptionViewItem *opt, QRect *checkRect,
QRect *pixmapRect, QRect *textRect, bool sizehint) const;
@@ -62,6 +65,7 @@ public:
&& option.font == cachedOption->font
&& option.viewItemPosition == cachedOption->viewItemPosition;
}
+#endif // QT_CONFIG(quick_itemview)
QString toolButtonElideText(const QStyleOptionToolButton *toolbutton,
const QRect &textRect, int flags) const;
diff --git a/src/quicknativestyle/qstyle/qquickstylehelper.cpp b/src/quicknativestyle/qstyle/qquickstylehelper.cpp
index dab6b041d8..6b73a5fcf3 100644
--- a/src/quicknativestyle/qstyle/qquickstylehelper.cpp
+++ b/src/quicknativestyle/qstyle/qquickstylehelper.cpp
@@ -121,14 +121,13 @@ static QPointF calcRadialPos(const QStyleOptionSlider *dial, qreal offset)
const int r = qMin(width, height) / 2;
const int currentSliderPosition = dial->upsideDown ? dial->sliderPosition : (dial->maximum - dial->sliderPosition);
qreal a = 0;
+ qreal startAngle = (90. - dial->startAngle) * Q_PI / 180.;
+ qreal spanAngle = (dial->endAngle - dial->startAngle) * Q_PI / 180.;
if (dial->maximum == dial->minimum)
a = Q_PI / 2;
- else if (dial->dialWrapping)
- a = Q_PI * 3 / 2 - (currentSliderPosition - dial->minimum) * 2 * Q_PI
- / (dial->maximum - dial->minimum);
else
- a = (Q_PI * 8 - (currentSliderPosition - dial->minimum) * 10 * Q_PI
- / (dial->maximum - dial->minimum)) / 6;
+ a = (startAngle - (currentSliderPosition - dial->minimum) * spanAngle
+ / (dial->maximum - dial->minimum));
qreal xc = width / 2.0;
qreal yc = height / 2.0;
qreal len = r - QStyleHelper::calcBigLineSize(r) - 3;
diff --git a/src/quicknativestyle/qstyle/qquickstyleoption.cpp b/src/quicknativestyle/qstyle/qquickstyleoption.cpp
index c3f5df860a..83afa8e399 100644
--- a/src/quicknativestyle/qstyle/qquickstyleoption.cpp
+++ b/src/quicknativestyle/qstyle/qquickstyleoption.cpp
@@ -385,6 +385,7 @@ QStyleOptionTitleBar::QStyleOptionTitleBar(int versionIn)
{
}
+#if QT_CONFIG(quick_itemview)
/*!
Constructs a QStyleOptionViewItem, initializing the members
variables to their default values.
@@ -406,6 +407,7 @@ QStyleOptionViewItem::QStyleOptionViewItem(int versionIn)
checkState(Qt::Unchecked), viewItemPosition(QStyleOptionViewItem::Invalid)
{
}
+#endif // QT_CONFIG(quick_itemview)
/*!
Constructs a QStyleOptionTabWidgetFrame, initializing the members
diff --git a/src/quicknativestyle/qstyle/qquickstyleoption.h b/src/quicknativestyle/qstyle/qquickstyleoption.h
index e7770cc277..ed430baaca 100644
--- a/src/quicknativestyle/qstyle/qquickstyleoption.h
+++ b/src/quicknativestyle/qstyle/qquickstyleoption.h
@@ -9,11 +9,15 @@
#include <QtCore/qlocale.h>
#include <QtCore/qvariant.h>
#include <QtCore/qdebug.h>
-#include <QtCore/qabstractitemmodel.h>
#include <QtGui/qicon.h>
#include <QtGui/qfontmetrics.h>
+#include <QtQuick/private/qtquick-config_p.h>
+#if QT_CONFIG(quick_itemview)
+#include <QtCore/qabstractitemmodel.h>
+#endif
+
QT_BEGIN_NAMESPACE
class QQuickItem;
@@ -35,7 +39,6 @@ public:
SO_CustomBase = 0xf00,
SO_ComplexCustomBase = 0xf000000
};
- Q_ENUMS(OptionType)
enum StyleOptionType { Type = SO_Default };
enum StyleOptionVersion { Version = 1 };
@@ -376,6 +379,7 @@ protected:
Q_DECL_DEPRECATED typedef QStyleOptionDockWidget QStyleOptionDockWidgetV2;
+#if QT_CONFIG(quick_itemview)
class QStyleOptionViewItem : public QStyleOption
{
public:
@@ -429,6 +433,7 @@ Q_DECLARE_OPERATORS_FOR_FLAGS(QStyleOptionViewItem::ViewItemFeatures)
Q_DECL_DEPRECATED typedef QStyleOptionViewItem QStyleOptionViewItemV2;
Q_DECL_DEPRECATED typedef QStyleOptionViewItem QStyleOptionViewItemV3;
Q_DECL_DEPRECATED typedef QStyleOptionViewItem QStyleOptionViewItemV4;
+#endif // QT_CONFIG(quick_itemview)
class QStyleOptionToolBox : public QStyleOption
{
@@ -514,6 +519,8 @@ public:
int pageStep;
qreal notchTarget;
bool dialWrapping;
+ qreal startAngle;
+ qreal endAngle;
QStyleOptionSlider();
QStyleOptionSlider(const QStyleOptionSlider &other) : QStyleOptionComplex(Version, Type) { *this = other; }
diff --git a/src/quicknativestyle/qstyle/windows/qquickwindowsstyle.cpp b/src/quicknativestyle/qstyle/windows/qquickwindowsstyle.cpp
index 73b2692241..64528c8fb7 100644
--- a/src/quicknativestyle/qstyle/windows/qquickwindowsstyle.cpp
+++ b/src/quicknativestyle/qstyle/windows/qquickwindowsstyle.cpp
@@ -2292,7 +2292,7 @@ void QWindowsStyle::refreshPalette()
QPalette pal;
using QWindowsApplication = QNativeInterface::Private::QWindowsApplication;
if (auto nativeWindowsApp = dynamic_cast<QWindowsApplication *>(QGuiApplicationPrivate::platformIntegration()))
- nativeWindowsApp->lightSystemPalette(pal);
+ nativeWindowsApp->populateLightSystemPalette(pal);
QQuickTheme::instance()->setPalette(QQuickTheme::System, pal);
}
diff --git a/src/quicknativestyle/qstyle/windows/qquickwindowsxpstyle.cpp b/src/quicknativestyle/qstyle/windows/qquickwindowsxpstyle.cpp
index 4a729b339f..a6b8807ed0 100644
--- a/src/quicknativestyle/qstyle/windows/qquickwindowsxpstyle.cpp
+++ b/src/quicknativestyle/qstyle/windows/qquickwindowsxpstyle.cpp
@@ -760,7 +760,7 @@ bool QWindowsXPStylePrivate::drawBackgroundThruNativeBuffer(XPThemeData &themeDa
#ifdef DEBUG_XP_STYLE
char buf[25];
- ::sprintf(buf, "+ Pixmap(%3d, %3d) ]", w, h);
+ ::snprintf(buf, sizeof(buf), "+ Pixmap(%3d, %3d) ]", w, h);
printf("---[ CACHED %s--------> Name(%-10s) Part(%d) State(%d)\n",
haveCachedPixmap ? buf : "]-------------------",
qPrintable(themeData.name), themeData.partId, themeData.stateId);
@@ -3879,22 +3879,24 @@ void QWindowsXPStylePrivate::dumpNativeDIB(int w, int h)
static int pCount = 0;
DWORD *bufPix = (DWORD*)bufferPixels;
- char *bufferDump = new char[bufferH * bufferW * 16];
+ const unsigned int bufferSize = bufferH * bufferW * 16;
+ char *bufferDump = new char[bufferSize];
+ char *bufferEndAdress = bufferDump + bufferSize;
char *bufferPos = bufferDump;
memset(bufferDump, 0, sizeof(bufferDump));
- bufferPos += sprintf(bufferPos, "const int pixelBufferW%d = %d;\n", pCount, w);
- bufferPos += sprintf(bufferPos, "const int pixelBufferH%d = %d;\n", pCount, h);
- bufferPos += sprintf(bufferPos, "const unsigned DWORD pixelBuffer%d[] = {", pCount);
+ bufferPos += snprintf(bufferPos, bufferEndAdress - bufferPos, "const int pixelBufferW%d = %d;\n", pCount, w);
+ bufferPos += snprintf(bufferPos, bufferEndAdress - bufferPos, "const int pixelBufferH%d = %d;\n", pCount, h);
+ bufferPos += snprintf(bufferPos, bufferEndAdress - bufferPos, "const unsigned DWORD pixelBuffer%d[] = {", pCount);
for (int iy = 0; iy < h; ++iy) {
- bufferPos += sprintf(bufferPos, "\n ");
+ bufferPos += snprintf(bufferPos, bufferEndAdress - bufferPos, "\n ");
bufPix = (DWORD*)(bufferPixels + (iy * bufferW * 4));
for (int ix = 0; ix < w; ++ix) {
- bufferPos += sprintf(bufferPos, "0x%08x, ", *bufPix);
+ bufferPos += snprintf(bufferPos, bufferEndAdress - bufferPos, "0x%08x, ", *bufPix);
++bufPix;
}
}
- bufferPos += sprintf(bufferPos, "\n};\n\n");
+ bufferPos += snprintf(bufferPos, bufferEndAdress - bufferPos, "\n};\n\n");
printf(bufferDump);
delete[] bufferDump;
diff --git a/src/quicknativestyle/qtquickcontrols2nativestyleplugin.cpp b/src/quicknativestyle/qtquickcontrols2nativestyleplugin.cpp
index e0b0e77bf3..f1ff18c74f 100644
--- a/src/quicknativestyle/qtquickcontrols2nativestyleplugin.cpp
+++ b/src/quicknativestyle/qtquickcontrols2nativestyleplugin.cpp
@@ -13,10 +13,11 @@
#include "qquickcommonstyle.h"
#if defined(Q_OS_MACOS)
-#include "qquickmacstyle_mac_p.h"
#include "qquickmacfocusframe.h"
+#include "qquickmacstyle_mac_p.h"
#elif defined(Q_OS_WINDOWS)
-# include "qquickwindowsxpstyle_p.h"
+#include "qquickwindowsfocusframe.h"
+#include "qquickwindowsxpstyle_p.h"
#endif
QT_BEGIN_NAMESPACE
@@ -39,8 +40,8 @@ public:
void initializeTheme(QQuickTheme *theme) override;
QString name() const override;
-#if defined(Q_OS_MACOS)
- QScopedPointer<QQuickMacFocusFrame> m_focusFrame;
+#if defined(Q_OS_MACOS) || defined (Q_OS_WIN)
+ QScopedPointer<QQuickFocusFrame> m_focusFrame;
#endif
};
@@ -111,7 +112,7 @@ void QtQuickControls2NativeStylePlugin::initializeEngine(QQmlEngine *engine, con
style = new QMacStyle;
#elif defined(Q_OS_WINDOWS)
style = new QWindowsXPStyle;
- if (QGuiApplication::styleHints()->appearance() == Qt::Appearance::Dark)
+ if (QGuiApplication::styleHints()->colorScheme() == Qt::ColorScheme::Dark)
qobject_cast<QWindowsStyle *>(style)->refreshPalette();
#else
style = new QCommonStyle;
@@ -121,6 +122,8 @@ void QtQuickControls2NativeStylePlugin::initializeEngine(QQmlEngine *engine, con
#if defined(Q_OS_MACOS)
m_focusFrame.reset(new QQuickMacFocusFrame());
+#elif defined(Q_OS_WIN)
+ m_focusFrame.reset(new QQuickWindowsFocusFrame());
#endif
qAddPostRoutine(deleteQStyle);
diff --git a/src/quicknativestyle/util/FocusFrame.qml b/src/quicknativestyle/util/MacFocusFrame.qml
index eebee62c31..c281ff9b53 100644
--- a/src/quicknativestyle/util/FocusFrame.qml
+++ b/src/quicknativestyle/util/MacFocusFrame.qml
@@ -52,7 +52,7 @@ Item {
y: targetItem ? targetItem.y + topOffset - frameSize - root.y : 0
width: targetItem ? targetItem.width - leftOffset - rightOffset + (frameSize * 2) : 0
height: targetItem ? targetItem.height - topOffset - bottomOffset + (frameSize * 2) : 0
- radius: frameRadius
+ radius: frameRadius + frameSize
visible: targetItem && targetItem.visible
color: "transparent"
@@ -67,7 +67,7 @@ Item {
property: "frameSize"
duration: 300
from: 15
- to: 2.5
+ to: 3
easing.type: Easing.OutCubic
}
NumberAnimation {
diff --git a/src/quicknativestyle/util/WindowsFocusFrame.qml b/src/quicknativestyle/util/WindowsFocusFrame.qml
new file mode 100644
index 0000000000..0d23dacf1f
--- /dev/null
+++ b/src/quicknativestyle/util/WindowsFocusFrame.qml
@@ -0,0 +1,58 @@
+// Copyright (C) 2023 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
+
+Item {
+ id: root
+
+ // It's important that this item has a zero size. Otherwise, if the parent of the
+ // targetItem is e.g a layout, we will change the layout if we parent this item inside it.
+ width: 0
+ height: 0
+ // Stack on top of all siblings of the targetItem
+ z: 100
+
+ function moveToItem(item, margins, radius) {
+ if (!item) {
+ targetItem = null;
+ parent = null;
+ visible = false;
+ return;
+ }
+ visible = true
+ parent = item.parent
+ targetItem = item
+ leftOffset = margins.left
+ rightOffset = margins.right
+ topOffset = margins.top
+ bottomOffset = margins.bottom
+ frameRadius = radius
+ }
+
+ property Item targetItem
+ property real leftOffset: 0
+ property real rightOffset: 0
+ property real topOffset: 0
+ property real bottomOffset: 0
+ property real frameOpacity: 0
+ property real frameSize: 0
+ property real frameRadius: 0
+
+ Canvas {
+ x: targetItem ? targetItem.x + leftOffset - frameSize - root.x : 0
+ y: targetItem ? targetItem.y + topOffset - frameSize - root.y : 0
+ width: targetItem ? targetItem.width - leftOffset - rightOffset + (frameSize * 2) : 0
+ height: targetItem ? targetItem.height - topOffset - bottomOffset + (frameSize * 2) : 0
+ visible: targetItem && targetItem.visible
+
+ onPaint: {
+ let context = getContext("2d")
+ context.strokeStyle = Qt.rgba(0, 0, 0, 1)
+ context.setLineDash([1, 1])
+ context.beginPath()
+ context.roundedRect(0.5, 0.5, width - 1, height - 1, root.frameRadius, root.frameRadius)
+ context.stroke()
+ }
+ }
+}
diff --git a/src/quicknativestyle/util/qquickfocusframe.cpp b/src/quicknativestyle/util/qquickfocusframe.cpp
new file mode 100644
index 0000000000..bf1ee5a3ea
--- /dev/null
+++ b/src/quicknativestyle/util/qquickfocusframe.cpp
@@ -0,0 +1,118 @@
+// Copyright (C) 2023 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 "qquickfocusframe.h"
+
+#include <QtCore/qmetaobject.h>
+
+#include <QtGui/qguiapplication.h>
+
+#include <QtQml/qqmlengine.h>
+#include <QtQml/qqmlcontext.h>
+#include <QtQml/qqmlcomponent.h>
+
+#include <QtQuick/qquickitem.h>
+
+#include "items/qquickstyleitem.h"
+
+QT_BEGIN_NAMESPACE
+
+Q_LOGGING_CATEGORY(lcFocusFrame, "qt.quick.controls.focusframe")
+
+QQuickFocusFrameDescription QQuickFocusFrameDescription::Invalid = { nullptr, QQuickStyleMargins(), 0 };
+QScopedPointer<QQuickItem> QQuickFocusFrame::m_focusFrame;
+
+QQuickFocusFrame::QQuickFocusFrame()
+{
+ connect(qGuiApp, &QGuiApplication::focusObjectChanged, this, [this]{
+ if (auto item = qobject_cast<QQuickItem *>(qGuiApp->focusObject()))
+ moveToItem(item);
+ });
+}
+
+void QQuickFocusFrame::moveToItem(QQuickItem *item)
+{
+ if (!m_focusFrame) {
+ const auto context = QQmlEngine::contextForObject(item);
+ // In certain cases like QQuickWebEngineView, the item
+ // gets focus even though it has no QQmlEngine associated with its context.
+ // We need the engine for creating the focus frame component.
+ if (!context || !context->engine())
+ return;
+ m_focusFrame.reset(createFocusFrame(context));
+ if (!m_focusFrame) {
+ qWarning() << "Failed to create FocusFrame";
+ return;
+ }
+ }
+
+ const QQuickFocusFrameDescription &config = getDescriptionForItem(item);
+ QMetaObject::invokeMethod(m_focusFrame.data(), "moveToItem",
+ Q_ARG(QVariant, QVariant::fromValue(config.target)),
+ Q_ARG(QVariant, QVariant::fromValue(config.margins)),
+ Q_ARG(QVariant, QVariant::fromValue(config.radius)));
+}
+
+QQuickFocusFrameDescription QQuickFocusFrame::getDescriptionForItem(QQuickItem *focusItem) const
+{
+ qCDebug(lcFocusFrame) << "new focusobject:" << focusItem;
+ const auto parentItem = focusItem->parentItem();
+ if (!parentItem)
+ return QQuickFocusFrameDescription::Invalid;
+
+ // The item that gets active focus can be a child of the control (e.g
+ // editable ComboBox). In that case, resolve the actual control first.
+ const auto proxy = focusItem->property("__focusFrameControl").value<QQuickItem *>();
+ const auto control = proxy ? proxy : focusItem;
+ auto target = control->property("__focusFrameTarget").value<QQuickItem *>();
+ qCDebug(lcFocusFrame) << "target:" << target;
+ qCDebug(lcFocusFrame) << "control:" << control;
+
+ if (!target) {
+ // __focusFrameTarget points to the item in the control that should
+ // get the focus frame. This is usually the control itself, but can
+ // sometimes be a child (CheckBox). We anyway require
+ // this property to be set if we are to show the focus frame around
+ // the control in the first place. So for controls that don't want
+ // a frame (ProgressBar), we simply skip setting it.
+ // Also, we should never show a focus frame around custom controls.
+ // None of the built-in styles do that, so to be consistent, we
+ // shouldn't either. Besides, drawing a focus frame around an unknown
+ // item without any way to turn it off can easily be unwanted. A better
+ // way for custom controls to get a native focus frame is for us to offer
+ // a FocusFrame control (QTBUG-86818).
+ return QQuickFocusFrameDescription::Invalid;
+ }
+
+ // If the control gives us a QQuickStyleItem, we use that to configure the focus frame.
+ // By default we assume that the background delegate is a QQuickStyleItem, but the
+ // control can override this by setting __focusFrameStyleItem.
+ const auto styleItemProperty = control->property("__focusFrameStyleItem");
+ auto item = styleItemProperty.value<QQuickItem *>();
+ if (!item) {
+ const auto styleItemProperty = control->property("background");
+ item = styleItemProperty.value<QQuickItem *>();
+ }
+ qCDebug(lcFocusFrame) << "styleItem:" << item;
+ if (!item)
+ return QQuickFocusFrameDescription::Invalid;
+ if (QQuickStyleItem *styleItem = qobject_cast<QQuickStyleItem *>(item))
+ return { target, QQuickStyleMargins(styleItem->layoutMargins()), styleItem->focusFrameRadius() };
+
+ // Some controls don't have a QQuickStyleItem. But if the __focusFrameStyleItem
+ // has a "__focusFrameRadius" property set, we show a default focus frame using the specified radius instead.
+ const QVariant focusFrameRadiusVariant = item->property("__focusFrameRadius");
+ if (focusFrameRadiusVariant.isValid()) {
+ qCDebug(lcFocusFrame) << "'focusFrameRadius' property found, showing a default focus frame";
+ const QStyleOption opt;
+ const qreal radius = qMax(0.0, focusFrameRadiusVariant.toReal());
+ return { target, QQuickStyleMargins(), radius };
+ }
+
+ // The application has set a custom delegate on the control. In that
+ // case, it's the delegates responsibility to draw a focus frame.
+ qCDebug(lcFocusFrame) << "custom delegates in use, skip showing focus frame";
+ return QQuickFocusFrameDescription::Invalid;
+}
+
+QT_END_NAMESPACE
diff --git a/src/quicknativestyle/util/qquickfocusframe.h b/src/quicknativestyle/util/qquickfocusframe.h
new file mode 100644
index 0000000000..2121d6bdc5
--- /dev/null
+++ b/src/quicknativestyle/util/qquickfocusframe.h
@@ -0,0 +1,39 @@
+// Copyright (C) 2023 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 QQUICKFOCUSFRAME_H
+#define QQUICKFOCUSFRAME_H
+
+#include <QtQuick/qquickitem.h>
+#include "qquickstyleitem.h"
+
+QT_BEGIN_NAMESPACE
+
+Q_DECLARE_LOGGING_CATEGORY(lcFocusFrame)
+
+struct QQuickFocusFrameDescription {
+ QQuickItem *target;
+ QQuickStyleMargins margins;
+ const qreal radius = 3;
+ bool isValid() const { return target != nullptr; }
+ static QQuickFocusFrameDescription Invalid;
+};
+
+class QQuickFocusFrame : public QObject
+{
+ Q_OBJECT
+
+public:
+ QQuickFocusFrame();
+
+private:
+ static QScopedPointer<QQuickItem> m_focusFrame;
+
+ virtual QQuickItem *createFocusFrame(QQmlContext *context) = 0;
+ void moveToItem(QQuickItem *item);
+ QQuickFocusFrameDescription getDescriptionForItem(QQuickItem *focusItem) const;
+};
+
+QT_END_NAMESPACE
+
+#endif // QQUICKFOCUSFRAME_H
diff --git a/src/quicknativestyle/util/qquickmacfocusframe.h b/src/quicknativestyle/util/qquickmacfocusframe.h
index 88858c7688..e52cc9a300 100644
--- a/src/quicknativestyle/util/qquickmacfocusframe.h
+++ b/src/quicknativestyle/util/qquickmacfocusframe.h
@@ -1,38 +1,22 @@
-// Copyright (C) 2020 The Qt Company Ltd.
+// Copyright (C) 2023 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 QQUICKMACFOCUSFRAME_H
#define QQUICKMACFOCUSFRAME_H
-#include <QtQuick/qquickitem.h>
-#include <QtQuick/private/qquicktextedit_p.h>
-#include "qquickstyleitem.h"
+#include "qquickfocusframe.h"
QT_BEGIN_NAMESPACE
-Q_DECLARE_LOGGING_CATEGORY(lcFocusFrame)
-
-struct QQuickFocusFrameDescription {
- QQuickItem *target;
- QQuickStyleMargins margins;
- const qreal radius = 3;
- bool isValid() const { return target != nullptr; }
- static QQuickFocusFrameDescription Invalid;
-};
-
-class QQuickMacFocusFrame : public QObject
+class QQuickMacFocusFrame : public QQuickFocusFrame
{
Q_OBJECT
public:
- QQuickMacFocusFrame();
+ QQuickMacFocusFrame() = default;
private:
- static QScopedPointer<QQuickItem> m_focusFrame;
-
- void createFocusFrame(QQmlContext *context);
- void moveToItem(QQuickItem *item);
- QQuickFocusFrameDescription getDescriptionForItem(QQuickItem *focusItem) const;
+ virtual QQuickItem *createFocusFrame(QQmlContext *context) override;
};
QT_END_NAMESPACE
diff --git a/src/quicknativestyle/util/qquickmacfocusframe.mm b/src/quicknativestyle/util/qquickmacfocusframe.mm
index 8ebaf223be..c47d3e1b0a 100644
--- a/src/quicknativestyle/util/qquickmacfocusframe.mm
+++ b/src/quicknativestyle/util/qquickmacfocusframe.mm
@@ -1,141 +1,31 @@
-// Copyright (C) 2020 The Qt Company Ltd.
+// Copyright (C) 2023 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 "qquickmacfocusframe.h"
#include <AppKit/AppKit.h>
-#include <QtCore/qmetaobject.h>
-
#include <QtGui/qguiapplication.h>
#include <QtGui/private/qcoregraphics_p.h>
-#include <QtQml/qqmlengine.h>
-#include <QtQml/qqmlcontext.h>
#include <QtQml/qqmlcomponent.h>
-#include <QtQuick/qquickitem.h>
-#include <QtQuick/private/qquicktextinput_p.h>
-#include <QtQuick/private/qquicktextedit_p.h>
-#include <QtQuick/private/qquickflickable_p.h>
-
-#include <QtQuickTemplates2/private/qquickframe_p.h>
-#include <QtQuickTemplates2/private/qquickbutton_p.h>
-#include <QtQuickTemplates2/private/qquickscrollview_p.h>
-#include <QtQuickTemplates2/private/qquickslider_p.h>
-#include <QtQuickTemplates2/private/qquickcombobox_p.h>
-#include <QtQuickTemplates2/private/qquickcheckbox_p.h>
-#include <QtQuickTemplates2/private/qquickradiobutton_p.h>
-#include <QtQuickTemplates2/private/qquickspinbox_p.h>
-#include <QtQuickTemplates2/private/qquicktextfield_p.h>
-#include <QtQuickTemplates2/private/qquicktextarea_p.h>
-
-#include "items/qquickstyleitem.h"
-#include "qquicknativestyle.h"
-
QT_BEGIN_NAMESPACE
-Q_LOGGING_CATEGORY(lcFocusFrame, "qt.quick.controls.focusframe")
-
-QQuickFocusFrameDescription QQuickFocusFrameDescription::Invalid = { nullptr, QQuickStyleMargins(), 0 };
-QScopedPointer<QQuickItem> QQuickMacFocusFrame::m_focusFrame;
-
-QQuickMacFocusFrame::QQuickMacFocusFrame()
-{
- connect(qGuiApp, &QGuiApplication::focusObjectChanged, [=]{
- if (auto item = qobject_cast<QQuickItem *>(qGuiApp->focusObject()))
- moveToItem(item);
- });
-}
-
-void QQuickMacFocusFrame::moveToItem(QQuickItem *item)
-{
- if (!m_focusFrame) {
- const auto context = QQmlEngine::contextForObject(item);
- if (!context)
- return;
- createFocusFrame(context);
- }
-
- const QQuickFocusFrameDescription &config = getDescriptionForItem(item);
- QMetaObject::invokeMethod(m_focusFrame.data(), "moveToItem",
- Q_ARG(QVariant, QVariant::fromValue(config.target)),
- Q_ARG(QVariant, QVariant::fromValue(config.margins)),
- Q_ARG(QVariant, QVariant::fromValue(config.radius)));
-}
-
-void QQuickMacFocusFrame::createFocusFrame(QQmlContext *context)
+QQuickItem *QQuickMacFocusFrame::createFocusFrame(QQmlContext *context)
{
QQmlComponent component(
context->engine(),
QUrl(QStringLiteral(
- "qrc:/qt-project.org/imports/QtQuick/NativeStyle/util/FocusFrame.qml")));
- m_focusFrame.reset(qobject_cast<QQuickItem *>(component.create()));
+ "qrc:/qt-project.org/imports/QtQuick/NativeStyle/util/MacFocusFrame.qml")));
+ auto frame = qobject_cast<QQuickItem *>(component.create());
+ if (!frame)
+ return nullptr;
auto indicatorColor = qt_mac_toQColor(NSColor.keyboardFocusIndicatorColor.CGColor);
indicatorColor.setAlpha(255);
- m_focusFrame->setProperty("systemFrameColor", indicatorColor);
-}
-
-QQuickFocusFrameDescription QQuickMacFocusFrame::getDescriptionForItem(QQuickItem *focusItem) const
-{
- qCDebug(lcFocusFrame) << "new focusobject:" << focusItem;
- const auto parentItem = focusItem->parentItem();
- if (!parentItem)
- return QQuickFocusFrameDescription::Invalid;
-
- // The item that gets active focus can be a child of the control (e.g
- // editable ComboBox). In that case, resolve the actual control first.
- const auto proxy = focusItem->property("__focusFrameControl").value<QQuickItem *>();
- const auto control = proxy ? proxy : focusItem;
- auto target = control->property("__focusFrameTarget").value<QQuickItem *>();
- qCDebug(lcFocusFrame) << "target:" << target;
- qCDebug(lcFocusFrame) << "control:" << control;
-
- if (!target) {
- // __focusFrameTarget points to the item in the control that should
- // get the focus frame. This is usually the control itself, but can
- // sometimes be a child (CheckBox). We anyway require
- // this property to be set if we are to show the focus frame around
- // the control in the first place. So for controls that don't want
- // a frame (ProgressBar), we simply skip setting it.
- // Also, we should never show a focus frame around custom controls.
- // None of the built-in styles do that, so to be consistent, we
- // shouldn't either. Besides, drawing a focus frame around an unknown
- // item without any way to turn it off can easily be unwanted. A better
- // way for custom controls to get a native focus frame is for us to offer
- // a FocusFrame control (QTBUG-86818).
- return QQuickFocusFrameDescription::Invalid;
- }
-
- // If the control gives us a QQuickStyleItem, we use that to configure the focus frame.
- // By default we assume that the background delegate is a QQuickStyleItem, but the
- // control can override this by setting __focusFrameStyleItem.
- const auto styleItemProperty = control->property("__focusFrameStyleItem");
- auto item = styleItemProperty.value<QQuickItem *>();
- if (!item) {
- const auto styleItemProperty = control->property("background");
- item = styleItemProperty.value<QQuickItem *>();
- }
- qCDebug(lcFocusFrame) << "styleItem:" << item;
- if (!item)
- return QQuickFocusFrameDescription::Invalid;
- if (QQuickStyleItem *styleItem = qobject_cast<QQuickStyleItem *>(item))
- return { target, QQuickStyleMargins(styleItem->layoutMargins()), styleItem->focusFrameRadius() };
-
- // Some controls don't have a QQuickStyleItem. But if the __focusFrameStyleItem
- // has a "__isDefaultDelegate" property set, we show a default focus frame instead.
- if (item->property("__isDefaultDelegate").toBool() == true) {
- qCDebug(lcFocusFrame) << "'__isDefaultDelegate' property found, showing a default focus frame";
- const QStyleOption opt;
- const qreal radius = QQuickNativeStyle::style()->pixelMetric(QStyle::PM_TextFieldFocusFrameRadius, &opt);
- return { target, QQuickStyleMargins(), radius };
- }
-
- // The application has set a custom delegate on the control. In that
- // case, it's the delegates responsibility to draw a focus frame.
- qCDebug(lcFocusFrame) << "custom delegates in use, skip showing focus frame";
- return QQuickFocusFrameDescription::Invalid;
+ frame->setProperty("systemFrameColor", indicatorColor);
+ return frame;
}
QT_END_NAMESPACE
diff --git a/src/quicknativestyle/util/qquickwindowsfocusframe.cpp b/src/quicknativestyle/util/qquickwindowsfocusframe.cpp
new file mode 100644
index 0000000000..a92af42e21
--- /dev/null
+++ b/src/quicknativestyle/util/qquickwindowsfocusframe.cpp
@@ -0,0 +1,17 @@
+// Copyright (C) 2023 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 "qquickwindowsfocusframe.h"
+
+#include <QtQml/qqmlcomponent.h>
+
+QT_BEGIN_NAMESPACE
+
+QQuickItem *QQuickWindowsFocusFrame::createFocusFrame(QQmlContext *context)
+{
+ QQmlComponent component(context->engine(),
+ QUrl(QStringLiteral("qrc:/qt-project.org/imports/QtQuick/NativeStyle/util/WindowsFocusFrame.qml")));
+ return qobject_cast<QQuickItem *>(component.create());
+}
+
+QT_END_NAMESPACE
diff --git a/src/quicknativestyle/util/qquickwindowsfocusframe.h b/src/quicknativestyle/util/qquickwindowsfocusframe.h
new file mode 100644
index 0000000000..5bd60a1343
--- /dev/null
+++ b/src/quicknativestyle/util/qquickwindowsfocusframe.h
@@ -0,0 +1,24 @@
+// Copyright (C) 2023 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 QQUICKWINDOWSFOCUSFRAME_H
+#define QQUICKWINDOWSFOCUSFRAME_H
+
+#include "qquickfocusframe.h"
+
+QT_BEGIN_NAMESPACE
+
+class QQuickWindowsFocusFrame : public QQuickFocusFrame
+{
+ Q_OBJECT
+
+public:
+ QQuickWindowsFocusFrame() = default;
+
+private:
+ virtual QQuickItem *createFocusFrame(QQmlContext *context) override;
+};
+
+QT_END_NAMESPACE
+
+#endif // QQUICKWINDOWSFOCUSFRAME_H