mirror of
https://github.com/noctalia-dev/noctalia-shell.git
synced 2026-05-11 17:08:27 +08:00
Merge branch 'main' into battery-charging-treshold
This commit is contained in:
@@ -0,0 +1 @@
|
||||
ko_fi: lysec
|
||||
@@ -1,13 +0,0 @@
|
||||
{
|
||||
"languages": {
|
||||
"QML": {
|
||||
"format_on_save": "on",
|
||||
"formatter": {
|
||||
"external": {
|
||||
"command": "qmlfmt",
|
||||
"arguments": ["-e", "-b", "360", "-t", "2", "-i", "2"]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,3 @@
|
||||
[cursor]
|
||||
color=1f2430 ffcc66
|
||||
|
||||
[colors]
|
||||
foreground=cccac2
|
||||
background=1f2430
|
||||
@@ -21,4 +18,5 @@ bright5=dfbfff
|
||||
bright6=95e6cb
|
||||
bright7=ffffff
|
||||
selection-foreground=1f2430
|
||||
selection-background=409fff
|
||||
selection-background=409fff
|
||||
cursor=1f2430 ffcc66
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
[cursor]
|
||||
color=f8f9fa ffaa33
|
||||
|
||||
[colors]
|
||||
foreground=5c6166
|
||||
background=f8f9fa
|
||||
@@ -22,3 +19,4 @@ bright6=4cbf99
|
||||
bright7=d1d1d1
|
||||
selection-foreground=f8f9fa
|
||||
selection-background=035bd6
|
||||
cursor=f8f9fa ffaa33
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
[cursor]
|
||||
color=1e1e2e f5e0dc
|
||||
|
||||
[colors]
|
||||
foreground=cdd6f4
|
||||
background=1e1e2e
|
||||
@@ -22,3 +19,4 @@ bright6=6bd7ca
|
||||
bright7=bac2de
|
||||
selection-foreground=cdd6f4
|
||||
selection-background=585b70
|
||||
cursor=1e1e2e f5e0dc
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
[cursor]
|
||||
color=303446 f2d5cf
|
||||
|
||||
[colors]
|
||||
foreground=c6d0f5
|
||||
background=303446
|
||||
@@ -22,3 +19,4 @@ bright6=5abfb5
|
||||
bright7=b5bfe2
|
||||
selection-foreground=c6d0f5
|
||||
selection-background=626880
|
||||
cursor=303446 f2d5cf
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
[cursor]
|
||||
color=282a36 f8f8f2
|
||||
|
||||
[colors]
|
||||
foreground=f8f8f2
|
||||
background=282a36
|
||||
@@ -21,4 +18,5 @@ bright5=ff92df
|
||||
bright6=a4ffff
|
||||
bright7=ffffff
|
||||
selection-foreground=ffffff
|
||||
selection-background=44475a
|
||||
selection-background=44475a
|
||||
cursor=282a36 f8f8f2
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
[cursor]
|
||||
color=ffffff 282a36
|
||||
|
||||
[colors]
|
||||
foreground=282a36
|
||||
background=ffffff
|
||||
@@ -22,3 +19,4 @@ bright6=a4ffff
|
||||
bright7=000000
|
||||
selection-foreground=ffffff
|
||||
selection-background=6272a4
|
||||
cursor=ffffff 282a36
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
[cursor]
|
||||
color=4c3743 e69875
|
||||
|
||||
[colors]
|
||||
foreground=d3c6aa
|
||||
background=1e2326
|
||||
@@ -21,4 +18,5 @@ bright5=df69ba
|
||||
bright6=35a77c
|
||||
bright7=fffbef
|
||||
selection-foreground=d3c6aa
|
||||
selection-background=4c3743
|
||||
selection-background=4c3743
|
||||
cursor=4c3743 e69875
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
[cursor]
|
||||
color=eaedc8 f57d26
|
||||
|
||||
[colors]
|
||||
foreground=5c6a72
|
||||
background=efebd4
|
||||
@@ -21,4 +18,5 @@ bright5=df69ba
|
||||
bright6=35a77c
|
||||
bright7=fffbef
|
||||
selection-foreground=5c6a72
|
||||
selection-background=eaedc8
|
||||
selection-background=eaedc8
|
||||
cursor=eaedc8 f57d26
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
|
||||
[cursor]
|
||||
color=282828 ebdbb2
|
||||
|
||||
[colors]
|
||||
foreground=ebdbb2
|
||||
background=282828
|
||||
@@ -22,4 +19,5 @@ bright5=d3869b
|
||||
bright6=8ec07c
|
||||
bright7=ebdbb2
|
||||
selection-foreground=ebdbb2
|
||||
selection-background=665c54
|
||||
selection-background=665c54
|
||||
cursor=282828 ebdbb2
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
|
||||
[cursor]
|
||||
color=625e5c 3c3836
|
||||
|
||||
[colors]
|
||||
foreground=3c3836
|
||||
background=fbf1c7
|
||||
@@ -22,4 +19,5 @@ bright5=8f3f71
|
||||
bright6=427b58
|
||||
bright7=3c3836
|
||||
selection-foreground=fbf1c7
|
||||
selection-background=3c3836
|
||||
selection-background=3c3836
|
||||
cursor=625e5c 3c3836
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
[cursor]
|
||||
color=1f1f28 e6e0c2
|
||||
|
||||
[colors]
|
||||
foreground=ddd8bb
|
||||
background=1f1f28
|
||||
@@ -21,4 +18,5 @@ bright5=a98fd2
|
||||
bright6=7bc2df
|
||||
bright7=a8a48d
|
||||
selection-foreground=ddd8bb
|
||||
selection-background=49473e
|
||||
selection-background=49473e
|
||||
cursor=1f1f28 e6e0c2
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
[cursor]
|
||||
color=f2ecbc 43436c
|
||||
|
||||
[colors]
|
||||
foreground=545464
|
||||
background=f2ecbc
|
||||
@@ -22,3 +19,4 @@ bright6=5e857a
|
||||
bright7=43436c
|
||||
selection-foreground=f2ecbc
|
||||
selection-background=c9cbd1
|
||||
cursor=f2ecbc 43436c
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
[cursor]
|
||||
color=111111 aaaaaa
|
||||
|
||||
[colors]
|
||||
foreground=828282
|
||||
background=111111
|
||||
@@ -22,3 +19,4 @@ bright6=cccccc
|
||||
bright7=ffffff
|
||||
selection-foreground=111111
|
||||
selection-background=828282
|
||||
cursor=111111 aaaaaa
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
[cursor]
|
||||
color=d4d4d4 555555
|
||||
|
||||
[colors]
|
||||
foreground=696969
|
||||
background=d4d4d4
|
||||
@@ -22,3 +19,4 @@ bright6=333333
|
||||
bright7=000000
|
||||
selection-foreground=d4d4d4
|
||||
selection-background=696969
|
||||
cursor=d4d4d4 555555
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
[cursor]
|
||||
color=070722 fff59b
|
||||
|
||||
[colors]
|
||||
foreground=f3edf7
|
||||
background=070722
|
||||
@@ -22,3 +19,4 @@ bright6=9BFECE
|
||||
bright7=ffffff
|
||||
selection-foreground=070722
|
||||
selection-background=f3edf7
|
||||
cursor=070722 fff59b
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
[cursor]
|
||||
color=e6e8fa 5d65f5
|
||||
|
||||
[colors]
|
||||
foreground=4b55c8
|
||||
background=e6e8fa
|
||||
@@ -22,3 +19,4 @@ bright6=0e0e43
|
||||
bright7=0e0e43
|
||||
selection-foreground=e6e8fa
|
||||
selection-background=4b55c8
|
||||
cursor=e6e8fa 5d65f5
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
[cursor]
|
||||
color=1c1822 c7a1d8
|
||||
|
||||
[colors]
|
||||
foreground=e9e4f0
|
||||
background=1c1822
|
||||
@@ -22,3 +19,4 @@ bright6=e0b7c9
|
||||
bright7=ffffff
|
||||
selection-foreground=1c1822
|
||||
selection-background=e9e4f0
|
||||
cursor=1c1822 c7a1d8
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
[cursor]
|
||||
color=f5f1fa 9b59ba
|
||||
|
||||
[colors]
|
||||
foreground=1c1822
|
||||
background=f5f1fa
|
||||
@@ -22,3 +19,4 @@ bright6=c17093
|
||||
bright7=1c1822
|
||||
selection-foreground=f5f1fa
|
||||
selection-background=1c1822
|
||||
cursor=f5f1fa 9b59ba
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
|
||||
[cursor]
|
||||
color=282828 eceff4
|
||||
|
||||
[colors]
|
||||
foreground=d8dee9
|
||||
background=2e3440
|
||||
@@ -23,3 +20,4 @@ bright6=8fbcbb
|
||||
bright7=eceff4
|
||||
selection-foreground=4c566a
|
||||
selection-background=eceff4
|
||||
cursor=282828 eceff4
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
|
||||
[cursor]
|
||||
color=3b4252 7bb3c3
|
||||
|
||||
[colors]
|
||||
foreground=414858
|
||||
background=e5e9f0
|
||||
@@ -23,3 +20,4 @@ bright6=82afae
|
||||
bright7=eceff4
|
||||
selection-foreground=4c556a
|
||||
selection-background=d8dee9
|
||||
cursor=3b4252 7bb3c3
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
|
||||
[cursor]
|
||||
color=191724 e0def4
|
||||
|
||||
[colors]
|
||||
foreground=e0def4
|
||||
background=191724
|
||||
@@ -23,3 +20,4 @@ bright6=ebbcba
|
||||
bright7=e0def4
|
||||
selection-foreground=e0def4
|
||||
selection-background=403d52
|
||||
cursor=191724 e0def4
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
|
||||
[cursor]
|
||||
color=faf4ed 575279
|
||||
|
||||
[colors]
|
||||
foreground=575279
|
||||
background=faf4ed
|
||||
@@ -23,3 +20,4 @@ bright6=d7827e
|
||||
bright7=575279
|
||||
selection-foreground=575279
|
||||
selection-background=dfdad9
|
||||
cursor=faf4ed 575279
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
[cursor]
|
||||
color=073642 839496
|
||||
|
||||
[colors]
|
||||
foreground=839496
|
||||
background=002b36
|
||||
@@ -21,4 +18,5 @@ bright5=6c71c4
|
||||
bright6=93a1a1
|
||||
bright7=fdf6e3
|
||||
selection-foreground=93a1a1
|
||||
selection-background=073642
|
||||
selection-background=073642
|
||||
cursor=073642 839496
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
|
||||
[cursor]
|
||||
color=eee8d5 657b83
|
||||
|
||||
[colors]
|
||||
foreground=657b83
|
||||
background=fdf6e3
|
||||
@@ -22,4 +19,5 @@ bright5=6c71c4
|
||||
bright6=93a1a1
|
||||
bright7=fdf6e3
|
||||
selection-foreground=586e75
|
||||
selection-background=eee8d5
|
||||
selection-background=eee8d5
|
||||
cursor=eee8d5 657b83
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
[cursor]
|
||||
color=1a1b26 c0caf5
|
||||
|
||||
[colors]
|
||||
foreground=c0caf5
|
||||
background=1a1b26
|
||||
@@ -21,4 +18,5 @@ bright5=bb9af7
|
||||
bright6=7dcfff
|
||||
bright7=c0caf5
|
||||
selection-foreground=c0caf5
|
||||
selection-background=283457
|
||||
selection-background=283457
|
||||
cursor=1a1b26 c0caf5
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
[cursor]
|
||||
color=e1e2e7 3760bf
|
||||
|
||||
[colors]
|
||||
foreground=3760bf
|
||||
background=e1e2e7
|
||||
@@ -21,4 +18,5 @@ bright5=9854f1
|
||||
bright6=007197
|
||||
bright7=3760bf
|
||||
selection-foreground=3760bf
|
||||
selection-background=99a7df
|
||||
selection-background=99a7df
|
||||
cursor=e1e2e7 3760bf
|
||||
|
||||
@@ -0,0 +1,146 @@
|
||||
[KDE]
|
||||
contrast=4
|
||||
|
||||
[General]
|
||||
ColorScheme=Matugen
|
||||
Name=noctalia
|
||||
|
||||
[ColorEffects:Disabled]
|
||||
Color={{colors.surface_dim.default.hex}}
|
||||
ColorAmount=0
|
||||
ColorEffect=0
|
||||
ContrastAmount=0.65
|
||||
ContrastEffect=1
|
||||
IntensityAmount=0.1
|
||||
IntensityEffect=2
|
||||
|
||||
[ColorEffects:Inactive]
|
||||
ChangeSelectionColor=true
|
||||
Color={{colors.surface_variant.default.hex}}
|
||||
ColorAmount=0.025
|
||||
ColorEffect=2
|
||||
ContrastAmount=0.1
|
||||
ContrastEffect=2
|
||||
Enable=false
|
||||
IntensityAmount=0
|
||||
IntensityEffect=0
|
||||
|
||||
[Colors:Button]
|
||||
BackgroundAlternate={{colors.surface_container_low.default.hex}}
|
||||
BackgroundNormal={{colors.surface_container_high.default.hex}}
|
||||
DecorationFocus={{colors.primary.default.hex}}
|
||||
DecorationHover={{colors.primary.default.hex}}
|
||||
ForegroundActive={{colors.primary.default.hex}}
|
||||
ForegroundInactive={{colors.on_surface_variant.default.hex}}
|
||||
ForegroundLink={{colors.secondary.default.hex}}
|
||||
ForegroundNegative={{colors.error.default.hex}}
|
||||
ForegroundNeutral={{colors.tertiary.default.hex}}
|
||||
ForegroundNormal={{colors.on_surface.default.hex}}
|
||||
ForegroundPositive={{colors.tertiary_fixed.default.hex}}
|
||||
ForegroundVisited={{colors.on_secondary_container.default.hex}}
|
||||
|
||||
[Colors:Complementary]
|
||||
BackgroundAlternate={{colors.surface_container_low.default.hex}}
|
||||
BackgroundNormal={{colors.surface.default.hex}}
|
||||
DecorationFocus={{colors.primary.default.hex}}
|
||||
DecorationHover={{colors.primary.default.hex}}
|
||||
ForegroundActive={{colors.primary.default.hex}}
|
||||
ForegroundInactive={{colors.on_surface_variant.default.hex}}
|
||||
ForegroundLink={{colors.secondary.default.hex}}
|
||||
ForegroundNegative={{colors.error.default.hex}}
|
||||
ForegroundNeutral={{colors.tertiary.default.hex}}
|
||||
ForegroundNormal={{colors.on_primary_container.default.hex}}
|
||||
ForegroundPositive={{colors.tertiary_fixed.default.hex}}
|
||||
ForegroundVisited={{colors.on_secondary_container.default.hex}}
|
||||
|
||||
[Colors:Header]
|
||||
BackgroundAlternate={{colors.surface.default.hex}}
|
||||
BackgroundNormal={{colors.surface_container.default.hex}}
|
||||
DecorationFocus={{colors.primary.default.hex}}
|
||||
DecorationHover={{colors.primary.default.hex}}
|
||||
ForegroundActive={{colors.primary.default.hex}}
|
||||
ForegroundInactive={{colors.on_surface_variant.default.hex}}
|
||||
ForegroundLink={{colors.secondary.default.hex}}
|
||||
ForegroundNegative={{colors.error.default.hex}}
|
||||
ForegroundNeutral={{colors.tertiary.default.hex}}
|
||||
ForegroundNormal={{colors.on_surface.default.hex}}
|
||||
ForegroundPositive={{colors.tertiary_fixed.default.hex}}
|
||||
ForegroundVisited={{colors.on_secondary_container.default.hex}}
|
||||
|
||||
[Colors:Header][Inactive]
|
||||
BackgroundAlternate={{colors.surface_container.default.hex}}
|
||||
BackgroundNormal={{colors.surface.default.hex}}
|
||||
DecorationFocus={{colors.primary.default.hex}}
|
||||
DecorationHover={{colors.primary.default.hex}}
|
||||
ForegroundActive={{colors.primary.default.hex}}
|
||||
ForegroundInactive={{colors.on_surface_variant.default.hex}}
|
||||
ForegroundLink={{colors.secondary.default.hex}}
|
||||
ForegroundNegative={{colors.error.default.hex}}
|
||||
ForegroundNeutral={{colors.tertiary.default.hex}}
|
||||
ForegroundNormal={{colors.on_surface.default.hex}}
|
||||
ForegroundPositive={{colors.tertiary_fixed.default.hex}}
|
||||
ForegroundVisited={{colors.on_secondary_container.default.hex}}
|
||||
|
||||
[Colors:Selection]
|
||||
BackgroundAlternate={{colors.surface_container_low.default.hex}}
|
||||
BackgroundNormal={{colors.primary.default.hex}}
|
||||
DecorationFocus={{colors.primary.default.hex}}
|
||||
DecorationHover={{colors.primary.default.hex}}
|
||||
ForegroundActive={{colors.on_primary.default.hex}}
|
||||
ForegroundInactive={{colors.on_surface_variant.default.hex}}
|
||||
ForegroundLink={{colors.secondary_fixed.default.hex}}
|
||||
ForegroundNegative={{colors.error_container.default.hex}}
|
||||
ForegroundNeutral={{colors.tertiary_fixed_dim.default.hex}}
|
||||
ForegroundNormal={{colors.on_primary.default.hex}}
|
||||
ForegroundPositive={{colors.tertiary_container.default.hex}}
|
||||
ForegroundVisited={{colors.on_secondary_container.default.hex}}
|
||||
|
||||
[Colors:Tooltip]
|
||||
BackgroundAlternate={{colors.surface.default.hex}}
|
||||
BackgroundNormal={{colors.surface_container.default.hex}}
|
||||
DecorationFocus={{colors.primary.default.hex}}
|
||||
DecorationHover={{colors.primary.default.hex}}
|
||||
ForegroundActive={{colors.primary.default.hex}}
|
||||
ForegroundInactive={{colors.on_surface_variant.default.hex}}
|
||||
ForegroundLink={{colors.secondary.default.hex}}
|
||||
ForegroundNegative={{colors.error.default.hex}}
|
||||
ForegroundNeutral={{colors.tertiary.default.hex}}
|
||||
ForegroundNormal={{colors.on_background.default.hex}}
|
||||
ForegroundPositive={{colors.tertiary_fixed.default.hex}}
|
||||
ForegroundVisited={{colors.on_secondary_container.default.hex}}
|
||||
|
||||
[Colors:View]
|
||||
BackgroundAlternate={{colors.surface_container.default.hex}}
|
||||
BackgroundNormal={{colors.background.default.hex}}
|
||||
DecorationFocus={{colors.on_primary_container.default.hex}}
|
||||
DecorationHover={{colors.on_primary.default.hex}}
|
||||
ForegroundActive={{colors.primary.default.hex}}
|
||||
ForegroundInactive={{colors.on_surface_variant.default.hex}}
|
||||
ForegroundLink={{colors.secondary.default.hex}}
|
||||
ForegroundNegative={{colors.error.default.hex}}
|
||||
ForegroundNeutral={{colors.tertiary.default.hex}}
|
||||
ForegroundNormal={{colors.on_background.default.hex}}
|
||||
ForegroundPositive={{colors.tertiary_fixed.default.hex}}
|
||||
ForegroundVisited={{colors.on_secondary_container.default.hex}}
|
||||
|
||||
[Colors:Window]
|
||||
BackgroundAlternate={{colors.primary_container.default.hex}}
|
||||
BackgroundNormal={{colors.surface_container.default.hex}}
|
||||
DecorationFocus={{colors.primary.default.hex}}
|
||||
DecorationHover={{colors.primary.default.hex}}
|
||||
ForegroundActive={{colors.primary.default.hex}}
|
||||
ForegroundInactive={{colors.on_surface_variant.default.hex}}
|
||||
ForegroundLink={{colors.secondary.default.hex}}
|
||||
ForegroundNegative={{colors.error.default.hex}}
|
||||
ForegroundNeutral={{colors.tertiary.default.hex}}
|
||||
ForegroundNormal={{colors.on_background.default.hex}}
|
||||
ForegroundPositive={{colors.tertiary_fixed.default.hex}}
|
||||
ForegroundVisited={{colors.on_secondary_container.default.hex}}
|
||||
|
||||
[WM]
|
||||
activeBackground={{colors.primary_container.default.hex}}
|
||||
activeBlend={{colors.on_primary_container.default.hex}}
|
||||
activeForeground={{colors.on_primary_container.default.hex}}
|
||||
inactiveBackground={{colors.surface.default.hex}}
|
||||
inactiveBlend={{colors.on_surface_variant.default.hex}}
|
||||
inactiveForeground={{colors.on_surface_variant.default.hex}}
|
||||
+204
-59
@@ -13,32 +13,6 @@
|
||||
},
|
||||
"select-avatar": "Avatar-Bild auswählen"
|
||||
},
|
||||
"ui": {
|
||||
"section": {
|
||||
"label": "Benutzeroberfläche",
|
||||
"description": "Passen Sie das Aussehen, die Haptik und das Verhalten der Oberfläche an."
|
||||
},
|
||||
"tooltips": {
|
||||
"label": "Tooltips anzeigen",
|
||||
"description": "Tooltips in der gesamten Benutzeroberfläche aktivieren oder deaktivieren."
|
||||
},
|
||||
"dim-desktop": {
|
||||
"label": "Desktop abdunkeln",
|
||||
"description": "Desktop abdunkeln, wenn Panels oder Menüs geöffnet sind."
|
||||
},
|
||||
"border-radius": {
|
||||
"label": "Eckenradius",
|
||||
"description": "Steuert die Rundung der Ecken von Fenstern, Buttons und anderen Elementen."
|
||||
},
|
||||
"animation-speed": {
|
||||
"label": "Animationsgeschwindigkeit",
|
||||
"description": "Globale Animationsgeschwindigkeit anpassen."
|
||||
},
|
||||
"animation-disable": {
|
||||
"label": "UI-Animationen deaktivieren",
|
||||
"description": "Alle Animationen für eine schnellere, reaktionsschnellere Erfahrung deaktivieren."
|
||||
}
|
||||
},
|
||||
"screen-corners": {
|
||||
"section": {
|
||||
"label": "Bildschirmecken",
|
||||
@@ -54,7 +28,8 @@
|
||||
},
|
||||
"radius": {
|
||||
"label": "Bildschirmecken-Radius",
|
||||
"description": "Rundung der Bildschirmecken anpassen."
|
||||
"description": "Rundung der Bildschirmecken anpassen.",
|
||||
"reset": "Eckenradius des Bildschirms zurücksetzen"
|
||||
}
|
||||
},
|
||||
"fonts": {
|
||||
@@ -83,16 +58,6 @@
|
||||
}
|
||||
},
|
||||
"reset-scaling": "Skalierung zurücksetzen"
|
||||
},
|
||||
"control-center": {
|
||||
"section": {
|
||||
"label": "Kontrollzentrum",
|
||||
"description": "Konfigurieren Sie die Positionierung und das Verhalten des Kontrollzentrum-Panels."
|
||||
},
|
||||
"position": {
|
||||
"label": "Position",
|
||||
"description": "Wählen Sie, wo das Kontrollzentrum-Panel beim Öffnen erscheint."
|
||||
}
|
||||
}
|
||||
},
|
||||
"audio": {
|
||||
@@ -179,11 +144,9 @@
|
||||
"monitors": {
|
||||
"section": {
|
||||
"label": "Monitor-spezifische Einstellungen",
|
||||
"description": "Skalierung und Helligkeit für jeden Bildschirm anpassen."
|
||||
"description": "Helligkeitseinstellungen für jedes Display anpassen."
|
||||
},
|
||||
"scale": "Skalierung",
|
||||
"brightness": "Helligkeit",
|
||||
"reset-scaling": "Skalierung zurücksetzen",
|
||||
"brightness-step": {
|
||||
"label": "Helligkeits-Schrittgröße",
|
||||
"description": "Schrittgröße für Helligkeitsänderungen anpassen (Mausrad und Tastenkombinationen)."
|
||||
@@ -259,17 +222,20 @@
|
||||
"widgets": {
|
||||
"section": {
|
||||
"label": "Widget-Positionierung",
|
||||
"description": "Widgets per Drag & Drop innerhalb jeder Sektion neu anordnen oder Add/Remove-Buttons zum Verwalten verwenden."
|
||||
"description": "Widgets per Drag & Drop neu anordnen. Abzeichen zeigen die Verwendung an: [L]inks, [M]itte, [R]echts."
|
||||
}
|
||||
},
|
||||
"monitors": {
|
||||
"section": {
|
||||
"label": "Monitor-Anzeige",
|
||||
"description": "Statusleiste auf bestimmten Monitoren anzeigen. Standard ist alle, wenn keine ausgewählt sind."
|
||||
},
|
||||
"only-same-output": {
|
||||
"label": "Nur Apps vom gleichen Bildschirm",
|
||||
"description": "Zeige nur Apps vom dem Bildschirm an, wo sich das Dock befindet."
|
||||
}
|
||||
},
|
||||
"tray": {
|
||||
"blacklist": {
|
||||
"label": "Ausschlussliste",
|
||||
"description": "Füge Ausschlussregeln für die Tray-Symbolleiste hinzu, unterstützt Platzhalter (*).",
|
||||
"placeholder": "z.B., nm-applet, Fcitx*"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -294,6 +260,10 @@
|
||||
"floating-distance": {
|
||||
"label": "Dock-Schwebeabstand",
|
||||
"description": "Schwebeabstand vom Bildschirmrand anpassen."
|
||||
},
|
||||
"colorize-icons": {
|
||||
"label": "Symbole einfärben",
|
||||
"description": "Theme-Farben auf Dock-App-Symbole anwenden (nur nicht fokussierte Apps)."
|
||||
}
|
||||
},
|
||||
"monitors": {
|
||||
@@ -406,6 +376,10 @@
|
||||
"label": "Bildschirmanzeige aktivieren",
|
||||
"description": "Lautstärke- und Helligkeitsänderungen in Echtzeit anzeigen."
|
||||
},
|
||||
"always-on-top": {
|
||||
"label": "Immer im Vordergrund",
|
||||
"description": "Bildschirmanzeige über Vollbildfenstern und anderen Ebenen anzeigen."
|
||||
},
|
||||
"location": {
|
||||
"label": "Position",
|
||||
"description": "Wo Bildschirmanzeigen erscheinen."
|
||||
@@ -533,6 +507,9 @@
|
||||
},
|
||||
"qt": {
|
||||
"description": "Schreibt {filepath}"
|
||||
},
|
||||
"kcolorscheme": {
|
||||
"description": "Schreibt {filepath}"
|
||||
}
|
||||
},
|
||||
"terminal": {
|
||||
@@ -558,9 +535,9 @@
|
||||
"description": "Schreibt {filepath} und lädt neu",
|
||||
"description-missing": "Erfordert fuzzel Starter"
|
||||
},
|
||||
"vesktop": {
|
||||
"description": "Schreibt {filepath}",
|
||||
"description-missing": "Erfordert vesktop Discord-Client"
|
||||
"discord": {
|
||||
"description": "Schreibt {filepath} für {client}",
|
||||
"description-missing": "Kein Discord-Client erkannt. Installieren Sie vesktop, webcord, armcord, equibop, lightcord oder dorion."
|
||||
},
|
||||
"pywalfox": {
|
||||
"description": "Schreibt {filepath} und führt pywalfox update aus",
|
||||
@@ -707,7 +684,8 @@
|
||||
"description": "Ein Dankeschön an unseren {count} <b>großartigen</b> Mitwirkenden!",
|
||||
"description_plural": "Ein Dankeschön an unsere {count} <b>großartigen</b> Mitwirkenden!"
|
||||
}
|
||||
}
|
||||
},
|
||||
"support": "Unterstützen Sie uns"
|
||||
},
|
||||
"hooks": {
|
||||
"title": "Hooks",
|
||||
@@ -741,6 +719,69 @@
|
||||
"description": "• Hintergrundbild-Hook: $1 = Hintergrundbild-Pfad, $2 = Bildschirmname\n• Theme-Wechsel-Hook: $1 = true/false (Dunkelmodus-Status)"
|
||||
}
|
||||
}
|
||||
},
|
||||
"control-center": {
|
||||
"position": {
|
||||
"description": "Wählen Sie aus, wo das Kontrollzentrum angezeigt wird, wenn es geöffnet wird.",
|
||||
"label": "Position"
|
||||
},
|
||||
"section": {
|
||||
"description": "Konfigurieren Sie die Positionierung und das Verhalten des Control Center-Panels.",
|
||||
"label": "Aussehen"
|
||||
},
|
||||
"title": "Kontrollzentrum",
|
||||
"cards": {
|
||||
"section": {
|
||||
"description": "Passen Sie an, welche Steuerelemente im Kontrollzentrum angezeigt werden und in welcher Reihenfolge.",
|
||||
"label": "Karten"
|
||||
}
|
||||
},
|
||||
"shortcuts": {
|
||||
"section": {
|
||||
"description": "Konfigurieren und verwalten Sie die Verknüpfungs-Widgets.",
|
||||
"label": "Widgets für Kurzbefehle"
|
||||
},
|
||||
"sectionLeft": "Links",
|
||||
"sectionRight": "Richtig"
|
||||
}
|
||||
},
|
||||
"user-interface": {
|
||||
"animation-disable": {
|
||||
"description": "Deaktivieren Sie alle Animationen für eine schnellere und reaktionsfreudigere Erfahrung.",
|
||||
"label": "UI-Animationen deaktivieren"
|
||||
},
|
||||
"animation-speed": {
|
||||
"description": "Globale Animationsgeschwindigkeit anpassen.",
|
||||
"label": "Animationsgeschwindigkeit",
|
||||
"reset": "Animationsgeschwindigkeit zurücksetzen"
|
||||
},
|
||||
"border-radius": {
|
||||
"description": "Steuert die Eckenrundung von Fenstern, Schaltflächen und anderen Elementen.",
|
||||
"label": "Eckenradius",
|
||||
"reset": "Rahmenradius zurücksetzen"
|
||||
},
|
||||
"compact-lockscreen": {
|
||||
"description": "Zeige nur die Login-Eingabe und Systemsteuerung, blende Wetter- und Medien-Widgets aus.",
|
||||
"label": "Kompakter Sperrbildschirm"
|
||||
},
|
||||
"dim-desktop": {
|
||||
"description": "Den Desktop abdunkeln, wenn Bedienfelder oder Menüs geöffnet sind.",
|
||||
"label": "Dim Desktop"
|
||||
},
|
||||
"scaling": {
|
||||
"description": "Ändert die Größe der allgemeinen Benutzeroberfläche, mit Ausnahme der Leiste.",
|
||||
"label": "Oberflächenskalierung",
|
||||
"reset-scaling": "Schnittstellenskalierung zurücksetzen"
|
||||
},
|
||||
"section": {
|
||||
"description": "Passen Sie das Aussehen, die Haptik und das Verhalten der Benutzeroberfläche an.",
|
||||
"label": "Aussehen"
|
||||
},
|
||||
"title": "Benutzeroberfläche",
|
||||
"tooltips": {
|
||||
"description": "Tooltips in der gesamten Benutzeroberfläche aktivieren oder deaktivieren.",
|
||||
"label": "Tooltips anzeigen"
|
||||
}
|
||||
}
|
||||
},
|
||||
"general": {
|
||||
@@ -766,7 +807,11 @@
|
||||
},
|
||||
"file-picker": {
|
||||
"select-folder": "Ordner auswählen",
|
||||
"select-file": "Datei auswählen"
|
||||
"select-file": "Datei auswählen",
|
||||
"cancel": "Abbrechen",
|
||||
"search-placeholder": "Dateien und Ordner suchen...",
|
||||
"select-current": "Aktuelle auswählen",
|
||||
"title": "Dateiauswahl"
|
||||
},
|
||||
"datetime-tokens": {
|
||||
"common": {
|
||||
@@ -857,9 +902,9 @@
|
||||
"search-placeholder": "Widgets suchen..."
|
||||
},
|
||||
"active-window": {
|
||||
"auto-hide": {
|
||||
"label": "Automatisch ausblenden",
|
||||
"description": "Widget automatisch ausblenden, wenn kein Fenster aktiv ist."
|
||||
"hide-mode": {
|
||||
"label": "Ausblendmodus",
|
||||
"description": "Steuert das Verhalten des Widgets, wenn kein Fenster aktiv ist."
|
||||
},
|
||||
"show-app-icon": {
|
||||
"label": "App-Symbol anzeigen",
|
||||
@@ -872,6 +917,10 @@
|
||||
"width": {
|
||||
"description": "Steuert die horizontale Größe des Widgets.",
|
||||
"label": "Widget-Breite"
|
||||
},
|
||||
"colorize-icons": {
|
||||
"label": "Symbole einfärben",
|
||||
"description": "Theme-Farben auf das aktive Fenster-Symbol anwenden."
|
||||
}
|
||||
},
|
||||
"system-monitor": {
|
||||
@@ -1002,9 +1051,9 @@
|
||||
}
|
||||
},
|
||||
"media-mini": {
|
||||
"auto-hide": {
|
||||
"label": "Automatisch ausblenden",
|
||||
"description": "Widget automatisch ausblenden, wenn keine Medien abgespielt werden."
|
||||
"hide-mode": {
|
||||
"label": "Ausblendmodus",
|
||||
"description": "Steuert das Verhalten des Widgets, wenn keine Medien abgespielt werden."
|
||||
},
|
||||
"show-album-art": {
|
||||
"label": "Albumcover anzeigen",
|
||||
@@ -1065,6 +1114,16 @@
|
||||
"only-same-output": {
|
||||
"label": "Nur vom gleichen Bildschirm",
|
||||
"description": "Zeige nur Apps vom dem Bildschirm an, wo sich die Taskbar befindet."
|
||||
},
|
||||
"colorize-icons": {
|
||||
"label": "Symbole einfärben",
|
||||
"description": "Theme-Farben auf Taskbar-Symbole anwenden."
|
||||
}
|
||||
},
|
||||
"tray": {
|
||||
"colorize-icons": {
|
||||
"label": "Symbole einfärben",
|
||||
"description": "Theme-Farben auf Tray-Symbole anwenden."
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1234,7 +1293,8 @@
|
||||
"density": {
|
||||
"compact": "Kompakt",
|
||||
"default": "Standard",
|
||||
"comfortable": "Bequem"
|
||||
"comfortable": "Bequem",
|
||||
"mini": "Mini"
|
||||
}
|
||||
},
|
||||
"launcher": {
|
||||
@@ -1259,6 +1319,11 @@
|
||||
"bottom_right": "Unten rechts",
|
||||
"bottom_center": "Unten mittig",
|
||||
"top_center": "Oben mittig"
|
||||
},
|
||||
"quickSettingsStyle": {
|
||||
"modern": "Modern",
|
||||
"classic": "Klassisch",
|
||||
"compact": "Kompakt"
|
||||
}
|
||||
},
|
||||
"osd": {
|
||||
@@ -1318,6 +1383,11 @@
|
||||
"microphone-input": "Mikrofon-Eingabe",
|
||||
"both": "System-Ausgabe + Mikrofon-Eingabe"
|
||||
}
|
||||
},
|
||||
"hide-modes": {
|
||||
"hidden": "Ausblenden, wenn leer",
|
||||
"transparent": "Transparent, wenn leer",
|
||||
"visible": "Immer sichtbar"
|
||||
}
|
||||
},
|
||||
"session-menu": {
|
||||
@@ -1355,9 +1425,9 @@
|
||||
"calculator-error": "Fehler"
|
||||
},
|
||||
"system": {
|
||||
"uptime": "System-Laufzeit: {uptime}",
|
||||
"uptime": "Laufzeit: {uptime}",
|
||||
"welcome-back": "Willkommen zurück,",
|
||||
"monitor-description": "{model} ({width}x{height})",
|
||||
"monitor-description": "{model} ({width}x{height} @ {scale}x)",
|
||||
"scaling-percentage": "{percentage}%",
|
||||
"location-display": "{name} ({coordinates})",
|
||||
"signal-strength": "{signal}%",
|
||||
@@ -1398,6 +1468,78 @@
|
||||
"restart": "Neu starten",
|
||||
"suspend": "Ruhezustand"
|
||||
},
|
||||
"quickSettings": {
|
||||
"notifications": {
|
||||
"label": {
|
||||
"enabled": "Benachrichtigungen",
|
||||
"disabled": "Nicht stören"
|
||||
},
|
||||
"tooltip": {
|
||||
"action": "Linksklick: Benachrichtigungsverlauf öffnen\nRechtsklick: Nicht stören umschalten"
|
||||
}
|
||||
},
|
||||
"screenRecorder": {
|
||||
"label": {
|
||||
"recording": "Stopp",
|
||||
"stopped": "Aufnehmen"
|
||||
},
|
||||
"tooltip": {
|
||||
"action": "Klicken zum Starten/Stoppen der Bildschirmaufnahme"
|
||||
}
|
||||
},
|
||||
"powerProfile": {
|
||||
"label": {
|
||||
"unavailable": "Energieprofil"
|
||||
},
|
||||
"tooltip": {
|
||||
"action": "Klicken zum Wechseln des Energieprofils"
|
||||
}
|
||||
},
|
||||
"wifi": {
|
||||
"label": {
|
||||
"ethernet": "Ethernet",
|
||||
"wifi": "Wi-Fi",
|
||||
"disconnected": "Wi-Fi getrennt"
|
||||
},
|
||||
"tooltip": {
|
||||
"action": "Klicken zum Verwalten der Wi-Fi-Verbindungen"
|
||||
}
|
||||
},
|
||||
"bluetooth": {
|
||||
"label": {
|
||||
"enabled": "Bluetooth",
|
||||
"disabled": "Bluetooth"
|
||||
},
|
||||
"tooltip": {
|
||||
"action": "Klicken zum Verwalten der Bluetooth-Geräte"
|
||||
}
|
||||
},
|
||||
"nightLight": {
|
||||
"label": {
|
||||
"enabled": "Nachtlicht",
|
||||
"forced": "Nachtlicht",
|
||||
"disabled": "Nachtlicht"
|
||||
},
|
||||
"tooltip": {
|
||||
"action": "Klicken zum Wechseln des Nachtlicht-Modus\nRechtsklick: Einstellungen öffnen"
|
||||
}
|
||||
},
|
||||
"wallpaperSelector": {
|
||||
"label": "Hintergrundbild",
|
||||
"tooltip": {
|
||||
"action": "Linksklick: Hintergrundbildauswahl öffnen\nRechtsklick: Zufälliges Hintergrundbild setzen"
|
||||
}
|
||||
},
|
||||
"keepAwake": {
|
||||
"label": {
|
||||
"enabled": "Wach halten",
|
||||
"disabled": "Wach halten"
|
||||
},
|
||||
"tooltip": {
|
||||
"action": "Klicken zum Umschalten des Wach-halten-Modus"
|
||||
}
|
||||
}
|
||||
},
|
||||
"toast": {
|
||||
"night-light": {
|
||||
"enabled": "Aktiviert",
|
||||
@@ -1445,6 +1587,9 @@
|
||||
"enabled": "Aktiviert",
|
||||
"disabled": "Deaktiviert"
|
||||
},
|
||||
"kofi": {
|
||||
"opened": "Ko-fi-Seite in Ihrem Browser geöffnet"
|
||||
},
|
||||
"do-not-disturb": {
|
||||
"enabled": "'Nicht stören' aktiviert",
|
||||
"disabled": "'Nicht stören' deaktiviert",
|
||||
|
||||
+204
-54
@@ -13,32 +13,6 @@
|
||||
},
|
||||
"select-avatar": "Select avatar image"
|
||||
},
|
||||
"ui": {
|
||||
"section": {
|
||||
"label": "User interface",
|
||||
"description": "Customize the look, feel, and behavior of the interface."
|
||||
},
|
||||
"tooltips": {
|
||||
"label": "Show tooltips",
|
||||
"description": "Enable or disable tooltips throughout the interface."
|
||||
},
|
||||
"dim-desktop": {
|
||||
"label": "Dim desktop",
|
||||
"description": "Dim the desktop when panels or menus are open."
|
||||
},
|
||||
"border-radius": {
|
||||
"label": "Border radius",
|
||||
"description": "Controls the corner roundness of windows, buttons, and other elements."
|
||||
},
|
||||
"animation-speed": {
|
||||
"label": "Animation speed",
|
||||
"description": "Adjust global animation speed."
|
||||
},
|
||||
"animation-disable": {
|
||||
"label": "Disable UI Animations",
|
||||
"description": "Disable all animations for a faster, more responsive experience."
|
||||
}
|
||||
},
|
||||
"screen-corners": {
|
||||
"section": {
|
||||
"label": "Screen corners",
|
||||
@@ -54,7 +28,8 @@
|
||||
},
|
||||
"radius": {
|
||||
"label": "Screen corners radius",
|
||||
"description": "Adjust the rounded corners of the screen."
|
||||
"description": "Adjust the rounded corners of the screen.",
|
||||
"reset": "Reset screen corners radius"
|
||||
}
|
||||
},
|
||||
"fonts": {
|
||||
@@ -83,17 +58,8 @@
|
||||
"description": "Increase or decrease the size of the monospaced text."
|
||||
}
|
||||
}
|
||||
},
|
||||
"control-center": {
|
||||
"section": {
|
||||
"label": "Control Center",
|
||||
"description": "Configure the Control Center panel positioning and behavior."
|
||||
},
|
||||
"position": {
|
||||
"label": "Position",
|
||||
"description": "Choose where the Control Center panel appears when opened."
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
"audio": {
|
||||
"title": "Audio",
|
||||
@@ -179,11 +145,9 @@
|
||||
"monitors": {
|
||||
"section": {
|
||||
"label": "Per-monitor settings",
|
||||
"description": "Adjust scaling and brightness for each display."
|
||||
"description": "Adjust settings brightness for each display."
|
||||
},
|
||||
"scale": "Scale",
|
||||
"brightness": "Brightness",
|
||||
"reset-scaling": "Reset scaling",
|
||||
"brightness-step": {
|
||||
"label": "Brightness step size",
|
||||
"description": "Adjust the step size for brightness changes (scroll wheel and keyboard shortcuts)."
|
||||
@@ -259,7 +223,7 @@
|
||||
"widgets": {
|
||||
"section": {
|
||||
"label": "Widgets positioning",
|
||||
"description": "Drag and drop widgets to reorder them within each section, or use the add/remove buttons to manage widgets."
|
||||
"description": "Drag and drop widgets to reorder them. Badges indicate usage: [L]eft, [C]enter, [R]ight."
|
||||
}
|
||||
},
|
||||
"monitors": {
|
||||
@@ -267,6 +231,13 @@
|
||||
"label": "Monitors display",
|
||||
"description": "Show bar on specific monitors. Defaults to all if none are chosen."
|
||||
}
|
||||
},
|
||||
"tray": {
|
||||
"blacklist": {
|
||||
"label": "Blacklist",
|
||||
"description": "Add tray exclusion rules, supports wildcards (*).",
|
||||
"placeholder": "e.g., nm-applet, Fcitx*"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dock": {
|
||||
@@ -290,6 +261,10 @@
|
||||
"floating-distance": {
|
||||
"label": "Dock floating distance",
|
||||
"description": "Adjust the floating distance from the screen edge."
|
||||
},
|
||||
"colorize-icons": {
|
||||
"label": "Colorize Icons",
|
||||
"description": "Apply theme colors to dock app icons (non-focused apps only)."
|
||||
}
|
||||
},
|
||||
"monitors": {
|
||||
@@ -402,6 +377,10 @@
|
||||
"label": "Enable on screen display",
|
||||
"description": "Show volume and brightness changes in real-time."
|
||||
},
|
||||
"always-on-top": {
|
||||
"label": "Always on top",
|
||||
"description": "Display OSD above fullscreen windows and other layers."
|
||||
},
|
||||
"location": {
|
||||
"label": "Location",
|
||||
"description": "Where on-screen displays appear."
|
||||
@@ -533,6 +512,9 @@
|
||||
},
|
||||
"qt": {
|
||||
"description": "Write {filepath}"
|
||||
},
|
||||
"kcolorscheme": {
|
||||
"description": "Write {filepath}"
|
||||
}
|
||||
},
|
||||
"terminal": {
|
||||
@@ -558,9 +540,9 @@
|
||||
"description": "Write {filepath} and reload",
|
||||
"description-missing": "Requires {app} to be installed"
|
||||
},
|
||||
"vesktop": {
|
||||
"description": "Write {filepath}",
|
||||
"description-missing": "Requires {app} to be installed"
|
||||
"discord": {
|
||||
"description": "Write {filepath} for {client}",
|
||||
"description-missing": "No Discord client detected. Install vesktop, webcord, armcord, equibop, lightcord, or dorion."
|
||||
},
|
||||
"pywalfox": {
|
||||
"description": "Write {filepath} and run pywalfox update",
|
||||
@@ -703,7 +685,8 @@
|
||||
"description": "Shout-out to our {count} <b>awesome</b> contributor!",
|
||||
"description_plural": "Shout-out to our {count} <b>awesome</b> contributors!"
|
||||
}
|
||||
}
|
||||
},
|
||||
"support": "Support us"
|
||||
},
|
||||
"hooks": {
|
||||
"title": "Hooks",
|
||||
@@ -737,6 +720,69 @@
|
||||
"description": "• Wallpaper Hook: $1 = wallpaper path, $2 = screen name\n• Theme Toggle Hook: $1 = true/false (dark mode state)"
|
||||
}
|
||||
}
|
||||
},
|
||||
"control-center": {
|
||||
"title": "Control Center",
|
||||
"section": {
|
||||
"label": "Appearance",
|
||||
"description": "Configure the Control Center panel positioning and behavior."
|
||||
},
|
||||
"position": {
|
||||
"label": "Position",
|
||||
"description": "Choose where the Control Center panel appears when opened."
|
||||
},
|
||||
"cards": {
|
||||
"section": {
|
||||
"label": "Cards",
|
||||
"description": "Customize which controls appear in the Control Center and in what order."
|
||||
}
|
||||
},
|
||||
"shortcuts": {
|
||||
"section": {
|
||||
"label": "Shortcuts widgets",
|
||||
"description": "Configure and manage the shortcuts widgets."
|
||||
},
|
||||
"sectionLeft": "Left",
|
||||
"sectionRight": "Right"
|
||||
}
|
||||
},
|
||||
"user-interface": {
|
||||
"title": "User interface",
|
||||
"section": {
|
||||
"label": "Appearance",
|
||||
"description": "Customize the look, feel, and behavior of the interface."
|
||||
},
|
||||
"tooltips": {
|
||||
"label": "Show tooltips",
|
||||
"description": "Enable or disable tooltips throughout the interface."
|
||||
},
|
||||
"scaling": {
|
||||
"label": "Interface scaling",
|
||||
"description": "Changes the size of the general user interface, excluding the bar.",
|
||||
"reset-scaling": "Reset interface scaling"
|
||||
},
|
||||
"dim-desktop": {
|
||||
"label": "Dim desktop",
|
||||
"description": "Dim the desktop when panels or menus are open."
|
||||
},
|
||||
"compact-lockscreen": {
|
||||
"label": "Compact lock screen",
|
||||
"description": "Show only the login input and system controls, hiding weather and media widgets."
|
||||
},
|
||||
"border-radius": {
|
||||
"label": "Border radius",
|
||||
"description": "Controls the corner roundness of windows, buttons, and other elements.",
|
||||
"reset": "Reset border radius"
|
||||
},
|
||||
"animation-speed": {
|
||||
"label": "Animation speed",
|
||||
"description": "Adjust global animation speed.",
|
||||
"reset": "Reset animation speed"
|
||||
},
|
||||
"animation-disable": {
|
||||
"label": "Disable UI Animations",
|
||||
"description": "Disable all animations for a faster, more responsive experience."
|
||||
}
|
||||
}
|
||||
},
|
||||
"widgets": {
|
||||
@@ -744,8 +790,12 @@
|
||||
"placeholder": "Placeholder"
|
||||
},
|
||||
"file-picker": {
|
||||
"title": "File Picker",
|
||||
"select-folder": "Select Folder",
|
||||
"select-file": "Select File"
|
||||
"select-file": "Select File",
|
||||
"search-placeholder": "Search files and folders...",
|
||||
"select-current": "Select Current",
|
||||
"cancel": "Cancel"
|
||||
},
|
||||
"datetime-tokens": {
|
||||
"common": {
|
||||
@@ -836,9 +886,9 @@
|
||||
"search-placeholder": "Search widget..."
|
||||
},
|
||||
"active-window": {
|
||||
"auto-hide": {
|
||||
"label": "Hide automatically",
|
||||
"description": "Automatically hide the widget when no window is active."
|
||||
"hide-mode": {
|
||||
"label": "Hiding mode",
|
||||
"description": "Controls how the widget behaves when no window is active."
|
||||
},
|
||||
"show-app-icon": {
|
||||
"label": "Show app icon",
|
||||
@@ -851,6 +901,10 @@
|
||||
"width": {
|
||||
"label": "Widget Width",
|
||||
"description": "Controls the horizontal size of the widget."
|
||||
},
|
||||
"colorize-icons": {
|
||||
"label": "Colorize Icons",
|
||||
"description": "Apply theme colors to active window icon."
|
||||
}
|
||||
},
|
||||
"system-monitor": {
|
||||
@@ -981,9 +1035,9 @@
|
||||
}
|
||||
},
|
||||
"media-mini": {
|
||||
"auto-hide": {
|
||||
"label": "Hide automatically",
|
||||
"description": "Automatically hide the widget when no media is playing."
|
||||
"hide-mode": {
|
||||
"label": "Hiding mode",
|
||||
"description": "Controls how the widget behaves when no media is playing."
|
||||
},
|
||||
"show-album-art": {
|
||||
"label": "Show album art",
|
||||
@@ -1044,6 +1098,16 @@
|
||||
"only-same-output": {
|
||||
"label": "Only from same output",
|
||||
"description": "Show only apps from the output where the bar is located."
|
||||
},
|
||||
"colorize-icons": {
|
||||
"label": "Colorize Icons",
|
||||
"description": "Apply theme colors to taskbar icons."
|
||||
}
|
||||
},
|
||||
"tray": {
|
||||
"colorize-icons": {
|
||||
"label": "Colorize Icons",
|
||||
"description": "Apply theme colors to tray icons."
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1211,6 +1275,7 @@
|
||||
"right": "Right"
|
||||
},
|
||||
"density": {
|
||||
"mini": "Mini",
|
||||
"compact": "Compact",
|
||||
"default": "Default",
|
||||
"comfortable": "Comfortable"
|
||||
@@ -1238,6 +1303,11 @@
|
||||
"bottom_right": "Bottom right",
|
||||
"bottom_center": "Bottom center",
|
||||
"top_center": "Top center"
|
||||
},
|
||||
"quickSettingsStyle": {
|
||||
"modern": "Modern",
|
||||
"classic": "Classic",
|
||||
"compact": "Compact"
|
||||
}
|
||||
},
|
||||
"osd": {
|
||||
@@ -1274,6 +1344,11 @@
|
||||
"hover": "Scroll On Hover",
|
||||
"never": "Never Scroll"
|
||||
},
|
||||
"hide-modes": {
|
||||
"visible": "Always Visible",
|
||||
"hidden": "Hide When Empty",
|
||||
"transparent": "Transparent When Empty"
|
||||
},
|
||||
"frame-rates": {
|
||||
"fps": "{fps} FPS"
|
||||
},
|
||||
@@ -1334,9 +1409,9 @@
|
||||
"calculator-error": "Error"
|
||||
},
|
||||
"system": {
|
||||
"uptime": "System uptime: {uptime}",
|
||||
"uptime": "Uptime: {uptime}",
|
||||
"welcome-back": "Welcome back,",
|
||||
"monitor-description": "{model} ({width}x{height})",
|
||||
"monitor-description": "{model} ({width}x{height} @ {scale}x)",
|
||||
"scaling-percentage": "{percentage}%",
|
||||
"location-display": "{name} ({coordinates})",
|
||||
"signal-strength": "{signal}%",
|
||||
@@ -1359,6 +1434,78 @@
|
||||
"restart": "Restart",
|
||||
"suspend": "Suspend"
|
||||
},
|
||||
"quickSettings": {
|
||||
"notifications": {
|
||||
"label": {
|
||||
"enabled": "Notifications",
|
||||
"disabled": "Do Not Disturb"
|
||||
},
|
||||
"tooltip": {
|
||||
"action": "Left click: Open notification history\nRight click: Toggle Do Not Disturb"
|
||||
}
|
||||
},
|
||||
"screenRecorder": {
|
||||
"label": {
|
||||
"recording": "Stop",
|
||||
"stopped": "Record"
|
||||
},
|
||||
"tooltip": {
|
||||
"action": "Click to start/stop screen recording"
|
||||
}
|
||||
},
|
||||
"powerProfile": {
|
||||
"label": {
|
||||
"unavailable": "Power Profile"
|
||||
},
|
||||
"tooltip": {
|
||||
"action": "Click to cycle power profile"
|
||||
}
|
||||
},
|
||||
"wifi": {
|
||||
"label": {
|
||||
"ethernet": "Ethernet",
|
||||
"wifi": "Wi-Fi",
|
||||
"disconnected": "Wi-Fi Disconnected"
|
||||
},
|
||||
"tooltip": {
|
||||
"action": "Click to manage Wi-Fi connections"
|
||||
}
|
||||
},
|
||||
"bluetooth": {
|
||||
"label": {
|
||||
"enabled": "Bluetooth",
|
||||
"disabled": "Bluetooth"
|
||||
},
|
||||
"tooltip": {
|
||||
"action": "Click to manage Bluetooth devices"
|
||||
}
|
||||
},
|
||||
"nightLight": {
|
||||
"label": {
|
||||
"enabled": "Night Light",
|
||||
"forced": "Night Light",
|
||||
"disabled": "Night Light"
|
||||
},
|
||||
"tooltip": {
|
||||
"action": "Click to cycle Night Light mode\nRight click: Open settings"
|
||||
}
|
||||
},
|
||||
"wallpaperSelector": {
|
||||
"label": "Wallpaper",
|
||||
"tooltip": {
|
||||
"action": "Left click: Open wallpaper selector\nRight click: Set random wallpaper"
|
||||
}
|
||||
},
|
||||
"keepAwake": {
|
||||
"label": {
|
||||
"enabled": "Keep Awake",
|
||||
"disabled": "Keep Awake"
|
||||
},
|
||||
"tooltip": {
|
||||
"action": "Click to toggle keep awake mode"
|
||||
}
|
||||
}
|
||||
},
|
||||
"toast": {
|
||||
"night-light": {
|
||||
"enabled": "Enabled",
|
||||
@@ -1406,6 +1553,9 @@
|
||||
"enabled": "Enabled",
|
||||
"disabled": "Disabled"
|
||||
},
|
||||
"kofi": {
|
||||
"opened": "Ko-fi page opened in your browser"
|
||||
},
|
||||
"do-not-disturb": {
|
||||
"enabled": "'Do not disturb' enabled",
|
||||
"disabled": "'Do not disturb' disabled",
|
||||
|
||||
+204
-55
@@ -13,32 +13,6 @@
|
||||
},
|
||||
"select-avatar": "Seleccionar imagen de avatar"
|
||||
},
|
||||
"ui": {
|
||||
"section": {
|
||||
"label": "Interfaz de usuario",
|
||||
"description": "Personaliza la apariencia, sensación y comportamiento de la interfaz."
|
||||
},
|
||||
"tooltips": {
|
||||
"label": "Mostrar tooltips",
|
||||
"description": "Activar o desactivar tooltips en toda la interfaz."
|
||||
},
|
||||
"dim-desktop": {
|
||||
"label": "Atenuar escritorio",
|
||||
"description": "Atenúa el escritorio cuando los paneles o menús están abiertos."
|
||||
},
|
||||
"border-radius": {
|
||||
"label": "Radio del borde",
|
||||
"description": "Controla la redondez de las esquinas de ventanas, botones y otros elementos."
|
||||
},
|
||||
"animation-speed": {
|
||||
"label": "Velocidad de la animación",
|
||||
"description": "Ajusta la velocidad de la animación global."
|
||||
},
|
||||
"animation-disable": {
|
||||
"label": "Desactivar animaciones de UI",
|
||||
"description": "Desactivar todas las animaciones para una experiencia más rápida y responsiva."
|
||||
}
|
||||
},
|
||||
"screen-corners": {
|
||||
"section": {
|
||||
"label": "Esquinas de la pantalla",
|
||||
@@ -54,7 +28,8 @@
|
||||
},
|
||||
"radius": {
|
||||
"label": "Radio de las esquinas de la pantalla",
|
||||
"description": "Ajusta las esquinas redondeadas de la pantalla."
|
||||
"description": "Ajusta las esquinas redondeadas de la pantalla.",
|
||||
"reset": "Restablecer el radio de las esquinas de la pantalla"
|
||||
}
|
||||
},
|
||||
"fonts": {
|
||||
@@ -83,16 +58,6 @@
|
||||
}
|
||||
},
|
||||
"reset-scaling": "Restablecer la escala"
|
||||
},
|
||||
"control-center": {
|
||||
"section": {
|
||||
"label": "Centro de control",
|
||||
"description": "Configurar el posicionamiento y comportamiento del panel del centro de control."
|
||||
},
|
||||
"position": {
|
||||
"label": "Posición",
|
||||
"description": "Elige dónde aparece el panel del centro de control cuando se abre."
|
||||
}
|
||||
}
|
||||
},
|
||||
"audio": {
|
||||
@@ -179,11 +144,9 @@
|
||||
"monitors": {
|
||||
"section": {
|
||||
"label": "Configuración por monitor",
|
||||
"description": "Ajusta la escala y el brillo para cada pantalla."
|
||||
"description": "Ajustar el brillo de la configuración para cada pantalla."
|
||||
},
|
||||
"scale": "Escala",
|
||||
"brightness": "Brillo",
|
||||
"reset-scaling": "Restablecer escala",
|
||||
"brightness-step": {
|
||||
"label": "Tamaño del paso de brillo",
|
||||
"description": "Ajusta el tamaño del paso para los cambios de brillo (rueda de desplazamiento y atajos de teclado)."
|
||||
@@ -259,7 +222,7 @@
|
||||
"widgets": {
|
||||
"section": {
|
||||
"label": "Posicionamiento de widgets",
|
||||
"description": "Arrastra y suelta widgets para reordenarlos dentro de cada sección, o usa los botones de añadir/eliminar para gestionar los widgets."
|
||||
"description": "Arrastra y suelta widgets para reordenarlos. Las insignias indican el uso: [I]zquierda, [C]entro, [D]erecha."
|
||||
}
|
||||
},
|
||||
"monitors": {
|
||||
@@ -267,6 +230,13 @@
|
||||
"label": "Visualización en monitores",
|
||||
"description": "Muestra la barra en monitores específicos. Por defecto, se muestra en todos si no se elige ninguno."
|
||||
}
|
||||
},
|
||||
"tray": {
|
||||
"blacklist": {
|
||||
"label": "Lista negra",
|
||||
"description": "Agregar reglas de exclusión de la bandeja, admite comodines (*).",
|
||||
"placeholder": "ej., nm-applet, Fcitx*"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dock": {
|
||||
@@ -290,6 +260,10 @@
|
||||
"floating-distance": {
|
||||
"label": "Distancia de flotación del dock",
|
||||
"description": "Ajusta la distancia de flotación desde el borde de la pantalla."
|
||||
},
|
||||
"colorize-icons": {
|
||||
"label": "Colorear iconos",
|
||||
"description": "Aplicar colores del tema a los iconos de aplicaciones del dock (solo aplicaciones no enfocadas)."
|
||||
}
|
||||
},
|
||||
"monitors": {
|
||||
@@ -402,6 +376,10 @@
|
||||
"label": "Activar visualización en pantalla",
|
||||
"description": "Mostrar cambios de volumen y brillo en tiempo real."
|
||||
},
|
||||
"always-on-top": {
|
||||
"label": "Siempre encima",
|
||||
"description": "Mostrar OSD por encima de ventanas de pantalla completa y otras capas."
|
||||
},
|
||||
"location": {
|
||||
"label": "Ubicación",
|
||||
"description": "Dónde aparece la visualización en pantalla."
|
||||
@@ -529,6 +507,9 @@
|
||||
},
|
||||
"qt": {
|
||||
"description": "Escribir {filepath}"
|
||||
},
|
||||
"kcolorscheme": {
|
||||
"description": "Escribir {filepath}"
|
||||
}
|
||||
},
|
||||
"terminal": {
|
||||
@@ -554,9 +535,9 @@
|
||||
"description": "Escribir {filepath} y recargar",
|
||||
"description-missing": "Requiere que {app} esté instalado"
|
||||
},
|
||||
"vesktop": {
|
||||
"description": "Escribir {filepath}",
|
||||
"description-missing": "Requiere que {app} esté instalado"
|
||||
"discord": {
|
||||
"description": "Escribir {filepath} para {client}",
|
||||
"description-missing": "No se detectó cliente de Discord. Instala vesktop, webcord, armcord, equibop, lightcord o dorion."
|
||||
},
|
||||
"pywalfox": {
|
||||
"description": "Escribir {filepath} y ejecutar pywalfox update",
|
||||
@@ -703,7 +684,8 @@
|
||||
"description": "¡Un saludo a nuestro <b>increíble</b> colaborador número {count}!",
|
||||
"description_plural": "¡Un saludo a nuestros {count} <b>increíbles</b> colaboradores!"
|
||||
}
|
||||
}
|
||||
},
|
||||
"support": "Apóyanos"
|
||||
},
|
||||
"hooks": {
|
||||
"title": "Hooks",
|
||||
@@ -737,6 +719,69 @@
|
||||
"description": "• Hook de fondo de pantalla: $1 = ruta del fondo de pantalla, $2 = nombre de la pantalla\n• Hook de cambio de tema: $1 = true/false (estado del modo oscuro)"
|
||||
}
|
||||
}
|
||||
},
|
||||
"control-center": {
|
||||
"position": {
|
||||
"description": "Elige dónde aparece el panel del Centro de control cuando se abre.",
|
||||
"label": "Posición"
|
||||
},
|
||||
"section": {
|
||||
"description": "Configurar el posicionamiento y el comportamiento del panel del Centro de control.",
|
||||
"label": "Apariencia"
|
||||
},
|
||||
"title": "Centro de control",
|
||||
"cards": {
|
||||
"section": {
|
||||
"description": "Personaliza qué controles aparecen en el Centro de control y en qué orden.",
|
||||
"label": "Tarjetas"
|
||||
}
|
||||
},
|
||||
"shortcuts": {
|
||||
"section": {
|
||||
"description": "Configurar y administrar los widgets de accesos directos.",
|
||||
"label": "Widgets de accesos directos"
|
||||
},
|
||||
"sectionLeft": "Izquierda",
|
||||
"sectionRight": "Derecha"
|
||||
}
|
||||
},
|
||||
"user-interface": {
|
||||
"animation-disable": {
|
||||
"description": "Desactiva todas las animaciones para una experiencia más rápida y con mayor capacidad de respuesta.",
|
||||
"label": "Desactivar animaciones de la interfaz de usuario"
|
||||
},
|
||||
"animation-speed": {
|
||||
"description": "Ajustar la velocidad global de la animación.",
|
||||
"label": "Velocidad de animación",
|
||||
"reset": "Restablecer la velocidad de la animación"
|
||||
},
|
||||
"border-radius": {
|
||||
"description": "Controla la redondez de las esquinas de las ventanas, los botones y otros elementos.",
|
||||
"label": "Radio de borde",
|
||||
"reset": "Restablecer el radio del borde"
|
||||
},
|
||||
"compact-lockscreen": {
|
||||
"description": "Mostrar solo el campo de inicio de sesión y los controles del sistema, ocultando los widgets del clima y multimedia.",
|
||||
"label": "Pantalla de bloqueo compacta"
|
||||
},
|
||||
"dim-desktop": {
|
||||
"description": "Atenuar el escritorio cuando los paneles o menús estén abiertos.",
|
||||
"label": "Dim escritorio"
|
||||
},
|
||||
"scaling": {
|
||||
"description": "Cambia el tamaño de la interfaz de usuario general, excluyendo la barra.",
|
||||
"label": "Escalado de la interfaz",
|
||||
"reset-scaling": "Restablecer el escalado de la interfaz"
|
||||
},
|
||||
"section": {
|
||||
"description": "Personaliza la apariencia, el ambiente y el comportamiento de la interfaz.",
|
||||
"label": "Apariencia"
|
||||
},
|
||||
"title": "Interfaz de usuario",
|
||||
"tooltips": {
|
||||
"description": "Activar o desactivar los avisos emergentes en toda la interfaz.",
|
||||
"label": "Mostrar sugerencias"
|
||||
}
|
||||
}
|
||||
},
|
||||
"widgets": {
|
||||
@@ -745,7 +790,11 @@
|
||||
},
|
||||
"file-picker": {
|
||||
"select-folder": "Seleccionar carpeta",
|
||||
"select-file": "Seleccionar archivo"
|
||||
"select-file": "Seleccionar archivo",
|
||||
"cancel": "Cancelar",
|
||||
"search-placeholder": "Buscar archivos y carpetas...",
|
||||
"select-current": "Seleccionar actual",
|
||||
"title": "Selector de archivos"
|
||||
},
|
||||
"datetime-tokens": {
|
||||
"common": {
|
||||
@@ -836,9 +885,9 @@
|
||||
"search-placeholder": "Buscar widgets..."
|
||||
},
|
||||
"active-window": {
|
||||
"auto-hide": {
|
||||
"label": "Ocultar automáticamente",
|
||||
"description": "Ocultar automáticamente el widget cuando no hay ventana activa."
|
||||
"hide-mode": {
|
||||
"label": "Modo de ocultación",
|
||||
"description": "Controla el comportamiento del widget cuando no hay ventana activa."
|
||||
},
|
||||
"show-app-icon": {
|
||||
"label": "Mostrar icono de la aplicación",
|
||||
@@ -851,6 +900,10 @@
|
||||
"width": {
|
||||
"description": "Controla el tamaño horizontal del widget.",
|
||||
"label": "Ancho del widget"
|
||||
},
|
||||
"colorize-icons": {
|
||||
"label": "Colorear iconos",
|
||||
"description": "Aplicar colores del tema al icono de la ventana activa."
|
||||
}
|
||||
},
|
||||
"system-monitor": {
|
||||
@@ -981,9 +1034,9 @@
|
||||
}
|
||||
},
|
||||
"media-mini": {
|
||||
"auto-hide": {
|
||||
"label": "Ocultar automáticamente",
|
||||
"description": "Ocultar automáticamente el widget cuando no se está reproduciendo ningún medio."
|
||||
"hide-mode": {
|
||||
"label": "Modo de ocultación",
|
||||
"description": "Controla el comportamiento del widget cuando no se está reproduciendo ningún medio."
|
||||
},
|
||||
"show-album-art": {
|
||||
"label": "Mostrar arte del álbum",
|
||||
@@ -1044,6 +1097,16 @@
|
||||
"only-same-output": {
|
||||
"description": "Muestra solo las aplicaciones del resultado donde se encuentra la barra.",
|
||||
"label": "Solo de la misma salida"
|
||||
},
|
||||
"colorize-icons": {
|
||||
"label": "Colorear iconos",
|
||||
"description": "Aplicar colores del tema a los iconos de la barra de tareas."
|
||||
}
|
||||
},
|
||||
"tray": {
|
||||
"colorize-icons": {
|
||||
"label": "Colorear iconos",
|
||||
"description": "Aplicar colores del tema a los iconos de la bandeja del sistema."
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1213,7 +1276,8 @@
|
||||
"density": {
|
||||
"compact": "Compacta",
|
||||
"default": "Predeterminada",
|
||||
"comfortable": "Cómoda"
|
||||
"comfortable": "Cómoda",
|
||||
"mini": "Mini"
|
||||
}
|
||||
},
|
||||
"launcher": {
|
||||
@@ -1238,6 +1302,11 @@
|
||||
"bottom_right": "Inferior derecha",
|
||||
"bottom_center": "Inferior central",
|
||||
"top_center": "Superior central"
|
||||
},
|
||||
"quickSettingsStyle": {
|
||||
"modern": "Moderno",
|
||||
"classic": "Clásico",
|
||||
"compact": "Compacto"
|
||||
}
|
||||
},
|
||||
"osd": {
|
||||
@@ -1297,6 +1366,11 @@
|
||||
"microphone-input": "Entrada del micrófono",
|
||||
"both": "Salida del sistema + entrada del micrófono"
|
||||
}
|
||||
},
|
||||
"hide-modes": {
|
||||
"hidden": "Ocultar cuando esté vacío",
|
||||
"transparent": "Transparente cuando está vacío",
|
||||
"visible": "Siempre visible"
|
||||
}
|
||||
},
|
||||
"session-menu": {
|
||||
@@ -1334,9 +1408,9 @@
|
||||
"calculator-error": "Error"
|
||||
},
|
||||
"system": {
|
||||
"uptime": "Tiempo de actividad: {uptime}",
|
||||
"uptime": "Actividad: {uptime}",
|
||||
"welcome-back": "¡Bienvenido de nuevo,",
|
||||
"monitor-description": "{model} ({width}x{height})",
|
||||
"monitor-description": "{model} ({width}x{height} @ {scale}x)",
|
||||
"scaling-percentage": "{percentage}%",
|
||||
"location-display": "{name} ({coordinates})",
|
||||
"signal-strength": "{signal}%",
|
||||
@@ -1359,6 +1433,78 @@
|
||||
"restart": "Reiniciar",
|
||||
"suspend": "Suspender"
|
||||
},
|
||||
"quickSettings": {
|
||||
"notifications": {
|
||||
"label": {
|
||||
"enabled": "Notificaciones",
|
||||
"disabled": "No molestar"
|
||||
},
|
||||
"tooltip": {
|
||||
"action": "Clic izquierdo: Abrir historial de notificaciones\nClic derecho: Alternar No molestar"
|
||||
}
|
||||
},
|
||||
"screenRecorder": {
|
||||
"label": {
|
||||
"recording": "Detener",
|
||||
"stopped": "Grabar"
|
||||
},
|
||||
"tooltip": {
|
||||
"action": "Hacer clic para iniciar/detener la grabación de pantalla"
|
||||
}
|
||||
},
|
||||
"powerProfile": {
|
||||
"label": {
|
||||
"unavailable": "Perfil de energía"
|
||||
},
|
||||
"tooltip": {
|
||||
"action": "Hacer clic para cambiar el perfil de energía"
|
||||
}
|
||||
},
|
||||
"wifi": {
|
||||
"label": {
|
||||
"ethernet": "Ethernet",
|
||||
"wifi": "Wi-Fi",
|
||||
"disconnected": "Wi-Fi desconectado"
|
||||
},
|
||||
"tooltip": {
|
||||
"action": "Hacer clic para gestionar las conexiones Wi-Fi"
|
||||
}
|
||||
},
|
||||
"bluetooth": {
|
||||
"label": {
|
||||
"enabled": "Bluetooth",
|
||||
"disabled": "Bluetooth"
|
||||
},
|
||||
"tooltip": {
|
||||
"action": "Hacer clic para gestionar los dispositivos Bluetooth"
|
||||
}
|
||||
},
|
||||
"nightLight": {
|
||||
"label": {
|
||||
"enabled": "Luz nocturna",
|
||||
"forced": "Luz nocturna",
|
||||
"disabled": "Luz nocturna"
|
||||
},
|
||||
"tooltip": {
|
||||
"action": "Hacer clic para alternar el modo Luz nocturna\nClic derecho: Abrir configuración"
|
||||
}
|
||||
},
|
||||
"wallpaperSelector": {
|
||||
"label": "Fondo de pantalla",
|
||||
"tooltip": {
|
||||
"action": "Clic izquierdo: Abrir selector de fondo de pantalla\nClic derecho: Establecer fondo de pantalla aleatorio"
|
||||
}
|
||||
},
|
||||
"keepAwake": {
|
||||
"label": {
|
||||
"enabled": "Mantener despierto",
|
||||
"disabled": "Mantener despierto"
|
||||
},
|
||||
"tooltip": {
|
||||
"action": "Hacer clic para alternar el modo Mantener despierto"
|
||||
}
|
||||
}
|
||||
},
|
||||
"toast": {
|
||||
"night-light": {
|
||||
"enabled": "Activada",
|
||||
@@ -1406,6 +1552,9 @@
|
||||
"enabled": "Activado",
|
||||
"disabled": "Desactivado"
|
||||
},
|
||||
"kofi": {
|
||||
"opened": "Página de Ko-fi abierta en tu navegador"
|
||||
},
|
||||
"do-not-disturb": {
|
||||
"enabled": "'No molestar' activado",
|
||||
"disabled": "'No molestar' desactivado",
|
||||
|
||||
+206
-57
@@ -13,32 +13,6 @@
|
||||
},
|
||||
"select-avatar": "Sélectionner une image d'avatar"
|
||||
},
|
||||
"ui": {
|
||||
"section": {
|
||||
"label": "Interface utilisateur",
|
||||
"description": "Personnalisez l'apparence, l'ergonomie et le comportement de l'interface."
|
||||
},
|
||||
"tooltips": {
|
||||
"label": "Afficher les tooltips",
|
||||
"description": "Activer ou désactiver les tooltips dans toute l'interface."
|
||||
},
|
||||
"dim-desktop": {
|
||||
"label": "Assombrir le bureau",
|
||||
"description": "Assombrir le bureau lorsque des panneaux ou des menus sont ouverts."
|
||||
},
|
||||
"border-radius": {
|
||||
"label": "Rayon de bordure",
|
||||
"description": "Contrôle l'arrondi des coins des fenêtres, des boutons et d'autres éléments."
|
||||
},
|
||||
"animation-speed": {
|
||||
"label": "Vitesse d'animation",
|
||||
"description": "Ajustez la vitesse globale des animations."
|
||||
},
|
||||
"animation-disable": {
|
||||
"label": "Désactiver les animations de l'interface",
|
||||
"description": "Désactiver toutes les animations pour une expérience plus rapide et réactive."
|
||||
}
|
||||
},
|
||||
"screen-corners": {
|
||||
"section": {
|
||||
"label": "Coins de l'écran",
|
||||
@@ -54,7 +28,8 @@
|
||||
},
|
||||
"radius": {
|
||||
"label": "Rayon des coins de l'écran",
|
||||
"description": "Ajustez l'arrondi des coins de l'écran."
|
||||
"description": "Ajustez l'arrondi des coins de l'écran.",
|
||||
"reset": "Réinitialiser le rayon des coins de l'écran"
|
||||
}
|
||||
},
|
||||
"fonts": {
|
||||
@@ -83,16 +58,6 @@
|
||||
}
|
||||
},
|
||||
"reset-scaling": "Réinitialiser l'échelle"
|
||||
},
|
||||
"control-center": {
|
||||
"section": {
|
||||
"label": "Centre de contrôle",
|
||||
"description": "Configurer le positionnement et le comportement du panneau du centre de contrôle."
|
||||
},
|
||||
"position": {
|
||||
"label": "Position",
|
||||
"description": "Choisissez où apparaît le panneau du centre de contrôle lors de l'ouverture."
|
||||
}
|
||||
}
|
||||
},
|
||||
"audio": {
|
||||
@@ -179,11 +144,9 @@
|
||||
"monitors": {
|
||||
"section": {
|
||||
"label": "Paramètres par moniteur",
|
||||
"description": "Ajustez la mise à l'échelle et la luminosité pour chaque écran."
|
||||
"description": "Ajustez la luminosité pour chaque écran."
|
||||
},
|
||||
"scale": "Mise à l'échelle",
|
||||
"brightness": "Luminosité",
|
||||
"reset-scaling": "Réinitialiser la mise à l'échelle",
|
||||
"brightness-step": {
|
||||
"label": "Incrément de luminosité",
|
||||
"description": "Ajustez l'incrément pour les changements de luminosité (molette de la souris et raccourcis clavier)."
|
||||
@@ -259,14 +222,21 @@
|
||||
"widgets": {
|
||||
"section": {
|
||||
"label": "Positionnement des widgets",
|
||||
"description": "Glissez-déposez les widgets pour les réorganiser dans chaque section, ou utilisez les boutons ajouter/supprimer pour gérer les widgets."
|
||||
"description": "Faites glisser et déposez les widgets pour les réorganiser. Les badges indiquent l'utilisation : [G]auche, [C]entre, [D]roite."
|
||||
}
|
||||
},
|
||||
"monitors": {
|
||||
"section": {
|
||||
"label": "Affichage sur les moniteur",
|
||||
"label": "Affichage sur les moniteurs",
|
||||
"description": "Afficher la barre sur des moniteurs spécifiques. Par défaut, sur tous si aucun n'est choisi."
|
||||
}
|
||||
},
|
||||
"tray": {
|
||||
"blacklist": {
|
||||
"label": "Liste noire",
|
||||
"description": "Ajouter des règles d'exclusion pour la boîte à miniatures, prend en charge les caractères génériques (*).",
|
||||
"placeholder": "ex: nm-applet, Fcitx*"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dock": {
|
||||
@@ -290,6 +260,10 @@
|
||||
"floating-distance": {
|
||||
"label": "Distance de flottaison du dock",
|
||||
"description": "Ajustez la distance de flottaison par rapport au bord de l'écran."
|
||||
},
|
||||
"colorize-icons": {
|
||||
"label": "Coloriser les icônes",
|
||||
"description": "Appliquer les couleurs du thème aux icônes d'applications du dock (applications non focalisées uniquement)."
|
||||
}
|
||||
},
|
||||
"monitors": {
|
||||
@@ -402,6 +376,10 @@
|
||||
"label": "Activer l'affichage à l'écran",
|
||||
"description": "Afficher en temps réel les changements de volume et de luminosité."
|
||||
},
|
||||
"always-on-top": {
|
||||
"label": "Toujours au premier plan",
|
||||
"description": "Afficher l'OSD au-dessus des fenêtres plein écran et autres couches."
|
||||
},
|
||||
"location": {
|
||||
"label": "Emplacement",
|
||||
"description": "Emplacement des affichages à l'écran."
|
||||
@@ -529,6 +507,9 @@
|
||||
},
|
||||
"qt": {
|
||||
"description": "Écrire {filepath}"
|
||||
},
|
||||
"kcolorscheme": {
|
||||
"description": "Écrire {filepath}"
|
||||
}
|
||||
},
|
||||
"terminal": {
|
||||
@@ -554,9 +535,9 @@
|
||||
"description": "Écrire ~/.config/fuzzel/themes/noctalia et recharger",
|
||||
"description-missing": "Nécessite que le lanceur fuzzel soit installé"
|
||||
},
|
||||
"vesktop": {
|
||||
"description": "Écrire ~/.config/vesktop/themes/noctalia.theme.css",
|
||||
"description-missing": "Nécessite que le client Discord vesktop soit installé"
|
||||
"discord": {
|
||||
"description": "Écrire {filepath} pour {client}",
|
||||
"description-missing": "Aucun client Discord détecté. Installez vesktop, webcord, armcord, equibop, lightcord ou dorion."
|
||||
},
|
||||
"pywalfox": {
|
||||
"description": "Écrire ~/.cache/wal/colors.json et exécuter pywalfox update",
|
||||
@@ -703,7 +684,8 @@
|
||||
"description": "Un grand merci à notre {count} <b>super</b> contributeur !",
|
||||
"description_plural": "Un grand merci à nos {count} <b>super</b> contributeurs !"
|
||||
}
|
||||
}
|
||||
},
|
||||
"support": "Soutenez-nous"
|
||||
},
|
||||
"hooks": {
|
||||
"title": "Hooks",
|
||||
@@ -737,6 +719,69 @@
|
||||
"description": "• Hook Fond d'écran : $1 = chemin du fond d'écran, $2 = nom de l'écran\n• Hook de bascule de thème : $1 = true/false (état du mode sombre)"
|
||||
}
|
||||
}
|
||||
},
|
||||
"control-center": {
|
||||
"position": {
|
||||
"description": "Choisissez où le panneau du Centre de contrôle apparaît lorsqu'il est ouvert.",
|
||||
"label": "Position"
|
||||
},
|
||||
"section": {
|
||||
"description": "Configurer le positionnement et le comportement du panneau du Centre de contrôle.",
|
||||
"label": "Apparence"
|
||||
},
|
||||
"title": "Centre de contrôle",
|
||||
"cards": {
|
||||
"section": {
|
||||
"description": "Personnalisez les commandes qui apparaissent dans le Centre de contrôle et leur ordre d'affichage.",
|
||||
"label": "Cartes"
|
||||
}
|
||||
},
|
||||
"shortcuts": {
|
||||
"section": {
|
||||
"description": "Configurer et gérer les widgets de raccourcis.",
|
||||
"label": "Widgets de raccourcis"
|
||||
},
|
||||
"sectionLeft": "Gauche",
|
||||
"sectionRight": "Droite"
|
||||
}
|
||||
},
|
||||
"user-interface": {
|
||||
"animation-disable": {
|
||||
"description": "Désactiver toutes les animations pour une expérience plus rapide et plus réactive.",
|
||||
"label": "Désactiver les animations de l'interface utilisateur"
|
||||
},
|
||||
"animation-speed": {
|
||||
"description": "Ajuster la vitesse globale de l'animation.",
|
||||
"label": "Vitesse d'animation",
|
||||
"reset": "Réinitialiser la vitesse de l'animation"
|
||||
},
|
||||
"border-radius": {
|
||||
"description": "Contrôle l'arrondi des angles des fenêtres, des boutons et d'autres éléments.",
|
||||
"label": "Rayon de bordure",
|
||||
"reset": "Réinitialiser le rayon de la bordure"
|
||||
},
|
||||
"compact-lockscreen": {
|
||||
"description": "Afficher uniquement le champ de saisie de connexion et les commandes système, en masquant les widgets météo et multimédia.",
|
||||
"label": "Écran de verrouillage compact"
|
||||
},
|
||||
"dim-desktop": {
|
||||
"description": "Atténuer le bureau lorsque des panneaux ou des menus sont ouverts.",
|
||||
"label": "Dim bureau"
|
||||
},
|
||||
"scaling": {
|
||||
"description": "Modifie la taille de l'interface utilisateur générale, à l'exception de la barre.",
|
||||
"label": "Mise à l'échelle de l'interface",
|
||||
"reset-scaling": "Réinitialiser l'échelle de l'interface"
|
||||
},
|
||||
"section": {
|
||||
"description": "Personnaliser l'apparence, l'ergonomie et le comportement de l'interface.",
|
||||
"label": "Apparence"
|
||||
},
|
||||
"title": "Interface utilisateur",
|
||||
"tooltips": {
|
||||
"description": "Activer ou désactiver les info-bulles dans toute l'interface.",
|
||||
"label": "Afficher les infobulles"
|
||||
}
|
||||
}
|
||||
},
|
||||
"widgets": {
|
||||
@@ -745,7 +790,11 @@
|
||||
},
|
||||
"file-picker": {
|
||||
"select-folder": "Sélectionner un dossier",
|
||||
"select-file": "Sélectionner un fichier"
|
||||
"select-file": "Sélectionner un fichier",
|
||||
"cancel": "Annuler",
|
||||
"search-placeholder": "Rechercher des fichiers et des dossiers...",
|
||||
"select-current": "Sélectionner Actuel",
|
||||
"title": "Sélecteur de fichiers"
|
||||
},
|
||||
"datetime-tokens": {
|
||||
"common": {
|
||||
@@ -844,13 +893,17 @@
|
||||
"label": "Mode de défilement",
|
||||
"description": "Contrôler quand le défilement de texte est activé pour les titres de fenêtre longs."
|
||||
},
|
||||
"auto-hide": {
|
||||
"label": "Masquer automatiquement",
|
||||
"description": "Masquer automatiquement le widget quand aucune fenêtre n'est active."
|
||||
"hide-mode": {
|
||||
"label": "Mode de masquage",
|
||||
"description": "Contrôle le comportement du widget lorsqu'aucune fenêtre n'est active."
|
||||
},
|
||||
"width": {
|
||||
"description": "Contrôle la taille horizontale du widget.",
|
||||
"label": "Largeur du widget"
|
||||
},
|
||||
"colorize-icons": {
|
||||
"label": "Coloriser les icônes",
|
||||
"description": "Appliquer les couleurs du thème à l'icône de la fenêtre active."
|
||||
}
|
||||
},
|
||||
"system-monitor": {
|
||||
@@ -997,9 +1050,9 @@
|
||||
"label": "Mode de défilement",
|
||||
"description": "Contrôler quand le défilement de texte est activé pour les titres de piste longs."
|
||||
},
|
||||
"auto-hide": {
|
||||
"label": "Masquer automatiquement",
|
||||
"description": "Masquer automatiquement le widget quand aucun média n'est en cours de lecture."
|
||||
"hide-mode": {
|
||||
"label": "Mode de masquage",
|
||||
"description": "Contrôle le comportement du widget lorsqu'aucun média n'est en cours de lecture."
|
||||
},
|
||||
"no-active-player": "Aucun lecteur actif"
|
||||
},
|
||||
@@ -1044,6 +1097,16 @@
|
||||
"only-same-output": {
|
||||
"description": "Afficher uniquement les applications de la sortie où la barre est située.",
|
||||
"label": "Seulement à partir de la même sortie"
|
||||
},
|
||||
"colorize-icons": {
|
||||
"label": "Coloriser les icônes",
|
||||
"description": "Appliquer les couleurs du thème aux icônes de la barre des tâches."
|
||||
}
|
||||
},
|
||||
"tray": {
|
||||
"colorize-icons": {
|
||||
"label": "Coloriser les icônes",
|
||||
"description": "Appliquer les couleurs du thème aux icônes de la barre système."
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1213,7 +1276,8 @@
|
||||
"density": {
|
||||
"compact": "Compact",
|
||||
"default": "Défaut",
|
||||
"comfortable": "Confortable"
|
||||
"comfortable": "Confortable",
|
||||
"mini": "Mini"
|
||||
}
|
||||
},
|
||||
"launcher": {
|
||||
@@ -1238,6 +1302,11 @@
|
||||
"bottom_right": "En bas à droite",
|
||||
"bottom_center": "En bas au centre",
|
||||
"top_center": "En haut au centre"
|
||||
},
|
||||
"quickSettingsStyle": {
|
||||
"modern": "Moderne",
|
||||
"classic": "Classique",
|
||||
"compact": "Compact"
|
||||
}
|
||||
},
|
||||
"osd": {
|
||||
@@ -1297,6 +1366,11 @@
|
||||
"microphone-input": "Entrée microphone",
|
||||
"both": "Sortie système + entrée microphone"
|
||||
}
|
||||
},
|
||||
"hide-modes": {
|
||||
"hidden": "Masquer si vide",
|
||||
"transparent": "Transparent quand vide",
|
||||
"visible": "Toujours visible"
|
||||
}
|
||||
},
|
||||
"session-menu": {
|
||||
@@ -1334,9 +1408,8 @@
|
||||
"calculator-error": "Erreur"
|
||||
},
|
||||
"system": {
|
||||
"uptime": "Temps d'activité : {uptime}",
|
||||
"welcome-back": "Bon retour,",
|
||||
"monitor-description": "{model} ({width}x{height})",
|
||||
"monitor-description": "{model} ({width}x{height} @ {scale}x)",
|
||||
"scaling-percentage": "{percentage}%",
|
||||
"location-display": "{name} ({coordinates})",
|
||||
"signal-strength": "{signal}%",
|
||||
@@ -1348,7 +1421,8 @@
|
||||
"user-requested": "Demandé par l'utilisateur",
|
||||
"unknown": "Inconnu",
|
||||
"unknown-version": "Inconnue",
|
||||
"unknown-layout": "Inconnue"
|
||||
"unknown-layout": "Inconnue",
|
||||
"uptime": "Activité : {uptime}"
|
||||
},
|
||||
"lock-screen": {
|
||||
"password": "Entrez votre mot de passe...",
|
||||
@@ -1359,6 +1433,78 @@
|
||||
"restart": "Redémarrer",
|
||||
"suspend": "Mettre en veille"
|
||||
},
|
||||
"quickSettings": {
|
||||
"notifications": {
|
||||
"label": {
|
||||
"enabled": "Notifications",
|
||||
"disabled": "Ne pas déranger"
|
||||
},
|
||||
"tooltip": {
|
||||
"action": "Clic gauche : Ouvrir l'historique des notifications\nClic droit : Basculer Ne pas déranger"
|
||||
}
|
||||
},
|
||||
"screenRecorder": {
|
||||
"label": {
|
||||
"recording": "Arrêter",
|
||||
"stopped": "Enregistrer"
|
||||
},
|
||||
"tooltip": {
|
||||
"action": "Cliquer pour démarrer/arrêter l'enregistrement d'écran"
|
||||
}
|
||||
},
|
||||
"powerProfile": {
|
||||
"label": {
|
||||
"unavailable": "Profil d'alimentation"
|
||||
},
|
||||
"tooltip": {
|
||||
"action": "Cliquer pour changer de profil d'alimentation"
|
||||
}
|
||||
},
|
||||
"wifi": {
|
||||
"label": {
|
||||
"ethernet": "Ethernet",
|
||||
"wifi": "Wi-Fi",
|
||||
"disconnected": "Wi-Fi déconnecté"
|
||||
},
|
||||
"tooltip": {
|
||||
"action": "Cliquer pour gérer les connexions Wi-Fi"
|
||||
}
|
||||
},
|
||||
"bluetooth": {
|
||||
"label": {
|
||||
"enabled": "Bluetooth",
|
||||
"disabled": "Bluetooth"
|
||||
},
|
||||
"tooltip": {
|
||||
"action": "Cliquer pour gérer les appareils Bluetooth"
|
||||
}
|
||||
},
|
||||
"nightLight": {
|
||||
"label": {
|
||||
"enabled": "Lumière nocturne",
|
||||
"forced": "Lumière nocturne",
|
||||
"disabled": "Lumière nocturne"
|
||||
},
|
||||
"tooltip": {
|
||||
"action": "Cliquer pour basculer le mode Lumière nocturne\nClic droit : Ouvrir les paramètres"
|
||||
}
|
||||
},
|
||||
"wallpaperSelector": {
|
||||
"label": "Fond d'écran",
|
||||
"tooltip": {
|
||||
"action": "Clic gauche : Ouvrir le sélecteur de fond d'écran\nClic droit : Définir un fond d'écran aléatoire"
|
||||
}
|
||||
},
|
||||
"keepAwake": {
|
||||
"label": {
|
||||
"enabled": "Rester éveillé",
|
||||
"disabled": "Rester éveillé"
|
||||
},
|
||||
"tooltip": {
|
||||
"action": "Cliquer pour basculer le mode Rester éveillé"
|
||||
}
|
||||
}
|
||||
},
|
||||
"toast": {
|
||||
"night-light": {
|
||||
"enabled": "Activé",
|
||||
@@ -1406,6 +1552,9 @@
|
||||
"enabled": "Activé",
|
||||
"disabled": "Désactivé"
|
||||
},
|
||||
"kofi": {
|
||||
"opened": "Page Ko-fi ouverte dans votre navigateur"
|
||||
},
|
||||
"do-not-disturb": {
|
||||
"enabled": "'Ne pas déranger' activé",
|
||||
"disabled": "'Ne pas déranger' désactivé",
|
||||
|
||||
+204
-55
@@ -13,32 +13,6 @@
|
||||
},
|
||||
"select-avatar": "Selecionar imagem de avatar"
|
||||
},
|
||||
"ui": {
|
||||
"section": {
|
||||
"label": "Interface do usuário",
|
||||
"description": "Personalize a aparência, a sensação e o comportamento da interface."
|
||||
},
|
||||
"tooltips": {
|
||||
"label": "Mostrar tooltips",
|
||||
"description": "Ativar ou desativar tooltips em toda a interface."
|
||||
},
|
||||
"dim-desktop": {
|
||||
"label": "Escurecer área de trabalho",
|
||||
"description": "Escurece a área de trabalho quando painéis ou menus estão abertos."
|
||||
},
|
||||
"border-radius": {
|
||||
"label": "Raio da borda",
|
||||
"description": "Controla o arredondamento dos cantos de janelas, botões e outros elementos."
|
||||
},
|
||||
"animation-speed": {
|
||||
"label": "Velocidade da animação",
|
||||
"description": "Ajuste a velocidade global da animação."
|
||||
},
|
||||
"animation-disable": {
|
||||
"label": "Desativar animações da interface",
|
||||
"description": "Desativar todas as animações para uma experiência mais rápida e responsiva."
|
||||
}
|
||||
},
|
||||
"screen-corners": {
|
||||
"section": {
|
||||
"label": "Cantos da tela",
|
||||
@@ -54,7 +28,8 @@
|
||||
},
|
||||
"radius": {
|
||||
"label": "Raio dos cantos da tela",
|
||||
"description": "Ajuste os cantos arredondados da tela."
|
||||
"description": "Ajuste os cantos arredondados da tela.",
|
||||
"reset": "Redefinir raio dos cantos da tela"
|
||||
}
|
||||
},
|
||||
"fonts": {
|
||||
@@ -83,16 +58,6 @@
|
||||
}
|
||||
},
|
||||
"reset-scaling": "Redefinir escala"
|
||||
},
|
||||
"control-center": {
|
||||
"section": {
|
||||
"label": "Centro de controle",
|
||||
"description": "Configurar o posicionamento e comportamento do painel do centro de controle."
|
||||
},
|
||||
"position": {
|
||||
"label": "Posição",
|
||||
"description": "Escolha onde o painel do centro de controle aparece quando aberto."
|
||||
}
|
||||
}
|
||||
},
|
||||
"audio": {
|
||||
@@ -179,11 +144,9 @@
|
||||
"monitors": {
|
||||
"section": {
|
||||
"label": "Configurações por monitor",
|
||||
"description": "Ajuste a escala e o brilho para cada tela."
|
||||
"description": "Ajustar o brilho das configurações para cada tela."
|
||||
},
|
||||
"scale": "Escala",
|
||||
"brightness": "Brilho",
|
||||
"reset-scaling": "Redefinir escala",
|
||||
"brightness-step": {
|
||||
"label": "Tamanho do passo do brilho",
|
||||
"description": "Ajuste o tamanho do passo para alterações de brilho (roda do mouse e atalhos de teclado)."
|
||||
@@ -259,7 +222,7 @@
|
||||
"widgets": {
|
||||
"section": {
|
||||
"label": "Posicionamento dos widgets",
|
||||
"description": "Arraste e solte os widgets para reordená-los em cada seção, ou use os botões de adicionar/remover para gerenciar os widgets."
|
||||
"description": "Arraste e solte widgets para reordená-los. Os emblemas indicam o uso: [E]squerda, [C]entro, [D]ireita."
|
||||
}
|
||||
},
|
||||
"monitors": {
|
||||
@@ -267,6 +230,13 @@
|
||||
"label": "Exibição nos monitores",
|
||||
"description": "Mostra a barra em monitores específicos. O padrão é todos, se nenhum for escolhido."
|
||||
}
|
||||
},
|
||||
"tray": {
|
||||
"blacklist": {
|
||||
"label": "Lista Negra",
|
||||
"description": "Adicione regras de exclusão para a bandeja do sistema, suporta curingas (*).",
|
||||
"placeholder": "ex: nm-applet, Fcitx*"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dock": {
|
||||
@@ -290,6 +260,10 @@
|
||||
"floating-distance": {
|
||||
"label": "Distância de flutuação da dock",
|
||||
"description": "Ajuste a distância de flutuação da borda da tela."
|
||||
},
|
||||
"colorize-icons": {
|
||||
"label": "Colorir ícones",
|
||||
"description": "Aplicar cores do tema aos ícones de aplicativos da dock (apenas aplicativos não focados)."
|
||||
}
|
||||
},
|
||||
"monitors": {
|
||||
@@ -495,6 +469,9 @@
|
||||
},
|
||||
"qt": {
|
||||
"description": "Escrever {filepath}"
|
||||
},
|
||||
"kcolorscheme": {
|
||||
"description": "Escrever {filepath}"
|
||||
}
|
||||
},
|
||||
"terminal": {
|
||||
@@ -520,9 +497,9 @@
|
||||
"description": "Escrever {filepath} e recarregar",
|
||||
"description-missing": "Requer que o {app} esteja instalado"
|
||||
},
|
||||
"vesktop": {
|
||||
"description": "Escrever {filepath}",
|
||||
"description-missing": "Requer que o {app} esteja instalado"
|
||||
"discord": {
|
||||
"description": "Escrever {filepath} para {client}",
|
||||
"description-missing": "Nenhum cliente Discord detectado. Instale vesktop, webcord, armcord, equibop, lightcord ou dorion."
|
||||
},
|
||||
"pywalfox": {
|
||||
"description": "Escrever {filepath} e executar pywalfox update",
|
||||
@@ -669,7 +646,8 @@
|
||||
"description": "Agradecimentos ao nosso <b>incrível</b> colaborador!",
|
||||
"description_plural": "Agradecimentos aos nossos {count} <b>incríveis</b> colaboradores!"
|
||||
}
|
||||
}
|
||||
},
|
||||
"support": "Apoie-nos"
|
||||
},
|
||||
"hooks": {
|
||||
"title": "Hooks",
|
||||
@@ -717,6 +695,10 @@
|
||||
"label": "Ativar exibição na tela",
|
||||
"description": "Mostrar alterações de volume e brilho em tempo real."
|
||||
},
|
||||
"always-on-top": {
|
||||
"label": "Sempre no topo",
|
||||
"description": "Exibir OSD acima de janelas em tela cheia e outras camadas."
|
||||
},
|
||||
"location": {
|
||||
"label": "Localização",
|
||||
"description": "Onde a exibição na tela aparece."
|
||||
@@ -737,6 +719,69 @@
|
||||
"description": "Mostrar a OSD em monitores específicos. Padrão é todos se nenhum for escolhido."
|
||||
}
|
||||
}
|
||||
},
|
||||
"control-center": {
|
||||
"position": {
|
||||
"description": "Escolha onde o painel da Central de Controle aparece quando aberto.",
|
||||
"label": "Posição"
|
||||
},
|
||||
"section": {
|
||||
"description": "Configurar o posicionamento e o comportamento do painel da Central de Controle.",
|
||||
"label": "Aparência"
|
||||
},
|
||||
"title": "Central de Controle",
|
||||
"cards": {
|
||||
"section": {
|
||||
"description": "Personalize quais controles aparecem na Central de Controle e em que ordem.",
|
||||
"label": "Cartas"
|
||||
}
|
||||
},
|
||||
"shortcuts": {
|
||||
"section": {
|
||||
"description": "Configure e gerencie os widgets de atalhos.",
|
||||
"label": "Widgets de atalhos"
|
||||
},
|
||||
"sectionLeft": "Esquerda",
|
||||
"sectionRight": "Direito/Certo/À direita"
|
||||
}
|
||||
},
|
||||
"user-interface": {
|
||||
"animation-disable": {
|
||||
"description": "Desative todas as animações para uma experiência mais rápida e responsiva.",
|
||||
"label": "Desativar animações da interface do usuário"
|
||||
},
|
||||
"animation-speed": {
|
||||
"description": "Ajustar a velocidade global da animação.",
|
||||
"label": "Velocidade da animação",
|
||||
"reset": "Redefinir velocidade da animação"
|
||||
},
|
||||
"border-radius": {
|
||||
"description": "Controla o arredondamento dos cantos de janelas, botões e outros elementos.",
|
||||
"label": "Raio da borda",
|
||||
"reset": "Redefinir raio da borda"
|
||||
},
|
||||
"compact-lockscreen": {
|
||||
"description": "Mostrar apenas a entrada de login e os controles do sistema, ocultando widgets de clima e mídia.",
|
||||
"label": "Tela de bloqueio compacta"
|
||||
},
|
||||
"dim-desktop": {
|
||||
"description": "Escurecer a área de trabalho quando painéis ou menus estiverem abertos.",
|
||||
"label": "Dim área de trabalho"
|
||||
},
|
||||
"scaling": {
|
||||
"description": "Altera o tamanho da interface geral do usuário, excluindo a barra.",
|
||||
"label": "Escalonamento da interface",
|
||||
"reset-scaling": "Redefinir escala da interface"
|
||||
},
|
||||
"section": {
|
||||
"description": "Personalize a aparência, a sensação e o comportamento da interface.",
|
||||
"label": "Aparência"
|
||||
},
|
||||
"title": "Interface do usuário",
|
||||
"tooltips": {
|
||||
"description": "Ativar ou desativar dicas de ferramentas em toda a interface.",
|
||||
"label": "Mostrar dicas de ferramenta"
|
||||
}
|
||||
}
|
||||
},
|
||||
"widgets": {
|
||||
@@ -745,7 +790,11 @@
|
||||
},
|
||||
"file-picker": {
|
||||
"select-folder": "Selecionar Pasta",
|
||||
"select-file": "Selecionar Arquivo"
|
||||
"select-file": "Selecionar Arquivo",
|
||||
"cancel": "Cancelar",
|
||||
"search-placeholder": "Pesquisar arquivos e pastas...",
|
||||
"select-current": "Selecionar Atual",
|
||||
"title": "Seletor de Arquivos"
|
||||
},
|
||||
"datetime-tokens": {
|
||||
"common": {
|
||||
@@ -836,9 +885,9 @@
|
||||
"search-placeholder": "Pesquisar widgets..."
|
||||
},
|
||||
"active-window": {
|
||||
"auto-hide": {
|
||||
"label": "Ocultar automaticamente",
|
||||
"description": "Ocultar automaticamente o widget quando nenhuma janela está ativa."
|
||||
"hide-mode": {
|
||||
"label": "Modo de ocultação",
|
||||
"description": "Controla o comportamento do widget quando nenhuma janela está ativa."
|
||||
},
|
||||
"show-app-icon": {
|
||||
"label": "Mostrar ícone do aplicativo",
|
||||
@@ -851,6 +900,10 @@
|
||||
"width": {
|
||||
"description": "Controla o tamanho horizontal do widget.",
|
||||
"label": "Largura do Widget"
|
||||
},
|
||||
"colorize-icons": {
|
||||
"label": "Colorir ícones",
|
||||
"description": "Aplicar cores do tema ao ícone da janela ativa."
|
||||
}
|
||||
},
|
||||
"system-monitor": {
|
||||
@@ -981,9 +1034,9 @@
|
||||
}
|
||||
},
|
||||
"media-mini": {
|
||||
"auto-hide": {
|
||||
"label": "Ocultar automaticamente",
|
||||
"description": "Ocultar automaticamente o widget quando nenhuma mídia está sendo reproduzida."
|
||||
"hide-mode": {
|
||||
"label": "Modo de ocultação",
|
||||
"description": "Controla o comportamento do widget quando nenhuma mídia está sendo reproduzida."
|
||||
},
|
||||
"show-album-art": {
|
||||
"label": "Mostrar arte do álbum",
|
||||
@@ -1044,6 +1097,16 @@
|
||||
"only-same-output": {
|
||||
"description": "Mostrar apenas os aplicativos da saída onde a barra está localizada.",
|
||||
"label": "Apenas da mesma saída"
|
||||
},
|
||||
"colorize-icons": {
|
||||
"label": "Colorir ícones",
|
||||
"description": "Aplicar cores do tema aos ícones da barra de tarefas."
|
||||
}
|
||||
},
|
||||
"tray": {
|
||||
"colorize-icons": {
|
||||
"label": "Colorir ícones",
|
||||
"description": "Aplicar cores do tema aos ícones da bandeja do sistema."
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1237,6 +1300,11 @@
|
||||
"bottom_right": "Inferior direito",
|
||||
"bottom_center": "Centro inferior",
|
||||
"top_center": "Centro superior"
|
||||
},
|
||||
"quickSettingsStyle": {
|
||||
"modern": "Moderno",
|
||||
"classic": "Clássico",
|
||||
"compact": "Compacto"
|
||||
}
|
||||
},
|
||||
"bar": {
|
||||
@@ -1249,7 +1317,8 @@
|
||||
"density": {
|
||||
"compact": "Compacta",
|
||||
"default": "Padrão",
|
||||
"comfortable": "Confortável"
|
||||
"comfortable": "Confortável",
|
||||
"mini": "Mini"
|
||||
}
|
||||
},
|
||||
"display-mode": {
|
||||
@@ -1297,6 +1366,11 @@
|
||||
"microphone-input": "Entrada do microfone",
|
||||
"both": "Saída do sistema + entrada do microfone"
|
||||
}
|
||||
},
|
||||
"hide-modes": {
|
||||
"hidden": "Ocultar Quando Vazio",
|
||||
"transparent": "Transparente quando vazio",
|
||||
"visible": "Sempre Visível"
|
||||
}
|
||||
},
|
||||
"session-menu": {
|
||||
@@ -1334,9 +1408,9 @@
|
||||
"calculator-error": "Erro"
|
||||
},
|
||||
"system": {
|
||||
"uptime": "Sistema ativo há: {uptime}",
|
||||
"uptime": "Atividade: {uptime}",
|
||||
"welcome-back": "Bem-vindo(a) de volta, {user}!",
|
||||
"monitor-description": "{model} ({width}x{height})",
|
||||
"monitor-description": "{model} ({width}x{height} @ {scale}x)",
|
||||
"scaling-percentage": "{percentage}%",
|
||||
"location-display": "{name} ({coordinates})",
|
||||
"signal-strength": "{signal}%",
|
||||
@@ -1359,6 +1433,78 @@
|
||||
"restart": "Reiniciar",
|
||||
"suspend": "Suspender"
|
||||
},
|
||||
"quickSettings": {
|
||||
"notifications": {
|
||||
"label": {
|
||||
"enabled": "Notificações",
|
||||
"disabled": "Não perturbar"
|
||||
},
|
||||
"tooltip": {
|
||||
"action": "Clique esquerdo: Abrir histórico de notificações\nClique direito: Alternar Não perturbar"
|
||||
}
|
||||
},
|
||||
"screenRecorder": {
|
||||
"label": {
|
||||
"recording": "Parar",
|
||||
"stopped": "Gravar"
|
||||
},
|
||||
"tooltip": {
|
||||
"action": "Clique para iniciar/parar a gravação da tela"
|
||||
}
|
||||
},
|
||||
"powerProfile": {
|
||||
"label": {
|
||||
"unavailable": "Perfil de energia"
|
||||
},
|
||||
"tooltip": {
|
||||
"action": "Clique para alternar o perfil de energia"
|
||||
}
|
||||
},
|
||||
"wifi": {
|
||||
"label": {
|
||||
"ethernet": "Ethernet",
|
||||
"wifi": "Wi-Fi",
|
||||
"disconnected": "Wi-Fi desconectado"
|
||||
},
|
||||
"tooltip": {
|
||||
"action": "Clique para gerenciar conexões Wi-Fi"
|
||||
}
|
||||
},
|
||||
"bluetooth": {
|
||||
"label": {
|
||||
"enabled": "Bluetooth",
|
||||
"disabled": "Bluetooth"
|
||||
},
|
||||
"tooltip": {
|
||||
"action": "Clique para gerenciar dispositivos Bluetooth"
|
||||
}
|
||||
},
|
||||
"nightLight": {
|
||||
"label": {
|
||||
"enabled": "Luz noturna",
|
||||
"forced": "Luz noturna",
|
||||
"disabled": "Luz noturna"
|
||||
},
|
||||
"tooltip": {
|
||||
"action": "Clique para alternar o modo Luz noturna\nClique direito: Abrir configurações"
|
||||
}
|
||||
},
|
||||
"wallpaperSelector": {
|
||||
"label": "Papel de parede",
|
||||
"tooltip": {
|
||||
"action": "Clique esquerdo: Abrir seletor de papel de parede\nClique direito: Definir papel de parede aleatório"
|
||||
}
|
||||
},
|
||||
"keepAwake": {
|
||||
"label": {
|
||||
"enabled": "Manter acordado",
|
||||
"disabled": "Manter acordado"
|
||||
},
|
||||
"tooltip": {
|
||||
"action": "Clique para alternar o modo Manter acordado"
|
||||
}
|
||||
}
|
||||
},
|
||||
"toast": {
|
||||
"night-light": {
|
||||
"enabled": "Ativada",
|
||||
@@ -1406,6 +1552,9 @@
|
||||
"enabled": "Ativado",
|
||||
"disabled": "Desativado"
|
||||
},
|
||||
"kofi": {
|
||||
"opened": "Página do Ko-fi aberta no seu navegador"
|
||||
},
|
||||
"do-not-disturb": {
|
||||
"enabled": "'Não perturbe' ativado",
|
||||
"disabled": "'Não perturbe' desativado",
|
||||
|
||||
+203
-54
@@ -13,32 +13,6 @@
|
||||
},
|
||||
"select-avatar": "选择头像图片"
|
||||
},
|
||||
"ui": {
|
||||
"section": {
|
||||
"label": "用户界面",
|
||||
"description": "自定义界面的外观、风格和行为。"
|
||||
},
|
||||
"tooltips": {
|
||||
"label": "显示工具提示",
|
||||
"description": "在整个界面中启用或禁用工具提示。"
|
||||
},
|
||||
"dim-desktop": {
|
||||
"label": "调暗桌面",
|
||||
"description": "当面板或菜单打开时调暗桌面。"
|
||||
},
|
||||
"border-radius": {
|
||||
"label": "边框圆角",
|
||||
"description": "控制窗口、按钮及其他元素的边角圆度。"
|
||||
},
|
||||
"animation-speed": {
|
||||
"label": "动画速度",
|
||||
"description": "调整全局动画速度。"
|
||||
},
|
||||
"animation-disable": {
|
||||
"label": "关闭动画",
|
||||
"description": "禁用所有动画效果,以获得更快速、更灵敏的体验。"
|
||||
}
|
||||
},
|
||||
"screen-corners": {
|
||||
"section": {
|
||||
"label": "屏幕边角",
|
||||
@@ -54,7 +28,8 @@
|
||||
},
|
||||
"radius": {
|
||||
"label": "屏幕边角半径",
|
||||
"description": "调整屏幕圆角的弧度。"
|
||||
"description": "调整屏幕圆角的弧度。",
|
||||
"reset": "重置屏幕圆角半径"
|
||||
}
|
||||
},
|
||||
"fonts": {
|
||||
@@ -83,16 +58,6 @@
|
||||
"description": "增大或减小等宽文本的尺寸"
|
||||
}
|
||||
}
|
||||
},
|
||||
"control-center": {
|
||||
"section": {
|
||||
"label": "控制中心",
|
||||
"description": "配置控制中心面板的定位和行为。"
|
||||
},
|
||||
"position": {
|
||||
"label": "位置",
|
||||
"description": "选择控制中心面板打开时出现的位置。"
|
||||
}
|
||||
}
|
||||
},
|
||||
"audio": {
|
||||
@@ -179,11 +144,9 @@
|
||||
"monitors": {
|
||||
"section": {
|
||||
"label": "显示器设置",
|
||||
"description": "调整每个显示器的缩放比例和亮度。"
|
||||
"description": "调整每个显示器的亮度设置。"
|
||||
},
|
||||
"scale": "缩放比例",
|
||||
"brightness": "亮度",
|
||||
"reset-scaling": "重置缩放",
|
||||
"brightness-step": {
|
||||
"label": "亮度步长",
|
||||
"description": "调整亮度变化的步长(滚轮和键盘快捷键)。"
|
||||
@@ -259,7 +222,7 @@
|
||||
"widgets": {
|
||||
"section": {
|
||||
"label": "小部件定位",
|
||||
"description": "拖放小部件以在每个部分内重新排序,或使用添加/删除按钮管理小部件。"
|
||||
"description": "拖放小部件以重新排序。徽章表示使用情况:[L]左、[C]中、[R]右。"
|
||||
}
|
||||
},
|
||||
"monitors": {
|
||||
@@ -267,6 +230,13 @@
|
||||
"label": "显示器显示",
|
||||
"description": "在特定显示器上显示状态栏。如果未选择,则默认为全部。"
|
||||
}
|
||||
},
|
||||
"tray": {
|
||||
"blacklist": {
|
||||
"label": "黑名单",
|
||||
"description": "添加托盘排除规则,支持通配符 (*)。",
|
||||
"placeholder": "例如:nm-applet, Fcitx*"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dock": {
|
||||
@@ -290,6 +260,10 @@
|
||||
"floating-distance": {
|
||||
"label": "Dock 浮动距离",
|
||||
"description": "调整距离屏幕边缘的浮动距离。"
|
||||
},
|
||||
"colorize-icons": {
|
||||
"label": "着色图标",
|
||||
"description": "将主题颜色应用到 Dock 应用图标(仅限非聚焦应用)。"
|
||||
}
|
||||
},
|
||||
"monitors": {
|
||||
@@ -402,6 +376,10 @@
|
||||
"label": "启用屏幕显示",
|
||||
"description": "实时显示音量与亮度变化。"
|
||||
},
|
||||
"always-on-top": {
|
||||
"label": "始终置顶",
|
||||
"description": "在全屏窗口和其他图层之上显示OSD。"
|
||||
},
|
||||
"location": {
|
||||
"label": "位置",
|
||||
"description": "屏幕显示出现的位置。"
|
||||
@@ -529,6 +507,9 @@
|
||||
},
|
||||
"qt": {
|
||||
"description": "写入 {filepath}"
|
||||
},
|
||||
"kcolorscheme": {
|
||||
"description": "写入 {filepath}"
|
||||
}
|
||||
},
|
||||
"terminal": {
|
||||
@@ -554,9 +535,9 @@
|
||||
"description": "写入 {filepath} 并重新加载",
|
||||
"description-missing": "需要安装 {app}"
|
||||
},
|
||||
"vesktop": {
|
||||
"description": "写入 {filepath}",
|
||||
"description-missing": "需要安装 {app}"
|
||||
"discord": {
|
||||
"description": "为 {client} 写入 {filepath}",
|
||||
"description-missing": "未检测到 Discord 客户端。请安装 vesktop、webcord、armcord、equibop、lightcord 或 dorion。"
|
||||
},
|
||||
"pywalfox": {
|
||||
"description": "写入 {filepath} 并运行 pywalfox update",
|
||||
@@ -703,7 +684,8 @@
|
||||
"description": "向我们 {count} 位<b>超棒的</b>贡献者致敬!",
|
||||
"description_plural": "向我们 {count} 位<b>超棒的</b>贡献者致敬!"
|
||||
}
|
||||
}
|
||||
},
|
||||
"support": "支持我们"
|
||||
},
|
||||
"hooks": {
|
||||
"title": "钩子",
|
||||
@@ -737,6 +719,69 @@
|
||||
"description": "• 壁纸钩子: $1 = 壁纸路径, $2 = 屏幕名称\n• 主题切换钩子: $1 = true/false (深色模式状态)"
|
||||
}
|
||||
}
|
||||
},
|
||||
"control-center": {
|
||||
"position": {
|
||||
"description": "选择打开控制中心时面板出现的位置。",
|
||||
"label": "位置"
|
||||
},
|
||||
"section": {
|
||||
"description": "配置控制中心面板的位置和行为。",
|
||||
"label": "外观"
|
||||
},
|
||||
"title": "控制中心",
|
||||
"cards": {
|
||||
"section": {
|
||||
"description": "自定义在控制中心显示的控制项及其顺序。",
|
||||
"label": "卡片"
|
||||
}
|
||||
},
|
||||
"shortcuts": {
|
||||
"section": {
|
||||
"description": "配置和管理快捷方式小部件。",
|
||||
"label": "快捷方式小部件"
|
||||
},
|
||||
"sectionLeft": "左",
|
||||
"sectionRight": "右"
|
||||
}
|
||||
},
|
||||
"user-interface": {
|
||||
"animation-disable": {
|
||||
"description": "禁用所有动画以获得更快、更流畅的体验。",
|
||||
"label": "禁用 UI 动画"
|
||||
},
|
||||
"animation-speed": {
|
||||
"description": "调整全局动画速度。",
|
||||
"label": "动画速度",
|
||||
"reset": "重置动画速度"
|
||||
},
|
||||
"border-radius": {
|
||||
"description": "控制窗口、按钮和其他元素的圆角程度。",
|
||||
"label": "边框半径",
|
||||
"reset": "重置边框半径"
|
||||
},
|
||||
"compact-lockscreen": {
|
||||
"description": "仅显示登录输入和系统控制,隐藏天气和媒体小部件。",
|
||||
"label": "紧凑型锁屏"
|
||||
},
|
||||
"dim-desktop": {
|
||||
"description": "当面板或菜单打开时,桌面变暗。",
|
||||
"label": "昏暗的桌面"
|
||||
},
|
||||
"scaling": {
|
||||
"description": "更改通用用户界面大小,不包括栏。",
|
||||
"label": "界面缩放",
|
||||
"reset-scaling": "重置界面缩放"
|
||||
},
|
||||
"section": {
|
||||
"description": "自定义界面的外观、感觉和行为。",
|
||||
"label": "外观"
|
||||
},
|
||||
"title": "用户界面",
|
||||
"tooltips": {
|
||||
"description": "启用或禁用整个界面的工具提示。",
|
||||
"label": "显示工具提示"
|
||||
}
|
||||
}
|
||||
},
|
||||
"widgets": {
|
||||
@@ -745,7 +790,11 @@
|
||||
},
|
||||
"file-picker": {
|
||||
"select-folder": "选择文件夹",
|
||||
"select-file": "选择文件"
|
||||
"select-file": "选择文件",
|
||||
"cancel": "取消",
|
||||
"search-placeholder": "搜索文件和文件夹...",
|
||||
"select-current": "选择当前",
|
||||
"title": "文件选择器"
|
||||
},
|
||||
"datetime-tokens": {
|
||||
"common": {
|
||||
@@ -836,9 +885,9 @@
|
||||
"search-placeholder": "搜索小部件..."
|
||||
},
|
||||
"active-window": {
|
||||
"auto-hide": {
|
||||
"label": "自动隐藏",
|
||||
"description": "当没有活动窗口时自动隐藏小部件。"
|
||||
"hide-mode": {
|
||||
"label": "隐藏模式",
|
||||
"description": "控制当没有活动窗口时小部件的行为。"
|
||||
},
|
||||
"show-app-icon": {
|
||||
"label": "显示应用图标",
|
||||
@@ -851,6 +900,10 @@
|
||||
"width": {
|
||||
"description": "控制小部件的水平尺寸。",
|
||||
"label": "小部件宽度"
|
||||
},
|
||||
"colorize-icons": {
|
||||
"label": "着色图标",
|
||||
"description": "将主题颜色应用到活动窗口图标。"
|
||||
}
|
||||
},
|
||||
"system-monitor": {
|
||||
@@ -981,9 +1034,9 @@
|
||||
}
|
||||
},
|
||||
"media-mini": {
|
||||
"auto-hide": {
|
||||
"label": "自动隐藏",
|
||||
"description": "当没有媒体播放时自动隐藏小部件。"
|
||||
"hide-mode": {
|
||||
"label": "隐藏模式",
|
||||
"description": "控制当没有媒体播放时小部件的行为。"
|
||||
},
|
||||
"show-album-art": {
|
||||
"label": "显示专辑封面",
|
||||
@@ -1044,6 +1097,16 @@
|
||||
"only-same-output": {
|
||||
"label": "仅显示同屏幕",
|
||||
"description": "仅显示任务栏所在屏幕上的应用程序"
|
||||
},
|
||||
"colorize-icons": {
|
||||
"label": "着色图标",
|
||||
"description": "将主题颜色应用到任务栏图标。"
|
||||
}
|
||||
},
|
||||
"tray": {
|
||||
"colorize-icons": {
|
||||
"label": "着色图标",
|
||||
"description": "将主题颜色应用到系统托盘图标。"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1213,7 +1276,8 @@
|
||||
"density": {
|
||||
"compact": "紧凑",
|
||||
"default": "默认",
|
||||
"comfortable": "舒适"
|
||||
"comfortable": "舒适",
|
||||
"mini": "迷你"
|
||||
}
|
||||
},
|
||||
"launcher": {
|
||||
@@ -1238,6 +1302,11 @@
|
||||
"bottom_right": "右下角",
|
||||
"bottom_center": "底部居中",
|
||||
"top_center": "顶部居中"
|
||||
},
|
||||
"quickSettingsStyle": {
|
||||
"modern": "现代",
|
||||
"classic": "经典",
|
||||
"compact": "紧凑"
|
||||
}
|
||||
},
|
||||
"osd": {
|
||||
@@ -1297,6 +1366,11 @@
|
||||
"microphone-input": "麦克风输入",
|
||||
"both": "系统输出 + 麦克风输入"
|
||||
}
|
||||
},
|
||||
"hide-modes": {
|
||||
"hidden": "当为空时隐藏",
|
||||
"transparent": "空时透明",
|
||||
"visible": "始终可见"
|
||||
}
|
||||
},
|
||||
"session-menu": {
|
||||
@@ -1336,7 +1410,7 @@
|
||||
"system": {
|
||||
"uptime": "系统运行时间:{uptime}",
|
||||
"welcome-back": "欢迎回来,",
|
||||
"monitor-description": "{model} ({width}x{height})",
|
||||
"monitor-description": "{model} ({width}x{height} @ {scale}x)",
|
||||
"scaling-percentage": "{percentage}%",
|
||||
"location-display": "{name} ({coordinates})",
|
||||
"signal-strength": "{signal}%",
|
||||
@@ -1359,6 +1433,78 @@
|
||||
"restart": "重启",
|
||||
"suspend": "挂起"
|
||||
},
|
||||
"quickSettings": {
|
||||
"notifications": {
|
||||
"label": {
|
||||
"enabled": "通知",
|
||||
"disabled": "勿扰模式"
|
||||
},
|
||||
"tooltip": {
|
||||
"action": "左键:打开通知历史\n右键:切换勿扰模式"
|
||||
}
|
||||
},
|
||||
"screenRecorder": {
|
||||
"label": {
|
||||
"recording": "停止",
|
||||
"stopped": "录制"
|
||||
},
|
||||
"tooltip": {
|
||||
"action": "点击开始/停止屏幕录制"
|
||||
}
|
||||
},
|
||||
"powerProfile": {
|
||||
"label": {
|
||||
"unavailable": "电源模式"
|
||||
},
|
||||
"tooltip": {
|
||||
"action": "点击切换电源模式"
|
||||
}
|
||||
},
|
||||
"wifi": {
|
||||
"label": {
|
||||
"ethernet": "以太网",
|
||||
"wifi": "Wi-Fi",
|
||||
"disconnected": "Wi-Fi 已断开"
|
||||
},
|
||||
"tooltip": {
|
||||
"action": "点击管理 Wi-Fi 连接"
|
||||
}
|
||||
},
|
||||
"bluetooth": {
|
||||
"label": {
|
||||
"enabled": "蓝牙",
|
||||
"disabled": "蓝牙"
|
||||
},
|
||||
"tooltip": {
|
||||
"action": "点击管理蓝牙设备"
|
||||
}
|
||||
},
|
||||
"nightLight": {
|
||||
"label": {
|
||||
"enabled": "夜间模式",
|
||||
"forced": "夜间模式",
|
||||
"disabled": "夜间模式"
|
||||
},
|
||||
"tooltip": {
|
||||
"action": "点击切换夜间模式\n右键:打开设置"
|
||||
}
|
||||
},
|
||||
"wallpaperSelector": {
|
||||
"label": "壁纸",
|
||||
"tooltip": {
|
||||
"action": "左键:打开壁纸选择器\n右键:设置随机壁纸"
|
||||
}
|
||||
},
|
||||
"keepAwake": {
|
||||
"label": {
|
||||
"enabled": "保持唤醒",
|
||||
"disabled": "保持唤醒"
|
||||
},
|
||||
"tooltip": {
|
||||
"action": "点击切换保持唤醒模式"
|
||||
}
|
||||
}
|
||||
},
|
||||
"toast": {
|
||||
"night-light": {
|
||||
"enabled": "已启用",
|
||||
@@ -1406,6 +1552,9 @@
|
||||
"enabled": "已启用",
|
||||
"disabled": "已禁用"
|
||||
},
|
||||
"kofi": {
|
||||
"opened": "Ko-fi页面已在您的浏览器中打开"
|
||||
},
|
||||
"do-not-disturb": {
|
||||
"enabled": "'勿扰模式'已启用",
|
||||
"disabled": "'勿扰模式'已禁用",
|
||||
|
||||
@@ -36,12 +36,6 @@
|
||||
{
|
||||
"id": "NotificationHistory"
|
||||
},
|
||||
{
|
||||
"id": "WiFi"
|
||||
},
|
||||
{
|
||||
"id": "Bluetooth"
|
||||
},
|
||||
{
|
||||
"id": "Battery"
|
||||
},
|
||||
@@ -65,10 +59,12 @@
|
||||
"dimDesktop": true,
|
||||
"showScreenCorners": false,
|
||||
"forceBlackScreenCorners": false,
|
||||
"scaleRatio": 1,
|
||||
"radiusRatio": 1,
|
||||
"screenRadiusRatio": 1,
|
||||
"animationSpeed": 1,
|
||||
"animationDisabled": false
|
||||
"animationDisabled": false,
|
||||
"compactLockScreen": false
|
||||
},
|
||||
"location": {
|
||||
"name": "Tokyo",
|
||||
@@ -112,7 +108,59 @@
|
||||
"terminalCommand": "xterm -e"
|
||||
},
|
||||
"controlCenter": {
|
||||
"position": "close_to_bar_button"
|
||||
"position": "close_to_bar_button",
|
||||
"shortcuts": {
|
||||
"left": [
|
||||
{
|
||||
"id": "WiFi"
|
||||
},
|
||||
{
|
||||
"id": "Bluetooth"
|
||||
},
|
||||
{
|
||||
"id": "ScreenRecorder"
|
||||
},
|
||||
{
|
||||
"id": "WallpaperSelector"
|
||||
}
|
||||
],
|
||||
"right": [
|
||||
{
|
||||
"id": "Notifications"
|
||||
},
|
||||
{
|
||||
"id": "PowerProfile"
|
||||
},
|
||||
{
|
||||
"id": "KeepAwake"
|
||||
},
|
||||
{
|
||||
"id": "NightLight"
|
||||
}
|
||||
]
|
||||
},
|
||||
"cards": [
|
||||
{
|
||||
"enabled": true,
|
||||
"id": "profile-card"
|
||||
},
|
||||
{
|
||||
"enabled": true,
|
||||
"id": "shortcuts-card"
|
||||
},
|
||||
{
|
||||
"enabled": true,
|
||||
"id": "audio-card"
|
||||
},
|
||||
{
|
||||
"enabled": true,
|
||||
"id": "weather-card"
|
||||
},
|
||||
{
|
||||
"enabled": true,
|
||||
"id": "media-sysmon-card"
|
||||
}
|
||||
]
|
||||
},
|
||||
"dock": {
|
||||
"displayMode": "always_visible",
|
||||
@@ -120,7 +168,8 @@
|
||||
"floatingRatio": 1,
|
||||
"onlySameOutput": true,
|
||||
"monitors": [],
|
||||
"pinnedApps": []
|
||||
"pinnedApps": [],
|
||||
"colorizeIcons": false
|
||||
},
|
||||
"network": {
|
||||
"wifiEnabled": true
|
||||
@@ -140,7 +189,8 @@
|
||||
"enabled": true,
|
||||
"location": "top_right",
|
||||
"monitors": [],
|
||||
"autoHideMs": 2000
|
||||
"autoHideMs": 2000,
|
||||
"alwaysOnTop": false
|
||||
},
|
||||
"audio": {
|
||||
"volumeStep": 5,
|
||||
@@ -155,7 +205,6 @@
|
||||
"fontFixed": "DejaVu Sans Mono",
|
||||
"fontDefaultScale": 1,
|
||||
"fontFixedScale": 1,
|
||||
"monitorsScaling": [],
|
||||
"idleInhibitorEnabled": false,
|
||||
"tooltipsEnabled": true
|
||||
},
|
||||
@@ -172,11 +221,18 @@
|
||||
"templates": {
|
||||
"gtk": false,
|
||||
"qt": false,
|
||||
"kcolorscheme": false,
|
||||
"kitty": false,
|
||||
"ghostty": false,
|
||||
"foot": false,
|
||||
"fuzzel": false,
|
||||
"vesktop": false,
|
||||
"discord": false,
|
||||
"discord_vesktop": false,
|
||||
"discord_webcord": false,
|
||||
"discord_armcord": false,
|
||||
"discord_equibop": false,
|
||||
"discord_lightcord": false,
|
||||
"discord_dorion": false,
|
||||
"pywalfox": false,
|
||||
"enableUserTemplates": false
|
||||
},
|
||||
|
||||
@@ -123,13 +123,13 @@ EOF
|
||||
# Make API call to Gemini
|
||||
local api_url="https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=${api_key}"
|
||||
|
||||
print_color $BLUE " API URL: $api_url" >&2
|
||||
# print_color $BLUE " API URL: $api_url" >&2
|
||||
|
||||
local response=$(curl -s -X POST "$api_url" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "$request_body" 2>/dev/null)
|
||||
|
||||
print_color $BLUE " API Response: $response" >&2
|
||||
# print_color $BLUE " API Response: $response" >&2
|
||||
|
||||
# Extract the translation from response - try multiple parsing approaches
|
||||
local translation=$(echo "$response" | jq -r '.candidates[0].content.parts[0].text // .text // empty' 2>/dev/null | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
|
||||
@@ -181,6 +181,40 @@ inject_translation() {
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to remove a key from JSON file using jq
|
||||
remove_json_key() {
|
||||
local json_file=$1
|
||||
local key_path=$2
|
||||
|
||||
# Split key path into array
|
||||
local -a path_parts
|
||||
IFS='.' read -ra path_parts <<< "$key_path"
|
||||
|
||||
# Build jq path array
|
||||
local jq_path="["
|
||||
for i in "${!path_parts[@]}"; do
|
||||
if [[ $i -gt 0 ]]; then
|
||||
jq_path+=","
|
||||
fi
|
||||
jq_path+="\"${path_parts[$i]}\""
|
||||
done
|
||||
jq_path+="]"
|
||||
|
||||
# Create a temporary file
|
||||
local temp_file=$(mktemp)
|
||||
|
||||
# Use jq to delete the path
|
||||
jq --argjson path "$jq_path" 'delpaths([$path])' "$json_file" > "$temp_file"
|
||||
|
||||
if [[ $? -eq 0 ]]; then
|
||||
mv "$temp_file" "$json_file"
|
||||
return 0
|
||||
else
|
||||
rm -f "$temp_file"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to extract all keys from a JSON file recursively
|
||||
extract_keys() {
|
||||
local json_file=$1
|
||||
@@ -207,6 +241,78 @@ extract_keys() {
|
||||
' "$json_file" 2>/dev/null | sort
|
||||
}
|
||||
|
||||
# Function to extract empty keys from a JSON file recursively
|
||||
extract_empty_keys() {
|
||||
local json_file=$1
|
||||
|
||||
if [[ ! -f "$json_file" ]]; then
|
||||
echo "Error: File $json_file not found" >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Extract all keys with empty string or null values recursively using jq
|
||||
jq -r '
|
||||
def empty_keys_recursive:
|
||||
if type == "object" then
|
||||
keys[] as $k |
|
||||
if (.[$k] | type) == "object" then
|
||||
($k + "." + (.[$k] | empty_keys_recursive))
|
||||
elif (.[$k] == "" or .[$k] == null) then
|
||||
$k
|
||||
else
|
||||
empty
|
||||
end
|
||||
else
|
||||
empty
|
||||
end;
|
||||
empty_keys_recursive
|
||||
' "$json_file" 2>/dev/null | sort
|
||||
}
|
||||
|
||||
# Function to remove empty objects recursively from JSON file
|
||||
remove_empty_objects() {
|
||||
local json_file=$1
|
||||
|
||||
# Create a temporary file
|
||||
local temp_file=$(mktemp)
|
||||
|
||||
# Use jq to recursively remove empty objects
|
||||
# This function walks the entire JSON tree and removes any object that contains no leaf values
|
||||
jq '
|
||||
def remove_empty:
|
||||
if type == "object" then
|
||||
to_entries |
|
||||
map(
|
||||
.value |= remove_empty
|
||||
) |
|
||||
map(
|
||||
select(
|
||||
.value != {} and
|
||||
.value != [] and
|
||||
.value != null and
|
||||
.value != ""
|
||||
)
|
||||
) |
|
||||
from_entries |
|
||||
if length == 0 then empty else . end
|
||||
elif type == "array" then
|
||||
map(remove_empty) |
|
||||
map(select(. != null and . != {} and . != [] and . != ""))
|
||||
else
|
||||
.
|
||||
end;
|
||||
remove_empty
|
||||
' "$json_file" > "$temp_file" 2>/dev/null
|
||||
|
||||
if [[ $? -eq 0 ]]; then
|
||||
mv "$temp_file" "$json_file"
|
||||
return 0
|
||||
else
|
||||
rm -f "$temp_file"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to get language files
|
||||
get_language_files() {
|
||||
find "$FOLDER_PATH" -maxdepth 1 -name "*.json" -type f | sort
|
||||
@@ -223,15 +329,20 @@ generate_header() {
|
||||
echo "Reference file: $REFERENCE_FILE"
|
||||
echo "Folder: $(realpath "$FOLDER_PATH")"
|
||||
if $TRANSLATE_MODE; then
|
||||
echo "Mode: TRANSLATION ENABLED"
|
||||
echo "Mode: TRANSLATION ENABLED (translates missing keys, removes extra/empty keys and empty objects)"
|
||||
fi
|
||||
echo ""
|
||||
echo "Notes:"
|
||||
echo "- Keys are compared recursively through all nested JSON objects"
|
||||
echo "- Missing keys indicate incomplete translations"
|
||||
echo "- Extra keys might indicate deprecated keys or translation-specific additions"
|
||||
echo "- Empty keys are keys with empty string (\"\") or null values"
|
||||
echo "- Empty objects are nested objects containing no actual values (only other empty objects)"
|
||||
echo "- Translation completion percentage is calculated based on English reference"
|
||||
echo "- Results are sorted by descending line numbers for easier editing"
|
||||
if $TRANSLATE_MODE; then
|
||||
echo "- In translation mode, extra keys, empty keys, and empty objects are automatically removed"
|
||||
fi
|
||||
echo ""
|
||||
echo "This report compares all language JSON files against the English reference file"
|
||||
echo "and identifies missing keys and extra keys in each language."
|
||||
@@ -427,11 +538,92 @@ compare_language() {
|
||||
done
|
||||
rm -f "$temp_extra"
|
||||
echo ""
|
||||
|
||||
# Remove extra keys if in translate mode
|
||||
if $TRANSLATE_MODE; then
|
||||
print_color $BLUE "Removing extra keys from $lang_name..." >&2
|
||||
local removed_count=0
|
||||
local failed_removal_count=0
|
||||
|
||||
while IFS= read -r key; do
|
||||
if [[ -n "$key" ]]; then
|
||||
print_color $YELLOW " Removing: $key" >&2
|
||||
|
||||
if remove_json_key "$lang_file" "$key"; then
|
||||
print_color $GREEN " ✓ Removed: $key" >&2
|
||||
removed_count=$((removed_count + 1))
|
||||
else
|
||||
print_color $RED " ✗ Failed to remove: $key" >&2
|
||||
failed_removal_count=$((failed_removal_count + 1))
|
||||
fi
|
||||
fi
|
||||
done <<< "$extra_keys"
|
||||
|
||||
echo ""
|
||||
print_color $GREEN "Removal complete: $removed_count removed, $failed_removal_count failed" >&2
|
||||
echo ""
|
||||
fi
|
||||
else
|
||||
echo "✅ No extra keys in $lang_name"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
# Handle empty keys in translate mode
|
||||
if $TRANSLATE_MODE; then
|
||||
local empty_keys=$(extract_empty_keys "$lang_file")
|
||||
local empty_count=$(count_non_empty_lines "$empty_keys")
|
||||
|
||||
if [[ $empty_count -gt 0 && -n "$empty_keys" ]]; then
|
||||
echo "EMPTY KEYS IN $lang_name:"
|
||||
|
||||
# Display empty keys
|
||||
local counter=1
|
||||
while IFS= read -r key; do
|
||||
if [[ -n "$key" ]]; then
|
||||
local lang_line=$(find_key_line_number "$lang_file" "$key")
|
||||
printf " %3d. %s (%s:%s)\n" "$counter" "$key" "$(basename "$lang_file")" "$lang_line"
|
||||
counter=$((counter + 1))
|
||||
fi
|
||||
done <<< "$empty_keys"
|
||||
echo ""
|
||||
|
||||
print_color $BLUE "Removing empty keys from $lang_name..." >&2
|
||||
local removed_empty_count=0
|
||||
local failed_empty_removal_count=0
|
||||
|
||||
while IFS= read -r key; do
|
||||
if [[ -n "$key" ]]; then
|
||||
print_color $YELLOW " Removing empty key: $key" >&2
|
||||
|
||||
if remove_json_key "$lang_file" "$key"; then
|
||||
print_color $GREEN " ✓ Removed: $key" >&2
|
||||
removed_empty_count=$((removed_empty_count + 1))
|
||||
else
|
||||
print_color $RED " ✗ Failed to remove: $key" >&2
|
||||
failed_empty_removal_count=$((failed_empty_removal_count + 1))
|
||||
fi
|
||||
fi
|
||||
done <<< "$empty_keys"
|
||||
|
||||
echo ""
|
||||
print_color $GREEN "Empty key removal complete: $removed_empty_count removed, $failed_empty_removal_count failed" >&2
|
||||
echo ""
|
||||
else
|
||||
echo "✅ No empty keys in $lang_name"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
# Remove empty objects (nested objects with no actual values)
|
||||
print_color $BLUE "Cleaning up empty objects in $lang_name..." >&2
|
||||
if remove_empty_objects "$lang_file"; then
|
||||
print_color $GREEN "✓ Successfully removed all empty objects" >&2
|
||||
echo ""
|
||||
else
|
||||
print_color $RED "✗ Failed to clean up empty objects" >&2
|
||||
echo ""
|
||||
fi
|
||||
fi
|
||||
|
||||
# Clean up
|
||||
rm -f "$lang_keys_file"
|
||||
}
|
||||
@@ -545,7 +737,7 @@ main() {
|
||||
echo "Target language: $target_language"
|
||||
fi
|
||||
if $TRANSLATE_MODE; then
|
||||
echo "Translation mode: ENABLED"
|
||||
echo "Translation mode: ENABLED (translated missing keys, removed extra keys, removed empty keys and objects)"
|
||||
fi
|
||||
echo "Report generated: $(date '+%Y-%m-%d %H:%M:%S')"
|
||||
echo ""
|
||||
@@ -568,7 +760,9 @@ show_usage() {
|
||||
echo "This script compares JSON language files in '$FOLDER_PATH' against the English reference." >&2
|
||||
echo "" >&2
|
||||
echo "Arguments:" >&2
|
||||
echo " --translate Enable automatic translation of missing keys using Gemini API" >&2
|
||||
echo " --translate Enable automatic translation of missing keys, removal of extra keys," >&2
|
||||
echo " removal of empty keys (empty strings or null values), and removal of" >&2
|
||||
echo " empty objects (nested objects containing no actual values)" >&2
|
||||
echo " --list-models List all available Gemini models and exit" >&2
|
||||
echo " language_code Optional. Compare only the specified language (e.g., 'fr', 'es', 'de')" >&2
|
||||
echo " If not provided, all language files will be compared" >&2
|
||||
@@ -581,8 +775,8 @@ show_usage() {
|
||||
echo " $0 # Compare all languages" >&2
|
||||
echo " $0 fr # Compare only French (fr.json)" >&2
|
||||
echo " $0 --list-models # List available Gemini models" >&2
|
||||
echo " $0 --translate # Compare all and translate missing keys" >&2
|
||||
echo " $0 --translate fr # Translate missing keys for French only" >&2
|
||||
echo " $0 --translate # Compare all, translate missing, remove extra/empty keys and objects" >&2
|
||||
echo " $0 --translate fr # Translate and clean French only" >&2
|
||||
echo "" >&2
|
||||
echo "Requirements:" >&2
|
||||
echo " - jq must be installed" >&2
|
||||
@@ -595,6 +789,7 @@ show_usage() {
|
||||
echo " - Comparison report is printed to stdout" >&2
|
||||
echo " - Progress messages are printed to stderr" >&2
|
||||
echo " - Results are sorted by descending line numbers for easier editing" >&2
|
||||
echo " - In translate mode, extra keys, empty keys, and empty objects are removed" >&2
|
||||
}
|
||||
|
||||
# Handle command line arguments
|
||||
+14
-4
@@ -54,6 +54,9 @@ Singleton {
|
||||
var data = JSON.parse(text())
|
||||
root.translations = data
|
||||
Logger.log("I18n", `Loaded translations for "${root.langCode}"`)
|
||||
if (debug) {
|
||||
Logger.log("I18n", `Available root keys: ${Object.keys(data).join(", ")}`)
|
||||
}
|
||||
|
||||
root.isLoaded = true
|
||||
root.translationsLoaded()
|
||||
@@ -279,9 +282,9 @@ Singleton {
|
||||
interpolations = {}
|
||||
|
||||
if (!isLoaded) {
|
||||
// if (debug) {
|
||||
// Logger.warn("I18n", "Translations not loaded yet")
|
||||
// }
|
||||
if (debug) {
|
||||
Logger.warn("I18n", "Translations not loaded yet")
|
||||
}
|
||||
return key
|
||||
}
|
||||
|
||||
@@ -291,12 +294,19 @@ Singleton {
|
||||
// Look-up translation in the active language
|
||||
var value = translations
|
||||
var notFound = false
|
||||
if (debug) {
|
||||
Logger.log("I18n", `Looking up key: "${key}"`)
|
||||
}
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
if (value && typeof value === "object" && keys[i] in value) {
|
||||
value = value[keys[i]]
|
||||
if (debug) {
|
||||
Logger.log("I18n", `Found key part "${keys[i]}"`)
|
||||
}
|
||||
} else {
|
||||
if (debug) {
|
||||
Logger.warn("I18n", `Translation key "${key}" not found`)
|
||||
Logger.warn("I18n", `Translation key "${key}" not found at part "${keys[i]}"`)
|
||||
Logger.warn("I18n", `Available keys: ${Object.keys(value || {}).join(", ")}`)
|
||||
}
|
||||
notFound = true
|
||||
break
|
||||
|
||||
+79
-11
@@ -33,6 +33,7 @@ Singleton {
|
||||
|
||||
// Signal emitted when settings are loaded after startupcale changes
|
||||
signal settingsLoaded
|
||||
signal settingsSaved
|
||||
|
||||
// -----------------------------------------------------
|
||||
// -----------------------------------------------------
|
||||
@@ -71,11 +72,7 @@ Singleton {
|
||||
running: false
|
||||
interval: 1000
|
||||
onTriggered: {
|
||||
settingsFileView.writeAdapter()
|
||||
// Write to fallback location if set
|
||||
if (Quickshell.env("NOCTALIA_SETTINGS_FALLBACK")) {
|
||||
settingsFallbackFileView.writeAdapter()
|
||||
}
|
||||
root.saveImmediate()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -162,10 +159,6 @@ Singleton {
|
||||
"id": "Tray"
|
||||
}, {
|
||||
"id": "NotificationHistory"
|
||||
}, {
|
||||
"id": "WiFi"
|
||||
}, {
|
||||
"id": "Bluetooth"
|
||||
}, {
|
||||
"id": "Battery"
|
||||
}, {
|
||||
@@ -186,10 +179,12 @@ Singleton {
|
||||
property bool dimDesktop: true
|
||||
property bool showScreenCorners: false
|
||||
property bool forceBlackScreenCorners: false
|
||||
property real scaleRatio: 1.0
|
||||
property real radiusRatio: 1.0
|
||||
property real screenRadiusRatio: 1.0
|
||||
property real animationSpeed: 1.0
|
||||
property bool animationDisabled: false
|
||||
property bool compactLockScreen: false
|
||||
}
|
||||
|
||||
// location
|
||||
@@ -246,6 +241,43 @@ Singleton {
|
||||
property JsonObject controlCenter: JsonObject {
|
||||
// Position: close_to_bar_button, center, top_left, top_right, bottom_left, bottom_right, bottom_center, top_center
|
||||
property string position: "close_to_bar_button"
|
||||
property JsonObject shortcuts
|
||||
shortcuts: JsonObject {
|
||||
property list<var> left: [{
|
||||
"id": "WiFi"
|
||||
}, {
|
||||
"id": "Bluetooth"
|
||||
}, {
|
||||
"id": "ScreenRecorder"
|
||||
}, {
|
||||
"id": "WallpaperSelector"
|
||||
}]
|
||||
property list<var> right: [{
|
||||
"id": "Notifications"
|
||||
}, {
|
||||
"id": "PowerProfile"
|
||||
}, {
|
||||
"id": "KeepAwake"
|
||||
}, {
|
||||
"id": "NightLight"
|
||||
}]
|
||||
}
|
||||
property list<var> cards: [{
|
||||
"id": "profile-card",
|
||||
"enabled": true
|
||||
}, {
|
||||
"id": "shortcuts-card",
|
||||
"enabled": true
|
||||
}, {
|
||||
"id": "audio-card",
|
||||
"enabled": true
|
||||
}, {
|
||||
"id": "weather-card",
|
||||
"enabled": true
|
||||
}, {
|
||||
"id": "media-sysmon-card",
|
||||
"enabled": true
|
||||
}]
|
||||
}
|
||||
|
||||
// dock
|
||||
@@ -257,6 +289,7 @@ Singleton {
|
||||
property list<string> monitors: []
|
||||
// Desktop entry IDs pinned to the dock (e.g., "org.kde.konsole", "firefox.desktop")
|
||||
property list<string> pinnedApps: []
|
||||
property bool colorizeIcons: false
|
||||
}
|
||||
|
||||
// network
|
||||
@@ -283,6 +316,7 @@ Singleton {
|
||||
property string location: "top_right"
|
||||
property list<string> monitors: []
|
||||
property int autoHideMs: 2000
|
||||
property bool alwaysOnTop: false
|
||||
}
|
||||
|
||||
// audio
|
||||
@@ -301,7 +335,6 @@ Singleton {
|
||||
property string fontFixed: "DejaVu Sans Mono"
|
||||
property real fontDefaultScale: 1.0
|
||||
property real fontFixedScale: 1.0
|
||||
property list<var> monitorsScaling: []
|
||||
property bool idleInhibitorEnabled: false
|
||||
property bool tooltipsEnabled: true
|
||||
}
|
||||
@@ -323,11 +356,18 @@ Singleton {
|
||||
property JsonObject templates: JsonObject {
|
||||
property bool gtk: false
|
||||
property bool qt: false
|
||||
property bool kcolorscheme: false
|
||||
property bool kitty: false
|
||||
property bool ghostty: false
|
||||
property bool foot: false
|
||||
property bool fuzzel: false
|
||||
property bool vesktop: false
|
||||
property bool discord: false
|
||||
property bool discord_vesktop: false
|
||||
property bool discord_webcord: false
|
||||
property bool discord_armcord: false
|
||||
property bool discord_equibop: false
|
||||
property bool discord_lightcord: false
|
||||
property bool discord_dorion: false
|
||||
property bool pywalfox: false
|
||||
property bool enableUserTemplates: false
|
||||
}
|
||||
@@ -356,6 +396,34 @@ Singleton {
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Function to preprocess paths by expanding "~" to user's home directory
|
||||
function preprocessPath(path) {
|
||||
if (typeof path !== "string" || path === "") {
|
||||
return path
|
||||
}
|
||||
|
||||
// Expand "~" to user's home directory
|
||||
if (path.startsWith("~/")) {
|
||||
return Quickshell.env("HOME") + path.substring(1)
|
||||
} else if (path === "~") {
|
||||
return Quickshell.env("HOME")
|
||||
}
|
||||
|
||||
return path
|
||||
}
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Public function to trigger immediate settings saving
|
||||
function saveImmediate() {
|
||||
settingsFileView.writeAdapter()
|
||||
// Write to fallback location if set
|
||||
if (Quickshell.env("NOCTALIA_SETTINGS_FALLBACK")) {
|
||||
settingsFallbackFileView.writeAdapter()
|
||||
}
|
||||
root.settingsSaved() // Emit signal after saving
|
||||
}
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Generate default settings at the root of the repo
|
||||
function generateDefaultSettings() {
|
||||
|
||||
+36
-30
@@ -29,27 +29,25 @@ Singleton {
|
||||
property int fontWeightBold: 700
|
||||
|
||||
// Radii
|
||||
property int radiusXXS: 4 * Settings.data.general.radiusRatio
|
||||
property int radiusXS: 8 * Settings.data.general.radiusRatio
|
||||
property int radiusS: 12 * Settings.data.general.radiusRatio
|
||||
property int radiusM: 16 * Settings.data.general.radiusRatio
|
||||
property int radiusL: 20 * Settings.data.general.radiusRatio
|
||||
|
||||
//screen Radii
|
||||
property int screenRadius: 20 * Settings.data.general.screenRadiusRatio
|
||||
property int radiusXXS: Math.round(4 * Settings.data.general.radiusRatio)
|
||||
property int radiusXS: Math.round(8 * Settings.data.general.radiusRatio)
|
||||
property int radiusS: Math.round(12 * Settings.data.general.radiusRatio)
|
||||
property int radiusM: Math.round(16 * Settings.data.general.radiusRatio)
|
||||
property int radiusL: Math.round(20 * Settings.data.general.radiusRatio)
|
||||
property int screenRadius: Math.round(20 * Settings.data.general.screenRadiusRatio)
|
||||
|
||||
// Border
|
||||
property int borderS: 1
|
||||
property int borderM: 2
|
||||
property int borderL: 3
|
||||
property int borderS: Math.round(1 * uiScaleRatio)
|
||||
property int borderM: Math.round(2 * uiScaleRatio)
|
||||
property int borderL: Math.round(3 * uiScaleRatio)
|
||||
|
||||
// Margins (for margins and spacing)
|
||||
property int marginXXS: 2
|
||||
property int marginXS: 4
|
||||
property int marginS: 8
|
||||
property int marginM: 12
|
||||
property int marginL: 16
|
||||
property int marginXL: 24
|
||||
property int marginXXS: Math.round(2 * uiScaleRatio)
|
||||
property int marginXS: Math.round(4 * uiScaleRatio)
|
||||
property int marginS: Math.round(6 * uiScaleRatio)
|
||||
property int marginM: Math.round(9 * uiScaleRatio)
|
||||
property int marginL: Math.round(13 * uiScaleRatio)
|
||||
property int marginXL: Math.round(18 * uiScaleRatio)
|
||||
|
||||
// Opacity
|
||||
property real opacityNone: 0.0
|
||||
@@ -70,31 +68,39 @@ Singleton {
|
||||
property int tooltipDelayLong: 1200
|
||||
property int pillDelay: 500
|
||||
|
||||
// Settings widgets base size
|
||||
// Widgets base size
|
||||
property real baseWidgetSize: 33
|
||||
property real sliderWidth: 200
|
||||
|
||||
property real uiScaleRatio: Settings.data.general.scaleRatio
|
||||
|
||||
// Bar Dimensions
|
||||
property real barHeight: {
|
||||
if (Settings.data.bar.density === "compact") {
|
||||
switch (Settings.data.bar.density) {
|
||||
case "mini":
|
||||
return (Settings.data.bar.position === "left" || Settings.data.bar.position === "right") ? 22 : 20
|
||||
case "compact":
|
||||
return (Settings.data.bar.position === "left" || Settings.data.bar.position === "right") ? 27 : 25
|
||||
}
|
||||
if (Settings.data.bar.density === "default") {
|
||||
return (Settings.data.bar.position === "left" || Settings.data.bar.position === "right") ? 33 : 31
|
||||
}
|
||||
if (Settings.data.bar.density === "comfortable") {
|
||||
case "comfortable":
|
||||
return (Settings.data.bar.position === "left" || Settings.data.bar.position === "right") ? 39 : 37
|
||||
default:
|
||||
|
||||
case "default":
|
||||
return (Settings.data.bar.position === "left" || Settings.data.bar.position === "right") ? 33 : 31
|
||||
}
|
||||
}
|
||||
property real capsuleHeight: {
|
||||
if (Settings.data.bar.density === "compact") {
|
||||
switch (Settings.data.bar.density) {
|
||||
case "mini":
|
||||
return barHeight * 1.0
|
||||
case "compact":
|
||||
return barHeight * 0.85
|
||||
}
|
||||
if (Settings.data.bar.density === "default") {
|
||||
return barHeight * 0.82
|
||||
}
|
||||
if (Settings.data.bar.density === "comfortable") {
|
||||
case "comfortable":
|
||||
return barHeight * 0.73
|
||||
default:
|
||||
|
||||
case "default":
|
||||
return barHeight * 0.82
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,7 +101,9 @@ Singleton {
|
||||
"brightness-low": "brightness-down-filled",
|
||||
"brightness-high": "brightness-up-filled",
|
||||
"settings-general": "adjustments-horizontal",
|
||||
"settings-bar": "capsule-horizontal",
|
||||
"settings-bar": "crop-16-9",
|
||||
"settings-user-interface": "layout-board",
|
||||
"settings-control-center": "adjustments-horizontal",
|
||||
"settings-dock": "layout-bottombar",
|
||||
"settings-launcher": "rocket",
|
||||
"settings-audio": "device-speaker",
|
||||
|
||||
+2
-2
@@ -41,7 +41,7 @@ Singleton {
|
||||
return `${year}${month}${day}-${hours}${minutes}${seconds}`
|
||||
}
|
||||
|
||||
// Format an easy to read approximate duration ex: 4h32m
|
||||
// Format an easy to read approximate duration ex: 4h 32m
|
||||
// Used to display the time remaining on the Battery widget, computer uptime, etc..
|
||||
function formatVagueHumanReadableDuration(totalSeconds) {
|
||||
if (typeof totalSeconds !== 'number' || totalSeconds < 0) {
|
||||
@@ -69,7 +69,7 @@ Singleton {
|
||||
parts.push(`${seconds}s`)
|
||||
}
|
||||
|
||||
return parts.join('')
|
||||
return parts.join(' ')
|
||||
}
|
||||
|
||||
// Format a date into
|
||||
|
||||
@@ -44,19 +44,6 @@ Variants {
|
||||
property real fillMode: WallpaperService.getFillModeUniform()
|
||||
property vector4d fillColor: Qt.vector4d(Settings.data.wallpaper.fillColor.r, Settings.data.wallpaper.fillColor.g, Settings.data.wallpaper.fillColor.b, 1.0)
|
||||
|
||||
property int monitoredWidth: modelData.width
|
||||
property int monitoredHeight: modelData.height
|
||||
|
||||
onMonitoredWidthChanged: {
|
||||
Logger.log("Background", "Screen width changed to:", monitoredWidth, "for", modelData.name)
|
||||
recalculateImageSizes()
|
||||
}
|
||||
|
||||
onMonitoredHeightChanged: {
|
||||
Logger.log("Background", "Screen height changed to:", monitoredHeight, "for", modelData.name)
|
||||
recalculateImageSizes()
|
||||
}
|
||||
|
||||
Component.onCompleted: setWallpaperInitial()
|
||||
|
||||
Component.onDestruction: {
|
||||
@@ -87,6 +74,13 @@ Variants {
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: CompositorService
|
||||
function onDisplayScalesChanged() {
|
||||
setWallpaperInitial()
|
||||
}
|
||||
}
|
||||
|
||||
color: Color.transparent
|
||||
screen: modelData
|
||||
WlrLayershell.layer: WlrLayer.Background
|
||||
@@ -121,33 +115,22 @@ Variants {
|
||||
visible: false
|
||||
cache: false
|
||||
asynchronous: true
|
||||
|
||||
sourceSize: undefined
|
||||
onStatusChanged: {
|
||||
if (status === Image.Error) {
|
||||
Logger.warn("Current wallpaper failed to load:", source)
|
||||
} else if (status === Image.Ready && !dimensionsCalculated) {
|
||||
dimensionsCalculated = true
|
||||
calculateSourceSize()
|
||||
const optimalSize = calculateOptimalWallpaperSize(implicitWidth, implicitHeight)
|
||||
if (optimalSize !== false) {
|
||||
sourceSize = optimalSize
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onSourceChanged: {
|
||||
dimensionsCalculated = false
|
||||
sourceSize = undefined
|
||||
}
|
||||
|
||||
function calculateSourceSize() {
|
||||
if (implicitWidth > 0 && implicitHeight > 0) {
|
||||
const imageAspectRatio = implicitWidth / implicitHeight
|
||||
if (modelData.width >= modelData.height) {
|
||||
const w = Math.min(modelData.width, implicitWidth)
|
||||
sourceSize = Qt.size(w, w / imageAspectRatio)
|
||||
} else {
|
||||
const h = Math.min(modelData.height, implicitHeight)
|
||||
sourceSize = Qt.size(h * imageAspectRatio, h)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Image {
|
||||
@@ -161,33 +144,22 @@ Variants {
|
||||
visible: false
|
||||
cache: false
|
||||
asynchronous: true
|
||||
|
||||
sourceSize: undefined
|
||||
onStatusChanged: {
|
||||
if (status === Image.Error) {
|
||||
Logger.warn("Next wallpaper failed to load:", source)
|
||||
} else if (status === Image.Ready && !dimensionsCalculated) {
|
||||
dimensionsCalculated = true
|
||||
calculateSourceSize()
|
||||
const optimalSize = calculateOptimalWallpaperSize(implicitWidth, implicitHeight)
|
||||
if (optimalSize !== false) {
|
||||
sourceSize = optimalSize
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onSourceChanged: {
|
||||
dimensionsCalculated = false
|
||||
sourceSize = undefined
|
||||
}
|
||||
|
||||
function calculateSourceSize() {
|
||||
if (implicitWidth > 0 && implicitHeight > 0) {
|
||||
const imageAspectRatio = implicitWidth / implicitHeight
|
||||
if (modelData.width >= modelData.height) {
|
||||
const w = Math.min(modelData.width, implicitWidth)
|
||||
sourceSize = Qt.size(w, w / imageAspectRatio)
|
||||
} else {
|
||||
const h = Math.min(modelData.height, implicitHeight)
|
||||
sourceSize = Qt.size(h * imageAspectRatio, h)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Dynamic shader loader - only loads the active transition shader
|
||||
@@ -344,6 +316,31 @@ Variants {
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------
|
||||
function calculateOptimalWallpaperSize(wpWidth, wpHeight) {
|
||||
const compositorScale = CompositorService.getDisplayScale(modelData.name)
|
||||
const screenWidth = modelData.width * compositorScale
|
||||
const screenHeight = modelData.height * compositorScale
|
||||
if (wpWidth <= screenWidth || wpHeight <= screenHeight || wpWidth <= 0 || wpHeight <= 0) {
|
||||
// Do not resize if wallpaper is smaller than one of the screen dimension
|
||||
return
|
||||
}
|
||||
|
||||
const imageAspectRatio = wpWidth / wpHeight
|
||||
var dim = Qt.size(0, 0)
|
||||
if (screenWidth >= screenHeight) {
|
||||
const w = Math.min(screenWidth, wpWidth)
|
||||
dim = Qt.size(w, w / imageAspectRatio)
|
||||
} else {
|
||||
const h = Math.min(screenHeight, wpHeight)
|
||||
dim = Qt.size(h * imageAspectRatio, h)
|
||||
}
|
||||
|
||||
Logger.log("Background", `Wallpaper resized on ${modelData.name} ${screenWidth}x${screenHeight} @ ${compositorScale}x`, "src:", wpWidth, wpHeight, "dst:", dim.width, dim.height)
|
||||
return dim
|
||||
}
|
||||
|
||||
// ------------------------------------------------------
|
||||
function recalculateImageSizes() {
|
||||
if (currentWallpaper.status === Image.Ready) {
|
||||
currentWallpaper.calculateSourceSize()
|
||||
@@ -353,6 +350,7 @@ Variants {
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------
|
||||
function setWallpaperInitial() {
|
||||
// On startup, defer assigning wallpaper until the service cache is ready, retries every tick
|
||||
if (!WallpaperService || !WallpaperService.isInitialized) {
|
||||
@@ -363,6 +361,7 @@ Variants {
|
||||
setWallpaperImmediate(WallpaperService.getWallpaper(modelData.name))
|
||||
}
|
||||
|
||||
// ------------------------------------------------------
|
||||
function setWallpaperImmediate(source) {
|
||||
transitionAnimation.stop()
|
||||
transitionProgress = 0.0
|
||||
@@ -376,6 +375,7 @@ Variants {
|
||||
})
|
||||
}
|
||||
|
||||
// ------------------------------------------------------
|
||||
function setWallpaperWithTransition(source) {
|
||||
if (source === currentWallpaper.source) {
|
||||
return
|
||||
@@ -409,6 +409,7 @@ Variants {
|
||||
transitionAnimation.start()
|
||||
}
|
||||
|
||||
// ------------------------------------------------------
|
||||
// Main method that actually trigger the wallpaper change
|
||||
function changeWallpaper() {
|
||||
// Get the transitionType from the settings
|
||||
|
||||
@@ -16,21 +16,11 @@ Loader {
|
||||
id: root
|
||||
|
||||
required property ShellScreen modelData
|
||||
property real scaling: ScalingService.getScreenScale(screen)
|
||||
screen: modelData
|
||||
|
||||
property color cornerColor: Settings.data.general.forceBlackScreenCorners ? Qt.rgba(0, 0, 0, 1) : Qt.alpha(Color.mSurface, Settings.data.bar.backgroundOpacity)
|
||||
property real cornerRadius: Style.screenRadius * scaling
|
||||
property real cornerSize: Style.screenRadius * scaling
|
||||
|
||||
Connections {
|
||||
target: ScalingService
|
||||
function onScaleChanged(screenName, scale) {
|
||||
if (screenName === screen.name) {
|
||||
scaling = scale
|
||||
}
|
||||
}
|
||||
}
|
||||
property real cornerRadius: Style.screenRadius
|
||||
property real cornerSize: Style.screenRadius
|
||||
|
||||
color: Color.transparent
|
||||
|
||||
@@ -48,10 +38,10 @@ Loader {
|
||||
margins {
|
||||
// When bar is floating, corners should be at screen edges (no margins)
|
||||
// When bar is not floating, respect bar margins as before
|
||||
top: !Settings.data.bar.floating && BarService.isVisible && ((modelData && Settings.data.bar.monitors.includes(modelData.name)) || (Settings.data.bar.monitors.length === 0)) && Settings.data.bar.position === "top" && Settings.data.bar.backgroundOpacity > 0 ? Math.round(Style.barHeight * scaling) : 0
|
||||
bottom: !Settings.data.bar.floating && BarService.isVisible && ((modelData && Settings.data.bar.monitors.includes(modelData.name)) || (Settings.data.bar.monitors.length === 0)) && Settings.data.bar.position === "bottom" && Settings.data.bar.backgroundOpacity > 0 ? Math.round(Style.barHeight * scaling) : 0
|
||||
left: !Settings.data.bar.floating && BarService.isVisible && ((modelData && Settings.data.bar.monitors.includes(modelData.name)) || (Settings.data.bar.monitors.length === 0)) && Settings.data.bar.position === "left" && Settings.data.bar.backgroundOpacity > 0 ? Math.round(Style.barHeight * scaling) : 0
|
||||
right: !Settings.data.bar.floating && BarService.isVisible && ((modelData && Settings.data.bar.monitors.includes(modelData.name)) || (Settings.data.bar.monitors.length === 0)) && Settings.data.bar.position === "right" && Settings.data.bar.backgroundOpacity > 0 ? Math.round(Style.barHeight * scaling) : 0
|
||||
top: !Settings.data.bar.floating && BarService.isVisible && ((modelData && Settings.data.bar.monitors.includes(modelData.name)) || (Settings.data.bar.monitors.length === 0)) && Settings.data.bar.position === "top" && Settings.data.bar.backgroundOpacity > 0 ? Style.barHeight : 0
|
||||
bottom: !Settings.data.bar.floating && BarService.isVisible && ((modelData && Settings.data.bar.monitors.includes(modelData.name)) || (Settings.data.bar.monitors.length === 0)) && Settings.data.bar.position === "bottom" && Settings.data.bar.backgroundOpacity > 0 ? Style.barHeight : 0
|
||||
left: !Settings.data.bar.floating && BarService.isVisible && ((modelData && Settings.data.bar.monitors.includes(modelData.name)) || (Settings.data.bar.monitors.length === 0)) && Settings.data.bar.position === "left" && Settings.data.bar.backgroundOpacity > 0 ? Style.barHeight : 0
|
||||
right: !Settings.data.bar.floating && BarService.isVisible && ((modelData && Settings.data.bar.monitors.includes(modelData.name)) || (Settings.data.bar.monitors.length === 0)) && Settings.data.bar.position === "right" && Settings.data.bar.backgroundOpacity > 0 ? Style.barHeight : 0
|
||||
}
|
||||
|
||||
mask: Region {}
|
||||
|
||||
+16
-32
@@ -17,16 +17,6 @@ Variants {
|
||||
id: root
|
||||
|
||||
required property ShellScreen modelData
|
||||
property real scaling: ScalingService.getScreenScale(modelData)
|
||||
|
||||
Connections {
|
||||
target: ScalingService
|
||||
function onScaleChanged(screenName, scale) {
|
||||
if ((modelData !== null) && (screenName === modelData.name)) {
|
||||
scaling = scale
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
active: BarService.isVisible && modelData && modelData.name ? (Settings.data.bar.monitors.includes(modelData.name) || (Settings.data.bar.monitors.length === 0)) : false
|
||||
|
||||
@@ -35,8 +25,8 @@ Variants {
|
||||
|
||||
WlrLayershell.namespace: "noctalia-bar"
|
||||
|
||||
implicitHeight: (Settings.data.bar.position === "left" || Settings.data.bar.position === "right") ? screen.height : Math.round(Style.barHeight * scaling)
|
||||
implicitWidth: (Settings.data.bar.position === "left" || Settings.data.bar.position === "right") ? Math.round(Style.barHeight * scaling) : screen.width
|
||||
implicitHeight: (Settings.data.bar.position === "left" || Settings.data.bar.position === "right") ? screen.height : Style.barHeight
|
||||
implicitWidth: (Settings.data.bar.position === "left" || Settings.data.bar.position === "right") ? Style.barHeight : screen.width
|
||||
color: Color.transparent
|
||||
|
||||
anchors {
|
||||
@@ -49,10 +39,10 @@ Variants {
|
||||
// Floating bar margins - only apply when floating is enabled
|
||||
// Also don't apply margin on the opposite side ot the bar orientation, ex: if bar is floating on top, margin is only applied on top, not bottom.
|
||||
margins {
|
||||
top: Settings.data.bar.floating && Settings.data.bar.position !== "bottom" ? Settings.data.bar.marginVertical * Style.marginXL * scaling : 0
|
||||
bottom: Settings.data.bar.floating && Settings.data.bar.position !== "top" ? Settings.data.bar.marginVertical * Style.marginXL * scaling : 0
|
||||
left: Settings.data.bar.floating && Settings.data.bar.position !== "right" ? Settings.data.bar.marginHorizontal * Style.marginXL * scaling : 0
|
||||
right: Settings.data.bar.floating && Settings.data.bar.position !== "left" ? Settings.data.bar.marginHorizontal * Style.marginXL * scaling : 0
|
||||
top: Settings.data.bar.floating && Settings.data.bar.position !== "bottom" ? Settings.data.bar.marginVertical * Style.marginXL : 0
|
||||
bottom: Settings.data.bar.floating && Settings.data.bar.position !== "top" ? Settings.data.bar.marginVertical * Style.marginXL : 0
|
||||
left: Settings.data.bar.floating && Settings.data.bar.position !== "right" ? Settings.data.bar.marginHorizontal * Style.marginXL : 0
|
||||
right: Settings.data.bar.floating && Settings.data.bar.position !== "left" ? Settings.data.bar.marginHorizontal * Style.marginXL : 0
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
@@ -105,8 +95,8 @@ Variants {
|
||||
ColumnLayout {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: Style.marginM * root.scaling
|
||||
spacing: Style.marginS * root.scaling
|
||||
anchors.topMargin: Style.marginM
|
||||
spacing: Style.marginS
|
||||
|
||||
Repeater {
|
||||
model: Settings.data.bar.widgets.left
|
||||
@@ -114,7 +104,6 @@ Variants {
|
||||
widgetId: (modelData.id !== undefined ? modelData.id : "")
|
||||
widgetProps: {
|
||||
"screen": root.modelData || null,
|
||||
"scaling": ScalingService.getScreenScale(screen),
|
||||
"widgetId": modelData.id,
|
||||
"section": "left",
|
||||
"sectionWidgetIndex": index,
|
||||
@@ -129,7 +118,7 @@ Variants {
|
||||
ColumnLayout {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: Style.marginS * root.scaling
|
||||
spacing: Style.marginS
|
||||
|
||||
Repeater {
|
||||
model: Settings.data.bar.widgets.center
|
||||
@@ -137,7 +126,6 @@ Variants {
|
||||
widgetId: (modelData.id !== undefined ? modelData.id : "")
|
||||
widgetProps: {
|
||||
"screen": root.modelData || null,
|
||||
"scaling": ScalingService.getScreenScale(screen),
|
||||
"widgetId": modelData.id,
|
||||
"section": "center",
|
||||
"sectionWidgetIndex": index,
|
||||
@@ -152,8 +140,8 @@ Variants {
|
||||
ColumnLayout {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.bottomMargin: Style.marginM * root.scaling
|
||||
spacing: Style.marginS * root.scaling
|
||||
anchors.bottomMargin: Style.marginM
|
||||
spacing: Style.marginS
|
||||
|
||||
Repeater {
|
||||
model: Settings.data.bar.widgets.right
|
||||
@@ -161,7 +149,6 @@ Variants {
|
||||
widgetId: (modelData.id !== undefined ? modelData.id : "")
|
||||
widgetProps: {
|
||||
"screen": root.modelData || null,
|
||||
"scaling": ScalingService.getScreenScale(screen),
|
||||
"widgetId": modelData.id,
|
||||
"section": "right",
|
||||
"sectionWidgetIndex": index,
|
||||
@@ -185,9 +172,9 @@ Variants {
|
||||
id: leftSection
|
||||
objectName: "leftSection"
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: Style.marginS * root.scaling
|
||||
anchors.leftMargin: Style.marginS
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: Style.marginS * root.scaling
|
||||
spacing: Style.marginS
|
||||
|
||||
Repeater {
|
||||
model: Settings.data.bar.widgets.left
|
||||
@@ -195,7 +182,6 @@ Variants {
|
||||
widgetId: (modelData.id !== undefined ? modelData.id : "")
|
||||
widgetProps: {
|
||||
"screen": root.modelData || null,
|
||||
"scaling": ScalingService.getScreenScale(screen),
|
||||
"widgetId": modelData.id,
|
||||
"section": "left",
|
||||
"sectionWidgetIndex": index,
|
||||
@@ -212,7 +198,7 @@ Variants {
|
||||
objectName: "centerSection"
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: Style.marginS * root.scaling
|
||||
spacing: Style.marginS
|
||||
|
||||
Repeater {
|
||||
model: Settings.data.bar.widgets.center
|
||||
@@ -220,7 +206,6 @@ Variants {
|
||||
widgetId: (modelData.id !== undefined ? modelData.id : "")
|
||||
widgetProps: {
|
||||
"screen": root.modelData || null,
|
||||
"scaling": ScalingService.getScreenScale(screen),
|
||||
"widgetId": modelData.id,
|
||||
"section": "center",
|
||||
"sectionWidgetIndex": index,
|
||||
@@ -236,9 +221,9 @@ Variants {
|
||||
id: rightSection
|
||||
objectName: "rightSection"
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: Style.marginS * root.scaling
|
||||
anchors.rightMargin: Style.marginS
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: Style.marginS * root.scaling
|
||||
spacing: Style.marginS
|
||||
|
||||
Repeater {
|
||||
model: Settings.data.bar.widgets.right
|
||||
@@ -246,7 +231,6 @@ Variants {
|
||||
widgetId: (modelData.id !== undefined ? modelData.id : "")
|
||||
widgetProps: {
|
||||
"screen": root.modelData || null,
|
||||
"scaling": ScalingService.getScreenScale(screen),
|
||||
"widgetId": modelData.id,
|
||||
"section": "right",
|
||||
"sectionWidgetIndex": index,
|
||||
|
||||
@@ -18,11 +18,11 @@ ColumnLayout {
|
||||
}
|
||||
|
||||
Layout.fillWidth: true
|
||||
spacing: Style.marginM * scaling
|
||||
spacing: Style.marginM
|
||||
|
||||
NText {
|
||||
text: root.label
|
||||
pointSize: Style.fontSizeL * scaling
|
||||
pointSize: Style.fontSizeL
|
||||
color: Color.mSecondary
|
||||
font.weight: Style.fontWeightMedium
|
||||
Layout.fillWidth: true
|
||||
@@ -51,35 +51,35 @@ ColumnLayout {
|
||||
}
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: deviceLayout.implicitHeight + (Style.marginM * scaling * 2)
|
||||
radius: Style.radiusM * scaling
|
||||
Layout.preferredHeight: deviceLayout.implicitHeight + (Style.marginM * 2)
|
||||
radius: Style.radiusM
|
||||
color: Color.mSurface
|
||||
border.width: Math.max(1, Style.borderS * scaling)
|
||||
border.width: Math.max(1, Style.borderS)
|
||||
border.color: getContentColor(Color.mOutline)
|
||||
|
||||
RowLayout {
|
||||
id: deviceLayout
|
||||
anchors.fill: parent
|
||||
anchors.margins: Style.marginM * scaling
|
||||
spacing: Style.marginM * scaling
|
||||
anchors.margins: Style.marginM
|
||||
spacing: Style.marginM
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
|
||||
// One device BT icon
|
||||
NIcon {
|
||||
icon: BluetoothService.getDeviceIcon(modelData)
|
||||
pointSize: Style.fontSizeXXL * scaling
|
||||
pointSize: Style.fontSizeXXL
|
||||
color: getContentColor(Color.mOnSurface)
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: Style.marginXXS * scaling
|
||||
spacing: Style.marginXXS
|
||||
|
||||
// Device name
|
||||
NText {
|
||||
text: modelData.name || modelData.deviceName
|
||||
pointSize: Style.fontSizeM * scaling
|
||||
pointSize: Style.fontSizeM
|
||||
font.weight: Style.fontWeightMedium
|
||||
elide: Text.ElideRight
|
||||
color: getContentColor(Color.mOnSurface)
|
||||
@@ -90,7 +90,7 @@ ColumnLayout {
|
||||
NText {
|
||||
text: BluetoothService.getStatusString(modelData)
|
||||
visible: text !== ""
|
||||
pointSize: Style.fontSizeXS * scaling
|
||||
pointSize: Style.fontSizeXS
|
||||
color: getContentColor(Color.mOnSurfaceVariant)
|
||||
}
|
||||
|
||||
@@ -98,26 +98,26 @@ ColumnLayout {
|
||||
RowLayout {
|
||||
visible: modelData.signalStrength !== undefined
|
||||
Layout.fillWidth: true
|
||||
spacing: Style.marginXS * scaling
|
||||
spacing: Style.marginXS
|
||||
|
||||
// Device signal strength - "Unknown" when not connected
|
||||
NText {
|
||||
text: BluetoothService.getSignalStrength(modelData)
|
||||
pointSize: Style.fontSizeXS * scaling
|
||||
pointSize: Style.fontSizeXS
|
||||
color: getContentColor(Color.mOnSurfaceVariant)
|
||||
}
|
||||
|
||||
NIcon {
|
||||
visible: modelData.signalStrength > 0 && !modelData.pairing && !modelData.blocked
|
||||
text: BluetoothService.getSignalIcon(modelData)
|
||||
pointSize: Style.fontSizeXS * scaling
|
||||
pointSize: Style.fontSizeXS
|
||||
color: getContentColor(Color.mOnSurface)
|
||||
}
|
||||
|
||||
NText {
|
||||
visible: modelData.signalStrength > 0 && !modelData.pairing && !modelData.blocked
|
||||
text: (modelData.signalStrength !== undefined && modelData.signalStrength > 0) ? modelData.signalStrength + "%" : ""
|
||||
pointSize: Style.fontSizeXS * scaling
|
||||
pointSize: Style.fontSizeXS
|
||||
color: getContentColor(Color.mOnSurface)
|
||||
}
|
||||
}
|
||||
@@ -126,7 +126,7 @@ ColumnLayout {
|
||||
NText {
|
||||
visible: modelData.batteryAvailable
|
||||
text: BluetoothService.getBattery(modelData)
|
||||
pointSize: Style.fontSizeXS * scaling
|
||||
pointSize: Style.fontSizeXS
|
||||
color: getContentColor(Color.mOnSurfaceVariant)
|
||||
}
|
||||
}
|
||||
@@ -142,7 +142,7 @@ ColumnLayout {
|
||||
visible: (modelData.state !== BluetoothDeviceState.Connecting)
|
||||
enabled: (canConnect || canDisconnect) && !isBusy
|
||||
outlined: !button.hovered
|
||||
fontSize: Style.fontSizeXS * scaling
|
||||
fontSize: Style.fontSizeXS
|
||||
fontWeight: Style.fontWeightMedium
|
||||
backgroundColor: {
|
||||
if (device.canDisconnect && !isBusy) {
|
||||
|
||||
@@ -11,8 +11,8 @@ import qs.Widgets
|
||||
NPanel {
|
||||
id: root
|
||||
|
||||
preferredWidth: 380
|
||||
preferredHeight: 500
|
||||
preferredWidth: 380 * Style.uiScaleRatio
|
||||
preferredHeight: 500 * Style.uiScaleRatio
|
||||
panelKeyboardFocus: true
|
||||
|
||||
panelContent: Rectangle {
|
||||
@@ -20,23 +20,23 @@ NPanel {
|
||||
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
anchors.margins: Style.marginL * scaling
|
||||
spacing: Style.marginM * scaling
|
||||
anchors.margins: Style.marginL
|
||||
spacing: Style.marginM
|
||||
|
||||
// HEADER
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: Style.marginM * scaling
|
||||
spacing: Style.marginM
|
||||
|
||||
NIcon {
|
||||
icon: "bluetooth"
|
||||
pointSize: Style.fontSizeXXL * scaling
|
||||
pointSize: Style.fontSizeXXL
|
||||
color: Color.mPrimary
|
||||
}
|
||||
|
||||
NText {
|
||||
text: I18n.tr("bluetooth.panel.title")
|
||||
pointSize: Style.fontSizeL * scaling
|
||||
pointSize: Style.fontSizeL
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Color.mOnSurface
|
||||
Layout.fillWidth: true
|
||||
@@ -46,7 +46,7 @@ NPanel {
|
||||
id: bluetoothSwitch
|
||||
checked: BluetoothService.enabled
|
||||
onToggled: checked => BluetoothService.setBluetoothEnabled(checked)
|
||||
baseSize: Style.baseWidgetSize * 0.65 * scaling
|
||||
baseSize: Style.baseWidgetSize * 0.65
|
||||
}
|
||||
|
||||
NIconButton {
|
||||
@@ -84,25 +84,25 @@ NPanel {
|
||||
// Center the content within this rectangle
|
||||
ColumnLayout {
|
||||
anchors.centerIn: parent
|
||||
spacing: Style.marginM * scaling
|
||||
spacing: Style.marginM
|
||||
|
||||
NIcon {
|
||||
icon: "bluetooth-off"
|
||||
pointSize: 64 * scaling
|
||||
pointSize: 64
|
||||
color: Color.mOnSurfaceVariant
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
|
||||
NText {
|
||||
text: I18n.tr("bluetooth.panel.disabled")
|
||||
pointSize: Style.fontSizeL * scaling
|
||||
pointSize: Style.fontSizeL
|
||||
color: Color.mOnSurfaceVariant
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
|
||||
NText {
|
||||
text: I18n.tr("bluetooth.panel.enable-message")
|
||||
pointSize: Style.fontSizeS * scaling
|
||||
pointSize: Style.fontSizeS
|
||||
color: Color.mOnSurfaceVariant
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
@@ -120,7 +120,7 @@ NPanel {
|
||||
|
||||
ColumnLayout {
|
||||
width: parent.width
|
||||
spacing: Style.marginM * scaling
|
||||
spacing: Style.marginM
|
||||
|
||||
// Connected devices
|
||||
BluetoothDevicesList {
|
||||
@@ -168,7 +168,7 @@ NPanel {
|
||||
// Fallback - No devices, scanning
|
||||
ColumnLayout {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
spacing: Style.marginM * scaling
|
||||
spacing: Style.marginM
|
||||
visible: {
|
||||
if (!BluetoothService.adapter || !BluetoothService.adapter.discovering || !Bluetooth.devices) {
|
||||
return false
|
||||
@@ -182,11 +182,11 @@ NPanel {
|
||||
|
||||
RowLayout {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
spacing: Style.marginXS * scaling
|
||||
spacing: Style.marginXS
|
||||
|
||||
NIcon {
|
||||
icon: "refresh"
|
||||
pointSize: Style.fontSizeXXL * 1.5 * scaling
|
||||
pointSize: Style.fontSizeXXL * 1.5
|
||||
color: Color.mPrimary
|
||||
|
||||
RotationAnimation on rotation {
|
||||
@@ -200,14 +200,14 @@ NPanel {
|
||||
|
||||
NText {
|
||||
text: I18n.tr("bluetooth.panel.scanning")
|
||||
pointSize: Style.fontSizeL * scaling
|
||||
pointSize: Style.fontSizeL
|
||||
color: Color.mOnSurface
|
||||
}
|
||||
}
|
||||
|
||||
NText {
|
||||
text: I18n.tr("bluetooth.panel.pairing-mode")
|
||||
pointSize: Style.fontSizeM * scaling
|
||||
pointSize: Style.fontSizeM
|
||||
color: Color.mOnSurfaceVariant
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
|
||||
@@ -10,22 +10,40 @@ import qs.Widgets
|
||||
NPanel {
|
||||
id: root
|
||||
|
||||
preferredWidth: Settings.data.location.showWeekNumberInCalendar ? 340 : 320
|
||||
preferredHeight: 380
|
||||
readonly property var now: Time.date
|
||||
|
||||
preferredWidth: (Settings.data.location.showWeekNumberInCalendar ? 400 : 380) * Style.uiScaleRatio
|
||||
preferredHeight: 520 * Style.uiScaleRatio
|
||||
panelKeyboardFocus: true
|
||||
|
||||
panelContent: ColumnLayout {
|
||||
id: content
|
||||
anchors.fill: parent
|
||||
anchors.margins: Style.marginL * scaling
|
||||
spacing: Style.marginM * scaling
|
||||
anchors.margins: Style.marginL
|
||||
spacing: Style.marginM
|
||||
|
||||
readonly property int firstDayOfWeek: Qt.locale().firstDayOfWeek
|
||||
property bool isCurrentMonth: checkIsCurrentMonth()
|
||||
readonly property bool weatherReady: (LocationService.data.weather !== null)
|
||||
|
||||
function checkIsCurrentMonth() {
|
||||
return (Time.date.getMonth() === grid.month) && (Time.date.getFullYear() === grid.year)
|
||||
}
|
||||
|
||||
Shortcut {
|
||||
sequence: "Escape"
|
||||
onActivated: {
|
||||
if (timerActive) {
|
||||
cancelTimer()
|
||||
} else {
|
||||
cancelTimer()
|
||||
root.close()
|
||||
}
|
||||
}
|
||||
context: Qt.WidgetShortcut
|
||||
enabled: root.opened
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: Time
|
||||
function onDateChanged() {
|
||||
@@ -33,143 +51,290 @@ NPanel {
|
||||
}
|
||||
}
|
||||
|
||||
// Current day
|
||||
// Combined blue banner with date/time and weather summary
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 80 * scaling
|
||||
radius: Style.radiusL * scaling
|
||||
Layout.preferredHeight: blueColumn.implicitHeight + Style.marginM * 2
|
||||
radius: Style.radiusL
|
||||
color: Color.mPrimary
|
||||
|
||||
RowLayout {
|
||||
anchors.fill: parent
|
||||
anchors.margins: Style.marginL * scaling
|
||||
anchors.topMargin: 12 * scaling
|
||||
spacing: Style.marginM * scaling
|
||||
ColumnLayout {
|
||||
id: blueColumn
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.topMargin: Style.marginM
|
||||
anchors.leftMargin: Style.marginM
|
||||
anchors.bottomMargin: Style.marginM
|
||||
anchors.rightMargin: clockItem.width + (Style.marginM * 2)
|
||||
spacing: 0
|
||||
|
||||
// Month, Year and Day
|
||||
// Combined layout for weather icon, date, and weather text
|
||||
RowLayout {
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
Layout.fillHeight: true
|
||||
spacing: Style.marginM * scaling
|
||||
Layout.fillWidth: true
|
||||
height: 60 * Style.uiScaleRatio
|
||||
clip: true
|
||||
spacing: Style.marginS
|
||||
|
||||
// Big day of the month
|
||||
// Weather icon and temperature
|
||||
ColumnLayout {
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
spacing: Style.marginXXS
|
||||
|
||||
NIcon {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
icon: weatherReady ? LocationService.weatherSymbolFromCode(LocationService.data.weather.current_weather.weathercode) : "cloud"
|
||||
pointSize: Style.fontSizeXXL
|
||||
color: Color.mOnPrimary
|
||||
}
|
||||
|
||||
NText {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text: {
|
||||
if (!weatherReady)
|
||||
return ""
|
||||
var temp = LocationService.data.weather.current_weather.temperature
|
||||
var suffix = "C"
|
||||
if (Settings.data.location.useFahrenheit) {
|
||||
temp = LocationService.celsiusToFahrenheit(temp)
|
||||
suffix = "F"
|
||||
}
|
||||
temp = Math.round(temp)
|
||||
return `${temp}°${suffix}`
|
||||
}
|
||||
pointSize: Style.fontSizeM
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Color.mOnPrimary
|
||||
}
|
||||
}
|
||||
|
||||
// Today day number - with simple, stable animation
|
||||
NText {
|
||||
opacity: content.isCurrentMonth ? 1.0 : 0.0
|
||||
Layout.preferredWidth: content.isCurrentMonth ? implicitWidth : 0
|
||||
elide: Text.ElideNone
|
||||
clip: true
|
||||
|
||||
Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft
|
||||
text: Time.date.getDate()
|
||||
pointSize: Style.fontSizeXXXL * 1.5 * scaling
|
||||
pointSize: Style.fontSizeXXXL * 1.5
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Color.mOnPrimary
|
||||
visible: isCurrentMonth
|
||||
Layout.preferredWidth: visible ? implicitWidth : 0
|
||||
Layout.fillHeight: true
|
||||
|
||||
Behavior on opacity {
|
||||
NumberAnimation {
|
||||
duration: Style.animationFast
|
||||
}
|
||||
}
|
||||
Behavior on Layout.preferredWidth {
|
||||
NumberAnimation {
|
||||
duration: Style.animationFast
|
||||
easing.type: Easing.InOutQuad
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Month and Year
|
||||
// Month, year, location
|
||||
ColumnLayout {
|
||||
spacing: 0
|
||||
Layout.preferredWidth: 170 * Style.uiScaleRatio
|
||||
Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft
|
||||
Layout.bottomMargin: Style.marginXXS
|
||||
Layout.topMargin: -Style.marginXXS
|
||||
spacing: -Style.marginXS
|
||||
|
||||
NText {
|
||||
text: Qt.locale().monthName(grid.month, Locale.LongFormat).toUpperCase()
|
||||
pointSize: Style.fontSizeL * scaling
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Color.mOnPrimary
|
||||
}
|
||||
RowLayout {
|
||||
spacing: 0
|
||||
|
||||
NText {
|
||||
text: grid.year
|
||||
pointSize: Style.fontSizeM * scaling
|
||||
color: Qt.alpha(Color.mOnPrimary, 0.8)
|
||||
}
|
||||
}
|
||||
}
|
||||
NText {
|
||||
text: Qt.locale().monthName(grid.month, Locale.LongFormat).toUpperCase()
|
||||
pointSize: Style.fontSizeXL * 1.1
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Color.mOnPrimary
|
||||
Layout.alignment: Qt.AlignBaseline
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
// Digital clock with circular progress
|
||||
Item {
|
||||
width: Style.fontSizeXXXL * 2 * scaling
|
||||
height: Style.fontSizeXXXL * 2 * scaling
|
||||
|
||||
// Seconds circular progress
|
||||
Canvas {
|
||||
id: secondsProgress
|
||||
anchors.fill: parent
|
||||
|
||||
property real progress: Time.date.getSeconds() / 60
|
||||
onProgressChanged: requestPaint()
|
||||
|
||||
Connections {
|
||||
target: Time
|
||||
function onDateChanged() {
|
||||
secondsProgress.progress = Time.date.getSeconds() / 60
|
||||
NText {
|
||||
text: ` ${grid.year}`
|
||||
pointSize: Style.fontSizeM
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Qt.alpha(Color.mOnPrimary, 0.7)
|
||||
Layout.alignment: Qt.AlignBaseline
|
||||
}
|
||||
}
|
||||
|
||||
onPaint: {
|
||||
var ctx = getContext("2d")
|
||||
var centerX = width / 2
|
||||
var centerY = height / 2
|
||||
var radius = Math.min(width, height) / 2 - 4 * scaling
|
||||
RowLayout {
|
||||
spacing: 0
|
||||
|
||||
ctx.reset()
|
||||
NText {
|
||||
text: {
|
||||
if (!weatherReady)
|
||||
return I18n.tr("calendar.weather.loading")
|
||||
const chunks = Settings.data.location.name.split(",")
|
||||
return chunks[0]
|
||||
}
|
||||
pointSize: Style.fontSizeM
|
||||
font.weight: Style.fontWeightMedium
|
||||
color: Color.mOnPrimary
|
||||
Layout.maximumWidth: 150
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
|
||||
// Background circle
|
||||
ctx.beginPath()
|
||||
ctx.arc(centerX, centerY, radius, 0, 2 * Math.PI)
|
||||
ctx.lineWidth = 3 * scaling
|
||||
ctx.strokeStyle = Qt.alpha(Color.mOnPrimary, 0.15)
|
||||
ctx.stroke()
|
||||
|
||||
// Progress arc
|
||||
ctx.beginPath()
|
||||
ctx.arc(centerX, centerY, radius, -Math.PI / 2, -Math.PI / 2 + progress * 2 * Math.PI)
|
||||
ctx.lineWidth = 3 * scaling
|
||||
ctx.strokeStyle = Color.mOnPrimary
|
||||
ctx.lineCap = "round"
|
||||
ctx.stroke()
|
||||
NText {
|
||||
text: weatherReady ? ` (${LocationService.data.weather.timezone_abbreviation})` : ""
|
||||
pointSize: Style.fontSizeXS
|
||||
font.weight: Style.fontWeightMedium
|
||||
color: Qt.alpha(Color.mOnPrimary, 0.7)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Digital clock
|
||||
ColumnLayout {
|
||||
anchors.centerIn: parent
|
||||
spacing: -3 * scaling
|
||||
// Spacer to push content left
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NText {
|
||||
text: {
|
||||
var t = Settings.data.location.use12hourFormat ? Qt.locale().toString(new Date(), "hh AP") : Qt.locale().toString(new Date(), "HH")
|
||||
return t.split(" ")[0]
|
||||
}
|
||||
pointSize: Style.fontSizeS * scaling
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Color.mOnPrimary
|
||||
family: Settings.data.ui.fontFixed
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
// Digital clock with circular progress
|
||||
Item {
|
||||
id: clockItem
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: Style.marginM
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
height: Math.round((Style.fontSizeXXXL * 1.9) / 2 * Style.uiScaleRatio) * 2
|
||||
width: clockItem.height
|
||||
|
||||
// Seconds circular progress
|
||||
Canvas {
|
||||
id: secondsProgress
|
||||
anchors.fill: parent
|
||||
property real progress: now.getSeconds() / 60
|
||||
onProgressChanged: requestPaint()
|
||||
Connections {
|
||||
target: Time
|
||||
function onDateChanged() {
|
||||
const total = now.getSeconds() * 1000 + now.getMilliseconds()
|
||||
secondsProgress.progress = total / 60000
|
||||
}
|
||||
}
|
||||
onPaint: {
|
||||
var ctx = getContext("2d")
|
||||
var centerX = width / 2
|
||||
var centerY = height / 2
|
||||
var radius = Math.min(width, height) / 2 - 3
|
||||
ctx.reset()
|
||||
|
||||
// Background circle
|
||||
ctx.beginPath()
|
||||
ctx.arc(centerX, centerY, radius, 0, 2 * Math.PI)
|
||||
ctx.lineWidth = 2.5
|
||||
ctx.strokeStyle = Qt.alpha(Color.mOnPrimary, 0.15)
|
||||
ctx.stroke()
|
||||
|
||||
// Progress arc
|
||||
ctx.beginPath()
|
||||
ctx.arc(centerX, centerY, radius, -Math.PI / 2, -Math.PI / 2 + progress * 2 * Math.PI)
|
||||
ctx.lineWidth = 2.5
|
||||
ctx.strokeStyle = Color.mOnPrimary
|
||||
ctx.lineCap = "round"
|
||||
ctx.stroke()
|
||||
}
|
||||
}
|
||||
|
||||
// Digital clock
|
||||
ColumnLayout {
|
||||
anchors.centerIn: parent
|
||||
spacing: -Style.marginXXS
|
||||
|
||||
NText {
|
||||
text: {
|
||||
var t = Settings.data.location.use12hourFormat ? Qt.locale().toString(now, "hh AP") : Qt.locale().toString(now, "HH")
|
||||
return t.split(" ")[0]
|
||||
}
|
||||
|
||||
NText {
|
||||
text: Qt.formatTime(Time.date, "mm")
|
||||
pointSize: Style.fontSizeS * scaling
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Color.mOnPrimary
|
||||
family: Settings.data.ui.fontFixed
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
pointSize: Style.fontSizeXS
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Color.mOnPrimary
|
||||
family: Settings.data.ui.fontFixed
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
|
||||
NText {
|
||||
text: Qt.formatTime(now, "mm")
|
||||
pointSize: Style.fontSizeXXS
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Color.mOnPrimary
|
||||
family: Settings.data.ui.fontFixed
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Navigation and divider
|
||||
// ... (rest of the file is unchanged) ...
|
||||
RowLayout {
|
||||
visible: weatherReady
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
spacing: Style.marginL
|
||||
Repeater {
|
||||
model: weatherReady ? Math.min(6, LocationService.data.weather.daily.time.length) : 0
|
||||
delegate: ColumnLayout {
|
||||
Layout.preferredWidth: 0
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
spacing: Style.marginS
|
||||
NText {
|
||||
text: {
|
||||
var weatherDate = new Date(LocationService.data.weather.daily.time[index].replace(/-/g, "/"))
|
||||
return Qt.locale().toString(weatherDate, "ddd")
|
||||
}
|
||||
color: Color.mOnSurfaceVariant
|
||||
pointSize: Style.fontSizeM
|
||||
font.weight: Style.fontWeightMedium
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
NIcon {
|
||||
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
|
||||
icon: LocationService.weatherSymbolFromCode(LocationService.data.weather.daily.weathercode[index])
|
||||
pointSize: Style.fontSizeXXL * 1.5
|
||||
color: Color.mPrimary
|
||||
}
|
||||
NText {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text: {
|
||||
var max = LocationService.data.weather.daily.temperature_2m_max[index]
|
||||
var min = LocationService.data.weather.daily.temperature_2m_min[index]
|
||||
if (Settings.data.location.useFahrenheit) {
|
||||
max = LocationService.celsiusToFahrenheit(max)
|
||||
min = LocationService.celsiusToFahrenheit(min)
|
||||
}
|
||||
max = Math.round(max)
|
||||
min = Math.round(min)
|
||||
return `${max}°/${min}°`
|
||||
}
|
||||
pointSize: Style.fontSizeXS
|
||||
color: Color.mOnSurfaceVariant
|
||||
font.weight: Style.fontWeightMedium
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
RowLayout {
|
||||
visible: !weatherReady
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
NBusyIndicator {}
|
||||
}
|
||||
Item {}
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: Style.marginS * scaling
|
||||
|
||||
spacing: Style.marginS
|
||||
NDivider {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
NIconButton {
|
||||
icon: "chevron-left"
|
||||
onClicked: {
|
||||
@@ -179,7 +344,6 @@ NPanel {
|
||||
content.isCurrentMonth = content.checkIsCurrentMonth()
|
||||
}
|
||||
}
|
||||
|
||||
NIconButton {
|
||||
icon: "calendar"
|
||||
onClicked: {
|
||||
@@ -188,7 +352,6 @@ NPanel {
|
||||
content.isCurrentMonth = true
|
||||
}
|
||||
}
|
||||
|
||||
NIconButton {
|
||||
icon: "chevron-right"
|
||||
onClicked: {
|
||||
@@ -199,31 +362,24 @@ NPanel {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Names of days of the week
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: 0
|
||||
|
||||
Item {
|
||||
visible: Settings.data.location.showWeekNumberInCalendar
|
||||
Layout.preferredWidth: visible ? Style.baseWidgetSize * 0.7 * scaling : 0
|
||||
Layout.preferredWidth: visible ? Style.baseWidgetSize * 0.7 : 0
|
||||
}
|
||||
|
||||
GridLayout {
|
||||
Layout.fillWidth: true
|
||||
columns: 7
|
||||
rows: 1
|
||||
columnSpacing: 0
|
||||
rowSpacing: 0
|
||||
|
||||
Repeater {
|
||||
model: 7
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: Style.baseWidgetSize * 0.6 * scaling
|
||||
|
||||
Layout.preferredHeight: Style.baseWidgetSize * 0.6
|
||||
NText {
|
||||
anchors.centerIn: parent
|
||||
text: {
|
||||
@@ -232,7 +388,7 @@ NPanel {
|
||||
return dayNames[dayIndex]
|
||||
}
|
||||
color: Color.mPrimary
|
||||
pointSize: Style.fontSizeS * scaling
|
||||
pointSize: Style.fontSizeS
|
||||
font.weight: Style.fontWeightBold
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
}
|
||||
@@ -240,31 +396,24 @@ NPanel {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Grid with weeks and days
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
spacing: 0
|
||||
|
||||
// Column of week numbers
|
||||
ColumnLayout {
|
||||
visible: Settings.data.location.showWeekNumberInCalendar
|
||||
Layout.preferredWidth: visible ? Style.baseWidgetSize * 0.7 * scaling : 0
|
||||
Layout.preferredWidth: visible ? Style.baseWidgetSize * 0.7 : 0
|
||||
Layout.fillHeight: true
|
||||
spacing: 0
|
||||
|
||||
Repeater {
|
||||
model: 6
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
|
||||
NText {
|
||||
anchors.centerIn: parent
|
||||
color: Color.mOutline
|
||||
pointSize: Style.fontSizeXXS * scaling
|
||||
pointSize: Style.fontSizeXXS
|
||||
font.weight: Style.fontWeightMedium
|
||||
text: {
|
||||
let firstOfMonth = new Date(grid.year, grid.month, 1)
|
||||
@@ -292,27 +441,21 @@ NPanel {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Days Grid
|
||||
MonthGrid {
|
||||
id: grid
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
spacing: Style.marginXXS * scaling
|
||||
spacing: Style.marginXXS
|
||||
month: Time.date.getMonth()
|
||||
year: Time.date.getFullYear()
|
||||
locale: Qt.locale()
|
||||
|
||||
delegate: Item {
|
||||
Rectangle {
|
||||
width: Style.baseWidgetSize * 0.9 * scaling
|
||||
height: Style.baseWidgetSize * 0.9 * scaling
|
||||
width: Style.baseWidgetSize * 0.9
|
||||
height: Style.baseWidgetSize * 0.9
|
||||
anchors.centerIn: parent
|
||||
radius: Style.radiusM * scaling
|
||||
|
||||
radius: Style.radiusM
|
||||
color: model.today ? Color.mSecondary : Color.transparent
|
||||
|
||||
NText {
|
||||
anchors.centerIn: parent
|
||||
text: model.day
|
||||
@@ -324,10 +467,9 @@ NPanel {
|
||||
return Color.mOnSurfaceVariant
|
||||
}
|
||||
opacity: model.month === grid.month ? 1.0 : 0.4
|
||||
pointSize: Style.fontSizeM * scaling
|
||||
pointSize: Style.fontSizeM
|
||||
font.weight: model.today ? Style.fontWeightBold : Style.fontWeightMedium
|
||||
}
|
||||
|
||||
Behavior on color {
|
||||
ColorAnimation {
|
||||
duration: Style.animationFast
|
||||
|
||||
@@ -12,13 +12,13 @@ Item {
|
||||
property string text: ""
|
||||
property string suffix: ""
|
||||
property string tooltipText: ""
|
||||
property string density: ""
|
||||
property bool autoHide: false
|
||||
property bool forceOpen: false
|
||||
property bool forceClose: false
|
||||
property bool disableOpen: false
|
||||
property bool rightOpen: false
|
||||
property bool hovered: false
|
||||
property bool compact: false
|
||||
|
||||
readonly property string barPosition: Settings.data.bar.position
|
||||
readonly property bool isVerticalBar: barPosition === "left" || barPosition === "right"
|
||||
@@ -54,7 +54,7 @@ Item {
|
||||
disableOpen: root.disableOpen
|
||||
rightOpen: root.rightOpen
|
||||
hovered: root.hovered
|
||||
compact: root.compact
|
||||
density: root.density
|
||||
onShown: root.shown()
|
||||
onHidden: root.hidden()
|
||||
onEntered: root.entered()
|
||||
@@ -79,7 +79,7 @@ Item {
|
||||
disableOpen: root.disableOpen
|
||||
rightOpen: root.rightOpen
|
||||
hovered: root.hovered
|
||||
compact: root.compact
|
||||
density: root.density
|
||||
onShown: root.shown()
|
||||
onHidden: root.hidden()
|
||||
onEntered: root.entered()
|
||||
|
||||
@@ -14,13 +14,13 @@ Item {
|
||||
property string text: ""
|
||||
property string suffix: ""
|
||||
property string tooltipText: ""
|
||||
property string density: ""
|
||||
property bool autoHide: false
|
||||
property bool forceOpen: false
|
||||
property bool forceClose: false
|
||||
property bool disableOpen: false
|
||||
property bool rightOpen: false
|
||||
property bool hovered: false
|
||||
property bool compact: false
|
||||
|
||||
// Effective shown state (true if hovered/animated open or forced)
|
||||
readonly property bool revealed: !forceClose && (forceOpen || showPill)
|
||||
@@ -38,13 +38,28 @@ Item {
|
||||
property bool showPill: false
|
||||
property bool shouldAnimateHide: false
|
||||
|
||||
readonly property int pillHeight: Math.round(Style.capsuleHeight * scaling)
|
||||
readonly property int pillPaddingHorizontal: Math.round(Style.capsuleHeight * 0.2 * scaling)
|
||||
readonly property int pillOverlap: Math.round(Style.capsuleHeight * 0.5 * scaling)
|
||||
readonly property int pillMaxWidth: Math.max(1, textItem.implicitWidth + pillPaddingHorizontal * 2 + pillOverlap)
|
||||
readonly property int pillHeight: Style.capsuleHeight
|
||||
readonly property int pillPaddingHorizontal: Math.round(Style.capsuleHeight * 0.2)
|
||||
readonly property int pillOverlap: Math.round(Style.capsuleHeight * 0.5)
|
||||
readonly property int pillMaxWidth: Math.max(1, Math.round(textItem.implicitWidth + pillPaddingHorizontal * 2 + pillOverlap))
|
||||
|
||||
readonly property real iconSize: Math.max(1, compact ? pillHeight * 0.65 : pillHeight * 0.48)
|
||||
readonly property real textSize: Math.max(1, compact ? pillHeight * 0.45 : pillHeight * 0.33)
|
||||
readonly property real iconSize: {
|
||||
switch (root.density) {
|
||||
case "compact":
|
||||
return Math.max(1, Math.round(pillHeight * 0.65))
|
||||
default:
|
||||
return Math.max(1, Math.round(pillHeight * 0.48))
|
||||
}
|
||||
}
|
||||
|
||||
readonly property real textSize: {
|
||||
switch (root.density) {
|
||||
case "compact":
|
||||
return Math.max(1, Math.round(pillHeight * 0.45))
|
||||
default:
|
||||
return Math.max(1, Math.round(pillHeight * 0.33))
|
||||
}
|
||||
}
|
||||
|
||||
width: pillHeight + Math.max(0, pill.width - pillOverlap)
|
||||
height: pillHeight
|
||||
@@ -68,10 +83,12 @@ Item {
|
||||
opacity: revealed ? Style.opacityFull : Style.opacityNone
|
||||
color: Settings.data.bar.showCapsule ? Color.mSurfaceVariant : Color.transparent
|
||||
|
||||
topLeftRadius: rightOpen ? 0 : pillHeight * 0.5
|
||||
bottomLeftRadius: rightOpen ? 0 : pillHeight * 0.5
|
||||
topRightRadius: rightOpen ? pillHeight * 0.5 : 0
|
||||
bottomRightRadius: rightOpen ? pillHeight * 0.5 : 0
|
||||
readonly property int halfPillHeight: Math.round(pillHeight * 0.5)
|
||||
|
||||
topLeftRadius: rightOpen ? 0 : halfPillHeight
|
||||
bottomLeftRadius: rightOpen ? 0 : halfPillHeight
|
||||
topRightRadius: rightOpen ? halfPillHeight : 0
|
||||
bottomRightRadius: rightOpen ? halfPillHeight : 0
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
NText {
|
||||
@@ -80,16 +97,17 @@ Item {
|
||||
x: {
|
||||
// Better text horizontal centering
|
||||
var centerX = (parent.width - width) / 2
|
||||
var offset = rightOpen ? Style.marginXS * scaling : -Style.marginXS * scaling
|
||||
var offset = rightOpen ? Style.marginXS : -Style.marginXS
|
||||
if (forceOpen) {
|
||||
// If its force open, the icon disc background is the same color as the bg pill move text slightly
|
||||
offset += rightOpen ? -Style.marginXXS * scaling : Style.marginXXS * scaling
|
||||
offset += rightOpen ? -Style.marginXXS : Style.marginXXS
|
||||
}
|
||||
return centerX + offset
|
||||
}
|
||||
text: root.text + root.suffix
|
||||
family: Settings.data.ui.fontFixed
|
||||
pointSize: textSize
|
||||
applyUiScale: false
|
||||
font.weight: Style.fontWeightBold
|
||||
color: forceOpen ? Color.mOnSurface : Color.mPrimary
|
||||
visible: revealed
|
||||
@@ -131,6 +149,7 @@ Item {
|
||||
NIcon {
|
||||
icon: root.icon
|
||||
pointSize: iconSize
|
||||
applyUiScale: false
|
||||
color: hovered ? Color.mOnTertiary : Color.mOnSurface
|
||||
// Center horizontally
|
||||
x: (iconCircle.width - width) / 2
|
||||
|
||||
@@ -12,13 +12,13 @@ Item {
|
||||
property string text: ""
|
||||
property string suffix: ""
|
||||
property string tooltipText: ""
|
||||
property string density: ""
|
||||
property bool autoHide: false
|
||||
property bool forceOpen: false
|
||||
property bool forceClose: false
|
||||
property bool disableOpen: false
|
||||
property bool rightOpen: false
|
||||
property bool hovered: false
|
||||
property bool compact: false
|
||||
|
||||
// Bar position detection for pill direction
|
||||
readonly property string barPosition: Settings.data.bar.position
|
||||
@@ -45,15 +45,30 @@ Item {
|
||||
property bool shouldAnimateHide: false
|
||||
|
||||
// Sizing logic for vertical bars
|
||||
readonly property int buttonSize: Math.round(Style.capsuleHeight * scaling)
|
||||
readonly property int buttonSize: Style.capsuleHeight
|
||||
readonly property int pillHeight: buttonSize
|
||||
readonly property int pillPaddingVertical: 3 * 2 * scaling // Very precise adjustment don't replace by Style.margin
|
||||
readonly property int pillOverlap: buttonSize * 0.5
|
||||
readonly property int pillPaddingVertical: 3 * 2 // Very precise adjustment don't replace by Style.margin
|
||||
readonly property int pillOverlap: Math.round(buttonSize * 0.5)
|
||||
readonly property int maxPillWidth: buttonSize
|
||||
readonly property int maxPillHeight: Math.max(1, textItem.implicitHeight + pillPaddingVertical * 4)
|
||||
readonly property int maxPillHeight: Math.max(1, Math.round(textItem.implicitHeight + pillPaddingVertical * 4))
|
||||
|
||||
readonly property real iconSize: Math.max(1, compact ? pillHeight * 0.65 : pillHeight * 0.48)
|
||||
readonly property real textSize: Math.max(1, compact ? pillHeight * 0.38 : pillHeight * 0.33)
|
||||
readonly property real iconSize: {
|
||||
switch (root.density) {
|
||||
case "compact":
|
||||
return Math.max(1, Math.round(pillHeight * 0.65))
|
||||
default:
|
||||
return Math.max(1, Math.round(pillHeight * 0.48))
|
||||
}
|
||||
}
|
||||
|
||||
readonly property real textSize: {
|
||||
switch (root.density) {
|
||||
case "compact":
|
||||
return Math.max(1, Math.round(pillHeight * 0.38))
|
||||
default:
|
||||
return Math.max(1, Math.round(pillHeight * 0.33))
|
||||
}
|
||||
}
|
||||
|
||||
// For vertical bars: width is just icon size, height includes pill space
|
||||
width: buttonSize
|
||||
@@ -79,11 +94,13 @@ Item {
|
||||
opacity: revealed ? Style.opacityFull : Style.opacityNone
|
||||
color: Settings.data.bar.showCapsule ? Color.mSurfaceVariant : Color.transparent
|
||||
|
||||
readonly property int halfButtonSize: Math.round(buttonSize * 0.5)
|
||||
|
||||
// Radius logic for vertical expansion - rounded on the side that connects to icon
|
||||
topLeftRadius: openUpward ? buttonSize * 0.5 : 0
|
||||
bottomLeftRadius: openDownward ? buttonSize * 0.5 : 0
|
||||
topRightRadius: openUpward ? buttonSize * 0.5 : 0
|
||||
bottomRightRadius: openDownward ? buttonSize * 0.5 : 0
|
||||
topLeftRadius: openUpward ? halfButtonSize : 0
|
||||
bottomLeftRadius: openDownward ? halfButtonSize : 0
|
||||
topRightRadius: openUpward ? halfButtonSize : 0
|
||||
bottomRightRadius: openDownward ? halfButtonSize : 0
|
||||
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
|
||||
@@ -92,16 +109,17 @@ Item {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.verticalCenterOffset: {
|
||||
var offset = openDownward ? pillPaddingVertical * 0.75 : -pillPaddingVertical * 0.75
|
||||
var offset = openDownward ? Math.round(pillPaddingVertical * 0.75) : -Math.round(pillPaddingVertical * 0.75)
|
||||
if (forceOpen) {
|
||||
// If its force open, the icon disc background is the same color as the bg pill move text slightly
|
||||
offset += rightOpen ? -Style.marginXXS * scaling : Style.marginXXS * scaling
|
||||
offset += rightOpen ? -Style.marginXXS : Style.marginXXS
|
||||
}
|
||||
return offset
|
||||
}
|
||||
text: root.text + root.suffix
|
||||
family: Settings.data.ui.fontFixed
|
||||
pointSize: textSize
|
||||
applyUiScale: false
|
||||
font.weight: Style.fontWeightMedium
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
@@ -154,6 +172,7 @@ Item {
|
||||
NIcon {
|
||||
icon: root.icon
|
||||
pointSize: iconSize
|
||||
applyUiScale: false
|
||||
color: hovered ? Color.mOnTertiary : Color.mOnSurface
|
||||
// Center horizontally
|
||||
x: (iconCircle.width - width) / 2
|
||||
|
||||
@@ -16,18 +16,8 @@ Item {
|
||||
implicitWidth: getImplicitSize(loader.item, "implicitWidth")
|
||||
implicitHeight: getImplicitSize(loader.item, "implicitHeight")
|
||||
|
||||
Connections {
|
||||
target: ScalingService
|
||||
enabled: loader.item && (loader.item.screen !== undefined)
|
||||
function onScaleChanged(aScreenName, scale) {
|
||||
if (loader.item && loader.item.screen && aScreenName === screenName) {
|
||||
loader.item['scaling'] = scale
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getImplicitSize(item, prop) {
|
||||
return (item && item.visible) ? item[prop] : 0
|
||||
return (item && item.visible) ? Math.round(item[prop]) : 0
|
||||
}
|
||||
|
||||
Loader {
|
||||
@@ -77,7 +67,7 @@ Item {
|
||||
// Error handling
|
||||
onWidgetIdChanged: {
|
||||
if (widgetId && !BarWidgetRegistry.hasWidget(widgetId)) {
|
||||
Logger.warn("BarWidgetLoader", "Widget not found in bar registry:", widgetId)
|
||||
Logger.warn("BarWidgetLoader", "Widget not found in registry:", widgetId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,23 +15,13 @@ PopupWindow {
|
||||
property bool isSubMenu: false
|
||||
property bool isHovered: rootMouseArea.containsMouse
|
||||
property ShellScreen screen
|
||||
property real scaling: ScalingService.getScreenScale(screen)
|
||||
|
||||
Connections {
|
||||
target: ScalingService
|
||||
function onScaleChanged(screenName, scale) {
|
||||
if ((screen != null) && (screenName === screen.name)) {
|
||||
scaling = scale
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
readonly property int menuWidth: 180
|
||||
|
||||
implicitWidth: menuWidth * scaling
|
||||
implicitWidth: menuWidth
|
||||
|
||||
// Use the content height of the Flickable for implicit height
|
||||
implicitHeight: Math.min(screen ? screen.height * 0.9 : Screen.height * 0.9, flickable.contentHeight + (Style.marginS * 2 * scaling))
|
||||
implicitHeight: Math.min(screen ? screen.height * 0.9 : Screen.height * 0.9, flickable.contentHeight + (Style.marginS * 2))
|
||||
visible: false
|
||||
color: Color.transparent
|
||||
anchor.item: anchorItem
|
||||
@@ -98,14 +88,14 @@ PopupWindow {
|
||||
anchors.fill: parent
|
||||
color: Color.mSurface
|
||||
border.color: Color.mOutline
|
||||
border.width: Math.max(1, Style.borderS * scaling)
|
||||
radius: Style.radiusM * scaling
|
||||
border.width: Math.max(1, Style.borderS)
|
||||
radius: Style.radiusM
|
||||
}
|
||||
|
||||
Flickable {
|
||||
id: flickable
|
||||
anchors.fill: parent
|
||||
anchors.margins: Style.marginS * scaling
|
||||
anchors.margins: Style.marginS
|
||||
contentHeight: columnLayout.implicitHeight
|
||||
interactive: true
|
||||
|
||||
@@ -125,11 +115,11 @@ PopupWindow {
|
||||
Layout.preferredWidth: parent.width
|
||||
Layout.preferredHeight: {
|
||||
if (modelData?.isSeparator) {
|
||||
return 8 * scaling
|
||||
return 8
|
||||
} else {
|
||||
// Calculate based on text content
|
||||
const textHeight = text.contentHeight || (Style.fontSizeS * scaling * 1.2)
|
||||
return Math.max(28 * scaling, textHeight + (Style.marginS * 2 * scaling))
|
||||
const textHeight = text.contentHeight || (Style.fontSizeS * 1.2)
|
||||
return Math.max(28, textHeight + (Style.marginS * 2))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,35 +128,35 @@ PopupWindow {
|
||||
|
||||
NDivider {
|
||||
anchors.centerIn: parent
|
||||
width: parent.width - (Style.marginM * scaling * 2)
|
||||
width: parent.width - (Style.marginM * 2)
|
||||
visible: modelData?.isSeparator ?? false
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: mouseArea.containsMouse ? Color.mTertiary : Color.transparent
|
||||
radius: Style.radiusS * scaling
|
||||
radius: Style.radiusS
|
||||
visible: !(modelData?.isSeparator ?? false)
|
||||
|
||||
RowLayout {
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: Style.marginM * scaling
|
||||
anchors.rightMargin: Style.marginM * scaling
|
||||
spacing: Style.marginS * scaling
|
||||
anchors.leftMargin: Style.marginM
|
||||
anchors.rightMargin: Style.marginM
|
||||
spacing: Style.marginS
|
||||
|
||||
NText {
|
||||
id: text
|
||||
Layout.fillWidth: true
|
||||
color: (modelData?.enabled ?? true) ? (mouseArea.containsMouse ? Color.mOnTertiary : Color.mOnSurface) : Color.mOnSurfaceVariant
|
||||
text: modelData?.text !== "" ? modelData?.text.replace(/[\n\r]+/g, ' ') : "..."
|
||||
pointSize: Style.fontSizeS * scaling
|
||||
pointSize: Style.fontSizeS
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
|
||||
Image {
|
||||
Layout.preferredWidth: Style.marginL * scaling
|
||||
Layout.preferredHeight: Style.marginL * scaling
|
||||
Layout.preferredWidth: Style.marginL
|
||||
Layout.preferredHeight: Style.marginL
|
||||
source: modelData?.icon ?? ""
|
||||
visible: (modelData?.icon ?? "") !== ""
|
||||
fillMode: Image.PreserveAspectFit
|
||||
@@ -174,7 +164,8 @@ PopupWindow {
|
||||
|
||||
NIcon {
|
||||
icon: modelData?.hasChildren ? "menu" : ""
|
||||
pointSize: Style.fontSizeS * scaling
|
||||
pointSize: Style.fontSizeS
|
||||
applyUiScale: false
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
visible: modelData?.hasChildren ?? false
|
||||
color: (mouseArea.containsMouse ? Color.mOnTertiary : Color.mOnSurface)
|
||||
@@ -216,8 +207,8 @@ PopupWindow {
|
||||
}
|
||||
|
||||
// Need a slight overlap so that menu don't close when moving the mouse to a submenu
|
||||
const submenuWidth = menuWidth * scaling // Assuming a similar width as the parent
|
||||
const overlap = 4 * scaling // A small overlap to bridge the mouse path
|
||||
const submenuWidth = menuWidth // Assuming a similar width as the parent
|
||||
const overlap = 4 // A small overlap to bridge the mouse path
|
||||
|
||||
// Determine submenu opening direction based on bar position and available space
|
||||
let openLeft = false
|
||||
|
||||
@@ -10,8 +10,8 @@ import qs.Widgets
|
||||
NPanel {
|
||||
id: root
|
||||
|
||||
preferredWidth: 400
|
||||
preferredHeight: 500
|
||||
preferredWidth: 400 * Style.uiScaleRatio
|
||||
preferredHeight: 500 * Style.uiScaleRatio
|
||||
panelKeyboardFocus: true
|
||||
|
||||
property string passwordSsid: ""
|
||||
@@ -25,23 +25,23 @@ NPanel {
|
||||
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
anchors.margins: Style.marginL * scaling
|
||||
spacing: Style.marginM * scaling
|
||||
anchors.margins: Style.marginL
|
||||
spacing: Style.marginM
|
||||
|
||||
// Header
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: Style.marginM * scaling
|
||||
spacing: Style.marginM
|
||||
|
||||
NIcon {
|
||||
icon: Settings.data.network.wifiEnabled ? "wifi" : "wifi-off"
|
||||
pointSize: Style.fontSizeXXL * scaling
|
||||
pointSize: Style.fontSizeXXL
|
||||
color: Settings.data.network.wifiEnabled ? Color.mPrimary : Color.mOnSurfaceVariant
|
||||
}
|
||||
|
||||
NText {
|
||||
text: I18n.tr("wifi.panel.title")
|
||||
pointSize: Style.fontSizeL * scaling
|
||||
pointSize: Style.fontSizeL
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Color.mOnSurface
|
||||
Layout.fillWidth: true
|
||||
@@ -51,7 +51,7 @@ NPanel {
|
||||
id: wifiSwitch
|
||||
checked: Settings.data.network.wifiEnabled
|
||||
onToggled: checked => NetworkService.setWifiEnabled(checked)
|
||||
baseSize: Style.baseWidgetSize * 0.65 * scaling
|
||||
baseSize: Style.baseWidgetSize * 0.65
|
||||
}
|
||||
|
||||
NIconButton {
|
||||
@@ -78,28 +78,28 @@ NPanel {
|
||||
Rectangle {
|
||||
visible: NetworkService.lastError.length > 0
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: errorRow.implicitHeight + (Style.marginM * scaling * 2)
|
||||
Layout.preferredHeight: errorRow.implicitHeight + (Style.marginM * 2)
|
||||
color: Qt.rgba(Color.mError.r, Color.mError.g, Color.mError.b, 0.1)
|
||||
radius: Style.radiusS * scaling
|
||||
border.width: Math.max(1, Style.borderS * scaling)
|
||||
radius: Style.radiusS
|
||||
border.width: Math.max(1, Style.borderS)
|
||||
border.color: Color.mError
|
||||
|
||||
RowLayout {
|
||||
id: errorRow
|
||||
anchors.fill: parent
|
||||
anchors.margins: Style.marginM * scaling
|
||||
spacing: Style.marginS * scaling
|
||||
anchors.margins: Style.marginM
|
||||
spacing: Style.marginS
|
||||
|
||||
NIcon {
|
||||
icon: "warning"
|
||||
pointSize: Style.fontSizeL * scaling
|
||||
pointSize: Style.fontSizeL
|
||||
color: Color.mError
|
||||
}
|
||||
|
||||
NText {
|
||||
text: NetworkService.lastError
|
||||
color: Color.mError
|
||||
pointSize: Style.fontSizeS * scaling
|
||||
pointSize: Style.fontSizeS
|
||||
wrapMode: Text.Wrap
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
@@ -122,7 +122,7 @@ NPanel {
|
||||
ColumnLayout {
|
||||
visible: !Settings.data.network.wifiEnabled
|
||||
anchors.fill: parent
|
||||
spacing: Style.marginM * scaling
|
||||
spacing: Style.marginM
|
||||
|
||||
Item {
|
||||
Layout.fillHeight: true
|
||||
@@ -130,21 +130,21 @@ NPanel {
|
||||
|
||||
NIcon {
|
||||
icon: "wifi-off"
|
||||
pointSize: 64 * scaling
|
||||
pointSize: 64
|
||||
color: Color.mOnSurfaceVariant
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
|
||||
NText {
|
||||
text: I18n.tr("wifi.panel.disabled")
|
||||
pointSize: Style.fontSizeL * scaling
|
||||
pointSize: Style.fontSizeL
|
||||
color: Color.mOnSurfaceVariant
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
|
||||
NText {
|
||||
text: I18n.tr("wifi.panel.enable-message")
|
||||
pointSize: Style.fontSizeS * scaling
|
||||
pointSize: Style.fontSizeS
|
||||
color: Color.mOnSurfaceVariant
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
@@ -158,7 +158,7 @@ NPanel {
|
||||
ColumnLayout {
|
||||
visible: Settings.data.network.wifiEnabled && NetworkService.scanning && Object.keys(NetworkService.networks).length === 0
|
||||
anchors.fill: parent
|
||||
spacing: Style.marginL * scaling
|
||||
spacing: Style.marginL
|
||||
|
||||
Item {
|
||||
Layout.fillHeight: true
|
||||
@@ -167,13 +167,13 @@ NPanel {
|
||||
NBusyIndicator {
|
||||
running: true
|
||||
color: Color.mPrimary
|
||||
size: Style.baseWidgetSize * scaling
|
||||
size: Style.baseWidgetSize
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
|
||||
NText {
|
||||
text: I18n.tr("wifi.panel.searching")
|
||||
pointSize: Style.fontSizeNormal * scaling
|
||||
pointSize: Style.fontSizeM
|
||||
color: Color.mOnSurfaceVariant
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
@@ -193,7 +193,7 @@ NPanel {
|
||||
|
||||
ColumnLayout {
|
||||
width: parent.width
|
||||
spacing: Style.marginM * scaling
|
||||
spacing: Style.marginM
|
||||
|
||||
// Network list
|
||||
Repeater {
|
||||
@@ -211,14 +211,14 @@ NPanel {
|
||||
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
implicitHeight: netColumn.implicitHeight + (Style.marginM * scaling * 2)
|
||||
radius: Style.radiusM * scaling
|
||||
implicitHeight: netColumn.implicitHeight + (Style.marginM * 2)
|
||||
radius: Style.radiusM
|
||||
|
||||
// Add opacity for operations in progress
|
||||
opacity: (NetworkService.disconnectingFrom === modelData.ssid || NetworkService.forgettingNetwork === modelData.ssid) ? 0.6 : 1.0
|
||||
|
||||
color: modelData.connected ? Qt.rgba(Color.mPrimary.r, Color.mPrimary.g, Color.mPrimary.b, 0.05) : Color.mSurface
|
||||
border.width: Math.max(1, Style.borderS * scaling)
|
||||
border.width: Math.max(1, Style.borderS)
|
||||
border.color: modelData.connected ? Color.mPrimary : Color.mOutline
|
||||
|
||||
// Smooth opacity animation
|
||||
@@ -230,29 +230,29 @@ NPanel {
|
||||
|
||||
ColumnLayout {
|
||||
id: netColumn
|
||||
width: parent.width - (Style.marginM * scaling * 2)
|
||||
x: Style.marginM * scaling
|
||||
y: Style.marginM * scaling
|
||||
spacing: Style.marginS * scaling
|
||||
width: parent.width - (Style.marginM * 2)
|
||||
x: Style.marginM
|
||||
y: Style.marginM
|
||||
spacing: Style.marginS
|
||||
|
||||
// Main row
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: Style.marginS * scaling
|
||||
spacing: Style.marginS
|
||||
|
||||
NIcon {
|
||||
icon: NetworkService.signalIcon(modelData.signal)
|
||||
pointSize: Style.fontSizeXXL * scaling
|
||||
pointSize: Style.fontSizeXXL
|
||||
color: modelData.connected ? Color.mPrimary : Color.mOnSurface
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: 2 * scaling
|
||||
spacing: 2
|
||||
|
||||
NText {
|
||||
text: modelData.ssid
|
||||
pointSize: Style.fontSizeNormal * scaling
|
||||
pointSize: Style.fontSizeM
|
||||
font.weight: modelData.connected ? Style.fontWeightBold : Style.fontWeightMedium
|
||||
color: Color.mOnSurface
|
||||
elide: Text.ElideRight
|
||||
@@ -260,30 +260,30 @@ NPanel {
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
spacing: Style.marginXS * scaling
|
||||
spacing: Style.marginXS
|
||||
|
||||
NText {
|
||||
text: I18n.tr("system.signal-strength", {
|
||||
"signal": modelData.signal
|
||||
})
|
||||
pointSize: Style.fontSizeXXS * scaling
|
||||
pointSize: Style.fontSizeXXS
|
||||
color: Color.mOnSurfaceVariant
|
||||
}
|
||||
|
||||
NText {
|
||||
text: "•"
|
||||
pointSize: Style.fontSizeXXS * scaling
|
||||
pointSize: Style.fontSizeXXS
|
||||
color: Color.mOnSurfaceVariant
|
||||
}
|
||||
|
||||
NText {
|
||||
text: NetworkService.isSecured(modelData.security) ? modelData.security : "Open"
|
||||
pointSize: Style.fontSizeXXS * scaling
|
||||
pointSize: Style.fontSizeXXS
|
||||
color: Color.mOnSurfaceVariant
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.preferredWidth: Style.marginXXS * scaling
|
||||
Layout.preferredWidth: Style.marginXXS
|
||||
}
|
||||
|
||||
// Update the status badges area (around line 237)
|
||||
@@ -291,14 +291,14 @@ NPanel {
|
||||
visible: modelData.connected && NetworkService.disconnectingFrom !== modelData.ssid
|
||||
color: Color.mPrimary
|
||||
radius: height * 0.5
|
||||
width: connectedText.implicitWidth + (Style.marginS * scaling * 2)
|
||||
height: connectedText.implicitHeight + (Style.marginXXS * scaling * 2)
|
||||
width: connectedText.implicitWidth + (Style.marginS * 2)
|
||||
height: connectedText.implicitHeight + (Style.marginXXS * 2)
|
||||
|
||||
NText {
|
||||
id: connectedText
|
||||
anchors.centerIn: parent
|
||||
text: I18n.tr("wifi.panel.connected")
|
||||
pointSize: Style.fontSizeXXS * scaling
|
||||
pointSize: Style.fontSizeXXS
|
||||
color: Color.mOnPrimary
|
||||
}
|
||||
}
|
||||
@@ -307,14 +307,14 @@ NPanel {
|
||||
visible: NetworkService.disconnectingFrom === modelData.ssid
|
||||
color: Color.mError
|
||||
radius: height * 0.5
|
||||
width: disconnectingText.implicitWidth + (Style.marginS * scaling * 2)
|
||||
height: disconnectingText.implicitHeight + (Style.marginXXS * scaling * 2)
|
||||
width: disconnectingText.implicitWidth + (Style.marginS * 2)
|
||||
height: disconnectingText.implicitHeight + (Style.marginXXS * 2)
|
||||
|
||||
NText {
|
||||
id: disconnectingText
|
||||
anchors.centerIn: parent
|
||||
text: I18n.tr("wifi.panel.disconnecting")
|
||||
pointSize: Style.fontSizeXXS * scaling
|
||||
pointSize: Style.fontSizeXXS
|
||||
color: Color.mOnPrimary
|
||||
}
|
||||
}
|
||||
@@ -323,14 +323,14 @@ NPanel {
|
||||
visible: NetworkService.forgettingNetwork === modelData.ssid
|
||||
color: Color.mError
|
||||
radius: height * 0.5
|
||||
width: forgettingText.implicitWidth + (Style.marginS * scaling * 2)
|
||||
height: forgettingText.implicitHeight + (Style.marginXXS * scaling * 2)
|
||||
width: forgettingText.implicitWidth + (Style.marginS * 2)
|
||||
height: forgettingText.implicitHeight + (Style.marginXXS * 2)
|
||||
|
||||
NText {
|
||||
id: forgettingText
|
||||
anchors.centerIn: parent
|
||||
text: I18n.tr("wifi.panel.forgetting")
|
||||
pointSize: Style.fontSizeXXS * scaling
|
||||
pointSize: Style.fontSizeXXS
|
||||
color: Color.mOnPrimary
|
||||
}
|
||||
}
|
||||
@@ -339,16 +339,16 @@ NPanel {
|
||||
visible: modelData.cached && !modelData.connected && NetworkService.forgettingNetwork !== modelData.ssid && NetworkService.disconnectingFrom !== modelData.ssid
|
||||
color: Color.transparent
|
||||
border.color: Color.mOutline
|
||||
border.width: Math.max(1, Style.borderS * scaling)
|
||||
border.width: Math.max(1, Style.borderS)
|
||||
radius: height * 0.5
|
||||
width: savedText.implicitWidth + (Style.marginS * scaling * 2)
|
||||
height: savedText.implicitHeight + (Style.marginXXS * scaling * 2)
|
||||
width: savedText.implicitWidth + (Style.marginS * 2)
|
||||
height: savedText.implicitHeight + (Style.marginXXS * 2)
|
||||
|
||||
NText {
|
||||
id: savedText
|
||||
anchors.centerIn: parent
|
||||
text: I18n.tr("wifi.panel.saved")
|
||||
pointSize: Style.fontSizeXXS * scaling
|
||||
pointSize: Style.fontSizeXXS
|
||||
color: Color.mOnSurfaceVariant
|
||||
}
|
||||
}
|
||||
@@ -357,13 +357,13 @@ NPanel {
|
||||
|
||||
// Action area
|
||||
RowLayout {
|
||||
spacing: Style.marginS * scaling
|
||||
spacing: Style.marginS
|
||||
|
||||
NBusyIndicator {
|
||||
visible: NetworkService.connectingTo === modelData.ssid || NetworkService.disconnectingFrom === modelData.ssid || NetworkService.forgettingNetwork === modelData.ssid
|
||||
running: visible
|
||||
color: Color.mPrimary
|
||||
size: Style.baseWidgetSize * 0.5 * scaling
|
||||
size: Style.baseWidgetSize * 0.5
|
||||
}
|
||||
|
||||
NIconButton {
|
||||
@@ -384,7 +384,7 @@ NPanel {
|
||||
return I18n.tr("wifi.panel.password")
|
||||
}
|
||||
outlined: !hovered
|
||||
fontSize: Style.fontSizeXS * scaling
|
||||
fontSize: Style.fontSizeXS
|
||||
enabled: !NetworkService.connecting
|
||||
onClicked: {
|
||||
if (modelData.existing || modelData.cached || !NetworkService.isSecured(modelData.security)) {
|
||||
@@ -401,7 +401,7 @@ NPanel {
|
||||
visible: modelData.connected && NetworkService.disconnectingFrom !== modelData.ssid
|
||||
text: I18n.tr("wifi.panel.disconnect")
|
||||
outlined: !hovered
|
||||
fontSize: Style.fontSizeXS * scaling
|
||||
fontSize: Style.fontSizeXS
|
||||
backgroundColor: Color.mError
|
||||
onClicked: NetworkService.disconnect(modelData.ssid)
|
||||
}
|
||||
@@ -412,35 +412,35 @@ NPanel {
|
||||
Rectangle {
|
||||
visible: passwordSsid === modelData.ssid && NetworkService.disconnectingFrom !== modelData.ssid && NetworkService.forgettingNetwork !== modelData.ssid
|
||||
Layout.fillWidth: true
|
||||
height: passwordRow.implicitHeight + Style.marginS * scaling * 2
|
||||
height: passwordRow.implicitHeight + Style.marginS * 2
|
||||
color: Color.mSurfaceVariant
|
||||
border.color: Color.mOutline
|
||||
border.width: Math.max(1, Style.borderS * scaling)
|
||||
radius: Style.radiusS * scaling
|
||||
border.width: Math.max(1, Style.borderS)
|
||||
radius: Style.radiusS
|
||||
|
||||
RowLayout {
|
||||
id: passwordRow
|
||||
anchors.fill: parent
|
||||
anchors.margins: Style.marginS * scaling
|
||||
spacing: Style.marginM * scaling
|
||||
anchors.margins: Style.marginS
|
||||
spacing: Style.marginM
|
||||
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
radius: Style.radiusXS * scaling
|
||||
radius: Style.radiusXS
|
||||
color: Color.mSurface
|
||||
border.color: pwdInput.activeFocus ? Color.mSecondary : Color.mOutline
|
||||
border.width: Math.max(1, Style.borderS * scaling)
|
||||
border.width: Math.max(1, Style.borderS)
|
||||
|
||||
TextInput {
|
||||
id: pwdInput
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.margins: Style.marginS * scaling
|
||||
anchors.margins: Style.marginS
|
||||
text: passwordInput
|
||||
font.family: Settings.data.ui.fontFixed
|
||||
font.pointSize: Style.fontSizeS * scaling
|
||||
font.pointSize: Style.fontSizeS
|
||||
color: Color.mOnSurface
|
||||
echoMode: TextInput.Password
|
||||
selectByMouse: true
|
||||
@@ -462,14 +462,14 @@ NPanel {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
text: I18n.tr("wifi.panel.enter-password")
|
||||
color: Color.mOnSurfaceVariant
|
||||
pointSize: Style.fontSizeS * scaling
|
||||
pointSize: Style.fontSizeS
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NButton {
|
||||
text: I18n.tr("wifi.panel.connect")
|
||||
fontSize: Style.fontSizeXXS * scaling
|
||||
fontSize: Style.fontSizeXXS
|
||||
enabled: passwordInput.length > 0 && !NetworkService.connecting
|
||||
outlined: true
|
||||
onClicked: {
|
||||
@@ -494,28 +494,28 @@ NPanel {
|
||||
Rectangle {
|
||||
visible: expandedSsid === modelData.ssid && NetworkService.disconnectingFrom !== modelData.ssid && NetworkService.forgettingNetwork !== modelData.ssid
|
||||
Layout.fillWidth: true
|
||||
height: forgetRow.implicitHeight + Style.marginS * 2 * scaling
|
||||
height: forgetRow.implicitHeight + Style.marginS * 2
|
||||
color: Color.mSurfaceVariant
|
||||
radius: Style.radiusS * scaling
|
||||
border.width: Math.max(1, Style.borderS * scaling)
|
||||
radius: Style.radiusS
|
||||
border.width: Math.max(1, Style.borderS)
|
||||
border.color: Color.mOutline
|
||||
|
||||
RowLayout {
|
||||
id: forgetRow
|
||||
anchors.fill: parent
|
||||
anchors.margins: Style.marginS * scaling
|
||||
spacing: Style.marginM * scaling
|
||||
anchors.margins: Style.marginS
|
||||
spacing: Style.marginM
|
||||
|
||||
RowLayout {
|
||||
NIcon {
|
||||
icon: "trash"
|
||||
pointSize: Style.fontSizeL * scaling
|
||||
pointSize: Style.fontSizeL
|
||||
color: Color.mError
|
||||
}
|
||||
|
||||
NText {
|
||||
text: I18n.tr("wifi.panel.forget-network")
|
||||
pointSize: Style.fontSizeS * scaling
|
||||
pointSize: Style.fontSizeS
|
||||
color: Color.mError
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
@@ -524,7 +524,7 @@ NPanel {
|
||||
NButton {
|
||||
id: forgetButton
|
||||
text: I18n.tr("wifi.panel.forget")
|
||||
fontSize: Style.fontSizeXXS * scaling
|
||||
fontSize: Style.fontSizeXXS
|
||||
backgroundColor: Color.mError
|
||||
outlined: forgetButton.hovered ? false : true
|
||||
onClicked: {
|
||||
@@ -550,7 +550,7 @@ NPanel {
|
||||
ColumnLayout {
|
||||
visible: Settings.data.network.wifiEnabled && !NetworkService.scanning && Object.keys(NetworkService.networks).length === 0
|
||||
anchors.fill: parent
|
||||
spacing: Style.marginL * scaling
|
||||
spacing: Style.marginL
|
||||
|
||||
Item {
|
||||
Layout.fillHeight: true
|
||||
@@ -558,14 +558,14 @@ NPanel {
|
||||
|
||||
NIcon {
|
||||
icon: "search"
|
||||
pointSize: 64 * scaling
|
||||
pointSize: 64
|
||||
color: Color.mOnSurfaceVariant
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
|
||||
NText {
|
||||
text: I18n.tr("wifi.panel.no-networks")
|
||||
pointSize: Style.fontSizeL * scaling
|
||||
pointSize: Style.fontSizeL
|
||||
color: Color.mOnSurfaceVariant
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
|
||||
@@ -10,8 +10,8 @@ import qs.Widgets
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
property ShellScreen screen
|
||||
property real scaling: 1.0
|
||||
|
||||
// Widget properties passed from Bar.qml for per-instance settings
|
||||
property string widgetId: ""
|
||||
@@ -30,23 +30,23 @@ Item {
|
||||
return {}
|
||||
}
|
||||
|
||||
readonly property bool hasActiveWindow: CompositorService.getFocusedWindowTitle() !== ""
|
||||
readonly property string windowTitle: CompositorService.getFocusedWindowTitle() || "No active window"
|
||||
readonly property string fallbackIcon: "user-desktop"
|
||||
|
||||
readonly property string barPosition: Settings.data.bar.position
|
||||
readonly property bool compact: (Settings.data.bar.density === "compact")
|
||||
|
||||
// Widget settings - matching MediaMini pattern
|
||||
readonly property bool showIcon: (widgetSettings.showIcon !== undefined) ? widgetSettings.showIcon : widgetMetadata.showIcon
|
||||
readonly property bool autoHide: (widgetSettings.autoHide !== undefined) ? widgetSettings.autoHide : widgetMetadata.autoHide
|
||||
readonly property string hideMode: (widgetSettings.hideMode !== undefined) ? widgetSettings.hideMode : widgetMetadata.hideMode
|
||||
readonly property string scrollingMode: (widgetSettings.scrollingMode !== undefined) ? widgetSettings.scrollingMode : (widgetMetadata.scrollingMode !== undefined ? widgetMetadata.scrollingMode : "hover")
|
||||
readonly property int widgetWidth: (widgetSettings.width !== undefined) ? widgetSettings.width : Math.max(widgetMetadata.width, screen.width * 0.06)
|
||||
|
||||
implicitHeight: visible ? ((barPosition === "left" || barPosition === "right") ? calculatedVerticalHeight() : Math.round(Style.barHeight * scaling)) : 0
|
||||
implicitWidth: visible ? ((barPosition === "left" || barPosition === "right") ? Math.round(Style.baseWidgetSize * 0.8 * scaling) : (widgetWidth * scaling)) : 0
|
||||
readonly property bool isVerticalBar: (Settings.data.bar.position === "left" || Settings.data.bar.position === "right")
|
||||
readonly property bool hasFocusedWindow: CompositorService.getFocusedWindow() !== null
|
||||
readonly property string windowTitle: CompositorService.getFocusedWindowTitle() || "No active window"
|
||||
readonly property string fallbackIcon: "user-desktop"
|
||||
|
||||
opacity: !autoHide || hasActiveWindow ? 1.0 : 0
|
||||
implicitHeight: visible ? (isVerticalBar ? calculatedVerticalDimension() : Style.barHeight) : 0
|
||||
implicitWidth: visible ? (isVerticalBar ? calculatedVerticalDimension() : widgetWidth) : 0
|
||||
|
||||
// "visible": Always Visible, "hidden": Hide When Empty, "transparent": Transparent When Empty
|
||||
visible: hideMode !== "hidden" || hasFocusedWindow
|
||||
opacity: hideMode !== "transparent" || hasFocusedWindow ? 1.0 : 0
|
||||
Behavior on opacity {
|
||||
NumberAnimation {
|
||||
duration: Style.animationNormal
|
||||
@@ -54,8 +54,9 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
function calculatedVerticalHeight() {
|
||||
return Math.round(Style.baseWidgetSize * 0.8 * scaling)
|
||||
function calculatedVerticalDimension() {
|
||||
const ratio = (Settings.data.bar.density === "mini") ? 0.67 : 0.8
|
||||
return Math.round(Style.baseWidgetSize * ratio)
|
||||
}
|
||||
|
||||
function getAppIcon() {
|
||||
@@ -106,7 +107,8 @@ Item {
|
||||
id: fullTitleMetrics
|
||||
visible: false
|
||||
text: windowTitle
|
||||
pointSize: Style.fontSizeS * scaling
|
||||
pointSize: Style.fontSizeS
|
||||
applyUiScale: false
|
||||
font.weight: Style.fontWeightMedium
|
||||
}
|
||||
|
||||
@@ -115,29 +117,29 @@ Item {
|
||||
visible: root.visible
|
||||
anchors.left: parent.left
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: (barPosition === "left" || barPosition === "right") ? Math.round(Style.baseWidgetSize * 0.8 * scaling) : (widgetWidth * scaling)
|
||||
height: (barPosition === "left" || barPosition === "right") ? Math.round(Style.baseWidgetSize * 0.8 * scaling) : Math.round(Style.capsuleHeight * scaling)
|
||||
radius: (barPosition === "left" || barPosition === "right") ? width / 2 : Math.round(Style.radiusM * scaling)
|
||||
width: isVerticalBar ? root.width : widgetWidth
|
||||
height: isVerticalBar ? width : Style.capsuleHeight
|
||||
radius: isVerticalBar ? width / 2 : Style.radiusM
|
||||
color: Settings.data.bar.showCapsule ? Color.mSurfaceVariant : Color.transparent
|
||||
|
||||
Item {
|
||||
id: mainContainer
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: (barPosition === "left" || barPosition === "right") ? 0 : Style.marginS * scaling
|
||||
anchors.rightMargin: (barPosition === "left" || barPosition === "right") ? 0 : Style.marginS * scaling
|
||||
anchors.leftMargin: isVerticalBar ? 0 : Style.marginS
|
||||
anchors.rightMargin: isVerticalBar ? 0 : Style.marginS
|
||||
|
||||
// Horizontal layout for top/bottom bars
|
||||
RowLayout {
|
||||
id: rowLayout
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: Style.marginS * scaling
|
||||
visible: barPosition === "top" || barPosition === "bottom"
|
||||
spacing: Style.marginS
|
||||
visible: !isVerticalBar
|
||||
z: 1
|
||||
|
||||
// Window icon
|
||||
Item {
|
||||
Layout.preferredWidth: Math.round(18 * scaling)
|
||||
Layout.preferredHeight: Math.round(18 * scaling)
|
||||
Layout.preferredWidth: 18
|
||||
Layout.preferredHeight: 18
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
visible: showIcon
|
||||
|
||||
@@ -148,6 +150,15 @@ Item {
|
||||
asynchronous: true
|
||||
smooth: true
|
||||
visible: source !== ""
|
||||
|
||||
// Apply dock shader to active window icon (always themed)
|
||||
layer.enabled: widgetSettings.colorizeIcons !== false
|
||||
layer.effect: ShaderEffect {
|
||||
property color targetColor: Color.mOnSurface
|
||||
property real colorizeMode: 0.0 // Dock mode (grayscale)
|
||||
|
||||
fragmentShader: Qt.resolvedUrl(Quickshell.shellDir + "/Shaders/qsb/appicon_colorize.frag.qsb")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -156,10 +167,10 @@ Item {
|
||||
id: titleContainer
|
||||
Layout.preferredWidth: {
|
||||
// Calculate available width based on other elements
|
||||
var iconWidth = (showIcon && windowIcon.visible ? (18 * scaling + Style.marginS * scaling) : 0)
|
||||
var totalMargins = Style.marginXXS * scaling * 2
|
||||
var iconWidth = (showIcon && windowIcon.visible ? (18 + Style.marginS) : 0)
|
||||
var totalMargins = Style.marginXXS * 2
|
||||
var availableWidth = mainContainer.width - iconWidth - totalMargins
|
||||
return Math.max(20 * scaling, availableWidth)
|
||||
return Math.max(20, availableWidth)
|
||||
}
|
||||
Layout.maximumWidth: Layout.preferredWidth
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
@@ -238,12 +249,13 @@ Item {
|
||||
x: scrollX
|
||||
|
||||
RowLayout {
|
||||
spacing: 50 * scaling // Gap between text copies
|
||||
spacing: 50 // Gap between text copies
|
||||
|
||||
NText {
|
||||
id: titleText
|
||||
text: windowTitle
|
||||
pointSize: Style.fontSizeS * scaling
|
||||
pointSize: Style.fontSizeS
|
||||
applyUiScale: false
|
||||
font.weight: Style.fontWeightMedium
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
color: Color.mOnSurface
|
||||
@@ -253,6 +265,8 @@ Item {
|
||||
NText {
|
||||
text: windowTitle
|
||||
font: titleText.font
|
||||
pointSize: Style.fontSizeS
|
||||
applyUiScale: false
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
color: Color.mOnSurface
|
||||
visible: titleContainer.needsScrolling && titleContainer.isScrolling
|
||||
@@ -275,7 +289,7 @@ Item {
|
||||
id: infiniteScroll
|
||||
running: titleContainer.isScrolling && !titleContainer.isResetting
|
||||
from: 0
|
||||
to: -(titleContainer.textWidth + 50 * scaling)
|
||||
to: -(titleContainer.textWidth + 50)
|
||||
duration: Math.max(4000, windowTitle.length * 100)
|
||||
loops: Animation.Infinite
|
||||
easing.type: Easing.Linear
|
||||
@@ -295,15 +309,15 @@ Item {
|
||||
Item {
|
||||
id: verticalLayout
|
||||
anchors.centerIn: parent
|
||||
width: parent.width - Style.marginM * scaling * 2
|
||||
height: parent.height - Style.marginM * scaling * 2
|
||||
visible: barPosition === "left" || barPosition === "right"
|
||||
width: parent.width - Style.marginM * 2
|
||||
height: parent.height - Style.marginM * 2
|
||||
visible: isVerticalBar
|
||||
z: 1
|
||||
|
||||
// Window icon
|
||||
Item {
|
||||
width: Style.baseWidgetSize * 0.5 * scaling
|
||||
height: Style.baseWidgetSize * 0.5 * scaling
|
||||
width: Style.baseWidgetSize * 0.5
|
||||
height: width
|
||||
anchors.centerIn: parent
|
||||
visible: windowTitle !== ""
|
||||
|
||||
@@ -314,6 +328,15 @@ Item {
|
||||
asynchronous: true
|
||||
smooth: true
|
||||
visible: source !== ""
|
||||
|
||||
// Apply dock shader to active window icon (always themed)
|
||||
layer.enabled: widgetSettings.colorizeIcons !== false
|
||||
layer.effect: ShaderEffect {
|
||||
property color targetColor: Color.mOnSurface
|
||||
property real colorizeMode: 0.0 // Dock mode (grayscale)
|
||||
|
||||
fragmentShader: Qt.resolvedUrl(Quickshell.shellDir + "/Shaders/qsb/appicon_colorize.frag.qsb")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -326,7 +349,7 @@ Item {
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
acceptedButtons: Qt.LeftButton
|
||||
onEntered: {
|
||||
if ((windowTitle !== "") && (barPosition === "left" || barPosition === "right") || (scrollingMode === "never")) {
|
||||
if ((windowTitle !== "") && isVerticalBar || (scrollingMode === "never")) {
|
||||
TooltipService.show(Screen, root, windowTitle, BarService.getTooltipDirection())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,6 @@ Item {
|
||||
id: root
|
||||
|
||||
property ShellScreen screen
|
||||
property real scaling: 1.0
|
||||
|
||||
// Widget properties passed from Bar.qml for per-instance settings
|
||||
property string widgetId: ""
|
||||
@@ -87,7 +86,7 @@ Item {
|
||||
BarPill {
|
||||
id: pill
|
||||
|
||||
compact: (Settings.data.bar.density === "compact")
|
||||
density: Settings.data.bar.density
|
||||
rightOpen: BarService.getPillDirection(root)
|
||||
icon: testMode ? BatteryService.getIcon(testPercent, testCharging, true) : BatteryService.getIcon(percent, charging, isReady)
|
||||
text: (isReady || testMode) ? Math.round(percent) : "-"
|
||||
|
||||
@@ -10,10 +10,11 @@ import qs.Widgets
|
||||
NIconButton {
|
||||
id: root
|
||||
|
||||
property real scaling: 1.0
|
||||
property ShellScreen screen
|
||||
|
||||
baseSize: Style.capsuleHeight
|
||||
compact: (Settings.data.bar.density === "compact")
|
||||
applyUiScale: false
|
||||
density: Settings.data.bar.density
|
||||
colorBg: Settings.data.bar.showCapsule ? Color.mSurfaceVariant : Color.transparent
|
||||
colorFg: Color.mOnSurface
|
||||
colorBorder: Color.transparent
|
||||
|
||||
@@ -10,7 +10,6 @@ Item {
|
||||
id: root
|
||||
|
||||
property ShellScreen screen
|
||||
property real scaling: 1.0
|
||||
|
||||
// Widget properties passed from Bar.qml for per-instance settings
|
||||
property string widgetId: ""
|
||||
@@ -77,7 +76,7 @@ Item {
|
||||
BarPill {
|
||||
id: pill
|
||||
|
||||
compact: (Settings.data.bar.density === "compact")
|
||||
density: Settings.data.bar.density
|
||||
rightOpen: BarService.getPillDirection(root)
|
||||
icon: getIcon()
|
||||
autoHide: false // Important to be false so we can hover as long as we want
|
||||
|
||||
@@ -9,7 +9,6 @@ Rectangle {
|
||||
id: root
|
||||
|
||||
property ShellScreen screen
|
||||
property real scaling: 1.0
|
||||
|
||||
// Widget properties passed from Bar.qml for per-instance settings
|
||||
property string widgetId: ""
|
||||
@@ -30,7 +29,7 @@ Rectangle {
|
||||
|
||||
readonly property string barPosition: Settings.data.bar.position
|
||||
readonly property bool isBarVertical: barPosition === "left" || barPosition === "right"
|
||||
readonly property bool compact: (Settings.data.bar.density === "compact")
|
||||
readonly property bool density: Settings.data.bar.density
|
||||
|
||||
readonly property var now: Time.date
|
||||
|
||||
@@ -41,11 +40,11 @@ Rectangle {
|
||||
readonly property string formatHorizontal: widgetSettings.formatHorizontal !== undefined ? widgetSettings.formatHorizontal : widgetMetadata.formatHorizontal
|
||||
readonly property string formatVertical: widgetSettings.formatVertical !== undefined ? widgetSettings.formatVertical : widgetMetadata.formatVertical
|
||||
|
||||
implicitWidth: isBarVertical ? Math.round(Style.capsuleHeight * scaling) : Math.round((isBarVertical ? verticalLoader.implicitWidth : horizontalLoader.implicitWidth) + Style.marginM * 2 * scaling)
|
||||
implicitWidth: isBarVertical ? Style.capsuleHeight : Math.round((isBarVertical ? verticalLoader.implicitWidth : horizontalLoader.implicitWidth) + Style.marginM * 2)
|
||||
|
||||
implicitHeight: isBarVertical ? Math.round(verticalLoader.implicitHeight + Style.marginS * 2 * scaling) : Math.round(Style.capsuleHeight * scaling)
|
||||
implicitHeight: isBarVertical ? Math.round(verticalLoader.implicitHeight + Style.marginS * 2) : Style.capsuleHeight
|
||||
|
||||
radius: Math.round(Style.radiusS * scaling)
|
||||
radius: Style.radiusS
|
||||
color: Settings.data.bar.showCapsule ? Color.mSurfaceVariant : Color.transparent
|
||||
|
||||
Item {
|
||||
@@ -59,7 +58,7 @@ Rectangle {
|
||||
anchors.centerIn: parent
|
||||
sourceComponent: ColumnLayout {
|
||||
anchors.centerIn: parent
|
||||
spacing: Settings.data.bar.showCapsule ? -4 * scaling : -2 * scaling
|
||||
spacing: Settings.data.bar.showCapsule ? -4 : -2
|
||||
Repeater {
|
||||
id: repeater
|
||||
model: Qt.locale().toString(now, formatHorizontal.trim()).split("\\n")
|
||||
@@ -69,11 +68,12 @@ Rectangle {
|
||||
family: useCustomFont && customFont ? customFont : Settings.data.ui.fontDefault
|
||||
pointSize: {
|
||||
if (repeater.model.length == 1) {
|
||||
return Style.fontSizeS * scaling
|
||||
return Style.fontSizeS
|
||||
} else {
|
||||
return (index == 0) ? Style.fontSizeXS * scaling : Style.fontSizeXXS * scaling
|
||||
return (index == 0) ? Style.fontSizeXS : Style.fontSizeXXS
|
||||
}
|
||||
}
|
||||
applyUiScale: false
|
||||
font.weight: Style.fontWeightBold
|
||||
color: usePrimaryColor ? Color.mPrimary : Color.mOnSurface
|
||||
wrapMode: Text.WordWrap
|
||||
@@ -90,14 +90,15 @@ Rectangle {
|
||||
anchors.centerIn: parent // Now this works without layout conflicts
|
||||
sourceComponent: ColumnLayout {
|
||||
anchors.centerIn: parent
|
||||
spacing: -2 * scaling
|
||||
spacing: -2
|
||||
Repeater {
|
||||
model: Qt.locale().toString(now, formatVertical.trim()).split(" ")
|
||||
delegate: NText {
|
||||
visible: text !== ""
|
||||
text: modelData
|
||||
family: useCustomFont && customFont ? customFont : Settings.data.ui.fontDefault
|
||||
pointSize: Style.fontSizeS * scaling
|
||||
pointSize: Style.fontSizeS
|
||||
applyUiScale: false
|
||||
font.weight: Style.fontWeightBold
|
||||
color: usePrimaryColor ? Color.mPrimary : Color.mOnSurface
|
||||
wrapMode: Text.WordWrap
|
||||
|
||||
@@ -9,7 +9,7 @@ import qs.Services
|
||||
NIconButton {
|
||||
id: root
|
||||
|
||||
property real scaling: 1.0
|
||||
property ShellScreen screen
|
||||
|
||||
// Widget properties passed from Bar.qml for per-instance settings
|
||||
property string widgetId: ""
|
||||
@@ -37,7 +37,8 @@ NIconButton {
|
||||
tooltipText: I18n.tr("tooltips.open-control-center")
|
||||
tooltipDirection: BarService.getTooltipDirection()
|
||||
baseSize: Style.capsuleHeight
|
||||
compact: (Settings.data.bar.density === "compact")
|
||||
applyUiScale: false
|
||||
density: Settings.data.bar.density
|
||||
colorBg: (Settings.data.bar.showCapsule ? Color.mSurfaceVariant : Color.transparent)
|
||||
colorFg: Color.mOnSurface
|
||||
colorBgHover: useDistroLogo ? Color.mSurfaceVariant : Color.mTertiary
|
||||
|
||||
@@ -11,9 +11,7 @@ import qs.Modules.Bar.Extras
|
||||
Item {
|
||||
id: root
|
||||
|
||||
// Widget properties passed from Bar.qml
|
||||
property var screen
|
||||
property real scaling: 1.0
|
||||
property ShellScreen screen
|
||||
|
||||
// Widget properties passed from Bar.qml for per-instance settings
|
||||
property string widgetId: ""
|
||||
@@ -50,7 +48,7 @@ Item {
|
||||
rightOpen: BarService.getPillDirection(root)
|
||||
icon: customIcon
|
||||
text: _dynamicText
|
||||
compact: (Settings.data.bar.density === "compact")
|
||||
density: Settings.data.bar.density
|
||||
autoHide: false
|
||||
forceOpen: _dynamicText !== ""
|
||||
forceClose: false
|
||||
|
||||
@@ -6,13 +6,14 @@ import qs.Services
|
||||
NIconButton {
|
||||
id: root
|
||||
|
||||
property real scaling: 1.0
|
||||
property ShellScreen screen
|
||||
|
||||
icon: "dark-mode"
|
||||
tooltipText: Settings.data.colorSchemes.darkMode ? I18n.tr("tooltips.switch-to-light-mode") : I18n.tr("tooltips.switch-to-dark-mode")
|
||||
tooltipDirection: BarService.getTooltipDirection()
|
||||
compact: (Settings.data.bar.density === "compact")
|
||||
density: Settings.data.bar.density
|
||||
baseSize: Style.capsuleHeight
|
||||
applyUiScale: false
|
||||
colorBg: Settings.data.colorSchemes.darkMode ? (Settings.data.bar.showCapsule ? Color.mSurfaceVariant : Color.transparent) : Color.mPrimary
|
||||
colorFg: Settings.data.colorSchemes.darkMode ? Color.mOnSurface : Color.mOnPrimary
|
||||
colorBorder: Color.transparent
|
||||
|
||||
@@ -8,10 +8,11 @@ import qs.Widgets
|
||||
NIconButton {
|
||||
id: root
|
||||
|
||||
property real scaling: 1.0
|
||||
property ShellScreen screen
|
||||
|
||||
baseSize: Style.capsuleHeight
|
||||
compact: (Settings.data.bar.density === "compact")
|
||||
applyUiScale: false
|
||||
density: Settings.data.bar.density
|
||||
icon: IdleInhibitorService.isInhibited ? "keep-awake-on" : "keep-awake-off"
|
||||
tooltipText: IdleInhibitorService.isInhibited ? I18n.tr("tooltips.disable-keep-awake") : I18n.tr("tooltips.enable-keep-awake")
|
||||
tooltipDirection: BarService.getTooltipDirection()
|
||||
|
||||
@@ -12,7 +12,6 @@ Item {
|
||||
id: root
|
||||
|
||||
property ShellScreen screen
|
||||
property real scaling: 1.0
|
||||
|
||||
// Widget properties passed from Bar.qml for per-instance settings
|
||||
property string widgetId: ""
|
||||
@@ -43,7 +42,7 @@ Item {
|
||||
id: pill
|
||||
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
compact: (Settings.data.bar.density === "compact")
|
||||
density: Settings.data.bar.density
|
||||
rightOpen: BarService.getPillDirection(root)
|
||||
icon: "keyboard"
|
||||
autoHide: false // Important to be false so we can hover as long as we want
|
||||
|
||||
@@ -11,7 +11,6 @@ Item {
|
||||
id: root
|
||||
|
||||
property ShellScreen screen
|
||||
property real scaling: 1.0
|
||||
|
||||
// Widget properties passed from Bar.qml for per-instance settings
|
||||
property string widgetId: ""
|
||||
@@ -30,10 +29,9 @@ Item {
|
||||
return {}
|
||||
}
|
||||
|
||||
readonly property string barPosition: Settings.data.bar.position
|
||||
readonly property bool compact: (Settings.data.bar.density === "compact")
|
||||
readonly property bool isVerticalBar: (Settings.data.bar.position === "left" || Settings.data.bar.position === "right")
|
||||
|
||||
readonly property bool autoHide: (widgetSettings.autoHide !== undefined) ? widgetSettings.autoHide : widgetMetadata.autoHide
|
||||
readonly property string hideMode: (widgetSettings.hideMode !== undefined) ? widgetSettings.hideMode : "hidden" // "visible", "hidden", "transparent"
|
||||
readonly property bool showAlbumArt: (widgetSettings.showAlbumArt !== undefined) ? widgetSettings.showAlbumArt : widgetMetadata.showAlbumArt
|
||||
readonly property bool showVisualizer: (widgetSettings.showVisualizer !== undefined) ? widgetSettings.showVisualizer : widgetMetadata.showVisualizer
|
||||
readonly property string visualizerType: (widgetSettings.visualizerType !== undefined && widgetSettings.visualizerType !== "") ? widgetSettings.visualizerType : widgetMetadata.visualizerType
|
||||
@@ -42,7 +40,7 @@ Item {
|
||||
// Fixed width - no expansion
|
||||
readonly property real widgetWidth: Math.max(145, screen.width * 0.06)
|
||||
|
||||
readonly property bool hasActivePlayer: MediaService.currentPlayer !== null && getTitle() !== ""
|
||||
readonly property bool hasActivePlayer: MediaService.currentPlayer !== null
|
||||
readonly property string placeholderText: I18n.tr("bar.widget-settings.media-mini.no-active-player")
|
||||
|
||||
readonly property string tooltipText: {
|
||||
@@ -60,10 +58,12 @@ Item {
|
||||
return title
|
||||
}
|
||||
|
||||
implicitHeight: visible ? ((barPosition === "left" || barPosition === "right") ? calculatedVerticalHeight() : Math.round(Style.barHeight * scaling)) : 0
|
||||
implicitWidth: visible ? ((barPosition === "left" || barPosition === "right") ? Math.round(Style.baseWidgetSize * 0.8 * scaling) : (widgetWidth * scaling)) : 0
|
||||
implicitHeight: visible ? (isVerticalBar ? calculatedVerticalDimension() : Style.barHeight) : 0
|
||||
implicitWidth: visible ? (isVerticalBar ? calculatedVerticalDimension() : widgetWidth) : 0
|
||||
|
||||
opacity: !autoHide || hasActivePlayer || (!hasActivePlayer && !autoHide) ? 1.0 : 0
|
||||
// "visible": Always Visible, "hidden": Hide When Empty, "transparent": Transparent When Empty
|
||||
visible: hideMode !== "hidden" || hasActivePlayer
|
||||
opacity: hideMode !== "transparent" || hasActivePlayer ? 1.0 : 0
|
||||
Behavior on opacity {
|
||||
NumberAnimation {
|
||||
duration: Style.animationNormal
|
||||
@@ -75,8 +75,9 @@ Item {
|
||||
return MediaService.trackTitle + (MediaService.trackArtist !== "" ? ` - ${MediaService.trackArtist}` : "")
|
||||
}
|
||||
|
||||
function calculatedVerticalHeight() {
|
||||
return Math.round(Style.baseWidgetSize * 0.8 * scaling)
|
||||
function calculatedVerticalDimension() {
|
||||
const ratio = (Settings.data.bar.density === "mini") ? 0.67 : 0.8
|
||||
return Math.round(Style.baseWidgetSize * ratio)
|
||||
}
|
||||
|
||||
// A hidden text element to safely measure the full title width
|
||||
@@ -85,6 +86,7 @@ Item {
|
||||
visible: false
|
||||
text: titleText.text
|
||||
font: titleText.font
|
||||
applyUiScale: false
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
@@ -92,16 +94,16 @@ Item {
|
||||
visible: root.visible
|
||||
anchors.left: parent.left
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: (barPosition === "left" || barPosition === "right") ? Math.round(Style.baseWidgetSize * 0.8 * scaling) : (widgetWidth * scaling)
|
||||
height: (barPosition === "left" || barPosition === "right") ? Math.round(Style.baseWidgetSize * 0.8 * scaling) : Math.round(Style.capsuleHeight * scaling)
|
||||
radius: (barPosition === "left" || barPosition === "right") ? width / 2 : Math.round(Style.radiusM * scaling)
|
||||
width: isVerticalBar ? root.width : (widgetWidth)
|
||||
height: isVerticalBar ? width : Style.capsuleHeight
|
||||
radius: isVerticalBar ? width / 2 : Style.radiusM
|
||||
color: Settings.data.bar.showCapsule ? Color.mSurfaceVariant : Color.transparent
|
||||
|
||||
Item {
|
||||
id: mainContainer
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: (barPosition === "left" || barPosition === "right") ? 0 : Style.marginS * scaling
|
||||
anchors.rightMargin: (barPosition === "left" || barPosition === "right") ? 0 : Style.marginS * scaling
|
||||
anchors.leftMargin: isVerticalBar ? 0 : Style.marginS
|
||||
anchors.rightMargin: isVerticalBar ? 0 : Style.marginS
|
||||
|
||||
Loader {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
@@ -110,8 +112,8 @@ Item {
|
||||
z: 0
|
||||
|
||||
sourceComponent: LinearSpectrum {
|
||||
width: mainContainer.width - Style.marginS * scaling
|
||||
height: 20 * scaling
|
||||
width: mainContainer.width - Style.marginS
|
||||
height: 20
|
||||
values: CavaService.values
|
||||
fillColor: Color.mPrimary
|
||||
opacity: 0.4
|
||||
@@ -125,8 +127,8 @@ Item {
|
||||
z: 0
|
||||
|
||||
sourceComponent: MirroredSpectrum {
|
||||
width: mainContainer.width - Style.marginS * scaling
|
||||
height: mainContainer.height - Style.marginS * scaling
|
||||
width: mainContainer.width - Style.marginS
|
||||
height: mainContainer.height - Style.marginS
|
||||
values: CavaService.values
|
||||
fillColor: Color.mPrimary
|
||||
opacity: 0.4
|
||||
@@ -140,8 +142,8 @@ Item {
|
||||
z: 0
|
||||
|
||||
sourceComponent: WaveSpectrum {
|
||||
width: mainContainer.width - Style.marginS * scaling
|
||||
height: mainContainer.height - Style.marginS * scaling
|
||||
width: mainContainer.width - Style.marginS
|
||||
height: mainContainer.height - Style.marginS
|
||||
values: CavaService.values
|
||||
fillColor: Color.mPrimary
|
||||
opacity: 0.4
|
||||
@@ -153,15 +155,15 @@ Item {
|
||||
id: rowLayout
|
||||
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: Style.marginS * scaling
|
||||
visible: (barPosition === "top" || barPosition === "bottom")
|
||||
spacing: Style.marginS
|
||||
visible: !isVerticalBar
|
||||
z: 1 // Above the visualizer
|
||||
|
||||
NIcon {
|
||||
id: windowIcon
|
||||
icon: hasActivePlayer ? (MediaService.isPlaying ? "media-pause" : "media-play") : "disc"
|
||||
color: hasActivePlayer ? Color.mOnSurface : Color.mOnSurfaceVariant
|
||||
pointSize: Style.fontSizeL * scaling
|
||||
pointSize: Style.fontSizeL
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
visible: !hasActivePlayer || (!showAlbumArt && !trackArt.visible)
|
||||
@@ -173,15 +175,15 @@ Item {
|
||||
spacing: 0
|
||||
|
||||
Item {
|
||||
Layout.preferredWidth: Math.round(21 * scaling)
|
||||
Layout.preferredHeight: Math.round(21 * scaling)
|
||||
Layout.preferredWidth: Math.round(21 * Style.uiScaleRatio)
|
||||
Layout.preferredHeight: Math.round(21 * Style.uiScaleRatio)
|
||||
|
||||
NImageCircled {
|
||||
id: trackArt
|
||||
anchors.fill: parent
|
||||
imagePath: MediaService.trackArtUrl
|
||||
fallbackIcon: MediaService.isPlaying ? "media-pause" : "media-play"
|
||||
fallbackIconSize: 10 * scaling
|
||||
fallbackIconSize: 10
|
||||
borderWidth: 0
|
||||
border.color: Color.transparent
|
||||
}
|
||||
@@ -192,11 +194,11 @@ Item {
|
||||
id: titleContainer
|
||||
Layout.preferredWidth: {
|
||||
// Calculate available width based on other elements in the row
|
||||
var iconWidth = (windowIcon.visible ? (Style.fontSizeL * scaling + Style.marginS * scaling) : 0)
|
||||
var albumArtWidth = (hasActivePlayer && showAlbumArt ? (18 * scaling + Style.marginS * scaling) : 0)
|
||||
var totalMargins = Style.marginXXS * scaling * 2
|
||||
var iconWidth = (windowIcon.visible ? (Style.fontSizeL + Style.marginS) : 0)
|
||||
var albumArtWidth = (hasActivePlayer && showAlbumArt ? (18 + Style.marginS) : 0)
|
||||
var totalMargins = Style.marginXXS * 2
|
||||
var availableWidth = mainContainer.width - iconWidth - albumArtWidth - totalMargins
|
||||
return Math.max(20 * scaling, availableWidth)
|
||||
return Math.max(20, availableWidth)
|
||||
}
|
||||
Layout.maximumWidth: Layout.preferredWidth
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
@@ -281,12 +283,13 @@ Item {
|
||||
x: scrollX
|
||||
|
||||
RowLayout {
|
||||
spacing: 50 * scaling // Gap between text copies
|
||||
spacing: 50 // Gap between text copies
|
||||
|
||||
NText {
|
||||
id: titleText
|
||||
text: hasActivePlayer ? getTitle() : placeholderText
|
||||
pointSize: Style.fontSizeS * scaling
|
||||
pointSize: Style.fontSizeS
|
||||
applyUiScale: false
|
||||
font.weight: Style.fontWeightMedium
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: hasActivePlayer ? Text.AlignLeft : Text.AlignHCenter
|
||||
@@ -296,6 +299,7 @@ Item {
|
||||
NText {
|
||||
text: hasActivePlayer ? getTitle() : placeholderText
|
||||
font: titleText.font
|
||||
applyUiScale: false
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: hasActivePlayer ? Text.AlignLeft : Text.AlignHCenter
|
||||
color: hasActivePlayer ? Color.mOnSurface : Color.mOnSurfaceVariant
|
||||
@@ -319,7 +323,7 @@ Item {
|
||||
id: infiniteScroll
|
||||
running: titleContainer.isScrolling && !titleContainer.isResetting
|
||||
from: 0
|
||||
to: -(titleContainer.textWidth + 50 * scaling) // Scroll one complete text width + gap
|
||||
to: -(titleContainer.textWidth + 50) // Scroll one complete text width + gap
|
||||
duration: Math.max(4000, getTitle().length * 120)
|
||||
loops: Animation.Infinite
|
||||
easing.type: Easing.Linear
|
||||
@@ -339,15 +343,15 @@ Item {
|
||||
Item {
|
||||
id: verticalLayout
|
||||
anchors.centerIn: parent
|
||||
width: parent.width - Style.marginM * scaling * 2
|
||||
height: parent.height - Style.marginM * scaling * 2
|
||||
visible: barPosition === "left" || barPosition === "right"
|
||||
width: parent.width - Style.marginM * 2
|
||||
height: parent.height - Style.marginM * 2
|
||||
visible: isVerticalBar
|
||||
z: 1 // Above the visualizer
|
||||
|
||||
// Media icon
|
||||
Item {
|
||||
width: Style.baseWidgetSize * 0.5 * scaling
|
||||
height: Style.baseWidgetSize * 0.5 * scaling
|
||||
width: Style.baseWidgetSize * 0.5
|
||||
height: width
|
||||
anchors.centerIn: parent
|
||||
|
||||
NIcon {
|
||||
@@ -355,7 +359,7 @@ Item {
|
||||
anchors.fill: parent
|
||||
icon: hasActivePlayer ? (MediaService.isPlaying ? "media-pause" : "media-play") : "disc"
|
||||
color: hasActivePlayer ? Color.mOnSurface : Color.mOnSurfaceVariant
|
||||
pointSize: Style.fontSizeL * scaling
|
||||
pointSize: Style.fontSizeL
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
}
|
||||
@@ -387,7 +391,7 @@ Item {
|
||||
|
||||
onEntered: {
|
||||
var textToShow = hasActivePlayer ? tooltipText : placeholderText
|
||||
if ((textToShow !== "") && (barPosition === "left" || barPosition === "right") || (scrollingMode === "never")) {
|
||||
if ((textToShow !== "") && isVerticalBar || (scrollingMode === "never")) {
|
||||
TooltipService.show(Screen, root, textToShow, BarService.getTooltipDirection())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@ Item {
|
||||
id: root
|
||||
|
||||
property ShellScreen screen
|
||||
property real scaling: 1.0
|
||||
|
||||
// Widget properties passed from Bar.qml for per-instance settings
|
||||
property string widgetId: ""
|
||||
@@ -92,7 +91,7 @@ Item {
|
||||
|
||||
rightOpen: BarService.getPillDirection(root)
|
||||
icon: getIcon()
|
||||
compact: (Settings.data.bar.density === "compact")
|
||||
density: Settings.data.bar.density
|
||||
autoHide: false // Important to be false so we can hover as long as we want
|
||||
text: Math.round(AudioService.inputVolume * 100)
|
||||
suffix: "%"
|
||||
|
||||
@@ -11,10 +11,11 @@ import qs.Widgets
|
||||
NIconButton {
|
||||
id: root
|
||||
|
||||
property real scaling: 1.0
|
||||
property ShellScreen screen
|
||||
|
||||
compact: (Settings.data.bar.density === "compact")
|
||||
density: Settings.data.bar.density
|
||||
baseSize: Style.capsuleHeight
|
||||
applyUiScale: false
|
||||
colorBg: Settings.data.nightLight.forced ? Color.mPrimary : (Settings.data.bar.showCapsule ? Color.mSurfaceVariant : Color.transparent)
|
||||
colorFg: Settings.data.nightLight.forced ? Color.mOnPrimary : Color.mOnSurface
|
||||
colorBorder: Color.transparent
|
||||
|
||||
@@ -10,7 +10,7 @@ import qs.Widgets
|
||||
NIconButton {
|
||||
id: root
|
||||
|
||||
property real scaling: 1.0
|
||||
property ShellScreen screen
|
||||
|
||||
// Widget properties passed from Bar.qml for per-instance settings
|
||||
property string widgetId: ""
|
||||
@@ -49,7 +49,8 @@ NIconButton {
|
||||
}
|
||||
|
||||
baseSize: Style.capsuleHeight
|
||||
compact: (Settings.data.bar.density === "compact")
|
||||
applyUiScale: false
|
||||
density: Settings.data.bar.density
|
||||
icon: Settings.data.notifications.doNotDisturb ? "bell-off" : "bell"
|
||||
tooltipText: Settings.data.notifications.doNotDisturb ? I18n.tr("tooltips.open-notification-history-disable-dnd") : I18n.tr("tooltips.open-notification-history-enable-dnd")
|
||||
tooltipDirection: BarService.getTooltipDirection()
|
||||
@@ -68,14 +69,14 @@ NIconButton {
|
||||
Loader {
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
anchors.rightMargin: 2 * scaling
|
||||
anchors.topMargin: 1 * scaling
|
||||
anchors.rightMargin: 2
|
||||
anchors.topMargin: 1
|
||||
z: 2
|
||||
active: showUnreadBadge && (!hideWhenZero || computeUnreadCount() > 0)
|
||||
sourceComponent: Rectangle {
|
||||
id: badge
|
||||
readonly property int count: computeUnreadCount()
|
||||
height: 8 * scaling
|
||||
height: 8
|
||||
width: height
|
||||
radius: height / 2
|
||||
color: Color.mError
|
||||
|
||||
@@ -9,17 +9,17 @@ import qs.Widgets
|
||||
NIconButton {
|
||||
id: root
|
||||
|
||||
property real scaling: 1.0
|
||||
property ShellScreen screen
|
||||
|
||||
baseSize: Style.capsuleHeight
|
||||
applyUiScale: false
|
||||
density: Settings.data.bar.density
|
||||
visible: PowerProfileService.available
|
||||
|
||||
icon: PowerProfileService.getIcon()
|
||||
tooltipText: I18n.tr("tooltips.power-profile", {
|
||||
"profile": PowerProfileService.getName()
|
||||
})
|
||||
tooltipDirection: BarService.getTooltipDirection()
|
||||
compact: (Settings.data.bar.density === "compact")
|
||||
colorBg: (PowerProfileService.profile === PowerProfile.Balanced) ? (Settings.data.bar.showCapsule ? Color.mSurfaceVariant : Color.transparent) : Color.mPrimary
|
||||
colorFg: (PowerProfileService.profile === PowerProfile.Balanced) ? Color.mOnSurface : Color.mOnPrimary
|
||||
colorBorder: Color.transparent
|
||||
|
||||
@@ -7,13 +7,14 @@ import qs.Widgets
|
||||
NIconButton {
|
||||
id: root
|
||||
|
||||
property real scaling: 1.0
|
||||
property ShellScreen screen
|
||||
|
||||
icon: "camera-video"
|
||||
tooltipText: ScreenRecorderService.isRecording ? I18n.tr("tooltips.click-to-stop-recording") : I18n.tr("tooltips.click-to-start-recording")
|
||||
tooltipDirection: BarService.getTooltipDirection()
|
||||
compact: (Settings.data.bar.density === "compact")
|
||||
density: Settings.data.bar.density
|
||||
baseSize: Style.capsuleHeight
|
||||
applyUiScale: false
|
||||
colorBg: ScreenRecorderService.isRecording ? Color.mPrimary : (Settings.data.bar.showCapsule ? Color.mSurfaceVariant : Color.transparent)
|
||||
colorFg: ScreenRecorderService.isRecording ? Color.mOnPrimary : Color.mOnSurface
|
||||
colorBorder: Color.transparent
|
||||
|
||||
@@ -8,10 +8,11 @@ import qs.Widgets
|
||||
NIconButton {
|
||||
id: root
|
||||
|
||||
property real scaling: 1.0
|
||||
property ShellScreen screen
|
||||
|
||||
compact: (Settings.data.bar.density === "compact")
|
||||
density: Settings.data.bar.density
|
||||
baseSize: Style.capsuleHeight
|
||||
applyUiScale: false
|
||||
icon: "power"
|
||||
tooltipText: I18n.tr("tooltips.session-menu")
|
||||
tooltipDirection: BarService.getTooltipDirection()
|
||||
|
||||
@@ -8,9 +8,7 @@ import qs.Widgets
|
||||
Item {
|
||||
id: root
|
||||
|
||||
// Widget properties passed from Bar.qml
|
||||
property var screen
|
||||
property real scaling: 1.0
|
||||
property ShellScreen screen
|
||||
|
||||
// Widget properties passed from Bar.qml for per-instance settings
|
||||
property string widgetId: ""
|
||||
@@ -33,8 +31,8 @@ Item {
|
||||
readonly property int spacerWidth: widgetSettings.width !== undefined ? widgetSettings.width : widgetMetadata.width
|
||||
|
||||
// Set the width based on user settings
|
||||
implicitWidth: spacerWidth * scaling
|
||||
implicitHeight: Style.barHeight * scaling
|
||||
implicitWidth: spacerWidth
|
||||
implicitHeight: Style.barHeight
|
||||
width: implicitWidth
|
||||
height: implicitHeight
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@ Rectangle {
|
||||
id: root
|
||||
|
||||
property ShellScreen screen
|
||||
property real scaling: 1.0
|
||||
|
||||
// Widget properties passed from Bar.qml for per-instance settings
|
||||
property string widgetId: ""
|
||||
@@ -30,7 +29,7 @@ Rectangle {
|
||||
|
||||
readonly property string barPosition: Settings.data.bar.position
|
||||
readonly property bool isVertical: barPosition === "left" || barPosition === "right"
|
||||
readonly property bool compact: (Settings.data.bar.density === "compact")
|
||||
readonly property bool density: Settings.data.bar.density
|
||||
|
||||
readonly property bool showCpuUsage: (widgetSettings.showCpuUsage !== undefined) ? widgetSettings.showCpuUsage : widgetMetadata.showCpuUsage
|
||||
readonly property bool showCpuTemp: (widgetSettings.showCpuTemp !== undefined) ? widgetSettings.showCpuTemp : widgetMetadata.showCpuTemp
|
||||
@@ -42,12 +41,12 @@ Rectangle {
|
||||
readonly property real iconSize: textSize * 1.4
|
||||
readonly property real textSize: {
|
||||
var base = isVertical ? width * 0.82 : height
|
||||
return Math.max(1, compact ? base * 0.43 : base * 0.33)
|
||||
return Math.max(1, (density === "compact") ? base * 0.43 : base * 0.33)
|
||||
}
|
||||
|
||||
readonly property int percentTextWidth: Math.ceil(percentMetrics.boundingRect.width + 3 * scaling)
|
||||
readonly property int tempTextWidth: Math.ceil(tempMetrics.boundingRect.width + 3 * scaling)
|
||||
readonly property int memTextWidth: Math.ceil(memMetrics.boundingRect.width + 3 * scaling)
|
||||
readonly property int percentTextWidth: Math.ceil(percentMetrics.boundingRect.width + 3)
|
||||
readonly property int tempTextWidth: Math.ceil(tempMetrics.boundingRect.width + 3)
|
||||
readonly property int memTextWidth: Math.ceil(memMetrics.boundingRect.width + 3)
|
||||
|
||||
TextMetrics {
|
||||
id: percentMetrics
|
||||
@@ -74,9 +73,9 @@ Rectangle {
|
||||
}
|
||||
|
||||
anchors.centerIn: parent
|
||||
implicitWidth: isVertical ? Math.round(Style.capsuleHeight * scaling) : Math.round(mainGrid.implicitWidth + Style.marginM * 2 * scaling)
|
||||
implicitHeight: isVertical ? Math.round(mainGrid.implicitHeight + Style.marginM * 2 * scaling) : Math.round(Style.capsuleHeight * scaling)
|
||||
radius: Math.round(Style.radiusM * scaling)
|
||||
implicitWidth: isVertical ? Style.capsuleHeight : Math.round(mainGrid.implicitWidth + Style.marginM * 2)
|
||||
implicitHeight: isVertical ? Math.round(mainGrid.implicitHeight + Style.marginM * 2) : Style.capsuleHeight
|
||||
radius: Style.radiusM
|
||||
color: Settings.data.bar.showCapsule ? Color.mSurfaceVariant : Color.transparent
|
||||
|
||||
GridLayout {
|
||||
@@ -85,13 +84,13 @@ Rectangle {
|
||||
flow: isVertical ? GridLayout.TopToBottom : GridLayout.LeftToRight
|
||||
rows: isVertical ? -1 : 1
|
||||
columns: isVertical ? 1 : -1
|
||||
rowSpacing: isVertical ? (Style.marginM * scaling) : 0
|
||||
columnSpacing: isVertical ? 0 : (Style.marginM * scaling)
|
||||
rowSpacing: isVertical ? (Style.marginM) : 0
|
||||
columnSpacing: isVertical ? 0 : (Style.marginM)
|
||||
|
||||
// CPU Usage Component
|
||||
Item {
|
||||
Layout.preferredWidth: isVertical ? root.width : iconSize + percentTextWidth + (Style.marginXXS * scaling)
|
||||
Layout.preferredHeight: Math.round(Style.capsuleHeight * scaling)
|
||||
Layout.preferredWidth: isVertical ? root.width : iconSize + percentTextWidth + (Style.marginXXS)
|
||||
Layout.preferredHeight: Style.capsuleHeight
|
||||
Layout.alignment: isVertical ? Qt.AlignHCenter : Qt.AlignVCenter
|
||||
visible: showCpuUsage
|
||||
|
||||
@@ -101,12 +100,13 @@ Rectangle {
|
||||
flow: isVertical ? GridLayout.TopToBottom : GridLayout.LeftToRight
|
||||
rows: isVertical ? 2 : 1
|
||||
columns: isVertical ? 1 : 2
|
||||
rowSpacing: Style.marginXXS * scaling
|
||||
columnSpacing: Style.marginXXS * scaling
|
||||
rowSpacing: Style.marginXXS
|
||||
columnSpacing: Style.marginXXS
|
||||
|
||||
NIcon {
|
||||
icon: "cpu-usage"
|
||||
pointSize: iconSize
|
||||
applyUiScale: false
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
Layout.row: isVertical ? 1 : 0
|
||||
Layout.column: 0
|
||||
@@ -116,6 +116,7 @@ Rectangle {
|
||||
text: `${Math.round(SystemStatService.cpuUsage)}%`
|
||||
family: Settings.data.ui.fontFixed
|
||||
pointSize: textSize
|
||||
applyUiScale: false
|
||||
font.weight: Style.fontWeightMedium
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
Layout.preferredWidth: isVertical ? -1 : percentTextWidth
|
||||
@@ -131,8 +132,8 @@ Rectangle {
|
||||
|
||||
// CPU Temperature Component
|
||||
Item {
|
||||
Layout.preferredWidth: isVertical ? root.width : (iconSize + tempTextWidth) + (Style.marginXXS * scaling)
|
||||
Layout.preferredHeight: Math.round(Style.capsuleHeight * scaling)
|
||||
Layout.preferredWidth: isVertical ? root.width : (iconSize + tempTextWidth) + (Style.marginXXS)
|
||||
Layout.preferredHeight: Style.capsuleHeight
|
||||
Layout.alignment: isVertical ? Qt.AlignHCenter : Qt.AlignVCenter
|
||||
visible: showCpuTemp
|
||||
|
||||
@@ -142,12 +143,13 @@ Rectangle {
|
||||
flow: isVertical ? GridLayout.TopToBottom : GridLayout.LeftToRight
|
||||
rows: isVertical ? 2 : 1
|
||||
columns: isVertical ? 1 : 2
|
||||
rowSpacing: Style.marginXXS * scaling
|
||||
columnSpacing: Style.marginXXS * scaling
|
||||
rowSpacing: Style.marginXXS
|
||||
columnSpacing: Style.marginXXS
|
||||
|
||||
NIcon {
|
||||
icon: "cpu-temperature"
|
||||
pointSize: iconSize
|
||||
applyUiScale: false
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
Layout.row: isVertical ? 1 : 0
|
||||
Layout.column: 0
|
||||
@@ -157,6 +159,7 @@ Rectangle {
|
||||
text: `${Math.round(SystemStatService.cpuTemp)}°`
|
||||
family: Settings.data.ui.fontFixed
|
||||
pointSize: textSize
|
||||
applyUiScale: false
|
||||
font.weight: Style.fontWeightMedium
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
Layout.preferredWidth: isVertical ? -1 : tempTextWidth
|
||||
@@ -172,8 +175,8 @@ Rectangle {
|
||||
|
||||
// Memory Usage Component
|
||||
Item {
|
||||
Layout.preferredWidth: isVertical ? root.width : iconSize + (showMemoryAsPercent ? percentTextWidth : memTextWidth) + (Style.marginXXS * scaling)
|
||||
Layout.preferredHeight: Math.round(Style.capsuleHeight * scaling)
|
||||
Layout.preferredWidth: isVertical ? root.width : iconSize + (showMemoryAsPercent ? percentTextWidth : memTextWidth) + (Style.marginXXS)
|
||||
Layout.preferredHeight: Style.capsuleHeight
|
||||
Layout.alignment: isVertical ? Qt.AlignHCenter : Qt.AlignVCenter
|
||||
visible: showMemoryUsage
|
||||
|
||||
@@ -183,12 +186,13 @@ Rectangle {
|
||||
flow: isVertical ? GridLayout.TopToBottom : GridLayout.LeftToRight
|
||||
rows: isVertical ? 2 : 1
|
||||
columns: isVertical ? 1 : 2
|
||||
rowSpacing: Style.marginXXS * scaling
|
||||
columnSpacing: Style.marginXXS * scaling
|
||||
rowSpacing: Style.marginXXS
|
||||
columnSpacing: Style.marginXXS
|
||||
|
||||
NIcon {
|
||||
icon: "memory"
|
||||
pointSize: iconSize
|
||||
applyUiScale: false
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
Layout.row: isVertical ? 1 : 0
|
||||
Layout.column: 0
|
||||
@@ -198,6 +202,7 @@ Rectangle {
|
||||
text: showMemoryAsPercent ? `${Math.round(SystemStatService.memPercent)}%` : `${SystemStatService.memGb.toFixed(1)}G`
|
||||
family: Settings.data.ui.fontFixed
|
||||
pointSize: textSize
|
||||
applyUiScale: false
|
||||
font.weight: Style.fontWeightMedium
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
Layout.preferredWidth: isVertical ? -1 : (showMemoryAsPercent ? percentTextWidth : memTextWidth)
|
||||
@@ -213,8 +218,8 @@ Rectangle {
|
||||
|
||||
// Network Download Speed Component
|
||||
Item {
|
||||
Layout.preferredWidth: isVertical ? root.width : iconSize + memTextWidth + (Style.marginXXS * scaling)
|
||||
Layout.preferredHeight: Math.round(Style.capsuleHeight * scaling)
|
||||
Layout.preferredWidth: isVertical ? root.width : iconSize + memTextWidth + (Style.marginXXS)
|
||||
Layout.preferredHeight: Style.capsuleHeight
|
||||
Layout.alignment: isVertical ? Qt.AlignHCenter : Qt.AlignVCenter
|
||||
visible: showNetworkStats
|
||||
|
||||
@@ -224,12 +229,13 @@ Rectangle {
|
||||
flow: isVertical ? GridLayout.TopToBottom : GridLayout.LeftToRight
|
||||
rows: isVertical ? 2 : 1
|
||||
columns: isVertical ? 1 : 2
|
||||
rowSpacing: Style.marginXXS * scaling
|
||||
columnSpacing: Style.marginXXS * scaling
|
||||
rowSpacing: Style.marginXXS
|
||||
columnSpacing: Style.marginXXS
|
||||
|
||||
NIcon {
|
||||
icon: "download-speed"
|
||||
pointSize: iconSize
|
||||
applyUiScale: false
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
Layout.row: isVertical ? 1 : 0
|
||||
Layout.column: 0
|
||||
@@ -239,6 +245,7 @@ Rectangle {
|
||||
text: isVertical ? SystemStatService.formatCompactSpeed(SystemStatService.rxSpeed) : SystemStatService.formatSpeed(SystemStatService.rxSpeed)
|
||||
family: Settings.data.ui.fontFixed
|
||||
pointSize: textSize
|
||||
applyUiScale: false
|
||||
font.weight: Style.fontWeightMedium
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
Layout.preferredWidth: isVertical ? -1 : memTextWidth
|
||||
@@ -254,8 +261,8 @@ Rectangle {
|
||||
|
||||
// Network Upload Speed Component
|
||||
Item {
|
||||
Layout.preferredWidth: isVertical ? root.width : iconSize + memTextWidth + (Style.marginXXS * scaling)
|
||||
Layout.preferredHeight: Math.round(Style.capsuleHeight * scaling)
|
||||
Layout.preferredWidth: isVertical ? root.width : iconSize + memTextWidth + (Style.marginXXS)
|
||||
Layout.preferredHeight: Style.capsuleHeight
|
||||
Layout.alignment: isVertical ? Qt.AlignHCenter : Qt.AlignVCenter
|
||||
visible: showNetworkStats
|
||||
|
||||
@@ -265,12 +272,13 @@ Rectangle {
|
||||
flow: isVertical ? GridLayout.TopToBottom : GridLayout.LeftToRight
|
||||
rows: isVertical ? 2 : 1
|
||||
columns: isVertical ? 1 : 2
|
||||
rowSpacing: Style.marginXXS * scaling
|
||||
columnSpacing: Style.marginXXS * scaling
|
||||
rowSpacing: Style.marginXXS
|
||||
columnSpacing: Style.marginXXS
|
||||
|
||||
NIcon {
|
||||
icon: "upload-speed"
|
||||
pointSize: iconSize
|
||||
applyUiScale: false
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
Layout.row: isVertical ? 1 : 0
|
||||
Layout.column: 0
|
||||
@@ -280,6 +288,7 @@ Rectangle {
|
||||
text: isVertical ? SystemStatService.formatCompactSpeed(SystemStatService.txSpeed) : SystemStatService.formatSpeed(SystemStatService.txSpeed)
|
||||
family: Settings.data.ui.fontFixed
|
||||
pointSize: textSize
|
||||
applyUiScale: false
|
||||
font.weight: Style.fontWeightMedium
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
Layout.preferredWidth: isVertical ? -1 : memTextWidth
|
||||
@@ -295,8 +304,8 @@ Rectangle {
|
||||
|
||||
// Disk Usage Component (primary drive)
|
||||
Item {
|
||||
Layout.preferredWidth: isVertical ? root.width : iconSize + percentTextWidth + (Style.marginXXS * scaling)
|
||||
Layout.preferredHeight: Math.round(Style.capsuleHeight * scaling)
|
||||
Layout.preferredWidth: isVertical ? root.width : iconSize + percentTextWidth + (Style.marginXXS)
|
||||
Layout.preferredHeight: Style.capsuleHeight
|
||||
Layout.alignment: isVertical ? Qt.AlignHCenter : Qt.AlignVCenter
|
||||
visible: showDiskUsage
|
||||
|
||||
@@ -306,12 +315,13 @@ Rectangle {
|
||||
flow: isVertical ? GridLayout.TopToBottom : GridLayout.LeftToRight
|
||||
rows: isVertical ? 2 : 1
|
||||
columns: isVertical ? 1 : 2
|
||||
rowSpacing: Style.marginXXS * scaling
|
||||
columnSpacing: Style.marginXXS * scaling
|
||||
rowSpacing: Style.marginXXS
|
||||
columnSpacing: Style.marginXXS
|
||||
|
||||
NIcon {
|
||||
icon: "storage"
|
||||
pointSize: iconSize
|
||||
applyUiScale: false
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
Layout.row: isVertical ? 1 : 0
|
||||
Layout.column: 0
|
||||
@@ -321,6 +331,7 @@ Rectangle {
|
||||
text: `${SystemStatService.diskPercent}%`
|
||||
family: Settings.data.ui.fontFixed
|
||||
pointSize: textSize
|
||||
applyUiScale: false
|
||||
font.weight: Style.fontWeightMedium
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
Layout.preferredWidth: isVertical ? -1 : percentTextWidth
|
||||
|
||||
@@ -12,7 +12,6 @@ Rectangle {
|
||||
id: root
|
||||
|
||||
property ShellScreen screen
|
||||
property real scaling: 1.0
|
||||
|
||||
// Widget properties passed from Bar.qml for per-instance settings
|
||||
property string widgetId: ""
|
||||
@@ -21,8 +20,8 @@ Rectangle {
|
||||
property int sectionWidgetsCount: 0
|
||||
|
||||
readonly property bool isVerticalBar: Settings.data.bar.position === "left" || Settings.data.bar.position === "right"
|
||||
readonly property bool compact: (Settings.data.bar.density === "compact")
|
||||
readonly property real itemSize: compact ? Style.capsuleHeight * 0.9 * scaling : Style.capsuleHeight * 0.8 * scaling
|
||||
readonly property bool density: Settings.data.bar.density
|
||||
readonly property real itemSize: (density === "compact") ? Style.capsuleHeight * 0.9 : Style.capsuleHeight * 0.8
|
||||
|
||||
property var widgetMetadata: BarWidgetRegistry.widgetMetadata[widgetId]
|
||||
property var widgetSettings: {
|
||||
@@ -36,27 +35,27 @@ Rectangle {
|
||||
}
|
||||
|
||||
// Always visible when there are toplevels
|
||||
implicitWidth: isVerticalBar ? Math.round(Style.capsuleHeight * scaling) : taskbarLayout.implicitWidth + Style.marginM * scaling * 2
|
||||
implicitHeight: isVerticalBar ? taskbarLayout.implicitHeight + Style.marginM * scaling * 2 : Math.round(Style.capsuleHeight * scaling)
|
||||
radius: Math.round(Style.radiusM * scaling)
|
||||
implicitWidth: isVerticalBar ? Style.capsuleHeight : Math.round(taskbarLayout.implicitWidth + Style.marginM * 2)
|
||||
implicitHeight: isVerticalBar ? Math.round(taskbarLayout.implicitHeight + Style.marginM * 2) : Style.capsuleHeight
|
||||
radius: Style.radiusM
|
||||
color: Settings.data.bar.showCapsule ? Color.mSurfaceVariant : Color.transparent
|
||||
|
||||
GridLayout {
|
||||
id: taskbarLayout
|
||||
anchors.fill: parent
|
||||
anchors {
|
||||
leftMargin: isVerticalBar ? undefined : Style.marginM * scaling
|
||||
rightMargin: isVerticalBar ? undefined : Style.marginM * scaling
|
||||
topMargin: compact ? 0 : isVerticalBar ? Style.marginM * scaling : undefined
|
||||
bottomMargin: compact ? 0 : isVerticalBar ? Style.marginM * scaling : undefined
|
||||
leftMargin: isVerticalBar ? undefined : Style.marginM
|
||||
rightMargin: isVerticalBar ? undefined : Style.marginM
|
||||
topMargin: (density === "compact") ? 0 : isVerticalBar ? Style.marginM : undefined
|
||||
bottomMargin: (density === "compact") ? 0 : isVerticalBar ? Style.marginM : undefined
|
||||
}
|
||||
|
||||
// Configure GridLayout to behave like RowLayout or ColumnLayout
|
||||
rows: isVerticalBar ? -1 : 1 // -1 means unlimited
|
||||
columns: isVerticalBar ? 1 : -1 // -1 means unlimited
|
||||
|
||||
rowSpacing: isVerticalBar ? Style.marginXXS * root.scaling : 0
|
||||
columnSpacing: isVerticalBar ? 0 : Style.marginXXS * root.scaling
|
||||
rowSpacing: isVerticalBar ? Style.marginXXS : 0
|
||||
columnSpacing: isVerticalBar ? 0 : Style.marginXXS
|
||||
|
||||
Repeater {
|
||||
model: CompositorService.windows
|
||||
@@ -81,13 +80,22 @@ Rectangle {
|
||||
asynchronous: true
|
||||
opacity: modelData.isFocused ? Style.opacityFull : 0.6
|
||||
|
||||
// Apply dock shader to all taskbar icons
|
||||
layer.enabled: widgetSettings.colorizeIcons !== false
|
||||
layer.effect: ShaderEffect {
|
||||
property color targetColor: Color.mOnSurface
|
||||
property real colorizeMode: 0.0 // Dock mode (grayscale)
|
||||
|
||||
fragmentShader: Qt.resolvedUrl(Quickshell.shellDir + "/Shaders/qsb/appicon_colorize.frag.qsb")
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
anchors.bottomMargin: -2 * scaling
|
||||
anchors.bottomMargin: -2
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
id: iconBackground
|
||||
width: 4 * scaling
|
||||
height: 4 * scaling
|
||||
width: 4
|
||||
height: 4
|
||||
color: modelData.isFocused ? Color.mPrimary : Color.transparent
|
||||
radius: width * 0.5
|
||||
}
|
||||
@@ -105,13 +113,13 @@ Rectangle {
|
||||
|
||||
if (mouse.button === Qt.LeftButton) {
|
||||
try {
|
||||
CompositorService.focusWindow(taskbarItem.modelData.id)
|
||||
CompositorService.focusWindow(taskbarItem.modelData)
|
||||
} catch (error) {
|
||||
Logger.error("Taskbar", "Failed to activate toplevel: " + error)
|
||||
}
|
||||
} else if (mouse.button === Qt.RightButton) {
|
||||
try {
|
||||
CompositorService.closeWindow(taskbarItem.modelData.id)
|
||||
CompositorService.closeWindow(taskbarItem.modelData)
|
||||
} catch (error) {
|
||||
Logger.error("Taskbar", "Failed to close toplevel: " + error)
|
||||
}
|
||||
|
||||
+185
-66
@@ -14,12 +14,109 @@ Rectangle {
|
||||
id: root
|
||||
|
||||
property ShellScreen screen
|
||||
property real scaling: 1.0
|
||||
|
||||
// Widget properties passed from Bar.qml for per-instance settings
|
||||
property string widgetId: ""
|
||||
property string section: ""
|
||||
property int sectionWidgetIndex: -1
|
||||
property int sectionWidgetsCount: 0
|
||||
|
||||
property var widgetMetadata: BarWidgetRegistry.widgetMetadata[widgetId]
|
||||
property var widgetSettings: {
|
||||
if (section && sectionWidgetIndex >= 0) {
|
||||
var widgets = Settings.data.bar.widgets[section]
|
||||
if (widgets && sectionWidgetIndex < widgets.length) {
|
||||
return widgets[sectionWidgetIndex]
|
||||
}
|
||||
}
|
||||
return {}
|
||||
}
|
||||
|
||||
readonly property string barPosition: Settings.data.bar.position
|
||||
readonly property bool isVertical: barPosition === "left" || barPosition === "right"
|
||||
readonly property bool compact: (Settings.data.bar.density === "compact")
|
||||
readonly property real itemSize: isVertical ? width * 0.75 : height * 0.85
|
||||
readonly property bool density: Settings.data.bar.density
|
||||
property real itemSize: Math.round(Style.capsuleHeight * 0.65)
|
||||
property list<string> blacklist: widgetSettings.blacklist || widgetMetadata.blacklist || [] // Read from settings
|
||||
property var filteredItems: []
|
||||
|
||||
function wildCardMatch(str, rule) {
|
||||
if (!str || !rule) {
|
||||
return false
|
||||
}
|
||||
Logger.log("Tray", "wildCardMatch - Input str:", str, "rule:", rule)
|
||||
|
||||
// Escape all special regex characters in the rule
|
||||
let escapedRule = rule.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
|
||||
// Convert '*' to '.*' for wildcard matching
|
||||
let pattern = escapedRule.replace(/\\\*/g, '.*')
|
||||
// Add ^ and $ to match the entire string
|
||||
pattern = '^' + pattern + '$'
|
||||
|
||||
Logger.log("Tray", "wildCardMatch - Generated pattern:", pattern)
|
||||
|
||||
try {
|
||||
const regex = new RegExp(pattern, 'i')
|
||||
// 'i' for case-insensitive
|
||||
Logger.log("Tray", "wildCardMatch - Regex test result:", regex.test(str))
|
||||
return regex.test(str)
|
||||
} catch (e) {
|
||||
Logger.warn("Tray", "Invalid regex pattern for wildcard match:", rule, e.message)
|
||||
return false // If regex is invalid, it won't match
|
||||
}
|
||||
}
|
||||
|
||||
// Debounce timer for updateFilteredItems to prevent excessive calls
|
||||
// when multiple events (e.g., SystemTray changes, settings saves)
|
||||
// trigger it in rapid succession, reducing redundant processing.
|
||||
Timer {
|
||||
id: updateDebounceTimer
|
||||
interval: 100 // milliseconds
|
||||
running: false
|
||||
repeat: false
|
||||
onTriggered: _performFilteredItemsUpdate()
|
||||
}
|
||||
|
||||
function _performFilteredItemsUpdate() {
|
||||
if (!root.blacklist || root.blacklist.length === 0) {
|
||||
if (SystemTray.items && SystemTray.items.values) {
|
||||
filteredItems = SystemTray.items.values
|
||||
} else {
|
||||
filteredItems = []
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
let newItems = []
|
||||
if (SystemTray.items && SystemTray.items.values) {
|
||||
const trayItems = SystemTray.items.values
|
||||
for (var i = 0; i < trayItems.length; i++) {
|
||||
const item = trayItems[i]
|
||||
if (!item) {
|
||||
continue
|
||||
}
|
||||
|
||||
const title = item.tooltipTitle || item.name || item.id || ""
|
||||
|
||||
let isBlacklisted = false
|
||||
for (var j = 0; j < root.blacklist.length; j++) {
|
||||
const rule = root.blacklist[j]
|
||||
if (wildCardMatch(title, rule)) {
|
||||
isBlacklisted = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if (!isBlacklisted) {
|
||||
newItems.push(item)
|
||||
}
|
||||
}
|
||||
}
|
||||
filteredItems = newItems
|
||||
}
|
||||
|
||||
function updateFilteredItems() {
|
||||
updateDebounceTimer.restart()
|
||||
}
|
||||
|
||||
function onLoaded() {
|
||||
// When the widget is fully initialized with its props set the screen for the trayMenu
|
||||
@@ -28,10 +125,28 @@ Rectangle {
|
||||
}
|
||||
}
|
||||
|
||||
visible: SystemTray.items.values.length > 0
|
||||
implicitWidth: isVertical ? Math.round(Style.capsuleHeight * scaling) : (trayFlow.implicitWidth + Style.marginS * scaling * 2)
|
||||
implicitHeight: isVertical ? (trayFlow.implicitHeight + Style.marginS * scaling * 2) : Math.round(Style.capsuleHeight * scaling)
|
||||
radius: Math.round(Style.radiusM * scaling)
|
||||
Connections {
|
||||
target: SystemTray.items
|
||||
function onValuesChanged() {
|
||||
root.updateFilteredItems()
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: Settings
|
||||
function onSettingsSaved() {
|
||||
root.updateFilteredItems()
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
root.updateFilteredItems() // Initial update
|
||||
}
|
||||
|
||||
visible: filteredItems.length > 0
|
||||
implicitWidth: isVertical ? Style.capsuleHeight : Math.round(trayFlow.implicitWidth + Style.marginM * 2)
|
||||
implicitHeight: isVertical ? Math.round(trayFlow.implicitHeight + Style.marginM * 2) : Style.capsuleHeight
|
||||
radius: Style.radiusM
|
||||
color: Settings.data.bar.showCapsule ? Color.mSurfaceVariant : Color.transparent
|
||||
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
@@ -39,12 +154,12 @@ Rectangle {
|
||||
Flow {
|
||||
id: trayFlow
|
||||
anchors.centerIn: parent
|
||||
spacing: Style.marginS * scaling
|
||||
spacing: Style.marginM
|
||||
flow: isVertical ? Flow.TopToBottom : Flow.LeftToRight
|
||||
|
||||
Repeater {
|
||||
id: repeater
|
||||
model: SystemTray.items
|
||||
model: filteredItems
|
||||
|
||||
delegate: Item {
|
||||
width: itemSize
|
||||
@@ -56,10 +171,7 @@ Rectangle {
|
||||
|
||||
property ShellScreen screen: root.screen
|
||||
|
||||
anchors.centerIn: parent
|
||||
width: Style.marginL * scaling
|
||||
height: Style.marginL * scaling
|
||||
smooth: false
|
||||
anchors.fill: parent
|
||||
asynchronous: true
|
||||
backer.fillMode: Image.PreserveAspectFit
|
||||
source: {
|
||||
@@ -70,7 +182,6 @@ Rectangle {
|
||||
|
||||
// Process icon path
|
||||
if (icon.includes("?path=")) {
|
||||
// Seems qmlfmt does not support the following ES6 syntax: const[name, path] = icon.split
|
||||
const chunks = icon.split("?path=")
|
||||
const name = chunks[0]
|
||||
const path = chunks[1]
|
||||
@@ -80,69 +191,77 @@ Rectangle {
|
||||
return icon
|
||||
}
|
||||
opacity: status === Image.Ready ? 1 : 0
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.MiddleButton
|
||||
onClicked: mouse => {
|
||||
if (!modelData) {
|
||||
return
|
||||
}
|
||||
layer.enabled: widgetSettings.colorizeIcons !== false
|
||||
layer.effect: ShaderEffect {
|
||||
property color targetColor: Color.mOnSurface
|
||||
property real colorizeMode: 1.0 // Tray mode (intensity-based)
|
||||
|
||||
if (mouse.button === Qt.LeftButton) {
|
||||
// Close any open menu first
|
||||
trayPanel.close()
|
||||
fragmentShader: Qt.resolvedUrl(Quickshell.shellDir + "/Shaders/qsb/appicon_colorize.frag.qsb")
|
||||
}
|
||||
|
||||
if (!modelData.onlyMenu) {
|
||||
modelData.activate()
|
||||
}
|
||||
} else if (mouse.button === Qt.MiddleButton) {
|
||||
// Close any open menu first
|
||||
trayPanel.close()
|
||||
|
||||
modelData.secondaryActivate && modelData.secondaryActivate()
|
||||
} else if (mouse.button === Qt.RightButton) {
|
||||
TooltipService.hideImmediately()
|
||||
|
||||
// Close the menu if it was visible
|
||||
if (trayPanel && trayPanel.visible) {
|
||||
trayPanel.close()
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.MiddleButton
|
||||
onClicked: mouse => {
|
||||
if (!modelData) {
|
||||
return
|
||||
}
|
||||
|
||||
if (modelData.hasMenu && modelData.menu && trayMenu.item) {
|
||||
trayPanel.open()
|
||||
if (mouse.button === Qt.LeftButton) {
|
||||
// Close any open menu first
|
||||
trayPanel.close()
|
||||
|
||||
// Position menu based on bar position
|
||||
let menuX, menuY
|
||||
if (barPosition === "left") {
|
||||
// For left bar: position menu to the right of the bar
|
||||
menuX = width + Style.marginM * scaling
|
||||
menuY = 0
|
||||
} else if (barPosition === "right") {
|
||||
// For right bar: position menu to the left of the bar
|
||||
menuX = -trayMenu.item.width - Style.marginM * scaling
|
||||
menuY = 0
|
||||
} else {
|
||||
// For horizontal bars: center horizontally and position below
|
||||
menuX = (width / 2) - (trayMenu.item.width / 2)
|
||||
menuY = Math.round(Style.barHeight * scaling)
|
||||
if (!modelData.onlyMenu) {
|
||||
modelData.activate()
|
||||
}
|
||||
} else if (mouse.button === Qt.MiddleButton) {
|
||||
// Close any open menu first
|
||||
trayPanel.close()
|
||||
|
||||
modelData.secondaryActivate && modelData.secondaryActivate()
|
||||
} else if (mouse.button === Qt.RightButton) {
|
||||
TooltipService.hideImmediately()
|
||||
|
||||
// Close the menu if it was visible
|
||||
if (trayPanel && trayPanel.visible) {
|
||||
trayPanel.close()
|
||||
return
|
||||
}
|
||||
|
||||
if (modelData.hasMenu && modelData.menu && trayMenu.item) {
|
||||
trayPanel.open()
|
||||
|
||||
// Position menu based on bar position
|
||||
let menuX, menuY
|
||||
if (barPosition === "left") {
|
||||
// For left bar: position menu to the right of the bar
|
||||
menuX = width + Style.marginM
|
||||
menuY = 0
|
||||
} else if (barPosition === "right") {
|
||||
// For right bar: position menu to the left of the bar
|
||||
menuX = -trayMenu.item.width - Style.marginM
|
||||
menuY = 0
|
||||
} else {
|
||||
// For horizontal bars: center horizontally and position below
|
||||
menuX = (width / 2) - (trayMenu.item.width / 2)
|
||||
menuY = Style.barHeight
|
||||
}
|
||||
trayMenu.item.menu = modelData.menu
|
||||
trayMenu.item.showAt(parent, menuX, menuY)
|
||||
} else {
|
||||
Logger.log("Tray", "No menu available for", modelData.id, "or trayMenu not set")
|
||||
}
|
||||
trayMenu.item.menu = modelData.menu
|
||||
trayMenu.item.showAt(parent, menuX, menuY)
|
||||
} else {
|
||||
Logger.log("Tray", "No menu available for", modelData.id, "or trayMenu not set")
|
||||
}
|
||||
}
|
||||
}
|
||||
onEntered: {
|
||||
trayPanel.close()
|
||||
TooltipService.show(Screen, trayIcon, modelData.tooltipTitle || modelData.name || modelData.id || "Tray Item", BarService.getTooltipDirection())
|
||||
onEntered: {
|
||||
trayPanel.close()
|
||||
TooltipService.show(Screen, trayIcon, modelData.tooltipTitle || modelData.name || modelData.id || "Tray Item", BarService.getTooltipDirection())
|
||||
}
|
||||
onExited: TooltipService.hide()
|
||||
}
|
||||
onExited: TooltipService.hide()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@ Item {
|
||||
id: root
|
||||
|
||||
property ShellScreen screen
|
||||
property real scaling: 1.0
|
||||
|
||||
// Widget properties passed from Bar.qml for per-instance settings
|
||||
property string widgetId: ""
|
||||
@@ -75,7 +74,7 @@ Item {
|
||||
BarPill {
|
||||
id: pill
|
||||
|
||||
compact: (Settings.data.bar.density === "compact")
|
||||
density: Settings.data.bar.density
|
||||
rightOpen: BarService.getPillDirection(root)
|
||||
icon: getIcon()
|
||||
autoHide: false // Important to be false so we can hover as long as we want
|
||||
|
||||
@@ -8,10 +8,11 @@ import qs.Widgets
|
||||
NIconButton {
|
||||
id: root
|
||||
|
||||
property real scaling: 1.0
|
||||
property ShellScreen screen
|
||||
|
||||
baseSize: Style.capsuleHeight
|
||||
compact: (Settings.data.bar.density === "compact")
|
||||
applyUiScale: false
|
||||
density: Settings.data.bar.density
|
||||
icon: "wallpaper-selector"
|
||||
tooltipText: I18n.tr("tooltips.open-wallpaper-selector")
|
||||
tooltipDirection: BarService.getTooltipDirection()
|
||||
|
||||
@@ -10,10 +10,11 @@ import qs.Widgets
|
||||
NIconButton {
|
||||
id: root
|
||||
|
||||
property real scaling: 1.0
|
||||
property ShellScreen screen
|
||||
|
||||
compact: (Settings.data.bar.density === "compact")
|
||||
density: Settings.data.bar.density
|
||||
baseSize: Style.capsuleHeight
|
||||
applyUiScale: false
|
||||
colorBg: (Settings.data.bar.showCapsule ? Color.mSurfaceVariant : Color.transparent)
|
||||
colorFg: Color.mOnSurface
|
||||
colorBorder: Color.transparent
|
||||
|
||||
@@ -13,7 +13,6 @@ Item {
|
||||
id: root
|
||||
|
||||
property ShellScreen screen
|
||||
property real scaling: 1.0
|
||||
|
||||
// Widget properties passed from Bar.qml for per-instance settings
|
||||
property string widgetId: ""
|
||||
@@ -34,9 +33,9 @@ Item {
|
||||
|
||||
readonly property string barPosition: Settings.data.bar.position
|
||||
readonly property bool isVertical: barPosition === "left" || barPosition === "right"
|
||||
readonly property bool compact: (Settings.data.bar.density === "compact")
|
||||
readonly property bool density: Settings.data.bar.density
|
||||
readonly property real baseDimensionRatio: {
|
||||
const b = compact ? 0.85 : 0.65
|
||||
const b = (density === "compact") ? 0.85 : 0.65
|
||||
if (widgetSettings.labelMode === "none") {
|
||||
return b * 0.75
|
||||
}
|
||||
@@ -54,8 +53,8 @@ Item {
|
||||
property bool effectsActive: false
|
||||
property color effectColor: Color.mPrimary
|
||||
|
||||
property int horizontalPadding: Math.round(Style.marginS * scaling)
|
||||
property int spacingBetweenPills: Math.round(Style.marginXS * scaling)
|
||||
property int horizontalPadding: Math.round(Style.marginS)
|
||||
property int spacingBetweenPills: Math.round(Style.marginXS)
|
||||
|
||||
// Wheel scroll handling
|
||||
property int wheelAccumulatedDelta: 0
|
||||
@@ -63,19 +62,19 @@ Item {
|
||||
|
||||
signal workspaceChanged(int workspaceId, color accentColor)
|
||||
|
||||
implicitWidth: isVertical ? Math.round(Style.barHeight * scaling) : computeWidth()
|
||||
implicitHeight: isVertical ? computeHeight() : Math.round(Style.barHeight * scaling)
|
||||
implicitWidth: isVertical ? Style.barHeight : computeWidth()
|
||||
implicitHeight: isVertical ? computeHeight() : Style.barHeight
|
||||
|
||||
function getWorkspaceWidth(ws) {
|
||||
const d = Style.capsuleHeight * root.baseDimensionRatio
|
||||
const factor = ws.isFocused ? 2.2 : 1
|
||||
return d * factor * scaling
|
||||
const factor = ws.isActive ? 2.2 : 1
|
||||
return d * factor
|
||||
}
|
||||
|
||||
function getWorkspaceHeight(ws) {
|
||||
const d = Style.capsuleHeight * root.baseDimensionRatio
|
||||
const factor = ws.isFocused ? 2.2 : 1
|
||||
return d * factor * scaling
|
||||
const factor = ws.isActive ? 2.2 : 1
|
||||
return d * factor
|
||||
}
|
||||
|
||||
function computeWidth() {
|
||||
@@ -119,7 +118,7 @@ Item {
|
||||
next = localWorkspaces.count - 1
|
||||
const ws = localWorkspaces.get(next)
|
||||
if (ws && ws.idx !== undefined)
|
||||
CompositorService.switchToWorkspace(ws.idx)
|
||||
CompositorService.switchToWorkspace(ws)
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
@@ -203,9 +202,9 @@ Item {
|
||||
|
||||
Rectangle {
|
||||
id: workspaceBackground
|
||||
width: isVertical ? Math.round(Style.capsuleHeight * scaling) : parent.width
|
||||
height: isVertical ? parent.height : Math.round(Style.capsuleHeight * scaling)
|
||||
radius: Math.round(Style.radiusM * scaling)
|
||||
width: isVertical ? Style.capsuleHeight : parent.width
|
||||
height: isVertical ? parent.height : Style.capsuleHeight
|
||||
radius: Style.radiusM
|
||||
color: Settings.data.bar.showCapsule ? Color.mSurfaceVariant : Color.transparent
|
||||
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
@@ -266,7 +265,7 @@ Item {
|
||||
Item {
|
||||
id: workspacePillContainer
|
||||
width: root.getWorkspaceWidth(model)
|
||||
height: Style.capsuleHeight * root.baseDimensionRatio * scaling
|
||||
height: Style.capsuleHeight * root.baseDimensionRatio
|
||||
|
||||
Rectangle {
|
||||
id: pill
|
||||
@@ -286,7 +285,8 @@ Item {
|
||||
}
|
||||
}
|
||||
family: Settings.data.ui.fontFixed
|
||||
pointSize: model.isFocused ? workspacePillContainer.height * 0.45 : workspacePillContainer.height * 0.42
|
||||
pointSize: model.isActive ? workspacePillContainer.height * 0.45 : workspacePillContainer.height * 0.42
|
||||
applyUiScale: false
|
||||
font.capitalization: Font.AllUppercase
|
||||
font.weight: Style.fontWeightBold
|
||||
wrapMode: Text.Wrap
|
||||
@@ -295,7 +295,7 @@ Item {
|
||||
return Color.mOnPrimary
|
||||
if (model.isUrgent)
|
||||
return Color.mOnError
|
||||
if (model.isActive || model.isOccupied)
|
||||
if (model.isOccupied)
|
||||
return Color.mOnSecondary
|
||||
|
||||
return Color.mOnSecondary
|
||||
@@ -310,12 +310,12 @@ Item {
|
||||
return Color.mPrimary
|
||||
if (model.isUrgent)
|
||||
return Color.mError
|
||||
if (model.isActive || model.isOccupied)
|
||||
if (model.isOccupied)
|
||||
return Color.mSecondary
|
||||
|
||||
return Qt.alpha(Color.mSecondary, 0.3)
|
||||
}
|
||||
scale: model.isFocused ? 1.0 : 0.9
|
||||
scale: model.isActive ? 1.0 : 0.9
|
||||
z: 0
|
||||
|
||||
MouseArea {
|
||||
@@ -323,7 +323,7 @@ Item {
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
CompositorService.switchToWorkspace(model.idx)
|
||||
CompositorService.switchToWorkspace(model)
|
||||
}
|
||||
hoverEnabled: true
|
||||
}
|
||||
@@ -387,7 +387,7 @@ Item {
|
||||
radius: width / 2
|
||||
color: Color.transparent
|
||||
border.color: root.effectColor
|
||||
border.width: Math.max(1, Math.round((2 + 6 * (1.0 - root.masterProgress)) * scaling))
|
||||
border.width: Math.max(1, Math.round((2 + 6 * (1.0 - root.masterProgress))))
|
||||
opacity: root.effectsActive && model.isFocused ? (1.0 - root.masterProgress) * 0.7 : 0
|
||||
visible: root.effectsActive && model.isFocused
|
||||
z: 1
|
||||
@@ -409,7 +409,7 @@ Item {
|
||||
model: localWorkspaces
|
||||
Item {
|
||||
id: workspacePillContainerVertical
|
||||
width: Style.capsuleHeight * root.baseDimensionRatio * scaling
|
||||
width: Style.capsuleHeight * root.baseDimensionRatio
|
||||
height: root.getWorkspaceHeight(model)
|
||||
|
||||
Rectangle {
|
||||
@@ -430,7 +430,8 @@ Item {
|
||||
}
|
||||
}
|
||||
family: Settings.data.ui.fontFixed
|
||||
pointSize: model.isFocused ? workspacePillContainerVertical.width * 0.45 : workspacePillContainerVertical.width * 0.42
|
||||
pointSize: model.isActive ? workspacePillContainerVertical.width * 0.45 : workspacePillContainerVertical.width * 0.42
|
||||
applyUiScale: false
|
||||
font.capitalization: Font.AllUppercase
|
||||
font.weight: Style.fontWeightBold
|
||||
wrapMode: Text.Wrap
|
||||
@@ -439,7 +440,7 @@ Item {
|
||||
return Color.mOnPrimary
|
||||
if (model.isUrgent)
|
||||
return Color.mOnError
|
||||
if (model.isActive || model.isOccupied)
|
||||
if (model.isOccupied)
|
||||
return Color.mOnSecondary
|
||||
|
||||
return Color.mOnSurface
|
||||
@@ -454,12 +455,12 @@ Item {
|
||||
return Color.mPrimary
|
||||
if (model.isUrgent)
|
||||
return Color.mError
|
||||
if (model.isActive || model.isOccupied)
|
||||
if (model.isOccupied)
|
||||
return Color.mSecondary
|
||||
|
||||
return Color.mOutline
|
||||
}
|
||||
scale: model.isFocused ? 1.0 : 0.9
|
||||
scale: model.isActive ? 1.0 : 0.9
|
||||
z: 0
|
||||
|
||||
MouseArea {
|
||||
@@ -467,7 +468,7 @@ Item {
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
CompositorService.switchToWorkspace(model.idx)
|
||||
CompositorService.switchToWorkspace(model)
|
||||
}
|
||||
hoverEnabled: true
|
||||
}
|
||||
@@ -531,7 +532,7 @@ Item {
|
||||
radius: width / 2
|
||||
color: Color.transparent
|
||||
border.color: root.effectColor
|
||||
border.width: Math.max(1, Math.round((2 + 6 * (1.0 - root.masterProgress)) * scaling))
|
||||
border.width: Math.max(1, Math.round((2 + 6 * (1.0 - root.masterProgress))))
|
||||
opacity: root.effectsActive && model.isFocused ? (1.0 - root.masterProgress) * 0.7 : 0
|
||||
visible: root.effectsActive && model.isFocused
|
||||
z: 1
|
||||
|
||||
@@ -0,0 +1,155 @@
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import qs.Commons
|
||||
import qs.Services
|
||||
import qs.Widgets
|
||||
|
||||
// Audio controls card: output and input volume controls
|
||||
NBox {
|
||||
id: root
|
||||
|
||||
property real localOutputVolume: AudioService.volume || 0
|
||||
property bool localOutputVolumeChanging: false
|
||||
|
||||
property real localInputVolume: AudioService.inputVolume || 0
|
||||
property bool localInputVolumeChanging: false
|
||||
|
||||
// Timer to debounce volume changes
|
||||
Timer {
|
||||
interval: 100
|
||||
running: true
|
||||
repeat: true
|
||||
onTriggered: {
|
||||
if (Math.abs(localOutputVolume - AudioService.volume) >= 0.01) {
|
||||
AudioService.setVolume(localOutputVolume)
|
||||
}
|
||||
if (Math.abs(localInputVolume - AudioService.inputVolume) >= 0.01) {
|
||||
AudioService.setInputVolume(localInputVolume)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Connections to update local volumes when AudioService changes
|
||||
Connections {
|
||||
target: AudioService.sink?.audio ? AudioService.sink?.audio : null
|
||||
function onVolumeChanged() {
|
||||
if (!localOutputVolumeChanging) {
|
||||
localOutputVolume = AudioService.volume
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: AudioService.source?.audio ? AudioService.source?.audio : null
|
||||
function onVolumeChanged() {
|
||||
if (!localInputVolumeChanging) {
|
||||
localInputVolume = AudioService.inputVolume
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
anchors.fill: parent
|
||||
anchors.margins: Style.marginM
|
||||
spacing: Style.marginM
|
||||
|
||||
// Output Volume Section
|
||||
ColumnLayout {
|
||||
spacing: Style.marginXXS
|
||||
Layout.fillWidth: true
|
||||
opacity: AudioService.sink ? 1.0 : 0.5
|
||||
enabled: AudioService.sink
|
||||
|
||||
// Output Volume Header
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: Style.marginXS
|
||||
|
||||
NIconButton {
|
||||
icon: AudioService.muted ? "volume-off" : "volume-high"
|
||||
baseSize: Style.baseWidgetSize * 0.5
|
||||
colorFg: AudioService.muted ? Color.mError : Color.mOnSurface
|
||||
colorBg: Color.transparent
|
||||
colorBgHover: Color.mTertiary
|
||||
colorFgHover: Color.mOnTertiary
|
||||
onClicked: {
|
||||
if (AudioService.sink && AudioService.sink.audio) {
|
||||
AudioService.sink.audio.muted = !AudioService.muted
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NText {
|
||||
text: AudioService.sink ? AudioService.sink.description : "No output device"
|
||||
pointSize: Style.fontSizeXS
|
||||
color: Color.mOnSurfaceVariant
|
||||
font.weight: Style.fontWeightMedium
|
||||
elide: Text.ElideRight
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
}
|
||||
|
||||
// Output Volume Slider
|
||||
NSlider {
|
||||
Layout.fillWidth: true
|
||||
from: 0
|
||||
to: Settings.data.audio.volumeOverdrive ? 1.5 : 1.0
|
||||
value: localOutputVolume
|
||||
stepSize: 0.01
|
||||
heightRatio: 0.5
|
||||
onMoved: localOutputVolume = value
|
||||
onPressedChanged: localOutputVolumeChanging = pressed
|
||||
tooltipText: `${Math.round(localOutputVolume * 100)}%`
|
||||
tooltipDirection: "bottom"
|
||||
}
|
||||
}
|
||||
|
||||
// Input Volume Section
|
||||
ColumnLayout {
|
||||
spacing: Style.marginXXS
|
||||
Layout.fillWidth: true
|
||||
opacity: AudioService.source ? 1.0 : 0.5
|
||||
enabled: AudioService.source
|
||||
|
||||
// Input Volume Header
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: Style.marginXS
|
||||
|
||||
NIconButton {
|
||||
icon: AudioService.inputMuted ? "microphone-off" : "microphone"
|
||||
baseSize: Style.baseWidgetSize * 0.5
|
||||
colorFg: AudioService.inputMuted ? Color.mError : Color.mOnSurface
|
||||
colorBg: Color.transparent
|
||||
colorBgHover: Color.mTertiary
|
||||
colorFgHover: Color.mOnTertiary
|
||||
onClicked: AudioService.setInputMuted(!AudioService.inputMuted)
|
||||
}
|
||||
|
||||
NText {
|
||||
text: AudioService.source ? AudioService.source.description : "No input device"
|
||||
pointSize: Style.fontSizeXS
|
||||
color: Color.mOnSurfaceVariant
|
||||
font.weight: Style.fontWeightMedium
|
||||
elide: Text.ElideRight
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
}
|
||||
|
||||
// Input Volume Slider
|
||||
NSlider {
|
||||
Layout.fillWidth: true
|
||||
from: 0
|
||||
to: Settings.data.audio.volumeOverdrive ? 1.5 : 1.0
|
||||
value: localInputVolume
|
||||
stepSize: 0.01
|
||||
heightRatio: 0.5
|
||||
onMoved: localInputVolume = value
|
||||
onPressedChanged: localInputVolumeChanging = pressed
|
||||
tooltipText: `${Math.round(localInputVolume * 100)}%`
|
||||
tooltipDirection: "bottom"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,7 +20,7 @@ NBox {
|
||||
id: bgArtImage
|
||||
anchors.fill: parent
|
||||
imagePath: MediaService.trackArtUrl
|
||||
imageRadius: Style.radiusM * scaling
|
||||
imageRadius: Style.radiusM
|
||||
visible: MediaService.trackArtUrl !== ""
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ NBox {
|
||||
anchors.fill: parent
|
||||
color: Color.mSurfaceVariant
|
||||
opacity: 0.85
|
||||
radius: Style.radiusM * scaling
|
||||
radius: Style.radiusM
|
||||
}
|
||||
|
||||
// Border
|
||||
@@ -38,7 +38,7 @@ NBox {
|
||||
color: Color.transparent
|
||||
border.color: Color.mOutline
|
||||
border.width: 1
|
||||
radius: Style.radiusM * scaling
|
||||
radius: Style.radiusM
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ NBox {
|
||||
sourceItem: Rectangle {
|
||||
width: root.width
|
||||
height: root.height
|
||||
radius: Style.radiusM * scaling
|
||||
radius: Style.radiusM
|
||||
color: "white"
|
||||
}
|
||||
}
|
||||
@@ -84,7 +84,7 @@ NBox {
|
||||
anchors.fill: parent
|
||||
values: CavaService.values
|
||||
fillColor: Color.mPrimary
|
||||
opacity: MediaService.trackArtUrl !== "" ? 0.4 : 0.8
|
||||
opacity: MediaService.trackArtUrl !== "" ? 0.5 : 0.8
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,7 +94,7 @@ NBox {
|
||||
anchors.fill: parent
|
||||
values: CavaService.values
|
||||
fillColor: Color.mPrimary
|
||||
opacity: MediaService.trackArtUrl !== "" ? 0.4 : 0.8
|
||||
opacity: MediaService.trackArtUrl !== "" ? 0.5 : 0.8
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,41 +104,41 @@ NBox {
|
||||
anchors.fill: parent
|
||||
values: CavaService.values
|
||||
fillColor: Color.mPrimary
|
||||
opacity: MediaService.trackArtUrl !== "" ? 0.4 : 0.8
|
||||
opacity: MediaService.trackArtUrl !== "" ? 0.5 : 0.8
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Player selector - positioned at the very top
|
||||
// Player selector
|
||||
Rectangle {
|
||||
id: playerSelectorButton
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.topMargin: Style.marginXS * scaling
|
||||
anchors.leftMargin: Style.marginM * scaling
|
||||
anchors.rightMargin: Style.marginM * scaling
|
||||
height: Style.barHeight * scaling
|
||||
anchors.topMargin: Style.marginXS
|
||||
anchors.leftMargin: Style.marginM
|
||||
anchors.rightMargin: Style.marginM
|
||||
height: Style.barHeight
|
||||
visible: MediaService.getAvailablePlayers().length > 1
|
||||
radius: Style.radiusM * scaling
|
||||
radius: Style.radiusM
|
||||
color: Color.transparent
|
||||
|
||||
property var currentPlayer: MediaService.getAvailablePlayers()[MediaService.selectedPlayerIndex]
|
||||
|
||||
RowLayout {
|
||||
anchors.fill: parent
|
||||
spacing: Style.marginS * scaling
|
||||
spacing: Style.marginS
|
||||
|
||||
NIcon {
|
||||
icon: "caret-down"
|
||||
pointSize: Style.fontSizeXXL * scaling
|
||||
pointSize: Style.fontSizeXXL
|
||||
color: Color.mOnSurfaceVariant
|
||||
}
|
||||
|
||||
NText {
|
||||
text: playerSelectorButton.currentPlayer ? playerSelectorButton.currentPlayer.identity : ""
|
||||
pointSize: Style.fontSizeXS * scaling
|
||||
pointSize: Style.fontSizeXS
|
||||
color: Color.mOnSurfaceVariant
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
@@ -170,7 +170,7 @@ NBox {
|
||||
NContextMenu {
|
||||
id: playerContextMenu
|
||||
parent: root
|
||||
width: 200 * scaling
|
||||
width: 200
|
||||
|
||||
onTriggered: function (action) {
|
||||
var index = parseInt(action)
|
||||
@@ -184,14 +184,14 @@ NBox {
|
||||
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
anchors.margins: Style.marginM * scaling
|
||||
anchors.margins: Style.marginM
|
||||
|
||||
// No media player detected
|
||||
ColumnLayout {
|
||||
id: fallback
|
||||
|
||||
visible: !main.visible
|
||||
spacing: Style.marginS * scaling
|
||||
spacing: Style.marginS
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
@@ -204,12 +204,12 @@ NBox {
|
||||
|
||||
ColumnLayout {
|
||||
anchors.centerIn: parent
|
||||
spacing: Style.marginL * scaling
|
||||
spacing: Style.marginL
|
||||
|
||||
Item {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.preferredWidth: Style.fontSizeXXXL * 4 * scaling
|
||||
Layout.preferredHeight: Style.fontSizeXXXL * 4 * scaling
|
||||
Layout.preferredWidth: Style.fontSizeXXXL * 4
|
||||
Layout.preferredHeight: Style.fontSizeXXXL * 4
|
||||
|
||||
// Pulsating audio circles (background)
|
||||
Repeater {
|
||||
@@ -258,7 +258,7 @@ NBox {
|
||||
NIcon {
|
||||
anchors.centerIn: parent
|
||||
icon: "disc"
|
||||
pointSize: Style.fontSizeXXXL * 3 * scaling
|
||||
pointSize: Style.fontSizeXXXL * 3
|
||||
color: Color.mOnSurfaceVariant
|
||||
|
||||
RotationAnimator on rotation {
|
||||
@@ -274,7 +274,7 @@ NBox {
|
||||
// Descriptive text
|
||||
ColumnLayout {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
spacing: Style.marginXS * scaling
|
||||
spacing: Style.marginXS
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -290,23 +290,23 @@ NBox {
|
||||
id: main
|
||||
|
||||
visible: MediaService.currentPlayer && MediaService.canPlay
|
||||
spacing: Style.marginS * scaling
|
||||
spacing: Style.marginS
|
||||
|
||||
// Spacer to push content down
|
||||
Item {
|
||||
Layout.preferredHeight: Style.marginM * scaling
|
||||
Layout.preferredHeight: Style.marginM
|
||||
}
|
||||
|
||||
// Metadata at the bottom left
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignLeft
|
||||
spacing: Style.marginXS * scaling
|
||||
spacing: Style.marginXS
|
||||
|
||||
NText {
|
||||
visible: MediaService.trackTitle !== ""
|
||||
text: MediaService.trackTitle
|
||||
pointSize: Style.fontSizeM * scaling
|
||||
pointSize: Style.fontSizeL
|
||||
font.weight: Style.fontWeightBold
|
||||
elide: Text.ElideRight
|
||||
wrapMode: Text.Wrap
|
||||
@@ -318,7 +318,7 @@ NBox {
|
||||
visible: MediaService.trackArtist !== ""
|
||||
text: MediaService.trackArtist
|
||||
color: Color.mPrimary
|
||||
pointSize: Style.fontSizeS * scaling
|
||||
pointSize: Style.fontSizeS
|
||||
elide: Text.ElideRight
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
@@ -327,7 +327,7 @@ NBox {
|
||||
visible: MediaService.trackAlbum !== ""
|
||||
text: MediaService.trackAlbum
|
||||
color: Color.mOnSurfaceVariant
|
||||
pointSize: Style.fontSizeM * scaling
|
||||
pointSize: Style.fontSizeM
|
||||
elide: Text.ElideRight
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
@@ -338,7 +338,7 @@ NBox {
|
||||
id: progressWrapper
|
||||
visible: (MediaService.currentPlayer && MediaService.trackLength > 0)
|
||||
Layout.fillWidth: true
|
||||
height: Style.baseWidgetSize * 0.5 * scaling
|
||||
height: Style.baseWidgetSize * 0.5
|
||||
|
||||
property real localSeekRatio: -1
|
||||
property real lastSentSeekRatio: -1
|
||||
@@ -376,7 +376,7 @@ NBox {
|
||||
stepSize: 0
|
||||
snapAlways: false
|
||||
enabled: MediaService.trackLength > 0 && MediaService.canSeek
|
||||
heightRatio: 0.65
|
||||
heightRatio: 0.6
|
||||
|
||||
onMoved: {
|
||||
progressWrapper.localSeekRatio = value
|
||||
@@ -408,12 +408,12 @@ NBox {
|
||||
|
||||
// Spacer to push media controls down
|
||||
Item {
|
||||
Layout.preferredHeight: Style.marginL * scaling
|
||||
Layout.preferredHeight: Style.marginL
|
||||
}
|
||||
|
||||
// Media controls
|
||||
RowLayout {
|
||||
spacing: Style.marginS * scaling
|
||||
spacing: Style.marginS
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
import QtQuick
|
||||
import QtQuick.Effects
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import Quickshell.Widgets
|
||||
import qs.Modules.Settings
|
||||
import qs.Modules.ControlCenter
|
||||
import qs.Commons
|
||||
import qs.Services
|
||||
import qs.Widgets
|
||||
|
||||
// Header card with avatar, user and quick actions
|
||||
NBox {
|
||||
id: root
|
||||
|
||||
property string uptimeText: "--"
|
||||
|
||||
RowLayout {
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.margins: Style.marginM
|
||||
spacing: Style.marginM
|
||||
|
||||
NImageCircled {
|
||||
Layout.preferredWidth: Math.round(Style.baseWidgetSize * 1.25 * Style.uiScaleRatio)
|
||||
Layout.preferredHeight: Math.round(Style.baseWidgetSize * 1.25 * Style.uiScaleRatio)
|
||||
imagePath: Settings.preprocessPath(Settings.data.general.avatarImage)
|
||||
fallbackIcon: "person"
|
||||
borderColor: Color.mPrimary
|
||||
borderWidth: Math.max(1, Style.borderM)
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: Style.marginXXS
|
||||
NText {
|
||||
text: Quickshell.env("USER") || "user"
|
||||
font.weight: Style.fontWeightBold
|
||||
font.capitalization: Font.Capitalize
|
||||
}
|
||||
NText {
|
||||
text: I18n.tr("system.uptime", {
|
||||
"uptime": uptimeText
|
||||
})
|
||||
pointSize: Style.fontSizeS
|
||||
color: Color.mOnSurfaceVariant
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
spacing: Style.marginS
|
||||
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
NIconButton {
|
||||
icon: "settings"
|
||||
tooltipText: I18n.tr("tooltips.open-settings")
|
||||
onClicked: {
|
||||
settingsPanel.requestedTab = SettingsPanel.Tab.General
|
||||
settingsPanel.open()
|
||||
}
|
||||
}
|
||||
|
||||
NIconButton {
|
||||
icon: "power"
|
||||
tooltipText: I18n.tr("tooltips.session-menu")
|
||||
onClicked: {
|
||||
sessionMenuPanel.open()
|
||||
controlCenterPanel.close()
|
||||
}
|
||||
}
|
||||
|
||||
NIconButton {
|
||||
icon: "close"
|
||||
tooltipText: I18n.tr("tooltips.close")
|
||||
onClicked: {
|
||||
controlCenterPanel.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------
|
||||
// Uptime
|
||||
Timer {
|
||||
interval: 60000
|
||||
repeat: true
|
||||
running: true
|
||||
onTriggered: uptimeProcess.running = true
|
||||
}
|
||||
|
||||
Process {
|
||||
id: uptimeProcess
|
||||
command: ["cat", "/proc/uptime"]
|
||||
running: true
|
||||
|
||||
stdout: StdioCollector {
|
||||
onStreamFinished: {
|
||||
var uptimeSeconds = parseFloat(this.text.trim().split(' ')[0])
|
||||
uptimeText = Time.formatVagueHumanReadableDuration(uptimeSeconds)
|
||||
uptimeProcess.running = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function updateSystemInfo() {
|
||||
uptimeProcess.running = true
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import qs.Commons
|
||||
import qs.Services
|
||||
import qs.Widgets
|
||||
import qs.Modules.ControlCenter
|
||||
import qs.Modules.ControlCenter.Cards
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: Style.marginL
|
||||
|
||||
NBox {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: root.shortcutsHeight
|
||||
|
||||
RowLayout {
|
||||
id: leftContent
|
||||
anchors.fill: parent
|
||||
spacing: Style.marginS
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: Settings.data.controlCenter.shortcuts.left
|
||||
delegate: ControlCenterWidgetLoader {
|
||||
Layout.fillWidth: false
|
||||
widgetId: (modelData.id !== undefined ? modelData.id : "")
|
||||
widgetProps: {
|
||||
"screen": root.modelData || null,
|
||||
"widgetId": modelData.id,
|
||||
"section": "quickSettings",
|
||||
"sectionWidgetIndex": index,
|
||||
"sectionWidgetsCount": Settings.data.controlCenter.shortcuts.left.length
|
||||
}
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NBox {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: root.shortcutsHeight
|
||||
|
||||
RowLayout {
|
||||
id: rightContent
|
||||
anchors.fill: parent
|
||||
spacing: Style.marginS
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: Settings.data.controlCenter.shortcuts.right
|
||||
delegate: ControlCenterWidgetLoader {
|
||||
Layout.fillWidth: false
|
||||
widgetId: (modelData.id !== undefined ? modelData.id : "")
|
||||
widgetProps: {
|
||||
"screen": root.modelData || null,
|
||||
"widgetId": modelData.id,
|
||||
"section": "quickSettings",
|
||||
"sectionWidgetIndex": index,
|
||||
"sectionWidgetsCount": Settings.data.controlCenter.shortcuts.right.length
|
||||
}
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,47 +9,50 @@ import qs.Widgets
|
||||
NBox {
|
||||
id: root
|
||||
|
||||
GridLayout {
|
||||
Item {
|
||||
id: content
|
||||
anchors.fill: parent
|
||||
anchors.margins: Style.marginXS * scaling
|
||||
columns: 2
|
||||
rows: 2
|
||||
columnSpacing: Style.marginS * scaling
|
||||
rowSpacing: Style.marginS * scaling
|
||||
anchors.margins: Style.marginS
|
||||
|
||||
NCircleStat {
|
||||
value: SystemStatService.cpuUsage
|
||||
icon: "cpu-usage"
|
||||
flat: true
|
||||
contentScale: 0.8
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
NCircleStat {
|
||||
value: SystemStatService.cpuTemp
|
||||
suffix: "°C"
|
||||
icon: "cpu-temperature"
|
||||
flat: true
|
||||
contentScale: 0.8
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
NCircleStat {
|
||||
value: SystemStatService.memPercent
|
||||
icon: "memory"
|
||||
flat: true
|
||||
contentScale: 0.8
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
NCircleStat {
|
||||
value: SystemStatService.diskPercent
|
||||
icon: "storage"
|
||||
flat: true
|
||||
contentScale: 0.8
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
property int widgetHeight: Math.round(65 * Style.uiScaleRatio)
|
||||
|
||||
ColumnLayout {
|
||||
anchors.centerIn: parent
|
||||
spacing: 0
|
||||
|
||||
NCircleStat {
|
||||
value: SystemStatService.cpuUsage
|
||||
icon: "cpu-usage"
|
||||
flat: true
|
||||
contentScale: 0.8
|
||||
height: content.widgetHeight
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
NCircleStat {
|
||||
value: SystemStatService.cpuTemp
|
||||
suffix: "°C"
|
||||
icon: "cpu-temperature"
|
||||
flat: true
|
||||
contentScale: 0.8
|
||||
height: content.widgetHeight
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
NCircleStat {
|
||||
value: SystemStatService.memPercent
|
||||
icon: "memory"
|
||||
flat: true
|
||||
contentScale: 0.8
|
||||
height: content.widgetHeight
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
NCircleStat {
|
||||
value: SystemStatService.diskPercent
|
||||
icon: "storage"
|
||||
flat: true
|
||||
contentScale: 0.8
|
||||
height: content.widgetHeight
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,330 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Effects
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import Quickshell.Widgets
|
||||
import Quickshell.Services.UPower
|
||||
import qs.Modules.Settings
|
||||
import qs.Modules.ControlCenter
|
||||
import qs.Commons
|
||||
import qs.Services
|
||||
import qs.Widgets
|
||||
|
||||
// Header card with avatar, user and quick actions
|
||||
NBox {
|
||||
id: root
|
||||
|
||||
property string uptimeText: "--"
|
||||
property real spacing: Style.marginS * scaling
|
||||
readonly property bool hasPP: PowerProfileService.available
|
||||
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
anchors.margins: Style.marginM * scaling
|
||||
|
||||
// Profile, Uptime, Settings, SessionMenu, Close
|
||||
RowLayout {
|
||||
id: content
|
||||
|
||||
spacing: root.spacing
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
|
||||
NImageCircled {
|
||||
width: Style.baseWidgetSize * 1.25 * scaling
|
||||
height: Style.baseWidgetSize * 1.25 * scaling
|
||||
imagePath: Settings.data.general.avatarImage
|
||||
fallbackIcon: "person"
|
||||
borderColor: Color.mPrimary
|
||||
borderWidth: Math.max(1, Style.borderM * scaling)
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
Layout.topMargin: Style.marginXS * scaling
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: Style.marginXXS * scaling
|
||||
NText {
|
||||
text: Quickshell.env("USER") || "user"
|
||||
font.weight: Style.fontWeightBold
|
||||
font.capitalization: Font.Capitalize
|
||||
}
|
||||
NText {
|
||||
text: I18n.tr("system.uptime", {
|
||||
"uptime": uptimeText
|
||||
})
|
||||
pointSize: Style.fontSizeS * scaling
|
||||
color: Color.mOnSurfaceVariant
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
spacing: root.spacing
|
||||
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
||||
|
||||
NIconButton {
|
||||
baseSize: Style.baseWidgetSize * 0.9
|
||||
icon: "settings"
|
||||
tooltipText: I18n.tr("tooltips.open-settings")
|
||||
onClicked: {
|
||||
settingsPanel.requestedTab = SettingsPanel.Tab.General
|
||||
settingsPanel.open()
|
||||
}
|
||||
}
|
||||
|
||||
NIconButton {
|
||||
baseSize: Style.baseWidgetSize * 0.9
|
||||
icon: "power"
|
||||
tooltipText: I18n.tr("tooltips.session-menu")
|
||||
onClicked: {
|
||||
sessionMenuPanel.open()
|
||||
controlCenterPanel.close()
|
||||
}
|
||||
}
|
||||
|
||||
NIconButton {
|
||||
baseSize: Style.baseWidgetSize * 0.9
|
||||
icon: "close"
|
||||
tooltipText: I18n.tr("tooltips.close")
|
||||
onClicked: {
|
||||
controlCenterPanel.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
id: utilitiesRow
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
Layout.topMargin: Style.marginM * scaling
|
||||
Layout.bottomMargin: Style.marginM * scaling
|
||||
Layout.fillWidth: true
|
||||
|
||||
// Left group - Media & Display
|
||||
Rectangle {
|
||||
color: Color.mSurface
|
||||
radius: Style.radiusM * scaling
|
||||
Layout.preferredHeight: Style.baseWidgetSize * 1.2 * scaling
|
||||
Layout.preferredWidth: childrenRect.width + (Style.marginS * scaling * 2)
|
||||
|
||||
RowLayout {
|
||||
anchors.centerIn: parent
|
||||
spacing: Style.marginM * scaling
|
||||
|
||||
// Screen Recorder
|
||||
NIconButton {
|
||||
baseSize: Style.baseWidgetSize * 0.9
|
||||
icon: "camera-video"
|
||||
visible: ProgramCheckerService.gpuScreenRecorderAvailable
|
||||
tooltipText: ScreenRecorderService.isRecording ? I18n.tr("tooltips.stop-screen-recording") : I18n.tr("tooltips.start-screen-recording")
|
||||
colorBg: ScreenRecorderService.isRecording ? Color.mPrimary : Color.mSurfaceVariant
|
||||
colorFg: ScreenRecorderService.isRecording ? Color.mOnPrimary : Color.mPrimary
|
||||
onClicked: {
|
||||
ScreenRecorderService.toggleRecording()
|
||||
if (!ScreenRecorderService.isRecording) {
|
||||
var panel = PanelService.getPanel("controlCenterPanel")
|
||||
panel?.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Wallpaper
|
||||
NIconButton {
|
||||
baseSize: Style.baseWidgetSize * 0.9
|
||||
visible: Settings.data.wallpaper.enabled
|
||||
icon: "wallpaper-selector"
|
||||
tooltipText: I18n.tr("tooltips.wallpaper-selector")
|
||||
onClicked: PanelService.getPanel("wallpaperPanel")?.toggle(this)
|
||||
onRightClicked: WallpaperService.setRandomWallpaper()
|
||||
}
|
||||
|
||||
// Night Light
|
||||
NIconButton {
|
||||
baseSize: Style.baseWidgetSize * 0.9
|
||||
visible: ProgramCheckerService.wlsunsetAvailable
|
||||
colorBg: Settings.data.nightLight.forced ? Color.mPrimary : Color.transparent
|
||||
colorFg: Settings.data.nightLight.forced ? Color.mOnPrimary : Color.mPrimary
|
||||
icon: Settings.data.nightLight.enabled ? (Settings.data.nightLight.forced ? "nightlight-forced" : "nightlight-on") : "nightlight-off"
|
||||
tooltipText: Settings.data.nightLight.enabled ? (Settings.data.nightLight.forced ? I18n.tr("tooltips.night-light-forced") : I18n.tr("tooltips.night-light-enabled")) : I18n.tr("tooltips.night-light-disabled")
|
||||
onClicked: {
|
||||
if (!Settings.data.nightLight.enabled) {
|
||||
Settings.data.nightLight.enabled = true
|
||||
Settings.data.nightLight.forced = false
|
||||
} else if (Settings.data.nightLight.enabled && !Settings.data.nightLight.forced) {
|
||||
Settings.data.nightLight.forced = true
|
||||
} else {
|
||||
Settings.data.nightLight.enabled = false
|
||||
Settings.data.nightLight.forced = false
|
||||
}
|
||||
}
|
||||
|
||||
onRightClicked: {
|
||||
var settingsPanel = PanelService.getPanel("settingsPanel")
|
||||
settingsPanel.requestedTab = SettingsPanel.Tab.Display
|
||||
settingsPanel.open()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Spacer
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
// Center group - Network & Caffeine
|
||||
Rectangle {
|
||||
color: Color.mSurface
|
||||
radius: Style.radiusM * scaling
|
||||
Layout.preferredHeight: Style.baseWidgetSize * 1.2 * scaling
|
||||
Layout.preferredWidth: childrenRect.width + (Style.marginS * scaling * 2)
|
||||
|
||||
RowLayout {
|
||||
anchors.centerIn: parent
|
||||
spacing: Style.marginM * scaling
|
||||
|
||||
// Wifi
|
||||
NIconButton {
|
||||
id: wifiButton
|
||||
baseSize: Style.baseWidgetSize * 0.9
|
||||
tooltipText: I18n.tr("tooltips.manage-wifi")
|
||||
icon: {
|
||||
try {
|
||||
if (NetworkService.ethernetConnected) {
|
||||
return "ethernet"
|
||||
}
|
||||
let connected = false
|
||||
let signalStrength = 0
|
||||
for (const net in NetworkService.networks) {
|
||||
if (NetworkService.networks[net].connected) {
|
||||
connected = true
|
||||
signalStrength = NetworkService.networks[net].signal
|
||||
break
|
||||
}
|
||||
}
|
||||
return connected ? NetworkService.signalIcon(signalStrength) : "wifi-off"
|
||||
} catch (error) {
|
||||
Logger.error("Wi-Fi", "Error getting icon:", error)
|
||||
return "signal_wifi_bad"
|
||||
}
|
||||
}
|
||||
onClicked: PanelService.getPanel("wifiPanel")?.toggle(this)
|
||||
onRightClicked: PanelService.getPanel("wifiPanel")?.toggle(this)
|
||||
}
|
||||
|
||||
// Bluetooth
|
||||
NIconButton {
|
||||
baseSize: Style.baseWidgetSize * 0.9
|
||||
tooltipText: I18n.tr("tooltips.bluetooth-devices")
|
||||
icon: BluetoothService.enabled ? "bluetooth" : "bluetooth-off"
|
||||
onClicked: PanelService.getPanel("bluetoothPanel")?.toggle(this)
|
||||
onRightClicked: PanelService.getPanel("bluetoothPanel")?.toggle(this)
|
||||
}
|
||||
|
||||
// Caffeine (Keep Awake)
|
||||
NIconButton {
|
||||
baseSize: Style.baseWidgetSize * 0.9
|
||||
icon: IdleInhibitorService.isInhibited ? "keep-awake-on" : "keep-awake-off"
|
||||
tooltipText: IdleInhibitorService.isInhibited ? I18n.tr("tooltips.disable-keep-awake") : I18n.tr("tooltips.enable-keep-awake")
|
||||
colorBg: IdleInhibitorService.isInhibited ? Color.mPrimary : Color.mSurfaceVariant
|
||||
colorFg: IdleInhibitorService.isInhibited ? Color.mOnPrimary : Color.mPrimary
|
||||
onClicked: {
|
||||
IdleInhibitorService.manualToggle()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Spacer
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
// Right group - Power Profiles
|
||||
Rectangle {
|
||||
color: Color.mSurface
|
||||
radius: Style.radiusM * scaling
|
||||
Layout.preferredHeight: Style.baseWidgetSize * 1.2 * scaling
|
||||
Layout.preferredWidth: childrenRect.width + (Style.marginS * scaling * 2)
|
||||
|
||||
RowLayout {
|
||||
anchors.centerIn: parent
|
||||
spacing: Style.marginM * scaling
|
||||
|
||||
// Performance
|
||||
NIconButton {
|
||||
baseSize: Style.baseWidgetSize * 0.9
|
||||
icon: PowerProfileService.getIcon(PowerProfile.Performance)
|
||||
tooltipText: I18n.tr("tooltips.set-power-profile", {
|
||||
"profile": PowerProfileService.getName(PowerProfile.Performance)
|
||||
})
|
||||
enabled: hasPP
|
||||
opacity: enabled ? Style.opacityFull : Style.opacityMedium
|
||||
colorBg: (enabled && PowerProfileService.profile === PowerProfile.Performance) ? Color.mPrimary : Color.mSurfaceVariant
|
||||
colorFg: (enabled && PowerProfileService.profile === PowerProfile.Performance) ? Color.mOnPrimary : Color.mPrimary
|
||||
onClicked: PowerProfileService.setProfile(PowerProfile.Performance)
|
||||
}
|
||||
|
||||
// Balanced
|
||||
NIconButton {
|
||||
baseSize: Style.baseWidgetSize * 0.9
|
||||
icon: PowerProfileService.getIcon(PowerProfile.Balanced)
|
||||
tooltipText: I18n.tr("tooltips.set-power-profile", {
|
||||
"profile": PowerProfileService.getName(PowerProfile.Balanced)
|
||||
})
|
||||
enabled: hasPP
|
||||
opacity: enabled ? Style.opacityFull : Style.opacityMedium
|
||||
colorBg: (enabled && PowerProfileService.profile === PowerProfile.Balanced) ? Color.mPrimary : Color.mSurfaceVariant
|
||||
colorFg: (enabled && PowerProfileService.profile === PowerProfile.Balanced) ? Color.mOnPrimary : Color.mPrimary
|
||||
onClicked: PowerProfileService.setProfile(PowerProfile.Balanced)
|
||||
}
|
||||
|
||||
// Eco
|
||||
NIconButton {
|
||||
baseSize: Style.baseWidgetSize * 0.9
|
||||
icon: PowerProfileService.getIcon(PowerProfile.PowerSaver)
|
||||
tooltipText: I18n.tr("tooltips.set-power-profile", {
|
||||
"profile": PowerProfileService.getName(PowerProfile.PowerSaver)
|
||||
})
|
||||
enabled: hasPP
|
||||
opacity: enabled ? Style.opacityFull : Style.opacityMedium
|
||||
colorBg: (enabled && PowerProfileService.profile === PowerProfile.PowerSaver) ? Color.mPrimary : Color.mSurfaceVariant
|
||||
colorFg: (enabled && PowerProfileService.profile === PowerProfile.PowerSaver) ? Color.mOnPrimary : Color.mPrimary
|
||||
onClicked: PowerProfileService.setProfile(PowerProfile.PowerSaver)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------
|
||||
// Uptime
|
||||
Timer {
|
||||
interval: 60000
|
||||
repeat: true
|
||||
running: true
|
||||
onTriggered: uptimeProcess.running = true
|
||||
}
|
||||
|
||||
Process {
|
||||
id: uptimeProcess
|
||||
command: ["cat", "/proc/uptime"]
|
||||
running: true
|
||||
|
||||
stdout: StdioCollector {
|
||||
onStreamFinished: {
|
||||
var uptimeSeconds = parseFloat(this.text.trim().split(' ')[0])
|
||||
uptimeText = Time.formatVagueHumanReadableDuration(uptimeSeconds)
|
||||
uptimeProcess.running = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function updateSystemInfo() {
|
||||
uptimeProcess.running = true
|
||||
}
|
||||
}
|
||||
@@ -16,28 +16,28 @@ NBox {
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
anchors.margins: Style.marginM * scaling
|
||||
spacing: Style.marginM * scaling
|
||||
anchors.margins: Style.marginM
|
||||
spacing: Style.marginM
|
||||
clip: true
|
||||
|
||||
RowLayout {
|
||||
spacing: Style.marginS * scaling
|
||||
spacing: Style.marginS
|
||||
NIcon {
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
icon: weatherReady ? LocationService.weatherSymbolFromCode(LocationService.data.weather.current_weather.weathercode) : ""
|
||||
pointSize: Style.fontSizeXXXL * 1.75 * scaling
|
||||
pointSize: Style.fontSizeXXXL * 1.75
|
||||
color: Color.mPrimary
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
spacing: Style.marginXXS * scaling
|
||||
spacing: Style.marginXXS
|
||||
NText {
|
||||
text: {
|
||||
// Ensure the name is not too long if one had to specify the country
|
||||
const chunks = Settings.data.location.name.split(",")
|
||||
return chunks[0]
|
||||
}
|
||||
pointSize: Style.fontSizeL * scaling
|
||||
pointSize: Style.fontSizeL
|
||||
font.weight: Style.fontWeightBold
|
||||
}
|
||||
|
||||
@@ -57,13 +57,13 @@ NBox {
|
||||
temp = Math.round(temp)
|
||||
return `${temp}°${suffix}`
|
||||
}
|
||||
pointSize: Style.fontSizeXL * scaling
|
||||
pointSize: Style.fontSizeXL
|
||||
font.weight: Style.fontWeightBold
|
||||
}
|
||||
|
||||
NText {
|
||||
text: weatherReady ? `(${LocationService.data.weather.timezone_abbreviation})` : ""
|
||||
pointSize: Style.fontSizeXS * scaling
|
||||
pointSize: Style.fontSizeXS
|
||||
color: Color.mOnSurfaceVariant
|
||||
visible: LocationService.data.weather
|
||||
}
|
||||
@@ -80,12 +80,12 @@ NBox {
|
||||
visible: weatherReady
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
|
||||
spacing: Style.marginL * scaling
|
||||
spacing: Style.marginL
|
||||
Repeater {
|
||||
model: weatherReady ? LocationService.data.weather.daily.time : []
|
||||
delegate: ColumnLayout {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
spacing: Style.marginS * scaling
|
||||
spacing: Style.marginXS
|
||||
NText {
|
||||
text: {
|
||||
var weatherDate = new Date(LocationService.data.weather.daily.time[index].replace(/-/g, "/"))
|
||||
@@ -97,7 +97,7 @@ NBox {
|
||||
NIcon {
|
||||
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
|
||||
icon: LocationService.weatherSymbolFromCode(LocationService.data.weather.daily.weathercode[index])
|
||||
pointSize: Style.fontSizeXXL * 1.6 * scaling
|
||||
pointSize: Style.fontSizeXXL * 1.6
|
||||
color: Color.mPrimary
|
||||
}
|
||||
NText {
|
||||
@@ -113,7 +113,7 @@ NBox {
|
||||
min = Math.round(min)
|
||||
return `${max}°/${min}°`
|
||||
}
|
||||
pointSize: Style.fontSizeXS * scaling
|
||||
pointSize: Style.fontSizeXS
|
||||
color: Color.mOnSurfaceVariant
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,9 +10,39 @@ import qs.Widgets
|
||||
NPanel {
|
||||
id: root
|
||||
|
||||
preferredWidth: 480
|
||||
preferredHeight: 580
|
||||
panelKeyboardFocus: true
|
||||
preferredWidth: Math.round(460 * Style.uiScaleRatio)
|
||||
preferredHeight: {
|
||||
var height = 0
|
||||
var count = 0
|
||||
for (var i = 0; i < Settings.data.controlCenter.cards.length; i++) {
|
||||
const card = Settings.data.controlCenter.cards[i]
|
||||
if (!card.enabled) {
|
||||
continue
|
||||
}
|
||||
count++
|
||||
switch (card.id) {
|
||||
case "profile-card":
|
||||
height += profileHeight
|
||||
break
|
||||
case "shortcuts-card":
|
||||
height += shortcutsHeight
|
||||
break
|
||||
case "audio-card":
|
||||
height += audioHeight
|
||||
break
|
||||
case "weather-card":
|
||||
height += weatherHeight
|
||||
break
|
||||
case "media-sysmon-card":
|
||||
height += mediaSysMonHeight
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
return height + (count + 1) * Style.marginL
|
||||
}
|
||||
|
||||
// Positioning
|
||||
readonly property string controlCenterPosition: Settings.data.controlCenter.position
|
||||
@@ -23,46 +53,97 @@ NPanel {
|
||||
panelAnchorBottom: controlCenterPosition !== "close_to_bar_button" && controlCenterPosition.startsWith("bottom_")
|
||||
panelAnchorTop: controlCenterPosition !== "close_to_bar_button" && controlCenterPosition.startsWith("top_")
|
||||
|
||||
readonly property int profileHeight: Math.round(64 * Style.uiScaleRatio)
|
||||
readonly property int shortcutsHeight: Math.round(52 * Style.uiScaleRatio)
|
||||
readonly property int audioHeight: Math.round(60 * Style.uiScaleRatio)
|
||||
readonly property int weatherHeight: Math.round(190 * Style.uiScaleRatio)
|
||||
readonly property int mediaSysMonHeight: Math.round(260 * Style.uiScaleRatio)
|
||||
|
||||
panelContent: Item {
|
||||
id: content
|
||||
|
||||
property real cardSpacing: Style.marginL * scaling
|
||||
|
||||
// Layout content
|
||||
ColumnLayout {
|
||||
id: layout
|
||||
anchors.fill: parent
|
||||
anchors.margins: content.cardSpacing
|
||||
spacing: content.cardSpacing
|
||||
x: Style.marginL
|
||||
y: Style.marginL
|
||||
width: parent.width - (Style.marginL * 2)
|
||||
spacing: Style.marginL
|
||||
|
||||
// Top Card: profile + utilities
|
||||
TopCard {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: Math.max(124 * scaling)
|
||||
Repeater {
|
||||
model: Settings.data.controlCenter.cards
|
||||
Loader {
|
||||
active: modelData.enabled
|
||||
visible: active
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: {
|
||||
switch (modelData.id) {
|
||||
case "profile-card":
|
||||
return profileHeight
|
||||
case "shortcuts-card":
|
||||
return shortcutsHeight
|
||||
case "audio-card":
|
||||
return audioHeight
|
||||
case "weather-card":
|
||||
return weatherHeight
|
||||
case "media-sysmon-card":
|
||||
return mediaSysMonHeight
|
||||
default:
|
||||
return 0
|
||||
}
|
||||
}
|
||||
sourceComponent: {
|
||||
switch (modelData.id) {
|
||||
case "profile-card":
|
||||
return profileCard
|
||||
case "shortcuts-card":
|
||||
return shortcutsCard
|
||||
case "audio-card":
|
||||
return audioCard
|
||||
case "weather-card":
|
||||
return weatherCard
|
||||
case "media-sysmon-card":
|
||||
return mediaSysMonCard
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Weather
|
||||
WeatherCard {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: Math.max(196 * scaling)
|
||||
}
|
||||
Component {
|
||||
id: profileCard
|
||||
ProfileCard {}
|
||||
}
|
||||
|
||||
// Media + stats column
|
||||
Component {
|
||||
id: shortcutsCard
|
||||
ShortcutsCard {}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: audioCard
|
||||
AudioCard {}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: weatherCard
|
||||
WeatherCard {}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: mediaSysMonCard
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: Math.max(196 * scaling)
|
||||
spacing: content.cardSpacing
|
||||
spacing: Style.marginL
|
||||
|
||||
// Media card
|
||||
MediaCard {
|
||||
Layout.preferredWidth: Math.max(270 * scaling)
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
|
||||
// System monitors combined in one card
|
||||
SystemMonitorCard {
|
||||
Layout.preferredWidth: Math.max(160 * scaling)
|
||||
Layout.preferredHeight: Math.max(196 * scaling)
|
||||
Layout.preferredWidth: Math.round(Style.baseWidgetSize * 2.625)
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
import qs.Services
|
||||
import qs.Commons
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
property string widgetId: ""
|
||||
property var widgetProps: ({})
|
||||
property string screenName: widgetProps && widgetProps.screen ? widgetProps.screen.name : ""
|
||||
property string section: widgetProps && widgetProps.section || ""
|
||||
property int sectionIndex: widgetProps && widgetProps.sectionWidgetIndex || 0
|
||||
|
||||
// Don't reserve space unless the loaded widget is really visible
|
||||
implicitWidth: getImplicitSize(loader.item, "implicitWidth")
|
||||
implicitHeight: getImplicitSize(loader.item, "implicitHeight")
|
||||
|
||||
function getImplicitSize(item, prop) {
|
||||
return (item && item.visible) ? item[prop] : 0
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: loader
|
||||
anchors.fill: parent
|
||||
active: widgetId !== ""
|
||||
asynchronous: false
|
||||
sourceComponent: {
|
||||
if (!active) {
|
||||
return null
|
||||
}
|
||||
return ControlCenterWidgetRegistry.getWidget(widgetId)
|
||||
}
|
||||
|
||||
onLoaded: {
|
||||
if (item && widgetProps) {
|
||||
// Apply properties to loaded widget
|
||||
for (var prop in widgetProps) {
|
||||
if (item.hasOwnProperty(prop)) {
|
||||
item[prop] = widgetProps[prop]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (item.hasOwnProperty("onLoaded")) {
|
||||
item.onLoaded()
|
||||
}
|
||||
|
||||
//Logger.log("ControlCenterWidgetLoader", "Loaded", widgetId, "on screen", item.screen.name)
|
||||
}
|
||||
|
||||
Component.onDestruction: {
|
||||
// Explicitly clear references
|
||||
widgetProps = null
|
||||
}
|
||||
}
|
||||
|
||||
// Error handling
|
||||
onWidgetIdChanged: {
|
||||
if (widgetId && !ControlCenterWidgetRegistry.hasWidget(widgetId)) {
|
||||
Logger.warn("ControlCenterWidgetLoader", "Widget not found in registry:", widgetId)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import qs.Commons
|
||||
import qs.Services
|
||||
import qs.Widgets
|
||||
|
||||
NIconButtonHot {
|
||||
property ShellScreen screen
|
||||
|
||||
icon: BluetoothService.enabled ? "bluetooth" : "bluetooth-off"
|
||||
tooltipText: I18n.tr("quickSettings.bluetooth.tooltip.action")
|
||||
onClicked: PanelService.getPanel("bluetoothPanel")?.toggle(this)
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import qs.Commons
|
||||
import qs.Services
|
||||
import qs.Widgets
|
||||
|
||||
NIconButtonHot {
|
||||
property ShellScreen screen
|
||||
|
||||
icon: IdleInhibitorService.isInhibited ? "keep-awake-on" : "keep-awake-off"
|
||||
hot: IdleInhibitorService.isInhibited
|
||||
tooltipText: I18n.tr("quickSettings.keepAwake.tooltip.action")
|
||||
onClicked: IdleInhibitorService.manualToggle()
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import qs.Commons
|
||||
import qs.Services
|
||||
import qs.Widgets
|
||||
|
||||
NIconButtonHot {
|
||||
property ShellScreen screen
|
||||
|
||||
enabled: ProgramCheckerService.wlsunsetAvailable
|
||||
icon: Settings.data.nightLight.enabled ? (Settings.data.nightLight.forced ? "nightlight-forced" : "nightlight-on") : "nightlight-off"
|
||||
hot: !Settings.data.nightLight.enabled || Settings.data.nightLight.forced
|
||||
tooltipText: I18n.tr("quickSettings.nightLight.tooltip.action")
|
||||
|
||||
onClicked: {
|
||||
if (!Settings.data.nightLight.enabled) {
|
||||
Settings.data.nightLight.enabled = true
|
||||
Settings.data.nightLight.forced = false
|
||||
} else if (Settings.data.nightLight.enabled && !Settings.data.nightLight.forced) {
|
||||
Settings.data.nightLight.forced = true
|
||||
} else {
|
||||
Settings.data.nightLight.enabled = false
|
||||
Settings.data.nightLight.forced = false
|
||||
}
|
||||
}
|
||||
|
||||
onRightClicked: {
|
||||
var settingsPanel = PanelService.getPanel("settingsPanel")
|
||||
settingsPanel.requestedTab = SettingsPanel.Tab.Display
|
||||
settingsPanel.open()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import qs.Commons
|
||||
import qs.Services
|
||||
import qs.Widgets
|
||||
|
||||
NIconButtonHot {
|
||||
property ShellScreen screen
|
||||
|
||||
icon: Settings.data.notifications.doNotDisturb ? "bell-off" : "bell"
|
||||
hot: Settings.data.notifications.doNotDisturb
|
||||
tooltipText: I18n.tr("quickSettings.notifications.tooltip.action")
|
||||
onClicked: PanelService.getPanel("notificationHistoryPanel")?.toggle(this)
|
||||
onRightClicked: Settings.data.notifications.doNotDisturb = !Settings.data.notifications.doNotDisturb
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import Quickshell.Services.UPower
|
||||
import qs.Commons
|
||||
import qs.Services
|
||||
import qs.Widgets
|
||||
|
||||
// Performance
|
||||
NIconButtonHot {
|
||||
property ShellScreen screen
|
||||
|
||||
readonly property bool hasPP: PowerProfileService.available
|
||||
|
||||
enabled: hasPP
|
||||
icon: PowerProfileService.getIcon()
|
||||
hot: !PowerProfileService.isDefault()
|
||||
tooltipText: I18n.tr("quickSettings.powerProfile.tooltip.action")
|
||||
onClicked: {
|
||||
PowerProfileService.cycleProfile()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import qs.Commons
|
||||
import qs.Services
|
||||
import qs.Widgets
|
||||
|
||||
NIconButtonHot {
|
||||
property ShellScreen screen
|
||||
|
||||
enabled: ProgramCheckerService.gpuScreenRecorderAvailable
|
||||
icon: "camera-video"
|
||||
hot: ScreenRecorderService.isRecording
|
||||
tooltipText: I18n.tr("quickSettings.screenRecorder.tooltip.action")
|
||||
onClicked: {
|
||||
ScreenRecorderService.toggleRecording()
|
||||
if (!ScreenRecorderService.isRecording) {
|
||||
var panel = PanelService.getPanel("controlCenterPanel")
|
||||
panel?.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import qs.Commons
|
||||
import qs.Services
|
||||
import qs.Widgets
|
||||
|
||||
NIconButtonHot {
|
||||
property ShellScreen screen
|
||||
|
||||
enabled: Settings.data.wallpaper.enabled
|
||||
icon: "wallpaper-selector"
|
||||
tooltipText: I18n.tr("quickSettings.wallpaperSelector.tooltip.action")
|
||||
onClicked: PanelService.getPanel("wallpaperPanel")?.toggle(this)
|
||||
onRightClicked: WallpaperService.setRandomWallpaper()
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import qs.Commons
|
||||
import qs.Services
|
||||
import qs.Widgets
|
||||
|
||||
NIconButtonHot {
|
||||
property ShellScreen screen
|
||||
|
||||
icon: {
|
||||
try {
|
||||
if (NetworkService.ethernetConnected) {
|
||||
return "ethernet"
|
||||
}
|
||||
let connected = false
|
||||
let signalStrength = 0
|
||||
for (const net in NetworkService.networks) {
|
||||
if (NetworkService.networks[net].connected) {
|
||||
connected = true
|
||||
signalStrength = NetworkService.networks[net].signal
|
||||
break
|
||||
}
|
||||
}
|
||||
return connected ? NetworkService.signalIcon(signalStrength) : "wifi-off"
|
||||
} catch (error) {
|
||||
Logger.error("Wi-Fi", "Error getting icon:", error)
|
||||
return "signal_wifi_bad"
|
||||
}
|
||||
}
|
||||
|
||||
tooltipText: I18n.tr("quickSettings.wifi.tooltip.action")
|
||||
onClicked: PanelService.getPanel("wifiPanel")?.toggle(this)
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user