aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGustav Sörnäs <gustav@sornas.net>2021-05-02 22:53:30 +0200
committerGustav Sörnäs <gustav@sornas.net>2021-05-02 22:53:30 +0200
commit9e393263e820c328355ac58584ac635540ef2e6b (patch)
tree1dcb48b87c5f919afc1408bd5b508ba17c0a2ecc /src
parentea012211b6ad4d6973504b334816c568af9e60f3 (diff)
downloadmail-9e393263e820c328355ac58584ac635540ef2e6b.tar.gz
add basic window abstraction
Diffstat (limited to 'src')
-rw-r--r--src/buffer/mod.rs18
-rw-r--r--src/buffer/threads.rs41
-rw-r--r--src/main.rs8
-rw-r--r--src/window.rs43
4 files changed, 79 insertions, 31 deletions
diff --git a/src/buffer/mod.rs b/src/buffer/mod.rs
index 10b49c1..0a7e9ba 100644
--- a/src/buffer/mod.rs
+++ b/src/buffer/mod.rs
@@ -1,23 +1,33 @@
mod threads;
+use crate::window::Window;
+
use std::io::{Stdin, Write};
use termion::event::Key;
use termion::input::TermRead;
pub use threads::Threads;
+
pub struct Client {
+ window: Window,
buffers: Vec<Buffer>,
}
impl Client {
- pub fn new(initial_buffer: Buffer) -> Self {
+ pub fn new<W: Write>(initial_buffer: Buffer, out: &mut W) -> Self {
+ let mut window = Window::new();
+ match &initial_buffer {
+ Buffer::Threads(t) => t.fill_window(&mut window),
+ }
+ window.draw(out).unwrap();
Self {
+ window,
buffers: vec![initial_buffer],
}
}
- pub fn run<W: Write>(mut self, mut screen: W, stdin: Stdin) {
+ pub fn run<W: Write>(mut self, out: &mut W, stdin: Stdin) {
for c in stdin.keys() {
let c = c.unwrap();
// Global keybinds
@@ -32,12 +42,14 @@ impl Client {
}
let next_buffer = match self.buffers.last_mut().unwrap() {
- Buffer::Threads(s) => s.tick(&mut screen, c),
+ Buffer::Threads(s) => s.tick(&mut self.window, c),
};
if let Some(next_buffer) = next_buffer {
self.buffers.push(next_buffer);
}
+
+ self.window.draw(out).unwrap();
}
}
}
diff --git a/src/buffer/threads.rs b/src/buffer/threads.rs
index 85ffb0f..3525c2a 100644
--- a/src/buffer/threads.rs
+++ b/src/buffer/threads.rs
@@ -1,9 +1,9 @@
use crate::db;
+use crate::window::{Line, Window};
use super::Buffer;
use notmuch::DatabaseMode;
-use std::io::Write;
-use termion::{color, event::Key};
+use termion::event::Key;
pub struct Threads {
threads: Vec<Thread>,
@@ -68,11 +68,21 @@ impl Threads {
.collect();
}
- pub fn init<W: Write>(&self, out: &mut W) {
- self.draw(out);
+ pub fn fill_window(&self, window: &mut Window) {
+ println!("filling");
+ for (i, thread) in self.threads.iter().enumerate() {
+ let s = format!("thread: \'{}\' {:?}", thread.subject, thread.authors);
+ window.lines.push(
+ if self.i == i {
+ Line::Highlight(s)
+ } else {
+ Line::Normal(s)
+ }
+ );
+ }
}
- pub fn tick<W: Write>(&mut self, out: &mut W, key: Key) -> Option<Buffer> {
+ pub fn tick(&mut self, window: &mut Window, key: Key) -> Option<Buffer> {
match key {
Key::Char('j') => self.i += 1,
Key::Char('k') => self.i =
@@ -87,7 +97,7 @@ impl Threads {
}
Key::Char('s') => {
let sent = Threads::from_query(String::from("tag:sent"));
- sent.init(out);
+ sent.fill_window(window);
return Some(Buffer::Threads(sent));
}
Key::Char('r') => self.reload(),
@@ -96,24 +106,7 @@ impl Threads {
if !self.threads.is_empty() {
self.i = self.i.rem_euclid(self.threads.len());
}
- self.draw(out);
+ self.fill_window(window);
None
}
-
- fn draw<W: Write>(&self, out: &mut W) {
- write!(out, "{}", termion::clear::All).unwrap();
-
- for (i, thread) in self.threads.iter().enumerate() {
- write!(out, "{}", termion::cursor::Goto(1, (i + 1) as u16)).unwrap();
- let highlight = i == self.i;
- if highlight {
- write!(out, "{}", color::Fg(color::Red)).unwrap();
- }
- write!(out, "thread {:?}, {:?}", thread.subject, thread.authors).unwrap();
- if highlight {
- write!(out, "{}", color::Fg(color::Reset)).unwrap();
- }
- }
- out.flush().unwrap();
- }
}
diff --git a/src/main.rs b/src/main.rs
index a1a4220..59ed28d 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,5 +1,6 @@
-mod db;
mod buffer;
+mod db;
+mod window;
use crate::buffer::{Client, Buffer};
use crate::buffer::Threads;
@@ -16,8 +17,7 @@ fn main() {
let mut screen = termion::cursor::HideCursor::from(screen);
let threads = Threads::from_query(String::from("tag:inbox"));
- threads.init(&mut screen);
- let client = Client::new(Buffer::Threads(threads));
- client.run(screen, stdin);
+ let client = Client::new(Buffer::Threads(threads), &mut screen);
+ client.run(&mut screen, stdin);
}
diff --git a/src/window.rs b/src/window.rs
new file mode 100644
index 0000000..178c484
--- /dev/null
+++ b/src/window.rs
@@ -0,0 +1,43 @@
+//! A window is an abstraction for the UI. Buffers (like [Threads]) draw "to" windows.
+
+use std::io::Write;
+use termion::{clear, color, cursor};
+
+pub enum Line {
+ Normal(String),
+ Highlight(String),
+}
+
+pub struct Window {
+ pub lines: Vec<Line>,
+}
+
+impl Window {
+ pub fn new() -> Self {
+ Self {
+ lines: Vec::new(),
+ }
+ }
+
+ pub fn draw<W: Write>(&mut self, out: &mut W) -> Result<(), std::io::Error> {
+ write!(out, "{}", clear::All)?;
+
+ for (i, line) in self.lines.iter().enumerate() {
+ write!(out, "{}", cursor::Goto(1, (i + 1) as u16))?;
+ match line {
+ Line::Normal(s) => write!(out, "{}", s)?,
+ Line::Highlight(s) => write!(
+ out,
+ "{}{}{}",
+ color::Fg(color::Red),
+ s,
+ color::Fg(color::Reset),
+ )?,
+ }
+ }
+ out.flush()?;
+
+ self.lines.clear();
+ Ok(())
+ }
+}