Skip to content

Commit 33b791c

Browse files
committed
countdown
1 parent 1021df4 commit 33b791c

File tree

4 files changed

+138
-44
lines changed

4 files changed

+138
-44
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ members = [
1717
name = "rust_clock"
1818
authors = ["Hoothin <[email protected]>"]
1919
license = "MIT"
20-
version = "0.1.0"
20+
version = "0.1.1"
2121
edition = "2021"
2222
description = "Clock popup every half hour"
2323
build = "build.rs"

conf.ini

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
[Config]
22
time=:30:,:00:
3-
#sound=sound.ogg
3+
#sound=sound.ogg
4+
countdown=::30,::10

src/main.rs

Lines changed: 134 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,13 @@ use rodio::{Decoder, OutputStream, Sink};
1616
fn main() -> Result<(), eframe::Error> {
1717
let result = fs::read_to_string("conf.ini");
1818
if let Err(_) = result {
19-
fs::write("conf.ini", "[Config]\ntime=:30:,:00:\n#sound=assets/sound.ogg").unwrap()
19+
fs::write("conf.ini", "[Config]\ntime=:30:,:00:\n#sound=assets/sound.ogg\n#countdown=:20:,::20").unwrap()
2020
}
2121

2222
let i = Ini::load_from_file("conf.ini").unwrap();
2323
let mut time_str = "".to_string();
2424
let mut sound_path = "".to_string();
25+
let mut countdown = "".to_string();
2526
for (sec, prop) in i.iter() {
2627
if let Some(s) = sec {
2728
if s == "Config" {
@@ -30,6 +31,8 @@ fn main() -> Result<(), eframe::Error> {
3031
time_str = v.to_string();
3132
} else if k == "sound" {
3233
sound_path = v.to_string();
34+
} else if k == "countdown" {
35+
countdown = v.to_string();
3336
}
3437
}
3538
}
@@ -40,6 +43,7 @@ fn main() -> Result<(), eframe::Error> {
4043

4144
let tray_menu = Menu::new();
4245
let quit_i = MenuItem::new("Quit", true, None);
46+
let countdown_i = MenuItem::new("Countdown", true, None);
4347
tray_menu.append_items(&[
4448
&PredefinedMenuItem::about(
4549
None,
@@ -50,6 +54,8 @@ fn main() -> Result<(), eframe::Error> {
5054
}),
5155
),
5256
&PredefinedMenuItem::separator(),
57+
&countdown_i,
58+
&PredefinedMenuItem::separator(),
5359
&quit_i,
5460
]);
5561

@@ -76,18 +82,20 @@ fn main() -> Result<(), eframe::Error> {
7682
"Rust clock", // unused title
7783
options,
7884
Box::new(move |_cc| Box::new(MyApp{
79-
quit: quit_i.id(),
85+
quit_index: quit_i.id(),
8086
visible: true,
8187
time2show: time_str,
8288
sound_path: sound_path,
89+
countdown: countdown,
90+
countdown_index: countdown_i.id(),
8391
..MyApp::default()
8492
})),
8593
)
8694
}
8795

8896
#[derive(Default)]
8997
struct MyApp {
90-
quit: u32,
98+
quit_index: u32,
9199
time: f32,
92100
time2show: String,
93101
tikpop: bool,
@@ -96,7 +104,11 @@ struct MyApp {
96104
last_pos_y: f32,
97105
last_visible: bool,
98106
sound_path: String,
99-
inited: bool
107+
countdown: String,
108+
countdown_index: u32,
109+
inited: bool,
110+
countdown_start: bool,
111+
countdown_start_time: i64
100112
}
101113

102114
impl eframe::App for MyApp {
@@ -121,7 +133,89 @@ impl eframe::App for MyApp {
121133
.insert(0, "my_font".to_owned());
122134
ctx.set_fonts(fonts);
123135
}
124-
clock_window_frame(ctx, frame, self);
136+
let mut begin_tik = || {
137+
self.last_visible = self.visible;
138+
if let Some(pos) = frame.get_window_pos() {
139+
self.last_pos_x = pos.x;
140+
self.last_pos_y = pos.y;
141+
}
142+
self.visible = true;
143+
frame.set_visible(true);
144+
self.time = 0.0;
145+
frame.set_window_pos(Pos2::new(init_x, init_y));
146+
if self.sound_path != "" {
147+
let result = fs::File::open(&self.sound_path);
148+
if let Ok(file) = result {
149+
let file = BufReader::new(file);
150+
std::thread::spawn(move || {
151+
let (_stream, stream_handle) = OutputStream::try_default().unwrap();
152+
let source = Decoder::new(file).unwrap();
153+
let sink = Sink::try_new(&stream_handle).unwrap();
154+
sink.append(source);
155+
sink.sleep_until_end();
156+
});
157+
}
158+
}
159+
ctx.request_repaint_after(std::time::Duration::from_millis(16));
160+
};
161+
let mut custom_clock = "".to_string();
162+
if self.countdown_start == true {
163+
let mut over_time = (Local::now().timestamp() - self.countdown_start_time) as i32;
164+
if self.countdown == "" {
165+
if over_time > 600 {
166+
self.countdown_start_time = Local::now().timestamp();
167+
if self.tikpop == false {
168+
begin_tik();
169+
self.tikpop = true;
170+
}
171+
}
172+
let left_time = 600.0 - over_time as f32;
173+
let minute = (left_time / 60.0) as u32;
174+
let second = (left_time % 60.0) as u32;
175+
custom_clock = format!("00:{:02}:{:02}", minute, second);
176+
} else {
177+
let countdown_arr: Vec<&str> = self.countdown.split(',').collect();
178+
let mut total_time:i32 = 0;
179+
for x in &countdown_arr {
180+
let single_time: Vec<&str> = x.split(':').collect();
181+
let mut cur_time:i32 = 0;
182+
if single_time[0] != "" {
183+
cur_time = cur_time + single_time[0].to_string().parse::<i32>().unwrap() * 3600;
184+
}
185+
if single_time[1] != "" {
186+
cur_time = cur_time + single_time[1].to_string().parse::<i32>().unwrap() * 60;
187+
}
188+
if single_time[2] != "" {
189+
cur_time = cur_time + single_time[2].to_string().parse::<i32>().unwrap();
190+
}
191+
total_time = total_time + cur_time;
192+
if self.tikpop == false && over_time == total_time.into() {
193+
begin_tik();
194+
self.tikpop = true;
195+
} else if over_time < total_time {
196+
let left_time = (total_time - over_time) as f32;
197+
let hour = (left_time / 60.0 / 60.0) as u32;
198+
let minute = (left_time / 60.0) as u32;
199+
let second = (left_time % 60.0) as u32;
200+
custom_clock = format!("{:02}:{:02}:{:02}", hour, minute, second);
201+
break;
202+
}
203+
}
204+
if custom_clock == "" {
205+
over_time = 0;
206+
self.countdown_start_time = Local::now().timestamp();
207+
let left_time = (total_time - over_time) as f32;
208+
let hour = (left_time / 60.0 / 60.0) as u32;
209+
let minute = (left_time / 60.0) as u32;
210+
let second = (left_time % 60.0) as u32;
211+
custom_clock = format!("{:02}:{:02}:{:02}", hour, minute, second);
212+
if self.tikpop == false {
213+
begin_tik();
214+
self.tikpop = true;
215+
}
216+
}
217+
}
218+
}
125219
if self.tikpop == true {
126220
self.time += 2.0;
127221
frame.set_mouse_passthrough(false);
@@ -153,38 +247,19 @@ impl eframe::App for MyApp {
153247
let time2show_arr: Vec<&str> = self.time2show.split(',').collect();
154248
for x in &time2show_arr {
155249
let single_time: Vec<&str> = x.split(':').collect();
156-
if (single_time[0] == "" || single_time[0] == hour) &&
157-
(single_time[1] == "" || single_time[1] == minute) &&
158-
((single_time[2] == "" && second == "0") || single_time[2] == second) {
159-
self.last_visible = self.visible;
160-
if let Some(pos) = frame.get_window_pos() {
161-
self.last_pos_x = pos.x;
162-
self.last_pos_y = pos.y;
250+
if (single_time[0] == "" || single_time[0] == hour || single_time[0] == "0".to_string() + &hour) &&
251+
(single_time[1] == "" || single_time[1] == minute || single_time[1] == "0".to_string() + &minute) &&
252+
((single_time[2] == "" && (second == "0" || second == "00")) || single_time[2] == second) {
253+
if self.tikpop == false {
254+
begin_tik();
255+
self.tikpop = true;
163256
}
164-
self.visible = true;
165-
self.tikpop = true;
166-
frame.set_visible(true);
167-
self.time = 0.0;
168-
frame.set_window_pos(Pos2::new(init_x, init_y));
169-
if self.sound_path != "" {
170-
let result = fs::File::open(&self.sound_path);
171-
if let Ok(file) = result {
172-
let file = BufReader::new(file);
173-
std::thread::spawn(move || {
174-
let (_stream, stream_handle) = OutputStream::try_default().unwrap();
175-
let source = Decoder::new(file).unwrap();
176-
let sink = Sink::try_new(&stream_handle).unwrap();
177-
sink.append(source);
178-
sink.sleep_until_end();
179-
});
180-
}
181-
}
182-
ctx.request_repaint_after(std::time::Duration::from_millis(16));
183257
break;
184258
}
185259
}
186260
}
187261
}
262+
clock_window_frame(ctx, frame, self, custom_clock);
188263

189264
if let Ok(TrayEvent {
190265
event: tray_icon::ClickEvent::Left,
@@ -201,8 +276,15 @@ impl eframe::App for MyApp {
201276
}
202277
}
203278
if let Ok(event) = MenuEvent::receiver().try_recv() {
204-
if event.id == self.quit {
279+
if event.id == self.quit_index {
205280
std::process::exit(0)
281+
} else if event.id == self.countdown_index {
282+
self.countdown_start = !self.countdown_start;
283+
if self.countdown_start == true {
284+
self.visible = true;
285+
frame.set_visible(self.visible);
286+
self.countdown_start_time = Local::now().timestamp();
287+
}
206288
}
207289
}
208290
}
@@ -211,7 +293,8 @@ impl eframe::App for MyApp {
211293
fn clock_window_frame(
212294
ctx: &egui::Context,
213295
frame: &mut eframe::Frame,
214-
app: &mut MyApp
296+
app: &mut MyApp,
297+
custom_clock: String
215298
) {
216299
use egui::*;
217300
let text_color = ctx.style().visuals.text_color();
@@ -240,13 +323,23 @@ fn clock_window_frame(
240323
);
241324

242325
// Paint the title:
243-
painter.text(
244-
rect.center_top() + vec2(-41.0, 51.0),
245-
Align2::LEFT_CENTER,
246-
now.format("%H:%M:%S"),
247-
FontId::proportional(50.0),
248-
text_color,
249-
);
326+
if custom_clock == "" {
327+
painter.text(
328+
rect.center_top() + vec2(-41.0, 51.0),
329+
Align2::LEFT_CENTER,
330+
now.format("%H:%M:%S"),
331+
FontId::proportional(50.0),
332+
text_color,
333+
);
334+
} else {
335+
painter.text(
336+
rect.center_top() + vec2(-41.0, 51.0),
337+
Align2::LEFT_CENTER,
338+
custom_clock,
339+
FontId::proportional(50.0),
340+
text_color,
341+
);
342+
}
250343

251344
painter.circle_filled(
252345
Pos2::new(55.0, 50.0),
@@ -294,7 +387,7 @@ fn clock_window_frame(
294387
if app.tikpop == false {
295388
let close_response = ui.put(
296389
Rect::from_min_size(rect.left_top(), Vec2::splat(28.0)),
297-
Button::new(RichText::new("").size(24.0)).frame(false),
390+
Button::new(RichText::new("").size(16.0)).frame(false),
298391
);
299392
if close_response.clicked() {
300393
frame.set_visible(false);

0 commit comments

Comments
 (0)