P5Panel, P5Button, P5Slider and P5Tooltip become Panel, ActionButton, LevelSlider and Tooltip. ActionButton and LevelSlider avoid clashing with QtQuick.Controls, which the ask panel imports.
130 lines
3.6 KiB
QML
130 lines
3.6 KiB
QML
import QtQuick
|
|
import "root:/config"
|
|
import "root:/components"
|
|
|
|
// Hairline slider with a round handle. Drag or click anywhere on the rail.
|
|
Item {
|
|
id: root
|
|
|
|
property real value: 0 // 0..1
|
|
property color accent: Theme.primary
|
|
property real stepSize: 0.05
|
|
|
|
signal moved(real value)
|
|
|
|
implicitHeight: 18
|
|
implicitWidth: 200
|
|
focusPolicy: root.enabled ? Qt.StrongFocus : Qt.NoFocus
|
|
|
|
readonly property real _lean: Theme.skew * height
|
|
|
|
function commit(nextValue: real): void {
|
|
if (!root.enabled)
|
|
return;
|
|
root.moved(Math.max(0, Math.min(1, nextValue)));
|
|
}
|
|
|
|
// Rail
|
|
Skew {
|
|
id: rail
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
anchors.left: parent.left
|
|
anchors.right: parent.right
|
|
height: root.activeFocus ? 4 : 2
|
|
// Focus widens the rail and rings it in the accent rather than filling
|
|
// it: the level fill is often the accent itself, and a solid accent
|
|
// rail swallowed it.
|
|
color: root.activeFocus
|
|
? Theme.surfaceAlt
|
|
: Theme.alpha(root.enabled ? Theme.outline : Theme.treatmentDisabledMark, 0.7)
|
|
borderColor: root.activeFocus ? Theme.accent : "transparent"
|
|
borderWidth: root.activeFocus ? Theme.stroke : 0
|
|
|
|
Behavior on height {
|
|
NumberAnimation { duration: Theme.durFast }
|
|
}
|
|
}
|
|
|
|
// Fill
|
|
Skew {
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
anchors.left: parent.left
|
|
width: Math.max(0, Math.min(1, root.value)) * root.width
|
|
height: root.activeFocus ? 4 : 2
|
|
color: root.enabled ? root.accent : Theme.treatmentDisabledText
|
|
|
|
Behavior on width {
|
|
enabled: !drag.active
|
|
NumberAnimation { duration: Theme.durFast }
|
|
}
|
|
|
|
Behavior on color {
|
|
ColorAnimation { duration: Theme.durBase }
|
|
}
|
|
}
|
|
|
|
// Handle
|
|
Skew {
|
|
id: handle
|
|
width: height
|
|
radius: height / 2
|
|
height: root.activeFocus || hover.hovered || drag.active ? 12 : 10
|
|
color: root.enabled ? Theme.text : Theme.treatmentDisabledText
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
x: Math.max(0, Math.min(1, root.value)) * root.width - width / 2
|
|
|
|
Behavior on height {
|
|
NumberAnimation { duration: Theme.durFast; easing.type: Easing.OutCubic }
|
|
}
|
|
Behavior on x {
|
|
enabled: !drag.active
|
|
NumberAnimation { duration: Theme.durFast }
|
|
}
|
|
}
|
|
|
|
HoverHandler {
|
|
id: hover
|
|
enabled: root.enabled
|
|
cursorShape: Qt.PointingHandCursor
|
|
}
|
|
|
|
TapHandler {
|
|
enabled: root.enabled
|
|
onPressedChanged: if (pressed) root.forceActiveFocus(Qt.MouseFocusReason)
|
|
onTapped: event => root.commit(event.position.x / root.width)
|
|
}
|
|
|
|
DragHandler {
|
|
id: drag
|
|
enabled: root.enabled
|
|
target: null
|
|
xAxis.enabled: true
|
|
yAxis.enabled: false
|
|
onCentroidChanged: {
|
|
if (!active) return;
|
|
root.forceActiveFocus(Qt.MouseFocusReason);
|
|
root.commit(centroid.position.x / root.width);
|
|
}
|
|
}
|
|
|
|
Keys.onPressed: event => {
|
|
switch (event.key) {
|
|
case Qt.Key_Left:
|
|
root.commit(root.value - root.stepSize);
|
|
break;
|
|
case Qt.Key_Right:
|
|
root.commit(root.value + root.stepSize);
|
|
break;
|
|
case Qt.Key_Home:
|
|
root.commit(0);
|
|
break;
|
|
case Qt.Key_End:
|
|
root.commit(1);
|
|
break;
|
|
default:
|
|
return;
|
|
}
|
|
event.accepted = true;
|
|
}
|
|
}
|