summaryrefslogtreecommitdiff
path: root/modules/controlcenter/components
diff options
context:
space:
mode:
Diffstat (limited to 'modules/controlcenter/components')
-rw-r--r--modules/controlcenter/components/DeviceDetails.qml108
-rw-r--r--modules/controlcenter/components/DeviceList.qml125
2 files changed, 233 insertions, 0 deletions
diff --git a/modules/controlcenter/components/DeviceDetails.qml b/modules/controlcenter/components/DeviceDetails.qml
new file mode 100644
index 0000000..256e689
--- /dev/null
+++ b/modules/controlcenter/components/DeviceDetails.qml
@@ -0,0 +1,108 @@
+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
+
+/**
+ * DeviceDetails
+ *
+ * A reusable base component for displaying device/network details with a standardized
+ * structure. Provides a header, connection status section, and flexible sections for
+ * device-specific information.
+ *
+ * This component eliminates duplication across WirelessDetails, EthernetDetails, and Bluetooth Details
+ * by providing a common structure while allowing full customization of sections.
+ *
+ * Usage:
+ * ```qml
+ * DeviceDetails {
+ * session: root.session
+ * device: session.network.active
+ * headerComponent: Component {
+ * ConnectionHeader {
+ * icon: "wifi"
+ * title: device?.ssid ?? ""
+ * }
+ * }
+ * sections: [
+ * Component {
+ * // Connection status section
+ * },
+ * Component {
+ * // Properties section
+ * }
+ * ]
+ * }
+ * ```
+ */
+Item {
+ id: root
+
+ required property Session session
+ property var device: null
+
+ property Component headerComponent: null
+ property list<Component> sections: []
+
+ // Optional: Custom content to insert after header but before sections
+ property Component topContent: null
+
+ // Optional: Custom content to insert after all sections
+ 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
+
+ // Header component (e.g., ConnectionHeader or SettingsHeader)
+ Loader {
+ id: headerLoader
+
+ Layout.fillWidth: true
+ sourceComponent: root.headerComponent
+ visible: root.headerComponent !== null
+ }
+
+ // Top content (optional)
+ Loader {
+ id: topContentLoader
+
+ Layout.fillWidth: true
+ sourceComponent: root.topContent
+ visible: root.topContent !== null
+ }
+
+ // Sections
+ Repeater {
+ model: root.sections
+
+ Loader {
+ Layout.fillWidth: true
+ sourceComponent: modelData
+ }
+ }
+
+ // Bottom content (optional)
+ 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
new file mode 100644
index 0000000..f8473ff
--- /dev/null
+++ b/modules/controlcenter/components/DeviceList.qml
@@ -0,0 +1,125 @@
+pragma ComponentBehavior: Bound
+
+import ".."
+import qs.components
+import qs.components.controls
+import qs.components.containers
+import qs.services
+import qs.config
+import QtQuick
+import QtQuick.Layouts
+
+/**
+ * DeviceList
+ *
+ * A reusable base component for displaying lists of devices/networks with a standardized
+ * structure. Provides a header with action buttons, title/subtitle, and a scrollable list
+ * with customizable delegates.
+ *
+ * This component eliminates duplication across WirelessList, EthernetList, and Bluetooth DeviceList
+ * by providing a common structure while allowing full customization of headers and delegates.
+ *
+ * Usage:
+ * ```qml
+ * DeviceList {
+ * session: root.session
+ * title: qsTr("Networks (%1)").arg(Nmcli.networks.length)
+ * description: qsTr("All available WiFi networks")
+ * model: ScriptModel {
+ * values: [...Nmcli.networks].sort(...)
+ * }
+ * activeItem: session.network.active
+ * onItemSelected: (item) => {
+ * session.network.active = item;
+ * }
+ * headerComponent: Component {
+ * RowLayout {
+ * // Custom header buttons
+ * }
+ * }
+ * delegate: Component {
+ * // Custom delegate for each item
+ * }
+ * }
+ * ```
+ */
+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
+
+ signal itemSelected(var item)
+
+ spacing: Appearance.spacing.small
+
+ // Header with action buttons (optional)
+ Loader {
+ id: headerLoader
+
+ Layout.fillWidth: true
+ sourceComponent: root.headerComponent
+ visible: root.headerComponent !== null
+ }
+
+ // Title and description row
+ 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
+ }
+ }
+
+ // Expose view for access from parent components
+ property alias view: view
+
+ // Description text
+ StyledText {
+ visible: root.description !== ""
+ Layout.fillWidth: true
+ text: root.description
+ color: Colours.palette.m3outline
+ }
+
+ // List view
+ StyledListView {
+ id: view
+
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+
+ model: root.model
+ delegate: root.delegate
+
+ spacing: Appearance.spacing.small / 2
+ clip: true
+
+ StyledScrollBar.vertical: StyledScrollBar {
+ flickable: view
+ }
+ }
+}
+