gdritter repos knurling / 87ea1f9
Allow widget to contain mutable state that updates only occasionally Getty Ritter 3 years ago
4 changed file(s) with 64 addition(s) and 10 deletion(s). Collapse all Expand all
11 use crate::widgets as w;
2 use std::time;
23
34 mod defaults {
45 pub const BG_COLOR: (f64, f64, f64) = (0.1, 0.1, 0.1);
910 }
1011
1112 pub struct Config {
12 left: Vec<Box<dyn w::Widget>>,
13 right: Vec<Box<dyn w::Widget>>,
13 left: Vec<WidgetWrapper>,
14 right: Vec<WidgetWrapper>,
1415 bg_color: (f64, f64, f64),
1516 fg_color: (f64, f64, f64),
1617 font: String,
1718 height: i32,
1819 buffer: i32,
20 }
21
22 pub struct WidgetWrapper {
23 update: Option<(time::Duration, time::SystemTime)>,
24 widget: Box<dyn w::Widget>,
25 }
26
27 impl WidgetWrapper {
28 fn new(mut widget: Box<dyn w::Widget>) -> WidgetWrapper {
29 let update = if let Some(f) = widget.update_frequency() {
30 widget.update();
31 Some((time::Duration::new(f, 0), time::SystemTime::now()))
32 } else {
33 None
34 };
35 WidgetWrapper { update, widget }
36 }
37
38 fn update(&mut self) {
39 if let Some((freq, ref mut last)) = self.update {
40 if let Ok(since) = last.elapsed() {
41 if since > freq {
42 self.widget.update();
43 *last = time::SystemTime::now();
44 }
45 }
46 }
47 }
1948 }
2049
2150 pub fn color_from_hex(input: &str) -> Result<(f64, f64, f64), failure::Error> {
6594 if name == "sep" {
6695 target = &mut conf.right;
6796 } else {
68 target.push(w::mk_widget(name, section)?);
97 target.push(WidgetWrapper::new(w::mk_widget(name, section)?));
6998 }
7099 }
71100
142171
143172 let mut offset = 10;
144173 for w in self.left.iter() {
145 offset += 10 + w.draw(&d, w::Located::FromLeft(offset));
174 offset += 10 + w.widget.draw(&d, w::Located::FromLeft(offset));
146175 }
147176 offset = 10;
148177 for w in self.right.iter() {
149 offset += 10 + w.draw(&d, w::Located::FromRight(offset));
178 offset += 10 + w.widget.draw(&d, w::Located::FromRight(offset));
150179 }
151180
152181 Ok(())
182 }
183
184 pub fn update(&mut self) {
185 for w in self.left.iter_mut() { w.update() }
186 for w in self.right.iter_mut() { w.update() }
153187 }
154188
155189 pub fn font(&self) -> &str {
1313
1414 fn main() -> Result<(), failure::Error> {
1515 // set up the display and the window
16 let config = config::Config::find_config()?;
16 let mut config = config::Config::find_config()?;
1717 let height = config.get_height();
1818
1919 let mut d = Display::create()?;
142142 // otherwise, draw the thing!
143143 config.draw(&ctx, &layout, &input, *sz)?;
144144 }
145 config.update();
145146 }
146147
147148 Ok(())
66 pub struct MPD {
77 host: String,
88 port: usize,
9 last_state: State,
910 }
1011
1112 enum State {
1516
1617 impl MPD {
1718 pub fn new(host: String, port: usize) -> MPD {
18 MPD {host, port}
19 let last_state = State::Stopped;
20 MPD {host, port, last_state}
1921 }
2022
2123 fn get_song(&self) -> Result<State, failure::Error> {
6163
6264 impl Widget for MPD {
6365 fn draw(&self, d: &Drawing, loc: Located) -> i32 {
66 match self.last_state {
67 State::Playing(ref song) => loc.draw_text(d, &format!("[{}]", song)),
68 State::Stopped => loc.draw_text(d, &format!("[N/A]")),
69 }
70 }
71
72 fn update_frequency(&self) -> Option<u64> {
73 Some(5)
74 }
75
76 fn update(&mut self) {
6477 match self.get_song() {
65 Ok(State::Playing(song)) => loc.draw_text(d, &format!("[{}]", song)),
66 Ok(State::Stopped) => loc.draw_text(d, &format!("[N/A]")),
67 Err(_err) => loc.draw_text(d, &format!("[Error]")),
78 Ok(state) => self.last_state = state,
79 Err(err) => eprintln!("Failed to update MPD status: {}", err),
6880 }
6981 }
7082 }
3939 }
4040
4141 pub trait Widget {
42 fn update_frequency(&self) -> Option<u64> {
43 None
44 }
45
46 fn update(&mut self) {
47 }
48
4249 fn draw(&self, d: &Drawing, loc: Located) -> i32;
4350 }