From 3f3f3a7d788ac555a94446731749e7b3aa9319c6 Mon Sep 17 00:00:00 2001 From: ATMDA Date: Mon, 17 Nov 2025 10:23:32 -0500 Subject: controlcenter: connected button group component --- .../controlcenter/taskbar/ConnectedButtonGroup.qml | 141 +++++++++++++++++++++ 1 file changed, 141 insertions(+) create mode 100644 modules/controlcenter/taskbar/ConnectedButtonGroup.qml (limited to 'modules/controlcenter/taskbar/ConnectedButtonGroup.qml') diff --git a/modules/controlcenter/taskbar/ConnectedButtonGroup.qml b/modules/controlcenter/taskbar/ConnectedButtonGroup.qml new file mode 100644 index 0000000..7999b70 --- /dev/null +++ b/modules/controlcenter/taskbar/ConnectedButtonGroup.qml @@ -0,0 +1,141 @@ +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 + + Layout.fillWidth: true + implicitHeight: buttonRow.implicitHeight + Appearance.padding.large * 2 + radius: Appearance.rounding.normal + color: Colours.layer(Colours.palette.m3surfaceContainer, 2) + clip: true + + Behavior on implicitHeight { + Anim {} + } + + RowLayout { + id: buttonRow + anchors.left: parent.left + anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter + anchors.margins: Appearance.padding.large + 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 isChecked: false + + // Initialize from root property + Component.onCompleted: { + if (root.rootItem && modelData.propertyName) { + isChecked = root.rootItem[modelData.propertyName]; + } + } + + checked: isChecked + toggle: false + type: TextButton.Tonal + + // Listen for property changes on rootItem + Connections { + target: root.rootItem + enabled: root.rootItem !== null && modelData.propertyName !== undefined + + function onShowAudioChanged() { + if (modelData.propertyName === "showAudio") { + button.isChecked = root.rootItem.showAudio; + } + } + + function onShowMicrophoneChanged() { + if (modelData.propertyName === "showMicrophone") { + button.isChecked = root.rootItem.showMicrophone; + } + } + + function onShowKbLayoutChanged() { + if (modelData.propertyName === "showKbLayout") { + button.isChecked = root.rootItem.showKbLayout; + } + } + + function onShowNetworkChanged() { + if (modelData.propertyName === "showNetwork") { + button.isChecked = root.rootItem.showNetwork; + } + } + + function onShowBluetoothChanged() { + if (modelData.propertyName === "showBluetooth") { + button.isChecked = root.rootItem.showBluetooth; + } + } + + function onShowBatteryChanged() { + if (modelData.propertyName === "showBattery") { + button.isChecked = root.rootItem.showBattery; + } + } + + function onShowLockStatusChanged() { + if (modelData.propertyName === "showLockStatus") { + button.isChecked = root.rootItem.showLockStatus; + } + } + } + + + // 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) { + modelData.onToggled(!checked); + } + } + + 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 + } + } + } + } + } +} + -- cgit v1.2.3-freya From 388cb0e373b1615b6d90028d74094c222fa48460 Mon Sep 17 00:00:00 2001 From: ATMDA Date: Mon, 17 Nov 2025 10:36:17 -0500 Subject: controlcenter: refined connected button groups --- .../controlcenter/taskbar/ConnectedButtonGroup.qml | 185 +++++++++++---------- modules/controlcenter/taskbar/TaskbarPane.qml | 134 +++++++-------- 2 files changed, 162 insertions(+), 157 deletions(-) (limited to 'modules/controlcenter/taskbar/ConnectedButtonGroup.qml') diff --git a/modules/controlcenter/taskbar/ConnectedButtonGroup.qml b/modules/controlcenter/taskbar/ConnectedButtonGroup.qml index 7999b70..83ff95e 100644 --- a/modules/controlcenter/taskbar/ConnectedButtonGroup.qml +++ b/modules/controlcenter/taskbar/ConnectedButtonGroup.qml @@ -12,9 +12,10 @@ StyledRect { 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: buttonRow.implicitHeight + Appearance.padding.large * 2 + implicitHeight: layout.implicitHeight + Appearance.padding.large * 2 radius: Appearance.rounding.normal color: Colours.layer(Colours.palette.m3surfaceContainer, 2) clip: true @@ -23,115 +24,125 @@ StyledRect { Anim {} } - RowLayout { - id: buttonRow - anchors.left: parent.left - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter + ColumnLayout { + id: layout + + anchors.fill: parent anchors.margins: Appearance.padding.large - 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 isChecked: false - - // Initialize from root property - Component.onCompleted: { - if (root.rootItem && modelData.propertyName) { - isChecked = root.rootItem[modelData.propertyName]; - } - } - - checked: isChecked - toggle: false - type: TextButton.Tonal - - // Listen for property changes on rootItem - Connections { - target: root.rootItem - enabled: root.rootItem !== null && modelData.propertyName !== undefined - - function onShowAudioChanged() { - if (modelData.propertyName === "showAudio") { - button.isChecked = root.rootItem.showAudio; + 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 isChecked: false + + // Initialize from root property + Component.onCompleted: { + if (root.rootItem && modelData.propertyName) { + isChecked = root.rootItem[modelData.propertyName]; } } + + checked: isChecked + toggle: false + type: TextButton.Tonal + + // Listen for property changes on rootItem + Connections { + target: root.rootItem + enabled: root.rootItem !== null && modelData.propertyName !== undefined + + function onShowAudioChanged() { + if (modelData.propertyName === "showAudio") { + button.isChecked = root.rootItem.showAudio; + } + } - function onShowMicrophoneChanged() { - if (modelData.propertyName === "showMicrophone") { - button.isChecked = root.rootItem.showMicrophone; + function onShowMicrophoneChanged() { + if (modelData.propertyName === "showMicrophone") { + button.isChecked = root.rootItem.showMicrophone; + } } - } - function onShowKbLayoutChanged() { - if (modelData.propertyName === "showKbLayout") { - button.isChecked = root.rootItem.showKbLayout; + function onShowKbLayoutChanged() { + if (modelData.propertyName === "showKbLayout") { + button.isChecked = root.rootItem.showKbLayout; + } } - } - function onShowNetworkChanged() { - if (modelData.propertyName === "showNetwork") { - button.isChecked = root.rootItem.showNetwork; + function onShowNetworkChanged() { + if (modelData.propertyName === "showNetwork") { + button.isChecked = root.rootItem.showNetwork; + } } - } - function onShowBluetoothChanged() { - if (modelData.propertyName === "showBluetooth") { - button.isChecked = root.rootItem.showBluetooth; + function onShowBluetoothChanged() { + if (modelData.propertyName === "showBluetooth") { + button.isChecked = root.rootItem.showBluetooth; + } } - } - function onShowBatteryChanged() { - if (modelData.propertyName === "showBattery") { - button.isChecked = root.rootItem.showBattery; + function onShowBatteryChanged() { + if (modelData.propertyName === "showBattery") { + button.isChecked = root.rootItem.showBattery; + } } - } - function onShowLockStatusChanged() { - if (modelData.propertyName === "showLockStatus") { - button.isChecked = root.rootItem.showLockStatus; + function onShowLockStatusChanged() { + if (modelData.propertyName === "showLockStatus") { + button.isChecked = root.rootItem.showLockStatus; + } } } - } + // 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 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) - // 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) { - modelData.onToggled(!checked); + onClicked: { + if (modelData.onToggled) { + modelData.onToggled(!checked); + } } - } - Behavior on Layout.preferredWidth { - Anim { - duration: Appearance.anim.durations.expressiveFastSpatial - easing.bezierCurve: Appearance.anim.curves.expressiveFastSpatial + 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 + Behavior on radius { + Anim { + duration: Appearance.anim.durations.expressiveFastSpatial + easing.bezierCurve: Appearance.anim.curves.expressiveFastSpatial + } } } } diff --git a/modules/controlcenter/taskbar/TaskbarPane.qml b/modules/controlcenter/taskbar/TaskbarPane.qml index d7cc664..0ec27e5 100644 --- a/modules/controlcenter/taskbar/TaskbarPane.qml +++ b/modules/controlcenter/taskbar/TaskbarPane.qml @@ -164,7 +164,6 @@ Item { readonly property bool allSectionsExpanded: clockSection.expanded && barBehaviorSection.expanded && - statusIconsSection.expanded && traySettingsSection.expanded && workspacesSection.expanded @@ -189,13 +188,76 @@ Item { const shouldExpand = !sidebarLayout.allSectionsExpanded; clockSection.expanded = shouldExpand; barBehaviorSection.expanded = shouldExpand; - statusIconsSection.expanded = shouldExpand; traySettingsSection.expanded = shouldExpand; workspacesSection.expanded = shouldExpand; } } } + ConnectedButtonGroup { + rootItem: root + title: qsTr("Status Icons") + + options: [ + { + label: qsTr("Audio"), + propertyName: "showAudio", + onToggled: function(checked) { + root.showAudio = checked; + root.saveConfig(); + } + }, + { + label: qsTr("Mic"), + propertyName: "showMicrophone", + onToggled: function(checked) { + root.showMicrophone = checked; + root.saveConfig(); + } + }, + { + label: qsTr("KB"), + propertyName: "showKbLayout", + onToggled: function(checked) { + root.showKbLayout = checked; + root.saveConfig(); + } + }, + { + label: qsTr("Network"), + propertyName: "showNetwork", + onToggled: function(checked) { + root.showNetwork = checked; + root.saveConfig(); + } + }, + { + label: qsTr("BT"), + propertyName: "showBluetooth", + onToggled: function(checked) { + root.showBluetooth = checked; + root.saveConfig(); + } + }, + { + label: qsTr("Battery"), + propertyName: "showBattery", + onToggled: function(checked) { + root.showBattery = checked; + root.saveConfig(); + } + }, + { + label: qsTr("Lock"), + propertyName: "showLockStatus", + onToggled: function(checked) { + root.showLockStatus = checked; + root.saveConfig(); + } + } + ] + } + CollapsibleSection { id: clockSection title: qsTr("Clock") @@ -332,74 +394,6 @@ Item { } } - CollapsibleSection { - id: statusIconsSection - title: qsTr("Status Icons") - - ConnectedButtonGroup { - rootItem: root - - options: [ - { - label: qsTr("Audio"), - propertyName: "showAudio", - onToggled: function(checked) { - root.showAudio = checked; - root.saveConfig(); - } - }, - { - label: qsTr("Mic"), - propertyName: "showMicrophone", - onToggled: function(checked) { - root.showMicrophone = checked; - root.saveConfig(); - } - }, - { - label: qsTr("KB"), - propertyName: "showKbLayout", - onToggled: function(checked) { - root.showKbLayout = checked; - root.saveConfig(); - } - }, - { - label: qsTr("Network"), - propertyName: "showNetwork", - onToggled: function(checked) { - root.showNetwork = checked; - root.saveConfig(); - } - }, - { - label: qsTr("BT"), - propertyName: "showBluetooth", - onToggled: function(checked) { - root.showBluetooth = checked; - root.saveConfig(); - } - }, - { - label: qsTr("Battery"), - propertyName: "showBattery", - onToggled: function(checked) { - root.showBattery = checked; - root.saveConfig(); - } - }, - { - label: qsTr("Lock"), - propertyName: "showLockStatus", - onToggled: function(checked) { - root.showLockStatus = checked; - root.saveConfig(); - } - } - ] - } - } - CollapsibleSection { id: traySettingsSection title: qsTr("Tray Settings") -- cgit v1.2.3-freya From 821ee4389ab2a81c5abba910936662d22e5f0480 Mon Sep 17 00:00:00 2001 From: ATMDA Date: Mon, 17 Nov 2025 12:21:44 -0500 Subject: controlcenter: taskbar panel layout reorg --- components/SectionContainer.qml | 4 +- .../controlcenter/taskbar/ConnectedButtonGroup.qml | 18 + modules/controlcenter/taskbar/TaskbarPane.qml | 578 +++++++++++---------- 3 files changed, 328 insertions(+), 272 deletions(-) (limited to 'modules/controlcenter/taskbar/ConnectedButtonGroup.qml') diff --git a/components/SectionContainer.qml b/components/SectionContainer.qml index f7dfef4..60e3d59 100644 --- a/components/SectionContainer.qml +++ b/components/SectionContainer.qml @@ -10,6 +10,7 @@ StyledRect { default property alias content: contentColumn.data property real contentSpacing: Appearance.spacing.larger + property bool alignTop: false Layout.fillWidth: true implicitHeight: contentColumn.implicitHeight + Appearance.padding.large * 2 @@ -22,7 +23,8 @@ StyledRect { anchors.left: parent.left anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter + anchors.top: root.alignTop ? parent.top : undefined + anchors.verticalCenter: root.alignTop ? undefined : parent.verticalCenter anchors.margins: Appearance.padding.large spacing: root.contentSpacing diff --git a/modules/controlcenter/taskbar/ConnectedButtonGroup.qml b/modules/controlcenter/taskbar/ConnectedButtonGroup.qml index 83ff95e..e35ccfc 100644 --- a/modules/controlcenter/taskbar/ConnectedButtonGroup.qml +++ b/modules/controlcenter/taskbar/ConnectedButtonGroup.qml @@ -113,6 +113,24 @@ StyledRect { button.isChecked = root.rootItem.showLockStatus; } } + + function onTrayBackgroundChanged() { + if (modelData.propertyName === "trayBackground") { + button.isChecked = root.rootItem.trayBackground; + } + } + + function onTrayCompactChanged() { + if (modelData.propertyName === "trayCompact") { + button.isChecked = root.rootItem.trayCompact; + } + } + + function onTrayRecolourChanged() { + if (modelData.propertyName === "trayRecolour") { + button.isChecked = root.rootItem.trayRecolour; + } + } } // Match utilities Toggles radius styling diff --git a/modules/controlcenter/taskbar/TaskbarPane.qml b/modules/controlcenter/taskbar/TaskbarPane.qml index 915e611..3f14dd6 100644 --- a/modules/controlcenter/taskbar/TaskbarPane.qml +++ b/modules/controlcenter/taskbar/TaskbarPane.qml @@ -161,11 +161,7 @@ Item { spacing: Appearance.spacing.small - readonly property bool allSectionsExpanded: - clockSection.expanded && - barBehaviorSection.expanded && - traySettingsSection.expanded && - workspacesSection.expanded + readonly property bool allSectionsExpanded: true RowLayout { spacing: Appearance.spacing.smaller @@ -185,11 +181,7 @@ Item { type: IconButton.Text label.animate: true onClicked: { - const shouldExpand = !sidebarLayout.allSectionsExpanded; - clockSection.expanded = shouldExpand; - barBehaviorSection.expanded = shouldExpand; - traySettingsSection.expanded = shouldExpand; - workspacesSection.expanded = shouldExpand; + // No collapsible sections remaining } } } @@ -258,345 +250,389 @@ Item { ] } - CollapsibleSection { - id: clockSection - title: qsTr("Clock") - - SwitchRow { - label: qsTr("Show clock icon") - checked: root.clockShowIcon - onToggled: checked => { - root.clockShowIcon = checked; - root.saveConfig(); - } - } - } - - CollapsibleSection { - id: barBehaviorSection - title: qsTr("Bar Behavior") + RowLayout { + Layout.fillWidth: true + spacing: Appearance.spacing.small - SwitchRow { - label: qsTr("Persistent") - checked: root.persistent - onToggled: checked => { - root.persistent = checked; - root.saveConfig(); - } - } + ColumnLayout { + Layout.fillWidth: true + Layout.alignment: Qt.AlignTop + spacing: 0 - SwitchRow { - label: qsTr("Show on hover") - checked: root.showOnHover - onToggled: checked => { - root.showOnHover = checked; - root.saveConfig(); - } - } + SectionContainer { + Layout.fillWidth: true + alignTop: true - SectionContainer { - contentSpacing: Appearance.spacing.normal + StyledText { + text: qsTr("Workspaces") + font.pointSize: Appearance.font.size.normal + } - ColumnLayout { + StyledRect { Layout.fillWidth: true - spacing: Appearance.spacing.small + implicitHeight: workspacesShownRow.implicitHeight + Appearance.padding.large * 2 + radius: Appearance.rounding.normal + color: Colours.layer(Colours.palette.m3surfaceContainer, 2) + + Behavior on implicitHeight { + Anim {} + } RowLayout { - Layout.fillWidth: true + id: workspacesShownRow + anchors.left: parent.left + anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter + anchors.margins: Appearance.padding.large spacing: Appearance.spacing.normal StyledText { - text: qsTr("Drag threshold") - font.pointSize: Appearance.font.size.normal - } - - Item { Layout.fillWidth: true + text: qsTr("Shown") } - StyledRect { - Layout.preferredWidth: 70 - implicitHeight: dragThresholdInput.implicitHeight + Appearance.padding.small * 2 - color: dragThresholdInputHover.containsMouse || dragThresholdInput.activeFocus - ? Colours.layer(Colours.palette.m3surfaceContainer, 3) - : Colours.layer(Colours.palette.m3surfaceContainer, 2) - radius: Appearance.rounding.small - border.width: 1 - border.color: dragThresholdInput.activeFocus - ? Colours.palette.m3primary - : Qt.alpha(Colours.palette.m3outline, 0.3) - - Behavior on color { CAnim {} } - Behavior on border.color { CAnim {} } - - MouseArea { - id: dragThresholdInputHover - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.IBeamCursor - acceptedButtons: Qt.NoButton - } - - StyledTextField { - id: dragThresholdInput - anchors.centerIn: parent - width: parent.width - Appearance.padding.normal - horizontalAlignment: TextInput.AlignHCenter - validator: IntValidator { bottom: 0; top: 100 } - - Component.onCompleted: { - text = root.dragThreshold.toString(); - } - - onTextChanged: { - if (activeFocus) { - const val = parseInt(text); - if (!isNaN(val) && val >= 0 && val <= 100) { - root.dragThreshold = val; - root.saveConfig(); - } - } - } - onEditingFinished: { - const val = parseInt(text); - if (isNaN(val) || val < 0 || val > 100) { - text = root.dragThreshold.toString(); - } - } + CustomSpinBox { + min: 1 + max: 20 + value: root.workspacesShown + onValueModified: value => { + root.workspacesShown = value; + root.saveConfig(); } } + } + } - StyledText { - text: "px" - color: Colours.palette.m3outline - font.pointSize: Appearance.font.size.normal - } + StyledRect { + Layout.fillWidth: true + implicitHeight: workspacesActiveIndicatorRow.implicitHeight + Appearance.padding.large * 2 + radius: Appearance.rounding.normal + color: Colours.layer(Colours.palette.m3surfaceContainer, 2) + + Behavior on implicitHeight { + Anim {} } - StyledSlider { - id: dragThresholdSlider + RowLayout { + id: workspacesActiveIndicatorRow + anchors.left: parent.left + anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter + anchors.margins: Appearance.padding.large + spacing: Appearance.spacing.normal - Layout.fillWidth: true - implicitHeight: Appearance.padding.normal * 3 + StyledText { + Layout.fillWidth: true + text: qsTr("Active indicator") + } - from: 0 - to: 100 - value: root.dragThreshold - onMoved: { - root.dragThreshold = Math.round(dragThresholdSlider.value); - if (!dragThresholdInput.activeFocus) { - dragThresholdInput.text = Math.round(dragThresholdSlider.value).toString(); + StyledSwitch { + checked: root.workspacesActiveIndicator + onToggled: { + root.workspacesActiveIndicator = checked; + root.saveConfig(); } - root.saveConfig(); } } } - } - } - CollapsibleSection { - id: traySettingsSection - title: qsTr("Tray Settings") - - SwitchRow { - label: qsTr("Background") - checked: root.trayBackground - onToggled: checked => { - root.trayBackground = checked; - root.saveConfig(); - } - } - - SwitchRow { - label: qsTr("Compact") - checked: root.trayCompact - onToggled: checked => { - root.trayCompact = checked; - root.saveConfig(); - } - } + StyledRect { + Layout.fillWidth: true + implicitHeight: workspacesOccupiedBgRow.implicitHeight + Appearance.padding.large * 2 + radius: Appearance.rounding.normal + color: Colours.layer(Colours.palette.m3surfaceContainer, 2) - SwitchRow { - label: qsTr("Recolour") - checked: root.trayRecolour - onToggled: checked => { - root.trayRecolour = checked; - root.saveConfig(); - } - } - } + Behavior on implicitHeight { + Anim {} + } - CollapsibleSection { - id: workspacesSection - title: qsTr("Workspaces") + RowLayout { + id: workspacesOccupiedBgRow + anchors.left: parent.left + anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter + anchors.margins: Appearance.padding.large + spacing: Appearance.spacing.normal - StyledRect { - Layout.fillWidth: true - implicitHeight: workspacesShownRow.implicitHeight + Appearance.padding.large * 2 - radius: Appearance.rounding.normal - color: Colours.tPalette.m3surfaceContainer + StyledText { + Layout.fillWidth: true + text: qsTr("Occupied background") + } - Behavior on implicitHeight { - Anim {} + StyledSwitch { + checked: root.workspacesOccupiedBg + onToggled: { + root.workspacesOccupiedBg = checked; + root.saveConfig(); + } + } + } } - RowLayout { - id: workspacesShownRow - anchors.left: parent.left - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - anchors.margins: Appearance.padding.large - spacing: Appearance.spacing.normal + StyledRect { + Layout.fillWidth: true + implicitHeight: workspacesShowWindowsRow.implicitHeight + Appearance.padding.large * 2 + radius: Appearance.rounding.normal + color: Colours.layer(Colours.palette.m3surfaceContainer, 2) - StyledText { - Layout.fillWidth: true - text: qsTr("Shown") + Behavior on implicitHeight { + Anim {} } - CustomSpinBox { - min: 1 - max: 20 - value: root.workspacesShown - onValueModified: value => { - root.workspacesShown = value; - root.saveConfig(); + RowLayout { + id: workspacesShowWindowsRow + anchors.left: parent.left + anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter + anchors.margins: Appearance.padding.large + spacing: Appearance.spacing.normal + + StyledText { + Layout.fillWidth: true + text: qsTr("Show windows") + } + + StyledSwitch { + checked: root.workspacesShowWindows + onToggled: { + root.workspacesShowWindows = checked; + root.saveConfig(); + } } } } - } - StyledRect { - Layout.fillWidth: true - implicitHeight: workspacesActiveIndicatorRow.implicitHeight + Appearance.padding.large * 2 - radius: Appearance.rounding.normal - color: Colours.tPalette.m3surfaceContainer + StyledRect { + Layout.fillWidth: true + implicitHeight: workspacesPerMonitorRow.implicitHeight + Appearance.padding.large * 2 + radius: Appearance.rounding.normal + color: Colours.layer(Colours.palette.m3surfaceContainer, 2) - Behavior on implicitHeight { - Anim {} - } + Behavior on implicitHeight { + Anim {} + } - RowLayout { - id: workspacesActiveIndicatorRow - anchors.left: parent.left - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - anchors.margins: Appearance.padding.large - spacing: Appearance.spacing.normal + RowLayout { + id: workspacesPerMonitorRow + anchors.left: parent.left + anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter + anchors.margins: Appearance.padding.large + spacing: Appearance.spacing.normal - StyledText { - Layout.fillWidth: true - text: qsTr("Active indicator") - } + StyledText { + Layout.fillWidth: true + text: qsTr("Per monitor workspaces") + } - StyledSwitch { - checked: root.workspacesActiveIndicator - onToggled: { - root.workspacesActiveIndicator = checked; - root.saveConfig(); + StyledSwitch { + checked: root.workspacesPerMonitor + onToggled: { + root.workspacesPerMonitor = checked; + root.saveConfig(); + } } } } + } } - StyledRect { + ColumnLayout { Layout.fillWidth: true - implicitHeight: workspacesOccupiedBgRow.implicitHeight + Appearance.padding.large * 2 - radius: Appearance.rounding.normal - color: Colours.tPalette.m3surfaceContainer - - Behavior on implicitHeight { - Anim {} - } + Layout.alignment: Qt.AlignTop + spacing: Appearance.spacing.small - RowLayout { - id: workspacesOccupiedBgRow - anchors.left: parent.left - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - anchors.margins: Appearance.padding.large - spacing: Appearance.spacing.normal + SectionContainer { + Layout.fillWidth: true + alignTop: true StyledText { - Layout.fillWidth: true - text: qsTr("Occupied background") + text: qsTr("Clock") + font.pointSize: Appearance.font.size.normal } - StyledSwitch { - checked: root.workspacesOccupiedBg - onToggled: { - root.workspacesOccupiedBg = checked; + SwitchRow { + label: qsTr("Show clock icon") + checked: root.clockShowIcon + onToggled: checked => { + root.clockShowIcon = checked; root.saveConfig(); } } } + + SectionContainer { + Layout.fillWidth: true + alignTop: true + + ConnectedButtonGroup { + rootItem: root + title: qsTr("Tray Settings") + + options: [ + { + label: qsTr("Background"), + propertyName: "trayBackground", + onToggled: function(checked) { + root.trayBackground = checked; + root.saveConfig(); + } + }, + { + label: qsTr("Compact"), + propertyName: "trayCompact", + onToggled: function(checked) { + root.trayCompact = checked; + root.saveConfig(); + } + }, + { + label: qsTr("Recolour"), + propertyName: "trayRecolour", + onToggled: function(checked) { + root.trayRecolour = checked; + root.saveConfig(); + } + } + ] + } + } } - StyledRect { + ColumnLayout { Layout.fillWidth: true - implicitHeight: workspacesShowWindowsRow.implicitHeight + Appearance.padding.large * 2 - radius: Appearance.rounding.normal - color: Colours.tPalette.m3surfaceContainer - - Behavior on implicitHeight { - Anim {} - } + Layout.alignment: Qt.AlignTop + spacing: 0 - RowLayout { - id: workspacesShowWindowsRow - anchors.left: parent.left - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - anchors.margins: Appearance.padding.large - spacing: Appearance.spacing.normal + SectionContainer { + Layout.fillWidth: true + alignTop: true StyledText { - Layout.fillWidth: true - text: qsTr("Show windows") + text: qsTr("Bar Behavior") + font.pointSize: Appearance.font.size.normal } - StyledSwitch { - checked: root.workspacesShowWindows - onToggled: { - root.workspacesShowWindows = checked; + SwitchRow { + label: qsTr("Persistent") + checked: root.persistent + onToggled: checked => { + root.persistent = checked; root.saveConfig(); } } - } - } - StyledRect { - Layout.fillWidth: true - implicitHeight: workspacesPerMonitorRow.implicitHeight + Appearance.padding.large * 2 - radius: Appearance.rounding.normal - color: Colours.tPalette.m3surfaceContainer + SwitchRow { + label: qsTr("Show on hover") + checked: root.showOnHover + onToggled: checked => { + root.showOnHover = checked; + root.saveConfig(); + } + } - Behavior on implicitHeight { - Anim {} - } + SectionContainer { + contentSpacing: Appearance.spacing.normal - RowLayout { - id: workspacesPerMonitorRow - anchors.left: parent.left - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - anchors.margins: Appearance.padding.large - spacing: Appearance.spacing.normal + ColumnLayout { + Layout.fillWidth: true + spacing: Appearance.spacing.small - StyledText { - Layout.fillWidth: true - text: qsTr("Per monitor workspaces") - } + RowLayout { + Layout.fillWidth: true + spacing: Appearance.spacing.normal - StyledSwitch { - checked: root.workspacesPerMonitor - onToggled: { - root.workspacesPerMonitor = checked; - root.saveConfig(); + StyledText { + text: qsTr("Drag threshold") + font.pointSize: Appearance.font.size.normal + } + + Item { + Layout.fillWidth: true + } + + StyledRect { + Layout.preferredWidth: 70 + implicitHeight: dragThresholdInput.implicitHeight + Appearance.padding.small * 2 + color: dragThresholdInputHover.containsMouse || dragThresholdInput.activeFocus + ? Colours.layer(Colours.palette.m3surfaceContainer, 3) + : Colours.layer(Colours.palette.m3surfaceContainer, 2) + radius: Appearance.rounding.small + border.width: 1 + border.color: dragThresholdInput.activeFocus + ? Colours.palette.m3primary + : Qt.alpha(Colours.palette.m3outline, 0.3) + + Behavior on color { CAnim {} } + Behavior on border.color { CAnim {} } + + MouseArea { + id: dragThresholdInputHover + anchors.fill: parent + hoverEnabled: true + cursorShape: Qt.IBeamCursor + acceptedButtons: Qt.NoButton + } + + StyledTextField { + id: dragThresholdInput + anchors.centerIn: parent + width: parent.width - Appearance.padding.normal + horizontalAlignment: TextInput.AlignHCenter + validator: IntValidator { bottom: 0; top: 100 } + + Component.onCompleted: { + text = root.dragThreshold.toString(); + } + + onTextChanged: { + if (activeFocus) { + const val = parseInt(text); + if (!isNaN(val) && val >= 0 && val <= 100) { + root.dragThreshold = val; + root.saveConfig(); + } + } + } + onEditingFinished: { + const val = parseInt(text); + if (isNaN(val) || val < 0 || val > 100) { + text = root.dragThreshold.toString(); + } + } + } + } + + StyledText { + text: "px" + color: Colours.palette.m3outline + font.pointSize: Appearance.font.size.normal + } + } + + StyledSlider { + id: dragThresholdSlider + + Layout.fillWidth: true + implicitHeight: Appearance.padding.normal * 3 + + from: 0 + to: 100 + value: root.dragThreshold + onMoved: { + root.dragThreshold = Math.round(dragThresholdSlider.value); + if (!dragThresholdInput.activeFocus) { + dragThresholdInput.text = Math.round(dragThresholdSlider.value).toString(); + } + root.saveConfig(); + } + } } } } } } + } } } -- cgit v1.2.3-freya From 7ac403d93304f122b051ad3c9ef794941648d1f5 Mon Sep 17 00:00:00 2001 From: ATMDA Date: Tue, 18 Nov 2025 12:10:41 -0500 Subject: controlcenter: added more missing options to taskbar panel --- .../controlcenter/taskbar/ConnectedButtonGroup.qml | 18 ++++ modules/controlcenter/taskbar/TaskbarPane.qml | 112 +++++++++++++++++++-- 2 files changed, 123 insertions(+), 7 deletions(-) (limited to 'modules/controlcenter/taskbar/ConnectedButtonGroup.qml') diff --git a/modules/controlcenter/taskbar/ConnectedButtonGroup.qml b/modules/controlcenter/taskbar/ConnectedButtonGroup.qml index e35ccfc..af386c3 100644 --- a/modules/controlcenter/taskbar/ConnectedButtonGroup.qml +++ b/modules/controlcenter/taskbar/ConnectedButtonGroup.qml @@ -131,6 +131,24 @@ StyledRect { button.isChecked = root.rootItem.trayRecolour; } } + + function onScrollWorkspacesChanged() { + if (modelData.propertyName === "scrollWorkspaces") { + button.isChecked = root.rootItem.scrollWorkspaces; + } + } + + function onScrollVolumeChanged() { + if (modelData.propertyName === "scrollVolume") { + button.isChecked = root.rootItem.scrollVolume; + } + } + + function onScrollBrightnessChanged() { + if (modelData.propertyName === "scrollBrightness") { + button.isChecked = root.rootItem.scrollBrightness; + } + } } // Match utilities Toggles radius styling diff --git a/modules/controlcenter/taskbar/TaskbarPane.qml b/modules/controlcenter/taskbar/TaskbarPane.qml index 18d5304..e84e5fe 100644 --- a/modules/controlcenter/taskbar/TaskbarPane.qml +++ b/modules/controlcenter/taskbar/TaskbarPane.qml @@ -47,6 +47,16 @@ Item { property bool workspacesShowWindows: Config.bar.workspaces.showWindows ?? false property bool workspacesPerMonitor: Config.bar.workspaces.perMonitorWorkspaces ?? true + // Scroll Actions + property bool scrollWorkspaces: Config.bar.scrollActions.workspaces ?? true + property bool scrollVolume: Config.bar.scrollActions.volume ?? true + property bool scrollBrightness: Config.bar.scrollActions.brightness ?? true + + // Popouts + property bool popoutActiveWindow: Config.bar.popouts.activeWindow ?? true + property bool popoutTray: Config.bar.popouts.tray ?? true + property bool popoutStatusIcons: Config.bar.popouts.statusIcons ?? true + anchors.fill: parent Component.onCompleted: { @@ -93,6 +103,16 @@ Item { Config.bar.workspaces.showWindows = root.workspacesShowWindows; Config.bar.workspaces.perMonitorWorkspaces = root.workspacesPerMonitor; + // Update scroll actions + Config.bar.scrollActions.workspaces = root.scrollWorkspaces; + Config.bar.scrollActions.volume = root.scrollVolume; + Config.bar.scrollActions.brightness = root.scrollBrightness; + + // Update popouts + Config.bar.popouts.activeWindow = root.popoutActiveWindow; + Config.bar.popouts.tray = root.popoutTray; + Config.bar.popouts.statusIcons = root.popoutStatusIcons; + // Update entries from the model (same approach as clock - use provided value if available) const entries = []; for (let i = 0; i < entriesModel.count; i++) { @@ -257,7 +277,7 @@ Item { ColumnLayout { Layout.fillWidth: true Layout.alignment: Qt.AlignTop - spacing: Appearance.spacing.small + spacing: Appearance.spacing.normal SectionContainer { Layout.fillWidth: true @@ -435,6 +455,47 @@ Item { } } } + + SectionContainer { + Layout.fillWidth: true + alignTop: true + + StyledText { + text: qsTr("Scroll Actions") + font.pointSize: Appearance.font.size.normal + } + + ConnectedButtonGroup { + rootItem: root + + options: [ + { + label: qsTr("Workspaces"), + propertyName: "scrollWorkspaces", + onToggled: function(checked) { + root.scrollWorkspaces = checked; + root.saveConfig(); + } + }, + { + label: qsTr("Volume"), + propertyName: "scrollVolume", + onToggled: function(checked) { + root.scrollVolume = checked; + root.saveConfig(); + } + }, + { + label: qsTr("Brightness"), + propertyName: "scrollBrightness", + onToggled: function(checked) { + root.scrollBrightness = checked; + root.saveConfig(); + } + } + ] + } + } } ColumnLayout { @@ -501,12 +562,6 @@ Item { ] } } - } - - ColumnLayout { - Layout.fillWidth: true - Layout.alignment: Qt.AlignTop - spacing: Appearance.spacing.small SectionContainer { Layout.fillWidth: true @@ -635,6 +690,49 @@ Item { } } } + + ColumnLayout { + Layout.fillWidth: true + Layout.alignment: Qt.AlignTop + spacing: Appearance.spacing.normal + + SectionContainer { + Layout.fillWidth: true + alignTop: true + + StyledText { + text: qsTr("Popouts") + font.pointSize: Appearance.font.size.normal + } + + SwitchRow { + label: qsTr("Active window") + checked: root.popoutActiveWindow + onToggled: checked => { + root.popoutActiveWindow = checked; + root.saveConfig(); + } + } + + SwitchRow { + label: qsTr("Tray") + checked: root.popoutTray + onToggled: checked => { + root.popoutTray = checked; + root.saveConfig(); + } + } + + SwitchRow { + label: qsTr("Status icons") + checked: root.popoutStatusIcons + onToggled: checked => { + root.popoutStatusIcons = checked; + root.saveConfig(); + } + } + } + } } } -- cgit v1.2.3-freya From 324b32c0c2ea1df2229dc341f3d120733a9320ae Mon Sep 17 00:00:00 2001 From: ATMDA Date: Wed, 19 Nov 2025 22:34:06 -0500 Subject: refactor: update ConnectedButtonGroup --- .../controlcenter/taskbar/ConnectedButtonGroup.qml | 105 +++------------------ 1 file changed, 13 insertions(+), 92 deletions(-) (limited to 'modules/controlcenter/taskbar/ConnectedButtonGroup.qml') diff --git a/modules/controlcenter/taskbar/ConnectedButtonGroup.qml b/modules/controlcenter/taskbar/ConnectedButtonGroup.qml index af386c3..bf3a97f 100644 --- a/modules/controlcenter/taskbar/ConnectedButtonGroup.qml +++ b/modules/controlcenter/taskbar/ConnectedButtonGroup.qml @@ -54,100 +54,20 @@ StyledRect { Layout.fillWidth: true text: modelData.label - property bool isChecked: false + property bool _checked: false - // Initialize from root property - Component.onCompleted: { - if (root.rootItem && modelData.propertyName) { - isChecked = root.rootItem[modelData.propertyName]; - } - } - - checked: isChecked + checked: _checked toggle: false type: TextButton.Tonal - // Listen for property changes on rootItem - Connections { - target: root.rootItem - enabled: root.rootItem !== null && modelData.propertyName !== undefined - - function onShowAudioChanged() { - if (modelData.propertyName === "showAudio") { - button.isChecked = root.rootItem.showAudio; - } - } - - function onShowMicrophoneChanged() { - if (modelData.propertyName === "showMicrophone") { - button.isChecked = root.rootItem.showMicrophone; - } - } - - function onShowKbLayoutChanged() { - if (modelData.propertyName === "showKbLayout") { - button.isChecked = root.rootItem.showKbLayout; - } - } - - function onShowNetworkChanged() { - if (modelData.propertyName === "showNetwork") { - button.isChecked = root.rootItem.showNetwork; - } - } - - function onShowBluetoothChanged() { - if (modelData.propertyName === "showBluetooth") { - button.isChecked = root.rootItem.showBluetooth; - } - } - - function onShowBatteryChanged() { - if (modelData.propertyName === "showBattery") { - button.isChecked = root.rootItem.showBattery; - } - } - - function onShowLockStatusChanged() { - if (modelData.propertyName === "showLockStatus") { - button.isChecked = root.rootItem.showLockStatus; - } - } - - function onTrayBackgroundChanged() { - if (modelData.propertyName === "trayBackground") { - button.isChecked = root.rootItem.trayBackground; - } - } - - function onTrayCompactChanged() { - if (modelData.propertyName === "trayCompact") { - button.isChecked = root.rootItem.trayCompact; - } - } - - function onTrayRecolourChanged() { - if (modelData.propertyName === "trayRecolour") { - button.isChecked = root.rootItem.trayRecolour; - } - } - - function onScrollWorkspacesChanged() { - if (modelData.propertyName === "scrollWorkspaces") { - button.isChecked = root.rootItem.scrollWorkspaces; - } - } - - function onScrollVolumeChanged() { - if (modelData.propertyName === "scrollVolume") { - button.isChecked = root.rootItem.scrollVolume; - } - } - - function onScrollBrightnessChanged() { - if (modelData.propertyName === "scrollBrightness") { - button.isChecked = root.rootItem.scrollBrightness; - } + // 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; + }); } } @@ -162,8 +82,9 @@ StyledRect { Layout.preferredWidth: implicitWidth + (stateLayer.pressed ? Appearance.padding.large : internalChecked ? Appearance.padding.smaller : 0) onClicked: { - if (modelData.onToggled) { - modelData.onToggled(!checked); + if (modelData.onToggled && root.rootItem && modelData.propertyName) { + const currentValue = root.rootItem[modelData.propertyName] ?? false; + modelData.onToggled(!currentValue); } } -- cgit v1.2.3-freya