From 5d94c0a7d44a2255b81815a52a7056a94a39842d Mon Sep 17 00:00:00 2001 From: nippy Date: Sat, 18 Apr 2026 13:49:56 +0200 Subject: update Raveos themes --- .../ControlCenter/Details/BrightnessDetail.qml | 498 +++++++++++++++++++++ 1 file changed, 498 insertions(+) create mode 100644 raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Details/BrightnessDetail.qml (limited to 'raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Details/BrightnessDetail.qml') 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 new file mode 100644 index 0000000..0d42e62 --- /dev/null +++ b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/ControlCenter/Details/BrightnessDetail.qml @@ -0,0 +1,498 @@ +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); + } + } + } + } + } + } +} -- cgit v1.3