mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-04-04 04:42:05 -04:00
feat: Implement M3 design elevation & shadow effects
- Added global toggles in the Themes tab - Light color & directional user ovverides - Independent shadow overrides per/bar - Refactored various components to sync the updated designs
This commit is contained in:
@@ -878,12 +878,17 @@ Item {
|
||||
x: hoveredButton ? hoveredButton.mapToItem(aboutTab, hoveredButton.width / 2, 0).x - width / 2 : 0
|
||||
y: hoveredButton ? communityIcons.mapToItem(aboutTab, 0, 0).y - height - 8 : 0
|
||||
|
||||
layer.enabled: true
|
||||
layer.effect: MultiEffect {
|
||||
shadowEnabled: true
|
||||
shadowOpacity: 0.15
|
||||
shadowVerticalOffset: 2
|
||||
shadowBlur: 0.5
|
||||
ElevationShadow {
|
||||
anchors.fill: parent
|
||||
z: -1
|
||||
level: Theme.elevationLevel1
|
||||
fallbackOffset: 1
|
||||
targetRadius: communityTooltip.radius
|
||||
targetColor: communityTooltip.color
|
||||
borderColor: communityTooltip.border.color
|
||||
borderWidth: communityTooltip.border.width
|
||||
shadowOpacity: Theme.elevationLevel1 && Theme.elevationLevel1.alpha !== undefined ? Theme.elevationLevel1.alpha : 0.2
|
||||
shadowEnabled: Theme.elevationEnabled
|
||||
}
|
||||
|
||||
StyledText {
|
||||
|
||||
@@ -52,9 +52,11 @@ Item {
|
||||
}
|
||||
|
||||
function _isBarActive(c) {
|
||||
if (!c.enabled) return false;
|
||||
if (!c.enabled)
|
||||
return false;
|
||||
const prefs = c.screenPreferences || ["all"];
|
||||
if (prefs.length > 0) return true;
|
||||
if (prefs.length > 0)
|
||||
return true;
|
||||
return (c.showOnLastDisplay ?? true) && Quickshell.screens.length === 1;
|
||||
}
|
||||
|
||||
@@ -64,7 +66,8 @@ Item {
|
||||
return;
|
||||
|
||||
const hasHorizontal = configs.some(c => {
|
||||
if (!_isBarActive(c)) return false;
|
||||
if (!_isBarActive(c))
|
||||
return false;
|
||||
const p = c.position ?? SettingsData.Position.Top;
|
||||
return p === SettingsData.Position.Top || p === SettingsData.Position.Bottom;
|
||||
});
|
||||
@@ -72,7 +75,8 @@ Item {
|
||||
return;
|
||||
|
||||
const hasVertical = configs.some(c => {
|
||||
if (!_isBarActive(c)) return false;
|
||||
if (!_isBarActive(c))
|
||||
return false;
|
||||
const p = c.position ?? SettingsData.Position.Top;
|
||||
return p === SettingsData.Position.Left || p === SettingsData.Position.Right;
|
||||
});
|
||||
@@ -136,7 +140,9 @@ Item {
|
||||
scrollYBehavior: defaultBar.scrollYBehavior ?? "workspace",
|
||||
shadowIntensity: defaultBar.shadowIntensity ?? 0,
|
||||
shadowOpacity: defaultBar.shadowOpacity ?? 60,
|
||||
shadowColorMode: defaultBar.shadowColorMode ?? "text",
|
||||
shadowDirectionMode: defaultBar.shadowDirectionMode ?? "inherit",
|
||||
shadowDirection: defaultBar.shadowDirection ?? "top",
|
||||
shadowColorMode: defaultBar.shadowColorMode ?? "default",
|
||||
shadowCustomColor: defaultBar.shadowCustomColor ?? "#000000"
|
||||
};
|
||||
SettingsData.addBarConfig(newBar);
|
||||
@@ -1040,6 +1046,237 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
SettingsCard {
|
||||
id: shadowCard
|
||||
iconName: "layers"
|
||||
title: I18n.tr("Shadow Override", "bar shadow settings card")
|
||||
settingKey: "barShadow"
|
||||
collapsible: true
|
||||
expanded: true
|
||||
visible: selectedBarConfig?.enabled
|
||||
|
||||
readonly property bool shadowActive: (selectedBarConfig?.shadowIntensity ?? 0) > 0
|
||||
readonly property bool isCustomColor: (selectedBarConfig?.shadowColorMode ?? "default") === "custom"
|
||||
readonly property string directionSource: selectedBarConfig?.shadowDirectionMode ?? "inherit"
|
||||
|
||||
StyledText {
|
||||
width: parent.width
|
||||
text: I18n.tr("Enable a custom override below to set per-bar shadow intensity, opacity, and color.")
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Theme.surfaceVariantText
|
||||
wrapMode: Text.WordWrap
|
||||
horizontalAlignment: Text.AlignLeft
|
||||
}
|
||||
|
||||
SettingsToggleRow {
|
||||
text: I18n.tr("Custom Shadow Override")
|
||||
description: I18n.tr("Override the global shadow with per-bar settings")
|
||||
checked: shadowCard.shadowActive
|
||||
onToggled: checked => {
|
||||
if (checked) {
|
||||
SettingsData.updateBarConfig(selectedBarId, {
|
||||
shadowIntensity: 12,
|
||||
shadowOpacity: 60
|
||||
});
|
||||
} else {
|
||||
SettingsData.updateBarConfig(selectedBarId, {
|
||||
shadowIntensity: 0
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SettingsSliderRow {
|
||||
visible: shadowCard.shadowActive
|
||||
text: I18n.tr("Intensity", "shadow intensity slider")
|
||||
minimum: 0
|
||||
maximum: 100
|
||||
unit: "px"
|
||||
defaultValue: 12
|
||||
value: selectedBarConfig?.shadowIntensity ?? 0
|
||||
onSliderValueChanged: newValue => SettingsData.updateBarConfig(selectedBarId, {
|
||||
shadowIntensity: newValue
|
||||
})
|
||||
}
|
||||
|
||||
SettingsSliderRow {
|
||||
visible: shadowCard.shadowActive
|
||||
text: I18n.tr("Opacity")
|
||||
minimum: 10
|
||||
maximum: 100
|
||||
unit: "%"
|
||||
defaultValue: 60
|
||||
value: selectedBarConfig?.shadowOpacity ?? 60
|
||||
onSliderValueChanged: newValue => SettingsData.updateBarConfig(selectedBarId, {
|
||||
shadowOpacity: newValue
|
||||
})
|
||||
}
|
||||
|
||||
SettingsDropdownRow {
|
||||
visible: shadowCard.shadowActive
|
||||
text: I18n.tr("Direction Source", "bar shadow direction source")
|
||||
description: I18n.tr("Choose how this bar resolves shadow direction")
|
||||
settingKey: "barShadowDirectionSource"
|
||||
options: [I18n.tr("Inherit Global (Default)", "bar shadow direction source option"), I18n.tr("Auto (Bar-aware)", "bar shadow direction source option"), I18n.tr("Manual", "bar shadow direction source option")]
|
||||
currentValue: {
|
||||
switch (shadowCard.directionSource) {
|
||||
case "autoBar":
|
||||
return I18n.tr("Auto (Bar-aware)", "bar shadow direction source option");
|
||||
case "manual":
|
||||
return I18n.tr("Manual", "bar shadow direction source option");
|
||||
default:
|
||||
return I18n.tr("Inherit Global (Default)", "bar shadow direction source option");
|
||||
}
|
||||
}
|
||||
onValueChanged: value => {
|
||||
if (value === I18n.tr("Auto (Bar-aware)", "bar shadow direction source option")) {
|
||||
SettingsData.updateBarConfig(selectedBarId, {
|
||||
shadowDirectionMode: "autoBar"
|
||||
});
|
||||
} else if (value === I18n.tr("Manual", "bar shadow direction source option")) {
|
||||
SettingsData.updateBarConfig(selectedBarId, {
|
||||
shadowDirectionMode: "manual"
|
||||
});
|
||||
} else {
|
||||
SettingsData.updateBarConfig(selectedBarId, {
|
||||
shadowDirectionMode: "inherit"
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SettingsDropdownRow {
|
||||
visible: shadowCard.shadowActive && shadowCard.directionSource === "manual"
|
||||
text: I18n.tr("Manual Direction", "bar manual shadow direction")
|
||||
description: I18n.tr("Use a fixed shadow direction for this bar")
|
||||
settingKey: "barShadowDirectionManual"
|
||||
options: [I18n.tr("Top", "shadow direction option"), I18n.tr("Top Left", "shadow direction option"), I18n.tr("Top Right", "shadow direction option"), I18n.tr("Bottom", "shadow direction option")]
|
||||
currentValue: {
|
||||
switch (selectedBarConfig?.shadowDirection) {
|
||||
case "topLeft":
|
||||
return I18n.tr("Top Left", "shadow direction option");
|
||||
case "topRight":
|
||||
return I18n.tr("Top Right", "shadow direction option");
|
||||
case "bottom":
|
||||
return I18n.tr("Bottom", "shadow direction option");
|
||||
default:
|
||||
return I18n.tr("Top", "shadow direction option");
|
||||
}
|
||||
}
|
||||
onValueChanged: value => {
|
||||
if (value === I18n.tr("Top Left", "shadow direction option")) {
|
||||
SettingsData.updateBarConfig(selectedBarId, {
|
||||
shadowDirection: "topLeft"
|
||||
});
|
||||
} else if (value === I18n.tr("Top Right", "shadow direction option")) {
|
||||
SettingsData.updateBarConfig(selectedBarId, {
|
||||
shadowDirection: "topRight"
|
||||
});
|
||||
} else if (value === I18n.tr("Bottom", "shadow direction option")) {
|
||||
SettingsData.updateBarConfig(selectedBarId, {
|
||||
shadowDirection: "bottom"
|
||||
});
|
||||
} else {
|
||||
SettingsData.updateBarConfig(selectedBarId, {
|
||||
shadowDirection: "top"
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Column {
|
||||
visible: shadowCard.shadowActive
|
||||
width: parent.width
|
||||
spacing: Theme.spacingS
|
||||
|
||||
StyledText {
|
||||
text: I18n.tr("Color")
|
||||
font.pixelSize: Theme.fontSizeMedium
|
||||
color: Theme.surfaceText
|
||||
horizontalAlignment: Text.AlignLeft
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: Theme.spacingM
|
||||
}
|
||||
|
||||
Item {
|
||||
width: parent.width
|
||||
height: shadowColorGroup.implicitHeight
|
||||
|
||||
DankButtonGroup {
|
||||
id: shadowColorGroup
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
buttonPadding: parent.width < 420 ? Theme.spacingXS : Theme.spacingS
|
||||
minButtonWidth: parent.width < 420 ? 36 : 56
|
||||
textSize: parent.width < 420 ? Theme.fontSizeSmall : Theme.fontSizeMedium
|
||||
model: [I18n.tr("Default (Black)"), I18n.tr("Surface", "shadow color option"), I18n.tr("Primary"), I18n.tr("Secondary"), I18n.tr("Custom")]
|
||||
selectionMode: "single"
|
||||
currentIndex: {
|
||||
switch (selectedBarConfig?.shadowColorMode || "default") {
|
||||
case "surface":
|
||||
return 1;
|
||||
case "primary":
|
||||
return 2;
|
||||
case "secondary":
|
||||
return 3;
|
||||
case "custom":
|
||||
return 4;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
onSelectionChanged: (index, selected) => {
|
||||
if (!selected)
|
||||
return;
|
||||
let mode = "default";
|
||||
switch (index) {
|
||||
case 1:
|
||||
mode = "surface";
|
||||
break;
|
||||
case 2:
|
||||
mode = "primary";
|
||||
break;
|
||||
case 3:
|
||||
mode = "secondary";
|
||||
break;
|
||||
case 4:
|
||||
mode = "custom";
|
||||
break;
|
||||
}
|
||||
SettingsData.updateBarConfig(selectedBarId, {
|
||||
shadowColorMode: mode
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
visible: selectedBarConfig?.shadowColorMode === "custom"
|
||||
width: 32
|
||||
height: 32
|
||||
radius: 16
|
||||
color: selectedBarConfig?.shadowCustomColor ?? "#000000"
|
||||
border.color: Theme.outline
|
||||
border.width: 1
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
PopoutService.colorPickerModal.selectedColor = selectedBarConfig?.shadowCustomColor ?? "#000000";
|
||||
PopoutService.colorPickerModal.pickerTitle = I18n.tr("Color");
|
||||
PopoutService.colorPickerModal.onColorSelectedCallback = function (color) {
|
||||
SettingsData.updateBarConfig(selectedBarId, {
|
||||
shadowCustomColor: color.toString()
|
||||
});
|
||||
};
|
||||
PopoutService.colorPickerModal.show();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SettingsCard {
|
||||
iconName: "rounded_corner"
|
||||
title: I18n.tr("Corners & Background")
|
||||
@@ -1142,134 +1379,6 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
SettingsCard {
|
||||
id: shadowCard
|
||||
iconName: "layers"
|
||||
title: I18n.tr("Shadow", "bar shadow settings card")
|
||||
settingKey: "barShadow"
|
||||
collapsible: true
|
||||
expanded: false
|
||||
visible: selectedBarConfig?.enabled
|
||||
|
||||
readonly property bool shadowActive: (selectedBarConfig?.shadowIntensity ?? 0) > 0
|
||||
readonly property bool isCustomColor: (selectedBarConfig?.shadowColorMode ?? "text") === "custom"
|
||||
|
||||
SettingsSliderRow {
|
||||
text: I18n.tr("Intensity", "shadow intensity slider")
|
||||
minimum: 0
|
||||
maximum: 100
|
||||
unit: "%"
|
||||
value: selectedBarConfig?.shadowIntensity ?? 0
|
||||
onSliderValueChanged: newValue => SettingsData.updateBarConfig(selectedBarId, {
|
||||
shadowIntensity: newValue
|
||||
})
|
||||
}
|
||||
|
||||
SettingsSliderRow {
|
||||
visible: shadowCard.shadowActive
|
||||
text: I18n.tr("Opacity")
|
||||
minimum: 10
|
||||
maximum: 100
|
||||
unit: "%"
|
||||
value: selectedBarConfig?.shadowOpacity ?? 60
|
||||
onSliderValueChanged: newValue => SettingsData.updateBarConfig(selectedBarId, {
|
||||
shadowOpacity: newValue
|
||||
})
|
||||
}
|
||||
|
||||
Column {
|
||||
visible: shadowCard.shadowActive
|
||||
width: parent.width
|
||||
spacing: Theme.spacingS
|
||||
|
||||
StyledText {
|
||||
text: I18n.tr("Color")
|
||||
font.pixelSize: Theme.fontSizeMedium
|
||||
color: Theme.surfaceText
|
||||
horizontalAlignment: Text.AlignLeft
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: Theme.spacingM
|
||||
}
|
||||
|
||||
Item {
|
||||
width: parent.width
|
||||
height: shadowColorGroup.implicitHeight
|
||||
|
||||
DankButtonGroup {
|
||||
id: shadowColorGroup
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
buttonPadding: parent.width < 420 ? Theme.spacingXS : Theme.spacingS
|
||||
minButtonWidth: parent.width < 420 ? 36 : 56
|
||||
textSize: parent.width < 420 ? Theme.fontSizeSmall : Theme.fontSizeMedium
|
||||
model: [I18n.tr("Text", "shadow color option"), I18n.tr("Surface", "shadow color option"), I18n.tr("Primary"), I18n.tr("Secondary"), I18n.tr("Custom")]
|
||||
selectionMode: "single"
|
||||
currentIndex: {
|
||||
switch (selectedBarConfig?.shadowColorMode || "text") {
|
||||
case "surface":
|
||||
return 1;
|
||||
case "primary":
|
||||
return 2;
|
||||
case "secondary":
|
||||
return 3;
|
||||
case "custom":
|
||||
return 4;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
onSelectionChanged: (index, selected) => {
|
||||
if (!selected)
|
||||
return;
|
||||
let mode = "text";
|
||||
switch (index) {
|
||||
case 1:
|
||||
mode = "surface";
|
||||
break;
|
||||
case 2:
|
||||
mode = "primary";
|
||||
break;
|
||||
case 3:
|
||||
mode = "secondary";
|
||||
break;
|
||||
case 4:
|
||||
mode = "custom";
|
||||
break;
|
||||
}
|
||||
SettingsData.updateBarConfig(selectedBarId, {
|
||||
shadowColorMode: mode
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
visible: selectedBarConfig?.shadowColorMode === "custom"
|
||||
width: 32
|
||||
height: 32
|
||||
radius: 16
|
||||
color: selectedBarConfig?.shadowCustomColor ?? "#000000"
|
||||
border.color: Theme.outline
|
||||
border.width: 1
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
PopoutService.colorPickerModal.selectedColor = selectedBarConfig?.shadowCustomColor ?? "#000000";
|
||||
PopoutService.colorPickerModal.pickerTitle = I18n.tr("Color");
|
||||
PopoutService.colorPickerModal.onColorSelectedCallback = function (color) {
|
||||
SettingsData.updateBarConfig(selectedBarId, {
|
||||
shadowCustomColor: color.toString()
|
||||
});
|
||||
};
|
||||
PopoutService.colorPickerModal.show();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SettingsToggleCard {
|
||||
iconName: "border_style"
|
||||
title: I18n.tr("Border")
|
||||
|
||||
@@ -274,7 +274,7 @@ Item {
|
||||
settingKey: "notificationPopupShadowEnabled"
|
||||
tags: ["notification", "popup", "shadow", "radius", "rounded"]
|
||||
text: I18n.tr("Popup Shadow")
|
||||
description: I18n.tr("Show drop shadow on notification popups")
|
||||
description: I18n.tr("Show drop shadow on notification popups. Requires M3 Elevation to be enabled in Theme & Colors.")
|
||||
checked: SettingsData.notificationPopupShadowEnabled
|
||||
onToggled: checked => SettingsData.set("notificationPopupShadowEnabled", checked)
|
||||
}
|
||||
|
||||
@@ -126,6 +126,15 @@ Item {
|
||||
return Theme.warning;
|
||||
}
|
||||
|
||||
function openM3ShadowColorPicker() {
|
||||
PopoutService.colorPickerModal.selectedColor = SettingsData.m3ElevationCustomColor ?? "#000000";
|
||||
PopoutService.colorPickerModal.pickerTitle = I18n.tr("Shadow Color");
|
||||
PopoutService.colorPickerModal.onColorSelectedCallback = function (color) {
|
||||
SettingsData.set("m3ElevationCustomColor", color.toString());
|
||||
};
|
||||
PopoutService.colorPickerModal.show();
|
||||
}
|
||||
|
||||
function formatThemeAutoTime(isoString) {
|
||||
if (!isoString)
|
||||
return "";
|
||||
@@ -1592,6 +1601,189 @@ Item {
|
||||
defaultValue: 12
|
||||
onSliderValueChanged: newValue => SettingsData.setCornerRadius(newValue)
|
||||
}
|
||||
|
||||
SettingsToggleRow {
|
||||
tab: "theme"
|
||||
tags: ["elevation", "shadow", "lift", "m3", "material"]
|
||||
settingKey: "m3ElevationEnabled"
|
||||
text: I18n.tr("Shadows")
|
||||
description: I18n.tr("Material inspired shadows and elevation on modals, popouts, and dialogs")
|
||||
checked: SettingsData.m3ElevationEnabled ?? true
|
||||
onToggled: checked => SettingsData.set("m3ElevationEnabled", checked)
|
||||
}
|
||||
|
||||
SettingsSliderRow {
|
||||
tab: "theme"
|
||||
tags: ["elevation", "shadow", "intensity", "blur", "m3"]
|
||||
settingKey: "m3ElevationIntensity"
|
||||
text: I18n.tr("Shadow Intensity")
|
||||
description: I18n.tr("Controls the base blur radius and offset of shadows")
|
||||
value: SettingsData.m3ElevationIntensity ?? 12
|
||||
minimum: 0
|
||||
maximum: 100
|
||||
unit: "px"
|
||||
defaultValue: 12
|
||||
visible: SettingsData.m3ElevationEnabled ?? true
|
||||
onSliderValueChanged: newValue => SettingsData.set("m3ElevationIntensity", newValue)
|
||||
}
|
||||
|
||||
SettingsSliderRow {
|
||||
tab: "theme"
|
||||
tags: ["elevation", "shadow", "opacity", "transparency", "m3"]
|
||||
settingKey: "m3ElevationOpacity"
|
||||
text: I18n.tr("Shadow Opacity")
|
||||
description: I18n.tr("Controls the transparency of the shadow")
|
||||
value: SettingsData.m3ElevationOpacity ?? 30
|
||||
minimum: 0
|
||||
maximum: 100
|
||||
unit: "%"
|
||||
defaultValue: 30
|
||||
visible: SettingsData.m3ElevationEnabled ?? true
|
||||
onSliderValueChanged: newValue => SettingsData.set("m3ElevationOpacity", newValue)
|
||||
}
|
||||
|
||||
SettingsDropdownRow {
|
||||
tab: "theme"
|
||||
tags: ["elevation", "shadow", "color", "m3"]
|
||||
settingKey: "m3ElevationColorMode"
|
||||
text: I18n.tr("Shadow Color")
|
||||
description: I18n.tr("Base color for shadows (opacity is applied automatically)")
|
||||
options: [I18n.tr("Default (Black)", "shadow color option"), I18n.tr("Text Color", "shadow color option"), I18n.tr("Primary", "shadow color option"), I18n.tr("Surface Variant", "shadow color option"), I18n.tr("Custom", "shadow color option")]
|
||||
currentValue: {
|
||||
switch (SettingsData.m3ElevationColorMode) {
|
||||
case "text":
|
||||
return I18n.tr("Text Color", "shadow color option");
|
||||
case "primary":
|
||||
return I18n.tr("Primary", "shadow color option");
|
||||
case "surfaceVariant":
|
||||
return I18n.tr("Surface Variant", "shadow color option");
|
||||
case "custom":
|
||||
return I18n.tr("Custom", "shadow color option");
|
||||
default:
|
||||
return I18n.tr("Default (Black)", "shadow color option");
|
||||
}
|
||||
}
|
||||
visible: SettingsData.m3ElevationEnabled ?? true
|
||||
onValueChanged: value => {
|
||||
if (value === I18n.tr("Primary", "shadow color option")) {
|
||||
SettingsData.set("m3ElevationColorMode", "primary");
|
||||
} else if (value === I18n.tr("Surface Variant", "shadow color option")) {
|
||||
SettingsData.set("m3ElevationColorMode", "surfaceVariant");
|
||||
} else if (value === I18n.tr("Custom", "shadow color option")) {
|
||||
SettingsData.set("m3ElevationColorMode", "custom");
|
||||
openM3ShadowColorPicker();
|
||||
} else if (value === I18n.tr("Text Color", "shadow color option")) {
|
||||
SettingsData.set("m3ElevationColorMode", "text");
|
||||
} else {
|
||||
SettingsData.set("m3ElevationColorMode", "default");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SettingsDropdownRow {
|
||||
tab: "theme"
|
||||
tags: ["elevation", "shadow", "direction", "light", "advanced", "m3"]
|
||||
settingKey: "m3ElevationLightDirection"
|
||||
text: I18n.tr("Light Direction")
|
||||
description: I18n.tr("Controls shadow cast direction for elevation layers")
|
||||
options: [I18n.tr("Auto (Bar-aware)", "shadow direction option"), I18n.tr("Top (Default)", "shadow direction option"), I18n.tr("Top Left", "shadow direction option"), I18n.tr("Top Right", "shadow direction option"), I18n.tr("Bottom", "shadow direction option")]
|
||||
currentValue: {
|
||||
switch (SettingsData.m3ElevationLightDirection) {
|
||||
case "autoBar":
|
||||
return I18n.tr("Auto (Bar-aware)", "shadow direction option");
|
||||
case "topLeft":
|
||||
return I18n.tr("Top Left", "shadow direction option");
|
||||
case "topRight":
|
||||
return I18n.tr("Top Right", "shadow direction option");
|
||||
case "bottom":
|
||||
return I18n.tr("Bottom", "shadow direction option");
|
||||
default:
|
||||
return I18n.tr("Top (Default)", "shadow direction option");
|
||||
}
|
||||
}
|
||||
visible: SettingsData.m3ElevationEnabled ?? true
|
||||
onValueChanged: value => {
|
||||
if (value === I18n.tr("Auto (Bar-aware)", "shadow direction option")) {
|
||||
SettingsData.set("m3ElevationLightDirection", "autoBar");
|
||||
} else if (value === I18n.tr("Top Left", "shadow direction option")) {
|
||||
SettingsData.set("m3ElevationLightDirection", "topLeft");
|
||||
} else if (value === I18n.tr("Top Right", "shadow direction option")) {
|
||||
SettingsData.set("m3ElevationLightDirection", "topRight");
|
||||
} else if (value === I18n.tr("Bottom", "shadow direction option")) {
|
||||
SettingsData.set("m3ElevationLightDirection", "bottom");
|
||||
} else {
|
||||
SettingsData.set("m3ElevationLightDirection", "top");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
visible: (SettingsData.m3ElevationEnabled ?? true) && SettingsData.m3ElevationColorMode === "custom"
|
||||
width: parent.width
|
||||
implicitHeight: 36
|
||||
height: implicitHeight
|
||||
|
||||
Row {
|
||||
anchors.left: parent.left
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: Theme.spacingM
|
||||
|
||||
StyledText {
|
||||
text: I18n.tr("Custom Shadow Color")
|
||||
color: Theme.surfaceText
|
||||
font.pixelSize: Theme.fontSizeMedium
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
width: 26
|
||||
height: 26
|
||||
radius: 13
|
||||
color: SettingsData.m3ElevationCustomColor ?? "#000000"
|
||||
border.color: Theme.outline
|
||||
border.width: 1
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: openM3ShadowColorPicker()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SettingsToggleRow {
|
||||
tab: "theme"
|
||||
tags: ["elevation", "shadow", "modal", "dialog", "m3"]
|
||||
settingKey: "modalElevationEnabled"
|
||||
text: I18n.tr("Modal Shadows")
|
||||
description: I18n.tr("Shadow elevation on modals and dialogs")
|
||||
checked: SettingsData.modalElevationEnabled ?? true
|
||||
visible: SettingsData.m3ElevationEnabled ?? true
|
||||
onToggled: checked => SettingsData.set("modalElevationEnabled", checked)
|
||||
}
|
||||
|
||||
SettingsToggleRow {
|
||||
tab: "theme"
|
||||
tags: ["elevation", "shadow", "popout", "popup", "osd", "dropdown", "m3"]
|
||||
settingKey: "popoutElevationEnabled"
|
||||
text: I18n.tr("Popout Shadows")
|
||||
description: I18n.tr("Shadow elevation on popouts, OSDs, and dropdowns")
|
||||
checked: SettingsData.popoutElevationEnabled ?? true
|
||||
visible: SettingsData.m3ElevationEnabled ?? true
|
||||
onToggled: checked => SettingsData.set("popoutElevationEnabled", checked)
|
||||
}
|
||||
|
||||
SettingsToggleRow {
|
||||
tab: "theme"
|
||||
tags: ["elevation", "shadow", "bar", "panel", "navigation", "m3"]
|
||||
settingKey: "barElevationEnabled"
|
||||
text: I18n.tr("Bar Shadows")
|
||||
description: I18n.tr("Shadow elevation on bars and panels")
|
||||
checked: SettingsData.barElevationEnabled ?? true
|
||||
visible: SettingsData.m3ElevationEnabled ?? true
|
||||
onToggled: checked => SettingsData.set("barElevationEnabled", checked)
|
||||
}
|
||||
}
|
||||
|
||||
SettingsCard {
|
||||
@@ -2138,12 +2330,41 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
SettingsCard {
|
||||
tab: "theme"
|
||||
tags: ["icon", "theme", "system"]
|
||||
title: I18n.tr("Icon Theme")
|
||||
settingKey: "iconTheme"
|
||||
iconName: "interests"
|
||||
|
||||
SettingsDropdownRow {
|
||||
tab: "theme"
|
||||
tags: ["icon", "theme", "system"]
|
||||
settingKey: "iconTheme"
|
||||
text: I18n.tr("Icon Theme")
|
||||
description: I18n.tr("DankShell & System Icons (requires restart)")
|
||||
currentValue: SettingsData.iconTheme
|
||||
enableFuzzySearch: true
|
||||
popupWidthOffset: 100
|
||||
maxPopupHeight: 236
|
||||
options: cachedIconThemes
|
||||
onValueChanged: value => {
|
||||
SettingsData.setIconTheme(value);
|
||||
if (Quickshell.env("QT_QPA_PLATFORMTHEME") != "gtk3" && Quickshell.env("QT_QPA_PLATFORMTHEME") != "qt6ct" && Quickshell.env("QT_QPA_PLATFORMTHEME_QT6") != "qt6ct") {
|
||||
ToastService.showError(I18n.tr("Missing Environment Variables", "qt theme env error title"), I18n.tr("You need to set either:\nQT_QPA_PLATFORMTHEME=gtk3 OR\nQT_QPA_PLATFORMTHEME=qt6ct\nas environment variables, and then restart the shell.\n\nqt6ct requires qt6ct-kde to be installed.", "qt theme env error body"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SettingsCard {
|
||||
tab: "theme"
|
||||
tags: ["matugen", "templates", "theming"]
|
||||
title: I18n.tr("Matugen Templates")
|
||||
settingKey: "matugenTemplates"
|
||||
iconName: "auto_awesome"
|
||||
collapsible: true
|
||||
expanded: false
|
||||
visible: Theme.matugenAvailable
|
||||
|
||||
SettingsToggleRow {
|
||||
@@ -2448,33 +2669,6 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
SettingsCard {
|
||||
tab: "theme"
|
||||
tags: ["icon", "theme", "system"]
|
||||
title: I18n.tr("Icon Theme")
|
||||
settingKey: "iconTheme"
|
||||
iconName: "interests"
|
||||
|
||||
SettingsDropdownRow {
|
||||
tab: "theme"
|
||||
tags: ["icon", "theme", "system"]
|
||||
settingKey: "iconTheme"
|
||||
text: I18n.tr("Icon Theme")
|
||||
description: I18n.tr("DankShell & System Icons (requires restart)")
|
||||
currentValue: SettingsData.iconTheme
|
||||
enableFuzzySearch: true
|
||||
popupWidthOffset: 100
|
||||
maxPopupHeight: 236
|
||||
options: cachedIconThemes
|
||||
onValueChanged: value => {
|
||||
SettingsData.setIconTheme(value);
|
||||
if (Quickshell.env("QT_QPA_PLATFORMTHEME") != "gtk3" && Quickshell.env("QT_QPA_PLATFORMTHEME") != "qt6ct" && Quickshell.env("QT_QPA_PLATFORMTHEME_QT6") != "qt6ct") {
|
||||
ToastService.showError(I18n.tr("Missing Environment Variables", "qt theme env error title"), I18n.tr("You need to set either:\nQT_QPA_PLATFORMTHEME=gtk3 OR\nQT_QPA_PLATFORMTHEME=qt6ct\nas environment variables, and then restart the shell.\n\nqt6ct requires qt6ct-kde to be installed.", "qt theme env error body"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SettingsCard {
|
||||
tab: "theme"
|
||||
tags: ["system", "app", "theming", "gtk", "qt"]
|
||||
|
||||
@@ -706,14 +706,15 @@ Item {
|
||||
anchors.left: parent.left
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
layer.enabled: true
|
||||
layer.enabled: Theme.elevationEnabled
|
||||
layer.effect: MultiEffect {
|
||||
shadowEnabled: true
|
||||
shadowHorizontalOffset: 0
|
||||
shadowVerticalOffset: 4
|
||||
shadowBlur: 0.8
|
||||
shadowColor: Qt.rgba(0, 0, 0, 0.2)
|
||||
shadowOpacity: 0.2
|
||||
shadowEnabled: Theme.elevationEnabled
|
||||
shadowHorizontalOffset: Theme.elevationOffsetX(Theme.elevationLevel1)
|
||||
shadowVerticalOffset: Theme.elevationOffsetY(Theme.elevationLevel1, 1)
|
||||
shadowBlur: Theme.elevationEnabled ? Math.max(0, Math.min(1, (Theme.elevationLevel1 && Theme.elevationLevel1.blurPx !== undefined ? Theme.elevationLevel1.blurPx : 4) / Theme.elevationBlurMax)) : 0
|
||||
blurMax: Theme.elevationBlurMax
|
||||
shadowColor: Theme.elevationShadowColor(Theme.elevationLevel1)
|
||||
shadowOpacity: Theme.elevationLevel1 && Theme.elevationLevel1.alpha !== undefined ? Theme.elevationLevel1.alpha : 0.2
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user