aboutsummaryrefslogtreecommitdiffstats
path: root/src/clapcontrols/ClapDial.qml
diff options
context:
space:
mode:
Diffstat (limited to 'src/clapcontrols/ClapDial.qml')
-rw-r--r--src/clapcontrols/ClapDial.qml237
1 files changed, 237 insertions, 0 deletions
diff --git a/src/clapcontrols/ClapDial.qml b/src/clapcontrols/ClapDial.qml
new file mode 100644
index 0000000..771f9cb
--- /dev/null
+++ b/src/clapcontrols/ClapDial.qml
@@ -0,0 +1,237 @@
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Qt-Commercial
+
+import QtQml
+import QtQuick
+import QtQuick.Controls.Basic
+import QtQuick.Shapes
+
+import Clap.Interface
+import Clap.Controls
+
+Dial {
+ id: ctrl
+ Keys.onLeftPressed: {}
+ required property int paramId
+ property var param
+ property var paramInfo
+ property real modulation: 0
+
+ property bool modulationEnabled: false
+ property real defaultValue: range / 2
+ property bool inverted: false
+ property int textPrecision: 2
+ property int precisionMultiplier: 10
+ property string valueType: "dB"
+
+ readonly property color cBg: QClapStyle.color("bg2")
+ readonly property color cFg: QClapStyle.color("fg")
+ readonly property color cBorder: QClapStyle.color("bg0_h")
+ readonly property color cParam: QClapStyle.color("fg3")
+ readonly property color cMod: QClapStyle.color("orange")
+ readonly property color cNormal: QClapStyle.color("transparent")
+ property color cBgNormal: Qt.tint(cBg, cNormal)
+ property color cFgNormal: Qt.tint(cFg, cNormal)
+ property color cBorderNormal: Qt.tint(cBorder, cNormal)
+ property color cParamNormal: Qt.tint(cParam, cNormal)
+ property color cModNormal: Qt.tint(cMod, cNormal)
+
+ readonly property color cDisabled: "red"
+ property color cBgDisabled: Qt.tint(cBg, cDisabled)
+ property color cFgDisabled: Qt.tint(cFg, cDisabled)
+ property color cBorderDisabled: Qt.tint(cBorder, cDisabled)
+ property color cParamDisabled: Qt.tint(cParam, cDisabled)
+ property color cModDisabled: Qt.tint(cMod, cDisabled)
+
+ readonly property real range: Math.abs(from - to)
+ readonly property int size: ctrl.background.width
+ readonly property real center: size / 2
+ readonly property real borderWidth: size * 0.13
+ readonly property real modulationAngle: (modulation - (-80)) * (520 - (-260)) / (80 - (-80)) + (-260)
+ readonly property real startAnglePos: 130
+ property bool precisionMode: false
+
+ Connections {
+ target: ClapInterface
+ function onParamChanged() {
+ ctrl.param = ClapInterface.param(paramId);
+ ctrl.value = ctrl.param.value;
+ ctrl.modulation = ctrl.param.modulation;
+ }
+ function onParamInfoChanged() {
+ ctrl.paramInfo = ClapInterface.paramInfo(paramId);
+ ctrl.value = ctrl.paramInfo.defaultValue;
+ ctrl.from = ctrl.paramInfo.minValue;
+ ctrl.to = ctrl.paramInfo.maxValue;
+ }
+ function onStateChanged() {
+ switch(ClapInterface.state) {
+ case ClapInterface.Active: {
+ ctrl.enabled = true;
+ break;
+ }
+ case ClapInterface.Inactive: {
+ ctrl.enabled = false;
+ break;
+ }
+ }
+ }
+ }
+
+ onValueChanged: {
+ if (ctrl.pressed || ctrl.hovered) {
+ ClapInterface.enqueueParam(ctrl.paramId, ctrl.value);
+ }
+ }
+
+ function clamp(val, min, max) {
+ return Math.min(Math.max(val, min), max);
+ }
+
+ enum ColorType { Bg, Fg, Border, Param, Mod }
+ function activeColor(type) {
+ switch(type) {
+ case ClapDial.ColorType.Bg: {
+ return !ctrl.enabled ? ctrl.cBgDisabled : ctrl.cBg
+ }
+ case ClapDial.ColorType.Fg: {
+ return !ctrl.enabled ? ctrl.cFgDisabled :
+ !ctrl.precisionMode ? ctrl.cFg : QClapStyle.color("yellow2")
+ }
+ case ClapDial.ColorType.Border: {
+ return !ctrl.enabled ? ctrl.cBorderDisabled : ctrl.cBorder
+ }
+ case ClapDial.ColorType.Param: {
+ return !ctrl.enabled ? ctrl.cParamDisabled : ctrl.cParam
+ }
+ case ClapDial.ColorType.Mod: {
+ return !ctrl.modulationEnabled ? "transparent" :
+ !ctrl.enabled ? ctrl.cModDisabled :
+ !(ctrl.hovered | ctrl.activeFocus) ? ctrl.cModNormal
+ : ctrl.cMod
+ }
+ }
+ }
+
+ implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
+ implicitContentWidth + leftPadding + rightPadding)
+ implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
+ implicitContentHeight + topPadding + bottomPadding)
+
+ // Keys.onLeftPressed: {}
+ stepSize: range / 20
+ inputMode: Dial.Vertical
+ focusPolicy: Qt.WheelFocus
+ padding: 10
+ wheelEnabled: true
+ focus: true
+ startAngle: 0
+ endAngle: 280
+ enabled: true
+
+ background: Rectangle {
+ implicitWidth: 100
+ implicitHeight: 100
+
+ width: Math.max(64, Math.min(ctrl.width, ctrl.height))
+ height: width
+
+ x: ctrl.width / 2 - width / 2
+ y: ctrl.height / 2 - height / 2
+
+ radius: width / 2
+ color: ctrl.activeColor(ClapDial.ColorType.Bg)
+ border.color: ctrl.activeColor(ClapDial.ColorType.Border)
+ border.width: ctrl.borderWidth
+ antialiasing: true
+
+ Text {
+ anchors.centerIn: parent
+ font.pointSize: ctrl.size * 0.1
+ text: !ctrl.precisionMode ? ctrl.value.toFixed(ctrl.textPrecision) + ' ' + ctrl.valueType
+ : ctrl.value.toFixed(4)
+ color: ctrl.activeColor(ClapDial.ColorType.Fg)
+ }
+ } // background
+
+ handle: Shape {
+ z: 1
+ implicitWidth: ctrl.background.width
+ implicitHeight: ctrl.background.height
+ x: ctrl.background.x
+ y: ctrl.background.y
+ layer.enabled: true
+ layer.samples: 4
+ antialiasing: true
+
+ component ParamIndication: ShapePath {
+ id: indication
+
+ required property real range
+ required property real borderAmount
+ property real offset: 0
+ property real start: ctrl.startAnglePos
+ readonly property real radius: (ctrl.background.width / 2) - (borderAmount / 2) - offset
+
+ capStyle: ShapePath.FlatCap
+ fillColor: "transparent"
+ strokeWidth: borderAmount
+
+ PathAngleArc {
+ centerX: ctrl.center
+ centerY: ctrl.center
+ radiusX: indication.radius
+ radiusY: radiusX
+ startAngle: indication.start
+ sweepAngle: indication.range
+ }
+ }
+
+ ParamIndication { // Parameter Value
+ range: ctrl.angle
+ borderAmount: ctrl.borderWidth + 1
+ strokeColor: ctrl.activeColor(ClapDial.ColorType.Param)
+ }
+
+ ParamIndication { // Parameter Modulation
+ range: ctrl.modulationAngle
+ borderAmount: ctrl.borderWidth * 0.5
+ strokeColor: ctrl.activeColor(ClapDial.ColorType.Mod)
+ offset: borderAmount + 1
+ }
+ }
+
+ Keys.onPressed: (event) => {
+ if (event.key === Qt.Key_Shift) {
+ ctrl.precisionMode = true;
+ }
+ }
+ Keys.onReleased: (event) => {
+ if (event.key === Qt.Key_Shift) {
+ ctrl.precisionMode = false;
+ }
+ }
+
+ // NormalMode
+ WheelHandler {
+ acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad
+ acceptedModifiers: Qt.NoModifier
+ cursorShape: Qt.DragMoveCursor
+ onWheel: (wev) => {
+ let delta = (wev.angleDelta.y / 120) * ctrl.stepSize;
+ let v = !ctrl.inverted ? ctrl.value + delta : ctrl.value - delta;
+ ctrl.value = ctrl.clamp(ctrl.from, v, ctrl.to);
+ }
+ }
+ // PrecisionMode
+ WheelHandler {
+ acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad
+ acceptedModifiers: Qt.ShiftModifier
+ cursorShape: Qt.DragMoveCursor
+ onWheel: (wev) => {
+ let delta = (wev.angleDelta.y / (120 * 10)) * ctrl.stepSize;
+ let v = !ctrl.inverted ? ctrl.value + delta : ctrl.value - delta;
+ ctrl.value = ctrl.clamp(ctrl.from, v, ctrl.to);
+ }
+ }
+}