mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-01-25 14:02:53 -05:00
dankbar/controlcenter: add VPN, mic, brightness, battery, and printer
options for widget
This commit is contained in:
@@ -2,7 +2,6 @@ import QtQuick
|
||||
import qs.Common
|
||||
import qs.Services
|
||||
import qs.Modules.ControlCenter.Details
|
||||
import qs.Modules.ControlCenter.Models
|
||||
|
||||
Item {
|
||||
id: root
|
||||
@@ -11,17 +10,21 @@ Item {
|
||||
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
|
||||
|
||||
function getDetailHeight(section) {
|
||||
const maxAvailable = parent ? parent.height - Theme.spacingS : 9999
|
||||
if (section === "wifi") return Math.min(350, maxAvailable)
|
||||
if (section === "bluetooth") return Math.min(350, maxAvailable)
|
||||
if (section.startsWith("brightnessSlider_")) return Math.min(400, maxAvailable)
|
||||
return Math.min(250, maxAvailable)
|
||||
const maxAvailable = parent ? parent.height - Theme.spacingS : 9999;
|
||||
if (section === "wifi")
|
||||
return Math.min(350, maxAvailable);
|
||||
if (section === "bluetooth")
|
||||
return Math.min(350, maxAvailable);
|
||||
if (section.startsWith("brightnessSlider_"))
|
||||
return Math.min(400, maxAvailable);
|
||||
return Math.min(250, maxAvailable);
|
||||
}
|
||||
|
||||
Loader {
|
||||
@@ -49,18 +52,18 @@ Item {
|
||||
|
||||
function onDeviceNameChanged(newDeviceName) {
|
||||
if (root.expandedWidgetData && root.expandedWidgetData.id === "brightnessSlider") {
|
||||
const widgets = SettingsData.controlCenterWidgets || []
|
||||
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
|
||||
const updatedWidget = Object.assign({}, w);
|
||||
updatedWidget.deviceName = newDeviceName;
|
||||
return updatedWidget;
|
||||
}
|
||||
return w
|
||||
})
|
||||
SettingsData.set("controlCenterWidgets", newWidgets)
|
||||
return w;
|
||||
});
|
||||
SettingsData.set("controlCenterWidgets", newWidgets);
|
||||
if (root.collapseCallback) {
|
||||
root.collapseCallback()
|
||||
root.collapseCallback();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -73,18 +76,18 @@ Item {
|
||||
|
||||
function onMountPathChanged(newMountPath) {
|
||||
if (root.expandedWidgetData && root.expandedWidgetData.id === "diskUsage") {
|
||||
const widgets = SettingsData.controlCenterWidgets || []
|
||||
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
|
||||
const updatedWidget = Object.assign({}, w);
|
||||
updatedWidget.mountPath = newMountPath;
|
||||
return updatedWidget;
|
||||
}
|
||||
return w
|
||||
})
|
||||
SettingsData.set("controlCenterWidgets", newWidgets)
|
||||
return w;
|
||||
});
|
||||
SettingsData.set("controlCenterWidgets", newWidgets);
|
||||
if (root.collapseCallback) {
|
||||
root.collapseCallback()
|
||||
root.collapseCallback();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -92,86 +95,97 @@ Item {
|
||||
|
||||
onExpandedSectionChanged: {
|
||||
if (pluginDetailInstance) {
|
||||
pluginDetailInstance.destroy()
|
||||
pluginDetailInstance = null
|
||||
pluginDetailInstance.destroy();
|
||||
pluginDetailInstance = null;
|
||||
}
|
||||
pluginDetailLoader.active = false
|
||||
coreDetailLoader.active = false
|
||||
pluginDetailLoader.active = false;
|
||||
coreDetailLoader.active = false;
|
||||
|
||||
if (!root.expandedSection) {
|
||||
return
|
||||
return;
|
||||
}
|
||||
|
||||
if (root.expandedSection.startsWith("builtin_")) {
|
||||
const builtinId = root.expandedSection
|
||||
let builtinInstance = null
|
||||
const builtinId = root.expandedSection;
|
||||
let builtinInstance = null;
|
||||
|
||||
if (builtinId === "builtin_vpn") {
|
||||
if (widgetModel?.vpnLoader) {
|
||||
widgetModel.vpnLoader.active = true
|
||||
widgetModel.vpnLoader.active = true;
|
||||
}
|
||||
builtinInstance = widgetModel.vpnBuiltinInstance
|
||||
builtinInstance = widgetModel.vpnBuiltinInstance;
|
||||
}
|
||||
if (builtinId === "builtin_cups") {
|
||||
if (widgetModel?.cupsLoader) {
|
||||
widgetModel.cupsLoader.active = true
|
||||
widgetModel.cupsLoader.active = true;
|
||||
}
|
||||
builtinInstance = widgetModel.cupsBuiltinInstance
|
||||
builtinInstance = widgetModel.cupsBuiltinInstance;
|
||||
}
|
||||
|
||||
if (!builtinInstance || !builtinInstance.ccDetailContent) {
|
||||
return
|
||||
return;
|
||||
}
|
||||
|
||||
pluginDetailLoader.sourceComponent = builtinInstance.ccDetailContent
|
||||
pluginDetailLoader.active = parent.height > 0
|
||||
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]
|
||||
const pluginId = root.expandedSection.replace("plugin_", "");
|
||||
const pluginComponent = PluginService.pluginWidgetComponents[pluginId];
|
||||
if (!pluginComponent) {
|
||||
return
|
||||
return;
|
||||
}
|
||||
|
||||
pluginDetailInstance = pluginComponent.createObject(null)
|
||||
pluginDetailInstance = pluginComponent.createObject(null);
|
||||
if (!pluginDetailInstance || !pluginDetailInstance.ccDetailContent) {
|
||||
if (pluginDetailInstance) {
|
||||
pluginDetailInstance.destroy()
|
||||
pluginDetailInstance = null
|
||||
pluginDetailInstance.destroy();
|
||||
pluginDetailInstance = null;
|
||||
}
|
||||
return
|
||||
return;
|
||||
}
|
||||
|
||||
pluginDetailLoader.sourceComponent = pluginDetailInstance.ccDetailContent
|
||||
pluginDetailLoader.active = parent.height > 0
|
||||
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
|
||||
coreDetailLoader.sourceComponent = diskUsageDetailComponent;
|
||||
coreDetailLoader.active = parent.height > 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (root.expandedSection.startsWith("brightnessSlider_")) {
|
||||
coreDetailLoader.sourceComponent = brightnessDetailComponent
|
||||
coreDetailLoader.active = parent.height > 0
|
||||
return
|
||||
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
|
||||
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
|
||||
coreDetailLoader.active = parent.height > 0;
|
||||
}
|
||||
|
||||
Component {
|
||||
@@ -183,12 +197,12 @@ Item {
|
||||
id: bluetoothDetailComponent
|
||||
BluetoothDetail {
|
||||
id: bluetoothDetail
|
||||
onShowCodecSelector: function(device) {
|
||||
onShowCodecSelector: function (device) {
|
||||
if (root.bluetoothCodecSelector) {
|
||||
root.bluetoothCodecSelector.show(device)
|
||||
root.bluetoothCodecSelector.codecSelected.connect(function(deviceAddress, codecName) {
|
||||
bluetoothDetail.updateDeviceCodecDisplay(deviceAddress, codecName)
|
||||
})
|
||||
root.bluetoothCodecSelector.show(device);
|
||||
root.bluetoothCodecSelector.codecSelected.connect(function (deviceAddress, codecName) {
|
||||
bluetoothDetail.updateDeviceCodecDisplay(deviceAddress, codecName);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -223,6 +237,7 @@ Item {
|
||||
initialDeviceName: root.expandedWidgetData?.deviceName || ""
|
||||
instanceId: root.expandedWidgetData?.instanceId || ""
|
||||
screenName: root.screenName
|
||||
screenModel: root.screenModel
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -82,6 +82,7 @@ DankPopout {
|
||||
|
||||
onShouldBeVisibleChanged: {
|
||||
if (shouldBeVisible) {
|
||||
collapseAll();
|
||||
Qt.callLater(() => {
|
||||
if (NetworkService.activeService) {
|
||||
NetworkService.activeService.autoRefreshEnabled = NetworkService.wifiEnabled;
|
||||
@@ -179,6 +180,7 @@ DankPopout {
|
||||
bluetoothCodecSelector: bluetoothCodecSelector
|
||||
colorPickerModal: root.colorPickerModal
|
||||
screenName: root.triggerScreen?.name || ""
|
||||
screenModel: root.triggerScreen?.model || ""
|
||||
parentScreen: root.triggerScreen
|
||||
onExpandClicked: (widgetData, globalIndex) => {
|
||||
root.expandedWidgetIndex = globalIndex;
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import Quickshell
|
||||
import Quickshell.Services.Pipewire
|
||||
import qs.Common
|
||||
@@ -10,8 +9,8 @@ Rectangle {
|
||||
id: root
|
||||
|
||||
property bool hasInputVolumeSliderInCC: {
|
||||
const widgets = SettingsData.controlCenterWidgets || []
|
||||
return widgets.some(widget => widget.id === "inputVolumeSlider")
|
||||
const widgets = SettingsData.controlCenterWidgets || [];
|
||||
return widgets.some(widget => widget.id === "inputVolumeSlider");
|
||||
}
|
||||
|
||||
implicitHeight: headerRow.height + (hasInputVolumeSliderInCC ? 0 : volumeSlider.height) + audioContent.height + Theme.spacingM
|
||||
@@ -66,7 +65,7 @@ Rectangle {
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
if (AudioService.source && AudioService.source.audio) {
|
||||
AudioService.source.audio.muted = !AudioService.source.audio.muted
|
||||
AudioService.source.audio.muted = !AudioService.source.audio.muted;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -74,9 +73,10 @@ Rectangle {
|
||||
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"
|
||||
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
|
||||
@@ -97,11 +97,11 @@ Rectangle {
|
||||
valueOverride: actualVolumePercent
|
||||
thumbOutlineColor: Theme.surfaceVariant
|
||||
|
||||
onSliderValueChanged: function(newValue) {
|
||||
onSliderValueChanged: function (newValue) {
|
||||
if (AudioService.source && AudioService.source.audio) {
|
||||
AudioService.source.audio.volume = newValue / 100
|
||||
AudioService.source.audio.volume = newValue / 100;
|
||||
if (newValue > 0 && AudioService.source.audio.muted) {
|
||||
AudioService.source.audio.muted = false
|
||||
AudioService.source.audio.muted = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -128,22 +128,26 @@ Rectangle {
|
||||
model: ScriptModel {
|
||||
values: {
|
||||
const nodes = Pipewire.nodes.values.filter(node => {
|
||||
return node.audio && !node.isSink && !node.isStream
|
||||
})
|
||||
const pins = SettingsData.audioInputDevicePins || {}
|
||||
const pinnedName = pins["preferredInput"]
|
||||
|
||||
let sorted = [...nodes]
|
||||
return node.audio && !node.isSink && !node.isStream;
|
||||
});
|
||||
const pins = SettingsData.audioInputDevicePins || {};
|
||||
const pinnedName = pins["preferredInput"];
|
||||
|
||||
let sorted = [...nodes];
|
||||
sorted.sort((a, b) => {
|
||||
// Pinned device first
|
||||
if (a.name === pinnedName && b.name !== pinnedName) return -1
|
||||
if (b.name === pinnedName && a.name !== pinnedName) return 1
|
||||
if (a.name === pinnedName && b.name !== pinnedName)
|
||||
return -1;
|
||||
if (b.name === pinnedName && a.name !== pinnedName)
|
||||
return 1;
|
||||
// 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
|
||||
if (a === AudioService.source && b !== AudioService.source)
|
||||
return -1;
|
||||
if (b === AudioService.source && a !== AudioService.source)
|
||||
return 1;
|
||||
return 0;
|
||||
});
|
||||
return sorted;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -167,11 +171,11 @@ Rectangle {
|
||||
DankIcon {
|
||||
name: {
|
||||
if (modelData.name.includes("bluez"))
|
||||
return "headset"
|
||||
return "headset";
|
||||
else if (modelData.name.includes("usb"))
|
||||
return "headset"
|
||||
return "headset";
|
||||
else
|
||||
return "mic"
|
||||
return "mic";
|
||||
}
|
||||
size: Theme.iconSize - 4
|
||||
color: modelData === AudioService.source ? Theme.primary : Theme.surfaceText
|
||||
@@ -181,9 +185,9 @@ Rectangle {
|
||||
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
|
||||
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 {
|
||||
@@ -215,8 +219,8 @@ Rectangle {
|
||||
height: 28
|
||||
radius: height / 2
|
||||
color: {
|
||||
const isThisDevicePinned = (SettingsData.audioInputDevicePins || {})["preferredInput"] === modelData.name
|
||||
return isThisDevicePinned ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : Theme.withAlpha(Theme.surfaceText, 0.05)
|
||||
const isThisDevicePinned = (SettingsData.audioInputDevicePins || {})["preferredInput"] === modelData.name;
|
||||
return isThisDevicePinned ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : Theme.withAlpha(Theme.surfaceText, 0.05);
|
||||
}
|
||||
|
||||
Row {
|
||||
@@ -228,21 +232,21 @@ Rectangle {
|
||||
name: "push_pin"
|
||||
size: 16
|
||||
color: {
|
||||
const isThisDevicePinned = (SettingsData.audioInputDevicePins || {})["preferredInput"] === modelData.name
|
||||
return isThisDevicePinned ? Theme.primary : Theme.surfaceText
|
||||
const isThisDevicePinned = (SettingsData.audioInputDevicePins || {})["preferredInput"] === modelData.name;
|
||||
return isThisDevicePinned ? Theme.primary : Theme.surfaceText;
|
||||
}
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
StyledText {
|
||||
text: {
|
||||
const isThisDevicePinned = (SettingsData.audioInputDevicePins || {})["preferredInput"] === modelData.name
|
||||
return isThisDevicePinned ? "Pinned" : "Pin"
|
||||
const isThisDevicePinned = (SettingsData.audioInputDevicePins || {})["preferredInput"] === modelData.name;
|
||||
return isThisDevicePinned ? "Pinned" : "Pin";
|
||||
}
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: {
|
||||
const isThisDevicePinned = (SettingsData.audioInputDevicePins || {})["preferredInput"] === modelData.name
|
||||
return isThisDevicePinned ? Theme.primary : Theme.surfaceText
|
||||
const isThisDevicePinned = (SettingsData.audioInputDevicePins || {})["preferredInput"] === modelData.name;
|
||||
return isThisDevicePinned ? Theme.primary : Theme.surfaceText;
|
||||
}
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
@@ -252,16 +256,16 @@ Rectangle {
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
const pins = JSON.parse(JSON.stringify(SettingsData.audioInputDevicePins || {}))
|
||||
const isCurrentlyPinned = pins["preferredInput"] === modelData.name
|
||||
|
||||
const pins = JSON.parse(JSON.stringify(SettingsData.audioInputDevicePins || {}));
|
||||
const isCurrentlyPinned = pins["preferredInput"] === modelData.name;
|
||||
|
||||
if (isCurrentlyPinned) {
|
||||
delete pins["preferredInput"]
|
||||
delete pins["preferredInput"];
|
||||
} else {
|
||||
pins["preferredInput"] = modelData.name
|
||||
pins["preferredInput"] = modelData.name;
|
||||
}
|
||||
|
||||
SettingsData.set("audioInputDevicePins", pins)
|
||||
|
||||
SettingsData.set("audioInputDevicePins", pins);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -274,7 +278,7 @@ Rectangle {
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
if (modelData) {
|
||||
Pipewire.preferredDefaultAudioSource = modelData
|
||||
Pipewire.preferredDefaultAudioSource = modelData;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -282,4 +286,4 @@ Rectangle {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import Quickshell
|
||||
import qs.Common
|
||||
import qs.Services
|
||||
import qs.Widgets
|
||||
@@ -11,88 +9,91 @@ Rectangle {
|
||||
property string initialDeviceName: ""
|
||||
property string instanceId: ""
|
||||
property string screenName: ""
|
||||
property string screenModel: ""
|
||||
|
||||
signal deviceNameChanged(string newDeviceName)
|
||||
|
||||
property string currentDeviceName: ""
|
||||
|
||||
function getScreenPinKey() {
|
||||
if (SettingsData.displayNameMode === "model" && screenModel && screenModel.length > 0) {
|
||||
return screenModel;
|
||||
}
|
||||
return screenName || "";
|
||||
}
|
||||
|
||||
function resolveDeviceName() {
|
||||
if (!DisplayService.brightnessAvailable || !DisplayService.devices || DisplayService.devices.length === 0) {
|
||||
return ""
|
||||
return "";
|
||||
}
|
||||
|
||||
if (screenName && screenName.length > 0) {
|
||||
const pins = SettingsData.brightnessDevicePins || {}
|
||||
const pinnedDevice = pins[screenName]
|
||||
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
|
||||
}
|
||||
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 found = DisplayService.devices.find(dev => dev.name === initialDeviceName);
|
||||
if (found)
|
||||
return found.name;
|
||||
}
|
||||
|
||||
const currentDeviceNameFromService = DisplayService.currentDevice
|
||||
const currentDeviceNameFromService = DisplayService.currentDevice;
|
||||
if (currentDeviceNameFromService) {
|
||||
const found = DisplayService.devices.find(dev => dev.name === currentDeviceNameFromService)
|
||||
if (found) {
|
||||
return found.name
|
||||
}
|
||||
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 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
|
||||
}
|
||||
const ddc = DisplayService.devices.find(d => d.class === "ddc");
|
||||
if (ddc)
|
||||
return ddc.name;
|
||||
|
||||
return DisplayService.devices.length > 0 ? DisplayService.devices[0].name : ""
|
||||
return DisplayService.devices.length > 0 ? DisplayService.devices[0].name : "";
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
currentDeviceName = resolveDeviceName()
|
||||
currentDeviceName = resolveDeviceName();
|
||||
}
|
||||
|
||||
property bool isPinnedToScreen: {
|
||||
if (!screenName || screenName.length === 0) {
|
||||
return false
|
||||
}
|
||||
const pins = SettingsData.brightnessDevicePins || {}
|
||||
return pins[screenName] === currentDeviceName
|
||||
const pinKey = getScreenPinKey();
|
||||
if (!pinKey || pinKey.length === 0)
|
||||
return false;
|
||||
const pins = SettingsData.brightnessDevicePins || {};
|
||||
return pins[pinKey] === currentDeviceName;
|
||||
}
|
||||
|
||||
function togglePinToScreen() {
|
||||
if (!screenName || screenName.length === 0 || !currentDeviceName || currentDeviceName.length === 0) {
|
||||
return
|
||||
}
|
||||
|
||||
const pins = JSON.parse(JSON.stringify(SettingsData.brightnessDevicePins || {}))
|
||||
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[screenName]
|
||||
delete pins[pinKey];
|
||||
} else {
|
||||
pins[screenName] = currentDeviceName
|
||||
pins[pinKey] = currentDeviceName;
|
||||
}
|
||||
|
||||
SettingsData.set("brightnessDevicePins", pins)
|
||||
SettingsData.set("brightnessDevicePins", pins);
|
||||
}
|
||||
|
||||
implicitHeight: {
|
||||
if (height > 0) {
|
||||
return height
|
||||
return height;
|
||||
}
|
||||
return brightnessContent.height + Theme.spacingM
|
||||
return brightnessContent.height + Theme.spacingM;
|
||||
}
|
||||
radius: Theme.cornerRadius
|
||||
color: Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency)
|
||||
@@ -165,7 +166,7 @@ Rectangle {
|
||||
}
|
||||
|
||||
StyledText {
|
||||
text: screenName || "Unknown Monitor"
|
||||
text: root.getScreenPinKey() || "Unknown Monitor"
|
||||
font.pixelSize: Theme.fontSizeMedium
|
||||
color: Theme.surfaceText
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
@@ -216,8 +217,8 @@ Rectangle {
|
||||
required property int index
|
||||
|
||||
property real deviceBrightness: {
|
||||
DisplayService.brightnessVersion
|
||||
return DisplayService.getDeviceBrightness(modelData.name)
|
||||
DisplayService.brightnessVersion;
|
||||
return DisplayService.getDeviceBrightness(modelData.name);
|
||||
}
|
||||
|
||||
width: parent.width
|
||||
@@ -248,19 +249,19 @@ Rectangle {
|
||||
|
||||
DankIcon {
|
||||
name: {
|
||||
const deviceClass = modelData.class || ""
|
||||
const deviceName = modelData.name || ""
|
||||
const deviceClass = modelData.class || "";
|
||||
const deviceName = modelData.name || "";
|
||||
|
||||
if (deviceClass === "backlight" || deviceClass === "ddc") {
|
||||
if (deviceBrightness <= 33)
|
||||
return "brightness_low"
|
||||
return "brightness_low";
|
||||
if (deviceBrightness <= 66)
|
||||
return "brightness_medium"
|
||||
return "brightness_high"
|
||||
return "brightness_medium";
|
||||
return "brightness_high";
|
||||
} else if (deviceName.includes("kbd")) {
|
||||
return "keyboard"
|
||||
return "keyboard";
|
||||
} else {
|
||||
return "lightbulb"
|
||||
return "lightbulb";
|
||||
}
|
||||
}
|
||||
size: Theme.iconSize
|
||||
@@ -283,12 +284,12 @@ Rectangle {
|
||||
|
||||
StyledText {
|
||||
text: {
|
||||
const name = modelData.name || ""
|
||||
const deviceClass = modelData.class || ""
|
||||
const name = modelData.name || "";
|
||||
const deviceClass = modelData.class || "";
|
||||
if (deviceClass === "backlight") {
|
||||
return name.replace("_", " ").replace(/\b\w/g, c => c.toUpperCase())
|
||||
return name.replace("_", " ").replace(/\b\w/g, c => c.toUpperCase());
|
||||
}
|
||||
return name
|
||||
return name;
|
||||
}
|
||||
font.pixelSize: Theme.fontSizeMedium
|
||||
color: Theme.surfaceText
|
||||
@@ -307,14 +308,14 @@ Rectangle {
|
||||
|
||||
StyledText {
|
||||
text: {
|
||||
const deviceClass = modelData.class || ""
|
||||
const deviceClass = modelData.class || "";
|
||||
if (deviceClass === "backlight")
|
||||
return "Backlight device"
|
||||
return "Backlight device";
|
||||
if (deviceClass === "ddc")
|
||||
return "DDC/CI monitor"
|
||||
return "DDC/CI monitor";
|
||||
if (deviceClass === "leds")
|
||||
return "LED device"
|
||||
return deviceClass
|
||||
return "LED device";
|
||||
return deviceClass;
|
||||
}
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Theme.surfaceVariantText
|
||||
@@ -353,9 +354,9 @@ Rectangle {
|
||||
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)
|
||||
const current = SessionData.getBrightnessExponent(modelData.name);
|
||||
const newValue = Math.max(1.0, Math.round((current - 0.1) * 10) / 10);
|
||||
SessionData.setBrightnessExponent(modelData.name, newValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -395,9 +396,9 @@ Rectangle {
|
||||
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)
|
||||
const current = SessionData.getBrightnessExponent(modelData.name);
|
||||
const newValue = Math.min(2.5, Math.round((current + 0.1) * 10) / 10);
|
||||
SessionData.setBrightnessExponent(modelData.name, newValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -433,8 +434,8 @@ Rectangle {
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
const currentState = SessionData.getBrightnessExponential(modelData.name)
|
||||
SessionData.setBrightnessExponential(modelData.name, !currentState)
|
||||
const currentState = SessionData.getBrightnessExponential(modelData.name);
|
||||
SessionData.setBrightnessExponential(modelData.name, !currentState);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -447,15 +448,16 @@ Rectangle {
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
if (screenName && screenName.length > 0 && modelData.name !== currentDeviceName) {
|
||||
const pins = JSON.parse(JSON.stringify(SettingsData.brightnessDevicePins || {}))
|
||||
if (pins[screenName]) {
|
||||
delete pins[screenName]
|
||||
SettingsData.set("brightnessDevicePins", pins)
|
||||
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)
|
||||
currentDeviceName = modelData.name;
|
||||
deviceNameChanged(modelData.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,17 +17,17 @@ QtObject {
|
||||
}
|
||||
|
||||
onItemChanged: {
|
||||
root.vpnBuiltinInstance = item
|
||||
root.vpnBuiltinInstance = item;
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: SettingsData
|
||||
function onControlCenterWidgetsChanged() {
|
||||
const widgets = SettingsData.controlCenterWidgets || []
|
||||
const hasVpnWidget = widgets.some(w => w.id === "builtin_vpn")
|
||||
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
|
||||
console.log("VpnWidget: No VPN widget in control center, deactivating loader");
|
||||
vpnLoader.active = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -40,35 +40,36 @@ QtObject {
|
||||
}
|
||||
|
||||
onItemChanged: {
|
||||
root.cupsBuiltinInstance = item
|
||||
root.cupsBuiltinInstance = item;
|
||||
if (item && !DMSService.activeSubscriptions.includes("cups") && !DMSService.activeSubscriptions.includes("all")) {
|
||||
DMSService.addSubscription("cups")
|
||||
DMSService.addSubscription("cups");
|
||||
}
|
||||
}
|
||||
|
||||
onActiveChanged: {
|
||||
if (!active) {
|
||||
if (DMSService.activeSubscriptions.includes("cups")) {
|
||||
DMSService.removeSubscription("cups")
|
||||
DMSService.removeSubscription("cups");
|
||||
}
|
||||
root.cupsBuiltinInstance = null
|
||||
root.cupsBuiltinInstance = null;
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: SettingsData
|
||||
function onControlCenterWidgetsChanged() {
|
||||
const widgets = SettingsData.controlCenterWidgets || []
|
||||
const hasCupsWidget = widgets.some(w => w.id === "builtin_cups")
|
||||
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
|
||||
console.log("CupsWidget: No CUPS widget in control center, deactivating loader");
|
||||
cupsLoader.active = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
readonly property var coreWidgetDefinitions: [{
|
||||
readonly property var coreWidgetDefinitions: [
|
||||
{
|
||||
"id": "nightMode",
|
||||
"text": "Night Mode",
|
||||
"description": "Blue light filter",
|
||||
@@ -76,28 +77,32 @@ QtObject {
|
||||
"type": "toggle",
|
||||
"enabled": DisplayService.automationAvailable,
|
||||
"warning": !DisplayService.automationAvailable ? "Requires night mode support" : undefined
|
||||
}, {
|
||||
},
|
||||
{
|
||||
"id": "darkMode",
|
||||
"text": "Dark Mode",
|
||||
"description": "System theme toggle",
|
||||
"icon": "contrast",
|
||||
"type": "toggle",
|
||||
"enabled": true
|
||||
}, {
|
||||
},
|
||||
{
|
||||
"id": "doNotDisturb",
|
||||
"text": "Do Not Disturb",
|
||||
"description": "Block notifications",
|
||||
"icon": "do_not_disturb_on",
|
||||
"type": "toggle",
|
||||
"enabled": true
|
||||
}, {
|
||||
},
|
||||
{
|
||||
"id": "idleInhibitor",
|
||||
"text": "Keep Awake",
|
||||
"description": "Prevent screen timeout",
|
||||
"icon": "motion_sensor_active",
|
||||
"type": "toggle",
|
||||
"enabled": true
|
||||
}, {
|
||||
},
|
||||
{
|
||||
"id": "wifi",
|
||||
"text": "Network",
|
||||
"description": "Wi-Fi and Ethernet connection",
|
||||
@@ -105,7 +110,8 @@ QtObject {
|
||||
"type": "connection",
|
||||
"enabled": NetworkService.wifiAvailable,
|
||||
"warning": !NetworkService.wifiAvailable ? "Wi-Fi not available" : undefined
|
||||
}, {
|
||||
},
|
||||
{
|
||||
"id": "bluetooth",
|
||||
"text": "Bluetooth",
|
||||
"description": "Device connections",
|
||||
@@ -113,28 +119,32 @@ QtObject {
|
||||
"type": "connection",
|
||||
"enabled": BluetoothService.available,
|
||||
"warning": !BluetoothService.available ? "Bluetooth not available" : undefined
|
||||
}, {
|
||||
},
|
||||
{
|
||||
"id": "audioOutput",
|
||||
"text": "Audio Output",
|
||||
"description": "Speaker settings",
|
||||
"icon": "volume_up",
|
||||
"type": "connection",
|
||||
"enabled": true
|
||||
}, {
|
||||
},
|
||||
{
|
||||
"id": "audioInput",
|
||||
"text": "Audio Input",
|
||||
"description": "Microphone settings",
|
||||
"icon": "mic",
|
||||
"type": "connection",
|
||||
"enabled": true
|
||||
}, {
|
||||
},
|
||||
{
|
||||
"id": "volumeSlider",
|
||||
"text": "Volume Slider",
|
||||
"description": "Audio volume control",
|
||||
"icon": "volume_up",
|
||||
"type": "slider",
|
||||
"enabled": true
|
||||
}, {
|
||||
},
|
||||
{
|
||||
"id": "brightnessSlider",
|
||||
"text": "Brightness Slider",
|
||||
"description": "Display brightness control",
|
||||
@@ -143,21 +153,24 @@ QtObject {
|
||||
"enabled": DisplayService.brightnessAvailable,
|
||||
"warning": !DisplayService.brightnessAvailable ? "Brightness control not available" : undefined,
|
||||
"allowMultiple": true
|
||||
}, {
|
||||
},
|
||||
{
|
||||
"id": "inputVolumeSlider",
|
||||
"text": "Input Volume Slider",
|
||||
"description": "Microphone volume control",
|
||||
"icon": "mic",
|
||||
"type": "slider",
|
||||
"enabled": true
|
||||
}, {
|
||||
},
|
||||
{
|
||||
"id": "battery",
|
||||
"text": "Battery",
|
||||
"description": "Battery and power management",
|
||||
"icon": "battery_std",
|
||||
"type": "action",
|
||||
"enabled": true
|
||||
}, {
|
||||
},
|
||||
{
|
||||
"id": "diskUsage",
|
||||
"text": "Disk Usage",
|
||||
"description": "Filesystem usage monitoring",
|
||||
@@ -166,14 +179,16 @@ QtObject {
|
||||
"enabled": DgopService.dgopAvailable,
|
||||
"warning": !DgopService.dgopAvailable ? "Requires 'dgop' tool" : undefined,
|
||||
"allowMultiple": true
|
||||
}, {
|
||||
},
|
||||
{
|
||||
"id": "colorPicker",
|
||||
"text": "Color Picker",
|
||||
"description": "Choose colors from palette",
|
||||
"icon": "palette",
|
||||
"type": "action",
|
||||
"enabled": true
|
||||
}, {
|
||||
},
|
||||
{
|
||||
"id": "builtin_vpn",
|
||||
"text": "VPN",
|
||||
"description": "VPN connections",
|
||||
@@ -182,7 +197,8 @@ QtObject {
|
||||
"enabled": DMSNetworkService.available,
|
||||
"warning": !DMSNetworkService.available ? "VPN not available" : undefined,
|
||||
"isBuiltinPlugin": true
|
||||
}, {
|
||||
},
|
||||
{
|
||||
"id": "builtin_cups",
|
||||
"text": "Printers",
|
||||
"description": "Print Server Management",
|
||||
@@ -191,78 +207,79 @@ QtObject {
|
||||
"enabled": CupsService.available,
|
||||
"warning": !CupsService.available ? "CUPS not available" : undefined,
|
||||
"isBuiltinPlugin": true
|
||||
}]
|
||||
}
|
||||
]
|
||||
|
||||
function getPluginWidgets() {
|
||||
const plugins = []
|
||||
const loadedPlugins = PluginService.getLoadedPlugins()
|
||||
const plugins = [];
|
||||
const loadedPlugins = PluginService.getLoadedPlugins();
|
||||
|
||||
for (var i = 0; i < loadedPlugins.length; i++) {
|
||||
const plugin = loadedPlugins[i]
|
||||
const plugin = loadedPlugins[i];
|
||||
|
||||
if (plugin.type === "daemon") {
|
||||
continue
|
||||
continue;
|
||||
}
|
||||
|
||||
const pluginComponent = PluginService.pluginWidgetComponents[plugin.id]
|
||||
const pluginComponent = PluginService.pluginWidgetComponents[plugin.id];
|
||||
if (!pluginComponent || typeof pluginComponent.createObject !== 'function') {
|
||||
continue
|
||||
continue;
|
||||
}
|
||||
|
||||
const tempInstance = pluginComponent.createObject(null)
|
||||
const tempInstance = pluginComponent.createObject(null);
|
||||
if (!tempInstance) {
|
||||
continue
|
||||
continue;
|
||||
}
|
||||
|
||||
const hasCCWidget = tempInstance.ccWidgetIcon && tempInstance.ccWidgetIcon.length > 0
|
||||
tempInstance.destroy()
|
||||
const hasCCWidget = tempInstance.ccWidgetIcon && tempInstance.ccWidgetIcon.length > 0;
|
||||
tempInstance.destroy();
|
||||
|
||||
if (!hasCCWidget) {
|
||||
continue
|
||||
continue;
|
||||
}
|
||||
|
||||
plugins.push({
|
||||
"id": "plugin_" + plugin.id,
|
||||
"pluginId": plugin.id,
|
||||
"text": plugin.name || "Plugin",
|
||||
"description": plugin.description || "",
|
||||
"icon": plugin.icon || "extension",
|
||||
"type": "plugin",
|
||||
"enabled": true,
|
||||
"isPlugin": true
|
||||
})
|
||||
"id": "plugin_" + plugin.id,
|
||||
"pluginId": plugin.id,
|
||||
"text": plugin.name || "Plugin",
|
||||
"description": plugin.description || "",
|
||||
"icon": plugin.icon || "extension",
|
||||
"type": "plugin",
|
||||
"enabled": true,
|
||||
"isPlugin": true
|
||||
});
|
||||
}
|
||||
|
||||
return plugins
|
||||
return plugins;
|
||||
}
|
||||
|
||||
readonly property var baseWidgetDefinitions: coreWidgetDefinitions
|
||||
|
||||
function getWidgetForId(widgetId) {
|
||||
return WidgetUtils.getWidgetForId(baseWidgetDefinitions, widgetId)
|
||||
return WidgetUtils.getWidgetForId(baseWidgetDefinitions, widgetId);
|
||||
}
|
||||
|
||||
function addWidget(widgetId) {
|
||||
WidgetUtils.addWidget(widgetId)
|
||||
WidgetUtils.addWidget(widgetId);
|
||||
}
|
||||
|
||||
function removeWidget(index) {
|
||||
WidgetUtils.removeWidget(index)
|
||||
WidgetUtils.removeWidget(index);
|
||||
}
|
||||
|
||||
function toggleWidgetSize(index) {
|
||||
WidgetUtils.toggleWidgetSize(index)
|
||||
WidgetUtils.toggleWidgetSize(index);
|
||||
}
|
||||
|
||||
function moveWidget(fromIndex, toIndex) {
|
||||
WidgetUtils.moveWidget(fromIndex, toIndex)
|
||||
WidgetUtils.moveWidget(fromIndex, toIndex);
|
||||
}
|
||||
|
||||
function resetToDefault() {
|
||||
WidgetUtils.resetToDefault()
|
||||
WidgetUtils.resetToDefault();
|
||||
}
|
||||
|
||||
function clearAll() {
|
||||
WidgetUtils.clearAll()
|
||||
WidgetUtils.clearAll();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user