NClock: factorize NClockAnalog/Digital

i18n: rephrase analog clock translation
This commit is contained in:
Ly-sec
2025-11-03 18:32:46 +01:00
parent b9d198a879
commit 3c69d5b4da
9 changed files with 283 additions and 8 deletions
+1 -1
View File
@@ -693,7 +693,7 @@
"description": "Ereignisse im Kalender-Panel anzeigen."
},
"use-analog": {
"description": "Eine Analoguhr auf dem Kalenderbildschirm anzeigen.",
"description": "Eine Analoguhr im Kalenderfenster und auf dem Sperrbildschirm anzeigen.",
"label": "Analoge Uhr verwenden"
},
"first-day-of-week": {
+1 -1
View File
@@ -699,7 +699,7 @@
},
"use-analog": {
"label": "Use analog style clock",
"description": "Show an analog style clock on the calendar screen."
"description": "Show an analog style clock on the calendar window and lock screen."
}
}
},
+1 -1
View File
@@ -693,7 +693,7 @@
"description": "Mostrar eventos en el panel del calendario."
},
"use-analog": {
"description": "Mostrar un reloj de estilo analógico en la pantalla del calendario.",
"description": "Mostrar un reloj de estilo analógico en la ventana del calendario y en la pantalla de bloqueo.",
"label": "Usar reloj de estilo analógico"
},
"first-day-of-week": {
+1 -1
View File
@@ -693,7 +693,7 @@
"description": "Afficher les événements dans le panneau du calendrier."
},
"use-analog": {
"description": "Afficher une horloge de style analogique sur l'écran du calendrier.",
"description": "Afficher une horloge de style analogique dans la fenêtre du calendrier et sur l'écran de verrouillage.",
"label": "Utiliser une horloge de style analogique."
},
"first-day-of-week": {
+1 -1
View File
@@ -655,7 +655,7 @@
"description": "Exibir eventos no painel do calendário."
},
"use-analog": {
"description": "Mostrar um relógio estilo analógico na tela do calendário.",
"description": "Mostrar um relógio estilo analógico na janela do calendário e na tela de bloqueio.",
"label": "Use um relógio de estilo analógico."
},
"first-day-of-week": {
+1 -1
View File
@@ -693,7 +693,7 @@
"description": "在日历面板中显示事件。"
},
"use-analog": {
"description": "在日历屏幕上显示一个模拟时钟。",
"description": "在日历窗口和锁定屏幕上显示模拟时钟。",
"label": "使用模拟时钟样式"
},
"first-day-of-week": {
+2 -1
View File
@@ -201,11 +201,12 @@ NPanel {
}
// Analog clock
ClockLoader {
NClock {
id: clockLoader
anchors.right: parent.right
anchors.rightMargin: Style.marginXL
anchors.verticalCenter: parent.verticalCenter
clockStyle: Settings.data.location.analogClockInCalendar ? "analog" : "digital"
progressColor: Color.mOnPrimary
Layout.alignment: Qt.AlignVCenter
now: root.now
+2 -1
View File
@@ -365,8 +365,9 @@ Loader {
}
// Clock
ClockLoader {
NClock {
now: Time.date
clockStyle: Settings.data.location.analogClockInCalendar ? "analog" : "digital"
Layout.preferredWidth: 70
Layout.preferredHeight: 70
Layout.alignment: Qt.AlignVCenter
+273
View File
@@ -0,0 +1,273 @@
import QtQuick
import QtQuick.Layouts
import qs.Commons
import qs.Widgets
import qs.Services
import Quickshell
import "../Helpers/ColorsConvert.js" as ColorsConvert
Item {
id: root
property var now: Time.date
// Style: "analog" or "digital"
property string clockStyle: "analog"
// Color properties
property color backgroundColor: Color.mPrimary
property color clockColor: Color.mOnPrimary
property color secondHandColor: {
var defaultColor = Color.mError
var bestContrast = 1.0 // 1.0 is "no contrast"
var bestColor = defaultColor
var candidates = [Color.mSecondary, Color.mTertiary, Color.mError]
const minContrast = 1.149
for (var i = 0; i < candidates.length; i++) {
var candidate = candidates[i]
var contrastClock = ColorsConvert.getContrastRatio(candidate.toString(), clockColor.toString())
if (contrastClock < minContrast) {
continue
}
var contrastBg = ColorsConvert.getContrastRatio(candidate.toString(), backgroundColor.toString())
if (contrastBg < minContrast) {
continue
}
var currentWorstContrast = Math.min(contrastBg, contrastClock)
if (currentWorstContrast > bestContrast) {
bestContrast = currentWorstContrast
bestColor = candidate
}
}
return bestColor
}
property color progressColor: root.secondHandColor
height: Math.round((Style.fontSizeXXXL * 1.9) / 2 * Style.uiScaleRatio) * 2
width: root.height
Loader {
id: clockLoader
anchors.fill: parent
sourceComponent: root.clockStyle === "analog" ? analogClockComponent : digitalClockComponent
onLoaded: {
item.now = Qt.binding(function () {
return root.now
})
item.backgroundColor = Qt.binding(function () {
return root.backgroundColor
})
item.clockColor = Qt.binding(function () {
return root.clockColor
})
if (item.hasOwnProperty("secondHandColor")) {
item.secondHandColor = Qt.binding(function () {
return root.secondHandColor
})
}
if (item.hasOwnProperty("progressColor")) {
item.progressColor = Qt.binding(function () {
return root.progressColor
})
}
}
}
// Analog Clock Component
component NClockAnalog: Item {
property var now
property color backgroundColor: Color.mPrimary
property color clockColor: Color.mOnPrimary
property color secondHandColor: Color.mError
anchors.fill: parent
Canvas {
id: clockCanvas
anchors.fill: parent
property int hours: now.getHours()
property int minutes: now.getMinutes()
property int seconds: now.getSeconds()
onPaint: {
const markAlpha = 0.7
var ctx = getContext("2d")
ctx.reset()
ctx.translate(width / 2, height / 2)
var radius = Math.min(width, height) / 2
// Hour marks
ctx.strokeStyle = Qt.alpha(clockColor, markAlpha)
ctx.lineWidth = 2 * Style.uiScaleRatio
var scaleFactor = 0.7
for (var i = 0; i < 12; i++) {
var scaleFactor = 0.8
if (i % 3 === 0) {
scaleFactor = 0.65
}
ctx.save()
ctx.rotate(i * Math.PI / 6)
ctx.beginPath()
ctx.moveTo(0, -radius * scaleFactor)
ctx.lineTo(0, -radius)
ctx.stroke()
ctx.restore()
}
// Hour hand
ctx.save()
var hourAngle = (hours % 12 + minutes / 60) * Math.PI / 6
ctx.rotate(hourAngle)
ctx.strokeStyle = clockColor
ctx.lineWidth = 3 * Style.uiScaleRatio
ctx.lineCap = "round"
ctx.beginPath()
ctx.moveTo(0, 0)
ctx.lineTo(0, -radius * 0.6)
ctx.stroke()
ctx.restore()
// Minute hand
ctx.save()
var minuteAngle = (minutes + seconds / 60) * Math.PI / 30
ctx.rotate(minuteAngle)
ctx.strokeStyle = clockColor
ctx.lineWidth = 2 * Style.uiScaleRatio
ctx.lineCap = "round"
ctx.beginPath()
ctx.moveTo(0, 0)
ctx.lineTo(0, -radius * 0.9)
ctx.stroke()
ctx.restore()
// Second hand
ctx.save()
var secondAngle = seconds * Math.PI / 30
ctx.rotate(secondAngle)
ctx.strokeStyle = secondHandColor
ctx.lineWidth = 1.6 * Style.uiScaleRatio
ctx.lineCap = "round"
ctx.beginPath()
ctx.moveTo(0, 0)
ctx.lineTo(0, -radius)
ctx.stroke()
ctx.restore()
// Center dot
ctx.beginPath()
ctx.arc(0, 0, 3 * Style.uiScaleRatio, 0, 2 * Math.PI)
ctx.fillStyle = clockColor
ctx.fill()
}
Timer {
interval: 1000
running: true
repeat: true
onTriggered: {
clockCanvas.hours = now.getHours()
clockCanvas.minutes = now.getMinutes()
clockCanvas.seconds = now.getSeconds()
clockCanvas.requestPaint()
}
}
Component.onCompleted: requestPaint()
}
}
// Digital Clock Component
component NClockDigital: Item {
property var now
property color backgroundColor: Color.mPrimary
property color clockColor: Color.mOnPrimary
property color progressColor: Color.mError
anchors.fill: parent
// Digital clock's seconds circular progress
Canvas {
id: secondsProgress
anchors.fill: parent
property real progress: now.getSeconds() / 60
onProgressChanged: requestPaint()
Connections {
target: Time
function onDateChanged() {
const total = now.getSeconds() * 1000 + now.getMilliseconds()
secondsProgress.progress = total / 60000
}
}
onPaint: {
var ctx = getContext("2d")
var centerX = width / 2
var centerY = height / 2
var radius = Math.min(width, height) / 2 - 3
ctx.reset()
// Background circle
ctx.beginPath()
ctx.arc(centerX, centerY, radius, 0, 2 * Math.PI)
ctx.lineWidth = 2.5
ctx.strokeStyle = Qt.alpha(clockColor, 0.15)
ctx.stroke()
// Progress arc
ctx.beginPath()
ctx.arc(centerX, centerY, radius, -Math.PI / 2, -Math.PI / 2 + progress * 2 * Math.PI)
ctx.lineWidth = 2.5
ctx.strokeStyle = progressColor
ctx.lineCap = "round"
ctx.stroke()
}
}
// Digital clock
ColumnLayout {
anchors.centerIn: parent
spacing: -Style.marginXXS
NText {
text: {
var t = Settings.data.location.use12hourFormat ? I18n.locale.toString(now, "hh AP") : I18n.locale.toString(now, "HH")
return t.split(" ")[0]
}
pointSize: Style.fontSizeXS
font.weight: Style.fontWeightBold
color: clockColor
family: Settings.data.ui.fontFixed
Layout.alignment: Qt.AlignHCenter
}
NText {
text: Qt.formatTime(now, "mm")
pointSize: Style.fontSizeXXS
font.weight: Style.fontWeightBold
color: clockColor
family: Settings.data.ui.fontFixed
Layout.alignment: Qt.AlignHCenter
}
}
}
Component {
id: analogClockComponent
NClockAnalog {}
}
Component {
id: digitalClockComponent
NClockDigital {}
}
}