From 69428059e0d1035be94143cc34a145869d678c52 Mon Sep 17 00:00:00 2001 From: Soramane <61896496+soramanew@users.noreply.github.com> Date: Thu, 28 May 2026 17:08:15 +0800 Subject: [PATCH] feat: expressive lock clock --- modules/lock/Center.qml | 49 +++-------------------- modules/lock/Clock.qml | 86 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+), 43 deletions(-) create mode 100644 modules/lock/Clock.qml diff --git a/modules/lock/Center.qml b/modules/lock/Center.qml index 5d4b9fd8..d7f83052 100644 --- a/modules/lock/Center.qml +++ b/modules/lock/Center.qml @@ -22,58 +22,21 @@ ColumnLayout { spacing: Tokens.spacing.largeIncreased * 2 - RowLayout { + Clock { Layout.alignment: Qt.AlignHCenter - spacing: Tokens.spacing.small - - StyledText { - Layout.alignment: Qt.AlignVCenter - text: Time.hourStr - color: Colours.palette.m3secondary - font: Tokens.font.clock.size(Math.floor(28 * 3 * root.centerScale)).weight(Font.Bold).build() - } - - StyledText { - Layout.alignment: Qt.AlignVCenter - text: ":" - color: Colours.palette.m3primary - font: Tokens.font.clock.size(Math.floor(28 * 3 * root.centerScale)).weight(Font.Bold).build() - } - - StyledText { - Layout.alignment: Qt.AlignVCenter - text: Time.minuteStr - color: Colours.palette.m3secondary - font: Tokens.font.clock.size(Math.floor(28 * 3 * root.centerScale)).weight(Font.Bold).build() - } - - Loader { - asynchronous: true - Layout.leftMargin: Tokens.spacing.small - Layout.alignment: Qt.AlignVCenter - - active: GlobalConfig.services.useTwelveHourClock - visible: active - - sourceComponent: StyledText { - text: Time.amPmStr - color: Colours.palette.m3primary - font: Tokens.font.clock.size(Math.floor(28 * 2 * root.centerScale)).weight(Font.Bold).build() - } - } + centerScale: root.centerScale } StyledText { Layout.alignment: Qt.AlignHCenter - Layout.topMargin: -Tokens.padding.extraLargeIncreased + Layout.topMargin: -Tokens.padding.largeIncreased - text: Time.format("dddd, d MMMM yyyy") - color: Colours.palette.m3tertiary - font: Tokens.font.mono.builders.large.size(Math.floor(28 * root.centerScale)).weight(Font.Bold).build() + text: Time.format("dddd • d MMM").toUpperCase() + color: Colours.palette.m3onSurface + font: Tokens.font.title.builders.medium.weight(Font.DemiBold).build() } StyledClippingRect { - Layout.topMargin: Tokens.spacing.largeIncreased * 2 Layout.alignment: Qt.AlignHCenter implicitWidth: root.centerWidth / 2 diff --git a/modules/lock/Clock.qml b/modules/lock/Clock.qml new file mode 100644 index 00000000..3b520eb8 --- /dev/null +++ b/modules/lock/Clock.qml @@ -0,0 +1,86 @@ +import QtQuick +import Caelestia.Config +import qs.components +import qs.services + +Item { + id: root + + required property real centerScale + + function calcTopOff(metrics: TextMetrics): real { + return metrics.tightBoundingRect.y - metrics.boundingRect.y; + } + + implicitWidth: hours.implicitWidth + minutes.implicitWidth + Tokens.spacing.small + implicitHeight: hourMetrics.tightBoundingRect.height + + StyledText { + id: hours + + y: -root.calcTopOff(hourMetrics) + text: Time.hourStr + color: Colours.palette.m3primary + font: Tokens.font.headline.builders.large.scale(7 * root.centerScale).width(30).build() + + TextMetrics { + id: hourMetrics + + text: hours.text + font: hours.font + } + } + + StyledText { + id: minutes + + anchors.right: parent.right + y: -root.calcTopOff(minuteMetrics) + + text: Time.minuteStr + color: Colours.palette.m3secondary + font: Tokens.font.headline.builders.large.scale(3.8 * root.centerScale).width(30).build() + + TextMetrics { + id: minuteMetrics + + text: minutes.text + font: minutes.font + } + } + + StyledRect { + anchors.left: minutes.left + anchors.leftMargin: minuteMetrics.tightBoundingRect.x + y: hourMetrics.tightBoundingRect.height - implicitHeight + + color: Colours.tPalette.m3surfaceContainerHigh + radius: Tokens.rounding.large + + implicitWidth: minuteMetrics.tightBoundingRect.width + implicitHeight: amPmMetrics.tightBoundingRect.height + Tokens.padding.large * 2 + + StyledText { + id: amPm + + anchors.centerIn: parent + width: amPmMetrics.tightBoundingRect.width + height: amPmMetrics.tightBoundingRect.height + transform: Translate { + x: -amPmMetrics.tightBoundingRect.x + y: -root.calcTopOff(amPmMetrics) + } + + text: Time.amPmStr + color: Colours.palette.m3onSurface + font: Tokens.font.headline.builders.small.scale(2 * root.centerScale).width(30).build() + + TextMetrics { + id: amPmMetrics + + text: amPm.text + font: amPm.font + } + } + } +}