diff options
Diffstat (limited to 'raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter')
39 files changed, 0 insertions, 8603 deletions
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/BuiltinPlugins/CupsWidget.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/BuiltinPlugins/CupsWidget.qml deleted file mode 100644 index a275397..0000000 --- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/BuiltinPlugins/CupsWidget.qml +++ /dev/null @@ -1,321 +0,0 @@ -import QtQuick -import QtQuick.Layouts -import qs.Common -import qs.Services -import qs.Widgets -import qs.Modules.Plugins - -PluginComponent { - id: root - - Ref { - service: CupsService - } - - ccWidgetIcon: CupsService.cupsAvailable && CupsService.getPrintersNum() > 0 ? "print" : "print_disabled" - ccWidgetPrimaryText: I18n.tr("Printers") - ccWidgetSecondaryText: { - if (CupsService.cupsAvailable && CupsService.getPrintersNum() > 0) { - return I18n.tr("Printers: ") + CupsService.getPrintersNum() + " - " + I18n.tr("Jobs: ") + CupsService.getTotalJobsNum(); - } else { - if (!CupsService.cupsAvailable) { - return I18n.tr("Print Server not available"); - } else { - return I18n.tr("No printer found"); - } - } - } - ccWidgetIsActive: CupsService.cupsAvailable && CupsService.getTotalJobsNum() > 0 - - onCcWidgetToggled: {} - - ccDetailContent: Component { - Rectangle { - id: detailRoot - implicitHeight: detailColumn.implicitHeight + Theme.spacingM * 2 - radius: Theme.cornerRadius - color: Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency) - - DankActionButton { - anchors.top: parent.top - anchors.right: parent.right - anchors.topMargin: Theme.spacingS - anchors.rightMargin: Theme.spacingS - iconName: "settings" - buttonSize: 24 - iconSize: 14 - iconColor: Theme.surfaceVariantText - onClicked: { - PopoutService.closeControlCenter(); - PopoutService.openSettingsWithTab("printers"); - } - } - - Column { - visible: !CupsService.cupsAvailable || CupsService.getPrintersNum() == 0 - anchors.centerIn: parent - spacing: Theme.spacingS - - DankIcon { - name: "print_disabled" - size: 36 - color: Theme.surfaceVariantText - anchors.horizontalCenter: parent.horizontalCenter - } - - StyledText { - text: !CupsService.cupsAvailable ? I18n.tr("Print Server not available") : I18n.tr("No printer found") - font.pixelSize: Theme.fontSizeMedium - color: Theme.surfaceVariantText - anchors.horizontalCenter: parent.horizontalCenter - } - } - - Column { - id: detailColumn - anchors.fill: parent - anchors.margins: Theme.spacingM - spacing: Theme.spacingS - visible: CupsService.cupsAvailable && CupsService.getPrintersNum() > 0 - height: visible ? 120 : 0 - - RowLayout { - spacing: Theme.spacingS - width: parent.width - - DankDropdown { - id: printerDropdown - text: "" - Layout.fillWidth: true - Layout.maximumWidth: parent.width - 180 - description: "" - currentValue: { - CupsService.getSelectedPrinter(); - } - options: CupsService.getPrintersNames() - onValueChanged: value => { - CupsService.setSelectedPrinter(value); - } - } - - Column { - spacing: Theme.spacingS - - StyledText { - text: CupsService.getCurrentPrinterStatePrettyShort() - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceText - font.weight: Font.Medium - anchors.horizontalCenter: parent.horizontalCenter - } - - Row { - spacing: Theme.spacingM - - Rectangle { - height: 24 - width: 80 - radius: 14 - color: printerStatusToggle.containsMouse ? Theme.errorHover : Theme.surfaceLight - visible: true - opacity: 1.0 - - Row { - anchors.centerIn: parent - spacing: Theme.spacingXS - - DankIcon { - anchors.verticalCenter: parent.verticalCenter - name: CupsService.getCurrentPrinterState() === "stopped" ? "play_arrow" : "pause" - size: Theme.fontSizeSmall + 4 - color: Theme.surfaceText - } - - StyledText { - anchors.verticalCenter: parent.verticalCenter - text: CupsService.getCurrentPrinterState() === "stopped" ? I18n.tr("Resume") : I18n.tr("Pause") - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceText - font.weight: Font.Medium - } - } - - MouseArea { - id: printerStatusToggle - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - enabled: true - onClicked: { - const selected = CupsService.getSelectedPrinter(); - if (CupsService.getCurrentPrinterState() === "stopped") { - CupsService.resumePrinter(selected); - } else { - CupsService.pausePrinter(selected); - } - } - } - } - - Rectangle { - height: 24 - width: 80 - radius: 14 - color: clearJobsToggle.containsMouse ? Theme.errorHover : Theme.surfaceLight - visible: true - opacity: 1.0 - - Row { - anchors.centerIn: parent - spacing: Theme.spacingXS - - DankIcon { - anchors.verticalCenter: parent.verticalCenter - name: "delete_forever" - size: Theme.fontSizeSmall + 4 - color: Theme.surfaceText - } - - StyledText { - anchors.verticalCenter: parent.verticalCenter - text: I18n.tr("Jobs") - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceText - font.weight: Font.Medium - } - } - - MouseArea { - id: clearJobsToggle - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - enabled: true - onClicked: { - const selected = CupsService.getSelectedPrinter(); - CupsService.purgeJobs(selected); - } - } - } - } - } - } - - Rectangle { - height: 1 - width: parent.width - color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12) - } - - DankFlickable { - width: parent.width - height: 160 - contentHeight: listCol.height - clip: true - - Column { - id: listCol - width: parent.width - spacing: Theme.spacingXS - - Item { - width: parent.width - height: 120 - visible: CupsService.getCurrentPrinterJobs().length === 0 - - Column { - anchors.centerIn: parent - spacing: Theme.spacingS - - DankIcon { - name: "work" - size: 36 - color: Theme.surfaceVariantText - anchors.horizontalCenter: parent.horizontalCenter - } - - StyledText { - text: I18n.tr("The job queue of this printer is empty") - font.pixelSize: Theme.fontSizeMedium - color: Theme.surfaceVariantText - anchors.horizontalCenter: parent.horizontalCenter - } - } - } - - Repeater { - model: CupsService.getCurrentPrinterJobs() - - delegate: Rectangle { - required property var modelData - - width: parent ? parent.width : 300 - height: 50 - radius: Theme.cornerRadius - color: Theme.surfaceLight - border.width: 1 - border.color: Theme.outlineLight - opacity: 1.0 - - RowLayout { - anchors.left: parent.left - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - anchors.margins: Theme.spacingM - spacing: Theme.spacingM - - DankIcon { - name: "docs" - size: Theme.iconSize + 2 - color: Theme.surfaceText - Layout.alignment: Qt.AlignVCenter - } - - Column { - spacing: 2 - Layout.alignment: Qt.AlignVCenter - Layout.fillWidth: true - - StyledText { - text: "[" + modelData.id + "] " + modelData.state + " (" + (modelData.size / 1024) + "kb)" - font.pixelSize: Theme.fontSizeMedium - color: Theme.surfaceText - elide: Text.ElideRight - wrapMode: Text.NoWrap - width: parent.width - } - - StyledText { - text: { - var date = new Date(modelData.timeCreated); - return date.toLocaleString(Qt.locale(), Locale.ShortFormat); - } - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceTextMedium - } - } - - Item { - Layout.fillWidth: true - } - } - - DankActionButton { - id: cancelJobButton - anchors.right: parent.right - anchors.rightMargin: Theme.spacingM - anchors.verticalCenter: parent.verticalCenter - iconName: "delete" - buttonSize: 36 - onClicked: { - CupsService.cancelJob(CupsService.getSelectedPrinter(), modelData.id); - } - } - } - } - } - } - } - } - } -} diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/BuiltinPlugins/VpnWidget.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/BuiltinPlugins/VpnWidget.qml deleted file mode 100644 index 531045e..0000000 --- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/BuiltinPlugins/VpnWidget.qml +++ /dev/null @@ -1,33 +0,0 @@ -import QtQuick -import qs.Common -import qs.Services -import qs.Widgets -import qs.Modules.Plugins - -PluginComponent { - id: root - - Ref { - service: DMSNetworkService - } - - ccWidgetIcon: DMSNetworkService.isBusy ? "sync" : (DMSNetworkService.connected ? "vpn_lock" : "vpn_key_off") - ccWidgetPrimaryText: I18n.tr("VPN") - ccWidgetSecondaryText: { - if (!DMSNetworkService.connected) - return I18n.tr("Disconnected"); - const names = DMSNetworkService.activeNames || []; - if (names.length <= 1) - return names[0] || I18n.tr("Connected"); - return names[0] + " +" + (names.length - 1); - } - ccWidgetIsActive: DMSNetworkService.connected - - onCcWidgetToggled: DMSNetworkService.toggleVpn() - - ccDetailContent: Component { - VpnDetailContent { - listHeight: 260 - } - } -} diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Components/ActionTile.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Components/ActionTile.qml deleted file mode 100644 index d85c779..0000000 --- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Components/ActionTile.qml +++ /dev/null @@ -1,132 +0,0 @@ -import QtQuick -import qs.Common -import qs.Widgets - -Rectangle { - id: root - - LayoutMirroring.enabled: I18n.isRtl - LayoutMirroring.childrenInherit: true - - property string iconName: "" - property string text: "" - property string secondaryText: "" - property bool isActive: false - property bool enabled: true - property int widgetIndex: 0 - property var widgetData: null - property bool editMode: false - - signal clicked - - width: parent ? parent.width : 200 - height: 60 - radius: { - if (Theme.cornerRadius === 0) - return 0; - return isActive ? Theme.cornerRadius : Theme.cornerRadius + 4; - } - - readonly property color _tileBgActive: Theme.ccTileActiveBg - readonly property color _tileBgInactive: Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency) - readonly property color _tileRingActive: Theme.ccTileRing - - color: isActive ? _tileBgActive : _tileBgInactive - border.color: isActive ? _tileRingActive : Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08) - border.width: isActive ? 1 : 1 - opacity: enabled ? 1.0 : 0.6 - - function hoverTint(base) { - const factor = 1.2; - return Theme.isLightMode ? Qt.darker(base, factor) : Qt.lighter(base, factor); - } - - Rectangle { - anchors.fill: parent - radius: Theme.cornerRadius - color: mouseArea.containsMouse ? hoverTint(root.color) : "transparent" - opacity: mouseArea.containsMouse ? 0.08 : 0.0 - - Behavior on opacity { - NumberAnimation { - duration: Theme.shortDuration - } - } - } - - Row { - anchors.fill: parent - anchors.leftMargin: Theme.spacingL + 2 - anchors.rightMargin: Theme.spacingM - spacing: Theme.spacingM - - DankIcon { - name: root.iconName - size: Theme.iconSize - color: isActive ? Theme.ccTileActiveText : Theme.ccTileInactiveIcon - anchors.verticalCenter: parent.verticalCenter - } - - Item { - width: parent.width - Theme.iconSize - parent.spacing - height: parent.height - - Column { - anchors.left: parent.left - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - spacing: 2 - - Typography { - width: parent.width - text: root.text - style: Typography.Style.Body - color: isActive ? Theme.ccTileActiveText : Theme.surfaceText - elide: Text.ElideRight - wrapMode: Text.NoWrap - horizontalAlignment: Text.AlignLeft - } - - Typography { - width: parent.width - text: root.secondaryText - style: Typography.Style.Caption - color: isActive ? Theme.ccTileActiveText : Theme.surfaceVariantText - visible: text.length > 0 - elide: Text.ElideRight - wrapMode: Text.NoWrap - horizontalAlignment: Text.AlignLeft - } - } - } - } - - DankRipple { - id: ripple - cornerRadius: root.radius - } - - MouseArea { - id: mouseArea - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - enabled: root.enabled - onPressed: mouse => ripple.trigger(mouse.x, mouse.y) - onClicked: root.clicked() - } - - Behavior on color { - ColorAnimation { - duration: Theme.shortDuration - easing.type: Theme.standardEasing - } - } - - Behavior on radius { - NumberAnimation { - duration: Theme.shortDuration - easing.type: Theme.standardEasing - } - } -} diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Components/DetailHost.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Components/DetailHost.qml deleted file mode 100644 index a3b1156..0000000 --- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Components/DetailHost.qml +++ /dev/null @@ -1,250 +0,0 @@ -import QtQuick -import qs.Common -import qs.Services -import qs.Modules.ControlCenter.Details - -Item { - id: root - - property string expandedSection: "" - property var expandedWidgetData: null - property var bluetoothCodecSelector: null - property string screenName: "" - property string screenModel: "" - - property var pluginDetailInstance: null - property var widgetModel: null - property var collapseCallback: null - property real maxAvailableHeight: 9999 - - function getDetailHeight(section) { - switch (true) { - case section === "wifi": - case section === "bluetooth": - case section === "builtin_vpn": - return Math.min(350, maxAvailableHeight); - case section.startsWith("brightnessSlider_"): - return Math.min(400, maxAvailableHeight); - case section.startsWith("plugin_"): - if (pluginDetailInstance?.ccDetailHeight) - return Math.min(pluginDetailInstance.ccDetailHeight, maxAvailableHeight); - return Math.min(250, maxAvailableHeight); - default: - return Math.min(250, maxAvailableHeight); - } - } - - Loader { - id: pluginDetailLoader - width: parent.width - height: parent.height - Theme.spacingS - y: Theme.spacingS - active: false - sourceComponent: null - } - - Loader { - id: coreDetailLoader - width: parent.width - height: parent.height - Theme.spacingS - y: Theme.spacingS - active: false - sourceComponent: null - } - - Connections { - target: coreDetailLoader.item - enabled: root.expandedSection.startsWith("brightnessSlider_") - ignoreUnknownSignals: true - - function onDeviceNameChanged(newDeviceName) { - if (root.expandedWidgetData && root.expandedWidgetData.id === "brightnessSlider") { - const widgets = SettingsData.controlCenterWidgets || []; - const newWidgets = widgets.map(w => { - if (w.id === "brightnessSlider" && w.instanceId === root.expandedWidgetData.instanceId) { - const updatedWidget = Object.assign({}, w); - updatedWidget.deviceName = newDeviceName; - return updatedWidget; - } - return w; - }); - SettingsData.set("controlCenterWidgets", newWidgets); - if (root.collapseCallback) { - root.collapseCallback(); - } - } - } - } - - Connections { - target: coreDetailLoader.item - enabled: root.expandedSection.startsWith("diskUsage_") - ignoreUnknownSignals: true - - function onMountPathChanged(newMountPath) { - if (root.expandedWidgetData && root.expandedWidgetData.id === "diskUsage") { - const widgets = SettingsData.controlCenterWidgets || []; - const newWidgets = widgets.map(w => { - if (w.id === "diskUsage" && w.instanceId === root.expandedWidgetData.instanceId) { - const updatedWidget = Object.assign({}, w); - updatedWidget.mountPath = newMountPath; - return updatedWidget; - } - return w; - }); - SettingsData.set("controlCenterWidgets", newWidgets); - if (root.collapseCallback) { - root.collapseCallback(); - } - } - } - } - - onExpandedSectionChanged: { - if (pluginDetailInstance) { - pluginDetailInstance.destroy(); - pluginDetailInstance = null; - } - pluginDetailLoader.active = false; - coreDetailLoader.active = false; - - if (!root.expandedSection) { - return; - } - - if (root.expandedSection.startsWith("builtin_")) { - const builtinId = root.expandedSection; - let builtinInstance = null; - - if (builtinId === "builtin_vpn") { - if (widgetModel?.vpnLoader) { - widgetModel.vpnLoader.active = true; - } - builtinInstance = widgetModel.vpnBuiltinInstance; - } - if (builtinId === "builtin_cups") { - if (widgetModel?.cupsLoader) { - widgetModel.cupsLoader.active = true; - } - builtinInstance = widgetModel.cupsBuiltinInstance; - } - - if (!builtinInstance || !builtinInstance.ccDetailContent) { - return; - } - - pluginDetailLoader.sourceComponent = builtinInstance.ccDetailContent; - pluginDetailLoader.active = parent.height > 0; - return; - } - - if (root.expandedSection.startsWith("plugin_")) { - const pluginId = root.expandedSection.replace("plugin_", ""); - const pluginComponent = PluginService.pluginWidgetComponents[pluginId]; - if (!pluginComponent) { - return; - } - - pluginDetailInstance = pluginComponent.createObject(null); - if (!pluginDetailInstance || !pluginDetailInstance.ccDetailContent) { - if (pluginDetailInstance) { - pluginDetailInstance.destroy(); - pluginDetailInstance = null; - } - return; - } - - pluginDetailLoader.sourceComponent = pluginDetailInstance.ccDetailContent; - pluginDetailLoader.active = parent.height > 0; - return; - } - - if (root.expandedSection.startsWith("diskUsage_")) { - coreDetailLoader.sourceComponent = diskUsageDetailComponent; - coreDetailLoader.active = parent.height > 0; - return; - } - - if (root.expandedSection.startsWith("brightnessSlider_")) { - coreDetailLoader.sourceComponent = brightnessDetailComponent; - coreDetailLoader.active = parent.height > 0; - return; - } - - switch (root.expandedSection) { - case "network": - case "wifi": - coreDetailLoader.sourceComponent = networkDetailComponent; - break; - case "bluetooth": - coreDetailLoader.sourceComponent = bluetoothDetailComponent; - break; - case "audioOutput": - coreDetailLoader.sourceComponent = audioOutputDetailComponent; - break; - case "audioInput": - coreDetailLoader.sourceComponent = audioInputDetailComponent; - break; - case "battery": - coreDetailLoader.sourceComponent = batteryDetailComponent; - break; - default: - return; - } - - coreDetailLoader.active = parent.height > 0; - } - - Component { - id: networkDetailComponent - NetworkDetail {} - } - - Component { - id: bluetoothDetailComponent - BluetoothDetail { - id: bluetoothDetail - onShowCodecSelector: function (device) { - if (root.bluetoothCodecSelector) { - root.bluetoothCodecSelector.show(device); - root.bluetoothCodecSelector.codecSelected.connect(function (deviceAddress, codecName) { - bluetoothDetail.updateDeviceCodecDisplay(deviceAddress, codecName); - }); - } - } - } - } - - Component { - id: audioOutputDetailComponent - AudioOutputDetail {} - } - - Component { - id: audioInputDetailComponent - AudioInputDetail {} - } - - Component { - id: batteryDetailComponent - BatteryDetail {} - } - - Component { - id: diskUsageDetailComponent - DiskUsageDetail { - currentMountPath: root.expandedWidgetData?.mountPath || "/" - instanceId: root.expandedWidgetData?.instanceId || "" - } - } - - Component { - id: brightnessDetailComponent - BrightnessDetail { - initialDeviceName: root.expandedWidgetData?.deviceName || "" - instanceId: root.expandedWidgetData?.instanceId || "" - screenName: root.screenName - screenModel: root.screenModel - } - } -} diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Components/DragDropDetailHost.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Components/DragDropDetailHost.qml deleted file mode 100644 index 4a7ff19..0000000 --- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Components/DragDropDetailHost.qml +++ /dev/null @@ -1,91 +0,0 @@ -import QtQuick -import qs.Common -import qs.Modules.ControlCenter.Details - -Item { - id: root - - property string expandedSection: "" - property var expandedWidgetData: null - - height: active ? 250 : 0 - visible: active - - readonly property bool active: expandedSection !== "" - - Loader { - anchors.fill: parent - anchors.topMargin: Theme.spacingS - sourceComponent: { - if (!root.active) - return null; - - if (expandedSection.startsWith("diskUsage_")) { - return diskUsageDetailComponent; - } - - switch (expandedSection) { - case "wifi": - return networkDetailComponent; - case "bluetooth": - return bluetoothDetailComponent; - case "audioOutput": - return audioOutputDetailComponent; - case "audioInput": - return audioInputDetailComponent; - case "battery": - return batteryDetailComponent; - default: - return null; - } - } - } - - Component { - id: networkDetailComponent - NetworkDetail {} - } - - Component { - id: bluetoothDetailComponent - BluetoothDetail {} - } - - Component { - id: audioOutputDetailComponent - AudioOutputDetail {} - } - - Component { - id: audioInputDetailComponent - AudioInputDetail {} - } - - Component { - id: batteryDetailComponent - BatteryDetail {} - } - - Component { - id: diskUsageDetailComponent - DiskUsageDetail { - currentMountPath: root.expandedWidgetData?.mountPath || "/" - instanceId: root.expandedWidgetData?.instanceId || "" - - onMountPathChanged: newMountPath => { - if (root.expandedWidgetData && root.expandedWidgetData.id === "diskUsage") { - const widgets = SettingsData.controlCenterWidgets || []; - const newWidgets = widgets.map(w => { - if (w.id === "diskUsage" && w.instanceId === root.expandedWidgetData.instanceId) { - const updatedWidget = Object.assign({}, w); - updatedWidget.mountPath = newMountPath; - return updatedWidget; - } - return w; - }); - SettingsData.set("controlCenterWidgets", newWidgets); - } - } - } - } -} diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Components/DragDropGrid.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Components/DragDropGrid.qml deleted file mode 100644 index 4cdd979..0000000 --- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Components/DragDropGrid.qml +++ /dev/null @@ -1,1091 +0,0 @@ -import QtQuick -import qs.Common -import qs.Services -import qs.Modules.ControlCenter.Widgets -import qs.Modules.ControlCenter.Components -import "../utils/layout.js" as LayoutUtils - -Column { - id: root - - property bool editMode: false - property string expandedSection: "" - property int expandedWidgetIndex: -1 - property var model: null - property var expandedWidgetData: null - property var bluetoothCodecSelector: null - property bool darkModeTransitionPending: false - property string screenName: "" - property string screenModel: "" - property var parentScreen: null - - signal expandClicked(var widgetData, int globalIndex) - signal removeWidget(int index) - signal moveWidget(int fromIndex, int toIndex) - signal toggleWidgetSize(int index) - signal collapseRequested - - function requestCollapse() { - collapseRequested(); - } - - spacing: editMode ? Theme.spacingL : Theme.spacingS - - property real maxPopoutHeight: 9999 - property var currentRowWidgets: [] - property real currentRowWidth: 0 - property int expandedRowIndex: -1 - property var colorPickerModal: null - - readonly property real _maxDetailHeight: { - const rows = layoutResult.rows; - let totalRowHeight = 0; - for (let i = 0; i < rows.length; i++) { - const sliderOnly = rows[i].every(w => { - const id = w.id || ""; - return id === "volumeSlider" || id === "brightnessSlider" || id === "inputVolumeSlider"; - }); - totalRowHeight += sliderOnly ? 36 : 60; - } - const rowSpacing = Math.max(0, rows.length - 1) * spacing; - return Math.max(100, maxPopoutHeight - totalRowHeight - rowSpacing); - } - - function calculateRowsAndWidgets() { - return LayoutUtils.calculateRowsAndWidgets(root, expandedSection, expandedWidgetIndex); - } - - property var layoutResult: { - const dummy = [expandedSection, expandedWidgetIndex, model?.controlCenterWidgets]; - return calculateRowsAndWidgets(); - } - - onLayoutResultChanged: { - expandedRowIndex = layoutResult.expandedRowIndex; - } - - function moveToTop(item) { - const children = root.children; - for (var i = 0; i < children.length; i++) { - if (children[i] === item) - continue; - if (children[i].z) - children[i].z = Math.min(children[i].z, 999); - } - item.z = 1000; - } - - Repeater { - model: root.layoutResult.rows - - Column { - width: root.width - spacing: 0 - property int rowIndex: index - property var rowWidgets: modelData - property bool isSliderOnlyRow: { - const widgets = rowWidgets || []; - if (widgets.length === 0) - return false; - return widgets.every(w => w.id === "volumeSlider" || w.id === "brightnessSlider" || w.id === "inputVolumeSlider"); - } - topPadding: isSliderOnlyRow ? (root.editMode ? 4 : -6) : 0 - bottomPadding: isSliderOnlyRow ? (root.editMode ? 4 : -6) : 0 - - Flow { - width: parent.width - spacing: Theme.spacingS - - Repeater { - model: rowWidgets || [] - - DragDropWidgetWrapper { - widgetData: modelData - property int globalWidgetIndex: { - const widgets = SettingsData.controlCenterWidgets || []; - for (var i = 0; i < widgets.length; i++) { - if (widgets[i].id === modelData.id) { - if (modelData.id === "diskUsage" || modelData.id === "brightnessSlider") { - if (widgets[i].instanceId === modelData.instanceId) { - return i; - } - } else { - return i; - } - } - } - return -1; - } - property int widgetWidth: modelData.width || 50 - width: { - const baseWidth = root.width; - const spacing = Theme.spacingS; - if (widgetWidth <= 25) { - return (baseWidth - spacing * 3) / 4; - } else if (widgetWidth <= 50) { - return (baseWidth - spacing) / 2; - } else if (widgetWidth <= 75) { - return (baseWidth - spacing * 2) * 0.75; - } else { - return baseWidth; - } - } - height: isSliderOnlyRow ? 48 : 60 - - editMode: root.editMode - widgetIndex: globalWidgetIndex - gridCellWidth: width - gridCellHeight: height - gridColumns: 4 - gridLayout: root - isSlider: { - const id = modelData.id || ""; - return id === "volumeSlider" || id === "brightnessSlider" || id === "inputVolumeSlider"; - } - - widgetComponent: { - const id = modelData.id || ""; - if (id.startsWith("builtin_")) { - return builtinPluginWidgetComponent; - } else if (id.startsWith("plugin_")) { - return pluginWidgetComponent; - } else if (id === "wifi" || id === "bluetooth" || id === "audioOutput" || id === "audioInput") { - return compoundPillComponent; - } else if (id === "volumeSlider") { - return audioSliderComponent; - } else if (id === "brightnessSlider") { - return brightnessSliderComponent; - } else if (id === "inputVolumeSlider") { - return inputAudioSliderComponent; - } else if (id === "battery") { - return widgetWidth <= 25 ? smallBatteryComponent : batteryPillComponent; - } else if (id === "diskUsage") { - return widgetWidth <= 25 ? smallDiskUsageComponent : diskUsagePillComponent; - } else if (id === "colorPicker") { - return colorPickerPillComponent; - } else { - return widgetWidth <= 25 ? smallToggleComponent : toggleButtonComponent; - } - } - - onWidgetMoved: (fromIndex, toIndex) => root.moveWidget(fromIndex, toIndex) - onRemoveWidget: index => root.removeWidget(index) - onToggleWidgetSize: index => root.toggleWidgetSize(index) - } - } - } - - DetailHost { - id: detailHost - width: parent.width - maxAvailableHeight: root._maxDetailHeight - height: active ? (getDetailHeight(root.expandedSection) + Theme.spacingS) : 0 - property bool active: { - if (root.expandedSection === "") - return false; - - if (root.expandedSection.startsWith("diskUsage_") && root.expandedWidgetData) { - const expandedInstanceId = root.expandedWidgetData.instanceId; - return rowWidgets.some(w => w.id === "diskUsage" && w.instanceId === expandedInstanceId); - } - - if (root.expandedSection.startsWith("brightnessSlider_") && root.expandedWidgetData) { - const expandedInstanceId = root.expandedWidgetData.instanceId; - return rowWidgets.some(w => w.id === "brightnessSlider" && w.instanceId === expandedInstanceId); - } - - return rowIndex === root.expandedRowIndex; - } - visible: active - expandedSection: root.expandedSection - expandedWidgetData: root.expandedWidgetData - bluetoothCodecSelector: root.bluetoothCodecSelector - widgetModel: root.model - collapseCallback: root.requestCollapse - screenName: root.screenName - screenModel: root.screenModel - } - } - } - - Component { - id: errorPillComponent - ErrorPill { - property var widgetData: parent.widgetData || {} - width: parent.width - height: 60 - primaryMessage: { - if (!DMSService.dmsAvailable) { - return I18n.tr("DMS_SOCKET not available"); - } - return I18n.tr("NM not supported"); - } - secondaryMessage: I18n.tr("update dms for NM integration.") - } - } - - Component { - id: compoundPillComponent - CompoundPill { - property var widgetData: parent.widgetData || {} - property int widgetIndex: parent.widgetIndex || 0 - property var widgetDef: root.model?.getWidgetForId(widgetData.id || "") - width: parent.width - height: 60 - iconName: { - switch (widgetData.id || "") { - case "wifi": - { - if (NetworkService.wifiToggling) - return "sync"; - - const status = NetworkService.networkStatus; - if (status === "ethernet") - return "settings_ethernet"; - if (status === "vpn") - return NetworkService.ethernetConnected ? "settings_ethernet" : NetworkService.wifiSignalIcon; - if (status === "wifi") - return NetworkService.wifiSignalIcon; - if (NetworkService.wifiEnabled) - return "wifi_off"; - return "wifi_off"; - } - case "bluetooth": - { - if (!BluetoothService.available) - return "bluetooth_disabled"; - if (!BluetoothService.adapter || !BluetoothService.adapter.enabled) - return "bluetooth_disabled"; - return "bluetooth"; - } - case "audioOutput": - { - if (!AudioService.sink) - return "volume_off"; - let volume = AudioService.sink.audio.volume; - let muted = AudioService.sink.audio.muted; - if (muted) - return "volume_off"; - if (volume === 0.0) - return "volume_mute"; - if (volume <= 0.33) - return "volume_down"; - if (volume <= 0.66) - return "volume_up"; - return "volume_up"; - } - case "audioInput": - { - if (!AudioService.source) - return "mic_off"; - let muted = AudioService.source.audio.muted; - return muted ? "mic_off" : "mic"; - } - default: - return widgetDef?.icon || "help"; - } - } - primaryText: { - switch (widgetData.id || "") { - case "wifi": - { - if (NetworkService.wifiToggling) - return NetworkService.wifiEnabled ? I18n.tr("Disabling WiFi...", "network status") : I18n.tr("Enabling WiFi...", "network status"); - - const status = NetworkService.networkStatus; - if (status === "ethernet") - return I18n.tr("Ethernet", "network status"); - if (status === "vpn") { - if (NetworkService.ethernetConnected) - return I18n.tr("Ethernet", "network status"); - if (NetworkService.wifiConnected && NetworkService.currentWifiSSID) - return NetworkService.currentWifiSSID; - } - if (status === "wifi" && NetworkService.currentWifiSSID) - return NetworkService.currentWifiSSID; - if (NetworkService.wifiEnabled) - return I18n.tr("Not connected", "network status"); - return I18n.tr("WiFi off", "network status"); - } - case "bluetooth": - { - if (!BluetoothService.available) - return I18n.tr("Bluetooth", "bluetooth status"); - if (!BluetoothService.adapter) - return I18n.tr("No adapter", "bluetooth status"); - if (!BluetoothService.adapter.enabled) - return I18n.tr("Disabled", "bluetooth status"); - return I18n.tr("Enabled", "bluetooth status"); - } - case "audioOutput": - return AudioService.sink?.description || I18n.tr("No output device", "audio status"); - case "audioInput": - return AudioService.source?.description || I18n.tr("No input device", "audio status"); - default: - return widgetDef?.text || I18n.tr("Unknown", "widget status"); - } - } - secondaryText: { - switch (widgetData.id || "") { - case "wifi": - { - if (NetworkService.wifiToggling) - return I18n.tr("Please wait...", "network status"); - - const status = NetworkService.networkStatus; - if (status === "ethernet") - return I18n.tr("Connected", "network status"); - if (status === "vpn") { - if (NetworkService.ethernetConnected) - return I18n.tr("Connected", "network status"); - if (NetworkService.wifiConnected) - return NetworkService.wifiSignalStrength > 0 ? NetworkService.wifiSignalStrength + "%" : I18n.tr("Connected", "network status"); - } - if (status === "wifi") - return NetworkService.wifiSignalStrength > 0 ? NetworkService.wifiSignalStrength + "%" : I18n.tr("Connected", "network status"); - if (NetworkService.wifiEnabled) - return I18n.tr("Select network", "network status"); - return ""; - } - case "bluetooth": - { - if (!BluetoothService.available) - return I18n.tr("No adapters", "bluetooth status"); - if (!BluetoothService.adapter || !BluetoothService.adapter.enabled) - return I18n.tr("Off", "bluetooth status"); - const primaryDevice = (() => { - if (!BluetoothService.adapter || !BluetoothService.adapter.devices) - return null; - let devices = [...BluetoothService.adapter.devices.values.filter(dev => dev && (dev.paired || dev.trusted))]; - for (let device of devices) { - if (device && device.connected) - return device; - } - return null; - })(); - if (primaryDevice) - return primaryDevice.name || primaryDevice.alias || primaryDevice.deviceName || I18n.tr("Connected Device", "bluetooth status"); - return I18n.tr("No devices", "bluetooth status"); - } - case "audioOutput": - { - if (!AudioService.sink) - return I18n.tr("Select device", "audio status"); - if (AudioService.sink.audio.muted) - return I18n.tr("Muted", "audio status"); - const volume = AudioService.sink.audio.volume; - if (typeof volume !== "number" || isNaN(volume)) - return "0%"; - return Math.round(volume * 100) + "%"; - } - case "audioInput": - { - if (!AudioService.source) - return I18n.tr("Select device", "audio status"); - if (AudioService.source.audio.muted) - return I18n.tr("Muted", "audio status"); - const volume = AudioService.source.audio.volume; - if (typeof volume !== "number" || isNaN(volume)) - return "0%"; - return Math.round(volume * 100) + "%"; - } - default: - return widgetDef?.description || ""; - } - } - isActive: { - switch (widgetData.id || "") { - case "wifi": - { - if (NetworkService.wifiToggling) - return false; - - const status = NetworkService.networkStatus; - if (status === "ethernet") - return true; - if (status === "vpn") - return NetworkService.ethernetConnected || NetworkService.wifiConnected; - if (status === "wifi") - return true; - return NetworkService.wifiEnabled; - } - case "bluetooth": - return !!(BluetoothService.available && BluetoothService.adapter && BluetoothService.adapter.enabled); - case "audioOutput": - return !!(AudioService.sink && !AudioService.sink.audio.muted); - case "audioInput": - return !!(AudioService.source && !AudioService.source.audio.muted); - default: - return false; - } - } - enabled: widgetDef?.enabled ?? true - onToggled: { - if (root.editMode) - return; - switch (widgetData.id || "") { - case "wifi": - { - if (NetworkService.networkStatus !== "ethernet" && !NetworkService.wifiToggling) { - NetworkService.toggleWifiRadio(); - } - break; - } - case "bluetooth": - { - if (BluetoothService.available && BluetoothService.adapter) { - BluetoothService.adapter.enabled = !BluetoothService.adapter.enabled; - } - break; - } - case "audioOutput": - { - if (AudioService.sink && AudioService.sink.audio) { - AudioService.sink.audio.muted = !AudioService.sink.audio.muted; - } - break; - } - case "audioInput": - { - if (AudioService.source && AudioService.source.audio) { - AudioService.source.audio.muted = !AudioService.source.audio.muted; - } - break; - } - } - } - onExpandClicked: { - if (root.editMode) - return; - root.expandClicked(widgetData, widgetIndex); - } - onWheelEvent: function (wheelEvent) { - if (root.editMode) - return; - const id = widgetData.id || ""; - if (id === "audioOutput") { - if (!AudioService.sink || !AudioService.sink.audio) - return; - let delta = wheelEvent.angleDelta.y; - let maxVol = AudioService.sinkMaxVolume; - let currentVolume = AudioService.sink.audio.volume * 100; - let newVolume; - if (delta > 0) - newVolume = Math.min(maxVol, currentVolume + 5); - else - newVolume = Math.max(0, currentVolume - 5); - AudioService.sink.audio.muted = false; - AudioService.sink.audio.volume = newVolume / 100; - wheelEvent.accepted = true; - } else if (id === "audioInput") { - if (!AudioService.source || !AudioService.source.audio) - return; - let delta = wheelEvent.angleDelta.y; - let currentVolume = AudioService.source.audio.volume * 100; - let newVolume; - if (delta > 0) - newVolume = Math.min(100, currentVolume + 5); - else - newVolume = Math.max(0, currentVolume - 5); - AudioService.source.audio.muted = false; - AudioService.source.audio.volume = newVolume / 100; - wheelEvent.accepted = true; - } - } - } - } - - Component { - id: audioSliderComponent - Item { - property var widgetData: parent.widgetData || {} - property int widgetIndex: parent.widgetIndex || 0 - width: parent.width - height: 16 - - AudioSliderRow { - anchors.centerIn: parent - width: parent.width - height: 14 - property color sliderTrackColor: Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency) - } - } - } - - Component { - id: brightnessSliderComponent - Item { - property var widgetData: parent.widgetData || {} - property int widgetIndex: parent.widgetIndex || 0 - width: parent.width - height: 16 - - BrightnessSliderRow { - id: brightnessSliderRow - anchors.centerIn: parent - width: parent.width - height: 14 - deviceName: widgetData.deviceName || "" - instanceId: widgetData.instanceId || "" - screenName: root.screenName - parentScreen: root.parentScreen - property color sliderTrackColor: Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency) - - onIconClicked: { - if (!root.editMode && DisplayService.devices && DisplayService.devices.length > 1) { - root.expandClicked(widgetData, widgetIndex); - } - } - } - } - } - - Component { - id: inputAudioSliderComponent - Item { - property var widgetData: parent.widgetData || {} - property int widgetIndex: parent.widgetIndex || 0 - width: parent.width - height: 16 - - InputAudioSliderRow { - anchors.centerIn: parent - width: parent.width - height: 14 - property color sliderTrackColor: Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency) - } - } - } - - Component { - id: batteryPillComponent - BatteryPill { - property var widgetData: parent.widgetData || {} - property int widgetIndex: parent.widgetIndex || 0 - width: parent.width - height: 60 - - onExpandClicked: { - if (!root.editMode) { - root.expandClicked(widgetData, widgetIndex); - } - } - } - } - - Component { - id: smallBatteryComponent - SmallBatteryButton { - property var widgetData: parent.widgetData || {} - property int widgetIndex: parent.widgetIndex || 0 - width: parent.width - height: 48 - - onClicked: { - if (!root.editMode) { - root.expandClicked(widgetData, widgetIndex); - } - } - } - } - - Component { - id: toggleButtonComponent - ToggleButton { - property var widgetData: parent.widgetData || {} - property int widgetIndex: parent.widgetIndex || 0 - width: parent.width - height: 60 - - iconName: { - switch (widgetData.id || "") { - case "nightMode": - return DisplayService.nightModeEnabled ? "nightlight" : "dark_mode"; - case "darkMode": - return "contrast"; - case "doNotDisturb": - return SessionData.doNotDisturb ? "do_not_disturb_on" : "do_not_disturb_off"; - case "idleInhibitor": - return SessionService.idleInhibited ? "motion_sensor_active" : "motion_sensor_idle"; - default: - return "help"; - } - } - - text: { - switch (widgetData.id || "") { - case "nightMode": - return I18n.tr("Night Mode"); - case "darkMode": - return I18n.tr("Dark Mode"); - case "doNotDisturb": - return I18n.tr("Do Not Disturb"); - case "idleInhibitor": - return SessionService.idleInhibited ? I18n.tr("Keeping Awake") : I18n.tr("Keep Awake"); - default: - return I18n.tr("Unknown", "widget status"); - } - } - - iconRotation: { - if (widgetData.id !== "darkMode") - return 0; - if (darkModeTransitionPending) { - return SessionData.isLightMode ? 180 : 0; - } - return SessionData.isLightMode ? 180 : 0; - } - - isActive: { - switch (widgetData.id || "") { - case "nightMode": - return DisplayService.nightModeEnabled || false; - case "darkMode": - return !SessionData.isLightMode; - case "doNotDisturb": - return SessionData.doNotDisturb || false; - case "idleInhibitor": - return SessionService.idleInhibited || false; - default: - return false; - } - } - - enabled: !root.editMode - - onClicked: { - if (root.editMode) - return; - switch (widgetData.id || "") { - case "nightMode": - { - if (DisplayService.automationAvailable) - DisplayService.toggleNightMode(); - break; - } - case "darkMode": - { - const newMode = !SessionData.isLightMode; - Theme.screenTransition(); - Theme.setLightMode(newMode); - break; - } - case "doNotDisturb": - { - SessionData.setDoNotDisturb(!SessionData.doNotDisturb); - break; - } - case "idleInhibitor": - { - SessionService.toggleIdleInhibit(); - break; - } - } - } - } - } - - Component { - id: smallToggleComponent - SmallToggleButton { - property var widgetData: parent.widgetData || {} - property int widgetIndex: parent.widgetIndex || 0 - width: parent.width - height: 48 - - iconName: { - switch (widgetData.id || "") { - case "nightMode": - return DisplayService.nightModeEnabled ? "nightlight" : "dark_mode"; - case "darkMode": - return "contrast"; - case "doNotDisturb": - return SessionData.doNotDisturb ? "do_not_disturb_on" : "do_not_disturb_off"; - case "idleInhibitor": - return SessionService.idleInhibited ? "motion_sensor_active" : "motion_sensor_idle"; - default: - return "help"; - } - } - - iconRotation: { - if (widgetData.id !== "darkMode") - return 0; - if (darkModeTransitionPending) { - return SessionData.isLightMode ? 180 : 0; - } - return SessionData.isLightMode ? 180 : 0; - } - - isActive: { - switch (widgetData.id || "") { - case "nightMode": - return DisplayService.nightModeEnabled || false; - case "darkMode": - return !SessionData.isLightMode; - case "doNotDisturb": - return SessionData.doNotDisturb || false; - case "idleInhibitor": - return SessionService.idleInhibited || false; - default: - return false; - } - } - - enabled: !root.editMode - - onClicked: { - if (root.editMode) - return; - switch (widgetData.id || "") { - case "nightMode": - { - if (DisplayService.automationAvailable) - DisplayService.toggleNightMode(); - break; - } - case "darkMode": - { - const newMode = !SessionData.isLightMode; - Theme.screenTransition(); - Theme.setLightMode(newMode); - break; - } - case "doNotDisturb": - { - SessionData.setDoNotDisturb(!SessionData.doNotDisturb); - break; - } - case "idleInhibitor": - { - SessionService.toggleIdleInhibit(); - break; - } - } - } - } - } - - Component { - id: diskUsagePillComponent - DiskUsagePill { - property var widgetData: parent.widgetData || {} - property int widgetIndex: parent.widgetIndex || 0 - width: parent.width - height: 60 - - mountPath: widgetData.mountPath || "/" - instanceId: widgetData.instanceId || "" - - onExpandClicked: { - if (!root.editMode) { - root.expandClicked(widgetData, widgetIndex); - } - } - } - } - - Component { - id: smallDiskUsageComponent - SmallDiskUsageButton { - property var widgetData: parent.widgetData || {} - property int widgetIndex: parent.widgetIndex || 0 - width: parent.width - height: 48 - - mountPath: widgetData.mountPath || "/" - instanceId: widgetData.instanceId || "" - - onClicked: { - if (!root.editMode) { - root.expandClicked(widgetData, widgetIndex); - } - } - } - } - - Component { - id: colorPickerPillComponent - ColorPickerPill { - property var widgetData: parent.widgetData || {} - property int widgetIndex: parent.widgetIndex || 0 - width: parent.width - height: 60 - - colorPickerModal: root.colorPickerModal - } - } - - Component { - id: builtinPluginWidgetComponent - Loader { - property var widgetData: parent.widgetData || {} - property int widgetIndex: parent.widgetIndex || 0 - property int widgetWidth: widgetData.width || 50 - width: parent.width - height: 60 - - property var builtinInstance: null - - Component.onCompleted: { - const id = widgetData.id || ""; - if (id === "builtin_vpn") { - if (root.model?.vpnLoader) { - root.model.vpnLoader.active = true; - } - builtinInstance = Qt.binding(() => root.model?.vpnBuiltinInstance); - } - if (id === "builtin_cups") { - if (root.model?.cupsLoader) { - root.model.cupsLoader.active = true; - } - builtinInstance = Qt.binding(() => root.model?.cupsBuiltinInstance); - } - } - - sourceComponent: { - if (!builtinInstance) - return null; - - const hasDetail = builtinInstance.ccDetailContent !== null; - - if (widgetWidth <= 25) { - return builtinSmallToggleComponent; - } else if (hasDetail) { - return builtinCompoundPillComponent; - } else { - return builtinToggleComponent; - } - } - } - } - - Component { - id: builtinCompoundPillComponent - CompoundPill { - property var widgetData: parent.widgetData || {} - property int widgetIndex: parent.widgetIndex || 0 - property var builtinInstance: parent.builtinInstance - - iconName: builtinInstance?.ccWidgetIcon || "extension" - primaryText: builtinInstance?.ccWidgetPrimaryText || "Built-in" - secondaryText: builtinInstance?.ccWidgetSecondaryText || "" - isActive: builtinInstance?.ccWidgetIsActive || false - - onToggled: { - if (root.editMode) - return; - if (builtinInstance) { - builtinInstance.ccWidgetToggled(); - } - } - - onExpandClicked: { - if (root.editMode) - return; - if (builtinInstance) { - builtinInstance.ccWidgetExpanded(); - } - root.expandClicked(widgetData, widgetIndex); - } - } - } - - Component { - id: builtinToggleComponent - ToggleButton { - property var widgetData: parent.widgetData || {} - property int widgetIndex: parent.widgetIndex || 0 - property var builtinInstance: parent.builtinInstance - - iconName: builtinInstance?.ccWidgetIcon || "extension" - text: builtinInstance?.ccWidgetPrimaryText || "Built-in" - isActive: builtinInstance?.ccWidgetIsActive || false - enabled: !root.editMode - - onClicked: { - if (root.editMode) - return; - if (builtinInstance) { - builtinInstance.ccWidgetToggled(); - } - } - } - } - - Component { - id: builtinSmallToggleComponent - SmallToggleButton { - property var widgetData: parent.widgetData || {} - property int widgetIndex: parent.widgetIndex || 0 - property var builtinInstance: parent.builtinInstance - - iconName: builtinInstance?.ccWidgetIcon || "extension" - isActive: builtinInstance?.ccWidgetIsActive || false - enabled: !root.editMode - - onClicked: { - if (root.editMode) - return; - if (builtinInstance) { - builtinInstance.ccWidgetToggled(); - } - } - } - } - - Component { - id: pluginWidgetComponent - Loader { - property var widgetData: parent.widgetData || {} - property int widgetIndex: parent.widgetIndex || 0 - property int widgetWidth: widgetData.width || 50 - width: parent.width - height: 60 - - property var pluginInstance: null - property string pluginId: widgetData.id?.replace("plugin_", "") || "" - - sourceComponent: { - if (!pluginInstance) - return null; - - const hasDetail = pluginInstance.ccDetailContent !== null; - - if (widgetWidth <= 25) { - return pluginSmallToggleComponent; - } else if (hasDetail) { - return pluginCompoundPillComponent; - } else { - return pluginToggleComponent; - } - } - - function tryCreatePluginInstance() { - const pluginComponent = PluginService.pluginWidgetComponents[pluginId]; - if (!pluginComponent) - return false; - try { - const instance = pluginComponent.createObject(null, { - "pluginId": pluginId, - "pluginService": PluginService, - "visible": false, - "width": 0, - "height": 0 - }); - if (instance) { - pluginInstance = instance; - return true; - } - } catch (e) { - console.warn("DragDropGrid: stale plugin component for", pluginId, "- reloading"); - PluginService.reloadPlugin(pluginId); - } - return false; - } - - Component.onCompleted: { - Qt.callLater(() => tryCreatePluginInstance()); - } - - Connections { - target: PluginService - function onPluginDataChanged(changedPluginId) { - if (changedPluginId === pluginId && pluginInstance) { - pluginInstance.loadPluginData(); - } - } - function onPluginLoaded(loadedPluginId) { - if (loadedPluginId !== pluginId || pluginInstance) - return; - Qt.callLater(() => tryCreatePluginInstance()); - } - } - - Component.onDestruction: { - if (pluginInstance) { - pluginInstance.destroy(); - } - } - } - } - - Component { - id: pluginCompoundPillComponent - CompoundPill { - property var widgetData: parent.widgetData || {} - property int widgetIndex: parent.widgetIndex || 0 - property var pluginInstance: parent.pluginInstance - - iconName: pluginInstance?.ccWidgetIcon || "extension" - primaryText: pluginInstance?.ccWidgetPrimaryText || "Plugin" - secondaryText: pluginInstance?.ccWidgetSecondaryText || "" - isActive: pluginInstance?.ccWidgetIsActive || false - - onToggled: { - if (root.editMode) - return; - if (pluginInstance) { - pluginInstance.ccWidgetToggled(); - } - } - - onExpandClicked: { - if (root.editMode) - return; - if (pluginInstance) { - pluginInstance.ccWidgetExpanded(); - } - root.expandClicked(widgetData, widgetIndex); - } - } - } - - Component { - id: pluginToggleComponent - ToggleButton { - property var widgetData: parent.widgetData || {} - property int widgetIndex: parent.widgetIndex || 0 - property var pluginInstance: parent.pluginInstance - property var widgetDef: root.model?.getWidgetForId(widgetData.id || "") - - iconName: pluginInstance?.ccWidgetIcon || widgetDef?.icon || "extension" - text: pluginInstance?.ccWidgetPrimaryText || widgetDef?.text || "Plugin" - secondaryText: pluginInstance?.ccWidgetSecondaryText || "" - isActive: pluginInstance?.ccWidgetIsActive || false - enabled: !root.editMode - - onClicked: { - if (root.editMode) - return; - if (pluginInstance) { - pluginInstance.ccWidgetToggled(); - } - } - } - } - - Component { - id: pluginSmallToggleComponent - SmallToggleButton { - property var widgetData: parent.widgetData || {} - property int widgetIndex: parent.widgetIndex || 0 - property var pluginInstance: parent.pluginInstance - property var widgetDef: root.model?.getWidgetForId(widgetData.id || "") - - iconName: pluginInstance?.ccWidgetIcon || widgetDef?.icon || "extension" - isActive: pluginInstance?.ccWidgetIsActive || false - enabled: !root.editMode - - onClicked: { - if (root.editMode) - return; - if (pluginInstance && pluginInstance.ccDetailContent) { - root.expandClicked(widgetData, widgetIndex); - } else if (pluginInstance) { - pluginInstance.ccWidgetToggled(); - } - } - } - } -} diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Components/DragDropWidgetWrapper.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Components/DragDropWidgetWrapper.qml deleted file mode 100644 index 7cb0e2c..0000000 --- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Components/DragDropWidgetWrapper.qml +++ /dev/null @@ -1,289 +0,0 @@ -import QtQuick -import qs.Common -import qs.Services -import qs.Widgets - -Item { - id: root - - property bool editMode: false - property var widgetData: null - property int widgetIndex: -1 - property bool isSlider: false - property Component widgetComponent: null - property real gridCellWidth: 100 - property real gridCellHeight: 60 - property int gridColumns: 4 - property var gridLayout: null - - z: dragArea.drag.active ? 10000 : 1 - - signal widgetMoved(int fromIndex, int toIndex) - signal removeWidget(int index) - signal toggleWidgetSize(int index) - - width: { - const widgetWidth = widgetData?.width || 50 - if (widgetWidth <= 25) return gridCellWidth - else if (widgetWidth <= 50) return gridCellWidth * 2 - else if (widgetWidth <= 75) return gridCellWidth * 3 - else return gridCellWidth * 4 - } - height: isSlider ? 16 : gridCellHeight - - Rectangle { - id: dragIndicator - anchors.fill: parent - color: "transparent" - border.color: Theme.primary - border.width: dragArea.drag.active ? 2 : 0 - radius: Theme.cornerRadius - opacity: dragArea.drag.active ? 0.8 : 1.0 - z: dragArea.drag.active ? 10000 : 1 - - Behavior on border.width { - NumberAnimation { duration: 150 } - } - Behavior on opacity { - NumberAnimation { duration: 150 } - } - } - - Loader { - id: widgetLoader - anchors.fill: parent - sourceComponent: widgetComponent - property var widgetData: root.widgetData - property int widgetIndex: root.widgetIndex - property int globalWidgetIndex: root.widgetIndex - property int widgetWidth: root.widgetData?.width || 50 - - - MouseArea { - id: editModeBlocker - anchors.fill: parent - enabled: root.editMode - acceptedButtons: Qt.AllButtons - onPressed: function(mouse) { mouse.accepted = true } - onWheel: function(wheel) { wheel.accepted = true } - z: 100 - } - } - - MouseArea { - id: dragArea - anchors.fill: parent - enabled: editMode - cursorShape: editMode ? Qt.OpenHandCursor : Qt.PointingHandCursor - drag.target: editMode ? root : null - drag.axis: Drag.XAndYAxis - drag.smoothed: true - - onPressed: function(mouse) { - if (editMode) { - cursorShape = Qt.ClosedHandCursor - if (root.gridLayout && root.gridLayout.moveToTop) { - root.gridLayout.moveToTop(root) - } - } - } - - onReleased: function(mouse) { - if (editMode) { - cursorShape = Qt.OpenHandCursor - root.snapToGrid() - } - } - } - - Drag.active: dragArea.drag.active - Drag.hotSpot.x: width / 2 - Drag.hotSpot.y: height / 2 - - function swapIndices(i, j) { - if (i === j) return; - const arr = SettingsData.controlCenterWidgets; - if (!arr || i < 0 || j < 0 || i >= arr.length || j >= arr.length) return; - - const copy = arr.slice(); - const tmp = copy[i]; - copy[i] = copy[j]; - copy[j] = tmp; - - SettingsData.set("controlCenterWidgets", copy); - } - - function snapToGrid() { - if (!editMode || !gridLayout) return - - const globalPos = root.mapToItem(gridLayout, 0, 0) - const cellWidth = gridLayout.width / gridColumns - const cellHeight = gridCellHeight + Theme.spacingS - - const centerX = globalPos.x + (root.width / 2) - const centerY = globalPos.y + (root.height / 2) - - let targetCol = Math.max(0, Math.floor(centerX / cellWidth)) - let targetRow = Math.max(0, Math.floor(centerY / cellHeight)) - - targetCol = Math.min(targetCol, gridColumns - 1) - - const newIndex = findBestInsertionIndex(targetRow, targetCol) - - if (newIndex !== widgetIndex && newIndex >= 0 && newIndex < (SettingsData.controlCenterWidgets?.length || 0)) { - swapIndices(widgetIndex, newIndex) - } - } - - function findBestInsertionIndex(targetRow, targetCol) { - const widgets = SettingsData.controlCenterWidgets || []; - const n = widgets.length; - if (!n || widgetIndex < 0 || widgetIndex >= n) return -1; - - function spanFor(width) { - const w = width ?? 50; - if (w <= 25) return 1; - if (w <= 50) return 2; - if (w <= 75) return 3; - return 4; - } - - const cols = gridColumns || 4; - - let row = 0, col = 0; - let draggedOrigKey = null; - - const pos = []; - - for (let i = 0; i < n; i++) { - const span = Math.min(spanFor(widgets[i].width), cols); - - if (col + span > cols) { - row++; - col = 0; - } - - const startCol = col; - const centerKey = row * cols + (startCol + (span - 1) / 2); - - if (i === widgetIndex) { - draggedOrigKey = centerKey; - } else { - pos.push({ index: i, row, startCol, span, centerKey }); - } - - col += span; - if (col >= cols) { - row++; - col = 0; - } - } - - if (pos.length === 0) return -1; - - const centerColCoord = targetCol + 0.5; - const targetKey = targetRow * cols + centerColCoord; - - for (let k = 0; k < pos.length; k++) { - const p = pos[k]; - if (p.row === targetRow && centerColCoord >= p.startCol && centerColCoord < (p.startCol + p.span)) { - return p.index; - } - } - - let lo = 0, hi = pos.length - 1; - if (targetKey <= pos[0].centerKey) return pos[0].index; - if (targetKey >= pos[hi].centerKey) return pos[hi].index; - - while (lo <= hi) { - const mid = (lo + hi) >> 1; - const mk = pos[mid].centerKey; - if (targetKey < mk) hi = mid - 1; - else if (targetKey > mk) lo = mid + 1; - else return pos[mid].index; - } - const movingUp = (draggedOrigKey != null) ? (targetKey < draggedOrigKey) : false; - return (movingUp ? pos[lo].index : pos[hi].index); - } - - Rectangle { - width: 16 - height: 16 - radius: 8 - color: Theme.error - anchors.top: parent.top - anchors.right: parent.right - anchors.margins: -4 - visible: editMode - z: 10 - - DankIcon { - anchors.centerIn: parent - name: "close" - size: 12 - color: Theme.primaryText - } - - MouseArea { - anchors.fill: parent - cursorShape: Qt.PointingHandCursor - onClicked: removeWidget(widgetIndex) - } - } - - SizeControls { - anchors.bottom: parent.bottom - anchors.left: parent.left - anchors.margins: -6 - visible: editMode - z: 10 - currentSize: root.widgetData?.width || 50 - isSlider: root.isSlider - widgetIndex: root.widgetIndex - onSizeChanged: (newSize) => { - var widgets = SettingsData.controlCenterWidgets.slice() - if (widgetIndex >= 0 && widgetIndex < widgets.length) { - widgets[widgetIndex].width = newSize - SettingsData.set("controlCenterWidgets", widgets) - } - } - } - - Rectangle { - id: dragHandle - width: 16 - height: 12 - radius: 2 - color: Theme.primary - anchors.top: parent.top - anchors.left: parent.left - anchors.margins: 4 - visible: editMode - z: 15 - opacity: dragArea.drag.active ? 1.0 : 0.7 - - DankIcon { - anchors.centerIn: parent - name: "drag_indicator" - size: 10 - color: Theme.primaryText - } - - Behavior on opacity { - NumberAnimation { duration: 150 } - } - } - - Rectangle { - anchors.fill: parent - color: editMode ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08) : "transparent" - radius: Theme.cornerRadius - border.color: "transparent" - border.width: 0 - z: -1 - - Behavior on color { - ColorAnimation { duration: Theme.shortDuration } - } - } -} diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Components/EditControls.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Components/EditControls.qml deleted file mode 100644 index 50531aa..0000000 --- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Components/EditControls.qml +++ /dev/null @@ -1,245 +0,0 @@ -import QtQuick -import QtQuick.Controls -import qs.Common -import qs.Widgets - -Row { - id: root - - LayoutMirroring.enabled: I18n.isRtl - LayoutMirroring.childrenInherit: true - - property var availableWidgets: [] - property Item popoutContent: null - - signal addWidget(string widgetId) - signal resetToDefault - signal clearAll - - height: 48 - spacing: Theme.spacingS - - onAddWidget: addWidgetPopup.close() - - Popup { - id: addWidgetPopup - parent: popoutContent - x: parent ? Math.round((parent.width - width) / 2) : 0 - y: parent ? Math.round((parent.height - height) / 2) : 0 - width: 400 - height: 300 - modal: false - focus: true - closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside - - background: Rectangle { - color: Theme.withAlpha(Theme.surfaceContainer, Theme.popupTransparency) - border.color: Theme.primarySelected - border.width: 0 - radius: Theme.cornerRadius - } - - contentItem: Item { - anchors.fill: parent - anchors.margins: Theme.spacingL - - Row { - id: headerRow - anchors.top: parent.top - anchors.left: parent.left - anchors.right: parent.right - spacing: Theme.spacingM - - DankIcon { - name: "add_circle" - size: Theme.iconSize - color: Theme.primary - anchors.verticalCenter: parent.verticalCenter - } - - Typography { - text: I18n.tr("Add Widget") - style: Typography.Style.Subtitle - color: Theme.surfaceText - anchors.verticalCenter: parent.verticalCenter - } - } - - DankListView { - anchors.top: headerRow.bottom - anchors.topMargin: Theme.spacingM - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: parent.bottom - spacing: Theme.spacingS - clip: true - model: root.availableWidgets - - delegate: Rectangle { - width: 400 - Theme.spacingL * 2 - height: 50 - radius: Theme.cornerRadius - color: widgetMouseArea.containsMouse ? Theme.primaryHover : Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency) - border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2) - border.width: 0 - - Row { - anchors.fill: parent - anchors.margins: Theme.spacingM - spacing: Theme.spacingM - - DankIcon { - name: modelData.icon - size: Theme.iconSize - color: Theme.primary - anchors.verticalCenter: parent.verticalCenter - } - - Column { - anchors.verticalCenter: parent.verticalCenter - spacing: 2 - width: 400 - Theme.spacingL * 2 - Theme.iconSize - Theme.spacingM * 3 - Theme.iconSize - - Typography { - text: modelData.text - style: Typography.Style.Body - color: Theme.surfaceText - elide: Text.ElideRight - width: parent.width - horizontalAlignment: Text.AlignLeft - } - - Typography { - text: modelData.description - style: Typography.Style.Caption - color: Theme.outline - elide: Text.ElideRight - width: parent.width - horizontalAlignment: Text.AlignLeft - } - } - - DankIcon { - name: "add" - size: Theme.iconSize - 4 - color: Theme.primary - anchors.verticalCenter: parent.verticalCenter - } - } - - MouseArea { - id: widgetMouseArea - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onClicked: { - root.addWidget(modelData.id); - } - } - } - } - } - } - - Rectangle { - width: (parent.width - Theme.spacingS * 2) / 3 - height: 48 - radius: Theme.cornerRadius - color: Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) - border.color: Theme.primary - border.width: 0 - - Row { - anchors.centerIn: parent - spacing: Theme.spacingS - - DankIcon { - name: "add" - size: Theme.iconSize - 2 - color: Theme.primary - anchors.verticalCenter: parent.verticalCenter - } - - Typography { - text: I18n.tr("Add Widget") - style: Typography.Style.Button - color: Theme.primary - anchors.verticalCenter: parent.verticalCenter - } - } - - MouseArea { - anchors.fill: parent - cursorShape: Qt.PointingHandCursor - onClicked: addWidgetPopup.open() - } - } - - Rectangle { - width: (parent.width - Theme.spacingS * 2) / 3 - height: 48 - radius: Theme.cornerRadius - color: Qt.rgba(Theme.warning.r, Theme.warning.g, Theme.warning.b, 0.12) - border.color: Theme.warning - border.width: 0 - - Row { - anchors.centerIn: parent - spacing: Theme.spacingS - - DankIcon { - name: "settings_backup_restore" - size: Theme.iconSize - 2 - color: Theme.warning - anchors.verticalCenter: parent.verticalCenter - } - - Typography { - text: I18n.tr("Defaults") - style: Typography.Style.Button - color: Theme.warning - anchors.verticalCenter: parent.verticalCenter - } - } - - MouseArea { - anchors.fill: parent - cursorShape: Qt.PointingHandCursor - onClicked: root.resetToDefault() - } - } - - Rectangle { - width: (parent.width - Theme.spacingS * 2) / 3 - height: 48 - radius: Theme.cornerRadius - color: Qt.rgba(Theme.error.r, Theme.error.g, Theme.error.b, 0.12) - border.color: Theme.error - border.width: 0 - - Row { - anchors.centerIn: parent - spacing: Theme.spacingS - - DankIcon { - name: "clear_all" - size: Theme.iconSize - 2 - color: Theme.error - anchors.verticalCenter: parent.verticalCenter - } - - Typography { - text: I18n.tr("Reset") - style: Typography.Style.Button - color: Theme.error - anchors.verticalCenter: parent.verticalCenter - } - } - - MouseArea { - anchors.fill: parent - cursorShape: Qt.PointingHandCursor - onClicked: root.clearAll() - } - } -} diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Components/HeaderPane.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Components/HeaderPane.qml deleted file mode 100644 index d36c5b6..0000000 --- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Components/HeaderPane.qml +++ /dev/null @@ -1,118 +0,0 @@ -import QtQuick -import qs.Common -import qs.Services -import qs.Widgets - -Rectangle { - id: root - - LayoutMirroring.enabled: I18n.isRtl - LayoutMirroring.childrenInherit: true - - property bool editMode: false - - signal powerButtonClicked - signal lockRequested - signal editModeToggled - signal settingsButtonClicked - - Component.onCompleted: DgopService.addRef("system") - Component.onDestruction: DgopService.removeRef("system") - - implicitHeight: 70 - radius: Theme.cornerRadius - color: Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency) - border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08) - border.width: 0 - - Row { - anchors.left: parent.left - anchors.verticalCenter: parent.verticalCenter - anchors.leftMargin: Theme.spacingL - anchors.rightMargin: Theme.spacingL - spacing: Theme.spacingM - - DankCircularImage { - id: avatarContainer - - width: 60 - height: 60 - imageSource: { - if (PortalService.profileImage === "") - return ""; - - if (PortalService.profileImage.startsWith("/")) - return "file://" + PortalService.profileImage; - - return PortalService.profileImage; - } - fallbackIcon: "person" - } - - Column { - anchors.verticalCenter: parent.verticalCenter - spacing: 2 - - Typography { - text: UserInfoService.fullName || UserInfoService.username || I18n.tr("User") - style: Typography.Style.Subtitle - color: Theme.surfaceText - } - - Typography { - text: DgopService.uptime || I18n.tr("Unknown") - style: Typography.Style.Caption - color: Theme.surfaceVariantText - } - } - } - - Row { - id: actionButtonsRow - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - anchors.rightMargin: Theme.spacingXS - spacing: Theme.spacingXS - - DankActionButton { - buttonSize: 36 - iconName: "lock" - iconSize: Theme.iconSize - 4 - iconColor: Theme.surfaceText - backgroundColor: "transparent" - onClicked: { - root.lockRequested(); - } - } - - DankActionButton { - buttonSize: 36 - iconName: "power_settings_new" - iconSize: Theme.iconSize - 4 - iconColor: Theme.surfaceText - backgroundColor: "transparent" - onClicked: root.powerButtonClicked() - } - - DankActionButton { - buttonSize: 36 - iconName: "settings" - iconSize: Theme.iconSize - 4 - iconColor: Theme.surfaceText - backgroundColor: "transparent" - onClicked: { - root.settingsButtonClicked(); - PopoutService.focusOrToggleSettings(); - } - } - - DankActionButton { - buttonSize: 36 - iconName: editMode ? "done" : "edit" - iconSize: Theme.iconSize - 4 - iconColor: editMode ? Theme.primary : Theme.surfaceText - backgroundColor: "transparent" - onClicked: root.editModeToggled() - } - } -} diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Components/PowerButton.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Components/PowerButton.qml deleted file mode 100644 index 8ed7444..0000000 --- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Components/PowerButton.qml +++ /dev/null @@ -1,55 +0,0 @@ -import QtQuick -import qs.Common -import qs.Widgets - -Rectangle { - id: root - - LayoutMirroring.enabled: I18n.isRtl - LayoutMirroring.childrenInherit: true - - property string iconName: "" - property string text: "" - - signal pressed - - height: 34 - radius: Theme.cornerRadius - color: mouseArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.5) - - Row { - anchors.centerIn: parent - spacing: Theme.spacingXS - - DankIcon { - name: root.iconName - size: Theme.fontSizeSmall - color: mouseArea.containsMouse ? Theme.primary : Theme.surfaceText - anchors.verticalCenter: parent.verticalCenter - } - - Typography { - text: root.text - style: Typography.Style.Button - color: mouseArea.containsMouse ? Theme.primary : Theme.surfaceText - anchors.verticalCenter: parent.verticalCenter - } - } - - DankRipple { - id: ripple - cornerRadius: root.radius - } - - MouseArea { - id: mouseArea - - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onPressed: mouse => { - ripple.trigger(mouse.x, mouse.y); - root.pressed(); - } - } -} diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Components/SizeControls.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Components/SizeControls.qml deleted file mode 100644 index aeae4ee..0000000 --- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Components/SizeControls.qml +++ /dev/null @@ -1,52 +0,0 @@ -import QtQuick -import QtQuick.Controls -import qs.Common -import qs.Widgets - -Row { - id: root - - property int currentSize: 50 - property bool isSlider: false - property int widgetIndex: -1 - - signal sizeChanged(int newSize) - - readonly property var availableSizes: isSlider ? [50, 75, 100] : [25, 50, 75, 100] - - spacing: 2 - - Repeater { - model: root.availableSizes - - Rectangle { - width: 16 - height: 16 - radius: 3 - color: modelData === root.currentSize ? Theme.primary : Theme.surfaceContainer - border.color: modelData === root.currentSize ? Theme.primary : Theme.outline - border.width: 1 - - StyledText { - anchors.centerIn: parent - text: modelData.toString() - font.pixelSize: 8 - font.weight: Font.Medium - color: modelData === root.currentSize ? Theme.primaryText : Theme.surfaceText - } - - MouseArea { - anchors.fill: parent - cursorShape: Qt.PointingHandCursor - onClicked: { - root.currentSize = modelData - root.sizeChanged(modelData) - } - } - - Behavior on color { - ColorAnimation { duration: Theme.shortDuration } - } - } - } -} diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Components/Typography.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Components/Typography.qml deleted file mode 100644 index f3e554f..0000000 --- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Components/Typography.qml +++ /dev/null @@ -1,46 +0,0 @@ -import QtQuick -import qs.Common -import qs.Widgets - -StyledText { - id: root - - enum Style { - Title, - Subtitle, - Body, - Caption, - Button - } - - property int style: Typography.Style.Body - - font.pixelSize: { - switch (style) { - case Typography.Style.Title: return Theme.fontSizeXLarge - case Typography.Style.Subtitle: return Theme.fontSizeLarge - case Typography.Style.Body: return Theme.fontSizeMedium - case Typography.Style.Caption: return Theme.fontSizeSmall - case Typography.Style.Button: return Theme.fontSizeSmall - default: return Theme.fontSizeMedium - } - } - - font.weight: { - switch (style) { - case Typography.Style.Title: return Font.Bold - case Typography.Style.Subtitle: return Font.Medium - case Typography.Style.Body: return Font.Normal - case Typography.Style.Caption: return Font.Normal - case Typography.Style.Button: return Font.Medium - default: return Font.Normal - } - } - - color: { - switch (style) { - case Typography.Style.Caption: return Theme.surfaceVariantText - default: return Theme.surfaceText - } - } -} diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/ControlCenterPopout.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/ControlCenterPopout.qml deleted file mode 100644 index d8839aa..0000000 --- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/ControlCenterPopout.qml +++ /dev/null @@ -1,272 +0,0 @@ -import QtQuick -import Quickshell.Wayland -import qs.Common -import qs.Modules.ControlCenter.Details -import qs.Services -import qs.Widgets -import qs.Modules.ControlCenter.Components -import qs.Modules.ControlCenter.Models -import "./utils/state.js" as StateUtils - -DankPopout { - id: root - - layerNamespace: "dms:control-center" - fullHeightSurface: true - - property string expandedSection: "" - property var triggerScreen: null - property bool editMode: false - property int expandedWidgetIndex: -1 - property var expandedWidgetData: null - property bool powerMenuOpen: powerMenuModalLoader?.item?.shouldBeVisible ?? false - - signal lockRequested - - function collapseAll() { - expandedSection = ""; - expandedWidgetIndex = -1; - expandedWidgetData = null; - } - - onEditModeChanged: { - if (editMode) { - collapseAll(); - } - } - - onVisibleChanged: { - if (!visible) { - collapseAll(); - } - } - - readonly property color _containerBg: Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency) - - function openWithSection(section) { - StateUtils.openWithSection(root, section); - } - - function toggleSection(section) { - StateUtils.toggleSection(root, section); - } - - popupWidth: 550 - popupHeight: { - const screenHeight = (triggerScreen?.height ?? 1080); - const maxHeight = screenHeight - 100; - const contentHeight = contentLoader.item && contentLoader.item.implicitHeight > 0 ? contentLoader.item.implicitHeight + 20 : 400; - return Math.min(maxHeight, contentHeight); - } - triggerWidth: 80 - positioning: "" - screen: triggerScreen - shouldBeVisible: false - - property bool credentialsPromptOpen: NetworkService.credentialsRequested - property bool wifiPasswordModalOpen: PopoutService.wifiPasswordModal?.visible ?? false - property bool polkitModalOpen: PopoutService.polkitAuthModal?.visible ?? false - property bool anyModalOpen: credentialsPromptOpen || wifiPasswordModalOpen || polkitModalOpen || powerMenuOpen - - backgroundInteractive: !anyModalOpen - - onCredentialsPromptOpenChanged: { - if (credentialsPromptOpen && shouldBeVisible) - close(); - } - - onPolkitModalOpenChanged: { - if (polkitModalOpen && shouldBeVisible) - close(); - } - - customKeyboardFocus: { - if (!shouldBeVisible) - return WlrKeyboardFocus.None; - if (anyModalOpen) - return WlrKeyboardFocus.None; - if (CompositorService.useHyprlandFocusGrab) - return WlrKeyboardFocus.OnDemand; - return WlrKeyboardFocus.Exclusive; - } - - onBackgroundClicked: close() - - onShouldBeVisibleChanged: { - if (shouldBeVisible) { - collapseAll(); - Qt.callLater(() => { - if (NetworkService.activeService) - NetworkService.activeService.autoRefreshEnabled = NetworkService.wifiEnabled; - }); - } else { - Qt.callLater(() => { - if (NetworkService.activeService) { - NetworkService.activeService.autoRefreshEnabled = false; - } - if (BluetoothService.adapter && BluetoothService.adapter.discovering) - BluetoothService.adapter.discovering = false; - editMode = false; - }); - } - } - - WidgetModel { - id: widgetModel - } - - content: Component { - Rectangle { - id: controlContent - - LayoutMirroring.enabled: I18n.isRtl - LayoutMirroring.childrenInherit: true - - implicitHeight: mainColumn.implicitHeight + Theme.spacingM - property alias bluetoothCodecSelector: bluetoothCodecSelector - - color: "transparent" - clip: true - - Rectangle { - anchors.fill: parent - color: Qt.rgba(0, 0, 0, 0.6) - radius: parent.radius - visible: root.powerMenuOpen - z: 5000 - - Behavior on opacity { - NumberAnimation { - duration: 200 - easing.type: Easing.OutCubic - } - } - } - - Column { - id: mainColumn - width: parent.width - Theme.spacingL * 2 - x: Theme.spacingL - y: Theme.spacingL - spacing: Theme.spacingS - - HeaderPane { - id: headerPane - width: parent.width - editMode: root.editMode - onEditModeToggled: root.editMode = !root.editMode - onPowerButtonClicked: { - if (powerMenuModalLoader) { - powerMenuModalLoader.active = true; - if (powerMenuModalLoader.item) { - const bounds = Qt.rect(root.alignedX, root.alignedY, root.popupWidth, root.popupHeight); - powerMenuModalLoader.item.openFromControlCenter(bounds, root.screen); - } - } - } - onLockRequested: { - root.close(); - root.lockRequested(); - } - onSettingsButtonClicked: { - root.close(); - } - } - - DragDropGrid { - id: widgetGrid - width: parent.width - editMode: root.editMode - maxPopoutHeight: { - const screenHeight = (root.triggerScreen?.height ?? 1080); - return screenHeight - 100 - Theme.spacingL - headerPane.height - Theme.spacingS; - } - expandedSection: root.expandedSection - expandedWidgetIndex: root.expandedWidgetIndex - expandedWidgetData: root.expandedWidgetData - model: widgetModel - bluetoothCodecSelector: bluetoothCodecSelector - colorPickerModal: root.colorPickerModal - screenName: root.triggerScreen?.name || "" - screenModel: root.triggerScreen?.model || "" - parentScreen: root.triggerScreen - onExpandClicked: (widgetData, globalIndex) => { - root.expandedWidgetIndex = globalIndex; - root.expandedWidgetData = widgetData; - if (widgetData.id === "diskUsage") { - root.toggleSection("diskUsage_" + (widgetData.instanceId || "default")); - } else if (widgetData.id === "brightnessSlider") { - root.toggleSection("brightnessSlider_" + (widgetData.instanceId || "default")); - } else { - root.toggleSection(widgetData.id); - } - } - onRemoveWidget: index => widgetModel.removeWidget(index) - onMoveWidget: (fromIndex, toIndex) => widgetModel.moveWidget(fromIndex, toIndex) - onToggleWidgetSize: index => widgetModel.toggleWidgetSize(index) - onCollapseRequested: root.collapseAll() - } - - EditControls { - width: parent.width - visible: editMode - popoutContent: controlContent - availableWidgets: { - if (!editMode) - return []; - const existingIds = (SettingsData.controlCenterWidgets || []).map(w => w.id); - const allWidgets = widgetModel.baseWidgetDefinitions.concat(widgetModel.getPluginWidgets()); - return allWidgets.filter(w => w.allowMultiple || !existingIds.includes(w.id)); - } - onAddWidget: widgetId => widgetModel.addWidget(widgetId) - onResetToDefault: () => widgetModel.resetToDefault() - onClearAll: () => widgetModel.clearAll() - } - } - - BluetoothCodecSelector { - id: bluetoothCodecSelector - anchors.fill: parent - z: 10000 - } - } - } - - Component { - id: networkDetailComponent - NetworkDetail {} - } - - Component { - id: bluetoothDetailComponent - BluetoothDetail { - id: bluetoothDetail - onShowCodecSelector: function (device) { - if (contentLoader.item && contentLoader.item.bluetoothCodecSelector) { - contentLoader.item.bluetoothCodecSelector.show(device); - contentLoader.item.bluetoothCodecSelector.codecSelected.connect(function (deviceAddress, codecName) { - bluetoothDetail.updateDeviceCodecDisplay(deviceAddress, codecName); - }); - } - } - } - } - - Component { - id: audioOutputDetailComponent - AudioOutputDetail {} - } - - Component { - id: audioInputDetailComponent - AudioInputDetail {} - } - - Component { - id: batteryDetailComponent - BatteryDetail {} - } - - property var colorPickerModal: null - property var powerMenuModalLoader: null -} diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Details/AudioInputDetail.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Details/AudioInputDetail.qml deleted file mode 100644 index 8fc2d46..0000000 --- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Details/AudioInputDetail.qml +++ /dev/null @@ -1,363 +0,0 @@ -import QtQuick -import Quickshell -import Quickshell.Services.Pipewire -import qs.Common -import qs.Services -import qs.Widgets - -Rectangle { - id: root - - LayoutMirroring.enabled: I18n.isRtl - LayoutMirroring.childrenInherit: true - - property bool hasInputVolumeSliderInCC: { - const widgets = SettingsData.controlCenterWidgets || []; - return widgets.some(widget => widget.id === "inputVolumeSlider"); - } - - implicitHeight: headerRow.height + (hasInputVolumeSliderInCC ? 0 : volumeSlider.height) + audioContent.height + Theme.spacingM - radius: Theme.cornerRadius - color: Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency) - border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08) - border.width: 0 - - Row { - id: headerRow - anchors.left: parent.left - anchors.right: parent.right - anchors.top: parent.top - anchors.leftMargin: Theme.spacingM - anchors.rightMargin: Theme.spacingM - anchors.topMargin: Theme.spacingS - height: 40 - - StyledText { - id: headerText - text: I18n.tr("Input Devices") - font.pixelSize: Theme.fontSizeLarge - color: Theme.surfaceText - font.weight: Font.Medium - anchors.verticalCenter: parent.verticalCenter - } - - Item { - height: 1 - width: parent.width - headerText.width - settingsButton.width - } - - DankActionButton { - id: settingsButton - anchors.verticalCenter: parent.verticalCenter - iconName: "settings" - buttonSize: 28 - iconSize: 16 - iconColor: Theme.surfaceVariantText - onClicked: { - PopoutService.closeControlCenter(); - PopoutService.openSettingsWithTab("audio"); - } - } - } - - Row { - id: volumeSlider - anchors.left: parent.left - anchors.right: parent.right - anchors.top: headerRow.bottom - anchors.leftMargin: Theme.spacingM - anchors.rightMargin: Theme.spacingM - anchors.topMargin: Theme.spacingXS - height: 35 - spacing: 0 - visible: !hasInputVolumeSliderInCC - - Rectangle { - width: Theme.iconSize + Theme.spacingS * 2 - height: Theme.iconSize + Theme.spacingS * 2 - anchors.verticalCenter: parent.verticalCenter - radius: (Theme.iconSize + Theme.spacingS * 2) / 2 - color: iconArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : "transparent" - - DankRipple { - id: iconRipple - cornerRadius: parent.radius - } - - MouseArea { - id: iconArea - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onPressed: mouse => iconRipple.trigger(mouse.x, mouse.y) - onClicked: { - if (AudioService.source && AudioService.source.audio) { - AudioService.source.audio.muted = !AudioService.source.audio.muted; - } - } - } - - DankIcon { - anchors.centerIn: parent - name: { - if (!AudioService.source || !AudioService.source.audio) - return "mic_off"; - let muted = AudioService.source.audio.muted; - return muted ? "mic_off" : "mic"; - } - size: Theme.iconSize - color: AudioService.source && AudioService.source.audio && !AudioService.source.audio.muted && AudioService.source.audio.volume > 0 ? Theme.primary : Theme.surfaceText - } - } - - DankSlider { - readonly property real actualVolumePercent: AudioService.source && AudioService.source.audio ? Math.round(AudioService.source.audio.volume * 100) : 0 - - anchors.verticalCenter: parent.verticalCenter - width: parent.width - (Theme.iconSize + Theme.spacingS * 2) - enabled: AudioService.source && AudioService.source.audio - minimum: 0 - maximum: 100 - value: AudioService.source && AudioService.source.audio ? Math.min(100, Math.round(AudioService.source.audio.volume * 100)) : 0 - showValue: true - unit: "%" - valueOverride: actualVolumePercent - thumbOutlineColor: Theme.surfaceVariant - - onSliderValueChanged: function (newValue) { - if (AudioService.source && AudioService.source.audio) { - AudioService.source.audio.volume = newValue / 100; - if (newValue > 0 && AudioService.source.audio.muted) { - AudioService.source.audio.muted = false; - } - } - } - } - } - - DankFlickable { - id: audioContent - anchors.top: hasInputVolumeSliderInCC ? headerRow.bottom : volumeSlider.bottom - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: parent.bottom - anchors.margins: Theme.spacingM - anchors.topMargin: hasInputVolumeSliderInCC ? Theme.spacingM : Theme.spacingS - contentHeight: audioColumn.height - clip: true - - property int maxPinnedInputs: 3 - - function normalizePinList(value) { - if (Array.isArray(value)) - return value.filter(v => v); - if (typeof value === "string" && value.length > 0) - return [value]; - return []; - } - - function getPinnedInputs() { - const pins = SettingsData.audioInputDevicePins || {}; - return normalizePinList(pins["preferredInput"]); - } - - Column { - id: audioColumn - width: parent.width - spacing: Theme.spacingS - - Repeater { - model: ScriptModel { - values: { - const hidden = SessionData.hiddenInputDeviceNames ?? []; - const nodes = Pipewire.nodes.values.filter(node => { - if (!node.audio || node.isSink || node.isStream) - return false; - return !hidden.includes(node.name); - }); - const pinnedList = audioContent.getPinnedInputs(); - - let sorted = [...nodes]; - sorted.sort((a, b) => { - // Pinned device first - const aPinnedIndex = pinnedList.indexOf(a.name); - const bPinnedIndex = pinnedList.indexOf(b.name); - if (aPinnedIndex !== -1 || bPinnedIndex !== -1) { - if (aPinnedIndex === -1) - return 1; - if (bPinnedIndex === -1) - return -1; - return aPinnedIndex - bPinnedIndex; - } - // Then active device - if (a === AudioService.source && b !== AudioService.source) - return -1; - if (b === AudioService.source && a !== AudioService.source) - return 1; - return 0; - }); - return sorted; - } - } - - delegate: Rectangle { - required property var modelData - required property int index - - width: parent.width - height: 50 - radius: Theme.cornerRadius - color: deviceMouseArea.containsMouse ? Theme.primaryHoverLight : Theme.surfaceLight - border.color: modelData === AudioService.source ? Theme.primary : Theme.outlineLight - border.width: modelData === AudioService.source ? 2 : 1 - - Row { - anchors.left: parent.left - anchors.verticalCenter: parent.verticalCenter - anchors.leftMargin: Theme.spacingM - spacing: Theme.spacingS - - DankIcon { - name: { - if (modelData.name.includes("bluez")) - return "headset"; - else if (modelData.name.includes("usb")) - return "headset"; - else - return "mic"; - } - size: Theme.iconSize - 4 - color: modelData === AudioService.source ? Theme.primary : Theme.surfaceText - anchors.verticalCenter: parent.verticalCenter - } - - Column { - anchors.verticalCenter: parent.verticalCenter - width: { - const iconWidth = Theme.iconSize; - const pinButtonWidth = pinInputRow.width + Theme.spacingS * 4 + Theme.spacingM; - return parent.parent.width - iconWidth - parent.spacing - pinButtonWidth - Theme.spacingM * 2; - } - - StyledText { - text: AudioService.displayName(modelData) - font.pixelSize: Theme.fontSizeMedium - color: Theme.surfaceText - font.weight: modelData === AudioService.source ? Font.Medium : Font.Normal - elide: Text.ElideRight - width: parent.width - wrapMode: Text.NoWrap - horizontalAlignment: Text.AlignLeft - } - - StyledText { - text: modelData === AudioService.source ? I18n.tr("Active") : I18n.tr("Available") - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceVariantText - elide: Text.ElideRight - width: parent.width - wrapMode: Text.NoWrap - horizontalAlignment: Text.AlignLeft - } - } - } - - Rectangle { - anchors.right: parent.right - anchors.rightMargin: Theme.spacingM - anchors.verticalCenter: parent.verticalCenter - width: pinInputRow.width + Theme.spacingS * 2 - height: 28 - radius: height / 2 - color: { - const isThisDevicePinned = audioContent.getPinnedInputs().includes(modelData.name); - return isThisDevicePinned ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : Theme.withAlpha(Theme.surfaceText, 0.05); - } - - Row { - id: pinInputRow - anchors.centerIn: parent - spacing: 4 - - DankIcon { - name: "push_pin" - size: 16 - color: { - const isThisDevicePinned = audioContent.getPinnedInputs().includes(modelData.name); - return isThisDevicePinned ? Theme.primary : Theme.surfaceText; - } - anchors.verticalCenter: parent.verticalCenter - } - - StyledText { - text: { - const isThisDevicePinned = audioContent.getPinnedInputs().includes(modelData.name); - return isThisDevicePinned ? I18n.tr("Pinned") : I18n.tr("Pin"); - } - font.pixelSize: Theme.fontSizeSmall - color: { - const isThisDevicePinned = audioContent.getPinnedInputs().includes(modelData.name); - return isThisDevicePinned ? Theme.primary : Theme.surfaceText; - } - anchors.verticalCenter: parent.verticalCenter - } - } - - DankRipple { - id: pinRipple - cornerRadius: parent.radius - } - - MouseArea { - anchors.fill: parent - cursorShape: Qt.PointingHandCursor - onPressed: mouse => pinRipple.trigger(mouse.x, mouse.y) - onClicked: { - const pins = JSON.parse(JSON.stringify(SettingsData.audioInputDevicePins || {})); - let pinnedList = audioContent.normalizePinList(pins["preferredInput"]); - const pinIndex = pinnedList.indexOf(modelData.name); - - if (pinIndex !== -1) { - pinnedList.splice(pinIndex, 1); - } else { - pinnedList.unshift(modelData.name); - if (pinnedList.length > audioContent.maxPinnedInputs) - pinnedList = pinnedList.slice(0, audioContent.maxPinnedInputs); - } - - if (pinnedList.length > 0) - pins["preferredInput"] = pinnedList; - else - delete pins["preferredInput"]; - - SettingsData.set("audioInputDevicePins", pins); - } - } - } - - DankRipple { - id: deviceRipple - cornerRadius: parent.radius - } - - MouseArea { - id: deviceMouseArea - anchors.fill: parent - anchors.rightMargin: pinInputRow.width + Theme.spacingS * 4 - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onPressed: mouse => { - let mapped = mapToItem(parent, mouse.x, mouse.y); - deviceRipple.trigger(mapped.x, mapped.y); - } - onClicked: { - if (modelData) { - Pipewire.preferredDefaultAudioSource = modelData; - } - } - } - } - } - } - } -} diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Details/AudioOutputDetail.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Details/AudioOutputDetail.qml deleted file mode 100644 index 7e86ae4..0000000 --- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Details/AudioOutputDetail.qml +++ /dev/null @@ -1,544 +0,0 @@ -import QtQuick -import Quickshell -import Quickshell.Services.Pipewire -import qs.Common -import qs.Services -import qs.Widgets - -Rectangle { - id: root - - LayoutMirroring.enabled: I18n.isRtl - LayoutMirroring.childrenInherit: true - - property bool hasVolumeSliderInCC: { - const widgets = SettingsData.controlCenterWidgets || []; - return widgets.some(widget => widget.id === "volumeSlider"); - } - - implicitHeight: headerRow.height + (!hasVolumeSliderInCC ? volumeSlider.height : 0) + audioContent.height + Theme.spacingM - radius: Theme.cornerRadius - color: Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency) - border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08) - border.width: 0 - - Row { - id: headerRow - anchors.left: parent.left - anchors.right: parent.right - anchors.top: parent.top - anchors.leftMargin: Theme.spacingM - anchors.rightMargin: Theme.spacingM - anchors.topMargin: Theme.spacingS - height: 40 - - StyledText { - id: headerText - text: I18n.tr("Audio Devices") - font.pixelSize: Theme.fontSizeLarge - color: Theme.surfaceText - font.weight: Font.Medium - anchors.verticalCenter: parent.verticalCenter - } - - Item { - height: 1 - width: parent.width - headerText.width - settingsButton.width - } - - DankActionButton { - id: settingsButton - anchors.verticalCenter: parent.verticalCenter - iconName: "settings" - buttonSize: 28 - iconSize: 16 - iconColor: Theme.surfaceVariantText - onClicked: { - PopoutService.closeControlCenter(); - PopoutService.openSettingsWithTab("audio"); - } - } - } - - Row { - id: volumeSlider - anchors.left: parent.left - anchors.right: parent.right - anchors.top: headerRow.bottom - anchors.leftMargin: Theme.spacingM - anchors.rightMargin: Theme.spacingM - anchors.topMargin: Theme.spacingXS - height: 35 - spacing: 0 - visible: !hasVolumeSliderInCC - - Rectangle { - width: Theme.iconSize + Theme.spacingS * 2 - height: Theme.iconSize + Theme.spacingS * 2 - anchors.verticalCenter: parent.verticalCenter - radius: (Theme.iconSize + Theme.spacingS * 2) / 2 - color: iconArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : "transparent" - - DankRipple { - id: muteRipple - cornerRadius: parent.radius - } - - MouseArea { - id: iconArea - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onPressed: mouse => muteRipple.trigger(mouse.x, mouse.y) - onClicked: { - if (AudioService.sink && AudioService.sink.audio) { - AudioService.sink.audio.muted = !AudioService.sink.audio.muted; - } - } - } - - DankIcon { - anchors.centerIn: parent - name: { - if (!AudioService.sink || !AudioService.sink.audio) - return "volume_off"; - let muted = AudioService.sink.audio.muted; - let volume = AudioService.sink.audio.volume; - if (muted) - return "volume_off"; - if (volume === 0.0) - return "volume_mute"; - if (volume <= 0.33) - return "volume_down"; - if (volume <= 0.66) - return "volume_up"; - return "volume_up"; - } - size: Theme.iconSize - color: AudioService.sink && AudioService.sink.audio && !AudioService.sink.audio.muted && AudioService.sink.audio.volume > 0 ? Theme.primary : Theme.surfaceText - } - } - - DankSlider { - readonly property real actualVolumePercent: AudioService.sink && AudioService.sink.audio ? Math.round(AudioService.sink.audio.volume * 100) : 0 - - anchors.verticalCenter: parent.verticalCenter - width: parent.width - (Theme.iconSize + Theme.spacingS * 2) - enabled: AudioService.sink && AudioService.sink.audio - minimum: 0 - maximum: AudioService.sinkMaxVolume - value: AudioService.sink && AudioService.sink.audio ? Math.min(AudioService.sinkMaxVolume, Math.round(AudioService.sink.audio.volume * 100)) : 0 - showValue: true - unit: "%" - valueOverride: actualVolumePercent - thumbOutlineColor: Theme.surfaceVariant - - onSliderValueChanged: function (newValue) { - if (AudioService.sink && AudioService.sink.audio) { - AudioService.sink.audio.volume = newValue / 100; - if (newValue > 0 && AudioService.sink.audio.muted) { - AudioService.sink.audio.muted = false; - } - AudioService.volumeChanged(); - } - } - } - } - - DankFlickable { - id: audioContent - anchors.top: volumeSlider.visible ? volumeSlider.bottom : headerRow.bottom - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: parent.bottom - anchors.margins: Theme.spacingM - anchors.topMargin: volumeSlider.visible ? Theme.spacingS : Theme.spacingM - contentHeight: audioColumn.height - clip: true - - property int maxPinnedOutputs: 3 - - function normalizePinList(value) { - if (Array.isArray(value)) - return value.filter(v => v); - if (typeof value === "string" && value.length > 0) - return [value]; - return []; - } - - function getPinnedOutputs() { - const pins = SettingsData.audioOutputDevicePins || {}; - return normalizePinList(pins["preferredOutput"]); - } - - Column { - id: audioColumn - width: parent.width - spacing: Theme.spacingS - - Repeater { - model: ScriptModel { - values: { - const hidden = SessionData.hiddenOutputDeviceNames ?? []; - const nodes = Pipewire.nodes.values.filter(node => { - if (!node.audio || !node.isSink || node.isStream) - return false; - return !hidden.includes(node.name); - }); - const pinnedList = audioContent.getPinnedOutputs(); - - let sorted = [...nodes]; - sorted.sort((a, b) => { - // Pinned device first - const aPinnedIndex = pinnedList.indexOf(a.name); - const bPinnedIndex = pinnedList.indexOf(b.name); - if (aPinnedIndex !== -1 || bPinnedIndex !== -1) { - if (aPinnedIndex === -1) - return 1; - if (bPinnedIndex === -1) - return -1; - return aPinnedIndex - bPinnedIndex; - } - // Then active device - if (a === AudioService.sink && b !== AudioService.sink) - return -1; - if (b === AudioService.sink && a !== AudioService.sink) - return 1; - return 0; - }); - return sorted; - } - } - - delegate: Rectangle { - id: outputDelegate - required property var modelData - required property int index - - width: parent.width - height: 50 - radius: Theme.cornerRadius - color: deviceMouseArea.containsMouse ? Theme.primaryHoverLight : Theme.surfaceLight - border.color: modelData === AudioService.sink ? Theme.primary : Theme.outlineLight - border.width: modelData === AudioService.sink ? 2 : 1 - - DankRipple { - id: deviceRipple - cornerRadius: outputDelegate.radius - } - - Row { - anchors.left: parent.left - anchors.verticalCenter: parent.verticalCenter - anchors.leftMargin: Theme.spacingM - spacing: Theme.spacingS - - DankIcon { - name: AudioService.sinkIcon(modelData) - size: Theme.iconSize - 4 - color: modelData === AudioService.sink ? Theme.primary : Theme.surfaceText - anchors.verticalCenter: parent.verticalCenter - } - - Column { - anchors.verticalCenter: parent.verticalCenter - width: { - const iconWidth = Theme.iconSize; - const pinButtonWidth = pinOutputRow.width + Theme.spacingS * 4 + Theme.spacingM; - return parent.parent.width - iconWidth - parent.spacing - pinButtonWidth - Theme.spacingM * 2; - } - - StyledText { - text: AudioService.displayName(modelData) - font.pixelSize: Theme.fontSizeMedium - color: Theme.surfaceText - font.weight: modelData === AudioService.sink ? Font.Medium : Font.Normal - elide: Text.ElideRight - width: parent.width - wrapMode: Text.NoWrap - horizontalAlignment: Text.AlignLeft - } - - StyledText { - text: modelData === AudioService.sink ? I18n.tr("Active") : I18n.tr("Available") - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceVariantText - elide: Text.ElideRight - width: parent.width - wrapMode: Text.NoWrap - horizontalAlignment: Text.AlignLeft - } - } - } - - Rectangle { - anchors.right: parent.right - anchors.rightMargin: Theme.spacingM - anchors.verticalCenter: parent.verticalCenter - width: pinOutputRow.width + Theme.spacingS * 2 - height: 28 - radius: height / 2 - color: { - const isThisDevicePinned = audioContent.getPinnedOutputs().includes(modelData.name); - return isThisDevicePinned ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : Theme.withAlpha(Theme.surfaceText, 0.05); - } - - Row { - id: pinOutputRow - anchors.centerIn: parent - spacing: 4 - - DankIcon { - name: "push_pin" - size: 16 - color: { - const isThisDevicePinned = audioContent.getPinnedOutputs().includes(modelData.name); - return isThisDevicePinned ? Theme.primary : Theme.surfaceText; - } - anchors.verticalCenter: parent.verticalCenter - } - - StyledText { - text: { - const isThisDevicePinned = audioContent.getPinnedOutputs().includes(modelData.name); - return isThisDevicePinned ? I18n.tr("Pinned") : I18n.tr("Pin"); - } - font.pixelSize: Theme.fontSizeSmall - color: { - const isThisDevicePinned = audioContent.getPinnedOutputs().includes(modelData.name); - return isThisDevicePinned ? Theme.primary : Theme.surfaceText; - } - anchors.verticalCenter: parent.verticalCenter - } - } - - DankRipple { - id: pinRipple - cornerRadius: parent.radius - } - - MouseArea { - anchors.fill: parent - cursorShape: Qt.PointingHandCursor - onPressed: mouse => pinRipple.trigger(mouse.x, mouse.y) - onClicked: { - const pins = JSON.parse(JSON.stringify(SettingsData.audioOutputDevicePins || {})); - let pinnedList = audioContent.normalizePinList(pins["preferredOutput"]); - const pinIndex = pinnedList.indexOf(modelData.name); - - if (pinIndex !== -1) { - pinnedList.splice(pinIndex, 1); - } else { - pinnedList.unshift(modelData.name); - if (pinnedList.length > audioContent.maxPinnedOutputs) - pinnedList = pinnedList.slice(0, audioContent.maxPinnedOutputs); - } - - if (pinnedList.length > 0) - pins["preferredOutput"] = pinnedList; - else - delete pins["preferredOutput"]; - - SettingsData.set("audioOutputDevicePins", pins); - } - } - } - - MouseArea { - id: deviceMouseArea - anchors.fill: parent - anchors.rightMargin: pinOutputRow.width + Theme.spacingS * 4 - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onPressed: mouse => { - let mapped = deviceMouseArea.mapToItem(outputDelegate, mouse.x, mouse.y); - deviceRipple.trigger(mapped.x, mapped.y); - } - onClicked: { - if (modelData) { - Pipewire.preferredDefaultAudioSink = modelData; - } - } - } - } - } - Row { - id: playbackHeaderRow - anchors.left: parent.left - anchors.right: parent.right - anchors.leftMargin: Theme.spacingM - anchors.rightMargin: Theme.spacingM - height: 28 - - StyledText { - id: playbackHeaderText - text: I18n.tr("Playback") - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceVariantText - font.weight: Font.Medium - anchors.verticalCenter: parent.verticalCenter - } - } - - Repeater { - model: ScriptModel { - values: { - const nodes = Pipewire.nodes.values.filter(node => { - return node.audio && node.isSink && node.isStream; - }); - return nodes; - } - } - - delegate: Rectangle { - required property var modelData - required property int index - - width: parent.width - height: 50 - radius: Theme.cornerRadius - color: Theme.surfaceLight - border.color: modelData === AudioService.sink ? Theme.primary : Theme.outlineLight - border.width: modelData === AudioService.sink ? 2 : 1 - - Row { - anchors.left: parent.left - anchors.verticalCenter: parent.verticalCenter - anchors.leftMargin: Theme.spacingM - spacing: Theme.spacingS - - DankIcon { - name: "album" - size: Theme.iconSize - 4 - color: !modelData.audio.muted ? Theme.primary : Theme.surfaceText - anchors.verticalCenter: parent.verticalCenter - } - - Column { - anchors.verticalCenter: parent.verticalCenter - width: { - const iconWidth = Theme.iconSize; - return parent.parent.width - iconWidth - parent.spacing - Theme.spacingM * 2; - } - - StyledText { - text: { - const modelDataMediaName = modelData && modelData.properties ? (modelData.properties["media.name"] || "") : ""; - const mediaName = AudioService.displayName(modelData) + ": " + modelDataMediaName; - const max = 35; - return mediaName.length > max ? mediaName.substring(0, max) + "..." : mediaName; - } - font.pixelSize: Theme.fontSizeMedium - color: Theme.surfaceText - font.weight: modelData === AudioService.sink ? Font.Medium : Font.Normal - elide: Text.ElideRight - width: parent.width - wrapMode: Text.NoWrap - } - } - } - Rectangle { - anchors.right: parent.right - anchors.rightMargin: 120 - anchors.verticalCenter: parent.verticalCenter - width: appVolumeRow.width - height: 28 - radius: height / 2 - - Item { - id: appVolumeRow - property color sliderTrackColor: "transparent" - anchors.centerIn: parent - - height: 40 - width: parent.width - - Rectangle { - anchors.right: parent.right - anchors.rightMargin: Theme.spacingM - width: Theme.iconSize + Theme.spacingS * 2 - height: Theme.iconSize + Theme.spacingS * 2 - anchors.verticalCenter: parent.verticalCenter - radius: Theme.cornerRadius - color: appIconArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : Theme.withAlpha(Theme.primary, 0) - - DankRipple { - id: appMuteRipple - cornerRadius: parent.radius - } - - MouseArea { - id: appIconArea - anchors.fill: parent - visible: modelData !== null - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onPressed: mouse => appMuteRipple.trigger(mouse.x, mouse.y) - onClicked: { - if (modelData) { - SessionData.suppressOSDTemporarily(); - modelData.audio.muted = !modelData.audio.muted; - } - } - } - - DankIcon { - anchors.centerIn: parent - name: { - if (!modelData) - return "volume_off"; - - let volume = modelData.audio.volume; - let muted = modelData.audio.muted; - - if (muted) - return "volume_off"; - if (volume === 0.0) - return "volume_mute"; - if (volume <= 0.33) - return "volume_down"; - if (volume <= 0.66) - return "volume_up"; - return "volume_up"; - } - size: Theme.iconSize - color: modelData && !modelData.audio.muted && modelData.audio.volume > 0 ? Theme.primary : Theme.surfaceText - } - } - - DankSlider { - readonly property real actualVolumePercent: modelData ? Math.round(modelData.audio.volume * 100) : 0 - - anchors.verticalCenter: parent.verticalCenter - width: 100 - enabled: modelData !== null - minimum: 0 - maximum: 100 - value: modelData ? Math.min(100, Math.round(modelData.audio.volume * 100)) : 0 - showValue: true - unit: "%" - valueOverride: actualVolumePercent - thumbOutlineColor: Theme.surfaceContainer - trackColor: appVolumeRow.sliderTrackColor.a > 0 ? appVolumeRow.sliderTrackColor : Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency) - - onSliderValueChanged: function (newValue) { - if (modelData) { - SessionData.suppressOSDTemporarily(); - modelData.audio.volume = newValue / 100.0; - if (newValue > 0 && modelData.audio.muted) { - modelData.audio.muted = false; - } - AudioService.playVolumeChangeSoundIfEnabled(); - } - } - } - } - PwObjectTracker { - objects: [modelData] - } - } - } - } - } - } -} diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Details/BatteryDetail.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Details/BatteryDetail.qml deleted file mode 100644 index 1f0206a..0000000 --- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Details/BatteryDetail.qml +++ /dev/null @@ -1,267 +0,0 @@ -import QtQuick -import Quickshell.Services.UPower -import qs.Common -import qs.Services -import qs.Widgets - -Rectangle { - id: root - - LayoutMirroring.enabled: I18n.isRtl - LayoutMirroring.childrenInherit: true - - implicitHeight: contentColumn.implicitHeight + Theme.spacingL * 2 - radius: Theme.cornerRadius - color: Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency) - border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08) - border.width: 0 - - function isActiveProfile(profile) { - if (typeof PowerProfiles === "undefined") { - return false; - } - return PowerProfiles.profile === profile; - } - - function setProfile(profile) { - if (typeof PowerProfiles === "undefined") { - ToastService.showError("power-profiles-daemon not available"); - return; - } - PowerProfiles.profile = profile; - if (PowerProfiles.profile !== profile) { - ToastService.showError("Failed to set power profile"); - } - } - - Column { - id: contentColumn - width: parent.width - Theme.spacingL * 2 - anchors.left: parent.left - anchors.top: parent.top - anchors.margins: Theme.spacingL - spacing: Theme.spacingL - - Row { - id: headerRow - width: parent.width - spacing: Theme.spacingM - - DankIcon { - name: BatteryService.getBatteryIcon() - size: Theme.iconSizeLarge - color: { - if (BatteryService.isLowBattery && !BatteryService.isCharging) - return Theme.error; - if (BatteryService.isCharging || BatteryService.isPluggedIn) - return Theme.primary; - return Theme.surfaceText; - } - anchors.verticalCenter: parent.verticalCenter - } - - Column { - spacing: Theme.spacingXS - anchors.verticalCenter: parent.verticalCenter - width: parent.width - Theme.iconSizeLarge - Theme.spacingM - - Row { - spacing: Theme.spacingS - - StyledText { - text: BatteryService.batteryAvailable ? `${BatteryService.batteryLevel}%` : I18n.tr("Power") - font.pixelSize: Theme.fontSizeXLarge - color: { - if (BatteryService.isLowBattery && !BatteryService.isCharging) { - return Theme.error; - } - if (BatteryService.isCharging) { - return Theme.primary; - } - return Theme.surfaceText; - } - font.weight: Font.Bold - } - - StyledText { - text: BatteryService.batteryAvailable ? BatteryService.batteryStatus : I18n.tr("Management") - font.pixelSize: Theme.fontSizeLarge - color: { - if (BatteryService.isLowBattery && !BatteryService.isCharging) { - return Theme.error; - } - if (BatteryService.isCharging) { - return Theme.primary; - } - return Theme.surfaceText; - } - font.weight: Font.Medium - anchors.verticalCenter: parent.verticalCenter - } - } - - StyledText { - text: { - if (!BatteryService.batteryAvailable) - return I18n.tr("Power profile management available"); - const time = BatteryService.formatTimeRemaining(); - if (time !== "Unknown") { - return BatteryService.isCharging ? I18n.tr("Time until full: %1").arg(time) : I18n.tr("Time remaining: %1").arg(time); - } - return ""; - } - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceTextMedium - visible: text.length > 0 - elide: Text.ElideRight - width: parent.width - horizontalAlignment: Text.AlignLeft - } - } - } - - Row { - width: parent.width - spacing: Theme.spacingM - visible: BatteryService.batteryAvailable - - StyledRect { - width: (parent.width - Theme.spacingM) / 2 - height: 64 - radius: Theme.cornerRadius - color: Theme.surfaceLight - border.color: Theme.outlineLight - border.width: 1 - - Column { - anchors.centerIn: parent - spacing: Theme.spacingXS - - StyledText { - text: I18n.tr("Health") - font.pixelSize: Theme.fontSizeSmall - color: Theme.primary - font.weight: Font.Medium - anchors.horizontalCenter: parent.horizontalCenter - } - - StyledText { - text: BatteryService.batteryHealth - font.pixelSize: Theme.fontSizeLarge - color: { - if (BatteryService.batteryHealth === "N/A") { - return Theme.surfaceText; - } - const healthNum = parseInt(BatteryService.batteryHealth); - return healthNum < 80 ? Theme.error : Theme.surfaceText; - } - font.weight: Font.Bold - anchors.horizontalCenter: parent.horizontalCenter - } - } - } - - StyledRect { - width: (parent.width - Theme.spacingM) / 2 - height: 64 - radius: Theme.cornerRadius - color: Theme.surfaceLight - border.color: Theme.outlineLight - border.width: 1 - - Column { - anchors.centerIn: parent - spacing: Theme.spacingXS - - StyledText { - text: I18n.tr("Capacity") - font.pixelSize: Theme.fontSizeSmall - color: Theme.primary - font.weight: Font.Medium - anchors.horizontalCenter: parent.horizontalCenter - } - - StyledText { - text: BatteryService.batteryCapacity > 0 ? `${BatteryService.batteryCapacity.toFixed(1)} Wh` : I18n.tr("Unknown") - font.pixelSize: Theme.fontSizeLarge - color: Theme.surfaceText - font.weight: Font.Bold - anchors.horizontalCenter: parent.horizontalCenter - } - } - } - } - - DankButtonGroup { - property var profileModel: (typeof PowerProfiles !== "undefined") ? [PowerProfile.PowerSaver, PowerProfile.Balanced].concat(PowerProfiles.hasPerformanceProfile ? [PowerProfile.Performance] : []) : [PowerProfile.PowerSaver, PowerProfile.Balanced, PowerProfile.Performance] - property int currentProfileIndex: { - if (typeof PowerProfiles === "undefined") - return 1; - return profileModel.findIndex(profile => isActiveProfile(profile)); - } - - model: profileModel.map(profile => Theme.getPowerProfileLabel(profile)) - currentIndex: currentProfileIndex - selectionMode: "single" - anchors.horizontalCenter: parent.horizontalCenter - onSelectionChanged: (index, selected) => { - if (!selected) - return; - setProfile(profileModel[index]); - } - } - - StyledRect { - width: parent.width - height: degradationContent.implicitHeight + Theme.spacingL * 2 - radius: Theme.cornerRadius - color: Qt.rgba(Theme.error.r, Theme.error.g, Theme.error.b, 0.12) - border.color: Qt.rgba(Theme.error.r, Theme.error.g, Theme.error.b, 0.3) - border.width: 0 - visible: (typeof PowerProfiles !== "undefined") && PowerProfiles.degradationReason !== PerformanceDegradationReason.None - - Column { - id: degradationContent - width: parent.width - Theme.spacingL * 2 - anchors.left: parent.left - anchors.top: parent.top - anchors.margins: Theme.spacingL - spacing: Theme.spacingS - - Row { - width: parent.width - spacing: Theme.spacingM - - DankIcon { - name: "warning" - size: Theme.iconSize - color: Theme.error - anchors.verticalCenter: parent.verticalCenter - } - - Column { - spacing: Theme.spacingXS - anchors.verticalCenter: parent.verticalCenter - width: parent.width - Theme.iconSize - Theme.spacingM - - StyledText { - text: I18n.tr("Power Profile Degradation") - font.pixelSize: Theme.fontSizeLarge - color: Theme.error - font.weight: Font.Medium - } - - StyledText { - text: (typeof PowerProfiles !== "undefined") ? PerformanceDegradationReason.toString(PowerProfiles.degradationReason) : "" - font.pixelSize: Theme.fontSizeSmall - color: Qt.rgba(Theme.error.r, Theme.error.g, Theme.error.b, 0.8) - wrapMode: Text.WordWrap - width: parent.width - horizontalAlignment: Text.AlignLeft - } - } - } - } - } - } -} diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Details/BluetoothCodecSelector.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Details/BluetoothCodecSelector.qml deleted file mode 100644 index 0cad08c..0000000 --- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Details/BluetoothCodecSelector.qml +++ /dev/null @@ -1,332 +0,0 @@ -import QtQuick -import qs.Common -import qs.Services -import qs.Widgets - -Item { - id: root - - LayoutMirroring.enabled: I18n.isRtl - LayoutMirroring.childrenInherit: true - - property var device: null - property bool modalVisible: false - property var parentItem - property var availableCodecs: [] - property string currentCodec: "" - property bool isLoading: false - - readonly property bool deviceValid: device !== null && device.connected && BluetoothService.isAudioDevice(device) - - signal codecSelected(string deviceAddress, string codecName) - - function show(bluetoothDevice) { - if (!bluetoothDevice?.connected) - return; - if (!BluetoothService.isAudioDevice(bluetoothDevice)) - return; - device = bluetoothDevice; - isLoading = true; - availableCodecs = []; - currentCodec = ""; - visible = true; - modalVisible = true; - queryCodecs(); - Qt.callLater(() => { - focusScope.forceActiveFocus(); - }); - } - - function hide() { - modalVisible = false; - Qt.callLater(() => { - visible = false; - device = null; - }); - } - - function queryCodecs() { - if (!deviceValid) { - hide(); - return; - } - - const capturedDevice = device; - const capturedAddress = device.address; - - BluetoothService.getAvailableCodecs(capturedDevice, function (codecs, current) { - if (!root.deviceValid || root.device?.address !== capturedAddress) - return; - availableCodecs = codecs; - currentCodec = current; - isLoading = false; - }); - } - - function selectCodec(profileName) { - if (!deviceValid || isLoading) - return; - - const capturedDevice = device; - const capturedAddress = device.address; - - const selectedCodec = availableCodecs.find(c => c.profile === profileName); - if (!selectedCodec) - return; - - BluetoothService.updateDeviceCodec(capturedAddress, selectedCodec.name); - codecSelected(capturedAddress, selectedCodec.name); - - isLoading = true; - BluetoothService.switchCodec(capturedDevice, profileName, function (success, message) { - if (!root.device || root.device.address !== capturedAddress) - return; - - isLoading = false; - if (success) { - ToastService.showToast(message, ToastService.levelInfo); - Qt.callLater(root.hide); - return; - } - ToastService.showToast(message, ToastService.levelError); - }); - } - - onDeviceValidChanged: { - if (modalVisible && !deviceValid) { - hide(); - } - } - - visible: false - anchors.fill: parent - z: 2000 - - MouseArea { - id: modalBlocker - anchors.fill: parent - visible: modalVisible - enabled: modalVisible - hoverEnabled: true - preventStealing: true - propagateComposedEvents: false - - onClicked: root.hide() - onWheel: wheel => { - wheel.accepted = true; - } - onPositionChanged: mouse => { - mouse.accepted = true; - } - } - - Rectangle { - id: modalBackground - anchors.fill: parent - color: Qt.rgba(0, 0, 0, 0.5) - opacity: modalVisible ? 1 : 0 - - Behavior on opacity { - NumberAnimation { - duration: Theme.mediumDuration - easing.type: Theme.emphasizedEasing - } - } - } - - FocusScope { - id: focusScope - - anchors.fill: parent - focus: root.visible - enabled: root.visible - - Keys.onEscapePressed: { - root.hide(); - event.accepted = true; - } - } - - Rectangle { - id: modalContent - anchors.centerIn: parent - width: 320 - height: contentColumn.implicitHeight + Theme.spacingL * 2 - radius: Theme.cornerRadius - color: Theme.withAlpha(Theme.surfaceContainer, Theme.popupTransparency) - border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08) - border.width: 0 - opacity: modalVisible ? 1 : 0 - scale: modalVisible ? 1 : 0.9 - - MouseArea { - anchors.fill: parent - hoverEnabled: true - preventStealing: true - propagateComposedEvents: false - onClicked: mouse => { - mouse.accepted = true; - } - onWheel: wheel => { - wheel.accepted = true; - } - onPositionChanged: mouse => { - mouse.accepted = true; - } - } - - Column { - id: contentColumn - - anchors.left: parent.left - anchors.right: parent.right - anchors.top: parent.top - anchors.margins: Theme.spacingL - spacing: Theme.spacingM - - Row { - width: parent.width - spacing: Theme.spacingM - - DankIcon { - name: device ? BluetoothService.getDeviceIcon(device) : "headset" - size: Theme.iconSize + 4 - color: Theme.primary - anchors.verticalCenter: parent.verticalCenter - } - - Column { - anchors.verticalCenter: parent.verticalCenter - spacing: 2 - - StyledText { - text: device ? (device.name || device.deviceName) : "" - font.pixelSize: Theme.fontSizeLarge - color: Theme.surfaceText - font.weight: Font.Medium - } - - StyledText { - text: I18n.tr("Audio Codec Selection") - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceTextMedium - } - } - } - - Rectangle { - width: parent.width - height: 1 - color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.05) - } - - StyledText { - text: isLoading ? I18n.tr("Loading codecs...") : I18n.tr("Current: %1").arg(currentCodec) - font.pixelSize: Theme.fontSizeSmall - color: isLoading ? Theme.primary : Theme.surfaceTextMedium - font.weight: Font.Medium - } - - Column { - width: parent.width - spacing: Theme.spacingXS - visible: !isLoading - - Repeater { - model: availableCodecs - - Rectangle { - width: parent.width - height: 48 - radius: Theme.cornerRadius - color: { - if (modelData.name === currentCodec) - return Theme.withAlpha(Theme.surfaceContainerHighest, Theme.popupTransparency); - else if (codecMouseArea.containsMouse) - return Theme.surfaceHover; - else - return "transparent"; - } - border.color: "transparent" - border.width: 0 - - Row { - anchors.left: parent.left - anchors.leftMargin: Theme.spacingM - anchors.verticalCenter: parent.verticalCenter - spacing: Theme.spacingS - - Rectangle { - width: 6 - height: 6 - radius: 3 - color: modelData.qualityColor - anchors.verticalCenter: parent.verticalCenter - } - - Column { - anchors.verticalCenter: parent.verticalCenter - spacing: 2 - - StyledText { - text: modelData.name - font.pixelSize: Theme.fontSizeMedium - color: modelData.name === currentCodec ? Theme.primary : Theme.surfaceText - font.weight: modelData.name === currentCodec ? Font.Medium : Font.Normal - } - - StyledText { - text: modelData.description - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceTextMedium - } - } - } - - DankIcon { - name: "check" - size: Theme.iconSize - 4 - color: Theme.primary - anchors.right: parent.right - anchors.rightMargin: Theme.spacingM - anchors.verticalCenter: parent.verticalCenter - visible: modelData.name === currentCodec - } - - DankRipple { - id: codecRipple - cornerRadius: parent.radius - } - - MouseArea { - id: codecMouseArea - - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - enabled: modelData.name !== currentCodec && !isLoading - onPressed: mouse => codecRipple.trigger(mouse.x, mouse.y) - onClicked: { - selectCodec(modelData.profile); - } - } - } - } - } - } - - Behavior on opacity { - NumberAnimation { - duration: Theme.mediumDuration - easing.type: Theme.emphasizedEasing - } - } - - Behavior on scale { - NumberAnimation { - duration: Theme.mediumDuration - easing.type: Theme.emphasizedEasing - } - } - } -} diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Details/BluetoothDetail.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Details/BluetoothDetail.qml deleted file mode 100644 index 580ea9f..0000000 --- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Details/BluetoothDetail.qml +++ /dev/null @@ -1,743 +0,0 @@ -import QtQuick -import QtQuick.Controls -import Quickshell -import Quickshell.Bluetooth -import qs.Common -import qs.Services -import qs.Widgets - -Rectangle { - id: root - - LayoutMirroring.enabled: I18n.isRtl - LayoutMirroring.childrenInherit: true - - implicitHeight: { - if (height > 0) - return height; - if (!BluetoothService.adapter?.enabled) - return headerRow.height; - return headerRow.height + bluetoothContent.height + Theme.spacingM; - } - radius: Theme.cornerRadius - color: Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency) - border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08) - border.width: 0 - - property var bluetoothCodecModalRef: null - property var devicesBeingPaired: new Set() - - signal showCodecSelector(var device) - - function isDeviceBeingPaired(deviceAddress) { - return devicesBeingPaired.has(deviceAddress); - } - - function handlePairDevice(device) { - if (!device) - return; - const deviceAddr = device.address; - const pairingSet = devicesBeingPaired; - - pairingSet.add(deviceAddr); - devicesBeingPairedChanged(); - - BluetoothService.pairDevice(device, function (response) { - pairingSet.delete(deviceAddr); - devicesBeingPairedChanged(); - - if (response.error) { - ToastService.showError(I18n.tr("Pairing failed"), response.error); - return; - } - if (!BluetoothService.enhancedPairingAvailable) { - ToastService.showSuccess(I18n.tr("Device paired")); - } - }); - } - - function updateDeviceCodecDisplay(deviceAddress, codecName) { - for (let i = 0; i < pairedRepeater.count; i++) { - const item = pairedRepeater.itemAt(i); - if (!item?.modelData) - continue; - if (item.modelData.address !== deviceAddress) - continue; - item.currentCodec = codecName; - break; - } - } - - function normalizePinList(value) { - if (Array.isArray(value)) - return value.filter(v => v); - if (typeof value === "string" && value.length > 0) - return [value]; - return []; - } - - function getPinnedDevices() { - const pins = SettingsData.bluetoothDevicePins || {}; - return normalizePinList(pins["preferredDevice"]); - } - - Row { - id: headerRow - anchors.left: parent.left - anchors.right: parent.right - anchors.top: parent.top - anchors.leftMargin: Theme.spacingM - anchors.rightMargin: Theme.spacingM - anchors.topMargin: Theme.spacingS - height: 40 - - StyledText { - id: headerText - text: I18n.tr("Bluetooth Settings") - font.pixelSize: Theme.fontSizeLarge - color: Theme.surfaceText - font.weight: Font.Medium - anchors.verticalCenter: parent.verticalCenter - } - - Item { - width: Math.max(0, parent.width - headerText.implicitWidth - scanButton.width - Theme.spacingM) - height: parent.height - } - - Rectangle { - id: scanButton - - readonly property bool adapterEnabled: BluetoothService.adapter?.enabled ?? false - readonly property bool isDiscovering: BluetoothService.adapter?.discovering ?? false - - width: 100 - height: 36 - radius: 18 - color: scanMouseArea.containsMouse && adapterEnabled ? Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency) : "transparent" - border.color: adapterEnabled ? Theme.primary : Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12) - border.width: 0 - visible: adapterEnabled - - Row { - anchors.centerIn: parent - spacing: Theme.spacingXS - - DankIcon { - name: scanButton.isDiscovering ? "stop" : "bluetooth_searching" - size: 18 - color: scanButton.adapterEnabled ? Theme.primary : Theme.surfaceVariantText - anchors.verticalCenter: parent.verticalCenter - } - - StyledText { - text: scanButton.isDiscovering ? I18n.tr("Scanning") : I18n.tr("Scan") - color: scanButton.adapterEnabled ? Theme.primary : Theme.surfaceVariantText - font.pixelSize: Theme.fontSizeMedium - font.weight: Font.Medium - anchors.verticalCenter: parent.verticalCenter - } - } - - DankRipple { - id: scanRipple - cornerRadius: scanButton.radius - } - - MouseArea { - id: scanMouseArea - anchors.fill: parent - hoverEnabled: true - enabled: scanButton.adapterEnabled - cursorShape: enabled ? Qt.PointingHandCursor : Qt.ArrowCursor - onPressed: mouse => scanRipple.trigger(mouse.x, mouse.y) - onClicked: { - if (!BluetoothService.adapter) - return; - BluetoothService.adapter.discovering = !BluetoothService.adapter.discovering; - } - } - } - } - - DankFlickable { - id: bluetoothContent - anchors.top: headerRow.bottom - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: parent.bottom - anchors.margins: Theme.spacingM - anchors.topMargin: Theme.spacingM - visible: BluetoothService.adapter?.enabled ?? false - contentHeight: bluetoothColumn.height - clip: true - - readonly property int maxPinnedDevices: 3 - - Column { - id: bluetoothColumn - width: parent.width - spacing: Theme.spacingS - - ScriptModel { - id: pairedDevicesModel - objectProp: "address" - values: { - if (!BluetoothService.adapter?.devices) - return []; - - const pinnedList = root.getPinnedDevices(); - const devices = [...BluetoothService.adapter.devices.values.filter(dev => dev && (dev.paired || dev.trusted))]; - - devices.sort((a, b) => { - const aPinnedIndex = pinnedList.indexOf(a.address); - const bPinnedIndex = pinnedList.indexOf(b.address); - - if (aPinnedIndex !== -1 || bPinnedIndex !== -1) { - if (aPinnedIndex === -1) - return 1; - if (bPinnedIndex === -1) - return -1; - return aPinnedIndex - bPinnedIndex; - } - - if (a.connected !== b.connected) - return a.connected ? -1 : 1; - - return (b.signalStrength || 0) - (a.signalStrength || 0); - }); - - return devices; - } - } - - Repeater { - id: pairedRepeater - model: pairedDevicesModel - - delegate: Rectangle { - id: pairedDelegate - required property var modelData - required property int index - - readonly property string currentCodec: BluetoothService.deviceCodecs[modelData.address] || "" - readonly property bool isConnecting: modelData.state === BluetoothDeviceState.Connecting - readonly property bool isConnected: modelData.connected - readonly property bool isPinned: root.getPinnedDevices().includes(modelData.address) - readonly property string deviceName: modelData.name || modelData.deviceName || I18n.tr("Unknown Device") - - width: parent.width - height: 50 - radius: Theme.cornerRadius - - Component.onCompleted: { - if (!isConnected) - return; - if (!BluetoothService.isAudioDevice(modelData)) - return; - BluetoothService.refreshDeviceCodec(modelData); - } - - color: { - if (isConnecting) - return Qt.rgba(Theme.warning.r, Theme.warning.g, Theme.warning.b, 0.12); - if (deviceMouseArea.containsMouse) - return Theme.primaryHoverLight; - return Theme.surfaceLight; - } - - border.color: { - if (isConnecting) - return Theme.warning; - if (isConnected) - return Theme.primary; - return Theme.outlineLight; - } - border.width: (isConnecting || isConnected) ? 2 : 1 - - Row { - anchors.left: parent.left - anchors.verticalCenter: parent.verticalCenter - anchors.leftMargin: Theme.spacingM - spacing: Theme.spacingS - - DankIcon { - name: BluetoothService.getDeviceIcon(pairedDelegate.modelData) - size: Theme.iconSize - 4 - anchors.verticalCenter: parent.verticalCenter - color: { - if (pairedDelegate.isConnecting) - return Theme.warning; - if (pairedDelegate.isConnected) - return Theme.primary; - return Theme.surfaceText; - } - } - - Column { - anchors.verticalCenter: parent.verticalCenter - width: 200 - - StyledText { - text: pairedDelegate.deviceName - font.pixelSize: Theme.fontSizeMedium - color: Theme.surfaceText - font.weight: pairedDelegate.isConnected ? Font.Medium : Font.Normal - elide: Text.ElideRight - width: parent.width - horizontalAlignment: Text.AlignLeft - } - - Row { - spacing: Theme.spacingXS - - StyledText { - text: { - if (pairedDelegate.isConnecting) - return I18n.tr("Connecting..."); - if (!pairedDelegate.isConnected) - return I18n.tr("Paired"); - if (!pairedDelegate.currentCodec) - return I18n.tr("Connected"); - return I18n.tr("Connected") + " • " + pairedDelegate.currentCodec; - } - font.pixelSize: Theme.fontSizeSmall - color: pairedDelegate.isConnecting ? Theme.warning : Theme.surfaceVariantText - } - - StyledText { - readonly property var btBattery: { - const name = pairedDelegate.deviceName; - return BatteryService.bluetoothDevices.find(dev => dev.name === name || dev.name.toLowerCase().includes(name.toLowerCase()) || name.toLowerCase().includes(dev.name.toLowerCase())); - } - text: { - if (pairedDelegate.modelData.batteryAvailable && pairedDelegate.modelData.battery > 0) - return "• " + Math.round(pairedDelegate.modelData.battery * 100) + "%"; - if (btBattery) - return "• " + btBattery.percentage + "%"; - return ""; - } - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceVariantText - visible: text.length > 0 - } - - StyledText { - text: pairedDelegate.modelData.signalStrength > 0 ? "• " + pairedDelegate.modelData.signalStrength + "%" : "" - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceVariantText - visible: text.length > 0 - } - } - } - } - - Rectangle { - anchors.right: pairedOptionsButton.left - anchors.rightMargin: Theme.spacingS - anchors.verticalCenter: parent.verticalCenter - width: pinBluetoothRow.width + Theme.spacingS * 2 - height: 28 - radius: height / 2 - color: pairedDelegate.isPinned ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : Theme.withAlpha(Theme.surfaceText, 0.05) - - Row { - id: pinBluetoothRow - anchors.centerIn: parent - spacing: 4 - - DankIcon { - name: "push_pin" - size: 16 - color: pairedDelegate.isPinned ? Theme.primary : Theme.surfaceText - anchors.verticalCenter: parent.verticalCenter - } - - StyledText { - text: pairedDelegate.isPinned ? I18n.tr("Pinned") : I18n.tr("Pin") - font.pixelSize: Theme.fontSizeSmall - color: pairedDelegate.isPinned ? Theme.primary : Theme.surfaceText - anchors.verticalCenter: parent.verticalCenter - } - } - - MouseArea { - anchors.fill: parent - cursorShape: Qt.PointingHandCursor - onClicked: { - const pins = JSON.parse(JSON.stringify(SettingsData.bluetoothDevicePins || {})); - let pinnedList = root.normalizePinList(pins["preferredDevice"]); - const pinIndex = pinnedList.indexOf(pairedDelegate.modelData.address); - - if (pinIndex !== -1) { - pinnedList.splice(pinIndex, 1); - } else { - pinnedList.unshift(pairedDelegate.modelData.address); - if (pinnedList.length > bluetoothContent.maxPinnedDevices) - pinnedList = pinnedList.slice(0, bluetoothContent.maxPinnedDevices); - } - - if (pinnedList.length > 0) { - pins["preferredDevice"] = pinnedList; - } else { - delete pins["preferredDevice"]; - } - - SettingsData.set("bluetoothDevicePins", pins); - } - } - } - - DankActionButton { - id: pairedOptionsButton - anchors.right: parent.right - anchors.rightMargin: Theme.spacingS - anchors.verticalCenter: parent.verticalCenter - iconName: "more_horiz" - buttonSize: 28 - onClicked: { - if (bluetoothContextMenu.visible) { - bluetoothContextMenu.close(); - return; - } - bluetoothContextMenu.currentDevice = pairedDelegate.modelData; - bluetoothContextMenu.popup(pairedOptionsButton, -bluetoothContextMenu.width + pairedOptionsButton.width, pairedOptionsButton.height + Theme.spacingXS); - } - } - - DankRipple { - id: deviceRipple - cornerRadius: pairedDelegate.radius - } - - MouseArea { - id: deviceMouseArea - anchors.fill: parent - anchors.rightMargin: pairedOptionsButton.width + Theme.spacingM + pinBluetoothRow.width + Theme.spacingS * 4 - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onPressed: mouse => { - const pos = mapToItem(pairedDelegate, mouse.x, mouse.y); - deviceRipple.trigger(pos.x, pos.y); - } - onClicked: { - if (pairedDelegate.isConnected) { - pairedDelegate.modelData.disconnect(); - return; - } - BluetoothService.connectDeviceWithTrust(pairedDelegate.modelData); - } - } - } - } - - Rectangle { - width: parent.width - height: 1 - color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12) - visible: pairedRepeater.count > 0 && availableRepeater.count > 0 - } - - Item { - width: parent.width - height: 80 - visible: (BluetoothService.adapter?.discovering ?? false) && availableRepeater.count === 0 - - DankIcon { - anchors.centerIn: parent - name: "sync" - size: 24 - color: Qt.rgba(Theme.surfaceText.r || 0.8, Theme.surfaceText.g || 0.8, Theme.surfaceText.b || 0.8, 0.4) - - RotationAnimation on rotation { - running: parent.visible - loops: Animation.Infinite - from: 0 - to: 360 - duration: 1500 - } - } - } - - ScriptModel { - id: availableDevicesModel - objectProp: "address" - values: { - if (!BluetoothService.adapter?.discovering) - return []; - if (!Bluetooth.devices) - return []; - - const filtered = Bluetooth.devices.values.filter(dev => dev && !dev.paired && !dev.pairing && !dev.blocked && (dev.signalStrength === undefined || dev.signalStrength > 0)); - return BluetoothService.sortDevices(filtered); - } - } - - Repeater { - id: availableRepeater - model: availableDevicesModel - - delegate: Rectangle { - id: availableDelegate - required property var modelData - required property int index - - readonly property bool canConnect: BluetoothService.canConnect(modelData) - readonly property bool isBusy: BluetoothService.isDeviceBusy(modelData) || root.isDeviceBeingPaired(modelData.address) - readonly property bool isInteractive: canConnect && !isBusy - readonly property string deviceName: modelData.name || modelData.deviceName || I18n.tr("Unknown Device") - - width: parent.width - height: 50 - radius: Theme.cornerRadius - color: availableMouseArea.containsMouse && isInteractive ? Theme.primaryHoverLight : Theme.surfaceLight - border.color: Theme.outlineLight - border.width: 1 - opacity: isInteractive ? 1 : 0.6 - - Row { - anchors.left: parent.left - anchors.verticalCenter: parent.verticalCenter - anchors.leftMargin: Theme.spacingM - spacing: Theme.spacingS - - DankIcon { - name: BluetoothService.getDeviceIcon(availableDelegate.modelData) - size: Theme.iconSize - 4 - color: Theme.surfaceText - anchors.verticalCenter: parent.verticalCenter - } - - Column { - anchors.verticalCenter: parent.verticalCenter - width: 200 - - StyledText { - text: availableDelegate.deviceName - font.pixelSize: Theme.fontSizeMedium - color: Theme.surfaceText - elide: Text.ElideRight - width: parent.width - horizontalAlignment: Text.AlignLeft - } - - Row { - spacing: Theme.spacingXS - - StyledText { - text: { - if (availableDelegate.modelData.pairing || availableDelegate.isBusy) - return I18n.tr("Pairing..."); - if (availableDelegate.modelData.blocked) - return I18n.tr("Blocked"); - return BluetoothService.getSignalStrength(availableDelegate.modelData); - } - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceVariantText - } - - StyledText { - text: availableDelegate.modelData.signalStrength > 0 ? "• " + availableDelegate.modelData.signalStrength + "%" : "" - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceVariantText - visible: text.length > 0 && !availableDelegate.modelData.pairing && !availableDelegate.modelData.blocked - } - } - } - } - - StyledText { - anchors.right: parent.right - anchors.rightMargin: Theme.spacingM - anchors.verticalCenter: parent.verticalCenter - text: { - if (availableDelegate.isBusy) - return I18n.tr("Pairing..."); - if (!availableDelegate.canConnect) - return I18n.tr("Cannot pair"); - return I18n.tr("Pair"); - } - font.pixelSize: Theme.fontSizeSmall - color: availableDelegate.isInteractive ? Theme.primary : Theme.surfaceVariantText - font.weight: Font.Medium - } - - DankRipple { - id: availableRipple - cornerRadius: availableDelegate.radius - } - - MouseArea { - id: availableMouseArea - anchors.fill: parent - hoverEnabled: true - cursorShape: availableDelegate.isInteractive ? Qt.PointingHandCursor : Qt.ArrowCursor - enabled: availableDelegate.isInteractive - onPressed: mouse => availableRipple.trigger(mouse.x, mouse.y) - onClicked: root.handlePairDevice(availableDelegate.modelData) - } - } - } - - Item { - width: parent.width - height: 60 - visible: !BluetoothService.adapter - - StyledText { - anchors.centerIn: parent - text: I18n.tr("No Bluetooth adapter found") - font.pixelSize: Theme.fontSizeMedium - color: Theme.surfaceVariantText - } - } - } - } - - Menu { - id: bluetoothContextMenu - width: 150 - closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent - - property var currentDevice: null - - readonly property bool hasDevice: currentDevice !== null - readonly property bool deviceConnected: currentDevice?.connected ?? false - readonly property bool showCodecOption: hasDevice && deviceConnected && BluetoothService.isAudioDevice(currentDevice) - - background: Rectangle { - color: Theme.withAlpha(Theme.surfaceContainer, Theme.popupTransparency) - radius: Theme.cornerRadius - border.width: 0 - border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12) - } - - MenuItem { - text: bluetoothContextMenu.deviceConnected ? I18n.tr("Disconnect") : I18n.tr("Connect") - height: 32 - - contentItem: StyledText { - text: parent.text - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceText - leftPadding: Theme.spacingS - verticalAlignment: Text.AlignVCenter - } - - background: Rectangle { - color: parent.hovered ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08) : "transparent" - radius: Theme.cornerRadius / 2 - } - - onTriggered: { - if (!bluetoothContextMenu.hasDevice) - return; - if (bluetoothContextMenu.deviceConnected) { - bluetoothContextMenu.currentDevice.disconnect(); - return; - } - BluetoothService.connectDeviceWithTrust(bluetoothContextMenu.currentDevice); - } - } - - MenuItem { - text: I18n.tr("Audio Codec") - height: bluetoothContextMenu.showCodecOption ? 32 : 0 - visible: bluetoothContextMenu.showCodecOption - - contentItem: StyledText { - text: parent.text - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceText - leftPadding: Theme.spacingS - verticalAlignment: Text.AlignVCenter - } - - background: Rectangle { - color: parent.hovered ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08) : "transparent" - radius: Theme.cornerRadius / 2 - } - - onTriggered: { - if (!bluetoothContextMenu.hasDevice) - return; - if (!bluetoothContextMenu.currentDevice.connected) - return; - if (!BluetoothService.isAudioDevice(bluetoothContextMenu.currentDevice)) - return; - showCodecSelector(bluetoothContextMenu.currentDevice); - } - } - - MenuItem { - text: bluetoothContextMenu.currentDevice?.trusted ? I18n.tr("Untrust") : I18n.tr("Trust") - height: 32 - - contentItem: StyledText { - text: parent.text - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceText - leftPadding: Theme.spacingS - verticalAlignment: Text.AlignVCenter - } - - background: Rectangle { - color: parent.hovered ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08) : "transparent" - radius: Theme.cornerRadius / 2 - } - - onTriggered: { - if (!bluetoothContextMenu.hasDevice) - return; - bluetoothContextMenu.currentDevice.trusted = !bluetoothContextMenu.currentDevice.trusted; - } - } - - MenuItem { - text: I18n.tr("Forget Device") - height: 32 - - contentItem: StyledText { - text: parent.text - font.pixelSize: Theme.fontSizeSmall - color: Theme.error - leftPadding: Theme.spacingS - verticalAlignment: Text.AlignVCenter - } - - background: Rectangle { - color: parent.hovered ? Qt.rgba(Theme.error.r, Theme.error.g, Theme.error.b, 0.08) : "transparent" - radius: Theme.cornerRadius / 2 - } - - onTriggered: { - if (!bluetoothContextMenu.hasDevice) - return; - if (!BluetoothService.enhancedPairingAvailable) { - bluetoothContextMenu.currentDevice.forget(); - return; - } - - const devicePath = BluetoothService.getDevicePath(bluetoothContextMenu.currentDevice); - DMSService.bluetoothRemove(devicePath, response => { - if (!response.error) - return; - ToastService.showError(I18n.tr("Failed to remove device"), response.error); - }); - } - } - } - - Connections { - target: DMSService - - function onBluetoothPairingRequest(data) { - const modal = PopoutService.bluetoothPairingModal; - if (!modal) - return; - if (modal.token === data.token) - return; - modal.show(data); - } - } -} diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Details/BrightnessDetail.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Details/BrightnessDetail.qml deleted file mode 100644 index 0d42e62..0000000 --- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Details/BrightnessDetail.qml +++ /dev/null @@ -1,498 +0,0 @@ -import QtQuick -import Quickshell -import qs.Common -import qs.Services -import qs.Widgets - -Rectangle { - id: root - - LayoutMirroring.enabled: I18n.isRtl - LayoutMirroring.childrenInherit: true - - property string initialDeviceName: "" - property string instanceId: "" - property string screenName: "" - property string screenModel: "" - - signal deviceNameChanged(string newDeviceName) - - property string currentDeviceName: "" - - function getScreenPinKey() { - if (!screenName) - return ""; - const screen = Quickshell.screens.find(s => s.name === screenName); - if (screen) { - return SettingsData.getScreenDisplayName(screen); - } - if (SettingsData.displayNameMode === "model" && screenModel && screenModel.length > 0) { - return screenModel; - } - return screenName; - } - - function resolveDeviceName() { - if (!DisplayService.brightnessAvailable || !DisplayService.devices || DisplayService.devices.length === 0) { - return ""; - } - - const pinKey = getScreenPinKey(); - if (pinKey.length > 0) { - const pins = SettingsData.brightnessDevicePins || {}; - const pinnedDevice = pins[pinKey]; - if (pinnedDevice && pinnedDevice.length > 0) { - const found = DisplayService.devices.find(dev => dev.name === pinnedDevice); - if (found) - return found.name; - } - } - - if (initialDeviceName && initialDeviceName.length > 0) { - const found = DisplayService.devices.find(dev => dev.name === initialDeviceName); - if (found) - return found.name; - } - - const currentDeviceNameFromService = DisplayService.currentDevice; - if (currentDeviceNameFromService) { - const found = DisplayService.devices.find(dev => dev.name === currentDeviceNameFromService); - if (found) - return found.name; - } - - const backlight = DisplayService.devices.find(d => d.class === "backlight"); - if (backlight) - return backlight.name; - - const ddc = DisplayService.devices.find(d => d.class === "ddc"); - if (ddc) - return ddc.name; - - return DisplayService.devices.length > 0 ? DisplayService.devices[0].name : ""; - } - - Component.onCompleted: { - currentDeviceName = resolveDeviceName(); - } - - property bool isPinnedToScreen: { - const pinKey = getScreenPinKey(); - if (!pinKey || pinKey.length === 0) - return false; - const pins = SettingsData.brightnessDevicePins || {}; - return pins[pinKey] === currentDeviceName; - } - - function togglePinToScreen() { - const pinKey = getScreenPinKey(); - if (!pinKey || pinKey.length === 0 || !currentDeviceName || currentDeviceName.length === 0) - return; - const pins = JSON.parse(JSON.stringify(SettingsData.brightnessDevicePins || {})); - - if (isPinnedToScreen) { - delete pins[pinKey]; - } else { - pins[pinKey] = currentDeviceName; - } - - SettingsData.set("brightnessDevicePins", pins); - } - - implicitHeight: { - if (height > 0) { - return height; - } - return brightnessContent.height + Theme.spacingM; - } - radius: Theme.cornerRadius - color: Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency) - border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08) - border.width: 0 - - DankFlickable { - id: brightnessContent - anchors.top: parent.top - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: parent.bottom - anchors.margins: Theme.spacingM - anchors.topMargin: Theme.spacingM - contentHeight: brightnessColumn.height - clip: true - - Column { - id: brightnessColumn - width: parent.width - spacing: Theme.spacingS - - Item { - width: parent.width - height: 100 - visible: !DisplayService.brightnessAvailable || !DisplayService.devices || DisplayService.devices.length === 0 - - Column { - anchors.centerIn: parent - spacing: Theme.spacingM - - DankIcon { - anchors.horizontalCenter: parent.horizontalCenter - name: DisplayService.brightnessAvailable ? "brightness_6" : "error" - size: 32 - color: DisplayService.brightnessAvailable ? Theme.primary : Theme.error - } - - StyledText { - anchors.horizontalCenter: parent.horizontalCenter - text: DisplayService.brightnessAvailable ? I18n.tr("No brightness devices available") : I18n.tr("Brightness control not available") - font.pixelSize: Theme.fontSizeMedium - color: Theme.surfaceText - horizontalAlignment: Text.AlignHCenter - } - } - } - - Rectangle { - width: parent.width - height: 40 - visible: screenName && screenName.length > 0 && DisplayService.devices && DisplayService.devices.length > 1 - radius: Theme.cornerRadius - color: Theme.withAlpha(Theme.surfaceContainerHighest, Theme.popupTransparency) - - Item { - anchors.fill: parent - anchors.margins: Theme.spacingM - - Row { - anchors.left: parent.left - anchors.verticalCenter: parent.verticalCenter - spacing: Theme.spacingM - - DankIcon { - name: "monitor" - size: Theme.iconSize - color: Theme.surfaceText - anchors.verticalCenter: parent.verticalCenter - } - - StyledText { - text: root.getScreenPinKey() || I18n.tr("Unknown Monitor") - font.pixelSize: Theme.fontSizeMedium - color: Theme.surfaceText - anchors.verticalCenter: parent.verticalCenter - } - } - - Rectangle { - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - width: pinRow.width + Theme.spacingS * 2 - height: 28 - radius: height / 2 - color: isPinnedToScreen ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : Theme.withAlpha(Theme.surfaceText, 0.05) - - Row { - id: pinRow - anchors.centerIn: parent - spacing: 4 - - DankIcon { - name: isPinnedToScreen ? "push_pin" : "push_pin" - size: 16 - color: isPinnedToScreen ? Theme.primary : Theme.surfaceText - anchors.verticalCenter: parent.verticalCenter - } - - StyledText { - text: isPinnedToScreen ? I18n.tr("Pinned") : I18n.tr("Pin") - font.pixelSize: Theme.fontSizeSmall - color: isPinnedToScreen ? Theme.primary : Theme.surfaceText - anchors.verticalCenter: parent.verticalCenter - } - } - - DankRipple { - id: pinRipple - cornerRadius: parent.radius - } - - MouseArea { - anchors.fill: parent - cursorShape: Qt.PointingHandCursor - onPressed: mouse => pinRipple.trigger(mouse.x, mouse.y) - onClicked: root.togglePinToScreen() - } - } - } - } - - Repeater { - model: DisplayService.devices || [] - delegate: Rectangle { - required property var modelData - required property int index - - property real deviceBrightness: { - DisplayService.brightnessVersion; - return DisplayService.getDeviceBrightness(modelData.name); - } - - width: parent.width - height: 100 - radius: Theme.cornerRadius - color: Theme.withAlpha(Theme.surfaceContainerHighest, Theme.popupTransparency) - border.color: modelData.name === currentDeviceName ? Theme.primary : Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12) - border.width: modelData.name === currentDeviceName ? 2 : 0 - - Column { - anchors.fill: parent - anchors.margins: Theme.spacingM - spacing: Theme.spacingS - - Item { - width: parent.width - height: Math.max(deviceIconColumn.height, deviceInfoColumn.height, exponentControls.height) - - Row { - anchors.left: parent.left - anchors.verticalCenter: parent.verticalCenter - spacing: Theme.spacingM - - Column { - id: deviceIconColumn - anchors.verticalCenter: parent.verticalCenter - spacing: 2 - - DankIcon { - name: { - const deviceClass = modelData.class || ""; - const deviceName = modelData.name || ""; - - if (deviceClass === "backlight" || deviceClass === "ddc") { - if (deviceBrightness <= 33) - return "brightness_low"; - if (deviceBrightness <= 66) - return "brightness_medium"; - return "brightness_high"; - } else if (deviceName.includes("kbd")) { - return "keyboard"; - } else { - return "lightbulb"; - } - } - size: Theme.iconSize - color: modelData.name === currentDeviceName ? Theme.primary : Theme.surfaceText - anchors.horizontalCenter: parent.horizontalCenter - } - - StyledText { - text: Math.round(deviceBrightness) + "%" - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceText - anchors.horizontalCenter: parent.horizontalCenter - } - } - - Column { - id: deviceInfoColumn - anchors.verticalCenter: parent.verticalCenter - width: parent.parent.width - deviceIconColumn.width - exponentControls.width - Theme.spacingM * 3 - - StyledText { - text: { - const name = modelData.name || ""; - const deviceClass = modelData.class || ""; - if (deviceClass === "backlight") { - return name.replace("_", " ").replace(/\b\w/g, c => c.toUpperCase()); - } - return name; - } - font.pixelSize: Theme.fontSizeMedium - color: Theme.surfaceText - font.weight: modelData.name === currentDeviceName ? Font.Medium : Font.Normal - elide: Text.ElideRight - width: parent.width - horizontalAlignment: Text.AlignLeft - } - - StyledText { - text: modelData.name - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceVariantText - elide: Text.ElideRight - width: parent.width - horizontalAlignment: Text.AlignLeft - } - - StyledText { - text: { - const deviceClass = modelData.class || ""; - if (deviceClass === "backlight") - return I18n.tr("Backlight device"); - if (deviceClass === "ddc") - return I18n.tr("DDC/CI monitor"); - if (deviceClass === "leds") - return I18n.tr("LED device"); - return deviceClass; - } - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceVariantText - elide: Text.ElideRight - width: parent.width - horizontalAlignment: Text.AlignLeft - } - } - } - - Row { - id: exponentControls - width: 140 - height: 28 - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - spacing: Theme.spacingXS - visible: SessionData.getBrightnessExponential(modelData.name) - z: 1 - - StyledRect { - width: 28 - height: 28 - radius: Theme.cornerRadius - color: Theme.withAlpha(Theme.surfaceContainerHighest, Theme.popupTransparency) - opacity: SessionData.getBrightnessExponent(modelData.name) > 1.0 ? 1.0 : 0.4 - - DankIcon { - anchors.centerIn: parent - name: "remove" - size: 14 - color: Theme.surfaceText - } - - StateLayer { - stateColor: Theme.primary - cornerRadius: parent.radius - enabled: SessionData.getBrightnessExponent(modelData.name) > 1.0 - onClicked: { - const current = SessionData.getBrightnessExponent(modelData.name); - const newValue = Math.max(1.0, Math.round((current - 0.1) * 10) / 10); - SessionData.setBrightnessExponent(modelData.name, newValue); - } - } - } - - StyledRect { - width: 50 - height: 28 - radius: Theme.cornerRadius - color: Theme.withAlpha(Theme.surfaceContainerHighest, Theme.popupTransparency) - border.width: 0 - - StyledText { - anchors.centerIn: parent - text: SessionData.getBrightnessExponent(modelData.name).toFixed(1) - font.pixelSize: Theme.fontSizeSmall - font.weight: Font.Medium - color: Theme.primary - } - } - - StyledRect { - width: 28 - height: 28 - radius: Theme.cornerRadius - color: Theme.withAlpha(Theme.surfaceContainerHighest, Theme.popupTransparency) - opacity: SessionData.getBrightnessExponent(modelData.name) < 2.5 ? 1.0 : 0.4 - - DankIcon { - anchors.centerIn: parent - name: "add" - size: 14 - color: Theme.surfaceText - } - - StateLayer { - stateColor: Theme.primary - cornerRadius: parent.radius - enabled: SessionData.getBrightnessExponent(modelData.name) < 2.5 - onClicked: { - const current = SessionData.getBrightnessExponent(modelData.name); - const newValue = Math.min(2.5, Math.round((current + 0.1) * 10) / 10); - SessionData.setBrightnessExponent(modelData.name, newValue); - } - } - } - } - } - - Rectangle { - width: parent.width - height: 24 - radius: height / 2 - color: SessionData.getBrightnessExponential(modelData.name) ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : Theme.withAlpha(Theme.surfaceText, 0.05) - - Row { - anchors.centerIn: parent - spacing: 4 - - DankIcon { - name: "show_chart" - size: 14 - color: SessionData.getBrightnessExponential(modelData.name) ? Theme.primary : Theme.surfaceText - anchors.verticalCenter: parent.verticalCenter - } - - StyledText { - text: SessionData.getBrightnessExponential(modelData.name) ? I18n.tr("Exponential") : I18n.tr("Linear") - font.pixelSize: Theme.fontSizeSmall - color: SessionData.getBrightnessExponential(modelData.name) ? Theme.primary : Theme.surfaceText - anchors.verticalCenter: parent.verticalCenter - } - } - - DankRipple { - id: expToggleRipple - cornerRadius: parent.radius - } - - MouseArea { - anchors.fill: parent - cursorShape: Qt.PointingHandCursor - onPressed: mouse => expToggleRipple.trigger(mouse.x, mouse.y) - onClicked: { - const currentState = SessionData.getBrightnessExponential(modelData.name); - SessionData.setBrightnessExponential(modelData.name, !currentState); - } - } - } - } - - DankRipple { - id: deviceRipple - cornerRadius: parent.radius - } - - MouseArea { - anchors.fill: parent - anchors.bottomMargin: 28 - anchors.rightMargin: SessionData.getBrightnessExponential(modelData.name) ? 145 : 0 - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onPressed: mouse => deviceRipple.trigger(mouse.x, mouse.y) - onClicked: { - const pinKey = root.getScreenPinKey(); - if (pinKey.length > 0 && modelData.name !== currentDeviceName) { - const pins = JSON.parse(JSON.stringify(SettingsData.brightnessDevicePins || {})); - if (pins[pinKey]) { - delete pins[pinKey]; - SettingsData.set("brightnessDevicePins", pins); - } - } - currentDeviceName = modelData.name; - deviceNameChanged(modelData.name); - } - } - } - } - } - } -} diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Details/DiskUsageDetail.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Details/DiskUsageDetail.qml deleted file mode 100644 index 90fbf9d..0000000 --- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Details/DiskUsageDetail.qml +++ /dev/null @@ -1,177 +0,0 @@ -import QtQuick -import qs.Common -import qs.Services -import qs.Widgets - -Rectangle { - id: root - - LayoutMirroring.enabled: I18n.isRtl - LayoutMirroring.childrenInherit: true - - property string currentMountPath: "/" - property string instanceId: "" - - signal mountPathChanged(string newMountPath) - - implicitHeight: diskContent.height + Theme.spacingM - radius: Theme.cornerRadius - color: Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency) - border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08) - border.width: 0 - - Component.onCompleted: { - DgopService.addRef(["diskmounts"]); - } - - Component.onDestruction: { - DgopService.removeRef(["diskmounts"]); - } - - DankFlickable { - id: diskContent - anchors.top: parent.top - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: parent.bottom - anchors.margins: Theme.spacingM - anchors.topMargin: Theme.spacingM - contentHeight: diskColumn.height - clip: true - - Column { - id: diskColumn - width: parent.width - spacing: Theme.spacingS - - Item { - width: parent.width - height: 100 - visible: !DgopService.dgopAvailable || !DgopService.diskMounts || DgopService.diskMounts.length === 0 - - Column { - anchors.centerIn: parent - spacing: Theme.spacingM - - DankIcon { - anchors.horizontalCenter: parent.horizontalCenter - name: DgopService.dgopAvailable ? "storage" : "error" - size: 32 - color: DgopService.dgopAvailable ? Theme.primary : Theme.error - } - - StyledText { - anchors.horizontalCenter: parent.horizontalCenter - text: DgopService.dgopAvailable ? I18n.tr("No disk data available") : I18n.tr("dgop not available") - font.pixelSize: Theme.fontSizeMedium - color: Theme.surfaceText - horizontalAlignment: Text.AlignHCenter - } - } - } - - Repeater { - model: DgopService.diskMounts || [] - delegate: Rectangle { - required property var modelData - required property int index - - width: parent.width - height: 80 - radius: Theme.cornerRadius - color: Theme.surfaceLight - border.color: modelData.mount === currentMountPath ? Theme.primary : Theme.outlineLight - border.width: modelData.mount === currentMountPath ? 2 : 1 - - Row { - anchors.left: parent.left - anchors.verticalCenter: parent.verticalCenter - anchors.leftMargin: Theme.spacingM - spacing: Theme.spacingM - - Column { - anchors.verticalCenter: parent.verticalCenter - spacing: 2 - - DankIcon { - name: "storage" - size: Theme.iconSize - color: { - const percentStr = modelData.percent?.replace("%", "") || "0"; - const percent = parseFloat(percentStr) || 0; - if (percent > 90) - return Theme.error; - if (percent > 75) - return Theme.warning; - return modelData.mount === currentMountPath ? Theme.primary : Theme.surfaceText; - } - anchors.horizontalCenter: parent.horizontalCenter - } - - StyledText { - text: { - const percentStr = modelData.percent?.replace("%", "") || "0"; - const percent = parseFloat(percentStr) || 0; - return percent.toFixed(0) + "%"; - } - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceText - anchors.horizontalCenter: parent.horizontalCenter - } - } - - Column { - anchors.verticalCenter: parent.verticalCenter - width: parent.parent.width - parent.parent.anchors.leftMargin - parent.spacing - 50 - Theme.spacingM - - StyledText { - text: modelData.mount === "/" ? I18n.tr("Root Filesystem") : modelData.mount - font.pixelSize: Theme.fontSizeMedium - color: Theme.surfaceText - font.weight: modelData.mount === currentMountPath ? Font.Medium : Font.Normal - elide: Text.ElideRight - width: parent.width - horizontalAlignment: Text.AlignLeft - } - - StyledText { - text: modelData.mount - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceVariantText - elide: Text.ElideRight - width: parent.width - visible: modelData.mount !== "/" - horizontalAlignment: Text.AlignLeft - } - - StyledText { - text: `${modelData.used || "?"} / ${modelData.size || "?"}` - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceVariantText - elide: Text.ElideRight - width: parent.width - horizontalAlignment: Text.AlignLeft - } - } - } - - DankRipple { - id: mountRipple - cornerRadius: parent.radius - } - - MouseArea { - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onPressed: mouse => mountRipple.trigger(mouse.x, mouse.y) - onClicked: { - currentMountPath = modelData.mount; - mountPathChanged(modelData.mount); - } - } - } - } - } - } -} diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Details/NetworkDetail.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Details/NetworkDetail.qml deleted file mode 100644 index 5f1738a..0000000 --- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Details/NetworkDetail.qml +++ /dev/null @@ -1,893 +0,0 @@ -import QtQuick -import QtQuick.Controls -import Quickshell -import qs.Common -import qs.Services -import qs.Widgets -import qs.Modals - -Rectangle { - id: root - - LayoutMirroring.enabled: I18n.isRtl - LayoutMirroring.childrenInherit: true - - implicitHeight: { - if (height > 0) - return height; - if (NetworkService.wifiToggling) - return headerRow.height + wifiToggleContent.height + Theme.spacingM; - if (NetworkService.wifiEnabled) - return headerRow.height + wifiContent.height + Theme.spacingM; - return headerRow.height + wifiOffContent.height + Theme.spacingM; - } - radius: Theme.cornerRadius - color: Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency) - border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08) - border.width: 0 - - Component.onCompleted: { - NetworkService.addRef(); - } - - Component.onDestruction: { - NetworkService.removeRef(); - } - - property bool hasEthernetAvailable: (NetworkService.ethernetDevices?.length ?? 0) > 0 - property bool hasWifiAvailable: (NetworkService.wifiDevices?.length ?? 0) > 0 - property bool hasBothConnectionTypes: hasEthernetAvailable && hasWifiAvailable - property int maxPinnedNetworks: 3 - - function normalizePinList(value) { - if (Array.isArray(value)) - return value.filter(v => v); - if (typeof value === "string" && value.length > 0) - return [value]; - return []; - } - - function getPinnedNetworks() { - const pins = SettingsData.wifiNetworkPins || {}; - return normalizePinList(pins["preferredWifi"]); - } - - property int currentPreferenceIndex: { - if (DMSService.apiVersion < 5) - return 1; - if (NetworkService.backend !== "networkmanager" || DMSService.apiVersion <= 10) - return 1; - if (!hasEthernetAvailable) - return 1; - if (!hasWifiAvailable) - return 0; - - const pref = NetworkService.userPreference; - switch (pref) { - case "ethernet": - return 0; - case "wifi": - return 1; - default: - return NetworkService.networkStatus === "ethernet" ? 0 : 1; - } - } - - Row { - id: headerRow - anchors.left: parent.left - anchors.right: parent.right - anchors.top: parent.top - anchors.leftMargin: Theme.spacingM - anchors.rightMargin: Theme.spacingM - anchors.topMargin: Theme.spacingS - height: Math.max(headerLeft.implicitHeight, rightControls.implicitHeight) + Theme.spacingS * 2 - - StyledText { - id: headerLeft - text: I18n.tr("Network") - font.pixelSize: Theme.fontSizeLarge - color: Theme.surfaceText - font.weight: Font.Medium - anchors.verticalCenter: parent.verticalCenter - } - - Item { - height: 1 - width: parent.width - headerLeft.width - rightControls.width - } - - Row { - id: rightControls - anchors.verticalCenter: parent.verticalCenter - spacing: Theme.spacingS - - DankDropdown { - id: wifiDeviceDropdown - anchors.verticalCenter: parent.verticalCenter - visible: currentPreferenceIndex === 1 && (NetworkService.wifiDevices?.length ?? 0) > 1 - compactMode: true - dropdownWidth: 120 - popupWidth: 160 - alignPopupRight: true - - options: { - const devices = NetworkService.wifiDevices; - if (!devices || devices.length === 0) - return [I18n.tr("Auto")]; - return [I18n.tr("Auto")].concat(devices.map(d => d.name)); - } - - currentValue: NetworkService.wifiDeviceOverride || I18n.tr("Auto") - - onValueChanged: value => { - const deviceName = value === I18n.tr("Auto") ? "" : value; - NetworkService.setWifiDeviceOverride(deviceName); - } - } - - DankButtonGroup { - id: preferenceControls - anchors.verticalCenter: parent.verticalCenter - visible: hasBothConnectionTypes && NetworkService.backend === "networkmanager" && DMSService.apiVersion > 10 - buttonHeight: 28 - textSize: Theme.fontSizeSmall - - model: [I18n.tr("Ethernet"), I18n.tr("WiFi")] - currentIndex: currentPreferenceIndex - selectionMode: "single" - onSelectionChanged: (index, selected) => { - if (!selected) - return; - NetworkService.setNetworkPreference(index === 0 ? "ethernet" : "wifi"); - } - } - - DankActionButton { - anchors.verticalCenter: parent.verticalCenter - iconName: "settings" - buttonSize: 28 - iconSize: 16 - iconColor: Theme.surfaceVariantText - onClicked: { - PopoutService.closeControlCenter(); - PopoutService.openSettingsWithTab("network"); - } - } - } - } - - Item { - id: wifiToggleContent - anchors.top: headerRow.bottom - anchors.left: parent.left - anchors.right: parent.right - anchors.margins: Theme.spacingM - anchors.topMargin: Theme.spacingM - visible: currentPreferenceIndex === 1 && NetworkService.wifiToggling - height: visible ? wifiToggleColumn.implicitHeight + Theme.spacingM * 2 : 0 - - Column { - id: wifiToggleColumn - anchors.centerIn: parent - spacing: Theme.spacingM - - DankIcon { - anchors.horizontalCenter: parent.horizontalCenter - name: "sync" - size: 32 - color: Theme.primary - - RotationAnimation on rotation { - running: NetworkService.wifiToggling - loops: Animation.Infinite - from: 0 - to: 360 - duration: 1000 - } - } - - StyledText { - anchors.horizontalCenter: parent.horizontalCenter - text: NetworkService.wifiEnabled ? I18n.tr("Disabling WiFi...") : I18n.tr("Enabling WiFi...") - font.pixelSize: Theme.fontSizeMedium - color: Theme.surfaceText - horizontalAlignment: Text.AlignHCenter - } - } - } - - Item { - id: wifiOffContent - anchors.top: headerRow.bottom - anchors.left: parent.left - anchors.right: parent.right - anchors.margins: Theme.spacingM - anchors.topMargin: Theme.spacingM - visible: currentPreferenceIndex === 1 && !NetworkService.wifiEnabled && !NetworkService.wifiToggling - height: visible ? wifiOffColumn.implicitHeight + Theme.spacingM * 2 : 0 - - Column { - id: wifiOffColumn - anchors.centerIn: parent - spacing: Theme.spacingL - width: parent.width - - DankIcon { - anchors.horizontalCenter: parent.horizontalCenter - name: "wifi_off" - size: 48 - color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.5) - } - - StyledText { - anchors.horizontalCenter: parent.horizontalCenter - text: I18n.tr("WiFi is off") - font.pixelSize: Theme.fontSizeLarge - color: Theme.surfaceText - font.weight: Font.Medium - horizontalAlignment: Text.AlignHCenter - } - - Rectangle { - anchors.horizontalCenter: parent.horizontalCenter - width: enableWifiLabel.implicitWidth + Theme.spacingL * 2 - height: enableWifiLabel.implicitHeight + Theme.spacingM * 2 - radius: height / 2 - color: enableWifiButton.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08) - border.width: 0 - border.color: Theme.primary - - StyledText { - id: enableWifiLabel - anchors.centerIn: parent - text: I18n.tr("Enable WiFi") - color: Theme.primary - font.pixelSize: Theme.fontSizeMedium - font.weight: Font.Medium - } - - MouseArea { - id: enableWifiButton - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onClicked: NetworkService.toggleWifiRadio() - } - } - } - } - - ScriptModel { - id: wiredConnectionsModel - objectProp: "uuid" - values: { - const networks = NetworkService.wiredConnections; - if (!networks) - return []; - let sorted = [...networks]; - sorted.sort((a, b) => { - if (a.isActive && !b.isActive) - return -1; - if (!a.isActive && b.isActive) - return 1; - return a.id.localeCompare(b.id); - }); - return sorted; - } - } - - DankFlickable { - id: wiredContent - anchors.top: headerRow.bottom - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: parent.bottom - anchors.margins: Theme.spacingM - anchors.topMargin: Theme.spacingM - visible: currentPreferenceIndex === 0 && NetworkService.backend === "networkmanager" && DMSService.apiVersion > 10 - contentHeight: wiredColumn.height - clip: true - - Column { - id: wiredColumn - width: parent.width - spacing: Theme.spacingS - - Repeater { - model: wiredConnectionsModel - - delegate: Rectangle { - id: wiredDelegate - required property var modelData - required property int index - - readonly property bool isActive: modelData.isActive - readonly property string configName: modelData.id || I18n.tr("Unknown Config") - - width: parent.width - height: wiredContentRow.implicitHeight + Theme.spacingM * 2 - radius: Theme.cornerRadius - color: wiredNetworkMouseArea.containsMouse ? Theme.primaryHoverLight : Theme.surfaceLight - border.color: isActive ? Theme.primary : Theme.outlineLight - border.width: isActive ? 2 : 1 - - Row { - id: wiredContentRow - anchors.left: parent.left - anchors.verticalCenter: parent.verticalCenter - anchors.leftMargin: Theme.spacingM - spacing: Theme.spacingS - - DankIcon { - name: "lan" - size: Theme.iconSize - 4 - color: wiredDelegate.isActive ? Theme.primary : Theme.surfaceText - anchors.verticalCenter: parent.verticalCenter - } - - Column { - anchors.verticalCenter: parent.verticalCenter - width: 200 - - StyledText { - text: wiredDelegate.configName - font.pixelSize: Theme.fontSizeMedium - color: wiredDelegate.isActive ? Theme.primary : Theme.surfaceText - font.weight: wiredDelegate.isActive ? Font.Medium : Font.Normal - elide: Text.ElideRight - width: parent.width - } - } - } - - DankActionButton { - id: wiredOptionsButton - anchors.right: parent.right - anchors.rightMargin: Theme.spacingS - anchors.verticalCenter: parent.verticalCenter - iconName: "more_horiz" - buttonSize: 28 - onClicked: { - if (wiredNetworkContextMenu.visible) { - wiredNetworkContextMenu.close(); - return; - } - wiredNetworkContextMenu.currentID = modelData.id; - wiredNetworkContextMenu.currentUUID = modelData.uuid; - wiredNetworkContextMenu.currentConnected = wiredDelegate.isActive; - wiredNetworkContextMenu.popup(wiredOptionsButton, -wiredNetworkContextMenu.width + wiredOptionsButton.width, wiredOptionsButton.height + Theme.spacingXS); - } - } - - DankRipple { - id: wiredRipple - cornerRadius: parent.radius - } - - MouseArea { - id: wiredNetworkMouseArea - anchors.fill: parent - anchors.rightMargin: wiredOptionsButton.width + Theme.spacingS - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onPressed: mouse => wiredRipple.trigger(mouse.x, mouse.y) - onClicked: function (event) { - if (modelData.uuid !== NetworkService.ethernetConnectionUuid) - NetworkService.connectToSpecificWiredConfig(modelData.uuid); - event.accepted = true; - } - } - } - } - } - } - - Menu { - id: wiredNetworkContextMenu - width: 150 - closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent - - property string currentID: "" - property string currentUUID: "" - property bool currentConnected: false - - background: Rectangle { - color: Theme.withAlpha(Theme.surfaceContainer, Theme.popupTransparency) - radius: Theme.cornerRadius - border.width: 0 - border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12) - } - - MenuItem { - text: I18n.tr("Activate") - height: !wiredNetworkContextMenu.currentConnected ? 32 : 0 - visible: !wiredNetworkContextMenu.currentConnected - - contentItem: StyledText { - text: parent.text - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceText - leftPadding: Theme.spacingS - verticalAlignment: Text.AlignVCenter - } - - background: Rectangle { - color: parent.hovered ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08) : "transparent" - radius: Theme.cornerRadius / 2 - } - - onTriggered: { - if (!wiredNetworkContextMenu.currentConnected) - NetworkService.connectToSpecificWiredConfig(wiredNetworkContextMenu.currentUUID); - } - } - - MenuItem { - text: I18n.tr("Disconnect") - height: wiredNetworkContextMenu.currentConnected ? 32 : 0 - visible: wiredNetworkContextMenu.currentConnected - - contentItem: StyledText { - text: parent.text - font.pixelSize: Theme.fontSizeSmall - color: Theme.error - leftPadding: Theme.spacingS - verticalAlignment: Text.AlignVCenter - } - - background: Rectangle { - color: parent.hovered ? Qt.rgba(Theme.error.r, Theme.error.g, Theme.error.b, 0.08) : "transparent" - radius: Theme.cornerRadius / 2 - } - - onTriggered: { - NetworkService.toggleNetworkConnection("ethernet"); - } - } - - MenuItem { - text: I18n.tr("Network Info") - height: wiredNetworkContextMenu.currentConnected ? 32 : 0 - visible: wiredNetworkContextMenu.currentConnected - - contentItem: StyledText { - text: parent.text - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceText - leftPadding: Theme.spacingS - verticalAlignment: Text.AlignVCenter - } - - background: Rectangle { - color: parent.hovered ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08) : "transparent" - radius: Theme.cornerRadius / 2 - } - - onTriggered: { - const networkData = NetworkService.getWiredNetworkInfo(wiredNetworkContextMenu.currentUUID); - networkWiredInfoModalLoader.active = true; - networkWiredInfoModalLoader.item.showNetworkInfo(wiredNetworkContextMenu.currentID, networkData); - } - } - } - - ScriptModel { - id: wifiNetworksModel - objectProp: "ssid" - values: wifiContent.menuOpen ? wifiContent.frozenNetworks : wifiContent.sortedNetworks - } - - Item { - id: wifiScanningOverlay - anchors.top: headerRow.bottom - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: parent.bottom - anchors.margins: Theme.spacingM - anchors.topMargin: Theme.spacingM - visible: currentPreferenceIndex === 1 && NetworkService.wifiEnabled && !NetworkService.wifiToggling && NetworkService.wifiInterface && (NetworkService.wifiNetworks?.length ?? 0) < 1 && NetworkService.isScanning - - DankIcon { - anchors.centerIn: parent - name: "refresh" - size: 48 - color: Qt.rgba(Theme.surfaceText.r || 0.8, Theme.surfaceText.g || 0.8, Theme.surfaceText.b || 0.8, 0.3) - - RotationAnimation on rotation { - running: wifiScanningOverlay.visible - loops: Animation.Infinite - from: 0 - to: 360 - duration: 1000 - } - } - } - - DankListView { - id: wifiContent - anchors.top: headerRow.bottom - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: parent.bottom - anchors.margins: Theme.spacingM - anchors.topMargin: Theme.spacingM - visible: currentPreferenceIndex === 1 && NetworkService.wifiEnabled && !NetworkService.wifiToggling && !wifiScanningOverlay.visible - clip: true - spacing: Theme.spacingS - model: wifiNetworksModel - - property var frozenNetworks: [] - property bool menuOpen: false - property var sortedNetworks: { - const ssid = NetworkService.currentWifiSSID; - const networks = NetworkService.wifiNetworks; - const pinnedList = root.getPinnedNetworks(); - - let sorted = [...networks]; - sorted.sort((a, b) => { - const aPinnedIndex = pinnedList.indexOf(a.ssid); - const bPinnedIndex = pinnedList.indexOf(b.ssid); - if (aPinnedIndex !== -1 || bPinnedIndex !== -1) { - if (aPinnedIndex === -1) - return 1; - if (bPinnedIndex === -1) - return -1; - return aPinnedIndex - bPinnedIndex; - } - if (a.ssid === ssid) - return -1; - if (b.ssid === ssid) - return 1; - return b.signal - a.signal; - }); - return sorted; - } - onSortedNetworksChanged: { - if (!menuOpen) - frozenNetworks = sortedNetworks; - } - onMenuOpenChanged: { - if (menuOpen) - frozenNetworks = sortedNetworks; - } - - delegate: Rectangle { - id: wifiDelegate - required property var modelData - required property int index - - readonly property bool isConnected: modelData.ssid === NetworkService.currentWifiSSID - readonly property bool isPinned: root.getPinnedNetworks().includes(modelData.ssid) - readonly property string networkName: modelData.ssid || I18n.tr("Unknown Network") - readonly property int signalStrength: modelData.signal || 0 - - width: wifiContent.width - height: wifiContentRow.implicitHeight + Theme.spacingM * 2 - radius: Theme.cornerRadius - color: networkMouseArea.containsMouse ? Theme.primaryHoverLight : Theme.surfaceLight - border.color: wifiDelegate.isConnected ? Theme.primary : Theme.outlineLight - border.width: wifiDelegate.isConnected ? 2 : 1 - - Row { - id: wifiContentRow - anchors.left: parent.left - anchors.verticalCenter: parent.verticalCenter - anchors.leftMargin: Theme.spacingM - spacing: Theme.spacingS - - DankIcon { - name: { - if (wifiDelegate.signalStrength >= 50) - return "wifi"; - if (wifiDelegate.signalStrength >= 25) - return "wifi_2_bar"; - return "wifi_1_bar"; - } - size: Theme.iconSize - 4 - color: wifiDelegate.isConnected ? Theme.primary : Theme.surfaceText - anchors.verticalCenter: parent.verticalCenter - } - - Column { - anchors.verticalCenter: parent.verticalCenter - width: 200 - - StyledText { - text: wifiDelegate.networkName - font.pixelSize: Theme.fontSizeMedium - color: Theme.surfaceText - font.weight: wifiDelegate.isConnected ? Font.Medium : Font.Normal - elide: Text.ElideRight - width: parent.width - } - - Row { - spacing: Theme.spacingXS - - StyledText { - text: wifiDelegate.isConnected ? I18n.tr("Connected") + " \u2022" : (modelData.secured ? I18n.tr("Secured") + " \u2022" : I18n.tr("Open") + " \u2022") - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceVariantText - } - - StyledText { - text: modelData.saved ? I18n.tr("Saved") : "" - font.pixelSize: Theme.fontSizeSmall - color: Theme.primary - visible: text.length > 0 - } - - StyledText { - text: (modelData.saved ? "\u2022 " : "") + wifiDelegate.signalStrength + "%" - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceVariantText - } - } - } - } - - DankActionButton { - id: optionsButton - anchors.right: parent.right - anchors.rightMargin: Theme.spacingS - anchors.verticalCenter: parent.verticalCenter - iconName: "more_horiz" - buttonSize: 28 - onClicked: { - if (networkContextMenu.visible) { - networkContextMenu.close(); - return; - } - wifiContent.menuOpen = true; - networkContextMenu.currentSSID = modelData.ssid; - networkContextMenu.currentSecured = modelData.secured; - networkContextMenu.currentConnected = wifiDelegate.isConnected; - networkContextMenu.currentSaved = modelData.saved; - networkContextMenu.currentSignal = modelData.signal; - networkContextMenu.currentAutoconnect = modelData.autoconnect || false; - networkContextMenu.popup(optionsButton, -networkContextMenu.width + optionsButton.width, optionsButton.height + Theme.spacingXS); - } - } - - Rectangle { - id: pinButton - anchors.right: parent.right - anchors.rightMargin: optionsButton.width + Theme.spacingM + Theme.spacingS - anchors.verticalCenter: parent.verticalCenter - width: pinWifiRow.width + Theme.spacingS * 2 - height: pinWifiRow.implicitHeight + Theme.spacingXS * 2 - radius: height / 2 - color: wifiDelegate.isPinned ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : Theme.withAlpha(Theme.surfaceText, 0.05) - - Row { - id: pinWifiRow - anchors.centerIn: parent - spacing: 4 - - DankIcon { - name: "push_pin" - size: 16 - color: wifiDelegate.isPinned ? Theme.primary : Theme.surfaceText - anchors.verticalCenter: parent.verticalCenter - } - - StyledText { - text: wifiDelegate.isPinned ? I18n.tr("Pinned") : I18n.tr("Pin") - font.pixelSize: Theme.fontSizeSmall - color: wifiDelegate.isPinned ? Theme.primary : Theme.surfaceText - anchors.verticalCenter: parent.verticalCenter - } - } - - DankRipple { - id: pinRipple - cornerRadius: parent.radius - } - - MouseArea { - anchors.fill: parent - cursorShape: Qt.PointingHandCursor - onPressed: mouse => pinRipple.trigger(mouse.x, mouse.y) - onClicked: { - const pins = JSON.parse(JSON.stringify(SettingsData.wifiNetworkPins || {})); - let pinnedList = root.normalizePinList(pins["preferredWifi"]); - const pinIndex = pinnedList.indexOf(modelData.ssid); - - if (pinIndex !== -1) { - pinnedList.splice(pinIndex, 1); - } else { - pinnedList.unshift(modelData.ssid); - if (pinnedList.length > root.maxPinnedNetworks) - pinnedList = pinnedList.slice(0, root.maxPinnedNetworks); - } - - if (pinnedList.length > 0) - pins["preferredWifi"] = pinnedList; - else - delete pins["preferredWifi"]; - - SettingsData.set("wifiNetworkPins", pins); - } - } - } - - DankActionButton { - id: qrCodeButton - visible: modelData.secured && modelData.saved - anchors.right: parent.right - anchors.rightMargin: optionsButton.width + pinWifiRow.width + 3 * Theme.spacingM + Theme.spacingS - anchors.verticalCenter: parent.verticalCenter - iconName: "qr_code" - buttonSize: 28 - onClicked: { - PopoutService.showWifiQRCodeModal(modelData.ssid); - } - } - - DankRipple { - id: wifiRipple - cornerRadius: parent.radius - } - - MouseArea { - id: networkMouseArea - anchors.fill: parent - anchors.rightMargin: optionsButton.width + pinWifiRow.width + (qrCodeButton.visible ? qrCodeButton.width : 0) + Theme.spacingS * 5 + Theme.spacingM - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onPressed: mouse => wifiRipple.trigger(mouse.x, mouse.y) - onClicked: function (event) { - if (wifiDelegate.isConnected) { - event.accepted = true; - return; - } - if (modelData.secured && !modelData.saved && DMSService.apiVersion < 7) { - PopoutService.showWifiPasswordModal(modelData.ssid); - } else { - NetworkService.connectToWifi(modelData.ssid); - } - event.accepted = true; - } - } - } - } - - Menu { - id: networkContextMenu - width: 150 - closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent - - property string currentSSID: "" - property bool currentSecured: false - property bool currentConnected: false - property bool currentSaved: false - property int currentSignal: 0 - property bool currentAutoconnect: false - - readonly property bool showSavedOptions: currentSaved || currentConnected - - onClosed: { - wifiContent.menuOpen = false; - } - - background: Rectangle { - color: Theme.withAlpha(Theme.surfaceContainer, Theme.popupTransparency) - radius: Theme.cornerRadius - border.width: 0 - border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12) - } - - MenuItem { - text: networkContextMenu.currentConnected ? I18n.tr("Disconnect") : I18n.tr("Connect") - height: 32 - - contentItem: StyledText { - text: parent.text - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceText - leftPadding: Theme.spacingS - verticalAlignment: Text.AlignVCenter - } - - background: Rectangle { - color: parent.hovered ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08) : "transparent" - radius: Theme.cornerRadius / 2 - } - - onTriggered: { - if (networkContextMenu.currentConnected) { - NetworkService.disconnectWifi(); - return; - } - if (networkContextMenu.currentSecured && !networkContextMenu.currentSaved && DMSService.apiVersion < 7) { - PopoutService.showWifiPasswordModal(networkContextMenu.currentSSID); - return; - } - NetworkService.connectToWifi(networkContextMenu.currentSSID); - } - } - - MenuItem { - text: I18n.tr("Network Info") - height: 32 - - contentItem: StyledText { - text: parent.text - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceText - leftPadding: Theme.spacingS - verticalAlignment: Text.AlignVCenter - } - - background: Rectangle { - color: parent.hovered ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08) : "transparent" - radius: Theme.cornerRadius / 2 - } - - onTriggered: { - const networkData = NetworkService.getNetworkInfo(networkContextMenu.currentSSID); - networkInfoModalLoader.active = true; - networkInfoModalLoader.item.showNetworkInfo(networkContextMenu.currentSSID, networkData); - } - } - - MenuItem { - text: networkContextMenu.currentAutoconnect ? I18n.tr("Disable Autoconnect") : I18n.tr("Enable Autoconnect") - height: networkContextMenu.showSavedOptions && DMSService.apiVersion > 13 ? 32 : 0 - visible: networkContextMenu.showSavedOptions && DMSService.apiVersion > 13 - - contentItem: StyledText { - text: parent.text - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceText - leftPadding: Theme.spacingS - verticalAlignment: Text.AlignVCenter - } - - background: Rectangle { - color: parent.hovered ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08) : "transparent" - radius: Theme.cornerRadius / 2 - } - - onTriggered: { - NetworkService.setWifiAutoconnect(networkContextMenu.currentSSID, !networkContextMenu.currentAutoconnect); - } - } - - MenuItem { - text: I18n.tr("Forget Network") - height: networkContextMenu.showSavedOptions ? 32 : 0 - visible: networkContextMenu.showSavedOptions - - contentItem: StyledText { - text: parent.text - font.pixelSize: Theme.fontSizeSmall - color: Theme.error - leftPadding: Theme.spacingS - verticalAlignment: Text.AlignVCenter - } - - background: Rectangle { - color: parent.hovered ? Qt.rgba(Theme.error.r, Theme.error.g, Theme.error.b, 0.08) : "transparent" - radius: Theme.cornerRadius / 2 - } - - onTriggered: { - NetworkService.forgetWifiNetwork(networkContextMenu.currentSSID); - } - } - } - - Loader { - id: networkInfoModalLoader - active: false - sourceComponent: NetworkInfoModal {} - } - - Loader { - id: networkWiredInfoModalLoader - active: false - sourceComponent: NetworkWiredInfoModal {} - } -} diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Models/WidgetModel.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Models/WidgetModel.qml deleted file mode 100644 index ac616ae..0000000 --- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Models/WidgetModel.qml +++ /dev/null @@ -1,283 +0,0 @@ -import QtQuick -import qs.Common -import qs.Services -import qs.Modules.ControlCenter.BuiltinPlugins -import "../utils/widgets.js" as WidgetUtils - -QtObject { - id: root - - property var vpnBuiltinInstance: null - property var cupsBuiltinInstance: null - - property var vpnLoader: Loader { - active: false - sourceComponent: Component { - VpnWidget {} - } - - onItemChanged: { - root.vpnBuiltinInstance = item; - } - - Connections { - target: SettingsData - function onControlCenterWidgetsChanged() { - const widgets = SettingsData.controlCenterWidgets || []; - const hasVpnWidget = widgets.some(w => w.id === "builtin_vpn"); - if (!hasVpnWidget && vpnLoader.active) { - console.log("VpnWidget: No VPN widget in control center, deactivating loader"); - vpnLoader.active = false; - } - } - } - } - - property var cupsLoader: Loader { - active: false - sourceComponent: Component { - CupsWidget {} - } - - onItemChanged: { - root.cupsBuiltinInstance = item; - } - - onActiveChanged: { - if (!active) { - root.cupsBuiltinInstance = null; - } - } - - Connections { - target: SettingsData - function onControlCenterWidgetsChanged() { - const widgets = SettingsData.controlCenterWidgets || []; - const hasCupsWidget = widgets.some(w => w.id === "builtin_cups"); - if (!hasCupsWidget && cupsLoader.active) { - console.log("CupsWidget: No CUPS widget in control center, deactivating loader"); - cupsLoader.active = false; - } - } - } - } - - readonly property var coreWidgetDefinitions: [ - { - "id": "nightMode", - "text": I18n.tr("Night Mode"), - "description": I18n.tr("Blue light filter"), - "icon": "nightlight", - "type": "toggle", - "enabled": DisplayService.automationAvailable, - "warning": !DisplayService.automationAvailable ? I18n.tr("Requires night mode support") : undefined - }, - { - "id": "darkMode", - "text": I18n.tr("Dark Mode"), - "description": I18n.tr("System theme toggle"), - "icon": "contrast", - "type": "toggle", - "enabled": true - }, - { - "id": "doNotDisturb", - "text": I18n.tr("Do Not Disturb"), - "description": I18n.tr("Block notifications"), - "icon": "do_not_disturb_on", - "type": "toggle", - "enabled": true - }, - { - "id": "idleInhibitor", - "text": I18n.tr("Keep Awake"), - "description": I18n.tr("Prevent screen timeout"), - "icon": "motion_sensor_active", - "type": "toggle", - "enabled": true - }, - { - "id": "wifi", - "text": I18n.tr("Network"), - "description": I18n.tr("Wi-Fi and Ethernet connection"), - "icon": "wifi", - "type": "connection", - "enabled": NetworkService.wifiAvailable, - "warning": !NetworkService.wifiAvailable ? I18n.tr("Wi-Fi not available") : undefined - }, - { - "id": "bluetooth", - "text": I18n.tr("Bluetooth"), - "description": I18n.tr("Device connections"), - "icon": "bluetooth", - "type": "connection", - "enabled": BluetoothService.available, - "warning": !BluetoothService.available ? I18n.tr("Bluetooth not available") : undefined - }, - { - "id": "audioOutput", - "text": I18n.tr("Audio Output"), - "description": I18n.tr("Speaker settings"), - "icon": "volume_up", - "type": "connection", - "enabled": true - }, - { - "id": "audioInput", - "text": I18n.tr("Audio Input"), - "description": I18n.tr("Microphone settings"), - "icon": "mic", - "type": "connection", - "enabled": true - }, - { - "id": "volumeSlider", - "text": I18n.tr("Volume Slider"), - "description": I18n.tr("Audio volume control"), - "icon": "volume_up", - "type": "slider", - "enabled": true - }, - { - "id": "brightnessSlider", - "text": I18n.tr("Brightness Slider"), - "description": I18n.tr("Display brightness control"), - "icon": "brightness_6", - "type": "slider", - "enabled": DisplayService.brightnessAvailable, - "warning": !DisplayService.brightnessAvailable ? I18n.tr("Brightness control not available") : undefined, - "allowMultiple": true - }, - { - "id": "inputVolumeSlider", - "text": I18n.tr("Input Volume Slider"), - "description": I18n.tr("Microphone volume control"), - "icon": "mic", - "type": "slider", - "enabled": true - }, - { - "id": "battery", - "text": I18n.tr("Battery"), - "description": I18n.tr("Battery and power management"), - "icon": "battery_std", - "type": "action", - "enabled": true - }, - { - "id": "diskUsage", - "text": I18n.tr("Disk Usage"), - "description": I18n.tr("Filesystem usage monitoring"), - "icon": "storage", - "type": "action", - "enabled": DgopService.dgopAvailable, - "warning": !DgopService.dgopAvailable ? I18n.tr("Requires 'dgop' tool") : undefined, - "allowMultiple": true - }, - { - "id": "colorPicker", - "text": I18n.tr("Color Picker"), - "description": I18n.tr("Choose colors from palette"), - "icon": "palette", - "type": "action", - "enabled": true - }, - { - "id": "builtin_vpn", - "text": I18n.tr("VPN"), - "description": I18n.tr("VPN connections"), - "icon": "vpn_key", - "type": "builtin_plugin", - "enabled": DMSNetworkService.available, - "warning": !DMSNetworkService.available ? I18n.tr("VPN not available") : undefined, - "isBuiltinPlugin": true - }, - { - "id": "builtin_cups", - "text": I18n.tr("Printers"), - "description": I18n.tr("Print Server Management"), - "icon": "Print", - "type": "builtin_plugin", - "enabled": CupsService.available, - "warning": !CupsService.available ? I18n.tr("CUPS not available") : undefined, - "isBuiltinPlugin": true - } - ] - - function getPluginWidgets() { - const plugins = []; - const loadedPlugins = PluginService.getLoadedPlugins(); - - for (var i = 0; i < loadedPlugins.length; i++) { - const plugin = loadedPlugins[i]; - - if (plugin.type === "daemon") { - continue; - } - - const pluginComponent = PluginService.pluginWidgetComponents[plugin.id]; - if (!pluginComponent) - continue; - - let tempInstance; - try { - tempInstance = pluginComponent.createObject(null); - } catch (e) { - PluginService.reloadPlugin(plugin.id); - continue; - } - if (!tempInstance) - continue; - - const hasCCWidget = tempInstance.ccWidgetIcon && tempInstance.ccWidgetIcon.length > 0; - tempInstance.destroy(); - - if (!hasCCWidget) { - continue; - } - - plugins.push({ - "id": "plugin_" + plugin.id, - "pluginId": plugin.id, - "text": plugin.name || I18n.tr("Plugin"), - "description": plugin.description || "", - "icon": plugin.icon || "extension", - "type": "plugin", - "enabled": true, - "isPlugin": true - }); - } - - return plugins; - } - - readonly property var baseWidgetDefinitions: coreWidgetDefinitions - - function getWidgetForId(widgetId) { - return WidgetUtils.getWidgetForId(baseWidgetDefinitions, widgetId); - } - - function addWidget(widgetId) { - WidgetUtils.addWidget(widgetId); - } - - function removeWidget(index) { - WidgetUtils.removeWidget(index); - } - - function toggleWidgetSize(index) { - WidgetUtils.toggleWidgetSize(index); - } - - function moveWidget(fromIndex, toIndex) { - WidgetUtils.moveWidget(fromIndex, toIndex); - } - - function resetToDefault() { - WidgetUtils.resetToDefault(); - } - - function clearAll() { - WidgetUtils.clearAll(); - } -} diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Widgets/AudioSliderRow.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Widgets/AudioSliderRow.qml deleted file mode 100644 index 81d346d..0000000 --- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Widgets/AudioSliderRow.qml +++ /dev/null @@ -1,103 +0,0 @@ -import QtQuick -import qs.Common -import qs.Services -import qs.Widgets - -Row { - id: root - - LayoutMirroring.enabled: I18n.isRtl - LayoutMirroring.childrenInherit: true - - property var defaultSink: AudioService.sink - property color sliderTrackColor: "transparent" - - height: 40 - spacing: 0 - - Rectangle { - width: Theme.iconSize + Theme.spacingS * 2 - height: Theme.iconSize + Theme.spacingS * 2 - anchors.verticalCenter: parent.verticalCenter - radius: (Theme.iconSize + Theme.spacingS * 2) / 2 - color: iconArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : Theme.withAlpha(Theme.primary, 0) - - DankRipple { - id: iconRipple - cornerRadius: parent.radius - } - - MouseArea { - id: iconArea - anchors.fill: parent - visible: defaultSink !== null - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onPressed: mouse => iconRipple.trigger(mouse.x, mouse.y) - onClicked: { - if (defaultSink) { - SessionData.suppressOSDTemporarily(); - defaultSink.audio.muted = !defaultSink.audio.muted; - } - } - } - - DankIcon { - anchors.centerIn: parent - name: { - if (!defaultSink) - return "volume_off"; - - let volume = defaultSink.audio.volume; - let muted = defaultSink.audio.muted; - - if (muted) - return "volume_off"; - if (volume === 0.0) - return "volume_mute"; - if (volume <= 0.33) - return "volume_down"; - if (volume <= 0.66) - return "volume_up"; - return "volume_up"; - } - size: Theme.iconSize - color: defaultSink && !defaultSink.audio.muted && defaultSink.audio.volume > 0 ? Theme.primary : Theme.surfaceText - } - } - - DankSlider { - id: volumeSlider - - readonly property real actualVolumePercent: defaultSink ? Math.round(defaultSink.audio.volume * 100) : 0 - - anchors.verticalCenter: parent.verticalCenter - width: parent.width - (Theme.iconSize + Theme.spacingS * 2) - enabled: defaultSink !== null - minimum: 0 - maximum: AudioService.sinkMaxVolume - showValue: true - unit: "%" - valueOverride: actualVolumePercent - thumbOutlineColor: Theme.surfaceContainer - trackColor: root.sliderTrackColor.a > 0 ? root.sliderTrackColor : Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency) - - onSliderValueChanged: function (newValue) { - if (defaultSink) { - SessionData.suppressOSDTemporarily(); - defaultSink.audio.volume = newValue / 100.0; - if (newValue > 0 && defaultSink.audio.muted) { - defaultSink.audio.muted = false; - } - AudioService.playVolumeChangeSoundIfEnabled(); - } - } - } - - Binding { - target: volumeSlider - property: "value" - value: defaultSink ? Math.min(AudioService.sinkMaxVolume, Math.round(defaultSink.audio.volume * 100)) : 0 - when: !volumeSlider.isDragging - } -} diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Widgets/BatteryPill.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Widgets/BatteryPill.qml deleted file mode 100644 index c14c308..0000000 --- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Widgets/BatteryPill.qml +++ /dev/null @@ -1,46 +0,0 @@ -import QtQuick -import qs.Common -import qs.Services -import qs.Modules.ControlCenter.Widgets - -CompoundPill { - id: root - - iconName: BatteryService.getBatteryIcon() - - isActive: BatteryService.batteryAvailable && (BatteryService.isCharging || BatteryService.isPluggedIn) - - primaryText: { - if (!BatteryService.batteryAvailable) { - return I18n.tr("No battery"); - } - return I18n.tr("Battery"); - } - - secondaryText: { - if (!BatteryService.batteryAvailable) { - return I18n.tr("Not available"); - } - if (BatteryService.isCharging) { - return `${BatteryService.batteryLevel}% • ` + I18n.tr("Charging"); - } - if (BatteryService.isPluggedIn) { - return `${BatteryService.batteryLevel}% • ` + I18n.tr("Plugged in"); - } - return `${BatteryService.batteryLevel}%`; - } - - iconColor: { - if (BatteryService.isLowBattery && !BatteryService.isCharging) { - return Theme.error; - } - if (BatteryService.isCharging || BatteryService.isPluggedIn) { - return Theme.primary; - } - return Theme.surfaceText; - } - - onToggled: { - expandClicked(); - } -} diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Widgets/BrightnessSliderRow.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Widgets/BrightnessSliderRow.qml deleted file mode 100644 index 037c08f..0000000 --- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Widgets/BrightnessSliderRow.qml +++ /dev/null @@ -1,194 +0,0 @@ -import QtQuick -import qs.Common -import qs.Services -import qs.Widgets - -Row { - id: root - - LayoutMirroring.enabled: I18n.isRtl - LayoutMirroring.childrenInherit: true - - property string deviceName: "" - property string instanceId: "" - property string screenName: "" - property var parentScreen: null - - signal iconClicked - - height: 40 - spacing: 0 - - DankTooltipV2 { - id: sharedTooltip - } - - property string targetDeviceName: { - if (!DisplayService.brightnessAvailable || !DisplayService.devices || DisplayService.devices.length === 0) { - return ""; - } - - if (screenName && screenName.length > 0) { - const pins = SettingsData.brightnessDevicePins || {}; - const pinnedDevice = pins[screenName]; - if (pinnedDevice && pinnedDevice.length > 0) { - const found = DisplayService.devices.find(dev => dev.name === pinnedDevice); - if (found) { - return found.name; - } - } - } - - if (deviceName && deviceName.length > 0) { - const found = DisplayService.devices.find(dev => dev.name === deviceName); - if (found) { - return found.name; - } - } - - const currentDeviceName = DisplayService.currentDevice; - if (currentDeviceName) { - const found = DisplayService.devices.find(dev => dev.name === currentDeviceName); - if (found) { - return found.name; - } - } - - const backlight = DisplayService.devices.find(d => d.class === "backlight"); - if (backlight) { - return backlight.name; - } - - const ddc = DisplayService.devices.find(d => d.class === "ddc"); - if (ddc) { - return ddc.name; - } - - return DisplayService.devices.length > 0 ? DisplayService.devices[0].name : ""; - } - - property var targetDevice: { - if (!targetDeviceName || !DisplayService.devices) { - return null; - } - - return DisplayService.devices.find(dev => dev.name === targetDeviceName) || null; - } - - property real targetBrightness: { - DisplayService.brightnessVersion; - if (!targetDeviceName) { - return 0; - } - - return DisplayService.getDeviceBrightness(targetDeviceName); - } - - Rectangle { - width: Theme.iconSize + Theme.spacingS * 2 - height: Theme.iconSize + Theme.spacingS * 2 - anchors.verticalCenter: parent.verticalCenter - radius: (Theme.iconSize + Theme.spacingS * 2) / 2 - color: iconArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : Theme.withAlpha(Theme.primary, 0) - - DankRipple { - id: iconRipple - cornerRadius: parent.radius - } - - MouseArea { - id: iconArea - anchors.fill: parent - hoverEnabled: true - cursorShape: DisplayService.devices && DisplayService.devices.length > 1 ? Qt.PointingHandCursor : Qt.ArrowCursor - - onPressed: mouse => iconRipple.trigger(mouse.x, mouse.y) - onClicked: { - if (DisplayService.devices && DisplayService.devices.length > 1) { - root.iconClicked(); - } - } - - onEntered: { - const tooltipText = targetDevice ? "bl device: " + targetDevice.name : "Backlight Control"; - sharedTooltip.show(tooltipText, iconArea, 0, 0, "bottom"); - } - - onExited: { - sharedTooltip.hide(); - } - - DankIcon { - anchors.centerIn: parent - name: { - if (!DisplayService.brightnessAvailable || !targetDevice) { - return "brightness_low"; - } - - if (targetDevice.class === "backlight" || targetDevice.class === "ddc") { - const brightness = targetBrightness; - if (brightness <= 33) - return "brightness_low"; - if (brightness <= 66) - return "brightness_medium"; - return "brightness_high"; - } else if (targetDevice.name.includes("kbd")) { - return "keyboard"; - } else { - return "lightbulb"; - } - } - size: Theme.iconSize - color: DisplayService.brightnessAvailable && targetDevice && targetBrightness > 0 ? Theme.primary : Theme.surfaceText - } - } - } - - DankSlider { - id: brightnessSlider - - anchors.verticalCenter: parent.verticalCenter - width: parent.width - (Theme.iconSize + Theme.spacingS * 2) - enabled: DisplayService.brightnessAvailable && targetDeviceName.length > 0 - minimum: { - if (!targetDevice) - return 1; - const isExponential = SessionData.getBrightnessExponential(targetDevice.id); - if (isExponential) { - return 1; - } - return (targetDevice.class === "backlight" || targetDevice.class === "ddc") ? 1 : 0; - } - maximum: { - if (!targetDevice) - return 100; - const isExponential = SessionData.getBrightnessExponential(targetDevice.id); - if (isExponential) { - return 100; - } - return targetDevice.displayMax || 100; - } - showValue: true - unit: { - if (!targetDevice) - return "%"; - const isExponential = SessionData.getBrightnessExponential(targetDevice.id); - if (isExponential) { - return "%"; - } - return targetDevice.class === "ddc" ? "" : "%"; - } - onSliderValueChanged: function (newValue) { - if (DisplayService.brightnessAvailable && targetDeviceName) { - DisplayService.setBrightness(newValue, targetDeviceName, true); - } - } - thumbOutlineColor: Theme.surfaceContainer - trackColor: Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency) - - Binding on value { - value: root.targetBrightness - when: !brightnessSlider.isDragging - } - } -} diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Widgets/ColorPickerPill.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Widgets/ColorPickerPill.qml deleted file mode 100644 index a95410b..0000000 --- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Widgets/ColorPickerPill.qml +++ /dev/null @@ -1,29 +0,0 @@ -import QtQuick -import qs.Common -import qs.Modules.ControlCenter.Widgets - -CompoundPill { - id: root - - property var colorPickerModal: null - - isActive: true - iconName: "palette" - iconColor: Theme.primary - primaryText: I18n.tr("Color Picker") - secondaryText: I18n.tr("Choose a color") - - onToggled: { - console.log("ColorPickerPill toggled, modal:", colorPickerModal); - if (colorPickerModal) { - colorPickerModal.show(); - } - } - - onExpandClicked: { - console.log("ColorPickerPill expandClicked, modal:", colorPickerModal); - if (colorPickerModal) { - colorPickerModal.show(); - } - } -} diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Widgets/CompactSlider.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Widgets/CompactSlider.qml deleted file mode 100644 index eeed4c4..0000000 --- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Widgets/CompactSlider.qml +++ /dev/null @@ -1,71 +0,0 @@ -import QtQuick -import qs.Common -import qs.Widgets - -Rectangle { - id: root - - LayoutMirroring.enabled: I18n.isRtl - LayoutMirroring.childrenInherit: true - - property string iconName: "" - property color iconColor: Theme.surfaceText - property string labelText: "" - property real value: 0.0 - property real maximumValue: 1.0 - property real minimumValue: 0.0 - property bool enabled: true - - signal sliderValueChanged(real value) - - width: parent ? parent.width : 200 - height: 60 - radius: Theme.cornerRadius - color: Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency) - border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08) - border.width: 0 - opacity: enabled ? 1.0 : 0.6 - - Row { - anchors.left: parent.left - anchors.verticalCenter: parent.verticalCenter - anchors.leftMargin: Theme.spacingM - anchors.right: sliderContainer.left - anchors.rightMargin: Theme.spacingS - spacing: Theme.spacingS - - DankIcon { - name: root.iconName - size: Theme.iconSize - color: root.iconColor - anchors.verticalCenter: parent.verticalCenter - } - - StyledText { - text: root.labelText - font.pixelSize: Theme.fontSizeMedium - color: Theme.surfaceText - font.weight: Font.Medium - anchors.verticalCenter: parent.verticalCenter - } - } - - Rectangle { - id: sliderContainer - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - anchors.rightMargin: Theme.spacingM - width: 120 - height: parent.height - Theme.spacingS * 2 - - DankSlider { - anchors.centerIn: parent - width: parent.width - enabled: root.enabled - minimum: Math.round(root.minimumValue * 100) - maximum: Math.round(root.maximumValue * 100) - value: Math.round(root.value * 100) - onSliderValueChanged: root.sliderValueChanged(newValue / 100.0) - } - } -} diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Widgets/CompoundPill.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Widgets/CompoundPill.qml deleted file mode 100644 index 9165ec4..0000000 --- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Widgets/CompoundPill.qml +++ /dev/null @@ -1,205 +0,0 @@ -import QtQuick -import qs.Common -import qs.Widgets - -Rectangle { - id: root - - LayoutMirroring.enabled: I18n.isRtl - LayoutMirroring.childrenInherit: true - - property string iconName: "" - property color iconColor: Theme.surfaceText - property string primaryText: "" - property string secondaryText: "" - property bool expanded: false - property bool isActive: false - property bool showExpandArea: true - - signal toggled - signal expandClicked - signal wheelEvent(var wheelEvent) - - width: parent ? parent.width : 220 - height: 60 - radius: Theme.cornerRadius - - function hoverTint(base) { - const factor = 1.2; - return Theme.isLightMode ? Qt.darker(base, factor) : Qt.lighter(base, factor); - } - - readonly property color _containerBg: Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency) - - color: { - const baseColor = bodyMouse.containsMouse ? Theme.primaryPressed : _containerBg; - return baseColor; - } - border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.10) - border.width: 0 - antialiasing: true - - readonly property color _labelPrimary: Theme.surfaceText - readonly property color _labelSecondary: Theme.surfaceVariantText - readonly property color _tileBgActive: Theme.ccTileActiveBg - readonly property color _tileBgInactive: { - const transparency = Theme.popupTransparency; - const surface = Theme.surfaceContainer || Qt.rgba(0.1, 0.1, 0.1, 1); - return Qt.rgba(surface.r, surface.g, surface.b, transparency); - } - readonly property color _tileRingActive: Theme.ccTileRing - readonly property color _tileRingInactive: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.18) - readonly property color _tileIconActive: Theme.ccTileActiveText - readonly property color _tileIconInactive: Theme.ccTileInactiveIcon - - property int _padH: Theme.spacingS - property int _tileSize: 48 - property int _tileRadius: Theme.cornerRadius - - Rectangle { - id: rightHoverOverlay - anchors.fill: parent - radius: root.radius - z: 0 - visible: false - color: hoverTint(_containerBg) - opacity: 0.08 - antialiasing: true - Behavior on opacity { - NumberAnimation { - duration: Theme.shortDuration - } - } - } - - DankRipple { - id: bodyRipple - cornerRadius: root.radius - } - - Row { - id: row - anchors.fill: parent - anchors.leftMargin: _padH - anchors.rightMargin: Theme.spacingM - spacing: Theme.spacingM - - Rectangle { - id: iconTile - z: 1 - width: _tileSize - height: _tileSize - anchors.verticalCenter: parent.verticalCenter - radius: _tileRadius - color: isActive ? _tileBgActive : _tileBgInactive - border.color: isActive ? _tileRingActive : "transparent" - border.width: isActive ? 1 : 0 - antialiasing: true - - Rectangle { - anchors.fill: parent - radius: _tileRadius - color: hoverTint(iconTile.color) - opacity: tileMouse.pressed ? 0.3 : (tileMouse.containsMouse ? 0.2 : 0.0) - visible: opacity > 0 - antialiasing: true - Behavior on opacity { - NumberAnimation { - duration: Theme.shortDuration - } - } - } - - DankIcon { - anchors.centerIn: parent - name: iconName - size: Theme.iconSize - color: isActive ? _tileIconActive : _tileIconInactive - } - - DankRipple { - id: tileRipple - cornerRadius: _tileRadius - } - - MouseArea { - id: tileMouse - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onPressed: mouse => tileRipple.trigger(mouse.x, mouse.y) - onClicked: root.toggled() - } - } - - Item { - id: body - width: row.width - iconTile.width - row.spacing - height: row.height - - Column { - anchors.left: parent.left - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - spacing: 2 - - StyledText { - width: parent.width - text: root.primaryText - color: _labelPrimary - font.pixelSize: Theme.fontSizeMedium - font.weight: Font.Medium - elide: Text.ElideRight - wrapMode: Text.NoWrap - horizontalAlignment: Text.AlignLeft - } - StyledText { - width: parent.width - text: root.secondaryText - color: _labelSecondary - font.pixelSize: Theme.fontSizeSmall - visible: text.length > 0 - elide: Text.ElideRight - wrapMode: Text.NoWrap - horizontalAlignment: Text.AlignLeft - } - } - - MouseArea { - id: bodyMouse - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onEntered: { - rightHoverOverlay.visible = true; - rightHoverOverlay.opacity = 0.08; - } - onExited: { - rightHoverOverlay.opacity = 0.0; - rightHoverOverlay.visible = false; - } - onPressed: mouse => { - const pos = mapToItem(root, mouse.x, mouse.y); - bodyRipple.trigger(pos.x, pos.y); - rightHoverOverlay.opacity = 0.16; - } - onReleased: rightHoverOverlay.opacity = containsMouse ? 0.08 : 0.0 - onClicked: root.expandClicked() - onWheel: function (ev) { - root.wheelEvent(ev); - } - } - } - } - - focus: true - Keys.onPressed: function (ev) { - if (ev.key === Qt.Key_Space || ev.key === Qt.Key_Return) { - root.toggled(); - ev.accepted = true; - } else if (ev.key === Qt.Key_Right) { - root.expandClicked(); - ev.accepted = true; - } - } -} diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Widgets/DetailView.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Widgets/DetailView.qml deleted file mode 100644 index 2d946f3..0000000 --- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Widgets/DetailView.qml +++ /dev/null @@ -1,23 +0,0 @@ -import QtQuick - -Rectangle { - id: root - - property string title: "" - property Component content: null - property bool isVisible: true - property int contentHeight: 300 - - width: parent ? parent.width : 400 - implicitHeight: isVisible ? contentHeight : 0 - height: implicitHeight - color: "transparent" - clip: true - - Loader { - id: contentLoader - anchors.fill: parent - sourceComponent: root.content - asynchronous: true - } -} diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Widgets/DiskUsagePill.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Widgets/DiskUsagePill.qml deleted file mode 100644 index 827df4e..0000000 --- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Widgets/DiskUsagePill.qml +++ /dev/null @@ -1,76 +0,0 @@ -import QtQuick -import qs.Common -import qs.Services -import qs.Modules.ControlCenter.Widgets - -CompoundPill { - id: root - - property string mountPath: "/" - property string instanceId: "" - - iconName: "storage" - - property var selectedMount: { - if (!DgopService.diskMounts || DgopService.diskMounts.length === 0) { - return null; - } - - const targetMount = DgopService.diskMounts.find(mount => mount.mount === mountPath); - return targetMount || DgopService.diskMounts.find(mount => mount.mount === "/") || DgopService.diskMounts[0]; - } - - property real usagePercent: { - if (!selectedMount || !selectedMount.percent) { - return 0; - } - const percentStr = selectedMount.percent.replace("%", ""); - return parseFloat(percentStr) || 0; - } - - isActive: DgopService.dgopAvailable && selectedMount !== null - - primaryText: { - if (!DgopService.dgopAvailable) { - return I18n.tr("Disk Usage"); - } - if (!selectedMount) { - return I18n.tr("No disk data"); - } - return selectedMount.mount; - } - - secondaryText: { - if (!DgopService.dgopAvailable) { - return I18n.tr("dgop not available"); - } - if (!selectedMount) { - return I18n.tr("No disk data available"); - } - return `${selectedMount.used} / ${selectedMount.size} (${usagePercent.toFixed(0)}%)`; - } - - iconColor: { - if (!DgopService.dgopAvailable || !selectedMount) { - return Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.5); - } - if (usagePercent > 90) { - return Theme.error; - } - if (usagePercent > 75) { - return Theme.warning; - } - return Theme.surfaceText; - } - - Component.onCompleted: { - DgopService.addRef(["diskmounts"]); - } - Component.onDestruction: { - DgopService.removeRef(["diskmounts"]); - } - - onToggled: { - expandClicked(); - } -} diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Widgets/ErrorPill.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Widgets/ErrorPill.qml deleted file mode 100644 index cece467..0000000 --- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Widgets/ErrorPill.qml +++ /dev/null @@ -1,56 +0,0 @@ -import QtQuick -import qs.Common -import qs.Widgets - -StyledRect { - id: root - - LayoutMirroring.enabled: I18n.isRtl - LayoutMirroring.childrenInherit: true - - property string primaryMessage: "" - property string secondaryMessage: "" - - radius: Theme.cornerRadius - color: Qt.rgba(Theme.warning.r, Theme.warning.g, Theme.warning.b, 0.1) - border.color: Theme.warning - border.width: 1 - - Row { - anchors.fill: parent - anchors.margins: Theme.spacingM - spacing: Theme.spacingXS - - DankIcon { - name: "warning" - size: 16 - color: Theme.warning - anchors.top: parent.top - anchors.topMargin: 2 - } - - Column { - width: parent.width - 16 - parent.spacing - spacing: Theme.spacingXS - - StyledText { - width: parent.width - text: root.primaryMessage - font.pixelSize: Theme.fontSizeSmall - color: Theme.warning - font.weight: Font.Medium - wrapMode: Text.WordWrap - horizontalAlignment: Text.AlignLeft - } - - StyledText { - width: parent.width - text: root.secondaryMessage - font.pixelSize: Theme.fontSizeSmall - color: Theme.warning - visible: text.length > 0 - horizontalAlignment: Text.AlignLeft - } - } - } -} diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Widgets/InputAudioSliderRow.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Widgets/InputAudioSliderRow.qml deleted file mode 100644 index 49ea30e..0000000 --- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Widgets/InputAudioSliderRow.qml +++ /dev/null @@ -1,87 +0,0 @@ -import QtQuick -import qs.Common -import qs.Services -import qs.Widgets - -Row { - id: root - - LayoutMirroring.enabled: I18n.isRtl - LayoutMirroring.childrenInherit: true - - property var defaultSource: AudioService.source - property color sliderTrackColor: "transparent" - - height: 40 - spacing: 0 - - Rectangle { - width: Theme.iconSize + Theme.spacingS * 2 - height: Theme.iconSize + Theme.spacingS * 2 - anchors.verticalCenter: parent.verticalCenter - radius: (Theme.iconSize + Theme.spacingS * 2) / 2 - color: iconArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : Theme.withAlpha(Theme.primary, 0) - - DankRipple { - id: iconRipple - cornerRadius: parent.radius - } - - MouseArea { - id: iconArea - anchors.fill: parent - visible: defaultSource !== null - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onPressed: mouse => iconRipple.trigger(mouse.x, mouse.y) - onClicked: { - if (defaultSource) { - SessionData.suppressOSDTemporarily(); - defaultSource.audio.muted = !defaultSource.audio.muted; - } - } - } - - DankIcon { - anchors.centerIn: parent - name: { - if (!defaultSource) - return "mic_off"; - - let volume = defaultSource.audio.volume; - let muted = defaultSource.audio.muted; - - if (muted || volume === 0.0) - return "mic_off"; - return "mic"; - } - size: Theme.iconSize - color: defaultSource && !defaultSource.audio.muted && defaultSource.audio.volume > 0 ? Theme.primary : Theme.surfaceText - } - } - - DankSlider { - readonly property real actualVolumePercent: defaultSource ? Math.round(defaultSource.audio.volume * 100) : 0 - - anchors.verticalCenter: parent.verticalCenter - width: parent.width - (Theme.iconSize + Theme.spacingS * 2) - enabled: defaultSource !== null - minimum: 0 - maximum: 100 - value: defaultSource ? Math.min(100, Math.round(defaultSource.audio.volume * 100)) : 0 - showValue: true - unit: "%" - valueOverride: actualVolumePercent - thumbOutlineColor: Theme.surfaceContainer - trackColor: root.sliderTrackColor.a > 0 ? root.sliderTrackColor : Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency) - onSliderValueChanged: function (newValue) { - if (defaultSource) { - SessionData.suppressOSDTemporarily(); - defaultSource.audio.volume = newValue / 100.0; - if (newValue > 0 && defaultSource.audio.muted) { - defaultSource.audio.muted = false; - } - } - } - } -} diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Widgets/SmallBatteryButton.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Widgets/SmallBatteryButton.qml deleted file mode 100644 index 02da286..0000000 --- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Widgets/SmallBatteryButton.qml +++ /dev/null @@ -1,113 +0,0 @@ -import QtQuick -import qs.Common -import qs.Services -import qs.Widgets - -Rectangle { - id: root - - LayoutMirroring.enabled: I18n.isRtl - LayoutMirroring.childrenInherit: true - - property bool isActive: BatteryService.batteryAvailable && (BatteryService.isCharging || BatteryService.isPluggedIn) - property bool enabled: BatteryService.batteryAvailable - - signal clicked - - width: parent ? ((parent.width - parent.spacing * 3) / 4) : 48 - height: 48 - radius: { - if (Theme.cornerRadius === 0) - return 0; - return isActive ? Theme.cornerRadius : Theme.cornerRadius + 4; - } - - function hoverTint(base) { - const factor = 1.2; - return Theme.isLightMode ? Qt.darker(base, factor) : Qt.lighter(base, factor); - } - - readonly property color _tileBgActive: Theme.ccTileActiveBg - readonly property color _tileBgInactive: Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency) - readonly property color _tileRingActive: Theme.ccTileRing - readonly property color _tileIconActive: Theme.ccTileActiveText - readonly property color _tileIconInactive: Theme.ccTileInactiveIcon - - color: { - if (isActive) - return _tileBgActive; - const baseColor = mouseArea.containsMouse ? Theme.primaryPressed : _tileBgInactive; - return baseColor; - } - border.color: isActive ? _tileRingActive : "transparent" - border.width: isActive ? 1 : 0 - antialiasing: true - opacity: enabled ? 1.0 : 0.6 - - Rectangle { - anchors.fill: parent - radius: parent.radius - color: hoverTint(root.color) - opacity: mouseArea.pressed ? 0.3 : (mouseArea.containsMouse ? 0.2 : 0.0) - visible: opacity > 0 - antialiasing: true - Behavior on opacity { - NumberAnimation { - duration: Theme.shortDuration - } - } - } - - Row { - anchors.centerIn: parent - spacing: 4 - - DankIcon { - name: BatteryService.getBatteryIcon() - size: parent.parent.width * 0.25 - color: { - if (BatteryService.isLowBattery && !BatteryService.isCharging) { - return Theme.error; - } - return isActive ? _tileIconActive : _tileIconInactive; - } - anchors.verticalCenter: parent.verticalCenter - } - - StyledText { - text: BatteryService.batteryAvailable ? `${BatteryService.batteryLevel}%` : "" - font.pixelSize: parent.parent.width * 0.15 - font.weight: Font.Medium - color: { - if (BatteryService.isLowBattery && !BatteryService.isCharging) { - return Theme.error; - } - return isActive ? _tileIconActive : _tileIconInactive; - } - anchors.verticalCenter: parent.verticalCenter - visible: BatteryService.batteryAvailable - } - } - - DankRipple { - id: ripple - cornerRadius: root.radius - } - - MouseArea { - id: mouseArea - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - enabled: root.enabled - onPressed: mouse => ripple.trigger(mouse.x, mouse.y) - onClicked: root.clicked() - } - - Behavior on radius { - NumberAnimation { - duration: Theme.shortDuration - easing.type: Theme.standardEasing - } - } -} diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Widgets/SmallDiskUsageButton.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Widgets/SmallDiskUsageButton.qml deleted file mode 100644 index 30c4e36..0000000 --- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Widgets/SmallDiskUsageButton.qml +++ /dev/null @@ -1,129 +0,0 @@ -import QtQuick -import qs.Common -import qs.Services -import qs.Widgets - -Rectangle { - id: root - - LayoutMirroring.enabled: I18n.isRtl - LayoutMirroring.childrenInherit: true - - property string mountPath: "/" - property string instanceId: "" - - property var selectedMount: { - if (!DgopService.diskMounts || DgopService.diskMounts.length === 0) - return null; - const targetMount = DgopService.diskMounts.find(mount => mount.mount === mountPath); - return targetMount || DgopService.diskMounts.find(mount => mount.mount === "/") || DgopService.diskMounts[0]; - } - - property real usagePercent: { - if (!selectedMount?.percent) - return 0; - return parseFloat(selectedMount.percent.replace("%", "")) || 0; - } - - property bool enabled: DgopService.dgopAvailable - - signal clicked - - width: parent ? ((parent.width - parent.spacing * 3) / 4) : 48 - height: 48 - radius: Theme.cornerRadius + 4 - - function hoverTint(base) { - const factor = 1.2; - return Theme.isLightMode ? Qt.darker(base, factor) : Qt.lighter(base, factor); - } - - readonly property color _tileBg: Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency) - - color: mouseArea.containsMouse ? Theme.primaryPressed : _tileBg - border.color: "transparent" - border.width: 0 - antialiasing: true - opacity: enabled ? 1.0 : 0.6 - - Rectangle { - anchors.fill: parent - radius: parent.radius - color: hoverTint(root.color) - opacity: mouseArea.pressed ? 0.3 : (mouseArea.containsMouse ? 0.2 : 0.0) - visible: opacity > 0 - antialiasing: true - Behavior on opacity { - NumberAnimation { - duration: Theme.shortDuration - } - } - } - - Row { - anchors.centerIn: parent - spacing: Theme.spacingXS - - DankIcon { - anchors.verticalCenter: parent.verticalCenter - name: "storage" - size: Theme.iconSizeSmall - color: { - if (root.usagePercent > 90) - return Theme.error; - if (root.usagePercent > 75) - return Theme.warning; - return Theme.ccTileInactiveIcon; - } - } - - Column { - anchors.verticalCenter: parent.verticalCenter - spacing: 0 - - StyledText { - text: root.selectedMount?.mount || root.mountPath - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceVariantText - elide: Text.ElideMiddle - width: Math.min(implicitWidth, root.width - Theme.iconSizeSmall - Theme.spacingM) - horizontalAlignment: Text.AlignLeft - } - - StyledText { - text: `${root.usagePercent.toFixed(0)}%` - font.pixelSize: Theme.fontSizeSmall - font.weight: Font.Bold - color: { - if (root.usagePercent > 90) - return Theme.error; - if (root.usagePercent > 75) - return Theme.warning; - return Theme.ccTileInactiveIcon; - } - } - } - } - - DankRipple { - id: ripple - cornerRadius: root.radius - } - - MouseArea { - id: mouseArea - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - enabled: root.enabled - onPressed: mouse => ripple.trigger(mouse.x, mouse.y) - onClicked: root.clicked() - } - - Component.onCompleted: { - DgopService.addRef(["diskmounts"]); - } - Component.onDestruction: { - DgopService.removeRef(["diskmounts"]); - } -} diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Widgets/SmallToggleButton.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Widgets/SmallToggleButton.qml deleted file mode 100644 index 7d86947..0000000 --- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Widgets/SmallToggleButton.qml +++ /dev/null @@ -1,90 +0,0 @@ -import QtQuick -import qs.Common -import qs.Widgets - -Rectangle { - id: root - - property string iconName: "" - property bool isActive: false - property bool enabled: true - property real iconRotation: 0 - - signal clicked - signal iconRotationCompleted - - width: parent ? ((parent.width - parent.spacing * 3) / 4) : 48 - height: 48 - radius: { - if (Theme.cornerRadius === 0) - return 0; - return isActive ? Theme.cornerRadius : Theme.cornerRadius + 4; - } - - function hoverTint(base) { - const factor = 1.2; - return Theme.isLightMode ? Qt.darker(base, factor) : Qt.lighter(base, factor); - } - - readonly property color _tileBgActive: Theme.ccTileActiveBg - readonly property color _tileBgInactive: Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency) - readonly property color _tileRingActive: Theme.ccTileRing - readonly property color _tileIconActive: Theme.ccTileActiveText - readonly property color _tileIconInactive: Theme.ccTileInactiveIcon - - color: { - if (isActive) - return _tileBgActive; - const baseColor = mouseArea.containsMouse ? Theme.primaryPressed : _tileBgInactive; - return baseColor; - } - border.color: isActive ? _tileRingActive : "transparent" - border.width: isActive ? 1 : 0 - antialiasing: true - opacity: enabled ? 1.0 : 0.6 - - Rectangle { - anchors.fill: parent - radius: parent.radius - color: hoverTint(root.color) - opacity: mouseArea.pressed ? 0.3 : (mouseArea.containsMouse ? 0.2 : 0.0) - visible: opacity > 0 - antialiasing: true - Behavior on opacity { - NumberAnimation { - duration: Theme.shortDuration - } - } - } - - DankIcon { - anchors.centerIn: parent - name: iconName - size: Theme.iconSize - color: isActive ? _tileIconActive : _tileIconInactive - rotation: iconRotation - onRotationCompleted: root.iconRotationCompleted() - } - - DankRipple { - id: ripple - cornerRadius: root.radius - } - - MouseArea { - id: mouseArea - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - enabled: root.enabled - onPressed: mouse => ripple.trigger(mouse.x, mouse.y) - onClicked: root.clicked() - } - - Behavior on radius { - NumberAnimation { - duration: Theme.shortDuration - easing.type: Theme.standardEasing - } - } -} diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Widgets/ToggleButton.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Widgets/ToggleButton.qml deleted file mode 100644 index b8adda8..0000000 --- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Widgets/ToggleButton.qml +++ /dev/null @@ -1,134 +0,0 @@ -import QtQuick -import qs.Common -import qs.Widgets - -Rectangle { - id: root - - LayoutMirroring.enabled: I18n.isRtl - LayoutMirroring.childrenInherit: true - - property string iconName: "" - property string text: "" - property bool isActive: false - property bool enabled: true - property string secondaryText: "" - property real iconRotation: 0 - - signal clicked - signal iconRotationCompleted - - width: parent ? parent.width : 200 - height: 60 - radius: { - if (Theme.cornerRadius === 0) - return 0; - return isActive ? Theme.cornerRadius : Theme.cornerRadius + 4; - } - - readonly property color _tileBgActive: Theme.ccTileActiveBg - readonly property color _tileBgInactive: Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency) - readonly property color _tileRingActive: Theme.ccTileRing - - color: { - if (isActive) - return _tileBgActive; - const baseColor = mouseArea.containsMouse ? Theme.primaryPressed : _tileBgInactive; - return baseColor; - } - border.color: isActive ? _tileRingActive : Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08) - border.width: 0 - opacity: enabled ? 1.0 : 0.6 - - function hoverTint(base) { - const factor = 1.2; - return Theme.isLightMode ? Qt.darker(base, factor) : Qt.lighter(base, factor); - } - - readonly property color _containerBg: Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency) - - Rectangle { - anchors.fill: parent - radius: Theme.cornerRadius - color: mouseArea.containsMouse ? hoverTint(_containerBg) : Theme.withAlpha(_containerBg, 0) - opacity: mouseArea.containsMouse ? 0.08 : 0.0 - - Behavior on opacity { - NumberAnimation { - duration: Theme.shortDuration - } - } - } - - Row { - anchors.fill: parent - anchors.leftMargin: Theme.spacingL + 2 - anchors.rightMargin: Theme.spacingM - spacing: Theme.spacingM - - DankIcon { - name: root.iconName - size: Theme.iconSize - color: isActive ? Theme.ccTileActiveText : Theme.ccTileInactiveIcon - anchors.verticalCenter: parent.verticalCenter - rotation: root.iconRotation - onRotationCompleted: root.iconRotationCompleted() - } - - Item { - width: parent.width - Theme.iconSize - parent.spacing - height: parent.height - - Column { - anchors.left: parent.left - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - spacing: 2 - - StyledText { - width: parent.width - text: root.text - font.pixelSize: Theme.fontSizeMedium - color: isActive ? Theme.ccTileActiveText : Theme.surfaceText - font.weight: Font.Medium - elide: Text.ElideRight - wrapMode: Text.NoWrap - horizontalAlignment: Text.AlignLeft - } - - StyledText { - width: parent.width - text: root.secondaryText - font.pixelSize: Theme.fontSizeSmall - color: isActive ? Theme.ccTileActiveText : Theme.surfaceVariantText - visible: text.length > 0 - elide: Text.ElideRight - wrapMode: Text.NoWrap - horizontalAlignment: Text.AlignLeft - } - } - } - } - - DankRipple { - id: ripple - cornerRadius: root.radius - } - - MouseArea { - id: mouseArea - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - enabled: root.enabled - onPressed: mouse => ripple.trigger(mouse.x, mouse.y) - onClicked: root.clicked() - } - - Behavior on radius { - NumberAnimation { - duration: Theme.shortDuration - easing.type: Theme.standardEasing - } - } -} diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/utils/layout.js b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/utils/layout.js deleted file mode 100644 index b8e5651..0000000 --- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/utils/layout.js +++ /dev/null @@ -1,45 +0,0 @@ -function calculateRowsAndWidgets(controlCenterColumn, expandedSection, expandedWidgetIndex) { - var rows = [] - var currentRow = [] - var currentWidth = 0 - var expandedRow = -1 - - const widgets = SettingsData.controlCenterWidgets || [] - const baseWidth = controlCenterColumn.width - const spacing = Theme.spacingS - - for (var i = 0; i < widgets.length; i++) { - const widget = widgets[i] - const widgetWidth = widget.width || 50 - - var itemWidth - if (widgetWidth <= 25) { - itemWidth = (baseWidth - spacing * 3) / 4 - } else if (widgetWidth <= 50) { - itemWidth = (baseWidth - spacing) / 2 - } else if (widgetWidth <= 75) { - itemWidth = (baseWidth - spacing * 2) * 0.75 - } else { - itemWidth = baseWidth - } - - if (currentRow.length > 0 && (currentWidth + spacing + itemWidth > baseWidth)) { - rows.push([...currentRow]) - currentRow = [widget] - currentWidth = itemWidth - } else { - currentRow.push(widget) - currentWidth += (currentRow.length > 1 ? spacing : 0) + itemWidth - } - - if (expandedWidgetIndex === i) { - expandedRow = rows.length - } - } - - if (currentRow.length > 0) { - rows.push(currentRow) - } - - return { rows: rows, expandedRowIndex: expandedRow } -} diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/utils/state.js b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/utils/state.js deleted file mode 100644 index a2d59a6..0000000 --- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/utils/state.js +++ /dev/null @@ -1,17 +0,0 @@ -function openWithSection(root, section) { - if (root.shouldBeVisible) { - root.close(); - } else { - root.expandedSection = section; - root.open(); - } -} - -function toggleSection(root, section) { - if (root.expandedSection === section) { - root.expandedSection = ""; - root.expandedWidgetIndex = -1; - } else { - root.expandedSection = section; - } -} diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/utils/widgets.js b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/utils/widgets.js deleted file mode 100644 index 3e11d88..0000000 --- a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/utils/widgets.js +++ /dev/null @@ -1,90 +0,0 @@ -function getWidgetForId(baseWidgetDefinitions, widgetId) { - return baseWidgetDefinitions.find(w => w.id === widgetId) -} - -function addWidget(widgetId) { - var widgets = SettingsData.controlCenterWidgets.slice() - var widget = { - "id": widgetId, - "enabled": true, - "width": 50 - } - - if (widgetId === "diskUsage") { - widget.instanceId = generateUniqueId() - widget.mountPath = "/" - } - - if (widgetId === "brightnessSlider") { - widget.instanceId = generateUniqueId() - widget.deviceName = "" - } - - widgets.push(widget) - SettingsData.set("controlCenterWidgets", widgets) -} - -function generateUniqueId() { - return Date.now().toString(36) + Math.random().toString(36).substr(2) -} - -function removeWidget(index) { - var widgets = SettingsData.controlCenterWidgets.slice() - if (index >= 0 && index < widgets.length) { - widgets.splice(index, 1) - SettingsData.set("controlCenterWidgets", widgets) - } -} - -function toggleWidgetSize(index) { - var widgets = SettingsData.controlCenterWidgets.slice() - if (index >= 0 && index < widgets.length) { - const currentWidth = widgets[index].width || 50 - const id = widgets[index].id || "" - - if (id === "wifi" || id === "bluetooth" || id === "audioOutput" || id === "audioInput") { - widgets[index].width = currentWidth <= 50 ? 100 : 50 - } else { - if (currentWidth <= 25) { - widgets[index].width = 50 - } else if (currentWidth <= 50) { - widgets[index].width = 100 - } else { - widgets[index].width = 25 - } - } - - SettingsData.set("controlCenterWidgets", widgets) - } -} - -function reorderWidgets(newOrder) { - SettingsData.set("controlCenterWidgets", newOrder) -} - -function moveWidget(fromIndex, toIndex) { - let widgets = [...(SettingsData.controlCenterWidgets || [])] - if (fromIndex >= 0 && fromIndex < widgets.length && toIndex >= 0 && toIndex < widgets.length) { - const movedWidget = widgets.splice(fromIndex, 1)[0] - widgets.splice(toIndex, 0, movedWidget) - SettingsData.set("controlCenterWidgets", widgets) - } -} - -function resetToDefault() { - const defaultWidgets = [ - {"id": "volumeSlider", "enabled": true, "width": 50}, - {"id": "brightnessSlider", "enabled": true, "width": 50}, - {"id": "wifi", "enabled": true, "width": 50}, - {"id": "bluetooth", "enabled": true, "width": 50}, - {"id": "audioOutput", "enabled": true, "width": 50}, - {"id": "audioInput", "enabled": true, "width": 50}, - {"id": "nightMode", "enabled": true, "width": 50}, - {"id": "darkMode", "enabled": true, "width": 50} - ] - SettingsData.set("controlCenterWidgets", defaultWidgets) -} - -function clearAll() { - SettingsData.set("controlCenterWidgets", []) -} |