Files
DankMaterialShell/quickshell/Modules/Settings/ThemeSurfacesTab.qml
T

732 lines
33 KiB
QML

import QtQuick
import qs.Common
import qs.Services
import qs.DCommon.Widgets
import qs.Modules.Settings.Widgets
Column {
id: root
property var parentModal: null
readonly property bool followsSurfaces: SettingsData.floatingWindowSyncGlobal ?? true
readonly property bool borderEnabled: SettingsData.blurBorderEnabled ?? false
readonly property bool layerOutlineEnabled: (SettingsData.blurLayerOutlineOpacity ?? 0) > 0
readonly property string windowRadiusKey: CompositorService.supportsLayoutConfig ? CompositorService.configKey + "LayoutRadiusOverride" : ""
width: parent?.width ?? 0
spacing: Theme.spacingL
Component.onCompleted: {
BlurService.probe();
CompositorService.refreshDmsWindowFloatingRule();
}
ConfigInclude {
id: windowRulesInclude
includeKind: "windowrules"
procTag: "windowrules-include-theme"
onFixed: {
if (CompositorService.isMango)
MangoService.reloadConfig();
CompositorService.seedDmsWindowFloatingRule();
}
}
readonly property var opacityTargets: {
SettingsData.barConfigs;
SettingsData.dockConfigs;
const frameBarId = SettingsData.frameEnabled ? SettingsData.frameBarConfig?.id : undefined;
const bars = SettingsData.barConfigs.filter(config => !SettingsData.isDotBarConfig(config)).map(config => ({
key: "bar:" + config.id,
kind: "bar",
id: config.id,
name: config.name || config.id,
enabled: config.enabled !== false,
override: config.followInterfaceStyle === false,
transparency: config.transparency ?? 1,
frame: config.id === frameBarId
}));
const docks = SettingsData.dockConfigs.map(config => ({
key: "dock:" + config.id,
kind: "dock",
id: config.id,
name: config.name,
enabled: config.enabled !== false,
override: config.followInterfaceStyle === false,
transparency: config.transparency ?? 1,
overlay: config.useOverlayLayer ?? false
}));
return bars.concat(docks);
}
function setOpacityOverride(target, patch) {
if (target.kind === "bar") {
SettingsData.updateBarConfig(target.id, patch);
return;
}
SettingsData.updateDockConfig(target.id, patch);
}
function openSurfaceBorderColorPicker() {
PopoutService.colorPickerModal.selectedColor = SettingsData.blurBorderCustomColor ?? "#ffffff";
PopoutService.colorPickerModal.pickerTitle = I18n.tr("Surface Border Color");
PopoutService.colorPickerModal.onColorSelectedCallback = function (color) {
SettingsData.set("blurBorderCustomColor", color.toString());
};
PopoutService.colorPickerModal.open();
}
SettingsCard {
tab: "theme"
title: I18n.tr("Appearance")
settingKey: "surfaceAppearance"
SettingsButtonGroupRow {
tab: "theme"
tags: ["style", "classic", "expressive", "pill", "round", "shape", "morph", "corners", "buttons"]
settingKey: "interfaceStyle"
text: I18n.tr("Style")
model: [I18n.tr("Expressive"), I18n.tr("Classic", "interface style option with one corner radius on controls and no shape change on press")]
values: ["expressive", "classic"]
value: SettingsData.interfaceStyle
fallbackValue: "expressive"
onValueSelected: value => SettingsData.set("interfaceStyle", value)
}
SettingsButtonGroupRow {
tab: "theme"
tags: ["density", "compact", "dense", "spacious", "comfortable", "spacing", "padding", "rows", "menus", "control center", "bar", "dock", "island", "frame", "size"]
settingKey: "density"
text: I18n.tr("Interface density", "interface density setting label")
model: [I18n.tr("Spacious", "interface density option with the most room between items"), I18n.tr("Comfortable", "interface density option with the default spacing"), I18n.tr("Compact", "interface density option fitting the most items on screen"), I18n.tr("Dense", "interface density option denser than compact for small text and tight rows")]
values: ["spacious", "comfortable", "compact", "dense"]
value: SettingsData.density
fallbackValue: "comfortable"
onValueSelected: value => SettingsData.set("density", value)
}
SettingsSliderRow {
tab: "theme"
tags: ["classic", "divider", "dividers", "lines", "rows", "sections", "sidebar", "outline"]
settingKey: "sectionDividerOpacity"
visible: SettingsData.interfaceStyle === "classic"
text: I18n.tr("Section dividers", "classic interface style: strength of the lines between rows of a settings section")
minimumLabel: I18n.tr("Off")
minimum: 0
maximum: 40
step: 1
value: Math.round((SettingsData.sectionDividerOpacity ?? 0) * 100)
onSliderValueChanged: newValue => SettingsData.set("sectionDividerOpacity", newValue / 100)
}
}
SettingsCard {
tab: "theme"
tags: ["surface", "popup", "transparency", "opacity", "modal", "corner", "radius", "blur", "background", "glass", "frosted", "shadow", "elevation", "foreground", "layers"]
title: I18n.tr("Surfaces", "plural noun, settings title, shell surfaces like popouts and modals")
settingKey: "surfaceStyling"
SettingsSliderRow {
tab: "theme"
tags: ["surface", "popup", "transparency", "opacity", "modal"]
settingKey: "popupTransparency"
text: I18n.tr("Opacity")
value: Math.round(SettingsData.popupTransparency * 100)
minimum: 0
maximum: 100
onSliderValueChanged: newValue => SettingsData.set("popupTransparency", newValue / 100)
}
SettingsToggleSliderRow {
tab: "theme"
tags: ["foreground", "layers", "opacity", "transparency", "contrast", "cards", "surface", "blur", "glass", "frosted"]
settingKey: "blurForegroundLayers"
valueKeys: ["foregroundLayerTransparency"]
text: I18n.tr("Foreground layers")
checked: SettingsData.blurForegroundLayers ?? true
value: Math.round((SettingsData.foregroundLayerTransparency ?? 1.0) * 100)
minimum: 0
maximum: 100
onToggled: checked => SettingsData.set("blurForegroundLayers", checked)
onSliderValueChanged: newValue => SettingsData.set("foregroundLayerTransparency", newValue / 100)
}
SettingsToggleSliderRow {
tab: "theme"
tags: ["foreground", "layers", "outline", "border", "opacity", "cards", "pills", "widgets", "notifications", "control center"]
settingKey: "blurLayerOutline"
text: I18n.tr("Layer outline")
description: I18n.tr("Faint edge on cards, pills and widgets", "surface layer outline toggle description")
checked: root.layerOutlineEnabled
value: Math.round((SettingsData.blurLayerOutlineOpacity ?? 0) * 100)
minimum: 1
maximum: 40
onToggled: checked => SettingsData.set("blurLayerOutlineOpacity", checked ? 0.12 : 0)
onSliderValueChanged: newValue => SettingsData.set("blurLayerOutlineOpacity", newValue / 100)
}
SettingsToggleSliderRow {
tab: "theme"
tags: ["surface", "popup", "modal", "border", "outline", "edge", "color", "opacity"]
settingKey: "blurBorderEnabled"
accessoryKeys: ["blurBorderColor", "blurBorderCustomColor"]
valueKeys: ["blurBorderOpacity"]
text: I18n.tr("Border")
description: I18n.tr("Edge around popups and modals", "surface border toggle description")
checked: root.borderEnabled
value: Math.round((SettingsData.blurBorderOpacity ?? 0.35) * 100)
minimum: 0
maximum: 100
onToggled: checked => SettingsData.set("blurBorderEnabled", checked)
onSliderValueChanged: newValue => SettingsData.set("blurBorderOpacity", newValue / 100)
accessory: DDropdown {
id: borderColorMenu
visible: root.borderEnabled
anchors.verticalCenter: parent.verticalCenter
text: I18n.tr("Border color")
showLabel: false
downKeyOpens: false
triggerHeight: Theme.switchTrackHeight
alignPopupRight: !I18n.isRtl
options: [I18n.tr("Outline", "surface border color"), I18n.tr("Primary", "surface border color"), I18n.tr("Secondary", "surface border color"), I18n.tr("Text Color", "surface border color"), I18n.tr("Custom", "surface border color")]
optionColorMap: ({
[I18n.tr("Outline", "surface border color")]: Theme.outline,
[I18n.tr("Primary", "surface border color")]: Theme.primary,
[I18n.tr("Secondary", "surface border color")]: Theme.secondary,
[I18n.tr("Text Color", "surface border color")]: Theme.surfaceText,
[I18n.tr("Custom", "surface border color")]: SettingsData.blurBorderCustomColor ?? "#ffffff"
})
currentValue: {
switch (SettingsData.blurBorderColor) {
case "primary":
return I18n.tr("Primary", "surface border color");
case "secondary":
return I18n.tr("Secondary", "surface border color");
case "surfaceText":
return I18n.tr("Text Color", "surface border color");
case "custom":
return I18n.tr("Custom", "surface border color");
default:
return I18n.tr("Outline", "surface border color");
}
}
onValueChanged: value => {
switch (value) {
case I18n.tr("Primary", "surface border color"):
SettingsData.set("blurBorderColor", "primary");
return;
case I18n.tr("Secondary", "surface border color"):
SettingsData.set("blurBorderColor", "secondary");
return;
case I18n.tr("Text Color", "surface border color"):
SettingsData.set("blurBorderColor", "surfaceText");
return;
case I18n.tr("Custom", "surface border color"):
SettingsData.set("blurBorderColor", "custom");
root.openSurfaceBorderColorPicker();
return;
}
SettingsData.set("blurBorderColor", "outline");
}
}
}
SettingsControlledBy {
visible: SettingsData.connectedFrameModeActive && root.borderEnabled
parentModal: root.parentModal
section: "frameBorder"
settingLabel: I18n.tr("Border")
reason: I18n.tr("Managed by Frame in Connected Mode")
}
SettingsToggleSliderRow {
tab: "theme"
tags: ["blur", "background", "transparency", "glass", "frosted", "strength", "radius", "size", "passes", "reach"]
settingKey: "blurEnabled"
valueKeys: ["blurStrength"]
text: I18n.tr("Background blur")
visible: BlurService.available
checked: SettingsData.blurEnabled ?? false
value: BlurService.strength
minimum: 16
maximum: 160
unit: "px"
onToggled: checked => {
SettingsData.set("blurEnabled", checked);
if (!checked || SettingsData.blurBorderSeeded)
return;
SettingsData.set("blurBorderSeeded", true);
SettingsData.set("blurBorderEnabled", true);
SettingsSearchService.navigateToSection("blurBorderEnabled");
}
onSliderValueChanged: newValue => SettingsData.set("blurStrength", newValue)
}
SettingsNoteRow {
visible: BlurService.probed && !BlurService.available
noteIconName: "info"
tint: Theme.surfaceVariantText
tintBackground: Theme.surfaceVariantAlpha
text: I18n.tr("Your compositor does not support ext-background blur")
}
SettingsNavRow {
tab: "theme"
tags: ["blur", "xray", "compositor", "layout"]
settingKey: "blurXrayLink"
visible: BlurService.available && (CompositorService.isNiri || CompositorService.isHyprland)
title: I18n.tr("Xray options are in Compositor → Layout")
onClicked: keyboard => root.parentModal?.navigateTo("compositor_layout", keyboard)
}
SettingsSplitRow {
tab: "theme"
tags: ["elevation", "shadow", "lift", "m3", "material"]
settingKey: "m3ElevationLink"
title: I18n.tr("Shadows")
subtitle: SettingsTabs.page("surface_shadows")?.hint ?? ""
resetKeys: ["m3ElevationEnabled"]
checked: SettingsData.m3ElevationEnabled ?? true
onNavigated: keyboard => root.parentModal?.navigateTo("surface_shadows", keyboard)
onToggled: checked => SettingsData.set("m3ElevationEnabled", checked)
}
}
SettingsCard {
tab: "theme"
tags: ["corner", "radius", "rounded", "square", "fixed", "material", "shape", "window"]
title: I18n.tr("Corners")
settingKey: "surfaceCorners"
SettingsButtonGroupRow {
tab: "theme"
tags: ["corner", "radius", "rounded", "square", "fixed", "material", "shape"]
settingKey: "radiusMode"
text: I18n.tr("Corner style")
model: [I18n.tr("Material", "corner style: Material shape scale with a strength slider"), I18n.tr("Fixed", "corner style: one radius for every corner")]
currentIndex: SettingsData.radiusMode === "fixed" ? 1 : 0
onSelectionChanged: (index, selected) => {
if (selected)
SettingsData.set("radiusMode", index === 1 ? "fixed" : "scale");
}
}
SettingsSliderRow {
tab: "theme"
tags: ["corner", "radius", "rounded", "square", "strength"]
settingKey: "radiusStrength"
visible: SettingsData.radiusMode !== "fixed"
text: I18n.tr("Radius strength", "global component corner rounding")
description: I18n.tr("50 uses Material shapes. Lower values reduce rounding; higher values increase it.", "radius strength slider description")
minimumLabel: I18n.tr("Square")
value: SettingsData.radiusStrength
minimum: 0
maximum: 100
unit: ""
onSliderValueChanged: newValue => SettingsData.set("radiusStrength", newValue)
}
SettingsSliderRow {
tab: "theme"
tags: ["corner", "radius", "rounded", "square", "fixed"]
settingKey: "fixedRadius"
visible: SettingsData.radiusMode === "fixed"
text: I18n.tr("Corner radius")
minimumLabel: I18n.tr("Square")
value: SettingsData.fixedRadius
minimum: 0
maximum: 32
unit: "px"
onSliderValueChanged: newValue => SettingsData.set("fixedRadius", newValue)
}
SettingsToggleSliderRow {
tab: "theme"
tags: ["window", "corner", "radius", "match", "follow", "link", "strength", "rounded", "popout", "menu", "modal", "compositor", "niri", "hyprland", "mango"]
settingKey: "windowRadius"
text: I18n.tr("Override window radius", "toggle: stop the window radius following the corner style setting")
visible: root.windowRadiusKey !== ""
checked: Theme.compositorRadiusOverride >= 0
value: Theme.windowRadius
minimum: 0
maximum: 64
unit: "px"
onToggled: checked => SettingsData.set(root.windowRadiusKey, checked ? Math.round(Theme.windowRadius) : -1)
onSliderDragFinished: finalValue => SettingsData.set(root.windowRadiusKey, finalValue)
}
}
Repeater {
model: [
{
kind: "bar",
title: I18n.tr("Bars"),
settingKey: "barOpacityOverrides"
},
{
kind: "dock",
title: I18n.tr("Docks"),
settingKey: "dockOpacityOverrides"
}
]
SettingsCard {
id: targetCard
required property var modelData
readonly property var targets: root.opacityTargets.filter(target => target.kind === modelData.kind)
readonly property var activeTargets: targets.filter(target => target.enabled)
readonly property var hiddenTargets: targets.filter(target => !target.enabled)
// String keys: a config edit must not rebuild the row holding the focused control
readonly property string activeKeys: activeTargets.map(target => target.key).join("\n")
readonly property string hiddenKeys: hiddenTargets.map(target => target.key).join("\n")
property bool showHidden: false
tab: "theme"
tags: ["surface", "opacity", "transparency", modelData.kind, "override"]
title: modelData.title
settingKey: modelData.settingKey
visible: targets.length > 0
SettingsControlledBy {
visible: targetCard.modelData.kind === "dock" && SettingsData.connectedFrameModeActive && targetCard.activeTargets.some(target => !target.overlay)
parentModal: root.parentModal
section: "frameSurfaceOpacity"
settingLabel: I18n.tr("Opacity")
reason: I18n.tr("Managed by Frame in Connected Mode")
}
Repeater {
model: targetCard.activeKeys ? targetCard.activeKeys.split("\n") : []
delegate: opacityTargetRow
}
SettingsRow {
tab: "theme"
tags: ["surface", "opacity", "transparency", targetCard.modelData.kind, "hidden", "disabled"]
title: I18n.tr("Hidden (%1)", "island settings: hidden groups divider, %1 is count").arg(targetCard.hiddenTargets.length)
iconName: "visibility_off"
visible: targetCard.hiddenTargets.length > 0
clickable: true
onClicked: targetCard.showHidden = !targetCard.showHidden
DIcon {
anchors.verticalCenter: parent.verticalCenter
name: targetCard.showHidden ? "expand_less" : "expand_more"
size: Theme.iconSize
color: Theme.onSurfaceVariant
}
}
Repeater {
model: targetCard.showHidden && targetCard.hiddenKeys ? targetCard.hiddenKeys.split("\n") : []
delegate: opacityTargetRow
}
}
}
SettingsCard {
tab: "theme"
tags: ["floating", "window", "settings", "notepad", "authentication", "polkit", "opacity", "transparency", "foreground", "tile", "tiling", "override"]
title: I18n.tr("Floating windows")
settingKey: "floatingWindows"
SettingsToggleCard {
tab: "theme"
tags: ["floating", "window", "sync", "global", "surface", "opacity", "override"]
settingKey: "floatingWindowSyncGlobal"
title: I18n.tr("Override", "verb, toggle to override the global setting for this item")
checked: !root.followsSurfaces
onToggled: checked => SettingsData.set("floatingWindowSyncGlobal", !checked)
SettingsSliderRow {
tab: "theme"
tags: ["floating", "window", "opacity", "transparency", "settings", "notepad", "authentication", "polkit"]
settingKey: "floatingWindowTransparency"
text: I18n.tr("Opacity")
value: Math.round(Theme.floatingWindowTransparency * 100)
minimum: 0
maximum: 100
onSliderValueChanged: newValue => SettingsData.set("floatingWindowTransparency", newValue / 100)
}
SettingsToggleSliderRow {
tab: "theme"
tags: ["floating", "window", "foreground", "layers", "opacity", "transparency", "contrast", "cards", "blur", "glass"]
settingKey: "floatingWindowForegroundLayers"
valueKeys: ["floatingWindowForegroundTransparency"]
text: I18n.tr("Foreground layers")
checked: Theme.floatingWindowForegroundLayers
value: Math.round(Theme.floatingWindowForegroundTransparency * 100)
minimum: 0
maximum: 100
onToggled: checked => SettingsData.set("floatingWindowForegroundLayers", checked)
onSliderValueChanged: newValue => SettingsData.set("floatingWindowForegroundTransparency", newValue / 100)
}
}
SettingsToggleRow {
tab: "theme"
tags: ["floating", "window", "title", "bar", "header", "csd", "decoration", "compositor", "kwin", "controls"]
settingKey: "floatingWindowTitleBars"
text: I18n.tr("Title bars")
description: I18n.tr("Off lets the compositor decorate DMS windows. Open windows update when reopened.", "theme floating windows section, title bars toggle description")
checked: SettingsData.floatingWindowTitleBars
onToggled: checked => SettingsData.set("floatingWindowTitleBars", checked)
}
SettingsToggleRow {
tab: "theme"
tags: ["floating", "window", "tile", "tiling", "compositor", "rule", "niri", "hyprland", "mango"]
settingKey: "dmsWindowsFloating"
text: I18n.tr("Open floating")
description: I18n.tr("Adds a compositor window rule so DMS windows such as Settings open floating", "theme floating windows section, open floating toggle description")
visible: windowRulesInclude.compositorSupported
checked: CompositorService.dmsWindowFloatingActive
modified: !checked
onToggled: checked => {
CompositorService.setDmsWindowFloatingRule(checked);
if (checked)
windowRulesInclude.check();
}
}
IncludeSetupBanner {
include: windowRulesInclude
visibleCondition: windowRulesInclude.compositorSupported && CompositorService.dmsWindowFloatingActive
}
}
Component {
id: opacityTargetRow
SettingsToggleSliderRow {
id: overrideRow
required property string modelData
readonly property var target: root.opacityTargets.find(entry => entry.key === modelData) ?? null
tab: "theme"
tags: ["surface", "opacity", "transparency", "bar", "dock", "override"]
settingKey: "surfaceOpacity_" + modelData.replace(":", "_")
text: target?.name ?? ""
description: target?.frame ? I18n.tr("Frame") + " · " + I18n.tr("Override") : I18n.tr("Override")
checked: target?.override ?? false
value: Math.round((target?.transparency ?? 1) * 100)
minimum: 0
maximum: 100
modified: target?.override ?? false
valueModified: (target?.transparency ?? 1) !== 1
onResetRequested: root.setOpacityOverride(target, {
followInterfaceStyle: true,
transparency: 1
})
onValueResetRequested: root.setOpacityOverride(target, {
transparency: 1
})
onToggled: checked => root.setOpacityOverride(target, {
followInterfaceStyle: !checked
})
onSliderDragFinished: finalValue => root.setOpacityOverride(target, {
transparency: finalValue / 100
})
}
}
SettingsToggleCard {
tab: "theme"
tags: ["focus", "ring", "keyboard", "outline", "highlight"]
settingKey: "focusRingEnabled"
iconName: "center_focus_strong"
title: I18n.tr("Focus ring")
checked: SettingsData.focusRingEnabled
onToggled: checked => SettingsData.set("focusRingEnabled", checked)
SettingsSliderRow {
tab: "theme"
tags: ["focus", "ring", "thickness", "width"]
settingKey: "focusRingWidth"
text: I18n.tr("Thickness")
value: Math.round(SettingsData.focusRingWidth * 10)
minimum: 10
maximum: 40
step: 5
decimals: 1
unit: "px"
onSliderValueChanged: newValue => SettingsData.set("focusRingWidth", newValue / 10)
}
SettingsDropdownRow {
tab: "theme"
tags: ["focus", "ring", "color"]
settingKey: "focusRingColor"
text: I18n.tr("Color")
options: [I18n.tr("Primary", "surface border color"), I18n.tr("Secondary", "surface border color"), I18n.tr("Outline", "surface border color"), I18n.tr("Text Color", "surface border color")]
optionColorMap: ({
[I18n.tr("Primary", "surface border color")]: Theme.primary,
[I18n.tr("Secondary", "surface border color")]: Theme.secondary,
[I18n.tr("Outline", "surface border color")]: Theme.outline,
[I18n.tr("Text Color", "surface border color")]: Theme.surfaceText
})
currentValue: {
switch (SettingsData.focusRingColor) {
case "secondary":
return I18n.tr("Secondary", "surface border color");
case "outline":
return I18n.tr("Outline", "surface border color");
case "surfaceText":
return I18n.tr("Text Color", "surface border color");
default:
return I18n.tr("Primary", "surface border color");
}
}
onValueChanged: value => {
switch (value) {
case I18n.tr("Secondary", "surface border color"):
SettingsData.set("focusRingColor", "secondary");
return;
case I18n.tr("Outline", "surface border color"):
SettingsData.set("focusRingColor", "outline");
return;
case I18n.tr("Text Color", "surface border color"):
SettingsData.set("focusRingColor", "surfaceText");
return;
}
SettingsData.set("focusRingColor", "primary");
}
}
}
SettingsToggleCard {
tab: "theme"
tags: ["scroll", "scrollbar", "scrollbars", "list", "page"]
settingKey: "scrollbarsEnabled"
iconName: "unfold_more"
title: I18n.tr("Scrollbars", "theme settings toggle, show scrollbars on lists and pages")
checked: SettingsData.scrollbarsEnabled
onToggled: checked => SettingsData.set("scrollbarsEnabled", checked)
}
SettingsCard {
tab: "theme"
tags: ["button", "color", "accent"]
title: I18n.tr("Colors")
settingKey: "surfaceColors"
SettingsDropdownRow {
tab: "theme"
tags: ["button", "color", "primary", "accent", "action"]
settingKey: "buttonColorMode"
text: I18n.tr("Button color")
options: [I18n.tr("Primary", "button color option"), I18n.tr("Primary Container", "button color option"), I18n.tr("Secondary", "button color option"), I18n.tr("Surface Variant", "button color option")]
optionColorMap: ({
[I18n.tr("Primary", "button color option")]: Theme.roleColor("primary"),
[I18n.tr("Primary Container", "button color option")]: Theme.roleColor("primaryContainer"),
[I18n.tr("Secondary", "button color option")]: Theme.roleColor("secondary"),
[I18n.tr("Surface Variant", "button color option")]: Theme.roleColor("surfaceVariant")
})
currentValue: {
switch (SettingsData.buttonColorMode) {
case "primaryContainer":
return I18n.tr("Primary Container", "button color option");
case "secondary":
return I18n.tr("Secondary", "button color option");
case "surfaceVariant":
return I18n.tr("Surface Variant", "button color option");
default:
return I18n.tr("Primary", "button color option");
}
}
onValueChanged: value => {
switch (value) {
case I18n.tr("Primary Container", "button color option"):
SettingsData.set("buttonColorMode", "primaryContainer");
return;
case I18n.tr("Secondary", "button color option"):
SettingsData.set("buttonColorMode", "secondary");
return;
case I18n.tr("Surface Variant", "button color option"):
SettingsData.set("buttonColorMode", "surfaceVariant");
return;
}
SettingsData.set("buttonColorMode", "primary");
}
}
SettingsSliderRow {
tab: "theme"
tags: ["container", "accent", "color", "saturation", "tint", "pastel", "primary", "card"]
settingKey: "containerSaturation"
text: I18n.tr("Container saturation", "theme setting, saturation of tinted accent containers")
description: I18n.tr("Tinted cards and badges across the shell", "container saturation setting description")
value: SettingsData.containerSaturation
minimum: 0
maximum: 200
step: 5
onSliderValueChanged: newValue => SettingsData.set("containerSaturation", newValue)
}
}
SettingsCard {
tab: "theme"
tags: ["control center", "icon", "scale", "size", "tile"]
title: I18n.tr("Control Center", "Control Center")
settingKey: "controlCenterIcons"
SettingsDropdownRow {
tab: "theme"
tags: ["control", "center", "tile", "button", "color", "active"]
settingKey: "controlCenterTileColorMode"
text: I18n.tr("Tile color", "control center tile color dropdown label")
options: [I18n.tr("Primary", "tile color option"), I18n.tr("Primary Container", "tile color option"), I18n.tr("Secondary", "tile color option"), I18n.tr("Surface Variant", "tile color option")]
optionColorMap: ({
[I18n.tr("Primary", "tile color option")]: Theme.roleColor("primary"),
[I18n.tr("Primary Container", "tile color option")]: Theme.roleColor("primaryContainer"),
[I18n.tr("Secondary", "tile color option")]: Theme.roleColor("secondary"),
[I18n.tr("Surface Variant", "tile color option")]: Theme.roleColor("surfaceVariant")
})
currentValue: {
switch (SettingsData.controlCenterTileColorMode) {
case "primaryContainer":
return I18n.tr("Primary Container", "tile color option");
case "secondary":
return I18n.tr("Secondary", "tile color option");
case "surfaceVariant":
return I18n.tr("Surface Variant", "tile color option");
default:
return I18n.tr("Primary", "tile color option");
}
}
onValueChanged: value => {
switch (value) {
case I18n.tr("Primary Container", "tile color option"):
SettingsData.set("controlCenterTileColorMode", "primaryContainer");
return;
case I18n.tr("Secondary", "tile color option"):
SettingsData.set("controlCenterTileColorMode", "secondary");
return;
case I18n.tr("Surface Variant", "tile color option"):
SettingsData.set("controlCenterTileColorMode", "surfaceVariant");
return;
}
SettingsData.set("controlCenterTileColorMode", "primary");
}
}
SettingsSliderRow {
tab: "theme"
tags: ["control", "center", "icon", "scale", "size", "tile", "header"]
settingKey: "controlCenterIconScale"
text: I18n.tr("Icon scale")
minimum: 50
maximum: 150
step: 5
unit: ""
decimals: 2
value: Math.round(SettingsData.controlCenterIconScale * 100)
onSliderValueChanged: value => SettingsData.set("controlCenterIconScale", value / 100)
}
}
}