Hook into the libadwaita styles #55
|
@ -335,12 +335,14 @@ dependencies = [
|
||||||
"fluent",
|
"fluent",
|
||||||
"fluent-ergonomics",
|
"fluent-ergonomics",
|
||||||
"futures",
|
"futures",
|
||||||
|
"gdk4",
|
||||||
"geo-types",
|
"geo-types",
|
||||||
"gio",
|
"gio",
|
||||||
"glib",
|
"glib",
|
||||||
"gtk4",
|
"gtk4",
|
||||||
"ifc",
|
"ifc",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
|
"libadwaita",
|
||||||
"memorycache",
|
"memorycache",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"serde",
|
"serde",
|
||||||
|
@ -1263,6 +1265,39 @@ version = "0.5.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8"
|
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]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.147"
|
version = "0.2.147"
|
||||||
|
|
|
@ -6,6 +6,7 @@ edition = "2018"
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
adw = { version = "0.4", package = "libadwaita", features = [ "v1_2" ] }
|
||||||
cairo-rs = { version = "0.17" }
|
cairo-rs = { version = "0.17" }
|
||||||
chrono = { version = "0.4", features = ["serde"] }
|
chrono = { version = "0.4", features = ["serde"] }
|
||||||
fluent-ergonomics = { path = "../fluent-ergonomics/" }
|
fluent-ergonomics = { path = "../fluent-ergonomics/" }
|
||||||
|
@ -14,6 +15,7 @@ futures = { version = "0.3" }
|
||||||
geo-types = { path = "../geo-types/" }
|
geo-types = { path = "../geo-types/" }
|
||||||
gio = { version = "0.17" }
|
gio = { version = "0.17" }
|
||||||
glib = { version = "0.17" }
|
glib = { version = "0.17" }
|
||||||
|
gdk = { version = "0.6", package = "gdk4" }
|
||||||
gtk = { version = "0.6", package = "gtk4" }
|
gtk = { version = "0.6", package = "gtk4" }
|
||||||
ifc = { path = "../ifc/" }
|
ifc = { path = "../ifc/" }
|
||||||
lazy_static = { version = "1.4" }
|
lazy_static = { version = "1.4" }
|
||||||
|
|
|
@ -2,19 +2,20 @@ use crate::{
|
||||||
components::{Date, TransitClock},
|
components::{Date, TransitClock},
|
||||||
types::State,
|
types::State,
|
||||||
};
|
};
|
||||||
|
use adw::prelude::AdwApplicationWindowExt;
|
||||||
use gtk::prelude::*;
|
use gtk::prelude::*;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct ApplicationWindow {
|
pub struct ApplicationWindow {
|
||||||
pub window: gtk::ApplicationWindow,
|
pub window: adw::ApplicationWindow,
|
||||||
pub date_label: Date,
|
pub date_label: Date,
|
||||||
pub next_event: gtk::Label,
|
pub next_event: gtk::Label,
|
||||||
pub transit_clock: TransitClock,
|
pub transit_clock: TransitClock,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ApplicationWindow {
|
impl ApplicationWindow {
|
||||||
pub fn new(app: >k::Application) -> Self {
|
pub fn new(app: &adw::Application) -> Self {
|
||||||
let window = gtk::ApplicationWindow::new(app);
|
let window = adw::ApplicationWindow::new(app);
|
||||||
|
|
||||||
let layout = gtk::Box::builder()
|
let layout = gtk::Box::builder()
|
||||||
.orientation(gtk::Orientation::Vertical)
|
.orientation(gtk::Orientation::Vertical)
|
||||||
|
@ -38,7 +39,7 @@ impl ApplicationWindow {
|
||||||
let transit_clock = TransitClock::new();
|
let transit_clock = TransitClock::new();
|
||||||
layout.append(&transit_clock);
|
layout.append(&transit_clock);
|
||||||
|
|
||||||
window.set_child(Some(&layout));
|
window.set_content(Some(&layout));
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
window,
|
window,
|
||||||
|
|
|
@ -43,6 +43,7 @@ impl TransitClock {
|
||||||
s.set_draw_func({
|
s.set_draw_func({
|
||||||
let s = s.clone();
|
let s = s.clone();
|
||||||
move |_, context, width, height| {
|
move |_, context, width, height| {
|
||||||
|
let style_context = WidgetExt::style_context(&s);
|
||||||
let center_x = width as f64 / 2.;
|
let center_x = width as f64 / 2.;
|
||||||
let center_y = height as f64 / 2.;
|
let center_y = height as f64 / 2.;
|
||||||
let radius = width.min(height) as f64 / 2. * 0.9;
|
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 sunrise = info.sunrise - NaiveTime::from_hms_opt(0, 0, 0).unwrap();
|
||||||
let sunset = info.sunset - 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)
|
.center(center_x, center_y)
|
||||||
.radius(radius)
|
.radius(radius)
|
||||||
.rotation(-PI / 2.)
|
.rotation(-PI / 2.)
|
||||||
.wedges(
|
.wedges(
|
||||||
vec![Wedge {
|
vec![
|
||||||
start_angle: (PI * 2.) * sunset.num_seconds() as f64 / full_day,
|
Wedge {
|
||||||
end_angle: (PI * 2.) * sunrise.num_seconds() as f64 / full_day,
|
start_angle: (PI * 2.) * sunset.num_seconds() as f64 / full_day,
|
||||||
color: Color {
|
end_angle: (PI * 2.) * sunrise.num_seconds() as f64 / full_day,
|
||||||
r: 0.1,
|
color: Color {
|
||||||
g: 0.1,
|
r: night_color.red() as f64,
|
||||||
b: 0.8,
|
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(),
|
.into_iter(),
|
||||||
)
|
)
|
||||||
.draw(context);
|
.draw(context);
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use cairo::Context;
|
use cairo::Context;
|
||||||
|
use gtk::{gdk::RGBA, prelude::*, StyleContext};
|
||||||
use std::f64::consts::PI;
|
use std::f64::consts::PI;
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
|
@ -21,16 +22,19 @@ pub struct PieChart {
|
||||||
center_x: f64,
|
center_x: f64,
|
||||||
center_y: f64,
|
center_y: f64,
|
||||||
radius: f64,
|
radius: f64,
|
||||||
|
|
||||||
|
border_color: RGBA,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PieChart {
|
impl PieChart {
|
||||||
pub fn new() -> Self {
|
pub fn new(style_context: &StyleContext) -> Self {
|
||||||
Self {
|
Self {
|
||||||
rotation: 0.,
|
rotation: 0.,
|
||||||
wedges: vec![],
|
wedges: vec![],
|
||||||
center_x: 0.,
|
center_x: 0.,
|
||||||
center_y: 0.,
|
center_y: 0.,
|
||||||
radius: 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);
|
context.arc(self.center_x, self.center_y, self.radius, 0., 2. * PI);
|
||||||
let _ = context.stroke();
|
let _ = context.stroke();
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,7 +70,7 @@ pub struct Core {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
let app = gtk::Application::builder()
|
let app = adw::Application::builder()
|
||||||
.application_id("com.luminescent-dreams.dashboard")
|
.application_id("com.luminescent-dreams.dashboard")
|
||||||
.resource_base_path("/com/luminescent-dreams/dashboard")
|
.resource_base_path("/com/luminescent-dreams/dashboard")
|
||||||
.build();
|
.build();
|
||||||
|
@ -94,21 +94,22 @@ pub fn main() {
|
||||||
async move {
|
async move {
|
||||||
let soluna_client = SolunaClient::new();
|
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 {
|
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() {
|
if let Some(ref gtk_tx) = *core.tx.read().unwrap() {
|
||||||
let _ = gtk_tx.send(Message::Refresh(state.clone()));
|
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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// 41.78, -71.41
|
// 41.78, -71.41
|
||||||
// https://api.solunar.org/solunar/41.78,-71.41,20211029,-4
|
// 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 geo_types::{Latitude, Longitude};
|
||||||
use memorycache::MemoryCache;
|
use memorycache::MemoryCache;
|
||||||
use reqwest;
|
use reqwest;
|
||||||
|
@ -111,7 +111,16 @@ impl SolunaClient {
|
||||||
.and_then(|header| header.to_str().ok())
|
.and_then(|header| header.to_str().ok())
|
||||||
.and_then(|expiration| DateTime::parse_from_rfc2822(expiration).ok())
|
.and_then(|expiration| DateTime::parse_from_rfc2822(expiration).ok())
|
||||||
.map(|dt_local| DateTime::<Utc>::from(dt_local))
|
.map(|dt_local| DateTime::<Utc>::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),
|
||||||
|
);
|
||||||
let soluna: SunMoonJs = response.json().await.unwrap();
|
let soluna: SunMoonJs = response.json().await.unwrap();
|
||||||
(expiration, soluna)
|
(expiration, soluna)
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in New Issue