Files
noctalia-shell/Modules/Cards/BrightnessCard.qml
T
2025-12-15 10:12:59 -05:00

133 lines
3.6 KiB
QML

import QtQuick
import QtQuick.Layouts
import Quickshell
import qs.Commons
import qs.Services.Hardware
import qs.Widgets
// Brightness control card for the ControlCenter
NBox {
id: root
Layout.fillWidth: true
clip: true
// Get the primary monitor (first screen)
readonly property var brightnessMonitor: {
if (Quickshell.screens.length > 0) {
return BrightnessService.getMonitorForScreen(Quickshell.screens[0]);
}
return null;
}
property real localBrightness: 0
property bool localBrightnessChanging: false
Component.onCompleted: {
if (brightnessMonitor) {
localBrightness = brightnessMonitor.brightness || 0;
}
}
// Update local brightness when monitor changes
Connections {
target: BrightnessService
function onMonitorBrightnessChanged(monitor, newBrightness) {
if (monitor === brightnessMonitor && !localBrightnessChanging) {
localBrightness = newBrightness;
}
}
}
// Update local brightness when monitor's brightness property changes
Connections {
target: brightnessMonitor
ignoreUnknownSignals: true
function onBrightnessUpdated() {
if (brightnessMonitor && !localBrightnessChanging) {
localBrightness = brightnessMonitor.brightness || 0;
}
}
}
// Timer to debounce brightness changes
Timer {
interval: 100
running: true
repeat: true
onTriggered: {
if (brightnessMonitor && Math.abs(localBrightness - brightnessMonitor.brightness) >= 0.01) {
brightnessMonitor.setBrightness(localBrightness);
}
}
}
RowLayout {
anchors.fill: parent
anchors.margins: Style.marginM
spacing: Style.marginM
// Brightness Section
ColumnLayout {
spacing: Style.marginXXS
Layout.fillWidth: true
Layout.preferredWidth: 0
opacity: brightnessMonitor && brightnessMonitor.brightnessControlAvailable ? 1.0 : 0.5
enabled: brightnessMonitor && brightnessMonitor.brightnessControlAvailable
// Brightness Header
RowLayout {
Layout.fillWidth: true
spacing: Style.marginXS
NIconButton {
icon: {
if (!brightnessMonitor)
return "brightness-low";
const brightness = brightnessMonitor.brightness || 0;
if (brightness <= 0.001)
return "sun-off";
return brightness <= 0.5 ? "brightness-low" : "brightness-high";
}
baseSize: Style.baseWidgetSize * 0.5
colorFg: Color.mOnSurface
colorBg: Color.transparent
colorBgHover: Color.mHover
colorFgHover: Color.mOnHover
}
NText {
text: brightnessMonitor ? I18n.tr("settings.display.monitors.brightness") : "No display"
pointSize: Style.fontSizeXS
color: Color.mOnSurfaceVariant
font.weight: Style.fontWeightMedium
elide: Text.ElideRight
Layout.fillWidth: true
Layout.preferredWidth: 0
}
NText {
text: brightnessMonitor ? Math.round(localBrightness * 100) + "%" : "N/A"
pointSize: Style.fontSizeXS
color: Color.mOnSurfaceVariant
opacity: brightnessMonitor && brightnessMonitor.brightnessControlAvailable ? 1.0 : 0.5
}
}
// Brightness Slider
NSlider {
Layout.fillWidth: true
from: 0
to: 1
value: localBrightness
stepSize: 0.01
heightRatio: 0.5
onMoved: localBrightness = value
onPressedChanged: localBrightnessChanging = pressed
tooltipText: `${Math.round(localBrightness * 100)}%`
tooltipDirection: "bottom"
}
}
}
}