summaryrefslogtreecommitdiff
path: root/modules/controlcenter
diff options
context:
space:
mode:
Diffstat (limited to 'modules/controlcenter')
-rw-r--r--modules/controlcenter/ControlCenter.qml100
-rw-r--r--modules/controlcenter/NavRail.qml231
-rw-r--r--modules/controlcenter/PaneRegistry.qml68
-rw-r--r--modules/controlcenter/Panes.qml171
-rw-r--r--modules/controlcenter/Session.qml21
-rw-r--r--modules/controlcenter/WindowFactory.qml62
-rw-r--r--modules/controlcenter/WindowTitle.qml51
-rw-r--r--modules/controlcenter/audio/AudioPane.qml621
-rw-r--r--modules/controlcenter/bluetooth/BtPane.qml73
-rw-r--r--modules/controlcenter/bluetooth/Details.qml671
-rw-r--r--modules/controlcenter/bluetooth/DeviceList.qml264
-rw-r--r--modules/controlcenter/bluetooth/Settings.qml532
-rw-r--r--modules/controlcenter/components/DeviceDetails.qml70
-rw-r--r--modules/controlcenter/components/DeviceList.qml84
-rw-r--r--modules/controlcenter/components/PaneTransition.qml71
-rw-r--r--modules/controlcenter/components/ReadonlySlider.qml67
-rw-r--r--modules/controlcenter/components/SettingsHeader.qml37
-rw-r--r--modules/controlcenter/components/SliderInput.qml180
-rw-r--r--modules/controlcenter/components/SplitPaneLayout.qml109
-rw-r--r--modules/controlcenter/components/SplitPaneWithDetails.qml93
-rw-r--r--modules/controlcenter/dashboard/DashboardPane.qml135
-rw-r--r--modules/controlcenter/dashboard/GeneralSection.qml128
-rw-r--r--modules/controlcenter/dashboard/PerformanceSection.qml106
-rw-r--r--modules/controlcenter/network/EthernetDetails.qml118
-rw-r--r--modules/controlcenter/network/EthernetList.qml177
-rw-r--r--modules/controlcenter/network/EthernetPane.qml50
-rw-r--r--modules/controlcenter/network/EthernetSettings.qml76
-rw-r--r--modules/controlcenter/network/NetworkSettings.qml99
-rw-r--r--modules/controlcenter/network/NetworkingPane.qml309
-rw-r--r--modules/controlcenter/network/WirelessDetails.qml211
-rw-r--r--modules/controlcenter/network/WirelessList.qml228
-rw-r--r--modules/controlcenter/network/WirelessPane.qml57
-rw-r--r--modules/controlcenter/network/WirelessPasswordDialog.qml511
-rw-r--r--modules/controlcenter/network/WirelessSettings.qml73
-rw-r--r--modules/controlcenter/state/BluetoothState.qml12
-rw-r--r--modules/controlcenter/state/EthernetState.qml7
-rw-r--r--modules/controlcenter/state/NetworkState.qml9
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
-}