1 use std::{io, sync::MutexGuard}; 2 3 use crate::utils::{buffer::LineState, cursor::CursorCrtl, style::StyleManager}; 4 5 use super::{ 6 mode::mode::ModeType, 7 uicore::{UiCore, APP_INFO, CONTENT_WINSIZE, DEF_STYLE, UI_CMD_HEIGHT}, 8 }; 9 10 pub const TAB_STR: &'static str = " "; 11 12 pub trait KeyEventCallback { 13 fn enter(&self, ui: &mut MutexGuard<UiCore>) -> io::Result<WarpUiCallBackType>; 14 fn tab(&self, ui: &mut MutexGuard<UiCore>) -> io::Result<WarpUiCallBackType>; 15 fn backspace(&self, ui: &mut MutexGuard<UiCore>) -> io::Result<WarpUiCallBackType> { 16 if ui.cursor.x() == 0 { 17 let y = ui.cursor.y(); 18 let (merged, linelen) = ui.buffer.merge_line(y); 19 if merged { 20 // 需要向上翻页 21 if ui.cursor.y() == 0 { 22 ui.scroll_down(1)?; 23 ui.cursor.move_to_nextline(1)?; 24 } 25 // 重新渲染 26 ui.cursor.move_up(1)?; 27 28 let y = ui.cursor.y(); 29 let ret = 30 ui.render_content(y, (CONTENT_WINSIZE.read().unwrap().rows - y + 1) as usize)?; 31 32 // 清除之前显示行 33 // 计算需要clear的行号 34 let clear_y = if ui.cursor.y() == 0 { y + 1 } else { y }; 35 let row = clear_y + ret as u16; 36 37 ui.cursor.move_to_row(row)?; 38 39 DEF_STYLE.read().unwrap().set_content_style()?; 40 41 ui.cursor.set_prefix_mode(false); 42 StyleManager::reset_color()?; 43 ui.cursor.move_to_columu(0)?; 44 ui.cursor 45 .write(&TAB_STR[..CursorCrtl::PREFIX_COL as usize])?; 46 ui.cursor.set_prefix_mode(true); 47 48 ui.cursor.clear_current_line()?; 49 50 ui.cursor.move_to_row(y)?; 51 ui.cursor.move_to_columu(linelen as u16)?; 52 ui.cursor.highlight(Some(clear_y))?; 53 ui.set_edited(); 54 return Ok(WarpUiCallBackType::None); 55 } else { 56 return Ok(WarpUiCallBackType::None); 57 } 58 } 59 60 let y = ui.cursor.y(); 61 let x = ui.cursor.x(); 62 63 let line = ui.buffer.get_line(y); 64 if line.flags.contains(LineState::LOCKED) { 65 APP_INFO.lock().unwrap().info = "Row is locked".to_string(); 66 return Ok(WarpUiCallBackType::None); 67 } 68 self.left(ui)?; 69 70 ui.buffer.remove_char(x - 1, y); 71 72 let line = ui.buffer.get_line(y); 73 74 ui.cursor.write(format!( 75 "{} ", 76 String::from_utf8_lossy(&line.data[x as usize..]) 77 ))?; 78 79 ui.cursor.highlight(None)?; 80 81 ui.cursor.move_to_columu(x - 1)?; 82 83 Ok(WarpUiCallBackType::None) 84 } 85 fn up(&self, ui: &mut MutexGuard<UiCore>) -> io::Result<WarpUiCallBackType> { 86 if ui.cursor.y() == 0 { 87 if ui.buffer.offset() == 0 { 88 // 上面没有数据 89 return Ok(WarpUiCallBackType::None); 90 } 91 // 向上滚动 92 ui.scroll_down(1)?; 93 94 let linesize = ui.buffer.get_linesize(ui.cursor.y()); 95 96 // 考虑\n 97 if linesize - 1 < ui.cursor.x() { 98 ui.cursor.move_to_columu(linesize - 1)?; 99 } 100 return Ok(WarpUiCallBackType::None); 101 } 102 let linesize = ui.buffer.get_linesize(ui.cursor.y() - 1); 103 104 if linesize == 0 { 105 return Ok(WarpUiCallBackType::None); 106 } 107 108 ui.cursor.move_up(1)?; 109 110 // 考虑\n 111 if linesize - 1 < ui.cursor.x() { 112 ui.cursor.move_to_columu(linesize - 1)?; 113 } 114 115 let last_y = ui.cursor.y() + 1; 116 ui.cursor.highlight(Some(last_y))?; 117 118 Ok(WarpUiCallBackType::None) 119 } 120 fn down(&self, ui: &mut MutexGuard<UiCore>) -> io::Result<WarpUiCallBackType> { 121 let size = *CONTENT_WINSIZE.read().unwrap(); 122 let mut linesize = ui.buffer.get_linesize(ui.cursor.y() + 1); 123 124 if linesize == 0 { 125 return Ok(WarpUiCallBackType::None); 126 } 127 128 if ui.cursor.y() == size.rows - UI_CMD_HEIGHT { 129 // 向shang滚动 130 ui.scroll_up(1)?; 131 if linesize < ui.cursor.x() { 132 ui.cursor.move_to_columu(linesize - 1)?; 133 } 134 return Ok(WarpUiCallBackType::None); 135 } 136 137 // \n 138 linesize -= 1; 139 140 ui.cursor.move_down(1)?; 141 142 if linesize < ui.cursor.x() { 143 ui.cursor.move_to_columu(linesize)?; 144 } 145 let last_y = ui.cursor.y() - 1; 146 ui.cursor.highlight(Some(last_y))?; 147 148 Ok(WarpUiCallBackType::None) 149 } 150 fn left(&self, ui: &mut MutexGuard<UiCore>) -> io::Result<WarpUiCallBackType> { 151 ui.cursor.move_left(1)?; 152 Ok(WarpUiCallBackType::None) 153 } 154 fn right(&self, ui: &mut MutexGuard<UiCore>) -> io::Result<WarpUiCallBackType> { 155 ui.cursor.move_right(1)?; 156 Ok(WarpUiCallBackType::None) 157 } 158 fn esc(&self, ui: &mut MutexGuard<UiCore>) -> io::Result<WarpUiCallBackType>; 159 fn input_data( 160 &self, 161 ui: &mut MutexGuard<UiCore>, 162 data: &[u8], 163 ) -> io::Result<WarpUiCallBackType>; 164 } 165 166 #[derive(Debug, PartialEq)] 167 pub enum WarpUiCallBackType { 168 ChangMode(ModeType), 169 Exit(bool), 170 None, 171 } 172