nosignal-shell/modules/controlcenter/components/ConnectedButtonGroup.qml
Bora Gülerman aea2ac96ef
controlcenter/taskbar: add excludedScreens (#1215)
also changed controlcenter/components/ConnectedButtonGroup
  - Changed row layout to grid layout
  - Added optional prop: row, which defaults to 1 so it looks same as
row layout if not given
  - added new field to options, which bypasses rootItem bind. This is
needed because we can not predict the number of monitors the user has,
and can not create a seperate variable for each one
2026-03-15 18:42:34 +11:00

115 lines
4.2 KiB
QML

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, state: bool?}
property var rootItem: null // The root item that contains the properties we want to bind to
property string title: "" // Optional title text
property int rows: 1 // Number of rows
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
}
GridLayout {
id: buttonGrid
Layout.alignment: Qt.AlignHCenter
rowSpacing: Appearance.spacing.small
columnSpacing: Appearance.spacing.small
rows: root.rows
columns: Math.ceil(root.options.length / root.rows)
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 (modelData.state !== undefined && modelData.state) {
_checked = modelData.state;
}
else 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
}
}
}
}
}
}
}