Show the solstices and equinoxes

This commit is contained in:
Savanni D'Gerinel 2023-08-10 12:35:48 -04:00
parent 1f2c7b8002
commit b2ca3d195d
8 changed files with 135 additions and 13 deletions

View File

@ -1,5 +1,9 @@
@define-color background_color @purple_5;
label { label {
font-size: 200%; font-size: 200%;
padding: 4px;
}
.highlight {
color: @accent_fg_color;
background-color: @accent_bg_color;
} }

View File

@ -1,5 +1,5 @@
use crate::{ use crate::{
components::{Date, TransitCard, TransitClock}, components::{Date, Events, TransitCard, TransitClock},
types::State, types::State,
}; };
use adw::prelude::AdwApplicationWindowExt; use adw::prelude::AdwApplicationWindowExt;
@ -10,7 +10,7 @@ use gtk::{prelude::*, STYLE_PROVIDER_PRIORITY_USER};
pub struct ApplicationWindow { pub struct ApplicationWindow {
pub window: adw::ApplicationWindow, pub window: adw::ApplicationWindow,
pub date_label: Date, pub date_label: Date,
pub next_event: gtk::Label, pub events: Events,
pub transit_card: TransitCard, pub transit_card: TransitCard,
pub transit_clock: TransitClock, pub transit_clock: TransitClock,
} }
@ -43,6 +43,7 @@ impl ApplicationWindow {
let date_label = Date::new(); let date_label = Date::new();
layout.append(&date_label); layout.append(&date_label);
/*
let next_event = gtk::Label::builder() let next_event = gtk::Label::builder()
.margin_bottom(8) .margin_bottom(8)
.margin_top(8) .margin_top(8)
@ -50,6 +51,10 @@ impl ApplicationWindow {
.margin_end(8) .margin_end(8)
.build(); .build();
layout.append(&next_event); layout.append(&next_event);
*/
let events = Events::new();
layout.append(&events);
let transit_card = TransitCard::new(); let transit_card = TransitCard::new();
layout.append(&transit_card); layout.append(&transit_card);
@ -62,7 +67,7 @@ impl ApplicationWindow {
Self { Self {
window, window,
date_label, date_label,
next_event, events,
transit_card, transit_card,
transit_clock, transit_clock,
} }
@ -70,7 +75,9 @@ impl ApplicationWindow {
pub fn update_state(&self, state: State) { pub fn update_state(&self, state: State) {
self.date_label.update_date(state.date); 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 { if let Some(transit) = state.transit {
self.transit_card.update_transit(&transit); self.transit_card.update_transit(&transit);
self.transit_clock.update_transit(transit); self.transit_clock.update_transit(transit);

View File

@ -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")
}
}
}
}

View File

@ -1,6 +1,9 @@
mod date; mod date;
pub use date::Date; pub use date::Date;
mod events;
pub use events::Events;
mod label; mod label;
pub use label::Label; pub use label::Label;

View File

@ -106,6 +106,7 @@ pub fn main() {
let state = State { let state = State {
date: IFC::from(now.date_naive().with_year(12023).unwrap()), date: IFC::from(now.date_naive().with_year(12023).unwrap()),
next_event: EVENTS.next_event(now.with_timezone(&Utc)).unwrap(), next_event: EVENTS.next_event(now.with_timezone(&Utc)).unwrap(),
events: EVENTS.yearly_events(now.year()).unwrap(),
transit: Some(transit), transit: Some(transit),
}; };

View File

@ -133,11 +133,9 @@ fn parse_events() -> Vec<Option<YearlyEvents>> {
pub struct Solstices(HashMap<i32, YearlyEvents>); pub struct Solstices(HashMap<i32, YearlyEvents>);
impl Solstices { impl Solstices {
/* pub fn yearly_events(&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())
} }
*/
pub fn next_event(&self, date: chrono::DateTime<chrono::Utc>) -> Option<Event> { pub fn next_event(&self, date: chrono::DateTime<chrono::Utc>) -> Option<Event> {
let year_events = self.0.get(&date.year()); let year_events = self.0.get(&date.year());

View File

@ -1,9 +1,13 @@
use crate::{solstices::Event, soluna_client::SunMoon}; use crate::{
solstices::{Event, YearlyEvents},
soluna_client::SunMoon,
};
use ifc::IFC; use ifc::IFC;
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct State { pub struct State {
pub date: IFC, pub date: IFC,
pub next_event: Event, pub next_event: Event,
pub events: YearlyEvents,
pub transit: Option<SunMoon>, pub transit: Option<SunMoon>,
} }

View File

@ -232,9 +232,9 @@ impl IFC {
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct Day { pub struct Day {
year: i32, pub year: i32,
month: u8, pub month: u8,
day: u8, pub day: u8,
} }
impl From<chrono::NaiveDate> for IFC { impl From<chrono::NaiveDate> for IFC {