Browse Source

Make widgets configurable

Thomas Dy 7 years ago
parent
commit
031071ba81
5 changed files with 58 additions and 38 deletions
  1. 2 2
      src/config.rs
  2. 19 23
      src/main.rs
  3. 11 6
      src/widgets/mod.rs
  4. 9 3
      src/widgets/spacer.rs
  5. 17 4
      src/widgets/wm.rs

+ 2 - 2
src/config.rs

@@ -1,8 +1,8 @@
-extern crate toml;
-
 use std::fs::File;
 use std::io::prelude::*;
 
+use toml;
+
 pub type Config = toml::Value;
 
 pub fn load(path: &str) -> Config {

+ 19 - 23
src/main.rs

@@ -1,6 +1,7 @@
 extern crate xcb;
 extern crate mpd;
 extern crate simple_signal;
+extern crate toml;
 
 extern crate freetype;
 extern crate fontconfig_sys;
@@ -50,32 +51,27 @@ fn main() {
         }
 
         let mut panel = ui::panel::Panel::new(conn, &cfg);
-        let params = widgets::WidgetParams {
-            id: "".to_string(),
-            context: panel.make_context(),
-            tx: tx.clone(),
-            config: cfg.clone()
-        };
 
-        let left_widgets: Vec<widgets::WidgetConstructor> = vec![
-            widgets::bspwm,
-            widgets::spacer,
-            widgets::title
-        ];
+        if let Some(&toml::Value::Array(ref configs)) = cfg.lookup("widget") {
+            for config in configs {
+                let type_ = config.lookup("type").and_then(|v| v.as_str()).unwrap();
+                let align = config.lookup("align").and_then(|v| v.as_str()).unwrap_or("left");
 
-        let right_widgets: Vec<widgets::WidgetConstructor> = vec![
-            widgets::mpd,
-            widgets::sensors,
-            widgets::tray
-        ];
+                let params = widgets::WidgetParams {
+                    id: "".to_string(),
+                    context: panel.make_context(),
+                    tx: tx.clone(),
+                    config: config.clone()
+                };
 
-        for cons in left_widgets {
-            let widget = cons(params.clone());
-            panel.add_left_widget(widget);
-        }
-        for cons in right_widgets {
-            let widget = cons(params.clone());
-            panel.add_right_widget(widget);
+                if let Some(cons) = widgets::by_type(type_) {
+                    let widget = cons(params.clone());
+                    match align {
+                        "right" => panel.add_right_widget(widget),
+                        _ => panel.add_left_widget(widget)
+                    }
+                }
+            }
         }
 
         panel.create();

+ 11 - 6
src/widgets/mod.rs

@@ -14,12 +14,17 @@ mod wm;
 mod spacer;
 mod music;
 
-pub use self::title::title;
-pub use self::tray::tray;
-pub use self::sensors::sensors;
-pub use self::spacer::spacer;
-pub use self::music::mpd;
-pub use self::wm::bspwm;
+pub fn by_type(name: &str) -> Option<WidgetConstructor> {
+    match name {
+        "title" => Some(title::title),
+        "tray" => Some(tray::tray),
+        "sensors" => Some(sensors::sensors),
+        "spacer" => Some(spacer::spacer),
+        "mpd" => Some(music::mpd),
+        "bspwm" => Some(wm::bspwm),
+        _ => None
+    }
+}
 
 pub type MessageSender = mpsc::Sender<Message>;
 

+ 9 - 3
src/widgets/spacer.rs

@@ -8,12 +8,18 @@ pub struct Spacer {
 }
 
 pub fn spacer(params: WidgetParams) -> Box<Widget> {
-    // TODO parse config
     let mut context = params.context;
-    context.set_bg_color(color::GREY);
+    let width = params.config.lookup("width")
+        .and_then(|v| v.as_integer())
+        .expect("spacer requires a width definition");
+    let color = params.config.lookup("color")
+        .and_then(|v| v.as_str())
+        .and_then(|s| color::from_str(s))
+        .expect("spacer requires a color definition");
+    context.set_bg_color(color);
     let widget = Spacer {
         context: context,
-        width: 4
+        width: width as u16
     };
     Box::new(widget)
 }

+ 17 - 4
src/widgets/wm.rs

@@ -3,6 +3,8 @@ use std::io::BufReader;
 use std::process::{Command, Stdio};
 use std::thread;
 
+use xcb::render::Color;
+
 use ui::context::Context;
 use ui::color;
 use widgets::{Message, MessageSender, Update, Widget, WidgetParams};
@@ -26,20 +28,31 @@ impl Desktop {
 pub struct Bspwm {
     context: Context,
     tx: MessageSender,
+    urgent_color: Color,
+    selected_color: Color,
     desktops: Vec<Desktop>
 }
 
 pub fn bspwm(params: WidgetParams) -> Box<Widget> {
+    let urgent_color = params.config.lookup("urgent_color")
+        .and_then(|v| v.as_str())
+        .and_then(|s| color::from_str(s))
+        .unwrap_or(color::RED);
+    let selected_color = params.config.lookup("selected_color")
+        .and_then(|v| v.as_str())
+        .and_then(|s| color::from_str(s))
+        .unwrap_or(color::LIGHT_GREEN);
     let widget = Bspwm {
         context: params.context,
         tx: params.tx,
-        desktops: vec![]
+        desktops: vec![],
+        urgent_color: urgent_color,
+        selected_color: selected_color
     };
     Box::new(widget)
 }
 
 impl Bspwm {
-
     fn parse_bspwm(&mut self, line: &str) {
         let (kind, line) = line.split_at(1);
         if kind != "W" { return };
@@ -90,10 +103,10 @@ impl Widget for Bspwm {
     fn render(&mut self, x: u16, _w: u16) {
         for desktop in self.desktops.iter() {
             let color = if desktop.selected {
-                color::LIGHT_GREEN
+                self.selected_color
             }
             else if desktop.urgent {
-                color::RED
+                self.urgent_color
             }
             else {
                 self.context.default_bg_color