6 Commits
v0.1.0 ... main

Author SHA1 Message Date
Julian Freeman
04937933f5 adjust size 2026-03-02 13:00:53 -04:00
Julian Freeman
31cd7df52f adjust legs length 2026-03-02 12:40:07 -04:00
Julian Freeman
e4a636a115 fix resize 2026-03-02 12:35:50 -04:00
Julian Freeman
df5752d013 little fix 2026-03-01 20:43:46 -04:00
Julian Freeman
05a57dc4c8 add dark mode 2026-03-01 20:36:54 -04:00
Julian Freeman
8550420711 change color 2026-03-01 14:34:33 -04:00
3 changed files with 81 additions and 33 deletions

2
Cargo.lock generated
View File

@@ -2752,7 +2752,7 @@ dependencies = [
[[package]] [[package]]
name = "my-clock" name = "my-clock"
version = "0.1.0" version = "0.1.3"
dependencies = [ dependencies = [
"chrono", "chrono",
"embed-resource", "embed-resource",

View File

@@ -1,6 +1,6 @@
[package] [package]
name = "my-clock" name = "my-clock"
version = "0.1.0" version = "0.1.3"
edition = "2021" edition = "2021"
[dependencies] [dependencies]

View File

@@ -3,7 +3,7 @@ use chrono::{Local, Timelike};
slint::slint! { slint::slint! {
export component AppWindow inherits Window { export component AppWindow inherits Window {
title: "Modern Clock"; title: "时钟";
icon: @image-url("../assets/icon.png"); icon: @image-url("../assets/icon.png");
no-frame: true; no-frame: true;
background: transparent; background: transparent;
@@ -15,7 +15,8 @@ slint::slint! {
in-out property <float> minute: 0.0; in-out property <float> minute: 0.0;
in-out property <float> second: 0.0; in-out property <float> second: 0.0;
in-out property <bool> is_on_top: true; in-out property <bool> is_on_top: true;
in-out property <float> dial_opacity: 0.85; in-out property <bool> is_dark_mode: false;
in-out property <float> dial_opacity: 0.92;
in-out property <length> clock_size: 300px; in-out property <length> clock_size: 300px;
property <length> mouse_start_x; property <length> mouse_start_x;
@@ -29,7 +30,7 @@ slint::slint! {
x: touch_area.mouse-x; x: touch_area.mouse-x;
y: touch_area.mouse-y; y: touch_area.mouse-y;
width: 160px; width: 160px;
height: 200px; height: 240px;
Rectangle { Rectangle {
background: #1e1e1e; background: #1e1e1e;
@@ -52,6 +53,14 @@ slint::slint! {
t1 := TouchArea { clicked => { root.toggle_always_on_top(); menu_popup.close(); } } t1 := TouchArea { clicked => { root.toggle_always_on_top(); menu_popup.close(); } }
} }
Rectangle {
height: 30px;
background: t_theme.has-hover ? #333 : transparent;
border-radius: 4px;
Text { text: root.is_dark_mode ? "亮色主题" : "暗色主题"; color: #ddd; font-size: 14px; }
t_theme := TouchArea { clicked => { root.is_dark_mode = !root.is_dark_mode; menu_popup.close(); } }
}
Rectangle { Rectangle {
height: 30px; height: 30px;
background: t2.has-hover ? #333 : transparent; background: t2.has-hover ? #333 : transparent;
@@ -98,20 +107,54 @@ slint::slint! {
Rectangle { Rectangle {
width: 100%; height: 100%; width: 100%; height: 100%;
background: rgba(25, 25, 25, root.dial_opacity);
border-radius: self.width / 2; // 背景渐变层
border-width: 1.5px; Rectangle {
border-color: rgba(255, 255, 255, 0.15); width: 100%; height: 100%;
background: root.is_dark_mode ?
@radial-gradient(circle, #3a5dbd 0%, #1a2a6c 70%, #000055 100%) :
@radial-gradient(circle, #fff9a0 0%, #ffcc33 100%);
opacity: root.dial_opacity;
border-radius: self.width / 2;
}
for i in 12 : Path { // 装饰性内环和外边框
Rectangle {
width: 100%; height: 100%;
border-radius: self.width / 2;
border-width: root.clock_size * 0.008;
border-color: root.is_dark_mode ? rgba(100, 150, 255, 0.3) : rgba(255, 255, 255, 0.4);
Rectangle {
width: 97%; height: 97%;
border-radius: self.width / 2;
border-width: root.clock_size * 0.004;
border-color: root.is_dark_mode ? rgba(100, 150, 255, 0.15) : rgba(255, 255, 255, 0.2);
}
}
// 强化全局高光层
Rectangle {
width: 100%; height: 100%;
border-radius: self.width / 2;
background: root.is_dark_mode ?
@radial-gradient(circle, rgba(100, 150, 255, 0.1) 0%, transparent 80%) :
@radial-gradient(circle, rgba(255, 255, 255, 0.15) 0%, transparent 80%);
}
for i in 60 : Path {
viewbox-width: 100; viewbox-height: 100; viewbox-width: 100; viewbox-height: 100;
width: 100%; height: 100%; width: 100%; height: 100%;
stroke: rgba(255, 255, 255, 0.4); property <bool> is_hour: (Math.mod(i, 5) == 0);
stroke-width: 2px; stroke: root.is_dark_mode ?
property <float> angle: i * 30; (is_hour ? rgba(200, 220, 255, 0.5) : rgba(200, 220, 255, 0.25)) :
(is_hour ? rgba(0, 0, 0, 0.5) : rgba(0, 0, 0, 0.25));
stroke-width: is_hour ? root.clock_size * 0.007 : root.clock_size * 0.0035;
property <float> angle: i * 6;
property <float> start_r: is_hour ? 43 : 45;
MoveTo { MoveTo {
x: 50 + Math.sin(parent.angle * 1deg) * 42; x: 50 + Math.sin(parent.angle * 1deg) * parent.start_r;
y: 50 - Math.cos(parent.angle * 1deg) * 42; y: 50 - Math.cos(parent.angle * 1deg) * parent.start_r;
} }
LineTo { LineTo {
x: 50 + Math.sin(parent.angle * 1deg) * 47; x: 50 + Math.sin(parent.angle * 1deg) * 47;
@@ -119,33 +162,38 @@ slint::slint! {
} }
} }
for entry in [ {t: "12", a: 0}, {t: "3", a: 90}, {t: "6", a: 180}, {t: "9", a: 270} ] : Text { for entry in [
{t: "12", a: 0}, {t: "1", a: 30}, {t: "2", a: 60}, {t: "3", a: 90},
{t: "4", a: 120}, {t: "5", a: 150}, {t: "6", a: 180}, {t: "7", a: 210},
{t: "8", a: 240}, {t: "9", a: 270}, {t: "10", a: 300}, {t: "11", a: 330}
] : Text {
property <float> rad: entry.a * 3.14159 / 180; property <float> rad: entry.a * 3.14159 / 180;
property <length> r: parent.width / 2 - 35px; property <length> r: parent.width * 0.39;
x: parent.width / 2 + Math.sin(rad * 1rad) * r - self.width / 2; x: parent.width / 2 + Math.sin(rad * 1rad) * r - self.width / 2;
y: parent.height / 2 - Math.cos(rad * 1rad) * r - self.height / 2; y: parent.height / 2 - Math.cos(rad * 1rad) * r - self.height / 2;
text: entry.t; text: entry.t;
color: rgba(255, 255, 255, 0.25); color: root.is_dark_mode ? rgba(255, 255, 255, 0.8) : rgba(0, 0, 0, 0.7);
font-size: 16px; font-size: parent.width * 0.05;
font-weight: 500;
} }
Path { Path {
viewbox-width: 100; viewbox-height: 100; viewbox-width: 100; viewbox-height: 100;
width: 100%; height: 100%; width: 100%; height: 100%;
stroke: #ffffff; stroke: root.is_dark_mode ? #e0e0e0 : #1a1a1a;
stroke-width: 4px; stroke-width: root.clock_size * 0.017;
MoveTo { x: 50; y: 50; } MoveTo { x: 50; y: 50; }
LineTo { LineTo {
x: 50 + Math.sin(root.hour * 1deg) * 25; x: 50 + Math.sin(root.hour * 1deg) * 23;
y: 50 - Math.cos(root.hour * 1deg) * 25; y: 50 - Math.cos(root.hour * 1deg) * 23;
} }
} }
Path { Path {
viewbox-width: 100; viewbox-height: 100; viewbox-width: 100; viewbox-height: 100;
width: 100%; height: 100%; width: 100%; height: 100%;
stroke: #bbbbbb; stroke: root.is_dark_mode ? #bdbdbd : #333333;
stroke-width: 3px; stroke-width: root.clock_size * 0.012;
MoveTo { x: 50; y: 50; } MoveTo { x: 50; y: 50; }
LineTo { LineTo {
x: 50 + Math.sin(root.minute * 1deg) * 35; x: 50 + Math.sin(root.minute * 1deg) * 35;
@@ -157,22 +205,22 @@ slint::slint! {
viewbox-width: 100; viewbox-height: 100; viewbox-width: 100; viewbox-height: 100;
width: 100%; height: 100%; width: 100%; height: 100%;
stroke: #ff3b30; stroke: #ff3b30;
stroke-width: 1.5px; stroke-width: root.clock_size * 0.005;
MoveTo { x: 50; y: 50; } MoveTo { x: 50; y: 50; }
LineTo { LineTo {
x: 50 + Math.sin(root.second * 1deg) * 42; x: 50 + Math.sin(root.second * 1deg) * 44;
y: 50 - Math.cos(root.second * 1deg) * 42; y: 50 - Math.cos(root.second * 1deg) * 44;
} }
} }
Rectangle { Rectangle {
x: (parent.width - self.width) / 2; x: (parent.width - self.width) / 2;
y: (parent.height - self.height) / 2; y: (parent.height - self.height) / 2;
width: 8px; height: 8px; width: root.clock_size * 0.03; height: self.width;
background: #222; background: root.is_dark_mode ? #e0e0e0 : #1a1a1a;
border-radius: 4px; border-radius: self.width / 2;
border-width: 2px; border-width: self.width * 0.2;
border-color: white; border-color: root.is_dark_mode ? #1a2a6c : #ffcc33;
} }
} }
} }