Files
bbedward ccbf1d38ad widgets: bump qml-common, rename Dank* prefixed widgets to D, add
deprecation notice to plugin compatibility shims

- When qml-common became a thing, we left qs.Widgets shims in place for
  plugin compatibility
- It's annoying to need to maintain them when qml-common has any change,
  add a warning so we can safely deprecate them in the future
- One shot rename the common stuff to D to make it shorter and nicer to
  write
2026-10-05 16:47:19 -04:00

354 lines
14 KiB
QML

import QtQuick
import qs.Common
import qs.Services
import qs.DCommon.Widgets
import qs.Modules.Settings.Widgets
import "../../Common/Format.js" as Format
Item {
id: root
property var desktopApps: []
property var parentModal: null
function addNightModeExcludedApp() {
const name = excludeEditor.value.trim();
if (!name)
return;
SettingsData.addNightModeExcludedApp(name);
excludeEditor.value = "";
}
Component.onCompleted: desktopApps = AppSearchService.getVisibleApplications() || []
Component.onDestruction: desktopApps = []
component StatusTile: Rectangle {
id: tile
property string iconName: ""
property color iconColor: Theme.primary
property string value: ""
property string label: ""
width: (parent.width - Theme.spacingM) / 2
height: tileColumn.implicitHeight + Theme.spacingM * 2
radius: Theme.cornerRadius
color: SettingsMetrics.controlColor
border.color: Theme.floatingWindowFieldBorderColor
border.width: Theme.outlineWidth
Column {
id: tileColumn
anchors.centerIn: parent
spacing: Theme.spacingXS
DIcon {
name: tile.iconName
size: Theme.iconSize
color: tile.iconColor
anchors.horizontalCenter: parent.horizontalCenter
}
StyledText {
text: tile.value
font.pixelSize: Theme.fontSizeLarge
font.weight: Theme.fontWeightMedium
color: Theme.surfaceText
anchors.horizontalCenter: parent.horizontalCenter
}
StyledText {
text: tile.label
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
anchors.horizontalCenter: parent.horizontalCenter
}
}
}
SettingsPage {
id: mainColumn
SettingsCard {
visible: NightModeService.gammaAdjustAvailable
SettingsSliderRow {
settingKey: "displayGamma"
resetStore: SessionData
resetKeys: ["displayGamma"]
tags: ["gamma", "display", "panel", "washed out", "brightness"]
text: I18n.tr("Gamma")
minimum: 50
maximum: 200
step: 5
unit: ""
decimals: 2
value: Math.round(SessionData.displayGamma * 100)
onSliderValueChanged: newValue => NightModeService.setDisplayGamma(newValue / 100)
}
SettingsSliderRow {
settingKey: "displayContrast"
resetStore: SessionData
resetKeys: ["displayContrast"]
tags: ["contrast", "display", "panel", "washed out"]
text: I18n.tr("Contrast")
minimum: 50
maximum: 200
step: 5
value: Math.round(SessionData.displayContrast * 100)
onSliderValueChanged: newValue => NightModeService.setDisplayContrast(newValue / 100)
}
}
SettingsCard {
SettingsToggleRow {
text: I18n.tr("Night mode")
description: NightModeService.gammaControlAvailable ? "" : I18n.tr("Gamma control not available. Requires DMS API v6+.")
checked: NightModeService.nightModeEnabled
enabled: NightModeService.gammaControlAvailable
onToggled: NightModeService.toggleNightMode()
}
SettingsSliderRow {
settingKey: "nightModeTemperature"
resetStore: SessionData
resetKeys: ["nightModeTemperature"]
tags: ["gamma", "night", "temperature", "kelvin", "warm", "color", "blue light"]
visible: NightModeService.gammaControlAvailable
text: SessionData.nightModeAutoEnabled ? I18n.tr("Night temperature") : I18n.tr("Color Temperature", "Color Temperature")
minimum: 1000
maximum: 6000
step: 100
unit: "K"
value: SessionData.nightModeTemperature
onSliderValueChanged: newValue => {
SessionData.setNightModeTemperature(newValue);
if (SessionData.nightModeHighTemperature < newValue)
SessionData.setNightModeHighTemperature(newValue);
}
}
SettingsSliderRow {
settingKey: "nightModeHighTemperature"
resetStore: SessionData
resetKeys: ["nightModeHighTemperature"]
tags: ["gamma", "day", "temperature", "kelvin", "color"]
visible: NightModeService.gammaControlAvailable && SessionData.nightModeAutoEnabled
text: I18n.tr("Day temperature")
minimum: SessionData.nightModeTemperature
maximum: 10000
step: 100
unit: "K"
value: Math.max(SessionData.nightModeHighTemperature, SessionData.nightModeTemperature)
onSliderValueChanged: newValue => SessionData.setNightModeHighTemperature(newValue)
}
SettingsToggleRow {
text: I18n.tr("Automatic control")
checked: SessionData.nightModeAutoEnabled
visible: NightModeService.gammaControlAvailable
onToggled: checked => {
if (checked !== NightModeService.nightModeEnabled)
NightModeService.toggleNightMode();
SessionData.setNightModeAutoEnabled(checked);
}
}
}
SettingsCard {
visible: SessionData.nightModeAutoEnabled && NightModeService.gammaControlAvailable
SettingsButtonGroupRow {
id: autoModeGroup
readonly property bool locationMode: SessionData.nightModeAutoMode === "location"
text: I18n.tr("Mode", "noun, setting label, e.g. wallpaper cycling mode, wifi mode, display mode")
model: [I18n.tr("Time"), I18n.tr("Location")]
currentIndex: locationMode ? 1 : 0
onLocationModeChanged: currentIndex = locationMode ? 1 : 0
onSelectionChanged: (index, selected) => {
if (!selected)
return;
SessionData.setNightModeAutoMode(index === 1 ? "location" : "time");
}
}
SettingsTimeRow {
visible: !autoModeGroup.locationMode
is24Hour: SettingsData.use24HourClock
startTitle: I18n.tr("Start")
startHour: SessionData.nightModeStartHour
startMinute: SessionData.nightModeStartMinute
endTitle: I18n.tr("End", "noun, end time label for night mode schedule or calendar event")
endHour: SessionData.nightModeEndHour
endMinute: SessionData.nightModeEndMinute
onStartChanged: (hour, minute) => {
SessionData.setNightModeStartHour(hour);
SessionData.setNightModeStartMinute(minute);
}
onEndChanged: (hour, minute) => {
SessionData.setNightModeEndHour(hour);
SessionData.setNightModeEndMinute(minute);
}
}
SettingsSliderRow {
settingKey: "nightModeTransitionMinutes"
resetStore: SessionData
resetKeys: ["nightModeTransitionMinutes"]
tags: ["gamma", "night", "transition", "duration", "fade"]
text: I18n.tr("Transition duration")
minimum: 0
maximum: 180
step: 5
unit: "min"
value: SessionData.nightModeTransitionMinutes
visible: !autoModeGroup.locationMode && DMSService.apiVersion >= 32
onSliderValueChanged: newValue => SessionData.setNightModeTransitionMinutes(newValue)
}
SettingsLocationSection {
visible: autoModeGroup.locationMode
description: ""
}
}
SettingsCard {
title: I18n.tr("Current status")
visible: SessionData.nightModeAutoEnabled && NightModeService.gammaControlAvailable && NightModeService.nightModeEnabled && NightModeService.gammaCurrentTemp > 0
Column {
spacing: Theme.spacingM
Row {
width: parent.width
spacing: Theme.spacingM
StatusTile {
iconName: "device_thermostat"
value: NightModeService.gammaCurrentTemp + "K"
label: I18n.tr("Current temperature")
}
StatusTile {
iconName: NightModeService.gammaIsDay ? "wb_sunny" : "nightlight"
iconColor: NightModeService.gammaIsDay ? Theme.warning : Theme.secondary
value: NightModeService.gammaIsDay ? I18n.tr("Daytime", "night mode status label, current period is day") : I18n.tr("Night")
label: I18n.tr("Current period")
}
}
Row {
width: parent.width
spacing: Theme.spacingM
visible: autoModeGroup.locationMode && (NightModeService.gammaSunriseTime || NightModeService.gammaSunsetTime)
StatusTile {
visible: NightModeService.gammaSunriseTime
iconName: "wb_twilight"
iconColor: Theme.warning
value: Format.formatIsoTime(NightModeService.gammaSunriseTime)
label: I18n.tr("Sunrise")
}
StatusTile {
visible: NightModeService.gammaSunsetTime
iconName: "wb_twilight"
iconColor: Theme.secondary
value: Format.formatIsoTime(NightModeService.gammaSunsetTime)
label: I18n.tr("Sunset")
}
}
}
SettingsRow {
visible: NightModeService.gammaNextTransition
iconName: "schedule"
title: I18n.tr("Next Transition")
subtitle: Format.formatIsoTime(NightModeService.gammaNextTransition)
}
}
SettingsCard {
iconName: "settings_night_sight"
title: I18n.tr("Night mode exceptions", "settings card title: windows and apps that pause night mode while focused")
settingKey: "nightModeExceptions"
tags: ["gamma", "night", "mode", "fullscreen", "app", "media", "exceptions", "exclude", "ignore"]
visible: NightModeService.gammaControlAvailable
collapsible: true
expanded: false
SettingsToggleRow {
settingKey: "nightModeExcludeFullscreen"
text: I18n.tr("Fullscreen windows", "night mode exceptions toggle: pause while a fullscreen window is focused")
description: I18n.tr("Pause night mode while a fullscreen window has focus", "night mode exceptions toggle description")
checked: SettingsData.nightModeExcludeFullscreen
onToggled: checked => SettingsData.set("nightModeExcludeFullscreen", checked)
}
SettingsTextFieldRow {
id: excludeEditor
leftIconName: "apps"
text: I18n.tr("Excluded apps", "night mode exceptions: list of apps that pause night mode while focused")
description: I18n.tr("Pause night mode while one of these apps has focus", "night mode excluded apps field description")
placeholderText: I18n.tr("App name or identity (e.g., firefox)")
onAccepted: root.addNightModeExcludedApp()
actions: [
DIconButton {
variant: "filled"
iconName: "add"
Accessible.name: I18n.tr("Add")
enabled: excludeEditor.value.trim() !== ""
onClicked: root.addNightModeExcludedApp()
},
DIconButton {
iconName: "apps"
tooltipText: I18n.tr("Browse")
onClicked: appBrowserPopup.show()
}
]
}
Repeater {
model: SettingsData.nightModeExcludedApps
delegate: SettingsRow {
required property string modelData
required property int index
title: modelData
iconName: "bedtime_off"
DActionButton {
anchors.verticalCenter: parent.verticalCenter
iconName: "delete"
iconColor: Theme.error
Accessible.name: I18n.tr("Remove")
onClicked: SettingsData.removeNightModeExcludedApp(index)
}
}
}
SettingsRow {
visible: !SettingsData.nightModeExcludedApps?.length
title: I18n.tr("No excluded apps configured", "night mode exceptions empty list placeholder")
titleColor: Theme.surfaceVariantText
}
}
}
AppBrowserPopup {
id: appBrowserPopup
appsModel: root.desktopApps
parentModal: root.parentModal
onAppSelected: appId => {
var name = appId;
if (name.endsWith(".desktop")) {
name = name.slice(0, -8);
}
SettingsData.addNightModeExcludedApp(name);
}
}
}