Start working on a moon phase clock
This commit was merged in pull request #438.
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@@ -857,6 +857,7 @@ dependencies = [
|
||||
"reqwest",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror 2.0.19",
|
||||
"tokio",
|
||||
"unic-langid",
|
||||
]
|
||||
|
||||
@@ -27,6 +27,7 @@ tokio = { version = "1", features = ["full"] }
|
||||
unic-langid = { version = "0.9" }
|
||||
async-trait.workspace = true
|
||||
jiff.workspace = true
|
||||
thiserror.workspace = true
|
||||
|
||||
[build-dependencies]
|
||||
glib-build-tools = "0.18"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use crate::{
|
||||
components::{Date, Events, SunClock, TransitCard},
|
||||
components::{Date, Events, MoonClock, SunClock, TransitCard},
|
||||
types::State,
|
||||
};
|
||||
use adw::prelude::AdwApplicationWindowExt;
|
||||
@@ -14,7 +14,8 @@ pub struct ApplicationWindow {
|
||||
pub sun_card: TransitCard,
|
||||
pub moon_card: TransitCard,
|
||||
pub sun_clock: SunClock,
|
||||
pub moon_clock: SunClock,
|
||||
pub moon_clock: MoonClock,
|
||||
pub moon_phase: gtk::Label,
|
||||
}
|
||||
|
||||
impl ApplicationWindow {
|
||||
@@ -51,7 +52,7 @@ impl ApplicationWindow {
|
||||
let events = Events::default();
|
||||
layout.append(&events);
|
||||
|
||||
let (sun_card, moon_card) = {
|
||||
let (sun_card, moon_card, moon_phase) = {
|
||||
let row = gtk::Box::builder()
|
||||
.orientation(gtk::Orientation::Horizontal)
|
||||
.hexpand(true)
|
||||
@@ -60,14 +61,23 @@ impl ApplicationWindow {
|
||||
.build();
|
||||
let sun_card = TransitCard::default();
|
||||
sun_card.set_hexpand(true);
|
||||
sun_card.set_vexpand(false);
|
||||
row.append(&sun_card);
|
||||
|
||||
let moon_section = gtk::Box::builder()
|
||||
.orientation(gtk::Orientation::Vertical)
|
||||
.build();
|
||||
|
||||
let moon_card = TransitCard::default();
|
||||
moon_card.set_hexpand(true);
|
||||
row.append(&moon_card);
|
||||
moon_section.append(&moon_card);
|
||||
|
||||
let phase = gtk::Label::builder().build();
|
||||
moon_section.append(&phase);
|
||||
|
||||
row.append(&moon_section);
|
||||
layout.append(&row);
|
||||
(sun_card, moon_card)
|
||||
(sun_card, moon_card, phase)
|
||||
};
|
||||
|
||||
let (sun_clock, moon_clock) = {
|
||||
@@ -79,7 +89,7 @@ impl ApplicationWindow {
|
||||
let sun_clock = SunClock::default();
|
||||
row.append(&sun_clock);
|
||||
|
||||
let moon_clock = SunClock::default();
|
||||
let moon_clock = MoonClock::default();
|
||||
row.append(&moon_clock);
|
||||
|
||||
layout.append(&row);
|
||||
@@ -96,6 +106,7 @@ impl ApplicationWindow {
|
||||
moon_card,
|
||||
sun_clock,
|
||||
moon_clock,
|
||||
moon_phase,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,11 +115,13 @@ impl ApplicationWindow {
|
||||
self.events.set_events(state.events, state.next_event);
|
||||
if let Some(transit) = state.sun_stats {
|
||||
self.sun_card.update_transit(transit.clone().into());
|
||||
self.sun_clock.update_transit(transit.clone().into());
|
||||
self.moon_clock.update_transit(transit.into());
|
||||
self.sun_clock.update_transit(transit.into());
|
||||
}
|
||||
if let Some(transit) = state.moon_stats {
|
||||
println!("transit phase: {}", transit.phase);
|
||||
self.moon_card.update_transit(transit.clone().into());
|
||||
self.moon_clock.update_transit(transit.clone().into());
|
||||
self.moon_phase.set_text(&format!("{}", transit.phase));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,4 +8,4 @@ mod label;
|
||||
pub use label::Label;
|
||||
|
||||
mod transit;
|
||||
pub use transit::{SunClock, TransitCard};
|
||||
pub use transit::{MoonClock, SunClock, TransitCard};
|
||||
|
||||
@@ -129,7 +129,6 @@ impl Default for SunClock {
|
||||
.second(0)
|
||||
.build()
|
||||
.unwrap();
|
||||
println!("today: {:?}", today);
|
||||
|
||||
#[allow(deprecated)]
|
||||
let style_context = WidgetExt::style_context(&s);
|
||||
@@ -198,3 +197,57 @@ impl SunClock {
|
||||
self.queue_draw();
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct MoonClockPrivate {
|
||||
info: Rc<RefCell<Option<MoonStats>>>,
|
||||
}
|
||||
|
||||
#[glib::object_subclass]
|
||||
impl ObjectSubclass for MoonClockPrivate {
|
||||
const NAME: &'static str = "MoonClock";
|
||||
type Type = MoonClock;
|
||||
type ParentType = gtk::DrawingArea;
|
||||
}
|
||||
|
||||
impl ObjectImpl for MoonClockPrivate {}
|
||||
impl WidgetImpl for MoonClockPrivate {}
|
||||
impl DrawingAreaImpl for MoonClockPrivate {}
|
||||
|
||||
glib::wrapper! {
|
||||
pub struct MoonClock(ObjectSubclass<MoonClockPrivate>) @extends gtk::DrawingArea, gtk::Widget;
|
||||
}
|
||||
|
||||
impl Default for MoonClock {
|
||||
fn default() -> 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| {
|
||||
#[allow(deprecated)]
|
||||
let style_context = WidgetExt::style_context(&s);
|
||||
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() {
|
||||
context.set_source_rgb(0., 0., 0.);
|
||||
context.arc(center_x, center_y, radius, 0., 2. * PI);
|
||||
let _ = context.fill();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
s
|
||||
}
|
||||
}
|
||||
|
||||
impl MoonClock {
|
||||
pub fn update_transit(&self, transit_info: MoonStats) {
|
||||
*self.imp().info.borrow_mut() = Some(transit_info);
|
||||
self.queue_draw();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use async_trait::async_trait;
|
||||
use chrono::NaiveTime;
|
||||
use geo_types::{Latitude, Longitude};
|
||||
use thiserror::Error;
|
||||
|
||||
mod mock_client;
|
||||
use jiff::Timestamp;
|
||||
@@ -41,3 +42,39 @@ pub enum LunarPhase {
|
||||
LastQuarter,
|
||||
WaningCrescent,
|
||||
}
|
||||
|
||||
impl std::fmt::Display for LunarPhase {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
|
||||
match self {
|
||||
LunarPhase::NewMoon => f.write_str("New Moon"),
|
||||
LunarPhase::WaxingCrescent => f.write_str("Waxing Crescent"),
|
||||
LunarPhase::FirstQuarter => f.write_str("First Quarter"),
|
||||
LunarPhase::WaxingGibbous => f.write_str("Waxing Gibbous"),
|
||||
LunarPhase::FullMoon => f.write_str("Full Moon"),
|
||||
LunarPhase::WaningGibbous => f.write_str("Waning Gibbous"),
|
||||
LunarPhase::LastQuarter => f.write_str("Last Quarter"),
|
||||
LunarPhase::WaningCrescent => f.write_str("Waning Crescent"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
#[error("Error parsing the moon phase")]
|
||||
pub struct LunarPhaseParseError;
|
||||
|
||||
impl std::str::FromStr for LunarPhase {
|
||||
type Err = LunarPhaseParseError;
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
match s {
|
||||
"NewMoon" => Ok(LunarPhase::NewMoon),
|
||||
"Waxing Crescent" => Ok(LunarPhase::WaxingCrescent),
|
||||
"First Quarter" => Ok(LunarPhase::FirstQuarter),
|
||||
"Waxing Gibbous" => Ok(LunarPhase::WaxingGibbous),
|
||||
"Full Moon" => Ok(LunarPhase::FullMoon),
|
||||
"Waning Gibbous" => Ok(LunarPhase::WaningGibbous),
|
||||
"Last Quarter" => Ok(LunarPhase::LastQuarter),
|
||||
"Waning Crescent" => Ok(LunarPhase::WaningCrescent),
|
||||
_ => Err(LunarPhaseParseError),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ impl SunriseSunsetClient {
|
||||
let moon_stats = MoonStats {
|
||||
rise: body.moonrise.map(|t| t.parse().unwrap()),
|
||||
set: body.moonset.map(|t| t.parse().unwrap()),
|
||||
phase: LunarPhase::NewMoon,
|
||||
phase: body.moon_phase.parse().unwrap(),
|
||||
};
|
||||
|
||||
let new_cache = Cache {
|
||||
|
||||
Reference in New Issue
Block a user