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}; #[derive(Default)] pub struct TransitClockPrivate { info: Rc>>, } #[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 Default for TransitClock { fn default() -> 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 style_context = WidgetExt::style_context(&s); 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(); let night_color = style_context.lookup_color("dark_5").unwrap(); let day_color = style_context.lookup_color("blue_1").unwrap(); PieChart::new(&style_context) .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: night_color.red() as f64, g: night_color.green() as f64, b: night_color.blue() as f64, }, }, Wedge { start_angle: (PI * 2.) * sunrise.num_seconds() as f64 / full_day, end_angle: (PI * 2.) * sunset.num_seconds() as f64 / full_day, color: Color { r: day_color.red() as f64, g: day_color.green() as f64, b: day_color.blue() as f64, }, }, ] .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 } } impl TransitClock { pub fn update_transit(&self, transit_info: SunMoon) { *self.imp().info.borrow_mut() = Some(transit_info); self.queue_draw(); } }