Show astronomical events in the UI #58
|
@ -1,5 +1,9 @@
|
|||
@define-color background_color @purple_5;
|
||||
|
||||
label {
|
||||
font-size: 200%;
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
.highlight {
|
||||
color: @accent_fg_color;
|
||||
background-color: @accent_bg_color;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::{
|
||||
components::{Date, TransitCard, TransitClock},
|
||||
components::{Date, Events, TransitCard, TransitClock},
|
||||
types::State,
|
||||
};
|
||||
use adw::prelude::AdwApplicationWindowExt;
|
||||
|
@ -10,7 +10,7 @@ use gtk::{prelude::*, STYLE_PROVIDER_PRIORITY_USER};
|
|||
pub struct ApplicationWindow {
|
||||
pub window: adw::ApplicationWindow,
|
||||
pub date_label: Date,
|
||||
pub next_event: gtk::Label,
|
||||
pub events: Events,
|
||||
pub transit_card: TransitCard,
|
||||
pub transit_clock: TransitClock,
|
||||
}
|
||||
|
@ -43,6 +43,7 @@ impl ApplicationWindow {
|
|||
let date_label = Date::new();
|
||||
layout.append(&date_label);
|
||||
|
||||
/*
|
||||
let next_event = gtk::Label::builder()
|
||||
.margin_bottom(8)
|
||||
.margin_top(8)
|
||||
|
@ -50,6 +51,10 @@ impl ApplicationWindow {
|
|||
.margin_end(8)
|
||||
.build();
|
||||
layout.append(&next_event);
|
||||
*/
|
||||
|
||||
let events = Events::new();
|
||||
layout.append(&events);
|
||||
|
||||
let transit_card = TransitCard::new();
|
||||
layout.append(&transit_card);
|
||||
|
@ -62,7 +67,7 @@ impl ApplicationWindow {
|
|||
Self {
|
||||
window,
|
||||
date_label,
|
||||
next_event,
|
||||
events,
|
||||
transit_card,
|
||||
transit_clock,
|
||||
}
|
||||
|
@ -70,7 +75,9 @@ impl ApplicationWindow {
|
|||
|
||||
pub fn update_state(&self, state: State) {
|
||||
self.date_label.update_date(state.date);
|
||||
self.next_event.set_text(&format!("{:?}", state.next_event));
|
||||
/* self.next_event.set_text(&format!("{:?}", state.next_event)); */
|
||||
|
||||
self.events.set_events(state.events, state.next_event);
|
||||
if let Some(transit) = state.transit {
|
||||
self.transit_card.update_transit(&transit);
|
||||
self.transit_clock.update_transit(transit);
|
||||
|
|
|
@ -0,0 +1,105 @@
|
|||
use crate::{
|
||||
components::Date,
|
||||
solstices::{self, YearlyEvents},
|
||||
soluna_client::SunMoon,
|
||||
};
|
||||
use chrono::TimeZone;
|
||||
use glib::Object;
|
||||
use gtk::{prelude::*, subclass::prelude::*, IconLookupFlags};
|
||||
use ifc::IFC;
|
||||
|
||||
#[derive(PartialEq)]
|
||||
pub enum UpcomingEvent {
|
||||
SpringEquinox,
|
||||
SummerSolstice,
|
||||
AutumnEquinox,
|
||||
WinterSolstice,
|
||||
}
|
||||
|
||||
pub struct EventsPrivate {
|
||||
spring_equinox: Date,
|
||||
summer_solstice: Date,
|
||||
autumn_equinox: Date,
|
||||
winter_solstice: Date,
|
||||
next: UpcomingEvent,
|
||||
}
|
||||
|
||||
impl Default for EventsPrivate {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
spring_equinox: Date::new(),
|
||||
summer_solstice: Date::new(),
|
||||
autumn_equinox: Date::new(),
|
||||
winter_solstice: Date::new(),
|
||||
next: UpcomingEvent::SpringEquinox,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[glib::object_subclass]
|
||||
impl ObjectSubclass for EventsPrivate {
|
||||
const NAME: &'static str = "Events";
|
||||
type Type = Events;
|
||||
type ParentType = gtk::Box;
|
||||
}
|
||||
|
||||
impl ObjectImpl for EventsPrivate {}
|
||||
impl WidgetImpl for EventsPrivate {}
|
||||
impl BoxImpl for EventsPrivate {}
|
||||
|
||||
glib::wrapper! {
|
||||
pub struct Events(ObjectSubclass<EventsPrivate>) @extends gtk::Widget, gtk::Box, @implements gtk::Orientable;
|
||||
}
|
||||
|
||||
impl Events {
|
||||
pub fn new() -> Self {
|
||||
let s: Self = Object::builder().build();
|
||||
s.set_orientation(gtk::Orientation::Horizontal);
|
||||
s.set_spacing(8);
|
||||
|
||||
s.append(&s.imp().spring_equinox);
|
||||
s.append(&s.imp().summer_solstice);
|
||||
s.append(&s.imp().autumn_equinox);
|
||||
s.append(&s.imp().winter_solstice);
|
||||
|
||||
s
|
||||
}
|
||||
|
||||
pub fn set_events(&self, events: YearlyEvents, next_event: solstices::Event) {
|
||||
self.imp()
|
||||
.spring_equinox
|
||||
.update_date(IFC::from(events.spring_equinox.date_naive()));
|
||||
|
||||
self.imp()
|
||||
.summer_solstice
|
||||
.update_date(IFC::from(events.summer_solstice.date_naive()));
|
||||
|
||||
self.imp()
|
||||
.autumn_equinox
|
||||
.update_date(IFC::from(events.autumn_equinox.date_naive()));
|
||||
|
||||
self.imp()
|
||||
.winter_solstice
|
||||
.update_date(IFC::from(events.winter_solstice.date_naive()));
|
||||
|
||||
self.imp().spring_equinox.remove_css_class("highlight");
|
||||
self.imp().summer_solstice.remove_css_class("highlight");
|
||||
self.imp().autumn_equinox.remove_css_class("highlight");
|
||||
self.imp().winter_solstice.remove_css_class("highlight");
|
||||
|
||||
match next_event {
|
||||
solstices::Event::SpringEquinox(_) => {
|
||||
self.imp().spring_equinox.add_css_class("highlight")
|
||||
}
|
||||
solstices::Event::SummerSolstice(_) => {
|
||||
self.imp().summer_solstice.add_css_class("highlight")
|
||||
}
|
||||
solstices::Event::AutumnEquinox(_) => {
|
||||
self.imp().autumn_equinox.add_css_class("highlight")
|
||||
}
|
||||
solstices::Event::WinterSolstice(_) => {
|
||||
self.imp().winter_solstice.add_css_class("highlight")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,9 @@
|
|||
mod date;
|
||||
pub use date::Date;
|
||||
|
||||
mod events;
|
||||
pub use events::Events;
|
||||
|
||||
mod label;
|
||||
pub use label::Label;
|
||||
|
||||
|
|
|
@ -106,6 +106,7 @@ pub fn main() {
|
|||
let state = State {
|
||||
date: IFC::from(now.date_naive().with_year(12023).unwrap()),
|
||||
next_event: EVENTS.next_event(now.with_timezone(&Utc)).unwrap(),
|
||||
events: EVENTS.yearly_events(now.year()).unwrap(),
|
||||
transit: Some(transit),
|
||||
};
|
||||
|
||||
|
|
|
@ -133,11 +133,9 @@ fn parse_events() -> Vec<Option<YearlyEvents>> {
|
|||
pub struct Solstices(HashMap<i32, YearlyEvents>);
|
||||
|
||||
impl Solstices {
|
||||
/*
|
||||
pub fn acquire(&self, year: i32) -> Option<YearlyEvents> {
|
||||
pub fn yearly_events(&self, year: i32) -> Option<YearlyEvents> {
|
||||
self.0.get(&year).map(|c| c.clone())
|
||||
}
|
||||
*/
|
||||
|
||||
pub fn next_event(&self, date: chrono::DateTime<chrono::Utc>) -> Option<Event> {
|
||||
let year_events = self.0.get(&date.year());
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
use crate::{solstices::Event, soluna_client::SunMoon};
|
||||
use crate::{
|
||||
solstices::{Event, YearlyEvents},
|
||||
soluna_client::SunMoon,
|
||||
};
|
||||
use ifc::IFC;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct State {
|
||||
pub date: IFC,
|
||||
pub next_event: Event,
|
||||
pub events: YearlyEvents,
|
||||
pub transit: Option<SunMoon>,
|
||||
}
|
||||
|
|
|
@ -232,9 +232,9 @@ impl IFC {
|
|||
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub struct Day {
|
||||
year: i32,
|
||||
month: u8,
|
||||
day: u8,
|
||||
pub year: i32,
|
||||
pub month: u8,
|
||||
pub day: u8,
|
||||
}
|
||||
|
||||
impl From<chrono::NaiveDate> for IFC {
|
||||
|
|
Loading…
Reference in New Issue