mirror of
https://github.com/zoriya/noctalia-shell.git
synced 2026-05-29 09:02:12 +00:00
Split clocks out into multiple files
This commit is contained in:
@@ -0,0 +1,135 @@
|
||||
import QtQuick
|
||||
import qs.Commons
|
||||
import Quickshell
|
||||
|
||||
|
||||
Item {
|
||||
property var now
|
||||
anchors.fill: parent
|
||||
|
||||
Canvas {
|
||||
id: clockCanvas
|
||||
anchors.fill: parent
|
||||
|
||||
property int hours: now.getHours()
|
||||
property int minutes: now.getMinutes()
|
||||
property int seconds: now.getSeconds()
|
||||
property real markAlpha: 0.7
|
||||
property color secondHandColor: {
|
||||
var defaultColor = Color.mError
|
||||
var backgroundL = Color.mPrimary.hslLightness
|
||||
var hourMarkL = (Color.mOnPrimary.hslLightness * markAlpha) + (backgroundL *(1.0-markAlpha))
|
||||
|
||||
var bestWorstContrast = -1
|
||||
var bestColor = defaultColor
|
||||
|
||||
var candidates = [
|
||||
Color.mSecondary,
|
||||
Color.mTertiary,
|
||||
Color.mError,
|
||||
]
|
||||
|
||||
for (var i = 0; i < candidates.length; i++) {
|
||||
var candidateColor = candidates[i]
|
||||
var candidateL = candidateColor.hslLightness
|
||||
|
||||
var diffBackground = Math.abs(backgroundL - candidateL)
|
||||
var diffHourMark = Math.abs(hourMarkL - candidateL)
|
||||
|
||||
var currentWorstContrast = Math.min(diffBackground, diffHourMark)
|
||||
|
||||
if (currentWorstContrast > bestWorstContrast) {
|
||||
bestWorstContrast = currentWorstContrast
|
||||
bestColor = candidateColor
|
||||
}
|
||||
}
|
||||
|
||||
return bestColor
|
||||
}
|
||||
|
||||
onPaint: {
|
||||
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(Color.mOnPrimary, 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 = Color.mOnPrimary
|
||||
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 = Color.mOnPrimary
|
||||
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 = Color.mOnPrimary
|
||||
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()
|
||||
}
|
||||
}
|
||||
@@ -215,204 +215,13 @@ NPanel {
|
||||
}
|
||||
|
||||
// Analog clock
|
||||
Item {
|
||||
id: clockItem
|
||||
ClockLoader {
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: Style.marginM
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
height: Math.round((Style.fontSizeXXXL * 1.9) / 2 * Style.uiScaleRatio) * 2
|
||||
width: clockItem.height
|
||||
|
||||
Canvas {
|
||||
id: clockCanvas
|
||||
visible: Settings.data.location.analogClockInCalendar
|
||||
anchors.fill: parent
|
||||
|
||||
property int hours: now.getHours()
|
||||
property int minutes: now.getMinutes()
|
||||
property int seconds: now.getSeconds()
|
||||
property real markAlpha: 0.7
|
||||
property color secondHandColor: {
|
||||
var defaultColor = Color.mError
|
||||
var backgroundL = Color.mPrimary.hslLightness
|
||||
var hourMarkL = (Color.mOnPrimary.hslLightness * markAlpha) + (backgroundL * (1.0 - markAlpha))
|
||||
|
||||
var bestWorstContrast = -1
|
||||
var bestColor = defaultColor
|
||||
|
||||
var candidates = [Color.mSecondary, Color.mTertiary, Color.mError]
|
||||
|
||||
for (var i = 0; i < candidates.length; i++) {
|
||||
var candidateColor = candidates[i]
|
||||
var candidateL = candidateColor.hslLightness
|
||||
|
||||
var diffBackground = Math.abs(backgroundL - candidateL)
|
||||
var diffHourMark = Math.abs(hourMarkL - candidateL)
|
||||
|
||||
var currentWorstContrast = Math.min(diffBackground, diffHourMark)
|
||||
|
||||
if (currentWorstContrast > bestWorstContrast) {
|
||||
bestWorstContrast = currentWorstContrast
|
||||
bestColor = candidateColor
|
||||
}
|
||||
}
|
||||
|
||||
return bestColor
|
||||
}
|
||||
|
||||
onPaint: {
|
||||
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(Color.mOnPrimary, 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 = Color.mOnPrimary
|
||||
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 = Color.mOnPrimary
|
||||
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 = Color.mOnPrimary
|
||||
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's seconds circular progress
|
||||
Canvas {
|
||||
id: secondsProgress
|
||||
visible: !Settings.data.location.analogClockInCalendar
|
||||
anchors.fill: parent
|
||||
property real progress: now.getSeconds() / 60
|
||||
onProgressChanged: requestPaint()
|
||||
Connections {
|
||||
target: Time
|
||||
function onDateChanged() {
|
||||
const total = now.getSeconds() * 1000 + now.getMilliseconds()
|
||||
secondsProgress.progress = total / 60000
|
||||
}
|
||||
}
|
||||
onPaint: {
|
||||
var ctx = getContext("2d")
|
||||
var centerX = width / 2
|
||||
var centerY = height / 2
|
||||
var radius = Math.min(width, height) / 2 - 3
|
||||
ctx.reset()
|
||||
|
||||
// Background circle
|
||||
ctx.beginPath()
|
||||
ctx.arc(centerX, centerY, radius, 0, 2 * Math.PI)
|
||||
ctx.lineWidth = 2.5
|
||||
ctx.strokeStyle = Qt.alpha(Color.mOnPrimary, 0.15)
|
||||
ctx.stroke()
|
||||
|
||||
// Progress arc
|
||||
ctx.beginPath()
|
||||
ctx.arc(centerX, centerY, radius, -Math.PI / 2, -Math.PI / 2 + progress * 2 * Math.PI)
|
||||
ctx.lineWidth = 2.5
|
||||
ctx.strokeStyle = Color.mOnPrimary
|
||||
ctx.lineCap = "round"
|
||||
ctx.stroke()
|
||||
}
|
||||
}
|
||||
|
||||
// Digital clock
|
||||
ColumnLayout {
|
||||
visible: !Settings.data.location.analogClockInCalendar
|
||||
anchors.centerIn: parent
|
||||
spacing: -Style.marginXXS
|
||||
|
||||
NText {
|
||||
text: {
|
||||
var t = Settings.data.location.use12hourFormat ? Qt.locale().toString(now, "hh AP") : Qt.locale().toString(now, "HH")
|
||||
return t.split(" ")[0]
|
||||
}
|
||||
|
||||
pointSize: Style.fontSizeXS
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Color.mOnPrimary
|
||||
family: Settings.data.ui.fontFixed
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
|
||||
NText {
|
||||
text: Qt.formatTime(now, "mm")
|
||||
pointSize: Style.fontSizeXXS
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Color.mOnPrimary
|
||||
family: Settings.data.ui.fontFixed
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
}
|
||||
now: root.now
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
import QtQuick
|
||||
import qs.Commons
|
||||
import qs.Services
|
||||
import Quickshell
|
||||
|
||||
Item {
|
||||
id: clockRoot
|
||||
|
||||
property var now
|
||||
|
||||
height: Math.round((Style.fontSizeXXXL * 1.9) / 2 * Style.uiScaleRatio) * 2
|
||||
width: clockRoot.height
|
||||
|
||||
Loader {
|
||||
id: clockLoader
|
||||
anchors.fill: parent
|
||||
|
||||
source: Settings.data.location.analogClockInCalendar ? "AnalogClock.qml" : "DigitalClock.qml"
|
||||
|
||||
onLoaded: {
|
||||
// Bind the loaded item's 'now' property to *this* component's 'now' property
|
||||
item.now = Qt.binding(function() { return clockRoot.now })
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
import QtQuick
|
||||
import qs.Commons
|
||||
import Quickshell
|
||||
|
||||
|
||||
Item {
|
||||
property var now
|
||||
anchors.fill: parent
|
||||
|
||||
// Digital clock's seconds circular progress
|
||||
Canvas {
|
||||
id: secondsProgress
|
||||
visible: !Settings.data.location.analogClockInCalendar
|
||||
anchors.fill: parent
|
||||
property real progress: now.getSeconds() / 60
|
||||
onProgressChanged: requestPaint()
|
||||
Connections {
|
||||
target: Time
|
||||
function onDateChanged() {
|
||||
const total = now.getSeconds() * 1000 + now.getMilliseconds()
|
||||
secondsProgress.progress = total / 60000
|
||||
}
|
||||
}
|
||||
onPaint: {
|
||||
var ctx = getContext("2d")
|
||||
var centerX = width / 2
|
||||
var centerY = height / 2
|
||||
var radius = Math.min(width, height) / 2 - 3
|
||||
ctx.reset()
|
||||
|
||||
// Background circle
|
||||
ctx.beginPath()
|
||||
ctx.arc(centerX, centerY, radius, 0, 2 * Math.PI)
|
||||
ctx.lineWidth = 2.5
|
||||
ctx.strokeStyle = Qt.alpha(Color.mOnPrimary, 0.15)
|
||||
ctx.stroke()
|
||||
|
||||
// Progress arc
|
||||
ctx.beginPath()
|
||||
ctx.arc(centerX, centerY, radius, -Math.PI / 2, -Math.PI / 2 + progress * 2 * Math.PI)
|
||||
ctx.lineWidth = 2.5
|
||||
ctx.strokeStyle = Color.mOnPrimary
|
||||
ctx.lineCap = "round"
|
||||
ctx.stroke()
|
||||
}
|
||||
}
|
||||
|
||||
// Digital clock
|
||||
ColumnLayout {
|
||||
visible: !Settings.data.location.analogClockInCalendar
|
||||
anchors.centerIn: parent
|
||||
spacing: -Style.marginXXS
|
||||
|
||||
NText {
|
||||
text: {
|
||||
var t = Settings.data.location.use12hourFormat ? Qt.locale().toString(now, "hh AP") : Qt.locale().toString(now, "HH")
|
||||
return t.split(" ")[0]
|
||||
}
|
||||
|
||||
pointSize: Style.fontSizeXS
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Color.mOnPrimary
|
||||
family: Settings.data.ui.fontFixed
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
|
||||
NText {
|
||||
text: Qt.formatTime(now, "mm")
|
||||
pointSize: Style.fontSizeXXS
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Color.mOnPrimary
|
||||
family: Settings.data.ui.fontFixed
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user