mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2025-12-06 05:25:41 -05:00
286 lines
11 KiB
QML
286 lines
11 KiB
QML
import QtQuick
|
|
import qs.Common
|
|
import qs.Widgets
|
|
import qs.Modules.Settings.Widgets
|
|
|
|
Item {
|
|
id: root
|
|
|
|
property var cachedFontFamilies: []
|
|
property var cachedMonoFamilies: []
|
|
property bool fontsEnumerated: false
|
|
|
|
function enumerateFonts() {
|
|
var fonts = [];
|
|
var availableFonts = Qt.fontFamilies();
|
|
|
|
for (var i = 0; i < availableFonts.length; i++) {
|
|
var fontName = availableFonts[i];
|
|
if (fontName.startsWith("."))
|
|
continue;
|
|
fonts.push(fontName);
|
|
}
|
|
fonts.sort();
|
|
fonts.unshift("Default");
|
|
cachedFontFamilies = fonts;
|
|
|
|
var monoFonts = [];
|
|
for (var j = 0; j < availableFonts.length; j++) {
|
|
var fontName2 = availableFonts[j];
|
|
if (fontName2.startsWith("."))
|
|
continue;
|
|
var lowerName = fontName2.toLowerCase();
|
|
if (lowerName.includes("mono") || lowerName.includes("code") || lowerName.includes("console") || lowerName.includes("terminal") || lowerName.includes("courier") || lowerName.includes("jetbrains") || lowerName.includes("fira") || lowerName.includes("hack") || lowerName.includes("source code") || lowerName.includes("cascadia")) {
|
|
monoFonts.push(fontName2);
|
|
}
|
|
}
|
|
monoFonts.sort();
|
|
monoFonts.unshift("Default");
|
|
cachedMonoFamilies = monoFonts;
|
|
}
|
|
|
|
Timer {
|
|
id: fontEnumerationTimer
|
|
interval: 50
|
|
running: false
|
|
onTriggered: {
|
|
if (fontsEnumerated)
|
|
return;
|
|
enumerateFonts();
|
|
fontsEnumerated = true;
|
|
}
|
|
}
|
|
|
|
Component.onCompleted: {
|
|
fontEnumerationTimer.start();
|
|
}
|
|
|
|
DankFlickable {
|
|
anchors.fill: parent
|
|
clip: true
|
|
contentHeight: mainColumn.height + Theme.spacingXL
|
|
contentWidth: width
|
|
|
|
Column {
|
|
id: mainColumn
|
|
width: Math.min(550, parent.width - Theme.spacingL * 2)
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
spacing: Theme.spacingXL
|
|
|
|
SettingsCard {
|
|
tab: "typography"
|
|
tags: ["font", "family", "text", "typography"]
|
|
title: I18n.tr("Typography")
|
|
iconName: "text_fields"
|
|
|
|
SettingsDropdownRow {
|
|
tab: "typography"
|
|
tags: ["font", "family", "normal", "text"]
|
|
settingKey: "fontFamily"
|
|
text: I18n.tr("Normal Font")
|
|
description: I18n.tr("Select the font family for UI text")
|
|
options: root.fontsEnumerated ? root.cachedFontFamilies : ["Default"]
|
|
currentValue: SettingsData.fontFamily === Theme.defaultFontFamily ? "Default" : (SettingsData.fontFamily || "Default")
|
|
enableFuzzySearch: true
|
|
popupWidthOffset: 100
|
|
maxPopupHeight: 400
|
|
onValueChanged: value => {
|
|
if (value === "Default")
|
|
SettingsData.set("fontFamily", Theme.defaultFontFamily);
|
|
else
|
|
SettingsData.set("fontFamily", value);
|
|
}
|
|
}
|
|
|
|
SettingsDropdownRow {
|
|
tab: "typography"
|
|
tags: ["font", "monospace", "code", "terminal"]
|
|
settingKey: "monoFontFamily"
|
|
text: I18n.tr("Monospace Font")
|
|
description: I18n.tr("Select monospace font for process list and technical displays")
|
|
options: root.fontsEnumerated ? root.cachedMonoFamilies : ["Default"]
|
|
currentValue: SettingsData.monoFontFamily === SettingsData.defaultMonoFontFamily ? "Default" : (SettingsData.monoFontFamily || "Default")
|
|
enableFuzzySearch: true
|
|
popupWidthOffset: 100
|
|
maxPopupHeight: 400
|
|
onValueChanged: value => {
|
|
if (value === "Default")
|
|
SettingsData.set("monoFontFamily", SettingsData.defaultMonoFontFamily);
|
|
else
|
|
SettingsData.set("monoFontFamily", value);
|
|
}
|
|
}
|
|
|
|
Rectangle {
|
|
width: parent.width
|
|
height: 1
|
|
color: Theme.outline
|
|
opacity: 0.15
|
|
}
|
|
|
|
SettingsDropdownRow {
|
|
tab: "typography"
|
|
tags: ["font", "weight", "bold", "light"]
|
|
settingKey: "fontWeight"
|
|
text: I18n.tr("Font Weight")
|
|
description: I18n.tr("Select font weight for UI text")
|
|
options: ["Thin", "Extra Light", "Light", "Regular", "Medium", "Demi Bold", "Bold", "Extra Bold", "Black"]
|
|
currentValue: {
|
|
switch (SettingsData.fontWeight) {
|
|
case Font.Thin:
|
|
return "Thin";
|
|
case Font.ExtraLight:
|
|
return "Extra Light";
|
|
case Font.Light:
|
|
return "Light";
|
|
case Font.Normal:
|
|
return "Regular";
|
|
case Font.Medium:
|
|
return "Medium";
|
|
case Font.DemiBold:
|
|
return "Demi Bold";
|
|
case Font.Bold:
|
|
return "Bold";
|
|
case Font.ExtraBold:
|
|
return "Extra Bold";
|
|
case Font.Black:
|
|
return "Black";
|
|
default:
|
|
return "Regular";
|
|
}
|
|
}
|
|
onValueChanged: value => {
|
|
var weight;
|
|
switch (value) {
|
|
case "Thin":
|
|
weight = Font.Thin;
|
|
break;
|
|
case "Extra Light":
|
|
weight = Font.ExtraLight;
|
|
break;
|
|
case "Light":
|
|
weight = Font.Light;
|
|
break;
|
|
case "Regular":
|
|
weight = Font.Normal;
|
|
break;
|
|
case "Medium":
|
|
weight = Font.Medium;
|
|
break;
|
|
case "Demi Bold":
|
|
weight = Font.DemiBold;
|
|
break;
|
|
case "Bold":
|
|
weight = Font.Bold;
|
|
break;
|
|
case "Extra Bold":
|
|
weight = Font.ExtraBold;
|
|
break;
|
|
case "Black":
|
|
weight = Font.Black;
|
|
break;
|
|
default:
|
|
weight = Font.Normal;
|
|
break;
|
|
}
|
|
SettingsData.set("fontWeight", weight);
|
|
}
|
|
}
|
|
|
|
SettingsSliderRow {
|
|
tab: "typography"
|
|
tags: ["font", "scale", "size", "zoom"]
|
|
settingKey: "fontScale"
|
|
text: I18n.tr("Font Scale")
|
|
description: I18n.tr("Scale all font sizes throughout the shell")
|
|
minimum: 75
|
|
maximum: 150
|
|
value: Math.round(SettingsData.fontScale * 100)
|
|
unit: "%"
|
|
defaultValue: 100
|
|
onSliderValueChanged: newValue => SettingsData.set("fontScale", newValue / 100)
|
|
}
|
|
}
|
|
|
|
SettingsCard {
|
|
tab: "typography"
|
|
tags: ["animation", "speed", "motion", "duration"]
|
|
title: I18n.tr("Animation Speed")
|
|
iconName: "animation"
|
|
|
|
Item {
|
|
width: parent.width
|
|
height: animationSpeedGroup.implicitHeight
|
|
clip: true
|
|
|
|
DankButtonGroup {
|
|
id: animationSpeedGroup
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
buttonPadding: parent.width < 480 ? Theme.spacingS : Theme.spacingL
|
|
minButtonWidth: parent.width < 480 ? 44 : 64
|
|
textSize: parent.width < 480 ? Theme.fontSizeSmall : Theme.fontSizeMedium
|
|
model: [I18n.tr("None"), I18n.tr("Short"), I18n.tr("Medium"), I18n.tr("Long"), I18n.tr("Custom")]
|
|
selectionMode: "single"
|
|
currentIndex: SettingsData.animationSpeed
|
|
onSelectionChanged: (index, selected) => {
|
|
if (!selected)
|
|
return;
|
|
SettingsData.set("animationSpeed", index);
|
|
}
|
|
|
|
Connections {
|
|
target: SettingsData
|
|
function onAnimationSpeedChanged() {
|
|
animationSpeedGroup.currentIndex = SettingsData.animationSpeed;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Rectangle {
|
|
width: parent.width
|
|
height: 1
|
|
color: Theme.outline
|
|
opacity: 0.15
|
|
}
|
|
|
|
SettingsSliderRow {
|
|
id: durationSlider
|
|
tab: "typography"
|
|
tags: ["animation", "duration", "custom", "speed"]
|
|
settingKey: "customAnimationDuration"
|
|
text: I18n.tr("Custom Duration")
|
|
description: I18n.tr("Fine-tune animation timing in milliseconds")
|
|
minimum: 0
|
|
maximum: 750
|
|
value: Theme.currentAnimationBaseDuration
|
|
unit: "ms"
|
|
defaultValue: 200
|
|
onSliderValueChanged: newValue => {
|
|
SettingsData.set("animationSpeed", SettingsData.AnimationSpeed.Custom);
|
|
SettingsData.set("customAnimationDuration", newValue);
|
|
}
|
|
|
|
Connections {
|
|
target: SettingsData
|
|
function onAnimationSpeedChanged() {
|
|
if (SettingsData.animationSpeed === SettingsData.AnimationSpeed.Custom)
|
|
return;
|
|
durationSlider.value = Theme.currentAnimationBaseDuration;
|
|
}
|
|
}
|
|
|
|
Connections {
|
|
target: Theme
|
|
function onCurrentAnimationBaseDurationChanged() {
|
|
if (SettingsData.animationSpeed === SettingsData.AnimationSpeed.Custom)
|
|
return;
|
|
durationSlider.value = Theme.currentAnimationBaseDuration;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|