From ab4bddf408e38bd062fbb91837bc3a807ed32547 Mon Sep 17 00:00:00 2001 From: Jeremy Soller <jackpot51@gmail.com> Date: Thu, 18 Feb 2016 12:54:15 -0700 Subject: [PATCH] Application chooser --- src/launcher/main.rs | 106 +++++++++++++++++++++++++++++++++------- src/launcher/package.rs | 6 +-- 2 files changed, 92 insertions(+), 20 deletions(-) diff --git a/src/launcher/main.rs b/src/launcher/main.rs index 75e2c22..e030c13 100644 --- a/src/launcher/main.rs +++ b/src/launcher/main.rs @@ -11,7 +11,21 @@ use package::Package; pub mod package; -fn draw(window: &mut Window, packages: &Vec<Box<Package>>, shutdown: &BmpFile, mouse_x: i32, mouse_y: i32){ +fn get_packages() -> Vec<Package> { + let mut packages: Vec<Package> = Vec::new(); + + //TODO: Use a directory walk + for entry_result in fs::read_dir("/apps/").unwrap() { + let entry = entry_result.unwrap(); + if entry.file_type().unwrap().is_dir() { + packages.push(Package::from_path(&("/apps/".to_string() + entry.file_name().to_str().unwrap()))); + } + } + + packages +} + +fn draw(window: &mut Window, packages: &Vec<Package>, shutdown: &BmpFile, mouse_x: i32, mouse_y: i32){ window.set(Color::rgba(0, 0, 0, 0)); let w = window.width(); window.rect(0, 16, w, 32, Color::rgba(0, 0, 0, 128)); @@ -65,41 +79,99 @@ fn draw(window: &mut Window, packages: &Vec<Box<Package>>, shutdown: &BmpFile, m window.sync(); } -fn main() { - let mut packages: Vec<Box<Package>> = Vec::new(); +fn draw_chooser(window: &mut Window, packages: &Vec<Package>, mouse_x: i32, mouse_y: i32){ + let w = window.width(); - //TODO: Use a directory walk - for entry_result in fs::read_dir("/apps/").unwrap() { - let entry = entry_result.unwrap(); - if entry.file_type().unwrap().is_dir() { - packages.push(Package::from_path(&("/apps/".to_string() + entry.file_name().to_str().unwrap()))); + window.set(Color::rgb(255, 255, 255)); + + let mut y = 0; + for package in packages.iter() { + if mouse_y >= y as i32 && mouse_y < y + 32 { + window.rect(0, y, w, 32, Color::rgb(128, 128, 128)); } + + if package.icon.has_data() { + window.image(0, y, package.icon.width() as u32, package.icon.height() as u32, &package.icon); + } + + let mut c_x = 40; + for c in package.name.chars() { + window.char(c_x as i32, y + 8, c, Color::rgb(0, 0, 0)); + c_x += 8; + } + + y += 32; } + window.sync(); +} + +fn main() { let paths = env::args().skip(1); if paths.len() > 0 { for ref path in paths { - for package in packages.iter() { - let mut accepted = false; + let mut packages = get_packages(); + + packages.retain(|package| -> bool { for accept in package.accepts.iter() { if (accept.starts_with('*') && path.ends_with(&accept[1 ..])) || (accept.ends_with('*') && path.starts_with(&accept[.. accept.len() - 1])) { - accepted = true; - break; + return true; } } - if accepted { - if let Err(err) = Command::new(&package.binary).arg(&path).spawn() { - println!("launcher: failed to launch '{}': {}", package.binary, err); + false + }); + + if packages.len() > 1 { + for package in packages.iter() { + println!("{:?}: {}", package.binary, package.icon.has_data()); + } + + let mut window = Window::new(-1, -1, 400, packages.len() as u32 * 32, path).unwrap(); + + draw_chooser(&mut window, &packages, -1, -1); + 'choosing: loop { + for event in window.events() { + match event.to_option() { + EventOption::Mouse(mouse_event) => { + draw_chooser(&mut window, &packages, mouse_event.x, mouse_event.y); + + if mouse_event.left_button { + let mut y = 0; + for package in packages.iter() { + if package.icon.has_data() { + if mouse_event.y >= y && mouse_event.y < y + 32 { + if let Err(err) = Command::new(&package.binary).arg(path).spawn() { + println!("{}: Failed to launch: {}", package.binary, err); + } + break 'choosing; + } + y += 32; + } + } + } + }, + EventOption::Quit(_) => break 'choosing, + _ => () + } } - break; + + thread::yield_now(); } + } else if let Some(package) = packages.get(0) { + if let Err(err) = Command::new(&package.binary).arg(&path).spawn() { + println!("launcher: failed to launch '{}': {}", package.binary, err); + } + } else { + println!("launcher: no application found for '{}'", path); } } } else { + let packages = get_packages(); + let shutdown = BmpFile::from_path("/ui/actions/system-shutdown.bmp"); if ! shutdown.has_data() { - println!("Failed to read shutdown icon"); + println!("launcher: failed to read shutdown icon"); } let mut window = Window::new(0, 600 - 48, 800, 48, "").unwrap(); diff --git a/src/launcher/package.rs b/src/launcher/package.rs index fe6ddab..1e004b7 100644 --- a/src/launcher/package.rs +++ b/src/launcher/package.rs @@ -25,8 +25,8 @@ pub struct Package { impl Package { /// Create package from URL - pub fn from_path(url: &str) -> Box<Self> { - let mut package = Box::new(Package { + pub fn from_path(url: &str) -> Self { + let mut package = Package { url: url.to_string(), id: String::new(), name: String::new(), @@ -35,7 +35,7 @@ impl Package { accepts: Vec::new(), authors: Vec::new(), descriptions: Vec::new(), - }); + }; for part in url.rsplit('/') { if !part.is_empty() { -- GitLab