Skip to content

Commit

Permalink
Add tray icon
Browse files Browse the repository at this point in the history
  • Loading branch information
tocisz committed Feb 4, 2018
1 parent 247b849 commit d9f1c88
Show file tree
Hide file tree
Showing 8 changed files with 144 additions and 31 deletions.
9 changes: 7 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
[package]
name = "wsnotify"
version = "0.1.0"
authors = ["Tomasz Cichocki <tomasz.cichocki@optiva.com>"]
authors = ["Tomasz Cichocki <cichymail@gmail.com>"]

[dependencies]
notify = "4.0.0"
app_dirs = "^1.1.1"
app_dirs = "^1.1.1"
systray = { git = "https://github.com/tocisz/systray-rs" }
# systray = { path = "../systray-rs" }

[build-dependencies]
embed-resource = { git = "https://github.com/nabijaczleweli/rust-embed-resource" }
5 changes: 5 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
extern crate embed_resource;

fn main() {
embed_resource::compile("resource/icons.res");
}
3 changes: 3 additions & 0 deletions resource/icons.res
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Delete ICON "if_Delete_132746.ico"
Stop ICON "if_No-entry_132776.ico"
OK ICON "if_OK_132710.ico"
Binary file added resource/if_Delete_132746.ico
Binary file not shown.
Binary file added resource/if_No-entry_132776.ico
Binary file not shown.
Binary file added resource/if_OK_132710.ico
Binary file not shown.
76 changes: 47 additions & 29 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ extern crate notify;

use notify::{Watcher, RecursiveMode, RawEvent, raw_watcher};
use notify::op::Op;
use std::sync::mpsc::channel;
use std::sync::mpsc::{channel,Sender};

extern crate app_dirs;
use app_dirs::*;
Expand All @@ -12,7 +12,10 @@ use std::path::Path;
use std::io::Seek;
use std::io::SeekFrom;
use std::io::Read;
//use std::io::Error;
use std::thread;

mod ten_minutes;
use ten_minutes::MeterControlMessage;

fn read_file_length(path: &std::path::Path) -> Result<usize,std::io::Error> {
match std::fs::metadata(path) {
Expand Down Expand Up @@ -41,17 +44,23 @@ trait CameraEventWatcher {
fn on_image_save(&self, line: &str);
}

struct EchoCameraWatcher {}
impl CameraEventWatcher for EchoCameraWatcher {
struct SystrayCameraWatcher {
tx : Sender<MeterControlMessage>
}
impl CameraEventWatcher for SystrayCameraWatcher {
fn on_camera_start(&self, line: &str) {
println!("{}", line);
}

fn on_camera_prepare(&self, line: &str) {
println!("{}", line);
}

fn on_camera_finish(&self, line: &str) {
println!("{}", line);
self.tx.send(MeterControlMessage::MarkSafe).ok();
}

fn on_capture_start(&self, line: &str) {
println!("{}", line);
}
Expand Down Expand Up @@ -90,12 +99,12 @@ impl FileScanner {
fn handle_event(&mut self, op: Op) -> Result<(), String> {

if op != notify::op::WRITE {
// TODO support handling logfile rolling
// TODO support handling of logfile rolling
return Ok(());
}

let len = read_file_length(&self.file_name).map_err( |err| err.to_string())?;
// println!("{:?} {}", op, len);
//println!("{:?} {}", op, len);

let mut buffer = vec![0; len-self.last_byte_read].into_boxed_slice();
self.file.seek(SeekFrom::Start(self.last_byte_read as u64))
Expand Down Expand Up @@ -129,28 +138,37 @@ impl FileScanner {

const APP_INFO: AppInfo = AppInfo{name: "Logs", author: "CrossoverWorkSmart"};

fn main() {
let mut path = get_app_root(AppDataType::UserConfig, &APP_INFO).unwrap();
path.push("deskapp.log");
let path = path.as_path();

// Create a channel to receive the events.
let (tx, rx) = channel();

// Create a watcher object, delivering raw events.
// The notification back-end is selected based on the platform.
let mut watcher = raw_watcher(tx).unwrap();
let camera = Box::new(EchoCameraWatcher{});
let mut scanner = FileScanner::create(path, camera).unwrap();

// Add a path to be watched. All files and directories at that path and
// below will be monitored for changes.
watcher.watch(path, RecursiveMode::NonRecursive).unwrap();
loop {
match rx.recv() {
Ok(RawEvent{path: Some(_path), op: Ok(op), cookie: _cookie}) => scanner.handle_event(op).unwrap(),
Ok(event) => println!("broken event: {:?}", event),
Err(e) => println!("watch error: {:?}", e),
fn create_log_watch_thread(ui_tx: Sender<MeterControlMessage>) {
thread::spawn(move || {
let mut path = get_app_root(AppDataType::UserConfig, &APP_INFO).unwrap();
path.push("deskapp.log");
let path = path.as_path();

// Create a channel to receive the events.
let (tx, rx) = channel();

// Create a watcher object, delivering raw events.
// The notification back-end is selected based on the platform.
let mut watcher = raw_watcher(tx).unwrap();
let camera = Box::new(SystrayCameraWatcher { tx: ui_tx });
let mut scanner = FileScanner::create(path, camera).unwrap();

// Add a path to be watched. All files and directories at that path and
// below will be monitored for changes.
watcher.watch(path, RecursiveMode::NonRecursive).unwrap();
loop {
match rx.recv() {
Ok(RawEvent { path: Some(_path), op: Ok(op), cookie: _cookie }) => scanner.handle_event(op).unwrap(),
Ok(event) => println!("broken event: {:?}", event),
Err(e) => println!("watch error: {:?}", e),
}
}
}
});
}

#[cfg(target_os = "windows")]
fn main() {
let (ui_tx, ui_rx) = channel();
create_log_watch_thread(ui_tx);
ten_minutes::TenMinutesMeter::new(ui_rx).main();
}
82 changes: 82 additions & 0 deletions src/ten_minutes.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
extern crate systray;

use std::sync::mpsc::Receiver;

use std::time::{Duration, SystemTime, UNIX_EPOCH};
use std::process;

pub enum MeterControlMessage {
MarkSafe
}

pub struct TenMinutesMeter {
app : systray::Application,
rx : Receiver<MeterControlMessage>,
last_reminder : u16,
}

impl TenMinutesMeter {
pub fn new(rx : Receiver<MeterControlMessage>) -> TenMinutesMeter {
match systray::Application::new() {
Ok(w) => {
let mut app = w;
TenMinutesMeter::init(&mut app);
TenMinutesMeter {
app,
rx,
last_reminder: 0,
}
},
Err(_) => panic!("Can't create window!")
}
}

fn init(app : &mut systray::Application) -> () {
app.set_icon_from_resource(&"Stop".to_string()).ok();
// app.add_menu_item(&"Print a thing".to_string(), |_| {
// println!("Printing a thing!");
// }).ok();
// app.add_menu_separator().ok();
app.add_menu_item(&"Quit".to_string(), |window| {
window.shutdown().ok();
window.quit();
process::exit(0);
}).ok();
}

pub fn main(&mut self) -> () {
loop {
match self.app.wait_for_message_timeout(Duration::from_secs(1)) {
Ok(()) => (),
Err(e) => {
println!("{:?}", e);
return;
},
}

for m in self.rx.try_iter() {
match m {
MeterControlMessage::MarkSafe => self.mark_safe()
}
}

let since_epoch = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
let reminder = (since_epoch.as_secs() % 600) as u16;

if self.last_reminder > reminder {
self.mark_unsafe();
}

self.last_reminder = reminder;
}
}

pub fn mark_unsafe(&self) {
self.app.set_icon_from_resource(&"Stop".to_string()).ok();
}

pub fn mark_safe(&self) {
self.app.set_icon_from_resource(&"OK".to_string()).ok();
}
}

0 comments on commit d9f1c88

Please sign in to comment.