summaryrefslogtreecommitdiff
path: root/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/Settings/TypographyMotionTab.qml
diff options
context:
space:
mode:
Diffstat (limited to 'raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/Settings/TypographyMotionTab.qml')
-rw-r--r--raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/Settings/TypographyMotionTab.qml490
1 files changed, 490 insertions, 0 deletions
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/Settings/TypographyMotionTab.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/Settings/TypographyMotionTab.qml
new file mode 100644
index 0000000..8648acb
--- /dev/null
+++ b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/Settings/TypographyMotionTab.qml
@@ -0,0 +1,490 @@
+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;
+ cachedMonoFamilies = fonts;
+ }
+
+ 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
+ topPadding: 4
+ 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")
+ settingKey: "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")
+ settingKey: "animationSpeed"
+ 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("Animation Duration")
+ description: I18n.tr("Globally scale all animation durations")
+ minimum: 0
+ maximum: 1000
+ 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;
+ }
+ }
+ }
+
+ Rectangle {
+ width: parent.width
+ height: 1
+ color: Theme.outline
+ opacity: 0.15
+ }
+
+ SettingsToggleRow {
+ tab: "typography"
+ tags: ["animation", "sync", "popout", "modal", "global"]
+ settingKey: "syncComponentAnimationSpeeds"
+ text: I18n.tr("Sync Popouts & Modals")
+ description: I18n.tr("Popouts and Modals follow global Animation Speed (disable to customize independently)")
+ checked: SettingsData.syncComponentAnimationSpeeds
+ onToggled: checked => SettingsData.set("syncComponentAnimationSpeeds", checked)
+
+ Connections {
+ target: SettingsData
+ function onSyncComponentAnimationSpeedsChanged() {
+ }
+ }
+ }
+ }
+
+ SettingsCard {
+ tab: "typography"
+ tags: ["animation", "speed", "motion", "duration", "popout", "sync"]
+ title: I18n.tr("%1 Animation Speed").arg(I18n.tr("Popouts"))
+ settingKey: "popoutAnimationSpeed"
+ iconName: "open_in_new"
+
+ Item {
+ width: parent.width
+ height: popoutSpeedGroup.implicitHeight
+ clip: true
+
+ DankButtonGroup {
+ id: popoutSpeedGroup
+ 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.popoutAnimationSpeed
+ onSelectionChanged: (index, selected) => {
+ if (!selected)
+ return;
+ if (SettingsData.syncComponentAnimationSpeeds)
+ SettingsData.set("syncComponentAnimationSpeeds", false);
+ SettingsData.set("popoutAnimationSpeed", index);
+ }
+
+ Connections {
+ target: SettingsData
+ function onPopoutAnimationSpeedChanged() {
+ popoutSpeedGroup.currentIndex = SettingsData.popoutAnimationSpeed;
+ }
+ }
+ }
+ }
+
+ Rectangle {
+ width: parent.width
+ height: 1
+ color: Theme.outline
+ opacity: 0.15
+ }
+
+ SettingsSliderRow {
+ id: popoutDurationSlider
+ tab: "typography"
+ tags: ["animation", "duration", "custom", "speed", "popout"]
+ settingKey: "popoutCustomAnimationDuration"
+ text: I18n.tr("Custom Duration")
+ description: I18n.tr("%1 custom animation duration").arg(I18n.tr("Popouts"))
+ minimum: 0
+ maximum: 1000
+ value: Theme.popoutAnimationDuration
+ unit: "ms"
+ defaultValue: 150
+ onSliderValueChanged: newValue => {
+ if (SettingsData.syncComponentAnimationSpeeds)
+ SettingsData.set("syncComponentAnimationSpeeds", false);
+ SettingsData.set("popoutAnimationSpeed", SettingsData.AnimationSpeed.Custom);
+ SettingsData.set("popoutCustomAnimationDuration", newValue);
+ }
+
+ Connections {
+ target: SettingsData
+ function onPopoutAnimationSpeedChanged() {
+ if (SettingsData.popoutAnimationSpeed === SettingsData.AnimationSpeed.Custom)
+ return;
+ popoutDurationSlider.value = Theme.popoutAnimationDuration;
+ }
+ }
+
+ Connections {
+ target: Theme
+ function onPopoutAnimationDurationChanged() {
+ if (!SettingsData.syncComponentAnimationSpeeds && SettingsData.popoutAnimationSpeed === SettingsData.AnimationSpeed.Custom)
+ return;
+ popoutDurationSlider.value = Theme.popoutAnimationDuration;
+ }
+ }
+ }
+ }
+
+ SettingsCard {
+ tab: "typography"
+ tags: ["animation", "speed", "motion", "duration", "modal", "sync"]
+ title: I18n.tr("%1 Animation Speed").arg(I18n.tr("Modals"))
+ settingKey: "modalAnimationSpeed"
+ iconName: "web_asset"
+
+ Item {
+ width: parent.width
+ height: modalSpeedGroup.implicitHeight
+ clip: true
+
+ DankButtonGroup {
+ id: modalSpeedGroup
+ 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.modalAnimationSpeed
+ onSelectionChanged: (index, selected) => {
+ if (!selected)
+ return;
+ if (SettingsData.syncComponentAnimationSpeeds)
+ SettingsData.set("syncComponentAnimationSpeeds", false);
+ SettingsData.set("modalAnimationSpeed", index);
+ }
+
+ Connections {
+ target: SettingsData
+ function onModalAnimationSpeedChanged() {
+ modalSpeedGroup.currentIndex = SettingsData.modalAnimationSpeed;
+ }
+ }
+ }
+ }
+
+ Rectangle {
+ width: parent.width
+ height: 1
+ color: Theme.outline
+ opacity: 0.15
+ }
+
+ SettingsSliderRow {
+ id: modalDurationSlider
+ tab: "typography"
+ tags: ["animation", "duration", "custom", "speed", "modal"]
+ settingKey: "modalCustomAnimationDuration"
+ text: I18n.tr("Custom Duration")
+ description: I18n.tr("%1 custom animation duration").arg(I18n.tr("Modals"))
+ minimum: 0
+ maximum: 1000
+ value: Theme.modalAnimationDuration
+ unit: "ms"
+ defaultValue: 150
+ onSliderValueChanged: newValue => {
+ if (SettingsData.syncComponentAnimationSpeeds)
+ SettingsData.set("syncComponentAnimationSpeeds", false);
+ SettingsData.set("modalAnimationSpeed", SettingsData.AnimationSpeed.Custom);
+ SettingsData.set("modalCustomAnimationDuration", newValue);
+ }
+
+ Connections {
+ target: SettingsData
+ function onModalAnimationSpeedChanged() {
+ if (SettingsData.modalAnimationSpeed === SettingsData.AnimationSpeed.Custom)
+ return;
+ modalDurationSlider.value = Theme.modalAnimationDuration;
+ }
+ }
+
+ Connections {
+ target: Theme
+ function onModalAnimationDurationChanged() {
+ if (!SettingsData.syncComponentAnimationSpeeds && SettingsData.modalAnimationSpeed === SettingsData.AnimationSpeed.Custom)
+ return;
+ modalDurationSlider.value = Theme.modalAnimationDuration;
+ }
+ }
+ }
+ }
+
+ SettingsCard {
+ tab: "typography"
+ tags: ["animation", "ripple", "effect", "material", "feedback"]
+ title: I18n.tr("Ripple Effects")
+ settingKey: "enableRippleEffects"
+ iconName: "radio_button_unchecked"
+
+ SettingsToggleRow {
+ tab: "typography"
+ tags: ["animation", "ripple", "effect", "material", "click"]
+ settingKey: "enableRippleEffects"
+ text: I18n.tr("Enable Ripple Effects")
+ description: I18n.tr("Show Material Design ripple animations on interactive elements")
+ checked: SettingsData.enableRippleEffects ?? true
+ onToggled: newValue => SettingsData.set("enableRippleEffects", newValue)
+
+ Connections {
+ target: SettingsData
+ function onEnableRippleEffectsChanged() {
+ }
+ }
+ }
+ }
+ }
+ }
+}