gdritter repos knurling / 9c77396
Add the ability to use a TOML-based configuration file Getty Ritter 5 years ago
7 changed file(s) with 110 addition(s) and 85 deletion(s). Collapse all Expand all
139139 "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
140140 "pango 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
141141 "pangocairo 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
142 "toml 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
142143 "x11 2.18.1 (registry+https://github.com/rust-lang/crates.io-index)",
143144 ]
144145
251252 source = "registry+https://github.com/rust-lang/crates.io-index"
252253
253254 [[package]]
255 name = "serde"
256 version = "1.0.94"
257 source = "registry+https://github.com/rust-lang/crates.io-index"
258
259 [[package]]
254260 name = "syn"
255261 version = "0.15.29"
256262 source = "registry+https://github.com/rust-lang/crates.io-index"
279285 "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
280286 "redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)",
281287 "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
288 ]
289
290 [[package]]
291 name = "toml"
292 version = "0.5.1"
293 source = "registry+https://github.com/rust-lang/crates.io-index"
294 dependencies = [
295 "serde 1.0.94 (registry+https://github.com/rust-lang/crates.io-index)",
282296 ]
283297
284298 [[package]]
342356 "checksum quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)" = "cdd8e04bd9c52e0342b406469d494fcb033be4bdbe5c606016defbb1681411e1"
343357 "checksum redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)" = "423e376fffca3dfa06c9e9790a9ccd282fafb3cc6e6397d01dbf64f9bacc6b85"
344358 "checksum rustc-demangle 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "adacaae16d02b6ec37fdc7acfcddf365978de76d1983d3ee22afc260e1ca9619"
359 "checksum serde 1.0.94 (registry+https://github.com/rust-lang/crates.io-index)" = "076a696fdea89c19d3baed462576b8f6d663064414b5c793642da8dfeb99475b"
345360 "checksum syn 0.15.29 (registry+https://github.com/rust-lang/crates.io-index)" = "1825685f977249735d510a242a6727b46efe914bb67e38d30c071b1b72b1d5c2"
346361 "checksum synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "73687139bf99285483c96ac0add482c3776528beac1d97d444f6e91f203a2015"
347362 "checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f"
363 "checksum toml 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b8c96d7873fa7ef8bdeb3a9cda3ac48389b4154f32b9803b4bc26220b677b039"
348364 "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
349365 "checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0"
350366 "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
88 cairo-rs = "0.6"
99 pango = "0.6"
1010 pangocairo = "0.7"
11 # time = "0.1"
1211 chrono = "*"
1312 libc = "0.2"
1413 failure = "*"
14 toml = "0.5"
1515
1616 [dependencies.cairo-sys-rs]
1717 version = "0.8"
1 background = "ff0000"
2
3 [[widgets]]
4 name = "stdin"
5
6 [[widgets]]
7 name = "sep"
8
9 [[widgets]]
10 name = "time"
1 use crate::widgets as w;
2
3 pub struct Config {
4 left: Vec<Box<w::Widget>>,
5 right: Vec<Box<w::Widget>>,
6 }
7
8 impl Config {
9 pub fn from_toml(input: toml::Value) -> Result<Config, failure::Error> {
10 let mut conf = Config { left: Vec::new(), right: Vec::new() };
11 let widgets = &input.as_table().ok_or(format_err!("invalid config"))?["widgets"];
12 let mut target = &mut conf.left;
13 for section in widgets.as_array().ok_or(format_err!("invalid config"))? {
14 let section = section.as_table().ok_or(format_err!("invalid config"))?;
15 match section["name"].as_str().ok_or(format_err!(""))? {
16 "box" => target.push(Box::new(w::SmallBox)),
17 "battery" => target.push(Box::new(w::Battery::new()?)),
18 "sep" => target = &mut conf.right,
19 "stdin" => target.push(Box::new(w::Stdin::new())),
20 "time" => target.push(Box::new(w::Time::new())),
21 _ => (),
22 }
23 }
24 Ok(conf)
25 }
26
27 pub fn from_file(path: impl AsRef<std::path::Path>) -> Result<Config, failure::Error> {
28 let body = std::fs::read_to_string(path)?;
29 let val = body.parse::<toml::Value>()?;
30 Config::from_toml(val)
31 }
32
33 pub fn draw(&self, ctx: &cairo::Context, layout: &pango::Layout, stdin: &str, size: w::Size) -> Result<(), failure::Error>{
34 // the background is... gray-ish? this'll be configurable eventually
35 ctx.set_source_rgb(0.1, 0.1, 0.1);
36 ctx.paint();
37
38 // and the text is white
39 ctx.set_source_rgb(1.0, 1.0, 1.0);
40
41 // set up a struct with everything that widgets need to draw
42 let d = w::Drawing {
43 ctx: ctx,
44 lyt: &layout,
45 size,
46 stdin,
47 };
48
49 let mut offset = 10;
50 for w in self.left.iter() {
51 offset += 10 + w.draw(&d, w::Located::FromLeft(offset));
52 }
53 offset = 10;
54 for w in self.right.iter() {
55 offset += 10 + w.draw(&d, w::Located::FromRight(offset));
56 }
57
58 Ok(())
59 }
60 }
11 #[macro_use]
22 extern crate failure;
33
4 mod config;
45 mod widgets;
56 mod window;
67
78 use std::os::unix::io::AsRawFd;
89 use pango::LayoutExt;
910
10 use widgets::Widget;
11 use window::{Display,Event,Size,Window};
11 use widgets::Size;
12 use window::{Display,Event,Window};
1213
1314 fn main() -> Result<(), failure::Error> {
1415 // set up the display and the window
16 let config = config::Config::from_file("sample.toml")?;
1517 let mut d = Display::create()?;
1618 let mut ws = Vec::new();
1719 for (x_off, wd) in d.get_widths()? {
7779 layout.set_font_description(&font);
7880
7981 // do an initial pass at drawing the bar!
80 draw(&ctx, &layout, &input, w.size())?;
82 config.draw(&ctx, &layout, &input, w.size())?;
8183
8284 ctxs.push((ctx, layout, w.size()));
8385 }
116118 break;
117119 }
118120 for (ctx, layout, sz) in ctxs.iter() {
119 draw(&ctx, &layout, &input, *sz)?;
121 config.draw(&ctx, &layout, &input, *sz)?;
120122 }
121123 }
122124
133135
134136 for (ctx, layout, sz) in ctxs.iter() {
135137 // otherwise, draw the thing!
136 draw(&ctx, &layout, &input, *sz)?;
138 config.draw(&ctx, &layout, &input, *sz)?;
137139 }
138140 }
139141
140142 Ok(())
141143 }
142
143
144 /// Do our Cairo drawing. This needs to be refactored to allow for
145 /// more configurability in terms of what gets written!
146 fn draw(
147 ctx: &cairo::Context,
148 layout: &pango::Layout,
149 left: &str,
150 size: Size)
151 -> Result<(), failure::Error>
152 {
153 // the background is... gray-ish? this'll be configurable eventually
154 ctx.set_source_rgb(0.1, 0.1, 0.1);
155 ctx.paint();
156
157 // and the text is white
158 ctx.set_source_rgb(1.0, 1.0, 1.0);
159
160 // set up a struct with everything that widgets need to draw
161 let drawing = widgets::Drawing {
162 ctx: ctx,
163 lyt: &layout,
164 size,
165 };
166 // set up our widgets
167 let text = widgets::Text::new(left);
168 let time = widgets::Time::new();
169 // let bat = widgets::Battery::new()?;
170
171 // and create a 'config' which tells us which widgets to draw from
172 // the left, and which from the right
173 let config = widgets::Config {
174 left: vec![
175 &text as &Widget,
176 ],
177 right: vec![
178 // &bat as &Widget,
179 &time as &Widget,
180 ],
181 };
182 // and draw them!
183 config.draw(&drawing);
184
185 Ok(())
186 }
1 use crate::window::Size;
21 use pango::LayoutExt;
2
3 #[derive(Debug,Clone,Copy)]
4 pub struct Size {
5 pub wd: i32,
6 pub ht: i32,
7 pub xo: i32,
8 pub yo: i32,
9 }
310
411 #[derive(Debug,Clone,Copy)]
512 pub enum Located {
613 FromLeft(i32),
714 FromRight(i32),
8 }
9
10 pub struct Config<'r> {
11 pub left: Vec<&'r Widget>,
12 pub right: Vec<&'r Widget>,
13 }
14
15 impl<'r> Config<'r> {
16 pub fn draw(&self, d: &Drawing) {
17 let mut offset = 10;
18 for w in self.left.iter() {
19 offset += 10 + w.draw(d, Located::FromLeft(offset));
20 }
21 offset = 10;
22 for w in self.right.iter() {
23 offset += 10 + w.draw(d, Located::FromRight(offset));
24 }
25 }
2615 }
2716
2817 impl Located {
4635 pub ctx: &'t cairo::Context,
4736 pub lyt: &'t pango::Layout,
4837 pub size: Size,
38 pub stdin: &'t str,
4939 }
5040
5141 pub trait Widget {
7464
7565
7666 #[derive(Debug)]
77 pub struct Text<'t> {
78 text: &'t str,
79 }
67 pub struct Stdin;
8068
81 impl<'t> Text<'t> {
82 pub fn new(text: &str) -> Text {
83 Text { text }
69 impl Stdin {
70 pub fn new() -> Stdin {
71 Stdin
8472 }
8573 }
8674
87 impl<'t> Widget for Text<'t> {
75 impl Widget for Stdin {
8876 fn draw(&self, d: &Drawing, loc: Located) -> i32 {
89 loc.draw_text(d, &self.text)
77 loc.draw_text(d, &d.stdin)
9078 }
9179 }
9280
44 use std::{mem,ptr};
55 use std::os::raw::{c_int,c_uchar};
66
7 #[derive(Debug,Clone,Copy)]
8 pub struct Size {
9 pub wd: i32,
10 pub ht: i32,
11 pub xo: i32,
12 pub yo: i32,
13 }
7 use crate::widgets::Size;
148
159 pub struct Display {
1610 pub display: *mut xlib::_XDisplay,