diff options
Diffstat (limited to 'modules/controlcenter')
37 files changed, 0 insertions, 5882 deletions
diff --git a/modules/controlcenter/ControlCenter.qml b/modules/controlcenter/ControlCenter.qml deleted file mode 100644 index 4aacfad..0000000 --- a/modules/controlcenter/ControlCenter.qml +++ /dev/null @@ -1,100 +0,0 @@ -pragma ComponentBehavior: Bound - -import qs.components -import qs.components.controls -import qs.services -import qs.config -import Quickshell -import QtQuick -import QtQuick.Layouts - -Item { - id: root - - required property ShellScreen screen - readonly property int rounding: floating ? 0 : Appearance.rounding.normal - - property alias floating: session.floating - property alias active: session.active - property alias navExpanded: session.navExpanded - - readonly property Session session: Session { - id: session - - root: root - } - - function close(): void { - } - - implicitWidth: implicitHeight * Config.controlCenter.sizes.ratio - implicitHeight: screen.height * Config.controlCenter.sizes.heightMult - - GridLayout { - anchors.fill: parent - - rowSpacing: 0 - columnSpacing: 0 - rows: root.floating ? 2 : 1 - columns: 2 - - Loader { - Layout.fillWidth: true - Layout.columnSpan: 2 - - active: root.floating - visible: active - - sourceComponent: WindowTitle { - screen: root.screen - session: root.session - } - } - - StyledRect { - Layout.fillHeight: true - - topLeftRadius: root.rounding - bottomLeftRadius: root.rounding - implicitWidth: navRail.implicitWidth - color: Colours.tPalette.m3surfaceContainer - - CustomMouseArea { - anchors.fill: parent - - function onWheel(event: WheelEvent): void { - // Prevent tab switching during initial opening animation to avoid blank pages - if (!panes.initialOpeningComplete) { - return; - } - - if (event.angleDelta.y < 0) - root.session.activeIndex = Math.min(root.session.activeIndex + 1, root.session.panes.length - 1); - else if (event.angleDelta.y > 0) - root.session.activeIndex = Math.max(root.session.activeIndex - 1, 0); - } - } - - NavRail { - id: navRail - - screen: root.screen - session: root.session - initialOpeningComplete: root.initialOpeningComplete - } - } - - Panes { - id: panes - - Layout.fillWidth: true - Layout.fillHeight: true - - topRightRadius: root.rounding - bottomRightRadius: root.rounding - session: root.session - } - } - - readonly property bool initialOpeningComplete: panes.initialOpeningComplete -} diff --git a/modules/controlcenter/NavRail.qml b/modules/controlcenter/NavRail.qml deleted file mode 100644 index e61a741..0000000 --- a/modules/controlcenter/NavRail.qml +++ /dev/null @@ -1,231 +0,0 @@ -pragma ComponentBehavior: Bound - -import qs.components -import qs.services -import qs.config -import qs.modules.controlcenter -import Quickshell -import QtQuick -import QtQuick.Layouts - -Item { - id: root - - required property ShellScreen screen - required property Session session - required property bool initialOpeningComplete - - implicitWidth: layout.implicitWidth + Appearance.padding.larger * 4 - implicitHeight: layout.implicitHeight + Appearance.padding.large * 2 - - ColumnLayout { - id: layout - - anchors.left: parent.left - anchors.verticalCenter: parent.verticalCenter - anchors.leftMargin: Appearance.padding.larger * 2 - spacing: Appearance.spacing.normal - - states: State { - name: "expanded" - when: root.session.navExpanded - - PropertyChanges { - layout.spacing: Appearance.spacing.small - } - } - - transitions: Transition { - Anim { - properties: "spacing" - } - } - - Loader { - Layout.topMargin: Appearance.spacing.large - active: !root.session.floating - visible: active - - sourceComponent: StyledRect { - readonly property int nonAnimWidth: normalWinIcon.implicitWidth + (root.session.navExpanded ? normalWinLabel.anchors.leftMargin + normalWinLabel.implicitWidth : 0) + normalWinIcon.anchors.leftMargin * 2 - - implicitWidth: nonAnimWidth - implicitHeight: root.session.navExpanded ? normalWinIcon.implicitHeight + Appearance.padding.normal * 2 : nonAnimWidth - - color: Colours.palette.m3primaryContainer - radius: Appearance.rounding.small - - StateLayer { - id: normalWinState - - color: Colours.palette.m3onPrimaryContainer - - function onClicked(): void { - root.session.root.close(); - WindowFactory.create(null, { - active: root.session.active, - navExpanded: root.session.navExpanded - }); - } - } - - MaterialIcon { - id: normalWinIcon - - anchors.left: parent.left - anchors.verticalCenter: parent.verticalCenter - anchors.leftMargin: Appearance.padding.large - - text: "select_window" - color: Colours.palette.m3onPrimaryContainer - font.pointSize: Appearance.font.size.large - fill: 1 - } - - StyledText { - id: normalWinLabel - - anchors.left: normalWinIcon.right - anchors.verticalCenter: parent.verticalCenter - anchors.leftMargin: Appearance.spacing.normal - - text: qsTr("Float window") - color: Colours.palette.m3onPrimaryContainer - opacity: root.session.navExpanded ? 1 : 0 - - Behavior on opacity { - Anim { - duration: Appearance.anim.durations.small - } - } - } - - Behavior on implicitWidth { - Anim { - duration: Appearance.anim.durations.expressiveDefaultSpatial - easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial - } - } - - Behavior on implicitHeight { - Anim { - duration: Appearance.anim.durations.expressiveDefaultSpatial - easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial - } - } - } - } - - Repeater { - model: PaneRegistry.count - - NavItem { - required property int index - Layout.topMargin: index === 0 ? Appearance.spacing.large * 2 : 0 - icon: PaneRegistry.getByIndex(index).icon - label: PaneRegistry.getByIndex(index).label - } - } - } - - component NavItem: Item { - id: item - - required property string icon - required property string label - readonly property bool active: root.session.active === label - - implicitWidth: background.implicitWidth - implicitHeight: background.implicitHeight + smallLabel.implicitHeight + smallLabel.anchors.topMargin - - states: State { - name: "expanded" - when: root.session.navExpanded - - PropertyChanges { - expandedLabel.opacity: 1 - smallLabel.opacity: 0 - background.implicitWidth: icon.implicitWidth + icon.anchors.leftMargin * 2 + expandedLabel.anchors.leftMargin + expandedLabel.implicitWidth - background.implicitHeight: icon.implicitHeight + Appearance.padding.normal * 2 - item.implicitHeight: background.implicitHeight - } - } - - transitions: Transition { - Anim { - property: "opacity" - duration: Appearance.anim.durations.small - } - - Anim { - properties: "implicitWidth,implicitHeight" - duration: Appearance.anim.durations.expressiveDefaultSpatial - easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial - } - } - - StyledRect { - id: background - - radius: Appearance.rounding.full - color: Qt.alpha(Colours.palette.m3secondaryContainer, item.active ? 1 : 0) - - implicitWidth: icon.implicitWidth + icon.anchors.leftMargin * 2 - implicitHeight: icon.implicitHeight + Appearance.padding.small - - StateLayer { - color: item.active ? Colours.palette.m3onSecondaryContainer : Colours.palette.m3onSurface - - function onClicked(): void { - // Prevent tab switching during initial opening animation to avoid blank pages - if (!root.initialOpeningComplete) { - return; - } - root.session.active = item.label; - } - } - - MaterialIcon { - id: icon - - anchors.left: parent.left - anchors.verticalCenter: parent.verticalCenter - anchors.leftMargin: Appearance.padding.large - - text: item.icon - color: item.active ? Colours.palette.m3onSecondaryContainer : Colours.palette.m3onSurface - font.pointSize: Appearance.font.size.large - fill: item.active ? 1 : 0 - - Behavior on fill { - Anim {} - } - } - - StyledText { - id: expandedLabel - - anchors.left: icon.right - anchors.verticalCenter: parent.verticalCenter - anchors.leftMargin: Appearance.spacing.normal - - opacity: 0 - text: item.label - color: item.active ? Colours.palette.m3onSecondaryContainer : Colours.palette.m3onSurface - font.capitalization: Font.Capitalize - } - - StyledText { - id: smallLabel - - anchors.horizontalCenter: icon.horizontalCenter - anchors.top: icon.bottom - anchors.topMargin: Appearance.spacing.small / 2 - - text: item.label - font.pointSize: Appearance.font.size.small - font.capitalization: Font.Capitalize - } - } - } -} diff --git a/modules/controlcenter/PaneRegistry.qml b/modules/controlcenter/PaneRegistry.qml deleted file mode 100644 index 20719ca..0000000 --- a/modules/controlcenter/PaneRegistry.qml +++ /dev/null @@ -1,68 +0,0 @@ -pragma Singleton - -import QtQuick - -QtObject { - id: root - - readonly property list<QtObject> panes: [ - QtObject { - readonly property string id: "network" - readonly property string label: "network" - readonly property string icon: "router" - readonly property string component: "network/NetworkingPane.qml" - }, - QtObject { - readonly property string id: "bluetooth" - readonly property string label: "bluetooth" - readonly property string icon: "settings_bluetooth" - readonly property string component: "bluetooth/BtPane.qml" - }, - QtObject { - readonly property string id: "audio" - readonly property string label: "audio" - readonly property string icon: "volume_up" - readonly property string component: "audio/AudioPane.qml" - }, - ] - - readonly property int count: panes.length - - readonly property var labels: { - const result = []; - for (let i = 0; i < panes.length; i++) { - result.push(panes[i].label); - } - return result; - } - - function getByIndex(index: int): QtObject { - if (index >= 0 && index < panes.length) { - return panes[index]; - } - return null; - } - - function getIndexByLabel(label: string): int { - for (let i = 0; i < panes.length; i++) { - if (panes[i].label === label) { - return i; - } - } - return -1; - } - - function getByLabel(label: string): QtObject { - const index = getIndexByLabel(label); - return getByIndex(index); - } - - function getById(id: string): QtObject { - for (let i = 0; i < panes.length; i++) { - if (panes[i].id === id) { - return panes[i]; - } - } - return null; - } -} diff --git a/modules/controlcenter/Panes.qml b/modules/controlcenter/Panes.qml deleted file mode 100644 index 4794c03..0000000 --- a/modules/controlcenter/Panes.qml +++ /dev/null @@ -1,171 +0,0 @@ -pragma ComponentBehavior: Bound - -import "bluetooth" -import "network" -import "audio" -import qs.components -import qs.services -import qs.config -import qs.modules.controlcenter -import Quickshell.Widgets -import QtQuick -import QtQuick.Layouts - -ClippingRectangle { - id: root - - required property Session session - - readonly property bool initialOpeningComplete: layout.initialOpeningComplete - - color: "transparent" - clip: true - focus: false - activeFocusOnTab: false - - MouseArea { - anchors.fill: parent - z: -1 - onPressed: function (mouse) { - root.focus = true; - mouse.accepted = false; - } - } - - Connections { - target: root.session - - function onActiveIndexChanged(): void { - root.focus = true; - } - } - - ColumnLayout { - id: layout - - spacing: 0 - y: -root.session.activeIndex * root.height - clip: true - - property bool animationComplete: true - property bool initialOpeningComplete: false - - Timer { - id: animationDelayTimer - interval: Appearance.anim.durations.normal - onTriggered: { - layout.animationComplete = true; - } - } - - Timer { - id: initialOpeningTimer - interval: Appearance.anim.durations.large - running: true - onTriggered: { - layout.initialOpeningComplete = true; - } - } - - Repeater { - model: PaneRegistry.count - - Pane { - required property int index - paneIndex: index - componentPath: PaneRegistry.getByIndex(index).component - } - } - - Behavior on y { - Anim {} - } - - Connections { - target: root.session - function onActiveIndexChanged(): void { - layout.animationComplete = false; - animationDelayTimer.restart(); - } - } - } - - component Pane: Item { - id: pane - - required property int paneIndex - required property string componentPath - - implicitWidth: root.width - implicitHeight: root.height - - property bool hasBeenLoaded: false - - function updateActive(): void { - const diff = Math.abs(root.session.activeIndex - pane.paneIndex); - const isActivePane = diff === 0; - let shouldBeActive = false; - - if (!layout.initialOpeningComplete) { - shouldBeActive = isActivePane; - } else { - if (diff <= 1) { - shouldBeActive = true; - } else if (pane.hasBeenLoaded) { - shouldBeActive = true; - } else { - shouldBeActive = layout.animationComplete; - } - } - - loader.active = shouldBeActive; - } - - Loader { - id: loader - - anchors.fill: parent - clip: false - active: false - - Component.onCompleted: { - Qt.callLater(pane.updateActive); - } - - onActiveChanged: { - if (active && !pane.hasBeenLoaded) { - pane.hasBeenLoaded = true; - } - - if (active && !item) { - loader.setSource(pane.componentPath, { - "session": root.session - }); - } - } - - onItemChanged: { - if (item) { - pane.hasBeenLoaded = true; - } - } - } - - Connections { - target: root.session - function onActiveIndexChanged(): void { - pane.updateActive(); - } - } - - Connections { - target: layout - function onInitialOpeningCompleteChanged(): void { - pane.updateActive(); - } - function onAnimationCompleteChanged(): void { - pane.updateActive(); - } - } - } -} diff --git a/modules/controlcenter/Session.qml b/modules/controlcenter/Session.qml deleted file mode 100644 index b7dd888..0000000 --- a/modules/controlcenter/Session.qml +++ /dev/null @@ -1,21 +0,0 @@ -import QtQuick -import "./state" -import qs.modules.controlcenter - -QtObject { - readonly property list<string> panes: PaneRegistry.labels - - required property var root - property bool floating: false - property string active: "network" - property int activeIndex: 0 - property bool navExpanded: false - - readonly property BluetoothState bt: BluetoothState {} - readonly property NetworkState network: NetworkState {} - readonly property EthernetState ethernet: EthernetState {} - - onActiveChanged: activeIndex = Math.max(0, panes.indexOf(active)) - onActiveIndexChanged: if (panes[activeIndex]) - active = panes[activeIndex] -} diff --git a/modules/controlcenter/WindowFactory.qml b/modules/controlcenter/WindowFactory.qml deleted file mode 100644 index abcf5df..0000000 --- a/modules/controlcenter/WindowFactory.qml +++ /dev/null @@ -1,62 +0,0 @@ -pragma Singleton - -import qs.components -import qs.services -import Quickshell -import QtQuick - -Singleton { - id: root - - function create(parent: Item, props: var): void { - controlCenter.createObject(parent ?? dummy, props); - } - - QtObject { - id: dummy - } - - Component { - id: controlCenter - - FloatingWindow { - id: win - - property alias active: cc.active - property alias navExpanded: cc.navExpanded - - color: Colours.tPalette.m3surface - - onVisibleChanged: { - if (!visible) - destroy(); - } - - implicitWidth: cc.implicitWidth - implicitHeight: cc.implicitHeight - - minimumSize.width: implicitWidth - minimumSize.height: implicitHeight - maximumSize.width: implicitWidth - maximumSize.height: implicitHeight - - title: qsTr("Caelestia Settings - %1").arg(cc.active.slice(0, 1).toUpperCase() + cc.active.slice(1)) - - ControlCenter { - id: cc - - anchors.fill: parent - screen: win.screen - floating: true - - function close(): void { - win.destroy(); - } - } - - Behavior on color { - CAnim {} - } - } - } -} diff --git a/modules/controlcenter/WindowTitle.qml b/modules/controlcenter/WindowTitle.qml deleted file mode 100644 index fb71608..0000000 --- a/modules/controlcenter/WindowTitle.qml +++ /dev/null @@ -1,51 +0,0 @@ -import qs.components -import qs.services -import qs.config -import Quickshell -import QtQuick - -StyledRect { - id: root - - required property ShellScreen screen - required property Session session - - implicitHeight: text.implicitHeight + Appearance.padding.normal - color: Colours.tPalette.m3surfaceContainer - - StyledText { - id: text - - anchors.horizontalCenter: parent.horizontalCenter - anchors.bottom: parent.bottom - - text: qsTr("Caelestia Settings - %1").arg(root.session.active) - font.capitalization: Font.Capitalize - font.pointSize: Appearance.font.size.larger - font.weight: 500 - } - - Item { - anchors.right: parent.right - anchors.top: parent.top - anchors.margins: Appearance.padding.normal - - implicitWidth: implicitHeight - implicitHeight: closeIcon.implicitHeight + Appearance.padding.small - - StateLayer { - radius: Appearance.rounding.full - - function onClicked(): void { - QsWindow.window.destroy(); - } - } - - MaterialIcon { - id: closeIcon - - anchors.centerIn: parent - text: "close" - } - } -} diff --git a/modules/controlcenter/audio/AudioPane.qml b/modules/controlcenter/audio/AudioPane.qml deleted file mode 100644 index 01d90be..0000000 --- a/modules/controlcenter/audio/AudioPane.qml +++ /dev/null @@ -1,621 +0,0 @@ -pragma ComponentBehavior: Bound - -import ".." -import "../components" -import qs.components -import qs.components.controls -import qs.components.effects -import qs.components.containers -import qs.services -import qs.config -import Quickshell.Widgets -import QtQuick -import QtQuick.Layouts - -Item { - id: root - - required property Session session - - anchors.fill: parent - - SplitPaneLayout { - anchors.fill: parent - - leftContent: Component { - - StyledFlickable { - id: leftAudioFlickable - flickableDirection: Flickable.VerticalFlick - contentHeight: leftContent.height - - StyledScrollBar.vertical: StyledScrollBar { - flickable: leftAudioFlickable - } - - ColumnLayout { - id: leftContent - - anchors.left: parent.left - anchors.right: parent.right - spacing: Appearance.spacing.normal - - RowLayout { - Layout.fillWidth: true - spacing: Appearance.spacing.smaller - - StyledText { - text: qsTr("Audio") - font.pointSize: Appearance.font.size.large - font.weight: 500 - } - - Item { - Layout.fillWidth: true - } - } - - CollapsibleSection { - id: outputDevicesSection - - Layout.fillWidth: true - title: qsTr("Output devices") - expanded: true - - ColumnLayout { - Layout.fillWidth: true - spacing: Appearance.spacing.small - - RowLayout { - Layout.fillWidth: true - spacing: Appearance.spacing.small - - StyledText { - text: qsTr("Devices (%1)").arg(Audio.sinks.length) - font.pointSize: Appearance.font.size.normal - font.weight: 500 - } - } - - StyledText { - Layout.fillWidth: true - text: qsTr("All available output devices") - color: Colours.palette.m3outline - } - - Repeater { - Layout.fillWidth: true - model: Audio.sinks - - delegate: StyledRect { - required property var modelData - - Layout.fillWidth: true - - color: Audio.sink?.id === modelData.id ? Colours.layer(Colours.palette.m3surfaceContainer, 2) : "transparent" - radius: Appearance.rounding.normal - - StateLayer { - function onClicked(): void { - Audio.setAudioSink(modelData); - } - } - - RowLayout { - id: outputRowLayout - - anchors.left: parent.left - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - anchors.margins: Appearance.padding.normal - - spacing: Appearance.spacing.normal - - MaterialIcon { - text: Audio.sink?.id === modelData.id ? "speaker" : "speaker_group" - font.pointSize: Appearance.font.size.large - fill: Audio.sink?.id === modelData.id ? 1 : 0 - } - - StyledText { - Layout.fillWidth: true - elide: Text.ElideRight - maximumLineCount: 1 - - text: modelData.description || qsTr("Unknown") - font.weight: Audio.sink?.id === modelData.id ? 500 : 400 - } - } - - implicitHeight: outputRowLayout.implicitHeight + Appearance.padding.normal * 2 - } - } - } - } - - CollapsibleSection { - id: inputDevicesSection - - Layout.fillWidth: true - title: qsTr("Input devices") - expanded: true - - ColumnLayout { - Layout.fillWidth: true - spacing: Appearance.spacing.small - - RowLayout { - Layout.fillWidth: true - spacing: Appearance.spacing.small - - StyledText { - text: qsTr("Devices (%1)").arg(Audio.sources.length) - font.pointSize: Appearance.font.size.normal - font.weight: 500 - } - } - - StyledText { - Layout.fillWidth: true - text: qsTr("All available input devices") - color: Colours.palette.m3outline - } - - Repeater { - Layout.fillWidth: true - model: Audio.sources - - delegate: StyledRect { - required property var modelData - - Layout.fillWidth: true - - color: Audio.source?.id === modelData.id ? Colours.layer(Colours.palette.m3surfaceContainer, 2) : "transparent" - radius: Appearance.rounding.normal - - StateLayer { - function onClicked(): void { - Audio.setAudioSource(modelData); - } - } - - RowLayout { - id: inputRowLayout - - anchors.left: parent.left - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - anchors.margins: Appearance.padding.normal - - spacing: Appearance.spacing.normal - - MaterialIcon { - text: "mic" - font.pointSize: Appearance.font.size.large - fill: Audio.source?.id === modelData.id ? 1 : 0 - } - - StyledText { - Layout.fillWidth: true - elide: Text.ElideRight - maximumLineCount: 1 - - text: modelData.description || qsTr("Unknown") - font.weight: Audio.source?.id === modelData.id ? 500 : 400 - } - } - - implicitHeight: inputRowLayout.implicitHeight + Appearance.padding.normal * 2 - } - } - } - } - } - } - } - - rightContent: Component { - StyledFlickable { - id: rightAudioFlickable - flickableDirection: Flickable.VerticalFlick - contentHeight: contentLayout.height - - StyledScrollBar.vertical: StyledScrollBar { - flickable: rightAudioFlickable - } - - ColumnLayout { - id: contentLayout - - anchors.left: parent.left - anchors.right: parent.right - anchors.top: parent.top - spacing: Appearance.spacing.normal - - SettingsHeader { - icon: "volume_up" - title: qsTr("Audio Settings") - } - - SectionHeader { - title: qsTr("Output volume") - description: qsTr("Control the volume of your output device") - } - - SectionContainer { - contentSpacing: Appearance.spacing.normal - - ColumnLayout { - Layout.fillWidth: true - spacing: Appearance.spacing.small - - RowLayout { - Layout.fillWidth: true - spacing: Appearance.spacing.normal - - StyledText { - text: qsTr("Volume") - font.pointSize: Appearance.font.size.normal - font.weight: 500 - } - - Item { - Layout.fillWidth: true - } - - StyledInputField { - id: outputVolumeInput - Layout.preferredWidth: 70 - validator: IntValidator { - bottom: 0 - top: 100 - } - enabled: !Audio.muted - - Component.onCompleted: { - text = Math.round(Audio.volume * 100).toString(); - } - - Connections { - target: Audio - function onVolumeChanged() { - if (!outputVolumeInput.hasFocus) { - outputVolumeInput.text = Math.round(Audio.volume * 100).toString(); - } - } - } - - onTextEdited: text => { - if (hasFocus) { - const val = parseInt(text); - if (!isNaN(val) && val >= 0 && val <= 100) { - Audio.setVolume(val / 100); - } - } - } - - onEditingFinished: { - const val = parseInt(text); - if (isNaN(val) || val < 0 || val > 100) { - text = Math.round(Audio.volume * 100).toString(); - } - } - } - - StyledText { - text: "%" - color: Colours.palette.m3outline - font.pointSize: Appearance.font.size.normal - opacity: Audio.muted ? 0.5 : 1 - } - - StyledRect { - implicitWidth: implicitHeight - implicitHeight: muteIcon.implicitHeight + Appearance.padding.normal * 2 - - radius: Appearance.rounding.normal - color: Audio.muted ? Colours.palette.m3secondary : Colours.palette.m3secondaryContainer - - StateLayer { - function onClicked(): void { - if (Audio.sink?.audio) { - Audio.sink.audio.muted = !Audio.sink.audio.muted; - } - } - } - - MaterialIcon { - id: muteIcon - - anchors.centerIn: parent - text: Audio.muted ? "volume_off" : "volume_up" - color: Audio.muted ? Colours.palette.m3onSecondary : Colours.palette.m3onSecondaryContainer - } - } - } - - StyledSlider { - id: outputVolumeSlider - Layout.fillWidth: true - implicitHeight: Appearance.padding.normal * 3 - - value: Audio.volume - enabled: !Audio.muted - opacity: enabled ? 1 : 0.5 - onMoved: { - Audio.setVolume(value); - if (!outputVolumeInput.hasFocus) { - outputVolumeInput.text = Math.round(value * 100).toString(); - } - } - } - } - } - - SectionHeader { - title: qsTr("Input volume") - description: qsTr("Control the volume of your input device") - } - - SectionContainer { - contentSpacing: Appearance.spacing.normal - - ColumnLayout { - Layout.fillWidth: true - spacing: Appearance.spacing.small - - RowLayout { - Layout.fillWidth: true - spacing: Appearance.spacing.normal - - StyledText { - text: qsTr("Volume") - font.pointSize: Appearance.font.size.normal - font.weight: 500 - } - - Item { - Layout.fillWidth: true - } - - StyledInputField { - id: inputVolumeInput - Layout.preferredWidth: 70 - validator: IntValidator { - bottom: 0 - top: 100 - } - enabled: !Audio.sourceMuted - - Component.onCompleted: { - text = Math.round(Audio.sourceVolume * 100).toString(); - } - - Connections { - target: Audio - function onSourceVolumeChanged() { - if (!inputVolumeInput.hasFocus) { - inputVolumeInput.text = Math.round(Audio.sourceVolume * 100).toString(); - } - } - } - - onTextEdited: text => { - if (hasFocus) { - const val = parseInt(text); - if (!isNaN(val) && val >= 0 && val <= 100) { - Audio.setSourceVolume(val / 100); - } - } - } - - onEditingFinished: { - const val = parseInt(text); - if (isNaN(val) || val < 0 || val > 100) { - text = Math.round(Audio.sourceVolume * 100).toString(); - } - } - } - - StyledText { - text: "%" - color: Colours.palette.m3outline - font.pointSize: Appearance.font.size.normal - opacity: Audio.sourceMuted ? 0.5 : 1 - } - - StyledRect { - implicitWidth: implicitHeight - implicitHeight: muteInputIcon.implicitHeight + Appearance.padding.normal * 2 - - radius: Appearance.rounding.normal - color: Audio.sourceMuted ? Colours.palette.m3secondary : Colours.palette.m3secondaryContainer - - StateLayer { - function onClicked(): void { - if (Audio.source?.audio) { - Audio.source.audio.muted = !Audio.source.audio.muted; - } - } - } - - MaterialIcon { - id: muteInputIcon - - anchors.centerIn: parent - text: "mic_off" - color: Audio.sourceMuted ? Colours.palette.m3onSecondary : Colours.palette.m3onSecondaryContainer - } - } - } - - StyledSlider { - id: inputVolumeSlider - Layout.fillWidth: true - implicitHeight: Appearance.padding.normal * 3 - - value: Audio.sourceVolume - enabled: !Audio.sourceMuted - opacity: enabled ? 1 : 0.5 - onMoved: { - Audio.setSourceVolume(value); - if (!inputVolumeInput.hasFocus) { - inputVolumeInput.text = Math.round(value * 100).toString(); - } - } - } - } - } - - SectionHeader { - title: qsTr("Applications") - description: qsTr("Control volume for individual applications") - } - - SectionContainer { - contentSpacing: Appearance.spacing.normal - - ColumnLayout { - Layout.fillWidth: true - spacing: Appearance.spacing.small - - Repeater { - model: Audio.streams - Layout.fillWidth: true - - delegate: ColumnLayout { - required property var modelData - required property int index - - Layout.fillWidth: true - spacing: Appearance.spacing.smaller - - RowLayout { - Layout.fillWidth: true - spacing: Appearance.spacing.normal - - MaterialIcon { - text: "apps" - font.pointSize: Appearance.font.size.normal - fill: 0 - } - - StyledText { - Layout.fillWidth: true - elide: Text.ElideRight - maximumLineCount: 1 - text: Audio.getStreamName(modelData) - font.pointSize: Appearance.font.size.normal - font.weight: 500 - } - - StyledInputField { - id: streamVolumeInput - Layout.preferredWidth: 70 - validator: IntValidator { - bottom: 0 - top: 100 - } - enabled: !Audio.getStreamMuted(modelData) - - Component.onCompleted: { - text = Math.round(Audio.getStreamVolume(modelData) * 100).toString(); - } - - Connections { - target: modelData - function onAudioChanged() { - if (!streamVolumeInput.hasFocus && modelData?.audio) { - streamVolumeInput.text = Math.round(modelData.audio.volume * 100).toString(); - } - } - } - - onTextEdited: text => { - if (hasFocus) { - const val = parseInt(text); - if (!isNaN(val) && val >= 0 && val <= 100) { - Audio.setStreamVolume(modelData, val / 100); - } - } - } - - onEditingFinished: { - const val = parseInt(text); - if (isNaN(val) || val < 0 || val > 100) { - text = Math.round(Audio.getStreamVolume(modelData) * 100).toString(); - } - } - } - - StyledText { - text: "%" - color: Colours.palette.m3outline - font.pointSize: Appearance.font.size.normal - opacity: Audio.getStreamMuted(modelData) ? 0.5 : 1 - } - - StyledRect { - implicitWidth: implicitHeight - implicitHeight: streamMuteIcon.implicitHeight + Appearance.padding.normal * 2 - - radius: Appearance.rounding.normal - color: Audio.getStreamMuted(modelData) ? Colours.palette.m3secondary : Colours.palette.m3secondaryContainer - - StateLayer { - function onClicked(): void { - Audio.setStreamMuted(modelData, !Audio.getStreamMuted(modelData)); - } - } - - MaterialIcon { - id: streamMuteIcon - - anchors.centerIn: parent - text: Audio.getStreamMuted(modelData) ? "volume_off" : "volume_up" - color: Audio.getStreamMuted(modelData) ? Colours.palette.m3onSecondary : Colours.palette.m3onSecondaryContainer - } - } - } - - StyledSlider { - Layout.fillWidth: true - implicitHeight: Appearance.padding.normal * 3 - - value: Audio.getStreamVolume(modelData) - enabled: !Audio.getStreamMuted(modelData) - opacity: enabled ? 1 : 0.5 - onMoved: { - Audio.setStreamVolume(modelData, value); - if (!streamVolumeInput.hasFocus) { - streamVolumeInput.text = Math.round(value * 100).toString(); - } - } - - Connections { - target: modelData - function onAudioChanged() { - if (modelData?.audio) { - value = modelData.audio.volume; - } - } - } - } - } - } - - StyledText { - Layout.fillWidth: true - visible: Audio.streams.length === 0 - text: qsTr("No applications currently playing audio") - color: Colours.palette.m3outline - font.pointSize: Appearance.font.size.small - horizontalAlignment: Text.AlignHCenter - } - } - } - } - } - } - } -} diff --git a/modules/controlcenter/bluetooth/BtPane.qml b/modules/controlcenter/bluetooth/BtPane.qml deleted file mode 100644 index 7d3b9ca..0000000 --- a/modules/controlcenter/bluetooth/BtPane.qml +++ /dev/null @@ -1,73 +0,0 @@ -pragma ComponentBehavior: Bound - -import ".." -import "../components" -import "." -import qs.components -import qs.components.controls -import qs.components.containers -import qs.config -import Quickshell.Widgets -import Quickshell.Bluetooth -import QtQuick - -SplitPaneWithDetails { - id: root - - required property Session session - - anchors.fill: parent - - activeItem: session.bt.active - paneIdGenerator: function (item) { - return item ? (item.address || "") : ""; - } - - leftContent: Component { - StyledFlickable { - id: leftFlickable - - flickableDirection: Flickable.VerticalFlick - contentHeight: deviceList.height - - StyledScrollBar.vertical: StyledScrollBar { - flickable: leftFlickable - } - - DeviceList { - id: deviceList - - anchors.left: parent.left - anchors.right: parent.right - session: root.session - } - } - } - - rightDetailsComponent: Component { - Details { - session: root.session - } - } - - rightSettingsComponent: Component { - StyledFlickable { - id: settingsFlickable - flickableDirection: Flickable.VerticalFlick - contentHeight: settingsInner.height - - StyledScrollBar.vertical: StyledScrollBar { - flickable: settingsFlickable - } - - Settings { - id: settingsInner - - anchors.left: parent.left - anchors.right: parent.right - anchors.top: parent.top - session: root.session - } - } - } -} diff --git a/modules/controlcenter/bluetooth/Details.qml b/modules/controlcenter/bluetooth/Details.qml deleted file mode 100644 index bc276e0..0000000 --- a/modules/controlcenter/bluetooth/Details.qml +++ /dev/null @@ -1,671 +0,0 @@ -pragma ComponentBehavior: Bound - -import ".." -import "../components" -import qs.components -import qs.components.controls -import qs.components.effects -import qs.components.containers -import qs.services -import qs.config -import qs.utils -import Quickshell.Bluetooth -import QtQuick -import QtQuick.Layouts - -StyledFlickable { - id: root - - required property Session session - readonly property BluetoothDevice device: session.bt.active - - flickableDirection: Flickable.VerticalFlick - contentHeight: detailsWrapper.height - - StyledScrollBar.vertical: StyledScrollBar { - flickable: root - } - - Item { - id: detailsWrapper - - anchors.left: parent.left - anchors.right: parent.right - anchors.top: parent.top - implicitHeight: details.implicitHeight - - DeviceDetails { - id: details - - anchors.left: parent.left - anchors.right: parent.right - anchors.top: parent.top - - session: root.session - device: root.device - - headerComponent: Component { - SettingsHeader { - icon: Icons.getBluetoothIcon(root.device?.icon ?? "") - title: root.device?.name ?? "" - } - } - - sections: [ - Component { - ColumnLayout { - spacing: Appearance.spacing.normal - - StyledText { - Layout.topMargin: Appearance.spacing.large - text: qsTr("Connection status") - font.pointSize: Appearance.font.size.larger - font.weight: 500 - } - - StyledText { - text: qsTr("Connection settings for this device") - color: Colours.palette.m3outline - } - - StyledRect { - Layout.fillWidth: true - implicitHeight: deviceStatus.implicitHeight + Appearance.padding.large * 2 - - radius: Appearance.rounding.normal - color: Colours.tPalette.m3surfaceContainer - - ColumnLayout { - id: deviceStatus - - anchors.left: parent.left - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - anchors.margins: Appearance.padding.large - - spacing: Appearance.spacing.larger - - Toggle { - label: qsTr("Connected") - checked: root.device?.connected ?? false - toggle.onToggled: root.device.connected = checked - } - - Toggle { - label: qsTr("Paired") - checked: root.device?.paired ?? false - toggle.onToggled: { - if (root.device.paired) - root.device.forget(); - else - root.device.pair(); - } - } - - Toggle { - label: qsTr("Blocked") - checked: root.device?.blocked ?? false - toggle.onToggled: root.device.blocked = checked - } - } - } - } - }, - Component { - ColumnLayout { - spacing: Appearance.spacing.normal - - StyledText { - Layout.topMargin: Appearance.spacing.large - text: qsTr("Device properties") - font.pointSize: Appearance.font.size.larger - font.weight: 500 - } - - StyledText { - text: qsTr("Additional settings") - color: Colours.palette.m3outline - } - - StyledRect { - Layout.fillWidth: true - implicitHeight: deviceProps.implicitHeight + Appearance.padding.large * 2 - - radius: Appearance.rounding.normal - color: Colours.tPalette.m3surfaceContainer - - ColumnLayout { - id: deviceProps - - anchors.left: parent.left - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - anchors.margins: Appearance.padding.large - - spacing: Appearance.spacing.larger - - RowLayout { - Layout.fillWidth: true - spacing: Appearance.spacing.small - - Item { - id: renameDevice - - Layout.fillWidth: true - Layout.rightMargin: Appearance.spacing.small - - implicitHeight: renameLabel.implicitHeight + deviceNameEdit.implicitHeight - - states: State { - name: "editingDeviceName" - when: root.session.bt.editingDeviceName - - AnchorChanges { - target: deviceNameEdit - anchors.top: renameDevice.top - } - PropertyChanges { - renameDevice.implicitHeight: deviceNameEdit.implicitHeight - renameLabel.opacity: 0 - deviceNameEdit.padding: Appearance.padding.normal - } - } - - transitions: Transition { - AnchorAnimation { - duration: Appearance.anim.durations.normal - easing.type: Easing.BezierSpline - easing.bezierCurve: Appearance.anim.curves.standard - } - Anim { - properties: "implicitHeight,opacity,padding" - } - } - - StyledText { - id: renameLabel - - anchors.left: parent.left - - text: qsTr("Device name") - color: Colours.palette.m3outline - font.pointSize: Appearance.font.size.small - } - - StyledTextField { - id: deviceNameEdit - - anchors.left: parent.left - anchors.right: parent.right - anchors.top: renameLabel.bottom - anchors.leftMargin: root.session.bt.editingDeviceName ? 0 : -Appearance.padding.normal - - text: root.device?.name ?? "" - readOnly: !root.session.bt.editingDeviceName - onAccepted: { - root.session.bt.editingDeviceName = false; - root.device.name = text; - } - - leftPadding: Appearance.padding.normal - rightPadding: Appearance.padding.normal - - background: StyledRect { - radius: Appearance.rounding.small - border.width: 2 - border.color: Colours.palette.m3primary - opacity: root.session.bt.editingDeviceName ? 1 : 0 - - Behavior on border.color { - CAnim {} - } - - Behavior on opacity { - Anim {} - } - } - - Behavior on anchors.leftMargin { - Anim {} - } - } - } - - StyledRect { - implicitWidth: implicitHeight - implicitHeight: cancelEditIcon.implicitHeight + Appearance.padding.smaller * 2 - - radius: Appearance.rounding.small - color: Colours.palette.m3secondaryContainer - opacity: root.session.bt.editingDeviceName ? 1 : 0 - scale: root.session.bt.editingDeviceName ? 1 : 0.5 - - StateLayer { - color: Colours.palette.m3onSecondaryContainer - disabled: !root.session.bt.editingDeviceName - - function onClicked(): void { - root.session.bt.editingDeviceName = false; - deviceNameEdit.text = Qt.binding(() => root.device?.name ?? ""); - } - } - - MaterialIcon { - id: cancelEditIcon - - anchors.centerIn: parent - animate: true - text: "cancel" - color: Colours.palette.m3onSecondaryContainer - } - - Behavior on opacity { - Anim {} - } - - Behavior on scale { - Anim { - duration: Appearance.anim.durations.expressiveFastSpatial - easing.bezierCurve: Appearance.anim.curves.expressiveFastSpatial - } - } - } - - StyledRect { - implicitWidth: implicitHeight - implicitHeight: editIcon.implicitHeight + Appearance.padding.smaller * 2 - - radius: root.session.bt.editingDeviceName ? Appearance.rounding.small : implicitHeight / 2 * Math.min(1, Appearance.rounding.scale) - color: Qt.alpha(Colours.palette.m3primary, root.session.bt.editingDeviceName ? 1 : 0) - - StateLayer { - color: root.session.bt.editingDeviceName ? Colours.palette.m3onPrimary : Colours.palette.m3onSurface - - function onClicked(): void { - root.session.bt.editingDeviceName = !root.session.bt.editingDeviceName; - if (root.session.bt.editingDeviceName) - deviceNameEdit.forceActiveFocus(); - else - deviceNameEdit.accepted(); - } - } - - MaterialIcon { - id: editIcon - - anchors.centerIn: parent - animate: true - text: root.session.bt.editingDeviceName ? "check_circle" : "edit" - color: root.session.bt.editingDeviceName ? Colours.palette.m3onPrimary : Colours.palette.m3onSurface - } - - Behavior on radius { - Anim {} - } - } - } - - Toggle { - label: qsTr("Trusted") - checked: root.device?.trusted ?? false - toggle.onToggled: root.device.trusted = checked - } - - Toggle { - label: qsTr("Wake allowed") - checked: root.device?.wakeAllowed ?? false - toggle.onToggled: root.device.wakeAllowed = checked - } - } - } - } - }, - Component { - ColumnLayout { - spacing: Appearance.spacing.normal - - StyledText { - Layout.topMargin: Appearance.spacing.large - text: qsTr("Device information") - font.pointSize: Appearance.font.size.larger - font.weight: 500 - } - - StyledText { - text: qsTr("Information about this device") - color: Colours.palette.m3outline - } - - StyledRect { - Layout.fillWidth: true - implicitHeight: deviceInfo.implicitHeight + Appearance.padding.large * 2 - - radius: Appearance.rounding.normal - color: Colours.tPalette.m3surfaceContainer - - ColumnLayout { - id: deviceInfo - - anchors.left: parent.left - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - anchors.margins: Appearance.padding.large - - spacing: Appearance.spacing.small / 2 - - StyledText { - text: root.device?.batteryAvailable ? qsTr("Device battery (%1%)").arg(root.device.battery * 100) : qsTr("Battery unavailable") - } - - RowLayout { - id: batteryPercent - Layout.topMargin: Appearance.spacing.small / 2 - Layout.fillWidth: true - Layout.preferredHeight: Appearance.padding.smaller - spacing: Appearance.spacing.small / 2 - - StyledRect { - Layout.fillWidth: true - Layout.fillHeight: true - radius: Appearance.rounding.full - color: Colours.palette.m3secondaryContainer - - StyledRect { - anchors.left: parent.left - anchors.top: parent.top - anchors.bottom: parent.bottom - anchors.margins: parent.height * 0.25 - - implicitWidth: root.device?.batteryAvailable ? batteryPercent.width * root.device.battery : 0 - radius: Appearance.rounding.full - color: Colours.palette.m3primary - } - } - } - - StyledText { - Layout.topMargin: Appearance.spacing.normal - text: qsTr("Dbus path") - } - - StyledText { - text: root.device?.dbusPath ?? "" - color: Colours.palette.m3outline - font.pointSize: Appearance.font.size.small - } - - StyledText { - Layout.topMargin: Appearance.spacing.normal - text: qsTr("MAC address") - } - - StyledText { - text: root.device?.address ?? "" - color: Colours.palette.m3outline - font.pointSize: Appearance.font.size.small - } - - StyledText { - Layout.topMargin: Appearance.spacing.normal - text: qsTr("Bonded") - } - - StyledText { - text: root.device?.bonded ? qsTr("Yes") : qsTr("No") - color: Colours.palette.m3outline - font.pointSize: Appearance.font.size.small - } - - StyledText { - Layout.topMargin: Appearance.spacing.normal - text: qsTr("System name") - } - - StyledText { - text: root.device?.deviceName ?? "" - color: Colours.palette.m3outline - font.pointSize: Appearance.font.size.small - } - } - } - } - } - ] - } - } - - ColumnLayout { - anchors.right: fabRoot.right - anchors.bottom: fabRoot.top - anchors.bottomMargin: Appearance.padding.normal - - Repeater { - id: fabMenu - - model: ListModel { - ListElement { - name: "trust" - icon: "handshake" - } - ListElement { - name: "block" - icon: "block" - } - ListElement { - name: "pair" - icon: "missing_controller" - } - ListElement { - name: "connect" - icon: "bluetooth_connected" - } - } - - StyledClippingRect { - id: fabMenuItem - - required property var modelData - required property int index - - Layout.alignment: Qt.AlignRight - - implicitHeight: fabMenuItemInner.implicitHeight + Appearance.padding.larger * 2 - - radius: Appearance.rounding.full - color: Colours.palette.m3primaryContainer - - opacity: 0 - - states: State { - name: "visible" - when: root.session.bt.fabMenuOpen - - PropertyChanges { - fabMenuItem.implicitWidth: fabMenuItemInner.implicitWidth + Appearance.padding.large * 2 - fabMenuItem.opacity: 1 - fabMenuItemInner.opacity: 1 - } - } - - transitions: [ - Transition { - to: "visible" - - SequentialAnimation { - PauseAnimation { - duration: (fabMenu.count - 1 - fabMenuItem.index) * Appearance.anim.durations.small / 8 - } - ParallelAnimation { - Anim { - property: "implicitWidth" - duration: Appearance.anim.durations.expressiveFastSpatial - easing.bezierCurve: Appearance.anim.curves.expressiveFastSpatial - } - Anim { - property: "opacity" - duration: Appearance.anim.durations.small - } - } - } - }, - Transition { - from: "visible" - - SequentialAnimation { - PauseAnimation { - duration: fabMenuItem.index * Appearance.anim.durations.small / 8 - } - ParallelAnimation { - Anim { - property: "implicitWidth" - duration: Appearance.anim.durations.expressiveFastSpatial - easing.bezierCurve: Appearance.anim.curves.expressiveFastSpatial - } - Anim { - property: "opacity" - duration: Appearance.anim.durations.small - } - } - } - } - ] - - StateLayer { - function onClicked(): void { - root.session.bt.fabMenuOpen = false; - - const name = fabMenuItem.modelData.name; - if (fabMenuItem.modelData.name !== "pair") - root.device[`${name}ed`] = !root.device[`${name}ed`]; - else if (root.device.paired) - root.device.forget(); - else - root.device.pair(); - } - } - - RowLayout { - id: fabMenuItemInner - - anchors.centerIn: parent - spacing: Appearance.spacing.normal - opacity: 0 - - MaterialIcon { - text: fabMenuItem.modelData.icon - color: Colours.palette.m3onPrimaryContainer - fill: 1 - } - - StyledText { - animate: true - text: (root.device && root.device[`${fabMenuItem.modelData.name}ed`] ? fabMenuItem.modelData.name === "connect" ? "dis" : "un" : "") + fabMenuItem.modelData.name - color: Colours.palette.m3onPrimaryContainer - font.capitalization: Font.Capitalize - Layout.preferredWidth: implicitWidth - - Behavior on Layout.preferredWidth { - Anim { - duration: Appearance.anim.durations.small - } - } - } - } - } - } - } - - Item { - id: fabRoot - - x: root.contentX + root.width - width - y: root.contentY + root.height - height - width: 64 - height: 64 - z: 10000 - - StyledRect { - id: fabBg - - anchors.right: parent.right - anchors.top: parent.top - - implicitWidth: 64 - implicitHeight: 64 - - radius: Appearance.rounding.normal - color: root.session.bt.fabMenuOpen ? Colours.palette.m3primary : Colours.palette.m3primaryContainer - - states: State { - name: "expanded" - when: root.session.bt.fabMenuOpen - - PropertyChanges { - fabBg.implicitWidth: 48 - fabBg.implicitHeight: 48 - fabBg.radius: 48 / 2 - fab.font.pointSize: Appearance.font.size.larger - } - } - - transitions: Transition { - Anim { - properties: "implicitWidth,implicitHeight" - duration: Appearance.anim.durations.expressiveFastSpatial - easing.bezierCurve: Appearance.anim.curves.expressiveFastSpatial - } - Anim { - properties: "radius,font.pointSize" - } - } - - Elevation { - anchors.fill: parent - radius: parent.radius - z: -1 - level: fabState.containsMouse && !fabState.pressed ? 4 : 3 - } - - StateLayer { - id: fabState - - color: root.session.bt.fabMenuOpen ? Colours.palette.m3onPrimary : Colours.palette.m3onPrimaryContainer - - function onClicked(): void { - root.session.bt.fabMenuOpen = !root.session.bt.fabMenuOpen; - } - } - - MaterialIcon { - id: fab - - anchors.centerIn: parent - animate: true - text: root.session.bt.fabMenuOpen ? "close" : "settings" - color: root.session.bt.fabMenuOpen ? Colours.palette.m3onPrimary : Colours.palette.m3onPrimaryContainer - font.pointSize: Appearance.font.size.large - fill: 1 - } - } - } - - component Toggle: RowLayout { - required property string label - property alias checked: toggle.checked - property alias toggle: toggle - - Layout.fillWidth: true - spacing: Appearance.spacing.normal - - StyledText { - Layout.fillWidth: true - text: parent.label - } - - StyledSwitch { - id: toggle - - cLayer: 2 - } - } -} diff --git a/modules/controlcenter/bluetooth/DeviceList.qml b/modules/controlcenter/bluetooth/DeviceList.qml deleted file mode 100644 index 2a2bde9..0000000 --- a/modules/controlcenter/bluetooth/DeviceList.qml +++ /dev/null @@ -1,264 +0,0 @@ -pragma ComponentBehavior: Bound - -import ".." -import "../components" -import qs.components -import qs.components.controls -import qs.components.containers -import qs.services -import qs.config -import qs.utils -import Quickshell -import Quickshell.Bluetooth -import QtQuick -import QtQuick.Layouts - -DeviceList { - id: root - - required property Session session - readonly property bool smallDiscoverable: width <= 540 - readonly property bool smallPairable: width <= 480 - - title: qsTr("Devices (%1)").arg(Bluetooth.devices.values.length) - description: qsTr("All available bluetooth devices") - activeItem: session.bt.active - - model: ScriptModel { - id: deviceModel - - values: [...Bluetooth.devices.values].sort((a, b) => (b.connected - a.connected) || (b.paired - a.paired) || a.name.localeCompare(b.name)) - } - - headerComponent: Component { - RowLayout { - spacing: Appearance.spacing.smaller - - StyledText { - text: qsTr("Bluetooth") - font.pointSize: Appearance.font.size.large - font.weight: 500 - } - - Item { - Layout.fillWidth: true - } - - ToggleButton { - toggled: Bluetooth.defaultAdapter?.enabled ?? false - icon: "power" - accent: "Tertiary" - iconSize: Appearance.font.size.normal - horizontalPadding: Appearance.padding.normal - verticalPadding: Appearance.padding.smaller - tooltip: qsTr("Toggle Bluetooth") - - onClicked: { - const adapter = Bluetooth.defaultAdapter; - if (adapter) - adapter.enabled = !adapter.enabled; - } - } - - ToggleButton { - toggled: Bluetooth.defaultAdapter?.discoverable ?? false - icon: root.smallDiscoverable ? "group_search" : "" - label: root.smallDiscoverable ? "" : qsTr("Discoverable") - iconSize: Appearance.font.size.normal - horizontalPadding: Appearance.padding.normal - verticalPadding: Appearance.padding.smaller - tooltip: qsTr("Make discoverable") - - onClicked: { - const adapter = Bluetooth.defaultAdapter; - if (adapter) - adapter.discoverable = !adapter.discoverable; - } - } - - ToggleButton { - toggled: Bluetooth.defaultAdapter?.pairable ?? false - icon: "missing_controller" - label: root.smallPairable ? "" : qsTr("Pairable") - iconSize: Appearance.font.size.normal - horizontalPadding: Appearance.padding.normal - verticalPadding: Appearance.padding.smaller - tooltip: qsTr("Make pairable") - - onClicked: { - const adapter = Bluetooth.defaultAdapter; - if (adapter) - adapter.pairable = !adapter.pairable; - } - } - - ToggleButton { - toggled: Bluetooth.defaultAdapter?.discovering ?? false - icon: "bluetooth_searching" - accent: "Secondary" - iconSize: Appearance.font.size.normal - horizontalPadding: Appearance.padding.normal - verticalPadding: Appearance.padding.smaller - tooltip: qsTr("Scan for devices") - - onClicked: { - const adapter = Bluetooth.defaultAdapter; - if (adapter) - adapter.discovering = !adapter.discovering; - } - } - - ToggleButton { - toggled: !root.session.bt.active - icon: "settings" - accent: "Primary" - iconSize: Appearance.font.size.normal - horizontalPadding: Appearance.padding.normal - verticalPadding: Appearance.padding.smaller - tooltip: qsTr("Bluetooth settings") - - onClicked: { - if (root.session.bt.active) - root.session.bt.active = null; - else { - root.session.bt.active = root.model.values[0] ?? null; - } - } - } - } - } - - delegate: Component { - StyledRect { - id: device - - required property BluetoothDevice modelData - readonly property bool loading: modelData && (modelData.state === BluetoothDeviceState.Connecting || modelData.state === BluetoothDeviceState.Disconnecting) - readonly property bool connected: modelData && modelData.state === BluetoothDeviceState.Connected - - width: ListView.view ? ListView.view.width : undefined - implicitHeight: deviceInner.implicitHeight + Appearance.padding.normal * 2 - - color: Qt.alpha(Colours.tPalette.m3surfaceContainer, root.activeItem === modelData ? Colours.tPalette.m3surfaceContainer.a : 0) - radius: Appearance.rounding.normal - - StateLayer { - id: stateLayer - - function onClicked(): void { - if (device.modelData) - root.session.bt.active = device.modelData; - } - } - - RowLayout { - id: deviceInner - - anchors.fill: parent - anchors.margins: Appearance.padding.normal - - spacing: Appearance.spacing.normal - - StyledRect { - implicitWidth: implicitHeight - implicitHeight: icon.implicitHeight + Appearance.padding.normal * 2 - - radius: Appearance.rounding.normal - color: device.connected ? Colours.palette.m3primaryContainer : (device.modelData && device.modelData.bonded) ? Colours.palette.m3secondaryContainer : Colours.tPalette.m3surfaceContainerHigh - - StyledRect { - anchors.fill: parent - radius: parent.radius - color: Qt.alpha(device.connected ? Colours.palette.m3onPrimaryContainer : (device.modelData && device.modelData.bonded) ? Colours.palette.m3onSecondaryContainer : Colours.palette.m3onSurface, stateLayer.pressed ? 0.1 : stateLayer.containsMouse ? 0.08 : 0) - } - - MaterialIcon { - id: icon - - anchors.centerIn: parent - text: Icons.getBluetoothIcon(device.modelData ? device.modelData.icon : "") - color: device.connected ? Colours.palette.m3onPrimaryContainer : (device.modelData && device.modelData.bonded) ? Colours.palette.m3onSecondaryContainer : Colours.palette.m3onSurface - font.pointSize: Appearance.font.size.large - fill: device.connected ? 1 : 0 - - Behavior on fill { - Anim {} - } - } - } - - ColumnLayout { - Layout.fillWidth: true - - spacing: 0 - - StyledText { - Layout.fillWidth: true - text: device.modelData ? device.modelData.name : qsTr("Unknown") - elide: Text.ElideRight - } - - StyledText { - Layout.fillWidth: true - text: (device.modelData ? device.modelData.address : "") + (device.connected ? qsTr(" (Connected)") : (device.modelData && device.modelData.bonded) ? qsTr(" (Paired)") : "") - color: Colours.palette.m3outline - font.pointSize: Appearance.font.size.small - elide: Text.ElideRight - } - } - - StyledRect { - id: connectBtn - - implicitWidth: implicitHeight - implicitHeight: connectIcon.implicitHeight + Appearance.padding.smaller * 2 - - radius: Appearance.rounding.full - color: Qt.alpha(Colours.palette.m3primaryContainer, device.connected ? 1 : 0) - - CircularIndicator { - anchors.fill: parent - running: device.loading - } - - StateLayer { - color: device.connected ? Colours.palette.m3onPrimaryContainer : Colours.palette.m3onSurface - disabled: device.loading - - function onClicked(): void { - if (device.loading) - return; - - if (device.connected) { - device.modelData.connected = false; - } else { - if (device.modelData.bonded) { - device.modelData.connected = true; - } else { - device.modelData.pair(); - } - } - } - } - - MaterialIcon { - id: connectIcon - - anchors.centerIn: parent - animate: true - text: device.connected ? "link_off" : "link" - color: device.connected ? Colours.palette.m3onPrimaryContainer : Colours.palette.m3onSurface - - opacity: device.loading ? 0 : 1 - - Behavior on opacity { - Anim {} - } - } - } - } - } - } - - onItemSelected: item => session.bt.active = item -} diff --git a/modules/controlcenter/bluetooth/Settings.qml b/modules/controlcenter/bluetooth/Settings.qml deleted file mode 100644 index c547240..0000000 --- a/modules/controlcenter/bluetooth/Settings.qml +++ /dev/null @@ -1,532 +0,0 @@ -pragma ComponentBehavior: Bound - -import ".." -import "../components" -import qs.components -import qs.components.controls -import qs.components.effects -import qs.services -import qs.config -import Quickshell.Bluetooth -import QtQuick -import QtQuick.Layouts - -ColumnLayout { - id: root - - required property Session session - - spacing: Appearance.spacing.normal - - SettingsHeader { - icon: "bluetooth" - title: qsTr("Bluetooth Settings") - } - - StyledText { - Layout.topMargin: Appearance.spacing.large - text: qsTr("Adapter status") - font.pointSize: Appearance.font.size.larger - font.weight: 500 - } - - StyledText { - text: qsTr("General adapter settings") - color: Colours.palette.m3outline - } - - StyledRect { - Layout.fillWidth: true - implicitHeight: adapterStatus.implicitHeight + Appearance.padding.large * 2 - - radius: Appearance.rounding.normal - color: Colours.tPalette.m3surfaceContainer - - ColumnLayout { - id: adapterStatus - - anchors.left: parent.left - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - anchors.margins: Appearance.padding.large - - spacing: Appearance.spacing.larger - - Toggle { - label: qsTr("Powered") - checked: Bluetooth.defaultAdapter?.enabled ?? false - toggle.onToggled: { - const adapter = Bluetooth.defaultAdapter; - if (adapter) - adapter.enabled = checked; - } - } - - Toggle { - label: qsTr("Discoverable") - checked: Bluetooth.defaultAdapter?.discoverable ?? false - toggle.onToggled: { - const adapter = Bluetooth.defaultAdapter; - if (adapter) - adapter.discoverable = checked; - } - } - - Toggle { - label: qsTr("Pairable") - checked: Bluetooth.defaultAdapter?.pairable ?? false - toggle.onToggled: { - const adapter = Bluetooth.defaultAdapter; - if (adapter) - adapter.pairable = checked; - } - } - } - } - - StyledText { - Layout.topMargin: Appearance.spacing.large - text: qsTr("Adapter properties") - font.pointSize: Appearance.font.size.larger - font.weight: 500 - } - - StyledText { - text: qsTr("Per-adapter settings") - color: Colours.palette.m3outline - } - - StyledRect { - Layout.fillWidth: true - implicitHeight: adapterSettings.implicitHeight + Appearance.padding.large * 2 - - radius: Appearance.rounding.normal - color: Colours.tPalette.m3surfaceContainer - - ColumnLayout { - id: adapterSettings - - anchors.left: parent.left - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - anchors.margins: Appearance.padding.large - - spacing: Appearance.spacing.larger - - RowLayout { - Layout.fillWidth: true - spacing: Appearance.spacing.normal - - StyledText { - Layout.fillWidth: true - text: qsTr("Current adapter") - } - - Item { - id: adapterPickerButton - - property bool expanded - - implicitWidth: adapterPicker.implicitWidth + Appearance.padding.normal * 2 - implicitHeight: adapterPicker.implicitHeight + Appearance.padding.smaller * 2 - - StateLayer { - radius: Appearance.rounding.small - - function onClicked(): void { - adapterPickerButton.expanded = !adapterPickerButton.expanded; - } - } - - RowLayout { - id: adapterPicker - - anchors.fill: parent - anchors.margins: Appearance.padding.normal - anchors.topMargin: Appearance.padding.smaller - anchors.bottomMargin: Appearance.padding.smaller - spacing: Appearance.spacing.normal - - StyledText { - Layout.leftMargin: Appearance.padding.small - text: Bluetooth.defaultAdapter?.name ?? qsTr("None") - } - - MaterialIcon { - text: "expand_more" - } - } - - Elevation { - anchors.fill: adapterListBg - radius: adapterListBg.radius - opacity: adapterPickerButton.expanded ? 1 : 0 - scale: adapterPickerButton.expanded ? 1 : 0.7 - level: 2 - - Behavior on opacity { - Anim {} - } - - Behavior on scale { - Anim { - duration: Appearance.anim.durations.expressiveFastSpatial - easing.bezierCurve: Appearance.anim.curves.expressiveFastSpatial - } - } - } - - StyledClippingRect { - id: adapterListBg - - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: parent.bottom - implicitHeight: adapterPickerButton.expanded ? adapterList.implicitHeight : adapterPickerButton.implicitHeight - - color: Colours.palette.m3secondaryContainer - radius: Appearance.rounding.small - opacity: adapterPickerButton.expanded ? 1 : 0 - scale: adapterPickerButton.expanded ? 1 : 0.7 - - ColumnLayout { - id: adapterList - - anchors.left: parent.left - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - - spacing: 0 - - Repeater { - model: Bluetooth.adapters - - Item { - id: adapter - - required property BluetoothAdapter modelData - - Layout.fillWidth: true - implicitHeight: adapterInner.implicitHeight + Appearance.padding.normal * 2 - - StateLayer { - disabled: !adapterPickerButton.expanded - - function onClicked(): void { - adapterPickerButton.expanded = false; - root.session.bt.currentAdapter = adapter.modelData; - } - } - - RowLayout { - id: adapterInner - - anchors.left: parent.left - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - anchors.margins: Appearance.padding.normal - spacing: Appearance.spacing.normal - - StyledText { - Layout.fillWidth: true - Layout.leftMargin: Appearance.padding.small - text: adapter.modelData.name - color: Colours.palette.m3onSecondaryContainer - } - - MaterialIcon { - text: "check" - color: Colours.palette.m3onSecondaryContainer - visible: adapter.modelData === root.session.bt.currentAdapter - } - } - } - } - } - - Behavior on opacity { - Anim {} - } - - Behavior on scale { - Anim { - duration: Appearance.anim.durations.expressiveFastSpatial - easing.bezierCurve: Appearance.anim.curves.expressiveFastSpatial - } - } - - Behavior on implicitHeight { - Anim { - duration: Appearance.anim.durations.expressiveDefaultSpatial - easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial - } - } - } - } - } - - RowLayout { - Layout.fillWidth: true - spacing: Appearance.spacing.normal - - StyledText { - Layout.fillWidth: true - text: qsTr("Discoverable timeout") - } - - CustomSpinBox { - min: 0 - value: root.session.bt.currentAdapter?.discoverableTimeout ?? 0 - onValueModified: value => { - if (root.session.bt.currentAdapter) { - root.session.bt.currentAdapter.discoverableTimeout = value; - } - } - } - } - - RowLayout { - Layout.fillWidth: true - spacing: Appearance.spacing.small - - Item { - id: renameAdapter - - Layout.fillWidth: true - Layout.rightMargin: Appearance.spacing.small - - implicitHeight: renameLabel.implicitHeight + adapterNameEdit.implicitHeight - - states: State { - name: "editingAdapterName" - when: root.session.bt.editingAdapterName - - AnchorChanges { - target: adapterNameEdit - anchors.top: renameAdapter.top - } - PropertyChanges { - renameAdapter.implicitHeight: adapterNameEdit.implicitHeight - renameLabel.opacity: 0 - adapterNameEdit.padding: Appearance.padding.normal - } - } - - transitions: Transition { - AnchorAnimation { - duration: Appearance.anim.durations.normal - easing.type: Easing.BezierSpline - easing.bezierCurve: Appearance.anim.curves.standard - } - Anim { - properties: "implicitHeight,opacity,padding" - } - } - - StyledText { - id: renameLabel - - anchors.left: parent.left - - text: qsTr("Rename adapter (currently does not work)") - color: Colours.palette.m3outline - font.pointSize: Appearance.font.size.small - } - - StyledTextField { - id: adapterNameEdit - - anchors.left: parent.left - anchors.right: parent.right - anchors.top: renameLabel.bottom - anchors.leftMargin: root.session.bt.editingAdapterName ? 0 : -Appearance.padding.normal - - text: root.session.bt.currentAdapter?.name ?? "" - readOnly: !root.session.bt.editingAdapterName - onAccepted: { - root.session.bt.editingAdapterName = false; - } - - leftPadding: Appearance.padding.normal - rightPadding: Appearance.padding.normal - - background: StyledRect { - radius: Appearance.rounding.small - border.width: 2 - border.color: Colours.palette.m3primary - opacity: root.session.bt.editingAdapterName ? 1 : 0 - - Behavior on border.color { - CAnim {} - } - - Behavior on opacity { - Anim {} - } - } - - Behavior on anchors.leftMargin { - Anim {} - } - } - } - - StyledRect { - implicitWidth: implicitHeight - implicitHeight: cancelEditIcon.implicitHeight + Appearance.padding.smaller * 2 - - radius: Appearance.rounding.small - color: Colours.palette.m3secondaryContainer - opacity: root.session.bt.editingAdapterName ? 1 : 0 - scale: root.session.bt.editingAdapterName ? 1 : 0.5 - - StateLayer { - color: Colours.palette.m3onSecondaryContainer - disabled: !root.session.bt.editingAdapterName - - function onClicked(): void { - root.session.bt.editingAdapterName = false; - adapterNameEdit.text = Qt.binding(() => root.session.bt.currentAdapter?.name ?? ""); - } - } - - MaterialIcon { - id: cancelEditIcon - - anchors.centerIn: parent - animate: true - text: "cancel" - color: Colours.palette.m3onSecondaryContainer - } - - Behavior on opacity { - Anim {} - } - - Behavior on scale { - Anim { - duration: Appearance.anim.durations.expressiveFastSpatial - easing.bezierCurve: Appearance.anim.curves.expressiveFastSpatial - } - } - } - - StyledRect { - implicitWidth: implicitHeight - implicitHeight: editIcon.implicitHeight + Appearance.padding.smaller * 2 - - radius: root.session.bt.editingAdapterName ? Appearance.rounding.small : implicitHeight / 2 * Math.min(1, Appearance.rounding.scale) - color: Qt.alpha(Colours.palette.m3primary, root.session.bt.editingAdapterName ? 1 : 0) - - StateLayer { - color: root.session.bt.editingAdapterName ? Colours.palette.m3onPrimary : Colours.palette.m3onSurface - - function onClicked(): void { - root.session.bt.editingAdapterName = !root.session.bt.editingAdapterName; - if (root.session.bt.editingAdapterName) - adapterNameEdit.forceActiveFocus(); - else - adapterNameEdit.accepted(); - } - } - - MaterialIcon { - id: editIcon - - anchors.centerIn: parent - animate: true - text: root.session.bt.editingAdapterName ? "check_circle" : "edit" - color: root.session.bt.editingAdapterName ? Colours.palette.m3onPrimary : Colours.palette.m3onSurface - } - - Behavior on radius { - Anim {} - } - } - } - } - } - - StyledText { - Layout.topMargin: Appearance.spacing.large - text: qsTr("Adapter information") - font.pointSize: Appearance.font.size.larger - font.weight: 500 - } - - StyledText { - text: qsTr("Information about the default adapter") - color: Colours.palette.m3outline - } - - StyledRect { - Layout.fillWidth: true - implicitHeight: adapterInfo.implicitHeight + Appearance.padding.large * 2 - - radius: Appearance.rounding.normal - color: Colours.tPalette.m3surfaceContainer - - ColumnLayout { - id: adapterInfo - - anchors.left: parent.left - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - anchors.margins: Appearance.padding.large - - spacing: Appearance.spacing.small / 2 - - StyledText { - text: qsTr("Adapter state") - } - - StyledText { - text: Bluetooth.defaultAdapter ? BluetoothAdapterState.toString(Bluetooth.defaultAdapter.state) : qsTr("Unknown") - color: Colours.palette.m3outline - font.pointSize: Appearance.font.size.small - } - - StyledText { - Layout.topMargin: Appearance.spacing.normal - text: qsTr("Dbus path") - } - - StyledText { - text: Bluetooth.defaultAdapter?.dbusPath ?? "" - color: Colours.palette.m3outline - font.pointSize: Appearance.font.size.small - } - - StyledText { - Layout.topMargin: Appearance.spacing.normal - text: qsTr("Adapter id") - } - - StyledText { - text: Bluetooth.defaultAdapter?.adapterId ?? "" - color: Colours.palette.m3outline - font.pointSize: Appearance.font.size.small - } - } - } - - component Toggle: RowLayout { - required property string label - property alias checked: toggle.checked - property alias toggle: toggle - - Layout.fillWidth: true - spacing: Appearance.spacing.normal - - StyledText { - Layout.fillWidth: true - text: parent.label - } - - StyledSwitch { - id: toggle - - cLayer: 2 - } - } -} diff --git a/modules/controlcenter/components/DeviceDetails.qml b/modules/controlcenter/components/DeviceDetails.qml deleted file mode 100644 index a5d0647..0000000 --- a/modules/controlcenter/components/DeviceDetails.qml +++ /dev/null @@ -1,70 +0,0 @@ -pragma ComponentBehavior: Bound - -import ".." -import qs.components -import qs.components.controls -import qs.components.effects -import qs.components.containers -import qs.config -import QtQuick -import QtQuick.Layouts - -Item { - id: root - - property Session session - property var device: null - - property Component headerComponent: null - property list<Component> sections: [] - - property Component topContent: null - property Component bottomContent: null - - implicitWidth: layout.implicitWidth - implicitHeight: layout.implicitHeight - - ColumnLayout { - id: layout - - anchors.left: parent.left - anchors.right: parent.right - anchors.top: parent.top - spacing: Appearance.spacing.normal - - Loader { - id: headerLoader - - Layout.fillWidth: true - sourceComponent: root.headerComponent - visible: root.headerComponent !== null - } - - Loader { - id: topContentLoader - - Layout.fillWidth: true - sourceComponent: root.topContent - visible: root.topContent !== null - } - - Repeater { - model: root.sections - - Loader { - required property Component modelData - - Layout.fillWidth: true - sourceComponent: modelData - } - } - - Loader { - id: bottomContentLoader - - Layout.fillWidth: true - sourceComponent: root.bottomContent - visible: root.bottomContent !== null - } - } -} diff --git a/modules/controlcenter/components/DeviceList.qml b/modules/controlcenter/components/DeviceList.qml deleted file mode 100644 index 722f9a1..0000000 --- a/modules/controlcenter/components/DeviceList.qml +++ /dev/null @@ -1,84 +0,0 @@ -pragma ComponentBehavior: Bound - -import ".." -import qs.components -import qs.components.controls -import qs.components.containers -import qs.services -import qs.config -import Quickshell -import QtQuick -import QtQuick.Layouts - -ColumnLayout { - id: root - - property Session session: null - property var model: null - property Component delegate: null - - property string title: "" - property string description: "" - property var activeItem: null - property Component headerComponent: null - property Component titleSuffix: null - property bool showHeader: true - - signal itemSelected(var item) - - spacing: Appearance.spacing.small - - Loader { - id: headerLoader - - Layout.fillWidth: true - sourceComponent: root.headerComponent - visible: root.headerComponent !== null && root.showHeader - } - - RowLayout { - Layout.fillWidth: true - Layout.topMargin: root.headerComponent ? 0 : 0 - spacing: Appearance.spacing.small - visible: root.title !== "" || root.description !== "" - - StyledText { - visible: root.title !== "" - text: root.title - font.pointSize: Appearance.font.size.large - font.weight: 500 - } - - Loader { - sourceComponent: root.titleSuffix - visible: root.titleSuffix !== null - } - - Item { - Layout.fillWidth: true - } - } - - property alias view: view - - StyledText { - visible: root.description !== "" - Layout.fillWidth: true - text: root.description - color: Colours.palette.m3outline - } - - StyledListView { - id: view - - Layout.fillWidth: true - implicitHeight: contentHeight - - model: root.model - delegate: root.delegate - - spacing: Appearance.spacing.small / 2 - interactive: false - clip: false - } -} diff --git a/modules/controlcenter/components/PaneTransition.qml b/modules/controlcenter/components/PaneTransition.qml deleted file mode 100644 index 5d80dbe..0000000 --- a/modules/controlcenter/components/PaneTransition.qml +++ /dev/null @@ -1,71 +0,0 @@ -pragma ComponentBehavior: Bound - -import qs.config -import QtQuick - -SequentialAnimation { - id: root - - required property Item target - property list<PropertyAction> propertyActions - - property real scaleFrom: 1.0 - property real scaleTo: 0.8 - property real opacityFrom: 1.0 - property real opacityTo: 0.0 - - ParallelAnimation { - NumberAnimation { - target: root.target - property: "opacity" - from: root.opacityFrom - to: root.opacityTo - duration: Appearance.anim.durations.normal / 2 - easing.type: Easing.BezierSpline - easing.bezierCurve: Appearance.anim.curves.standardAccel - } - - NumberAnimation { - target: root.target - property: "scale" - from: root.scaleFrom - to: root.scaleTo - duration: Appearance.anim.durations.normal / 2 - easing.type: Easing.BezierSpline - easing.bezierCurve: Appearance.anim.curves.standardAccel - } - } - - ScriptAction { - script: { - for (let i = 0; i < root.propertyActions.length; i++) { - const action = root.propertyActions[i]; - if (action.target && action.property !== undefined) { - action.target[action.property] = action.value; - } - } - } - } - - ParallelAnimation { - NumberAnimation { - target: root.target - property: "opacity" - from: root.opacityTo - to: root.opacityFrom - duration: Appearance.anim.durations.normal / 2 - easing.type: Easing.BezierSpline - easing.bezierCurve: Appearance.anim.curves.standardDecel - } - - NumberAnimation { - target: root.target - property: "scale" - from: root.scaleTo - to: root.scaleFrom - duration: Appearance.anim.durations.normal / 2 - easing.type: Easing.BezierSpline - easing.bezierCurve: Appearance.anim.curves.standardDecel - } - } -} diff --git a/modules/controlcenter/components/ReadonlySlider.qml b/modules/controlcenter/components/ReadonlySlider.qml deleted file mode 100644 index 169d636..0000000 --- a/modules/controlcenter/components/ReadonlySlider.qml +++ /dev/null @@ -1,67 +0,0 @@ -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 - } - } -} diff --git a/modules/controlcenter/components/SettingsHeader.qml b/modules/controlcenter/components/SettingsHeader.qml deleted file mode 100644 index 0dc190c..0000000 --- a/modules/controlcenter/components/SettingsHeader.qml +++ /dev/null @@ -1,37 +0,0 @@ -pragma ComponentBehavior: Bound - -import qs.components -import qs.config -import QtQuick -import QtQuick.Layouts - -Item { - id: root - - required property string icon - required property string title - - Layout.fillWidth: true - implicitHeight: column.implicitHeight - - ColumnLayout { - id: column - - anchors.centerIn: parent - spacing: Appearance.spacing.normal - - MaterialIcon { - Layout.alignment: Qt.AlignHCenter - text: root.icon - font.pointSize: Appearance.font.size.extraLarge * 3 - font.bold: true - } - - StyledText { - Layout.alignment: Qt.AlignHCenter - text: root.title - font.pointSize: Appearance.font.size.large - font.bold: true - } - } -} diff --git a/modules/controlcenter/components/SliderInput.qml b/modules/controlcenter/components/SliderInput.qml deleted file mode 100644 index 11b3f70..0000000 --- a/modules/controlcenter/components/SliderInput.qml +++ /dev/null @@ -1,180 +0,0 @@ -pragma ComponentBehavior: Bound - -import qs.components -import qs.components.controls -import qs.components.effects -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 real stepSize: 0 - property var validator: null - property string suffix: "" // Optional suffix text (e.g., "×", "px") - property int decimals: 1 // Number of decimal places to show (default: 1) - property var formatValueFunction: null // Optional custom format function - property var parseValueFunction: null // Optional custom parse function - - function formatValue(val: real): string { - if (formatValueFunction) { - return formatValueFunction(val); - } - // Default format function - // Check if it's an IntValidator (IntValidator doesn't have a 'decimals' property) - if (validator && validator.bottom !== undefined && validator.decimals === undefined) { - return Math.round(val).toString(); - } - // For DoubleValidator or no validator, use the decimals property - return val.toFixed(root.decimals); - } - - function parseValue(text: string): real { - if (parseValueFunction) { - return parseValueFunction(text); - } - // Default parse function - if (validator && validator.bottom !== undefined) { - // Check if it's an integer validator - if (validator.top !== undefined && validator.top === Math.floor(validator.top)) { - return parseInt(text); - } - } - return parseFloat(text); - } - - signal valueModified(real newValue) - - property bool _initialized: false - - spacing: Appearance.spacing.small - - Component.onCompleted: { - // Set initialized flag after a brief delay to allow component to fully load - Qt.callLater(() => { - _initialized = true; - }); - } - - RowLayout { - Layout.fillWidth: true - spacing: Appearance.spacing.normal - - StyledText { - visible: root.label !== "" - text: root.label - font.pointSize: Appearance.font.size.normal - } - - Item { - Layout.fillWidth: true - } - - StyledInputField { - id: inputField - Layout.preferredWidth: 70 - validator: root.validator - - Component.onCompleted: { - // Initialize text without triggering valueModified signal - text = root.formatValue(root.value); - } - - onTextEdited: text => { - if (hasFocus) { - const val = root.parseValue(text); - if (!isNaN(val)) { - // Validate against validator bounds if available - let isValid = true; - if (root.validator) { - if (root.validator.bottom !== undefined && val < root.validator.bottom) { - isValid = false; - } - if (root.validator.top !== undefined && val > root.validator.top) { - isValid = false; - } - } - - if (isValid) { - root.valueModified(val); - } - } - } - } - - onEditingFinished: { - const val = root.parseValue(text); - let isValid = true; - if (root.validator) { - if (root.validator.bottom !== undefined && val < root.validator.bottom) { - isValid = false; - } - if (root.validator.top !== undefined && val > root.validator.top) { - isValid = false; - } - } - - if (isNaN(val) || !isValid) { - text = root.formatValue(root.value); - } - } - } - - StyledText { - visible: root.suffix !== "" - text: root.suffix - color: Colours.palette.m3outline - font.pointSize: Appearance.font.size.normal - } - } - - StyledSlider { - id: slider - - Layout.fillWidth: true - implicitHeight: Appearance.padding.normal * 3 - - from: root.from - to: root.to - stepSize: root.stepSize - - // Use Binding to allow slider to move freely during dragging - Binding { - target: slider - property: "value" - value: root.value - when: !slider.pressed - } - - onValueChanged: { - // Update input field text in real-time as slider moves during dragging - // Always update when slider value changes (during dragging or external updates) - if (!inputField.hasFocus) { - const newValue = root.stepSize > 0 ? Math.round(value / root.stepSize) * root.stepSize : value; - inputField.text = root.formatValue(newValue); - } - } - - onMoved: { - const newValue = root.stepSize > 0 ? Math.round(value / root.stepSize) * root.stepSize : value; - root.valueModified(newValue); - if (!inputField.hasFocus) { - inputField.text = root.formatValue(newValue); - } - } - } - - // Update input field when value changes externally (slider is already bound) - onValueChanged: { - // Only update if component is initialized to avoid issues during creation - if (root._initialized && !inputField.hasFocus) { - inputField.text = root.formatValue(root.value); - } - } -} diff --git a/modules/controlcenter/components/SplitPaneLayout.qml b/modules/controlcenter/components/SplitPaneLayout.qml deleted file mode 100644 index 89504a0..0000000 --- a/modules/controlcenter/components/SplitPaneLayout.qml +++ /dev/null @@ -1,109 +0,0 @@ -pragma ComponentBehavior: Bound - -import qs.components -import qs.components.effects -import qs.config -import Quickshell.Widgets -import QtQuick -import QtQuick.Layouts - -RowLayout { - id: root - - spacing: 0 - - property Component leftContent: null - property Component rightContent: null - - property real leftWidthRatio: 0.4 - property int leftMinimumWidth: 420 - property var leftLoaderProperties: ({}) - property var rightLoaderProperties: ({}) - - property alias leftLoader: leftLoader - property alias rightLoader: rightLoader - - Item { - id: leftPane - - Layout.preferredWidth: Math.floor(parent.width * root.leftWidthRatio) - Layout.minimumWidth: root.leftMinimumWidth - Layout.fillHeight: true - - ClippingRectangle { - id: leftClippingRect - - anchors.fill: parent - anchors.margins: Appearance.padding.normal - anchors.leftMargin: 0 - anchors.rightMargin: Appearance.padding.normal / 2 - - radius: leftBorder.innerRadius - color: "transparent" - - Loader { - id: leftLoader - - anchors.fill: parent - anchors.margins: Appearance.padding.large + Appearance.padding.normal - anchors.leftMargin: Appearance.padding.large - anchors.rightMargin: Appearance.padding.large + Appearance.padding.normal / 2 - - sourceComponent: root.leftContent - - Component.onCompleted: { - for (const key in root.leftLoaderProperties) { - leftLoader[key] = root.leftLoaderProperties[key]; - } - } - } - } - - InnerBorder { - id: leftBorder - - leftThickness: 0 - rightThickness: Appearance.padding.normal / 2 - } - } - - Item { - id: rightPane - - Layout.fillWidth: true - Layout.fillHeight: true - - ClippingRectangle { - id: rightClippingRect - - anchors.fill: parent - anchors.margins: Appearance.padding.normal - anchors.leftMargin: 0 - anchors.rightMargin: Appearance.padding.normal / 2 - - radius: rightBorder.innerRadius - color: "transparent" - - Loader { - id: rightLoader - - anchors.fill: parent - anchors.margins: Appearance.padding.large * 2 - - sourceComponent: root.rightContent - - Component.onCompleted: { - for (const key in root.rightLoaderProperties) { - rightLoader[key] = root.rightLoaderProperties[key]; - } - } - } - } - - InnerBorder { - id: rightBorder - - leftThickness: Appearance.padding.normal / 2 - } - } -} diff --git a/modules/controlcenter/components/SplitPaneWithDetails.qml b/modules/controlcenter/components/SplitPaneWithDetails.qml deleted file mode 100644 index ce8c9d0..0000000 --- a/modules/controlcenter/components/SplitPaneWithDetails.qml +++ /dev/null @@ -1,93 +0,0 @@ -pragma ComponentBehavior: Bound - -import ".." -import qs.components -import qs.components.effects -import qs.components.containers -import qs.config -import Quickshell.Widgets -import QtQuick -import QtQuick.Layouts - -Item { - id: root - - required property Component leftContent - required property Component rightDetailsComponent - required property Component rightSettingsComponent - - property var activeItem: null - property var paneIdGenerator: function (item) { - return item ? String(item) : ""; - } - - property Component overlayComponent: null - - SplitPaneLayout { - id: splitLayout - - anchors.fill: parent - - leftContent: root.leftContent - - rightContent: Component { - Item { - id: rightPaneItem - - property var pane: root.activeItem - property string paneId: root.paneIdGenerator(pane) - property Component targetComponent: root.rightSettingsComponent - property Component nextComponent: root.rightSettingsComponent - - function getComponentForPane() { - return pane ? root.rightDetailsComponent : root.rightSettingsComponent; - } - - Component.onCompleted: { - targetComponent = getComponentForPane(); - nextComponent = targetComponent; - } - - Loader { - id: rightLoader - - anchors.fill: parent - - opacity: 1 - scale: 1 - transformOrigin: Item.Center - - clip: false - sourceComponent: rightPaneItem.targetComponent - } - - Behavior on paneId { - PaneTransition { - target: rightLoader - propertyActions: [ - PropertyAction { - target: rightPaneItem - property: "targetComponent" - value: rightPaneItem.nextComponent - } - ] - } - } - - onPaneChanged: { - nextComponent = getComponentForPane(); - paneId = root.paneIdGenerator(pane); - } - } - } - } - - Loader { - id: overlayLoader - - anchors.fill: parent - z: 1000 - sourceComponent: root.overlayComponent - active: root.overlayComponent !== null - } -} diff --git a/modules/controlcenter/dashboard/DashboardPane.qml b/modules/controlcenter/dashboard/DashboardPane.qml deleted file mode 100644 index df29f09..0000000 --- a/modules/controlcenter/dashboard/DashboardPane.qml +++ /dev/null @@ -1,135 +0,0 @@ -pragma ComponentBehavior: Bound - -import ".." -import "../components" -import qs.components -import qs.components.controls -import qs.components.effects -import qs.components.containers -import qs.services -import qs.config -import qs.utils -import Quickshell -import Quickshell.Widgets -import QtQuick -import QtQuick.Layouts - -Item { - id: root - - required property Session session - - // General Settings - property bool enabled: Config.dashboard.enabled ?? true - property bool showOnHover: Config.dashboard.showOnHover ?? true - property int mediaUpdateInterval: Config.dashboard.mediaUpdateInterval ?? 1000 - property int resourceUpdateInterval: Config.dashboard.resourceUpdateInterval ?? 1000 - property int dragThreshold: Config.dashboard.dragThreshold ?? 50 - - // Dashboard Tabs - property bool showDashboard: Config.dashboard.showDashboard ?? true - property bool showMedia: Config.dashboard.showMedia ?? true - property bool showPerformance: Config.dashboard.showPerformance ?? true - property bool showWeather: Config.dashboard.showWeather ?? true - - // Performance Resources - property bool showBattery: Config.dashboard.performance.showBattery ?? false - property bool showGpu: Config.dashboard.performance.showGpu ?? true - property bool showCpu: Config.dashboard.performance.showCpu ?? true - property bool showMemory: Config.dashboard.performance.showMemory ?? true - property bool showStorage: Config.dashboard.performance.showStorage ?? true - property bool showNetwork: Config.dashboard.performance.showNetwork ?? true - - anchors.fill: parent - - function saveConfig() { - Config.dashboard.enabled = root.enabled; - Config.dashboard.showOnHover = root.showOnHover; - Config.dashboard.mediaUpdateInterval = root.mediaUpdateInterval; - Config.dashboard.resourceUpdateInterval = root.resourceUpdateInterval; - Config.dashboard.dragThreshold = root.dragThreshold; - Config.dashboard.showDashboard = root.showDashboard; - Config.dashboard.showMedia = root.showMedia; - Config.dashboard.showPerformance = root.showPerformance; - Config.dashboard.showWeather = root.showWeather; - Config.dashboard.performance.showBattery = root.showBattery; - Config.dashboard.performance.showGpu = root.showGpu; - Config.dashboard.performance.showCpu = root.showCpu; - Config.dashboard.performance.showMemory = root.showMemory; - Config.dashboard.performance.showStorage = root.showStorage; - Config.dashboard.performance.showNetwork = root.showNetwork; - // Note: sizes properties are readonly and cannot be modified - Config.save(); - } - - ClippingRectangle { - id: dashboardClippingRect - anchors.fill: parent - anchors.margins: Appearance.padding.normal - anchors.leftMargin: 0 - anchors.rightMargin: Appearance.padding.normal - - radius: dashboardBorder.innerRadius - color: "transparent" - - Loader { - id: dashboardLoader - - anchors.fill: parent - anchors.margins: Appearance.padding.large + Appearance.padding.normal - anchors.leftMargin: Appearance.padding.large - anchors.rightMargin: Appearance.padding.large - - sourceComponent: dashboardContentComponent - } - } - - InnerBorder { - id: dashboardBorder - leftThickness: 0 - rightThickness: Appearance.padding.normal - } - - Component { - id: dashboardContentComponent - - StyledFlickable { - id: dashboardFlickable - flickableDirection: Flickable.VerticalFlick - contentHeight: dashboardLayout.height - - StyledScrollBar.vertical: StyledScrollBar { - flickable: dashboardFlickable - } - - ColumnLayout { - id: dashboardLayout - anchors.left: parent.left - anchors.right: parent.right - anchors.top: parent.top - - spacing: Appearance.spacing.normal - - RowLayout { - spacing: Appearance.spacing.smaller - - StyledText { - text: qsTr("Dashboard") - font.pointSize: Appearance.font.size.large - font.weight: 500 - } - } - - // General Settings Section - GeneralSection { - rootItem: root - } - - // Performance Resources Section - PerformanceSection { - rootItem: root - } - } - } - } -} diff --git a/modules/controlcenter/dashboard/GeneralSection.qml b/modules/controlcenter/dashboard/GeneralSection.qml deleted file mode 100644 index 95e7531..0000000 --- a/modules/controlcenter/dashboard/GeneralSection.qml +++ /dev/null @@ -1,128 +0,0 @@ -import ".." -import "../components" -import qs.components -import qs.components.controls -import qs.services -import qs.config -import QtQuick -import QtQuick.Layouts - -SectionContainer { - id: root - - required property var rootItem - - Layout.fillWidth: true - alignTop: true - - StyledText { - text: qsTr("General Settings") - font.pointSize: Appearance.font.size.normal - } - - SwitchRow { - label: qsTr("Enabled") - checked: root.rootItem.enabled - onToggled: checked => { - root.rootItem.enabled = checked; - root.rootItem.saveConfig(); - } - } - - SwitchRow { - label: qsTr("Show on hover") - checked: root.rootItem.showOnHover - onToggled: checked => { - root.rootItem.showOnHover = checked; - root.rootItem.saveConfig(); - } - } - - RowLayout { - Layout.fillWidth: true - spacing: Appearance.spacing.normal - - SwitchRow { - Layout.fillWidth: true - label: qsTr("Show Dashboard tab") - checked: root.rootItem.showDashboard - onToggled: checked => { - root.rootItem.showDashboard = checked; - root.rootItem.saveConfig(); - } - } - - SwitchRow { - Layout.fillWidth: true - label: qsTr("Show Media tab") - checked: root.rootItem.showMedia - onToggled: checked => { - root.rootItem.showMedia = checked; - root.rootItem.saveConfig(); - } - } - - SwitchRow { - Layout.fillWidth: true - label: qsTr("Show Performance tab") - checked: root.rootItem.showPerformance - onToggled: checked => { - root.rootItem.showPerformance = checked; - root.rootItem.saveConfig(); - } - } - - SwitchRow { - Layout.fillWidth: true - label: qsTr("Show Weather tab") - checked: root.rootItem.showWeather - onToggled: checked => { - root.rootItem.showWeather = checked; - root.rootItem.saveConfig(); - } - } - } - - SliderInput { - Layout.fillWidth: true - - label: qsTr("Media update interval") - value: root.rootItem.mediaUpdateInterval - from: 100 - to: 10000 - stepSize: 100 - suffix: "ms" - validator: IntValidator { - bottom: 100 - top: 10000 - } - formatValueFunction: val => Math.round(val).toString() - parseValueFunction: text => parseInt(text) - - onValueModified: newValue => { - root.rootItem.mediaUpdateInterval = Math.round(newValue); - root.rootItem.saveConfig(); - } - } - - SliderInput { - Layout.fillWidth: true - - label: qsTr("Drag threshold") - value: root.rootItem.dragThreshold - from: 0 - to: 100 - suffix: "px" - validator: IntValidator { - bottom: 0 - top: 100 - } - formatValueFunction: val => Math.round(val).toString() - parseValueFunction: text => parseInt(text) - - onValueModified: newValue => { - root.rootItem.dragThreshold = Math.round(newValue); - root.rootItem.saveConfig(); - } - } -} diff --git a/modules/controlcenter/dashboard/PerformanceSection.qml b/modules/controlcenter/dashboard/PerformanceSection.qml deleted file mode 100644 index ac84752..0000000 --- a/modules/controlcenter/dashboard/PerformanceSection.qml +++ /dev/null @@ -1,106 +0,0 @@ -import ".." -import "../components" -import QtQuick -import QtQuick.Layouts -import Quickshell.Services.UPower -import qs.components -import qs.components.controls -import qs.config -import qs.services - -SectionContainer { - id: root - - required property var rootItem - // GPU toggle is hidden when gpuType is "NONE" (no GPU data available) - readonly property bool gpuAvailable: SystemUsage.gpuType !== "NONE" - // Battery toggle is hidden when no laptop battery is present - readonly property bool batteryAvailable: UPower.displayDevice.isLaptopBattery - - Layout.fillWidth: true - alignTop: true - - StyledText { - text: qsTr("Performance Resources") - font.pointSize: Appearance.font.size.normal - } - - ConnectedButtonGroup { - rootItem: root.rootItem - options: { - let opts = []; - if (root.batteryAvailable) - opts.push({ - "label": qsTr("Battery"), - "propertyName": "showBattery", - "onToggled": function (checked) { - root.rootItem.showBattery = checked; - root.rootItem.saveConfig(); - } - }); - - if (root.gpuAvailable) - opts.push({ - "label": qsTr("GPU"), - "propertyName": "showGpu", - "onToggled": function (checked) { - root.rootItem.showGpu = checked; - root.rootItem.saveConfig(); - } - }); - - opts.push({ - "label": qsTr("CPU"), - "propertyName": "showCpu", - "onToggled": function (checked) { - root.rootItem.showCpu = checked; - root.rootItem.saveConfig(); - } - }, { - "label": qsTr("Memory"), - "propertyName": "showMemory", - "onToggled": function (checked) { - root.rootItem.showMemory = checked; - root.rootItem.saveConfig(); - } - }, { - "label": qsTr("Storage"), - "propertyName": "showStorage", - "onToggled": function (checked) { - root.rootItem.showStorage = checked; - root.rootItem.saveConfig(); - } - }, { - "label": qsTr("Network"), - "propertyName": "showNetwork", - "onToggled": function (checked) { - root.rootItem.showNetwork = checked; - root.rootItem.saveConfig(); - } - }); - return opts; - } - } - - SliderInput { - Layout.fillWidth: true - - label: qsTr("Resource update interval") - value: root.rootItem.resourceUpdateInterval - from: 100 - to: 10000 - stepSize: 100 - suffix: "ms" - validator: IntValidator { - bottom: 100 - top: 10000 - } - formatValueFunction: val => Math.round(val).toString() - parseValueFunction: text => parseInt(text) - - onValueModified: newValue => { - root.rootItem.resourceUpdateInterval = Math.round(newValue); - root.rootItem.saveConfig(); - } - } -} diff --git a/modules/controlcenter/network/EthernetDetails.qml b/modules/controlcenter/network/EthernetDetails.qml deleted file mode 100644 index 4e60b3d..0000000 --- a/modules/controlcenter/network/EthernetDetails.qml +++ /dev/null @@ -1,118 +0,0 @@ -pragma ComponentBehavior: Bound - -import ".." -import "../components" -import qs.components -import qs.components.controls -import qs.components.effects -import qs.components.containers -import qs.services -import qs.config -import QtQuick -import QtQuick.Layouts - -DeviceDetails { - id: root - - required property Session session - readonly property var ethernetDevice: root.session.ethernet.active - - device: ethernetDevice - - Component.onCompleted: { - if (ethernetDevice && ethernetDevice.interface) { - Nmcli.getEthernetDeviceDetails(ethernetDevice.interface, () => {}); - } - } - - onEthernetDeviceChanged: { - if (ethernetDevice && ethernetDevice.interface) { - Nmcli.getEthernetDeviceDetails(ethernetDevice.interface, () => {}); - } else { - Nmcli.ethernetDeviceDetails = null; - } - } - - headerComponent: Component { - ConnectionHeader { - icon: "cable" - title: root.ethernetDevice?.interface ?? qsTr("Unknown") - } - } - - sections: [ - Component { - ColumnLayout { - spacing: Appearance.spacing.normal - - SectionHeader { - title: qsTr("Connection status") - description: qsTr("Connection settings for this device") - } - - SectionContainer { - ToggleRow { - label: qsTr("Connected") - checked: root.ethernetDevice?.connected ?? false - toggle.onToggled: { - if (checked) { - Nmcli.connectEthernet(root.ethernetDevice?.connection || "", root.ethernetDevice?.interface || "", () => {}); - } else { - if (root.ethernetDevice?.connection) { - Nmcli.disconnectEthernet(root.ethernetDevice.connection, () => {}); - } - } - } - } - } - } - }, - Component { - ColumnLayout { - spacing: Appearance.spacing.normal - - SectionHeader { - title: qsTr("Device properties") - description: qsTr("Additional information") - } - - SectionContainer { - contentSpacing: Appearance.spacing.small / 2 - - PropertyRow { - label: qsTr("Interface") - value: root.ethernetDevice?.interface ?? qsTr("Unknown") - } - - PropertyRow { - showTopMargin: true - label: qsTr("Connection") - value: root.ethernetDevice?.connection || qsTr("Not connected") - } - - PropertyRow { - showTopMargin: true - label: qsTr("State") - value: root.ethernetDevice?.state ?? qsTr("Unknown") - } - } - } - }, - Component { - ColumnLayout { - spacing: Appearance.spacing.normal - - SectionHeader { - title: qsTr("Connection information") - description: qsTr("Network connection details") - } - - SectionContainer { - ConnectionInfoSection { - deviceDetails: Nmcli.ethernetDeviceDetails - } - } - } - } - ] -} diff --git a/modules/controlcenter/network/EthernetList.qml b/modules/controlcenter/network/EthernetList.qml deleted file mode 100644 index d1eb957..0000000 --- a/modules/controlcenter/network/EthernetList.qml +++ /dev/null @@ -1,177 +0,0 @@ -pragma ComponentBehavior: Bound - -import ".." -import "../components" -import qs.components -import qs.components.controls -import qs.components.containers -import qs.services -import qs.config -import QtQuick -import QtQuick.Layouts - -DeviceList { - id: root - - required property Session session - - title: qsTr("Devices (%1)").arg(Nmcli.ethernetDevices.length) - description: qsTr("All available ethernet devices") - activeItem: session.ethernet.active - - model: Nmcli.ethernetDevices - - headerComponent: Component { - RowLayout { - spacing: Appearance.spacing.smaller - - StyledText { - text: qsTr("Settings") - font.pointSize: Appearance.font.size.large - font.weight: 500 - } - - Item { - Layout.fillWidth: true - } - - ToggleButton { - toggled: !root.session.ethernet.active - icon: "settings" - accent: "Primary" - iconSize: Appearance.font.size.normal - horizontalPadding: Appearance.padding.normal - verticalPadding: Appearance.padding.smaller - - onClicked: { - if (root.session.ethernet.active) - root.session.ethernet.active = null; - else { - root.session.ethernet.active = root.view.model.get(0)?.modelData ?? null; - } - } - } - } - } - - delegate: Component { - StyledRect { - id: ethernetItem - - required property var modelData - readonly property bool isActive: root.activeItem && modelData && root.activeItem.interface === modelData.interface - - width: ListView.view ? ListView.view.width : undefined - implicitHeight: rowLayout.implicitHeight + Appearance.padding.normal * 2 - - color: Qt.alpha(Colours.tPalette.m3surfaceContainer, ethernetItem.isActive ? Colours.tPalette.m3surfaceContainer.a : 0) - radius: Appearance.rounding.normal - - StateLayer { - id: stateLayer - - function onClicked(): void { - root.session.ethernet.active = modelData; - } - } - - RowLayout { - id: rowLayout - - anchors.fill: parent - anchors.margins: Appearance.padding.normal - - spacing: Appearance.spacing.normal - - StyledRect { - implicitWidth: implicitHeight - implicitHeight: icon.implicitHeight + Appearance.padding.normal * 2 - - radius: Appearance.rounding.normal - color: modelData.connected ? Colours.palette.m3primaryContainer : Colours.tPalette.m3surfaceContainerHigh - - StyledRect { - anchors.fill: parent - radius: parent.radius - color: Qt.alpha(modelData.connected ? Colours.palette.m3onPrimaryContainer : Colours.palette.m3onSurface, stateLayer.pressed ? 0.1 : stateLayer.containsMouse ? 0.08 : 0) - } - - MaterialIcon { - id: icon - - anchors.centerIn: parent - text: "cable" - font.pointSize: Appearance.font.size.large - fill: modelData.connected ? 1 : 0 - color: modelData.connected ? Colours.palette.m3onPrimaryContainer : Colours.palette.m3onSurface - - Behavior on fill { - Anim {} - } - } - } - - ColumnLayout { - Layout.fillWidth: true - - spacing: 0 - - StyledText { - Layout.fillWidth: true - text: modelData.interface || qsTr("Unknown") - elide: Text.ElideRight - } - - RowLayout { - Layout.fillWidth: true - spacing: Appearance.spacing.smaller - - StyledText { - Layout.fillWidth: true - text: modelData.connected ? qsTr("Connected") : qsTr("Disconnected") - color: modelData.connected ? Colours.palette.m3primary : Colours.palette.m3outline - font.pointSize: Appearance.font.size.small - font.weight: modelData.connected ? 500 : 400 - elide: Text.ElideRight - } - } - } - - StyledRect { - id: connectBtn - - implicitWidth: implicitHeight - implicitHeight: connectIcon.implicitHeight + Appearance.padding.smaller * 2 - - radius: Appearance.rounding.full - color: Qt.alpha(Colours.palette.m3primaryContainer, modelData.connected ? 1 : 0) - - StateLayer { - color: modelData.connected ? Colours.palette.m3onPrimaryContainer : Colours.palette.m3onSurface - - function onClicked(): void { - if (modelData.connected && modelData.connection) { - Nmcli.disconnectEthernet(modelData.connection, () => {}); - } else { - Nmcli.connectEthernet(modelData.connection || "", modelData.interface || "", () => {}); - } - } - } - - MaterialIcon { - id: connectIcon - - anchors.centerIn: parent - animate: true - text: modelData.connected ? "link_off" : "link" - color: modelData.connected ? Colours.palette.m3onPrimaryContainer : Colours.palette.m3onSurface - } - } - } - } - } - - onItemSelected: function (item) { - session.ethernet.active = item; - } -} diff --git a/modules/controlcenter/network/EthernetPane.qml b/modules/controlcenter/network/EthernetPane.qml deleted file mode 100644 index 59d82bb..0000000 --- a/modules/controlcenter/network/EthernetPane.qml +++ /dev/null @@ -1,50 +0,0 @@ -pragma ComponentBehavior: Bound - -import ".." -import "../components" -import qs.components -import qs.components.containers -import qs.config -import Quickshell.Widgets -import QtQuick - -SplitPaneWithDetails { - id: root - - required property Session session - - anchors.fill: parent - - activeItem: session.ethernet.active - paneIdGenerator: function (item) { - return item ? (item.interface || "") : ""; - } - - leftContent: Component { - EthernetList { - session: root.session - } - } - - rightDetailsComponent: Component { - EthernetDetails { - session: root.session - } - } - - rightSettingsComponent: Component { - StyledFlickable { - flickableDirection: Flickable.VerticalFlick - contentHeight: settingsInner.height - clip: true - - EthernetSettings { - id: settingsInner - - anchors.left: parent.left - anchors.right: parent.right - session: root.session - } - } - } -} diff --git a/modules/controlcenter/network/EthernetSettings.qml b/modules/controlcenter/network/EthernetSettings.qml deleted file mode 100644 index 90bfcf4..0000000 --- a/modules/controlcenter/network/EthernetSettings.qml +++ /dev/null @@ -1,76 +0,0 @@ -pragma ComponentBehavior: Bound - -import ".." -import "../components" -import qs.components -import qs.components.controls -import qs.components.effects -import qs.services -import qs.config -import QtQuick -import QtQuick.Layouts - -ColumnLayout { - id: root - - required property Session session - - spacing: Appearance.spacing.normal - - SettingsHeader { - icon: "cable" - title: qsTr("Ethernet settings") - } - - StyledText { - Layout.topMargin: Appearance.spacing.large - text: qsTr("Ethernet devices") - font.pointSize: Appearance.font.size.larger - font.weight: 500 - } - - StyledText { - text: qsTr("Available ethernet devices") - color: Colours.palette.m3outline - } - - StyledRect { - Layout.fillWidth: true - implicitHeight: ethernetInfo.implicitHeight + Appearance.padding.large * 2 - - radius: Appearance.rounding.normal - color: Colours.tPalette.m3surfaceContainer - - ColumnLayout { - id: ethernetInfo - - anchors.left: parent.left - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - anchors.margins: Appearance.padding.large - - spacing: Appearance.spacing.small / 2 - - StyledText { - text: qsTr("Total devices") - } - - StyledText { - text: qsTr("%1").arg(Nmcli.ethernetDevices.length) - color: Colours.palette.m3outline - font.pointSize: Appearance.font.size.small - } - - StyledText { - Layout.topMargin: Appearance.spacing.normal - text: qsTr("Connected devices") - } - - StyledText { - text: qsTr("%1").arg(Nmcli.ethernetDevices.filter(d => d.connected).length) - color: Colours.palette.m3outline - font.pointSize: Appearance.font.size.small - } - } - } -} diff --git a/modules/controlcenter/network/NetworkSettings.qml b/modules/controlcenter/network/NetworkSettings.qml deleted file mode 100644 index 69f4e63..0000000 --- a/modules/controlcenter/network/NetworkSettings.qml +++ /dev/null @@ -1,99 +0,0 @@ -pragma ComponentBehavior: Bound - -import ".." -import "../components" -import qs.components -import qs.components.controls -import qs.components.containers -import qs.components.effects -import qs.services -import qs.config -import QtQuick -import QtQuick.Controls -import QtQuick.Layouts - -ColumnLayout { - id: root - - required property Session session - - spacing: Appearance.spacing.normal - - SettingsHeader { - icon: "router" - title: qsTr("Network Settings") - } - - SectionHeader { - Layout.topMargin: Appearance.spacing.large - title: qsTr("Ethernet") - description: qsTr("Ethernet device information") - } - - SectionContainer { - contentSpacing: Appearance.spacing.small / 2 - - PropertyRow { - label: qsTr("Total devices") - value: qsTr("%1").arg(Nmcli.ethernetDevices.length) - } - - PropertyRow { - showTopMargin: true - label: qsTr("Connected devices") - value: qsTr("%1").arg(Nmcli.ethernetDevices.filter(d => d.connected).length) - } - } - - SectionHeader { - Layout.topMargin: Appearance.spacing.large - title: qsTr("Wireless") - description: qsTr("WiFi network settings") - } - - SectionContainer { - ToggleRow { - label: qsTr("WiFi enabled") - checked: Nmcli.wifiEnabled - toggle.onToggled: { - Nmcli.enableWifi(checked); - } - } - } - - SectionHeader { - Layout.topMargin: Appearance.spacing.large - title: qsTr("Current connection") - description: qsTr("Active network connection information") - } - - SectionContainer { - contentSpacing: Appearance.spacing.small / 2 - - PropertyRow { - label: qsTr("Network") - value: Nmcli.active ? Nmcli.active.ssid : (Nmcli.activeEthernet ? Nmcli.activeEthernet.interface : qsTr("Not connected")) - } - - PropertyRow { - showTopMargin: true - visible: Nmcli.active !== null - label: qsTr("Signal strength") - value: Nmcli.active ? qsTr("%1%").arg(Nmcli.active.strength) : qsTr("N/A") - } - - PropertyRow { - showTopMargin: true - visible: Nmcli.active !== null - label: qsTr("Security") - value: Nmcli.active ? (Nmcli.active.isSecure ? qsTr("Secured") : qsTr("Open")) : qsTr("N/A") - } - - PropertyRow { - showTopMargin: true - visible: Nmcli.active !== null - label: qsTr("Frequency") - value: Nmcli.active ? qsTr("%1 MHz").arg(Nmcli.active.frequency) : qsTr("N/A") - } - } -} diff --git a/modules/controlcenter/network/NetworkingPane.qml b/modules/controlcenter/network/NetworkingPane.qml deleted file mode 100644 index c32fbb7..0000000 --- a/modules/controlcenter/network/NetworkingPane.qml +++ /dev/null @@ -1,309 +0,0 @@ -pragma ComponentBehavior: Bound - -import ".." -import "../components" -import "." -import qs.components -import qs.components.controls -import qs.components.effects -import qs.components.containers -import qs.services -import qs.config -import qs.utils -import Quickshell -import Quickshell.Widgets -import QtQuick -import QtQuick.Layouts - -Item { - id: root - - required property Session session - - anchors.fill: parent - - SplitPaneLayout { - id: splitLayout - - anchors.fill: parent - - leftContent: Component { - StyledFlickable { - id: leftFlickable - - flickableDirection: Flickable.VerticalFlick - contentHeight: leftContent.height - - StyledScrollBar.vertical: StyledScrollBar { - flickable: leftFlickable - } - - ColumnLayout { - id: leftContent - - anchors.left: parent.left - anchors.right: parent.right - spacing: Appearance.spacing.normal - - RowLayout { - Layout.fillWidth: true - spacing: Appearance.spacing.smaller - - StyledText { - text: qsTr("Network") - font.pointSize: Appearance.font.size.large - font.weight: 500 - } - - Item { - Layout.fillWidth: true - } - - ToggleButton { - toggled: Nmcli.wifiEnabled - icon: "wifi" - accent: "Tertiary" - iconSize: Appearance.font.size.normal - horizontalPadding: Appearance.padding.normal - verticalPadding: Appearance.padding.smaller - tooltip: qsTr("Toggle WiFi") - - onClicked: { - Nmcli.toggleWifi(null); - } - } - - ToggleButton { - toggled: Nmcli.scanning - icon: "wifi_find" - accent: "Secondary" - iconSize: Appearance.font.size.normal - horizontalPadding: Appearance.padding.normal - verticalPadding: Appearance.padding.smaller - tooltip: qsTr("Scan for networks") - - onClicked: { - Nmcli.rescanWifi(); - } - } - - ToggleButton { - toggled: !root.session.ethernet.active && !root.session.network.active - icon: "settings" - accent: "Primary" - iconSize: Appearance.font.size.normal - horizontalPadding: Appearance.padding.normal - verticalPadding: Appearance.padding.smaller - tooltip: qsTr("Network settings") - - onClicked: { - if (root.session.ethernet.active || root.session.network.active) { - root.session.ethernet.active = null; - root.session.network.active = null; - } else { - if (Nmcli.ethernetDevices.length > 0) { - root.session.ethernet.active = Nmcli.ethernetDevices[0]; - } else if (Nmcli.networks.length > 0) { - root.session.network.active = Nmcli.networks[0]; - } - } - } - } - } - - CollapsibleSection { - id: ethernetListSection - - Layout.fillWidth: true - title: qsTr("Ethernet") - expanded: true - - Loader { - Layout.fillWidth: true - sourceComponent: Component { - EthernetList { - session: root.session - showHeader: false - } - } - } - } - - CollapsibleSection { - id: wirelessListSection - - Layout.fillWidth: true - title: qsTr("Wireless") - expanded: true - - Loader { - Layout.fillWidth: true - sourceComponent: Component { - WirelessList { - session: root.session - showHeader: false - } - } - } - } - } - } - } - - rightContent: Component { - Item { - id: rightPaneItem - - property var ethernetPane: root.session && root.session.ethernet ? root.session.ethernet.active : null - property var wirelessPane: root.session && root.session.network ? root.session.network.active : null - property var pane: ethernetPane || wirelessPane - property string paneId: ethernetPane ? ("eth:" + (ethernetPane.interface || "")) : (wirelessPane ? ("wifi:" + (wirelessPane.ssid || wirelessPane.bssid || "")) : "settings") - property Component targetComponent: settingsComponent - property Component nextComponent: settingsComponent - - function getComponentForPane() { - if (ethernetPane) - return ethernetDetailsComponent; - if (wirelessPane) - return wirelessDetailsComponent; - return settingsComponent; - } - - Component.onCompleted: { - targetComponent = getComponentForPane(); - nextComponent = targetComponent; - } - - Connections { - target: root.session && root.session.ethernet ? root.session.ethernet : null - enabled: target !== null - - function onActiveChanged() { - // Clear others when ethernet is selected - if (root.session && root.session.ethernet && root.session.ethernet.active) { - if (root.session.network && root.session.network.active) - root.session.network.active = null; - } - rightPaneItem.nextComponent = rightPaneItem.getComponentForPane(); - } - } - - Connections { - target: root.session && root.session.network ? root.session.network : null - enabled: target !== null - - function onActiveChanged() { - // Clear others when wireless is selected - if (root.session && root.session.network && root.session.network.active) { - if (root.session.ethernet && root.session.ethernet.active) - root.session.ethernet.active = null; - } - rightPaneItem.nextComponent = rightPaneItem.getComponentForPane(); - } - } - - Loader { - id: rightLoader - - anchors.fill: parent - - opacity: 1 - scale: 1 - transformOrigin: Item.Center - clip: false - - asynchronous: true - sourceComponent: rightPaneItem.targetComponent - } - - Behavior on paneId { - PaneTransition { - target: rightLoader - propertyActions: [ - PropertyAction { - target: rightPaneItem - property: "targetComponent" - value: rightPaneItem.nextComponent - } - ] - } - } - } - } - } - - Component { - id: settingsComponent - - StyledFlickable { - id: settingsFlickable - flickableDirection: Flickable.VerticalFlick - contentHeight: settingsInner.height - - StyledScrollBar.vertical: StyledScrollBar { - flickable: settingsFlickable - } - - NetworkSettings { - id: settingsInner - - anchors.left: parent.left - anchors.right: parent.right - anchors.top: parent.top - session: root.session - } - } - } - - Component { - id: ethernetDetailsComponent - - StyledFlickable { - id: ethernetFlickable - flickableDirection: Flickable.VerticalFlick - contentHeight: ethernetDetailsInner.height - - StyledScrollBar.vertical: StyledScrollBar { - flickable: ethernetFlickable - } - - EthernetDetails { - id: ethernetDetailsInner - - anchors.left: parent.left - anchors.right: parent.right - anchors.top: parent.top - session: root.session - } - } - } - - Component { - id: wirelessDetailsComponent - - StyledFlickable { - id: wirelessFlickable - flickableDirection: Flickable.VerticalFlick - contentHeight: wirelessDetailsInner.height - - StyledScrollBar.vertical: StyledScrollBar { - flickable: wirelessFlickable - } - - WirelessDetails { - id: wirelessDetailsInner - - anchors.left: parent.left - anchors.right: parent.right - anchors.top: parent.top - session: root.session - } - } - } - - WirelessPasswordDialog { - anchors.fill: parent - session: root.session - z: 1000 - } -} diff --git a/modules/controlcenter/network/WirelessDetails.qml b/modules/controlcenter/network/WirelessDetails.qml deleted file mode 100644 index e8777cd..0000000 --- a/modules/controlcenter/network/WirelessDetails.qml +++ /dev/null @@ -1,211 +0,0 @@ -pragma ComponentBehavior: Bound - -import ".." -import "../components" -import "." -import qs.components -import qs.components.controls -import qs.components.effects -import qs.components.containers -import qs.services -import qs.config -import qs.utils -import QtQuick -import QtQuick.Layouts - -DeviceDetails { - id: root - - required property Session session - readonly property var network: root.session.network.active - - device: network - - Component.onCompleted: { - updateDeviceDetails(); - checkSavedProfile(); - } - - onNetworkChanged: { - connectionUpdateTimer.stop(); - if (network && network.ssid) { - connectionUpdateTimer.start(); - } - updateDeviceDetails(); - checkSavedProfile(); - } - - function checkSavedProfile(): void { - if (network && network.ssid) { - Nmcli.loadSavedConnections(() => {}); - } - } - - Connections { - target: Nmcli - function onActiveChanged() { - updateDeviceDetails(); - } - function onWirelessDeviceDetailsChanged() { - if (network && network.ssid) { - const isActive = network.active || (Nmcli.active && Nmcli.active.ssid === network.ssid); - if (isActive && Nmcli.wirelessDeviceDetails && Nmcli.wirelessDeviceDetails !== null) { - connectionUpdateTimer.stop(); - } - } - } - } - - Timer { - id: connectionUpdateTimer - interval: 500 - repeat: true - running: network && network.ssid - onTriggered: { - if (network) { - const isActive = network.active || (Nmcli.active && Nmcli.active.ssid === network.ssid); - if (isActive) { - if (!Nmcli.wirelessDeviceDetails || Nmcli.wirelessDeviceDetails === null) { - Nmcli.getWirelessDeviceDetails("", () => {}); - } else { - connectionUpdateTimer.stop(); - } - } else { - if (Nmcli.wirelessDeviceDetails !== null) { - Nmcli.wirelessDeviceDetails = null; - } - } - } - } - } - - function updateDeviceDetails(): void { - if (network && network.ssid) { - const isActive = network.active || (Nmcli.active && Nmcli.active.ssid === network.ssid); - if (isActive) { - Nmcli.getWirelessDeviceDetails(""); - } else { - Nmcli.wirelessDeviceDetails = null; - } - } else { - Nmcli.wirelessDeviceDetails = null; - } - } - - headerComponent: Component { - ConnectionHeader { - icon: root.network?.isSecure ? "lock" : "wifi" - title: root.network?.ssid ?? qsTr("Unknown") - } - } - - sections: [ - Component { - ColumnLayout { - spacing: Appearance.spacing.normal - - SectionHeader { - title: qsTr("Connection status") - description: qsTr("Connection settings for this network") - } - - SectionContainer { - ToggleRow { - label: qsTr("Connected") - checked: root.network?.active ?? false - toggle.onToggled: { - if (checked) { - NetworkConnection.handleConnect(root.network, root.session, null); - } else { - Nmcli.disconnectFromNetwork(); - } - } - } - - TextButton { - Layout.fillWidth: true - Layout.topMargin: Appearance.spacing.normal - Layout.minimumHeight: Appearance.font.size.normal + Appearance.padding.normal * 2 - visible: { - if (!root.network || !root.network.ssid) { - return false; - } - return Nmcli.hasSavedProfile(root.network.ssid); - } - inactiveColour: Colours.palette.m3secondaryContainer - inactiveOnColour: Colours.palette.m3onSecondaryContainer - text: qsTr("Forget Network") - - onClicked: { - if (root.network && root.network.ssid) { - if (root.network.active) { - Nmcli.disconnectFromNetwork(); - } - Nmcli.forgetNetwork(root.network.ssid); - } - } - } - } - } - }, - Component { - ColumnLayout { - spacing: Appearance.spacing.normal - - SectionHeader { - title: qsTr("Network properties") - description: qsTr("Additional information") - } - - SectionContainer { - contentSpacing: Appearance.spacing.small / 2 - - PropertyRow { - label: qsTr("SSID") - value: root.network?.ssid ?? qsTr("Unknown") - } - - PropertyRow { - showTopMargin: true - label: qsTr("BSSID") - value: root.network?.bssid ?? qsTr("Unknown") - } - - PropertyRow { - showTopMargin: true - label: qsTr("Signal strength") - value: root.network ? qsTr("%1%").arg(root.network.strength) : qsTr("N/A") - } - - PropertyRow { - showTopMargin: true - label: qsTr("Frequency") - value: root.network ? qsTr("%1 MHz").arg(root.network.frequency) : qsTr("N/A") - } - - PropertyRow { - showTopMargin: true - label: qsTr("Security") - value: root.network ? (root.network.isSecure ? root.network.security : qsTr("Open")) : qsTr("N/A") - } - } - } - }, - Component { - ColumnLayout { - spacing: Appearance.spacing.normal - - SectionHeader { - title: qsTr("Connection information") - description: qsTr("Network connection details") - } - - SectionContainer { - ConnectionInfoSection { - deviceDetails: Nmcli.wirelessDeviceDetails - } - } - } - } - ] -} diff --git a/modules/controlcenter/network/WirelessList.qml b/modules/controlcenter/network/WirelessList.qml deleted file mode 100644 index 57a155f..0000000 --- a/modules/controlcenter/network/WirelessList.qml +++ /dev/null @@ -1,228 +0,0 @@ -pragma ComponentBehavior: Bound - -import ".." -import "../components" -import "." -import qs.components -import qs.components.controls -import qs.components.containers -import qs.components.effects -import qs.services -import qs.config -import qs.utils -import Quickshell -import QtQuick -import QtQuick.Layouts - -DeviceList { - id: root - - required property Session session - - title: qsTr("Networks (%1)").arg(Nmcli.networks.length) - description: qsTr("All available WiFi networks") - activeItem: session.network.active - - titleSuffix: Component { - StyledText { - visible: Nmcli.scanning - text: qsTr("Scanning...") - color: Colours.palette.m3primary - font.pointSize: Appearance.font.size.small - } - } - - model: ScriptModel { - values: [...Nmcli.networks].sort((a, b) => { - if (a.active !== b.active) - return b.active - a.active; - return b.strength - a.strength; - }) - } - - headerComponent: Component { - RowLayout { - spacing: Appearance.spacing.smaller - - StyledText { - text: qsTr("Settings") - font.pointSize: Appearance.font.size.large - font.weight: 500 - } - - Item { - Layout.fillWidth: true - } - - ToggleButton { - toggled: Nmcli.wifiEnabled - icon: "wifi" - accent: "Tertiary" - iconSize: Appearance.font.size.normal - horizontalPadding: Appearance.padding.normal - verticalPadding: Appearance.padding.smaller - - onClicked: { - Nmcli.toggleWifi(null); - } - } - - ToggleButton { - toggled: Nmcli.scanning - icon: "wifi_find" - accent: "Secondary" - iconSize: Appearance.font.size.normal - horizontalPadding: Appearance.padding.normal - verticalPadding: Appearance.padding.smaller - - onClicked: { - Nmcli.rescanWifi(); - } - } - - ToggleButton { - toggled: !root.session.network.active - icon: "settings" - accent: "Primary" - iconSize: Appearance.font.size.normal - horizontalPadding: Appearance.padding.normal - verticalPadding: Appearance.padding.smaller - - onClicked: { - if (root.session.network.active) - root.session.network.active = null; - else { - root.session.network.active = root.view.model.get(0)?.modelData ?? null; - } - } - } - } - } - - delegate: Component { - StyledRect { - required property var modelData - - width: ListView.view ? ListView.view.width : undefined - - color: Qt.alpha(Colours.tPalette.m3surfaceContainer, root.activeItem === modelData ? Colours.tPalette.m3surfaceContainer.a : 0) - radius: Appearance.rounding.normal - - StateLayer { - function onClicked(): void { - root.session.network.active = modelData; - if (modelData && modelData.ssid) { - root.checkSavedProfileForNetwork(modelData.ssid); - } - } - } - - RowLayout { - id: rowLayout - - anchors.left: parent.left - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - anchors.margins: Appearance.padding.normal - - spacing: Appearance.spacing.normal - - StyledRect { - implicitWidth: implicitHeight - implicitHeight: icon.implicitHeight + Appearance.padding.normal * 2 - - radius: Appearance.rounding.normal - color: modelData.active ? Colours.palette.m3primaryContainer : Colours.tPalette.m3surfaceContainerHigh - - MaterialIcon { - id: icon - - anchors.centerIn: parent - text: Icons.getNetworkIcon(modelData.strength, modelData.isSecure) - font.pointSize: Appearance.font.size.large - fill: modelData.active ? 1 : 0 - color: modelData.active ? Colours.palette.m3onPrimaryContainer : Colours.palette.m3onSurface - } - } - - ColumnLayout { - Layout.fillWidth: true - - spacing: 0 - - StyledText { - Layout.fillWidth: true - elide: Text.ElideRight - maximumLineCount: 1 - - text: modelData.ssid || qsTr("Unknown") - } - - RowLayout { - Layout.fillWidth: true - spacing: Appearance.spacing.smaller - - StyledText { - Layout.fillWidth: true - text: { - if (modelData.active) - return qsTr("Connected"); - if (modelData.isSecure && modelData.security && modelData.security.length > 0) { - return modelData.security; - } - if (modelData.isSecure) - return qsTr("Secured"); - return qsTr("Open"); - } - color: modelData.active ? Colours.palette.m3primary : Colours.palette.m3outline - font.pointSize: Appearance.font.size.small - font.weight: modelData.active ? 500 : 400 - elide: Text.ElideRight - } - } - } - - StyledRect { - implicitWidth: implicitHeight - implicitHeight: connectIcon.implicitHeight + Appearance.padding.smaller * 2 - - radius: Appearance.rounding.full - color: Qt.alpha(Colours.palette.m3primaryContainer, modelData.active ? 1 : 0) - - StateLayer { - function onClicked(): void { - if (modelData.active) { - Nmcli.disconnectFromNetwork(); - } else { - NetworkConnection.handleConnect(modelData, root.session, null); - } - } - } - - MaterialIcon { - id: connectIcon - - anchors.centerIn: parent - text: modelData.active ? "link_off" : "link" - color: modelData.active ? Colours.palette.m3onPrimaryContainer : Colours.palette.m3onSurface - } - } - } - - implicitHeight: rowLayout.implicitHeight + Appearance.padding.normal * 2 - } - } - - onItemSelected: function (item) { - session.network.active = item; - if (item && item.ssid) { - checkSavedProfileForNetwork(item.ssid); - } - } - - function checkSavedProfileForNetwork(ssid: string): void { - if (ssid && ssid.length > 0) { - Nmcli.loadSavedConnections(() => {}); - } - } -} diff --git a/modules/controlcenter/network/WirelessPane.qml b/modules/controlcenter/network/WirelessPane.qml deleted file mode 100644 index 8150af9..0000000 --- a/modules/controlcenter/network/WirelessPane.qml +++ /dev/null @@ -1,57 +0,0 @@ -pragma ComponentBehavior: Bound - -import ".." -import "../components" -import qs.components -import qs.components.containers -import qs.config -import Quickshell.Widgets -import QtQuick - -SplitPaneWithDetails { - id: root - - required property Session session - - anchors.fill: parent - - activeItem: session.network.active - paneIdGenerator: function (item) { - return item ? (item.ssid || item.bssid || "") : ""; - } - - leftContent: Component { - WirelessList { - session: root.session - } - } - - rightDetailsComponent: Component { - WirelessDetails { - session: root.session - } - } - - rightSettingsComponent: Component { - StyledFlickable { - flickableDirection: Flickable.VerticalFlick - contentHeight: settingsInner.height - clip: true - - WirelessSettings { - id: settingsInner - - anchors.left: parent.left - anchors.right: parent.right - session: root.session - } - } - } - - overlayComponent: Component { - WirelessPasswordDialog { - anchors.fill: parent - session: root.session - } - } -} diff --git a/modules/controlcenter/network/WirelessPasswordDialog.qml b/modules/controlcenter/network/WirelessPasswordDialog.qml deleted file mode 100644 index 7ad5204..0000000 --- a/modules/controlcenter/network/WirelessPasswordDialog.qml +++ /dev/null @@ -1,511 +0,0 @@ -pragma ComponentBehavior: Bound - -import ".." -import "." -import qs.components -import qs.components.controls -import qs.components.effects -import qs.components.containers -import qs.services -import qs.config -import qs.utils -import Quickshell -import QtQuick -import QtQuick.Layouts - -Item { - id: root - - required property Session session - - readonly property var network: { - if (session.network.pendingNetwork) { - return session.network.pendingNetwork; - } - if (session.network.active) { - return session.network.active; - } - return null; - } - - property bool isClosing: false - visible: session.network.showPasswordDialog || isClosing - enabled: session.network.showPasswordDialog && !isClosing - focus: enabled - - Keys.onEscapePressed: { - closeDialog(); - } - - Rectangle { - anchors.fill: parent - color: Qt.rgba(0, 0, 0, 0.5) - opacity: root.session.network.showPasswordDialog && !root.isClosing ? 1 : 0 - - Behavior on opacity { - Anim {} - } - - MouseArea { - anchors.fill: parent - onClicked: closeDialog() - } - } - - StyledRect { - id: dialog - - anchors.centerIn: parent - - implicitWidth: 400 - implicitHeight: content.implicitHeight + Appearance.padding.large * 2 - - radius: Appearance.rounding.normal - color: Colours.tPalette.m3surface - opacity: root.session.network.showPasswordDialog && !root.isClosing ? 1 : 0 - scale: root.session.network.showPasswordDialog && !root.isClosing ? 1 : 0.7 - - Behavior on opacity { - Anim {} - } - - Behavior on scale { - Anim {} - } - - ParallelAnimation { - running: root.isClosing - onFinished: { - if (root.isClosing) { - root.session.network.showPasswordDialog = false; - root.isClosing = false; - } - } - - Anim { - target: dialog - property: "opacity" - to: 0 - } - Anim { - target: dialog - property: "scale" - to: 0.7 - } - } - - Keys.onEscapePressed: closeDialog() - - ColumnLayout { - id: content - - anchors.left: parent.left - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - anchors.margins: Appearance.padding.large - - spacing: Appearance.spacing.normal - - MaterialIcon { - Layout.alignment: Qt.AlignHCenter - text: "lock" - font.pointSize: Appearance.font.size.extraLarge * 2 - } - - StyledText { - Layout.alignment: Qt.AlignHCenter - text: qsTr("Enter password") - font.pointSize: Appearance.font.size.large - font.weight: 500 - } - - StyledText { - Layout.alignment: Qt.AlignHCenter - text: root.network ? qsTr("Network: %1").arg(root.network.ssid) : "" - color: Colours.palette.m3outline - font.pointSize: Appearance.font.size.small - } - - StyledText { - id: statusText - - Layout.alignment: Qt.AlignHCenter - Layout.topMargin: Appearance.spacing.small - visible: connectButton.connecting || connectButton.hasError - text: { - if (connectButton.hasError) { - return qsTr("Connection failed. Please check your password and try again."); - } - if (connectButton.connecting) { - return qsTr("Connecting..."); - } - return ""; - } - color: connectButton.hasError ? Colours.palette.m3error : Colours.palette.m3onSurfaceVariant - font.pointSize: Appearance.font.size.small - font.weight: 400 - wrapMode: Text.WordWrap - Layout.maximumWidth: parent.width - Appearance.padding.large * 2 - } - - Item { - id: passwordContainer - Layout.topMargin: Appearance.spacing.large - Layout.fillWidth: true - implicitHeight: Math.max(48, charList.implicitHeight + Appearance.padding.normal * 2) - - focus: true - Keys.onPressed: event => { - if (!activeFocus) { - forceActiveFocus(); - } - - if (connectButton.hasError && event.text && event.text.length > 0) { - connectButton.hasError = false; - } - - if (event.key === Qt.Key_Enter || event.key === Qt.Key_Return) { - if (connectButton.enabled) { - connectButton.clicked(); - } - event.accepted = true; - } else if (event.key === Qt.Key_Backspace) { - if (event.modifiers & Qt.ControlModifier) { - passwordBuffer = ""; - } else { - passwordBuffer = passwordBuffer.slice(0, -1); - } - event.accepted = true; - } else if (event.text && event.text.length > 0) { - passwordBuffer += event.text; - event.accepted = true; - } - } - - property string passwordBuffer: "" - - Connections { - target: root.session.network - function onShowPasswordDialogChanged(): void { - if (root.session.network.showPasswordDialog) { - Qt.callLater(() => { - passwordContainer.forceActiveFocus(); - passwordContainer.passwordBuffer = ""; - connectButton.hasError = false; - }); - } - } - } - - Connections { - target: root - function onVisibleChanged(): void { - if (root.visible) { - Qt.callLater(() => { - passwordContainer.forceActiveFocus(); - }); - } - } - } - - StyledRect { - anchors.fill: parent - radius: Appearance.rounding.normal - color: passwordContainer.activeFocus ? Qt.lighter(Colours.tPalette.m3surfaceContainer, 1.05) : Colours.tPalette.m3surfaceContainer - border.width: passwordContainer.activeFocus || connectButton.hasError ? 4 : (root.visible ? 1 : 0) - border.color: { - if (connectButton.hasError) { - return Colours.palette.m3error; - } - if (passwordContainer.activeFocus) { - return Colours.palette.m3primary; - } - return root.visible ? Colours.palette.m3outline : "transparent"; - } - - Behavior on border.color { - CAnim {} - } - - Behavior on border.width { - CAnim {} - } - - Behavior on color { - CAnim {} - } - } - - StateLayer { - hoverEnabled: false - cursorShape: Qt.IBeamCursor - - function onClicked(): void { - passwordContainer.forceActiveFocus(); - } - } - - StyledText { - id: placeholder - anchors.centerIn: parent - text: qsTr("Password") - color: Colours.palette.m3outline - font.pointSize: Appearance.font.size.normal - font.family: Appearance.font.family.mono - opacity: passwordContainer.passwordBuffer ? 0 : 1 - - Behavior on opacity { - Anim {} - } - } - - ListView { - id: charList - - readonly property int fullWidth: count * (implicitHeight + spacing) - spacing - - anchors.centerIn: parent - implicitWidth: fullWidth - implicitHeight: Appearance.font.size.normal - - orientation: Qt.Horizontal - spacing: Appearance.spacing.small / 2 - interactive: false - - model: ScriptModel { - values: passwordContainer.passwordBuffer.split("") - } - - delegate: StyledRect { - id: ch - - implicitWidth: implicitHeight - implicitHeight: charList.implicitHeight - - color: Colours.palette.m3onSurface - radius: Appearance.rounding.small / 2 - - opacity: 0 - scale: 0 - Component.onCompleted: { - opacity = 1; - scale = 1; - } - ListView.onRemove: removeAnim.start() - - SequentialAnimation { - id: removeAnim - - PropertyAction { - target: ch - property: "ListView.delayRemove" - value: true - } - ParallelAnimation { - Anim { - target: ch - property: "opacity" - to: 0 - } - Anim { - target: ch - property: "scale" - to: 0.5 - } - } - PropertyAction { - target: ch - property: "ListView.delayRemove" - value: false - } - } - - Behavior on opacity { - Anim {} - } - - Behavior on scale { - Anim { - duration: Appearance.anim.durations.expressiveFastSpatial - easing.bezierCurve: Appearance.anim.curves.expressiveFastSpatial - } - } - } - - Behavior on implicitWidth { - Anim {} - } - } - } - - RowLayout { - Layout.topMargin: Appearance.spacing.normal - Layout.fillWidth: true - spacing: Appearance.spacing.normal - - TextButton { - id: cancelButton - - Layout.fillWidth: true - Layout.minimumHeight: Appearance.font.size.normal + Appearance.padding.normal * 2 - inactiveColour: Colours.palette.m3secondaryContainer - inactiveOnColour: Colours.palette.m3onSecondaryContainer - text: qsTr("Cancel") - - onClicked: root.closeDialog() - } - - TextButton { - id: connectButton - - property bool connecting: false - property bool hasError: false - - Layout.fillWidth: true - Layout.minimumHeight: Appearance.font.size.normal + Appearance.padding.normal * 2 - inactiveColour: Colours.palette.m3primary - inactiveOnColour: Colours.palette.m3onPrimary - text: qsTr("Connect") - enabled: passwordContainer.passwordBuffer.length > 0 && !connecting - - onClicked: { - if (!root.network || connecting) { - return; - } - - const password = passwordContainer.passwordBuffer; - if (!password || password.length === 0) { - return; - } - - hasError = false; - connecting = true; - enabled = false; - text = qsTr("Connecting..."); - - NetworkConnection.connectWithPassword(root.network, password, result => { - if (result && result.success) {} else if (result && result.needsPassword) { - connectionMonitor.stop(); - connecting = false; - hasError = true; - enabled = true; - text = qsTr("Connect"); - passwordContainer.passwordBuffer = ""; - if (root.network && root.network.ssid) { - Nmcli.forgetNetwork(root.network.ssid); - } - } else { - connectionMonitor.stop(); - connecting = false; - hasError = true; - enabled = true; - text = qsTr("Connect"); - passwordContainer.passwordBuffer = ""; - if (root.network && root.network.ssid) { - Nmcli.forgetNetwork(root.network.ssid); - } - } - }); - - connectionMonitor.start(); - } - } - } - } - } - - function checkConnectionStatus(): void { - if (!root.visible || !connectButton.connecting) { - return; - } - - const isConnected = root.network && Nmcli.active && Nmcli.active.ssid && Nmcli.active.ssid.toLowerCase().trim() === root.network.ssid.toLowerCase().trim(); - - if (isConnected) { - connectionSuccessTimer.start(); - return; - } - - if (Nmcli.pendingConnection === null && connectButton.connecting) { - if (connectionMonitor.repeatCount > 10) { - connectionMonitor.stop(); - connectButton.connecting = false; - connectButton.hasError = true; - connectButton.enabled = true; - connectButton.text = qsTr("Connect"); - passwordContainer.passwordBuffer = ""; - if (root.network && root.network.ssid) { - Nmcli.forgetNetwork(root.network.ssid); - } - } - } - } - - Timer { - id: connectionMonitor - interval: 1000 - repeat: true - triggeredOnStart: false - property int repeatCount: 0 - - onTriggered: { - repeatCount++; - checkConnectionStatus(); - } - - onRunningChanged: { - if (!running) { - repeatCount = 0; - } - } - } - - Timer { - id: connectionSuccessTimer - interval: 500 - onTriggered: { - if (root.visible && Nmcli.active && Nmcli.active.ssid) { - const stillConnected = Nmcli.active.ssid.toLowerCase().trim() === root.network.ssid.toLowerCase().trim(); - if (stillConnected) { - connectionMonitor.stop(); - connectButton.connecting = false; - connectButton.text = qsTr("Connect"); - closeDialog(); - } - } - } - } - - Connections { - target: Nmcli - function onActiveChanged() { - if (root.visible) { - checkConnectionStatus(); - } - } - function onConnectionFailed(ssid: string) { - if (root.visible && root.network && root.network.ssid === ssid && connectButton.connecting) { - connectionMonitor.stop(); - connectButton.connecting = false; - connectButton.hasError = true; - connectButton.enabled = true; - connectButton.text = qsTr("Connect"); - passwordContainer.passwordBuffer = ""; - Nmcli.forgetNetwork(ssid); - } - } - } - - function closeDialog(): void { - if (isClosing) { - return; - } - - isClosing = true; - passwordContainer.passwordBuffer = ""; - connectButton.connecting = false; - connectButton.hasError = false; - connectButton.text = qsTr("Connect"); - connectionMonitor.stop(); - } -} diff --git a/modules/controlcenter/network/WirelessSettings.qml b/modules/controlcenter/network/WirelessSettings.qml deleted file mode 100644 index b4eb391..0000000 --- a/modules/controlcenter/network/WirelessSettings.qml +++ /dev/null @@ -1,73 +0,0 @@ -pragma ComponentBehavior: Bound - -import ".." -import "../components" -import qs.components -import qs.components.controls -import qs.components.effects -import qs.services -import qs.config -import QtQuick -import QtQuick.Layouts - -ColumnLayout { - id: root - - required property Session session - - spacing: Appearance.spacing.normal - - SettingsHeader { - icon: "wifi" - title: qsTr("Network settings") - } - - SectionHeader { - Layout.topMargin: Appearance.spacing.large - title: qsTr("WiFi status") - description: qsTr("General WiFi settings") - } - - SectionContainer { - ToggleRow { - label: qsTr("WiFi enabled") - checked: Nmcli.wifiEnabled - toggle.onToggled: { - Nmcli.enableWifi(checked); - } - } - } - - SectionHeader { - Layout.topMargin: Appearance.spacing.large - title: qsTr("Network information") - description: qsTr("Current network connection") - } - - SectionContainer { - contentSpacing: Appearance.spacing.small / 2 - - PropertyRow { - label: qsTr("Connected network") - value: Nmcli.active ? Nmcli.active.ssid : qsTr("Not connected") - } - - PropertyRow { - showTopMargin: true - label: qsTr("Signal strength") - value: Nmcli.active ? qsTr("%1%").arg(Nmcli.active.strength) : qsTr("N/A") - } - - PropertyRow { - showTopMargin: true - label: qsTr("Security") - value: Nmcli.active ? (Nmcli.active.isSecure ? qsTr("Secured") : qsTr("Open")) : qsTr("N/A") - } - - PropertyRow { - showTopMargin: true - label: qsTr("Frequency") - value: Nmcli.active ? qsTr("%1 MHz").arg(Nmcli.active.frequency) : qsTr("N/A") - } - } -} diff --git a/modules/controlcenter/state/BluetoothState.qml b/modules/controlcenter/state/BluetoothState.qml deleted file mode 100644 index 8678672..0000000 --- a/modules/controlcenter/state/BluetoothState.qml +++ /dev/null @@ -1,12 +0,0 @@ -import Quickshell.Bluetooth -import QtQuick - -QtObject { - id: root - - property BluetoothDevice active: null - property BluetoothAdapter currentAdapter: Bluetooth.defaultAdapter - property bool editingAdapterName: false - property bool fabMenuOpen: false - property bool editingDeviceName: false -} diff --git a/modules/controlcenter/state/EthernetState.qml b/modules/controlcenter/state/EthernetState.qml deleted file mode 100644 index 58f5fc8..0000000 --- a/modules/controlcenter/state/EthernetState.qml +++ /dev/null @@ -1,7 +0,0 @@ -import QtQuick - -QtObject { - id: root - - property var active: null -} diff --git a/modules/controlcenter/state/NetworkState.qml b/modules/controlcenter/state/NetworkState.qml deleted file mode 100644 index f9324c8..0000000 --- a/modules/controlcenter/state/NetworkState.qml +++ /dev/null @@ -1,9 +0,0 @@ -import QtQuick - -QtObject { - id: root - - property var active: null - property bool showPasswordDialog: false - property var pendingNetwork: null -} |