xref: /Held/src/utils/ui/event.rs (revision 984a200e159c143eb730a2df362731fe1a62fe01)
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