settings: align nested rows and page widths to shared spacing

This commit is contained in:
bbedward
2026-09-22 14:19:41 -04:00
parent 17d52d3c88
commit abd51287f3
11 changed files with 337 additions and 928 deletions
+1 -3
View File
@@ -11,8 +11,6 @@ import qs.Modules.Settings.Widgets
Item {
id: root
readonly property int contentMaxWidth: 550
readonly property var log: Log.scoped("AutoStartTab")
property var parentModal: null
property var entries: []
@@ -371,7 +369,7 @@ Item {
Column {
id: mainColumn
topPadding: Theme.spacingXS
width: Math.min(root.contentMaxWidth, parent.width - Theme.spacingL * 2)
width: Math.min(SettingsMetrics.contentMaxWidth, parent.width - Theme.spacingL * 2)
anchors.horizontalCenter: parent.horizontalCenter
spacing: Theme.spacingXL
visible: DesktopService.autostartAvailable
+1 -2
View File
@@ -79,8 +79,7 @@ done
SettingsRow {
body: Column {
width: parent.width - Theme.spacingM * 2
x: Theme.spacingM
width: parent.width
spacing: Theme.spacingM
Row {
+12 -19
View File
@@ -364,26 +364,19 @@ Item {
hoverPopouts: checked
})
Column {
width: parent.width
spacing: Theme.spacingS
SettingsSliderRow {
visible: bar.selectedBarConfig?.hoverPopouts ?? false
leftPadding: Theme.spacingM
SettingsSliderRow {
width: parent.width - parent.leftPadding
text: I18n.tr("Open delay")
resetStore: bar
resetKeys: ["hoverPopoutDelay"]
value: bar.selectedBarConfig?.hoverPopoutDelay ?? 150
minimum: 0
maximum: 1000
unit: "ms"
onSliderValueChanged: newValue => {
SettingsData.updateBarConfig(bar.selectedBarId, {
hoverPopoutDelay: newValue
});
}
text: I18n.tr("Open delay")
resetStore: bar
resetKeys: ["hoverPopoutDelay"]
value: bar.selectedBarConfig?.hoverPopoutDelay ?? 150
minimum: 0
maximum: 1000
unit: "ms"
onSliderValueChanged: newValue => {
SettingsData.updateBarConfig(bar.selectedBarId, {
hoverPopoutDelay: newValue
});
}
}
}
@@ -95,8 +95,7 @@ Item {
SettingsRow {
body: Column {
width: parent.width - Theme.spacingM * 2
x: Theme.spacingM
width: parent.width
spacing: Theme.spacingM
Row {
@@ -129,8 +128,7 @@ Item {
SettingsRow {
body: Column {
width: parent.width - Theme.spacingM * 2
x: Theme.spacingM
width: parent.width
spacing: Theme.spacingM
Row {
@@ -344,8 +342,7 @@ Item {
SettingsRow {
body: Column {
width: parent.width - Theme.spacingM * 2
x: Theme.spacingM
width: parent.width
spacing: Theme.spacingM
Row {
+51 -392
View File
@@ -1,5 +1,4 @@
import QtQuick
import QtQuick.Layouts
import Quickshell
import qs.Common
import qs.Modules.Settings.Widgets
@@ -15,12 +14,9 @@ Item {
function getBarComponentsFromSettings() {
const bars = SettingsData.barConfigs || [];
return bars.map(bar => {
const isIsland = SettingsData.isIslandBarConfig(bar);
return {
"id": "bar:" + bar.id,
"name": bar.name || "Bar",
"description": isIsland ? I18n.tr("Dank Island instance") : I18n.tr("Individual bar configuration"),
"icon": isIsland ? "view_in_ar" : "toolbar",
"barId": bar.id
};
});
@@ -32,28 +28,23 @@ Item {
return [...getBarComponentsFromSettings(),
{
"id": "notifications",
"name": I18n.tr("Notification popups"),
"icon": "notifications"
"name": I18n.tr("Notification popups")
},
{
"id": "wallpaper",
"name": I18n.tr("Wallpaper"),
"icon": "wallpaper"
"name": I18n.tr("Wallpaper")
},
{
"id": "osd",
"name": I18n.tr("OSD", "on-screen display, shell component name in per-display settings"),
"icon": "picture_in_picture"
"name": I18n.tr("OSD", "on-screen display, shell component name in per-display settings")
},
{
"id": "toast",
"name": I18n.tr("Toasts", "noun plural, toast popups, shell component name in per-display settings"),
"icon": "campaign"
"name": I18n.tr("Toasts", "noun plural, toast popups, shell component name in per-display settings")
},
{
"id": "notepad",
"name": I18n.tr("Notepad"),
"icon": "sticky_note_2"
"name": I18n.tr("Notepad")
}
];
}
@@ -114,398 +105,66 @@ Item {
SettingsPage {
id: mainColumn
StyledRect {
width: parent.width
height: screensInfoSection.implicitHeight + Theme.spacingL * 2
radius: Theme.cornerRadius
color: Theme.floatingWindowNestedSurface
border.color: Theme.outlineMedium
border.width: Theme.layerOutlineWidth
SettingsCard {
title: I18n.tr("Available displays (%1)", "display widgets settings heading, %1 is the monitor count").arg(Quickshell.screens.length)
Column {
id: screensInfoSection
anchors.fill: parent
anchors.margins: Theme.spacingL
spacing: Theme.spacingM
Row {
width: parent.width
spacing: Theme.spacingM
DankIcon {
name: "monitor"
size: Theme.iconSize
color: Theme.primary
anchors.verticalCenter: parent.verticalCenter
}
Column {
width: parent.width - Theme.iconSize - Theme.spacingM
spacing: Theme.spacingXS
anchors.verticalCenter: parent.verticalCenter
StyledText {
text: I18n.tr("Connected displays")
font.pixelSize: Theme.fontSizeLarge
font.weight: Theme.fontWeightMedium
color: Theme.surfaceText
width: parent.width
horizontalAlignment: Text.AlignLeft
}
}
SettingsButtonGroupRow {
id: displayModeGroup
readonly property bool modelMode: SettingsData.displayNameMode === "model"
text: I18n.tr("Name format")
model: [I18n.tr("Name"), I18n.tr("Model")]
currentIndex: modelMode ? 1 : 0
onModelModeChanged: currentIndex = modelMode ? 1 : 0
onSelectionChanged: (index, selected) => {
if (!selected)
return;
SettingsData.displayNameMode = index === 1 ? "model" : "system";
SettingsData.saveSettings();
}
}
Column {
width: parent.width
spacing: Theme.spacingS
Repeater {
model: Quickshell.screens
Column {
width: parent.width
spacing: Theme.spacingXS
SettingsRow {
required property var modelData
readonly property var currentMode: WlrOutputService.wlrOutputAvailable ? WlrOutputService.getOutput(modelData.name)?.currentMode : null
Row {
width: parent.width
spacing: Theme.spacingM
StyledText {
text: I18n.tr("Available displays (%1)", "display widgets settings heading, %1 is the monitor count").arg(Quickshell.screens.length)
font.pixelSize: Theme.fontSizeMedium
font.weight: Theme.fontWeightMedium
color: Theme.surfaceText
horizontalAlignment: Text.AlignLeft
}
Item {
width: 1
height: 1
Layout.fillWidth: true
}
Column {
spacing: Theme.spacingXS
anchors.verticalCenter: parent.verticalCenter
StyledText {
text: I18n.tr("Name format")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
anchors.horizontalCenter: parent.horizontalCenter
}
DankButtonGroup {
id: displayModeGroup
model: [I18n.tr("Name"), I18n.tr("Model")]
currentIndex: SettingsData.displayNameMode === "model" ? 1 : 0
onSelectionChanged: (index, selected) => {
if (!selected)
return;
SettingsData.displayNameMode = index === 1 ? "model" : "system";
SettingsData.saveSettings();
}
Connections {
target: SettingsData
function onDisplayNameModeChanged() {
displayModeGroup.currentIndex = SettingsData.displayNameMode === "model" ? 1 : 0;
}
}
}
}
}
}
Repeater {
model: Quickshell.screens
delegate: Rectangle {
width: parent.width
height: screenRow.implicitHeight + Theme.spacingS * 2
radius: Theme.cornerRadius
color: Theme.floatingWindowNestedSurface
border.color: Theme.outlineMedium
border.width: Theme.layerOutlineWidth
Row {
id: screenRow
anchors.fill: parent
anchors.margins: Theme.spacingS
spacing: Theme.spacingM
DankIcon {
name: "desktop_windows"
size: Theme.iconSizeMedium
color: Theme.primary
anchors.verticalCenter: parent.verticalCenter
}
Column {
width: parent.width - Theme.iconSize - Theme.spacingM * 2
anchors.verticalCenter: parent.verticalCenter
spacing: Theme.spacingXS / 2
StyledText {
text: SettingsData.getScreenDisplayName(modelData)
font.pixelSize: Theme.fontSizeMedium
font.weight: Theme.fontWeightMedium
color: Theme.surfaceText
width: parent.width
horizontalAlignment: Text.AlignLeft
}
Row {
width: parent.width
spacing: Theme.spacingS
property var wlrOutput: WlrOutputService.wlrOutputAvailable ? WlrOutputService.getOutput(modelData.name) : null
property var currentMode: wlrOutput?.currentMode
StyledText {
text: {
if (parent.currentMode) {
return parent.currentMode.width + "×" + parent.currentMode.height + "@" + Math.round(parent.currentMode.refresh / 1000) + "Hz";
}
return modelData.width + "×" + modelData.height;
}
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
}
StyledText {
text: "•"
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
}
StyledText {
text: SettingsData.displayNameMode === "system" ? (modelData.model || "Unknown Model") : modelData.name
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
}
}
}
}
}
iconName: "desktop_windows"
title: SettingsData.getScreenDisplayName(modelData)
subtitle: {
const size = currentMode ? currentMode.width + "×" + currentMode.height + "@" + Math.round(currentMode.refresh / 1000) + "Hz" : modelData.width + "×" + modelData.height;
return size + " · " + (SettingsData.displayNameMode === "system" ? (modelData.model || I18n.tr("Unknown Model")) : modelData.name);
}
}
}
}
Column {
width: parent.width
spacing: Theme.spacingL
Repeater {
model: root.variantComponents
Repeater {
model: root.variantComponents
SettingsCard {
id: componentCard
required property var modelData
delegate: StyledRect {
width: parent.width
height: componentSection.implicitHeight + Theme.spacingL * 2
radius: Theme.cornerRadius
color: Theme.floatingWindowNestedSurface
border.color: Theme.outlineMedium
border.width: Theme.layerOutlineWidth
title: modelData.name
Column {
id: componentSection
SettingsDisplayPicker {
displayPreferences: root.getScreenPreferences(componentCard.modelData.id)
emptyMeansAll: false
allowEmpty: true
showLastDisplay: ["notifications", "osd", "toast", "notepad"].includes(componentCard.modelData.id) || componentCard.modelData.id.startsWith("bar:")
showOnLastDisplay: root.getShowOnLastDisplay(componentCard.modelData.id)
onPreferencesChanged: prefs => root.setScreenPreferences(componentCard.modelData.id, prefs)
onLastDisplayToggled: checked => root.setShowOnLastDisplay(componentCard.modelData.id, checked)
}
anchors.fill: parent
anchors.margins: Theme.spacingL
spacing: Theme.spacingM
Row {
width: parent.width
spacing: Theme.spacingM
DankIcon {
name: modelData.icon
size: Theme.iconSize
color: Theme.primary
anchors.verticalCenter: parent.verticalCenter
}
Column {
width: parent.width - Theme.iconSize - Theme.spacingM
spacing: Theme.spacingXS
anchors.verticalCenter: parent.verticalCenter
StyledText {
text: modelData.name
font.pixelSize: Theme.fontSizeLarge
font.weight: Theme.fontWeightMedium
color: Theme.surfaceText
width: parent.width
horizontalAlignment: Text.AlignLeft
}
StyledText {
visible: text !== ""
text: modelData.description ?? ""
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
wrapMode: Text.WordWrap
width: parent.width
horizontalAlignment: Text.AlignLeft
}
}
}
SettingsDisplayPicker {
readonly property string componentId: modelData.id
visible: componentId !== "dock"
displayPreferences: root.getScreenPreferences(componentId)
emptyMeansAll: false
allowEmpty: true
showLastDisplay: ["dankBar", "notifications", "osd", "toast", "notepad"].includes(componentId) || componentId.startsWith("bar:")
showOnLastDisplay: root.getShowOnLastDisplay(componentId)
onPreferencesChanged: prefs => root.setScreenPreferences(componentId, prefs)
onLastDisplayToggled: checked => root.setShowOnLastDisplay(componentId, checked)
}
SettingsToggleRow {
resetKeys: ["notificationFocusedMonitor"]
visible: modelData.id === "notifications"
text: I18n.tr("Focused display only")
checked: SettingsData.notificationFocusedMonitor
onToggled: checked => SettingsData.set("notificationFocusedMonitor", checked)
}
Column {
visible: modelData.id === "dock"
width: parent.width
spacing: Theme.spacingS
StyledText {
text: I18n.tr("Show on displays") + ":"
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
font.weight: Theme.fontWeightMedium
width: parent.width
horizontalAlignment: Text.AlignLeft
}
Column {
property string componentId: modelData.id
width: parent.width
spacing: Theme.spacingXS
DankToggle {
width: parent.width
text: I18n.tr("All displays")
checked: {
var prefs = root.getScreenPreferences(parent.componentId);
return prefs.includes("all") || (typeof prefs[0] === "string" && prefs[0] === "all");
}
onToggled: checked => {
if (checked) {
root.setScreenPreferences(parent.componentId, ["all"]);
} else {
root.setScreenPreferences(parent.componentId, []);
const cid = parent.componentId;
if (["dankBar", "notifications", "osd", "toast"].includes(cid) || cid.startsWith("bar:")) {
root.setShowOnLastDisplay(cid, true);
}
}
}
}
DankToggle {
width: parent.width
text: I18n.tr("Focused display only")
visible: parent.componentId === "notifications"
checked: SettingsData.notificationFocusedMonitor
onToggled: checked => SettingsData.set("notificationFocusedMonitor", checked)
}
DankToggle {
width: parent.width
text: I18n.tr("Show on last display")
checked: root.getShowOnLastDisplay(parent.componentId)
visible: {
const prefs = root.getScreenPreferences(parent.componentId);
const isAll = prefs.includes("all") || (typeof prefs[0] === "string" && prefs[0] === "all");
const cid = parent.componentId;
const isRelevantComponent = ["dankBar", "notifications", "osd", "toast", "notepad"].includes(cid) || cid.startsWith("bar:");
return !isAll && isRelevantComponent;
}
onToggled: checked => {
root.setShowOnLastDisplay(parent.componentId, checked);
}
}
Rectangle {
width: parent.width
height: 1
color: Theme.outline
opacity: 0.2
visible: {
var prefs = root.getScreenPreferences(parent.componentId);
return !prefs.includes("all") && !(typeof prefs[0] === "string" && prefs[0] === "all");
}
}
Column {
width: parent.width
spacing: Theme.spacingXS
visible: {
var prefs = root.getScreenPreferences(parent.componentId);
return !prefs.includes("all") && !(typeof prefs[0] === "string" && prefs[0] === "all");
}
Repeater {
model: Quickshell.screens
delegate: DankToggle {
property var screenData: modelData
property string componentId: parent.parent.componentId
width: parent.width
text: SettingsData.getScreenDisplayName(screenData)
description: screenData.width + "×" + screenData.height + " • " + (SettingsData.displayNameMode === "system" ? (screenData.model || "Unknown Model") : screenData.name)
checked: {
var prefs = root.getScreenPreferences(componentId);
if (typeof prefs[0] === "string" && prefs[0] === "all")
return false;
return SettingsData.isScreenInPreferences(screenData, prefs);
}
onToggled: checked => {
var currentPrefs = root.getScreenPreferences(componentId);
if (typeof currentPrefs[0] === "string" && currentPrefs[0] === "all") {
currentPrefs = [];
}
const screenModelIndex = SettingsData.getScreenModelIndex(screenData);
var newPrefs = currentPrefs.filter(pref => {
if (typeof pref === "string")
return false;
if (pref.modelIndex !== undefined && screenModelIndex >= 0) {
return !(pref.model === screenData.model && pref.modelIndex === screenModelIndex);
}
return pref.name !== screenData.name || pref.model !== screenData.model;
});
if (checked) {
const prefObj = {
"name": screenData.name,
"model": screenData.model || ""
};
if (screenModelIndex >= 0) {
prefObj.modelIndex = screenModelIndex;
}
newPrefs.push(prefObj);
}
root.setScreenPreferences(componentId, newPrefs);
}
}
}
}
}
}
}
SettingsToggleRow {
resetKeys: ["notificationFocusedMonitor"]
visible: componentCard.modelData.id === "notifications"
text: I18n.tr("Focused display only")
checked: SettingsData.notificationFocusedMonitor
onToggled: checked => SettingsData.set("notificationFocusedMonitor", checked)
}
}
}
+224 -456
View File
@@ -8,482 +8,250 @@ import "../../Common/Format.js" as Format
Item {
id: root
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: Theme.floatingWindowNestedSurface
border.color: Theme.outlineMedium
border.width: Theme.layerOutlineWidth
Column {
id: tileColumn
anchors.centerIn: parent
spacing: Theme.spacingXS
DankIcon {
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
StyledRect {
width: parent.width
height: gammaSection.implicitHeight + Theme.spacingL * 2
radius: Theme.cornerRadius
color: Theme.floatingWindowNestedSurface
border.color: Theme.outlineMedium
border.width: Theme.layerOutlineWidth
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 {
id: gammaSection
anchors.fill: parent
anchors.margins: Theme.spacingL
spacing: Theme.spacingM
Column {
Row {
width: parent.width
spacing: Theme.spacingS
leftPadding: Theme.spacingM
rightPadding: Theme.spacingM
visible: NightModeService.gammaAdjustAvailable
spacing: Theme.spacingM
SettingsSliderRow {
settingKey: "displayGamma"
resetStore: SessionData
resetKeys: ["displayGamma"]
tags: ["gamma", "display", "panel", "washed out", "brightness"]
width: parent.width - parent.leftPadding - parent.rightPadding
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)
StatusTile {
iconName: "device_thermostat"
value: NightModeService.gammaCurrentTemp + "K"
label: I18n.tr("Current temperature")
}
SettingsSliderRow {
settingKey: "displayContrast"
resetStore: SessionData
resetKeys: ["displayContrast"]
tags: ["contrast", "display", "panel", "washed out"]
width: parent.width - parent.leftPadding - parent.rightPadding
text: I18n.tr("Contrast")
minimum: 50
maximum: 200
step: 5
value: Math.round(SessionData.displayContrast * 100)
onSliderValueChanged: newValue => NightModeService.setDisplayContrast(newValue / 100)
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")
}
}
DankToggle {
id: nightModeToggle
Row {
width: parent.width
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: checked => {
NightModeService.toggleNightMode();
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")
}
Connections {
function onNightModeEnabledChanged() {
nightModeToggle.checked = NightModeService.nightModeEnabled;
}
target: NightModeService
StatusTile {
visible: NightModeService.gammaSunsetTime
iconName: "wb_twilight"
iconColor: Theme.secondary
value: Format.formatIsoTime(NightModeService.gammaSunsetTime)
label: I18n.tr("Sunset")
}
}
}
Column {
width: parent.width
spacing: Theme.spacingS
leftPadding: Theme.spacingM
rightPadding: Theme.spacingM
visible: NightModeService.gammaControlAvailable
SettingsSliderRow {
id: nightTempSlider
settingKey: "nightModeTemperature"
resetStore: SessionData
resetKeys: ["nightModeTemperature"]
tags: ["gamma", "night", "temperature", "kelvin", "warm", "color", "blue light"]
width: parent.width - parent.leftPadding - parent.rightPadding
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 {
id: dayTempSlider
settingKey: "nightModeHighTemperature"
resetStore: SessionData
resetKeys: ["nightModeHighTemperature"]
tags: ["gamma", "day", "temperature", "kelvin", "color"]
width: parent.width - parent.leftPadding - parent.rightPadding
text: I18n.tr("Day temperature")
minimum: SessionData.nightModeTemperature
maximum: 10000
step: 100
unit: "K"
value: Math.max(SessionData.nightModeHighTemperature, SessionData.nightModeTemperature)
visible: SessionData.nightModeAutoEnabled
onSliderValueChanged: newValue => SessionData.setNightModeHighTemperature(newValue)
}
}
DankToggle {
id: automaticToggle
width: parent.width
text: I18n.tr("Automatic control")
checked: SessionData.nightModeAutoEnabled
visible: NightModeService.gammaControlAvailable
onToggled: checked => {
if (checked && !NightModeService.nightModeEnabled) {
NightModeService.toggleNightMode();
} else if (!checked && NightModeService.nightModeEnabled) {
NightModeService.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 && NightModeService.gammaControlAvailable
Connections {
target: SessionData
function onNightModeAutoEnabledChanged() {
automaticSettings.visible = SessionData.nightModeAutoEnabled;
}
}
Item {
width: parent.width
height: modeTabBarNight.height + Theme.spacingM
DankTabBar {
id: modeTabBarNight
width: 200
tabHeight: 45
anchors.horizontalCenter: parent.horizontalCenter
model: [
{
"text": I18n.tr("Time"),
"icon": "access_time"
},
{
"text": I18n.tr("Location"),
"icon": "place"
}
]
Component.onCompleted: {
currentIndex = SessionData.nightModeAutoMode === "location" ? 1 : 0;
Qt.callLater(updateIndicator);
}
onTabClicked: index => {
SessionData.setNightModeAutoMode(index === 1 ? "location" : "time");
currentIndex = index;
}
Connections {
target: SessionData
function onNightModeAutoModeChanged() {
modeTabBarNight.currentIndex = SessionData.nightModeAutoMode === "location" ? 1 : 0;
Qt.callLater(modeTabBarNight.updateIndicator);
}
}
}
}
SettingsTimeRow {
visible: SessionData.nightModeAutoMode === "time"
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"]
width: parent.width
text: I18n.tr("Transition duration")
minimum: 0
maximum: 180
step: 5
unit: "min"
value: SessionData.nightModeTransitionMinutes
visible: (SessionData.nightModeAutoMode === "time") && (DMSService.apiVersion >= 32)
onSliderValueChanged: newValue => SessionData.setNightModeTransitionMinutes(newValue)
}
SettingsLocationSection {
width: parent.width
visible: SessionData.nightModeAutoMode === "location"
description: ""
}
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: NightModeService.nightModeEnabled && NightModeService.gammaCurrentTemp > 0
Row {
width: parent.width
spacing: Theme.spacingS
DankIcon {
name: NightModeService.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: Theme.fontWeightMedium
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.floatingWindowNestedSurface
border.color: Theme.outlineMedium
border.width: Theme.layerOutlineWidth
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: NightModeService.gammaCurrentTemp + "K"
font.pixelSize: Theme.fontSizeLarge
font.weight: Theme.fontWeightMedium
color: Theme.surfaceText
anchors.horizontalCenter: parent.horizontalCenter
}
StyledText {
text: I18n.tr("Current temperature")
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.floatingWindowNestedSurface
border.color: Theme.outlineMedium
border.width: Theme.layerOutlineWidth
Column {
id: periodColumn
anchors.centerIn: parent
spacing: Theme.spacingXS
DankIcon {
name: NightModeService.gammaIsDay ? "wb_sunny" : "nightlight"
size: Theme.iconSize
color: NightModeService.gammaIsDay ? "#FFA726" : "#7E57C2"
anchors.horizontalCenter: parent.horizontalCenter
}
StyledText {
text: NightModeService.gammaIsDay ? I18n.tr("Daytime", "night mode status label, current period is day") : I18n.tr("Night")
font.pixelSize: Theme.fontSizeLarge
font.weight: Theme.fontWeightMedium
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" && (NightModeService.gammaSunriseTime || NightModeService.gammaSunsetTime)
Rectangle {
width: (parent.width - Theme.spacingM) / 2
height: sunriseColumn.implicitHeight + Theme.spacingM * 2
radius: Theme.cornerRadius
color: Theme.floatingWindowNestedSurface
border.color: Theme.outlineMedium
border.width: Theme.layerOutlineWidth
visible: NightModeService.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: Format.formatIsoTime(NightModeService.gammaSunriseTime)
font.pixelSize: Theme.fontSizeLarge
font.weight: Theme.fontWeightMedium
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.floatingWindowNestedSurface
border.color: Theme.outlineMedium
border.width: Theme.layerOutlineWidth
visible: NightModeService.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: Format.formatIsoTime(NightModeService.gammaSunsetTime)
font.pixelSize: Theme.fontSizeLarge
font.weight: Theme.fontWeightMedium
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.floatingWindowNestedSurface
border.color: Theme.outlineMedium
border.width: Theme.layerOutlineWidth
visible: NightModeService.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: Theme.spacingXXS
anchors.verticalCenter: parent.verticalCenter
StyledText {
text: I18n.tr("Next Transition")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
}
StyledText {
text: Format.formatIsoTime(NightModeService.gammaNextTransition)
font.pixelSize: Theme.fontSizeMedium
font.weight: Theme.fontWeightMedium
color: Theme.surfaceText
}
}
}
}
}
}
SettingsRow {
visible: NightModeService.gammaNextTransition
iconName: "schedule"
title: I18n.tr("Next Transition")
subtitle: Format.formatIsoTime(NightModeService.gammaNextTransition)
}
}
}
+7 -9
View File
@@ -11,8 +11,6 @@ import qs.Widgets
Item {
id: keybindsTab
readonly property int contentMaxWidth: 650
LayoutMirroring.enabled: I18n.isRtl
LayoutMirroring.childrenInherit: true
@@ -472,7 +470,7 @@ Item {
bottomPadding: Theme.spacingXL
StyledRect {
width: Math.min(keybindsTab.contentMaxWidth, parent.width - Theme.spacingL * 2)
width: Math.min(SettingsMetrics.contentMaxWidth, parent.width - Theme.spacingL * 2)
height: headerSection.implicitHeight + Theme.spacingL * 2
anchors.horizontalCenter: parent.horizontalCenter
radius: Theme.cornerRadius
@@ -557,7 +555,7 @@ Item {
StyledRect {
id: warningBox
width: Math.min(keybindsTab.contentMaxWidth, parent.width - Theme.spacingL * 2)
width: Math.min(SettingsMetrics.contentMaxWidth, parent.width - Theme.spacingL * 2)
height: warningSection.implicitHeight + Theme.spacingL * 2
anchors.horizontalCenter: parent.horizontalCenter
radius: Theme.cornerRadius
@@ -646,7 +644,7 @@ Item {
}
StyledRect {
width: Math.min(keybindsTab.contentMaxWidth, parent.width - Theme.spacingL * 2)
width: Math.min(SettingsMetrics.contentMaxWidth, parent.width - Theme.spacingL * 2)
height: categorySection.implicitHeight + Theme.spacingL * 2
anchors.horizontalCenter: parent.horizontalCenter
radius: Theme.cornerRadius
@@ -727,7 +725,7 @@ Item {
}
SettingsGroup {
width: Math.min(keybindsTab.contentMaxWidth, parent.width - Theme.spacingL * 2)
width: Math.min(SettingsMetrics.contentMaxWidth, parent.width - Theme.spacingL * 2)
anchors.horizontalCenter: parent.horizontalCenter
visible: keybindsTab.hasEditDraft && (keybindsTab.reviewingEdit || keybindsTab.editError !== "" || keybindsTab.editDraft.operation !== "set")
@@ -788,7 +786,7 @@ Item {
}
StyledRect {
width: Math.min(keybindsTab.contentMaxWidth, parent.width - Theme.spacingL * 2)
width: Math.min(SettingsMetrics.contentMaxWidth, parent.width - Theme.spacingL * 2)
height: newBindSection.implicitHeight + Theme.spacingL * 2
anchors.horizontalCenter: parent.horizontalCenter
radius: Theme.cornerRadius
@@ -859,7 +857,7 @@ Item {
}
StyledRect {
width: Math.min(keybindsTab.contentMaxWidth, parent.width - Theme.spacingL * 2)
width: Math.min(SettingsMetrics.contentMaxWidth, parent.width - Theme.spacingL * 2)
height: bindsListHeader.implicitHeight + Theme.spacingL * 2
anchors.horizontalCenter: parent.horizontalCenter
radius: Theme.cornerRadius
@@ -957,7 +955,7 @@ Item {
KeybindItem {
id: bindItem
width: Math.min(keybindsTab.contentMaxWidth, parent.width - Theme.spacingL * 2)
width: Math.min(SettingsMetrics.contentMaxWidth, parent.width - Theme.spacingL * 2)
anchors.horizontalCenter: parent.horizontalCenter
bindData: modelData
isExpanded: keybindsTab.expandedKey === modelData.action
@@ -578,8 +578,7 @@ Item {
SettingsRow {
visible: SettingsData.lockScreenSecurityKeyShortcutEnabled && SettingsData.enableU2f && SettingsData.u2fMode === "or" && !root.lockU2fControlledByPrimary
body: Row {
width: parent.width - Theme.spacingM * 2
x: Theme.spacingM
width: parent.width
spacing: Theme.spacingM
Column {
@@ -65,16 +65,15 @@ Item {
Item {
width: parent.width
height: root.hasContent ? expandedContent.height + Theme.spacingM : 0
height: root.hasContent ? expandedContent.height : 0
Column {
id: expandedContent
enabled: root.checked
anchors.left: parent.left
anchors.right: parent.right
anchors.leftMargin: SettingsMetrics.rowPaddingH
anchors.rightMargin: SettingsMetrics.rowPaddingH
spacing: Theme.spacingM
anchors.leftMargin: root.iconName !== "" ? Theme.iconSize + Theme.spacingL : 0
spacing: 0
}
}
}
@@ -12,8 +12,6 @@ import qs.Modules.Settings.Widgets
Item {
id: root
readonly property int contentMaxWidth: 650
LayoutMirroring.enabled: I18n.isRtl
LayoutMirroring.childrenInherit: true
@@ -301,7 +299,6 @@ Item {
SettingsPage {
id: flickable
contentMaxWidth: root.contentMaxWidth
SettingsCard {
id: headerSection
@@ -9379,40 +9379,9 @@
"parentLabel": "Displays",
"description": "Night mode, gamma, contrast"
},
{
"section": "nightModeTemperature",
"label": "Night temperature",
"tabIndex": 25,
"category": "Gamma control",
"keywords": [
"blue light",
"celsius",
"color",
"color temperature",
"control",
"displays",
"fahrenheit",
"gamma",
"kelvin",
"monitor",
"monitors",
"night",
"night light",
"output",
"outputs",
"redshift",
"resolution",
"screen",
"screens",
"temp",
"temperature",
"warm"
],
"parentLabel": "Displays"
},
{
"section": "nightModeTransitionMinutes",
"label": "Transition duration",
"label": "Mode",
"tabIndex": 25,
"category": "Gamma control",
"keywords": [
@@ -9423,6 +9392,7 @@
"duration",
"fade",
"gamma",
"mode",
"monitor",
"monitors",
"night",
@@ -9437,6 +9407,38 @@
],
"parentLabel": "Displays"
},
{
"section": "nightModeTemperature",
"label": "Night mode",
"tabIndex": 25,
"category": "Gamma control",
"keywords": [
"available",
"blue light",
"color",
"color temperature",
"control",
"displays",
"gamma",
"kelvin",
"mode",
"monitor",
"monitors",
"night",
"night light",
"output",
"outputs",
"redshift",
"requires",
"resolution",
"screen",
"screens",
"temperature",
"warm"
],
"parentLabel": "Displays",
"description": "Gamma control not available. Requires DMS API v6+."
},
{
"section": "_tab_26",
"label": "Display assignment",