Make the application responsive to time passing

This commit is contained in:
Savanni D'Gerinel 2023-08-09 12:53:14 -04:00
parent 0078f1db27
commit 4714a06daa
1 changed files with 139 additions and 53 deletions

View File

@ -5,11 +5,19 @@ extern crate serde_derive;
extern crate lazy_static; extern crate lazy_static;
*/ */
use chrono::{Datelike, Duration, NaiveTime}; use chrono::{Datelike, Duration, Local, NaiveTime};
use glib::Object; use geo_types::{Latitude, Longitude};
use glib::{Object, Sender};
use gtk::{prelude::*, subclass::prelude::*, Orientation}; use gtk::{prelude::*, subclass::prelude::*, Orientation};
use ifc::IFC; use ifc::IFC;
use std::{cell::RefCell, env, f64::consts::PI, ops::Deref, rc::Rc}; use std::{
cell::RefCell,
env,
f64::consts::PI,
ops::Deref,
rc::Rc,
sync::{Arc, RwLock},
};
mod drawing; mod drawing;
use drawing::{Color, PieChart, Wedge}; use drawing::{Color, PieChart, Wedge};
@ -19,7 +27,7 @@ use geo_types::{Latitude, Longitude};
*/ */
mod soluna_client; mod soluna_client;
use soluna_client::{LunarPhase, SunMoon}; use soluna_client::{SolunaClient, SunMoon};
/* /*
mod solstices; mod solstices;
@ -169,8 +177,37 @@ async fn page(
} }
*/ */
#[derive(Default)] #[derive(Clone, Debug)]
pub struct DatePrivate {} pub enum Message {
Refresh(State),
}
#[derive(Clone, Debug)]
pub struct State {
date: IFC,
transit: Option<SunMoon>,
}
#[derive(Clone)]
pub struct Core {
tx: Arc<RwLock<Option<Sender<Message>>>>,
}
pub struct DatePrivate {
date: Rc<RefCell<IFC>>,
label: Rc<RefCell<gtk::Label>>,
}
impl Default for DatePrivate {
fn default() -> Self {
Self {
date: Rc::new(RefCell::new(IFC::from(
chrono::Local::now().date_naive().with_year(12023).unwrap(),
))),
label: Rc::new(RefCell::new(gtk::Label::new(None))),
}
}
}
#[glib::object_subclass] #[glib::object_subclass]
impl ObjectSubclass for DatePrivate { impl ObjectSubclass for DatePrivate {
@ -197,19 +234,27 @@ impl Date {
s.set_margin_start(8); s.set_margin_start(8);
s.set_margin_end(8); s.set_margin_end(8);
let dt = IFC::from(chrono::Local::now().date_naive().with_year(12023).unwrap()); s.append(&*s.imp().label.borrow());
s.append(&gtk::Label::new(Some(
format!( s.redraw();
"{:?}, {:?} {}, {}",
dt.weekday(),
dt.month(),
dt.day(),
dt.year()
)
.as_ref(),
)));
s s
} }
fn update_date(&self, date: IFC) {
*self.imp().date.borrow_mut() = date;
self.redraw();
}
fn redraw(&self) {
let date = self.imp().date.borrow().clone();
self.imp().label.borrow_mut().set_text(&format!(
"{:?}, {:?} {}, {}",
date.weekday(),
date.month(),
date.day(),
date.year()
));
}
} }
pub struct TransitClockPrivate { pub struct TransitClockPrivate {
@ -240,13 +285,11 @@ glib::wrapper! {
} }
impl TransitClock { impl TransitClock {
pub fn new(sun_moon_info: SunMoon) -> Self { pub fn new() -> Self {
let s: Self = Object::builder().build(); let s: Self = Object::builder().build();
s.set_width_request(500); s.set_width_request(500);
s.set_height_request(500); s.set_height_request(500);
*s.imp().info.borrow_mut() = Some(sun_moon_info);
s.set_draw_func({ s.set_draw_func({
let s = s.clone(); let s = s.clone();
move |_, context, width, height| { move |_, context, width, height| {
@ -291,6 +334,11 @@ impl TransitClock {
s s
} }
pub fn update_transit(&self, transit_info: SunMoon) {
*self.imp().info.borrow_mut() = Some(transit_info);
self.queue_draw();
}
} }
pub fn main() { pub fn main() {
@ -299,9 +347,48 @@ pub fn main() {
.resource_base_path("/com/luminescent-dreams/dashboard") .resource_base_path("/com/luminescent-dreams/dashboard")
.build(); .build();
app.connect_activate( let latitude = Latitude::from(41.78);
// let runtime = runtime.clone(); let longitude = Longitude::from(-71.41);
|app| {
let runtime = Arc::new(
tokio::runtime::Builder::new_multi_thread()
.enable_all()
.build()
.unwrap(),
);
let core = Core {
tx: Arc::new(RwLock::new(None)),
};
let app_handle = runtime.spawn({
let core = core.clone();
async move {
let soluna_client = SolunaClient::new();
let transit = soluna_client
.request(latitude, longitude, Local::now())
.await;
let state = State {
date: IFC::from(Local::now().date_naive().with_year(12023).unwrap()),
transit: Some(transit),
};
loop {
if let Some(ref gtk_tx) = *core.tx.read().unwrap() {
let _ = gtk_tx.send(Message::Refresh(state.clone()));
}
std::thread::sleep(std::time::Duration::from_secs(300));
}
}
});
app.connect_activate(move |app| {
let (gtk_tx, gtk_rx) =
gtk::glib::MainContext::channel::<Message>(gtk::glib::PRIORITY_DEFAULT);
*core.tx.write().unwrap() = Some(gtk_tx);
let window = gtk::ApplicationWindow::new(app); let window = gtk::ApplicationWindow::new(app);
window.present(); window.present();
@ -310,34 +397,33 @@ pub fn main() {
.hexpand(true) .hexpand(true)
.vexpand(true) .vexpand(true)
.build(); .build();
let date = Date::new(); let date_label = Date::new();
layout.append(&date); layout.append(&date_label);
let button = gtk::Button::builder() let transit_clock = TransitClock::new();
.label("Text") layout.append(&transit_clock);
.margin_bottom(8)
.margin_top(8)
.margin_start(8)
.margin_end(8)
.build();
layout.append(&button);
let day = TransitClock::new(SunMoon {
sunrise: NaiveTime::from_hms_opt(7, 0, 0).unwrap(),
sunset: NaiveTime::from_hms_opt(22, 0, 0).unwrap(),
moonrise: NaiveTime::from_hms_opt(15, 0, 0),
moonset: NaiveTime::from_hms_opt(5, 0, 0),
moon_phase: LunarPhase::WaningCrescent,
});
layout.append(&day);
window.set_child(Some(&layout)); window.set_child(Some(&layout));
},
); gtk_rx.attach(None, move |msg| {
let Message::Refresh(state) = msg;
println!("new state: {:?}", state);
date_label.update_date(state.date);
if let Some(transit) = state.transit {
transit_clock.update_transit(transit);
}
Continue(true)
});
std::thread::spawn(move || {});
});
let args: Vec<String> = env::args().collect(); let args: Vec<String> = env::args().collect();
ApplicationExtManual::run_with_args(&app, &args); ApplicationExtManual::run_with_args(&app, &args);
let _ = runtime.block_on(async { app_handle.await });
/* /*
let now = Local::now(); let now = Local::now();
let ifc = ifc::IFC::from(now.date_naive().with_year(12023).unwrap()); let ifc = ifc::IFC::from(now.date_naive().with_year(12023).unwrap());