Compare commits
3 Commits
0078f1db27
...
5e2b7fbc99
Author | SHA1 | Date |
---|---|---|
Savanni D'Gerinel | 5e2b7fbc99 | |
Savanni D'Gerinel | e2d3875587 | |
Savanni D'Gerinel | 4714a06daa |
|
@ -0,0 +1,44 @@
|
||||||
|
use crate::{
|
||||||
|
components::{Date, TransitClock},
|
||||||
|
types::State,
|
||||||
|
};
|
||||||
|
use gtk::prelude::*;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct ApplicationWindow {
|
||||||
|
pub window: gtk::ApplicationWindow,
|
||||||
|
pub date_label: Date,
|
||||||
|
pub transit_clock: TransitClock,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ApplicationWindow {
|
||||||
|
pub fn new(app: >k::Application) -> Self {
|
||||||
|
let window = gtk::ApplicationWindow::new(app);
|
||||||
|
let date_label = Date::new();
|
||||||
|
let transit_clock = TransitClock::new();
|
||||||
|
|
||||||
|
let layout = gtk::Box::builder()
|
||||||
|
.orientation(gtk::Orientation::Vertical)
|
||||||
|
.hexpand(true)
|
||||||
|
.vexpand(true)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
layout.append(&date_label);
|
||||||
|
layout.append(&transit_clock);
|
||||||
|
|
||||||
|
window.set_child(Some(&layout));
|
||||||
|
|
||||||
|
Self {
|
||||||
|
window,
|
||||||
|
date_label,
|
||||||
|
transit_clock,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update_state(&self, state: State) {
|
||||||
|
self.date_label.update_date(state.date);
|
||||||
|
if let Some(transit) = state.transit {
|
||||||
|
self.transit_clock.update_transit(transit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,69 @@
|
||||||
|
use chrono::Datelike;
|
||||||
|
use glib::Object;
|
||||||
|
use gtk::{prelude::*, subclass::prelude::*};
|
||||||
|
use ifc::IFC;
|
||||||
|
use std::{cell::RefCell, rc::Rc};
|
||||||
|
|
||||||
|
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]
|
||||||
|
impl ObjectSubclass for DatePrivate {
|
||||||
|
const NAME: &'static str = "Date";
|
||||||
|
type Type = Date;
|
||||||
|
type ParentType = gtk::Box;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ObjectImpl for DatePrivate {}
|
||||||
|
impl WidgetImpl for DatePrivate {}
|
||||||
|
impl BoxImpl for DatePrivate {}
|
||||||
|
|
||||||
|
glib::wrapper! {
|
||||||
|
pub struct Date(ObjectSubclass<DatePrivate>) @extends gtk::Box, gtk::Widget;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Date {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
let s: Self = Object::builder().build();
|
||||||
|
s.add_css_class("card");
|
||||||
|
s.add_css_class("activatable");
|
||||||
|
s.set_margin_bottom(8);
|
||||||
|
s.set_margin_top(8);
|
||||||
|
s.set_margin_start(8);
|
||||||
|
s.set_margin_end(8);
|
||||||
|
|
||||||
|
s.append(&*s.imp().label.borrow());
|
||||||
|
|
||||||
|
s.redraw();
|
||||||
|
s
|
||||||
|
}
|
||||||
|
|
||||||
|
pub 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()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
mod date;
|
||||||
|
pub use date::Date;
|
||||||
|
|
||||||
|
mod transit_clock;
|
||||||
|
pub use transit_clock::TransitClock;
|
|
@ -0,0 +1,92 @@
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,30 +1,29 @@
|
||||||
/*
|
use chrono::{Datelike, Local};
|
||||||
#[macro_use]
|
use geo_types::{Latitude, Longitude};
|
||||||
extern crate serde_derive;
|
use glib::Sender;
|
||||||
#[macro_use]
|
|
||||||
extern crate lazy_static;
|
|
||||||
*/
|
|
||||||
|
|
||||||
use chrono::{Datelike, Duration, NaiveTime};
|
|
||||||
use glib::Object;
|
|
||||||
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::{
|
||||||
|
env,
|
||||||
|
sync::{Arc, RwLock},
|
||||||
|
};
|
||||||
|
|
||||||
|
mod app_window;
|
||||||
|
use app_window::ApplicationWindow;
|
||||||
|
|
||||||
|
mod components;
|
||||||
|
use components::{Date, TransitClock};
|
||||||
|
|
||||||
mod drawing;
|
mod drawing;
|
||||||
use drawing::{Color, PieChart, Wedge};
|
|
||||||
|
|
||||||
/*
|
|
||||||
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;
|
||||||
use solstices::EVENTS;
|
use solstices::EVENTS;
|
||||||
*/
|
|
||||||
|
mod types;
|
||||||
|
use types::State;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
const EO_TEXT: &'static str = "
|
const EO_TEXT: &'static str = "
|
||||||
|
@ -59,238 +58,16 @@ summer_solstice = Somera Solstico
|
||||||
autumn_equinox = Aŭtuna Ekvinokso
|
autumn_equinox = Aŭtuna Ekvinokso
|
||||||
winter_solstice = Vintra Solstico
|
winter_solstice = Vintra Solstico
|
||||||
";
|
";
|
||||||
|
|
||||||
fn date(fluent: Arc<fluent_ergonomics::FluentErgo>, today: ifc::IFC) -> impl Render {
|
|
||||||
let mut day_args = FluentArgs::new();
|
|
||||||
day_args.set(
|
|
||||||
"day",
|
|
||||||
FluentValue::String(Cow::Owned(String::from(today.weekday_ifc()))),
|
|
||||||
);
|
|
||||||
let tago = fluent.tr("tago", Some(&day_args)).unwrap();
|
|
||||||
|
|
||||||
let mut month_args = FluentArgs::new();
|
|
||||||
month_args.set(
|
|
||||||
"month",
|
|
||||||
FluentValue::String(Cow::Owned(String::from(today.month_ifc()))),
|
|
||||||
);
|
|
||||||
let monato = fluent.tr("month", Some(&month_args)).unwrap();
|
|
||||||
|
|
||||||
owned_html! {p : format!("{}, {} {}, {}", tago, monato, today.day(), today.year());}
|
|
||||||
}
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
#[derive(Clone, Debug)]
|
||||||
fn soluna_desegno<Tz: TimeZone>(sun_moon: SunMoon<Tz>) -> impl Render {
|
pub enum Message {
|
||||||
owned_html! {
|
Refresh(State),
|
||||||
table {
|
|
||||||
tr {
|
|
||||||
th : "Sunleviĝo";
|
|
||||||
th : "Sunfalo";
|
|
||||||
th : "Lunleviĝo";
|
|
||||||
th : "Lunfalo";
|
|
||||||
}
|
|
||||||
tr {
|
|
||||||
td : format!("{}", sun_moon.sunrise.format("%H:%M"));
|
|
||||||
td : format!("{}", sun_moon.sunset.format("%H:%M"));
|
|
||||||
td : sun_moon.moonrise.map(|v| format!("{}", v.format("%H:%M"))).unwrap_or("".to_string());
|
|
||||||
td : sun_moon.moonset.map(|v| format!("{}", v.format("%H:%M"))).unwrap_or("".to_string());
|
|
||||||
td : format!("{:?}", sun_moon.moon_phase);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
fn astronomia_eventa_desegno(
|
|
||||||
fluent: Arc<fluent_ergonomics::FluentErgo>,
|
|
||||||
event: Option<Event>,
|
|
||||||
) -> impl Render {
|
|
||||||
let s = match event {
|
|
||||||
None => "".to_owned(),
|
|
||||||
Some(event) => {
|
|
||||||
let eventa_str = match event {
|
|
||||||
Event::SpringEquinox(_) => fluent.tr("spring_equinox", None),
|
|
||||||
Event::SummerSolstice(_) => fluent.tr("summer_solstice", None),
|
|
||||||
Event::AutumnEquinox(_) => fluent.tr("autumn_equinox", None),
|
|
||||||
Event::WinterSolstice(_) => fluent.tr("winter_solstice", None),
|
|
||||||
}
|
|
||||||
.unwrap();
|
|
||||||
format!("{} {}", eventa_str, event.date().format("%Y-%m-%d"))
|
|
||||||
}
|
|
||||||
};
|
|
||||||
owned_html! {
|
|
||||||
div : s.clone();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
fn page_template(
|
|
||||||
fluent: Arc<fluent_ergonomics::FluentErgo>,
|
|
||||||
today: ifc::IFC,
|
|
||||||
sun_moon: SunMoon,
|
|
||||||
event: Option<solstices::Event>,
|
|
||||||
) -> String {
|
|
||||||
format!(
|
|
||||||
"{}",
|
|
||||||
html! {
|
|
||||||
: doctype::HTML;
|
|
||||||
html {
|
|
||||||
head {
|
|
||||||
title: "Superrigardo";
|
|
||||||
}
|
|
||||||
body {
|
|
||||||
h1(id="heading", class="title") : date(fluent.clone(), today);
|
|
||||||
div : soluna_desegno(sun_moon.clone());
|
|
||||||
div : astronomia_eventa_desegno(fluent.clone(), event);
|
|
||||||
// div : cirklo();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn page(
|
#[derive(Clone)]
|
||||||
fluent: Arc<fluent_ergonomics::FluentErgo>,
|
pub struct Core {
|
||||||
solar_client: Arc<SolunaClient>,
|
tx: Arc<RwLock<Option<Sender<Message>>>>,
|
||||||
latitude: Latitude,
|
|
||||||
longitude: Longitude,
|
|
||||||
) -> Result<Html<String>, Rejection> {
|
|
||||||
let now = Utc::now();
|
|
||||||
let d = ifc::IFC::from(now.with_timezone(&New_York).date());
|
|
||||||
let sun_moon = solar_client
|
|
||||||
.request(latitude, longitude, now.with_timezone(&New_York).date())
|
|
||||||
.await;
|
|
||||||
let next_event = EVENTS.next_event(now);
|
|
||||||
Ok(warp::reply::html(page_template(
|
|
||||||
fluent, d, sun_moon, next_event,
|
|
||||||
)))
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
#[derive(Default)]
|
|
||||||
pub struct DatePrivate {}
|
|
||||||
|
|
||||||
#[glib::object_subclass]
|
|
||||||
impl ObjectSubclass for DatePrivate {
|
|
||||||
const NAME: &'static str = "Date";
|
|
||||||
type Type = Date;
|
|
||||||
type ParentType = gtk::Box;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ObjectImpl for DatePrivate {}
|
|
||||||
impl WidgetImpl for DatePrivate {}
|
|
||||||
impl BoxImpl for DatePrivate {}
|
|
||||||
|
|
||||||
glib::wrapper! {
|
|
||||||
pub struct Date(ObjectSubclass<DatePrivate>) @extends gtk::Box, gtk::Widget;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Date {
|
|
||||||
fn new() -> Self {
|
|
||||||
let s: Self = Object::builder().build();
|
|
||||||
s.add_css_class("card");
|
|
||||||
s.add_css_class("activatable");
|
|
||||||
s.set_margin_bottom(8);
|
|
||||||
s.set_margin_top(8);
|
|
||||||
s.set_margin_start(8);
|
|
||||||
s.set_margin_end(8);
|
|
||||||
|
|
||||||
let dt = IFC::from(chrono::Local::now().date_naive().with_year(12023).unwrap());
|
|
||||||
s.append(>k::Label::new(Some(
|
|
||||||
format!(
|
|
||||||
"{:?}, {:?} {}, {}",
|
|
||||||
dt.weekday(),
|
|
||||||
dt.month(),
|
|
||||||
dt.day(),
|
|
||||||
dt.year()
|
|
||||||
)
|
|
||||||
.as_ref(),
|
|
||||||
)));
|
|
||||||
s
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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(sun_moon_info: SunMoon) -> Self {
|
|
||||||
let s: Self = Object::builder().build();
|
|
||||||
s.set_width_request(500);
|
|
||||||
s.set_height_request(500);
|
|
||||||
|
|
||||||
*s.imp().info.borrow_mut() = Some(sun_moon_info);
|
|
||||||
|
|
||||||
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 main() {
|
pub fn main() {
|
||||||
|
@ -299,45 +76,69 @@ 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 window = gtk::ApplicationWindow::new(app);
|
|
||||||
window.present();
|
|
||||||
|
|
||||||
let layout = gtk::Box::builder()
|
let runtime = Arc::new(
|
||||||
.orientation(Orientation::Vertical)
|
tokio::runtime::Builder::new_multi_thread()
|
||||||
.hexpand(true)
|
.enable_all()
|
||||||
.vexpand(true)
|
.build()
|
||||||
.build();
|
.unwrap(),
|
||||||
let date = Date::new();
|
|
||||||
layout.append(&date);
|
|
||||||
|
|
||||||
let button = gtk::Button::builder()
|
|
||||||
.label("Text")
|
|
||||||
.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));
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
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 = ApplicationWindow::new(app);
|
||||||
|
window.window.present();
|
||||||
|
|
||||||
|
gtk_rx.attach(None, {
|
||||||
|
let window = window.clone();
|
||||||
|
move |msg| {
|
||||||
|
let Message::Refresh(state) = msg;
|
||||||
|
ApplicationWindow::update_state(&window, state);
|
||||||
|
|
||||||
|
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());
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use chrono;
|
use chrono;
|
||||||
use chrono::prelude::*;
|
use chrono::prelude::*;
|
||||||
|
use lazy_static::lazy_static;
|
||||||
use serde_derive::{Deserialize, Serialize};
|
use serde_derive::{Deserialize, Serialize};
|
||||||
use serde_json;
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
// http://astropixels.com/ephemeris/soleq2001.html
|
// http://astropixels.com/ephemeris/soleq2001.html
|
||||||
|
@ -133,7 +133,7 @@ fn parse_events() -> Vec<Option<YearlyEvents>> {
|
||||||
pub struct Solstices(HashMap<i32, YearlyEvents>);
|
pub struct Solstices(HashMap<i32, YearlyEvents>);
|
||||||
|
|
||||||
impl Solstices {
|
impl Solstices {
|
||||||
pub fn akiru(&self, year: i32) -> Option<YearlyEvents> {
|
pub fn acquire(&self, year: i32) -> Option<YearlyEvents> {
|
||||||
self.0.get(&year).map(|c| c.clone())
|
self.0.get(&year).map(|c| c.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
use crate::soluna_client::SunMoon;
|
||||||
|
use ifc::IFC;
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct State {
|
||||||
|
pub date: IFC,
|
||||||
|
pub transit: Option<SunMoon>,
|
||||||
|
}
|
Loading…
Reference in New Issue