Files
home/.local/share/plasma/plasmoids/KdeControlStation/contents/ui/lib/Slider.qml
2025-10-08 10:35:48 +02:00

209 lines
7.1 KiB
QML

import QtQuick 2.15
import QtQuick.Layouts 1.15
import QtQuick.Controls 2.15
import org.kde.plasma.core as PlasmaCore
import org.kde.plasma.components as PlasmaComponents
import org.kde.kirigami as Kirigami
Card {
id: sliderComp
signal moved
signal clicked
signal togglePage
property bool pressed: false
property alias title: title.text
property alias secondaryTitle: secondaryTitle.text
property var value: 0
property bool useIconButton: false
property string source
property bool canTogglePage: false
property bool showTitle: true
property bool thinSlider: false
property bool mediumSizeSlider: false
property int from: 0
property int to: 100
property color highlightColor: root.useSystemColorsOnSliders ? root.themeHighlightColor : root.slidersColor
// Helps to play volume feedback while moving with cursor
Binding { sliderComp.pressed: sliderLoader.item.pressed }
// Binds slider value whent it's changed by keyboard
Binding {
target: sliderLoader.item
property: "value"
value: sliderComp.value
restoreMode: Binding.RestoreBindingOrValue
}
Connections {
target: sliderLoader.item
function onMoved() {
sliderComp.value = sliderLoader.item.value;
sliderComp.moved();
}
}
MouseArea {
id: mouseArea
anchors.fill: parent
hoverEnabled: true
enabled: !root.editingLayout
cursorShape: Qt.PointingHandCursor
onClicked: sliderComp.togglePage()
}
ColumnLayout {
anchors.fill: parent
anchors.margins: root.largeSpacing
clip: true
spacing: 1
RowLayout {
Layout.fillHeight: true
Layout.fillWidth: true
spacing: 1
visible: showTitle
PlasmaComponents.Label {
id: title
Layout.fillHeight: true
Layout.fillWidth: true
Layout.alignment: Qt.AlignLeft
font.pixelSize: root.largeFontSize
font.weight: Font.Bold
font.capitalization: Font.Capitalize
elide: Text.ElideRight
}
PlasmaComponents.Label {
id: secondaryTitle
visible: root.showPercentage
Layout.fillHeight: true
Layout.fillWidth: true
Layout.alignment: Qt.AlignRight
font.pixelSize: root.largeFontSize
font.weight: Font.Bold
font.capitalization: Font.Capitalize
horizontalAlignment: Text.AlignRight
}
}
RowLayout {
Layout.fillHeight: true
Layout.fillWidth: true
spacing: 0
Kirigami.Icon {
id: icon
source: sliderComp.source
visible: !sliderComp.useIconButton
Layout.preferredHeight: root.largeFontSize*2
Layout.preferredWidth: Layout.preferredHeight
Layout.margins: 0
}
PlasmaComponents.ToolButton {
id: iconButton
visible: sliderComp.useIconButton
icon.name: sliderComp.source
Layout.preferredHeight: root.largeFontSize*2
Layout.preferredWidth: Layout.preferredHeight
onClicked: sliderComp.clicked()
}
Loader {
id: sliderLoader
sourceComponent: root.usePlasmaSliders ? plasmaSlider : customSlider
Layout.fillWidth: true
Layout.margins: 0
onLoaded: { sliderLoader.item.value = sliderComp.value; }
}
Component {
id: customSlider
Slider {
id: slider
Layout.fillWidth: true
Layout.margins: 0
from: sliderComp.from
to: sliderComp.to
stepSize: 2
snapMode: Slider.SnapAlways
background: Rectangle {
x: slider.leftPadding
y: slider.topPadding + slider.availableHeight / 2 - height / 2
implicitWidth: 200
implicitHeight: thinSlider ? 7 : mediumSizeSlider ? 11 : 22
width: slider.availableWidth
height: parent.height
radius: height / 2
color: root.disabledBgColor
border.color: root.isDarkTheme ? root.disabledBgColor : Qt.rgba(0, 0, 0, 0.27)
Rectangle {
id: levelIndicator
width: (value - from) / (to - from) * (slider.width - handle.width) + (handle.width)
height: parent.height - 2
color: highlightColor
radius: height / 2
border.width: 0
anchors.verticalCenter: parent.verticalCenter
}
}
handle: Rectangle {
id: handle
x: slider.leftPadding + slider.visualPosition * (slider.availableWidth - width)
y: slider.topPadding + slider.availableHeight / 2 - height / 2
implicitWidth: thinSlider ? 17 :
(mediumSizeSlider&&(slider.hovered || slider.pressed)) ? levelIndicator.height*3.7 :
levelIndicator.height
implicitHeight: thinSlider ? 17 :
(mediumSizeSlider&&(slider.hovered || slider.pressed)) ? levelIndicator.height*2.5 :
levelIndicator.height
radius: mediumSizeSlider ? 10 : height / 2
color: mediumSizeSlider && slider.pressed ? "transparent" : slider.pressed ? "#f0f0f0" : "#f6f6f6"
border.color: "#bdbebf"
Behavior on implicitWidth {
NumberAnimation { duration: 200 }
}
}
}
}
Component {
id: plasmaSlider
PlasmaComponents.Slider {
id: slider
Layout.fillWidth: true
Layout.margins: 0
from: sliderComp.from
to: sliderComp.to
stepSize: 2
snapMode: Slider.SnapAlways
}
}
PlasmaComponents.ToolButton {
id: openVolumePageButton
visible: sliderComp.canTogglePage
icon.name: "arrow-right"
Layout.preferredHeight: root.largeFontSize*2
Layout.preferredWidth: Layout.preferredHeight
onClicked: sliderComp.togglePage()
}
}
}
}