v1.0.2: arrow keys, start menu paging support
key press convenience methods, fix logo, docs, add more chars
This commit is contained in:
@@ -62,7 +62,7 @@ impl WindowLike for FileExplorer {
|
||||
},
|
||||
WindowMessage::KeyPress(key_press) => {
|
||||
self.state = State::List;
|
||||
if key_press.key == '𐘂' { //the enter key
|
||||
if key_press.is_enter() {
|
||||
if self.current_dir_contents.len() > 0 {
|
||||
let selected_entry = &self.current_dir_contents[self.position];
|
||||
if !selected_entry.is_file {
|
||||
@@ -74,8 +74,8 @@ impl WindowLike for FileExplorer {
|
||||
}
|
||||
}
|
||||
WindowMessageResponse::DoNothing
|
||||
} else if key_press.key == 'j' || key_press.key == 'k' {
|
||||
if key_press.key == 'j' {
|
||||
} else if key_press.key == 'j' || key_press.is_down_arrow() || key_press.key == 'k' || key_press.is_up_arrow() {
|
||||
if key_press.key == 'j' || key_press.is_down_arrow() {
|
||||
//down
|
||||
if self.position == self.current_dir_contents.len() - 1 {
|
||||
self.position = 0;
|
||||
@@ -94,7 +94,7 @@ impl WindowLike for FileExplorer {
|
||||
let max_height = self.dimensions[1] - HEIGHT;
|
||||
if self.position > self.top_position {
|
||||
let current_height = (self.position - self.top_position + 1) * HEIGHT;
|
||||
if current_height > self.dimensions[1] {
|
||||
if current_height > max_height {
|
||||
//somehow this is slightly off sometimes
|
||||
self.top_position += (current_height - max_height).div_ceil(HEIGHT);
|
||||
}
|
||||
@@ -138,7 +138,7 @@ impl WindowLike for FileExplorer {
|
||||
} else {
|
||||
name.unwrap()
|
||||
};
|
||||
instructions.push(DrawInstructions::Text([5, start_y], vec!["nimbus-roman".to_string(), "shippori-mincho".to_string()], name, if is_selected { theme_info.top_text } else { theme_info.text }, if is_selected { theme_info.top } else { theme_info.background }, None, None));
|
||||
instructions.push(DrawInstructions::Text([5, start_y + 4], vec!["nimbus-roman".to_string(), "shippori-mincho".to_string()], name, if is_selected { theme_info.top_text } else { theme_info.text }, if is_selected { theme_info.top } else { theme_info.background }, None, None));
|
||||
start_y += HEIGHT;
|
||||
i += 1;
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@ use std::env;
|
||||
use linux::fb::Framebuffer;
|
||||
use termion::input::TermRead;
|
||||
use termion::raw::IntoRawMode;
|
||||
use termion::{ clear, cursor };
|
||||
use termion::event::Key;
|
||||
|
||||
use ming_wm_lib::window_manager_types::KeyChar;
|
||||
@@ -17,7 +16,11 @@ use ming_wm_lib::messages::*;
|
||||
use ming_wm::framebuffer::{ FramebufferWriter, FramebufferInfo };
|
||||
use ming_wm::window_manager::WindowManager;
|
||||
|
||||
//use Linear A for escape, backspace, enter
|
||||
const CLEAR_ALL: &'static str = "\x1b[2J";
|
||||
const HIDE_CURSOR: &'static str = "\x1b[?25l";
|
||||
const SHOW_CURSOR: &'static str = "\x1b[?25h";
|
||||
|
||||
//use Linear A for escape, backspace, enter, arrow keys
|
||||
//Linear A used only internally in onscreen keyboard: 𐘎 is alt, 𐘧 is switch board, 𐘾 is ctrl
|
||||
fn key_to_char(key: Key) -> Option<KeyChar> {
|
||||
match key {
|
||||
@@ -27,6 +30,10 @@ fn key_to_char(key: Key) -> Option<KeyChar> {
|
||||
Key::Ctrl(c) => Some(KeyChar::Ctrl(c)),
|
||||
Key::Backspace => Some(KeyChar::Press('𐘁')),
|
||||
Key::Esc => Some(KeyChar::Press('𐘃')),
|
||||
Key::Up => Some(KeyChar::Press('𐙘')),
|
||||
Key::Down => Some(KeyChar::Press('𐘞')),
|
||||
Key::Left => Some(KeyChar::Press('𐙣')),
|
||||
Key::Right => Some(KeyChar::Press('𐙥')),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
@@ -68,9 +75,9 @@ fn init(framebuffer: Framebuffer, framebuffer_info: FramebufferInfo) {
|
||||
|
||||
let mut stdout = stdout().into_raw_mode().unwrap();
|
||||
|
||||
write!(stdout, "{}", clear::All).unwrap();
|
||||
write!(stdout, "{}", CLEAR_ALL).unwrap();
|
||||
|
||||
write!(stdout, "{}", cursor::Hide).unwrap();
|
||||
write!(stdout, "{}", HIDE_CURSOR).unwrap();
|
||||
|
||||
stdout.flush().unwrap();
|
||||
|
||||
@@ -147,12 +154,12 @@ fn init(framebuffer: Framebuffer, framebuffer_info: FramebufferInfo) {
|
||||
ThreadMessage::KeyChar(kc) => wm.handle_message(WindowManagerMessage::KeyChar(kc.clone())),
|
||||
ThreadMessage::Touch(x, y) => wm.handle_message(WindowManagerMessage::Touch(x, y)),
|
||||
ThreadMessage::Clear => {
|
||||
write!(stdout, "{}", clear::All).unwrap();
|
||||
write!(stdout, "{}", CLEAR_ALL).unwrap();
|
||||
stdout.flush().unwrap();
|
||||
},
|
||||
ThreadMessage::Exit => {
|
||||
if !wm.locked {
|
||||
write!(stdout, "{}", cursor::Show).unwrap();
|
||||
write!(stdout, "{}", SHOW_CURSOR).unwrap();
|
||||
stdout.suspend_raw_mode().unwrap();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
@@ -94,7 +94,7 @@ impl WindowLike for Malvim {
|
||||
WindowMessage::KeyPress(key_press) => {
|
||||
let mut changed = true;
|
||||
let mut new = false;
|
||||
if key_press.key == '𐘃' { //escape key
|
||||
if key_press.is_escape() {
|
||||
self.mode = Mode::Normal;
|
||||
self.state = State::None;
|
||||
changed = false;
|
||||
@@ -113,7 +113,7 @@ impl WindowLike for Malvim {
|
||||
let current_file = &mut self.files[self.current_file_index];
|
||||
let current_length = current_file.content[current_file.line_pos].chars().count();
|
||||
let line = ¤t_file.content[current_file.line_pos];
|
||||
if key_press.key == '𐘂' { //the enter key
|
||||
if key_press.is_enter() {
|
||||
let mut line: Vec<char> = line.chars().collect();
|
||||
let (left, right) = line.split_at_mut(current_file.cursor_pos);
|
||||
let left = left.into_iter().map(|c| c.to_string()).collect::<Vec<String>>().join("");
|
||||
@@ -136,7 +136,7 @@ impl WindowLike for Malvim {
|
||||
current_file.content.insert(current_file.line_pos + 1, " ".repeat(spaces) + &right);
|
||||
current_file.line_pos += 1;
|
||||
current_file.cursor_pos = spaces;
|
||||
} else if key_press.key == '𐘁' { //backspace
|
||||
} else if key_press.is_backspace() {
|
||||
if current_length > 0 && current_file.cursor_pos > 0 {
|
||||
current_file.content[current_file.line_pos] = line.remove(current_file.cursor_pos - 1, 1);
|
||||
current_file.cursor_pos -= 1;
|
||||
@@ -150,7 +150,7 @@ impl WindowLike for Malvim {
|
||||
current_file.cursor_pos = old_previous_line_length;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
} else if !key_press.is_arrow() { //arrow keys in insert mode is something i cannot support in good conscience
|
||||
current_file.content[current_file.line_pos] = line.substring(0, current_file.cursor_pos).to_string() + &key_press.key.to_string() + line.substring(current_file.cursor_pos, line.chars().count());
|
||||
current_file.cursor_pos += 1;
|
||||
}
|
||||
@@ -241,11 +241,11 @@ impl WindowLike for Malvim {
|
||||
current_file.cursor_pos = 0;
|
||||
}
|
||||
}
|
||||
} else if key_press.key == 'h' {
|
||||
} else if key_press.key == 'h' || key_press.is_left_arrow() {
|
||||
current_file.cursor_pos = current_file.cursor_pos.checked_sub(self.maybe_num.unwrap_or(1)).unwrap_or(0);
|
||||
changed = false;
|
||||
} else if key_press.key == 'j' || key_press.key == 'k' {
|
||||
if key_press.key == 'j' {
|
||||
} else if key_press.key == 'j' || key_press.is_down_arrow() || key_press.key == 'k' || key_press.is_up_arrow() {
|
||||
if key_press.key == 'j' || key_press.is_down_arrow() {
|
||||
current_file.line_pos += self.maybe_num.unwrap_or(1);
|
||||
if current_file.line_pos >= current_file.content.len() {
|
||||
current_file.line_pos = current_file.content.len() - 1;
|
||||
@@ -256,7 +256,7 @@ impl WindowLike for Malvim {
|
||||
let new_length = current_file.content[current_file.line_pos].chars().count();
|
||||
current_file.cursor_pos = calc_new_cursor_pos(current_file.cursor_pos, new_length);
|
||||
changed = false;
|
||||
} else if key_press.key == 'l' {
|
||||
} else if key_press.key == 'l' || key_press.is_right_arrow() {
|
||||
if current_length > 0 {
|
||||
current_file.cursor_pos += self.maybe_num.unwrap_or(1);
|
||||
let line_len = current_file.content[current_file.line_pos].chars().count();
|
||||
@@ -309,7 +309,7 @@ impl WindowLike for Malvim {
|
||||
} else if self.mode == Mode::Command {
|
||||
self.bottom_message = None;
|
||||
let command = self.command.clone().unwrap_or("".to_string());
|
||||
if key_press.key == '𐘂' { //the enter key
|
||||
if key_press.is_enter() {
|
||||
new = self.process_command();
|
||||
self.command = None;
|
||||
self.mode = Mode::Normal;
|
||||
@@ -330,7 +330,7 @@ impl WindowLike for Malvim {
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if key_press.key == '𐘁' { //backspace
|
||||
} else if key_press.is_backspace() {
|
||||
if command.len() > 0 {
|
||||
self.command = Some(command[..command.len() - 1].to_string());
|
||||
}
|
||||
|
||||
@@ -54,6 +54,7 @@ impl WindowLike for Minesweeper {
|
||||
self.random_chars = String::new();
|
||||
self.state = State::BeforePlaying;
|
||||
} else {
|
||||
//since must be u8, the Linear A (enter, backspace, etc) stuff won't do anything
|
||||
if u8::try_from(key_press.key).is_ok() {
|
||||
self.random_chars.push(key_press.key);
|
||||
}
|
||||
|
||||
@@ -104,13 +104,13 @@ impl WindowLike for Terminal {
|
||||
WindowMessage::KeyPress(key_press) => {
|
||||
match self.mode {
|
||||
Mode::Input => {
|
||||
if key_press.key == '𐘁' { //backspace
|
||||
if key_press.is_backspace() {
|
||||
if self.current_input.len() > 0 {
|
||||
self.current_input = self.current_input.remove_last();
|
||||
} else {
|
||||
return WindowMessageResponse::DoNothing;
|
||||
}
|
||||
} else if key_press.key == '𐘂' { //the enter key
|
||||
} else if key_press.is_enter() {
|
||||
self.lines.push("$ ".to_string() + &self.current_input);
|
||||
self.history.push(self.current_input.clone());
|
||||
self.history_index = None;
|
||||
@@ -127,6 +127,10 @@ impl WindowLike for Terminal {
|
||||
return WindowMessageResponse::DoNothing;
|
||||
}
|
||||
}
|
||||
} else if key_press.is_up_arrow() {
|
||||
self.prev();
|
||||
} else if key_press.is_down_arrow() {
|
||||
self.next();
|
||||
} else {
|
||||
self.current_input += &key_press.key.to_string();
|
||||
}
|
||||
@@ -175,19 +179,16 @@ impl WindowLike for Terminal {
|
||||
}
|
||||
},
|
||||
Mode::Stdin => {
|
||||
if key_press.key == '𐘃' {
|
||||
//esc
|
||||
if key_press.is_escape() {
|
||||
self.mode = Mode::Running;
|
||||
} else if key_press.key == '𐘂' {
|
||||
//enter
|
||||
} else if key_press.is_enter() {
|
||||
let _ = self.pty_in_tx.as_mut().unwrap().send(self.current_stdin_input.clone());
|
||||
self.mode = Mode::Running;
|
||||
let pcl_len = self.process_current_line.len();
|
||||
self.lines.push(strip_ansi_escape_codes(String::from_utf8(self.process_current_line.clone()).unwrap_or("?".repeat(pcl_len))) + &self.current_stdin_input);
|
||||
self.current_stdin_input = String::new();
|
||||
self.process_current_line = Vec::new();
|
||||
} else if key_press.key == '𐘁' {
|
||||
//backspace
|
||||
} else if key_press.is_backspace() {
|
||||
if self.current_stdin_input.len() > 0 {
|
||||
self.current_stdin_input = self.current_stdin_input.remove_last();
|
||||
} else {
|
||||
@@ -210,24 +211,12 @@ impl WindowLike for Terminal {
|
||||
} else if self.mode == Mode::Input && (key_press.key == 'p' || key_press.key == 'n') {
|
||||
//only the last command is saved unlike other terminals. good enough for me
|
||||
if key_press.key == 'p' && self.history.len() > 0 {
|
||||
if let Some(history_index) = self.history_index {
|
||||
if history_index > 0 {
|
||||
self.history_index = Some(history_index - 1);
|
||||
}
|
||||
} else {
|
||||
self.history_index = Some(self.history.len() - 1);
|
||||
}
|
||||
self.current_input = self.history[self.history_index.unwrap()].clone();
|
||||
|
||||
self.prev();
|
||||
self.calc_actual_lines();
|
||||
WindowMessageResponse::JustRedraw
|
||||
} else if key_press.key == 'n' {
|
||||
if self.history_index.is_none() || self.history_index.unwrap() == self.history.len() - 1 {
|
||||
self.history_index = None;
|
||||
self.current_input = String::new();
|
||||
} else {
|
||||
self.history_index = Some(self.history_index.unwrap() + 1);
|
||||
self.current_input = self.history[self.history_index.unwrap()].clone();
|
||||
}
|
||||
self.next();
|
||||
self.calc_actual_lines();
|
||||
WindowMessageResponse::JustRedraw
|
||||
} else {
|
||||
@@ -300,6 +289,27 @@ impl Terminal {
|
||||
Default::default()
|
||||
}
|
||||
|
||||
fn prev(&mut self) {
|
||||
if let Some(history_index) = self.history_index {
|
||||
if history_index > 0 {
|
||||
self.history_index = Some(history_index - 1);
|
||||
}
|
||||
} else {
|
||||
self.history_index = Some(self.history.len() - 1);
|
||||
}
|
||||
self.current_input = self.history[self.history_index.unwrap()].clone();
|
||||
}
|
||||
|
||||
fn next(&mut self) {
|
||||
if self.history_index.is_none() || self.history_index.unwrap() == self.history.len() - 1 {
|
||||
self.history_index = None;
|
||||
self.current_input = String::new();
|
||||
} else {
|
||||
self.history_index = Some(self.history_index.unwrap() + 1);
|
||||
self.current_input = self.history[self.history_index.unwrap()].clone();
|
||||
}
|
||||
}
|
||||
|
||||
fn get_max_lines(&self) -> usize {
|
||||
(self.dimensions[1] - PADDING * 2 - LINE_HEIGHT) / LINE_HEIGHT
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user