aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJan Arve Sæther <jan-arve.saether@qt.io>2020-09-23 13:13:02 +0200
committerJan Arve Sæther <jan-arve.saether@qt.io>2020-09-29 12:41:00 +0200
commitad25ebd08247579754243b09f8fa60b778d9a3aa (patch)
treee6c300389d0662abecb1e5e53b0ef2bf170fd459 /src
parent0ea96f1896a13c8e01b4ee9d45439565e19eb18a (diff)
windows: Add hover animation to Button and CheckBox
Move the hover animation handling API from macOS ScrollBar down to QQuickStyleItem. Change-Id: I36c8b173a15d0f4e10a59b7f3ccfe635e05c73e7 Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/imports/controls/macos/ScrollBar.qml4
-rw-r--r--src/imports/controls/windows/Button.qml12
-rw-r--r--src/imports/controls/windows/CheckBox.qml68
-rw-r--r--src/imports/nativestyle/items/qquickstyleitem.cpp9
-rw-r--r--src/imports/nativestyle/items/qquickstyleitem.h18
-rw-r--r--src/imports/nativestyle/items/qquickstyleitemscrollbar.cpp2
-rw-r--r--src/imports/nativestyle/items/qquickstyleitemscrollbar.h17
7 files changed, 108 insertions, 22 deletions
diff --git a/src/imports/controls/macos/ScrollBar.qml b/src/imports/controls/macos/ScrollBar.qml
index 94416acd..d0ad6e9b 100644
--- a/src/imports/controls/macos/ScrollBar.qml
+++ b/src/imports/controls/macos/ScrollBar.qml
@@ -55,10 +55,10 @@ NativeStyle.DefaultScrollBar {
height: contentItem.height
control: controlRoot
subControl: NativeStyle.ScrollBar.Handle
- overrideState: NativeStyle.ScrollBar.AlwaysHovered
+ overrideState: NativeStyle.StyleItem.AlwaysHovered
opacity: controlRoot.hovered || control.pressed ? 1 : 0
visible: contentItem instanceof NativeStyle.StyleItem
- Behavior on opacity { NumberAnimation { duration: 150 } }
+ Behavior on opacity { NumberAnimation { duration: parent.transitionDuration } }
}
}
diff --git a/src/imports/controls/windows/Button.qml b/src/imports/controls/windows/Button.qml
index 751cfb3f..99b909f8 100644
--- a/src/imports/controls/windows/Button.qml
+++ b/src/imports/controls/windows/Button.qml
@@ -62,7 +62,19 @@ T.Button {
contentWidth: contentItem.implicitWidth
contentHeight: contentItem.implicitHeight
useNinePatchImage: false
+ overrideState: NativeStyle.StyleItem.NeverHovered
+ }
+ NativeStyle.Button {
+ control: control
+ x: background.x
+ y: background.y
+ width: background.width
+ height: background.height
+ useNinePatchImage: false
+ overrideState: NativeStyle.StyleItem.AlwaysHovered
+ opacity: control.hovered ? 1 : 0
+ Behavior on opacity { NumberAnimation { duration: parent.transitionDuration } }
}
icon.width: 24
diff --git a/src/imports/controls/windows/CheckBox.qml b/src/imports/controls/windows/CheckBox.qml
index d1a56fee..03778c4f 100644
--- a/src/imports/controls/windows/CheckBox.qml
+++ b/src/imports/controls/windows/CheckBox.qml
@@ -35,7 +35,73 @@
****************************************************************************/
import QtQuick
+import QtQuick.Templates as T
+import QtQuick.Controls
+import QtQuick.Controls.impl
import QtQuick.NativeStyle as NativeStyle
-NativeStyle.DefaultCheckBox {
+T.CheckBox {
+ id: control
+
+ readonly property bool nativeIndicator: indicator instanceof NativeStyle.StyleItem
+
+ implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
+ implicitContentWidth + leftPadding + rightPadding)
+ implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
+ implicitContentHeight + topPadding + bottomPadding,
+ implicitIndicatorHeight + topPadding + bottomPadding)
+
+ font.pixelSize: nativeIndicator ? indicator.styleFont(control).pixelSize : undefined
+
+ spacing: nativeIndicator ? 0 : 6
+ padding: nativeIndicator ? 0 : 6
+
+ indicator: NativeStyle.CheckBox {
+ control: control
+ y: control.topPadding + (control.availableHeight - height) >> 1
+ contentWidth: contentItem.implicitWidth
+ contentHeight: contentItem.implicitHeight
+ useNinePatchImage: false
+ overrideState: NativeStyle.StyleItem.NeverHovered
+ }
+
+ NativeStyle.CheckBox {
+ control: control
+ x: indicator.x
+ y: indicator.y
+ z: 99 // Needs to be above the "unhovered" indicator
+ width: indicator.width
+ height: indicator.height
+ useNinePatchImage: false
+ overrideState: NativeStyle.StyleItem.AlwaysHovered
+ opacity: control.hovered ? 1 : 0
+ Behavior on opacity { NumberAnimation { duration: parent.transitionDuration } }
+ }
+
+ contentItem: CheckLabel {
+ text: control.text
+ font: control.font
+ color: control.palette.windowText
+
+ // For some reason, the other styles set padding here (in the delegate), instead of in
+ // the control above. And they also adjust the indicator position by setting x and y
+ // explicitly (instead of using insets). So we follow the same pattern to ensure that
+ // setting a custom contentItem delegate from the app will end up looking the same for
+ // all styles. But this should probably be fixed for all styles (to make them work the
+ // same way as e.g Buttons).
+ leftPadding: {
+ if (nativeIndicator)
+ indicator.contentPadding.left
+ else
+ indicator && !mirrored ? indicator.width + spacing : 0
+ }
+
+ topPadding: nativeIndicator ? indicator.contentPadding.top : 0
+ rightPadding: {
+ if (nativeIndicator)
+ indicator.contentPadding.right
+ else
+ indicator && mirrored ? indicator.width + spacing : 0
+ }
+ }
}
diff --git a/src/imports/nativestyle/items/qquickstyleitem.cpp b/src/imports/nativestyle/items/qquickstyleitem.cpp
index 03659aa2..c45f0c91 100644
--- a/src/imports/nativestyle/items/qquickstyleitem.cpp
+++ b/src/imports/nativestyle/items/qquickstyleitem.cpp
@@ -196,6 +196,15 @@ void QQuickStyleItem::initStyleOptionBase(QStyleOption &styleOption)
styleOption.state |= QStyle::State_KeyboardFocusChange;
}
+ if (m_overrideState != None) {
+ // In Button.qml we fade between two versions of
+ // the handle, depending on if it's hovered or not
+ if (m_overrideState & AlwaysHovered)
+ styleOption.state |= QStyle::State_MouseOver;
+ else if (m_overrideState & NeverHovered)
+ styleOption.state &= ~QStyle::State_MouseOver;
+ }
+
qqc2Debug() << styleOption;
}
diff --git a/src/imports/nativestyle/items/qquickstyleitem.h b/src/imports/nativestyle/items/qquickstyleitem.h
index 3d5bfc31..ff870684 100644
--- a/src/imports/nativestyle/items/qquickstyleitem.h
+++ b/src/imports/nativestyle/items/qquickstyleitem.h
@@ -160,6 +160,9 @@ class QQuickStyleItem : public QQuickItem
Q_PROPERTY(qreal contentHeight READ contentHeight WRITE setContentHeight)
Q_PROPERTY(bool useNinePatchImage MEMBER m_useNinePatchImage)
+ Q_PROPERTY(OverrideState overrideState MEMBER m_overrideState)
+ Q_PROPERTY(int transitionDuration MEMBER m_transitionDuration)
+
// Output
Q_PROPERTY(QQuickStyleMargins contentPadding READ contentPadding() NOTIFY contentPaddingChanged)
Q_PROPERTY(QQuickStyleMargins layoutMargins READ layoutMargins() NOTIFY layoutMarginsChanged)
@@ -176,6 +179,14 @@ public:
};
Q_DECLARE_FLAGS(DirtyFlags, DirtyFlag)
+ enum OverrideState {
+ None = 0,
+ AlwaysHovered,
+ NeverHovered,
+ };
+ Q_ENUM(OverrideState)
+
+
#ifdef QT_DEBUG
enum DebugFlag {
NoDebug = 0x00,
@@ -244,6 +255,7 @@ protected:
#ifdef QT_DEBUG
DebugFlags m_debugFlags = NoDebug;
#endif
+ OverrideState m_overrideState = None;
private:
inline void updateGeometry();
@@ -259,6 +271,12 @@ private:
bool m_useNinePatchImage = true;
bool m_polishing = false;
+#ifdef Q_OS_MACOS
+ int m_transitionDuration = 150;
+#else
+ int m_transitionDuration = 400;
+#endif
+
private:
friend class QtQuickControls2MacOSStylePlugin;
};
diff --git a/src/imports/nativestyle/items/qquickstyleitemscrollbar.cpp b/src/imports/nativestyle/items/qquickstyleitemscrollbar.cpp
index 72f850a8..77185b48 100644
--- a/src/imports/nativestyle/items/qquickstyleitemscrollbar.cpp
+++ b/src/imports/nativestyle/items/qquickstyleitemscrollbar.cpp
@@ -83,7 +83,6 @@ void QQuickStyleItemScrollBar::initStyleOption(QStyleOptionSlider &styleOption)
if (scrollBar->isPressed())
styleOption.state |= QStyle::State_Sunken;
-#ifdef Q_OS_MACOS
if (m_overrideState != None) {
// In ScrollBar.qml we fade between two versions of
// the handle, depending on if it's hovered or not
@@ -92,7 +91,6 @@ void QQuickStyleItemScrollBar::initStyleOption(QStyleOptionSlider &styleOption)
else if (m_overrideState & NeverHovered)
styleOption.state &= ~QStyle::State_Sunken;
}
-#endif
// The following values will let the handle fill 100% of the
// groove / imageSize. But when the handle is resized by
diff --git a/src/imports/nativestyle/items/qquickstyleitemscrollbar.h b/src/imports/nativestyle/items/qquickstyleitemscrollbar.h
index db241ad8..e181d4ec 100644
--- a/src/imports/nativestyle/items/qquickstyleitemscrollbar.h
+++ b/src/imports/nativestyle/items/qquickstyleitemscrollbar.h
@@ -46,10 +46,6 @@ class QQuickStyleItemScrollBar : public QQuickStyleItem
Q_PROPERTY(SubControl subControl MEMBER m_subControl)
-#ifdef Q_OS_MACOS
- Q_PROPERTY(OverrideState overrideState MEMBER m_overrideState)
-#endif
-
QML_NAMED_ELEMENT(ScrollBar)
public:
@@ -59,15 +55,6 @@ public:
};
Q_ENUM(SubControl)
-#ifdef Q_OS_MACOS
- enum OverrideState {
- None = 0,
- AlwaysHovered,
- NeverHovered,
- };
- Q_ENUM(OverrideState)
-#endif
-
QFont styleFont(QQuickItem *control) override;
protected:
@@ -80,10 +67,6 @@ private:
private:
SubControl m_subControl = Groove;
-
-#ifdef Q_OS_MACOS
- OverrideState m_overrideState = None;
-#endif
};
#endif // QQUICKSTYLEITEMSCROLLBAR_H