mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-10-30 06:57:49 -04:00
230 lines
9.5 KiB
QML
230 lines
9.5 KiB
QML
pragma ComponentBehavior: Bound
|
|
|
|
import QtQuick
|
|
import Quickshell
|
|
import qs.Common
|
|
import qs.Modules.ControlCenter
|
|
import qs.Modules.ControlCenter.Widgets
|
|
import qs.Services
|
|
import qs.Widgets
|
|
|
|
Item {
|
|
id: root
|
|
|
|
LayoutMirroring.enabled: I18n.isRtl
|
|
LayoutMirroring.childrenInherit: true
|
|
|
|
property string initialDeviceName: ""
|
|
property string instanceId: ""
|
|
property string screenName: ""
|
|
property string screenModel: ""
|
|
property string currentDeviceName: ""
|
|
|
|
readonly property string title: I18n.tr("Brightness")
|
|
readonly property var devices: BrightnessService.devices || []
|
|
readonly property bool multipleDevices: devices.length > 1
|
|
readonly property bool showPins: screenName.length > 0 && multipleDevices
|
|
|
|
signal deviceNameChanged(string newDeviceName)
|
|
|
|
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)
|
|
return screenModel;
|
|
return screenName;
|
|
}
|
|
|
|
function resolveCurrentDevice() {
|
|
if (!BrightnessService.brightnessAvailable || devices.length === 0)
|
|
return "";
|
|
const pinKey = getScreenPinKey();
|
|
const pinnedDevice = pinKey ? (CacheData.brightnessDevicePins || {})[pinKey] : "";
|
|
if (pinnedDevice && devices.find(d => d.name === pinnedDevice))
|
|
return pinnedDevice;
|
|
if (instanceId) {
|
|
const widget = (SettingsData.controlCenterWidgets || []).find(w => w.id === "brightnessSlider" && w.instanceId === instanceId);
|
|
if (widget?.deviceName && devices.find(d => d.name === widget.deviceName))
|
|
return widget.deviceName;
|
|
}
|
|
if (BrightnessService.currentDevice && devices.find(d => d.name === BrightnessService.currentDevice))
|
|
return BrightnessService.currentDevice;
|
|
if (initialDeviceName && devices.find(d => d.name === initialDeviceName))
|
|
return initialDeviceName;
|
|
const backlight = devices.find(d => d.class === "backlight");
|
|
if (backlight)
|
|
return backlight.name;
|
|
const ddc = devices.find(d => d.class === "ddc");
|
|
if (ddc)
|
|
return ddc.name;
|
|
return devices[0].name;
|
|
}
|
|
|
|
function selectDevice(deviceName) {
|
|
if (!deviceName || deviceName === currentDeviceName)
|
|
return;
|
|
const pinKey = getScreenPinKey();
|
|
if (pinKey) {
|
|
const pins = CacheData.brightnessDevicePins || {};
|
|
if (pins[pinKey] && pins[pinKey] !== deviceName) {
|
|
const next = JSON.parse(JSON.stringify(pins));
|
|
delete next[pinKey];
|
|
CacheData.set("brightnessDevicePins", next);
|
|
}
|
|
}
|
|
currentDeviceName = deviceName;
|
|
BrightnessService.setCurrentDevice(deviceName, true);
|
|
deviceNameChanged(deviceName);
|
|
}
|
|
|
|
function isDevicePinnedToScreen(deviceName) {
|
|
const pinKey = getScreenPinKey();
|
|
if (!pinKey || !deviceName)
|
|
return false;
|
|
return (CacheData.brightnessDevicePins || {})[pinKey] === deviceName;
|
|
}
|
|
|
|
function togglePinForDevice(deviceName) {
|
|
const pinKey = getScreenPinKey();
|
|
if (!pinKey || !deviceName)
|
|
return;
|
|
const pins = JSON.parse(JSON.stringify(CacheData.brightnessDevicePins || {}));
|
|
if (pins[pinKey] === deviceName)
|
|
delete pins[pinKey];
|
|
else
|
|
pins[pinKey] = deviceName;
|
|
CacheData.set("brightnessDevicePins", pins);
|
|
}
|
|
|
|
function deviceIcon(device, brightness) {
|
|
const deviceClass = device.class || "";
|
|
if (deviceClass === "backlight" || deviceClass === "ddc") {
|
|
if (brightness <= CcMetrics.brightnessLowMax)
|
|
return "brightness_low";
|
|
return brightness <= CcMetrics.brightnessMediumMax ? "brightness_medium" : "brightness_high";
|
|
}
|
|
return (device.name || "").includes("kbd") ? "keyboard" : "lightbulb";
|
|
}
|
|
|
|
function deviceClassLabel(device) {
|
|
switch (device.class || "") {
|
|
case "backlight":
|
|
return I18n.tr("Backlight device");
|
|
case "ddc":
|
|
return I18n.tr("DDC/CI monitor");
|
|
case "leds":
|
|
return I18n.tr("LED device");
|
|
default:
|
|
return device.class || "";
|
|
}
|
|
}
|
|
|
|
Component.onCompleted: currentDeviceName = resolveCurrentDevice()
|
|
|
|
DankFlickable {
|
|
anchors.fill: parent
|
|
contentHeight: column.height
|
|
clip: true
|
|
|
|
Column {
|
|
id: column
|
|
width: parent.width
|
|
spacing: CcMetrics.detailContentGap
|
|
|
|
CcEmptyState {
|
|
visible: !BrightnessService.brightnessAvailable || root.devices.length === 0
|
|
iconName: BrightnessService.brightnessAvailable ? "brightness_6" : "error"
|
|
iconColor: BrightnessService.brightnessAvailable ? Theme.primary : Theme.error
|
|
title: BrightnessService.brightnessAvailable ? I18n.tr("No brightness devices available") : I18n.tr("Brightness control not available")
|
|
}
|
|
|
|
CcSectionLabel {
|
|
visible: root.showPins
|
|
text: root.getScreenPinKey() || I18n.tr("Unknown Monitor")
|
|
|
|
actions: CcPinChip {
|
|
readonly property bool pinnedHere: {
|
|
CacheData.brightnessDevicePins;
|
|
return root.isDevicePinnedToScreen(root.currentDeviceName);
|
|
}
|
|
|
|
iconOnly: false
|
|
pinned: pinnedHere
|
|
enabled: root.currentDeviceName.length > 0
|
|
onToggled: root.togglePinForDevice(root.currentDeviceName)
|
|
}
|
|
}
|
|
|
|
CcGroup {
|
|
visible: root.devices.length > 0
|
|
|
|
Repeater {
|
|
model: root.devices
|
|
|
|
CcListRow {
|
|
id: deviceRow
|
|
|
|
required property var modelData
|
|
|
|
readonly property string deviceName: modelData.name || ""
|
|
readonly property real deviceBrightness: {
|
|
BrightnessService.brightnessVersion;
|
|
return BrightnessService.getDeviceBrightness(deviceName);
|
|
}
|
|
readonly property bool pinnedHere: {
|
|
CacheData.brightnessDevicePins;
|
|
return root.isDevicePinnedToScreen(deviceName);
|
|
}
|
|
readonly property bool exponential: SessionData.getBrightnessExponential(deviceName)
|
|
readonly property real exponent: SessionData.getBrightnessExponent(deviceName)
|
|
|
|
iconName: root.deviceIcon(modelData, deviceBrightness)
|
|
active: deviceName === root.currentDeviceName
|
|
showActiveCheck: true
|
|
title: BrightnessService.deviceTitle(modelData)
|
|
subtitle: deviceName + " • " + root.deviceClassLabel(modelData)
|
|
trailingBadge: Math.round(deviceBrightness) + "%"
|
|
clickable: true
|
|
onClicked: root.selectDevice(deviceName)
|
|
|
|
CcPinChip {
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
visible: root.showPins
|
|
pinned: deviceRow.pinnedHere
|
|
onToggled: root.togglePinForDevice(deviceRow.deviceName)
|
|
}
|
|
|
|
body: Row {
|
|
width: parent.width
|
|
spacing: Theme.spacingM
|
|
visible: deviceRow.active
|
|
|
|
DankToggle {
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
width: parent.width - stepper.width - parent.spacing
|
|
text: I18n.tr("Exponential", "adjective, toggle for an exponential brightness curve per device")
|
|
checked: deviceRow.exponential
|
|
onToggled: checked => SessionData.setBrightnessExponential(deviceRow.deviceName, checked)
|
|
}
|
|
|
|
DankNumberStepper {
|
|
id: stepper
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
visible: deviceRow.exponential
|
|
text: deviceRow.exponent.toFixed(1)
|
|
decrementEnabled: deviceRow.exponent > CcMetrics.brightnessExponentMin
|
|
incrementEnabled: deviceRow.exponent < CcMetrics.brightnessExponentMax
|
|
onDecrement: () => SessionData.setBrightnessExponent(deviceRow.deviceName, Math.max(CcMetrics.brightnessExponentMin, Math.round((deviceRow.exponent - CcMetrics.brightnessExponentStep) * 10) / 10))
|
|
onIncrement: () => SessionData.setBrightnessExponent(deviceRow.deviceName, Math.min(CcMetrics.brightnessExponentMax, Math.round((deviceRow.exponent + CcMetrics.brightnessExponentStep) * 10) / 10))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|