Switch battery check to be mutable-update form
Getty Ritter
4 years ago
90 | 90 | let section = section |
91 | 91 | .as_table() |
92 | 92 | .ok_or_else(|| format_err!("invalid config"))?; |
93 |
let name = section["name"] |
|
93 | let name = section["name"] | |
94 | .as_str() | |
95 | .ok_or_else(|| format_err!("invalid config"))?; | |
94 | 96 | if name == "sep" { |
95 | 97 | target = &mut conf.right; |
96 | 98 | } else { |
182 | 184 | } |
183 | 185 | |
184 | 186 | 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() } | |
187 | for w in self.left.iter_mut() { | |
188 | w.update() | |
189 | } | |
190 | for w in self.right.iter_mut() { | |
191 | w.update() | |
192 | } | |
187 | 193 | } |
188 | 194 | |
189 | 195 | pub fn font(&self) -> &str { |
208 | 214 | layout.set_font_description(&font); |
209 | 215 | layout.set_text("lj"); |
210 | 216 | let (_, h) = layout.get_size(); |
211 | (h / pango::SCALE) | |
212 | } | |
213 | } | |
217 | h / pango::SCALE | |
218 | } | |
219 | } |
1 |
use crate::widgets::widget::{ |
|
1 | use crate::widgets::widget::{Drawing, Located, Widget}; | |
2 | 2 | |
3 | 3 | pub struct Battery { |
4 | 4 | file_list: Vec<std::path::PathBuf>, |
5 | 5 | charging: Option<std::path::PathBuf>, |
6 | last_status: f64, | |
7 | last_charging: bool, | |
6 | 8 | } |
7 | 9 | |
8 | 10 | impl Battery { |
19 | 21 | } |
20 | 22 | } |
21 | 23 | let ac_path = std::path::Path::new("/sys/class/power_supply/AC/online"); |
22 | ||
23 | 24 | Ok(Battery { |
24 | 25 | file_list: batteries, |
25 | 26 | charging: if ac_path.exists() { |
27 | 28 | } else { |
28 | 29 | None |
29 | 30 | }, |
31 | last_status: 1.0f64, | |
32 | last_charging: false, | |
30 | 33 | }) |
31 | 34 | } |
32 | 35 | |
55 | 58 | |
56 | 59 | impl Widget for Battery { |
57 | 60 | fn draw(&self, d: &Drawing, loc: Located) -> i32 { |
58 |
let amt = self. |
|
61 | let amt = self.last_status; | |
59 | 62 | let sz = d.size.ht - (d.buffer as i32 * 2); |
60 | 63 | let x = loc.target_x(d, sz); |
61 | 64 | match amt { |
62 | _ if self.is_charging().unwrap_or(false) => d.ctx.set_source_rgb(0.5, 0.5, 1.0), | |
63 | Ok(x) if x < 0.1 => d.ctx.set_source_rgb(1.0, 0.0, 0.0), | |
64 | Ok(x) if x < 0.5 => d.ctx.set_source_rgb(1.0, 1.0, 0.0), | |
65 | Ok(_) => d.ctx.set_source_rgb(0.0, 1.0, 0.5), | |
66 |
|
|
65 | _ if self.last_charging => d.ctx.set_source_rgb(0.5, 0.5, 1.0), | |
66 | x if x < 0.1 => d.ctx.set_source_rgb(1.0, 0.0, 0.0), | |
67 | x if x < 0.5 => d.ctx.set_source_rgb(1.0, 1.0, 0.0), | |
68 | _ => d.ctx.set_source_rgb(0.0, 1.0, 0.5), | |
67 | 69 | } |
68 | 70 | |
69 | 71 | d.ctx.rectangle( |
70 | 72 | x, |
71 | 73 | d.buffer * 2.0, |
72 |
sz as f64 * amt |
|
74 | sz as f64 * amt, | |
73 | 75 | sz as f64 - d.buffer * 2.0, |
74 | 76 | ); |
75 | 77 | d.ctx.fill(); |
81 | 83 | |
82 | 84 | sz |
83 | 85 | } |
86 | ||
87 | fn update_frequency(&self) -> Option<u64> { | |
88 | Some(10) | |
89 | } | |
90 | ||
91 | fn update(&mut self) { | |
92 | if let Ok(status) = self.read_status() { | |
93 | self.last_status = status; | |
94 | } | |
95 | ||
96 | if let Ok(charging) = self.is_charging() { | |
97 | self.last_charging = charging; | |
98 | } | |
99 | } | |
84 | 100 | } |
3 | 3 | pub mod standard; |
4 | 4 | pub mod widget; |
5 | 5 | |
6 |
pub use crate::widgets::widget::{ |
|
6 | pub use crate::widgets::widget::{Drawing, Located, Size, Widget}; | |
7 | 7 | |
8 |
const ALL_WIDGETS: [( |
|
8 | const ALL_WIDGETS: [( | |
9 | &str, | |
10 | &dyn Fn(&toml::map::Map<String, toml::Value>) -> Result<Box<dyn Widget>, failure::Error>, | |
11 | ); 6] = [ | |
9 | 12 | ("box", &|_| Ok(Box::new(standard::Time::new()))), |
10 | 13 | ("battery", &|_| Ok(Box::new(battery::Battery::new()?))), |
11 | 14 | ("caesura", &|_| Ok(Box::new(standard::Caesura))), |
12 | 15 | ("mpd", &|config| { |
13 | let host = config["host"].as_str().ok_or_else(|| format_err!("MPD host should be a string"))?; | |
14 | let port = config["port"].as_integer().ok_or_else(|| format_err!("MPD port should be an integer"))?; | |
16 | let host = config["host"] | |
17 | .as_str() | |
18 | .ok_or_else(|| format_err!("MPD host should be a string"))?; | |
19 | let port = config["port"] | |
20 | .as_integer() | |
21 | .ok_or_else(|| format_err!("MPD port should be an integer"))?; | |
15 | 22 | Ok(Box::new(mpd::MPD::new(host.to_string(), port as usize))) |
16 | 23 | }), |
17 | 24 | ("stdin", &|_| Ok(Box::new(standard::Stdin::new()))), |
18 | 25 | ("time", &|_| Ok(Box::new(standard::Time::new()))), |
19 | 26 | ]; |
20 | 27 | |
21 |
pub fn mk_widget( |
|
28 | pub fn mk_widget( | |
29 | name: &str, | |
30 | section: &toml::map::Map<String, toml::Value>, | |
31 | ) -> Result<Box<dyn Widget>, failure::Error> { | |
22 | 32 | for (n, f) in ALL_WIDGETS.iter() { |
23 | 33 | if n == &name { |
24 | 34 | return f(section); |
1 |
use crate::widgets::widget::{ |
|
1 | use crate::widgets::widget::{Drawing, Located, Widget}; | |
2 | 2 | |
3 |
use std::io::{ |
|
3 | use std::io::{BufRead, BufReader, Write}; | |
4 | 4 | use std::net::TcpStream; |
5 | 5 | |
6 | 6 | pub struct MPD { |
17 | 17 | impl MPD { |
18 | 18 | pub fn new(host: String, port: usize) -> MPD { |
19 | 19 | let last_state = State::Stopped; |
20 |
MPD { |
|
20 | MPD { | |
21 | host, | |
22 | port, | |
23 | last_state, | |
24 | } | |
21 | 25 | } |
22 | 26 | |
23 | 27 | fn get_song(&self) -> Result<State, failure::Error> { |