mirror of
https://github.com/noctalia-dev/noctalia-shell.git
synced 2026-05-11 17:08:27 +08:00
sliders: rewrote the display using Shape to avoid visible stacked hacks when cross-fading colors
This commit is contained in:
+82
-22
@@ -1,6 +1,6 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Effects
|
||||
import QtQuick.Shapes
|
||||
import qs.Commons
|
||||
import qs.Services.UI
|
||||
|
||||
@@ -20,9 +20,9 @@ Slider {
|
||||
|
||||
readonly property real knobDiameter: Math.round((Style.baseWidgetSize * widthRatio * Style.uiScaleRatio) / 2) * 2
|
||||
readonly property real trackWidth: Math.round((knobDiameter * 0.4 * Style.uiScaleRatio) / 2) * 2
|
||||
readonly property real trackRadius: Math.min(Style.iRadiusL, trackWidth / 2)
|
||||
readonly property real cutoutExtra: Math.round((Style.baseWidgetSize * 0.1 * Style.uiScaleRatio) / 2) * 2
|
||||
|
||||
//horizontal: false
|
||||
orientation: Qt.Vertical
|
||||
|
||||
padding: cutoutExtra / 2
|
||||
@@ -30,25 +30,19 @@ Slider {
|
||||
snapMode: snapAlways ? Slider.SnapAlways : Slider.SnapOnRelease
|
||||
implicitWidth: Math.max(trackWidth, knobDiameter)
|
||||
|
||||
background: Rectangle {
|
||||
background: Item {
|
||||
id: bgContainer
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
x: root.leftPadding + root.availableWidth / 2 - width / 2
|
||||
|
||||
height: root.availableHeight - root.knobDiameter
|
||||
width: root.trackWidth
|
||||
height: root.availableHeight
|
||||
|
||||
radius: Math.min(Style.iRadiusL, width / 2)
|
||||
color: Qt.alpha(Color.mSurface, 0.5)
|
||||
border.color: Qt.alpha(Color.mOutline, 0.5)
|
||||
border.width: Style.borderS
|
||||
|
||||
// Gradients
|
||||
gradient: root.rainbowMode ? rainbowGradient : standardGradient
|
||||
Gradient {
|
||||
id: standardGradient
|
||||
orientation: Gradient.Vertical
|
||||
LinearGradient {
|
||||
id: standardLinearGradient
|
||||
x1: 0
|
||||
y1: 0
|
||||
x2: 0
|
||||
y2: root.availableHeight
|
||||
GradientStop {
|
||||
position: 0.0
|
||||
color: root.topColor
|
||||
@@ -58,9 +52,13 @@ Slider {
|
||||
color: root.bottomColor
|
||||
}
|
||||
}
|
||||
Gradient {
|
||||
id: rainbowGradient
|
||||
orientation: Gradient.Vertical
|
||||
|
||||
LinearGradient {
|
||||
id: rainbowLinearGradient
|
||||
x1: 0
|
||||
y1: 0
|
||||
x2: 0
|
||||
y2: root.availableHeight
|
||||
GradientStop {
|
||||
position: 0.000
|
||||
color: "#FF0000"
|
||||
@@ -91,6 +89,69 @@ Slider {
|
||||
}
|
||||
}
|
||||
|
||||
Shape {
|
||||
anchors.centerIn: parent
|
||||
width: root.trackWidth
|
||||
height: bgContainer.height
|
||||
layer.enabled: true
|
||||
layer.samples: 4
|
||||
|
||||
ShapePath {
|
||||
id: trackPath
|
||||
strokeColor: Qt.alpha(Color.mOutline, 0.5)
|
||||
strokeWidth: Style.borderS
|
||||
fillGradient: root.rainbowMode ? rainbowLinearGradient : standardLinearGradient
|
||||
|
||||
readonly property real w: root.trackWidth
|
||||
readonly property real h: root.availableHeight
|
||||
readonly property real r: root.trackRadius
|
||||
|
||||
startX: r
|
||||
startY: 0
|
||||
|
||||
PathLine {
|
||||
x: trackPath.w - trackPath.r
|
||||
y: 0
|
||||
}
|
||||
PathArc {
|
||||
x: trackPath.w
|
||||
y: trackPath.r
|
||||
radiusX: trackPath.r
|
||||
radiusY: trackPath.r
|
||||
}
|
||||
PathLine {
|
||||
x: trackPath.w
|
||||
y: trackPath.h - trackPath.r
|
||||
}
|
||||
PathArc {
|
||||
x: trackPath.w - trackPath.r
|
||||
y: trackPath.h
|
||||
radiusX: trackPath.r
|
||||
radiusY: trackPath.r
|
||||
}
|
||||
PathLine {
|
||||
x: trackPath.r
|
||||
y: trackPath.h
|
||||
}
|
||||
PathArc {
|
||||
x: 0
|
||||
y: trackPath.h - trackPath.r
|
||||
radiusX: trackPath.r
|
||||
radiusY: trackPath.r
|
||||
}
|
||||
PathLine {
|
||||
x: 0
|
||||
y: trackPath.r
|
||||
}
|
||||
PathArc {
|
||||
x: trackPath.r
|
||||
y: 0
|
||||
radiusX: trackPath.r
|
||||
radiusY: trackPath.r
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Circular cutout
|
||||
Rectangle {
|
||||
id: knobCutout
|
||||
@@ -98,8 +159,7 @@ Slider {
|
||||
implicitHeight: root.knobDiameter + root.cutoutExtra
|
||||
radius: Math.min(Style.iRadiusL, width / 2)
|
||||
color: root.cutoutColor !== undefined ? root.cutoutColor : Color.mSurface
|
||||
|
||||
y: root.visualPosition * (root.availableHeight - root.knobDiameter) - ((root.knobDiameter + root.cutoutExtra) / 2)
|
||||
y: root.visualPosition * (root.availableHeight - root.knobDiameter) - root.cutoutExtra / 2
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
}
|
||||
}
|
||||
|
||||
+147
-40
@@ -1,6 +1,6 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Effects
|
||||
import QtQuick.Shapes
|
||||
import qs.Commons
|
||||
import qs.Services.UI
|
||||
|
||||
@@ -19,6 +19,7 @@ Slider {
|
||||
|
||||
readonly property real knobDiameter: Math.round((Style.baseWidgetSize * heightRatio * Style.uiScaleRatio) / 2) * 2
|
||||
readonly property real trackHeight: Math.round((knobDiameter * 0.4 * Style.uiScaleRatio) / 2) * 2
|
||||
readonly property real trackRadius: Math.min(Style.iRadiusL, trackHeight / 2)
|
||||
readonly property real cutoutExtra: Math.round((Style.baseWidgetSize * 0.1 * Style.uiScaleRatio) / 2) * 2
|
||||
|
||||
padding: cutoutExtra / 2
|
||||
@@ -26,49 +27,155 @@ Slider {
|
||||
snapMode: snapAlways ? Slider.SnapAlways : Slider.SnapOnRelease
|
||||
implicitHeight: Math.max(trackHeight, knobDiameter)
|
||||
|
||||
background: Rectangle {
|
||||
background: Item {
|
||||
id: bgContainer
|
||||
x: root.leftPadding
|
||||
y: root.topPadding + root.availableHeight / 2 - height / 2
|
||||
y: root.topPadding + root.availableHeight / 2 - root.trackHeight / 2
|
||||
implicitWidth: Style.sliderWidth
|
||||
implicitHeight: trackHeight
|
||||
implicitHeight: root.trackHeight
|
||||
width: root.availableWidth
|
||||
height: implicitHeight
|
||||
radius: Math.min(Style.iRadiusL, height / 2)
|
||||
color: Qt.alpha(Color.mSurface, 0.5)
|
||||
border.color: Qt.alpha(Color.mOutline, 0.5)
|
||||
border.width: Style.borderS
|
||||
height: root.trackHeight
|
||||
|
||||
// A container composite shape that puts a semicircle on the end
|
||||
Item {
|
||||
id: activeTrackContainer
|
||||
width: root.visualPosition * parent.width
|
||||
height: parent.height
|
||||
readonly property real fillWidth: root.visualPosition * width
|
||||
|
||||
// The rounded end cap made from a rounded rectangle
|
||||
Rectangle {
|
||||
width: parent.height
|
||||
height: parent.height
|
||||
radius: Math.min(Style.iRadiusL, width / 2)
|
||||
color: Qt.darker(effectiveFillColor, 1.2) //starting color of gradient
|
||||
// Background track
|
||||
Shape {
|
||||
anchors.fill: parent
|
||||
layer.enabled: true
|
||||
layer.samples: 4
|
||||
|
||||
ShapePath {
|
||||
id: bgPath
|
||||
strokeColor: Qt.alpha(Color.mOutline, 0.5)
|
||||
strokeWidth: Style.borderS
|
||||
fillColor: Qt.alpha(Color.mSurface, 0.5)
|
||||
|
||||
readonly property real w: bgContainer.width
|
||||
readonly property real h: bgContainer.height
|
||||
readonly property real r: root.trackRadius
|
||||
|
||||
startX: r
|
||||
startY: 0
|
||||
|
||||
PathLine {
|
||||
x: bgPath.w - bgPath.r
|
||||
y: 0
|
||||
}
|
||||
PathArc {
|
||||
x: bgPath.w
|
||||
y: bgPath.r
|
||||
radiusX: bgPath.r
|
||||
radiusY: bgPath.r
|
||||
}
|
||||
PathLine {
|
||||
x: bgPath.w
|
||||
y: bgPath.h - bgPath.r
|
||||
}
|
||||
PathArc {
|
||||
x: bgPath.w - bgPath.r
|
||||
y: bgPath.h
|
||||
radiusX: bgPath.r
|
||||
radiusY: bgPath.r
|
||||
}
|
||||
PathLine {
|
||||
x: bgPath.r
|
||||
y: bgPath.h
|
||||
}
|
||||
PathArc {
|
||||
x: 0
|
||||
y: bgPath.h - bgPath.r
|
||||
radiusX: bgPath.r
|
||||
radiusY: bgPath.r
|
||||
}
|
||||
PathLine {
|
||||
x: 0
|
||||
y: bgPath.r
|
||||
}
|
||||
PathArc {
|
||||
x: bgPath.r
|
||||
y: 0
|
||||
radiusX: bgPath.r
|
||||
radiusY: bgPath.r
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The main rectangle
|
||||
Rectangle {
|
||||
x: parent.height / 2
|
||||
width: parent.width - x // Fills the rest of the container
|
||||
height: parent.height
|
||||
radius: 0
|
||||
// Animated gradient fill
|
||||
gradient: Gradient {
|
||||
orientation: Gradient.Horizontal
|
||||
GradientStop {
|
||||
position: 0.0
|
||||
color: Qt.darker(effectiveFillColor, 1.2)
|
||||
}
|
||||
GradientStop {
|
||||
position: 1.0
|
||||
color: effectiveFillColor
|
||||
}
|
||||
LinearGradient {
|
||||
id: fillGradient
|
||||
x1: 0
|
||||
y1: 0
|
||||
x2: root.availableWidth
|
||||
y2: 0
|
||||
GradientStop {
|
||||
position: 0.0
|
||||
color: Qt.darker(effectiveFillColor, 1.2)
|
||||
}
|
||||
GradientStop {
|
||||
position: 1.0
|
||||
color: effectiveFillColor
|
||||
}
|
||||
}
|
||||
|
||||
// Active/filled track
|
||||
Shape {
|
||||
width: bgContainer.fillWidth
|
||||
height: bgContainer.height
|
||||
visible: bgContainer.fillWidth > 0
|
||||
layer.enabled: true
|
||||
layer.samples: 4
|
||||
clip: true
|
||||
|
||||
ShapePath {
|
||||
id: fillPath
|
||||
strokeColor: "transparent"
|
||||
fillGradient: fillGradient
|
||||
|
||||
readonly property real fullWidth: root.availableWidth
|
||||
readonly property real h: root.trackHeight
|
||||
readonly property real r: root.trackRadius
|
||||
|
||||
startX: r
|
||||
startY: 0
|
||||
|
||||
PathLine {
|
||||
x: fillPath.fullWidth - fillPath.r
|
||||
y: 0
|
||||
}
|
||||
PathArc {
|
||||
x: fillPath.fullWidth
|
||||
y: fillPath.r
|
||||
radiusX: fillPath.r
|
||||
radiusY: fillPath.r
|
||||
}
|
||||
PathLine {
|
||||
x: fillPath.fullWidth
|
||||
y: fillPath.h - fillPath.r
|
||||
}
|
||||
PathArc {
|
||||
x: fillPath.fullWidth - fillPath.r
|
||||
y: fillPath.h
|
||||
radiusX: fillPath.r
|
||||
radiusY: fillPath.r
|
||||
}
|
||||
PathLine {
|
||||
x: fillPath.r
|
||||
y: fillPath.h
|
||||
}
|
||||
PathArc {
|
||||
x: 0
|
||||
y: fillPath.h - fillPath.r
|
||||
radiusX: fillPath.r
|
||||
radiusY: fillPath.r
|
||||
}
|
||||
PathLine {
|
||||
x: 0
|
||||
y: fillPath.r
|
||||
}
|
||||
PathArc {
|
||||
x: fillPath.r
|
||||
y: 0
|
||||
radiusX: fillPath.r
|
||||
radiusY: fillPath.r
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -76,11 +183,11 @@ Slider {
|
||||
// Circular cutout
|
||||
Rectangle {
|
||||
id: knobCutout
|
||||
implicitWidth: knobDiameter + cutoutExtra
|
||||
implicitHeight: knobDiameter + cutoutExtra
|
||||
implicitWidth: root.knobDiameter + root.cutoutExtra
|
||||
implicitHeight: root.knobDiameter + root.cutoutExtra
|
||||
radius: Math.min(Style.iRadiusL, width / 2)
|
||||
color: root.cutoutColor !== undefined ? root.cutoutColor : Color.mSurface
|
||||
x: root.leftPadding + root.visualPosition * (root.availableWidth - root.knobDiameter) - cutoutExtra
|
||||
x: root.visualPosition * (root.availableWidth - root.knobDiameter) - root.cutoutExtra / 2
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user