summaryrefslogtreecommitdiff
path: root/modules/controlcenter/components
diff options
context:
space:
mode:
Diffstat (limited to 'modules/controlcenter/components')
-rw-r--r--modules/controlcenter/components/ConnectedButtonGroup.qml108
-rw-r--r--modules/controlcenter/components/ReadonlySlider.qml67
2 files changed, 175 insertions, 0 deletions
diff --git a/modules/controlcenter/components/ConnectedButtonGroup.qml b/modules/controlcenter/components/ConnectedButtonGroup.qml
new file mode 100644
index 0000000..01cd612
--- /dev/null
+++ b/modules/controlcenter/components/ConnectedButtonGroup.qml
@@ -0,0 +1,108 @@
+import ".."
+import qs.components
+import qs.components.controls
+import qs.components.effects
+import qs.services
+import qs.config
+import QtQuick
+import QtQuick.Layouts
+
+StyledRect {
+ id: root
+
+ property var options: [] // Array of {label: string, propertyName: string, onToggled: function}
+ property var rootItem: null // The root item that contains the properties we want to bind to
+ property string title: "" // Optional title text
+
+ Layout.fillWidth: true
+ implicitHeight: layout.implicitHeight + Appearance.padding.large * 2
+ radius: Appearance.rounding.normal
+ color: Colours.layer(Colours.palette.m3surfaceContainer, 2)
+ clip: true
+
+ Behavior on implicitHeight {
+ Anim {}
+ }
+
+ ColumnLayout {
+ id: layout
+
+ anchors.fill: parent
+ anchors.margins: Appearance.padding.large
+ spacing: Appearance.spacing.normal
+
+ StyledText {
+ visible: root.title !== ""
+ text: root.title
+ font.pointSize: Appearance.font.size.normal
+ }
+
+ RowLayout {
+ id: buttonRow
+ Layout.alignment: Qt.AlignHCenter
+ spacing: Appearance.spacing.small
+
+ Repeater {
+ id: repeater
+ model: root.options
+
+ delegate: TextButton {
+ id: button
+ required property int index
+ required property var modelData
+
+ Layout.fillWidth: true
+ text: modelData.label
+
+ property bool _checked: false
+
+ checked: _checked
+ toggle: false
+ type: TextButton.Tonal
+
+ // Create binding in Component.onCompleted
+ Component.onCompleted: {
+ if (root.rootItem && modelData.propertyName) {
+ const propName = modelData.propertyName;
+ const rootItem = root.rootItem;
+ _checked = Qt.binding(function () {
+ return rootItem[propName] ?? false;
+ });
+ }
+ }
+
+ // Match utilities Toggles radius styling
+ // Each button has full rounding (not connected) since they have spacing
+ radius: stateLayer.pressed ? Appearance.rounding.small / 2 : internalChecked ? Appearance.rounding.small : Appearance.rounding.normal
+
+ // Match utilities Toggles inactive color
+ inactiveColour: Colours.layer(Colours.palette.m3surfaceContainerHighest, 2)
+
+ // Adjust width similar to utilities toggles
+ Layout.preferredWidth: implicitWidth + (stateLayer.pressed ? Appearance.padding.large : internalChecked ? Appearance.padding.smaller : 0)
+
+ onClicked: {
+ if (modelData.onToggled && root.rootItem && modelData.propertyName) {
+ const currentValue = root.rootItem[modelData.propertyName] ?? false;
+ modelData.onToggled(!currentValue);
+ }
+ }
+
+ Behavior on Layout.preferredWidth {
+ Anim {
+ duration: Appearance.anim.durations.expressiveFastSpatial
+ easing.bezierCurve: Appearance.anim.curves.expressiveFastSpatial
+ }
+ }
+
+ Behavior on radius {
+ Anim {
+ duration: Appearance.anim.durations.expressiveFastSpatial
+ easing.bezierCurve: Appearance.anim.curves.expressiveFastSpatial
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/modules/controlcenter/components/ReadonlySlider.qml b/modules/controlcenter/components/ReadonlySlider.qml
new file mode 100644
index 0000000..169d636
--- /dev/null
+++ b/modules/controlcenter/components/ReadonlySlider.qml
@@ -0,0 +1,67 @@
+import ".."
+import "../components"
+import qs.components
+import qs.components.controls
+import qs.services
+import qs.config
+import QtQuick
+import QtQuick.Layouts
+
+ColumnLayout {
+ id: root
+
+ property string label: ""
+ property real value: 0
+ property real from: 0
+ property real to: 100
+ property string suffix: ""
+ property bool readonly: false
+
+ spacing: Appearance.spacing.small
+
+ RowLayout {
+ Layout.fillWidth: true
+ spacing: Appearance.spacing.normal
+
+ StyledText {
+ visible: root.label !== ""
+ text: root.label
+ font.pointSize: Appearance.font.size.normal
+ color: root.readonly ? Colours.palette.m3outline : Colours.palette.m3onSurface
+ }
+
+ Item {
+ Layout.fillWidth: true
+ }
+
+ MaterialIcon {
+ visible: root.readonly
+ text: "lock"
+ color: Colours.palette.m3outline
+ font.pointSize: Appearance.font.size.small
+ }
+
+ StyledText {
+ text: Math.round(root.value) + (root.suffix !== "" ? " " + root.suffix : "")
+ font.pointSize: Appearance.font.size.normal
+ color: root.readonly ? Colours.palette.m3outline : Colours.palette.m3onSurface
+ }
+ }
+
+ StyledRect {
+ Layout.fillWidth: true
+ implicitHeight: Appearance.padding.normal
+ radius: Appearance.rounding.full
+ color: Colours.layer(Colours.palette.m3surfaceContainerHighest, 1)
+ opacity: root.readonly ? 0.5 : 1.0
+
+ StyledRect {
+ anchors.left: parent.left
+ anchors.top: parent.top
+ anchors.bottom: parent.bottom
+ width: parent.width * ((root.value - root.from) / (root.to - root.from))
+ radius: parent.radius
+ color: root.readonly ? Colours.palette.m3outline : Colours.palette.m3primary
+ }
+ }
+}