launcher: Modes

This commit is contained in:
Kenny Levinsen
2019-08-07 01:14:13 +02:00
parent ea2fd4b701
commit 18c93ec538
+117 -30
View File
@@ -6,6 +6,8 @@ use crate::module::{Input, ModuleImpl};
use std::cell::RefCell;
use std::cmp::Ordering;
use std::io::Read;
use std::process::Command;
use std::str;
use atty::Stream;
use chrono::{DateTime, Local};
@@ -29,6 +31,7 @@ impl Launcher {
let options = inbuf
.split("\n")
.into_iter()
.filter(|s| s.len() > 0)
.map(|s| s.to_string())
.collect();
@@ -41,45 +44,43 @@ impl Launcher {
dirty: true,
})
} else {
Err(::std::io::Error::new(
::std::io::ErrorKind::Other,
"input is a tty",
))
}
Ok(Launcher {
options: vec![],
matches: vec![],
cur: "".to_string(),
offset: 0,
font: RefCell::new(Font::new(&ROBOTO_REGULAR, 32.0)),
dirty: true,
})
}
}
impl ModuleImpl for Launcher {
fn draw(
fn draw_launcher(
&self,
buf: &mut Buffer,
bg: &Color,
_time: &DateTime<Local>,
) -> Result<Vec<(i32, i32, i32, i32)>, ::std::io::Error> {
buf.memset(bg);
self.font.borrow_mut().auto_draw_text(
&mut buf.subdimensions((0, 0, 128, 32))?,
let mut x_off = if self.cur.len() > 0 {
let c = if self.matches.len() == 0 { Color::new(1.0, 0.5, 0.5, 1.0) } else { Color::new(1.0, 1.0, 1.0, 1.0) };
let dim = self.font.borrow_mut().auto_draw_text(
&mut buf.subdimensions((0, 0, 1232, 32))?,
bg,
&Color::new(0.75, 0.75, 0.75, 1.0),
"Run: ",
)?;
let mut x_off: i32 = 0;
let mut width_remaining: i32 = 1232 - 64;
if self.matches.len() == 0 && self.cur.len() > 0 {
self.font.borrow_mut().auto_draw_text(
&mut buf
.subdimensions((64, 0, width_remaining as u32, 32))
.unwrap(),
bg,
&Color::new(1.0, 0.5, 0.5, 1.0),
&c,
&self.cur,
)?;
dim.0 + 8
} else {
0
};
let mut width_remaining: i32 = 1232 - x_off as i32;
for (idx, m) in self.matches.iter().enumerate() {
let mut b =
match buf.subdimensions((64 + x_off as u32, 0, width_remaining as u32, 32)) {
match buf.subdimensions((x_off, 0, width_remaining as u32, 32)) {
Ok(b) => b,
Err(_) => break,
};
@@ -106,20 +107,99 @@ impl ModuleImpl for Launcher {
)?
};
x_off += (size.0 + 8) as i32;
x_off += size.0 + 8;
width_remaining -= (size.0 + 8) as i32;
if width_remaining < 0 {
break;
}
}
Ok(vec![buf.get_signed_bounds()])
}
fn draw_calc(
&self,
buf: &mut Buffer,
bg: &Color,
) -> Result<Vec<(i32, i32, i32, i32)>, ::std::io::Error> {
buf.memset(bg);
let x_off = if self.cur.len() > 0 {
let dim = self.font.borrow_mut().auto_draw_text(
&mut buf.subdimensions((0, 0, 1232, 32))?,
bg,
&Color::new(1.0, 1.0, 1.0, 1.0),
&self.cur,
)?;
dim.0 + 16
} else {
0
};
if let Ok(output) = Command::new("ivy")
.arg("-e")
.arg(&self.cur.chars().skip(1).collect::<String>())
.output() {
if let Ok(stdout) = str::from_utf8(&output.stdout) {
let stdout = stdout.trim();
if stdout.len() > 0 {
self.font.borrow_mut().auto_draw_text(
&mut buf.subdimensions((x_off, 0, 1232-x_off, 32))?,
bg,
&Color::new(0.75, 0.75, 0.75, 1.0),
&format!(" = {:}", stdout),
)?;
}
}
}
Ok(vec![buf.get_signed_bounds()])
}
fn draw_shell(
&self,
buf: &mut Buffer,
bg: &Color,
) -> Result<Vec<(i32, i32, i32, i32)>, ::std::io::Error> {
buf.memset(bg);
self.font.borrow_mut().auto_draw_text(
&mut buf.subdimensions((0, 0, 1232, 32))?,
bg,
&Color::new(1.0, 1.0, 1.0, 1.0),
&self.cur,
)?;
Ok(vec![buf.get_signed_bounds()])
}
}
impl ModuleImpl for Launcher {
fn draw(
&self,
buf: &mut Buffer,
bg: &Color,
_time: &DateTime<Local>,
) -> Result<Vec<(i32, i32, i32, i32)>, ::std::io::Error> {
buf.memset(bg);
match self.cur.chars().next() {
Some('=') => self.draw_calc(buf, bg),
Some('!') => self.draw_shell(buf, bg),
_ => self.draw_launcher(buf, bg),
}?;
Ok(vec![buf.get_signed_bounds()])
}
fn update(&mut self, _time: &DateTime<Local>, force: bool) -> Result<bool, ::std::io::Error> {
if self.dirty || force {
match self.cur.chars().next() {
Some('=') => (),
Some('!') => (),
_ => {
let mut m = self
.options
.iter()
@@ -143,6 +223,9 @@ impl ModuleImpl for Launcher {
});
self.matches = m.into_iter().map(|(_, x)| x).collect();
}
};
self.dirty = false;
Ok(true)
} else {
@@ -161,13 +244,17 @@ impl ModuleImpl for Launcher {
}
}
keysyms::XKB_KEY_Return => {
if self.matches.len() > self.offset {
println!("{}", self.matches[self.offset]);
std::process::exit(0);
} else {
println!("{}", self.cur);
match self.cur.chars().next() {
Some('=') => (),
Some('!') => {
println!("{}", self.cur.chars().skip(1).collect::<String>());
std::process::exit(0);
}
_ => if self.matches.len() > self.offset {
println!("{}", self.matches[self.offset]);
std::process::exit(0);
}
};
}
keysyms::XKB_KEY_Right => {
if self.matches.len() > 0 && self.offset < self.matches.len() - 1 {