mirror of
https://github.com/zoriya/noctalia-shell.git
synced 2026-08-15 18:43:59 +00:00
Merge branch 'main' into Consistent-Hover
This commit is contained in:
+88
-21
@@ -31,6 +31,10 @@
|
||||
"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": {
|
||||
@@ -829,21 +833,54 @@
|
||||
"search-placeholder": "Widgets suchen..."
|
||||
},
|
||||
"active-window": {
|
||||
"auto-hide": "Automatisch ausblenden",
|
||||
"scrolling-mode": "Scrollmodus",
|
||||
"show-app-icon": "App-Symbol anzeigen"
|
||||
"auto-hide": {
|
||||
"label": "Automatisch ausblenden",
|
||||
"description": "Widget automatisch ausblenden, wenn kein Fenster aktiv ist."
|
||||
},
|
||||
"show-app-icon": {
|
||||
"label": "App-Symbol anzeigen",
|
||||
"description": "Anwendungssymbol neben dem Fenstertitel anzeigen."
|
||||
},
|
||||
"scrolling-mode": {
|
||||
"label": "Scrollmodus",
|
||||
"description": "Steuern, wann Textscrolling für lange Fenstertitel aktiviert ist."
|
||||
}
|
||||
},
|
||||
"system-monitor": {
|
||||
"cpu-usage": "CPU-Auslastung",
|
||||
"cpu-temperature": "CPU-Temperatur",
|
||||
"memory-usage": "Speicherverbrauch",
|
||||
"memory-percentage": "Speicher als Prozentsatz",
|
||||
"network-traffic": "Netzwerkverkehr",
|
||||
"storage-usage": "Speichernutzung"
|
||||
"cpu-usage": {
|
||||
"label": "CPU-Auslastung",
|
||||
"description": "Aktuelle CPU-Auslastung in Prozent anzeigen."
|
||||
},
|
||||
"cpu-temperature": {
|
||||
"label": "CPU-Temperatur",
|
||||
"description": "CPU-Temperaturwerte anzeigen, falls verfügbar."
|
||||
},
|
||||
"memory-usage": {
|
||||
"label": "Speicherverbrauch",
|
||||
"description": "Aktuelle RAM-Nutzungsinformationen anzeigen."
|
||||
},
|
||||
"memory-percentage": {
|
||||
"label": "Speicher als Prozentsatz",
|
||||
"description": "Speicherverbrauch als Prozentsatz statt absolute Werte anzeigen."
|
||||
},
|
||||
"network-traffic": {
|
||||
"label": "Netzwerkverkehr",
|
||||
"description": "Upload- und Download-Geschwindigkeiten anzeigen."
|
||||
},
|
||||
"storage-usage": {
|
||||
"label": "Speichernutzung",
|
||||
"description": "Festplattenspeicher-Nutzungsinformationen anzeigen."
|
||||
}
|
||||
},
|
||||
"notification-history": {
|
||||
"show-unread-badge": "Badge für ungelesene Nachrichten anzeigen",
|
||||
"hide-badge-when-zero": "Badge ausblenden, wenn null"
|
||||
"show-unread-badge": {
|
||||
"label": "Badge für ungelesene Nachrichten anzeigen",
|
||||
"description": "Badge mit der Anzahl ungelesener Benachrichtigungen anzeigen."
|
||||
},
|
||||
"hide-badge-when-zero": {
|
||||
"label": "Badge ausblenden, wenn null",
|
||||
"description": "Benachrichtigungs-Badge ausblenden, wenn keine ungelesenen Benachrichtigungen vorhanden sind."
|
||||
}
|
||||
},
|
||||
"battery": {
|
||||
"display-mode": {
|
||||
@@ -856,7 +893,10 @@
|
||||
}
|
||||
},
|
||||
"control-center": {
|
||||
"use-distro-logo": "Distro-Logo anstelle von Symbol verwenden",
|
||||
"use-distro-logo": {
|
||||
"label": "Distro-Logo anstelle von Symbol verwenden",
|
||||
"description": "Logo Ihrer Distribution anstelle eines benutzerdefinierten Symbols verwenden."
|
||||
},
|
||||
"icon": {
|
||||
"label": "Symbol",
|
||||
"description": "Symbol aus der Bibliothek oder eine benutzerdefinierte Datei auswählen."
|
||||
@@ -878,7 +918,10 @@
|
||||
}
|
||||
},
|
||||
"workspace": {
|
||||
"label-mode": "Beschriftungsmodus",
|
||||
"label-mode": {
|
||||
"label": "Beschriftungsmodus",
|
||||
"description": "Wählen Sie, wie Arbeitsbereichs-Beschriftungen angezeigt werden."
|
||||
},
|
||||
"hide-unoccupied": {
|
||||
"label": "Unbesetzte ausblenden",
|
||||
"description": "Arbeitsbereiche ohne Fenster nicht anzeigen."
|
||||
@@ -908,9 +951,18 @@
|
||||
"description": "Symbol aus der Bibliothek auswählen."
|
||||
},
|
||||
"browse": "Durchsuchen",
|
||||
"left-click": "Linksklick",
|
||||
"right-click": "Rechtsklick",
|
||||
"middle-click": "Mittelklick",
|
||||
"left-click": {
|
||||
"label": "Linksklick",
|
||||
"description": "Befehl, der ausgeführt wird, wenn die Schaltfläche links angeklickt wird."
|
||||
},
|
||||
"right-click": {
|
||||
"label": "Rechtsklick",
|
||||
"description": "Befehl, der ausgeführt wird, wenn die Schaltfläche rechts angeklickt wird."
|
||||
},
|
||||
"middle-click": {
|
||||
"label": "Mittelklick",
|
||||
"description": "Befehl, der ausgeführt wird, wenn die Schaltfläche mit der mittleren Maustaste angeklickt wird."
|
||||
},
|
||||
"dynamic-text": "Dynamischer Text",
|
||||
"display-command-output": {
|
||||
"label": "Befehlsausgabe anzeigen",
|
||||
@@ -922,11 +974,26 @@
|
||||
}
|
||||
},
|
||||
"media-mini": {
|
||||
"auto-hide": "Automatisch ausblenden",
|
||||
"show-album-art": "Albumcover anzeigen",
|
||||
"show-visualizer": "Visualizer anzeigen",
|
||||
"visualizer-type": "Visualizer-Typ",
|
||||
"scrolling-mode": "Scrollmodus"
|
||||
"auto-hide": {
|
||||
"label": "Automatisch ausblenden",
|
||||
"description": "Widget automatisch ausblenden, wenn keine Medien abgespielt werden."
|
||||
},
|
||||
"show-album-art": {
|
||||
"label": "Albumcover anzeigen",
|
||||
"description": "Albumcover des aktuell abgespielten Tracks anzeigen."
|
||||
},
|
||||
"show-visualizer": {
|
||||
"label": "Visualizer anzeigen",
|
||||
"description": "Audio-Visualizer anzeigen, wenn Musik abgespielt wird."
|
||||
},
|
||||
"visualizer-type": {
|
||||
"label": "Visualizer-Typ",
|
||||
"description": "Stil des Audio-Visualizers auswählen."
|
||||
},
|
||||
"scrolling-mode": {
|
||||
"label": "Scrollmodus",
|
||||
"description": "Steuern, wann Textscrolling für lange Track-Titel aktiviert ist."
|
||||
}
|
||||
},
|
||||
"clock": {
|
||||
"use-primary-color": {
|
||||
|
||||
+84
-21
@@ -816,21 +816,54 @@
|
||||
"search-placeholder": "Search widget..."
|
||||
},
|
||||
"active-window": {
|
||||
"auto-hide": "Hide automatically",
|
||||
"show-app-icon": "Show app icon",
|
||||
"scrolling-mode": "Scrolling mode"
|
||||
"auto-hide": {
|
||||
"label": "Hide automatically",
|
||||
"description": "Automatically hide the widget when no window is active."
|
||||
},
|
||||
"show-app-icon": {
|
||||
"label": "Show app icon",
|
||||
"description": "Display the application icon next to the window title."
|
||||
},
|
||||
"scrolling-mode": {
|
||||
"label": "Scrolling mode",
|
||||
"description": "Control when text scrolling is enabled for long window titles."
|
||||
}
|
||||
},
|
||||
"system-monitor": {
|
||||
"cpu-usage": "CPU usage",
|
||||
"cpu-temperature": "CPU temperature",
|
||||
"memory-usage": "Memory usage",
|
||||
"memory-percentage": "Memory as percentage",
|
||||
"network-traffic": "Network traffic",
|
||||
"storage-usage": "Storage usage"
|
||||
"cpu-usage": {
|
||||
"label": "CPU usage",
|
||||
"description": "Display current CPU usage percentage."
|
||||
},
|
||||
"cpu-temperature": {
|
||||
"label": "CPU temperature",
|
||||
"description": "Show CPU temperature readings if available."
|
||||
},
|
||||
"memory-usage": {
|
||||
"label": "Memory usage",
|
||||
"description": "Display current RAM usage information."
|
||||
},
|
||||
"memory-percentage": {
|
||||
"label": "Memory as percentage",
|
||||
"description": "Show memory usage as a percentage instead of absolute values."
|
||||
},
|
||||
"network-traffic": {
|
||||
"label": "Network traffic",
|
||||
"description": "Display network upload and download speeds."
|
||||
},
|
||||
"storage-usage": {
|
||||
"label": "Storage usage",
|
||||
"description": "Show disk space usage information."
|
||||
}
|
||||
},
|
||||
"notification-history": {
|
||||
"show-unread-badge": "Show unread badge",
|
||||
"hide-badge-when-zero": "Hide badge when zero"
|
||||
"show-unread-badge": {
|
||||
"label": "Show unread badge",
|
||||
"description": "Display a badge showing the number of unread notifications."
|
||||
},
|
||||
"hide-badge-when-zero": {
|
||||
"label": "Hide badge when zero",
|
||||
"description": "Hide the notification badge when there are no unread notifications."
|
||||
}
|
||||
},
|
||||
"battery": {
|
||||
"display-mode": {
|
||||
@@ -843,7 +876,10 @@
|
||||
}
|
||||
},
|
||||
"control-center": {
|
||||
"use-distro-logo": "Use distro logo instead of icon",
|
||||
"use-distro-logo": {
|
||||
"label": "Use distro logo instead of icon",
|
||||
"description": "Use your distribution's logo instead of a custom icon."
|
||||
},
|
||||
"icon": {
|
||||
"label": "Icon",
|
||||
"description": "Select an icon from the library or a custom file."
|
||||
@@ -865,7 +901,10 @@
|
||||
}
|
||||
},
|
||||
"workspace": {
|
||||
"label-mode": "Label Mode",
|
||||
"label-mode": {
|
||||
"label": "Label Mode",
|
||||
"description": "Choose how workspace labels are displayed."
|
||||
},
|
||||
"hide-unoccupied": {
|
||||
"label": "Hide unoccupied",
|
||||
"description": "Don't display workspaces without windows."
|
||||
@@ -895,9 +934,18 @@
|
||||
"description": "Select an icon from the library."
|
||||
},
|
||||
"browse": "Browse",
|
||||
"left-click": "Left click",
|
||||
"right-click": "Right click",
|
||||
"middle-click": "Middle click",
|
||||
"left-click": {
|
||||
"label": "Left click",
|
||||
"description": "Command to execute when the button is left-clicked."
|
||||
},
|
||||
"right-click": {
|
||||
"label": "Right click",
|
||||
"description": "Command to execute when the button is right-clicked."
|
||||
},
|
||||
"middle-click": {
|
||||
"label": "Middle click",
|
||||
"description": "Command to execute when the button is middle-clicked."
|
||||
},
|
||||
"dynamic-text": "Dynamic text",
|
||||
"display-command-output": {
|
||||
"label": "Display Command Output",
|
||||
@@ -909,11 +957,26 @@
|
||||
}
|
||||
},
|
||||
"media-mini": {
|
||||
"auto-hide": "Hide automatically",
|
||||
"show-album-art": "Show album art",
|
||||
"show-visualizer": "Show visualizer",
|
||||
"visualizer-type": "Visualizer type",
|
||||
"scrolling-mode": "Scrolling mode"
|
||||
"auto-hide": {
|
||||
"label": "Hide automatically",
|
||||
"description": "Automatically hide the widget when no media is playing."
|
||||
},
|
||||
"show-album-art": {
|
||||
"label": "Show album art",
|
||||
"description": "Display the album artwork for the currently playing track."
|
||||
},
|
||||
"show-visualizer": {
|
||||
"label": "Show visualizer",
|
||||
"description": "Display an audio visualizer when music is playing."
|
||||
},
|
||||
"visualizer-type": {
|
||||
"label": "Visualizer type",
|
||||
"description": "Choose the style of audio visualizer to display."
|
||||
},
|
||||
"scrolling-mode": {
|
||||
"label": "Scrolling mode",
|
||||
"description": "Control when text scrolling is enabled for long track titles."
|
||||
}
|
||||
},
|
||||
"clock": {
|
||||
"use-primary-color": {
|
||||
|
||||
+88
-21
@@ -29,6 +29,10 @@
|
||||
"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": {
|
||||
@@ -810,21 +814,54 @@
|
||||
"search-placeholder": "Buscar widgets..."
|
||||
},
|
||||
"active-window": {
|
||||
"auto-hide": "Ocultar automáticamente",
|
||||
"show-app-icon": "Mostrar icono de la aplicación",
|
||||
"scrolling-mode": "Modo de desplazamiento"
|
||||
"auto-hide": {
|
||||
"label": "Ocultar automáticamente",
|
||||
"description": "Ocultar automáticamente el widget cuando no hay ventana activa."
|
||||
},
|
||||
"show-app-icon": {
|
||||
"label": "Mostrar icono de la aplicación",
|
||||
"description": "Mostrar el icono de la aplicación junto al título de la ventana."
|
||||
},
|
||||
"scrolling-mode": {
|
||||
"label": "Modo de desplazamiento",
|
||||
"description": "Controlar cuándo está habilitado el desplazamiento de texto para títulos de ventana largos."
|
||||
}
|
||||
},
|
||||
"system-monitor": {
|
||||
"cpu-usage": "Uso de CPU",
|
||||
"cpu-temperature": "Temperatura de la CPU",
|
||||
"memory-usage": "Uso de memoria",
|
||||
"memory-percentage": "Memoria como porcentaje",
|
||||
"network-traffic": "Tráfico de red",
|
||||
"storage-usage": "Uso de almacenamiento"
|
||||
"cpu-usage": {
|
||||
"label": "Uso de CPU",
|
||||
"description": "Mostrar el porcentaje actual de uso de CPU."
|
||||
},
|
||||
"cpu-temperature": {
|
||||
"label": "Temperatura de la CPU",
|
||||
"description": "Mostrar lecturas de temperatura de CPU si están disponibles."
|
||||
},
|
||||
"memory-usage": {
|
||||
"label": "Uso de memoria",
|
||||
"description": "Mostrar información actual del uso de RAM."
|
||||
},
|
||||
"memory-percentage": {
|
||||
"label": "Memoria como porcentaje",
|
||||
"description": "Mostrar el uso de memoria como porcentaje en lugar de valores absolutos."
|
||||
},
|
||||
"network-traffic": {
|
||||
"label": "Tráfico de red",
|
||||
"description": "Mostrar velocidades de carga y descarga de la red."
|
||||
},
|
||||
"storage-usage": {
|
||||
"label": "Uso de almacenamiento",
|
||||
"description": "Mostrar información del uso del espacio en disco."
|
||||
}
|
||||
},
|
||||
"notification-history": {
|
||||
"show-unread-badge": "Mostrar insignia de no leídos",
|
||||
"hide-badge-when-zero": "Ocultar insignia cuando es cero"
|
||||
"show-unread-badge": {
|
||||
"label": "Mostrar insignia de no leídos",
|
||||
"description": "Mostrar una insignia con el número de notificaciones no leídas."
|
||||
},
|
||||
"hide-badge-when-zero": {
|
||||
"label": "Ocultar insignia cuando es cero",
|
||||
"description": "Ocultar la insignia de notificaciones cuando no hay notificaciones no leídas."
|
||||
}
|
||||
},
|
||||
"battery": {
|
||||
"display-mode": {
|
||||
@@ -837,7 +874,10 @@
|
||||
}
|
||||
},
|
||||
"control-center": {
|
||||
"use-distro-logo": "Usar logo de la distro en lugar del icono",
|
||||
"use-distro-logo": {
|
||||
"label": "Usar logo de la distribución en lugar de icono",
|
||||
"description": "Usar el logo de tu distribución en lugar de un icono personalizado."
|
||||
},
|
||||
"icon": {
|
||||
"label": "Icono",
|
||||
"description": "Selecciona un icono de la biblioteca o un archivo personalizado."
|
||||
@@ -859,7 +899,10 @@
|
||||
}
|
||||
},
|
||||
"workspace": {
|
||||
"label-mode": "Modo de etiqueta",
|
||||
"label-mode": {
|
||||
"label": "Modo de etiqueta",
|
||||
"description": "Elegir cómo se muestran las etiquetas de los espacios de trabajo."
|
||||
},
|
||||
"hide-unoccupied": {
|
||||
"label": "Ocultar desocupados",
|
||||
"description": "No mostrar espacios de trabajo sin ventanas."
|
||||
@@ -889,9 +932,18 @@
|
||||
"description": "Selecciona un icono de la biblioteca."
|
||||
},
|
||||
"browse": "Explorar",
|
||||
"left-click": "Clic izquierdo",
|
||||
"right-click": "Clic derecho",
|
||||
"middle-click": "Clic central",
|
||||
"left-click": {
|
||||
"label": "Clic izquierdo",
|
||||
"description": "Comando a ejecutar cuando se hace clic izquierdo en el botón."
|
||||
},
|
||||
"right-click": {
|
||||
"label": "Clic derecho",
|
||||
"description": "Comando a ejecutar cuando se hace clic derecho en el botón."
|
||||
},
|
||||
"middle-click": {
|
||||
"label": "Clic medio",
|
||||
"description": "Comando a ejecutar cuando se hace clic medio en el botón."
|
||||
},
|
||||
"dynamic-text": "Texto dinámico",
|
||||
"display-command-output": {
|
||||
"label": "Mostrar salida de comando",
|
||||
@@ -903,11 +955,26 @@
|
||||
}
|
||||
},
|
||||
"media-mini": {
|
||||
"auto-hide": "Ocultar automáticamente",
|
||||
"show-album-art": "Mostrar carátula del álbum",
|
||||
"show-visualizer": "Mostrar visualizador",
|
||||
"visualizer-type": "Tipo de visualizador",
|
||||
"scrolling-mode": "Modo de desplazamiento"
|
||||
"auto-hide": {
|
||||
"label": "Ocultar automáticamente",
|
||||
"description": "Ocultar automáticamente el widget cuando no se está reproduciendo ningún medio."
|
||||
},
|
||||
"show-album-art": {
|
||||
"label": "Mostrar arte del álbum",
|
||||
"description": "Mostrar la portada del álbum de la pista que se está reproduciendo actualmente."
|
||||
},
|
||||
"show-visualizer": {
|
||||
"label": "Mostrar visualizador",
|
||||
"description": "Mostrar un visualizador de audio cuando se reproduce música."
|
||||
},
|
||||
"visualizer-type": {
|
||||
"label": "Tipo de visualizador",
|
||||
"description": "Elegir el estilo de visualizador de audio a mostrar."
|
||||
},
|
||||
"scrolling-mode": {
|
||||
"label": "Modo de desplazamiento",
|
||||
"description": "Controlar cuándo está habilitado el desplazamiento de texto para títulos de pista largos."
|
||||
}
|
||||
},
|
||||
"clock": {
|
||||
"use-primary-color": {
|
||||
|
||||
+88
-21
@@ -29,6 +29,10 @@
|
||||
"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": {
|
||||
@@ -810,21 +814,54 @@
|
||||
"search-placeholder": "Rechercher des widgets..."
|
||||
},
|
||||
"active-window": {
|
||||
"show-app-icon": "Afficher l'icône de l'application",
|
||||
"scrolling-mode": "Mode de défilement",
|
||||
"auto-hide": "Masquer automatiquement"
|
||||
"show-app-icon": {
|
||||
"label": "Afficher l'icône de l'application",
|
||||
"description": "Afficher l'icône de l'application à côté du titre de la fenêtre."
|
||||
},
|
||||
"scrolling-mode": {
|
||||
"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."
|
||||
}
|
||||
},
|
||||
"system-monitor": {
|
||||
"cpu-usage": "Utilisation du CPU",
|
||||
"cpu-temperature": "Température du CPU",
|
||||
"memory-usage": "Utilisation de la mémoire",
|
||||
"memory-percentage": "Mémoire en pourcentage",
|
||||
"network-traffic": "Trafic réseau",
|
||||
"storage-usage": "Utilisation du stockage"
|
||||
"cpu-usage": {
|
||||
"label": "Utilisation du CPU",
|
||||
"description": "Afficher le pourcentage d'utilisation actuel du CPU."
|
||||
},
|
||||
"cpu-temperature": {
|
||||
"label": "Température du CPU",
|
||||
"description": "Afficher les lectures de température du CPU si disponibles."
|
||||
},
|
||||
"memory-usage": {
|
||||
"label": "Utilisation de la mémoire",
|
||||
"description": "Afficher les informations actuelles d'utilisation de la RAM."
|
||||
},
|
||||
"memory-percentage": {
|
||||
"label": "Mémoire en pourcentage",
|
||||
"description": "Afficher l'utilisation de la mémoire en pourcentage au lieu de valeurs absolues."
|
||||
},
|
||||
"network-traffic": {
|
||||
"label": "Trafic réseau",
|
||||
"description": "Afficher les vitesses de téléchargement et de téléversement du réseau."
|
||||
},
|
||||
"storage-usage": {
|
||||
"label": "Utilisation du stockage",
|
||||
"description": "Afficher les informations d'utilisation de l'espace disque."
|
||||
}
|
||||
},
|
||||
"notification-history": {
|
||||
"show-unread-badge": "Afficher le badge non lu",
|
||||
"hide-badge-when-zero": "Masquer le badge si zéro"
|
||||
"show-unread-badge": {
|
||||
"label": "Afficher le badge non lu",
|
||||
"description": "Afficher un badge montrant le nombre de notifications non lues."
|
||||
},
|
||||
"hide-badge-when-zero": {
|
||||
"label": "Masquer le badge quand zéro",
|
||||
"description": "Masquer le badge de notification quand il n'y a pas de notifications non lues."
|
||||
}
|
||||
},
|
||||
"battery": {
|
||||
"display-mode": {
|
||||
@@ -837,7 +874,10 @@
|
||||
}
|
||||
},
|
||||
"control-center": {
|
||||
"use-distro-logo": "Utiliser le logo de la distribution au lieu de l'icône",
|
||||
"use-distro-logo": {
|
||||
"label": "Utiliser le logo de la distribution au lieu de l'icône",
|
||||
"description": "Utiliser le logo de votre distribution au lieu d'une icône personnalisée."
|
||||
},
|
||||
"icon": {
|
||||
"label": "Icône",
|
||||
"description": "Sélectionnez une icône de la bibliothèque ou un fichier personnalisé."
|
||||
@@ -859,7 +899,10 @@
|
||||
}
|
||||
},
|
||||
"workspace": {
|
||||
"label-mode": "Mode d'étiquette",
|
||||
"label-mode": {
|
||||
"label": "Mode d'étiquette",
|
||||
"description": "Choisir comment les étiquettes d'espace de travail sont affichées."
|
||||
},
|
||||
"hide-unoccupied": {
|
||||
"label": "Masquer les inoccupés",
|
||||
"description": "Ne pas afficher les espaces de travail sans fenêtres."
|
||||
@@ -889,9 +932,18 @@
|
||||
"description": "Sélectionnez une icône dans la bibliothèque."
|
||||
},
|
||||
"browse": "Parcourir",
|
||||
"left-click": "Clic gauche",
|
||||
"right-click": "Clic droit",
|
||||
"middle-click": "Clic du milieu",
|
||||
"left-click": {
|
||||
"label": "Clic gauche",
|
||||
"description": "Commande à exécuter quand le bouton est cliqué à gauche."
|
||||
},
|
||||
"right-click": {
|
||||
"label": "Clic droit",
|
||||
"description": "Commande à exécuter quand le bouton est cliqué à droite."
|
||||
},
|
||||
"middle-click": {
|
||||
"label": "Clic milieu",
|
||||
"description": "Commande à exécuter quand le bouton est cliqué au milieu."
|
||||
},
|
||||
"dynamic-text": "Texte dynamique",
|
||||
"display-command-output": {
|
||||
"label": "Afficher la sortie de la commande",
|
||||
@@ -903,11 +955,26 @@
|
||||
}
|
||||
},
|
||||
"media-mini": {
|
||||
"show-album-art": "Afficher la pochette de l'album",
|
||||
"show-visualizer": "Afficher le visualiseur",
|
||||
"visualizer-type": "Type de visualiseur",
|
||||
"scrolling-mode": "Mode de défilement",
|
||||
"auto-hide": "Masquer automatiquement"
|
||||
"show-album-art": {
|
||||
"label": "Afficher la pochette d'album",
|
||||
"description": "Afficher la pochette d'album de la piste en cours de lecture."
|
||||
},
|
||||
"show-visualizer": {
|
||||
"label": "Afficher le visualiseur",
|
||||
"description": "Afficher un visualiseur audio quand la musique est en cours de lecture."
|
||||
},
|
||||
"visualizer-type": {
|
||||
"label": "Type de visualiseur",
|
||||
"description": "Choisir le style de visualiseur audio à afficher."
|
||||
},
|
||||
"scrolling-mode": {
|
||||
"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."
|
||||
}
|
||||
},
|
||||
"clock": {
|
||||
"use-primary-color": {
|
||||
|
||||
+90
-37
@@ -29,6 +29,10 @@
|
||||
"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": {
|
||||
@@ -713,7 +717,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"widgets": {
|
||||
"tooltip": {
|
||||
"placeholder": "Espaço reservado"
|
||||
@@ -811,21 +814,54 @@
|
||||
"search-placeholder": "Pesquisar widgets..."
|
||||
},
|
||||
"active-window": {
|
||||
"auto-hide": "Ocultar automaticamente",
|
||||
"show-app-icon": "Mostrar ícone do aplicativo",
|
||||
"scrolling-mode": "Modo de Rolagem"
|
||||
"auto-hide": {
|
||||
"label": "Ocultar automaticamente",
|
||||
"description": "Ocultar automaticamente o widget quando nenhuma janela está ativa."
|
||||
},
|
||||
"show-app-icon": {
|
||||
"label": "Mostrar ícone do aplicativo",
|
||||
"description": "Exibir o ícone do aplicativo ao lado do título da janela."
|
||||
},
|
||||
"scrolling-mode": {
|
||||
"label": "Modo de rolagem",
|
||||
"description": "Controlar quando a rolagem de texto está habilitada para títulos de janela longos."
|
||||
}
|
||||
},
|
||||
"system-monitor": {
|
||||
"cpu-usage": "Uso de CPU",
|
||||
"cpu-temperature": "Temperatura da CPU",
|
||||
"memory-usage": "Uso de memória",
|
||||
"memory-percentage": "Memória em porcentagem",
|
||||
"network-traffic": "Tráfego de rede",
|
||||
"storage-usage": "Uso de armazenamento"
|
||||
"cpu-usage": {
|
||||
"label": "Uso da CPU",
|
||||
"description": "Exibir o percentual atual de uso da CPU."
|
||||
},
|
||||
"cpu-temperature": {
|
||||
"label": "Temperatura da CPU",
|
||||
"description": "Mostrar leituras de temperatura da CPU se disponíveis."
|
||||
},
|
||||
"memory-usage": {
|
||||
"label": "Uso de memória",
|
||||
"description": "Exibir informações atuais de uso da RAM."
|
||||
},
|
||||
"memory-percentage": {
|
||||
"label": "Memória como percentual",
|
||||
"description": "Mostrar o uso de memória como percentual em vez de valores absolutos."
|
||||
},
|
||||
"network-traffic": {
|
||||
"label": "Tráfego de rede",
|
||||
"description": "Exibir velocidades de upload e download da rede."
|
||||
},
|
||||
"storage-usage": {
|
||||
"label": "Uso de armazenamento",
|
||||
"description": "Mostrar informações de uso do espaço em disco."
|
||||
}
|
||||
},
|
||||
"notification-history": {
|
||||
"show-unread-badge": "Mostrar selo de não lidas",
|
||||
"hide-badge-when-zero": "Ocultar selo quando for zero"
|
||||
"show-unread-badge": {
|
||||
"label": "Mostrar distintivo de não lidos",
|
||||
"description": "Exibir um distintivo mostrando o número de notificações não lidas."
|
||||
},
|
||||
"hide-badge-when-zero": {
|
||||
"label": "Ocultar distintivo quando zero",
|
||||
"description": "Ocultar o distintivo de notificação quando não há notificações não lidas."
|
||||
}
|
||||
},
|
||||
"battery": {
|
||||
"display-mode": {
|
||||
@@ -838,7 +874,10 @@
|
||||
}
|
||||
},
|
||||
"control-center": {
|
||||
"use-distro-logo": "Usar logo da distro em vez do ícone",
|
||||
"use-distro-logo": {
|
||||
"label": "Usar logo da distribuição em vez de ícone",
|
||||
"description": "Usar o logo da sua distribuição em vez de um ícone personalizado."
|
||||
},
|
||||
"icon": {
|
||||
"label": "Ícone",
|
||||
"description": "Selecione um ícone da biblioteca ou um arquivo personalizado."
|
||||
@@ -860,7 +899,10 @@
|
||||
}
|
||||
},
|
||||
"workspace": {
|
||||
"label-mode": "Modo de Rótulo",
|
||||
"label-mode": {
|
||||
"label": "Modo de rótulo",
|
||||
"description": "Escolher como os rótulos de espaço de trabalho são exibidos."
|
||||
},
|
||||
"hide-unoccupied": {
|
||||
"label": "Ocultar desocupados",
|
||||
"description": "Não exibir áreas de trabalho sem janelas."
|
||||
@@ -890,9 +932,18 @@
|
||||
"description": "Selecione um ícone da biblioteca."
|
||||
},
|
||||
"browse": "Navegar",
|
||||
"left-click": "Clique esquerdo",
|
||||
"right-click": "Clique direito",
|
||||
"middle-click": "Clique do meio",
|
||||
"left-click": {
|
||||
"label": "Clique esquerdo",
|
||||
"description": "Comando a executar quando o botão é clicado com o botão esquerdo."
|
||||
},
|
||||
"right-click": {
|
||||
"label": "Clique direito",
|
||||
"description": "Comando a executar quando o botão é clicado com o botão direito."
|
||||
},
|
||||
"middle-click": {
|
||||
"label": "Clique do meio",
|
||||
"description": "Comando a executar quando o botão é clicado com o botão do meio."
|
||||
},
|
||||
"dynamic-text": "Texto dinâmico",
|
||||
"display-command-output": {
|
||||
"label": "Exibir Saída de Comando",
|
||||
@@ -904,11 +955,26 @@
|
||||
}
|
||||
},
|
||||
"media-mini": {
|
||||
"auto-hide": "Ocultar automaticamente",
|
||||
"show-album-art": "Mostrar arte do álbum",
|
||||
"show-visualizer": "Mostrar visualizador",
|
||||
"visualizer-type": "Tipo de visualizador",
|
||||
"scrolling-mode": "Modo de rolagem"
|
||||
"auto-hide": {
|
||||
"label": "Ocultar automaticamente",
|
||||
"description": "Ocultar automaticamente o widget quando nenhuma mídia está sendo reproduzida."
|
||||
},
|
||||
"show-album-art": {
|
||||
"label": "Mostrar arte do álbum",
|
||||
"description": "Exibir a arte do álbum da faixa atualmente sendo reproduzida."
|
||||
},
|
||||
"show-visualizer": {
|
||||
"label": "Mostrar visualizador",
|
||||
"description": "Exibir um visualizador de áudio quando música está sendo reproduzida."
|
||||
},
|
||||
"visualizer-type": {
|
||||
"label": "Tipo de visualizador",
|
||||
"description": "Escolher o estilo de visualizador de áudio a exibir."
|
||||
},
|
||||
"scrolling-mode": {
|
||||
"label": "Modo de rolagem",
|
||||
"description": "Controlar quando a rolagem de texto está habilitada para títulos de faixa longos."
|
||||
}
|
||||
},
|
||||
"clock": {
|
||||
"use-primary-color": {
|
||||
@@ -1105,8 +1171,8 @@
|
||||
"bottom_right": "Inferior direito",
|
||||
"bottom_center": "Centro inferior",
|
||||
"top_center": "Centro superior",
|
||||
"center_left": "Esquerda central",
|
||||
"center_right": "Direita central"
|
||||
"center_left": "Centro à esquerda",
|
||||
"center_right": "Centro à direita"
|
||||
}
|
||||
},
|
||||
"bar": {
|
||||
@@ -1122,19 +1188,6 @@
|
||||
"comfortable": "Confortável"
|
||||
}
|
||||
},
|
||||
"launcher": {
|
||||
"position": {
|
||||
"center": "Centro (padrão)",
|
||||
"top_left": "Superior esquerdo",
|
||||
"top_right": "Superior direito",
|
||||
"bottom_left": "Inferior esquerdo",
|
||||
"bottom_right": "Inferior direito",
|
||||
"bottom_center": "Centro inferior",
|
||||
"top_center": "Centro superior",
|
||||
"center_left": "Centro à esquerda",
|
||||
"center_right": "Centro à direita"
|
||||
}
|
||||
},
|
||||
"display-mode": {
|
||||
"on-hover": "Ao passar o mouse",
|
||||
"always-show": "Sempre mostrar",
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+16
-3
@@ -170,11 +170,24 @@ Singleton {
|
||||
|
||||
// Detect user's favorite locale - languages
|
||||
for (var i = 0; i < Qt.locale().uiLanguages.length; i++) {
|
||||
const userLang = Qt.locale().uiLanguages[i].substring(0, 2)
|
||||
if (availableLanguages.includes(userLang)) {
|
||||
setLanguage(userLang)
|
||||
const fullUserLang = Qt.locale().uiLanguages[i]
|
||||
|
||||
// Try full code match (such as zh CN, en US)
|
||||
if (availableLanguages.includes(fullUserLang)) {
|
||||
Logger.log("I18n", `Exact match found: "${fullUserLang}"`)
|
||||
setLanguage(fullUserLang)
|
||||
return
|
||||
}
|
||||
|
||||
// If full code match fails, try short code matching (such as zh, en)
|
||||
const shortUserLang = fullUserLang.substring(0, 2)
|
||||
if (availableLanguages.includes(shortUserLang)) {
|
||||
Logger.log("I18n", `Short code match found: "${shortUserLang}" from "${fullUserLang}"`)
|
||||
setLanguage(shortUserLang)
|
||||
return
|
||||
}
|
||||
|
||||
Logger.log("I18n", `No match for system language: "${fullUserLang}"`)
|
||||
}
|
||||
|
||||
// Fallback to first available language (preferably "en" if available)
|
||||
|
||||
@@ -46,6 +46,13 @@ Item {
|
||||
width: pillHeight + Math.max(0, pill.width - pillOverlap)
|
||||
height: pillHeight
|
||||
|
||||
Connections {
|
||||
target: root
|
||||
function onTooltipTextChanged() {
|
||||
TooltipService.updateText(root.tooltipText)
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: pill
|
||||
width: revealed ? pillMaxWidth : 1
|
||||
@@ -195,14 +202,6 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
NTooltip {
|
||||
id: tooltip
|
||||
positionAbove: Settings.data.bar.position === "bottom"
|
||||
target: pill
|
||||
delay: Style.tooltipDelayLong
|
||||
text: root.tooltipText
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: showTimer
|
||||
interval: Style.pillDelay
|
||||
@@ -220,7 +219,7 @@ Item {
|
||||
onEntered: {
|
||||
hovered = true
|
||||
root.entered()
|
||||
tooltip.show()
|
||||
TooltipService.show(pill, root.tooltipText, BarService.getTooltipDirection(), Style.tooltipDelayLong)
|
||||
if (disableOpen || forceClose) {
|
||||
return
|
||||
}
|
||||
@@ -234,7 +233,7 @@ Item {
|
||||
if (!forceOpen && !forceClose) {
|
||||
hide()
|
||||
}
|
||||
tooltip.hide()
|
||||
TooltipService.hide()
|
||||
}
|
||||
onClicked: function (mouse) {
|
||||
if (mouse.button === Qt.LeftButton) {
|
||||
|
||||
@@ -58,6 +58,13 @@ Item {
|
||||
width: buttonSize
|
||||
height: revealed ? (buttonSize + maxPillHeight - pillOverlap) : buttonSize
|
||||
|
||||
Connections {
|
||||
target: root
|
||||
function onTooltipTextChanged() {
|
||||
TooltipService.updateText(root.tooltipText)
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: pill
|
||||
width: revealed ? maxPillWidth : 1
|
||||
@@ -236,15 +243,6 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
NTooltip {
|
||||
id: tooltip
|
||||
target: pill
|
||||
text: root.tooltipText
|
||||
positionLeft: barPosition === "right"
|
||||
positionRight: barPosition === "left"
|
||||
delay: Style.tooltipDelayLong
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: showTimer
|
||||
interval: Style.pillDelay
|
||||
@@ -262,7 +260,7 @@ Item {
|
||||
onEntered: {
|
||||
hovered = true
|
||||
root.entered()
|
||||
tooltip.show()
|
||||
TooltipService.show(pill, root.tooltipText, BarService.getTooltipDirection(), Style.tooltipDelayLong)
|
||||
if (disableOpen || forceClose) {
|
||||
return
|
||||
}
|
||||
@@ -276,7 +274,7 @@ Item {
|
||||
if (!forceOpen && !forceClose) {
|
||||
hide()
|
||||
}
|
||||
tooltip.hide()
|
||||
TooltipService.hide()
|
||||
}
|
||||
onClicked: function (mouse) {
|
||||
if (mouse.button === Qt.LeftButton) {
|
||||
|
||||
@@ -328,29 +328,17 @@ Item {
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
acceptedButtons: Qt.LeftButton
|
||||
onEntered: {
|
||||
if (barPosition === "left" || barPosition === "right") {
|
||||
tooltip.show()
|
||||
} else if ((tooltip.text !== "") && (scrollingMode === "never")) {
|
||||
tooltip.show()
|
||||
if ((windowTitle !== "") && (barPosition === "left" || barPosition === "right") || (scrollingMode === "never")) {
|
||||
TooltipService.show(root, windowTitle, BarService.getTooltipDirection())
|
||||
}
|
||||
}
|
||||
onExited: {
|
||||
tooltip.hide()
|
||||
TooltipService.hide()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NTooltip {
|
||||
id: tooltip
|
||||
text: windowTitle
|
||||
target: (barPosition === "left" || barPosition === "right") ? verticalLayout : windowActiveRect
|
||||
positionLeft: barPosition === "right"
|
||||
positionRight: barPosition === "left"
|
||||
positionAbove: Settings.data.bar.position === "bottom"
|
||||
delay: Style.tooltipDelay
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: CompositorService
|
||||
function onActiveWindowChanged() {
|
||||
|
||||
@@ -19,9 +19,9 @@ NIconButton {
|
||||
colorFg: Color.mOnSurface
|
||||
colorBorder: Color.transparent
|
||||
colorBorderHover: Color.transparent
|
||||
|
||||
icon: BluetoothService.enabled ? "bluetooth" : "bluetooth-off"
|
||||
tooltipText: I18n.tr("tooltips.bluetooth-devices")
|
||||
tooltipDirection: BarService.getTooltipDirection()
|
||||
icon: BluetoothService.enabled ? "bluetooth" : "bluetooth-off"
|
||||
onClicked: PanelService.getPanel("bluetoothPanel")?.toggle(this)
|
||||
onRightClicked: PanelService.getPanel("bluetoothPanel")?.toggle(this)
|
||||
}
|
||||
|
||||
@@ -106,14 +106,6 @@ Rectangle {
|
||||
}
|
||||
}
|
||||
}
|
||||
NTooltip {
|
||||
id: tooltip
|
||||
text: I18n.tr("clock.tooltip")
|
||||
target: clockContainer
|
||||
positionAbove: Settings.data.bar.position === "bottom"
|
||||
positionLeft: barPosition === "right"
|
||||
positionRight: barPosition === "left"
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: clockMouseArea
|
||||
@@ -122,14 +114,14 @@ Rectangle {
|
||||
hoverEnabled: true
|
||||
onEntered: {
|
||||
if (!PanelService.getPanel("calendarPanel")?.active) {
|
||||
tooltip.show()
|
||||
TooltipService.show(root, I18n.tr("clock.tooltip"), BarService.getTooltipDirection())
|
||||
}
|
||||
}
|
||||
onExited: {
|
||||
tooltip.hide()
|
||||
TooltipService.hide()
|
||||
}
|
||||
onClicked: {
|
||||
tooltip.hide()
|
||||
TooltipService.hide()
|
||||
PanelService.getPanel("calendarPanel")?.toggle(this)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,9 +36,7 @@ NIconButton {
|
||||
// If we have a custom path or distro logo, don't use the theme icon.
|
||||
icon: (customIconPath === "" && !useDistroLogo) ? customIcon : ""
|
||||
tooltipText: I18n.tr("tooltips.open-control-center")
|
||||
tooltipPositionAbove: Settings.data.bar.position === "bottom"
|
||||
tooltipPositionLeft: Settings.data.bar.position === "right"
|
||||
tooltipPositionRight: Settings.data.bar.position === "left"
|
||||
tooltipDirection: BarService.getTooltipDirection()
|
||||
baseSize: Style.capsuleHeight
|
||||
compact: (Settings.data.bar.density === "compact")
|
||||
colorBg: (Settings.data.bar.showCapsule ? Color.mSurfaceVariant : Color.transparent)
|
||||
|
||||
@@ -11,9 +11,7 @@ NIconButton {
|
||||
|
||||
icon: "dark-mode"
|
||||
tooltipText: Settings.data.colorSchemes.darkMode ? I18n.tr("tooltips.switch-to-light-mode") : I18n.tr("tooltips.switch-to-dark-mode")
|
||||
tooltipPositionAbove: Settings.data.bar.position === "bottom"
|
||||
tooltipPositionLeft: Settings.data.bar.position === "right"
|
||||
tooltipPositionRight: Settings.data.bar.position === "left"
|
||||
tooltipDirection: BarService.getTooltipDirection()
|
||||
compact: (Settings.data.bar.density === "compact")
|
||||
baseSize: Style.capsuleHeight
|
||||
colorBg: Settings.data.colorSchemes.darkMode ? (Settings.data.bar.showCapsule ? Color.mSurfaceVariant : Color.transparent) : Color.mPrimary
|
||||
|
||||
@@ -15,9 +15,7 @@ NIconButton {
|
||||
compact: (Settings.data.bar.density === "compact")
|
||||
icon: IdleInhibitorService.isInhibited ? "keep-awake-on" : "keep-awake-off"
|
||||
tooltipText: IdleInhibitorService.isInhibited ? I18n.tr("tooltips.disable-keep-awake") : I18n.tr("tooltips.enable-keep-awake")
|
||||
tooltipPositionAbove: Settings.data.bar.position === "bottom"
|
||||
tooltipPositionLeft: Settings.data.bar.position === "right"
|
||||
tooltipPositionRight: Settings.data.bar.position === "left"
|
||||
tooltipDirection: BarService.getTooltipDirection()
|
||||
colorBg: IdleInhibitorService.isInhibited ? Color.mPrimary : (Settings.data.bar.showCapsule ? Color.mSurfaceVariant : Color.transparent)
|
||||
colorFg: IdleInhibitorService.isInhibited ? Color.mOnPrimary : Color.mOnSurface
|
||||
colorBorder: Color.transparent
|
||||
|
||||
@@ -42,6 +42,21 @@ Item {
|
||||
// Fixed width - no expansion
|
||||
readonly property real widgetWidth: Math.max(1, screen.width * 0.06)
|
||||
|
||||
readonly property string tooltipText: {
|
||||
var title = getTitle()
|
||||
var controls = ""
|
||||
if (MediaService.canGoNext) {
|
||||
controls += "Right click for next.\n"
|
||||
}
|
||||
if (MediaService.canGoPrevious) {
|
||||
controls += "Middle click for previous."
|
||||
}
|
||||
if (controls !== "") {
|
||||
return title + "\n\n" + controls
|
||||
}
|
||||
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
|
||||
|
||||
@@ -360,39 +375,14 @@ Item {
|
||||
}
|
||||
|
||||
onEntered: {
|
||||
if ((tooltip.text !== "") && (barPosition === "left" || barPosition === "right")) {
|
||||
tooltip.show()
|
||||
} else if ((tooltip.text !== "") && (scrollingMode === "never")) {
|
||||
tooltip.show()
|
||||
if ((tooltipText !== "") && (barPosition === "left" || barPosition === "right") || (scrollingMode === "never")) {
|
||||
TooltipService.show(root, tooltipText, BarService.getTooltipDirection())
|
||||
}
|
||||
}
|
||||
onExited: {
|
||||
tooltip.hide()
|
||||
TooltipService.hide()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NTooltip {
|
||||
id: tooltip
|
||||
text: {
|
||||
var title = getTitle()
|
||||
var controls = ""
|
||||
if (MediaService.canGoNext) {
|
||||
controls += "Right click for next.\n"
|
||||
}
|
||||
if (MediaService.canGoPrevious) {
|
||||
controls += "Middle click for previous."
|
||||
}
|
||||
if (controls !== "") {
|
||||
return title + "\n\n" + controls
|
||||
}
|
||||
return title
|
||||
}
|
||||
target: (barPosition === "left" || barPosition === "right") ? verticalLayout : mediaMini
|
||||
positionLeft: barPosition === "right"
|
||||
positionRight: barPosition === "left"
|
||||
positionAbove: Settings.data.bar.position === "bottom"
|
||||
delay: Style.tooltipDelay
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,9 +23,7 @@ NIconButton {
|
||||
|
||||
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")
|
||||
tooltipPositionAbove: Settings.data.bar.position === "bottom"
|
||||
tooltipPositionLeft: Settings.data.bar.position === "right"
|
||||
tooltipPositionRight: Settings.data.bar.position === "left"
|
||||
tooltipDirection: BarService.getTooltipDirection()
|
||||
onClicked: {
|
||||
// Check if wlsunset is available before enabling night light
|
||||
if (!ProgramCheckerService.wlsunsetAvailable) {
|
||||
|
||||
@@ -53,9 +53,7 @@ NIconButton {
|
||||
compact: (Settings.data.bar.density === "compact")
|
||||
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")
|
||||
tooltipPositionAbove: Settings.data.bar.position === "bottom"
|
||||
tooltipPositionLeft: Settings.data.bar.position === "right"
|
||||
tooltipPositionRight: Settings.data.bar.position === "left"
|
||||
tooltipDirection: BarService.getTooltipDirection()
|
||||
colorBg: (Settings.data.bar.showCapsule ? Color.mSurfaceVariant : Color.transparent)
|
||||
colorFg: Color.mOnSurface
|
||||
colorBorder: Color.transparent
|
||||
|
||||
@@ -19,9 +19,7 @@ NIconButton {
|
||||
tooltipText: I18n.tr("tooltips.power-profile", {
|
||||
"profile": PowerProfileService.getName()
|
||||
})
|
||||
tooltipPositionAbove: Settings.data.bar.position === "bottom"
|
||||
tooltipPositionLeft: Settings.data.bar.position === "right"
|
||||
tooltipPositionRight: Settings.data.bar.position === "left"
|
||||
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
|
||||
|
||||
@@ -12,9 +12,7 @@ NIconButton {
|
||||
|
||||
icon: "camera-video"
|
||||
tooltipText: ScreenRecorderService.isRecording ? I18n.tr("tooltips.click-to-stop-recording") : I18n.tr("tooltips.click-to-start-recording")
|
||||
tooltipPositionAbove: Settings.data.bar.position === "bottom"
|
||||
tooltipPositionLeft: Settings.data.bar.position === "right"
|
||||
tooltipPositionRight: Settings.data.bar.position === "left"
|
||||
tooltipDirection: BarService.getTooltipDirection()
|
||||
compact: (Settings.data.bar.density === "compact")
|
||||
baseSize: Style.capsuleHeight
|
||||
colorBg: ScreenRecorderService.isRecording ? Color.mPrimary : (Settings.data.bar.showCapsule ? Color.mSurfaceVariant : Color.transparent)
|
||||
|
||||
@@ -15,9 +15,7 @@ NIconButton {
|
||||
baseSize: Style.capsuleHeight
|
||||
icon: "power"
|
||||
tooltipText: I18n.tr("tooltips.session-menu")
|
||||
tooltipPositionAbove: Settings.data.bar.position === "bottom"
|
||||
tooltipPositionLeft: Settings.data.bar.position === "right"
|
||||
tooltipPositionRight: Settings.data.bar.position === "left"
|
||||
tooltipDirection: BarService.getTooltipDirection()
|
||||
colorBg: (Settings.data.bar.showCapsule ? Color.mSurfaceVariant : Color.transparent)
|
||||
colorFg: Color.mError
|
||||
colorBorder: Color.transparent
|
||||
|
||||
@@ -98,17 +98,8 @@ Rectangle {
|
||||
}
|
||||
}
|
||||
}
|
||||
onEntered: taskbarTooltip.show()
|
||||
onExited: taskbarTooltip.hide()
|
||||
}
|
||||
|
||||
NTooltip {
|
||||
id: taskbarTooltip
|
||||
text: taskbarItem.modelData.title || taskbarItem.modelData.appId || "Unknown app."
|
||||
target: taskbarItem
|
||||
positionAbove: Settings.data.bar.position === "bottom"
|
||||
positionLeft: Settings.data.bar.position === "right"
|
||||
positionRight: Settings.data.bar.position === "left"
|
||||
onEntered: TooltipService.show(taskbarItem, taskbarItem.modelData.title || taskbarItem.modelData.appId || "Unknown app.", BarService.getTooltipDirection())
|
||||
onExited: TooltipService.hide()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,7 +102,7 @@ Rectangle {
|
||||
|
||||
modelData.secondaryActivate && modelData.secondaryActivate()
|
||||
} else if (mouse.button === Qt.RightButton) {
|
||||
trayTooltip.hide()
|
||||
TooltipService.hideImmediately()
|
||||
|
||||
// Close the menu if it was visible
|
||||
if (trayPanel && trayPanel.visible) {
|
||||
@@ -135,15 +135,11 @@ Rectangle {
|
||||
}
|
||||
}
|
||||
}
|
||||
onEntered: trayTooltip.show()
|
||||
onExited: trayTooltip.hide()
|
||||
}
|
||||
|
||||
NTooltip {
|
||||
id: trayTooltip
|
||||
target: trayIcon
|
||||
text: modelData.tooltipTitle || modelData.name || modelData.id || "Tray Item"
|
||||
positionAbove: Settings.data.bar.position === "bottom"
|
||||
onEntered: {
|
||||
trayPanel.close()
|
||||
TooltipService.show(trayIcon, modelData.tooltipTitle || modelData.name || modelData.id || "Tray Item", BarService.getTooltipDirection())
|
||||
}
|
||||
onExited: TooltipService.hide()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,9 +15,7 @@ NIconButton {
|
||||
compact: (Settings.data.bar.density === "compact")
|
||||
icon: "wallpaper-selector"
|
||||
tooltipText: I18n.tr("tooltips.open-wallpaper-selector")
|
||||
tooltipPositionAbove: Settings.data.bar.position === "bottom"
|
||||
tooltipPositionLeft: Settings.data.bar.position === "right"
|
||||
tooltipPositionRight: Settings.data.bar.position === "left"
|
||||
tooltipDirection: BarService.getTooltipDirection()
|
||||
colorBg: (Settings.data.bar.showCapsule ? Color.mSurfaceVariant : Color.transparent)
|
||||
colorFg: Color.mOnSurface
|
||||
colorBorder: Color.transparent
|
||||
|
||||
@@ -19,7 +19,8 @@ NIconButton {
|
||||
colorFg: Color.mOnSurface
|
||||
colorBorder: Color.transparent
|
||||
colorBorderHover: Color.transparent
|
||||
|
||||
tooltipText: I18n.tr("tooltips.manage-wifi")
|
||||
tooltipDirection: BarService.getTooltipDirection()
|
||||
icon: {
|
||||
try {
|
||||
if (NetworkService.ethernetConnected) {
|
||||
@@ -40,10 +41,6 @@ NIconButton {
|
||||
return "signal_wifi_bad"
|
||||
}
|
||||
}
|
||||
tooltipText: I18n.tr("tooltips.manage-wifi")
|
||||
tooltipPositionAbove: Settings.data.bar.position === "bottom"
|
||||
tooltipPositionLeft: Settings.data.bar.position === "right"
|
||||
tooltipPositionRight: Settings.data.bar.position === "left"
|
||||
onClicked: PanelService.getPanel("wifiPanel")?.toggle(this)
|
||||
onRightClicked: PanelService.getPanel("wifiPanel")?.toggle(this)
|
||||
}
|
||||
|
||||
+4
-12
@@ -373,14 +373,6 @@ Variants {
|
||||
}
|
||||
}
|
||||
|
||||
// Individual tooltip for this app
|
||||
NTooltip {
|
||||
id: appTooltip
|
||||
target: appButton
|
||||
positionAbove: true
|
||||
visible: false
|
||||
}
|
||||
|
||||
Image {
|
||||
id: appIcon
|
||||
width: iconSize
|
||||
@@ -481,8 +473,8 @@ Variants {
|
||||
onEntered: {
|
||||
anyAppHovered = true
|
||||
const appName = appButton.appTitle || appButton.appId || "Unknown"
|
||||
appTooltip.text = appName.length > 40 ? appName.substring(0, 37) + "..." : appName
|
||||
appTooltip.isVisible = true
|
||||
const tooltipText = appName.length > 40 ? appName.substring(0, 37) + "..." : appName
|
||||
TooltipService.show(appButton, tooltipText, "top")
|
||||
if (autoHide) {
|
||||
showTimer.stop()
|
||||
hideTimer.stop()
|
||||
@@ -492,7 +484,7 @@ Variants {
|
||||
|
||||
onExited: {
|
||||
anyAppHovered = false
|
||||
appTooltip.hide()
|
||||
TooltipService.hide()
|
||||
if (autoHide && !dockHovered && !peekHovered && !menuHovered) {
|
||||
hideTimer.restart()
|
||||
}
|
||||
@@ -508,7 +500,7 @@ Variants {
|
||||
// Close any other existing context menu first
|
||||
root.closeAllContextMenus()
|
||||
// Hide tooltip when showing context menu
|
||||
appTooltip.hide()
|
||||
TooltipService.hide()
|
||||
contextMenu.show(appButton, modelData.toplevel || modelData)
|
||||
return
|
||||
}
|
||||
|
||||
+90
-81
@@ -14,9 +14,12 @@ PopupWindow {
|
||||
property var toplevel: null
|
||||
property Item anchorItem: null
|
||||
property real scaling: 1.0
|
||||
property bool hovered: menuMouseArea.containsMouse || activateMouseArea.containsMouse || pinMouseArea.containsMouse || closeMouseArea.containsMouse
|
||||
property bool hovered: menuMouseArea.containsMouse
|
||||
property var onAppClosed: null // Callback function for when an app is closed
|
||||
|
||||
// Track which menu item is hovered
|
||||
property int hoveredItem: -1 // -1: none, 0: focus, 1: pin, 2: close
|
||||
|
||||
signal requestClose
|
||||
|
||||
implicitWidth: 140 * scaling
|
||||
@@ -70,25 +73,64 @@ PopupWindow {
|
||||
visible = false
|
||||
}
|
||||
|
||||
// Close menu when clicking on background, track hover for the whole menu area
|
||||
MouseArea {
|
||||
id: menuMouseArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||
onClicked: function (mouse) {
|
||||
if (mouse.button === Qt.RightButton) {
|
||||
root.hide() // Close on right-click
|
||||
} else {
|
||||
root.hide() // Close when clicking on the background (outside menu content)
|
||||
// Helper function to determine which menu item is under the mouse
|
||||
function getHoveredItem(mouseY) {
|
||||
const itemHeight = 32 * scaling
|
||||
const startY = Style.marginM * scaling
|
||||
const relativeY = mouseY - startY
|
||||
|
||||
if (relativeY < 0)
|
||||
return -1
|
||||
|
||||
const itemIndex = Math.floor(relativeY / itemHeight)
|
||||
return itemIndex >= 0 && itemIndex < 3 ? itemIndex : -1
|
||||
}
|
||||
|
||||
// Handle menu item clicks
|
||||
function handleItemClick(itemIndex) {
|
||||
switch (itemIndex) {
|
||||
case 0:
|
||||
// Focus
|
||||
if (root.toplevel?.activate) {
|
||||
root.toplevel.activate()
|
||||
}
|
||||
root.requestClose()
|
||||
break
|
||||
case 1:
|
||||
// Pin/Unpin
|
||||
if (root.toplevel?.appId) {
|
||||
root.toggleAppPin(root.toplevel.appId)
|
||||
}
|
||||
root.requestClose()
|
||||
break
|
||||
case 2:
|
||||
// Close
|
||||
// Check if toplevel is still valid before trying to close it
|
||||
const isValidToplevel = root.toplevel && ToplevelManager && ToplevelManager.toplevels.values.includes(root.toplevel)
|
||||
|
||||
if (isValidToplevel && root.toplevel.close) {
|
||||
root.toplevel.close()
|
||||
// Trigger immediate dock update callback if provided
|
||||
if (root.onAppClosed && typeof root.onAppClosed === "function") {
|
||||
Qt.callLater(root.onAppClosed)
|
||||
}
|
||||
} else {
|
||||
Logger.warn("DockMenu", "Cannot close app - invalid toplevel reference")
|
||||
}
|
||||
root.hide()
|
||||
root.requestClose()
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
Shortcut {
|
||||
sequences: ["Escape"]
|
||||
enabled: root.visible
|
||||
onActivated: root.hide()
|
||||
Timer {
|
||||
id: closeTimer
|
||||
interval: 500
|
||||
repeat: false
|
||||
running: false
|
||||
onTriggered: {
|
||||
root.hide()
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
@@ -98,12 +140,32 @@ PopupWindow {
|
||||
border.color: Color.mOutline
|
||||
border.width: Math.max(1, Style.borderS * scaling)
|
||||
|
||||
// Prevent clicks inside the menu from closing it
|
||||
// Single MouseArea to handle both auto-close and menu interactions
|
||||
MouseArea {
|
||||
id: menuMouseArea
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
hoverEnabled: true
|
||||
cursorShape: root.hoveredItem >= 0 ? Qt.PointingHandCursor : Qt.ArrowCursor
|
||||
|
||||
} // Do nothing, just consume the click
|
||||
onEntered: {
|
||||
closeTimer.stop()
|
||||
}
|
||||
|
||||
onExited: {
|
||||
root.hoveredItem = -1
|
||||
closeTimer.start()
|
||||
}
|
||||
|
||||
onPositionChanged: mouse => {
|
||||
root.hoveredItem = root.getHoveredItem(mouse.y)
|
||||
}
|
||||
|
||||
onClicked: mouse => {
|
||||
const clickedItem = root.getHoveredItem(mouse.y)
|
||||
if (clickedItem >= 0) {
|
||||
root.handleItemClick(clickedItem)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Column {
|
||||
@@ -116,7 +178,7 @@ PopupWindow {
|
||||
Rectangle {
|
||||
width: parent.width
|
||||
height: 32 * scaling
|
||||
color: activateMouseArea.containsMouse ? Color.mTertiary : Color.transparent
|
||||
color: root.hoveredItem === 0 ? Color.mTertiary : Color.transparent
|
||||
radius: Style.radiusXS * scaling
|
||||
|
||||
Row {
|
||||
@@ -128,38 +190,24 @@ PopupWindow {
|
||||
NIcon {
|
||||
icon: "eye"
|
||||
font.pointSize: Style.fontSizeL * scaling
|
||||
color: activateMouseArea.containsMouse ? Color.mOnTertiary : Color.mOnSurfaceVariant
|
||||
color: root.hoveredItem === 0 ? Color.mOnTertiary : Color.mOnSurfaceVariant
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
NText {
|
||||
text: I18n.tr("dock.menu.focus")
|
||||
font.pointSize: Style.fontSizeS * scaling
|
||||
color: activateMouseArea.containsMouse ? Color.mOnTertiary : Color.mOnSurfaceVariant
|
||||
color: root.hoveredItem === 0 ? Color.mOnTertiary : Color.mOnSurfaceVariant
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: activateMouseArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
|
||||
onClicked: {
|
||||
if (root.toplevel?.activate) {
|
||||
root.toplevel.activate()
|
||||
}
|
||||
root.requestClose()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Pin/Unpin item
|
||||
Rectangle {
|
||||
width: parent.width
|
||||
height: 32 * scaling
|
||||
color: pinMouseArea.containsMouse ? Color.mTertiary : Color.transparent
|
||||
color: root.hoveredItem === 1 ? Color.mTertiary : Color.transparent
|
||||
radius: Style.radiusXS * scaling
|
||||
|
||||
Row {
|
||||
@@ -175,7 +223,7 @@ PopupWindow {
|
||||
return root.isAppPinned(root.toplevel.appId) ? "unpin" : "pin"
|
||||
}
|
||||
font.pointSize: Style.fontSizeL * scaling
|
||||
color: pinMouseArea.containsMouse ? Color.mOnTertiary : Color.mOnSurfaceVariant
|
||||
color: root.hoveredItem === 1 ? Color.mOnTertiary : Color.mOnSurfaceVariant
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
@@ -186,32 +234,17 @@ PopupWindow {
|
||||
return root.isAppPinned(root.toplevel.appId) ? I18n.tr("dock.menu.unpin") : I18n.tr("dock.menu.pin")
|
||||
}
|
||||
font.pointSize: Style.fontSizeS * scaling
|
||||
color: pinMouseArea.containsMouse ? Color.mOnTertiary : Color.mOnSurfaceVariant
|
||||
color: root.hoveredItem === 1 ? Color.mOnTertiary : Color.mOnSurfaceVariant
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: pinMouseArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
|
||||
onClicked: {
|
||||
if (root.toplevel?.appId) {
|
||||
root.toggleAppPin(root.toplevel.appId)
|
||||
}
|
||||
//root.hide()
|
||||
root.requestClose()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Close item
|
||||
Rectangle {
|
||||
width: parent.width
|
||||
height: 32 * scaling
|
||||
color: closeMouseArea.containsMouse ? Color.mTertiary : Color.transparent
|
||||
color: root.hoveredItem === 2 ? Color.mTertiary : Color.transparent
|
||||
radius: Style.radiusXS * scaling
|
||||
|
||||
Row {
|
||||
@@ -223,41 +256,17 @@ PopupWindow {
|
||||
NIcon {
|
||||
icon: "close"
|
||||
font.pointSize: Style.fontSizeL * scaling
|
||||
color: closeMouseArea.containsMouse ? Color.mOnTertiary : Color.mOnSurfaceVariant
|
||||
color: root.hoveredItem === 2 ? Color.mOnTertiary : Color.mOnSurfaceVariant
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
NText {
|
||||
text: I18n.tr("dock.menu.close")
|
||||
font.pointSize: Style.fontSizeS * scaling
|
||||
color: closeMouseArea.containsMouse ? Color.mOnTertiary : Color.mOnSurfaceVariant
|
||||
color: root.hoveredItem === 2 ? Color.mOnTertiary : Color.mOnSurfaceVariant
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: closeMouseArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
|
||||
onClicked: {
|
||||
// Check if toplevel is still valid before trying to close it
|
||||
const isValidToplevel = root.toplevel && ToplevelManager && ToplevelManager.toplevels.values.includes(root.toplevel)
|
||||
|
||||
if (isValidToplevel && root.toplevel.close) {
|
||||
root.toplevel.close()
|
||||
// Trigger immediate dock update callback if provided
|
||||
if (root.onAppClosed && typeof root.onAppClosed === "function") {
|
||||
Qt.callLater(root.onAppClosed)
|
||||
}
|
||||
} else {
|
||||
Logger.warn("DockMenu", "Cannot close app - invalid toplevel reference")
|
||||
}
|
||||
root.hide()
|
||||
root.requestClose()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -894,7 +894,7 @@ Loader {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.bottom: parent.top
|
||||
anchors.bottomMargin: Style.marginM * scaling
|
||||
radius: Style.radiusM * scaling
|
||||
radius: Style.radiusS * scaling
|
||||
color: Color.mSurface
|
||||
border.color: Color.mOutline
|
||||
border.width: Math.max(1, Style.borderS * scaling)
|
||||
@@ -905,7 +905,8 @@ Loader {
|
||||
anchors.margins: Style.marginM * scaling
|
||||
anchors.fill: parent
|
||||
text: I18n.tr("lock-screen.shut-down")
|
||||
font.pointSize: Style.fontSizeM * scaling
|
||||
font.pointSize: Style.fontSizeS * scaling
|
||||
color: Color.mOnSurfaceVariant
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
@@ -945,7 +946,7 @@ Loader {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.bottom: parent.top
|
||||
anchors.bottomMargin: Style.marginM * scaling
|
||||
radius: Style.radiusM * scaling
|
||||
radius: Style.radiusS * scaling
|
||||
color: Color.mSurface
|
||||
border.color: Color.mOutline
|
||||
border.width: Math.max(1, Style.borderS * scaling)
|
||||
@@ -956,7 +957,8 @@ Loader {
|
||||
anchors.margins: Style.marginM * scaling
|
||||
anchors.fill: parent
|
||||
text: I18n.tr("lock-screen.restart")
|
||||
font.pointSize: Style.fontSizeM * scaling
|
||||
font.pointSize: Style.fontSizeS * scaling
|
||||
color: Color.mOnSurfaceVariant
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
@@ -997,7 +999,7 @@ Loader {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.bottom: parent.top
|
||||
anchors.bottomMargin: Style.marginM * scaling
|
||||
radius: Style.radiusM * scaling
|
||||
radius: Style.radiusS * scaling
|
||||
color: Color.mSurface
|
||||
border.color: Color.mOutline
|
||||
border.width: Math.max(1, Style.borderS * scaling)
|
||||
@@ -1008,7 +1010,8 @@ Loader {
|
||||
anchors.margins: Style.marginM * scaling
|
||||
anchors.fill: parent
|
||||
text: I18n.tr("lock-screen.suspend")
|
||||
font.pointSize: Style.fontSizeM * scaling
|
||||
font.pointSize: Style.fontSizeS * scaling
|
||||
color: Color.mOnSurfaceVariant
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
|
||||
+9
-9
@@ -410,10 +410,10 @@ Variants {
|
||||
// Make visible and animate in
|
||||
osdItem.visible = true
|
||||
// Use Qt.callLater to ensure the visible change is processed before animation
|
||||
Qt.callLater(function () {
|
||||
osdItem.opacity = 1
|
||||
osdItem.scale = 1.0
|
||||
})
|
||||
Qt.callLater(() => {
|
||||
osdItem.opacity = 1
|
||||
osdItem.scale = 1.0
|
||||
})
|
||||
|
||||
// Start the auto-hide timer
|
||||
hideTimer.start()
|
||||
@@ -524,11 +524,11 @@ Variants {
|
||||
root.item.showOSD()
|
||||
} else {
|
||||
// If item not ready yet, wait for it
|
||||
Qt.callLater(function () {
|
||||
if (root.item) {
|
||||
root.item.showOSD()
|
||||
}
|
||||
})
|
||||
Qt.callLater(() => {
|
||||
if (root.item) {
|
||||
root.item.showOSD()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -69,6 +69,7 @@ Popup {
|
||||
|
||||
NIconButton {
|
||||
icon: "close"
|
||||
tooltipText: "Close"
|
||||
onClicked: widgetSettings.close()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,20 +29,23 @@ ColumnLayout {
|
||||
|
||||
NToggle {
|
||||
Layout.fillWidth: true
|
||||
label: I18n.tr("bar.widget-settings.active-window.auto-hide")
|
||||
label: I18n.tr("bar.widget-settings.active-window.auto-hide.label")
|
||||
description: I18n.tr("bar.widget-settings.active-window.auto-hide.description")
|
||||
checked: root.valueAutoHide
|
||||
onToggled: checked => root.valueAutoHide = checked
|
||||
}
|
||||
|
||||
NToggle {
|
||||
Layout.fillWidth: true
|
||||
label: I18n.tr("bar.widget-settings.active-window.show-app-icon")
|
||||
label: I18n.tr("bar.widget-settings.active-window.show-app-icon.label")
|
||||
description: I18n.tr("bar.widget-settings.active-window.show-app-icon.description")
|
||||
checked: root.valueShowIcon
|
||||
onToggled: checked => root.valueShowIcon = checked
|
||||
}
|
||||
|
||||
NComboBox {
|
||||
label: I18n.tr("bar.widget-settings.active-window.scrolling-mode")
|
||||
label: I18n.tr("bar.widget-settings.active-window.scrolling-mode.label")
|
||||
description: I18n.tr("bar.widget-settings.active-window.scrolling-mode.description")
|
||||
model: [{
|
||||
"key": "always",
|
||||
"name": I18n.tr("options.scrolling-modes.always")
|
||||
|
||||
@@ -28,7 +28,8 @@ ColumnLayout {
|
||||
}
|
||||
|
||||
NToggle {
|
||||
label: I18n.tr("bar.widget-settings.control-center.use-distro-logo")
|
||||
label: I18n.tr("bar.widget-settings.control-center.use-distro-logo.label")
|
||||
description: I18n.tr("bar.widget-settings.control-center.use-distro-logo.description")
|
||||
checked: valueUseDistroLogo
|
||||
onToggled: {
|
||||
valueUseDistroLogo = checked
|
||||
|
||||
@@ -58,7 +58,8 @@ ColumnLayout {
|
||||
NTextInput {
|
||||
id: leftClickExecInput
|
||||
Layout.fillWidth: true
|
||||
label: I18n.tr("bar.widget-settings.custom-button.left-click")
|
||||
label: I18n.tr("bar.widget-settings.custom-button.left-click.label")
|
||||
description: I18n.tr("bar.widget-settings.custom-button.left-click.description")
|
||||
placeholderText: I18n.tr("placeholders.enter-command")
|
||||
text: widgetData?.leftClickExec || widgetMetadata.leftClickExec
|
||||
}
|
||||
@@ -66,7 +67,8 @@ ColumnLayout {
|
||||
NTextInput {
|
||||
id: rightClickExecInput
|
||||
Layout.fillWidth: true
|
||||
label: I18n.tr("bar.widget-settings.custom-button.right-click")
|
||||
label: I18n.tr("bar.widget-settings.custom-button.right-click.label")
|
||||
description: I18n.tr("bar.widget-settings.custom-button.right-click.description")
|
||||
placeholderText: I18n.tr("placeholders.enter-command")
|
||||
text: widgetData?.rightClickExec || widgetMetadata.rightClickExec
|
||||
}
|
||||
@@ -74,7 +76,8 @@ ColumnLayout {
|
||||
NTextInput {
|
||||
id: middleClickExecInput
|
||||
Layout.fillWidth: true
|
||||
label: I18n.tr("bar.widget-settings.custom-button.middle-click")
|
||||
label: I18n.tr("bar.widget-settings.custom-button.middle-click.label")
|
||||
description: I18n.tr("bar.widget-settings.custom-button.middle-click.description")
|
||||
placeholderText: I18n.tr("placeholders.enter-command")
|
||||
text: widgetData.middleClickExec || widgetMetadata.middleClickExec
|
||||
}
|
||||
|
||||
@@ -32,26 +32,30 @@ ColumnLayout {
|
||||
|
||||
NToggle {
|
||||
Layout.fillWidth: true
|
||||
label: I18n.tr("bar.widget-settings.media-mini.auto-hide")
|
||||
label: I18n.tr("bar.widget-settings.media-mini.auto-hide.label")
|
||||
description: I18n.tr("bar.widget-settings.media-mini.auto-hide.description")
|
||||
checked: root.valueAutoHide
|
||||
onToggled: checked => root.valueAutoHide = checked
|
||||
}
|
||||
|
||||
NToggle {
|
||||
label: I18n.tr("bar.widget-settings.media-mini.show-album-art")
|
||||
label: I18n.tr("bar.widget-settings.media-mini.show-album-art.label")
|
||||
description: I18n.tr("bar.widget-settings.media-mini.show-album-art.description")
|
||||
checked: valueShowAlbumArt
|
||||
onToggled: checked => valueShowAlbumArt = checked
|
||||
}
|
||||
|
||||
NToggle {
|
||||
label: I18n.tr("bar.widget-settings.media-mini.show-visualizer")
|
||||
label: I18n.tr("bar.widget-settings.media-mini.show-visualizer.label")
|
||||
description: I18n.tr("bar.widget-settings.media-mini.show-visualizer.description")
|
||||
checked: valueShowVisualizer
|
||||
onToggled: checked => valueShowVisualizer = checked
|
||||
}
|
||||
|
||||
NComboBox {
|
||||
visible: valueShowVisualizer
|
||||
label: I18n.tr("bar.widget-settings.media-mini.visualizer-type")
|
||||
label: I18n.tr("bar.widget-settings.media-mini.visualizer-type.label")
|
||||
description: I18n.tr("bar.widget-settings.media-mini.visualizer-type.description")
|
||||
model: [{
|
||||
"key": "linear",
|
||||
"name": I18n.tr("options.visualizer-types.linear")
|
||||
@@ -68,7 +72,8 @@ ColumnLayout {
|
||||
}
|
||||
|
||||
NComboBox {
|
||||
label: I18n.tr("bar.widget-settings.media-mini.scrolling-mode")
|
||||
label: I18n.tr("bar.widget-settings.media-mini.scrolling-mode.label")
|
||||
description: I18n.tr("bar.widget-settings.media-mini.scrolling-mode.description")
|
||||
model: [{
|
||||
"key": "always",
|
||||
"name": I18n.tr("options.scrolling-modes.always")
|
||||
|
||||
@@ -25,13 +25,15 @@ ColumnLayout {
|
||||
}
|
||||
|
||||
NToggle {
|
||||
label: I18n.tr("bar.widget-settings.notification-history.show-unread-badge")
|
||||
label: I18n.tr("bar.widget-settings.notification-history.show-unread-badge.label")
|
||||
description: I18n.tr("bar.widget-settings.notification-history.show-unread-badge.description")
|
||||
checked: valueShowUnreadBadge
|
||||
onToggled: checked => valueShowUnreadBadge = checked
|
||||
}
|
||||
|
||||
NToggle {
|
||||
label: I18n.tr("bar.widget-settings.notification-history.hide-badge-when-zero")
|
||||
label: I18n.tr("bar.widget-settings.notification-history.hide-badge-when-zero.label")
|
||||
description: I18n.tr("bar.widget-settings.notification-history.hide-badge-when-zero.description")
|
||||
checked: valueHideWhenZero
|
||||
onToggled: checked => valueHideWhenZero = checked
|
||||
}
|
||||
|
||||
@@ -35,7 +35,8 @@ ColumnLayout {
|
||||
NToggle {
|
||||
id: showCpuUsage
|
||||
Layout.fillWidth: true
|
||||
label: I18n.tr("bar.widget-settings.system-monitor.cpu-usage")
|
||||
label: I18n.tr("bar.widget-settings.system-monitor.cpu-usage.label")
|
||||
description: I18n.tr("bar.widget-settings.system-monitor.cpu-usage.description")
|
||||
checked: valueShowCpuUsage
|
||||
onToggled: checked => valueShowCpuUsage = checked
|
||||
}
|
||||
@@ -43,7 +44,8 @@ ColumnLayout {
|
||||
NToggle {
|
||||
id: showCpuTemp
|
||||
Layout.fillWidth: true
|
||||
label: I18n.tr("bar.widget-settings.system-monitor.cpu-temperature")
|
||||
label: I18n.tr("bar.widget-settings.system-monitor.cpu-temperature.label")
|
||||
description: I18n.tr("bar.widget-settings.system-monitor.cpu-temperature.description")
|
||||
checked: valueShowCpuTemp
|
||||
onToggled: checked => valueShowCpuTemp = checked
|
||||
}
|
||||
@@ -51,7 +53,8 @@ ColumnLayout {
|
||||
NToggle {
|
||||
id: showMemoryUsage
|
||||
Layout.fillWidth: true
|
||||
label: I18n.tr("bar.widget-settings.system-monitor.memory-usage")
|
||||
label: I18n.tr("bar.widget-settings.system-monitor.memory-usage.label")
|
||||
description: I18n.tr("bar.widget-settings.system-monitor.memory-usage.description")
|
||||
checked: valueShowMemoryUsage
|
||||
onToggled: checked => valueShowMemoryUsage = checked
|
||||
}
|
||||
@@ -59,7 +62,8 @@ ColumnLayout {
|
||||
NToggle {
|
||||
id: showMemoryAsPercent
|
||||
Layout.fillWidth: true
|
||||
label: I18n.tr("bar.widget-settings.system-monitor.memory-percentage")
|
||||
label: I18n.tr("bar.widget-settings.system-monitor.memory-percentage.label")
|
||||
description: I18n.tr("bar.widget-settings.system-monitor.memory-percentage.description")
|
||||
checked: valueShowMemoryAsPercent
|
||||
onToggled: checked => valueShowMemoryAsPercent = checked
|
||||
visible: valueShowMemoryUsage
|
||||
@@ -68,7 +72,8 @@ ColumnLayout {
|
||||
NToggle {
|
||||
id: showNetworkStats
|
||||
Layout.fillWidth: true
|
||||
label: I18n.tr("bar.widget-settings.system-monitor.network-traffic")
|
||||
label: I18n.tr("bar.widget-settings.system-monitor.network-traffic.label")
|
||||
description: I18n.tr("bar.widget-settings.system-monitor.network-traffic.description")
|
||||
checked: valueShowNetworkStats
|
||||
onToggled: checked => valueShowNetworkStats = checked
|
||||
}
|
||||
@@ -76,7 +81,8 @@ ColumnLayout {
|
||||
NToggle {
|
||||
id: showDiskUsage
|
||||
Layout.fillWidth: true
|
||||
label: I18n.tr("bar.widget-settings.system-monitor.storage-usage")
|
||||
label: I18n.tr("bar.widget-settings.system-monitor.storage-usage.label")
|
||||
description: I18n.tr("bar.widget-settings.system-monitor.storage-usage.description")
|
||||
checked: valueShowDiskUsage
|
||||
onToggled: checked => valueShowDiskUsage = checked
|
||||
}
|
||||
|
||||
@@ -23,7 +23,8 @@ ColumnLayout {
|
||||
NComboBox {
|
||||
id: labelModeCombo
|
||||
|
||||
label: I18n.tr("bar.widget-settings.workspace.label-mode")
|
||||
label: I18n.tr("bar.widget-settings.workspace.label-mode.label")
|
||||
description: I18n.tr("bar.widget-settings.workspace.label-mode.description")
|
||||
model: [{
|
||||
"key": "none",
|
||||
"name": I18n.tr("options.workspace-labels.none")
|
||||
|
||||
@@ -150,6 +150,7 @@ ColumnLayout {
|
||||
// AudioService Devices
|
||||
ColumnLayout {
|
||||
spacing: Style.marginS * scaling
|
||||
Layout.fillWidth: true
|
||||
|
||||
NHeader {
|
||||
label: I18n.tr("settings.audio.devices.section.label")
|
||||
@@ -175,14 +176,15 @@ ColumnLayout {
|
||||
Repeater {
|
||||
model: AudioService.sinks
|
||||
NRadioButton {
|
||||
required property PwNode modelData
|
||||
ButtonGroup.group: sinks
|
||||
required property PwNode modelData
|
||||
text: modelData.description
|
||||
checked: AudioService.sink?.id === modelData.id
|
||||
onClicked: {
|
||||
AudioService.setAudioSink(modelData)
|
||||
localVolume = AudioService.volume
|
||||
}
|
||||
text: modelData.description
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -204,12 +206,14 @@ ColumnLayout {
|
||||
|
||||
Repeater {
|
||||
model: AudioService.sources
|
||||
//Layout.fillWidth: true
|
||||
NRadioButton {
|
||||
required property PwNode modelData
|
||||
ButtonGroup.group: sources
|
||||
required property PwNode modelData
|
||||
text: modelData.description
|
||||
checked: AudioService.source?.id === modelData.id
|
||||
onClicked: AudioService.setAudioSource(modelData)
|
||||
text: modelData.description
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,11 +93,11 @@ Item {
|
||||
// Activate the loader and show toast
|
||||
windowLoader.active = true
|
||||
// Need a small delay to ensure the window is created
|
||||
Qt.callLater(function () {
|
||||
if (windowLoader.item) {
|
||||
windowLoader.item.showToast(data.message, data.description, data.type, data.duration)
|
||||
}
|
||||
})
|
||||
Qt.callLater(() => {
|
||||
if (windowLoader.item) {
|
||||
windowLoader.item.showToast(data.message, data.description, data.type, data.duration)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function onToastHidden() {
|
||||
|
||||
@@ -0,0 +1,406 @@
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import qs.Commons
|
||||
import qs.Services
|
||||
import qs.Widgets
|
||||
|
||||
PopupWindow {
|
||||
id: root
|
||||
|
||||
property string text: ""
|
||||
property string direction: "auto" // "auto", "left", "right", "top", "bottom"
|
||||
property int margin: Style.marginXS // distance from target
|
||||
property int padding: Style.marginM
|
||||
property int delay: 0
|
||||
property int hideDelay: 0
|
||||
property int maxWidth: 320
|
||||
property real scaling: 1.0
|
||||
property int animationDuration: Style.animationFast
|
||||
property real animationScale: 0.85
|
||||
|
||||
// Internal properties
|
||||
property var targetItem: null
|
||||
property real anchorX: 0
|
||||
property real anchorY: 0
|
||||
property bool isPositioned: false
|
||||
property bool pendingShow: false
|
||||
property bool animatingOut: true
|
||||
|
||||
visible: false
|
||||
color: Color.transparent
|
||||
|
||||
anchor.item: targetItem
|
||||
anchor.rect.x: anchorX
|
||||
anchor.rect.y: anchorY
|
||||
|
||||
// Timer for showing tooltip after delay
|
||||
Timer {
|
||||
id: showTimer
|
||||
interval: root.delay
|
||||
repeat: false
|
||||
onTriggered: {
|
||||
root.positionAndShow()
|
||||
}
|
||||
}
|
||||
|
||||
// Timer for hiding tooltip after delay
|
||||
Timer {
|
||||
id: hideTimer
|
||||
interval: root.hideDelay
|
||||
repeat: false
|
||||
onTriggered: {
|
||||
root.startHideAnimation()
|
||||
}
|
||||
}
|
||||
|
||||
// Show animation
|
||||
ParallelAnimation {
|
||||
id: showAnimation
|
||||
|
||||
PropertyAnimation {
|
||||
target: tooltipContainer
|
||||
property: "opacity"
|
||||
from: 0.0
|
||||
to: 1.0
|
||||
duration: root.animationDuration
|
||||
easing.type: Easing.OutCubic
|
||||
}
|
||||
|
||||
PropertyAnimation {
|
||||
target: tooltipContainer
|
||||
property: "scale"
|
||||
from: root.animationScale
|
||||
to: 1.0
|
||||
duration: root.animationDuration
|
||||
easing.type: Easing.OutBack
|
||||
easing.overshoot: 1.2
|
||||
}
|
||||
}
|
||||
|
||||
// Hide animation
|
||||
ParallelAnimation {
|
||||
id: hideAnimation
|
||||
|
||||
PropertyAnimation {
|
||||
target: tooltipContainer
|
||||
property: "opacity"
|
||||
from: 1.0
|
||||
to: 0.0
|
||||
duration: root.animationDuration * 0.75 // Slightly faster hide
|
||||
easing.type: Easing.InCubic
|
||||
}
|
||||
|
||||
PropertyAnimation {
|
||||
target: tooltipContainer
|
||||
property: "scale"
|
||||
from: 1.0
|
||||
to: root.animationScale
|
||||
duration: root.animationDuration * 0.75
|
||||
easing.type: Easing.InCubic
|
||||
}
|
||||
|
||||
onFinished: {
|
||||
root.completeHide()
|
||||
}
|
||||
}
|
||||
|
||||
// Function to show tooltip
|
||||
function show(target, tipText, customDirection, showDelay) {
|
||||
if (!target || !tipText || tipText === "")
|
||||
return
|
||||
|
||||
delay = showDelay
|
||||
|
||||
// Stop any running timers and animations
|
||||
hideTimer.stop()
|
||||
showTimer.stop()
|
||||
hideAnimation.stop()
|
||||
animatingOut = false
|
||||
|
||||
// If we're already showing for a different target, hide immediately
|
||||
if (visible && targetItem !== target) {
|
||||
hideImmediately()
|
||||
}
|
||||
|
||||
// Set properties
|
||||
targetItem = target
|
||||
text = tipText
|
||||
pendingShow = true
|
||||
|
||||
if (customDirection !== undefined) {
|
||||
direction = customDirection
|
||||
} else {
|
||||
direction = "auto"
|
||||
}
|
||||
|
||||
// Start show timer
|
||||
showTimer.start()
|
||||
}
|
||||
|
||||
// Function to position and display the tooltip
|
||||
function positionAndShow() {
|
||||
if (!targetItem || !targetItem.parent || !pendingShow) {
|
||||
return
|
||||
}
|
||||
|
||||
// Get screen dimensions - try multiple methods
|
||||
var screenWidth = Screen.width
|
||||
var screenHeight = Screen.height
|
||||
|
||||
// Try to get screen from target item
|
||||
if (targetItem) {
|
||||
if (targetItem.screen) {
|
||||
screenWidth = targetItem.screen.width
|
||||
screenHeight = targetItem.screen.height
|
||||
scaling = ScalingService.getScreenScale(targetItem.screen)
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate tooltip dimensions
|
||||
const tipWidth = Math.min(tooltipText.implicitWidth + (padding * 2 * scaling), maxWidth * scaling)
|
||||
root.implicitWidth = tipWidth
|
||||
|
||||
const tipHeight = tooltipText.implicitHeight + (padding * 2 * scaling)
|
||||
root.implicitHeight = tipHeight
|
||||
|
||||
// Get target's global position
|
||||
const targetGlobal = targetItem.mapToGlobal(0, 0)
|
||||
const targetWidth = targetItem.width
|
||||
const targetHeight = targetItem.height
|
||||
|
||||
var newAnchorX = 0
|
||||
var newAnchorY = 0
|
||||
|
||||
if (direction === "auto") {
|
||||
// Calculate available space in each direction
|
||||
const spaceLeft = targetGlobal.x
|
||||
const spaceRight = screenWidth - (targetGlobal.x + targetWidth)
|
||||
const spaceTop = targetGlobal.y
|
||||
const spaceBottom = screenHeight - (targetGlobal.y + targetHeight)
|
||||
|
||||
// Try positions in order of available space
|
||||
const positions = [{
|
||||
"dir": "bottom",
|
||||
"space": spaceBottom,
|
||||
"x": (targetWidth - tipWidth) / 2,
|
||||
"y": targetHeight + margin * scaling,
|
||||
"fits": spaceBottom >= tipHeight + margin * scaling
|
||||
}, {
|
||||
"dir": "top",
|
||||
"space": spaceTop,
|
||||
"x": (targetWidth - tipWidth) / 2,
|
||||
"y": -tipHeight - margin * scaling,
|
||||
"fits": spaceTop >= tipHeight + margin * scaling
|
||||
}, {
|
||||
"dir": "right",
|
||||
"space": spaceRight,
|
||||
"x": targetWidth + margin * scaling,
|
||||
"y": (targetHeight - tipHeight) / 2,
|
||||
"fits": spaceRight >= tipWidth + margin * scaling
|
||||
}, {
|
||||
"dir": "left",
|
||||
"space": spaceLeft,
|
||||
"x": -tipWidth - margin * scaling,
|
||||
"y": (targetHeight - tipHeight) / 2,
|
||||
"fits": spaceLeft >= tipWidth + margin * scaling
|
||||
}]
|
||||
|
||||
// Find first position that fits
|
||||
var selectedPosition = null
|
||||
for (var i = 0; i < positions.length; i++) {
|
||||
if (positions[i].fits) {
|
||||
selectedPosition = positions[i]
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// If none fit perfectly
|
||||
if (!selectedPosition) {
|
||||
// Sort by available space and use position with most space
|
||||
positions.sort(function (a, b) {
|
||||
return b.space - a.space
|
||||
})
|
||||
selectedPosition = positions[0]
|
||||
}
|
||||
|
||||
newAnchorX = selectedPosition.x
|
||||
newAnchorY = selectedPosition.y
|
||||
|
||||
// Adjust horizontal position to keep tooltip on screen
|
||||
if (direction === "auto") {
|
||||
const globalX = targetGlobal.x + newAnchorX
|
||||
if (globalX < 0) {
|
||||
newAnchorX = -targetGlobal.x + margin * scaling
|
||||
} else if (globalX + tipWidth > screenWidth) {
|
||||
newAnchorX = screenWidth - targetGlobal.x - tipWidth - margin * scaling
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Manual direction positioning
|
||||
switch (direction) {
|
||||
case "left":
|
||||
newAnchorX = -tipWidth - margin * scaling
|
||||
newAnchorY = (targetHeight - tipHeight) / 2
|
||||
break
|
||||
case "right":
|
||||
newAnchorX = targetWidth + margin * scaling
|
||||
newAnchorY = (targetHeight - tipHeight) / 2
|
||||
break
|
||||
case "top":
|
||||
newAnchorX = (targetWidth - tipWidth) / 2
|
||||
newAnchorY = -tipHeight - margin * scaling
|
||||
break
|
||||
case "bottom":
|
||||
newAnchorX = (targetWidth - tipWidth) / 2
|
||||
newAnchorY = targetHeight + margin * scaling
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Apply position
|
||||
anchorX = newAnchorX
|
||||
anchorY = newAnchorY
|
||||
isPositioned = true
|
||||
pendingShow = false
|
||||
|
||||
// Show tooltip and start animation
|
||||
visible = true
|
||||
|
||||
// Initialize animation state
|
||||
tooltipContainer.opacity = 0.0
|
||||
tooltipContainer.scale = animationScale
|
||||
|
||||
// Start show animation
|
||||
showAnimation.start()
|
||||
|
||||
// Force anchor update after showing
|
||||
Qt.callLater(() => {
|
||||
if (root.anchor && root.visible) {
|
||||
root.anchor.updateAnchor()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Function to hide tooltip
|
||||
function hide() {
|
||||
// Stop show timer if it's running
|
||||
showTimer.stop()
|
||||
pendingShow = false
|
||||
|
||||
// Stop hide timer if it's running
|
||||
hideTimer.stop()
|
||||
|
||||
if (hideDelay > 0 && visible && !animatingOut) {
|
||||
hideTimer.start()
|
||||
} else {
|
||||
startHideAnimation()
|
||||
}
|
||||
}
|
||||
|
||||
function startHideAnimation() {
|
||||
if (!visible || animatingOut)
|
||||
return
|
||||
|
||||
animatingOut = true
|
||||
showAnimation.stop() // Stop show animation if running
|
||||
hideAnimation.start()
|
||||
}
|
||||
|
||||
function completeHide() {
|
||||
visible = false
|
||||
animatingOut = false
|
||||
pendingShow = false
|
||||
text = ""
|
||||
isPositioned = false
|
||||
tooltipContainer.opacity = 1.0
|
||||
tooltipContainer.scale = 1.0
|
||||
}
|
||||
|
||||
// Quick hide without delay or animation
|
||||
function hideImmediately() {
|
||||
showTimer.stop()
|
||||
hideTimer.stop()
|
||||
showAnimation.stop()
|
||||
hideAnimation.stop()
|
||||
pendingShow = false
|
||||
animatingOut = false
|
||||
completeHide()
|
||||
}
|
||||
|
||||
// Update text function for binding support
|
||||
function updateText(newText) {
|
||||
if (visible && targetItem) {
|
||||
text = newText
|
||||
positionAndShow()
|
||||
}
|
||||
}
|
||||
|
||||
// Reset function to clean up state
|
||||
function reset() {
|
||||
// Stop all timers and animations
|
||||
showTimer.stop()
|
||||
hideTimer.stop()
|
||||
showAnimation.stop()
|
||||
hideAnimation.stop()
|
||||
|
||||
// Clear all state
|
||||
visible = false
|
||||
pendingShow = false
|
||||
animatingOut = false
|
||||
text = ""
|
||||
isPositioned = false
|
||||
|
||||
// Reset to defaults
|
||||
direction = "auto"
|
||||
delay = 0
|
||||
hideDelay = 0
|
||||
|
||||
// Reset container state
|
||||
tooltipContainer.opacity = 1.0
|
||||
tooltipContainer.scale = 1.0
|
||||
}
|
||||
|
||||
// Tooltip content container for animations
|
||||
Item {
|
||||
id: tooltipContainer
|
||||
anchors.fill: parent
|
||||
|
||||
// Animation properties
|
||||
opacity: 1.0
|
||||
scale: 1.0
|
||||
transformOrigin: Item.Center
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: Color.mSurface
|
||||
border.color: Color.mOutline
|
||||
border.width: Math.max(1, Style.borderS * scaling)
|
||||
radius: Style.radiusS * scaling
|
||||
|
||||
// Only show content when we have text
|
||||
visible: root.text !== ""
|
||||
|
||||
NText {
|
||||
id: tooltipText
|
||||
anchors.centerIn: parent
|
||||
anchors.margins: root.padding * root.scaling
|
||||
text: root.text
|
||||
font.pointSize: Style.fontSizeS * scaling
|
||||
color: Color.mOnSurfaceVariant
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
wrapMode: Text.WordWrap
|
||||
width: root.maxWidth
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
reset()
|
||||
}
|
||||
|
||||
Component.onDestruction: {
|
||||
reset()
|
||||
}
|
||||
}
|
||||
@@ -202,4 +202,17 @@ Singleton {
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
function getTooltipDirection() {
|
||||
switch (Settings.data.bar.position) {
|
||||
case "right":
|
||||
return "left"
|
||||
case "left":
|
||||
return "right"
|
||||
case "bottom":
|
||||
return "top"
|
||||
default:
|
||||
return "bottom"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
pragma Singleton
|
||||
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
import qs.Commons
|
||||
import qs.Modules.Tooltip
|
||||
|
||||
Singleton {
|
||||
id: root
|
||||
|
||||
property var activeTooltip: null
|
||||
property var pendingTooltip: null // Track tooltip being created
|
||||
|
||||
property Component tooltipComponent: Component {
|
||||
Tooltip {}
|
||||
}
|
||||
|
||||
function show(target, text, direction, delay) {
|
||||
// Don't create if no text
|
||||
if (!target || !text) {
|
||||
Logger.log("Tooltip", "No target or text")
|
||||
return
|
||||
}
|
||||
|
||||
// If we have a pending tooltip for a different target, cancel it
|
||||
if (pendingTooltip && pendingTooltip.targetItem !== target) {
|
||||
pendingTooltip.hideImmediately()
|
||||
pendingTooltip.destroy()
|
||||
pendingTooltip = null
|
||||
}
|
||||
|
||||
// If we have an active tooltip for a different target, hide it
|
||||
if (activeTooltip && activeTooltip.targetItem !== target) {
|
||||
activeTooltip.hideImmediately()
|
||||
// Don't destroy immediately - let it clean itself up
|
||||
activeTooltip = null
|
||||
}
|
||||
|
||||
// If we already have a tooltip for this target, just update it
|
||||
if (activeTooltip && activeTooltip.targetItem === target) {
|
||||
activeTooltip.updateText(text)
|
||||
return activeTooltip
|
||||
}
|
||||
|
||||
// Create new tooltip instance
|
||||
const newTooltip = tooltipComponent.createObject(null)
|
||||
|
||||
if (newTooltip) {
|
||||
// Track as pending until it's visible
|
||||
pendingTooltip = newTooltip
|
||||
|
||||
// Connect cleanup when tooltip hides
|
||||
newTooltip.visibleChanged.connect(() => {
|
||||
if (!newTooltip.visible) {
|
||||
// Clean up after a delay to avoid interfering with new tooltips
|
||||
Qt.callLater(() => {
|
||||
if (newTooltip && !newTooltip.visible) {
|
||||
if (activeTooltip === newTooltip) {
|
||||
activeTooltip = null
|
||||
}
|
||||
if (pendingTooltip === newTooltip) {
|
||||
pendingTooltip = null
|
||||
}
|
||||
newTooltip.destroy()
|
||||
}
|
||||
})
|
||||
} else {
|
||||
// Tooltip is now visible, move from pending to active
|
||||
if (pendingTooltip === newTooltip) {
|
||||
activeTooltip = newTooltip
|
||||
pendingTooltip = null
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// Show the tooltip
|
||||
newTooltip.show(target, text, direction || "auto", delay || Style.tooltipDelay)
|
||||
|
||||
return newTooltip
|
||||
} else {
|
||||
Logger.error("Tooltip", "Failed to create tooltip instance")
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
function hide() {
|
||||
if (pendingTooltip) {
|
||||
pendingTooltip.hide()
|
||||
}
|
||||
if (activeTooltip) {
|
||||
activeTooltip.hide()
|
||||
}
|
||||
}
|
||||
|
||||
function hideImmediately() {
|
||||
if (pendingTooltip) {
|
||||
pendingTooltip.hideImmediately()
|
||||
pendingTooltip.destroy()
|
||||
pendingTooltip = null
|
||||
}
|
||||
if (activeTooltip) {
|
||||
activeTooltip.hideImmediately()
|
||||
activeTooltip.destroy()
|
||||
activeTooltip = null
|
||||
}
|
||||
}
|
||||
|
||||
function updateText(newText) {
|
||||
if (activeTooltip) {
|
||||
activeTooltip.updateText(newText)
|
||||
}
|
||||
}
|
||||
}
|
||||
+5
-10
@@ -2,6 +2,7 @@ import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import qs.Commons
|
||||
import qs.Services
|
||||
|
||||
Rectangle {
|
||||
id: root
|
||||
@@ -126,12 +127,6 @@ Rectangle {
|
||||
}
|
||||
}
|
||||
|
||||
NTooltip {
|
||||
id: tooltip
|
||||
target: root
|
||||
text: root.tooltipText
|
||||
}
|
||||
|
||||
// Mouse interaction
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
@@ -144,18 +139,18 @@ Rectangle {
|
||||
onEntered: {
|
||||
root.hovered = true
|
||||
if (tooltipText) {
|
||||
tooltip.show()
|
||||
TooltipService.show(root, root.tooltipText)
|
||||
}
|
||||
}
|
||||
onExited: {
|
||||
root.hovered = false
|
||||
if (tooltipText) {
|
||||
tooltip.hide()
|
||||
TooltipService.hide()
|
||||
}
|
||||
}
|
||||
onPressed: mouse => {
|
||||
if (tooltipText) {
|
||||
tooltip.hide()
|
||||
TooltipService.hide()
|
||||
}
|
||||
if (mouse.button === Qt.LeftButton) {
|
||||
root.clicked()
|
||||
@@ -169,7 +164,7 @@ Rectangle {
|
||||
onCanceled: {
|
||||
root.hovered = false
|
||||
if (tooltipText) {
|
||||
tooltip.hide()
|
||||
TooltipService.hide()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+4
-15
@@ -11,9 +11,7 @@ Rectangle {
|
||||
|
||||
property string icon
|
||||
property string tooltipText
|
||||
property bool tooltipPositionAbove: false
|
||||
property bool tooltipPositionLeft: false
|
||||
property bool tooltipPositionRight: false
|
||||
property string tooltipDirection: "auto"
|
||||
property bool enabled: true
|
||||
property bool allowClickWhenDisabled: false
|
||||
property bool hovering: false
|
||||
@@ -65,15 +63,6 @@ Rectangle {
|
||||
}
|
||||
}
|
||||
|
||||
NTooltip {
|
||||
id: tooltip
|
||||
target: root
|
||||
positionAbove: root.tooltipPositionAbove
|
||||
positionLeft: root.tooltipPositionLeft
|
||||
positionRight: root.tooltipPositionRight
|
||||
text: root.tooltipText
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
// Always enabled to allow hover/tooltip even when the button is disabled
|
||||
enabled: true
|
||||
@@ -84,20 +73,20 @@ Rectangle {
|
||||
onEntered: {
|
||||
hovering = root.enabled ? true : false
|
||||
if (tooltipText) {
|
||||
tooltip.show()
|
||||
TooltipService.show(parent, tooltipText, tooltipDirection)
|
||||
}
|
||||
root.entered()
|
||||
}
|
||||
onExited: {
|
||||
hovering = false
|
||||
if (tooltipText) {
|
||||
tooltip.hide()
|
||||
TooltipService.hide()
|
||||
}
|
||||
root.exited()
|
||||
}
|
||||
onClicked: function (mouse) {
|
||||
if (tooltipText) {
|
||||
tooltip.hide()
|
||||
TooltipService.hide()
|
||||
}
|
||||
if (!root.enabled && !allowClickWhenDisabled) {
|
||||
return
|
||||
|
||||
@@ -44,6 +44,7 @@ RadioButton {
|
||||
font.pointSize: Style.fontSizeM * scaling
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.left: outerCircle.right
|
||||
anchors.right: parent.right
|
||||
anchors.leftMargin: Style.marginS * scaling
|
||||
}
|
||||
}
|
||||
|
||||
@@ -255,11 +255,11 @@ RowLayout {
|
||||
// Ensure the model is filtered when popup opens
|
||||
filterModel()
|
||||
// Small delay to ensure the popup is fully rendered
|
||||
Qt.callLater(function () {
|
||||
if (searchInput && searchInput.inputItem) {
|
||||
searchInput.inputItem.forceActiveFocus()
|
||||
}
|
||||
})
|
||||
Qt.callLater(() => {
|
||||
if (searchInput && searchInput.inputItem) {
|
||||
searchInput.inputItem.forceActiveFocus()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+107
-47
@@ -10,10 +10,10 @@ RowLayout {
|
||||
id: root
|
||||
|
||||
// Public properties
|
||||
property alias value: spinBox.value
|
||||
property alias from: spinBox.from
|
||||
property alias to: spinBox.to
|
||||
property alias stepSize: spinBox.stepSize
|
||||
property int value: 0
|
||||
property int from: 0
|
||||
property int to: 100
|
||||
property int stepSize: 1
|
||||
property string suffix: ""
|
||||
property string prefix: ""
|
||||
property string label: ""
|
||||
@@ -23,8 +23,8 @@ RowLayout {
|
||||
property int baseSize: Style.baseWidgetSize
|
||||
|
||||
// Convenience properties for common naming
|
||||
property alias minimum: spinBox.from
|
||||
property alias maximum: spinBox.to
|
||||
property alias minimum: root.from
|
||||
property alias maximum: root.to
|
||||
|
||||
signal entered
|
||||
signal exited
|
||||
@@ -36,12 +36,12 @@ RowLayout {
|
||||
description: root.description
|
||||
}
|
||||
|
||||
// Value
|
||||
// Main spinbox container
|
||||
Rectangle {
|
||||
id: spinBoxContainer
|
||||
implicitWidth: 100 * scaling // Wider for better proportions
|
||||
implicitHeight: (root.baseSize - 4) * scaling // Slightly shorter than toggle
|
||||
radius: height / 2 // Fully rounded like toggle
|
||||
implicitWidth: 120 * scaling
|
||||
implicitHeight: (root.baseSize - 4) * scaling
|
||||
radius: height * 0.5
|
||||
color: Color.mSurfaceVariant
|
||||
border.color: (root.hovering || decreaseArea.containsMouse || increaseArea.containsMouse) ? Color.mTertiary : Color.mOutline
|
||||
border.width: 1
|
||||
@@ -52,7 +52,7 @@ RowLayout {
|
||||
}
|
||||
}
|
||||
|
||||
// Mouse area for scroll wheel and hover
|
||||
// Mouse area for hover and scroll
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.NoButton
|
||||
@@ -66,10 +66,12 @@ RowLayout {
|
||||
root.exited()
|
||||
}
|
||||
onWheel: wheel => {
|
||||
if (wheel.angleDelta.y > 0 && spinBox.value < spinBox.to) {
|
||||
spinBox.increase()
|
||||
} else if (wheel.angleDelta.y < 0 && spinBox.value > spinBox.from) {
|
||||
spinBox.decrease()
|
||||
if (wheel.angleDelta.y > 0 && root.value < root.to) {
|
||||
let newValue = Math.min(root.to, root.value + root.stepSize)
|
||||
root.value = newValue
|
||||
} else if (wheel.angleDelta.y < 0 && root.value > root.from) {
|
||||
let newValue = Math.max(root.from, root.value - root.stepSize)
|
||||
root.value = newValue
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -82,7 +84,8 @@ RowLayout {
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.left: parent.left
|
||||
opacity: root.enabled && spinBox.value > spinBox.from ? 1.0 : 0.3
|
||||
opacity: root.enabled && root.value > root.from ? 1.0 : 0.3
|
||||
|
||||
|
||||
Item {
|
||||
id: leftSemicircle
|
||||
@@ -133,14 +136,17 @@ RowLayout {
|
||||
color: decreaseArea.containsMouse ? Color.mOnPrimary : Color.mPrimary
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: decreaseArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
enabled: root.enabled && spinBox.value > spinBox.from
|
||||
onClicked: spinBox.decrease()
|
||||
MouseArea {
|
||||
id: decreaseArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
enabled: root.enabled && root.value > root.from
|
||||
onClicked: {
|
||||
let newValue = Math.max(root.from, root.value - root.stepSize)
|
||||
root.value = newValue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -153,6 +159,8 @@ RowLayout {
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.right: parent.right
|
||||
opacity: root.enabled && spinBox.value < spinBox.to ? 1.0 : 0.3
|
||||
opacity: root.enabled && root.value < root.to ? 1.0 : 0.3
|
||||
|
||||
|
||||
Item {
|
||||
id: rightSemicircle
|
||||
@@ -208,44 +216,96 @@ RowLayout {
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
enabled: root.enabled && spinBox.value < spinBox.to
|
||||
onClicked: spinBox.increase()
|
||||
enabled: root.enabled && root.value < root.to
|
||||
onClicked: {
|
||||
let newValue = Math.min(root.to, root.value + root.stepSize)
|
||||
root.value = newValue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Center value display
|
||||
SpinBox {
|
||||
id: spinBox
|
||||
// Center value display with separate prefix, value, and suffix
|
||||
Rectangle {
|
||||
id: valueContainer
|
||||
anchors.left: decreaseButton.right
|
||||
anchors.right: increaseButton.left
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.margins: 4 * scaling
|
||||
height: parent.height
|
||||
color: "transparent"
|
||||
|
||||
background: Item {}
|
||||
up.indicator: Item {}
|
||||
down.indicator: Item {}
|
||||
Row {
|
||||
anchors.centerIn: parent
|
||||
spacing: 0
|
||||
|
||||
font.pointSize: Style.fontSizeM * scaling
|
||||
font.family: Settings.data.ui.fontDefault
|
||||
|
||||
from: 0
|
||||
to: 100
|
||||
stepSize: 1
|
||||
editable: false // Only use buttons/scroll
|
||||
enabled: root.enabled
|
||||
|
||||
contentItem: Item {
|
||||
anchors.fill: parent
|
||||
|
||||
NText {
|
||||
anchors.centerIn: parent
|
||||
text: root.prefix + spinBox.value + root.suffix
|
||||
// Prefix text (non-editable)
|
||||
Text {
|
||||
text: root.prefix
|
||||
font.family: Settings.data.ui.fontFixed
|
||||
font.pointSize: Style.fontSizeM * scaling
|
||||
font.weight: Style.fontWeightMedium
|
||||
color: Color.mOnSurface
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
visible: root.prefix !== ""
|
||||
}
|
||||
|
||||
// Editable number input
|
||||
TextInput {
|
||||
id: valueInput
|
||||
text: root.value.toString()
|
||||
font.family: Settings.data.ui.fontFixed
|
||||
font.pointSize: Style.fontSizeM * scaling
|
||||
font.weight: Style.fontWeightMedium
|
||||
color: Color.mOnSurface
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
selectByMouse: true
|
||||
enabled: root.enabled
|
||||
|
||||
// Only allow numeric input within range
|
||||
validator: IntValidator {
|
||||
bottom: root.from
|
||||
top: root.to
|
||||
}
|
||||
|
||||
Keys.onReturnPressed: {
|
||||
applyValue()
|
||||
focus = false
|
||||
}
|
||||
|
||||
Keys.onEscapePressed: {
|
||||
text = root.value.toString()
|
||||
focus = false
|
||||
}
|
||||
|
||||
onFocusChanged: {
|
||||
if (focus) {
|
||||
selectAll()
|
||||
} else {
|
||||
applyValue()
|
||||
}
|
||||
}
|
||||
|
||||
function applyValue() {
|
||||
let newValue = parseInt(text)
|
||||
if (!isNaN(newValue)) {
|
||||
newValue = Math.max(root.from, Math.min(root.to, newValue))
|
||||
root.value = newValue
|
||||
text = root.value.toString()
|
||||
} else {
|
||||
text = root.value.toString()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Suffix text (non-editable)
|
||||
Text {
|
||||
text: root.suffix
|
||||
font.family: Settings.data.ui.fontFixed
|
||||
font.pointSize: Style.fontSizeM * scaling
|
||||
font.weight: Style.fontWeightMedium
|
||||
color: Color.mOnSurface
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
visible: root.suffix !== ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,197 +0,0 @@
|
||||
import QtQuick
|
||||
import qs.Commons
|
||||
import qs.Services
|
||||
|
||||
Window {
|
||||
id: root
|
||||
|
||||
property bool isVisible: false
|
||||
property string text: I18n.tr("widgets.tooltip.placeholder")
|
||||
property Item target: null
|
||||
property int delay: Style.tooltipDelay
|
||||
property bool positionAbove: false
|
||||
property bool positionLeft: false
|
||||
property bool positionRight: false
|
||||
|
||||
readonly property string barPosition: Settings.data.bar.position
|
||||
|
||||
flags: Qt.ToolTip | Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint
|
||||
color: Color.transparent
|
||||
visible: false
|
||||
|
||||
onIsVisibleChanged: {
|
||||
if (isVisible) {
|
||||
if (delay > 0) {
|
||||
timerShow.running = true
|
||||
} else {
|
||||
_showNow()
|
||||
}
|
||||
} else {
|
||||
_hideNow()
|
||||
}
|
||||
}
|
||||
|
||||
function show() {
|
||||
isVisible = true
|
||||
}
|
||||
function hide() {
|
||||
isVisible = false
|
||||
timerShow.running = false
|
||||
}
|
||||
|
||||
function _showNow() {
|
||||
// Compute new size everytime we show the tooltip
|
||||
width = Math.max(50 * scaling, tooltipText.implicitWidth + Style.marginL * 2 * scaling)
|
||||
height = Math.max(40 * scaling, tooltipText.implicitHeight + Style.marginM * 2 * scaling)
|
||||
|
||||
if (!target) {
|
||||
return
|
||||
}
|
||||
|
||||
if (positionLeft) {
|
||||
// Position tooltip to the left of the target
|
||||
var pos = target.mapToGlobal(0, 0)
|
||||
x = pos.x - width - 12 // 12 px margin to the left
|
||||
y = pos.y - height / 2 + target.height / 2
|
||||
} else if (positionRight) {
|
||||
// Position tooltip to the right of the target
|
||||
var pos = target.mapToGlobal(target.width, 0)
|
||||
x = pos.x + 12 // 12 px margin to the right
|
||||
y = pos.y - height / 2 + target.height / 2
|
||||
} else if (positionAbove) {
|
||||
// Position tooltip above the target
|
||||
var pos = target.mapToGlobal(0, 0)
|
||||
x = pos.x - width / 2 + target.width / 2
|
||||
y = pos.y - height - 12 // 12 px margin above
|
||||
} else {
|
||||
// Position tooltip below the target
|
||||
var pos = target.mapToGlobal(0, target.height)
|
||||
x = pos.x - width / 2 + target.width / 2
|
||||
y = pos.y + 12 // 12 px margin below
|
||||
}
|
||||
|
||||
// Start with animation values
|
||||
tooltipRect.scaleValue = 0.8
|
||||
tooltipRect.opacityValue = 0.0
|
||||
visible = true
|
||||
|
||||
// Use a timer to trigger the animation after the component is visible
|
||||
showTimer.start()
|
||||
}
|
||||
|
||||
function _hideNow() {
|
||||
// Start hide animation
|
||||
tooltipRect.scaleValue = 0.8
|
||||
tooltipRect.opacityValue = 0.0
|
||||
|
||||
// Hide after animation completes
|
||||
hideTimer.start()
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: root.target
|
||||
function onXChanged() {
|
||||
if (root.visible) {
|
||||
root._showNow()
|
||||
}
|
||||
}
|
||||
function onYChanged() {
|
||||
if (root.visible) {
|
||||
root._showNow()
|
||||
}
|
||||
}
|
||||
function onWidthChanged() {
|
||||
if (root.visible) {
|
||||
root._showNow()
|
||||
}
|
||||
}
|
||||
function onHeightChanged() {
|
||||
if (root.visible) {
|
||||
root._showNow()
|
||||
}
|
||||
}
|
||||
}
|
||||
Connections {
|
||||
target: root
|
||||
function onTextChanged() {
|
||||
if (root.visible) {
|
||||
root._showNow()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: timerShow
|
||||
interval: delay
|
||||
running: false
|
||||
repeat: false
|
||||
onTriggered: {
|
||||
_showNow()
|
||||
running = false
|
||||
}
|
||||
}
|
||||
|
||||
// Timer to hide tooltip after animation
|
||||
Timer {
|
||||
id: hideTimer
|
||||
interval: Style.animationNormal
|
||||
repeat: false
|
||||
onTriggered: {
|
||||
visible = false
|
||||
}
|
||||
}
|
||||
|
||||
// Timer to trigger show animation
|
||||
Timer {
|
||||
id: showTimer
|
||||
interval: Style.animationFast / 15 // Very short delay to ensure component is visible
|
||||
repeat: false
|
||||
onTriggered: {
|
||||
// Animate to final values
|
||||
tooltipRect.scaleValue = 1.0
|
||||
tooltipRect.opacityValue = 1.0
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: tooltipRect
|
||||
anchors.fill: parent
|
||||
radius: Style.radiusM * scaling
|
||||
color: Color.mSurface
|
||||
border.color: Color.mOutline
|
||||
border.width: Math.max(1, Style.borderS * scaling)
|
||||
z: 1
|
||||
|
||||
// Animation properties
|
||||
property real scaleValue: 1.0
|
||||
property real opacityValue: 1.0
|
||||
|
||||
scale: scaleValue
|
||||
opacity: opacityValue
|
||||
|
||||
// Animation behaviors
|
||||
Behavior on scale {
|
||||
NumberAnimation {
|
||||
duration: Style.animationNormal
|
||||
easing.type: Easing.OutExpo
|
||||
}
|
||||
}
|
||||
|
||||
Behavior on opacity {
|
||||
NumberAnimation {
|
||||
duration: Style.animationNormal
|
||||
easing.type: Easing.OutQuad
|
||||
}
|
||||
}
|
||||
|
||||
NText {
|
||||
id: tooltipText
|
||||
anchors.centerIn: parent
|
||||
text: root.text
|
||||
font.pointSize: Style.fontSizeM * scaling
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
wrapMode: Text.Wrap
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user