mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-01-25 05:52:50 -05:00
- Configure position, VRR, orientation, resolution, refresh rate - Split Display section into Configuration, Gamma, and Widgets - MangoWC omits VRR because it doesnt have per-display VRR - HDR configuration not present for Hyprland
670 lines
33 KiB
QML
670 lines
33 KiB
QML
import QtQuick
|
|
import qs.Common
|
|
import qs.Services
|
|
import qs.Widgets
|
|
|
|
Item {
|
|
id: root
|
|
|
|
function formatGammaTime(isoString) {
|
|
if (!isoString)
|
|
return "";
|
|
try {
|
|
const date = new Date(isoString);
|
|
if (isNaN(date.getTime()))
|
|
return "";
|
|
return date.toLocaleTimeString(Qt.locale(), "HH:mm");
|
|
} catch (e) {
|
|
return "";
|
|
}
|
|
}
|
|
|
|
DankFlickable {
|
|
anchors.fill: parent
|
|
clip: true
|
|
contentHeight: mainColumn.height + Theme.spacingXL
|
|
contentWidth: width
|
|
|
|
Column {
|
|
id: mainColumn
|
|
|
|
width: Math.min(550, parent.width - Theme.spacingL * 2)
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
spacing: Theme.spacingXL
|
|
|
|
StyledRect {
|
|
width: parent.width
|
|
height: gammaSection.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.2)
|
|
border.width: 0
|
|
|
|
Column {
|
|
id: gammaSection
|
|
|
|
anchors.fill: parent
|
|
anchors.margins: Theme.spacingL
|
|
spacing: Theme.spacingM
|
|
|
|
Row {
|
|
width: parent.width
|
|
spacing: Theme.spacingM
|
|
|
|
DankIcon {
|
|
name: "brightness_6"
|
|
size: Theme.iconSize
|
|
color: Theme.primary
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
}
|
|
|
|
StyledText {
|
|
text: I18n.tr("Gamma Control")
|
|
font.pixelSize: Theme.fontSizeLarge
|
|
font.weight: Font.Medium
|
|
color: Theme.surfaceText
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
}
|
|
}
|
|
|
|
DankToggle {
|
|
id: nightModeToggle
|
|
|
|
width: parent.width
|
|
text: I18n.tr("Night Mode")
|
|
description: DisplayService.gammaControlAvailable ? I18n.tr("Apply warm color temperature to reduce eye strain. Use automation settings below to control when it activates.") : I18n.tr("Gamma control not available. Requires DMS API v6+.")
|
|
checked: DisplayService.nightModeEnabled
|
|
enabled: DisplayService.gammaControlAvailable
|
|
onToggled: checked => {
|
|
DisplayService.toggleNightMode();
|
|
}
|
|
|
|
Connections {
|
|
function onNightModeEnabledChanged() {
|
|
nightModeToggle.checked = DisplayService.nightModeEnabled;
|
|
}
|
|
|
|
target: DisplayService
|
|
}
|
|
}
|
|
|
|
Column {
|
|
width: parent.width
|
|
spacing: Theme.spacingS
|
|
leftPadding: Theme.spacingM
|
|
rightPadding: Theme.spacingM
|
|
visible: DisplayService.gammaControlAvailable
|
|
|
|
DankDropdown {
|
|
width: parent.width - parent.leftPadding - parent.rightPadding
|
|
text: SessionData.nightModeAutoEnabled ? I18n.tr("Night Temperature") : I18n.tr("Color Temperature")
|
|
description: SessionData.nightModeAutoEnabled ? I18n.tr("Color temperature for night mode") : I18n.tr("Warm color temperature to apply")
|
|
currentValue: SessionData.nightModeTemperature + "K"
|
|
options: {
|
|
var temps = [];
|
|
for (var i = 2500; i <= 6000; i += 500) {
|
|
temps.push(i + "K");
|
|
}
|
|
return temps;
|
|
}
|
|
onValueChanged: value => {
|
|
var temp = parseInt(value.replace("K", ""));
|
|
SessionData.setNightModeTemperature(temp);
|
|
if (SessionData.nightModeHighTemperature < temp) {
|
|
SessionData.setNightModeHighTemperature(temp);
|
|
}
|
|
}
|
|
}
|
|
|
|
DankDropdown {
|
|
width: parent.width - parent.leftPadding - parent.rightPadding
|
|
text: I18n.tr("Day Temperature")
|
|
description: I18n.tr("Color temperature for day time")
|
|
currentValue: SessionData.nightModeHighTemperature + "K"
|
|
visible: SessionData.nightModeAutoEnabled
|
|
options: {
|
|
var temps = [];
|
|
var minTemp = SessionData.nightModeTemperature;
|
|
for (var i = Math.max(2500, minTemp); i <= 10000; i += 500) {
|
|
temps.push(i + "K");
|
|
}
|
|
return temps;
|
|
}
|
|
onValueChanged: value => {
|
|
var temp = parseInt(value.replace("K", ""));
|
|
if (temp >= SessionData.nightModeTemperature) {
|
|
SessionData.setNightModeHighTemperature(temp);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
DankToggle {
|
|
id: automaticToggle
|
|
width: parent.width
|
|
text: I18n.tr("Automatic Control")
|
|
description: I18n.tr("Only adjust gamma based on time or location rules.")
|
|
checked: SessionData.nightModeAutoEnabled
|
|
visible: DisplayService.gammaControlAvailable
|
|
onToggled: checked => {
|
|
if (checked && !DisplayService.nightModeEnabled) {
|
|
DisplayService.toggleNightMode();
|
|
} else if (!checked && DisplayService.nightModeEnabled) {
|
|
DisplayService.toggleNightMode();
|
|
}
|
|
SessionData.setNightModeAutoEnabled(checked);
|
|
}
|
|
|
|
Connections {
|
|
target: SessionData
|
|
function onNightModeAutoEnabledChanged() {
|
|
automaticToggle.checked = SessionData.nightModeAutoEnabled;
|
|
}
|
|
}
|
|
}
|
|
|
|
Column {
|
|
id: automaticSettings
|
|
width: parent.width
|
|
spacing: Theme.spacingS
|
|
visible: SessionData.nightModeAutoEnabled && DisplayService.gammaControlAvailable
|
|
|
|
Connections {
|
|
target: SessionData
|
|
function onNightModeAutoEnabledChanged() {
|
|
automaticSettings.visible = SessionData.nightModeAutoEnabled;
|
|
}
|
|
}
|
|
|
|
Item {
|
|
width: parent.width
|
|
height: 45 + Theme.spacingM
|
|
|
|
DankTabBar {
|
|
id: modeTabBarNight
|
|
width: 200
|
|
height: 45
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
model: [
|
|
{
|
|
"text": "Time",
|
|
"icon": "access_time"
|
|
},
|
|
{
|
|
"text": "Location",
|
|
"icon": "place"
|
|
}
|
|
]
|
|
|
|
Component.onCompleted: {
|
|
currentIndex = SessionData.nightModeAutoMode === "location" ? 1 : 0;
|
|
Qt.callLater(updateIndicator);
|
|
}
|
|
|
|
onTabClicked: index => {
|
|
DisplayService.setNightModeAutomationMode(index === 1 ? "location" : "time");
|
|
currentIndex = index;
|
|
}
|
|
|
|
Connections {
|
|
target: SessionData
|
|
function onNightModeAutoModeChanged() {
|
|
modeTabBarNight.currentIndex = SessionData.nightModeAutoMode === "location" ? 1 : 0;
|
|
Qt.callLater(modeTabBarNight.updateIndicator);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Column {
|
|
width: parent.width
|
|
spacing: Theme.spacingM
|
|
visible: SessionData.nightModeAutoMode === "time"
|
|
|
|
Column {
|
|
spacing: Theme.spacingXS
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
|
|
Row {
|
|
spacing: Theme.spacingM
|
|
|
|
StyledText {
|
|
text: ""
|
|
width: 50
|
|
height: 20
|
|
}
|
|
|
|
StyledText {
|
|
text: I18n.tr("Hour")
|
|
font.pixelSize: Theme.fontSizeSmall
|
|
color: Theme.surfaceVariantText
|
|
width: 70
|
|
horizontalAlignment: Text.AlignHCenter
|
|
}
|
|
|
|
StyledText {
|
|
text: I18n.tr("Minute")
|
|
font.pixelSize: Theme.fontSizeSmall
|
|
color: Theme.surfaceVariantText
|
|
width: 70
|
|
horizontalAlignment: Text.AlignHCenter
|
|
}
|
|
}
|
|
|
|
Row {
|
|
spacing: Theme.spacingM
|
|
|
|
StyledText {
|
|
text: I18n.tr("Start")
|
|
font.pixelSize: Theme.fontSizeMedium
|
|
color: Theme.surfaceText
|
|
width: 50
|
|
height: 40
|
|
verticalAlignment: Text.AlignVCenter
|
|
}
|
|
|
|
DankDropdown {
|
|
dropdownWidth: 70
|
|
currentValue: SessionData.nightModeStartHour.toString()
|
|
options: {
|
|
var hours = [];
|
|
for (var i = 0; i < 24; i++) {
|
|
hours.push(i.toString());
|
|
}
|
|
return hours;
|
|
}
|
|
onValueChanged: value => {
|
|
SessionData.setNightModeStartHour(parseInt(value));
|
|
}
|
|
}
|
|
|
|
DankDropdown {
|
|
dropdownWidth: 70
|
|
currentValue: SessionData.nightModeStartMinute.toString().padStart(2, '0')
|
|
options: {
|
|
var minutes = [];
|
|
for (var i = 0; i < 60; i += 5) {
|
|
minutes.push(i.toString().padStart(2, '0'));
|
|
}
|
|
return minutes;
|
|
}
|
|
onValueChanged: value => {
|
|
SessionData.setNightModeStartMinute(parseInt(value));
|
|
}
|
|
}
|
|
}
|
|
|
|
Row {
|
|
spacing: Theme.spacingM
|
|
|
|
StyledText {
|
|
text: I18n.tr("End")
|
|
font.pixelSize: Theme.fontSizeMedium
|
|
color: Theme.surfaceText
|
|
width: 50
|
|
height: 40
|
|
verticalAlignment: Text.AlignVCenter
|
|
}
|
|
|
|
DankDropdown {
|
|
dropdownWidth: 70
|
|
currentValue: SessionData.nightModeEndHour.toString()
|
|
options: {
|
|
var hours = [];
|
|
for (var i = 0; i < 24; i++) {
|
|
hours.push(i.toString());
|
|
}
|
|
return hours;
|
|
}
|
|
onValueChanged: value => {
|
|
SessionData.setNightModeEndHour(parseInt(value));
|
|
}
|
|
}
|
|
|
|
DankDropdown {
|
|
dropdownWidth: 70
|
|
currentValue: SessionData.nightModeEndMinute.toString().padStart(2, '0')
|
|
options: {
|
|
var minutes = [];
|
|
for (var i = 0; i < 60; i += 5) {
|
|
minutes.push(i.toString().padStart(2, '0'));
|
|
}
|
|
return minutes;
|
|
}
|
|
onValueChanged: value => {
|
|
SessionData.setNightModeEndMinute(parseInt(value));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Column {
|
|
property bool isLocationMode: SessionData.nightModeAutoMode === "location"
|
|
visible: isLocationMode
|
|
spacing: Theme.spacingM
|
|
width: parent.width
|
|
|
|
DankToggle {
|
|
id: ipLocationToggle
|
|
width: parent.width
|
|
text: I18n.tr("Use IP Location")
|
|
description: I18n.tr("Automatically detect location based on IP address")
|
|
checked: SessionData.nightModeUseIPLocation || false
|
|
onToggled: checked => {
|
|
SessionData.setNightModeUseIPLocation(checked);
|
|
}
|
|
|
|
Connections {
|
|
target: SessionData
|
|
function onNightModeUseIPLocationChanged() {
|
|
ipLocationToggle.checked = SessionData.nightModeUseIPLocation;
|
|
}
|
|
}
|
|
}
|
|
|
|
Column {
|
|
width: parent.width
|
|
spacing: Theme.spacingM
|
|
leftPadding: Theme.spacingM
|
|
visible: !SessionData.nightModeUseIPLocation
|
|
|
|
StyledText {
|
|
text: I18n.tr("Manual Coordinates")
|
|
font.pixelSize: Theme.fontSizeMedium
|
|
color: Theme.surfaceText
|
|
}
|
|
|
|
Row {
|
|
spacing: Theme.spacingL
|
|
|
|
Column {
|
|
spacing: Theme.spacingXS
|
|
|
|
StyledText {
|
|
text: I18n.tr("Latitude")
|
|
font.pixelSize: Theme.fontSizeSmall
|
|
color: Theme.surfaceVariantText
|
|
}
|
|
|
|
DankTextField {
|
|
width: 120
|
|
height: 40
|
|
text: SessionData.latitude.toString()
|
|
placeholderText: "0.0"
|
|
onEditingFinished: {
|
|
const lat = parseFloat(text);
|
|
if (!isNaN(lat) && lat >= -90 && lat <= 90 && lat !== SessionData.latitude) {
|
|
SessionData.setLatitude(lat);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Column {
|
|
spacing: Theme.spacingXS
|
|
|
|
StyledText {
|
|
text: I18n.tr("Longitude")
|
|
font.pixelSize: Theme.fontSizeSmall
|
|
color: Theme.surfaceVariantText
|
|
}
|
|
|
|
DankTextField {
|
|
width: 120
|
|
height: 40
|
|
text: SessionData.longitude.toString()
|
|
placeholderText: "0.0"
|
|
onEditingFinished: {
|
|
const lon = parseFloat(text);
|
|
if (!isNaN(lon) && lon >= -180 && lon <= 180 && lon !== SessionData.longitude) {
|
|
SessionData.setLongitude(lon);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
StyledText {
|
|
text: I18n.tr("Uses sunrise/sunset times to automatically adjust night mode based on your location.")
|
|
font.pixelSize: Theme.fontSizeSmall
|
|
color: Theme.surfaceVariantText
|
|
width: parent.width - parent.leftPadding
|
|
wrapMode: Text.WordWrap
|
|
}
|
|
}
|
|
}
|
|
|
|
Rectangle {
|
|
width: parent.width
|
|
height: 1
|
|
color: Theme.outline
|
|
opacity: 0.2
|
|
visible: gammaStatusSection.visible
|
|
}
|
|
|
|
Column {
|
|
id: gammaStatusSection
|
|
width: parent.width
|
|
spacing: Theme.spacingM
|
|
visible: DisplayService.nightModeEnabled && DisplayService.gammaCurrentTemp > 0
|
|
|
|
Row {
|
|
width: parent.width
|
|
spacing: Theme.spacingS
|
|
|
|
DankIcon {
|
|
name: DisplayService.gammaIsDay ? "light_mode" : "dark_mode"
|
|
size: Theme.iconSizeSmall
|
|
color: Theme.primary
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
}
|
|
|
|
StyledText {
|
|
text: I18n.tr("Current Status")
|
|
font.pixelSize: Theme.fontSizeMedium
|
|
font.weight: Font.Medium
|
|
color: Theme.surfaceText
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
}
|
|
}
|
|
|
|
Row {
|
|
width: parent.width
|
|
spacing: Theme.spacingM
|
|
|
|
Rectangle {
|
|
width: (parent.width - Theme.spacingM) / 2
|
|
height: tempColumn.implicitHeight + Theme.spacingM * 2
|
|
radius: Theme.cornerRadius
|
|
color: Theme.surfaceContainerHigh
|
|
|
|
Column {
|
|
id: tempColumn
|
|
anchors.centerIn: parent
|
|
spacing: Theme.spacingXS
|
|
|
|
DankIcon {
|
|
name: "device_thermostat"
|
|
size: Theme.iconSize
|
|
color: Theme.primary
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
}
|
|
|
|
StyledText {
|
|
text: DisplayService.gammaCurrentTemp + "K"
|
|
font.pixelSize: Theme.fontSizeLarge
|
|
font.weight: Font.Medium
|
|
color: Theme.surfaceText
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
}
|
|
|
|
StyledText {
|
|
text: I18n.tr("Current Temp")
|
|
font.pixelSize: Theme.fontSizeSmall
|
|
color: Theme.surfaceVariantText
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
}
|
|
}
|
|
}
|
|
|
|
Rectangle {
|
|
width: (parent.width - Theme.spacingM) / 2
|
|
height: periodColumn.implicitHeight + Theme.spacingM * 2
|
|
radius: Theme.cornerRadius
|
|
color: Theme.surfaceContainerHigh
|
|
|
|
Column {
|
|
id: periodColumn
|
|
anchors.centerIn: parent
|
|
spacing: Theme.spacingXS
|
|
|
|
DankIcon {
|
|
name: DisplayService.gammaIsDay ? "wb_sunny" : "nightlight"
|
|
size: Theme.iconSize
|
|
color: DisplayService.gammaIsDay ? "#FFA726" : "#7E57C2"
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
}
|
|
|
|
StyledText {
|
|
text: DisplayService.gammaIsDay ? I18n.tr("Daytime") : I18n.tr("Night")
|
|
font.pixelSize: Theme.fontSizeLarge
|
|
font.weight: Font.Medium
|
|
color: Theme.surfaceText
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
}
|
|
|
|
StyledText {
|
|
text: I18n.tr("Current Period")
|
|
font.pixelSize: Theme.fontSizeSmall
|
|
color: Theme.surfaceVariantText
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Row {
|
|
width: parent.width
|
|
spacing: Theme.spacingM
|
|
visible: SessionData.nightModeAutoMode === "location" && (DisplayService.gammaSunriseTime || DisplayService.gammaSunsetTime)
|
|
|
|
Rectangle {
|
|
width: (parent.width - Theme.spacingM) / 2
|
|
height: sunriseColumn.implicitHeight + Theme.spacingM * 2
|
|
radius: Theme.cornerRadius
|
|
color: Theme.surfaceContainerHigh
|
|
visible: DisplayService.gammaSunriseTime
|
|
|
|
Column {
|
|
id: sunriseColumn
|
|
anchors.centerIn: parent
|
|
spacing: Theme.spacingXS
|
|
|
|
DankIcon {
|
|
name: "wb_twilight"
|
|
size: Theme.iconSize
|
|
color: "#FF7043"
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
}
|
|
|
|
StyledText {
|
|
text: root.formatGammaTime(DisplayService.gammaSunriseTime)
|
|
font.pixelSize: Theme.fontSizeLarge
|
|
font.weight: Font.Medium
|
|
color: Theme.surfaceText
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
}
|
|
|
|
StyledText {
|
|
text: I18n.tr("Sunrise")
|
|
font.pixelSize: Theme.fontSizeSmall
|
|
color: Theme.surfaceVariantText
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
}
|
|
}
|
|
}
|
|
|
|
Rectangle {
|
|
width: (parent.width - Theme.spacingM) / 2
|
|
height: sunsetColumn.implicitHeight + Theme.spacingM * 2
|
|
radius: Theme.cornerRadius
|
|
color: Theme.surfaceContainerHigh
|
|
visible: DisplayService.gammaSunsetTime
|
|
|
|
Column {
|
|
id: sunsetColumn
|
|
anchors.centerIn: parent
|
|
spacing: Theme.spacingXS
|
|
|
|
DankIcon {
|
|
name: "wb_twilight"
|
|
size: Theme.iconSize
|
|
color: "#5C6BC0"
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
}
|
|
|
|
StyledText {
|
|
text: root.formatGammaTime(DisplayService.gammaSunsetTime)
|
|
font.pixelSize: Theme.fontSizeLarge
|
|
font.weight: Font.Medium
|
|
color: Theme.surfaceText
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
}
|
|
|
|
StyledText {
|
|
text: I18n.tr("Sunset")
|
|
font.pixelSize: Theme.fontSizeSmall
|
|
color: Theme.surfaceVariantText
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Rectangle {
|
|
width: parent.width
|
|
height: nextChangeRow.implicitHeight + Theme.spacingM * 2
|
|
radius: Theme.cornerRadius
|
|
color: Theme.surfaceContainerHigh
|
|
visible: DisplayService.gammaNextTransition
|
|
|
|
Row {
|
|
id: nextChangeRow
|
|
anchors.centerIn: parent
|
|
spacing: Theme.spacingM
|
|
|
|
DankIcon {
|
|
name: "schedule"
|
|
size: Theme.iconSize
|
|
color: Theme.primary
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
}
|
|
|
|
Column {
|
|
spacing: 2
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
|
|
StyledText {
|
|
text: I18n.tr("Next Transition")
|
|
font.pixelSize: Theme.fontSizeSmall
|
|
color: Theme.surfaceVariantText
|
|
}
|
|
|
|
StyledText {
|
|
text: root.formatGammaTime(DisplayService.gammaNextTransition)
|
|
font.pixelSize: Theme.fontSizeMedium
|
|
font.weight: Font.Medium
|
|
color: Theme.surfaceText
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|