mirror of
https://github.com/zoriya/noctalia-shell.git
synced 2026-06-02 02:26:00 +00:00
OsdTab: move all OSD related settings into their own tab
OSD: add Left/Right Center options (will display vertically) TablerIcons: add OSD Tab icon i18n: added translation to all files for OSDTab (generated)
This commit is contained in:
@@ -363,6 +363,40 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"osd": {
|
||||
"title": "Bildschirmanzeige",
|
||||
"description": "Bildschirm-Overlays wie Lautstärke- und Helligkeitsanzeigen konfigurieren.",
|
||||
"section": {
|
||||
"general": {
|
||||
"label": "Allgemein",
|
||||
"description": "Sichtbarkeit und Verhalten der OSD konfigurieren."
|
||||
}
|
||||
},
|
||||
"enabled": {
|
||||
"label": "Bildschirmanzeige aktivieren",
|
||||
"description": "Lautstärke- und Helligkeitsänderungen in Echtzeit anzeigen."
|
||||
},
|
||||
"location": {
|
||||
"label": "Position",
|
||||
"description": "Wo Bildschirmanzeigen erscheinen."
|
||||
},
|
||||
"duration": {
|
||||
"section": {
|
||||
"label": "Automatisches Ausblenden",
|
||||
"description": "Wie lange die OSD sichtbar bleibt, bevor sie automatisch ausgeblendet wird."
|
||||
},
|
||||
"auto-hide": {
|
||||
"label": "Ausblenden nach",
|
||||
"description": "Zeitspanne bis zum automatischen Ausblenden anpassen."
|
||||
}
|
||||
},
|
||||
"monitors": {
|
||||
"section": {
|
||||
"label": "Monitor-Anzeige",
|
||||
"description": "OSD auf bestimmten Monitoren anzeigen. Standard ist alle, wenn keine ausgewählt sind."
|
||||
}
|
||||
}
|
||||
},
|
||||
"wallpaper": {
|
||||
"title": "Hintergrundbild",
|
||||
"settings": {
|
||||
@@ -1086,7 +1120,21 @@
|
||||
"bottom_left": "Unten links",
|
||||
"bottom_right": "Unten rechts",
|
||||
"bottom_center": "Unten mittig",
|
||||
"top_center": "Oben mittig"
|
||||
"top_center": "Oben mittig",
|
||||
"center_left": "Links mittig",
|
||||
"center_right": "Rechts mittig"
|
||||
}
|
||||
},
|
||||
"osd": {
|
||||
"position": {
|
||||
"top_left": "Oben links",
|
||||
"top_right": "Oben rechts",
|
||||
"top_center": "Oben mittig",
|
||||
"bottom_left": "Unten links",
|
||||
"bottom_right": "Unten rechts",
|
||||
"bottom_center": "Unten mittig",
|
||||
"center_left": "Links mittig",
|
||||
"center_right": "Rechts mittig"
|
||||
}
|
||||
},
|
||||
"display-mode": {
|
||||
@@ -1264,6 +1312,10 @@
|
||||
"battery": {
|
||||
"low": "Niedriger Batteriestand",
|
||||
"low-desc": "Batterie ist bei {percent}%. Bitte schließen Sie das Ladegerät an."
|
||||
},
|
||||
"missing-control-center": {
|
||||
"label": "Letztes Control-Center-Widget entfernt",
|
||||
"description": "Das Control-Center-Widget wurde aus der Leiste entfernt. Um es erneut über die Leiste zu öffnen, fügen Sie das Widget wieder hinzu."
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -363,6 +363,40 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"osd": {
|
||||
"title": "On-Screen Display",
|
||||
"description": "Configure on-screen indicators such as volume and brightness overlays.",
|
||||
"section": {
|
||||
"general": {
|
||||
"label": "General",
|
||||
"description": "Configure visibility and behavior of OSD."
|
||||
}
|
||||
},
|
||||
"enabled": {
|
||||
"label": "Enable on screen display",
|
||||
"description": "Show volume and brightness changes in real-time."
|
||||
},
|
||||
"location": {
|
||||
"label": "Location",
|
||||
"description": "Where on-screen displays appear."
|
||||
},
|
||||
"duration": {
|
||||
"section": {
|
||||
"label": "Auto-hide timeout",
|
||||
"description": "How long OSD remains visible before hiding automatically."
|
||||
},
|
||||
"auto-hide": {
|
||||
"label": "Auto-hide after",
|
||||
"description": "Adjust the time before OSD disappears."
|
||||
}
|
||||
},
|
||||
"monitors": {
|
||||
"section": {
|
||||
"label": "Monitors display",
|
||||
"description": "Show OSD on specific monitors. Defaults to all if none are chosen."
|
||||
}
|
||||
}
|
||||
},
|
||||
"wallpaper": {
|
||||
"title": "Wallpaper",
|
||||
"settings": {
|
||||
@@ -1069,7 +1103,21 @@
|
||||
"bottom_left": "Bottom left",
|
||||
"bottom_right": "Bottom right",
|
||||
"bottom_center": "Bottom center",
|
||||
"top_center": "Top center"
|
||||
"top_center": "Top center",
|
||||
"center_left": "Left center",
|
||||
"center_right": "Right center"
|
||||
}
|
||||
},
|
||||
"osd": {
|
||||
"position": {
|
||||
"top_left": "Top left",
|
||||
"top_right": "Top right",
|
||||
"top_center": "Top center",
|
||||
"bottom_left": "Bottom left",
|
||||
"bottom_right": "Bottom right",
|
||||
"bottom_center": "Bottom center",
|
||||
"center_left": "Left center",
|
||||
"center_right": "Right center"
|
||||
}
|
||||
},
|
||||
"display-mode": {
|
||||
|
||||
@@ -361,6 +361,40 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"osd": {
|
||||
"title": "Visualización en pantalla",
|
||||
"description": "Configura indicadores superpuestos como volumen y brillo.",
|
||||
"section": {
|
||||
"general": {
|
||||
"label": "General",
|
||||
"description": "Configura visibilidad y comportamiento del OSD."
|
||||
}
|
||||
},
|
||||
"enabled": {
|
||||
"label": "Activar visualización en pantalla",
|
||||
"description": "Mostrar cambios de volumen y brillo en tiempo real."
|
||||
},
|
||||
"location": {
|
||||
"label": "Ubicación",
|
||||
"description": "Dónde aparece la visualización en pantalla."
|
||||
},
|
||||
"duration": {
|
||||
"section": {
|
||||
"label": "Tiempo de ocultación automática",
|
||||
"description": "Cuánto tiempo permanece visible el OSD antes de ocultarse automáticamente."
|
||||
},
|
||||
"auto-hide": {
|
||||
"label": "Ocultar después de",
|
||||
"description": "Ajusta el tiempo antes de que el OSD desaparezca."
|
||||
}
|
||||
},
|
||||
"monitors": {
|
||||
"section": {
|
||||
"label": "Visualización en monitores",
|
||||
"description": "Mostrar el OSD en monitores específicos. Por defecto, en todos si no se elige ninguno."
|
||||
}
|
||||
}
|
||||
},
|
||||
"wallpaper": {
|
||||
"title": "Fondo de pantalla",
|
||||
"settings": {
|
||||
@@ -1066,7 +1100,21 @@
|
||||
"bottom_left": "Inferior izquierda",
|
||||
"bottom_right": "Inferior derecha",
|
||||
"bottom_center": "Inferior central",
|
||||
"top_center": "Superior central"
|
||||
"top_center": "Superior central",
|
||||
"center_left": "Izquierda centrado",
|
||||
"center_right": "Derecha centrado"
|
||||
}
|
||||
},
|
||||
"osd": {
|
||||
"position": {
|
||||
"top_left": "Superior izquierda",
|
||||
"top_right": "Superior derecha",
|
||||
"top_center": "Superior central",
|
||||
"bottom_left": "Inferior izquierda",
|
||||
"bottom_right": "Inferior derecha",
|
||||
"bottom_center": "Inferior central",
|
||||
"center_left": "Izquierda centrado",
|
||||
"center_right": "Derecha centrado"
|
||||
}
|
||||
},
|
||||
"display-mode": {
|
||||
@@ -1232,6 +1280,10 @@
|
||||
"battery": {
|
||||
"low": "Batería baja",
|
||||
"low-desc": "La batería está al {percent}%. Por favor, conecta el cargador."
|
||||
},
|
||||
"missing-control-center": {
|
||||
"label": "Se eliminó el último widget del Centro de control",
|
||||
"description": "El widget del Centro de control se eliminó de la barra. Para acceder a él nuevamente desde la barra, debes volver a añadir el widget."
|
||||
}
|
||||
},
|
||||
"weather": {
|
||||
|
||||
@@ -361,6 +361,40 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"osd": {
|
||||
"title": "Affichage à l'écran",
|
||||
"description": "Configurer les indicateurs à l'écran tels que le volume et la luminosité.",
|
||||
"section": {
|
||||
"general": {
|
||||
"label": "Général",
|
||||
"description": "Configurer la visibilité et le comportement de l'OSD."
|
||||
}
|
||||
},
|
||||
"enabled": {
|
||||
"label": "Activer l'affichage à l'écran",
|
||||
"description": "Afficher en temps réel les changements de volume et de luminosité."
|
||||
},
|
||||
"location": {
|
||||
"label": "Emplacement",
|
||||
"description": "Emplacement des affichages à l'écran."
|
||||
},
|
||||
"duration": {
|
||||
"section": {
|
||||
"label": "Délai d'auto‑masquage",
|
||||
"description": "Temps d'affichage avant masquage automatique de l'OSD."
|
||||
},
|
||||
"auto-hide": {
|
||||
"label": "Masquer après",
|
||||
"description": "Ajuster le délai avant disparition de l'OSD."
|
||||
}
|
||||
},
|
||||
"monitors": {
|
||||
"section": {
|
||||
"label": "Affichage sur les moniteurs",
|
||||
"description": "Afficher l'OSD sur des moniteurs spécifiques. Par défaut sur tous si aucun n'est choisi."
|
||||
}
|
||||
}
|
||||
},
|
||||
"wallpaper": {
|
||||
"title": "Fond d'écran",
|
||||
"settings": {
|
||||
@@ -1066,7 +1100,21 @@
|
||||
"bottom_left": "En bas à gauche",
|
||||
"bottom_right": "En bas à droite",
|
||||
"bottom_center": "En bas au centre",
|
||||
"top_center": "En haut au centre"
|
||||
"top_center": "En haut au centre",
|
||||
"center_left": "Gauche centre",
|
||||
"center_right": "Droite centre"
|
||||
}
|
||||
},
|
||||
"osd": {
|
||||
"position": {
|
||||
"top_left": "En haut à gauche",
|
||||
"top_right": "En haut à droite",
|
||||
"top_center": "En haut au centre",
|
||||
"bottom_left": "En bas à gauche",
|
||||
"bottom_right": "En bas à droite",
|
||||
"bottom_center": "En bas au centre",
|
||||
"center_left": "Gauche centre",
|
||||
"center_right": "Droite centre"
|
||||
}
|
||||
},
|
||||
"display-mode": {
|
||||
@@ -1232,6 +1280,10 @@
|
||||
"battery": {
|
||||
"low": "Batterie faible",
|
||||
"low-desc": "La batterie est à {percent}%. Veuillez brancher le chargeur."
|
||||
},
|
||||
"missing-control-center": {
|
||||
"label": "Dernier widget du Centre de contrôle supprimé",
|
||||
"description": "Le widget du Centre de contrôle a été retiré de la barre. Pour y accéder à nouveau depuis la barre, veuillez ré‑ajouter le widget."
|
||||
}
|
||||
},
|
||||
"weather": {
|
||||
|
||||
@@ -673,8 +673,43 @@
|
||||
"description": "• Hook de Papel de Parede: $1 = caminho do papel de parede, $2 = nome da tela\n• Hook de Alternância de Tema: $1 = true/false (estado do modo escuro)"
|
||||
}
|
||||
}
|
||||
},
|
||||
"osd": {
|
||||
"title": "Exibição na tela",
|
||||
"description": "Configure indicadores na tela, como volume e brilho.",
|
||||
"section": {
|
||||
"general": {
|
||||
"label": "Geral",
|
||||
"description": "Configurar visibilidade e comportamento da OSD."
|
||||
}
|
||||
},
|
||||
"enabled": {
|
||||
"label": "Ativar exibição na tela",
|
||||
"description": "Mostrar alterações de volume e brilho em tempo real."
|
||||
},
|
||||
"location": {
|
||||
"label": "Localização",
|
||||
"description": "Onde a exibição na tela aparece."
|
||||
},
|
||||
"duration": {
|
||||
"section": {
|
||||
"label": "Tempo para ocultar",
|
||||
"description": "Quanto tempo a OSD permanece visível antes de ocultar automaticamente."
|
||||
},
|
||||
"auto-hide": {
|
||||
"label": "Ocultar após",
|
||||
"description": "Ajusta o tempo antes da OSD desaparecer."
|
||||
}
|
||||
},
|
||||
"monitors": {
|
||||
"section": {
|
||||
"label": "Exibição nos monitores",
|
||||
"description": "Mostrar a OSD em monitores específicos. Padrão é todos se nenhum for escolhido."
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"widgets": {
|
||||
"tooltip": {
|
||||
"placeholder": "Espaço reservado"
|
||||
@@ -1045,6 +1080,31 @@
|
||||
"test": "Testar"
|
||||
},
|
||||
"options": {
|
||||
"osd": {
|
||||
"position": {
|
||||
"top_left": "Superior esquerdo",
|
||||
"top_right": "Superior direito",
|
||||
"top_center": "Centro superior",
|
||||
"bottom_left": "Inferior esquerdo",
|
||||
"bottom_right": "Inferior direito",
|
||||
"bottom_center": "Centro inferior",
|
||||
"center_left": "Esquerda central",
|
||||
"center_right": "Direita central"
|
||||
}
|
||||
},
|
||||
"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": "Esquerda central",
|
||||
"center_right": "Direita central"
|
||||
}
|
||||
},
|
||||
"bar": {
|
||||
"position": {
|
||||
"top": "Topo",
|
||||
@@ -1232,6 +1292,10 @@
|
||||
"battery": {
|
||||
"low": "Bateria Fraca",
|
||||
"low-desc": "A bateria está em {percent}%. Por favor, conecte o carregador."
|
||||
},
|
||||
"missing-control-center": {
|
||||
"label": "Último widget da Central de Controle removido",
|
||||
"description": "O widget da Central de Controle foi removido da barra. Para acessá-lo novamente pela barra, adicione o widget novamente."
|
||||
}
|
||||
},
|
||||
"weather": {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"settingsVersion": 6,
|
||||
"settingsVersion": 8,
|
||||
"bar": {
|
||||
"position": "top",
|
||||
"backgroundOpacity": 1,
|
||||
@@ -132,8 +132,13 @@
|
||||
"respectExpireTimeout": false,
|
||||
"lowUrgencyDuration": 3,
|
||||
"normalUrgencyDuration": 8,
|
||||
"criticalUrgencyDuration": 15,
|
||||
"enableOSD": true
|
||||
"criticalUrgencyDuration": 15
|
||||
},
|
||||
"osd": {
|
||||
"enabled": true,
|
||||
"location": "top_right",
|
||||
"monitors": [],
|
||||
"autoHideMs": 2000
|
||||
},
|
||||
"audio": {
|
||||
"volumeStep": 5,
|
||||
|
||||
@@ -114,7 +114,7 @@ Singleton {
|
||||
JsonAdapter {
|
||||
id: adapter
|
||||
|
||||
property int settingsVersion: 6
|
||||
property int settingsVersion: 8
|
||||
|
||||
// bar
|
||||
property JsonObject bar: JsonObject {
|
||||
@@ -255,7 +255,14 @@ Singleton {
|
||||
property int lowUrgencyDuration: 3
|
||||
property int normalUrgencyDuration: 8
|
||||
property int criticalUrgencyDuration: 15
|
||||
property bool enableOSD: true
|
||||
}
|
||||
|
||||
// on-screen display
|
||||
property JsonObject osd: JsonObject {
|
||||
property bool enabled: true
|
||||
property string location: "top_right"
|
||||
property list<string> monitors: []
|
||||
property int autoHideMs: 2000
|
||||
}
|
||||
|
||||
// audio
|
||||
|
||||
@@ -112,6 +112,7 @@ Singleton {
|
||||
"settings-screen-recorder": "video",
|
||||
"settings-hooks": "link",
|
||||
"settings-notifications": "bell",
|
||||
"settings-osd": "picture-in-picture",
|
||||
"settings-about": "info-square-rounded",
|
||||
"bluetooth": "bluetooth",
|
||||
"bt-device-generic": "bluetooth",
|
||||
|
||||
+183
-63
@@ -7,7 +7,7 @@ import qs.Commons
|
||||
import qs.Services
|
||||
import qs.Widgets
|
||||
|
||||
// Unified OSD component - handles both volume and brightness with a single instance
|
||||
// Unified OSD component
|
||||
// Loader activates only when showing OSD, deactivates when hidden to save resources
|
||||
Variants {
|
||||
model: Quickshell.screens
|
||||
@@ -22,7 +22,7 @@ Variants {
|
||||
property ListModel notificationModel: NotificationService.activeList
|
||||
|
||||
// If no notification display activated in settings, then show them all
|
||||
property bool canShowOnThisScreen: Settings.isLoaded && modelData && (Settings.data.notifications.monitors.includes(modelData.name) || (Settings.data.notifications.monitors.length === 0))
|
||||
property bool canShowOnThisScreen: Settings.isLoaded && modelData && (Settings.data.osd.monitors.includes(modelData.name) || (Settings.data.osd.monitors.length === 0))
|
||||
|
||||
// Loader is only active when actually showing something
|
||||
active: false
|
||||
@@ -71,9 +71,13 @@ Variants {
|
||||
// Get display percentage
|
||||
function getDisplayPercentage() {
|
||||
if (currentOSDType === "volume") {
|
||||
return isMuted ? "0%" : Math.round(currentVolume * 100) + "%"
|
||||
if (isMuted)
|
||||
return "0%"
|
||||
const pct = Math.round(Math.min(1.0, currentVolume) * 100)
|
||||
return pct + "%"
|
||||
} else if (currentOSDType === "brightness") {
|
||||
return Math.round(currentBrightness * 100) + "%"
|
||||
const pct = Math.round(Math.min(1.0, currentBrightness) * 100)
|
||||
return pct + "%"
|
||||
}
|
||||
return ""
|
||||
}
|
||||
@@ -83,8 +87,6 @@ Variants {
|
||||
if (currentOSDType === "volume") {
|
||||
if (isMuted)
|
||||
return Color.mError
|
||||
if (currentVolume > 1.0)
|
||||
return Color.mError
|
||||
return Color.mPrimary
|
||||
}
|
||||
return Color.mPrimary
|
||||
@@ -99,14 +101,23 @@ Variants {
|
||||
}
|
||||
|
||||
sourceComponent: PanelWindow {
|
||||
id: panel
|
||||
screen: modelData
|
||||
|
||||
readonly property string location: (Settings.isLoaded && Settings.data && Settings.data.notifications && Settings.data.notifications.location) ? Settings.data.notifications.location : "top_right"
|
||||
readonly property string location: (Settings.isLoaded && Settings.data && Settings.data.osd && Settings.data.osd.location) ? Settings.data.osd.location : "top_right"
|
||||
readonly property bool isTop: (location === "top") || (location.length >= 3 && location.substring(0, 3) === "top")
|
||||
readonly property bool isBottom: (location === "bottom") || (location.length >= 6 && location.substring(0, 6) === "bottom")
|
||||
readonly property bool isLeft: location.indexOf("_left") >= 0
|
||||
readonly property bool isRight: location.indexOf("_right") >= 0
|
||||
readonly property bool isLeft: (location.indexOf("_left") >= 0) || (location === "left")
|
||||
readonly property bool isRight: (location.indexOf("_right") >= 0) || (location === "right")
|
||||
readonly property bool isCentered: (location === "top" || location === "bottom")
|
||||
readonly property bool verticalMode: (location === "left" || location === "right")
|
||||
readonly property int hWidth: Math.round(320 * root.scaling)
|
||||
readonly property int hHeight: Math.round(64 * root.scaling)
|
||||
// Ensure an even width to keep the vertical bar perfectly centered
|
||||
readonly property int barThickness: (function () {
|
||||
const base = Math.max(6, Math.round(6 * root.scaling))
|
||||
return (base % 2 === 0) ? base : base + 1
|
||||
})()
|
||||
|
||||
// Anchor selection based on location (window edges)
|
||||
anchors.top: isTop
|
||||
@@ -159,7 +170,7 @@ Variants {
|
||||
return base
|
||||
}
|
||||
|
||||
implicitWidth: 320 * root.scaling
|
||||
implicitWidth: verticalMode ? hHeight : hWidth
|
||||
implicitHeight: osdItem.height
|
||||
|
||||
color: Color.transparent
|
||||
@@ -171,16 +182,20 @@ Variants {
|
||||
id: osdItem
|
||||
|
||||
width: parent.width
|
||||
height: Math.round(contentLayout.implicitHeight + Style.marginL * 2 * root.scaling)
|
||||
height: panel.verticalMode ? panel.hWidth : Math.round(64 * root.scaling)
|
||||
radius: Style.radiusL * root.scaling
|
||||
color: Color.mSurface
|
||||
border.color: Color.mOutline
|
||||
border.width: Math.max(2, Style.borderM * root.scaling)
|
||||
border.width: (function () {
|
||||
const bw = Math.max(2, Math.round(Style.borderM * root.scaling))
|
||||
return (bw % 2 === 0) ? bw : bw + 1
|
||||
})()
|
||||
visible: false
|
||||
opacity: 0
|
||||
scale: 0.85
|
||||
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.horizontalCenter: verticalMode ? undefined : parent.horizontalCenter
|
||||
anchors.verticalCenter: verticalMode ? parent.verticalCenter : undefined
|
||||
|
||||
Behavior on opacity {
|
||||
NumberAnimation {
|
||||
@@ -200,7 +215,7 @@ Variants {
|
||||
|
||||
Timer {
|
||||
id: hideTimer
|
||||
interval: 2000
|
||||
interval: Settings.data.osd.autoHideMs
|
||||
onTriggered: osdItem.hide()
|
||||
}
|
||||
|
||||
@@ -216,52 +231,30 @@ Variants {
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
id: contentLayout
|
||||
Loader {
|
||||
id: contentLoader
|
||||
anchors.fill: parent
|
||||
anchors.margins: Style.marginM * root.scaling
|
||||
spacing: Style.marginM * root.scaling
|
||||
active: true
|
||||
sourceComponent: verticalMode ? verticalContent : horizontalContent
|
||||
}
|
||||
|
||||
NIcon {
|
||||
icon: root.getIcon()
|
||||
color: root.getIconColor()
|
||||
font.pointSize: Style.fontSizeXL * root.scaling
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
Component {
|
||||
id: horizontalContent
|
||||
Item {
|
||||
anchors.fill: parent
|
||||
|
||||
// Smooth icon transitions
|
||||
Behavior on color {
|
||||
ColorAnimation {
|
||||
duration: Style.animationNormal
|
||||
easing.type: Easing.InOutQuad
|
||||
}
|
||||
}
|
||||
}
|
||||
Row {
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.margins: Style.marginM * root.scaling
|
||||
spacing: Style.marginM * root.scaling
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
spacing: Style.marginXS * root.scaling
|
||||
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: Math.round(6 * root.scaling)
|
||||
radius: Math.round(3 * root.scaling)
|
||||
color: Color.mSurfaceVariant
|
||||
|
||||
Rectangle {
|
||||
anchors.left: parent.left
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
width: parent.width * Math.min(1.0, root.getCurrentValue())
|
||||
radius: parent.radius
|
||||
color: root.getProgressColor()
|
||||
|
||||
Behavior on width {
|
||||
NumberAnimation {
|
||||
duration: Style.animationNormal
|
||||
easing.type: Easing.InOutQuad
|
||||
}
|
||||
}
|
||||
NIcon {
|
||||
icon: root.getIcon()
|
||||
color: root.getIconColor()
|
||||
font.pointSize: Style.fontSizeXL * root.scaling
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
Behavior on color {
|
||||
ColorAnimation {
|
||||
@@ -270,14 +263,141 @@ Variants {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Progress bar with calculated width
|
||||
Rectangle {
|
||||
width: Math.round(220 * root.scaling)
|
||||
height: panel.barThickness
|
||||
radius: Math.round(panel.barThickness / 2)
|
||||
color: Color.mSurfaceVariant
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
Rectangle {
|
||||
anchors.left: parent.left
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
width: parent.width * Math.min(1.0, root.getCurrentValue())
|
||||
radius: parent.radius
|
||||
color: root.getProgressColor()
|
||||
|
||||
Behavior on width {
|
||||
NumberAnimation {
|
||||
duration: Style.animationNormal
|
||||
easing.type: Easing.InOutQuad
|
||||
}
|
||||
}
|
||||
Behavior on color {
|
||||
ColorAnimation {
|
||||
duration: Style.animationNormal
|
||||
easing.type: Easing.InOutQuad
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Percentage text
|
||||
NText {
|
||||
text: root.getDisplayPercentage()
|
||||
color: Color.mOnSurface
|
||||
font.pointSize: Style.fontSizeS * root.scaling
|
||||
font.family: Settings.data.ui.fontFixed
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
horizontalAlignment: Text.AlignLeft
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
width: Math.round(50 * root.scaling)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: verticalContent
|
||||
ColumnLayout {
|
||||
// Ensure inner padding respects the rounded corners; avoid clipping the icon/text
|
||||
property int vMargin: (function () {
|
||||
const styleMargin = Math.round(Style.marginL * root.scaling)
|
||||
const cornerGuard = Math.round(osdItem.radius)
|
||||
return Math.max(styleMargin, cornerGuard)
|
||||
})()
|
||||
property int vMarginTop: Math.max(Math.round(osdItem.radius), Math.round(Style.marginS * root.scaling))
|
||||
property int balanceDelta: Math.round(Style.marginS * root.scaling)
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.topMargin: vMarginTop
|
||||
anchors.bottomMargin: vMargin
|
||||
width: (function () {
|
||||
const w = parent.width - (vMargin * 2)
|
||||
return (w % 2 === 0) ? w : w - 1
|
||||
})()
|
||||
spacing: Math.round(Style.marginS * root.scaling)
|
||||
|
||||
// Percentage text at top
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: percentText.implicitHeight
|
||||
NText {
|
||||
id: percentText
|
||||
text: root.getDisplayPercentage()
|
||||
color: Color.mOnSurface
|
||||
font.pointSize: Style.fontSizeS * root.scaling
|
||||
font.family: Settings.data.ui.fontFixed
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
}
|
||||
|
||||
NText {
|
||||
text: root.getDisplayPercentage()
|
||||
color: Color.mOnSurface
|
||||
font.pointSize: Style.fontSizeS * root.scaling
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
Layout.minimumWidth: Math.round(32 * root.scaling)
|
||||
// Progress bar
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
Rectangle {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
width: panel.barThickness
|
||||
radius: Math.round(panel.barThickness / 2)
|
||||
color: Color.mSurfaceVariant
|
||||
|
||||
Rectangle {
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: parent.bottom
|
||||
height: parent.height * Math.min(1.0, root.getCurrentValue())
|
||||
radius: parent.radius
|
||||
color: root.getProgressColor()
|
||||
|
||||
Behavior on height {
|
||||
NumberAnimation {
|
||||
duration: Style.animationNormal
|
||||
easing.type: Easing.InOutQuad
|
||||
}
|
||||
}
|
||||
Behavior on color {
|
||||
ColorAnimation {
|
||||
duration: Style.animationNormal
|
||||
easing.type: Easing.InOutQuad
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Icon at bottom
|
||||
NIcon {
|
||||
icon: root.getIcon()
|
||||
color: root.getIconColor()
|
||||
font.pointSize: Style.fontSizeXL * root.scaling
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom
|
||||
Layout.bottomMargin: vMargin + Math.round(Style.marginM * root.scaling) + balanceDelta
|
||||
Behavior on color {
|
||||
ColorAnimation {
|
||||
duration: Style.animationNormal
|
||||
easing.type: Easing.InOutQuad
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -387,7 +507,7 @@ Variants {
|
||||
|
||||
function showOSD(type) {
|
||||
// Check if OSD is enabled in settings and can show on this screen
|
||||
if (!Settings.data.notifications.enableOSD || !canShowOnThisScreen) {
|
||||
if (!Settings.data.osd.enabled || !canShowOnThisScreen) {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ NPanel {
|
||||
Audio,
|
||||
Bar,
|
||||
ColorScheme,
|
||||
OSD,
|
||||
Display,
|
||||
Dock,
|
||||
General,
|
||||
@@ -70,6 +71,10 @@ NPanel {
|
||||
id: displayTab
|
||||
DisplayTab {}
|
||||
}
|
||||
Component {
|
||||
id: osdTab
|
||||
OsdTab {}
|
||||
}
|
||||
Component {
|
||||
id: networkTab
|
||||
NetworkTab {}
|
||||
@@ -139,6 +144,11 @@ NPanel {
|
||||
"label": "settings.display.title",
|
||||
"icon": "settings-display",
|
||||
"source": displayTab
|
||||
}, {
|
||||
"id": SettingsPanel.Tab.OSD,
|
||||
"label": "settings.osd.title",
|
||||
"icon": "settings-osd",
|
||||
"source": osdTab
|
||||
}, {
|
||||
"id": SettingsPanel.Tab.Notifications,
|
||||
"label": "settings.notifications.title",
|
||||
|
||||
@@ -72,12 +72,7 @@ ColumnLayout {
|
||||
onToggled: checked => Settings.data.notifications.alwaysOnTop = checked
|
||||
}
|
||||
|
||||
NToggle {
|
||||
label: I18n.tr("settings.notifications.settings.enable-osd.label")
|
||||
description: I18n.tr("settings.notifications.settings.enable-osd.description")
|
||||
checked: Settings.data.notifications.enableOSD
|
||||
onToggled: checked => Settings.data.notifications.enableOSD = checked
|
||||
}
|
||||
// OSD settings moved to the dedicated OSD tab
|
||||
}
|
||||
|
||||
NDivider {
|
||||
|
||||
@@ -0,0 +1,139 @@
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Controls
|
||||
import Quickshell
|
||||
import qs.Commons
|
||||
import qs.Services
|
||||
import qs.Widgets
|
||||
|
||||
ColumnLayout {
|
||||
id: root
|
||||
|
||||
// Helper functions to update arrays immutably
|
||||
function addMonitor(list, name) {
|
||||
const arr = (list || []).slice()
|
||||
if (!arr.includes(name))
|
||||
arr.push(name)
|
||||
return arr
|
||||
}
|
||||
function removeMonitor(list, name) {
|
||||
return (list || []).filter(function (n) {
|
||||
return n !== name
|
||||
})
|
||||
}
|
||||
|
||||
// Display
|
||||
ColumnLayout {
|
||||
spacing: Style.marginL * scaling
|
||||
Layout.fillWidth: true
|
||||
|
||||
NComboBox {
|
||||
label: I18n.tr("settings.osd.location.label")
|
||||
description: I18n.tr("settings.osd.location.description")
|
||||
model: [{
|
||||
"key": "top",
|
||||
"name": I18n.tr("options.osd.position.top_center")
|
||||
}, {
|
||||
"key": "top_left",
|
||||
"name": I18n.tr("options.osd.position.top_left")
|
||||
}, {
|
||||
"key": "top_right",
|
||||
"name": I18n.tr("options.osd.position.top_right")
|
||||
}, {
|
||||
"key": "bottom",
|
||||
"name": I18n.tr("options.osd.position.bottom_center")
|
||||
}, {
|
||||
"key": "bottom_left",
|
||||
"name": I18n.tr("options.osd.position.bottom_left")
|
||||
}, {
|
||||
"key": "bottom_right",
|
||||
"name": I18n.tr("options.osd.position.bottom_right")
|
||||
}, {
|
||||
"key": "left",
|
||||
"name": I18n.tr("options.osd.position.center_left")
|
||||
}, {
|
||||
"key": "right",
|
||||
"name": I18n.tr("options.osd.position.center_right")
|
||||
}]
|
||||
currentKey: Settings.data.osd.location || "top_right"
|
||||
onSelected: key => Settings.data.osd.location = key
|
||||
}
|
||||
}
|
||||
|
||||
NDivider {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: Style.marginXL * scaling
|
||||
Layout.bottomMargin: Style.marginXL * scaling
|
||||
}
|
||||
|
||||
// General
|
||||
ColumnLayout {
|
||||
spacing: Style.marginL * scaling
|
||||
Layout.fillWidth: true
|
||||
|
||||
NHeader {
|
||||
label: I18n.tr("settings.osd.section.general.label")
|
||||
description: I18n.tr("settings.osd.section.general.description")
|
||||
}
|
||||
|
||||
NToggle {
|
||||
label: I18n.tr("settings.osd.enabled.label")
|
||||
description: I18n.tr("settings.osd.enabled.description")
|
||||
checked: Settings.data.osd.enabled
|
||||
onToggled: checked => Settings.data.osd.enabled = checked
|
||||
}
|
||||
|
||||
NLabel {
|
||||
label: I18n.tr("settings.osd.duration.auto-hide.label")
|
||||
description: I18n.tr("settings.osd.duration.auto-hide.description")
|
||||
}
|
||||
|
||||
NValueSlider {
|
||||
Layout.fillWidth: true
|
||||
from: 500
|
||||
to: 5000
|
||||
stepSize: 100
|
||||
value: Settings.data.osd.autoHideMs
|
||||
onMoved: value => Settings.data.osd.autoHideMs = value
|
||||
text: Math.round(Settings.data.osd.autoHideMs / 1000 * 10) / 10 + "s"
|
||||
}
|
||||
}
|
||||
|
||||
NDivider {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: Style.marginXL * scaling
|
||||
Layout.bottomMargin: Style.marginXL * scaling
|
||||
}
|
||||
|
||||
// Monitor Configuration
|
||||
ColumnLayout {
|
||||
spacing: Style.marginL * scaling
|
||||
Layout.fillWidth: true
|
||||
|
||||
NHeader {
|
||||
label: I18n.tr("settings.osd.monitors.section.label")
|
||||
description: I18n.tr("settings.osd.monitors.section.description")
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: Quickshell.screens || []
|
||||
delegate: NCheckbox {
|
||||
Layout.fillWidth: true
|
||||
label: modelData.name || I18n.tr("system.unknown")
|
||||
description: I18n.tr("system.monitor-description", {
|
||||
"model": modelData.model,
|
||||
"width": modelData.width,
|
||||
"height": modelData.height
|
||||
})
|
||||
checked: (Settings.data.osd.monitors || []).indexOf(modelData.name) !== -1
|
||||
onToggled: checked => {
|
||||
if (checked) {
|
||||
Settings.data.osd.monitors = addMonitor(Settings.data.osd.monitors, modelData.name)
|
||||
} else {
|
||||
Settings.data.osd.monitors = removeMonitor(Settings.data.osd.monitors, modelData.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user