use crate::{ drawing::{Color, PieChart, Wedge}, soluna_client::SunMoon, }; use chrono::{Duration, NaiveTime}; use glib::Object; use gtk::{prelude::*, subclass::prelude::*}; use std::{cell::RefCell, f64::consts::PI, rc::Rc}; pub struct TransitClockPrivate { info: Rc>>, } impl Default for TransitClockPrivate { fn default() -> Self { Self { info: Rc::new(RefCell::new(None)), } } } #[glib::object_subclass] impl ObjectSubclass for TransitClockPrivate { const NAME: &'static str = "TransitClock"; type Type = TransitClock; type ParentType = gtk::DrawingArea; } impl ObjectImpl for TransitClockPrivate {} impl WidgetImpl for TransitClockPrivate {} impl DrawingAreaImpl for TransitClockPrivate {} glib::wrapper! { pub struct TransitClock(ObjectSubclass) @extends gtk::DrawingArea, gtk::Widget; } impl TransitClock { pub fn new() -> Self { let s: Self = Object::builder().build(); s.set_width_request(500); s.set_height_request(500); s.set_draw_func({ let s = s.clone(); move |_, context, width, height| { let center_x = width as f64 / 2.; let center_y = height as f64 / 2.; let radius = width.min(height) as f64 / 2. * 0.9; if let Some(ref info) = *s.imp().info.borrow() { let full_day = Duration::days(1).num_seconds() as f64; let sunrise = info.sunrise - NaiveTime::from_hms_opt(0, 0, 0).unwrap(); let sunset = info.sunset - NaiveTime::from_hms_opt(0, 0, 0).unwrap(); PieChart::new() .center(center_x, center_y) .radius(radius) .rotation(-PI / 2.) .wedges( vec![Wedge { start_angle: (PI * 2.) * sunset.num_seconds() as f64 / full_day, end_angle: (PI * 2.) * sunrise.num_seconds() as f64 / full_day, color: Color { r: 0.1, g: 0.1, b: 0.8, }, }] .into_iter(), ) .draw(context); (0..24).for_each(|tick| { context.set_source_rgb(0., 0., 0.); context.translate(center_x, center_y); context.rotate(tick as f64 * (PI / 12.)); context.move_to(radius - 5., 0.); context.line_to(radius - 10., 0.); let _ = context.stroke(); context.identity_matrix(); }); } } }); s } pub fn update_transit(&self, transit_info: SunMoon) { *self.imp().info.borrow_mut() = Some(transit_info); self.queue_draw(); } }