Draw gui cursor shape
This commit is contained in:
		
							parent
							
								
									90dc2d4a53
								
							
						
					
					
						commit
						609d593db5
					
				
							
								
								
									
										126
									
								
								src/cursor.rs
									
									
									
									
									
								
							
							
						
						
									
										126
									
								
								src/cursor.rs
									
									
									
									
									
								
							| @ -3,6 +3,7 @@ use ui_model::Color; | ||||
| use ui::UiMutex; | ||||
| use shell; | ||||
| use mode; | ||||
| use nvim; | ||||
| use nvim::{RepaintMode, RedrawEvents}; | ||||
| use std::sync::{Arc, Weak}; | ||||
| 
 | ||||
| @ -123,7 +124,63 @@ impl Cursor { | ||||
|         let current_point = ctx.get_current_point(); | ||||
|         ctx.set_source_rgba(1.0 - bg.0, 1.0 - bg.1, 1.0 - bg.2, 0.6 * state.alpha.0); | ||||
| 
 | ||||
|         let cursor_width = if shell.mode.is(&mode::NvimMode::Insert) { | ||||
|         let (y, width, height) = | ||||
|             cursor_rect(&shell.mode, char_width, line_height, line_y, double_width); | ||||
| 
 | ||||
|         ctx.rectangle(current_point.0, y, width, height); | ||||
|         if state.anim_phase == AnimPhase::NoFocus { | ||||
|             ctx.stroke(); | ||||
|         } else { | ||||
|             ctx.fill(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| fn cursor_rect(mode: &mode::Mode, | ||||
|                char_width: f64, | ||||
|                line_height: f64, | ||||
|                line_y: f64, | ||||
|                double_width: bool) | ||||
|                -> (f64, f64, f64) { | ||||
|     if let Some(mode_info) = mode.mode_info() { | ||||
|         match mode_info.cursor_shape() { | ||||
|             None | | ||||
|             Some(&nvim::CursorShape::Unknown) | | ||||
|             Some(&nvim::CursorShape::Block) => { | ||||
|                 let cursor_width = if double_width { | ||||
|                     char_width * 2.0 | ||||
|                 } else { | ||||
|                     char_width | ||||
|                 }; | ||||
|                 (line_y, cursor_width, line_height) | ||||
|             } | ||||
|             Some(&nvim::CursorShape::Vertical) => { | ||||
|                 let cell_percentage = mode_info.cell_percentage(); | ||||
|                 let cursor_width = if cell_percentage > 0 { | ||||
|                     (char_width * cell_percentage as f64) / 100.0 | ||||
|                 } else { | ||||
|                     char_width | ||||
|                 }; | ||||
|                 (line_y, cursor_width, line_height) | ||||
|             } | ||||
|             Some(&nvim::CursorShape::Horizontal) => { | ||||
|                 let cell_percentage = mode_info.cell_percentage(); | ||||
|                 let cursor_width = if double_width { | ||||
|                     char_width * 2.0 | ||||
|                 } else { | ||||
|                     char_width | ||||
|                 }; | ||||
| 
 | ||||
|                 if cell_percentage > 0 { | ||||
|                     let height = (line_height * cell_percentage as f64) / 100.0; | ||||
|                     (line_y + line_height - height, cursor_width, height) | ||||
|                 } else { | ||||
|                     (line_y, cursor_width, line_height) | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } else { | ||||
|         let cursor_width = if mode.is(&mode::NvimMode::Insert) { | ||||
|             char_width / 5.0 | ||||
|         } else { | ||||
|             if double_width { | ||||
| @ -133,15 +190,9 @@ impl Cursor { | ||||
|             } | ||||
|         }; | ||||
| 
 | ||||
|         ctx.rectangle(current_point.0, line_y, cursor_width, line_height); | ||||
|         if state.anim_phase == AnimPhase::NoFocus { | ||||
|             ctx.stroke(); | ||||
|         } else { | ||||
|             ctx.fill(); | ||||
|         } | ||||
|         (line_y, cursor_width, line_height) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| fn anim_step(state: &Arc<UiMutex<State>>) -> glib::Continue { | ||||
|     let mut mut_state = state.borrow_mut(); | ||||
| 
 | ||||
| @ -201,3 +252,62 @@ impl Drop for Cursor { | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[cfg(test)] | ||||
| mod tests { | ||||
|     use super::*; | ||||
| 
 | ||||
|     #[test] | ||||
|     fn test_cursor_rect_horizontal() { | ||||
|         let mut mode = mode::Mode::new(); | ||||
|         let mode_info = nvim::ModeInfo::new(&vec![(From::from("cursor_shape"), | ||||
|                                                    From::from("horizontal")), | ||||
|                                                   (From::from("cell_percentage"), From::from(25))]); | ||||
|         mode.update("insert", 0); | ||||
|         mode.set_info(true, vec![mode_info.unwrap()]); | ||||
|         let char_width = 50.0; | ||||
|         let line_height = 30.0; | ||||
|         let line_y = 0.0; | ||||
| 
 | ||||
|         let (y, width, height) = cursor_rect(&mode, char_width, line_height, line_y, false); | ||||
|         assert_eq!(line_y + line_height - line_height / 4.0, y); | ||||
|         assert_eq!(char_width, width); | ||||
|         assert_eq!(line_height / 4.0, height); | ||||
|     } | ||||
| 
 | ||||
|     #[test] | ||||
|     fn test_cursor_rect_horizontal_doublewidth() { | ||||
|         let mut mode = mode::Mode::new(); | ||||
|         let mode_info = nvim::ModeInfo::new(&vec![(From::from("cursor_shape"), | ||||
|                                                    From::from("horizontal")), | ||||
|                                                   (From::from("cell_percentage"), From::from(25))]); | ||||
|         mode.update("insert", 0); | ||||
|         mode.set_info(true, vec![mode_info.unwrap()]); | ||||
|         let char_width = 50.0; | ||||
|         let line_height = 30.0; | ||||
|         let line_y = 0.0; | ||||
| 
 | ||||
|         let (y, width, height) = cursor_rect(&mode, char_width, line_height, line_y, true); | ||||
|         assert_eq!(line_y + line_height - line_height / 4.0, y); | ||||
|         assert_eq!(char_width * 2.0, width); | ||||
|         assert_eq!(line_height / 4.0, height); | ||||
|     } | ||||
| 
 | ||||
|     #[test] | ||||
|     fn test_cursor_rect_vertical() { | ||||
|         let mut mode = mode::Mode::new(); | ||||
|         let mode_info = nvim::ModeInfo::new(&vec![(From::from("cursor_shape"), | ||||
|                                                    From::from("vertical")), | ||||
|                                                   (From::from("cell_percentage"), From::from(25))]); | ||||
|         mode.update("insert", 0); | ||||
|         mode.set_info(true, vec![mode_info.unwrap()]); | ||||
|         let char_width = 50.0; | ||||
|         let line_height = 30.0; | ||||
|         let line_y = 0.0; | ||||
| 
 | ||||
|         let (y, width, height) = cursor_rect(&mode, char_width, line_height, line_y, false); | ||||
|         assert_eq!(line_y, y); | ||||
|         assert_eq!(char_width / 4.0, width); | ||||
|         assert_eq!(line_height, height); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -26,11 +26,10 @@ impl Mode { | ||||
|         self.mode == *mode | ||||
|     } | ||||
| 
 | ||||
|     pub fn mode_info(&self) -> nvim::ModeInfo { | ||||
|     pub fn mode_info(&self) -> Option<&nvim::ModeInfo> { | ||||
|         self.info | ||||
|             .as_ref() | ||||
|             .and_then(|i| i.get(self.idx).cloned()) | ||||
|             .unwrap_or_else(nvim::ModeInfo::default) | ||||
|             .and_then(|i| i.get(self.idx)) | ||||
|     } | ||||
| 
 | ||||
|     pub fn update(&mut self, mode: &str, idx: usize) { | ||||
|  | ||||
							
								
								
									
										13
									
								
								src/nvim.rs
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								src/nvim.rs
									
									
									
									
									
								
							| @ -139,13 +139,6 @@ pub struct ModeInfo { | ||||
| } | ||||
| 
 | ||||
| impl ModeInfo { | ||||
|     pub fn default() -> Self { | ||||
|         ModeInfo { | ||||
|             cursor_shape: Some(CursorShape::Block), | ||||
|             cell_percentage: None, | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     pub fn new(mode_info_arr: &Vec<(Value, Value)>) -> Result<Self, String> { | ||||
|         let mode_info_map = mode_info_arr.to_attrs_map()?; | ||||
| 
 | ||||
| @ -167,12 +160,12 @@ impl ModeInfo { | ||||
|            }) | ||||
|     } | ||||
| 
 | ||||
|     pub fn cursor_shape(&self) -> CursorShape { | ||||
|         self.cursor_shape.as_ref().cloned().unwrap_or(CursorShape::Block) | ||||
|     pub fn cursor_shape(&self) -> Option<&CursorShape> { | ||||
|         self.cursor_shape.as_ref() | ||||
|     } | ||||
| 
 | ||||
|     pub fn cell_percentage(&self) -> u64 { | ||||
|         self.cell_percentage.unwrap_or(100) | ||||
|         self.cell_percentage.unwrap_or(0) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 daa
						daa