v1.0.2: arrow keys, start menu paging support

key press convenience methods, fix logo, docs, add more chars
This commit is contained in:
stjet
2025-03-23 21:41:59 +00:00
parent cdb35767ac
commit fa4627316d
81 changed files with 278 additions and 86 deletions

View File

@@ -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;
}

View File

@@ -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);
}

View File

@@ -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 = &current_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());
}

View File

@@ -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);
}

View File

@@ -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
}