Files
Marlon Kranzandpurian23 6d331b8fde fix(settings): show what frame mode controls (#3654)
* fix(settings): show what frame mode controls

With frame mode on, many settings did nothing or were hidden while
still applying, and nothing said so. The frame takes its color and
opacity from the first non-island bar, but that bar's Surface card is
hidden while the frame styles it, so neither had a visible control.

Add Background and Override/Opacity rows to the Appearance Frame card,
bound to the same frame bar the renderer reads. Settings the frame
provides in connected mode get a "Managed by Frame in Connected Mode"
note (Interface style border, corner style, background blur and dock
opacity, shadow targets, launcher border); settings with no effect get
"Disabled by Frame Mode" (maximize detection, bar shadow, the bar's
overlay layer in separate mode). Bar size, the bar's overlay layer in
connected mode, dock Over fullscreen and the controls of overlay-layer
docks and launchers are shown again, since they still apply.
Notification Over fullscreen shows as forced on when the frame covers
every display, and launcher rows the Spotlight style ignores are
disabled.

Also relabel the frame Width row as Thickness, raise the inset padding
maximum to its automatic range, and drop a FrameWindow handler for the
removed frameOpacity signal. No new strings.

* settings: show what frame mode controls, fix review findings

---------

Co-authored-by: purian23 <[email protected]>
2026-10-10 00:37:54 -04:00

688 lines
31 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"
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 scale", "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)
}
}
}