Browse Source

Implement sensors widget

Thomas Dy 7 years ago
parent
commit
113ba3f519
6 changed files with 81 additions and 27 deletions
  1. 1 1
      src/main.rs
  2. 2 26
      src/sensors/mod.rs
  3. 17 0
      src/ui/mod.rs
  4. 6 0
      src/ui/panel.rs
  5. 54 0
      src/ui/sensors.rs
  6. 1 0
      src/ui/widget.rs

+ 1 - 1
src/main.rs

@@ -6,7 +6,7 @@ extern crate chan_signal;
 extern crate freetype;
 extern crate fontconfig_sys;
 
-//mod sensors;
+mod sensors;
 //mod comm;
 mod config;
 //mod bspwm;

+ 2 - 26
src/sensors/mod.rs

@@ -5,11 +5,7 @@ mod netspeed;
 mod time;
 mod temperature;
 
-use comm;
-use comm::Channel;
 use config::Config;
-use std::thread;
-use std::time::Duration;
 use self::battery::BatterySensor;
 use self::tp_battery::TPBatterySensor;
 use self::disk::DiskSensor;
@@ -23,7 +19,7 @@ pub trait Sensor {
     fn process(&mut self);
 }
 
-pub fn sensors(tx: &Channel, config: &Config) {
+pub fn sensor_list(config: &Config) -> Vec<Box<Sensor>> {
     let zone = config.lookup("sensors.thermal_zone").unwrap();
     let zone = zone.as_str().unwrap();
 
@@ -49,25 +45,5 @@ pub fn sensors(tx: &Channel, config: &Config) {
         items.iter().flat_map(|elem| elem.as_str()).collect::<Vec<&str>>()
     });
     tp_bat.map(|bats| sensors.insert(1, Box::new(TPBatterySensor::new(&bats))));
-
-    let delay = Duration::from_secs(1);
-    loop {
-        let status = sensors.iter_mut()
-            .map(|sensor| {
-                sensor.process();
-                format!(
-                    "%{{B#666666}} {} %{{B-}} {}",
-                    sensor.icon(),
-                    sensor.status()
-                )
-            })
-            .collect::<Vec<String>>();
-
-        comm::send(tx, "sensors", &reduce(status));
-        thread::sleep(delay);
-    }
-}
-
-fn reduce(arr: Vec<String>) -> String {
-    arr.into_iter().fold("".to_string(), |acc, elem| format!("{} {}", acc, elem))
+    sensors
 }

+ 17 - 0
src/ui/mod.rs

@@ -3,6 +3,7 @@ mod panel;
 mod ext;
 mod title;
 mod tray;
+mod sensors;
 mod util;
 mod widget;
 mod x11;
@@ -12,6 +13,7 @@ use chan_signal;
 use config::Config;
 
 use std::thread;
+use std::time;
 
 pub const SIZE: u16 = 20;
 
@@ -30,6 +32,7 @@ pub fn ui_main(signal: chan::Receiver<chan_signal::Signal>, cfg: &Config) -> i32
             });
         }
 
+        let (update_tx, update_rx) = chan::sync(10);
         let (mut panel, panel_rx) = panel::Panel::new(conn, cfg);
 
         let title = title::Title::new(panel.conn.clone(), panel.make_draw_context());
@@ -38,13 +41,27 @@ pub fn ui_main(signal: chan::Receiver<chan_signal::Signal>, cfg: &Config) -> i32
         let tray = tray::Tray::new(panel.tx.clone(), panel.conn.clone(), panel.window);
         panel.add_right_widget(Box::new(tray));
 
+        let sensors = sensors::Sensors::new(panel.make_draw_context(), cfg);
+        panel.add_right_widget(Box::new(sensors));
+
         panel.create();
 
+        thread::spawn(move || {
+            loop {
+                update_tx.send(());
+                thread::sleep(time::Duration::from_secs(1));
+            }
+        });
+
         loop {
             chan_select!(
                 panel_rx.recv() => {
                     panel.relayout();
                 },
+                update_rx.recv() => {
+                    panel.update();
+                    panel.relayout();
+                },
                 rx.recv() -> event => {
                     if panel.handle_event(event.unwrap()) {
                         println!("Exiting");

+ 6 - 0
src/ui/panel.rs

@@ -134,6 +134,12 @@ impl Panel {
         self.right_widgets.push(widget);
     }
 
+    pub fn update(&mut self) {
+        for widget in self.widgets_iter() {
+            widget.update()
+        }
+    }
+
     pub fn relayout(&mut self) {
         let color = xcb::render::Color::new(0, 0, 0, 0xFFFF);
         xcb::render::fill_rectangles(

+ 54 - 0
src/ui/sensors.rs

@@ -0,0 +1,54 @@
+use config::Config;
+use super::super::sensors;
+use super::super::sensors::Sensor;
+use ui::widget;
+
+const MARGIN: u16 = 7;
+
+pub struct Sensors {
+    context: widget::DrawContext,
+    sensors: Vec<Box<Sensor>>
+}
+
+impl Sensors {
+    pub fn new(context: widget::DrawContext, config: &Config) -> Sensors {
+        Sensors {
+            context: context,
+            sensors: sensors::sensor_list(config)
+        }
+    }
+}
+
+impl widget::Widget for Sensors {
+    fn render(&mut self, x: u16) {
+        let mut offset = x;
+        for ref sensor in self.sensors.iter() {
+            let icon_width = self.context.measure_text(&sensor.icon());
+            let status_width = self.context.measure_text(&sensor.status());
+
+            self.context.set_bg_color(0x6666, 0x6666, 0x6666, 0xFFFF);
+            self.context.draw_bg(offset, icon_width + MARGIN * 2);
+            self.context.draw_text(&sensor.icon(), offset + MARGIN);
+            offset += icon_width + MARGIN * 2;
+
+            self.context.set_bg_color(0x0, 0x0, 0x0, 0xFFFF);
+            self.context.draw_text(&sensor.status(), offset + MARGIN);
+            offset += status_width + MARGIN * 2;
+        }
+    }
+
+    fn width(&mut self) -> u16 {
+        let mut sum = 0;
+        for ref sensor in self.sensors.iter() {
+            let text = format!("{}{}", sensor.icon(), sensor.status());
+            sum += self.context.measure_text(&text) + MARGIN * 4;
+        }
+        sum
+    }
+
+    fn update(&mut self) {
+        for ref mut sensor in self.sensors.iter_mut() {
+            sensor.process()
+        }
+    }
+}

+ 1 - 0
src/ui/widget.rs

@@ -11,6 +11,7 @@ pub trait Widget {
     fn handle_event(&mut self, _event: &xcb::GenericEvent, _is_finishing: bool) -> bool {
         false
     }
+    fn update(&mut self) {}
     fn finish(&mut self) {}
 }