93 lines
3.1 KiB
Rust
93 lines
3.1 KiB
Rust
|
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<RefCell<Option<SunMoon>>>,
|
||
|
}
|
||
|
|
||
|
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<TransitClockPrivate>) @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();
|
||
|
}
|
||
|
}
|