mirror of
https://github.com/noctalia-dev/noctalia-shell.git
synced 2026-05-11 17:08:27 +08:00
Merge branch 'main' of github.com:noctalia-dev/noctalia-shell
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
{
|
||||
"dark": {
|
||||
"mPrimary": "#37f499",
|
||||
"mOnPrimary": "#171928",
|
||||
"mSecondary": "#04d1f9",
|
||||
"mOnSecondary": "#171928",
|
||||
"mTertiary": "#a48cf2",
|
||||
"mOnTertiary": "#171928",
|
||||
"mError": "#f16c75",
|
||||
"mOnError": "#171928",
|
||||
"mSurface": "#212337",
|
||||
"mOnSurface": "#ebfafa",
|
||||
"mSurfaceVariant": "#292e42",
|
||||
"mOnSurfaceVariant": "#ABB4DA",
|
||||
"mOutline": "#3b4261",
|
||||
"mShadow": "#414868"
|
||||
},
|
||||
"light": {
|
||||
"mPrimary": "#37f499",
|
||||
"mOnPrimary": "#171928",
|
||||
"mSecondary": "#04d1f9",
|
||||
"mOnSecondary": "#171928",
|
||||
"mTertiary": "#a48cf2",
|
||||
"mOnTertiary": "#171928",
|
||||
"mError": "#f16c75",
|
||||
"mOnError": "#171928",
|
||||
"mSurface": "#ffffff",
|
||||
"mOnSurface": "#171928",
|
||||
"mSurfaceVariant": "#f2f4f8",
|
||||
"mOnSurfaceVariant": "#3b4261",
|
||||
"mOutline": "#b0b6c3",
|
||||
"mShadow": "#e0e3e8"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
[colors]
|
||||
foreground=ebfafa
|
||||
background=212337
|
||||
regular0=21222c
|
||||
regular1=f9515d
|
||||
regular2=37f499
|
||||
regular3=e9f941
|
||||
regular4=9071f4
|
||||
regular5=f265b5
|
||||
regular6=04d1f9
|
||||
regular7=ebfafa
|
||||
bright0=7081d0
|
||||
bright1=f16c75
|
||||
bright2=69F8B3
|
||||
bright3=f1fc79
|
||||
bright4=a48cf2
|
||||
bright5=FD92CE
|
||||
bright6=66e4fd
|
||||
bright7=ffffff
|
||||
selection-foreground=ebfafa
|
||||
selection-background=bf4f8e
|
||||
cursor=37f499 f8f8f2
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
[colors]
|
||||
foreground=212337
|
||||
background=ebfafa
|
||||
regular0=ebfafa # black → white
|
||||
regular1=ba1a1a # red (darker)
|
||||
regular2=1a7f4c # green (darker)
|
||||
regular3=9e8c13 # yellow (darker)
|
||||
regular4=3a3e8c # blue (darker)
|
||||
regular5=8c2a6c # magenta (darker)
|
||||
regular6=1a6c8c # cyan (darker)
|
||||
regular7=212337 # white → black
|
||||
bright0=7081d0 # keep as accent
|
||||
bright1=d23b3b # lighter red
|
||||
bright2=37f499 # original green
|
||||
bright3=e9f941 # original yellow
|
||||
bright4=9071f4 # original blue
|
||||
bright5=f265b5 # original magenta
|
||||
bright6=04d1f9 # original cyan
|
||||
bright7=212337 # black
|
||||
selection-foreground=212337
|
||||
selection-background=bf4f8e
|
||||
cursor=1a7f4c 212337
|
||||
@@ -0,0 +1,21 @@
|
||||
palette = 0=#21222c
|
||||
palette = 1=#f9515d
|
||||
palette = 2=#37f499
|
||||
palette = 3=#e9f941
|
||||
palette = 4=#9071f4
|
||||
palette = 5=#f265b5
|
||||
palette = 6=#04d1f9
|
||||
palette = 7=#ebfafa
|
||||
palette = 8=#7081d0
|
||||
palette = 9=#f16c75
|
||||
palette = 10=#69F8B3
|
||||
palette = 11=#f1fc79
|
||||
palette = 12=#a48cf2
|
||||
palette = 13=#FD92CE
|
||||
palette = 14=#66e4fd
|
||||
palette = 15=#ffffff
|
||||
background = 212337
|
||||
foreground = ebfafa
|
||||
cursor-color = 37f499
|
||||
selection-background = bf4f8e
|
||||
selection-foreground = ebfafa
|
||||
@@ -0,0 +1,22 @@
|
||||
palette = 0=#f8f8fa # base background (was dark, now light)
|
||||
palette = 1=#d7263d # red (less saturated)
|
||||
palette = 2=#1eb980 # green (cooler, lighter)
|
||||
palette = 3=#f7c948 # yellow (warmer)
|
||||
palette = 4=#5e60ce # blue (lighter)
|
||||
palette = 5=#c77dff # magenta (lighter)
|
||||
palette = 6=#38a1db # cyan (lighter)
|
||||
palette = 7=#21222c # base foreground (was background, now dark)
|
||||
palette = 8=#bfc9e3 # bright black (light gray)
|
||||
palette = 9=#f9515d # bright red
|
||||
palette = 10=#37f499 # bright green
|
||||
palette = 11=#e9f941 # bright yellow
|
||||
palette = 12=#9071f4 # bright blue
|
||||
palette = 13=#f265b5 # bright magenta
|
||||
palette = 14=#04d1f9 # bright cyan
|
||||
palette = 15=#21222c # bright white (dark for contrast)
|
||||
background = f8f8fa
|
||||
foreground = 21222c
|
||||
cursor-color = 5e60ce
|
||||
selection-background = d7e3fa
|
||||
selection-foreground = 21222c
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
color0 #21222c
|
||||
color1 #f9515d
|
||||
color2 #37f499
|
||||
color3 #e9f941
|
||||
color4 #9071f4
|
||||
color5 #f265b5
|
||||
color6 #04d1f9
|
||||
color7 #ebfafa
|
||||
color8 #7081d0
|
||||
color9 #f16c75
|
||||
color10 #69F8B3
|
||||
color11 #f1fc79
|
||||
color12 #a48cf2
|
||||
color13 #FD92CE
|
||||
color14 #66e4fd
|
||||
color15 #ffffff
|
||||
background #212337
|
||||
selection_foreground #ebfafa
|
||||
cursor #37f499
|
||||
cursor_text_color #f8f8f2
|
||||
foreground #ebfafa
|
||||
selection_background #bf4f8e
|
||||
@@ -0,0 +1,22 @@
|
||||
color0 #ebfafa
|
||||
color1 #f9515d
|
||||
color2 #37f499
|
||||
color3 #e9f941
|
||||
color4 #9071f4
|
||||
color5 #f265b5
|
||||
color6 #04d1f9
|
||||
color7 #212337
|
||||
color8 #7081d0
|
||||
color9 #f16c75
|
||||
color10 #69F8B3
|
||||
color11 #f1fc79
|
||||
color12 #a48cf2
|
||||
color13 #FD92CE
|
||||
color14 #66e4fd
|
||||
color15 #323449
|
||||
background #ebfafa
|
||||
selection_foreground #ebfafa
|
||||
cursor #212337
|
||||
cursor_text_color #ebfafa
|
||||
foreground #212337
|
||||
selection_background #bf4f8e
|
||||
@@ -1322,7 +1322,8 @@
|
||||
"bottom_left": "Unten links",
|
||||
"bottom_right": "Unten rechts",
|
||||
"bottom_center": "Unten mittig",
|
||||
"top_center": "Oben mittig"
|
||||
"top_center": "Oben mittig",
|
||||
"center": "Mitte"
|
||||
},
|
||||
"quickSettingsStyle": {
|
||||
"modern": "Modern",
|
||||
@@ -1622,5 +1623,34 @@
|
||||
"label": "Letztes Control-Center-Widget entfernt",
|
||||
"description": "Das Control-Center-Widget wurde aus der Leiste entfernt. Um es erneut über die Leiste zu öffnen, fügen Sie das Widget wieder hinzu. Sie können es auch durch Rechtsklick auf die Leiste öffnen."
|
||||
}
|
||||
},
|
||||
"setup": {
|
||||
"customize": {
|
||||
"header": "Erlebnis anpassen",
|
||||
"subheader": "Leistenposition, Dichte, Skalierung und mehr einstellen."
|
||||
},
|
||||
"appearance": {
|
||||
"header": "Erscheinungsbild",
|
||||
"subheader": "Dunkelmodus und Farbquellen wählen (Matugen oder vordefiniert)."
|
||||
},
|
||||
"wallpaper": {
|
||||
"header": "Wähle dein Hintergrundbild",
|
||||
"subheader": "Bestimme die Stimmung mit einem schönen Hintergrund.",
|
||||
"select-prompt": "Wähle unten ein Hintergrundbild",
|
||||
"preview-error": "Bild konnte nicht geladen werden",
|
||||
"none-in-dir": "Keine Hintergrundbilder im Verzeichnis gefunden",
|
||||
"no-dir": "Kein Hintergrundbild-Verzeichnis ausgewählt",
|
||||
"no-valid": "Keine gültigen Bilddateien gefunden in: {dir}",
|
||||
"choose-dir": "Wähle ein Verzeichnis mit deinen Hintergrundbildern",
|
||||
"dir": {
|
||||
"label": "Hintergrundbild-Verzeichnis",
|
||||
"description": "Wähle den Ordner mit deinen Hintergrundbildern",
|
||||
"browse": "Ordner auswählen",
|
||||
"select-title": "Hintergrundbild-Ordner wählen"
|
||||
}
|
||||
},
|
||||
"welcome": {
|
||||
"note": "Nur ein paar Grundeinstellungen – alle Optionen findest du in den Einstellungen"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1305,7 +1305,8 @@
|
||||
"bottom_left": "Bottom left",
|
||||
"bottom_right": "Bottom right",
|
||||
"bottom_center": "Bottom center",
|
||||
"top_center": "Top center"
|
||||
"top_center": "Top center",
|
||||
"center": "Center"
|
||||
},
|
||||
"quickSettingsStyle": {
|
||||
"modern": "Modern",
|
||||
@@ -1622,5 +1623,34 @@
|
||||
"lifespan": "Extended lifespan ({percent}%)",
|
||||
"disabled": "Battery manager disabled"
|
||||
}
|
||||
},
|
||||
"setup": {
|
||||
"customize": {
|
||||
"header": "Customize your experience",
|
||||
"subheader": "Adjust bar position, density, scaling and more."
|
||||
},
|
||||
"appearance": {
|
||||
"header": "Appearance",
|
||||
"subheader": "Choose dark mode and color sources (Matugen or predefined)."
|
||||
},
|
||||
"wallpaper": {
|
||||
"header": "Choose your wallpaper",
|
||||
"subheader": "Set the mood with a beautiful background.",
|
||||
"select-prompt": "Select a wallpaper below",
|
||||
"preview-error": "Failed to load image",
|
||||
"none-in-dir": "No wallpapers found in directory",
|
||||
"no-dir": "No wallpaper directory selected",
|
||||
"no-valid": "No valid image files found in: {dir}",
|
||||
"choose-dir": "Choose a directory containing your wallpaper images",
|
||||
"dir": {
|
||||
"label": "Wallpaper directory",
|
||||
"description": "Choose the folder containing your wallpapers",
|
||||
"browse": "Browse for wallpaper folder",
|
||||
"select-title": "Select wallpaper folder"
|
||||
}
|
||||
},
|
||||
"welcome": {
|
||||
"note": "Just a few basics to get you started - full options are in Settings"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1305,7 +1305,8 @@
|
||||
"bottom_left": "Inferior izquierda",
|
||||
"bottom_right": "Inferior derecha",
|
||||
"bottom_center": "Inferior central",
|
||||
"top_center": "Superior central"
|
||||
"top_center": "Superior central",
|
||||
"center": "Centro"
|
||||
},
|
||||
"quickSettingsStyle": {
|
||||
"modern": "Moderno",
|
||||
@@ -1622,5 +1623,34 @@
|
||||
"lifespan": "Vida útil prolongada ({percent}%)",
|
||||
"disabled": "Administrador de batería deshabilitado"
|
||||
}
|
||||
},
|
||||
"setup": {
|
||||
"customize": {
|
||||
"header": "Personaliza tu experiencia",
|
||||
"subheader": "Ajusta la posición de la barra, densidad, escala y más."
|
||||
},
|
||||
"appearance": {
|
||||
"header": "Apariencia",
|
||||
"subheader": "Elige modo oscuro y fuentes de color (Matugen o predefinido)."
|
||||
},
|
||||
"wallpaper": {
|
||||
"header": "Elige tu fondo",
|
||||
"subheader": "Define el ambiente con un bonito fondo.",
|
||||
"select-prompt": "Selecciona un fondo abajo",
|
||||
"preview-error": "No se pudo cargar la imagen",
|
||||
"none-in-dir": "No se encontraron fondos en el directorio",
|
||||
"no-dir": "No se seleccionó un directorio de fondos",
|
||||
"no-valid": "No se encontraron imágenes válidas en: {dir}",
|
||||
"choose-dir": "Elige un directorio que contenga tus fondos",
|
||||
"dir": {
|
||||
"label": "Directorio de fondos",
|
||||
"description": "Elige la carpeta que contiene tus fondos",
|
||||
"browse": "Seleccionar carpeta",
|
||||
"select-title": "Seleccionar carpeta de fondos"
|
||||
}
|
||||
},
|
||||
"welcome": {
|
||||
"note": "Solo algunos conceptos básicos para empezar: todas las opciones están en Configuración."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1305,7 +1305,8 @@
|
||||
"bottom_left": "En bas à gauche",
|
||||
"bottom_right": "En bas à droite",
|
||||
"bottom_center": "En bas au centre",
|
||||
"top_center": "En haut au centre"
|
||||
"top_center": "En haut au centre",
|
||||
"center": "Centre"
|
||||
},
|
||||
"quickSettingsStyle": {
|
||||
"modern": "Moderne",
|
||||
@@ -1622,5 +1623,34 @@
|
||||
"lifespan": "Durée de vie prolongée ({percent}%)",
|
||||
"disabled": "Gestionnaire de batterie désactivé"
|
||||
}
|
||||
},
|
||||
"setup": {
|
||||
"customize": {
|
||||
"header": "Personnaliser votre expérience",
|
||||
"subheader": "Ajustez la position de la barre, la densité, l'échelle et plus encore."
|
||||
},
|
||||
"appearance": {
|
||||
"header": "Apparence",
|
||||
"subheader": "Choisissez le mode sombre et la source des couleurs (Matugen ou prédéfinie)."
|
||||
},
|
||||
"wallpaper": {
|
||||
"header": "Choisissez votre fond d'écran",
|
||||
"subheader": "Définissez l'ambiance avec un joli fond.",
|
||||
"select-prompt": "Sélectionnez un fond ci-dessous",
|
||||
"preview-error": "Échec du chargement de l'image",
|
||||
"none-in-dir": "Aucun fond d'écran trouvé dans le répertoire",
|
||||
"no-dir": "Aucun répertoire de fonds d'écran sélectionné",
|
||||
"no-valid": "Aucun fichier image valide trouvé dans : {dir}",
|
||||
"choose-dir": "Choisissez un répertoire contenant vos fonds d'écran",
|
||||
"dir": {
|
||||
"label": "Répertoire des fonds d'écran",
|
||||
"description": "Choisissez le dossier contenant vos fonds d'écran",
|
||||
"browse": "Parcourir le dossier",
|
||||
"select-title": "Sélectionner le dossier des fonds d'écran"
|
||||
}
|
||||
},
|
||||
"welcome": {
|
||||
"note": "Quelques réglages de base pour démarrer — toutes les options sont dans Paramètres"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+38
-14
@@ -1303,7 +1303,8 @@
|
||||
"bottom_left": "Inferior esquerdo",
|
||||
"bottom_right": "Inferior direito",
|
||||
"bottom_center": "Centro inferior",
|
||||
"top_center": "Centro superior"
|
||||
"top_center": "Centro superior",
|
||||
"center": "Centro"
|
||||
},
|
||||
"quickSettingsStyle": {
|
||||
"modern": "Moderno",
|
||||
@@ -1615,18 +1616,41 @@
|
||||
"discharging-rate": "Taxa de descarregamento: {rate} W.",
|
||||
"charging": "Carregando.",
|
||||
"discharging": "Descarregando.",
|
||||
"battery-manager": {
|
||||
"title": "Limite da bateria",
|
||||
"set-success-desc": "Limite da bateria definido para {percent}%",
|
||||
"initial-setup": "Configuração inicial necessária",
|
||||
"set-failed": "Falha ao definir o limite da bateria",
|
||||
"install-success": "Instalado com sucesso",
|
||||
"install-missing": "Arquivos necessários ausentes",
|
||||
"install-unsupported": "Sistema não suportado",
|
||||
"install-failed": "Falha na instalação",
|
||||
"uninstall-setup": "Desinstalando, autenticação necessária",
|
||||
"uninstall-success": "Desinstalado com sucesso",
|
||||
"uninstall-failed": "Falha na desinstalação"
|
||||
"panel": {
|
||||
"balanced": "Balanceado ({percent}%)",
|
||||
"disabled": "Gerenciador de bateria desativado",
|
||||
"full": "Capacidade máxima ({percent}%)",
|
||||
"lifespan": "Vida útil prolongada ({percent}%)",
|
||||
"title": "Limite de carga"
|
||||
}
|
||||
},
|
||||
"setup": {
|
||||
"customize": {
|
||||
"header": "Personalizar a sua experiência",
|
||||
"subheader": "Ajuste a posição da barra, densidade, escala e mais."
|
||||
},
|
||||
"appearance": {
|
||||
"header": "Aparência",
|
||||
"subheader": "Escolha o modo escuro e as fontes de cores (Matugen ou predefinidas)."
|
||||
},
|
||||
"wallpaper": {
|
||||
"header": "Escolha o seu papel de parede",
|
||||
"subheader": "Defina o ambiente com um belo fundo.",
|
||||
"select-prompt": "Selecione um papel de parede abaixo",
|
||||
"preview-error": "Falha ao carregar a imagem",
|
||||
"none-in-dir": "Nenhum papel de parede encontrado no diretório",
|
||||
"no-dir": "Nenhum diretório de papéis de parede selecionado",
|
||||
"no-valid": "Nenhuma imagem válida encontrada em: {dir}",
|
||||
"choose-dir": "Escolha um diretório contendo seus papéis de parede",
|
||||
"dir": {
|
||||
"label": "Diretório de papéis de parede",
|
||||
"description": "Escolha a pasta que contém seus papéis de parede",
|
||||
"browse": "Procurar pasta",
|
||||
"select-title": "Selecionar pasta de papéis de parede"
|
||||
}
|
||||
},
|
||||
"welcome": {
|
||||
"note": "Apenas alguns ajustes básicos para começar - o restante está em Configurações"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1305,7 +1305,8 @@
|
||||
"bottom_left": "左下角",
|
||||
"bottom_right": "右下角",
|
||||
"bottom_center": "底部居中",
|
||||
"top_center": "顶部居中"
|
||||
"top_center": "顶部居中",
|
||||
"center": "居中"
|
||||
},
|
||||
"quickSettingsStyle": {
|
||||
"modern": "现代",
|
||||
@@ -1622,5 +1623,34 @@
|
||||
"lifespan": "延长寿命 ({percent}%)",
|
||||
"disabled": "电池管理器已禁用"
|
||||
}
|
||||
},
|
||||
"setup": {
|
||||
"customize": {
|
||||
"header": "自定义体验",
|
||||
"subheader": "调整状态栏位置、密度、缩放等。"
|
||||
},
|
||||
"appearance": {
|
||||
"header": "外观",
|
||||
"subheader": "选择深色模式与配色来源(Matugen 或预设)。"
|
||||
},
|
||||
"wallpaper": {
|
||||
"header": "选择你的壁纸",
|
||||
"subheader": "用精美壁纸营造氛围。",
|
||||
"select-prompt": "在下方选择一张壁纸",
|
||||
"preview-error": "图片加载失败",
|
||||
"none-in-dir": "目录中未找到壁纸",
|
||||
"no-dir": "未选择壁纸目录",
|
||||
"no-valid": "在 {dir} 中未找到有效图片文件",
|
||||
"choose-dir": "选择包含壁纸图片的目录",
|
||||
"dir": {
|
||||
"label": "壁纸目录",
|
||||
"description": "选择存放壁纸的文件夹",
|
||||
"browse": "浏览文件夹",
|
||||
"select-title": "选择壁纸文件夹"
|
||||
}
|
||||
},
|
||||
"welcome": {
|
||||
"note": "先进行一些基础设置——更多选项可在“设置”中找到"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="256"
|
||||
height="256"
|
||||
viewBox="0 0 67.733334 67.733334"
|
||||
version="1.1"
|
||||
id="svg1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<defs
|
||||
id="defs1" />
|
||||
<g
|
||||
id="g60"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#0e0e43;stroke-width:6.2176;stroke-dasharray:none;stroke-opacity:1"
|
||||
transform="matrix(1.0000606,0,0,1.0000606,-5.3736738,-63.880929)">
|
||||
<g
|
||||
id="g1"
|
||||
transform="matrix(0.3457623,0,0,0.3457623,1.8096128,40.073954)"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#0e0e43;stroke-width:17.9823;stroke-dasharray:none;stroke-opacity:1">
|
||||
<g
|
||||
id="g2"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#0e0e43;stroke-width:1.4785;stroke-dasharray:none;stroke-opacity:1"
|
||||
transform="matrix(12.162505,0,0,12.162505,-32.462207,-452.96894)">
|
||||
<path
|
||||
id="path1"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#0e0e43;stroke-width:1.4785;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:9.1;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
|
||||
d="m 11.646507,43.642549 c -4.038226,8.9e-4 -7.3116325,3.274297 -7.3125227,7.312523 -1.947e-4,4.038993 3.2735294,7.313597 7.3125227,7.314488 3.487073,-0.0084 6.483277,-2.47736 7.158181,-5.898508 -0.620978,1.570892 -1.854119,2.821688 -3.416025,3.464933 0.0015,0.277406 0.0039,0.532472 0.0039,0.726484 -0.739445,0 -1.37585,-0.10185 -1.92189,-0.271448 -0.146668,0.01695 -0.293894,0.02867 -0.441396,0.03514 -3.4356877,2.08e-4 -6.2209147,-2.785019 -6.2207066,-6.220707 -2.081e-4,-3.435688 2.7850189,-6.220915 6.2207066,-6.220707 0.192387,2.18e-4 0.38466,0.0094 0.576199,0.0274 -0.637785,-0.178134 -1.296807,-0.268831 -1.959001,-0.269605 z m -3.1385553,3.085838 c 0.1447941,0.443587 0.436407,0.880884 0.8274942,1.046718 -0.1090884,0.328801 -0.1096117,0.719225 -0.1096117,1.137282 0,0.90457 0.6427321,1.676019 1.5479578,1.983086 -0.329929,-0.04179 -0.632013,-0.123222 -0.8682918,-0.287054 -0.431935,0.07708 -0.6133052,0.557376 -0.5744781,1.118235 0.2769283,4.000144 2.8097509,3.741322 2.8324539,3.734783 -1.853097,-0.904141 -1.549482,-2.377876 -1.610382,-2.847445 0.07631,0.794735 0.926406,3.057084 4.098271,3.057084 0,-0.953411 0.0047,-3.40281 -0.304135,-4.157993 -0.09728,-0.294206 -0.3627,-1.081221 -0.686056,-1.169354 -0.262025,0.29403 -0.643893,0.449619 -1.095011,0.527045 0.867912,-0.322492 1.4773,-1.077475 1.4773,-1.958387 0,-0.418057 -5.29e-4,-0.808481 -0.109612,-1.137282 0.391087,-0.165834 0.682701,-0.603131 0.827494,-1.046718 -0.472651,-0.0073 -1.224795,0.166618 -1.866593,0.187028 -0.321367,-0.08366 -0.733857,-0.129693 -1.260165,-0.130256 -0.526307,5.76e-4 -0.938675,0.04659 -1.260042,0.130256 -0.6417973,-0.02041 -1.3939415,-0.194302 -1.8665933,-0.187028 z" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
id="g55"
|
||||
style="fill:#fff59b;fill-opacity:1"
|
||||
transform="matrix(4.2055905,0,0,4.2055905,-14.788898,-180.43362)">
|
||||
<path
|
||||
id="path55"
|
||||
style="fill:#fff59b;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:9.1;stroke-dasharray:none;paint-order:fill markers stroke"
|
||||
d="m 11.646484,43.642578 a 7.3141356,7.3141356 0 0 0 -7.3124996,7.3125 7.3141356,7.3141356 0 0 0 7.3124996,7.314453 7.3141356,7.3141356 0 0 0 7.158204,-5.898437 6.2203302,6.2203302 0 0 1 -3.416016,3.464844 c 0.0015,0.277406 0.0039,0.53255 0.0039,0.726562 -0.739445,0 -1.375835,-0.101886 -1.921875,-0.271484 a 6.2203302,6.2203302 0 0 1 -0.441406,0.03516 6.2203302,6.2203302 0 0 1 -6.2207032,-6.220703 6.2203302,6.2203302 0 0 1 6.2207032,-6.220703 6.2203302,6.2203302 0 0 1 0.576172,0.02734 7.3141356,7.3141356 0 0 0 -1.958985,-0.269531 z" />
|
||||
</g>
|
||||
<path
|
||||
id="path56"
|
||||
style="fill:#a9aefe;fill-opacity:1;stroke:none;stroke-width:1.34608;stroke-miterlimit:9.1;paint-order:fill markers stroke"
|
||||
d="m 42.66444,31.291474 c -1.802882,2.023105 -4.950139,2.492661 -8.5254,2.5028 -2.71816,-0.0077 -5.450476,-0.128227 -7.26956,-1.389551 -1.816542,0.324182 -2.579157,2.344033 -2.415866,4.702777 1.164647,16.822967 11.81672,15.734645 11.912198,15.707145 -7.793366,-3.802447 -6.516498,-10.00048 -6.772622,-11.975293 0.320928,3.34233 3.895926,12.856764 17.235494,12.856764 0,-4.009655 0.01992,-14.311035 -1.27908,-17.487024 -0.409124,-1.237312 -1.52526,-4.546963 -2.885164,-4.917618 z" />
|
||||
<rect
|
||||
style="fill:#f3edf7;fill-opacity:1;stroke-width:6.29839;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:6.4"
|
||||
id="rect3"
|
||||
width="16.253635"
|
||||
height="10.520533"
|
||||
x="25.887611"
|
||||
y="19.681677" />
|
||||
<path
|
||||
id="path57"
|
||||
style="fill:#a9aefe;fill-opacity:1;stroke:none;stroke-width:3.76565;stroke-miterlimit:9.1;paint-order:fill markers stroke"
|
||||
d="m 20.992013,16.087004 c 0.608944,1.865545 1.835334,3.704314 3.480086,4.401745 -0.458781,1.382804 -0.460831,3.024949 -0.460831,4.783126 0,4.927895 4.533698,8.919413 10.130359,8.938559 5.596664,-0.01912 10.130367,-4.010667 10.130367,-8.938559 0,-1.758177 -0.0021,-3.400322 -0.460833,-4.783126 1.644753,-0.697431 2.871142,-2.5362 3.480084,-4.401745 -1.987776,-0.0305 -5.150908,0.700757 -7.850047,0.786595 -1.351539,-0.351845 -3.086137,-0.545868 -5.299571,-0.548233 -2.213431,0.0024 -3.948027,0.196367 -5.299568,0.548233 -2.699135,-0.08584 -5.862266,-0.817187 -7.850046,-0.786595 z m 6.777419,4.648053 c 0.55547,-0.01383 1.299779,0.06204 2.304161,0.246319 0.672198,0.123302 1.523536,0.452402 2.034019,0.754813 0.950807,0.563264 1.073595,1.207697 2.034015,1.207697 0.96042,0 1.083207,-0.644433 2.034018,-1.207697 0.510483,-0.302418 1.361822,-0.631511 2.034021,-0.754813 4.591459,-0.842328 3.821732,0.523962 3.821732,2.836505 0,2.387132 -1.935155,4.32229 -4.322291,4.32229 -0.76295,-0.0037 -1.511332,-0.20934 -2.169091,-0.595905 -0.01546,0.03375 -0.02887,0.06484 -0.04768,0.09535 l -0.969338,1.573189 c -0.105239,0.171222 -0.243797,0.257467 -0.381378,0.254251 -0.13758,0.0031 -0.276139,-0.08303 -0.381378,-0.254251 l -0.969338,-1.573189 c -0.01871,-0.0305 -0.03212,-0.06159 -0.04768,-0.09535 -0.657763,0.386585 -1.406142,0.592188 -2.169091,0.595905 -2.387137,0 -4.32229,-1.935158 -4.32229,-4.32229 0,-1.806673 -0.466271,-3.033173 1.517569,-3.082814 z" />
|
||||
<path
|
||||
id="path58"
|
||||
style="fill:none;stroke:#0e0e43;stroke-width:1.22052;stroke-linecap:round;stroke-miterlimit:9.1;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
|
||||
d="M 32.3042,25.300596 A 1.9914438,1.9914438 0 0 1 30.579559,26.29632 1.9914438,1.9914438 0 0 1 28.854918,25.300596" />
|
||||
<path
|
||||
id="path59"
|
||||
style="fill:none;stroke:#0e0e43;stroke-width:1.22052;stroke-linecap:round;stroke-miterlimit:9.1;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
|
||||
d="M 39.428334,25.300596 A 1.9914438,1.9914438 0 0 1 37.703696,26.29632 1.9914438,1.9914438 0 0 1 35.979053,25.300596" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 6.8 KiB |
@@ -1,5 +1,6 @@
|
||||
{
|
||||
"settingsVersion": 15,
|
||||
"settingsVersion": 16,
|
||||
"setupCompleted": false,
|
||||
"bar": {
|
||||
"position": "top",
|
||||
"backgroundOpacity": 1,
|
||||
|
||||
@@ -14,6 +14,7 @@ Singleton {
|
||||
readonly property alias data: adapter
|
||||
property bool isLoaded: false
|
||||
property bool directoriesCreated: false
|
||||
property int settingsVersion: 16
|
||||
|
||||
// Define our app directories
|
||||
// Default config directory: ~/.config/noctalia
|
||||
@@ -100,6 +101,9 @@ Singleton {
|
||||
|
||||
// Emit the signal
|
||||
root.settingsLoaded()
|
||||
|
||||
// Finally, update our local settings version
|
||||
adapter.settingsVersion = settingsVersion
|
||||
}
|
||||
}
|
||||
onLoadFailed: function (error) {
|
||||
@@ -125,7 +129,8 @@ Singleton {
|
||||
JsonAdapter {
|
||||
id: adapter
|
||||
|
||||
property int settingsVersion: 15
|
||||
property int settingsVersion: root.settingsVersion
|
||||
property bool setupCompleted: false
|
||||
|
||||
// bar
|
||||
property JsonObject bar: JsonObject {
|
||||
|
||||
@@ -128,6 +128,12 @@ Singleton {
|
||||
"bt-device-watch": "device-watch",
|
||||
"bt-device-speaker": "device-speaker",
|
||||
"bt-device-tv": "device-tv",
|
||||
"antenna-bars-1": "antenna-bars-1",
|
||||
"antenna-bars-2": "antenna-bars-2",
|
||||
"antenna-bars-3": "antenna-bars-3",
|
||||
"antenna-bars-4": "antenna-bars-4",
|
||||
"antenna-bars-5": "antenna-bars-5",
|
||||
"antenna-bars-off": "antenna-bars-off",
|
||||
"noctalia": "noctalia",
|
||||
"hyprland": "hyprland",
|
||||
"filepicker-folder": "folder",
|
||||
|
||||
@@ -109,7 +109,7 @@ ColumnLayout {
|
||||
|
||||
NIcon {
|
||||
visible: modelData.signalStrength > 0 && !modelData.pairing && !modelData.blocked
|
||||
text: BluetoothService.getSignalIcon(modelData)
|
||||
icon: BluetoothService.getSignalIcon(modelData)
|
||||
pointSize: Style.fontSizeXS
|
||||
color: getContentColor(Color.mOnSurface)
|
||||
}
|
||||
|
||||
@@ -46,8 +46,8 @@ NPanel {
|
||||
|
||||
// Positioning
|
||||
readonly property string controlCenterPosition: Settings.data.controlCenter.position
|
||||
panelAnchorHorizontalCenter: controlCenterPosition !== "close_to_bar_button" && controlCenterPosition.endsWith("_center")
|
||||
panelAnchorVerticalCenter: false
|
||||
panelAnchorHorizontalCenter: controlCenterPosition !== "close_to_bar_button" && (controlCenterPosition.endsWith("_center") || controlCenterPosition === "center")
|
||||
panelAnchorVerticalCenter: controlCenterPosition === "center"
|
||||
panelAnchorLeft: controlCenterPosition !== "close_to_bar_button" && controlCenterPosition.endsWith("_left")
|
||||
panelAnchorRight: controlCenterPosition !== "close_to_bar_button" && controlCenterPosition.endsWith("_right")
|
||||
panelAnchorBottom: controlCenterPosition !== "close_to_bar_button" && controlCenterPosition.startsWith("bottom_")
|
||||
|
||||
@@ -336,7 +336,6 @@ ColumnLayout {
|
||||
NIcon {
|
||||
icon: "check"
|
||||
pointSize: Style.fontSizeXS
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Color.mOnSecondary
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
|
||||
@@ -143,6 +143,9 @@ ColumnLayout {
|
||||
}, {
|
||||
"key": "top_center",
|
||||
"name": I18n.tr("options.control-center.position.top_center")
|
||||
}, {
|
||||
"key": "center",
|
||||
"name": I18n.tr("options.control-center.position.center")
|
||||
}]
|
||||
currentKey: Settings.data.controlCenter.position
|
||||
onSelected: function (key) {
|
||||
|
||||
@@ -0,0 +1,557 @@
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Controls
|
||||
import Quickshell.Io
|
||||
import qs.Commons
|
||||
import qs.Services
|
||||
import qs.Widgets
|
||||
|
||||
ColumnLayout {
|
||||
id: root
|
||||
spacing: Style.marginM
|
||||
|
||||
function extractSchemeName(path) {
|
||||
var basename = path.split('/').pop()
|
||||
return basename.replace('.json', '')
|
||||
}
|
||||
|
||||
// Cache for scheme colors (mirrors ColorSchemeTab approach)
|
||||
property var schemeColorsCache: ({})
|
||||
property int cacheVersion: 0
|
||||
|
||||
function getSchemeColor(schemeName, key) {
|
||||
try {
|
||||
var mode = Settings.data.colorSchemes.darkMode ? "dark" : "light"
|
||||
var data = schemeColorsCache[schemeName]
|
||||
if (data && data[mode] && data[mode][key])
|
||||
return data[mode][key]
|
||||
} catch (e) {
|
||||
|
||||
}
|
||||
return Color.mSurfaceVariant
|
||||
}
|
||||
|
||||
// Match ColorSchemeTab helpers
|
||||
function schemeLoaded(schemeName, jsonData) {
|
||||
var value = jsonData || {}
|
||||
schemeColorsCache[schemeName] = value
|
||||
cacheVersion++
|
||||
Logger.log("SetupAppearanceStep", `Loaded scheme ${schemeName}`)
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: ColorSchemeService
|
||||
function onSchemesChanged() {
|
||||
Logger.log("SetupAppearanceStep", `Color schemes changed: ${ColorSchemeService.schemes.length}`)
|
||||
schemeColorsCache = {}
|
||||
cacheVersion++
|
||||
}
|
||||
}
|
||||
|
||||
// Beautiful header with icon
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
Layout.bottomMargin: Style.marginL
|
||||
spacing: Style.marginM
|
||||
|
||||
Rectangle {
|
||||
width: 40
|
||||
height: 40
|
||||
radius: Style.radiusL
|
||||
color: Color.mSurfaceVariant
|
||||
opacity: 0.6
|
||||
|
||||
NIcon {
|
||||
icon: "palette"
|
||||
pointSize: Style.fontSizeL
|
||||
color: Color.mPrimary
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: Style.marginXS
|
||||
|
||||
NText {
|
||||
text: I18n.tr("setup.appearance.header")
|
||||
pointSize: Style.fontSizeXL
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Color.mPrimary
|
||||
}
|
||||
|
||||
NText {
|
||||
text: I18n.tr("setup.appearance.subheader")
|
||||
pointSize: Style.fontSizeM
|
||||
color: Color.mOnSurfaceVariant
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ScrollView {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
clip: true
|
||||
contentWidth: availableWidth
|
||||
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
|
||||
ScrollBar.vertical.policy: ScrollBar.AsNeeded
|
||||
|
||||
ColumnLayout {
|
||||
width: parent.width
|
||||
spacing: Style.marginM
|
||||
|
||||
// Dark Mode Toggle
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: Style.marginM
|
||||
|
||||
Rectangle {
|
||||
width: 28
|
||||
height: 28
|
||||
radius: Style.radiusM
|
||||
color: Color.mSurface
|
||||
|
||||
NIcon {
|
||||
icon: "moon"
|
||||
pointSize: Style.fontSizeL
|
||||
color: Color.mPrimary
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: 2
|
||||
|
||||
NText {
|
||||
text: I18n.tr("settings.color-scheme.color-source.dark-mode.label")
|
||||
pointSize: Style.fontSizeL
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Color.mOnSurface
|
||||
}
|
||||
|
||||
NText {
|
||||
text: I18n.tr("settings.color-scheme.color-source.dark-mode.description")
|
||||
pointSize: Style.fontSizeS
|
||||
color: Color.mOnSurfaceVariant
|
||||
wrapMode: Text.WordWrap
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
}
|
||||
|
||||
NToggle {
|
||||
checked: Settings.data.colorSchemes.darkMode
|
||||
onToggled: checked => Settings.data.colorSchemes.darkMode = checked
|
||||
}
|
||||
}
|
||||
|
||||
// Divider
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 1
|
||||
color: Color.mOutline
|
||||
opacity: 0.2
|
||||
Layout.topMargin: Style.marginS
|
||||
Layout.bottomMargin: Style.marginS
|
||||
}
|
||||
|
||||
// Wallpaper Colors Toggle
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: Style.marginM
|
||||
|
||||
Rectangle {
|
||||
width: 28
|
||||
height: 28
|
||||
radius: Style.radiusM
|
||||
color: Color.mSurface
|
||||
|
||||
NIcon {
|
||||
icon: "color-picker"
|
||||
pointSize: Style.fontSizeL
|
||||
color: Color.mPrimary
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: 2
|
||||
|
||||
NText {
|
||||
text: I18n.tr("settings.color-scheme.color-source.use-wallpaper-colors.label")
|
||||
pointSize: Style.fontSizeL
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Color.mOnSurface
|
||||
}
|
||||
|
||||
NText {
|
||||
text: I18n.tr("settings.color-scheme.color-source.use-wallpaper-colors.description")
|
||||
pointSize: Style.fontSizeS
|
||||
color: Color.mOnSurfaceVariant
|
||||
wrapMode: Text.WordWrap
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
}
|
||||
|
||||
NToggle {
|
||||
enabled: ProgramCheckerService.matugenAvailable
|
||||
opacity: ProgramCheckerService.matugenAvailable ? 1.0 : 0.6
|
||||
checked: Settings.data.colorSchemes.useWallpaperColors && ProgramCheckerService.matugenAvailable
|
||||
onToggled: checked => {
|
||||
if (!ProgramCheckerService.matugenAvailable)
|
||||
return
|
||||
if (checked) {
|
||||
Settings.data.colorSchemes.useWallpaperColors = true
|
||||
AppThemeService.generate()
|
||||
} else {
|
||||
Settings.data.colorSchemes.useWallpaperColors = false
|
||||
if (Settings.data.colorSchemes.predefinedScheme) {
|
||||
ColorSchemeService.applyScheme(Settings.data.colorSchemes.predefinedScheme)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Matugen not available notice
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: Style.marginS
|
||||
visible: !ProgramCheckerService.matugenAvailable
|
||||
|
||||
Rectangle {
|
||||
width: 28
|
||||
height: 28
|
||||
radius: Style.radiusM
|
||||
color: Color.mSurface
|
||||
NIcon {
|
||||
icon: "alert-triangle"
|
||||
pointSize: Style.fontSizeL
|
||||
color: Color.mPrimary
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
}
|
||||
NText {
|
||||
text: I18n.tr("settings.color-scheme.color-source.use-wallpaper-colors.description")
|
||||
// Reuse description; availability is visually indicated
|
||||
pointSize: Style.fontSizeS
|
||||
color: Color.mOnSurfaceVariant
|
||||
wrapMode: Text.WordWrap
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
}
|
||||
|
||||
// Matugen scheme type (visible when wallpaper colors enabled and matugen available)
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: Style.marginM
|
||||
visible: Settings.data.colorSchemes.useWallpaperColors && ProgramCheckerService.matugenAvailable
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: Style.marginS
|
||||
|
||||
Rectangle {
|
||||
width: 28
|
||||
height: 28
|
||||
radius: Style.radiusM
|
||||
color: Color.mSurface
|
||||
|
||||
NIcon {
|
||||
icon: "wand"
|
||||
pointSize: Style.fontSizeL
|
||||
color: Color.mPrimary
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: 2
|
||||
|
||||
NText {
|
||||
text: I18n.tr("settings.color-scheme.color-source.matugen-scheme-type.label")
|
||||
pointSize: Style.fontSizeL
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Color.mOnSurface
|
||||
}
|
||||
|
||||
NText {
|
||||
text: I18n.tr("settings.color-scheme.color-source.matugen-scheme-type.description")
|
||||
pointSize: Style.fontSizeS
|
||||
color: Color.mOnSurfaceVariant
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Matugen scheme options styled like bar position buttons
|
||||
GridLayout {
|
||||
Layout.fillWidth: true
|
||||
columns: 2
|
||||
rowSpacing: Style.marginS
|
||||
columnSpacing: Style.marginS
|
||||
|
||||
Repeater {
|
||||
model: [{
|
||||
"key": "scheme-content",
|
||||
"name": "Content"
|
||||
}, {
|
||||
"key": "scheme-expressive",
|
||||
"name": "Expressive"
|
||||
}, {
|
||||
"key": "scheme-fidelity",
|
||||
"name": "Fidelity"
|
||||
}, {
|
||||
"key": "scheme-fruit-salad",
|
||||
"name": "Fruit Salad"
|
||||
}, {
|
||||
"key": "scheme-monochrome",
|
||||
"name": "Monochrome"
|
||||
}, {
|
||||
"key": "scheme-neutral",
|
||||
"name": "Neutral"
|
||||
}, {
|
||||
"key": "scheme-rainbow",
|
||||
"name": "Rainbow"
|
||||
}, {
|
||||
"key": "scheme-tonal-spot",
|
||||
"name": "Tonal Spot"
|
||||
}]
|
||||
delegate: Rectangle {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 48
|
||||
radius: Style.radiusM
|
||||
border.width: 1
|
||||
|
||||
property bool isActive: Settings.data.colorSchemes.matugenSchemeType === modelData.key
|
||||
|
||||
color: (hoverHandler.hovered || isActive) ? Color.mPrimary : Color.mSurfaceVariant
|
||||
border.color: (hoverHandler.hovered || isActive) ? Color.mPrimary : Color.mOutline
|
||||
opacity: (hoverHandler.hovered || isActive) ? 1.0 : 0.8
|
||||
|
||||
NText {
|
||||
text: modelData.name
|
||||
pointSize: Style.fontSizeM
|
||||
font.weight: (hoverHandler.hovered || parent.isActive) ? Style.fontWeightBold : Style.fontWeightMedium
|
||||
color: (hoverHandler.hovered || parent.isActive) ? Color.mOnPrimary : Color.mOnSurface
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
|
||||
HoverHandler {
|
||||
id: hoverHandler
|
||||
}
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
Settings.data.colorSchemes.matugenSchemeType = modelData.key
|
||||
AppThemeService.generate()
|
||||
}
|
||||
}
|
||||
|
||||
Behavior on color {
|
||||
ColorAnimation {
|
||||
duration: Style.animationFast
|
||||
}
|
||||
}
|
||||
Behavior on border.color {
|
||||
ColorAnimation {
|
||||
duration: Style.animationFast
|
||||
}
|
||||
}
|
||||
Behavior on opacity {
|
||||
NumberAnimation {
|
||||
duration: Style.animationFast
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Divider
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 1
|
||||
color: Color.mOutline
|
||||
opacity: 0.2
|
||||
Layout.topMargin: Style.marginS
|
||||
Layout.bottomMargin: Style.marginS
|
||||
visible: !Settings.data.colorSchemes.useWallpaperColors
|
||||
}
|
||||
|
||||
// Predefined schemes section (visible when wallpaper colors disabled)
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: Style.marginM
|
||||
visible: !Settings.data.colorSchemes.useWallpaperColors
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: Style.marginS
|
||||
|
||||
Rectangle {
|
||||
width: 28
|
||||
height: 28
|
||||
radius: Style.radiusM
|
||||
color: Color.mSurface
|
||||
|
||||
NIcon {
|
||||
icon: "palette"
|
||||
pointSize: Style.fontSizeL
|
||||
color: Color.mPrimary
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: 2
|
||||
|
||||
NText {
|
||||
text: I18n.tr("settings.color-scheme.predefined.section.label")
|
||||
pointSize: Style.fontSizeL
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Color.mOnSurface
|
||||
}
|
||||
|
||||
NText {
|
||||
text: I18n.tr("settings.color-scheme.predefined.section.description")
|
||||
pointSize: Style.fontSizeS
|
||||
color: Color.mOnSurfaceVariant
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Predefined schemes Grid (matches ColorSchemeTab)
|
||||
GridLayout {
|
||||
id: schemesGrid
|
||||
columns: Math.max(2, Math.floor((parent.width - Style.marginM * 2) / 180))
|
||||
rowSpacing: Style.marginM
|
||||
columnSpacing: Style.marginM
|
||||
Layout.fillWidth: true
|
||||
|
||||
Repeater {
|
||||
model: ColorSchemeService.schemes
|
||||
|
||||
delegate: Rectangle {
|
||||
id: schemeItem
|
||||
|
||||
property string schemePath: modelData
|
||||
property string schemeName: root.extractSchemeName(modelData)
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
height: 50
|
||||
radius: Style.radiusS
|
||||
color: root.cacheVersion >= 0 ? root.getSchemeColor(schemeName, "mSurface") : root.getSchemeColor(schemeName, "mSurface")
|
||||
border.width: Math.max(1, Style.borderL)
|
||||
border.color: itemMouseArea.containsMouse ? Color.mTertiary : (Settings.data.colorSchemes.predefinedScheme === schemeName ? Color.mSecondary : Color.mOutline)
|
||||
|
||||
RowLayout {
|
||||
anchors.fill: parent
|
||||
anchors.margins: Style.marginL
|
||||
spacing: Style.marginXS
|
||||
|
||||
NText {
|
||||
text: schemeItem.schemeName
|
||||
pointSize: Style.fontSizeS
|
||||
font.weight: Style.fontWeightMedium
|
||||
color: Color.mOnSurface
|
||||
Layout.fillWidth: true
|
||||
elide: Text.ElideRight
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
wrapMode: Text.WordWrap
|
||||
maximumLineCount: 1
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
width: 14
|
||||
height: 14
|
||||
radius: width * 0.5
|
||||
color: root.cacheVersion >= 0 ? (function () {
|
||||
var mode = Settings.data.colorSchemes.darkMode ? "dark" : "light"
|
||||
var cached = root.schemeColorsCache[schemeItem.schemeName]
|
||||
return (cached && cached[mode] && cached[mode].mPrimary) || root.getSchemeColor(schemeItem.schemeName, "mPrimary")
|
||||
})() : Color.mPrimary
|
||||
}
|
||||
Rectangle {
|
||||
width: 14
|
||||
height: 14
|
||||
radius: width * 0.5
|
||||
color: root.cacheVersion >= 0 ? (function () {
|
||||
var mode = Settings.data.colorSchemes.darkMode ? "dark" : "light"
|
||||
var cached = root.schemeColorsCache[schemeItem.schemeName]
|
||||
return (cached && cached[mode] && cached[mode].mSecondary) || root.getSchemeColor(schemeItem.schemeName, "mSecondary")
|
||||
})() : Color.mSecondary
|
||||
}
|
||||
Rectangle {
|
||||
width: 14
|
||||
height: 14
|
||||
radius: width * 0.5
|
||||
color: root.cacheVersion >= 0 ? (function () {
|
||||
var mode = Settings.data.colorSchemes.darkMode ? "dark" : "light"
|
||||
var cached = root.schemeColorsCache[schemeItem.schemeName]
|
||||
return (cached && cached[mode] && cached[mode].mTertiary) || root.getSchemeColor(schemeItem.schemeName, "mTertiary")
|
||||
})() : Color.mTertiary
|
||||
}
|
||||
Rectangle {
|
||||
width: 14
|
||||
height: 14
|
||||
radius: width * 0.5
|
||||
color: root.cacheVersion >= 0 ? (function () {
|
||||
var mode = Settings.data.colorSchemes.darkMode ? "dark" : "light"
|
||||
var cached = root.schemeColorsCache[schemeItem.schemeName]
|
||||
return (cached && cached[mode] && cached[mode].mError) || root.getSchemeColor(schemeItem.schemeName, "mError")
|
||||
})() : Color.mError
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: itemMouseArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
Settings.data.colorSchemes.useWallpaperColors = false
|
||||
Settings.data.colorSchemes.predefinedScheme = schemeItem.schemeName
|
||||
ColorSchemeService.applyScheme(Settings.data.colorSchemes.predefinedScheme)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Bottom spacer
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: Style.marginL
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Hidden loader to populate schemeColorsCache from files
|
||||
Item {
|
||||
visible: false
|
||||
Repeater {
|
||||
model: ColorSchemeService.schemes
|
||||
delegate: Item {
|
||||
FileView {
|
||||
path: modelData
|
||||
blockLoading: false
|
||||
onLoaded: {
|
||||
var schemeName = root.extractSchemeName(path)
|
||||
try {
|
||||
var jsonData = JSON.parse(text())
|
||||
root.schemeLoaded(schemeName, jsonData)
|
||||
} catch (e) {
|
||||
root.schemeLoaded(schemeName, null)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,508 @@
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Controls
|
||||
import Quickshell
|
||||
import qs.Commons
|
||||
import qs.Services
|
||||
import qs.Widgets
|
||||
|
||||
ColumnLayout {
|
||||
id: root
|
||||
|
||||
property real selectedScaleRatio: 1.0
|
||||
property string selectedBarPosition: "top"
|
||||
property bool selectedDimDesktop: true
|
||||
|
||||
signal scaleRatioChanged(real ratio)
|
||||
signal barPositionChanged(string position)
|
||||
signal dimDesktopChanged(bool dim)
|
||||
|
||||
spacing: Style.marginM
|
||||
|
||||
// Beautiful header with icon
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
Layout.bottomMargin: Style.marginL
|
||||
spacing: Style.marginM
|
||||
|
||||
Rectangle {
|
||||
width: 40
|
||||
height: 40
|
||||
radius: Style.radiusL
|
||||
color: Color.mSurfaceVariant
|
||||
opacity: 0.6
|
||||
|
||||
NIcon {
|
||||
icon: "palette"
|
||||
pointSize: Style.fontSizeL
|
||||
color: Color.mPrimary
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: Style.marginXS
|
||||
|
||||
NText {
|
||||
text: I18n.tr("setup.customize.header")
|
||||
pointSize: Style.fontSizeXL
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Color.mPrimary
|
||||
}
|
||||
|
||||
NText {
|
||||
text: I18n.tr("setup.customize.subheader")
|
||||
pointSize: Style.fontSizeM
|
||||
color: Color.mOnSurfaceVariant
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ScrollView {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
clip: true
|
||||
contentWidth: availableWidth
|
||||
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
|
||||
ScrollBar.vertical.policy: ScrollBar.AsNeeded
|
||||
|
||||
ColumnLayout {
|
||||
width: parent.width
|
||||
spacing: Style.marginM
|
||||
|
||||
// Bar Position section
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: Style.marginM
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: Style.marginS
|
||||
|
||||
Rectangle {
|
||||
width: 28
|
||||
height: 28
|
||||
radius: Style.radiusM
|
||||
color: Color.mSurface
|
||||
|
||||
NIcon {
|
||||
icon: "layout-2"
|
||||
pointSize: Style.fontSizeL
|
||||
color: Color.mPrimary
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: 2
|
||||
|
||||
NText {
|
||||
text: I18n.tr("settings.bar.appearance.position.label")
|
||||
pointSize: Style.fontSizeL
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Color.mOnSurface
|
||||
}
|
||||
|
||||
NText {
|
||||
text: I18n.tr("settings.bar.appearance.position.description")
|
||||
pointSize: Style.fontSizeS
|
||||
color: Color.mOnSurfaceVariant
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: Style.marginS
|
||||
|
||||
Repeater {
|
||||
model: [{
|
||||
"key": "top",
|
||||
"name": I18n.tr("options.bar.position.top"),
|
||||
"icon": "arrow-up"
|
||||
}, {
|
||||
"key": "bottom",
|
||||
"name": I18n.tr("options.bar.position.bottom"),
|
||||
"icon": "arrow-down"
|
||||
}, {
|
||||
"key": "left",
|
||||
"name": I18n.tr("options.bar.position.left"),
|
||||
"icon": "arrow-left"
|
||||
}, {
|
||||
"key": "right",
|
||||
"name": I18n.tr("options.bar.position.right"),
|
||||
"icon": "arrow-right"
|
||||
}]
|
||||
delegate: Rectangle {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 40
|
||||
radius: Style.radiusM
|
||||
border.width: 1
|
||||
|
||||
property bool isActive: selectedBarPosition === modelData.key
|
||||
|
||||
color: (hoverHandler.hovered || isActive) ? Color.mPrimary : Color.mSurfaceVariant
|
||||
border.color: (hoverHandler.hovered || isActive) ? Color.mPrimary : Color.mOutline
|
||||
opacity: (hoverHandler.hovered || isActive) ? 1.0 : 0.8
|
||||
|
||||
NText {
|
||||
text: modelData.name
|
||||
pointSize: Style.fontSizeM
|
||||
font.weight: (hoverHandler.hovered || parent.isActive) ? Style.fontWeightBold : Style.fontWeightMedium
|
||||
color: (hoverHandler.hovered || parent.isActive) ? Color.mOnPrimary : Color.mOnSurface
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
|
||||
HoverHandler {
|
||||
id: hoverHandler
|
||||
}
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
selectedBarPosition = modelData.key
|
||||
barPositionChanged(modelData.key)
|
||||
}
|
||||
}
|
||||
|
||||
Behavior on color {
|
||||
ColorAnimation {
|
||||
duration: Style.animationFast
|
||||
}
|
||||
}
|
||||
Behavior on border.color {
|
||||
ColorAnimation {
|
||||
duration: Style.animationFast
|
||||
}
|
||||
}
|
||||
Behavior on opacity {
|
||||
NumberAnimation {
|
||||
duration: Style.animationFast
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Divider
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 1
|
||||
color: Color.mOutline
|
||||
opacity: 0.2
|
||||
Layout.topMargin: Style.marginS
|
||||
Layout.bottomMargin: Style.marginS
|
||||
}
|
||||
|
||||
// Dim Desktop section
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: Style.marginM
|
||||
|
||||
Rectangle {
|
||||
width: 32
|
||||
height: 32
|
||||
radius: Style.radiusM
|
||||
color: Color.mSurface
|
||||
NIcon {
|
||||
icon: "moon"
|
||||
pointSize: Style.fontSizeL
|
||||
color: Color.mPrimary
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: 2
|
||||
NText {
|
||||
text: I18n.tr("settings.user-interface.dim-desktop.label")
|
||||
pointSize: Style.fontSizeL
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Color.mOnSurface
|
||||
}
|
||||
NText {
|
||||
text: I18n.tr("settings.user-interface.dim-desktop.description")
|
||||
pointSize: Style.fontSizeS
|
||||
color: Color.mOnSurfaceVariant
|
||||
wrapMode: Text.WordWrap
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
}
|
||||
|
||||
NToggle {
|
||||
checked: selectedDimDesktop
|
||||
onToggled: function (checked) {
|
||||
selectedDimDesktop = checked
|
||||
dimDesktopChanged(checked)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Divider
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 1
|
||||
color: Color.mOutline
|
||||
opacity: 0.2
|
||||
Layout.topMargin: Style.marginS
|
||||
Layout.bottomMargin: Style.marginS
|
||||
}
|
||||
|
||||
// Bar Density section
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: Style.marginM
|
||||
|
||||
Rectangle {
|
||||
width: 32
|
||||
height: 32
|
||||
radius: Style.radiusM
|
||||
color: Color.mSurface
|
||||
NIcon {
|
||||
icon: "minimize"
|
||||
pointSize: Style.fontSizeL
|
||||
color: Color.mPrimary
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: 2
|
||||
NText {
|
||||
text: I18n.tr("settings.bar.appearance.density.label")
|
||||
pointSize: Style.fontSizeL
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Color.mOnSurface
|
||||
}
|
||||
NText {
|
||||
text: I18n.tr("settings.bar.appearance.density.description")
|
||||
pointSize: Style.fontSizeS
|
||||
color: Color.mOnSurfaceVariant
|
||||
wrapMode: Text.WordWrap
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
spacing: Style.marginS
|
||||
Repeater {
|
||||
model: [{
|
||||
"key": "mini",
|
||||
"name": I18n.tr("options.bar.density.mini")
|
||||
}, {
|
||||
"key": "compact",
|
||||
"name": I18n.tr("options.bar.density.compact")
|
||||
}, {
|
||||
"key": "default",
|
||||
"name": I18n.tr("options.bar.density.default")
|
||||
}, {
|
||||
"key": "comfortable",
|
||||
"name": I18n.tr("options.bar.density.comfortable")
|
||||
}]
|
||||
delegate: Rectangle {
|
||||
radius: 16
|
||||
border.width: 1
|
||||
Layout.preferredHeight: 32
|
||||
Layout.preferredWidth: Math.max(90, densityText.implicitWidth + Style.marginXL * 2)
|
||||
|
||||
property bool isActive: Settings.data.bar.density === modelData.key
|
||||
|
||||
color: (hoverHandler.hovered || isActive) ? Color.mPrimary : Color.mSurfaceVariant
|
||||
border.color: (hoverHandler.hovered || isActive) ? Color.mPrimary : Color.mOutline
|
||||
opacity: (hoverHandler.hovered || isActive) ? 1.0 : 0.8
|
||||
|
||||
NText {
|
||||
id: densityText
|
||||
text: modelData.name
|
||||
pointSize: Style.fontSizeS
|
||||
font.weight: (hoverHandler.hovered || parent.isActive) ? Style.fontWeightBold : Style.fontWeightMedium
|
||||
color: (hoverHandler.hovered || parent.isActive) ? Color.mOnPrimary : Color.mOnSurface
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
|
||||
HoverHandler {
|
||||
id: hoverHandler
|
||||
}
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
Settings.data.bar.density = modelData.key
|
||||
}
|
||||
}
|
||||
|
||||
Behavior on color {
|
||||
ColorAnimation {
|
||||
duration: Style.animationFast
|
||||
}
|
||||
}
|
||||
Behavior on border.color {
|
||||
ColorAnimation {
|
||||
duration: Style.animationFast
|
||||
}
|
||||
}
|
||||
Behavior on opacity {
|
||||
NumberAnimation {
|
||||
duration: Style.animationFast
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Divider
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 1
|
||||
color: Color.mOutline
|
||||
opacity: 0.2
|
||||
Layout.topMargin: Style.marginS
|
||||
Layout.bottomMargin: Style.marginS
|
||||
}
|
||||
|
||||
// UI Scale section
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: Style.marginM
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: Style.marginS
|
||||
Rectangle {
|
||||
width: 32
|
||||
height: 32
|
||||
radius: Style.radiusM
|
||||
color: Color.mSurface
|
||||
NIcon {
|
||||
icon: "maximize"
|
||||
pointSize: Style.fontSizeL
|
||||
color: Color.mPrimary
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
}
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: 2
|
||||
NText {
|
||||
text: I18n.tr("settings.user-interface.scaling.label")
|
||||
pointSize: Style.fontSizeL
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Color.mOnSurface
|
||||
}
|
||||
NText {
|
||||
text: I18n.tr("settings.user-interface.scaling.description")
|
||||
pointSize: Style.fontSizeS
|
||||
color: Color.mOnSurfaceVariant
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NValueSlider {
|
||||
Layout.fillWidth: true
|
||||
from: 0.8
|
||||
to: 1.2
|
||||
stepSize: 0.05
|
||||
value: selectedScaleRatio
|
||||
onMoved: function (value) {
|
||||
selectedScaleRatio = value
|
||||
scaleRatioChanged(value)
|
||||
}
|
||||
text: Math.floor(selectedScaleRatio * 100) + "%"
|
||||
}
|
||||
}
|
||||
|
||||
// Divider
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 1
|
||||
color: Color.mOutline
|
||||
opacity: 0.2
|
||||
Layout.topMargin: Style.marginS
|
||||
Layout.bottomMargin: Style.marginS
|
||||
}
|
||||
|
||||
// Bar Floating toggle
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: Style.marginM
|
||||
Rectangle {
|
||||
width: 32
|
||||
height: 32
|
||||
radius: Style.radiusM
|
||||
color: Color.mSurface
|
||||
NIcon {
|
||||
icon: "layout-2"
|
||||
pointSize: Style.fontSizeL
|
||||
color: Color.mPrimary
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
}
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: 2
|
||||
NText {
|
||||
text: I18n.tr("settings.bar.appearance.floating.label")
|
||||
pointSize: Style.fontSizeL
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Color.mOnSurface
|
||||
}
|
||||
NText {
|
||||
text: I18n.tr("settings.bar.appearance.floating.description")
|
||||
pointSize: Style.fontSizeS
|
||||
color: Color.mOnSurfaceVariant
|
||||
wrapMode: Text.WordWrap
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
}
|
||||
NToggle {
|
||||
checked: Settings.data.bar.floating
|
||||
onToggled: function (checked) {
|
||||
Settings.data.bar.floating = checked
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Divider
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 1
|
||||
color: Color.mOutline
|
||||
opacity: 0.2
|
||||
Layout.topMargin: Style.marginS
|
||||
Layout.bottomMargin: Style.marginS
|
||||
}
|
||||
|
||||
// Bar Background Opacity
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: Style.marginM
|
||||
NLabel {
|
||||
label: I18n.tr("settings.bar.appearance.background-opacity.label")
|
||||
description: I18n.tr("settings.bar.appearance.background-opacity.description")
|
||||
}
|
||||
NValueSlider {
|
||||
Layout.fillWidth: true
|
||||
from: 0
|
||||
to: 1
|
||||
stepSize: 0.01
|
||||
value: Settings.data.bar.backgroundOpacity
|
||||
onMoved: function (value) {
|
||||
Settings.data.bar.backgroundOpacity = value
|
||||
}
|
||||
text: Math.floor(Settings.data.bar.backgroundOpacity * 100) + "%"
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: Style.marginL
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,508 @@
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Effects
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import qs.Commons
|
||||
import qs.Services
|
||||
import qs.Widgets
|
||||
import "../../Helpers/FuzzySort.js" as FuzzySort
|
||||
|
||||
ColumnLayout {
|
||||
id: root
|
||||
|
||||
property string selectedDirectory: ""
|
||||
property string selectedWallpaper: ""
|
||||
|
||||
signal directoryChanged(string directory)
|
||||
signal wallpaperChanged(string wallpaper)
|
||||
|
||||
spacing: Style.marginL
|
||||
|
||||
// Beautiful header with icon
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
Layout.bottomMargin: Style.marginL
|
||||
spacing: Style.marginM
|
||||
|
||||
RowLayout {
|
||||
spacing: Style.marginM
|
||||
|
||||
Rectangle {
|
||||
width: 40
|
||||
height: 40
|
||||
radius: Style.radiusL
|
||||
color: Color.mSurfaceVariant
|
||||
opacity: 0.6
|
||||
|
||||
NIcon {
|
||||
icon: "image"
|
||||
pointSize: Style.fontSizeL
|
||||
color: Color.mPrimary
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
spacing: Style.marginXS
|
||||
|
||||
NText {
|
||||
text: I18n.tr("setup.wallpaper.header")
|
||||
pointSize: Style.fontSizeXL
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Color.mPrimary
|
||||
}
|
||||
|
||||
NText {
|
||||
text: I18n.tr("setup.wallpaper.subheader")
|
||||
pointSize: Style.fontSizeM
|
||||
color: Color.mOnSurfaceVariant
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Large preview with rounded corners and shadow effect
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
Layout.minimumHeight: 180
|
||||
color: Color.mSurfaceVariant
|
||||
radius: Style.radiusL
|
||||
border.color: selectedWallpaper !== "" ? Color.mPrimary : Color.mOutline
|
||||
border.width: selectedWallpaper !== "" ? 2 : 1
|
||||
clip: true
|
||||
|
||||
// Mirror WallpaperPanel approach with rounded shader mask
|
||||
NImageCached {
|
||||
id: previewCached
|
||||
anchors.fill: parent
|
||||
anchors.margins: 4
|
||||
maxCacheDimension: 512
|
||||
cacheFolder: Settings.cacheDirImagesWallpapers
|
||||
imagePath: selectedWallpaper !== "" ? "file://" + selectedWallpaper : ""
|
||||
visible: false // used as texture source for the shader
|
||||
}
|
||||
|
||||
ShaderEffect {
|
||||
anchors.fill: parent
|
||||
anchors.margins: 4
|
||||
property var source: ShaderEffectSource {
|
||||
sourceItem: previewCached
|
||||
hideSource: true
|
||||
live: true
|
||||
recursive: false
|
||||
format: ShaderEffectSource.RGBA
|
||||
}
|
||||
property real itemWidth: width
|
||||
property real itemHeight: height
|
||||
property real cornerRadius: Style.radiusL
|
||||
property real imageOpacity: 1.0
|
||||
fragmentShader: Qt.resolvedUrl(Quickshell.shellDir + "/Shaders/qsb/rounded_image.frag.qsb")
|
||||
supportsAtlasTextures: false
|
||||
blending: true
|
||||
}
|
||||
|
||||
// Loading placeholder
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: Color.mSurfaceVariant
|
||||
radius: Style.radiusL
|
||||
visible: (previewCached.status === Image.Loading || previewCached.status === Image.Null) && selectedWallpaper !== ""
|
||||
|
||||
NIcon {
|
||||
icon: "image"
|
||||
pointSize: Style.fontSizeXXL
|
||||
color: Color.mOnSurfaceVariant
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
}
|
||||
|
||||
// Error placeholder
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: Color.mError
|
||||
opacity: 0.1
|
||||
radius: Style.radiusL
|
||||
visible: previewCached.status === Image.Error && selectedWallpaper !== ""
|
||||
|
||||
ColumnLayout {
|
||||
anchors.centerIn: parent
|
||||
spacing: Style.marginS
|
||||
|
||||
NIcon {
|
||||
icon: "alert-circle"
|
||||
pointSize: Style.fontSizeXXL
|
||||
color: Color.mError
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
|
||||
NText {
|
||||
text: I18n.tr("setup.wallpaper.preview-error")
|
||||
pointSize: Style.fontSizeS
|
||||
color: Color.mError
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NBusyIndicator {
|
||||
anchors.centerIn: parent
|
||||
visible: (previewCached.status === Image.Loading || previewCached.status === Image.Null) && selectedWallpaper !== ""
|
||||
running: visible
|
||||
size: 28
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
anchors.centerIn: parent
|
||||
spacing: Style.marginL
|
||||
visible: selectedWallpaper === ""
|
||||
opacity: 0.6
|
||||
|
||||
Rectangle {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
width: 64
|
||||
height: 64
|
||||
radius: width / 2
|
||||
color: Color.mPrimary
|
||||
opacity: 0.15
|
||||
|
||||
NIcon {
|
||||
icon: "sparkles"
|
||||
pointSize: Style.fontSizeXXL
|
||||
color: Color.mPrimary
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
}
|
||||
|
||||
NText {
|
||||
text: I18n.tr("setup.wallpaper.select-prompt")
|
||||
pointSize: Style.fontSizeL
|
||||
color: Color.mOnSurfaceVariant
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
font.weight: Style.fontWeightMedium
|
||||
}
|
||||
}
|
||||
|
||||
Behavior on border.color {
|
||||
ColorAnimation {
|
||||
duration: Style.animationFast
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Wallpaper gallery strip
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 90
|
||||
visible: filteredWallpapers.length > 0
|
||||
|
||||
ScrollView {
|
||||
anchors.fill: parent
|
||||
clip: true
|
||||
ScrollBar.horizontal.policy: ScrollBar.AsNeeded
|
||||
ScrollBar.vertical.policy: ScrollBar.AlwaysOff
|
||||
|
||||
RowLayout {
|
||||
spacing: Style.marginM
|
||||
height: parent.height
|
||||
|
||||
Repeater {
|
||||
model: filteredWallpapers
|
||||
delegate: Rectangle {
|
||||
Layout.preferredWidth: 120
|
||||
Layout.preferredHeight: 80
|
||||
color: Color.mSurface
|
||||
radius: Style.radiusM
|
||||
border.color: selectedWallpaper === modelData ? Color.mPrimary : Color.mOutline
|
||||
border.width: selectedWallpaper === modelData ? 2 : 1
|
||||
clip: true
|
||||
|
||||
// Cached thumbnail (used as shader source)
|
||||
NImageCached {
|
||||
id: thumbCached
|
||||
anchors.fill: parent
|
||||
anchors.margins: 3
|
||||
maxCacheDimension: 256
|
||||
cacheFolder: Settings.cacheDirImagesWallpapers
|
||||
imagePath: "file://" + modelData
|
||||
visible: false
|
||||
}
|
||||
|
||||
ShaderEffect {
|
||||
anchors.fill: parent
|
||||
anchors.margins: 3
|
||||
property var source: ShaderEffectSource {
|
||||
sourceItem: thumbCached
|
||||
hideSource: true
|
||||
live: true
|
||||
recursive: false
|
||||
format: ShaderEffectSource.RGBA
|
||||
}
|
||||
property real itemWidth: width
|
||||
property real itemHeight: height
|
||||
property real cornerRadius: Style.radiusM - 3
|
||||
property real imageOpacity: 1.0
|
||||
fragmentShader: Qt.resolvedUrl(Quickshell.shellDir + "/Shaders/qsb/rounded_image.frag.qsb")
|
||||
supportsAtlasTextures: false
|
||||
blending: true
|
||||
}
|
||||
|
||||
// Loading state
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: Color.mSurfaceVariant
|
||||
radius: Style.radiusM
|
||||
visible: thumbCached.status === Image.Loading
|
||||
|
||||
NIcon {
|
||||
icon: "image"
|
||||
pointSize: Style.fontSizeL
|
||||
color: Color.mOnSurfaceVariant
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
}
|
||||
|
||||
// Error state
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: Color.mSurfaceVariant
|
||||
radius: Style.radiusM
|
||||
visible: thumbCached.status === Image.Error
|
||||
|
||||
NIcon {
|
||||
icon: "image"
|
||||
pointSize: Style.fontSizeL
|
||||
color: Color.mOnSurfaceVariant
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
}
|
||||
|
||||
NBusyIndicator {
|
||||
anchors.centerIn: parent
|
||||
visible: thumbCached.status === Image.Loading || thumbCached.status === Image.Null
|
||||
running: visible
|
||||
size: 18
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: Color.mPrimary
|
||||
opacity: hoverHandler.hovered ? 0.1 : 0
|
||||
radius: Style.radiusM
|
||||
Behavior on opacity {
|
||||
NumberAnimation {
|
||||
duration: Style.animationFast
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
visible: selectedWallpaper === modelData
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.margins: 6
|
||||
width: 24
|
||||
height: 24
|
||||
radius: width / 2
|
||||
color: Color.mPrimary
|
||||
|
||||
NIcon {
|
||||
icon: "check"
|
||||
pointSize: Style.fontSizeS
|
||||
color: Color.mOnPrimary
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
}
|
||||
|
||||
HoverHandler {
|
||||
id: hoverHandler
|
||||
}
|
||||
|
||||
TapHandler {
|
||||
onTapped: {
|
||||
selectedWallpaper = modelData
|
||||
wallpaperChanged(modelData)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Helpful info card
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 80
|
||||
color: Color.mSurfaceVariant
|
||||
radius: Style.radiusM
|
||||
opacity: 0.4
|
||||
visible: filteredWallpapers.length === 0
|
||||
|
||||
RowLayout {
|
||||
anchors.fill: parent
|
||||
anchors.margins: Style.marginL
|
||||
spacing: Style.marginM
|
||||
|
||||
NIcon {
|
||||
icon: "folder-open"
|
||||
pointSize: Style.fontSizeL
|
||||
color: Color.mOnSurfaceVariant
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: Style.marginXS
|
||||
NText {
|
||||
text: filteredWallpapers.length === 0 && selectedDirectory !== "" ? I18n.tr("setup.wallpaper.none-in-dir") : I18n.tr("setup.wallpaper.no-dir")
|
||||
pointSize: Style.fontSizeM
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Color.mOnSurfaceVariant
|
||||
}
|
||||
NText {
|
||||
text: selectedDirectory !== "" ? I18n.tr("setup.wallpaper.no-valid", {
|
||||
"dir": selectedDirectory
|
||||
}) : I18n.tr("setup.wallpaper.choose-dir")
|
||||
pointSize: Style.fontSizeS
|
||||
color: Color.mOnSurfaceVariant
|
||||
wrapMode: Text.WordWrap
|
||||
Layout.fillWidth: true
|
||||
opacity: 0.8
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Directory selection
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: Style.marginM
|
||||
|
||||
NTextInputButton {
|
||||
id: wallpaperPathInput
|
||||
label: I18n.tr("setup.wallpaper.dir.label")
|
||||
description: I18n.tr("setup.wallpaper.dir.description")
|
||||
text: selectedDirectory
|
||||
buttonIcon: "folder-open"
|
||||
buttonTooltip: I18n.tr("setup.wallpaper.dir.browse")
|
||||
Layout.fillWidth: true
|
||||
onInputEditingFinished: {
|
||||
selectedDirectory = text
|
||||
directoryChanged(text)
|
||||
}
|
||||
onButtonClicked: directoryPicker.open()
|
||||
}
|
||||
}
|
||||
|
||||
// Internal properties and functions
|
||||
property list<string> wallpapersList: []
|
||||
property list<string> filteredWallpapers: []
|
||||
|
||||
function updateFilteredWallpapers() {
|
||||
filteredWallpapers = wallpapersList
|
||||
}
|
||||
|
||||
function refreshWallpapers() {
|
||||
if (!selectedDirectory || selectedDirectory === "") {
|
||||
wallpapersList = []
|
||||
filteredWallpapers = []
|
||||
return
|
||||
}
|
||||
if (typeof WallpaperService !== "undefined" && WallpaperService.getWallpapersList) {
|
||||
var wallpapers = WallpaperService.getWallpapersList(Screen.name)
|
||||
wallpapersList = wallpapers
|
||||
updateFilteredWallpapers()
|
||||
if (wallpapersList.length > 0 && selectedWallpaper === "") {
|
||||
selectedWallpaper = wallpapersList[0]
|
||||
}
|
||||
} else {
|
||||
readDirectoryImages(selectedDirectory)
|
||||
}
|
||||
}
|
||||
|
||||
function readDirectoryImages(directoryPath) {
|
||||
directoryScanner.command = ["find", directoryPath, "-type", "f", "\\(-iname", "*.jpg", "-o", "-iname", "*.jpeg", "-o", "-iname", "*.png", "-o", "-iname", "*.bmp", "-o", "-iname", "*.webp", "-o", "-iname", "*.svg", "\\)"]
|
||||
directoryScanner.running = true
|
||||
return []
|
||||
}
|
||||
|
||||
onSelectedDirectoryChanged: {
|
||||
if (typeof Settings !== "undefined" && Settings.data && Settings.data.wallpaper) {
|
||||
Settings.data.wallpaper.directory = selectedDirectory
|
||||
}
|
||||
if (typeof WallpaperService !== "undefined" && WallpaperService.refreshWallpapersList) {
|
||||
WallpaperService.refreshWallpapersList()
|
||||
}
|
||||
Qt.callLater(refreshWallpapers)
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: WallpaperService
|
||||
enabled: typeof WallpaperService !== "undefined"
|
||||
function onWallpaperListChanged(screenName, count) {
|
||||
if (screenName === Screen.name) {
|
||||
Qt.callLater(refreshWallpapers)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: initialRefreshTimer
|
||||
interval: 1000
|
||||
running: false
|
||||
repeat: false
|
||||
onTriggered: refreshWallpapers()
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
if (typeof Settings !== "undefined" && Settings.data && Settings.data.wallpaper && Settings.data.wallpaper.directory) {
|
||||
selectedDirectory = Settings.data.wallpaper.directory
|
||||
} else {
|
||||
selectedDirectory = Quickshell.env("HOME") + "/Pictures/Wallpapers"
|
||||
}
|
||||
if (typeof WallpaperService !== "undefined" && WallpaperService.currentWallpaper) {
|
||||
selectedWallpaper = WallpaperService.currentWallpaper
|
||||
}
|
||||
initialRefreshTimer.start()
|
||||
}
|
||||
|
||||
NFilePicker {
|
||||
id: directoryPicker
|
||||
selectionMode: "folders"
|
||||
title: I18n.tr("setup.wallpaper.dir.select-title")
|
||||
initialPath: selectedDirectory || Quickshell.env("HOME") + "/Pictures"
|
||||
onAccepted: paths => {
|
||||
if (paths.length > 0) {
|
||||
selectedDirectory = paths[0]
|
||||
directoryChanged(paths[0])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Process {
|
||||
id: directoryScanner
|
||||
command: ["find", "", "-type", "f", "\\(-iname", "*.jpg", "-o", "-iname", "*.jpeg", "-o", "-iname", "*.png", "-o", "-iname", "*.bmp", "-o", "-iname", "*.webp", "-o", "-iname", "*.svg", "\\)"]
|
||||
running: false
|
||||
stdout: StdioCollector {}
|
||||
stderr: StdioCollector {}
|
||||
onExited: function (exitCode) {
|
||||
if (exitCode === 0) {
|
||||
var lines = stdout.text.split('\n')
|
||||
var images = []
|
||||
for (var i = 0; i < lines.length; i++) {
|
||||
var line = lines[i].trim()
|
||||
if (line !== '') {
|
||||
images.push(line)
|
||||
}
|
||||
}
|
||||
wallpapersList = images
|
||||
updateFilteredWallpapers()
|
||||
if (wallpapersList.length > 0 && selectedWallpaper === "") {
|
||||
selectedWallpaper = wallpapersList[0]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,414 @@
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Controls
|
||||
import Quickshell
|
||||
import Quickshell.Wayland
|
||||
import qs.Commons
|
||||
import qs.Services
|
||||
import qs.Widgets
|
||||
|
||||
NPanel {
|
||||
id: root
|
||||
|
||||
preferredWidth: 520
|
||||
preferredHeight: 600
|
||||
preferredWidthRatio: 0.4
|
||||
preferredHeightRatio: 0.6
|
||||
panelAnchorHorizontalCenter: true
|
||||
panelAnchorVerticalCenter: true
|
||||
panelKeyboardFocus: true
|
||||
|
||||
// Prevent closing during setup
|
||||
backgroundClickEnabled: false
|
||||
draggable: false
|
||||
|
||||
property int currentStep: 0
|
||||
property int totalSteps: 4
|
||||
|
||||
// Setup wizard data
|
||||
property string selectedWallpaperDirectory: Settings.defaultWallpapersDirectory
|
||||
property string selectedWallpaper: ""
|
||||
property real selectedScaleRatio: 1.0
|
||||
property string selectedBarPosition: "top"
|
||||
property bool selectedDimDesktop: true
|
||||
|
||||
panelContent: Component {
|
||||
Item {
|
||||
id: container
|
||||
anchors.fill: parent
|
||||
|
||||
ColumnLayout {
|
||||
id: wizardContent
|
||||
anchors.fill: parent
|
||||
anchors.margins: Style.marginXL
|
||||
spacing: Style.marginL
|
||||
|
||||
// Override ESC key to prevent closing during setup
|
||||
Shortcut {
|
||||
sequences: ["Escape"]
|
||||
enabled: root.active
|
||||
onActivated: {
|
||||
|
||||
// Do nothing - prevent ESC from closing the setup wizard
|
||||
}
|
||||
context: Qt.WindowShortcut
|
||||
}
|
||||
|
||||
// Step content - takes most of the space
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
Layout.minimumHeight: 300
|
||||
|
||||
StackLayout {
|
||||
id: stepStack
|
||||
anchors.fill: parent
|
||||
currentIndex: currentStep
|
||||
|
||||
// Step 0: Welcome - Beautiful centered design
|
||||
Item {
|
||||
ColumnLayout {
|
||||
anchors.centerIn: parent
|
||||
width: Math.min(parent.width - Style.marginXL * 2, 420)
|
||||
spacing: Style.marginXL
|
||||
|
||||
// Logo with subtle glow effect
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 120
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
|
||||
Rectangle {
|
||||
anchors.centerIn: parent
|
||||
width: 120
|
||||
height: 120
|
||||
radius: width / 2
|
||||
color: Color.mPrimary
|
||||
opacity: 0.08
|
||||
scale: 1.3
|
||||
}
|
||||
|
||||
Image {
|
||||
anchors.centerIn: parent
|
||||
width: 110
|
||||
height: 110
|
||||
source: Qt.resolvedUrl(Quickshell.shellDir + "/Assets/noctalia.svg")
|
||||
fillMode: Image.PreserveAspectFit
|
||||
smooth: true
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: Color.mSurfaceVariant
|
||||
radius: width / 2
|
||||
border.color: Color.mOutline
|
||||
border.width: 2
|
||||
visible: parent.status === Image.Error
|
||||
|
||||
NIcon {
|
||||
icon: "sparkles"
|
||||
pointSize: Style.fontSizeXXL * 1.5
|
||||
color: Color.mPrimary
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
}
|
||||
|
||||
// Subtle pulse animation
|
||||
SequentialAnimation on scale {
|
||||
running: true
|
||||
loops: Animation.Infinite
|
||||
NumberAnimation {
|
||||
from: 1.0
|
||||
to: 1.05
|
||||
duration: 2000
|
||||
easing.type: Easing.InOutQuad
|
||||
}
|
||||
NumberAnimation {
|
||||
from: 1.05
|
||||
to: 1.0
|
||||
duration: 2000
|
||||
easing.type: Easing.InOutQuad
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Welcome text with gradient feel
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
spacing: Style.marginM
|
||||
|
||||
NText {
|
||||
text: "Welcome to Noctalia! ✨"
|
||||
pointSize: Style.fontSizeXXL * 1.4
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Color.mOnSurface
|
||||
Layout.fillWidth: true
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
}
|
||||
|
||||
NText {
|
||||
text: "Let's make your desktop uniquely yours"
|
||||
pointSize: Style.fontSizeL
|
||||
color: Color.mOnSurfaceVariant
|
||||
Layout.fillWidth: true
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
|
||||
// Friendly subtext
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: Style.marginL
|
||||
Layout.preferredHeight: childrenRect.height + Style.marginM * 2
|
||||
color: Color.mSurfaceVariant
|
||||
radius: Style.radiusL
|
||||
opacity: 0.4
|
||||
|
||||
NText {
|
||||
anchors.centerIn: parent
|
||||
width: parent.width - Style.marginL * 2
|
||||
text: I18n.tr("setup.welcome.note")
|
||||
pointSize: Style.fontSizeM
|
||||
color: Color.mOnSurfaceVariant
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Step 1: Wallpaper Setup
|
||||
SetupWallpaperStep {
|
||||
id: step1
|
||||
selectedDirectory: root.selectedWallpaperDirectory
|
||||
selectedWallpaper: root.selectedWallpaper
|
||||
onDirectoryChanged: function (directory) {
|
||||
root.selectedWallpaperDirectory = directory
|
||||
root.applyWallpaperSettings()
|
||||
}
|
||||
onWallpaperChanged: function (wallpaper) {
|
||||
root.selectedWallpaper = wallpaper
|
||||
root.applyWallpaperSettings()
|
||||
}
|
||||
}
|
||||
|
||||
// Step 2: UI Configuration
|
||||
SetupCustomizeStep {
|
||||
id: step2
|
||||
selectedScaleRatio: root.selectedScaleRatio
|
||||
selectedBarPosition: root.selectedBarPosition
|
||||
selectedDimDesktop: root.selectedDimDesktop
|
||||
onScaleRatioChanged: function (ratio) {
|
||||
root.selectedScaleRatio = ratio
|
||||
root.applyUISettings()
|
||||
}
|
||||
onBarPositionChanged: function (position) {
|
||||
root.selectedBarPosition = position
|
||||
root.applyUISettings()
|
||||
}
|
||||
onDimDesktopChanged: function (dim) {
|
||||
root.selectedDimDesktop = dim
|
||||
root.applyUISettings()
|
||||
}
|
||||
}
|
||||
|
||||
// Step 3: Appearance - Dark mode and color source
|
||||
SetupAppearanceStep {
|
||||
id: step3
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Elegant divider
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 1
|
||||
color: Color.mOutline
|
||||
opacity: 0.2
|
||||
}
|
||||
|
||||
// Modern progress indicator with labels
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 32
|
||||
|
||||
RowLayout {
|
||||
anchors.centerIn: parent
|
||||
spacing: Style.marginM
|
||||
|
||||
Repeater {
|
||||
model: [{
|
||||
"icon": "sparkles",
|
||||
"label": "Welcome"
|
||||
}, {
|
||||
"icon": "image",
|
||||
"label": "Wallpaper"
|
||||
}, {
|
||||
"icon": "settings",
|
||||
"label": "Customize"
|
||||
}, {
|
||||
"icon": "palette",
|
||||
"label": "Appearance"
|
||||
}]
|
||||
delegate: RowLayout {
|
||||
spacing: Style.marginS
|
||||
|
||||
Rectangle {
|
||||
width: 24
|
||||
height: 24
|
||||
radius: width / 2
|
||||
color: index <= currentStep ? Color.mPrimary : Color.mSurfaceVariant
|
||||
border.color: index === currentStep ? Color.mPrimary : "transparent"
|
||||
border.width: index === currentStep ? 2 : 0
|
||||
|
||||
NIcon {
|
||||
icon: modelData.icon
|
||||
pointSize: Style.fontSizeS
|
||||
color: index <= currentStep ? Color.mOnPrimary : Color.mOnSurfaceVariant
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
|
||||
Behavior on color {
|
||||
ColorAnimation {
|
||||
duration: Style.animationNormal
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NText {
|
||||
text: modelData.label
|
||||
pointSize: Style.fontSizeS
|
||||
color: index <= currentStep ? Color.mPrimary : Color.mOnSurfaceVariant
|
||||
font.weight: index === currentStep ? Style.fontWeightBold : Style.fontWeightRegular
|
||||
|
||||
Behavior on color {
|
||||
ColorAnimation {
|
||||
duration: Style.animationNormal
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Connector line
|
||||
Rectangle {
|
||||
width: 40
|
||||
height: 2
|
||||
radius: 1
|
||||
color: index < currentStep ? Color.mPrimary : Color.mSurfaceVariant
|
||||
visible: index < totalSteps - 1
|
||||
|
||||
Behavior on color {
|
||||
ColorAnimation {
|
||||
duration: Style.animationNormal
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Smooth navigation buttons
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 44
|
||||
Layout.topMargin: Style.marginS
|
||||
|
||||
RowLayout {
|
||||
anchors.fill: parent
|
||||
spacing: Style.marginM
|
||||
|
||||
NButton {
|
||||
text: "Skip Setup"
|
||||
outlined: true
|
||||
visible: currentStep === 0
|
||||
Layout.preferredHeight: 44
|
||||
onClicked: {
|
||||
root.completeSetup()
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
NButton {
|
||||
text: "← Back"
|
||||
outlined: true
|
||||
visible: currentStep > 0
|
||||
Layout.preferredHeight: 44
|
||||
onClicked: {
|
||||
if (currentStep > 0) {
|
||||
currentStep--
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NButton {
|
||||
text: currentStep === totalSteps - 1 ? "All Done!" : "Continue →"
|
||||
Layout.preferredHeight: 44
|
||||
onClicked: {
|
||||
if (currentStep < totalSteps - 1) {
|
||||
currentStep++
|
||||
} else {
|
||||
root.completeSetup()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function completeSetup() {
|
||||
Logger.log("SetupWizard", "Completing setup with selected options")
|
||||
|
||||
if (selectedWallpaperDirectory !== Settings.data.wallpaper.directory) {
|
||||
Settings.data.wallpaper.directory = selectedWallpaperDirectory
|
||||
WallpaperService.refreshWallpapersList()
|
||||
}
|
||||
|
||||
if (selectedWallpaper !== "") {
|
||||
WallpaperService.changeWallpaper(selectedWallpaper, undefined)
|
||||
}
|
||||
|
||||
Settings.data.general.scaleRatio = selectedScaleRatio
|
||||
Settings.data.bar.position = selectedBarPosition
|
||||
Settings.data.general.dimDesktop = selectedDimDesktop
|
||||
Settings.data.setupCompleted = true
|
||||
|
||||
Settings.saveImmediate()
|
||||
Logger.log("SetupWizard", "Setup completed successfully")
|
||||
root.close()
|
||||
}
|
||||
|
||||
function applyWallpaperSettings() {
|
||||
if (selectedWallpaperDirectory !== Settings.data.wallpaper.directory) {
|
||||
Settings.data.wallpaper.directory = selectedWallpaperDirectory
|
||||
WallpaperService.refreshWallpapersList()
|
||||
}
|
||||
|
||||
if (selectedWallpaper !== "") {
|
||||
WallpaperService.changeWallpaper(selectedWallpaper, undefined)
|
||||
}
|
||||
}
|
||||
|
||||
function applyUISettings() {
|
||||
Settings.data.general.scaleRatio = selectedScaleRatio
|
||||
Settings.data.bar.position = selectedBarPosition
|
||||
Settings.data.general.dimDesktop = selectedDimDesktop
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
Logger.log("SetupWizard", "Setup wizard opened")
|
||||
// Initialize selections from existing settings to avoid overwriting user config
|
||||
if (Settings && Settings.data) {
|
||||
selectedScaleRatio = Settings.data.general.scaleRatio
|
||||
selectedBarPosition = Settings.data.bar.position
|
||||
selectedDimDesktop = Settings.data.general.dimDesktop
|
||||
selectedWallpaperDirectory = Settings.data.wallpaper.directory || Settings.defaultWallpapersDirectory
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -423,7 +423,6 @@ NPanel {
|
||||
NIcon {
|
||||
icon: "check"
|
||||
pointSize: Style.fontSizeM
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Color.mOnSecondary
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
|
||||
@@ -105,8 +105,8 @@ Singleton {
|
||||
// Wallpaper Colors Generation
|
||||
// --------------------------------------------------------------------------------
|
||||
function generateFromWallpaper() {
|
||||
Logger.log("AppThemeService", "Generating from wallpaper on screen:", Screen.name)
|
||||
|
||||
// Logger.log("AppThemeService", "Generating from wallpaper on screen:", Screen.name)
|
||||
const wp = WallpaperService.getWallpaper(Screen.name).replace(/'/g, "'\\''")
|
||||
if (!wp) {
|
||||
Logger.error("AppThemeService", "No wallpaper found")
|
||||
|
||||
@@ -60,7 +60,6 @@ Singleton {
|
||||
if (enabled) {
|
||||
setChargingMode(BatteryService.ChargingMode.Full)
|
||||
} else {
|
||||
BatteryService.chargingMode = BatteryService.ChargingMode.Disabled
|
||||
BatteryService.initialSetter = true
|
||||
ToastService.showNotice(I18n.tr("toast.battery-manager.title"), I18n.tr("toast.battery-manager.uninstall-setup"))
|
||||
PanelService.getPanel("batteryPanel")?.toggle(this)
|
||||
@@ -194,6 +193,7 @@ Singleton {
|
||||
Logger.log("BatteryService", "Battery Manager uninstalled successfully")
|
||||
ToastService.showNotice(I18n.tr("toast.battery-manager.title"), I18n.tr("toast.battery-manager.uninstall-success"))
|
||||
Settings.data.battery.chargingMode = BatteryService.chargingMode
|
||||
BatteryService.chargingMode = BatteryService.ChargingMode.Disabled
|
||||
cleanupProcess.running = true
|
||||
} else {
|
||||
ToastService.showError(I18n.tr("toast.battery-manager.title"), I18n.tr("toast.battery-manager.uninstall-failed"))
|
||||
|
||||
@@ -171,22 +171,22 @@ Singleton {
|
||||
|
||||
function getSignalIcon(device) {
|
||||
if (!device || device.signalStrength === undefined || device.signalStrength <= 0) {
|
||||
return "signal_cellular_null"
|
||||
return "antenna-bars-off"
|
||||
}
|
||||
var signal = device.signalStrength
|
||||
if (signal >= 80) {
|
||||
return "signal_cellular_4_bar"
|
||||
return "antenna-bars-5"
|
||||
}
|
||||
if (signal >= 60) {
|
||||
return "signal_cellular_3_bar"
|
||||
return "antenna-bars-4"
|
||||
}
|
||||
if (signal >= 40) {
|
||||
return "signal_cellular_2_bar"
|
||||
return "antenna-bars-3"
|
||||
}
|
||||
if (signal >= 20) {
|
||||
return "signal_cellular_1_bar"
|
||||
return "antenna-bars-2"
|
||||
}
|
||||
return "signal_cellular_0_bar"
|
||||
return "antenna-bars-1"
|
||||
}
|
||||
|
||||
function isDeviceBusy(device) {
|
||||
|
||||
@@ -38,12 +38,19 @@ Singleton {
|
||||
let allPlayers = Mpris.players.values
|
||||
let finalPlayers = []
|
||||
const genericBrowsers = ["firefox", "chromium", "chrome"]
|
||||
const blacklist = (Settings.data.audio && Settings.data.audio.mprisBlacklist) ? Settings.data.audio.mprisBlacklist : []
|
||||
|
||||
// Separate players into specific and generic lists
|
||||
let specificPlayers = []
|
||||
let genericPlayers = []
|
||||
for (var i = 0; i < allPlayers.length; i++) {
|
||||
const identity = String(allPlayers[i].identity || "").toLowerCase()
|
||||
const match = blacklist.find(b => {
|
||||
const s = String(b || "").toLowerCase()
|
||||
return s && (identity.includes(s))
|
||||
})
|
||||
if (match)
|
||||
continue
|
||||
if (genericBrowsers.some(b => identity.includes(b))) {
|
||||
genericPlayers.push(allPlayers[i])
|
||||
} else {
|
||||
|
||||
@@ -61,7 +61,6 @@ RowLayout {
|
||||
icon: "check"
|
||||
color: root.activeOnColor
|
||||
pointSize: Math.max(Style.fontSizeXS, root.baseSize * 0.5)
|
||||
font.weight: Style.fontWeightBold
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
|
||||
@@ -624,7 +624,6 @@ Popup {
|
||||
NIcon {
|
||||
icon: "filepicker-check"
|
||||
pointSize: Style.fontSizeS
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Color.mOnSecondary
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
|
||||
@@ -31,8 +31,9 @@ Image {
|
||||
}
|
||||
onCachePathChanged: {
|
||||
if (imageHash && cachePath) {
|
||||
// Try to load the cached version, failure will be detected below in onStatusChanged
|
||||
source = cachePath
|
||||
// Check if cache file exists before trying to load it
|
||||
cacheChecker.command = ["test", "-f", cachePath]
|
||||
cacheChecker.running = true
|
||||
}
|
||||
}
|
||||
onStatusChanged: {
|
||||
@@ -48,4 +49,19 @@ Image {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Check if cache file exists to avoid warnings
|
||||
Process {
|
||||
id: cacheChecker
|
||||
running: false
|
||||
onExited: function (exitCode) {
|
||||
if (exitCode === 0 && root.cachePath) {
|
||||
// Cache file exists, load it
|
||||
root.source = root.cachePath
|
||||
} else if (root.imagePath) {
|
||||
// Cache doesn't exist, load original directly
|
||||
root.source = root.imagePath
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -217,7 +217,6 @@ Item {
|
||||
icon: "check"
|
||||
color: root.activeOnColor
|
||||
pointSize: Math.max(Style.fontSizeXS, root.baseSize * 0.5)
|
||||
font.weight: Style.fontWeightBold
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
|
||||
@@ -49,9 +49,13 @@
|
||||
nixpkgs.legacyPackages.${pkgs.system}.app2unit;
|
||||
};
|
||||
|
||||
nixosModules.default = {pkgs, ...}: {
|
||||
nixosModules.default = {
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}: {
|
||||
imports = [./nix/nixos-module.nix];
|
||||
services.noctalia-shell.package = self.packages.${pkgs.system}.default;
|
||||
services.noctalia-shell.package = lib.mkDefault self.packages.${pkgs.system}.default;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -40,6 +40,7 @@ import qs.Modules.OSD
|
||||
import qs.Modules.Settings
|
||||
import qs.Modules.Toast
|
||||
import qs.Modules.Wallpaper
|
||||
import qs.Modules.SetupWizard
|
||||
|
||||
ShellRoot {
|
||||
id: shellRoot
|
||||
@@ -168,4 +169,32 @@ ShellRoot {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------
|
||||
// Setup Wizard
|
||||
Loader {
|
||||
id: setupWizardLoader
|
||||
active: false
|
||||
asynchronous: true
|
||||
sourceComponent: SetupWizard {}
|
||||
onLoaded: {
|
||||
if (setupWizardLoader.item && setupWizardLoader.item.open) {
|
||||
setupWizardLoader.item.open()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: Settings
|
||||
function onSettingsLoaded() {
|
||||
// Only open the setup wizard for new users
|
||||
if (!Settings.data.setupCompleted) {
|
||||
if (Settings.data.settingsVersion >= Settings.settingsVersion) {
|
||||
setupWizardLoader.active = true
|
||||
} else {
|
||||
Settings.data.setupCompleted = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user