mirror of
https://github.com/noctalia-dev/noctalia-shell.git
synced 2026-05-11 17:08:27 +08:00
Initial commit
This commit is contained in:
@@ -0,0 +1,177 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Effects
|
||||
import qs.Commons
|
||||
import qs.Services.UI
|
||||
|
||||
Slider {
|
||||
id: root
|
||||
|
||||
property color fillColor: "transparent"
|
||||
property var cutoutColor: Color.mSurface
|
||||
property bool snapAlways: true
|
||||
property real widthRatio: 0.7
|
||||
property string tooltipText
|
||||
property string tooltipDirection: "auto"
|
||||
property bool hovering: false
|
||||
property color topColor: "white"
|
||||
property color bottomColor: "black"
|
||||
property bool rainbowMode: false
|
||||
|
||||
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 cutoutExtra: Math.round((Style.baseWidgetSize * 0.1 * Style.uiScaleRatio) / 2) * 2
|
||||
|
||||
//horizontal: false
|
||||
orientation: Qt.Vertical
|
||||
|
||||
padding: cutoutExtra / 2
|
||||
|
||||
snapMode: snapAlways ? Slider.SnapAlways : Slider.SnapOnRelease
|
||||
implicitWidth: Math.max(trackWidth, knobDiameter)
|
||||
|
||||
background: Rectangle {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
x: root.leftPadding + root.availableWidth / 2 - width / 2
|
||||
|
||||
height: root.availableHeight - root.knobDiameter
|
||||
width: root.trackWidth
|
||||
|
||||
radius: 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
|
||||
GradientStop {
|
||||
position: 0.0
|
||||
color: root.topColor
|
||||
}
|
||||
GradientStop {
|
||||
position: 1.0
|
||||
color: root.bottomColor
|
||||
}
|
||||
}
|
||||
Gradient {
|
||||
id: rainbowGradient
|
||||
orientation: Gradient.Vertical
|
||||
GradientStop {
|
||||
position: 0.000
|
||||
color: "#FF0000"
|
||||
}
|
||||
GradientStop {
|
||||
position: 0.167
|
||||
color: "#FF00FF"
|
||||
}
|
||||
GradientStop {
|
||||
position: 0.333
|
||||
color: "#0000FF"
|
||||
}
|
||||
GradientStop {
|
||||
position: 0.500
|
||||
color: "#00FFFF"
|
||||
}
|
||||
GradientStop {
|
||||
position: 0.667
|
||||
color: "#00FF00"
|
||||
}
|
||||
GradientStop {
|
||||
position: 0.833
|
||||
color: "#FFFF00"
|
||||
}
|
||||
GradientStop {
|
||||
position: 1.000
|
||||
color: "#FF0000"
|
||||
}
|
||||
}
|
||||
|
||||
// Circular cutout
|
||||
Rectangle {
|
||||
id: knobCutout
|
||||
implicitWidth: root.knobDiameter + root.cutoutExtra
|
||||
implicitHeight: root.knobDiameter + root.cutoutExtra
|
||||
radius: width / 2
|
||||
color: root.cutoutColor !== undefined ? root.cutoutColor : Color.mSurface
|
||||
|
||||
y: root.visualPosition * (root.availableHeight - root.knobDiameter) - ((root.knobDiameter + root.cutoutExtra) / 2)
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
}
|
||||
}
|
||||
|
||||
handle: Item {
|
||||
implicitWidth: root.knobDiameter
|
||||
implicitHeight: root.knobDiameter
|
||||
y: root.topPadding + root.visualPosition * (root.availableHeight - height)
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
|
||||
Rectangle {
|
||||
id: knob
|
||||
implicitWidth: root.knobDiameter
|
||||
implicitHeight: root.knobDiameter
|
||||
radius: width / 2
|
||||
color: {
|
||||
if (root.rainbowMode) {
|
||||
// Hue Logic: Map position (0.0 to 1.0) directly to Hue
|
||||
return Qt.hsva(1 - root.visualPosition, 1, 1, 1);
|
||||
} else {
|
||||
// Linear Interpolation for Standard Gradients
|
||||
// visualPosition 0.0 = Top, 1.0 = Bottom
|
||||
var t = root.visualPosition;
|
||||
var r = root.topColor.r * (1 - t) + root.bottomColor.r * t;
|
||||
var g = root.topColor.g * (1 - t) + root.bottomColor.g * t;
|
||||
var b = root.topColor.b * (1 - t) + root.bottomColor.b * t;
|
||||
return Qt.rgba(r, g, b, 1);
|
||||
}
|
||||
}
|
||||
|
||||
border.color: root.pressed ? Color.mHover : Color.mPrimary
|
||||
border.width: Style.borderL
|
||||
anchors.centerIn: parent
|
||||
|
||||
Behavior on color {
|
||||
ColorAnimation {
|
||||
duration: Style.animationFast
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
enabled: true
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
hoverEnabled: true
|
||||
acceptedButtons: Qt.NoButton // Don't accept any mouse buttons - only hover
|
||||
propagateComposedEvents: true
|
||||
|
||||
onEntered: {
|
||||
root.hovering = true;
|
||||
if (root.tooltipText) {
|
||||
TooltipService.show(screen, knob, root.tooltipText, root.tooltipDirection);
|
||||
}
|
||||
}
|
||||
|
||||
onExited: {
|
||||
root.hovering = false;
|
||||
if (root.tooltipText) {
|
||||
TooltipService.hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Hide tooltip when slider is pressed (anywhere on the slider)
|
||||
Connections {
|
||||
target: root
|
||||
function onPressedChanged() {
|
||||
if (root.pressed && root.tooltipText) {
|
||||
TooltipService.hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user