From 63884a32f646f84702a34bc1069cb208fbd3b0cd Mon Sep 17 00:00:00 2001 From: Savanni D'Gerinel Date: Wed, 9 Aug 2023 23:33:51 -0400 Subject: [PATCH 1/3] Start drawing the transit clock using libadwaita colors --- Cargo.lock | 35 +++++++++++++++++++++++ dashboard/Cargo.toml | 2 ++ dashboard/src/app_window.rs | 9 +++--- dashboard/src/components/transit_clock.rs | 34 ++++++++++++++++------ dashboard/src/drawing/pie_chart.rs | 12 ++++++-- dashboard/src/main.rs | 2 +- flake.nix | 1 + 7 files changed, 79 insertions(+), 16 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0679578..1739816 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -335,12 +335,14 @@ dependencies = [ "fluent", "fluent-ergonomics", "futures", + "gdk4", "geo-types", "gio", "glib", "gtk4", "ifc", "lazy_static", + "libadwaita", "memorycache", "reqwest", "serde", @@ -1263,6 +1265,39 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" +[[package]] +name = "libadwaita" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ab9c0843f9f23ff25634df2743690c3a1faffe0a190e60c490878517eb81abf" +dependencies = [ + "bitflags 1.3.2", + "gdk-pixbuf", + "gdk4", + "gio", + "glib", + "gtk4", + "libadwaita-sys", + "libc", + "pango", +] + +[[package]] +name = "libadwaita-sys" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4231cb2499a9f0c4cdfa4885414b33e39901ddcac61150bc0bb4ff8a57ede404" +dependencies = [ + "gdk4-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "gtk4-sys", + "libc", + "pango-sys", + "system-deps", +] + [[package]] name = "libc" version = "0.2.147" diff --git a/dashboard/Cargo.toml b/dashboard/Cargo.toml index 56d2f49..9ce0edb 100644 --- a/dashboard/Cargo.toml +++ b/dashboard/Cargo.toml @@ -6,6 +6,7 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +adw = { version = "0.4", package = "libadwaita", features = [ "v1_2" ] } cairo-rs = { version = "0.17" } chrono = { version = "0.4", features = ["serde"] } fluent-ergonomics = { path = "../fluent-ergonomics/" } @@ -14,6 +15,7 @@ futures = { version = "0.3" } geo-types = { path = "../geo-types/" } gio = { version = "0.17" } glib = { version = "0.17" } +gdk = { version = "0.6", package = "gdk4" } gtk = { version = "0.6", package = "gtk4" } ifc = { path = "../ifc/" } lazy_static = { version = "1.4" } diff --git a/dashboard/src/app_window.rs b/dashboard/src/app_window.rs index 66c5dc1..90e0cd6 100644 --- a/dashboard/src/app_window.rs +++ b/dashboard/src/app_window.rs @@ -2,19 +2,20 @@ use crate::{ components::{Date, TransitClock}, types::State, }; +use adw::prelude::AdwApplicationWindowExt; use gtk::prelude::*; #[derive(Clone)] pub struct ApplicationWindow { - pub window: gtk::ApplicationWindow, + pub window: adw::ApplicationWindow, pub date_label: Date, pub next_event: gtk::Label, pub transit_clock: TransitClock, } impl ApplicationWindow { - pub fn new(app: >k::Application) -> Self { - let window = gtk::ApplicationWindow::new(app); + pub fn new(app: &adw::Application) -> Self { + let window = adw::ApplicationWindow::new(app); let layout = gtk::Box::builder() .orientation(gtk::Orientation::Vertical) @@ -38,7 +39,7 @@ impl ApplicationWindow { let transit_clock = TransitClock::new(); layout.append(&transit_clock); - window.set_child(Some(&layout)); + window.set_content(Some(&layout)); Self { window, diff --git a/dashboard/src/components/transit_clock.rs b/dashboard/src/components/transit_clock.rs index 24a0d5b..be2f0de 100644 --- a/dashboard/src/components/transit_clock.rs +++ b/dashboard/src/components/transit_clock.rs @@ -43,6 +43,7 @@ impl TransitClock { s.set_draw_func({ let s = s.clone(); move |_, context, width, height| { + 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; @@ -51,20 +52,35 @@ impl TransitClock { 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() + let night_color = style_context.lookup_color("dark_5").unwrap(); + let day_color = style_context.lookup_color("blue_1").unwrap(); + + PieChart::new(&style_context) .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, + 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: night_color.red() as f64, + g: night_color.green() as f64, + b: night_color.blue() as f64, + }, }, - }] + Wedge { + start_angle: (PI * 2.) * sunrise.num_seconds() as f64 + / full_day, + end_angle: (PI * 2.) * sunset.num_seconds() as f64 / full_day, + color: Color { + r: day_color.red() as f64, + g: day_color.green() as f64, + b: day_color.blue() as f64, + }, + }, + ] .into_iter(), ) .draw(context); diff --git a/dashboard/src/drawing/pie_chart.rs b/dashboard/src/drawing/pie_chart.rs index 918deb5..d5d3183 100644 --- a/dashboard/src/drawing/pie_chart.rs +++ b/dashboard/src/drawing/pie_chart.rs @@ -1,4 +1,5 @@ use cairo::Context; +use gtk::{gdk::RGBA, prelude::*, StyleContext}; use std::f64::consts::PI; #[derive(Clone, Debug)] @@ -21,16 +22,19 @@ pub struct PieChart { center_x: f64, center_y: f64, radius: f64, + + border_color: RGBA, } impl PieChart { - pub fn new() -> Self { + pub fn new(style_context: &StyleContext) -> Self { Self { rotation: 0., wedges: vec![], center_x: 0., center_y: 0., radius: 0., + border_color: style_context.lookup_color("theme_fg_color").unwrap(), } } @@ -81,7 +85,11 @@ impl PieChart { }, ); - context.set_source_rgb(1., 1., 1.); + context.set_source_rgb( + self.border_color.red() as f64, + self.border_color.green() as f64, + self.border_color.blue() as f64, + ); context.arc(self.center_x, self.center_y, self.radius, 0., 2. * PI); let _ = context.stroke(); } diff --git a/dashboard/src/main.rs b/dashboard/src/main.rs index 3eaa100..26b66eb 100644 --- a/dashboard/src/main.rs +++ b/dashboard/src/main.rs @@ -70,7 +70,7 @@ pub struct Core { } pub fn main() { - let app = gtk::Application::builder() + let app = adw::Application::builder() .application_id("com.luminescent-dreams.dashboard") .resource_base_path("/com/luminescent-dreams/dashboard") .build(); diff --git a/flake.nix b/flake.nix index 9fdfd6e..3a4d491 100644 --- a/flake.nix +++ b/flake.nix @@ -23,6 +23,7 @@ pkgs.mkShell { name = "ld-tools-devshell"; buildInputs = [ + pkgs.libadwaita pkgs.clang pkgs.entr pkgs.glade -- 2.44.1 From 6a6dc3dc1e99dd8f79c561727c575437c37c434c Mon Sep 17 00:00:00 2001 From: Savanni D'Gerinel Date: Thu, 10 Aug 2023 09:11:05 -0400 Subject: [PATCH 2/3] Make the application update every now and then --- dashboard/src/main.rs | 23 ++++++++++++----------- dashboard/src/soluna_client.rs | 14 ++++++++++++-- 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/dashboard/src/main.rs b/dashboard/src/main.rs index 26b66eb..57a79a4 100644 --- a/dashboard/src/main.rs +++ b/dashboard/src/main.rs @@ -94,21 +94,22 @@ pub fn main() { async move { let soluna_client = SolunaClient::new(); - let transit = soluna_client - .request(latitude, longitude, Local::now()) - .await; - - let now = Local::now(); - let state = State { - date: IFC::from(now.date_naive().with_year(12023).unwrap()), - next_event: EVENTS.next_event(now.with_timezone(&Utc)).unwrap(), - transit: Some(transit), - }; loop { + let transit = soluna_client + .request(latitude.clone(), longitude.clone(), Local::now()) + .await; + + let now = Local::now(); + let state = State { + date: IFC::from(now.date_naive().with_year(12023).unwrap()), + next_event: EVENTS.next_event(now.with_timezone(&Utc)).unwrap(), + transit: Some(transit), + }; + 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)); + std::thread::sleep(std::time::Duration::from_secs(60)); } } }); diff --git a/dashboard/src/soluna_client.rs b/dashboard/src/soluna_client.rs index f705043..1f023c6 100644 --- a/dashboard/src/soluna_client.rs +++ b/dashboard/src/soluna_client.rs @@ -1,7 +1,7 @@ // 41.78, -71.41 // https://api.solunar.org/solunar/41.78,-71.41,20211029,-4 -use chrono::{DateTime, Duration, NaiveTime, Offset, TimeZone, Utc}; +use chrono::{DateTime, Duration, Local, NaiveTime, Offset, TimeZone, Timelike, Utc}; use geo_types::{Latitude, Longitude}; use memorycache::MemoryCache; use reqwest; @@ -111,7 +111,17 @@ impl SolunaClient { .and_then(|header| header.to_str().ok()) .and_then(|expiration| DateTime::parse_from_rfc2822(expiration).ok()) .map(|dt_local| DateTime::::from(dt_local)) - .unwrap_or(Utc::now() + Duration::seconds(3600)); + .unwrap_or( + Local::now() + .with_hour(0) + .and_then(|dt| dt.with_minute(0)) + .and_then(|dt| dt.with_second(0)) + .and_then(|dt| dt.with_nanosecond(0)) + .map(|dt| dt.with_timezone(&Utc)) + .unwrap() + + Duration::days(1), + ); + println!("expiration: {:?}", expiration); let soluna: SunMoonJs = response.json().await.unwrap(); (expiration, soluna) }) -- 2.44.1 From 4afdd16414515e94e87990c124515873f0f03632 Mon Sep 17 00:00:00 2001 From: Savanni D'Gerinel Date: Thu, 10 Aug 2023 09:16:37 -0400 Subject: [PATCH 3/3] Remove a stray print --- dashboard/src/soluna_client.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/dashboard/src/soluna_client.rs b/dashboard/src/soluna_client.rs index 1f023c6..c533104 100644 --- a/dashboard/src/soluna_client.rs +++ b/dashboard/src/soluna_client.rs @@ -121,7 +121,6 @@ impl SolunaClient { .unwrap() + Duration::days(1), ); - println!("expiration: {:?}", expiration); let soluna: SunMoonJs = response.json().await.unwrap(); (expiration, soluna) }) -- 2.44.1