big savings

pull/6/head
dvkt 5 years ago
parent 72ec92c861
commit 7eccabb518

@ -3,7 +3,7 @@ use gopher::Type;
use menu::{Line, Menu};
use std::io::stdout;
use std::io::Write;
use ui::{Action, Key, View, MAX_COLS, SCROLL_LINES};
use ui::{prompt, Action, Key, View, MAX_COLS, SCROLL_LINES};
pub struct MenuView {
pub input: String, // user's inputted value
@ -11,8 +11,6 @@ pub struct MenuView {
pub link: usize, // selected link
pub scroll: usize, // scrolling offset
pub size: (usize, usize), // cols, rows
pub prompt: String, // input prompt, if any
pub state: State, // view state
}
#[derive(PartialEq)]
@ -55,8 +53,6 @@ impl MenuView {
link: 0,
scroll: 0,
size: (0, 0),
state: State::Default,
prompt: String::new(),
}
}
@ -164,10 +160,9 @@ impl MenuView {
out.push_str(&" \r\n".repeat(rows - 1 - self.lines().len()).to_string());
}
out.push_str(&format!(
"{}{}{}{}",
"{}{}{}",
termion::cursor::Goto(1, self.size.1 as u16),
termion::clear::CurrentLine,
self.prompt,
self.input
));
out
@ -175,10 +170,9 @@ impl MenuView {
fn redraw_input(&self) -> Action {
print!(
"{}{}{}{}",
"{}{}{}",
termion::cursor::Goto(1, self.size.1 as u16),
termion::clear::CurrentLine,
self.prompt,
self.input
);
stdout().flush();
@ -377,9 +371,11 @@ impl MenuView {
let url = line.url.to_string();
let (typ, _, _, _) = gopher::parse_url(&url);
if typ == Type::Search {
self.prompt = format!("{}> ", line.name);
self.state = State::Search;
self.redraw_input()
if let Some(query) = prompt(&format!("{}> ", line.name)) {
Action::Open(format!("{}?{}", url, query))
} else {
Action::None
}
} else {
Action::Open(url)
}
@ -388,57 +384,7 @@ impl MenuView {
}
}
fn process_search_keypress(&mut self, key: Key) -> Action {
match key {
Key::Char('\n') => {
self.state = State::Default;
self.prompt.clear();
if let Some(link) = self.link(self.link) {
let url = format!("{}?{}", link.url, self.input);
self.input.clear();
Action::Open(url)
} else {
self.input.clear();
Action::Error("Error searching".to_string())
}
}
Key::Backspace | Key::Delete => {
self.input.pop();
self.redraw_input()
}
Key::Esc => {
if !self.input.is_empty() {
self.input.clear();
self.redraw_input()
} else {
self.state = State::Default;
self.prompt.clear();
self.redraw_input()
}
}
Key::Ctrl('c') => {
if !self.input.is_empty() {
self.input.clear();
self.redraw_input()
} else {
self.state = State::Default;
self.prompt.clear();
self.redraw_input()
}
}
Key::Char(c) => {
self.input.push(c);
self.redraw_input()
}
_ => Action::Keypress(key),
}
}
fn process_key(&mut self, key: Key) -> Action {
if self.state == State::Search {
return self.process_search_keypress(key);
}
match key {
Key::Char('\n') => self.action_open(),
Key::Up | Key::Ctrl('p') => self.action_up(),

@ -162,63 +162,6 @@ impl UI {
stdout().flush();
}
// Prompt user for input.
fn prompt(&self, prompt: &str) -> Option<String> {
print!(
"{}{}{}{}{}",
color::Fg(color::Reset),
termion::cursor::Goto(1, self.size.1 as u16),
termion::clear::CurrentLine,
prompt,
termion::cursor::Show,
);
stdout().flush();
let mut input = String::new();
for k in stdin().keys() {
if let Ok(key) = k {
match key {
Key::Char('\n') => {
print!("{}{}", termion::clear::CurrentLine, termion::cursor::Hide);
stdout().flush();
return Some(input);
}
Key::Char(c) => input.push(c),
Key::Esc | Key::Ctrl('c') => {
if input.is_empty() {
print!("{}{}", termion::clear::CurrentLine, termion::cursor::Hide);
stdout().flush();
return None;
} else {
input.clear();
}
}
Key::Backspace | Key::Delete => {
input.pop();
}
_ => {}
}
} else {
break;
}
print!(
"{}{}{}{}",
termion::cursor::Goto(1, self.size.1 as u16),
termion::clear::CurrentLine,
prompt,
input,
);
stdout().flush();
}
if !input.is_empty() {
Some(input)
} else {
None
}
}
fn add_page<T: View + 'static>(&mut self, view: T) {
self.dirty = true;
if !self.pages.is_empty() && self.page < self.pages.len() - 1 {
@ -267,7 +210,7 @@ impl UI {
}
}
Action::Keypress(Key::Ctrl('g')) => {
if let Some(url) = self.prompt("Go to URL: ") {
if let Some(url) = prompt("Go to URL: ") {
if !url.contains("://") && !url.starts_with("gopher://") {
self.open(&format!("gopher://{}", url))?;
} else {
@ -327,3 +270,62 @@ fn open_external(url: &str) -> io::Result<()> {
.output()
.and_then(|_| Ok(()))
}
/// Prompt user for input and return what was entered, if anything.
pub fn prompt(prompt: &str) -> Option<String> {
let (_cols, rows) = termion::terminal_size().unwrap();
print!(
"{}{}{}{}{}",
color::Fg(color::Reset),
termion::cursor::Goto(1, rows),
termion::clear::CurrentLine,
prompt,
termion::cursor::Show,
);
stdout().flush();
let mut input = String::new();
for k in stdin().keys() {
if let Ok(key) = k {
match key {
Key::Char('\n') => {
print!("{}{}", termion::clear::CurrentLine, termion::cursor::Hide);
stdout().flush();
return Some(input);
}
Key::Char(c) => input.push(c),
Key::Esc | Key::Ctrl('c') => {
if input.is_empty() {
print!("{}{}", termion::clear::CurrentLine, termion::cursor::Hide);
stdout().flush();
return None;
} else {
input.clear();
}
}
Key::Backspace | Key::Delete => {
input.pop();
}
_ => {}
}
} else {
break;
}
print!(
"{}{}{}{}",
termion::cursor::Goto(1, rows),
termion::clear::CurrentLine,
prompt,
input,
);
stdout().flush();
}
if !input.is_empty() {
Some(input)
} else {
None
}
}

Loading…
Cancel
Save